LCOV - code coverage report
Current view: top level - include/actions - ActionWarehouse.h (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 48 58 82.8 %
Date: 2025-07-17 01:28:37 Functions: 22 22 100.0 %
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             : #include <string>
      13             : #include <set>
      14             : #include <map>
      15             : #include <vector>
      16             : #include <list>
      17             : #include <ostream>
      18             : 
      19             : // MOOSE includes
      20             : #include "Action.h"
      21             : #include "ConsoleStreamInterface.h"
      22             : 
      23             : /// alias to hide implementation details
      24             : using ActionIterator = std::list<Action *>::iterator;
      25             : 
      26             : class MooseMesh;
      27             : class Syntax;
      28             : class ActionFactory;
      29             : class FEProblem;
      30             : class PhysicsBase;
      31             : 
      32             : /**
      33             :  * Storage for action instances.
      34             :  */
      35             : class ActionWarehouse : public ConsoleStreamInterface
      36             : {
      37             : public:
      38             :   ActionWarehouse(MooseApp & app, Syntax & syntax, ActionFactory & factory);
      39             :   ~ActionWarehouse();
      40             : 
      41             :   /**
      42             :    * Builds all auto-buildable tasks.  This method is typically called after the Parser has
      43             :    * created Actions based on an input file.
      44             :    */
      45             :   void build();
      46             : 
      47             :   /**
      48             :    * This method deletes all of the Actions in the warehouse.
      49             :    */
      50             :   void clear();
      51             : 
      52             :   /**
      53             :    * \p returns a Boolean indicating whether the warehouse is empty or not.
      54             :    */
      55             :   bool empty() const { return _action_blocks.empty(); }
      56             : 
      57             :   /**
      58             :    * This method add an \p Action instance to the warehouse.
      59             :    */
      60             :   void addActionBlock(std::shared_ptr<Action> blk);
      61             : 
      62             :   /**
      63             :    * This method checks the actions stored in the warehouse against the list of required registered
      64             :    * actions to see if all of them have been satisfied.  It should be called before running
      65             :    * a MOOSE problem
      66             :    */
      67             :   void checkUnsatisfiedActions() const;
      68             : 
      69             :   /**
      70             :    * This method is used only during debugging when \p show_actions is set to \p true.
      71             :    * It prints all of the actions sets in the correct dependency resolved order with
      72             :    * all of the Action objects inside.
      73             :    */
      74             :   void printActionDependencySets() const;
      75             : 
      76             :   /**
      77             :    * This method uses the Actions in the warehouse to reproduce the input file.  This method
      78             :    * is useful for debugging as it can assist in finding difficult to track parsing or input
      79             :    * file problems.
      80             :    * @param out A writable \p ostream object where the output will be sent.
      81             :    */
      82             :   void printInputFile(std::ostream & out);
      83             : 
      84             :   ///@{
      85             :   /**
      86             :    * Iterators to the Actions in the warehouse.  Iterators should always be used when executing
      87             :    * Actions to capture dynamically added Actions (meta-Actions).  Meta-Actions are allowed to
      88             :    * create and add additional Actions to the warehouse on the fly.  Those Actions will fire
      89             :    * as long as their associated task hasn't already passed (i.e. matches or is later).
      90             :    */
      91             :   ActionIterator actionBlocksWithActionBegin(const std::string & task);
      92             :   ActionIterator actionBlocksWithActionEnd(const std::string & task);
      93             :   ///@}
      94             : 
      95             :   /**
      96             :    * Returns a reference to all of the actions.
      97             :    */
      98             :   const std::vector<std::shared_ptr<Action>> & allActionBlocks() const;
      99             : 
     100             :   /**
     101             :    * Retrieve a constant list of \p Action pointers associated with the passed in task.
     102             :    * Empty list will be returned if no actions are associated with the task.
     103             :    */
     104             :   const std::list<Action *> & getActionListByName(const std::string & task) const;
     105             : 
     106             :   /**
     107             :    * Retrieve an action with its name and the desired type.
     108             :    * @param name The action name.
     109             :    */
     110             :   template <class T>
     111         356 :   const T & getAction(const std::string & name) const
     112             :   {
     113         356 :     typename std::shared_ptr<T> p;
     114       11340 :     for (auto act_ptr : _all_ptrs)
     115             :     {
     116       10984 :       if (act_ptr->name() == name)
     117             :       {
     118         550 :         p = std::dynamic_pointer_cast<T>(act_ptr);
     119         550 :         if (p)
     120         356 :           break;
     121             :       }
     122             :     }
     123         356 :     if (!p)
     124             :     {
     125           0 :       std::vector<std::string> all_names;
     126           0 :       for (auto act_ptr : _all_ptrs)
     127           0 :         if (!act_ptr->name().empty())
     128           0 :           all_names.push_back(act_ptr->name());
     129             :         else
     130           0 :           all_names.push_back("unnamed");
     131           0 :       mooseError("Action with name '",
     132             :                  name,
     133             :                  "' does not exist.\n These are the Actions that do exist:",
     134             :                  Moose::stringify(all_names));
     135           0 :     }
     136         712 :     return *p;
     137         356 :   }
     138             :   template <class T>
     139         132 :   T * getPhysics(const std::string & name) const
     140             :   {
     141         132 :     auto physics = const_cast<T *>(&getAction<T>(name));
     142         132 :     if (!dynamic_cast<const PhysicsBase *>(physics))
     143           0 :       mooseError("The Physics requested of type '",
     144             :                  MooseUtils::prettyCppType<T>(),
     145             :                  "' and name '",
     146             :                  name,
     147             :                  "' is not derived from the PhysicsBase class");
     148         132 :     return physics;
     149             :   }
     150             : 
     151             :   /**
     152             :    * Retrieve all actions in a specific type ordered by their names.
     153             :    */
     154             :   template <class T>
     155      455671 :   std::vector<const T *> getActions()
     156             :   {
     157             :     // we need to create the map first to ensure that all actions in the map are unique
     158             :     // and the actions are sorted by their names
     159      455671 :     typename std::map<std::string, const std::shared_ptr<T>> actions;
     160    23304168 :     for (auto act_ptr : _all_ptrs)
     161             :     {
     162    22848497 :       auto p = std::dynamic_pointer_cast<T>(act_ptr);
     163    22848497 :       if (p)
     164      455769 :         actions.insert(std::make_pair(act_ptr->name(), p));
     165             :     }
     166             :     // construct the vector from the map entries
     167      455671 :     std::vector<const T *> action_vector;
     168      911440 :     for (auto & pair : actions)
     169      455769 :       action_vector.push_back(pair.second.get());
     170      911342 :     return action_vector;
     171      455671 :   }
     172             : 
     173             :   /**
     174             :    * Retrieve all Physics with a specific type ordered by their names
     175             :    */
     176             :   template <class T>
     177             :   std::vector<T *> getPhysics()
     178             :   {
     179             :     const auto physics_vector = getActions<T>();
     180             :     for (const auto phys_ptr : physics_vector)
     181             :       if (!dynamic_cast<const PhysicsBase *>(phys_ptr))
     182             :         mooseError("The Physics requested of type '",
     183             :                    MooseUtils::prettyCppType<T>(),
     184             :                    "' and name '",
     185             :                    phys_ptr->name(),
     186             :                    "' is not derived from the PhysicsBase class");
     187             :     return physics_vector;
     188             :   }
     189             : 
     190             :   /**
     191             :    * Retrieve the action on a specific task with its type.
     192             :    * Error will be thrown if more than one actions are found.
     193             :    * @param task The task name.
     194             :    * @return The action pointer. Null means that such an action does not exist.
     195             :    */
     196             :   template <class T>
     197      112643 :   const T * getActionByTask(const std::string & task)
     198             :   {
     199      112643 :     const auto it = _action_blocks.find(task);
     200      112643 :     if (it == _action_blocks.end())
     201          36 :       return nullptr;
     202             : 
     203      112607 :     T * p = nullptr;
     204      188567 :     for (const auto & action : it->second)
     205             :     {
     206       75960 :       T * tp = dynamic_cast<T *>(action);
     207       75960 :       if (tp)
     208             :       {
     209       75960 :         if (p)
     210           0 :           mooseError("More than one actions have been detected in getActionByTask for the task '",
     211             :                      task,
     212             :                      "' in the app '",
     213           0 :                      getMooseAppName(),
     214             :                      "'");
     215             :         else
     216       75960 :           p = tp;
     217             :       }
     218             :     }
     219      112607 :     return p;
     220             :   }
     221             : 
     222             :   void setFinalTask(const std::string & task);
     223             : 
     224             :   /**
     225             :    * Check if Actions associated with passed in task exist.
     226             :    */
     227             :   bool hasActions(const std::string & task) const;
     228             : 
     229             :   /**
     230             :    * This method loops over all actions in the warehouse and executes them.  Meta-actions
     231             :    * may add new actions to the warehouse on the fly and they will still be executed in order
     232             :    */
     233             :   void executeAllActions();
     234             : 
     235             :   /**
     236             :    * This method executes only the actions in the warehouse that satisfy the task
     237             :    * passed in.
     238             :    */
     239             :   void executeActionsWithAction(const std::string & name);
     240             : 
     241             :   /**
     242             :    * This method sets a Boolean which is used to print information about action dependencies
     243             :    * before various warehouse operations during the problem setup phase.
     244             :    * @param state Flag indicating whether to print action dependencies.
     245             :    */
     246        1623 :   void showActionDependencies(bool state = true) { _show_action_dependencies = state; }
     247             : 
     248             :   /**
     249             :    * This method sets a Boolean which is used to show information about action execution
     250             :    * of various warehouse operations during the problem setup phase.
     251             :    * @param state Flag indicating whether to show action information.
     252             :    */
     253        1623 :   void showActions(bool state = true) { _show_actions = state; }
     254             : 
     255             :   /**
     256             :    * This method sets a Boolean which is used to show debugging information when
     257             :    * actions are inserted in the warehouse by the parser.
     258             :    * @param state Flag indicating whether to show action insertion.
     259             :    */
     260        1623 :   void showParser(bool state = true) { _show_parser = state; }
     261             : 
     262             :   //// Getters
     263       62764 :   Syntax & syntax() { return _syntax; }
     264             : 
     265             :   // We are not really using the reference counting capabilities of
     266             :   // shared pointers here, just their memory management capability.
     267             :   // Therefore, _mesh is actually being used more like a unique_ptr in
     268             :   // this context.  Since full support for unique_ptr is not quite
     269             :   // available yet, we've implemented it as a std::shared_ptr.
     270     3402707 :   std::shared_ptr<MooseMesh> & mesh() { return _mesh; }
     271       23649 :   const std::shared_ptr<MooseMesh> & getMesh() const { return _mesh; }
     272             : 
     273     3131324 :   std::shared_ptr<MooseMesh> & displacedMesh() { return _displaced_mesh; }
     274          95 :   const std::shared_ptr<MooseMesh> & getDisplacedMesh() const { return _displaced_mesh; }
     275             : 
     276     6530607 :   std::shared_ptr<FEProblemBase> & problemBase() { return _problem; }
     277             :   std::shared_ptr<FEProblem> problem();
     278       33251 :   MooseApp & mooseApp() { return _app; }
     279             :   const std::string & getMooseAppName();
     280     3345938 :   const std::string & getCurrentTaskName() const { return _current_task; }
     281             : 
     282             :   /**
     283             :    * @return The current action that is running, if any
     284             :    */
     285     2469723 :   const Action * getCurrentAction() const { return _current_action; }
     286             :   /**
     287             :    * @return The name of the current action that is running
     288             :    */
     289             :   std::string getCurrentActionName() const;
     290             : 
     291             :   /**
     292             :    * @returns True if a task with the name \p task is registered.
     293             :    */
     294             :   bool hasTask(const std::string & task) const;
     295             :   /**
     296             :    * @returns True if the registered task with the name \p task is complete.
     297             :    */
     298             :   bool isTaskComplete(const std::string & task) const;
     299             : 
     300             : protected:
     301             :   /**
     302             :    * This method auto-builds all Actions that needs to be built and adds them to ActionWarehouse.
     303             :    * An Action needs to be built if it is associated with a task that is marked as required and
     304             :    * all of it's parameters are valid (are not required or have default values supplied).
     305             :    *
     306             :    * @param task The name of the task to find and build Actions for.
     307             :    */
     308             :   void buildBuildableActions(const std::string & task);
     309             : 
     310             :   std::vector<std::shared_ptr<Action>> _all_ptrs;
     311             : 
     312             :   /// The MooseApp this Warehouse is associated with
     313             :   MooseApp & _app;
     314             :   /// Reference to a "syntax" of actions
     315             :   Syntax & _syntax;
     316             :   /// The Factory that builds Actions
     317             :   ActionFactory & _action_factory;
     318             :   /// Pointers to the actual parsed input file blocks
     319             :   std::map<std::string, std::list<Action *>> _action_blocks;
     320             :   /// The container that holds the sorted action names from the DependencyResolver
     321             :   std::vector<std::string> _ordered_names;
     322             :   /// The completed tasks
     323             :   std::set<std::string> _completed_tasks;
     324             :   /// Use to store the current list of unsatisfied dependencies
     325             :   std::set<std::string> _unsatisfied_dependencies;
     326             : 
     327             :   /**
     328             :    *  Flag to indicate whether or not there is an active iterator on this class.
     329             :    *  There can only be a single active iterator because of the potential for
     330             :    *  meta Actions to add new Actions into the warehouse on the fly
     331             :    */
     332             :   bool _generator_valid;
     333             : 
     334             :   /// Whether or not the action warehouse prints the action dependency information
     335             :   bool _show_action_dependencies;
     336             :   /// Whether or not the action warehouse prints the action execution information
     337             :   bool _show_actions;
     338             :   /// Whether or not to print messages when actions are inserted in the warehouse by the parser
     339             :   bool _show_parser;
     340             : 
     341             :   // When executing the actions in the warehouse, this string will always contain
     342             :   // the current task name
     343             :   std::string _current_task;
     344             :   // The current action that is running
     345             :   Action * _current_action;
     346             : 
     347             :   //
     348             :   // data created by actions
     349             :   //
     350             : 
     351             :   /// Mesh class
     352             :   std::shared_ptr<MooseMesh> _mesh;
     353             : 
     354             :   /// Possible mesh for displaced problem
     355             :   std::shared_ptr<MooseMesh> _displaced_mesh;
     356             : 
     357             :   /// Problem class
     358             :   std::shared_ptr<FEProblemBase> _problem;
     359             : 
     360             : private:
     361             :   /// Last task to run before (optional) early termination - blank means no early termination.
     362             :   std::string _final_task;
     363             : 
     364             :   const std::list<Action *> _empty_action_list;
     365             : 
     366             :   /// Mutex for preventing read/write races for _completed_tasks
     367             :   mutable std::mutex _completed_tasks_mutex;
     368             : };

Generated by: LCOV version 1.14