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