/// <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]; } } } } }
/// <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]; }