Exemple #1
0
            public void ReinitializeVerticeArrays()
            {
                for (int i = 0; i < 3; i++)
                {
                    vrts[i]     = e0.vrts[ExtendedElement.TetraIdxOfFaceVertex(fidx0, i)];
                    vrts[i + 3] = e1.vrts[ExtendedElement.TetraIdxOfFaceVertex(fidx1, (i + relativeOrientationIndex) % 3)];
                }
                Node temp = vrts[5];

                vrts[5] = vrts[4];
                vrts[4] = temp;
            }
Exemple #2
0
        // convert normal geometry to extended
        public static void Extend(this Mesh mg)
        {
            // replace Nodes, Faces and Elements with Extended
            for (int i = 0; i < mg.nodes.Count; i++)
            {
                mg.nodes[i] = new ExtendedNode(mg.nodes[i]);
            }

            for (int i = 0; i < mg.faces.Count; i++)
            {
                Face         fc   = mg.faces[i];
                ExtendedFace exfc = new ExtendedFace();
                for (int j = 0; j < 3; j++)
                {
                    exfc.vrts[j] = mg.nodes[fc.vrts[j].id];
                }
                exfc.granule = fc.granule;
                exfc.tag     = fc.tag;
                mg.faces[i]  = exfc;
            }

            for (int i = 0; i < mg.elems.Count; i++)
            {
                Element         elem   = mg.elems[i];
                ExtendedElement exelem = new ExtendedElement();
                exelem.id      = i;
                exelem.granule = elem.granule;
                for (int j = 0; j < 4; j++)
                {
                    exelem.vrts[j] = mg.nodes[elem.vrts[j].id];
                }
                mg.elems[i] = exelem;
            }

            foreach (GranuleEdge ge in mg.edges)
            {
                ge.vrts[0] = mg.nodes[ge.vrts[0].id];
                ge.vrts[1] = mg.nodes[ge.vrts[1].id];
            }
            Trace.Assert(mg.czs.Count == 0, "mg.czs already initialized");
        }
Exemple #3
0
            int relativeOrientationIndex = -1; // used when creating CZ from Face

            public ExtendedCZ(Face f, ExtendedElement e0, ExtendedElement e1)
            {
                // create a CZ from a face that connects 2 elements
                this.e0 = e0; this.e1 = e1;
                Trace.Assert(e0 != e1, "CZ connects two identicla elements");
                Trace.Assert(e0.granule != e1.granule, $"CZ connects same granule, g0: {e0.granule} g1: {e1.granule}");
                fidx0 = e0.WhichFace(f);
                fidx1 = e1.WhichFace(f);

                Node firstNd = e0.vrts[ExtendedElement.TetraIdxOfFaceVertex(fidx0, 0)];

                relativeOrientationIndex = -1;
                for (int i = 0; i < 3; i++)
                {
                    Node testNd = e1.vrts[ExtendedElement.TetraIdxOfFaceVertex(fidx1, i)];
                    if (testNd == firstNd)
                    {
                        relativeOrientationIndex = i; break;
                    }
                }
                Trace.Assert(relativeOrientationIndex != -1);
            }
