示例#1
0
        /// <summary>
        /// Creates an <see cref="OperatorFactory"/> with appropriate terms
        /// (convective/diffusive) for the selected <paramref name="formulation"/>.
        /// </summary>
        /// <param name="formulation">
        /// The chosen equation system
        /// </param>
        /// <param name="control"></param>
        /// <param name="gridData"></param>
        /// <param name="speciesMap"></param>
        /// <param name="workingSet"></param>
        /// <param name="boundaryMap">
        /// Boundary information
        /// </param>
        /// <returns>
        /// An instance of <see cref="OperatorFactory"/> that has been
        /// configured with the fluxes defined by
        /// <see cref="CNSControl.ConvectiveFluxType"/> and/or
        /// <see cref="CNSControl.DiffusiveFluxType"/>.
        /// </returns>
        public static OperatorFactory GetOperatorFactory(
            this DomainTypes formulation, CNSControl control, IGridData gridData, BoundaryConditionMap boundaryMap, CNSFieldSet workingSet, ISpeciesMap speciesMap)
        {
            switch (formulation)
            {
            case DomainTypes.Standard:
                return(new OperatorFactory(
                           control, gridData, workingSet, speciesMap, boundaryMap));

            case DomainTypes.StaticImmersedBoundary:
            case DomainTypes.MovingImmersedBoundary:
                FluxBuilder convectiveBuilder = control.ConvectiveFluxType.GetBuilder(
                    control, boundaryMap, speciesMap);
                return(new IBMOperatorFactory(
                           (IBMControl)control,
                           gridData,
                           workingSet,
                           speciesMap,
                           boundaryMap));

            default:
                throw new Exception(
                          "Unknown formulation \"" + control.DomainType + "\"");
            }
        }
        /// <summary>
        /// Dispatcher to determine the correct sub-class of
        /// <see cref="BoundaryConditionSource"/> when creating a source term
        /// for a specific equation component.
        /// </summary>
        public static BoundaryConditionSource CreateBoundaryConditionSource(
            this IEquationComponent equationComponent, CNSControl control, ISpeciesMap speciesMap, BoundaryCondition boundaryCondition)
        {
            BoundaryConditionSource result;

            if (equationComponent is INonlinearFlux)
            {
                result = new BoundaryConditionSourceFromINonlinearFlux(
                    control, speciesMap, boundaryCondition, (INonlinearFlux)equationComponent);
            }
            else if (equationComponent is SIPGFlux)
            {
                result = new BoundaryConditionSourceFromSIPGFlux(
                    control, speciesMap, boundaryCondition, (SIPGFlux)equationComponent);
            }
            else if (equationComponent is INonlinear2ndOrderForm)
            {
                result = new BoundaryConditionSourceFromINonlinear2ndOrderForm(
                    control, speciesMap, boundaryCondition, (INonlinear2ndOrderForm)equationComponent);
            }
            else
            {
                throw new NotImplementedException("To do");
            }

            return(result);
        }
示例#3
0
        /// <summary>
        /// Instantiates the correct sub-class of <see cref="FluxBuilder"/>
        /// corresponding to the selected <paramref name="flux"/>.
        /// </summary>
        /// <param name="flux">
        /// The flux for which the builder should be instantiated.
        /// </param>
        /// <param name="control">
        /// Configuration options
        /// </param>
        /// <param name="boundaryMap">
        /// Information about boundary conditions
        /// </param>
        /// <param name="speciesMap">
        /// Mapping of different species int he domain
        /// </param>
        /// <returns>
        /// An instance of a flux builder that builds fluxes
        /// corresponding to the given <paramref name="flux"/>.
        /// </returns>
        public static FluxBuilder GetBuilder(this ConvectiveFluxTypes flux, CNSControl control, BoundaryConditionMap boundaryMap, ISpeciesMap speciesMap)
        {
            switch (flux)
            {
            case ConvectiveFluxTypes.Rusanov:
                return(new RusanovFluxBuilder(control, boundaryMap, speciesMap));

            case ConvectiveFluxTypes.HLL:
                return(new HLLFluxBuilder(control, boundaryMap, speciesMap));

            case ConvectiveFluxTypes.HLLC:
                return(new HLLCFluxBuilder(control, boundaryMap, speciesMap));

            case ConvectiveFluxTypes.OptimizedHLLC:
                return(new OptimizedHLLCFLuxBuilder(control, boundaryMap, speciesMap));

            case ConvectiveFluxTypes.Godunov:
                return(new GodunovFluxBuilder(control, boundaryMap, speciesMap));

            case ConvectiveFluxTypes.MovingFrameRusanov:
                return(new MovingFrameRusanovFluxBuilder(control, boundaryMap, speciesMap));

            case ConvectiveFluxTypes.None:
                return(NullFluxBuilder.Instance);

            default:
                throw new Exception("Unknown flux function \"" + flux + "\"");
            }
        }
