/// <summary> /// Provided a list of all faces in the mesh, extract faces on the boundary - unsorted /// </summary> public static List <CMeshFace> ExtractBoundaryFaces(List <CMeshFace> meshFaces) { List <CMeshFace> bcs = new List <CMeshFace>(); for (int i = 0; i < meshFaces.Count; i++) { CMeshFace meshFace = meshFaces[i]; if (meshFace.IsBoundaryFace()) { bcs.Add(meshFace); } } return(bcs); }
/// <summary> /// Depth First Search visit method /// </summary> /// <param name="elementIndex">Start element</param> /// <param name="subMeshId">Sub mesh ID</param> /// <returns>Number of elements in sub mesh</returns> private int BFSVisit(int elementIndex, int subMeshId) { int numElmtsInSubMesh = 0; // Element has been discovered _stack.Push(elementIndex); ElmtSubMesh[elementIndex] = subMeshId; numElmtsInSubMesh++; while (_stack.Count > 0) { int elmt = _stack.Pop(); List <CMeshFace> elmtFaces = _meshData.Elements[elmt].Faces; for (int i = 0; i < elmtFaces.Count; i++) { // Find element on the other side of the face CMeshFace elmtFace = elmtFaces[i]; // Boundary faces never has an element on the other side if (elmtFace.IsBoundaryFace()) { continue; } int otherElmt; if (elmtFace.LeftElement.Index == elmt) { otherElmt = elmtFace.RightElement.Index; } else { otherElmt = elmtFace.LeftElement.Index; } // Check if we have already visited otherElmt if (ElmtSubMesh[otherElmt] == 0) { // Element has been discovered _stack.Push(otherElmt); ElmtSubMesh[otherElmt] = subMeshId; numElmtsInSubMesh++; } } } return(numElmtsInSubMesh); }
/// <summary> /// Return all boundary faces. Unsorted /// </summary> /// <param name="meshData">MeshData object to get boundary faces for</param> /// <param name="checkAllFaces">In case boundary codes are set incorrectly, this will check all faces</param> public static List <CMeshFace> GetBoundaryFaces(this CMeshData meshData, bool checkAllFaces) { //System.Diagnostics.Stopwatch timer = MeshExtensions.StartTimer(); List <CMeshFace>[] facesFromNode = new List <CMeshFace> [meshData.NumberOfNodes]; // Preallocate list of face on all nodes - used in next loop for (int i = 0; i < meshData.NumberOfNodes; i++) { facesFromNode[i] = new List <CMeshFace>(); } // Create all potential boundary faces - those having // boundary code on both to-node and from-node // (not all those need to be boundary faces). for (int ielmt = 0; ielmt < meshData.NumberOfElements; ielmt++) { CreateAddElementFaces(meshData, facesFromNode, ielmt, checkAllFaces); } // Figure out boundary code and store all boundary faces List <CMeshFace> boundaryFaces = new List <CMeshFace>(); for (int i = 0; i < facesFromNode.Length; i++) { List <CMeshFace> facesFromThisNode = facesFromNode[i]; for (int j = 0; j < facesFromThisNode.Count; j++) { CMeshFace face = facesFromThisNode[j]; // Only take those with fromNode matching this node - // otherwise they are taken twice. //if (face.FromNode.Index == i) { face.SetBoundaryCode(); if (face.IsBoundaryFace()) { boundaryFaces.Add(face); } } } } //timer.Report("GetBoundaryFaces"); return(boundaryFaces); }
/// <summary> /// Build list of <see cref="CMeshBoundary"/>, one for each boundary code, based on the <paramref name="meshFaces"/> /// <para> /// The <paramref name="meshFaces"/> need only contain boundary faces. Internal faces are ignored. /// </para> /// </summary> private static List <CMeshBoundary> BuildBoundaryList(CMeshData mesh, List <CMeshFace> meshFaces) { // Sort all faces on boundary code, assuming code numbers does not grow very big. List <List <CMeshFace> > bcs = new List <List <CMeshFace> >(); for (int i = 0; i < meshFaces.Count; i++) { CMeshFace meshFace = meshFaces[i]; if (meshFace.IsBoundaryFace()) { while (meshFace.Code + 1 > bcs.Count) { List <CMeshFace> boundaryFaces = new List <CMeshFace>(); bcs.Add(boundaryFaces); } bcs[meshFace.Code].Add(meshFace); } } List <CMeshBoundary> boundaries = new List <CMeshBoundary>(); BoundarySegmentsBuilder bsb = new BoundarySegmentsBuilder(mesh); // For each boundary code, find segments for (int ic = 0; ic < bcs.Count; ic++) { int code = ic; List <CMeshFace> faces = bcs[ic]; List <LinkedList <int> > segments = bsb.BuildBoundarySegments(faces); if (segments == null) { continue; } // Create mesh boundary with segments CMeshBoundary meshBoundary = new CMeshBoundary() { Code = code }; foreach (LinkedList <int> segment in segments) { if (segment == null) { continue; } List <CMeshFace> segmentFaces = new List <CMeshFace>(segment.Count); foreach (int currentFace in segment) { segmentFaces.Add(faces[currentFace]); } meshBoundary.Segments.Add(segmentFaces); } boundaries.Add(meshBoundary); } //// Sort on boundary codes - well, they are created in code-order //boundaries.Sort((mb1, mb2) => mb1.Code.CompareTo(mb2.Code)); return(boundaries); }