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" 42 #ifdef LIBMESH_ENABLE_EXCEPTIONS 46 #ifdef LIBMESH_HAVE_OPENMP 55 #ifdef LIBMESH_HAVE_FENV_H 58 #ifdef LIBMESH_HAVE_XMMINTRIN_H 59 # include <xmmintrin.h> 63 #if defined(LIBMESH_HAVE_MPI) 64 # include "libmesh/ignore_warnings.h" 66 # include "libmesh/restore_warnings.h" 67 #endif // #if defined(LIBMESH_HAVE_MPI) 69 #if defined(LIBMESH_HAVE_PETSC) 70 # include "libmesh/petsc_solver_exception.h" 72 # include <petscerror.h> 73 # include "libmesh/petscdmlibmesh.h" 74 # if defined(LIBMESH_HAVE_SLEPC) 76 # include "libmesh/ignore_warnings.h" 77 # include "libmesh/slepc_macro.h" 79 # include "libmesh/restore_warnings.h" 80 # endif // #if defined(LIBMESH_HAVE_SLEPC) 81 #endif // #if defined(LIBMESH_HAVE_PETSC) 83 #ifdef LIBMESH_HAVE_NETGEN 90 #include "netgen/nglib/nglib.h" 96 #if defined(LIBMESH_HAVE_MPI) && defined(LIBMESH_HAVE_VTK) 97 #include "libmesh/ignore_warnings.h" 98 # include "vtkMPIController.h" 99 #include "libmesh/restore_warnings.h" 108 std::unique_ptr<GetPot> command_line;
110 std::set<std::string> command_line_name_set;
112 std::unique_ptr<std::ofstream> _ofstream;
116 std::streambuf * out_buf (
nullptr);
117 std::streambuf * err_buf (
nullptr);
119 std::unique_ptr<libMesh::Threads::task_scheduler_init> task_scheduler;
120 #if defined(LIBMESH_HAVE_PETSC) 121 bool libmesh_initialized_petsc =
false;
123 #if defined(LIBMESH_HAVE_SLEPC) 124 bool libmesh_initialized_slepc =
false;
132 #if LIBMESH_HAVE_DECL_SIGACTION 133 void libmesh_handleFPE(
int , siginfo_t *
info,
void * )
137 switch (
info->si_code)
139 case FPE_INTDIV:
libMesh::err <<
"integer divide by zero";
break;
140 case FPE_INTOVF:
libMesh::err <<
"integer overflow";
break;
141 case FPE_FLTDIV:
libMesh::err <<
"floating point divide by zero";
break;
142 case FPE_FLTOVF:
libMesh::err <<
"floating point overflow";
break;
143 case FPE_FLTUND:
libMesh::err <<
"floating point underflow";
break;
144 case FPE_FLTRES:
libMesh::err <<
"floating point inexact result";
break;
145 case FPE_FLTINV:
libMesh::err <<
"invalid floating point operation";
break;
146 case FPE_FLTSUB:
libMesh::err <<
"subscript out of range";
break;
151 libmesh_error_msg(
"\nTo track this down, compile in debug mode, then in gdb do:\n" \
152 <<
" break libmesh_handleFPE\n" \
158 void libmesh_handleSEGV(
int , siginfo_t *
info,
void * )
161 libMesh::err <<
"Segmentation fault exception signaled (";
162 switch (
info->si_code)
164 case SEGV_MAPERR:
libMesh::err <<
"Address not mapped";
break;
165 case SEGV_ACCERR:
libMesh::err <<
"Invalid permissions";
break;
170 libmesh_error_msg(
"\nTo track this down, compile in debug mode, then in gdb do:\n" \
171 <<
" break libmesh_handleSEGV\n" \
180 #ifdef LIBMESH_HAVE_MPI 183 libmesh_not_implemented();
198 namespace libMeshPrivateData {
214 #ifdef LIBMESH_HAVE_MPI 226 #ifdef LIBMESH_ENABLE_PERFORMANCE_LOGGING
234 #ifdef LIBMESH_USE_COMPLEX_NUMBERS 250 #ifdef LIBMESH_HAVE_MPI 259 #if defined(LIBMESH_HAVE_PETSC) // PETSc is the default 261 #elif defined(LIBMESH_TRILINOS_HAVE_AZTECOO) // Use Trilinos if PETSc isn't there 263 #elif defined(LIBMESH_HAVE_EIGEN) // Use Eigen if neither are there 265 #elif defined(LIBMESH_HAVE_LASPACK) // Use LASPACK as a last resort 267 #else // No valid linear solver package at compile time 289 #ifdef LIBMESH_ENABLE_EXCEPTIONS 295 #ifdef LIBMESH_ENABLE_EXCEPTIONS 299 std::exception_ptr ex = std::current_exception();
304 std::rethrow_exception(ex);
306 catch (
const std::exception & std_ex)
349 #if defined(LIBMESH_HAVE_MPI) 351 MPI_Initialized (&mpi_initialized);
357 #ifdef LIBMESH_ENABLE_EXCEPTIONS 376 command_line = std::make_unique<GetPot>(argc, argv);
384 auto check_empty_command_line_value = [](
auto & cl,
const std::string & option) {
385 libmesh_error_msg_if(cl.search(option),
386 "Detected option " << option <<
" with no value. Did you forget '='?");
395 std::vector<std::string> n_threads_opt(2);
396 n_threads_opt[0] =
"--n_threads";
397 n_threads_opt[1] =
"--n-threads";
403 for (
auto & option : n_threads_opt)
404 check_empty_command_line_value(*command_line, option);
410 #if !LIBMESH_USING_THREADS 414 libmesh_warning(
"Warning: You requested --n-threads>1 but no threading model is active!\n" 415 <<
"Forcing --n-threads==1 instead!");
420 #ifdef LIBMESH_HAVE_OPENMP 424 task_scheduler = std::make_unique<Threads::task_scheduler_init>(
libMesh::n_threads());
435 const bool handle_mpi_errors =
false;
437 #if defined(LIBMESH_HAVE_MPI) 442 int mpi_thread_request = using_threads;
444 if (mpi_thread_type.empty())
446 check_empty_command_line_value(*command_line,
"--mpi-thread-type");
447 #if defined(PETSC_HAVE_STRUMPACK) && defined(PETSC_HAVE_SLATE) 454 mpi_thread_request = 3;
459 if (mpi_thread_type ==
"single")
462 libmesh_error_msg(
"We are using threads, so we require more mpi thread support " 463 "than '--mpi-thread-type=single'");
464 mpi_thread_request = 0;
466 else if (mpi_thread_type ==
"funneled")
467 mpi_thread_request = 1;
468 else if (mpi_thread_type ==
"serialized")
469 mpi_thread_request = 2;
470 else if (mpi_thread_type ==
"multiple")
471 mpi_thread_request = 3;
474 "Unsupported mpi thread type '" 476 <<
"'. Allowed options are 'single', 'funneled', 'serialized', and 'multiple'");
481 handle_mpi_errors, COMM_WORLD_IN);
484 const std::string timpi_sync =
494 cast_int<processor_id_type>(this->
comm().
rank());
496 cast_int<processor_id_type>(this->
comm().
size());
518 libmesh_parallel_only(this->
comm());
528 #if defined(LIBMESH_HAVE_PETSC) 533 #if defined(LIBMESH_HAVE_MPI) 541 #ifdef LIBMESH_HAVE_MPI 545 this->
_comm->
get() = PETSC_COMM_SELF;
550 PetscBool petsc_already_initialized;
552 if (petsc_already_initialized != PETSC_TRUE)
553 libmesh_initialized_petsc =
true;
554 # if defined(LIBMESH_HAVE_SLEPC) 561 if (!SlepcInitializeCalled)
564 libmesh_initialized_slepc =
true;
567 if (libmesh_initialized_petsc)
575 #ifdef LIBMESH_HAVE_NETGEN 579 #if defined(LIBMESH_HAVE_MPI) && defined(LIBMESH_HAVE_VTK) 595 command_line = std::make_unique<GetPot>(argc, argv);
603 std::ios::sync_with_stdio(
false);
614 std::ostream * newout =
new std::ostream(std::cout.rdbuf());
616 std::ostream * newerr =
new std::ostream(std::cerr.rdbuf());
627 if (cmdline_has_redirect_stdout)
628 libmesh_warning(
"The --redirect-stdout command line option has been deprecated. " 629 "Use '--redirect-output basename' instead.");
635 if (cmdline_has_redirect_stdout || cmdline_has_redirect_output)
637 std::string basename =
"stdout";
640 if (cmdline_has_redirect_output)
643 command_line->search(1,
"--redirect-output");
646 std::string next_string =
"";
647 next_string = command_line->next(next_string);
652 if (next_string.size() > 0 && next_string.find_first_of(
"-") != 0)
653 basename = next_string;
656 std::ostringstream filename;
658 _ofstream = std::make_unique<std::ofstream>(filename.str().c_str());
685 #ifdef LIBMESH_ENABLE_EXCEPTIONS 698 #if defined(LIBMESH_HAVE_HDF5) && !defined(_MSC_VER) 711 setenv(
"HDF5_USE_FILE_LOCKING",
"FALSE", 0);
712 #endif // LIBMESH_HAVE_HDF5 747 task_scheduler.reset();
764 #if !defined(LIBMESH_ENABLE_REFERENCE_COUNTING) || defined(NDEBUG) 766 libMesh::err <<
"Compile in DEBUG mode with --enable-reference-counting" 768 <<
"for more information" 808 #ifdef LIBMESH_ENABLE_EXCEPTIONS 814 #ifdef LIBMESH_HAVE_NETGEN 821 #if defined(LIBMESH_HAVE_PETSC) 826 for (
const auto &
name : cli_names)
827 if (!
name.empty() &&
name[0] ==
'-')
832 PetscBool used = PETSC_FALSE;
833 auto ierr = PetscOptionsUsed(NULL,
name.c_str(), &used);
835 if (used == PETSC_FALSE)
837 ierr = PetscOptionsClearValue(NULL,
name.c_str());
844 #
if defined(LIBMESH_HAVE_MPI)
849 PetscErrorCode ierr = LIBMESH_PETSC_SUCCESS;
850 # if defined(LIBMESH_HAVE_SLEPC) 851 if (libmesh_initialized_slepc)
852 ierr = SlepcFinalize();
854 if (libmesh_initialized_petsc)
855 ierr = PetscFinalize();
861 #if defined(LIBMESH_HAVE_MPI) && defined(LIBMESH_HAVE_VTK) 868 #if defined(LIBMESH_HAVE_MPI) 886 #if !defined(LIBMESH_HAVE_FEENABLEEXCEPT) && defined(LIBMESH_HAVE_XMMINTRIN_H) 887 static int flags = 0;
892 #ifdef LIBMESH_HAVE_FEENABLEEXCEPT 893 feenableexcept(FE_DIVBYZERO | FE_INVALID);
894 #elif LIBMESH_HAVE_XMMINTRIN_H 895 flags = _MM_GET_EXCEPTION_MASK();
896 _MM_SET_EXCEPTION_MASK(flags & ~_MM_MASK_INVALID);
899 #if LIBMESH_HAVE_DECL_SIGACTION 900 struct sigaction new_action, old_action;
903 new_action.sa_sigaction = libmesh_handleFPE;
904 sigemptyset (&new_action.sa_mask);
905 new_action.sa_flags = SA_SIGINFO;
907 sigaction (SIGFPE,
nullptr, &old_action);
908 if (old_action.sa_handler != SIG_IGN)
909 sigaction (SIGFPE, &new_action,
nullptr);
914 #ifdef LIBMESH_HAVE_FEDISABLEEXCEPT 915 fedisableexcept(FE_DIVBYZERO | FE_INVALID);
916 #elif LIBMESH_HAVE_XMMINTRIN_H 917 _MM_SET_EXCEPTION_MASK(flags);
919 signal(SIGFPE, SIG_DFL);
928 #if LIBMESH_HAVE_DECL_SIGACTION 929 static struct sigaction old_action;
930 static bool was_on =
false;
934 struct sigaction new_action;
938 new_action.sa_sigaction = libmesh_handleSEGV;
939 sigemptyset (&new_action.sa_mask);
940 new_action.sa_flags = SA_SIGINFO;
942 sigaction (SIGSEGV, &new_action, &old_action);
947 sigaction (SIGSEGV, &old_action,
nullptr);
950 libmesh_error_msg(
"System call sigaction not supported.");
961 static std::mutex command_line_names_mutex;
962 std::scoped_lock lock(command_line_names_mutex);
964 command_line_name_set.insert(
name);
971 for (
auto & getter : {&GetPot::get_requested_arguments,
972 &GetPot::get_requested_variables,
973 &GetPot::get_requested_sections})
974 for (
const std::string &
name : (getpot.*getter)())
981 return std::vector<std::string>(command_line_name_set.begin(),
982 command_line_name_set.end());
993 if (!command_line.get())
999 bool found_it = command_line->search(arg);
1004 std::replace(arg.begin(), arg.end(),
'_',
'-');
1005 found_it = command_line->search(arg);
1011 auto name_begin = arg.begin();
1012 while (*name_begin ==
'-')
1014 std::replace(name_begin, arg.end(),
'-',
'_');
1015 found_it = command_line->search(arg);
1023 template <
typename T>
1030 if (command_line->have_variable(
name))
1038 const std::string stringvalue =
1039 (*command_line)(
name, std::string());
1046 template <
typename T>
1053 for (
const auto & entry : names)
1059 const std::string stringvalue =
1060 (*command_line)(entry, std::string());
1065 for (
const auto & entry : names)
1066 if (command_line->have_variable(entry))
1077 template <
typename T>
1089 return command_line->next(
value);
1096 template <
typename T>
1106 if (command_line->have_variable(
name))
1108 unsigned size = command_line->vector_variable_size(
name);
1111 for (
unsigned i=0; i<size; ++i)
1112 vec[i] = (*command_line)(
name, vec[i], i);
1121 static bool called =
false;
1129 #ifdef LIBMESH_HAVE_PETSC 1134 #ifdef LIBMESH_TRILINOS_HAVE_AZTECOO 1140 #ifdef LIBMESH_HAVE_EIGEN 1142 #
if defined(LIBMESH_HAVE_MPI)
1151 #ifdef LIBMESH_HAVE_LASPACK 1153 #
if defined(LIBMESH_HAVE_MPI)
1166 #
if defined(LIBMESH_HAVE_MPI)
1190 template LIBMESH_EXPORT std::string command_line_value<std::string> (
const std::string &, std::string);
1201 template LIBMESH_EXPORT std::string command_line_value<std::string> (
const std::vector<std::string> &, std::string);
1212 template LIBMESH_EXPORT std::string command_line_next<std::string> (std::string, std::string);
1224 #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)
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.
static unsigned int n_objects()
Prints the number of outstanding (created, but not yet destroyed) objects.
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 &...)
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)
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 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