示例#4
0
 /// <summary>
 /// Constructs a new Euler flux
 /// </summary>
 /// <param name="config">Configuration options</param>
 /// <param name="boundaryMap">Boundary value definition</param>
 /// <param name="equationComponent">
 /// Concerned component of the Euler equations
 /// </param>
 /// <param name="speciesMap">
 /// Mapping that determines the active species in some point.
 /// </param>
 protected EulerFlux(CNSControl config, IBoundaryConditionMap boundaryMap, IEulerEquationComponent equationComponent, ISpeciesMap speciesMap)
 {
     this.config            = config;
     this.boundaryMap       = boundaryMap;
     this.equationComponent = equationComponent;
     this.speciesMap        = speciesMap;
 }
示例#5
0
 /// <summary>
 /// Constructs a new supersonic inlet using the values defined by
 /// <paramref name="densityFunction"/>,
 /// <paramref name="velocityFunctions"/> and
 /// <paramref name="pressureFunction"/> as values at the boundary.
 /// </summary>
 /// <param name="config"><see cref="BoundaryCondition"/></param>
 /// <param name="densityFunction">
 /// The prescribed density at the inlet
 /// </param>
 /// <param name="velocityFunctions">
 /// The prescribed velocity components at the inlet
 /// </param>
 /// <param name="pressureFunction">
 /// The prescribed pressure at the inlet
 /// </param>
 public SupersonicInlet(CNSControl config, Func <double[], double, double> densityFunction, Func <double[], double, double>[] velocityFunctions, Func <double[], double, double> pressureFunction)
     : base(config)
 {
     this.DensityFunction   = densityFunction;
     this.VelocityFunctions = velocityFunctions;
     this.PressureFunction  = pressureFunction;
 }
示例#6
0
 public OptimizedSIPGDensityFlux(CNSControl config, IBoundaryConditionMap boundaryMap, ISpeciesMap speciesMap, IGridData gridData, Func <MultidimensionalArray> cellMetric)
 {
     this.config      = config;
     this.speciesMap  = speciesMap;
     this.boundaryMap = boundaryMap;
     this.gridData    = gridData;
 }
示例#7
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="control"></param>
 /// <param name="vortexSpeed"></param>
 /// <param name="periodic"></param>
 /// <param name="BoxSize"></param>
 public IsentropicVortexExactSolution(CNSControl control, double vortexSpeed, bool periodic = false, double BoxSize = 0.0)
 {
     this.control     = control;
     this.vortexSpeed = vortexSpeed;
     this.periodic    = periodic;
     this.BoxSize     = BoxSize;
 }
示例#8
0
        /// <summary>
        /// Constructs a new flux builder.
        /// </summary>
        /// <param name="control"></param>
        /// <param name="boundaryMap"></param>
        /// <param name="speciesMap"></param>
        /// <param name="gridData"></param>
        public OptimizedSIPGFluxBuilder(CNSControl control, IBoundaryConditionMap boundaryMap, ISpeciesMap speciesMap, GridData gridData)
            : base(control, boundaryMap, speciesMap)
        {
            this.gridData = gridData;

            //Create Functions for calculation the cell metric, needed as Func<> because
            //LevelSet field and HMF options are not known at this point
            if (speciesMap is IBM.ImmersedSpeciesMap)
            {
                // IBM case
                ImmersedSpeciesMap IBMspeciesMap = speciesMap as ImmersedSpeciesMap;
                cellMetricFunc = delegate() {
                    SpeciesId             species    = IBMspeciesMap.Tracker.GetSpeciesId(IBMspeciesMap.Control.FluidSpeciesName);
                    MultidimensionalArray cellMetric = IBMspeciesMap.CellAgglomeration.CellLengthScales[species].CloneAs();
                    cellMetric.ApplyAll(x => 1 / x);
                    // Needed, because 1/x produces NaN in void cells and can happen that penalty factor leads then to NaN
                    cellMetric.ApplyAll(delegate(double x) {
                        if (double.IsNaN(x) || double.IsInfinity(x))
                        {
                            return(0);
                        }
                        else
                        {
                            return(x);
                        }
                    });
                    return(cellMetric);
                };
            }
            else
            {
                // Non-IBM
                cellMetricFunc = () => gridData.Cells.cj;
            }
        }
