示例#1
0
        public static void TestNonLinearSolverConfigurations()
        {
            //Arrange --- set configs
            var ACS = new AppControlSolver();
            NonLinearSolverConfig nlconfig = ACS.NonLinearSolver;
            LinearSolverConfig    lconfig  = ACS.LinearSolver;

            lconfig.verbose             = true;
            lconfig.NoOfMultigridLevels = 3;
            lconfig.TargetBlockSize     = 10;
            nlconfig.verbose            = true;
            var SF = new SolverFactory(nlconfig, lconfig);

            //Arrange --- get test multigrid operator stuff
            AggregationGridData[] seq;
            var MGO             = Utils.CreateTestMGOperator(out seq, Resolution: 10);
            var map             = MGO.Mapping;
            var changeofbasisis = Utils.GetAllMGConfig(MGO);
            var agggridbasisis  = Utils.GetAllAggGridBasis(MGO);

            //Arrange --- get nonlinear codes available
            var             nonlincodes = (NonLinearSolverCode[])Enum.GetValues(typeof(NonLinearSolverCode));
            NonlinearSolver NLsolver    = null;

            //Arrange --- get test linear Solver to set in NLsolver
            ISolverSmootherTemplate LinSolver = null;

            LinearSolverCode[] LinTestcandidates = { LinearSolverCode.classic_pardiso, LinearSolverCode.exp_gmres_levelpmg }; // in order to test the GMRES variants of the NL solver

            //Act and Assert
            foreach (var lincode in LinTestcandidates)
            {
                lconfig.SolverCode = lincode;
                TestDelegate nldlg = () => SF.GenerateNonLin(out NLsolver, out LinSolver, null, agggridbasisis, changeofbasisis, seq);
                SF.Clear();
                foreach (NonLinearSolverCode nlcode in nonlincodes)
                {
                    nlconfig.SolverCode = nlcode;
                    if (nlconfig.SolverCode == NonLinearSolverCode.selfmade)
                    {
                        SF.Selfmade_nonlinsolver = new Newton(null, agggridbasisis, changeofbasisis);
                    }
                    Assert.DoesNotThrow(nldlg, "", null);
                    Assert.IsNotNull(NLsolver);
                }
                Console.WriteLine("====");
            }
        }
示例#2
0
        public void UseSolver <T1, T2>(ISolverSmootherTemplate solver, T1 INOUT_X, T2 IN_RHS, bool UseGuess = true)
            where T1 : IList <double>
            where T2 : IList <double>
        {
            if (this.LevelIndex != 0)
            {
                throw new NotSupportedException("Not Inteded to be called on any multi-grid level but the finest one.");
            }

            int I = this.Mapping.ProblemMapping.LocalLength;

            if (INOUT_X.Count != I)
            {
                throw new ArgumentException("Vector length mismatch.", "INOUT_X");
            }
            if (IN_RHS.Count != I)
            {
                throw new ArgumentException("Vector length mismatch.", "IN_RHS");
            }

            if (this.FinerLevel != null)
            {
                throw new NotSupportedException("This method may only be called on the top level.");
            }

            //if(this.Mapping.AggGrid.NoOfAggregateCells != this.Mapping.ProblemMapping.GridDat.Cells.NoOfCells)
            //    throw new ArgumentException();
            //int J = this.Mapping.AggGrid.NoOfAggregateCells;


            int L = this.Mapping.LocalLength;

            double[] X = new double[L];
            double[] B = new double[L];
            this.TransformRhsInto(IN_RHS, B);
            if (UseGuess)
            {
                this.TransformSolInto(INOUT_X, X);
            }

            solver.ResetStat();
            solver.Solve(X, B);

            this.TransformSolFrom(INOUT_X, X);
        }
