LCOV - code coverage report
Current view: top level - src/utils - FormattedTable.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 419b9d Lines: 302 328 92.1 %
Date: 2025-08-08 20:01:16 Functions: 27 28 96.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             : #include "FormattedTable.h"
      11             : #include "MooseError.h"
      12             : #include "MooseUtils.h"
      13             : 
      14             : #include "libmesh/exodusII_io.h"
      15             : 
      16             : #include <iomanip>
      17             : #include <iterator>
      18             : 
      19             : const unsigned short FormattedTable::_column_width = 15;
      20             : const unsigned short FormattedTable::_min_pps_width = 40;
      21             : 
      22             : const unsigned short DEFAULT_CSV_PRECISION = 14;
      23             : const std::string DEFAULT_CSV_DELIMITER = ",";
      24             : 
      25             : template <>
      26             : void
      27      225350 : dataStore(std::ostream & stream, FormattedTable & table, void * context)
      28             : {
      29      225350 :   table.fillEmptyValues();
      30      225350 :   storeHelper(stream, table._data, context);
      31      225350 :   storeHelper(stream, table._align_widths, context);
      32      225350 :   storeHelper(stream, table._column_names, context);
      33      225350 :   storeHelper(stream, table._output_row_index, context);
      34      225350 :   storeHelper(stream, table._headers_output, context);
      35      225350 : }
      36             : 
      37             : template <>
      38             : void
      39       62037 : dataLoad(std::istream & stream, FormattedTable & table, void * context)
      40             : {
      41       62037 :   loadHelper(stream, table._data, context);
      42       62037 :   loadHelper(stream, table._align_widths, context);
      43       62037 :   loadHelper(stream, table._column_names, context);
      44       62037 :   loadHelper(stream, table._output_row_index, context);
      45       62037 :   loadHelper(stream, table._headers_output, context);
      46       62037 : }
      47             : 
      48             : template <>
      49             : void
      50     1601383 : dataStore(std::ostream & stream, std::shared_ptr<TableValueBase> & value_base, void * context)
      51             : {
      52     1601383 :   value_base->store(stream, context);
      53     1601383 : }
      54             : 
      55             : template <>
      56             : void
      57       66548 : dataLoad(std::istream & stream, std::shared_ptr<TableValueBase> & value_base, void * context)
      58             : {
      59       66548 :   std::string type;
      60       66548 :   dataLoad(stream, type, context);
      61       66548 :   if (type == typeid(bool).name())
      62           0 :     TableValue<bool>::load(stream, value_base, context);
      63             : 
      64       66548 :   else if (type == typeid(unsigned short int).name())
      65           0 :     TableValue<unsigned short int>::load(stream, value_base, context);
      66             : 
      67       66548 :   else if (type == typeid(unsigned int).name())
      68         564 :     TableValue<unsigned int>::load(stream, value_base, context);
      69             : 
      70       65984 :   else if (type == typeid(unsigned long int).name())
      71          56 :     TableValue<unsigned long int>::load(stream, value_base, context);
      72             : 
      73       65928 :   else if (type == typeid(unsigned long long int).name())
      74           0 :     TableValue<unsigned long long int>::load(stream, value_base, context);
      75             : 
      76       65928 :   else if (type == typeid(short int).name())
      77           0 :     TableValue<short int>::load(stream, value_base, context);
      78             : 
      79       65928 :   else if (type == typeid(int).name())
      80         370 :     TableValue<int>::load(stream, value_base, context);
      81             : 
      82       65558 :   else if (type == typeid(long int).name())
      83           0 :     TableValue<long int>::load(stream, value_base, context);
      84             : 
      85       65558 :   else if (type == typeid(long long int).name())
      86           0 :     TableValue<long long int>::load(stream, value_base, context);
      87             : 
      88       65558 :   else if (type == typeid(float).name())
      89           0 :     TableValue<float>::load(stream, value_base, context);
      90             : 
      91       65558 :   else if (type == typeid(double).name())
      92       65194 :     TableValue<double>::load(stream, value_base, context);
      93             : 
      94         364 :   else if (type == typeid(long double).name())
      95           0 :     TableValue<long double>::load(stream, value_base, context);
      96             : 
      97         364 :   else if (type == typeid(char).name())
      98           0 :     TableValue<char>::load(stream, value_base, context);
      99             : 
     100         364 :   else if (type == typeid(char *).name())
     101           0 :     TableValue<char *>::load(stream, value_base, context);
     102             : 
     103         364 :   else if (type == typeid(std::string).name())
     104         364 :     TableValue<std::string>::load(stream, value_base, context);
     105             : 
     106             :   else
     107           0 :     mooseError("Unsupported table value type ", demangle(type.c_str()));
     108       66548 : }
     109             : 
     110             : void
     111      460536 : FormattedTable::close()
     112             : {
     113      460536 :   if (!_output_file.is_open())
     114      398930 :     return;
     115       61606 :   _output_file.flush();
     116       61606 :   _output_file.close();
     117       61606 :   _output_file_name = "";
     118             : }
     119             : 
     120             : void
     121       61606 : FormattedTable::open(const std::string & file_name)
     122             : {
     123       61606 :   if (_output_file.is_open() && _output_file_name == file_name)
     124           0 :     return;
     125       61606 :   close();
     126       61606 :   _output_file_name = file_name;
     127             : 
     128       61606 :   std::ios_base::openmode open_flags = std::ios::out;
     129       61606 :   if (_append)
     130        2169 :     open_flags |= std::ios::app;
     131             :   else
     132             :   {
     133       59437 :     open_flags |= std::ios::trunc;
     134       59437 :     _output_row_index = 0;
     135       59437 :     _headers_output = false;
     136             :   }
     137             : 
     138       61606 :   _output_file.open(file_name.c_str(), open_flags);
     139       61606 :   if (_output_file.fail())
     140           0 :     mooseError("Unable to open file ", file_name);
     141             : }
     142             : 
     143      347772 : FormattedTable::FormattedTable()
     144      347772 :   : _output_row_index(0),
     145      347772 :     _headers_output(false),
     146      347772 :     _append(false),
     147      347772 :     _output_time(true),
     148      347772 :     _csv_delimiter(DEFAULT_CSV_DELIMITER),
     149      347772 :     _csv_precision(DEFAULT_CSV_PRECISION)
     150             : {
     151      347772 : }
     152             : 
     153        3915 : FormattedTable::FormattedTable(const FormattedTable & o)
     154        3915 :   : _column_names(o._column_names),
     155        3915 :     _output_file_name(""),
     156        3915 :     _output_row_index(o._output_row_index),
     157        3915 :     _headers_output(o._headers_output),
     158        3915 :     _append(o._append),
     159        3915 :     _output_time(o._output_time),
     160        3915 :     _csv_delimiter(o._csv_delimiter),
     161        3915 :     _csv_precision(o._csv_precision),
     162        7830 :     _column_names_unsorted(o._column_names_unsorted)
     163             : {
     164        3915 :   if (_output_file.is_open())
     165           0 :     mooseError("Copying a FormattedTable with an open stream is not supported");
     166             : 
     167        3915 :   for (const auto & it : o._data)
     168           0 :     _data.emplace_back(it.first, it.second);
     169        3915 : }
     170             : 
     171      337324 : FormattedTable::~FormattedTable() { close(); }
     172             : 
     173             : bool
     174     1385607 : FormattedTable::empty() const
     175             : {
     176     1385607 :   return _data.empty();
     177             : }
     178             : 
     179             : void
     180         837 : FormattedTable::append(bool append_existing_file)
     181             : {
     182         837 :   _append = append_existing_file;
     183         837 : }
     184             : 
     185             : void
     186      367964 : FormattedTable::addRow(Real time)
     187             : {
     188      367964 :   _data.emplace_back(time, std::map<std::string, std::shared_ptr<TableValueBase>>());
     189      367964 : }
     190             : 
     191             : Real
     192      322240 : FormattedTable::getLastTime() const
     193             : {
     194             :   mooseAssert(!empty(), "No Data stored in the FormattedTable");
     195      322240 :   return _data.rbegin()->first;
     196             : }
     197             : 
     198             : void
     199       36035 : FormattedTable::printOmittedRow(std::ostream & out,
     200             :                                 std::map<std::string, unsigned short> & col_widths,
     201             :                                 std::vector<std::string>::iterator & col_begin,
     202             :                                 std::vector<std::string>::iterator & col_end) const
     203             : {
     204       36035 :   printNoDataRow(':', ' ', out, col_widths, col_begin, col_end);
     205       36035 : }
     206             : 
     207             : void
     208      417624 : FormattedTable::printRowDivider(std::ostream & out,
     209             :                                 std::map<std::string, unsigned short> & col_widths,
     210             :                                 std::vector<std::string>::iterator & col_begin,
     211             :                                 std::vector<std::string>::iterator & col_end) const
     212             : {
     213      417624 :   printNoDataRow('+', '-', out, col_widths, col_begin, col_end);
     214      417624 : }
     215             : 
     216             : void
     217      453659 : FormattedTable::printNoDataRow(char intersect_char,
     218             :                                char fill_char,
     219             :                                std::ostream & out,
     220             :                                std::map<std::string, unsigned short> & col_widths,
     221             :                                std::vector<std::string>::iterator & col_begin,
     222             :                                std::vector<std::string>::iterator & col_end) const
     223             : {
     224      453659 :   out.fill(fill_char);
     225      453659 :   out << std::right << intersect_char;
     226      453659 :   if (_output_time)
     227      453659 :     out << std::setw(_column_width + 2) << intersect_char;
     228     1295115 :   for (auto header_it = col_begin; header_it != col_end; ++header_it)
     229      841456 :     out << std::setw(col_widths[*header_it] + 2) << intersect_char;
     230      453659 :   out << "\n";
     231             : 
     232             :   // Clear the fill character
     233      453659 :   out.fill(' ');
     234      453659 : }
     235             : 
     236             : void
     237           0 : FormattedTable::printTable(const std::string & file_name)
     238             : {
     239           0 :   open(file_name);
     240           0 :   printTable(_output_file);
     241           0 : }
     242             : 
     243             : void
     244           4 : FormattedTable::printTable(std::ostream & out, unsigned int last_n_entries)
     245             : {
     246           4 :   printTable(out, last_n_entries, MooseEnum("ENVIRONMENT=-1", "ENVIRONMENT"));
     247           4 : }
     248             : 
     249             : void
     250      134504 : FormattedTable::printTable(std::ostream & out,
     251             :                            unsigned int last_n_entries,
     252             :                            const MooseEnum & suggested_term_width)
     253             : {
     254             :   unsigned short term_width;
     255             : 
     256      134504 :   if (suggested_term_width == "ENVIRONMENT")
     257      134090 :     term_width = MooseUtils::getTermWidth(true);
     258         414 :   else if (suggested_term_width == "AUTO")
     259           0 :     term_width = MooseUtils::getTermWidth(false);
     260             :   else
     261         416 :     term_width = MooseUtils::stringToInteger(suggested_term_width);
     262             : 
     263      134498 :   if (term_width < _min_pps_width)
     264           0 :     term_width = _min_pps_width;
     265             : 
     266      134498 :   std::vector<std::string>::iterator col_it = _column_names.begin();
     267      134498 :   std::vector<std::string>::iterator col_end = _column_names.end();
     268             : 
     269      134498 :   std::vector<std::string>::iterator curr_begin = col_it;
     270      134498 :   std::vector<std::string>::iterator curr_end;
     271      273706 :   while (col_it != col_end)
     272             :   {
     273      139208 :     std::map<std::string, unsigned short> col_widths;
     274      139208 :     unsigned int curr_width = _column_width + 4;
     275      139208 :     unsigned int cols_in_group = 0;
     276      410302 :     while (curr_width < term_width && col_it != col_end)
     277             :     {
     278      271094 :       curr_end = col_it;
     279      271094 :       col_widths[*col_it] = col_it->length() > _column_width ? col_it->length() + 1 : _column_width;
     280             : 
     281      271094 :       curr_width += col_widths[*col_it] + 3;
     282      271094 :       ++col_it;
     283      271094 :       ++cols_in_group;
     284             :     }
     285      139208 :     if (col_it != col_end && cols_in_group >= 2)
     286             :     {
     287             :       // curr_width -= col_widths[*curr_end];
     288        4710 :       col_widths.erase(*curr_end);
     289        4710 :       col_it = curr_end;
     290             :     }
     291             :     else
     292      134498 :       curr_end = col_it;
     293             : 
     294      139208 :     printTablePiece(out, last_n_entries, col_widths, curr_begin, curr_end);
     295      139208 :     curr_begin = curr_end;
     296      139208 :   }
     297      134498 : }
     298             : 
     299             : void
     300      139208 : FormattedTable::printTablePiece(std::ostream & out,
     301             :                                 unsigned int last_n_entries,
     302             :                                 std::map<std::string, unsigned short> & col_widths,
     303             :                                 std::vector<std::string>::iterator & col_begin,
     304             :                                 std::vector<std::string>::iterator & col_end)
     305             : {
     306      139208 :   fillEmptyValues(last_n_entries);
     307             :   /**
     308             :    * Print out the header row
     309             :    */
     310      139208 :   printRowDivider(out, col_widths, col_begin, col_end);
     311      139208 :   out << "|";
     312      139208 :   if (_output_time)
     313      139208 :     out << std::setw(_column_width) << std::left << " time" << " |";
     314      405592 :   for (auto header_it = col_begin; header_it != col_end; ++header_it)
     315      266384 :     out << " " << std::setw(col_widths[*header_it]) << *header_it << "|";
     316      139208 :   out << "\n";
     317      139208 :   printRowDivider(out, col_widths, col_begin, col_end);
     318             : 
     319      139208 :   auto data_it = _data.begin();
     320      139208 :   if (last_n_entries)
     321             :   {
     322      139206 :     if (_data.size() > last_n_entries)
     323             :     {
     324             :       // Print a blank row to indicate that values have been ommited
     325       36035 :       printOmittedRow(out, col_widths, col_begin, col_end);
     326             : 
     327             :       // Jump to the right place in the vector
     328       36035 :       data_it += _data.size() - last_n_entries;
     329             :     }
     330             :   }
     331             :   // Now print the remaining data rows
     332     1097127 :   for (; data_it != _data.end(); ++data_it)
     333             :   {
     334      957919 :     out << "|";
     335      957919 :     if (_output_time)
     336      957919 :       out << std::right << std::setw(_column_width) << std::scientific << data_it->first << " |";
     337     2484644 :     for (auto header_it = col_begin; header_it != col_end; ++header_it)
     338             :     {
     339     1526725 :       auto & tmp = data_it->second;
     340     1526725 :       out << std::setw(col_widths[*header_it]) << *tmp[*header_it] << " |";
     341             :     }
     342      957919 :     out << "\n";
     343             :   }
     344             : 
     345      139208 :   printRowDivider(out, col_widths, col_begin, col_end);
     346      139208 : }
     347             : 
     348             : void
     349       61606 : FormattedTable::printCSV(const std::string & file_name, int interval, bool align)
     350             : {
     351       61606 :   fillEmptyValues();
     352             : 
     353       61606 :   open(file_name);
     354             : 
     355       61606 :   if (_output_row_index == 0)
     356             :   {
     357             :     /**
     358             :      * When the alignment option is set to true, the widths of the columns needs to be computed
     359             :      * based on longest of the column name of the data supplied. This is done here by creating a
     360             :      * map
     361             :      * of the widths for each of the columns, including time
     362             :      */
     363       59492 :     if (align)
     364             :     {
     365             :       // Set the initial width to the names of the columns
     366          34 :       _align_widths["time"] = 4;
     367             : 
     368         272 :       for (const auto & col_name : _column_names)
     369         238 :         _align_widths[col_name] = col_name.size();
     370             : 
     371             :       // Loop through the various times
     372         117 :       for (const auto & it : _data)
     373             :       {
     374             :         // Update the time _align_width
     375             :         {
     376          83 :           std::ostringstream oss;
     377          83 :           oss << std::setprecision(_csv_precision) << it.first;
     378          83 :           unsigned int w = oss.str().size();
     379          83 :           _align_widths["time"] = std::max(_align_widths["time"], w);
     380          83 :         }
     381             : 
     382             :         // Loop through the data for the current time and update the _align_widths
     383         664 :         for (const auto & jt : it.second)
     384             :         {
     385         581 :           std::ostringstream oss;
     386         581 :           oss << std::setprecision(_csv_precision) << *jt.second;
     387         581 :           unsigned int w = oss.str().size();
     388         581 :           _align_widths[jt.first] = std::max(_align_widths[jt.first], w);
     389         581 :         }
     390             :       }
     391             :     }
     392             : 
     393             :     // Output Header
     394       59492 :     if (!_headers_output)
     395             :     {
     396       59492 :       if (_output_time)
     397             :       {
     398       52694 :         if (align)
     399          34 :           _output_file << std::setw(_align_widths["time"]) << "time";
     400             :         else
     401       52660 :           _output_file << "time";
     402       52694 :         _headers_output = true;
     403             :       }
     404             : 
     405      217350 :       for (const auto & col_name : _column_names)
     406             :       {
     407      157858 :         if (_headers_output)
     408      151060 :           _output_file << _csv_delimiter;
     409             : 
     410      157858 :         if (align)
     411         238 :           _output_file << std::right << std::setw(_align_widths[col_name]) << col_name;
     412             :         else
     413      157620 :           _output_file << col_name;
     414      157858 :         _headers_output = true;
     415             :       }
     416       59492 :       _output_file << "\n";
     417             :     }
     418             :   }
     419             : 
     420     5120539 :   for (; _output_row_index < _data.size(); ++_output_row_index)
     421             :   {
     422     5058933 :     if (_output_row_index % interval == 0)
     423     5058933 :       printRow(_data[_output_row_index], align);
     424             :   }
     425             : 
     426       61606 :   close();
     427       61606 : }
     428             : 
     429             : void
     430     5058933 : FormattedTable::printRow(
     431             :     std::pair<Real, std::map<std::string, std::shared_ptr<TableValueBase>>> & row_data, bool align)
     432             : {
     433     5058933 :   bool first = true;
     434             : 
     435     5058933 :   if (_output_time)
     436             :   {
     437     4874643 :     if (align)
     438          85 :       _output_file << std::setprecision(_csv_precision) << std::right
     439          85 :                    << std::setw(_align_widths["time"]) << row_data.first;
     440             :     else
     441     4874558 :       _output_file << std::setprecision(_csv_precision) << row_data.first;
     442     4874643 :     first = false;
     443             :   }
     444             : 
     445    15554507 :   for (const auto & col_name : _column_names)
     446             :   {
     447    10495574 :     std::map<std::string, std::shared_ptr<TableValueBase>> & tmp = row_data.second;
     448             : 
     449    10495574 :     if (!first)
     450    10311284 :       _output_file << _csv_delimiter;
     451             :     else
     452      184290 :       first = false;
     453             : 
     454    10495574 :     if (align)
     455         595 :       _output_file << std::setprecision(_csv_precision) << std::right
     456         595 :                    << std::setw(_align_widths[col_name]) << *tmp[col_name];
     457             :     else
     458    10494979 :       _output_file << std::setprecision(_csv_precision) << *tmp[col_name];
     459             :   }
     460     5058933 :   _output_file << "\n";
     461     5058933 : }
     462             : 
     463             : // const strings that the gnuplot generator needs
     464             : namespace gnuplot
     465             : {
     466             : const std::string before_terminal = "set terminal ";
     467             : const std::string before_ext = "\nset output 'all";
     468             : const std::string after_ext =
     469             :     "'\nset title 'All Postprocessors'\nset xlabel 'time'\nset ylabel 'values'\nplot";
     470             : }
     471             : 
     472             : void
     473          72 : FormattedTable::makeGnuplot(const std::string & base_file, const std::string & format)
     474             : {
     475          72 :   fillEmptyValues();
     476             : 
     477             :   // TODO: run this once at end of simulation, right now it runs every iteration
     478             :   // TODO: do I need to be more careful escaping column names?
     479             :   // Note: open and close the files each time, having open files may mess with gnuplot
     480             : 
     481             :   // supported filetypes: ps, png
     482          72 :   std::string extension, terminal;
     483          72 :   if (format == "png")
     484             :   {
     485          24 :     extension = ".png";
     486          24 :     terminal = "png";
     487             :   }
     488             : 
     489          48 :   else if (format == "ps")
     490             :   {
     491          24 :     extension = ".ps";
     492          24 :     terminal = "postscript";
     493             :   }
     494             : 
     495          24 :   else if (format == "gif")
     496             :   {
     497          24 :     extension = ".gif";
     498          24 :     terminal = "gif";
     499             :   }
     500             : 
     501             :   else
     502           0 :     mooseError("gnuplot format \"" + format + "\" is not supported.");
     503             : 
     504             :   // Write the data to disk
     505          72 :   std::string dat_name = base_file + ".dat";
     506          72 :   std::ofstream datfile;
     507          72 :   datfile.open(dat_name.c_str(), std::ios::trunc | std::ios::out);
     508          72 :   if (datfile.fail())
     509           0 :     mooseError("Unable to open file ", dat_name);
     510             : 
     511          72 :   datfile << "# time";
     512         144 :   for (const auto & col_name : _column_names)
     513          72 :     datfile << '\t' << col_name;
     514          72 :   datfile << '\n';
     515             : 
     516         180 :   for (auto & data_it : _data)
     517             :   {
     518         108 :     datfile << data_it.first;
     519         216 :     for (const auto & col_name : _column_names)
     520             :     {
     521         108 :       auto & tmp = data_it.second;
     522         108 :       datfile << '\t' << *tmp[col_name];
     523             :     }
     524         108 :     datfile << '\n';
     525             :   }
     526          72 :   datfile.flush();
     527          72 :   datfile.close();
     528             : 
     529             :   // Write the gnuplot script
     530          72 :   std::string gp_name = base_file + ".gp";
     531          72 :   std::ofstream gpfile;
     532          72 :   gpfile.open(gp_name.c_str(), std::ios::trunc | std::ios::out);
     533          72 :   if (gpfile.fail())
     534           0 :     mooseError("Unable to open file ", gp_name);
     535             : 
     536             :   gpfile << gnuplot::before_terminal << terminal << gnuplot::before_ext << extension
     537          72 :          << gnuplot::after_ext;
     538             : 
     539             :   // plot all postprocessors in one plot
     540          72 :   int column = 2;
     541         144 :   for (const auto & col_name : _column_names)
     542             :   {
     543          72 :     gpfile << " '" << dat_name << "' using 1:" << column << " title '" << col_name
     544          72 :            << "' with linespoints";
     545          72 :     column++;
     546          72 :     if (column - 2 < static_cast<int>(_column_names.size()))
     547           0 :       gpfile << ", \\\n";
     548             :   }
     549          72 :   gpfile << "\n\n";
     550             : 
     551             :   // plot the postprocessors individually
     552          72 :   column = 2;
     553         144 :   for (const auto & col_name : _column_names)
     554             :   {
     555          72 :     gpfile << "set output '" << col_name << extension << "'\n";
     556          72 :     gpfile << "set ylabel '" << col_name << "'\n";
     557          72 :     gpfile << "plot '" << dat_name << "' using 1:" << column << " title '" << col_name
     558          72 :            << "' with linespoints\n\n";
     559          72 :     column++;
     560             :   }
     561             : 
     562          72 :   gpfile.flush();
     563          72 :   gpfile.close();
     564          72 : }
     565             : 
     566             : void
     567       18394 : FormattedTable::clear()
     568             : {
     569       18394 :   _data.clear();
     570       18394 :   _output_file.close();
     571       18394 :   _output_row_index = 0;
     572       18394 : }
     573             : 
     574             : void
     575      426236 : FormattedTable::fillEmptyValues(unsigned int last_n_entries)
     576             : {
     577      426236 :   auto begin = _data.begin();
     578      426236 :   auto end = _data.end();
     579      426236 :   if (last_n_entries && (last_n_entries < _data.size()))
     580       36035 :     begin = end - last_n_entries;
     581             : 
     582     7985900 :   for (auto it = begin; it != end; ++it)
     583             :   {
     584     7559664 :     auto & datamap = it->second;
     585     7559664 :     if (datamap.size() != _column_names.size())
     586             :     {
     587         238 :       for (const auto & col_name : _column_names)
     588         172 :         if (!datamap[col_name])
     589          66 :           datamap[col_name] =
     590         132 :               std::dynamic_pointer_cast<TableValueBase>(std::make_shared<TableValue<char>>('0'));
     591             :     }
     592             :     else
     593             :     {
     594    22131648 :       for (auto & [key, val] : datamap)
     595    14572050 :         if (!val)
     596           0 :           val = std::dynamic_pointer_cast<TableValueBase>(std::make_shared<TableValue<char>>('0'));
     597             :     }
     598             :   }
     599      426236 : }
     600             : 
     601             : MooseEnum
     602      156572 : FormattedTable::getWidthModes()
     603             : {
     604      156572 :   return MooseEnum("ENVIRONMENT=-1 AUTO=0 80=80 120=120 160=160", "ENVIRONMENT", true);
     605             : }
     606             : 
     607             : void
     608      134507 : FormattedTable::sortColumns()
     609             : {
     610      134507 :   if (_column_names_unsorted)
     611             :   {
     612       23511 :     std::sort(_column_names.begin(), _column_names.end());
     613       23511 :     _column_names_unsorted = false;
     614             :   }
     615      134507 : }
     616             : 
     617             : std::ostream &
     618    12022988 : operator<<(std::ostream & os, const TableValueBase & value)
     619             : {
     620    12022988 :   value.print(os);
     621    12022988 :   return os;
     622             : }

Generated by: LCOV version 1.14