10#include "libmesh/petsc_macro.h"
24#include "libmesh/libmesh_common.h"
25#include "libmesh/petsc_nonlinear_solver.h"
26#include "libmesh/coupling_matrix.h"
30template <
typename Base>
38 "topsplit",
"Entrance to splits, the top split will specify how splits will go.");
42 "Set to true if you want the full set of couplings between variables "
43 "simply for convenience so you don't have to set every off_diag_row "
44 "and off_diag_column combination.");
48template <
typename Base>
52 _nl(this->_fe_problem.getNonlinearSystemBase(this->_nl_sys_num)),
53 _decomposition_split(this->template getParam<
std::string>(
"topsplit"))
56 mooseError(
"The field split preconditioner can only be used with PETSc");
59 unsigned int n_vars = _nl.nVariables();
63 bool full = this->
template getParam<bool>(
"full");
66 std::unique_ptr<CouplingMatrix> cm = std::make_unique<CouplingMatrix>(n_vars);
69 if (this->isParamValid(
"off_diag_row") && this->isParamValid(
"off_diag_column"))
72 const auto off_diag_rows =
73 this->
template getParam<std::vector<NonlinearVariableName>>(
"off_diag_row");
74 const auto off_diag_columns =
75 this->
template getParam<std::vector<NonlinearVariableName>>(
"off_diag_column");
78 for (
unsigned int i = 0; i <
n_vars; i++)
82 std::vector<std::vector<unsigned int>> off_diag(n_vars);
83 if (off_diag_rows.size() * off_diag_columns.size() != 0 &&
84 off_diag_rows.size() == off_diag_columns.size())
87 unsigned int row = _nl.getVariable(0, off_diag_rows[i]).number();
88 unsigned int column = _nl.getVariable(0, off_diag_columns[i]).number();
89 (*cm)(row, column) = 1;
95 for (
unsigned int i = 0; i <
n_vars; i++)
96 for (
unsigned int j = 0; j <
n_vars; j++)
99 this->setCouplingMatrix(std::move(cm));
102 _nl.useFieldSplitPreconditioner(
this);
105template <
typename Base>
111 DMCreateMoose(_nl.comm().get(), _nl, dofMap(), system(), _decomposition_split,
dm));
112 LibmeshPetscCallA(_nl.comm().get(),
113 PetscObjectSetOptionsPrefix((PetscObject)*
dm, prefix().c_str()));
114 LibmeshPetscCall(DMSetFromOptions(*
dm));
115 LibmeshPetscCall(DMSetUp(*
dm));
137 DM
dm = LIBMESH_PETSC_NULLPTR;
143 auto *
const petsc_solver =
145 SNES snes = petsc_solver->snes(
prefix().c_str());
147 LibmeshPetscCall(SNESGetDM(snes, &
dm));
150 LibmeshPetscCall(PetscObjectTypeCompare((PetscObject)
dm, DMMOOSE, &ismoose));
155 LibmeshPetscCall(SNESSetDM(snes,
dm));
156 LibmeshPetscCall(DMDestroy(&
dm));
182 LibmeshPetscCall(SNESGetKSP(snes, &ksp));
registerMooseObjectAliased("MooseApp", FieldSplitPreconditioner, "FSP")
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
PetscErrorCode PetscOptionItems *PetscErrorCode DM dm
PetscErrorCode DMCreateMoose(MPI_Comm comm, NonlinearSystemBase &nl, const libMesh::DofMapBase &dof_map, const libMesh::System &system, const std::string &dm_name, DM *dm)
Create a MOOSE DM.
PetscErrorCode DMMooseRegisterAll()
Implements a preconditioner designed to map onto PETSc's PCFieldSplit.
FieldSplitPreconditionerTempl(const InputParameters ¶meters)
static InputParameters validParams()
Constructor.
std::string _decomposition_split
The decomposition split.
NonlinearSystemBase & _nl
The nonlinear system this FSP is associated with (convenience reference)
void createMooseDM(DM *dm)
creates the MOOSE data management object
virtual void setupDM() override
setup the data management data structure that manages the field split
virtual const libMesh::System & system() const override
virtual std::string prefix() const override
static InputParameters validParams()
virtual const libMesh::DofMapBase & dofMap() const override
FieldSplitPreconditioner(const InputParameters ¶meters)
virtual KSP getKSP() override
Base class for MOOSE preconditioners.
std::shared_ptr< Split > getSplit(const std::string &name)
Retrieves a split by name.
virtual libMesh::NonlinearSolver< Number > * nonlinearSolver()=0
virtual libMesh::System & system() override
Get the reference to the libMesh system.
std::string prefix() const
virtual libMesh::DofMap & dofMap()
Gets writeable reference to the dof map.
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
auto index_range(const T &sizable)
SolverPackage default_solver_package()