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 : #pragma once
11 :
12 : // MOOSE includes
13 : #include "DependencyResolverInterface.h"
14 : #include "BoundaryRestrictable.h"
15 : #include "BlockRestrictable.h"
16 : #include "TransientInterface.h"
17 : #include "Coupleable.h"
18 : #include "MaterialPropertyInterface.h"
19 : #include "MooseVariableDependencyInterface.h"
20 : #include "SubProblem.h"
21 : #include "MooseApp.h"
22 :
23 : // Forward declarations
24 : class MooseVariableFieldBase;
25 :
26 : /**
27 : * A base storage container for MooseObjects.
28 : */
29 : template <typename T>
30 : class MooseObjectWarehouseBase
31 : {
32 : public:
33 : /**
34 : * Constructor.
35 : * @param threaded When true (default) threaded storage is enabled.
36 : */
37 : MooseObjectWarehouseBase(bool threaded = true);
38 :
39 : /**
40 : * Destructor.
41 : */
42 : virtual ~MooseObjectWarehouseBase();
43 :
44 : /**
45 : * Adds an object to the storage structure.
46 : * @param tid The thread ID (default is 0)
47 : * @param recurse Whether or not to build recusive warehouses (typically for Kernels)
48 : */
49 : virtual void addObject(std::shared_ptr<T> object, THREAD_ID tid = 0, bool recurse = true);
50 :
51 : /**
52 : * Return how many kernels we store in the current warehouse
53 : */
54 : unsigned int size(THREAD_ID tid = 0) const;
55 :
56 : ///@{
57 : /**
58 : * Retrieve complete vector to the all/block/boundary restricted objects for a given thread.
59 : * @param tid The thread id to retrieve objects from
60 : */
61 : const std::vector<std::shared_ptr<T>> & getObjects(THREAD_ID tid = 0) const;
62 : const std::map<SubdomainID, std::vector<std::shared_ptr<T>>> &
63 : getBlockObjects(THREAD_ID tid = 0) const;
64 : const std::vector<std::shared_ptr<T>> & getBlockObjects(SubdomainID id, THREAD_ID tid = 0) const;
65 : const std::map<BoundaryID, std::vector<std::shared_ptr<T>>> &
66 : getBoundaryObjects(THREAD_ID tid = 0) const;
67 : const std::vector<std::shared_ptr<T>> & getBoundaryObjects(BoundaryID id,
68 : THREAD_ID tid = 0) const;
69 : ///@}
70 :
71 : ///@{
72 : /**
73 : * Retrieve complete vector to the active all/block/boundary restricted objects for a given
74 : * thread.
75 : * @param tid The thread id to retrieve objects from
76 : */
77 : const std::vector<std::shared_ptr<T>> & getActiveObjects(THREAD_ID tid = 0) const;
78 : const std::map<SubdomainID, std::vector<std::shared_ptr<T>>> &
79 : getActiveBlockObjects(THREAD_ID tid = 0) const;
80 : const std::vector<std::shared_ptr<T>> & getActiveBlockObjects(SubdomainID id,
81 : THREAD_ID tid = 0) const;
82 : const std::map<BoundaryID, std::vector<std::shared_ptr<T>>> &
83 : getActiveBoundaryObjects(THREAD_ID tid = 0) const;
84 : const std::vector<std::shared_ptr<T>> & getActiveBoundaryObjects(BoundaryID id,
85 : THREAD_ID tid = 0) const;
86 : ///@}
87 :
88 : ///@{
89 : /**
90 : * Convenience functions for determining if objects exist.
91 : */
92 : bool hasObjects(THREAD_ID tid = 0) const;
93 : bool hasActiveObjects(THREAD_ID tid = 0) const;
94 : bool hasObjectsForVariable(const VariableName & var_name, THREAD_ID tid) const;
95 : bool hasActiveBlockObjects(THREAD_ID tid = 0) const;
96 : bool hasActiveBlockObjects(SubdomainID id, THREAD_ID tid = 0) const;
97 : bool hasActiveBoundaryObjects(THREAD_ID tid = 0) const;
98 : bool hasActiveBoundaryObjects(BoundaryID id, THREAD_ID tid = 0) const;
99 : bool hasBoundaryObjects(BoundaryID id, THREAD_ID tid = 0) const;
100 : ///@}
101 :
102 : /**
103 : * Whether there are objects for this variable and the set of blocks passed
104 : * @param var_name name of the variable
105 : * @param blocks blocks to consider
106 : * @param blocks_covered subset of blocks for which there is an object
107 : */
108 : bool hasObjectsForVariableAndBlocks(const VariableName & var_name,
109 : const std::set<SubdomainID> & blocks,
110 : std::set<SubdomainID> & blocks_covered,
111 : THREAD_ID tid) const;
112 :
113 : /**
114 : * Return a set of active SubdomainsIDs
115 : */
116 : std::set<SubdomainID> getActiveBlocks(THREAD_ID tid = 0) const;
117 :
118 : ///@{
119 : /**
120 : * Convenience functions for checking/getting specific objects
121 : */
122 : bool hasActiveObject(const std::string & name, THREAD_ID tid = 0) const;
123 : std::shared_ptr<T> getObject(const std::string & name, THREAD_ID tid = 0) const;
124 : std::shared_ptr<T> getActiveObject(const std::string & name, THREAD_ID tid = 0) const;
125 : ///@}
126 :
127 : /// Getter for objects that have the 'variable' set to a particular variable
128 : /// Note that users should check whether there are objects using 'hasObjectsForVariable' before
129 : /// calling this routine, because it will throw if there are no objects for this variable
130 : const std::vector<std::shared_ptr<T>> & getObjectsForVariable(const VariableName & var_name,
131 : THREAD_ID tid) const;
132 :
133 : /**
134 : * Updates the active objects storage.
135 : */
136 : virtual void updateActive(THREAD_ID tid = 0);
137 :
138 : /**
139 : * Sort the objects using the DependencyResolver.
140 : */
141 : void sort(THREAD_ID tid = 0);
142 :
143 : ///@{
144 : /**
145 : * Update variable dependency vector.
146 : */
147 : void updateVariableDependency(std::set<MooseVariableFieldBase *> & needed_moose_vars,
148 : THREAD_ID tid = 0) const;
149 : void updateBlockVariableDependency(SubdomainID id,
150 : std::set<MooseVariableFieldBase *> & needed_moose_vars,
151 : THREAD_ID tid = 0) const;
152 : void updateBoundaryVariableDependency(std::set<MooseVariableFieldBase *> & needed_moose_vars,
153 : THREAD_ID tid = 0) const;
154 : void updateBoundaryVariableDependency(BoundaryID id,
155 : std::set<MooseVariableFieldBase *> & needed_moose_vars,
156 : THREAD_ID tid = 0) const;
157 : ///@}
158 :
159 : ///@{
160 : /**
161 : * Update FE variable coupleable vector tag vector
162 : */
163 : void updateBlockFEVariableCoupledVectorTagDependency(SubdomainID id,
164 : std::set<TagID> & needed_fe_var_vector_tags,
165 : THREAD_ID tid = 0) const;
166 : void updateBoundaryFEVariableCoupledVectorTagDependency(
167 : BoundaryID id, std::set<TagID> & needed_fe_var_vector_tags, THREAD_ID tid = 0) const;
168 : ///@}
169 :
170 : ///@{
171 : /**
172 : * Update material property dependency vector.
173 : */
174 : void updateMatPropDependency(std::unordered_set<unsigned int> & needed_mat_props,
175 : THREAD_ID tid = 0) const;
176 : void updateBlockMatPropDependency(SubdomainID id,
177 : std::unordered_set<unsigned int> & needed_mat_props,
178 : THREAD_ID tid = 0) const;
179 : void updateBoundaryMatPropDependency(std::unordered_set<unsigned int> & needed_mat_props,
180 : THREAD_ID tid = 0) const;
181 : void updateBoundaryMatPropDependency(BoundaryID id,
182 : std::unordered_set<unsigned int> & needed_mat_props,
183 : THREAD_ID tid = 0) const;
184 : ///@}
185 :
186 : /**
187 : * Populates a set of covered subdomains and the associated variable names.
188 : */
189 : void subdomainsCovered(std::set<SubdomainID> & subdomains_covered,
190 : std::set<std::string> & unique_variables,
191 : THREAD_ID tid = 0) const;
192 :
193 : /**
194 : * Return the number of threads.
195 : */
196 : THREAD_ID numThreads() const { return _num_threads; }
197 :
198 : /**
199 : * Output the active content of the warehouse to a string, meant to be output to the console
200 : * @param tid the thread id
201 : * @param prefix a string to prepend to the string
202 : */
203 : std::string activeObjectsToFormattedString(THREAD_ID tid = 0,
204 : const std::string & prefix = "[DBG]") const;
205 :
206 : protected:
207 : /// Convenience member storing the number of threads used for storage (1 or libMesh::n_threads)
208 : const THREAD_ID _num_threads;
209 :
210 : /// Storage container for the ALL pointers (THREAD_ID on outer vector)
211 : std::vector<std::vector<std::shared_ptr<T>>> _all_objects;
212 :
213 : /// All active objects (THREAD_ID on outer vector)
214 : std::vector<std::vector<std::shared_ptr<T>>> _active_objects;
215 :
216 : // All block restricted objects (THREAD_ID on outer vector)
217 : std::vector<std::map<SubdomainID, std::vector<std::shared_ptr<T>>>> _all_block_objects;
218 :
219 : /// Active block restricted objects (THREAD_ID on outer vector)
220 : std::vector<std::map<SubdomainID, std::vector<std::shared_ptr<T>>>> _active_block_objects;
221 :
222 : // All boundary restricted objects (THREAD_ID on outer vector)
223 : std::vector<std::map<BoundaryID, std::vector<std::shared_ptr<T>>>> _all_boundary_objects;
224 :
225 : /// Active boundary restricted objects (THREAD_ID on outer vector)
226 : std::vector<std::map<BoundaryID, std::vector<std::shared_ptr<T>>>> _active_boundary_objects;
227 :
228 : /// All objects with a certain variable selected, as the 'variable' parameter
229 : std::vector<std::map<VariableName, std::vector<std::shared_ptr<T>>>> _all_variable_objects;
230 :
231 : /**
232 : * Helper method for updating active vectors
233 : */
234 : static void updateActiveHelper(std::vector<std::shared_ptr<T>> & active,
235 : const std::vector<std::shared_ptr<T>> & all);
236 :
237 : /**
238 : * Helper method for sorting vectors of objects.
239 : */
240 : static void sortHelper(std::vector<std::shared_ptr<T>> & objects);
241 :
242 : /**
243 : * Helper method for updating variable dependency vector
244 : */
245 : static void updateVariableDependencyHelper(std::set<MooseVariableFieldBase *> & needed_moose_vars,
246 : const std::vector<std::shared_ptr<T>> & objects);
247 :
248 : /**
249 : * Helper method for updating FE variable coupleable vector tag vector
250 : */
251 : static void
252 : updateFEVariableCoupledVectorTagDependencyHelper(std::set<TagID> & needed_fe_var_vector_tags,
253 : const std::vector<std::shared_ptr<T>> & objects);
254 :
255 : /**
256 : * Helper method for updating material property dependency vector
257 : */
258 : static void updateMatPropDependencyHelper(std::unordered_set<unsigned int> & needed_mat_props,
259 : const std::vector<std::shared_ptr<T>> & objects);
260 :
261 : /**
262 : * Calls assert on thread id.
263 : */
264 : void checkThreadID(THREAD_ID tid) const;
265 :
266 : friend class MaterialWarehouse;
267 : };
268 :
269 : template <typename T>
270 27743924 : MooseObjectWarehouseBase<T>::MooseObjectWarehouseBase(bool threaded /*=true*/)
271 27743924 : : _num_threads(threaded ? libMesh::n_threads() : 1),
272 27743924 : _all_objects(_num_threads),
273 27743924 : _active_objects(_num_threads),
274 27743924 : _all_block_objects(_num_threads),
275 27743924 : _active_block_objects(_num_threads),
276 27743924 : _all_boundary_objects(_num_threads),
277 27743924 : _active_boundary_objects(_num_threads),
278 55487848 : _all_variable_objects(_num_threads)
279 : {
280 27743924 : }
281 :
282 : template <typename T>
283 73971290 : MooseObjectWarehouseBase<T>::~MooseObjectWarehouseBase()
284 : {
285 73971290 : }
286 :
287 : template <typename T>
288 : unsigned int
289 21083053 : MooseObjectWarehouseBase<T>::size(THREAD_ID tid /* =0 */) const
290 : {
291 21083053 : checkThreadID(tid);
292 21083053 : return _all_objects[tid].size();
293 : }
294 :
295 : template <typename T>
296 : void
297 1435298 : MooseObjectWarehouseBase<T>::addObject(std::shared_ptr<T> object,
298 : THREAD_ID tid /*= 0*/,
299 : bool /* recurse = true */)
300 : {
301 1435298 : checkThreadID(tid);
302 :
303 : // Stores object in list of all objects
304 1435298 : _all_objects[tid].push_back(object);
305 :
306 : // If enabled, store object in a list of all active
307 1435298 : bool enabled = object->enabled();
308 1435298 : if (enabled)
309 1434632 : _active_objects[tid].push_back(object);
310 :
311 : // Perform casts to the Block/BoundaryRestrictable
312 1435298 : std::shared_ptr<BoundaryRestrictable> bnd =
313 : std::dynamic_pointer_cast<BoundaryRestrictable>(object);
314 1435298 : std::shared_ptr<BlockRestrictable> blk = std::dynamic_pointer_cast<BlockRestrictable>(object);
315 :
316 : // Boundary Restricted
317 1435298 : if (bnd && bnd->boundaryRestricted())
318 : {
319 387807 : const std::set<BoundaryID> & ids = bnd->boundaryIDs();
320 865270 : for (std::set<BoundaryID>::const_iterator it = ids.begin(); it != ids.end(); ++it)
321 : {
322 477463 : _all_boundary_objects[tid][*it].push_back(object);
323 477463 : if (enabled)
324 477443 : _active_boundary_objects[tid][*it].push_back(object);
325 : }
326 : }
327 :
328 : // Block Restricted
329 1047491 : else if (blk)
330 : {
331 738395 : const std::set<SubdomainID> & ids =
332 738395 : blk->blockRestricted() ? blk->blockIDs() : blk->meshBlockIDs();
333 1582579 : for (std::set<SubdomainID>::const_iterator it = ids.begin(); it != ids.end(); ++it)
334 : {
335 844184 : _all_block_objects[tid][*it].push_back(object);
336 844184 : if (enabled)
337 843692 : _active_block_objects[tid][*it].push_back(object);
338 : }
339 :
340 : // Check variables
341 738395 : std::shared_ptr<Coupleable> c_ptr = std::dynamic_pointer_cast<Coupleable>(object);
342 738395 : if (c_ptr)
343 966379 : for (MooseVariableFieldBase * var : c_ptr->getCoupledMooseVars())
344 233502 : blk->checkVariable(*var);
345 :
346 738375 : const InputParameters & parameters = object->parameters();
347 :
348 738375 : SubProblem & problem = *parameters.get<SubProblem *>("_subproblem");
349 :
350 738375 : THREAD_ID tid = parameters.get<THREAD_ID>("_tid");
351 :
352 738375 : if (parameters.isParamValid("variable"))
353 : {
354 : // Try the scalar version first
355 654526 : std::string variable_name = parameters.getMooseType("variable");
356 654526 : if (variable_name == "")
357 : // When using vector variables, we are only going to use the first one in the list at the
358 : // interface level...
359 120613 : variable_name = parameters.getVecMooseType("variable")[0];
360 :
361 654526 : blk->checkVariable(problem.getVariable(
362 : tid, variable_name, Moose::VarKindType::VAR_ANY, Moose::VarFieldType::VAR_FIELD_ANY));
363 :
364 654514 : _all_variable_objects[tid][variable_name].push_back(object);
365 654514 : }
366 738363 : }
367 1435266 : }
368 :
369 : template <typename T>
370 : inline const std::vector<std::shared_ptr<T>> &
371 15951241 : MooseObjectWarehouseBase<T>::getObjects(THREAD_ID tid /* = 0*/) const
372 : {
373 15951241 : checkThreadID(tid);
374 15951241 : return _all_objects[tid];
375 : }
376 :
377 : template <typename T>
378 : inline const std::map<BoundaryID, std::vector<std::shared_ptr<T>>> &
379 226 : MooseObjectWarehouseBase<T>::getBoundaryObjects(THREAD_ID tid /* = 0*/) const
380 : {
381 226 : checkThreadID(tid);
382 226 : return _all_boundary_objects[tid];
383 : }
384 :
385 : template <typename T>
386 : bool
387 18734814 : MooseObjectWarehouseBase<T>::hasBoundaryObjects(BoundaryID id, THREAD_ID tid /* = 0*/) const
388 : {
389 18734814 : checkThreadID(tid);
390 18734814 : return _all_boundary_objects[tid].find(id) != _all_boundary_objects[tid].end();
391 : }
392 :
393 : template <typename T>
394 : const std::vector<std::shared_ptr<T>> &
395 977411 : MooseObjectWarehouseBase<T>::getBoundaryObjects(BoundaryID id, THREAD_ID tid /* = 0*/) const
396 : {
397 977411 : checkThreadID(tid);
398 977411 : const auto iter = _all_boundary_objects[tid].find(id);
399 : mooseAssert(iter != _all_boundary_objects[tid].end(),
400 : "Unable to located active boundary objects for the given id: " << id << ".");
401 977411 : return iter->second;
402 : }
403 :
404 : template <typename T>
405 : inline const std::map<SubdomainID, std::vector<std::shared_ptr<T>>> &
406 678 : MooseObjectWarehouseBase<T>::getBlockObjects(THREAD_ID tid /* = 0*/) const
407 : {
408 678 : checkThreadID(tid);
409 678 : return _all_block_objects[tid];
410 : }
411 :
412 : template <typename T>
413 : const std::vector<std::shared_ptr<T>> &
414 40 : MooseObjectWarehouseBase<T>::getBlockObjects(SubdomainID id, THREAD_ID tid /* = 0*/) const
415 : {
416 40 : checkThreadID(tid);
417 40 : const auto iter = _all_block_objects[tid].find(id);
418 : mooseAssert(iter != _all_block_objects[tid].end(),
419 : "Unable to located active block objects for the given id: " << id << ".");
420 40 : return iter->second;
421 : }
422 :
423 : template <typename T>
424 : inline const std::vector<std::shared_ptr<T>> &
425 33469367 : MooseObjectWarehouseBase<T>::getActiveObjects(THREAD_ID tid /* = 0*/) const
426 : {
427 33469367 : checkThreadID(tid);
428 33469367 : return _active_objects[tid];
429 : }
430 :
431 : template <typename T>
432 : inline const std::map<BoundaryID, std::vector<std::shared_ptr<T>>> &
433 4592494 : MooseObjectWarehouseBase<T>::getActiveBoundaryObjects(THREAD_ID tid /* = 0*/) const
434 : {
435 4592494 : checkThreadID(tid);
436 4592494 : return _active_boundary_objects[tid];
437 : }
438 :
439 : template <typename T>
440 : const std::vector<std::shared_ptr<T>> &
441 66566976 : MooseObjectWarehouseBase<T>::getActiveBoundaryObjects(BoundaryID id, THREAD_ID tid /* = 0*/) const
442 : {
443 66566976 : checkThreadID(tid);
444 66566976 : const auto iter = _active_boundary_objects[tid].find(id);
445 : mooseAssert(iter != _active_boundary_objects[tid].end(),
446 : "Unable to located active boundary objects for the given id: " << id << ".");
447 66566976 : return iter->second;
448 : }
449 :
450 : template <typename T>
451 : inline const std::map<SubdomainID, std::vector<std::shared_ptr<T>>> &
452 22853061 : MooseObjectWarehouseBase<T>::getActiveBlockObjects(THREAD_ID tid /* = 0*/) const
453 : {
454 22853061 : checkThreadID(tid);
455 22853061 : return _active_block_objects[tid];
456 : }
457 :
458 : template <typename T>
459 : const std::vector<std::shared_ptr<T>> &
460 409651289 : MooseObjectWarehouseBase<T>::getActiveBlockObjects(SubdomainID id, THREAD_ID tid /* = 0*/) const
461 : {
462 409651289 : checkThreadID(tid);
463 409651289 : const auto iter = _active_block_objects[tid].find(id);
464 : mooseAssert(iter != _active_block_objects[tid].end(),
465 : "Unable to located active block objects for the given id: " << id << ".");
466 409651289 : return iter->second;
467 : }
468 :
469 : template <typename T>
470 : bool
471 55526 : MooseObjectWarehouseBase<T>::hasObjects(THREAD_ID tid /* = 0*/) const
472 : {
473 55526 : checkThreadID(tid);
474 55526 : return !_all_objects[tid].empty();
475 : }
476 :
477 : template <typename T>
478 : bool
479 47448138 : MooseObjectWarehouseBase<T>::hasActiveObjects(THREAD_ID tid /* = 0*/) const
480 : {
481 47448138 : checkThreadID(tid);
482 47448138 : return !_active_objects[tid].empty();
483 : }
484 :
485 : template <typename T>
486 : bool
487 4 : MooseObjectWarehouseBase<T>::hasObjectsForVariable(const VariableName & var_name,
488 : THREAD_ID tid) const
489 : {
490 4 : checkThreadID(tid);
491 4 : return _all_variable_objects[tid].count(var_name);
492 : }
493 :
494 : template <typename T>
495 : bool
496 4 : MooseObjectWarehouseBase<T>::hasObjectsForVariableAndBlocks(const VariableName & var_name,
497 : const std::set<SubdomainID> & blocks,
498 : std::set<SubdomainID> & blocks_covered,
499 : THREAD_ID tid /* = 0*/) const
500 : {
501 4 : checkThreadID(tid);
502 4 : blocks_covered.clear();
503 4 : if (!hasObjectsForVariable(var_name, tid))
504 0 : return false;
505 :
506 : // Check block restriction as a whole
507 8 : for (const auto & object : libmesh_map_find(_all_variable_objects[tid], var_name))
508 : {
509 4 : std::shared_ptr<BlockRestrictable> blk = std::dynamic_pointer_cast<BlockRestrictable>(object);
510 4 : if (blk && blk->hasBlocks(blocks))
511 : {
512 4 : blocks_covered = blocks;
513 4 : return true;
514 : }
515 : }
516 : // No object has all the blocks, but one might overlap, which could be troublesome.
517 : // We'll keep track of which blocks are covered in case several overlap
518 0 : for (const auto & object : libmesh_map_find(_all_variable_objects[tid], var_name))
519 : {
520 0 : std::shared_ptr<BlockRestrictable> blk = std::dynamic_pointer_cast<BlockRestrictable>(object);
521 0 : if (blk)
522 0 : for (const auto & block : blocks)
523 0 : if (blk->hasBlocks(block))
524 0 : blocks_covered.insert(block);
525 : }
526 : // No overlap at all
527 0 : if (blocks_covered.empty())
528 0 : return false;
529 :
530 0 : return (blocks == blocks_covered);
531 : }
532 :
533 : template <typename T>
534 : bool
535 15450108 : MooseObjectWarehouseBase<T>::hasActiveBlockObjects(THREAD_ID tid /* = 0*/) const
536 : {
537 15450108 : checkThreadID(tid);
538 15450108 : bool has_active_block_objects = false;
539 15703298 : for (const auto & object_pair : _active_block_objects[tid])
540 253190 : has_active_block_objects |= !(object_pair.second.empty());
541 15450108 : return has_active_block_objects;
542 : }
543 :
544 : template <typename T>
545 : bool
546 2473224909 : MooseObjectWarehouseBase<T>::hasActiveBlockObjects(SubdomainID id, THREAD_ID tid /* = 0*/) const
547 : {
548 2473224909 : checkThreadID(tid);
549 2473224909 : const auto iter = _active_block_objects[tid].find(id);
550 2473224909 : return iter != _active_block_objects[tid].end();
551 : }
552 :
553 : template <typename T>
554 : bool
555 35374462 : MooseObjectWarehouseBase<T>::hasActiveBoundaryObjects(THREAD_ID tid /* = 0*/) const
556 : {
557 35374462 : checkThreadID(tid);
558 35374462 : bool has_active_boundary_objects = false;
559 37997038 : for (const auto & object_pair : _active_boundary_objects[tid])
560 2622576 : has_active_boundary_objects |= !(object_pair.second.empty());
561 35374462 : return has_active_boundary_objects;
562 : }
563 :
564 : template <typename T>
565 : bool
566 289749540 : MooseObjectWarehouseBase<T>::hasActiveBoundaryObjects(BoundaryID id, THREAD_ID tid /* = 0*/) const
567 : {
568 289749540 : checkThreadID(tid);
569 289749540 : const auto iter = _active_boundary_objects[tid].find(id);
570 289749540 : return iter != _active_boundary_objects[tid].end();
571 : }
572 :
573 : template <typename T>
574 : bool
575 254295 : MooseObjectWarehouseBase<T>::hasActiveObject(const std::string & name, THREAD_ID tid /* = 0*/) const
576 : {
577 254295 : checkThreadID(tid);
578 393557 : for (const auto & object : _active_objects[tid])
579 372241 : if (object->name() == name)
580 232979 : return true;
581 21316 : return false;
582 : }
583 :
584 : template <typename T>
585 : std::shared_ptr<T>
586 22912 : MooseObjectWarehouseBase<T>::getObject(const std::string & name, THREAD_ID tid /* = 0*/) const
587 : {
588 22912 : checkThreadID(tid);
589 25955 : for (const auto & object : _all_objects[tid])
590 25955 : if (object->name() == name)
591 22912 : return object;
592 0 : mooseError("Unable to locate object: ", name, ".");
593 : }
594 :
595 : template <typename T>
596 : std::shared_ptr<T>
597 1050858 : MooseObjectWarehouseBase<T>::getActiveObject(const std::string & name, THREAD_ID tid /* = 0*/) const
598 : {
599 1050858 : checkThreadID(tid);
600 1313412 : for (const auto & object : _active_objects[tid])
601 1313408 : if (object->name() == name)
602 1050854 : return object;
603 4 : mooseError("Unable to locate active object: ", name, ".");
604 : }
605 :
606 : template <typename T>
607 : const std::vector<std::shared_ptr<T>> &
608 : MooseObjectWarehouseBase<T>::getObjectsForVariable(const VariableName & var_name,
609 : THREAD_ID tid /* = 0*/) const
610 : {
611 : return libmesh_map_find(_all_variable_objects[tid], var_name);
612 : }
613 :
614 : template <typename T>
615 : std::set<SubdomainID>
616 55939 : MooseObjectWarehouseBase<T>::getActiveBlocks(THREAD_ID tid /* = 0*/) const
617 : {
618 55939 : checkThreadID(tid);
619 55939 : std::set<SubdomainID> ids;
620 67389 : for (const auto & object_pair : _active_block_objects[tid])
621 11450 : ids.insert(object_pair.first);
622 55939 : return ids;
623 0 : }
624 :
625 : template <typename T>
626 : void
627 153194073 : MooseObjectWarehouseBase<T>::updateActive(THREAD_ID tid /*= 0*/)
628 : {
629 153194073 : checkThreadID(tid);
630 :
631 153194073 : updateActiveHelper(_active_objects[tid], _all_objects[tid]);
632 :
633 154809584 : for (const auto & object_pair : _all_block_objects[tid])
634 1615511 : updateActiveHelper(_active_block_objects[tid][object_pair.first], object_pair.second);
635 :
636 156722844 : for (const auto & object_pair : _all_boundary_objects[tid])
637 3528771 : updateActiveHelper(_active_boundary_objects[tid][object_pair.first], object_pair.second);
638 153194073 : }
639 :
640 : template <typename T>
641 : void
642 158338355 : MooseObjectWarehouseBase<T>::updateActiveHelper(std::vector<std::shared_ptr<T>> & active,
643 : const std::vector<std::shared_ptr<T>> & all)
644 : {
645 : // Clear the active list
646 158338355 : active.clear();
647 :
648 158338355 : std::copy_if(all.begin(),
649 : all.end(),
650 : std::back_inserter(active),
651 15771099 : [](const std::shared_ptr<T> & object) { return object->enabled(); });
652 158338355 : }
653 :
654 : template <typename T>
655 : void
656 12785075 : MooseObjectWarehouseBase<T>::sort(THREAD_ID tid /* = 0*/)
657 : {
658 12785075 : checkThreadID(tid);
659 :
660 12831083 : for (auto & object_pair : _all_block_objects[tid])
661 46008 : sortHelper(object_pair.second);
662 :
663 12790814 : for (auto & object_pair : _all_boundary_objects[tid])
664 5739 : sortHelper(object_pair.second);
665 :
666 12785075 : sortHelper(_all_objects[tid]);
667 :
668 : // The active lists now must be update to reflect the order changes
669 12785075 : updateActive(tid);
670 12785075 : }
671 :
672 : template <typename T>
673 : void
674 711284 : MooseObjectWarehouseBase<T>::updateVariableDependency(
675 : std::set<MooseVariableFieldBase *> & needed_moose_vars, THREAD_ID tid /* = 0*/) const
676 : {
677 711284 : if (hasActiveObjects(tid))
678 645111 : updateVariableDependencyHelper(needed_moose_vars, _all_objects[tid]);
679 711284 : }
680 :
681 : template <typename T>
682 : void
683 8968122 : MooseObjectWarehouseBase<T>::updateBlockVariableDependency(
684 : SubdomainID id,
685 : std::set<MooseVariableFieldBase *> & needed_moose_vars,
686 : THREAD_ID tid /* = 0*/) const
687 : {
688 8968122 : if (hasActiveBlockObjects(id, tid))
689 4304039 : updateVariableDependencyHelper(needed_moose_vars, getActiveBlockObjects(id, tid));
690 8968122 : }
691 :
692 : template <typename T>
693 : void
694 8968122 : MooseObjectWarehouseBase<T>::updateBoundaryVariableDependency(
695 : std::set<MooseVariableFieldBase *> & needed_moose_vars, THREAD_ID tid /* = 0*/) const
696 : {
697 8968122 : if (hasActiveBoundaryObjects(tid))
698 : {
699 511874 : typename std::map<BoundaryID, std::vector<std::shared_ptr<T>>>::const_iterator it;
700 1727079 : for (const auto & object_pair : _active_boundary_objects[tid])
701 1215205 : updateVariableDependencyHelper(needed_moose_vars, object_pair.second);
702 : }
703 8968122 : }
704 :
705 : template <typename T>
706 : void
707 17906390 : MooseObjectWarehouseBase<T>::updateBoundaryVariableDependency(
708 : BoundaryID id,
709 : std::set<MooseVariableFieldBase *> & needed_moose_vars,
710 : THREAD_ID tid /* = 0*/) const
711 : {
712 17906390 : if (hasActiveBoundaryObjects(id, tid))
713 16463 : updateVariableDependencyHelper(needed_moose_vars, getActiveBoundaryObjects(id, tid));
714 17906390 : }
715 :
716 : template <typename T>
717 : void
718 6180818 : MooseObjectWarehouseBase<T>::updateVariableDependencyHelper(
719 : std::set<MooseVariableFieldBase *> & needed_moose_vars,
720 : const std::vector<std::shared_ptr<T>> & objects)
721 : {
722 20026794 : for (const auto & object : objects)
723 : {
724 13845976 : auto c = dynamic_cast<const MooseVariableDependencyInterface *>(object.get());
725 13845976 : if (c)
726 : {
727 13845976 : const auto & mv_deps = c->getMooseVariableDependencies();
728 13845976 : needed_moose_vars.insert(mv_deps.begin(), mv_deps.end());
729 : }
730 : }
731 6180818 : }
732 :
733 : template <typename T>
734 : void
735 15134275 : MooseObjectWarehouseBase<T>::updateBlockFEVariableCoupledVectorTagDependency(
736 : SubdomainID id, std::set<TagID> & needed_fe_var_vector_tags, THREAD_ID tid /* = 0*/) const
737 : {
738 15134275 : if (hasActiveBlockObjects(id, tid))
739 5861904 : updateFEVariableCoupledVectorTagDependencyHelper(needed_fe_var_vector_tags,
740 : getActiveBlockObjects(id, tid));
741 15134275 : }
742 :
743 : template <typename T>
744 : void
745 13242 : MooseObjectWarehouseBase<T>::updateBoundaryFEVariableCoupledVectorTagDependency(
746 : BoundaryID id, std::set<TagID> & needed_fe_var_vector_tags, THREAD_ID tid /* = 0*/) const
747 : {
748 13242 : if (hasActiveBoundaryObjects(id, tid))
749 13242 : updateFEVariableCoupledVectorTagDependencyHelper(needed_fe_var_vector_tags,
750 : getActiveBoundaryObjects(id, tid));
751 13242 : }
752 :
753 : template <typename T>
754 : void
755 5875146 : MooseObjectWarehouseBase<T>::updateFEVariableCoupledVectorTagDependencyHelper(
756 : std::set<TagID> & needed_fe_var_vector_tags, const std::vector<std::shared_ptr<T>> & objects)
757 : {
758 19833789 : for (const auto & object : objects)
759 : {
760 13958643 : auto c = dynamic_cast<const Coupleable *>(object.get());
761 13958643 : if (c)
762 : {
763 13958643 : const auto & tag_deps = c->getFEVariableCoupleableVectorTags();
764 13958643 : needed_fe_var_vector_tags.insert(tag_deps.begin(), tag_deps.end());
765 : }
766 : }
767 5875146 : }
768 :
769 : template <typename T>
770 : void
771 106469 : MooseObjectWarehouseBase<T>::updateMatPropDependency(
772 : std::unordered_set<unsigned int> & needed_mat_props, THREAD_ID tid /* = 0*/) const
773 : {
774 106469 : if (hasActiveObjects(tid))
775 80127 : updateMatPropDependencyHelper(needed_mat_props, _all_objects[tid]);
776 106469 : }
777 :
778 : template <typename T>
779 : void
780 9493243 : MooseObjectWarehouseBase<T>::updateBlockMatPropDependency(
781 : SubdomainID id,
782 : std::unordered_set<unsigned int> & needed_mat_props,
783 : THREAD_ID tid /* = 0*/) const
784 : {
785 9493243 : if (hasActiveBlockObjects(id, tid))
786 4829160 : updateMatPropDependencyHelper(needed_mat_props, getActiveBlockObjects(id, tid));
787 9493243 : }
788 :
789 : template <typename T>
790 : void
791 8968122 : MooseObjectWarehouseBase<T>::updateBoundaryMatPropDependency(
792 : std::unordered_set<unsigned int> & needed_mat_props, THREAD_ID tid /* = 0*/) const
793 : {
794 8968122 : if (hasActiveBoundaryObjects(tid))
795 1727079 : for (auto & active_bnd_object : _active_boundary_objects[tid])
796 1215205 : updateMatPropDependencyHelper(needed_mat_props, active_bnd_object.second);
797 8968122 : }
798 :
799 : template <typename T>
800 : void
801 17906390 : MooseObjectWarehouseBase<T>::updateBoundaryMatPropDependency(
802 : BoundaryID id,
803 : std::unordered_set<unsigned int> & needed_mat_props,
804 : THREAD_ID tid /* = 0*/) const
805 : {
806 17906390 : if (hasActiveBoundaryObjects(id, tid))
807 16463 : updateMatPropDependencyHelper(needed_mat_props, getActiveBoundaryObjects(id, tid));
808 17906390 : }
809 :
810 : template <typename T>
811 : void
812 6140955 : MooseObjectWarehouseBase<T>::updateMatPropDependencyHelper(
813 : std::unordered_set<unsigned int> & needed_mat_props,
814 : const std::vector<std::shared_ptr<T>> & objects)
815 : {
816 19767929 : for (auto & object : objects)
817 : {
818 13626974 : auto c = dynamic_cast<const MaterialPropertyInterface *>(object.get());
819 13626974 : if (c)
820 : {
821 13592323 : auto & mp_deps = c->getMatPropDependencies();
822 13592323 : needed_mat_props.insert(mp_deps.begin(), mp_deps.end());
823 : }
824 : }
825 6140955 : }
826 :
827 : template <typename T>
828 : void
829 158372 : MooseObjectWarehouseBase<T>::subdomainsCovered(std::set<SubdomainID> & subdomains_covered,
830 : std::set<std::string> & unique_variables,
831 : THREAD_ID tid /*=0*/) const
832 : {
833 234889 : for (const auto & object : _active_objects[tid])
834 : {
835 76517 : unique_variables.insert(object->variable().name());
836 76517 : const auto additional_variables_covered = object->additionalROVariables();
837 76517 : unique_variables.insert(additional_variables_covered.begin(),
838 : additional_variables_covered.end());
839 : }
840 :
841 202397 : for (const auto & object_pair : _active_block_objects[tid])
842 44025 : subdomains_covered.insert(object_pair.first);
843 158372 : }
844 :
845 : template <typename T>
846 : std::string
847 50071 : MooseObjectWarehouseBase<T>::activeObjectsToFormattedString(
848 : const THREAD_ID tid /*=0*/, const std::string & prefix /*="[DBG]"*/) const
849 : {
850 50071 : std::vector<std::string> output;
851 253639 : for (const auto & object : _active_objects[tid])
852 203568 : output.push_back(object->name());
853 100142 : return ConsoleUtils::formatString(MooseUtils::join(output, " "), prefix);
854 50071 : }
855 :
856 : template <typename T>
857 : void
858 12866186 : MooseObjectWarehouseBase<T>::sortHelper(std::vector<std::shared_ptr<T>> & objects)
859 : {
860 : // Do nothing if the vector is empty
861 12866186 : if (objects.empty())
862 12744676 : return;
863 :
864 : try
865 : {
866 : // Sort based on dependencies
867 121510 : DependencyResolverInterface::sort<std::shared_ptr<T>>(objects);
868 : }
869 4 : catch (CyclicDependencyException<std::shared_ptr<T>> & e)
870 : {
871 4 : DependencyResolverInterface::cyclicDependencyError<std::shared_ptr<T>>(
872 : e, "Cyclic dependency detected in object ordering");
873 : }
874 : }
875 :
876 : template <typename T>
877 : inline void
878 3873060778 : MooseObjectWarehouseBase<T>::checkThreadID(THREAD_ID libmesh_dbg_var(tid)) const
879 : {
880 : mooseAssert(tid < _num_threads,
881 : "Attempting to access a thread id ("
882 : << tid << ") greater than the number allowed by the storage item ("
883 : << _num_threads << ")");
884 3873060778 : }
|