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