예제 #1
0
        static private void EvalComponent <T>(LevSetIntParams _inParams,
                                              int gamma, EquationComponentArgMapping <T> bf, Stopwatch[] timers,
                                              MultidimensionalArray SumBuf,
                                              MultidimensionalArray[] FieldValuesPos, MultidimensionalArray[] FieldValuesNeg, MultidimensionalArray[] FieldGradientValuesPos, MultidimensionalArray[] FieldGradientValuesNeg,
                                              int DELTA,
                                              Stopwatch timer,
                                              Action <T, LevSetIntParams, 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.ParamsPos = new MultidimensionalArray[NoOfParams];
                _inParams.ParamsNeg = new MultidimensionalArray[NoOfParams];
                for (int c = 0; c < NoOfParams; c++)
                {
                    int targ = bf.AllToSub[i, c + NoOfArgs];
                    Debug.Assert(targ >= 0);
                    _inParams.ParamsPos[c] = FieldValuesPos[targ];
                    _inParams.ParamsNeg[c] = FieldValuesNeg[targ];
                }

                // evaluate equation components
                timers[i].Start();
                ComponentFunc(comp, _inParams, uA, uB, Grad_uA, Grad_uB, SumBuf);
                timers[i].Stop();
#if DEBUG
                SumBuf.CheckForNanOrInf();
#endif
            }
            timer.Stop();
        }
