/// <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, CompressibleBoundaryCondMap 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> /// 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, IGridData gridData, CNSFieldSet workingSet, ISpeciesMap speciesMap, CompressibleBoundaryCondMap 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> /// <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> /// 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, CompressibleBoundaryCondMap 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> /// Constructs a new operator factory which additionally implements /// the boundary conditions at immersed boundaries. /// </summary> /// <param name="control"></param> /// <param name="gridData"></param> /// <param name="workingSet"></param> /// <param name="speciesMap"></param> /// <param name="boundaryMap"></param> public IBMOperatorFactory( IBMControl control, IGridData gridData, CNSFieldSet workingSet, ISpeciesMap speciesMap, CompressibleBoundaryCondMap boundaryMap) : base(control, gridData, workingSet, speciesMap, boundaryMap) { this.immersedBoundaryFluxBuilders.Add(new BoundaryConditionSourceFluxBuilder( control, boundaryMap, speciesMap, convectiveFluxBuilder, diffusiveFluxBuilder)); }
/// <summary> /// Constructs a new flux builder where the boundary conditions are /// evaluated using the convective fluxes defined by /// <paramref name="convectiveBuilder"/>. /// </summary> /// <param name="control"></param> /// <param name="boundaryMap"></param> /// <param name="speciesMap"></param> /// <param name="convectiveBuilder"></param> /// <param name="diffusiveBuilder"></param> public BoundaryConditionSourceFluxBuilder( IBMControl control, CompressibleBoundaryCondMap boundaryMap, ISpeciesMap speciesMap, FluxBuilder convectiveBuilder, FluxBuilder diffusiveBuilder) : base(control, boundaryMap, speciesMap) { standardOperator = new Operator(control); if (convectiveBuilder != null) { convectiveBuilder.BuildFluxes(standardOperator); } if (diffusiveBuilder != null) { diffusiveBuilder.BuildFluxes(standardOperator); } string levelSetBoundaryType = control.LevelSetBoundaryTag; boundaryCondition = boundaryMap.GetBoundaryCondition(levelSetBoundaryType); }
/// <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, CompressibleBoundaryCondMap boundaryMap, ISpeciesMap speciesMap, IGridData gridData, Func <MultidimensionalArray> cellMetric) { this.config = config; this.boundaryMap = boundaryMap; this.speciesMap = speciesMap; this.gridData = gridData; this.dimension = CompressibleEnvironment.NumberOfDimensions; this.cellMetricFunc = cellMetric; foreach (byte edgeTag in boundaryMap.EdgeTag2EdgeTagName.Keys) { edgeTagBool[edgeTag] = (boundaryMap.EdgeTag2Type[edgeTag] == CompressibleBcType.adiabaticWall); } // 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 SpatialOperator BuildEulerOperator(IGridData gridData, CompressibleControl control) { // Boundary condition map Material material = control.GetMaterial(); IBoundaryConditionMap boundaryMap = new CompressibleBoundaryCondMap(gridData, control, material); // Initialize operator SpatialOperator EulerOperator = new SpatialOperator( new string[] { CompressibleVariables.Density, CompressibleVariables.Momentum.xComponent, CompressibleVariables.Momentum.yComponent, CompressibleVariables.Energy }, new string[] { }, new string[] { CompressibleVariables.Density, CompressibleVariables.Momentum.xComponent, CompressibleVariables.Momentum.yComponent, CompressibleVariables.Energy }, QuadOrderFunc.NonLinearWithoutParameters(2) ); // Map fluxes EulerOperator.EquationComponents[CompressibleVariables.Density].Add(new OptimizedHLLCDensityFlux(boundaryMap, material)); EulerOperator.EquationComponents[CompressibleVariables.Momentum.xComponent].Add(new OptimizedHLLCMomentumFlux(boundaryMap, 0, material)); EulerOperator.EquationComponents[CompressibleVariables.Momentum.yComponent].Add(new OptimizedHLLCMomentumFlux(boundaryMap, 1, material)); EulerOperator.EquationComponents[CompressibleVariables.Energy].Add(new OptimizedHLLCEnergyFlux(boundaryMap, material)); EulerOperator.Commit(); return(EulerOperator); }
/// <summary> /// Constructs a new flux builder. /// </summary> /// <param name="control"></param> /// <param name="boundaryMap"></param> /// <param name="speciesMap"></param> /// <param name="gridData"></param> public SIPGFluxBuilder(CNSControl control, CompressibleBoundaryCondMap boundaryMap, ISpeciesMap speciesMap, IGridData 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; SpeciesId species = IBMspeciesMap.Tracker.GetSpeciesId(IBMspeciesMap.Control.FluidSpeciesName); cellMetricFunc = delegate() { 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 MultidimensionalArray cj = ((GridData)gridData).Cells.cj; cellMetricFunc = () => cj; } }
public OptimizedSIPGEnergyFlux(CNSControl config, CompressibleBoundaryCondMap boundaryMap, ISpeciesMap speciesMap, IGridData 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 boundaryMap.EdgeTag2EdgeTagName.Keys) { edgeTagBool[edgeTag] = (boundaryMap.EdgeTag2Type[edgeTag] == CompressibleBcType.adiabaticWall); } // [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> /// ctor <see cref="SIPGFlux"/> /// </summary> /// <param name="config"><see cref="SIPGFlux"/></param> /// <param name="boundaryMap"><see cref="SIPGFlux"/></param> /// <param name="speciesMap"><see cref="SIPGFlux"/></param> /// <param name="gridData"><see cref="SIPGFlux"/></param> /// <param name="component"><see cref="SIPGFlux"/></param> /// <param name="cellMetricFunc"><see cref="SIPGFlux"/></param> public SIPGDensityFlux(CNSControl config, CompressibleBoundaryCondMap boundaryMap, ISpeciesMap speciesMap, IGridData gridData, int component, Func <MultidimensionalArray> cellMetricFunc) : base(config, boundaryMap, speciesMap, gridData, cellMetricFunc) { this.component = component; }
/// <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, CompressibleBoundaryCondMap 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> /// Builds a new source provider. /// </summary> /// <param name="control"> /// Configuration options. /// </param> /// <param name="boundaryMap"></param> /// <param name="speciesMap"></param> public CustomSourceBuilder(CNSControl control, CompressibleBoundaryCondMap boundaryMap, ISpeciesMap speciesMap) : base(control, boundaryMap, speciesMap) { }
/// <summary> /// /// </summary> /// <param name="control"></param> /// <param name="boundaryMap"></param> /// <param name="speciesMap"></param> public SpongeLayerFluxBuilder(CNSControl control, CompressibleBoundaryCondMap boundaryMap, ISpeciesMap speciesMap) : base(control, boundaryMap, speciesMap) { this.config = control.SpongeLayerConfig; }
/// <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, CompressibleBoundaryCondMap boundaryMap, ISpeciesMap speciesMap, IGridData 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> /// Constructs a new flux builder /// </summary> /// <param name="control">Configuration options</param> /// <param name="boundaryMap"> /// The boundary mapping which is required for the construction of the /// specific fluxes. /// </param> /// <param name="speciesMap"> /// The species mapping which is required to determine the active /// equation of state upon evaluation of the fluxes. /// </param> protected FluxBuilder(CNSControl control, CompressibleBoundaryCondMap boundaryMap, ISpeciesMap speciesMap) { this.control = control; this.boundaryMap = boundaryMap; this.speciesMap = speciesMap; }
public LaplacianArtificialViscosityFluxBuilder(CNSControl control, CompressibleBoundaryCondMap boundaryMap, ISpeciesMap speciesMap) : base(control, boundaryMap, speciesMap) { }
/// <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 GodunovFluxBuilder(CNSControl control, CompressibleBoundaryCondMap boundaryMap, ISpeciesMap speciesMap) : base(control, boundaryMap, speciesMap) { }
/// <summary> /// <see cref="FluxBuilder.FluxBuilder"/> /// </summary> /// <param name="control"></param> /// <param name="boundaryMap"></param> /// <param name="speciesMap"></param> public OptimizedHLLCFluxBuilder(CNSControl control, CompressibleBoundaryCondMap boundaryMap, ISpeciesMap speciesMap) : base(control, boundaryMap, speciesMap) { // }