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