Ejemplo n.º 1
0
        /// <summary>
        /// Evaluates the vector-valued anti-derivatives defining the
        /// moment-fitting basis (cf. <see cref="lambdaBasis"/>) in each node
        /// of all cells in the given range
        /// </summary>
        /// <param name="i0">
        /// First cell in range
        /// </param>
        /// <param name="length">
        /// Number of cells
        /// </param>
        /// <returns>
        /// The values of <see cref="lambdaBasis"/> in each node
        /// <list type="bullet">
        ///     <item>1st index: Node index</item>
        ///     <item>2nd index: Basis function index</item>
        ///     <item>3rd index: Spatial dimension</item>
        /// </list>
        /// </returns>
        /// <remarks>
        /// This method does not evaluate a Lambda which is constant since the
        /// derivative of such function is zero. As a result, the integral over
        /// this function is zero, too, which makes it useless for the
        /// construction of a quadrature rule
        /// </remarks>
        /// <param name="NS">
        /// Nodes at which to evaluate.
        /// </param>
        private MultidimensionalArray EvaluateLambdas(int cell, NodeSet NS)
        {
            int D = LevelSetData.GridDat.SpatialDimension;

            Debug.Assert(
                lambdaBasis.Count % D == 0,
                "Number of polynomials in basis should be divisible by D = " + D);

            int noOfLambdas = lambdaBasis.Count / D;
            int noOfNodes   = NS.NoOfNodes;

            if (RestrictNodes)
            {
                AffineTrafo trafo = trafos[localCellIndex2SubgridIndex[cell]];

                AffineTrafo inverse = trafo.Invert();
                NS = new NodeSet(RefElement, inverse.Transform(NS));
                NS.LockForever();

                MultidimensionalArray lambdaValues = lambdaBasis.Values.GetValues(NS);
                lambdaValues = lambdaValues.ResizeShallow(noOfNodes, noOfLambdas, D);

                for (int i = 0; i < noOfNodes; i++)
                {
                    for (int j = 0; j < noOfLambdas; j++)
                    {
                        for (int d = 0; d < D; d++)
                        {
                            // Bounding box transformation is assumed to just a
                            // stretching, i.e. off-diagonals are zero
                            lambdaValues[i, j, d] *= trafo.Matrix[d, d];
                        }
                    }
                }

                return(lambdaValues);
            }
            else
            {
                MultidimensionalArray lambdaValues = lambdaBasis.Values.GetValues(NS);
                return(lambdaValues.ResizeShallow(noOfNodes, noOfLambdas, D));
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Non-vectorized reference implementation of
        /// <see cref="GetOptimizedRule(int, AffineTrafo, NodeSet, double[,], int)"/>
        /// </summary>
        /// <param name="cell"></param>
        /// <param name="trafo"></param>
        /// <param name="nodes"></param>
        /// <param name="quadResults"></param>
        /// <param name="order"></param>
        /// <returns></returns>
        private QuadRule GetOptimizedRule(int cell, AffineTrafo trafo, NodeSet nodes, double[,] quadResults, int order)
        {
            int maxLambdaDegree = order + 1;
            int noOfLambdas     = GetNumberOfLambdas(maxLambdaDegree);
            int noOfNodes       = nodes.GetLength(0);

            // Leading dimension of B (rhs); required by DGELSY
            int LDB = Math.Max(noOfLambdas, noOfNodes);

            double[] rhs = new double[LDB];

            AffineTrafo inverseTrafo = trafo.Invert();
            NodeSet     trafoNodes   = new NodeSet(RefElement, inverseTrafo.Transform(nodes));

            trafoNodes.LockForever();

            Basis basis = new Basis(LevelSetData.GridDat, order);
            MultidimensionalArray basisValues = basis.Evaluate(trafoNodes);

            int iSubGrid = localCellIndex2SubgridIndex[cell];

            for (int k = 0; k < noOfLambdas; k++)
            {
                rhs[k] += quadResults[iSubGrid, k];
            }

            LAPACK.F77_LAPACK.DGELSY(noOfLambdas, noOfNodes, basisValues.Storage, rhs, 1, RCOND);

            QuadRule optimizedRule = new QuadRule()
            {
                Nodes            = nodes,
                Weights          = MultidimensionalArray.Create(noOfNodes),
                OrderOfPrecision = order
            };

            for (int j = 0; j < noOfNodes; j++)
            {
                optimizedRule.Weights[j] = rhs[j];
            }

            return(optimizedRule);
        }