LCOV - code coverage report
Current view: top level - src/Util - Util.cpp (source / functions) Hit Total Coverage
Test: coverage_merged.info Lines: 118 220 53.6 %
Date: 2025-01-16 18:33:59 Functions: 15 23 65.2 %

          Line data    Source code
       1             : #include "Util.H"
       2             : #include "Color.H"
       3             : 
       4             : #include <chrono>
       5             : #include <filesystem>
       6             : 
       7             : #include "AMReX_ParallelDescriptor.H"
       8             : #include "AMReX_Utility.H"
       9             : 
      10             : #include "IO/ParmParse.H"
      11             : #include "IO/WriteMetaData.H"
      12             : #include "IO/FileNameParse.H"
      13             : #include "Color.H"
      14             : #include "Numeric/Stencil.H"
      15             : 
      16             : namespace Util
      17             : {
      18             : 
      19             : std::string filename = "";
      20             : std::string globalprefix = "";
      21             : std::pair<std::string,std::string> file_overwrite;
      22             : 
      23          97 : std::string GetFileName()
      24             : {
      25          97 :     if (filename == "")
      26             :     {
      27          66 :         IO::ParmParse pp;
      28          99 :         IO::ParmParse pp_amr("amr");
      29             : 
      30          33 :         if (pp_amr.contains("plot_file") && pp.contains("plot_file"))
      31           0 :             Util::Abort("plot_file specified in too many locations");
      32          33 :         else if (pp_amr.contains("plot_file"))
      33             :         {
      34           0 :             if (amrex::ParallelDescriptor::IOProcessor())
      35             :                 amrex::Warning("amr.plot_file will be depricated; use plot_file instead");
      36           0 :             pp_amr.query("plot_file", filename);
      37             : 
      38             :         }
      39          33 :         else if (pp.contains("plot_file"))
      40             :         {
      41          33 :             pp_query("plot_file", filename); // Name of directory containing all output data
      42             :         }
      43          33 :         IO::FileNameParse(filename);
      44             :         // else
      45             :         // if (amrex::ParallelDescriptor::IOProcessor())
      46             :         // Util::Abort("No plot file specified! (Specify plot_file = \"plot_file_name\" in input file");
      47             :     }
      48          97 :     return filename;
      49             : }
      50           2 : void CopyFileToOutputDir(std::string a_path, bool fullpath, std::string prefix)
      51             : {
      52             :     try
      53             :     {
      54           2 :         if (filename == "")
      55           0 :             Util::Exception(INFO,"Cannot back up files yet because the output directory has not been specified");
      56             : 
      57           6 :         std::string basefilename = std::filesystem::path(a_path).filename();
      58           6 :         std::string absolutepath = std::filesystem::absolute(std::filesystem::path(a_path)).string();
      59           4 :         std::string abspathfilename = absolutepath;
      60           2 :         std::replace(abspathfilename.begin(),abspathfilename.end(),'/','_');
      61           2 :         if (prefix != "")
      62             :         {
      63           2 :             abspathfilename = prefix + "__" + abspathfilename;
      64           2 :             basefilename    = prefix + "__" + abspathfilename;
      65             :         }
      66             : 
      67           2 :         if (amrex::ParallelDescriptor::IOProcessor())
      68             :         {
      69           2 :             std::string destinationpath;
      70           2 :             if (fullpath) destinationpath = filename+"/"+abspathfilename;
      71           0 :             else          destinationpath = filename+"/"+basefilename;
      72             : 
      73             :             // Copy the file where the file name is the absolute path, with / replaced with _
      74           2 :             if (std::filesystem::exists(destinationpath))
      75           0 :                 Util::Exception(INFO,"Trying to copy ",destinationpath," but it already exists.");
      76           2 :             std::filesystem::copy_file(a_path,destinationpath);
      77             :         }
      78             :     }
      79           0 :     catch (std::filesystem::filesystem_error const& ex)
      80             :     {
      81           0 :         Util::Exception(INFO,
      82             :                         "file system error: \n",
      83           0 :                         "     what():  " , ex.what()  , '\n',
      84           0 :                         "     path1(): " , ex.path1() , '\n',
      85           0 :                         "     path2(): " , ex.path2() , '\n',
      86           0 :                         "     code().value():    " , ex.code().value() , '\n',
      87           0 :                         "     code().message():  " , ex.code().message() , '\n',
      88           0 :                         "     code().category(): " , ex.code().category().name());
      89             :     }
      90           2 : }
      91             : 
      92           0 : std::pair<std::string,std::string> GetOverwrittenFile()
      93             : {
      94           0 :     return file_overwrite;
      95             : }
      96             : 
      97           0 : void SignalHandler(int s)
      98             : {
      99           0 :     if (amrex::ParallelDescriptor::IOProcessor())
     100             :     {
     101           0 :         std::string filename = GetFileName();
     102           0 :         IO::Status status = IO::Status::Running;
     103           0 :         if (s == SIGSEGV) status = IO::Status::Segfault;
     104           0 :         else if (s == SIGINT) status = IO::Status::Interrupt;
     105           0 :         if (s == SIGABRT) status = IO::Status::Abort;
     106           0 :         if (filename != "")
     107           0 :             IO::WriteMetaData(filename,status);
     108             :     }
     109             : 
     110             : #ifdef MEME
     111             :     IO::ParmParse pp;
     112             :     if (!pp.contains("nomeme"))
     113             :     {
     114             :         time_t timer; time(&timer);
     115             :         std::stringstream cmd;
     116             :         cmd << "xdg-open " << BUILD_DIR << "/src/Util/Meme/cat0" << (1+((int)timer)%6) << ".gif &";
     117             :         std::system(cmd.str().c_str());
     118             :         std::cout << Color::Bold << Color::FG::Red << "PROGRAM FAILED!" << Color::Reset << " (Compile without -DMEME, or set nomeme = 1 in the input file to disable this!)";
     119             :     }
     120             : #endif 
     121             : 
     122           0 :     amrex::BLBackTrace::handler(s);
     123           0 : }
     124             : 
     125             : 
     126           0 : void Initialize ()
     127             : {
     128           0 :     int argc = 0;
     129           0 :     char **argv = nullptr;
     130           0 :     Initialize(argc,argv);
     131           0 : }
     132          33 : void Initialize (int argc, char* argv[])
     133             : {
     134          33 :     srand (time(NULL));
     135             : 
     136          33 :     amrex::Initialize(argc, argv);
     137             : 
     138          99 :     IO::ParmParse pp_amrex("amrex");
     139          33 :     pp_amrex.add("throw_exception",1);
     140             :     //amrex.throw_exception=1
     141             : 
     142          33 :     signal(SIGSEGV, Util::SignalHandler);
     143          33 :     signal(SIGINT,  Util::SignalHandler);
     144          33 :     signal(SIGABRT, Util::SignalHandler);
     145             : 
     146          66 :     std::string filename = GetFileName();
     147             : 
     148          33 :     if (amrex::ParallelDescriptor::IOProcessor() && filename != "")
     149             :     {
     150          33 :         file_overwrite = Util::CreateCleanDirectory(filename, false);
     151          33 :         IO::WriteMetaData(filename);
     152             :     }
     153          33 : }
     154             : 
     155          33 : void Finalize()
     156             : {
     157          66 :     std::string filename = GetFileName();
     158          33 :     if (filename != "")
     159          33 :         IO::WriteMetaData(filename,IO::Status::Complete);
     160          33 :     amrex::Finalize();
     161          33 : }
     162             : 
     163             : 
     164             : 
     165             : void
     166           0 : Abort (const char * msg) { Terminate(msg, SIGABRT, true); }
     167             : 
     168             : void
     169           0 : Terminate(const char * /* msg */, int signal, bool /*backtrace*/)
     170             : {
     171           0 :     SignalHandler(signal);
     172           0 : }
     173             : 
     174             : std::pair<std::string,std::string>
     175          33 : CreateCleanDirectory (const std::string &path, bool callbarrier)
     176             : {
     177          33 :     std::pair<std::string,std::string> ret("","");
     178             : 
     179          33 :     if(amrex::ParallelDescriptor::IOProcessor()) {
     180          33 :         if(amrex::FileExists(path)) {
     181           0 :             std::time_t t = std::time(0);
     182           0 :             std::tm * now = std::localtime(&t);
     183           0 :             int year = now->tm_year+1900;
     184           0 :             int month = now->tm_mon+1;
     185           0 :             int day = now->tm_mday;
     186           0 :             int hour = now->tm_hour;
     187           0 :             int minute = now->tm_min;
     188           0 :             int second = now->tm_sec;
     189             : 
     190           0 :             std::stringstream ss;
     191             :             ss << year
     192           0 :                 << std::setfill('0') << std::setw(2) << month
     193           0 :                 << std::setfill('0') << std::setw(2) << day
     194           0 :                 << std::setfill('0') << std::setw(2) << hour
     195           0 :                 << std::setfill('0') << std::setw(2) << minute
     196           0 :                 << std::setfill('0') << std::setw(2) << second;
     197             : 
     198           0 :             std::string newoldname(path + ".old." + ss.str());
     199           0 :             if (amrex::system::verbose) {
     200           0 :                 amrex::Print() << "Util::CreateCleanDirectory():  " << path
     201           0 :                             << " exists.  Renaming to:  " << newoldname << std::endl;
     202             :             }
     203           0 :             std::rename(path.c_str(), newoldname.c_str());
     204           0 :             ret.first = path;
     205           0 :             ret.second = newoldname;
     206             :         }
     207          33 :         if( ! amrex::UtilCreateDirectory(path, 0755)) {
     208           0 :             amrex::CreateDirectoryFailed(path);
     209             :         }
     210             :     }
     211          33 :     if(callbarrier) {
     212             :         // Force other processors to wait until directory is built.
     213           0 :         amrex::ParallelDescriptor::Barrier("amrex::UtilCreateCleanDirectory");
     214             :     }
     215          33 :     return ret;
     216             : }
     217             : 
     218             : 
     219             : 
     220             : 
     221             : 
     222             : 
     223             : namespace String
     224             : {
     225         586 : int ReplaceAll(std::string &str, const std::string before, const std::string after)
     226             : {
     227         586 :     size_t start_pos = 0;
     228         658 :     while((start_pos = str.find(before, start_pos)) != std::string::npos) {
     229          72 :         str.replace(start_pos, before.length(), after);
     230          72 :         start_pos += after.length();
     231             :     }
     232         586 :     return 0;
     233             : }
     234        2713 : int ReplaceAll(std::string &str, const char before, const std::string after)
     235             : {
     236        2713 :     size_t start_pos = 0;
     237        2713 :     while((start_pos = str.find(before, start_pos)) != std::string::npos) {
     238           0 :         str.replace(start_pos, 1, after);
     239           0 :         start_pos += after.length();
     240             :     }
     241        2713 :     return 0;
     242             : }
     243             : 
     244           0 : std::string Join(std::vector<std::string> & vec, char separator)
     245             : {
     246           0 :     std::ostringstream oss;
     247           0 :     for (size_t i = 0; i < vec.size(); ++i) {
     248           0 :         oss << vec[i];
     249           0 :         if (i < vec.size() - 1) { // Don't add separator after the last element
     250           0 :             oss << separator;
     251             :         }
     252             :     }
     253           0 :     return oss.str();
     254             : }
     255             : 
     256           0 : std::string Wrap(std::string text, unsigned per_line)
     257             : {
     258           0 :     unsigned line_begin = 0;
     259             : 
     260           0 :     while (line_begin < text.size())
     261             :     {
     262           0 :         const unsigned ideal_end = line_begin + per_line ;
     263           0 :         unsigned line_end = ideal_end <= text.size() ? ideal_end : text.size()-1;
     264             : 
     265           0 :         if (line_end == text.size() - 1)
     266           0 :             ++line_end;
     267           0 :         else if (std::isspace(text[line_end]))
     268             :         {
     269           0 :             text[line_end] = '\n';
     270           0 :             ++line_end;
     271             :         }
     272             :         else    // backtrack
     273             :         {
     274           0 :             unsigned end = line_end;
     275           0 :             while ( end > line_begin && !std::isspace(text[end]))
     276           0 :                 --end;
     277             : 
     278           0 :             if (end != line_begin)                  
     279             :             {                                       
     280           0 :                 line_end = end;                     
     281           0 :                 text[line_end++] = '\n';            
     282             :             }                                       
     283             :             else                                    
     284           0 :                 text.insert(line_end++, 1, '\n');
     285             :         }
     286             : 
     287           0 :         line_begin = line_end;
     288             :     }
     289             : 
     290           0 :     return text;
     291             : }
     292         112 : std::vector<std::string> Split(std::string &str, const char delim)
     293             : {
     294         112 :     std::vector<std::string> ret;
     295         224 :     std::stringstream ss(str);
     296         224 :     std::string item;
     297         343 :     while (std::getline(ss, item, delim)) {
     298         231 :         ret.push_back(item);
     299             :     }
     300         224 :     return ret;
     301             : }
     302         417 : bool Contains(std::string &str, const std::string find)
     303             : {
     304         417 :     if (str.find(find) != std::string::npos) return true;
     305         273 :     else return false;
     306             : }
     307             : 
     308             : template<>
     309           1 : std::complex<int> Parse(std::string input)
     310             : {
     311           1 :     int re=0, im=0;
     312             : 
     313           1 :     ReplaceAll(input, "+", " +");
     314           1 :     ReplaceAll(input, "-", " -");
     315           1 :     std::vector<std::string> tokens = Split(input,' ');
     316           2 :     for (unsigned int i = 0; i < tokens.size(); i++)
     317             :     {
     318           1 :         if(tokens[i]=="") continue;
     319           1 :         if(Contains(tokens[i],"i"))
     320             :         {
     321           0 :             ReplaceAll(tokens[i],"i","");
     322           0 :             im += std::stoi(tokens[i]);
     323             :         }
     324             :         else 
     325             :         {
     326           1 :             re += std::stoi(tokens[i]);
     327             :         }
     328             :     }
     329           2 :     return std::complex<int>(re,im);
     330             : }
     331             : 
     332             : 
     333             : }
     334             : 
     335             : 
     336             : namespace Test
     337             : {
     338          28 : int Message(std::string testname)
     339             : {
     340          28 :     if (amrex::ParallelDescriptor::IOProcessor())
     341          28 :         std::cout << std::left
     342          28 :             << Color::FG::White << Color::Bold << testname << Color::Reset << std::endl;
     343          28 :     return 0;
     344             : }
     345           0 : int Message(std::string testname, int failed)
     346             : {
     347           0 :     if (amrex::ParallelDescriptor::IOProcessor())
     348             :     {
     349             :         winsize w;
     350           0 :         ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
     351           0 :         std::stringstream ss;
     352           0 :         if (!failed)
     353           0 :             ss << "[" << Color::FG::Green << Color::Bold << "PASS" << Color::Reset << "]";
     354             :         else
     355           0 :             ss << "[" << Color::FG::Red << Color::Bold << "FAIL" << Color::Reset << "]";
     356             : 
     357           0 :         int terminalwidth = 80; //std::min(w.ws_col,(short unsigned int) 100);
     358             : 
     359           0 :         std::cout << std::left
     360             :             << testname 
     361           0 :             << std::setw(terminalwidth - testname.size() + ss.str().size() - 6)  << std::right << std::setfill('.') << ss.str() << std::endl;
     362             :     }
     363           0 :     return failed;
     364             : }
     365         118 : int SubMessage(std::string testname, int failed)
     366             : {
     367         118 :     if (amrex::ParallelDescriptor::IOProcessor())
     368             :     {
     369             :         winsize w;
     370         118 :         ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
     371         118 :         std::stringstream ss;
     372         118 :         if (!failed)
     373         118 :             ss << "[" << Color::FG::LightGreen << Color::Bold << "PASS" << Color::Reset << "]";
     374             :         else
     375           0 :             ss << "[" << Color::FG::Red << Color::Bold << "FAIL" << Color::Reset << "]";
     376             : 
     377         118 :         int terminalwidth = 80; 
     378             : 
     379         118 :         std::cout << std::left
     380             :             << "  ├ "
     381             :             << testname 
     382         118 :             << std::setw(terminalwidth - testname.size() + ss.str().size() - 12)  << std::right << std::setfill('.') << ss.str() << std::endl;
     383             :     }
     384         118 :     return failed;
     385             : }
     386          28 : int SubFinalMessage(int failed)
     387             : {
     388          28 :     if (amrex::ParallelDescriptor::IOProcessor())
     389             :     {
     390             :         winsize w;
     391          28 :         ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
     392          56 :         std::stringstream ss;
     393          28 :         std::cout << std::left << "  └ ";
     394             : 
     395          28 :         if (!failed)
     396          28 :             std::cout << Color::FG::Green << Color::Bold << failed << " tests failed" << Color::Reset << std::endl;
     397             :         else
     398           0 :             std::cout << Color::FG::Red << Color::Bold << failed << " tests failed" << Color::Reset << std::endl;
     399             :     }
     400          28 :     return failed;
     401             : }
     402             : 
     403             : }
     404             : 
     405          62 : void AverageCellcenterToNode(amrex::MultiFab& node_mf, const int &dcomp, const amrex::MultiFab &cell_mf, const int &scomp, const int &ncomp/*, const int ngrow=0*/)
     406             : {
     407         124 :     Util::Assert(INFO,TEST(dcomp + ncomp <= node_mf.nComp()));
     408         124 :     Util::Assert(INFO,TEST(scomp + ncomp <= cell_mf.nComp()));
     409             :     //Util::Assert(INFO,TEST(cell_mf.boxArray() == node_mf.boxArray()));
     410         124 :     Util::Assert(INFO,TEST(cell_mf.DistributionMap() == cell_mf.DistributionMap()));
     411         124 :     Util::Assert(INFO,TEST(cell_mf.nGrow() > 0));
     412         269 :     for (amrex::MFIter mfi(node_mf,amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi)
     413             :     {
     414         207 :             amrex::Box bx = mfi.nodaltilebox();
     415         207 :             amrex::Array4<Set::Scalar>       const& node = node_mf.array(mfi);
     416         207 :             amrex::Array4<const Set::Scalar> const& cell = cell_mf.array(mfi);
     417         414 :             for (int n = 0; n < ncomp; n++)
     418         207 :                 amrex::ParallelFor (bx,[=] AMREX_GPU_DEVICE(int i, int j, int k) {
     419      212934 :                                             node(i,j,k,dcomp+n) = Numeric::Interpolate::CellToNodeAverage(cell,i,j,k,scomp+n);
     420      106467 :                                         });
     421             :     }
     422          62 : }
     423             : 
     424             : 
     425             : }

Generated by: LCOV version 1.14