LCOV - code coverage report
Current view: top level - src/outputs - OutputWarehouse.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 909fe5 Lines: 200 212 94.3 %
Date: 2025-08-29 20:01:24 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       68420 : OutputWarehouse::OutputWarehouse(MooseApp & app)
      26             :   : PerfGraphInterface(app, "OutputWarehouse"),
      27       68420 :     _app(app),
      28       68420 :     _buffer_action_console_outputs(false),
      29       68420 :     _common_params_ptr(NULL),
      30       68420 :     _output_exec_flag(EXEC_CUSTOM),
      31       68420 :     _force_output(false),
      32       68420 :     _last_message_ended_in_newline(true),
      33       68420 :     _last_buffer(NULL),
      34      273680 :     _num_printed(0)
      35             : {
      36             :   // Set the reserved names
      37      136840 :   _reserved.insert("none"); // allows 'none' to be used as a keyword in 'outputs' parameter
      38      136840 :   _reserved.insert("all");  // allows 'all' to be used as a keyword in 'outputs' parameter
      39       68420 : }
      40             : 
      41       62828 : OutputWarehouse::~OutputWarehouse()
      42             : {
      43             :   // If the output buffer is not empty, it needs to be written
      44       62828 :   if (_console_buffer.str().length())
      45           0 :     mooseConsole();
      46       62828 : }
      47             : 
      48             : void
      49       60677 : OutputWarehouse::initialSetup()
      50             : {
      51      303385 :   TIME_SECTION("initialSetup", 5, "Setting Up Outputs");
      52             : 
      53       60677 :   resetFileBase();
      54             : 
      55      345925 :   for (const auto & obj : _all_objects)
      56      285316 :     obj->initialSetup();
      57       60609 : }
      58             : 
      59             : void
      60      285034 : OutputWarehouse::timestepSetup()
      61             : {
      62     1614370 :   for (const auto & obj : _all_objects)
      63     1329336 :     obj->timestepSetup();
      64      285034 : }
      65             : 
      66             : void
      67     1892273 : OutputWarehouse::customSetup(const ExecFlagType & exec_type)
      68             : {
      69    10784592 :   for (const auto & obj : _all_objects)
      70     8892319 :     obj->customSetup(exec_type);
      71     1892273 : }
      72             : 
      73             : void
      74      365801 : OutputWarehouse::solveSetup()
      75             : {
      76     2090097 :   for (const auto & obj : _all_objects)
      77     1724296 :     obj->solveSetup();
      78      365801 : }
      79             : 
      80             : void
      81      525227 : OutputWarehouse::jacobianSetup()
      82             : {
      83     3012823 :   for (const auto & obj : _all_objects)
      84     2487596 :     obj->jacobianSetup();
      85      525227 : }
      86             : 
      87             : void
      88     3296434 : OutputWarehouse::residualSetup()
      89             : {
      90    18721190 :   for (const auto & obj : _all_objects)
      91    15424756 :     obj->residualSetup();
      92     3296434 : }
      93             : 
      94             : void
      95     5588464 : OutputWarehouse::subdomainSetup()
      96             : {
      97    32275042 :   for (const auto & obj : _all_objects)
      98    26686578 :     obj->subdomainSetup();
      99     5588464 : }
     100             : 
     101             : void
     102      290782 : OutputWarehouse::addOutput(std::shared_ptr<Output> const output)
     103             : {
     104      290782 :   _all_ptrs.push_back(output);
     105             : 
     106             :   // Add the object to the warehouse storage, Checkpoint placed at end so they are called last
     107      290782 :   Checkpoint * cp = dynamic_cast<Checkpoint *>(output.get());
     108      290782 :   if (cp != NULL)
     109       49619 :     _all_objects.push_back(output.get());
     110             :   else
     111      241163 :     _all_objects.insert(_all_objects.begin(), output.get());
     112             : 
     113             :   // Store the name and pointer
     114      290782 :   _object_map[output->name()] = output.get();
     115      290782 :   _object_names.insert(output->name());
     116             : 
     117             :   // Insert object sync times to the global set
     118      290782 :   const std::set<Real> & sync_times = output->getSyncTimes();
     119      290782 :   _sync_times.insert(sync_times.begin(), sync_times.end());
     120      290782 : }
     121             : 
     122             : bool
     123      348226 : OutputWarehouse::hasOutput(const std::string & name) const
     124             : {
     125      348226 :   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      266075 : OutputWarehouse::getOutputNames()
     144             : {
     145      382459 :   if (_object_names.empty() && _app.actionWarehouse().hasActions("add_output"))
     146             :   {
     147      116370 :     const auto & actions = _app.actionWarehouse().getActionListByName("add_output");
     148      344046 :     for (const auto & act : actions)
     149      285861 :       _object_names.insert(act->name());
     150             :   }
     151      266075 :   return _object_names;
     152             : }
     153             : 
     154             : void
     155      165801 : OutputWarehouse::addOutputFilename(const OutputName & obj_name, const OutFileBase & filename)
     156             : {
     157      165801 :   _file_base_map[obj_name].insert(filename);
     158      487102 :   for (const auto & it : _file_base_map)
     159      321305 :     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      165797 : }
     162             : 
     163             : void
     164     1313883 : OutputWarehouse::outputStep(ExecFlagType type)
     165             : {
     166     1313883 :   if (_force_output)
     167          25 :     type = EXEC_FORCED;
     168             : 
     169     7488516 :   for (const auto & obj : _all_objects)
     170     6174645 :     if (obj->enabled())
     171     6174645 :       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     1313871 :   flushConsoleBuffer();
     184             : 
     185             :   // Reset force output flag
     186     1313871 :   _force_output = false;
     187     1313871 : }
     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      124035 : OutputWarehouse::mooseConsole()
     200             : {
     201      124035 :   mooseConsole(_console_buffer);
     202      124035 : }
     203             : 
     204             : void
     205     6082329 : OutputWarehouse::mooseConsole(std::ostringstream & buffer)
     206             : {
     207     6082329 :   std::lock_guard<std::mutex> lock(moose_console_mutex);
     208             : 
     209     6082329 :   std::string message = buffer.str();
     210             : 
     211             :   // If someone else is writing - then we may need a newline
     212     6082329 :   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     6082329 :   std::vector<Console *> objects = getOutputs<Console>();
     217     6082329 :   if (!objects.empty())
     218             :   {
     219    12099194 :     for (const auto & obj : objects)
     220     6050108 :       obj->mooseConsole(message);
     221             : 
     222             :     // Reset
     223     6049086 :     buffer.clear();
     224    12098172 :     buffer.str("");
     225             :   }
     226       99729 :   else if (_app.actionWarehouse().hasTask("add_output") &&
     227      132972 :            !_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       33239 :     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       33239 :     if (_app.multiAppLevel() > 0)
     237        1070 :       MooseUtils::indentMessage(_app.name(), message, COLOR_CYAN, _last_message_ended_in_newline);
     238             : 
     239       33239 :     Moose::out << message << std::flush;
     240       33239 :     buffer.clear();
     241       33239 :     buffer.str("");
     242             : 
     243       33239 :     _last_message_ended_in_newline = this_message_ends_in_newline;
     244             :   }
     245             : 
     246     6082329 :   _last_buffer = &buffer;
     247             : 
     248     6082329 :   _num_printed++;
     249     6082329 : }
     250             : 
     251             : void
     252    10772289 : OutputWarehouse::flushConsoleBuffer()
     253             : {
     254    10772289 :   if (!_console_buffer.str().empty())
     255           0 :     mooseConsole();
     256    10772289 : }
     257             : 
     258             : void
     259        8536 : OutputWarehouse::setFileNumbers(std::map<std::string, unsigned int> input, unsigned int offset)
     260             : {
     261       41216 :   for (const auto & obj : _all_objects)
     262             :   {
     263       32680 :     FileOutput * ptr = dynamic_cast<FileOutput *>(obj);
     264       32680 :     if (ptr != NULL)
     265             :     {
     266       15582 :       std::map<std::string, unsigned int>::const_iterator it = input.find(ptr->name());
     267       15582 :       if (it != input.end())
     268             :       {
     269         194 :         int value = it->second + offset;
     270         194 :         if (value < 0)
     271           0 :           ptr->setFileNumber(0);
     272             :         else
     273         194 :           ptr->setFileNumber(it->second + offset);
     274             :       }
     275             :     }
     276             :   }
     277        8536 : }
     278             : 
     279             : std::map<std::string, unsigned int>
     280       12492 : OutputWarehouse::getFileNumbers()
     281             : {
     282             : 
     283       12492 :   std::map<std::string, unsigned int> output;
     284       13176 :   for (const auto & obj : _all_objects)
     285             :   {
     286         684 :     FileOutput * ptr = dynamic_cast<FileOutput *>(obj);
     287         684 :     if (ptr != NULL)
     288         380 :       output[ptr->name()] = ptr->getFileNumber();
     289             :   }
     290       12492 :   return output;
     291           0 : }
     292             : 
     293             : void
     294       67586 : OutputWarehouse::setCommonParameters(const InputParameters * params_ptr)
     295             : {
     296       67586 :   _common_params_ptr = params_ptr;
     297       67586 : }
     298             : 
     299             : const InputParameters *
     300      290796 : OutputWarehouse::getCommonParameters() const
     301             : {
     302      290796 :   return _common_params_ptr;
     303             : }
     304             : 
     305             : std::set<Real> &
     306       62696 : OutputWarehouse::getSyncTimes()
     307             : {
     308       62696 :   return _sync_times;
     309             : }
     310             : 
     311             : void
     312       58647 : OutputWarehouse::addInterfaceHideVariables(const std::string & output_name,
     313             :                                            const std::set<std::string> & variable_names)
     314             : {
     315       58647 :   _interface_map[output_name].insert(variable_names.begin(), variable_names.end());
     316       58647 : }
     317             : 
     318             : void
     319     2213612 : 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     2213612 :       _interface_map.find(output_name);
     324     2213612 :   if (it != _interface_map.end())
     325      117534 :     hide = it->second;
     326     2213612 : }
     327             : 
     328             : void
     329      547033 : OutputWarehouse::checkOutputs(const std::set<OutputName> & names,
     330             :                               const bool supports_material_output)
     331             : {
     332      547033 :   std::string reserved_name = "";
     333      632189 :   for (const auto & name : names)
     334             :   {
     335       85172 :     const bool is_reserved_name = isReservedName(name);
     336       85172 :     if (is_reserved_name)
     337       28962 :       reserved_name = name;
     338       85172 :     if (!is_reserved_name)
     339             :     {
     340       56210 :       if (!hasOutput(name))
     341          12 :         mooseError("The output object '", name, "' is not a defined output object.");
     342       56198 :       if (supports_material_output && !hasMaterialPropertyOutput(name))
     343           4 :         mooseError("The output object '", name, "' does not support material output.");
     344             :     }
     345             :   }
     346      547017 :   if (!reserved_name.empty() && names.size() > 1)
     347           4 :     mooseError("When setting output name to reserved name '" + reserved_name +
     348             :                "', only one entry is allowed in outputs parameter.");
     349      547013 : }
     350             : 
     351             : std::set<OutputName>
     352        4360 : OutputWarehouse::getAllMaterialPropertyOutputNames() const
     353             : {
     354        4360 :   std::set<OutputName> output_names;
     355       15378 :   for (const auto & pair : _object_map)
     356             :   {
     357       11018 :     const auto * output = static_cast<const Output *>(pair.second);
     358       11018 :     if (output->supportsMaterialPropertyOutput())
     359        4284 :       output_names.insert(pair.first);
     360             :   }
     361        4360 :   return output_names;
     362           0 : }
     363             : 
     364             : const std::set<std::string> &
     365           0 : OutputWarehouse::getReservedNames() const
     366             : {
     367           0 :   return _reserved;
     368             : }
     369             : 
     370             : bool
     371       99777 : OutputWarehouse::isReservedName(const std::string & name)
     372             : {
     373       99777 :   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       89528 : OutputWarehouse::allowOutput(bool state)
     384             : {
     385      437817 :   for (const auto & obj : _all_objects)
     386      348289 :     obj->allowOutput(state);
     387       89528 : }
     388             : 
     389             : void
     390          25 : OutputWarehouse::forceOutput()
     391             : {
     392          25 :   _force_output = true;
     393          25 : }
     394             : 
     395             : void
     396        4358 : OutputWarehouse::reset()
     397             : {
     398       20897 :   for (const auto & pair : _object_map)
     399             :   {
     400       16539 :     auto * table = dynamic_cast<TableOutput *>(pair.second);
     401       16539 :     if (table != NULL)
     402        4669 :       table->clear();
     403       16539 :     auto * exodus = dynamic_cast<Exodus *>(pair.second);
     404       16539 :     if (exodus != NULL)
     405        2743 :       exodus->clear();
     406             :   }
     407        4358 : }
     408             : 
     409             : void
     410       73067 : OutputWarehouse::resetFileBase()
     411             : {
     412             :   // Set the file base from the application to FileOutputs and add associated filenames
     413      358507 :   for (const auto & obj : _all_objects)
     414      285444 :     if (FileOutput * file_output = dynamic_cast<FileOutput *>(obj))
     415             :     {
     416      165801 :       std::string file_base;
     417      165801 :       if (obj->parameters().get<bool>("_built_by_moose"))
     418             :       {
     419      458406 :         if (obj->isParamValid("file_base"))
     420      121467 :           file_base = obj->getParam<std::string>("file_base");
     421             :         else
     422      112313 :           file_base = _app.getOutputFileBase();
     423             :       }
     424             :       else
     425       12999 :         file_base = _app.getOutputFileBase(true) + "_" + obj->name();
     426             : 
     427      165801 :       file_output->setFileBase(file_base);
     428      165801 :       addOutputFilename(obj->name(), file_output->filename());
     429      165797 :     }
     430       73063 : }

Generated by: LCOV version 1.14