Пример #1
0
        /// <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
        }
Пример #2
0
        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);
            }
        }
Пример #3
0
        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);
            }
        }
Пример #4
0
        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);
            }
        }
Пример #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 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");
            }
        }
Пример #6
0
        /*
         * /// <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;
            }
        }
Пример #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");
            }
        }