20 #include "libmesh/libmesh_common.h" 21 #include "libmesh/equation_systems.h" 22 #include "libmesh/nonlinear_implicit_system.h" 23 #include "libmesh/nonlinear_solver.h" 24 #include "libmesh/linear_implicit_system.h" 25 #include "libmesh/transient_system.h" 26 #include "libmesh/numeric_vector.h" 27 #include "libmesh/sparse_matrix.h" 28 #include "libmesh/string_to_enum.h" 29 #include "libmesh/coupling_matrix.h" 40 params.
addClassDescription(
"Physics-based preconditioner (PBP) allows individual physics to have " 41 "their own preconditioner.");
45 "The order the block rows will be solved in. Put the name of variables here " 46 "to stand for solving that variable's block row. A variable may appear more " 47 "than once (to create cylces if you like).");
48 params.
addRequiredParam<std::vector<std::string>>(
"preconditioner",
"TODO: docstring");
56 _nl(_fe_problem.getNonlinearSystemBase(_nl_sys_num))
58 const auto & libmesh_system =
_nl.
system();
71 std::unique_ptr<CouplingMatrix> cm = std::make_unique<CouplingMatrix>(
n_vars);
73 bool full = getParam<bool>(
"full");
78 for (
unsigned int i = 0; i <
n_vars; i++)
82 for (
const auto & off_diag : getParam<NonlinearVariableName, NonlinearVariableName>(
83 "off_diag_row",
"off_diag_column"))
85 const auto row = libmesh_system.variable_number(off_diag.first);
86 const auto column = libmesh_system.variable_number(off_diag.second);
87 (*cm)(row, column) = 1;
94 for (
unsigned int i = 0; i <
n_vars; i++)
95 for (
unsigned int j = 0; j <
n_vars; j++)
103 const std::vector<std::string> & pc_types = getParam<std::vector<std::string>>(
"preconditioner");
104 for (
unsigned int i = 0; i < num_systems; i++)
105 _pre_type[i] = Utility::string_to_enum<PreconditionerType>(pc_types[i]);
108 const std::vector<std::string> & solve_order = getParam<std::vector<std::string>>(
"solve_order");
117 std::vector<std::vector<unsigned int>> off_diag(
n_vars);
120 const std::vector<NonlinearVariableName> & odr =
121 getParam<std::vector<NonlinearVariableName>>(
"off_diag_row");
122 const std::vector<NonlinearVariableName> & odc =
123 getParam<std::vector<NonlinearVariableName>>(
"off_diag_column");
129 off_diag[row].push_back(column);
133 for (
unsigned int var = 0; var <
n_vars; var++)
139 mooseError(
"PBP must be used with JFNK solve type");
146 std::vector<unsigned int> off_diag,
175 TIME_SECTION(
"init", 2,
"Initializing PhysicsBasedPreconditioner");
180 const unsigned int num_systems =
_systems.size();
186 for (
unsigned int i = 0; i < num_systems; i++)
191 for (
unsigned int system_var = 0; system_var < num_systems; system_var++)
205 preconditioner->
init();
212 const unsigned int num_systems =
_systems.size();
214 std::vector<JacobianBlock *>
blocks;
217 for (
unsigned int system_var = 0; system_var < num_systems; system_var++)
229 unsigned int coupled_var =
_off_diag[system_var][diag];
241 for (
auto & block :
blocks)
248 TIME_SECTION(
"apply", 1,
"Applying PhysicsBasedPreconditioner");
250 const unsigned int num_systems =
_systems.size();
255 for (
unsigned int sys = 0; sys < num_systems; sys++)
273 unsigned int coupled_var =
_off_diag[system_var][diag];
302 for (
unsigned int system_var = 0; system_var < num_systems; system_var++)
virtual void setup()
This is called every time the "operator might have changed".
virtual const std::set< SubdomainID > * getVariableBlocks(unsigned int var_number)
Get the block where a variable of this system is defined.
Helper class for holding the preconditioning blocks to fill.
virtual void apply(const NumericVector< Number > &x, NumericVector< Number > &y)
Computes the preconditioned vector "y" based on input "x".
static void copyVarValues(MeshBase &mesh, const unsigned int from_system, const unsigned int from_var, const NumericVector< Number > &from_vector, const unsigned int to_system, const unsigned int to_var, NumericVector< Number > &to_vector)
Helper function for copying values associated with variables in vectors from two different systems...
std::vector< std::vector< unsigned int > > _off_diag
Holds which off diagonal blocks to compute.
const Variable & variable(unsigned int var) const
std::vector< libMesh::LinearImplicitSystem * > _systems
List of linear system that build up the preconditioner.
std::vector< libMesh::PreconditionerType > _pre_type
Which preconditioner to use for each solve.
PreconditionerType type() const
NonlinearSystemBase & _nl
The nonlinear system this PBP is associated with (convenience reference)
NumericVector< Number > * rhs
void set_matrix(SparseMatrix< Number > &mat)
FEProblemBase & _fe_problem
Subproblem this preconditioner is part of.
const Parallel::Communicator & _communicator
virtual void attachPreconditioner(libMesh::Preconditioner< Number > *preconditioner)=0
Attach a customized preconditioner that requires physics knowledge.
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
virtual void clear()
Release all memory and clear data structures.
Base class for MOOSE preconditioners.
unsigned int variable_number(std::string_view var) const
virtual void init()
Initialize data structures if not done so already.
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
virtual unsigned int nVariables() const
Get the number of variables in this system.
virtual void computeJacobianBlocks(std::vector< JacobianBlock *> &blocks, const unsigned int nl_sys_num)
Computes several Jacobian blocks simultaneously, summing their contributions into smaller preconditio...
virtual void scale(const T factor)=0
unsigned int number() const
static InputParameters validParams()
Constructor.
const std::string _type
The type of this class.
virtual ~PhysicsBasedPreconditioner()
PhysicsBasedPreconditioner(const InputParameters ¶ms)
Jacobian-Free Newton Krylov.
virtual libMesh::EquationSystems & es() override
std::unique_ptr< NumericVector< Number > > solution
MooseMesh wraps a libMesh::Mesh object and enhances its capabilities by caching additional data and s...
Implements a segregated solve preconditioner.
unsigned int add_variable(std::string_view var, const FEType &type, const std::set< subdomain_id_type > *const active_subdomains=nullptr)
const std::string & variable_name(const unsigned int i) const
static InputParameters validParams()
unsigned int number() const
Gets the number of this system.
std::vector< std::vector< libMesh::SparseMatrix< Number > * > > _off_diag_mats
Holds pointers to the off-diagonal matrices.
void vector_mult_add(NumericVector< T > &dest, const NumericVector< T > &arg) const
virtual MooseMesh & mesh() override
std::vector< unsigned int > _solve_order
Holds the order the blocks are solved for.
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type.
SolverParams & solverParams(unsigned int solver_sys_num=0)
Get the solver parameters.
void setCouplingMatrix(std::unique_ptr< libMesh::CouplingMatrix > cm)
Setup the coupling matrix on the finite element problem.
void set_type(const PreconditionerType pct)
std::vector< std::unique_ptr< libMesh::Preconditioner< Number > > > _preconditioners
Holds one Preconditioner object per small system to solve.
registerMooseObjectAliased("MooseApp", PhysicsBasedPreconditioner, "PBP")
unsigned int n_vars() const
virtual System & add_system(std::string_view system_type, std::string_view name)
bool assemble_before_solve
SparseMatrix< Number > & add_matrix(std::string_view mat_name, ParallelType type=PARALLEL, MatrixBuildType mat_build_type=MatrixBuildType::AUTOMATIC)
void addSystem(unsigned int var, std::vector< unsigned int > off_diag, libMesh::PreconditionerType type=libMesh::AMG_PRECOND)
Add a diagonal system + possibly off-diagonals ones as well, also specifying type of preconditioning...
const SparseMatrix< Number > & get_system_matrix() const
auto index_range(const T &sizable)
const FEType & type() const
virtual libMesh::System & system() override
Get the reference to the libMesh system.