https://mooseframework.inl.gov
ScalarCoupleable.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 "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.getObjectName()),
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 #ifdef MOOSE_KOKKOS_ENABLED
72  : _sc_fe_problem(object._sc_fe_problem),
73  _sc_tid(object._sc_tid),
74  _real_zero(object._real_zero),
75  _scalar_zero(object._scalar_zero),
76  _point_zero(object._point_zero),
77  _sc_parameters(object._sc_parameters),
78  _sc_name(object._sc_name),
79  _sc_is_implicit(object._sc_is_implicit)
80 {
81 }
82 #endif
83 
84 bool
85 ScalarCoupleable::isCoupledScalar(const std::string & var_name_in, unsigned int i) const
86 {
87  const auto var_name = _sc_parameters.checkForRename(var_name_in);
88 
89  auto it = _coupled_scalar_vars.find(var_name);
90  if (it != _coupled_scalar_vars.end())
91  return (i < it->second.size());
92  else
93  {
94  // Make sure the user originally requested this value in the InputParameter syntax
95  if (!_sc_parameters.hasCoupledValue(var_name))
97  ": The coupled scalar variable \"",
98  var_name,
99  "\" was never added to this object's "
100  "InputParameters, please double-check "
101  "your spelling");
102 
103  return false;
104  }
105 }
106 
107 unsigned int
108 ScalarCoupleable::coupledScalar(const std::string & var_name, const unsigned int comp) const
109 {
110  checkVar(var_name);
111  return getScalarVar(var_name, comp)->number();
112 }
113 
114 Order
115 ScalarCoupleable::coupledScalarOrder(const std::string & var_name, const unsigned int comp) const
116 {
117  checkVar(var_name);
118  if (!isCoupledScalar(var_name, comp))
120 
121  return getScalarVar(var_name, comp)->order();
122 }
123 
124 const VariableValue *
125 ScalarCoupleable::getDefaultValue(const std::string & var_name) const
126 {
127  auto default_value_it = _default_value.find(var_name);
128  if (default_value_it == _default_value.end())
129  {
130  auto value = std::make_unique<VariableValue>(_sc_fe_problem.getMaxScalarOrder(),
132  default_value_it = _default_value.insert(std::make_pair(var_name, std::move(value))).first;
133  }
134 
135  return default_value_it->second.get();
136 }
137 
138 const VariableValue &
139 ScalarCoupleable::coupledScalarValue(const std::string & var_name, const unsigned int comp) const
140 {
141  checkVar(var_name);
142  if (!isCoupledScalar(var_name, comp))
143  return *getDefaultValue(var_name);
144 
145  auto var = getScalarVar(var_name, comp);
146  return _sc_is_implicit ? var->sln() : var->slnOld();
147 }
148 
149 const ADVariableValue &
150 ScalarCoupleable::adCoupledScalarValue(const std::string & var_name, const unsigned int comp) const
151 {
152  checkVar(var_name);
153  if (!isCoupledScalar(var_name, comp))
154  return *getADDefaultValue(var_name);
155 
156  auto var = getScalarVar(var_name, comp);
157 
158  if (_sc_is_implicit)
159  return var->adSln();
160  else
161  mooseError("adCoupledValue for non-implicit calculations is not currently supported. Use "
162  "coupledValue instead for non-implicit");
163 }
164 
165 template <>
167 ScalarCoupleable::coupledGenericScalarValue<false>(const std::string & var_name,
168  const unsigned int comp) const
169 {
170  return coupledScalarValue(var_name, comp);
171 }
172 
173 template <>
175 ScalarCoupleable::coupledGenericScalarValue<true>(const std::string & var_name,
176  const unsigned int comp) const
177 {
178  return adCoupledScalarValue(var_name, comp);
179 }
180 
181 const ADVariableValue *
182 ScalarCoupleable::getADDefaultValue(const std::string & var_name) const
183 {
184  auto default_value_it = _dual_default_value.find(var_name);
185  if (default_value_it == _dual_default_value.end())
186  {
187  auto value = std::make_unique<ADVariableValue>(_sc_fe_problem.getMaxScalarOrder(),
189  default_value_it = _dual_default_value.insert(std::make_pair(var_name, std::move(value))).first;
190  }
191 
192  return default_value_it->second.get();
193 }
194 
195 const VariableValue &
197  TagID tag,
198  const unsigned int comp) const
199 {
200  checkVar(var_name);
201  if (!isCoupledScalar(var_name, comp))
202  return *getDefaultValue(var_name);
203 
205  mooseError("Attempting to couple to vector tag scalar with ID ",
206  tag,
207  "in ",
208  _sc_name,
209  ", but a vector tag with that ID does not exist");
210 
211  _sc_coupleable_vector_tags.insert(tag);
212 
213  return getScalarVar(var_name, comp)->vectorTagSln(tag);
214 }
215 
216 const VariableValue &
218  TagID tag,
219  const unsigned int comp) const
220 {
221  checkVar(var_name);
222  if (!isCoupledScalar(var_name, comp))
223  return *getDefaultValue(var_name);
224 
225  _sc_coupleable_matrix_tags.insert(tag);
226 
227  return getScalarVar(var_name, comp)->matrixTagSln(tag);
228 }
229 
230 const VariableValue &
231 ScalarCoupleable::coupledScalarValueOld(const std::string & var_name, const unsigned int comp) const
232 {
233  checkVar(var_name);
234  if (!isCoupledScalar(var_name, comp))
235  return *getDefaultValue(var_name);
236 
237  validateExecutionerType(var_name, "coupledScalarValueOld");
238  auto var = getScalarVar(var_name, comp);
239  return _sc_is_implicit ? var->slnOld() : var->slnOlder();
240 }
241 
242 const VariableValue &
243 ScalarCoupleable::coupledScalarValueOlder(const std::string & var_name,
244  const unsigned int comp) const
245 {
246  checkVar(var_name);
247  if (!isCoupledScalar(var_name, comp))
248  return *getDefaultValue(var_name);
249 
250  validateExecutionerType(var_name, "coupledScalarValueOlder");
251  auto var = getScalarVar(var_name, comp);
252  if (_sc_is_implicit)
253  return var->slnOlder();
254  else
255  mooseError("Older values not available for explicit schemes");
256 }
257 
258 const VariableValue &
259 ScalarCoupleable::coupledScalarDot(const std::string & var_name, const unsigned int comp) const
260 {
261  checkVar(var_name);
262  validateExecutionerType(var_name, "coupledScalarDot");
263  return getScalarVar(var_name, comp)->uDot();
264 }
265 
266 const ADVariableValue &
267 ScalarCoupleable::adCoupledScalarDot(const std::string & var_name, const unsigned int comp) const
268 {
269  checkVar(var_name);
270  validateExecutionerType(var_name, "adCoupledScalarDot");
271  return getScalarVar(var_name, comp)->adUDot();
272 }
273 
274 const VariableValue &
275 ScalarCoupleable::coupledScalarDotDot(const std::string & var_name, const unsigned int comp) const
276 {
277  checkVar(var_name);
278  validateExecutionerType(var_name, "coupledScalarDotDot");
279  return getScalarVar(var_name, comp)->uDotDot();
280 }
281 
282 const VariableValue &
283 ScalarCoupleable::coupledScalarDotOld(const std::string & var_name, const unsigned int comp) const
284 {
285  checkVar(var_name);
286  validateExecutionerType(var_name, "coupledScalarDotOld");
287  return getScalarVar(var_name, comp)->uDotOld();
288 }
289 
290 const VariableValue &
291 ScalarCoupleable::coupledScalarDotDotOld(const std::string & var_name,
292  const unsigned int comp) const
293 {
294  checkVar(var_name);
295  validateExecutionerType(var_name, "coupledScalarDotDotOld");
296  return getScalarVar(var_name, comp)->uDotDotOld();
297 }
298 const VariableValue &
299 ScalarCoupleable::coupledScalarDotDu(const std::string & var_name, const unsigned int comp) const
300 {
301  checkVar(var_name);
302  validateExecutionerType(var_name, "coupledScalarDotDu");
303  return getScalarVar(var_name, comp)->duDotDu();
304 }
305 
306 const VariableValue &
307 ScalarCoupleable::coupledScalarDotDotDu(const std::string & var_name, const unsigned int comp) const
308 {
309  checkVar(var_name);
310  validateExecutionerType(var_name, "coupledScalarDotDotDu");
311  return getScalarVar(var_name, comp)->duDotDotDu();
312 }
313 
314 void
315 ScalarCoupleable::checkVar(const std::string & var_name_in) const
316 {
317  const auto var_name = _sc_parameters.checkForRename(var_name_in);
318 
319  auto it = _sc_coupled_vars.find(var_name);
320  if (it != _sc_coupled_vars.end())
321  {
322  std::string cvars;
323  for (auto jt : it->second)
324  cvars += " " + jt->name();
326  ": Trying to couple a field variable where scalar variable is expected, '",
327  var_name,
328  " =",
329  cvars,
330  "'");
331  }
332  // NOTE: non-existent variables are handled in the constructor
333 }
334 
335 const MooseVariableScalar *
336 ScalarCoupleable::getScalarVar(const std::string & var_name_in, const unsigned int comp) const
337 {
338  const auto var_name = _sc_parameters.checkForRename(var_name_in);
339 
340  const auto it = _coupled_scalar_vars.find(var_name);
341  if (it != _coupled_scalar_vars.end())
342  {
343  const auto & entry = it->second;
344  if (comp < entry.size())
345  return entry[comp];
346  else
347  mooseError(_sc_name, ": Trying to get a non-existent component of variable '", var_name, "'");
348  }
349  else
350  mooseError(_sc_name, ": Trying to get a non-existent variable '", var_name, "'");
351 }
352 
353 void
355  const std::string & fn_name) const
356 {
359  ": Calling '",
360  fn_name,
361  "' on variable \"",
362  name,
363  "\" when using a \"Steady\" executioner is not allowed. This value is available "
364  "only in transient simulations.");
365 }
366 
367 unsigned int
368 ScalarCoupleable::coupledScalarComponents(const std::string & var_name_in) const
369 {
370  const auto var_name = _sc_parameters.checkForRename(var_name_in);
371 
372  const auto it = _coupled_scalar_vars.find(var_name);
373  if (it != _coupled_scalar_vars.end())
374  return it->second.size();
375 
376  mooseError(_sc_name, ": Trying to get a non-existent variable '", var_name, "'");
377 }
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.
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:210
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:323
unsigned int number() const
Get variable number coming from libMesh.
char ** vars
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:1135
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
Moose::GenericType< VariableValue, is_ad > GenericVariableValue
Definition: MooseTypes.h:663
Every object that can be built by the factory should be derived from this class.
Definition: MooseObject.h:28
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:201
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:315
libMesh::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:78
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).
Interface for objects that needs scalar coupling capabilities.
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.
libMesh::Order coupledScalarOrder(const std::string &var_name, unsigned int comp=0) const
Returns the order for a scalar coupled variable by name.
libMesh::Order getMaxScalarOrder() const
unsigned int THREAD_ID
Definition: MooseTypes.h:209