www.mooseframework.org
AddVariableAction.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 // Standard includes
11 #include <sstream>
12 #include <stdexcept>
13 
14 // MOOSE includes
15 #include "AddVariableAction.h"
16 #include "FEProblem.h"
17 #include "Factory.h"
18 #include "MooseEnum.h"
19 #include "MooseEigenSystem.h"
20 #include "MooseObjectAction.h"
21 #include "MooseMesh.h"
22 
23 #include "libmesh/libmesh.h"
24 #include "libmesh/exodusII_io.h"
25 #include "libmesh/equation_systems.h"
26 #include "libmesh/nonlinear_implicit_system.h"
27 #include "libmesh/explicit_system.h"
28 #include "libmesh/string_to_enum.h"
29 
30 registerMooseAction("MooseApp", AddVariableAction, "add_variable");
31 
33 
36 {
37  auto params = MooseObjectAction::validParams();
38 
39  // The user may specify a type in the Variables block, but if they don't we'll just use all the
40  // parameters available from MooseVariableBase
41  params.set<std::string>("type") = "MooseVariableBase";
42 
43  // The below is for backwards compatibility
46  params.addParam<MooseEnum>(
47  "family", families, "Specifies the family of FE shape functions to use for this variable");
48  params.addParam<MooseEnum>("order",
49  orders,
50  "Specifies the order of the FE shape function to use "
51  "for this variable (additional orders not listed are "
52  "allowed)");
53  params.addParam<std::vector<Real>>("scaling",
54  "Specifies a scaling factor to apply to this variable");
55  return params;
56 }
57 
59  : MooseObjectAction(params),
60  _fe_type(feType(params)),
61  _scalar_var(_fe_type.family == SCALAR),
62  _components(1)
63 {
64 }
65 
68 {
69  return MooseEnum("LAGRANGE MONOMIAL HERMITE SCALAR HIERARCHIC CLOUGH XYZ SZABAB BERNSTEIN "
70  "L2_LAGRANGE L2_HIERARCHIC NEDELEC_ONE LAGRANGE_VEC MONOMIAL_VEC",
71  "LAGRANGE");
72 }
73 
76 {
77  return MooseEnum("CONSTANT FIRST SECOND THIRD FOURTH", "FIRST", true);
78 }
79 
80 FEType
82 {
83  return {Utility::string_to_enum<Order>(params.get<MooseEnum>("order")),
84  Utility::string_to_enum<FEFamily>(params.get<MooseEnum>("family"))};
85 }
86 
87 void
89 {
90  _components = _moose_object_pars.get<unsigned int>("components");
91  if (_components == 0)
92  mooseError("There must be at least one variable component, but somehow 0 has been specified");
93 
94  // We have to do some sanity checks because of our work to maintain backwards compatibility.
95  // `family`, `order`, and `scaling` are all parameters duplicated between this action and the
96  // `MooseVariable*` object itself. Consequently during input file parsing, the params objects for
97  // both the action and MooseVariable object can be populated with the exact same parameters.
98  // However, some applications actually create their variables solely through creation and setting
99  // of `AddVariableAction` parameters which means that the `MooseVariableBase*` params will never
100  // be populated. So we should apply the parameters directly from the action. There should be no
101  // case in which both params objects get set by the user and they have different values
102 
103  if (_pars.isParamSetByUser("family") && _moose_object_pars.isParamSetByUser("family") &&
104  !_pars.get<MooseEnum>("family").compareCurrent(_moose_object_pars.get<MooseEnum>("family")))
105  mooseError("Both the MooseVariable* and Add*VariableAction parameters objects have had the "
106  "`family` parameter set, and they are different values: ",
107  _moose_object_pars.get<MooseEnum>("family"),
108  " and ",
109  _pars.get<MooseEnum>("family"),
110  " respectively. I don't know how you achieved this, but you need to rectify it.");
111 
112  if (_pars.isParamSetByUser("order") && _moose_object_pars.isParamSetByUser("order") &&
113  !_pars.get<MooseEnum>("order").compareCurrent(_moose_object_pars.get<MooseEnum>("order")))
114  mooseError("Both the MooseVariable* and Add*VariableAction parameters objects have had the "
115  "`order` parameter set, and they are different values: ",
116  _moose_object_pars.get<MooseEnum>("order"),
117  " and ",
118  _pars.get<MooseEnum>("order"),
119  " respectively. I don't know how you achieved this, but you need to rectify it.");
120 
121  if (_pars.isParamSetByUser("scaling") && _moose_object_pars.isParamSetByUser("scaling") &&
122  _pars.get<std::vector<Real>>("scaling") !=
123  _moose_object_pars.get<std::vector<Real>>("scaling"))
124  mooseError("Both the MooseVariable* and Add*VariableAction parameters objects have had the "
125  "`scaling` parameter set, and they are different values. I don't know how you "
126  "achieved this, but you need to rectify it.");
127 
128  _moose_object_pars.applySpecificParameters(_pars, {"order", "family", "scaling"});
129 
130  // Determine the MooseVariable type
132 
133  // Need static_cast to resolve overloads
134  _problem_add_var_method = static_cast<void (FEProblemBase::*)(
135  const std::string &, const std::string &, InputParameters &)>(&FEProblemBase::addVariable);
136 }
137 
138 void
140 {
141  // If we've been called that means that current_task == "add_variable"
142  init();
143 
144  // Get necessary data for creating a variable
145  std::string var_name = name();
146  addVariable(var_name);
147 
148  // Set the initial condition
149  if (_moose_object_pars.isParamValid("initial_condition"))
151 }
152 
153 void
155 {
156  // Variable name
157  std::string var_name = name();
158 
159  // Create the object name
160  std::string long_name("");
161  long_name += var_name;
162  long_name += "_moose";
163 
164  // Set the parameters for the action
165  InputParameters action_params = _action_factory.getValidParams("AddOutputAction");
166  action_params.set<ActionWarehouse *>("awh") = &_awh;
167 
168  if (_scalar_var)
169  action_params.set<std::string>("type") = "ScalarConstantIC";
170  else if (_components == 1)
171  action_params.set<std::string>("type") = "ConstantIC";
172  else
173  action_params.set<std::string>("type") = "ArrayConstantIC";
174 
175  // Create the action
176  std::shared_ptr<MooseObjectAction> action = std::static_pointer_cast<MooseObjectAction>(
177  _action_factory.create("AddInitialConditionAction", long_name, action_params));
178 
179  // Set the required parameters for the object to be created
180  action->getObjectParams().set<VariableName>("variable") = var_name;
181  auto value = _moose_object_pars.get<std::vector<Real>>("initial_condition");
182  if (value.size() != _components)
183  mooseError("Size of 'initial_condition' is not consistent");
184  if (_components > 1)
185  {
187  for (unsigned int i = 0; i < _components; ++i)
188  v(i) = value[i];
189  action->getObjectParams().set<RealEigenVector>("value") = v;
190  }
191  else
192  action->getObjectParams().set<Real>("value") = value[0];
193 
194  // Store the action in the ActionWarehouse
195  _awh.addActionBlock(action);
196 }
197 
198 std::string
199 AddVariableAction::determineType(const FEType & fe_type, unsigned int components)
200 {
201  if (components > 1)
202  {
203  if (fe_type.family == LAGRANGE_VEC || fe_type.family == NEDELEC_ONE ||
204  fe_type.family == MONOMIAL_VEC)
205  mooseError("Vector finite element families do not currently have ArrayVariable support");
206  else
207  return "ArrayMooseVariable";
208  }
209  else if (fe_type == FEType(0, MONOMIAL))
210  return "MooseVariableConstMonomial";
211  else if (fe_type.family == SCALAR)
212  return "MooseVariableScalar";
213  else if (fe_type.family == LAGRANGE_VEC || fe_type.family == NEDELEC_ONE ||
214  fe_type.family == MONOMIAL_VEC)
215  return "VectorMooseVariable";
216  else
217  return "MooseVariable";
218 }
219 
220 void
221 AddVariableAction::addVariable(const std::string & var_name)
222 {
223  // Compare sizes of scaling_factor and components for Array Variables
224  const auto & scale_factor = _moose_object_pars.isParamValid("scaling")
225  ? _moose_object_pars.get<std::vector<Real>>("scaling")
226  : std::vector<Real>(_components, 1);
227  if (scale_factor.size() != _components)
228  mooseError("Size of 'scaling' is not consistent");
229 
231 
232  if (_moose_object_pars.get<bool>("eigen"))
233  {
234  MooseEigenSystem & esys(static_cast<MooseEigenSystem &>(_problem->getNonlinearSystemBase()));
235  esys.markEigenVariable(var_name);
236  }
237 }
238 
239 std::set<SubdomainID>
241 {
242  // Extract and return the block ids supplied in the input
243  std::set<SubdomainID> blocks;
244  std::vector<SubdomainName> block_param =
245  _moose_object_pars.get<std::vector<SubdomainName>>("block");
246  for (const auto & subdomain_name : block_param)
247  {
248  SubdomainID blk_id = _problem->mesh().getSubdomainID(subdomain_name);
249  blocks.insert(blk_id);
250  }
251  return blocks;
252 }
FEProblemBase::addVariable
virtual void addVariable(const std::string &var_type, const std::string &var_name, InputParameters &params)
Canonical method for adding a non-linear variable.
Definition: FEProblemBase.C:2013
InputParameters::isParamSetByUser
bool isParamSetByUser(const std::string &name) const
Method returns true if the parameter was by the user.
Definition: InputParameters.C:837
MooseMesh.h
FEProblem.h
ActionFactory::getValidParams
InputParameters getValidParams(const std::string &name)
Definition: ActionFactory.C:70
AddVariableAction::getSubdomainIDs
std::set< SubdomainID > getSubdomainIDs()
Get the block ids from the input parameters.
Definition: AddVariableAction.C:240
AddVariableAction::_fe_type
FEType _fe_type
FEType for the variable being created.
Definition: AddVariableAction.h:87
AddVariableAction::act
virtual void act() override
Method to add objects to the simulation or perform other setup tasks.
Definition: AddVariableAction.C:139
AddVariableAction::determineType
static std::string determineType(const FEType &fe_type, unsigned int components)
determine the variable type given an FEType and number of components
Definition: AddVariableAction.C:199
registerMooseAction
registerMooseAction("MooseApp", AddVariableAction, "add_variable")
MooseEnum
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition: MooseEnum.h:31
defineLegacyParams
defineLegacyParams(AddVariableAction)
ActionWarehouse::addActionBlock
void addActionBlock(std::shared_ptr< Action > blk)
This method add an Action instance to the warehouse.
Definition: ActionWarehouse.C:73
Action::name
const std::string & name() const
The name of the action.
Definition: Action.h:105
MooseEigenSystem
Definition: MooseEigenSystem.h:19
Action::_action_factory
ActionFactory & _action_factory
Builds Actions.
Definition: Action.h:219
Action::_problem
std::shared_ptr< FEProblemBase > & _problem
Convenience reference to a problem this action works on.
Definition: Action.h:246
AddVariableAction::getNonlinearVariableOrders
static MooseEnum getNonlinearVariableOrders()
Get the possible variable orders.
Definition: AddVariableAction.C:75
mooseError
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition: MooseError.h:210
MooseObjectAction::validParams
static InputParameters validParams()
Definition: MooseObjectAction.C:21
ActionWarehouse
Storage for action instances.
Definition: ActionWarehouse.h:34
InputParameters
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
Definition: InputParameters.h:53
InputParameters::set
T & set(const std::string &name, bool quiet_mode=false)
Returns a writable reference to the named parameters.
Definition: InputParameters.h:987
ActionFactory::create
std::shared_ptr< Action > create(const std::string &action, const std::string &action_name, InputParameters &parameters)
Definition: ActionFactory.C:41
AddVariableAction::getNonlinearVariableFamilies
static MooseEnum getNonlinearVariableFamilies()
Get the possible variable families.
Definition: AddVariableAction.C:67
AddVariableAction::_components
unsigned int _components
Number of components for an array variable.
Definition: AddVariableAction.h:93
MooseObjectAction::_type
std::string _type
The Object type that is being created.
Definition: MooseObjectAction.h:48
InputParameters::isParamValid
bool isParamValid(const std::string &name) const
This method returns parameters that have been initialized in one fashion or another,...
Definition: InputParameters.C:257
MooseObjectAction::_moose_object_pars
InputParameters _moose_object_pars
The parameters for the object to be created.
Definition: MooseObjectAction.h:51
Action::_name
std::string _name
The name of the action.
Definition: Action.h:207
AddVariableAction
Adds nonlinear variable.
Definition: AddVariableAction.h:25
Action::_pars
InputParameters _pars
Input parameters for the action.
Definition: Action.h:201
SubdomainID
subdomain_id_type SubdomainID
Definition: AutomaticMortarGeneration.h:48
MooseObjectAction.h
AddVariableAction::addVariable
void addVariable(const std::string &var_name)
Adds a nonlinear variable to the system.
Definition: AddVariableAction.C:221
MooseEnum.h
AddVariableAction::feType
static FEType feType(const InputParameters &params)
determine the FEType by examining family and order in the provided parameters
Definition: AddVariableAction.C:81
MooseEigenSystem.h
AddVariableAction::init
virtual void init()
Initialize the action's member variables.
Definition: AddVariableAction.C:88
MooseObjectAction
Definition: MooseObjectAction.h:21
libMesh::RealEigenVector
Eigen::Matrix< Real, Eigen::Dynamic, 1 > RealEigenVector
Definition: MooseTypes.h:133
AddVariableAction.h
Action::_awh
ActionWarehouse & _awh
Reference to ActionWarehouse where we store object build by actions.
Definition: Action.h:237
FEProblemBase
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
Definition: FEProblemBase.h:139
Factory.h
MooseEigenSystem::markEigenVariable
virtual void markEigenVariable(const VariableName &var_name)
Mark a variable as a variable of the eigen system.
Definition: MooseEigenSystem.C:74
InputParameters::applySpecificParameters
void applySpecificParameters(const InputParameters &common, const std::vector< std::string > &include, bool allow_private=false)
Method for applying common parameters.
Definition: InputParameters.C:729
AddVariableAction::_scalar_var
bool _scalar_var
True if the variable being created is a scalar.
Definition: AddVariableAction.h:90
AddVariableAction::_problem_add_var_method
std::function< void(FEProblemBase &, const std::string &, const std::string &, InputParameters &)> _problem_add_var_method
Definition: AddVariableAction.h:96
AddVariableAction::createInitialConditionAction
void createInitialConditionAction()
Create the action to generate the InitialCondition object.
Definition: AddVariableAction.C:154
AddVariableAction::validParams
static InputParameters validParams()
Class constructor.
Definition: AddVariableAction.C:35
AddVariableAction::AddVariableAction
AddVariableAction(InputParameters params)
Definition: AddVariableAction.C:58