Exemplo n.º 1
0
            MultidimensionalArray Compute_OrthonormalizationTrafo(int j0, int Len, int Degree)
            {
                // init
                // ====

                int            iKref    = this.m_Owner.iGeomCells.GetRefElementIndex(j0);
                PolynomialList Polys    = this.GetOrthonormalPolynomials(Degree)[iKref];
                int            N        = Polys.Count;
                CellType       cellType = this.m_Owner.iGeomCells.GetCellType(j0);

#if DEBUG
                // checking
                for (int j = 1; j < Len; j++)
                {
                    int jCell = j + j0;

                    if (this.m_Owner.iGeomCells.GetCellType(jCell) != cellType)
                    {
                        throw new NotSupportedException("All cells in chunk must have same type.");
                    }
                }
#endif
                // storage for result
                MultidimensionalArray NonlinOrtho = MultidimensionalArray.Create(Len, N, N);


                if (m_Owner.iGeomCells.IsCellAffineLinear(j0))
                {
                    // affine-linear branch
                    // ++++++++++++++++++++

                    MultidimensionalArray scl = this.Scaling;

                    for (int j = 0; j < Len; j++)
                    {
                        int jCell = j + j0;

                        double scl_j = scl[jCell];

                        for (int n = 0; n < N; n++)
                        {
                            NonlinOrtho[j, n, n] = scl_j;
                        }
                    }
                }
                else
                {
                    // nonlinear cells branch
                    // ++++++++++++++++++++++

                    // init
                    // ====

                    var Kref = m_Owner.iGeomCells.GetRefElement(j0);
                    int deg; // polynomial degree of integrand: Degree of Jacobi determinat + 2* degree of basis polynomials in ref.-space.
                    {
                        int D = m_Owner.SpatialDimension;
                        deg = Kref.GetInterpolationDegree(cellType);
                        if (deg > 1)
                        {
                            deg -= 1;
                        }
                        deg *= D;
                        deg += 2 * Degree;
                    }
                    var qr = Kref.GetQuadratureRule((int)deg);
                    int K  = qr.NoOfNodes;

                    // evaluate basis polys in ref space
                    // =================================

                    MultidimensionalArray BasisValues = this.EvaluateBasis(qr.Nodes, Degree);
                    Debug.Assert(BasisValues.GetLength(0) == K);
                    if (BasisValues.GetLength(0) > N)
                    {
                        BasisValues = BasisValues.ExtractSubArrayShallow(new int[] { 0, 0 }, new int[] { K - 1, N - 1 });
                    }

                    // compute \f$ A_{k n m} = \phi_{k n} \phi_{k m} w_{k} \f$
                    // (cell-INdependentd part of mass matrix computation)
                    // ==================================================================

                    MultidimensionalArray A = MultidimensionalArray.Create(K, N, N);
                    A.Multiply(1.0, qr.Weights, BasisValues, BasisValues, 0.0, "knm", "k", "kn", "km");

                    // Determine mass matrix  \f$ M \f$ in all cells by quadrature
                    // \f$ M_{n m} = \sum_{k} J_k A_{k n m} \f$
                    // =====================================================

                    MultidimensionalArray J = m_Owner.JacobianDeterminat.GetValue_Cell(qr.Nodes, j0, Len);

                    // store mass-matrix in 'NonlinOrtho' to save mem alloc
                    NonlinOrtho.Multiply(1.0, A, J, 0.0, "jmn", "knm", "jk");


                    // Compute change-of-basis for all cells
                    // (invese of cholesky)
                    // =====================================


                    for (int j = 0; j < Len; j++)
                    {
                        MultidimensionalArray Mj = NonlinOrtho.ExtractSubArrayShallow(j, -1, -1); // mass-matrix of basis on refrence element in cell j+j0


#if DEBUG
                        MultidimensionalArray MjClone = Mj.CloneAs();
#endif

                        //Mj.InvertSymmetrical();
                        Mj.SymmetricLDLInversion(Mj, null);

                        // clear lower triangular part
                        // Debug.Assert(Mj.NoOfCols == N);
                        for (int n = 1; n < N; n++)
                        {
                            for (int m = 0; m < n; m++)
                            {
                                Mj[n, m] = 0.0;
                            }
                        }
#if DEBUG
                        MultidimensionalArray B  = NonlinOrtho.ExtractSubArrayShallow(j, -1, -1);
                        MultidimensionalArray Bt = B.Transpose();
                        double MjNorm            = MjClone.InfNorm();
                        double Bnorm             = B.InfNorm();


                        MultidimensionalArray check = IMatrixExtensions.GEMM(Bt, MjClone, B);
                        check.AccEye(-1.0);
                        double checkNorm = check.InfNorm();

                        double RelErr = checkNorm / Math.Max(MjNorm, Bnorm);

                        Debug.Assert(RelErr < 1.0e-5, "Fatal error in numerical orthonomalization on nonlinear cell.");
#endif
                    }
                }

                // return
                // =========

                return(NonlinOrtho);
            }
