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"
34 #include "timpi/communicator.h"
35 #include "timpi/timpi_init.h"
41 #ifdef LIBMESH_ENABLE_EXCEPTIONS
45 #ifdef LIBMESH_HAVE_OPENMP
54 #ifdef LIBMESH_HAVE_FENV_H
57 #ifdef LIBMESH_HAVE_XMMINTRIN_H
58 # include <xmmintrin.h>
62 #if defined(LIBMESH_HAVE_MPI)
63 # include "libmesh/ignore_warnings.h"
65 # include "libmesh/restore_warnings.h"
66 #endif // #if defined(LIBMESH_HAVE_MPI)
68 #if defined(LIBMESH_HAVE_PETSC)
69 # include "libmesh/petsc_macro.h"
71 # include <petscerror.h>
72 # include "libmesh/petscdmlibmesh.h"
73 # if defined(LIBMESH_HAVE_SLEPC)
75 # include "libmesh/ignore_warnings.h"
76 # include "libmesh/slepc_macro.h"
78 # include "libmesh/restore_warnings.h"
79 # endif // #if defined(LIBMESH_HAVE_SLEPC)
80 #endif // #if defined(LIBMESH_HAVE_PETSC)
84 #if defined(LIBMESH_HAVE_MPI) && defined(LIBMESH_HAVE_VTK)
85 #include "libmesh/ignore_warnings.h"
86 # include "vtkMPIController.h"
87 #include "libmesh/restore_warnings.h"
94 std::unique_ptr<GetPot> command_line;
95 std::unique_ptr<std::ofstream> _ofstream;
99 std::streambuf * out_buf (
nullptr);
100 std::streambuf * err_buf (
nullptr);
102 std::unique_ptr<libMesh::Threads::task_scheduler_init> task_scheduler;
103 #if defined(LIBMESH_HAVE_PETSC)
104 bool libmesh_initialized_petsc =
false;
106 #if defined(LIBMESH_HAVE_SLEPC)
107 bool libmesh_initialized_slepc =
false;
115 #if LIBMESH_HAVE_DECL_SIGACTION
116 void libmesh_handleFPE(
int , siginfo_t * info,
void * )
120 switch (info->si_code)
122 case FPE_INTDIV:
libMesh::err <<
"integer divide by zero";
break;
123 case FPE_INTOVF:
libMesh::err <<
"integer overflow";
break;
124 case FPE_FLTDIV:
libMesh::err <<
"floating point divide by zero";
break;
125 case FPE_FLTOVF:
libMesh::err <<
"floating point overflow";
break;
126 case FPE_FLTUND:
libMesh::err <<
"floating point underflow";
break;
127 case FPE_FLTRES:
libMesh::err <<
"floating point inexact result";
break;
128 case FPE_FLTINV:
libMesh::err <<
"invalid floating point operation";
break;
129 case FPE_FLTSUB:
libMesh::err <<
"subscript out of range";
break;
134 libmesh_error_msg(
"\nTo track this down, compile in debug mode, then in gdb do:\n" \
135 <<
" break libmesh_handleFPE\n" \
141 void libmesh_handleSEGV(
int , siginfo_t * info,
void * )
144 libMesh::err <<
"Segmentation fault exception signaled (";
145 switch (info->si_code)
147 case SEGV_MAPERR:
libMesh::err <<
"Address not mapped";
break;
148 case SEGV_ACCERR:
libMesh::err <<
"Invalid permissions";
break;
153 libmesh_error_msg(
"\nTo track this down, compile in debug mode, then in gdb do:\n" \
154 <<
" break libmesh_handleSEGV\n" \
163 #ifdef LIBMESH_HAVE_MPI
166 libmesh_not_implemented();
181 namespace libMeshPrivateData {
197 #ifdef LIBMESH_HAVE_MPI
203 OStreamProxy
out(std::cout);
204 OStreamProxy
err(std::cerr);
209 #ifdef LIBMESH_ENABLE_PERFORMANCE_LOGGING
219 #ifdef LIBMESH_USE_COMPLEX_NUMBERS
235 #ifdef LIBMESH_HAVE_MPI
244 #if defined(LIBMESH_HAVE_PETSC) // PETSc is the default
246 #elif defined(LIBMESH_TRILINOS_HAVE_AZTECOO) // Use Trilinos if PETSc isn't there
248 #elif defined(LIBMESH_HAVE_EIGEN) // Use Eigen if neither are there
250 #elif defined(LIBMESH_HAVE_LASPACK) // Use LASPACK as a last resort
252 #else // No valid linear solver package at compile time
274 #ifdef LIBMESH_ENABLE_EXCEPTIONS
282 std::exception_ptr ex = std::current_exception();
287 std::rethrow_exception(ex);
289 catch (
const std::exception & std_ex)
331 #if defined(LIBMESH_HAVE_MPI)
333 MPI_Initialized (&mpi_initialized);
348 TIMPI::communicator COMM_WORLD_IN,
int n_threads)
354 command_line = std::make_unique<GetPot>(argc, argv);
368 std::vector<std::string> n_threads_opt(2);
369 n_threads_opt[0] =
"--n_threads";
370 n_threads_opt[1] =
"--n-threads";
376 for (
auto & option : n_threads_opt)
377 libmesh_error_msg_if(command_line->search(option),
378 "Detected option " << option <<
379 " with no value. Did you forget '='?");
385 #if !LIBMESH_USING_THREADS
389 libmesh_warning(
"Warning: You requested --n-threads>1 but no threading model is active!\n"
390 <<
"Forcing --n-threads==1 instead!");
395 #ifdef LIBMESH_HAVE_OPENMP
399 task_scheduler = std::make_unique<Threads::task_scheduler_init>(
libMesh::n_threads());
407 libmesh_assert(remote_elem);
410 const bool handle_mpi_errors =
false;
412 #if defined(LIBMESH_HAVE_MPI)
418 new TIMPI::TIMPIInit(argc, argv, using_threads,
419 handle_mpi_errors, COMM_WORLD_IN);
422 const std::string timpi_sync =
424 _comm->sync_type(timpi_sync);
432 cast_int<processor_id_type>(this->
comm().rank());
434 cast_int<processor_id_type>(this->
comm().size());
450 libmesh_assert_greater (libMeshPrivateData::_n_processors, 0);
456 libmesh_parallel_only(this->
comm());
461 new TIMPI::TIMPIInit(argc, argv, using_threads,
466 #if defined(LIBMESH_HAVE_PETSC)
471 #if defined(LIBMESH_HAVE_MPI)
481 #ifdef LIBMESH_HAVE_MPI
485 this->
_comm->get() = PETSC_COMM_SELF;
490 PetscBool petsc_already_initialized;
491 ierr = PetscInitialized(&petsc_already_initialized);
493 if (petsc_already_initialized != PETSC_TRUE)
494 libmesh_initialized_petsc =
true;
495 # if defined(LIBMESH_HAVE_SLEPC)
502 if (!SlepcInitializeCalled)
504 ierr = SlepcInitialize (&argc, const_cast<char ***>(&argv),
nullptr,
nullptr);
506 libmesh_initialized_slepc =
true;
509 if (libmesh_initialized_petsc)
511 ierr = PetscInitialize (&argc, const_cast<char ***>(&argv),
nullptr,
nullptr);
520 #if defined(LIBMESH_HAVE_MPI) && defined(LIBMESH_HAVE_VTK)
536 command_line = std::make_unique<GetPot>(argc, argv);
544 std::ios::sync_with_stdio(
false);
555 std::ostream * newout =
new std::ostream(std::cout.rdbuf());
557 std::ostream * newerr =
new std::ostream(std::cerr.rdbuf());
568 if (cmdline_has_redirect_stdout)
569 libmesh_warning(
"The --redirect-stdout command line option has been deprecated. "
570 "Use '--redirect-output basename' instead.");
576 if (cmdline_has_redirect_stdout || cmdline_has_redirect_output)
578 std::string basename =
"stdout";
581 if (cmdline_has_redirect_output)
584 command_line->search(1,
"--redirect-output");
587 std::string next_string =
"";
588 next_string = command_line->next(next_string);
593 if (next_string.size() > 0 && next_string.find_first_of(
"-") != 0)
594 basename = next_string;
597 std::ostringstream filename;
599 _ofstream = std::make_unique<std::ofstream>(filename.str().c_str());
626 #ifdef LIBMESH_ENABLE_EXCEPTIONS
639 #if defined(LIBMESH_HAVE_HDF5) && !defined(_MSC_VER)
652 setenv(
"HDF5_USE_FILE_LOCKING",
"FALSE", 0);
653 #endif // LIBMESH_HAVE_HDF5
678 this->
comm().barrier();
688 task_scheduler.reset();
705 #if !defined(LIBMESH_ENABLE_REFERENCE_COUNTING) || defined(NDEBUG)
707 libMesh::err <<
"Compile in DEBUG mode with --enable-reference-counting"
709 <<
"for more information"
749 #ifdef LIBMESH_ENABLE_EXCEPTIONS
759 #if defined(LIBMESH_HAVE_PETSC)
762 #
if defined(LIBMESH_HAVE_MPI)
767 # if defined(LIBMESH_HAVE_SLEPC)
768 if (libmesh_initialized_slepc)
771 if (libmesh_initialized_petsc)
777 #if defined(LIBMESH_HAVE_MPI) && defined(LIBMESH_HAVE_VTK)
784 #if defined(LIBMESH_HAVE_MPI)
802 #if !defined(LIBMESH_HAVE_FEENABLEEXCEPT) && defined(LIBMESH_HAVE_XMMINTRIN_H)
803 static int flags = 0;
808 #ifdef LIBMESH_HAVE_FEENABLEEXCEPT
809 feenableexcept(FE_DIVBYZERO | FE_INVALID);
810 #elif LIBMESH_HAVE_XMMINTRIN_H
811 flags = _MM_GET_EXCEPTION_MASK();
812 _MM_SET_EXCEPTION_MASK(flags & ~_MM_MASK_INVALID);
815 #if LIBMESH_HAVE_DECL_SIGACTION
816 struct sigaction new_action, old_action;
819 new_action.sa_sigaction = libmesh_handleFPE;
820 sigemptyset (&new_action.sa_mask);
821 new_action.sa_flags = SA_SIGINFO;
823 sigaction (SIGFPE,
nullptr, &old_action);
824 if (old_action.sa_handler != SIG_IGN)
825 sigaction (SIGFPE, &new_action,
nullptr);
830 #ifdef LIBMESH_HAVE_FEDISABLEEXCEPT
831 fedisableexcept(FE_DIVBYZERO | FE_INVALID);
832 #elif LIBMESH_HAVE_XMMINTRIN_H
833 _MM_SET_EXCEPTION_MASK(flags);
835 signal(SIGFPE, SIG_DFL);
844 #if LIBMESH_HAVE_DECL_SIGACTION
845 static struct sigaction old_action;
846 static bool was_on =
false;
850 struct sigaction new_action;
854 new_action.sa_sigaction = libmesh_handleSEGV;
855 sigemptyset (&new_action.sa_mask);
856 new_action.sa_flags = SA_SIGINFO;
858 sigaction (SIGSEGV, &new_action, &old_action);
863 sigaction (SIGSEGV, &old_action,
nullptr);
866 libmesh_error_msg(
"System call sigaction not supported.");
875 libmesh_assert(command_line.get());
878 libmesh_assert(!arg.empty());
880 bool found_it = command_line->search(arg);
885 std::replace(arg.begin(), arg.end(),
'_',
'-');
886 found_it = command_line->search(arg);
892 auto name_begin = arg.begin();
893 while (*name_begin ==
'-')
895 std::replace(name_begin, arg.end(),
'-',
'_');
896 found_it = command_line->search(arg);
904 template <
typename T>
908 libmesh_assert(command_line.get());
911 if (command_line->have_variable(name))
912 value = (*command_line)(name, value);
917 template <
typename T>
921 libmesh_assert(command_line.get());
924 for (
const auto & entry : name)
925 if (command_line->have_variable(entry))
927 value = (*command_line)(entry, value);
936 template <
typename T>
942 return command_line->next(value);
949 template <
typename T>
953 libmesh_assert(command_line.get());
956 if (command_line->have_variable(name))
958 unsigned size = command_line->vector_variable_size(name);
961 for (
unsigned i=0; i<size; ++i)
962 vec[i] = (*command_line)(name, vec[i], i);
971 static bool called =
false;
979 #ifdef LIBMESH_HAVE_PETSC
984 #ifdef LIBMESH_TRILINOS_HAVE_AZTECOO
990 #ifdef LIBMESH_HAVE_EIGEN
992 #
if defined(LIBMESH_HAVE_MPI)
1001 #ifdef LIBMESH_HAVE_LASPACK
1003 #
if defined(LIBMESH_HAVE_MPI)
1016 #
if defined(LIBMESH_HAVE_MPI)
1040 template LIBMESH_EXPORT std::string command_line_value<std::string> (
const std::string &, std::string);
1051 template LIBMESH_EXPORT std::string command_line_value<std::string> (
const std::vector<std::string> &, std::string);
1062 template LIBMESH_EXPORT std::string command_line_next<std::string> (std::string, std::string);
1074 #ifdef LIBMESH_DEFAULT_QUADRUPLE_PRECISION
template LIBMESH_EXPORT Real command_line_value< Real >(const std::string &, Real)
template LIBMESH_EXPORT double command_line_value< double >(const std::string &, double)
T command_line_next(std::string name, T 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 > &)
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 > &)
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)
void write_traceout()
Writes a stack trace to a uniquely named file if –enable-tracefiles has been set by configure...
int _n_threads
Total number of threads possible.
vtkMPIController * _vtk_mpi_controller
static void setup()
Setup function.
uint8_t processor_id_type
const Number imaginary
The imaginary unit, .
SolverPackage default_solver_package()
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 &name, T value)
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)
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)
const Parallel::Communicator & comm() const
Returns a Communicator created from the TIMPIInit object we hold, which will be a compatibility shim ...
template LIBMESH_EXPORT short command_line_next< short >(std::string, short)
template LIBMESH_EXPORT unsigned short command_line_value< unsigned short >(const std::string &, unsigned short)
MPI_Errhandler libmesh_errhandler
TIMPI::TIMPIInit * _timpi_init
void enableFPE(bool on)
Toggle floating point exceptions – courtesy of Cody Permann & MOOSE team.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void command_line_vector(const std::string &name, std::vector< T > &vec)
PerfLog perflog
A PerfLog object to log performance.
processor_id_type global_processor_id()
bool initialized()
Checks that library initialization has been done.
void libMesh_MPI_Handler(MPI_Comm *, int *,...)
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)
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)
template LIBMESH_EXPORT void command_line_vector< Real >(const std::string &, std::vector< Real > &)
void libmesh_terminate_handler()
Parallel::Communicator * _comm