public override void GetRestrictionMatrix(BlockMsrMatrix RST, MultigridMapping mgMap, int iF) { if (!object.ReferenceEquals(mgMap.AggBasis[iF], this)) { throw new ArgumentException(); } //MsrMatrix RST = new MsrMatrix(mgMap.Partitioning, mgMap.ProblemMapping); int JAGG = this.AggGrid.iLogicalCells.NoOfLocalUpdatedCells; int[] degrees = mgMap.DgDegree; int NoFld = degrees.Length; int N_rest; // = new int[NoFld]; int N_full; // = new int[NoFld]; { BoSSS.Foundation.Basis b = mgMap.ProblemMapping.BasisS[iF]; BoSSS.Foundation.Basis NxB = (b is BoSSS.Foundation.XDG.XDGBasis) ? ((BoSSS.Foundation.XDG.XDGBasis)b).NonX_Basis : b; N_rest = NxB.Polynomials[0].Where(poly => poly.AbsoluteDegree <= degrees[iF]).Count(); N_full = NxB.Length; } int mgMap_Offset = mgMap.Partitioning.i0; for (int jAgg = 0; jAgg < JAGG; jAgg++) { int[] AgCell = this.AggGrid.iLogicalCells.AggregateCellToParts[jAgg]; int K = AgCell.Length; int NoSpc_Agg = this.NoOfSpecies[jAgg]; // number of species in aggregate cell for (int iSpc_Agg = 0; iSpc_Agg < NoSpc_Agg; iSpc_Agg++) // loop over all species in aggregate cell { { // loop over DG fields in the mapping int NROW = N_rest; int NCOL = N_full; Debug.Assert(mgMap.AggBasis[iF].GetLength(jAgg, degrees[iF]) == N_rest * NoSpc_Agg); int i0Agg_Loc = mgMap.LocalUniqueIndex(iF, jAgg, N_rest * iSpc_Agg); int i0Agg = i0Agg_Loc + mgMap_Offset; Debug.Assert(i0Agg >= mgMap.Partitioning.i0); Debug.Assert(i0Agg < mgMap.Partitioning.iE); if (this.SpeciesIndexMapping[jAgg] == null) { Debug.Assert(NoSpc_Agg == 1); Debug.Assert(NoSpc_Agg == 1); // default branch: // use restriction/prolongation from un-cut basis // +++++++++++++++++++++++++++++++++++++++++++++ MultidimensionalArray Trf = base.CompositeBasis[jAgg]; for (int k = 0; k < K; k++) // loop over the cells which form the aggregated cell... { int jCell = AgCell[k]; int i0Full = mgMap.ProblemMapping.GlobalUniqueCoordinateIndex(iF, jCell, 0); var Block = Trf.ExtractSubArrayShallow(k, -1, -1); for (int nRow = 0; nRow < NROW; nRow++) { for (int nCol = 0; nCol < NCOL; nCol++) { RST[i0Agg + nRow, i0Full + nCol] = Block[nCol, nRow]; } } } } else { int NoSpc = this.NoOfSpecies[jAgg]; int[,] sim = SpeciesIndexMapping[jAgg]; Debug.Assert(sim.GetLength(0) == NoSpc); Debug.Assert(sim.GetLength(1) == K); MultidimensionalArray Trf; if (this.XCompositeBasis[jAgg] == null || this.XCompositeBasis[jAgg][iSpc_Agg] == null) { Trf = base.CompositeBasis[jAgg]; } else { Trf = this.XCompositeBasis[jAgg][iSpc_Agg]; } for (int k = 0; k < K; k++) // loop over the cells which form the aggregated cell... { int jCell = AgCell[k]; int iSpcBase = sim[iSpc_Agg, k]; if (iSpcBase < 0) { //for(int n = 0; n < N; n++) // FulCoords[k, n] = 0; } else { int i0Full = mgMap.ProblemMapping.GlobalUniqueCoordinateIndex(iF, jCell, iSpcBase * N_full); var Block = Trf.ExtractSubArrayShallow(k, -1, -1); for (int nRow = 0; nRow < NROW; nRow++) { for (int nCol = 0; nCol < NCOL; nCol++) { RST[i0Agg + nRow, i0Full + nCol] = Block[nCol, nRow]; } } } } } } } } //return RST; }
public override void ProlongateToFullGrid <T, V>(T FullGridVector, V AggGridVector) { var fullMapping = new UnsetteledCoordinateMapping(this.XDGBasis); if (FullGridVector.Count != fullMapping.LocalLength) { throw new ArgumentException("mismatch in vector length", "FullGridVector"); } int L = this.LocalDim; if (AggGridVector.Count != L) { throw new ArgumentException("mismatch in vector length", "AggGridVector"); } var ag = this.AggGrid; var agCls = ag.iLogicalCells.AggregateCellToParts; int JAGG = ag.iLogicalCells.NoOfLocalUpdatedCells; int Nmax = this.XDGBasis.MaximalLength; int N = this.DGBasis.Length; Debug.Assert(Nmax % N == 0); var FulCoords = new double[N]; var AggCoords = new double[N]; for (int jAgg = 0; jAgg < JAGG; jAgg++) // loop over all composite cells... { int[] agCl = agCls[jAgg]; int K = agCl.Length; if (this.SpeciesIndexMapping[jAgg] == null) { Debug.Assert(this.XCompositeBasis[jAgg] == null); int i0 = jAgg * Nmax; // index offset into 'AggGridVector' for (int n = 0; n < N; n++) { AggCoords[n] = AggGridVector[n + i0]; } for (int k = 0; k < K; k++) // loop over the cells wich form the aggregated cell... { int jCell = agCl[k]; int j0 = fullMapping.LocalUniqueCoordinateIndex(0, jCell, 0); MultidimensionalArray Trf = base.CompositeBasis[jAgg].ExtractSubArrayShallow(k, -1, -1); //Trf.Solve(FulCoords, AggCoords); Trf.GEMV(1.0, AggCoords, 0.0, FulCoords); for (int n = 0; n < N; n++) { FullGridVector[j0 + n] = FulCoords[n]; } } } else { int NoSpc = this.NoOfSpecies[jAgg]; int[,] sim = SpeciesIndexMapping[jAgg]; Debug.Assert(sim.GetLength(0) == NoSpc); Debug.Assert(sim.GetLength(1) == K); for (int iSpcAgg = 0; iSpcAgg < NoSpc; iSpcAgg++) { int i0 = jAgg * Nmax + iSpcAgg * N; // index offset into 'AggGridVector' for (int n = 0; n < N; n++) { AggCoords[n] = AggGridVector[n + i0]; } for (int k = 0; k < K; k++) // loop over the cells wich form the aggregated cell... { int jCell = agCl[k]; int iSpcBase = sim[iSpcAgg, k]; if (iSpcBase < 0) { continue; } int j0 = fullMapping.LocalUniqueCoordinateIndex(0, jCell, iSpcBase * N); MultidimensionalArray Trf; if (this.XCompositeBasis[jAgg] == null || this.XCompositeBasis[jAgg][iSpcAgg] == null) { Trf = base.CompositeBasis[jAgg].ExtractSubArrayShallow(k, -1, -1); } else { Trf = this.XCompositeBasis[jAgg][iSpcAgg].ExtractSubArrayShallow(k, -1, -1); } Trf.GEMV(1.0, AggCoords, 0.0, FulCoords); for (int n = 0; n < N; n++) { FullGridVector[j0 + n] = FulCoords[n]; } } } } } }