LCOV - code coverage report
Current view: top level - src/outputs - OutputWarehouse.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 201 212 94.8 %
Date: 2025-07-17 01:28:37 Functions: 33 36 91.7 %
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       62755 : OutputWarehouse::OutputWarehouse(MooseApp & app)
      26             :   : PerfGraphInterface(app, "OutputWarehouse"),
      27       62755 :     _app(app),
      28       62755 :     _buffer_action_console_outputs(false),
      29       62755 :     _common_params_ptr(NULL),
      30       62755 :     _output_exec_flag(EXEC_CUSTOM),
      31       62755 :     _force_output(false),
      32       62755 :     _last_message_ended_in_newline(true),
      33       62755 :     _last_buffer(NULL),
      34      125510 :     _num_printed(0)
      35             : {
      36             :   // Set the reserved names
      37       62755 :   _reserved.insert("none"); // allows 'none' to be used as a keyword in 'outputs' parameter
      38       62755 :   _reserved.insert("all");  // allows 'all' to be used as a keyword in 'outputs' parameter
      39       62755 : }
      40             : 
      41       57254 : OutputWarehouse::~OutputWarehouse()
      42             : {
      43             :   // If the output buffer is not empty, it needs to be written
      44       57254 :   if (_console_buffer.str().length())
      45           0 :     mooseConsole();
      46       57254 : }
      47             : 
      48             : void
      49       55472 : OutputWarehouse::initialSetup()
      50             : {
      51       55472 :   TIME_SECTION("initialSetup", 5, "Setting Up Outputs");
      52             : 
      53       55472 :   resetFileBase();
      54             : 
      55      316083 :   for (const auto & obj : _all_objects)
      56      260679 :     obj->initialSetup();
      57       55404 : }
      58             : 
      59             : void
      60      259232 : OutputWarehouse::timestepSetup()
      61             : {
      62     1467762 :   for (const auto & obj : _all_objects)
      63     1208530 :     obj->timestepSetup();
      64      259232 : }
      65             : 
      66             : void
      67     1724449 : OutputWarehouse::customSetup(const ExecFlagType & exec_type)
      68             : {
      69     9827341 :   for (const auto & obj : _all_objects)
      70     8102892 :     obj->customSetup(exec_type);
      71     1724449 : }
      72             : 
      73             : void
      74      334226 : OutputWarehouse::solveSetup()
      75             : {
      76     1909377 :   for (const auto & obj : _all_objects)
      77     1575151 :     obj->solveSetup();
      78      334226 : }
      79             : 
      80             : void
      81      481922 : OutputWarehouse::jacobianSetup()
      82             : {
      83     2764525 :   for (const auto & obj : _all_objects)
      84     2282603 :     obj->jacobianSetup();
      85      481922 : }
      86             : 
      87             : void
      88     3043777 : OutputWarehouse::residualSetup()
      89             : {
      90    17273775 :   for (const auto & obj : _all_objects)
      91    14229998 :     obj->residualSetup();
      92     3043777 : }
      93             : 
      94             : void
      95     4966466 : OutputWarehouse::subdomainSetup()
      96             : {
      97    28613337 :   for (const auto & obj : _all_objects)
      98    23646871 :     obj->subdomainSetup();
      99     4966466 : }
     100             : 
     101             : void
     102      266109 : OutputWarehouse::addOutput(std::shared_ptr<Output> const output)
     103             : {
     104      266109 :   _all_ptrs.push_back(output);
     105             : 
     106             :   // Add the object to the warehouse storage, Checkpoint placed at end so they are called last
     107      266109 :   Checkpoint * cp = dynamic_cast<Checkpoint *>(output.get());
     108      266109 :   if (cp != NULL)
     109       45426 :     _all_objects.push_back(output.get());
     110             :   else
     111      220683 :     _all_objects.insert(_all_objects.begin(), output.get());
     112             : 
     113             :   // Store the name and pointer
     114      266109 :   _object_map[output->name()] = output.get();
     115      266109 :   _object_names.insert(output->name());
     116             : 
     117             :   // Insert object sync times to the global set
     118      266109 :   const std::set<Real> & sync_times = output->getSyncTimes();
     119      266109 :   _sync_times.insert(sync_times.begin(), sync_times.end());
     120      266109 : }
     121             : 
     122             : bool
     123      322508 : OutputWarehouse::hasOutput(const std::string & name) const
     124             : {
     125      322508 :   return _object_map.find(name) != _object_map.end();
     126             : }
     127             : 
     128             : bool
     129        1113 : OutputWarehouse::hasMaterialPropertyOutput(const std::string & name) const
     130             : {
     131        1113 :   const auto found_object = hasOutput(name);
     132        1113 :   if (!found_object)
     133           0 :     return false;
     134             :   else
     135             :   {
     136             :     // Check if output object supports material property output
     137        1113 :     const auto * output_object = static_cast<const Output *>(_object_map.at(name));
     138        1113 :     return output_object->supportsMaterialPropertyOutput();
     139             :   }
     140             : }
     141             : 
     142             : const std::set<OutputName> &
     143      245818 : OutputWarehouse::getOutputNames()
     144             : {
     145      245818 :   if (_object_names.empty() && _app.actionWarehouse().hasActions("add_output"))
     146             :   {
     147       53574 :     const auto & actions = _app.actionWarehouse().getActionListByName("add_output");
     148      316659 :     for (const auto & act : actions)
     149      263085 :       _object_names.insert(act->name());
     150             :   }
     151      245818 :   return _object_names;
     152             : }
     153             : 
     154             : void
     155      151476 : OutputWarehouse::addOutputFilename(const OutputName & obj_name, const OutFileBase & filename)
     156             : {
     157      151476 :   _file_base_map[obj_name].insert(filename);
     158      445006 :   for (const auto & it : _file_base_map)
     159      293534 :     if (it.first != obj_name && it.second.find(filename) != it.second.end())
     160           4 :       mooseError("An output file with the name, ", filename, ", already exists.");
     161      151472 : }
     162             : 
     163             : void
     164     1138888 : OutputWarehouse::outputStep(ExecFlagType type)
     165             : {
     166     1138888 :   if (_force_output)
     167          22 :     type = EXEC_FORCED;
     168             : 
     169     6486239 :   for (const auto & obj : _all_objects)
     170     5347363 :     if (obj->enabled())
     171     5347363 :       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     1138876 :   flushConsoleBuffer();
     184             : 
     185             :   // Reset force output flag
     186     1138876 :   _force_output = false;
     187     1138876 : }
     188             : 
     189             : void
     190        3078 : OutputWarehouse::meshChanged()
     191             : {
     192        3366 :   for (const auto & obj : _all_objects)
     193         288 :     obj->meshChanged();
     194        3078 : }
     195             : 
     196             : static std::mutex moose_console_mutex;
     197             : 
     198             : void
     199      113404 : OutputWarehouse::mooseConsole()
     200             : {
     201      113404 :   mooseConsole(_console_buffer);
     202      113404 : }
     203             : 
     204             : void
     205     5592324 : OutputWarehouse::mooseConsole(std::ostringstream & buffer)
     206             : {
     207     5592324 :   std::lock_guard<std::mutex> lock(moose_console_mutex);
     208             : 
     209     5592324 :   std::string message = buffer.str();
     210             : 
     211             :   // If someone else is writing - then we may need a newline
     212     5592324 :   if (&buffer != _last_buffer && !_last_message_ended_in_newline)
     213         116 :     message = '\n' + message;
     214             : 
     215             :   // Loop through all Console Output objects and pass the current output buffer
     216     5592324 :   std::vector<Console *> objects = getOutputs<Console>();
     217     5592324 :   if (!objects.empty())
     218             :   {
     219    11129478 :     for (const auto & obj : objects)
     220     5565250 :       obj->mooseConsole(message);
     221             : 
     222             :     // Reset
     223     5564228 :     buffer.clear();
     224     5564228 :     buffer.str("");
     225             :   }
     226       28096 :   else if (!_app.actionWarehouse().isTaskComplete("add_output"))
     227             :   {
     228       28092 :     if (!_buffer_action_console_outputs)
     229             :     {
     230             :       // this will cause messages to console before its construction immediately flushed and
     231             :       // cleared.
     232       28092 :       bool this_message_ends_in_newline = message.empty() ? true : message.back() == '\n';
     233             : 
     234             :       // If that last message ended in newline then this one may need
     235             :       // to start with indenting
     236             :       // Note that we only indent the first line if the last message ended in new line
     237       28092 :       if (_app.multiAppLevel() > 0)
     238         512 :         MooseUtils::indentMessage(_app.name(), message, COLOR_CYAN, _last_message_ended_in_newline);
     239             : 
     240       28092 :       Moose::out << message << std::flush;
     241       28092 :       buffer.clear();
     242       28092 :       buffer.str("");
     243             : 
     244       28092 :       _last_message_ended_in_newline = this_message_ends_in_newline;
     245             :     }
     246             :   }
     247             : 
     248     5592324 :   _last_buffer = &buffer;
     249             : 
     250     5592324 :   _num_printed++;
     251     5592324 : }
     252             : 
     253             : void
     254     9838097 : OutputWarehouse::flushConsoleBuffer()
     255             : {
     256     9838097 :   if (!_console_buffer.str().empty())
     257           0 :     mooseConsole();
     258     9838097 : }
     259             : 
     260             : void
     261        7854 : OutputWarehouse::setFileNumbers(std::map<std::string, unsigned int> input, unsigned int offset)
     262             : {
     263       37891 :   for (const auto & obj : _all_objects)
     264             :   {
     265       30037 :     FileOutput * ptr = dynamic_cast<FileOutput *>(obj);
     266       30037 :     if (ptr != NULL)
     267             :     {
     268       14305 :       std::map<std::string, unsigned int>::const_iterator it = input.find(ptr->name());
     269       14305 :       if (it != input.end())
     270             :       {
     271         180 :         int value = it->second + offset;
     272         180 :         if (value < 0)
     273           0 :           ptr->setFileNumber(0);
     274             :         else
     275         180 :           ptr->setFileNumber(it->second + offset);
     276             :       }
     277             :     }
     278             :   }
     279        7854 : }
     280             : 
     281             : std::map<std::string, unsigned int>
     282       11463 : OutputWarehouse::getFileNumbers()
     283             : {
     284             : 
     285       11463 :   std::map<std::string, unsigned int> output;
     286       12093 :   for (const auto & obj : _all_objects)
     287             :   {
     288         630 :     FileOutput * ptr = dynamic_cast<FileOutput *>(obj);
     289         630 :     if (ptr != NULL)
     290         350 :       output[ptr->name()] = ptr->getFileNumber();
     291             :   }
     292       11463 :   return output;
     293           0 : }
     294             : 
     295             : void
     296       61914 : OutputWarehouse::setCommonParameters(const InputParameters * params_ptr)
     297             : {
     298       61914 :   _common_params_ptr = params_ptr;
     299       61914 : }
     300             : 
     301             : const InputParameters *
     302      266123 : OutputWarehouse::getCommonParameters() const
     303             : {
     304      266123 :   return _common_params_ptr;
     305             : }
     306             : 
     307             : std::set<Real> &
     308       57032 : OutputWarehouse::getSyncTimes()
     309             : {
     310       57032 :   return _sync_times;
     311             : }
     312             : 
     313             : void
     314       55443 : OutputWarehouse::addInterfaceHideVariables(const std::string & output_name,
     315             :                                            const std::set<std::string> & variable_names)
     316             : {
     317       55443 :   _interface_map[output_name].insert(variable_names.begin(), variable_names.end());
     318       55443 : }
     319             : 
     320             : void
     321     2020070 : OutputWarehouse::buildInterfaceHideVariables(const std::string & output_name,
     322             :                                              std::set<std::string> & hide)
     323             : {
     324             :   std::map<std::string, std::set<std::string>>::const_iterator it =
     325     2020070 :       _interface_map.find(output_name);
     326     2020070 :   if (it != _interface_map.end())
     327      111090 :     hide = it->second;
     328     2020070 : }
     329             : 
     330             : void
     331      500809 : OutputWarehouse::checkOutputs(const std::set<OutputName> & names,
     332             :                               const bool supports_material_output)
     333             : {
     334      500809 :   std::string reserved_name = "";
     335      582394 :   for (const auto & name : names)
     336             :   {
     337       81601 :     const bool is_reserved_name = isReservedName(name);
     338       81601 :     if (is_reserved_name)
     339       26354 :       reserved_name = name;
     340       81601 :     if (!is_reserved_name)
     341             :     {
     342       55247 :       if (!hasOutput(name))
     343          12 :         mooseError("The output object '", name, "' is not a defined output object.");
     344       55235 :       if (supports_material_output && !hasMaterialPropertyOutput(name))
     345           4 :         mooseError("The output object '", name, "' does not support material output.");
     346             :     }
     347             :   }
     348      500793 :   if (!reserved_name.empty() && names.size() > 1)
     349           4 :     mooseError("When setting output name to reserved name '" + reserved_name +
     350             :                "', only one entry is allowed in outputs parameter.");
     351      500789 : }
     352             : 
     353             : std::set<OutputName>
     354        4038 : OutputWarehouse::getAllMaterialPropertyOutputNames() const
     355             : {
     356        4038 :   std::set<OutputName> output_names;
     357       14233 :   for (const auto & pair : _object_map)
     358             :   {
     359       10195 :     const auto * output = static_cast<const Output *>(pair.second);
     360       10195 :     if (output->supportsMaterialPropertyOutput())
     361        3960 :       output_names.insert(pair.first);
     362             :   }
     363        4038 :   return output_names;
     364           0 : }
     365             : 
     366             : const std::set<std::string> &
     367           0 : OutputWarehouse::getReservedNames() const
     368             : {
     369           0 :   return _reserved;
     370             : }
     371             : 
     372             : bool
     373       94755 : OutputWarehouse::isReservedName(const std::string & name)
     374             : {
     375       94755 :   return _reserved.find(name) != _reserved.end();
     376             : }
     377             : 
     378             : void
     379           0 : OutputWarehouse::setOutputExecutionType(ExecFlagType type)
     380             : {
     381           0 :   _output_exec_flag = type;
     382           0 : }
     383             : 
     384             : void
     385       81694 : OutputWarehouse::allowOutput(bool state)
     386             : {
     387      399411 :   for (const auto & obj : _all_objects)
     388      317717 :     obj->allowOutput(state);
     389       81694 : }
     390             : 
     391             : void
     392          22 : OutputWarehouse::forceOutput()
     393             : {
     394          22 :   _force_output = true;
     395          22 : }
     396             : 
     397             : void
     398        3814 : OutputWarehouse::reset()
     399             : {
     400       18363 :   for (const auto & pair : _object_map)
     401             :   {
     402       14549 :     auto * table = dynamic_cast<TableOutput *>(pair.second);
     403       14549 :     if (table != NULL)
     404        4098 :       table->clear();
     405       14549 :     auto * exodus = dynamic_cast<Exodus *>(pair.second);
     406       14549 :     if (exodus != NULL)
     407        2463 :       exodus->clear();
     408             :   }
     409        3814 : }
     410             : 
     411             : void
     412       66839 : OutputWarehouse::resetFileBase()
     413             : {
     414             :   // Set the file base from the application to FileOutputs and add associated filenames
     415      327642 :   for (const auto & obj : _all_objects)
     416      260807 :     if (FileOutput * file_output = dynamic_cast<FileOutput *>(obj))
     417             :     {
     418      151476 :       std::string file_base;
     419      151476 :       if (obj->parameters().get<bool>("_built_by_moose"))
     420             :       {
     421      139849 :         if (obj->isParamValid("file_base"))
     422       37204 :           file_base = obj->getParam<std::string>("file_base");
     423             :         else
     424      102645 :           file_base = _app.getOutputFileBase();
     425             :       }
     426             :       else
     427       11627 :         file_base = _app.getOutputFileBase(true) + "_" + obj->name();
     428             : 
     429      151476 :       file_output->setFileBase(file_base);
     430      151476 :       addOutputFilename(obj->name(), file_output->filename());
     431      151472 :     }
     432       66835 : }

Generated by: LCOV version 1.14