示例#1
0
        /// <summary>
        /// see <see cref="DGField.Evaluate(int,int,NodeSet,MultidimensionalArray,int,double)"/>
        /// </summary>
        override public void Evaluate(int j0, int Len, NodeSet NS, MultidimensionalArray result, int ResultIndexOffset, double ResultPreScale)
        {
            int D = GridDat.SpatialDimension; // spatial dimension
            int N = m_Basis.Length;           // number of coordinates per cell
            int M = NS.NoOfNodes;             // number of nodes

            if (result.Dimension != 2)
            {
                throw new ArgumentOutOfRangeException("result", "dimension of result array must be 2");
            }
            if (Len > result.GetLength(0) + ResultIndexOffset)
            {
                throw new ArgumentOutOfRangeException("mismatch between Len and 0-th length of result");
            }
            if (result.GetLength(1) != M)
            {
                throw new ArgumentOutOfRangeException();
            }

            var coöSys    = NS.GetNodeCoordinateSystem(this.GridDat);
            var resultAcc = result.ExtractSubArrayShallow(new int[] { ResultIndexOffset, 0 }, new int[] { ResultIndexOffset + Len - 1, M - 1 });

            if (coöSys != NodeCoordinateSystem.CellCoord)
            {
                throw new ArgumentOutOfRangeException();
            }

            var coord = m_Mda_Coordinates.ExtractSubArrayShallow(new int[] { j0, 0 }, new int[] { j0 + Len - 1, N - 1 });

            DGField.EvaluateInternal(j0, Len, NS, this.m_Basis, coord, resultAcc, ResultPreScale);
        }
示例#2
0
        /// <summary>
        /// Evaluates the gradient of the field;
        /// </summary>
        /// <param name="j0">local index of the first cell to evaluate</param>
        /// <param name="Len">Number of cells to evaluate</param>
        /// <param name="NS">
        /// As usual, the node set.
        /// </param>
        /// <param name="result">
        /// on exit, result of the evaluations are accumulated there;
        /// the original content is scaled by <paramref name="ResultPreScale"/>;
        /// 1st index: cell index minus <paramref name="j0"/>;
        /// 2nd index: node index;
        /// 3rd index: spatial coordinate;
        /// </param>
        /// <param name="ResultCellindexOffset">
        /// an offset for the first index of <paramref name="result"/>;
        /// </param>
        /// <param name="ResultPreScale">
        /// see <paramref name="result"/>
        /// </param>
        public override void EvaluateGradient(int j0, int Len, NodeSet NS, MultidimensionalArray result, int ResultCellindexOffset, double ResultPreScale)
        {
            int D = GridDat.SpatialDimension; // spatial dimension
            int N = m_Basis.Length;           // number of coordinates per cell
            int M = NS.NoOfNodes;             // number of nodes

            var resultAcc = result.ExtractSubArrayShallow(new int[] { ResultCellindexOffset, 0, 0 }, new int[] { ResultCellindexOffset + Len - 1, M - 1, D - 1 });

            var coöSys = NS.GetNodeCoordinateSystem(this.GridDat);

            if (coöSys != NodeCoordinateSystem.CellCoord)
            {
                throw new ArgumentOutOfRangeException();
            }


            DGField.EvaluateGradientInternal(j0, Len, NS, this.m_Basis, m_Mda_Coordinates, j0, resultAcc, ResultPreScale);
        }
示例#3
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);
             * }  */
        }
