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