libMesh
libmesh.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 
19 // Local includes
20 #include "libmesh/libmesh.h"
21 
22 // libMesh includes
23 #include "libmesh/getpot.h"
24 #include "libmesh/reference_counter.h"
25 #include "libmesh/libmesh_singleton.h"
26 #include "libmesh/remote_elem.h"
27 #include "libmesh/threads.h"
28 #include "libmesh/parallel_only.h"
29 #include "libmesh/print_trace.h"
30 #include "libmesh/enum_solver_package.h"
31 #include "libmesh/perf_log.h"
32 #include "libmesh/thread_buffered_syncbuf.h"
33 
34 // TIMPI includes
35 #include "timpi/communicator.h"
36 #include "timpi/timpi_init.h"
37 
38 // C/C++ includes
39 #include <cstdlib>
40 #include <iostream>
41 #include <fstream>
42 
43 #ifdef LIBMESH_ENABLE_EXCEPTIONS
44 #include <exception>
45 #endif
46 
47 #ifdef LIBMESH_HAVE_OPENMP
48 #include <omp.h>
49 #endif
50 
51 #include "stdlib.h" // C, not C++ - we need setenv() from POSIX
52 #include "signal.h"
53 
54 
55 // floating-point exceptions
56 #ifdef LIBMESH_HAVE_FENV_H
57 # include <fenv.h>
58 #endif
59 #ifdef LIBMESH_HAVE_XMMINTRIN_H
60 # include <xmmintrin.h>
61 #endif
62 
63 
64 #if defined(LIBMESH_HAVE_MPI)
65 # include "libmesh/ignore_warnings.h"
66 # include <mpi.h>
67 # include "libmesh/restore_warnings.h"
68 #endif // #if defined(LIBMESH_HAVE_MPI)
69 
70 #if defined(LIBMESH_HAVE_PETSC)
71 # include "libmesh/petsc_solver_exception.h"
72 # include <petsc.h>
73 # include <petscerror.h>
74 # include "libmesh/petscdmlibmesh.h"
75 # if defined(LIBMESH_HAVE_SLEPC)
76 // Ignore unused variable warnings from SLEPc
77 # include "libmesh/ignore_warnings.h"
78 # include "libmesh/slepc_macro.h"
79 # include <slepc.h>
80 # include "libmesh/restore_warnings.h"
81 # endif // #if defined(LIBMESH_HAVE_SLEPC)
82 #endif // #if defined(LIBMESH_HAVE_PETSC)
83 
84 #ifdef LIBMESH_HAVE_NETGEN
85 // We need the nglib namespace, because it's used everywhere in nglib
86 // and we don't get binary compatibility without it.
87 //
88 // We need the nglib namespace *here*, because somehow nobody ever
89 // figured out to just put it in nglib.h?
90 namespace nglib {
91 #include "netgen/nglib/nglib.h"
92 }
93 #endif
94 
95 // If we're using MPI and VTK has been detected, we need to do some
96 // MPI initialize/finalize stuff for VTK.
97 #if defined(LIBMESH_HAVE_MPI) && defined(LIBMESH_HAVE_VTK)
98 #include "libmesh/ignore_warnings.h"
99 # include "vtkMPIController.h"
100 #include "libmesh/restore_warnings.h"
101 #endif
102 
103 #include <mutex>
104 
105 // --------------------------------------------------------
106 // Local anonymous namespace to hold miscellaneous bits
107 namespace {
108 
109 std::unique_ptr<GetPot> command_line;
110 
111 std::set<std::string> command_line_name_set;
112 
113 std::unique_ptr<std::ofstream> _ofstream;
114 // If std::cout and std::cerr are redirected, we need to
115 // be a little careful and save the original streambuf objects,
116 // replacing them in the destructor before program termination.
117 std::streambuf * out_buf (nullptr);
118 std::streambuf * err_buf (nullptr);
119 
120 std::unique_ptr<libMesh::Threads::task_scheduler_init> task_scheduler;
121 #if defined(LIBMESH_HAVE_PETSC)
122 bool libmesh_initialized_petsc = false;
123 #endif
124 #if defined(LIBMESH_HAVE_SLEPC)
125 bool libmesh_initialized_slepc = false;
126 #endif
127 
128 
129 
133 #if LIBMESH_HAVE_DECL_SIGACTION
134 void libmesh_handleFPE(int /*signo*/, siginfo_t * info, void * /*context*/)
135 {
136  libMesh::err << std::endl;
137  libMesh::err << "Floating point exception signaled (";
138  switch (info->si_code)
139  {
140  case FPE_INTDIV: libMesh::err << "integer divide by zero"; break;
141  case FPE_INTOVF: libMesh::err << "integer overflow"; break;
142  case FPE_FLTDIV: libMesh::err << "floating point divide by zero"; break;
143  case FPE_FLTOVF: libMesh::err << "floating point overflow"; break;
144  case FPE_FLTUND: libMesh::err << "floating point underflow"; break;
145  case FPE_FLTRES: libMesh::err << "floating point inexact result"; break;
146  case FPE_FLTINV: libMesh::err << "invalid floating point operation"; break;
147  case FPE_FLTSUB: libMesh::err << "subscript out of range"; break;
148  default: libMesh::err << "unrecognized"; break;
149  }
150  libMesh::err << ")!" << std::endl;
151 
152  libmesh_error_msg("\nTo track this down, compile in debug mode, then in gdb do:\n" \
153  << " break libmesh_handleFPE\n" \
154  << " run ...\n" \
155  << " bt");
156 }
157 
158 
159 void libmesh_handleSEGV(int /*signo*/, siginfo_t * info, void * /*context*/)
160 {
161  libMesh::err << std::endl;
162  libMesh::err << "Segmentation fault exception signaled (";
163  switch (info->si_code)
164  {
165  case SEGV_MAPERR: libMesh::err << "Address not mapped"; break;
166  case SEGV_ACCERR: libMesh::err << "Invalid permissions"; break;
167  default: libMesh::err << "unrecognized"; break;
168  }
169  libMesh::err << ")!" << std::endl;
170 
171  libmesh_error_msg("\nTo track this down, compile in debug mode, then in gdb do:\n" \
172  << " break libmesh_handleSEGV\n" \
173  << " run ...\n" \
174  << " bt");
175 }
176 #endif
177 }
178 
179 
180 
181 #ifdef LIBMESH_HAVE_MPI
182 void libMesh_MPI_Handler (MPI_Comm *, int *, ...)
183 {
184  libmesh_not_implemented();
185 }
186 #endif
187 
188 
189 namespace libMesh
190 {
191 
199 namespace libMeshPrivateData {
200 
204 extern bool _is_initialized;
205 
210 }
211 
212 
213 // ------------------------------------------------------------
214 // libMesh data initialization
215 #ifdef LIBMESH_HAVE_MPI
216 MPI_Comm GLOBAL_COMM_WORLD = MPI_COMM_NULL;
217 #else
218 int GLOBAL_COMM_WORLD = 0;
219 #endif
220 
221 OStreamProxy out(std::cout);
222 OStreamProxy err(std::cerr);
223 
224 // Our thread-safe wrappers and the “pre-wrap” sink pointers
225 std::unique_ptr<ThreadBufferedSyncbuf> _out_syncd_thread_buffer;
226 std::unique_ptr<ThreadBufferedSyncbuf> _err_syncd_thread_buffer;
227 std::streambuf * _out_prewrap_buf = nullptr;
228 std::streambuf * _err_prewrap_buf = nullptr;
229 
230 // Install after redirection/drop decisions
232 {
233  auto check_stored_buffer = [](const auto * const libmesh_dbg_var(stored_buffer)) {
234  libmesh_assert_msg(!stored_buffer,
235  "Oops, we've already stored a prewrapped buffer. We must be calling this "
236  "function a second time in which case we're going to lose the already "
237  "stored prewrapped buffer forever");
238  };
239 
240  // libMesh::out
241  if (auto * ob = libMesh::out.rdbuf(); ob)
242  {
243  check_stored_buffer(_out_prewrap_buf);
244  _out_prewrap_buf = ob;
246  std::make_unique<ThreadBufferedSyncbuf>(*ob, /*flush_on_newline=*/true);
248  }
249 
250  // libMesh::err
251  if (auto * eb = libMesh::err.rdbuf(); eb)
252  {
253  check_stored_buffer(_err_prewrap_buf);
254  _err_prewrap_buf = eb;
256  std::make_unique<ThreadBufferedSyncbuf>(*eb, /*flush_on_newline=*/true);
258  }
259 }
260 
261 // Uninstall before restoring/redirection teardown
263 {
265  {
266  // flush any thread-local leftovers on this thread
267  libMesh::out << std::flush;
269  _out_syncd_thread_buffer.reset();
270  _out_prewrap_buf = nullptr;
271  }
273  {
274  libMesh::err << std::flush;
276  _err_syncd_thread_buffer.reset();
277  _err_prewrap_buf = nullptr;
278  }
279 }
280 
281 bool warned_about_auto_ptr(false);
282 
283 PerfLog perflog ("libMesh",
284 #ifdef LIBMESH_ENABLE_PERFORMANCE_LOGGING
285  true
286 #else
287  false
288 #endif
289  );
290 
291 
292 #ifdef LIBMESH_USE_COMPLEX_NUMBERS
293 const Number imaginary (0., 1.);
294 // const Number zero (0., 0.);
295 #else
296 // const Number zero = 0.;
297 #endif
298 
299 // This is now a static constant in the header; no reason not to let
300 // the compiler inline it.
301 
302 // const unsigned int invalid_uint = static_cast<unsigned int>(-1);
303 
304 
305 
306 // ------------------------------------------------------------
307 // libMesh::libMeshPrivateData data initialization
308 #ifdef LIBMESH_HAVE_MPI
309 MPI_Errhandler libmesh_errhandler;
310 
313 #endif
314 int libMesh::libMeshPrivateData::_n_threads = 1; /* Threads::task_scheduler_init::automatic; */
317 #if defined(LIBMESH_HAVE_PETSC) // PETSc is the default
319 #elif defined(LIBMESH_TRILINOS_HAVE_AZTECOO) // Use Trilinos if PETSc isn't there
321 #elif defined(LIBMESH_HAVE_EIGEN) // Use Eigen if neither are there
323 #elif defined(LIBMESH_HAVE_LASPACK) // Use LASPACK as a last resort
325 #else // No valid linear solver package at compile time
327 #endif
328 
329 
330 
331 // ------------------------------------------------------------
332 // libMesh functions
333 
335 {
337 }
338 
339 
340 
341 bool closed()
342 {
344 }
345 
346 
347 #ifdef LIBMESH_ENABLE_EXCEPTIONS
348 std::terminate_handler old_terminate_handler;
349 #endif
350 
352 {
353 #ifdef LIBMESH_ENABLE_EXCEPTIONS
354  // If we have an active exception, it may have an error message that
355  // we should print.
356  libMesh::err << "libMesh terminating";
357  std::exception_ptr ex = std::current_exception();
358  if (ex)
359  {
360  try
361  {
362  std::rethrow_exception(ex);
363  }
364  catch (const std::exception & std_ex)
365  {
366  libMesh::err << ":\n" << std_ex.what();
367  }
368  }
369  libMesh::err << std::endl;
370 #endif
371 
372  // If this got called then we're probably crashing; let's print a
373  // stack trace. The trace files that are ultimately written depend on:
374  // 1.) Who throws the exception.
375  // 2.) Whether the C++ runtime unwinds the stack before the
376  // terminate_handler is called (this is implementation defined).
377  //
378  // The various cases are summarized in the table below:
379  //
380  // | libmesh exception | other exception
381  // -------------------------------------
382  // stack unwinds | A | B
383  // stack does not unwind | C | D
384  //
385  // Case A: There will be two stack traces in the file: one "useful"
386  // one, and one nearly empty one due to stack unwinding.
387  // Case B: You will get one nearly empty stack trace (not great, Bob!)
388  // Case C: You will get two nearly identical stack traces, ignore one of them.
389  // Case D: You will get one useful stack trace.
390  //
391  // Cases A and B (where the stack unwinds when an exception leaves
392  // main) appear to be non-existent in practice. I don't have a
393  // definitive list, but the stack does not unwind for GCC on either
394  // Mac or Linux. I think there's good reasons for this behavior too:
395  // it's much easier to get a stack trace when the stack doesn't
396  // unwind, for example.
398 
399  // We may care about performance data pre-crash; it would be sad to
400  // throw that away.
403 
404  // If we have MPI and it has been initialized, we need to be sure
405  // and call MPI_Abort instead of std::abort, so that the parallel
406  // job can die nicely.
407 #if defined(LIBMESH_HAVE_MPI)
408  int mpi_initialized;
409  MPI_Initialized (&mpi_initialized);
410 
411  if (mpi_initialized)
412  MPI_Abort(libMesh::GLOBAL_COMM_WORLD, 1);
413 #endif
414 
415 #ifdef LIBMESH_ENABLE_EXCEPTIONS
416  // The system terminate_handler may do useful things, or the user
417  // may have set their own terminate handler that we want to call.
419 #endif
420 
421  // The last attempt to die if nothing else has killed us
422  std::abort();
423 }
424 
425 
426 
427 LibMeshInit::LibMeshInit (int argc, const char * const * argv,
428  TIMPI::communicator COMM_WORLD_IN, int n_threads)
429 {
430  // should _not_ be initialized already.
432 
433  // Build a command-line parser.
434  command_line = std::make_unique<GetPot>(argc, argv);
435 
436  // Disable performance logging upon request
437  {
438  if (libMesh::on_command_line ("--disable-perflog"))
439  libMesh::perflog.disable_logging();
440  }
441 
442  auto check_empty_command_line_value = [](auto & cl, const std::string & option) {
443  libmesh_error_msg_if(cl.search(option),
444  "Detected option " << option << " with no value. Did you forget '='?");
445  };
446 
447  // Build a task scheduler
448  {
449  // Get the requested number of threads, defaults to 1 to avoid MPI and
450  // multithreading competition. If you would like to use MPI and multithreading
451  // at the same time then (n_mpi_processes_per_node)x(n_threads) should be the
452  // number of processing cores per node.
453  std::vector<std::string> n_threads_opt(2);
454  n_threads_opt[0] = "--n_threads";
455  n_threads_opt[1] = "--n-threads";
457  libMesh::command_line_value(n_threads_opt, n_threads);
458 
460  {
461  for (auto & option : n_threads_opt)
462  check_empty_command_line_value(*command_line, option);
463 
465  }
466 
467  // If there's no threading model active, force _n_threads==1
468 #if !LIBMESH_USING_THREADS
470  {
472  libmesh_warning("Warning: You requested --n-threads>1 but no threading model is active!\n"
473  << "Forcing --n-threads==1 instead!");
474  }
475 #endif
476 
477  // Set the number of OpenMP threads to the same as the number of threads libMesh is going to use
478 #ifdef LIBMESH_HAVE_OPENMP
479  omp_set_num_threads(libMesh::libMeshPrivateData::_n_threads);
480 #endif
481 
482  task_scheduler = std::make_unique<Threads::task_scheduler_init>(libMesh::n_threads());
483  }
484 
485  // Construct singletons who may be at risk of the
486  // "static initialization order fiasco"
488 
489  // Make sure the construction worked
491 
492  const bool using_threads = libMesh::n_threads() > 1;
493  const bool handle_mpi_errors = false; // libMesh does this
494 
495 #if defined(LIBMESH_HAVE_MPI)
496 
497  // Allow the user to bypass MPI initialization
498  if (!libMesh::on_command_line ("--disable-mpi"))
499  {
500  int mpi_thread_request = using_threads;
501  const auto mpi_thread_type = libMesh::command_line_value("--mpi-thread-type", std::string(""));
502  if (mpi_thread_type.empty())
503  {
504  check_empty_command_line_value(*command_line, "--mpi-thread-type");
505 #if defined(PETSC_HAVE_STRUMPACK) && defined(PETSC_HAVE_SLATE)
506  // For GPU computations, the solver strumpack uses slate which always requests
507  // MPI_THREAD_MULTIPLE. The solution here is not perfect because the run may never be
508  // using strumpack, but we believe it's better to force the MPI library to use locks
509  // whenever it accesses the message queue, that is, when processing any sends and receive,
510  // than it is to require users to pre-announce/signal what solvers they are using through
511  // --mpi-thread-type
512  mpi_thread_request = 3;
513 #endif
514  }
515  else
516  {
517  if (mpi_thread_type == "single")
518  {
519  if (using_threads)
520  libmesh_error_msg("We are using threads, so we require more mpi thread support "
521  "than '--mpi-thread-type=single'");
522  mpi_thread_request = 0;
523  }
524  else if (mpi_thread_type == "funneled")
525  mpi_thread_request = 1;
526  else if (mpi_thread_type == "serialized")
527  mpi_thread_request = 2;
528  else if (mpi_thread_type == "multiple")
529  mpi_thread_request = 3;
530  else
531  libmesh_error_msg(
532  "Unsupported mpi thread type '"
533  << mpi_thread_type
534  << "'. Allowed options are 'single', 'funneled', 'serialized', and 'multiple'");
535  }
536 
537  this->_timpi_init =
538  new TIMPI::TIMPIInit(argc, argv, mpi_thread_request,
539  handle_mpi_errors, COMM_WORLD_IN);
540  _comm = new Parallel::Communicator(this->_timpi_init->comm().get());
541 
542  const std::string timpi_sync =
543  libMesh::command_line_value("--timpi-sync", std::string("nbx"));
544  _comm->sync_type(timpi_sync);
545 
546  libMesh::GLOBAL_COMM_WORLD = COMM_WORLD_IN;
547 
548  //MPI_Comm_set_name not supported in at least SGI MPT's MPI implementation
549  //MPI_Comm_set_name (libMesh::COMM_WORLD, "libMesh::COMM_WORLD");
550 
552  cast_int<processor_id_type>(this->comm().rank());
554  cast_int<processor_id_type>(this->comm().size());
555 
556  // Set up an MPI error handler if requested. This helps us get
557  // into a debugger with a proper stack when an MPI error occurs.
558  if (libMesh::on_command_line ("--handle-mpi-errors"))
559  {
560  timpi_call_mpi
561  (MPI_Comm_create_errhandler(libMesh_MPI_Handler, &libmesh_errhandler));
562  timpi_call_mpi
563  (MPI_Comm_set_errhandler(libMesh::GLOBAL_COMM_WORLD, libmesh_errhandler));
564  timpi_call_mpi
565  (MPI_Comm_set_errhandler(MPI_COMM_WORLD, libmesh_errhandler));
566  }
567  }
568 
569  // Could we have gotten bad values from the above calls?
570  libmesh_assert_greater (libMeshPrivateData::_n_processors, 0);
571 
572  // The cast_int already tested _processor_id>=0
573  // libmesh_assert_greater_equal (libMeshPrivateData::_processor_id, 0);
574 
575  // Let's be sure we properly initialize on every processor at once:
576  libmesh_parallel_only(this->comm());
577 
578 #else
579  libmesh_ignore(COMM_WORLD_IN);
580  this->_timpi_init =
581  new TIMPI::TIMPIInit(argc, argv, using_threads,
582  handle_mpi_errors);
583  _comm = new Parallel::Communicator(this->_timpi_init->comm().get());
584 #endif
585 
586 #if defined(LIBMESH_HAVE_PETSC)
587 
588  // Allow the user to bypass PETSc initialization
589  if (!libMesh::on_command_line ("--disable-petsc")
590 
591 #if defined(LIBMESH_HAVE_MPI)
592  // If the user bypassed MPI, we'd better be safe and assume that
593  // PETSc was built to require it; otherwise PETSc initialization
594  // dies.
595  && !libMesh::on_command_line ("--disable-mpi")
596 #endif
597  )
598  {
599 #ifdef LIBMESH_HAVE_MPI
600  PETSC_COMM_WORLD = libMesh::GLOBAL_COMM_WORLD;
601 #else
602  // PETSc --with-mpi=0 doesn't like our default "communicator" 0
603  this->_comm->get() = PETSC_COMM_SELF;
604 #endif
605 
606  // Check whether the calling program has already initialized
607  // PETSc, and avoid duplicate Initialize/Finalize
608  PetscBool petsc_already_initialized;
609  LibmeshPetscCallA(libMesh::GLOBAL_COMM_WORLD, PetscInitialized(&petsc_already_initialized));
610  if (petsc_already_initialized != PETSC_TRUE)
611  libmesh_initialized_petsc = true;
612 # if defined(LIBMESH_HAVE_SLEPC)
613 
614  // If SLEPc allows us to check whether the calling program
615  // has already initialized it, we do that, and avoid
616  // duplicate Initialize/Finalize.
617  // We assume that SLEPc will handle PETSc appropriately,
618  // which it does in the versions we've checked.
619  if (!SlepcInitializeCalled)
620  {
621  LibmeshPetscCallA(libMesh::GLOBAL_COMM_WORLD, SlepcInitialize (&argc, const_cast<char ***>(&argv), nullptr, nullptr));
622  libmesh_initialized_slepc = true;
623  }
624 # else
625  if (libmesh_initialized_petsc)
626  LibmeshPetscCallA(libMesh::GLOBAL_COMM_WORLD, PetscInitialize (&argc, const_cast<char ***>(&argv), nullptr, nullptr));
627 # endif
628  // Register the reference implementation of DMlibMesh
629  LibmeshPetscCallA(libMesh::GLOBAL_COMM_WORLD, DMRegister(DMLIBMESH, DMCreate_libMesh));
630  }
631 #endif
632 
633 #ifdef LIBMESH_HAVE_NETGEN
634  nglib::Ng_Init();
635 #endif
636 
637 #if defined(LIBMESH_HAVE_MPI) && defined(LIBMESH_HAVE_VTK)
638  // Do MPI initialization for VTK.
639  _vtk_mpi_controller = vtkMPIController::New();
640  _vtk_mpi_controller->Initialize(&argc, const_cast<char ***>(&argv), /*initialized_externally=*/1);
641  _vtk_mpi_controller->SetGlobalController(_vtk_mpi_controller);
642 #endif
643 
644  // Re-parse the command-line arguments. Note that PETSc and MPI
645  // initialization above may have removed command line arguments
646  // that are not relevant to this application in the above calls.
647  // We don't want a false-positive by detecting those arguments.
648  //
649  // Note: this seems overly paranoid/like it should be unnecessary,
650  // plus we were doing it wrong for many years and not clearing the
651  // existing GetPot object before re-parsing the command line, so all
652  // the command line arguments appeared twice in the GetPot object...
653  command_line = std::make_unique<GetPot>(argc, argv);
654 
655  // Not syncing with stdio is an optimization when simultaneous
656  // C and C++ style access to output streams is not required.
657  // The amount of benefit which occurs is probably implementation
658  // defined, and may be nothing. On the other hand, I have seen
659  // some IO tests where IO performance improves by a factor of two.
660  // However, not syncing the streams means thread safety is no longer
661  // guaranteed and we have indeed seen thread sanitizer warnings
662  // during concurrent writes to std::cout when toggling this boolean
663  // to true. We default to preferring safety and correctness instead
664  // of performance
665  if (libMesh::on_command_line ("--dont-sync-with-stdio"))
666  std::ios::sync_with_stdio(false);
667 
668  // Honor the --separate-libmeshout command-line option.
669  // When this is specified, the library uses an independent ostream
670  // for libMesh::out/libMesh::err messages, and
671  // std::cout and std::cerr are untouched by any other options
672  if (libMesh::on_command_line ("--separate-libmeshout"))
673  {
674  // Redirect. We'll share streambufs with cout/cerr for now, but
675  // presumably anyone using this option will want to replace the
676  // bufs later.
677  std::ostream * newout = new std::ostream(std::cout.rdbuf());
678  libMesh::out = *newout;
679  std::ostream * newerr = new std::ostream(std::cerr.rdbuf());
680  libMesh::err = *newerr;
681  }
682 
683  // Process command line arguments for redirecting stdout/stderr.
684  bool
685  cmdline_has_redirect_stdout = libMesh::on_command_line ("--redirect-stdout"),
686  cmdline_has_redirect_output = libMesh::on_command_line ("--redirect-output");
687 
688  // The --redirect-stdout command-line option has been deprecated in
689  // favor of "--redirect-output basename".
690  if (cmdline_has_redirect_stdout)
691  libmesh_warning("The --redirect-stdout command line option has been deprecated. "
692  "Use '--redirect-output basename' instead.");
693 
694  // Honor the "--redirect-stdout" and "--redirect-output basename"
695  // command-line options. When one of these is specified, each
696  // processor sends libMesh::out/libMesh::err messages to
697  // stdout.processor.#### (default) or basename.processor.####.
698  if (cmdline_has_redirect_stdout || cmdline_has_redirect_output)
699  {
700  std::string basename = "stdout";
701 
702  // Look for following argument if using new API
703  if (cmdline_has_redirect_output)
704  {
705  // Set the cursor to the correct location in the list of command line arguments.
706  command_line->search(1, "--redirect-output");
707 
708  // Get the next option on the command line as a string.
709  std::string next_string = "";
710  next_string = command_line->next(next_string);
711 
712  // If the next string starts with a dash, we assume it's
713  // another flag and not a file basename requested by the
714  // user.
715  if (next_string.size() > 0 && next_string.find_first_of("-") != 0)
716  basename = next_string;
717  }
718 
719  std::ostringstream filename;
720  filename << basename << ".processor." << libMesh::global_processor_id();
721  _ofstream = std::make_unique<std::ofstream>(filename.str().c_str());
722 
723  // Redirect, saving the original streambufs!
724  out_buf = libMesh::out.rdbuf (_ofstream->rdbuf());
725  err_buf = libMesh::err.rdbuf (_ofstream->rdbuf());
726  }
727 
728  // redirect libMesh::out to nothing on all
729  // other processors unless explicitly told
730  // not to via the --keep-cout command-line argument.
731  if (!libMesh::on_command_line ("--keep-cout"))
732  if (libMesh::global_processor_id() != 0)
733  libMesh::out.rdbuf (nullptr);
734 
735  // Similarly, the user can request to drop cerr on all non-0 ranks.
736  // By default, errors are printed on all ranks, but this can lead to
737  // interleaved/unpredictable outputs when doing parallel regression
738  // testing, which this option is designed to support.
739  if (libMesh::on_command_line ("--drop-cerr"))
740  if (libMesh::global_processor_id() != 0)
741  libMesh::err.rdbuf (nullptr);
742 
743  // Now that we've finished setting our stream buffers, let's wrap them (if they're non-null) in our thread-safe wrapper
744  if (!libMesh::on_command_line ("--disable-thread-safe-output"))
746 
747  // Check command line to override printing
748  // of reference count information.
749  if (libMesh::on_command_line("--disable-refcount-printing"))
751 
752 #ifdef LIBMESH_ENABLE_EXCEPTIONS
753  // Set our terminate handler to write stack traces in the event of a
754  // crash
755  old_terminate_handler = std::set_terminate(libmesh_terminate_handler);
756 #endif
757 
758 
759  if (libMesh::on_command_line("--enable-fpe"))
760  libMesh::enableFPE(true);
761 
762  if (libMesh::on_command_line("--enable-segv"))
763  libMesh::enableSEGV(true);
764 
765 #if defined(LIBMESH_HAVE_HDF5) && !defined(_MSC_VER)
766  // We may be running with ExodusII configured not to use HDF5 (in
767  // which case user code which wants to lock files has to do flock()
768  // itself) or with ExodusII configured to use HDF5 (which will
769  // helpfully try to get an exclusive flock() itself, and then scream
770  // and die if user code has already locked the file. To get
771  // consistent behavior, we need to disable file locking. The only
772  // reliable way I can see to do this is via an HDF5 environment
773  // variable.
774  //
775  // If the user set this environment variable then we'll trust that
776  // they know what they're doing. If not then we'll set FALSE,
777  // because that's a better default for us than the unset default.
778  setenv("HDF5_USE_FILE_LOCKING", "FALSE", /*overwrite=false*/0);
779 #endif // LIBMESH_HAVE_HDF5
780 
781  // The library is now ready for use
783 
784 
785  // Make sure these work. Library methods
786  // depend on these being implemented properly,
787  // so this is a good time to test them!
790 }
791 
792 
793 
795 {
796  // Every processor had better be ready to exit at the same time.
797  // This would be a libmesh_parallel_only() function, except that
798  // libmesh_parallel_only() uses libmesh_assert() which throws an
799  // exception() which causes compilers to scream about exceptions
800  // inside destructors.
801 
802  // Even if we're not doing parallel_only debugging, we don't want
803  // one processor to try to exit until all others are done working.
804  this->comm().barrier();
805 
806  // We can't delete, finalize, etc. more than once without
807  // reinitializing in between
808  libmesh_exceptionless_assert(!libMesh::closed());
809 
810  // Delete reference counted singleton(s)
812 
813  // Clear the thread task manager we started
814  task_scheduler.reset();
815 
816  // Force the \p ReferenceCounter to print
817  // its reference count information. This allows
818  // us to find memory leaks. By default the
819  // \p ReferenceCounter only prints its information
820  // when the last created object has been destroyed.
821  // That does no good if we are leaking memory!
823 
824 
825  // Print an informative message if we detect a memory leak
826  if (ReferenceCounter::n_objects() != 0)
827  {
828  libMesh::err << "Memory leak detected!"
829  << std::endl;
830 
831 #if !defined(LIBMESH_ENABLE_REFERENCE_COUNTING) || defined(NDEBUG)
832 
833  libMesh::err << "Compile in DEBUG mode with --enable-reference-counting"
834  << std::endl
835  << "for more information"
836  << std::endl;
837 #endif
838 
839  }
840 
841  // print the perflog to individual processor's file.
843 
844  // Now clear the logging object, we don't want it to print
845  // a second time during the PerfLog destructor.
847 
848  // Reconnect the output streams
849  // (don't do this, or we will get messages from objects
850  // that go out of scope after the following return)
851  //std::cout.rdbuf(std::cerr.rdbuf());
852 
853 
854  // Set the initialized() flag to false
856 
857  // Before resetting the stream buffers, let's remove our thread wrappers
858  if (!libMesh::on_command_line ("--disable-thread-safe-output"))
860 
861  if (libMesh::on_command_line ("--redirect-stdout") ||
862  libMesh::on_command_line ("--redirect-output"))
863  {
864  // If stdout/stderr were redirected to files, reset them now.
865  libMesh::out.rdbuf (out_buf);
866  libMesh::err.rdbuf (err_buf);
867  }
868 
869  // If we built our own output streams, we want to clean them up.
870  if (libMesh::on_command_line ("--separate-libmeshout"))
871  {
872  delete libMesh::out.get();
873  delete libMesh::err.get();
874 
875  libMesh::out.reset(std::cout);
876  libMesh::err.reset(std::cerr);
877  }
878 
879 #ifdef LIBMESH_ENABLE_EXCEPTIONS
880  // Reset the old terminate handler; maybe the user code wants to
881  // keep doing C++ stuff after closing libMesh stuff.
882  std::set_terminate(old_terminate_handler);
883 #endif
884 
885 #ifdef LIBMESH_HAVE_NETGEN
886  nglib::Ng_Exit();
887 #endif
888 
889  if (libMesh::on_command_line("--enable-fpe"))
890  libMesh::enableFPE(false);
891 
892 #if defined(LIBMESH_HAVE_PETSC)
893  // Let PETSc know about all the command line objects that we
894  // consumed without asking them, so we don't get unused option
895  // warnings about those.
896  std::vector<std::string> cli_names = command_line_names();
897  for (const auto & name : cli_names)
898  if (!name.empty() && name[0] == '-')
899  {
900  // Newer PETSc can give me a double-free I'm having trouble
901  // replicating; let's protect against trying to clear
902  // already-used values
903  PetscBool used = PETSC_FALSE;
904  auto ierr = PetscOptionsUsed(NULL, name.c_str(), &used);
905  CHKERRABORT(libMesh::GLOBAL_COMM_WORLD, ierr);
906  if (used == PETSC_FALSE)
907  {
908  ierr = PetscOptionsClearValue(NULL, name.c_str());
909  CHKERRABORT(libMesh::GLOBAL_COMM_WORLD, ierr);
910  }
911  }
912 
913  // Allow the user to bypass PETSc finalization
914  if (!libMesh::on_command_line ("--disable-petsc")
915 #if defined(LIBMESH_HAVE_MPI)
916  && !libMesh::on_command_line ("--disable-mpi")
917 #endif
918  )
919  {
920  PetscErrorCode ierr = LIBMESH_PETSC_SUCCESS;
921 # if defined(LIBMESH_HAVE_SLEPC)
922  if (libmesh_initialized_slepc)
923  ierr = SlepcFinalize();
924 # else
925  if (libmesh_initialized_petsc)
926  ierr = PetscFinalize();
927 # endif
928  CHKERRABORT(libMesh::GLOBAL_COMM_WORLD, ierr);
929  }
930 #endif
931 
932 #if defined(LIBMESH_HAVE_MPI) && defined(LIBMESH_HAVE_VTK)
933  _vtk_mpi_controller->Finalize(/*finalized_externally=*/1);
934  _vtk_mpi_controller->Delete();
935 #endif
936 
937  delete this->_comm;
938 
939 #if defined(LIBMESH_HAVE_MPI)
940  // Allow the user to bypass MPI finalization
941  if (!libMesh::on_command_line ("--disable-mpi"))
942  {
943  delete this->_timpi_init;
944  }
945 #else
946  delete this->_timpi_init;
947 #endif
948 }
949 
950 
951 
955 void enableFPE(bool on)
956 {
957 #if !defined(LIBMESH_HAVE_FEENABLEEXCEPT) && defined(LIBMESH_HAVE_XMMINTRIN_H)
958  static int flags = 0;
959 #endif
960 
961  if (on)
962  {
963 #ifdef LIBMESH_HAVE_FEENABLEEXCEPT
964  feenableexcept(FE_DIVBYZERO | FE_INVALID);
965 #elif LIBMESH_HAVE_XMMINTRIN_H
966  flags = _MM_GET_EXCEPTION_MASK(); // store the flags
967  _MM_SET_EXCEPTION_MASK(flags & ~_MM_MASK_INVALID);
968 #endif
969 
970 #if LIBMESH_HAVE_DECL_SIGACTION
971  struct sigaction new_action, old_action;
972 
973  // Set up the structure to specify the new action.
974  new_action.sa_sigaction = libmesh_handleFPE;
975  sigemptyset (&new_action.sa_mask);
976  new_action.sa_flags = SA_SIGINFO;
977 
978  sigaction (SIGFPE, nullptr, &old_action);
979  if (old_action.sa_handler != SIG_IGN)
980  sigaction (SIGFPE, &new_action, nullptr);
981 #endif
982  }
983  else
984  {
985 #ifdef LIBMESH_HAVE_FEDISABLEEXCEPT
986  fedisableexcept(FE_DIVBYZERO | FE_INVALID);
987 #elif LIBMESH_HAVE_XMMINTRIN_H
988  _MM_SET_EXCEPTION_MASK(flags);
989 #endif
990  signal(SIGFPE, SIG_DFL);
991  }
992 }
993 
994 
995 // Enable handling of SIGSEGV by libMesh
996 // (potentially instead of PETSc)
997 void enableSEGV(bool on)
998 {
999 #if LIBMESH_HAVE_DECL_SIGACTION
1000  static struct sigaction old_action;
1001  static bool was_on = false;
1002 
1003  if (on)
1004  {
1005  struct sigaction new_action;
1006  was_on = true;
1007 
1008  // Set up the structure to specify the new action.
1009  new_action.sa_sigaction = libmesh_handleSEGV;
1010  sigemptyset (&new_action.sa_mask);
1011  new_action.sa_flags = SA_SIGINFO;
1012 
1013  sigaction (SIGSEGV, &new_action, &old_action);
1014  }
1015  else if (was_on)
1016  {
1017  was_on = false;
1018  sigaction (SIGSEGV, &old_action, nullptr);
1019  }
1020 #else
1021  libmesh_error_msg("System call sigaction not supported.");
1022 #endif
1023 }
1024 
1025 
1026 
1027 void add_command_line_name(const std::string & name)
1028 {
1029  // Users had better not be asking about an empty string
1030  libmesh_assert(!name.empty());
1031 
1032  static std::mutex command_line_names_mutex;
1033  std::scoped_lock lock(command_line_names_mutex);
1034 
1035  command_line_name_set.insert(name);
1036 }
1037 
1038 
1039 
1040 void add_command_line_names(const GetPot & getpot)
1041 {
1042  for (auto & getter : {&GetPot::get_requested_arguments,
1043  &GetPot::get_requested_variables,
1044  &GetPot::get_requested_sections})
1045  for (const std::string & name : (getpot.*getter)())
1047 }
1048 
1049 
1050 std::vector<std::string> command_line_names()
1051 {
1052  return std::vector<std::string>(command_line_name_set.begin(),
1053  command_line_name_set.end());
1054 }
1055 
1056 
1057 
1058 bool on_command_line (std::string arg)
1059 {
1060  // Make sure the command line parser is ready for use. If it's not,
1061  // then we'll have to treat the command line as empty, for maximum
1062  // compatibility with programs that don't use LibMeshInit but
1063  // indirectly (e.g. via error handling code) query the command line.
1064  if (!command_line.get())
1065  return false;
1066 
1067  // Keep track of runtime queries, for later
1068  add_command_line_name(arg);
1069 
1070  bool found_it = command_line->search(arg);
1071 
1072  if (!found_it)
1073  {
1074  // Try with all dashes instead of underscores
1075  std::replace(arg.begin(), arg.end(), '_', '-');
1076  found_it = command_line->search(arg);
1077  }
1078 
1079  if (!found_it)
1080  {
1081  // OK, try with all underscores instead of dashes
1082  auto name_begin = arg.begin();
1083  while (*name_begin == '-')
1084  ++name_begin;
1085  std::replace(name_begin, arg.end(), '-', '_');
1086  found_it = command_line->search(arg);
1087  }
1088 
1089  return found_it;
1090 }
1091 
1092 
1093 
1094 template <typename T>
1095 T command_line_value (const std::string & name, T value)
1096 {
1097  // Make sure the command line parser is ready for use
1098  libmesh_assert(command_line.get());
1099 
1100  // only if the variable exists in the file
1101  if (command_line->have_variable(name))
1102  {
1103  value = (*command_line)(name, value);
1104 
1105  // Keep track of runtime queries, for later. GetPot splits
1106  // foo=bar into a separate name=value, so we can query for the
1107  // name, but as far as PETSc is concerned that's one CLI
1108  // argument. We'll store it that way.
1109  const std::string stringvalue =
1110  (*command_line)(name, std::string());
1111  add_command_line_name(name+"="+stringvalue);
1112  }
1113 
1114  return value;
1115 }
1116 
1117 template <typename T>
1118 T command_line_value (const std::vector<std::string> & names, T value)
1119 {
1120  // Make sure the command line parser is ready for use
1121  libmesh_assert(command_line.get());
1122 
1123  // Keep track of runtime queries, for later
1124  for (const auto & entry : names)
1125  {
1126  // Keep track of runtime queries, for later. GetPot splits
1127  // foo=bar into a separate name=value, so we can query for the
1128  // name, but as far as PETSc is concerned that's one CLI
1129  // argument. We'll store it that way.
1130  const std::string stringvalue =
1131  (*command_line)(entry, std::string());
1132  add_command_line_name(entry+"="+stringvalue);
1133  }
1134 
1135  // Check for multiple options (return the first that matches)
1136  for (const auto & entry : names)
1137  if (command_line->have_variable(entry))
1138  {
1139  value = (*command_line)(entry, value);
1140  break;
1141  }
1142 
1143  return value;
1144 }
1145 
1146 
1147 
1148 template <typename T>
1149 T command_line_next (std::string name, T value)
1150 {
1151  // Make sure the command line parser is ready for use
1152  libmesh_assert(command_line.get());
1153 
1154  // Keep track of runtime queries, for later
1156 
1157  // on_command_line also puts the command_line cursor in the spot we
1158  // need
1159  if (on_command_line(name))
1160  return command_line->next(value);
1161 
1162  return value;
1163 }
1164 
1165 
1166 
1167 template <typename T>
1168 void command_line_vector (const std::string & name, std::vector<T> & vec)
1169 {
1170  // Make sure the command line parser is ready for use
1171  libmesh_assert(command_line.get());
1172 
1173  // Keep track of runtime queries, for later
1175 
1176  // only if the variable exists on the command line
1177  if (command_line->have_variable(name))
1178  {
1179  unsigned size = command_line->vector_variable_size(name);
1180  vec.resize(size);
1181 
1182  for (unsigned i=0; i<size; ++i)
1183  vec[i] = (*command_line)(name, vec[i], i);
1184  }
1185 }
1186 
1187 
1189 {
1191 
1192  static bool called = false;
1193 
1194  // Check the command line. Since the command line is
1195  // unchanging it is sufficient to do this only once.
1196  if (!called)
1197  {
1198  called = true;
1199 
1200 #ifdef LIBMESH_HAVE_PETSC
1201  if (libMesh::on_command_line ("--use-petsc"))
1203 #endif
1204 
1205 #ifdef LIBMESH_TRILINOS_HAVE_AZTECOO
1206  if (libMesh::on_command_line ("--use-trilinos") ||
1207  libMesh::on_command_line ("--disable-petsc"))
1209 #endif
1210 
1211 #ifdef LIBMESH_HAVE_EIGEN
1212  if (libMesh::on_command_line ("--use-eigen" ) ||
1213 #if defined(LIBMESH_HAVE_MPI)
1214  // If the user bypassed MPI, we disable PETSc and Trilinos
1215  // too
1216  libMesh::on_command_line ("--disable-mpi") ||
1217 #endif
1218  libMesh::on_command_line ("--disable-petsc"))
1220 #endif
1221 
1222 #ifdef LIBMESH_HAVE_LASPACK
1223  if (libMesh::on_command_line ("--use-laspack" ) ||
1224 #if defined(LIBMESH_HAVE_MPI)
1225  // If the user bypassed MPI, we disable PETSc and Trilinos
1226  // too
1227  libMesh::on_command_line ("--disable-mpi") ||
1228 #endif
1229  libMesh::on_command_line ("--disable-petsc"))
1231 #endif
1232 
1233  if (libMesh::on_command_line ("--disable-laspack") &&
1234  libMesh::on_command_line ("--disable-trilinos") &&
1235  libMesh::on_command_line ("--disable-eigen") &&
1236  (
1237 #if defined(LIBMESH_HAVE_MPI)
1238  // If the user bypassed MPI, we disable PETSc too
1239  libMesh::on_command_line ("--disable-mpi") ||
1240 #endif
1241  libMesh::on_command_line ("--disable-petsc")))
1243  }
1244 
1245 
1247 }
1248 
1249 
1250 
1251 //-------------------------------------------------------------------------------
1252 template LIBMESH_EXPORT unsigned char command_line_value<unsigned char> (const std::string &, unsigned char);
1253 template LIBMESH_EXPORT unsigned short command_line_value<unsigned short> (const std::string &, unsigned short);
1254 template LIBMESH_EXPORT unsigned int command_line_value<unsigned int> (const std::string &, unsigned int);
1255 template LIBMESH_EXPORT char command_line_value<char> (const std::string &, char);
1256 template LIBMESH_EXPORT short command_line_value<short> (const std::string &, short);
1257 template LIBMESH_EXPORT int command_line_value<int> (const std::string &, int);
1258 template LIBMESH_EXPORT float command_line_value<float> (const std::string &, float);
1259 template LIBMESH_EXPORT double command_line_value<double> (const std::string &, double);
1260 template LIBMESH_EXPORT long double command_line_value<long double> (const std::string &, long double);
1261 template LIBMESH_EXPORT std::string command_line_value<std::string> (const std::string &, std::string);
1262 
1263 template LIBMESH_EXPORT unsigned char command_line_value<unsigned char> (const std::vector<std::string> &, unsigned char);
1264 template LIBMESH_EXPORT unsigned short command_line_value<unsigned short> (const std::vector<std::string> &, unsigned short);
1265 template LIBMESH_EXPORT unsigned int command_line_value<unsigned int> (const std::vector<std::string> &, unsigned int);
1266 template LIBMESH_EXPORT char command_line_value<char> (const std::vector<std::string> &, char);
1267 template LIBMESH_EXPORT short command_line_value<short> (const std::vector<std::string> &, short);
1268 template LIBMESH_EXPORT int command_line_value<int> (const std::vector<std::string> &, int);
1269 template LIBMESH_EXPORT float command_line_value<float> (const std::vector<std::string> &, float);
1270 template LIBMESH_EXPORT double command_line_value<double> (const std::vector<std::string> &, double);
1271 template LIBMESH_EXPORT long double command_line_value<long double> (const std::vector<std::string> &, long double);
1272 template LIBMESH_EXPORT std::string command_line_value<std::string> (const std::vector<std::string> &, std::string);
1273 
1274 template LIBMESH_EXPORT unsigned char command_line_next<unsigned char> (std::string, unsigned char);
1275 template LIBMESH_EXPORT unsigned short command_line_next<unsigned short> (std::string, unsigned short);
1276 template LIBMESH_EXPORT unsigned int command_line_next<unsigned int> (std::string, unsigned int);
1277 template LIBMESH_EXPORT char command_line_next<char> (std::string, char);
1278 template LIBMESH_EXPORT short command_line_next<short> (std::string, short);
1279 template LIBMESH_EXPORT int command_line_next<int> (std::string, int);
1280 template LIBMESH_EXPORT float command_line_next<float> (std::string, float);
1281 template LIBMESH_EXPORT double command_line_next<double> (std::string, double);
1282 template LIBMESH_EXPORT long double command_line_next<long double> (std::string, long double);
1283 template LIBMESH_EXPORT std::string command_line_next<std::string> (std::string, std::string);
1284 
1285 template LIBMESH_EXPORT void command_line_vector<unsigned char> (const std::string &, std::vector<unsigned char> &);
1286 template LIBMESH_EXPORT void command_line_vector<unsigned short>(const std::string &, std::vector<unsigned short> &);
1287 template LIBMESH_EXPORT void command_line_vector<unsigned int> (const std::string &, std::vector<unsigned int> &);
1288 template LIBMESH_EXPORT void command_line_vector<char> (const std::string &, std::vector<char> &);
1289 template LIBMESH_EXPORT void command_line_vector<short> (const std::string &, std::vector<short> &);
1290 template LIBMESH_EXPORT void command_line_vector<int> (const std::string &, std::vector<int> &);
1291 template LIBMESH_EXPORT void command_line_vector<float> (const std::string &, std::vector<float> &);
1292 template LIBMESH_EXPORT void command_line_vector<double> (const std::string &, std::vector<double> &);
1293 template LIBMESH_EXPORT void command_line_vector<long double> (const std::string &, std::vector<long double> &);
1294 
1295 #ifdef LIBMESH_DEFAULT_QUADRUPLE_PRECISION
1296 template LIBMESH_EXPORT Real command_line_value<Real> (const std::string &, Real);
1297 template LIBMESH_EXPORT Real command_line_value<Real> (const std::vector<std::string> &, Real);
1298 template LIBMESH_EXPORT Real command_line_next<Real> (std::string, Real);
1299 template LIBMESH_EXPORT void command_line_vector<Real> (const std::string &, std::vector<Real> &);
1300 #endif
1301 
1302 } // namespace libMesh
template LIBMESH_EXPORT Real command_line_value< Real >(const std::string &, Real)
std::string name(const ElemQuality q)
This function returns a string containing some name for q.
Definition: elem_quality.C:42
OStreamProxy err
template LIBMESH_EXPORT double command_line_value< double >(const std::string &, double)
std::unique_ptr< ThreadBufferedSyncbuf > _err_syncd_thread_buffer
Definition: libmesh.C:226
T command_line_next(std::string name, T default_value)
Use GetPot&#39;s search()/next() functions to get following arguments from the command line...
Definition: libmesh.C:1149
template LIBMESH_EXPORT char command_line_value< char >(const std::string &, char)
bool closed()
Checks that the library has been closed.
Definition: libmesh.C:341
void install_thread_buffered_sync()
Definition: libmesh.C:231
static unsigned int n_objects()
Prints the number of outstanding (created, but not yet destroyed) objects.
std::streambuf * _out_prewrap_buf
Definition: libmesh.C:227
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
void sync_type(const SyncType st)
MPI_Info info
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:997
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:311
void barrier() const
bool warned_about_auto_ptr
template LIBMESH_EXPORT void command_line_vector< unsigned char >(const std::string &, std::vector< unsigned char > &)
processor_id_type rank() const
PerfLog perflog
A PerfLog object to log performance.
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.
template LIBMESH_EXPORT float command_line_value< float >(const std::string &, float)
The libMesh namespace provides an interface to certain functionality in the library.
void write_traceout()
Writes a stack trace to a uniquely named file if –enable-tracefiles has been set by configure...
Definition: print_trace.C:240
void reset(streamT &target)
Reset the proxy to point to a different target.
int _n_threads
Total number of threads possible.
Definition: libmesh.C:314
vtkMPIController * _vtk_mpi_controller
Definition: libmesh.h:148
static void setup()
Setup function.
EXTERN_C_BEGIN PETSC_EXTERN PetscErrorCode DMCreate_libMesh(DM)
uint8_t processor_id_type
Definition: id_types.h:104
const Number imaginary
The imaginary unit, .
const Parallel::Communicator & comm() const
Returns a Communicator created from the TIMPIInit object we hold, which will be a compatibility shim ...
Definition: libmesh.h:128
SolverPackage default_solver_package()
Definition: libmesh.C:1188
processor_id_type size() const
template LIBMESH_EXPORT void command_line_vector< int >(const std::string &, std::vector< int > &)
void libmesh_ignore(const Args &...)
std::unique_ptr< ThreadBufferedSyncbuf > _out_syncd_thread_buffer
Definition: libmesh.C:225
T command_line_value(const std::string &, T)
Definition: libmesh.C:1095
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:315
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)
template LIBMESH_EXPORT void command_line_vector< short >(const std::string &, std::vector< short > &)
virtual ~LibMeshInit()
Destructor.
Definition: libmesh.C:794
template LIBMESH_EXPORT int command_line_value< int >(const std::string &, int)
std::terminate_handler old_terminate_handler
Definition: libmesh.C:348
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:312
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)
BasicOStreamProxy OStreamProxy
libmesh_assert(ctx)
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)
std::streambuf * _err_prewrap_buf
Definition: libmesh.C:228
Definition: libmesh.C:90
template LIBMESH_EXPORT short command_line_next< short >(std::string, short)
streambufT * rdbuf() const
Get the associated stream buffer.
communicator & get()
template LIBMESH_EXPORT unsigned short command_line_value< unsigned short >(const std::string &, unsigned short)
MPI_Errhandler libmesh_errhandler
Definition: libmesh.C:309
TIMPI::TIMPIInit * _timpi_init
Definition: libmesh.h:135
void clear()
Clears all the internal data and restores the data structures to a pristine state.
Definition: perf_log.C:78
void enableFPE(bool on)
Toggle hardware trap floating point exceptions.
Definition: libmesh.C:955
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void add_command_line_names(const GetPot &getpot)
Merge a GetPot object&#39;s requested names into the set of queried command-line names.
Definition: libmesh.C:1040
void add_command_line_name(const std::string &name)
Add a name to the set of queried command-line names.
Definition: libmesh.C:1027
DIE A HORRIBLE DEATH HERE typedef MPI_Comm communicator
void command_line_vector(const std::string &, std::vector< T > &)
Definition: libmesh.C:1168
OStreamProxy out
std::vector< std::string > command_line_names()
Definition: libmesh.C:1050
processor_id_type global_processor_id()
Definition: libmesh_base.h:85
static const bool value
Definition: xdr_io.C:55
void print_log() const
Print the log.
Definition: perf_log.C:697
bool initialized()
Checks that library initialization has been done.
Definition: libmesh.C:334
void libMesh_MPI_Handler(MPI_Comm *, int *,...)
Definition: libmesh.C:182
streamT * get()
Rather than implement every ostream/ios/ios_base function, we&#39;ll be lazy and make esoteric uses go th...
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:1058
SolverPackage
Defines an enum for various linear solver packages.
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:316
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)
void uninstall_thread_buffered_sync()
Definition: libmesh.C:262
void ErrorVector unsigned int
Definition: adjoints_ex3.C:360
const Communicator & comm() const
template LIBMESH_EXPORT void command_line_vector< Real >(const std::string &, std::vector< Real > &)
void libmesh_terminate_handler()
A terminate handler.
Definition: libmesh.C:351
Parallel::Communicator * _comm
Definition: libmesh.h:142
const RemoteElem * remote_elem
Definition: remote_elem.C:57