示例#3
0
        /// <summary>
        /// Returns either a solver for the Navier-Stokes or the Stokes system.
        /// E.g. for testing purposes, one might also use a nonlinear solver on a Stokes system.
        /// </summary>
        protected virtual string GetSolver(out NonlinearSolver nonlinSolver, out ISolverSmootherTemplate linearSolver)
        {
            nonlinSolver = null;
            linearSolver = null;

            if (Config_SpatialOperatorType != SpatialOperatorType.Nonlinear)
            {
                m_nonlinconfig.SolverCode = BoSSS.Solution.Control.NonLinearSolverCode.Picard;
            }

            XdgSolverFactory.GenerateNonLin(out nonlinSolver, out linearSolver, this.AssembleMatrixCallback, this.MultigridBasis, Config_MultigridOperator, MultigridSequence);

            string ls_strg  = String.Format("{0}", m_linearconfig.SolverCode);
            string nls_strg = String.Format("{0}", m_nonlinconfig.SolverCode);

            if ((this.Config_LevelSetHandling == LevelSetHandling.Coupled_Iterative) && (nonlinSolver.Equals(typeof(FixpointIterator))))
            {
                ((FixpointIterator)nonlinSolver).CoupledIteration_Converged = LevelSetConvergenceReached;
            }

            // set callback for diagnostic output
            // ----------------------------------
            if (nonlinSolver != null)
            {
                nonlinSolver.IterationCallback += this.LogResis;
                if (linearSolver != null && linearSolver is ISolverWithCallback)
                {
                    //((ISolverWithCallback)linearSolver).IterationCallback = this.MiniLogResi;
                }
            }
            else
            {
                if (linearSolver != null && linearSolver is ISolverWithCallback)
                {
                    ((ISolverWithCallback)linearSolver).IterationCallback = this.LogResis;
                }
            }

            return(String.Format("nonlinear Solver: {0}, linear Solver: {1}", nls_strg, ls_strg));
        }
示例#4
0
        public static void TestLinearSolverConfigurations()
        {
            //Arrange --- configs
            var ACS = new AppControlSolver();
            LinearSolverConfig    lconfig  = ACS.LinearSolver;
            NonLinearSolverConfig nlconfig = ACS.NonLinearSolver; // is not of interest in this test, but we have to set this ...

            lconfig.verbose             = true;
            lconfig.NoOfMultigridLevels = 3;
            lconfig.TargetBlockSize     = 10;
            var SF = new SolverFactory(nlconfig, lconfig);

            //Arrange --- Multigrid stuff
            AggregationGridData[] seq;
            var MGO             = Utils.CreateTestMGOperator(out seq, Resolution: 10);
            var changeofbasisis = Utils.GetAllMGConfig(MGO);
            var agggridbasisis  = Utils.GetAllAggGridBasis(MGO);

            //Arrange --- get available lincodes
            var lincodes = (LinearSolverCode[])Enum.GetValues(typeof(LinearSolverCode));
            ISolverSmootherTemplate LinSolver = null;
            TestDelegate            lindlg    = () => SF.GenerateLinear(out LinSolver, agggridbasisis, changeofbasisis);

            //Act and Assert
            foreach (LinearSolverCode code in lincodes)
            {
                SF.Clear();
                lconfig.SolverCode = code;
                if (code == LinearSolverCode.selfmade)
                {
                    SF.Selfmade_linsolver = new DirectSolver()
                    {
                        WhichSolver = DirectSolver._whichSolver.PARDISO
                    }
                }
                ;
                Assert.DoesNotThrow(lindlg, "", null);
                Assert.IsNotNull(LinSolver);
            }
        }
