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

Generated by: LCOV version 1.14