Exemplo n.º 1
0
    public HPRefElement(Element2d el)
    {
        this.levelx = 0;
        this.levely = 0;
        this.levelz = 0;
        this.type   = HP_NONE;
        this.index  = el.GetIndex();
        this.np     = el.GetNV();
        this.domin  = -1;
        this.domout = -1;
        //Reset();

        for (int i = 0; i < np; i++)
        {
            pnums[i] = el[i];
        }

        Point3d[] points = MeshTopology.GetVertices(el.GetType());
        for (int i = 0; i < np; i++)
        {
            for (int l = 0; l < 3; l++)
            {
                param[i][l] = points[i].X(l + 1);
            }
        }
    }
Exemplo n.º 2
0
//C++ TO C# CONVERTER WARNING: 'const' methods are not available in C#:
//ORIGINAL LINE: void GetFace(int i, Element2d & face) const
        public void GetFace(int i, Element2d face)
        {
            // face.SetType(TRIG);
            face[0] = pnums[GlobalMembers.deltetfaces[i][0]];
            face[1] = pnums[GlobalMembers.deltetfaces[i][1]];
            face[2] = pnums[GlobalMembers.deltetfaces[i][2]];
        }
Exemplo n.º 3
0
//C++ TO C# CONVERTER WARNING: 'const' methods are not available in C#:
//ORIGINAL LINE: virtual double FuncDeriv(const Vector & x, const Vector & dir, double & deriv) const
        public override double FuncDeriv(Vector x, Vector dir, ref double deriv)
        {
            // from 2d:

            int       j;
            int       k;
            int       lpi;
            int       gpi;
            Vec <3>   n, vgrad;
            Point <3> pp1;
            Vec2d     g1   = new Vec2d();
            Vec2d     vdir = new Vec2d();
            double    badness;
            double    hbad;
            double    hderiv;

            vgrad   = 0;
            badness = 0;

            ld.meshthis.GetNormalVector(ld.surfi, ld.sp1, ld.gi1, n);

            // pp1 = sp1;
            //    pp1.Add2 (x.Get(1), t1, x.Get(2), t2);
            pp1 = ld.sp1 + x(0) * ld.t1.functorMethod + x(1) * ld.t2.functorMethod;

//C++ TO C# CONVERTER NOTE: This static local variable declaration (not allowed in C#) has been moved just prior to the method:
//	  static Array<Point2d> pts2d;
            FuncDeriv_pts2d.SetSize(mesh.GetNP());

            deriv = 0;

            for (j = 1; j <= ld.locelements.Size(); j++)
            {
                lpi = ld.locrots.Get(j);
                Element2d bel = mesh[ld.locelements.Get(j)];

                gpi = bel.PNum(lpi);

                for (k = 1; k <= bel.GetNP(); k++)
                {
                    PointIndex pi = bel.PNum(k);
                    FuncDeriv_pts2d.Elem(pi) = new Point2d(ld.t1.functorMethod * (new mesh.Point(pi) - ld.sp1), ld.t2.functorMethod * (new mesh.Point(pi) - ld.sp1));
                }
                FuncDeriv_pts2d.Elem(gpi) = new Point2d(x(0), x(1));


                vdir = new Vec2d(dir(0), dir(1));

                hbad = bel.CalcJacobianBadnessDirDeriv(FuncDeriv_pts2d, lpi, vdir, ref hderiv);

                deriv   += hderiv;
                badness += hbad;
            }


            return(badness);
        }
Exemplo n.º 4
0
//C++ TO C# CONVERTER WARNING: 'const' methods are not available in C#:
//ORIGINAL LINE: virtual double FuncGrad(const Vector & x, Vector & grad) const
        public override double FuncGrad(Vector x, Vector grad)
        {
            int       j;
            int       rot;
            Vec <3>   n1, n2, v1, v2, e1, e2, vgrad;
            Point <3> pp1;
            Vec <2>   g1;
            double    badness;
            double    hbadness;

            vgrad   = 0.0;
            badness = 0;

            pp1 = ld.sp1 + x(0) * ld.t1.functorMethod;
            ld.meshthis.ProjectPoint2(ld.surfi, ld.surfi2, ref pp1);

            for (j = 0; j < ld.locelements.Size(); j++)
            {
                rot = ld.locrots[j];
                Element2d bel = mesh[ld.locelements[j]];

                v1 = mesh[bel.PNumMod(rot + 1)] - pp1;
                v2 = mesh[bel.PNumMod(rot + 2)] - pp1;

                e1  = v1;
                e2  = v2;
                e1 /= e1.Length();
                e2 -= (e1 * e2) * e1;
                e2 /= e2.Length();

                if (ld.uselocalh != 0)
                {
                    ld.loch = ld.lochs[j];
                }
                netgen.GlobalMembers.CalcTriangleBadness((e1 * v1), (e1 * v2), (e2 * v2), ld.locmetricweight, ld.loch, hbadness, g1(0), g1(1));

                badness += hbadness;
                vgrad   += g1(0) * e1 + g1(1) * e2;
            }

            ld.meshthis.GetNormalVector(ld.surfi, pp1, n1);
            ld.meshthis.GetNormalVector(ld.surfi2, pp1, n2);

            v1 = netgen.GlobalMembers.Cross(n1, n2);
            v1.Normalize();

            grad(0) = (vgrad * v1) * (ld.t1.functorMethod * v1);

            return(badness);
        }
