www.mooseframework.org
MoosePreconditioner.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
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 // MOOSE includes
11 #include "MoosePreconditioner.h"
12 #include "FEProblem.h"
13 #include "PetscSupport.h"
14 #include "NonlinearSystem.h"
15 
16 #include "libmesh/coupling_matrix.h"
17 #include "libmesh/numeric_vector.h"
18 
21 {
23  params.addPrivateParam<FEProblemBase *>("_fe_problem_base");
24 
25  MooseEnum pc_side("left right symmetric default", "default");
26  params.addParam<MooseEnum>("pc_side", pc_side, "Preconditioning side");
27  MooseEnum ksp_norm("none preconditioned unpreconditioned natural default", "unpreconditioned");
28  params.addParam<MooseEnum>(
29  "ksp_norm", ksp_norm, "Sets the norm that is used for convergence testing");
30  params.registerBase("MoosePreconditioner");
31 
32  params.addParam<std::vector<NonlinearVariableName>>(
33  "off_diag_row",
34  "The variable names for the off-diagonal rows you want to add into the matrix; they will be "
35  "associated with an off-diagonal column from the same position in off_diag_column.");
36  params.addParam<std::vector<NonlinearVariableName>>(
37  "off_diag_column",
38  "The variable names for the off-diagonal columns you want to add into the matrix; they "
39  "will be associated with an off-diagonal row from the same position in off_diag_row.");
40  params.addParam<bool>("full",
41  false,
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.");
45  params.addParam<NonlinearSystemName>(
46  "nl_sys",
47  "The nonlinear system whose linearization this preconditioner should be applied to.");
48 
50 
51  return params;
52 }
53 
55  : MooseObject(params),
56  Restartable(this, "Preconditioners"),
57  PerfGraphInterface(this),
58  _fe_problem(*params.getCheckedPointerParam<FEProblemBase *>("_fe_problem_base")),
59  _nl_sys_num(
60  isParamValid("nl_sys") ? _fe_problem.nlSysNum(getParam<NonlinearSystemName>("nl_sys")) : 0),
61  _nl(_fe_problem.getNonlinearSystemBase(_nl_sys_num))
62 {
63  _nl.setPCSide(getParam<MooseEnum>("pc_side"));
64 
65  _nl.setMooseKSPNormType(getParam<MooseEnum>("ksp_norm"));
66 
67  bool full = getParam<bool>("full");
68 
69  // We either have a full coupling or a custom coupling
70  if (full && isParamValid("off_diag_row"))
71  paramError("off_diag_row", "Set full=false to specify the off-diagonal rows manually");
72  if (full && isParamValid("off_diag_column"))
73  paramError("off_diag_column", "Set full=false to specify the off-diagonal columns manually");
74 
75  // Off-diagonal rows and colums must match
76  if (isParamValid("off_diag_row"))
77  {
78  if (isParamValid("off_diag_column"))
79  {
80  const auto off_diag =
81  getParam<NonlinearVariableName, NonlinearVariableName>("off_diag_row", "off_diag_column");
82  }
83  else
84  paramError("off_diag_row",
85  "If off-diagonal rows are specified, matching off-diagonal "
86  "columns must be specified as well");
87  }
88  else if (isParamValid("off_diag_column"))
89  paramError("off_diag_column",
90  "If off-diagonal columns are specified, matching off-diagonal "
91  "rows must be specified as well");
92 }
93 
94 void
96  const unsigned int from_system,
97  const unsigned int from_var,
98  const NumericVector<Number> & from_vector,
99  const unsigned int to_system,
100  const unsigned int to_var,
101  NumericVector<Number> & to_vector)
102 {
103  for (auto & node : mesh.local_node_ptr_range())
104  {
105  unsigned int n_comp = node->n_comp(from_system, from_var);
106 
107  mooseAssert(node->n_comp(from_system, from_var) == node->n_comp(to_system, to_var),
108  "Number of components does not match in each system");
109 
110  for (unsigned int i = 0; i < n_comp; i++)
111  {
112  dof_id_type from_dof = node->dof_number(from_system, from_var, i);
113  dof_id_type to_dof = node->dof_number(to_system, to_var, i);
114 
115  to_vector.set(to_dof, from_vector(from_dof));
116  }
117  }
118 
119  for (auto & elem : as_range(mesh.local_elements_begin(), mesh.local_elements_end()))
120  {
121  unsigned int n_comp = elem->n_comp(from_system, from_var);
122 
123  mooseAssert(elem->n_comp(from_system, from_var) == elem->n_comp(to_system, to_var),
124  "Number of components does not match in each system");
125 
126  for (unsigned int i = 0; i < n_comp; i++)
127  {
128  dof_id_type from_dof = elem->dof_number(from_system, from_var, i);
129  dof_id_type to_dof = elem->dof_number(to_system, to_var, i);
130 
131  to_vector.set(to_dof, from_vector(from_dof));
132  }
133  }
134 }
135 
136 void
137 MoosePreconditioner::setCouplingMatrix(std::unique_ptr<CouplingMatrix> cm)
138 {
139  for (const auto i : make_range(_fe_problem.numNonlinearSystems()))
140  {
141  if (i == libMesh::cast_int<unsigned int>(_fe_problem.numNonlinearSystems() - 1))
142  // This is the last nonlinear system, so it's safe now to move the object
143  _fe_problem.setCouplingMatrix(std::move(cm), i);
144  else
145  _fe_problem.setCouplingMatrix(std::make_unique<CouplingMatrix>(*cm), i);
146  }
147 }
NonlinearSystemBase & _nl
The nonlinear system whose linearization this preconditioner should be applied to.
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...
A class for creating restricted objects.
Definition: Restartable.h:28
virtual std::size_t numNonlinearSystems() const override
void addPrivateParam(const std::string &name, const T &value)
These method add a parameter to the InputParameters object which can be retrieved like any other para...
MeshBase & mesh
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
void setPCSide(MooseEnum pcs)
Set the side on which the preconditioner is applied to.
Definition: SolverSystem.C:77
FEProblemBase & _fe_problem
Subproblem this preconditioner is part of.
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
void registerBase(const std::string &value)
This method must be called from every base "Moose System" to create linkage with the Action System...
MoosePreconditioner(const InputParameters &params)
Every object that can be built by the factory should be derived from this class.
Definition: MooseObject.h:33
void setCouplingMatrix(std::unique_ptr< CouplingMatrix > cm, const unsigned int nl_sys_num)
Set custom coupling matrix.
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition: MooseEnum.h:31
static InputParameters validParams()
void paramError(const std::string &param, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
Interface for objects interacting with the PerfGraph.
InputParameters getPetscValidParams()
Returns the PETSc options that are common between Executioners and Preconditioners.
Definition: PetscSupport.C:848
IntRange< T > make_range(T beg, T end)
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an option parameter and a documentation string to the InputParameters object...
virtual void set(const numeric_index_type i, const Number value)=0
static InputParameters validParams()
Definition: MooseObject.C:25
void setCouplingMatrix(std::unique_ptr< CouplingMatrix > cm)
Setup the coupling matrix on the finite element problem.
void setMooseKSPNormType(MooseEnum kspnorm)
Set the norm in which the linear convergence will be measured.
Definition: SolverSystem.C:92
uint8_t dof_id_type