LCOV - code coverage report
Current view: top level - src/base - AppFactory.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: ae1258 Lines: 87 97 89.7 %
Date: 2025-09-05 08:15:23 Functions: 12 17 70.6 %
Legend: Lines: hit not hit

          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      474426 : 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      474426 :   if (!instance)
      24       55887 :     instance = new AppFactory;
      25      474426 :   return *instance;
      26             : }
      27             : 
      28           4 : AppFactory::~AppFactory() {}
      29             : 
      30             : const std::string AppFactory::main_app_name = "main";
      31             : 
      32             : InputParameters
      33       68445 : AppFactory::getValidParams(const std::string & name)
      34             : {
      35       68445 :   if (const auto it = _name_to_build_info.find(name); it != _name_to_build_info.end())
      36       68445 :     return it->second->buildParameters();
      37             : 
      38           0 :   mooseError(std::string("A '") + name + "' is not a registered object\n\n");
      39             : }
      40             : 
      41             : const InputParameters &
      42       68445 : AppFactory::getAppParams(const InputParameters & params) const
      43             : {
      44       68445 :   const auto id = getAppParamsID(params);
      45       68445 :   if (const auto it = _input_parameters.find(id); it != _input_parameters.end())
      46       68445 :     return *it->second;
      47           0 :   mooseError("AppFactory::getAppParams(): Parameters for application with ID ", id, " not found");
      48             : }
      49             : 
      50             : void
      51       62856 : AppFactory::clearAppParams(const InputParameters & params, const ClearAppParamsKey)
      52             : {
      53       62856 :   const auto id = getAppParamsID(params);
      54       62856 :   if (const auto it = _input_parameters.find(id); it != _input_parameters.end())
      55       62855 :     _input_parameters.erase(it);
      56             :   else
      57           1 :     mooseError(
      58             :         "AppFactory::clearAppParams(): Parameters for application with ID ", id, " not found");
      59       62855 : }
      60             : 
      61             : std::unique_ptr<MooseApp>
      62           3 : AppFactory::create(const std::string & app_type,
      63             :                    const std::vector<std::string> & cli_args /* = {} */)
      64             : {
      65           3 :   auto parser = std::make_unique<Parser>(std::vector<std::string>());
      66           3 :   parser->parse();
      67           3 :   parser->setAppType(app_type);
      68             : 
      69           9 :   auto command_line = std::make_unique<CommandLine>(std::vector<std::string>{"unused"});
      70           3 :   command_line->addArguments(cli_args);
      71           3 :   command_line->parse();
      72             : 
      73           6 :   return AppFactory::create(std::move(parser), std::move(command_line));
      74          12 : }
      75             : 
      76             : std::unique_ptr<MooseApp>
      77       56023 : 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       56023 :   const std::string app_type = parser->getAppType();
      86             : 
      87       56023 :   auto app_params = AppFactory::instance().getValidParams(parser->getAppType());
      88      112046 :   app_params.set<std::shared_ptr<Parser>>("_parser") = std::move(parser);
      89      112046 :   app_params.set<std::shared_ptr<CommandLine>>("_command_line") = std::move(command_line);
      90             : 
      91      112042 :   return AppFactory::instance().create(app_type, main_app_name, app_params, MPI_COMM_WORLD);
      92       56019 : }
      93             : 
      94             : std::shared_ptr<MooseApp>
      95           1 : AppFactory::createAppShared(const std::string & default_app_type,
      96             :                             int argc,
      97             :                             char ** argv,
      98             :                             MPI_Comm comm_world_in)
      99             : {
     100           1 :   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           1 :   auto command_line_params = emptyInputParameters();
     105           1 :   MooseApp::addInputParam(command_line_params);
     106           1 :   MooseApp::addAppParam(command_line_params);
     107             :   {
     108           1 :     CommandLine pre_command_line(argc, argv);
     109           1 :     pre_command_line.parse();
     110           1 :     pre_command_line.populateCommandLineParams(command_line_params);
     111           1 :   }
     112           1 :   const auto & input_filenames = command_line_params.get<std::vector<std::string>>("input_file");
     113           1 :   std::string app_type = command_line_params.get<std::string>("app_to_run");
     114             : 
     115           1 :   auto command_line = std::make_unique<CommandLine>(argc, argv);
     116           1 :   command_line->parse();
     117             : 
     118           1 :   auto parser = std::make_unique<Parser>(input_filenames);
     119           1 :   parser->setCommandLineParams(command_line->buildHitParams());
     120           1 :   parser->parse();
     121             : 
     122           1 :   if (app_type.empty())
     123           1 :     app_type = default_app_type;
     124             :   else
     125           0 :     mooseDeprecated("Please use [Application] block to specify application type, '--app <AppName>' "
     126             :                     "is deprecated and will be removed in a future release.");
     127             : 
     128           1 :   parser->setAppType(app_type);
     129             : 
     130           1 :   auto app_params = AppFactory::instance().getValidParams(app_type);
     131           2 :   app_params.set<std::shared_ptr<Parser>>("_parser") = std::move(parser);
     132           2 :   app_params.set<std::shared_ptr<CommandLine>>("_command_line") = std::move(command_line);
     133             : 
     134           4 :   return AppFactory::instance().create(app_type, "main", app_params, comm_world_in);
     135           1 : }
     136             : 
     137             : std::unique_ptr<MooseApp>
     138       68445 : 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       68445 :   const auto it = _name_to_build_info.find(app_type);
     145       68445 :   if (it == _name_to_build_info.end())
     146           3 :     mooseError("AppFactory::Create(): Application '" + app_type + "' was not registered");
     147       68444 :   auto & build_info = it->second;
     148             : 
     149       68444 :   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       68444 :   parameters.set<std::string>(MooseBase::type_param) = app_type;
     153       68444 :   parameters.set<std::string>(MooseBase::name_param) = name;
     154       68444 :   parameters.set<std::string>(MooseBase::unique_name_param) = "Application/" + name;
     155      136888 :   parameters.set<std::shared_ptr<Parallel::Communicator>>("_comm") = comm;
     156       68444 :   parameters.set<std::string>("_app_name") = name;
     157             : 
     158       68444 :   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       68444 :   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       68444 :   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       68444 :   const auto & params = storeAppParams(parameters);
     173             : 
     174       68444 :   build_info->_app_creation_count++;
     175             : 
     176      136883 :   return build_info->build(params);
     177       68442 : }
     178             : 
     179             : std::shared_ptr<MooseApp>
     180           0 : AppFactory::createShared(const std::string & app_type,
     181             :                          const std::string & name,
     182             :                          InputParameters parameters,
     183             :                          MPI_Comm comm_world_in)
     184             : {
     185           0 :   return AppFactory::instance().create(app_type, name, parameters, comm_world_in);
     186             : }
     187             : 
     188             : std::size_t
     189           0 : AppFactory::createdAppCount(const std::string & app_type) const
     190             : {
     191             :   // Error if the application type is not located
     192           0 :   const auto it = _name_to_build_info.find(app_type);
     193           0 :   if (it == _name_to_build_info.end())
     194           0 :     mooseError("AppFactory::createdAppCount(): '", app_type, "' is not a registered app");
     195             : 
     196           0 :   return it->second->_app_creation_count;
     197             : }
     198             : 
     199             : const InputParameters &
     200       68446 : AppFactory::storeAppParams(InputParameters & params)
     201             : {
     202             :   const std::size_t next_id =
     203       80865 :       _input_parameters.size() ? (std::prev(_input_parameters.end())->first + 1) : 0;
     204       68446 :   params.addPrivateParam<std::size_t>("_app_params_id", next_id);
     205             :   const auto it_inserted_pair =
     206       68446 :       _input_parameters.emplace(next_id, std::make_unique<InputParameters>(params));
     207             :   mooseAssert(it_inserted_pair.second, "Already exists");
     208       68446 :   auto & stored_params = *it_inserted_pair.first->second;
     209       68446 :   stored_params.finalize("");
     210       68446 :   return stored_params;
     211             : }
     212             : 
     213             : std::size_t
     214      131305 : AppFactory::getAppParamsID(const InputParameters & params) const
     215             : {
     216      131305 :   if (!params.have_parameter<std::size_t>("_app_params_id"))
     217           1 :     mooseError("AppFactory::getAppParamsID(): Invalid application parameters (missing "
     218             :                "'_app_params_id')");
     219      131304 :   return params.get<std::size_t>("_app_params_id");
     220             : }

Generated by: LCOV version 1.14