/// <summary> /// returns the (possible) number of species in cell <paramref name="j"/>; /// </summary> /// <param name="j"> /// local cell index; /// </param> /// <param name="ReducedRegionCode"> /// on exit, the reduced region code for cell <paramref name="j"/> /// in an 3-adic representation; This number /// is later on required as an input for <see cref="GetSpeciesIndex(SpeciesId,int)"/>; /// </param> /// <returns></returns> /// <remarks> /// Here, three states for each of the for level sets are considered: /// <list type="bullet"> /// <item>positive far (FAR+)</item> /// <item>negative far (FAR-)</item> /// <item>positive near, negative near or cut</item> /// </list> /// This implies, that also for cells in the near region, memory is allocated for more than one /// species. /// </remarks> public int GetNoOfSpecies(int j, out ReducedRegionCode ReducedRegionCode) { ushort celJ = m_LevSetRegions[j]; return(this.m_owner.GetNoOfSpeciesByRegionCode(celJ, out ReducedRegionCode)); }
/// <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); } } } }