Ejemplo n.º 1
0
        public IBMABevolve(
            SpatialOperator standardOperator,
            SpatialOperator boundaryOperator,
            CoordinateMapping fieldsMap,
            CoordinateMapping parametersMap,
            ISpeciesMap ibmSpeciesMap,
            int explicitOrder,
            int levelSetQuadratureOrder,
            XQuadFactoryHelper.MomentFittingVariants momentFittingVariant,
            SubGrid sgrd,
            bool adaptive = false)
            : base(standardOperator, fieldsMap, parametersMap, explicitOrder, adaptive: adaptive, sgrd: sgrd)
        {
            speciesMap = ibmSpeciesMap as ImmersedSpeciesMap;
            if (speciesMap == null)
            {
                throw new ArgumentException(
                          "Only supported for species maps of type 'ImmersedSpeciesMap'",
                          "speciesMap");
            }

            this.boundaryOperator          = boundaryOperator;
            this.boundaryParameterMap      = parametersMap;
            agglomerationPatternHasChanged = true;
        }
Ejemplo n.º 2
0
        public IBMAdamsBashforth(
            SpatialOperator standardOperator,
            SpatialOperator boundaryOperator,
            CoordinateMapping fieldsMap,
            CoordinateMapping parametersMap,
            ISpeciesMap ibmSpeciesMap,
            IBMControl control,
            IList <TimeStepConstraint> timeStepConstraints)
            : base(standardOperator, fieldsMap, parametersMap, control.ExplicitOrder, timeStepConstraints, ibmSpeciesMap.SubGrid)    // TO DO: I SIMPLY REMOVED PARAMETERMAP HERE; MAKE THIS MORE PRETTY
        {
            speciesMap = ibmSpeciesMap as ImmersedSpeciesMap;
            if (this.speciesMap == null)
            {
                throw new ArgumentException(
                          "Only supported for species maps of type 'ImmersedSpeciesMap'",
                          "speciesMap");
            }

            this.boundaryOperator          = boundaryOperator;
            this.boundaryParameterMap      = parametersMap;
            agglomerationPatternHasChanged = true;

            // StarUp Phase needs also an IBM time stepper
            RungeKuttaScheme = new IBMSplitRungeKutta(
                standardOperator,
                boundaryOperator,
                fieldsMap,
                parametersMap,
                speciesMap,
                timeStepConstraints);
        }
Ejemplo n.º 3
0
        /// <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);
        }
Ejemplo n.º 4
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;
 }
Ejemplo n.º 5
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(CompressibleControl config, IBoundaryConditionMap boundaryMap, IEulerEquationComponent equationComponent, ISpeciesMap speciesMap)
 {
     this.config            = config;
     this.boundaryMap       = boundaryMap;
     this.equationComponent = equationComponent;
     this.speciesMap        = speciesMap;
 }
Ejemplo n.º 6
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];
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Projects the initial level set after calling
        /// <see cref="CNSFieldSet.ProjectInitialValues"/>
        /// </summary>
        /// <param name="speciesMap"></param>
        /// <param name="initialValues"></param>
        public override void ProjectInitialValues(ISpeciesMap speciesMap, IDictionary <string, Func <double[], double> > initialValues)
        {
            LevelSet.ProjectField(NonVectorizedScalarFunction.Vectorize(
                                      X => config.LevelSetFunction(X, 0.0)));
            speciesMap.As <ImmersedSpeciesMap>().Tracker.UpdateTracker(0.0);

            base.ProjectInitialValues(speciesMap, initialValues);
        }
Ejemplo n.º 8
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;
 }
Ejemplo n.º 9
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;
        }
Ejemplo n.º 10
0
        /// <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;
            }
        }
Ejemplo n.º 11
0
 /// <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,
     GridData gridData,
     CNSFieldSet workingSet,
     ISpeciesMap speciesMap,
     IBoundaryConditionMap boundaryMap)
     : base(control, gridData, workingSet, speciesMap, boundaryMap)
 {
     this.immersedBoundaryFluxBuilders.Add(new BoundaryConditionSourceFluxBuilder(
                                               control, boundaryMap, speciesMap, convectiveFluxBuilder, diffusiveFluxBuilder));
 }