示例#9
0
        public OptimizedSIPGEnergyFlux(CNSControl config, IBoundaryConditionMap boundaryMap, ISpeciesMap speciesMap, GridData gridData, Func <MultidimensionalArray> cellMetricFunc)
        {
            this.config         = config;
            this.speciesMap     = speciesMap;
            this.boundaryMap    = boundaryMap;
            this.gridDat        = gridData;
            this.dimension      = gridDat.SpatialDimension;
            this.material       = speciesMap.GetMaterial(double.NaN);
            this.cellMetricFunc = cellMetricFunc;

            double p = new int[] { config.DensityDegree, config.MomentumDegree, config.EnergyDegree }.Max();

            penaltyFactor = config.SIPGPenaltyScaling * p * p;

            foreach (byte edgeTag in gridData.Edges.EdgeTags)
            {
                if (boundaryMap.EdgeTagNames[edgeTag].StartsWith("adiabaticWall", StringComparison.InvariantCultureIgnoreCase))
                {
                    edgeTagBool[edgeTag] = true;
                }
                else
                {
                    edgeTagBool[edgeTag] = false;
                }
            }

            // [NumOfArguments, dimension, dimension]
            // [ k , l , j] --> indices according to Hartmann2008 or AnnualReport2014_SKE (i doesn't exist)
            GTensorIn  = new double[dimension, dimension, dimension + 2];
            GTensorOut = new double[dimension, dimension, dimension + 2];
        }
示例#10
0
        /// <summary>
        /// Instantiates the <see cref="FluxBuilder"/> associated with the
        /// given <paramref name="diffusiveFlux"/>.
        /// </summary>
        /// <param name="diffusiveFlux">
        /// The selected flux type.
        /// </param>
        /// <param name="control">
        /// <see cref="FluxBuilder.FluxBuilder"/>
        /// </param>
        /// <param name="boundaryMap">
        /// <see cref="FluxBuilder.FluxBuilder"/>
        /// </param>
        /// <param name="speciesMap">
        /// <see cref="FluxBuilder.FluxBuilder"/>
        /// </param>
        /// <param name="gridData">
        /// Grid information; e.g. required for the calculation of penalty
        /// parameters
        /// </param>
        /// <returns>
        /// An instance of <see cref="FluxBuilder"/> that constructs the fluxes
        /// corresponding to <paramref name="diffusiveFlux"/>.
        /// </returns>
        public static FluxBuilder GetBuilder(this DiffusiveFluxTypes diffusiveFlux, CNSControl control, IBoundaryConditionMap boundaryMap, ISpeciesMap speciesMap, GridData gridData)
        {
            int minDegree = Math.Min(
                Math.Min(control.DensityDegree, control.MomentumDegree),
                control.EnergyDegree);

            switch (diffusiveFlux)
            {
            case DiffusiveFluxTypes.SIPG:
                if (minDegree < 1)
                {
                    throw new Exception(
                              "SIPG is only valid for DG degrees greater than 0");
                }
                return(new SIPGFluxBuilder(control, boundaryMap, speciesMap, gridData));

            case DiffusiveFluxTypes.OptimizedSIPG:
                if (minDegree < 1)
                {
                    throw new Exception(
                              "SIPG is only valid for DG degrees greater than 0");
                }
                return(new OptimizedSIPGFluxBuilder(control, boundaryMap, speciesMap, gridData));

            case DiffusiveFluxTypes.None:
                return(NullFluxBuilder.Instance);

            default:
                throw new Exception("Unknown flux function \"" + diffusiveFlux + "\"");
            }
        }
示例#11
0
 /// <summary>
 /// <see cref="EulerFlux"/>
 /// </summary>
 /// <param name="config"><see cref="EulerFlux"/></param>
 /// <param name="boundaryMap"><see cref="EulerFlux"/></param>
 /// <param name="equationComponent"><see cref="EulerFlux"/></param>
 /// <param name="speciesMap"><see cref="EulerFlux"/></param>
 protected HLLCFlux(CNSControl config, IBoundaryConditionMap boundaryMap, IEulerEquationComponent equationComponent, ISpeciesMap speciesMap)
     : base(config, boundaryMap, equationComponent, speciesMap)
 {
     if (config.EquationOfState is IdealGas == false)
     {
         throw new Exception("HLLC flux currently only works for ideal gases");
     }
 }
