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