Line data Source code
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 : // 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 :
19 : InputParameters
20 112610 : MoosePreconditioner::validParams()
21 : {
22 112610 : InputParameters params = MooseObject::validParams();
23 112610 : params.addPrivateParam<FEProblemBase *>("_fe_problem_base");
24 :
25 112610 : MooseEnum pc_side("left right symmetric default", "default");
26 112610 : params.addParam<MooseEnum>("pc_side", pc_side, "Preconditioning side");
27 112610 : MooseEnum ksp_norm("none preconditioned unpreconditioned natural default", "unpreconditioned");
28 112610 : params.addParam<MooseEnum>(
29 : "ksp_norm", ksp_norm, "Sets the norm that is used for convergence testing");
30 112610 : params.registerBase("MoosePreconditioner");
31 :
32 112610 : 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 112610 : 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 337830 : params.addParam<bool>("full",
41 225220 : 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 112610 : params.addParam<NonlinearSystemName>(
46 : "nl_sys",
47 : "The nonlinear system whose linearization this preconditioner should be applied to.");
48 :
49 112610 : params += Moose::PetscSupport::getPetscValidParams();
50 :
51 225220 : return params;
52 112610 : }
53 :
54 13492 : MoosePreconditioner::MoosePreconditioner(const InputParameters & params)
55 : : MooseObject(params),
56 : Restartable(this, "Preconditioners"),
57 : PerfGraphInterface(this),
58 13492 : _fe_problem(*params.getCheckedPointerParam<FEProblemBase *>("_fe_problem_base")),
59 13492 : _nl_sys_num(
60 13492 : isParamValid("nl_sys") ? _fe_problem.nlSysNum(getParam<NonlinearSystemName>("nl_sys")) : 0),
61 26984 : _nl(_fe_problem.getNonlinearSystemBase(_nl_sys_num))
62 : {
63 13492 : _nl.setPCSide(getParam<MooseEnum>("pc_side"));
64 :
65 13492 : _nl.setMooseKSPNormType(getParam<MooseEnum>("ksp_norm"));
66 :
67 13492 : bool full = getParam<bool>("full");
68 :
69 : // We either have a full coupling or a custom coupling
70 13492 : if (full && isParamValid("off_diag_row"))
71 0 : paramError("off_diag_row", "Set full=false to specify the off-diagonal rows manually");
72 13492 : if (full && isParamValid("off_diag_column"))
73 0 : paramError("off_diag_column", "Set full=false to specify the off-diagonal columns manually");
74 :
75 : // Off-diagonal rows and colums must match
76 13492 : if (isParamValid("off_diag_row"))
77 : {
78 90 : if (isParamValid("off_diag_column"))
79 : {
80 : const auto off_diag =
81 90 : getParam<NonlinearVariableName, NonlinearVariableName>("off_diag_row", "off_diag_column");
82 90 : }
83 : else
84 0 : paramError("off_diag_row",
85 : "If off-diagonal rows are specified, matching off-diagonal "
86 : "columns must be specified as well");
87 : }
88 13402 : else if (isParamValid("off_diag_column"))
89 0 : paramError("off_diag_column",
90 : "If off-diagonal columns are specified, matching off-diagonal "
91 : "rows must be specified as well");
92 :
93 : // This must be set early because the solve type is queried by later actions
94 13492 : Moose::PetscSupport::setSolveTypeFromParams(_fe_problem, params);
95 13492 : }
96 :
97 : void
98 11456 : MoosePreconditioner::copyVarValues(MeshBase & mesh,
99 : const unsigned int from_system,
100 : const unsigned int from_var,
101 : const NumericVector<Number> & from_vector,
102 : const unsigned int to_system,
103 : const unsigned int to_var,
104 : NumericVector<Number> & to_vector)
105 : {
106 1429088 : for (auto & node : mesh.local_node_ptr_range())
107 : {
108 708816 : unsigned int n_comp = node->n_comp(from_system, from_var);
109 :
110 : mooseAssert(node->n_comp(from_system, from_var) == node->n_comp(to_system, to_var),
111 : "Number of components does not match in each system");
112 :
113 1410632 : for (unsigned int i = 0; i < n_comp; i++)
114 : {
115 701816 : dof_id_type from_dof = node->dof_number(from_system, from_var, i);
116 701816 : dof_id_type to_dof = node->dof_number(to_system, to_var, i);
117 :
118 701816 : to_vector.set(to_dof, from_vector(from_dof));
119 : }
120 11456 : }
121 :
122 1194336 : for (auto & elem : as_range(mesh.local_elements_begin(), mesh.local_elements_end()))
123 : {
124 591440 : unsigned int n_comp = elem->n_comp(from_system, from_var);
125 :
126 : mooseAssert(elem->n_comp(from_system, from_var) == elem->n_comp(to_system, to_var),
127 : "Number of components does not match in each system");
128 :
129 609360 : for (unsigned int i = 0; i < n_comp; i++)
130 : {
131 17920 : dof_id_type from_dof = elem->dof_number(from_system, from_var, i);
132 17920 : dof_id_type to_dof = elem->dof_number(to_system, to_var, i);
133 :
134 17920 : to_vector.set(to_dof, from_vector(from_dof));
135 : }
136 11456 : }
137 11456 : }
138 :
139 : void
140 13492 : MoosePreconditioner::setCouplingMatrix(std::unique_ptr<CouplingMatrix> cm)
141 : {
142 13492 : _fe_problem.setCouplingMatrix(std::move(cm), _nl_sys_num);
143 13492 : }
144 :
145 : void
146 13095 : MoosePreconditioner::initialSetup()
147 : {
148 13095 : Moose::PetscSupport::storePetscOptions(_fe_problem, _nl.prefix(), *this);
149 13095 : }
|