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 <vector> 13 : 14 : #include "MooseApp.h" 15 : #include "Capabilities.h" 16 : 17 : #ifdef MOOSE_UNIT_TEST 18 : #include "gtest/gtest.h" 19 : class GTEST_TEST_CLASS_NAME_(AppFactoryTest, manageAppParams); 20 : class GTEST_TEST_CLASS_NAME_(AppFactoryTest, appCopyConstructParams); 21 : #endif 22 : 23 : // Forward declarations 24 : class InputParameters; 25 : 26 : /** 27 : * Macros 28 : */ 29 : #define registerApp(name) AppFactory::instance().reg<name>(#name) 30 : 31 : /** 32 : * alias to wrap shared pointer type 33 : */ 34 : using MooseAppPtr = std::shared_ptr<MooseApp>; 35 : 36 : /** 37 : * Polymorphic data structure with parameter and object build access. 38 : */ 39 : struct AppFactoryBuildInfoBase 40 : { 41 : virtual MooseAppPtr build(const InputParameters & params) = 0; 42 : virtual InputParameters buildParameters() = 0; 43 1 : virtual ~AppFactoryBuildInfoBase() = default; 44 : 45 : std::size_t _app_creation_count = 0; 46 : }; 47 : template <typename T> 48 : struct AppFactoryBuildInfo : public AppFactoryBuildInfoBase 49 : { 50 62730 : virtual MooseAppPtr build(const InputParameters & params) override 51 : { 52 62730 : return std::make_shared<T>(params); 53 : } 54 62727 : virtual InputParameters buildParameters() override { return T::validParams(); } 55 : }; 56 : 57 : using AppFactoryBuildInfoMap = std::map<std::string, std::unique_ptr<AppFactoryBuildInfoBase>>; 58 : 59 : /** 60 : * Generic AppFactory class for building Application objects 61 : */ 62 : class AppFactory 63 : { 64 : public: 65 : /** 66 : * Get the instance of the AppFactory 67 : * @return Reference to the AppFactory instance 68 : */ 69 : static AppFactory & instance(); 70 : 71 : virtual ~AppFactory(); 72 : 73 : static InputParameters validParams(); 74 : /** 75 : * Helper function for creating a MooseApp from command-line arguments and a Parser. 76 : * 77 : * The parser must be set and have an app type set. 78 : */ 79 : static MooseAppPtr createAppShared(int argc, char ** argv, std::unique_ptr<Parser> parser); 80 : 81 : /** 82 : * Deprecated helper function for creating a MooseApp for Apps haven't adapted to the new Parser 83 : * and Builder changes. This function needed to be removed after the new Parser and Builder merged 84 : */ 85 : static MooseAppPtr createAppShared(const std::string & default_app_type, 86 : int argc, 87 : char ** argv, 88 : MPI_Comm comm_word = MPI_COMM_WORLD); 89 : 90 : /** 91 : * Register a new object 92 : * @param name Name of the object to register 93 : */ 94 : template <typename T> 95 : void reg(const std::string & name); 96 : 97 : /** 98 : * Get valid parameters for the object 99 : * @param name Name of the object whose parameter we are requesting 100 : * @return Parameters of the object 101 : */ 102 : InputParameters getValidParams(const std::string & name); 103 : 104 : /** 105 : * @return The parameters for the application named \p name 106 : * 107 : * This is needed because we poorly decided to not pass references 108 : * of the InputParameters in all derived MooseApp objects. This enables 109 : * the MooseApp to get the copy of the parameters that it was actually 110 : * built with using this factory. 111 : */ 112 : const InputParameters & getAppParams(const InputParameters & params) const; 113 : 114 : /** 115 : * Class that is used as a parameter to clearAppParams() that allows only 116 : * MooseApp to call clearAppParams(). 117 : */ 118 : class ClearAppParamsKey 119 : { 120 : friend class MooseApp; 121 : #ifdef MOOSE_UNIT_TEST 122 : FRIEND_TEST(::AppFactoryTest, manageAppParams); 123 : #endif 124 57256 : ClearAppParamsKey() {} 125 : ClearAppParamsKey(const ClearAppParamsKey &) {} 126 : }; 127 : 128 : /** 129 : * Clears the stored parameters for the given application parameteres 130 : * 131 : * See getAppParams() for why this is needed. 132 : */ 133 : void clearAppParams(const InputParameters & params, const ClearAppParamsKey); 134 : 135 : /** 136 : * Build an application object (must be registered) 137 : * @param app_type Type of the application being constructed 138 : * @param name Name for the object 139 : * @param parameters Parameters this object should have 140 : * @return The created object 141 : */ 142 : MooseAppPtr createShared(const std::string & app_type, 143 : const std::string & name, 144 : InputParameters parameters, 145 : MPI_Comm COMM_WORLD_IN); 146 : 147 : /** 148 : * Returns a reference to the map from names to AppFactoryBuildInfo pointers 149 : */ 150 85576 : const auto & registeredObjects() const { return _name_to_build_info; } 151 : 152 : /** 153 : * Returns a Boolean indicating whether an application type has been registered 154 : */ 155 109480 : bool isRegistered(const std::string & app_name) const 156 : { 157 109480 : return _name_to_build_info.count(app_name); 158 : } 159 : 160 : /** 161 : * @returns the amount of times the AppFactory created the named App-type 162 : */ 163 : std::size_t createdAppCount(const std::string & app_type) const; 164 : 165 : /** 166 : * Returns the map of object name to a function pointer for building said object's 167 : * input parameters. 168 : */ 169 : const AppFactoryBuildInfoMap & registeredObjectBuildInfos() const { return _name_to_build_info; } 170 : 171 : ///@{ Don't allow creation through copy/move construction or assignment 172 : AppFactory(AppFactory const &) = delete; 173 : Registry & operator=(AppFactory const &) = delete; 174 : 175 : AppFactory(AppFactory &&) = delete; 176 : Registry & operator=(AppFactory &&) = delete; 177 : ///@} 178 : 179 : protected: 180 : AppFactoryBuildInfoMap _name_to_build_info; 181 : 182 : private: 183 : // Private constructor for singleton pattern 184 51211 : AppFactory() {} 185 : 186 : /** 187 : * Stores the given parameters within _input_parameters for app construction 188 : * 189 : * Also calls finalize() on the parameters. 190 : */ 191 : const InputParameters & storeAppParams(InputParameters & params); 192 : 193 : /** 194 : * Get the ID for the InputParameters associated with an application, used 195 : * in storing them in _input_parameters. 196 : * 197 : * This is needed until app constructors do not copy construct parameters. 198 : * See getAppParams() for more information. 199 : * 200 : * The parameters passed in here (from the app) could be copy-constructed 201 : * parameters, but will contain a "_app_params_id" parameter that allows 202 : * us to get the actual parameters (owned by this factory). 203 : */ 204 : std::size_t getAppParamsID(const InputParameters & params) const; 205 : 206 : #ifdef MOOSE_UNIT_TEST 207 : FRIEND_TEST(::AppFactoryTest, manageAppParams); 208 : FRIEND_TEST(::AppFactoryTest, appCopyConstructParams); 209 : #endif 210 : 211 : /// Storage of input parameters used in applications (ID (from getAppParamsID()) -> params) 212 : std::map<std::size_t, std::unique_ptr<InputParameters>> _input_parameters; 213 : }; 214 : 215 : template <typename T> 216 : void 217 51187 : AppFactory::reg(const std::string & name) 218 : { 219 51187 : if (isRegistered(name)) 220 0 : return; 221 : 222 51187 : _name_to_build_info[name] = std::make_unique<AppFactoryBuildInfo<T>>(); 223 153561 : Moose::Capabilities::getCapabilityRegistry().add( 224 102374 : name, true, "MOOSE application " + name + " is available."); 225 : }