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