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 30906639 : MooseObjectWarehouseBase<T>::MooseObjectWarehouseBase(bool threaded /*=true*/)
271 30906639 : : _num_threads(threaded ? libMesh::n_threads() : 1),
272 30906639 : _all_objects(_num_threads),
273 30906639 : _active_objects(_num_threads),
274 30906639 : _all_block_objects(_num_threads),
275 30906639 : _active_block_objects(_num_threads),
276 30906639 : _all_boundary_objects(_num_threads),
277 30906639 : _active_boundary_objects(_num_threads),
278 61813278 : _all_variable_objects(_num_threads)
279 : {
280 30906639 : }
281 :
282 : template <typename T>
283 82815134 : MooseObjectWarehouseBase<T>::~MooseObjectWarehouseBase()
284 : {
285 82815134 : }
286 :
287 : template <typename T>
288 : unsigned int
289 22628866 : MooseObjectWarehouseBase<T>::size(THREAD_ID tid /* =0 */) const
290 : {
291 22628866 : checkThreadID(tid);
292 22628866 : return _all_objects[tid].size();
293 : }
294 :
295 : template <typename T>
296 : void
297 1574658 : MooseObjectWarehouseBase<T>::addObject(std::shared_ptr<T> object,
298 : THREAD_ID tid /*= 0*/,
299 : bool /* recurse = true */)
300 : {
301 1574658 : checkThreadID(tid);
302 :
303 : // Stores object in list of all objects
304 1574658 : _all_objects[tid].push_back(object);
305 :
306 : // If enabled, store object in a list of all active
307 1574658 : bool enabled = object->enabled();
308 1574658 : if (enabled)
309 1573948 : _active_objects[tid].push_back(object);
310 :
311 : // Perform casts to the Block/BoundaryRestrictable
312 1574658 : std::shared_ptr<BoundaryRestrictable> bnd =
313 : std::dynamic_pointer_cast<BoundaryRestrictable>(object);
314 1574658 : std::shared_ptr<BlockRestrictable> blk = std::dynamic_pointer_cast<BlockRestrictable>(object);
315 :
316 : // Boundary Restricted
317 1574658 : if (bnd && bnd->boundaryRestricted())
318 : {
319 417605 : const std::set<BoundaryID> & ids = bnd->boundaryIDs();
320 930304 : for (std::set<BoundaryID>::const_iterator it = ids.begin(); it != ids.end(); ++it)
321 : {
322 512699 : _all_boundary_objects[tid][*it].push_back(object);
323 512699 : if (enabled)
324 512679 : _active_boundary_objects[tid][*it].push_back(object);
325 : }
326 : }
327 :
328 : // Block Restricted
329 1157053 : else if (blk)
330 : {
331 789122 : const std::set<SubdomainID> & ids =
332 789122 : blk->blockRestricted() ? blk->blockIDs() : blk->meshBlockIDs();
333 1692230 : for (std::set<SubdomainID>::const_iterator it = ids.begin(); it != ids.end(); ++it)
334 : {
335 903108 : _all_block_objects[tid][*it].push_back(object);
336 903108 : if (enabled)
337 902576 : _active_block_objects[tid][*it].push_back(object);
338 : }
339 :
340 : // Check variables
341 789122 : std::shared_ptr<Coupleable> c_ptr = std::dynamic_pointer_cast<Coupleable>(object);
342 789122 : if (c_ptr)
343 1032998 : for (MooseVariableFieldBase * var : c_ptr->getCoupledMooseVars())
344 249874 : blk->checkVariable(*var);
345 :
346 789102 : const InputParameters & parameters = object->parameters();
347 :
348 789102 : SubProblem & problem = *parameters.get<SubProblem *>("_subproblem");
349 :
350 789102 : THREAD_ID tid = parameters.get<THREAD_ID>("_tid");
351 :
352 789102 : if (parameters.isParamValid("variable"))
353 : {
354 : // Try the scalar version first
355 699572 : std::string variable_name = parameters.getMooseType("variable");
356 699572 : 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 128706 : variable_name = parameters.getVecMooseType("variable")[0];
360 :
361 699572 : blk->checkVariable(problem.getVariable(
362 : tid, variable_name, Moose::VarKindType::VAR_ANY, Moose::VarFieldType::VAR_FIELD_ANY));
363 :
364 699560 : _all_variable_objects[tid][variable_name].push_back(object);
365 699560 : }
366 789090 : }
367 1574626 : }
368 :
369 : template <typename T>
370 : inline const std::vector<std::shared_ptr<T>> &
371 17240341 : MooseObjectWarehouseBase<T>::getObjects(THREAD_ID tid /* = 0*/) const
372 : {
373 17240341 : checkThreadID(tid);
374 17240341 : return _all_objects[tid];
375 : }
376 :
377 : template <typename T>
378 : inline const std::map<BoundaryID, std::vector<std::shared_ptr<T>>> &
379 242 : MooseObjectWarehouseBase<T>::getBoundaryObjects(THREAD_ID tid /* = 0*/) const
380 : {
381 242 : checkThreadID(tid);
382 242 : return _all_boundary_objects[tid];
383 : }
384 :
385 : template <typename T>
386 : bool
387 20851715 : MooseObjectWarehouseBase<T>::hasBoundaryObjects(BoundaryID id, THREAD_ID tid /* = 0*/) const
388 : {
389 20851715 : checkThreadID(tid);
390 20851715 : 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 1082060 : MooseObjectWarehouseBase<T>::getBoundaryObjects(BoundaryID id, THREAD_ID tid /* = 0*/) const
396 : {
397 1082060 : checkThreadID(tid);
398 1082060 : 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 1082060 : return iter->second;
402 : }
403 :
404 : template <typename T>
405 : inline const std::map<SubdomainID, std::vector<std::shared_ptr<T>>> &
406 726 : MooseObjectWarehouseBase<T>::getBlockObjects(THREAD_ID tid /* = 0*/) const
407 : {
408 726 : checkThreadID(tid);
409 726 : 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 36670868 : MooseObjectWarehouseBase<T>::getActiveObjects(THREAD_ID tid /* = 0*/) const
426 : {
427 36670868 : checkThreadID(tid);
428 36670868 : return _active_objects[tid];
429 : }
430 :
431 : template <typename T>
432 : inline const std::map<BoundaryID, std::vector<std::shared_ptr<T>>> &
433 5189119 : MooseObjectWarehouseBase<T>::getActiveBoundaryObjects(THREAD_ID tid /* = 0*/) const
434 : {
435 5189119 : checkThreadID(tid);
436 5189119 : return _active_boundary_objects[tid];
437 : }
438 :
439 : template <typename T>
440 : const std::vector<std::shared_ptr<T>> &
441 74189977 : MooseObjectWarehouseBase<T>::getActiveBoundaryObjects(BoundaryID id, THREAD_ID tid /* = 0*/) const
442 : {
443 74189977 : checkThreadID(tid);
444 74189977 : 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 74189977 : return iter->second;
448 : }
449 :
450 : template <typename T>
451 : inline const std::map<SubdomainID, std::vector<std::shared_ptr<T>>> &
452 25713332 : MooseObjectWarehouseBase<T>::getActiveBlockObjects(THREAD_ID tid /* = 0*/) const
453 : {
454 25713332 : checkThreadID(tid);
455 25713332 : return _active_block_objects[tid];
456 : }
457 :
458 : template <typename T>
459 : const std::vector<std::shared_ptr<T>> &
460 453719947 : MooseObjectWarehouseBase<T>::getActiveBlockObjects(SubdomainID id, THREAD_ID tid /* = 0*/) const
461 : {
462 453719947 : checkThreadID(tid);
463 453719947 : 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 453719947 : return iter->second;
467 : }
468 :
469 : template <typename T>
470 : bool
471 60058 : MooseObjectWarehouseBase<T>::hasObjects(THREAD_ID tid /* = 0*/) const
472 : {
473 60058 : checkThreadID(tid);
474 60058 : return !_all_objects[tid].empty();
475 : }
476 :
477 : template <typename T>
478 : bool
479 51308509 : MooseObjectWarehouseBase<T>::hasActiveObjects(THREAD_ID tid /* = 0*/) const
480 : {
481 51308509 : checkThreadID(tid);
482 51308509 : 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 16663362 : MooseObjectWarehouseBase<T>::hasActiveBlockObjects(THREAD_ID tid /* = 0*/) const
536 : {
537 16663362 : checkThreadID(tid);
538 16663362 : bool has_active_block_objects = false;
539 16941074 : for (const auto & object_pair : _active_block_objects[tid])
540 277712 : has_active_block_objects |= !(object_pair.second.empty());
541 16663362 : return has_active_block_objects;
542 : }
543 :
544 : template <typename T>
545 : bool
546 2748891746 : MooseObjectWarehouseBase<T>::hasActiveBlockObjects(SubdomainID id, THREAD_ID tid /* = 0*/) const
547 : {
548 2748891746 : checkThreadID(tid);
549 2748891746 : const auto iter = _active_block_objects[tid].find(id);
550 2748891746 : return iter != _active_block_objects[tid].end();
551 : }
552 :
553 : template <typename T>
554 : bool
555 38043401 : MooseObjectWarehouseBase<T>::hasActiveBoundaryObjects(THREAD_ID tid /* = 0*/) const
556 : {
557 38043401 : checkThreadID(tid);
558 38043401 : bool has_active_boundary_objects = false;
559 40792737 : for (const auto & object_pair : _active_boundary_objects[tid])
560 2749336 : has_active_boundary_objects |= !(object_pair.second.empty());
561 38043401 : return has_active_boundary_objects;
562 : }
563 :
564 : template <typename T>
565 : bool
566 322043190 : MooseObjectWarehouseBase<T>::hasActiveBoundaryObjects(BoundaryID id, THREAD_ID tid /* = 0*/) const
567 : {
568 322043190 : checkThreadID(tid);
569 322043190 : const auto iter = _active_boundary_objects[tid].find(id);
570 322043190 : return iter != _active_boundary_objects[tid].end();
571 : }
572 :
573 : template <typename T>
574 : bool
575 303947 : MooseObjectWarehouseBase<T>::hasActiveObject(const std::string & name, THREAD_ID tid /* = 0*/) const
576 : {
577 303947 : checkThreadID(tid);
578 513836 : for (const auto & object : _active_objects[tid])
579 490790 : if (object->name() == name)
580 280901 : return true;
581 23046 : return false;
582 : }
583 :
584 : template <typename T>
585 : std::shared_ptr<T>
586 24763 : MooseObjectWarehouseBase<T>::getObject(const std::string & name, THREAD_ID tid /* = 0*/) const
587 : {
588 24763 : checkThreadID(tid);
589 28070 : for (const auto & object : _all_objects[tid])
590 28070 : if (object->name() == name)
591 24763 : return object;
592 0 : mooseError("Unable to locate object: ", name, ".");
593 : }
594 :
595 : template <typename T>
596 : std::shared_ptr<T>
597 1281809 : MooseObjectWarehouseBase<T>::getActiveObject(const std::string & name, THREAD_ID tid /* = 0*/) const
598 : {
599 1281809 : checkThreadID(tid);
600 1730961 : for (const auto & object : _active_objects[tid])
601 1730957 : if (object->name() == name)
602 1281805 : 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 60447 : MooseObjectWarehouseBase<T>::getActiveBlocks(THREAD_ID tid /* = 0*/) const
617 : {
618 60447 : checkThreadID(tid);
619 60447 : std::set<SubdomainID> ids;
620 72744 : for (const auto & object_pair : _active_block_objects[tid])
621 12297 : ids.insert(object_pair.first);
622 60447 : return ids;
623 0 : }
624 :
625 : template <typename T>
626 : void
627 172039742 : MooseObjectWarehouseBase<T>::updateActive(THREAD_ID tid /*= 0*/)
628 : {
629 172039742 : checkThreadID(tid);
630 :
631 172039742 : updateActiveHelper(_active_objects[tid], _all_objects[tid]);
632 :
633 173796998 : for (const auto & object_pair : _all_block_objects[tid])
634 1757256 : updateActiveHelper(_active_block_objects[tid][object_pair.first], object_pair.second);
635 :
636 175865219 : for (const auto & object_pair : _all_boundary_objects[tid])
637 3825477 : updateActiveHelper(_active_boundary_objects[tid][object_pair.first], object_pair.second);
638 172039742 : }
639 :
640 : template <typename T>
641 : void
642 177622475 : 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 177622475 : active.clear();
647 :
648 177622475 : std::copy_if(all.begin(),
649 : all.end(),
650 : std::back_inserter(active),
651 17119648 : [](const std::shared_ptr<T> & object) { return object->enabled(); });
652 177622475 : }
653 :
654 : template <typename T>
655 : void
656 14268461 : MooseObjectWarehouseBase<T>::sort(THREAD_ID tid /* = 0*/)
657 : {
658 14268461 : checkThreadID(tid);
659 :
660 14318304 : for (auto & object_pair : _all_block_objects[tid])
661 49843 : sortHelper(object_pair.second);
662 :
663 14274634 : for (auto & object_pair : _all_boundary_objects[tid])
664 6173 : sortHelper(object_pair.second);
665 :
666 14268461 : sortHelper(_all_objects[tid]);
667 :
668 : // The active lists now must be update to reflect the order changes
669 14268461 : updateActive(tid);
670 14268461 : }
671 :
672 : template <typename T>
673 : void
674 766618 : MooseObjectWarehouseBase<T>::updateVariableDependency(
675 : std::set<MooseVariableFieldBase *> & needed_moose_vars, THREAD_ID tid /* = 0*/) const
676 : {
677 766618 : if (hasActiveObjects(tid))
678 693261 : updateVariableDependencyHelper(needed_moose_vars, _all_objects[tid]);
679 766618 : }
680 :
681 : template <typename T>
682 : void
683 9618008 : MooseObjectWarehouseBase<T>::updateBlockVariableDependency(
684 : SubdomainID id,
685 : std::set<MooseVariableFieldBase *> & needed_moose_vars,
686 : THREAD_ID tid /* = 0*/) const
687 : {
688 9618008 : if (hasActiveBlockObjects(id, tid))
689 4613903 : updateVariableDependencyHelper(needed_moose_vars, getActiveBlockObjects(id, tid));
690 9618008 : }
691 :
692 : template <typename T>
693 : void
694 9618008 : MooseObjectWarehouseBase<T>::updateBoundaryVariableDependency(
695 : std::set<MooseVariableFieldBase *> & needed_moose_vars, THREAD_ID tid /* = 0*/) const
696 : {
697 9618008 : if (hasActiveBoundaryObjects(tid))
698 : {
699 532263 : typename std::map<BoundaryID, std::vector<std::shared_ptr<T>>>::const_iterator it;
700 1801912 : for (const auto & object_pair : _active_boundary_objects[tid])
701 1269649 : updateVariableDependencyHelper(needed_moose_vars, object_pair.second);
702 : }
703 9618008 : }
704 :
705 : template <typename T>
706 : void
707 19364734 : MooseObjectWarehouseBase<T>::updateBoundaryVariableDependency(
708 : BoundaryID id,
709 : std::set<MooseVariableFieldBase *> & needed_moose_vars,
710 : THREAD_ID tid /* = 0*/) const
711 : {
712 19364734 : if (hasActiveBoundaryObjects(id, tid))
713 17580 : updateVariableDependencyHelper(needed_moose_vars, getActiveBoundaryObjects(id, tid));
714 19364734 : }
715 :
716 : template <typename T>
717 : void
718 6594393 : MooseObjectWarehouseBase<T>::updateVariableDependencyHelper(
719 : std::set<MooseVariableFieldBase *> & needed_moose_vars,
720 : const std::vector<std::shared_ptr<T>> & objects)
721 : {
722 21343636 : for (const auto & object : objects)
723 : {
724 14749243 : auto c = dynamic_cast<const MooseVariableDependencyInterface *>(object.get());
725 14749243 : if (c)
726 : {
727 14749243 : const auto & mv_deps = c->getMooseVariableDependencies();
728 14749243 : needed_moose_vars.insert(mv_deps.begin(), mv_deps.end());
729 : }
730 : }
731 6594393 : }
732 :
733 : template <typename T>
734 : void
735 16324919 : MooseObjectWarehouseBase<T>::updateBlockFEVariableCoupledVectorTagDependency(
736 : SubdomainID id, std::set<TagID> & needed_fe_var_vector_tags, THREAD_ID tid /* = 0*/) const
737 : {
738 16324919 : if (hasActiveBlockObjects(id, tid))
739 6341847 : updateFEVariableCoupledVectorTagDependencyHelper(needed_fe_var_vector_tags,
740 : getActiveBlockObjects(id, tid));
741 16324919 : }
742 :
743 : template <typename T>
744 : void
745 14430 : MooseObjectWarehouseBase<T>::updateBoundaryFEVariableCoupledVectorTagDependency(
746 : BoundaryID id, std::set<TagID> & needed_fe_var_vector_tags, THREAD_ID tid /* = 0*/) const
747 : {
748 14430 : if (hasActiveBoundaryObjects(id, tid))
749 14430 : updateFEVariableCoupledVectorTagDependencyHelper(needed_fe_var_vector_tags,
750 : getActiveBoundaryObjects(id, tid));
751 14430 : }
752 :
753 : template <typename T>
754 : void
755 6356277 : MooseObjectWarehouseBase<T>::updateFEVariableCoupledVectorTagDependencyHelper(
756 : std::set<TagID> & needed_fe_var_vector_tags, const std::vector<std::shared_ptr<T>> & objects)
757 : {
758 21405390 : for (const auto & object : objects)
759 : {
760 15049113 : auto c = dynamic_cast<const Coupleable *>(object.get());
761 15049113 : if (c)
762 : {
763 15049113 : const auto & tag_deps = c->getFEVariableCoupleableVectorTags();
764 15049113 : needed_fe_var_vector_tags.insert(tag_deps.begin(), tag_deps.end());
765 : }
766 : }
767 6356277 : }
768 :
769 : template <typename T>
770 : void
771 116907 : MooseObjectWarehouseBase<T>::updateMatPropDependency(
772 : std::unordered_set<unsigned int> & needed_mat_props, THREAD_ID tid /* = 0*/) const
773 : {
774 116907 : if (hasActiveObjects(tid))
775 87785 : updateMatPropDependencyHelper(needed_mat_props, _all_objects[tid]);
776 116907 : }
777 :
778 : template <typename T>
779 : void
780 10179213 : MooseObjectWarehouseBase<T>::updateBlockMatPropDependency(
781 : SubdomainID id,
782 : std::unordered_set<unsigned int> & needed_mat_props,
783 : THREAD_ID tid /* = 0*/) const
784 : {
785 10179213 : if (hasActiveBlockObjects(id, tid))
786 5175108 : updateMatPropDependencyHelper(needed_mat_props, getActiveBlockObjects(id, tid));
787 10179213 : }
788 :
789 : template <typename T>
790 : void
791 9618008 : MooseObjectWarehouseBase<T>::updateBoundaryMatPropDependency(
792 : std::unordered_set<unsigned int> & needed_mat_props, THREAD_ID tid /* = 0*/) const
793 : {
794 9618008 : if (hasActiveBoundaryObjects(tid))
795 1801912 : for (auto & active_bnd_object : _active_boundary_objects[tid])
796 1269649 : updateMatPropDependencyHelper(needed_mat_props, active_bnd_object.second);
797 9618008 : }
798 :
799 : template <typename T>
800 : void
801 19364734 : MooseObjectWarehouseBase<T>::updateBoundaryMatPropDependency(
802 : BoundaryID id,
803 : std::unordered_set<unsigned int> & needed_mat_props,
804 : THREAD_ID tid /* = 0*/) const
805 : {
806 19364734 : if (hasActiveBoundaryObjects(id, tid))
807 17580 : updateMatPropDependencyHelper(needed_mat_props, getActiveBoundaryObjects(id, tid));
808 19364734 : }
809 :
810 : template <typename T>
811 : void
812 6550122 : MooseObjectWarehouseBase<T>::updateMatPropDependencyHelper(
813 : std::unordered_set<unsigned int> & needed_mat_props,
814 : const std::vector<std::shared_ptr<T>> & objects)
815 : {
816 21058825 : for (auto & object : objects)
817 : {
818 14508703 : auto c = dynamic_cast<const MaterialPropertyInterface *>(object.get());
819 14508703 : if (c)
820 : {
821 14470452 : auto & mp_deps = c->getMatPropDependencies();
822 14470452 : needed_mat_props.insert(mp_deps.begin(), mp_deps.end());
823 : }
824 : }
825 6550122 : }
826 :
827 : template <typename T>
828 : void
829 170104 : MooseObjectWarehouseBase<T>::subdomainsCovered(std::set<SubdomainID> & subdomains_covered,
830 : std::set<std::string> & unique_variables,
831 : THREAD_ID tid /*=0*/) const
832 : {
833 252425 : for (const auto & object : _active_objects[tid])
834 : {
835 82321 : unique_variables.insert(object->variable().name());
836 82321 : const auto additional_variables_covered = object->additionalROVariables();
837 82321 : unique_variables.insert(additional_variables_covered.begin(),
838 : additional_variables_covered.end());
839 : }
840 :
841 217550 : for (const auto & object_pair : _active_block_objects[tid])
842 47446 : subdomains_covered.insert(object_pair.first);
843 170104 : }
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 14355901 : MooseObjectWarehouseBase<T>::sortHelper(std::vector<std::shared_ptr<T>> & objects)
859 : {
860 : // Do nothing if the vector is empty
861 14355901 : if (objects.empty())
862 14224851 : return;
863 :
864 : try
865 : {
866 : // Sort based on dependencies
867 131050 : 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 4293286034 : 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 4293286034 : }
|