libmesh.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2018 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 // Local includes
20 #include "libmesh/libmesh.h"
21 #include "libmesh/getpot.h"
22 #include "libmesh/parallel.h"
25 #include "libmesh/remote_elem.h"
26 #include "libmesh/threads.h"
27 #include "libmesh/print_trace.h"
28 
29 
30 // C/C++ includes
31 #include <iostream>
32 #include <fstream>
33 
34 #ifdef LIBMESH_ENABLE_EXCEPTIONS
35 #include <exception>
36 #endif
37 
38 #ifdef LIBMESH_HAVE_OPENMP
39 #include <omp.h>
40 #endif
41 
42 #include "signal.h"
43 
44 
45 // floating-point exceptions
46 #ifdef LIBMESH_HAVE_FENV_H
47 # include <fenv.h>
48 #endif
49 #ifdef LIBMESH_HAVE_XMMINTRIN_H
50 # include <xmmintrin.h>
51 #endif
52 
53 
54 #if defined(LIBMESH_HAVE_MPI)
55 # include "libmesh/ignore_warnings.h"
56 # include <mpi.h>
58 #endif // #if defined(LIBMESH_HAVE_MPI)
59 
60 #if defined(LIBMESH_HAVE_PETSC)
61 # include "libmesh/petsc_macro.h"
62 # include <petsc.h>
63 # include <petscerror.h>
64 #if !PETSC_RELEASE_LESS_THAN(3,3,0)
65 #include "libmesh/petscdmlibmesh.h"
66 #endif
67 # if defined(LIBMESH_HAVE_SLEPC)
68 // Ignore unused variable warnings from SLEPc
69 # include "libmesh/ignore_warnings.h"
70 # include "libmesh/slepc_macro.h"
71 # include <slepc.h>
73 # endif // #if defined(LIBMESH_HAVE_SLEPC)
74 #endif // #if defined(LIBMESH_HAVE_PETSC)
75 
76 // If we're using MPI and VTK has been detected, we need to do some
77 // MPI initialize/finalize stuff for VTK.
78 #if defined(LIBMESH_HAVE_MPI) && defined(LIBMESH_HAVE_VTK)
80 # include "vtkMPIController.h"
82 #endif
83 
84 // --------------------------------------------------------
85 // Local anonymous namespace to hold miscellaneous bits
86 namespace {
87 
88 std::unique_ptr<GetPot> command_line;
89 std::unique_ptr<std::ofstream> _ofstream;
90 // If std::cout and std::cerr are redirected, we need to
91 // be a little careful and save the original streambuf objects,
92 // replacing them in the destructor before program termination.
93 std::streambuf * out_buf (libmesh_nullptr);
94 std::streambuf * err_buf (libmesh_nullptr);
95 
96 std::unique_ptr<libMesh::Threads::task_scheduler_init> task_scheduler;
97 #if defined(LIBMESH_HAVE_MPI)
98 bool libmesh_initialized_mpi = false;
99 #endif
100 #if defined(LIBMESH_HAVE_PETSC)
101 bool libmesh_initialized_petsc = false;
102 #endif
103 #if defined(LIBMESH_HAVE_SLEPC)
104 bool libmesh_initialized_slepc = false;
105 #endif
106 
107 
108 
112 #if LIBMESH_HAVE_DECL_SIGACTION
113 void libmesh_handleFPE(int /*signo*/, siginfo_t * info, void * /*context*/)
114 {
115  libMesh::err << std::endl;
116  libMesh::err << "Floating point exception signaled (";
117  switch (info->si_code)
118  {
119  case FPE_INTDIV: libMesh::err << "integer divide by zero"; break;
120  case FPE_INTOVF: libMesh::err << "integer overflow"; break;
121  case FPE_FLTDIV: libMesh::err << "floating point divide by zero"; break;
122  case FPE_FLTOVF: libMesh::err << "floating point overflow"; break;
123  case FPE_FLTUND: libMesh::err << "floating point underflow"; break;
124  case FPE_FLTRES: libMesh::err << "floating point inexact result"; break;
125  case FPE_FLTINV: libMesh::err << "invalid floating point operation"; break;
126  case FPE_FLTSUB: libMesh::err << "subscript out of range"; break;
127  default: libMesh::err << "unrecognized"; break;
128  }
129  libMesh::err << ")!" << std::endl;
130 
131  libmesh_error_msg("\nTo track this down, compile in debug mode, then in gdb do:\n" \
132  << " break libmesh_handleFPE\n" \
133  << " run ...\n" \
134  << " bt");
135 }
136 
137 
138 void libmesh_handleSEGV(int /*signo*/, siginfo_t * info, void * /*context*/)
139 {
140  libMesh::err << std::endl;
141  libMesh::err << "Segmentation fault exception signaled (";
142  switch (info->si_code)
143  {
144  case SEGV_MAPERR: libMesh::err << "Address not mapped"; break;
145  case SEGV_ACCERR: libMesh::err << "Invalid permissions"; break;
146  default: libMesh::err << "unrecognized"; break;
147  }
148  libMesh::err << ")!" << std::endl;
149 
150  libmesh_error_msg("\nTo track this down, compile in debug mode, then in gdb do:\n" \
151  << " break libmesh_handleSEGV\n" \
152  << " run ...\n" \
153  << " bt");
154 }
155 #endif
156 }
157 
158 
159 
160 #ifdef LIBMESH_HAVE_MPI
161 void libMesh_MPI_Handler (MPI_Comm *, int *, ...)
162 {
163  libmesh_not_implemented();
164 }
165 #endif
166 
167 
168 namespace libMesh
169 {
170 
178 namespace libMeshPrivateData {
179 
183 extern bool _is_initialized;
184 
189 }
190 
191 
192 // ------------------------------------------------------------
193 // libMesh data initialization
194 #ifdef LIBMESH_HAVE_MPI
195 #ifndef LIBMESH_DISABLE_COMMWORLD
196 MPI_Comm COMM_WORLD = MPI_COMM_NULL;
197 #endif
198 MPI_Comm GLOBAL_COMM_WORLD = MPI_COMM_NULL;
199 #else
200 #ifndef LIBMESH_DISABLE_COMMWORLD
201 int COMM_WORLD = 0;
202 #endif
203 int GLOBAL_COMM_WORLD = 0;
204 #endif
205 
206 #ifdef LIBMESH_DISABLE_COMMWORLD
209 #else
211 Parallel::Communicator & Parallel::Communicator_World = CommWorld;
212 #endif
213 
214 
215 OStreamProxy out(std::cout);
216 OStreamProxy err(std::cerr);
217 
218 bool warned_about_auto_ptr(false);
219 
220 PerfLog perflog ("libMesh",
221 #ifdef LIBMESH_ENABLE_PERFORMANCE_LOGGING
222  true
223 #else
224  false
225 #endif
226  );
227 
228 
229 // const Real pi = 3.1415926535897932384626433832795029L;
230 
231 #ifdef LIBMESH_USE_COMPLEX_NUMBERS
232 const Number imaginary (0., 1.);
233 // const Number zero (0., 0.);
234 #else
235 // const Number zero = 0.;
236 #endif
237 
238 // This is now a static constant in the header; no reason not to let
239 // the compiler inline it.
240 
241 // const unsigned int invalid_uint = static_cast<unsigned int>(-1);
242 
243 
244 
245 // ------------------------------------------------------------
246 // libMesh::libMeshPrivateData data initialization
247 #ifdef LIBMESH_HAVE_MPI
248 MPI_Errhandler libmesh_errhandler;
249 
252 #endif
253 int libMesh::libMeshPrivateData::_n_threads = 1; /* Threads::task_scheduler_init::automatic; */
256 #if defined(LIBMESH_HAVE_PETSC) // PETSc is the default
258 #elif defined(LIBMESH_TRILINOS_HAVE_AZTECOO) // Use Trilinos if PETSc isn't there
260 #elif defined(LIBMESH_HAVE_EIGEN) // Use Eigen if neither are there
262 #elif defined(LIBMESH_HAVE_LASPACK) // Use LASPACK as a last resort
264 #else // No valid linear solver package at compile time
266 #endif
267 
268 
269 
270 // ------------------------------------------------------------
271 // libMesh functions
272 
274 {
276 }
277 
278 
279 
280 bool closed()
281 {
283 }
284 
285 
286 #ifdef LIBMESH_ENABLE_EXCEPTIONS
287 std::terminate_handler old_terminate_handler;
288 
290 {
291  // If this got called then we're probably crashing; let's print a
292  // stack trace. The trace files that are ultimately written depend on:
293  // 1.) Who throws the exception.
294  // 2.) Whether the C++ runtime unwinds the stack before the
295  // terminate_handler is called (this is implementation defined).
296  //
297  // The various cases are summarized in the table below:
298  //
299  // | libmesh exception | other exception
300  // -------------------------------------
301  // stack unwinds | A | B
302  // stack does not unwind | C | D
303  //
304  // Case A: There will be two stack traces in the file: one "useful"
305  // one, and one nearly empty one due to stack unwinding.
306  // Case B: You will get one nearly empty stack trace (not great, Bob!)
307  // Case C: You will get two nearly identical stack traces, ignore one of them.
308  // Case D: You will get one useful stack trace.
309  //
310  // Cases A and B (where the stack unwinds when an exception leaves
311  // main) appear to be non-existent in practice. I don't have a
312  // definitive list, but the stack does not unwind for GCC on either
313  // Mac or Linux. I think there's good reasons for this behavior too:
314  // it's much easier to get a stack trace when the stack doesn't
315  // unwind, for example.
317 
318  // We may care about performance data pre-crash; it would be sad to
319  // throw that away.
322 
323  // If we have MPI and it has been initialized, we need to be sure
324  // and call MPI_Abort instead of std::abort, so that the parallel
325  // job can die nicely.
326 #if defined(LIBMESH_HAVE_MPI)
327  int mpi_initialized;
328  MPI_Initialized (&mpi_initialized);
329 
330  if (mpi_initialized)
331  MPI_Abort(libMesh::GLOBAL_COMM_WORLD, 1);
332  else
333 #endif
334  // The system terminate_handler may do useful things like printing
335  // uncaught exception information, or the user may have created
336  // their own terminate handler that we want to call.
338 }
339 #endif
340 
341 
342 
343 #ifndef LIBMESH_HAVE_MPI
344 LibMeshInit::LibMeshInit (int argc, const char * const * argv)
345 #else
346 LibMeshInit::LibMeshInit (int argc, const char * const * argv,
347  MPI_Comm COMM_WORLD_IN)
348 #endif
349 {
350  // should _not_ be initialized already.
351  libmesh_assert (!libMesh::initialized());
352 
353  // Build a command-line parser.
354  command_line.reset (new GetPot (argc, argv));
355 
356  // Disable performance logging upon request
357  {
358  if (libMesh::on_command_line ("--disable-perflog"))
360  }
361 
362  // Build a task scheduler
363  {
364  // Get the requested number of threads, defaults to 1 to avoid MPI and
365  // multithreading competition. If you would like to use MPI and multithreading
366  // at the same time then (n_mpi_processes_per_node)x(n_threads) should be the
367  // number of processing cores per node.
368  std::vector<std::string> n_threads(2);
369  n_threads[0] = "--n_threads";
370  n_threads[1] = "--n-threads";
371  libMesh::libMeshPrivateData::_n_threads =
372  libMesh::command_line_value (n_threads, 1);
373 
374  // If there's no threading model active, force _n_threads==1
375 #if !LIBMESH_USING_THREADS
376  if (libMesh::libMeshPrivateData::_n_threads != 1)
377  {
378  libMesh::libMeshPrivateData::_n_threads = 1;
379  libmesh_warning("Warning: You requested --n-threads>1 but no threading model is active!\n"
380  << "Forcing --n-threads==1 instead!");
381  }
382 #endif
383 
384  // Set the number of OpenMP threads to the same as the number of threads libMesh is going to use
385 #ifdef LIBMESH_HAVE_OPENMP
386  omp_set_num_threads(libMesh::libMeshPrivateData::_n_threads);
387 #endif
388 
389  task_scheduler.reset (new Threads::task_scheduler_init(libMesh::n_threads()));
390  }
391 
392  // Construct singletons who may be at risk of the
393  // "static initialization order fiasco"
395 
396  // Make sure the construction worked
397  libmesh_assert(remote_elem);
398 
399 #if defined(LIBMESH_HAVE_MPI)
400 
401  // Allow the user to bypass MPI initialization
402  if (!libMesh::on_command_line ("--disable-mpi"))
403  {
404  // Check whether the calling program has already initialized
405  // MPI, and avoid duplicate Init/Finalize
406  int flag;
407  libmesh_call_mpi(MPI_Initialized (&flag));
408 
409  if (!flag)
410  {
411 #if MPI_VERSION > 1
412  int mpi_thread_provided;
413  const int mpi_thread_requested = libMesh::n_threads() > 1 ?
414  MPI_THREAD_FUNNELED :
415  MPI_THREAD_SINGLE;
416 
417  libmesh_call_mpi
418  (MPI_Init_thread (&argc, const_cast<char ***>(&argv),
419  mpi_thread_requested, &mpi_thread_provided));
420 
421  if ((libMesh::n_threads() > 1) &&
422  (mpi_thread_provided < MPI_THREAD_FUNNELED))
423  {
424  libmesh_warning("Warning: MPI failed to guarantee MPI_THREAD_FUNNELED\n"
425  << "for a threaded run.\n"
426  << "Be sure your library is funneled-thread-safe..."
427  << std::endl);
428 
429  // Ideally, if an MPI stack tells us it's unsafe for us
430  // to use threads, we shouldn't use threads.
431  // In practice, we've encountered one MPI stack (an
432  // mvapich2 configuration) that returned
433  // MPI_THREAD_SINGLE as a proper warning, two stacks
434  // that handle MPI_THREAD_FUNNELED properly, and two
435  // current stacks plus a couple old stacks that return
436  // MPI_THREAD_SINGLE but support libMesh threaded runs
437  // anyway.
438 
439  // libMesh::libMeshPrivateData::_n_threads = 1;
440  // task_scheduler.reset (new Threads::task_scheduler_init(libMesh::n_threads()));
441  }
442 #else
443  if (libMesh::libMeshPrivateData::_n_threads > 1)
444  {
445  libmesh_warning("Warning: using MPI1 for threaded code.\n" <<
446  "Be sure your library is funneled-thread-safe..." <<
447  std::endl);
448  }
449 
450  libmesh_call_mpi
451  (MPI_Init (&argc, const_cast<char ***>(&argv)));
452 #endif
453  libmesh_initialized_mpi = true;
454  }
455 
456  // Duplicate the input communicator for internal use
457  // And get a Parallel::Communicator copy too, to use
458  // as a default for that API
459  this->_comm = COMM_WORLD_IN;
460 
461  libMesh::GLOBAL_COMM_WORLD = COMM_WORLD_IN;
462 
463 #ifndef LIBMESH_DISABLE_COMMWORLD
464  libMesh::COMM_WORLD = COMM_WORLD_IN;
465  Parallel::Communicator_World = COMM_WORLD_IN;
466 #endif
467 
468  //MPI_Comm_set_name not supported in at least SGI MPT's MPI implementation
469  //MPI_Comm_set_name (libMesh::COMM_WORLD, "libMesh::COMM_WORLD");
470 
472  cast_int<processor_id_type>(this->comm().rank());
474  cast_int<processor_id_type>(this->comm().size());
475 
476  // Set up an MPI error handler if requested. This helps us get
477  // into a debugger with a proper stack when an MPI error occurs.
478  if (libMesh::on_command_line ("--handle-mpi-errors"))
479  {
480 #if MPI_VERSION > 1
481  libmesh_call_mpi
482  (MPI_Comm_create_errhandler(libMesh_MPI_Handler, &libmesh_errhandler));
483  libmesh_call_mpi
484  (MPI_Comm_set_errhandler(libMesh::GLOBAL_COMM_WORLD, libmesh_errhandler));
485  libmesh_call_mpi
486  (MPI_Comm_set_errhandler(MPI_COMM_WORLD, libmesh_errhandler));
487 #else
488  libmesh_call_mpi
489  (MPI_Errhandler_create(libMesh_MPI_Handler, &libmesh_errhandler));
490  libmesh_call_mpi
491  (MPI_Errhandler_set(libMesh::GLOBAL_COMM_WORLD, libmesh_errhandler));
492  libmesh_call_mpi
493  (MPI_Errhandler_set(MPI_COMM_WORLD, libmesh_errhandler));
494 #endif // #if MPI_VERSION > 1
495  }
496  }
497 
498  // Could we have gotten bad values from the above calls?
499  libmesh_assert_greater (libMeshPrivateData::_n_processors, 0);
500 
501  // The cast_int already tested _processor_id>=0
502  // libmesh_assert_greater_equal (libMeshPrivateData::_processor_id, 0);
503 
504  // Let's be sure we properly initialize on every processor at once:
505  libmesh_parallel_only(this->comm());
506 
507 #endif
508 
509 #if defined(LIBMESH_HAVE_PETSC)
510 
511  // Allow the user to bypass PETSc initialization
512  if (!libMesh::on_command_line ("--disable-petsc")
513 
514 #if defined(LIBMESH_HAVE_MPI)
515  // If the user bypassed MPI, we'd better be safe and assume that
516  // PETSc was built to require it; otherwise PETSc initialization
517  // dies.
518  && !libMesh::on_command_line ("--disable-mpi")
519 #endif
520  )
521  {
522  int ierr=0;
523 
524  PETSC_COMM_WORLD = libMesh::GLOBAL_COMM_WORLD;
525 
526  // Check whether the calling program has already initialized
527  // PETSc, and avoid duplicate Initialize/Finalize
528  PetscBool petsc_already_initialized;
529  ierr = PetscInitialized(&petsc_already_initialized);
530  CHKERRABORT(libMesh::GLOBAL_COMM_WORLD,ierr);
531  if (petsc_already_initialized != PETSC_TRUE)
532  libmesh_initialized_petsc = true;
533 # if defined(LIBMESH_HAVE_SLEPC)
534 
535  // If SLEPc allows us to check whether the calling program
536  // has already initialized it, we do that, and avoid
537  // duplicate Initialize/Finalize.
538  // We assume that SLEPc will handle PETSc appropriately,
539  // which it does in the versions we've checked.
540  if (!SlepcInitializeCalled)
541  {
542  ierr = SlepcInitialize (&argc, const_cast<char ***>(&argv), libmesh_nullptr, libmesh_nullptr);
543  CHKERRABORT(libMesh::GLOBAL_COMM_WORLD,ierr);
544  libmesh_initialized_slepc = true;
545  }
546 # else
547  if (libmesh_initialized_petsc)
548  {
549  ierr = PetscInitialize (&argc, const_cast<char ***>(&argv), libmesh_nullptr, libmesh_nullptr);
550  CHKERRABORT(libMesh::GLOBAL_COMM_WORLD,ierr);
551  }
552 # endif
553 #if !PETSC_RELEASE_LESS_THAN(3,3,0)
554  // Register the reference implementation of DMlibMesh
555 #if PETSC_RELEASE_LESS_THAN(3,4,0)
556  ierr = DMRegister(DMLIBMESH, PETSC_NULL, "DMCreate_libMesh", DMCreate_libMesh); CHKERRABORT(libMesh::GLOBAL_COMM_WORLD,ierr);
557 #else
558  ierr = DMRegister(DMLIBMESH, DMCreate_libMesh); CHKERRABORT(libMesh::GLOBAL_COMM_WORLD,ierr);
559 #endif
560 
561 #endif
562  }
563 #endif
564 
565 #if defined(LIBMESH_HAVE_MPI) && defined(LIBMESH_HAVE_VTK)
566  // Do MPI initialization for VTK.
567  _vtk_mpi_controller = vtkMPIController::New();
568  _vtk_mpi_controller->Initialize(&argc, const_cast<char ***>(&argv), /*initialized_externally=*/1);
569  _vtk_mpi_controller->SetGlobalController(_vtk_mpi_controller);
570 #endif
571 
572  // Re-parse the command-line arguments. Note that PETSc and MPI
573  // initialization above may have removed command line arguments
574  // that are not relevant to this application in the above calls.
575  // We don't want a false-positive by detecting those arguments.
576  //
577  // Note: this seems overly paranoid/like it should be unnecessary,
578  // plus we were doing it wrong for many years and not clearing the
579  // existing GetPot object before re-parsing the command line, so all
580  // the command line arguments appeared twice in the GetPot object...
581  command_line.reset (new GetPot (argc, argv));
582 
583  // The following line is an optimization when simultaneous
584  // C and C++ style access to output streams is not required.
585  // The amount of benefit which occurs is probably implementation
586  // defined, and may be nothing. On the other hand, I have seen
587  // some IO tests where IO performance improves by a factor of two.
588  if (!libMesh::on_command_line ("--sync-with-stdio"))
589  std::ios::sync_with_stdio(false);
590 
591  // Honor the --separate-libmeshout command-line option.
592  // When this is specified, the library uses an independent ostream
593  // for libMesh::out/libMesh::err messages, and
594  // std::cout and std::cerr are untouched by any other options
595  if (libMesh::on_command_line ("--separate-libmeshout"))
596  {
597  // Redirect. We'll share streambufs with cout/cerr for now, but
598  // presumably anyone using this option will want to replace the
599  // bufs later.
600  std::ostream * newout = new std::ostream(std::cout.rdbuf());
601  libMesh::out = *newout;
602  std::ostream * newerr = new std::ostream(std::cerr.rdbuf());
603  libMesh::err = *newerr;
604  }
605 
606  // Process command line arguments for redirecting stdout/stderr.
607  bool
608  cmdline_has_redirect_stdout = libMesh::on_command_line ("--redirect-stdout"),
609  cmdline_has_redirect_output = libMesh::on_command_line ("--redirect-output");
610 
611  // The --redirect-stdout command-line option has been deprecated in
612  // favor of "--redirect-output basename".
613  if (cmdline_has_redirect_stdout)
614  libmesh_warning("The --redirect-stdout command line option has been deprecated. "
615  "Use '--redirect-output basename' instead.");
616 
617  // Honor the "--redirect-stdout" and "--redirect-output basename"
618  // command-line options. When one of these is specified, each
619  // processor sends libMesh::out/libMesh::err messages to
620  // stdout.processor.#### (default) or basename.processor.####.
621  if (cmdline_has_redirect_stdout || cmdline_has_redirect_output)
622  {
623  std::string basename = "stdout";
624 
625  // Look for following argument if using new API
626  if (cmdline_has_redirect_output)
627  {
628  // Set the cursor to the correct location in the list of command line arguments.
629  command_line->search(1, "--redirect-output");
630 
631  // Get the next option on the command line as a string.
632  std::string next_string = "";
633  next_string = command_line->next(next_string);
634 
635  // If the next string starts with a dash, we assume it's
636  // another flag and not a file basename requested by the
637  // user.
638  if (next_string.size() > 0 && next_string.find_first_of("-") != 0)
639  basename = next_string;
640  }
641 
642  std::ostringstream filename;
643  filename << basename << ".processor." << libMesh::global_processor_id();
644  _ofstream.reset (new std::ofstream (filename.str().c_str()));
645 
646  // Redirect, saving the original streambufs!
647  out_buf = libMesh::out.rdbuf (_ofstream->rdbuf());
648  err_buf = libMesh::err.rdbuf (_ofstream->rdbuf());
649  }
650 
651  // redirect libMesh::out to nothing on all
652  // other processors unless explicitly told
653  // not to via the --keep-cout command-line argument.
654  if (libMesh::global_processor_id() != 0)
655  if (!libMesh::on_command_line ("--keep-cout"))
657 
658  // Similarly, the user can request to drop cerr on all non-0 ranks.
659  // By default, errors are printed on all ranks, but this can lead to
660  // interleaved/unpredictable outputs when doing parallel regression
661  // testing, which this option is designed to support.
662  if (libMesh::global_processor_id() != 0)
663  if (libMesh::on_command_line ("--drop-cerr"))
665 
666  // Check command line to override printing
667  // of reference count information.
668  if (libMesh::on_command_line("--disable-refcount-printing"))
670 
671 #ifdef LIBMESH_ENABLE_EXCEPTIONS
672  // Set our terminate handler to write stack traces in the event of a
673  // crash
674  old_terminate_handler = std::set_terminate(libmesh_terminate_handler);
675 #endif
676 
677 
678  if (libMesh::on_command_line("--enable-fpe"))
679  libMesh::enableFPE(true);
680 
681  if (libMesh::on_command_line("--enable-segv"))
682  libMesh::enableSEGV(true);
683 
684  // The library is now ready for use
686 
687 
688  // Make sure these work. Library methods
689  // depend on these being implemented properly,
690  // so this is a good time to test them!
691  libmesh_assert (libMesh::initialized());
692  libmesh_assert (!libMesh::closed());
693 }
694 
695 
696 
698 {
699  // Every processor had better be ready to exit at the same time.
700  // This would be a libmesh_parallel_only() function, except that
701  // libmesh_parallel_only() uses libmesh_assert() which throws an
702  // exception() which causes compilers to scream about exceptions
703  // inside destructors.
704 
705  // Even if we're not doing parallel_only debugging, we don't want
706  // one processor to try to exit until all others are done working.
707  this->comm().barrier();
708 
709  // We can't delete, finalize, etc. more than once without
710  // reinitializing in between
711  libmesh_exceptionless_assert(!libMesh::closed());
712 
713  // Delete reference counted singleton(s)
715 
716  // Clear the thread task manager we started
717  task_scheduler.reset();
718 
719  // Force the \p ReferenceCounter to print
720  // its reference count information. This allows
721  // us to find memory leaks. By default the
722  // \p ReferenceCounter only prints its information
723  // when the last created object has been destroyed.
724  // That does no good if we are leaking memory!
726 
727 
728  // Print an informative message if we detect a memory leak
729  if (ReferenceCounter::n_objects() != 0)
730  {
731  libMesh::err << "Memory leak detected!"
732  << std::endl;
733 
734 #if !defined(LIBMESH_ENABLE_REFERENCE_COUNTING) || defined(NDEBUG)
735 
736  libMesh::err << "Compile in DEBUG mode with --enable-reference-counting"
737  << std::endl
738  << "for more information"
739  << std::endl;
740 #endif
741 
742  }
743 
744  // print the perflog to individual processor's file.
746 
747  // Now clear the logging object, we don't want it to print
748  // a second time during the PerfLog destructor.
750 
751  // Reconnect the output streams
752  // (don't do this, or we will get messages from objects
753  // that go out of scope after the following return)
754  //std::cout.rdbuf(std::cerr.rdbuf());
755 
756 
757  // Set the initialized() flag to false
759 
760  if (libMesh::on_command_line ("--redirect-stdout") ||
761  libMesh::on_command_line ("--redirect-output"))
762  {
763  // If stdout/stderr were redirected to files, reset them now.
764  libMesh::out.rdbuf (out_buf);
765  libMesh::err.rdbuf (err_buf);
766  }
767 
768  // If we built our own output streams, we want to clean them up.
769  if (libMesh::on_command_line ("--separate-libmeshout"))
770  {
771  delete libMesh::out.get();
772  delete libMesh::err.get();
773 
774  libMesh::out.reset(std::cout);
775  libMesh::err.reset(std::cerr);
776  }
777 
778 #ifdef LIBMESH_ENABLE_EXCEPTIONS
779  // Reset the old terminate handler; maybe the user code wants to
780  // keep doing C++ stuff after closing libMesh stuff.
781  std::set_terminate(old_terminate_handler);
782 #endif
783 
784 
785  if (libMesh::on_command_line("--enable-fpe"))
786  libMesh::enableFPE(false);
787 
788 #if defined(LIBMESH_HAVE_PETSC)
789  // Allow the user to bypass PETSc finalization
790  if (!libMesh::on_command_line ("--disable-petsc")
791 #if defined(LIBMESH_HAVE_MPI)
792  && !libMesh::on_command_line ("--disable-mpi")
793 #endif
794  )
795  {
796 # if defined(LIBMESH_HAVE_SLEPC)
797  if (libmesh_initialized_slepc)
798  SlepcFinalize();
799 # else
800  if (libmesh_initialized_petsc)
801  PetscFinalize();
802 # endif
803  }
804 #endif
805 
806 #if defined(LIBMESH_HAVE_MPI) && defined(LIBMESH_HAVE_VTK)
807  _vtk_mpi_controller->Finalize(/*finalized_externally=*/1);
808  _vtk_mpi_controller->Delete();
809 #endif
810 
811 #if defined(LIBMESH_HAVE_MPI)
812  // Allow the user to bypass MPI finalization
813  if (!libMesh::on_command_line ("--disable-mpi"))
814  {
815  this->_comm.clear();
816 #ifndef LIBMESH_DISABLE_COMMWORLD
817  Parallel::Communicator_World.clear();
818 #endif
819 
820  if (libmesh_initialized_mpi)
821  {
822  // We can't just libmesh_assert here because destructor,
823  // but we ought to report any errors
824  unsigned int error_code = MPI_Finalize();
825  if (error_code != MPI_SUCCESS)
826  {
827  char error_string[MPI_MAX_ERROR_STRING+1];
828  int error_string_len;
829  MPI_Error_string(error_code, error_string,
830  &error_string_len);
831  std::cerr << "Failure from MPI_Finalize():\n"
832  << error_string << std::endl;
833  }
834  }
835  }
836 #endif
837 }
838 
839 
840 
844 void enableFPE(bool on)
845 {
846 #if !defined(LIBMESH_HAVE_FEENABLEEXCEPT) && defined(LIBMESH_HAVE_XMMINTRIN_H) && !defined(__SUNPRO_CC)
847  static int flags = 0;
848 #endif
849 
850  if (on)
851  {
852 #ifdef LIBMESH_HAVE_FEENABLEEXCEPT
853  feenableexcept(FE_DIVBYZERO | FE_INVALID);
854 #elif LIBMESH_HAVE_XMMINTRIN_H
855 # ifndef __SUNPRO_CC
856  flags = _MM_GET_EXCEPTION_MASK(); // store the flags
857  _MM_SET_EXCEPTION_MASK(flags & ~_MM_MASK_INVALID);
858 # endif
859 #endif
860 
861 #if LIBMESH_HAVE_DECL_SIGACTION
862  struct sigaction new_action, old_action;
863 
864  // Set up the structure to specify the new action.
865  new_action.sa_sigaction = libmesh_handleFPE;
866  sigemptyset (&new_action.sa_mask);
867  new_action.sa_flags = SA_SIGINFO;
868 
869  sigaction (SIGFPE, libmesh_nullptr, &old_action);
870  if (old_action.sa_handler != SIG_IGN)
871  sigaction (SIGFPE, &new_action, libmesh_nullptr);
872 #endif
873  }
874  else
875  {
876 #ifdef LIBMESH_HAVE_FEDISABLEEXCEPT
877  fedisableexcept(FE_DIVBYZERO | FE_INVALID);
878 #elif LIBMESH_HAVE_XMMINTRIN_H
879 # ifndef __SUNPRO_CC
880  _MM_SET_EXCEPTION_MASK(flags);
881 # endif
882 #endif
883  signal(SIGFPE, SIG_DFL);
884  }
885 }
886 
887 
888 // Enable handling of SIGSEGV by libMesh
889 // (potentially instead of PETSc)
890 void enableSEGV(bool on)
891 {
892 #if LIBMESH_HAVE_DECL_SIGACTION
893  static struct sigaction old_action;
894  static bool was_on = false;
895 
896  if (on)
897  {
898  struct sigaction new_action;
899  was_on = true;
900 
901  // Set up the structure to specify the new action.
902  new_action.sa_sigaction = libmesh_handleSEGV;
903  sigemptyset (&new_action.sa_mask);
904  new_action.sa_flags = SA_SIGINFO;
905 
906  sigaction (SIGSEGV, &new_action, &old_action);
907  }
908  else if (was_on)
909  {
910  was_on = false;
911  sigaction (SIGSEGV, &old_action, libmesh_nullptr);
912  }
913 #else
914  libmesh_error_msg("System call sigaction not supported.");
915 #endif
916 }
917 
918 
919 
920 bool on_command_line (const std::string & arg)
921 {
922  // Make sure the command line parser is ready for use
923  libmesh_assert(command_line.get());
924 
925  return command_line->search (arg);
926 }
927 
928 
929 
930 template <typename T>
931 T command_line_value (const std::string & name, T value)
932 {
933  // Make sure the command line parser is ready for use
934  libmesh_assert(command_line.get());
935 
936  // only if the variable exists in the file
937  if (command_line->have_variable(name.c_str()))
938  value = (*command_line)(name.c_str(), value);
939 
940  return value;
941 }
942 
943 template <typename T>
944 T command_line_value (const std::vector<std::string> & name, T value)
945 {
946  // Make sure the command line parser is ready for use
947  libmesh_assert(command_line.get());
948 
949  // Check for multiple options (return the first that matches)
950  for (std::vector<std::string>::const_iterator i=name.begin(); i != name.end(); ++i)
951  if (command_line->have_variable(i->c_str()))
952  {
953  value = (*command_line)(i->c_str(), value);
954  break;
955  }
956 
957  return value;
958 }
959 
960 
961 
962 template <typename T>
963 T command_line_next (const std::string & name, T value)
964 {
965  // Make sure the command line parser is ready for use
966  libmesh_assert(command_line.get());
967 
968  if (command_line->search(1, name.c_str()))
969  value = command_line->next(value);
970 
971  return value;
972 }
973 
974 
975 
976 template <typename T>
977 void command_line_vector (const std::string & name, std::vector<T> & vec)
978 {
979  // Make sure the command line parser is ready for use
980  libmesh_assert(command_line.get());
981 
982  // only if the variable exists on the command line
983  if (command_line->have_variable(name.c_str()))
984  {
985  unsigned size = command_line->vector_variable_size(name.c_str());
986  vec.resize(size);
987 
988  for (unsigned i=0; i<size; ++i)
989  vec[i] = (*command_line)(name.c_str(), vec[i], i);
990  }
991 }
992 
993 
995 {
996  libmesh_assert (libMesh::initialized());
997 
998  static bool called = false;
999 
1000  // Check the command line. Since the command line is
1001  // unchanging it is sufficient to do this only once.
1002  if (!called)
1003  {
1004  called = true;
1005 
1006 #ifdef LIBMESH_HAVE_PETSC
1007  if (libMesh::on_command_line ("--use-petsc"))
1009 #endif
1010 
1011 #ifdef LIBMESH_TRILINOS_HAVE_AZTECOO
1012  if (libMesh::on_command_line ("--use-trilinos") ||
1013  libMesh::on_command_line ("--disable-petsc"))
1015 #endif
1016 
1017 #ifdef LIBMESH_HAVE_EIGEN
1018  if (libMesh::on_command_line ("--use-eigen" ) ||
1019 #if defined(LIBMESH_HAVE_MPI)
1020  // If the user bypassed MPI, we disable PETSc and Trilinos
1021  // too
1022  libMesh::on_command_line ("--disable-mpi") ||
1023 #endif
1024  libMesh::on_command_line ("--disable-petsc"))
1026 #endif
1027 
1028 #ifdef LIBMESH_HAVE_LASPACK
1029  if (libMesh::on_command_line ("--use-laspack" ) ||
1030 #if defined(LIBMESH_HAVE_MPI)
1031  // If the user bypassed MPI, we disable PETSc and Trilinos
1032  // too
1033  libMesh::on_command_line ("--disable-mpi") ||
1034 #endif
1035  libMesh::on_command_line ("--disable-petsc"))
1037 #endif
1038 
1039  if (libMesh::on_command_line ("--disable-laspack") &&
1040  libMesh::on_command_line ("--disable-trilinos") &&
1041  libMesh::on_command_line ("--disable-eigen") &&
1042  (
1043 #if defined(LIBMESH_HAVE_MPI)
1044  // If the user bypassed MPI, we disable PETSc too
1045  libMesh::on_command_line ("--disable-mpi") ||
1046 #endif
1047  libMesh::on_command_line ("--disable-petsc")))
1049  }
1050 
1051 
1053 }
1054 
1055 
1056 
1057 //-------------------------------------------------------------------------------
1058 template int command_line_value<int> (const std::string &, int);
1059 template float command_line_value<float> (const std::string &, float);
1060 template double command_line_value<double> (const std::string &, double);
1061 template long double command_line_value<long double> (const std::string &, long double);
1062 template std::string command_line_value<std::string> (const std::string &, std::string);
1063 
1064 template int command_line_value<int> (const std::vector<std::string> &, int);
1065 template float command_line_value<float> (const std::vector<std::string> &, float);
1066 template double command_line_value<double> (const std::vector<std::string> &, double);
1067 template long double command_line_value<long double> (const std::vector<std::string> &, long double);
1068 template std::string command_line_value<std::string> (const std::vector<std::string> &, std::string);
1069 
1070 template int command_line_next<int> (const std::string &, int);
1071 template float command_line_next<float> (const std::string &, float);
1072 template double command_line_next<double> (const std::string &, double);
1073 template long double command_line_next<long double> (const std::string &, long double);
1074 template std::string command_line_next<std::string> (const std::string &, std::string);
1075 
1076 template void command_line_vector<int> (const std::string &, std::vector<int> &);
1077 template void command_line_vector<float> (const std::string &, std::vector<float> &);
1078 template void command_line_vector<double> (const std::string &, std::vector<double> &);
1079 template void command_line_vector<long double> (const std::string &, std::vector<long double> &);
1080 
1081 } // namespace libMesh
std::string name(const ElemQuality q)
Definition: elem_quality.C:39
bool closed()
Definition: libmesh.C:280
static unsigned int n_objects()
unsigned int n_threads()
Definition: libmesh_base.h:125
template long double command_line_next< long double >(const std::string &, long double)
FakeCommunicator & Communicator_World
EIGEN_SOLVERS
Definition: libmesh.C:261
streambufT * rdbuf() const
TRILINOS_SOLVERS
Definition: libmesh.C:259
void enableSEGV(bool on)
Definition: libmesh.C:890
processor_id_type _n_processors
Definition: libmesh.C:250
template void command_line_vector< long double >(const std::string &, std::vector< long double > &)
bool warned_about_auto_ptr
uint8_t processor_id_type
Definition: id_types.h:99
const class libmesh_nullptr_t libmesh_nullptr
MPI_Comm GLOBAL_COMM_WORLD
Definition: libmesh.C:198
void write_traceout()
Definition: print_trace.C:233
MPI_Comm COMM_WORLD
Definition: libmesh.C:196
void reset(streamT &target)
template int command_line_value< int >(const std::string &, int)
const Number imaginary
SolverPackage default_solver_package()
Definition: libmesh.C:994
Responsible for timing and summarizing events.
Definition: perf_log.h:125
LibMeshInit(int argc, const char *const *argv, MPI_Comm COMM_WORLD_IN=MPI_COMM_WORLD)
PetscErrorCode DMCreate_libMesh(DM dm)
template void command_line_vector< float >(const std::string &, std::vector< float > &)
LASPACK_SOLVERS
Definition: libmesh.C:263
template float command_line_next< float >(const std::string &, float)
template void command_line_vector< int >(const std::string &, std::vector< int > &)
std::terminate_handler old_terminate_handler
Definition: libmesh.C:287
processor_id_type _processor_id
Definition: libmesh.C:251
OStreamProxy err(std::cerr)
static void print_info(std::ostream &out=libMesh::out)
PerfLog perflog("libMesh",#ifdef LIBMESH_ENABLE_PERFORMANCE_LOGGING true#else false#endif)
template int command_line_next< int >(const std::string &, int)
MPI_Errhandler libmesh_errhandler
Definition: libmesh.C:248
template double command_line_next< double >(const std::string &, double)
void clear()
Definition: perf_log.C:77
Parallel::FakeCommunicator CommWorld
Definition: libmesh.C:207
void enableFPE(bool on)
Definition: libmesh.C:844
PetscTruth PetscBool
Definition: petsc_macro.h:64
void command_line_vector(const std::string &name, std::vector< T > &vec)
Definition: libmesh.C:977
T command_line_next(const std::string &name, T value)
Definition: libmesh.C:963
PetscErrorCode ierr
bool on_command_line(const std::string &arg)
Definition: libmesh.C:920
processor_id_type global_processor_id()
Definition: libmesh_base.h:114
static const bool value
Definition: xdr_io.C:108
template void command_line_vector< double >(const std::string &, std::vector< double > &)
bool initialized()
Definition: libmesh.C:273
template float command_line_value< float >(const std::string &, float)
void libMesh_MPI_Handler(MPI_Comm *, int *,...)
Definition: libmesh.C:161
INVALID_SOLVER_PACKAGE
Definition: libmesh.C:265
static void cleanup()
void print_log() const
Definition: perf_log.C:684
template long double command_line_value< long double >(const std::string &, long double)
T command_line_value(const std::string &name, T value)
Definition: libmesh.C:931
template double command_line_value< double >(const std::string &, double)
static void disable_print_counter_info()
OStreamProxy out(std::cout)
SolverPackage _solver_package
Definition: libmesh.C:255
void disable_logging()
Definition: perf_log.h:156
void libmesh_terminate_handler()
Definition: libmesh.C:289
const RemoteElem * remote_elem
Definition: remote_elem.C:57