示例#4
0
        /// <summary>
        /// Evaluates the field along edges.
        /// </summary>
        /// <param name="ResultIndexOffset">
        /// An offset for the first index of <paramref name="ValueIN"/> resp. <paramref name="ValueOT"/>,
        /// i.e. the first result will be written to
        /// <paramref name="ValueIN"/>[<paramref name="ResultIndexOffset"/>,*].
        /// </param>
        /// <param name="e0">Index of the first edge to evaluate.</param>
        /// <param name="Len">Number of edges to evaluate</param>
        /// <param name="NS">
        /// nodes to evaluate at
        /// </param>
        /// <param name="ValueIN">
        /// If not null, contains the following output:
        /// On exit, the value of the DG field at the given nodes are
        /// <em>accumulated</em> (!) there. Before the values are added,
        /// the original content is scaled by <paramref name="ResultPreScale"/>.<br/>
        /// The array is 2-dimensional:
        /// <list type="bullet">
        ///   <item>
        ///   1st index: edge index <i>j</i> - <paramref name="e0"/>;
        ///   </item>
        ///   <item>
        ///   2nd index: node index <i>k</i>, corresponds with 1st index of
        ///   the node set <paramref name="NS"/>;
        ///   </item>
        /// </list>
        /// </param>
        /// <param name="ValueOUT">
        /// Same as <paramref name="ValueIN"/>.
        /// </param>
        /// <param name="MeanValueIN">
        /// If not null, contains the following output:
        /// On exit, the mean values of the DG field at the given edges are
        /// <em>accumulated</em> (!) there. Before the values are added,
        /// the original content is scaled by <paramref name="ResultPreScale"/>.<br/>
        /// The array is 2-dimensional:
        /// <list type="bullet">
        ///   <item>
        ///   1st index: edge index <i>j</i> - <paramref name="e0"/>;
        ///   </item>
        ///   <item>
        ///   2nd index: node index <i>k</i>, corresponds with 1st index of
        ///   the node set <paramref name="NS"/>;
        ///   </item>
        /// </list>
        /// </param>
        /// <param name="MeanValueOT">
        /// Same as <paramref name="MeanValueIN"/>.
        /// </param>
        /// <param name="GradientIN">
        /// If not null, contains the following output:
        /// On exit, the value of the gradient of DG field at the given nodes
        /// are <em>accumulated</em> (!) there. Before the values are added,
        /// the original content is scaled by <paramref name="ResultPreScale"/>.<br/>
        /// The array is 3-dimensional:
        /// <list type="bullet">
        ///   <item>
        ///   1st index: edge index <i>j</i> - <paramref name="e0"/>;
        ///   </item>
        ///   <item>
        ///   2nd index: node index <i>k</i>, corresponds with 1st index of
        ///   the node set <paramref name="NS"/>;
        ///   </item>
        ///   <item>
        ///   2rd index: spatial dimension;
        ///   </item>
        /// </list>
        /// </param>
        /// <param name="GradientOT">
        /// Same as <paramref name="GradientIN"/>.
        /// </param>
        /// <param name="ResultPreScale">
        /// Scaling that is applied to <paramref name="ValueIN"/> and <paramref name="ValueOUT"/> before
        /// the field evaluation is added
        /// </param>
        public override void EvaluateEdge(int e0, int Len, NodeSet NS,
                                          MultidimensionalArray ValueIN, MultidimensionalArray ValueOT,
                                          MultidimensionalArray MeanValueIN = null, MultidimensionalArray MeanValueOT = null,
                                          MultidimensionalArray GradientIN  = null, MultidimensionalArray GradientOT  = null,
                                          int ResultIndexOffset             = 0, double ResultPreScale = 0.0) //
        {
            int D = GridDat.SpatialDimension;                                                                 // spatial dimension
            int N = m_Basis.Length;                                                                           // number of coordinates per cell
            int K = NS.NoOfNodes;                                                                             // number of nodes

            if ((ValueIN != null) != (ValueOT != null))
            {
                throw new ArgumentException();
            }
            if ((MeanValueIN != null) != (MeanValueOT != null))
            {
                throw new ArgumentException();
            }
            if ((GradientIN != null) != (GradientOT != null))
            {
                throw new ArgumentException();
            }

            if (ValueIN != null)
            {
                if (ValueIN.Dimension != 2)
                {
                    throw new ArgumentException("result", "dimension of result array must be 2");
                }
                if (Len > ValueIN.GetLength(0) + ResultIndexOffset)
                {
                    throw new ArgumentException("mismatch between Len and 0-th length of result");
                }
                if (ValueIN.GetLength(1) != K)
                {
                    throw new ArgumentException();
                }
                if (ValueOT.Dimension != 2)
                {
                    throw new ArgumentException("result", "dimension of result array must be 2");
                }
                if (Len > ValueOT.GetLength(0) + ResultIndexOffset)
                {
                    throw new ArgumentException("mismatch between Len and 0-th length of result");
                }
                if (ValueOT.GetLength(1) != K)
                {
                    throw new ArgumentException();
                }

                if (!(ResultIndexOffset == 0 && Len == ValueIN.GetLength(0)))
                {
                    ValueIN = ValueIN.ExtractSubArrayShallow(new int[] { ResultIndexOffset, 0 }, new int[] { ResultIndexOffset + Len - 1, K - 1 });
                }

                if (!(ResultIndexOffset == 0 && Len == ValueOT.GetLength(0)))
                {
                    ValueOT = ValueOT.ExtractSubArrayShallow(new int[] { ResultIndexOffset, 0 }, new int[] { ResultIndexOffset + Len - 1, K - 1 });
                }
            }

            if (MeanValueIN != null)
            {
                if (MeanValueIN.Dimension != 1)
                {
                    throw new ArgumentException("Dimension of mean-value result array must be 1.");
                }
                if (Len > MeanValueIN.GetLength(0) + ResultIndexOffset)
                {
                    throw new ArgumentException("mismatch between Len and 0-th length of result");
                }
                if (MeanValueOT.Dimension != 1)
                {
                    throw new ArgumentException("Dimension of mean-value result array must be 1.");
                }
                if (Len > MeanValueOT.GetLength(0) + ResultIndexOffset)
                {
                    throw new ArgumentException("mismatch between Len and 0-th length of result");
                }

                if (!(ResultIndexOffset == 0 && Len == MeanValueIN.GetLength(0)))
                {
                    MeanValueIN = MeanValueIN.ExtractSubArrayShallow(new int[] { ResultIndexOffset }, new int[] { ResultIndexOffset + Len - 1 });
                }

                if (!(ResultIndexOffset == 0 && Len == MeanValueOT.GetLength(0)))
                {
                    MeanValueOT = MeanValueOT.ExtractSubArrayShallow(new int[] { ResultIndexOffset }, new int[] { ResultIndexOffset + Len - 1 });
                }
            }

            if (GradientIN != null)
            {
                if (GradientIN.Dimension != 3)
                {
                    throw new ArgumentException("Dimension of gradient result array must be 3.");
                }
                if (Len > GradientIN.GetLength(0) + ResultIndexOffset)
                {
                    throw new ArgumentException("mismatch between Len and 0-th length of result");
                }
                if (GradientIN.GetLength(1) != K)
                {
                    throw new ArgumentException();
                }
                if (GradientIN.GetLength(2) != D)
                {
                    throw new ArgumentException();
                }
                if (GradientOT.Dimension != 3)
                {
                    throw new ArgumentException("Dimension of gradient result array must be 3.");
                }
                if (Len > GradientOT.GetLength(0) + ResultIndexOffset)
                {
                    throw new ArgumentException("mismatch between Len and 0-th length of result");
                }
                if (GradientOT.GetLength(1) != K)
                {
                    throw new ArgumentException();
                }
                if (GradientOT.GetLength(2) != D)
                {
                    throw new ArgumentException();
                }

                if (!(ResultIndexOffset == 0 && Len == GradientIN.GetLength(0)))
                {
                    GradientIN = GradientIN.ExtractSubArrayShallow(new int[] { ResultIndexOffset, 0, 0 }, new int[] { ResultIndexOffset + Len - 1, K - 1, D - 1 });
                }

                if (!(ResultIndexOffset == 0 && Len == GradientOT.GetLength(0)))
                {
                    GradientOT = GradientOT.ExtractSubArrayShallow(new int[] { ResultIndexOffset, 0, 0 }, new int[] { ResultIndexOffset + Len - 1, K - 1, D - 1 });
                }
            }


            var coöSys = NS.GetNodeCoordinateSystem(this.GridDat);

            if (coöSys != NodeCoordinateSystem.EdgeCoord)
            {
                throw new ArgumentOutOfRangeException();
            }

            DGField.EvaluateEdgeInternal(e0, Len, NS, this.m_Basis, this.m_Mda_Coordinates,
                                         ValueIN, ValueOT,
                                         MeanValueIN, MeanValueOT,
                                         GradientIN, GradientOT,
                                         ResultPreScale);
        }