void IInnerEdgeSource_V.InternalEdge_V(ref EdgeFormParams inp, MultidimensionalArray Koeff_V)
        {
            int j0       = inp.e0;
            int Len      = inp.Len;
            int N        = inp.Nodes.GetLength(1); // nodes per cell
            int D        = inp.Nodes.GetLength(2); // spatial dim.
            int NoOfVars = this.ArgumentOrdering.Count;

            // check dimension of input array
            Koeff_V.CheckLengths(Len, N, 2);


            // create temp mem:
            int NP = (this.ParameterOrdering != null) ? this.ParameterOrdering.Count : 0;

            double[]     ParamsPos = new double[NP];
            double[]     ParamsNeg = new double[NP];
            CommonParams cp;

            cp.Normal         = new Vector(D);
            cp.X              = new Vector(D);
            cp.Parameters_IN  = ParamsNeg;
            cp.Parameters_OUT = ParamsPos;
            cp.time           = inp.time;
            cp.iEdge          = -123456;
            cp.GridDat        = null;

            // temp mem.
            double[] uA = new double[NoOfVars];
            double[] uB = new double[NoOfVars];
            double[,] Grad_uA = new double[NoOfVars, D];
            double[,] Grad_uB = new double[NoOfVars, D];
            double vA = 0;
            double vB = 0;

            double[] Grad_vA = new double[D];
            double[] Grad_vB = new double[D];

            for (int j = 0; j < Len; j++)   // loop over items...
            {
                int iSpcNeg = 0;
                int iSpcPos = 1;
                cp.jCellIn  = j + inp.e0;
                cp.jCellOut = cp.jCellIn;

                for (int n = 0; n < N; n++)   // loop over nodes...
                {
                    cp.Normal.SetFrom(inp.Normals, j, n);
                    cp.X.SetFrom(inp.Nodes, j, n);
                    for (int i = 0; i < NP; i++)
                    {
                        ParamsPos[i] = inp.ParameterVars_OUT[i][j, n];
                        ParamsNeg[i] = inp.ParameterVars_IN[i][j, n];
                    }

                    Koeff_V[j, n, iSpcNeg] = GetSourceCoeff(ref vA, ref cp, uA, uB, Grad_uA, Grad_uB, ref vA, ref vB, Grad_vA, Grad_vB);
                    Koeff_V[j, n, iSpcPos] = GetSourceCoeff(ref vB, ref cp, uA, uB, Grad_uA, Grad_uB, ref vA, ref vB, Grad_vA, Grad_vB);
                }
            }
        }
Exemple #2
0
        public void InternalEdge_GradV(ref EdgeFormParams efp,
                                       MultidimensionalArray[] Uin, MultidimensionalArray[] Uout, MultidimensionalArray[] GradUin, MultidimensionalArray[] GradUout,
                                       MultidimensionalArray fin, MultidimensionalArray fot)
        {
            int NumOfCells = efp.Len;

            Debug.Assert(fin.GetLength(0) == NumOfCells);
            Debug.Assert(fot.GetLength(0) == NumOfCells);
            int NumOfNodes = fin.GetLength(1);            // no of nodes per cell

            for (int cell = 0; cell < NumOfCells; cell++) // loop over cells...
            {
                int iEdge = efp.e0 + cell;

                for (int node = 0; node < NumOfNodes; node++)   // loop over nodes...
                {
                    double uJump   = 0.5 * (Uin[0][cell, node] - Uout[0][cell, node]);
                    double fluxIn  = efp.ParameterVars_IN[0][cell, node] * uJump;
                    double fluxOut = efp.ParameterVars_OUT[0][cell, node] * uJump;

                    for (int d = 0; d < GridData.SpatialDimension; d++)
                    {
                        double n = efp.Normals[cell, node, d];
                        fin[cell, node, d] -= fluxIn * n;
                        fot[cell, node, d] -= fluxOut * n;
                    }
                }
            }
        }
