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

Generated by: LCOV version 1.14