示例#12
0
 /// <summary>
 /// <see cref="EulerFlux.EulerFlux"/>
 /// </summary>
 /// <param name="config">
 /// <see cref="EulerFlux.EulerFlux"/>
 /// </param>
 /// <param name="boundaryMap">
 /// <see cref="EulerFlux.EulerFlux"/>
 /// </param>
 /// <param name="equationComponent">
 /// <see cref="EulerFlux.EulerFlux"/>
 /// </param>
 /// <param name="speciesMap">
 /// <see cref="EulerFlux.EulerFlux"/>
 /// </param>
 public GodunovFlux(CNSControl config, IBoundaryConditionMap boundaryMap, IEulerEquationComponent equationComponent, ISpeciesMap speciesMap)
     : base(config, boundaryMap, equationComponent, speciesMap)
 {
     if (config.EquationOfState is IdealGas == false)
     {
         throw new Exception("Riemann solver currently only supports ideal gases");
     }
 }
示例#13
0
 /// <summary>
 /// ctor for the implementation of the SIPG momentum fluxes
 /// </summary>
 /// <param name="config"><see cref="SIPGFlux.config"/></param>
 /// <param name="boundaryMap"><see cref="SIPGFlux.boundaryMap"/></param>
 /// <param name="speciesMap"><see cref="SIPGFlux.speciesMap"/></param>
 /// <param name="gridData"><see cref="SIPGFlux.gridData"/></param>
 /// <param name="component"><see cref="SIPGFlux.Component"/></param>
 /// <param name="cellMetricFunc"><see cref="SIPGFlux"/></param>
 public SIPGMomentumFlux(CNSControl config, BoundaryConditionMap boundaryMap, ISpeciesMap speciesMap, IGridData gridData, int component, Func <MultidimensionalArray> cellMetricFunc)
     : base(config, boundaryMap, speciesMap, gridData, cellMetricFunc)
 {
     if (component < 1 || component > CompressibleEnvironment.NumberOfDimensions)
     {
         throw new ArgumentOutOfRangeException("component");
     }
     this.component = component;
 }
示例#14
0
 /// <summary>
 /// <see cref="FluxBuilder"/>
 /// </summary>
 /// <param name="control"><see cref="FluxBuilder"/>
 /// <see cref="FluxBuilder"/>
 /// </param>
 /// <param name="boundaryMap"><see cref="FluxBuilder"/>
 /// <see cref="FluxBuilder"/>
 /// </param>
 /// <param name="speciesMap">
 /// <see cref="FluxBuilder"/>
 /// </param>
 public MovingFrameRusanovFluxBuilder(CNSControl control, CompressibleBoundaryCondMap boundaryMap, ISpeciesMap speciesMap)
     : base(control, boundaryMap, speciesMap)
 {
     this.ibmSpeciesMap = speciesMap as ImmersedSpeciesMap;
     if (ibmSpeciesMap == null)
     {
         throw new System.Exception();
     }
 }
示例#15
0
        /// <summary>
        /// Prepares the construction of a new equation system
        /// </summary>
        /// <param name="control"></param>
        /// <param name="gridData"></param>
        /// <param name="workingSet"></param>
        /// <param name="speciesMap"></param>
        /// <param name="boundaryMap"></param>
        /// <remarks>
        /// Source terms are currently considered independent of the considered
        /// equation system and are thus constructed automatically from the
        /// control file (see <see cref="CustomSourceBuilder"/>).
        /// </remarks>
        public OperatorFactory(
            CNSControl control,
            GridData gridData,
            CNSFieldSet workingSet,
            ISpeciesMap speciesMap,
            IBoundaryConditionMap boundaryMap)
        {
            bool hasConvection = control.ActiveOperators.HasFlag(Operators.Convection);
            bool hasDiffusion  = control.ActiveOperators.HasFlag(Operators.Diffusion);

            if (!hasConvection && !hasDiffusion)
            {
                throw new Exception(
                          "Either convective or diffusive terms must be active");
            }

            if (hasConvection)
            {
                this.convectiveFluxBuilder = control.ConvectiveFluxType.GetBuilder(
                    control, boundaryMap, speciesMap);
            }

            if (hasDiffusion)
            {
                this.diffusiveFluxBuilder = control.DiffusiveFluxType.GetBuilder(
                    control, boundaryMap, speciesMap, gridData);
            }

            if (control.ActiveOperators.HasFlag(Operators.Gravity))
            {
                this.sourceTermBuilders.Add(
                    new GravityFluxBuilder(control, boundaryMap, speciesMap));
            }

            if (control.ActiveOperators.HasFlag(Operators.CustomSource))
            {
                this.sourceTermBuilders.Add(
                    new CustomSourceBuilder(control, boundaryMap, speciesMap));
            }

            if (control.ActiveOperators.HasFlag(Operators.SpongeLayer))
            {
                this.sourceTermBuilders.Add(
                    new SpongeLayerFluxBuilder(control, boundaryMap, speciesMap));
            }

            if (control.ActiveOperators.HasFlag(Operators.ArtificialViscosity))
            {
                this.sourceTermBuilders.Add(
                    new LaplacianArtificialViscosityFluxBuilder(control, boundaryMap, speciesMap));
            }

            this.control    = control;
            this.gridData   = gridData;
            this.workingSet = workingSet;
            this.speciesMap = speciesMap;
        }
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="config"></param>
        /// <param name="speciesMap"></param>
        /// <param name="boundaryCondition"></param>
        /// <param name="fluxFunction"></param>
        public BoundaryConditionSourceFromINonlinear2ndOrderForm(
            CNSControl config, ISpeciesMap speciesMap, BoundaryCondition boundaryCondition, INonlinear2ndOrderForm fluxFunction)
            : base(config, speciesMap, boundaryCondition)
        {
            this.fluxFunction = fluxFunction;

            if (boundaryCondition is AdiabaticWall)
            {
                adiaWall = true;
            }
        }
