$extrastylesheet
00001 // The libMesh Finite Element Library. 00002 // Copyright (C) 2002-2014 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner 00003 00004 // This library is free software; you can redistribute it and/or 00005 // modify it under the terms of the GNU Lesser General Public 00006 // License as published by the Free Software Foundation; either 00007 // version 2.1 of the License, or (at your option) any later version. 00008 00009 // This library is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 // Lesser General Public License for more details. 00013 00014 // You should have received a copy of the GNU Lesser General Public 00015 // License along with this library; if not, write to the Free Software 00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00017 00018 00019 00020 #ifndef LIBMESH_LIBMESH_COMMON_H 00021 #define LIBMESH_LIBMESH_COMMON_H 00022 00023 // The library configuration options 00024 #include "libmesh/libmesh_config.h" 00025 00026 // Use actual timestamps or constant dummies (to aid ccache) 00027 #ifdef LIBMESH_ENABLE_TIMESTAMPS 00028 # define __LIBMESH_TIME__ __TIME__ 00029 # define __LIBMESH_DATE__ __DATE__ 00030 #else 00031 # define __LIBMESH_TIME__ "notime" 00032 # define __LIBMESH_DATE__ "nodate" 00033 #endif 00034 00035 // C/C++ includes everyone should know about 00036 #include <cstdlib> 00037 #ifdef __PGI 00038 // BSK, Thu Feb 20 08:32:06 CST 2014 - For some reason, unless PGI gets 00039 // <cmath> early this nonsense shows up: 00040 // "/software/x86_64/pgi/12.9/linux86-64/12.9/include/CC/cmath", line 57: error: 00041 // the global scope has no "abs" 00042 // using _STLP_VENDOR_CSTD::abs; 00043 // So include <cmath> as early as possible under the PGI compilers. 00044 # include <cmath> 00045 #endif 00046 #include <complex> 00047 #include <typeinfo> // std::bad_cast 00048 00049 00050 // Include the MPI definition 00051 #ifdef LIBMESH_HAVE_MPI 00052 # include "libmesh/ignore_warnings.h" 00053 # include <mpi.h> 00054 # include "libmesh/restore_warnings.h" 00055 #endif 00056 00057 // _basic_ library functionality 00058 #include "libmesh/libmesh_base.h" 00059 #include "libmesh/libmesh_exceptions.h" 00060 extern "C" { 00061 #include "libmesh/libmesh_C_isnan.h" 00062 } 00063 00064 // Proxy class for libMesh::out/err output 00065 #include "libmesh/ostream_proxy.h" 00066 00067 // Here we add missing types to the standard namespace. For example, 00068 // std::max(double, float) etc... are well behaved but not defined 00069 // by the standard. This also includes workarounds for super-strict 00070 // implementations, for example Sun Studio and PGI C++. However, 00071 // this necessarily requires breaking the ISO-C++ standard, and is 00072 // really just a hack. As such, only do it if we are building the 00073 // libmesh library itself. Specifially, *DO NOT* export this to 00074 // user code or install this header. 00075 #ifdef LIBMESH_IS_COMPILING_ITSELF 00076 # include "libmesh/libmesh_augment_std_namespace.h" 00077 #endif 00078 00079 00080 namespace libMesh 00081 { 00082 00083 00084 // A namespace for functions used in the bodies of the macros below. 00085 // The macros generally call these functions with __FILE__, __LINE__, 00086 // __DATE__, and __TIME__ in the appropriate order. These should not 00087 // be called by users directly! The implementations can be found in 00088 // libmesh_common.C. 00089 namespace MacroFunctions 00090 { 00091 void here(const char* file, int line, const char* date, const char* time); 00092 void stop(const char* file, int line, const char* date, const char* time); 00093 void report_error(const char* file, int line, const char* date, const char* time); 00094 } 00095 00096 // Undefine any existing macros 00097 #ifdef Real 00098 # undef Real 00099 #endif 00100 00101 //#ifdef REAL 00102 //# undef REAL 00103 //#endif 00104 00105 #ifdef Complex 00106 # undef Complex 00107 #endif 00108 00109 #ifdef COMPLEX 00110 # undef COMPLEX 00111 #endif 00112 00113 #ifdef MPI_REAL 00114 # undef MPI_REAL 00115 #endif 00116 00117 // Check to see if TOLERANCE has been defined by another 00118 // package, if so we might want to change the name... 00119 #ifdef TOLERANCE 00120 DIE A HORRIBLE DEATH HERE... 00121 # undef TOLERANCE 00122 #endif 00123 00124 00125 00126 // Define the type to use for real numbers 00127 00128 typedef LIBMESH_DEFAULT_SCALAR_TYPE Real; 00129 00130 // Define a corresponding tolerance. This is what should be 00131 // considered "good enough" when doing floating point comparisons. 00132 // For example, v == 0 is changed to std::abs(v) < TOLERANCE. 00133 00134 #ifndef LIBMESH_DEFAULT_SINGLE_PRECISION 00135 #ifdef LIBMESH_DEFAULT_TRIPLE_PRECISION 00136 static const Real TOLERANCE = 1.e-8; 00137 # define MPI_REAL MPI_LONG_DOUBLE 00138 #else 00139 static const Real TOLERANCE = 1.e-6; 00140 # define MPI_REAL MPI_DOUBLE 00141 #endif 00142 #else 00143 static const Real TOLERANCE = 2.5e-3; 00144 # define MPI_REAL MPI_FLOAT 00145 #endif 00146 00147 // Define the type to use for complex numbers 00148 // Always use std::complex<double>, as required by Petsc? 00149 // If your version of Petsc doesn't support 00150 // std::complex<other_precision>, then you'd better just leave 00151 // Real==double 00152 typedef std::complex<Real> Complex; 00153 typedef std::complex<Real> COMPLEX; 00154 00155 00156 // Helper functions for complex/real numbers 00157 // to clean up #ifdef LIBMESH_USE_COMPLEX_NUMBERS elsewhere 00158 template<typename T> inline T libmesh_real(T a) { return a; } 00159 template<typename T> inline T libmesh_conj(T a) { return a; } 00160 00161 template<typename T> 00162 inline T libmesh_real(std::complex<T> a) { return std::real(a); } 00163 00164 template<typename T> 00165 inline std::complex<T> libmesh_conj(std::complex<T> a) { return std::conj(a); } 00166 00167 // isnan isn't actually C++ standard yet; in contexts where it's not defined in 00168 // cmath, libmesh_isnan will just end up returning false. 00169 inline bool libmesh_isnan(float a) { return libmesh_C_isnan_float(a); } 00170 inline bool libmesh_isnan(double a) { return libmesh_C_isnan_double(a); } 00171 inline bool libmesh_isnan(long double a) { return libmesh_C_isnan_longdouble(a); } 00172 00173 template <typename T> 00174 inline bool libmesh_isnan(std::complex<T> a) { return (libmesh_isnan(std::real(a)) || libmesh_isnan(std::imag(a))); } 00175 00176 00177 // Define the value type for unknowns in simulations. 00178 // This is either Real or Complex, depending on how 00179 // the library was configures 00180 #if defined (LIBMESH_USE_REAL_NUMBERS) 00181 typedef Real Number; 00182 #elif defined (LIBMESH_USE_COMPLEX_NUMBERS) 00183 typedef Complex Number; 00184 #else 00185 DIE A HORRIBLE DEATH HERE... 00186 #endif 00187 00188 00189 // Define the value type for error estimates. 00190 // Since AMR/C decisions don't have to be precise, 00191 // we default to float for memory efficiency. 00192 typedef float ErrorVectorReal; 00193 #define MPI_ERRORVECTORREAL MPI_FLOAT 00194 00195 00196 #ifdef LIBMESH_HAVE_MPI 00197 #ifndef LIBMESH_DISABLE_COMMWORLD 00198 00201 extern MPI_Comm COMM_WORLD; 00202 #endif 00203 00207 extern MPI_Comm GLOBAL_COMM_WORLD; 00208 #else 00209 #ifndef LIBMESH_DISABLE_COMMWORLD 00210 00214 extern int COMM_WORLD; 00215 #endif 00216 00221 extern int GLOBAL_COMM_WORLD; 00222 #endif 00223 00224 // Let's define a couple output streams - these will default 00225 // to cout/cerr, but LibMeshInit (or the user) can also set them to 00226 // something more sophisticated. 00227 // 00228 // We use a proxy class rather than references so they can be 00229 // reseated at runtime. 00230 00231 extern OStreamProxy out; 00232 extern OStreamProxy err; 00233 00234 // This global variable is to help us deprecate AutoPtr. We can't 00235 // just use libmesh_deprecated() because then you get one print out 00236 // per template instantiation, instead of one total print out. 00237 extern bool warned_about_auto_ptr; 00238 00239 // These are useful macros that behave like functions in the code. 00240 // If you want to make sure you are accessing a section of code just 00241 // stick a libmesh_here(); in it, for example 00242 #define libmesh_here() \ 00243 do { \ 00244 libMesh::MacroFunctions::here(__FILE__, __LINE__, __LIBMESH_DATE__, __LIBMESH_TIME__); \ 00245 } while(0) 00246 00247 // the libmesh_stop() macro will stop the code until a SIGCONT signal 00248 // is recieved. This is useful, for example, when determining the 00249 // memory used by a given operation. A libmesh_stop() could be 00250 // instered before and after a questionable operation and the delta 00251 // memory can be obtained from a ps or top. This macro only works for 00252 // serial cases. 00253 #define libmesh_stop() \ 00254 do { \ 00255 libMesh::MacroFunctions::stop(__FILE__, __LINE__, __LIBMESH_DATE__, __LIBMESH_TIME__); \ 00256 } while(0) 00257 00258 // The libmesh_dbg_var() macro indicates that an argument to a function 00259 // is used only in debug mode (i.e., when NDEBUG is not defined). 00260 #ifndef NDEBUG 00261 #define libmesh_dbg_var(var) var 00262 #else 00263 #define libmesh_dbg_var(var) 00264 #endif 00265 00266 // The libmesh_assert() macro acts like C's assert(), but throws a 00267 // libmesh_error() (including stack trace, etc) instead of just exiting 00268 #ifdef NDEBUG 00269 00270 #define libmesh_assert(asserted) ((void) 0) 00271 #define libmesh_exceptionless_assert(asserted) ((void) 0) 00272 #define libmesh_assert_msg(asserted, msg) ((void) 0) 00273 #define libmesh_assert_equal_to(expr1,expr2) ((void) 0) 00274 #define libmesh_assert_not_equal_to(expr1,expr2) ((void) 0) 00275 #define libmesh_assert_less(expr1,expr2) ((void) 0) 00276 #define libmesh_assert_greater(expr1,expr2) ((void) 0) 00277 #define libmesh_assert_less_equal(expr1,expr2) ((void) 0) 00278 #define libmesh_assert_greater_equal(expr1,expr2) ((void) 0) 00279 00280 #else 00281 00282 #define libmesh_assert(asserted) \ 00283 do { \ 00284 if (!(asserted)) { \ 00285 libMesh::err << "Assertion `" #asserted "' failed." << std::endl; \ 00286 libmesh_error(); \ 00287 } } while(0) 00288 00289 #define libmesh_exceptionless_assert(asserted) \ 00290 do { \ 00291 if (!(asserted)) { \ 00292 libMesh::err << "Assertion `" #asserted "' failed." << std::endl; \ 00293 libmesh_exceptionless_error(); \ 00294 } } while(0) 00295 00296 #define libmesh_assert_msg(asserted, msg) \ 00297 do { \ 00298 if (!(asserted)) { \ 00299 libMesh::err << "Assertion `" #asserted "' failed." << std::endl; \ 00300 libmesh_error_msg(msg); \ 00301 } } while(0) 00302 00303 #define libmesh_assert_equal_to(expr1,expr2) \ 00304 do { \ 00305 if (!(expr1 == expr2)) { \ 00306 libMesh::err << "Assertion `" #expr1 " == " #expr2 "' failed.\n" #expr1 " = " << (expr1) << "\n" #expr2 " = " << (expr2) << std::endl; \ 00307 libmesh_error(); \ 00308 } } while(0) 00309 00310 #define libmesh_assert_not_equal_to(expr1,expr2) \ 00311 do { \ 00312 if (!(expr1 != expr2)) { \ 00313 libMesh::err << "Assertion `" #expr1 " != " #expr2 "' failed.\n" #expr1 " = " << (expr1) << "\n" #expr2 " = " << (expr2) << std::endl; \ 00314 libmesh_error(); \ 00315 } } while(0) 00316 00317 #define libmesh_assert_less(expr1,expr2) \ 00318 do { \ 00319 if (!(expr1 < expr2)) { \ 00320 libMesh::err << "Assertion `" #expr1 " < " #expr2 "' failed.\n" #expr1 " = " << (expr1) << "\n" #expr2 " = " << (expr2) << std::endl; \ 00321 libmesh_error(); \ 00322 } } while(0) 00323 00324 #define libmesh_assert_greater(expr1,expr2) \ 00325 do { \ 00326 if (!(expr1 > expr2)) { \ 00327 libMesh::err << "Assertion `" #expr1 " > " #expr2 "' failed.\n" #expr1 " = " << (expr1) << "\n" #expr2 " = " << (expr2) << std::endl; \ 00328 libmesh_error(); \ 00329 } } while(0) 00330 00331 #define libmesh_assert_less_equal(expr1,expr2) \ 00332 do { \ 00333 if (!(expr1 <= expr2)) { \ 00334 libMesh::err << "Assertion `" #expr1 " <= " #expr2 "' failed.\n" #expr1 " = " << (expr1) << "\n" #expr2 " = " << (expr2) << std::endl; \ 00335 libmesh_error(); \ 00336 } } while(0) 00337 00338 #define libmesh_assert_greater_equal(expr1,expr2) \ 00339 do { \ 00340 if (!(expr1 >= expr2)) { \ 00341 libMesh::err << "Assertion `" #expr1 " >= " #expr2 "' failed.\n" #expr1 " = " << (expr1) << "\n" #expr2 " = " << (expr2) << std::endl; \ 00342 libmesh_error(); \ 00343 } } while(0) 00344 00345 #endif 00346 00347 // The libmesh_error() macro prints a message and throws a LogicError 00348 // exception 00349 // 00350 // The libmesh_not_implemented() macro prints a message and throws a 00351 // NotImplemented exception 00352 // 00353 // The libmesh_file_error(const std::string& filename) macro prints a message 00354 // and throws a FileError exception 00355 // 00356 // The libmesh_convergence_failure() macro 00357 // throws a ConvergenceFailure exception 00358 #define libmesh_error() \ 00359 do { \ 00360 libMesh::MacroFunctions::report_error(__FILE__, __LINE__, __LIBMESH_DATE__, __LIBMESH_TIME__); \ 00361 LIBMESH_THROW(libMesh::LogicError()); \ 00362 } while(0) 00363 00364 #define libmesh_exceptionless_error() \ 00365 do { \ 00366 libMesh::MacroFunctions::report_error(__FILE__, __LINE__, __LIBMESH_DATE__, __LIBMESH_TIME__); \ 00367 std::terminate(); \ 00368 } while(0) 00369 00370 #define libmesh_error_msg(msg) \ 00371 do { \ 00372 libMesh::MacroFunctions::report_error(__FILE__, __LINE__, __LIBMESH_DATE__, __LIBMESH_TIME__); \ 00373 libMesh::err << msg << std::endl; \ 00374 LIBMESH_THROW(libMesh::LogicError()); \ 00375 } while(0) 00376 00377 #define libmesh_not_implemented() \ 00378 do { \ 00379 libMesh::MacroFunctions::report_error(__FILE__, __LINE__, __LIBMESH_DATE__, __LIBMESH_TIME__); \ 00380 LIBMESH_THROW(libMesh::NotImplemented()); \ 00381 } while(0) 00382 00383 #define libmesh_not_implemented_msg(msg) \ 00384 do { \ 00385 libMesh::MacroFunctions::report_error(__FILE__, __LINE__, __LIBMESH_DATE__, __LIBMESH_TIME__); \ 00386 libMesh::err << msg << std::endl; \ 00387 LIBMESH_THROW(libMesh::NotImplemented()); \ 00388 } while(0) 00389 00390 #define libmesh_file_error(filename) \ 00391 do { \ 00392 libMesh::MacroFunctions::report_error(__FILE__, __LINE__, __LIBMESH_DATE__, __LIBMESH_TIME__); \ 00393 LIBMESH_THROW(libMesh::FileError(filename)); \ 00394 } while(0) 00395 00396 #define libmesh_file_error_msg(filename, msg) \ 00397 do { \ 00398 libMesh::MacroFunctions::report_error(__FILE__, __LINE__, __LIBMESH_DATE__, __LIBMESH_TIME__); \ 00399 libMesh:err << msg << std::endl; \ 00400 LIBMESH_THROW(libMesh::FileError(filename)); \ 00401 } while(0) 00402 00403 #define libmesh_convergence_failure() \ 00404 do { \ 00405 LIBMESH_THROW(libMesh::ConvergenceFailure()); \ 00406 } while(0) 00407 00408 // The libmesh_example_requires() macro prints a message and calls 00409 // "return 77;" if the condition specified by the macro is not true. This 00410 // macro is used in the example executables, which should run when the 00411 // configure-time libMesh options support them but which should exit 00412 // without failure otherwise. 00413 // 00414 // This macro only works in main(), because we have no better way than 00415 // "return" from main to immediately exit successfully - std::exit() 00416 // gets seen by at least some MPI stacks as failure. 00417 // 00418 // 77 is the automake code for a skipped test. 00419 00420 #define libmesh_example_requires(condition, option) \ 00421 do { \ 00422 if (!(condition)) { \ 00423 libMesh::out << "Configuring libMesh with " #option " is required to run this example." << std::endl; \ 00424 return 77; \ 00425 } } while(0) 00426 00427 // The libmesh_do_once macro helps us avoid redundant repeated 00428 // repetitions of the same warning messages 00429 #undef libmesh_do_once 00430 #define libmesh_do_once(do_this) \ 00431 do { \ 00432 static bool did_this_already = false; \ 00433 if (!did_this_already) { \ 00434 did_this_already = true; \ 00435 do_this; \ 00436 } } while (0) 00437 00438 00439 // The libmesh_warning macro outputs a file/line/time stamped warning 00440 // message, if warnings are enabled. 00441 #ifdef LIBMESH_ENABLE_WARNINGS 00442 #define libmesh_warning(message) \ 00443 libmesh_do_once(libMesh::out << message \ 00444 << __FILE__ << ", line " << __LINE__ << ", compiled " << __LIBMESH_DATE__ << " at " << __LIBMESH_TIME__ << " ***" << std::endl;) 00445 #else 00446 #define libmesh_warning(message) ((void) 0) 00447 #endif 00448 00449 // The libmesh_experimental macro warns that you are using 00450 // bleeding-edge code 00451 #undef libmesh_experimental 00452 #define libmesh_experimental() \ 00453 libmesh_warning("*** Warning, This code is untested, experimental, or likely to see future API changes: "); 00454 00455 00456 // The libmesh_deprecated macro warns that you are using obsoleted code 00457 #undef libmesh_deprecated 00458 #define libmesh_deprecated() \ 00459 libmesh_warning("*** Warning, This code is deprecated, and likely to be removed in future library versions! "); 00460 00461 // A function template for ignoring unused variables. This is a way 00462 // to shut up unused variable compiler warnings on a case by case 00463 // basis. 00464 template<class T> inline void libmesh_ignore( const T& ) { } 00465 00466 00467 // cast_ref and cast_ptr do a dynamic cast and assert 00468 // the result, if we have RTTI enabled and we're in debug or 00469 // development modes, but they just do a faster static cast if we're 00470 // in optimized mode. 00471 // 00472 // Use these casts when you're certain that a cast will succeed in 00473 // correct code but you want to be able to double-check. 00474 template <typename Tnew, typename Told> 00475 inline Tnew cast_ref(Told& oldvar) 00476 { 00477 #if !defined(NDEBUG) && defined(LIBMESH_HAVE_RTTI) && defined(LIBMESH_ENABLE_EXCEPTIONS) 00478 try 00479 { 00480 Tnew newvar = dynamic_cast<Tnew>(oldvar); 00481 return newvar; 00482 } 00483 catch (std::bad_cast) 00484 { 00485 libMesh::err << "Failed to convert " << typeid(Told).name() 00486 << " reference to " << typeid(Tnew).name() 00487 << std::endl; 00488 libMesh::err << "The " << typeid(Told).name() 00489 << " appears to be a " 00490 << typeid(*(&oldvar)).name() << std::endl; 00491 libmesh_error(); 00492 } 00493 #else 00494 return(static_cast<Tnew>(oldvar)); 00495 #endif 00496 } 00497 00498 template <typename Tnew, typename Told> 00499 inline Tnew libmesh_cast_ref(Told& oldvar) 00500 { 00501 // we use the less redundantly named libMesh::cast_ref now 00502 libmesh_deprecated(); 00503 return cast_ref<Tnew>(oldvar); 00504 } 00505 00506 // We use two different function names to avoid an odd overloading 00507 // ambiguity bug with icc 10.1.008 00508 template <typename Tnew, typename Told> 00509 inline Tnew cast_ptr (Told* oldvar) 00510 { 00511 #if !defined(NDEBUG) && defined(LIBMESH_HAVE_RTTI) 00512 Tnew newvar = dynamic_cast<Tnew>(oldvar); 00513 if (!newvar) 00514 { 00515 libMesh::err << "Failed to convert " << typeid(Told).name() 00516 << " pointer to " << typeid(Tnew).name() 00517 << std::endl; 00518 libMesh::err << "The " << typeid(Told).name() 00519 << " appears to be a " 00520 << typeid(*oldvar).name() << std::endl; 00521 libmesh_error(); 00522 } 00523 return newvar; 00524 #else 00525 return(static_cast<Tnew>(oldvar)); 00526 #endif 00527 } 00528 00529 00530 template <typename Tnew, typename Told> 00531 inline Tnew libmesh_cast_ptr (Told* oldvar) 00532 { 00533 // we use the less redundantly named libMesh::cast_ptr now 00534 return cast_ptr<Tnew>(oldvar); 00535 } 00536 00537 00538 // cast_int asserts that the value of the castee is within the 00539 // bounds which are exactly representable by the output type, if we're 00540 // in debug or development modes, but it just does a faster static 00541 // cast if we're in optimized mode. 00542 // 00543 // Use these casts when you're certain that a cast will succeed in 00544 // correct code but you want to be able to double-check. 00545 template <typename Tnew, typename Told> 00546 inline Tnew cast_int (Told oldvar) 00547 { 00548 libmesh_assert_equal_to 00549 (oldvar, static_cast<Told>(static_cast<Tnew>(oldvar))); 00550 00551 return(static_cast<Tnew>(oldvar)); 00552 } 00553 00554 00555 template <typename Tnew, typename Told> 00556 inline Tnew libmesh_cast_int (Told oldvar) 00557 { 00558 // we use the less redundantly named libMesh::cast_int now 00559 return cast_int<Tnew>(oldvar); 00560 } 00561 00562 00563 // build a integer representation of version 00564 #define LIBMESH_VERSION_ID(major,minor,patch) (((major) << 16) | ((minor) << 8) | ((patch) & 0xFF)) 00565 00566 } // namespace libMesh 00567 00568 00569 // Backwards compatibility 00570 namespace libMeshEnums 00571 { 00572 using namespace libMesh; 00573 } 00574 00575 #endif // LIBMESH_LIBMESH_COMMON_H