/// <summary> /// Automatic choice of linear solver depending on problem size, immersed boundary, polynomial degree, etc. /// </summary> static void AutomaticChoice(IBM_Control Control, XdgBDFTimestepping Timestepper) { throw new NotImplementedException("Option currently not available"); // Detecting MPI Size MPI.Wrappers.csMPI.Raw.Comm_Size(MPI.Wrappers.csMPI.Raw._COMM.WORLD, out int size); //Timestepper.MultigridSequence[0]. // Spatial Dimension //Timestepper. // Wenn Gesamtproblem in 2D < 100000 DoFs -> Direct Solver // Wenn Gesamtproblem in 3D < 10000 DoFs -> Direct Solver // Block Solve 3D ca. 6000 DoFs per Process -> Adjust Blocks per Process // Coarse Solve ca. 5000 bis 10000 DoFs. -> Adjust Multigrid Levels }
protected override void CreateEquationsAndSolvers(GridUpdateDataVaultBase L) { int quadorder = this.u.Basis.Degree * 2 + 1; Op = new XSpatialOperator(1, 0, 1, (A, B, C) => quadorder, "u", "c1"); var blkFlux = new DxFlux(this.LsTrk, alpha_A, alpha_B); Op.EquationComponents["c1"].Add(blkFlux); // Flux in Bulk Phase; Op.EquationComponents["c1"].Add(new LevSetFlx(this.LsTrk, alpha_A, alpha_B)); // flux am lev-set 0 Op.Commit(); if (L == null) { TimeIntegration = new XdgBDFTimestepping( new DGField[] { u }, new DGField[] { uResidual }, base.LsTrk, true, DelComputeOperatorMatrix, null, DelUpdateLevelset, 3, // BDF3 //-1, // Crank-Nicolson //0, // Explicit Euler LevelSetHandling.LieSplitting, MassMatrixShapeandDependence.IsTimeDependent, SpatialOperatorType.LinearTimeDependent, MassScale, MultigridOperatorConfig, this.MultigridSequence, this.LsTrk.SpeciesIdS.ToArray(), quadorder, this.THRESHOLD, true, this.Control.NonLinearSolver, this.Control.LinearSolver); } else { Debug.Assert(object.ReferenceEquals(this.MultigridSequence[0].ParentGrid, this.GridData)); TimeIntegration.DataRestoreAfterBalancing(L, new DGField[] { u }, new DGField[] { uResidual }, base.LsTrk, this.MultigridSequence); } }
protected override void CreateEquationsAndSolvers(LoadbalData L) { Op = new XSpatialOperator(1, 0, 1, QuadOrderFunc.SumOfMaxDegrees(RoundUp: true), "u", "c1"); var blkFlux = new DxFlux(this.LsTrk, Control.alpha_A, Control.alpha_B); Op.EquationComponents["c1"].Add(blkFlux); // Flux in Bulk Phase; Op.EquationComponents["c1"].Add(new LevSetFlx(this.LsTrk, Control.alpha_A, Control.alpha_B)); // flux am lev-set 0 Op.OnIntegratingBulk += blkFlux.NowIntegratingBulk; Op.Commit(); if (L == null) { TimeIntegration = new XdgBDFTimestepping( new DGField[] { u }, new DGField[] { uResidual }, base.LsTrk, true, DelComputeOperatorMatrix, DelUpdateLevelset, DelUpdateCutCellMetrics, 3, // BDF3 //-1, // Crank-Nicolson //0, // Explicit Euler LevelSetHandling.LieSplitting, MassMatrixShapeandDependence.IsTimeDependent, SpatialOperatorType.LinearTimeDependent, MassScale, MultigridOperatorConfig, this.MultigridSequence, this.THRESHOLD, true); } else { Debug.Assert(object.ReferenceEquals(this.MultigridSequence[0].ParentGrid, this.GridData)); TimeIntegration.DataRestoreAfterBalancing(L, new DGField[] { u }, new DGField[] { uResidual }, base.LsTrk, this.MultigridSequence); } }
protected override void CreateEquationsAndSolvers(GridUpdateDataVaultBase L) { if (Operator != null) { return; } // create operator // --------------- Func <double[], double, double> S; switch (this.Control.InterfaceMode) { case InterfaceMode.MovingInterface: S = this.Control.S; break; case InterfaceMode.Splitting: S = (X, t) => 0.0; break; default: throw new NotImplementedException(); } int quadOrder; if (this.Control.Eq == Equation.ScalarTransport) { quadOrder = this.LinearQuadratureDegree; Func <double[], double, double>[] uBnd = new Func <double[], double, double> [this.Grid.EdgeTagNames.Keys.Max() + 1]; for (int iEdgeTag = 1; iEdgeTag < uBnd.Length; iEdgeTag++) { string nameEdgeTag; if (this.Grid.EdgeTagNames.TryGetValue((byte)iEdgeTag, out nameEdgeTag)) { if (!this.Control.BoundaryValues[nameEdgeTag].Evaluators.TryGetValue("u", out uBnd[iEdgeTag])) { uBnd[iEdgeTag] = (X, t) => 0.0; } } } Operator = new XSpatialOperator(1, 2, 1, (A, B, C) => quadOrder, "u", "Vx", "Vy", "Cod1"); Operator.EquationComponents["Cod1"].Add(new TranportFlux_Bulk() { Inflow = uBnd }); Operator.EquationComponents["Cod1"].Add(new TransportFlux_Interface(this.LsTrk, S)); Operator.Commit(); } else if (this.Control.Eq == Equation.HeatEq) { quadOrder = this.LinearQuadratureDegree; Operator = new XSpatialOperator(1, 0, 1, (A, B, C) => quadOrder, "u", "Cod1"); var bulkFlx = new HeatFlux_Bulk() { m_muA = this.Control.muA, m_muB = this.Control.muB, m_rhsA = this.Control.rhsA, m_rhsB = this.Control.rhsB }; var intfFlx = new HeatFlux_Interface(this.LsTrk, S) { m_muA = this.Control.muA, m_muB = this.Control.muB }; Operator.EquationComponents["Cod1"].Add(bulkFlx); Operator.EquationComponents["Cod1"].Add(intfFlx); Operator.Commit(); } else if (this.Control.Eq == Equation.Burgers) { quadOrder = this.NonlinearQuadratureDegree; Operator = new XSpatialOperator(1, 1, 1, (A, B, C) => quadOrder, "u", "u0", "Cod1"); Operator.EquationComponents["Cod1"].Add(new BurgersFlux_Bulk() { Direction = this.Control.BurgersDirection, Inflow = this.Control.u_Ex }); Operator.EquationComponents["Cod1"].Add(new BurgersFlux_Interface(this.LsTrk, S, this.Control.BurgersDirection)); Operator.Commit(); } else { throw new NotImplementedException(); } // create timestepper // ------------------ LevelSetHandling lsh; switch (this.Control.InterfaceMode) { case InterfaceMode.MovingInterface: lsh = LevelSetHandling.Coupled_Once; break; case InterfaceMode.Splitting: lsh = LevelSetHandling.LieSplitting; break; default: throw new NotImplementedException(); } RungeKuttaScheme rksch = null; int bdfOrder = -1000; if (this.Control.TimeSteppingScheme == TimeSteppingScheme.CrankNicolson) { bdfOrder = -1; } else if (this.Control.TimeSteppingScheme == TimeSteppingScheme.ExplicitEuler) { bdfOrder = 0; } else if (this.Control.TimeSteppingScheme == TimeSteppingScheme.ImplicitEuler) { bdfOrder = 1; } else if (this.Control.TimeSteppingScheme.ToString().StartsWith("BDF")) { bdfOrder = Convert.ToInt32(this.Control.TimeSteppingScheme.ToString().Substring(3)); } else if (this.Control.TimeSteppingScheme == TimeSteppingScheme.RK1) { rksch = RungeKuttaScheme.ExplicitEuler; } else if (this.Control.TimeSteppingScheme == TimeSteppingScheme.RK1u1) { rksch = RungeKuttaScheme.ExplicitEuler2; } else if (this.Control.TimeSteppingScheme == TimeSteppingScheme.RK2) { rksch = RungeKuttaScheme.Heun2; } else if (this.Control.TimeSteppingScheme == TimeSteppingScheme.RK3) { rksch = RungeKuttaScheme.TVD3; } else if (this.Control.TimeSteppingScheme == TimeSteppingScheme.RK4) { rksch = RungeKuttaScheme.RungeKutta1901; } else if (this.Control.TimeSteppingScheme == TimeSteppingScheme.RK_ImplicitEuler) { rksch = RungeKuttaScheme.ImplicitEuler; } else if (this.Control.TimeSteppingScheme == TimeSteppingScheme.RK_CrankNic) { rksch = RungeKuttaScheme.CrankNicolson; } else if (this.Control.TimeSteppingScheme == TimeSteppingScheme.RK_IMEX3) { rksch = RungeKuttaScheme.IMEX3; } else { throw new NotImplementedException(); } if (bdfOrder > -1000) { m_BDF_Timestepper = new XdgBDFTimestepping(new DGField[] { this.u }, new DGField[] { this.Residual }, LsTrk, true, DelComputeOperatorMatrix, DelUpdateLevelset, bdfOrder, lsh, MassMatrixShapeandDependence.IsTimeDependent, SpatialOperatorType.LinearTimeDependent, MassScale, null, base.MultigridSequence, this.LsTrk.SpeciesIdS.ToArray(), quadOrder, this.Control.AgglomerationThreshold, false); } else { m_RK_Timestepper = new XdgRKTimestepping(new DGField[] { this.u }, new DGField[] { this.Residual }, LsTrk, DelComputeOperatorMatrix, DelUpdateLevelset, rksch, lsh, MassMatrixShapeandDependence.IsTimeDependent, SpatialOperatorType.LinearTimeDependent, MassScale, null, base.MultigridSequence, this.LsTrk.SpeciesIdS.ToArray(), quadOrder, this.Control.AgglomerationThreshold, false); } }
/// <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 nonlinear Solver switch (Control.NonlinearSolve) { case NonlinearSolverCodes.NewtonGMRES: Timestepper.Config_NonlinearSolver = NonlinearSolverMethod.Newton; break; case NonlinearSolverCodes.Picard: Timestepper.Config_NonlinearSolver = NonlinearSolverMethod.Picard; break; default: throw new NotImplementedException("Nonlinear solver option not available"); } switch (Control.LinearSolve) { case LinearSolverCodes.automatic: AutomaticChoice(Control, Timestepper); break; case LinearSolverCodes.classic_mumps: Timestepper.Config_linearSolver = new DirectSolver() { WhichSolver = DirectSolver._whichSolver.MUMPS }; break; case LinearSolverCodes.classic_pardiso: Timestepper.Config_linearSolver = 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"); } Timestepper.Config_linearSolver = 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"); } Timestepper.Config_linearSolver = 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"); } Timestepper.Config_linearSolver = 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"); } Timestepper.Config_linearSolver = new Schwarz() { m_BlockingStrategy = new Schwarz.MultigridBlocks() { Depth = Control.NoOfMultigridLevels - 1 }, Overlap = 1, CoarseSolver = DetermineMGSquence(Control.NoOfMultigridLevels - 2) }; break; case LinearSolverCodes.exp_softgmres: Timestepper.Config_linearSolver = new SoftGMRES() { MaxKrylovDim = Timestepper.Config_MaxKrylovDim, }; break; case LinearSolverCodes.exp_softgmres_schwarz_Kcycle_directcoarse_overlap: Timestepper.Config_linearSolver = new SoftGMRES() { MaxKrylovDim = Timestepper.Config_MaxKrylovDim, Precond = new Schwarz() { m_BlockingStrategy = new Schwarz.MultigridBlocks() { Depth = Control.NoOfMultigridLevels - 1 }, Overlap = 1, CoarseSolver = DetermineMGSquence(Control.NoOfMultigridLevels - 2) }, }; break; default: throw new NotImplementedException("Linear solver option not available"); } }
/* * /// <summary> * /// Legacy-Constructor for user-specified <see cref="DelComputeOperatorMatrix"/> * /// </summary> * public XdgTimestepping( * DelComputeOperatorMatrix userComputeOperatorMatrix, * IEnumerable<DGField> Fields, * IEnumerable<DGField> IterationResiduals, * TimeSteppingScheme __Scheme, * DelUpdateLevelset _UpdateLevelset, * LevelSetHandling _LevelSetHandling, * MultigridOperator.ChangeOfBasisConfig[][] _MultigridOperatorConfig, * AggregationGridData[] _MultigridSequence, * double _AgglomerationThreshold, * LinearSolverConfig LinearSolver, NonLinearSolverConfig NonLinearSolver) // * { * this.Scheme = __Scheme; * this.XdgOperator = op; * * this.Parameters = op.InvokeParameterFactory(Fields); * * * foreach (var f in Fields.Cat(IterationResiduals).Cat(Parameters)) { * if (f != null && f is XDGField xf) { * if (LsTrk == null) { * LsTrk = xf.Basis.Tracker; * } else { * if (!object.ReferenceEquals(LsTrk, xf.Basis.Tracker)) * throw new ArgumentException(); * } * } * } * if (LsTrk == null) * throw new ArgumentException("unable to get Level Set Tracker reference"); * * bool UseX = Fields.Any(f => f is XDGField) || IterationResiduals.Any(f => f is XDGField); * * ConstructorCommon(op, UseX, * Fields, this.Parameters, IterationResiduals, * myDelComputeXOperatorMatrix, * _UpdateLevelset, * _LevelSetHandling, * _MultigridOperatorConfig, * _MultigridSequence, * _AgglomerationThreshold, * LinearSolver, NonLinearSolver); * * } */ private void ConstructorCommon( ISpatialOperator op, bool UseX, IEnumerable <DGField> Fields, IEnumerable <DGField> __Parameters, IEnumerable <DGField> IterationResiduals, SpeciesId[] spcToCompute, DelUpdateLevelset _UpdateLevelset, LevelSetHandling _LevelSetHandling, MultigridOperator.ChangeOfBasisConfig[][] _MultigridOperatorConfig, AggregationGridData[] _MultigridSequence, double _AgglomerationThreshold, LinearSolverConfig LinearSolver, NonLinearSolverConfig NonLinearSolver) // { RungeKuttaScheme rksch; int bdfOrder; DecodeScheme(this.Scheme, out rksch, out bdfOrder); SpatialOperatorType _SpatialOperatorType = SpatialOperatorType.Nonlinear; int quadOrder = op.QuadOrderFunction( Fields.Select(f => f.Basis.Degree).ToArray(), Parameters.Select(f => f != null ? f.Basis.Degree : 0).ToArray(), IterationResiduals.Select(f => f.Basis.Degree).ToArray()); // default solvers // =============== if (LinearSolver == null) { LinearSolver = new LinearSolverConfig() { SolverCode = LinearSolverCode.automatic }; } if (NonLinearSolver == null) { NonLinearSolver = new NonLinearSolverConfig() { SolverCode = NonLinearSolverCode.Newton }; } // default Multi-Grid // ================== if (_MultigridSequence == null) { _MultigridSequence = new[] { CoarseningAlgorithms.ZeroAggregation(this.GridDat) }; } // default level-set treatment // =========================== if (_UpdateLevelset == null) { _UpdateLevelset = this.UpdateLevelsetWithNothing; if (_LevelSetHandling != LevelSetHandling.None) { throw new ArgumentException($"If level-set handling is set to {_LevelSetHandling} (anything but {LevelSetHandling.None}) an updating routine must be specified."); } } // default multigrid operator config // ================================= if (_MultigridOperatorConfig == null) { int NoOfVar = Fields.Count(); _MultigridOperatorConfig = new MultigridOperator.ChangeOfBasisConfig[0][]; _MultigridOperatorConfig[0] = new MultigridOperator.ChangeOfBasisConfig[NoOfVar]; for (int iVar = 0; iVar < NoOfVar; iVar++) { _MultigridOperatorConfig[0][iVar] = new MultigridOperator.ChangeOfBasisConfig() { DegreeS = new int[] { Fields.ElementAt(iVar).Basis.Degree }, mode = MultigridOperator.Mode.Eye, VarIndex = new int[] { iVar } }; } } // finally, create timestepper // =========================== if (bdfOrder > -1000) { m_BDF_Timestepper = new XdgBDFTimestepping(Fields, __Parameters, IterationResiduals, LsTrk, true, this.ComputeOperatorMatrix, op, _UpdateLevelset, bdfOrder, _LevelSetHandling, MassMatrixShapeandDependence.IsTimeDependent, _SpatialOperatorType, _MultigridOperatorConfig, _MultigridSequence, spcToCompute, quadOrder, _AgglomerationThreshold, UseX, NonLinearSolver, LinearSolver); m_BDF_Timestepper.Config_AgglomerationThreshold = _AgglomerationThreshold; } else { m_RK_Timestepper = new XdgRKTimestepping(Fields.ToArray(), __Parameters, IterationResiduals.ToArray(), LsTrk, this.ComputeOperatorMatrix, op, _UpdateLevelset, rksch, _LevelSetHandling, MassMatrixShapeandDependence.IsTimeDependent, _SpatialOperatorType, _MultigridOperatorConfig, _MultigridSequence, spcToCompute, quadOrder, _AgglomerationThreshold, UseX, NonLinearSolver, LinearSolver); m_RK_Timestepper.Config_AgglomerationThreshold = _AgglomerationThreshold; } }
/// <summary> /// Automatic choice of linear solver depending on problem size, immersed boundary, polynomial degree, etc. /// </summary> static ISolverSmootherTemplate AutomaticChoice(IBM_Control Control, XdgBDFTimestepping Timestepper) { //int pV = Control.FieldOptions["VelocityX"].Degree; int pP = Control.FieldOptions["Pressure"].Degree; int pV = pP + 1; // Detecting variables for solver determination var D = Timestepper.MultigridSequence[0].SpatialDimension; var cellsLoc = Timestepper.MultigridSequence[0].CellPartitioning.LocalLength; var cellsGlo = Timestepper.MultigridSequence[0].CellPartitioning.TotalLength; ISolverSmootherTemplate tempsolve = null; var size = Timestepper.MultigridSequence[0].CellPartitioning.MpiSize; // !!!!!!!!!!!UNTERSCHEIDUNG OB PICARD ODER NEWTON!!!!!!!!!!!! if (Timestepper.Config_NonlinearSolver == NonlinearSolverMethod.NewtonGMRES) { // Spatial Dimension switch (D) { case 1: break; throw new NotImplementedException("Currently not implemented for " + D + " Dimensions"); //break; case 2: throw new NotImplementedException("Currently not implemented for " + D + " Dimensions"); //break; case 3: var dofsPerCell3D = (3 * (pV * pV * pV + 6 * pV * pV + 11 * pV + 6) / 6 + 1 * (pP * pP * pP + 6 * pP * pP + 11 * pP + 6) / 6); var dofsLoc = dofsPerCell3D * cellsLoc; var dofsGlo = dofsPerCell3D * cellsGlo; var PPP = (int)Math.Ceiling(dofsLoc / 6500.0); Console.WriteLine("Analysing the problem yields " + PPP + " parts per process."); if (dofsGlo > 10000) { if (Control.NoOfMultigridLevels < 2) { throw new ApplicationException("At least 2 Multigridlevels are required"); } Timestepper.Config_linearSolver = new Schwarz() { m_BlockingStrategy = new Schwarz.METISBlockingStrategy() { NoOfPartsPerProcess = PPP, }, Overlap = 1, CoarseSolver = DetermineMGSquence(Control.NoOfMultigridLevels - 2) }; } else { Timestepper.Config_linearSolver = new DirectSolver() { WhichSolver = DirectSolver._whichSolver.MUMPS }; } break; default: throw new NotImplementedException("Currently not implemented for " + D + " Dimensions"); } } else { // Spatial Dimension switch (D) { case 1: break; throw new NotImplementedException("Currently not implemented for " + D + " Dimensions"); //break; case 2: throw new NotImplementedException("Currently not implemented for " + D + " Dimensions"); //break; case 3: var dofsPerCell3D = (3 * (pV * pV * pV + 6 * pV * pV + 11 * pV + 6) / 6 + 1 * (pP * pP * pP + 6 * pP * pP + 11 * pP + 6) / 6); var dofsLoc = dofsPerCell3D * cellsLoc; var dofsGlo = dofsPerCell3D * cellsGlo; if (dofsGlo > 10000) { if (Control.NoOfMultigridLevels < 2) { throw new ApplicationException("At least 2 Multigridlevels are required"); } tempsolve = new SoftGMRES() { MaxKrylovDim = Timestepper.Config_MaxKrylovDim, m_Tolerance = Timestepper.Config_SolverConvergenceCriterion, Precond = new Schwarz() { m_BlockingStrategy = new Schwarz.SimpleBlocking() { NoOfPartsPerProcess = (int)Math.Ceiling(dofsLoc / 6500.0), }, Overlap = 1, CoarseSolver = DetermineMGSquence(Control.NoOfMultigridLevels - 2) }, }; } else { tempsolve = new DirectSolver() { WhichSolver = DirectSolver._whichSolver.MUMPS }; } break; default: throw new NotImplementedException("Currently not implemented for " + D + " Dimensions"); } } return(tempsolve); //Timestepper. // Wenn Gesamtproblem in 2D < 100000 DoFs -> Direct Solver // Wenn Gesamtproblem in 3D < 10000 DoFs -> Direct Solver // Block Solve 3D ca. 6000 DoFs per Process -> Adjust Blocks per Process // Coarse Solve ca. 5000 bis 10000 DoFs. -> Adjust Multigrid Levels }
/// <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"); } }