LCOV - code coverage report
Current view: top level - src/outputs - OutputWarehouse.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #33416 (b10b36) with base 9fbd27 Lines: 202 212 95.3 %
Date: 2026-07-23 16:15:30 Functions: 34 36 94.4 %
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 "OutputWarehouse.h"
      12             : #include "Output.h"
      13             : #include "Console.h"
      14             : #include "FileOutput.h"
      15             : #include "Checkpoint.h"
      16             : #include "FEProblem.h"
      17             : #include "TableOutput.h"
      18             : #include "Exodus.h"
      19             : 
      20             : #include <libgen.h>
      21             : #include <sys/types.h>
      22             : #include <sys/stat.h>
      23             : #include <unistd.h>
      24             : 
      25       68103 : OutputWarehouse::OutputWarehouse(MooseApp & app)
      26             :   : PerfGraphInterface(app, "OutputWarehouse"),
      27       68103 :     _app(app),
      28       68103 :     _buffer_action_console_outputs(false),
      29       68103 :     _common_params_ptr(NULL),
      30       68103 :     _output_exec_flag(EXEC_CUSTOM),
      31       68103 :     _force_output(false),
      32       68103 :     _last_message_ended_in_newline(true),
      33       68103 :     _last_buffer(NULL),
      34      272412 :     _num_printed(0)
      35             : {
      36             :   // Set the reserved names
      37      136206 :   _reserved.insert("none"); // allows 'none' to be used as a keyword in 'outputs' parameter
      38      136206 :   _reserved.insert("all");  // allows 'all' to be used as a keyword in 'outputs' parameter
      39       68103 : }
      40             : 
      41       63958 : OutputWarehouse::~OutputWarehouse()
      42             : {
      43             :   // If the output buffer is not empty, it needs to be written
      44       63958 :   if (_console_buffer.str().length())
      45           0 :     mooseConsole();
      46       63958 : }
      47             : 
      48             : void
      49       60532 : OutputWarehouse::initialSetup()
      50             : {
      51      302660 :   TIME_SECTION("initialSetup", 5, "Setting Up Outputs");
      52             : 
      53       60532 :   resetFileBase();
      54             : 
      55      346580 :   for (const auto & obj : _all_objects)
      56      286094 :     obj->initialSetup();
      57       60486 : }
      58             : 
      59             : void
      60      270214 : OutputWarehouse::timestepSetup()
      61             : {
      62     1529695 :   for (const auto & obj : _all_objects)
      63     1259481 :     obj->timestepSetup();
      64      270214 : }
      65             : 
      66             : void
      67     1800883 : OutputWarehouse::customSetup(const ExecFlagType & exec_type)
      68             : {
      69    10285842 :   for (const auto & obj : _all_objects)
      70     8484959 :     obj->customSetup(exec_type);
      71     1800883 : }
      72             : 
      73             : void
      74      342930 : OutputWarehouse::solveSetup()
      75             : {
      76     1957822 :   for (const auto & obj : _all_objects)
      77     1614892 :     obj->solveSetup();
      78      342930 : }
      79             : 
      80             : void
      81      501034 : OutputWarehouse::jacobianSetup()
      82             : {
      83     2897954 :   for (const auto & obj : _all_objects)
      84     2396920 :     obj->jacobianSetup();
      85      501034 : }
      86             : 
      87             : void
      88     3056630 : OutputWarehouse::residualSetup()
      89             : {
      90    17367887 :   for (const auto & obj : _all_objects)
      91    14311257 :     obj->residualSetup();
      92     3056630 : }
      93             : 
      94             : void
      95     5084655 : OutputWarehouse::subdomainSetup()
      96             : {
      97    29371437 :   for (const auto & obj : _all_objects)
      98    24286782 :     obj->subdomainSetup();
      99     5084655 : }
     100             : 
     101             : void
     102      290523 : OutputWarehouse::addOutput(std::shared_ptr<Output> const output)
     103             : {
     104      290523 :   _all_ptrs.push_back(output);
     105             : 
     106             :   // Add the object to the warehouse storage, Checkpoint placed at end so they are called last
     107      290523 :   Checkpoint * cp = dynamic_cast<Checkpoint *>(output.get());
     108      290523 :   if (cp != NULL)
     109       49364 :     _all_objects.push_back(output.get());
     110             :   else
     111      241159 :     _all_objects.insert(_all_objects.begin(), output.get());
     112             : 
     113             :   // Store the name and pointer
     114      290523 :   _object_map[output->name()] = output.get();
     115      290523 :   _object_names.insert(output->name());
     116             : 
     117             :   // Insert object sync times to the global set
     118      290523 :   const std::set<Real> & sync_times = output->getSyncTimes();
     119      290523 :   _sync_times.insert(sync_times.begin(), sync_times.end());
     120      290523 : }
     121             : 
     122             : bool
     123      326476 : OutputWarehouse::hasOutput(const std::string & name) const
     124             : {
     125      326476 :   return _object_map.find(name) != _object_map.end();
     126             : }
     127             : 
     128             : bool
     129        1126 : OutputWarehouse::hasMaterialPropertyOutput(const std::string & name) const
     130             : {
     131        1126 :   const auto found_object = hasOutput(name);
     132        1126 :   if (!found_object)
     133           0 :     return false;
     134             :   else
     135             :   {
     136             :     // Check if output object supports material property output
     137        1126 :     const auto * output_object = static_cast<const Output *>(_object_map.at(name));
     138        1126 :     return output_object->supportsMaterialPropertyOutput();
     139             :   }
     140             : }
     141             : 
     142             : const std::set<OutputName> &
     143      260203 : OutputWarehouse::getOutputNames()
     144             : {
     145      373035 :   if (_object_names.empty() && _app.actionWarehouse().hasActions("add_output"))
     146             :   {
     147      112704 :     const auto & actions = _app.actionWarehouse().getActionListByName("add_output");
     148      334622 :     for (const auto & act : actions)
     149      278270 :       _object_names.insert(act->name());
     150             :   }
     151      260203 :   return _object_names;
     152             : }
     153             : 
     154             : void
     155      165289 : OutputWarehouse::addOutputFilename(const OutputName & obj_name, const OutFileBase & filename)
     156             : {
     157      165289 :   _file_base_map[obj_name].insert(filename);
     158      485572 :   for (const auto & it : _file_base_map)
     159      320286 :     if (it.first != obj_name && it.second.find(filename) != it.second.end())
     160           3 :       mooseError("An output file with the name, ", filename, ", already exists.");
     161      165286 : }
     162             : 
     163             : void
     164     1243350 : OutputWarehouse::outputStep(ExecFlagType type)
     165             : {
     166     1243350 :   if (_force_output)
     167          23 :     type = EXEC_FORCED;
     168             : 
     169     7082676 :   for (const auto & obj : _all_objects)
     170     5839335 :     if (obj->enabled())
     171     5839335 :       obj->outputStep(type);
     172             : 
     173             :   /**
     174             :    * This is one of three locations where we explicitly flush the output buffers during a
     175             :    * simulation:
     176             :    * PetscOutput::petscNonlinearOutput()
     177             :    * PetscOutput::petscLinearOutput()
     178             :    * OutputWarehouse::outputStep()
     179             :    *
     180             :    * All other Console output _should_ be using newlines to avoid covering buffer errors
     181             :    * and to avoid excessive I/O
     182             :    */
     183     1243341 :   flushConsoleBuffer();
     184             : 
     185             :   // Reset force output flag
     186     1243341 :   _force_output = false;
     187     1243341 : }
     188             : 
     189             : void
     190        3429 : OutputWarehouse::meshChanged()
     191             : {
     192        3709 :   for (const auto & obj : _all_objects)
     193         280 :     obj->meshChanged();
     194        3429 : }
     195             : 
     196             : static std::mutex moose_console_mutex;
     197             : 
     198             : void
     199      123212 : OutputWarehouse::mooseConsole()
     200             : {
     201      123212 :   mooseConsole(_console_buffer);
     202      123212 : }
     203             : 
     204             : void
     205     5151186 : OutputWarehouse::mooseConsole(std::ostringstream & buffer)
     206             : {
     207     5151186 :   std::lock_guard<std::mutex> lock(moose_console_mutex);
     208             : 
     209     5151186 :   std::string message = buffer.str();
     210             : 
     211             :   // If someone else is writing - then we may need a newline
     212     5151186 :   if (&buffer != _last_buffer && !_last_message_ended_in_newline)
     213           0 :     message = '\n' + message;
     214             : 
     215             :   // Loop through all Console Output objects and pass the current output buffer
     216     5151186 :   std::vector<Console *> objects = getOutputs<Console>();
     217     5151186 :   if (!objects.empty())
     218             :   {
     219    10248210 :     for (const auto & obj : objects)
     220     5124213 :       obj->mooseConsole(message);
     221             : 
     222             :     // Reset
     223     5123997 :     buffer.clear();
     224    10247994 :     buffer.str("");
     225             :   }
     226       81567 :   else if (_app.actionWarehouse().hasTask("add_output") &&
     227      108756 :            !_app.actionWarehouse().isTaskComplete("add_output") && !_buffer_action_console_outputs)
     228             :   {
     229             :     // this will cause messages to console before its construction immediately flushed and
     230             :     // cleared.
     231       26878 :     bool this_message_ends_in_newline = message.empty() ? true : message.back() == '\n';
     232             : 
     233             :     // If that last message ended in newline then this one may need
     234             :     // to start with indenting
     235             :     // Note that we only indent the first line if the last message ended in new line
     236       26878 :     if (_app.multiAppLevel() > 0)
     237         826 :       MooseUtils::indentMessage(_app.name(), message, COLOR_CYAN, _last_message_ended_in_newline);
     238             : 
     239       26878 :     Moose::out << message << std::flush;
     240       26878 :     buffer.clear();
     241       26878 :     buffer.str("");
     242             : 
     243       26878 :     _last_message_ended_in_newline = this_message_ends_in_newline;
     244             :   }
     245             : 
     246     5151186 :   _last_buffer = &buffer;
     247             : 
     248     5151186 :   _num_printed++;
     249     5151186 : }
     250             : 
     251             : void
     252    10128206 : OutputWarehouse::flushConsoleBuffer()
     253             : {
     254    10128206 :   if (!_console_buffer.str().empty())
     255           0 :     mooseConsole();
     256    10128206 : }
     257             : 
     258             : void
     259        7964 : OutputWarehouse::setFileNumbers(std::map<std::string, unsigned int> input, unsigned int offset)
     260             : {
     261       38869 :   for (const auto & obj : _all_objects)
     262             :   {
     263       30905 :     FileOutput * ptr = dynamic_cast<FileOutput *>(obj);
     264       30905 :     if (ptr != NULL)
     265             :     {
     266       14957 :       std::map<std::string, unsigned int>::const_iterator it = input.find(ptr->name());
     267       14957 :       if (it != input.end())
     268             :       {
     269         176 :         int value = it->second + offset;
     270         176 :         if (value < 0)
     271           0 :           ptr->setFileNumber(0);
     272             :         else
     273         176 :           ptr->setFileNumber(it->second + offset);
     274             :       }
     275             :     }
     276             :   }
     277        7964 : }
     278             : 
     279             : std::map<std::string, unsigned int>
     280       12316 : OutputWarehouse::getFileNumbers()
     281             : {
     282             : 
     283       12316 :   std::map<std::string, unsigned int> output;
     284       12937 :   for (const auto & obj : _all_objects)
     285             :   {
     286         621 :     FileOutput * ptr = dynamic_cast<FileOutput *>(obj);
     287         621 :     if (ptr != NULL)
     288         345 :       output[ptr->name()] = ptr->getFileNumber();
     289             :   }
     290       12316 :   return output;
     291           0 : }
     292             : 
     293             : void
     294       67138 : OutputWarehouse::setCommonParameters(const InputParameters * params_ptr)
     295             : {
     296       67138 :   _common_params_ptr = params_ptr;
     297       67138 : }
     298             : 
     299             : const InputParameters *
     300      290471 : OutputWarehouse::getCommonParameters() const
     301             : {
     302      290471 :   return _common_params_ptr;
     303             : }
     304             : 
     305             : std::set<Real> &
     306       61422 : OutputWarehouse::getSyncTimes()
     307             : {
     308       61422 :   return _sync_times;
     309             : }
     310             : 
     311             : void
     312       51013 : OutputWarehouse::addInterfaceHideVariables(const std::string & output_name,
     313             :                                            const std::set<std::string> & variable_names)
     314             : {
     315       51013 :   _interface_map[output_name].insert(variable_names.begin(), variable_names.end());
     316       51013 : }
     317             : 
     318             : void
     319     2147445 : OutputWarehouse::buildInterfaceHideVariables(const std::string & output_name,
     320             :                                              std::set<std::string> & hide)
     321             : {
     322             :   std::map<std::string, std::set<std::string>>::const_iterator it =
     323     2147445 :       _interface_map.find(output_name);
     324     2147445 :   if (it != _interface_map.end())
     325      111894 :     hide = it->second;
     326     2147445 : }
     327             : 
     328             : void
     329      530935 : OutputWarehouse::checkOutputs(const std::set<OutputName> & names,
     330             :                               const bool supports_material_output)
     331             : {
     332      530935 :   std::string reserved_name = "";
     333      593773 :   for (const auto & name : names)
     334             :   {
     335       62850 :     const bool is_reserved_name = isReservedName(name);
     336       62850 :     if (is_reserved_name)
     337       27990 :       reserved_name = name;
     338       62850 :     if (!is_reserved_name)
     339             :     {
     340       34860 :       if (!hasOutput(name))
     341           9 :         mooseError("The output object '", name, "' is not a defined output object.");
     342       34851 :       if (supports_material_output && !hasMaterialPropertyOutput(name))
     343           3 :         mooseError("The output object '", name, "' does not support material output.");
     344             :     }
     345             :   }
     346      530923 :   if (!reserved_name.empty() && names.size() > 1)
     347           3 :     mooseError("When setting output name to reserved name '" + reserved_name +
     348             :                "', only one entry is allowed in outputs parameter.");
     349      530920 : }
     350             : 
     351             : std::set<OutputName>
     352        4127 : OutputWarehouse::getAllMaterialPropertyOutputNames() const
     353             : {
     354        4127 :   std::set<OutputName> output_names;
     355       14561 :   for (const auto & pair : _object_map)
     356             :   {
     357       10434 :     const auto * output = static_cast<const Output *>(pair.second);
     358       10434 :     if (output->supportsMaterialPropertyOutput())
     359        4064 :       output_names.insert(pair.first);
     360             :   }
     361        4127 :   return output_names;
     362           0 : }
     363             : 
     364             : const std::set<std::string> &
     365           2 : OutputWarehouse::getReservedNames() const
     366             : {
     367           2 :   return _reserved;
     368             : }
     369             : 
     370             : bool
     371       77600 : OutputWarehouse::isReservedName(const std::string & name)
     372             : {
     373       77600 :   return _reserved.find(name) != _reserved.end();
     374             : }
     375             : 
     376             : void
     377           0 : OutputWarehouse::setOutputExecutionType(ExecFlagType type)
     378             : {
     379           0 :   _output_exec_flag = type;
     380           0 : }
     381             : 
     382             : void
     383       83891 : OutputWarehouse::allowOutput(bool state)
     384             : {
     385      410296 :   for (const auto & obj : _all_objects)
     386      326405 :     obj->allowOutput(state);
     387       83891 : }
     388             : 
     389             : void
     390          23 : OutputWarehouse::forceOutput()
     391             : {
     392          23 :   _force_output = true;
     393          23 : }
     394             : 
     395             : void
     396        5168 : OutputWarehouse::reset()
     397             : {
     398       24106 :   for (const auto & pair : _object_map)
     399             :   {
     400       18938 :     auto * table = dynamic_cast<TableOutput *>(pair.second);
     401       18938 :     if (table != NULL)
     402        5503 :       table->clear();
     403       18938 :     auto * exodus = dynamic_cast<Exodus *>(pair.second);
     404       18938 :     if (exodus != NULL)
     405        2567 :       exodus->clear();
     406             :   }
     407        5168 : }
     408             : 
     409             : void
     410       72740 : OutputWarehouse::resetFileBase()
     411             : {
     412             :   // Set the file base from the application to FileOutputs and add associated filenames
     413      358917 :   for (const auto & obj : _all_objects)
     414      286180 :     if (FileOutput * file_output = dynamic_cast<FileOutput *>(obj))
     415             :     {
     416      165289 :       std::string file_base;
     417      165289 :       if (obj->parameters().get<bool>("_built_by_moose"))
     418             :       {
     419      456603 :         if (obj->isParamValid("file_base"))
     420      125727 :           file_base = obj->getParam<std::string>("file_base");
     421             :         else
     422      110292 :           file_base = _app.getOutputFileBase();
     423             :       }
     424             :       else
     425       13088 :         file_base = _app.getOutputFileBase(true) + "_" + obj->name();
     426             : 
     427      165289 :       file_output->setFileBase(file_base);
     428      165289 :       addOutputFilename(obj->name(), file_output->filename());
     429      165286 :     }
     430       72737 : }

Generated by: LCOV version 1.14