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)
345 SNES snes = solver->
snes();
348 LibmeshPetscCall2(solver->
comm(), SNESGetKSP(snes, &ksp));
351 LibmeshPetscCall2(solver->
comm(), KSPGetIterationNumber(ksp, &ksp_it));
354 LibmeshPetscCall2(solver->
comm(), SNESGetType(snes, &snes_type));
356 libmesh_assert_msg(snes_type,
"We're being called from SNES; snes_type should be non-null");
359 LibmeshPetscCall2(solver->
comm(), SNESGetJacobian(snes, &J, NULL, NULL, NULL));
360 libmesh_assert_msg(J,
"We're being called from SNES; J should be non-null");
363 LibmeshPetscCall2(solver->
comm(), MatGetType(J, &mat_type));
364 libmesh_assert_msg(mat_type,
"We're being called from SNES; mat_type should be non-null");
366 bool is_operator_mffd = strcmp(mat_type, MATMFFD) == 0;
368 if ((ksp_it == PetscInt(0)) && is_operator_mffd)
372 if (computing_base_vector)
374 Vec nonlinear_residual;
376 LibmeshPetscCall2(solver->
comm(), SNESGetFunction(snes, &nonlinear_residual, NULL, NULL));
378 PetscBool vecs_equal;
379 LibmeshPetscCall2(solver->
comm(), VecEqual(r, nonlinear_residual, &vecs_equal));
381 libmesh_error_msg_if(!(vecs_equal == PETSC_TRUE),
382 "You requested to reuse the nonlinear residual vector as the base vector for "
383 "computing the action of the matrix-free Jacobian, but the vectors are not "
384 "the same. Your physics must have states; either remove the states "
385 "from your code or make sure that you set_mf_reuse_base(false)");
408 LOG_SCOPE(
"jacobian()",
"PetscNonlinearSolver");
416 libmesh_parallel_only(solver->
comm());
422 PetscInt n_iterations = 0;
423 LibmeshPetscCall2(solver->
comm(), SNESGetIterationNumber(snes, &n_iterations));
431 "ERROR: cannot specify both a function and object to compute the Jacobian!");
434 "ERROR: cannot specify both a function and object to compute the combined Residual & Jacobian!");
444 PetscBool p_is_shell = PETSC_FALSE;
445 PetscBool j_is_mffd = PETSC_FALSE;
446 PetscBool j_is_shell = PETSC_FALSE;
448 LibmeshPetscCall2(sys.
comm(), PetscObjectTypeCompare((PetscObject)pc, MATSHELL, &p_is_shell));
450 LibmeshPetscCall2(sys.
comm(), PetscObjectTypeCompare((PetscObject)jac, MATMFFD, &j_is_mffd));
451 LibmeshPetscCall2(sys.
comm(), PetscObjectTypeCompare((PetscObject)jac, MATSHELL, &j_is_shell));
452 if (j_is_mffd == PETSC_TRUE)
458 mffd_jac.
assign(jac,
false);
466 if ((j_is_shell == PETSC_TRUE) || (j_is_mffd == PETSC_TRUE))
469 if (pc && (p_is_shell == PETSC_TRUE))
480 X_global.swap(X_sys);
482 X_global.swap(X_sys);
501 else if (solver->
matvec !=
nullptr)
505 libmesh_error_msg(
"Error! Unable to compute residual and/or Jacobian!");
518 (j_is_shell == PETSC_TRUE));
539 libmesh_parallel_only(solver->
comm());
559 LOG_SCOPE(
"postcheck()",
"PetscNonlinearSolver");
563 *changed_w = PETSC_FALSE;
564 *changed_y = PETSC_FALSE;
572 libmesh_parallel_only(solver->
comm());
577 "ERROR: cannot specify both a function and object for performing the solve postcheck!");
592 changed_search_direction =
false,
593 changed_new_soln =
false;
604 changed_search_direction,
612 changed_search_direction,
618 if (changed_search_direction)
619 *changed_y = PETSC_TRUE;
621 if (changed_new_soln)
622 *changed_w = PETSC_TRUE;
631 LOG_SCOPE(
"precheck()",
"PetscNonlinearSolver");
635 *changed = PETSC_FALSE;
643 libmesh_parallel_only(solver->
comm());
653 petsc_changed =
false;
655 auto & sys = solver->
system();
656 auto & x_sys = *cast_ptr<PetscVector<Number> *>(sys.
solution.get());
681 *changed = PETSC_TRUE;
695 linesearch_object(nullptr),
696 _reason(SNES_CONVERGED_ITERATING),
697 _n_linear_iterations(0),
698 _current_nonlinear_iteration_number(0),
699 _zero_out_residual(true),
700 _zero_out_jacobian(true),
701 _default_monitor(true),
702 _snesmf_reuse_base(true),
703 _reproducible_residual(true),
704 _computing_base_vector(true),
721 this->_is_initialized =
false;
726 if (!(reuse_preconditioner()))
737 _current_nonlinear_iteration_number = 0;
744 parallel_object_only();
749 this->_is_initialized =
true;
754 LibmeshPetscCall(SNESCreate(this->comm().get(), _snes.get()));
763 LibmeshPetscCall(SNESSetOptionsPrefix(_snes, name));
767#if defined(LIBMESH_ENABLE_AMR) && defined(LIBMESH_HAVE_METAPHYSICL)
769 "--" + (name ? std::string(name) : std::string(
"")) +
"use_petsc_dm");
773 this->_dm_wrapper.init_and_attach_petscdm(this->system(), _snes);
778 LibmeshPetscCall(DMCreate(this->comm().get(), dm.
get()));
779 LibmeshPetscCall(DMSetType(dm, DMLIBMESH));
783 LibmeshPetscCall(DMSetOptionsPrefix(dm, name));
785 LibmeshPetscCall(DMSetFromOptions(dm));
786 LibmeshPetscCall(DMSetUp(dm));
787 LibmeshPetscCall(SNESSetDM(_snes, dm));
791 setup_default_monitor();
795 if (this->_solver_configuration)
797 this->_solver_configuration->set_options_during_init();
800 if (this->_preconditioner)
803 LibmeshPetscCall(SNESGetKSP (_snes, &ksp));
805 LibmeshPetscCall(KSPGetPC(ksp,&pc));
807 this->_preconditioner->init();
809 LibmeshPetscCall(PCSetType(pc, PCSHELL));
810 LibmeshPetscCall(PCShellSetContext(pc,(
void *)this->_preconditioner));
823 if (this->postcheck || this->postcheck_object)
825 SNESLineSearch linesearch;
826 LibmeshPetscCall(SNESGetLineSearch(_snes, &linesearch));
831 if (this->precheck_object)
833 SNESLineSearch linesearch;
834 LibmeshPetscCall(SNESGetLineSearch(_snes, &linesearch));
856 parallel_object_only();
858 std::vector<NumericVector<Number> *> sp;
859 if (computeSubspaceObject)
860 (*computeSubspaceObject)(sp, this->system());
862 (*computeSubspace)(sp, this->system());
864 *msp = LIBMESH_PETSC_NULLPTR;
867 PetscInt nmodes = cast_int<PetscInt>(sp.size());
869 std::vector<Vec> modes(nmodes);
870 std::vector<PetscScalar> dots(nmodes);
872 for (PetscInt i=0; i<nmodes; ++i)
874 auto pv = cast_ptr<PetscVector<T> *>(sp[i]);
876 LibmeshPetscCall(VecDuplicate(pv->vec(), &modes[i]));
878 LibmeshPetscCall(VecCopy(pv->vec(), modes[i]));
882 LibmeshPetscCall(VecNormalize(modes[0], LIBMESH_PETSC_NULLPTR));
884 for (PetscInt i=1; i<nmodes; i++)
887 LibmeshPetscCall(VecMDot(modes[i], i, modes.data(), dots.data()));
889 for (PetscInt j=0; j<i; j++)
892 LibmeshPetscCall(VecMAXPY(modes[i], i, dots.data(), modes.data()));
894 LibmeshPetscCall(VecNormalize(modes[i], LIBMESH_PETSC_NULLPTR));
897 LibmeshPetscCall(MatNullSpaceCreate(this->comm().get(), PETSC_FALSE, nmodes, modes.data(), msp));
899 for (PetscInt i=0; i<nmodes; ++i)
900 LibmeshPetscCall(VecDestroy(&modes[i]));
905std::pair<unsigned int, Real>
910 const unsigned int m_its)
912 return this->solve(pre_in, pre_in, x_in, r_in, tol, m_its);
916std::pair<unsigned int, Real>
924 parallel_object_only();
926 LOG_SCOPE(
"solve()",
"PetscNonlinearSolver");
935 PetscInt n_iterations =0;
937 Real final_residual_norm=0.;
941 if ((reuse_preconditioner()) && (!_setup_reuse))
944 LibmeshPetscCall(SNESSetLagPreconditionerPersists(_snes, PETSC_TRUE));
947 LibmeshPetscCall(SNESSetLagPreconditioner(_snes, -2));
954 else if (!(reuse_preconditioner()))
957 LibmeshPetscCall(SNESSetLagPreconditionerPersists(_snes, PETSC_FALSE));
960 _setup_reuse =
false;
961 LibmeshPetscCall(SNESMonitorCancel(_snes));
963 setup_default_monitor();
971 if (this->jacobian || this->jacobian_object || this->residual_and_jacobian_object)
976 LibmeshPetscCall(SNESGetKSP (_snes, &ksp));
980 LibmeshPetscCall(KSPSetTolerances (ksp, this->initial_linear_tolerance, PETSC_DEFAULT,
981 PETSC_DEFAULT, this->max_linear_iterations));
984 LibmeshPetscCall(SNESSetTolerances(_snes,
985 this->absolute_residual_tolerance,
986 this->relative_residual_tolerance,
987 this->relative_step_tolerance,
988 this->max_nonlinear_iterations,
989 this->max_function_evaluations));
992 if (this->absolute_step_tolerance != 0)
993 libmesh_warning(
"Setting the absolute step tolerance is not supported with the PETSc nonlinear solver.");
996#if !PETSC_VERSION_LESS_THAN(3,8,0)
997 LibmeshPetscCall(SNESSetDivergenceTolerance(_snes, this->divergence_tolerance));
1001#if PETSC_VERSION_LESS_THAN(3,7,0)
1002 LibmeshPetscCall(KSPSetFromOptions(ksp));
1004 LibmeshPetscCall(SNESSetFromOptions(_snes));
1007 LibmeshPetscCall(KSPGetPC(ksp, &pc));
1010#if defined(LIBMESH_HAVE_PETSC_HYPRE) && PETSC_VERSION_LESS_THAN(3, 23, 0) && \
1011 !PETSC_VERSION_LESS_THAN(3, 12, 0) && defined(PETSC_HAVE_HYPRE_DEVICE)
1014 LibmeshPetscCallExternal(HYPRE_Initialize);
1015 PetscScalar * dummyarray;
1017 LibmeshPetscCall(VecGetArrayAndMemType(x->vec(), &dummyarray, &mtype));
1018 LibmeshPetscCall(VecRestoreArrayAndMemType(x->vec(), &dummyarray));
1019 if (PetscMemTypeHost(mtype))
1020 LibmeshPetscCallExternal(HYPRE_SetMemoryLocation, HYPRE_MEMORY_HOST);
1024 if (this->user_presolve)
1025 this->user_presolve(this->system());
1028 if (this->_preconditioner)
1030 this->_preconditioner->set_matrix(pre_in);
1031 this->_preconditioner->init();
1036 if (this->_solver_configuration)
1037 this->_solver_configuration->configure_solver();
1051#if !PETSC_VERSION_LESS_THAN(3,6,0)
1052 LibmeshPetscCall(SNESSetSolution(_snes, x->vec()));
1054 LibmeshPetscCall(SNESSetUp(_snes));
1057 LibmeshPetscCall(SNESGetJacobian(_snes, &J, &P,
1058 LIBMESH_PETSC_NULLPTR,
1059 LIBMESH_PETSC_NULLPTR));
1061#if !PETSC_VERSION_LESS_THAN(3,8,4)
1068 LibmeshPetscCall(MatSNESMFSetReuseBase(J, PETSC_FALSE));
1071 LibmeshPetscCall(MatSNESMFSetReuseBase(J,
static_cast<PetscBool
>(_snesmf_reuse_base)));
1076 if (this->nullspace || this->nullspace_object)
1079 this->build_mat_null_space(this->nullspace_object, this->nullspace, msp.
get());
1082 LibmeshPetscCall(MatSetNullSpace(J, msp));
1084 LibmeshPetscCall(MatSetNullSpace(P, msp));
1089 if (this->transpose_nullspace || this->transpose_nullspace_object)
1091#if PETSC_VERSION_LESS_THAN(3,6,0)
1092 libmesh_warning(
"MatSetTransposeNullSpace is only supported for PETSc >= 3.6, transpose nullspace will be ignored.");
1095 this->build_mat_null_space(this->transpose_nullspace_object, this->transpose_nullspace, msp.
get());
1098 LibmeshPetscCall(MatSetTransposeNullSpace(J, msp));
1100 LibmeshPetscCall(MatSetTransposeNullSpace(P, msp));
1106 if (this->nearnullspace || this->nearnullspace_object)
1109 this->build_mat_null_space(this->nearnullspace_object, this->nearnullspace, msp.
get());
1113 LibmeshPetscCall(MatSetNearNullSpace(J, msp));
1115 LibmeshPetscCall(MatSetNearNullSpace(P, msp));
1119 SNESLineSearch linesearch;
1120 if (linesearch_object)
1122 LibmeshPetscCall(SNESGetLineSearch(_snes, &linesearch));
1123 LibmeshPetscCall(SNESLineSearchSetType(linesearch, SNESLINESEARCHSHELL));
1124#if PETSC_RELEASE_GREATER_EQUALS(3, 21, 0)
1131 LibmeshPetscCall(SNESSolve (_snes, LIBMESH_PETSC_NULLPTR, x->vec()));
1133 LibmeshPetscCall(SNESGetIterationNumber(_snes, &n_iterations));
1135 LibmeshPetscCall(SNESGetLinearSolveIterations(_snes, &_n_linear_iterations));
1142 LibmeshPetscCall(SNESGetFunction(_snes, &f, 0, 0));
1143 LibmeshPetscCall(VecNorm(f, NORM_2,
pPR(&final_residual_norm)));
1146 LibmeshPetscCall(SNESGetConvergedReason(_snes, &_reason));
1149 this->converged = (_reason >= 0);
1155 return std::make_pair(n_iterations, final_residual_norm);
1160template <
typename T>
1164 libMesh::out <<
"Nonlinear solver convergence/divergence reason: "
1165 << SNESConvergedReasons[this->get_converged_reason()] << std::endl;
1170template <
typename T>
1174 LibmeshPetscCall(SNESGetConvergedReason(_snes, &_reason));
1179template <
typename T>
1182 return _n_linear_iterations;
1185template <
typename T>
1188 if (_default_monitor)
1193template <
typename T>
1196 return this->_reuse_preconditioner;
1199template <
typename T>
1202 return this->_reuse_preconditioner_max_linear_its;
1205template <
typename T>
1209 this->_is_initialized =
false;
1211 _setup_reuse =
false;
processor_id_type size() const
void enforce_constraints_on_residual(const NonlinearImplicitSystem &system, NumericVector< Number > *rhs, NumericVector< Number > const *solution, bool homogeneous=true) const
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.
void enforce_constraints_on_jacobian(const NonlinearImplicitSystem &system, SparseMatrix< Number > *jac) const
const SparseMatrix< Number > & get_system_matrix() const
virtual void jacobian(const NumericVector< Number > &X, SparseMatrix< Number > &J, sys_type &S)=0
Jacobian function.
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 precheck(const NumericVector< Number > &precheck_soln, NumericVector< Number > &search_direction, bool &changed, sys_type &S)=0
Abstract precheck method that users must override.
virtual void residual(const NumericVector< Number > &X, NumericVector< Number > &R, sys_type &S)=0
Residual function.
virtual void residual_and_jacobian(const NumericVector< Number > &X, NumericVector< Number > *R, SparseMatrix< Number > *J, sys_type &S)=0
Residual & Jacobian function, calculated simultaneously.
Callable abstract base class to be used as a callback to provide the solver with a basis for the syst...
Manages consistently variables, degrees of freedom, coefficient vectors, matrices and non-linear solv...
This base class can be inherited from to provide interfaces to nonlinear solvers from different packa...
const sys_type & system() const
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...
NonlinearImplicitSystem::ComputeResidual * mffd_residual_object
Object that computes the residual R(X) of the nonlinear system at the input iterate X for the purpose...
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...
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.
NonlinearImplicitSystem::ComputeResidual * residual_object
Object that computes the residual R(X) of the nonlinear system at the input iterate X.
bool _exact_constraint_enforcement
Whether we should enforce exact constraints globally during a solve.
NonlinearImplicitSystem::ComputeJacobian * jacobian_object
Object that computes the Jacobian J(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.
NonlinearImplicitSystem::ComputePreCheck * precheck_object
NonlinearImplicitSystem::ComputePostCheck * postcheck_object
A callable object that is executed after each nonlinear iteration.
NonlinearImplicitSystem::ComputeResidualandJacobian * residual_and_jacobian_object
Object that computes either the residual or the Jacobian of the nonlinear system at the input itera...
NonlinearImplicitSystem::ComputeResidual * fd_residual_object
Object that computes the residual R(X) of the nonlinear system at the input iterate X for the purpose...
Provides a uniform interface to vector storage schemes for different linear algebra libraries.
const Parallel::Communicator & comm() const
This class allows to use a PETSc shell matrix as a PetscMatrix.
void assign(Mat m, bool set_context)
Adopt an existing, externally-owned Mat, without destroying it when this object goes out of scope.
This class provides a nice interface to the PETSc C-based data structures for parallel,...
static PetscMatrixBase< T > * get_context(Mat mat, const TIMPI::Communicator &comm)
virtual void close() override
Calls the SparseMatrix's internal assembly routines, ensuring that the values are consistent across p...
This class provides an interface to PETSc iterative solvers that is compatible with the libMesh Nonli...
virtual void clear() override
Release all memory and clear data structures.
unsigned _current_nonlinear_iteration_number
Stores the current nonlinear iteration number.
bool snes_mf_reuse_base() const
virtual int get_total_linear_iterations() override
Get the total number of linear iterations done in the last solve.
bool computing_base_vector() const
std::unique_ptr< ComputeLineSearchObject > linesearch_object
A callable object that can be used to specify a custom line-search.
virtual std::pair< unsigned int, Real > solve(SparseMatrix< T > &pre_in, NumericVector< T > &, NumericVector< T > &, const double, const unsigned int) override
Call the Petsc solver, using the same matrix for the system and preconditioner matrices.
void setup_default_monitor()
Setup the default monitor if required.
bool _zero_out_residual
true to zero out residual before going into application level call-back, otherwise false
void set_computing_base_vector(bool computing_base_vector)
Set whether we are computing the base vector for matrix-free finite-differencing.
bool _zero_out_jacobian
true to zero out jacobian before going into application level call-back, otherwise false
virtual void init(const char *name=nullptr) override
Initialize data structures if not done so already.
bool reproducible_residual() const
virtual void print_converged_reason() override
Prints a useful message about why the latest nonlinear solve con(di)verged.
void build_mat_null_space(NonlinearImplicitSystem::ComputeVectorSubspace *computeSubspaceObject, void(*)(std::vector< NumericVector< Number > * > &, sys_type &), MatNullSpace *)
virtual bool reuse_preconditioner() const override
Getter for preconditioner reuse.
virtual void force_new_preconditioner() override
Immediately force a new preconditioner, even if reuse is set.
SNESConvergedReason get_converged_reason()
SNES snes(const char *name=nullptr)
virtual unsigned int reuse_preconditioner_max_linear_its() const override
Getter for the maximum iterations flag for preconditioner reuse.
~PetscNonlinearSolver()
Destructor.
PetscNonlinearSolver(sys_type &system)
Constructor.
static void set_petsc_aux_data(PC &pc, System &sys, const unsigned v=0)
Builds PETSc auxiliary data needed by preconditioners such as hypre ams/ads.
This class provides a nice interface to PETSc's Vec object.
virtual void close() override
Calls the NumericVector's internal assembly routines, ensuring that the values are consistent across ...
virtual void zero() override
Set all entries to zero.
PetscNonlinearSolver< Number > * solver
ResidualContext(PetscNonlinearSolver< Number > *solver_in, NonlinearImplicitSystem &sys_in)
NonlinearImplicitSystem & sys
void attach_dof_map(const DofMap &dof_map)
Set a pointer to the DofMap to use.
virtual void zero()=0
Set all entries to 0.
std::unique_ptr< NumericVector< Number > > current_local_solution
All the values I need to compute my contribution to the simulation at hand.
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
virtual void update()
Update the local values to reflect the solution on neighboring processors.
const DofMap & get_dof_map() const
The libMesh namespace provides an interface to certain functionality in the library.
PetscFunctionReturn(LIBMESH_PETSC_SUCCESS)
PetscErrorCode libmesh_petsc_snes_jacobian(SNES, Vec x, Mat jac, Mat pc, void *ctx)
PetscErrorCode libmesh_petsc_linesearch_shellfunc(SNESLineSearch linesearch, void *ctx)
PetscErrorCode libmesh_petsc_snes_postcheck(SNESLineSearch, Vec x, Vec y, Vec w, PetscBool *changed_y, PetscBool *changed_w, void *context)
ResidualContext libmesh_petsc_snes_residual_helper(SNES snes, Vec x, void *ctx)
PetscErrorCode libmesh_petsc_snes_fd_residual(SNES, Vec x, Vec r, void *ctx)
PetscErrorCode libmesh_petsc_snes_residual(SNES, Vec x, Vec r, void *ctx)
PetscErrorCode libmesh_petsc_preconditioner_apply(PC pc, Vec x, Vec y)
PetscErrorCode libmesh_petsc_snes_monitor(SNES, PetscInt its, PetscReal fnorm, void *)
PetscErrorCode libmesh_petsc_snes_mffd_residual(SNES snes, Vec x, Vec r, void *ctx)
PetscErrorCode libmesh_petsc_preconditioner_setup(PC pc)
PetscErrorCode libmesh_petsc_recalculate_monitor(SNES snes, PetscInt it, PetscReal norm, void *mctx)
PetscErrorCode libmesh_petsc_snes_precheck(SNESLineSearch, Vec X, Vec Y, PetscBool *changed, void *context)
bool initialized()
Checks that library initialization has been done.
PetscErrorCode libmesh_petsc_snes_mffd_interface(void *ctx, Vec x, Vec r)
bool on_command_line(std::string arg)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
PETSC_EXTERN PetscErrorCode DMlibMeshSetSystem(DM, libMesh::NonlinearImplicitSystem &)
Any functional implementation of the DMlibMesh API must compose the following functions with the DM o...