LCOV - code coverage report
Current view: top level - src/Util - Util.cpp (source / functions) Coverage Total Hit
Test: coverage_merged.info Lines: 58.5 % 236 138
Test Date: 2025-02-27 04:17:48 Functions: 69.6 % 23 16

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

Generated by: LCOV version 2.0-1