Ejemplo n.º 12
0
        /// <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();
            }
        }
Ejemplo n.º 13
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();
            }
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Projects the given <paramref name="initialValues"/> onto the
        /// conservative variable fields <see cref="Density"/>,
        /// <see cref="Momentum"/> and <see cref="Energy"/>. Initial values
        /// may either be given in conservative (see
        /// <see cref="VariableTypes.ConservativeVariables"/>) or primitive
        /// (see <see cref="VariableTypes.PrimitiveVariables"/>) variables
        /// </summary>
        /// <param name="speciesMap"></param>
        /// <param name="initialValues">
        /// The given initial value functions, where the dictionary keys
        /// represent variable names.
        /// </param>
        public virtual void ProjectInitialValues(ISpeciesMap speciesMap, IDictionary <string, Func <double[], double> > initialValues)
        {
            int numberOfDimensions      = CNSEnvironment.NumberOfDimensions;
            CellQuadratureScheme scheme = new CellQuadratureScheme(true, speciesMap.SubGrid.VolumeMask);

            if (config.GetInitialValueVariables() == VariableTypes.ConservativeVariables)
            {
                Density.ProjectField(1.0, initialValues[Variables.Density], scheme);

                for (int d = 0; d < numberOfDimensions; d++)
                {
                    Momentum[d].ProjectField(1.0, initialValues[Variables.Momentum[d]], scheme);
                }

                Energy.ProjectField(1.0, initialValues[Variables.Energy], scheme);
            }
            else if (config.GetInitialValueVariables() == VariableTypes.PrimitiveVariables)
            {
                var densityFunction = initialValues[Variables.Density];
                Density.ProjectField(1.0, densityFunction, scheme);

                Func <double[], double>[] velocityFunctions = new Func <double[], double> [numberOfDimensions];
                for (int d = 0; d < numberOfDimensions; d++)
                {
                    velocityFunctions[d] = initialValues[Variables.Velocity[d]];
                    Momentum[d].ProjectField(1.0, X => densityFunction(X) * velocityFunctions[d](X), scheme);
                }

                var pressureFunction = initialValues[Variables.Pressure];
                Energy.ProjectField(
                    1.0,
                    delegate(double[] X) {
                    double rho = densityFunction(X);
                    double p   = pressureFunction(X);

                    Vector u = new Vector(numberOfDimensions);
                    for (int d = 0; d < numberOfDimensions; d++)
                    {
                        u[d] = velocityFunctions[d](X);
                    }

                    StateVector state = StateVector.FromPrimitiveQuantities(
                        speciesMap.GetMaterial(double.NaN), rho, u, p);
                    return(state.Energy);
                },
                    scheme);
            }
            else
            {
                throw new ArgumentException(
                          "Please specify initial values either in primitive or in conservative variables");
            }
        }
Ejemplo n.º 15
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();
            }
        }
Ejemplo n.º 16
0
        public static IBMRungeKutta CreateRungeKuttaTimeStepper(
            this TimesteppingStrategies strategy,
            IBMControl control,
            OperatorFactory equationSystem,
            CNSFieldSet fieldSet,
            CoordinateMapping parameterMap,
            ISpeciesMap speciesMap,
            IList <TimeStepConstraint> timeStepConstraints)
        {
            ImmersedSpeciesMap ibmSpeciesMap = speciesMap as ImmersedSpeciesMap;

            if (ibmSpeciesMap == null)
            {
                throw new ArgumentException(
                          "Only supported for species maps of type 'ImmersedSpeciesMap'",
                          "speciesMap");
            }

            IBMOperatorFactory ibmFactory = equationSystem as IBMOperatorFactory;

            if (ibmFactory == null)
            {
                throw new Exception();
            }

            CoordinateMapping variableMap = new CoordinateMapping(fieldSet.ConservativeVariables);

            switch (strategy)
            {
            case TimesteppingStrategies.LieSplitting:
            case TimesteppingStrategies.StrangSplitting:
                return(new IBMSplitRungeKutta(
                           equationSystem.GetJoinedOperator().ToSpatialOperator(fieldSet),
                           ibmFactory.GetImmersedBoundaryOperator().ToSpatialOperator(fieldSet),
                           variableMap,
                           parameterMap,
                           ibmSpeciesMap,
                           timeStepConstraints));

            case TimesteppingStrategies.MovingFrameFlux:
                return(new IBMMovingFrameRungeKutta(
                           equationSystem.GetJoinedOperator().ToSpatialOperator(fieldSet),
                           ibmFactory.GetImmersedBoundaryOperator().ToSpatialOperator(fieldSet),
                           variableMap,
                           parameterMap,
                           ibmSpeciesMap,
                           timeStepConstraints));

            default:
                throw new System.NotImplementedException();
            }
        }