예제 #2
0
        void ILinearLevelSetComponent_V.LevelSetForm_V(LevSetIntParams inp, MultidimensionalArray Koeff_V)
        {
            int             j0       = inp.i0;
            int             Len      = inp.Len;
            int             N        = inp.X.GetLength(1); // nodes per cell
            int             D        = inp.X.GetLength(2); // spatial dim.
            int             NoOfVars = this.ArgumentOrdering.Count;
            LevelSetTracker lsTrk    = m_LsTrk;

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


            // create temp mem:
            double[] node   = new double[D];
            double[] normal = new double[D];
            int      NP     = (this.ParameterOrdering != null) ? this.ParameterOrdering.Count : 0;

            double[]       ParamsPos = new double[NP];
            double[]       ParamsNeg = new double[NP];
            CommonParamsLs cp        = default(CommonParamsLs);

            cp.n         = normal;
            cp.x         = node;
            cp.ParamsNeg = ParamsNeg;
            cp.ParamsPos = ParamsPos;
            cp.time      = inp.time;


            // 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];
            var      h_min   = this.m_LsTrk.GridDat.Cells.h_min;


            //LevelSetSignCode pos;
            //LevelSetSignCode neg;
            //GetSignCode(out neg, out pos);
            SpeciesId posSpc = this.PositiveSpecies;
            SpeciesId negSpc = this.NegativeSpecies;

            var Reg = lsTrk.Regions;

            for (int j = 0; j < Len; j++)   // loop over items...
            {
                ReducedRegionCode rrc;
                int NoOf = Reg.GetNoOfSpecies(j + inp.i0, out rrc);
                Debug.Assert(NoOf == 2);
                //int iSpcPos = lsTrk.GetSpeciesIndex(rrc, pos);
                //int iSpcNeg = lsTrk.GetSpeciesIndex(rrc, neg);
                int iSpcPos = lsTrk.GetSpeciesIndex(rrc, posSpc);
                int iSpcNeg = lsTrk.GetSpeciesIndex(rrc, negSpc);
                cp.jCell = j + inp.i0;
                if (inp.PosCellLengthScale != null)
                {
                    cp.PosCellLengthScale = inp.PosCellLengthScale[cp.jCell];
                }
                else
                {
                    cp.PosCellLengthScale = double.NaN;
                }
                if (inp.NegCellLengthScale != null)
                {
                    cp.NegCellLengthScale = inp.NegCellLengthScale[cp.jCell];
                }
                else
                {
                    cp.NegCellLengthScale = double.NaN;
                }

                for (int n = 0; n < N; n++)   // loop over nodes...
                {
                    inp.Normal.CopyTo(normal, j, n, -1);
                    inp.X.CopyTo(node, j, n, -1);
                    for (int i = 0; i < NP; i++)
                    {
                        ParamsPos[i] = inp.ParamsPos[i][j, n];
                        ParamsNeg[i] = inp.ParamsNeg[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);
                }
            }
        }
예제 #3
0
        static private void EvalComponent <T>(LevSetIntParams _inParams,
                                              int gamma, EquationComponentArgMapping <T> bf,
                                              MultidimensionalArray[][] argsPerComp, MultidimensionalArray[,] argsSum,
                                              int componentIdx,
                                              MultidimensionalArray ParamFieldValuesPos, MultidimensionalArray ParamFieldValuesNeg,
                                              int DELTA,
                                              Stopwatch timer,
                                              IDictionary <SpeciesId, MultidimensionalArray> LengthScales,
                                              CallComponent <T> ComponentFunc) where T : ILevelSetComponent
        {
            timer.Start();


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

                LengthScales.TryGetValue(comp.NegativeSpecies, out _inParams.NegCellLengthScale);
                LengthScales.TryGetValue(comp.PositiveSpecies, out _inParams.PosCellLengthScale);

                argsPerComp[gamma][i].Clear();

                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 parameters
                _inParams.ParamsPos = new MultidimensionalArray[NoOfParams];
                _inParams.ParamsNeg = new MultidimensionalArray[NoOfParams];
                for (int c = 0; c < NoOfParams; c++)
                {
                    int targ = bf.AllToSub[i, c + NoOfArgs] - DELTA;
                    Debug.Assert(targ >= 0);
                    _inParams.ParamsPos[c] = ParamFieldValuesPos.ExtractSubArrayShallow(targ, -1, -1);
                    _inParams.ParamsNeg[c] = ParamFieldValuesNeg.ExtractSubArrayShallow(targ, -1, -1);
                }

                // evaluate equation components
                ComponentFunc(comp, gamma, i, _inParams);
#if DEBUG
                argsPerComp[gamma][i].CheckForNanOrInf();
#endif

                // sum up bilinear forms:
                {
                    MultidimensionalArray Summand = argsPerComp[gamma][i];

                    if (componentIdx >= 0)
                    {
                        for (int c = 0; c < NoOfArgs; c++)   // loop over arguments of equation component
                        {
                            int   targ   = bf.AllToSub[i, c];
                            int[] selSum = new int[Summand.Dimension];
                            selSum.SetAll(-1);
                            selSum[componentIdx] = c;

                            MultidimensionalArray Accu = argsSum[gamma, targ];

                            //int[] selAccu = new int[Accu.Dimension];
                            //selAccu.SetAll(-1);
                            //selAccu[componentIdx] = targ;
#if DEBUG
                            Summand.ExtractSubArrayShallow(selSum).CheckForNanOrInf();
#endif

                            Accu.Acc(1.0, Summand.ExtractSubArrayShallow(selSum));
                        }
                    }
                    else
                    {
                        // affin
#if DEBUG
                        Summand.CheckForNanOrInf();
#endif
                        MultidimensionalArray Accu = argsSum[gamma, 0];
                        Accu.Acc(1.0, Summand);
                    }
                }
            }
            timer.Stop();
        }