Exemple #3
0
        void IEdgeform_GradUxGradV.InternalEdge(ref EdgeFormParams efp, MultidimensionalArray GradUxGradV)
        {
            InitGlobals(efp);

            Debug.Assert(L == efp.Len);
            Debug.Assert(efp.ParameterVars_IN.Length == NoParams);
            Debug.Assert(efp.ParameterVars_OUT.Length == NoParams);
            Debug.Assert(efp.Len == GradUxGradV.GetLength(0));
            Debug.Assert(2 == GradUxGradV.GetLength(2));
            Debug.Assert(2 == GradUxGradV.GetLength(3));
            Debug.Assert(NoArgs == GradUxGradV.GetLength(4));
            Debug.Assert(D == GradUxGradV.GetLength(6));
            Debug.Assert(D == GradUxGradV.GetLength(6));

            CommonParams cp = default(CommonParams);

            cp.Normale        = new double[D];
            cp.X              = new double[D];
            cp.Parameters_IN  = new double[NoParams];
            cp.Parameters_OUT = new double[NoParams];
            cp.GridDat        = efp.GridDat;

            for (int l = 0; l < L; l++)  // loop over edges
            {
                cp.iEdge = efp.e0 + l;

                for (int k = 0; k < K; k++)  // loop over quadrature nodes

                {
                    for (int d = 0; d < D; d++)
                    {
                        cp.Normale[d] = efp.Normals[l, k, d];
                        cp.X[d]       = efp.NodesGlobal[l, k, d];
                    }

                    for (int np = 0; np < NoParams; np++)
                    {
                        cp.Parameters_IN[np]  = efp.ParameterVars_IN[np][l, k];
                        cp.Parameters_OUT[np] = efp.ParameterVars_OUT[np][l, k];
                    }

                    for (int d1 = 0; d1 < D; d1++)
                    {
                        for (int d2 = 0; d2 < D; d2++)
                        {
                            for (int c = 0; c < NoArgs; c++)
                            {
                                GradUxGradV[l, k, 0, 0, c, d1, d2] = GetCoeff(ref Grad_uA[c, d1], ref Grad_vA[d2], ref cp);
                                GradUxGradV[l, k, 0, 1, c, d1, d2] = GetCoeff(ref Grad_uB[c, d1], ref Grad_vA[d2], ref cp);
                                GradUxGradV[l, k, 1, 0, c, d1, d2] = GetCoeff(ref Grad_uA[c, d1], ref Grad_vB[d2], ref cp);
                                GradUxGradV[l, k, 1, 1, c, d1, d2] = GetCoeff(ref Grad_uB[c, d1], ref Grad_vB[d2], ref cp);
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// see <see cref="IInnerEdgeform_UxGradV.InternalEdge_UxGradV"/>
        /// </summary>
        void IInnerEdgeform_UxGradV.InternalEdge_UxGradV(ref EdgeFormParams efp, MultidimensionalArray UxGradV)
        {
            InitGlobals(efp);
            var E2C = efp.GridDat.iGeomEdges.CellIndices;

            Debug.Assert(L == efp.Len);
            Debug.Assert(efp.ParameterVars_IN.Length == NoParams);
            Debug.Assert(efp.ParameterVars_OUT.Length == NoParams);
            Debug.Assert(efp.Len == UxGradV.GetLength(0));
            Debug.Assert(2 == UxGradV.GetLength(2));
            Debug.Assert(2 == UxGradV.GetLength(3));
            Debug.Assert(NoArgs == UxGradV.GetLength(4));
            Debug.Assert(D == UxGradV.GetLength(5));

            CommonParams cp;

            cp.Normal         = new Vector(D);
            cp.X              = new Vector(D);
            cp.Parameters_IN  = new double[NoParams];
            cp.Parameters_OUT = new double[NoParams];
            cp.GridDat        = efp.GridDat;
            cp.time           = efp.time;

            for (int l = 0; l < L; l++)  // loop over edges
            {
                cp.iEdge    = efp.e0 + l;
                cp.jCellIn  = E2C[cp.iEdge, 0];
                cp.jCellOut = E2C[cp.iEdge, 1];

                for (int k = 0; k < K; k++)   // loop over quadrature nodes

                {
                    for (int d = 0; d < D; d++)
                    {
                        cp.Normal[d] = efp.Normals[l, k, d];
                        cp.X[d]      = efp.Nodes[l, k, d];
                    }

                    for (int np = 0; np < NoParams; np++)
                    {
                        cp.Parameters_IN[np]  = efp.ParameterVars_IN[np][l, k];
                        cp.Parameters_OUT[np] = efp.ParameterVars_OUT[np][l, k];
                    }

                    for (int d = 0; d < D; d++)
                    {
                        for (int c = 0; c < NoArgs; c++)
                        {
                            UxGradV[l, k, 0, 0, c, d] = GetCoeff(ref uA[c], ref Grad_vA[d], ref cp);
                            UxGradV[l, k, 0, 1, c, d] = GetCoeff(ref uB[c], ref Grad_vA[d], ref cp);
                            UxGradV[l, k, 1, 0, c, d] = GetCoeff(ref uA[c], ref Grad_vB[d], ref cp);
                            UxGradV[l, k, 1, 1, c, d] = GetCoeff(ref uB[c], ref Grad_vB[d], ref cp);
                        }
                    }
                }
            }
        }
Exemple #5
0
        /// <summary>
        /// Consistency and penalty term
        /// </summary>
        void INonlinEdgeForm_V.BoundaryEdge(ref EdgeFormParams efp,
                                            MultidimensionalArray[] Uin, MultidimensionalArray[] GradUin,
                                            MultidimensionalArray fin)
        {
            int NumOfCells = efp.Len;

            Debug.Assert(fin.GetLength(0) == NumOfCells);
            int NumOfNodes = fin.GetLength(1); // no of nodes per cell
            int dimension  = efp.GridDat.SpatialDimension;

            for (int cell = 0; cell < NumOfCells; cell++)   // loop over cells...
            {
                int iEdge = efp.e0 + cell;

                // Penalty is calculated according to the formula in background cells
                int    jCellIn = this.GridData.Edges.CellIndices[iEdge, 0];
                double penalty = 2 * this.penalties[jCellIn];

                byte          edgeTag  = this.GridData.iGeomEdges.EdgeTags[iEdge];
                XDGHeatBcType edgeType = this.boundaryCondMap.EdgeTag2Type[edgeTag];
                Func <double[], double, double> dirichletFunction = this.boundaryCondMap.bndFunction["u"][edgeTag];

                for (int node = 0; node < NumOfNodes; node++)   // loop over nodes...

                // Global node coordinates
                {
                    double[] X = new double[dimension];
                    for (int i = 0; i < dimension; i++)
                    {
                        X[i] = efp.NodesGlobal[cell, node, i];
                    }

                    // SIPG Flux Loops
                    double viscosityIn = efp.ParameterVars_IN[0][cell, node];

                    switch (edgeType)
                    {
                    case XDGHeatBcType.Dirichlet:
                        double g_D = dirichletFunction(X, efp.time);

                        double flux = 0.0;
                        for (int d = 0; d < GridData.SpatialDimension; d++)
                        {
                            double n = efp.Normals[cell, node, d];
                            flux -= viscosityIn * GradUin[0][cell, node, d] * n;               // Consistency term
                        }
                        flux            += viscosityIn * (Uin[0][cell, node] - g_D) * penalty; // Penalty term
                        fin[cell, node] += flux;
                        break;

                    default:
                        // Boundary value is zero neumann boundary, i.e. do nothing
                        break;
                    }
                }
            }
        }
Exemple #6
0
        static private void EvalComponent <T>(ref EdgeFormParams _inParams,
                                              int gamma, EquationComponentArgMapping <T> bf, Stopwatch[] timers,
                                              MultidimensionalArray SumBufIn, MultidimensionalArray SumBufOt,
                                              MultidimensionalArray[] FieldValuesPos, MultidimensionalArray[] FieldValuesNeg, MultidimensionalArray[] FieldGradientValuesPos, MultidimensionalArray[] FieldGradientValuesNeg,
                                              int DELTA,
                                              Stopwatch timer,
                                              Action <T, MultidimensionalArray[], MultidimensionalArray[], MultidimensionalArray[], MultidimensionalArray[], MultidimensionalArray, MultidimensionalArray> ComponentFunc)
            where T : ILevelSetForm //
        {
            timer.Start();



            for (int i = 0; i < bf.m_AllComponentsOfMyType.Length; i++)    // loop over equation components
            {
                var comp = bf.m_AllComponentsOfMyType[i];


                int NoOfArgs = bf.NoOfArguments[i];
                Debug.Assert(NoOfArgs == comp.ArgumentOrdering.Count);
                int NoOfParams = bf.NoOfParameters[i];
                Debug.Assert(NoOfParams == ((comp.ParameterOrdering != null) ? comp.ParameterOrdering.Count : 0));

                // map arguments
                var uA      = bf.MapArguments(FieldValuesNeg, comp, true);
                var uB      = bf.MapArguments(FieldValuesPos, comp, true);
                var Grad_uA = bf.MapArguments(FieldGradientValuesNeg, comp, true);
                var Grad_uB = bf.MapArguments(FieldGradientValuesPos, comp, true);

                // map parameters
                _inParams.ParameterVars_OUT = new MultidimensionalArray[NoOfParams];
                _inParams.ParameterVars_IN  = new MultidimensionalArray[NoOfParams];
                for (int c = 0; c < NoOfParams; c++)
                {
                    int targ = bf.AllToSub[i, c + NoOfArgs];
                    Debug.Assert(targ >= 0);
                    _inParams.ParameterVars_OUT[c] = FieldValuesPos[targ];
                    _inParams.ParameterVars_IN[c]  = FieldValuesNeg[targ];
                }

                // evaluate equation components
                timers[i].Start();
                ComponentFunc(comp, uA, uB, Grad_uA, Grad_uB, SumBufIn, SumBufOt);
                timers[i].Stop();
#if DEBUG
                SumBufIn.CheckForNanOrInf();
                SumBufOt.CheckForNanOrInf();
#endif
            }
            timer.Stop();
        }
Exemple #7
0
        /// <summary>
        /// Symmetry term
        /// </summary>
        void INonlinEdgeForm_GradV.BoundaryEdge(ref EdgeFormParams efp,
                                                MultidimensionalArray[] Uin, MultidimensionalArray[] GradUin,
                                                MultidimensionalArray fin)
        {
            int NumOfCells = efp.Len;

            Debug.Assert(fin.GetLength(0) == NumOfCells);
            int NumOfNodes = fin.GetLength(1); // no of nodes per cell
            int dimension  = efp.GridDat.SpatialDimension;

            for (int cell = 0; cell < NumOfCells; cell++)   // loop over cells...
            {
                int iEdge = efp.e0 + cell;

                byte          edgeTag  = this.GridData.iGeomEdges.EdgeTags[iEdge];
                XDGHeatBcType edgeType = this.boundaryCondMap.EdgeTag2Type[edgeTag];
                Func <double[], double, double> dirichletFunction = this.boundaryCondMap.bndFunction["u"][edgeTag];

                for (int node = 0; node < NumOfNodes; node++)   // loop over nodes...

                // Global node coordinates
                {
                    double[] X = new double[dimension];
                    for (int i = 0; i < dimension; i++)
                    {
                        X[i] = efp.NodesGlobal[cell, node, i];
                    }

                    switch (edgeType)
                    {
                    case XDGHeatBcType.Dirichlet:
                        double g_D = dirichletFunction(X, efp.time);
                        //double uJump = 0.5 * (Uin[0][cell, node] - g_D);
                        double uJump  = 1.0 * (Uin[0][cell, node] - g_D);
                        double fluxIn = efp.ParameterVars_IN[0][cell, node] * uJump;

                        for (int d = 0; d < GridData.SpatialDimension; d++)
                        {
                            double n = efp.Normals[cell, node, d];
                            fin[cell, node, d] -= fluxIn * n;
                        }
                        break;

                    default:
                        // Boundary value is zero neumann boundary, i.e. do nothing
                        break;
                    }
                }
            }
        }
Exemple #8
0
        /// <summary>
        /// see <see cref="IEdgeform_GradUxV.InternalEdge"/>
        /// </summary>
        void IEdgeform_GradUxV.InternalEdge(ref EdgeFormParams efp, MultidimensionalArray GradUxV)
        {
            InitGlobals(efp);

            Debug.Assert(efp.ParameterVars_IN.Length == NoParams);
            Debug.Assert(efp.ParameterVars_OUT.Length == NoParams);


            CommonParams cp = default(CommonParams);

            cp.Normale        = new double[D];
            cp.X              = new double[D];
            cp.Parameters_IN  = new double[NoParams];
            cp.Parameters_OUT = new double[NoParams];
            cp.GridDat        = efp.GridDat;
            cp.time           = efp.time;

            for (int l = 0; l < L; l++)   // loop over edges
            {
                cp.iEdge = efp.e0 + l;

                for (int k = 0; k < K; k++)   // loop over quadrature nodes

                {
                    for (int d = 0; d < D; d++)
                    {
                        cp.Normale[d] = efp.Normals[l, k, d];
                        cp.X[d]       = efp.NodesGlobal[l, k, d];
                    }

                    for (int np = 0; np < NoParams; np++)
                    {
                        cp.Parameters_IN[np]  = efp.ParameterVars_IN[np][l, k];
                        cp.Parameters_OUT[np] = efp.ParameterVars_OUT[np][l, k];
                    }

                    for (int d = 0; d < D; d++)
                    {
                        for (int c = 0; c < NoArgs; c++)
                        {
                            GradUxV[l, k, 0, 0, c, d] = GetCoeff(ref Grad_uA[c, d], ref vA, ref cp);
                            GradUxV[l, k, 0, 1, c, d] = GetCoeff(ref Grad_uB[c, d], ref vA, ref cp);
                            GradUxV[l, k, 1, 0, c, d] = GetCoeff(ref Grad_uA[c, d], ref vB, ref cp);
                            GradUxV[l, k, 1, 1, c, d] = GetCoeff(ref Grad_uB[c, d], ref vB, ref cp);
                        }
                    }
                }
            }
        }
Exemple #9
0
        private void InitGlobals(EdgeFormParams efp)
        {
            D        = efp.GridDat.SpatialDimension;
            K        = efp.Normals.GetLength(1);
            L        = efp.Len;
            NoArgs   = this.ArgumentOrdering.Count;
            NoParams = this.ParameterOrdering != null ? this.ParameterOrdering.Count : 0;

            uA      = new double[NoArgs];
            uB      = new double[NoArgs];
            Grad_uA = new double[NoArgs, D];
            Grad_uB = new double[NoArgs, D];
            Grad_vA = new double[D];
            Grad_vB = new double[D];
        }
Exemple #10
0
        void INonlinEdgeForm_V.BoundaryEdge(ref EdgeFormParams efp,
                                            MultidimensionalArray[] Uin, MultidimensionalArray[] GradUin,
                                            MultidimensionalArray fin)
        {
            //int NumOfCells = efp.Len;
            //Debug.Assert(fin.GetLength(0) == NumOfCells);
            //int NumOfNodes = fin.GetLength(1); // no of nodes per cell

            //int NumOfArguments = this.ArgumentOrdering.Count;
            //Debug.Assert(NumOfArguments == Uin.Length);
            //Debug.Assert(NumOfArguments == GradUin.Length);

            //double[] U_in = new double[NumOfArguments];
            //double[] U_ot = new double[NumOfArguments];
            //double[,] GradU_in = new double[dimension, NumOfArguments];

            //for (int cell = 0; cell < NumOfCells; cell++) { // loop over cells...
            //    int iEdge = efp.e0 + cell;

            //    for (int node = 0; node < NumOfNodes; node++) { // loop over nodes...

            //        for (int na = 0; na < NumOfArguments; na++) {
            //            U_in[na] = Uin[na][cell, node];

            //            for (int d = 0; d < dimension; d++) {
            //                GradU_in[d, na] = GradUin[na][cell, node, d];
            //            }
            //        }

            //        // SIPG Flux Loops
            //        //double flux = 0.0;
            //        //for (int k = 0; k < dimension; k++) {
            //        //    double nk = efp.Normals[cell, node, k];
            //        //    for (int l = 0; l < dimension; l++) {
            //        //        double nl = efp.Normals[cell, node, l];
            //        //        for (int j = 0; j < NumOfArguments; j++) {
            //        //            // consistency
            //        //            flux -= (GTensorOut[k, l, j] * GradU_in[l,j]) * nk;
            //        //            // penalty
            //        //            flux += (GTensorOut[k, l, j]) * (U_in[j] - U_ot[j]) * nl * Penalty * nk;
            //        //        }
            //        //    }
            //        //}
            //        //fin[cell, node] += flux;
            //    }
            //}
        }
Exemple #11
0
        void IEdgeform_GradUxGradV.BoundaryEdge(ref EdgeFormParams efp, MultidimensionalArray GradUxGradV)
        {
            InitGlobals(efp);

            CommonParamsBnd cp = default(CommonParamsBnd);

            cp.Normale       = new double[D];
            cp.X             = new double[D];
            cp.Parameters_IN = new double[NoParams];
            cp.GridDat       = efp.GridDat;
            cp.time          = efp.time;

            var _EdgeTags = efp.GridDat.iGeomEdges.EdgeTags;

            for (int l = 0; l < L; l++)  // loop over edges
            {
                cp.iEdge   = efp.e0 + l;
                cp.EdgeTag = _EdgeTags[cp.iEdge];

                for (int k = 0; k < K; k++)  // loop over quadrature nodes

                {
                    for (int d = 0; d < D; d++)
                    {
                        cp.Normale[d] = efp.Normals[l, k, d];
                        cp.X[d]       = efp.NodesGlobal[l, k, d];
                    }

                    for (int np = 0; np < NoParams; np++)
                    {
                        cp.Parameters_IN[np] = efp.ParameterVars_IN[np][l, k];
                    }

                    for (int d1 = 0; d1 < D; d1++)
                    {
                        for (int d2 = 0; d2 < D; d2++)
                        {
                            for (int c = 0; c < NoArgs; c++)
                            {
                                GradUxGradV[l, k, c, d1, d2] = GetCoeffBnd(ref Grad_uA[c, d1], ref Grad_vA[d2], ref cp);
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// see <see cref="IEdgeSource_GradV.InternalEdge"/>
        /// </summary>
        void IInnerEdgeSource_GradV.InternalEdge_GradV(ref EdgeFormParams efp, MultidimensionalArray GradV)
        {
            InitGlobals(efp);
            var E2C = efp.GridDat.iGeomEdges.CellIndices;

            CommonParams cp;

            cp.Normal         = new Vector(D);
            cp.X              = new Vector(D);
            cp.Parameters_IN  = new double[NoParams];
            cp.Parameters_OUT = new double[NoParams];
            cp.GridDat        = efp.GridDat;
            cp.time           = efp.time;

            var _EdgeTags = efp.GridDat.iGeomEdges.EdgeTags;

            for (int l = 0; l < L; l++)  // loop over edges
            {
                cp.iEdge    = efp.e0 + l;
                cp.jCellIn  = E2C[cp.iEdge, 0];
                cp.jCellOut = E2C[cp.iEdge, 1];

                for (int k = 0; k < K; k++)   // loop over quadrature nodes

                {
                    for (int d = 0; d < D; d++)
                    {
                        cp.Normal[d] = efp.Normals[l, k, d];
                        cp.X[d]      = efp.Nodes[l, k, d];
                    }

                    for (int np = 0; np < NoParams; np++)
                    {
                        cp.Parameters_IN[np]  = efp.ParameterVars_IN[np][l, k];
                        cp.Parameters_OUT[np] = efp.ParameterVars_OUT[np][l, k];
                    }

                    for (int d = 0; d < D; d++)
                    {
                        GradV[l, k, 0, d] = GetSourceCoeff(ref Grad_vA[d], ref cp);
                        GradV[l, k, 1, d] = GetSourceCoeff(ref Grad_vB[d], ref cp);
                    }
                }
            }
        }
        /// <summary>
        /// see <see cref="IBoundaryEdgeform_UxGradV.BoundaryEdge_UxGradV"/>
        /// </summary>
        void IBoundaryEdgeform_UxGradV.BoundaryEdge_UxGradV(ref EdgeFormParams efp, MultidimensionalArray UxGradV)
        {
            InitGlobals(efp);

            CommonParamsBnd cp;

            cp.Normal        = new Vector(D);
            cp.X             = new Vector(D);
            cp.Parameters_IN = new double[NoParams];
            cp.GridDat       = efp.GridDat;
            cp.time          = efp.time;

            var _EdgeTags = efp.GridDat.iGeomEdges.EdgeTags;

            for (int l = 0; l < L; l++)  // loop over edges
            {
                cp.iEdge   = efp.e0 + l;
                cp.EdgeTag = _EdgeTags[cp.iEdge];

                for (int k = 0; k < K; k++)  // loop over quadrature nodes

                {
                    for (int d = 0; d < D; d++)
                    {
                        cp.Normal[d] = efp.Normals[l, k, d];
                        cp.X[d]      = efp.Nodes[l, k, d];
                    }

                    for (int np = 0; np < NoParams; np++)
                    {
                        cp.Parameters_IN[np] = efp.ParameterVars_IN[np][l, k];
                    }

                    for (int d = 0; d < D; d++)
                    {
                        for (int c = 0; c < NoArgs; c++)
                        {
                            UxGradV[l, k, c, d] = GetCoeffBnd(ref uA[c], ref Grad_vA[d], ref cp);
                        }
                    }
                }
            }
        }
Exemple #14
0
        /// <summary>
        /// see <see cref="IEdgeSource_GradV.InternalEdge"/>
        /// </summary>
        void IEdgeSource_GradV.InternalEdge(ref EdgeFormParams efp, MultidimensionalArray GradV)
        {
            InitGlobals(efp);

            CommonParams cp = default(CommonParams);

            cp.Normale        = new double[D];
            cp.X              = new double[D];
            cp.Parameters_IN  = new double[NoParams];
            cp.Parameters_OUT = new double[NoParams];
            cp.GridDat        = efp.GridDat;

            var _EdgeTags = efp.GridDat.iGeomEdges.EdgeTags;

            for (int l = 0; l < L; l++)   // loop over edges
            {
                cp.iEdge = efp.e0 + l;

                for (int k = 0; k < K; k++)   // loop over quadrature nodes

                {
                    for (int d = 0; d < D; d++)
                    {
                        cp.Normale[d] = efp.Normals[l, k, d];
                        cp.X[d]       = efp.NodesGlobal[l, k, d];
                    }

                    for (int np = 0; np < NoParams; np++)
                    {
                        cp.Parameters_IN[np]  = efp.ParameterVars_IN[np][l, k];
                        cp.Parameters_OUT[np] = efp.ParameterVars_OUT[np][l, k];
                    }

                    for (int d = 0; d < D; d++)
                    {
                        GradV[l, k, 0, d] = GetSourceCoeff(ref Grad_vA[d], ref cp);
                        GradV[l, k, 1, d] = GetSourceCoeff(ref Grad_vB[d], ref cp);
                    }
                }
            }
        }
        void INonlinEdgeform_V.InternalEdge(ref EdgeFormParams efp,
                                            MultidimensionalArray[] Uin, MultidimensionalArray[] Uout, MultidimensionalArray[] GradUin, MultidimensionalArray[] GradUout,
                                            MultidimensionalArray fin, MultidimensionalArray fot,
                                            bool adiaWall)
        {
            int NumOfCells = efp.Len;

            Debug.Assert(fin.GetLength(0) == NumOfCells);
            Debug.Assert(fot.GetLength(0) == NumOfCells);
            int NumOfNodes = fin.GetLength(1);            // no of nodes per cell

            for (int cell = 0; cell < NumOfCells; cell++) // loop over cells...
            {
                int iEdge = efp.e0 + cell;
                //double Penalty = penalty(gridDat.Edges.CellIndices[iEdge, 0], gridDat.Edges.CellIndices[iEdge, 1], gridDat.Cells.cj);

                int    jCellIn  = gridData.Edges.CellIndices[iEdge, 0];
                int    jCellOut = gridData.Edges.CellIndices[iEdge, 1];
                double Penalty  = penaltyFactor * Math.Max(cellLengthScale[jCellIn], cellLengthScale[jCellOut]);

                for (int node = 0; node < NumOfNodes; node++)   // loop over nodes...
                // SIPG Flux Loops
                {
                    double viscosityIn  = efp.ParameterVars_IN[0][cell, node];
                    double viscosityOut = efp.ParameterVars_OUT[0][cell, node];

                    double flux = 0.0;
                    for (int d = 0; d < dimension; d++)
                    {
                        double n = efp.Normals[cell, node, d];
                        flux -= 0.5 * (viscosityIn * GradUin[0][cell, node, d] + viscosityOut * GradUout[0][cell, node, d]) * n;
                    }
                    flux += Math.Max(viscosityIn, viscosityOut) * (Uin[0][cell, node] - Uout[0][cell, node]) * Penalty;

                    fin[cell, node] += flux;
                    fot[cell, node] -= flux;
                }
            }
        }
Exemple #16
0
        public void InternalEdge_V(ref EdgeFormParams efp,
                                   MultidimensionalArray[] Uin, MultidimensionalArray[] Uout, MultidimensionalArray[] GradUin, MultidimensionalArray[] GradUout,
                                   MultidimensionalArray fin, MultidimensionalArray fot)
        {
            int NumOfCells = efp.Len;

            Debug.Assert(fin.GetLength(0) == NumOfCells);
            Debug.Assert(fot.GetLength(0) == NumOfCells);
            int NumOfNodes = fin.GetLength(1);            // no of nodes per cell

            for (int cell = 0; cell < NumOfCells; cell++) // loop over cells...
            {
                int iEdge = efp.e0 + cell;

                // Penalty is calculated according to the formula in background cells
                int    jCellIn  = this.GridData.Edges.CellIndices[iEdge, 0];
                int    jCellOut = this.GridData.Edges.CellIndices[iEdge, 1];
                double penalty  = Math.Max(this.penalties[jCellIn], this.penalties[jCellOut]);

                for (int node = 0; node < NumOfNodes; node++)   // loop over nodes...

                // SIPG Flux Loops
                {
                    double viscosityIn  = efp.ParameterVars_IN[0][cell, node];
                    double viscosityOut = efp.ParameterVars_OUT[0][cell, node];

                    double flux = 0.0;
                    for (int d = 0; d < GridData.SpatialDimension; d++)
                    {
                        double n = efp.Normals[cell, node, d];
                        flux -= 0.5 * (viscosityIn * GradUin[0][cell, node, d] + viscosityOut * GradUout[0][cell, node, d]) * n; // Consistency term
                    }
                    flux += Math.Max(viscosityIn, viscosityOut) * (Uin[0][cell, node] - Uout[0][cell, node]) * penalty;          // Penalty term

                    fin[cell, node] += flux;
                    fot[cell, node] -= flux;
                }
            }
        }
Exemple #17
0
        void INonlinEdgeForm_GradV.BoundaryEdge(ref EdgeFormParams efp,
                                                MultidimensionalArray[] Uin, MultidimensionalArray[] GradUin,
                                                MultidimensionalArray fin)
        {
            //Boundary value is zero neumann boundary!
            // i.e. do nothing!

            //int NumOfCells = efp.Len;
            //Debug.Assert(fin.GetLength(0) == NumOfCells);
            //int NumOfNodes = fin.GetLength(1); // no of nodes per cell

            //int NumOfArguments = this.ArgumentOrdering.Count;
            //Debug.Assert(NumOfArguments == Uin.Length);
            //Debug.Assert(NumOfArguments == GradUin.Length);

            //double[] U_in = new double[NumOfArguments];
            //double[] U_ot = new double[NumOfArguments];

            //for (int cell = 0; cell < NumOfCells; cell++) { // loop over cells...
            //    int iEdge = efp.e0 + cell;

            //    for (int node = 0; node < NumOfNodes; node++) { // loop over nodes...

            //        for (int na = 0; na < NumOfArguments; na++) {
            //            U_in[na] = Uin[na][cell, node];
            //        }

            //        //// Reference implementation
            //        //for (int d = 0; d < dimension; d++) {
            //        //        double n = efp.Normals[cell, node, d];
            //        //         fin[cell, node, d] -= 0.5 * efp.ParameterVars_IN[0][cell, node] * n;

            //        //}


            //    }
            //}
        }
Exemple #18
0
        /// <summary>
        /// see <see cref="IEdgeSource_V.BoundaryEdge"/>
        /// </summary>
        void IEdgeSource_V.BoundaryEdge(ref EdgeFormParams efp, MultidimensionalArray V)
        {
            InitGlobals(efp);

            CommonParamsBnd cp = default(CommonParamsBnd);

            cp.Normale       = new double[D];
            cp.X             = new double[D];
            cp.Parameters_IN = new double[NoParams];
            cp.GridDat       = efp.GridDat;
            cp.time          = efp.time;

            var _EdgeTags = efp.GridDat.iGeomEdges.EdgeTags;

            for (int l = 0; l < L; l++)   // loop over edges
            {
                cp.iEdge   = efp.e0 + l;
                cp.EdgeTag = _EdgeTags[cp.iEdge];

                for (int k = 0; k < K; k++)   // loop over quadrature nodes

                {
                    for (int d = 0; d < D; d++)
                    {
                        cp.Normale[d] = efp.Normals[l, k, d];
                        cp.X[d]       = efp.NodesGlobal[l, k, d];
                    }

                    for (int np = 0; np < NoParams; np++)
                    {
                        cp.Parameters_IN[np] = efp.ParameterVars_IN[np][l, k];
                    }

                    V[l, k] = GetSourceCoeffBnd(ref vA, ref cp);
                }
            }
        }
Exemple #19
0
        void INonlinInnerEdgeForm_V.NonlinInternalEdge_V(ref EdgeFormParams efp,
                                                         MultidimensionalArray[] Uin, MultidimensionalArray[] Uout, MultidimensionalArray[] GradUin, MultidimensionalArray[] GradUout,
                                                         MultidimensionalArray fin, MultidimensionalArray fot)
        {
            bool adiaWall   = this.AdiabaticWall;
            int  NumOfCells = efp.Len;

            Debug.Assert(fin.GetLength(0) == NumOfCells);
            Debug.Assert(fot.GetLength(0) == NumOfCells);
            int NumOfNodes = fin.GetLength(1); // no of nodes per cell

            int NumOfArguments = this.ArgumentOrdering.Count;

            Debug.Assert(NumOfArguments == Uin.Length);
            Debug.Assert(NumOfArguments == GradUin.Length);
            Debug.Assert(NumOfArguments == Uout.Length);
            Debug.Assert(NumOfArguments == GradUout.Length);


            double[] U_in = new double[NumOfArguments];
            double[] U_ot = new double[NumOfArguments];
            double[,] GradU_in = new double[dimension, NumOfArguments];
            double[,] GradU_ot = new double[dimension, NumOfArguments];

            int[,] E2Cl = gridDat.iGeomEdges.LogicalCellIndices;

            for (int cell = 0; cell < NumOfCells; cell++)   // loop over cells...
            {
                int iEdge = efp.e0 + cell;
                //double Penalty = penalty(gridDat.Edges.CellIndices[iEdge, 0], gridDat.Edges.CellIndices[iEdge, 1], gridDat.Cells.cj);
                int    jCellIn  = E2Cl[iEdge, 0];
                int    jCellOut = E2Cl[iEdge, 1];
                double Penalty  = penaltyFactor * Math.Max(cellMetric[jCellIn], cellMetric[jCellOut]);
                if (EVIL_HACK_CELL_INDEX >= 0)
                {
                    Penalty = penaltyFactor * cellMetric[EVIL_HACK_CELL_INDEX];
                }

                for (int node = 0; node < NumOfNodes; node++)   // loop over nodes...

                {
                    for (int na = 0; na < NumOfArguments; na++)
                    {
                        U_in[na] = Uin[na][cell, node];
                        U_ot[na] = Uout[na][cell, node];

                        for (int d = 0; d < dimension; d++)
                        {
                            GradU_in[d, na] = GradUin[na][cell, node, d];
                            GradU_ot[d, na] = GradUout[na][cell, node, d];
                        }
                    }
                    unsafe
                    {
                        fixed(double *pGin = GTensorIn, pGOut = GTensorOut)
                        {
                            UpdateBoundaryTensorComponent(U_in, adiaWall, dimension, pGin, material, cell);
                            UpdateBoundaryTensorComponent(U_ot, adiaWall, dimension, pGOut, material, cell);
                        }
                    }
                    //UpdateTensorComponent(U_in, dimension, GTensorIn, material);
                    //UpdateTensorComponent(U_ot, dimension, GTensorOut, material);

                    // SIPG Flux Loops
                    //double flux = 0.0;
                    //for (int k = 0; k < dimension; k++) {
                    //    double nk = efp.Normals[cell, node, k];
                    //    for (int l = 0; l < dimension; l++) {
                    //        double nl = efp.Normals[cell, node, l];
                    //        for (int j = 0; j < NumOfArguments; j++) {
                    //            // consistency
                    //            flux -= 0.5 * (GTensorIn[k, l, j] * GradU_in[l,j] + GTensorOut[k, l, j] * GradU_ot[l,j]) * nk;
                    //            // penalty
                    //            flux += 0.5 * (GTensorIn[k, l, j] + GTensorOut[k, l, j]) * (U_in[j] - U_ot[j]) * nl * Penalty * nk;
                    //        }
                    //    }
                    //}
                    //fin[cell, node] += flux;
                    //fot[cell, node] -= flux;
                    double flux = 0.0;
                    unsafe
                    {
                        fixed(double *pGin = GTensorIn, pGot = GTensorOut, pGradUin = GradU_in, pGradUot = GradU_ot, pUin = U_in, pUot = U_ot)
                        {
                            double *pGinVar = pGin;
                            double *pGotVar = pGot;

                            for (int k = 0; k < dimension; k++)
                            {
                                double *pGradUinVar = pGradUin;
                                double *pGradUotVar = pGradUot;
                                double  nk          = efp.Normals[cell, node, k];
                                for (int l = 0; l < dimension; l++)
                                {
                                    double  factor  = efp.Normals[cell, node, l] * Penalty * nk;
                                    double *pUinVar = pUin;
                                    double *pUotVar = pUot;
                                    for (int j = 0; j < NumOfArguments; j++)
                                    {
                                        // consistency
                                        flux -= 0.5 * (*pGinVar * *pGradUinVar + *pGotVar * *pGradUotVar) * nk;
                                        // penalty
                                        flux += 0.5 * (*pGinVar + *pGotVar) * (*pUinVar - *pUotVar) * factor;

                                        //Increment Pointer
                                        pGinVar++;
                                        pGotVar++;
                                        pGradUinVar++;
                                        pGradUotVar++;
                                        pUinVar++;
                                        pUotVar++;
                                    }
                                }
                            }
                        }
                    }
                    fin[cell, node] += flux;
                    fot[cell, node] -= flux;
                }
            }
        }
Exemple #20
0
 void INonlinEdgeForm_V.InternalEdge(ref EdgeFormParams efp,
                                     MultidimensionalArray[] Uin, MultidimensionalArray[] Uout, MultidimensionalArray[] GradUin, MultidimensionalArray[] GradUout,
                                     MultidimensionalArray fin, MultidimensionalArray fot)
 {
     InternalEdge_V(ref efp, Uin, Uout, GradUin, GradUout, fin, fot);
 }
        void INonlinEdgeform_GradV.InternalEdge(ref EdgeFormParams efp, MultidimensionalArray[] Uin, MultidimensionalArray[] Uout, MultidimensionalArray[] GradUin, MultidimensionalArray[] GradUout,
                                                MultidimensionalArray fin, MultidimensionalArray fot, bool adiaWall)
        {
            int L = efp.Len;

            Debug.Assert(fin.GetLength(0) == L);
            Debug.Assert(fot.GetLength(0) == L);
            int K         = fin.GetLength(1); // no of nodes per cell
            int D         = efp.GridDat.SpatialDimension;
            int _NOParams = this.ParameterOrdering == null ? 0 : this.ParameterOrdering.Count;

            Debug.Assert(_NOParams == efp.ParameterVars_IN.Length);
            Debug.Assert(_NOParams == efp.ParameterVars_OUT.Length);
            int _NOargs = this.ArgumentOrdering.Count;

            Debug.Assert(_NOargs == Uin.Length);
            Debug.Assert(_NOargs == GradUin.Length);
            Debug.Assert(_NOargs == Uout.Length);
            Debug.Assert(_NOargs == GradUout.Length);

            CommonParams cpv;

            cpv.GridDat        = efp.GridDat;
            cpv.Parameters_IN  = new double[_NOParams];
            cpv.Parameters_OUT = new double[_NOParams];
            cpv.Normale        = new double[D];
            cpv.X    = new double[D];
            cpv.time = efp.time;

            double[] _GradV_in = new double[D];
            double[,] _GradU_in = new double[_NOargs, D];
            double[] _U_in = new double[_NOargs];
            double   _V_in = 0.0;

            double[] _GradV_ot = new double[D];
            double[,] _GradU_ot = new double[_NOargs, D];
            double[] _U_ot = new double[_NOargs];
            double   _V_ot = 0.0;

            for (int l = 0; l < L; l++)  // loop over cells...
            {
                cpv.iEdge = efp.e0 + l;

                for (int k = 0; k < K; k++)  // loop over nodes...

                {
                    for (int np = 0; np < _NOParams; np++)
                    {
                        cpv.Parameters_IN[np]  = efp.ParameterVars_IN[np][l, k];
                        cpv.Parameters_OUT[np] = efp.ParameterVars_OUT[np][l, k];
                    }

                    for (int d = 0; d < D; d++)
                    {
                        cpv.Normale[d] = efp.Normals[l, k, d];
                        cpv.X[d]       = efp.NodesGlobal[l, k, d];
                    }

                    for (int na = 0; na < _NOargs; na++)
                    {
                        Debug.Assert((Uin[na] != null) == (Uout[na] != null));
                        if (Uin[na] != null)
                        {
                            _U_in[na] = Uin[na][l, k];
                            _U_ot[na] = Uout[na][l, k];
                        }
                        else
                        {
                            _U_in[na] = 0;
                            _U_ot[na] = 0;
                        }
                        Debug.Assert((GradUin[na] != null) == (GradUout[na] != null));
                        if (GradUin[na] != null)
                        {
                            for (int d = 0; d < D; d++)
                            {
                                _GradU_in[na, d] = GradUin[na][l, k, d];
                                _GradU_ot[na, d] = GradUout[na][l, k, d];
                            }
                        }
                        else
                        {
                            for (int d = 0; d < D; d++)
                            {
                                _GradU_in[na, d] = 0;
                                _GradU_ot[na, d] = 0;
                            }
                        }
                    }

                    for (int d = 0; d < D; d++)
                    {
                        _GradV_in[d]  = 1;
                        fin[l, k, d] += edgeForm.InnerEdgeForm(ref cpv, _U_in, _U_ot, _GradU_in, _GradU_ot, _V_in, _V_ot, _GradV_in, _GradV_ot);
                        _GradV_in[d]  = 0;
                        _GradV_ot[d]  = 1;
                        fot[l, k, d] += edgeForm.InnerEdgeForm(ref cpv, _U_in, _U_ot, _GradU_in, _GradU_ot, _V_in, _V_ot, _GradV_in, _GradV_ot);
                        _GradV_ot[d]  = 0;
                    }
                }
            }
        }
        void INonlinEdgeform_GradV.BoundaryEdge(ref EdgeFormParams efp, MultidimensionalArray[] Uin, MultidimensionalArray[] GradUin, MultidimensionalArray f)
        {
            int L = efp.Len;

            Debug.Assert(f.GetLength(0) == L);
            int K         = f.GetLength(1); // no of nodes per cell
            int D         = efp.GridDat.SpatialDimension;
            int _NOParams = this.ParameterOrdering == null ? 0 : this.ParameterOrdering.Count;

            Debug.Assert(_NOParams == efp.ParameterVars_IN.Length);
            int _NOargs = this.ArgumentOrdering.Count;

            Debug.Assert(_NOargs == Uin.Length);
            Debug.Assert(_NOargs == GradUin.Length);

            CommonParamsBnd cpv;

            cpv.GridDat       = efp.GridDat;
            cpv.Parameters_IN = new double[_NOParams];
            cpv.Normale       = new double[D];
            cpv.X             = new double[D];
            cpv.time          = efp.time;

            double[] _GradV_in = new double[D];
            double[,] _GradU_in = new double[_NOargs, D];
            double[] _U_in = new double[_NOargs];
            double   _V_in = 0.0;

            byte[] EdgeTags = efp.GridDat.iGeomEdges.EdgeTags;

            for (int l = 0; l < L; l++)  // loop over cells...
            {
                cpv.iEdge   = efp.e0 + l;
                cpv.EdgeTag = EdgeTags[cpv.iEdge];

                for (int k = 0; k < K; k++)  // loop over nodes...

                {
                    for (int np = 0; np < _NOParams; np++)
                    {
                        cpv.Parameters_IN[np] = efp.ParameterVars_IN[np][l, k];
                    }

                    for (int d = 0; d < D; d++)
                    {
                        cpv.Normale[d] = efp.Normals[l, k, d];
                        cpv.X[d]       = efp.NodesGlobal[l, k, d];
                    }

                    for (int na = 0; na < _NOargs; na++)
                    {
                        if (Uin[na] != null)
                        {
                            _U_in[na] = Uin[na][l, k];
                        }
                        else
                        {
                            _U_in[na] = 0;
                        }
                        if (GradUin[na] != null)
                        {
                            for (int d = 0; d < D; d++)
                            {
                                _GradU_in[na, d] = GradUin[na][l, k, d];
                            }
                        }
                        else
                        {
                            for (int d = 0; d < D; d++)
                            {
                                _GradU_in[na, d] = 0;
                            }
                        }
                    }

                    for (int d = 0; d < D; d++)
                    {
                        _GradV_in[d] = 1;
                        f[l, k, d]  += edgeForm.BoundaryEdgeForm(ref cpv, _U_in, _GradU_in, _V_in, _GradV_in);
                        _GradV_in[d] = 0;
                    }
                }
            }
        }
        /// <summary>
        /// Reformulates the given parameters into <paramref name="efp"/>,
        /// <paramref name="UBoundary"/> and <paramref name="normals"/>, which
        /// are in the form required by
        /// <see cref="INonlinEdgeForm_GradV.InternalEdge"/>
        /// and <see cref="INonlinEdgeForm_V.InternalEdge"/>
        /// </summary>
        /// <param name="prm"></param>
        /// <param name="U"></param>
        /// <param name="GradU"></param>
        /// <param name="efp"></param>
        /// <param name="UBoundary"></param>
        /// <param name="normals"></param>
        private void AdaptParameters(ref VolumFormParams prm, MultidimensionalArray[] U, MultidimensionalArray[] GradU, out EdgeFormParams efp, out MultidimensionalArray[] UBoundary, out MultidimensionalArray normals)
        {
            Debug.Assert(U[0].GetLength(0) == 1, "Number of cells must be 1");
            Debug.Assert(prm.Len == 1, "Number of cells must be 1");

            INonlinEdgeForm_GradV flux = fluxFunction;
            int noOfCells        = 1;
            int noOfNodesPerCell = prm.Xglobal.GetLength(1);

            UBoundary = new MultidimensionalArray[U.Length];
            for (int k = 0; k < U.Length; k++)
            {
                UBoundary[k] = MultidimensionalArray.Create(noOfCells, noOfNodesPerCell);
            }

            normals = MultidimensionalArray.Create(
                noOfCells, noOfNodesPerCell, CompressibleEnvironment.NumberOfDimensions);
            Material material = speciesMap.GetMaterial(double.NaN);

            for (int j = 0; j < noOfNodesPerCell; j++)
            {
                double[] x      = new double[CompressibleEnvironment.NumberOfDimensions];
                double[] normal = new double[CompressibleEnvironment.NumberOfDimensions];

                double abs = 0.0;
                for (int d = 0; d < CompressibleEnvironment.NumberOfDimensions; d++)
                {
                    x[d]      = prm.Xglobal[0, j, d];
                    normal[d] = prm.ParameterVars[d][0, j];
                    abs      += normal[d] * normal[d];
                }
                abs = Math.Sqrt(abs);

                Debug.Assert(abs > 1e-10, "Extremely flat level set gradient");

                for (int d = 0; d < CompressibleEnvironment.NumberOfDimensions; d++)
                {
                    normal[d] /= abs;
                }

                StateVector stateIn       = new StateVector(material, U, 0, j, CompressibleEnvironment.NumberOfDimensions);
                StateVector stateBoundary = boundaryCondition.GetBoundaryState(
                    prm.time, x, normal, stateIn);
                Debug.Assert(stateBoundary.IsValid, "Invalid boundary state");

                double[] UBoundaryLocal = stateBoundary.ToArray();
                for (int k = 0; k < U.Length; k++)
                {
                    UBoundary[k][0, j] = UBoundaryLocal[k];
                }

                for (int d = 0; d < CompressibleEnvironment.NumberOfDimensions; d++)
                {
                    normals[0, j, d] = normal[d];
                }
            }

            efp = new EdgeFormParams()
            {
                e0                = Math.Abs(prm.GridDat.iLogicalCells.Cells2Edges[prm.j0][0]) - 1, // THIS IS AN EVIL HACK; NEEDS TO BE CHANGED
                GridDat           = prm.GridDat,
                Len               = prm.Len,
                NodesGlobal       = prm.Xglobal,
                Normals           = normals,
                ParameterVars_IN  = prm.ParameterVars,
                ParameterVars_OUT = prm.ParameterVars,
                time              = prm.time
            };
        }
 void INonlinEdgeForm_GradV.BoundaryEdge(ref EdgeFormParams efp, MultidimensionalArray[] Uin, MultidimensionalArray[] GradUin, MultidimensionalArray f)
 {
     //Do nothing
 }
 void INonlinEdgeForm_GradV.InternalEdge(ref EdgeFormParams efp, MultidimensionalArray[] Uin, MultidimensionalArray[] Uout, MultidimensionalArray[] GradUin, MultidimensionalArray[] GradUout, MultidimensionalArray fIN, MultidimensionalArray fOT)
 {
     //Do nothing
 }
Exemple #26
0
        void INonlinInnerEdgeForm_GradV.NonlinInternalEdge_GradV(ref EdgeFormParams efp,
                                                                 MultidimensionalArray[] Uin, MultidimensionalArray[] Uout, MultidimensionalArray[] GradUin, MultidimensionalArray[] GradUout,
                                                                 MultidimensionalArray fin, MultidimensionalArray fot)
        {
            bool adiaWall   = this.AdiabaticWall;
            int  NumOfCells = efp.Len;

            Debug.Assert(fin.GetLength(0) == NumOfCells);
            Debug.Assert(fot.GetLength(0) == NumOfCells);
            int NumOfNodes = fin.GetLength(1); // no of nodes per cell

            int NumOfArguments = this.ArgumentOrdering.Count;

            Debug.Assert(NumOfArguments == Uin.Length);
            Debug.Assert(NumOfArguments == GradUin.Length);
            Debug.Assert(NumOfArguments == Uout.Length);
            Debug.Assert(NumOfArguments == GradUout.Length);

            double[] U_in = new double[NumOfArguments];
            double[] U_ot = new double[NumOfArguments];

            for (int cell = 0; cell < NumOfCells; cell++)   // loop over cells...
            {
                int iEdge = efp.e0 + cell;
                //double Penalty = penalty(gridDat.Edges.CellIndices[iEdge, 0], gridDat.Edges.CellIndices[iEdge, 1], gridDat.Cells.cj);

                for (int node = 0; node < NumOfNodes; node++)   // loop over nodes...

                {
                    for (int na = 0; na < NumOfArguments; na++)
                    {
                        U_in[na] = Uin[na][cell, node];
                        U_ot[na] = Uout[na][cell, node];
                    }

                    unsafe
                    {
                        fixed(double *pGin = GTensorIn, pGOut = GTensorOut)
                        {
                            UpdateBoundaryTensorComponent(U_in, adiaWall, dimension, pGin, material, cell);
                            UpdateBoundaryTensorComponent(U_ot, adiaWall, dimension, pGOut, material, cell);
                        }
                    }

                    //UpdateTensorComponent(U_in, dimension, GTensorIn, material);
                    //UpdateTensorComponent(U_ot, dimension, GTensorOut, material);

                    //for (int k = 0; k < dimension; k++) {
                    //    for (int l = 0; l < dimension; l++) {
                    //        double n = efp.Normals[cell, node, l];
                    //        for (int j = 0; j < NumOfArguments; j++) {
                    //            double uJump = U_in[j] - U_ot[j];
                    //            fin[cell, node, k] -= 0.5 * GTensorIn[k, l, j] * uJump * n;
                    //            fot[cell, node, k] -= 0.5 * GTensorOut[k, l, j] * uJump * n;
                    //        }
                    //    }
                    //}
                    unsafe
                    {
                        fixed(double *pGin = GTensorIn, pGot = GTensorOut, pUin = U_in, pUot = U_ot)
                        {
                            double *pGinVar = pGin;
                            double *pGotVar = pGot;

                            for (int k = 0; k < dimension; k++)
                            {
                                double accIn  = 0;
                                double accOut = 0;
                                for (int l = 0; l < dimension; l++)
                                {
                                    double *pUinVar = pUin;
                                    double *pUotVar = pUot;
                                    double  n       = efp.Normals[cell, node, l];
                                    for (int j = 0; j < NumOfArguments; j++)
                                    {
                                        double uJump = *pUinVar - *pUotVar;
                                        accIn  -= 0.5 * *pGinVar * uJump * n;
                                        accOut -= 0.5 * *pGotVar * uJump * n;

                                        //Increment Pointer
                                        pGinVar++;
                                        pGotVar++;
                                        pUinVar++;
                                        pUotVar++;
                                    }
                                }
                                fin[cell, node, k] += accIn;
                                fot[cell, node, k] += accOut;
                            }
                        }
                    }
                }
            }
        }
Exemple #27
0
 void INonlinBoundaryEdgeForm_V.NonlinBoundaryEdge_V(ref EdgeFormParams efp,
                                                     MultidimensionalArray[] Uin, MultidimensionalArray[] GradUin,
                                                     MultidimensionalArray fin)
 {
     //Do Nothing
 }
Exemple #28
0
 void INonlinInnerEdgeForm_V.NonlinInternalEdge_V(ref EdgeFormParams efp,
                                                  MultidimensionalArray[] Uin, MultidimensionalArray[] Uout, MultidimensionalArray[] GradUin, MultidimensionalArray[] GradUout,
                                                  MultidimensionalArray fin, MultidimensionalArray fot)
 {
     //Do nothing
 }
Exemple #29
0
        void INonlinBoundaryEdgeForm_V.NonlinBoundaryEdge_V(ref EdgeFormParams efp,
                                                            MultidimensionalArray[] Uin, MultidimensionalArray[] GradUin,
                                                            MultidimensionalArray fin)
        {
            int NumOfCells = efp.Len;

            Debug.Assert(fin.GetLength(0) == NumOfCells);
            int NumOfNodes = fin.GetLength(1); // no of nodes per cell


            int NumOfArguments = this.ArgumentOrdering.Count;

            Debug.Assert(NumOfArguments == Uin.Length);
            Debug.Assert(NumOfArguments == GradUin.Length);


            double[] U_in = new double[NumOfArguments];
            double[] U_ot = new double[NumOfArguments];
            double[,] GradU_in = new double[dimension, NumOfArguments];

            StateVector stateIn;
            StateVector stateOut;

            int[,] E2Cl = gridDat.iGeomEdges.LogicalCellIndices;

            for (int cell = 0; cell < NumOfCells; cell++)   // loop over cells...
            {
                int iEdge = efp.e0 + cell;
                //double Penalty = penalty(gridDat.Edges.CellIndices[iEdge, 0], gridDat.Edges.CellIndices[iEdge, 1], gridDat.Cells.cj);
                int    jCellIn = E2Cl[iEdge, 0];
                double Penalty = penaltyFactor * cellMetric[jCellIn];

                for (int node = 0; node < NumOfNodes; node++)   // loop over nodes...

                {
                    for (int na = 0; na < NumOfArguments; na++)
                    {
                        U_in[na] = Uin[na][cell, node];

                        for (int d = 0; d < dimension; d++)
                        {
                            GradU_in[d, na] = GradUin[na][cell, node, d];
                        }
                    }
                    //Preparing for BoundaryState
                    double[] X       = new double[dimension];
                    double[] Normale = new double[dimension];
                    for (int i = 0; i < dimension; i++)
                    {
                        X[i]       = efp.Nodes[cell, node, i];
                        Normale[i] = efp.Normals[cell, node, i];
                    }

                    stateIn  = new StateVector(U_in, speciesMap.GetMaterial(double.NaN));
                    stateOut = boundaryMap.GetBoundaryState(efp.GridDat.iGeomEdges.EdgeTags[iEdge], 0.0, X, Normale, stateIn);
                    U_ot     = stateOut.ToArray();

                    bool adiabaticWall = edgeTagBool[efp.GridDat.iGeomEdges.EdgeTags[iEdge]];

                    unsafe
                    {
                        fixed(double *pGOut = GTensorOut)
                        {
                            UpdateBoundaryTensorComponent(U_ot, adiabaticWall, dimension, pGOut, material, cell);
                        }
                    }

                    // SIPG Flux Loops
                    //double flux = 0.0;
                    //for (int k = 0; k < dimension; k++) {
                    //    double nk = efp.Normals[cell, node, k];
                    //    for (int l = 0; l < dimension; l++) {
                    //        double nl = efp.Normals[cell, node, l];
                    //        for (int j = 0; j < NumOfArguments; j++) {
                    //            // consistency
                    //            flux -= (GTensorOut[k, l, j] * GradU_in[l,j]) * nk;
                    //            // penalty
                    //            flux += (GTensorOut[k, l, j]) * (U_in[j] - U_ot[j]) * nl * Penalty * nk;
                    //        }
                    //    }
                    //}
                    //fin[cell, node] += flux;
                    double flux = 0.0;
                    unsafe
                    {
                        fixed(double *pGout = GTensorOut, pGradUin = GradU_in, pUin = U_in, pUot = U_ot)
                        {
                            double *pGoutVar = pGout;

                            for (int k = 0; k < dimension; k++)
                            {
                                double *pGradUinVar = pGradUin;
                                double  nk          = efp.Normals[cell, node, k];
                                for (int l = 0; l < dimension; l++)
                                {
                                    double  factor  = efp.Normals[cell, node, l] * Penalty * nk;
                                    double *pUinVar = pUin;
                                    double *pUotVar = pUot;
                                    for (int j = 0; j < NumOfArguments; j++)
                                    {
                                        // consistency
                                        flux -= *pGoutVar * *pGradUinVar * nk;
                                        // penalty
                                        flux += *pGoutVar * (*pUinVar - *pUotVar) * factor;
                                        //Increment Pointer
                                        pGradUinVar++;
                                        pGoutVar++;
                                        pUinVar++;
                                        pUotVar++;
                                    }
                                }
                            }
                        }
                    }
                    fin[cell, node] += flux;
                }
            }
        }
Exemple #30
0
        void INonlinBoundaryEdgeForm_GradV.NonlinBoundaryEdge_GradV(ref EdgeFormParams efp,
                                                                    MultidimensionalArray[] Uin, MultidimensionalArray[] GradUin,
                                                                    MultidimensionalArray fin)
        {
            int NumOfCells = efp.Len;

            Debug.Assert(fin.GetLength(0) == NumOfCells);
            int NumOfNodes = fin.GetLength(1); // no of nodes per cell

            int NumOfArguments = this.ArgumentOrdering.Count;

            Debug.Assert(NumOfArguments == Uin.Length);
            Debug.Assert(NumOfArguments == GradUin.Length);

            double[] U_in = new double[NumOfArguments];
            double[] U_ot = new double[NumOfArguments];

            StateVector stateIn;
            StateVector stateOut;

            for (int cell = 0; cell < NumOfCells; cell++)   // loop over cells...
            {
                int iEdge = efp.e0 + cell;
                //double Penalty = penalty(gridDat.Edges.CellIndices[iEdge, 0], gridDat.Edges.CellIndices[iEdge, 1], gridDat.Cells.cj);

                for (int node = 0; node < NumOfNodes; node++)   // loop over nodes...

                {
                    for (int na = 0; na < NumOfArguments; na++)
                    {
                        U_in[na] = Uin[na][cell, node];
                    }
                    //Preparing for BoundaryState
                    double[] X       = new double[dimension];
                    double[] Normale = new double[dimension];
                    for (int i = 0; i < dimension; i++)
                    {
                        X[i]       = efp.Nodes[cell, node, i];
                        Normale[i] = efp.Normals[cell, node, i];
                    }

                    stateIn  = new StateVector(U_in, speciesMap.GetMaterial(double.NaN));
                    stateOut = boundaryMap.GetBoundaryState(efp.GridDat.iGeomEdges.EdgeTags[iEdge], 0.0, X, Normale, stateIn);
                    U_ot     = stateOut.ToArray();

                    bool adiabaticWall = edgeTagBool[efp.GridDat.iGeomEdges.EdgeTags[iEdge]];

                    unsafe
                    {
                        fixed(double *pGOut = GTensorOut)
                        {
                            UpdateBoundaryTensorComponent(U_ot, adiabaticWall, dimension, pGOut, material, cell);
                        }
                    }


                    //// Reference implementation
                    //for (int k = 0; k < dimension; k++) {
                    //    for (int l = 0; l < dimension; l++) {
                    //        double n = efp.Normals[cell, node, l];
                    //        for (int j = 0; j < NumOfArguments; j++) {
                    //            fin[cell, node, k] -= GTensorOut[k, l, j] * (U_in[j] - U_ot[j]) * n;
                    //        }
                    //    }
                    //}

                    unsafe
                    {
                        fixed(double *pGot = GTensorOut, gUin = U_in, gUot = U_ot)
                        {
                            double *pGotVar = pGot;

                            for (int k = 0; k < dimension; k++)
                            {
                                for (int l = 0; l < dimension; l++)
                                {
                                    double  n       = efp.Normals[cell, node, l];
                                    double *pUinVar = gUin;
                                    double *pUotVar = gUot;
                                    for (int j = 0; j < NumOfArguments; j++)
                                    {
                                        fin[cell, node, k] -= *pGotVar * (*pUinVar - *pUotVar) * n;
                                        //Increment Pointer
                                        pGotVar++;
                                        pUinVar++;
                                        pUotVar++;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }