Ejemplo n.º 1
0
        public void LimitFieldValues(IEnumerable <DGField> ConservativeVariables, IEnumerable <DGField> DerivedFields)
        {
            var GridData = ConservativeVariables.First().GridDat;

            // Make sure primitive fields are up-to-date
            for (int d = 0; d < CompressibleEnvironment.NumberOfDimensions; d++)
            {
                CNSVariables.Velocity[d].UpdateFunction(
                    DerivedFields.Single(f => f.Identification == CNSVariables.Velocity[d].Name),
                    CellMask.GetFullMask(GridData),
                    program);
            }
            CNSVariables.Pressure.UpdateFunction(
                DerivedFields.Single(f => f.Identification == CNSVariables.Pressure.Name),
                CellMask.GetFullMask(GridData),
                program);

            // Limit and store primitive fields
            string[]  primitiveFieldNames = { CompressibleVariables.Density, CNSVariables.Velocity.xComponent, CNSVariables.Velocity.yComponent, CNSVariables.Pressure };
            DGField[] primitiveFields     = new DGField[primitiveFieldNames.Length];
            CellMask  shockedCells        = Sensor.GetShockedCellMask(GridData, sensorLimit, cellSize, dgDegree);
            int       k = 0;

            foreach (string name in primitiveFieldNames)
            {
                DGField field = ConservativeVariables.
                                Concat(DerivedFields).
                                Where(f => f.Identification.Equals(name)).
                                Single();

                foreach (Chunk chunk in shockedCells)
                {
                    foreach (int cell in chunk.Elements)
                    {
                        for (int j = 1; j < field.Coordinates.NoOfCols; j++)
                        {
                            field.Coordinates[cell, j] = 0.0;
                        }
                    }
                }

                primitiveFields[k] = field;
                k++;
            }

            // Update conservative variables by using limited primitive variables only in shocked cells
            int D = CompressibleEnvironment.NumberOfDimensions;

            for (int d = 0; d < D; d++)
            {
                DGField mom_d = ConservativeVariables.Single(f => f.Identification == CompressibleVariables.Momentum[d].Name);
                mom_d.Clear(shockedCells);
                mom_d.ProjectFunction(
                    1.0,
                    (X, U, j) => U[0] * U[1 + d],
                    new CellQuadratureScheme(true, shockedCells),
                    primitiveFields);
            }

            // Update total energy
            DGField Energy = ConservativeVariables.Single(f => f.Identification == CompressibleVariables.Energy.Name);

            Energy.Clear(shockedCells);
            Energy.ProjectFunction(
                1.0,
                delegate(double[] X, double[] U, int jCell) {
                double K = 0.0;
                for (int d = 0; d < D; d++)
                {
                    K += U[d + 1] * U[d + 1];
                }
                return(U[D + 1] / (program.Control.EquationOfState.HeatCapacityRatio - 1.0) + 0.5 * U[0] * K);
            },
                new CellQuadratureScheme(true, shockedCells),
                primitiveFields);
        }