Ejemplo n.º 1
0
        /// <summary>
        /// two <see cref="Basis"/>-objects are equal, if their polynomial list
        /// (<see cref="Polynomials"/>) is equal (equal Guid for each entry).
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public override bool Equals(object obj)
        {
            if (obj.GetType() != typeof(Basis))
            {
                return(false);
            }

            Basis other = (Basis)obj;

            if (!object.ReferenceEquals(other.m_GridDat, this.m_GridDat))
            {
                return(false);
            }

            int L = m_GridDat.iGeomCells.RefElements.Length;

            Debug.Assert(this.Polynomials.Count == L);
            Debug.Assert(other.Polynomials.Count == L);

            for (int l = 0; l < L; l++)
            {
                int N = this.Polynomials[l].Count;
                if (other.Polynomials[l].Count != N)
                {
                    return(false);
                }

                for (int i = N - 1; i >= 0; i--)
                {
                    if (!this.Polynomials[l][i].Equals(other.Polynomials[l][i]))
                    {
                        return(false);
                    }
                }
            }


            return(true);
        }
Ejemplo n.º 2
0
        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
        }
Ejemplo n.º 3
0
        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
        }
Ejemplo n.º 4
0
        public override void GetRestrictionMatrix(BlockMsrMatrix RST, MultigridMapping mgMap, int iF)
        {
            if (!object.ReferenceEquals(mgMap.AggBasis[iF], this))
            {
                throw new ArgumentException();
            }

            //MsrMatrix RST = new MsrMatrix(mgMap.Partitioning, mgMap.ProblemMapping);
            int JAGG = this.AggGrid.iLogicalCells.NoOfLocalUpdatedCells;

            int[] degrees = mgMap.DgDegree;
            int   NoFld   = degrees.Length;

            int N_rest; // = new int[NoFld];
            int N_full; // = new int[NoFld];
            {
                BoSSS.Foundation.Basis b   = mgMap.ProblemMapping.BasisS[iF];
                BoSSS.Foundation.Basis NxB = (b is BoSSS.Foundation.XDG.XDGBasis) ? ((BoSSS.Foundation.XDG.XDGBasis)b).NonX_Basis : b;
                N_rest = NxB.Polynomials[0].Where(poly => poly.AbsoluteDegree <= degrees[iF]).Count();
                N_full = NxB.Length;
            }


            int mgMap_Offset = mgMap.Partitioning.i0;

            for (int jAgg = 0; jAgg < JAGG; jAgg++)
            {
                int[] AgCell = this.AggGrid.iLogicalCells.AggregateCellToParts[jAgg];
                int   K      = AgCell.Length;


                int NoSpc_Agg = this.NoOfSpecies[jAgg];                  // number of species in aggregate cell
                for (int iSpc_Agg = 0; iSpc_Agg < NoSpc_Agg; iSpc_Agg++) // loop over all species in aggregate cell
                {
                    {                                                    // loop over DG fields in the mapping
                        int NROW = N_rest;
                        int NCOL = N_full;
                        Debug.Assert(mgMap.AggBasis[iF].GetLength(jAgg, degrees[iF]) == N_rest * NoSpc_Agg);
                        int i0Agg_Loc = mgMap.LocalUniqueIndex(iF, jAgg, N_rest * iSpc_Agg);
                        int i0Agg     = i0Agg_Loc + mgMap_Offset;
                        Debug.Assert(i0Agg >= mgMap.Partitioning.i0);
                        Debug.Assert(i0Agg < mgMap.Partitioning.iE);

                        if (this.SpeciesIndexMapping[jAgg] == null)
                        {
                            Debug.Assert(NoSpc_Agg == 1);
                            Debug.Assert(NoSpc_Agg == 1);


                            // default branch:
                            // use restriction/prolongation from un-cut basis
                            // +++++++++++++++++++++++++++++++++++++++++++++

                            MultidimensionalArray Trf = base.CompositeBasis[jAgg];

                            for (int k = 0; k < K; k++)  // loop over the cells which form the aggregated cell...
                            {
                                int jCell  = AgCell[k];
                                int i0Full = mgMap.ProblemMapping.GlobalUniqueCoordinateIndex(iF, jCell, 0);
                                var Block  = Trf.ExtractSubArrayShallow(k, -1, -1);


                                for (int nRow = 0; nRow < NROW; nRow++)
                                {
                                    for (int nCol = 0; nCol < NCOL; nCol++)
                                    {
                                        RST[i0Agg + nRow, i0Full + nCol] = Block[nCol, nRow];
                                    }
                                }
                            }
                        }
                        else
                        {
                            int NoSpc = this.NoOfSpecies[jAgg];
                            int[,] sim = SpeciesIndexMapping[jAgg];
                            Debug.Assert(sim.GetLength(0) == NoSpc);
                            Debug.Assert(sim.GetLength(1) == K);

                            MultidimensionalArray Trf;
                            if (this.XCompositeBasis[jAgg] == null || this.XCompositeBasis[jAgg][iSpc_Agg] == null)
                            {
                                Trf = base.CompositeBasis[jAgg];
                            }
                            else
                            {
                                Trf = this.XCompositeBasis[jAgg][iSpc_Agg];
                            }

                            for (int k = 0; k < K; k++)  // loop over the cells which form the aggregated cell...
                            {
                                int jCell    = AgCell[k];
                                int iSpcBase = sim[iSpc_Agg, k];

                                if (iSpcBase < 0)
                                {
                                    //for(int n = 0; n < N; n++)
                                    //    FulCoords[k, n] = 0;
                                }
                                else
                                {
                                    int i0Full = mgMap.ProblemMapping.GlobalUniqueCoordinateIndex(iF, jCell, iSpcBase * N_full);
                                    var Block  = Trf.ExtractSubArrayShallow(k, -1, -1);

                                    for (int nRow = 0; nRow < NROW; nRow++)
                                    {
                                        for (int nCol = 0; nCol < NCOL; nCol++)
                                        {
                                            RST[i0Agg + nRow, i0Full + nCol] = Block[nCol, nRow];
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            //return RST;
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Polynomial extrapolation between cells.
        /// </summary>
        /// <param name="CellPairs">
        /// A list of which cells should be extrapolated to which cells. <br/>
        /// 1st index: enumeration;<br/>
        /// 2nd index, in the range of 0 to 1: 0: cell to extrapolate from (source), i.e. values in this cell remain unchanged.
        /// 1: cell to extrapolate to (target), the values in this cell will be the polynomial continuation of the "cell to extrapolate from".
        /// </param>
        /// <param name="scl">
        /// optional scaling for the target cells
        /// </param>
        /// <param name="beta">
        /// optional input scaling scaling for the target cells
        /// </param>
        virtual public void CellExtrapolation <T, U>(int[,] CellPairs, T scl = default(T), U beta = default(U))
            where T : IList <double>
            where U : IList <double> //
        {
            //MPICollectiveWatchDog.Watch();

            if (CellPairs.GetLength(1) != 2)
            {
                throw new ArgumentOutOfRangeException("second dimension is expected to be 2!");
            }

            //if (!SurpressMPIUpdate)
            //    this.MPIExchange();

            int   Esub = CellPairs.GetLength(0);
            Basis B    = this.Basis;
            int   N    = B.Length;
            int   JE   = this.GridDat.iLogicalCells.Count;
            int   J    = this.GridDat.iLogicalCells.NoOfLocalUpdatedCells;

            if (scl != null)
            {
                if (scl.Count != Esub)
                {
                    throw new ArgumentException();
                }
            }

            var M = MultidimensionalArray.Create(Esub, N, N);

            B.GetExtrapolationMatrices(CellPairs, M);
            double[] V = null, W = null;
            for (int esub = 0; esub < Esub; esub++)
            {
                var M_tmp = M.ExtractSubArrayShallow(esub, -1, -1);

                int jCell0 = CellPairs[esub, 0];
                int jCell1 = CellPairs[esub, 1];
                if (jCell0 < 0 || jCell0 >= JE)
                {
                    throw new ArgumentOutOfRangeException();
                }
                if (jCell1 < 0 || jCell1 >= J)
                {
                    throw new ArgumentOutOfRangeException();
                }

                if (!this.GridDat.iGeomCells.IsCellAffineLinear(jCell0))
                {
                    throw new NotSupportedException("Currently not supported for curved cells.");
                }
                if (!this.GridDat.iGeomCells.IsCellAffineLinear(jCell1))
                {
                    throw new NotSupportedException("Currently not supported for curved cells.");
                }

                double _scl = 1.0;
                if (scl != null)
                {
                    _scl = scl[esub];
                }

                double _beta = 0.0;
                if (beta != null)
                {
                    _beta = beta[esub];
                }

                if (esub == 0)
                {
                    V = new double[this.Coordinates.NoOfCols];
                    W = new double[this.Coordinates.NoOfCols];
                }

                {
                    this.Coordinates.GetRow(jCell0, V);
                    this.Coordinates.GetRow(jCell1, W);

                    for (int n = 0; n < N; n++)
                    {
                        double acc0 = 0;
                        for (int m = 0; m < N; m++)
                        {
                            acc0 += V[m] * M_tmp[n, m];
                        }

                        W[n] = W[n] * _beta + acc0 * _scl;
                    }

                    this.Coordinates.SetRow(jCell1, W);
                }
            }
        }
Ejemplo n.º 6
0
        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);
             * }  */
        }
Ejemplo n.º 7
0
        /// <summary>
        /// evaluation of DG field; may be used in derived classes to implement <see cref="DGField.Evaluate(int,int,NodeSet,MultidimensionalArray,int,double)"/>.
        /// </summary>
        protected static void EvaluateInternal(int j0, int L, NodeSet NS, Basis basis, MultidimensionalArray Coördinates, int coördOffset, MultidimensionalArray ResultAcc, double ResultPreScale)
        {
            int  D, N, NumNodes;
            bool AffineLinear;

            CheckArgs(j0, L, NS, basis, Coördinates, ResultAcc, out D, out N, out NumNodes, out AffineLinear);
            Debug.Assert(ResultAcc.Dimension == 2);
            Debug.Assert(L == ResultAcc.GetLength(0));
            Debug.Assert(NumNodes == ResultAcc.GetLength(1));

            /*
             * MultidimensionalArray BasisValues;
             * BasisValues = basis.CellEval(NS, j0, L);
             * Debug.Assert(BasisValues.GetLength(0) == L, "No. of. cells mismatch");
             * Debug.Assert(BasisValues.GetLength(1) == M, "No. of. nodes mismatch");
             * Debug.Assert(BasisValues.GetLength(2) == N, "No. of. basis elements mismatch");
             *
             * ResultAcc.Multiply(1.0, Coördinates, BasisValues, ResultPreScale, "jm", "jn", "jmn");
             */

            //int[] geom2log = basis.GridDat.iGeomCells.GeomCell2LogicalCell;

            MultidimensionalArray BasisValues = basis.Evaluate(NS);

            if (L == 1 && AffineLinear)
            {
                // Special optimization for single-cell evaluation:
                // this happens very often for edge quadrature, so it is quite relevant.
                double scale0 = basis.GridDat.ChefBasis.Scaling[j0];
                Debug.Assert(basis.GridDat.iGeomCells.GeomCell2LogicalCell == null || basis.GridDat.iGeomCells.GeomCell2LogicalCell[j0] == j0);
                MultidimensionalArray Coördinates_j;
                if (coördOffset == 0 && Coördinates.GetLength(0) == 1)
                {
                    Coördinates_j = Coördinates;
                }
                else
                {
                    Coördinates_j = Coördinates.ExtractSubArrayShallow(new int[] { coördOffset, 0 }, new int[] { coördOffset, N - 1 });
                }
                ResultAcc.Multiply(scale0, Coördinates_j, BasisValues, ResultPreScale, ref mp_jk_jm_km); //"jk", "jm", "km");
            }
            else
            {
                int iBuf;
                MultidimensionalArray trfCoördinates = TempBuffer.GetTempMultidimensionalarray(out iBuf, L, N);
                TransformCoördinates(j0, L, basis, Coördinates, coördOffset, N, AffineLinear, trfCoördinates);

                if (ResultAcc.IsContinious && trfCoördinates.IsContinious && BasisValues.IsContinious)
                {
                    unsafe
                    {
                        fixed(double *_pResultAcc = ResultAcc.Storage, _ptrfCoördinates = trfCoördinates.Storage, _pBasisValues = BasisValues.Storage)
                        {
                            double *pResultAcc      = _pResultAcc + ResultAcc.Index(0, 0);
                            double *ptrfCoördinates = _ptrfCoördinates + trfCoördinates.Index(0, 0);
                            double *pBasisValues    = _pBasisValues + BasisValues.Index(0, 0);


//#if DEBUG
//                            MultidimensionalArray check = ResultAcc.CloneAs();

//#endif

                            int _M = ResultAcc.GetLength(1);   // entspricht k   (node    index)
                            int _N = ResultAcc.GetLength(0);   // entspricht j   (cell    index)
                            int _K = BasisValues.GetLength(1); // entspricht m   (DG mode index)

                            // NOTE: dimensions in FORTRAN order:
                            // pBasisValues     :  _K x _M
                            // ptrfCoördinates  :  _K x _N
                            // pResultAcc       :  _M x _N
                            //
                            // => FORTRAN GEMM
                            // pResultAcc = pBasisValues^T * ptrfCoördinates

                            int TRANSA = 'T';
                            int TRANSB = 'N';

                            BLAS.dgemm(TRANSA, TRANSB, _M, _N, _K,
                                       1.0,
                                       pBasisValues, _K,
                                       ptrfCoördinates, _K,
                                       ResultPreScale,
                                       pResultAcc, _M);

//#if DEBUG
//                            check.Multiply(1.0, trfCoördinates, BasisValues, ResultPreScale, ref mp_jk_jm_km);
//                            check.Acc(-1.0, ResultAcc);
//                            double error = check.L2Norm();
//                            Console.WriteLine("GEMM error: " + error);
//                            Debug.Assert(error < 1.0);
//#endif
                        }
                    }
                }
                else
                {
                    ResultAcc.Multiply(1.0, trfCoördinates, BasisValues, ResultPreScale, ref mp_jk_jm_km); //"jk", "jm", "km");
                }


                TempBuffer.FreeTempBuffer(iBuf);
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        /// evaluation of DG field gradient; may be used in derived classes to implement <see cref="EvaluateGradient"/>.
        /// </summary>
        protected static void EvaluateGradientInternal(int j0, int L, NodeSet NS, Basis basis, MultidimensionalArray Coördinates, int coördOffset, MultidimensionalArray ResultAcc, double ResultPreScale)
        {
            int  D, N, K;
            bool AffineLinear;

            CheckArgs(j0, L, NS, basis, Coördinates, ResultAcc, out D, out N, out K, out AffineLinear);
            Debug.Assert(ResultAcc.Dimension == 3);
            Debug.Assert(L == ResultAcc.GetLength(0));
            Debug.Assert(K == ResultAcc.GetLength(1));
            Debug.Assert(D == ResultAcc.GetLength(2));

            /*
             * MultidimensionalArray BasisGradValues;
             * BasisGradValues = basis.CellEvalGradient(NS, j0, L);
             *
             * ResultAcc.Multiply(1.0, Coördinates, BasisGradValues, ResultPreScale, "jmd", "jn", "jmnd");
             */

            MultidimensionalArray BasisGradValues = basis.EvaluateGradient(NS);
            int iBuf1, iBuf2;

            if (AffineLinear)
            {
                // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
                // affine-linear-cell:
                // Inverse Jacobian different for each cell, but constant among nodes
                // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

                if (L == 1)
                {
                    // Special optimization for single-cell evaluation:
                    // this happens very often for edge quadrature, so it is quite relevant.
                    double scale0 = basis.GridDat.ChefBasis.Scaling[j0];
                    MultidimensionalArray GradientRef = TempBuffer.GetTempMultidimensionalarray(out iBuf2, L, K, D);
                    MultidimensionalArray InvJacobi   = basis.GridDat.iGeomCells.InverseTransformation.ExtractSubArrayShallow(j0, -1, -1);

                    Debug.Assert(basis.GridDat.iGeomCells.GeomCell2LogicalCell == null || basis.GridDat.iGeomCells.GeomCell2LogicalCell[j0] == j0);
                    MultidimensionalArray Coördinates_j;
                    if (coördOffset == 0 && Coördinates.GetLength(0) == 1)
                    {
                        Coördinates_j = Coördinates;
                    }
                    else
                    {
                        Coördinates_j = Coördinates.ExtractSubArrayShallow(new int[] { coördOffset, 0 }, new int[] { coördOffset, N - 1 });
                    }

                    GradientRef.Multiply(scale0, Coördinates_j, BasisGradValues, 0.0, ref mp_jke_jm_kme);  // gradient in reference coördinates
                    ResultAcc.Multiply(1.0, InvJacobi, GradientRef, ResultPreScale, ref mp_jkd_ed_jke);

                    TempBuffer.FreeTempBuffer(iBuf2);
                }
                else
                {
                    MultidimensionalArray trfCoördinates = TempBuffer.GetTempMultidimensionalarray(out iBuf1, L, N);
                    MultidimensionalArray GradientRef    = TempBuffer.GetTempMultidimensionalarray(out iBuf2, L, K, D);
                    MultidimensionalArray InvJacobi      = basis.GridDat.iGeomCells.InverseTransformation.ExtractSubArrayShallow(new int[] { j0, 0, 0 }, new int[] { j0 + L - 1, D - 1, D - 1 });

                    TransformCoördinates(j0, L, basis, Coördinates, coördOffset, N, AffineLinear, trfCoördinates);
                    GradientRef.Multiply(1.0, trfCoördinates, BasisGradValues, 0.0, ref mp_jke_jm_kme);  // gradient in reference coördinates
                    ResultAcc.Multiply(1.0, InvJacobi, GradientRef, ResultPreScale, ref mp_jkd_jed_jke);

                    TempBuffer.FreeTempBuffer(iBuf1);
                    TempBuffer.FreeTempBuffer(iBuf2);
                }
            }
            else
            {
                // ++++++++++++++++++++++++++++++++++++++++++++++++++++++
                // curved-cell:
                // Inverse Jacobian different for each node and each cell
                // ++++++++++++++++++++++++++++++++++++++++++++++++++++++

                MultidimensionalArray trfCoördinates = TempBuffer.GetTempMultidimensionalarray(out iBuf1, L, N);
                MultidimensionalArray GradientRef    = TempBuffer.GetTempMultidimensionalarray(out iBuf2, L, K, D);
                MultidimensionalArray InvJacobi      = basis.GridDat.InverseJacobian.GetValue_Cell(NS, j0, L);

                TransformCoördinates(j0, L, basis, Coördinates, coördOffset, N, AffineLinear, trfCoördinates);
                GradientRef.Multiply(1.0, trfCoördinates, BasisGradValues, 0.0, ref mp_jke_jm_kme);  // gradient in reference coördinates
                ResultAcc.Multiply(1.0, InvJacobi, GradientRef, ResultPreScale, ref mp_jkd_jked_jke);

                TempBuffer.FreeTempBuffer(iBuf1);
                TempBuffer.FreeTempBuffer(iBuf2);
            }
        }
Ejemplo n.º 9
0
        private static void TransformCoördinates(int j0, int L,
                                                 Basis basis,
                                                 MultidimensionalArray Coördinates, int coördOffset,
                                                 int N, bool AffineLinear,
                                                 MultidimensionalArray trfCoördinates)
        {
            int[] geom2log = basis.GridDat.iGeomCells.GeomCell2LogicalCell;

            if (geom2log != null)
            {
                // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
                // aggregation grid branch -- apply index trafo to coordinates
                // (j0..j0+L) are geometical grid indices
                // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

                // extract trafo
                MultidimensionalArray trafo = basis.GridDat.ChefBasis.OrthonormalizationTrafo.GetValue_Cell(j0, L, basis.Degree);
                Debug.Assert(trafo.GetLength(0) == L);
                if (trafo.GetLength(1) > N)
                {
                    trafo = trafo.ExtractSubArrayShallow(new int[] { 0, 0, 0 }, new int[] { L - 1, N - 1, N - 1 });
                }

                // apply trafo
                unsafe
                {
                    fixed(int *p_geom2log = geom2log)
                    {
                        trfCoördinates.Multiply(1.0, trafo, Coördinates, 0.0, ref mp_jm_jmn_Tjn,
                                                p_geom2log, p_geom2log,
                                                trfPreOffset_A: 0, trfCycle_A: 0, trfPostOffset_A: 0,
                                                trfPreOffset_B: coördOffset, trfCycle_B: 1, trfPostOffset_B: 0); // geom cell to logical cell trafo for coördinates
                    }
                }
            }
            else if (AffineLinear)
            {
                // +++++++++++++++++++++++++
                // affine-linear grid branch
                // +++++++++++++++++++++++++

                // extract coördinates
                MultidimensionalArray _Coördinates;
                if (coördOffset > 0 || coördOffset + L < Coördinates.GetLength(0))
                {
                    _Coördinates = Coördinates.ExtractSubArrayShallow(new[] { coördOffset, 0 }, new[] { coördOffset + L - 1, N - 1 });
                }
                else
                {
                    _Coördinates = Coördinates;
                }

                // extract trafo
                MultidimensionalArray scale = basis.GridDat.ChefBasis.Scaling.ExtractSubArrayShallow(new int[] { j0 }, new int[] { j0 + L - 1 });

                // apply trafo
                trfCoördinates.Multiply(1.0, scale, _Coördinates, 0.0, ref mp_jn_j_jn);
            }
            else
            {
                // ++++++++++++++++++
                // curved cell branch
                // ++++++++++++++++++

                // extract coördinates
                MultidimensionalArray _Coördinates;
                if (coördOffset > 0 || coördOffset + L < Coördinates.GetLength(0))
                {
                    _Coördinates = Coördinates.ExtractSubArrayShallow(new[] { coördOffset, 0 }, new[] { coördOffset + L - 1, N - 1 });
                }
                else
                {
                    _Coördinates = Coördinates;
                }

                // extract trafo
                MultidimensionalArray trafo = basis.GridDat.ChefBasis.OrthonormalizationTrafo.GetValue_Cell(j0, L, basis.Degree);
                Debug.Assert(trafo.GetLength(0) == L);
                if (trafo.GetLength(1) > N)
                {
                    trafo = trafo.ExtractSubArrayShallow(new int[] { 0, 0, 0 }, new int[] { L - 1, N - 1, N - 1 });
                }

                // apply trafo
                trfCoördinates.Multiply(1.0, trafo, _Coördinates, 0.0, ref mp_jm_jmn_jn);
            }
        }
Ejemplo n.º 10
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="ctx"></param>
 /// <param name="D"></param>
 /// <param name="b"></param>
 public Tensor2Field(Context ctx, int D, Basis b)
     : this(ctx, D, b, "")
 {
 }
Ejemplo n.º 11
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="ctx"></param>
 /// <param name="D"></param>
 /// <param name="b"></param>
 /// <param name="id"></param>
 public Tensor2Field(Context ctx, int D, Basis b, string id)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 12
0
 /// <summary>
 /// constructs a new field with an empty identification string
 /// (see <see cref="DGField.Identification"/>); Because of this, this
 /// field can't be used for IO;
 /// </summary>
 public SinglePhaseField(Basis __Basis) :
     this(__Basis, null)
 {
 }
Ejemplo n.º 13
0
 /// <summary>
 /// an implementation of <see cref="FieldFactory{T}"/> that creates
 /// <see cref="SinglePhaseField"/>-DG-fields.
 /// </summary>
 /// <param name="__Basis">The basis that is used for this field</param>
 /// <param name="__Identification">
 /// identification string for this field; This can be null or empty,
 /// however, if IO should be performed for this object, the
 /// identification must be unique within the given context.
 /// </param>
 /// <returns>a <see cref="SinglePhaseField"/>-instance</returns>
 public static SinglePhaseField Factory(Basis __Basis, String __Identification)
 {
     return(new SinglePhaseField(__Basis, __Identification));
 }
Ejemplo n.º 14
0
 /// <summary>
 /// ctor
 /// </summary>
 /// <param name="D">
 /// number of components, i.d. dimension (see <see cref="Dim"/>)
 /// </param>
 /// <param name="b"></param>
 /// <param name="fac">
 /// factory for the instantiation of <see cref="DGField"/>-objects; By
 /// the factory model, it becomes possible to use this container for
 /// different subclasses of <see cref="DGField"/>.
 /// </param>
 public VectorField(int D, Basis b, Func <Basis, string, T> fac)
     : this(D, b, "", fac)
 {
 }