protected override SayeQuadRule SetGaussQuadratureNodes(SayeSquare arg) { //Aquire needed data //------------------------------------------------------------------------------------------------------------ QuadRule gaussRule_2D = Square.Instance.GetQuadratureRule(order); MultidimensionalArray nodes_GaussRule_2D = ((MultidimensionalArray)gaussRule_2D.Nodes).CloneAs(); MultidimensionalArray weights_GaussRule_2D = gaussRule_2D.Weights.CloneAs(); double[] diameters = arg.Diameters; MultidimensionalArray centerArr = arg.GetCellCenter().ExtractSubArrayShallow(new int[] { 0, -1 }); double jacobian = diameters[0] * diameters[1]; //AffineTransformation of nodes, scale weights //------------------------------------------------------------------------------------------------------------ //Scale Nodes for (int i = 0; i < 2; ++i) { nodes_GaussRule_2D.ColScale(i, diameters[i]); } //Scale Weights weights_GaussRule_2D.Scale(jacobian); //Move Nodes int[] index = new int[] { 0, -1 }; for (int i = 0; i < gaussRule_2D.NoOfNodes; ++i) { index[0] = i; nodes_GaussRule_2D.AccSubArray(1, centerArr, index); } //Set return data //------------------------------------------------------------------------------------------------------------ SayeQuadRule transformed_GaussRule_2D = new SayeQuadRule(nodes_GaussRule_2D, weights_GaussRule_2D); return(transformed_GaussRule_2D); }
private QuadRule CombineQr(QuadRule qrEdge, CellBoundaryQuadRule givenRule, int iFace) { int D = grd.SpatialDimension; var volSplx = m_cellBndQF.RefElement; int coD = D - 1; Debug.Assert(this.RefElement.SpatialDimension == coD); // extract edge rule // ----------------- int i0 = 0, iE = 0; for (int i = 0; i < iFace; i++) { i0 += givenRule.NumbersOfNodesPerFace[i]; } iE = i0 + givenRule.NumbersOfNodesPerFace[iFace] - 1; if (iE < i0) { // rule is empty (measure is zero). if (qrEdge == null) { QuadRule ret = new QuadRule(); ret.OrderOfPrecision = int.MaxValue - 1; ret.Nodes = new NodeSet(this.RefElement, 1, Math.Max(1, D - 1)); ret.Weights = MultidimensionalArray.Create(1); // this is an empty rule, since the weight is zero! // (rules with zero nodes may cause problems at various places.) return(ret); } else { qrEdge.Nodes.Scale(0.5); qrEdge.Weights.Scale(0.5); return(qrEdge); } } MultidimensionalArray NodesVol = givenRule.Nodes.ExtractSubArrayShallow(new int[] { i0, 0 }, new int[] { iE, D - 1 }); MultidimensionalArray Weigts = givenRule.Weights.ExtractSubArrayShallow(new int[] { i0 }, new int[] { iE }).CloneAs(); NodeSet Nodes = new NodeSet(this.RefElement, iE - i0 + 1, coD); volSplx.GetInverseFaceTrafo(iFace).Transform(NodesVol, Nodes); Nodes.LockForever(); //Debug.Assert((Weigts.Sum() - grd.Grid.GridSimplex.EdgeSimplex.Volume).Abs() < 1.0e-6, "i've forgotten the gramian"); // combine // ------- if (qrEdge == null) { // no rule defined yet - just set the one we have got // ++++++++++++++++++++++++++++++++++++++++++++++++++ qrEdge = new QuadRule(); qrEdge.Weights = Weigts; qrEdge.Nodes = Nodes; qrEdge.OrderOfPrecision = givenRule.OrderOfPrecision; } else { // take the mean of already defined and new rule // +++++++++++++++++++++++++++++++++++++++++++++ int L1 = qrEdge.Nodes.GetLength(0); int L2 = Nodes.GetLength(0); Debug.Assert(coD == qrEdge.Nodes.GetLength(1)); NodeSet newNodes = new NodeSet(this.RefElement, L1 + L2, coD); newNodes.SetSubArray(qrEdge.Nodes, new int[] { 0, 0 }, new int[] { L1 - 1, coD - 1 }); newNodes.SetSubArray(Nodes, new int[] { L1, 0 }, new int[] { L1 + L2 - 1, coD - 1 }); newNodes.LockForever(); MultidimensionalArray newWeights = MultidimensionalArray.Create(L1 + L2); newWeights.AccSubArray(0.5, qrEdge.Weights, new int[] { 0 }, new int[] { L1 - 1 }); newWeights.AccSubArray(0.5, Weigts, new int[] { L1 }, new int[] { L1 + L2 - 1 }); double oldSum = qrEdge.Weights.Sum(); double newSum = Weigts.Sum(); WeightInbalance += Math.Abs(oldSum - newSum); qrEdge.Nodes = newNodes; qrEdge.Weights = newWeights; qrEdge.OrderOfPrecision = Math.Min(qrEdge.OrderOfPrecision, givenRule.OrderOfPrecision); } // return // ------ return(qrEdge); }