示例#17
0
        /// <summary>
        /// Constructs a new constraint
        /// </summary>
        /// <param name="config"></param>
        /// <param name="gridData"></param>
        /// <param name="workingSet"></param>
        /// <param name="speciesMap"></param>
        public DiffusiveCFLConstraint(
            CNSControl config, GridData gridData, CNSFieldSet workingSet, ISpeciesMap speciesMap)
            : base(gridData, workingSet)
        {
            this.config     = config;
            this.speciesMap = speciesMap;

            if (gridData.Grid.RefElements.Length > 1)
            {
                throw new NotImplementedException();
            }
        }
示例#18
0
        public ArtificialViscosityCFLConstraint(
            CNSControl config, IGridData gridData, CNSFieldSet workingSet, ISpeciesMap speciesMap)
            : base(gridData, workingSet)
        {
            this.config     = config;
            this.speciesMap = speciesMap;

            if (gridData.iGeomCells.RefElements.Length > 1)
            {
                throw new NotImplementedException();
            }
        }
        /// <summary>
        /// Constructs a new constraint
        /// </summary>
        /// <param name="config"></param>
        /// <param name="gridData"></param>
        /// <param name="workingSet"></param>
        /// <param name="speciesMap"></param>
        public ConvectiveCFLConstraint(
            CNSControl config, IGridData gridData, CNSFieldSet workingSet, ISpeciesMap speciesMap)
            : base(gridData, workingSet)
        {
            this.control    = config;
            this.speciesMap = speciesMap;

            if (gridData.iGeomCells.RefElements.Length > 1 || !(gridData is GridData))
            {
                throw new NotImplementedException();
            }
        }
示例#20
0
        /// <summary>
        /// Factory for residual loggers. The instantiated objects depend on the
        /// defined <paramref name="loggerType"/>.
        /// </summary>
        /// <param name="loggerType">
        /// The type of logger to be instantiated
        /// </param>
        /// <param name="program">
        /// The program requesting the residual logger.
        /// </param>
        /// <param name="config">Configuration options</param>
        /// <param name="differentialOperator">
        /// The differential operator that defines the system of equations to
        /// be solved. May be null if <paramref name="loggerType"/> does
        /// <b>not</b> contain <see cref="ResidualLoggerTypes.Rigorous"/>.
        /// </param>
        /// <returns>
        /// A list of residual loggers, see <see cref="ResidualLogger"/>.
        /// </returns>
        public static IEnumerable <IResidualLogger> Instantiate <T>(
            this ResidualLoggerTypes loggerType,
            Program <T> program,
            CNSControl config,
            SpatialOperator differentialOperator)
            where T : CNSControl, new()
        {
            if (loggerType.HasFlag(ResidualLoggerTypes.ChangeRate) &&
                loggerType.HasFlag(ResidualLoggerTypes.Rigorous))
            {
                throw new Exception(
                          "Residual types \"changeRate\" and \"rigorous\" are mutually exclusive");
            }

            if (loggerType == ResidualLoggerTypes.None)
            {
                yield return(new NullResidualLogger(
                                 program.ResLogger, program.CurrentSessionInfo, program.WorkingSet));
            }
            else
            {
                if (loggerType.HasFlag(ResidualLoggerTypes.ChangeRate))
                {
                    loggerType ^= ResidualLoggerTypes.ChangeRate;
                    yield return(new ChangeRateResidualLogger(
                                     program.ResLogger, program.CurrentSessionInfo, program.WorkingSet, config.ResidualInterval));
                }

                if (loggerType.HasFlag(ResidualLoggerTypes.Rigorous))
                {
                    loggerType ^= ResidualLoggerTypes.Rigorous;
                    yield return(new RigorousResidualLogger <T>(
                                     program,
                                     config.ResidualInterval,
                                     differentialOperator));
                }

                if (loggerType.HasFlag(ResidualLoggerTypes.Query))
                {
                    loggerType ^= ResidualLoggerTypes.Query;
                    yield return(new QueryLogger(
                                     program.ResLogger, program));
                }

                if (loggerType != ResidualLoggerTypes.None)
                {
                    throw new NotImplementedException(
                              "Residual logging for residual type " + loggerType + " not implemented");
                }
            }
        }
