/// <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); }
/// <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 + "\""); } }
/// <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; }
/// <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; }
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; }
/// <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; }
/// <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; } }
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]; }
/// <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 + "\""); } }
/// <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"); } }
/// <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"); } }
/// <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; }
/// <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(); } }
/// <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; } }
/// <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(); } }
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(); } }
/// <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"); } } }
/// <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>(); }
/// <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"); } }
/// <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); }
/// <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); }
/// <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]; }
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); }
/// <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); }
/// <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(); } } } }
/// <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()); }
/// <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); }