예제 #1
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;
        }
예제 #2
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));
 }
예제 #3
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();
            }
        }
예제 #4
0
        /// <summary>
        /// Creates a <see cref="SpatialOperator"/> with the equation
        /// components that have been assigned to this operator.
        /// </summary>
        /// <returns></returns>
        public SpatialOperator ToSpatialOperator(CNSFieldSet fieldSet)
        {
            SpatialOperator spatialOp = new SpatialOperator(
                CompressibleEnvironment.PrimalArgumentOrdering,
                GetParameterOrdering(fieldSet),
                CompressibleEnvironment.PrimalArgumentOrdering,
                QuadOrderFunc.NonLinearWithoutParameters(2));

            MapComponents(spatialOp);
            spatialOp.Commit();
            return(spatialOp);
        }
예제 #5
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();
            }
        }
예제 #6
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();
            }
        }
예제 #7
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();
            }
        }
예제 #8
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");
            }
        }
예제 #9
0
        /// <summary>
        /// Returns the correct species map for the current domain type
        /// </summary>
        /// <param name="domainType">
        /// The considered domain type
        /// </param>
        /// <param name="workingSet"></param>
        /// <param name="control"></param>
        /// <param name="gridData"></param>
        /// <returns>
        /// A species map that is suitable for the current application.
        /// </returns>
        public static ISpeciesMap CreateSpeciesMap(this DomainTypes domainType, CNSFieldSet workingSet, CNSControl control, GridData gridData)
        {
            Material material = new Material(control);

            switch (domainType)
            {
            case DomainTypes.Standard:
                return(new SingleSpeciesMap(gridData, material));

            case DomainTypes.StaticImmersedBoundary:
            case DomainTypes.MovingImmersedBoundary:
                IBMFieldSet ibmWorkingSet = workingSet as IBMFieldSet;
                return(new ImmersedSpeciesMap(
                           (IBMControl)control, ibmWorkingSet.LevelSet, material));

            default:
                throw new Exception();
            }
        }
예제 #10
0
        /// <summary>
        /// Returns the correct species map for the current domain type
        /// </summary>
        /// <param name="domainType">
        /// The considered domain type
        /// </param>
        /// <param name="workingSet"></param>
        /// <param name="control"></param>
        /// <param name="gridData"></param>
        /// <returns>
        /// A species map that is suitable for the current application.
        /// </returns>
        public static ISpeciesMap CreateSpeciesMap(this DomainTypes domainType, CNSFieldSet workingSet, CNSControl control, IGridData gridData)
        {
            Material material = new Material(control.EquationOfState, control.ViscosityLaw, control.MachNumber, control.ReynoldsNumber, control.PrandtlNumber, control.FroudeNumber, control.ViscosityRatio);

            switch (domainType)
            {
            case DomainTypes.Standard:
                return(new SingleSpeciesMap(gridData, material));

            case DomainTypes.StaticImmersedBoundary:
            case DomainTypes.MovingImmersedBoundary:
                IBMFieldSet ibmWorkingSet = workingSet as IBMFieldSet;
                return(new ImmersedSpeciesMap(
                           (IBMControl)control, ibmWorkingSet.LevelSet, material));

            default:
                throw new Exception();
            }
        }
        /// <summary>
        /// Note: Only to be used if <paramref name="refResults"/> and
        /// <paramref name="loadBalResults"/> have the same grid AND the same
        /// grid partitioning
        /// </summary>
        /// <param name="refResults"></param>
        /// <param name="loadBalResults"></param>
        /// <param name="differenceThreshold"></param>
        private static void CompareErrors(CNSFieldSet refResults, CNSFieldSet loadBalResults, double differenceThreshold)
        {
            List <Action> assertions = new List <Action>();

            {
                double densityDifference = refResults.Density.L2Error(loadBalResults.Density, overrideGridCheck: true);
                string densityMessage    = String.Format(
                    "Density: {0} (Threshold is {1})",
                    densityDifference,
                    differenceThreshold);
                Console.WriteLine(densityMessage);
                assertions.Add(() => Assert.IsTrue(densityDifference < differenceThreshold, densityMessage));
            }

            for (int d = 0; d < refResults.Density.GridDat.SpatialDimension; d++)
            {
                double momentumDifference = refResults.Momentum[d].L2Error(loadBalResults.Momentum[d], overrideGridCheck: true);
                string momentumMessage    = String.Format(
                    "Momentum[{0}]: {1} (Threshold is {2})",
                    d,
                    momentumDifference,
                    differenceThreshold);
                Console.WriteLine(momentumMessage);
                assertions.Add(() => Assert.IsTrue(momentumDifference < differenceThreshold, momentumMessage));
            }

            {
                double energyDifference = refResults.Energy.L2Error(loadBalResults.Energy, overrideGridCheck: true);
                string energyMessage    = String.Format(
                    "Energy: {0} (Threshold is {1})",
                    energyDifference,
                    differenceThreshold);
                Console.WriteLine(energyMessage);
                assertions.Add(() => Assert.IsTrue(energyDifference < differenceThreshold, energyMessage));
            }

            assertions.ForEach(a => a());
        }
