https://mooseframework.inl.gov
Loading...
Searching...
No Matches
FieldSplitPreconditioner.C
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://mooseframework.inl.gov
3//*
4//* All rights reserved, see COPYRIGHT for full restrictions
5//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6//*
7//* Licensed under LGPL 2.1, please see LICENSE for details
8//* https://www.gnu.org/licenses/lgpl-2.1.html
9
10#include "libmesh/petsc_macro.h"
12
13// MOOSE includes
14#include "FEProblem.h"
15#include "MooseEnum.h"
16#include "MooseVariableFE.h"
17#include "NonlinearSystem.h"
18#include "PetscSupport.h"
19#include "MoosePreconditioner.h"
21#include "Split.h"
22#include "PetscDMMoose.h"
23
24#include "libmesh/libmesh_common.h"
25#include "libmesh/petsc_nonlinear_solver.h"
26#include "libmesh/coupling_matrix.h"
27
28template <typename Base>
31{
32 InputParameters params = Base::validParams();
33 params.addClassDescription("Preconditioner designed to map onto PETSc's PCFieldSplit.");
34
35 params.addRequiredParam<std::string>(
36 "topsplit", "Entrance to splits, the top split will specify how splits will go.");
37 // We should use full coupling Jacobian matrix by default
38 params.addParam<bool>("full",
39 true,
40 "Set to true if you want the full set of couplings between variables "
41 "simply for convenience so you don't have to set every off_diag_row "
42 "and off_diag_column combination.");
43 return params;
44}
45
46template <typename Base>
48 const InputParameters & parameters)
49 : Base(parameters),
50 _nl(this->_fe_problem.getNonlinearSystemBase(this->_nl_sys_num)),
51 _decomposition_split(this->template getParam<std::string>("topsplit"))
52{
54 mooseError("The field split preconditioner can only be used with PETSc");
55
56 // number of variables
57 unsigned int n_vars = _nl.nVariables();
58 // if we want to construct a full Jacobian?
59 // it is recommended to have a full Jacobian for using
60 // the fieldSplit preconditioner
61 bool full = this->template getParam<bool>("full");
62
63 // how variables couple
64 std::unique_ptr<CouplingMatrix> cm = std::make_unique<CouplingMatrix>(n_vars);
65 if (!full)
66 {
67 if (this->isParamValid("off_diag_row") && this->isParamValid("off_diag_column"))
68 {
69
70 const auto off_diag_rows =
71 this->template getParam<std::vector<NonlinearVariableName>>("off_diag_row");
72 const auto off_diag_columns =
73 this->template getParam<std::vector<NonlinearVariableName>>("off_diag_column");
74
75 // put 1s on diagonal
76 for (unsigned int i = 0; i < n_vars; i++)
77 (*cm)(i, i) = 1;
78
79 // off-diagonal entries
80 std::vector<std::vector<unsigned int>> off_diag(n_vars);
81 if (off_diag_rows.size() * off_diag_columns.size() != 0 &&
82 off_diag_rows.size() == off_diag_columns.size())
83 for (const auto i : index_range(off_diag_rows))
84 {
85 unsigned int row = _nl.getVariable(0, off_diag_rows[i]).number();
86 unsigned int column = _nl.getVariable(0, off_diag_columns[i]).number();
87 (*cm)(row, column) = 1;
88 }
89 }
90 }
91 else
92 {
93 for (unsigned int i = 0; i < n_vars; i++)
94 for (unsigned int j = 0; j < n_vars; j++)
95 (*cm)(i, j) = 1; // full coupling
96 }
97 this->setCouplingMatrix(std::move(cm));
98
99 // turn on a flag
101}
102
103template <typename Base>
104void
106{
107 LibmeshPetscCallA(
108 _nl.comm().get(),
109 DMCreateMoose(_nl.comm().get(), _nl, dofMap(), system(), _decomposition_split, dm));
110 LibmeshPetscCallA(_nl.comm().get(),
111 PetscObjectSetOptionsPrefix((PetscObject)*dm, prefix().c_str()));
112 LibmeshPetscCall(DMSetFromOptions(*dm));
113 LibmeshPetscCall(DMSetUp(*dm));
114}
115
117
123
126{
127 std::shared_ptr<Split> top_split = _nl.getSplit(_decomposition_split);
128 top_split->setup(_nl, _nl.prefix());
129}
130
131void
133{
134 PetscBool ismoose;
135 DM dm = LIBMESH_PETSC_NULLPTR;
136
137 // Initialize the part of the DM package that's packaged with Moose; in the PETSc source tree this
138 // call would be in DMInitializePackage()
139 LibmeshPetscCall(DMMooseRegisterAll());
140 // Create and set up the DM that will consume the split options and deal with block matrices.
141 auto * const petsc_solver =
142 cast_ptr<libMesh::PetscNonlinearSolver<Number> *>(_nl.nonlinearSolver());
143 SNES snes = petsc_solver->snes(prefix().c_str());
144 // if there exists a DMMoose object, not to recreate a new one
145 LibmeshPetscCall(SNESGetDM(snes, &dm));
146 if (dm)
147 {
148 LibmeshPetscCall(PetscObjectTypeCompare((PetscObject)dm, DMMOOSE, &ismoose));
149 if (ismoose)
150 return;
151 }
153 LibmeshPetscCall(SNESSetDM(snes, dm));
154 LibmeshPetscCall(DMDestroy(&dm));
155}
156
159{
160 return _nl.dofMap();
161}
162
163const System &
165{
166 return _nl.system();
167}
168
169std::string
171{
172 return _nl.prefix();
173}
174
175KSP
177{
178 KSP ksp;
179 auto snes = _nl.getSNES();
180 LibmeshPetscCall(SNESGetKSP(snes, &ksp));
181 return ksp;
182}
183
registerMooseObjectAliased("MooseApp", FieldSplitPreconditioner, "FSP")
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
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()
unsigned int n_vars
Implements a preconditioner designed to map onto PETSc's PCFieldSplit.
FieldSplitPreconditionerTempl(const InputParameters &parameters)
static InputParameters validParams()
Constructor.
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()
FieldSplitPreconditioner(const InputParameters &parameters)
virtual const libMesh::DofMapBase & dofMap() const override
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an optional parameter and a documentation string to the InputParameters object.
void addRequiredParam(const std::string &name, const std::string &doc_string)
This method adds a parameter and documentation string to the InputParameters object that will be extr...
void addClassDescription(const std::string &doc_string)
This method adds a description of the class that will be displayed in the input file syntax dump.
Base class for MOOSE preconditioners.
unsigned int number() const
Get variable number coming from libMesh.
virtual SNES getSNES()=0
void useFieldSplitPreconditioner(FieldSplitPreconditionerBase *fsp)
If called with a non-null object true this system will use a field split preconditioner matrix.
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 unsigned int nVariables() const
Get the number of variables in this system.
Definition SystemBase.C:890
MooseVariableFieldBase & getVariable(THREAD_ID tid, const std::string &var_name) const
Gets a reference to a variable of with specified name.
Definition SystemBase.C:89
virtual libMesh::DofMap & dofMap()
Gets writeable reference to the dof map.
SolverPackage default_solver_package()