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 490545 : ScalarCoupleable::ScalarCoupleable(const MooseObject * moose_object)
20 490545 : : _sc_fe_problem(
21 1962180 : *moose_object->parameters().getCheckedPointerParam<FEProblemBase *>("_fe_problem_base")),
22 981090 : _sc_tid(moose_object->parameters().isParamValid("_tid")
23 490545 : ? moose_object->parameters().get<THREAD_ID>("_tid")
24 : : 0),
25 490545 : _real_zero(_sc_fe_problem._real_zero[_sc_tid]),
26 490545 : _scalar_zero(_sc_fe_problem._scalar_zero[_sc_tid]),
27 490545 : _point_zero(_sc_fe_problem._point_zero[_sc_tid]),
28 490545 : _sc_parameters(moose_object->parameters()),
29 490545 : _sc_name(_sc_parameters.getObjectName()),
30 490545 : _sc_is_implicit(_sc_parameters.have_parameter<bool>("implicit")
31 490545 : ? _sc_parameters.get<bool>("implicit")
32 490545 : : true)
33 : {
34 1962180 : SubProblem & problem = *_sc_parameters.getCheckedPointerParam<SubProblem *>("_subproblem");
35 :
36 : // Coupling
37 490545 : for (std::set<std::string>::const_iterator iter = _sc_parameters.coupledVarsBegin();
38 787663 : iter != _sc_parameters.coupledVarsEnd();
39 297118 : ++iter)
40 : {
41 297118 : std::string name = *iter;
42 297118 : if (_sc_parameters.getVecMooseType(*iter) != std::vector<std::string>())
43 : {
44 75430 : std::vector<std::string> vars = _sc_parameters.getVecMooseType(*iter);
45 166839 : for (const auto & coupled_var_name : vars)
46 : {
47 91409 : if (problem.hasScalarVariable(coupled_var_name))
48 : {
49 2088 : MooseVariableScalar * scalar_var = &problem.getScalarVariable(_sc_tid, coupled_var_name);
50 2088 : _coupled_scalar_vars[name].push_back(scalar_var);
51 2088 : _coupled_moose_scalar_vars.push_back(scalar_var);
52 : }
53 89321 : else if (problem.hasVariable(coupled_var_name))
54 : {
55 : MooseVariableFEBase * moose_var =
56 89321 : &problem.getVariable(_sc_tid,
57 : coupled_var_name,
58 : Moose::VarKindType::VAR_ANY,
59 89321 : Moose::VarFieldType::VAR_FIELD_ANY);
60 89321 : _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 75430 : }
66 297118 : }
67 490545 : }
68 :
69 : #ifdef MOOSE_KOKKOS_ENABLED
70 200105 : ScalarCoupleable::ScalarCoupleable(const ScalarCoupleable & object,
71 200105 : const Moose::Kokkos::FunctorCopy &)
72 200105 : : _sc_fe_problem(object._sc_fe_problem),
73 200105 : _sc_tid(object._sc_tid),
74 200105 : _real_zero(object._real_zero),
75 200105 : _scalar_zero(object._scalar_zero),
76 200105 : _point_zero(object._point_zero),
77 200105 : _sc_parameters(object._sc_parameters),
78 200105 : _sc_name(object._sc_name),
79 200105 : _sc_is_implicit(object._sc_is_implicit)
80 : {
81 200105 : }
82 : #endif
83 :
84 : bool
85 2241 : ScalarCoupleable::isCoupledScalar(const std::string & var_name_in, unsigned int i) const
86 : {
87 2241 : const auto var_name = _sc_parameters.checkForRename(var_name_in);
88 :
89 2241 : auto it = _coupled_scalar_vars.find(var_name);
90 2241 : if (it != _coupled_scalar_vars.end())
91 1774 : return (i < it->second.size());
92 : else
93 : {
94 : // Make sure the user originally requested this value in the InputParameter syntax
95 467 : 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 467 : return false;
104 : }
105 2241 : }
106 :
107 : unsigned int
108 805 : ScalarCoupleable::coupledScalar(const std::string & var_name, const unsigned int comp) const
109 : {
110 805 : checkVar(var_name);
111 801 : return getScalarVar(var_name, comp)->number();
112 : }
113 :
114 : Order
115 126 : ScalarCoupleable::coupledScalarOrder(const std::string & var_name, const unsigned int comp) const
116 : {
117 126 : checkVar(var_name);
118 126 : if (!isCoupledScalar(var_name, comp))
119 28 : return _sc_fe_problem.getMaxScalarOrder();
120 :
121 98 : return getScalarVar(var_name, comp)->order();
122 : }
123 :
124 : const VariableValue *
125 28 : ScalarCoupleable::getDefaultValue(const std::string & var_name) const
126 : {
127 28 : auto default_value_it = _default_value.find(var_name);
128 28 : if (default_value_it == _default_value.end())
129 : {
130 0 : auto value = std::make_unique<VariableValue>(_sc_fe_problem.getMaxScalarOrder(),
131 28 : _sc_parameters.defaultCoupledValue(var_name));
132 28 : default_value_it = _default_value.insert(std::make_pair(var_name, std::move(value))).first;
133 28 : }
134 :
135 56 : return default_value_it->second.get();
136 : }
137 :
138 : const VariableValue &
139 1112 : ScalarCoupleable::coupledScalarValue(const std::string & var_name, const unsigned int comp) const
140 : {
141 1112 : checkVar(var_name);
142 1112 : if (!isCoupledScalar(var_name, comp))
143 28 : return *getDefaultValue(var_name);
144 :
145 1084 : auto var = getScalarVar(var_name, comp);
146 1084 : return _sc_is_implicit ? var->sln() : var->slnOld();
147 : }
148 :
149 : const ADVariableValue &
150 295 : ScalarCoupleable::adCoupledScalarValue(const std::string & var_name, const unsigned int comp) const
151 : {
152 295 : checkVar(var_name);
153 295 : if (!isCoupledScalar(var_name, comp))
154 0 : return *getADDefaultValue(var_name);
155 :
156 295 : auto var = getScalarVar(var_name, comp);
157 :
158 295 : if (_sc_is_implicit)
159 295 : 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 40 : ScalarCoupleable::coupledVectorTagScalarValue(const std::string & var_name,
197 : TagID tag,
198 : const unsigned int comp) const
199 : {
200 40 : checkVar(var_name);
201 40 : if (!isCoupledScalar(var_name, comp))
202 0 : return *getDefaultValue(var_name);
203 :
204 40 : 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 40 : _sc_coupleable_vector_tags.insert(tag);
212 :
213 40 : return getScalarVar(var_name, comp)->vectorTagSln(tag);
214 : }
215 :
216 : const VariableValue &
217 20 : ScalarCoupleable::coupledMatrixTagScalarValue(const std::string & var_name,
218 : TagID tag,
219 : const unsigned int comp) const
220 : {
221 20 : checkVar(var_name);
222 20 : if (!isCoupledScalar(var_name, comp))
223 0 : return *getDefaultValue(var_name);
224 :
225 20 : _sc_coupleable_matrix_tags.insert(tag);
226 :
227 20 : return getScalarVar(var_name, comp)->matrixTagSln(tag);
228 : }
229 :
230 : const VariableValue &
231 32 : ScalarCoupleable::coupledScalarValueOld(const std::string & var_name, const unsigned int comp) const
232 : {
233 32 : checkVar(var_name);
234 32 : if (!isCoupledScalar(var_name, comp))
235 0 : return *getDefaultValue(var_name);
236 :
237 32 : validateExecutionerType(var_name, "coupledScalarValueOld");
238 28 : auto var = getScalarVar(var_name, comp);
239 28 : return _sc_is_implicit ? var->slnOld() : var->slnOlder();
240 : }
241 :
242 : const VariableValue &
243 28 : ScalarCoupleable::coupledScalarValueOlder(const std::string & var_name,
244 : const unsigned int comp) const
245 : {
246 28 : checkVar(var_name);
247 28 : if (!isCoupledScalar(var_name, comp))
248 0 : return *getDefaultValue(var_name);
249 :
250 28 : validateExecutionerType(var_name, "coupledScalarValueOlder");
251 28 : auto var = getScalarVar(var_name, comp);
252 28 : if (_sc_is_implicit)
253 28 : return var->slnOlder();
254 : else
255 0 : mooseError("Older values not available for explicit schemes");
256 : }
257 :
258 : const VariableValue &
259 75 : ScalarCoupleable::coupledScalarDot(const std::string & var_name, const unsigned int comp) const
260 : {
261 75 : checkVar(var_name);
262 75 : validateExecutionerType(var_name, "coupledScalarDot");
263 71 : return getScalarVar(var_name, comp)->uDot();
264 : }
265 :
266 : const ADVariableValue &
267 13 : ScalarCoupleable::adCoupledScalarDot(const std::string & var_name, const unsigned int comp) const
268 : {
269 13 : checkVar(var_name);
270 13 : validateExecutionerType(var_name, "adCoupledScalarDot");
271 13 : 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 71 : ScalarCoupleable::coupledScalarDotDu(const std::string & var_name, const unsigned int comp) const
300 : {
301 71 : checkVar(var_name);
302 71 : validateExecutionerType(var_name, "coupledScalarDotDu");
303 71 : 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 2617 : ScalarCoupleable::checkVar(const std::string & var_name_in) const
316 : {
317 2617 : const auto var_name = _sc_parameters.checkForRename(var_name_in);
318 :
319 2617 : auto it = _sc_coupled_vars.find(var_name);
320 2617 : if (it != _sc_coupled_vars.end())
321 : {
322 4 : std::string cvars;
323 8 : for (auto jt : it->second)
324 4 : cvars += " " + jt->name();
325 4 : 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 2613 : }
334 :
335 : const MooseVariableScalar *
336 4079 : ScalarCoupleable::getScalarVar(const std::string & var_name_in, const unsigned int comp) const
337 : {
338 4079 : const auto var_name = _sc_parameters.checkForRename(var_name_in);
339 :
340 4079 : const auto it = _coupled_scalar_vars.find(var_name);
341 4079 : if (it != _coupled_scalar_vars.end())
342 : {
343 4079 : const auto & entry = it->second;
344 4079 : if (comp < entry.size())
345 8158 : 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 4079 : }
352 :
353 : void
354 219 : ScalarCoupleable::validateExecutionerType(const std::string & name,
355 : const std::string & fn_name) const
356 : {
357 219 : if (!_sc_fe_problem.isTransient())
358 8 : 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 211 : }
366 :
367 : unsigned int
368 177 : ScalarCoupleable::coupledScalarComponents(const std::string & var_name_in) const
369 : {
370 177 : const auto var_name = _sc_parameters.checkForRename(var_name_in);
371 :
372 177 : const auto it = _coupled_scalar_vars.find(var_name);
373 177 : if (it != _coupled_scalar_vars.end())
374 354 : return it->second.size();
375 :
376 0 : mooseError(_sc_name, ": Trying to get a non-existent variable '", var_name, "'");
377 177 : }
|