예제 #12
0
        public void LimitFieldValues(IProgram <CNSControl> program)
        {
            CNSFieldSet fieldSet = program.WorkingSet;

            foreach (var chunkRulePair in quadRuleSet)
            {
                if (chunkRulePair.Chunk.Len > 1)
                {
                    throw new System.Exception();
                }

                MultidimensionalArray densityValues = MultidimensionalArray.Create(chunkRulePair.Chunk.Len, chunkRulePair.Rule.NoOfNodes);
                fieldSet.Density.Evaluate(chunkRulePair.Chunk.i0, chunkRulePair.Chunk.Len, chunkRulePair.Rule.Nodes, densityValues);
                MultidimensionalArray m0Values = MultidimensionalArray.Create(chunkRulePair.Chunk.Len, chunkRulePair.Rule.NoOfNodes);
                fieldSet.Momentum[0].Evaluate(chunkRulePair.Chunk.i0, chunkRulePair.Chunk.Len, chunkRulePair.Rule.Nodes, m0Values);
                MultidimensionalArray m1Values = MultidimensionalArray.Create(chunkRulePair.Chunk.Len, chunkRulePair.Rule.NoOfNodes);
                fieldSet.Momentum[1].Evaluate(chunkRulePair.Chunk.i0, chunkRulePair.Chunk.Len, chunkRulePair.Rule.Nodes, m1Values);
                MultidimensionalArray energyValues = MultidimensionalArray.Create(chunkRulePair.Chunk.Len, chunkRulePair.Rule.NoOfNodes);
                fieldSet.Energy.Evaluate(chunkRulePair.Chunk.i0, chunkRulePair.Chunk.Len, chunkRulePair.Rule.Nodes, energyValues);

                for (int i = 0; i < chunkRulePair.Chunk.Len; i++)
                {
                    int cell = i + chunkRulePair.Chunk.i0;

                    CellMask             singleCellMask   = new CellMask(speciesMap.Tracker.GridDat, chunkRulePair.Chunk);
                    CellQuadratureScheme singleCellScheme = new CellQuadratureScheme(
                        new FixedRuleFactory <QuadRule>(chunkRulePair.Rule), singleCellMask);
                    var singleCellRule = singleCellScheme.Compile(speciesMap.Tracker.GridDat, 99);

                    SpeciesId species = speciesMap.Tracker.GetSpeciesId(speciesMap.Control.FluidSpeciesName);
                    double    volume  = speciesMap.QuadSchemeHelper.NonAgglomeratedMetrics.CutCellVolumes[species][cell];

                    double integralDensity = fieldSet.Density.LxError((ScalarFunction)null, (X, a, b) => a, singleCellRule);
                    double meanDensity     = integralDensity / volume;

                    if (meanDensity < epsilon)
                    {
                        throw new System.Exception();
                    }

                    double minDensity = double.MaxValue;
                    for (int j = 0; j < chunkRulePair.Rule.NoOfNodes; j++)
                    {
                        minDensity = Math.Min(minDensity, densityValues[i, j]);
                    }

                    double thetaDensity = Math.Min(1.0, (meanDensity - epsilon) / (meanDensity - minDensity));
                    if (thetaDensity < 1.0)
                    {
                        Console.WriteLine("Scaled density in cell {0}!", cell);
                    }

                    // Scale for positive density (Beware: Basis is not orthonormal on sub-volume!)
                    for (int j = 0; j < fieldSet.Density.Basis.Length; j++)
                    {
                        fieldSet.Density.Coordinates[cell, j] *= thetaDensity;
                    }
                    fieldSet.Density.AccConstant(meanDensity * (1.0 - thetaDensity), singleCellMask);

                    // Re-evaluate since inner energy has changed
                    densityValues.Clear();
                    fieldSet.Density.Evaluate(cell, 1, chunkRulePair.Rule.Nodes, densityValues);

#if DEBUG
                    // Probe 1
                    for (int j = 0; j < chunkRulePair.Rule.NoOfNodes; j++)
                    {
                        if (densityValues[i, j] - epsilon < -1e-15)
                        {
                            throw new System.Exception();
                        }
                    }
#endif

                    double integralMomentumX = fieldSet.Momentum[0].LxError((ScalarFunction)null, (X, a, b) => a, singleCellRule);
                    double meanMomentumX     = integralMomentumX / volume;
                    double integralMomentumY = fieldSet.Momentum[1].LxError((ScalarFunction)null, (X, a, b) => a, singleCellRule);
                    double meanMomentumY     = integralMomentumY / volume;
                    double integralEnergy    = fieldSet.Energy.LxError((ScalarFunction)null, (X, a, b) => a, singleCellRule);
                    double meanEnergy        = integralEnergy / volume;

                    double meanInnerEnergy = meanEnergy - 0.5 * (meanMomentumX * meanMomentumX + meanMomentumY * meanMomentumY) / meanDensity;
                    if (meanInnerEnergy < epsilon)
                    {
                        throw new System.Exception();
                    }

                    double minInnerEnergy = double.MaxValue;
                    for (int j = 0; j < chunkRulePair.Rule.NoOfNodes; j++)
                    {
                        double innerEnergy = energyValues[i, j] - 0.5 * (m0Values[i, j] * m0Values[i, j] + m1Values[i, j] * m1Values[i, j]) / densityValues[i, j];
                        minInnerEnergy = Math.Min(minInnerEnergy, innerEnergy);
                    }

                    // Scale for positive inner energy (Beware: Basis is not orthonormal on sub-volume!)
                    double thetaInnerEnergy = Math.Min(1.0, (meanInnerEnergy - epsilon) / (meanInnerEnergy - minInnerEnergy));
                    if (thetaInnerEnergy < 1.0)
                    {
                        Console.WriteLine("Scaled inner energy in cell {0}!", cell);
                    }


                    for (int j = 0; j < fieldSet.Density.Basis.Length; j++)
                    {
                        fieldSet.Density.Coordinates[chunkRulePair.Chunk.i0 + i, j]     *= thetaInnerEnergy;
                        fieldSet.Momentum[0].Coordinates[chunkRulePair.Chunk.i0 + i, j] *= thetaInnerEnergy;
                        fieldSet.Momentum[1].Coordinates[chunkRulePair.Chunk.i0 + i, j] *= thetaInnerEnergy;
                        fieldSet.Energy.Coordinates[chunkRulePair.Chunk.i0 + i, j]      *= thetaInnerEnergy;
                    }
                    fieldSet.Density.AccConstant(meanDensity * (1.0 - thetaInnerEnergy), singleCellMask);
                    fieldSet.Momentum[0].AccConstant(meanMomentumX * (1.0 - thetaInnerEnergy), singleCellMask);
                    fieldSet.Momentum[1].AccConstant(meanMomentumY * (1.0 - thetaInnerEnergy), singleCellMask);
                    fieldSet.Energy.AccConstant(meanEnergy * (1.0 - thetaInnerEnergy), singleCellMask);


#if DEBUG
                    // Probe 2
                    densityValues.Clear();
                    fieldSet.Density.Evaluate(chunkRulePair.Chunk.i0, chunkRulePair.Chunk.Len, chunkRulePair.Rule.Nodes, densityValues);
                    m0Values.Clear();
                    fieldSet.Momentum[0].Evaluate(chunkRulePair.Chunk.i0, chunkRulePair.Chunk.Len, chunkRulePair.Rule.Nodes, m0Values);
                    m1Values.Clear();
                    fieldSet.Momentum[1].Evaluate(chunkRulePair.Chunk.i0, chunkRulePair.Chunk.Len, chunkRulePair.Rule.Nodes, m1Values);
                    energyValues.Clear();
                    fieldSet.Energy.Evaluate(chunkRulePair.Chunk.i0, chunkRulePair.Chunk.Len, chunkRulePair.Rule.Nodes, energyValues);

                    for (int j = 0; j < chunkRulePair.Rule.NoOfNodes; j++)
                    {
                        StateVector state = new StateVector(
                            speciesMap.GetMaterial(1.0),
                            densityValues[i, j],
                            new Vector3D(m0Values[i, j], m1Values[i, j], 0.0),
                            energyValues[i, j]);
                        if (!state.IsValid)
                        {
                            throw new System.Exception();
                        }
                    }
#endif
                }
            }
        }
