Beispiel #1
0
        /// <summary>
        /// Uses <see cref="Grid.RefElement.GetQuadratureRule"/> to create a quad rule
        /// (i.e., the quad rule is the same for all elements of
        /// <paramref name="mask"/>)
        /// </summary>
        /// <param name="mask">
        /// <see cref="IQuadRuleFactory{QuadRule}.GetQuadRuleSet"/>
        /// </param>
        /// <param name="order">
        /// <see cref="IQuadRuleFactory{QuadRule}.GetQuadRuleSet"/>
        /// </param>
        /// <returns>
        /// <see cref="Grid.RefElement.GetQuadratureRule"/>
        /// </returns>
        public IEnumerable <IChunkRulePair <QuadRule> > GetQuadRuleSet(ExecutionMask mask, int order)
        {
            QuadRule rule = RefElement.GetQuadratureRule(order);

            Debug.Assert(rule.Nodes.IsLocked, "Error: non-locked quad rule from reference element.");
            Debug.Assert(object.ReferenceEquals(rule.Nodes.RefElement, RefElement), "Error: quad rule from reference element has not the right reference elment assigned.");

            return(mask.Select(chunk => new ChunkRulePair <QuadRule>(chunk, rule)));
        }
Beispiel #2
0
        /// <summary>
        /// Uses <see cref="Grid.RefElement.GetQuadratureRule"/> to create a quad rule
        /// (i.e., the quad rule is the same for all elements of
        /// <paramref name="mask"/>)
        /// </summary>
        /// <param name="mask">
        /// <see cref="IQuadRuleFactory{QuadRule}.GetQuadRuleSet"/>
        /// </param>
        /// <param name="order">
        /// <see cref="IQuadRuleFactory{QuadRule}.GetQuadRuleSet"/>
        /// </param>
        /// <returns>
        /// <see cref="Grid.RefElement.GetQuadratureRule"/>
        /// </returns>
        public IEnumerable <IChunkRulePair <QuadRule> > GetQuadRuleSet(ExecutionMask mask, int order)
        {
            if (mask.MaskType != MaskType.Geometrical)
            {
                throw new ArgumentException("Expecting a geometrical mask.");
            }

            QuadRule rule = RefElement.GetQuadratureRule(order);

            Debug.Assert(rule.Nodes.IsLocked, "Error: non-locked quad rule from reference element.");
            Debug.Assert(object.ReferenceEquals(rule.Nodes.RefElement, RefElement), "Error: quad rule from reference element has not the right reference elment assigned.");

            return(mask.Select(chunk => new ChunkRulePair <QuadRule>(chunk, rule)));
        }
            public IEnumerable <IChunkRulePair <QuadRule> > GetQuadRuleSet(ExecutionMask mask, int order)
            {
                if (mask.MaskType != MaskType.Geometrical)
                {
                    throw new ArgumentException("Expecting a geometrical mask.");
                }

                QuadRule fullRule = RefElement.GetQuadratureRule(order);
                int      L1       = fullRule.NoOfNodes;
                int      D        = fullRule.SpatialDim;

                var otherRule = m_orgrule.GetQuadRuleSet(mask, order);
                var ret       = new List <IChunkRulePair <QuadRule> >(otherRule.Count());

                foreach (var x in otherRule)
                {
                    Chunk    chk = x.Chunk;
                    QuadRule qr  = x.Rule;
                    int      L2  = qr.NoOfNodes;

                    Debug.Assert(qr.SpatialDim == fullRule.SpatialDim);

                    QuadRule compQr = new QuadRule();
                    compQr.OrderOfPrecision = qr.OrderOfPrecision;

                    compQr.Nodes   = new NodeSet(this.RefElement, L1 + L2, D);
                    compQr.Weights = MultidimensionalArray.Create(L1 + L2);


                    compQr.Nodes.SetSubArray(fullRule.Nodes, new int[] { 0, 0 }, new int[] { L1 - 1, D - 1 });
                    compQr.Weights.SetSubArray(fullRule.Weights, new int[] { 0 }, new int[] { L1 - 1 });
                    compQr.Nodes.SetSubArray(qr.Nodes, new int[] { L1, 0 }, new int[] { L1 + L2 - 1, D - 1 });
                    compQr.Weights.AccSubArray(-1, qr.Weights, new int[] { L1 }, new int[] { L1 + L2 - 1 });

                    compQr.Nodes.LockForever();

                    ret.Add(new ChunkRulePair <QuadRule>(chk, compQr));
                }

                return(ret);
            }
Beispiel #4
0
        static void JacobianTest(Cell cl, out bool PositiveJacobianFlag, out bool NegativeJacobianFlag, out bool Linear)
        {
            RefElement Kref = cl.Type.GetRefElement();

            int D = 3; // for OpenFOAM, we assume 3D;

            // get nodes within ref element, to test the Jacobian
            int deg = Kref.GetInterpolationDegree(cl.Type);

            if (deg > 1)
            {
                deg--;
            }
            deg *= 3;

            NodeSet TestNodes = Kref.GetQuadratureRule(2 * deg).Nodes;

            // evaluate derivatives of nodal polynomials for transformation
            PolynomialList[]        Deriv     = Kref.GetInterpolationPolynomials1stDeriv(cl.Type);
            MultidimensionalArray[] DerivEval = new MultidimensionalArray[D];
            for (int d = 0; d < D; d++)
            {
                DerivEval[d] = Deriv[d].Values.GetValues(TestNodes);
            }

            // evaluate Jacobian matrix
            MultidimensionalArray Jacobi = MultidimensionalArray.Create(TestNodes.NoOfNodes, D, D); // temporary storage for Jacobian matrix

            Debug.Assert(cl.TransformationParams.Dimension == 2);
            Debug.Assert(cl.TransformationParams.GetLength(1) == 3);

            for (int d1 = 0; d1 < D; d1++)
            {
                Debug.Assert(cl.TransformationParams.GetLength(0) == Deriv[d1].Count);
                MultidimensionalArray JacobiCol = Jacobi.ExtractSubArrayShallow(-1, -1, d1);
                JacobiCol.Multiply(1.0, DerivEval[d1], cl.TransformationParams, 0.0, "kd", "kn", "nd");
            }

            // do the tests
            NegativeJacobianFlag = false;
            PositiveJacobianFlag = false;
            double MinAbsJacobiDet = double.MaxValue;
            double MaxAbsJacobiDet = 0.0;

            for (int n = 0; n < TestNodes.NoOfNodes; n++)
            {
                double detJac = Jacobi.ExtractSubArrayShallow(n, -1, -1).Determinant();
                if (detJac <= 0)
                {
                    NegativeJacobianFlag = true;
                }
                if (detJac > 0)
                {
                    PositiveJacobianFlag = true;
                }

                MinAbsJacobiDet = Math.Min(MinAbsJacobiDet, detJac.Abs());
                MaxAbsJacobiDet = Math.Max(MaxAbsJacobiDet, detJac.Abs());
            }

            if ((MaxAbsJacobiDet - MinAbsJacobiDet) / MinAbsJacobiDet <= 1.0e-8)
            {
                Linear = true;
            }
            else
            {
                Linear = false;
            }
        }