https://mooseframework.inl.gov
AddVariableAction.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 
10 // MOOSE includes
11 #include "AddVariableAction.h"
12 #include "FEProblem.h"
13 #include "Factory.h"
14 #include "MooseEnum.h"
15 #include "MooseEigenSystem.h"
16 #include "MooseObjectAction.h"
17 #include "MooseMesh.h"
18 #include "CopyNodalVarsAction.h"
19 
20 #include "libmesh/string_to_enum.h"
21 #include "libmesh/fe_interface.h"
22 
23 using namespace libMesh;
24 
25 registerMooseAction("MooseApp", AddVariableAction, "add_variable");
26 
29 {
30  auto params = MooseObjectAction::validParams();
31  params.addClassDescription("Add a non-linear variable to the simulation.");
32 
33  // The user may specify a type in the Variables block, but if they don't we'll just use all the
34  // parameters available from MooseVariableBase
35  params.set<std::string>("type") = "MooseVariableBase";
36 
37  // The below is for backwards compatibility
38  params.addParam<MooseEnum>("family",
40  "Specifies the family of FE shape functions to use for this variable");
41  params.addParam<MooseEnum>("order",
43  "Specifies the order of the FE shape function to use for this "
44  "variable (additional orders not listed are allowed)");
45  params.addParam<std::vector<Real>>("scaling",
46  "Specifies a scaling factor to apply to this variable");
47  params.addParam<std::vector<Real>>("initial_condition",
48  "Specifies a constant initial condition for this variable");
49  params.transferParam<std::string>(CopyNodalVarsAction::validParams(), "initial_from_file_var");
50  return params;
51 }
52 
54  : MooseObjectAction(params),
55  _fe_type(feType(params)),
56  _scalar_var(_fe_type.family == SCALAR),
57  _fv_var(false),
58  _components(1)
59 {
60 }
61 
64 {
65  return MooseEnum("LAGRANGE MONOMIAL HERMITE SCALAR HIERARCHIC CLOUGH XYZ SZABAB BERNSTEIN "
66  "L2_LAGRANGE L2_HIERARCHIC NEDELEC_ONE LAGRANGE_VEC MONOMIAL_VEC "
67  "RAVIART_THOMAS RATIONAL_BERNSTEIN SIDE_HIERARCHIC L2_HIERARCHIC_VEC "
68  "L2_LAGRANGE_VEC L2_RAVIART_THOMAS",
69  "LAGRANGE");
70 }
71 
74 {
75  return MooseEnum(
76  "CONSTANT FIRST SECOND THIRD FOURTH FIFTH SIXTH SEVENTH EIGHTH NINTH TENTH ELEVENTH TWELFTH "
77  "THIRTEENTH FOURTEENTH FIFTEENTH SIXTEENTH SEVENTEENTH EIGHTTEENTH NINETEENTH TWENTIETH "
78  "TWENTYFIRST TWENTYSECOND TWENTYTHIRD TWENTYFOURTH TWENTYFIFTH TWENTYSIXTH TWENTYSEVENTH "
79  "TWENTYEIGHTH TWENTYNINTH THIRTIETH THIRTYFIRST THIRTYSECOND THIRTYTHIRD THIRTYFOURTH "
80  "THIRTYFIFTH THIRTYSIXTH THIRTYSEVENTH THIRTYEIGHTH THIRTYNINTH FORTIETH FORTYFIRST "
81  "FORTYSECOND FORTYTHIRD",
82  "FIRST",
83  true);
84 }
85 
86 FEType
88 {
89  return {Utility::string_to_enum<Order>(params.get<MooseEnum>("order")),
90  Utility::string_to_enum<FEFamily>(params.get<MooseEnum>("family"))};
91 }
92 
93 void
95 {
96  _components = _moose_object_pars.get<unsigned int>("components");
97  if (_components == 0)
98  mooseError("There must be at least one variable component, but somehow 0 has been specified");
99 
100  // We have to do some sanity checks because of our work to maintain backwards compatibility.
101  // `family`, `order`, and `scaling` are all parameters duplicated between this action and the
102  // `MooseVariable*` object itself. Consequently during input file parsing, the params objects for
103  // both the action and MooseVariable object can be populated with the exact same parameters.
104  // However, some applications actually create their variables solely through creation and setting
105  // of `AddVariableAction` parameters which means that the `MooseVariableBase*` params will never
106  // be populated. So we should apply the parameters directly from the action. There should be no
107  // case in which both params objects get set by the user and they have different values
108 
109  if (isParamSetByUser("family") && _moose_object_pars.isParamSetByUser("family") &&
110  !getParam<MooseEnum>("family").compareCurrent(_moose_object_pars.get<MooseEnum>("family")))
111  mooseError("Both the MooseVariable* and Add*VariableAction parameters objects have had the "
112  "`family` parameter set, and they are different values: ",
113  _moose_object_pars.get<MooseEnum>("family"),
114  " and ",
115  getParam<MooseEnum>("family"),
116  " respectively. I don't know how you achieved this, but you need to rectify it.");
117 
118  if (isParamSetByUser("order") && _moose_object_pars.isParamSetByUser("order") &&
119  !getParam<MooseEnum>("order").compareCurrent(_moose_object_pars.get<MooseEnum>("order")))
120  mooseError("Both the MooseVariable* and Add*VariableAction parameters objects have had the "
121  "`order` parameter set, and they are different values: ",
122  _moose_object_pars.get<MooseEnum>("order"),
123  " and ",
124  getParam<MooseEnum>("order"),
125  " respectively. I don't know how you achieved this, but you need to rectify it.");
126 
127  if (isParamSetByUser("scaling") && _moose_object_pars.isParamSetByUser("scaling") &&
128  getParam<std::vector<Real>>("scaling") !=
129  _moose_object_pars.get<std::vector<Real>>("scaling"))
130  mooseError("Both the MooseVariable* and Add*VariableAction parameters objects have had the "
131  "`scaling` parameter set, and they are different values. I don't know how you "
132  "achieved this, but you need to rectify it.");
133 
134  if (isParamSetByUser("initial_condition") && isParamSetByUser("initial_from_file_var"))
135  paramError("initial_condition",
136  "Two initial conditions have been provided for the variable ",
137  name(),
138  " using the 'initial_condition' and 'initial_from_file_var' parameters. Please "
139  "remove one of them.");
140 
141  _moose_object_pars.applySpecificParameters(_pars, {"order", "family", "scaling"});
142 
143  // Determine the MooseVariable type
144  _fv_var = _moose_object_pars.get<bool>("fv");
145  const auto is_array = _components > 1 || _moose_object_pars.get<bool>("array");
146  if (_type == "MooseVariableBase")
147  _type = variableType(_fe_type, _fv_var, is_array);
148  if (_fv_var)
149  _problem->needFV();
150 
151  // Need static_cast to resolve overloads
152  _problem_add_var_method = static_cast<void (FEProblemBase::*)(
153  const std::string &, const std::string &, InputParameters &)>(&FEProblemBase::addVariable);
154 }
155 
156 void
158 {
159  // If we've been called that means that current_task == "add_variable"
160  init();
161 
162  // Get necessary data for creating a variable
163  const auto var_name = varName();
164  addVariable(var_name);
165 
166  // Set the initial condition
167  if (isParamValid("initial_condition"))
168  {
169  const auto & value = getParam<std::vector<Real>>("initial_condition");
171  }
172 }
173 
174 void
175 AddVariableAction::createInitialConditionAction(const std::vector<Real> & value)
176 {
177  // Variable name
178  const auto var_name = varName();
179 
180  // Create the object name
181  std::string long_name("");
182  long_name += var_name;
183  long_name += "_moose";
184 
185  // Set the parameters for the action
186  InputParameters action_params = _action_factory.getValidParams("AddOutputAction");
187  action_params.set<ActionWarehouse *>("awh") = &_awh;
188 
189  // Associate all action and initial condition errors with "initial_condition"
190  associateWithParameter("initial_condition", action_params);
191 
192  const auto fe_field_type = FEInterface::field_type(_fe_type);
193  const bool is_vector = fe_field_type == TYPE_VECTOR;
194  const auto is_array = _components > 1 || _moose_object_pars.get<bool>("array");
195 
196  if (_scalar_var)
197  action_params.set<std::string>("type") = "ScalarConstantIC";
198  else if (!is_array)
199  {
200  if (is_vector)
201  action_params.set<std::string>("type") = "VectorConstantIC";
202  else
203  {
204  if (_fv_var)
205  action_params.set<std::string>("type") = "FVConstantIC";
206  else
207  action_params.set<std::string>("type") = "ConstantIC";
208  }
209  }
210  else
211  {
212  action_params.set<std::string>("type") = "ArrayConstantIC";
213  if (value.size() != _components)
214  mooseError("Size of 'initial_condition' is not consistent");
215  }
216 
217  // Create the action
218  std::shared_ptr<MooseObjectAction> action;
219  if (_fv_var)
220  action = std::static_pointer_cast<MooseObjectAction>(
221  _action_factory.create("AddFVInitialConditionAction", long_name, action_params));
222  else
223  action = std::static_pointer_cast<MooseObjectAction>(
224  _action_factory.create("AddInitialConditionAction", long_name, action_params));
225 
226  // Set the required parameters for the object to be created
227  action->getObjectParams().set<VariableName>("variable") = var_name;
228  if (is_array)
229  {
231  for (unsigned int i = 0; i < _components; ++i)
232  v(i) = value[i];
233  action->getObjectParams().set<RealEigenVector>("value") = v;
234  }
235  else if (is_vector)
236  {
237  action->getObjectParams().set<Real>("x_value") = value[0];
238  if (value.size() > 0)
239  action->getObjectParams().set<Real>("y_value") = value[1];
240  if (value.size() > 1)
241  action->getObjectParams().set<Real>("z_value") = value[2];
242  }
243  else
244  action->getObjectParams().set<Real>("value") = value[0];
245 
246  // Store the action in the ActionWarehouse
247  _awh.addActionBlock(action);
248 }
249 
250 std::string
251 AddVariableAction::determineType(const FEType & fe_type, unsigned int components, bool is_fv)
252 {
253  ::mooseDeprecated("AddVariableAction::determineType() is deprecated. Use "
254  "AddVariableAction::variableType() instead.");
255  return variableType(fe_type, is_fv, components > 1);
256 }
257 
258 std::string
259 AddVariableAction::variableType(const FEType & fe_type, const bool is_fv, const bool is_array)
260 {
261  if (is_fv)
262  return "MooseVariableFVReal";
263 
264  const auto fe_field_type = FEInterface::field_type(fe_type);
265 
266  if (is_array)
267  {
268  if (fe_field_type == TYPE_VECTOR)
269  ::mooseError("Vector finite element families do not currently have ArrayVariable support");
270  else
271  return "ArrayMooseVariable";
272  }
273  else if (fe_type == FEType(0, MONOMIAL))
274  return "MooseVariableConstMonomial";
275  else if (fe_type.family == SCALAR)
276  return "MooseVariableScalar";
277  else if (fe_field_type == TYPE_VECTOR)
278  return "VectorMooseVariable";
279  else
280  return "MooseVariable";
281 }
282 
283 void
284 AddVariableAction::addVariable(const std::string & var_name)
285 {
286  // Compare sizes of scaling_factor and components for Array Variables
287  const auto & scale_factor = _moose_object_pars.isParamValid("scaling")
288  ? _moose_object_pars.get<std::vector<Real>>("scaling")
289  : std::vector<Real>(_components, 1);
290  if (scale_factor.size() != _components)
291  mooseError("Size of 'scaling' is not consistent");
292 
294 
295  if (_moose_object_pars.get<bool>("eigen"))
296  {
297  // MooseEigenSystem will be eventually removed. NonlinearEigenSystem will be used intead.
298  // It is legal for NonlinearEigenSystem to specify a variable as eigen in input file,
299  // but we do not need to do anything here.
300  MooseEigenSystem * esys =
301  dynamic_cast<MooseEigenSystem *>(&_problem->getNonlinearSystemBase(/*nl_sys=*/0));
302  if (esys)
303  esys->markEigenVariable(var_name);
304  }
305 }
306 
307 std::set<SubdomainID>
309 {
310  // Extract and return the block ids supplied in the input
311  std::set<SubdomainID> blocks;
312  std::vector<SubdomainName> block_param =
313  _moose_object_pars.get<std::vector<SubdomainName>>("block");
314  for (const auto & subdomain_name : block_param)
315  {
316  SubdomainID blk_id = _problem->mesh().getSubdomainID(subdomain_name);
317  blocks.insert(blk_id);
318  }
319  return blocks;
320 }
static InputParameters validParams()
std::set< SubdomainID > getSubdomainIDs()
Get the block ids from the input parameters.
virtual std::string varName() const
Return the name of the nonlinear variable to be created.
bool _scalar_var
True if the variable being created is a scalar.
const InputParameters & _pars
The object&#39;s parameters.
Definition: MooseBase.h:394
virtual void act() override
Method to add objects to the simulation or perform other setup tasks.
ActionWarehouse & _awh
Reference to ActionWarehouse where we store object build by actions.
Definition: Action.h:169
void paramError(const std::string &param, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
Definition: MooseBase.h:467
Adds nonlinear variable.
char ** blocks
void applySpecificParameters(const InputParameters &common, const std::vector< std::string > &include, bool allow_private=false)
Method for applying common parameters.
InputParameters getValidParams(const std::string &name)
Definition: ActionFactory.C:94
static InputParameters validParams()
std::vector< std::pair< R1, R2 > > get(const std::string &param1, const std::string &param2) const
Combine two vector parameters into a single vector of pairs.
ActionFactory & _action_factory
Builds Actions.
T & set(const std::string &name, bool quiet_mode=false)
Returns a writable reference to the named parameters.
Storage for action instances.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
void addActionBlock(std::shared_ptr< Action > blk)
This method add an Action instance to the warehouse.
static InputParameters validParams()
registerMooseAction("MooseApp", AddVariableAction, "add_variable")
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
std::shared_ptr< Action > create(const std::string &action, const std::string &action_name, InputParameters &parameters)
Definition: ActionFactory.C:40
static MooseEnum getNonlinearVariableFamilies()
Get the possible variable families.
libMesh::FEType _fe_type
FEType for the variable being created.
bool _fv_var
True if the variable being created is finite volume.
const std::string & name() const
Get the name of the class.
Definition: MooseBase.h:103
InputParameters & getObjectParams()
Retrieve the parameters of the object to be created by this action.
static MooseEnum getNonlinearVariableOrders()
Get the possible variable orders.
unsigned int _components
Number of components for an array variable.
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
void createInitialConditionAction(const std::vector< Real > &value)
Create the action to generate the InitialCondition object.
void mooseDeprecated(Args &&... args) const
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition: MooseEnum.h:54
static std::string variableType(const libMesh::FEType &fe_type, const bool is_fv=false, const bool is_array=false)
Determines a variable type.
virtual void markEigenVariable(const VariableName &var_name)
Mark a variable as a variable of the eigen system.
virtual void addVariable(const std::string &var_type, const std::string &var_name, InputParameters &params)
Canonical method for adding a non-linear variable.
MONOMIAL
bool isParamSetByUser(const std::string &name) const
Method returns true if the parameter was set by the user.
static libMesh::FEType feType(const InputParameters &params)
determine the FEType by examining family and order in the provided parameters
std::string _type
The Object type that is being created.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
InputParameters _moose_object_pars
The parameters for the object to be created.
virtual void init()
Initialize the action&#39;s member variables.
void associateWithParameter(const std::string &param_name, InputParameters &params) const
Associates the object&#39;s parameters params with the input location from this Action&#39;s parameter with t...
Definition: Action.C:153
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:281
std::shared_ptr< FEProblemBase > & _problem
Convenience reference to a problem this action works on.
Definition: Action.h:178
void addVariable(const std::string &var_name)
Adds a nonlinear variable to the system.
Eigen::Matrix< Real, Eigen::Dynamic, 1 > RealEigenVector
Definition: MooseTypes.h:147
AddVariableAction(const InputParameters &params)
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
Definition: MooseBase.h:209
static std::string determineType(const libMesh::FEType &fe_type, unsigned int components, bool is_fv=false)
DEPRECATED: Use variableType instead.
TYPE_VECTOR
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:215
std::function< void(FEProblemBase &, const std::string &, const std::string &, InputParameters &)> _problem_add_var_method
bool isParamValid(const std::string &name) const
This method returns parameters that have been initialized in one fashion or another, i.e.