LCOV - code coverage report
Current view: top level - src/actions - CommonOutputAction.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #32971 (54bef8) with base c6cf66 Lines: 217 222 97.7 %
Date: 2026-05-29 20:35:17 Functions: 7 7 100.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 "CommonOutputAction.h"
      12             : #include "MooseApp.h"
      13             : #include "FEProblem.h"
      14             : #include "MooseObjectAction.h"
      15             : #include "ActionFactory.h"
      16             : #include "Output.h"
      17             : #include "OutputWarehouse.h"
      18             : #include "MooseUtils.h"
      19             : #include "PerfGraphReporter.h"
      20             : 
      21             : // Extrnal includes
      22             : #include "tinydir.h"
      23             : #include "pcrecpp.h"
      24             : #include <libgen.h>
      25             : #include <sys/types.h>
      26             : #include <sys/stat.h>
      27             : #include <unistd.h>
      28             : 
      29             : registerMooseAction("MooseApp", CommonOutputAction, "common_output");
      30             : registerMooseAction("MooseApp", CommonOutputAction, "add_output");
      31             : registerMooseAction("MooseApp", CommonOutputAction, "add_reporter");
      32             : 
      33             : InputParameters
      34       66081 : CommonOutputAction::validParams()
      35             : {
      36       66081 :   InputParameters params = Action::validParams();
      37      132162 :   params.addClassDescription("Adds short-cut syntax and common parameters to the Outputs block.");
      38             : 
      39             :   // Short-cut methods for typical output objects
      40      198243 :   params.addParam<bool>(
      41      132162 :       "exodus", false, "Output the results using the default settings for Exodus output.");
      42      198243 :   params.addParam<bool>(
      43      132162 :       "nemesis", false, "Output the results using the default settings for Nemesis output");
      44      198243 :   params.addParam<bool>(
      45      132162 :       "console", true, "Output the results using the default settings for Console output");
      46      198243 :   params.addParam<bool>("csv",
      47      132162 :                         false,
      48             :                         "Output the scalar variable and postprocessors to a *.csv "
      49             :                         "file using the default CSV output.");
      50      198243 :   params.addParam<bool>("xml",
      51      132162 :                         false,
      52             :                         "Output the vector postprocessors to a *.xml "
      53             :                         "file using the default XML output.");
      54      198243 :   params.addParam<bool>("json",
      55      132162 :                         false,
      56             :                         "Output Reporter values to a *.json "
      57             :                         "file using the default JSON output.");
      58      198243 :   params.addParam<bool>(
      59      132162 :       "vtk", false, "Output the results using the default settings for VTKOutput output");
      60      198243 :   params.addParam<bool>(
      61      132162 :       "xda", false, "Output the results using the default settings for XDA/XDR output (ascii)");
      62      198243 :   params.addParam<bool>(
      63      132162 :       "xdr", false, "Output the results using the default settings for XDA/XDR output (binary)");
      64      198243 :   params.addParam<bool>(
      65      132162 :       "gmv", false, "Output the results using the default settings for GMV output");
      66      198243 :   params.addParam<bool>(
      67      132162 :       "tecplot", false, "Output the results using the default settings for Tecplot output");
      68      198243 :   params.addParam<bool>(
      69             :       "gnuplot",
      70      132162 :       false,
      71             :       "Output the scalar and postprocessor results using the default settings for GNUPlot output");
      72      198243 :   params.addParam<bool>(
      73      132162 :       "solution_history", false, "Print a solution history file (.slh) using the default settings");
      74      264324 :   params.addParam<bool>("progress", false, "Print a progress bar");
      75      264324 :   params.addParam<bool>("dofmap", false, "Create the dof map .json output file");
      76      264324 :   params.addParam<bool>("controls", false, "Enable the screen output of Control systems.");
      77             : 
      78             :   // Common parameters
      79             : 
      80             :   // Note: Be sure that objects that share these parameters utilize the same defaults
      81      264324 :   params.addParam<bool>("color", true, "Set to false to turn off all coloring in all outputs");
      82      264324 :   params.addParam<std::string>("file_base",
      83             :                                "Common file base name to be utilized with all output objects");
      84      264324 :   params.addParam<std::vector<std::string>>("output_if_base_contains",
      85             :                                             "If this is supplied then output will only be done in "
      86             :                                             "the case that the output base contains one of these "
      87             :                                             "strings.  This is helpful in outputting only a subset "
      88             :                                             "of outputs when using MultiApps.");
      89      198243 :   params.addParam<unsigned int>(
      90      132162 :       "time_step_interval", 1, "The interval (number of time steps) at which output occurs");
      91      198243 :   params.addParam<std::vector<Real>>("sync_times",
      92      132162 :                                      std::vector<Real>(),
      93             :                                      "Times at which the output and solution is forced to occur");
      94      198243 :   params.addParam<Real>(
      95      132162 :       "min_simulation_time_interval", 0.0, "The minimum simulation time between output steps");
      96      198243 :   params.addParam<bool>(
      97      132162 :       "append_date", false, "When true the date and time are appended to the output filename.");
      98      264324 :   params.addParam<std::string>("append_date_format",
      99             :                                "The format of the date/time to append (see "
     100             :                                "http://www.cplusplus.com/reference/ctime/"
     101             :                                "strftime).");
     102             : 
     103      264324 :   params.addParam<std::vector<VariableName>>(
     104             :       "hide",
     105             :       {},
     106             :       "A list of the variables and postprocessors that should NOT be output to the Exodus "
     107             :       "file (may include Variables, ScalarVariables, and Postprocessor names).");
     108      198243 :   params.addParam<std::vector<VariableName>>(
     109             :       "show",
     110             :       {},
     111             :       "A list of the variables and postprocessors that should be output to the Exodus file "
     112             :       "(may include Variables, ScalarVariables, and Postprocessor names).");
     113             : 
     114             :   // Add the 'execute_on' input parameter
     115       66081 :   ExecFlagEnum exec_enum = Output::getDefaultExecFlagEnum();
     116      198243 :   exec_enum = {EXEC_INITIAL, EXEC_TIMESTEP_END};
     117      198243 :   params.addParam<ExecFlagEnum>("execute_on", exec_enum, exec_enum.getDocString());
     118             : 
     119             :   // Add special Console flags
     120      330405 :   params.addDeprecatedParam<bool>(
     121      132162 :       "print_perf_log", false, "Use perf_graph instead!", "Use perf_graph instead!");
     122             : 
     123      198243 :   params.addParam<bool>(
     124      132162 :       "perf_graph", false, "Enable printing of the performance graph to the screen (Console)");
     125             : 
     126      264324 :   params.addParam<bool>("perf_graph_live", true, "Enables printing of live progress messages");
     127      198243 :   params.addParam<Real>(
     128      132162 :       "perf_graph_live_time_limit", 5.0, "Time (in seconds) to wait before printing a message.");
     129      198243 :   params.addParam<unsigned int>(
     130      132162 :       "perf_graph_live_mem_limit", 100, "Memory (in MB) to cause a message to be printed.");
     131      264324 :   params.addParam<bool>("perf_graph_json", false, "Output the perf graph in JSON");
     132      264324 :   params.addParam<FileName>("perf_graph_json_file", "Path to a .json file to store the perf graph");
     133             : 
     134      198243 :   params.addParam<bool>("print_mesh_changed_info",
     135      132162 :                         false,
     136             :                         "When true, each time the mesh is changed the mesh information is printed");
     137      198243 :   params.addParam<bool>("print_linear_residuals",
     138      132162 :                         true,
     139             :                         "Enable printing of linear residuals to the screen (Console)");
     140      198243 :   params.addParam<bool>("print_nonlinear_residuals",
     141      132162 :                         true,
     142             :                         "Enable printing of nonlinear residuals to the screen (Console)");
     143      198243 :   params.addParam<bool>("print_nonlinear_converged_reason",
     144      132162 :                         true,
     145             :                         "Enable/disable printing of the nonlinear solver convergence reason to the "
     146             :                         "screen. This parameter only affects the output of the third-party solver "
     147             :                         "(e.g. PETSc), not MOOSE itself.");
     148      198243 :   params.addParam<bool>("print_linear_converged_reason",
     149      132162 :                         true,
     150             :                         "Enable/disable printing of the linear solver convergence reason to the "
     151             :                         "screen. This parameter only affects the output of the third-party solver "
     152             :                         "(e.g. PETSc), not MOOSE itself.");
     153             : 
     154      132162 :   params.addParam<bool>(
     155             :       "solution_invalidity_history",
     156      132162 :       true,
     157             :       "Enable printing of the time history of the solution invalidity occurrences "
     158             :       "to the screen (console)");
     159             : 
     160             :   // Return object
     161      132162 :   return params;
     162      132162 : }
     163             : 
     164       66031 : CommonOutputAction::CommonOutputAction(const InputParameters & params)
     165      198093 :   : Action(params), _action_params(_action_factory.getValidParams("AddOutputAction"))
     166             : {
     167       66031 : }
     168             : 
     169             : void
     170      186585 : CommonOutputAction::act()
     171             : {
     172             :   // Name of the PerfGraphReporter that could be created for the perf graph output
     173      294195 :   static const std::string perf_graph_reporter_name = "perf_graph_json";
     174             :   // Name of the JSON output that could be created for the perf graph output
     175      186585 :   static const OutputName perf_graph_json_output_name = "auto_perf_graph_json";
     176             : 
     177      186585 :   if (_current_task == "common_output")
     178             :   {
     179             :     // Store the common output parameters in the OutputWarehouse
     180       65927 :     _app.getOutputWarehouse().setCommonParameters(&_pars);
     181             : 
     182             : // Create the actions for the short-cut methods
     183             : #ifdef LIBMESH_HAVE_EXODUS_API
     184      197781 :     if (getParam<bool>("exodus"))
     185      101175 :       create("Exodus", "exodus");
     186             : #else
     187             :     if (getParam<bool>("exodus"))
     188             :       mooseWarning("Exodus output requested but not enabled through libMesh");
     189             : #endif
     190             : 
     191             : #ifdef LIBMESH_HAVE_NEMESIS_API
     192      197781 :     if (getParam<bool>("nemesis"))
     193         672 :       create("Nemesis", "nemesis");
     194             : #else
     195             :     if (getParam<bool>("nemesis"))
     196             :       mooseWarning("Nemesis output requested but not enabled through libMesh");
     197             : #endif
     198             : 
     199             :     // Only create a Console if screen output was not created
     200      197781 :     if (getParam<bool>("console") && !hasConsole())
     201      194412 :       create("Console", "console");
     202             : 
     203      197781 :     if (getParam<bool>("csv"))
     204       36288 :       create("CSV", "csv");
     205             : 
     206      197781 :     if (getParam<bool>("xml"))
     207         162 :       create("XMLOutput", "xml");
     208             : 
     209      197781 :     if (getParam<bool>("json"))
     210         390 :       create("JSON", "json");
     211             : 
     212             : #ifdef LIBMESH_HAVE_VTK
     213      197781 :     if (getParam<bool>("vtk"))
     214         213 :       create("VTK", "vtk");
     215             : #else
     216             :     if (getParam<bool>("vtk"))
     217             :       mooseWarning("VTK output requested but not enabled through libMesh");
     218             : #endif
     219             : 
     220      197781 :     if (getParam<bool>("xda"))
     221         390 :       create("XDA", "xda");
     222             : 
     223      197781 :     if (getParam<bool>("xdr"))
     224         144 :       create("XDR", "xdr");
     225             : 
     226      197781 :     if (getParam<bool>("gmv"))
     227         102 :       create("GMV", "gmv");
     228             : 
     229      197781 :     if (getParam<bool>("tecplot"))
     230         108 :       create("Tecplot", "tecplot");
     231             : 
     232      197781 :     if (getParam<bool>("gnuplot"))
     233          36 :       create("Gnuplot", "gnuplot");
     234             : 
     235      197781 :     if (getParam<bool>("solution_history"))
     236          36 :       create("SolutionHistory", "solution_history");
     237             : 
     238      197781 :     if (getParam<bool>("progress"))
     239          27 :       create("Progress", "progress");
     240             : 
     241      197781 :     if (getParam<bool>("dofmap"))
     242          72 :       create("DOFMap", "dofmap");
     243             : 
     244             :     // Helper for looking through a pair of [parameters, param name]
     245             :     // to find a true boolean parameter, returning the pair that was found
     246             :     const auto find_param =
     247      131845 :         [](const std::vector<std::pair<const InputParameters *, std::string>> & options)
     248             :     {
     249      131845 :       std::optional<std::string> from_param_name;
     250      131845 :       const InputParameters * from_params = nullptr;
     251      292234 :       for (const auto & [params, param_name] : options)
     252      224719 :         if (params->template get<bool>(param_name))
     253             :         {
     254       64330 :           from_param_name = param_name;
     255       64330 :           from_params = params;
     256       64330 :           break;
     257             :         }
     258      263690 :       return std::make_pair(from_param_name, from_params);
     259      131845 :     };
     260             : 
     261             :     {
     262       65927 :       const auto [from_param_name, from_params] =
     263      263708 :           find_param({{&parameters(), "controls"}, {&_app.parameters(), "show_controls"}});
     264       65927 :       if (from_param_name)
     265          54 :         create("ControlOutput", *from_param_name, from_params);
     266       65927 :     }
     267             : 
     268      197781 :     if (!_app.getParam<bool>("no_timing"))
     269             :     {
     270      263672 :       auto [from_param_name, from_params] = find_param({{&parameters(), "perf_graph"},
     271           0 :                                                         {&parameters(), "print_perf_log"},
     272      329590 :                                                         {&_app.parameters(), "timing"}});
     273       65918 :       if (from_param_name)
     274      192936 :         create("PerfGraphOutput", *from_param_name, from_params);
     275             : 
     276          24 :       const auto add_perf_graph_json = [this](const std::string & from_param_name,
     277             :                                               const std::string & set_param_name,
     278             :                                               const std::string & set_param_value)
     279             :       {
     280          24 :         const auto & value_names = PerfGraphReporter::value_names;
     281          24 :         std::vector<ReporterName> reporters;
     282          24 :         reporters.reserve(value_names.size());
     283         120 :         for (const auto & value_name : value_names)
     284             :         {
     285          96 :           const ReporterName name(perf_graph_reporter_name, value_name);
     286             : 
     287             :           // To avoid this reporter value appearing in all other JSON output
     288          96 :           _common_reporter_names.push_back(name);
     289             : 
     290          96 :           reporters.push_back(name);
     291          96 :         }
     292             : 
     293          72 :         auto params = _factory.getValidParams("JSON");
     294          24 :         params.set<std::vector<ReporterName>>("reporters") = reporters;
     295          72 :         params.set<ExecFlagEnum>("execute_on") = {EXEC_FINAL};
     296          72 :         params.set<ExecFlagEnum>("execute_system_information_on") = {EXEC_NONE};
     297          24 :         params.set<std::string>(set_param_name) = set_param_value;
     298          24 :         params.set<bool>("distributed") = false;
     299          24 :         if (set_param_name == "file_base")
     300          24 :           params.set<bool>("append_date") = false;
     301          72 :         create("JSON", from_param_name, &parameters(), &params, perf_graph_json_output_name);
     302          72 :       };
     303             : 
     304      197754 :       if (getParam<bool>("perf_graph_json"))
     305          72 :         add_perf_graph_json("perf_graph_json", "file_base_suffix", "perf_graph");
     306      197754 :       if (isParamValid("perf_graph_json_file"))
     307             :       {
     308          30 :         const auto & file = getParam<FileName>("perf_graph_json_file");
     309          15 :         if (MooseUtils::getExtension(file, true) != "json")
     310           6 :           paramError("perf_graph_json_file", "File must end with .json");
     311          12 :         const auto file_stripped = MooseUtils::stripExtension(file, true);
     312          36 :         add_perf_graph_json("perf_graph_json_file", "file_base", file_stripped);
     313          12 :       }
     314             : 
     315      197745 :       if (!getParam<bool>("perf_graph_live"))
     316             :       {
     317           0 :         if (!from_param_name)
     318           0 :           perfGraph().setActive(false);
     319           0 :         perfGraph().disableLivePrint();
     320             :       }
     321       65915 :     }
     322             :     else
     323             :     {
     324           9 :       perfGraph().setActive(false);
     325           9 :       perfGraph().disableLivePrint();
     326             :     }
     327             : 
     328      131848 :     perfGraph().setLiveTimeLimit(getParam<Real>("perf_graph_live_time_limit"));
     329      131848 :     perfGraph().setLiveMemoryLimit(getParam<unsigned int>("perf_graph_live_mem_limit"));
     330             : 
     331      197772 :     if (getParam<bool>("solution_invalidity_history"))
     332             :     {
     333      197739 :       create("SolutionInvalidityOutput", "solution_invalidity_history");
     334             :     }
     335             : 
     336      197772 :     if (!getParam<bool>("color"))
     337         166 :       Moose::setColorConsole(false);
     338             :   }
     339      120658 :   else if (_current_task == "add_output")
     340             :   {
     341             :     // More like remove output. This can't be done during the "common_output" task because the
     342             :     // finite element problem is not yet constructed
     343             : 
     344      422679 :     if (!getParam<bool>("console") || (isParamValid("print_nonlinear_converged_reason") &&
     345      241500 :                                        !getParam<bool>("print_nonlinear_converged_reason")))
     346          63 :       Moose::PetscSupport::dontAddNonlinearConvergedReason(*_problem);
     347             : 
     348      422679 :     if (!getParam<bool>("console") || (isParamValid("print_linear_converged_reason") &&
     349      241500 :                                        !getParam<bool>("print_linear_converged_reason")))
     350          72 :       Moose::PetscSupport::dontAddLinearConvergedReason(*_problem);
     351             :   }
     352       60265 :   else if (_current_task == "add_reporter")
     353             :   {
     354      301316 :     if (!_app.getParam<bool>("no_timing") &&
     355      361521 :         (getParam<bool>("perf_graph_json") || isParamValid("perf_graph_json_file")))
     356             :     {
     357          72 :       auto params = _factory.getValidParams("PerfGraphReporter");
     358          24 :       params.set<ExecFlagEnum>("execute_on") = EXEC_FINAL;
     359          48 :       params.set<std::vector<OutputName>>("outputs") =
     360         120 :           std::vector<OutputName>{perf_graph_json_output_name};
     361          48 :       _problem->addReporter("PerfGraphReporter", perf_graph_reporter_name, params);
     362          24 :     }
     363             :   }
     364             :   else
     365           0 :     mooseError("unrecognized task ", _current_task, " in CommonOutputAction.");
     366      318451 : }
     367             : 
     368             : void
     369      241676 : CommonOutputAction::create(const std::string & object_type,
     370             :                            const std::optional<std::string> & param_name,
     371             :                            const InputParameters * const from_params /* = nullptr */,
     372             :                            const InputParameters * const apply_params /* = nullptr */,
     373             :                            const std::optional<std::string> & object_name /* = {} */)
     374             : {
     375             :   // Create our copy of the parameters
     376      241676 :   auto params = _action_params;
     377             : 
     378             :   // Set the 'type =' parameters for the desired object
     379      241676 :   params.set<std::string>("type") = object_type;
     380             : 
     381             :   // Create the complete object name (uses lower case of type)
     382      241676 :   std::string name;
     383      241676 :   if (object_name)
     384          24 :     name = *object_name;
     385             :   else
     386             :   {
     387      241652 :     name = object_type;
     388      241652 :     std::transform(name.begin(), name.end(), name.begin(), ::tolower);
     389             :   }
     390             : 
     391             :   // Create the action
     392             :   std::shared_ptr<MooseObjectAction> action = std::static_pointer_cast<MooseObjectAction>(
     393      483352 :       _action_factory.create("AddOutputAction", name, params));
     394      241676 :   auto & object_params = action->getObjectParams();
     395             : 
     396             :   // Set flag indicating that the object to be created was created with short-cut syntax
     397      241676 :   object_params.set<bool>("_built_by_moose") = true;
     398             : 
     399             :   // Apply any additional parameters
     400      241676 :   if (apply_params)
     401          24 :     object_params.applyParameters(*apply_params);
     402             : 
     403             :   // Associate all action output object errors with param_name
     404             :   // If from_params is specified, it means to associate it with parameters other than parameters()
     405      241676 :   if (param_name)
     406             :   {
     407      241676 :     const InputParameters & associated_params = from_params ? *from_params : parameters();
     408      241676 :     associateWithParameter(associated_params, *param_name, object_params);
     409             :   }
     410             : 
     411             :   // Add the action to the warehouse
     412      241676 :   _awh.addActionBlock(action);
     413      241676 : }
     414             : 
     415             : bool
     416       65903 : CommonOutputAction::hasConsole()
     417             : {
     418             : 
     419             :   // Loop through all of the actions for adding output objects
     420      197709 :   for (ActionIterator it = _awh.actionBlocksWithActionBegin("add_output");
     421      535860 :        it != _awh.actionBlocksWithActionEnd("add_output");
     422      112717 :        it++)
     423             :   {
     424      113816 :     MooseObjectAction * moa = dynamic_cast<MooseObjectAction *>(*it);
     425      113816 :     if (!moa)
     426       67578 :       continue;
     427             : 
     428       46238 :     const std::string & type = moa->getMooseObjectType();
     429       46238 :     InputParameters & params = moa->getObjectParams();
     430       46238 :     if (type.compare("Console") == 0 && params.get<bool>("output_screen"))
     431        1099 :       return true;
     432             :   }
     433             : 
     434       64804 :   return false;
     435             : }

Generated by: LCOV version 1.14