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 33612595 : MooseObjectWarehouseBase<T>::MooseObjectWarehouseBase(bool threaded /*=true*/)
280 31612219 : : _num_threads(threaded ? libMesh::n_threads() : 1),
281 63224438 : _all_objects(_num_threads),
282 63224438 : _active_objects(_num_threads),
283 63224438 : _all_block_objects(_num_threads),
284 63224438 : _active_block_objects(_num_threads),
285 63224438 : _all_boundary_objects(_num_threads),
286 63224438 : _active_boundary_objects(_num_threads),
287 94836657 : _all_variable_objects(_num_threads)
288 : {
289 31755103 : }
290 :
291 : template <typename T>
292 85188160 : MooseObjectWarehouseBase<T>::~MooseObjectWarehouseBase()
293 : {
294 85188160 : }
295 :
296 : template <typename T>
297 : unsigned int
298 18308447 : MooseObjectWarehouseBase<T>::size(THREAD_ID tid /* =0 */) const
299 : {
300 18308447 : checkThreadID(tid);
301 18308447 : return _all_objects[tid].size();
302 : }
303 :
304 : template <typename T>
305 : void
306 1327001 : MooseObjectWarehouseBase<T>::addObject(std::shared_ptr<T> object,
307 : THREAD_ID tid /*= 0*/,
308 : bool /* recurse = true */)
309 : {
310 1327001 : checkThreadID(tid);
311 :
312 : // Stores object in list of all objects
313 1327001 : _all_objects[tid].push_back(object);
314 :
315 : // If enabled, store object in a list of all active
316 1327001 : bool enabled = object->enabled();
317 1327001 : if (enabled)
318 1326358 : _active_objects[tid].push_back(object);
319 :
320 : // Perform casts to the Block/BoundaryRestrictable
321 1327001 : std::shared_ptr<BoundaryRestrictable> bnd =
322 : std::dynamic_pointer_cast<BoundaryRestrictable>(object);
323 1327001 : std::shared_ptr<BlockRestrictable> blk = std::dynamic_pointer_cast<BlockRestrictable>(object);
324 :
325 : // Boundary Restricted
326 1327001 : 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 935049 : 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 1326983 : }
377 :
378 : template <typename T>
379 : inline const std::vector<std::shared_ptr<T>> &
380 16392553 : MooseObjectWarehouseBase<T>::getObjects(THREAD_ID tid /* = 0*/) const
381 : {
382 16392553 : checkThreadID(tid);
383 16392553 : 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 48802498 : MooseObjectWarehouseBase<T>::getActiveObjects(THREAD_ID tid /* = 0*/) const
435 : {
436 48802498 : checkThreadID(tid);
437 48802498 : 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 67540358 : MooseObjectWarehouseBase<T>::getActiveBoundaryObjects(BoundaryID id, THREAD_ID tid /* = 0*/) const
451 : {
452 67540358 : checkThreadID(tid);
453 67540358 : 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 135080716 : return iter->second;
457 : }
458 :
459 : template <typename T>
460 : inline const std::map<SubdomainID, std::vector<std::shared_ptr<T>>> &
461 22892284 : MooseObjectWarehouseBase<T>::getActiveBlockObjects(THREAD_ID tid /* = 0*/) const
462 : {
463 22892284 : checkThreadID(tid);
464 22892284 : return _active_block_objects[tid];
465 : }
466 :
467 : template <typename T>
468 : const std::vector<std::shared_ptr<T>> &
469 399774002 : MooseObjectWarehouseBase<T>::getActiveBlockObjects(SubdomainID id, THREAD_ID tid /* = 0*/) const
470 : {
471 399774002 : checkThreadID(tid);
472 399774002 : 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 799548004 : return iter->second;
476 : }
477 :
478 : template <typename T>
479 : bool
480 270332 : MooseObjectWarehouseBase<T>::hasObjects(THREAD_ID tid /* = 0*/) const
481 : {
482 270332 : checkThreadID(tid);
483 270332 : return !_all_objects[tid].empty();
484 : }
485 :
486 : template <typename T>
487 : bool
488 54929852 : MooseObjectWarehouseBase<T>::hasActiveObjects(THREAD_ID tid /* = 0*/) const
489 : {
490 54929852 : checkThreadID(tid);
491 54929852 : 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 15748777 : MooseObjectWarehouseBase<T>::hasActiveBlockObjects(THREAD_ID tid /* = 0*/) const
545 : {
546 15748777 : checkThreadID(tid);
547 15748777 : bool has_active_block_objects = false;
548 16003413 : for (const auto & object_pair : _active_block_objects[tid])
549 254636 : has_active_block_objects |= !(object_pair.second.empty());
550 15748777 : return has_active_block_objects;
551 : }
552 :
553 : template <typename T>
554 : bool
555 515527306 : MooseObjectWarehouseBase<T>::hasActiveBlockObjects(SubdomainID id, THREAD_ID tid /* = 0*/) const
556 : {
557 515527306 : checkThreadID(tid);
558 515527306 : const auto iter = _active_block_objects[tid].find(id);
559 515527306 : return iter != _active_block_objects[tid].end();
560 : }
561 :
562 : template <typename T>
563 : bool
564 35921726 : MooseObjectWarehouseBase<T>::hasActiveBoundaryObjects(THREAD_ID tid /* = 0*/) const
565 : {
566 35921726 : checkThreadID(tid);
567 35921726 : bool has_active_boundary_objects = false;
568 38326936 : for (const auto & object_pair : _active_boundary_objects[tid])
569 2405210 : has_active_boundary_objects |= !(object_pair.second.empty());
570 35921726 : return has_active_boundary_objects;
571 : }
572 :
573 : template <typename T>
574 : bool
575 397349963 : MooseObjectWarehouseBase<T>::hasActiveBoundaryObjects(BoundaryID id, THREAD_ID tid /* = 0*/) const
576 : {
577 397349963 : checkThreadID(tid);
578 397349963 : const auto iter = _active_boundary_objects[tid].find(id);
579 397349963 : return iter != _active_boundary_objects[tid].end();
580 : }
581 :
582 : template <typename T>
583 : bool
584 297702 : MooseObjectWarehouseBase<T>::hasActiveObject(const std::string & name, THREAD_ID tid /* = 0*/) const
585 : {
586 297702 : checkThreadID(tid);
587 502754 : for (const auto & object : _active_objects[tid])
588 479807 : if (object->name() == name)
589 274755 : return true;
590 22947 : 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 1196112 : MooseObjectWarehouseBase<T>::getActiveObject(const std::string & name, THREAD_ID tid /* = 0*/) const
607 : {
608 1196112 : checkThreadID(tid);
609 1615248 : for (const auto & object : _active_objects[tid])
610 1615245 : if (object->name() == name)
611 1196109 : 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 59744 : MooseObjectWarehouseBase<T>::getActiveBlocks(THREAD_ID tid /* = 0*/) const
626 : {
627 59744 : checkThreadID(tid);
628 59744 : std::set<SubdomainID> ids;
629 72263 : for (const auto & object_pair : _active_block_objects[tid])
630 12519 : ids.insert(object_pair.first);
631 59744 : return ids;
632 0 : }
633 :
634 : template <typename T>
635 : void
636 180295246 : MooseObjectWarehouseBase<T>::updateActive(THREAD_ID tid /*= 0*/)
637 : {
638 180295246 : checkThreadID(tid);
639 :
640 180295246 : updateActiveHelper(_active_objects[tid], _all_objects[tid]);
641 :
642 182025782 : for (const auto & object_pair : _all_block_objects[tid])
643 1730536 : updateActiveHelper(_active_block_objects[tid][object_pair.first], object_pair.second);
644 :
645 183866950 : for (const auto & object_pair : _all_boundary_objects[tid])
646 3571704 : updateActiveHelper(_active_boundary_objects[tid][object_pair.first], object_pair.second);
647 180295246 : }
648 :
649 : template <typename T>
650 : void
651 185597486 : 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 185597486 : active.clear();
656 :
657 185701572 : std::copy_if(all.begin(),
658 : all.end(),
659 : std::back_inserter(active),
660 16227900 : [](const std::shared_ptr<T> & object) { return object->enabled(); });
661 185597486 : }
662 :
663 : template <typename T>
664 : void
665 16653840 : MooseObjectWarehouseBase<T>::sort(THREAD_ID tid /* = 0*/)
666 : {
667 16653840 : checkThreadID(tid);
668 :
669 16704393 : for (auto & object_pair : _all_block_objects[tid])
670 50553 : sortHelper(object_pair.second);
671 :
672 16659780 : for (auto & object_pair : _all_boundary_objects[tid])
673 5940 : sortHelper(object_pair.second);
674 :
675 16653840 : sortHelper(_all_objects[tid]);
676 :
677 : // The active lists now must be update to reflect the order changes
678 16653840 : updateActive(tid);
679 16653840 : }
680 :
681 : template <typename T>
682 : void
683 1186891 : MooseObjectWarehouseBase<T>::updateVariableDependency(
684 : std::set<MooseVariableFieldBase *> & needed_moose_vars, THREAD_ID tid /* = 0*/) const
685 : {
686 1186891 : if (hasActiveObjects(tid))
687 909899 : updateVariableDependencyHelper(needed_moose_vars, _active_objects[tid]);
688 1186891 : }
689 :
690 : template <typename T>
691 : void
692 9067002 : MooseObjectWarehouseBase<T>::updateBlockVariableDependency(
693 : SubdomainID id,
694 : std::set<MooseVariableFieldBase *> & needed_moose_vars,
695 : THREAD_ID tid /* = 0*/) const
696 : {
697 9067002 : if (hasActiveBlockObjects(id, tid))
698 4343411 : updateVariableDependencyHelper(needed_moose_vars, getActiveBlockObjects(id, tid));
699 9067002 : }
700 :
701 : template <typename T>
702 : void
703 9067002 : MooseObjectWarehouseBase<T>::updateBoundaryVariableDependency(
704 : std::set<MooseVariableFieldBase *> & needed_moose_vars, THREAD_ID tid /* = 0*/) const
705 : {
706 9067002 : if (hasActiveBoundaryObjects(tid))
707 : {
708 466255 : typename std::map<BoundaryID, std::vector<std::shared_ptr<T>>>::const_iterator it;
709 1572325 : for (const auto & object_pair : _active_boundary_objects[tid])
710 1106070 : updateVariableDependencyHelper(needed_moose_vars, object_pair.second);
711 : }
712 9067002 : }
713 :
714 : template <typename T>
715 : void
716 18438781 : MooseObjectWarehouseBase<T>::updateBoundaryVariableDependency(
717 : BoundaryID id,
718 : std::set<MooseVariableFieldBase *> & needed_moose_vars,
719 : THREAD_ID tid /* = 0*/) const
720 : {
721 18438781 : if (hasActiveBoundaryObjects(id, tid))
722 16047 : updateVariableDependencyHelper(needed_moose_vars, getActiveBoundaryObjects(id, tid));
723 18438781 : }
724 :
725 : template <typename T>
726 : void
727 6375427 : MooseObjectWarehouseBase<T>::updateVariableDependencyHelper(
728 : std::set<MooseVariableFieldBase *> & needed_moose_vars,
729 : const std::vector<std::shared_ptr<T>> & objects)
730 : {
731 20357028 : for (const auto & object : objects)
732 : {
733 13981601 : auto c = dynamic_cast<const MooseVariableDependencyInterface *>(object.get());
734 13981601 : if (c)
735 : {
736 13981601 : const auto & mv_deps = c->getMooseVariableDependencies();
737 13981601 : needed_moose_vars.insert(mv_deps.begin(), mv_deps.end());
738 : }
739 : }
740 6375427 : }
741 :
742 : template <typename T>
743 : void
744 365222 : MooseObjectWarehouseBase<T>::updateFEVariableCoupledVectorTagDependency(
745 : std::set<TagID> & needed_fe_var_vector_tags, THREAD_ID tid /* = 0*/) const
746 : {
747 365222 : if (hasActiveObjects(tid))
748 245232 : updateFEVariableCoupledVectorTagDependencyHelper(needed_fe_var_vector_tags,
749 144200 : _active_objects[tid]);
750 365222 : }
751 :
752 : template <typename T>
753 : void
754 15416000 : MooseObjectWarehouseBase<T>::updateBlockFEVariableCoupledVectorTagDependency(
755 : SubdomainID id, std::set<TagID> & needed_fe_var_vector_tags, THREAD_ID tid /* = 0*/) const
756 : {
757 15416000 : if (hasActiveBlockObjects(id, tid))
758 5998090 : updateFEVariableCoupledVectorTagDependencyHelper(needed_fe_var_vector_tags,
759 : getActiveBlockObjects(id, tid));
760 15416000 : }
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 6263624 : MooseObjectWarehouseBase<T>::updateFEVariableCoupledVectorTagDependencyHelper(
775 : std::set<TagID> & needed_fe_var_vector_tags, const std::vector<std::shared_ptr<T>> & objects)
776 : {
777 20716249 : for (const auto & object : objects)
778 : {
779 14452625 : auto c = dynamic_cast<const Coupleable *>(object.get());
780 14452625 : if (c)
781 : {
782 14452625 : const auto & tag_deps = c->getFEVariableCoupleableVectorTags();
783 14452625 : needed_fe_var_vector_tags.insert(tag_deps.begin(), tag_deps.end());
784 : }
785 : }
786 6263624 : }
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 212861 : updateMatPropDependencyHelper(needed_mat_props, _active_objects[tid], producer_only);
797 294354 : }
798 :
799 : template <typename T>
800 : void
801 9674969 : 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 9674969 : if (hasActiveBlockObjects(id, tid))
808 4951378 : updateMatPropDependencyHelper(needed_mat_props, getActiveBlockObjects(id, tid), producer_only);
809 9674969 : }
810 :
811 : template <typename T>
812 : void
813 9067002 : 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 9067002 : if (hasActiveBoundaryObjects(tid))
819 1572325 : for (auto & active_bnd_object : _active_boundary_objects[tid])
820 1106070 : updateMatPropDependencyHelper(needed_mat_props, active_bnd_object.second, producer_only);
821 9067002 : }
822 :
823 : template <typename T>
824 : void
825 18438781 : 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 18438781 : if (hasActiveBoundaryObjects(id, tid))
832 16047 : updateMatPropDependencyHelper(
833 : needed_mat_props, getActiveBoundaryObjects(id, tid), producer_only);
834 18438781 : }
835 :
836 : template <typename T>
837 : void
838 6263212 : 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 19911651 : for (auto & object : objects)
844 : {
845 13648439 : auto c = dynamic_cast<const MaterialPropertyInterface *>(object.get());
846 13648439 : if (c)
847 : {
848 13614593 : auto & mp_deps = c->getMatPropDependencies();
849 13614593 : needed_mat_props.insert(mp_deps.begin(), mp_deps.end());
850 : }
851 : }
852 6263212 : }
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 46850 : MooseObjectWarehouseBase<T>::activeObjectsToFormattedString(
875 : const THREAD_ID tid /*=0*/, const std::string & prefix /*="[DBG]"*/) const
876 : {
877 46850 : std::vector<std::string> output;
878 221596 : for (const auto & object : _active_objects[tid])
879 174746 : output.push_back(object->name());
880 93700 : return ConsoleUtils::formatString(MooseUtils::join(output, " "), prefix);
881 46850 : }
882 :
883 : template <typename T>
884 : void
885 16762724 : MooseObjectWarehouseBase<T>::sortHelper(std::vector<std::shared_ptr<T>> & objects)
886 : {
887 : // Do nothing if the vector is empty
888 16762724 : if (objects.empty())
889 16627099 : 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 2116171099 : 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 2116171099 : }
|