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