20 #include "libmesh/libmesh.h" 23 #include "libmesh/getpot.h" 24 #include "libmesh/reference_counter.h" 25 #include "libmesh/libmesh_singleton.h" 26 #include "libmesh/remote_elem.h" 27 #include "libmesh/threads.h" 28 #include "libmesh/parallel_only.h" 29 #include "libmesh/print_trace.h" 30 #include "libmesh/enum_solver_package.h" 31 #include "libmesh/perf_log.h" 32 #include "libmesh/thread_buffered_syncbuf.h" 43 #ifdef LIBMESH_ENABLE_EXCEPTIONS 47 #ifdef LIBMESH_HAVE_OPENMP 56 #ifdef LIBMESH_HAVE_FENV_H 59 #ifdef LIBMESH_HAVE_XMMINTRIN_H 60 # include <xmmintrin.h> 64 #if defined(LIBMESH_HAVE_MPI) 65 # include "libmesh/ignore_warnings.h" 67 # include "libmesh/restore_warnings.h" 68 #endif // #if defined(LIBMESH_HAVE_MPI) 70 #if defined(LIBMESH_HAVE_PETSC) 71 # include "libmesh/petsc_solver_exception.h" 73 # include <petscerror.h> 74 # include "libmesh/petscdmlibmesh.h" 75 # if defined(LIBMESH_HAVE_SLEPC) 77 # include "libmesh/ignore_warnings.h" 78 # include "libmesh/slepc_macro.h" 80 # include "libmesh/restore_warnings.h" 81 # endif // #if defined(LIBMESH_HAVE_SLEPC) 82 #endif // #if defined(LIBMESH_HAVE_PETSC) 84 #ifdef LIBMESH_HAVE_NETGEN 91 #include "netgen/nglib/nglib.h" 97 #if defined(LIBMESH_HAVE_MPI) && defined(LIBMESH_HAVE_VTK) 98 #include "libmesh/ignore_warnings.h" 99 # include "vtkMPIController.h" 100 #include "libmesh/restore_warnings.h" 109 std::unique_ptr<GetPot> command_line;
111 std::set<std::string> command_line_name_set;
113 std::unique_ptr<std::ofstream> _ofstream;
117 std::streambuf * out_buf (
nullptr);
118 std::streambuf * err_buf (
nullptr);
120 std::unique_ptr<libMesh::Threads::task_scheduler_init> task_scheduler;
121 #if defined(LIBMESH_HAVE_PETSC) 122 bool libmesh_initialized_petsc =
false;
124 #if defined(LIBMESH_HAVE_SLEPC) 125 bool libmesh_initialized_slepc =
false;
133 #if LIBMESH_HAVE_DECL_SIGACTION 134 void libmesh_handleFPE(
int , siginfo_t *
info,
void * )
138 switch (
info->si_code)
140 case FPE_INTDIV:
libMesh::err <<
"integer divide by zero";
break;
141 case FPE_INTOVF:
libMesh::err <<
"integer overflow";
break;
142 case FPE_FLTDIV:
libMesh::err <<
"floating point divide by zero";
break;
143 case FPE_FLTOVF:
libMesh::err <<
"floating point overflow";
break;
144 case FPE_FLTUND:
libMesh::err <<
"floating point underflow";
break;
145 case FPE_FLTRES:
libMesh::err <<
"floating point inexact result";
break;
146 case FPE_FLTINV:
libMesh::err <<
"invalid floating point operation";
break;
147 case FPE_FLTSUB:
libMesh::err <<
"subscript out of range";
break;
152 libmesh_error_msg(
"\nTo track this down, compile in debug mode, then in gdb do:\n" \
153 <<
" break libmesh_handleFPE\n" \
159 void libmesh_handleSEGV(
int , siginfo_t *
info,
void * )
162 libMesh::err <<
"Segmentation fault exception signaled (";
163 switch (
info->si_code)
165 case SEGV_MAPERR:
libMesh::err <<
"Address not mapped";
break;
166 case SEGV_ACCERR:
libMesh::err <<
"Invalid permissions";
break;
171 libmesh_error_msg(
"\nTo track this down, compile in debug mode, then in gdb do:\n" \
172 <<
" break libmesh_handleSEGV\n" \
181 #ifdef LIBMESH_HAVE_MPI 184 libmesh_not_implemented();
199 namespace libMeshPrivateData {
215 #ifdef LIBMESH_HAVE_MPI 233 auto check_stored_buffer = [](
const auto *
const libmesh_dbg_var(stored_buffer)) {
234 libmesh_assert_msg(!stored_buffer,
235 "Oops, we've already stored a prewrapped buffer. We must be calling this " 236 "function a second time in which case we're going to lose the already " 237 "stored prewrapped buffer forever");
246 std::make_unique<ThreadBufferedSyncbuf>(*ob,
true);
256 std::make_unique<ThreadBufferedSyncbuf>(*eb,
true);
284 #ifdef LIBMESH_ENABLE_PERFORMANCE_LOGGING
292 #ifdef LIBMESH_USE_COMPLEX_NUMBERS 308 #ifdef LIBMESH_HAVE_MPI 317 #if defined(LIBMESH_HAVE_PETSC) // PETSc is the default 319 #elif defined(LIBMESH_TRILINOS_HAVE_AZTECOO) // Use Trilinos if PETSc isn't there 321 #elif defined(LIBMESH_HAVE_EIGEN) // Use Eigen if neither are there 323 #elif defined(LIBMESH_HAVE_LASPACK) // Use LASPACK as a last resort 325 #else // No valid linear solver package at compile time 347 #ifdef LIBMESH_ENABLE_EXCEPTIONS 353 #ifdef LIBMESH_ENABLE_EXCEPTIONS 357 std::exception_ptr ex = std::current_exception();
362 std::rethrow_exception(ex);
364 catch (
const std::exception & std_ex)
407 #if defined(LIBMESH_HAVE_MPI) 409 MPI_Initialized (&mpi_initialized);
415 #ifdef LIBMESH_ENABLE_EXCEPTIONS 434 command_line = std::make_unique<GetPot>(argc, argv);
442 auto check_empty_command_line_value = [](
auto & cl,
const std::string & option) {
443 libmesh_error_msg_if(cl.search(option),
444 "Detected option " << option <<
" with no value. Did you forget '='?");
453 std::vector<std::string> n_threads_opt(2);
454 n_threads_opt[0] =
"--n_threads";
455 n_threads_opt[1] =
"--n-threads";
461 for (
auto & option : n_threads_opt)
462 check_empty_command_line_value(*command_line, option);
468 #if !LIBMESH_USING_THREADS 472 libmesh_warning(
"Warning: You requested --n-threads>1 but no threading model is active!\n" 473 <<
"Forcing --n-threads==1 instead!");
478 #ifdef LIBMESH_HAVE_OPENMP 482 task_scheduler = std::make_unique<Threads::task_scheduler_init>(
libMesh::n_threads());
493 const bool handle_mpi_errors =
false;
495 #if defined(LIBMESH_HAVE_MPI) 500 int mpi_thread_request = using_threads;
502 if (mpi_thread_type.empty())
504 check_empty_command_line_value(*command_line,
"--mpi-thread-type");
505 #if defined(PETSC_HAVE_STRUMPACK) && defined(PETSC_HAVE_SLATE) 512 mpi_thread_request = 3;
517 if (mpi_thread_type ==
"single")
520 libmesh_error_msg(
"We are using threads, so we require more mpi thread support " 521 "than '--mpi-thread-type=single'");
522 mpi_thread_request = 0;
524 else if (mpi_thread_type ==
"funneled")
525 mpi_thread_request = 1;
526 else if (mpi_thread_type ==
"serialized")
527 mpi_thread_request = 2;
528 else if (mpi_thread_type ==
"multiple")
529 mpi_thread_request = 3;
532 "Unsupported mpi thread type '" 534 <<
"'. Allowed options are 'single', 'funneled', 'serialized', and 'multiple'");
539 handle_mpi_errors, COMM_WORLD_IN);
542 const std::string timpi_sync =
552 cast_int<processor_id_type>(this->
comm().
rank());
554 cast_int<processor_id_type>(this->
comm().
size());
576 libmesh_parallel_only(this->
comm());
586 #if defined(LIBMESH_HAVE_PETSC) 591 #if defined(LIBMESH_HAVE_MPI) 599 #ifdef LIBMESH_HAVE_MPI 603 this->
_comm->
get() = PETSC_COMM_SELF;
608 PetscBool petsc_already_initialized;
610 if (petsc_already_initialized != PETSC_TRUE)
611 libmesh_initialized_petsc =
true;
612 # if defined(LIBMESH_HAVE_SLEPC) 619 if (!SlepcInitializeCalled)
622 libmesh_initialized_slepc =
true;
625 if (libmesh_initialized_petsc)
633 #ifdef LIBMESH_HAVE_NETGEN 637 #if defined(LIBMESH_HAVE_MPI) && defined(LIBMESH_HAVE_VTK) 653 command_line = std::make_unique<GetPot>(argc, argv);
666 std::ios::sync_with_stdio(
false);
677 std::ostream * newout =
new std::ostream(std::cout.rdbuf());
679 std::ostream * newerr =
new std::ostream(std::cerr.rdbuf());
690 if (cmdline_has_redirect_stdout)
691 libmesh_warning(
"The --redirect-stdout command line option has been deprecated. " 692 "Use '--redirect-output basename' instead.");
698 if (cmdline_has_redirect_stdout || cmdline_has_redirect_output)
700 std::string basename =
"stdout";
703 if (cmdline_has_redirect_output)
706 command_line->search(1,
"--redirect-output");
709 std::string next_string =
"";
710 next_string = command_line->next(next_string);
715 if (next_string.size() > 0 && next_string.find_first_of(
"-") != 0)
716 basename = next_string;
719 std::ostringstream filename;
721 _ofstream = std::make_unique<std::ofstream>(filename.str().c_str());
752 #ifdef LIBMESH_ENABLE_EXCEPTIONS 765 #if defined(LIBMESH_HAVE_HDF5) && !defined(_MSC_VER) 778 setenv(
"HDF5_USE_FILE_LOCKING",
"FALSE", 0);
779 #endif // LIBMESH_HAVE_HDF5 814 task_scheduler.reset();
831 #if !defined(LIBMESH_ENABLE_REFERENCE_COUNTING) || defined(NDEBUG) 833 libMesh::err <<
"Compile in DEBUG mode with --enable-reference-counting" 835 <<
"for more information" 879 #ifdef LIBMESH_ENABLE_EXCEPTIONS 885 #ifdef LIBMESH_HAVE_NETGEN 892 #if defined(LIBMESH_HAVE_PETSC) 897 for (
const auto &
name : cli_names)
898 if (!
name.empty() &&
name[0] ==
'-')
903 PetscBool used = PETSC_FALSE;
904 auto ierr = PetscOptionsUsed(NULL,
name.c_str(), &used);
906 if (used == PETSC_FALSE)
908 ierr = PetscOptionsClearValue(NULL,
name.c_str());
915 #
if defined(LIBMESH_HAVE_MPI)
920 PetscErrorCode ierr = LIBMESH_PETSC_SUCCESS;
921 # if defined(LIBMESH_HAVE_SLEPC) 922 if (libmesh_initialized_slepc)
923 ierr = SlepcFinalize();
925 if (libmesh_initialized_petsc)
926 ierr = PetscFinalize();
932 #if defined(LIBMESH_HAVE_MPI) && defined(LIBMESH_HAVE_VTK) 939 #if defined(LIBMESH_HAVE_MPI) 957 #if !defined(LIBMESH_HAVE_FEENABLEEXCEPT) && defined(LIBMESH_HAVE_XMMINTRIN_H) 958 static int flags = 0;
963 #ifdef LIBMESH_HAVE_FEENABLEEXCEPT 964 feenableexcept(FE_DIVBYZERO | FE_INVALID);
965 #elif LIBMESH_HAVE_XMMINTRIN_H 966 flags = _MM_GET_EXCEPTION_MASK();
967 _MM_SET_EXCEPTION_MASK(flags & ~_MM_MASK_INVALID);
970 #if LIBMESH_HAVE_DECL_SIGACTION 971 struct sigaction new_action, old_action;
974 new_action.sa_sigaction = libmesh_handleFPE;
975 sigemptyset (&new_action.sa_mask);
976 new_action.sa_flags = SA_SIGINFO;
978 sigaction (SIGFPE,
nullptr, &old_action);
979 if (old_action.sa_handler != SIG_IGN)
980 sigaction (SIGFPE, &new_action,
nullptr);
985 #ifdef LIBMESH_HAVE_FEDISABLEEXCEPT 986 fedisableexcept(FE_DIVBYZERO | FE_INVALID);
987 #elif LIBMESH_HAVE_XMMINTRIN_H 988 _MM_SET_EXCEPTION_MASK(flags);
990 signal(SIGFPE, SIG_DFL);
999 #if LIBMESH_HAVE_DECL_SIGACTION 1000 static struct sigaction old_action;
1001 static bool was_on =
false;
1005 struct sigaction new_action;
1009 new_action.sa_sigaction = libmesh_handleSEGV;
1010 sigemptyset (&new_action.sa_mask);
1011 new_action.sa_flags = SA_SIGINFO;
1013 sigaction (SIGSEGV, &new_action, &old_action);
1018 sigaction (SIGSEGV, &old_action,
nullptr);
1021 libmesh_error_msg(
"System call sigaction not supported.");
1032 static std::mutex command_line_names_mutex;
1033 std::scoped_lock lock(command_line_names_mutex);
1035 command_line_name_set.insert(
name);
1042 for (
auto & getter : {&GetPot::get_requested_arguments,
1043 &GetPot::get_requested_variables,
1044 &GetPot::get_requested_sections})
1045 for (
const std::string &
name : (getpot.*getter)())
1052 return std::vector<std::string>(command_line_name_set.begin(),
1053 command_line_name_set.end());
1064 if (!command_line.get())
1070 bool found_it = command_line->search(arg);
1075 std::replace(arg.begin(), arg.end(),
'_',
'-');
1076 found_it = command_line->search(arg);
1082 auto name_begin = arg.begin();
1083 while (*name_begin ==
'-')
1085 std::replace(name_begin, arg.end(),
'-',
'_');
1086 found_it = command_line->search(arg);
1094 template <
typename T>
1101 if (command_line->have_variable(
name))
1109 const std::string stringvalue =
1110 (*command_line)(
name, std::string());
1117 template <
typename T>
1124 for (
const auto & entry : names)
1130 const std::string stringvalue =
1131 (*command_line)(entry, std::string());
1136 for (
const auto & entry : names)
1137 if (command_line->have_variable(entry))
1148 template <
typename T>
1160 return command_line->next(
value);
1167 template <
typename T>
1177 if (command_line->have_variable(
name))
1179 unsigned size = command_line->vector_variable_size(
name);
1182 for (
unsigned i=0; i<size; ++i)
1183 vec[i] = (*command_line)(
name, vec[i], i);
1192 static bool called =
false;
1200 #ifdef LIBMESH_HAVE_PETSC 1205 #ifdef LIBMESH_TRILINOS_HAVE_AZTECOO 1211 #ifdef LIBMESH_HAVE_EIGEN 1213 #
if defined(LIBMESH_HAVE_MPI)
1222 #ifdef LIBMESH_HAVE_LASPACK 1224 #
if defined(LIBMESH_HAVE_MPI)
1237 #
if defined(LIBMESH_HAVE_MPI)
1261 template LIBMESH_EXPORT std::string command_line_value<std::string> (
const std::string &, std::string);
1272 template LIBMESH_EXPORT std::string command_line_value<std::string> (
const std::vector<std::string> &, std::string);
1283 template LIBMESH_EXPORT std::string command_line_next<std::string> (std::string, std::string);
1295 #ifdef LIBMESH_DEFAULT_QUADRUPLE_PRECISION template LIBMESH_EXPORT Real command_line_value< Real >(const std::string &, Real)
std::string name(const ElemQuality q)
This function returns a string containing some name for q.
template LIBMESH_EXPORT double command_line_value< double >(const std::string &, double)
std::unique_ptr< ThreadBufferedSyncbuf > _err_syncd_thread_buffer
T command_line_next(std::string name, T default_value)
Use GetPot's search()/next() functions to get following arguments from the command line...
template LIBMESH_EXPORT char command_line_value< char >(const std::string &, char)
bool closed()
Checks that the library has been closed.
void install_thread_buffered_sync()
static unsigned int n_objects()
Prints the number of outstanding (created, but not yet destroyed) objects.
std::streambuf * _out_prewrap_buf
template LIBMESH_EXPORT float command_line_next< float >(std::string, float)
template LIBMESH_EXPORT void command_line_vector< long double >(const std::string &, std::vector< long double > &)
void sync_type(const SyncType st)
LibMeshInit(int argc, const char *const *argv, MPI_Comm COMM_WORLD_IN=MPI_COMM_WORLD, int n_threads=-1)
Initialize the library for use, with the command line options provided.
template LIBMESH_EXPORT long double command_line_value< long double >(const std::string &, long double)
void enableSEGV(bool on)
Toggle libMesh reporting of segmentation faults.
template LIBMESH_EXPORT unsigned char command_line_next< unsigned char >(std::string, unsigned char)
processor_id_type _n_processors
Total number of processors used.
bool warned_about_auto_ptr
template LIBMESH_EXPORT void command_line_vector< unsigned char >(const std::string &, std::vector< unsigned char > &)
processor_id_type rank() const
PerfLog perflog
A PerfLog object to log performance.
template LIBMESH_EXPORT void command_line_vector< unsigned int >(const std::string &, std::vector< unsigned int > &)
static void print_info(std::ostream &out_stream=libMesh::out)
Prints the reference information, by default to libMesh::out.
template LIBMESH_EXPORT Real command_line_next< Real >(std::string, Real)
MPI_Comm GLOBAL_COMM_WORLD
MPI Communicator used to initialize libMesh.
template LIBMESH_EXPORT float command_line_value< float >(const std::string &, float)
The libMesh namespace provides an interface to certain functionality in the library.
void write_traceout()
Writes a stack trace to a uniquely named file if –enable-tracefiles has been set by configure...
void reset(streamT &target)
Reset the proxy to point to a different target.
int _n_threads
Total number of threads possible.
vtkMPIController * _vtk_mpi_controller
static void setup()
Setup function.
EXTERN_C_BEGIN PETSC_EXTERN PetscErrorCode DMCreate_libMesh(DM)
uint8_t processor_id_type
const Number imaginary
The imaginary unit, .
const Parallel::Communicator & comm() const
Returns a Communicator created from the TIMPIInit object we hold, which will be a compatibility shim ...
SolverPackage default_solver_package()
processor_id_type size() const
template LIBMESH_EXPORT void command_line_vector< int >(const std::string &, std::vector< int > &)
void libmesh_ignore(const Args &...)
std::unique_ptr< ThreadBufferedSyncbuf > _out_syncd_thread_buffer
T command_line_value(const std::string &, T)
template LIBMESH_EXPORT void command_line_vector< double >(const std::string &, std::vector< double > &)
bool _is_initialized
Flag that tells if init() has been called.
template LIBMESH_EXPORT unsigned int command_line_next< unsigned int >(std::string, unsigned int)
template LIBMESH_EXPORT int command_line_next< int >(std::string, int)
template LIBMESH_EXPORT void command_line_vector< short >(const std::string &, std::vector< short > &)
virtual ~LibMeshInit()
Destructor.
template LIBMESH_EXPORT int command_line_value< int >(const std::string &, int)
std::terminate_handler old_terminate_handler
template LIBMESH_EXPORT unsigned char command_line_value< unsigned char >(const std::string &, unsigned char)
template LIBMESH_EXPORT double command_line_next< double >(std::string, double)
processor_id_type _processor_id
The local processor id.
template LIBMESH_EXPORT unsigned short command_line_next< unsigned short >(std::string, unsigned short)
template LIBMESH_EXPORT unsigned int command_line_value< unsigned int >(const std::string &, unsigned int)
BasicOStreamProxy OStreamProxy
template LIBMESH_EXPORT void command_line_vector< unsigned short >(const std::string &, std::vector< unsigned short > &)
template LIBMESH_EXPORT short command_line_value< short >(const std::string &, short)
std::streambuf * _err_prewrap_buf
template LIBMESH_EXPORT short command_line_next< short >(std::string, short)
streambufT * rdbuf() const
Get the associated stream buffer.
template LIBMESH_EXPORT unsigned short command_line_value< unsigned short >(const std::string &, unsigned short)
MPI_Errhandler libmesh_errhandler
TIMPI::TIMPIInit * _timpi_init
void clear()
Clears all the internal data and restores the data structures to a pristine state.
void enableFPE(bool on)
Toggle hardware trap floating point exceptions.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void add_command_line_names(const GetPot &getpot)
Merge a GetPot object's requested names into the set of queried command-line names.
void add_command_line_name(const std::string &name)
Add a name to the set of queried command-line names.
DIE A HORRIBLE DEATH HERE typedef MPI_Comm communicator
void command_line_vector(const std::string &, std::vector< T > &)
std::vector< std::string > command_line_names()
processor_id_type global_processor_id()
void print_log() const
Print the log.
bool initialized()
Checks that library initialization has been done.
void libMesh_MPI_Handler(MPI_Comm *, int *,...)
streamT * get()
Rather than implement every ostream/ios/ios_base function, we'll be lazy and make esoteric uses go th...
template LIBMESH_EXPORT void command_line_vector< char >(const std::string &, std::vector< char > &)
static void cleanup()
Cleanup function.
bool on_command_line(std::string arg)
SolverPackage
Defines an enum for various linear solver packages.
template LIBMESH_EXPORT char command_line_next< char >(std::string, char)
static void disable_print_counter_info()
SolverPackage _solver_package
The default solver package to use.
template LIBMESH_EXPORT void command_line_vector< float >(const std::string &, std::vector< float > &)
template LIBMESH_EXPORT long double command_line_next< long double >(std::string, long double)
void uninstall_thread_buffered_sync()
void ErrorVector unsigned int
const Communicator & comm() const
template LIBMESH_EXPORT void command_line_vector< Real >(const std::string &, std::vector< Real > &)
void libmesh_terminate_handler()
A terminate handler.
Parallel::Communicator * _comm
const RemoteElem * remote_elem