Exemplo n.º 5
0
    public void Update(TaskManager tm = DummyTaskManager, Tracer tracer = DummyTracer)
    {
//C++ TO C# CONVERTER NOTE: This static local variable declaration (not allowed in C#) has been moved just prior to the method:
//	static int timer = NgProfiler::CreateTimer("clusters");
//C++ TO C# CONVERTER NOTE: This static local variable declaration (not allowed in C#) has been moved just prior to the method:
//	static int timer1 = NgProfiler::CreateTimer("clusters1");
//C++ TO C# CONVERTER NOTE: This static local variable declaration (not allowed in C#) has been moved just prior to the method:
//	static int timer2 = NgProfiler::CreateTimer("clusters2");
//C++ TO C# CONVERTER NOTE: This static local variable declaration (not allowed in C#) has been moved just prior to the method:
//	static int timer3 = NgProfiler::CreateTimer("clusters3");
        NgProfiler.RegionTimer reg = new NgProfiler.RegionTimer(Update_timer);

        MeshTopology top = mesh.GetTopology();

        var id     = this.mesh.GetCommunicator().Rank();
        var ntasks = this.mesh.GetCommunicator().Size();

        bool hasedges = top.HasEdges();
        bool hasfaces = top.HasFaces();

        if (!hasedges || !hasfaces)
        {
            return;
        }

        if (id == 0)
        {
            PrintMessage(3, "Update clusters");
        }

        nv  = mesh.GetNV();
        ned = top.GetNEdges();
        nfa = top.GetNFaces();
        ne  = mesh.GetNE();
        int nse = mesh.GetNSE();

        cluster_reps.SetSize(nv + ned + nfa + ne);
        cluster_reps = -1;

        Array <int> llist = new Array <int>(nv + ned + nfa + ne);

        llist = 0;

        Array <int> nnums  = new Array <int>();
        Array <int> ednums = new Array <int>();
        Array <int> fanums = new Array <int>();
        int         changed;

        NgProfiler.StartTimer(Update_timer1);


        /*
         * for (int i = 1; i <= ne; i++)
         * {
         * const Element & el = mesh.VolumeElement(i);
         * ELEMENT_TYPE typ = el.GetType();
         *
         * top.GetElementEdges (i, ednums);
         * top.GetElementFaces (i, fanums);
         *
         * int elnv = top.GetNVertices (typ);
         * int elned = ednums.Size();
         * int elnfa = fanums.Size();
         *
         * nnums.SetSize(elnv+elned+elnfa+1);
         * for (int j = 1; j <= elnv; j++)
         * nnums.Elem(j) = el.PNum(j);
         * for (int j = 1; j <= elned; j++)
         * nnums.Elem(elnv+j) = nv+ednums.Elem(j);
         * for (int j = 1; j <= elnfa; j++)
         * nnums.Elem(elnv+elned+j) = nv+ned+fanums.Elem(j);
         * nnums.Elem(elnv+elned+elnfa+1) = nv+ned+nfa+i;
         *
         * for (int j = 0; j < nnums.Size(); j++)
         * cluster_reps.Elem(nnums[j]) = nnums[j];
         * }
         */
        netgen.GlobalMembers.ParallelForRange(new TaskManager(tm), ne, (uint begin, uint end) =>
        {
            Array <int> nnums  = new Array <int>();
            Array <int> ednums = new Array <int>();
            Array <int> fanums = new Array <int>();
            for (int i = (int)(begin + 1); i <= end; i++)
            {
                Element el       = mesh.VolumeElement(i);
                ELEMENT_TYPE typ = el.GetType();

                top.GetElementEdges(i, ednums);
                top.GetElementFaces(i, fanums);

                int elnv  = top.GetNVertices(typ);
                int elned = ednums.Size();
                int elnfa = fanums.Size();

                nnums.SetSize(elnv + elned + elnfa + 1);
                for (int j = 1; j <= elnv; j++)
                {
                    nnums.Elem(j) = el.PNum(j) + 1 - PointIndex.BASE;
                }
                for (int j = 1; j <= elned; j++)
                {
                    nnums.Elem(elnv + j) = nv + ednums.Elem(j);
                }
                for (int j = 1; j <= elnfa; j++)
                {
                    nnums.Elem(elnv + elned + j) = nv + ned + fanums.Elem(j);
                }
                nnums.Elem(elnv + elned + elnfa + 1) = nv + ned + nfa + i;

                for (int j = 0; j < nnums.Size(); j++)
                {
                    cluster_reps.Elem(nnums[j]) = nnums[j];
                }
            }
        });

        NgProfiler.StopTimer(Update_timer1);
        NgProfiler.StartTimer(Update_timer2);

        /*
         * for (int i = 1; i <= nse; i++)
         * {
         * const Element2d & el = mesh.SurfaceElement(i);
         * ELEMENT_TYPE typ = el.GetType();
         *
         * top.GetSurfaceElementEdges (i, ednums);
         * int fanum = top.GetSurfaceElementFace (i);
         *
         * int elnv = top.GetNVertices (typ);
         * int elned = ednums.Size();
         *
         * nnums.SetSize(elnv+elned+1);
         * for (int j = 1; j <= elnv; j++)
         * nnums.Elem(j) = el.PNum(j)+1-PointIndex::BASE;
         * for (int j = 1; j <= elned; j++)
         * nnums.Elem(elnv+j) = nv+ednums.Elem(j);
         * nnums.Elem(elnv+elned+1) = fanum;
         *
         * for (int j = 0; j < nnums.Size(); j++)
         * cluster_reps.Elem(nnums[j]) = nnums[j];
         * }
         */
        netgen.GlobalMembers.ParallelForRange(new TaskManager(tm), (uint)nse, (uint begin, uint end) =>
        {
            ArrayMem <int, 9> nnums  = new ArrayMem <int, 9>();
            ArrayMem <int, 9> ednums = new ArrayMem <int, 9>();
            for (int i = (int)(begin + 1); i <= end; i++)
            {
                Element2d el     = mesh.SurfaceElement(i);
                ELEMENT_TYPE typ = el.GetType();

                top.GetSurfaceElementEdges(i, ednums);
                int fanum = top.GetSurfaceElementFace(i);

                int elnv  = top.GetNVertices(typ);
                int elned = ednums.Size();

                nnums.SetSize(elnv + elned + 1);
                for (int j = 1; j <= elnv; j++)
                {
                    nnums.Elem(j) = el.PNum(j) + 1 - PointIndex.BASE;
                }
                for (int j = 1; j <= elned; j++)
                {
                    nnums.Elem(elnv + j) = nv + ednums.Elem(j);
                }
                nnums.Elem(elnv + elned + 1) = fanum;

                for (int j = 0; j < nnums.Size(); j++)
                {
                    cluster_reps.Elem(nnums[j]) = nnums[j];
                }
            }
        });


        NgProfiler.StopTimer(Update_timer2);
        NgProfiler.StartTimer(Update_timer3);


        int[] hex_cluster = { 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 7, 8, 5, 6, 7, 8, 1, 2, 3, 4, 9, 9, 5, 8, 6, 7, 9 };

        int[] prism_cluster = { 1, 2, 3, 1, 2, 3, 4, 5, 6, 4, 5, 6, 3, 1, 2, 7, 7, 4, 5, 6, 7 };

        int[] pyramid_cluster = { 1, 2, 2, 1, 3, 4, 2, 1, 4, 6, 5, 5, 6, 7, 5, 7, 6, 4, 7 };
        int[] tet_cluster14   = { 1, 2, 3, 1, 1, 4, 5, 4, 5, 6, 7, 5, 4, 7, 7 };

        int[] tet_cluster12 = { 1, 1, 2, 3, 4, 4, 5, 1, 6, 6, 7, 7, 4, 6, 7 };

        int[] tet_cluster13 = { 1, 2, 1, 3, 4, 6, 4, 5, 1, 5, 7, 4, 7, 5, 7 };

        int[] tet_cluster23 = { 2, 1, 1, 3, 6, 5, 5, 4, 4, 1, 5, 7, 7, 4, 7 };

        int[] tet_cluster24 = { 2, 1, 3, 1, 4, 1, 5, 4, 6, 5, 5, 7, 4, 7, 7 };

        int[] tet_cluster34 = { 2, 3, 1, 1, 4, 5, 1, 6, 4, 5, 5, 4, 7, 7, 7 };

        int cnt = 0;

        do
        {
            tracer("update cluster, identify", false);
            cnt++;
            changed = 0;

            for (int i = 1; i <= ne; i++)
            {
                Element      el  = mesh.VolumeElement(i);
                ELEMENT_TYPE typ = el.GetType();

//C++ TO C# CONVERTER TODO TASK: C# does not have an equivalent to pointers to value types:
//ORIGINAL LINE: const int * clustertab = null;
                int clustertab = null;
                switch (typ)
                {
                case PRISM:
                case PRISM12:
                    clustertab = prism_cluster;
                    break;

                case HEX:
                    clustertab = hex_cluster;
                    break;

                case PYRAMID:
                    clustertab = pyramid_cluster;
                    break;

                case TET:
                case TET10:
                    if (cluster_reps.Get(el.PNum(1) + 1 - PointIndex.BASE) == cluster_reps.Get(el.PNum(2) + 1 - PointIndex.BASE))
                    {
                        clustertab = tet_cluster12;
                    }
                    else if (cluster_reps.Get(el.PNum(1) + 1 - PointIndex.BASE) == cluster_reps.Get(el.PNum(3) + 1 - PointIndex.BASE))
                    {
                        clustertab = tet_cluster13;
                    }
                    else if (cluster_reps.Get(el.PNum(1) + 1 - PointIndex.BASE) == cluster_reps.Get(el.PNum(4) + 1 - PointIndex.BASE))
                    {
                        clustertab = tet_cluster14;
                    }
                    else if (cluster_reps.Get(el.PNum(2) + 1 - PointIndex.BASE) == cluster_reps.Get(el.PNum(3) + 1 - PointIndex.BASE))
                    {
                        clustertab = tet_cluster23;
                    }
                    else if (cluster_reps.Get(el.PNum(2) + 1 - PointIndex.BASE) == cluster_reps.Get(el.PNum(4) + 1 - PointIndex.BASE))
                    {
                        clustertab = tet_cluster24;
                    }
                    else if (cluster_reps.Get(el.PNum(3) + 1 - PointIndex.BASE) == cluster_reps.Get(el.PNum(4) + 1 - PointIndex.BASE))
                    {
                        clustertab = tet_cluster34;
                    }

                    else
                    {
                        clustertab = null;
                    }
                    break;

                default:
                    clustertab = null;
                    break;
                }

                if (clustertab != 0)
                {
                    top.GetElementEdges(i, ednums);
                    top.GetElementFaces(i, fanums);

                    int elnv  = top.GetNVertices(typ);
                    int elned = ednums.Size();
                    int elnfa = fanums.Size();

                    nnums.SetSize(elnv + elned + elnfa + 1);
                    for (int j = 1; j <= elnv; j++)
                    {
                        nnums.Elem(j) = el.PNum(j) + 1 - PointIndex.BASE;
                    }
                    for (int j = 1; j <= elned; j++)
                    {
                        nnums.Elem(elnv + j) = nv + ednums.Elem(j);
                    }
                    for (int j = 1; j <= elnfa; j++)
                    {
                        nnums.Elem(elnv + elned + j) = nv + ned + fanums.Elem(j);
                    }
                    nnums.Elem(elnv + elned + elnfa + 1) = nv + ned + nfa + i;



                    for (int j = 0; j < nnums.Size(); j++)
                    {
                        for (int k = 0; k < j; k++)
                        {
                            if (clustertab[j] == clustertab[k])
                            {
                                int jj = nnums[j];
                                int kk = nnums[k];

                                if (cluster_reps.Get(kk) < cluster_reps.Get(jj))
                                {
                                    swap(jj, kk);
                                }

                                if (cluster_reps.Get(jj) < cluster_reps.Get(kk))
                                {
                                    /*
                                     * cluster_reps.Elem(kk) = cluster_reps.Get(jj);
                                     * changed = 1;
                                     */

                                    int rep  = cluster_reps.Get(jj);
                                    int next = cluster_reps.Get(kk);
                                    do
                                    {
                                        int cur = next;
                                        next = llist.Elem(next);

                                        cluster_reps.Elem(cur) = rep;
                                        llist.Elem(cur)        = llist.Elem(rep);
                                        llist.Elem(rep)        = cur;
                                    } while (next != 0);
                                    changed = 1;
                                }
                            }
                        }
                    }
                }

                /*
                 * if (clustertab)
                 * {
                 * if (typ == PYRAMID)
                 * (*testout) << "pyramid";
                 * else if (typ == PRISM || typ == PRISM12)
                 * (*testout) << "prism";
                 * else if (typ == TET || typ == TET10)
                 * (*testout) << "tet";
                 * else
                 * (*testout) << "unknown type" << endl;
                 *
                 * (*testout) << ", nnums  = ";
                 * for (j = 0; j < nnums.Size(); j++)
                 * (*testout) << "node " << j << " = " << nnums[j] << ", rep = "
                 * << cluster_reps.Get(nnums[j]) << endl;
                 * }
                 */
            }
            tracer("update cluster, identify", true);
        } while (changed != 0);
        NgProfiler.StopTimer(Update_timer3);

        /*
         * (*testout) << "cluster reps:" << endl;
         * for (i = 1; i <= cluster_reps.Size(); i++)
         * {
         * (*testout) << i << ": ";
         * if (i <= nv)
         * (*testout) << "v" << i << " ";
         * else if (i <= nv+ned)
         * (*testout) << "e" << i-nv << " ";
         * else if (i <= nv+ned+nfa)
         * (*testout) << "f" << i-nv-ned << " ";
         * else
         * (*testout) << "c" << i-nv-ned-nfa << " ";
         * (*testout) << cluster_reps.Get(i) << endl;
         * }
         */
    }
