https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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
84bool
85ScalarCoupleable::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.hasCoupledVar(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
107unsigned int
108ScalarCoupleable::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
114Order
115ScalarCoupleable::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
124const VariableValue *
125ScalarCoupleable::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
138const VariableValue &
139ScalarCoupleable::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
149const ADVariableValue &
150ScalarCoupleable::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
165template <>
167ScalarCoupleable::coupledGenericScalarValue<false>(const std::string & var_name,
168 const unsigned int comp) const
169{
170 return coupledScalarValue(var_name, comp);
171}
172
173template <>
175ScalarCoupleable::coupledGenericScalarValue<true>(const std::string & var_name,
176 const unsigned int comp) const
177{
178 return adCoupledScalarValue(var_name, comp);
179}
180
181const ADVariableValue *
182ScalarCoupleable::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
195const VariableValue &
197 const std::string & tag_param_name,
198 const unsigned int comp) const
199{
200 checkVar(var_name);
201 if (!isCoupledScalar(var_name, comp))
202 return *getDefaultValue(var_name);
203
204 if (!_sc_parameters.isParamValid(tag_param_name))
205 mooseError("Tag name parameter '", tag_param_name, "' is invalid");
206
207 const auto & tag_name = _sc_parameters.get<TagName>(tag_param_name);
208
209 if (!_sc_fe_problem.vectorTagExists(tag_name))
210 mooseError("Attempting to couple to vector tag scalar with name ",
211 tag_name,
212 "in ",
213 _sc_name,
214 ", but a vector tag with that name does not exist");
215
216 const auto tag = _sc_fe_problem.getVectorTagID(tag_name);
217
218 _sc_coupleable_vector_tags.insert(tag);
219
220 return getScalarVar(var_name, comp)->vectorTagSln(tag);
221}
222
223const VariableValue &
225 const std::string & tag_param_name,
226 const unsigned int comp) const
227{
228 checkVar(var_name);
229 if (!isCoupledScalar(var_name, comp))
230 return *getDefaultValue(var_name);
231
232 if (!_sc_parameters.isParamValid(tag_param_name))
233 mooseError("Tag name parameter '", tag_param_name, "' is invalid");
234
235 const auto & tag_name = _sc_parameters.get<TagName>(tag_param_name);
236
237 if (!_sc_fe_problem.matrixTagExists(tag_name))
238 mooseError("Attempting to couple to matrx tag scalar with name ",
239 tag_name,
240 "in ",
241 _sc_name,
242 ", but a matrx tag with that name does not exist");
243
244 const auto tag = _sc_fe_problem.getMatrixTagID(tag_name);
245
246 _sc_coupleable_matrix_tags.insert(tag);
247
248 return getScalarVar(var_name, comp)->matrixTagSln(tag);
249}
250
251const VariableValue &
252ScalarCoupleable::coupledScalarValueOld(const std::string & var_name, const unsigned int comp) const
253{
254 checkVar(var_name);
255 if (!isCoupledScalar(var_name, comp))
256 return *getDefaultValue(var_name);
257
258 validateExecutionerType(var_name, "coupledScalarValueOld");
259 auto var = getScalarVar(var_name, comp);
260 return _sc_is_implicit ? var->slnOld() : var->slnOlder();
261}
262
263const VariableValue &
264ScalarCoupleable::coupledScalarValueOlder(const std::string & var_name,
265 const unsigned int comp) const
266{
267 checkVar(var_name);
268 if (!isCoupledScalar(var_name, comp))
269 return *getDefaultValue(var_name);
270
271 validateExecutionerType(var_name, "coupledScalarValueOlder");
272 auto var = getScalarVar(var_name, comp);
273 if (_sc_is_implicit)
274 return var->slnOlder();
275 else
276 mooseError("Older values not available for explicit schemes");
277}
278
279const VariableValue &
280ScalarCoupleable::coupledScalarDot(const std::string & var_name, const unsigned int comp) const
281{
282 checkVar(var_name);
283 validateExecutionerType(var_name, "coupledScalarDot");
284 return getScalarVar(var_name, comp)->uDot();
285}
286
287const ADVariableValue &
288ScalarCoupleable::adCoupledScalarDot(const std::string & var_name, const unsigned int comp) const
289{
290 checkVar(var_name);
291 validateExecutionerType(var_name, "adCoupledScalarDot");
292 return getScalarVar(var_name, comp)->adUDot();
293}
294
295const VariableValue &
296ScalarCoupleable::coupledScalarDotDot(const std::string & var_name, const unsigned int comp) const
297{
298 checkVar(var_name);
299 validateExecutionerType(var_name, "coupledScalarDotDot");
300 return getScalarVar(var_name, comp)->uDotDot();
301}
302
303const VariableValue &
304ScalarCoupleable::coupledScalarDotOld(const std::string & var_name, const unsigned int comp) const
305{
306 checkVar(var_name);
307 validateExecutionerType(var_name, "coupledScalarDotOld");
308 return getScalarVar(var_name, comp)->uDotOld();
309}
310
311const VariableValue &
312ScalarCoupleable::coupledScalarDotDotOld(const std::string & var_name,
313 const unsigned int comp) const
314{
315 checkVar(var_name);
316 validateExecutionerType(var_name, "coupledScalarDotDotOld");
317 return getScalarVar(var_name, comp)->uDotDotOld();
318}
319const VariableValue &
320ScalarCoupleable::coupledScalarDotDu(const std::string & var_name, const unsigned int comp) const
321{
322 checkVar(var_name);
323 validateExecutionerType(var_name, "coupledScalarDotDu");
324 return getScalarVar(var_name, comp)->duDotDu();
325}
326
327const VariableValue &
328ScalarCoupleable::coupledScalarDotDotDu(const std::string & var_name, const unsigned int comp) const
329{
330 checkVar(var_name);
331 validateExecutionerType(var_name, "coupledScalarDotDotDu");
332 return getScalarVar(var_name, comp)->duDotDotDu();
333}
334
335void
336ScalarCoupleable::checkVar(const std::string & var_name_in) const
337{
338 const auto & var_name = _sc_parameters.checkForRename(var_name_in);
339
340 auto it = _sc_coupled_vars.find(var_name);
341 if (it != _sc_coupled_vars.end())
342 {
343 std::string cvars;
344 for (auto jt : it->second)
345 cvars += " " + jt->name();
347 ": Trying to couple a field variable where scalar variable is expected, '",
348 var_name,
349 " =",
350 cvars,
351 "'");
352 }
353 // NOTE: non-existent variables are handled in the constructor
354}
355
357ScalarCoupleable::getScalarVar(const std::string & var_name_in, const unsigned int comp) const
358{
359 const auto & var_name = _sc_parameters.checkForRename(var_name_in);
360
361 const auto it = _coupled_scalar_vars.find(var_name);
362 if (it != _coupled_scalar_vars.end())
363 {
364 const auto & entry = it->second;
365 if (comp < entry.size())
366 return entry[comp];
367 else
368 mooseError(_sc_name, ": Trying to get a non-existent component of variable '", var_name, "'");
369 }
370 else
371 mooseError(_sc_name, ": Trying to get a non-existent variable '", var_name, "'");
372}
373
374void
376 const std::string & fn_name) const
377{
380 ": Calling '",
381 fn_name,
382 "' on variable \"",
383 name,
384 "\" when using a \"Steady\" executioner is not allowed. This value is available "
385 "only in transient simulations.");
386}
387
388unsigned int
389ScalarCoupleable::coupledScalarComponents(const std::string & var_name_in) const
390{
391 const auto & var_name = _sc_parameters.checkForRename(var_name_in);
392
393 const auto it = _coupled_scalar_vars.find(var_name);
394 if (it != _coupled_scalar_vars.end())
395 return it->second.size();
396
397 mooseError(_sc_name, ": Trying to get a non-existent variable '", var_name, "'");
398}
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
Moose::GenericType< VariableValue, is_ad > GenericVariableValue
Definition MooseTypes.h:712
OutputTools< Real >::VariableValue VariableValue
Definition MooseTypes.h:348
unsigned int THREAD_ID
Definition MooseTypes.h:237
char ** vars
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
libMesh::Order getMaxScalarOrder() const
virtual bool isTransient() const override
std::vector< std::string > getVecMooseType(const std::string &name) const
bool hasCoupledVar(const std::string &coupling_name) const
Return whether or not the coupled variable exists.
std::vector< std::pair< R1, R2 > > get(const std::string &param1, const std::string &param2) const
Combine two vector parameters into a single vector of pairs.
std::set< std::string >::const_iterator coupledVarsEnd() const
std::set< std::string >::const_iterator coupledVarsBegin() const
Methods returning iterators to the coupled variables names stored in this InputParameters object.
Real defaultCoupledValue(const std::string &coupling_name, unsigned int i=0) const
Get the default value for an optionally coupled variable.
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 std::string & checkForRename(const std::string &name) const
Checks whether the provided name is a renamed parameter name.
bool isParamValid(const std::string &name) const
This method returns parameters that have been initialized in one fashion or another,...
Every object that can be built by the factory should be derived from this class.
Definition MooseObject.h:31
libMesh::Order order() const
Get the order of this variable Note: Order enum can be implicitly converted to unsigned int.
unsigned int number() const
Get variable number coming from libMesh.
This class provides an interface for common operations on field variables of both FE and FV types wit...
Class for scalar variables (they are different).
const VariableValue & uDotOld() const
const VariableValue & uDot() const
const VariableValue & duDotDotDu() const
const VariableValue & uDotDotOld() const
const ADVariableValue & adUDot() const
Return the first derivative of the solution with derivative information.
const VariableValue & duDotDu() const
const VariableValue & uDotDot() const
const VariableValue & matrixTagSln(TagID tag) const
const VariableValue & vectorTagSln(TagID tag) const
Interface for objects that needs scalar coupling capabilities.
const VariableValue & coupledScalarValue(const std::string &var_name, unsigned int comp=0) const
Returns value of a scalar coupled variable.
const VariableValue & coupledMatrixTagScalarValue(const std::string &var_name, const std::string &tag_param_name, unsigned int comp=0) const
Returns value of a scalar coupled variable.
const std::string & _sc_name
The name of the object this interface is part of.
std::unordered_map< std::string, std::unique_ptr< VariableValue > > _default_value
Will hold the default value for optional coupled scalar variables.
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.
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.
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...
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_vector_tags
The scalar coupleable vector tags.
const InputParameters & _sc_parameters
std::set< TagID > _sc_coupleable_matrix_tags
The scalar coupleable matrix 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.
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.
const VariableValue & coupledVectorTagScalarValue(const std::string &var_name, const std::string &tag_param_name, unsigned int comp=0) const
Returns value of a scalar coupled variable.
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 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 & coupledScalarDotOld(const std::string &var_name, unsigned int comp=0) const
Returns the old time derivative of a scalar coupled variable.
const VariableValue & coupledScalarDotDotOld(const std::string &var_name, unsigned int comp=0) const
Returns the old second time derivative of a scalar coupled variable.
const VariableValue * getDefaultValue(const std::string &var_name) const
Helper method to return (and insert if necessary) the default value for an uncoupled variable.
std::unordered_map< std::string, std::unique_ptr< ADVariableValue > > _dual_default_value
Will hold the default AD value for optional coupled scalar variables.
bool isCoupledScalar(const std::string &var_name, unsigned int i=0) const
Returns true if a variables has been coupled_as name.
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.
FEProblemBase & _sc_fe_problem
libMesh::Order coupledScalarOrder(const std::string &var_name, unsigned int comp=0) const
Returns the order for a scalar coupled variable by name.
const MooseVariableScalar * getScalarVar(const std::string &var_name, unsigned int comp) const
Extract pointer to a scalar coupled variable.
const ADVariableValue & adCoupledScalarValue(const std::string &var_name, unsigned int comp=0) const
Returns AD value of a scalar coupled variable.
const VariableValue & coupledScalarDot(const std::string &var_name, unsigned int comp=0) const
Returns the time derivative of a scalar coupled variable.
ScalarCoupleable(const MooseObject *moose_object)
Constructing the object.
const THREAD_ID _sc_tid
Thread ID of the thread using this object.
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 bool _sc_is_implicit
True if implicit value is required.
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.
Generic class for solving transient nonlinear problems.
Definition SubProblem.h:79
virtual TagID getVectorTagID(const TagName &tag_name) const
Get a TagID from a TagName.
Definition SubProblem.C:192
virtual TagID getMatrixTagID(const TagName &tag_name) const
Get a TagID from a TagName.
Definition SubProblem.C:331
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 matrixTagExists(const TagName &tag_name) const
Check to see if a particular Tag exists.
Definition SubProblem.C:317
virtual bool hasScalarVariable(const std::string &var_name) const =0
Returns a Boolean indicating whether any system contains a variable with the name provided.
virtual bool hasVariable(const std::string &var_name) const =0
Whether or not this problem has the variable.
virtual bool vectorTagExists(const TagID tag_id) const
Check to see if a particular Tag exists.
Definition SubProblem.h:201
virtual MooseVariableScalar & getScalarVariable(const THREAD_ID tid, const std::string &var_name)=0
Returns the scalar variable reference from whichever system contains it.
@ VAR_FIELD_ANY
Definition MooseTypes.h:781
@ VAR_ANY
Definition MooseTypes.h:772