private static void CheckArgs(int j0, int L, NodeSet NS, Basis basis, MultidimensionalArray Coördinates, MultidimensionalArray ResultAcc, out int D, out int N, out int M, out bool AffineLinear) { D = basis.GridDat.SpatialDimension; // spatial dimension N = basis.GetLength(j0); // number of coordinates per cell M = NS.NoOfNodes; // number of nodes AffineLinear = basis.GridDat.iGeomCells.IsCellAffineLinear(j0); Debug.Assert(basis.GetType() == typeof(Basis)); Debug.Assert(Coördinates.Dimension == 2); Debug.Assert(Coördinates.GetLength(0) == L); Debug.Assert(Coördinates.GetLength(1) == N); #if DEBUG for (int i = 1; i < L; i++) { int jCell = j0 + i; Debug.Assert(basis.GridDat.iGeomCells.IsCellAffineLinear(jCell) == AffineLinear); Debug.Assert(basis.GetLength(jCell) == N); } #endif }
private static void CheckArgs(int j0, int L, NodeSet NS, Basis basis, MultidimensionalArray Coördinates, MultidimensionalArray ResultAcc, out int D, out int N, out int M, out bool AffineLinear) { int[] g2l = basis.GridDat.iGeomCells.GeomCell2LogicalCell; D = basis.GridDat.SpatialDimension; // spatial dimension if (g2l == null) { N = basis.GetLength(j0); // number of coordinates per cell -- standard grid } else { N = basis.GetLength(g2l[j0]); // number of coordinates per cell -- aggregation grid } M = NS.NoOfNodes; // number of nodes AffineLinear = basis.GridDat.iGeomCells.IsCellAffineLinear(j0); Debug.Assert(basis.GetType() == typeof(Basis)); Debug.Assert(Coördinates.Dimension == 2); Debug.Assert(Coördinates.GetLength(1) == N); #if DEBUG for (int i = 1; i < L; i++) { int jCell = j0 + i; Debug.Assert(basis.GridDat.iGeomCells.IsCellAffineLinear(jCell) == AffineLinear); if (g2l == null) { Debug.Assert(basis.GetLength(jCell) == N); } else { Debug.Assert(basis.GetLength(g2l[jCell]) == N); } } #endif }
protected static void EvaluateEdgeInternal(int e0, int Len, NodeSet NS, Basis _Basis, MultidimensionalArray Coord, MultidimensionalArray valIN, MultidimensionalArray valOT, MultidimensionalArray meanValIN, MultidimensionalArray meanValOT, MultidimensionalArray gradIN, MultidimensionalArray gradOT, double ResultPreScale) { // checks and init // =============== var grd = _Basis.GridDat; int NoOfNodes = NS.NoOfNodes; bool AffineLinear = grd.iGeomEdges.IsEdgeAffineLinear(e0); Debug.Assert(NS.GetNodeCoordinateSystem(grd) == NodeCoordinateSystem.EdgeCoord); Debug.Assert(valIN == null || valIN.Dimension == 2); Debug.Assert(valOT == null || valOT.Dimension == 2); Debug.Assert(valIN == null || valIN.GetLength(0) == Len); Debug.Assert(valOT == null || valOT.GetLength(0) == Len); Debug.Assert(valIN == null || valIN.GetLength(1) == NoOfNodes); Debug.Assert(valOT == null || valOT.GetLength(1) == NoOfNodes); int[,] trfIdx = grd.iGeomEdges.Edge2CellTrafoIndex; int[,] E2Cl = grd.iGeomEdges.LogicalCellIndices; int[,] E2Cg = grd.iGeomEdges.CellIndices; // transform DG coördinates // ======================== int Nin = _Basis.GetLength(E2Cl[e0, 0]); int Not = Nin; #if DEBUG for (int e = 0; e < Len; e++) { int iEdge = e + e0; int jCellIN = E2Cl[iEdge, 0]; int jCellOT = E2Cl[iEdge, 1]; Debug.Assert(_Basis.GetLength(jCellIN) == Nin); if (jCellOT >= 0) { Debug.Assert(_Basis.GetLength(jCellOT) == Not); } } #endif int iBufIN, iBufOT = 0; MultidimensionalArray trfCoördinatesIN = TempBuffer.GetTempMultidimensionalarray(out iBufIN, Len, Nin); MultidimensionalArray trfCoördinatesOT = Not > 0 ? TempBuffer.GetTempMultidimensionalarray(out iBufOT, Len, Not) : null; TransformCoördinatesEdge(e0, Len, grd, Coord, Nin, Not, _Basis.Degree, AffineLinear, trfCoördinatesIN, trfCoördinatesOT); // Evaluate // ======== unsafe { fixed(int *pTrfIndex = trfIdx) { MultidimensionalArray BasisValues = null; Debug.Assert((valIN != null) == (valOT != null)); if (valIN != null) { // compute the values // ------------------- BasisValues = grd.ChefBasis.EdgeEval.GetValues(NS, e0, Len, _Basis.Degree); Debug.Assert(BasisValues.Dimension == 3); MultidimensionalArray BasisValuesIN, BasisValuesOT; if (BasisValues.GetLength(2) > Nin) { BasisValuesIN = BasisValues.ExtractSubArrayShallow(new int[] { 0, 0, 0 }, new int[] { BasisValues.GetLength(0) - 1, NoOfNodes - 1, Nin - 1 }); } else { BasisValuesIN = BasisValues; } if (BasisValues.GetLength(2) > Not) { if (Nin == Not) { BasisValuesOT = BasisValuesIN; } else { BasisValuesOT = BasisValues.ExtractSubArrayShallow(new int[] { 0, 0, 0 }, new int[] { BasisValues.GetLength(0) - 1, NoOfNodes - 1, Nin - 1 }); } } else { BasisValuesOT = BasisValues; } { valIN.Multiply(1.0, trfCoördinatesIN, BasisValuesIN, ResultPreScale, ref mp_ik_im_Tikm, pTrfIndex, pTrfIndex, trfPreOffset_A: 0, trfCycle_A: 0, trfPostOffset_A: 0, trfPreOffset_B: (2 * e0), trfCycle_B: 2, trfPostOffset_B: 0); } if (Not > 0) { valOT.Multiply(1.0, trfCoördinatesOT, BasisValuesOT, ResultPreScale, ref mp_ik_im_Tikm, pTrfIndex, pTrfIndex, trfPreOffset_A: 0, trfCycle_A: 0, trfPostOffset_A: 0, trfPreOffset_B: (2 * e0 + 1), trfCycle_B: 2, trfPostOffset_B: 0); } } Debug.Assert((meanValIN != null) == (meanValOT != null)); if (meanValIN != null) { // compute the mean values // ----------------------- var _Basis0Values = BasisValues; if (_Basis0Values == null) { _Basis0Values = grd.ChefBasis.EdgeEval.GetValues(NS, e0, Len, 0); } // assume the 0-th basis polynomial \f$ \phi_0 \f$ is constant! _Basis0Values = _Basis0Values.ExtractSubArrayShallow(new int[] { 0, 0, 0 }, new int[] { BasisValues.GetLength(0) - 1, -1, -1 }); // DG coördinates for the 0-th mode: var _trfCoördinatesIN = trfCoördinatesIN.ExtractSubArrayShallow(new int[] { 0, 0 }, new int[] { Len - 1, -1 }); var _trfCoördinatesOT = trfCoördinatesOT.ExtractSubArrayShallow(new int[] { 0, 0 }, new int[] { Len - 1, -1 }); { meanValIN.Multiply(1.0, _trfCoördinatesIN, _Basis0Values, ResultPreScale, ref mp_i_i_Ti, pTrfIndex, pTrfIndex, trfPreOffset_A: 0, trfCycle_A: 0, trfPostOffset_A: 0, trfPreOffset_B: (2 * e0), trfCycle_B: 2, trfPostOffset_B: 0); } if (Not > 0) { meanValOT.Multiply(1.0, _trfCoördinatesOT, _Basis0Values, ResultPreScale, ref mp_i_i_Ti, pTrfIndex, pTrfIndex, trfPreOffset_A: 0, trfCycle_A: 0, trfPostOffset_A: 0, trfPreOffset_B: (2 * e0 + 1), trfCycle_B: 2, trfPostOffset_B: 0); } } Debug.Assert((gradIN != null) == (gradOT != null)); if (gradIN != null) { // compute gradient values // ----------------------- int D = grd.SpatialDimension; int iBuf2; MultidimensionalArray GradientRef = TempBuffer.GetTempMultidimensionalarray(out iBuf2, Len, NoOfNodes, D); MultidimensionalArray BasisGradValues = grd.ChefBasis.EdgeGradientEval.GetValues(NS, e0, Len, _Basis.Degree); Debug.Assert(BasisGradValues.Dimension == 4); MultidimensionalArray BasisGradValuesIN, BasisGradValuesOT; if (BasisGradValues.GetLength(2) > Nin) { BasisGradValuesIN = BasisGradValues.ExtractSubArrayShallow(new int[] { 0, 0, 0, 0 }, new int[] { BasisGradValues.GetLength(0) - 1, NoOfNodes - 1, Nin - 1, D - 1 }); } else { BasisGradValuesIN = BasisGradValues; } if (BasisGradValues.GetLength(2) > Not) { if (Nin == Not) { BasisGradValuesOT = BasisGradValuesIN; } else { BasisGradValuesOT = BasisGradValues.ExtractSubArrayShallow(new int[] { 0, 0, 0, 0 }, new int[] { BasisGradValues.GetLength(0) - 1, NoOfNodes - 1, Nin - 1, D - 1 }); } } else { BasisGradValuesOT = BasisGradValues; } if (AffineLinear) { // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // affine-linear-cell: // Inverse Jacobian different for each cell, but constant among nodes // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ var InvJacobi = grd.iGeomCells.InverseTransformation; Debug.Assert(grd is Grid.Classic.GridData, "implementation only valid for classic grid"); Debug.Assert(object.ReferenceEquals(E2Cg, E2Cl)); fixed(int *pE2Cl = E2Cl) { { GradientRef.Multiply(1.0, trfCoördinatesIN, BasisGradValuesIN, 0.0, ref mp_ike_im_Tikme, pTrfIndex, pTrfIndex, trfPreOffset_A: 0, trfCycle_A: 0, trfPostOffset_A: 0, trfPreOffset_B: (2 * e0), trfCycle_B: 2, trfPostOffset_B: 0); // gradient in reference coördinates gradIN.Multiply(1.0, InvJacobi, GradientRef, ResultPreScale, ref mp_ikd_Tied_ike, pE2Cl, pE2Cl, trfPreOffset_A: (2 * e0), trfCycle_A: 2, trfPostOffset_A: 0, trfPreOffset_B: 0, trfCycle_B: 0, trfPostOffset_B: 0); } if (Not > 0) { GradientRef.Multiply(1.0, trfCoördinatesOT, BasisGradValuesOT, 0.0, ref mp_ike_im_Tikme, pTrfIndex, pTrfIndex, trfPreOffset_A: 0, trfCycle_A: 0, trfPostOffset_A: 0, trfPreOffset_B: (2 * e0 + 1), trfCycle_B: 2, trfPostOffset_B: 0); // gradient in reference coördinates gradOT.Multiply(1.0, InvJacobi, GradientRef, ResultPreScale, ref mp_ikd_Tied_ike, pE2Cl, pE2Cl, trfPreOffset_A: (2 * e0 + 1), trfCycle_A: 2, trfPostOffset_A: 0, trfPreOffset_B: 0, trfCycle_B: 0, trfPostOffset_B: 0); } } } else { // ++++++++++++++++++++++++++++++++++++++++++++++++++++++ // curved-cell: // Inverse Jacobian different for each node and each cell // ++++++++++++++++++++++++++++++++++++++++++++++++++++++ MultidimensionalArray invJacobiIN, invJacobiOT; var TiJ = grd.InverseJacobian.GetValue_EdgeDV(NS, e0, Len); invJacobiIN = TiJ.Item1; invJacobiOT = TiJ.Item2; { GradientRef.Multiply(1.0, trfCoördinatesIN, BasisGradValuesIN, 0.0, ref mp_ike_im_Tikme, pTrfIndex, pTrfIndex, trfPreOffset_A: 0, trfCycle_A: 0, trfPostOffset_A: 0, trfPreOffset_B: (2 * e0), trfCycle_B: 2, trfPostOffset_B: 0); // gradient in reference coördinates, i.e. \f$ \nabla_{\vec{xi}} \f$ gradIN.Multiply(1.0, invJacobiIN, GradientRef, ResultPreScale, ref mp_ikd_iked_ike); // gradient in physical coördinates, i.e. \f$ \nabla_{\vec{x}}n \f$ } if (Not > 0) { GradientRef.Multiply(1.0, trfCoördinatesOT, BasisGradValuesOT, 0.0, ref mp_ike_im_Tikme, pTrfIndex, pTrfIndex, trfPreOffset_A: 0, trfCycle_A: 0, trfPostOffset_A: 0, trfPreOffset_B: (2 * e0 + 1), trfCycle_B: 2, trfPostOffset_B: 0); // gradient in reference coördinates, i.e. \f$ \nabla_{\vec{xi}} \f$ gradOT.Multiply(1.0, invJacobiOT, GradientRef, ResultPreScale, ref mp_ikd_iked_ike); // gradient in physical coördinates, i.e. \f$ \nabla_{\vec{x}} \f$ } } TempBuffer.FreeTempBuffer(iBuf2); } } } TempBuffer.FreeTempBuffer(iBufIN); if (Not > 0) { TempBuffer.FreeTempBuffer(iBufOT); } /* * { * var _BasisValues = grd.ChefBasis.EdgeEval.GetValues(NS, e0, Len, _Basis.Degree); * * * var resultINAccCheck = valIN.CloneAs(); * var resultOTAccCheck = valOT.CloneAs(); * * for(int e = 0; e < Len; e++) { * int iEdge = e + e0; * int jCellIN = E2C[iEdge, 0]; * int jCellOT = E2C[iEdge, 1]; * int iTrfIN = trfIdx[iEdge, 0]; * int iTrfOT = trfIdx[iEdge, 1]; * * for(int k = 0; k < NoOfNodes; k++) { * int BN = _Basis.GetLength(jCellIN); * * resultINAccCheck[e, k] *= ResultPreScale; * resultOTAccCheck[e, k] *= ResultPreScale; * * for(int n = 0; n < BN; n++) { * double Cinerr = trfCoördinatesIN[e, n] - Coord[jCellIN, n]; * double Coterr = jCellOT >= 0 ? trfCoördinatesOT[e, n] - Coord[jCellOT, n] : 0.0; * * if(Math.Abs(Cinerr) > 1.0e-5) * Console.WriteLine("44fuckIN" + e); * if(Math.Abs(Coterr) > 1.0e-5) * Console.WriteLine("44fuckOT" + e); * * * resultINAccCheck[e, k] += Coord[jCellIN, n] * _BasisValues[iTrfIN, k, n]; * if(jCellOT >= 0) * resultOTAccCheck[e, k] += Coord[jCellOT, n] * _BasisValues[iTrfOT, k, n]; * * } * * double Vinerr = resultINAccCheck[e, k] - valIN[e, k]; * double Voterr = jCellOT >= 0 ? resultOTAccCheck[e, k] - valOT[e, k] : 0.0; * * * * if(Math.Abs(Vinerr) > 1.0e-5) * Console.WriteLine("44fuckIN" + e); * if(Math.Abs(Voterr) > 1.0e-5) * Console.WriteLine("44fuckOT" + e); * } * * } * * //resultINAcc.Set(resultINAccCheck); * //resultOTAcc.Set(resultOTAccCheck); * } */ }