LCOV - code coverage report
Current view: top level - src/outputs - OutputWarehouse.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 419b9d Lines: 201 212 94.8 %
Date: 2025-08-08 20:01:16 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       67610 : OutputWarehouse::OutputWarehouse(MooseApp & app)
      26             :   : PerfGraphInterface(app, "OutputWarehouse"),
      27       67610 :     _app(app),
      28       67610 :     _buffer_action_console_outputs(false),
      29       67610 :     _common_params_ptr(NULL),
      30       67610 :     _output_exec_flag(EXEC_CUSTOM),
      31       67610 :     _force_output(false),
      32       67610 :     _last_message_ended_in_newline(true),
      33       67610 :     _last_buffer(NULL),
      34      135220 :     _num_printed(0)
      35             : {
      36             :   // Set the reserved names
      37       67610 :   _reserved.insert("none"); // allows 'none' to be used as a keyword in 'outputs' parameter
      38       67610 :   _reserved.insert("all");  // allows 'all' to be used as a keyword in 'outputs' parameter
      39       67610 : }
      40             : 
      41       62074 : OutputWarehouse::~OutputWarehouse()
      42             : {
      43             :   // If the output buffer is not empty, it needs to be written
      44       62074 :   if (_console_buffer.str().length())
      45           0 :     mooseConsole();
      46       62074 : }
      47             : 
      48             : void
      49       59988 : OutputWarehouse::initialSetup()
      50             : {
      51       59988 :   TIME_SECTION("initialSetup", 5, "Setting Up Outputs");
      52             : 
      53       59988 :   resetFileBase();
      54             : 
      55      341865 :   for (const auto & obj : _all_objects)
      56      281945 :     obj->initialSetup();
      57       59920 : }
      58             : 
      59             : void
      60      283095 : OutputWarehouse::timestepSetup()
      61             : {
      62     1603221 :   for (const auto & obj : _all_objects)
      63     1320126 :     obj->timestepSetup();
      64      283095 : }
      65             : 
      66             : void
      67     1881224 : OutputWarehouse::customSetup(const ExecFlagType & exec_type)
      68             : {
      69    10720921 :   for (const auto & obj : _all_objects)
      70     8839697 :     obj->customSetup(exec_type);
      71     1881224 : }
      72             : 
      73             : void
      74      364096 : OutputWarehouse::solveSetup()
      75             : {
      76     2080416 :   for (const auto & obj : _all_objects)
      77     1716320 :     obj->solveSetup();
      78      364096 : }
      79             : 
      80             : void
      81      522603 : OutputWarehouse::jacobianSetup()
      82             : {
      83     2997808 :   for (const auto & obj : _all_objects)
      84     2475205 :     obj->jacobianSetup();
      85      522603 : }
      86             : 
      87             : void
      88     3281351 : OutputWarehouse::residualSetup()
      89             : {
      90    18631111 :   for (const auto & obj : _all_objects)
      91    15349760 :     obj->residualSetup();
      92     3281351 : }
      93             : 
      94             : void
      95     5395947 : OutputWarehouse::subdomainSetup()
      96             : {
      97    31121439 :   for (const auto & obj : _all_objects)
      98    25725492 :     obj->subdomainSetup();
      99     5395947 : }
     100             : 
     101             : void
     102      287391 : OutputWarehouse::addOutput(std::shared_ptr<Output> const output)
     103             : {
     104      287391 :   _all_ptrs.push_back(output);
     105             : 
     106             :   // Add the object to the warehouse storage, Checkpoint placed at end so they are called last
     107      287391 :   Checkpoint * cp = dynamic_cast<Checkpoint *>(output.get());
     108      287391 :   if (cp != NULL)
     109       48978 :     _all_objects.push_back(output.get());
     110             :   else
     111      238413 :     _all_objects.insert(_all_objects.begin(), output.get());
     112             : 
     113             :   // Store the name and pointer
     114      287391 :   _object_map[output->name()] = output.get();
     115      287391 :   _object_names.insert(output->name());
     116             : 
     117             :   // Insert object sync times to the global set
     118      287391 :   const std::set<Real> & sync_times = output->getSyncTimes();
     119      287391 :   _sync_times.insert(sync_times.begin(), sync_times.end());
     120      287391 : }
     121             : 
     122             : bool
     123      344835 : OutputWarehouse::hasOutput(const std::string & name) const
     124             : {
     125      344835 :   return _object_map.find(name) != _object_map.end();
     126             : }
     127             : 
     128             : bool
     129        1195 : OutputWarehouse::hasMaterialPropertyOutput(const std::string & name) const
     130             : {
     131        1195 :   const auto found_object = hasOutput(name);
     132        1195 :   if (!found_object)
     133           0 :     return false;
     134             :   else
     135             :   {
     136             :     // Check if output object supports material property output
     137        1195 :     const auto * output_object = static_cast<const Output *>(_object_map.at(name));
     138        1195 :     return output_object->supportsMaterialPropertyOutput();
     139             :   }
     140             : }
     141             : 
     142             : const std::set<OutputName> &
     143      264013 : OutputWarehouse::getOutputNames()
     144             : {
     145      264013 :   if (_object_names.empty() && _app.actionWarehouse().hasActions("add_output"))
     146             :   {
     147       57696 :     const auto & actions = _app.actionWarehouse().getActionListByName("add_output");
     148      341134 :     for (const auto & act : actions)
     149      283438 :       _object_names.insert(act->name());
     150             :   }
     151      264013 :   return _object_names;
     152             : }
     153             : 
     154             : void
     155      163808 : OutputWarehouse::addOutputFilename(const OutputName & obj_name, const OutFileBase & filename)
     156             : {
     157      163808 :   _file_base_map[obj_name].insert(filename);
     158      481158 :   for (const auto & it : _file_base_map)
     159      317354 :     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      163804 : }
     162             : 
     163             : void
     164     1304132 : OutputWarehouse::outputStep(ExecFlagType type)
     165             : {
     166     1304132 :   if (_force_output)
     167          25 :     type = EXEC_FORCED;
     168             : 
     169     7432448 :   for (const auto & obj : _all_objects)
     170     6128328 :     if (obj->enabled())
     171     6128328 :       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     1304120 :   flushConsoleBuffer();
     184             : 
     185             :   // Reset force output flag
     186     1304120 :   _force_output = false;
     187     1304120 : }
     188             : 
     189             : void
     190        3363 : OutputWarehouse::meshChanged()
     191             : {
     192        3671 :   for (const auto & obj : _all_objects)
     193         308 :     obj->meshChanged();
     194        3363 : }
     195             : 
     196             : static std::mutex moose_console_mutex;
     197             : 
     198             : void
     199      122464 : OutputWarehouse::mooseConsole()
     200             : {
     201      122464 :   mooseConsole(_console_buffer);
     202      122464 : }
     203             : 
     204             : void
     205     6058017 : OutputWarehouse::mooseConsole(std::ostringstream & buffer)
     206             : {
     207     6058017 :   std::lock_guard<std::mutex> lock(moose_console_mutex);
     208             : 
     209     6058017 :   std::string message = buffer.str();
     210             : 
     211             :   // If someone else is writing - then we may need a newline
     212     6058017 :   if (&buffer != _last_buffer && !_last_message_ended_in_newline)
     213         106 :     message = '\n' + message;
     214             : 
     215             :   // Loop through all Console Output objects and pass the current output buffer
     216     6058017 :   std::vector<Console *> objects = getOutputs<Console>();
     217     6058017 :   if (!objects.empty())
     218             :   {
     219    12051420 :     for (const auto & obj : objects)
     220     6026221 :       obj->mooseConsole(message);
     221             : 
     222             :     // Reset
     223     6025199 :     buffer.clear();
     224     6025199 :     buffer.str("");
     225             :   }
     226       32818 :   else if (!_app.actionWarehouse().isTaskComplete("add_output"))
     227             :   {
     228       32814 :     if (!_buffer_action_console_outputs)
     229             :     {
     230             :       // this will cause messages to console before its construction immediately flushed and
     231             :       // cleared.
     232       32814 :       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       32814 :       if (_app.multiAppLevel() > 0)
     238         526 :         MooseUtils::indentMessage(_app.name(), message, COLOR_CYAN, _last_message_ended_in_newline);
     239             : 
     240       32814 :       Moose::out << message << std::flush;
     241       32814 :       buffer.clear();
     242       32814 :       buffer.str("");
     243             : 
     244       32814 :       _last_message_ended_in_newline = this_message_ends_in_newline;
     245             :     }
     246             :   }
     247             : 
     248     6058017 :   _last_buffer = &buffer;
     249             : 
     250     6058017 :   _num_printed++;
     251     6058017 : }
     252             : 
     253             : void
     254    10711428 : OutputWarehouse::flushConsoleBuffer()
     255             : {
     256    10711428 :   if (!_console_buffer.str().empty())
     257           0 :     mooseConsole();
     258    10711428 : }
     259             : 
     260             : void
     261        8522 : OutputWarehouse::setFileNumbers(std::map<std::string, unsigned int> input, unsigned int offset)
     262             : {
     263       41146 :   for (const auto & obj : _all_objects)
     264             :   {
     265       32624 :     FileOutput * ptr = dynamic_cast<FileOutput *>(obj);
     266       32624 :     if (ptr != NULL)
     267             :     {
     268       15554 :       std::map<std::string, unsigned int>::const_iterator it = input.find(ptr->name());
     269       15554 :       if (it != input.end())
     270             :       {
     271         194 :         int value = it->second + offset;
     272         194 :         if (value < 0)
     273           0 :           ptr->setFileNumber(0);
     274             :         else
     275         194 :           ptr->setFileNumber(it->second + offset);
     276             :       }
     277             :     }
     278             :   }
     279        8522 : }
     280             : 
     281             : std::map<std::string, unsigned int>
     282       12440 : OutputWarehouse::getFileNumbers()
     283             : {
     284             : 
     285       12440 :   std::map<std::string, unsigned int> output;
     286       13124 :   for (const auto & obj : _all_objects)
     287             :   {
     288         684 :     FileOutput * ptr = dynamic_cast<FileOutput *>(obj);
     289         684 :     if (ptr != NULL)
     290         380 :       output[ptr->name()] = ptr->getFileNumber();
     291             :   }
     292       12440 :   return output;
     293           0 : }
     294             : 
     295             : void
     296       66767 : OutputWarehouse::setCommonParameters(const InputParameters * params_ptr)
     297             : {
     298       66767 :   _common_params_ptr = params_ptr;
     299       66767 : }
     300             : 
     301             : const InputParameters *
     302      287405 : OutputWarehouse::getCommonParameters() const
     303             : {
     304      287405 :   return _common_params_ptr;
     305             : }
     306             : 
     307             : std::set<Real> &
     308       61489 : OutputWarehouse::getSyncTimes()
     309             : {
     310       61489 :   return _sync_times;
     311             : }
     312             : 
     313             : void
     314       58647 : OutputWarehouse::addInterfaceHideVariables(const std::string & output_name,
     315             :                                            const std::set<std::string> & variable_names)
     316             : {
     317       58647 :   _interface_map[output_name].insert(variable_names.begin(), variable_names.end());
     318       58647 : }
     319             : 
     320             : void
     321     2195054 : 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     2195054 :       _interface_map.find(output_name);
     326     2195054 :   if (it != _interface_map.end())
     327      117534 :     hide = it->second;
     328     2195054 : }
     329             : 
     330             : void
     331      542612 : OutputWarehouse::checkOutputs(const std::set<OutputName> & names,
     332             :                               const bool supports_material_output)
     333             : {
     334      542612 :   std::string reserved_name = "";
     335      627296 :   for (const auto & name : names)
     336             :   {
     337       84700 :     const bool is_reserved_name = isReservedName(name);
     338       84700 :     if (is_reserved_name)
     339       28490 :       reserved_name = name;
     340       84700 :     if (!is_reserved_name)
     341             :     {
     342       56210 :       if (!hasOutput(name))
     343          12 :         mooseError("The output object '", name, "' is not a defined output object.");
     344       56198 :       if (supports_material_output && !hasMaterialPropertyOutput(name))
     345           4 :         mooseError("The output object '", name, "' does not support material output.");
     346             :     }
     347             :   }
     348      542596 :   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      542592 : }
     352             : 
     353             : std::set<OutputName>
     354        4360 : OutputWarehouse::getAllMaterialPropertyOutputNames() const
     355             : {
     356        4360 :   std::set<OutputName> output_names;
     357       15378 :   for (const auto & pair : _object_map)
     358             :   {
     359       11018 :     const auto * output = static_cast<const Output *>(pair.second);
     360       11018 :     if (output->supportsMaterialPropertyOutput())
     361        4284 :       output_names.insert(pair.first);
     362             :   }
     363        4360 :   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       99077 : OutputWarehouse::isReservedName(const std::string & name)
     374             : {
     375       99077 :   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       89374 : OutputWarehouse::allowOutput(bool state)
     386             : {
     387      437047 :   for (const auto & obj : _all_objects)
     388      347673 :     obj->allowOutput(state);
     389       89374 : }
     390             : 
     391             : void
     392          25 : OutputWarehouse::forceOutput()
     393             : {
     394          25 :   _force_output = true;
     395          25 : }
     396             : 
     397             : void
     398        4257 : OutputWarehouse::reset()
     399             : {
     400       20464 :   for (const auto & pair : _object_map)
     401             :   {
     402       16207 :     auto * table = dynamic_cast<TableOutput *>(pair.second);
     403       16207 :     if (table != NULL)
     404        4568 :       table->clear();
     405       16207 :     auto * exodus = dynamic_cast<Exodus *>(pair.second);
     406       16207 :     if (exodus != NULL)
     407        2719 :       exodus->clear();
     408             :   }
     409        4257 : }
     410             : 
     411             : void
     412       72326 : OutputWarehouse::resetFileBase()
     413             : {
     414             :   // Set the file base from the application to FileOutputs and add associated filenames
     415      354395 :   for (const auto & obj : _all_objects)
     416      282073 :     if (FileOutput * file_output = dynamic_cast<FileOutput *>(obj))
     417             :     {
     418      163808 :       std::string file_base;
     419      163808 :       if (obj->parameters().get<bool>("_built_by_moose"))
     420             :       {
     421      151037 :         if (obj->isParamValid("file_base"))
     422       40373 :           file_base = obj->getParam<std::string>("file_base");
     423             :         else
     424      110664 :           file_base = _app.getOutputFileBase();
     425             :       }
     426             :       else
     427       12771 :         file_base = _app.getOutputFileBase(true) + "_" + obj->name();
     428             : 
     429      163808 :       file_output->setFileBase(file_base);
     430      163808 :       addOutputFilename(obj->name(), file_output->filename());
     431      163804 :     }
     432       72322 : }

Generated by: LCOV version 1.14