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 473435 : ScalarCoupleable::ScalarCoupleable(const MooseObject * moose_object)
20 473435 : : _sc_fe_problem(
21 473435 : *moose_object->parameters().getCheckedPointerParam<FEProblemBase *>("_fe_problem_base")),
22 946870 : _sc_tid(moose_object->parameters().isParamValid("_tid")
23 473435 : ? moose_object->parameters().get<THREAD_ID>("_tid")
24 : : 0),
25 473435 : _real_zero(_sc_fe_problem._real_zero[_sc_tid]),
26 473435 : _scalar_zero(_sc_fe_problem._scalar_zero[_sc_tid]),
27 473435 : _point_zero(_sc_fe_problem._point_zero[_sc_tid]),
28 473435 : _sc_parameters(moose_object->parameters()),
29 473435 : _sc_name(_sc_parameters.get<std::string>("_object_name")),
30 473435 : _sc_is_implicit(_sc_parameters.have_parameter<bool>("implicit")
31 473435 : ? _sc_parameters.get<bool>("implicit")
32 473435 : : true)
33 : {
34 473435 : SubProblem & problem = *_sc_parameters.getCheckedPointerParam<SubProblem *>("_subproblem");
35 :
36 : // Coupling
37 473435 : for (std::set<std::string>::const_iterator iter = _sc_parameters.coupledVarsBegin();
38 760664 : iter != _sc_parameters.coupledVarsEnd();
39 287229 : ++iter)
40 : {
41 287229 : std::string name = *iter;
42 287229 : if (_sc_parameters.getVecMooseType(*iter) != std::vector<std::string>())
43 : {
44 73300 : std::vector<std::string> vars = _sc_parameters.getVecMooseType(*iter);
45 162387 : for (const auto & coupled_var_name : vars)
46 : {
47 89087 : if (problem.hasScalarVariable(coupled_var_name))
48 : {
49 2080 : MooseVariableScalar * scalar_var = &problem.getScalarVariable(_sc_tid, coupled_var_name);
50 2080 : _coupled_scalar_vars[name].push_back(scalar_var);
51 2080 : _coupled_moose_scalar_vars.push_back(scalar_var);
52 : }
53 87007 : else if (problem.hasVariable(coupled_var_name))
54 : {
55 : MooseVariableFEBase * moose_var =
56 87007 : &problem.getVariable(_sc_tid,
57 : coupled_var_name,
58 : Moose::VarKindType::VAR_ANY,
59 87007 : Moose::VarFieldType::VAR_FIELD_ANY);
60 87007 : _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 73300 : }
66 287229 : }
67 473435 : }
68 :
69 : bool
70 2228 : ScalarCoupleable::isCoupledScalar(const std::string & var_name_in, unsigned int i) const
71 : {
72 2228 : const auto var_name = _sc_parameters.checkForRename(var_name_in);
73 :
74 2228 : auto it = _coupled_scalar_vars.find(var_name);
75 2228 : if (it != _coupled_scalar_vars.end())
76 1774 : return (i < it->second.size());
77 : else
78 : {
79 : // Make sure the user originally requested this value in the InputParameter syntax
80 454 : 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 454 : return false;
89 : }
90 2228 : }
91 :
92 : unsigned int
93 805 : ScalarCoupleable::coupledScalar(const std::string & var_name, const unsigned int comp) const
94 : {
95 805 : checkVar(var_name);
96 801 : return getScalarVar(var_name, comp)->number();
97 : }
98 :
99 : Order
100 126 : ScalarCoupleable::coupledScalarOrder(const std::string & var_name, const unsigned int comp) const
101 : {
102 126 : checkVar(var_name);
103 126 : if (!isCoupledScalar(var_name, comp))
104 28 : return _sc_fe_problem.getMaxScalarOrder();
105 :
106 98 : return getScalarVar(var_name, comp)->order();
107 : }
108 :
109 : const VariableValue *
110 28 : ScalarCoupleable::getDefaultValue(const std::string & var_name) const
111 : {
112 28 : auto default_value_it = _default_value.find(var_name);
113 28 : if (default_value_it == _default_value.end())
114 : {
115 0 : auto value = std::make_unique<VariableValue>(_sc_fe_problem.getMaxScalarOrder(),
116 28 : _sc_parameters.defaultCoupledValue(var_name));
117 28 : default_value_it = _default_value.insert(std::make_pair(var_name, std::move(value))).first;
118 28 : }
119 :
120 56 : return default_value_it->second.get();
121 : }
122 :
123 : const VariableValue &
124 1112 : ScalarCoupleable::coupledScalarValue(const std::string & var_name, const unsigned int comp) const
125 : {
126 1112 : checkVar(var_name);
127 1112 : if (!isCoupledScalar(var_name, comp))
128 28 : return *getDefaultValue(var_name);
129 :
130 1084 : auto var = getScalarVar(var_name, comp);
131 1084 : return _sc_is_implicit ? var->sln() : var->slnOld();
132 : }
133 :
134 : const ADVariableValue &
135 295 : ScalarCoupleable::adCoupledScalarValue(const std::string & var_name, const unsigned int comp) const
136 : {
137 295 : checkVar(var_name);
138 295 : if (!isCoupledScalar(var_name, comp))
139 0 : return *getADDefaultValue(var_name);
140 :
141 295 : auto var = getScalarVar(var_name, comp);
142 :
143 295 : if (_sc_is_implicit)
144 295 : 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 40 : ScalarCoupleable::coupledVectorTagScalarValue(const std::string & var_name,
182 : TagID tag,
183 : const unsigned int comp) const
184 : {
185 40 : checkVar(var_name);
186 40 : if (!isCoupledScalar(var_name, comp))
187 0 : return *getDefaultValue(var_name);
188 :
189 40 : 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 40 : _sc_coupleable_vector_tags.insert(tag);
197 :
198 40 : return getScalarVar(var_name, comp)->vectorTagSln(tag);
199 : }
200 :
201 : const VariableValue &
202 20 : ScalarCoupleable::coupledMatrixTagScalarValue(const std::string & var_name,
203 : TagID tag,
204 : const unsigned int comp) const
205 : {
206 20 : checkVar(var_name);
207 20 : if (!isCoupledScalar(var_name, comp))
208 0 : return *getDefaultValue(var_name);
209 :
210 20 : _sc_coupleable_matrix_tags.insert(tag);
211 :
212 20 : return getScalarVar(var_name, comp)->matrixTagSln(tag);
213 : }
214 :
215 : const VariableValue &
216 32 : ScalarCoupleable::coupledScalarValueOld(const std::string & var_name, const unsigned int comp) const
217 : {
218 32 : checkVar(var_name);
219 32 : if (!isCoupledScalar(var_name, comp))
220 0 : return *getDefaultValue(var_name);
221 :
222 32 : validateExecutionerType(var_name, "coupledScalarValueOld");
223 28 : auto var = getScalarVar(var_name, comp);
224 28 : return _sc_is_implicit ? var->slnOld() : var->slnOlder();
225 : }
226 :
227 : const VariableValue &
228 28 : ScalarCoupleable::coupledScalarValueOlder(const std::string & var_name,
229 : const unsigned int comp) const
230 : {
231 28 : checkVar(var_name);
232 28 : if (!isCoupledScalar(var_name, comp))
233 0 : return *getDefaultValue(var_name);
234 :
235 28 : validateExecutionerType(var_name, "coupledScalarValueOlder");
236 28 : auto var = getScalarVar(var_name, comp);
237 28 : if (_sc_is_implicit)
238 28 : return var->slnOlder();
239 : else
240 0 : mooseError("Older values not available for explicit schemes");
241 : }
242 :
243 : const VariableValue &
244 75 : ScalarCoupleable::coupledScalarDot(const std::string & var_name, const unsigned int comp) const
245 : {
246 75 : checkVar(var_name);
247 75 : validateExecutionerType(var_name, "coupledScalarDot");
248 71 : return getScalarVar(var_name, comp)->uDot();
249 : }
250 :
251 : const ADVariableValue &
252 13 : ScalarCoupleable::adCoupledScalarDot(const std::string & var_name, const unsigned int comp) const
253 : {
254 13 : checkVar(var_name);
255 13 : validateExecutionerType(var_name, "adCoupledScalarDot");
256 13 : 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 71 : ScalarCoupleable::coupledScalarDotDu(const std::string & var_name, const unsigned int comp) const
285 : {
286 71 : checkVar(var_name);
287 71 : validateExecutionerType(var_name, "coupledScalarDotDu");
288 71 : 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 2617 : ScalarCoupleable::checkVar(const std::string & var_name_in) const
301 : {
302 2617 : const auto var_name = _sc_parameters.checkForRename(var_name_in);
303 :
304 2617 : auto it = _sc_coupled_vars.find(var_name);
305 2617 : 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 2613 : }
319 :
320 : const MooseVariableScalar *
321 4071 : ScalarCoupleable::getScalarVar(const std::string & var_name_in, const unsigned int comp) const
322 : {
323 4071 : const auto var_name = _sc_parameters.checkForRename(var_name_in);
324 :
325 4071 : const auto it = _coupled_scalar_vars.find(var_name);
326 4071 : if (it != _coupled_scalar_vars.end())
327 : {
328 4071 : const auto & entry = it->second;
329 4071 : if (comp < entry.size())
330 8142 : 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 4071 : }
337 :
338 : void
339 219 : ScalarCoupleable::validateExecutionerType(const std::string & name,
340 : const std::string & fn_name) const
341 : {
342 219 : 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 211 : }
351 :
352 : unsigned int
353 177 : ScalarCoupleable::coupledScalarComponents(const std::string & var_name_in) const
354 : {
355 177 : const auto var_name = _sc_parameters.checkForRename(var_name_in);
356 :
357 177 : const auto it = _coupled_scalar_vars.find(var_name);
358 177 : if (it != _coupled_scalar_vars.end())
359 354 : return it->second.size();
360 :
361 0 : mooseError(_sc_name, ": Trying to get a non-existent variable '", var_name, "'");
362 177 : }
|