# include <petscsnes.h>
# include <exception>
+
# if defined(DEAL_II_HAVE_CXX20)
# include <concepts>
# endif
* - deal.II style using NonlinearSolver::setup_jacobian and
* NonlinearSolver::solve_with_jacobian.
* The preconditioning matrix can be specified using
- * NonlinearSolver::set_matrix. In case both approaches are implemented, the
+ * NonlinearSolver::set_matrix(). In case both approaches are implemented, the
* deal.II style will be used.
*
- * NonlinearSolver::set_matrices must be used in case the user wants to
+ * NonlinearSolver::set_matrices() must be used in case the user wants to
* provide the iteration matrix of the tangent system in the deal.II style
* approach, thus replacing the matrix-free linearization.
*
* The correctness of the constructed Jacobians passed using
- * NonlinearSolver::set_matrix can be checked using
+ * NonlinearSolver::set_matrix() can be checked using
* @code
* ./myApp -snes_test_jacobian
* @endcode
- * See NonlinearSolver::set_matrix and NonlinearSolver::set_matrices for
+ * See NonlinearSolver::set_matrix() and NonlinearSolver::set_matrices() for
* additional details.
*
* The deal.II style approach still allows command line customization, like
get_mpi_communicator() const;
/**
- * Reset the solver. It does not change the customization.
+ * Reset the solver, it does not change the customization.
*/
void
reinit();
/**
- * Reset solver. Change customization according to @p data.
+ * Reset solver.
+ * Change customization according to @p data.
*/
void
reinit(const NonlinearSolverData &data);
* Callback for monitoring the solution process.
*
* This function is called by NonlinearSolver at the beginning
- * of each time step. Input arguments are the current step number
- * and the current value for ||F(x)||.
+ * of each step. Input arguments are the current step number
+ * and the current value for $||F(x)||$.
*
* @note This variable represents a
* @ref GlossUserProvidedCallBack "user provided callback".
monitor;
/**
- * Callback to set up the Jacobian system.
+ * Callback for the set up of the Jacobian system.
*
* This callback gives full control to users to set up the tangent
* operator $\dfrac{\partial F}{\partial x}$.
PMatrixType,
Mat>)&&(concepts::is_dealii_petsc_matrix_type<AMatrixType> ||
std::constructible_from<AMatrixType, Mat>))
- MPI_Comm NonlinearSolver<VectorType, PMatrixType, AMatrixType>::
+ inline MPI_Comm NonlinearSolver<VectorType, PMatrixType, AMatrixType>::
get_mpi_communicator() const
{
return PetscObjectComm(reinterpret_cast<PetscObject>(snes));
PetscFunctionBeginUser;
auto user = static_cast<NonlinearSolver *>(ctx);
- VectorType xdealii(x);
- AMatrixType Adealii(A);
- PMatrixType Pdealii(P);
+ VectorType xdealii(x);
- user->A = &Adealii;
- user->P = &Pdealii;
const int lineno = __LINE__;
const int err = call_and_possibly_capture_snes_exception(
user->setup_jacobian,
PETSC_ERR_LIB,
PETSC_ERROR_INITIAL,
"Failure in snes_jacobian_with_setup from dealii::PETScWrappers::NonlinearSolver");
+ // The MatCopy calls below are 99% of the times dummy calls.
+ // They are only used in case we get different Mats then the one we passed
+ // to SNESSetJacobian.
+ if (user->P)
+ PetscCall(MatCopy(user->P->petsc_matrix(), P, SAME_NONZERO_PATTERN));
+ if (user->A)
+ PetscCall(MatCopy(user->A->petsc_matrix(), A, SAME_NONZERO_PATTERN));
petsc_increment_state_counter(P);
// Handle older versions of PETSc for which we cannot pass a MATSHELL
VectorType xdealii(x);
const int lineno = __LINE__;
const int err = call_and_possibly_capture_snes_exception(
- user->monitor,
- user->pending_exception,
- []() -> void {},
- xdealii,
- it,
- f);
+ user->monitor, user->pending_exception, {}, xdealii, it, f);
if (err)
return PetscError(
PetscObjectComm((PetscObject)snes),
P ? P->petsc_matrix() : nullptr,
snes_jacobian_with_setup,
this));
+
+ // Tell PETSc to set up a MFFD operator for the linear system matrix
if (!A)
set_use_matrix_free(snes, true, false);
-
// Do not waste memory by creating a dummy AIJ matrix inside PETSc.
if (!P)
{
}
// In case solve_with_jacobian is provided, create a shell
- // preconditioner wrapping the user call. The internal Krylov
- // solver will apply the preconditioner only once. This choice
+ // preconditioner wrapping the user call. The default internal Krylov
+ // solver only applies the preconditioner. This choice
// can be overridden by command line and users can use any other
// Krylov method if their solve is not accurate enough.
// Using solve_with_jacobian as a preconditioner allows users
}
} // namespace PETScWrappers
+
# undef AssertPETSc
# if defined(undefPetscCall)
# undef PetscCall
# undef undefPetscCall
# endif
+
DEAL_II_NAMESPACE_CLOSE
#endif // DEAL_II_WITH_PETSC
CHKERRQ(ierr); \
} \
while (0)
+# define undefPetscCall
# endif
namespace PETScWrappers
user->need_dummy_assemble = false;
// Handle the Jacobian-free case
- // This call allow to resample the linearization point
+ // This call allows to resample the linearization point
// of the MFFD tangent operator
PetscBool flg;
PetscCall(PetscObjectTypeCompare((PetscObject)A, MATMFFD, &flg));
// solver only applies the preconditioner. This choice
// can be overridden by command line and users can use any other
// Krylov method if their solve is not accurate enough.
- // Using solve_with_jacobian as a preconditioner allow users
+ // Using solve_with_jacobian as a preconditioner allows users
// to provide approximate solvers and possibly iterate on a matrix-free
// approximation of the tangent operator.
if (solve_with_jacobian)