LCOV - code coverage report
Current view: top level - src/base - AppFactory.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #33380 (547b29) with base 8581c3 Lines: 95 105 90.5 %
Date: 2026-07-20 19:36:28 Functions: 14 18 77.8 %
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 "Moose.h"
      14             : #include "MooseApp.h"
      15             : #include "Parser.h"
      16             : #include "MooseMain.h"
      17             : #include "Capabilities.h"
      18             : #include "MooseStringUtils.h"
      19             : 
      20             : AppFactory &
      21      417012 : AppFactory::instance()
      22             : {
      23             :   // We need a naked new here (_not_ a smart pointer or object instance) due to what seems like a
      24             :   // bug in clang's static object destruction when using dynamic library loading.
      25             :   static AppFactory * instance = nullptr;
      26      417012 :   if (!instance)
      27       54939 :     instance = new AppFactory;
      28      417012 :   return *instance;
      29             : }
      30             : 
      31           8 : AppFactory::~AppFactory() {}
      32             : 
      33             : const std::string AppFactory::main_app_name = "main";
      34             : 
      35             : InputParameters
      36       67703 : AppFactory::getValidParams(const std::string & name)
      37             : {
      38       67703 :   if (const auto it = _name_to_build_info.find(name); it != _name_to_build_info.end())
      39       67703 :     return it->second->buildParameters();
      40             : 
      41           0 :   mooseError(std::string("A '") + name + "' is not a registered object\n\n");
      42             : }
      43             : 
      44             : const InputParameters &
      45       67728 : AppFactory::getAppParams(const InputParameters & params) const
      46             : {
      47       67728 :   const auto id = getAppParamsID(params);
      48       67728 :   if (const auto it = _input_parameters.find(id); it != _input_parameters.end())
      49       67728 :     return *it->second;
      50           0 :   mooseError("AppFactory::getAppParams(): Parameters for application with ID ", id, " not found");
      51             : }
      52             : 
      53             : void
      54       63593 : AppFactory::clearAppParams(const InputParameters & params, const ClearAppParamsKey)
      55             : {
      56       63593 :   const auto id = getAppParamsID(params);
      57       63593 :   if (const auto it = _input_parameters.find(id); it != _input_parameters.end())
      58       63591 :     _input_parameters.erase(it);
      59             :   else
      60           2 :     mooseError(
      61             :         "AppFactory::clearAppParams(): Parameters for application with ID ", id, " not found");
      62       63591 : }
      63             : 
      64             : std::unique_ptr<MooseApp>
      65          40 : AppFactory::create(const std::string & app_type,
      66             :                    const std::vector<std::string> & cli_args /* = {} */)
      67             : {
      68          40 :   auto parser = std::make_unique<Parser>(std::vector<std::string>());
      69          40 :   parser->parse();
      70          40 :   parser->setAppType(app_type);
      71             : 
      72         120 :   auto command_line = std::make_unique<CommandLine>(std::vector<std::string>{"unused"});
      73          40 :   command_line->addArguments(cli_args);
      74          40 :   command_line->parse();
      75          80 :   Moose::_suppress_info = command_line->hasArgument("--suppress-info");
      76             : 
      77          80 :   return AppFactory::create(std::move(parser), std::move(command_line));
      78         160 : }
      79             : 
      80             : std::unique_ptr<MooseApp>
      81       55449 : AppFactory::create(std::unique_ptr<Parser> parser, std::unique_ptr<CommandLine> command_line)
      82             : {
      83             :   mooseAssert(parser, "Not set");
      84             :   mooseAssert(parser->getAppType().size(), "App type not set");
      85             :   mooseAssert(parser->queryRoot(), "Has not parsed");
      86             :   mooseAssert(command_line, "Not set");
      87             :   mooseAssert(command_line->hasParsed(), "Has not parsed");
      88             : 
      89       55449 :   const std::string app_type = parser->getAppType();
      90             : 
      91       55449 :   auto app_params = AppFactory::instance().getValidParams(parser->getAppType());
      92      110898 :   app_params.set<std::shared_ptr<Parser>>("_parser") = std::move(parser);
      93      110898 :   app_params.set<std::shared_ptr<CommandLine>>("_command_line") = std::move(command_line);
      94             : 
      95      110895 :   return AppFactory::instance().create(app_type, main_app_name, app_params, MPI_COMM_WORLD);
      96       55446 : }
      97             : 
      98             : std::shared_ptr<MooseApp>
      99           2 : AppFactory::createAppShared(const std::string & default_app_type,
     100             :                             int argc,
     101             :                             char ** argv,
     102             :                             MPI_Comm comm_world_in)
     103             : {
     104           2 :   mooseDeprecated("Please update your main.C to adapt new main function in MOOSE framework, "
     105             :                   "see'test/src/main.C in MOOSE as an example of moose::main()'. ");
     106             : 
     107             :   // Populate the -i and --app parameters early
     108           2 :   auto command_line_params = emptyInputParameters();
     109           2 :   MooseApp::addInputParam(command_line_params);
     110           2 :   MooseApp::addAppParam(command_line_params);
     111             :   {
     112           2 :     CommandLine pre_command_line(argc, argv);
     113           2 :     pre_command_line.parse();
     114           2 :     pre_command_line.populateCommandLineParams(command_line_params);
     115           2 :   }
     116           2 :   const auto & input_filenames = command_line_params.get<std::vector<std::string>>("input_file");
     117           2 :   std::string app_type = command_line_params.get<std::string>("app_to_run");
     118             : 
     119           2 :   auto command_line = std::make_unique<CommandLine>(argc, argv);
     120           2 :   command_line->parse();
     121           4 :   Moose::_suppress_info = command_line->hasArgument("--suppress-info");
     122             : 
     123           2 :   auto parser = std::make_unique<Parser>(input_filenames);
     124           2 :   parser->setCommandLineParams(command_line->buildHitParams());
     125           2 :   parser->parse();
     126             : 
     127           2 :   if (app_type.empty())
     128           2 :     app_type = default_app_type;
     129             :   else
     130           0 :     mooseDeprecated("Please use [Application] block to specify application type, '--app <AppName>' "
     131             :                     "is deprecated and will be removed in a future release.");
     132             : 
     133           2 :   parser->setAppType(app_type);
     134             : 
     135           2 :   auto app_params = AppFactory::instance().getValidParams(app_type);
     136           4 :   app_params.set<std::shared_ptr<Parser>>("_parser") = std::move(parser);
     137           4 :   app_params.set<std::shared_ptr<CommandLine>>("_command_line") = std::move(command_line);
     138             : 
     139           8 :   return AppFactory::instance().create(app_type, "main", app_params, comm_world_in);
     140           2 : }
     141             : 
     142             : std::unique_ptr<MooseApp>
     143       67728 : AppFactory::create(const std::string & app_type,
     144             :                    const std::string & name,
     145             :                    InputParameters parameters,
     146             :                    MPI_Comm comm_world_in)
     147             : {
     148             :   // Error if the application type is not located
     149       67728 :   const auto it = _name_to_build_info.find(app_type);
     150       67728 :   if (it == _name_to_build_info.end())
     151           6 :     mooseError("AppFactory::Create(): Application '" + app_type + "' was not registered");
     152       67726 :   auto & build_info = it->second;
     153             : 
     154       67726 :   auto comm = std::make_shared<Parallel::Communicator>(comm_world_in);
     155             : 
     156             :   // Take the app_type and add it to the parameters so that it can be retrieved in the Application
     157       67726 :   parameters.set<std::string>(MooseBase::type_param) = app_type;
     158       67726 :   parameters.set<std::string>(MooseBase::name_param) = name;
     159       67726 :   parameters.set<std::string>(MooseBase::unique_name_param) = "Application/" + name;
     160      135452 :   parameters.set<std::shared_ptr<Parallel::Communicator>>("_comm") = comm;
     161       67726 :   parameters.set<std::string>("_app_name") = name;
     162             : 
     163       67726 :   auto parser = parameters.get<std::shared_ptr<Parser>>("_parser");
     164             :   mooseAssert(parser, "Parser not valid");
     165             :   mooseAssert(parser->queryRoot(), "Parser has not parsed");
     166             : 
     167       67726 :   auto command_line = parameters.get<std::shared_ptr<CommandLine>>("_command_line");
     168             :   mooseAssert(command_line, "Command line not valid");
     169             :   mooseAssert(command_line->hasParsed(), "Command line has not parsed");
     170       67726 :   command_line->populateCommandLineParams(parameters);
     171             : 
     172             :   // Historically we decided to non-const copy construct all application parameters. In
     173             :   // order to get around that while apps are fixed (by taking a const reference instead),
     174             :   // we store the app params here and the MooseApp constructor will query the InputParameters
     175             :   // owned by ths factory instead of the ones that are passed to it (likely a const ref to a
     176             :   // copy of the derived app's parmeters)
     177       67726 :   const auto & params = storeAppParams(parameters);
     178             : 
     179       67726 :   build_info->_app_creation_count++;
     180             : 
     181      135447 :   return build_info->build(params);
     182       67727 : }
     183             : 
     184             : std::shared_ptr<MooseApp>
     185           0 : AppFactory::createShared(const std::string & app_type,
     186             :                          const std::string & name,
     187             :                          InputParameters parameters,
     188             :                          MPI_Comm comm_world_in)
     189             : {
     190           0 :   return AppFactory::instance().create(app_type, name, parameters, comm_world_in);
     191             : }
     192             : 
     193             : std::size_t
     194           0 : AppFactory::createdAppCount(const std::string & app_type) const
     195             : {
     196             :   // Error if the application type is not located
     197           0 :   const auto it = _name_to_build_info.find(app_type);
     198           0 :   if (it == _name_to_build_info.end())
     199           0 :     mooseError("AppFactory::createdAppCount(): '", app_type, "' is not a registered app");
     200             : 
     201           0 :   return it->second->_app_creation_count;
     202             : }
     203             : 
     204             : const InputParameters &
     205       67730 : AppFactory::storeAppParams(InputParameters & params)
     206             : {
     207             :   const std::size_t next_id =
     208       80003 :       _input_parameters.size() ? (std::prev(_input_parameters.end())->first + 1) : 0;
     209       67730 :   params.addPrivateParam<std::size_t>("_app_params_id", next_id);
     210             :   const auto it_inserted_pair =
     211       67730 :       _input_parameters.emplace(next_id, std::make_unique<InputParameters>(params));
     212             :   mooseAssert(it_inserted_pair.second, "Already exists");
     213       67730 :   auto & stored_params = *it_inserted_pair.first->second;
     214       67730 :   stored_params.finalize("");
     215       67730 :   return stored_params;
     216             : }
     217             : 
     218             : std::size_t
     219      131329 : AppFactory::getAppParamsID(const InputParameters & params) const
     220             : {
     221      131329 :   if (!params.have_parameter<std::size_t>("_app_params_id"))
     222           2 :     mooseError("AppFactory::getAppParamsID(): Invalid application parameters (missing "
     223             :                "'_app_params_id')");
     224      131327 :   return params.get<std::size_t>("_app_params_id");
     225             : }
     226             : 
     227             : void
     228       54960 : AppFactory::registerAppCapability(const std::string & app_name)
     229             : {
     230       54960 :   auto & capabilities = Moose::internal::Capabilities::getCapabilities({});
     231      109920 :   capabilities.add(MooseUtils::toLower(app_name),
     232       54960 :                    bool(true),
     233      109920 :                    "MOOSE application " + app_name + " is available.");
     234       54960 : }

Generated by: LCOV version 1.14