/// <summary> /// evaluation of field in cut- or near - cells; /// </summary> private void EvaluateMultiphase(int jCell, NodeSet NS, ReducedRegionCode ReducedRegionCode, int NoOfSpecies, MultidimensionalArray result, int ResultCellindexOffset, double ResultPreScale, EvaluateInternalSignature EvalFunc, ref MultidimensionalArray[] Buffer, Func <int, int[]> BufferDim, Picker p) { LevelSetTracker trk = this.Basis.Tracker; int NoOfLevSets = trk.LevelSets.Count; int M = NS.NoOfNodes; { //var resultAcc = result.ExtractSubArrayShallow(new int[] { ResultCellindexOffset + j, 0 }, new int[] { ResultCellindexOffset + j, M - 1 }); ushort RegionCode = trk.Regions.m_LevSetRegions[jCell]; bool OnlyOneSpecies = true; for (int i = 0; i < NoOfLevSets; i++) { int dst = LevelSetTracker.DecodeLevelSetDist(RegionCode, i); if (dst == 0) { // cut-cell with respect or levelset #i // +++++++++++++++++++++++++++++++++++++ OnlyOneSpecies = false; _levSetVals[i] = trk.DataHistories[i].Current.GetLevSetValues(NS, jCell, 1); } else { // near-cell with respect or levelset #i // +++++++++++++++++++++++++++++++++++++ // find the species index... _levSetVals[i] = null; _levSetSign[i] = dst; } //_levSetSign2[i] = dst; } if (OnlyOneSpecies) { // all level sets are 'NEAR' // +++++++++++++++++++++++++ LevelSetSignCode levset_bytecode = LevelSetSignCode.ComputeLevelSetBytecode(_levSetSign); int SpecInd = trk.GetSpeciesIndex(ReducedRegionCode, levset_bytecode); // evaluate species ... Evaluate_ithSpecies(jCell, NS, result, ResultCellindexOffset, ResultPreScale, SpecInd, EvalFunc); } else { // at least one cell is 'CUT' // ++++++++++++++++++++++++++ // allocate buffers/evaluate all species ... if (Buffer.Length < NoOfSpecies) { int oldL = Buffer.Length; Array.Resize(ref Buffer, NoOfSpecies); for (int i = oldL; i < NoOfSpecies; i++) { Buffer[i] = MultidimensionalArray.Create(BufferDim(M)); } } for (int i = 0; i < NoOfSpecies; i++) { if (Buffer[i].Dimension > 1 && Buffer[i].GetLength(1) != M) { Buffer[i].Allocate(BufferDim(M)); } this.Evaluate_ithSpecies(jCell, NS, Buffer[i], 0, 0.0, i, EvalFunc); } // ... and pick the right species for the Node for (int m = 0; m < M; m++) // loop over nodes { for (int i = 0; i < NoOfLevSets; i++) { if (_levSetVals[i] != null) { _levSetSign[i] = _levSetVals[i][0, m]; } } LevelSetSignCode levset_bytecode = LevelSetSignCode.ComputeLevelSetBytecode(_levSetSign); int SpecInd = trk.GetSpeciesIndex(ReducedRegionCode, levset_bytecode); p(result, ResultCellindexOffset, m, SpecInd, Buffer); } } } }
protected override void ComputeValues(NodeSet NS, int j0, int Len, MultidimensionalArray output) { Debug.Assert(CheckAll(j0, Len), "basis length must be equal for all cells from j0 to j0+Len"); int l0 = m_Owner.GetLength(j0); var trk = m_Owner.Tracker; // evaluation of un-cut polynomials // ================================ var BasisValues = NonXEval(NS, j0, Len); // evaluation of XDG // ================= if (l0 == m_Owner.NonX_Basis.Length) { // uncut region -> evaluation is equal to uncut basis // ++++++++++++++++++++++++++++++++++++++++++++++++++ output.Set(BasisValues); } else { // modulated basis polynomials // +++++++++++++++++++++++++++ int NoOfLevSets = trk.LevelSets.Count; int M = output.GetLength(1); // number of nodes output.Clear(); ReducedRegionCode rrc; int NoOfSpecies = trk.Regions.GetNoOfSpecies(j0, out rrc); int Nsep = m_Owner.DOFperSpeciesPerCell; for (int j = 0; j < Len; j++) // loop over cells { int jCell = j + j0; ushort RegionCode = trk.Regions.m_LevSetRegions[jCell]; int dist = 0; for (int i = 0; i < NoOfLevSets; i++) { dist = LevelSetTracker.DecodeLevelSetDist(RegionCode, i); if (dist == 0) { m_levSetVals[i] = trk.DataHistories[i].Current.GetLevSetValues(NS, jCell, 1); } else { //_levSetVals[i] = m_CCBasis.Tracker.GetLevSetValues(i, NodeSet, jCell, 1); m_levSetVals[i] = null; m_levSetSign[i] = dist; } } LevelSetSignCode levset_bytecode; int SpecInd; if (dist != 0) { // near - field: // Basis contains zero-entries // ++++++++++++++++++++++++++++ levset_bytecode = LevelSetSignCode.ComputeLevelSetBytecode(m_levSetSign); SpecInd = trk.GetSpeciesIndex(rrc, levset_bytecode); } else { levset_bytecode = default(LevelSetSignCode); SpecInd = 0; } for (int m = 0; m < M; m++) // loop over nodes { if (dist == 0) { // cut cells // Modulation necessary // +++++++++++++++++++++ for (int i = 0; i < NoOfLevSets; i++) { if (m_levSetVals[i] != null) { m_levSetSign[i] = m_levSetVals[i][0, m]; } } // re-compute species index levset_bytecode = LevelSetSignCode.ComputeLevelSetBytecode(m_levSetSign); SpecInd = trk.GetSpeciesIndex(rrc, levset_bytecode); } // separate coordinates { int n0 = Nsep * SpecInd; for (int n = 0; n < Nsep; n++) // loop over basis polynomials //output[j, m, n0 + n] = BasisValues[m, n]; { Operation(output, BasisValues, j, m, n0 + n, n); } } } } } }