protected override void AllocateBuffers(int NoOfItems, NodeSet ruleNodes) { base.AllocateBuffers(NoOfItems, ruleNodes); int NoOfNodes = ruleNodes.GetLength(0); fieldvalsB.Allocate(NoOfItems, NoOfNodes); }
protected override void AllocateBuffers(int NoOfItems, NodeSet rule) { base.AllocateBuffers(NoOfItems, rule); int NoOfNodes = rule.GetLength(0); if (m_func != null || m_Map != null) { m_NodesTransformed.Allocate(new int[] { NoOfItems, NoOfNodes, GridDat.SpatialDimension }); } }
protected override void AllocateBuffers(int NoOfItems, NodeSet rule) { base.AllocateBuffers(NoOfItems, rule); int NoOfNodes = rule.GetLength(0); if (evalRes == null) { evalRes = new MultidimensionalArray[m_fields.Length]; } for (int f = 0; f < m_fields.Length; f++) { evalRes[f] = MultidimensionalArray.Create(NoOfItems, NoOfNodes); } int D = GridDat.SpatialDimension; X = MultidimensionalArray.Create(NoOfItems, NoOfNodes, D); }
protected override void Evaluate(int i0, int Length, QuadRule rule, MultidimensionalArray EvalResult) { NodeSet NodesUntransformed = rule.Nodes; int M = NodesUntransformed.GetLength(0); //int D = NodesUntransformed.GetLength(1); MultidimensionalArray fieldvalsA = EvalResult.ResizeShallow(new int[] { Length, NodesUntransformed.GetLength(0) }); fieldvalsA.Clear(); m_FieldA.Evaluate(i0, Length, NodesUntransformed, fieldvalsA, 1.0); fieldvalsB.Clear(); m_FieldB.Evaluate(i0, Length, NodesUntransformed, fieldvalsB, 1.0); for (int j = 0; j < Length; j++) { for (int m = 0; m < M; m++) { EvalResult[j, m, 0] = fieldvalsA[j, m] * fieldvalsB[j, m]; } } }
/// <summary> /// /// </summary> /// <param name="CellPairs"> /// 1st index: list of cells <br/> /// 2nd index: in {0, 1} /// </param> /// <param name="M"> /// 1st index: corresponds with 1st index of <paramref name="CellPairs"/><br/> /// 2nd index: matrix row index <br/> /// 3rd index: matrix column index /// </param> /// <param name="Minv">the inverse of <paramref name="M"/></param> /// <remarks> /// Let \f$ K_j \f$ and \f$ K_i \f$ be two different cells with a linear-affine /// transformation to the reference element. /// Here, \f$ j \f$=<paramref name="CellPairs"/>[a,0] and \f$ i \f$=<paramref name="CellPairs"/>[a,1]. /// The DG-basis in these cells can uniquely be represented as /// \f[ /// \phi_{j n} (\vec{x}) = p_n (\vec{x}) \vec{1}_{K_j} (\vec{x}) /// \textrm{ and } /// \phi_{i m} (\vec{x}) = q_m (\vec{x}) \vec{1}_{K_i} (\vec{x}) /// \f] /// where \f$ \vec{1}_X \f$ denotes the characteristic function for set \f$ X \f$ /// and \f$ p_n\f$ and \f$ p_m\f$ are polynomials. /// Then, for the output \f$ M \f$ =<paramref name="M"/>[a,-,-] fulfills /// \f[ /// \phi_{j n} + \sum_{m} M_{m n} \phi_{i m} /// = /// p_n \vec{1}_{K_j \cup K_i} /// \f] /// </remarks> public void GetExtrapolationMatrices(int[,] CellPairs, MultidimensionalArray M, MultidimensionalArray Minv = null) { var m_Context = this.GridDat; int N = this.Length; int Esub = CellPairs.GetLength(0); int JE = this.GridDat.iLogicalCells.Count; int J = this.GridDat.iLogicalCells.NoOfLocalUpdatedCells; if (CellPairs.GetLength(1) != 2) { throw new ArgumentOutOfRangeException("second dimension is expected to be 2!"); } if (M.Dimension != 3) { throw new ArgumentException(); } if (M.GetLength(0) != Esub) { throw new ArgumentException(); } if (M.GetLength(1) != N || M.GetLength(2) != N) { throw new ArgumentException(); } if (Minv != null) { if (Minv.GetLength(0) != Esub) { throw new ArgumentException(); } if (Minv.GetLength(1) != N || Minv.GetLength(2) != N) { throw new ArgumentException(); } } MultidimensionalArray NodesGlobal = new MultidimensionalArray(3); MultidimensionalArray Minv_tmp = MultidimensionalArray.Create(N, N); MultidimensionalArray M_tmp = MultidimensionalArray.Create(N, N); for (int esub = 0; esub < Esub; esub++) // loop over the cell pairs... { int jCell0 = CellPairs[esub, 0]; int jCell1 = CellPairs[esub, 1]; if (jCell0 < 0 || jCell0 >= JE) { throw new ArgumentOutOfRangeException("Cell index out of range."); } if (jCell1 < 0 || jCell1 >= JE) { throw new ArgumentOutOfRangeException("Cell index out of range."); } bool swap; if (jCell0 >= J) { //if(true) { swap = true; int a = jCell0; jCell0 = jCell1; jCell1 = a; } else { swap = false; } if (!m_Context.iGeomCells.IsCellAffineLinear(jCell0)) { throw new NotSupportedException("Currently not supported for curved cells."); } if (!m_Context.iGeomCells.IsCellAffineLinear(jCell1)) { throw new NotSupportedException("Currently not supported for curved cells."); } Debug.Assert(jCell0 < J); var cellMask = new CellMask(m_Context, new[] { new Chunk() { i0 = jCell0, Len = 1 } }, MaskType.Geometrical); // we project the basis function from 'jCell1' onto 'jCell0' CellQuadrature.GetQuadrature(new int[2] { N, N }, m_Context, (new CellQuadratureScheme(true, cellMask)).Compile(m_Context, this.Degree * 2), // integrate over target cell delegate(int i0, int Length, QuadRule QR, MultidimensionalArray _EvalResult) { NodeSet nodes_Cell0 = QR.Nodes; Debug.Assert(Length == 1); NodesGlobal.Allocate(1, nodes_Cell0.GetLength(0), nodes_Cell0.GetLength(1)); m_Context.TransformLocal2Global(nodes_Cell0, jCell0, 1, NodesGlobal, 0); var nodes_Cell1 = new NodeSet(GridDat.iGeomCells.GetRefElement(jCell1), nodes_Cell0.GetLength(0), nodes_Cell0.GetLength(1)); m_Context.TransformGlobal2Local(NodesGlobal.ExtractSubArrayShallow(0, -1, -1), nodes_Cell1, jCell1, null); nodes_Cell1.LockForever(); var phi_0 = this.CellEval(nodes_Cell0, jCell0, 1).ExtractSubArrayShallow(0, -1, -1); var phi_1 = this.CellEval(nodes_Cell1, jCell1, 1).ExtractSubArrayShallow(0, -1, -1); var EvalResult = _EvalResult.ExtractSubArrayShallow(0, -1, -1, -1); EvalResult.Multiply(1.0, phi_1, phi_0, 0.0, "kmn", "kn", "km"); }, /*_SaveIntegrationResults:*/ delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) { Debug.Assert(Length == 1); var res = ResultsOfIntegration.ExtractSubArrayShallow(0, -1, -1); Minv_tmp.Clear(); Minv_tmp.Acc(1.0, res); }).Execute(); // compute the inverse Minv_tmp.InvertTo(M_tmp); // store if (!swap) { M.ExtractSubArrayShallow(esub, -1, -1).AccMatrix(1.0, M_tmp); if (Minv != null) { Minv.ExtractSubArrayShallow(esub, -1, -1).AccMatrix(1.0, Minv_tmp); } } else { M.ExtractSubArrayShallow(esub, -1, -1).AccMatrix(1.0, Minv_tmp); if (Minv != null) { Minv.ExtractSubArrayShallow(esub, -1, -1).AccMatrix(1.0, M_tmp); } } } }
/// <summary> /// Integrand evaluation. /// </summary> protected override void Evaluate(int i0, int Length, QuadRule rule, MultidimensionalArray EvalResult) { NodeSet NodesUntransformed = rule.Nodes; int M = NodesUntransformed.GetLength(0); int D = NodesUntransformed.GetLength(1); // evaluate scalar function ans store result in 'EvalResult' // ========================================================= Debug.Assert(!((m_func != null) && (m_funcEx != null))); if (m_func != null || m_Map != null) { GridDat.TransformLocal2Global(NodesUntransformed, i0, Length, m_NodesTransformed, 0); } if (m_func != null) { MultidimensionalArray inp = m_NodesTransformed.ResizeShallow(new int[] { Length *M, D }); MultidimensionalArray outp = EvalResult.ResizeShallow(new int[] { Length *M }); m_func(inp, outp); Debug.Assert(m_funcEx == null); } if (m_funcEx != null) { m_funcEx(i0, Length, NodesUntransformed, EvalResult.ExtractSubArrayShallow(-1, -1, 0)); Debug.Assert(m_func == null); } if (m_Map == null) { // L2 error branch // +++++++++++++++ MultidimensionalArray fieldvals = EvalResult.ResizeShallow(new int[] { Length, NodesUntransformed.GetLength(0) }); m_Owner.Evaluate(i0, Length, NodesUntransformed, fieldvals, -1.0); for (int j = 0; j < Length; j++) { for (int m = 0; m < M; m++) { double e; e = EvalResult[j, m, 0]; EvalResult[j, m, 0] = e * e; } } } else { // arbitrary mapping branch // ++++++++++++++++++++++++ MultidimensionalArray fieldvals = MultidimensionalArray.Create(new int[] { Length, NodesUntransformed.GetLength(0) }); m_Owner.Evaluate(i0, Length, NodesUntransformed, fieldvals, -1.0); double[] X = new double[D]; for (int j = 0; j < Length; j++) { for (int m = 0; m < M; m++) { double e; e = EvalResult[j, m, 0]; for (int d = 0; d < D; d++) { X[d] = m_NodesTransformed[j, m, d]; } EvalResult[j, m, 0] = this.m_Map(X, fieldvals[j, m], e); } } } }