Ejemplo n.º 17
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");
            }
        }
Ejemplo n.º 18
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];
        }
        /// <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, BoundaryConditionMap 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);
        }
Ejemplo n.º 20
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, 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];
        }
Ejemplo n.º 21
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 SIPGFluxBuilder(CNSControl control, BoundaryConditionMap 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;
            }
        }
Ejemplo n.º 22
0
        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];
        }
Ejemplo n.º 23
0
        /// <summary>
        /// Creates the appropriate time-stepper for a given
        /// <paramref name="timeStepperType"/>
        /// </summary>
        /// <param name="timeStepperType">
        /// The type of the time-stepper (e.g., Runge-Kutta) to be created
        /// </param>
        /// <param name="control">
        /// Configuration options
        /// </param>
        /// <param name="equationSystem">
        /// The equation system to be solved
        /// </param>
        /// <param name="fieldSet">
        /// Fields affected by the time-stepper
        /// </param>
        /// <param name="parameterMap">
        /// Fields serving as parameter for the time-stepper.
        /// </param>
        /// <param name="speciesMap">
        /// Mapping of different species inside the domain
        /// </param>
        /// <param name="program"></param>
        /// <returns>
        /// Depending on <paramref name="timeStepperType"/>, an appropriate
        /// implementation of <see cref="ITimeStepper"/>.
        /// </returns>
        /// <remarks>
        /// Currently limiting is not supported for Adams-Bashforth methods
        /// </remarks>
        public static ITimeStepper Instantiate <T>(
            this ExplicitSchemes timeStepperType,
            CNSControl control,
            OperatorFactory equationSystem,
            CNSFieldSet fieldSet,
            CoordinateMapping parameterMap,
            ISpeciesMap speciesMap,
            IProgram <T> program)
            where T : CNSControl, new()
        {
            CoordinateMapping variableMap = new CoordinateMapping(fieldSet.ConservativeVariables);

            IBMControl         ibmControl = control as IBMControl;
            IBMOperatorFactory ibmFactory = equationSystem as IBMOperatorFactory;

            if (control.DomainType != DomainTypes.Standard &&
                (ibmFactory == null || ibmControl == null))
            {
                throw new Exception();
            }

            ITimeStepper timeStepper;

            switch (timeStepperType)
            {
            case ExplicitSchemes.RungeKutta when control.DomainType == DomainTypes.Standard:
                timeStepper = new RungeKutta(
                    RungeKutta.GetDefaultScheme(control.ExplicitOrder),
                    equationSystem.GetJoinedOperator().ToSpatialOperator(fieldSet),
                    variableMap,
                    parameterMap,
                    equationSystem.GetJoinedOperator().CFLConstraints);
                break;

            case ExplicitSchemes.RungeKutta:
                timeStepper = ibmControl.TimesteppingStrategy.CreateRungeKuttaTimeStepper(
                    ibmControl,
                    equationSystem,
                    fieldSet,
                    parameterMap,
                    speciesMap,
                    equationSystem.GetJoinedOperator().CFLConstraints);
                break;

            case ExplicitSchemes.AdamsBashforth when control.DomainType == DomainTypes.Standard:
                timeStepper = new AdamsBashforth(
                    equationSystem.GetJoinedOperator().ToSpatialOperator(fieldSet),
                    variableMap,
                    parameterMap,
                    control.ExplicitOrder,
                    equationSystem.GetJoinedOperator().CFLConstraints);
                break;

            case ExplicitSchemes.AdamsBashforth:
                timeStepper = new IBMAdamsBashforth(
                    ibmFactory.GetJoinedOperator().ToSpatialOperator(fieldSet),
                    ibmFactory.GetImmersedBoundaryOperator().ToSpatialOperator(fieldSet),
                    variableMap,
                    parameterMap,
                    speciesMap,
                    ibmControl,
                    equationSystem.GetJoinedOperator().CFLConstraints);
                break;

            case ExplicitSchemes.LTS when control.DomainType == DomainTypes.Standard:
                timeStepper = new AdamsBashforthLTS(
                    equationSystem.GetJoinedOperator().ToSpatialOperator(fieldSet),
                    variableMap,
                    parameterMap,
                    control.ExplicitOrder,
                    control.NumberOfSubGrids,
                    equationSystem.GetJoinedOperator().CFLConstraints,
                    reclusteringInterval: control.ReclusteringInterval,
                    fluxCorrection: control.FluxCorrection,
                    saveToDBCallback: program.SaveToDatabase,
                    maxNumOfSubSteps: control.maxNumOfSubSteps,
                    forceReclustering: control.forceReclustering,
                    logging: control.WriteLTSLog,
                    consoleOutput: control.WriteLTSConsoleOutput);
                break;

            case ExplicitSchemes.LTS:
                timeStepper = new IBMAdamsBashforthLTS(
                    equationSystem.GetJoinedOperator().ToSpatialOperator(fieldSet),
                    ibmFactory.GetImmersedBoundaryOperator().ToSpatialOperator(fieldSet),
                    variableMap,
                    parameterMap,
                    speciesMap,
                    ibmControl,
                    equationSystem.GetJoinedOperator().CFLConstraints,
                    reclusteringInterval: control.ReclusteringInterval,
                    fluxCorrection: control.FluxCorrection,
                    maxNumOfSubSteps: control.maxNumOfSubSteps,
                    forceReclustering: control.forceReclustering,
                    logging: control.WriteLTSLog,
                    consoleOutput: control.WriteLTSConsoleOutput);
                break;

            case ExplicitSchemes.Rock4 when control.DomainType == DomainTypes.Standard:
                timeStepper = new ROCK4(equationSystem.GetJoinedOperator().ToSpatialOperator(fieldSet), new CoordinateVector(variableMap), null);
                break;

            case ExplicitSchemes.SSP54 when control.DomainType == DomainTypes.Standard:
                timeStepper = new RungeKutta(
                    RungeKuttaScheme.SSP54,
                    equationSystem.GetJoinedOperator().ToSpatialOperator(fieldSet),
                    variableMap,
                    parameterMap,
                    equationSystem.GetJoinedOperator().CFLConstraints);
                break;

            case ExplicitSchemes.RKC84 when control.DomainType == DomainTypes.Standard:
                timeStepper = new RungeKutta(
                    RungeKuttaScheme.RKC84,
                    equationSystem.GetJoinedOperator().ToSpatialOperator(fieldSet),
                    variableMap,
                    parameterMap,
                    equationSystem.GetJoinedOperator().CFLConstraints);
                break;

            case ExplicitSchemes.None:
                throw new System.ArgumentException("Cannot instantiate empty scheme");

            default:
                throw new NotImplementedException(String.Format(
                                                      "Explicit time stepper type '{0}' not implemented for domain type '{1}'",
                                                      timeStepperType,
                                                      control.DomainType));
            }

            // Make sure shock sensor is updated before every flux evaluation
            if (control.CNSShockSensor != null)
            {
                ExplicitEuler explicitEulerBasedTimestepper = timeStepper as ExplicitEuler;
                if (explicitEulerBasedTimestepper == null)
                {
                    throw new Exception(String.Format(
                                            "Shock-capturing currently not implemented for time-steppers of type '{0}'",
                                            timeStepperType));
                }

                explicitEulerBasedTimestepper.OnBeforeComputeChangeRate += delegate(double absTime, double relTime) {
                    // Note: Only shock sensor is updated, _NOT_ the corresponding variable
                    program.Control.CNSShockSensor.UpdateSensorValues(
                        program.WorkingSet.AllFields,
                        program.SpeciesMap,
                        explicitEulerBasedTimestepper.SubGrid.VolumeMask);
                    // Note: When being called, artificial viscosity is updated in the _ENTIRE_ (fluid) domain
                    var avField = program.WorkingSet.DerivedFields[CNSVariables.ArtificialViscosity];
                    CNSVariables.ArtificialViscosity.UpdateFunction(avField, program.SpeciesMap.SubGrid.VolumeMask, program);

                    // Test
                    //double sensorNorm = program.WorkingSet.DerivedFields[CNSVariables.ShockSensor].L2Norm();
                    //double avNorm = program.WorkingSet.DerivedFields[CNSVariables.ArtificialViscosity].L2Norm();
                    //Console.WriteLine("\r\nThis is OnBeforeComputeChangeRate");
                    //Console.WriteLine("SensorNeu: {0}", sensorNorm);
                    //Console.WriteLine("AVNeu: {0}", avNorm);
                };
            }

            // Make sure limiter is applied after each modification of conservative variables
            if (control.Limiter != null)
            {
                ExplicitEuler explicitEulerBasedTimestepper = timeStepper as ExplicitEuler;
                if (explicitEulerBasedTimestepper == null)
                {
                    throw new Exception(String.Format(
                                            "Limiting currently not implemented for time-steppers of type '{0}~",
                                            timeStepperType));
                }

                explicitEulerBasedTimestepper.OnAfterFieldUpdate +=
                    (t, f) => control.Limiter.LimitFieldValues(program.WorkingSet.ConservativeVariables, program.WorkingSet.DerivedFields.Values);
            }

            return(timeStepper);
        }
