/// <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 up the list of <see cref="Faces"/> /// </summary> /// <param name="elmtFaces">Also build up <see cref="MeshElement.Faces"/></param> public List <string> BuildFaces(bool elmtFaces = false) { List <string> errors = new List <string>(); int numberOfNodes = NumberOfNodes; int numberOfElements = NumberOfElements; bool hasElementFaces = Elements[0].Faces != null; //System.Diagnostics.Stopwatch timer = MeshExtensions.StartTimer(); if (Faces == null) { // Build up face lists // The exact number of faces is: NumberOfElements+NumberOfNodes + numberOfSubMeshes - numberOfHoles Faces = new List <CMeshFace>((int)((numberOfElements + numberOfNodes) * 1.01)); // Preallocate list of face on all nodes - used in next loop for (int i = 0; i < Nodes.Count; i++) { Nodes[i].Faces = new List <CMeshFace>(); } //timer.ReportAndRestart("Prealloc nodeface"); //watch.Start(); // Create all faces. for (int ielmt = 0; ielmt < Elements.Count; ielmt++) { MeshElement element = Elements[ielmt]; List <MeshNode> elmtNodes = element.Nodes; if (elmtFaces) { element.Faces = new List <CMeshFace>(elmtNodes.Count); } for (int j = 0; j < elmtNodes.Count; j++) { MeshNode fromNode = elmtNodes[j]; MeshNode toNode = elmtNodes[(j + 1) % elmtNodes.Count]; AddFace(element, fromNode, toNode); } } //timer.ReportAndRestart("Create faces "+Faces.Count); // Figure out boundary code for (int i = 0; i < Faces.Count; i++) { CMeshFace face = Faces[i]; face.SetBoundaryCode(errors); } //timer.ReportAndRestart("Set Boundary Code"); } if (elmtFaces && !hasElementFaces) { // If not already created, create the lists if (Elements[0].Faces == null) { for (int ielmt = 0; ielmt < numberOfElements; ielmt++) { Elements[ielmt].Faces = new List <CMeshFace>(); } } // Add face to the elements list of faces for (int i = 0; i < Faces.Count; i++) { CMeshFace face = Faces[i]; face.LeftElement.Faces.Add(face); if (face.RightElement != null) { face.RightElement.Faces.Add(face); } } } //timer.ReportAndRestart("Create element faces"); return(errors); }