예제 #13
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;
            }
        }
예제 #14
0
 /// <summary>
 /// Constructs a new constraint
 /// </summary>
 /// <param name="gridData"></param>
 /// <param name="workingSet"></param>
 public CFLConstraint(GridData gridData, CNSFieldSet workingSet)
     : base(gridData, workingSet.config.dtMin, workingSet.config.dtMax, workingSet.config.CFLFraction, workingSet.config.Endtime)
 {
     this.workingSet = workingSet;
 }
예제 #15
0
 /// <summary>
 /// <see cref="ResidualLogger"/>
 /// </summary>
 public NullResidualLogger(BoSSS.Solution.ResidualLogger baseLogger, SessionInfo currentSession, CNSFieldSet workingSet)
     : base(baseLogger, currentSession, workingSet, 0)
 {
 }
예제 #16
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();

            sensorValues = new SinglePhaseField(
                new Basis(fieldToTest.GridDat, 0));

            var quadrature = EdgeQuadrature.GetQuadrature(
                new int[] { 1 },
                (GridData)fieldToTest.GridDat,
                new EdgeQuadratureScheme().Compile(fieldToTest.GridDat, 2 * fieldToTest.Basis.Degree),
                delegate(int e0, int Length, QuadRule QR, MultidimensionalArray EvalResult) {
                MultidimensionalArray gIn  = MultidimensionalArray.Create(Length, QR.NoOfNodes);
                MultidimensionalArray gOut = MultidimensionalArray.Create(Length, QR.NoOfNodes);
                fieldToTest.EvaluateEdge(
                    e0,
                    Length,
                    QR.Nodes,
                    gIn,
                    gOut,
                    MeanValueIN: null,
                    MeanValueOT: null,
                    GradientIN: null,
                    GradientOT: null,
                    ResultIndexOffset: 0,
                    ResultPreScale: 0.0);

                for (int e = 0; e < Length; e++)
                {
                    int edge = e + e0;

                    // Check if "out" neighbor exist; ignore boundary edges for now
                    int outCell = fieldToTest.GridDat.iLogicalEdges.CellIndices[edge, 1];
                    if (outCell < 0)
                    {
                        continue;
                    }

                    for (int node = 0; node < QR.NoOfNodes; node++)
                    {
                        double jump = gOut[e, node] - gIn[e, node];
                        double mean = 0.5 * (gOut[e, node] + gIn[e, node]);
                        double s    = jump / mean;
                        if (!double.IsNaN(s))
                        {
                            EvalResult[e, node, 0] = s * s / (Math.Sign(s) * s + 0.001);
                        }
                    }
                }
            },
                delegate(int e0, int Length, MultidimensionalArray ResultsOfIntegration) {
                for (int e = 0; e < Length; e++)
                {
                    int edge = e + e0;
                    for (int neighbor = 0; neighbor < 2; neighbor++)       // loop over IN/OUT cells
                    {
                        int jCell = fieldToTest.GridDat.iLogicalEdges.CellIndices[edge, neighbor];
                        if (jCell < 0)
                        {
                            break;
                        }

                        sensorValues.Coordinates[jCell, 0] += ResultsOfIntegration[e, 0];
                    }
                }
            });

            quadrature.Execute();
        }