Ejemplo n.º 24
0
        public IBMAdamsBashforthLTS(SpatialOperator standardOperator, SpatialOperator boundaryOperator, CoordinateMapping fieldsMap, CoordinateMapping boundaryParameterMap, ISpeciesMap ibmSpeciesMap, IBMControl control, IList <TimeStepConstraint> timeStepConstraints, int reclusteringInterval, bool fluxCorrection, bool forceReclustering, int maxNumOfSubSteps = 0, bool logging = false, bool consoleOutput = false)
            : base(standardOperator, fieldsMap, boundaryParameterMap, control.ExplicitOrder, control.NumberOfSubGrids, true, timeStepConstraints, reclusteringInterval: reclusteringInterval, fluxCorrection: fluxCorrection, subGrid: ibmSpeciesMap.SubGrid, forceReclustering: forceReclustering, logging: logging, consoleOutput: consoleOutput)
        {
            this.speciesMap = ibmSpeciesMap as ImmersedSpeciesMap;
            if (this.speciesMap == null)
            {
                throw new ArgumentException(
                          "Only supported for species maps of type 'ImmersedSpeciesMap'",
                          "speciesMap");
            }
            this.standardOperator     = standardOperator;
            this.boundaryOperator     = boundaryOperator;
            this.boundaryParameterMap = boundaryParameterMap;
            this.fieldsMap            = fieldsMap;
            this.control = control;

            agglomerationPatternHasChanged = true;

            cutCells          = speciesMap.Tracker.Regions.GetCutCellMask();
            cutAndTargetCells = cutCells.Union(speciesMap.Agglomerator.AggInfo.TargetCells);

            if (consoleOutput)
            {
                Console.WriteLine("### This is IBM ABLTS ctor ###");
            }

            // Normal LTS constructor
            clusterer         = new Clusterer(this.gridData, maxNumOfSubSteps, cellAgglomerator: speciesMap.Agglomerator);
            CurrentClustering = clusterer.CreateClustering(control.NumberOfSubGrids, this.TimeStepConstraints, speciesMap.SubGrid);
            CurrentClustering = clusterer.TuneClustering(CurrentClustering, Time, this.TimeStepConstraints); // Might remove sub-grids when time step sizes are too similar

            ABevolver = new IBMABevolve[CurrentClustering.NumberOfClusters];

            for (int i = 0; i < ABevolver.Length; i++)
            {
                ABevolver[i] = new IBMABevolve(standardOperator, boundaryOperator, fieldsMap, boundaryParameterMap, speciesMap, control.ExplicitOrder, control.LevelSetQuadratureOrder, control.CutCellQuadratureType, sgrd: CurrentClustering.Clusters[i], adaptive: this.adaptive);
                ABevolver[i].OnBeforeComputeChangeRate += (t1, t2) => this.RaiseOnBeforeComputechangeRate(t1, t2);
            }

            GetBoundaryTopology();

            // Start-up phase needs an IBM Runge-Kutta time stepper
            RungeKuttaScheme = new IBMSplitRungeKutta(standardOperator, boundaryOperator, fieldsMap, boundaryParameterMap, speciesMap, timeStepConstraints);
        }
