LCOV - code coverage report
Current view: top level - include/warehouses - MooseObjectWarehouseBase.h (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 419b9d Lines: 258 270 95.6 %
Date: 2025-08-08 20:01:16 Functions: 488 624 78.2 %
Legend: Lines: hit not hit

          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 : }

Generated by: LCOV version 1.14