static public IBM_Control PrecTest3dDegenhardt(int precNo = 4, int channel = 1, int name_newton = 1, int k = 3, int cells_x = 4, int cells_yz = 5, int re = 100, int ASparts = 3, int ASDepth = 2, int MGLevels = 3, int maxKrDim = 1000, int saveToDB = 1) { IBM_Control C = new IBM_Control(); //in SolverFactory die DoF parts ändern //Possibilities: //channel = 0 --> channel 3D with sphere //channel = 1 --> channel 3D empty //channel = 2 --> channel 2D with cylinder //channel = 3 --> channel 2D empty string sessName = ""; if (channel == 0) { sessName = "Channel_3D_Sphere"; } else if (channel == 1) { sessName = "Channel_3D_empty"; } else if (channel == 2) { sessName = "Channel_2D_Cylinder"; } else if (channel == 3) { sessName = "Channel_2D_empty"; } string precString = ""; if (precNo == 0) { precString = "_noPrec"; } if (precNo == 1) { precString = "_Schur"; } if (precNo == 2) { precString = "_Simple"; } if (precNo == 3) { precString = "_AS-1000"; } if (precNo == 4) { precString = "_AS-5000"; } if (precNo == 5) { precString = "_AS-10000"; } if (precNo == 6) { precString = "_AS-MG"; } if (precNo == 7) { precString = "_localPrec"; } // basic database options // ====================== // if (saveToDB == 1) // C.savetodb = true; //else //C.savetodb = false; C.savetodb = true; C.DbPath = @" \\dc1\scratch\Krause\Datenbank_Louis\degenhardt_final"; //C.DbPath = @"\\hpccluster\hpccluster-scratch\krause\cluster_db"; //C.DbPath = @"/home/oe11okuz/BoSSS_DB/Lichtenberg_DB"; //string restartSession = "727da287-1b6a-463e-b7c9-7cc19093b5b3"; //string restartGrid = "3f8f3445-46f1-47ed-ac0e-8f0260f64d8f"; C.DynamicLoadBalancing_Period = 1; //C.DynamicLoadBalancing_CellCostEstimatorFactory = delegate (IApplication<AppControl> app, int noOfPerformanceClasses) { // Console.WriteLine("i was called"); // int[] map = new int[] { 1, 5, 100 }; // return new StaticCellCostEstimator(map); //}; if (name_newton == 1) { C.SessionName = "Newton_" + sessName + precString + "_k" + k + "_x" + cells_x + "_yz" + cells_yz + "_re" + re + "_asp" + ASparts + "_asd" + ASDepth + "_mgl" + MGLevels + "_kr" + maxKrDim; C.ProjectDescription = "Newton_" + sessName + precString + "_k" + k + "_x" + cells_x + "_yz" + cells_yz + "_re" + re + "_asp" + ASparts + "_asd" + ASDepth + "_mgl" + MGLevels + "_kr" + maxKrDim; } else { C.SessionName = "Picard_" + sessName + precString + "_k" + k + "_x" + cells_x + "_yz" + cells_yz + "_re" + re + "_asp" + ASparts + "_asd" + ASDepth + "_mgl" + MGLevels + "_kr" + maxKrDim; C.ProjectDescription = "Picard_" + sessName + precString + "_k" + k + "_x" + cells_x + "_yz" + cells_yz + "_re" + re + "_asp" + ASparts + "_asd" + ASDepth + "_mgl" + MGLevels + "_kr" + maxKrDim; } C.saveperiod = 1; //C.SessionName = "Sphere_k" + k + "_h" + h+"Re100"; C.ProjectName = "iteration-study"; C.Tags.Add("Prec param study"); // Create Fields C.FieldOptions.Add("VelocityX", new FieldOpts() { Degree = k, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); C.FieldOptions.Add("VelocityY", new FieldOpts() { Degree = k, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); C.FieldOptions.Add("Pressure", new FieldOpts() { Degree = k - 1, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); C.FieldOptions.Add("PhiDG", new FieldOpts() { Degree = 2, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); C.FieldOptions.Add("Phi", new FieldOpts() { Degree = 2, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); if (channel == 0 || channel == 1) //3D { C.FieldOptions.Add("VelocityZ", new FieldOpts() { Degree = k, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); } #region Creates grid () and sets BC //// Create Grid Console.WriteLine("...generating grid"); if (channel == 0 || channel == 1) //3D { #region grid 3D C.GridFunc = delegate { // x-direction var _xNodes = GenericBlas.Linspace(-0.5, 1.5, cells_x + 1); // y-direction var _yNodes = GenericBlas.Linspace(-0.5, 0.5, cells_yz + 1); // z-direction var _zNodes = GenericBlas.Linspace(-0.5, 0.5, cells_yz + 1); // Cut Out var grd = Grid3D.Cartesian3DGrid(_xNodes, _yNodes, _zNodes, CellType.Cube_Linear, false, true, false); grd.EdgeTagNames.Add(1, "Velocity_inlet"); grd.EdgeTagNames.Add(2, "Wall"); grd.EdgeTagNames.Add(3, "Pressure_Outlet"); grd.DefineEdgeTags(delegate(double[] _X) { var X = _X; double x = X[0]; double y = X[1]; double z = X[2]; if (Math.Abs(x - (-0.5)) < 1.0e-6) { // inlet return(1); } if (Math.Abs(x - (1.5)) < 1.0e-6) { // outlet return(3); } if (Math.Abs(y - (-0.5)) < 1.0e-6) { // left return(2); } if (Math.Abs(y - (0.5)) < 1.0e-6) { // right return(2); } if (Math.Abs(z - (-0.5)) < 1.0e-6) { // top left return(2); } if (Math.Abs(z - (0.5)) < 1.0e-6) { // top right return(2); } throw new ArgumentOutOfRangeException(); }); return(grd); }; #endregion } else { #region grid 2D C.GridFunc = delegate { // x-direction var _xnodes = GenericBlas.Linspace(-0.5, 1.5, cells_x + 1); // y-direction var _ynodes = GenericBlas.Linspace(-0.5, 0.5, cells_yz + 1); var grd = Grid2D.Cartesian2DGrid(_xnodes, _ynodes, CellType.Square_Linear, false, false); grd.EdgeTagNames.Add(1, "Velocity_inlet"); grd.EdgeTagNames.Add(2, "Wall"); grd.EdgeTagNames.Add(3, "Pressure_Outlet"); grd.DefineEdgeTags(delegate(double[] _X) { var X = _X; double x = X[0]; double y = X[1]; if (Math.Abs(x - (-0.5)) < 1.0e-6) { // inlet return(1); } if (Math.Abs(x - (1.5)) < 1.0e-6) { // outlet return(3); } if (Math.Abs(y - (-0.5)) < 1.0e-6) { // left return(2); } if (Math.Abs(y - (0.5)) < 1.0e-6) { // right return(2); } throw new ArgumentOutOfRangeException(); }); return(grd); }; #endregion } #endregion // set initial conditions C.InitialValues_Evaluators.Add("Pressure", X => 0); C.InitialValues_Evaluators.Add("VelocityY", X => 0); if (channel == 0 | channel == 1) //3D { //C.InitialValues_Evaluators.Add("VelocityX", X => 1 - 4 * (X[2] * X[2])); C.InitialValues_Evaluators.Add("VelocityX", X => 0); C.InitialValues_Evaluators.Add("VelocityZ", X => 0); } else { //C.InitialValues_Evaluators.Add("VelocityX", X => 1 - 4 * (X[1] * X[1])); C.InitialValues_Evaluators.Add("VelocityX", X => 0); } // Because its a sphere if (channel == 0) //3D channel sphere { C.particleRadius = 0.1; C.InitialValues_Evaluators.Add("Phi", x => - (x[0]).Pow2() + -(x[1]).Pow2() + -(x[2]).Pow2() + C.particleRadius.Pow2()); } else if (channel == 1 || channel == 3) //3D channel empty or 2D channel empty { C.InitialValues_Evaluators.Add("Phi", x => - 1); } else if (channel == 2) //2D channel cylinder { var radius = 0.1; C.particleRadius = radius; C.InitialValues_Evaluators.Add("Phi", X => - (X[0]).Pow2() + -(X[1]).Pow2() + radius.Pow2()); } Console.WriteLine("...starting calculation of Preconditioning test with 3D Channel"); if (name_newton == 1) { Console.WriteLine("newton_" + sessName + precString + "_k" + k + "_x" + cells_x + "_yz" + cells_yz + "_re" + re + "_asp" + ASparts + "_asd" + ASDepth + "_mgl" + MGLevels + "_kr" + maxKrDim); } else { Console.WriteLine("picard_" + sessName + precString + "_k" + k + "_x" + cells_x + "_yz" + cells_yz + "_re" + re + "_asp" + ASparts + "_asd" + ASDepth + "_mgl" + MGLevels + "_kr" + maxKrDim); } // Physical values C.PhysicalParameters.rho_A = 1; // 1/Re //C.PhysicalParameters.mu_A = 1.0 / 10.0; //C.PhysicalParameters.mu_A = 0.2 / re; C.PhysicalParameters.mu_A = 1.0 / re; // Boundary conditions C.AddBoundaryValue("Velocity_inlet", "VelocityY", (x, t) => 0); C.AddBoundaryValue("Wall"); C.AddBoundaryValue("Pressure_Outlet"); if (channel == 0 || channel == 1) //3D { C.AddBoundaryValue("Velocity_inlet", "VelocityX", (x, t) => 1 - 4 * (x[2] * x[2])); } else { C.AddBoundaryValue("Velocity_inlet", "VelocityX", (x, t) => 1 - 4 * (x[1] * x[1])); } // misc. solver options // ==================== C.PhysicalParameters.IncludeConvection = true; C.AdvancedDiscretizationOptions.PenaltySafety = 4; C.AdvancedDiscretizationOptions.CellAgglomerationThreshold = 0.2; C.LevelSetSmoothing = false; //C.LinearSolver.MaxKrylovDim = 1000; C.LinearSolver.MaxKrylovDim = maxKrDim; C.LinearSolver.MaxSolverIterations = 100; C.LinearSolver.MinSolverIterations = 1; C.NonLinearSolver.MaxSolverIterations = 100; C.NonLinearSolver.MinSolverIterations = 1; C.LinearSolver.ConvergenceCriterion = 1E-5; C.NonLinearSolver.ConvergenceCriterion = 1E-5; //C.LinearSolver.ConvergenceCriterion = 1E-6; C.VelocityBlockPrecondMode = MultigridOperator.Mode.SymPart_DiagBlockEquilib_DropIndefinite; // Choosing the Preconditioner ISolverSmootherTemplate Prec; if (name_newton == 1) { C.NonLinearSolver.SolverCode = NonLinearSolverCode.Newton; // Newton GMRES will be executed if a GMRES linsolver is chosen } else { C.NonLinearSolver.SolverCode = NonLinearSolverCode.Picard; // Picard GMRES will be executed if a GMRES linsolver is chosen } switch (precNo) { case 0: { Prec = null; break; } case 1: { C.LinearSolver.SolverCode = LinearSolverCode.exp_gmres_Schur; break; } case 2: { C.LinearSolver.SolverCode = LinearSolverCode.exp_gmres_Simple; break; } case 3: { C.LinearSolver.SolverCode = LinearSolverCode.exp_gmres_AS; C.LinearSolver.TargetBlockSize = 1000; C.LinearSolver.NoOfMultigridLevels = MGLevels; // 3 // --> grobes MG am Ende nochmal break; } case 4: { C.LinearSolver.SolverCode = LinearSolverCode.exp_gmres_AS; C.LinearSolver.TargetBlockSize = 5000; C.LinearSolver.NoOfMultigridLevels = MGLevels; break; } case 5: { C.LinearSolver.SolverCode = LinearSolverCode.exp_gmres_AS; C.LinearSolver.TargetBlockSize = 10000; C.LinearSolver.NoOfMultigridLevels = MGLevels; break; } case 6: { //depth = 2, // Depth = ASDepth, //--> MG bei der Blockzerlegung --> Resultat ergibt die Blöcke zur Berechnung (kleine Blöcke--> schlecht) C.LinearSolver.SolverCode = LinearSolverCode.exp_gmres_AS_MG; C.NoOfMultigridLevels = 2; C.LinearSolver.NoOfMultigridLevels = MGLevels; break; } case 7: { C.LinearSolver.SolverCode = LinearSolverCode.exp_gmres_localPrec;; C.LinearSolver.NoOfMultigridLevels = MGLevels; break; } case 8: { C.LinearSolver.NoOfMultigridLevels = 5; Prec = new Schwarz() { m_BlockingStrategy = new Schwarz.METISBlockingStrategy() { //noofparts = 5, NoOfPartsPerProcess = ASparts, }, CoarseSolver = new ClassicMultigrid() { CoarserLevelSolver = new ClassicMultigrid() { CoarserLevelSolver = new ClassicMultigrid() { CoarserLevelSolver = new DirectSolver() { WhichSolver = DirectSolver._whichSolver.MUMPS }, }, }, }, Overlap = 1 }; break; } default: { Prec = new SchurPrecond() { SchurOpt = SchurPrecond.SchurOptions.decoupledApprox }; break; } } // For Newton // C.LinearSolver.SolverCoder = Prec; ////For Picard //C.LinearSolver.SolverCoder = new SoftGMRES() //{ // MaxKrylovDim = C.LinearSolver.MaxKrylovDim, // Precond_solver = Prec, // m_Tolerance = 1E-6, // m_MaxIterations = 50 //}; // Timestepping // ============ C.Timestepper_Scheme = IBM_Control.TimesteppingScheme.BDF2; double dt = 1E20; C.dtFixed = dt; C.dtMax = dt; C.dtMin = dt; C.Endtime = 10000000; C.NoOfTimesteps = 1; return(C); }
/// <summary> /// Initialization of each multi-grid level /// </summary> public void Init(MultigridOperator op) { using (new FuncTrace()) { // checks // ====== var M = op.OperatorMatrix; var MgMap = op.Mapping; this.m_mgop = op; int MpiSize = M._RowPartitioning.MpiSize; if (!M.RowPartitioning.EqualsPartition(MgMap.Partitioning)) { throw new ArgumentException("Row partitioning mismatch."); } if (!M.ColPartition.EqualsPartition(MgMap.Partitioning)) { throw new ArgumentException("Column partitioning mismatch."); } // determine which levels to use // ============================= { var tempOp4Level = new List <MultigridOperator>(); var Op = op; do { tempOp4Level.Add(Op); Op = Op.CoarserLevel; if (Op == null) { break; } } while (tempOp4Level.Last().Mapping.TotalLength > LowestLevelDOFthreshold); Op4Level = tempOp4Level.ToArray(); Mtx4Level = new BlockMsrMatrix[Op4Level.Length]; for (int i = 0; i < Mtx4Level.Length; i++) { Mtx4Level[i] = Op4Level[i].OperatorMatrix; } } // define preconditioner's // ======================= { PrecondS = new ISolverSmootherTemplate[Op4Level.Length]; // all levels except the coarsest one for (int i = 0; i < PrecondS.Length - 1; i++) { int NoOfBlocks = (int)Math.Ceiling((double)(Op4Level[i].Mapping.LocalLength) / (double)LowestLevelDOFthreshold); // we want at least two blocks - otherwise we could use the direct solver directly. if (MpiSize > 1) { // more than one MPI core -> at least one block per core -> globally at least 2 cores NoOfBlocks = Math.Max(1, NoOfBlocks); } else { // singe MPI core -> at least two blocks NoOfBlocks = Math.Max(2, NoOfBlocks); } PrecondS[i] = new Schwarz() { FixedNoOfIterations = 1, CoarseSolver = null, m_BlockingStrategy = new Schwarz.METISBlockingStrategy() { NoOfPartsPerProcess = NoOfBlocks }, Overlap = 1 }; } // coarsest level PrecondS[PrecondS.Length - 1] = new DirectSolver() { WhichSolver = DirectSolver._whichSolver.PARDISO, TestSolution = false }; // init each level for (int i = 0; i < PrecondS.Length; i++) { PrecondS[i].Init(Op4Level[i]); } } } }
/// <summary> /// /// </summary> ISolverSmootherTemplate KcycleMultiSchwarz(MultigridOperator op) { var solver = new OrthonormalizationScheme() { MaxIter = 500, Tolerance = 1.0e-10, }; // my tests show that the ideal block size may be around 10'000 int DirectKickIn = base.Control.TargetBlockSize; MultigridOperator Current = op; var PrecondChain = new List<ISolverSmootherTemplate>(); for (int iLevel = 0; iLevel < base.MultigridSequence.Length; iLevel++) { int SysSize = Current.Mapping.TotalLength; int NoOfBlocks = (int)Math.Ceiling(((double)SysSize) / ((double)DirectKickIn)); bool useDirect = false; useDirect |= (SysSize < DirectKickIn); useDirect |= iLevel == base.MultigridSequence.Length - 1; useDirect |= NoOfBlocks.MPISum() <= 1; ISolverSmootherTemplate levelSolver; if (useDirect) { levelSolver = new DirectSolver() { WhichSolver = DirectSolver._whichSolver.PARDISO, TestSolution = false }; } else { Schwarz swz1 = new Schwarz() { m_MaxIterations = 1, CoarseSolver = null, m_BlockingStrategy = new Schwarz.METISBlockingStrategy() { NoOfPartsPerProcess = NoOfBlocks }, Overlap = 2 // overlap seems to help }; SoftPCG pcg1 = new SoftPCG() { m_MinIterations = 5, m_MaxIterations = 5 }; //*/ var pre = new SolverSquence() { SolverChain = new ISolverSmootherTemplate[] { swz1, pcg1 } }; levelSolver = swz1; } if (iLevel > 0) { GenericRestriction[] R = new GenericRestriction[iLevel]; for (int ir = 0; ir < R.Length; ir++) { R[ir] = new GenericRestriction(); if (ir >= 1) R[ir - 1].CoarserLevelSolver = R[ir]; } R[iLevel - 1].CoarserLevelSolver = levelSolver; PrecondChain.Add(R[0]); } else { PrecondChain.Add(levelSolver); } if (useDirect) { Console.WriteLine("Kswz: using {0} levels, lowest level DOF is {1}, target size is {2}.", iLevel + 1, SysSize, DirectKickIn); break; } Current = Current.CoarserLevel; } if (PrecondChain.Count > 1) { /* // construct a V-cycle for (int i = PrecondChain.Count - 2; i>= 0; i--) { PrecondChain.Add(PrecondChain[i]); } */ var tmp = PrecondChain.ToArray(); for (int i = 0; i < PrecondChain.Count; i++) { PrecondChain[i] = tmp[PrecondChain.Count - 1 - i]; } } solver.PrecondS = PrecondChain.ToArray(); solver.MaxKrylovDim = solver.PrecondS.Length * 4; return solver; }
/// <summary> /// Ganz ok. /// </summary> ISolverSmootherTemplate MultilevelSchwarz(MultigridOperator op) { var solver = new SoftPCG() { m_MaxIterations = 500, m_Tolerance = 1.0e-12 }; //var solver = new OrthonormalizationScheme() { // MaxIter = 500, // Tolerance = 1.0e-10, //}; //var solver = new SoftGMRES() { // m_MaxIterations = 500, // m_Tolerance = 1.0e-10, //}; // my tests show that the ideal block size may be around 10'000 int DirectKickIn = base.Control.TargetBlockSize; MultigridOperator Current = op; ISolverSmootherTemplate[] MultigridChain = new ISolverSmootherTemplate[base.MultigridSequence.Length]; for (int iLevel = 0; iLevel < base.MultigridSequence.Length; iLevel++) { int SysSize = Current.Mapping.TotalLength; int NoOfBlocks = (int)Math.Ceiling(((double)SysSize) / ((double)DirectKickIn)); bool useDirect = false; useDirect |= (SysSize < DirectKickIn); useDirect |= iLevel == base.MultigridSequence.Length - 1; useDirect |= NoOfBlocks.MPISum() <= 1; if (useDirect) { MultigridChain[iLevel] = new DirectSolver() { WhichSolver = DirectSolver._whichSolver.PARDISO, TestSolution = false }; } else { ClassicMultigrid MgLevel = new ClassicMultigrid() { m_MaxIterations = 1, m_Tolerance = 0.0 // termination controlled by top level PCG }; MultigridChain[iLevel] = MgLevel; ISolverSmootherTemplate pre, pst; if (iLevel > 0) { Schwarz swz1 = new Schwarz() { m_MaxIterations = 1, CoarseSolver = null, m_BlockingStrategy = new Schwarz.METISBlockingStrategy() { NoOfPartsPerProcess = NoOfBlocks }, Overlap = 0 // overlap does **NOT** seem to help }; SoftPCG pcg1 = new SoftPCG() { m_MinIterations = 5, m_MaxIterations = 5 }; SoftPCG pcg2 = new SoftPCG() { m_MinIterations = 5, m_MaxIterations = 5 }; var preChain = new ISolverSmootherTemplate[] { swz1, pcg1 }; var pstChain = new ISolverSmootherTemplate[] { swz1, pcg2 }; pre = new SolverSquence() { SolverChain = preChain }; pst = new SolverSquence() { SolverChain = pstChain }; } else { // +++++++++++++++++++++++++++++++++++++++++++++++++++ // top level - use only iterative (non-direct) solvers // +++++++++++++++++++++++++++++++++++++++++++++++++++ pre = new BlockJacobi() { NoOfIterations = 3, omega = 0.5 }; pst = new BlockJacobi() { NoOfIterations = 3, omega = 0.5 }; //preChain = new ISolverSmootherTemplate[] { pcg1 }; //pstChain = new ISolverSmootherTemplate[] { pcg2 }; } //if (iLevel > 0) { // MgLevel.PreSmoother = pre; // MgLevel.PostSmoother = pst; //} else { // //MgLevel.PreSmoother = pcg1; // ganz schlechte Idee, konvergiert gegen FALSCHE lösung // //MgLevel.PostSmoother = pcg2; // ganz schlechte Idee, konvergiert gegen FALSCHE lösung // MgLevel.PreSmoother = pre; // MgLevel.PostSmoother = pst; //} MgLevel.PreSmoother = pre; MgLevel.PostSmoother = pst; } if (iLevel > 0) { ((ClassicMultigrid)(MultigridChain[iLevel - 1])).CoarserLevelSolver = MultigridChain[iLevel]; } if (useDirect) { Console.WriteLine("MG: using {0} levels, lowest level DOF is {1}, target size is {2}.", iLevel + 1, SysSize, DirectKickIn); break; } Current = Current.CoarserLevel; } // end of level loop solver.Precond = MultigridChain[0]; //solver.PrecondS = new[] { MultigridChain[0] }; return solver; }
/// <summary> /// Choose solver depending on configurations made in the control file. /// </summary> /// <param name="nonlinSol"></param> /// <param name="linSol"></param> /// <param name="Timestepper"></param> public static void ChooseSolver(IBM_Control Control, ref XdgBDFTimestepping Timestepper) { // Set several solver options for Timestepper Timestepper.Config_SolverConvergenceCriterion = Control.Solver_ConvergenceCriterion; Timestepper.Config_MaxIterations = Control.MaxSolverIterations; Timestepper.Config_MinIterations = Control.MinSolverIterations; Timestepper.Config_MaxKrylovDim = Control.MaxKrylovDim; // Set to pseudo Picard if the Stokes equations should be solved if (Control.PhysicalParameters.IncludeConvection == false) { Control.NonlinearSolve = NonlinearSolverCodes.Picard; } ISolverSmootherTemplate templinearSolve = null; switch (Control.LinearSolve) { case LinearSolverCodes.automatic: templinearSolve = AutomaticChoice(Control, Timestepper); break; case LinearSolverCodes.classic_mumps: templinearSolve = new DirectSolver() { WhichSolver = DirectSolver._whichSolver.MUMPS }; break; case LinearSolverCodes.classic_pardiso: templinearSolve = new DirectSolver() { WhichSolver = DirectSolver._whichSolver.PARDISO }; break; case LinearSolverCodes.exp_schwarz_directcoarse_overlap: if (Control.NoOfMultigridLevels < 2) { throw new ApplicationException("At least 2 Multigridlevels are required"); } templinearSolve = new Schwarz() { m_BlockingStrategy = new Schwarz.METISBlockingStrategy() { NoOfPartsPerProcess = 1, }, Overlap = 1, CoarseSolver = DetermineMGSquence(Control.NoOfMultigridLevels - 2) }; break; case LinearSolverCodes.exp_schwarz_directcoarse: if (Control.NoOfMultigridLevels < 2) { throw new ApplicationException("At least 2 Multigridlevels are required"); } templinearSolve = new Schwarz() { m_BlockingStrategy = new Schwarz.METISBlockingStrategy() { NoOfPartsPerProcess = 1, }, Overlap = 0, CoarseSolver = DetermineMGSquence(Control.NoOfMultigridLevels - 2) }; break; case LinearSolverCodes.exp_schwarz_Kcycle_directcoarse: if (Control.NoOfMultigridLevels < 2) { throw new ApplicationException("At least 2 Multigridlevels are required"); } templinearSolve = new Schwarz() { m_BlockingStrategy = new Schwarz.MultigridBlocks() { Depth = Control.NoOfMultigridLevels - 1 }, Overlap = 0, CoarseSolver = DetermineMGSquence(Control.NoOfMultigridLevels - 2) }; break; case LinearSolverCodes.exp_schwarz_Kcycle_directcoarse_overlap: if (Control.NoOfMultigridLevels < 2) { throw new ApplicationException("At least 2 Multigridlevels are required"); } templinearSolve = new Schwarz() { m_BlockingStrategy = new Schwarz.MultigridBlocks() { Depth = Control.NoOfMultigridLevels - 1 }, Overlap = 1, CoarseSolver = DetermineMGSquence(Control.NoOfMultigridLevels - 2) }; break; case LinearSolverCodes.exp_softgmres: templinearSolve = new SoftGMRES() { MaxKrylovDim = Timestepper.Config_MaxKrylovDim, m_Tolerance = Timestepper.Config_SolverConvergenceCriterion, }; break; case LinearSolverCodes.exp_softgmres_schwarz_Kcycle_directcoarse_overlap: templinearSolve = new SoftGMRES() { MaxKrylovDim = Timestepper.Config_MaxKrylovDim, m_Tolerance = Timestepper.Config_SolverConvergenceCriterion, Precond = new Schwarz() { m_BlockingStrategy = new Schwarz.MultigridBlocks() { Depth = Control.NoOfMultigridLevels - 1 }, Overlap = 1, CoarseSolver = DetermineMGSquence(Control.NoOfMultigridLevels - 2) }, }; break; case LinearSolverCodes.exp_softgmres_schwarz_directcoarse_overlap: if (Control.NoOfMultigridLevels < 2) { throw new ApplicationException("At least 2 Multigridlevels are required"); } templinearSolve = new SoftGMRES() { MaxKrylovDim = Timestepper.Config_MaxKrylovDim, m_Tolerance = Timestepper.Config_SolverConvergenceCriterion, Precond = new Schwarz() { m_BlockingStrategy = new Schwarz.METISBlockingStrategy() { NoOfPartsPerProcess = 1, }, Overlap = 1, CoarseSolver = DetermineMGSquence(Control.NoOfMultigridLevels - 2) }, }; break; case LinearSolverCodes.exp_multigrid: if (Control.NoOfMultigridLevels < 2) { throw new ApplicationException("At least 2 Multigridlevels are required"); } templinearSolve = new ILU() { }; break; case LinearSolverCodes.exp_ILU: templinearSolve = new ILU() { }; break; case LinearSolverCodes.exp_Schur: templinearSolve = new SchurPrecond() { SchurOpt = SchurPrecond.SchurOptions.decoupledApprox }; break; case LinearSolverCodes.exp_Simple: templinearSolve = new SchurPrecond() { SchurOpt = SchurPrecond.SchurOptions.SIMPLE }; break; case LinearSolverCodes.exp_AS_1000: if (Timestepper.MultigridSequence[0].SpatialDimension == 3) //3D --> 212940DoF { templinearSolve = new Schwarz() { m_BlockingStrategy = new Schwarz.METISBlockingStrategy() { //noofparts = 76, NoOfPartsPerProcess = 213, // Warum 76 }, CoarseSolver = new DirectSolver() { WhichSolver = DirectSolver._whichSolver.MUMPS //PARDISO }, Overlap = 1 }; } else //2D --> 75088DoF { templinearSolve = new Schwarz() { m_BlockingStrategy = new Schwarz.METISBlockingStrategy() { //noofparts = 213, NoOfPartsPerProcess = 213, }, CoarseSolver = new DirectSolver() { WhichSolver = DirectSolver._whichSolver.MUMPS //PARDISO }, Overlap = 1 }; } break; case LinearSolverCodes.exp_AS_5000: if (Timestepper.MultigridSequence[0].SpatialDimension == 3) //3D --> 212940DoF { templinearSolve = new Schwarz() { m_BlockingStrategy = new Schwarz.METISBlockingStrategy() { //noofparts = 43, NoOfPartsPerProcess = 43, }, CoarseSolver = new DirectSolver() { WhichSolver = DirectSolver._whichSolver.MUMPS //PARDISO }, Overlap = 1 }; } else //2D --> 75088DoF { templinearSolve = new Schwarz() { m_BlockingStrategy = new Schwarz.METISBlockingStrategy() { //noofparts = 16, NoOfPartsPerProcess = 43, }, CoarseSolver = new DirectSolver() { WhichSolver = DirectSolver._whichSolver.MUMPS //PARDISO }, Overlap = 1 }; } break; case LinearSolverCodes.exp_AS_10000: if (Timestepper.MultigridSequence[0].SpatialDimension == 3) //3D --> 212940DoF { templinearSolve = new Schwarz() { m_BlockingStrategy = new Schwarz.METISBlockingStrategy() { //noofparts = 22, NoOfPartsPerProcess = 22, }, CoarseSolver = new DirectSolver() { WhichSolver = DirectSolver._whichSolver.MUMPS //PARDISO }, Overlap = 1 }; } else //2D --> 75088DoF { templinearSolve = new Schwarz() { m_BlockingStrategy = new Schwarz.METISBlockingStrategy() { //noofparts = 8, NoOfPartsPerProcess = 22, // }, CoarseSolver = new DirectSolver() { WhichSolver = DirectSolver._whichSolver.MUMPS //PARDISO }, Overlap = 1 }; } break; case LinearSolverCodes.exp_AS_MG: templinearSolve = new Schwarz() { m_BlockingStrategy = new Schwarz.MultigridBlocks() { //depth = asdepth, Depth = 2, }, CoarseSolver = new DirectSolver() { WhichSolver = DirectSolver._whichSolver.MUMPS //PARDISO }, Overlap = 1 }; break; case LinearSolverCodes.exp_localPrec: templinearSolve = new LocalizedOperatorPrec() { m_dt = Control.GetFixedTimestep(), m_muA = Control.PhysicalParameters.mu_A, }; break; default: throw new NotImplementedException("Linear solver option not available"); } // Set nonlinear Solver switch (Control.NonlinearSolve) { case NonlinearSolverCodes.NewtonGMRES: Timestepper.Config_NonlinearSolver = NonlinearSolverMethod.NewtonGMRES; Timestepper.Config_linearSolver = templinearSolve; break; case NonlinearSolverCodes.Picard: Timestepper.Config_NonlinearSolver = NonlinearSolverMethod.Picard; Timestepper.Config_linearSolver = templinearSolve; break; case NonlinearSolverCodes.Newton: Timestepper.Config_NonlinearSolver = NonlinearSolverMethod.Newton; Timestepper.Config_linearSolver = templinearSolve; break; case NonlinearSolverCodes.PicardGMRES: Timestepper.Config_NonlinearSolver = NonlinearSolverMethod.Picard; Timestepper.Config_linearSolver = new SoftGMRES() { MaxKrylovDim = Timestepper.Config_MaxKrylovDim, m_Tolerance = Timestepper.Config_SolverConvergenceCriterion, Precond = templinearSolve, m_MaxIterations = Timestepper.Config_MaxIterations, }; break; default: throw new NotImplementedException("Nonlinear solver option not available"); } }