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 : #include "AppFactory.h" 11 : #include "CommandLine.h" 12 : #include "InputParameters.h" 13 : #include "MooseApp.h" 14 : #include "Parser.h" 15 : #include "MooseMain.h" 16 : 17 : AppFactory & 18 628884 : AppFactory::instance() 19 : { 20 : // We need a naked new here (_not_ a smart pointer or object instance) due to what seems like a 21 : // bug in clang's static object destruction when using dynamic library loading. 22 : static AppFactory * instance = nullptr; 23 628884 : if (!instance) 24 51208 : instance = new AppFactory; 25 628884 : return *instance; 26 : } 27 : 28 3 : AppFactory::~AppFactory() {} 29 : 30 : InputParameters 31 62752 : AppFactory::getValidParams(const std::string & name) 32 : { 33 62752 : if (const auto it = _name_to_build_info.find(name); it != _name_to_build_info.end()) 34 62752 : return it->second->buildParameters(); 35 : 36 0 : mooseError(std::string("A '") + name + "' is not a registered object\n\n"); 37 : } 38 : 39 : const InputParameters & 40 251021 : AppFactory::getAppParams(const InputParameters & params) const 41 : { 42 251021 : const auto id = getAppParamsID(params); 43 251021 : if (const auto it = _input_parameters.find(id); it != _input_parameters.end()) 44 251021 : return *it->second; 45 0 : mooseError("AppFactory::getAppParams(): Parameters for application with ID ", id, " not found"); 46 : } 47 : 48 : void 49 57256 : AppFactory::clearAppParams(const InputParameters & params, const ClearAppParamsKey) 50 : { 51 57256 : const auto id = getAppParamsID(params); 52 57256 : if (const auto it = _input_parameters.find(id); it != _input_parameters.end()) 53 57255 : _input_parameters.erase(it); 54 : else 55 1 : mooseError( 56 : "AppFactory::clearAppParams(): Parameters for application with ID ", id, " not found"); 57 57255 : } 58 : 59 : MooseAppPtr 60 51354 : AppFactory::createAppShared(int argc, char ** argv, std::unique_ptr<Parser> parser) 61 : { 62 : mooseAssert(parser, "Not set"); 63 : mooseAssert(parser->getAppType().size(), "App type not set"); 64 51354 : const std::string app_type = parser->getAppType(); 65 : 66 51354 : auto command_line = std::make_unique<CommandLine>(argc, argv); 67 51354 : command_line->parse(); 68 : 69 51354 : auto app_params = AppFactory::instance().getValidParams(parser->getAppType()); 70 51354 : app_params.set<int>("_argc") = argc; 71 51354 : app_params.set<char **>("_argv") = argv; 72 51354 : app_params.set<std::shared_ptr<CommandLine>>("_command_line") = std::move(command_line); 73 51354 : app_params.set<std::shared_ptr<Parser>>("_parser") = std::move(parser); 74 : 75 102704 : return AppFactory::instance().createShared(app_type, "main", app_params, MPI_COMM_WORLD); 76 51350 : } 77 : 78 : MooseAppPtr 79 0 : AppFactory::createAppShared(const std::string & default_app_type, 80 : int argc, 81 : char ** argv, 82 : MPI_Comm comm_world_in) 83 : { 84 0 : mooseDeprecated("Please update your main.C to adapt new main function in MOOSE framework, " 85 : "see'test/src/main.C in MOOSE as an example of moose::main()'. "); 86 : 87 0 : auto command_line_params = emptyInputParameters(); 88 0 : MooseApp::addInputParam(command_line_params); 89 0 : MooseApp::addAppParam(command_line_params); 90 : 91 : { 92 0 : CommandLine pre_command_line(argc, argv); 93 0 : pre_command_line.parse(); 94 0 : pre_command_line.populateCommandLineParams(command_line_params); 95 0 : } 96 : 97 0 : const auto & input_filenames = command_line_params.get<std::vector<std::string>>("input_file"); 98 0 : auto parser = std::make_unique<Parser>(input_filenames); 99 0 : if (input_filenames.size()) 100 0 : parser->parse(); 101 : 102 0 : std::string app_type = command_line_params.get<std::string>("app_to_run"); 103 0 : if (app_type.empty()) 104 0 : app_type = default_app_type; 105 : else 106 0 : mooseDeprecated("Please use [Application] block to specify application type, '--app <AppName>' " 107 : "is deprecated and will be removed in a future release."); 108 : 109 0 : parser->setAppType(app_type); 110 0 : auto app_params = AppFactory::instance().getValidParams(app_type); 111 : 112 0 : app_params.set<int>("_argc") = argc; 113 0 : app_params.set<char **>("_argv") = argv; 114 : 115 0 : auto command_line = std::make_unique<CommandLine>(argc, argv); 116 0 : command_line->parse(); 117 0 : app_params.set<std::shared_ptr<CommandLine>>("_command_line") = std::move(command_line); 118 : 119 : // Take the front parser and add it to the parameters so that it can be retrieved in the 120 : // Application 121 0 : app_params.set<std::shared_ptr<Parser>>("_parser") = std::move(parser); 122 : 123 0 : return AppFactory::instance().createShared(app_type, "main", app_params, comm_world_in); 124 0 : } 125 : 126 : MooseAppPtr 127 62755 : AppFactory::createShared(const std::string & app_type, 128 : const std::string & name, 129 : InputParameters parameters, 130 : MPI_Comm comm_world_in) 131 : { 132 : // Error if the application type is not located 133 62755 : const auto it = _name_to_build_info.find(app_type); 134 62755 : if (it == _name_to_build_info.end()) 135 0 : mooseError("Object '" + app_type + "' was not registered."); 136 62755 : auto & build_info = it->second; 137 : 138 : // Take the app_type and add it to the parameters so that it can be retrieved in the Application 139 62755 : parameters.set<std::string>("_type") = app_type; 140 : 141 62755 : auto comm = std::make_shared<Parallel::Communicator>(comm_world_in); 142 : 143 62755 : parameters.set<std::shared_ptr<Parallel::Communicator>>("_comm") = comm; 144 62755 : parameters.set<std::string>("_app_name") = name; 145 : 146 62755 : if (!parameters.isParamValid("_command_line")) 147 0 : mooseError("Valid CommandLine object required"); 148 : 149 : std::shared_ptr<CommandLine> command_line = 150 62755 : parameters.get<std::shared_ptr<CommandLine>>("_command_line"); 151 : mooseAssert(command_line->hasParsed(), "Should have been parsed"); 152 : 153 62755 : command_line->populateCommandLineParams(parameters); 154 : 155 : // Historically we decided to non-const copy construct all application parameters. In 156 : // order to get around that while apps are fixed (by taking a const reference instead), 157 : // we store the app params here and the MooseApp constructor will query the InputParameters 158 : // owned by ths factory instead of the ones that are passed to it (likely a const ref to a 159 : // copy of the derived app's parmeters) 160 62755 : const auto & params = storeAppParams(parameters); 161 : 162 62755 : build_info->_app_creation_count++; 163 : 164 125505 : return build_info->build(params); 165 62752 : } 166 : 167 : std::size_t 168 0 : AppFactory::createdAppCount(const std::string & app_type) const 169 : { 170 : // Error if the application type is not located 171 0 : const auto it = _name_to_build_info.find(app_type); 172 0 : if (it == _name_to_build_info.end()) 173 0 : mooseError("AppFactory::createdAppCount(): '", app_type, "' is not a registered app"); 174 : 175 0 : return it->second->_app_creation_count; 176 : } 177 : 178 : const InputParameters & 179 62757 : AppFactory::storeAppParams(InputParameters & params) 180 : { 181 : const std::size_t next_id = 182 62757 : _input_parameters.size() ? (std::prev(_input_parameters.end())->first + 1) : 0; 183 62757 : params.addPrivateParam<std::size_t>("_app_params_id", next_id); 184 : const auto it_inserted_pair = 185 62757 : _input_parameters.emplace(next_id, std::make_unique<InputParameters>(params)); 186 : mooseAssert(it_inserted_pair.second, "Already exists"); 187 62757 : auto & stored_params = *it_inserted_pair.first->second; 188 62757 : stored_params.finalize(""); 189 62757 : return stored_params; 190 : } 191 : 192 : std::size_t 193 308281 : AppFactory::getAppParamsID(const InputParameters & params) const 194 : { 195 308281 : if (!params.have_parameter<std::size_t>("_app_params_id")) 196 1 : mooseError("AppFactory::getAppParamsID(): Invalid application parameters (missing " 197 : "'_app_params_id')"); 198 308280 : return params.get<std::size_t>("_app_params_id"); 199 : }