Exemplo n.º 6
0
//C++ TO C# CONVERTER WARNING: 'const' methods are not available in C#:
//ORIGINAL LINE: virtual double FuncGrad(const Vector & x, Vector & grad) const
        public override double FuncGrad(Vector x, ref Vector grad)
        {
            // from 2d:

            int       lpi;
            int       gpi;
            Vec <3>   n, vgrad;
            Point <3> pp1;
            Vec2d     g1   = new Vec2d();
            Vec2d     vdir = new Vec2d();
            double    badness;
            double    hbad;
            double    hderiv;

            vgrad   = 0;
            badness = 0;

            ld.meshthis.GetNormalVector(ld.surfi, ld.sp1, ld.gi1, n);

            pp1 = ld.sp1 + x(0) * ld.t1.functorMethod + x(1) * ld.t2.functorMethod;

            //  meshthis -> ProjectPoint (surfi, pp1);
            //  meshthis -> GetNormalVector (surfi, pp1, n);

//C++ TO C# CONVERTER NOTE: This static local variable declaration (not allowed in C#) has been moved just prior to the method:
//	  static Array<Point2d> pts2d;
            FuncGrad_pts2d.SetSize(mesh.GetNP());

            grad = 0;

            for (int j = 1; j <= ld.locelements.Size(); j++)
            {
                lpi = ld.locrots.Get(j);
                Element2d bel = mesh[ld.locelements.Get(j)];

                gpi = bel.PNum(lpi);

                for (int k = 1; k <= bel.GetNP(); k++)
                {
                    PointIndex pi = bel.PNum(k);
                    FuncGrad_pts2d.Elem(pi) = new Point2d(ld.t1.functorMethod * (new mesh.Point(pi) - ld.sp1), ld.t2.functorMethod * (new mesh.Point(pi) - ld.sp1));
                }
                FuncGrad_pts2d.Elem(gpi) = new Point2d(x(0), x(1));


                for (int k = 1; k <= 2; k++)
                {
                    if (k == 1)
                    {
                        vdir = new Vec2d(1, 0);
                    }
                    else
                    {
                        vdir = new Vec2d(0, 1);
                    }

                    hbad = bel.CalcJacobianBadnessDirDeriv(FuncGrad_pts2d, lpi, vdir, ref hderiv);

                    grad(k - 1) += hderiv;
                    if (k == 1)
                    {
                        badness += hbad;
                    }
                }
            }


            /*
             * vgrad.Add (-(vgrad * n), n);
             *
             * grad.Elem(1) = vgrad * t1;
             * grad.Elem(2) = vgrad * t2;
             */
            return(badness);
        }
Exemplo n.º 7
0
        internal PointSet method_0(ObjectId[] objectId_0, double double_0)
        {
            Database      workingDatabase = HostApplicationServices.WorkingDatabase;
            ProgressMeter progressMeter   = new ProgressMeter();

            progressMeter.SetLimit(objectId_0.Length);
            if (objectId_0.Length > 1)
            {
                progressMeter.Start("Generating points...");
            }
            MessageFilter messageFilter = new MessageFilter();

            System.Windows.Forms.Application.AddMessageFilter(messageFilter);
            int      num      = 0;
            PointSet pointSet = new PointSet();
            PointSet result;

            try
            {
                using (Transaction transaction = workingDatabase.TransactionManager.StartTransaction())
                {
                    List <Entity> list = new List <Entity>();
                    for (int i = 0; i < objectId_0.Length; i++)
                    {
                        list.Add((Entity)transaction.GetObject(objectId_0[i], (OpenMode)0));
                    }
                    Mesh2dControl mesh2dControl = new Mesh2dControl();
                    mesh2dControl.MaxNodeSpacing = (double_0);
                    mesh2dControl.ElementShape   = (0);
                    for (int j = 0; j < objectId_0.Length; j++)
                    {
                        Brep         brep         = new Brep(list[j]);
                        Mesh2dFilter mesh2dFilter = new Mesh2dFilter();
                        mesh2dFilter.Insert(brep, mesh2dControl);
                        Mesh2d mesh2d = new Mesh2d(mesh2dFilter);
                        using (Mesh2dElement2dEnumerator enumerator = mesh2d.Element2ds.GetEnumerator())
                        {
                            while (enumerator.MoveNext())
                            {
                                Element2d current = enumerator.Current;
                                messageFilter.CheckMessageFilter((long)num, 100);
                                num++;
                                using (Element2dNodeEnumerator enumerator2 = current.Nodes.GetEnumerator())
                                {
                                    while (enumerator2.MoveNext())
                                    {
                                        Node current2 = enumerator2.Current;
                                        pointSet.Add(new Point(current2.Point.X, current2.Point.Y, current2.Point.Z));
                                        current2.Dispose();
                                    }
                                }
                                current.Dispose();
                            }
                        }
                        progressMeter.MeterProgress();
                    }
                    pointSet.RemoveMultiplePoints3d();
                }
                progressMeter.Stop();
                result = pointSet;
            }
            catch
            {
                progressMeter.Stop();
                throw;
            }
            return(result);
        }