示例#21
0
        /// <summary>
        /// Constructs and empty operator.
        /// </summary>
        public Operator(CNSControl config)
        {
            this.config = config;

            DensityComponents  = new List <IEquationComponent>();
            MomentumComponents = new IList <IEquationComponent> [
                CompressibleEnvironment.NumberOfDimensions];
            for (int d = 0; d < CompressibleEnvironment.NumberOfDimensions; d++)
            {
                MomentumComponents[d] = new List <IEquationComponent>();
            }
            EnergyComponents = new List <IEquationComponent>();
            CFLConstraints   = new List <TimeStepConstraint>();
        }
示例#22
0
        /// <summary>
        /// Constructs a constraint that respects the given
        /// <paramref name="speciesMap"/>
        /// </summary>
        /// <param name="config"></param>
        /// <param name="gridData"></param>
        /// <param name="workingSet"></param>
        /// <param name="speciesMap"></param>
        public IBMConvectiveCFLConstraint(
            CNSControl config, GridData gridData, CNSFieldSet workingSet, ISpeciesMap speciesMap)
            : base(gridData, workingSet)
        {
            this.config     = config;
            this.speciesMap = speciesMap as ImmersedSpeciesMap;

            if (speciesMap == null)
            {
                throw new ArgumentException(
                          "This type requires an instance of 'ImmersedSpeciesMap'",
                          "speciesMap");
            }
        }
示例#23
0
 /// <summary>
 /// Perfoms a complete time convergence study, i.e on the same grid several runs are done with decreasing constant timestep.
 /// </summary>
 /// <param name="timeLevel">Number of refinement levels</param>
 /// <param name="dtStart">Starting timestep, i.e coarsest timesteps</param>
 /// <param name="order">Explicite timestepping order</param>
 /// <param name="timeStepper">Explicte timestepping scheme, default: Local Timestepping (LTS)</param>
 /// <returns></returns>
 public static CNSControl[] Gassner2DStudy_time(int timeLevel, double dtStart, int order, string timeStepper = "LTS")
 {
     CNSControl[] controls = new CNSControl[timeLevel];
     for (int i = 0; i < timeLevel; i++)
     {
         double factor = Math.Pow(2, i);
         double dt     = dtStart / factor;
         controls[i] = Gassner2D_time(dt, order, timeStepper);
         controls[i].Paramstudy_ContinueOnError    = true;
         controls[i].Paramstudy_CaseIdentification = new Tuple <string, object>[] {
             new Tuple <string, object>("dt", dt)
         };
     }
     return(controls);
 }
