LCOV - code coverage report
Current view: top level - include/base - libmesh_common.h (source / functions) Hit Total Coverage
Test: libMesh/libmesh: #4538 (c3bcaa) with base 0a0a9d Lines: 30 46 65.2 %
Date: 2026-09-01 22:57:06 Functions: 199 247 80.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // The libMesh Finite Element Library.
       2             : // Copyright (C) 2002-2026 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
       3             : 
       4             : // This library is free software; you can redistribute it and/or
       5             : // modify it under the terms of the GNU Lesser General Public
       6             : // License as published by the Free Software Foundation; either
       7             : // version 2.1 of the License, or (at your option) any later version.
       8             : 
       9             : // This library is distributed in the hope that it will be useful,
      10             : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12             : // Lesser General Public License for more details.
      13             : 
      14             : // You should have received a copy of the GNU Lesser General Public
      15             : // License along with this library; if not, write to the Free Software
      16             : // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
      17             : 
      18             : 
      19             : 
      20             : #ifndef LIBMESH_LIBMESH_COMMON_H
      21             : #define LIBMESH_LIBMESH_COMMON_H
      22             : 
      23             : // These flags should never be used together.  -DDEBUG means "turn on
      24             : // all the ridiculously expensive error checking"; -DNDEBUG means
      25             : // "turn off all the somewhat affordable error checking"
      26             : #if defined(DEBUG) && defined(NDEBUG)
      27             : #  error DEBUG and NDEBUG should never be defined simultaneously
      28             : #endif
      29             : 
      30             : // The library configuration options
      31             : #include "libmesh/libmesh_config.h"
      32             : 
      33             : // Device compilation support — must be included before assert macros
      34             : // so that LIBMESH_DEVICE_ASSERT is available for the Kokkos path.
      35             : #include "libmesh/libmesh_device.h"
      36             : 
      37             : // Use actual timestamps or constant dummies (to aid ccache)
      38             : #ifdef LIBMESH_ENABLE_TIMESTAMPS
      39             : #  define  LIBMESH_TIME __TIME__
      40             : #  define  LIBMESH_DATE __DATE__
      41             : #else
      42             : #  define  LIBMESH_TIME "notime"
      43             : #  define  LIBMESH_DATE "nodate"
      44             : #endif
      45             : 
      46             : // C/C++ includes everyone should know about
      47             : #include <cstdlib>
      48             : #ifdef __PGI
      49             : // BSK, Thu Feb 20 08:32:06 CST 2014 - For some reason, unless PGI gets
      50             : // <cmath> early this nonsense shows up:
      51             : // "/software/x86_64/pgi/12.9/linux86-64/12.9/include/CC/cmath", line 57: error:
      52             : //           the global scope has no "abs"
      53             : //   using _STLP_VENDOR_CSTD::abs;
      54             : // So include <cmath> as early as possible under the PGI compilers.
      55             : #  include <cmath>
      56             : #endif
      57             : #include <complex>
      58             : #include <typeinfo> // std::bad_cast
      59             : #include <type_traits> // std::decay
      60             : #include <functional> // std::less, etc
      61             : #include <string>
      62             : 
      63             : // Include the MPI definition
      64             : #ifdef LIBMESH_HAVE_MPI
      65             : # include "libmesh/ignore_warnings.h"
      66             : # include <mpi.h>
      67             : # include "libmesh/restore_warnings.h"
      68             : #endif
      69             : 
      70             : // Quad precision if we need it
      71             : #ifdef LIBMESH_DEFAULT_QUADRUPLE_PRECISION
      72             : #include "libmesh/float128_shims.h"
      73             : #endif
      74             : 
      75             : // _basic_ library functionality
      76             : #include "libmesh/libmesh_base.h"
      77             : #include "libmesh/libmesh_exceptions.h"
      78             : 
      79             : // Proxy class for libMesh::out/err output
      80             : #include "libmesh/ostream_proxy.h"
      81             : 
      82             : // Make sure the libmesh_nullptr define is available for backwards
      83             : // compatibility, although we no longer use it in the library.
      84             : #include "libmesh/libmesh_nullptr.h"
      85             : 
      86             : // C++ headers
      87             : #include <iomanip> // setprecision, in assertion macros
      88             : 
      89             : namespace libMesh
      90             : {
      91             : namespace Threads
      92             : {
      93             : // For thread-safe error-messaging. Definitions in threads.h
      94             : void lock_singleton_spin_mutex();
      95             : void unlock_singleton_spin_mutex();
      96             : }
      97             : 
      98             : // Let's define a couple output streams - these will default
      99             : // to cout/cerr, but LibMeshInit (or the user) can also set them to
     100             : // something more sophisticated.
     101             : //
     102             : // We use a proxy class rather than references so they can be
     103             : // reseated at runtime.
     104             : 
     105             : extern OStreamProxy out;
     106             : extern OStreamProxy err;
     107             : 
     108             : // A namespace for functions used in the bodies of the macros below.
     109             : // The macros generally call these functions with __FILE__, __LINE__,
     110             : // __DATE__, and __TIME__ in the appropriate order.  These should not
     111             : // be called by users directly!  The implementations can be found in
     112             : // libmesh_common.C.
     113             : namespace MacroFunctions
     114             : {
     115             : void here(const char * file, int line, const char * date, const char * time, std::ostream & os = libMesh::err);
     116             : void stop(const char * file, int line, const char * date, const char * time);
     117             : void report_error(const char * file, int line, const char * date, const char * time, std::ostream & os = libMesh::err);
     118             : }
     119             : 
     120             : // Undefine any existing macros
     121             : #ifdef Real
     122             : #  undef Real
     123             : #endif
     124             : 
     125             : //#ifdef REAL
     126             : //#  undef REAL
     127             : //#endif
     128             : 
     129             : #ifdef Complex
     130             : #  undef Complex
     131             : #endif
     132             : 
     133             : #ifdef COMPLEX
     134             : #  undef COMPLEX
     135             : #endif
     136             : 
     137             : // Check to see if TOLERANCE has been defined by another
     138             : // package, if so we might want to change the name...
     139             : #ifdef TOLERANCE
     140             : DIE A HORRIBLE DEATH HERE...
     141             : #  undef TOLERANCE
     142             : #endif
     143             : 
     144             : 
     145             : 
     146             : // Define the type to use for real numbers
     147             : 
     148             : typedef LIBMESH_DEFAULT_SCALAR_TYPE Real;
     149             : 
     150             : // Define a corresponding tolerance.  This is what should be
     151             : // considered "good enough" when doing floating point comparisons.
     152             : // For example, v == 0 is changed to std::abs(v) < TOLERANCE.
     153             : 
     154             : #ifdef LIBMESH_DEFAULT_SINGLE_PRECISION
     155             : static constexpr Real TOLERANCE = 2.5e-3;
     156             : # if defined (LIBMESH_DEFAULT_TRIPLE_PRECISION) || \
     157             :      defined (LIBMESH_DEFAULT_QUADRUPLE_PRECISION)
     158             : #  error Cannot define multiple precision levels
     159             : # endif
     160             : #endif
     161             : 
     162             : #ifdef LIBMESH_DEFAULT_TRIPLE_PRECISION
     163             : static constexpr Real TOLERANCE = 1.e-8;
     164             : # if defined (LIBMESH_DEFAULT_QUADRUPLE_PRECISION)
     165             : #  error Cannot define multiple precision levels
     166             : # endif
     167             : #endif
     168             : 
     169             : #ifdef LIBMESH_DEFAULT_QUADRUPLE_PRECISION
     170             : static constexpr Real TOLERANCE = 1.e-11;
     171             : #endif
     172             : 
     173             : #if !defined (LIBMESH_DEFAULT_SINGLE_PRECISION) && \
     174             :     !defined (LIBMESH_DEFAULT_TRIPLE_PRECISION) && \
     175             :     !defined (LIBMESH_DEFAULT_QUADRUPLE_PRECISION)
     176             : static constexpr Real TOLERANCE = 1.e-6;
     177             : #endif
     178             : 
     179             : // Define the type to use for complex numbers
     180             : // Always use std::complex<double>, as required by Petsc?
     181             : // If your version of Petsc doesn't support
     182             : // std::complex<other_precision>, then you'd better just leave
     183             : // Real==double
     184             : typedef std::complex<Real> Complex;
     185             : typedef std::complex<Real> COMPLEX;
     186             : 
     187             : 
     188             : // Helper functions for complex/real number components, to clean up
     189             : // #ifdef LIBMESH_USE_COMPLEX_NUMBERS elsewhere
     190             : //
     191             : // Some of these are just backwards compatibility shims for old code
     192             : // that predated C++11
     193    20240710 : template<typename T> LIBMESH_DEVICE_INLINE T libmesh_real(T a) { return a; }
     194             : template<typename T> LIBMESH_DEVICE_INLINE T libmesh_imag(T /*a*/) { return 0; }
     195   372980122 : template<typename T> LIBMESH_DEVICE_INLINE T libmesh_conj(T a) { return a; }
     196             : 
     197             : template<typename T>
     198           0 : LIBMESH_DEVICE_INLINE T libmesh_real(std::complex<T> a) { return std::real(a); }
     199             : 
     200             : template<typename T>
     201             : LIBMESH_DEVICE_INLINE T libmesh_imag(std::complex<T> a) { return std::imag(a); }
     202             : 
     203             : template<typename T>
     204             : LIBMESH_DEVICE_INLINE std::complex<T> libmesh_conj(std::complex<T> a) { return std::conj(a); }
     205             : 
     206             : // Helper functions for complex/real number classification, because
     207             : // for some reason std:: never added isfinite/isinf/isnan overloads
     208             : // for std::complex.
     209             : 
     210             : template <typename T>
     211         658 : LIBMESH_DEVICE_INLINE bool libmesh_isinf(T x) { using std::isinf; return isinf(x); }
     212             : 
     213             : template <typename T>
     214      203273 : LIBMESH_DEVICE_INLINE bool libmesh_isnan(T x) { using std::isnan; return isnan(x); }
     215             : 
     216             : // You'd think we'd treat inf,NaN pairs as NaN rather than infinite,
     217             : // but that's not what the C/C++ standards recommend (ever since C99
     218             : // Annex G), so we'll follow their lead.
     219             : //
     220             : // Anyone who doesn't care about these subtle NaN/inf distinctions
     221             : // should just test isfinite() in their code, and can also probably
     222             : // speed up their arithmetic greatly by using -fcx-limited-range
     223             : // and/or -fcx-fortran-rules
     224             : template <typename T>
     225             : LIBMESH_DEVICE_INLINE bool libmesh_isinf(std::complex<T> a)
     226             : { return (std::isinf(std::real(a)) || std::isinf(std::imag(a))); }
     227             : 
     228             : // Treats inf,NaN pairs as infinite rather than NaN
     229             : template <typename T>
     230       42964 : LIBMESH_DEVICE_INLINE bool libmesh_isnan(std::complex<T> a)
     231       42964 : { return ((std::isnan(std::real(a)) || std::isnan(std::imag(a))) &&
     232       42964 :           !std::isinf(std::real(a)) && !std::isinf(std::imag(a))); }
     233             : 
     234             : template <typename T>
     235             : LIBMESH_DEVICE_INLINE bool isfinite(std::complex<T> a)
     236             : {
     237             :   return (std::isfinite(std::real(a)) && std::isfinite(std::imag(a)));
     238             : }
     239             : 
     240             : template <typename T>
     241             : LIBMESH_DEVICE_INLINE bool isinf(std::complex<T> a)
     242             : {
     243             :   return (std::isinf(std::real(a)) || std::isinf(std::imag(a)));
     244             : }
     245             : 
     246             : template <typename T>
     247             : LIBMESH_DEVICE_INLINE bool isnan(std::complex<T> a)
     248             : {
     249             : { return ((std::isnan(std::real(a)) || std::isnan(std::imag(a))) &&
     250             :           !std::isinf(std::real(a)) && !std::isinf(std::imag(a))); }
     251             : }
     252             : 
     253             : // Define the value type for unknowns in simulations.
     254             : // This is either Real or Complex, depending on how
     255             : // the library was configures
     256             : #if   defined (LIBMESH_USE_REAL_NUMBERS)
     257             : typedef Real Number;
     258             : #elif defined (LIBMESH_USE_COMPLEX_NUMBERS)
     259             : typedef Complex Number;
     260             : #else
     261             : DIE A HORRIBLE DEATH HERE...
     262             : #endif
     263             : 
     264             : 
     265             : // Define the value type for error estimates.
     266             : // Since AMR/C decisions don't have to be precise,
     267             : // we default to float for memory efficiency.
     268             : typedef float ErrorVectorReal;
     269             : #define MPI_ERRORVECTORREAL MPI_FLOAT
     270             : 
     271             : 
     272             : #ifdef LIBMESH_HAVE_MPI
     273             : 
     274             : /**
     275             :  * MPI Communicator used to initialize libMesh.
     276             :  */
     277             : extern MPI_Comm GLOBAL_COMM_WORLD;
     278             : #else
     279             : 
     280             : /**
     281             :  * Something to use with CHKERRABORT if we're just using PETSc's MPI
     282             :  * "uni" stub.
     283             :  */
     284             : extern int GLOBAL_COMM_WORLD;
     285             : #endif
     286             : 
     287             : // This global variable is to help us deprecate AutoPtr.  We can't
     288             : // just use libmesh_deprecated() because then you get one print out
     289             : // per template instantiation, instead of one total print out.
     290             : extern bool warned_about_auto_ptr;
     291             : 
     292             : // These are useful macros that behave like functions in the code.
     293             : // If you want to make sure you are accessing a section of code just
     294             : // stick a libmesh_here(); in it, for example
     295             : #define libmesh_here()                                                  \
     296             :   do {                                                                  \
     297             :     libMesh::MacroFunctions::here(__FILE__, __LINE__, LIBMESH_DATE, LIBMESH_TIME); \
     298             :   } while (0)
     299             : 
     300             : // the libmesh_stop() macro will stop the code until a SIGCONT signal
     301             : // is received.  This is useful, for example, when determining the
     302             : // memory used by a given operation.  A libmesh_stop() could be
     303             : // inserted before and after a questionable operation and the delta
     304             : // memory can be obtained from a ps or top.  This macro only works for
     305             : // serial cases.
     306             : #define libmesh_stop()                                                  \
     307             :   do {                                                                  \
     308             :     libMesh::MacroFunctions::stop(__FILE__, __LINE__, LIBMESH_DATE, LIBMESH_TIME); \
     309             :   } while (0)
     310             : 
     311             : // The libmesh_dbg_var() macro indicates that an argument to a function
     312             : // is used only in debug and devel modes (i.e., when NDEBUG is not defined).
     313             : #ifndef NDEBUG
     314             : #define libmesh_dbg_var(var) var
     315             : #else
     316             : #define libmesh_dbg_var(var)
     317             : #endif
     318             : 
     319             : // The libmesh_inf_var() macro indicates that an argument to a function
     320             : // is used only when infinite elements are enabled
     321             : #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
     322             : #define libmesh_inf_var(var) var
     323             : #else
     324             : #define libmesh_inf_var(var)
     325             : #endif
     326             : 
     327             : // The libmesh_assert() macro acts like C's assert(), but throws a
     328             : // libmesh_error() (including stack trace, etc) instead of just exiting.
     329             : //
     330             : // In .K translation units (ACSM_KOKKOS_COMPILATION defined),
     331             : // LIBMESH_DEVICE_ASSERT is provided by libmesh_device.h using
     332             : // printf + Kokkos::abort() — device-safe across CUDA/HIP/SYCL.
     333             : // The assert macros delegate to it so that both host and device
     334             : // code in the same file get assertion checking.
     335             : #ifdef NDEBUG
     336             : 
     337             : #define libmesh_assert_msg(asserted, msg)  ((void) 0)
     338             : #define libmesh_exceptionless_assert_msg(asserted, msg)  ((void) 0)
     339             : #define libmesh_assert_equal_to_msg(expr1,expr2, msg)  ((void) 0)
     340             : #define libmesh_assert_not_equal_to_msg(expr1,expr2, msg)  ((void) 0)
     341             : #define libmesh_assert_less_msg(expr1,expr2, msg)  ((void) 0)
     342             : #define libmesh_assert_greater_msg(expr1,expr2, msg)  ((void) 0)
     343             : #define libmesh_assert_less_equal_msg(expr1,expr2, msg)  ((void) 0)
     344             : #define libmesh_assert_greater_equal_msg(expr1,expr2, msg)  ((void) 0)
     345             : 
     346             : #elif defined(ACSM_KOKKOS_COMPILATION)
     347             : 
     348             : // Kokkos compilation: use the device-safe assert from libmesh_device.h.
     349             : #define libmesh_assert_msg(asserted, msg)  LIBMESH_DEVICE_ASSERT(asserted)
     350             : #define libmesh_exceptionless_assert_msg(asserted, msg) LIBMESH_DEVICE_ASSERT(asserted)
     351             : #define libmesh_assert_equal_to_msg(expr1,expr2, msg)  LIBMESH_DEVICE_ASSERT((expr1) == (expr2))
     352             : #define libmesh_assert_not_equal_to_msg(expr1,expr2, msg)  LIBMESH_DEVICE_ASSERT((expr1) != (expr2))
     353             : #define libmesh_assert_less_msg(expr1,expr2, msg)  LIBMESH_DEVICE_ASSERT((expr1) < (expr2))
     354             : #define libmesh_assert_greater_msg(expr1,expr2, msg)  LIBMESH_DEVICE_ASSERT((expr1) > (expr2))
     355             : #define libmesh_assert_less_equal_msg(expr1,expr2, msg)  LIBMESH_DEVICE_ASSERT((expr1) <= (expr2))
     356             : #define libmesh_assert_greater_equal_msg(expr1,expr2, msg)  LIBMESH_DEVICE_ASSERT((expr1) >= (expr2))
     357             : 
     358             : #else
     359             : 
     360             : #define libmesh_assertion_types(expr1,expr2)                            \
     361             :   typedef typename std::decay<decltype(expr1)>::type libmesh_type1;     \
     362             :   typedef typename std::decay<decltype(expr2)>::type libmesh_type2
     363             : 
     364             : #define libmesh_assert_msg(asserted, msg)                               \
     365             :   do {                                                                  \
     366             :     if (!(asserted)) {                                                  \
     367             :       libmesh_error_msg("Assertion `" #asserted "' failed.\n" << msg);                                           \
     368             :     } } while (0)
     369             : 
     370             : #define libmesh_exceptionless_assert_msg(asserted, msg)                 \
     371             :   do {                                                                  \
     372             :     if (!(asserted)) {                                                  \
     373             :       libMesh::Threads::lock_singleton_spin_mutex();                    \
     374             :       libMesh::err << "Assertion `" #asserted "' failed." << std::endl; \
     375             :       libMesh::Threads::unlock_singleton_spin_mutex();                  \
     376             :       libmesh_exceptionless_error();                                    \
     377             :     } } while (0)
     378             : 
     379             : #define libmesh_assert_equal_to_msg(expr1,expr2, msg)                   \
     380             :   do {                                                                  \
     381             :     if (!((expr1) == (expr2))) {                                        \
     382             :       libmesh_error_msg(std::setprecision(17) << "Assertion `" #expr1 " == " #expr2 "' failed.\n" #expr1 " = " << (expr1) << "\n" #expr2 " = " << (expr2) << '\n' << msg << std::endl); \
     383             :     } } while (0)
     384             : 
     385             : #define libmesh_assert_not_equal_to_msg(expr1,expr2, msg)               \
     386             :   do {                                                                  \
     387             :     if (!((expr1) != (expr2))) {                                        \
     388             :       libmesh_error_msg(std::setprecision(17) << "Assertion `" #expr1 " != " #expr2 "' failed.\n" #expr1 " = " << (expr1) << "\n" #expr2 " = " << (expr2) << '\n' << msg << std::endl); \
     389             :     } } while (0)
     390             : 
     391             : template <template <class> class Comp>
     392             : struct casting_compare {
     393             : 
     394             :   template <typename T1, typename T2>
     395  1024937794 :   bool operator()(const T1 & e1, const T2 & e2) const
     396             :   {
     397             :     typedef typename std::decay<T1>::type DT1;
     398             :     typedef typename std::decay<T2>::type DT2;
     399  2049875588 :     return (Comp<DT2>()(static_cast<DT2>(e1), e2) &&
     400  2049875588 :             Comp<DT1>()(e1, static_cast<DT1>(e2)));
     401             :   }
     402             : 
     403             :   template <typename T1>
     404   185999293 :   bool operator()(const T1 & e1, const T1 & e2) const
     405             :   {
     406   185999293 :     return Comp<T1>()(e1, e2);
     407             :   }
     408             : };
     409             : 
     410             : #define libmesh_assert_less_msg(expr1,expr2, msg)                       \
     411             :   do {                                                                  \
     412             :     if (!libMesh::casting_compare<std::less>()(expr1, expr2)) {         \
     413             :       libmesh_error_msg(std::setprecision(17) << "Assertion `" #expr1 " < " #expr2 "' failed.\n" #expr1 " = " << (expr1) << "\n" #expr2 " = " << (expr2) << '\n' << msg << std::endl); \
     414             :     } } while (0)
     415             : 
     416             : #define libmesh_assert_greater_msg(expr1,expr2, msg)                    \
     417             :   do {                                                                  \
     418             :     if (!libMesh::casting_compare<std::greater>()(expr1, expr2)) {      \
     419             :       libmesh_error_msg(std::setprecision(17) << "Assertion `" #expr1 " > " #expr2 "' failed.\n" #expr1 " = " << (expr1) << "\n" #expr2 " = " << (expr2) << '\n' << msg << std::endl); \
     420             :     } } while (0)
     421             : 
     422             : #define libmesh_assert_less_equal_msg(expr1,expr2, msg)                 \
     423             :   do {                                                                  \
     424             :     if (!libMesh::casting_compare<std::less_equal>()(expr1, expr2)) {   \
     425             :       libmesh_error_msg(std::setprecision(17) << "Assertion `" #expr1 " <= " #expr2 "' failed.\n" #expr1 " = " << (expr1) << "\n" #expr2 " = " << (expr2) << '\n' << msg << std::endl); \
     426             :     } } while (0)
     427             : 
     428             : #define libmesh_assert_greater_equal_msg(expr1,expr2, msg)              \
     429             :   do {                                                                  \
     430             :     if (!libMesh::casting_compare<std::greater_equal>()(expr1, expr2)) { \
     431             :       libmesh_error_msg(std::setprecision(17) << "Assertion `" #expr1 " >= " #expr2 "' failed.\n" #expr1 " = " << (expr1) << "\n" #expr2 " = " << (expr2) << '\n' << msg << std::endl); \
     432             :     } } while (0)
     433             : 
     434             : #endif
     435             : 
     436             : 
     437             : #define libmesh_assert(asserted) libmesh_assert_msg(asserted, "")
     438             : #define libmesh_exceptionless_assert(asserted) libmesh_exceptionless_assert_msg(asserted, "")
     439             : #define libmesh_assert_equal_to(expr1,expr2) libmesh_assert_equal_to_msg(expr1,expr2, "")
     440             : #define libmesh_assert_not_equal_to(expr1,expr2) libmesh_assert_not_equal_to_msg(expr1,expr2, "")
     441             : #define libmesh_assert_less(expr1,expr2) libmesh_assert_less_msg(expr1,expr2, "")
     442             : #define libmesh_assert_greater(expr1,expr2) libmesh_assert_greater_msg(expr1,expr2, "")
     443             : #define libmesh_assert_less_equal(expr1,expr2) libmesh_assert_less_equal_msg(expr1,expr2, "")
     444             : #define libmesh_assert_greater_equal(expr1,expr2) libmesh_assert_greater_equal_msg(expr1,expr2, "")
     445             : 
     446             : // The libmesh_error() macro prints a message and throws a LogicError
     447             : // exception
     448             : //
     449             : // The libmesh_not_implemented() macro prints a message and throws a
     450             : // NotImplemented exception
     451             : //
     452             : // The libmesh_file_error(const std::string & filename) macro prints a message
     453             : // and throws a FileError exception
     454             : //
     455             : // The libmesh_convergence_failure() macro
     456             : // throws a ConvergenceFailure exception
     457             : //
     458             : // The libmesh_degenerate_mapping() macro prints a message into and
     459             : // throws a DegenerateMap exception
     460             : //
     461             : // The libmesh_terminate() macro prints a message and throws a
     462             : // TerminationException exception
     463             : #if LIBMESH_IN_DEVICE_CODE
     464             : #define libmesh_error_msg(msg)                                          \
     465             :   do {                                                                  \
     466             :     LIBMESH_DEVICE_ERROR_MSG(msg);                                      \
     467             :   } while (0)
     468             : #else
     469             : #define libmesh_error_msg(msg)                                          \
     470             :   do {                                                                  \
     471             :     std::stringstream message_stream;                                   \
     472             :     message_stream << msg << '\n';                                      \
     473             :     libMesh::MacroFunctions::report_error(__FILE__, __LINE__, LIBMESH_DATE, LIBMESH_TIME, message_stream); \
     474             :     LIBMESH_THROW(libMesh::LogicError(message_stream.str()));           \
     475             :   } while (0)
     476             : #endif
     477             : 
     478             : #define libmesh_error() libmesh_error_msg("")
     479             : 
     480             : #define libmesh_error_msg_if(cond, msg)         \
     481             :   do {                                          \
     482             :     if (cond)                                   \
     483             :       libmesh_error_msg(msg);                   \
     484             :   } while (0)
     485             : 
     486             : #define libmesh_exceptionless_error_msg(msg)                            \
     487             :   do {                                                                  \
     488             :     libMesh::Threads::lock_singleton_spin_mutex();                      \
     489             :     libMesh::err << msg << '\n';                                        \
     490             :     libMesh::Threads::unlock_singleton_spin_mutex();                    \
     491             :     libmesh_try { libMesh::MacroFunctions::report_error(__FILE__, __LINE__, LIBMESH_DATE, LIBMESH_TIME); } \
     492             :     libmesh_catch (...) {}                                              \
     493             :     std::terminate();                                                   \
     494             :   } while (0)
     495             : 
     496             : #define libmesh_exceptionless_error() libmesh_exceptionless_error_msg("")
     497             : 
     498             : #define libmesh_not_implemented_msg(msg)                                \
     499             :   do {                                                                  \
     500             :     std::stringstream message_stream;                                   \
     501             :     message_stream << msg << '\n';                                      \
     502             :     libMesh::MacroFunctions::report_error(__FILE__, __LINE__, LIBMESH_DATE, LIBMESH_TIME, message_stream); \
     503             :     LIBMESH_THROW(libMesh::NotImplemented(message_stream.str()));       \
     504             :   } while (0)
     505             : 
     506             : #define libmesh_not_implemented() libmesh_not_implemented_msg("")
     507             : 
     508             : #define libmesh_file_error_msg(filename, msg)                           \
     509             :   do {                                                                  \
     510             :     std::stringstream message_stream;                                   \
     511             :     message_stream << msg << '\n';                                      \
     512             :     libMesh::MacroFunctions::report_error(__FILE__, __LINE__, LIBMESH_DATE, LIBMESH_TIME, message_stream); \
     513             :     LIBMESH_THROW(libMesh::FileError(filename, message_stream.str()));  \
     514             :   } while (0)
     515             : 
     516             : #define libmesh_file_error(filename) libmesh_file_error_msg(filename,"")
     517             : 
     518             : #define libmesh_convergence_failure()                   \
     519             :   do {                                                  \
     520             :     LIBMESH_THROW(libMesh::ConvergenceFailure());       \
     521             :   } while (0)
     522             : 
     523             : #define libmesh_degenerate_mapping_msg(msg)                          \
     524             :   do {                                                               \
     525             :     std::stringstream message_stream;                                \
     526             :     message_stream << msg << '\n';                                   \
     527             :     LIBMESH_THROW(libMesh::DegenerateMap(message_stream.str())); \
     528             :   } while (0)
     529             : 
     530             : #define libmesh_degenerate_mapping(filename) libmesh_degenerate_mapping_msg("")
     531             : 
     532             : #define libmesh_terminate()                         \
     533             :   do {                                              \
     534             :     LIBMESH_THROW(libMesh::TerminationException()); \
     535             :   } while (0)
     536             : 
     537             : // The libmesh_example_requires() macro prints a message and calls
     538             : // "return 77;" if the condition specified by the macro is not true.  This
     539             : // macro is used in the example executables, which should run when the
     540             : // configure-time libMesh options support them but which should exit
     541             : // without failure otherwise.
     542             : //
     543             : // This macro only works in main(), because we have no better way than
     544             : // "return" from main to immediately exit successfully - std::exit()
     545             : // gets seen by at least some MPI stacks as failure.
     546             : //
     547             : // 77 is the automake code for a skipped test.
     548             : 
     549             : #define libmesh_example_requires(condition, option)                     \
     550             :   do {                                                                  \
     551             :     if (!(condition)) {                                                 \
     552             :       libMesh::out << "Configuring libMesh with " << option << " is required to run this example." << std::endl; \
     553             :       return 77;                                                        \
     554             :     } } while (0)
     555             : 
     556             : // The libmesh_do_once macro helps us avoid redundant repeated
     557             : // repetitions of the same warning messages
     558             : #undef libmesh_do_once
     559             : #define libmesh_do_once(do_this)                \
     560             :   do {                                          \
     561             :     static bool did_this_already = false;       \
     562             :     if (!did_this_already) {                    \
     563             :       did_this_already = true;                  \
     564             :       do_this;                                  \
     565             :     } } while (0)
     566             : 
     567             : 
     568             : // The libmesh_warning macro outputs a file/line/time stamped warning
     569             : // message, if warnings are enabled.
     570             : #ifdef LIBMESH_ENABLE_WARNINGS
     571             : #define libmesh_warning(message)                                        \
     572             :   libmesh_do_once(libMesh::out << message                               \
     573             :                   << __FILE__ << ", line " << __LINE__ << ", compiled " << LIBMESH_DATE << " at " << LIBMESH_TIME << " ***" << std::endl;)
     574             : #else
     575             : #define libmesh_warning(message)  ((void) 0)
     576             : #endif
     577             : 
     578             : // The libmesh_experimental macro warns that you are using
     579             : // bleeding-edge code
     580             : #undef libmesh_experimental
     581             : #define libmesh_experimental()                                          \
     582             :   libmesh_warning("*** Warning, This code is untested, experimental, or likely to see future API changes: ");
     583             : 
     584             : 
     585             : // The libmesh_deprecated macro warns that you are using obsoleted code
     586             : #undef libmesh_deprecated
     587             : #ifndef LIBMESH_ENABLE_DEPRECATED
     588             : #define libmesh_deprecated()                                            \
     589             :   libmesh_error_msg("*** Error, This code is deprecated, and likely to be removed in future library versions! ");
     590             : #else
     591             : #define libmesh_deprecated()                                            \
     592             :   libmesh_warning("*** Warning, This code is deprecated, and likely to be removed in future library versions! ");
     593             : #endif
     594             : 
     595             : // A function template for ignoring unused variables.  This is a way
     596             : // to shut up unused variable compiler warnings on a case by case
     597             : // basis.
     598   329400645 : template<class ...Args> inline void libmesh_ignore( const Args&... ) { }
     599             : 
     600             : 
     601             : // Workaround for incomplete C++17 support in some compilers/libs
     602             : 
     603             : #ifdef LIBMESH_HAVE_CXX17_SPLICING
     604             : template <typename T>
     605       53508 : void libmesh_merge_move(T & target, T & source)
     606             : {
     607       53508 :   target.merge(std::move(source));
     608     1610676 : }
     609             : #else
     610             : template <typename T>
     611             : void libmesh_merge_move(T & target, T & source)
     612             : {
     613             :   target.insert(source.begin(), source.end());
     614             :   source.clear(); // Avoid forwards-incompatibility
     615             : }
     616             : #endif // LIBMESH_HAVE_CXX17_SPLICING
     617             : 
     618             : /**
     619             :  * Mostly system independent demangler
     620             :  */
     621             :  std::string demangle(const char * name);
     622             : 
     623             : // cast_ref and cast_ptr do a dynamic cast and assert
     624             : // the result, if we have RTTI enabled and we're in debug or
     625             : // development modes, but they just do a faster static cast if we're
     626             : // in optimized mode.
     627             : //
     628             : // Use these casts when you're certain that a cast will succeed in
     629             : // correct code but you want to be able to double-check.
     630             : template <typename Tnew, typename Told>
     631     8606488 : inline Tnew cast_ref(Told & oldvar)
     632             : {
     633             : #if !defined(NDEBUG) && defined(LIBMESH_HAVE_RTTI) && defined(LIBMESH_ENABLE_EXCEPTIONS)
     634             :   try
     635             :     {
     636     8606488 :       Tnew newvar = dynamic_cast<Tnew>(oldvar);
     637     8606488 :       return newvar;
     638             :     }
     639           0 :   catch (std::bad_cast &)
     640             :     {
     641           0 :       libMesh::err << "Failed to convert " << demangle(typeid(Told).name())
     642           0 :                    << " reference to " << demangle(typeid(Tnew).name())
     643           0 :                    << std::endl;
     644           0 :       libMesh::err << "The " << demangle(typeid(Told).name())
     645           0 :                    << " appears to be a "
     646           0 :                    << demangle(typeid(*(&oldvar)).name()) << std::endl;
     647           0 :       libmesh_error();
     648             :     }
     649             : #else
     650             :   return(static_cast<Tnew>(oldvar));
     651             : #endif
     652             : }
     653             : 
     654             : // We use two different function names to avoid an odd overloading
     655             : // ambiguity bug with icc 10.1.008
     656             : template <typename Tnew, typename Told>
     657   743617611 : inline Tnew cast_ptr (Told * oldvar)
     658             : {
     659             : #if !defined(NDEBUG) && defined(LIBMESH_HAVE_RTTI)
     660   743617611 :   Tnew newvar = dynamic_cast<Tnew>(oldvar);
     661   743617611 :   if (!newvar)
     662             :     {
     663           0 :       libMesh::err << "Failed to convert " << demangle(typeid(Told).name())
     664           0 :                    << " pointer to " << demangle(typeid(Tnew).name())
     665           0 :                    << std::endl;
     666           0 :       libMesh::err << "The " << demangle(typeid(Told).name())
     667           0 :                    << " appears to be a "
     668           0 :                    << demangle(typeid(*oldvar).name()) << std::endl;
     669           0 :       libmesh_error();
     670             :     }
     671   743617611 :   return newvar;
     672             : #else
     673             :   return(static_cast<Tnew>(oldvar));
     674             : #endif
     675             : }
     676             : 
     677             : 
     678             : #ifdef LIBMESH_ENABLE_DEPRECATED
     679             : template <typename Tnew, typename Told>
     680             : inline Tnew libmesh_cast_ptr (Told * oldvar)
     681             : {
     682             :   libmesh_deprecated();
     683             : 
     684             :   // we use the less redundantly named libMesh::cast_ptr now
     685             :   return cast_ptr<Tnew>(oldvar);
     686             : }
     687             : #endif // LIBMESH_ENABLE_DEPRECATED
     688             : 
     689             : 
     690             : // cast_int asserts that the value of the castee is within the
     691             : // bounds which are exactly representable by the output type, if we're
     692             : // in debug or development modes, but it just does a faster static
     693             : // cast if we're in optimized mode.
     694             : //
     695             : // Use these casts when you're certain that a cast will succeed in
     696             : // correct code but you want to be able to double-check.
     697             : template <typename Tnew, typename Told>
     698  9031715111 : inline Tnew cast_int (Told oldvar)
     699             : {
     700   130436502 :   libmesh_assert_equal_to
     701             :     (oldvar, static_cast<Told>(static_cast<Tnew>(oldvar)));
     702             : 
     703 21741290812 :   return(static_cast<Tnew>(oldvar));
     704             : }
     705             : 
     706             : 
     707             : template <typename Tnew, typename Told>
     708             : inline Tnew libmesh_cast_int (Told oldvar)
     709             : {
     710             :   // we use the less redundantly named libMesh::cast_int now
     711             :   return cast_int<Tnew>(oldvar);
     712             : }
     713             : 
     714             : 
     715             : /**
     716             :  * restrict_int checks that the value of the castee is within the
     717             :  * bounds which are exactly representable by the output type, even in
     718             :  * optimized modes.
     719             :  *
     720             :  * Use this cast when you suspect that the input may not succeed in
     721             :  * correct code (e.g. when an input file is being read from a format
     722             :  * that may allow wider integer types than the current libMesh
     723             :  * configuration).
     724             :  */
     725             : template <typename Tnew, typename Told>
     726      733940 : inline Tnew restrict_int (Told oldvar)
     727             : {
     728             :   if constexpr (!std::is_same_v<Tnew, Told>)
     729             :     {
     730      733940 :       const Tnew returnval = static_cast<Tnew>(oldvar);
     731             : 
     732      733940 :       libmesh_error_msg_if (oldvar != static_cast<Told>(returnval),
     733             :                             "restrict_int failed: " << oldvar << " does not fit in type " << typeid(returnval).name());
     734             :     }
     735             : 
     736      733940 :   return oldvar;
     737             : }
     738             : 
     739             : /**
     740             :  * This is a helper variable template for cases when we want to use a default compile-time
     741             :  * error with constexpr-based if conditions. The templating delays the triggering
     742             :  * of the static assertion until the template is instantiated.
     743             :  */
     744             : template <class T>
     745             : constexpr std::false_type always_false{};
     746             : 
     747             : static constexpr std::size_t libmesh_dim = LIBMESH_DIM;
     748             : 
     749             : // build a integer representation of version
     750             : #define LIBMESH_VERSION_ID(major,minor,patch) (((major) << 16) | ((minor) << 8) | ((patch) & 0xFF))
     751             : 
     752             : 
     753             : // libmesh_override is simply a synonym for override as we now require
     754             : // a C++11 compiler that supports this keyword.
     755             : #define libmesh_override override
     756             : 
     757             : // libmesh_delete is simply a synonym for '=delete' as we now require
     758             : // a C++11 compiler that supports this keyword.
     759             : #define libmesh_delete =delete
     760             : 
     761             : // libmesh_final is simply a synonym for 'final' as we now require
     762             : // a C++11 compiler that supports this keyword.
     763             : #define libmesh_final final
     764             : 
     765             : // Define backwards-compatible fallthrough attribute.  We could
     766             : // eventually also add support for other compiler-specific fallthrough
     767             : // attributes.
     768             : #ifdef LIBMESH_HAVE_CXX17_FALLTHROUGH_ATTRIBUTE
     769             : #define libmesh_fallthrough() [[fallthrough]]
     770             : #elif defined(LIBMESH_HAVE_DOUBLE_UNDERSCORE_ATTRIBUTE_FALLTHROUGH)
     771             : #define libmesh_fallthrough() __attribute__((fallthrough))
     772             : #else
     773             : #define libmesh_fallthrough() ((void) 0)
     774             : #endif
     775             : 
     776             : template <typename T>
     777             : class PassKey
     778             : {
     779             :   friend T;
     780             :   constexpr PassKey() = default;
     781             : };
     782             : } // namespace libMesh
     783             : 
     784             : 
     785             : // Backwards compatibility
     786             : namespace libMeshEnums
     787             : {
     788             : using namespace libMesh;
     789             : }
     790             : 
     791             : // Backwards compatibility with pre-TIMPI reference
     792             : namespace TIMPI {}
     793             : 
     794             : namespace libMesh {
     795             :   namespace Parallel {
     796             :     using namespace TIMPI;
     797             :   }
     798             : }
     799             : 
     800             : 
     801             : // Here we add missing types to the standard namespace.  For example,
     802             : // std::max(double, float) etc... are well behaved but not defined
     803             : // by the standard.  This also includes workarounds for super-strict
     804             : // implementations, for example Sun Studio and PGI C++.  However,
     805             : // this necessarily requires breaking the ISO-C++ standard, and is
     806             : // really just a hack.  As such, only do it if we are building the
     807             : // libmesh library itself.  Specifically, *DO NOT* export this to
     808             : // user code or install this header.
     809             : //
     810             : // We put this at the end of libmesh_common.h so we can make use of
     811             : // any exotic definitions of Real above.
     812             : #ifdef LIBMESH_IS_COMPILING_ITSELF
     813             : #  include "libmesh/libmesh_augment_std_namespace.h"
     814             : #endif
     815             : 
     816             : 
     817             : #ifdef _MSC_VER
     818             : #define LIBMESH_EXPORT __declspec(dllexport)
     819             : #else
     820             : #define LIBMESH_EXPORT
     821             : #endif
     822             : 
     823             : 
     824             : #endif // LIBMESH_LIBMESH_COMMON_H

Generated by: LCOV version 1.14