Exemplo n.º 8
0
//C++ TO C# CONVERTER WARNING: The original C++ declaration of the following method implementation was not found:
        public void Delaunay(Mesh mesh, int domainnr, MeshingParameters mp)
        {
            //C++ TO C# CONVERTER NOTE: This static local variable declaration (not allowed in C#) has been moved just prior to the method:
            //	static int timer = NgProfiler::CreateTimer("Meshing2::Delaunay - total");
            //C++ TO C# CONVERTER NOTE: This static local variable declaration (not allowed in C#) has been moved just prior to the method:
            //	static int timerstart = NgProfiler::CreateTimer("Meshing2::Delaunay - start");
            //C++ TO C# CONVERTER NOTE: This static local variable declaration (not allowed in C#) has been moved just prior to the method:
            //	static int timerfinish = NgProfiler::CreateTimer("Meshing2::Delaunay - finish");
            //C++ TO C# CONVERTER NOTE: This static local variable declaration (not allowed in C#) has been moved just prior to the method:
            //	static int timer1 = NgProfiler::CreateTimer("Meshing2::Delaunay - incremental");
            //C++ TO C# CONVERTER NOTE: This static local variable declaration (not allowed in C#) has been moved just prior to the method:
            //	static int timer1a = NgProfiler::CreateTimer("Meshing2::Delaunay - incremental a");
            //C++ TO C# CONVERTER NOTE: This static local variable declaration (not allowed in C#) has been moved just prior to the method:
            //	static int timer1b = NgProfiler::CreateTimer("Meshing2::Delaunay - incremental b");
            //C++ TO C# CONVERTER NOTE: This static local variable declaration (not allowed in C#) has been moved just prior to the method:
            //	static int timer1c = NgProfiler::CreateTimer("Meshing2::Delaunay - incremental c");
            //C++ TO C# CONVERTER NOTE: This static local variable declaration (not allowed in C#) has been moved just prior to the method:
            //	static int timer1d = NgProfiler::CreateTimer("Meshing2::Delaunay - incremental d");
            NgProfiler.RegionTimer reg = new NgProfiler.RegionTimer(Delaunay_timer);



            Console.Write("2D Delaunay meshing (in progress)");
            Console.Write("\n");


            BlockFillLocalH(mesh, mp);

            NgProfiler.StartTimer(Delaunay_timerstart);

            // do the delaunay


            // face bounding box:
            Box <3> bbox(Box <3> .EMPTY_BOX);

            for (int i = 0; i < adfront.GetNFL(); i++)
            {
                FrontLine line = adfront.GetLine(i);
                bbox.Add(Point <3> (adfront.GetPoint(line.L [0])));
                bbox.Add(Point <3> (adfront.GetPoint(line.L [1])));
            }

            for (int i = 0; i < mesh.LockedPoints().Size(); i++)
            {
                bbox.Add(new mesh.Point(mesh.LockedPoints [i]));
            }

            Console.Write("bbox = ");
            Console.Write(bbox);
            Console.Write("\n");

            // external point
            Vec <3> vdiag = bbox.PMax() - bbox.PMin();

            var          old_points = mesh.Points().Range();
            DelaunayTrig startel    = new DelaunayTrig();

            startel[0] = mesh.AddPoint(bbox.PMin() + Vec <3> (-8 * vdiag(0), -8 * vdiag(1), 0));
            startel[1] = mesh.AddPoint(bbox.PMin() + Vec <3> (+8 * vdiag(0), -8 * vdiag(1), 0));
            startel[2] = mesh.AddPoint(bbox.PMin() + Vec <3> (0, 8 * vdiag(1), 0));

            Box <3> hbox;

            hbox.Set(mesh[startel[0]]);
            hbox.Add(mesh[startel[1]]);
            hbox.Add(mesh[startel[2]]);
            Point <3> hp = mesh[startel[0]];

            hp(2) = 1;
            hbox.Add(hp);
            hp(2) = -1;
            hbox.Add(hp);
            BoxTree <3> searchtree(hbox);

            Array <DelaunayTrig> tempels = new Array <DelaunayTrig>();

            startel.CalcCenter(mesh);

            tempels.Append(startel);
            searchtree.Insert(startel.BoundingBox(), 0);

            Array <int>     closeels     = new Array <int>();
            Array <int>     intersecting = new Array <int>();
            Array <INDEX_2> edges        = new Array <INDEX_2>();



            // reorder points
            Array <PointIndex, PointIndex.BASE, PointIndex> mixed = new Array <PointIndex, PointIndex.BASE, PointIndex>(old_points.Size());

            int[] prims = { 11, 13, 17, 19, 23, 29, 31, 37 };
            int   prim;

            {
                int i = 0;
                while (old_points.Size() % prims[i] == 0)
                {
                    i++;
                }
                prim = prims[i];
            }

            foreach (PointIndex pi in old_points)
            {
                mixed[pi] = new PointIndex((prim * pi) % old_points.Size() + PointIndex.BASE);
            }

            NgProfiler.StopTimer(Delaunay_timerstart);
            NgProfiler.StartTimer(Delaunay_timer1);


            foreach (PointIndex i1 in old_points)
            {
                PointIndex i = mixed[i1];

                NgProfiler.StartTimer(Delaunay_timer1a);
                Point <3> newp = mesh[i];
                intersecting.SetSize(0);
                edges.SetSize(0);

                searchtree.GetIntersecting(newp, newp, closeels);
                // for (int jj = 0; jj < closeels.Size(); jj++)
                // for (int j = 0; j < tempels.Size(); j++)
                foreach (int j in closeels)
                {
                    if (tempels[j][0] < 0)
                    {
                        continue;
                    }
                    Point <3> c  = tempels[j].Center();
                    double    r2 = tempels[j].Radius2();

                    bool inside = Dist2(mesh[i], c) < r2;
                    if (inside)
                    {
                        intersecting.Append(j);
                    }
                }

                NgProfiler.StopTimer(Delaunay_timer1a);
                NgProfiler.StartTimer(Delaunay_timer1b);

                // find outer edges
                foreach (var j in intersecting)
                {
                    DelaunayTrig trig = tempels[j];
                    for (int k = 0; k < 3; k++)
                    {
                        int     p1   = trig[k];
                        int     p2   = trig[(k + 1) % 3];
                        INDEX_2 edge = new INDEX_2(p1, p2);
                        edge.Sort();
                        bool found = false;
                        for (int l = 0; l < edges.Size(); l++)
                        {
                            if (edges[l] == edge)
                            {
                                edges.Delete(l);
                                found = true;
                                break;
                            }
                        }
                        if (!found)
                        {
                            edges.Append(edge);
                        }
                    }
                }

                NgProfiler.StopTimer(Delaunay_timer1b);
                NgProfiler.StartTimer(Delaunay_timer1c);

                /*
                 * for (int j = intersecting.Size()-1; j >= 0; j--)
                 * tempels.Delete (intersecting[j]);
                 */
                foreach (int j in intersecting)
                {
                    searchtree.DeleteElement(j);
                    tempels[j][0] = -1;
                    tempels[j][1] = -1;
                    tempels[j][2] = -1;
                }

                NgProfiler.StopTimer(Delaunay_timer1c);
                NgProfiler.StartTimer(Delaunay_timer1d);

                foreach (var edge in edges)
                {
                    DelaunayTrig trig = new DelaunayTrig(edge[0], edge[1], i);
                    trig.CalcCenter(mesh);
                    tempels.Append(trig);
                    searchtree.Insert(trig.BoundingBox(), tempels.Size() - 1);
                }

                NgProfiler.StopTimer(Delaunay_timer1d);
            }

            NgProfiler.StopTimer(Delaunay_timer1);
            NgProfiler.StartTimer(Delaunay_timerfinish);

            foreach (DelaunayTrig trig in tempels)
            {
                if (trig[0] < 0)
                {
                    continue;
                }

                Point <3> c = Center(mesh[trig[0]], mesh[trig[1]], mesh[trig[2]]);
                if (!adfront.Inside(Point <2> (c(0), c(1))))
                {
                    continue;
                }

                Vec <3> n = Cross(mesh[trig[1]] - mesh[trig[0]], mesh[trig[2]] - mesh[trig[0]]);
                if (n(2) < 0)
                {
                    Swap(ref trig[1], ref trig[2]);
                }

                Element2d el = new Element2d(trig[0], trig[1], trig[2]);
                el.SetIndex(domainnr);
                mesh.AddSurfaceElement(el);
            }

            foreach (PointIndex pi in mesh.Points().Range())
            {
                *testout << pi << ": " << mesh[pi].Type() << "\n";
            }

            NgProfiler.StopTimer(Delaunay_timerfinish);
        }