示例#24
0
        /// <summary>
        /// Does one run with a given timestep on a mesh with a refinment in the middel, i.e 96 cells with h=1/10
        /// and 16 cells with h=1/20, DGorder=11! It is a very fine spatial resolution to measure time discetizations errors
        /// </summary>
        /// <param name="dt">Timestep</param>
        /// <param name="timeStepper">Explicte timestepping scheme</param>
        /// <param name="order">Explicite timestepping order</param>
        /// <returns></returns>
        public static CNSControl Gassner2D_time(double dt, int order, string timeStepper)
        {
            CNSControl c = Gassner2D_conserved(10, 9);

            c.GridFunc = delegate {
                var grid = Grid2D.HangingNodes2D(true, true,
                                                 new GridBox(0, 0, 1, 1, 10),
                                                 new GridBox(0.4, 0.4, 0.6, 0.6, 4)
                                                 );
                grid.Name = "[0,1]x[0,1], h=1/10, Ratio 1:2";
                return(grid);
            };

            c.ReynoldsNumber = 1E7;

            c.CFLFraction = 0.2;
            c.dtMax       = dt;

            c.NoOfTimesteps    = int.MaxValue;
            c.NumberOfSubGrids = 2;
            c.Endtime          = 0.1;

            c.savetodb = true;

            switch (timeStepper)
            {
            case "LTS":
                c.ExplicitScheme = ExplicitSchemes.LTS;
                break;

            case "AB":
            case "AdamsBashforth":
                c.ExplicitScheme = ExplicitSchemes.AdamsBashforth;
                break;

            case "RK":
            case "RungeKutta":
                c.ExplicitScheme = ExplicitSchemes.RungeKutta;
                break;
            }
            c.ResidualLoggerType = ResidualLoggerTypes.Query;
            c.ResidualInterval   = 100;
            c.PrintInterval      = 100;
            c.ExplicitOrder      = order;
            c.ProjectName        = "TimeMMS_" + c.ExplicitScheme + c.ExplicitOrder + "_dt=" + dt;
            return(c);
        }
示例#25
0
        /// <summary>
        /// ctor
        /// </summary>
        /// <param name="config">Configuration options</param>
        /// <param name="boundaryMap">Boundary value definition</param>
        /// <param name="speciesMap">Mapping that determines the active species in some point</param>
        /// <param name="gridData"></param>
        /// <param name="cellMetric"></param>
        public SIPGFlux(CNSControl config, IBoundaryConditionMap boundaryMap, ISpeciesMap speciesMap, GridData gridData, Func <MultidimensionalArray> cellMetric)
        {
            this.config         = config;
            this.boundaryMap    = boundaryMap;
            this.speciesMap     = speciesMap;
            this.gridData       = gridData;
            this.dimension      = CNSEnvironment.NumberOfDimensions;
            this.cellMetricFunc = cellMetric;

            //Fills the dictionary, to avoid later string comparison
            foreach (byte edgeTag in gridData.Edges.EdgeTags)
            {
                if (boundaryMap.EdgeTagNames[edgeTag].StartsWith("adiabaticWall", StringComparison.InvariantCultureIgnoreCase))
                {
                    edgeTagBool[edgeTag] = true;
                }
                else
                {
                    edgeTagBool[edgeTag] = false;
                }
            }
            // calculation of the penalty factor
            double p = new int[] { config.DensityDegree, config.MomentumDegree, config.EnergyDegree }.Max();

            penaltyFactor = config.SIPGPenaltyScaling * p * p;

            //defining some constants
            double alpha = config.ViscosityRatio;

            alphaPlus43  = alpha + (4.0 / 3.0);
            alphaPlus13  = alpha + (1.0 / 3.0);
            alphaMinus23 = alpha - (2.0 / 3.0);

            stateIn  = new StateVector(new double[dimension + 2], speciesMap.GetMaterial(double.NaN));
            stateOut = new StateVector(new double[dimension + 2], speciesMap.GetMaterial(double.NaN));

            if (config.EquationOfState is IdealGas == false)
            {
                throw new Exception("SIPG flux currently only works for ideal gases");
            }

            GTensorIn  = new double[dimension, dimension, dimension + 2];
            GTensorOut = new double[dimension, dimension, dimension + 2];
        }
示例#26
0
        public static CNSControl[] BumpStudy(int noOfGridLevels, int maxDgDegree, double CFL, int minDgDegree = 0)
        {
            CNSControl[] controls = new CNSControl[noOfGridLevels * ((maxDgDegree - minDgDegree) + 1)];

            for (int i = minDgDegree; i <= maxDgDegree; i++)
            {
                for (int j = 0; j < noOfGridLevels; j++)
                {
                    int noOfCells = (int)Math.Pow(2, 3 + j);
                    controls[(i - minDgDegree) * noOfGridLevels + j] = Bump(noOfCells, i, CFL);
                    controls[(i - minDgDegree) * noOfGridLevels + j].Paramstudy_ContinueOnError    = true;
                    controls[(i - minDgDegree) * noOfGridLevels + j].Paramstudy_CaseIdentification = new Tuple <string, object>[] {
                        new Tuple <string, object>("refinement+dgDegree", i * 100 + noOfCells)
                    };
                }
            }

            return(controls);
        }