Exemplo n.º 2
0
        /// <summary>
        /// Compares the cell surface and the boundary integral.
        /// </summary>
        public static void TestSealing(GridData gdat)
        {
            int J = gdat.Cells.NoOfLocalUpdatedCells;

            int[,] E2C = gdat.Edges.CellIndices;

            //
            // compute cell surface via edge integrals
            //
            MultidimensionalArray CellSurf1 = MultidimensionalArray.Create(J);

            EdgeQuadrature.GetQuadrature(new int[] { 1 },
                                         gdat, new EdgeQuadratureScheme().Compile(gdat, 2),
                                         delegate(int i0, int Length, QuadRule rule, MultidimensionalArray EvalResult) { // evaluate
                EvalResult.SetAll(1.0);
            },
                                         delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) { // save results
                for (int i = 0; i < Length; i++)
                {
                    int iEdge   = i + i0;
                    int jCellIn = E2C[iEdge, 0];
                    int jCellOt = E2C[iEdge, 1];

                    CellSurf1[jCellIn] += ResultsOfIntegration[i, 0];
                    if (jCellOt >= 0 && jCellOt < J)
                    {
                        CellSurf1[jCellOt] += ResultsOfIntegration[i, 0];
                    }
                }
            }).Execute();

            //
            // compute cell surface via cell boundary integrals
            //
            var cbqs = new CellBoundaryQuadratureScheme(false, null);

            foreach (var Kref in gdat.Cells.RefElements)
            {
                cbqs.AddFactory(new StandardCellBoundaryQuadRuleFactory(Kref));
            }

            MultidimensionalArray CellSurf2 = MultidimensionalArray.Create(J);

            CellBoundaryQuadrature <CellBoundaryQuadRule> .GetQuadrature(new int[] { 1 },
                                                                         gdat, cbqs.Compile(gdat, 2),
                                                                         delegate(int i0, int Length, CellBoundaryQuadRule rule, MultidimensionalArray EvalResult) { // evaluate
                EvalResult.SetAll(1.0);
            },
                                                                         delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) { // save results
                int NoOfFaces = ResultsOfIntegration.GetLength(1);
                for (int i = 0; i < Length; i++)
                {
                    int jCell = i + i0;
                    for (int iFace = 0; iFace < NoOfFaces; iFace++)
                    {
                        CellSurf2[jCell] += ResultsOfIntegration[i, iFace, 0];
                    }
                }
            }, cs : CoordinateSystem.Physical).Execute();

            //
            // compare
            //
            MultidimensionalArray Err = CellSurf1.CloneAs();

            Err.Acc(-1.0, CellSurf2);
            double ErrNorm = Err.L2Norm();
            double TotSurf = CellSurf1.L2Norm();

            Console.WriteLine("Area Check " + Err.L2Norm());
            Assert.LessOrEqual(ErrNorm / TotSurf, 1.0e-8);

            //for (int j = 0; j < J; j++) {
            //    if (Err[j].Abs() >= 1.0e-6) {
            //        Console.WriteLine("Mismatch between edge area and cell surface area in cell {0}, GlobalId {1}, No. of neighbors {3},  {2:0.####E-00}", j, gdat.CurrentGlobalIdPermutation.Values[j], Err[j], gdat.Cells.CellNeighbours[j].Length);
            //        schas.SetMeanValue(j, 1);
            //    }
            //}
        }
