LCOV - code coverage report
Current view: top level - src/controls - MultiAppSamplerControl.C (source / functions) Hit Total Coverage
Test: idaholab/moose stochastic_tools: f45d79 Lines: 58 65 89.2 %
Date: 2025-07-25 05:00:46 Functions: 3 4 75.0 %
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             : // MOOSE includes
      11             : #include "MultiAppSamplerControl.h"
      12             : #include "Function.h"
      13             : #include "Sampler.h"
      14             : #include "MultiApp.h"
      15             : #include "SamplerFullSolveMultiApp.h"
      16             : 
      17             : registerMooseObject("StochasticToolsApp", MultiAppSamplerControl);
      18             : registerMooseObjectRenamed("StochasticToolsApp",
      19             :                            MultiAppCommandLineControl,
      20             :                            "01/01/2023 00:00",
      21             :                            MultiAppSamplerControl);
      22             : 
      23             : InputParameters
      24        3544 : MultiAppSamplerControl::validParams()
      25             : {
      26        3544 :   InputParameters params = Control::validParams();
      27        3544 :   params += SamplerInterface::validParams();
      28        3544 :   params.addClassDescription("Control for modifying the command line arguments of MultiApps.");
      29             : 
      30             :   // Set and suppress the 'execute_on' flag, it doesn't work with any other flag
      31       10632 :   params.set<ExecFlagEnum>("execute_on") = {EXEC_PRE_MULTIAPP_SETUP};
      32        3544 :   params.suppressParameter<ExecFlagEnum>("execute_on");
      33             : 
      34        7088 :   params.addRequiredParam<MultiAppName>("multi_app", "The name of the MultiApp to control.");
      35        7088 :   params.addRequiredParam<SamplerName>(
      36             :       "sampler",
      37             :       "The Sampler object to utilize for altering the command line options of the MultiApp.");
      38        7088 :   params.addRequiredParam<std::vector<std::string>>(
      39             :       "param_names", "The names of the command line parameters to set via the sampled data.");
      40             : 
      41        3544 :   return params;
      42        3544 : }
      43             : 
      44        1764 : MultiAppSamplerControl::MultiAppSamplerControl(const InputParameters & parameters)
      45             :   : Control(parameters),
      46             :     SamplerInterface(this),
      47        1764 :     _multi_app(_fe_problem.getMultiApp(getParam<MultiAppName>("multi_app"))),
      48        1764 :     _sampler(SamplerInterface::getSampler("sampler")),
      49        5292 :     _param_names(getParam<std::vector<std::string>>("param_names"))
      50             : {
      51        5292 :   if (!_sampler.getParam<ExecFlagEnum>("execute_on").isValueSet(EXEC_PRE_MULTIAPP_SETUP))
      52           8 :     _sampler.paramError(
      53             :         "execute_on",
      54             :         "The sampler object, '",
      55           4 :         _sampler.name(),
      56             :         "', is being used by the '",
      57             :         name(),
      58             :         "' object, thus the 'execute_on' of the sampler must include 'PRE_MULTIAPP_SETUP'.");
      59             : 
      60        1760 :   if (_multi_app->usingPositions())
      61           4 :     paramError("multi_app",
      62             :                "The MultiApp must construct its sub-apps in initial setup but not during its "
      63             :                "creation for '",
      64             :                type(),
      65             :                "'.\nTypically only sampler MultiApps work with '",
      66             :                type(),
      67             :                "' objects.");
      68             : 
      69        5268 :   bool batch_reset = _multi_app->isParamValid("mode") &&
      70        5268 :                      (_multi_app->getParam<MooseEnum>("mode") == "batch-reset");
      71        3512 :   bool batch_restore = _multi_app->isParamValid("mode") &&
      72        5268 :                        (_multi_app->getParam<MooseEnum>("mode") == "batch-restore");
      73        1756 :   if (batch_reset)
      74             :     ; // Do not perform the App count test, because in batch mode there is only one
      75             : 
      76        1176 :   else if (batch_restore)
      77           8 :     _multi_app->paramError(
      78             :         "mode",
      79             :         "The MultiApp object, '",
      80           4 :         _multi_app->name(),
      81             :         "', supplied to the '",
      82             :         name(),
      83             :         "' object is setup to run in 'batch-restore' mode, when using this mode command line "
      84             :         "arguments cannot be modified; batch-reset mode should be used instead.");
      85             : 
      86        1172 :   else if (_multi_app->numGlobalApps() != _sampler.getNumberOfRows())
      87           0 :     mooseError("The number of sub apps (",
      88           0 :                _multi_app->numGlobalApps(),
      89             :                ") created by MultiApp object '",
      90           0 :                _multi_app->name(),
      91             :                "' must be equal to the number for rows (",
      92           0 :                _sampler.getNumberOfRows(),
      93             :                ") for the '",
      94           0 :                _sampler.name(),
      95             :                "' Sampler object.");
      96        1752 : }
      97             : 
      98             : void
      99           0 : MultiAppSamplerControl::initialSetup()
     100             : {
     101             :   // Do not put anything here, this method is being called after execute because the execute_on
     102             :   // is set to PRE_MULTIAPP_SETUP for this class. It won't work any other way.
     103           0 : }
     104             : 
     105             : void
     106        1752 : MultiAppSamplerControl::execute()
     107             : {
     108             :   // Gather the original arguments given in the parameter so we can keep them
     109        1752 :   if (_orig_args.empty())
     110             :   {
     111        7008 :     _orig_args = getControllableValueByName<std::vector<CLIArgString>>(
     112        3504 :         "MultiApp", _multi_app->name(), "cli_args", true);
     113        1752 :     if (_orig_args.size() == 0)
     114        1704 :       _orig_args.push_back("");
     115          48 :     else if (_param_names.size())
     116          96 :       for (auto & clia : _orig_args)
     117          48 :         clia += ";";
     118             :   }
     119             : 
     120        1752 :   auto cli_args = _orig_args;
     121             : 
     122             :   // To avoid storing duplicated param_names for each sampler, we store only param_names once in
     123             :   // "cli_args".
     124             : 
     125             :   // Handle a couple errors up front regarding bracket expressions
     126             :   bool has_brackets = false;
     127        1752 :   if (_param_names.size())
     128             :   {
     129        1752 :     has_brackets = _param_names[0].find("[") != std::string::npos;
     130        4140 :     for (unsigned int i = 1; i < _param_names.size(); ++i)
     131        2392 :       if (has_brackets != (_param_names[i].find("[") != std::string::npos))
     132           4 :         paramError("param_names",
     133             :                    "If the bracket is used, it must be provided to every parameter.");
     134             :   }
     135        1748 :   if (!has_brackets && _sampler.getNumberOfCols() != _param_names.size())
     136           4 :     paramError("param_names",
     137             :                "The number of columns (",
     138           4 :                _sampler.getNumberOfCols(),
     139             :                ") must match the number of parameters (",
     140             :                _param_names.size(),
     141             :                ").");
     142             : 
     143             :   // Add the parameters that will be modified. The MultiApp will ultimately be
     144             :   // responsible for assigning the values from the sampler.
     145        1744 :   std::ostringstream oss;
     146        5864 :   for (dof_id_type col = 0; col < _param_names.size(); ++col)
     147             :   {
     148        4120 :     if (col > 0)
     149        2376 :       oss << ";";
     150        4120 :     oss << _param_names[col];
     151             :   }
     152             : 
     153             :   // Put all the parameters in a single string
     154        3488 :   for (auto & clia : cli_args)
     155        3488 :     clia += oss.str();
     156             : 
     157        5232 :   setControllableValueByName<std::vector<CLIArgString>>(
     158        1744 :       "MultiApp", _multi_app->name(), "cli_args", cli_args);
     159        1744 : }

Generated by: LCOV version 1.14