示例#27
0
        /// <summary>
        /// Fixed run for a convergence study of Local Timestepping (LTS) for 2 and 3 order
        /// -c cs:CNS.Tests.MMS.MMS_unsteady.Gassner2DStudy_LTS(4)
        /// </summary>
        /// <param name="timeLevel">Number of refinement levels</param>
        /// <returns></returns>
        public static CNSControl[] Gassner2DStudy_LTS(int timeLevel)
        {
            CNSControl[] controls = new CNSControl[2 * timeLevel];
            int          ii       = 0;
            double       dt       = 3.8E-4;

            CNSControl[] OneOrderSet = Gassner2DStudy_time(timeLevel, dt, 3);
            foreach (CNSControl run in OneOrderSet)
            {
                controls[ii] = run;
                ii++;
            }
            OneOrderSet = Gassner2DStudy_time(timeLevel, dt, 2);
            foreach (CNSControl run in OneOrderSet)
            {
                controls[ii] = run;
                ii++;
            }

            return(controls);
        }
示例#28
0
        /// <summary>
        /// <see cref="BoundaryCondition"/>
        /// </summary>
        /// <param name="config"><see cref="BoundaryCondition"/></param>
        /// <param name="temperatureFunction">
        /// The predefined temperature
        /// </param>
        /// <param name="wallVelocities">
        /// Optional wall velocity (individual formula for each direction)
        /// </param>
        public IsothermalWall(CNSControl config, Func <double[], double, double> temperatureFunction, Func <double[], double, double>[] wallVelocities = null)
            : base(config)
        {
            this.TemperatureFunction = temperatureFunction;
            this.WallVelocities      = wallVelocities;

            if (wallVelocities != null)
            {
                if (wallVelocities.Length != CNSEnvironment.NumberOfDimensions)
                {
                    throw new Exception();
                }

                for (int d = 0; d < wallVelocities.Length; d++)
                {
                    if (wallVelocities[d] == null)
                    {
                        throw new Exception();
                    }
                }
            }
        }
示例#29
0
        /// <summary>
        /// Performs a convergence study for Euler equations in 1D and uses
        /// a manufactured solution <see cref="Euler1D(int, int)"/>
        /// </summary>
        /// <param name="maxDgDegree"></param>
        /// <param name="refinements"></param>
        /// <returns></returns>
        public static CNSControl[] Euler1D_Study(int maxDgDegree, int refinements)
        {
            List <CNSControl> controls = new List <CNSControl>();
            int ii = 0;

            for (int i = 0; i <= maxDgDegree; i++)
            {
                for (int j = 0; j < refinements; j++)
                {
                    int        noOfCells = (int)Math.Pow(2, 3 + j);
                    CNSControl c         = Euler1D(i, noOfCells);
                    c.Paramstudy_ContinueOnError    = true;
                    c.Paramstudy_CaseIdentification = new Tuple <string, object>[] {
                        new Tuple <string, object>("dgDegree", i),
                        new Tuple <string, object>("refinement", j),
                    };
                    controls.Add(c);
                    ii++;
                }
            }
            return(controls.ToArray());
        }
示例#30
0
        /// <summary>
        /// Performs a convergence study for the compressible Navier-Stokes equations in 2D
        /// and uses a manufactured solution <see cref="Gassner2D_conserved(int, int, string)"/>
        /// </summary>
        /// <param name="noOfRefinements"></param>
        /// <param name="maxDegree"></param>
        /// <param name="minDegree"></param>
        /// <param name="dbPath"></param>
        /// <returns></returns>
        public static CNSControl[] Gassner2DStudy_conserved(int noOfRefinements, int maxDegree, int minDegree = 1, string dbPath = @"c:\bosss_dbv2\exp")
        {
            CNSControl[] controls = new CNSControl[(maxDegree + 1 - minDegree) * noOfRefinements];
            int          ii       = 0;

            for (int i = minDegree; i <= maxDegree; i++)
            {
                for (int j = 0; j < noOfRefinements; j++)
                {
                    double power = 3 + (double)j;
                    int    noOfCellsPerDirection = (int)Math.Pow(2, power);
                    controls[ii]          = Gassner2D_conserved(noOfCellsPerDirection, i, dbPath);
                    controls[ii].savetodb = true;
                    controls[ii].Paramstudy_ContinueOnError    = true;
                    controls[ii].Paramstudy_CaseIdentification = new Tuple <string, object>[] {
                        new Tuple <string, object>("divisions", i),
                        new Tuple <string, object>("dgDegree", i)
                    };
                    ii++;
                }
            }
            return(controls);
        }