www.mooseframework.org
MooseVariableBase.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 #include "MooseVariableBase.h"
11 
12 #include "AddVariableAction.h"
13 #include "SubProblem.h"
14 #include "SystemBase.h"
15 #include "MooseMesh.h"
16 #include "MooseApp.h"
18 #include "BlockRestrictable.h"
19 
20 #include "libmesh/variable.h"
21 #include "libmesh/dof_map.h"
22 #include "libmesh/system.h"
23 #include "libmesh/fe_type.h"
24 #include "libmesh/string_to_enum.h"
25 
26 // Users should never actually create this object
28 
31 {
34  params += OutputInterface::validParams();
35 
37  "CONSTANT FIRST SECOND THIRD FOURTH FIFTH SIXTH SEVENTH EIGHTH NINTH TENTH ELEVENTH TWELFTH "
38  "THIRTEENTH FOURTEENTH FIFTEENTH SIXTEENTH SEVENTEENTH EIGHTTEENTH NINETEENTH TWENTIETH "
39  "TWENTYFIRST TWENTYSECOND TWENTYTHIRD TWENTYFOURTH TWENTYFIFTH TWENTYSIXTH TWENTYSEVENTH "
40  "TWENTYEIGHTH TWENTYNINTH THIRTIETH THIRTYFIRST THIRTYSECOND THIRTYTHIRD THIRTYFOURTH "
41  "THIRTYFIFTH THIRTYSIXTH THIRTYSEVENTH THIRTYEIGHTH THIRTYNINTH FORTIETH FORTYFIRST "
42  "FORTYSECOND FORTYTHIRD",
43  "FIRST",
44  true);
45  params.addParam<MooseEnum>("order",
46  order,
47  "Order of the FE shape function to use for this variable (additional "
48  "orders not listed here are allowed, depending on the family).");
49 
51 
52  params.addParam<MooseEnum>(
53  "family", family, "Specifies the family of FE shape functions to use for this variable.");
54 
55  // ArrayVariable capability
56  params.addRangeCheckedParam<unsigned int>(
57  "components", 1, "components>0", "Number of components for an array variable");
58 
59  // Advanced input options
60  params.addParam<std::vector<Real>>("scaling",
61  "Specifies a scaling factor to apply to this variable");
62  params.addParam<bool>("eigen", false, "True to make this variable an eigen variable");
63  params.addParam<bool>("fv", false, "True to make this variable a finite volume variable");
64  params.addParam<bool>("array",
65  false,
66  "True to make this variable a array variable regardless of number of "
67  "components. If 'components' > 1, this will automatically be set to true.");
68  params.addParam<NonlinearSystemName>("nl_sys",
69  "nl0",
70  "If this variable is a nonlinear variable, this is the "
71  "nonlinear system to which it should be added.");
72  params.addParamNamesToGroup("scaling eigen", "Advanced");
73 
74  params.addParam<bool>("use_dual", false, "True to use dual basis for Lagrange multipliers");
75 
76  params.registerBase("MooseVariableBase");
77  params.addPrivateParam<SystemBase *>("_system_base");
78  params.addPrivateParam<FEProblemBase *>("_fe_problem_base");
79  params.addPrivateParam<Moose::VarKindType>("_var_kind");
80  params.addPrivateParam<unsigned int>("_var_num");
81  params.addPrivateParam<THREAD_ID>("tid");
82 
83  params.addClassDescription(
84  "Base class for Moose variables. This should never be the terminal object type");
85  return params;
86 }
87 
89  : MooseObject(parameters),
90  BlockRestrictable(this),
91  OutputInterface(parameters),
92  SetupInterface(this),
93  _sys(*getParam<SystemBase *>("_system_base")), // TODO: get from _fe_problem_base
94  _fe_type(Utility::string_to_enum<Order>(getParam<MooseEnum>("order")),
95  Utility::string_to_enum<FEFamily>(getParam<MooseEnum>("family"))),
96  _var_num(getParam<unsigned int>("_var_num")),
97  _is_eigen(getParam<bool>("eigen")),
98  _var_kind(getParam<Moose::VarKindType>("_var_kind")),
99  _subproblem(_sys.subproblem()),
100  _variable(_sys.system().variable(_var_num)),
101  _assembly(_subproblem.assembly(getParam<THREAD_ID>("_tid"),
102  _var_kind == Moose::VAR_NONLINEAR ? _sys.number() : 0)),
103  _dof_map(_sys.dofMap()),
104  _mesh(_subproblem.mesh()),
105  _tid(getParam<THREAD_ID>("tid")),
106  _count(getParam<unsigned int>("components")),
107  _scaling_factor(_count, 1.0),
108  _use_dual(getParam<bool>("use_dual")),
109  _is_array(getParam<bool>("array"))
110 {
111  scalingFactor(isParamValid("scaling") ? getParam<std::vector<Real>>("scaling")
112  : std::vector<Real>(_count, 1.));
113  if (getParam<bool>("fv") && getParam<bool>("eigen"))
114  paramError("eigen", "finite volume (fv=true) variables do not have eigen support");
115  if (getParam<bool>("fv") && _fe_type.family != MONOMIAL)
116  paramError("family", "finite volume (fv=true) variables must be have MONOMIAL family");
117  if (getParam<bool>("fv") && _fe_type.order != 0)
118  paramError("order", "finite volume (fv=true) variables currently support CONST order only");
119  if (_count > 1)
120  mooseAssert(_is_array, "Must be true with component > 1");
121  if (_is_array)
122  {
123  auto name0 = _sys.system().variable(_var_num).name();
124  std::size_t found = name0.find_last_of("_");
125  if (found == std::string::npos)
126  mooseError("Error creating ArrayMooseVariable name with base name ", name0);
127  _var_name = name0.substr(0, found);
128  }
129  else
130  {
131  mooseAssert(_count == 1, "component size of normal variable (_count) must be one");
132  _var_name = _sys.system().variable(_var_num).name();
133  }
134 
135  if (!blockRestricted())
136  _is_lower_d = false;
137  else
138  {
139  const auto & blk_ids = blockIDs();
140  mooseAssert(!blk_ids.empty(), "Every variable should have at least one subdomain");
141 
142  _is_lower_d = _mesh.isLowerD(*blk_ids.begin());
143 #ifdef DEBUG
144  for (auto it = ++blk_ids.begin(); it != blk_ids.end(); ++it)
145  mooseAssert(_is_lower_d == _mesh.isLowerD(*it),
146  "A user should not specify a mix of lower-dimensional and higher-dimensional "
147  "blocks for a variable");
148 #endif
149  }
150 }
151 
152 const std::vector<dof_id_type> &
154 {
155  const auto it = _sys.subproblem()._var_dof_map.find(name());
156  if (it != _sys.subproblem()._var_dof_map.end())
157  return it->second;
158  else
159  mooseError("VariableAllDoFMap not prepared for ",
160  name(),
161  " . Check nonlocal coupling requirement for the variable.");
162 }
163 
164 Order
166 {
167  return _fe_type.order;
168 }
169 
170 std::vector<dof_id_type>
171 MooseVariableBase::componentDofIndices(const std::vector<dof_id_type> & dof_indices,
172  unsigned int component) const
173 {
174  std::vector<dof_id_type> new_dof_indices(dof_indices);
175  if (component != 0)
176  {
177  if (isNodal())
178  for (auto & id : new_dof_indices)
179  id += component;
180  else
181  {
182  unsigned int n = dof_indices.size();
183  for (auto & id : new_dof_indices)
184  id += component * n;
185  }
186  }
187  return new_dof_indices;
188 }
189 
190 void
191 MooseVariableBase::scalingFactor(const std::vector<Real> & factor)
192 {
193  mooseAssert(factor.size() == _count, "Inconsistent scaling factor size");
194  for (const auto i : make_range(_count))
195  _scaling_factor[i] = factor[i];
196 }
197 
198 void
200 {
201  // Currently the scaling vector is only used through AD residual computing objects
203  (_subproblem.automaticScaling() || (std::find_if(_scaling_factor.begin(),
204  _scaling_factor.end(),
205  [](const Real element) {
207  element, 1.);
208  }) != _scaling_factor.end())))
209 
211 }
static InputParameters validParams()
virtual bool isNodal() const
Is this variable nodal.
std::vector< dof_id_type > componentDofIndices(const std::vector< dof_id_type > &dof_indices, unsigned int component) const
Obtain DoF indices of a component with the indices of the 0th component.
Order
FEType _fe_type
The FEType associated with this variable.
virtual void haveADObjects(bool have_ad_objects)
Method for setting whether we have any ad objects.
Definition: SubProblem.h:722
bool absoluteFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
Function to check whether two variables are equal within an absolute tolerance.
Definition: MooseUtils.h:346
static InputParameters validParams()
void addPrivateParam(const std::string &name, const T &value)
These method add a parameter to the InputParameters object which can be retrieved like any other para...
bool _is_lower_d
Whether this variable lives on lower dimensional blocks.
A class to provide an common interface to objects requiring "outputs" option.
MeshBase & mesh
const std::string & name() const override
Get the variable name.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
std::string _var_name
Variable name.
virtual const std::set< SubdomainID > & blockIDs() const
Return the block subdomain ids for this object Note, if this is not block restricted, this function returns all mesh subdomain ids.
virtual bool blockRestricted() const
Returns true if this object has been restricted to a block.
void addScalingVector()
Add the scaling factor vector to the system.
Definition: SystemBase.C:1474
Base class for a system (of equations)
Definition: SystemBase.h:84
void initialSetup() override
Gets called at the beginning of the simulation before this object is asked to do its job...
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
static MooseEnum getNonlinearVariableFamilies()
Get the possible variable families.
bool isLowerD(const SubdomainID subdomain_id) const
Definition: MooseMesh.h:2132
static InputParameters validParams()
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...
std::map< std::string, std::vector< dof_id_type > > _var_dof_map
Definition: SubProblem.h:629
registerMooseObject("MooseApp", MooseVariableBase)
SubProblem & _subproblem
Problem this variable is part of.
Every object that can be built by the factory should be derived from this class.
Definition: MooseObject.h:33
SystemBase & _sys
System this variable is part of.
T string_to_enum(const std::string &s)
VarKindType
Framework-wide stuff.
Definition: MooseTypes.h:627
std::vector< Real > _scaling_factor
scaling factor for this variable
const T & getParam(const std::string &name) const
Retrieve a parameter for the object.
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition: MooseEnum.h:31
Moose::VarKindType _var_kind
Variable type (see MooseTypes.h)
Real scalingFactor() const
Get the scaling factor for this variable.
virtual void automaticScaling(bool automatic_scaling)
Automatic scaling setter.
Definition: SubProblem.C:1100
virtual SubProblem & subproblem()
Definition: SystemBase.h:98
const unsigned int _count
Number of variables in the array.
virtual System & system()=0
Get the reference to the libMesh system.
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 ...
MONOMIAL
MooseMesh & _mesh
mesh the variable is active in
Order order() const
Get the order of this variable Note: Order enum can be implicitly converted to unsigned int...
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const std::vector< dof_id_type > & allDofIndices() const
Get all global dofindices for the variable.
unsigned int _var_num
variable number (from libMesh)
An interface that restricts an object to subdomains via the &#39;blocks&#39; input parameter.
IntRange< T > make_range(T beg, T end)
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...
void addRangeCheckedParam(const std::string &name, const T &value, const std::string &parsed_function, const std::string &doc_string)
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...
static InputParameters validParams()
Definition: MooseObject.C:24
FEFamily
const bool _is_array
Whether this is an array variable.
void ErrorVector unsigned int
MooseVariableBase(const InputParameters &parameters)
unsigned int THREAD_ID
Definition: MooseTypes.h:198
void addParamNamesToGroup(const std::string &space_delim_names, const std::string group_name)
This method takes a space delimited list of parameter names and adds them to the specified group name...