Line data Source code
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"
17 : #include "InputParameterWarehouse.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
29 : registerMooseObject("MooseApp", MooseVariableBase);
30 :
31 : InputParameters
32 404945 : MooseVariableBase::validParams()
33 : {
34 404945 : InputParameters params = MooseObject::validParams();
35 404945 : params += BlockRestrictable::validParams();
36 404945 : params += OutputInterface::validParams();
37 :
38 2429670 : params.transferParam<MooseEnum>(AddVariableAction::validParams(), "order");
39 2429670 : params.transferParam<MooseEnum>(AddVariableAction::validParams(), "family");
40 :
41 : // ArrayVariable capability
42 2024725 : params.addRangeCheckedParam<unsigned int>(
43 809890 : "components", 1, "components>0", "Number of components for an array variable");
44 :
45 : // Advanced input options
46 2429670 : params.transferParam<std::vector<Real>>(AddVariableAction::validParams(), "scaling");
47 1619780 : params.addParam<bool>("eigen", false, "True to make this variable an eigen variable");
48 1619780 : params.addParam<bool>("fv", false, "True to make this variable a finite volume variable");
49 1214835 : params.addParam<bool>("array",
50 809890 : 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 1619780 : 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 1619780 : 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 1619780 : 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 1619780 : params.addParamNamesToGroup("scaling eigen", "Advanced");
75 :
76 1619780 : params.addParam<bool>("use_dual", false, "True to use dual basis for Lagrange multipliers");
77 2429670 : params.transferParam<std::vector<Real>>(AddVariableAction::validParams(), "initial_condition");
78 2429670 : params.transferParam<std::string>(AddVariableAction::validParams(), "initial_from_file_var");
79 1619780 : params.addParamNamesToGroup("scaling eigen use_dual", "Advanced");
80 :
81 809890 : params.registerBase("MooseVariableBase");
82 809890 : params.addPrivateParam<SystemBase *>("_system_base");
83 809890 : params.addPrivateParam<FEProblemBase *>("_fe_problem_base");
84 809890 : params.addPrivateParam<Moose::VarKindType>("_var_kind");
85 809890 : params.addPrivateParam<unsigned int>("_var_num");
86 809890 : params.addPrivateParam<THREAD_ID>("tid");
87 :
88 404945 : params.addClassDescription(
89 : "Base class for Moose variables. This should never be the terminal object type");
90 404945 : return params;
91 0 : }
92 :
93 183856 : MooseVariableBase::MooseVariableBase(const InputParameters & parameters)
94 : : MooseObject(parameters),
95 : BlockRestrictable(this),
96 : OutputInterface(parameters),
97 : SetupInterface(this),
98 183856 : _sys(*getParam<SystemBase *>("_system_base")), // TODO: get from _fe_problem_base
99 551568 : _fe_type(Utility::string_to_enum<Order>(getParam<MooseEnum>("order")),
100 551568 : Utility::string_to_enum<FEFamily>(getParam<MooseEnum>("family"))),
101 367712 : _var_num(getParam<unsigned int>("_var_num")),
102 367712 : _is_eigen(getParam<bool>("eigen")),
103 367712 : _var_kind(getParam<Moose::VarKindType>("_var_kind")),
104 183856 : _subproblem(_sys.subproblem()),
105 183856 : _variable(_sys.system().variable(_var_num)),
106 367712 : _assembly(_subproblem.assembly(getParam<THREAD_ID>("_tid"),
107 183856 : (_var_kind == Moose::VAR_SOLVER) ? _sys.number() : 0)),
108 183856 : _dof_map(_sys.dofMap()),
109 183856 : _mesh(_subproblem.mesh()),
110 367712 : _tid(getParam<THREAD_ID>("tid")),
111 367712 : _count(getParam<unsigned int>("components")),
112 367712 : _scaling_factor(_count, 1.0),
113 919280 : _use_dual(getParam<bool>("use_dual"))
114 : {
115 735866 : scalingFactor(isParamValid("scaling") ? getParam<std::vector<Real>>("scaling")
116 367270 : : std::vector<Real>(_count, 1.));
117 564866 : if (getParam<bool>("fv") && getParam<bool>("eigen"))
118 0 : paramError("eigen", "finite volume (fv=true) variables do not have eigen support");
119 551568 : if (getParam<bool>("fv") && _fe_type.family != MONOMIAL)
120 0 : paramError("family", "finite volume (fv=true) variables must be have MONOMIAL family");
121 551568 : if (getParam<bool>("fv") && _fe_type.order != 0)
122 0 : paramError("order", "finite volume (fv=true) variables currently support CONST order only");
123 :
124 551568 : if (isParamValid("array_var_component_names"))
125 : {
126 2485 : auto name0 = _sys.system().variable(_var_num).name();
127 2485 : std::size_t found = name0.find_last_of("_");
128 2485 : if (found == std::string::npos)
129 0 : mooseError("Error creating ArrayMooseVariable name with base name ", name0);
130 2485 : const auto name_base = name0.substr(0, found);
131 4970 : const auto & name_endings = getParam<std::vector<std::string>>("array_var_component_names");
132 8121 : for (const auto & name : name_endings)
133 5636 : _array_var_component_names.push_back(name_base + '_' + name);
134 2485 : }
135 181371 : else if (_count != 1)
136 0 : mooseError("Component size of normal variable (_count) must be one; equals " +
137 0 : 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 183856 : if (_count > 1)
144 : mooseAssert(isArray(), "Must be true with component > 1");
145 183856 : }
146 :
147 : const std::string &
148 24650 : 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 24650 : return _array_var_component_names[i];
154 : }
155 :
156 : const std::vector<dof_id_type> &
157 10306 : MooseVariableBase::allDofIndices() const
158 : {
159 10306 : const auto it = _sys.subproblem()._var_dof_map.find(name());
160 10306 : if (it != _sys.subproblem()._var_dof_map.end())
161 20612 : return it->second;
162 : else
163 0 : mooseError("VariableAllDoFMap not prepared for ",
164 0 : name(),
165 : " . Check nonlocal coupling requirement for the variable.");
166 : }
167 :
168 : Order
169 294930847 : MooseVariableBase::order() const
170 : {
171 294930847 : return _fe_type.order;
172 : }
173 :
174 : std::vector<dof_id_type>
175 123537616 : 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 123537616 : std::vector<dof_id_type> new_dof_indices(dof_indices.size() / this->count());
181 668876534 : for (const auto i : index_range(new_dof_indices))
182 545338918 : new_dof_indices[i] = dof_indices[component * new_dof_indices.size() + i];
183 123537616 : return new_dof_indices;
184 0 : }
185 :
186 : void
187 184997 : MooseVariableBase::scalingFactor(const std::vector<Real> & factor)
188 : {
189 : mooseAssert(factor.size() == _count, "Inconsistent scaling factor size");
190 373155 : for (const auto i : make_range(_count))
191 188158 : _scaling_factor[i] = factor[i];
192 184997 : }
193 :
194 : void
195 178263 : MooseVariableBase::initialSetup()
196 : {
197 : // Currently the scaling vector is only used through AD residual computing objects
198 189176 : if ((_var_kind == Moose::VAR_SOLVER) && _subproblem.haveADObjects() &&
199 32133 : (_subproblem.automaticScaling() || (std::find_if(_scaling_factor.begin(),
200 : _scaling_factor.end(),
201 10633 : [](const Real element) {
202 21266 : return !MooseUtils::absoluteFuzzyEqual(
203 10633 : element, 1.);
204 199483 : }) != _scaling_factor.end())))
205 :
206 382 : _sys.addScalingVector();
207 178263 : }
208 :
209 : const NumericVector<Number> &
210 945124 : MooseVariableBase::getSolution(const Moose::StateArg & state) const
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 945124 : return (state.state == 0) ? *this->_sys.currentSolution()
217 945124 : : this->_sys.solutionState(state.state, state.iteration_type);
218 : }
|