/// <summary> /// Constructor for conventional (single-phase, non-X) DG /// </summary> public XdgTimestepping( SpatialOperator op, IEnumerable <DGField> Fields, IEnumerable <DGField> IterationResiduals, TimeSteppingScheme __Scheme, MultigridOperator.ChangeOfBasisConfig[][] _MultigridOperatorConfig = null, AggregationGridData[] _MultigridSequence = null, LinearSolverConfig LinearSolver = null, NonLinearSolverConfig NonLinearSolver = null) // { this.Scheme = __Scheme; this.DgOperator = op; this.Parameters = op.InvokeParameterFactory(Fields); var spc = CreateDummyTracker(Fields); ConstructorCommon(op, false, Fields, this.Parameters, IterationResiduals, new[] { spc }, UpdateLevelsetWithNothing, LevelSetHandling.None, _MultigridOperatorConfig, _MultigridSequence, 0.0, LinearSolver, NonLinearSolver); }
/// <summary> /// Constructor for an XDG operator /// </summary> public XdgTimestepping( XSpatialOperatorMk2 op, IEnumerable <DGField> Fields, IEnumerable <DGField> IterationResiduals, TimeSteppingScheme __Scheme, DelUpdateLevelset _UpdateLevelset = null, LevelSetHandling _LevelSetHandling = LevelSetHandling.None, MultigridOperator.ChangeOfBasisConfig[][] _MultigridOperatorConfig = null, AggregationGridData[] _MultigridSequence = null, double _AgglomerationThreshold = 0.1, LinearSolverConfig LinearSolver = null, NonLinearSolverConfig NonLinearSolver = null) // { 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); SpeciesId[] spcToCompute = op.Species.Select(spcName => LsTrk.GetSpeciesId(spcName)).ToArray(); ConstructorCommon(op, UseX, Fields, this.Parameters, IterationResiduals, spcToCompute, _UpdateLevelset, _LevelSetHandling, _MultigridOperatorConfig, _MultigridSequence, _AgglomerationThreshold, LinearSolver, NonLinearSolver); }
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("===="); } }
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); } }
/* * /// <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; } }