/// <summary> /// assigns the cell index of the aggregated cell <em>j</em> to all (fine) grid cells that /// the aggregated cell <em>j</em> consists of. /// </summary> static public void ColorDGField(this AggregationGrid ag, DGField f) { if (!object.ReferenceEquals(f.GridDat, ag.AncestorGrid)) { throw new ArgumentException("mismatch in base grid."); } f.Clear(); int J = ag.iLogicalCells.NoOfLocalUpdatedCells; for (int j = 0; j < J; j++) // loog over logical/aggregate cells { int[] Neighs = ag.iLogicalCells.CellNeighbours[j]; var NeighColors = Neighs.Select(jNeigComp => (int)Math.Round(f.GetMeanValue(ag.iLogicalCells.AggregateCellToParts[jNeigComp][0]))); int iCol = 1; for (iCol = 1; iCol < 2 * J; iCol++) { if (!NeighColors.Contains(iCol)) { break; } } foreach (int jGeom in ag.iLogicalCells.AggregateCellToParts[j]) { f.SetMeanValue(jGeom, iCol); //f.SetMeanValue(jGeom, j); } } }
public (int noOfClasses, int[] cellToPerformanceClassMap) ClassifyCells(IProgram <CNSControl> program) { if (!program.Control.ActiveOperators.HasFlag(Operators.ArtificialViscosity)) { throw new Exception( "The selected cell classifier is only sensible for runs with artificial viscosity"); } int noOfClasses = 2; int[] cellToPerformanceClassMap = new int[program.Grid.NoOfUpdateCells]; // old //foreach (Chunk chunk in program.Control.ArtificialViscosityLaw.GetShockedCellMask(program.GridData)) { // foreach (int cell in chunk.Elements) { // cellToPerformanceClassMap[cell] = 1; // } //} // new DGField avField = program.WorkingSet.DerivedFields[Variables.ArtificialViscosity]; foreach (Chunk chunk in program.SpeciesMap.SubGrid.VolumeMask) { foreach (int cell in chunk.Elements) { if (avField.GetMeanValue(cell) > 0) { cellToPerformanceClassMap[cell] = 1; } } } return(noOfClasses, cellToPerformanceClassMap); }
/// <summary> /// accumulates (to field <paramref name="f"/>), in every cell the /// distance form the cut cells times <paramref name="alpha"/>; /// Note: this is NOT the geometric distance, but the distance index /// that identifies the 'Near+1' , 'Near-1', 'Near+2', ..., - layers. /// </summary> public static void AccLevelSetDist(this DGField f, double alpha, LevelSetTracker LevSetTrk, int LevSetIdx) { int J = f.Basis.GridDat.iLogicalCells.NoOfLocalUpdatedCells; var r = LevSetTrk.Regions; for (int j = 0; j < J; j++) { int dist = LevelSetTracker.DecodeLevelSetDist(r.m_LevSetRegions[j], 0); f.SetMeanValue(j, f.GetMeanValue(j) + dist * alpha); } }
/// <summary> /// accumulates (to field <paramref name="f"/>), in every cell the /// number of species times <paramref name="alpha"/> /// </summary> public static void AccNoOfSpecies(this DGField f, double alpha, LevelSetTracker LevSetTrk, int LevSetIdx) { int J = f.Basis.GridDat.iLogicalCells.NoOfLocalUpdatedCells; var r = LevSetTrk.Regions; for (int j = 0; j < J; j++) { ReducedRegionCode rrc; int NoOfSpec = r.GetNoOfSpecies(j, out rrc); f.SetMeanValue(j, f.GetMeanValue(j) + NoOfSpec * alpha); } }
static private bool TestingGridDistributionDynamic() { //string dbPath = @"D:\Weber\BoSSS\test_db"; //TestCase: 5x4 grid, Timesteps, LTS-Cluster, PartOn,recInt,AV=false, dgdegree=0, Timestepping=LTS CNSControl control = ShockTube_PartTest_Dynamic(5, 4, 1, 2, true, 1); using (var solver = new HilbertTest()) { solver.Init(control); solver.RunSolverMode(); bool result = false; List <DGField> listOfDGFields = (List <DGField>)solver.IOFields; DGField field = listOfDGFields[12]; int D = field.GridDat.SpatialDimension; int J = field.GridDat.iLogicalCells.NoOfLocalUpdatedCells; //intention:Checking if BoundaryBox of LTSCluster==1 is as expected //Therefore Computing BoundaryBox of LTSCluster==1 var BB = new BoSSS.Platform.Utils.Geom.BoundingBox(D); var CellBB = new BoSSS.Platform.Utils.Geom.BoundingBox(D); for (int i = 0; i < J; i++) { if (field.GetMeanValue(i) == 1) { //Cell cj=solver.GridData.Cells.GetCell(i); solver.GridData.iLogicalCells.GetCellBoundingBox(i, CellBB); BB.AddBB(CellBB); } } BB.Max = BB.Max.MPIMax(); BB.Min = BB.Min.MPIMin(); for (int i = 0; i < D; i++) { BB.Max[i] = Math.Round(BB.Max[i] * 100) / 100; BB.Min[i] = Math.Round(BB.Min[i] * 100) / 100; } double[] MaxRef = { 0.6, 1 }; double[] MinRef = { 0, 0 }; if (ItemsAreEqual(BB.Max, MaxRef) && ItemsAreEqual(BB.Min, MinRef)) { //Comparing checkLTS to Distribution along HilbertCurve of Testcase int[] checkLTS = { 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 3, 3, 0, 0, 2, 2, 2, 3, 3, 3 }; //result = ItemsAreEqual(solver.Grid.GetHilbertSortedRanks(),checkLTS); int J0 = solver.GridData.CellPartitioning.i0; int JE = solver.GridData.CellPartitioning.iE; ulong[] discreteCenter = new ulong[D]; ulong[] local_HilbertIndex = new ulong[JE - J0]; int[] local_RankIndex = new int[JE - J0]; var _Grid = (GridCommons)(solver.Grid); for (int j = J0; j < JE; j++) { Cell Cj = _Grid.Cells[j - J0]; int NoOfNodes = Cj.TransformationParams.NoOfRows; for (int d = 0; d < D; d++) { double center = 0; for (int k = 0; k < NoOfNodes; k++) { center += Cj.TransformationParams[k, d]; } center = center / ((double)NoOfNodes); double centerTrf = center * Math.Pow(2, 32); centerTrf = Math.Round(centerTrf); if (centerTrf < 0) { centerTrf = 0; } if (centerTrf > ulong.MaxValue) { centerTrf = ulong.MaxValue; } discreteCenter[d] = (ulong)centerTrf; } ulong iH = ilPSP.HilbertCurve.HilbertCurve.hilbert_c2i(32, discreteCenter); local_HilbertIndex[j - J0] = iH; local_RankIndex[j - J0] = solver.MPIRank; } int[] CellsPerRank = { 5, 5, 5, 5 }; ulong[] HilbertIndex = local_HilbertIndex.MPIAllGatherv(CellsPerRank); int[] RankIndex = local_RankIndex.MPIAllGatherv(CellsPerRank); Array.Sort(HilbertIndex, RankIndex); result = ItemsAreEqual(RankIndex, checkLTS); } else { //catching error caused by changes to LTS-Clustering Console.WriteLine("Unexpected result for LTS Clusters! Computation of LTS Clusters changed. Test aborted."); result = false; } Console.WriteLine("Test Grid Distribution Dynamic LTS"); Console.WriteLine("Testresult: {0}", result); return(result); } }
/// <summary> /// Computes the maximum admissible step-size according to /// GassnerEtAl2008, equation 67. /// </summary> /// <param name="i0"></param> /// <param name="Length"></param> /// <returns></returns> protected override double GetCFLStepSize(int i0, int Length) { int iKref = gridData.Cells.GetRefElementIndex(i0); int noOfNodesPerCell = base.EvaluationPoints[iKref].NoOfNodes; double scaling = Math.Max(4.0 / 3.0, config.EquationOfState.HeatCapacityRatio / config.PrandtlNumber); DGField artificialViscosity = workingSet.ParameterFields.Where(c => c.Identification.Equals(Variables.ArtificialViscosity)).Single(); double cfl = double.MaxValue; switch (speciesMap) { case ImmersedSpeciesMap ibmMap: { MultidimensionalArray levelSetValues = ibmMap.Tracker.DataHistories[0].Current.GetLevSetValues(base.EvaluationPoints[iKref], i0, Length); SpeciesId species = ibmMap.Tracker.GetSpeciesId(ibmMap.Control.FluidSpeciesName); var hMinArray = ibmMap.CellAgglomeration.CellLengthScales[species]; for (int i = 0; i < Length; i++) { int cell = i0 + i; double hminlocal = hMinArray[cell]; double nu = artificialViscosity.GetMeanValue(cell) / config.ReynoldsNumber; Debug.Assert(!double.IsNaN(nu), "IBM ArtificialViscosityCFLConstraint: nu is NaN"); bool setCFL = false; for (int node = 0; node < noOfNodesPerCell; node++) { if (levelSetValues[i, node].Sign() != (double)ibmMap.Control.FluidSpeciesSign) { continue; } else if (setCFL == false) { setCFL = true; } } if (nu != 0 && setCFL) { double cflCell = hminlocal * hminlocal / scaling / nu; Debug.Assert(!double.IsNaN(cflCell), "Could not determine CFL number"); cfl = Math.Min(cfl, cflCell); } } } break; default: { for (int i = 0; i < Length; i++) { int cell = i0 + i; double hminlocal = gridData.Cells.h_min[cell]; double nu = artificialViscosity.GetMeanValue(cell) / config.ReynoldsNumber; Debug.Assert(!double.IsNaN(nu), "ArtificialViscosityCFLConstraint: nu is NaN"); if (nu != 0) { double cflCell = hminlocal * hminlocal / scaling / nu; Debug.Assert(!double.IsNaN(cflCell), "Could not determine CFL number"); cfl = Math.Min(cfl, cflCell); } } } break; } if (cfl == double.MaxValue) { return(cfl); } else { int degree = workingSet.ConservativeVariables.Max(f => f.Basis.Degree); int twoNPlusOne = 2 * degree + 1; return(cfl * GetBetaMax(degree) / twoNPlusOne / twoNPlusOne / Math.Sqrt(CNSEnvironment.NumberOfDimensions)); } }
public double GetSensorValue(int cellIndex) { return(sensorValues.GetMeanValue(cellIndex)); }
/// <summary> /// Computes the maximum admissible step-size according to /// GassnerEtAl2008, equation 67. /// </summary> /// <param name="i0"></param> /// <param name="Length"></param> /// <returns></returns> protected override double GetCFLStepSize(int i0, int Length) { BoSSS.Foundation.Grid.Classic.GridData __gridData = (BoSSS.Foundation.Grid.Classic.GridData)(this.gridData); int iKref = __gridData.Cells.GetRefElementIndex(i0); int noOfNodesPerCell = base.EvaluationPoints[iKref].NoOfNodes; double scaling = Math.Max(4.0 / 3.0, config.EquationOfState.HeatCapacityRatio / config.PrandtlNumber); MultidimensionalArray hmin = __gridData.Cells.h_min; DGField artificialViscosity = workingSet.ParameterFields.Where(c => c.Identification.Equals(CNSVariables.ArtificialViscosity)).Single(); double cfl = double.MaxValue; switch (speciesMap) { case ImmersedSpeciesMap ibmMap: { MultidimensionalArray levelSetValues = ibmMap.Tracker.DataHistories[0].Current.GetLevSetValues(base.EvaluationPoints[iKref], i0, Length); SpeciesId species = ibmMap.Tracker.GetSpeciesId(ibmMap.Control.FluidSpeciesName); MultidimensionalArray hminCut = ibmMap.CellAgglomeration.CellLengthScales[species]; for (int i = 0; i < Length; i++) // loop over cells... { int cell = i0 + i; double hminLocal = double.NaN; // Return double.MaxValue in all IBM source cells //if (ibmMap.sourceCells[cell]) { // cfl = double.MaxValue; // break; //} else if (ibmMap.cutCellsThatAreNotSourceCells[cell]) { if (ibmMap.cutCellsThatAreNotSourceCells[cell]) { hminLocal = hminCut[cell]; } else { hminLocal = hmin[cell]; } Debug.Assert(double.IsNaN(hminLocal) == false, "Hmin is NaN"); Debug.Assert(double.IsInfinity(hminLocal) == false, "Hmin is Inf"); double nu = artificialViscosity.GetMeanValue(cell) / config.ReynoldsNumber; Debug.Assert(!double.IsNaN(nu), "IBM ArtificialViscosityCFLConstraint: nu is NaN"); Debug.Assert(nu >= 0.0, "IBM ArtificialViscosityCFLConstraint: nu is negative"); bool setCFL = false; for (int node = 0; node < noOfNodesPerCell; node++) { if (levelSetValues[i, node].Sign() != (double)ibmMap.Control.FluidSpeciesSign) { continue; } else if (setCFL == false) { setCFL = true; } } if (nu != 0 && setCFL) { double cflhere = hminLocal * hminLocal / scaling / nu; Debug.Assert(!double.IsNaN(cflhere), "Could not determine CFL number"); cfl = Math.Min(cfl, cflhere); } } } break; default: { for (int i = 0; i < Length; i++) { int cell = i0 + i; double hminLocal; CellData cellData = __gridData.Cells; //if (!cellData.IsCellAffineLinear(cell)) { // //hminLocal = cellData.CellLengthScale[cell] * 2; // hminLocal = cellData.GetCellVolume(cell) / cellData.CellSurfaceArea[cell]; //} else { hminLocal = hmin[cell]; //} Debug.Assert(double.IsNaN(hminLocal) == false, "Hmin is NaN"); Debug.Assert(double.IsInfinity(hminLocal) == false, "Hmin is Inf"); double nu = artificialViscosity.GetMeanValue(cell) / config.ReynoldsNumber; Debug.Assert(!double.IsNaN(nu), "ArtificialViscosityCFLConstraint: nu is NaN"); Debug.Assert(nu >= 0.0, "IBM ArtificialViscosityCFLConstraint: nu is negative"); if (nu != 0) { double cflhere = hminLocal * hminLocal / scaling / nu; Debug.Assert(!double.IsNaN(cflhere), "Could not determine CFL number"); cfl = Math.Min(cfl, cflhere); } } } break; } if (cfl == double.MaxValue) { return(cfl); } else { int degree = workingSet.ConservativeVariables.Max(f => f.Basis.Degree); int twoNPlusOne = 2 * degree + 1; return(cfl * GetBetaMax(degree) / twoNPlusOne / twoNPlusOne / Math.Sqrt(CompressibleEnvironment.NumberOfDimensions)); } }