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 
31 AppFactory::getValidParams(const std::string & name)
32 {
33  if (const auto it = _name_to_build_info.find(name); it != _name_to_build_info.end())
34  return it->second->buildParameters();
35 
36  mooseError(std::string("A '") + name + "' is not a registered object\n\n");
37 }
38 
39 const InputParameters &
41 {
42  const auto id = getAppParamsID(params);
43  if (const auto it = _input_parameters.find(id); it != _input_parameters.end())
44  return *it->second;
45  mooseError("AppFactory::getAppParams(): Parameters for application with ID ", id, " not found");
46 }
47 
48 void
50 {
51  const auto id = getAppParamsID(params);
52  if (const auto it = _input_parameters.find(id); it != _input_parameters.end())
53  _input_parameters.erase(it);
54  else
55  mooseError(
56  "AppFactory::clearAppParams(): Parameters for application with ID ", id, " not found");
57 }
58 
60 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  const std::string app_type = parser->getAppType();
65 
66  auto command_line = std::make_unique<CommandLine>(argc, argv);
67  command_line->parse();
68 
69  auto app_params = AppFactory::instance().getValidParams(parser->getAppType());
70  app_params.set<int>("_argc") = argc;
71  app_params.set<char **>("_argv") = argv;
72  app_params.set<std::shared_ptr<CommandLine>>("_command_line") = std::move(command_line);
73  app_params.set<std::shared_ptr<Parser>>("_parser") = std::move(parser);
74 
75  return AppFactory::instance().createShared(app_type, "main", app_params, MPI_COMM_WORLD);
76 }
77 
79 AppFactory::createAppShared(const std::string & default_app_type,
80  int argc,
81  char ** argv,
82  MPI_Comm comm_world_in)
83 {
84  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  auto command_line_params = emptyInputParameters();
88  MooseApp::addInputParam(command_line_params);
89  MooseApp::addAppParam(command_line_params);
90 
91  {
92  CommandLine pre_command_line(argc, argv);
93  pre_command_line.parse();
94  pre_command_line.populateCommandLineParams(command_line_params);
95  }
96 
97  const auto & input_filenames = command_line_params.get<std::vector<std::string>>("input_file");
98  auto parser = std::make_unique<Parser>(input_filenames);
99  if (input_filenames.size())
100  parser->parse();
101 
102  std::string app_type = command_line_params.get<std::string>("app_to_run");
103  if (app_type.empty())
104  app_type = default_app_type;
105  else
106  mooseDeprecated("Please use [Application] block to specify application type, '--app <AppName>' "
107  "is deprecated and will be removed in a future release.");
108 
109  parser->setAppType(app_type);
110  auto app_params = AppFactory::instance().getValidParams(app_type);
111 
112  app_params.set<int>("_argc") = argc;
113  app_params.set<char **>("_argv") = argv;
114 
115  auto command_line = std::make_unique<CommandLine>(argc, argv);
116  command_line->parse();
117  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  app_params.set<std::shared_ptr<Parser>>("_parser") = std::move(parser);
122 
123  return AppFactory::instance().createShared(app_type, "main", app_params, comm_world_in);
124 }
125 
127 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  const auto it = _name_to_build_info.find(app_type);
134  if (it == _name_to_build_info.end())
135  mooseError("Object '" + app_type + "' was not registered.");
136  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  parameters.set<std::string>("_type") = app_type;
140 
141  auto comm = std::make_shared<Parallel::Communicator>(comm_world_in);
142 
143  parameters.set<std::shared_ptr<Parallel::Communicator>>("_comm") = comm;
144  parameters.set<std::string>("_app_name") = name;
145 
146  if (!parameters.isParamValid("_command_line"))
147  mooseError("Valid CommandLine object required");
148 
149  std::shared_ptr<CommandLine> command_line =
150  parameters.get<std::shared_ptr<CommandLine>>("_command_line");
151  mooseAssert(command_line->hasParsed(), "Should have been parsed");
152 
153  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  const auto & params = storeAppParams(parameters);
161 
162  build_info->_app_creation_count++;
163 
164  return build_info->build(params);
165 }
166 
167 std::size_t
168 AppFactory::createdAppCount(const std::string & app_type) const
169 {
170  // Error if the application type is not located
171  const auto it = _name_to_build_info.find(app_type);
172  if (it == _name_to_build_info.end())
173  mooseError("AppFactory::createdAppCount(): '", app_type, "' is not a registered app");
174 
175  return it->second->_app_creation_count;
176 }
177 
178 const InputParameters &
180 {
181  const std::size_t next_id =
182  _input_parameters.size() ? (std::prev(_input_parameters.end())->first + 1) : 0;
183  params.addPrivateParam<std::size_t>("_app_params_id", next_id);
184  const auto it_inserted_pair =
185  _input_parameters.emplace(next_id, std::make_unique<InputParameters>(params));
186  mooseAssert(it_inserted_pair.second, "Already exists");
187  auto & stored_params = *it_inserted_pair.first->second;
188  stored_params.finalize("");
189  return stored_params;
190 }
191 
192 std::size_t
194 {
195  if (!params.have_parameter<std::size_t>("_app_params_id"))
196  mooseError("AppFactory::getAppParamsID(): Invalid application parameters (missing "
197  "'_app_params_id')");
198  return params.get<std::size_t>("_app_params_id");
199 }
std::string name(const ElemQuality q)
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:302
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.
MooseAppPtr createShared(const std::string &app_type, const std::string &name, InputParameters parameters, MPI_Comm COMM_WORLD_IN)
Build an application object (must be registered)
Definition: AppFactory.C:127
const InputParameters & storeAppParams(InputParameters &params)
Stores the given parameters within _input_parameters for app construction.
Definition: AppFactory.C:179
static void addInputParam(InputParameters &params)
Definition: MooseApp.C:101
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:40
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
InputParameters emptyInputParameters()
This class wraps provides and tracks access to command line parameters.
Definition: CommandLine.h:29
virtual ~AppFactory()
Definition: AppFactory.C:28
std::shared_ptr< MooseApp > MooseAppPtr
alias to wrap shared pointer type
Definition: AppFactory.h:34
void populateCommandLineParams(InputParameters &params)
Populates the command line input parameters from params.
Definition: CommandLine.C:294
Generic AppFactory class for building Application objects.
Definition: AppFactory.h:62
void clearAppParams(const InputParameters &params, const ClearAppParamsKey)
Clears the stored parameters for the given application parameteres.
Definition: AppFactory.C:49
AppFactoryBuildInfoMap _name_to_build_info
Definition: AppFactory.h:180
std::size_t createdAppCount(const std::string &app_type) const
Definition: AppFactory.C:168
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:212
void mooseDeprecated(Args &&... args)
Emit a deprecated code/feature message with the given stringified, concatenated args.
Definition: MooseError.h:353
static MooseAppPtr createAppShared(int argc, char **argv, std::unique_ptr< Parser > parser)
Helper function for creating a MooseApp from command-line arguments and a Parser. ...
Definition: AppFactory.C:60
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:193
static void addAppParam(InputParameters &params)
Definition: MooseApp.C:94
Class that is used as a parameter to clearAppParams() that allows only MooseApp to call clearAppParam...
Definition: AppFactory.h:118
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:31
bool isParamValid(const std::string &name) const
This method returns parameters that have been initialized in one fashion or another, i.e.