/// <summary> /// Legacy interface, preserved as static function. /// </summary> static public void ComputeMatrixEx <M, V>( this XSpatialOperator xOp, LevelSetTracker lsTrk, UnsetteledCoordinateMapping DomainMap, IList <DGField> Parameters, UnsetteledCoordinateMapping CodomainMap, M Matrix, V AffineOffset, bool OnlyAffine, double time, bool MPIParameterExchange, SubGrid subGrid, params SpeciesId[] whichSpc) where M : IMutableMatrixEx where V : IList <double> // { Console.WriteLine("Warning: Legacy interface!"); Console.WriteLine(" Usage of XDG without an agglomerated penalty!"); int order = xOp.GetOrderFromQuadOrderFunction(DomainMap, Parameters, CodomainMap); MultiphaseCellAgglomerator dummy = lsTrk.GetAgglomerator(lsTrk.SpeciesIdS.ToArray(), order, 0.0); Dictionary <SpeciesId, MultidimensionalArray> Idummy = dummy.XDGSpaceMetrics.CutCellMetrics.InterfaceArea; var bla = new Dictionary <SpeciesId, XSpatialOperator.QrSchemPair>(); foreach (var sp in whichSpc) { bla.Add(sp, new XSpatialOperator.QrSchemPair()); } ComputeMatrixEx <M, V>( xOp, lsTrk, DomainMap, Parameters, CodomainMap, Matrix, AffineOffset, OnlyAffine, time, MPIParameterExchange, bla, dummy.CellLengthScales, Idummy, SubGrid: subGrid); Debug.Assert(dummy.TotalNumberOfAgglomerations <= 0, "internal error"); }
/// <summary> /// returns global unique indices which correlate to a certain sub-set of ... /// <list type="bullet"> /// <item>the mappings's basis (<paramref name="mapping"/>, <see cref="UnsetteledCoordinateMapping.BasisS"/>).</item> /// <item>species (<paramref name="_SpcIds"/>).</item> /// <item>cells (<paramref name="cm"/>).</item> /// </list> /// </summary> /// <param name="mapping"> /// the mapping /// </param> /// <param name="Fields"> /// determines which fields should be in the sub-vector-indices-list /// </param> /// <param name="_SpcIds"> /// determines which species should be in the sub-vector-indices-list; null indicates all species. /// </param> /// <param name="cm"> /// determines which cells should be in the sub-vector-indices-list; null indicates all cells. /// </param> /// <param name="regions"> /// Determines which XDG-coordinate belongs to which species. /// </param> /// <param name="presenceTest"> /// if true, cells where some species has zero measure are excluded from the sub-vector-indices-list. /// </param> /// <param name="drk"> /// a cell-agglomeration object: if null, ignored; if provided, /// cells which are eliminated by the agglomeration are excluded from the sub-vector-indices-list /// </param> /// <returns>a list of global (over all MPI processes) unique indices.</returns> static public int[] GetSubvectorIndices(this UnsetteledCoordinateMapping mapping, LevelSetTracker.LevelSetRegions regions, int[] Fields, ICollection <SpeciesId> _SpcIds = null, CellMask cm = null, bool presenceTest = true, MultiphaseCellAgglomerator drk = null) { #region Check Arguments // ========= SpeciesId[] SpcIds = null; if (_SpcIds == null) { // take all species, if arg is null SpcIds = regions.SpeciesIdS.ToArray(); } else { SpcIds = _SpcIds.ToArray(); } if (SpcIds.Length <= 0) { // return will be empty for no species return(new int[0]); } #endregion #region collect cells which are excluded by agglomeration // ================================================= int[][] ExcludeLists; if (drk != null) { ExcludeLists = new int[regions.SpeciesIdS.Count][]; // new Dictionary<SpeciesId, int[]>(); foreach (var id in SpcIds) { int[] ExcludeList = drk.GetAgglomerator(id).AggInfo.AgglomerationPairs.Select(pair => pair.jCellSource).ToArray(); Array.Sort(ExcludeList); ExcludeLists[id.cntnt - LevelSetTracker.___SpeciesIDOffest] = ExcludeList; } } else { ExcludeLists = null; } #endregion #region determine over which cells we want to loop // ========================================== CellMask loopCells; if ((new HashSet <SpeciesId>(regions.SpeciesIdS)).SetEquals(new HashSet <SpeciesId>(SpcIds))) { if (cm == null) { loopCells = CellMask.GetFullMask(regions.GridDat); } else { loopCells = cm; } } else { loopCells = regions.GetSpeciesMask(SpcIds[0]); for (int i = 1; i < SpcIds.Length; i++) { loopCells = loopCells.Intersect(regions.GetSpeciesMask(SpcIds[i])); } if (cm != null) { loopCells = loopCells.Intersect(cm); } } #endregion #region build list // ========== var R = new List <int>(); // which basis is XDG? var _BasisS = mapping.BasisS.ToArray(); XDGBasis[] _XBasisS = new XDGBasis[_BasisS.Length]; for (int i = 0; i < _BasisS.Length; i++) { _XBasisS[i] = _BasisS[i] as XDGBasis; } Tuple <int, SpeciesId>[] iSpcS = new Tuple <int, SpeciesId> [SpcIds.Length]; int KK; int Len_iSpcS = iSpcS.Length; int[] ExcludeListsPointer = new int[regions.SpeciesIdS.Count]; // loop over cells? foreach (int jCell in loopCells.ItemEnum) { int NoOfSpc = regions.GetNoOfSpecies(jCell); #region // // in cell 'jCell', for each species in 'SpcIds' ... // * is the species present in 'jCell'? // * what is the species index in 'jCell'? // * we also have to consider that due to agglomeration, the respective cut-cell for the species might have been agglomerated. // so we determine // * 'KK' is the number of species (from 'SpcIds') which is actually present and not agglomerated in 'jCell' // * for i in (0 ... KK-1), iSpcS[i] is a tuple of (Species-index-in-cell, SpeciesID) // // yes, the following code sucks: KK = 0; for (int k = 0; k < Len_iSpcS; k++) // loop over all species (provided as argument)... { SpeciesId id = SpcIds[k]; int __iSpcS = regions.GetSpeciesIndex(id, jCell); if (__iSpcS >= 0) { // species index is non-negative, so indices for the species are allocated ... if (!presenceTest || regions.IsSpeciesPresentInCell(id, jCell)) { // species is also present (i.e. has a greater-than-zero measure ... if (drk == null) { // no agglomeration exclution iSpcS[KK] = new Tuple <int, SpeciesId>(__iSpcS, id); KK++; } else { int q = id.cntnt - LevelSetTracker.___SpeciesIDOffest; var el = ExcludeLists[q]; while (ExcludeListsPointer[q] < el.Length && el[ExcludeListsPointer[q]] < jCell) { ExcludeListsPointer[q]++; } Debug.Assert(ExcludeListsPointer[q] >= el.Length || el[ExcludeListsPointer[q]] >= jCell); if (ExcludeListsPointer[q] >= el.Length || el[ExcludeListsPointer[q]] != jCell) { // cell is also not agglomerated ... iSpcS[KK] = new Tuple <int, SpeciesId>(__iSpcS, id); KK++; } } } } } if (KK > 1) { Array.Sort <Tuple <int, SpeciesId> >(iSpcS, 0, KK, new ilPSP.FuncComparer <Tuple <int, SpeciesId> >((a, b) => a.Item1 - b.Item1)); } // --------- esc (end of sucking code) #endregion for (int k = 0; k < KK; k++) // loop over species in cell { int iSpc = iSpcS[k].Item1; for (int i = 0; i < Fields.Length; i++) { int iField = Fields[i]; if (_XBasisS[iField] == null) { int N = _BasisS[iField].GetLength(jCell); int i0 = mapping.LocalUniqueCoordinateIndex(iField, jCell, 0); for (int n = 0; n < N; n++) { R.Add(i0 + n); } } else { int N = _XBasisS[iField].DOFperSpeciesPerCell; int i0 = mapping.LocalUniqueCoordinateIndex(iField, jCell, 0) + iSpc * N; for (int n = 0; n < N; n++) { R.Add(i0 + n); } } } } } #endregion return(R.ToArray()); }