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(); }
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); } } }
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(); }
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(); } }
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); } } }