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