13 #include "libmesh/petsc_nonlinear_solver.h" 14 #include "libmesh/petsc_solver_exception.h" 28 _solver =
dynamic_cast<PetscNonlinearSolver<Real> *
>(
32 "This line search operates only with Petsc, so Petsc must be your nonlinear solver.");
38 PetscBool changed_y = PETSC_FALSE, changed_w = PETSC_FALSE;
39 Vec X,
F, Y, W,
G, W1;
40 SNESLineSearch line_search;
41 PetscReal fnorm, xnorm, ynorm, gnorm;
42 PetscBool domainerror;
43 PetscReal ksp_rtol, ksp_abstol, ksp_dtol;
48 LibmeshPetscCall(SNESGetLineSearch(snes, &line_search));
49 LibmeshPetscCall(SNESLineSearchGetVecs(line_search, &X, &
F, &Y, &W, &
G));
50 LibmeshPetscCall(SNESLineSearchGetNorms(line_search, &xnorm, &fnorm, &ynorm));
51 LibmeshPetscCall(SNESLineSearchGetSNES(line_search, &snes));
52 LibmeshPetscCall(SNESLineSearchSetReason(line_search, SNES_LINESEARCH_SUCCEEDED));
53 LibmeshPetscCall(SNESGetKSP(snes, &ksp));
54 LibmeshPetscCall(KSPGetTolerances(ksp, &ksp_rtol, &ksp_abstol, &ksp_dtol, &ksp_maxits));
55 LibmeshPetscCall(VecDuplicate(W, &W1));
66 LibmeshPetscCall(SNESLineSearchPreCheck(line_search, X, Y, &changed_y));
75 LibmeshPetscCall(SNESComputeFunction(snes, W,
F));
76 LibmeshPetscCall(SNESGetFunctionDomainError(snes, &domainerror));
78 LibmeshPetscCall(SNESLineSearchSetReason(line_search, SNES_LINESEARCH_FAILED_DOMAIN));
80 LibmeshPetscCall(VecNorm(
F, NORM_2, &fnorm));
89 LibmeshPetscCall(KSPSetTolerances(ksp,
_contact_ltol, ksp_abstol, ksp_dtol, ksp_maxits));
90 _console <<
"Contact set changed since previous non-linear iteration!" << std::endl;
93 LibmeshPetscCall(KSPSetTolerances(ksp,
_user_ksp_rtol, ksp_abstol, ksp_dtol, ksp_maxits));
103 LibmeshPetscCall(SNESComputeFunction(snes, W1,
G));
104 LibmeshPetscCall(SNESGetFunctionDomainError(snes, &domainerror));
106 LibmeshPetscCall(SNESLineSearchSetReason(line_search, SNES_LINESEARCH_FAILED_DOMAIN));
108 LibmeshPetscCall(VecNorm(
G, NORM_2, &gnorm));
111 LibmeshPetscCall(VecCopy(
G,
F));
112 LibmeshPetscCall(VecCopy(W1, W));
125 LibmeshPetscCall(SNESLineSearchPostCheck(line_search, X, Y, W, &changed_y, &changed_w));
128 LibmeshPetscCall(VecWAXPY(W, -1., Y, X));
130 if (changed_w || changed_y)
132 LibmeshPetscCall(SNESComputeFunction(snes, W,
F));
133 LibmeshPetscCall(SNESGetFunctionDomainError(snes, &domainerror));
135 LibmeshPetscCall(SNESLineSearchSetReason(line_search, SNES_LINESEARCH_FAILED_DOMAIN));
143 LibmeshPetscCall(VecCopy(W, X));
145 LibmeshPetscCall(SNESLineSearchComputeNorms(line_search));
147 LibmeshPetscCall(VecDestroy(&W1));
SNES snes(const char *name=nullptr)
virtual libMesh::NonlinearSolver< Number > * nonlinearSolver() override
static const std::string F
static const std::string G
void mooseError(Args &&... args) const
const ConsoleStream _console
virtual NonlinearSystem & getNonlinearSystem(const unsigned int nl_sys_num) override