https://mooseframework.inl.gov
Loading...
Searching...
No Matches
AppFactory.C
Go to the documentation of this file.
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#include "Capabilities.h"
17#include "MooseStringUtils.h"
18
21{
22 // We need a naked new here (_not_ a smart pointer or object instance) due to what seems like a
23 // bug in clang's static object destruction when using dynamic library loading.
24 static AppFactory * instance = nullptr;
25 if (!instance)
26 instance = new AppFactory;
27 return *instance;
28}
29
31
32const std::string AppFactory::main_app_name = "main";
33
35AppFactory::getValidParams(const std::string & name)
36{
37 if (const auto it = _name_to_build_info.find(name); it != _name_to_build_info.end())
38 return it->second->buildParameters();
39
40 mooseError(std::string("A '") + name + "' is not a registered object\n\n");
41}
42
43const InputParameters &
45{
46 const auto id = getAppParamsID(params);
47 if (const auto it = _input_parameters.find(id); it != _input_parameters.end())
48 return *it->second;
49 mooseError("AppFactory::getAppParams(): Parameters for application with ID ", id, " not found");
50}
51
52void
54{
55 const auto id = getAppParamsID(params);
56 if (const auto it = _input_parameters.find(id); it != _input_parameters.end())
57 _input_parameters.erase(it);
58 else
60 "AppFactory::clearAppParams(): Parameters for application with ID ", id, " not found");
61}
62
63std::unique_ptr<MooseApp>
64AppFactory::create(const std::string & app_type,
65 const std::vector<std::string> & cli_args /* = {} */)
66{
67 auto parser = std::make_unique<Parser>(std::vector<std::string>());
68 parser->parse();
69 parser->setAppType(app_type);
70
71 auto command_line = std::make_unique<CommandLine>(std::vector<std::string>{"unused"});
72 command_line->addArguments(cli_args);
73 command_line->parse();
74
75 return AppFactory::create(std::move(parser), std::move(command_line));
76}
77
78std::unique_ptr<MooseApp>
79AppFactory::create(std::unique_ptr<Parser> parser, std::unique_ptr<CommandLine> command_line)
80{
81 mooseAssert(parser, "Not set");
82 mooseAssert(parser->getAppType().size(), "App type not set");
83 mooseAssert(parser->queryRoot(), "Has not parsed");
84 mooseAssert(command_line, "Not set");
85 mooseAssert(command_line->hasParsed(), "Has not parsed");
86
87 const std::string app_type = parser->getAppType();
88
89 auto app_params = AppFactory::instance().getValidParams(parser->getAppType());
90 app_params.set<std::shared_ptr<Parser>>("_parser") = std::move(parser);
91 app_params.set<std::shared_ptr<CommandLine>>("_command_line") = std::move(command_line);
92
93 return AppFactory::instance().create(app_type, main_app_name, app_params, MPI_COMM_WORLD);
94}
95
96std::shared_ptr<MooseApp>
97AppFactory::createAppShared(const std::string & default_app_type,
98 int argc,
99 char ** argv,
100 MPI_Comm comm_world_in)
101{
102 mooseDeprecated("Please update your main.C to adapt new main function in MOOSE framework, "
103 "see'test/src/main.C in MOOSE as an example of moose::main()'. ");
104
105 // Populate the -i and --app parameters early
106 auto command_line_params = emptyInputParameters();
107 MooseApp::addInputParam(command_line_params);
108 MooseApp::addAppParam(command_line_params);
109 {
110 CommandLine pre_command_line(argc, argv);
111 pre_command_line.parse();
112 pre_command_line.populateCommandLineParams(command_line_params);
113 }
114 const auto & input_filenames = command_line_params.get<std::vector<std::string>>("input_file");
115 std::string app_type = command_line_params.get<std::string>("app_to_run");
116
117 auto command_line = std::make_unique<CommandLine>(argc, argv);
118 command_line->parse();
119
120 auto parser = std::make_unique<Parser>(input_filenames);
121 parser->setCommandLineParams(command_line->buildHitParams());
122 parser->parse();
123
124 if (app_type.empty())
125 app_type = default_app_type;
126 else
127 mooseDeprecated("Please use [Application] block to specify application type, '--app <AppName>' "
128 "is deprecated and will be removed in a future release.");
129
130 parser->setAppType(app_type);
131
132 auto app_params = AppFactory::instance().getValidParams(app_type);
133 app_params.set<std::shared_ptr<Parser>>("_parser") = std::move(parser);
134 app_params.set<std::shared_ptr<CommandLine>>("_command_line") = std::move(command_line);
135
136 return AppFactory::instance().create(app_type, "main", app_params, comm_world_in);
137}
138
139std::unique_ptr<MooseApp>
140AppFactory::create(const std::string & app_type,
141 const std::string & name,
142 InputParameters parameters,
143 MPI_Comm comm_world_in)
144{
145 // Error if the application type is not located
146 const auto it = _name_to_build_info.find(app_type);
147 if (it == _name_to_build_info.end())
148 mooseError("AppFactory::Create(): Application '" + app_type + "' was not registered");
149 auto & build_info = it->second;
150
151 auto comm = std::make_shared<Parallel::Communicator>(comm_world_in);
152
153 // Take the app_type and add it to the parameters so that it can be retrieved in the Application
154 parameters.set<std::string>(MooseBase::type_param) = app_type;
155 parameters.set<std::string>(MooseBase::name_param) = name;
156 parameters.set<std::string>(MooseBase::unique_name_param) = "Application/" + name;
157 parameters.set<std::shared_ptr<Parallel::Communicator>>("_comm") = comm;
158 parameters.set<std::string>("_app_name") = name;
159
160 auto parser = parameters.get<std::shared_ptr<Parser>>("_parser");
161 mooseAssert(parser, "Parser not valid");
162 mooseAssert(parser->queryRoot(), "Parser has not parsed");
163
164 auto command_line = parameters.get<std::shared_ptr<CommandLine>>("_command_line");
165 mooseAssert(command_line, "Command line not valid");
166 mooseAssert(command_line->hasParsed(), "Command line has not parsed");
167 command_line->populateCommandLineParams(parameters);
168
169 // Historically we decided to non-const copy construct all application parameters. In
170 // order to get around that while apps are fixed (by taking a const reference instead),
171 // we store the app params here and the MooseApp constructor will query the InputParameters
172 // owned by ths factory instead of the ones that are passed to it (likely a const ref to a
173 // copy of the derived app's parmeters)
174 const auto & params = storeAppParams(parameters);
175
176 build_info->_app_creation_count++;
177
178 return build_info->build(params);
179}
180
181std::shared_ptr<MooseApp>
182AppFactory::createShared(const std::string & app_type,
183 const std::string & name,
184 InputParameters parameters,
185 MPI_Comm comm_world_in)
186{
187 return AppFactory::instance().create(app_type, name, parameters, comm_world_in);
188}
189
190std::size_t
191AppFactory::createdAppCount(const std::string & app_type) const
192{
193 // Error if the application type is not located
194 const auto it = _name_to_build_info.find(app_type);
195 if (it == _name_to_build_info.end())
196 mooseError("AppFactory::createdAppCount(): '", app_type, "' is not a registered app");
197
198 return it->second->_app_creation_count;
199}
200
201const InputParameters &
203{
204 const std::size_t next_id =
205 _input_parameters.size() ? (std::prev(_input_parameters.end())->first + 1) : 0;
206 params.addPrivateParam<std::size_t>("_app_params_id", next_id);
207 const auto it_inserted_pair =
208 _input_parameters.emplace(next_id, std::make_unique<InputParameters>(params));
209 mooseAssert(it_inserted_pair.second, "Already exists");
210 auto & stored_params = *it_inserted_pair.first->second;
211 stored_params.finalize("");
212 return stored_params;
213}
214
215std::size_t
217{
218 if (!params.have_parameter<std::size_t>("_app_params_id"))
219 mooseError("AppFactory::getAppParamsID(): Invalid application parameters (missing "
220 "'_app_params_id')");
221 return params.get<std::size_t>("_app_params_id");
222}
223
224void
225AppFactory::registerAppCapability(const std::string & app_name)
226{
227 auto & capabilities = Moose::internal::Capabilities::getCapabilities({});
228 capabilities.add(MooseUtils::toLower(app_name),
229 bool(true),
230 "MOOSE application " + app_name + " is available.");
231}
InputParameters emptyInputParameters()
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
void mooseDeprecated(Args &&... args)
Emit a deprecated code/feature message with the given stringified, concatenated args.
Definition MooseError.h:363
Class that is used as a parameter to clearAppParams() that allows only MooseApp to call clearAppParam...
Definition AppFactory.h:144
Generic AppFactory class for building Application objects.
Definition AppFactory.h:55
static std::shared_ptr< MooseApp > createAppShared(const std::string &default_app_type, int argc, char **argv, MPI_Comm comm_word=MPI_COMM_WORLD)
Deprecated helper function for creating a MooseApp for Apps haven't adapted to the new Parser and Bui...
Definition AppFactory.C:97
std::size_t getAppParamsID(const InputParameters &params) const
Get the ID for the InputParameters associated with an application, used in storing them in _input_par...
Definition AppFactory.C:216
const InputParameters & getAppParams(const InputParameters &params) const
Definition AppFactory.C:44
InputParameters getValidParams(const std::string &name)
Get valid parameters for the object.
Definition AppFactory.C:35
const InputParameters & storeAppParams(InputParameters &params)
Stores the given parameters within _input_parameters for app construction.
Definition AppFactory.C:202
void registerAppCapability(const std::string &app_name)
Register an application name as a capability.
Definition AppFactory.C:225
std::shared_ptr< MooseApp > createShared(const std::string &app_type, const std::string &name, InputParameters parameters, MPI_Comm COMM_WORLD_IN)
Definition AppFactory.C:182
AppFactoryBuildInfoMap _name_to_build_info
Definition AppFactory.h:193
std::size_t createdAppCount(const std::string &app_type) const
Definition AppFactory.C:191
static std::unique_ptr< MooseApp > create(const std::string &app_type, const std::vector< std::string > &cli_args={})
Create an app with no input and command line arguments.
Definition AppFactory.C:64
AppFactory()
Private constructor for singleton pattern.
Definition AppFactory.h:222
static const std::string main_app_name
The name for the "main" moose application.
Definition AppFactory.h:68
std::map< std::size_t, std::unique_ptr< InputParameters > > _input_parameters
Storage of input parameters used in applications (ID (from getAppParamsID()) -> params)
Definition AppFactory.h:231
static AppFactory & instance()
Get the instance of the AppFactory.
Definition AppFactory.C:20
void clearAppParams(const InputParameters &params, const ClearAppParamsKey)
Clears the stored parameters for the given application parameteres.
Definition AppFactory.C:53
virtual ~AppFactory()
Definition AppFactory.C:30
This class wraps provides and tracks access to command line parameters.
Definition CommandLine.h:30
void populateCommandLineParams(InputParameters &params)
Populates the command line input parameters from params.
void parse()
Performs the parsing, which is the combining of arguments into [name, value] pairs.
Definition CommandLine.C:69
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
void addPrivateParam(const std::string &name, const T &value)
These method add a parameter to the InputParameters object which can be retrieved like any other para...
std::vector< std::pair< R1, R2 > > get(const std::string &param1, const std::string &param2) const
Combine two vector parameters into a single vector of pairs.
bool have_parameter(std::string_view name) const
A wrapper around the Parameters base class method.
T & set(const std::string &name, bool quiet_mode=false)
Returns a writable reference to the named parameters.
static void addAppParam(InputParameters &params)
Definition MooseApp.C:264
static void addInputParam(InputParameters &params)
Definition MooseApp.C:271
static const std::string unique_name_param
The name of the parameter that contains the unique object name.
Definition MooseBase.h:57
static const std::string name_param
The name of the parameter that contains the object name.
Definition MooseBase.h:55
static const std::string type_param
The name of the parameter that contains the object type.
Definition MooseBase.h:53
static Capabilities & getCapabilities(const GetCapabilitiesPassKey)
Get the singleton Capabilities.
Capability & add(const std::string_view name, const Moose::Capability::Value &value, const std::string_view doc)
Add a capability.
std::string toLower(std::string name)
Convert supplied string to lower case.