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); }