From c911e49c238da9fcd294672c334f36e9dbe87136 Mon Sep 17 00:00:00 2001 From: "Mark C. Messner" Date: Tue, 14 Jun 2022 11:29:52 -0500 Subject: [PATCH] Modified setup to provide default getter Use getter/setter to supply the required properties for the new reuse capability. Default to libmesh_not_implemented() in superclass, implemented in the petsc solvers. --- include/solvers/nonlinear_solver.h | 37 +++++++++++++++++++----- include/solvers/petsc_nonlinear_solver.h | 10 +++++++ src/solvers/nonlinear_solver.C | 23 +++++++++++++++ src/solvers/petsc_nonlinear_solver.C | 21 +++++++++++--- src/systems/nonlinear_implicit_system.C | 4 +-- 5 files changed, 81 insertions(+), 14 deletions(-) diff --git a/include/solvers/nonlinear_solver.h b/include/solvers/nonlinear_solver.h index 864fc3857c..88e2099ce9 100644 --- a/include/solvers/nonlinear_solver.h +++ b/include/solvers/nonlinear_solver.h @@ -350,21 +350,42 @@ class NonlinearSolver : public ReferenceCountedObject>, bool converged; /** - * Whether we should reuse the linear preconditioner + * Set the solver configuration object. */ - bool reuse_preconditioner; + void set_solver_configuration(SolverConfiguration & solver_configuration); /** - * Number of linear iterations to retain the preconditioner + * Get the reuse_preconditioner flag */ - unsigned int reuse_preconditioner_max_its; + virtual bool reuse_preconditioner() const; /** - * Set the solver configuration object. + * Set the reuse preconditioner flag */ - void set_solver_configuration(SolverConfiguration & solver_configuration); + virtual void set_reuse_preconditioner(bool reuse); + + /** + * Get the reuse_preconditioner_max_its parameter + */ + virtual unsigned int reuse_preconditioner_max_its() const; + + /** + * Set the reuse_preconditioner_max_its parameter + */ + virtual void set_reuse_preconditioner_max_its(unsigned int i); + protected: + /** + * Whether we should reuse the linear preconditioner + */ + bool _reuse_preconditioner; + + /** + * Number of linear iterations to retain the preconditioner + */ + unsigned int _reuse_preconditioner_max_its; + /** * A reference to the system we are solving. */ @@ -425,8 +446,8 @@ NonlinearSolver::NonlinearSolver (sys_type & s) : initial_linear_tolerance(0), minimum_linear_tolerance(0), converged(false), - reuse_preconditioner(false), - reuse_preconditioner_max_its(0), + _reuse_preconditioner(false), + _reuse_preconditioner_max_its(0), _system(s), _is_initialized (false), _preconditioner (nullptr), diff --git a/include/solvers/petsc_nonlinear_solver.h b/include/solvers/petsc_nonlinear_solver.h index 387e7f2be0..3d400a161a 100644 --- a/include/solvers/petsc_nonlinear_solver.h +++ b/include/solvers/petsc_nonlinear_solver.h @@ -207,6 +207,16 @@ class PetscNonlinearSolver : public NonlinearSolver */ void setup_default_monitor(); + /** + * Getter for preconditioner reuse + */ + virtual bool reuse_preconditioner() const; + + /** + * Getter for the maximum iterations flag for preconditioner reuse + */ + virtual unsigned int reuse_preconditioner_max_its() const; + protected: /** diff --git a/src/solvers/nonlinear_solver.C b/src/solvers/nonlinear_solver.C index c87696147d..644fc0ac53 100644 --- a/src/solvers/nonlinear_solver.C +++ b/src/solvers/nonlinear_solver.C @@ -84,6 +84,29 @@ void NonlinearSolver::set_solver_configuration(SolverConfiguration & solver_c _solver_configuration = &solver_configuration; } +template +bool NonlinearSolver::reuse_preconditioner() const +{ + libmesh_not_implemented(); +} + +template +void NonlinearSolver::set_reuse_preconditioner(bool reuse) +{ + _reuse_preconditioner = reuse; +} + +template +unsigned int NonlinearSolver::reuse_preconditioner_max_its() const +{ + libmesh_not_implemented(); +} + +template +void NonlinearSolver::set_reuse_preconditioner_max_its(unsigned int i) +{ + _reuse_preconditioner_max_its = i; +} //------------------------------------------------------------------ // Explicit instantiations diff --git a/src/solvers/petsc_nonlinear_solver.C b/src/solvers/petsc_nonlinear_solver.C index 0d050a33ef..592d2a522e 100644 --- a/src/solvers/petsc_nonlinear_solver.C +++ b/src/solvers/petsc_nonlinear_solver.C @@ -670,7 +670,7 @@ void PetscNonlinearSolver::clear () // If we don't need the preconditioner next time // retain the original behavior of clearing the data // between solves. - if (!(this->reuse_preconditioner)) + if (!(reuse_preconditioner())) { // SNESReset really ought to work but replacing destory() with // SNESReset causes a very slight change in behavior that @@ -871,7 +871,7 @@ PetscNonlinearSolver::solve (SparseMatrix & pre_in, // System Preconditi // We don't want to do this twice because it resets // SNESSetLagPreconditioner - if ((this->reuse_preconditioner) && (!_setup_reuse)) + if ((reuse_preconditioner()) && (!_setup_reuse)) { _setup_reuse = true; ierr = SNESSetLagPreconditionerPersists(_snes, PETSC_TRUE); @@ -882,13 +882,14 @@ PetscNonlinearSolver::solve (SparseMatrix & pre_in, // System Preconditi LIBMESH_CHKERR(ierr); // Add in our callback which will trigger recalculating // the preconditioner when we hit reuse_preconditioner_max_its + unsigned int max_its = reuse_preconditioner_max_its(); ierr = SNESMonitorSet(_snes, &libmesh_petsc_recalculate_monitor, (void*) - &(this->reuse_preconditioner_max_its), + &max_its, NULL); LIBMESH_CHKERR(ierr); } - else if (!(this->reuse_preconditioner)) + else if (!(reuse_preconditioner())) // This covers the case where it was enabled but was then disabled { ierr = SNESSetLagPreconditionerPersists(_snes, PETSC_FALSE); @@ -1126,6 +1127,18 @@ void PetscNonlinearSolver::setup_default_monitor() } } +template +bool PetscNonlinearSolver::reuse_preconditioner() const +{ + return this->_reuse_preconditioner; +} + +template +unsigned int PetscNonlinearSolver::reuse_preconditioner_max_its() const +{ + return this->_reuse_preconditioner_max_its; +} + //------------------------------------------------------------------ // Explicit instantiations diff --git a/src/systems/nonlinear_implicit_system.C b/src/systems/nonlinear_implicit_system.C index c6c53799ce..12a632c601 100644 --- a/src/systems/nonlinear_implicit_system.C +++ b/src/systems/nonlinear_implicit_system.C @@ -148,8 +148,8 @@ void NonlinearImplicitSystem::set_solver_parameters () nonlinear_solver->max_linear_iterations = maxlinearits; nonlinear_solver->initial_linear_tolerance = linear_tol; nonlinear_solver->minimum_linear_tolerance = linear_min_tol; - nonlinear_solver->reuse_preconditioner = reuse_preconditioner; - nonlinear_solver->reuse_preconditioner_max_its = reuse_preconditioner_max_its; + nonlinear_solver->set_reuse_preconditioner(reuse_preconditioner); + nonlinear_solver->set_reuse_preconditioner_max_its(reuse_preconditioner_max_its); if (diff_solver.get()) {