Exemplo n.º 9
0
        public void UpdateCoarseGridGlobal()
        {
            // cout << "updatecoarsegridglobal called" << endl;
            if (id == 0)
            {
                PrintMessage(3, "UPDATE GLOBAL COARSEGRID STARTS");
            }

            int timer = NgProfiler.CreateTimer("UpdateCoarseGridGlobal");

            NgProfiler.RegionTimer reg = new NgProfiler.RegionTimer(timer);

            *testout << "ParallelMeshTopology :: UpdateCoarseGridGlobal" << "\n";

            MeshTopology topology = mesh.GetTopology();
            MPI_Comm     comm     = mesh.GetCommunicator();

            if (id == 0)
            {
                Array <Array <int> > sendarrays = new Array <Array <int> >(ntasks);
                for (int dest = 1; dest < ntasks; dest++)
                {
                    sendarrays[dest] = new Array <int>();
                }

                Array <int> edges = new Array <int>();
                Array <int> faces = new Array <int>();
                for (int el = 1; el <= mesh.GetNE(); el++)
                {
                    topology.GetElementFaces(el, faces);
                    topology.GetElementEdges(el, edges);
                    Element volel = mesh.VolumeElement(el);

                    // Array<int> & sendarray = *sendarrays[volel.GetPartition()];
                    Array <int> sendarray = *sendarrays[mesh.vol_partition[el - 1]];

                    for (int i = 0; i < edges.Size(); i++)
                    {
                        sendarray.Append(edges[i]);
                    }
                    for (int i = 0; i < faces.Size(); i++)
                    {
                        sendarray.Append(faces[i]);
                    }
                }

                for (int el = 1; el <= mesh.GetNSE(); el++)
                {
                    topology.GetSurfaceElementEdges(el, edges);
                    Element2d surfel = mesh.SurfaceElement(el);
                    // Array<int> & sendarray = *sendarrays[surfel.GetPartition()];
                    Array <int> sendarray = *sendarrays[mesh.surf_partition[el - 1]];

                    for (int i = 0; i < edges.Size(); i++)
                    {
                        sendarray.Append(edges[i]);
                    }
                    sendarray.Append(topology.GetSurfaceElementFace(el));
                }

                Array <MPI_Request> sendrequests = new Array <MPI_Request>();
                for (int dest = 1; dest < ntasks; dest++)
                {
                    sendrequests.Append(netgen.GlobalMembers.MyMPI_ISend(sendarrays[dest], dest, MPI_TAG_MESH + 10, new MPI_Comm(comm)));
                }
                MPI_Waitall(sendrequests.Size(), sendrequests[0], MPI_STATUS_IGNORE);

                for (int dest = 1; dest < ntasks; dest++)
                {
                    sendarrays[dest] = null;
                }
            }

            else

            {
                Array <int> recvarray = new Array <int>();
                netgen.GlobalMembers.MyMPI_Recv(ref recvarray, 0, MPI_TAG_MESH + 10, new MPI_Comm(comm));

                int ii = 0;

                Array <int> faces = new Array <int>();
                Array <int> edges = new Array <int>();

                for (int volel = 1; volel <= mesh.GetNE(); volel++)
                {
                    topology.GetElementEdges(volel, edges);
                    for (int i = 0; i < edges.Size(); i++)
                    {
                        SetLoc2Glob_Edge(edges[i], recvarray[ii++]);
                    }

                    topology.GetElementFaces(volel, faces);
                    for (int i = 0; i < faces.Size(); i++)
                    {
                        SetLoc2Glob_Face(faces[i], recvarray[ii++]);
                    }
                }

                for (int surfel = 1; surfel <= mesh.GetNSE(); surfel++)
                {
                    topology.GetSurfaceElementEdges(surfel, edges);
                    for (int i = 0; i < edges.Size(); i++)
                    {
                        SetLoc2Glob_Edge(edges[i], recvarray[ii++]);
                    }
                    int face = topology.GetSurfaceElementFace(surfel);
                    SetLoc2Glob_Face(face, recvarray[ii++]);
                }
            }

            is_updated = true;
        }