예제 #17
0
        /// <summary>
        /// Initializes <see cref="PreviousState"/>, <see cref="CurrentState"/>
        /// and the log files.
        /// </summary>
        /// <param name="baseLogger">Access to the actual log file</param>
        /// <param name="currentsession">The current session</param>
        /// <param name="workingSet">
        /// The initial working set ("0-th" iteration)
        /// </param>
        /// <param name="residualInterval">
        /// Interval at which residuals are calculated
        /// </param>
        public ResidualLogger(BoSSS.Solution.ResidualLogger baseLogger, SessionInfo currentsession, CNSFieldSet workingSet, int residualInterval)
        {
            this.baseLogger       = baseLogger;
            this.residualInterval = residualInterval;
            this.m_currentsession = currentsession;

            CurrentState  = new VectorField <DGField>(workingSet.ConservativeVariables);
            PreviousState = CurrentState.CloneAs();
        }
예제 #18
0
 /// <summary>
 /// <see cref="ResidualLogger"/>
 /// </summary>
 public ChangeRateResidualLogger(BoSSS.Solution.ResidualLogger baseLogger, SessionInfo currentSession, CNSFieldSet workingSet, int residualInterval)
     : base(baseLogger, currentSession, workingSet, residualInterval)
 {
 }
예제 #19
0
        /// <summary>
        /// Creates an <see cref="OperatorFactory"/> with appropriate terms
        /// (convective/diffusive) for the selected <paramref name="formulation"/>.
        /// </summary>
        /// <param name="formulation">
        /// The chosen equation system
        /// </param>
        /// <param name="control"></param>
        /// <param name="gridData"></param>
        /// <param name="speciesMap"></param>
        /// <param name="workingSet"></param>
        /// <param name="boundaryMap">
        /// Boundary information
        /// </param>
        /// <returns>
        /// An instance of <see cref="OperatorFactory"/> that has been
        /// configured with the fluxes defined by
        /// <see cref="CNSControl.ConvectiveFluxType"/> and/or
        /// <see cref="CNSControl.DiffusiveFluxType"/>.
        /// </returns>
        public static OperatorFactory GetOperatorFactory(
            this DomainTypes formulation, CNSControl control, IGridData gridData, BoundaryConditionMap boundaryMap, CNSFieldSet workingSet, ISpeciesMap speciesMap)
        {
            switch (formulation)
            {
            case DomainTypes.Standard:
                return(new OperatorFactory(
                           control, gridData, workingSet, speciesMap, boundaryMap));

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

            default:
                throw new Exception(
                          "Unknown formulation \"" + control.DomainType + "\"");
            }
        }
예제 #20
0
 /// <summary>
 /// The parameter ordering that is constructed from the the parameters
 /// defined by the operator factory since it should know what the
 /// operators need
 /// </summary>
 private IList <string> GetParameterOrdering(CNSFieldSet fieldSet)
 {
     return(fieldSet.ParameterFields.Select(f => f.Identification).ToList());
 }