www.mooseframework.org
Split.C
Go to the documentation of this file.
1 /****************************************************************/
2 /* DO NOT MODIFY THIS HEADER */
3 /* MOOSE - Multiphysics Object Oriented Simulation Environment */
4 /* */
5 /* (c) 2010 Battelle Energy Alliance, LLC */
6 /* ALL RIGHTS RESERVED */
7 /* */
8 /* Prepared by Battelle Energy Alliance, LLC */
9 /* Under Contract No. DE-AC07-05ID14517 */
10 /* With the U. S. Department of Energy */
11 /* */
12 /* See COPYRIGHT for full restrictions */
13 /****************************************************************/
14 
15 // MOOSE includes
16 #include "Split.h"
17 #include "InputParameters.h"
18 #include "PetscSupport.h"
19 #include "FEProblem.h"
20 #include "Conversion.h"
21 #include "NonlinearSystem.h"
22 
23 template <>
26 {
28  params.addParam<std::vector<NonlinearVariableName>>(
29  "vars", "Variables Split operates on (omitting this implies \"all variables\"");
30  params.addParam<std::vector<SubdomainName>>(
31  "blocks", "Mesh blocks Split operates on (omitting this implies \"all blocks\"");
32  params.addParam<std::vector<BoundaryName>>(
33  "sides", "Sidesets Split operates on (omitting this implies \"no sidesets\"");
34  params.addParam<std::vector<BoundaryName>>(
35  "unsides", "Sidesets Split excludes (omitting this implies \"do not exclude any sidesets\"");
36  params.addParam<std::vector<std::string>>(
37  "splitting", "The names of the splits (subsystems) in the decomposition of this split");
38 
39  MooseEnum SplittingTypeEnum("additive multiplicative symmetric_multiplicative schur", "additive");
40  params.addParam<MooseEnum>("splitting_type", SplittingTypeEnum, "Split decomposition type");
41 
42  MooseEnum SchurTypeEnum("full upper lower", "full");
43  params.addParam<MooseEnum>("schur_type", SchurTypeEnum, "Type of Schur complement");
44 
51  MooseEnum SchurPreEnum("S Sp A11", "S");
52  params.addParam<MooseEnum>(
53  "schur_pre", SchurPreEnum, "Type of Schur complement preconditioner matrix");
54 
55  MooseEnum SchurAInvEnum("diag lump", "diag");
56  params.addParam<MooseEnum>(
57  "schur_ainv",
58  SchurAInvEnum,
59  "Type of approximation to inv(A) used when forming S = D - C inv(A) B");
60 
61 #if LIBMESH_HAVE_PETSC
62  params.addParam<MultiMooseEnum>("petsc_options",
64  "PETSc flags for the FieldSplit solver");
65  params.addParam<std::vector<std::string>>("petsc_options_iname",
66  "PETSc option names for the FieldSplit solver");
67  params.addParam<std::vector<std::string>>("petsc_options_value",
68  "PETSc option values for the FieldSplit solver");
69 #endif
70 
71  params.registerBase("Split");
72  return params;
73 }
74 
75 Split::Split(const InputParameters & parameters)
76  : MooseObject(parameters),
77  Restartable(parameters, "Splits"),
78  _fe_problem(*parameters.getCheckedPointerParam<FEProblemBase *>("_fe_problem_base")),
79  _vars(getParam<std::vector<NonlinearVariableName>>("vars")),
80  _blocks(getParam<std::vector<SubdomainName>>("blocks")),
81  _sides(getParam<std::vector<BoundaryName>>("sides")),
82  _unsides(getParam<std::vector<BoundaryName>>("unsides")),
83  _splitting(getParam<std::vector<std::string>>("splitting")),
84  _splitting_type(getParam<MooseEnum>("splitting_type")),
85  _schur_type(getParam<MooseEnum>("schur_type")),
86  _schur_pre(getParam<MooseEnum>("schur_pre")),
87  _schur_ainv(getParam<MooseEnum>("schur_ainv"))
88 {
89  _petsc_options.flags = getParam<MultiMooseEnum>("petsc_options");
90  _petsc_options.inames = getParam<std::vector<std::string>>("petsc_options_iname");
91  _petsc_options.values = getParam<std::vector<std::string>>("petsc_options_value");
92 }
93 
94 void
95 Split::setup(const std::string & prefix)
96 {
97 // petsc 3.3.0 or later needed
98 #if !defined(LIBMESH_HAVE_PETSC) || PETSC_VERSION_LESS_THAN(3, 3, 0)
99  mooseError("The Splits functionality requires PETSc 3.3.0 or later.");
100 #endif
101 
102  // The Split::setup() implementation does not actually depend on any
103  // specific version of PETSc, so there's no need to wrap the entire
104  // function.
105 
106  // A reference to the PetscOptions
108  // prefix
109  std::string dmprefix = prefix + "dm_moose_";
110 
111  // var options
112  if (!_vars.empty())
113  {
114  po.inames.push_back(dmprefix + "vars");
115  po.values.push_back(Moose::stringify(_vars));
116 
117  for (const auto & var : _vars)
118  if (!_fe_problem.hasVariable(var))
119  mooseError("Variable '", var, "' specified in split '", name(), "' does not exist");
120  }
121 
122  // block options
123  if (!_blocks.empty())
124  {
125  po.inames.push_back(dmprefix + "blocks");
126  po.values.push_back(Moose::stringify(_blocks));
127  }
128 
129  // side options
130  if (!_sides.empty())
131  {
132  po.inames.push_back(dmprefix + "sides");
133  po.values.push_back(Moose::stringify(_sides));
134  }
135 
136  // unside options
137  if (!_unsides.empty())
138  {
139  po.inames.push_back(dmprefix + "unsides");
140  po.values.push_back(Moose::stringify(_unsides));
141  }
142 
143  if (!_splitting.empty())
144  {
145  // If this split has subsplits, it is presumed that the pc_type used to solve this split's
146  // subsystem is fieldsplit
147  // with the following parameters (unless overridden by the user-specified petsc_options below).
148  po.inames.push_back(prefix + "pc_type");
149  po.values.push_back("fieldsplit");
150 
151  // set Splitting Type
152  const std::string petsc_splitting_type[] = {
153  "additive", "multiplicative", "symmetric_multiplicative", "schur"};
154  po.inames.push_back(prefix + "pc_fieldsplit_type");
155  po.values.push_back(petsc_splitting_type[_splitting_type]);
156 
157  if (_splitting_type == SplittingTypeSchur)
158  {
159  // set Schur Type
160  const std::string petsc_schur_type[] = {"diag", "upper", "lower", "full"};
161  po.inames.push_back(prefix + "pc_fieldsplit_schur_fact_type");
162  po.values.push_back(petsc_schur_type[_splitting_type]);
163 
164  // set Schur Preconditioner
165  const std::string petsc_schur_pre[] = {
166  "self",
167  "selfp",
168 #if PETSC_VERSION_LESS_THAN(3, 4, 0)
169  "diag"
170 #else
171  "a11"
172 #endif
173  };
174  po.inames.push_back(prefix + "pc_fieldsplit_schur_precondition");
175  po.values.push_back(petsc_schur_pre[_schur_pre]);
176 
177  // set Schur AInv
178  const std::string petsc_schur_ainv[] = {"diag", "lump"};
179  po.inames.push_back(prefix + "mat_schur_complement_ainv_type");
180  po.values.push_back(petsc_schur_ainv[_schur_ainv]);
181  }
182 
183  // The DM associated with this split defines the subsplits' geometry.
184  po.inames.push_back(dmprefix + "nfieldsplits");
185  po.values.push_back(Moose::stringify(_splitting.size()));
186 
187  po.inames.push_back(dmprefix + "fieldsplit_names");
188  po.values.push_back(Moose::stringify(_splitting));
189 
190  // Finally, recursively configure the splits contained within this split.
191  for (const auto & split_name : _splitting)
192  {
193  std::shared_ptr<Split> split = _fe_problem.getNonlinearSystemBase().getSplit(split_name);
194  std::string sprefix = prefix + "fieldsplit_" + split_name + "_";
195  split->setup(sprefix);
196  }
197  }
198 
199  // Now we set the user-specified petsc options for this split, possibly overriding the above
200  // settings.
201  for (const auto & item : _petsc_options.flags)
202  {
203  // Need to prepend the prefix and strip off the leading '-' on the option name.
204  std::string op(item);
205  if (op[0] != '-')
206  mooseError("Invalid PETSc option name ", op, " for Split ", _name);
207 
208  // push back PETSc options
209  po.flags.push_back(prefix + op.substr(1));
210  }
211  // check if inames match values
212  if (_petsc_options.values.size() != _petsc_options.inames.size())
213  mooseError("PETSc option values do not match PETSc option names");
214 
215  for (std::size_t j = 0; j < _petsc_options.inames.size(); ++j)
216  {
217  // Need to prepend the prefix and strip off the leading '-' on the option name.
218  const std::string & op = _petsc_options.inames[j];
219  if (op[0] != '-')
220  mooseError("Invalid PETSc option name ", op, " for Split ", _name);
221 
222  po.inames.push_back(prefix + op.substr(1));
223  po.values.push_back(_petsc_options.values[j]);
224  }
225 }
const std::string & name() const
Get the name of the object.
Definition: MooseObject.h:47
std::vector< std::string > values
Values for PETSc key-value pairs.
Definition: PetscSupport.h:50
Moose::PetscSupport::PetscOptions & getPetscOptions()
Retrieve a writable reference the PETSc options (used by PetscSupport)
A class for creating restricted objects.
Definition: Restartable.h:31
NonlinearSystemBase & getNonlinearSystemBase()
std::vector< SubdomainName > _blocks
Definition: Split.h:55
std::vector< NonlinearVariableName > _vars
"Variables Split operates on
Definition: Split.h:51
std::vector< std::string > _splitting
Split subsystem list.
Definition: Split.h:61
A struct for storing the various types of petsc options and values.
Definition: PetscSupport.h:41
MultiMooseEnum flags
Single value PETSc options (flags)
Definition: PetscSupport.h:53
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
FEProblemBase & _fe_problem
Definition: Split.h:48
void registerBase(const std::string &value)
This method must be called from every base "Moose System" to create linkage with the Action System...
std::vector< BoundaryName > _sides
Definition: Split.h:56
MooseEnum _splitting_type
Definition: Split.h:65
Moose::PetscSupport::PetscOptions _petsc_options
Additional PETSc options.
Definition: Split.h:72
MultiMooseEnum getCommonPetscFlags()
A helper function to produce a MultiMooseEnum with commonly used PETSc single options (flags) ...
Definition: PetscSupport.C:785
std::vector< BoundaryName > _unsides
Definition: Split.h:57
Every object that can be built by the factory should be derived from this class.
Definition: MooseObject.h:36
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:37
virtual bool hasVariable(const std::string &var_name) override
virtual void setup(const std::string &prefix="-")
Definition: Split.C:95
std::string stringify(const T &t)
conversion to string
Definition: Conversion.h:66
MooseEnum _schur_ainv
Definition: Split.h:68
InputParameters validParams< MooseObject >()
Definition: MooseObject.C:22
Split(const InputParameters &parameters)
Definition: Split.C:75
const std::string & _name
The name of this object, reference to value stored in InputParameters.
Definition: MooseObject.h:114
void push_back(const std::string &names)
Insert operators Operator to insert (push_back) values into the enum.
MooseEnum _schur_pre
Definition: Split.h:67
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...
void mooseError(Args &&...args) const
Definition: MooseObject.h:80
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
InputParameters validParams< Split >()
Definition: Split.C:25
std::vector< std::string > inames
Keys for PETSc key-value pairs.
Definition: PetscSupport.h:47