Exemple #4
0
        public static void InsertCohesiveElements(this Mesh mg)
        {
            Trace.Assert(mg.czs.Count == 0, "CZs can be inserted only once");
            mg.Extend();
            mg.IdentifyParentsOfTriangles();

            // connectivity information for nodes
            foreach (ExtendedNode nd in mg.nodes)
            {
                nd.elementsOfNode.Clear();
            }
            foreach (Element e in mg.elems)
            {
                foreach (ExtendedNode n in e.vrts)
                {
                    n.elementsOfNode.Add(e);
                    if (!n.granules.Contains(e.granule))
                    {
                        n.granules.Add(e.granule);
                    }
                }
            }

            // preserve the exposed faces
            List <ExtendedFace> surface   = new List <ExtendedFace>();
            List <ExtendedFace> innerTris = new List <ExtendedFace>();

            foreach (ExtendedFace f in mg.faces)
            {
                if (f.elementsOfFace.Count == 1)
                {
                    surface.Add(f);
                }
                else if (f.elementsOfFace.Count == 2)
                {
                    innerTris.Add(f);
                }
            }

            foreach (Face f in surface)
            {
                foreach (Node nd in f.vrts)
                {
                    nd.isSurface = true;
                }
            }
            List <Tuple <ExtendedElement, int> > surfaceFaces = new List <Tuple <ExtendedElement, int> >(); // (element, faceIdx) format

            foreach (ExtendedFace f in mg.faces)
            {
                foreach (ExtendedElement e in f.elementsOfFace)
                {
                    Trace.Assert(e.ContainsFace(f), "error in .elementsOfFace");
                    int which = e.WhichFace(f);
                    // exposed faces are preserved in surfaceFaces
                    if (f.elementsOfFace.Count == 1)
                    {
                        surfaceFaces.Add(new Tuple <ExtendedElement, int>(e, which));
                    }
                    e.faces.Add(which);
                }
            }

            // store all edges within extended elements
            foreach (GranuleEdge ge in mg.edges)
            {
                ExtendedNode nd = (ExtendedNode)ge.vrts[0];
                foreach (ExtendedElement elem in nd.elementsOfNode)
                {
                    elem.AddEdgeIfContains(ge);
                }
            }

            // convert inner triangles into cohesive elements
            foreach (ExtendedFace f in innerTris)
            {
                ExtendedElement e0  = (ExtendedElement)f.elementsOfFace[0];
                ExtendedElement e1  = (ExtendedElement)f.elementsOfFace[1];
                ExtendedCZ      ecz = new ExtendedCZ(f, e0, e1);
                mg.czs.Add(ecz);
            }

            // list the nodes, which are connected to CZs
            foreach (Face t in innerTris)
            {
                foreach (ExtendedNode n in t.vrts)
                {
                    n._belongs_to_cz = true;
                }
            }
            List <ExtendedNode> nczs = new List <ExtendedNode>();

            foreach (ExtendedNode nd in mg.nodes)
            {
                if (nd._belongs_to_cz)
                {
                    nczs.Add(nd);
                }
            }

            // create linked list
            LinkedList <Node>     ll  = new LinkedList <Node>(mg.nodes);
            LinkedListNode <Node> lln = ll.First;

            do
            {
                ((ExtendedNode)lln.Value).ll_node = lln;
                lln = lln.Next;
            } while (lln != null);

            // split the nodes, which belong to cohesive elements
            foreach (ExtendedNode nd in nczs)
            {
                nd.SplitNode(ll);
            }

            // linked list becomes the new list of nodes; resequence
            mg.nodes = new List <Node>(ll);
            for (int i = 0; i < mg.nodes.Count; i++)
            {
                mg.nodes[i].id = i;
            }

            // infer cz.vrts[] from fidx
            foreach (ExtendedCZ cz in mg.czs)
            {
                cz.ReinitializeVerticeArrays();
            }

            // restore the list of faces and the list of edges
            mg.edges.Clear();
            mg.faces.Clear();
            foreach (ExtendedElement e in mg.elems)
            {
                foreach (int i in e.edges)
                {
                    mg.edges.Add(e.GetEdge(i));
                }
            }
            foreach (GranuleEdge ge in mg.edges)
            {
                ge.exposed = true;
            }

            // first, create exposed faces from surfaceFaces array
            foreach (Tuple <ExtendedElement, int> tuple in surfaceFaces)
            {
                ExtendedElement elem  = tuple.Item1;
                int             which = tuple.Item2;

                Face fc = elem.GetFace(which);
                fc.exposed = true;
                fc.id      = mg.faces.Count;
                mg.faces.Add(fc);
            }

            // create non-exposed faces from CZs, record their references into cz.faces
            foreach (ExtendedCZ cz in mg.czs)
            {
                Face fc = cz.e0.GetFace(cz.fidx0);
                fc.elem     = cz.e0;
                cz.faces[0] = fc;
                fc.granule  = cz.e0.granule;
                fc.exposed  = false;
                fc.id       = mg.faces.Count;
                mg.faces.Add(fc);

                fc          = cz.e1.GetFace(cz.fidx1);
                fc.elem     = cz.e1;
                cz.faces[1] = fc;
                fc.exposed  = false;
                fc.id       = mg.faces.Count;
                fc.granule  = cz.e1.granule;
                mg.faces.Add(fc);
            }

            // convert extended nodes back to regular
            mg.ConvertBack();
            mg.DetectSurfacesAfterLoadingMSH();
            for (int i = 0; i < mg.czs.Count; i++)
            {
                mg.czs[i].immutableID = i;
            }
        }