예제 #4
0
        protected override void Evaluate(int i0, int Len, QuadRule QR, MultidimensionalArray EvalResult)
        {
            NodeSet QuadNodes = QR.Nodes;
            int     D         = gridData.SpatialDimension;
            int     NoOfNodes = QuadNodes.NoOfNodes;
            int     GAMMA     = m_CodomainMap.NoOfVariables; // GAMMA: number of codom variables


            // Evaluate Domain & Parameter fields
            // --------------------------------

            Field_Eval.Start();

            for (int i = 0; i < m_DomainAndParamFields.Length; i++)
            {
                if (m_ValueRequired[i])
                {
                    DGField _Field = m_DomainAndParamFields[i];
                    if (_Field != null)
                    {
                        if (_Field is XDGField)
                        {
                            // jump in parameter i at level-set: separate evaluation for both sides
                            var _xField = _Field as XDGField;

                            _xField.GetSpeciesShadowField(this.SpeciesA).Evaluate(i0, Len, QuadNodes, m_FieldValuesNeg[i]);
                            _xField.GetSpeciesShadowField(this.SpeciesB).Evaluate(i0, Len, QuadNodes, m_FieldValuesPos[i]);
                        }
                        else
                        {
                            // no jump at level set: positive and negative limit of parameter i are equal
                            _Field.Evaluate(i0, Len, QuadNodes, m_FieldValuesPos[i]);
                            m_FieldValuesNeg[i].Set(m_FieldValuesPos[i]);
                        }
                    }
                    else
                    {
                        m_FieldValuesPos[i].Clear();
                        m_FieldValuesNeg[i].Clear();
                    }
                }

                if (m_GradientRequired[i])
                {
                    DGField _Field = m_DomainAndParamFields[i];
                    if (_Field != null)
                    {
                        if (_Field is XDGField)
                        {
                            // jump in parameter i at level-set: separate evaluation for both sides
                            var _xField = _Field as XDGField;

                            _xField.GetSpeciesShadowField(this.SpeciesA).EvaluateGradient(i0, Len, QuadNodes, m_FieldGradientValuesNeg[i]);
                            _xField.GetSpeciesShadowField(this.SpeciesB).EvaluateGradient(i0, Len, QuadNodes, m_FieldGradientValuesPos[i]);
                        }
                        else
                        {
                            // no jump at level set: positive and negative limit of parameter i are equal
                            _Field.EvaluateGradient(i0, Len, QuadNodes, m_FieldGradientValuesPos[i]);
                            m_FieldGradientValuesNeg[i].Set(m_FieldGradientValuesPos[i]);
                        }
                    }
                    else
                    {
                        m_FieldGradientValuesPos[i].Clear();
                        m_FieldGradientValuesNeg[i].Clear();
                    }
                }
            }

            Field_Eval.Stop();

            // Evaluate level sets and normals
            // -------------------------------

            ParametersAndNormals.Start();
            var NoOfLevSets = m_lsTrk.LevelSets.Count;
            MultidimensionalArray Normals     = m_lsTrk.DataHistories[m_LevSetIdx].Current.GetLevelSetNormals(QuadNodes, i0, Len);
            MultidimensionalArray NodesGlobal = gridData.GlobalNodes.GetValue_Cell(QuadNodes, i0, Len);

            ParametersAndNormals.Stop();

            // Evaluate basis and test functions
            // ---------------------------------

            bool[] ReqV     = new bool[GAMMA];
            bool[] ReqGradV = new bool[GAMMA];

            for (int gamma = 0; gamma < GAMMA; gamma++)
            {
                if (Koeff_V[gamma] != null)
                {
                    ReqV[gamma] = true;
                }
                if (Koeff_GradV[gamma] != null)
                {
                    ReqGradV[gamma] = true;
                }
            }

            MultidimensionalArray[] TestValues;         //            index: codom variable/test function
            MultidimensionalArray[] TestGradientValues; //    index: codom variable/test function
            int[,] sectionsTest;
            Basis_Eval.Start();
            LECQuadratureLevelSet <IMutableMatrixEx, double[]>
            .EvalBasis(i0, Len, this.m_CodomainMap.BasisS, ReqV, ReqGradV, out TestValues, out TestGradientValues, out sectionsTest, QuadNodes);

            Basis_Eval.Stop();


            // Evaluate Integral components
            // ----------------------------


            // loop over codomain variables ...
            for (int gamma = 0; gamma < GAMMA; gamma++)
            {
                // prepare parameters
                // - - - - - - - - -

                // set Normal's
                LevSetIntParams _inParams = new LevSetIntParams();
                _inParams.Normal = Normals;
                // set Nodes Global
                _inParams.X     = NodesGlobal;
                _inParams.time  = this.time;
                _inParams.LsTrk = this.m_lsTrk;
                _inParams.i0    = i0;
                Debug.Assert(_inParams.Len == Len);


                // clear summation buffers
                // - - - - - - - - - - - -

                if (Koeff_V[gamma] != null)
                {
                    Koeff_V[gamma].Clear();
                }
                if (Koeff_GradV[gamma] != null)
                {
                    Koeff_GradV[gamma].Clear();
                }


                // Evaluate Bilin. forms
                // - - - - - - - - - - -

                {
                    EvalComponent(_inParams, gamma, this.m_NonlinLsForm_V[gamma], this.m_NonlinLsForm_V_Watches[gamma],
                                  Koeff_V[gamma],
                                  m_FieldValuesPos, m_FieldValuesNeg, m_FieldGradientValuesPos, m_FieldGradientValuesNeg,
                                  DELTA,
                                  Flux_Eval,
                                  delegate(INonlinLevelSetForm_V _comp, LevSetIntParams inp, MultidimensionalArray[] uA, MultidimensionalArray[] uB, MultidimensionalArray[] Grad_uA, MultidimensionalArray[] Grad_uB, MultidimensionalArray SumBuf) {
                        _comp.LevelSetForm_V(_inParams, uA, uB, Grad_uA, Grad_uB, SumBuf);
                    });
                }
                {
                    EvalComponent(_inParams, gamma, this.m_NonlinLsForm_GradV[gamma], this.m_NonlinLsForm_GradV_Watches[gamma],
                                  Koeff_GradV[gamma],
                                  m_FieldValuesPos, m_FieldValuesNeg, m_FieldGradientValuesPos, m_FieldGradientValuesNeg,
                                  DELTA,
                                  Flux_Eval,
                                  delegate(INonlinLevelSetForm_GradV _comp, LevSetIntParams inp, MultidimensionalArray[] uA, MultidimensionalArray[] uB, MultidimensionalArray[] Grad_uA, MultidimensionalArray[] Grad_uB, MultidimensionalArray SumBuf) {
                        _comp.LevelSetForm_GradV(_inParams, uA, uB, Grad_uA, Grad_uB, SumBuf);
                    });
                }
            }

            // Summation Loops: multiply with test and trial functions
            // -------------------------------------------------------

            int[] offsetCod = new int[GAMMA];
            LECQuadratureLevelSet <IMutableMatrixEx, double[]> .
            CompOffsets(i0, Len, offsetCod, m_CodomainMap);

            for (int gamma = 0; gamma < GAMMA; gamma++)
            {
                // Evaluate Integrand
                // - - - - - - - - -

                var TestVal     = TestValues[gamma];
                var TestGradVal = TestGradientValues[gamma];
                int N;
                if (TestVal != null)
                {
                    N = TestVal.GetLength(2);
                }
                else if (TestGradVal != null)
                {
                    N = TestGradVal.GetLength(2);
                }
                else
                {
                    N = 0;
                }

                Loops.Start();



                // affine offset


                for (int cr = 0; cr < 2; cr++)  // loop over negative/positive species
                {
                    int[] extr0  = new int[] { 0, 0, sectionsTest[gamma, cr] * N + offsetCod[gamma] };
                    int[] extrE  = new int[] { Len - 1, NoOfNodes - 1, extr0[2] + N - 1 };
                    var   SubRes = EvalResult.ExtractSubArrayShallow(extr0, extrE);

                    if (Koeff_V[gamma] != null)
                    {
                        var Sum_Koeff_V_Cr = Koeff_V[gamma].ExtractSubArrayShallow(-1, -1, cr);
                        SubRes.Multiply(1.0, Sum_Koeff_V_Cr, TestVal, 1.0, "jkn", "jk", "jkn");
                    }
                    if (Koeff_GradV[gamma] != null)
                    {
                        var Sum_Koeff_NablaV_Cr = Koeff_GradV[gamma].ExtractSubArrayShallow(-1, -1, cr, -1);
                        SubRes.Multiply(1.0, Sum_Koeff_NablaV_Cr, TestGradVal, 1.0, "jkn", "jkd", "jknd");
                    }
                }


                Loops.Stop();
            }
        }
