20 #include "libmesh/libmesh_common.h" 22 #ifdef LIBMESH_HAVE_PETSC 25 #include "libmesh/libmesh_logging.h" 26 #include "libmesh/nonlinear_implicit_system.h" 27 #include "libmesh/petsc_nonlinear_solver.h" 28 #include "libmesh/petsc_linear_solver.h" 29 #include "libmesh/petsc_vector.h" 30 #include "libmesh/petsc_mffd_matrix.h" 31 #include "libmesh/dof_map.h" 32 #include "libmesh/preconditioner.h" 33 #include "libmesh/solver_configuration.h" 34 #include "libmesh/petscdmlibmesh.h" 35 #include "libmesh/petsc_preconditioner.h" 37 #if defined(LIBMESH_HAVE_PETSC_HYPRE) && PETSC_VERSION_LESS_THAN(3, 23, 0) && \ 38 !PETSC_VERSION_LESS_THAN(3, 12, 0) && defined(PETSC_HAVE_HYPRE_DEVICE) 39 #include <HYPRE_utilities.h> 59 LOG_SCOPE(
"residual()",
"PetscNonlinearSolver");
68 libmesh_parallel_only(solver->
comm());
74 PetscInt n_iterations = 0;
75 LibmeshPetscCall2(solver->
comm(), SNESGetIterationNumber(snes, &n_iterations));
125 LibmeshPetscCall2(solver->
comm(), SNESGetKSP(snes, &ksp));
128 LibmeshPetscCall2(solver->
comm(), KSPGetIterationNumber(ksp, &niter));
134 LibmeshPetscCall2(solver->
comm(), SNESSetLagPreconditioner(snes, -2));
146 << std::setw(2) << its
148 <<
", |residual|_2 = " << fnorm
162 libmesh_parallel_only(rc.
sys.
comm());
174 "ERROR: cannot specify both a function and object to compute the Residual!");
177 "ERROR: cannot specify both a function and object to compute the combined Residual & Jacobian!");
207 libmesh_error_msg(
"Error! Unable to compute residual and/or Jacobian!");
214 X_global.
swap(X_sys);
216 X_global.swap(X_sys);
238 libmesh_parallel_only(rc.
sys.
comm());
253 libmesh_error_msg(
"Error! Unable to compute residual for forming finite difference Jacobian!");
259 X_global.
swap(X_sys);
261 X_global.swap(X_sys);
284 libmesh_parallel_only(rc.
sys.
comm());
299 libmesh_error_msg(
"Error! Unable to compute residual for forming finite differenced" 300 "Jacobian-vector products!");
306 X_global.
swap(X_sys);
308 X_global.swap(X_sys);
335 #if !PETSC_VERSION_LESS_THAN(3,8,4) 342 SNES snes = solver->
snes();
345 LibmeshPetscCall2(solver->
comm(), SNESGetKSP(snes, &ksp));
348 LibmeshPetscCall2(solver->
comm(), KSPGetIterationNumber(ksp, &ksp_it));
351 LibmeshPetscCall2(solver->
comm(), SNESGetType(snes, &snes_type));
353 libmesh_assert_msg(snes_type,
"We're being called from SNES; snes_type should be non-null");
356 LibmeshPetscCall2(solver->
comm(), SNESGetJacobian(snes, &J, NULL, NULL, NULL));
357 libmesh_assert_msg(J,
"We're being called from SNES; J should be non-null");
360 LibmeshPetscCall2(solver->
comm(), MatGetType(J, &mat_type));
361 libmesh_assert_msg(mat_type,
"We're being called from SNES; mat_type should be non-null");
363 bool is_operator_mffd = strcmp(mat_type, MATMFFD) == 0;
365 if ((ksp_it == PetscInt(0)) && is_operator_mffd)
369 if (computing_base_vector)
371 Vec nonlinear_residual;
373 LibmeshPetscCall2(solver->
comm(), SNESGetFunction(snes, &nonlinear_residual, NULL, NULL));
375 PetscBool vecs_equal;
376 LibmeshPetscCall2(solver->
comm(), VecEqual(r, nonlinear_residual, &vecs_equal));
378 libmesh_error_msg_if(!(vecs_equal == PETSC_TRUE),
379 "You requested to reuse the nonlinear residual vector as the base vector for " 380 "computing the action of the matrix-free Jacobian, but the vectors are not " 381 "the same. Your physics must have states; either remove the states " 382 "from your code or make sure that you set_mf_reuse_base(false)");
405 LOG_SCOPE(
"jacobian()",
"PetscNonlinearSolver");
413 libmesh_parallel_only(solver->
comm());
419 PetscInt n_iterations = 0;
420 LibmeshPetscCall2(solver->
comm(), SNESGetIterationNumber(snes, &n_iterations));
428 "ERROR: cannot specify both a function and object to compute the Jacobian!");
431 "ERROR: cannot specify both a function and object to compute the combined Residual & Jacobian!");
441 PetscBool p_is_shell = PETSC_FALSE;
442 PetscBool j_is_mffd = PETSC_FALSE;
443 PetscBool j_is_shell = PETSC_FALSE;
445 LibmeshPetscCall2(sys.
comm(), PetscObjectTypeCompare((PetscObject)pc, MATSHELL, &p_is_shell));
447 LibmeshPetscCall2(sys.
comm(), PetscObjectTypeCompare((PetscObject)jac, MATMFFD, &j_is_mffd));
448 LibmeshPetscCall2(sys.
comm(), PetscObjectTypeCompare((PetscObject)jac, MATSHELL, &j_is_shell));
449 if (j_is_mffd == PETSC_TRUE)
461 if ((j_is_shell == PETSC_TRUE) || (j_is_mffd == PETSC_TRUE))
464 if (pc && (p_is_shell == PETSC_TRUE))
475 X_global.swap(X_sys);
477 X_global.swap(X_sys);
496 else if (solver->
matvec !=
nullptr)
500 libmesh_error_msg(
"Error! Unable to compute residual and/or Jacobian!");
513 (j_is_shell == PETSC_TRUE));
534 libmesh_parallel_only(solver->
comm());
554 LOG_SCOPE(
"postcheck()",
"PetscNonlinearSolver");
558 *changed_w = PETSC_FALSE;
559 *changed_y = PETSC_FALSE;
567 libmesh_parallel_only(solver->
comm());
572 "ERROR: cannot specify both a function and object for performing the solve postcheck!");
587 changed_search_direction =
false,
588 changed_new_soln =
false;
599 changed_search_direction,
607 changed_search_direction,
613 if (changed_search_direction)
614 *changed_y = PETSC_TRUE;
616 if (changed_new_soln)
617 *changed_w = PETSC_TRUE;
626 LOG_SCOPE(
"precheck()",
"PetscNonlinearSolver");
630 *changed = PETSC_FALSE;
638 libmesh_parallel_only(solver->
comm());
648 petsc_changed =
false;
650 auto & sys = solver->
system();
651 auto & x_sys = *cast_ptr<PetscVector<Number> *>(sys.solution.get());
665 auto & local_soln = *sys.current_local_solution.get();
667 sys.get_dof_map().enforce_constraints_exactly(sys, &local_soln);
676 *changed = PETSC_TRUE;
687 template <
typename T>
690 linesearch_object(nullptr),
691 _reason(SNES_CONVERGED_ITERATING),
692 _n_linear_iterations(0),
693 _current_nonlinear_iteration_number(0),
694 _zero_out_residual(true),
695 _zero_out_jacobian(true),
696 _default_monitor(true),
697 _snesmf_reuse_base(true),
698 _computing_base_vector(true),
700 _mffd_jac(this->_communicator)
706 template <
typename T>
711 template <
typename T>
721 if (!(reuse_preconditioner()))
732 _current_nonlinear_iteration_number = 0;
736 template <
typename T>
739 parallel_object_only();
749 LibmeshPetscCall(SNESCreate(this->comm().
get(), _snes.get()));
758 LibmeshPetscCall(SNESSetOptionsPrefix(_snes,
name));
762 #if defined(LIBMESH_ENABLE_AMR) && defined(LIBMESH_HAVE_METAPHYSICL) 764 "--" + (
name ? std::string(
name) : std::string(
"")) +
"use_petsc_dm");
768 this->_dm_wrapper.init_and_attach_petscdm(this->system(), _snes);
773 LibmeshPetscCall(DMCreate(this->comm().
get(), dm.
get()));
774 LibmeshPetscCall(DMSetType(dm, DMLIBMESH));
778 LibmeshPetscCall(DMSetOptionsPrefix(dm,
name));
780 LibmeshPetscCall(DMSetFromOptions(dm));
781 LibmeshPetscCall(DMSetUp(dm));
782 LibmeshPetscCall(SNESSetDM(_snes, dm));
786 setup_default_monitor();
790 if (this->_solver_configuration)
792 this->_solver_configuration->set_options_during_init();
795 if (this->_preconditioner)
798 LibmeshPetscCall(SNESGetKSP (_snes, &ksp));
800 LibmeshPetscCall(KSPGetPC(ksp,&pc));
802 this->_preconditioner->init();
804 LibmeshPetscCall(PCSetType(pc, PCSHELL));
805 LibmeshPetscCall(PCShellSetContext(pc,(
void *)this->_preconditioner));
818 if (this->postcheck || this->postcheck_object)
820 SNESLineSearch linesearch;
821 LibmeshPetscCall(SNESGetLineSearch(_snes, &linesearch));
826 if (this->precheck_object)
828 SNESLineSearch linesearch;
829 LibmeshPetscCall(SNESGetLineSearch(_snes, &linesearch));
836 template <
typename T>
845 template <
typename T>
851 parallel_object_only();
853 std::vector<NumericVector<Number> *> sp;
854 if (computeSubspaceObject)
855 (*computeSubspaceObject)(sp, this->system());
857 (*computeSubspace)(sp, this->system());
859 *msp = LIBMESH_PETSC_NULLPTR;
862 PetscInt nmodes = cast_int<PetscInt>(sp.size());
864 std::vector<Vec> modes(nmodes);
865 std::vector<PetscScalar> dots(nmodes);
867 for (PetscInt i=0; i<nmodes; ++i)
869 auto pv = cast_ptr<PetscVector<T> *>(sp[i]);
871 LibmeshPetscCall(VecDuplicate(pv->vec(), &modes[i]));
873 LibmeshPetscCall(VecCopy(pv->vec(), modes[i]));
877 LibmeshPetscCall(VecNormalize(modes[0], LIBMESH_PETSC_NULLPTR));
879 for (PetscInt i=1; i<nmodes; i++)
882 LibmeshPetscCall(VecMDot(modes[i], i, modes.data(), dots.data()));
884 for (PetscInt j=0; j<i; j++)
887 LibmeshPetscCall(VecMAXPY(modes[i], i, dots.data(), modes.data()));
889 LibmeshPetscCall(VecNormalize(modes[i], LIBMESH_PETSC_NULLPTR));
892 LibmeshPetscCall(MatNullSpaceCreate(this->comm().
get(), PETSC_FALSE, nmodes, modes.data(), msp));
894 for (PetscInt i=0; i<nmodes; ++i)
895 LibmeshPetscCall(VecDestroy(&modes[i]));
899 template <
typename T>
900 std::pair<unsigned int, Real>
907 parallel_object_only();
909 LOG_SCOPE(
"solve()",
"PetscNonlinearSolver");
917 PetscInt n_iterations =0;
919 Real final_residual_norm=0.;
923 if ((reuse_preconditioner()) && (!_setup_reuse))
926 LibmeshPetscCall(SNESSetLagPreconditionerPersists(_snes, PETSC_TRUE));
929 LibmeshPetscCall(SNESSetLagPreconditioner(_snes, -2));
936 else if (!(reuse_preconditioner()))
939 LibmeshPetscCall(SNESSetLagPreconditionerPersists(_snes, PETSC_FALSE));
942 _setup_reuse =
false;
943 LibmeshPetscCall(SNESMonitorCancel(_snes));
945 setup_default_monitor();
953 if (this->jacobian || this->jacobian_object || this->residual_and_jacobian_object)
958 LibmeshPetscCall(SNESGetKSP (_snes, &ksp));
962 LibmeshPetscCall(KSPSetTolerances (ksp, this->initial_linear_tolerance, PETSC_DEFAULT,
963 PETSC_DEFAULT, this->max_linear_iterations));
966 LibmeshPetscCall(SNESSetTolerances(_snes,
967 this->absolute_residual_tolerance,
968 this->relative_residual_tolerance,
969 this->relative_step_tolerance,
970 this->max_nonlinear_iterations,
971 this->max_function_evaluations));
974 if (this->absolute_step_tolerance != 0)
975 libmesh_warning(
"Setting the absolute step tolerance is not supported with the PETSc nonlinear solver.");
978 #if !PETSC_VERSION_LESS_THAN(3,8,0) 979 LibmeshPetscCall(SNESSetDivergenceTolerance(_snes, this->divergence_tolerance));
983 #if PETSC_VERSION_LESS_THAN(3,7,0) 984 LibmeshPetscCall(KSPSetFromOptions(ksp));
986 LibmeshPetscCall(SNESSetFromOptions(_snes));
989 LibmeshPetscCall(KSPGetPC(ksp, &pc));
992 #if defined(LIBMESH_HAVE_PETSC_HYPRE) && PETSC_VERSION_LESS_THAN(3, 23, 0) && \ 993 !PETSC_VERSION_LESS_THAN(3, 12, 0) && defined(PETSC_HAVE_HYPRE_DEVICE) 996 LibmeshPetscCallExternal(HYPRE_Initialize);
997 PetscScalar * dummyarray;
999 LibmeshPetscCall(VecGetArrayAndMemType(x->vec(), &dummyarray, &mtype));
1000 LibmeshPetscCall(VecRestoreArrayAndMemType(x->vec(), &dummyarray));
1001 if (PetscMemTypeHost(mtype))
1002 LibmeshPetscCallExternal(HYPRE_SetMemoryLocation, HYPRE_MEMORY_HOST);
1006 if (this->user_presolve)
1007 this->user_presolve(this->system());
1010 if (this->_preconditioner)
1012 this->_preconditioner->set_matrix(pre_in);
1013 this->_preconditioner->init();
1018 if (this->_solver_configuration)
1019 this->_solver_configuration->configure_solver();
1033 #if !PETSC_VERSION_LESS_THAN(3,6,0) 1034 LibmeshPetscCall(SNESSetSolution(_snes, x->vec()));
1036 LibmeshPetscCall(SNESSetUp(_snes));
1039 LibmeshPetscCall(SNESGetJacobian(_snes, &J, &P,
1040 LIBMESH_PETSC_NULLPTR,
1041 LIBMESH_PETSC_NULLPTR));
1043 #if !PETSC_VERSION_LESS_THAN(3,8,4) 1050 LibmeshPetscCall(MatSNESMFSetReuseBase(J, PETSC_FALSE));
1053 LibmeshPetscCall(MatSNESMFSetReuseBase(J, static_cast<PetscBool>(_snesmf_reuse_base)));
1058 if (this->nullspace || this->nullspace_object)
1061 this->build_mat_null_space(this->nullspace_object, this->nullspace, msp.
get());
1064 LibmeshPetscCall(MatSetNullSpace(J, msp));
1066 LibmeshPetscCall(MatSetNullSpace(P, msp));
1071 if (this->transpose_nullspace || this->transpose_nullspace_object)
1073 #if PETSC_VERSION_LESS_THAN(3,6,0) 1074 libmesh_warning(
"MatSetTransposeNullSpace is only supported for PETSc >= 3.6, transpose nullspace will be ignored.");
1077 this->build_mat_null_space(this->transpose_nullspace_object, this->transpose_nullspace, msp.
get());
1080 LibmeshPetscCall(MatSetTransposeNullSpace(J, msp));
1082 LibmeshPetscCall(MatSetTransposeNullSpace(P, msp));
1088 if (this->nearnullspace || this->nearnullspace_object)
1091 this->build_mat_null_space(this->nearnullspace_object, this->nearnullspace, msp.
get());
1095 LibmeshPetscCall(MatSetNearNullSpace(J, msp));
1097 LibmeshPetscCall(MatSetNearNullSpace(P, msp));
1101 SNESLineSearch linesearch;
1102 if (linesearch_object)
1104 LibmeshPetscCall(SNESGetLineSearch(_snes, &linesearch));
1105 LibmeshPetscCall(SNESLineSearchSetType(linesearch, SNESLINESEARCHSHELL));
1106 #if PETSC_RELEASE_GREATER_EQUALS(3, 21, 0) 1113 LibmeshPetscCall(SNESSolve (_snes, LIBMESH_PETSC_NULLPTR, x->vec()));
1115 LibmeshPetscCall(SNESGetIterationNumber(_snes, &n_iterations));
1117 LibmeshPetscCall(SNESGetLinearSolveIterations(_snes, &_n_linear_iterations));
1124 LibmeshPetscCall(SNESGetFunction(_snes, &f, 0, 0));
1125 LibmeshPetscCall(VecNorm(f, NORM_2,
pPR(&final_residual_norm)));
1128 LibmeshPetscCall(SNESGetConvergedReason(_snes, &_reason));
1131 this->converged = (_reason >= 0);
1137 return std::make_pair(n_iterations, final_residual_norm);
1142 template <
typename T>
1146 libMesh::out <<
"Nonlinear solver convergence/divergence reason: " 1147 << SNESConvergedReasons[this->get_converged_reason()] << std::endl;
1152 template <
typename T>
1156 LibmeshPetscCall(SNESGetConvergedReason(_snes, &_reason));
1161 template <
typename T>
1164 return _n_linear_iterations;
1167 template <
typename T>
1170 if (_default_monitor)
1175 template <
typename T>
1178 return this->_reuse_preconditioner;
1181 template <
typename T>
1184 return this->_reuse_preconditioner_max_linear_its;
1187 template <
typename T>
1193 _setup_reuse =
false;
1204 #endif // #ifdef LIBMESH_HAVE_PETSC unsigned _current_nonlinear_iteration_number
Stores the current nonlinear iteration number.
std::string name(const ElemQuality q)
This function returns a string containing some name for q.
PetscNonlinearSolver< Number > * solver
SNES snes(const char *name=nullptr)
This class provides a nice interface to PETSc's Vec object.
void(* residual)(const NumericVector< Number > &X, NumericVector< Number > &R, sys_type &S)
Function that computes the residual R(X) of the nonlinear system at the input iterate X...
This class provides an interface to the suite of preconditioners available from PETSc.
virtual unsigned int reuse_preconditioner_max_linear_its() const override
Getter for the maximum iterations flag for preconditioner reuse.
NonlinearImplicitSystem::ComputeResidualandJacobian * residual_and_jacobian_object
Object that computes either the residual or the Jacobian of the nonlinear system at the input itera...
virtual void residual(const NumericVector< Number > &X, NumericVector< Number > &R, sys_type &S)=0
Residual function.
PetscErrorCode libmesh_petsc_snes_fd_residual(SNES, Vec x, Vec r, void *ctx)
virtual void zero() override
Set all entries to zero.
PetscNonlinearSolver(sys_type &system)
Constructor.
PETSC_EXTERN PetscErrorCode DMlibMeshSetSystem(DM, libMesh::NonlinearImplicitSystem &)
Any functional implementation of the DMlibMesh API must compose the following functions with the DM o...
NonlinearImplicitSystem & sys
PetscErrorCode libmesh_petsc_preconditioner_apply(PC, Vec x, Vec y)
This function is called by PETSc to actually apply the preconditioner.
const Parallel::Communicator & comm() const
This base class can be inherited from to provide interfaces to nonlinear solvers from different packa...
static PetscMatrixBase< T > * get_context(Mat mat, const TIMPI::Communicator &comm)
PetscErrorCode libmesh_petsc_snes_postcheck(SNESLineSearch, Vec x, Vec y, Vec w, PetscBool *changed_y, PetscBool *changed_w, void *context)
bool _zero_out_residual
true to zero out residual before going into application level call-back, otherwise false ...
The libMesh namespace provides an interface to certain functionality in the library.
NonlinearImplicitSystem::ComputeResidual * residual_object
Object that computes the residual R(X) of the nonlinear system at the input iterate X...
void(* jacobian)(const NumericVector< Number > &X, SparseMatrix< Number > &J, sys_type &S)
Function that computes the Jacobian J(X) of the nonlinear system at the input iterate X...
PetscErrorCode libmesh_petsc_snes_monitor(SNES, PetscInt its, PetscReal fnorm, void *)
virtual void postcheck(const NumericVector< Number > &old_soln, NumericVector< Number > &search_direction, NumericVector< Number > &new_soln, bool &changed_search_direction, bool &changed_new_soln, sys_type &S)=0
This interface, which is inspired by PETSc's, passes the user: .) A constant reference to the "old" s...
virtual void swap(NumericVector< T > &v) override
Swaps the contents of this with v.
bool snes_mf_reuse_base() const
PetscErrorCode libmesh_petsc_snes_mffd_residual(SNES snes, Vec x, Vec r, void *ctx)
void enforce_constraints_on_residual(const NonlinearImplicitSystem &system, NumericVector< Number > *rhs, NumericVector< Number > const *solution, bool homogeneous=true) const
processor_id_type size() const
const sys_type & system() const
NonlinearImplicitSystem::ComputeJacobian * jacobian_object
Object that computes the Jacobian J(X) of the nonlinear system at the input iterate X...
virtual void zero()=0
Set all entries to 0.
bool _is_initialized
Flag that tells if init() has been called.
bool _zero_out_jacobian
true to zero out jacobian before going into application level call-back, otherwise false ...
bool _exact_constraint_enforcement
Whether we should enforce exact constraints globally during a solve.
virtual void jacobian(const NumericVector< Number > &X, SparseMatrix< Number > &J, sys_type &S)=0
Jacobian function.
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
void init(triangulateio &t)
Initializes the fields of t to nullptr/0 as necessary.
Manages consistently variables, degrees of freedom, coefficient vectors, matrices and non-linear solv...
ResidualContext(PetscNonlinearSolver< Number > *solver_in, NonlinearImplicitSystem &sys_in)
ResidualContext libmesh_petsc_snes_residual_helper(SNES snes, Vec x, void *ctx)
virtual void close() override
Calls the SparseMatrix's internal assembly routines, ensuring that the values are consistent across p...
PetscErrorCode libmesh_petsc_snes_mffd_interface(void *ctx, Vec x, Vec r)
void attach_dof_map(const DofMap &dof_map)
Set a pointer to the DofMap to use.
virtual void update()
Update the local values to reflect the solution on neighboring processors.
PetscErrorCode libmesh_petsc_preconditioner_setup(PC)
This function is called by PETSc to initialize the preconditioner.
PetscErrorCode libmesh_petsc_linesearch_shellfunc(SNESLineSearch linesearch, void *ctx)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
std::unique_ptr< ComputeLineSearchObject > linesearch_object
A callable object that can be used to specify a custom line-search.
NonlinearImplicitSystem::ComputePostCheck * postcheck_object
A callable object that is executed after each nonlinear iteration.
PetscErrorCode libmesh_petsc_snes_jacobian(SNES, Vec x, Mat jac, Mat pc, void *ctx)
PetscErrorCode libmesh_petsc_snes_precheck(SNESLineSearch, Vec X, Vec Y, PetscBool *changed, void *context)
virtual void precheck(const NumericVector< Number > &precheck_soln, NumericVector< Number > &search_direction, bool &changed, sys_type &S)=0
Abstract precheck method that users must override.
NonlinearImplicitSystem::ComputeResidual * mffd_residual_object
Object that computes the residual R(X) of the nonlinear system at the input iterate X for the purpose...
std::unique_ptr< NumericVector< Number > > current_local_solution
All the values I need to compute my contribution to the simulation at hand.
bool initialized()
Checks that library initialization has been done.
void(* postcheck)(const NumericVector< Number > &old_soln, NumericVector< Number > &search_direction, NumericVector< Number > &new_soln, bool &changed_search_direction, bool &changed_new_soln, sys_type &S)
Function that performs a "check" on the Newton search direction and solution after each nonlinear ste...
bool on_command_line(std::string arg)
NonlinearImplicitSystem::ComputePreCheck * precheck_object
PetscFunctionReturn(LIBMESH_PETSC_SUCCESS)
void set_computing_base_vector(bool computing_base_vector)
Set whether we are computing the base vector for matrix-free finite-differencing. ...
const DofMap & get_dof_map() const
const SparseMatrix< Number > & get_system_matrix() const
PetscErrorCode libmesh_petsc_snes_residual(SNES, Vec x, Vec r, void *ctx)
virtual void residual_and_jacobian(const NumericVector< Number > &X, NumericVector< Number > *R, SparseMatrix< Number > *J, sys_type &S)=0
Residual & Jacobian function, calculated simultaneously.
PetscErrorCode libmesh_petsc_recalculate_monitor(SNES snes, PetscInt it, PetscReal norm, void *mctx)
bool computing_base_vector() const
void(* matvec)(const NumericVector< Number > &X, NumericVector< Number > *R, SparseMatrix< Number > *J, sys_type &S)
Function that computes either the residual or the Jacobian of the nonlinear system at the input ite...
NonlinearImplicitSystem::ComputeResidual * fd_residual_object
Object that computes the residual R(X) of the nonlinear system at the input iterate X for the purpose...
void enforce_constraints_exactly(const System &system, NumericVector< Number > *v=nullptr, bool homogeneous=false) const
Constrains the numeric vector v, which represents a solution defined on the mesh. ...
Callable abstract base class to be used as a callback to provide the solver with a basis for the syst...
void enforce_constraints_on_jacobian(const NonlinearImplicitSystem &system, SparseMatrix< Number > *jac) const