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 
20 template <>
23 {
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", "Sidesets Split excludes (omitting this implies \"do not exclude any sidesets\"");
33  params.addParam<std::vector<std::string>>(
34  "splitting", "The names of the splits (subsystems) in the decomposition of this split");
35 
36  MooseEnum SplittingTypeEnum("additive multiplicative symmetric_multiplicative schur", "additive");
37  params.addParam<MooseEnum>("splitting_type", SplittingTypeEnum, "Split decomposition type");
38 
39  MooseEnum SchurTypeEnum("full upper lower", "full");
40  params.addParam<MooseEnum>("schur_type", SchurTypeEnum, "Type of Schur complement");
41 
48  MooseEnum SchurPreEnum("S Sp A11", "S");
49  params.addParam<MooseEnum>(
50  "schur_pre", SchurPreEnum, "Type of Schur complement preconditioner matrix");
51 
52  MooseEnum SchurAInvEnum("diag lump", "diag");
53  params.addParam<MooseEnum>(
54  "schur_ainv",
55  SchurAInvEnum,
56  "Type of approximation to inv(A) used when forming S = D - C inv(A) B");
57 
58 #if LIBMESH_HAVE_PETSC
59  params.addParam<MultiMooseEnum>("petsc_options",
61  "PETSc flags for the FieldSplit solver");
62  params.addParam<std::vector<std::string>>("petsc_options_iname",
63  "PETSc option names for the FieldSplit solver");
64  params.addParam<std::vector<std::string>>("petsc_options_value",
65  "PETSc option values for the FieldSplit solver");
66 #endif
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  _schur_ainv(getParam<MooseEnum>("schur_ainv"))
85 {
86  _petsc_options.flags = getParam<MultiMooseEnum>("petsc_options");
87  _petsc_options.inames = getParam<std::vector<std::string>>("petsc_options_iname");
88  _petsc_options.values = getParam<std::vector<std::string>>("petsc_options_value");
89 }
90 
91 void
92 Split::setup(const std::string & prefix)
93 {
94 // petsc 3.3.0 or later needed
95 #if !defined(LIBMESH_HAVE_PETSC) || PETSC_VERSION_LESS_THAN(3, 3, 0)
96  mooseError("The Splits functionality requires PETSc 3.3.0 or later.");
97 #endif
98 
99  // The Split::setup() implementation does not actually depend on any
100  // specific version of PETSc, so there's no need to wrap the entire
101  // function.
102 
103  // A reference to the PetscOptions
105  // prefix
106  std::string dmprefix = prefix + "dm_moose_";
107 
108  // var options
109  if (!_vars.empty())
110  {
111  po.inames.push_back(dmprefix + "vars");
112  po.values.push_back(Moose::stringify(_vars));
113 
114  for (const auto & var : _vars)
115  if (!_fe_problem.hasVariable(var))
116  mooseError("Variable '", var, "' specified in split '", name(), "' does not exist");
117  }
118 
119  // block options
120  if (!_blocks.empty())
121  {
122  po.inames.push_back(dmprefix + "blocks");
123  po.values.push_back(Moose::stringify(_blocks));
124  }
125 
126  // side options
127  if (!_sides.empty())
128  {
129  po.inames.push_back(dmprefix + "sides");
130  po.values.push_back(Moose::stringify(_sides));
131  }
132 
133  // unside options
134  if (!_unsides.empty())
135  {
136  po.inames.push_back(dmprefix + "unsides");
137  po.values.push_back(Moose::stringify(_unsides));
138  }
139 
140  if (!_splitting.empty())
141  {
142  // If this split has subsplits, it is presumed that the pc_type used to solve this split's
143  // subsystem is fieldsplit
144  // with the following parameters (unless overridden by the user-specified petsc_options below).
145  po.inames.push_back(prefix + "pc_type");
146  po.values.push_back("fieldsplit");
147 
148  // set Splitting Type
149  const std::string petsc_splitting_type[] = {
150  "additive", "multiplicative", "symmetric_multiplicative", "schur"};
151  po.inames.push_back(prefix + "pc_fieldsplit_type");
152  po.values.push_back(petsc_splitting_type[_splitting_type]);
153 
155  {
156  // set Schur Type
157  const std::string petsc_schur_type[] = {"diag", "upper", "lower", "full"};
158  po.inames.push_back(prefix + "pc_fieldsplit_schur_fact_type");
159  po.values.push_back(petsc_schur_type[_splitting_type]);
160 
161  // set Schur Preconditioner
162  const std::string petsc_schur_pre[] = {
163  "self",
164  "selfp",
165 #if PETSC_VERSION_LESS_THAN(3, 4, 0)
166  "diag"
167 #else
168  "a11"
169 #endif
170  };
171  po.inames.push_back(prefix + "pc_fieldsplit_schur_precondition");
172  po.values.push_back(petsc_schur_pre[_schur_pre]);
173 
174  // set Schur AInv
175  const std::string petsc_schur_ainv[] = {"diag", "lump"};
176  po.inames.push_back(prefix + "mat_schur_complement_ainv_type");
177  po.values.push_back(petsc_schur_ainv[_schur_ainv]);
178  }
179 
180  // The DM associated with this split defines the subsplits' geometry.
181  po.inames.push_back(dmprefix + "nfieldsplits");
182  po.values.push_back(Moose::stringify(_splitting.size()));
183 
184  po.inames.push_back(dmprefix + "fieldsplit_names");
185  po.values.push_back(Moose::stringify(_splitting));
186 
187  // Finally, recursively configure the splits contained within this split.
188  for (const auto & split_name : _splitting)
189  {
190  std::shared_ptr<Split> split = _fe_problem.getNonlinearSystemBase().getSplit(split_name);
191  std::string sprefix = prefix + "fieldsplit_" + split_name + "_";
192  split->setup(sprefix);
193  }
194  }
195 
196  // Now we set the user-specified petsc options for this split, possibly overriding the above
197  // settings.
198  for (const auto & item : _petsc_options.flags)
199  {
200  // Need to prepend the prefix and strip off the leading '-' on the option name.
201  std::string op(item);
202  if (op[0] != '-')
203  mooseError("Invalid PETSc option name ", op, " for Split ", _name);
204 
205  // push back PETSc options
206  po.flags.push_back(prefix + op.substr(1));
207  }
208  // check if inames match values
209  if (_petsc_options.values.size() != _petsc_options.inames.size())
210  mooseError("PETSc option values do not match PETSc option names");
211 
212  for (std::size_t j = 0; j < _petsc_options.inames.size(); ++j)
213  {
214  // Need to prepend the prefix and strip off the leading '-' on the option name.
215  const std::string & op = _petsc_options.inames[j];
216  if (op[0] != '-')
217  mooseError("Invalid PETSc option name ", op, " for Split ", _name);
218 
219  po.inames.push_back(prefix + op.substr(1));
220  po.values.push_back(_petsc_options.values[j]);
221  }
222 }
std::vector< std::string > values
Values for PETSc key-value pairs.
Definition: PetscSupport.h:48
virtual bool hasVariable(const std::string &var_name) const override
Moose::PetscSupport::PetscOptions & getPetscOptions()
Retrieve a writable reference the PETSc options (used by PetscSupport)
A class for creating restricted objects.
Definition: Restartable.h:29
Base class for split-based preconditioners.
Definition: Split.h:29
NonlinearSystemBase & getNonlinearSystemBase()
std::vector< SubdomainName > _blocks
Definition: Split.h:54
std::vector< NonlinearVariableName > _vars
"Variables Split operates on
Definition: Split.h:50
registerMooseObject("MooseApp", Split)
std::vector< std::string > _splitting
Split subsystem list.
Definition: Split.h:60
A struct for storing the various types of petsc options and values.
Definition: PetscSupport.h:39
MultiMooseEnum flags
Single value PETSc options (flags)
Definition: PetscSupport.h:51
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
void mooseError(Args &&... args) const
Definition: MooseObject.h:147
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
FEProblemBase & _fe_problem
Definition: Split.h:47
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< std::string > split(const std::string &str, const std::string &delimiter)
Python like split function for strings.
Definition: MooseUtils.C:736
std::vector< BoundaryName > _sides
Definition: Split.h:55
MooseEnum _splitting_type
Definition: Split.h:64
Moose::PetscSupport::PetscOptions _petsc_options
Additional PETSc options.
Definition: Split.h:71
MultiMooseEnum getCommonPetscFlags()
A helper function to produce a MultiMooseEnum with commonly used PETSc single options (flags) ...
Definition: PetscSupport.C:860
std::vector< BoundaryName > _unsides
Definition: Split.h:56
Every object that can be built by the factory should be derived from this class.
Definition: MooseObject.h:42
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
virtual void setup(const std::string &prefix="-")
Definition: Split.C:92
std::string stringify(const T &t)
conversion to string
Definition: Conversion.h:60
MooseEnum _schur_ainv
Definition: Split.h:67
InputParameters validParams< MooseObject >()
Definition: MooseObject.C:25
Split(const InputParameters &parameters)
Definition: Split.C:72
const std::string & _name
The name of this object, reference to value stored in InputParameters.
Definition: MooseObject.h:183
void push_back(const std::string &names)
Insert operators Operator to insert (push_back) values into the enum.
const std::string & name() const
Get the name of the object.
Definition: MooseObject.h:59
MooseEnum _schur_pre
Definition: Split.h:66
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...
InputParameters validParams< Split >()
Definition: Split.C:22
std::vector< std::string > inames
Keys for PETSc key-value pairs.
Definition: PetscSupport.h:45