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