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(THREAD_ID tid = 0) const;
100 : bool hasBoundaryObjects(BoundaryID id, THREAD_ID tid = 0) const;
101 : ///@}
102 :
103 : /**
104 : * Whether there are objects for this variable and the set of blocks passed
105 : * @param var_name name of the variable
106 : * @param blocks blocks to consider
107 : * @param blocks_covered subset of blocks for which there is an object
108 : */
109 : bool hasObjectsForVariableAndBlocks(const VariableName & var_name,
110 : const std::set<SubdomainID> & blocks,
111 : std::set<SubdomainID> & blocks_covered,
112 : THREAD_ID tid) const;
113 :
114 : /**
115 : * Return a set of active SubdomainsIDs
116 : */
117 : std::set<SubdomainID> getActiveBlocks(THREAD_ID tid = 0) const;
118 :
119 : ///@{
120 : /**
121 : * Convenience functions for checking/getting specific objects
122 : */
123 : bool hasActiveObject(const std::string & name, THREAD_ID tid = 0) const;
124 : std::shared_ptr<T> getObject(const std::string & name, THREAD_ID tid = 0) const;
125 : std::shared_ptr<T> getActiveObject(const std::string & name, THREAD_ID tid = 0) const;
126 : ///@}
127 :
128 : /// Getter for objects that have the 'variable' set to a particular variable
129 : /// Note that users should check whether there are objects using 'hasObjectsForVariable' before
130 : /// calling this routine, because it will throw if there are no objects for this variable
131 : const std::vector<std::shared_ptr<T>> & getObjectsForVariable(const VariableName & var_name,
132 : THREAD_ID tid) const;
133 :
134 : /**
135 : * Updates the active objects storage.
136 : */
137 : virtual void updateActive(THREAD_ID tid = 0);
138 :
139 : /**
140 : * Sort the objects using the DependencyResolver.
141 : */
142 : void sort(THREAD_ID tid = 0);
143 :
144 : ///@{
145 : /**
146 : * Update variable dependency vector.
147 : */
148 : void updateVariableDependency(std::set<MooseVariableFieldBase *> & needed_moose_vars,
149 : THREAD_ID tid = 0) const;
150 : void updateBlockVariableDependency(SubdomainID id,
151 : std::set<MooseVariableFieldBase *> & needed_moose_vars,
152 : THREAD_ID tid = 0) const;
153 : void updateBoundaryVariableDependency(std::set<MooseVariableFieldBase *> & needed_moose_vars,
154 : THREAD_ID tid = 0) const;
155 : void updateBoundaryVariableDependency(BoundaryID id,
156 : std::set<MooseVariableFieldBase *> & needed_moose_vars,
157 : THREAD_ID tid = 0) const;
158 : ///@}
159 :
160 : ///@{
161 : /**
162 : * Update FE variable coupleable vector tag vector for all objects, block-restricted objects, and
163 : * boundary-restricted objects
164 : */
165 : void updateFEVariableCoupledVectorTagDependency(std::set<TagID> & needed_fe_var_vector_tags,
166 : THREAD_ID tid = 0) const;
167 : void updateBlockFEVariableCoupledVectorTagDependency(SubdomainID id,
168 : std::set<TagID> & needed_fe_var_vector_tags,
169 : THREAD_ID tid = 0) const;
170 : void updateBoundaryFEVariableCoupledVectorTagDependency(
171 : BoundaryID id, std::set<TagID> & needed_fe_var_vector_tags, THREAD_ID tid = 0) const;
172 : ///@}
173 :
174 : ///@{
175 : /**
176 : * Update material property dependency vector.
177 : * @param producer_only Only append dependencies of materials producing the \p needed_mat_props
178 : */
179 : void updateMatPropDependency(std::unordered_set<unsigned int> & needed_mat_props,
180 : THREAD_ID tid = 0,
181 : const bool producer_only = false) const;
182 : void updateBlockMatPropDependency(SubdomainID id,
183 : std::unordered_set<unsigned int> & needed_mat_props,
184 : THREAD_ID tid = 0,
185 : const bool producer_only = false) const;
186 : void updateBoundaryMatPropDependency(std::unordered_set<unsigned int> & needed_mat_props,
187 : THREAD_ID tid = 0,
188 : const bool producer_only = false) const;
189 : void updateBoundaryMatPropDependency(BoundaryID id,
190 : std::unordered_set<unsigned int> & needed_mat_props,
191 : THREAD_ID tid = 0,
192 : const bool producer_only = false) const;
193 : ///@}
194 :
195 : /**
196 : * Populates a set of covered subdomains and the associated variable names.
197 : */
198 : void subdomainsCovered(std::set<SubdomainID> & subdomains_covered,
199 : std::set<std::string> & unique_variables,
200 : THREAD_ID tid = 0) const;
201 :
202 : /**
203 : * Return the number of threads.
204 : */
205 : THREAD_ID numThreads() const { return _num_threads; }
206 :
207 : /**
208 : * Output the active content of the warehouse to a string, meant to be output to the console
209 : * @param tid the thread id
210 : * @param prefix a string to prepend to the string
211 : */
212 : std::string activeObjectsToFormattedString(THREAD_ID tid = 0,
213 : const std::string & prefix = "[DBG]") const;
214 :
215 : protected:
216 : /// Convenience member storing the number of threads used for storage (1 or libMesh::n_threads)
217 : const THREAD_ID _num_threads;
218 :
219 : /// Storage container for the ALL pointers (THREAD_ID on outer vector)
220 : std::vector<std::vector<std::shared_ptr<T>>> _all_objects;
221 :
222 : /// All active objects (THREAD_ID on outer vector)
223 : std::vector<std::vector<std::shared_ptr<T>>> _active_objects;
224 :
225 : // All block restricted objects (THREAD_ID on outer vector)
226 : std::vector<std::map<SubdomainID, std::vector<std::shared_ptr<T>>>> _all_block_objects;
227 :
228 : /// Active block restricted objects (THREAD_ID on outer vector)
229 : std::vector<std::map<SubdomainID, std::vector<std::shared_ptr<T>>>> _active_block_objects;
230 :
231 : // All boundary restricted objects (THREAD_ID on outer vector)
232 : std::vector<std::map<BoundaryID, std::vector<std::shared_ptr<T>>>> _all_boundary_objects;
233 :
234 : /// Active boundary restricted objects (THREAD_ID on outer vector)
235 : std::vector<std::map<BoundaryID, std::vector<std::shared_ptr<T>>>> _active_boundary_objects;
236 :
237 : /// All objects with a certain variable selected, as the 'variable' parameter
238 : std::vector<std::map<VariableName, std::vector<std::shared_ptr<T>>>> _all_variable_objects;
239 :
240 : /**
241 : * Helper method for updating active vectors
242 : */
243 : static void updateActiveHelper(std::vector<std::shared_ptr<T>> & active,
244 : const std::vector<std::shared_ptr<T>> & all);
245 :
246 : /**
247 : * Helper method for sorting vectors of objects.
248 : */
249 : static void sortHelper(std::vector<std::shared_ptr<T>> & objects);
250 :
251 : /**
252 : * Helper method for updating variable dependency vector
253 : */
254 : static void updateVariableDependencyHelper(std::set<MooseVariableFieldBase *> & needed_moose_vars,
255 : const std::vector<std::shared_ptr<T>> & objects);
256 :
257 : /**
258 : * Helper method for updating FE variable coupleable vector tag vector
259 : */
260 : static void
261 : updateFEVariableCoupledVectorTagDependencyHelper(std::set<TagID> & needed_fe_var_vector_tags,
262 : const std::vector<std::shared_ptr<T>> & objects);
263 :
264 : /**
265 : * Helper method for updating material property dependency vector
266 : */
267 : virtual void updateMatPropDependencyHelper(std::unordered_set<unsigned int> & needed_mat_props,
268 : const std::vector<std::shared_ptr<T>> & objects,
269 : const bool producer_only) const;
270 :
271 : /**
272 : * Calls assert on thread id.
273 : */
274 : void checkThreadID(THREAD_ID tid) const;
275 :
276 : /**
277 : * Helper for determining whether we have boundary objects
278 : */
279 : bool hasBoundaryObjectsHelper(
280 : const std::vector<std::map<BoundaryID, std::vector<std::shared_ptr<T>>>> & boundary_objects,
281 : const THREAD_ID tid = 0) const;
282 :
283 : friend class MaterialWarehouse;
284 : };
285 :
286 : template <typename T>
287 33930516 : MooseObjectWarehouseBase<T>::MooseObjectWarehouseBase(bool threaded /*=true*/)
288 31887832 : : _num_threads(threaded ? libMesh::n_threads() : 1),
289 63775664 : _all_objects(_num_threads),
290 63775664 : _active_objects(_num_threads),
291 63775664 : _all_block_objects(_num_threads),
292 63775664 : _active_block_objects(_num_threads),
293 63775664 : _all_boundary_objects(_num_threads),
294 63775664 : _active_boundary_objects(_num_threads),
295 95663496 : _all_variable_objects(_num_threads)
296 : {
297 32033738 : }
298 :
299 : template <typename T>
300 85952688 : MooseObjectWarehouseBase<T>::~MooseObjectWarehouseBase()
301 : {
302 85952688 : }
303 :
304 : template <typename T>
305 : unsigned int
306 17008144 : MooseObjectWarehouseBase<T>::size(THREAD_ID tid /* =0 */) const
307 : {
308 17008144 : checkThreadID(tid);
309 17008144 : return _all_objects[tid].size();
310 : }
311 :
312 : template <typename T>
313 : void
314 1332468 : MooseObjectWarehouseBase<T>::addObject(std::shared_ptr<T> object,
315 : THREAD_ID tid /*= 0*/,
316 : bool /* recurse = true */)
317 : {
318 1332468 : checkThreadID(tid);
319 :
320 : // Stores object in list of all objects
321 1332468 : _all_objects[tid].push_back(object);
322 :
323 : // If enabled, store object in a list of all active
324 1332468 : bool enabled = object->enabled();
325 1332468 : if (enabled)
326 1331825 : _active_objects[tid].push_back(object);
327 :
328 : // Perform casts to the Block/BoundaryRestrictable
329 1332468 : std::shared_ptr<BoundaryRestrictable> bnd =
330 : std::dynamic_pointer_cast<BoundaryRestrictable>(object);
331 1332468 : std::shared_ptr<BlockRestrictable> blk = std::dynamic_pointer_cast<BlockRestrictable>(object);
332 :
333 : // Boundary Restricted
334 1332468 : if (bnd && bnd->boundaryRestricted())
335 : {
336 393440 : const std::set<BoundaryID> & ids = bnd->boundaryIDs();
337 875315 : for (std::set<BoundaryID>::const_iterator it = ids.begin(); it != ids.end(); ++it)
338 : {
339 481875 : _all_boundary_objects[tid][*it].push_back(object);
340 481875 : if (enabled)
341 481859 : _active_boundary_objects[tid][*it].push_back(object);
342 : }
343 : }
344 :
345 : // Block Restricted
346 939028 : else if (blk)
347 : {
348 645920 : const std::set<SubdomainID> & ids =
349 636646 : blk->blockRestricted() ? blk->blockIDs() : blk->meshBlockIDs();
350 1386148 : for (std::set<SubdomainID>::const_iterator it = ids.begin(); it != ids.end(); ++it)
351 : {
352 740228 : _all_block_objects[tid][*it].push_back(object);
353 740228 : if (enabled)
354 739746 : _active_block_objects[tid][*it].push_back(object);
355 : }
356 :
357 : // Check variables
358 645920 : std::shared_ptr<Coupleable> c_ptr = std::dynamic_pointer_cast<Coupleable>(object);
359 645920 : if (c_ptr)
360 744337 : for (MooseVariableFieldBase * var : c_ptr->getCoupledMooseVars())
361 103472 : blk->checkVariable(*var);
362 :
363 645911 : const InputParameters & parameters = object->parameters();
364 :
365 645911 : SubProblem & problem = *parameters.get<SubProblem *>("_subproblem");
366 :
367 645911 : THREAD_ID tid = parameters.get<THREAD_ID>("_tid");
368 :
369 1291822 : if (parameters.isParamValid("variable"))
370 : {
371 : // Try the scalar version first
372 572212 : std::string variable_name = parameters.getMooseType("variable");
373 572212 : if (variable_name == "")
374 : // When using vector variables, we are only going to use the first one in the list at the
375 : // interface level...
376 8376 : variable_name = parameters.getVecMooseType("variable")[0];
377 :
378 572212 : blk->checkVariable(problem.getVariable(
379 : tid, variable_name, Moose::VarKindType::VAR_ANY, Moose::VarFieldType::VAR_FIELD_ANY));
380 :
381 572203 : _all_variable_objects[tid][variable_name].push_back(object);
382 572203 : }
383 645902 : }
384 1332450 : }
385 :
386 : template <typename T>
387 : inline const std::vector<std::shared_ptr<T>> &
388 15349851 : MooseObjectWarehouseBase<T>::getObjects(THREAD_ID tid /* = 0*/) const
389 : {
390 15349851 : checkThreadID(tid);
391 15349851 : return _all_objects[tid];
392 : }
393 :
394 : template <typename T>
395 : inline const std::map<BoundaryID, std::vector<std::shared_ptr<T>>> &
396 277 : MooseObjectWarehouseBase<T>::getBoundaryObjects(THREAD_ID tid /* = 0*/) const
397 : {
398 277 : checkThreadID(tid);
399 277 : return _all_boundary_objects[tid];
400 : }
401 :
402 : template <typename T>
403 : bool
404 20488051 : MooseObjectWarehouseBase<T>::hasBoundaryObjects(BoundaryID id, THREAD_ID tid /* = 0*/) const
405 : {
406 20488051 : checkThreadID(tid);
407 20488051 : return _all_boundary_objects[tid].find(id) != _all_boundary_objects[tid].end();
408 : }
409 :
410 : template <typename T>
411 : const std::vector<std::shared_ptr<T>> &
412 1067141 : MooseObjectWarehouseBase<T>::getBoundaryObjects(BoundaryID id, THREAD_ID tid /* = 0*/) const
413 : {
414 1067141 : checkThreadID(tid);
415 1067141 : const auto iter = _all_boundary_objects[tid].find(id);
416 : mooseAssert(iter != _all_boundary_objects[tid].end(),
417 : "Unable to located active boundary objects for the given id: " << id << ".");
418 2134282 : return iter->second;
419 : }
420 :
421 : template <typename T>
422 : inline const std::map<SubdomainID, std::vector<std::shared_ptr<T>>> &
423 831 : MooseObjectWarehouseBase<T>::getBlockObjects(THREAD_ID tid /* = 0*/) const
424 : {
425 831 : checkThreadID(tid);
426 831 : return _all_block_objects[tid];
427 : }
428 :
429 : template <typename T>
430 : const std::vector<std::shared_ptr<T>> &
431 36 : MooseObjectWarehouseBase<T>::getBlockObjects(SubdomainID id, THREAD_ID tid /* = 0*/) const
432 : {
433 36 : checkThreadID(tid);
434 36 : const auto iter = _all_block_objects[tid].find(id);
435 : mooseAssert(iter != _all_block_objects[tid].end(),
436 : "Unable to located active block objects for the given id: " << id << ".");
437 72 : return iter->second;
438 : }
439 :
440 : template <typename T>
441 : inline const std::vector<std::shared_ptr<T>> &
442 49170402 : MooseObjectWarehouseBase<T>::getActiveObjects(THREAD_ID tid /* = 0*/) const
443 : {
444 49170402 : checkThreadID(tid);
445 49170402 : return _active_objects[tid];
446 : }
447 :
448 : template <typename T>
449 : inline const std::map<BoundaryID, std::vector<std::shared_ptr<T>>> &
450 4761993 : MooseObjectWarehouseBase<T>::getActiveBoundaryObjects(THREAD_ID tid /* = 0*/) const
451 : {
452 4761993 : checkThreadID(tid);
453 4761993 : return _active_boundary_objects[tid];
454 : }
455 :
456 : template <typename T>
457 : const std::vector<std::shared_ptr<T>> &
458 67639374 : MooseObjectWarehouseBase<T>::getActiveBoundaryObjects(BoundaryID id, THREAD_ID tid /* = 0*/) const
459 : {
460 67639374 : checkThreadID(tid);
461 67639374 : const auto iter = _active_boundary_objects[tid].find(id);
462 : mooseAssert(iter != _active_boundary_objects[tid].end(),
463 : "Unable to located active boundary objects for the given id: " << id << ".");
464 135278748 : return iter->second;
465 : }
466 :
467 : template <typename T>
468 : inline const std::map<SubdomainID, std::vector<std::shared_ptr<T>>> &
469 22879760 : MooseObjectWarehouseBase<T>::getActiveBlockObjects(THREAD_ID tid /* = 0*/) const
470 : {
471 22879760 : checkThreadID(tid);
472 22879760 : return _active_block_objects[tid];
473 : }
474 :
475 : template <typename T>
476 : const std::vector<std::shared_ptr<T>> &
477 398679786 : MooseObjectWarehouseBase<T>::getActiveBlockObjects(SubdomainID id, THREAD_ID tid /* = 0*/) const
478 : {
479 398679786 : checkThreadID(tid);
480 398679786 : const auto iter = _active_block_objects[tid].find(id);
481 : mooseAssert(iter != _active_block_objects[tid].end(),
482 : "Unable to located active block objects for the given id: " << id << ".");
483 797359572 : return iter->second;
484 : }
485 :
486 : template <typename T>
487 : bool
488 271098 : MooseObjectWarehouseBase<T>::hasObjects(THREAD_ID tid /* = 0*/) const
489 : {
490 271098 : checkThreadID(tid);
491 271098 : return !_all_objects[tid].empty();
492 : }
493 :
494 : template <typename T>
495 : bool
496 55048532 : MooseObjectWarehouseBase<T>::hasActiveObjects(THREAD_ID tid /* = 0*/) const
497 : {
498 55048532 : checkThreadID(tid);
499 55048532 : return !_active_objects[tid].empty();
500 : }
501 :
502 : template <typename T>
503 : bool
504 3 : MooseObjectWarehouseBase<T>::hasObjectsForVariable(const VariableName & var_name,
505 : THREAD_ID tid) const
506 : {
507 3 : checkThreadID(tid);
508 3 : return _all_variable_objects[tid].count(var_name);
509 : }
510 :
511 : template <typename T>
512 : bool
513 3 : MooseObjectWarehouseBase<T>::hasObjectsForVariableAndBlocks(const VariableName & var_name,
514 : const std::set<SubdomainID> & blocks,
515 : std::set<SubdomainID> & blocks_covered,
516 : THREAD_ID tid /* = 0*/) const
517 : {
518 3 : checkThreadID(tid);
519 3 : blocks_covered.clear();
520 3 : if (!hasObjectsForVariable(var_name, tid))
521 0 : return false;
522 :
523 : // Check block restriction as a whole
524 6 : for (const auto & object : libmesh_map_find(_all_variable_objects[tid], var_name))
525 : {
526 3 : std::shared_ptr<BlockRestrictable> blk = std::dynamic_pointer_cast<BlockRestrictable>(object);
527 3 : if (blk && blk->hasBlocks(blocks))
528 : {
529 3 : blocks_covered = blocks;
530 3 : return true;
531 : }
532 : }
533 : // No object has all the blocks, but one might overlap, which could be troublesome.
534 : // We'll keep track of which blocks are covered in case several overlap
535 0 : for (const auto & object : libmesh_map_find(_all_variable_objects[tid], var_name))
536 : {
537 0 : std::shared_ptr<BlockRestrictable> blk = std::dynamic_pointer_cast<BlockRestrictable>(object);
538 0 : if (blk)
539 0 : for (const auto & block : blocks)
540 0 : if (blk->hasBlocks(block))
541 0 : blocks_covered.insert(block);
542 : }
543 : // No overlap at all
544 0 : if (blocks_covered.empty())
545 0 : return false;
546 :
547 0 : return (blocks == blocks_covered);
548 : }
549 :
550 : template <typename T>
551 : bool
552 15769855 : MooseObjectWarehouseBase<T>::hasActiveBlockObjects(THREAD_ID tid /* = 0*/) const
553 : {
554 15769855 : checkThreadID(tid);
555 15769855 : bool has_active_block_objects = false;
556 16024583 : for (const auto & object_pair : _active_block_objects[tid])
557 254728 : has_active_block_objects |= !(object_pair.second.empty());
558 15769855 : return has_active_block_objects;
559 : }
560 :
561 : template <typename T>
562 : bool
563 510015242 : MooseObjectWarehouseBase<T>::hasActiveBlockObjects(SubdomainID id, THREAD_ID tid /* = 0*/) const
564 : {
565 510015242 : checkThreadID(tid);
566 510015242 : const auto iter = _active_block_objects[tid].find(id);
567 510015242 : return iter != _active_block_objects[tid].end();
568 : }
569 :
570 : template <typename T>
571 : bool
572 34702533 : MooseObjectWarehouseBase<T>::hasBoundaryObjectsHelper(
573 : const std::vector<std::map<BoundaryID, std::vector<std::shared_ptr<T>>>> & boundary_objects,
574 : THREAD_ID tid /* = 0*/) const
575 : {
576 34702533 : checkThreadID(tid);
577 34702533 : bool has_boundary_objects = false;
578 37110632 : for (const auto & object_pair : boundary_objects[tid])
579 2408099 : has_boundary_objects |= !(object_pair.second.empty());
580 34702533 : return has_boundary_objects;
581 : }
582 :
583 : template <typename T>
584 : bool
585 58791 : MooseObjectWarehouseBase<T>::hasBoundaryObjects(THREAD_ID tid /* = 0*/) const
586 : {
587 58791 : return hasBoundaryObjectsHelper(_all_boundary_objects, tid);
588 : }
589 :
590 : template <typename T>
591 : bool
592 34643742 : MooseObjectWarehouseBase<T>::hasActiveBoundaryObjects(THREAD_ID tid /* = 0*/) const
593 : {
594 34643742 : return hasBoundaryObjectsHelper(_active_boundary_objects, tid);
595 : }
596 :
597 : template <typename T>
598 : bool
599 395213158 : MooseObjectWarehouseBase<T>::hasActiveBoundaryObjects(BoundaryID id, THREAD_ID tid /* = 0*/) const
600 : {
601 395213158 : checkThreadID(tid);
602 395213158 : const auto iter = _active_boundary_objects[tid].find(id);
603 395213158 : return iter != _active_boundary_objects[tid].end();
604 : }
605 :
606 : template <typename T>
607 : bool
608 326890 : MooseObjectWarehouseBase<T>::hasActiveObject(const std::string & name, THREAD_ID tid /* = 0*/) const
609 : {
610 326890 : checkThreadID(tid);
611 537459 : for (const auto & object : _active_objects[tid])
612 514233 : if (object->name() == name)
613 303664 : return true;
614 23226 : return false;
615 : }
616 :
617 : template <typename T>
618 : std::shared_ptr<T>
619 26593 : MooseObjectWarehouseBase<T>::getObject(const std::string & name, THREAD_ID tid /* = 0*/) const
620 : {
621 26593 : checkThreadID(tid);
622 30220 : for (const auto & object : _all_objects[tid])
623 30220 : if (object->name() == name)
624 26593 : return object;
625 0 : mooseError("Unable to locate object: ", name, ".");
626 : }
627 :
628 : template <typename T>
629 : std::shared_ptr<T>
630 1200046 : MooseObjectWarehouseBase<T>::getActiveObject(const std::string & name, THREAD_ID tid /* = 0*/) const
631 : {
632 1200046 : checkThreadID(tid);
633 1621783 : for (const auto & object : _active_objects[tid])
634 1621780 : if (object->name() == name)
635 1200043 : return object;
636 3 : mooseError("Unable to locate active object: ", name, ".");
637 : }
638 :
639 : template <typename T>
640 : const std::vector<std::shared_ptr<T>> &
641 : MooseObjectWarehouseBase<T>::getObjectsForVariable(const VariableName & var_name,
642 : THREAD_ID tid /* = 0*/) const
643 : {
644 : return libmesh_map_find(_all_variable_objects[tid], var_name);
645 : }
646 :
647 : template <typename T>
648 : std::set<SubdomainID>
649 60276 : MooseObjectWarehouseBase<T>::getActiveBlocks(THREAD_ID tid /* = 0*/) const
650 : {
651 60276 : checkThreadID(tid);
652 60276 : std::set<SubdomainID> ids;
653 72813 : for (const auto & object_pair : _active_block_objects[tid])
654 12537 : ids.insert(object_pair.first);
655 60276 : return ids;
656 0 : }
657 :
658 : template <typename T>
659 : void
660 181042174 : MooseObjectWarehouseBase<T>::updateActive(THREAD_ID tid /*= 0*/)
661 : {
662 181042174 : checkThreadID(tid);
663 :
664 181042174 : updateActiveHelper(_active_objects[tid], _all_objects[tid]);
665 :
666 182774306 : for (const auto & object_pair : _all_block_objects[tid])
667 1732132 : updateActiveHelper(_active_block_objects[tid][object_pair.first], object_pair.second);
668 :
669 184618730 : for (const auto & object_pair : _all_boundary_objects[tid])
670 3576556 : updateActiveHelper(_active_boundary_objects[tid][object_pair.first], object_pair.second);
671 181042174 : }
672 :
673 : template <typename T>
674 : void
675 186350862 : MooseObjectWarehouseBase<T>::updateActiveHelper(std::vector<std::shared_ptr<T>> & active,
676 : const std::vector<std::shared_ptr<T>> & all)
677 : {
678 : // Clear the active list
679 186350862 : active.clear();
680 :
681 186454948 : std::copy_if(all.begin(),
682 : all.end(),
683 : std::back_inserter(active),
684 16253255 : [](const std::shared_ptr<T> & object) { return object->enabled(); });
685 186350862 : }
686 :
687 : template <typename T>
688 : void
689 16793603 : MooseObjectWarehouseBase<T>::sort(THREAD_ID tid /* = 0*/)
690 : {
691 16793603 : checkThreadID(tid);
692 :
693 16844455 : for (auto & object_pair : _all_block_objects[tid])
694 50852 : sortHelper(object_pair.second);
695 :
696 16799543 : for (auto & object_pair : _all_boundary_objects[tid])
697 5940 : sortHelper(object_pair.second);
698 :
699 16793603 : sortHelper(_all_objects[tid]);
700 :
701 : // The active lists now must be update to reflect the order changes
702 16793603 : updateActive(tid);
703 16793603 : }
704 :
705 : template <typename T>
706 : void
707 1163398 : MooseObjectWarehouseBase<T>::updateVariableDependency(
708 : std::set<MooseVariableFieldBase *> & needed_moose_vars, THREAD_ID tid /* = 0*/) const
709 : {
710 1163398 : if (hasActiveObjects(tid))
711 887350 : updateVariableDependencyHelper(needed_moose_vars, _active_objects[tid]);
712 1163398 : }
713 :
714 : template <typename T>
715 : void
716 8416192 : MooseObjectWarehouseBase<T>::updateBlockVariableDependency(
717 : SubdomainID id,
718 : std::set<MooseVariableFieldBase *> & needed_moose_vars,
719 : THREAD_ID tid /* = 0*/) const
720 : {
721 8416192 : if (hasActiveBlockObjects(id, tid))
722 4022671 : updateVariableDependencyHelper(needed_moose_vars, getActiveBlockObjects(id, tid));
723 8416192 : }
724 :
725 : template <typename T>
726 : void
727 8416192 : MooseObjectWarehouseBase<T>::updateBoundaryVariableDependency(
728 : std::set<MooseVariableFieldBase *> & needed_moose_vars, THREAD_ID tid /* = 0*/) const
729 : {
730 8416192 : if (hasActiveBoundaryObjects(tid))
731 : {
732 451107 : typename std::map<BoundaryID, std::vector<std::shared_ptr<T>>>::const_iterator it;
733 1524693 : for (const auto & object_pair : _active_boundary_objects[tid])
734 1073586 : updateVariableDependencyHelper(needed_moose_vars, object_pair.second);
735 : }
736 8416192 : }
737 :
738 : template <typename T>
739 : void
740 17113711 : MooseObjectWarehouseBase<T>::updateBoundaryVariableDependency(
741 : BoundaryID id,
742 : std::set<MooseVariableFieldBase *> & needed_moose_vars,
743 : THREAD_ID tid /* = 0*/) const
744 : {
745 17113711 : if (hasActiveBoundaryObjects(id, tid))
746 15367 : updateVariableDependencyHelper(needed_moose_vars, getActiveBoundaryObjects(id, tid));
747 17113711 : }
748 :
749 : template <typename T>
750 : void
751 5998974 : MooseObjectWarehouseBase<T>::updateVariableDependencyHelper(
752 : std::set<MooseVariableFieldBase *> & needed_moose_vars,
753 : const std::vector<std::shared_ptr<T>> & objects)
754 : {
755 19059775 : for (const auto & object : objects)
756 : {
757 13060801 : auto c = dynamic_cast<const MooseVariableDependencyInterface *>(object.get());
758 13060801 : if (c)
759 : {
760 13060801 : const auto & mv_deps = c->getMooseVariableDependencies();
761 13060801 : needed_moose_vars.insert(mv_deps.begin(), mv_deps.end());
762 : }
763 : }
764 5998974 : }
765 :
766 : template <typename T>
767 : void
768 365382 : MooseObjectWarehouseBase<T>::updateFEVariableCoupledVectorTagDependency(
769 : std::set<TagID> & needed_fe_var_vector_tags, THREAD_ID tid /* = 0*/) const
770 : {
771 365382 : if (hasActiveObjects(tid))
772 245310 : updateFEVariableCoupledVectorTagDependencyHelper(needed_fe_var_vector_tags,
773 144200 : _active_objects[tid]);
774 365382 : }
775 :
776 : template <typename T>
777 : void
778 14414942 : MooseObjectWarehouseBase<T>::updateBlockFEVariableCoupledVectorTagDependency(
779 : SubdomainID id, std::set<TagID> & needed_fe_var_vector_tags, THREAD_ID tid /* = 0*/) const
780 : {
781 14414942 : if (hasActiveBlockObjects(id, tid))
782 5657933 : updateFEVariableCoupledVectorTagDependencyHelper(needed_fe_var_vector_tags,
783 : getActiveBlockObjects(id, tid));
784 14414942 : }
785 :
786 : template <typename T>
787 : void
788 28472 : MooseObjectWarehouseBase<T>::updateBoundaryFEVariableCoupledVectorTagDependency(
789 : BoundaryID id, std::set<TagID> & needed_fe_var_vector_tags, THREAD_ID tid /* = 0*/) const
790 : {
791 28472 : if (hasActiveBoundaryObjects(id, tid))
792 20302 : updateFEVariableCoupledVectorTagDependencyHelper(needed_fe_var_vector_tags,
793 : getActiveBoundaryObjects(id, tid));
794 28472 : }
795 :
796 : template <typename T>
797 : void
798 5923545 : MooseObjectWarehouseBase<T>::updateFEVariableCoupledVectorTagDependencyHelper(
799 : std::set<TagID> & needed_fe_var_vector_tags, const std::vector<std::shared_ptr<T>> & objects)
800 : {
801 19492976 : for (const auto & object : objects)
802 : {
803 13569431 : auto c = dynamic_cast<const Coupleable *>(object.get());
804 13569431 : if (c)
805 : {
806 13569431 : const auto & tag_deps = c->getFEVariableCoupleableVectorTags();
807 13569431 : needed_fe_var_vector_tags.insert(tag_deps.begin(), tag_deps.end());
808 : }
809 : }
810 5923545 : }
811 :
812 : template <typename T>
813 : void
814 292940 : MooseObjectWarehouseBase<T>::updateMatPropDependency(
815 : std::unordered_set<unsigned int> & needed_mat_props,
816 : THREAD_ID tid /* = 0*/,
817 : const bool producer_only /* = false*/) const
818 : {
819 292940 : if (hasActiveObjects(tid))
820 211863 : updateMatPropDependencyHelper(needed_mat_props, _active_objects[tid], producer_only);
821 292940 : }
822 :
823 : template <typename T>
824 : void
825 9003032 : MooseObjectWarehouseBase<T>::updateBlockMatPropDependency(
826 : SubdomainID id,
827 : std::unordered_set<unsigned int> & needed_mat_props,
828 : THREAD_ID tid /* = 0*/,
829 : const bool producer_only /* = false*/) const
830 : {
831 9003032 : if (hasActiveBlockObjects(id, tid))
832 4609511 : updateMatPropDependencyHelper(needed_mat_props, getActiveBlockObjects(id, tid), producer_only);
833 9003032 : }
834 :
835 : template <typename T>
836 : void
837 8416192 : MooseObjectWarehouseBase<T>::updateBoundaryMatPropDependency(
838 : std::unordered_set<unsigned int> & needed_mat_props,
839 : THREAD_ID tid /* = 0*/,
840 : const bool producer_only /* = false*/) const
841 : {
842 8416192 : if (hasActiveBoundaryObjects(tid))
843 1524693 : for (auto & active_bnd_object : _active_boundary_objects[tid])
844 1073586 : updateMatPropDependencyHelper(needed_mat_props, active_bnd_object.second, producer_only);
845 8416192 : }
846 :
847 : template <typename T>
848 : void
849 17113711 : MooseObjectWarehouseBase<T>::updateBoundaryMatPropDependency(
850 : BoundaryID id,
851 : std::unordered_set<unsigned int> & needed_mat_props,
852 : THREAD_ID tid /* = 0*/,
853 : const bool producer_only /* = false*/) const
854 : {
855 17113711 : if (hasActiveBoundaryObjects(id, tid))
856 15367 : updateMatPropDependencyHelper(
857 : needed_mat_props, getActiveBoundaryObjects(id, tid), producer_only);
858 17113711 : }
859 :
860 : template <typename T>
861 : void
862 5887185 : MooseObjectWarehouseBase<T>::updateMatPropDependencyHelper(
863 : std::unordered_set<unsigned int> & needed_mat_props,
864 : const std::vector<std::shared_ptr<T>> & objects,
865 : const bool /* producer_only */) const
866 : {
867 18612490 : for (auto & object : objects)
868 : {
869 12725305 : auto c = dynamic_cast<const MaterialPropertyInterface *>(object.get());
870 12725305 : if (c)
871 : {
872 12692082 : auto & mp_deps = c->getMatPropDependencies();
873 12692082 : needed_mat_props.insert(mp_deps.begin(), mp_deps.end());
874 : }
875 : }
876 5887185 : }
877 :
878 : template <typename T>
879 : void
880 223058 : MooseObjectWarehouseBase<T>::subdomainsCovered(std::set<SubdomainID> & subdomains_covered,
881 : std::set<std::string> & unique_variables,
882 : THREAD_ID tid /*=0*/) const
883 : {
884 303131 : for (const auto & object : _active_objects[tid])
885 : {
886 80073 : unique_variables.insert(object->variable().name());
887 80073 : const auto additional_variables_covered = object->additionalROVariables();
888 80073 : unique_variables.insert(additional_variables_covered.begin(),
889 : additional_variables_covered.end());
890 : }
891 :
892 269520 : for (const auto & object_pair : _active_block_objects[tid])
893 46462 : subdomains_covered.insert(object_pair.first);
894 223058 : }
895 :
896 : template <typename T>
897 : std::string
898 47896 : MooseObjectWarehouseBase<T>::activeObjectsToFormattedString(
899 : const THREAD_ID tid /*=0*/, const std::string & prefix /*="[DBG]"*/) const
900 : {
901 47896 : std::vector<std::string> output;
902 225868 : for (const auto & object : _active_objects[tid])
903 177972 : output.push_back(object->name());
904 95792 : return ConsoleUtils::formatString(MooseUtils::join(output, " "), prefix);
905 47896 : }
906 :
907 : template <typename T>
908 : void
909 16902840 : MooseObjectWarehouseBase<T>::sortHelper(std::vector<std::shared_ptr<T>> & objects)
910 : {
911 : // Do nothing if the vector is empty
912 16902840 : if (objects.empty())
913 16766604 : return;
914 :
915 : try
916 : {
917 : // Sort based on dependencies
918 136236 : DependencyResolverInterface::sort<std::shared_ptr<T>>(objects);
919 : }
920 5 : catch (CyclicDependencyException<std::shared_ptr<T>> & e)
921 : {
922 5 : DependencyResolverInterface::cyclicDependencyError<std::shared_ptr<T>>(
923 : e, "Cyclic dependency detected in object ordering");
924 : }
925 : }
926 :
927 : template <typename T>
928 : inline void
929 2104101155 : MooseObjectWarehouseBase<T>::checkThreadID(THREAD_ID libmesh_dbg_var(tid)) const
930 : {
931 : mooseAssert(tid < _num_threads,
932 : "Attempting to access a thread id ("
933 : << tid << ") greater than the number allowed by the storage item ("
934 : << _num_threads << ")");
935 2104101155 : }
|