00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #if defined(BL_OLD_STL)
00028 #include <stdlib.h>
00029 #include <string.h>
00030 #include <ctype.h>
00031 #include <stdio.h>
00032 #include <time.h>
00033 #else
00034 #include <cstdlib>
00035 #include <cstring>
00036 #include <cctype>
00037 #include <cstdio>
00038 #include <ctime>
00039 #endif
00040
00041
00042 #include <iostream>
00043
00044 #include <sys/stat.h>
00045 #include <sys/types.h>
00046 #ifndef WIN32
00047 #include <sys/wait.h>
00048 #endif
00049 #include <errno.h>
00050
00051 #include <REAL.H>
00052 #include <BoxLib.H>
00053 #include <Utility.H>
00054 #include <BLassert.H>
00055
00056 #ifdef WIN32
00057 #include <direct.h>
00058 #define mkdir(a,b) _mkdir((a))
00059 const char* path_sep_str = "\\";
00060 #else
00061 const char* path_sep_str = "/";
00062 #endif
00063
00064 #ifdef BL_T3E
00065 #include <malloc.h>
00066 #endif
00067
00068 #if !defined(BL_ARCH_CRAY) && !defined(WIN32) && !defined(BL_T3E)
00069
00070 #include <sys/types.h>
00071 #include <sys/times.h>
00072 #ifdef BL_AIX
00073 #undef _XOPEN_SOURCE_EXTENDED
00074 #define _XOPEN_SOURCE_EXTENDED 1
00075 #endif
00076 #include <sys/time.h>
00077 #ifdef BL_AIX
00078 #undef _XOPEN_SOURCE_EXTENDED
00079 #endif
00080 #include <sys/param.h>
00081 #include <unistd.h>
00082
00083
00084
00085
00086 #if defined(__GNUG__) && defined(__sun) && defined(BL_SunOS)
00087 extern "C" int gettimeofday (struct timeval*, struct timezone*);
00088 #endif
00089
00090 double
00091 BoxLib::second (double* t)
00092 {
00093 struct tms buffer;
00094
00095 times(&buffer);
00096
00097 static long CyclesPerSecond = 0;
00098
00099 if (CyclesPerSecond == 0)
00100 {
00101 #if defined(_SC_CLK_TCK)
00102 CyclesPerSecond = sysconf(_SC_CLK_TCK);
00103 if (CyclesPerSecond == -1)
00104 BoxLib::Error("second(double*): sysconf() failed");
00105 #elif defined(HZ)
00106 CyclesPerSecond = HZ;
00107 #else
00108 CyclesPerSecond = 100;
00109 BoxLib::Warning("second(): sysconf(): default value of 100 for hz, worry about timings");
00110 #endif
00111 }
00112
00113 double dt = (buffer.tms_utime + buffer.tms_stime)/(1.0*CyclesPerSecond);
00114
00115 if (t != 0)
00116 *t = dt;
00117
00118 return dt;
00119 }
00120
00121 int BL_Initial_Wall_Clock_Time_Init = 0;
00122 long BL_Initial_Wall_Clock_Time_sec = 0;
00123 long BL_Initial_Wall_Clock_Time_usec = 0;
00124 double BL_Initial_Wall_Clock_Time = 0.0;
00125
00126 double
00127 get_initial_wall_clock_time ()
00128 {
00129 struct timeval tp;
00130
00131 if (gettimeofday(&tp, 0) != 0)
00132 BoxLib::Abort("get_time_of_day(): gettimeofday() failed");
00133
00134 BL_Initial_Wall_Clock_Time_Init = 1;
00135 BL_Initial_Wall_Clock_Time_sec = tp.tv_sec;
00136 BL_Initial_Wall_Clock_Time_usec = tp.tv_usec;
00137 return 0.0;
00138 }
00139
00140 double
00141 BoxLib::wsecond (double* t)
00142 {
00143 struct timeval tp;
00144
00145 if (BL_Initial_Wall_Clock_Time_Init==0) {
00146 BL_Initial_Wall_Clock_Time_Init=1;
00147 BL_Initial_Wall_Clock_Time=get_initial_wall_clock_time();
00148 }
00149 gettimeofday(&tp,0);
00150
00151 long dtsec = tp.tv_sec - BL_Initial_Wall_Clock_Time_sec;
00152 long dtusec = tp.tv_usec - BL_Initial_Wall_Clock_Time_usec;
00153 double dtusec_double = dtusec*1.0e-6;
00154 double dt = dtsec + dtusec_double;
00155
00156 if (t != 0)
00157 *t = dt;
00158
00159 return dt;
00160 }
00161
00162 #elif defined(WIN32)
00163
00164
00165 #include <windows.h>
00166
00167 namespace
00168 {
00169 double rate;
00170 bool inited = false;
00171 LONGLONG
00172 get_initial_wall_clock_time()
00173 {
00174 LARGE_INTEGER li;
00175 QueryPerformanceFrequency(&li);
00176 rate = 1.0/li.QuadPart;
00177 QueryPerformanceCounter(&li);
00178 inited = true;
00179 return li.QuadPart;
00180 }
00181 int BL_Initial_Wall_Clock_Time_Init = 0;
00182 LONGLONG BL_Initial_Wall_Clock_Time = 0;
00183 }
00184 double
00185 BoxLib::wsecond(double* rslt)
00186 {
00187 if (BL_Initial_Wall_Clock_Time_Init==0) {
00188 BL_Initial_Wall_Clock_Time_Init=1;
00189 BL_Initial_Wall_Clock_Time=get_initial_wall_clock_time();
00190 }
00191 BL_ASSERT( inited );
00192 LARGE_INTEGER li;
00193 QueryPerformanceCounter(&li);
00194 double result = double(li.QuadPart-BL_Initial_Wall_Clock_Time)*rate;
00195 if ( rslt ) *rslt = result;
00196 return result;
00197 }
00198
00199 #include <time.h>
00200 double
00201 BoxLib::second (double* r)
00202 {
00203 static clock_t start = -1;
00204
00205 clock_t finish = clock();
00206
00207 if (start == -1)
00208 start = finish;
00209
00210 double rr = double(finish - start)/CLOCKS_PER_SEC;
00211
00212 if (r)
00213 *r = rr;
00214
00215 return rr;
00216 }
00217
00218 #elif defined(BL_ARCH_CRAY)
00219
00220 #include <unistd.h>
00221
00222 extern "C" double SECOND();
00223 extern "C" double RTC();
00224
00225 double
00226 BoxLib::second (double* t_)
00227 {
00228 double t = SECOND();
00229 if (t_)
00230 *t_ = t;
00231 return t;
00232 }
00233
00234 static
00235 double
00236 get_initial_wall_clock_time ()
00237 {
00238 return RTC();
00239 }
00240
00241
00242
00243
00244 int BL_Initial_Wall_Clock_Time_Init = 0;
00245 double BL_Initial_Wall_Clock_Time = 0.0;
00246
00247 double
00248 BoxLib::wsecond (double* t_)
00249 {
00250 if (BL_Initial_Wall_Clock_Time_Init==0) {
00251 BL_Initial_Wall_Clock_Time_Init=1;
00252 BL_Initial_Wall_Clock_Time=get_initial_wall_clock_time();
00253 }
00254 double t = RTC() - BL_Initial_Wall_Clock_Time;
00255 if (t_)
00256 *t_ = t;
00257 return t;
00258 }
00259
00260 #elif defined(BL_T3E)
00261
00262
00263 #include <unistd.h>
00264 extern "C" long _rtc();
00265
00266 static double BL_Clock_Rate;
00267 extern "C"
00268 {
00269 long IRTC_RATE();
00270 long _irt();
00271 }
00272
00273 static
00274 long
00275 get_initial_wall_clock_time ()
00276 {
00277 BL_Clock_Rate = IRTC_RATE();
00278 return _rtc();
00279 }
00280
00281
00282
00283
00284 int BL_Initial_Wall_Clock_Time_Init = 0;
00285 long BL_Initial_Wall_Clock_Time = 0;
00286
00287
00288
00289
00290
00291
00292 double
00293 BoxLib::second (double* t_)
00294 {
00295 if (BL_Initial_Wall_Clock_Time_Init==0) {
00296 BL_Initial_Wall_Clock_Time_Init=1;
00297 BL_Initial_Wall_Clock_Time=get_initial_wall_clock_time();
00298 }
00299 double t = (_rtc() - BL_Initial_Wall_Clock_Time)/BL_Clock_Rate;
00300 if (t_)
00301 *t_ = t;
00302 return t;
00303 }
00304
00305 double
00306 BoxLib::wsecond (double* t_)
00307 {
00308 if (BL_Initial_Wall_Clock_Time_Init==0) {
00309 BL_Initial_Wall_Clock_Time_Init=1;
00310 BL_Initial_Wall_Clock_Time=get_initial_wall_clock_time();
00311 }
00312 double t = (_rtc() - BL_Initial_Wall_Clock_Time)/BL_Clock_Rate;
00313 if (t_)
00314 *t_ = t;
00315 return t;
00316 }
00317
00318 #else
00319
00320 #include <time.h>
00321
00322 double
00323 BoxLib::second (double* r)
00324 {
00325 static clock_t start = -1;
00326
00327 clock_t finish = clock();
00328
00329 if (start == -1)
00330 start = finish;
00331
00332 double rr = double(finish - start)/CLOCKS_PER_SEC;
00333
00334 if (r)
00335 *r = rr;
00336
00337 return rr;
00338 }
00339
00340 static
00341 time_t
00342 get_initial_wall_clock_time ()
00343 {
00344 return ::time(0);
00345 }
00346
00347
00348
00349
00350 int BL_Initial_Wall_Clock_Time_Init = 0;
00351 time_t BL_Initial_Wall_Clock_Time;
00352
00353 double
00354 BoxLib::wsecond (double* r)
00355 {
00356 time_t finish;
00357
00358 if (BL_Initial_Wall_Clock_Time_Init==0) {
00359 BL_Initial_Wall_Clock_Time_Init=1;
00360 BL_Initial_Wall_Clock_Time=get_initial_wall_clock_time();
00361 }
00362
00363 time(&finish);
00364
00365 double rr = double(finish - BL_Initial_Wall_Clock_Time);
00366
00367 if (r)
00368 *r = rr;
00369
00370 return rr;
00371 }
00372
00373 #endif
00375 void
00376 BoxLib::ResetWallClockTime ()
00377 {
00378 BL_Initial_Wall_Clock_Time = get_initial_wall_clock_time();
00379 }
00380
00381
00382
00383
00384
00385 bool
00386 BoxLib::is_integer (const char* str)
00387 {
00388 int len = 0;
00389
00390 if (str == 0 || (len = strlen(str)) == 0)
00391 return false;
00392
00393 for (int i = 0; i < len; i++)
00394 if (!isdigit(str[i]))
00395 return false;
00396
00397 return true;
00398 }
00399
00400 std::string
00401 BoxLib::Concatenate (const std::string& root,
00402 int num)
00403 {
00404 std::string result = root;
00405 char buf[sizeof(int) + 1];
00406 sprintf(buf, "%04d", num);
00407 result += buf;
00408 return result;
00409 }
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425 bool
00426 #ifdef WIN32
00427 BoxLib::UtilCreateDirectory (const std::string& path,
00428 int)
00429 #else
00430 BoxLib::UtilCreateDirectory (const std::string& path,
00431 mode_t mode)
00432 #endif
00433 {
00434 if (path.length() == 0 || path == path_sep_str)
00435 return true;
00436
00437 if (strchr(path.c_str(), *path_sep_str) == 0)
00438 {
00439
00440
00441
00442 return mkdir(path.c_str(),mode) < 0 && errno != EEXIST ? false : true;
00443 }
00444 else
00445 {
00446
00447
00448
00449 char* dir = new char[path.length() + 1];
00450 (void) strcpy(dir, path.c_str());
00451
00452 char* slash = strchr(dir, *path_sep_str);
00453
00454 if (dir[0] == *path_sep_str)
00455 {
00456
00457
00458
00459 do
00460 {
00461 if (*(slash+1) == 0)
00462 break;
00463 if ((slash = strchr(slash+1, *path_sep_str)) != 0)
00464 *slash = 0;
00465 if (mkdir(dir, mode) < 0 && errno != EEXIST)
00466 return false;
00467 if (slash)
00468 *slash = *path_sep_str;
00469 } while (slash);
00470 }
00471 else
00472 {
00473
00474
00475
00476 do
00477 {
00478 *slash = 0;
00479 if (mkdir(dir, mode) < 0 && errno != EEXIST)
00480 return false;
00481 *slash = *path_sep_str;
00482 } while ((slash = strchr(slash+1, *path_sep_str)) != 0);
00483
00484 if (mkdir(dir, mode) < 0 && errno != EEXIST)
00485 return false;
00486 }
00487
00488 delete [] dir;
00489
00490 return true;
00491 }
00492 }
00493
00494 void
00495 BoxLib::CreateDirectoryFailed (const std::string& dir)
00496 {
00497 std::string msg("Couldn't create directory: ");
00498 msg += dir;
00499 BoxLib::Error(msg.c_str());
00500 }
00501
00502 void
00503 BoxLib::FileOpenFailed (const std::string& file)
00504 {
00505 std::string msg("Couldn't open file: ");
00506 msg += file;
00507 BoxLib::Error(msg.c_str());
00508 }
00509
00510 void
00511 BoxLib::UnlinkFile (const std::string& file)
00512 {
00513 unlink(file.c_str());
00514 }
00515
00516 void
00517 BoxLib::OutOfMemory ()
00518 {
00519 #ifdef BL_T3E
00520 malloc_stats(0);
00521 #endif
00522 BoxLib::Error("Sorry, out of memory, bye ...");
00523 }
00524
00525 #ifdef WIN32
00526 pid_t
00527 BoxLib::Execute (const char* cmd)
00528 {
00529 BoxLib::Error("Execute failed!");
00530 return -1;
00531 }
00532 #else
00533 extern "C" pid_t fork();
00534
00535 pid_t
00536 BoxLib::Execute (const char* cmd)
00537 {
00538
00539 pid_t pid = fork();
00540
00541 if (pid == 0)
00542 {
00543 system(cmd);
00544
00545 exit(0);
00546 }
00547
00548 return pid;
00549 }
00550 #endif
00551
00552
00553
00554
00555
00556
00557 namespace
00558 {
00559 const long billion = 1000000000L;
00560 }
00561
00562 BoxLib::Time::Time()
00563 {
00564 tv_sec = 0;
00565 tv_nsec = 0;
00566 }
00567
00568 BoxLib::Time::Time(long s, long n)
00569 {
00570 BL_ASSERT(s >= 0);
00571 BL_ASSERT(n >= 0);
00572 BL_ASSERT(n < billion);
00573 tv_sec = s;
00574 tv_nsec = n;
00575 normalize();
00576 }
00577
00578 BoxLib::Time::Time(double d)
00579 {
00580 tv_sec = long(d);
00581 tv_nsec = long((d-tv_sec)*billion);
00582 normalize();
00583 }
00584
00585 double
00586 BoxLib::Time::as_double() const
00587 {
00588 return tv_sec + tv_nsec/double(billion);
00589 }
00590
00591 long
00592 BoxLib::Time::as_long() const
00593 {
00594 return tv_sec + tv_nsec/billion;
00595 }
00596
00597 BoxLib::Time&
00598 BoxLib::Time::operator+=(const Time& r)
00599 {
00600 tv_sec += r.tv_sec;
00601 tv_nsec += r.tv_nsec;
00602 normalize();
00603 return *this;
00604 }
00605
00606 BoxLib::Time
00607 BoxLib::Time::operator+(const Time& r) const
00608 {
00609 Time result(*this);
00610 return result+=r;
00611 }
00612
00613 void
00614 BoxLib::Time::normalize()
00615 {
00616 if ( tv_nsec > billion )
00617 {
00618 tv_nsec -= billion;
00619 tv_sec += 1;
00620 }
00621 }
00622
00623 BoxLib::Time
00624 BoxLib::Time::get_time()
00625 {
00626 return Time(BoxLib::wsecond());
00627 }
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661 namespace
00662 {
00663
00664
00665 const int M = 397;
00666 const unsigned long MATRIX_A = 0x9908B0DFUL;
00667 const unsigned long UPPER_MASK = 0x80000000UL;
00668 const unsigned long LOWER_MASK = 0x7FFFFFFFUL;
00669
00670
00671 const unsigned long TEMPERING_MASK_B = 0x9D2C5680UL;
00672 const unsigned long TEMPERING_MASK_C = 0xEFC60000UL;
00673
00674 inline unsigned long TEMPERING_SHIFT_U(unsigned long y) { return y >> 11L; }
00675 inline unsigned long TEMPERING_SHIFT_S(unsigned long y) { return y << 7L ; }
00676 inline unsigned long TEMPERING_SHIFT_T(unsigned long y) { return y << 15L; }
00677 inline unsigned long TEMPERING_SHIFT_L(unsigned long y) { return y >> 18L; }
00678 }
00679
00680
00681 void
00682 BoxLib::mt19937::sgenrand(unsigned long seed)
00683 {
00684 #ifdef BL_MERSENNE_ORIGINAL_INIT
00685 for ( int i = 0; i < N; ++i )
00686 {
00687 mt[i] = seed & 0xFFFF0000UL;
00688 seed = 69069U * seed + 1;
00689 mt[i] |= (seed& 0xFFFF0000UL) >> 16;
00690 seed = 69069U*seed + 1;
00691 }
00692 #else
00693 mt[0]= seed & 0xffffffffUL;
00694 for ( mti=1; mti<N; mti++ )
00695 {
00696 mt[mti] = (1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30L)) + mti);
00697
00698
00699
00700
00701 mt[mti] &= 0xffffffffUL;
00702 }
00703 #endif
00704 mti = N;
00705 }
00706
00707
00708
00709
00710 void
00711 BoxLib::mt19937::sgenrand(unsigned long init_key[], int key_length)
00712 {
00713 int i, j, k;
00714 sgenrand(19650218UL);
00715 i=1; j=0;
00716 k = (N>key_length ? N : key_length);
00717 for ( ; k; k-- )
00718 {
00719 mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525UL)) + init_key[j] + j;
00720 mt[i] &= 0xffffffffUL;
00721 i++; j++;
00722 if (i>=N) { mt[0] = mt[N-1]; i=1; }
00723 if (j>=key_length) j=0;
00724 }
00725 for ( k=N-1; k; k-- )
00726 {
00727 mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941UL)) - i;
00728 mt[i] &= 0xffffffffUL;
00729 i++;
00730 if (i>=N) { mt[0] = mt[N-1]; i=1; }
00731 }
00732
00733 mt[0] = 0x80000000UL;
00734 }
00735
00736 void
00737 BoxLib::mt19937::reload()
00738 {
00739 unsigned long y;
00740 int kk;
00741
00742 static unsigned long mag01[2]={0x0UL, MATRIX_A};
00743 for ( kk=0; kk<N-M; kk++ )
00744 {
00745 y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
00746 mt[kk] = mt[kk+M] ^ (y >> 1L) ^ mag01[y & 0x1UL];
00747 }
00748 for ( ; kk<N-1; kk++ )
00749 {
00750 y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
00751 mt[kk] = mt[kk+(M-N)] ^ (y >> 1L) ^ mag01[y & 0x1UL];
00752 }
00753 y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
00754 mt[N-1] = mt[M-1] ^ (y >> 1L) ^ mag01[y & 0x1UL];
00755
00756 mti = 0;
00757 }
00758
00759 unsigned long
00760 BoxLib::mt19937::igenrand()
00761 {
00762
00763 if ( mti >= N ) reload();
00764
00765 unsigned long y = mt[mti++];
00766 y ^= TEMPERING_SHIFT_U(y);
00767 y ^= TEMPERING_SHIFT_S(y) & TEMPERING_MASK_B;
00768 y ^= TEMPERING_SHIFT_T(y) & TEMPERING_MASK_C;
00769 y ^= TEMPERING_SHIFT_L(y);
00770
00771 return y;
00772 }
00773
00774 BoxLib::mt19937::mt19937(unsigned long seed)
00775 : init_seed(seed), mti(N+1)
00776 {
00777 sgenrand(seed);
00778 }
00779
00780 BoxLib::mt19937::mt19937 (unsigned long seed_array[], int len)
00781 {
00782 sgenrand(seed_array, len);
00783 }
00784
00785 void
00786 BoxLib::mt19937::rewind()
00787 {
00788 sgenrand(init_seed);
00789 }
00790
00791 double
00792 BoxLib::mt19937::d1_value()
00793 {
00794 return double(igenrand())/0xFFFFFFFFUL;
00795 }
00796
00797 double
00798 BoxLib::mt19937::d_value()
00799 {
00800 const double zzz = double(0x80000000UL)*2;
00801 return double(igenrand())/zzz;
00802 }
00803
00804 long
00805 BoxLib::mt19937::l_value()
00806 {
00807 return igenrand()&0x7FFFFFFFUL;
00808 }
00809
00810 unsigned long
00811 BoxLib::mt19937::u_value()
00812 {
00813 return igenrand();
00814 }
00815
00816 namespace
00817 {
00818 BoxLib::mt19937 the_generator;
00819 }
00820
00821 void
00822 BoxLib::InitRandom (unsigned long seed)
00823 {
00824 the_generator = mt19937(seed);
00825 }
00826
00827 double
00828 BoxLib::Random ()
00829 {
00830 return the_generator.d_value();
00831 }
00832
00833
00834
00835
00836
00837 #if defined(BL_FORT_USE_UPPERCASE)
00838 #define FORT_BLUTILRAND BLUTILRAND
00839 #elif defined(BL_FORT_USE_LOWERCASE)
00840 #define FORT_BLUTILRAND blutilrand
00841 #elif defined(BL_FORT_USE_UNDERSCORE)
00842 #define FORT_BLUTILRAND blutilrand_
00843 #endif
00844
00845 extern "C" void FORT_BLUTILRAND (Real* rn);
00846
00847 void
00848 FORT_BLUTILRAND (Real* rn)
00849 {
00850 BL_ASSERT(rn != 0);
00851 *rn = BoxLib::Random();
00852 }
00853
00854
00855
00856
00857
00858
00859 std::istream&
00860 BoxLib::operator>>(std::istream& is, const expect& exp)
00861 {
00862 int len = exp.istr.size();
00863 int n = 0;
00864 while ( n < len )
00865 {
00866 char c;
00867 is >> c;
00868 if ( !is ) break;
00869 if ( c != exp.istr[n++] )
00870 {
00871 is.putback(c);
00872 break;
00873 }
00874 }
00875 if ( n != len )
00876 {
00877 is.clear(std::ios::badbit|is.rdstate());
00878 std::string msg = "expect fails to find \"" + exp.the_string() + "\"";
00879 BoxLib::Error(msg.c_str());
00880 }
00881 return is;
00882 }
00883
00884 BoxLib::expect::expect(const char* istr_)
00885 : istr(istr_)
00886 {
00887 }
00888
00889 BoxLib::expect::expect(const std::string& str_)
00890 : istr(str_)
00891 {
00892 }
00893
00894 BoxLib::expect::expect(char c)
00895 {
00896 istr += c;
00897 }
00898
00899 const std::string&
00900 BoxLib::expect::the_string() const
00901 {
00902 return istr;
00903 }