Exemplo n.º 3
0
        /// <summary>
        /// Checks the minimal/maximal resolution of the material sample points and add/remove sample points if necessary
        /// </summary>
        protected bool Reseeding()
        {
            bool reseed = false;

            double domain_shift = DomainSize;

            if (this is PolarFourierLevSet)
            {
                domain_shift = 0.0;
            }

            int sp    = 0;
            int numSp = current_interfaceP.Lengths[0];

            while (sp < numSp)
            {
                // determine distance between two successive points (independent var in domainsize)
                double dist = getDomainDistance(current_interfaceP, sp, +1);

                if (dist <= 2.0 * InterfaceResolution && dist >= InterfaceResolution / 2.0)
                {
                    sp += 1;
                }
                else
                {
                    // check for adding
                    if (dist > 2.0 * InterfaceResolution)
                    {
                        Console.WriteLine("Reseeding: Adding after sp = {0}", sp);
                        reseed = true;

                        // add to current_interfaceP
                        MultidimensionalArray interP_Cache = current_interfaceP.CloneAs();
                        current_interfaceP = MultidimensionalArray.Create(numSp + 1, 2);
                        int dp = 0;
                        for (int p = 0; p < numSp + 1; p++)
                        {
                            if (p == sp + 1)
                            {
                                // interpolate the new sample point
                                if (p == numSp)
                                {
                                    current_interfaceP[p, 0] = (interP_Cache[sp, 0] + domain_shift + interP_Cache[0, 0]) / 2;
                                    current_interfaceP[p, 1] = (interP_Cache[sp, 1] + interP_Cache[0, 1]) / 2;
                                }
                                else
                                {
                                    current_interfaceP[p, 0] = (interP_Cache[sp, 0] + interP_Cache[sp + 1, 0]) / 2;
                                    current_interfaceP[p, 1] = (interP_Cache[sp, 1] + interP_Cache[sp + 1, 1]) / 2;
                                }
                                dp = -1;
                            }
                            else
                            {
                                current_interfaceP[p, 0] = interP_Cache[p + dp, 0];
                                current_interfaceP[p, 1] = interP_Cache[p + dp, 1];
                            }
                        }
                        numSp = current_interfaceP.Lengths[0];

                        // add to interfaceP (History)
                        //History_MultiArray interP_historyCache = interfaceP.CloneAs();
                        //interfaceP.Clear();
                        //for (int i = 0; i <= interfaceP.m_capacity; i++) {
                        //    MultidimensionalArray item = MultidimensionalArray.Create(current_interfaceP.Lengths);
                        //    dp = 0;
                        //    for (int p = 0; p < numSp; p++) {
                        //        if (p == sp + 1) {
                        //            // interpolate the new sample point
                        //            if (p == numSp - 1) {
                        //                item[p, 0] = ((interP_historyCache[-i])[sp, 0] + domain_shift + (interP_historyCache[-i])[0, 0]) / 2;
                        //                item[p, 1] = ((interP_historyCache[-i])[sp, 1] + (interP_historyCache[-i])[0, 1]) / 2;
                        //            } else {
                        //                item[p, 0] = ((interP_historyCache[-i])[sp, 0] + (interP_historyCache[-i])[sp + 1, 0]) / 2;
                        //                item[p, 1] = ((interP_historyCache[-i])[sp, 1] + (interP_historyCache[-i])[sp + 1, 1]) / 2;
                        //            }
                        //            dp = -1;
                        //        } else {
                        //            item[p, 0] = (interP_historyCache[-i])[p + dp, 0];
                        //            item[p, 1] = (interP_historyCache[-i])[p + dp, 1];
                        //        }
                        //    }
                        //    interfaceP.setHistoryEntry(-i, item);
                        //}

                        // velocity hist
                        //History_MultiArray velAtInter_historyCache = velocityAtInterfaceP.CloneAs();
                        //velocityAtInterfaceP.Clear();
                        //for (int i = 0; i <= velocityAtInterfaceP.m_capacity; i++) {
                        //    MultidimensionalArray item = MultidimensionalArray.Create(current_interfaceP.Lengths);
                        //    dp = 0;
                        //    for (int p = 0; p < numSp; p++) {
                        //        if (p == sp + 1) {
                        //            // interpolate the new sample point
                        //            if (p == numSp - 1) {
                        //                item[p, 1] = ((velAtInter_historyCache[-i])[sp, 0] + (velAtInter_historyCache[-i])[0, 0]) / 2;
                        //                item[p, 1] = ((velAtInter_historyCache[-i])[sp, 1] + (velAtInter_historyCache[-i])[0, 1]) / 2;
                        //            } else {
                        //                item[p, 1] = ((velAtInter_historyCache[-i])[sp, 0] + (velAtInter_historyCache[-i])[sp + 1, 0]) / 2;
                        //                item[p, 1] = ((velAtInter_historyCache[-i])[sp, 1] + (velAtInter_historyCache[-i])[sp + 1, 1]) / 2;
                        //            }
                        //            dp = -1;
                        //        } else {
                        //            item[p, 0] = (velAtInter_historyCache[-i])[p + dp, 0];
                        //            item[p, 1] = (velAtInter_historyCache[-i])[p + dp, 1];
                        //        }
                        //    }
                        //    velocityAtInterfaceP.setHistoryEntry(-i, item);
                        //}

                        // set next sample point to check
                        sp += 2;
                    }

                    // check for removing
                    if (dist < (InterfaceResolution / 2.0))
                    {
                        // check which points to remove
                        double dist_left  = getDomainDistance(current_interfaceP, sp, -1);
                        double dist_right = getDomainDistance(current_interfaceP, sp + 1, +1);
                        int    pdel       = 0;
                        if (dist_left <= dist_right)
                        {
                            // remove current sample point sp
                            pdel = sp;
                        }
                        else
                        {
                            // remove the next one sp+1
                            pdel = sp + 1;
                        }
                        Console.WriteLine("Reseeding: Removing sp = {0}", pdel);
                        reseed = true;

                        MultidimensionalArray interP_Cache = current_interfaceP.CloneAs();
                        current_interfaceP = MultidimensionalArray.Create(numSp - 1, 2);
                        int dp = 0;
                        for (int p = 0; p < numSp - 1; p++)
                        {
                            if (p == pdel)
                            {
                                dp = +1;
                            }
                            current_interfaceP[p, 0] = interP_Cache[p + dp, 0];
                            current_interfaceP[p, 1] = interP_Cache[p + dp, 1];
                        }
                        numSp = current_interfaceP.Lengths[0];

                        // remove in interfaceP (History)
                        //History_MultiArray interP_historyCache = interfaceP.CloneAs();
                        //interfaceP.Clear();
                        //for (int i = 0; i <= interfaceP.m_capacity; i++) {
                        //    MultidimensionalArray item = MultidimensionalArray.Create(current_interfaceP.Lengths);
                        //    dp = 0;
                        //    for (int p = 0; p < numSp; p++) {
                        //        if (p == pdel) {
                        //            dp = +1;
                        //        }
                        //        item[p, 0] = (interP_historyCache[-i])[p + dp, 0];
                        //        item[p, 1] = (interP_historyCache[-i])[p + dp, 1];
                        //    }
                        //    interfaceP.setHistoryEntry(-i, item);
                        //}

                        // velocity hist
                        //History_MultiArray velAtInter_historyCache = velocityAtInterfaceP.CloneAs();
                        //velocityAtInterfaceP.Clear();
                        //for (int i = 0; i <= velocityAtInterfaceP.m_capacity; i++) {
                        //    MultidimensionalArray item = MultidimensionalArray.Create(current_interfaceP.Lengths);
                        //    dp = 0;
                        //    for (int p = 0; p < numSp; p++) {
                        //        if (p == pdel) {
                        //            dp = +1;
                        //        }
                        //        item[p, 0] = (velAtInter_historyCache[-i])[p + dp, 0];
                        //        item[p, 1] = (velAtInter_historyCache[-i])[p + dp, 1];
                        //    }
                        //    velocityAtInterfaceP.setHistoryEntry(-i, item);
                        //}
                    }
                }
            }
            return(reseed);
        }