Exemplo n.º 10
0
    public void EdgeSwapping(Mesh mesh, int usemetric)
    {
        if (!faceindex)
        {
            if (usemetric != 0)
            {
                PrintMessage(3, "Edgeswapping, metric");
            }
            else
            {
                PrintMessage(3, "Edgeswapping, topological");
            }

            for (faceindex = 1; faceindex <= mesh.GetNFD(); faceindex++)
            {
                EdgeSwapping(mesh, usemetric);

                if (multithread.terminate)
                {
                    throw new Exception("Meshing stopped");
                }
            }

            faceindex = 0;
            mesh.CalcSurfacesOfNode();
            return;
        }


//C++ TO C# CONVERTER NOTE: This static local variable declaration (not allowed in C#) has been moved just prior to the method:
//	static int timer = NgProfiler::CreateTimer("EdgeSwapping 2D");
        NgProfiler.RegionTimer reg1 = new NgProfiler.RegionTimer(EdgeSwapping_timer);

//C++ TO C# CONVERTER NOTE: This static local variable declaration (not allowed in C#) has been moved just prior to the method:
//	static int timerstart = NgProfiler::CreateTimer("EdgeSwapping 2D start");
        NgProfiler.StartTimer(EdgeSwapping_timerstart);


        Array <SurfaceElementIndex> seia = new Array <SurfaceElementIndex>();

        mesh.GetSurfaceElementsOfFace(faceindex, seia);

        for (int i = 0; i < seia.Size(); i++)
        {
            if (mesh[seia[i]].GetNP() != 3)
            {
                GenericImprove(mesh);
                return;
            }
        }

        int surfnr = mesh.GetFaceDescriptor(faceindex).SurfNr();

        Array <Neighbour>             neighbors = new Array <Neighbour>(mesh.GetNSE());
        INDEX_2_HASHTABLE <trionedge> other     = new INDEX_2_HASHTABLE <trionedge>(seia.Size() + 2);


        Array <char> swapped = new Array <char>(mesh.GetNSE());
        Array <int, PointIndex.BASE>    pdef   = new Array <int, PointIndex.BASE>(mesh.GetNP());
        Array <double, PointIndex.BASE> pangle = new Array <double, PointIndex.BASE>(mesh.GetNP());


        // int e;
        // double d;
        // Vec3d nv1, nv2;

        // double loch(-1);
        double[] minangle = { 0, 1.481, 2.565, 3.627, 4.683, 5.736, 7, 9 };


        for (int i = 0; i < seia.Size(); i++)
        {
            Element2d sel = mesh[seia[i]];
            for (int j = 0; j < 3; j++)
            {
                pangle[sel[j]] = 0.0;
            }
        }
        // pangle = 0;

        for (int i = 0; i < seia.Size(); i++)
        {
            Element2d sel = mesh[seia[i]];
            for (int j = 0; j < 3; j++)
            {
                POINTTYPE typ = mesh[sel[j]].Type();
                if (typ == FIXEDPOINT || typ == EDGEPOINT)
                {
                    pangle[sel[j]] += Angle(mesh[sel[(j + 1) % 3]] - mesh[sel[j]], mesh[sel[(j + 2) % 3]] - mesh[sel[j]]);
                }
            }
        }

        // for (PointIndex pi = PointIndex::BASE;
        // pi < mesh.GetNP()+PointIndex::BASE; pi++)

        // pdef = 0;
        for (int i = 0; i < seia.Size(); i++)
        {
            Element2d sel = mesh[seia[i]];
            for (int j = 0; j < 3; j++)
            {
                PointIndex pi = sel[j];
                if (mesh[pi].Type() == INNERPOINT || mesh[pi].Type() == SURFACEPOINT)
                {
                    pdef[pi] = -6;
                }
                else
                {
                    for (int j = 0; j < 8; j++)
                    {
                        if (pangle[pi] >= minangle[j])
                        {
                            pdef[pi] = -1 - j;
                        }
                    }
                }
            }
        }

        for (int i = 0; i < seia.Size(); i++)
        {
            Element2d sel = mesh[seia[i]];
            for (int j = 0; j < 3; j++)
            {
                pdef[sel[j]]++;
            }
        }

        for (int i = 0; i < seia.Size(); i++)
        {
            for (int j = 0; j < 3; j++)
            {
                neighbors[seia[i]].SetNr(j, -1);
                neighbors[seia[i]].SetOrientation(j, 0);
            }
        }

        /*
         * Array<Vec3d> normals(mesh.GetNP());
         * for (i = 1; i <= mesh.GetNSE(); i++)
         * {
         * Element2d & hel = mesh.SurfaceElement(i);
         * if (hel.GetIndex() == faceindex)
         * for (k = 1; k <= 3; k++)
         * {
         * int pi = hel.PNum(k);
         * SelectSurfaceOfPoint (mesh.Point(pi), hel.GeomInfoPi(k));
         * int surfi = mesh.GetFaceDescriptor(faceindex).SurfNr();
         * GetNormalVector (surfi, mesh.Point(pi), normals.Elem(pi));
         * normals.Elem(pi) /= normals.Elem(pi).Length();
         * }
         * }
         */

        for (int i = 0; i < seia.Size(); i++)
        {
            Element2d sel = mesh[seia[i]];

            for (int j = 0; j < 3; j++)
            {
                PointIndex pi1 = sel.PNumMod(j + 2);
                PointIndex pi2 = sel.PNumMod(j + 3);

                //	    double loch = mesh.GetH(mesh[pi1]);

                INDEX_2 edge = new INDEX_2(pi1, pi2);
                edge.Sort();

                if (mesh.IsSegment(pi1, pi2))
                {
                    continue;
                }

                /*
                 * if (segments.Used (edge))
                 * continue;
                 */
                INDEX_2 ii2 = new INDEX_2(pi1, pi2);
                if (other.Used(ii2))
                {
                    // INDEX_2 i2s(ii2);
                    // i2s.Sort();

                    int i2 = other.Get(ii2).tnr;
                    int j2 = other.Get(ii2).sidenr;

                    neighbors[seia[i]].SetNr(j, i2);
                    neighbors[seia[i]].SetOrientation(j, j2);
                    neighbors[i2].SetNr(j2, seia[i]);
                    neighbors[i2].SetOrientation(j2, j);
                }
                else
                {
                    other.Set(new INDEX_2(pi2, pi1), new trionedge(seia[i], j));
                }
            }
        }

        for (int i = 0; i < seia.Size(); i++)
        {
            swapped[seia[i]] = 0;
        }

        NgProfiler.StopTimer(EdgeSwapping_timerstart);



        int t    = 4;
        int done = 0;

        while (done == 0 && t >= 2)
        {
            for (int i = 0; i < seia.Size(); i++)
            {
                SurfaceElementIndex t1 = seia[i];

                if (mesh[t1].IsDeleted())
                {
                    continue;
                }

                if (mesh[t1].GetIndex() != faceindex)
                {
                    continue;
                }

                if (multithread.terminate)
                {
                    throw new Exception("Meshing stopped");
                }

                for (int o1 = 0; o1 < 3; o1++)
                {
                    bool should;


                    SurfaceElementIndex t2 = neighbors[t1].GetNr(o1);
                    int o2 = neighbors[t1].GetOrientation(o1);

                    if (t2 == -1)
                    {
                        continue;
                    }
                    if (swapped[t1] || swapped[t2])
                    {
                        continue;
                    }


                    PointIndex pi1 = mesh[t1].PNumMod(o1 + 1 + 1);
                    PointIndex pi2 = mesh[t1].PNumMod(o1 + 1 + 2);
                    PointIndex pi3 = mesh[t1].PNumMod(o1 + 1);
                    PointIndex pi4 = mesh[t2].PNumMod(o2 + 1);

                    PointGeomInfo gi1 = mesh[t1].GeomInfoPiMod(o1 + 1 + 1);
                    PointGeomInfo gi2 = mesh[t1].GeomInfoPiMod(o1 + 1 + 2);
                    PointGeomInfo gi3 = mesh[t1].GeomInfoPiMod(o1 + 1);
                    PointGeomInfo gi4 = mesh[t2].GeomInfoPiMod(o2 + 1);

                    bool allowswap = true;

                    Vec <3> auxvec1 = mesh[pi3] - mesh[pi4];
                    Vec <3> auxvec2 = mesh[pi1] - mesh[pi4];

                    allowswap = allowswap && ngsimd.GlobalMembers.fabs(1.0 - (auxvec1 * auxvec2) / (auxvec1.Length() * auxvec2.Length())) > 1e-4;

                    if (!allowswap)
                    {
                        continue;
                    }

                    // normal of new
                    Vec <3> nv1 = netgen.GlobalMembers.Cross(auxvec1, auxvec2);

                    auxvec1   = new mesh.Point(pi4) - new mesh.Point(pi3);
                    auxvec2   = new mesh.Point(pi2) - new mesh.Point(pi3);
                    allowswap = allowswap && ngsimd.GlobalMembers.fabs(1.0 - (auxvec1 * auxvec2) / (auxvec1.Length() * auxvec2.Length())) > 1e-4;


                    if (!allowswap)
                    {
                        continue;
                    }

                    Vec <3> nv2 = netgen.GlobalMembers.Cross(auxvec1, auxvec2);


                    // normals of original
                    Vec <3> nv3 = netgen.GlobalMembers.Cross(mesh[pi1] - mesh[pi4], mesh[pi2] - mesh[pi4]);
                    Vec <3> nv4 = netgen.GlobalMembers.Cross(mesh[pi2] - mesh[pi3], mesh[pi1] - mesh[pi3]);

                    nv3 *= -1;
                    nv4 *= -1;
                    nv3.Normalize();
                    nv4.Normalize();

                    nv1.Normalize();
                    nv2.Normalize();

                    Vec <3> nvp3, nvp4;
                    SelectSurfaceOfPoint(new mesh.Point(pi3), gi3);
                    GetNormalVector(surfnr, new mesh.Point(pi3), gi3, nvp3);

                    nvp3.Normalize();

                    SelectSurfaceOfPoint(new mesh.Point(pi4), gi4);
                    GetNormalVector(surfnr, new mesh.Point(pi4), gi4, nvp4);

                    nvp4.Normalize();



                    double critval = ngsimd.GlobalMembers.cos(DefineConstants.M_PI / 6); // 30 degree
                    allowswap = allowswap && (nv1 * nvp3 > critval) && (nv1 * nvp4 > critval) && (nv2 * nvp3 > critval) && (nv2 * nvp4 > critval) && (nvp3 * nv3 > critval) && (nvp4 * nv4 > critval);


                    double horder = netgen.GlobalMembers.Dist(new mesh.Point(pi1), new mesh.Point(pi2));

                    if (nv1.Length() > 1e-3 * horder * horder && nv2.Length() > 1e-3 * horder * horder && allowswap)
                    {
                        if (usemetric == 0)
                        {
                            int    e = pdef[pi1] + pdef[pi2] - pdef[pi3] - pdef[pi4];
                            double d = netgen.GlobalMembers.Dist2(new mesh.Point(pi1), new mesh.Point(pi2)) - netgen.GlobalMembers.Dist2(new mesh.Point(pi3), new mesh.Point(pi4));

                            should = e >= t && (e > 2 || d > 0);
                        }
                        else
                        {
                            double loch = mesh.GetH(mesh[pi1]);
                            should = CalcTriangleBadness(new mesh.Point(pi4), new mesh.Point(pi3), new mesh.Point(pi1), metricweight, loch) + CalcTriangleBadness(new mesh.Point(pi3), new mesh.Point(pi4), new mesh.Point(pi2), metricweight, loch) < CalcTriangleBadness(new mesh.Point(pi1), new mesh.Point(pi2), new mesh.Point(pi3), metricweight, loch) + CalcTriangleBadness(new mesh.Point(pi2), new mesh.Point(pi1), new mesh.Point(pi4), metricweight, loch);
                        }

                        if (allowswap)
                        {
                            Element2d sw1 = new Element2d(pi4, pi3, pi1);
                            Element2d sw2 = new Element2d(pi3, pi4, pi2);

                            int legal1 = mesh.LegalTrig(mesh.SurfaceElement(t1)) + mesh.LegalTrig(mesh.SurfaceElement(t2));
                            int legal2 = mesh.LegalTrig(sw1) + mesh.LegalTrig(sw2);

                            if (legal1 < legal2)
                            {
                                should = true;
                            }
                            if (legal2 < legal1)
                            {
                                should = false;
                            }
                        }

                        if (should)
                        {
                            // do swapping !

                            done = 1;

                            mesh[t1].PNum(1) = pi1;
                            mesh[t1].PNum(2) = pi4;
                            mesh[t1].PNum(3) = pi3;

                            mesh[t2].PNum(1) = pi2;
                            mesh[t2].PNum(2) = pi3;
                            mesh[t2].PNum(3) = pi4;

                            mesh[t1].GeomInfoPi(1) = gi1;
                            mesh[t1].GeomInfoPi(2) = gi4;
                            mesh[t1].GeomInfoPi(3) = gi3;

                            mesh[t2].GeomInfoPi(1) = gi2;
                            mesh[t2].GeomInfoPi(2) = gi3;
                            mesh[t2].GeomInfoPi(3) = gi4;

                            pdef[pi1]--;
                            pdef[pi2]--;
                            pdef[pi3]++;
                            pdef[pi4]++;

                            swapped[t1] = 1;
                            swapped[t2] = 1;
                        }
                    }
                }
            }
            t--;
        }

        mesh.SetNextTimeStamp();
    }
