Beispiel #1
0
        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);
        }
Beispiel #2
0
        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);
        }