www.mooseframework.org
ScalarCoupleable.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 "ScalarCoupleable.h"
11 
12 // MOOSE includes
13 #include "FEProblem.h"
14 #include "MooseVariableFEBase.h"
15 #include "MooseVariableScalar.h"
16 #include "Problem.h"
17 #include "SubProblem.h"
18 
20  : _sc_fe_problem(
21  *moose_object->parameters().getCheckedPointerParam<FEProblemBase *>("_fe_problem_base")),
22  _sc_tid(moose_object->parameters().isParamValid("_tid")
23  ? moose_object->parameters().get<THREAD_ID>("_tid")
24  : 0),
25  _real_zero(_sc_fe_problem._real_zero[_sc_tid]),
26  _scalar_zero(_sc_fe_problem._scalar_zero[_sc_tid]),
27  _point_zero(_sc_fe_problem._point_zero[_sc_tid]),
28  _sc_parameters(moose_object->parameters()),
29  _sc_name(_sc_parameters.get<std::string>("_object_name")),
30  _sc_is_implicit(_sc_parameters.have_parameter<bool>("implicit")
31  ? _sc_parameters.get<bool>("implicit")
32  : true)
33 {
34  SubProblem & problem = *_sc_parameters.getCheckedPointerParam<SubProblem *>("_subproblem");
35 
36  // Coupling
37  for (std::set<std::string>::const_iterator iter = _sc_parameters.coupledVarsBegin();
39  ++iter)
40  {
41  std::string name = *iter;
42  if (_sc_parameters.getVecMooseType(*iter) != std::vector<std::string>())
43  {
44  std::vector<std::string> vars = _sc_parameters.getVecMooseType(*iter);
45  for (const auto & coupled_var_name : vars)
46  {
47  if (problem.hasScalarVariable(coupled_var_name))
48  {
49  MooseVariableScalar * scalar_var = &problem.getScalarVariable(_sc_tid, coupled_var_name);
50  _coupled_scalar_vars[name].push_back(scalar_var);
51  _coupled_moose_scalar_vars.push_back(scalar_var);
52  }
53  else if (problem.hasVariable(coupled_var_name))
54  {
55  MooseVariableFEBase * moose_var =
56  &problem.getVariable(_sc_tid,
57  coupled_var_name,
60  _sc_coupled_vars[name].push_back(moose_var);
61  }
62  else
63  mooseError(_sc_name, ": Coupled variable '", coupled_var_name, "' was not found");
64  }
65  }
66  }
67 }
68 
69 bool
70 ScalarCoupleable::isCoupledScalar(const std::string & var_name_in, unsigned int i) const
71 {
72  const auto var_name = _sc_parameters.checkForRename(var_name_in);
73 
74  auto it = _coupled_scalar_vars.find(var_name);
75  if (it != _coupled_scalar_vars.end())
76  return (i < it->second.size());
77  else
78  {
79  // Make sure the user originally requested this value in the InputParameter syntax
80  if (!_sc_parameters.hasCoupledValue(var_name))
82  ": The coupled scalar variable \"",
83  var_name,
84  "\" was never added to this object's "
85  "InputParameters, please double-check "
86  "your spelling");
87 
88  return false;
89  }
90 }
91 
92 unsigned int
93 ScalarCoupleable::coupledScalar(const std::string & var_name, const unsigned int comp) const
94 {
95  checkVar(var_name);
96  return getScalarVar(var_name, comp)->number();
97 }
98 
99 Order
100 ScalarCoupleable::coupledScalarOrder(const std::string & var_name, const unsigned int comp) const
101 {
102  checkVar(var_name);
103  if (!isCoupledScalar(var_name, comp))
105 
106  return getScalarVar(var_name, comp)->order();
107 }
108 
109 const VariableValue *
110 ScalarCoupleable::getDefaultValue(const std::string & var_name) const
111 {
112  auto default_value_it = _default_value.find(var_name);
113  if (default_value_it == _default_value.end())
114  {
115  auto value = std::make_unique<VariableValue>(_sc_fe_problem.getMaxScalarOrder(),
117  default_value_it = _default_value.insert(std::make_pair(var_name, std::move(value))).first;
118  }
119 
120  return default_value_it->second.get();
121 }
122 
123 const VariableValue &
124 ScalarCoupleable::coupledScalarValue(const std::string & var_name, const unsigned int comp) const
125 {
126  checkVar(var_name);
127  if (!isCoupledScalar(var_name, comp))
128  return *getDefaultValue(var_name);
129 
130  auto var = getScalarVar(var_name, comp);
131  return _sc_is_implicit ? var->sln() : var->slnOld();
132 }
133 
134 const ADVariableValue &
135 ScalarCoupleable::adCoupledScalarValue(const std::string & var_name, const unsigned int comp) const
136 {
137  checkVar(var_name);
138  if (!isCoupledScalar(var_name, comp))
139  return *getADDefaultValue(var_name);
140 
141  auto var = getScalarVar(var_name, comp);
142 
143  if (_sc_is_implicit)
144  return var->adSln();
145  else
146  mooseError("adCoupledValue for non-implicit calculations is not currently supported. Use "
147  "coupledValue instead for non-implicit");
148 }
149 
150 template <>
152 ScalarCoupleable::coupledGenericScalarValue<false>(const std::string & var_name,
153  const unsigned int comp) const
154 {
155  return coupledScalarValue(var_name, comp);
156 }
157 
158 template <>
160 ScalarCoupleable::coupledGenericScalarValue<true>(const std::string & var_name,
161  const unsigned int comp) const
162 {
163  return adCoupledScalarValue(var_name, comp);
164 }
165 
166 const ADVariableValue *
167 ScalarCoupleable::getADDefaultValue(const std::string & var_name) const
168 {
169  auto default_value_it = _dual_default_value.find(var_name);
170  if (default_value_it == _dual_default_value.end())
171  {
172  auto value = std::make_unique<ADVariableValue>(_sc_fe_problem.getMaxScalarOrder(),
174  default_value_it = _dual_default_value.insert(std::make_pair(var_name, std::move(value))).first;
175  }
176 
177  return default_value_it->second.get();
178 }
179 
180 const VariableValue &
182  TagID tag,
183  const unsigned int comp) const
184 {
185  checkVar(var_name);
186  if (!isCoupledScalar(var_name, comp))
187  return *getDefaultValue(var_name);
188 
190  mooseError("Attempting to couple to vector tag scalar with ID ",
191  tag,
192  "in ",
193  _sc_name,
194  ", but a vector tag with that ID does not exist");
195 
196  _sc_coupleable_vector_tags.insert(tag);
197 
198  return getScalarVar(var_name, comp)->vectorTagSln(tag);
199 }
200 
201 const VariableValue &
203  TagID tag,
204  const unsigned int comp) const
205 {
206  checkVar(var_name);
207  if (!isCoupledScalar(var_name, comp))
208  return *getDefaultValue(var_name);
209 
210  _sc_coupleable_matrix_tags.insert(tag);
211 
212  return getScalarVar(var_name, comp)->matrixTagSln(tag);
213 }
214 
215 const VariableValue &
216 ScalarCoupleable::coupledScalarValueOld(const std::string & var_name, const unsigned int comp) const
217 {
218  checkVar(var_name);
219  if (!isCoupledScalar(var_name, comp))
220  return *getDefaultValue(var_name);
221 
222  validateExecutionerType(var_name, "coupledScalarValueOld");
223  auto var = getScalarVar(var_name, comp);
224  return _sc_is_implicit ? var->slnOld() : var->slnOlder();
225 }
226 
227 const VariableValue &
228 ScalarCoupleable::coupledScalarValueOlder(const std::string & var_name,
229  const unsigned int comp) const
230 {
231  checkVar(var_name);
232  if (!isCoupledScalar(var_name, comp))
233  return *getDefaultValue(var_name);
234 
235  validateExecutionerType(var_name, "coupledScalarValueOlder");
236  auto var = getScalarVar(var_name, comp);
237  if (_sc_is_implicit)
238  return var->slnOlder();
239  else
240  mooseError("Older values not available for explicit schemes");
241 }
242 
243 const VariableValue &
244 ScalarCoupleable::coupledScalarDot(const std::string & var_name, const unsigned int comp) const
245 {
246  checkVar(var_name);
247  validateExecutionerType(var_name, "coupledScalarDot");
248  return getScalarVar(var_name, comp)->uDot();
249 }
250 
251 const ADVariableValue &
252 ScalarCoupleable::adCoupledScalarDot(const std::string & var_name, const unsigned int comp) const
253 {
254  checkVar(var_name);
255  validateExecutionerType(var_name, "adCoupledScalarDot");
256  return getScalarVar(var_name, comp)->adUDot();
257 }
258 
259 const VariableValue &
260 ScalarCoupleable::coupledScalarDotDot(const std::string & var_name, const unsigned int comp) const
261 {
262  checkVar(var_name);
263  validateExecutionerType(var_name, "coupledScalarDotDot");
264  return getScalarVar(var_name, comp)->uDotDot();
265 }
266 
267 const VariableValue &
268 ScalarCoupleable::coupledScalarDotOld(const std::string & var_name, const unsigned int comp) const
269 {
270  checkVar(var_name);
271  validateExecutionerType(var_name, "coupledScalarDotOld");
272  return getScalarVar(var_name, comp)->uDotOld();
273 }
274 
275 const VariableValue &
276 ScalarCoupleable::coupledScalarDotDotOld(const std::string & var_name,
277  const unsigned int comp) const
278 {
279  checkVar(var_name);
280  validateExecutionerType(var_name, "coupledScalarDotDotOld");
281  return getScalarVar(var_name, comp)->uDotDotOld();
282 }
283 const VariableValue &
284 ScalarCoupleable::coupledScalarDotDu(const std::string & var_name, const unsigned int comp) const
285 {
286  checkVar(var_name);
287  validateExecutionerType(var_name, "coupledScalarDotDu");
288  return getScalarVar(var_name, comp)->duDotDu();
289 }
290 
291 const VariableValue &
292 ScalarCoupleable::coupledScalarDotDotDu(const std::string & var_name, const unsigned int comp) const
293 {
294  checkVar(var_name);
295  validateExecutionerType(var_name, "coupledScalarDotDotDu");
296  return getScalarVar(var_name, comp)->duDotDotDu();
297 }
298 
299 void
300 ScalarCoupleable::checkVar(const std::string & var_name_in) const
301 {
302  const auto var_name = _sc_parameters.checkForRename(var_name_in);
303 
304  auto it = _sc_coupled_vars.find(var_name);
305  if (it != _sc_coupled_vars.end())
306  {
307  std::string cvars;
308  for (auto jt : it->second)
309  cvars += " " + jt->name();
311  ": Trying to couple a field variable where scalar variable is expected, '",
312  var_name,
313  " =",
314  cvars,
315  "'");
316  }
317  // NOTE: non-existent variables are handled in the constructor
318 }
319 
320 const MooseVariableScalar *
321 ScalarCoupleable::getScalarVar(const std::string & var_name_in, const unsigned int comp) const
322 {
323  const auto var_name = _sc_parameters.checkForRename(var_name_in);
324 
325  const auto it = _coupled_scalar_vars.find(var_name);
326  if (it != _coupled_scalar_vars.end())
327  {
328  const auto & entry = it->second;
329  if (comp < entry.size())
330  return entry[comp];
331  else
332  mooseError(_sc_name, ": Trying to get a non-existent component of variable '", var_name, "'");
333  }
334  else
335  mooseError(_sc_name, ": Trying to get a non-existent variable '", var_name, "'");
336 }
337 
338 void
340  const std::string & fn_name) const
341 {
344  ": Calling '",
345  fn_name,
346  "' on variable \"",
347  name,
348  "\" when using a \"Steady\" executioner is not allowed. This value is available "
349  "only in transient simulations.");
350 }
351 
352 unsigned int
353 ScalarCoupleable::coupledScalarComponents(const std::string & var_name_in) const
354 {
355  const auto var_name = _sc_parameters.checkForRename(var_name_in);
356 
357  const auto it = _coupled_scalar_vars.find(var_name);
358  if (it != _coupled_scalar_vars.end())
359  return it->second.size();
360 
361  mooseError(_sc_name, ": Trying to get a non-existent variable '", var_name, "'");
362 }
std::string name(const ElemQuality q)
virtual MooseVariableScalar & getScalarVariable(const THREAD_ID tid, const std::string &var_name)=0
Returns the scalar variable reference from whichever system contains it.
const VariableValue & uDotOld() const
const VariableValue & uDotDot() const
bool hasCoupledValue(const std::string &coupling_name) const
Return whether or not the coupled variable exists.
Order
const ADVariableValue & adUDot() const
Return the first derivative of the solution with derivative information.
std::unordered_map< std::string, std::vector< MooseVariableFieldBase * > > _sc_coupled_vars
Field variables coupled into this object (for error checking)
std::set< TagID > _sc_coupleable_matrix_tags
The scalar coupleable matrix tags.
typename Moose::GenericType< VariableValue, is_ad > GenericVariableValue
Definition: MooseTypes.h:573
const THREAD_ID _sc_tid
Thread ID of the thread using this object.
const VariableValue & coupledScalarDotDotDu(const std::string &var_name, unsigned int comp=0) const
Second time derivative of a scalar coupled variable with respect to the coefficients.
unsigned int TagID
Definition: MooseTypes.h:199
std::set< TagID > _sc_coupleable_vector_tags
The scalar coupleable vector tags.
const VariableValue & coupledScalarValueOld(const std::string &var_name, unsigned int comp=0) const
Returns the old (previous time step) value of a scalar coupled variable.
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:284
unsigned int number() const
Get variable number coming from libMesh.
T * get(const std::unique_ptr< T > &u)
The MooseUtils::get() specializations are used to support making forwards-compatible code changes fro...
Definition: MooseUtils.h:1147
const VariableValue & coupledScalarDot(const std::string &var_name, unsigned int comp=0) const
Returns the time derivative of a scalar coupled variable.
const bool _sc_is_implicit
True if implicit value is required.
T getCheckedPointerParam(const std::string &name, const std::string &error_string="") const
Verifies that the requested parameter exists and is not NULL and returns it to the caller...
const VariableValue & coupledScalarDotOld(const std::string &var_name, unsigned int comp=0) const
Returns the old time derivative of a scalar coupled variable.
std::set< std::string >::const_iterator coupledVarsBegin() const
Methods returning iterators to the coupled variables names stored in this InputParameters object...
const std::string & _sc_name
The name of the object this interface is part of.
const VariableValue & duDotDotDu() const
FEProblemBase & _sc_fe_problem
void validateExecutionerType(const std::string &name, const std::string &fn_name) const
Checks to make sure that the current Executioner has set "_is_transient" when old/older values are co...
This class provides an interface for common operations on field variables of both FE and FV types wit...
const VariableValue & coupledScalarDotDu(const std::string &var_name, unsigned int comp=0) const
Time derivative of a scalar coupled variable with respect to the coefficients.
const VariableValue & uDotDotOld() const
bool isCoupledScalar(const std::string &var_name, unsigned int i=0) const
Returns true if a variables has been coupled_as name.
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
const ADVariableValue & adCoupledScalarDot(const std::string &var_name, unsigned int comp=0) const
Returns the time derivative of a scalar coupled variable, including its dependence on the nonlinear d...
const VariableValue & coupledVectorTagScalarValue(const std::string &var_name, TagID tag, unsigned int comp=0) const
Returns value of a scalar coupled variable.
const VariableValue & uDot() const
const VariableValue & vectorTagSln(TagID tag) const
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
std::set< std::string >::const_iterator coupledVarsEnd() const
Every object that can be built by the factory should be derived from this class.
Definition: MooseObject.h:33
const VariableValue & coupledScalarValueOlder(const std::string &var_name, unsigned int comp=0) const
Returns the older (two time steps previous) value of a scalar coupled variable.
const VariableValue & coupledScalarDotDot(const std::string &var_name, unsigned int comp=0) const
Returns the second time derivative of a scalar coupled variable.
void checkVar(const std::string &var_name) const
Check that the right kind of variable is being coupled in.
const VariableValue & coupledScalarValue(const std::string &var_name, unsigned int comp=0) const
Returns value of a scalar coupled variable.
Real defaultCoupledValue(const std::string &coupling_name, unsigned int i=0) const
Get the default value for an optionally coupled variable.
virtual bool hasScalarVariable(const std::string &var_name) const =0
Returns a Boolean indicating whether any system contains a variable with the name provided...
const MooseVariableScalar * getScalarVar(const std::string &var_name, unsigned int comp) const
Extract pointer to a scalar coupled variable.
virtual bool vectorTagExists(const TagID tag_id) const
Check to see if a particular Tag exists.
Definition: SubProblem.h:163
std::unordered_map< std::string, std::vector< MooseVariableScalar * > > _coupled_scalar_vars
Coupled vars whose values we provide.
unsigned int coupledScalar(const std::string &var_name, unsigned int comp=0) const
Returns the index for a scalar coupled variable by name.
virtual const MooseVariableFieldBase & getVariable(const THREAD_ID tid, const std::string &var_name, Moose::VarKindType expected_var_type=Moose::VarKindType::VAR_ANY, Moose::VarFieldType expected_var_field_type=Moose::VarFieldType::VAR_FIELD_ANY) const =0
Returns the variable reference for requested variable which must be of the expected_var_type (Nonline...
virtual bool hasVariable(const std::string &var_name) const =0
Whether or not this problem has the variable.
const VariableValue & matrixTagSln(TagID tag) const
const InputParameters & _sc_parameters
OutputTools< Real >::VariableValue VariableValue
Definition: MooseTypes.h:302
Order order() const
Get the order of this variable Note: Order enum can be implicitly converted to unsigned int...
const ADVariableValue * getADDefaultValue(const std::string &var_name) const
Helper method to return (and insert if necessary) the AD default value for an uncoupled variable...
const ADVariableValue & adCoupledScalarValue(const std::string &var_name, unsigned int comp=0) const
Returns AD value of a scalar coupled variable.
Generic class for solving transient nonlinear problems.
Definition: SubProblem.h:75
const VariableValue * getDefaultValue(const std::string &var_name) const
Helper method to return (and insert if necessary) the default value for an uncoupled variable...
ScalarCoupleable(const MooseObject *moose_object)
Constructing the object.
const VariableValue & duDotDu() const
std::string checkForRename(const std::string &name) const
Checks whether the provided name is a renamed parameter name.
std::vector< MooseVariableScalar * > _coupled_moose_scalar_vars
Vector of coupled variables.
unsigned int coupledScalarComponents(const std::string &var_name) const
Return the number of components to the coupled scalar variable.
Class for scalar variables (they are different).
std::unordered_map< std::string, std::unique_ptr< VariableValue > > _default_value
Will hold the default value for optional coupled scalar variables.
std::unordered_map< std::string, std::unique_ptr< ADVariableValue > > _dual_default_value
Will hold the default AD value for optional coupled scalar variables.
virtual bool isTransient() const override
const VariableValue & coupledMatrixTagScalarValue(const std::string &var_name, TagID tag, unsigned int comp=0) const
Returns value of a scalar coupled variable.
std::vector< std::string > getVecMooseType(const std::string &name) const
const VariableValue & coupledScalarDotDotOld(const std::string &var_name, unsigned int comp=0) const
Returns the old second time derivative of a scalar coupled variable.
Order coupledScalarOrder(const std::string &var_name, unsigned int comp=0) const
Returns the order for a scalar coupled variable by name.
Order getMaxScalarOrder() const
unsigned int THREAD_ID
Definition: MooseTypes.h:198