MultidimensionalArray StokesAnsatzRHS(Basis TestBasis, CellBoundaryQuadratureScheme cellBndSchme, CellMask _mask, int order) { var GridDat = this.tracker.GridDat; CellBoundaryQuadrature <CellBoundaryQuadRule> qBnd = null; int N = TestBasis.Length; int D = GridDat.SpatialDimension; MultidimensionalArray RHS = MultidimensionalArray.Create(D, N, _mask.NoOfItemsLocally); double[] CellN = new double[D]; // cell normal double[] SurfN = new double[D]; // level-set normal double[] OutwardTang = new double[D]; // level-set tangent, outward of cell if (D != 2) { throw new NotSupportedException("Currently only supported for spatial dimension of 2."); } //MultidimensionalArray Nudes = null; int jSgrd = 0; qBnd = CellBoundaryQuadrature <CellBoundaryQuadRule> .GetQuadrature(new int[] { D, N }, GridDat, cellBndSchme.Compile(GridDat, order), delegate(int i0, int Length, CellBoundaryQuadRule NS, MultidimensionalArray EvalResult) { // Evaluate //MultidimensionalArray BasisValues = TestBasis.Evaluate(0); // reference //var LSNormals = LsTrk.GetLevelSetReferenceNormals(iLevSet, 0, i0, Length); // reference MultidimensionalArray BasisValues = TestBasis.CellEval(NS.Nodes, i0, Length); // physical MultidimensionalArray LSNormals = this.LevelSetData.GetLevelSetNormals(NS.Nodes, i0, Length); // physical for (int i = 0; i < Length; i++) // loop over cells //if(i0 + i == 1) { // EvalResult.ExtractSubArrayShallow(i, -1, -1, -1).Clear(); // continue; //} { CellBoundaryQuadRule cR = qBnd.CurrentRule; int[] NodesPerEdge = cR.NumbersOfNodesPerFace; var Kref = cR.RefElement; int NoOfFaces = Kref.NoOfFaces; int iNode = 0; Debug.Assert(NoOfFaces == NodesPerEdge.Length); for (int e = 0; e < NoOfFaces; e++) // loop over the faces of the cell { if (NodesPerEdge[e] <= 0) { continue; } // reference: //for (int d = 0; d < D; d++) { // CellN[d] = Kref.FaceNormals[e, d]; //} // ~~~~ // physical: var FaceNodes = new NodeSet(Kref, cR.Nodes.ExtractSubArrayShallow(new int[] { iNode, 0 }, new int[] { iNode + NodesPerEdge[e] - 1, D - 1 })); var FaceNormals = MultidimensionalArray.Create(NodesPerEdge[e], D); GridDat.Edges.GetNormalsForCell(FaceNodes, i0, e, FaceNormals); // ~~~~ for (int _n = 0; _n < NodesPerEdge[e]; _n++) // loop over nodes in one edge { for (int d = 0; d < D; d++) { SurfN[d] = LSNormals[i, iNode, d]; CellN[d] = FaceNormals[_n, d]; // physical } tangente(SurfN, CellN, OutwardTang); for (int n = 0; n < N; n++) // loop over Test polynomials (the same as the basis polynomials) { for (int d = 0; d < D; d++) // loop over spatial direction { EvalResult[i, iNode, d, n] = BasisValues[i, iNode, n] * OutwardTang[d]; // physical //EvalResult[i, iNode, d, n] = BasisValues[iNode, n]*OutwardTang[d]; // reference } } iNode++; } } Debug.Assert(iNode == EvalResult.GetLength(1)); } }, delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) { // SaveIntegrationResults for (int i = 0; i < Length; i++) { var ResPart = RHS.ExtractSubArrayShallow(new int[] { 0, 0, jSgrd }, new int[] { D - 1, N - 1, jSgrd - 1 }); int NoOfFaces = ResultsOfIntegration.GetLength(1); for (int e = 0; e < NoOfFaces; e++) { var ip = ResultsOfIntegration.ExtractSubArrayShallow(new int[] { i, e, 0, 0 }, new int[] { i - 1, e - 1, D - 1, N - 1 }); ResPart.Acc(1.0, ip); } jSgrd++; } }, cs : CoordinateSystem.Physical); qBnd.Execute(); var ret = RHS.ResizeShallow(N * D, _mask.NoOfItemsLocally); return(ret); }
protected MultidimensionalArray GaußAnsatzRHS(DivergenceFreeBasis TestBasis, CellBoundaryQuadratureScheme cellBndScheme, CellMask _mask, int order) { var _Context = this.tracker.GridDat; int D = this.tracker.GridDat.Grid.SpatialDimension; int N = TestBasis.Count; var coordSys = CoordinateSystem.Reference; var LsTrk = this.tracker; int Nrhs = _mask.NoOfItemsLocally; Debug.Assert(N % D == 0); N /= D; MultidimensionalArray RHS = MultidimensionalArray.Create(N, Nrhs); var splx = this.Kref; int NoOfFaces = splx.NoOfFaces; //var normals = _Context.GridDat.Normals; CellBoundaryQuadrature <CellBoundaryQuadRule> qBnd = null; int jSgrd = 0; qBnd = CellBoundaryQuadrature <CellBoundaryQuadRule> .GetQuadrature(new int[] { N }, _Context, cellBndScheme.Compile(_Context, order), delegate(int i0, int Length, CellBoundaryQuadRule QR, MultidimensionalArray EvalResult) { // Evaluate NodeSet Nodes = QR.Nodes; MultidimensionalArray BasisValues; if (coordSys == CoordinateSystem.Physical) { //BasisValues = TestBasis.CellEval(Nodes, i0, Length); throw new NotImplementedException("todo"); } else if (coordSys == CoordinateSystem.Reference) { BasisValues = TestBasis.Values.GetValues(Nodes); } else { throw new NotImplementedException(); } for (int i = 0; i < Length; i++) // loop over cells { CellBoundaryQuadRule cR = qBnd.CurrentRule; int[] NodesPerEdge = cR.NumbersOfNodesPerFace; Debug.Assert(object.ReferenceEquals(splx, cR.RefElement)); int iNode = 0; Debug.Assert(NoOfFaces == NodesPerEdge.Length); for (int e = 0; e < NoOfFaces; e++) // loop over the faces of the cell { for (int _n = 0; _n < NodesPerEdge[e]; _n++) // loop over nodes in one edge { for (int n = 0; n < N; n++) // loop over Test polynomials (the same as the basis polynomials) { double acc = 0; for (int d = 0; d < D; d++) // loop over spatial directions { if (coordSys == CoordinateSystem.Physical) { throw new NotImplementedException("todo"); //int q = _Context.GridDat.LocalCellIndexToEdges[i+i0, e]; //int iEdge = Math.Abs(q) - 1; //double Nsign = Math.Sign(q); //double Nd = normals[iEdge, d]; //EvalResult[i, iNode, n, d] = BasisValues[i, iNode, n]*Nd*Nsign; } else { Debug.Assert(coordSys == CoordinateSystem.Reference); double Nd = splx.FaceNormals[e, d]; //Debug.Assert(Nd == normals[iEdge, d]*Nsign); acc += BasisValues[iNode, n *D + d] * Nd; } } EvalResult[i, iNode, n] = acc; } iNode++; } } Debug.Assert(iNode == EvalResult.GetLength(1)); } }, delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) { // SaveIntegrationResults for (int i = 0; i < Length; i++) { var ResPart = RHS.ExtractSubArrayShallow(new int[] { 0, jSgrd }, new int[] { N - 1, jSgrd - 1 }); for (int e = 0; e < NoOfFaces; e++) { var ip = ResultsOfIntegration.ExtractSubArrayShallow(new int[] { i, e, 0 }, new int[] { i - 1, e - 1, N - 1 }); ResPart.Acc(1.0, ip); } jSgrd++; } }, cs : coordSys); qBnd.Execute(); return(RHS); }