Пример #1
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);
        }
Пример #2
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;
         * }
         */
    }
Пример #3
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);
        }