LCOV - code coverage report
Current view: top level - src/outputs - OutputWarehouse.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 39a256 Lines: 202 212 95.3 %
Date: 2026-07-14 14:36:17 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       67671 : OutputWarehouse::OutputWarehouse(MooseApp & app)
      26             :   : PerfGraphInterface(app, "OutputWarehouse"),
      27       67671 :     _app(app),
      28       67671 :     _buffer_action_console_outputs(false),
      29       67671 :     _common_params_ptr(NULL),
      30       67671 :     _output_exec_flag(EXEC_CUSTOM),
      31       67671 :     _force_output(false),
      32       67671 :     _last_message_ended_in_newline(true),
      33       67671 :     _last_buffer(NULL),
      34      270684 :     _num_printed(0)
      35             : {
      36             :   // Set the reserved names
      37      135342 :   _reserved.insert("none"); // allows 'none' to be used as a keyword in 'outputs' parameter
      38      135342 :   _reserved.insert("all");  // allows 'all' to be used as a keyword in 'outputs' parameter
      39       67671 : }
      40             : 
      41       63539 : OutputWarehouse::~OutputWarehouse()
      42             : {
      43             :   // If the output buffer is not empty, it needs to be written
      44       63539 :   if (_console_buffer.str().length())
      45           0 :     mooseConsole();
      46       63539 : }
      47             : 
      48             : void
      49       60142 : OutputWarehouse::initialSetup()
      50             : {
      51      300710 :   TIME_SECTION("initialSetup", 5, "Setting Up Outputs");
      52             : 
      53       60142 :   resetFileBase();
      54             : 
      55      344443 :   for (const auto & obj : _all_objects)
      56      284347 :     obj->initialSetup();
      57       60096 : }
      58             : 
      59             : void
      60      269309 : OutputWarehouse::timestepSetup()
      61             : {
      62     1524107 :   for (const auto & obj : _all_objects)
      63     1254798 :     obj->timestepSetup();
      64      269309 : }
      65             : 
      66             : void
      67     1798456 : OutputWarehouse::customSetup(const ExecFlagType & exec_type)
      68             : {
      69    10270786 :   for (const auto & obj : _all_objects)
      70     8472330 :     obj->customSetup(exec_type);
      71     1798456 : }
      72             : 
      73             : void
      74      342522 : OutputWarehouse::solveSetup()
      75             : {
      76     1955352 :   for (const auto & obj : _all_objects)
      77     1612830 :     obj->solveSetup();
      78      342522 : }
      79             : 
      80             : void
      81      500962 : OutputWarehouse::jacobianSetup()
      82             : {
      83     2897175 :   for (const auto & obj : _all_objects)
      84     2396213 :     obj->jacobianSetup();
      85      500962 : }
      86             : 
      87             : void
      88     3056602 : OutputWarehouse::residualSetup()
      89             : {
      90    17367456 :   for (const auto & obj : _all_objects)
      91    14310854 :     obj->residualSetup();
      92     3056602 : }
      93             : 
      94             : void
      95     5083659 : OutputWarehouse::subdomainSetup()
      96             : {
      97    29365093 :   for (const auto & obj : _all_objects)
      98    24281434 :     obj->subdomainSetup();
      99     5083659 : }
     100             : 
     101             : void
     102      288752 : OutputWarehouse::addOutput(std::shared_ptr<Output> const output)
     103             : {
     104      288752 :   _all_ptrs.push_back(output);
     105             : 
     106             :   // Add the object to the warehouse storage, Checkpoint placed at end so they are called last
     107      288752 :   Checkpoint * cp = dynamic_cast<Checkpoint *>(output.get());
     108      288752 :   if (cp != NULL)
     109       48965 :     _all_objects.push_back(output.get());
     110             :   else
     111      239787 :     _all_objects.insert(_all_objects.begin(), output.get());
     112             : 
     113             :   // Store the name and pointer
     114      288752 :   _object_map[output->name()] = output.get();
     115      288752 :   _object_names.insert(output->name());
     116             : 
     117             :   // Insert object sync times to the global set
     118      288752 :   const std::set<Real> & sync_times = output->getSyncTimes();
     119      288752 :   _sync_times.insert(sync_times.begin(), sync_times.end());
     120      288752 : }
     121             : 
     122             : bool
     123      324705 : OutputWarehouse::hasOutput(const std::string & name) const
     124             : {
     125      324705 :   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      258907 : OutputWarehouse::getOutputNames()
     144             : {
     145      371157 :   if (_object_names.empty() && _app.actionWarehouse().hasActions("add_output"))
     146             :   {
     147      112198 :     const auto & actions = _app.actionWarehouse().getActionListByName("add_output");
     148      333261 :     for (const auto & act : actions)
     149      277162 :       _object_names.insert(act->name());
     150             :   }
     151      258907 :   return _object_names;
     152             : }
     153             : 
     154             : void
     155      164171 : OutputWarehouse::addOutputFilename(const OutputName & obj_name, const OutFileBase & filename)
     156             : {
     157      164171 :   _file_base_map[obj_name].insert(filename);
     158      482267 :   for (const auto & it : _file_base_map)
     159      318099 :     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      164168 : }
     162             : 
     163             : void
     164     1240331 : OutputWarehouse::outputStep(ExecFlagType type)
     165             : {
     166     1240331 :   if (_force_output)
     167          23 :     type = EXEC_FORCED;
     168             : 
     169     7065039 :   for (const auto & obj : _all_objects)
     170     5824717 :     if (obj->enabled())
     171     5824717 :       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     1240322 :   flushConsoleBuffer();
     184             : 
     185             :   // Reset force output flag
     186     1240322 :   _force_output = false;
     187     1240322 : }
     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      122423 : OutputWarehouse::mooseConsole()
     200             : {
     201      122423 :   mooseConsole(_console_buffer);
     202      122423 : }
     203             : 
     204             : void
     205     5144215 : OutputWarehouse::mooseConsole(std::ostringstream & buffer)
     206             : {
     207     5144215 :   std::lock_guard<std::mutex> lock(moose_console_mutex);
     208             : 
     209     5144215 :   std::string message = buffer.str();
     210             : 
     211             :   // If someone else is writing - then we may need a newline
     212     5144215 :   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     5144215 :   std::vector<Console *> objects = getOutputs<Console>();
     217     5144215 :   if (!objects.empty())
     218             :   {
     219    10234322 :     for (const auto & obj : objects)
     220     5117269 :       obj->mooseConsole(message);
     221             : 
     222             :     // Reset
     223     5117053 :     buffer.clear();
     224    10234106 :     buffer.str("");
     225             :   }
     226       81486 :   else if (_app.actionWarehouse().hasTask("add_output") &&
     227      108648 :            !_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       26851 :     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       26851 :     if (_app.multiAppLevel() > 0)
     237         826 :       MooseUtils::indentMessage(_app.name(), message, COLOR_CYAN, _last_message_ended_in_newline);
     238             : 
     239       26851 :     Moose::out << message << std::flush;
     240       26851 :     buffer.clear();
     241       26851 :     buffer.str("");
     242             : 
     243       26851 :     _last_message_ended_in_newline = this_message_ends_in_newline;
     244             :   }
     245             : 
     246     5144215 :   _last_buffer = &buffer;
     247             : 
     248     5144215 :   _num_printed++;
     249     5144215 : }
     250             : 
     251             : void
     252    10121646 : OutputWarehouse::flushConsoleBuffer()
     253             : {
     254    10121646 :   if (!_console_buffer.str().empty())
     255           0 :     mooseConsole();
     256    10121646 : }
     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       12319 : OutputWarehouse::getFileNumbers()
     281             : {
     282             : 
     283       12319 :   std::map<std::string, unsigned int> output;
     284       12940 :   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       12319 :   return output;
     291           0 : }
     292             : 
     293             : void
     294       66742 : OutputWarehouse::setCommonParameters(const InputParameters * params_ptr)
     295             : {
     296       66742 :   _common_params_ptr = params_ptr;
     297       66742 : }
     298             : 
     299             : const InputParameters *
     300      288700 : OutputWarehouse::getCommonParameters() const
     301             : {
     302      288700 :   return _common_params_ptr;
     303             : }
     304             : 
     305             : std::set<Real> &
     306       61224 : OutputWarehouse::getSyncTimes()
     307             : {
     308       61224 :   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     2138643 : 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     2138643 :       _interface_map.find(output_name);
     324     2138643 :   if (it != _interface_map.end())
     325      111894 :     hide = it->second;
     326     2138643 : }
     327             : 
     328             : void
     329      528578 : OutputWarehouse::checkOutputs(const std::set<OutputName> & names,
     330             :                               const bool supports_material_output)
     331             : {
     332      528578 :   std::string reserved_name = "";
     333      591299 :   for (const auto & name : names)
     334             :   {
     335       62733 :     const bool is_reserved_name = isReservedName(name);
     336       62733 :     if (is_reserved_name)
     337       27873 :       reserved_name = name;
     338       62733 :     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      528566 :   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      528563 : }
     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       77112 : OutputWarehouse::isReservedName(const std::string & name)
     372             : {
     373       77112 :   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        5207 : OutputWarehouse::reset()
     397             : {
     398       24262 :   for (const auto & pair : _object_map)
     399             :   {
     400       19055 :     auto * table = dynamic_cast<TableOutput *>(pair.second);
     401       19055 :     if (table != NULL)
     402        5542 :       table->clear();
     403       19055 :     auto * exodus = dynamic_cast<Exodus *>(pair.second);
     404       19055 :     if (exodus != NULL)
     405        2567 :       exodus->clear();
     406             :   }
     407        5207 : }
     408             : 
     409             : void
     410       72353 : OutputWarehouse::resetFileBase()
     411             : {
     412             :   // Set the file base from the application to FileOutputs and add associated filenames
     413      356783 :   for (const auto & obj : _all_objects)
     414      284433 :     if (FileOutput * file_output = dynamic_cast<FileOutput *>(obj))
     415             :     {
     416      164171 :       std::string file_base;
     417      164171 :       if (obj->parameters().get<bool>("_built_by_moose"))
     418             :       {
     419      454362 :         if (obj->isParamValid("file_base"))
     420      124329 :           file_base = obj->getParam<std::string>("file_base");
     421             :         else
     422      110011 :           file_base = _app.getOutputFileBase();
     423             :       }
     424             :       else
     425       12717 :         file_base = _app.getOutputFileBase(true) + "_" + obj->name();
     426             : 
     427      164171 :       file_output->setFileBase(file_base);
     428      164171 :       addOutputFilename(obj->name(), file_output->filename());
     429      164168 :     }
     430       72350 : }

Generated by: LCOV version 1.14