Esempio n. 1
0
        /// <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(meshData);
                        if (face.IsBoundaryFace())
                        {
                            boundaryFaces.Add(face);
                        }
                    }
                }
            }

            //timer.Report("GetBoundaryFaces");
            return(boundaryFaces);
        }
Esempio n. 2
0
        /// <summary>
        /// Build faces of mesh. It will by default build <see cref="Faces"/> and the
        /// <see cref="NodesFaces"/>. It will only build the <see cref="ElementsFaces"/>
        /// if the <paramref name="elmtFaces"/> flag is set.
        /// </summary>
        /// <returns>String of errors. Null if no errors was found</returns>
        public List <string> BuildFaces(bool elmtFaces = false)
        {
            List <string> errors = new List <string>();

            int numberOfNodes    = NumberOfNodes;
            int numberOfElements = NumberOfElements;

            bool hasElementFaces = ElementsFaces != 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));
                if (elmtFaces)
                {
                    ElementsFaces = new List <int> [numberOfElements];
                }

                // Preallocate list of face on all nodes - used in next loop
                NodesFaces = new List <int> [numberOfNodes];
                for (int i = 0; i < numberOfNodes; i++)
                {
                    NodesFaces[i] = new List <int>();
                }
                //timer.ReportAndRestart("Prealloc nodeface");

                //watch.Start();
                // Create all faces.
                for (int ielmt = 0; ielmt < numberOfElements; ielmt++)
                {
                    int   element   = ielmt;
                    int[] elmtNodes = _connectivity[element];
                    if (elmtFaces)
                    {
                        ElementsFaces[ielmt] = new List <int>(elmtNodes.Length);
                    }
                    for (int j = 0; j < elmtNodes.Length; j++)
                    {
                        int fromNode = elmtNodes[j];
                        int toNode   = elmtNodes[(j + 1) % elmtNodes.Length];
                        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(this, errors);
                }
                //timer.ReportAndRestart("Set Boundary Code");
            }

            if (elmtFaces && !hasElementFaces)
            {
                // If not already created, create the lists
                if (ElementsFaces == null)
                {
                    ElementsFaces = new List <int> [numberOfElements];
                    for (int ielmt = 0; ielmt < numberOfElements; ielmt++)
                    {
                        ElementsFaces[ielmt] = new List <int>();
                    }
                }

                // Add face to the elements list of faces
                for (int i = 0; i < Faces.Count; i++)
                {
                    CMeshFace face = Faces[i];
                    ElementsFaces[face.LeftElement].Add(i);
                    if (face.RightElement >= 0)
                    {
                        ElementsFaces[face.RightElement].Add(i);
                    }
                }
            }
            //timer.ReportAndRestart("Create element faces");

            return(errors);
        }