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 for all objects, block-restricted objects, and
162 : * boundary-restricted objects
163 : */
164 : void updateFEVariableCoupledVectorTagDependency(std::set<TagID> & needed_fe_var_vector_tags,
165 : THREAD_ID tid = 0) const;
166 : void updateBlockFEVariableCoupledVectorTagDependency(SubdomainID id,
167 : std::set<TagID> & needed_fe_var_vector_tags,
168 : THREAD_ID tid = 0) const;
169 : void updateBoundaryFEVariableCoupledVectorTagDependency(
170 : BoundaryID id, std::set<TagID> & needed_fe_var_vector_tags, THREAD_ID tid = 0) const;
171 : ///@}
172 :
173 : ///@{
174 : /**
175 : * Update material property dependency vector.
176 : * @param producer_only Only append dependencies of materials producing the \p needed_mat_props
177 : */
178 : void updateMatPropDependency(std::unordered_set<unsigned int> & needed_mat_props,
179 : THREAD_ID tid = 0,
180 : const bool producer_only = false) const;
181 : void updateBlockMatPropDependency(SubdomainID id,
182 : std::unordered_set<unsigned int> & needed_mat_props,
183 : THREAD_ID tid = 0,
184 : const bool producer_only = false) const;
185 : void updateBoundaryMatPropDependency(std::unordered_set<unsigned int> & needed_mat_props,
186 : THREAD_ID tid = 0,
187 : const bool producer_only = false) const;
188 : void updateBoundaryMatPropDependency(BoundaryID id,
189 : std::unordered_set<unsigned int> & needed_mat_props,
190 : THREAD_ID tid = 0,
191 : const bool producer_only = false) const;
192 : ///@}
193 :
194 : /**
195 : * Populates a set of covered subdomains and the associated variable names.
196 : */
197 : void subdomainsCovered(std::set<SubdomainID> & subdomains_covered,
198 : std::set<std::string> & unique_variables,
199 : THREAD_ID tid = 0) const;
200 :
201 : /**
202 : * Return the number of threads.
203 : */
204 : THREAD_ID numThreads() const { return _num_threads; }
205 :
206 : /**
207 : * Output the active content of the warehouse to a string, meant to be output to the console
208 : * @param tid the thread id
209 : * @param prefix a string to prepend to the string
210 : */
211 : std::string activeObjectsToFormattedString(THREAD_ID tid = 0,
212 : const std::string & prefix = "[DBG]") const;
213 :
214 : protected:
215 : /// Convenience member storing the number of threads used for storage (1 or libMesh::n_threads)
216 : const THREAD_ID _num_threads;
217 :
218 : /// Storage container for the ALL pointers (THREAD_ID on outer vector)
219 : std::vector<std::vector<std::shared_ptr<T>>> _all_objects;
220 :
221 : /// All active objects (THREAD_ID on outer vector)
222 : std::vector<std::vector<std::shared_ptr<T>>> _active_objects;
223 :
224 : // All block restricted objects (THREAD_ID on outer vector)
225 : std::vector<std::map<SubdomainID, std::vector<std::shared_ptr<T>>>> _all_block_objects;
226 :
227 : /// Active block restricted objects (THREAD_ID on outer vector)
228 : std::vector<std::map<SubdomainID, std::vector<std::shared_ptr<T>>>> _active_block_objects;
229 :
230 : // All boundary restricted objects (THREAD_ID on outer vector)
231 : std::vector<std::map<BoundaryID, std::vector<std::shared_ptr<T>>>> _all_boundary_objects;
232 :
233 : /// Active boundary restricted objects (THREAD_ID on outer vector)
234 : std::vector<std::map<BoundaryID, std::vector<std::shared_ptr<T>>>> _active_boundary_objects;
235 :
236 : /// All objects with a certain variable selected, as the 'variable' parameter
237 : std::vector<std::map<VariableName, std::vector<std::shared_ptr<T>>>> _all_variable_objects;
238 :
239 : /**
240 : * Helper method for updating active vectors
241 : */
242 : static void updateActiveHelper(std::vector<std::shared_ptr<T>> & active,
243 : const std::vector<std::shared_ptr<T>> & all);
244 :
245 : /**
246 : * Helper method for sorting vectors of objects.
247 : */
248 : static void sortHelper(std::vector<std::shared_ptr<T>> & objects);
249 :
250 : /**
251 : * Helper method for updating variable dependency vector
252 : */
253 : static void updateVariableDependencyHelper(std::set<MooseVariableFieldBase *> & needed_moose_vars,
254 : const std::vector<std::shared_ptr<T>> & objects);
255 :
256 : /**
257 : * Helper method for updating FE variable coupleable vector tag vector
258 : */
259 : static void
260 : updateFEVariableCoupledVectorTagDependencyHelper(std::set<TagID> & needed_fe_var_vector_tags,
261 : const std::vector<std::shared_ptr<T>> & objects);
262 :
263 : /**
264 : * Helper method for updating material property dependency vector
265 : */
266 : virtual void updateMatPropDependencyHelper(std::unordered_set<unsigned int> & needed_mat_props,
267 : const std::vector<std::shared_ptr<T>> & objects,
268 : const bool producer_only) const;
269 :
270 : /**
271 : * Calls assert on thread id.
272 : */
273 : void checkThreadID(THREAD_ID tid) const;
274 :
275 : friend class MaterialWarehouse;
276 : };
277 :
278 : template <typename T>
279 33602790 : MooseObjectWarehouseBase<T>::MooseObjectWarehouseBase(bool threaded /*=true*/)
280 31606754 : : _num_threads(threaded ? libMesh::n_threads() : 1),
281 63213508 : _all_objects(_num_threads),
282 63213508 : _active_objects(_num_threads),
283 63213508 : _all_block_objects(_num_threads),
284 63213508 : _active_block_objects(_num_threads),
285 63213508 : _all_boundary_objects(_num_threads),
286 63213508 : _active_boundary_objects(_num_threads),
287 94820262 : _all_variable_objects(_num_threads)
288 : {
289 31749328 : }
290 :
291 : template <typename T>
292 85172287 : MooseObjectWarehouseBase<T>::~MooseObjectWarehouseBase()
293 : {
294 85172287 : }
295 :
296 : template <typename T>
297 : unsigned int
298 18297327 : MooseObjectWarehouseBase<T>::size(THREAD_ID tid /* =0 */) const
299 : {
300 18297327 : checkThreadID(tid);
301 18297327 : return _all_objects[tid].size();
302 : }
303 :
304 : template <typename T>
305 : void
306 1326990 : MooseObjectWarehouseBase<T>::addObject(std::shared_ptr<T> object,
307 : THREAD_ID tid /*= 0*/,
308 : bool /* recurse = true */)
309 : {
310 1326990 : checkThreadID(tid);
311 :
312 : // Stores object in list of all objects
313 1326990 : _all_objects[tid].push_back(object);
314 :
315 : // If enabled, store object in a list of all active
316 1326990 : bool enabled = object->enabled();
317 1326990 : if (enabled)
318 1326347 : _active_objects[tid].push_back(object);
319 :
320 : // Perform casts to the Block/BoundaryRestrictable
321 1326990 : std::shared_ptr<BoundaryRestrictable> bnd =
322 : std::dynamic_pointer_cast<BoundaryRestrictable>(object);
323 1326990 : std::shared_ptr<BlockRestrictable> blk = std::dynamic_pointer_cast<BlockRestrictable>(object);
324 :
325 : // Boundary Restricted
326 1326990 : if (bnd && bnd->boundaryRestricted())
327 : {
328 391952 : const std::set<BoundaryID> & ids = bnd->boundaryIDs();
329 871809 : for (std::set<BoundaryID>::const_iterator it = ids.begin(); it != ids.end(); ++it)
330 : {
331 479857 : _all_boundary_objects[tid][*it].push_back(object);
332 479857 : if (enabled)
333 479841 : _active_boundary_objects[tid][*it].push_back(object);
334 : }
335 : }
336 :
337 : // Block Restricted
338 935038 : else if (blk)
339 : {
340 644629 : const std::set<SubdomainID> & ids =
341 635355 : blk->blockRestricted() ? blk->blockIDs() : blk->meshBlockIDs();
342 1383463 : for (std::set<SubdomainID>::const_iterator it = ids.begin(); it != ids.end(); ++it)
343 : {
344 738834 : _all_block_objects[tid][*it].push_back(object);
345 738834 : if (enabled)
346 738352 : _active_block_objects[tid][*it].push_back(object);
347 : }
348 :
349 : // Check variables
350 644629 : std::shared_ptr<Coupleable> c_ptr = std::dynamic_pointer_cast<Coupleable>(object);
351 644629 : if (c_ptr)
352 743137 : for (MooseVariableFieldBase * var : c_ptr->getCoupledMooseVars())
353 103550 : blk->checkVariable(*var);
354 :
355 644620 : const InputParameters & parameters = object->parameters();
356 :
357 644620 : SubProblem & problem = *parameters.get<SubProblem *>("_subproblem");
358 :
359 644620 : THREAD_ID tid = parameters.get<THREAD_ID>("_tid");
360 :
361 1289240 : if (parameters.isParamValid("variable"))
362 : {
363 : // Try the scalar version first
364 571300 : std::string variable_name = parameters.getMooseType("variable");
365 571300 : if (variable_name == "")
366 : // When using vector variables, we are only going to use the first one in the list at the
367 : // interface level...
368 8376 : variable_name = parameters.getVecMooseType("variable")[0];
369 :
370 571300 : blk->checkVariable(problem.getVariable(
371 : tid, variable_name, Moose::VarKindType::VAR_ANY, Moose::VarFieldType::VAR_FIELD_ANY));
372 :
373 571291 : _all_variable_objects[tid][variable_name].push_back(object);
374 571291 : }
375 644611 : }
376 1326972 : }
377 :
378 : template <typename T>
379 : inline const std::vector<std::shared_ptr<T>> &
380 16383922 : MooseObjectWarehouseBase<T>::getObjects(THREAD_ID tid /* = 0*/) const
381 : {
382 16383922 : checkThreadID(tid);
383 16383922 : return _all_objects[tid];
384 : }
385 :
386 : template <typename T>
387 : inline const std::map<BoundaryID, std::vector<std::shared_ptr<T>>> &
388 277 : MooseObjectWarehouseBase<T>::getBoundaryObjects(THREAD_ID tid /* = 0*/) const
389 : {
390 277 : checkThreadID(tid);
391 277 : return _all_boundary_objects[tid];
392 : }
393 :
394 : template <typename T>
395 : bool
396 20040766 : MooseObjectWarehouseBase<T>::hasBoundaryObjects(BoundaryID id, THREAD_ID tid /* = 0*/) const
397 : {
398 20040766 : checkThreadID(tid);
399 20040766 : return _all_boundary_objects[tid].find(id) != _all_boundary_objects[tid].end();
400 : }
401 :
402 : template <typename T>
403 : const std::vector<std::shared_ptr<T>> &
404 966204 : MooseObjectWarehouseBase<T>::getBoundaryObjects(BoundaryID id, THREAD_ID tid /* = 0*/) const
405 : {
406 966204 : checkThreadID(tid);
407 966204 : const auto iter = _all_boundary_objects[tid].find(id);
408 : mooseAssert(iter != _all_boundary_objects[tid].end(),
409 : "Unable to located active boundary objects for the given id: " << id << ".");
410 1932408 : return iter->second;
411 : }
412 :
413 : template <typename T>
414 : inline const std::map<SubdomainID, std::vector<std::shared_ptr<T>>> &
415 831 : MooseObjectWarehouseBase<T>::getBlockObjects(THREAD_ID tid /* = 0*/) const
416 : {
417 831 : checkThreadID(tid);
418 831 : return _all_block_objects[tid];
419 : }
420 :
421 : template <typename T>
422 : const std::vector<std::shared_ptr<T>> &
423 36 : MooseObjectWarehouseBase<T>::getBlockObjects(SubdomainID id, THREAD_ID tid /* = 0*/) const
424 : {
425 36 : checkThreadID(tid);
426 36 : const auto iter = _all_block_objects[tid].find(id);
427 : mooseAssert(iter != _all_block_objects[tid].end(),
428 : "Unable to located active block objects for the given id: " << id << ".");
429 72 : return iter->second;
430 : }
431 :
432 : template <typename T>
433 : inline const std::vector<std::shared_ptr<T>> &
434 48787042 : MooseObjectWarehouseBase<T>::getActiveObjects(THREAD_ID tid /* = 0*/) const
435 : {
436 48787042 : checkThreadID(tid);
437 48787042 : return _active_objects[tid];
438 : }
439 :
440 : template <typename T>
441 : inline const std::map<BoundaryID, std::vector<std::shared_ptr<T>>> &
442 4764413 : MooseObjectWarehouseBase<T>::getActiveBoundaryObjects(THREAD_ID tid /* = 0*/) const
443 : {
444 4764413 : checkThreadID(tid);
445 4764413 : return _active_boundary_objects[tid];
446 : }
447 :
448 : template <typename T>
449 : const std::vector<std::shared_ptr<T>> &
450 67500609 : MooseObjectWarehouseBase<T>::getActiveBoundaryObjects(BoundaryID id, THREAD_ID tid /* = 0*/) const
451 : {
452 67500609 : checkThreadID(tid);
453 67500609 : const auto iter = _active_boundary_objects[tid].find(id);
454 : mooseAssert(iter != _active_boundary_objects[tid].end(),
455 : "Unable to located active boundary objects for the given id: " << id << ".");
456 135001218 : return iter->second;
457 : }
458 :
459 : template <typename T>
460 : inline const std::map<SubdomainID, std::vector<std::shared_ptr<T>>> &
461 22888980 : MooseObjectWarehouseBase<T>::getActiveBlockObjects(THREAD_ID tid /* = 0*/) const
462 : {
463 22888980 : checkThreadID(tid);
464 22888980 : return _active_block_objects[tid];
465 : }
466 :
467 : template <typename T>
468 : const std::vector<std::shared_ptr<T>> &
469 399565705 : MooseObjectWarehouseBase<T>::getActiveBlockObjects(SubdomainID id, THREAD_ID tid /* = 0*/) const
470 : {
471 399565705 : checkThreadID(tid);
472 399565705 : const auto iter = _active_block_objects[tid].find(id);
473 : mooseAssert(iter != _active_block_objects[tid].end(),
474 : "Unable to located active block objects for the given id: " << id << ".");
475 799131410 : return iter->second;
476 : }
477 :
478 : template <typename T>
479 : bool
480 270316 : MooseObjectWarehouseBase<T>::hasObjects(THREAD_ID tid /* = 0*/) const
481 : {
482 270316 : checkThreadID(tid);
483 270316 : return !_all_objects[tid].empty();
484 : }
485 :
486 : template <typename T>
487 : bool
488 54900596 : MooseObjectWarehouseBase<T>::hasActiveObjects(THREAD_ID tid /* = 0*/) const
489 : {
490 54900596 : checkThreadID(tid);
491 54900596 : return !_active_objects[tid].empty();
492 : }
493 :
494 : template <typename T>
495 : bool
496 3 : MooseObjectWarehouseBase<T>::hasObjectsForVariable(const VariableName & var_name,
497 : THREAD_ID tid) const
498 : {
499 3 : checkThreadID(tid);
500 3 : return _all_variable_objects[tid].count(var_name);
501 : }
502 :
503 : template <typename T>
504 : bool
505 3 : MooseObjectWarehouseBase<T>::hasObjectsForVariableAndBlocks(const VariableName & var_name,
506 : const std::set<SubdomainID> & blocks,
507 : std::set<SubdomainID> & blocks_covered,
508 : THREAD_ID tid /* = 0*/) const
509 : {
510 3 : checkThreadID(tid);
511 3 : blocks_covered.clear();
512 3 : if (!hasObjectsForVariable(var_name, tid))
513 0 : return false;
514 :
515 : // Check block restriction as a whole
516 6 : for (const auto & object : libmesh_map_find(_all_variable_objects[tid], var_name))
517 : {
518 3 : std::shared_ptr<BlockRestrictable> blk = std::dynamic_pointer_cast<BlockRestrictable>(object);
519 3 : if (blk && blk->hasBlocks(blocks))
520 : {
521 3 : blocks_covered = blocks;
522 3 : return true;
523 : }
524 : }
525 : // No object has all the blocks, but one might overlap, which could be troublesome.
526 : // We'll keep track of which blocks are covered in case several overlap
527 0 : for (const auto & object : libmesh_map_find(_all_variable_objects[tid], var_name))
528 : {
529 0 : std::shared_ptr<BlockRestrictable> blk = std::dynamic_pointer_cast<BlockRestrictable>(object);
530 0 : if (blk)
531 0 : for (const auto & block : blocks)
532 0 : if (blk->hasBlocks(block))
533 0 : blocks_covered.insert(block);
534 : }
535 : // No overlap at all
536 0 : if (blocks_covered.empty())
537 0 : return false;
538 :
539 0 : return (blocks == blocks_covered);
540 : }
541 :
542 : template <typename T>
543 : bool
544 15746069 : MooseObjectWarehouseBase<T>::hasActiveBlockObjects(THREAD_ID tid /* = 0*/) const
545 : {
546 15746069 : checkThreadID(tid);
547 15746069 : bool has_active_block_objects = false;
548 16000661 : for (const auto & object_pair : _active_block_objects[tid])
549 254592 : has_active_block_objects |= !(object_pair.second.empty());
550 15746069 : return has_active_block_objects;
551 : }
552 :
553 : template <typename T>
554 : bool
555 515290358 : MooseObjectWarehouseBase<T>::hasActiveBlockObjects(SubdomainID id, THREAD_ID tid /* = 0*/) const
556 : {
557 515290358 : checkThreadID(tid);
558 515290358 : const auto iter = _active_block_objects[tid].find(id);
559 515290358 : return iter != _active_block_objects[tid].end();
560 : }
561 :
562 : template <typename T>
563 : bool
564 35907864 : MooseObjectWarehouseBase<T>::hasActiveBoundaryObjects(THREAD_ID tid /* = 0*/) const
565 : {
566 35907864 : checkThreadID(tid);
567 35907864 : bool has_active_boundary_objects = false;
568 38312292 : for (const auto & object_pair : _active_boundary_objects[tid])
569 2404428 : has_active_boundary_objects |= !(object_pair.second.empty());
570 35907864 : return has_active_boundary_objects;
571 : }
572 :
573 : template <typename T>
574 : bool
575 397110835 : MooseObjectWarehouseBase<T>::hasActiveBoundaryObjects(BoundaryID id, THREAD_ID tid /* = 0*/) const
576 : {
577 397110835 : checkThreadID(tid);
578 397110835 : const auto iter = _active_boundary_objects[tid].find(id);
579 397110835 : return iter != _active_boundary_objects[tid].end();
580 : }
581 :
582 : template <typename T>
583 : bool
584 323887 : MooseObjectWarehouseBase<T>::hasActiveObject(const std::string & name, THREAD_ID tid /* = 0*/) const
585 : {
586 323887 : checkThreadID(tid);
587 532588 : for (const auto & object : _active_objects[tid])
588 509637 : if (object->name() == name)
589 300936 : return true;
590 22951 : return false;
591 : }
592 :
593 : template <typename T>
594 : std::shared_ptr<T>
595 26192 : MooseObjectWarehouseBase<T>::getObject(const std::string & name, THREAD_ID tid /* = 0*/) const
596 : {
597 26192 : checkThreadID(tid);
598 29817 : for (const auto & object : _all_objects[tid])
599 29817 : if (object->name() == name)
600 26192 : return object;
601 0 : mooseError("Unable to locate object: ", name, ".");
602 : }
603 :
604 : template <typename T>
605 : std::shared_ptr<T>
606 1195836 : MooseObjectWarehouseBase<T>::getActiveObject(const std::string & name, THREAD_ID tid /* = 0*/) const
607 : {
608 1195836 : checkThreadID(tid);
609 1614972 : for (const auto & object : _active_objects[tid])
610 1614969 : if (object->name() == name)
611 1195833 : return object;
612 3 : mooseError("Unable to locate active object: ", name, ".");
613 : }
614 :
615 : template <typename T>
616 : const std::vector<std::shared_ptr<T>> &
617 : MooseObjectWarehouseBase<T>::getObjectsForVariable(const VariableName & var_name,
618 : THREAD_ID tid /* = 0*/) const
619 : {
620 : return libmesh_map_find(_all_variable_objects[tid], var_name);
621 : }
622 :
623 : template <typename T>
624 : std::set<SubdomainID>
625 59733 : MooseObjectWarehouseBase<T>::getActiveBlocks(THREAD_ID tid /* = 0*/) const
626 : {
627 59733 : checkThreadID(tid);
628 59733 : std::set<SubdomainID> ids;
629 72252 : for (const auto & object_pair : _active_block_objects[tid])
630 12519 : ids.insert(object_pair.first);
631 59733 : return ids;
632 0 : }
633 :
634 : template <typename T>
635 : void
636 180282646 : MooseObjectWarehouseBase<T>::updateActive(THREAD_ID tid /*= 0*/)
637 : {
638 180282646 : checkThreadID(tid);
639 :
640 180282646 : updateActiveHelper(_active_objects[tid], _all_objects[tid]);
641 :
642 182013158 : for (const auto & object_pair : _all_block_objects[tid])
643 1730512 : updateActiveHelper(_active_block_objects[tid][object_pair.first], object_pair.second);
644 :
645 183854326 : for (const auto & object_pair : _all_boundary_objects[tid])
646 3571680 : updateActiveHelper(_active_boundary_objects[tid][object_pair.first], object_pair.second);
647 180282646 : }
648 :
649 : template <typename T>
650 : void
651 185584838 : MooseObjectWarehouseBase<T>::updateActiveHelper(std::vector<std::shared_ptr<T>> & active,
652 : const std::vector<std::shared_ptr<T>> & all)
653 : {
654 : // Clear the active list
655 185584838 : active.clear();
656 :
657 185688924 : std::copy_if(all.begin(),
658 : all.end(),
659 : std::back_inserter(active),
660 16227708 : [](const std::shared_ptr<T> & object) { return object->enabled(); });
661 185584838 : }
662 :
663 : template <typename T>
664 : void
665 16650837 : MooseObjectWarehouseBase<T>::sort(THREAD_ID tid /* = 0*/)
666 : {
667 16650837 : checkThreadID(tid);
668 :
669 16701390 : for (auto & object_pair : _all_block_objects[tid])
670 50553 : sortHelper(object_pair.second);
671 :
672 16656777 : for (auto & object_pair : _all_boundary_objects[tid])
673 5940 : sortHelper(object_pair.second);
674 :
675 16650837 : sortHelper(_all_objects[tid]);
676 :
677 : // The active lists now must be update to reflect the order changes
678 16650837 : updateActive(tid);
679 16650837 : }
680 :
681 : template <typename T>
682 : void
683 1186887 : MooseObjectWarehouseBase<T>::updateVariableDependency(
684 : std::set<MooseVariableFieldBase *> & needed_moose_vars, THREAD_ID tid /* = 0*/) const
685 : {
686 1186887 : if (hasActiveObjects(tid))
687 909891 : updateVariableDependencyHelper(needed_moose_vars, _active_objects[tid]);
688 1186887 : }
689 :
690 : template <typename T>
691 : void
692 9061452 : MooseObjectWarehouseBase<T>::updateBlockVariableDependency(
693 : SubdomainID id,
694 : std::set<MooseVariableFieldBase *> & needed_moose_vars,
695 : THREAD_ID tid /* = 0*/) const
696 : {
697 9061452 : if (hasActiveBlockObjects(id, tid))
698 4340556 : updateVariableDependencyHelper(needed_moose_vars, getActiveBlockObjects(id, tid));
699 9061452 : }
700 :
701 : template <typename T>
702 : void
703 9061452 : MooseObjectWarehouseBase<T>::updateBoundaryVariableDependency(
704 : std::set<MooseVariableFieldBase *> & needed_moose_vars, THREAD_ID tid /* = 0*/) const
705 : {
706 9061452 : if (hasActiveBoundaryObjects(tid))
707 : {
708 466094 : typename std::map<BoundaryID, std::vector<std::shared_ptr<T>>>::const_iterator it;
709 1571773 : for (const auto & object_pair : _active_boundary_objects[tid])
710 1105679 : updateVariableDependencyHelper(needed_moose_vars, object_pair.second);
711 : }
712 9061452 : }
713 :
714 : template <typename T>
715 : void
716 18429918 : MooseObjectWarehouseBase<T>::updateBoundaryVariableDependency(
717 : BoundaryID id,
718 : std::set<MooseVariableFieldBase *> & needed_moose_vars,
719 : THREAD_ID tid /* = 0*/) const
720 : {
721 18429918 : if (hasActiveBoundaryObjects(id, tid))
722 16045 : updateVariableDependencyHelper(needed_moose_vars, getActiveBoundaryObjects(id, tid));
723 18429918 : }
724 :
725 : template <typename T>
726 : void
727 6372171 : MooseObjectWarehouseBase<T>::updateVariableDependencyHelper(
728 : std::set<MooseVariableFieldBase *> & needed_moose_vars,
729 : const std::vector<std::shared_ptr<T>> & objects)
730 : {
731 20343125 : for (const auto & object : objects)
732 : {
733 13970954 : auto c = dynamic_cast<const MooseVariableDependencyInterface *>(object.get());
734 13970954 : if (c)
735 : {
736 13970954 : const auto & mv_deps = c->getMooseVariableDependencies();
737 13970954 : needed_moose_vars.insert(mv_deps.begin(), mv_deps.end());
738 : }
739 : }
740 6372171 : }
741 :
742 : template <typename T>
743 : void
744 365232 : MooseObjectWarehouseBase<T>::updateFEVariableCoupledVectorTagDependency(
745 : std::set<TagID> & needed_fe_var_vector_tags, THREAD_ID tid /* = 0*/) const
746 : {
747 365232 : if (hasActiveObjects(tid))
748 245238 : updateFEVariableCoupledVectorTagDependencyHelper(needed_fe_var_vector_tags,
749 144212 : _active_objects[tid]);
750 365232 : }
751 :
752 : template <typename T>
753 : void
754 15407610 : MooseObjectWarehouseBase<T>::updateBlockFEVariableCoupledVectorTagDependency(
755 : SubdomainID id, std::set<TagID> & needed_fe_var_vector_tags, THREAD_ID tid /* = 0*/) const
756 : {
757 15407610 : if (hasActiveBlockObjects(id, tid))
758 5995296 : updateFEVariableCoupledVectorTagDependencyHelper(needed_fe_var_vector_tags,
759 : getActiveBlockObjects(id, tid));
760 15407610 : }
761 :
762 : template <typename T>
763 : void
764 28472 : MooseObjectWarehouseBase<T>::updateBoundaryFEVariableCoupledVectorTagDependency(
765 : BoundaryID id, std::set<TagID> & needed_fe_var_vector_tags, THREAD_ID tid /* = 0*/) const
766 : {
767 28472 : if (hasActiveBoundaryObjects(id, tid))
768 20302 : updateFEVariableCoupledVectorTagDependencyHelper(needed_fe_var_vector_tags,
769 : getActiveBoundaryObjects(id, tid));
770 28472 : }
771 :
772 : template <typename T>
773 : void
774 6260836 : MooseObjectWarehouseBase<T>::updateFEVariableCoupledVectorTagDependencyHelper(
775 : std::set<TagID> & needed_fe_var_vector_tags, const std::vector<std::shared_ptr<T>> & objects)
776 : {
777 20703918 : for (const auto & object : objects)
778 : {
779 14443082 : auto c = dynamic_cast<const Coupleable *>(object.get());
780 14443082 : if (c)
781 : {
782 14443082 : const auto & tag_deps = c->getFEVariableCoupleableVectorTags();
783 14443082 : needed_fe_var_vector_tags.insert(tag_deps.begin(), tag_deps.end());
784 : }
785 : }
786 6260836 : }
787 :
788 : template <typename T>
789 : void
790 294354 : MooseObjectWarehouseBase<T>::updateMatPropDependency(
791 : std::unordered_set<unsigned int> & needed_mat_props,
792 : THREAD_ID tid /* = 0*/,
793 : const bool producer_only /* = false*/) const
794 : {
795 294354 : if (hasActiveObjects(tid))
796 212859 : updateMatPropDependencyHelper(needed_mat_props, _active_objects[tid], producer_only);
797 294354 : }
798 :
799 : template <typename T>
800 : void
801 9669413 : MooseObjectWarehouseBase<T>::updateBlockMatPropDependency(
802 : SubdomainID id,
803 : std::unordered_set<unsigned int> & needed_mat_props,
804 : THREAD_ID tid /* = 0*/,
805 : const bool producer_only /* = false*/) const
806 : {
807 9669413 : if (hasActiveBlockObjects(id, tid))
808 4948517 : updateMatPropDependencyHelper(needed_mat_props, getActiveBlockObjects(id, tid), producer_only);
809 9669413 : }
810 :
811 : template <typename T>
812 : void
813 9061452 : MooseObjectWarehouseBase<T>::updateBoundaryMatPropDependency(
814 : std::unordered_set<unsigned int> & needed_mat_props,
815 : THREAD_ID tid /* = 0*/,
816 : const bool producer_only /* = false*/) const
817 : {
818 9061452 : if (hasActiveBoundaryObjects(tid))
819 1571773 : for (auto & active_bnd_object : _active_boundary_objects[tid])
820 1105679 : updateMatPropDependencyHelper(needed_mat_props, active_bnd_object.second, producer_only);
821 9061452 : }
822 :
823 : template <typename T>
824 : void
825 18429918 : MooseObjectWarehouseBase<T>::updateBoundaryMatPropDependency(
826 : BoundaryID id,
827 : std::unordered_set<unsigned int> & needed_mat_props,
828 : THREAD_ID tid /* = 0*/,
829 : const bool producer_only /* = false*/) const
830 : {
831 18429918 : if (hasActiveBoundaryObjects(id, tid))
832 16045 : updateMatPropDependencyHelper(
833 : needed_mat_props, getActiveBoundaryObjects(id, tid), producer_only);
834 18429918 : }
835 :
836 : template <typename T>
837 : void
838 6259954 : MooseObjectWarehouseBase<T>::updateMatPropDependencyHelper(
839 : std::unordered_set<unsigned int> & needed_mat_props,
840 : const std::vector<std::shared_ptr<T>> & objects,
841 : const bool /* producer_only */) const
842 : {
843 19897746 : for (auto & object : objects)
844 : {
845 13637792 : auto c = dynamic_cast<const MaterialPropertyInterface *>(object.get());
846 13637792 : if (c)
847 : {
848 13603946 : auto & mp_deps = c->getMatPropDependencies();
849 13603946 : needed_mat_props.insert(mp_deps.begin(), mp_deps.end());
850 : }
851 : }
852 6259954 : }
853 :
854 : template <typename T>
855 : void
856 222062 : MooseObjectWarehouseBase<T>::subdomainsCovered(std::set<SubdomainID> & subdomains_covered,
857 : std::set<std::string> & unique_variables,
858 : THREAD_ID tid /*=0*/) const
859 : {
860 301539 : for (const auto & object : _active_objects[tid])
861 : {
862 79477 : unique_variables.insert(object->variable().name());
863 79477 : const auto additional_variables_covered = object->additionalROVariables();
864 79477 : unique_variables.insert(additional_variables_covered.begin(),
865 : additional_variables_covered.end());
866 : }
867 :
868 268331 : for (const auto & object_pair : _active_block_objects[tid])
869 46269 : subdomains_covered.insert(object_pair.first);
870 222062 : }
871 :
872 : template <typename T>
873 : std::string
874 46781 : MooseObjectWarehouseBase<T>::activeObjectsToFormattedString(
875 : const THREAD_ID tid /*=0*/, const std::string & prefix /*="[DBG]"*/) const
876 : {
877 46781 : std::vector<std::string> output;
878 221197 : for (const auto & object : _active_objects[tid])
879 174416 : output.push_back(object->name());
880 93562 : return ConsoleUtils::formatString(MooseUtils::join(output, " "), prefix);
881 46781 : }
882 :
883 : template <typename T>
884 : void
885 16759721 : MooseObjectWarehouseBase<T>::sortHelper(std::vector<std::shared_ptr<T>> & objects)
886 : {
887 : // Do nothing if the vector is empty
888 16759721 : if (objects.empty())
889 16624096 : return;
890 :
891 : try
892 : {
893 : // Sort based on dependencies
894 135625 : DependencyResolverInterface::sort<std::shared_ptr<T>>(objects);
895 : }
896 5 : catch (CyclicDependencyException<std::shared_ptr<T>> & e)
897 : {
898 5 : DependencyResolverInterface::cyclicDependencyError<std::shared_ptr<T>>(
899 : e, "Cyclic dependency detected in object ordering");
900 : }
901 : }
902 :
903 : template <typename T>
904 : inline void
905 2115249760 : MooseObjectWarehouseBase<T>::checkThreadID(THREAD_ID libmesh_dbg_var(tid)) const
906 : {
907 : mooseAssert(tid < _num_threads,
908 : "Attempting to access a thread id ("
909 : << tid << ") greater than the number allowed by the storage item ("
910 : << _num_threads << ")");
911 2115249760 : }
|