示例#5
0
        /// <summary>
        /// Returns either a solver for the Navier-Stokes or the Stokes system.
        /// E.g. for testing purposes, one might also use a nonlinear solver on a Stokes system.
        /// </summary>
        /// <param name="nonlinSolver"></param>
        /// <param name="linearSolver"></param>
        protected virtual string GetSolver(out NonlinearSolver nonlinSolver, out ISolverSmootherTemplate linearSolver)
        {
            nonlinSolver = null;
            linearSolver = null;

            string solverDescription = ""; // this.Control.option_solver;

            //solverDescription = string.Format("; No. of cells: {0}, p = {1}/{2}; MaxKrylovDim {3}, MaxIter {4};",
            //    this.GridData.Partitioning.TotalLength,
            //    this.CurrentVel[0].Basis.Degree,
            //    this.Pressure.Basis.Degree,
            //    MaxKrylovDim,
            //    MaxIterations);


            // define solver
            // -------------


            if (this.RequiresNonlinearSolver)
            {
                // +++++++++++++++++++++++++++++++++++++++++++++
                // the nonlinear solvers:
                // +++++++++++++++++++++++++++++++++++++++++++++

                switch (Config_NonlinearSolver)
                {
                case NonlinearSolverMethod.Picard:

                    nonlinSolver = new FixpointIterator(
                        this.AssembleMatrixCallback,
                        this.MultigridBasis,
                        this.Config_MultigridOperator)
                    {
                        MaxIter        = Config_MaxIterations,
                        MinIter        = Config_MinIterations,
                        m_LinearSolver = Config_linearSolver,
                        m_SessionPath  = SessionPath,
                        ConvCrit       = Config_SolverConvergenceCriterion,
                        UnderRelax     = Config_UnderRelax,
                    };

                    if (this.Config_LevelSetHandling == LevelSetHandling.Coupled_Iterative)
                    {
                        ((FixpointIterator)nonlinSolver).CoupledIteration_Converged = LevelSetConvergenceReached;
                    }

                    break;

                case NonlinearSolverMethod.Newton:

                    nonlinSolver = new Newton(
                        this.AssembleMatrixCallback,
                        this.MultigridBasis,
                        this.Config_MultigridOperator)
                    {
                        maxKrylovDim  = Config_MaxKrylovDim,
                        MaxIter       = Config_MaxIterations,
                        MinIter       = Config_MinIterations,
                        ApproxJac     = Newton.ApproxInvJacobianOptions.DirectSolver,
                        Precond       = Config_linearSolver,
                        GMRESConvCrit = Config_SolverConvergenceCriterion,
                        ConvCrit      = Config_SolverConvergenceCriterion,
                        m_SessionPath = SessionPath,
                    };
                    break;

                case NonlinearSolverMethod.NewtonGMRES:

                    nonlinSolver = new Newton(
                        this.AssembleMatrixCallback,
                        this.MultigridBasis,
                        this.Config_MultigridOperator)
                    {
                        maxKrylovDim = Config_MaxKrylovDim,
                        MaxIter      = Config_MaxIterations,
                        MinIter      = Config_MinIterations,
                        ApproxJac    = Newton.ApproxInvJacobianOptions.GMRES,
                        Precond      = Config_linearSolver,
                        //Precond = new RheologyJacobiPrecond() { m_We = 0.1},
                        GMRESConvCrit = Config_SolverConvergenceCriterion,
                        ConvCrit      = Config_SolverConvergenceCriterion,
                        m_SessionPath = SessionPath,
                    };
                    break;

                default:
                    throw new NotImplementedException();
                }
            }
            else
            {
                // +++++++++++++++++++++++++++++++++++++++++++++
                // the linear solvers:
                // +++++++++++++++++++++++++++++++++++++++++++++


                linearSolver = Config_linearSolver;
            }



            // set callback for diagnostic output
            // ----------------------------------

            if (nonlinSolver != null)
            {
                nonlinSolver.IterationCallback += this.LogResis;
            }

            if (linearSolver != null && linearSolver is ISolverWithCallback)
            {
                ((ISolverWithCallback)linearSolver).IterationCallback = this.LogResis;
            }

            // return
            // ------


            return(solverDescription);
        }
示例#6
0
        /// <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;
        }
示例#7
0
        /// <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
        }
示例#8
0
        /// <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");
            }
        }