LCOV - code coverage report
Current view: top level - src/Util - Util.cpp (source / functions) Coverage Total Hit
Test: coverage_merged.info Lines: 61.8 % 212 131
Test Date: 2025-12-09 18:08:38 Functions: 62.5 % 16 10

            Line data    Source code
       1              : #include "Util.H"
       2              : #include "Color.H"
       3              : 
       4              : #include <chrono>
       5              : #include <cstdlib>
       6              : #include <filesystem>
       7              : #include <stdexcept>
       8              : 
       9              : #include "AMReX_ParallelDescriptor.H"
      10              : #include "AMReX_Utility.H"
      11              : 
      12              : #include "IO/ParmParse.H"
      13              : #include "IO/WriteMetaData.H"
      14              : #include "IO/FileNameParse.H"
      15              : #include "Color.H"
      16              : #include "Numeric/Stencil.H"
      17              : 
      18              : namespace Util
      19              : {
      20              : 
      21              : std::string filename = "";
      22              : std::string globalprefix = "";
      23              : std::pair<std::string,std::string> file_overwrite;
      24              : bool initialized = false;
      25              : bool finalized = false;
      26              : 
      27          121 : std::string GetFileName()
      28              : {
      29          121 :     if (filename == "")
      30              :     {
      31           41 :         IO::ParmParse pp;
      32           41 :         IO::ParmParse pp_amr("amr");
      33              : 
      34          123 :         if (pp_amr.contains("plot_file") && pp.contains("plot_file"))
      35            0 :             Util::Abort("plot_file specified in too many locations");
      36           82 :         else if (pp_amr.contains("plot_file"))
      37              :         {
      38            0 :             if (amrex::ParallelDescriptor::IOProcessor())
      39              :                 amrex::Warning("amr.plot_file will be depricated; use plot_file instead");
      40            0 :             pp_amr.query("plot_file", filename);
      41              : 
      42              :         }
      43           82 :         else if (pp.contains("plot_file"))
      44              :         {
      45           41 :             pp_query("plot_file", filename); // Name of directory containing all output data
      46              :         }
      47           41 :         IO::FileNameParse(filename);
      48              :         // else
      49              :         // if (amrex::ParallelDescriptor::IOProcessor())
      50              :         // Util::Abort("No plot file specified! (Specify plot_file = \"plot_file_name\" in input file");
      51           41 :     }
      52          121 :     return filename;
      53              : }
      54            2 : void CopyFileToOutputDir(std::string a_path, bool fullpath, std::string prefix)
      55              : {
      56              :     try
      57              :     {
      58            2 :         if (filename == "")
      59            0 :             Util::Exception(INFO,"Cannot back up files yet because the output directory has not been specified");
      60              : 
      61            2 :         std::string basefilename = std::filesystem::path(a_path).filename();
      62            2 :         std::string absolutepath = std::filesystem::absolute(std::filesystem::path(a_path)).string();
      63            2 :         std::string abspathfilename = absolutepath;
      64            2 :         std::replace(abspathfilename.begin(),abspathfilename.end(),'/','_');
      65            2 :         if (prefix != "")
      66              :         {
      67            2 :             abspathfilename = prefix + "__" + abspathfilename;
      68            2 :             basefilename    = prefix + "__" + abspathfilename;
      69              :         }
      70              : 
      71            2 :         if (amrex::ParallelDescriptor::IOProcessor())
      72              :         {
      73            2 :             std::string destinationpath;
      74            2 :             if (fullpath) destinationpath = filename+"/"+abspathfilename;
      75            0 :             else          destinationpath = filename+"/"+basefilename;
      76              : 
      77              :             // Copy the file where the file name is the absolute path, with / replaced with _
      78            2 :             if (std::filesystem::exists(destinationpath))
      79            0 :                 Util::Exception(INFO,"Trying to copy ",destinationpath," but it already exists.");
      80            2 :             std::filesystem::copy_file(a_path,destinationpath);
      81            2 :         }
      82            2 :     }
      83            0 :     catch (std::filesystem::filesystem_error const& ex)
      84              :     {
      85            0 :         Util::Exception(INFO,
      86              :                         "file system error: \n",
      87            0 :                         "     what():  " , ex.what()  , '\n',
      88            0 :                         "     path1(): " , ex.path1() , '\n',
      89            0 :                         "     path2(): " , ex.path2() , '\n',
      90            0 :                         "     code().value():    " , ex.code().value() , '\n',
      91            0 :                         "     code().message():  " , ex.code().message() , '\n',
      92            0 :                         "     code().category(): " , ex.code().category().name());
      93            0 :     }
      94            2 : }
      95              : 
      96            0 : std::pair<std::string,std::string> GetOverwrittenFile()
      97              : {
      98            0 :     return file_overwrite;
      99              : }
     100              : 
     101            0 : void SignalHandler(int s)
     102              : {
     103            0 :     if (amrex::ParallelDescriptor::IOProcessor())
     104              :     {
     105            0 :         std::string filename = GetFileName();
     106            0 :         IO::Status status = IO::Status::Running;
     107            0 :         if (s == SIGSEGV) status = IO::Status::Segfault;
     108            0 :         else if (s == SIGINT) status = IO::Status::Interrupt;
     109            0 :         if (s == SIGABRT) status = IO::Status::Abort;
     110            0 :         if (filename != "")
     111            0 :             IO::WriteMetaData(filename,status);
     112            0 :     }
     113              : 
     114              : #ifdef MEME
     115              :     IO::ParmParse pp;
     116              :     if (!pp.contains("nomeme"))
     117              :     {
     118              :         time_t timer; time(&timer);
     119              :         std::stringstream cmd;
     120              :         cmd << "xdg-open " << BUILD_DIR << "/src/Util/Meme/cat0" << (1+((int)timer)%6) << ".gif &";
     121              :         std::system(cmd.str().c_str());
     122              :         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!)";
     123              :     }
     124              : #endif 
     125              : 
     126            0 :     amrex::BLBackTrace::handler(s);
     127            0 : }
     128              : 
     129              : 
     130            0 : void Initialize ()
     131              : {
     132            0 :     int argc = 0;
     133            0 :     char **argv = nullptr;
     134            0 :     Initialize(argc,argv);
     135            0 :     initialized = true;
     136            0 : }
     137           41 : void Initialize (int argc, char* argv[])
     138              : {
     139           41 :     srand (time(NULL));
     140              : 
     141           41 :     amrex::Initialize(argc, argv);
     142              : 
     143           41 :     IO::ParmParse pp_amrex("amrex");
     144           41 :     pp_amrex.add("throw_exception",1);
     145              :     //amrex.throw_exception=1
     146              : 
     147           41 :     signal(SIGSEGV, Util::SignalHandler);
     148           41 :     signal(SIGINT,  Util::SignalHandler);
     149           41 :     signal(SIGABRT, Util::SignalHandler);
     150              : 
     151           41 :     std::string filename = GetFileName();
     152              : 
     153           41 :     if (amrex::ParallelDescriptor::IOProcessor() && filename != "")
     154              :     {
     155           41 :         file_overwrite = Util::CreateCleanDirectory(filename, false);
     156           41 :         IO::WriteMetaData(filename);
     157              :     }
     158              : 
     159           41 :     IO::ParmParse pp;
     160           41 :     std::string length, time, mass, temperature, current, amount, luminousintensity;
     161              :     // Set the system length unit
     162           82 :     pp.query_default("system.length",length,"m");
     163              :     // Set the system time unit
     164           82 :     pp.query_default("system.time",time,"s");
     165              :     // Set the system mass unit
     166           82 :     pp.query_default("system.mass",mass,"kg");
     167              :     // Set the system temperature unit
     168           82 :     pp.query_default("system.temperature",temperature,"K");
     169              :     // Set the system current unit
     170           82 :     pp.query_default("system.current",current,"A");
     171              :     // Set the system amount unit
     172           82 :     pp.query_default("system.amount",amount,"mol");
     173              :     // Set the system luminous intensity unit
     174           41 :     pp.query_default("system.luminousintensity",luminousintensity,"cd");
     175              :     try
     176              :     {
     177           41 :         Unit::setLengthUnit(length);
     178           41 :         Unit::setTimeUnit(time);
     179           41 :         Unit::setMassUnit(mass);
     180           41 :         Unit::setTemperatureUnit(temperature);
     181           41 :         Unit::setCurrentUnit(current);
     182           41 :         Unit::setAmountUnit(amount);
     183           41 :         Unit::setLuminousIntensityUnit(luminousintensity);
     184              : 
     185              :         // Update Constants to desired system units
     186           41 :         Set::Constant::SetGlobalConstants();
     187              :     }
     188            0 :     catch (std::runtime_error &e)
     189              :     {
     190            0 :         Util::Exception(INFO, "Error in setting system units: ", e.what());
     191            0 :     }
     192              : 
     193              :     //
     194              :     // This is some logic to unit-ize the geometry.prob_lo, geometry.prob_hi input variables/
     195              :     // We also do some checking to make sure the geometry is valid.
     196              :     //
     197              :     // Note that here, unlike most places, we actually **replace and overwrite** the 
     198              :     // geom.prob_* variables, since they are read deep inside amrex infrastructure.
     199              :     //
     200              :     {
     201           82 :         IO::ParmParse pp("geometry");
     202              :         
     203           82 :         if (pp.contains("prob_lo"))
     204              :         {
     205           39 :             std::vector<Set::Scalar> prob_lo, prob_hi;
     206              :             // Location of the lower+left+bottom corner
     207           78 :             pp.queryarr("prob_lo", prob_lo, Unit::Length());
     208              :             // Location of the upper_right_top corner
     209           78 :             pp.queryarr("prob_hi", prob_hi, Unit::Length());
     210           39 :             pp.remove("prob_lo");
     211           39 :             pp.remove("prob_hi");
     212              : 
     213          273 :             Util::Assert(   INFO,TEST(prob_lo[0] < prob_hi[0]),
     214           39 :                             "Invalid domain specified: ", prob_lo[0], " < x < ", prob_hi[0], " is incorrect.");
     215          273 :             Util::Assert(   INFO,TEST(prob_lo[1] < prob_hi[1]),
     216           39 :                             "Invalid domain specified: ", prob_lo[0], " < y < ", prob_hi[0], " is incorrect.");
     217              : #if AMREX_SPACEDIM>2
     218           21 :             Util::Assert(   INFO,TEST(prob_lo[2] < prob_hi[2]),
     219            3 :                             "Invalid domain specified: ", prob_lo[0], " < z < ", prob_hi[0], " is incorrect.");
     220              : #endif
     221              : 
     222          156 :             Util::DebugMessage(INFO,"Domain lower left corner: ", Set::Vector(prob_lo.data()).transpose());
     223          156 :             Util::DebugMessage(INFO,"Domain upper right corenr: ", Set::Vector(prob_hi.data()).transpose());
     224              : 
     225           39 :             pp.addarr("prob_lo",prob_lo);
     226           39 :             pp.addarr("prob_hi",prob_hi);
     227           39 :         }
     228           41 :     }
     229           41 : }
     230              : 
     231           41 : void Finalize()
     232              : {
     233           41 :     std::string filename = GetFileName();
     234           41 :     if (filename != "")
     235           41 :         IO::WriteMetaData(filename,IO::Status::Complete);
     236           41 :     amrex::Finalize();
     237           41 :     finalized = true;
     238           41 : }
     239              : 
     240              : 
     241              : 
     242              : void
     243            0 : Abort (const char * msg) { Terminate(msg, SIGABRT, true); }
     244              : 
     245              : void
     246            0 : Terminate(const char * /* msg */, int signal, bool /*backtrace*/)
     247              : {
     248            0 :     SignalHandler(signal);
     249            0 : }
     250              : 
     251              : std::pair<std::string,std::string>
     252           41 : CreateCleanDirectory (const std::string &path, bool callbarrier)
     253              : {
     254           41 :     std::pair<std::string,std::string> ret("","");
     255              : 
     256           41 :     if(amrex::ParallelDescriptor::IOProcessor()) {
     257           41 :         if(amrex::FileExists(path)) {
     258            0 :             std::time_t t = std::time(0);
     259            0 :             std::tm * now = std::localtime(&t);
     260            0 :             int year = now->tm_year+1900;
     261            0 :             int month = now->tm_mon+1;
     262            0 :             int day = now->tm_mday;
     263            0 :             int hour = now->tm_hour;
     264            0 :             int minute = now->tm_min;
     265            0 :             int second = now->tm_sec;
     266              : 
     267            0 :             std::stringstream ss;
     268              :             ss << year
     269            0 :                 << std::setfill('0') << std::setw(2) << month
     270            0 :                 << std::setfill('0') << std::setw(2) << day
     271            0 :                 << std::setfill('0') << std::setw(2) << hour
     272            0 :                 << std::setfill('0') << std::setw(2) << minute
     273            0 :                 << std::setfill('0') << std::setw(2) << second;
     274              : 
     275            0 :             std::string newoldname(path + ".old." + ss.str());
     276            0 :             if (amrex::system::verbose) {
     277            0 :                 amrex::Print() << "Util::CreateCleanDirectory():  " << path
     278            0 :                             << " exists.  Renaming to:  " << newoldname << std::endl;
     279              :             }
     280            0 :             std::rename(path.c_str(), newoldname.c_str());
     281            0 :             ret.first = path;
     282            0 :             ret.second = newoldname;
     283            0 :         }
     284           41 :         if( ! amrex::UtilCreateDirectory(path, 0755)) {
     285            0 :             amrex::CreateDirectoryFailed(path);
     286              :         }
     287              :     }
     288           41 :     if(callbarrier) {
     289              :         // Force other processors to wait until directory is built.
     290            0 :         amrex::ParallelDescriptor::Barrier("amrex::UtilCreateCleanDirectory");
     291              :     }
     292           41 :     return ret;
     293            0 : }
     294              : 
     295              : 
     296              : namespace Test
     297              : {
     298           34 : int Message(std::string testname)
     299              : {
     300           34 :     if (amrex::ParallelDescriptor::IOProcessor())
     301           34 :         std::cout << std::left
     302           34 :             << Color::FG::White << Color::Bold << testname << Color::Reset << std::endl;
     303           34 :     return 0;
     304              : }
     305            0 : int Message(std::string testname, int failed)
     306              : {
     307            0 :     if (amrex::ParallelDescriptor::IOProcessor())
     308              :     {
     309              :         winsize w;
     310            0 :         ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
     311            0 :         std::stringstream ss;
     312            0 :         if (!failed)
     313            0 :             ss << "[" << Color::FG::Green << Color::Bold << "PASS" << Color::Reset << "]";
     314              :         else
     315            0 :             ss << "[" << Color::FG::Red << Color::Bold << "FAIL" << Color::Reset << "]";
     316              : 
     317            0 :         int terminalwidth = 80; //std::min(w.ws_col,(short unsigned int) 100);
     318              : 
     319            0 :         std::cout << std::left
     320              :             << testname 
     321            0 :             << std::setw(terminalwidth - testname.size() + ss.str().size() - 6)  << std::right << std::setfill('.') << ss.str() << std::endl;
     322            0 :     }
     323            0 :     return failed;
     324              : }
     325          136 : int SubMessage(std::string testname, int failed)
     326              : {
     327          136 :     if (amrex::ParallelDescriptor::IOProcessor())
     328              :     {
     329              :         winsize w;
     330          136 :         ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
     331          136 :         std::stringstream ss;
     332          136 :         if (!failed)
     333          136 :             ss << "[" << Color::FG::LightGreen << Color::Bold << "PASS" << Color::Reset << "]";
     334              :         else
     335            0 :             ss << "[" << Color::FG::Red << Color::Bold << "FAIL" << Color::Reset << "]";
     336              : 
     337          136 :         int terminalwidth = 80; 
     338              : 
     339          136 :         std::cout << std::left
     340              :             << "  ├ "
     341              :             << testname 
     342          136 :             << std::setw(terminalwidth - testname.size() + ss.str().size() - 12)  << std::right << std::setfill('.') << ss.str() << std::endl;
     343          136 :     }
     344          136 :     return failed;
     345              : }
     346           32 : int SubFinalMessage(int failed)
     347              : {
     348           32 :     if (amrex::ParallelDescriptor::IOProcessor())
     349              :     {
     350              :         winsize w;
     351           32 :         ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
     352           32 :         std::stringstream ss;
     353           32 :         std::cout << std::left << "  └ ";
     354              : 
     355           32 :         if (!failed)
     356           32 :             std::cout << Color::FG::Green << Color::Bold << failed << " tests failed" << Color::Reset << std::endl;
     357              :         else
     358            0 :             std::cout << Color::FG::Red << Color::Bold << failed << " tests failed" << Color::Reset << std::endl;
     359           32 :     }
     360           32 :     return failed;
     361              : }
     362              : 
     363              : }
     364              : 
     365           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*/)
     366              : {
     367          434 :     Util::Assert(INFO,TEST(dcomp + ncomp <= node_mf.nComp()));
     368          434 :     Util::Assert(INFO,TEST(scomp + ncomp <= cell_mf.nComp()));
     369              :     //Util::Assert(INFO,TEST(cell_mf.boxArray() == node_mf.boxArray()));
     370          434 :     Util::Assert(INFO,TEST(cell_mf.DistributionMap() == cell_mf.DistributionMap()));
     371          434 :     Util::Assert(INFO,TEST(cell_mf.nGrow() > 0));
     372          269 :     for (amrex::MFIter mfi(node_mf,amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi)
     373              :     {
     374          207 :             amrex::Box bx = mfi.nodaltilebox();
     375          207 :             amrex::Array4<Set::Scalar>       const& node = node_mf.array(mfi);
     376          207 :             amrex::Array4<const Set::Scalar> const& cell = cell_mf.array(mfi);
     377          414 :             for (int n = 0; n < ncomp; n++)
     378          207 :                 amrex::ParallelFor (bx,[=] AMREX_GPU_DEVICE(int i, int j, int k) {
     379       212934 :                                             node(i,j,k,dcomp+n) = Numeric::Interpolate::CellToNodeAverage(cell,i,j,k,scomp+n);
     380       106467 :                                         });
     381           62 :     }
     382           62 : }
     383              : 
     384              : 
     385              : }
        

Generated by: LCOV version 2.0-1