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/auto_ptr.h"
41 #ifdef LIBMESH_ENABLE_EXCEPTIONS
45 #ifdef LIBMESH_HAVE_OPENMP
53 #ifdef LIBMESH_HAVE_FENV_H
56 #ifdef LIBMESH_HAVE_XMMINTRIN_H
57 # include <xmmintrin.h>
61 #if defined(LIBMESH_HAVE_MPI)
62 # include "libmesh/ignore_warnings.h"
64 # include "libmesh/restore_warnings.h"
65 #endif // #if defined(LIBMESH_HAVE_MPI)
67 #if defined(LIBMESH_HAVE_PETSC)
68 # include "libmesh/petsc_macro.h"
70 # include <petscerror.h>
71 #if !PETSC_RELEASE_LESS_THAN(3,3,0)
72 #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)
85 #if defined(LIBMESH_HAVE_MPI) && defined(LIBMESH_HAVE_VTK)
86 #include "libmesh/ignore_warnings.h"
87 # include "vtkMPIController.h"
88 #include "libmesh/restore_warnings.h"
95 std::unique_ptr<GetPot> command_line;
96 std::unique_ptr<std::ofstream> _ofstream;
100 std::streambuf * out_buf (
nullptr);
101 std::streambuf * err_buf (
nullptr);
103 std::unique_ptr<libMesh::Threads::task_scheduler_init> task_scheduler;
104 #if defined(LIBMESH_HAVE_MPI)
105 bool libmesh_initialized_mpi =
false;
107 #if defined(LIBMESH_HAVE_PETSC)
108 bool libmesh_initialized_petsc =
false;
110 #if defined(LIBMESH_HAVE_SLEPC)
111 bool libmesh_initialized_slepc =
false;
119 #if LIBMESH_HAVE_DECL_SIGACTION
120 void libmesh_handleFPE(
int , siginfo_t * info,
void * )
124 switch (info->si_code)
126 case FPE_INTDIV:
libMesh::err <<
"integer divide by zero";
break;
127 case FPE_INTOVF:
libMesh::err <<
"integer overflow";
break;
128 case FPE_FLTDIV:
libMesh::err <<
"floating point divide by zero";
break;
129 case FPE_FLTOVF:
libMesh::err <<
"floating point overflow";
break;
130 case FPE_FLTUND:
libMesh::err <<
"floating point underflow";
break;
131 case FPE_FLTRES:
libMesh::err <<
"floating point inexact result";
break;
132 case FPE_FLTINV:
libMesh::err <<
"invalid floating point operation";
break;
133 case FPE_FLTSUB:
libMesh::err <<
"subscript out of range";
break;
138 libmesh_error_msg(
"\nTo track this down, compile in debug mode, then in gdb do:\n" \
139 <<
" break libmesh_handleFPE\n" \
145 void libmesh_handleSEGV(
int , siginfo_t * info,
void * )
148 libMesh::err <<
"Segmentation fault exception signaled (";
149 switch (info->si_code)
151 case SEGV_MAPERR:
libMesh::err <<
"Address not mapped";
break;
152 case SEGV_ACCERR:
libMesh::err <<
"Invalid permissions";
break;
157 libmesh_error_msg(
"\nTo track this down, compile in debug mode, then in gdb do:\n" \
158 <<
" break libmesh_handleSEGV\n" \
167 #ifdef LIBMESH_HAVE_MPI
170 libmesh_not_implemented();
185 namespace libMeshPrivateData {
201 #ifdef LIBMESH_HAVE_MPI
213 #ifdef LIBMESH_ENABLE_PERFORMANCE_LOGGING
223 #ifdef LIBMESH_USE_COMPLEX_NUMBERS
239 #ifdef LIBMESH_HAVE_MPI
248 #if defined(LIBMESH_HAVE_PETSC) // PETSc is the default
250 #elif defined(LIBMESH_TRILINOS_HAVE_AZTECOO) // Use Trilinos if PETSc isn't there
252 #elif defined(LIBMESH_HAVE_EIGEN) // Use Eigen if neither are there
254 #elif defined(LIBMESH_HAVE_LASPACK) // Use LASPACK as a last resort
256 #else // No valid linear solver package at compile time
278 #ifdef LIBMESH_ENABLE_EXCEPTIONS
318 #if defined(LIBMESH_HAVE_MPI)
320 MPI_Initialized (&mpi_initialized);
335 #ifndef LIBMESH_HAVE_MPI
339 MPI_Comm COMM_WORLD_IN)
346 command_line = libmesh_make_unique<GetPot>(argc, argv);
369 if (command_line->search(option))
370 libmesh_error_msg(
"Detected option " << option <<
371 " with no value. Did you forget '='?");
377 #if !LIBMESH_USING_THREADS
381 libmesh_warning(
"Warning: You requested --n-threads>1 but no threading model is active!\n"
382 <<
"Forcing --n-threads==1 instead!");
387 #ifdef LIBMESH_HAVE_OPENMP
391 task_scheduler = libmesh_make_unique<Threads::task_scheduler_init>(
libMesh::n_threads());
401 #if defined(LIBMESH_HAVE_MPI)
409 timpi_call_mpi(MPI_Initialized (&flag));
413 int mpi_thread_provided;
415 MPI_THREAD_FUNNELED :
419 (MPI_Init_thread (&argc, const_cast<char ***>(&argv),
420 mpi_thread_requested, &mpi_thread_provided));
423 (mpi_thread_provided < MPI_THREAD_FUNNELED))
425 libmesh_warning(
"Warning: MPI failed to guarantee MPI_THREAD_FUNNELED\n"
426 <<
"for a threaded run.\n"
427 <<
"Be sure your library is funneled-thread-safe..."
443 libmesh_initialized_mpi =
true;
449 this->_comm =
new Parallel::Communicator(COMM_WORLD_IN);
457 cast_int<processor_id_type>(this->comm().rank());
459 cast_int<processor_id_type>(this->comm().size());
481 libmesh_parallel_only(this->comm());
484 this->_comm =
new Parallel::Communicator();
487 #if defined(LIBMESH_HAVE_PETSC)
492 #
if defined(LIBMESH_HAVE_MPI)
507 ierr = PetscInitialized(&petsc_already_initialized);
509 if (petsc_already_initialized != PETSC_TRUE)
510 libmesh_initialized_petsc =
true;
511 # if defined(LIBMESH_HAVE_SLEPC)
518 if (!SlepcInitializeCalled)
520 ierr = SlepcInitialize (&argc, const_cast<char ***>(&argv),
nullptr,
nullptr);
522 libmesh_initialized_slepc =
true;
525 if (libmesh_initialized_petsc)
527 ierr = PetscInitialize (&argc, const_cast<char ***>(&argv),
nullptr,
nullptr);
531 #if !PETSC_RELEASE_LESS_THAN(3,3,0)
533 #if PETSC_RELEASE_LESS_THAN(3,4,0)
543 #if defined(LIBMESH_HAVE_MPI) && defined(LIBMESH_HAVE_VTK)
545 _vtk_mpi_controller = vtkMPIController::New();
546 _vtk_mpi_controller->Initialize(&argc, const_cast<char ***>(&argv), 1);
547 _vtk_mpi_controller->SetGlobalController(_vtk_mpi_controller);
559 command_line = libmesh_make_unique<GetPot>(argc, argv);
567 std::ios::sync_with_stdio(
false);
578 std::ostream * newout =
new std::ostream(std::cout.rdbuf());
580 std::ostream * newerr =
new std::ostream(std::cerr.rdbuf());
591 if (cmdline_has_redirect_stdout)
592 libmesh_warning(
"The --redirect-stdout command line option has been deprecated. "
593 "Use '--redirect-output basename' instead.");
599 if (cmdline_has_redirect_stdout || cmdline_has_redirect_output)
601 std::string basename =
"stdout";
604 if (cmdline_has_redirect_output)
607 command_line->search(1,
"--redirect-output");
610 std::string next_string =
"";
611 next_string = command_line->next(next_string);
616 if (next_string.size() > 0 && next_string.find_first_of(
"-") != 0)
617 basename = next_string;
620 std::ostringstream filename;
622 _ofstream = libmesh_make_unique<std::ofstream>(filename.str().c_str());
649 #ifdef LIBMESH_ENABLE_EXCEPTIONS
685 this->
comm().barrier();
695 task_scheduler.reset();
712 #if !defined(LIBMESH_ENABLE_REFERENCE_COUNTING) || defined(NDEBUG)
714 libMesh::err <<
"Compile in DEBUG mode with --enable-reference-counting"
716 <<
"for more information"
756 #ifdef LIBMESH_ENABLE_EXCEPTIONS
766 #if defined(LIBMESH_HAVE_PETSC)
769 #
if defined(LIBMESH_HAVE_MPI)
774 # if defined(LIBMESH_HAVE_SLEPC)
775 if (libmesh_initialized_slepc)
778 if (libmesh_initialized_petsc)
784 #if defined(LIBMESH_HAVE_MPI) && defined(LIBMESH_HAVE_VTK)
789 #if defined(LIBMESH_HAVE_MPI)
793 this->
comm().clear();
796 if (libmesh_initialized_mpi)
800 unsigned int error_code = MPI_Finalize();
801 if (error_code != MPI_SUCCESS)
803 char error_string[MPI_MAX_ERROR_STRING+1];
804 int error_string_len;
805 MPI_Error_string(error_code, error_string,
807 std::cerr <<
"Failure from MPI_Finalize():\n"
808 << error_string << std::endl;
824 #if !defined(LIBMESH_HAVE_FEENABLEEXCEPT) && defined(LIBMESH_HAVE_XMMINTRIN_H) && !defined(__SUNPRO_CC)
825 static int flags = 0;
830 #ifdef LIBMESH_HAVE_FEENABLEEXCEPT
831 feenableexcept(FE_DIVBYZERO | FE_INVALID);
832 #elif LIBMESH_HAVE_XMMINTRIN_H
834 flags = _MM_GET_EXCEPTION_MASK();
835 _MM_SET_EXCEPTION_MASK(flags & ~_MM_MASK_INVALID);
839 #if LIBMESH_HAVE_DECL_SIGACTION
840 struct sigaction new_action, old_action;
843 new_action.sa_sigaction = libmesh_handleFPE;
844 sigemptyset (&new_action.sa_mask);
845 new_action.sa_flags = SA_SIGINFO;
847 sigaction (SIGFPE,
nullptr, &old_action);
848 if (old_action.sa_handler != SIG_IGN)
849 sigaction (SIGFPE, &new_action,
nullptr);
854 #ifdef LIBMESH_HAVE_FEDISABLEEXCEPT
855 fedisableexcept(FE_DIVBYZERO | FE_INVALID);
856 #elif LIBMESH_HAVE_XMMINTRIN_H
858 _MM_SET_EXCEPTION_MASK(flags);
861 signal(SIGFPE, SIG_DFL);
870 #if LIBMESH_HAVE_DECL_SIGACTION
871 static struct sigaction old_action;
872 static bool was_on =
false;
876 struct sigaction new_action;
880 new_action.sa_sigaction = libmesh_handleSEGV;
881 sigemptyset (&new_action.sa_mask);
882 new_action.sa_flags = SA_SIGINFO;
884 sigaction (SIGSEGV, &new_action, &old_action);
889 sigaction (SIGSEGV, &old_action,
nullptr);
892 libmesh_error_msg(
"System call sigaction not supported.");
906 bool found_it = command_line->search(arg);
911 std::replace(arg.begin(), arg.end(),
'_',
'-');
912 found_it = command_line->search(arg);
918 auto name_begin = arg.begin();
919 while (*name_begin ==
'-')
921 std::replace(name_begin, arg.end(),
'-',
'_');
922 found_it = command_line->search(arg);
930 template <
typename T>
937 if (command_line->have_variable(
name))
943 template <
typename T>
950 for (
const auto & entry :
name)
951 if (command_line->have_variable(entry))
962 template <
typename T>
968 return command_line->next(
value);
975 template <
typename T>
982 if (command_line->have_variable(
name))
984 unsigned size = command_line->vector_variable_size(
name);
987 for (
unsigned i=0; i<size; ++i)
988 vec[i] = (*command_line)(
name, vec[i], i);
997 static bool called =
false;
1005 #ifdef LIBMESH_HAVE_PETSC
1010 #ifdef LIBMESH_TRILINOS_HAVE_AZTECOO
1016 #ifdef LIBMESH_HAVE_EIGEN
1018 #
if defined(LIBMESH_HAVE_MPI)
1027 #ifdef LIBMESH_HAVE_LASPACK
1029 #
if defined(LIBMESH_HAVE_MPI)
1042 #
if defined(LIBMESH_HAVE_MPI)
1066 template std::string command_line_value<std::string> (
const std::string &, std::string);
1077 template std::string command_line_value<std::string> (
const std::vector<std::string> &, std::string);
1088 template std::string command_line_next<std::string> (std::string, std::string);
1100 #ifdef LIBMESH_DEFAULT_QUADRUPLE_PRECISION