void GetAllSignCodesRecursive(int iLs, int NoOfLS, List <LevelSetSignCode> R, bool[] PrevSigns) { Debug.Assert(PrevSigns.Length == iLs); bool[] Sings_iLs; switch (GetSign(iLs)) { case LevelsetSign.Negative: Sings_iLs = new bool[] { false }; break; case LevelsetSign.Positive: Sings_iLs = new bool[] { true }; break; case LevelsetSign.Both: Sings_iLs = new bool[] { false, true }; break; default: throw new NotImplementedException(); } bool[] AllSigns = new bool[PrevSigns.Length + 1]; if (PrevSigns.Length > 0) { Array.Copy(PrevSigns, AllSigns, PrevSigns.Length); } if (iLs < NoOfLS - 1) { foreach (bool b in Sings_iLs) { AllSigns[iLs] = b; GetAllSignCodesRecursive(iLs + 1, NoOfLS, R, AllSigns); } } else { // end of recursion Debug.Assert(AllSigns.Length == NoOfLS); foreach (bool b in Sings_iLs) { AllSigns[iLs] = b; var lssc = new LevelSetSignCode(); lssc.SetSigns(AllSigns); R.Add(lssc); } } }
/// <summary> /// true, if <paramref name="cd"/> is contained in this /// </summary> public bool IsContained(LevelSetSignCode cd, int NoOfSignificant_LevSets) { for (int i = 0; i < NoOfSignificant_LevSets; i++) { LevelsetSign ls_i = GetSign(i); if (ls_i == LevelsetSign.Both) { continue; } LevelsetSign sg = cd.GetSign(i) ? LevelsetSign.Positive : LevelsetSign.Negative; if (sg != ls_i) { return(false); } } return(true); }
/// <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); } } } } } }