예제 #1
0
        /// <summary>
        /// writes the dammed result of the integration to the sparse matrix
        /// </summary>
        protected override void SaveIntegrationResults(int i0, int Length, MultidimensionalArray ResultsOfIntegration)
        {
            int GAMMA = this.m_CodomainMap.BasisS.Count;  // GAMMA: number of codom/row/test variables

            LECQuadratureLevelSet <IMutableMatrixEx, double[]> .CompOffsets(i0, Length, out int[] offsetRow, out int[] RowNonxN, m_CodomainMap);

            SpeciesId[] spcS = new[] { this.SpeciesA, this.SpeciesB };

            int[] _i0aff = new int[2];
            int[] _iEaff = new int[2];

            // loop over cells...
            for (int i = 0; i < Length; i++)
            {
                int jCell = i + i0;
#if DEBUG
                Debug.Assert(RowNonxN.ListEquals(m_CodomainMap.GetNonXBasisLengths(jCell)));
#endif

                _i0aff[0] = i;
                _iEaff[0] = -1;

                for (int gamma = 0; gamma < GAMMA; gamma++) // loop over rows...
                {
                    for (int cr = 0; cr < 2; cr++)          // loop over neg/pos species row...
                    {
                        SpeciesId rowSpc = spcS[cr];
                        int       Row0   = m_CodomainMap.LocalUniqueCoordinateIndex(m_lsTrk, gamma, jCell, rowSpc, 0);

                        _i0aff[1] = offsetRow[gamma] + RowNonxN[gamma] * cr; // the 'RowXbSw' is 0 for non-xdg, so both species will be added
                        _iEaff[1] = _i0aff[1] + RowNonxN[gamma] - 1;


                        var BlockRes = ResultsOfIntegration.ExtractSubArrayShallow(_i0aff, _iEaff);

                        for (int r = BlockRes.GetLength(0) - 1; r >= 0; r--)
                        {
                            ResultVector[Row0 + r] += BlockRes[r];
                        }
                    }
                }
            }
        }
