Skip to content

Commit

Permalink
Merge pull request #14154 from frombs/issue_13991
Browse files Browse the repository at this point in the history
Add PETSc SNES divergence tolerance support
  • Loading branch information
fdkong committed Dec 6, 2019
2 parents 1374819 + 46a2435 commit 1d11e95
Show file tree
Hide file tree
Showing 11 changed files with 111 additions and 3 deletions.
5 changes: 4 additions & 1 deletion framework/include/problems/FEProblemBase.h
Expand Up @@ -98,7 +98,8 @@ enum class MooseNonlinearConvergenceReason
CONVERGED_SNORM_RELATIVE = 4,
DIVERGED_FUNCTION_COUNT = -2,
DIVERGED_FNORM_NAN = -4,
DIVERGED_LINE_SEARCH = -6
DIVERGED_LINE_SEARCH = -6,
DIVERGED_DTOL = -9
};

// The idea with these enums is to abstract the reasons for
Expand Down Expand Up @@ -190,6 +191,7 @@ class FEProblemBase : public SubProblem, public Restartable
* @param snorm Norm of the change in the solution vector
* @param fnorm Norm of the residual vector
* @param rtol Relative residual convergence tolerance
* @param divtol Relative residual divergence tolerance
* @param stol Solution change convergence tolerance
* @param abstol Absolute residual convergence tolerance
* @param nfuncs Number of function evaluations
Expand All @@ -205,6 +207,7 @@ class FEProblemBase : public SubProblem, public Restartable
const Real snorm,
const Real fnorm,
const Real rtol,
const Real divtol,
const Real stol,
const Real abstol,
const PetscInt nfuncs,
Expand Down
1 change: 1 addition & 0 deletions framework/include/problems/ReferenceResidualProblem.h
Expand Up @@ -38,6 +38,7 @@ class ReferenceResidualProblem : public FEProblem
const Real snorm,
const Real fnorm,
const Real rtol,
const Real divtol,
const Real stol,
const Real abstol,
const PetscInt nfuncs,
Expand Down
5 changes: 4 additions & 1 deletion framework/src/executioners/FEProblemSolve.C
Expand Up @@ -62,6 +62,7 @@ FEProblemSolve::validParams()
params.addParam<unsigned int>("nl_max_funcs", 10000, "Max Nonlinear solver function evaluations");
params.addParam<Real>("nl_abs_tol", 1.0e-50, "Nonlinear Absolute Tolerance");
params.addParam<Real>("nl_rel_tol", 1.0e-8, "Nonlinear Relative Tolerance");
params.addParam<Real>("nl_div_tol", -1, "Nonlinear Divergence Tolerance");
params.addParam<Real>("nl_abs_step_tol", 1.0e-50, "Nonlinear Absolute step Tolerance");
params.addParam<Real>("nl_rel_step_tol", 1.0e-50, "Nonlinear Relative step Tolerance");
params.addParam<bool>(
Expand All @@ -84,7 +85,7 @@ FEProblemSolve::validParams()
params.addParam<bool>("verbose", false, "Set to true to print additional information");

params.addParamNamesToGroup("l_tol l_abs_tol l_abs_step_tol l_max_its nl_max_its nl_max_funcs "
"nl_abs_tol nl_rel_tol nl_abs_step_tol nl_rel_step_tol "
"nl_abs_tol nl_rel_tol nl_div_tol nl_abs_step_tol nl_rel_step_tol "
"snesmf_reuse_base compute_initial_residual_before_preset_bcs",
"Solver");
return params;
Expand Down Expand Up @@ -121,6 +122,8 @@ FEProblemSolve::FEProblemSolve(Executioner * ex)
es.parameters.set<Real>("nonlinear solver relative residual tolerance") =
getParam<Real>("nl_rel_tol");

es.parameters.set<Real>("nonlinear solver divergence tolerance") = getParam<Real>("nl_div_tol");

es.parameters.set<Real>("nonlinear solver absolute step tolerance") =
getParam<Real>("nl_abs_step_tol");

Expand Down
7 changes: 7 additions & 0 deletions framework/src/problems/FEProblemBase.C
Expand Up @@ -6161,6 +6161,7 @@ FEProblemBase::checkNonlinearConvergence(std::string & msg,
const Real snorm,
const Real fnorm,
const Real rtol,
const Real divtol,
const Real stol,
const Real abstol,
const PetscInt nfuncs,
Expand Down Expand Up @@ -6223,6 +6224,12 @@ FEProblemBase::checkNonlinearConvergence(std::string & msg,
<< '\n';
reason = MooseNonlinearConvergenceReason::CONVERGED_SNORM_RELATIVE;
}
else if (divtol > 0 && fnorm > the_residual * divtol)
{
oss << "Diverged due to initial residual " << the_residual << " > divergence tolerance "
<< divtol << " * initial residual " << the_residual << '\n';
reason = MooseNonlinearConvergenceReason::DIVERGED_DTOL;
}
}

system._last_nl_rnorm = fnorm;
Expand Down
1 change: 1 addition & 0 deletions framework/src/problems/ReferenceResidualProblem.C
Expand Up @@ -400,6 +400,7 @@ ReferenceResidualProblem::checkNonlinearConvergence(std::string & msg,
const Real snorm,
const Real fnorm,
const Real rtol,
const Real /*divtol*/,
const Real stol,
const Real abstol,
const PetscInt nfuncs,
Expand Down
17 changes: 16 additions & 1 deletion framework/src/utils/PetscSupport.C
Expand Up @@ -305,6 +305,13 @@ petscNonlinearConverged(SNES snes,
ierr = SNESGetTolerances(snes, &atol, &rtol, &stol, &maxit, &maxf);
CHKERRABORT(problem.comm().get(), ierr);

// Ask the SNES object about its divergence tolerance.
PetscReal divtol = 0.; // relative divergence tolerance
#if !PETSC_VERSION_LESS_THAN(3, 8, 0)
ierr = SNESGetDivergenceTolerance(snes, &divtol);
CHKERRABORT(problem.comm().get(), ierr);
#endif

// Get current number of function evaluations done by SNES.
PetscInt nfuncs = 0;
ierr = SNESGetNumberFunctionEvals(snes, &nfuncs);
Expand Down Expand Up @@ -345,6 +352,7 @@ petscNonlinearConverged(SNES snes,
snorm,
fnorm,
rtol,
divtol,
stol,
atol,
nfuncs,
Expand All @@ -370,6 +378,12 @@ petscNonlinearConverged(SNES snes,
*reason = SNES_CONVERGED_FNORM_RELATIVE;
break;

case MooseNonlinearConvergenceReason::DIVERGED_DTOL:
#if !PETSC_VERSION_LESS_THAN(3, 8, 0) // A new convergence enum in PETSc 3.8
*reason = SNES_DIVERGED_DTOL;
#endif
break;

case MooseNonlinearConvergenceReason::CONVERGED_SNORM_RELATIVE:
#if PETSC_VERSION_LESS_THAN(3, 3, 0)
*reason = SNES_CONVERGED_PNORM_RELATIVE;
Expand Down Expand Up @@ -764,7 +778,8 @@ getCommonPetscKeys()
"-pc_hypre_boomeramg_max_iter "
"-pc_hypre_boomeramg_strong_threshold -pc_hypre_type -pc_type -snes_atol "
"-snes_linesearch_type "
"-snes_ls -snes_max_it -snes_rtol -snes_type -sub_ksp_type -sub_pc_type",
"-snes_ls -snes_max_it -snes_rtol -snes_divergence_tolerance -snes_type "
"-sub_ksp_type -sub_pc_type",
"",
true);
}
Expand Down
Expand Up @@ -40,6 +40,7 @@ class AugmentedLagrangianContactProblem : public ReferenceResidualProblem
const Real snorm,
const Real fnorm,
const Real rtol,
const Real divtol,
const Real stol,
const Real abstol,
const PetscInt nfuncs,
Expand Down
Expand Up @@ -59,6 +59,7 @@ AugmentedLagrangianContactProblem::checkNonlinearConvergence(std::string & msg,
const Real snorm,
const Real fnorm,
const Real rtol,
const Real divtol,
const Real stol,
const Real abstol,
const PetscInt nfuncs,
Expand All @@ -78,6 +79,7 @@ AugmentedLagrangianContactProblem::checkNonlinearConvergence(std::string & msg,
snorm,
fnorm,
rtol,
divtol,
stol,
abstol,
nfuncs,
Expand Down
Binary file not shown.
@@ -0,0 +1,61 @@
[Mesh]
type = GeneratedMesh
dim = 2
nx = 15
ny = 15
[]

[Variables]
[./u]
scaling = 1e-4
[../]
[]

[Kernels]
[./diff]
type = CoefDiffusion
variable = u
coef = 0.1
[../]
[./time]
type = TimeDerivative
variable = u
[../]
[]

[BCs]
[./left]
type = DirichletBC
variable = u
boundary = left
value = -1000
[../]
[./right]
type = DirichletBC
variable = u
boundary = right
value = 100000
[../]
[]

[Executioner]
type = Transient
scheme = 'implicit-euler'
line_search = 'none'
solve_type = PJFNK

l_max_its = 20
nl_max_its = 20
nl_div_tol = 1.0e+4

dt = 5
num_steps = 4

petsc_options = '-snes_converged_reason -ksp_converged_reason '
petsc_options_iname = '-pc_type -pc_hypre_type '
petsc_options_value = 'hypre boomeramg'
[]

[Outputs]
exodus = true
[]
14 changes: 14 additions & 0 deletions test/tests/executioners/nl_divergence_tolerance/tests
@@ -0,0 +1,14 @@
[Tests]
design = 'syntax/Executioner/index.md'
[./test]
type = 'Exodiff'
input = 'nl_divergence_tolerance.i'
exodiff = 'nl_divergence_tolerance_out.e'
petsc_version = '>=3.8.0'
max_parallel = 1
max_threads = 1
mesh_mode = REPLICATED
requirement = "The Executioner system shall support the PETSc non-linear divergence tolerance."
issues = '#13991'
[../]
[]

0 comments on commit 1d11e95

Please sign in to comment.