/// <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))); }
/// <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); }
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; } }