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(); }
/// <summary> /// ctor. /// </summary> public NECQuadratureVolume(IGridData context, SpatialOperator DiffOp, IList <DGField> _DomainFields, IList <DGField> _ParameterFields, UnsetteledCoordinateMapping CodomainMapping, ICompositeQuadRule <QuadRule> domNrule) : base(context, DiffOp, _DomainFields, _ParameterFields, CodomainMapping) { // ----------------- // quadrature object // ----------------- m_Quad = CellQuadrature.GetQuadrature2(new int[] { CodomainMapping.NoOfCoordinatesPerCell }, context, domNrule, this.EvaluateEx, this.SaveIntegrationResults, this.AllocateBuffers); int Gamma = _DomainFields.Count; // ------------------------ // sort equation components // ------------------------ m_NonlinSources = EquationComponentArgMapping <INonlinearSource> .GetArgMapping(DiffOp, true); m_NonlinFormV = EquationComponentArgMapping <INonlinVolumeForm_V> .GetArgMapping(DiffOp, true, eq => ((eq.VolTerms & (TermActivationFlags.V | TermActivationFlags.UxV | TermActivationFlags.GradUxV)) != 0), eq => (eq is IVolumeForm ? new NonlinVolumeFormVectorizer((IVolumeForm)eq) : null)); m_NonlinFormGradV = EquationComponentArgMapping <INonlinVolumeForm_GradV> .GetArgMapping(DiffOp, true, eq => ((eq.VolTerms & (TermActivationFlags.UxGradV | TermActivationFlags.GradV | TermActivationFlags.GradUxGradV)) != 0), eq => (eq is IVolumeForm ? new NonlinVolumeFormVectorizer((IVolumeForm)eq) : null)); Debug.Assert(base.m_DomainFields.Length >= Gamma); m_ValueRequired = new bool[base.m_DomainFields.Length]; m_GradientRequired = new bool[Gamma]; // base.m_DomainFields may also contain parameter fields: for (int i = Gamma; i < base.m_DomainFields.Length; i++) { m_ValueRequired[i] = true; } this.m_NonlinFormV.DetermineReqFields(m_GradientRequired, comp => ((comp.VolTerms & (TermActivationFlags.GradUxGradV | TermActivationFlags.GradUxV)) != 0)); this.m_NonlinFormGradV.DetermineReqFields(m_GradientRequired, comp => ((comp.VolTerms & (TermActivationFlags.GradUxGradV | TermActivationFlags.GradUxV)) != 0)); this.m_NonlinFormV.DetermineReqFields(m_ValueRequired, comp => ((comp.VolTerms & (TermActivationFlags.UxGradV | TermActivationFlags.UxV)) != 0)); this.m_NonlinFormGradV.DetermineReqFields(m_ValueRequired, comp => ((comp.VolTerms & (TermActivationFlags.UxGradV | TermActivationFlags.UxV)) != 0)); this.m_NonlinSources.DetermineReqFields(m_ValueRequired, comp => true); base.m_NonlinFluxes.DetermineReqFields(m_ValueRequired, comp => true); base.m_NonlinFluxesEx.DetermineReqFields(m_ValueRequired, comp => true); // --------- // profiling // --------- var _CustomTimers = new Stopwatch[] { new Stopwatch(), new Stopwatch(), new Stopwatch(), new Stopwatch(), new Stopwatch(), new Stopwatch() }; var _CustomTimers_Names = new string[] { "Flux-Eval", "Basis-Eval", "Field-Eval", "Loops", "ParametersAndNormals", "Flux-Trafo" }; Flux_Eval = _CustomTimers[0]; Flux_Trafo = _CustomTimers[5]; Field_Eval = _CustomTimers[2]; Basis_Eval = _CustomTimers[1]; Loops = _CustomTimers[3]; ParametersAndNormals = _CustomTimers[4]; m_Quad.CustomTimers = m_Quad.CustomTimers.Cat(_CustomTimers); m_Quad.CustomTimers_Names = m_Quad.CustomTimers_Names.Cat(_CustomTimers_Names); m_Quad.CustomTimers_RootPointer = new int[_CustomTimers_Names.Length]; ArrayTools.SetAll(m_Quad.CustomTimers_RootPointer, -1); this.m_NonlinSources_watch = this.m_NonlinSources.InitStopWatches(0, m_Quad); this.m_NonlinFormV_watch = this.m_NonlinFormV.InitStopWatches(0, m_Quad); this.m_NonlinFormGradV_watch = this.m_NonlinFormGradV.InitStopWatches(0, m_Quad); base.m_NonlinFluxesWatches = base.m_NonlinFluxes.InitStopWatches(0, m_Quad); base.m_NonlinFluxesExWatches = base.m_NonlinFluxesEx.InitStopWatches(0, m_Quad); // --------------------- // alloc multidim arrays // --------------------- m_FluxValues = new MultidimensionalArray[m_CodomainBasisS.Length]; m_FluxValuesTrf = new MultidimensionalArray[m_CodomainBasisS.Length]; for (int i = 0; i < m_FluxValues.Length; i++) { if (m_NonlinFluxes[i].m_AllComponentsOfMyType.Length > 0 || m_NonlinFluxesEx[i].m_AllComponentsOfMyType.Length > 0 || m_NonlinFormGradV[i].m_AllComponentsOfMyType.Length > 0) { m_FluxValues[i] = new MultidimensionalArray(3); m_FluxValuesTrf[i] = new MultidimensionalArray(3); Basis GradBasis = base.m_CodomainBasisS[i]; if (m_MaxCodBasis_Gradient == null || m_MaxCodBasis_Gradient.Degree < GradBasis.Degree) { m_MaxCodBasis_Gradient = GradBasis; } } } m_SourceValues = new MultidimensionalArray[m_CodomainBasisS.Length]; for (int i = 0; i < m_SourceValues.Length; i++) { if (m_NonlinSources[i].m_AllComponentsOfMyType.Length > 0 || m_NonlinFormV[i].m_AllComponentsOfMyType.Length > 0) { m_SourceValues[i] = new MultidimensionalArray(2); Basis ValBasis = base.m_CodomainBasisS[i]; if (m_MaxCodBasis == null || m_MaxCodBasis.Degree < ValBasis.Degree) { m_MaxCodBasis = ValBasis; } } } m_FieldValues = new MultidimensionalArray[m_DomainFields.Length]; m_FieldGradients = new MultidimensionalArray[Gamma]; for (int i = 0; i < m_DomainFields.Length; i++) { if (m_ValueRequired[i]) { m_FieldValues[i] = new MultidimensionalArray(2); } if (i < Gamma && m_GradientRequired[i]) { m_FieldGradients[i] = new MultidimensionalArray(3); } } m_TestFuncWeighted = new MultidimensionalArray(2); m_TestFuncGradWeighted = new MultidimensionalArray(3); }
/// <summary> /// ctor. /// </summary> /// <param name="context">the context which Bjoern loves so much</param> /// <param name="DiffOp">the spatial operator</param> /// <param name="_DomainFields"> /// the mapping for the DG fields (variables) in the domain of the differential operator <paramref name="DiffOp"/>; /// </param> /// <param name="CodomainMapping"> /// the mapping for the DG fields (variables) in the codomain of the differential operator <paramref name="DiffOp"/>; /// </param> /// <param name="ParamFields"> /// the mapping for the DG fields (variables) in the parameter list of the differential operator <paramref name="DiffOp"/>; /// </param> protected NECQuadratureCommon(IGridData context, SpatialOperator DiffOp, IList <DGField> _DomainFields, IList <DGField> ParamFields, UnsetteledCoordinateMapping CodomainMapping) { // --------------- // check arguments // --------------- m_GrdDat = context; m_CodomainMapping = CodomainMapping; if (ParamFields != null && ParamFields.Count > 0) { // concatenate parameters to domain mapping IList <DGField> dom = _DomainFields, param = ParamFields; DGField[] fld = new DGField[dom.Count + param.Count]; int __i; for (__i = 0; __i < dom.Count; __i++) { fld[__i] = dom[__i]; } for (int j = 0; j < param.Count; j++) { fld[j + __i] = param[j]; } _DomainFields = fld; } m_CodomainBasisS = m_CodomainMapping.BasisS.ToArray(); m_DomainFields = _DomainFields.ToArray(); _DomainFields = null; m_DifferentialOperator = DiffOp; if ((DiffOp.DomainVar.Count + DiffOp.ParameterVar.Count) != m_DomainFields.Length) { string extMsg; extMsg = "[DiffOp domain and parameter vars: "; for (int ii = 0; ii < DiffOp.DomainVar.Count; ii++) { extMsg += (DiffOp.DomainVar[ii]); if (ii < DiffOp.DomainVar.Count - 1) { extMsg += ", "; } } extMsg += "; "; for (int ii = 0; ii < DiffOp.ParameterVar.Count; ii++) { extMsg += (DiffOp.ParameterVar[ii]); if (ii < DiffOp.ParameterVar.Count - 1) { extMsg += ", "; } } extMsg += "\n"; extMsg += "Domain/Parameter mapping vars: "; for (int ii = 0; ii < m_DomainFields.Length; ii++) { extMsg += (m_DomainFields[ii].Identification); if (ii < m_DomainFields.Length - 1) { extMsg += ", "; } } extMsg += "]"; throw new ArgumentException("mismatch between number of domain variables: " + extMsg, "DomainMapping,DiffOp"); } if (DiffOp.CodomainVar.Count != CodomainMapping.BasisS.Count) { throw new ArgumentException("mismatch between number of codomain variables", "CodomainMapping,DiffOp"); } IList <Basis> CoDomBasisS = m_CodomainMapping.BasisS; m_NoOfTestFunctions = new int[CoDomBasisS.Count]; m_MyMap = new int[CoDomBasisS.Count]; int i = 0; int c = 0; foreach (Basis b in CoDomBasisS) { m_NoOfTestFunctions[i] = b.Length; m_MyMap[i] = c; c += m_NoOfTestFunctions[i]; i++; } //m_MaxCodBasis = m_CodomainBasisS.ElementAtMax(bs => bs.Degree); //foreach(Basis bs in m_CodomainBasisS) { // if(!bs.IsSubBasis(m_MaxCodBasis)) // throw new NotImplementedException(); //} // ------------------------ // sort equation components // ------------------------ m_NonlinFluxes = EquationComponentArgMapping <INonlinearFlux> .GetArgMapping(DiffOp, true); m_NonlinFluxesEx = EquationComponentArgMapping <INonlinearFluxEx> .GetArgMapping(DiffOp, true); }
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(); }
/// <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]; }