public void ImplicitEuler(double dt, SubGrid S, SinglePhaseField inout_Levset) { var VolMsk = S.VolumeMask; var EdgMsk = S.InnerEdgesMask; UnsetteledCoordinateMapping Map = inout_Levset.Mapping; if (dt <= 0.0) { throw new ArgumentOutOfRangeException("Timestep size must be greater than 0."); } MsrMatrix Pmtx = PenaltyMatrix(EdgMsk, inout_Levset.Basis, inout_Levset.Basis); Pmtx.Scale(-1.0); int[] SubVecIdx = Map.GetSubvectorIndices(S, true, new int[] { 0 }); int L = SubVecIdx.Length; MsrMatrix SubMtx = new MsrMatrix(L, L); Pmtx.AccSubMatrixTo(1.0, SubMtx, SubVecIdx, default(int[]), SubVecIdx, default(int[])); SubMtx.AccEyeSp(1.0 / dt); double[] RHS = new double[L]; double[] SOL = new double[L]; RHS.AccV(1.0 / dt, inout_Levset.CoordinateVector, default(int[]), SubVecIdx); using (var solver = new PARDISOSolver()) { solver.DefineMatrix(SubMtx); solver.Solve(SOL, RHS); } inout_Levset.CoordinateVector.ClearEntries(SubVecIdx); inout_Levset.CoordinateVector.AccV(1.0, SOL, SubVecIdx, default(int[])); }
/// <summary> /// Krankplätze müssen verdichtet werden /// -Kranführer Ronny, ProSieben Reportage /// </summary> public void Init(MultigridOperator op) { // //System.Threading.Thread.Sleep(10000); // //ilPSP.Environment.StdoutOnlyOnRank0 = false; m_op = op; if (m_CoarseLowOrder > m_op.Mapping.DgDegree.Max()) { throw new ArgumentOutOfRangeException("CoarseLowOrder is higher than maximal DG degree"); } #if TEST var debugerSW = new StreamWriter(String.Concat("debug_of_", ilPSP.Environment.MPIEnv.MPI_Rank)); Console.WriteLine("variable TEST is defined"); //debugerSW.WriteLine("proc {0} reporting Num of Blocks {1}", ilPSP.Environment.MPIEnv.MPI_Rank, HighOrderBlocks_LUpivots.Length); #endif int D = this.m_op.GridData.SpatialDimension; var DGlowSelect = new SubBlockSelector(op.Mapping); Func <int, int, int, int, bool> lowFilter = (int iCell, int iVar, int iSpec, int pDeg) => pDeg <= (iVar != D ? CoarseLowOrder : CoarseLowOrder - 1); DGlowSelect.ModeSelector(lowFilter); if (AssignXdGCellsToLowBlocks) { ModifyLowSelector(DGlowSelect, op); } lMask = new BlockMask(DGlowSelect); m_lowMaskLen = lMask.GetNoOfMaskedRows; if (UseHiOrderSmoothing) { var DGhighSelect = new SubBlockSelector(op.Mapping); Func <int, int, int, int, bool> highFilter = (int iCell, int iVar, int iSpec, int pDeg) => pDeg > (iVar != D ? CoarseLowOrder : CoarseLowOrder - 1); DGhighSelect.ModeSelector(highFilter); if (AssignXdGCellsToLowBlocks) { ModifyHighSelector(DGhighSelect, op); } hMask = new BlockMask(DGhighSelect); m_highMaskLen = hMask.GetNoOfMaskedRows; BlockMsrMatrix P01HiMatrix = null; if (UseDiagonalPmg) { HighOrderBlocks_LU = hMask.GetDiagonalBlocks(op.OperatorMatrix, false, false); int NoOfBlocks = HighOrderBlocks_LU.Length; HighOrderBlocks_LUpivots = new int[NoOfBlocks][]; for (int jLoc = 0; jLoc < NoOfBlocks; jLoc++) { int len = HighOrderBlocks_LU[jLoc].NoOfRows; HighOrderBlocks_LUpivots[jLoc] = new int[len]; HighOrderBlocks_LU[jLoc].FactorizeLU(HighOrderBlocks_LUpivots[jLoc]); } } else { P01HiMatrix = hMask.GetSubBlockMatrix(op.OperatorMatrix, csMPI.Raw._COMM.SELF); hiSolver = new PARDISOSolver() { CacheFactorization = true, UseDoublePrecision = true, // keep it true, experiments showed, that this leads to fewer iterations SolverVersion = Parallelism.OMP }; hiSolver.DefineMatrix(P01HiMatrix); } } var P01SubMatrix = lMask.GetSubBlockMatrix(op.OperatorMatrix, csMPI.Raw._COMM.WORLD); intSolver = new PARDISOSolver() { CacheFactorization = true, UseDoublePrecision = false, // no difference towards =true observed for XDGPoisson SolverVersion = Parallelism.OMP }; intSolver.DefineMatrix(P01SubMatrix); #if TEST P01SubMatrix.SaveToTextFileSparseDebug("lowM"); P01SubMatrix.SaveToTextFileSparse("lowM_full"); if (!UseDiagonalPmg) { //P01HiMatrix.SaveToTextFileSparseDebug("hiM"); //P01HiMatrix.SaveToTextFileSparse("hiM_full"); } m_op.OperatorMatrix.SaveToTextFileSparseDebug("M"); m_op.OperatorMatrix.SaveToTextFileSparse("M_full"); debugerSW.Flush(); debugerSW.Close(); long[] bla = m_op.BaseGridProblemMapping.GridDat.CurrentGlobalIdPermutation.Values; bla.SaveToTextFileDebug("permutation_"); List <int> BlockI0 = new List <int>(); List <int> Block_N = new List <int>(); foreach (long Block in bla) { BlockI0.Add(m_op.Mapping.GetBlockI0((int)Block)); Block_N.Add(m_op.Mapping.GetBlockLen((int)Block)); } BlockI0.SaveToTextFileDebug("BlockI0"); Block_N.SaveToTextFileDebug("Block_N"); #endif }
/// <summary> /// ~ /// </summary> public void Init(MultigridOperator op) { //System.Threading.Thread.Sleep(10000); //ilPSP.Environment.StdoutOnlyOnRank0 = false; m_op = op; var Map = op.Mapping; int NoVars = Map.AggBasis.Length; int j0 = Map.FirstBlock; int J = Map.LocalNoOfBlocks; int[] degs = m_op.Degrees; for (int ideg = 0; ideg < degs.Length; ideg++) { if (degs[ideg] == 0) { throw new ArgumentException(String.Format("DGdegree for Variable {0} is 0, p-multigrid not possible", ideg)); } } var BS = Map.AggBasis; if (UseHiOrderSmoothing) { HighOrderBlocks_LU = new MultidimensionalArray[J]; HighOrderBlocks_LUpivots = new int[J][]; HighOrderBlocks_indices = new int[J][]; } var GsubIdx = new List <int>(); var LsubIdx = new List <int>(); var lowLocalBlocks_i0 = new List <int>(); var lowLocalBlocks__N = new List <int>(); int cnt = 0; /* * var debugerSW = new StreamWriter(String.Concat("debug_of_", ilPSP.Environment.MPIEnv.MPI_Rank)); * debugerSW.WriteLine("proc {0} reporting ...",ilPSP.Environment.MPIEnv.MPI_Rank); * debugerSW.WriteLine("Num of Blocks {0}",HighOrderBlocks_LUpivots.Length); */ for (int jLoc = 0; jLoc < J; jLoc++) { lowLocalBlocks_i0.Add(cnt); lowLocalBlocks__N.Add(0); var LhiIdx = new List <int>(); var IdxHighBlockOffset = new int[NoVars][]; var IdxHighOffset = new int[NoVars][]; int NpHiTot = 0; for (int iVar = 0; iVar < NoVars; iVar++) { int pReq; if (degs[iVar] <= 1) { pReq = 0; } else { pReq = CoarseLowOrder; } int Np1 = BS[iVar].GetLength(jLoc, pReq); int Np = BS[iVar].GetLength(jLoc, degs[iVar]); lowLocalBlocks__N[jLoc] += Np1; int NoOfSpc = BS[iVar].GetNoOfSpecies(jLoc); int NpBase = Np / NoOfSpc; int NpBaseLow = Np1 / NoOfSpc; IdxHighBlockOffset[iVar] = new int[NoOfSpc + 1]; IdxHighOffset[iVar] = new int[NoOfSpc]; for (int iSpc = 0; iSpc < NoOfSpc; iSpc++) { int n = 0; int cellOffset = NpBase * iSpc; IdxHighOffset[iVar][iSpc] = Map.GlobalUniqueIndex(iVar, jLoc, cellOffset + NpBaseLow); for (; n < NpBaseLow; n++) { int Lidx = Map.LocalUniqueIndex(iVar, jLoc, n + cellOffset); LsubIdx.Add(Lidx); //local block mapping Coarse Matrix (low order entries) to original matrix int Gidx = Map.GlobalUniqueIndex(iVar, jLoc, n + cellOffset); GsubIdx.Add(Gidx); //global mapping Coarse Matrix (low order entries) to original matrix } for (; n < NpBase; n++) { int Lidx = Map.LocalUniqueIndex(iVar, jLoc, n + cellOffset); LhiIdx.Add(Lidx); //local block mapping of high order entries to original matrix //int Gidx = Map.GlobalUniqueIndex(iVar, jLoc, n); //GhiIdx.Add(Gidx); } IdxHighBlockOffset[iVar][iSpc] = NpHiTot; NpHiTot += (NpBase - NpBaseLow); } IdxHighBlockOffset[iVar][NoOfSpc] = NpHiTot; Debug.Assert(GsubIdx.Last() == Map.GlobalUniqueIndex(iVar, jLoc, (NoOfSpc - 1) * NpBase + NpBaseLow - 1)); Debug.Assert(LhiIdx.Last() == Map.LocalUniqueIndex(iVar, jLoc, NoOfSpc * NpBase - 1)); } // Save high order blocks for later smoothing if (NpHiTot > 0) { HighOrderBlocks_LU[jLoc] = MultidimensionalArray.Create(NpHiTot, NpHiTot); HighOrderBlocks_indices[jLoc] = LhiIdx.ToArray(); for (int iVar = 0; iVar < NoVars; iVar++) { for (int jVar = 0; jVar < NoVars; jVar++) { for (int iSpc = 0; iSpc < BS[jVar].GetNoOfSpecies(jLoc); iSpc++) { int i0_hi = IdxHighOffset[iVar][iSpc]; int j0_hi = IdxHighOffset[jVar][iSpc]; int Row_i0 = IdxHighBlockOffset[iVar][iSpc]; int Col_i0 = IdxHighBlockOffset[jVar][iSpc]; int Row_ie = IdxHighBlockOffset[iVar][iSpc + 1]; int col_ie = IdxHighBlockOffset[jVar][iSpc + 1]; //debugerSW.WriteLine("Block {0}: i0={1} j0={2} iVar={3}", jLoc, i0_hi, j0_hi, iVar); m_op.OperatorMatrix.ReadBlock(i0_hi, j0_hi, HighOrderBlocks_LU[jLoc].ExtractSubArrayShallow(new int[] { Row_i0, Col_i0 }, new int[] { Row_ie - 1, col_ie - 1 })); } } } HighOrderBlocks_LUpivots[jLoc] = new int[NpHiTot]; HighOrderBlocks_LU[jLoc].FactorizeLU(HighOrderBlocks_LUpivots[jLoc]); } cnt += lowLocalBlocks__N[jLoc]; } m_LsubIdx = LsubIdx.ToArray(); BlockPartitioning localBlocking = new BlockPartitioning(GsubIdx.Count, lowLocalBlocks_i0, lowLocalBlocks__N, Map.MPI_Comm, i0isLocal: true); var P01SubMatrix = new BlockMsrMatrix(localBlocking); op.OperatorMatrix.AccSubMatrixTo(1.0, P01SubMatrix, GsubIdx, default(int[]), GsubIdx, default(int[])); intSolver = new PARDISOSolver() { CacheFactorization = true, UseDoublePrecision = false }; intSolver.DefineMatrix(P01SubMatrix); /* * LsubIdx.SaveToTextFileDebug("LsubIdx"); * GsubIdx.SaveToTextFileDebug("GsubIdx"); * P01SubMatrix.SaveToTextFileSparseDebug("lowM"); * m_op.OperatorMatrix.SaveToTextFileSparseDebug("M"); * P01SubMatrix.SaveToTextFileSparse("lowM_full"); * m_op.OperatorMatrix.SaveToTextFileSparse("M_full"); * * debugerSW.WriteLine("Dim of lowMatrix: {0}",GsubIdx.Count); * debugerSW.Flush(); * debugerSW.Close(); */ }