/// <summary> /// modifies a residual (i.e. an operator evaluation) /// in order to fix the pressure at some reference point /// </summary> /// <param name="currentState">current state of velocity & pressure</param> /// <param name="iVar">the index of the pressure variable in the mapping <paramref name="map"/>.</param> /// <param name="LsTrk"></param> /// <param name="Residual"></param> static public void SetPressureReferencePointResidual <T>(CoordinateVector currentState, int iVar, LevelSetTracker LsTrk, T Residual) where T : IList <double> { using (new FuncTrace()) { var map = currentState.Mapping; var GridDat = map.GridDat; if (Residual.Count != map.LocalLength) { throw new ArgumentException(); } Basis PressureBasis = (Basis)map.BasisS[iVar]; int D = GridDat.SpatialDimension; long GlobalID, GlobalCellIndex; bool IsInside, onthisProc; GridDat.LocatePoint(new double[D], out GlobalID, out GlobalCellIndex, out IsInside, out onthisProc, LsTrk.Regions.GetCutCellSubGrid().VolumeMask.Complement()); int iRowGl = -111; if (onthisProc) { int jCell = (int)GlobalCellIndex - GridDat.CellPartitioning.i0; NodeSet CenterNode = new NodeSet(GridDat.iGeomCells.GetRefElement(jCell), new double[D]); MultidimensionalArray LevSetValues = LsTrk.DataHistories[0].Current.GetLevSetValues(CenterNode, jCell, 1);; MultidimensionalArray CenterNodeGlobal = MultidimensionalArray.Create(1, D); GridDat.TransformLocal2Global(CenterNode, CenterNodeGlobal, jCell); //Console.WriteLine("Pressure Ref Point @( {0:0.###E-00} | {1:0.###E-00} )", CenterNodeGlobal[0,0], CenterNodeGlobal[0,1]); LevelSetSignCode scode = LevelSetSignCode.ComputeLevelSetBytecode(LevSetValues[0, 0]); ReducedRegionCode rrc; int No = LsTrk.Regions.GetNoOfSpecies(jCell, out rrc); int iSpc = LsTrk.GetSpeciesIndex(rrc, scode); iRowGl = (int)map.GlobalUniqueCoordinateIndex_FromGlobal(iVar, GlobalCellIndex, 0); } iRowGl = iRowGl.MPIMax(); // clear row // --------- if (onthisProc) { // set entry in residual vector equal to corresponding value in domain vector // (as if the corresponding matrix would have a 1 in the diagonal element and 0 everywhere else) int iRow = iRowGl - map.i0; Residual[iRow] = currentState[iRow]; } } }
/// <summary> /// modifies a matrix <paramref name="Mtx"/> and a right-hand-side <paramref name="rhs"/> /// in order to fix the pressure at some reference point /// </summary> /// <param name="map">row mapping for <paramref name="Mtx"/> as well as <paramref name="rhs"/></param> /// <param name="iVar">the index of the pressure variable in the mapping <paramref name="map"/>.</param> /// <param name="LsTrk"></param> /// <param name="Mtx"></param> /// <param name="rhs"></param> static public void SetPressureReferencePoint <T>(UnsetteledCoordinateMapping map, int iVar, LevelSetTracker LsTrk, BlockMsrMatrix Mtx, T rhs) where T : IList <double> { using (new FuncTrace()) { var GridDat = map.GridDat; if (rhs.Count != map.LocalLength) { throw new ArgumentException(); } if (!Mtx.RowPartitioning.EqualsPartition(map) || !Mtx.ColPartition.EqualsPartition(map)) { throw new ArgumentException(); } Basis PressureBasis = (Basis)map.BasisS[iVar]; int D = GridDat.SpatialDimension; long GlobalID, GlobalCellIndex; bool IsInside, onthisProc; GridDat.LocatePoint(new double[D], out GlobalID, out GlobalCellIndex, out IsInside, out onthisProc, LsTrk.Regions.GetCutCellSubGrid().VolumeMask.Complement()); int iRowGl = -111; if (onthisProc) { int jCell = (int)GlobalCellIndex - GridDat.CellPartitioning.i0; NodeSet CenterNode = new NodeSet(GridDat.iGeomCells.GetRefElement(jCell), new double[D]); MultidimensionalArray LevSetValues = LsTrk.DataHistories[0].Current.GetLevSetValues(CenterNode, jCell, 1);; MultidimensionalArray CenterNodeGlobal = MultidimensionalArray.Create(1, D); GridDat.TransformLocal2Global(CenterNode, CenterNodeGlobal, jCell); //Console.WriteLine("Pressure Ref Point @( {0:0.###E-00} | {1:0.###E-00} )", CenterNodeGlobal[0,0], CenterNodeGlobal[0,1]); LevelSetSignCode scode = LevelSetSignCode.ComputeLevelSetBytecode(LevSetValues[0, 0]); ReducedRegionCode rrc; int No = LsTrk.Regions.GetNoOfSpecies(jCell, out rrc); int iSpc = LsTrk.GetSpeciesIndex(rrc, scode); iRowGl = (int)map.GlobalUniqueCoordinateIndex_FromGlobal(iVar, GlobalCellIndex, 0); } iRowGl = iRowGl.MPIMax(); // clear row // --------- if (onthisProc) { // ref. cell is on local MPI process int jCell = (int)GlobalCellIndex - GridDat.CellPartitioning.i0; ReducedRegionCode rrc; int NoOfSpc = LsTrk.Regions.GetNoOfSpecies(jCell, out rrc); // set matrix row to identity Mtx.ClearRow(iRowGl); Mtx.SetDiagonalElement(iRowGl, 1.0); // clear RHS int iRow = iRowGl - Mtx.RowPartitioning.i0; rhs[iRow] = 0; } // clear column // ------------ { for (int i = Mtx.RowPartitioning.i0; i < Mtx.RowPartitioning.iE; i++) { if (i != iRowGl) { Mtx[i, iRowGl] = 0; } } } } }
void UpdateBoundingBoxes() { var grd = lsTrk.GridDat; int D = grd.SpatialDimension; int J = grd.Cells.Count; var KrefS = grd.Grid.RefElements; var VolQRs = KrefS.Select(Kref => Kref.GetBruteForceQuadRule(6, 2)).ToArray(); var BruteForceVolFam = VolQRs; // cache some vals SubGrid allCut = lsTrk.Regions.GetCutCellSubGrid(); int JsubCC = allCut.LocalNoOfCells; int NoOfLevSets = lsTrk.LevelSets.Count(); MultidimensionalArray[] LevSetVals = new MultidimensionalArray[NoOfLevSets]; MultidimensionalArray[] GlobalNodes = BruteForceVolFam.Select(nscc => MultidimensionalArray.Create(nscc.Nodes.NoOfNodes, D)).ToArray(); int[] m_CutCellSubGrid_SubgridIndex2LocalCellIndex = lsTrk.Regions.GetCutCellSubGrid().SubgridIndex2LocalCellIndex; // set BoundingBox'es for cut cells // ================================ double[] pt = new double[D]; for (int jsub = 0; jsub < JsubCC; jsub++) // loop over all local cells in subgrid ... { int j_cell = m_CutCellSubGrid_SubgridIndex2LocalCellIndex[jsub]; int iKref = grd.Cells.GetRefElementIndex(j_cell); int NoOfQuadNodes = BruteForceVolFam[iKref].NoOfNodes; // loop over level sets (evaluation) ... for (int levSetIdx = 0; levSetIdx < NoOfLevSets; levSetIdx++) { LevSetVals[levSetIdx] = lsTrk.DataHistories[levSetIdx].Current.GetLevSetValues(BruteForceVolFam[iKref].Nodes, j_cell, 1); } grd.TransformLocal2Global(BruteForceVolFam[iKref].Nodes, GlobalNodes[iKref], j_cell); ReducedRegionCode rrc; int NoOfSpec = lsTrk.Regions.GetNoOfSpecies(j_cell, out rrc); this.BoundingBoxes[j_cell] = NoOfSpec.ForLoop(iSpc => new BoundingBox(D)); for (int m = 0; m < NoOfQuadNodes; m++) { GlobalNodes[iKref].GetRow(m, pt); double val0 = LevSetVals[0][0, m]; double val1 = 0; if (NoOfLevSets > 1) { val1 = LevSetVals[1][0, m]; } double val2 = 0; if (NoOfLevSets > 2) { val2 = LevSetVals[2][0, m]; } double val3 = 0; if (NoOfLevSets > 3) { val3 = LevSetVals[3][0, m]; } LevelSetSignCode LevSetCode = LevelSetSignCode.ComputeLevelSetBytecode(val0, val1, val2, val3); int iSpec = lsTrk.GetSpeciesIndex(rrc, LevSetCode); this.BoundingBoxes[j_cell][iSpec].AddPoint(pt); } } // set Boundingboxes for un-cut cells // ================================== for (int j = 0; j < J; j++) { if (this.BoundingBoxes[j] == null) { ReducedRegionCode rrc; int NoOfSpc = lsTrk.Regions.GetNoOfSpecies(j, out rrc); BoundingBox BB = new BoundingBox(D); grd.Cells.GetCellBoundingBox(j, BB); this.BoundingBoxes[j] = new BoundingBox[] { BB }; } } }