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 "SubProblem.h"
11 : #include "Factory.h"
12 : #include "MooseMesh.h"
13 : #include "Conversion.h"
14 : #include "Function.h"
15 : #include "MooseApp.h"
16 : #include "MooseVariableFE.h"
17 : #include "MooseArray.h"
18 : #include "Assembly.h"
19 : #include "MooseObjectName.h"
20 : #include "RelationshipManager.h"
21 : #include "MooseUtils.h"
22 : #include "DisplacedSystem.h"
23 : #include "NonlinearSystemBase.h"
24 : #include "LinearSystem.h"
25 :
26 : #include "libmesh/equation_systems.h"
27 : #include "libmesh/system.h"
28 : #include "libmesh/dof_map.h"
29 : #include "libmesh/string_to_enum.h"
30 :
31 : #include <regex>
32 :
33 : using namespace libMesh;
34 :
35 : InputParameters
36 374006 : SubProblem::validParams()
37 : {
38 374006 : InputParameters params = Problem::validParams();
39 :
40 1122018 : params.addParam<bool>(
41 : "default_ghosting",
42 748012 : false,
43 : "Whether or not to use libMesh's default amount of algebraic and geometric ghosting");
44 :
45 1122018 : params.addParamNamesToGroup("default_ghosting", "Advanced");
46 :
47 374006 : return params;
48 0 : }
49 :
50 : const std::unordered_set<FEFamily> SubProblem::_default_families_without_p_refinement = {
51 : libMesh::LAGRANGE,
52 : libMesh::NEDELEC_ONE,
53 : libMesh::RAVIART_THOMAS,
54 : libMesh::LAGRANGE_VEC,
55 : libMesh::CLOUGH,
56 : libMesh::BERNSTEIN,
57 : libMesh::RATIONAL_BERNSTEIN};
58 :
59 : // SubProblem /////
60 67070 : SubProblem::SubProblem(const InputParameters & parameters)
61 : : Problem(parameters),
62 67070 : _factory(_app.getFactory()),
63 134140 : _default_ghosting(getParam<bool>("default_ghosting")),
64 67070 : _currently_computing_jacobian(false),
65 67070 : _currently_computing_residual_and_jacobian(false),
66 67070 : _computing_nonlinear_residual(false),
67 67070 : _currently_computing_residual(false),
68 67070 : _safe_access_tagged_matrices(false),
69 67070 : _safe_access_tagged_vectors(false),
70 67070 : _have_ad_objects(false),
71 67070 : _show_functors(false),
72 67070 : _show_chain_control_data(false),
73 134140 : _typed_vector_tags(2),
74 268280 : _have_p_refinement(false)
75 : {
76 67070 : unsigned int n_threads = libMesh::n_threads();
77 67070 : _active_elemental_moose_variables.resize(n_threads);
78 67070 : _has_active_elemental_moose_variables.resize(n_threads);
79 :
80 67070 : _active_fe_var_coupleable_matrix_tags.resize(n_threads);
81 67070 : _active_fe_var_coupleable_vector_tags.resize(n_threads);
82 67070 : _active_sc_var_coupleable_matrix_tags.resize(n_threads);
83 67070 : _active_sc_var_coupleable_vector_tags.resize(n_threads);
84 :
85 67070 : _functors.resize(n_threads);
86 67070 : _pbblf_functors.resize(n_threads);
87 67070 : _functor_to_request_info.resize(n_threads);
88 67070 : }
89 :
90 62566 : SubProblem::~SubProblem() {}
91 :
92 : TagID
93 432507 : SubProblem::addVectorTag(const TagName & tag_name,
94 : const Moose::VectorTagType type /* = Moose::VECTOR_TAG_RESIDUAL */)
95 : {
96 432507 : if (type == Moose::VECTOR_TAG_ANY)
97 0 : mooseError("Vector tag type cannot be VECTOR_TAG_ANY");
98 :
99 432507 : const auto tag_name_upper = MooseUtils::toUpper(tag_name);
100 :
101 : // First, see if the tag exists already
102 1688359 : for (const auto & vector_tag : _vector_tags)
103 : {
104 : mooseAssert(_vector_tags[vector_tag._id] == vector_tag, "Vector tags index mismatch");
105 1356912 : if (vector_tag._name == tag_name_upper)
106 : {
107 101060 : if (vector_tag._type != type)
108 0 : mooseError("While attempting to add vector tag with name '",
109 : tag_name_upper,
110 : "' and type ",
111 : type,
112 : ",\na tag with the same name but type ",
113 0 : vector_tag._type,
114 : " was found.\n\nA tag can only exist with one type.");
115 :
116 101060 : return vector_tag._id;
117 : }
118 : }
119 :
120 : // Doesn't exist - create it
121 331447 : const TagID new_tag_id = _vector_tags.size();
122 331447 : const TagTypeID new_tag_type_id = _typed_vector_tags[type].size();
123 : // Primary storage for all tags where the index in the vector == the tag ID
124 331447 : _vector_tags.emplace_back(new_tag_id, new_tag_type_id, tag_name_upper, type);
125 : // Secondary storage for each type so that we can have quick access to all tags of a type
126 331447 : _typed_vector_tags[type].emplace_back(new_tag_id, new_tag_type_id, tag_name_upper, type);
127 : // Name map storage for quick name access
128 331447 : _vector_tags_name_map.emplace(tag_name_upper, new_tag_id);
129 :
130 : // Make sure that _vector_tags, _typed_vector_tags, and _vector_tags_name_map are sane
131 331447 : verifyVectorTags();
132 :
133 331447 : return new_tag_id;
134 432507 : }
135 :
136 : bool
137 340575 : SubProblem::vectorTagExists(const TagName & tag_name) const
138 : {
139 : mooseAssert(verifyVectorTags(), "Vector tag storage invalid");
140 :
141 340575 : const auto tag_name_upper = MooseUtils::toUpper(tag_name);
142 2806104 : for (const auto & vector_tag : _vector_tags)
143 2487953 : if (vector_tag._name == tag_name_upper)
144 22424 : return true;
145 :
146 318151 : return false;
147 340575 : }
148 :
149 : void
150 12 : SubProblem::addNotZeroedVectorTag(const TagID tag)
151 : {
152 12 : _not_zeroed_tagged_vectors.insert(tag);
153 12 : }
154 :
155 : bool
156 9670503 : SubProblem::vectorTagNotZeroed(const TagID tag) const
157 : {
158 9670503 : return _not_zeroed_tagged_vectors.count(tag);
159 : }
160 :
161 : const VectorTag &
162 941108755 : SubProblem::getVectorTag(const TagID tag_id) const
163 : {
164 : mooseAssert(verifyVectorTags(), "Vector tag storage invalid");
165 :
166 941108755 : if (!vectorTagExists(tag_id))
167 0 : mooseError("Vector tag with ID ", tag_id, " does not exist");
168 :
169 941108755 : return _vector_tags[tag_id];
170 : }
171 :
172 : std::vector<VectorTag>
173 6711840 : SubProblem::getVectorTags(const std::set<TagID> & tag_ids) const
174 : {
175 : mooseAssert(verifyVectorTags(), "Vector tag storage invalid");
176 :
177 6711840 : std::vector<VectorTag> tags;
178 6711840 : tags.reserve(tag_ids.size());
179 26070441 : for (const auto & tag_id : tag_ids)
180 19358601 : tags.push_back(getVectorTag(tag_id));
181 6711840 : return tags;
182 0 : }
183 :
184 : const std::vector<VectorTag> &
185 11831472 : SubProblem::getVectorTags(const Moose::VectorTagType type /* = Moose::VECTOR_TAG_ANY */) const
186 : {
187 : mooseAssert(verifyVectorTags(), "Vector tag storage invalid");
188 :
189 11831472 : if (type == Moose::VECTOR_TAG_ANY)
190 563829 : return _vector_tags;
191 : else
192 11267643 : return _typed_vector_tags[type];
193 : }
194 :
195 : unsigned int
196 8347729 : SubProblem::numVectorTags(const Moose::VectorTagType type /* = Moose::VECTOR_TAG_ANY */) const
197 : {
198 : mooseAssert(verifyVectorTags(), "Vector tag storage invalid");
199 :
200 8347729 : return getVectorTags(type).size();
201 : }
202 :
203 : TagID
204 6878160 : SubProblem::getVectorTagID(const TagName & tag_name) const
205 : {
206 : mooseAssert(verifyVectorTags(), "Vector tag storage invalid");
207 :
208 6878160 : const auto tag_name_upper = MooseUtils::toUpper(tag_name);
209 6878160 : const auto search = _vector_tags_name_map.find(tag_name_upper);
210 6878160 : if (search != _vector_tags_name_map.end())
211 13756288 : return search->second;
212 :
213 : std::string message =
214 16 : tag_name_upper == "TIME"
215 : ? ".\n\nThis may occur if "
216 : "you have a TimeKernel in your problem but did not specify a transient executioner."
217 16 : : "";
218 16 : mooseError("Vector tag '", tag_name_upper, "' does not exist", message);
219 6878144 : }
220 :
221 : TagName
222 169607 : SubProblem::vectorTagName(const TagID tag_id) const
223 : {
224 : mooseAssert(verifyVectorTags(), "Vector tag storage invalid");
225 169607 : if (!vectorTagExists(tag_id))
226 0 : mooseError("Vector tag with ID ", tag_id, " does not exist");
227 :
228 169607 : return _vector_tags[tag_id]._name;
229 : }
230 :
231 : Moose::VectorTagType
232 2459775016 : SubProblem::vectorTagType(const TagID tag_id) const
233 : {
234 : mooseAssert(verifyVectorTags(), "Vector tag storage invalid");
235 2459775016 : if (!vectorTagExists(tag_id))
236 0 : mooseError("Vector tag with ID ", tag_id, " does not exist");
237 :
238 2459775016 : return _vector_tags[tag_id]._type;
239 : }
240 :
241 : bool
242 331447 : SubProblem::verifyVectorTags() const
243 : {
244 1504429 : for (TagID tag_id = 0; tag_id < _vector_tags.size(); ++tag_id)
245 : {
246 1172982 : const auto & vector_tag = _vector_tags[tag_id];
247 :
248 1172982 : if (vector_tag._id != tag_id)
249 0 : mooseError("Vector tag ", vector_tag._id, " id mismatch in _vector_tags");
250 1172982 : if (vector_tag._type == Moose::VECTOR_TAG_ANY)
251 0 : mooseError("Vector tag '", vector_tag._name, "' has type VECTOR_TAG_ANY");
252 :
253 1172982 : const auto search = _vector_tags_name_map.find(vector_tag._name);
254 1172982 : if (search == _vector_tags_name_map.end())
255 0 : mooseError("Vector tag ", vector_tag._id, " is not in _vector_tags_name_map");
256 1172982 : else if (search->second != tag_id)
257 0 : mooseError("Vector tag ", vector_tag._id, " has incorrect id in _vector_tags_name_map");
258 :
259 1172982 : unsigned int found_in_type = 0;
260 4396096 : for (TagTypeID tag_type_id = 0; tag_type_id < _typed_vector_tags[vector_tag._type].size();
261 : ++tag_type_id)
262 : {
263 3223114 : const auto & vector_tag_type = _typed_vector_tags[vector_tag._type][tag_type_id];
264 3223114 : if (vector_tag_type == vector_tag)
265 : {
266 1172982 : ++found_in_type;
267 1172982 : if (vector_tag_type._type_id != tag_type_id)
268 0 : mooseError("Type ID for Vector tag ", tag_id, " is incorrect");
269 : }
270 : }
271 :
272 1172982 : if (found_in_type == 0)
273 0 : mooseError("Vector tag ", tag_id, " not found in _typed_vector_tags");
274 1172982 : if (found_in_type > 1)
275 0 : mooseError("Vector tag ", tag_id, " found multiple times in _typed_vector_tags");
276 : }
277 :
278 331447 : unsigned int num_typed_vector_tags = 0;
279 994341 : for (const auto & typed_vector_tags : _typed_vector_tags)
280 662894 : num_typed_vector_tags += typed_vector_tags.size();
281 331447 : if (num_typed_vector_tags != _vector_tags.size())
282 0 : mooseError("Size mismatch between _vector_tags and _typed_vector_tags");
283 331447 : if (_vector_tags_name_map.size() != _vector_tags.size())
284 0 : mooseError("Size mismatch between _vector_tags and _vector_tags_name_map");
285 :
286 331447 : return true;
287 : }
288 :
289 : void
290 3320664 : SubProblem::selectVectorTagsFromSystem(const SystemBase & system,
291 : const std::vector<VectorTag> & input_vector_tags,
292 : std::set<TagID> & selected_tags)
293 : {
294 3320664 : selected_tags.clear();
295 12937253 : for (const auto & vector_tag : input_vector_tags)
296 9616589 : if (system.hasVector(vector_tag._id))
297 9614443 : selected_tags.insert(vector_tag._id);
298 3320664 : }
299 :
300 : void
301 5738 : SubProblem::selectMatrixTagsFromSystem(const SystemBase & system,
302 : const std::map<TagName, TagID> & input_matrix_tags,
303 : std::set<TagID> & selected_tags)
304 : {
305 5738 : selected_tags.clear();
306 11985 : for (const auto & matrix_tag_pair : input_matrix_tags)
307 6247 : if (system.hasMatrix(matrix_tag_pair.second))
308 5762 : selected_tags.insert(matrix_tag_pair.second);
309 5738 : }
310 :
311 : TagID
312 131122 : SubProblem::addMatrixTag(TagName tag_name)
313 : {
314 131122 : auto tag_name_upper = MooseUtils::toUpper(tag_name);
315 131122 : auto existing_tag = _matrix_tag_name_to_tag_id.find(tag_name_upper);
316 131122 : if (existing_tag == _matrix_tag_name_to_tag_id.end())
317 : {
318 130579 : auto tag_id = _matrix_tag_name_to_tag_id.size();
319 :
320 130579 : _matrix_tag_name_to_tag_id[tag_name_upper] = tag_id;
321 :
322 130579 : _matrix_tag_id_to_tag_name[tag_id] = tag_name_upper;
323 : }
324 :
325 262244 : return _matrix_tag_name_to_tag_id.at(tag_name_upper);
326 131122 : }
327 :
328 : bool
329 309122 : SubProblem::matrixTagExists(const TagName & tag_name) const
330 : {
331 309122 : auto tag_name_upper = MooseUtils::toUpper(tag_name);
332 :
333 618244 : return _matrix_tag_name_to_tag_id.find(tag_name_upper) != _matrix_tag_name_to_tag_id.end();
334 309122 : }
335 :
336 : bool
337 1674288 : SubProblem::matrixTagExists(TagID tag_id) const
338 : {
339 1674288 : return _matrix_tag_id_to_tag_name.find(tag_id) != _matrix_tag_id_to_tag_name.end();
340 : }
341 :
342 : TagID
343 307203 : SubProblem::getMatrixTagID(const TagName & tag_name) const
344 : {
345 307203 : auto tag_name_upper = MooseUtils::toUpper(tag_name);
346 :
347 307203 : if (!matrixTagExists(tag_name))
348 4 : mooseError("Matrix tag: ",
349 : tag_name,
350 : " does not exist. ",
351 : "If this is a TimeKernel then this may have happened because you didn't "
352 : "specify a Transient Executioner.");
353 :
354 614398 : return _matrix_tag_name_to_tag_id.at(tag_name_upper);
355 307199 : }
356 :
357 : TagName
358 444 : SubProblem::matrixTagName(TagID tag)
359 : {
360 444 : return _matrix_tag_id_to_tag_name[tag];
361 : }
362 :
363 : void
364 656299 : SubProblem::setActiveFEVariableCoupleableMatrixTags(std::set<TagID> & mtags, const THREAD_ID tid)
365 : {
366 656299 : _active_fe_var_coupleable_matrix_tags[tid] = mtags;
367 656299 : }
368 :
369 : void
370 7669424 : SubProblem::setActiveFEVariableCoupleableVectorTags(std::set<TagID> & vtags, const THREAD_ID tid)
371 : {
372 7669424 : _active_fe_var_coupleable_vector_tags[tid] = vtags;
373 15471904 : for (const auto sys_num : make_range(numSolverSystems()))
374 7802480 : systemBaseSolver(sys_num).setActiveVariableCoupleableVectorTags(vtags, tid);
375 7669424 : systemBaseAuxiliary().setActiveVariableCoupleableVectorTags(vtags, tid);
376 7669424 : }
377 :
378 : void
379 299357 : SubProblem::clearActiveFEVariableCoupleableVectorTags(const THREAD_ID tid)
380 : {
381 299357 : _active_fe_var_coupleable_vector_tags[tid].clear();
382 299357 : }
383 :
384 : void
385 299357 : SubProblem::clearActiveFEVariableCoupleableMatrixTags(const THREAD_ID tid)
386 : {
387 299357 : _active_fe_var_coupleable_matrix_tags[tid].clear();
388 299357 : }
389 :
390 : const std::set<TagID> &
391 1925073865 : SubProblem::getActiveFEVariableCoupleableMatrixTags(const THREAD_ID tid) const
392 : {
393 1925073865 : return _active_fe_var_coupleable_matrix_tags[tid];
394 : }
395 :
396 : const std::set<TagID> &
397 334 : SubProblem::getActiveFEVariableCoupleableVectorTags(const THREAD_ID tid) const
398 : {
399 334 : return _active_fe_var_coupleable_vector_tags[tid];
400 : }
401 :
402 : void
403 56031 : SubProblem::setActiveScalarVariableCoupleableMatrixTags(std::set<TagID> & mtags,
404 : const THREAD_ID tid)
405 : {
406 56031 : _active_sc_var_coupleable_matrix_tags[tid] = mtags;
407 56031 : }
408 :
409 : void
410 56031 : SubProblem::setActiveScalarVariableCoupleableVectorTags(std::set<TagID> & vtags,
411 : const THREAD_ID tid)
412 : {
413 56031 : _active_sc_var_coupleable_vector_tags[tid] = vtags;
414 112062 : for (const auto nl_sys_num : make_range(numNonlinearSystems()))
415 56031 : systemBaseNonlinear(nl_sys_num).setActiveScalarVariableCoupleableVectorTags(vtags, tid);
416 56031 : systemBaseAuxiliary().setActiveScalarVariableCoupleableVectorTags(vtags, tid);
417 56031 : }
418 :
419 : void
420 56031 : SubProblem::clearActiveScalarVariableCoupleableVectorTags(const THREAD_ID tid)
421 : {
422 56031 : _active_sc_var_coupleable_vector_tags[tid].clear();
423 56031 : }
424 :
425 : void
426 56031 : SubProblem::clearActiveScalarVariableCoupleableMatrixTags(const THREAD_ID tid)
427 : {
428 56031 : _active_sc_var_coupleable_matrix_tags[tid].clear();
429 56031 : }
430 :
431 : const std::set<TagID> &
432 569980 : SubProblem::getActiveScalarVariableCoupleableMatrixTags(const THREAD_ID tid) const
433 : {
434 569980 : return _active_sc_var_coupleable_matrix_tags[tid];
435 : }
436 :
437 : const std::set<TagID> &
438 0 : SubProblem::getActiveScalarVariableCoupleableVectorTags(const THREAD_ID tid) const
439 : {
440 0 : return _active_sc_var_coupleable_vector_tags[tid];
441 : }
442 :
443 : void
444 11862332 : SubProblem::setActiveElementalMooseVariables(const std::set<MooseVariableFEBase *> & moose_vars,
445 : const THREAD_ID tid)
446 : {
447 11862332 : if (!moose_vars.empty())
448 : {
449 11415840 : _has_active_elemental_moose_variables[tid] = 1;
450 11415840 : _active_elemental_moose_variables[tid] = moose_vars;
451 : }
452 11862332 : }
453 :
454 : const std::set<MooseVariableFEBase *> &
455 1282806667 : SubProblem::getActiveElementalMooseVariables(const THREAD_ID tid) const
456 : {
457 1282806667 : return _active_elemental_moose_variables[tid];
458 : }
459 :
460 : bool
461 1328140674 : SubProblem::hasActiveElementalMooseVariables(const THREAD_ID tid) const
462 : {
463 1328140674 : return _has_active_elemental_moose_variables[tid];
464 : }
465 :
466 : void
467 4902201 : SubProblem::clearActiveElementalMooseVariables(const THREAD_ID tid)
468 : {
469 4902201 : _has_active_elemental_moose_variables[tid] = 0;
470 4902201 : _active_elemental_moose_variables[tid].clear();
471 4902201 : }
472 :
473 : std::set<SubdomainID>
474 8 : SubProblem::getMaterialPropertyBlocks(const std::string & prop_name)
475 : {
476 8 : std::set<SubdomainID> blocks;
477 :
478 24 : for (const auto & it : _map_block_material_props)
479 : {
480 16 : const std::set<std::string> & prop_names = it.second;
481 16 : std::set<std::string>::iterator name_it = prop_names.find(prop_name);
482 16 : if (name_it != prop_names.end())
483 16 : blocks.insert(it.first);
484 : }
485 :
486 8 : return blocks;
487 0 : }
488 :
489 : std::vector<SubdomainName>
490 8 : SubProblem::getMaterialPropertyBlockNames(const std::string & prop_name)
491 : {
492 8 : std::set<SubdomainID> blocks = getMaterialPropertyBlocks(prop_name);
493 8 : std::vector<SubdomainName> block_names;
494 8 : block_names.reserve(blocks.size());
495 24 : for (const auto & block_id : blocks)
496 : {
497 16 : SubdomainName name;
498 16 : name = mesh().getMesh().subdomain_name(block_id);
499 16 : if (name.empty())
500 : {
501 8 : std::ostringstream oss;
502 8 : oss << block_id;
503 8 : name = oss.str();
504 8 : }
505 16 : block_names.push_back(name);
506 16 : }
507 :
508 16 : return block_names;
509 8 : }
510 :
511 : bool
512 360 : SubProblem::hasBlockMaterialProperty(SubdomainID bid, const std::string & prop_name)
513 : {
514 360 : auto it = _map_block_material_props.find(bid);
515 360 : if (it == _map_block_material_props.end())
516 0 : return false;
517 :
518 360 : if (it->second.count(prop_name) > 0)
519 270 : return true;
520 : else
521 90 : return false;
522 : }
523 :
524 : // TODO: remove code duplication by templating
525 : std::set<BoundaryID>
526 8 : SubProblem::getMaterialPropertyBoundaryIDs(const std::string & prop_name)
527 : {
528 8 : std::set<BoundaryID> boundaries;
529 :
530 20 : for (const auto & it : _map_boundary_material_props)
531 : {
532 12 : const std::set<std::string> & prop_names = it.second;
533 12 : std::set<std::string>::iterator name_it = prop_names.find(prop_name);
534 12 : if (name_it != prop_names.end())
535 12 : boundaries.insert(it.first);
536 : }
537 :
538 8 : return boundaries;
539 0 : }
540 :
541 : std::vector<BoundaryName>
542 8 : SubProblem::getMaterialPropertyBoundaryNames(const std::string & prop_name)
543 : {
544 8 : std::set<BoundaryID> boundaries = getMaterialPropertyBoundaryIDs(prop_name);
545 8 : std::vector<BoundaryName> boundary_names;
546 8 : boundary_names.reserve(boundaries.size());
547 8 : const BoundaryInfo & boundary_info = mesh().getMesh().get_boundary_info();
548 :
549 20 : for (const auto & bnd_id : boundaries)
550 : {
551 12 : BoundaryName name;
552 12 : if (bnd_id == Moose::ANY_BOUNDARY_ID)
553 4 : name = "ANY_BOUNDARY_ID";
554 : else
555 : {
556 8 : name = boundary_info.get_sideset_name(bnd_id);
557 8 : if (name.empty())
558 : {
559 0 : std::ostringstream oss;
560 0 : oss << bnd_id;
561 0 : name = oss.str();
562 0 : }
563 : }
564 12 : boundary_names.push_back(name);
565 12 : }
566 :
567 16 : return boundary_names;
568 8 : }
569 :
570 : bool
571 0 : SubProblem::hasBoundaryMaterialProperty(BoundaryID bid, const std::string & prop_name)
572 : {
573 0 : auto it = _map_boundary_material_props.find(bid);
574 0 : if (it == _map_boundary_material_props.end())
575 0 : return false;
576 :
577 0 : if (it->second.count(prop_name) > 0)
578 0 : return true;
579 : else
580 0 : return false;
581 : }
582 :
583 : void
584 71572 : SubProblem::storeSubdomainMatPropName(SubdomainID block_id, const std::string & name)
585 : {
586 71572 : _map_block_material_props[block_id].insert(name);
587 71572 : }
588 :
589 : void
590 67548 : SubProblem::storeBoundaryMatPropName(BoundaryID boundary_id, const std::string & name)
591 : {
592 67548 : _map_boundary_material_props[boundary_id].insert(name);
593 67548 : }
594 :
595 : void
596 9522 : SubProblem::storeSubdomainZeroMatProp(SubdomainID block_id, const MaterialPropertyName & name)
597 : {
598 9522 : _zero_block_material_props[block_id].insert(name);
599 9522 : }
600 :
601 : void
602 9522 : SubProblem::storeBoundaryZeroMatProp(BoundaryID boundary_id, const MaterialPropertyName & name)
603 : {
604 9522 : _zero_boundary_material_props[boundary_id].insert(name);
605 9522 : }
606 :
607 : void
608 46860 : SubProblem::storeSubdomainDelayedCheckMatProp(const std::string & requestor,
609 : SubdomainID block_id,
610 : const std::string & name)
611 : {
612 46860 : _map_block_material_props_check[block_id].insert(std::make_pair(requestor, name));
613 46860 : }
614 :
615 : void
616 6354 : SubProblem::storeBoundaryDelayedCheckMatProp(const std::string & requestor,
617 : BoundaryID boundary_id,
618 : const std::string & name)
619 : {
620 6354 : _map_boundary_material_props_check[boundary_id].insert(std::make_pair(requestor, name));
621 6354 : }
622 :
623 : void
624 62704 : SubProblem::checkBlockMatProps()
625 : {
626 : // Variable for storing all available blocks/boundaries from the mesh
627 62704 : std::set<SubdomainID> all_ids(mesh().meshSubdomains());
628 :
629 62704 : std::stringstream errors;
630 :
631 : // Loop through the properties to check
632 69472 : for (const auto & check_it : _map_block_material_props_check)
633 : {
634 : // The current id for the property being checked (BoundaryID || BlockID)
635 6768 : SubdomainID check_id = check_it.first;
636 :
637 13536 : std::set<SubdomainID> check_ids = {check_id};
638 :
639 : // Loop through all the block/boundary ids
640 13536 : for (const auto & id : check_ids)
641 : {
642 : // Loop through all the stored properties
643 51401 : for (const auto & prop_it : check_it.second)
644 : {
645 : // Produce an error if the material property is not defined on the current block/boundary
646 : // and any block/boundary
647 : // and not is not a zero material property.
648 44742 : if (_map_block_material_props[id].count(prop_it.second) == 0 &&
649 44742 : _zero_block_material_props[id].count(prop_it.second) == 0)
650 : {
651 53 : std::string check_name = restrictionSubdomainCheckName(id);
652 53 : if (check_name.empty())
653 48 : check_name = std::to_string(id);
654 106 : errors << "Material property '" << prop_it.second << "', requested by '" << prop_it.first
655 53 : << "' is not defined on block " << check_name << "\n";
656 53 : }
657 : }
658 : }
659 6768 : }
660 :
661 62704 : if (!errors.str().empty())
662 42 : mooseError(errors.str());
663 62662 : }
664 :
665 : void
666 62662 : SubProblem::checkBoundaryMatProps()
667 : {
668 : // Variable for storing the value for ANY_BOUNDARY_ID
669 62662 : BoundaryID any_id = Moose::ANY_BOUNDARY_ID;
670 :
671 : // Variable for storing all available blocks/boundaries from the mesh
672 62662 : std::set<BoundaryID> all_ids(mesh().getBoundaryIDs());
673 :
674 62662 : std::stringstream errors;
675 :
676 : // Loop through the properties to check
677 65398 : for (const auto & check_it : _map_boundary_material_props_check)
678 : {
679 : // The current id for the property being checked (BoundaryID || BlockID)
680 2736 : BoundaryID check_id = check_it.first;
681 :
682 : // In the case when the material being checked has an ID is set to ANY, then loop through all
683 : // the possible ids and verify that the material property is defined.
684 5472 : std::set<BoundaryID> check_ids{check_id};
685 2736 : if (check_id == any_id)
686 0 : check_ids = all_ids;
687 :
688 : // Loop through all the block/boundary ids
689 5472 : for (const auto & id : check_ids)
690 : {
691 : // Loop through all the stored properties
692 9090 : for (const auto & prop_it : check_it.second)
693 : {
694 : // Produce an error if the material property is not defined on the current block/boundary
695 : // and any block/boundary
696 : // and not is not a zero material property.
697 6354 : if (_map_boundary_material_props[id].count(prop_it.second) == 0 &&
698 5041 : _map_boundary_material_props[any_id].count(prop_it.second) == 0 &&
699 24118 : _zero_boundary_material_props[id].count(prop_it.second) == 0 &&
700 6369 : _zero_boundary_material_props[any_id].count(prop_it.second) == 0)
701 : {
702 15 : std::string check_name = restrictionBoundaryCheckName(id);
703 15 : if (check_name.empty())
704 0 : check_name = std::to_string(id);
705 30 : errors << "Material property '" << prop_it.second << "', requested by '" << prop_it.first
706 15 : << "' is not defined on boundary " << check_name << "\n";
707 15 : }
708 : }
709 : }
710 2736 : }
711 :
712 62662 : if (!errors.str().empty())
713 12 : mooseError(errors.str());
714 62650 : }
715 :
716 : bool
717 0 : SubProblem::nlConverged(const unsigned int nl_sys_num)
718 : {
719 : mooseAssert(nl_sys_num < numNonlinearSystems(),
720 : "The nonlinear system number is higher than the number of systems we have!");
721 0 : return solverSystemConverged(nl_sys_num);
722 : }
723 :
724 : void
725 66788 : SubProblem::markMatPropRequested(const std::string & prop_name)
726 : {
727 66788 : _material_property_requested.insert(prop_name);
728 66788 : }
729 :
730 : bool
731 0 : SubProblem::isMatPropRequested(const std::string & prop_name) const
732 : {
733 0 : return _material_property_requested.find(prop_name) != _material_property_requested.end();
734 : }
735 :
736 : void
737 51752 : SubProblem::addConsumedPropertyName(const MooseObjectName & obj_name, const std::string & prop_name)
738 : {
739 51752 : _consumed_material_properties[obj_name].insert(prop_name);
740 51752 : }
741 :
742 : const std::map<MooseObjectName, std::set<std::string>> &
743 248 : SubProblem::getConsumedPropertyMap() const
744 : {
745 248 : return _consumed_material_properties;
746 : }
747 :
748 : DiracKernelInfo &
749 1024 : SubProblem::diracKernelInfo()
750 : {
751 1024 : return _dirac_kernel_info;
752 : }
753 :
754 : Real
755 0 : SubProblem::finalNonlinearResidual(unsigned int) const
756 : {
757 0 : return 0;
758 : }
759 :
760 : unsigned int
761 0 : SubProblem::nNonlinearIterations(unsigned int) const
762 : {
763 0 : return 0;
764 : }
765 :
766 : unsigned int
767 0 : SubProblem::nLinearIterations(unsigned int) const
768 : {
769 0 : return 0;
770 : }
771 :
772 : std::string
773 53 : SubProblem::restrictionSubdomainCheckName(SubdomainID check_id)
774 : {
775 : // TODO: Put a better a interface in MOOSE
776 53 : std::map<subdomain_id_type, std::string> & name_map = mesh().getMesh().set_subdomain_name_map();
777 53 : std::map<subdomain_id_type, std::string>::const_iterator pos = name_map.find(check_id);
778 53 : if (pos != name_map.end())
779 5 : return pos->second;
780 96 : return "";
781 : }
782 :
783 : std::string
784 15 : SubProblem::restrictionBoundaryCheckName(BoundaryID check_id)
785 : {
786 15 : return mesh().getMesh().get_boundary_info().sideset_name(check_id);
787 : }
788 :
789 : void
790 146038405 : SubProblem::setCurrentBoundaryID(BoundaryID bid, const THREAD_ID tid)
791 : {
792 293377461 : for (const auto nl_sys_num : make_range(numNonlinearSystems()))
793 147339056 : assembly(tid, nl_sys_num).setCurrentBoundaryID(bid);
794 146038405 : }
795 :
796 : unsigned int
797 216 : SubProblem::getAxisymmetricRadialCoord() const
798 : {
799 216 : return mesh().getAxisymmetricRadialCoord();
800 : }
801 :
802 : bool
803 4 : SubProblem::hasLinearVariable(const std::string & var_name) const
804 : {
805 4 : for (const auto i : make_range(numLinearSystems()))
806 0 : if (systemBaseLinear(i).hasVariable(var_name))
807 0 : return true;
808 4 : return false;
809 : }
810 :
811 : bool
812 18 : SubProblem::hasAuxiliaryVariable(const std::string & var_name) const
813 : {
814 18 : return systemBaseAuxiliary().hasVariable(var_name);
815 : }
816 :
817 : template <typename T>
818 : MooseVariableFEBase &
819 4811952 : SubProblem::getVariableHelper(const THREAD_ID tid,
820 : const std::string & var_name,
821 : Moose::VarKindType expected_var_type,
822 : Moose::VarFieldType expected_var_field_type,
823 : const std::vector<T> & systems,
824 : const SystemBase & aux) const
825 : {
826 : // Eventual return value
827 4811952 : MooseVariableFEBase * var = nullptr;
828 :
829 4811952 : const auto [var_in_sys, sys_num] = determineSolverSystem(var_name);
830 :
831 : // First check that the variable is found on the expected system.
832 4811952 : if (expected_var_type == Moose::VarKindType::VAR_ANY)
833 : {
834 2637124 : if (var_in_sys)
835 1217694 : var = &(systems[sys_num]->getVariable(tid, var_name));
836 1419430 : else if (aux.hasVariable(var_name))
837 1419430 : var = &(aux.getVariable(tid, var_name));
838 : else
839 0 : mooseError("Unknown variable " + var_name);
840 : }
841 2373959 : else if (expected_var_type == Moose::VarKindType::VAR_SOLVER && var_in_sys &&
842 199131 : systems[sys_num]->hasVariable(var_name))
843 199131 : var = &(systems[sys_num]->getVariable(tid, var_name));
844 1975697 : else if (expected_var_type == Moose::VarKindType::VAR_AUXILIARY && aux.hasVariable(var_name))
845 1975697 : var = &(aux.getVariable(tid, var_name));
846 : else
847 : {
848 0 : std::string expected_var_type_string =
849 : (expected_var_type == Moose::VarKindType::VAR_SOLVER ? "nonlinear" : "auxiliary");
850 0 : mooseError("No ",
851 : expected_var_type_string,
852 : " variable named ",
853 : var_name,
854 : " found. "
855 : "Did you specify an auxiliary variable when you meant to specify a nonlinear "
856 : "variable (or vice-versa)?");
857 0 : }
858 :
859 : // Now make sure the var found has the expected field type.
860 7050256 : if ((expected_var_field_type == Moose::VarFieldType::VAR_FIELD_ANY) ||
861 2238304 : (expected_var_field_type == var->fieldType()))
862 4811944 : return *var;
863 : else
864 : {
865 8 : std::string expected_var_field_type_string =
866 : MooseUtils::toLower(Moose::stringify(expected_var_field_type));
867 8 : std::string var_field_type_string = MooseUtils::toLower(Moose::stringify(var->fieldType()));
868 :
869 8 : mooseError("No ",
870 : expected_var_field_type_string,
871 : " variable named ",
872 : var_name,
873 : " found. "
874 : "Did you specify a ",
875 : var_field_type_string,
876 : " variable when you meant to specify a ",
877 : expected_var_field_type_string,
878 : " variable?");
879 0 : }
880 : }
881 :
882 : void
883 307207 : SubProblem::reinitElemFaceRef(const Elem * elem,
884 : unsigned int side,
885 : Real tolerance,
886 : const std::vector<Point> * const pts,
887 : const std::vector<Real> * const weights,
888 : const THREAD_ID tid)
889 : {
890 614414 : for (const auto nl_sys_num : make_range(numNonlinearSystems()))
891 : {
892 : // - Set our _current_elem for proper dof index getting in the moose variables
893 : // - Reinitialize all of our FE objects so we have current phi, dphi, etc. data
894 : // Note that our number of shape functions will reflect the number of shapes associated with the
895 : // interior element while the number of quadrature points will be determined by the passed pts
896 : // parameter (which presumably will have a number of pts reflective of a facial quadrature rule)
897 307207 : assembly(tid, nl_sys_num).reinitElemFaceRef(elem, side, tolerance, pts, weights);
898 :
899 307207 : auto & nl = systemBaseNonlinear(nl_sys_num);
900 :
901 : // Actually get the dof indices in the moose variables
902 307207 : nl.prepare(tid);
903 :
904 : // Let's finally compute our variable values!
905 307207 : nl.reinitElemFace(elem, side, tid);
906 : }
907 :
908 : // do same for aux as for nl
909 307207 : systemBaseAuxiliary().prepare(tid);
910 307207 : systemBaseAuxiliary().reinitElemFace(elem, side, tid);
911 :
912 : // With the dof indices set in the moose variables, now let's properly size
913 : // our local residuals/Jacobians
914 307207 : auto & current_assembly = assembly(tid, currentNlSysNum());
915 307207 : if (currentlyComputingJacobian() || currentlyComputingResidualAndJacobian())
916 101316 : current_assembly.prepareJacobianBlock();
917 307207 : if (!currentlyComputingJacobian())
918 205891 : current_assembly.prepareResidual();
919 307207 : }
920 :
921 : void
922 307207 : SubProblem::reinitNeighborFaceRef(const Elem * neighbor_elem,
923 : unsigned int neighbor_side,
924 : Real tolerance,
925 : const std::vector<Point> * const pts,
926 : const std::vector<Real> * const weights,
927 : const THREAD_ID tid)
928 : {
929 614414 : for (const auto nl_sys_num : make_range(numNonlinearSystems()))
930 : {
931 : // - Set our _current_neighbor_elem for proper dof index getting in the moose variables
932 : // - Reinitialize all of our FE objects so we have current phi, dphi, etc. data
933 : // Note that our number of shape functions will reflect the number of shapes associated with the
934 : // interior element while the number of quadrature points will be determined by the passed pts
935 : // parameter (which presumably will have a number of pts reflective of a facial quadrature rule)
936 307207 : assembly(tid, nl_sys_num)
937 307207 : .reinitNeighborFaceRef(neighbor_elem, neighbor_side, tolerance, pts, weights);
938 :
939 307207 : auto & nl = systemBaseNonlinear(nl_sys_num);
940 :
941 : // Actually get the dof indices in the moose variables
942 307207 : nl.prepareNeighbor(tid);
943 :
944 : // Let's finally compute our variable values!
945 307207 : nl.reinitNeighborFace(neighbor_elem, neighbor_side, tid);
946 : }
947 :
948 : // do same for aux as for nl
949 307207 : systemBaseAuxiliary().prepareNeighbor(tid);
950 307207 : systemBaseAuxiliary().reinitNeighborFace(neighbor_elem, neighbor_side, tid);
951 :
952 : // With the dof indices set in the moose variables, now let's properly size
953 : // our local residuals/Jacobians
954 307207 : assembly(tid, currentNlSysNum()).prepareNeighbor();
955 307207 : }
956 :
957 : void
958 324608 : SubProblem::reinitLowerDElem(const Elem * elem,
959 : const THREAD_ID tid,
960 : const std::vector<Point> * const pts,
961 : const std::vector<Real> * const weights)
962 : {
963 649216 : for (const auto nl_sys_num : make_range(numNonlinearSystems()))
964 : {
965 : // - Set our _current_lower_d_elem for proper dof index getting in the moose variables
966 : // - Reinitialize all of our lower-d FE objects so we have current phi, dphi, etc. data
967 324608 : assembly(tid, nl_sys_num).reinitLowerDElem(elem, pts, weights);
968 :
969 324608 : auto & nl = systemBaseNonlinear(nl_sys_num);
970 :
971 : // Actually get the dof indices in the moose variables
972 324608 : nl.prepareLowerD(tid);
973 :
974 : // With the dof indices set in the moose variables, now let's properly size
975 : // our local residuals/Jacobians
976 324608 : assembly(tid, nl_sys_num).prepareLowerD();
977 :
978 : // Let's finally compute our variable values!
979 324608 : nl.reinitLowerD(tid);
980 : }
981 :
982 : // do same for aux as for nl
983 324608 : systemBaseAuxiliary().prepareLowerD(tid);
984 324608 : systemBaseAuxiliary().reinitLowerD(tid);
985 324608 : }
986 :
987 : void
988 284429 : SubProblem::reinitNeighborLowerDElem(const Elem * elem, const THREAD_ID tid)
989 : {
990 568858 : for (const auto nl_sys_num : make_range(numNonlinearSystems()))
991 284429 : assembly(tid, nl_sys_num).reinitNeighborLowerDElem(elem);
992 284429 : }
993 :
994 : void
995 568858 : SubProblem::reinitMortarElem(const Elem * elem, const THREAD_ID tid)
996 : {
997 1137716 : for (const auto nl_sys_num : make_range(numNonlinearSystems()))
998 568858 : assembly(tid, nl_sys_num).reinitMortarElem(elem);
999 568858 : }
1000 :
1001 : void
1002 34648 : SubProblem::cloneAlgebraicGhostingFunctor(GhostingFunctor & algebraic_gf, bool to_mesh)
1003 : {
1004 34648 : EquationSystems & eq = es();
1005 34648 : const auto n_sys = eq.n_systems();
1006 :
1007 34648 : auto pr = _root_alg_gf_to_sys_clones.emplace(
1008 34648 : &algebraic_gf, std::vector<std::shared_ptr<GhostingFunctor>>(n_sys - 1));
1009 : mooseAssert(pr.second, "We are adding a duplicate algebraic ghosting functor");
1010 34648 : auto & clones_vec = pr.first->second;
1011 :
1012 69536 : for (MooseIndex(n_sys) i = 1; i < n_sys; ++i)
1013 : {
1014 34888 : DofMap & dof_map = eq.get_system(i).get_dof_map();
1015 34888 : std::shared_ptr<GhostingFunctor> clone_alg_gf = algebraic_gf.clone();
1016 69776 : std::dynamic_pointer_cast<RelationshipManager>(clone_alg_gf)
1017 34888 : ->init(mesh(), *algebraic_gf.get_mesh(), &dof_map);
1018 34888 : dof_map.add_algebraic_ghosting_functor(clone_alg_gf, to_mesh);
1019 34888 : clones_vec[i - 1] = clone_alg_gf;
1020 34888 : }
1021 34648 : }
1022 :
1023 : void
1024 34648 : SubProblem::addAlgebraicGhostingFunctor(GhostingFunctor & algebraic_gf, bool to_mesh)
1025 : {
1026 34648 : EquationSystems & eq = es();
1027 34648 : const auto n_sys = eq.n_systems();
1028 34648 : if (!n_sys)
1029 0 : return;
1030 :
1031 34648 : eq.get_system(0).get_dof_map().add_algebraic_ghosting_functor(algebraic_gf, to_mesh);
1032 34648 : cloneAlgebraicGhostingFunctor(algebraic_gf, to_mesh);
1033 : }
1034 :
1035 : void
1036 47120 : SubProblem::cloneCouplingGhostingFunctor(GhostingFunctor & coupling_gf, bool to_mesh)
1037 : {
1038 47120 : const std::size_t num_nl_sys = numNonlinearSystems();
1039 :
1040 47120 : auto pr = _root_coupling_gf_to_sys_clones.emplace(
1041 47120 : &coupling_gf, std::vector<std::shared_ptr<GhostingFunctor>>(num_nl_sys - 1));
1042 : mooseAssert(pr.second, "We are adding a duplicate coupling functor");
1043 47120 : auto & clones_vec = pr.first->second;
1044 :
1045 47319 : for (const auto i : make_range(std::size_t(1), num_nl_sys))
1046 : {
1047 199 : DofMap & dof_map = systemBaseNonlinear(i).system().get_dof_map();
1048 199 : std::shared_ptr<GhostingFunctor> clone_coupling_gf = coupling_gf.clone();
1049 398 : std::dynamic_pointer_cast<RelationshipManager>(clone_coupling_gf)
1050 199 : ->init(mesh(), *coupling_gf.get_mesh(), &dof_map);
1051 199 : dof_map.add_coupling_functor(clone_coupling_gf, to_mesh);
1052 199 : clones_vec[i - 1] = clone_coupling_gf;
1053 199 : }
1054 47120 : }
1055 :
1056 : void
1057 48384 : SubProblem::addCouplingGhostingFunctor(GhostingFunctor & coupling_gf, bool to_mesh)
1058 : {
1059 48384 : const auto num_nl_sys = numNonlinearSystems();
1060 48384 : if (!num_nl_sys)
1061 1264 : return;
1062 :
1063 47120 : systemBaseNonlinear(0).system().get_dof_map().add_coupling_functor(coupling_gf, to_mesh);
1064 47120 : cloneCouplingGhostingFunctor(coupling_gf, to_mesh);
1065 : }
1066 :
1067 : void
1068 30 : SubProblem::removeAlgebraicGhostingFunctor(GhostingFunctor & algebraic_gf)
1069 : {
1070 30 : EquationSystems & eq = es();
1071 30 : const auto n_sys = eq.n_systems();
1072 30 : DofMap & nl_dof_map = eq.get_system(0).get_dof_map();
1073 :
1074 : const bool found_in_root_sys =
1075 30 : std::find(nl_dof_map.algebraic_ghosting_functors_begin(),
1076 : nl_dof_map.algebraic_ghosting_functors_end(),
1077 60 : &algebraic_gf) != nl_dof_map.algebraic_ghosting_functors_end();
1078 :
1079 : #ifndef NDEBUG
1080 : const bool found_in_our_map =
1081 : _root_alg_gf_to_sys_clones.find(&algebraic_gf) != _root_alg_gf_to_sys_clones.end();
1082 : mooseAssert(found_in_root_sys == found_in_our_map,
1083 : "If the ghosting functor exists in the root DofMap, then we need to have a key for "
1084 : "it in our gf to clones map");
1085 : #endif
1086 :
1087 30 : if (found_in_root_sys) // libMesh yells if we try to remove
1088 : // something that's not there
1089 0 : nl_dof_map.remove_algebraic_ghosting_functor(algebraic_gf);
1090 :
1091 30 : auto it = _root_alg_gf_to_sys_clones.find(&algebraic_gf);
1092 30 : if (it == _root_alg_gf_to_sys_clones.end())
1093 30 : return;
1094 :
1095 0 : auto & clones_vec = it->second;
1096 : mooseAssert((n_sys - 1) == clones_vec.size(),
1097 : "The size of the gf clones vector doesn't match the number of systems minus one");
1098 0 : if (clones_vec.empty())
1099 : {
1100 : mooseAssert(n_sys == 1, "The clones vector should only be empty if there is only one system");
1101 0 : return;
1102 : }
1103 :
1104 0 : for (const auto i : make_range(n_sys))
1105 0 : eq.get_system(i + 1).get_dof_map().remove_algebraic_ghosting_functor(*clones_vec[i]);
1106 :
1107 0 : _root_alg_gf_to_sys_clones.erase(it->first);
1108 : }
1109 :
1110 : void
1111 30 : SubProblem::removeCouplingGhostingFunctor(GhostingFunctor & coupling_gf)
1112 : {
1113 30 : EquationSystems & eq = es();
1114 30 : const auto num_nl_sys = numNonlinearSystems();
1115 30 : if (!num_nl_sys)
1116 30 : return;
1117 :
1118 30 : DofMap & nl_dof_map = eq.get_system(0).get_dof_map();
1119 30 : const bool found_in_root_sys = std::find(nl_dof_map.coupling_functors_begin(),
1120 : nl_dof_map.coupling_functors_end(),
1121 60 : &coupling_gf) != nl_dof_map.coupling_functors_end();
1122 :
1123 : #ifndef NDEBUG
1124 : const bool found_in_our_map =
1125 : _root_coupling_gf_to_sys_clones.find(&coupling_gf) != _root_coupling_gf_to_sys_clones.end();
1126 : mooseAssert(found_in_root_sys == found_in_our_map,
1127 : "If the ghosting functor exists in the root DofMap, then we need to have a key for "
1128 : "it in our gf to clones map");
1129 : #endif
1130 :
1131 30 : if (found_in_root_sys) // libMesh yells if we try to remove
1132 : // something that's not there
1133 30 : nl_dof_map.remove_coupling_functor(coupling_gf);
1134 :
1135 30 : auto it = _root_coupling_gf_to_sys_clones.find(&coupling_gf);
1136 30 : if (it == _root_coupling_gf_to_sys_clones.end())
1137 0 : return;
1138 :
1139 30 : auto & clones_vec = it->second;
1140 : mooseAssert((num_nl_sys - 1) == clones_vec.size(),
1141 : "The size of the gf clones vector doesn't match the number of systems minus one");
1142 30 : if (clones_vec.empty())
1143 : {
1144 : mooseAssert(num_nl_sys == 1,
1145 : "The clones vector should only be empty if there is only one nonlinear system");
1146 30 : return;
1147 : }
1148 :
1149 0 : for (const auto i : make_range(num_nl_sys))
1150 0 : eq.get_system(i + 1).get_dof_map().remove_coupling_functor(*clones_vec[i]);
1151 :
1152 0 : _root_coupling_gf_to_sys_clones.erase(it->first);
1153 : }
1154 :
1155 : void
1156 68438 : SubProblem::automaticScaling(bool automatic_scaling)
1157 : {
1158 135835 : for (const auto nl_sys_num : make_range(numNonlinearSystems()))
1159 67397 : systemBaseNonlinear(nl_sys_num).automaticScaling(automatic_scaling);
1160 68438 : }
1161 :
1162 : bool
1163 15184 : SubProblem::automaticScaling() const
1164 : {
1165 : // Currently going to assume that we are applying or not applying automatic scaling consistently
1166 : // across nonlinear systems
1167 15184 : return systemBaseNonlinear(0).automaticScaling();
1168 : }
1169 :
1170 : void
1171 363 : SubProblem::hasScalingVector(const unsigned int nl_sys_num)
1172 : {
1173 786 : for (const THREAD_ID tid : make_range(libMesh::n_threads()))
1174 423 : assembly(tid, nl_sys_num).hasScalingVector();
1175 363 : }
1176 :
1177 : void
1178 384581 : SubProblem::clearAllDofIndices()
1179 : {
1180 782066 : for (const auto nl_sys_num : make_range(numNonlinearSystems()))
1181 397485 : systemBaseNonlinear(nl_sys_num).clearAllDofIndices();
1182 384581 : systemBaseAuxiliary().clearAllDofIndices();
1183 384581 : }
1184 :
1185 : void
1186 323803 : SubProblem::timestepSetup()
1187 : {
1188 676262 : for (auto & map : _pbblf_functors)
1189 364164 : for (auto & pr : map)
1190 11705 : pr.second->timestepSetup();
1191 323803 : if (_show_chain_control_data)
1192 36 : _console << _app.getChainControlDataSystem().outputChainControlMap() << std::flush;
1193 323803 : }
1194 :
1195 : void
1196 2083667 : SubProblem::customSetup(const ExecFlagType & exec_type)
1197 : {
1198 4353407 : for (auto & map : _pbblf_functors)
1199 2352069 : for (auto & pr : map)
1200 82329 : pr.second->customSetup(exec_type);
1201 2083667 : }
1202 :
1203 : void
1204 3487928 : SubProblem::residualSetup()
1205 : {
1206 7289027 : for (auto & map : _pbblf_functors)
1207 3900244 : for (auto & pr : map)
1208 99145 : pr.second->residualSetup();
1209 3487928 : }
1210 :
1211 : void
1212 552481 : SubProblem::jacobianSetup()
1213 : {
1214 1155966 : for (auto & map : _pbblf_functors)
1215 621094 : for (auto & pr : map)
1216 17609 : pr.second->jacobianSetup();
1217 552481 : }
1218 :
1219 : void
1220 64426 : SubProblem::initialSetup()
1221 : {
1222 64426 : if (_show_functors)
1223 : {
1224 36 : showFunctors();
1225 36 : showFunctorRequestors();
1226 : }
1227 64426 : if (_show_chain_control_data)
1228 13 : _console << _app.getChainControlDataSystem().outputChainControlMap() << std::flush;
1229 :
1230 134822 : for (const auto & functors : _functors)
1231 388060 : for (const auto & [functor_wrapper_name, functor_wrapper] : functors)
1232 : {
1233 317664 : const auto & [true_functor_type, non_ad_functor, ad_functor] = functor_wrapper;
1234 : mooseAssert(non_ad_functor->wrapsNull() == ad_functor->wrapsNull(), "These must agree");
1235 317664 : const auto functor_name = removeSubstring(functor_wrapper_name, "wraps_");
1236 317664 : if (non_ad_functor->wrapsNull())
1237 0 : mooseError(
1238 : "No functor ever provided with name '",
1239 : functor_name,
1240 : "', which was requested by '",
1241 0 : MooseUtils::join(libmesh_map_find(_functor_to_requestors, functor_wrapper_name), ","),
1242 : "'.");
1243 508463 : if (true_functor_type == TrueFunctorIs::NONAD ? non_ad_functor->ownsWrappedFunctor()
1244 190799 : : ad_functor->ownsWrappedFunctor())
1245 0 : mooseError("Functor envelopes should not own the functors they wrap, but '",
1246 : functor_name,
1247 : "' is owned by the wrapper. Please open a MOOSE issue for help resolving this.");
1248 317664 : }
1249 64426 : }
1250 :
1251 : void
1252 36 : SubProblem::showFunctors() const
1253 : {
1254 36 : _console << "[DBG] Wrapped functors found in Subproblem" << std::endl;
1255 36 : std::string functor_names = "[DBG] ";
1256 284 : for (const auto & functor_pair : _functors[0])
1257 248 : functor_names += std::regex_replace(functor_pair.first, std::regex("wraps_"), "") + " ";
1258 36 : if (functor_names.size())
1259 36 : functor_names.pop_back();
1260 36 : _console << functor_names << std::endl;
1261 36 : }
1262 :
1263 : void
1264 36 : SubProblem::showFunctorRequestors() const
1265 : {
1266 128 : for (const auto & [functor, requestors] : _functor_to_requestors)
1267 : {
1268 92 : _console << "[DBG] Requestors for wrapped functor "
1269 92 : << std::regex_replace(functor, std::regex("wraps_"), "") << std::endl;
1270 276 : _console << "[DBG] " << MooseUtils::join(requestors, " ") << std::endl;
1271 : }
1272 36 : }
1273 :
1274 : bool
1275 550 : SubProblem::hasFunctor(const std::string & name, const THREAD_ID tid) const
1276 : {
1277 : mooseAssert(tid < _functors.size(), "Too large a thread ID");
1278 550 : auto & functors = _functors[tid];
1279 550 : return (functors.find("wraps_" + name) != functors.end());
1280 : }
1281 :
1282 : Moose::CoordinateSystemType
1283 478657854 : SubProblem::getCoordSystem(SubdomainID sid) const
1284 : {
1285 478657854 : return mesh().getCoordSystem(sid);
1286 : }
1287 :
1288 : void
1289 25457406 : SubProblem::reinitFVFace(const THREAD_ID tid, const FaceInfo & fi)
1290 : {
1291 52006746 : for (const auto nl : make_range(numNonlinearSystems()))
1292 26549340 : assembly(tid, nl).reinitFVFace(fi);
1293 25457406 : }
1294 :
1295 : void
1296 376637267 : SubProblem::cacheResidual(const THREAD_ID tid)
1297 : {
1298 376637267 : assembly(tid, currentNlSysNum())
1299 376637267 : .cacheResidual(Assembly::GlobalDataKey{}, currentResidualVectorTags());
1300 376637267 : }
1301 :
1302 : void
1303 38457458 : SubProblem::cacheResidualNeighbor(const THREAD_ID tid)
1304 : {
1305 38457458 : assembly(tid, currentNlSysNum())
1306 38457458 : .cacheResidualNeighbor(Assembly::GlobalDataKey{}, currentResidualVectorTags());
1307 38457458 : }
1308 :
1309 : void
1310 57872050 : SubProblem::addCachedResidual(const THREAD_ID tid)
1311 : {
1312 57872050 : assembly(tid, currentNlSysNum())
1313 57872050 : .addCachedResiduals(Assembly::GlobalDataKey{}, currentResidualVectorTags());
1314 57872050 : }
1315 :
1316 : void
1317 57305117 : SubProblem::cacheJacobian(const THREAD_ID tid)
1318 : {
1319 57305117 : assembly(tid, currentNlSysNum()).cacheJacobian(Assembly::GlobalDataKey{});
1320 57305117 : if (hasNonlocalCoupling())
1321 5880 : assembly(tid, currentNlSysNum()).cacheJacobianNonlocal(Assembly::GlobalDataKey{});
1322 57305117 : }
1323 :
1324 : void
1325 10576 : SubProblem::cacheJacobianNeighbor(const THREAD_ID tid)
1326 : {
1327 10576 : assembly(tid, currentNlSysNum()).cacheJacobianNeighbor(Assembly::GlobalDataKey{});
1328 10576 : }
1329 :
1330 : void
1331 4247452 : SubProblem::addCachedJacobian(const THREAD_ID tid)
1332 : {
1333 4247452 : assembly(tid, currentNlSysNum()).addCachedJacobian(Assembly::GlobalDataKey{});
1334 4247448 : }
1335 :
1336 : void
1337 234 : SubProblem::preparePRefinement()
1338 : {
1339 234 : std::unordered_set<FEFamily> disable_families;
1340 663 : for (const auto & [family, flag] : _family_for_p_refinement)
1341 429 : if (flag)
1342 195 : disable_families.insert(family);
1343 :
1344 486 : for (const auto tid : make_range(libMesh::n_threads()))
1345 504 : for (const auto s : make_range(numNonlinearSystems()))
1346 252 : assembly(tid, s).havePRefinement(disable_families);
1347 :
1348 234 : auto & eq = es();
1349 429 : for (const auto family : disable_families)
1350 585 : for (const auto i : make_range(eq.n_systems()))
1351 : {
1352 390 : auto & system = eq.get_system(i);
1353 390 : auto & dof_map = system.get_dof_map();
1354 936 : for (const auto vg : make_range(system.n_variable_groups()))
1355 : {
1356 546 : const auto & var_group = system.variable_group(vg);
1357 546 : if (var_group.type().family == family)
1358 195 : dof_map.should_p_refine(vg, false);
1359 : }
1360 : }
1361 :
1362 234 : _have_p_refinement = true;
1363 234 : }
1364 :
1365 : bool
1366 464 : SubProblem::doingPRefinement() const
1367 : {
1368 464 : return mesh().doingPRefinement();
1369 : }
1370 :
1371 : void
1372 161769 : SubProblem::markFamilyPRefinement(const InputParameters & params)
1373 : {
1374 161769 : auto family = Utility::string_to_enum<FEFamily>(params.get<MooseEnum>("family"));
1375 161769 : bool flag = _default_families_without_p_refinement.count(family);
1376 323538 : if (params.isParamValid("disable_p_refinement"))
1377 143 : flag = params.get<bool>("disable_p_refinement");
1378 :
1379 161769 : auto [it, inserted] = _family_for_p_refinement.emplace(family, flag);
1380 161769 : if (!inserted && flag != it->second)
1381 0 : mooseError("'disable_p_refinement' not set consistently for variables in ", family);
1382 161769 : }
1383 :
1384 : void
1385 157505 : SubProblem::setCurrentLowerDElem(const Elem * const lower_d_elem, const THREAD_ID tid)
1386 : {
1387 315010 : for (const auto nl_sys_num : make_range(numNonlinearSystems()))
1388 157505 : assembly(tid, nl_sys_num).setCurrentLowerDElem(lower_d_elem);
1389 157505 : }
1390 :
1391 : template MooseVariableFEBase &
1392 : SubProblem::getVariableHelper(const THREAD_ID tid,
1393 : const std::string & var_name,
1394 : Moose::VarKindType expected_var_type,
1395 : Moose::VarFieldType expected_var_field_type,
1396 : const std::vector<std::shared_ptr<SolverSystem>> & nls,
1397 : const SystemBase & aux) const;
1398 : template MooseVariableFEBase &
1399 : SubProblem::getVariableHelper(const THREAD_ID tid,
1400 : const std::string & var_name,
1401 : Moose::VarKindType expected_var_type,
1402 : Moose::VarFieldType expected_var_field_type,
1403 : const std::vector<std::unique_ptr<DisplacedSystem>> & nls,
1404 : const SystemBase & aux) const;
|