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 "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 :
19 454856 : ScalarCoupleable::ScalarCoupleable(const MooseObject * moose_object)
20 454856 : : _sc_fe_problem(
21 1819424 : *moose_object->parameters().getCheckedPointerParam<FEProblemBase *>("_fe_problem_base")),
22 909712 : _sc_tid(moose_object->parameters().isParamValid("_tid")
23 454856 : ? moose_object->parameters().get<THREAD_ID>("_tid")
24 : : 0),
25 454856 : _real_zero(_sc_fe_problem._real_zero[_sc_tid]),
26 454856 : _scalar_zero(_sc_fe_problem._scalar_zero[_sc_tid]),
27 454856 : _point_zero(_sc_fe_problem._point_zero[_sc_tid]),
28 454856 : _sc_parameters(moose_object->parameters()),
29 454856 : _sc_name(_sc_parameters.getObjectName()),
30 454856 : _sc_is_implicit(_sc_parameters.have_parameter<bool>("implicit")
31 454856 : ? _sc_parameters.get<bool>("implicit")
32 454856 : : true)
33 : {
34 1819424 : SubProblem & problem = *_sc_parameters.getCheckedPointerParam<SubProblem *>("_subproblem");
35 :
36 : // Coupling
37 454856 : for (std::set<std::string>::const_iterator iter = _sc_parameters.coupledVarsBegin();
38 734084 : iter != _sc_parameters.coupledVarsEnd();
39 279228 : ++iter)
40 : {
41 279228 : std::string name = *iter;
42 279228 : if (_sc_parameters.getVecMooseType(*iter) != std::vector<std::string>())
43 : {
44 73086 : std::vector<std::string> vars = _sc_parameters.getVecMooseType(*iter);
45 161295 : for (const auto & coupled_var_name : vars)
46 : {
47 88209 : if (problem.hasScalarVariable(coupled_var_name))
48 : {
49 1877 : MooseVariableScalar * scalar_var = &problem.getScalarVariable(_sc_tid, coupled_var_name);
50 1877 : _coupled_scalar_vars[name].push_back(scalar_var);
51 1877 : _coupled_moose_scalar_vars.push_back(scalar_var);
52 : }
53 86332 : else if (problem.hasVariable(coupled_var_name))
54 : {
55 : MooseVariableFEBase * moose_var =
56 86332 : &problem.getVariable(_sc_tid,
57 : coupled_var_name,
58 : Moose::VarKindType::VAR_ANY,
59 86332 : Moose::VarFieldType::VAR_FIELD_ANY);
60 86332 : _sc_coupled_vars[name].push_back(moose_var);
61 : }
62 : else
63 0 : mooseError(_sc_name, ": Coupled variable '", coupled_var_name, "' was not found");
64 : }
65 73086 : }
66 279228 : }
67 454856 : }
68 :
69 : #ifdef MOOSE_KOKKOS_ENABLED
70 534450 : ScalarCoupleable::ScalarCoupleable(const ScalarCoupleable & object,
71 534450 : const Moose::Kokkos::FunctorCopy &)
72 534450 : : _sc_fe_problem(object._sc_fe_problem),
73 534450 : _sc_tid(object._sc_tid),
74 534450 : _real_zero(object._real_zero),
75 534450 : _scalar_zero(object._scalar_zero),
76 534450 : _point_zero(object._point_zero),
77 534450 : _sc_parameters(object._sc_parameters),
78 534450 : _sc_name(object._sc_name),
79 534450 : _sc_is_implicit(object._sc_is_implicit)
80 : {
81 534450 : }
82 : #endif
83 :
84 : bool
85 1985 : ScalarCoupleable::isCoupledScalar(const std::string & var_name_in, unsigned int i) const
86 : {
87 1985 : const auto var_name = _sc_parameters.checkForRename(var_name_in);
88 :
89 1985 : auto it = _coupled_scalar_vars.find(var_name);
90 1985 : if (it != _coupled_scalar_vars.end())
91 1583 : return (i < it->second.size());
92 : else
93 : {
94 : // Make sure the user originally requested this value in the InputParameter syntax
95 402 : if (!_sc_parameters.hasCoupledValue(var_name))
96 0 : mooseError(_sc_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 402 : return false;
104 : }
105 1985 : }
106 :
107 : unsigned int
108 707 : ScalarCoupleable::coupledScalar(const std::string & var_name, const unsigned int comp) const
109 : {
110 707 : checkVar(var_name);
111 704 : return getScalarVar(var_name, comp)->number();
112 : }
113 :
114 : Order
115 117 : ScalarCoupleable::coupledScalarOrder(const std::string & var_name, const unsigned int comp) const
116 : {
117 117 : checkVar(var_name);
118 117 : if (!isCoupledScalar(var_name, comp))
119 26 : return _sc_fe_problem.getMaxScalarOrder();
120 :
121 91 : return getScalarVar(var_name, comp)->order();
122 : }
123 :
124 : const VariableValue *
125 26 : ScalarCoupleable::getDefaultValue(const std::string & var_name) const
126 : {
127 26 : auto default_value_it = _default_value.find(var_name);
128 26 : if (default_value_it == _default_value.end())
129 : {
130 0 : auto value = std::make_unique<VariableValue>(_sc_fe_problem.getMaxScalarOrder(),
131 26 : _sc_parameters.defaultCoupledValue(var_name));
132 26 : default_value_it = _default_value.insert(std::make_pair(var_name, std::move(value))).first;
133 26 : }
134 :
135 52 : return default_value_it->second.get();
136 : }
137 :
138 : const VariableValue &
139 996 : ScalarCoupleable::coupledScalarValue(const std::string & var_name, const unsigned int comp) const
140 : {
141 996 : checkVar(var_name);
142 996 : if (!isCoupledScalar(var_name, comp))
143 26 : return *getDefaultValue(var_name);
144 :
145 970 : auto var = getScalarVar(var_name, comp);
146 970 : return _sc_is_implicit ? var->sln() : var->slnOld();
147 : }
148 :
149 : const ADVariableValue &
150 268 : ScalarCoupleable::adCoupledScalarValue(const std::string & var_name, const unsigned int comp) const
151 : {
152 268 : checkVar(var_name);
153 268 : if (!isCoupledScalar(var_name, comp))
154 0 : return *getADDefaultValue(var_name);
155 :
156 268 : auto var = getScalarVar(var_name, comp);
157 :
158 268 : if (_sc_is_implicit)
159 268 : return var->adSln();
160 : else
161 0 : mooseError("adCoupledValue for non-implicit calculations is not currently supported. Use "
162 : "coupledValue instead for non-implicit");
163 : }
164 :
165 : template <>
166 : const GenericVariableValue<false> &
167 0 : ScalarCoupleable::coupledGenericScalarValue<false>(const std::string & var_name,
168 : const unsigned int comp) const
169 : {
170 0 : return coupledScalarValue(var_name, comp);
171 : }
172 :
173 : template <>
174 : const GenericVariableValue<true> &
175 0 : ScalarCoupleable::coupledGenericScalarValue<true>(const std::string & var_name,
176 : const unsigned int comp) const
177 : {
178 0 : return adCoupledScalarValue(var_name, comp);
179 : }
180 :
181 : const ADVariableValue *
182 0 : ScalarCoupleable::getADDefaultValue(const std::string & var_name) const
183 : {
184 0 : auto default_value_it = _dual_default_value.find(var_name);
185 0 : if (default_value_it == _dual_default_value.end())
186 : {
187 0 : auto value = std::make_unique<ADVariableValue>(_sc_fe_problem.getMaxScalarOrder(),
188 0 : _sc_parameters.defaultCoupledValue(var_name));
189 0 : default_value_it = _dual_default_value.insert(std::make_pair(var_name, std::move(value))).first;
190 0 : }
191 :
192 0 : return default_value_it->second.get();
193 : }
194 :
195 : const VariableValue &
196 28 : ScalarCoupleable::coupledVectorTagScalarValue(const std::string & var_name,
197 : TagID tag,
198 : const unsigned int comp) const
199 : {
200 28 : checkVar(var_name);
201 28 : if (!isCoupledScalar(var_name, comp))
202 0 : return *getDefaultValue(var_name);
203 :
204 28 : if (!_sc_fe_problem.vectorTagExists(tag))
205 0 : mooseError("Attempting to couple to vector tag scalar with ID ",
206 : tag,
207 : "in ",
208 0 : _sc_name,
209 : ", but a vector tag with that ID does not exist");
210 :
211 28 : _sc_coupleable_vector_tags.insert(tag);
212 :
213 28 : return getScalarVar(var_name, comp)->vectorTagSln(tag);
214 : }
215 :
216 : const VariableValue &
217 14 : ScalarCoupleable::coupledMatrixTagScalarValue(const std::string & var_name,
218 : TagID tag,
219 : const unsigned int comp) const
220 : {
221 14 : checkVar(var_name);
222 14 : if (!isCoupledScalar(var_name, comp))
223 0 : return *getDefaultValue(var_name);
224 :
225 14 : _sc_coupleable_matrix_tags.insert(tag);
226 :
227 14 : return getScalarVar(var_name, comp)->matrixTagSln(tag);
228 : }
229 :
230 : const VariableValue &
231 29 : ScalarCoupleable::coupledScalarValueOld(const std::string & var_name, const unsigned int comp) const
232 : {
233 29 : checkVar(var_name);
234 29 : if (!isCoupledScalar(var_name, comp))
235 0 : return *getDefaultValue(var_name);
236 :
237 29 : validateExecutionerType(var_name, "coupledScalarValueOld");
238 26 : auto var = getScalarVar(var_name, comp);
239 26 : return _sc_is_implicit ? var->slnOld() : var->slnOlder();
240 : }
241 :
242 : const VariableValue &
243 26 : ScalarCoupleable::coupledScalarValueOlder(const std::string & var_name,
244 : const unsigned int comp) const
245 : {
246 26 : checkVar(var_name);
247 26 : if (!isCoupledScalar(var_name, comp))
248 0 : return *getDefaultValue(var_name);
249 :
250 26 : validateExecutionerType(var_name, "coupledScalarValueOlder");
251 26 : auto var = getScalarVar(var_name, comp);
252 26 : if (_sc_is_implicit)
253 26 : return var->slnOlder();
254 : else
255 0 : mooseError("Older values not available for explicit schemes");
256 : }
257 :
258 : const VariableValue &
259 67 : ScalarCoupleable::coupledScalarDot(const std::string & var_name, const unsigned int comp) const
260 : {
261 67 : checkVar(var_name);
262 67 : validateExecutionerType(var_name, "coupledScalarDot");
263 64 : return getScalarVar(var_name, comp)->uDot();
264 : }
265 :
266 : const ADVariableValue &
267 12 : ScalarCoupleable::adCoupledScalarDot(const std::string & var_name, const unsigned int comp) const
268 : {
269 12 : checkVar(var_name);
270 12 : validateExecutionerType(var_name, "adCoupledScalarDot");
271 12 : return getScalarVar(var_name, comp)->adUDot();
272 : }
273 :
274 : const VariableValue &
275 0 : ScalarCoupleable::coupledScalarDotDot(const std::string & var_name, const unsigned int comp) const
276 : {
277 0 : checkVar(var_name);
278 0 : validateExecutionerType(var_name, "coupledScalarDotDot");
279 0 : return getScalarVar(var_name, comp)->uDotDot();
280 : }
281 :
282 : const VariableValue &
283 0 : ScalarCoupleable::coupledScalarDotOld(const std::string & var_name, const unsigned int comp) const
284 : {
285 0 : checkVar(var_name);
286 0 : validateExecutionerType(var_name, "coupledScalarDotOld");
287 0 : return getScalarVar(var_name, comp)->uDotOld();
288 : }
289 :
290 : const VariableValue &
291 0 : ScalarCoupleable::coupledScalarDotDotOld(const std::string & var_name,
292 : const unsigned int comp) const
293 : {
294 0 : checkVar(var_name);
295 0 : validateExecutionerType(var_name, "coupledScalarDotDotOld");
296 0 : return getScalarVar(var_name, comp)->uDotDotOld();
297 : }
298 : const VariableValue &
299 64 : ScalarCoupleable::coupledScalarDotDu(const std::string & var_name, const unsigned int comp) const
300 : {
301 64 : checkVar(var_name);
302 64 : validateExecutionerType(var_name, "coupledScalarDotDu");
303 64 : return getScalarVar(var_name, comp)->duDotDu();
304 : }
305 :
306 : const VariableValue &
307 0 : ScalarCoupleable::coupledScalarDotDotDu(const std::string & var_name, const unsigned int comp) const
308 : {
309 0 : checkVar(var_name);
310 0 : validateExecutionerType(var_name, "coupledScalarDotDotDu");
311 0 : return getScalarVar(var_name, comp)->duDotDotDu();
312 : }
313 :
314 : void
315 2328 : ScalarCoupleable::checkVar(const std::string & var_name_in) const
316 : {
317 2328 : const auto var_name = _sc_parameters.checkForRename(var_name_in);
318 :
319 2328 : auto it = _sc_coupled_vars.find(var_name);
320 2328 : if (it != _sc_coupled_vars.end())
321 : {
322 3 : std::string cvars;
323 6 : for (auto jt : it->second)
324 3 : cvars += " " + jt->name();
325 3 : mooseError(_sc_name,
326 : ": Trying to couple a field variable where scalar variable is expected, '",
327 : var_name,
328 : " =",
329 : cvars,
330 : "'");
331 0 : }
332 : // NOTE: non-existent variables are handled in the constructor
333 2325 : }
334 :
335 : const MooseVariableScalar *
336 3664 : ScalarCoupleable::getScalarVar(const std::string & var_name_in, const unsigned int comp) const
337 : {
338 3664 : const auto var_name = _sc_parameters.checkForRename(var_name_in);
339 :
340 3664 : const auto it = _coupled_scalar_vars.find(var_name);
341 3664 : if (it != _coupled_scalar_vars.end())
342 : {
343 3664 : const auto & entry = it->second;
344 3664 : if (comp < entry.size())
345 7328 : return entry[comp];
346 : else
347 0 : mooseError(_sc_name, ": Trying to get a non-existent component of variable '", var_name, "'");
348 : }
349 : else
350 0 : mooseError(_sc_name, ": Trying to get a non-existent variable '", var_name, "'");
351 3664 : }
352 :
353 : void
354 198 : ScalarCoupleable::validateExecutionerType(const std::string & name,
355 : const std::string & fn_name) const
356 : {
357 198 : if (!_sc_fe_problem.isTransient())
358 6 : mooseError(_sc_name,
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 192 : }
366 :
367 : unsigned int
368 157 : ScalarCoupleable::coupledScalarComponents(const std::string & var_name_in) const
369 : {
370 157 : const auto var_name = _sc_parameters.checkForRename(var_name_in);
371 :
372 157 : const auto it = _coupled_scalar_vars.find(var_name);
373 157 : if (it != _coupled_scalar_vars.end())
374 314 : return it->second.size();
375 :
376 0 : mooseError(_sc_name, ": Trying to get a non-existent variable '", var_name, "'");
377 157 : }
|