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 #include "Capabilities.h"
17 #include "MooseStringUtils.h"
18 
19 AppFactory &
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 
32 const std::string AppFactory::main_app_name = "main";
33 
35 AppFactory::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 
43 const 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 
52 void
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
59  mooseError(
60  "AppFactory::clearAppParams(): Parameters for application with ID ", id, " not found");
61 }
62 
63 std::unique_ptr<MooseApp>
64 AppFactory::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 
78 std::unique_ptr<MooseApp>
79 AppFactory::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 
96 std::shared_ptr<MooseApp>
97 AppFactory::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 
139 std::unique_ptr<MooseApp>
140 AppFactory::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 
181 std::shared_ptr<MooseApp>
182 AppFactory::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 
190 std::size_t
191 AppFactory::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 
201 const 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 
215 std::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 
224 void
225 AppFactory::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 }
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:311
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:182
static const std::string main_app_name
The name for the "main" moose application.
Definition: AppFactory.h:68
static Capabilities & getCapabilities(const GetCapabilitiesPassKey)
Get the singleton Capabilities.
Definition: Capabilities.C:52
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:97
const InputParameters & storeAppParams(InputParameters &params)
Stores the given parameters within _input_parameters for app construction.
Definition: AppFactory.C:202
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:44
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:30
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
void populateCommandLineParams(InputParameters &params)
Populates the command line input parameters from params.
Definition: CommandLine.C:311
Generic AppFactory class for building Application objects.
Definition: AppFactory.h:54
void clearAppParams(const InputParameters &params, const ClearAppParamsKey)
Clears the stored parameters for the given application parameteres.
Definition: AppFactory.C:53
Capability & add(const std::string_view name, const Moose::Capability::Value &value, const std::string_view doc)
Add a capability.
AppFactoryBuildInfoMap _name_to_build_info
Definition: AppFactory.h:193
std::size_t createdAppCount(const std::string &app_type) const
Definition: AppFactory.C:191
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
void mooseDeprecated(Args &&... args)
Emit a deprecated code/feature message with the given stringified, concatenated args.
Definition: MooseError.h:363
std::string toLower(std::string name)
Convert supplied string to lower case.
AppFactory()
Private constructor for singleton pattern.
Definition: AppFactory.h:222
static AppFactory & instance()
Get the instance of the AppFactory.
Definition: AppFactory.C:20
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:216
void registerAppCapability(const std::string &app_name)
Register an application name as a capability.
Definition: AppFactory.C:225
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:143
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:35