LCOV - code coverage report
Current view: top level - src/outputs - FileOutput.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 76 79 96.2 %
Date: 2025-07-17 01:28:37 Functions: 9 9 100.0 %
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             : // C POSIX includes
      11             : #include <sys/stat.h>
      12             : 
      13             : // MOOSE includes
      14             : #include "FileOutput.h"
      15             : #include "MooseApp.h"
      16             : #include "FEProblem.h"
      17             : 
      18             : #include <unistd.h>
      19             : #include <ctime>
      20             : 
      21             : #include "libmesh/utility.h"
      22             : 
      23             : InputParameters
      24      595979 : FileOutput::validParams()
      25             : {
      26             :   // Create InputParameters object for this stand-alone object
      27      595979 :   InputParameters params = PetscOutput::validParams();
      28      595979 :   params.addClassDescription("Base class for all file-based output");
      29      595979 :   params.addParam<std::string>(
      30             :       "file_base",
      31             :       "The desired solution output name without an extension. If not provided, MOOSE sets it "
      32             :       "with Outputs/file_base when available. Otherwise, MOOSE uses input file name and this "
      33             :       "object name for a master input or uses master file_base, the subapp name and this object "
      34             :       "name for a subapp input to set it.");
      35      595979 :   params.addParam<std::string>("file_base_suffix", "Suffix to add to the file base");
      36     1787937 :   params.addParam<bool>(
      37     1191958 :       "append_date", false, "When true the date and time are appended to the output filename.");
      38      595979 :   params.addParam<std::string>("append_date_format",
      39             :                                "The format of the date/time to append, if not given UTC format "
      40             :                                "is used (see http://www.cplusplus.com/reference/ctime/strftime).");
      41             :   // Add the padding option and list it as 'Advanced'
      42     1787937 :   params.addParam<unsigned int>(
      43     1191958 :       "padding", 4, "The number of digits for the extension suffix (e.g., out.e-s002)");
      44     1787937 :   params.addParam<std::vector<std::string>>("output_if_base_contains",
      45     1191958 :                                             std::vector<std::string>(),
      46             :                                             "If this is supplied then output will only be done in "
      47             :                                             "the case that the output base contains one of these "
      48             :                                             "strings.  This is helpful in outputting only a subset "
      49             :                                             "of outputs when using MultiApps.");
      50      595979 :   params.addParamNamesToGroup(
      51             :       "file_base append_date append_date_format padding output_if_base_contains",
      52             :       "File name customization");
      53             : 
      54      595979 :   return params;
      55           0 : }
      56             : 
      57      154259 : FileOutput::FileOutput(const InputParameters & parameters)
      58             :   : PetscOutput(parameters),
      59      154251 :     _file_num(declareRecoverableData<unsigned int>("file_num", 0)),
      60      154251 :     _padding(getParam<unsigned int>("padding")),
      61      308510 :     _output_if_base_contains(getParam<std::vector<std::string>>("output_if_base_contains"))
      62             : {
      63             :   // If restarting reset the file number
      64      154251 :   if (_app.isRestarting())
      65        1267 :     _file_num = 0;
      66             : 
      67      154251 :   if (isParamValid("file_base"))
      68             :   {
      69             :     // Check that we are the only process or not a subapp
      70       42236 :     if (!_app.isUltimateMaster())
      71          64 :       if (_app.multiAppNumber() > 0)
      72           4 :         mooseError("The parameter 'file_base' may not be specified for a child app when the "
      73             :                    "MultiApp has multiple instances of the child app, since all instances would "
      74             :                    "use the same file base and thus write to the same file.");
      75       42232 :     setFileBaseInternal(getParam<std::string>("file_base"));
      76             :   }
      77      154247 : }
      78             : 
      79             : bool
      80     3262320 : FileOutput::shouldOutput()
      81             : {
      82     3262320 :   if (!checkFilename())
      83           0 :     return false;
      84     3262320 :   return Output::shouldOutput();
      85             : }
      86             : 
      87             : bool
      88    11321241 : FileOutput::checkFilename()
      89             : {
      90             :   // Return true if 'output_if_base_contains' is not utilized
      91    11321241 :   if (_output_if_base_contains.empty())
      92    11320281 :     return true;
      93             : 
      94             :   // Assumed output is false
      95         960 :   bool output = false;
      96             : 
      97             :   // Loop through each string in the list
      98        2160 :   for (const auto & search_string : _output_if_base_contains)
      99             :   {
     100             :     // Search for the string in the file base, if found set the output to true and break the loop
     101        1680 :     if (_file_base.find(search_string) != std::string::npos)
     102             :     {
     103         480 :       output = true;
     104         480 :       break;
     105             :     }
     106             :   }
     107             : 
     108             :   // Return the value
     109         960 :   return output;
     110             : }
     111             : 
     112             : std::string
     113         173 : FileOutput::filename()
     114             : {
     115         173 :   return _file_base;
     116             : }
     117             : 
     118             : void
     119      151476 : FileOutput::setFileBase(const std::string & file_base)
     120             : {
     121      151476 :   if (!isParamValid("file_base"))
     122      109704 :     setFileBaseInternal(file_base);
     123      151476 : }
     124             : 
     125             : void
     126      151936 : FileOutput::setFileBaseInternal(const std::string & file_base)
     127             : {
     128      151936 :   _file_base = file_base;
     129             : 
     130      151936 :   if (isParamValid("file_base_suffix"))
     131          12 :     _file_base += "_" + getParam<std::string>("file_base_suffix");
     132             : 
     133             :   // Append the date/time
     134      151936 :   if (getParam<bool>("append_date"))
     135             :   {
     136          30 :     std::string format;
     137          30 :     if (isParamValid("append_date_format"))
     138          10 :       format = getParam<std::string>("append_date_format");
     139             :     else
     140          20 :       format = "%Y-%m-%dT%T%z";
     141             : 
     142             :     // Get the current time
     143             :     std::time_t now;
     144          30 :     ::time(&now); // need :: to avoid confusion with time() method of Output class
     145             : 
     146             :     // Format the time
     147             :     char buffer[80];
     148          30 :     strftime(buffer, 80, format.c_str(), localtime(&now));
     149          30 :     _file_base += "_";
     150          30 :     _file_base += buffer;
     151          30 :   }
     152             : 
     153             :   // Check the file directory of file_base and create if needed
     154      151936 :   std::filesystem::path directory_base = _file_base;
     155      151936 :   directory_base.remove_filename();
     156      151936 :   if (directory_base.empty())
     157      151730 :     directory_base = ".";
     158             :   // ensure relative path
     159      151936 :   directory_base = std::filesystem::relative(std::filesystem::absolute(directory_base));
     160             : 
     161      151936 :   std::filesystem::path possible_dir_to_make;
     162      303950 :   for (auto it = directory_base.begin(); it != directory_base.end(); ++it)
     163             :   {
     164      152014 :     possible_dir_to_make = possible_dir_to_make / *it;
     165      152014 :     const auto dir_string = possible_dir_to_make.generic_string();
     166      152014 :     if (_app.processor_id() == 0 && access(dir_string.c_str(), F_OK) == -1)
     167             :       // Directory does not exist. Create
     168          32 :       if (Utility::mkdir(dir_string.c_str()) == -1)
     169           0 :         mooseError("Could not create directory: " + dir_string + " for file base: " + _file_base);
     170      152014 :   }
     171      151936 : }
     172             : 
     173             : void
     174         180 : FileOutput::setFileNumber(unsigned int num)
     175             : {
     176         180 :   _file_num = num;
     177         180 : }
     178             : 
     179             : unsigned int
     180         808 : FileOutput::getFileNumber()
     181             : {
     182         808 :   return _file_num;
     183             : }

Generated by: LCOV version 1.14