예제 #2
0
        /// <summary>
        /// ctor.
        /// </summary>
        internal NECQuadratureLevelSet(IGridData context,
                                       XSpatialOperatorMk2 DiffOp,
                                       V __ResultVector,
                                       IList <DGField> __DomainFields,
                                       IList <DGField> __Parameters,
                                       UnsetteledCoordinateMapping CodomainMap,
                                       LevelSetTracker lsTrk, int _iLevSet, Tuple <SpeciesId, SpeciesId> SpeciesPair,
                                       ICompositeQuadRule <QuadRule> domAndRule) //
            : base(new int[] { CodomainMap.GetNonXBasisLengths(0).Sum() * 2 },   // we always integrate over species in pairs (neg + pos), so we need to alloc mem only 2 species
                   context,
                   domAndRule)                                                   //
        {
            MPICollectiveWatchDog.Watch();

            // -----------------------------------
            // set members / check ctor parameters
            // -----------------------------------
            m_lsTrk            = lsTrk;
            this.m_LevSetIdx   = _iLevSet;
            this.m_SpeciesPair = SpeciesPair;
            this.ResultVector  = __ResultVector;
            m_CodomainMap      = CodomainMap;
            var _Parameters = (__Parameters != null) ? __Parameters.ToArray() : new DGField[0];

            if (__DomainFields.Count != DiffOp.DomainVar.Count)
            {
                throw new ArgumentException("mismatch between number of domain variables in spatial operator and given domain variables");
            }
            if (_Parameters.Length != DiffOp.ParameterVar.Count)
            {
                throw new ArgumentException("mismatch between number of parameter variables in spatial operator and given parameters");
            }
            if (m_CodomainMap.NoOfVariables != DiffOp.CodomainVar.Count)
            {
                throw new ArgumentException("mismatch between number of codomain variables in spatial operator and given codomain mapping");
            }

            var _DomainAndParamFields = ArrayTools.Cat(__DomainFields, _Parameters);

            this.DELTA = __DomainFields.Count;

            m_DomainAndParamFieldsA = new ConventionalDGField[_DomainAndParamFields.Length];
            m_DomainAndParamFieldsB = new ConventionalDGField[_DomainAndParamFields.Length];
            for (int i = 0; i < m_DomainAndParamFieldsA.Length; i++)
            {
                var f = _DomainAndParamFields[i];
                if (f == null)
                {
                    m_DomainAndParamFieldsA[i] = null;
                    m_DomainAndParamFieldsB[i] = null;
                }
                else if (f is XDGField xf)
                {
                    m_DomainAndParamFieldsA[i] = xf.GetSpeciesShadowField(this.SpeciesA);
                    m_DomainAndParamFieldsB[i] = xf.GetSpeciesShadowField(this.SpeciesB);
                }
                else if (f is ConventionalDGField cf)
                {
                    m_DomainAndParamFieldsA[i] = cf;
                    m_DomainAndParamFieldsB[i] = null;
                }
                else
                {
                    throw new NotImplementedException("missing implementation for " + f.GetType().Name);
                }
            }

            LECQuadratureLevelSet <IMutableMatrix, double[]> .TestNegativeAndPositiveSpecies(domAndRule, m_lsTrk, SpeciesA, SpeciesB, m_LevSetIdx);

            // ------------------------
            // sort equation components
            // ------------------------

            int Gamma = m_CodomainMap.NoOfVariables;

            m_NonlinLsForm_V = EquationComponentArgMapping <INonlinLevelSetForm_V> .GetArgMapping(DiffOp, true,
                                                                                                  eq => ((eq.LevelSetTerms & (TermActivationFlags.V | TermActivationFlags.UxV | TermActivationFlags.GradUxV)) != 0) && Compfilter(eq),
                                                                                                  eq => (eq is ILevelSetForm)?new NonlinearLevelSetFormVectorizer((ILevelSetForm)eq, lsTrk) : null);

            m_NonlinLsForm_GradV = EquationComponentArgMapping <INonlinLevelSetForm_GradV> .GetArgMapping(DiffOp, true,
                                                                                                          eq => ((eq.LevelSetTerms & (TermActivationFlags.GradV | TermActivationFlags.UxGradV | TermActivationFlags.GradUxGradV)) != 0) && Compfilter(eq),
                                                                                                          eq => (eq is ILevelSetForm)?new NonlinearLevelSetFormVectorizer((ILevelSetForm)eq, lsTrk) : null);


            m_ValueRequired    = new bool[m_DomainAndParamFieldsA.Length];
            m_GradientRequired = new bool[m_DomainAndParamFieldsA.Length];

            m_NonlinLsForm_V.DetermineReqFields(m_GradientRequired,
                                                comp => ((comp.LevelSetTerms & (TermActivationFlags.GradUxGradV | TermActivationFlags.GradUxV)) != 0));
            m_NonlinLsForm_GradV.DetermineReqFields(m_GradientRequired,
                                                    comp => ((comp.LevelSetTerms & (TermActivationFlags.GradUxGradV | TermActivationFlags.GradUxV)) != 0));
            m_NonlinLsForm_V.DetermineReqFields(m_ValueRequired,
                                                comp => ((comp.LevelSetTerms & (TermActivationFlags.UxGradV | TermActivationFlags.UxV)) != 0));
            m_NonlinLsForm_GradV.DetermineReqFields(m_ValueRequired,
                                                    comp => ((comp.LevelSetTerms & (TermActivationFlags.UxGradV | TermActivationFlags.UxV)) != 0));

            for (int i = __DomainFields.Count; i < m_DomainAndParamFieldsA.Length; i++)
            {
                m_ValueRequired[i] = true; // parameters are always required!
            }


            // -----
            // alloc
            // -----

            Koeff_V     = new MultidimensionalArray[Gamma];
            Koeff_GradV = new MultidimensionalArray[Gamma];
            for (int gamma = 0; gamma < Gamma; gamma++)
            {
                Koeff_V[gamma]     = new MultidimensionalArray(3);
                Koeff_GradV[gamma] = new MultidimensionalArray(4);
            }

            Debug.Assert(m_DomainAndParamFieldsA.Length == m_DomainAndParamFieldsB.Length);
            int L = m_DomainAndParamFieldsA.Length;

            m_FieldValuesPos         = new MultidimensionalArray[L];
            m_FieldValuesNeg         = new MultidimensionalArray[L];
            m_FieldGradientValuesPos = new MultidimensionalArray[L];
            m_FieldGradientValuesNeg = new MultidimensionalArray[L];

            for (int l = 0; l < L; l++)
            {
                if (m_ValueRequired[l])
                {
                    m_FieldValuesPos[l] = new MultidimensionalArray(2);
                    m_FieldValuesNeg[l] = new MultidimensionalArray(2);
                }

                if (m_GradientRequired[l])
                {
                    m_FieldGradientValuesPos[l] = new MultidimensionalArray(3);
                    m_FieldGradientValuesNeg[l] = new MultidimensionalArray(3);
                }
            }


            // ------------------
            // init custom timers
            // ------------------

            base.CustomTimers             = new Stopwatch[] { new Stopwatch(), new Stopwatch(), new Stopwatch(), new Stopwatch(), new Stopwatch() };
            base.CustomTimers_Names       = new string[] { "Flux-Eval", "Basis-Eval", "Loops", "ParametersAndNormals", "Field-Eval" };
            base.CustomTimers_RootPointer = new int[5];
            ArrayTools.SetAll(base.CustomTimers_RootPointer, -1);

            this.m_NonlinLsForm_V_Watches     = this.m_NonlinLsForm_V.InitStopWatches(0, this);
            this.m_NonlinLsForm_GradV_Watches = this.m_NonlinLsForm_GradV.InitStopWatches(0, this);

            Flux_Eval            = base.CustomTimers[0];
            Basis_Eval           = base.CustomTimers[1];
            Loops                = base.CustomTimers[2];
            ParametersAndNormals = base.CustomTimers[3];
            Field_Eval           = base.CustomTimers[4];
        }