www.mooseframework.org
Split.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 "Split.h"
12 #include "InputParameters.h"
13 #include "PetscSupport.h"
14 #include "FEProblem.h"
15 #include "Conversion.h"
16 #include "NonlinearSystem.h"
17 
18 registerMooseObject("MooseApp", Split);
19 
22 {
24  params.addClassDescription("Field split based preconditioner for nonlinear solver.");
25  params.addParam<std::vector<NonlinearVariableName>>(
26  "vars", {}, "Variables Split operates on (omitting this implies \"all variables\"");
27  params.addParam<std::vector<SubdomainName>>(
28  "blocks", {}, "Mesh blocks Split operates on (omitting this implies \"all blocks\"");
29  params.addParam<std::vector<BoundaryName>>(
30  "sides", {}, "Sidesets Split operates on (omitting this implies \"no sidesets\"");
31  params.addParam<std::vector<BoundaryName>>(
32  "unsides",
33  {},
34  "Sidesets Split excludes (omitting this implies \"do not exclude any sidesets\"");
35  params.addParam<std::vector<std::string>>(
36  "splitting", {}, "The names of the splits (subsystems) in the decomposition of this split");
37  params.addParam<std::vector<BoundaryName>>(
38  "unside_by_var_boundary_name",
39  "A map from boundary name to unside by variable, e.g. only unside for a given variable.");
40  params.addParam<std::vector<NonlinearVariableName>>(
41  "unside_by_var_var_name",
42  "A map from boundary name to unside by variable, e.g. only unside for a given variable.");
43 
44  MooseEnum SplittingTypeEnum("additive multiplicative symmetric_multiplicative schur", "additive");
45  params.addParam<MooseEnum>("splitting_type", SplittingTypeEnum, "Split decomposition type");
46 
47  MooseEnum SchurTypeEnum("full upper lower", "full");
48  params.addParam<MooseEnum>("schur_type", SchurTypeEnum, "Type of Schur complement");
49 
56  MooseEnum SchurPreEnum("S Sp A11", "S");
57  params.addParam<MooseEnum>(
58  "schur_pre", SchurPreEnum, "Type of Schur complement preconditioner matrix");
59 
60  params.addParam<MultiMooseEnum>("petsc_options",
62  "PETSc flags for the FieldSplit solver");
63  params.addParam<std::vector<std::string>>("petsc_options_iname",
64  "PETSc option names for the FieldSplit solver");
65  params.addParam<std::vector<std::string>>("petsc_options_value",
66  "PETSc option values for the FieldSplit solver");
67 
68  params.registerBase("Split");
69  return params;
70 }
71 
72 Split::Split(const InputParameters & parameters)
73  : MooseObject(parameters),
74  Restartable(this, "Splits"),
75  _fe_problem(*getCheckedPointerParam<FEProblemBase *>("_fe_problem_base")),
76  _vars(getParam<std::vector<NonlinearVariableName>>("vars")),
77  _blocks(getParam<std::vector<SubdomainName>>("blocks")),
78  _sides(getParam<std::vector<BoundaryName>>("sides")),
79  _unsides(getParam<std::vector<BoundaryName>>("unsides")),
80  _splitting(getParam<std::vector<std::string>>("splitting")),
81  _splitting_type(getParam<MooseEnum>("splitting_type")),
82  _schur_type(getParam<MooseEnum>("schur_type")),
83  _schur_pre(getParam<MooseEnum>("schur_pre"))
84 {
85  _petsc_options.flags = getParam<MultiMooseEnum>("petsc_options");
87  getParam<std::string, std::string>("petsc_options_iname", "petsc_options_value");
88 }
89 
90 void
91 Split::setup(NonlinearSystemBase & nl, const std::string & prefix)
92 {
93  // The Split::setup() implementation does not actually depend on any
94  // specific version of PETSc, so there's no need to wrap the entire
95  // function.
96 
97  // A reference to the PetscOptions
99  // prefix
100  std::string dmprefix = prefix + "dm_moose_";
101 
102  if (isParamValid("unside_by_var_boundary_name"))
103  {
104  const auto & unside_by_var_boundary_name =
105  getParam<std::vector<BoundaryName>>("unside_by_var_boundary_name");
106  const auto & unside_by_var_var_name =
107  getParam<std::vector<NonlinearVariableName>>("unside_by_var_var_name");
108 
109  std::vector<std::string> vector_of_pairs;
110  for (const auto i : index_range(unside_by_var_boundary_name))
111  vector_of_pairs.push_back(unside_by_var_boundary_name[i] + ":" + unside_by_var_var_name[i]);
112  po.pairs.emplace_back(dmprefix + "unside_by_var", Moose::stringify(vector_of_pairs, ","));
113  }
114 
115  // var options
116  if (!_vars.empty())
117  {
118  po.pairs.emplace_back(dmprefix + "vars", Moose::stringify(_vars, ","));
119 
120  // check that variables are either field or scalars
121  for (const auto & var : _vars)
123  mooseError("Variable '", var, "' specified in split '", name(), "' does not exist");
124  }
125 
126  // block options
127  if (!_blocks.empty())
128  po.pairs.emplace_back(dmprefix + "blocks", Moose::stringify(_blocks, ","));
129 
130  // side options
131  if (!_sides.empty())
132  po.pairs.emplace_back(dmprefix + "sides", Moose::stringify(_sides, ","));
133 
134  // unside options
135  if (!_unsides.empty())
136  po.pairs.emplace_back(dmprefix + "unsides", Moose::stringify(_unsides, ","));
137 
138  if (!_splitting.empty())
139  {
140  // If this split has subsplits, it is presumed that the pc_type used to solve this split's
141  // subsystem is fieldsplit
142  // with the following parameters (unless overridden by the user-specified petsc_options below).
143  po.pairs.emplace_back(prefix + "pc_type", "fieldsplit");
144 
145  // set Splitting Type
146  const std::string petsc_splitting_type[] = {
147  "additive", "multiplicative", "symmetric_multiplicative", "schur"};
148  po.pairs.emplace_back(prefix + "pc_fieldsplit_type", petsc_splitting_type[_splitting_type]);
149 
151  {
152  // set Schur Type
153  const std::string petsc_schur_type[] = {"diag", "upper", "lower", "full"};
154  po.pairs.emplace_back(prefix + "pc_fieldsplit_schur_fact_type",
155  petsc_schur_type[_splitting_type]);
156 
157  // set Schur Preconditioner
158  const std::string petsc_schur_pre[] = {"self", "selfp", "a11"};
159  po.pairs.emplace_back(prefix + "pc_fieldsplit_schur_precondition",
160  petsc_schur_pre[_schur_pre]);
161  }
162 
163  // The DM associated with this split defines the subsplits' geometry.
164  po.pairs.emplace_back(dmprefix + "nfieldsplits", Moose::stringify(_splitting.size()));
165  po.pairs.emplace_back(dmprefix + "fieldsplit_names", Moose::stringify(_splitting, ","));
166 
167  // Finally, recursively configure the splits contained within this split.
168  for (const auto & split_name : _splitting)
169  {
170  std::shared_ptr<Split> split = nl.getSplit(split_name);
171  std::string sprefix = prefix + "fieldsplit_" + split_name + "_";
172  split->setup(nl, sprefix);
173  }
174  }
175 
176  // Now we set the user-specified petsc options for this split, possibly overriding the above
177  // settings.
178  for (const auto & item : _petsc_options.flags)
179  {
180  // Need to prepend the prefix and strip off the leading '-' on the option name.
181  std::string op(item);
182  if (op[0] != '-')
183  mooseError("Invalid PETSc option name ", op, " for Split ", _name);
184 
185  // push back PETSc options
186  po.flags.push_back(prefix + op.substr(1));
187  }
188 
189  for (auto & option : _petsc_options.pairs)
190  {
191  // Need to prepend the prefix and strip off the leading '-' on the option name.
192  const std::string & op = option.first;
193  if (op[0] != '-')
194  mooseError("Invalid PETSc option name ", op, " for Split ", _name);
195 
196  po.pairs.emplace_back(prefix + op.substr(1), option.second);
197  }
198 }
virtual void setup(NonlinearSystemBase &nl, const std::string &prefix="-")
Definition: Split.C:91
virtual bool hasVariable(const std::string &var_name) const override
Whether or not this problem has the variable.
Moose::PetscSupport::PetscOptions & getPetscOptions()
Retrieve a writable reference the PETSc options (used by PetscSupport)
A class for creating restricted objects.
Definition: Restartable.h:28
Base class for split-based preconditioners.
Definition: Split.h:25
const std::string & _name
The name of this class, reference to value stored in InputParameters.
Definition: MooseBase.h:75
std::vector< SubdomainName > _blocks
Definition: Split.h:52
std::vector< NonlinearVariableName > _vars
"Variables Split operates on
Definition: Split.h:48
registerMooseObject("MooseApp", Split)
std::vector< std::string > _splitting
Split subsystem list.
Definition: Split.h:58
A struct for storing the various types of petsc options and values.
Definition: PetscSupport.h:38
MultiMooseEnum flags
Single value PETSc options (flags)
Definition: PetscSupport.h:47
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
virtual bool hasScalarVariable(const std::string &var_name) const override
Returns a Boolean indicating whether any system contains a variable with the name provided...
std::vector< std::pair< std::string, std::string > > pairs
PETSc key-value pairs.
Definition: PetscSupport.h:44
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
virtual const std::string & name() const
Get the name of the class.
Definition: MooseBase.h:56
FEProblemBase & _fe_problem
Definition: Split.h:45
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...
Nonlinear system to be solved.
std::vector< BoundaryName > _sides
Definition: Split.h:53
MooseEnum _splitting_type
Definition: Split.h:62
Moose::PetscSupport::PetscOptions _petsc_options
Additional PETSc options.
Definition: Split.h:68
MultiMooseEnum getCommonPetscFlags()
A helper function to produce a MultiMooseEnum with commonly used PETSc single options (flags) ...
Definition: PetscSupport.C:874
std::vector< BoundaryName > _unsides
Definition: Split.h:54
Every object that can be built by the factory should be derived from this class.
Definition: MooseObject.h:33
std::shared_ptr< Split > getSplit(const std::string &name)
Retrieves a split by name.
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition: MooseEnum.h:31
std::string stringify(const T &t)
conversion to string
Definition: Conversion.h:62
tbb::split split
Split(const InputParameters &parameters)
Definition: Split.C:72
static InputParameters validParams()
Definition: Split.C:21
void push_back(const std::string &names)
Insert operators Operator to insert (push_back) values into the enum.
MooseEnum _schur_pre
Definition: Split.h:64
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type.
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...
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...
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
static InputParameters validParams()
Definition: MooseObject.C:24
auto index_range(const T &sizable)