示例#1
0
        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);
        }
示例#2
0
        /// <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]);
                    }
                }
            }
        }
示例#3
0
        /// <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;
        }
示例#4
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;
        }
示例#5
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");
            }
        }