void Setup_Frame2Full() { //if (FrameMap.Rank == 0) // Debugger.Launch(); //csMPI.Raw.Barrier(csMPI.Raw._COMM.WORLD); //FrameMap.GridDat.Cells.NoOfLocalUpdatedCells int L = FrameMap.LocalLength; Frame2Full_Lookup = new int[L]; Basis[] BasisS = FullMap.BasisS.ToArray(); XDGBasis[] XBasisS = new XDGBasis[BasisS.Length]; for (int i = 0; i < BasisS.Length; i++) { XBasisS[i] = BasisS[i] as XDGBasis; } var GridDat = this.FullMap.GridDat; Frame2Full_Lookup = new int[L]; Frame2Full_Lookup.SetAll(int.MinValue); int Jup = FrameMap.GridDat.iLogicalCells.NoOfLocalUpdatedCells; int Jtot = FrameMap.GridDat.iLogicalCells.Count; int G = BasisS.Length; for (int j = 0; j < Jup; j++) // loop over all cells ... { int NoOfSpc = m_Regions.GetNoOfSpecies(j); int iSpc = m_Regions.GetSpeciesIndex(m_spcId, j); for (int g = 0; g < G; g++) // loop over all basises { Basis b = BasisS[g]; XDGBasis xb = XBasisS[g]; bool b_is_XDGbasis = (xb != null); int n0, N; if (b_is_XDGbasis) { if (iSpc < 0) { n0 = int.MaxValue; N = int.MinValue; } else { N = xb.DOFperSpeciesPerCell; n0 = N * iSpc; } } else { n0 = 0; N = b.GetLength(j); } if (N >= 0) { int iFull = (int)FullMap.GlobalUniqueCoordinateIndex(g, j, n0); int iLoc = FrameMap.LocalUniqueCoordinateIndex(g, j, 0); for (int n = 0; n < N; n++) { Frame2Full_Lookup[iLoc + n] = iFull + n; Debug.Assert(Frame2Full_Lookup[iLoc + n] < 0 || FullMap.IsInLocalRange(Frame2Full_Lookup[iLoc + n])); } } } } #if DEBUG var _Frame2Full_Lookup = new int[L]; for (int iLoc = 0; iLoc < L; iLoc++) // loop over all indices of the frame... { int j, g, n; FrameMap.LocalFieldCoordinateIndex(iLoc, out g, out j, out n); int NoOfSpc = m_Regions.GetNoOfSpecies(j); Basis b = BasisS[g]; XDGBasis xb = XBasisS[g]; bool b_is_XDGbasis = (xb != null); int iSpc = m_Regions.GetSpeciesIndex(m_spcId, j); if (b_is_XDGbasis) { if (iSpc < 0) { _Frame2Full_Lookup[iLoc] = int.MinValue; } else { int Nsep = xb.DOFperSpeciesPerCell; _Frame2Full_Lookup[iLoc] = (int)(FullMap.GlobalUniqueCoordinateIndex(g, j, iSpc * Nsep + n)); } } else { _Frame2Full_Lookup[iLoc] = (int)(FullMap.GlobalUniqueCoordinateIndex(g, j, n)); } Debug.Assert(_Frame2Full_Lookup[iLoc] == Frame2Full_Lookup[iLoc]); } for (int l = 0; l < L; l++) { Debug.Assert(Frame2Full_Lookup[l] < 0 || FullMap.IsInLocalRange(Frame2Full_Lookup[l])); } #endif /* * if (m_supportExternal) { * int[] PeerProcess = GridDat.Parallel.ProcessesToReceiveFrom; * int TT = PeerProcess.Length; * int DOFperCell = FrameMap.MaxTotalNoOfCoordinatesPerCell; * * ExtRangeStart = new int[TT]; * ExtRangeLen = new int[TT]; * ExtRangeTrafo = new int[TT][]; * * for(int tt = 0; tt < TT; tt++) { * int otherRank = PeerProcess[tt]; * int jFristCell = GridDat.Parallel.m_RcvCommListsInsertIndex[otherRank]; * int Jrank = GridDat.Parallel.m_RcvCommListsNoOfItems[otherRank]; * * * int offset = (int)(FrameMap.GlobalUniqueCoordinateIndex(0, jFristCell, 0)); * ExtRangeStart[tt] = offset; * ExtRangeLen[tt] = Jrank*DOFperCell; * * * ExtRangeTrafo[tt] = new int[ExtRangeLen[tt]]; * ExtRangeTrafo[tt].SetAll(int.MinValue); * * for (int j = 0; j < Jrank; j++) { // loop over all external cells that this process receives from 'otherRank' ... * int jCell = j + jFristCell; * Debug.Assert(jCell >= Jup); * Debug.Assert(jCell < Jtot); * ReducedRegionCode rrc; * int NoOfSpc = m_lsTrk.GetNoOfSpecies(jCell, out rrc); * int iSpc = m_lsTrk.GetSpeciesIndexFromId(rrc, m_spcId); * * for (int g = 0; g < G; g++) { // loop over all basises * Basis b = BasisS[g]; * XDGBasis xb = XBasisS[g]; * bool b_is_XDGbasis = (xb != null); * * int n0, N; * if (b_is_XDGbasis) { * if (iSpc < 0) { * n0 = int.MaxValue; * N = int.MinValue; * } else { * N = xb.DOFperSpeciesPerCell; * n0 = N*iSpc; * } * } else { * n0 = 0; * N = b.GetLength(j); * } * * if (N >= 0) { * int iFull = (int)(FullMap.GlobalUniqueCoordinateIndex(g, jCell, n0)); * int iFrame = (int)(FrameMap.GlobalUniqueCoordinateIndex(g, jCell, 0)); * * for (int n = 0; n < N; n++) { * ExtRangeTrafo[tt][iFrame + n - offset] = iFull + n; * } * } * } * } * } * } */ { int NoOfSpc = this.m_Regions.SpeciesIdS.Count; int N_frame = this.FrameMap.MaxTotalNoOfCoordinatesPerCell; var FramBasisS = this.FrameMap.BasisS.ToArray(); var FullBasisS = this.FullMap.BasisS.ToArray(); int[] NBs = FramBasisS.Select(b => b.Length).ToArray(); int[] NBf = FullBasisS.Select(b => b.MaximalLength).ToArray(); Debug.Assert(NBf.Length == NBs.Length); for (int i = 0; i < NBf.Length; i++) { Debug.Assert(NBf[i] % NBs[i] == 0); } bool[] XBasis = FullBasisS.Select(b => b is XDGBasis).ToArray(); this.IndexTrafoWithinCell = new int[NoOfSpc, this.FrameMap.MaxTotalNoOfCoordinatesPerCell]; for (int iSpc = 0; iSpc < NoOfSpc; iSpc++) // loop over all possible species indices { int n_frame = 0; int n_full = 0; for (int ifld = 0; ifld < NBs.Length; ifld++) // loop over all basises in the mapping { if (XBasis[ifld]) { for (int n = 0; n < NBs[ifld]; n++) { this.IndexTrafoWithinCell[iSpc, n_frame + n] = n_full + iSpc * NBs[ifld] + n; } } else { for (int n = 0; n < NBs[ifld]; n++) { this.IndexTrafoWithinCell[iSpc, n_frame + n] = n_full + n; } } n_frame += NBs[ifld]; n_full += NBf[ifld]; } } } }
/// <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()); }
/// <summary> /// computes the mass matrices for a given mapping and accumulates the mass matrix to some other matrix. /// </summary> public void AccMassMatrix <T>(T M, UnsetteledCoordinateMapping mapping, IDictionary <SpeciesId, IEnumerable <double> > _alpha, bool inverse = false) where T : IMutableMatrixEx // { using (new FuncTrace()) { var _basisS = mapping.BasisS.ToArray(); var ctx = _basisS[0].GridDat; int J = ctx.iLogicalCells.NoOfLocalUpdatedCells; if (!M.RowPartitioning.EqualsPartition(mapping)) { throw new ArgumentException("Mismatch in row mapping."); } if (!M.ColPartition.EqualsPartition(mapping)) { throw new ArgumentException("Mismatch in column mapping."); } if (!_alpha.Keys.IsSubsetOf(this.AvailableSpecies)) { throw new ArgumentException("trying to obtain mass matrix for species that is not supported by this factory."); } foreach (var __alpha in _alpha.Values) { if (__alpha.Count() != _basisS.Length) { throw new ArgumentException("Number of alpha's must match number of variables/fields in mapping."); } } LevelSetTracker.LevelSetRegions regions = null;// XDGSpaceMetrics.LevelSetRegions; // compute the Mass-Blocks for the cut cells... // -------------------------------------------- int _MaxDeg = _basisS.Max(b => b.Degree); var RequestedSpecies = _alpha.Keys; UpdateBlocks(_MaxDeg, RequestedSpecies); Dictionary <SpeciesId, MassMatrixBlockContainer>[] invBlocks = null; if (inverse) { invBlocks = GetInverseMassMatrixBlocks(RequestedSpecies, mapping.BasisS.Select(b => b.Degree).ToArray()); //VariableAgglomerationSwitch = new bool[VariableAgglomerationSwitch.Length]; //VariableAgglomerationSwitch.SetAll(true); // we already took care about this in the 'GetInverseMassMatrixBlocks' } // set the matrix // -------------- for (int fld = 0; fld < _basisS.Length; fld++) // loop over Variables in mapping... // loop over species... { foreach (var species in _alpha.Keys) { double alpha = _alpha[species].ElementAt(fld); int[] jSub2jCell = this.MassBlocks[species].jSub2jCell; if (alpha != 0.0) { // properties of the basis XDGBasis Xbasis = _basisS[fld] as XDGBasis; Basis nonXbasis; Basis basis = _basisS[fld]; if (Xbasis != null) { nonXbasis = Xbasis.NonX_Basis; regions = Xbasis.Tracker.Regions; // compute species indices with respect to **actual** regions !!!! //if (!object.ReferenceEquals(Xbasis.Tracker, this.XDGSpaceMetrics.)) // throw new ArgumentException(); } else { nonXbasis = _basisS[fld]; } int N = nonXbasis.Length; // get Mass-Matrix subblock MultidimensionalArray Mass; if (!inverse) { Mass = this.MassBlocks[species].MassMatrixBlocks; } else { Mass = invBlocks[fld][species].MassMatrixBlocks; Debug.Assert(Mass.GetLength(1) == N); Debug.Assert(Mass.GetLength(2) == N); } // set diagonal element 1.0 in all cells of the subgrid // (later, we subtract 1.0 from the diagonal in cut cells) var speciesMask = XDGSpaceMetrics.LevelSetRegions.GetSpeciesMask(species); { foreach (int jCell in speciesMask.ItemEnum) { int iSpc = 0; if (Xbasis != null) { int NoOfSpc = regions.GetNoOfSpecies(jCell); iSpc = regions.GetSpeciesIndex(species, jCell); } int n0 = mapping.GlobalUniqueCoordinateIndex(fld, jCell, N * iSpc); for (int n = 0; n < N; n++) { M[n0 + n, n0 + n] += alpha; } } } // now, set then Non-Identity blocks in the cut cells var speciesBitMask = speciesMask.GetBitMask(); { int JSUB = jSub2jCell.Length; for (int jsub = 0; jsub < JSUB; jsub++) // loop over cut cells { int jCell = jSub2jCell[jsub]; if (!speciesBitMask[jCell]) { continue; } int iSpc = 0; if (Xbasis != null) { int NoOfSpc = regions.GetNoOfSpecies(jCell); iSpc = regions.GetSpeciesIndex(species, jCell); } var MassSub = Mass.ExtractSubArrayShallow(new int[] { jsub, 0, 0 }, new int[] { jsub - 1, N - 1, N - 1 }); int i0 = mapping.GlobalUniqueCoordinateIndex(fld, jCell, N * iSpc); for (int n = 0; n < N; n++) // loop over rows (within block) { for (int m = 0; m < N; m++) // loop over columns (within block) { M[i0 + n, i0 + m] += alpha * MassSub[n, m] - (m == n ? alpha : 0.0); } } } } } } } } }