예제 #5
0
        void INonlinLevelSetForm_V.LevelSetForm_V(LevSetIntParams inp, MultidimensionalArray[] uA, MultidimensionalArray[] uB, MultidimensionalArray[] Grad_uA, MultidimensionalArray[] Grad_uB, MultidimensionalArray Koeff_V)
        {
            int L = inp.Len;

            Debug.Assert(Koeff_V.GetLength(0) == L);
            int K         = Koeff_V.GetLength(1); // no of nodes per cell
            int D         = inp.X.GetLength(2);   // spatial dimension
            int _NOParams = this.ParameterOrdering == null ? 0 : this.ParameterOrdering.Count;

            Debug.Assert(_NOParams == inp.ParamsNeg.Length);
            Debug.Assert(_NOParams == inp.ParamsPos.Length);
            int _NOargs = this.ArgumentOrdering.Count;

            Debug.Assert(_NOargs == uA.Length);
            Debug.Assert(_NOargs == uB.Length);
            Debug.Assert(_NOargs == Grad_uA.Length);
            Debug.Assert(_NOargs == Grad_uB.Length);
            var       lsTrk  = inp.LsTrk;
            var       Reg    = lsTrk.Regions;
            SpeciesId posSpc = this.PositiveSpecies;
            SpeciesId negSpc = this.NegativeSpecies;

            CommonParamsLs cp;

            cp.n         = new double[D];
            cp.x         = new double[D];
            cp.ParamsPos = new double[_NOParams];
            cp.ParamsNeg = new double[_NOParams];
            cp.time      = inp.time;
            double[] _Grad_vA = new double[D];
            double[] _Grad_vB = new double[D];
            double[,] _Grad_uA = new double[_NOargs, D];
            double[,] _Grad_uB = new double[_NOargs, D];
            double[] _uA = new double[_NOargs];
            double[] _uB = new double[_NOargs];
            double   _vA = 0.0, _vB = 0.0;


            for (int l = 0; l < L; l++)   // loop over cells...
            {
                cp.jCell = inp.i0 + l;
                //if (inp.PosCellLengthScale != null)
                //    cp.PosCellLengthScale = inp.PosCellLengthScale[cp.jCell];
                //else
                //    cp.PosCellLengthScale = double.NaN;
                //if (inp.NegCellLengthScale != null)
                //    cp.NegCellLengthScale = inp.NegCellLengthScale[cp.jCell];
                //else
                //    cp.NegCellLengthScale = double.NaN;

                ReducedRegionCode rrc;
                int NoOf = Reg.GetNoOfSpecies(l + inp.i0, out rrc);
                Debug.Assert(NoOf == 2);
                int iSpcPos = lsTrk.GetSpeciesIndex(rrc, posSpc);
                int iSpcNeg = lsTrk.GetSpeciesIndex(rrc, negSpc);

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

                {
                    for (int np = 0; np < _NOParams; np++)
                    {
                        cp.ParamsPos[np] = inp.ParamsPos[np][l, k];
                        cp.ParamsNeg[np] = inp.ParamsNeg[np][l, k];
                    }
                    for (int d = 0; d < D; d++)
                    {
                        cp.x[d] = inp.X[l, k, d];
                        cp.n[d] = inp.Normal[l, k, d];
                    }

                    for (int na = 0; na < _NOargs; na++)
                    {
                        Debug.Assert((uA[na] != null) == (uB[na] != null));
                        if (uA[na] != null)
                        {
                            _uA[na] = uA[na][l, k];
                            _uB[na] = uB[na][l, k];
                        }
                        else
                        {
                            _uA[na] = 0;
                            _uA[na] = 0;
                        }
                        Debug.Assert((Grad_uA[na] != null) == (Grad_uB[na] != null));
                        if (Grad_uA[na] != null)
                        {
                            for (int d = 0; d < D; d++)
                            {
                                _Grad_uA[na, d] = Grad_uA[na][l, k, d];
                                _Grad_uB[na, d] = Grad_uB[na][l, k, d];
                            }
                        }
                        else
                        {
                            for (int d = 0; d < D; d++)
                            {
                                _Grad_uA[na, d] = 0;
                                _Grad_uB[na, d] = 0;
                            }
                        }
                    }

                    _vA = 1;
                    _vB = 0;
                    Koeff_V[l, k, iSpcNeg] += OrgComponent.LevelSetForm(ref cp, _uA, _uB, _Grad_uA, _Grad_uB, _vA, _vB, _Grad_vA, _Grad_vB);
                    _vA = 0;
                    _vB = 1;
                    Koeff_V[l, k, iSpcPos] += OrgComponent.LevelSetForm(ref cp, _uA, _uB, _Grad_uA, _Grad_uB, _vA, _vB, _Grad_vA, _Grad_vB);
                }
            }
        }