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