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