Ejemplo n.º 25
0
 /// <summary>
 /// Constructs a new flux
 /// </summary>
 /// <param name="config">
 /// Configuration options
 /// </param>
 /// <param name="speciesMap">
 /// Species map. Only support ideal gas in the entire domain.
 /// </param>
 /// <param name="boundaryMap">
 /// Mapping for boundary conditions
 /// </param>
 public OptimizedHLLCEnergyFlux(CNSControl config, ISpeciesMap speciesMap, IBoundaryConditionMap boundaryMap)
     : base(config, speciesMap, boundaryMap)
 {
 }
Ejemplo n.º 26
0
 /// <summary>
 /// Constructs a new flux
 /// </summary>
 /// <param name="config">
 /// Configuration options
 /// </param>
 /// <param name="speciesMap">
 /// Species map. Only support ideal gas in the entire domain.
 /// </param>
 /// <param name="boundaryMap">
 /// Mapping for boundary conditions
 /// </param>
 /// <param name="component">
 /// The component of the momentum vector.
 /// </param>
 public OptimizedHLLCMomentumFlux(CNSControl config, ISpeciesMap speciesMap, IBoundaryConditionMap boundaryMap, int component)
     : base(config, speciesMap, boundaryMap)
 {
     this.component = component;
 }
Ejemplo n.º 27
0
 /// <summary>
 /// Constructs a source term represented by the given
 /// <paramref name="formula"/>.
 /// </summary>
 /// <param name="speciesMap"></param>
 /// <param name="formula">
 /// A formula representing the actual source term.
 /// </param>
 public AdHocSourceTerm(ISpeciesMap speciesMap, Func <double[], double, StateVector, double> formula)
 {
     this.speciesMap       = speciesMap;
     this.formula          = formula;
     this.argumentOrdering = CompressibleEnvironment.PrimalArgumentOrdering;
 }
