void CreateCellFaceTags(Cell cell, List <BoundaryFace> tags) { foreach (BoundaryFace tag in tags) { byte edgeTag = GetEdgeTagOf(tag.BoundaryEdgeNumber); int faceIndice = tag.Face; CellFaceTag CFT = new CellFaceTag() { EdgeTag = edgeTag, FaceIndex = faceIndice, NeighCell_GlobalID = long.MinValue }; CFT.AddToArray(ref cell.CellFaceTags); } }
/// <summary> /// sets values for <see cref="Cell.CellFaceTags"/> by using a /// <paramref name="EdgeTagFunc"/>-function; also adds entries with empty names /// to the <see cref="EdgeTagNames"/>-dictionary, if the edge tag /// returned by the <paramref name="EdgeTagFunc"/>-function is not in /// the dictionary /// </summary> static public void DefineEdgeTags(this IGrid g, Func <Vector, string> EdgeTagFunc, params string[] EdgeTagNamesToEnsure) { int D = g.SpatialDimension; double[] x = new double[D]; MultidimensionalArray GlobalVerticesOut = MultidimensionalArray.CreateWrapper(x, 1, D); Dictionary <string, byte> EdgeTagNames_Reverse = new Dictionary <string, byte>(); EdgeTagNames_Reverse.Add("inner edge", 0); int[] etUseCount = new int[byte.MaxValue]; foreach (var kv in g.EdgeTagNames) { if (kv.Key == 0) { } else { EdgeTagNames_Reverse.Add(kv.Value, kv.Key); if (kv.Key >= GridCommons.FIRST_PERIODIC_BC_TAG) { etUseCount[kv.Key] = 1; } } } GridCommons baseGrid = null; if (g is GridCommons gcm) { baseGrid = gcm; } else if (g is Aggregation.AggregationGrid ag) { baseGrid = ag.RootGrid as GridCommons; } var GrdDatTmp = g.iGridData; // loop over edges... bool LoopOverEdges(Func <int, int, int, byte> GetEt) { bool _GridChanged = false; int NoOfEdges = GrdDatTmp.iGeomEdges.Count; for (int iEdge = 0; iEdge < NoOfEdges; ++iEdge) { if (GrdDatTmp.iGeomEdges.IsEdgeBoundaryEdge(iEdge)) { int jCell = GrdDatTmp.iGeomEdges.CellIndices[iEdge, 0]; int iFace = GrdDatTmp.iGeomEdges.FaceIndices[iEdge, 0]; // get edge tag byte et = GetEt(iEdge, jCell, iFace); // record edge tag if (baseGrid != null) { var _Cell = baseGrid.Cells[jCell]; var allCFTs = _Cell.CellFaceTags; int found = 0; if (allCFTs != null) { for (int i = 0; i < allCFTs.Length; i++) { if (allCFTs[i].NeighCell_GlobalID < 0 && allCFTs[i].FaceIndex == iFace) { found++; if (allCFTs[i].EdgeTag == et) { // nop } else { allCFTs[i].EdgeTag = et; _GridChanged = true; } } } } if (found > 1) { throw new ApplicationException(string.Format("Cell face tags inconsistent in cell (GlId={0},LocIdx={1}): found {2} boundary tags for face {3}.", _Cell.GlobalID, jCell, found, iFace)); } if (found <= 0) { CellFaceTag CFT = new CellFaceTag() { EdgeTag = et, FaceIndex = iFace, NeighCell_GlobalID = long.MinValue }; CFT.AddToArray(ref baseGrid.Cells[jCell].CellFaceTags); _GridChanged = true; } } GrdDatTmp.iGeomEdges.EdgeTags[iEdge] = et; etUseCount[et]++; } } return(_GridChanged); } byte RecordTag(int iedge, int jCell, int iFace) { var KRef = GrdDatTmp.iGeomCells.GetRefElement(jCell); // call edge-tag-name function GrdDatTmp.TransformLocal2Global(KRef.GetFaceCenter(iFace), GlobalVerticesOut, jCell); string EdgeTagName = EdgeTagFunc(x); // obtain edge tag if (!EdgeTagNames_Reverse.ContainsKey(EdgeTagName)) { int NewTag = EdgeTagNames_Reverse.Count; Debug.Assert(NewTag > 0); if (NewTag >= GridCommons.FIRST_PERIODIC_BC_TAG) { throw new ApplicationException("To many different edge tag names; at maximum " + (Classic.GridCommons.FIRST_PERIODIC_BC_TAG - 1) + " different tags for non-periodic boundaries."); } EdgeTagNames_Reverse.Add(EdgeTagName, (byte)NewTag); } var et = EdgeTagNames_Reverse[EdgeTagName]; return(et); } // pass 1: assign edge tags locally bool GridChanged = LoopOverEdges(RecordTag); GridChanged = GridChanged.MPIOr(); // pass 2: MPI syncronization if (GridChanged && g.Size > 1) { byte[] ETTranslation = SyncEdgeTagsOverMPI(EdgeTagNames_Reverse); if (ETTranslation != null) { LoopOverEdges(delegate(int iedge, int jCell, int iFace) { byte oldEt = GrdDatTmp.iGeomEdges.EdgeTags[iedge]; byte newEt = ETTranslation[oldEt]; return(newEt); }); } } // store & return etUseCount = etUseCount.MPISum(); g.EdgeTagNames.Clear(); foreach (var kv in EdgeTagNames_Reverse) { if (kv.Value == 0 || etUseCount[kv.Value] > 0) { g.EdgeTagNames.Add(kv.Value, kv.Key); } } if (GridChanged) { g.InvalidateGridData(); Console.WriteLine("Grid Edge Tags changed."); } foreach (string EdgeTagName in EdgeTagNamesToEnsure) { g.AddEdgeTag(EdgeTagName); } }