https://mooseframework.inl.gov
Loading...
Searching...
No Matches
SingleMatrixPreconditioner.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
11
12// MOOSE includes
13#include "FEProblem.h"
14#include "MooseUtils.h"
15#include "MooseVariableFE.h"
16#include "NonlinearSystem.h"
17
18#include "libmesh/coupling_matrix.h"
19
21
24{
26
27 params.addClassDescription("Single matrix preconditioner (SMP) builds a preconditioner using "
28 "user defined off-diagonal parts of the Jacobian.");
29
30 params.addParam<std::vector<NonlinearVariableName>>(
31 "coupled_groups",
32 {},
33 "List multiple space separated groups of comma separated variables. "
34 "Off-diagonal jacobians will be generated for all pairs within a group.");
35 params.addParam<bool>(
36 "trust_my_coupling",
37 false,
38 "Whether to trust my coupling even if the framework wants to be paranoid and create a full "
39 "coupling matrix, which can happen when using global AD indexing for example.");
40
41 return params;
42}
43
45 : MoosePreconditioner(params)
46{
48 unsigned int n_vars = nl.nVariables();
49 const auto & libmesh_system = nl.system();
50 auto cm = std::make_unique<CouplingMatrix>(n_vars);
51
52 // NEWTON and LINEAR solves are best solved with the exact Jacobian, so default to the full
53 // coupling unless the user specified the coupling themselves. This matches the preconditioner
54 // that is created automatically when there is no [Preconditioning] block.
55 const auto solve_type = _fe_problem.solverParams(_nl_sys_num)._type;
56 const bool full = getParam<bool>("full") ||
57 (!isParamSetByUser("full") && !isParamValid("off_diag_row") &&
58 getParam<std::vector<NonlinearVariableName>>("coupled_groups").empty() &&
59 (solve_type == Moose::ST_NEWTON || solve_type == Moose::ST_LINEAR));
60
61 if (!full)
62 {
63 // put 1s on diagonal
64 for (unsigned int i = 0; i < n_vars; ++i)
65 (*cm)(i, i) = 1;
66
67 // off-diagonal entries from the off_diag_row and off_diag_column parameters
68 for (const auto & off_diag :
69 getParam<NonlinearVariableName, NonlinearVariableName>("off_diag_row", "off_diag_column"))
70 {
71 const auto row = libmesh_system.variable_number(off_diag.first);
72 const auto column = libmesh_system.variable_number(off_diag.second);
73 (*cm)(row, column) = 1;
74 }
75
76 // off-diagonal entries from the coupled_groups parameters
77 const auto & all_vars = nl.getVariableNames();
78 for (const auto & group : getParam<std::vector<NonlinearVariableName>>("coupled_groups"))
79 {
80 std::vector<VariableName> vars;
81 MooseUtils::tokenize(group, vars, 1, ",");
82 try
83 {
84 MooseUtils::expandAllMatches(all_vars, vars);
85 }
86 catch (std::invalid_argument const & e)
87 {
88 mooseError("No variable name match found for '", e.what(), "'.");
89 }
90
91 for (const auto j : index_range(vars))
92 for (unsigned int k = j + 1; k < vars.size(); ++k)
93 {
94 const auto row = libmesh_system.variable_number(vars[j]);
95 const auto column = libmesh_system.variable_number(vars[k]);
96 (*cm)(row, column) = 1;
97 (*cm)(column, row) = 1;
98 }
99 }
100 }
101 else
102 {
103 for (unsigned int i = 0; i < n_vars; ++i)
104 for (unsigned int j = 0; j < n_vars; ++j)
105 (*cm)(i, j) = 1;
106 }
107
108 setCouplingMatrix(std::move(cm));
109 if (getParam<bool>("trust_my_coupling"))
111}
char ** vars
registerMooseObjectAliased("MooseApp", SingleMatrixPreconditioner, "SMP")
unsigned int n_vars
void trustUserCouplingMatrix()
Whether to trust the user coupling matrix even if we want to do things like be paranoid and create a ...
SolverParams & solverParams(unsigned int solver_sys_num=0)
Get the solver parameters.
NonlinearSystemBase & getNonlinearSystemBase(const unsigned int sys_num)
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 addClassDescription(const std::string &doc_string)
This method adds a description of the class that will be displayed in the input file syntax dump.
bool isParamSetByUser(const std::string &name) const
Test if the supplied parameter is set by a user, as opposed to not set or set to default.
Definition MooseBase.h:205
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type and optionally a file path to the top-level block p...
Definition MooseBase.h:271
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
Definition MooseBase.h:199
Base class for MOOSE preconditioners.
FEProblemBase & _fe_problem
Subproblem this preconditioner is part of.
void setCouplingMatrix(std::unique_ptr< libMesh::CouplingMatrix > cm)
Setup the coupling matrix on the finite element problem.
static InputParameters validParams()
const unsigned int _nl_sys_num
The nonlinear system number whose linearization this preconditioner should be applied to.
Nonlinear system to be solved.
virtual libMesh::System & system() override
Get the reference to the libMesh system.
Single matrix preconditioner.
static InputParameters validParams()
SingleMatrixPreconditioner(const InputParameters &params)
Moose::SolveType _type
virtual unsigned int nVariables() const
Get the number of variables in this system.
Definition SystemBase.C:891
const std::vector< VariableName > & getVariableNames() const
Definition SystemBase.h:893
void tokenize(const std::string &str, std::vector< T > &elements, unsigned int min_len=1, const std::string &delims="/")
This function will split the passed in string on a set of delimiters appending the substrings to the ...
@ ST_LINEAR
Solving a linear problem.
Definition MooseTypes.h:902
@ ST_NEWTON
Full Newton Solve.
Definition MooseTypes.h:900