Exemplo n.º 11
0
    public void CombineImprove(Mesh mesh)
    {
        if (!faceindex)
        {
            PrintMessage(3, "Combine improve");

            for (faceindex = 1; faceindex <= mesh.GetNFD(); faceindex++)
            {
                CombineImprove(mesh);

                if (multithread.terminate)
                {
                    throw new Exception("Meshing stopped");
                }
            }
            faceindex = 0;
            return;
        }


//C++ TO C# CONVERTER NOTE: This static local variable declaration (not allowed in C#) has been moved just prior to the method:
//	static int timer = NgProfiler::CreateTimer("Combineimprove 2D");
        NgProfiler.RegionTimer reg = new NgProfiler.RegionTimer(CombineImprove_timer);

//C++ TO C# CONVERTER NOTE: This static local variable declaration (not allowed in C#) has been moved just prior to the method:
//	static int timerstart = NgProfiler::CreateTimer("Combineimprove 2D start");
        NgProfiler.StartTimer(CombineImprove_timerstart);


//C++ TO C# CONVERTER NOTE: This static local variable declaration (not allowed in C#) has been moved just prior to the method:
//	static int timerstart1 = NgProfiler::CreateTimer("Combineimprove 2D start1");
        NgProfiler.StartTimer(CombineImprove_timerstart1);



        // int i, j, k, l;
        // PointIndex pi;
        // SurfaceElementIndex sei;


        Array <SurfaceElementIndex> seia = new Array <SurfaceElementIndex>();

        mesh.GetSurfaceElementsOfFace(faceindex, seia);


        for (int i = 0; i < seia.Size(); i++)
        {
            if (mesh[seia[i]].GetNP() != 3)
            {
                return;
            }
        }



        int surfnr = 0;

        if (faceindex)
        {
            surfnr = mesh.GetFaceDescriptor(faceindex).SurfNr();
        }


        // PointIndex pi1, pi2;
        // MeshPoint p1, p2, pnew;
        double  bad1;
        double  bad2;
        Vec <3> nv;

        int np = mesh.GetNP();
        //int nse = mesh.GetNSE();

        TABLE <SurfaceElementIndex, PointIndex.BASE> elementsonnode = new TABLE <SurfaceElementIndex, PointIndex.BASE>(np);
        Array <SurfaceElementIndex> hasonepi  = new Array <SurfaceElementIndex>();
        Array <SurfaceElementIndex> hasbothpi = new Array <SurfaceElementIndex>();

        for (int i = 0; i < seia.Size(); i++)
        {
            Element2d el = mesh[seia[i]];
            for (int j = 0; j < el.GetNP(); j++)
            {
                elementsonnode.Add(el[j], seia[i]);
            }
        }

        Array <bool, PointIndex.BASE> @fixed = new Array <bool, PointIndex.BASE>(np);

        @fixed = false;

        NgProfiler.StopTimer(CombineImprove_timerstart1);

        /*
         * for (SegmentIndex si = 0; si < mesh.GetNSeg(); si++)
         * {
         * INDEX_2 i2(mesh[si][0], mesh[si][1]);
         * fixed[i2.I1()] = true;
         * fixed[i2.I2()] = true;
         * }
         */

        for (int i = 0; i < seia.Size(); i++)
        {
            Element2d sel = mesh[seia[i]];
            for (int j = 0; j < sel.GetNP(); j++)
            {
                PointIndex pi1 = sel.PNumMod(j + 2);
                PointIndex pi2 = sel.PNumMod(j + 3);
                if (mesh.IsSegment(pi1, pi2))
                {
                    @fixed[pi1] = true;
                    @fixed[pi2] = true;
                }
            }
        }



        for (int i = 0; i < mesh.LockedPoints().Size(); i++)
        {
            @fixed[mesh.LockedPoints()[i]] = true;
        }



        Array <Vec <3>, PointIndex.BASE> normals = new Array <Vec <3>, PointIndex.BASE>(np);

        for (PointIndex pi = mesh.Points().Begin(); pi < mesh.Points().End(); pi++)
        {
            if (elementsonnode[pi].Size())
            {
                Element2d hel = mesh[elementsonnode[pi][0]];
                for (int k = 0; k < 3; k++)
                {
                    if (hel[k] == pi)
                    {
                        SelectSurfaceOfPoint(mesh[pi], hel.GeomInfoPi(k + 1));
                        GetNormalVector(surfnr, mesh[pi], hel.GeomInfoPi(k + 1), normals[pi]);
                        break;
                    }
                }
            }
        }

        NgProfiler.StopTimer(CombineImprove_timerstart);

        for (int i = 0; i < seia.Size(); i++)
        {
            SurfaceElementIndex sei  = seia[i];
            Element2d           elem = mesh[sei];
            if (elem.IsDeleted())
            {
                continue;
            }

            for (int j = 0; j < 3; j++)
            {
                PointIndex pi1 = elem[j];
                PointIndex pi2 = elem[(j + 1) % 3];

                if (pi1 < PointIndex.BASE || pi2 < PointIndex.BASE)
                {
                    continue;
                }

                /*
                 * INDEX_2 i2(pi1, pi2);
                 * i2.Sort();
                 * if (segmentht.Used(i2))
                 * continue;
                 */

                bool debugflag = false;

                if (debugflag)
                {
                    (*testout) << "Combineimprove, face = " << faceindex << "pi1 = " << pi1 << " pi2 = " << pi2 << "\n";
                }

                /*
                 * // save version:
                 * if (fixed.Get(pi1) || fixed.Get(pi2))
                 * continue;
                 * if (pi2 < pi1) swap (pi1, pi2);
                 */

                // more general
                if (@fixed[pi2])
                {
                    netgen.GlobalMembers.Swap(ref pi1, ref pi2);
                }

                if (@fixed[pi2])
                {
                    continue;
                }

                double loch = mesh.GetH(mesh[pi1]);

                INDEX_2 si2 = new INDEX_2(pi1, pi2);
                si2.Sort();

                /*
                 * if (edgetested.Used (si2))
                 * continue;
                 * edgetested.Set (si2, 1);
                 */

                hasonepi.SetSize(0);
                hasbothpi.SetSize(0);

                for (int k = 0; k < elementsonnode[pi1].Size(); k++)
                {
                    Element2d el2 = mesh[elementsonnode[pi1][k]];

                    if (el2.IsDeleted())
                    {
                        continue;
                    }

                    if (el2[0] == pi2 || el2[1] == pi2 || el2[2] == pi2)
                    {
                        hasbothpi.Append(elementsonnode[pi1][k]);
                        nv = netgen.GlobalMembers.Cross(new Vec3d(mesh[el2[0]], mesh[el2[1]]), new Vec3d(mesh[el2[0]], mesh[el2[2]]));
                    }
                    else
                    {
                        hasonepi.Append(elementsonnode[pi1][k]);
                    }
                }


                Element2d hel = mesh[hasbothpi[0]];
                for (int k = 0; k < 3; k++)
                {
                    if (hel[k] == pi1)
                    {
                        SelectSurfaceOfPoint(mesh[pi1], hel.GeomInfoPi(k + 1));
                        GetNormalVector(surfnr, mesh[pi1], hel.GeomInfoPi(k + 1), nv);
                        break;
                    }
                }

                //	  nv = normals.Get(pi1);



                for (int k = 0; k < elementsonnode[pi2].Size(); k++)
                {
                    Element2d el2 = mesh[elementsonnode[pi2][k]];
                    if (el2.IsDeleted())
                    {
                        continue;
                    }

                    if (el2[0] == pi1 || el2[1] == pi1 || el2[2] == pi1)
                    {
                        ;
                    }
                    else
                    {
                        hasonepi.Append(elementsonnode[pi2][k]);
                    }
                }

                bad1 = 0;
                int illegal1 = 0;
                int illegal2 = 0;
                for (int k = 0; k < hasonepi.Size(); k++)
                {
                    Element2d el = mesh[hasonepi[k]];
                    bad1     += CalcTriangleBadness(mesh[el[0]], mesh[el[1]], mesh[el[2]], nv, -1, loch);
                    illegal1 += 1 - mesh.LegalTrig(el);
                }

                for (int k = 0; k < hasbothpi.Size(); k++)
                {
                    Element2d el = mesh[hasbothpi[k]];
                    bad1     += CalcTriangleBadness(mesh[el[0]], mesh[el[1]], mesh[el[2]], nv, -1, loch);
                    illegal1 += 1 - mesh.LegalTrig(el);
                }
                bad1 /= (hasonepi.Size() + hasbothpi.Size());

                MeshPoint p1 = mesh[pi1];
                MeshPoint p2 = mesh[pi2];

                MeshPoint pnew = new MeshPoint(p1);
                mesh[pi1] = pnew;
                mesh[pi2] = pnew;

                bad2 = 0;
                for (int k = 0; k < hasonepi.Size(); k++)
                {
                    Element2d el  = mesh[hasonepi[k]];
                    double    err = CalcTriangleBadness(mesh[el[0]], mesh[el[1]], mesh[el[2]], nv, -1, loch);
                    bad2 += err;

                    Vec <3> hnv = netgen.GlobalMembers.Cross(new Vec3d(mesh[el[0]], mesh[el[1]]), new Vec3d(mesh[el[0]], mesh[el[2]]));
                    if (hnv * nv < 0)
                    {
                        bad2 += 1e10;
                    }

                    for (int l = 0; l < 3; l++)
                    {
                        if ((normals[el[l]] * nv) < 0.5)
                        {
                            bad2 += 1e10;
                        }
                    }

                    illegal2 += 1 - mesh.LegalTrig(el);
                }
                bad2 /= hasonepi.Size();

                mesh[pi1] = p1;
                mesh[pi2] = p2;


                if (debugflag)
                {
                    (*testout) << "bad1 = " << bad1 << ", bad2 = " << bad2 << "\n";
                }


                bool should = (bad2 < bad1 && bad2 < 1e4);
                if (bad2 < 1e4)
                {
                    if (illegal1 > illegal2)
                    {
                        should = true;
                    }
                    if (illegal2 > illegal1)
                    {
                        should = false;
                    }
                }


                if (should)
                {
                    /*
                     * (*testout) << "combine !" << endl;
                     * (*testout) << "bad1 = " << bad1 << ", bad2 = " << bad2 << endl;
                     * (*testout) << "illegal1 = " << illegal1 << ", illegal2 = " << illegal2 << endl;
                     * (*testout) << "loch = " << loch << endl;
                     */

                    mesh[pi1] = pnew;
                    PointGeomInfo gi = new PointGeomInfo();
                    // bool gi_set(false);


                    Element2d el1p = new Element2d(null);
                    int       l    = 0;
                    while (mesh[elementsonnode[pi1][l]].IsDeleted() && l < elementsonnode.EntrySize(pi1))
                    {
                        l++;
                    }
                    if (l < elementsonnode.EntrySize(pi1))
                    {
                        el1p = mesh[elementsonnode[pi1][l]];
                    }
                    else
                    {
                        cerr << "OOPS!" << "\n";
                    }

                    for (l = 0; l < el1p.GetNP(); l++)
                    {
                        if (el1p[l] == pi1)
                        {
                            gi = el1p.GeomInfoPi(l + 1);
                            // gi_set = true;
                        }
                    }

                    // (*testout) << "Connect point " << pi2 << " to " << pi1 << "\n";
                    for (int k = 0; k < elementsonnode[pi2].Size(); k++)
                    {
                        Element2d el = mesh[elementsonnode[pi2][k]];
                        if (el.IsDeleted())
                        {
                            continue;
                        }
                        elementsonnode.Add(pi1, elementsonnode[pi2][k]);

                        bool haspi1 = false;
                        for (l = 0; l < el.GetNP(); l++)
                        {
                            if (el[l] == pi1)
                            {
                                haspi1 = true;
                            }
                        }
                        if (haspi1)
                        {
                            continue;
                        }

                        for (int l = 0; l < el.GetNP(); l++)
                        {
                            if (el[l] == pi2)
                            {
                                el[l] = pi1;
                                el.GeomInfoPi(l + 1) = gi;
                            }

                            @fixed[el[l]] = true;
                        }
                    }

                    /*
                     * for (k = 0; k < hasbothpi.Size(); k++)
                     * {
                     * cout << mesh[hasbothpi[k]] << endl;
                     * for (l = 0; l < 3; l++)
                     * cout << mesh[mesh[hasbothpi[k]][l]] << " ";
                     * cout << endl;
                     * }
                     */

                    for (int k = 0; k < hasbothpi.Size(); k++)
                    {
                        mesh[hasbothpi[k]].Delete();

                        /*
                         * for (l = 0; l < 4; l++)
                         * mesh[hasbothpi[k]][l] = PointIndex::BASE-1;
                         */
                    }
                }
            }
        }

        //  mesh.Compress();
        mesh.SetNextTimeStamp();
    }