https://mooseframework.inl.gov
MooseVariableBase.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 #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 using namespace libMesh;
27 
28 // Users should never actually create this object
30 
33 {
36  params += OutputInterface::validParams();
37 
40 
41  // ArrayVariable capability
42  params.addRangeCheckedParam<unsigned int>(
43  "components", 1, "components>0", "Number of components for an array variable");
44 
45  // Advanced input options
46  params.transferParam<std::vector<Real>>(AddVariableAction::validParams(), "scaling");
47  params.addParam<bool>("eigen", false, "True to make this variable an eigen variable");
48  params.addParam<bool>("fv", false, "True to make this variable a finite volume variable");
49  params.addParam<bool>("array",
50  false,
51  "True to make this variable a array variable regardless of number of "
52  "components. If 'components' > 1, this will automatically be set to true.");
53 
54  params.addParam<std::vector<std::string>>(
55  "array_var_component_names",
56  "Only for use with array variables, allows setting custom names for each array variable "
57  "component. If this not set, the default name for each array variable componenet is "
58  "`base_name`+'_'+component number. If used, a name must be provided for each component and "
59  "the values are used to name the components as `base_name`+'_'+ "
60  "`array_var_component_names[component]`.");
61 
62  params.addParam<SolverSystemName>("solver_sys",
63  "nl0",
64  "If this variable is a solver variable, this is the "
65  "solver system to which it should be added.");
66  params.addParam<bool>(
67  "disable_p_refinement",
68  "True to disable p-refinement for this variable. Note that because this happens on the "
69  "family basis, users need to have this flag consistently set for all variables in the same "
70  "family. Currently MOOSE disables p-refinement for variables in the following families by "
71  "default: LAGRANGE NEDELEC_ONE RAVIART_THOMAS LAGRANGE_VEC CLOUGH BERNSTEIN and "
72  "RATIONAL_BERNSTEIN.");
73 
74  params.addParamNamesToGroup("scaling eigen", "Advanced");
75 
76  params.addParam<bool>("use_dual", false, "True to use dual basis for Lagrange multipliers");
77  params.transferParam<std::vector<Real>>(AddVariableAction::validParams(), "initial_condition");
78  params.transferParam<std::string>(AddVariableAction::validParams(), "initial_from_file_var");
79  params.addParamNamesToGroup("scaling eigen use_dual", "Advanced");
80 
81  params.registerBase("MooseVariableBase");
82  params.addPrivateParam<SystemBase *>("_system_base");
83  params.addPrivateParam<FEProblemBase *>("_fe_problem_base");
84  params.addPrivateParam<Moose::VarKindType>("_var_kind");
85  params.addPrivateParam<unsigned int>("_var_num");
86  params.addPrivateParam<THREAD_ID>("tid");
87 
88  params.addClassDescription(
89  "Base class for Moose variables. This should never be the terminal object type");
90  return params;
91 }
92 
94  : MooseObject(parameters),
95  BlockRestrictable(this),
96  OutputInterface(parameters),
97  SetupInterface(this),
98  _sys(*getParam<SystemBase *>("_system_base")), // TODO: get from _fe_problem_base
99  _fe_type(Utility::string_to_enum<Order>(getParam<MooseEnum>("order")),
100  Utility::string_to_enum<FEFamily>(getParam<MooseEnum>("family"))),
101  _var_num(getParam<unsigned int>("_var_num")),
102  _is_eigen(getParam<bool>("eigen")),
103  _var_kind(getParam<Moose::VarKindType>("_var_kind")),
104  _subproblem(_sys.subproblem()),
105  _variable(_sys.system().variable(_var_num)),
106  _assembly(_subproblem.assembly(getParam<THREAD_ID>("_tid"),
107  (_var_kind == Moose::VAR_SOLVER) ? _sys.number() : 0)),
108  _dof_map(_sys.dofMap()),
109  _mesh(_subproblem.mesh()),
110  _tid(getParam<THREAD_ID>("tid")),
111  _count(getParam<unsigned int>("components")),
112  _scaling_factor(_count, 1.0),
113  _use_dual(getParam<bool>("use_dual"))
114 {
115  scalingFactor(isParamValid("scaling") ? getParam<std::vector<Real>>("scaling")
116  : std::vector<Real>(_count, 1.));
117  if (getParam<bool>("fv") && getParam<bool>("eigen"))
118  paramError("eigen", "finite volume (fv=true) variables do not have eigen support");
119  if (getParam<bool>("fv") && _fe_type.family != MONOMIAL)
120  paramError("family", "finite volume (fv=true) variables must be have MONOMIAL family");
121  if (getParam<bool>("fv") && _fe_type.order != 0)
122  paramError("order", "finite volume (fv=true) variables currently support CONST order only");
123 
124  if (isParamValid("array_var_component_names"))
125  {
126  auto name0 = _sys.system().variable(_var_num).name();
127  std::size_t found = name0.find_last_of("_");
128  if (found == std::string::npos)
129  mooseError("Error creating ArrayMooseVariable name with base name ", name0);
130  const auto name_base = name0.substr(0, found);
131  const auto & name_endings = getParam<std::vector<std::string>>("array_var_component_names");
132  for (const auto & name : name_endings)
133  _array_var_component_names.push_back(name_base + '_' + name);
134  }
135  else if (_count != 1)
136  mooseError("Component size of normal variable (_count) must be one; equals " +
137  std::to_string(_count) + "");
138 
139  // check parameters set automatically by SystemBase related to array variables
140  mooseAssert(
141  isArray() ? _count == _array_var_component_names.size() : true,
142  "An inconsistent numer of names or no names were provided for array variable components");
143  if (_count > 1)
144  mooseAssert(isArray(), "Must be true with component > 1");
145 }
146 
147 const std::string &
148 MooseVariableBase::arrayVariableComponent(const unsigned int i) const
149 {
150  mooseAssert(
151  i < _array_var_component_names.size(),
152  "Requested array variable component number is greater than the number of component names.");
153  return _array_var_component_names[i];
154 }
155 
156 const std::vector<dof_id_type> &
158 {
159  const auto it = _sys.subproblem()._var_dof_map.find(name());
160  if (it != _sys.subproblem()._var_dof_map.end())
161  return it->second;
162  else
163  mooseError("VariableAllDoFMap not prepared for ",
164  name(),
165  " . Check nonlocal coupling requirement for the variable.");
166 }
167 
168 Order
170 {
171  return _fe_type.order;
172 }
173 
174 std::vector<dof_id_type>
175 MooseVariableBase::componentDofIndices(const std::vector<dof_id_type> & dof_indices,
176  unsigned int component) const
177 {
178  mooseAssert(dof_indices.size() % this->count() == 0,
179  "The dof indices container must be a multiple of count");
180  std::vector<dof_id_type> new_dof_indices(dof_indices.size() / this->count());
181  for (const auto i : index_range(new_dof_indices))
182  new_dof_indices[i] = dof_indices[component * new_dof_indices.size() + i];
183  return new_dof_indices;
184 }
185 
186 void
187 MooseVariableBase::scalingFactor(const std::vector<Real> & factor)
188 {
189  mooseAssert(factor.size() == _count, "Inconsistent scaling factor size");
190  for (const auto i : make_range(_count))
191  _scaling_factor[i] = factor[i];
192 }
193 
194 void
196 {
197  // Currently the scaling vector is only used through AD residual computing objects
199  (_subproblem.automaticScaling() || (std::find_if(_scaling_factor.begin(),
200  _scaling_factor.end(),
201  [](const Real element) {
202  return !MooseUtils::absoluteFuzzyEqual(
203  element, 1.);
204  }) != _scaling_factor.end())))
205 
207 }
208 
209 const NumericVector<Number> &
211 {
212  // It's not safe to use solutionState(0) because it returns the libMesh System solution member
213  // which is wrong during things like finite difference Jacobian evaluation, e.g. when PETSc
214  // perturbs the solution vector we feed these perturbations into the current_local_solution
215  // while the libMesh solution is frozen in the non-perturbed state
216  return (state.state == 0) ? *this->_sys.currentSolution()
217  : this->_sys.solutionState(state.state, state.iteration_type);
218 }
static InputParameters validParams()
const libMesh::NumericVector< libMesh::Number > & getSolution(const Moose::StateArg &state) const
Get the solution corresponding to the provided state.
virtual const NumericVector< Number > *const & currentSolution() const =0
The solution vector that is currently being operated on.
static InputParameters validParams()
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
const Variable & variable(unsigned int var) const
virtual void haveADObjects(bool have_ad_objects)
Method for setting whether we have any ad objects.
Definition: SubProblem.h:767
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
const T & getParam(const std::string &name) const
Retrieve a parameter for the object.
Definition: MooseBase.h:416
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...
std::vector< std::string > _array_var_component_names
Array variable names when the variable is an array variable.
unsigned int count() const
Get the number of components Note: For standard and vector variables, the number is one...
virtual libMesh::System & system()=0
Get the reference to the libMesh system.
virtual NumericVector< Number > & solutionState(const unsigned int state, Moose::SolutionIterationType iteration_type=Moose::SolutionIterationType::Time)
Get a state of the solution (0 = current, 1 = old, 2 = older, etc).
Definition: SystemBase.C:1433
A class to provide an common interface to objects requiring "outputs" option.
MeshBase & mesh
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
OrderWrapper order
void addScalingVector()
Add the scaling factor vector to the system.
Definition: SystemBase.C:1547
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
Base class for a system (of equations)
Definition: SystemBase.h:85
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 InputParameters validParams()
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:674
registerMooseObject("MooseApp", MooseVariableBase)
const std::string & name() const
Get the name of the class.
Definition: MooseBase.h:103
SubProblem & _subproblem
Problem this variable is part of.
libMesh::FEType _fe_type
The FEType associated with this variable.
Every object that can be built by the factory should be derived from this class.
Definition: MooseObject.h:28
SystemBase & _sys
System this variable is part of.
SolutionIterationType iteration_type
The solution iteration type, e.g. time or nonlinear.
T string_to_enum(const std::string &s)
VarKindType
Framework-wide stuff.
Definition: MooseTypes.h:763
SubProblem & subproblem()
Definition: SystemBase.h:102
std::vector< Real > _scaling_factor
scaling factor for this variable
virtual bool isArray() 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
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:1156
const unsigned int _count
Number of variables in the array.
void transferParam(const InputParameters &source_param, const std::string &name, const std::string &new_name="", const std::string &new_description="")
A routine to transfer a parameter from one class&#39; validParams to another.
MONOMIAL
libMesh::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)
const std::string & arrayVariableComponent(const unsigned int i) const
Returns the variable name of a component of an array variable.
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 and optionally a file path to the top-level block p...
Definition: MooseBase.h:281
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...
State argument for evaluating functors.
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an optional 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)
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
Definition: MooseBase.h:209
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...
const std::string & name() const
static InputParameters validParams()
Definition: MooseObject.C:25
FEFamily
void ErrorVector unsigned int
auto index_range(const T &sizable)
MooseVariableBase(const InputParameters &parameters)
unsigned int state
The state.
Base variable class.
unsigned int THREAD_ID
Definition: MooseTypes.h:237
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...