Ejemplo n.º 28
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 GodunovFluxBuilder(CNSControl control, CompressibleBoundaryCondMap boundaryMap, ISpeciesMap speciesMap)
     : base(control, boundaryMap, speciesMap)
 {
 }
Ejemplo n.º 29
0
 public LaplacianArtificialViscosityFluxBuilder(CNSControl control, IBoundaryConditionMap boundaryMap, ISpeciesMap speciesMap)
     : base(control, boundaryMap, speciesMap)
 {
 }
Ejemplo n.º 30
0
        public void UpdateSensorValues(CNSFieldSet fieldSet, ISpeciesMap speciesMap, CellMask cellMask)
        {
            DGField fieldToTest = fieldSet.ConservativeVariables.
                                  Concat(fieldSet.DerivedFields.Values).
                                  Where(f => f.Identification == sensorVariable.Name).
                                  Single();
            int degree    = fieldToTest.Basis.Degree;
            int noOfCells = fieldToTest.GridDat.iLogicalCells.NoOfLocalUpdatedCells;

            if (sensorValues == null || sensorValues.Length != noOfCells)
            {
                sensorValues = new double[noOfCells];
            }

            IMatrix coordinatesTimesMassMatrix;
            IMatrix coordinatesTruncatedTimesMassMatrix;

            if (speciesMap is ImmersedSpeciesMap ibmMap)
            {
                // Note: This has to be the _non_-agglomerated mass matrix
                // because we still live on the non-agglomerated mesh at this
                // point
                BlockMsrMatrix massMatrix = ibmMap.GetMassMatrixFactory(fieldToTest.Mapping).NonAgglomeratedMassMatrix;

                // Old
                DGField temp = fieldToTest.CloneAs();
                massMatrix.SpMV(1.0, fieldToTest.CoordinateVector, 0.0, temp.CoordinateVector);
                coordinatesTimesMassMatrix = temp.Coordinates;

                // Neu
                DGField uTruncated = fieldToTest.CloneAs();

                // Set all coordinates to zero
                for (int cell = 0; cell < uTruncated.Coordinates.NoOfRows; cell++)
                {
                    for (int coordinate = 0; coordinate < uTruncated.Coordinates.NoOfCols; coordinate++)
                    {
                        uTruncated.Coordinates[cell, coordinate] = 0;
                    }
                }

                // Copy only the coordiantes that belong to the highest modes
                foreach (int cell in cellMask.ItemEnum)
                {
                    foreach (int coordinate in fieldToTest.Basis.GetPolynomialIndicesForDegree(cell, degree))
                    {
                        uTruncated.Coordinates[cell, coordinate] = fieldToTest.Coordinates[cell, coordinate];
                    }
                }

                // Calculate M times u
                DGField vecF_Field = fieldToTest.CloneAs();
                massMatrix.SpMV(1.0, uTruncated.CoordinateVector, 0.0, vecF_Field.CoordinateVector);
                coordinatesTruncatedTimesMassMatrix = vecF_Field.Coordinates;
            }
            else
            {
                // Mass matrix is identity
                coordinatesTimesMassMatrix          = fieldToTest.Coordinates;
                coordinatesTruncatedTimesMassMatrix = fieldToTest.Coordinates;
            }
            //IMatrix coordinatesTimesMassMatrix = fieldToTest.Coordinates;

            //cellMask.SaveToTextFile("fluidCells.txt");

            // This is equivalent to norm(restrictedField) / norm(originalField)
            // Note: THIS WILL FAIL IN CUT CELLS
            foreach (int cell in cellMask.ItemEnum)
            {
                double numerator = 0.0;
                foreach (int coordinate in fieldToTest.Basis.GetPolynomialIndicesForDegree(cell, degree))
                {
                    //numerator += fieldToTest.Coordinates[cell, coordinate] * fieldToTest.Coordinates[cell, coordinate];
                    numerator += fieldToTest.Coordinates[cell, coordinate] * coordinatesTruncatedTimesMassMatrix[cell, coordinate];
                }

                double denominator = 0.0;
                for (int coordinate = 0; coordinate < fieldToTest.Basis.Length; coordinate++)
                {
                    //denominator += fieldToTest.Coordinates[cell, coordinate] * fieldToTest.Coordinates[cell, coordinate];
                    denominator += fieldToTest.Coordinates[cell, coordinate] * coordinatesTimesMassMatrix[cell, coordinate];
                }

                double result;
                if (denominator == 0.0)
                {
                    result = 0.0;
                }
                else
                {
                    result = numerator / denominator;
                }

                //Debug.Assert(denominator != 0, "Persson sensor: Denominator is zero!");

                //Debug.Assert(!(numerator / denominator).IsNaN(), "Persson sensor: Sensor value is NaN!");

                //Debug.Assert(numerator / denominator >= 0, "Persson sensor: Sensor value is negative!");

                sensorValues[cell] = result;
            }
        }