$extrastylesheet
libmesh_common.h
Go to the documentation of this file.
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