libMesh
Public Member Functions | Private Attributes | List of all members
libMesh::LibMeshInit Class Reference

The LibMeshInit class, when constructed, initializes the dependent libraries (e.g. More...

#include <libmesh.h>

Public Member Functions

 LibMeshInit (int argc, const char *const *argv, MPI_Comm COMM_WORLD_IN=MPI_COMM_WORLD)
 Initialize the library for use, with the command line options provided. More...
 
 LibMeshInit (int argc, const char *const *argv)
 
virtual ~LibMeshInit ()
 
const Parallel::Communicatorcomm () const
 
Parallel::Communicatorcomm ()
 

Private Attributes

Parallel::Communicator _comm
 
vtkMPIController * _vtk_mpi_controller
 

Detailed Description

The LibMeshInit class, when constructed, initializes the dependent libraries (e.g.

MPI or PETSC) and does the command line parsing needed by libMesh. The LibMeshInit destructor closes those libraries properly.

For most users, a single LibMeshInit object should be created at the start of your main() function. This object replaces the previous

libMesh::init()/libMesh::close()

methods, which are now deprecated.

Definition at line 62 of file libmesh.h.

Constructor & Destructor Documentation

libMesh::LibMeshInit::LibMeshInit ( int  argc,
const char *const *  argv,
MPI_Comm  COMM_WORLD_IN = MPI_COMM_WORLD 
)

Initialize the library for use, with the command line options provided.

This will e.g. call PetscInitialize if PETSC is available. You must create a LibMeshInit object before using any of the library functionality. This method may take an optional parameter to use a user-specified MPI communicator.

libMesh::LibMeshInit::LibMeshInit ( int  argc,
const char *const *  argv 
)

Definition at line 345 of file libmesh.C.

References libMesh::libMeshPrivateData::_is_initialized, libMesh::libMeshPrivateData::_n_processors, libMesh::libMeshPrivateData::_processor_id, libMesh::Singleton::cleanup(), libMesh::PerfLog::clear(), libMesh::closed(), libMesh::COMM_WORLD, libMesh::command_line_value(), libMesh::PerfLog::disable_logging(), libMesh::ReferenceCounter::disable_print_counter_info(), DMCreate_libMesh(), libMesh::enableFPE(), libMesh::enableSEGV(), libMesh::err, libMesh::BasicOStreamProxy< charT, traits >::get(), libMesh::GLOBAL_COMM_WORLD, libMesh::global_processor_id(), ierr, libMesh::initialized(), libMesh::libmesh_assert(), libMesh_MPI_Handler(), libmesh_nullptr, libMesh::libmesh_terminate_handler(), libMesh::ReferenceCounter::n_objects(), libMesh::n_threads(), libMesh::on_command_line(), libMesh::out, libMesh::perflog, libMesh::ReferenceCounter::print_info(), libMesh::PerfLog::print_log(), libMesh::BasicOStreamProxy< charT, traits >::rdbuf(), libMesh::remote_elem, libMesh::BasicOStreamProxy< charT, traits >::reset(), libMesh::Singleton::setup(), and ~LibMeshInit().

350 {
351  // should _not_ be initialized already.
353 
354  // Build a command-line parser.
355  command_line.reset (new GetPot (argc, argv));
356 
357  // Disable performance logging upon request
358  {
359  if (libMesh::on_command_line ("--disable-perflog"))
361  }
362 
363  // Build a task scheduler
364  {
365  // Get the requested number of threads, defaults to 1 to avoid MPI and
366  // multithreading competition. If you would like to use MPI and multithreading
367  // at the same time then (n_mpi_processes_per_node)x(n_threads) should be the
368  // number of processing cores per node.
369  std::vector<std::string> n_threads(2);
370  n_threads[0] = "--n_threads";
371  n_threads[1] = "--n-threads";
374 
375  // If there's no threading model active, force _n_threads==1
376 #if !LIBMESH_USING_THREADS
378  {
380  libmesh_warning("Warning: You requested --n-threads>1 but no threading model is active!\n"
381  << "Forcing --n-threads==1 instead!");
382  }
383 #endif
384 
385  // Set the number of OpenMP threads to the same as the number of threads libMesh is going to use
386 #ifdef LIBMESH_HAVE_OPENMP
387  omp_set_num_threads(libMesh::libMeshPrivateData::_n_threads);
388 #endif
389 
390  task_scheduler.reset (new Threads::task_scheduler_init(libMesh::n_threads()));
391  }
392 
393  // Construct singletons who may be at risk of the
394  // "static initialization order fiasco"
396 
397  // Make sure the construction worked
399 
400 #if defined(LIBMESH_HAVE_MPI)
401 
402  // Allow the user to bypass MPI initialization
403  if (!libMesh::on_command_line ("--disable-mpi"))
404  {
405  // Check whether the calling program has already initialized
406  // MPI, and avoid duplicate Init/Finalize
407  int flag;
408  libmesh_call_mpi(MPI_Initialized (&flag));
409 
410  if (!flag)
411  {
412 #if MPI_VERSION > 1
413  int mpi_thread_provided;
414  const int mpi_thread_requested = libMesh::n_threads() > 1 ?
415  MPI_THREAD_FUNNELED :
416  MPI_THREAD_SINGLE;
417 
418  libmesh_call_mpi
419  (MPI_Init_thread (&argc, const_cast<char ***>(&argv),
420  mpi_thread_requested, &mpi_thread_provided));
421 
422  if ((libMesh::n_threads() > 1) &&
423  (mpi_thread_provided < MPI_THREAD_FUNNELED))
424  {
425  libmesh_warning("Warning: MPI failed to guarantee MPI_THREAD_FUNNELED\n"
426  << "for a threaded run.\n"
427  << "Be sure your library is funneled-thread-safe..."
428  << std::endl);
429 
430  // Ideally, if an MPI stack tells us it's unsafe for us
431  // to use threads, we shouldn't use threads.
432  // In practice, we've encountered one MPI stack (an
433  // mvapich2 configuration) that returned
434  // MPI_THREAD_SINGLE as a proper warning, two stacks
435  // that handle MPI_THREAD_FUNNELED properly, and two
436  // current stacks plus a couple old stacks that return
437  // MPI_THREAD_SINGLE but support libMesh threaded runs
438  // anyway.
439 
440  // libMesh::libMeshPrivateData::_n_threads = 1;
441  // task_scheduler.reset (new Threads::task_scheduler_init(libMesh::n_threads()));
442  }
443 #else
445  {
446  libmesh_warning("Warning: using MPI1 for threaded code.\n" <<
447  "Be sure your library is funneled-thread-safe..." <<
448  std::endl);
449  }
450 
451  libmesh_call_mpi
452  (MPI_Init (&argc, const_cast<char ***>(&argv)));
453 #endif
454  libmesh_initialized_mpi = true;
455  }
456 
457  // Duplicate the input communicator for internal use
458  // And get a Parallel::Communicator copy too, to use
459  // as a default for that API
460  this->_comm = COMM_WORLD_IN;
461 
462  libMesh::GLOBAL_COMM_WORLD = COMM_WORLD_IN;
463 
464 #ifndef LIBMESH_DISABLE_COMMWORLD
465  libMesh::COMM_WORLD = COMM_WORLD_IN;
466  Parallel::Communicator_World = COMM_WORLD_IN;
467 #endif
468 
469  //MPI_Comm_set_name not supported in at least SGI MPT's MPI implementation
470  //MPI_Comm_set_name (libMesh::COMM_WORLD, "libMesh::COMM_WORLD");
471 
473  cast_int<processor_id_type>(this->comm().rank());
475  cast_int<processor_id_type>(this->comm().size());
476 
477  // Set up an MPI error handler if requested. This helps us get
478  // into a debugger with a proper stack when an MPI error occurs.
479  if (libMesh::on_command_line ("--handle-mpi-errors"))
480  {
481 #if MPI_VERSION > 1
482  libmesh_call_mpi
483  (MPI_Comm_create_errhandler(libMesh_MPI_Handler, &libmesh_errhandler));
484  libmesh_call_mpi
485  (MPI_Comm_set_errhandler(libMesh::GLOBAL_COMM_WORLD, libmesh_errhandler));
486  libmesh_call_mpi
487  (MPI_Comm_set_errhandler(MPI_COMM_WORLD, libmesh_errhandler));
488 #else
489  libmesh_call_mpi
490  (MPI_Errhandler_create(libMesh_MPI_Handler, &libmesh_errhandler));
491  libmesh_call_mpi
492  (MPI_Errhandler_set(libMesh::GLOBAL_COMM_WORLD, libmesh_errhandler));
493  libmesh_call_mpi
494  (MPI_Errhandler_set(MPI_COMM_WORLD, libmesh_errhandler));
495 #endif // #if MPI_VERSION > 1
496  }
497  }
498 
499  // Could we have gotten bad values from the above calls?
500  libmesh_assert_greater (libMeshPrivateData::_n_processors, 0);
501 
502  // The cast_int already tested _processor_id>=0
503  // libmesh_assert_greater_equal (libMeshPrivateData::_processor_id, 0);
504 
505  // Let's be sure we properly initialize on every processor at once:
506  libmesh_parallel_only(this->comm());
507 
508 #endif
509 
510 #if defined(LIBMESH_HAVE_PETSC)
511 
512  // Allow the user to bypass PETSc initialization
513  if (!libMesh::on_command_line ("--disable-petsc")
514 
515 #if defined(LIBMESH_HAVE_MPI)
516  // If the user bypassed MPI, we'd better be safe and assume that
517  // PETSc was built to require it; otherwise PETSc initialization
518  // dies.
519  && !libMesh::on_command_line ("--disable-mpi")
520 #endif
521  )
522  {
523  int ierr=0;
524 
525  PETSC_COMM_WORLD = libMesh::GLOBAL_COMM_WORLD;
526 
527  // Check whether the calling program has already initialized
528  // PETSc, and avoid duplicate Initialize/Finalize
529  PetscBool petsc_already_initialized;
530  ierr = PetscInitialized(&petsc_already_initialized);
531  CHKERRABORT(libMesh::GLOBAL_COMM_WORLD,ierr);
532  if (petsc_already_initialized != PETSC_TRUE)
533  libmesh_initialized_petsc = true;
534 # if defined(LIBMESH_HAVE_SLEPC)
535 
536  // If SLEPc allows us to check whether the calling program
537  // has already initialized it, we do that, and avoid
538  // duplicate Initialize/Finalize.
539  // We assume that SLEPc will handle PETSc appropriately,
540  // which it does in the versions we've checked.
541  if (!SlepcInitializeCalled)
542  {
543  ierr = SlepcInitialize (&argc, const_cast<char ***>(&argv), libmesh_nullptr, libmesh_nullptr);
544  CHKERRABORT(libMesh::GLOBAL_COMM_WORLD,ierr);
545  libmesh_initialized_slepc = true;
546  }
547 # else
548  if (libmesh_initialized_petsc)
549  {
550  ierr = PetscInitialize (&argc, const_cast<char ***>(&argv), libmesh_nullptr, libmesh_nullptr);
551  CHKERRABORT(libMesh::GLOBAL_COMM_WORLD,ierr);
552  }
553 # endif
554 #if !PETSC_RELEASE_LESS_THAN(3,3,0)
555  // Register the reference implementation of DMlibMesh
556 #if PETSC_RELEASE_LESS_THAN(3,4,0)
557  ierr = DMRegister(DMLIBMESH, PETSC_NULL, "DMCreate_libMesh", DMCreate_libMesh); CHKERRABORT(libMesh::GLOBAL_COMM_WORLD,ierr);
558 #else
559  ierr = DMRegister(DMLIBMESH, DMCreate_libMesh); CHKERRABORT(libMesh::GLOBAL_COMM_WORLD,ierr);
560 #endif
561 
562 #endif
563  }
564 #endif
565 
566 #if defined(LIBMESH_HAVE_MPI) && defined(LIBMESH_HAVE_VTK)
567  // Do MPI initialization for VTK.
568  _vtk_mpi_controller = vtkMPIController::New();
569  _vtk_mpi_controller->Initialize(&argc, const_cast<char ***>(&argv), /*initialized_externally=*/1);
570  _vtk_mpi_controller->SetGlobalController(_vtk_mpi_controller);
571 #endif
572 
573  // Re-parse the command-line arguments. Note that PETSc and MPI
574  // initialization above may have removed command line arguments
575  // that are not relevant to this application in the above calls.
576  // We don't want a false-positive by detecting those arguments.
577  //
578  // Note: this seems overly paranoid/like it should be unnecessary,
579  // plus we were doing it wrong for many years and not clearing the
580  // existing GetPot object before re-parsing the command line, so all
581  // the command line arguments appeared twice in the GetPot object...
582  command_line.reset (new GetPot (argc, argv));
583 
584  // The following line is an optimization when simultaneous
585  // C and C++ style access to output streams is not required.
586  // The amount of benefit which occurs is probably implementation
587  // defined, and may be nothing. On the other hand, I have seen
588  // some IO tests where IO performance improves by a factor of two.
589  if (!libMesh::on_command_line ("--sync-with-stdio"))
590  std::ios::sync_with_stdio(false);
591 
592  // Honor the --separate-libmeshout command-line option.
593  // When this is specified, the library uses an independent ostream
594  // for libMesh::out/libMesh::err messages, and
595  // std::cout and std::cerr are untouched by any other options
596  if (libMesh::on_command_line ("--separate-libmeshout"))
597  {
598  // Redirect. We'll share streambufs with cout/cerr for now, but
599  // presumably anyone using this option will want to replace the
600  // bufs later.
601  std::ostream * newout = new std::ostream(std::cout.rdbuf());
602  libMesh::out = *newout;
603  std::ostream * newerr = new std::ostream(std::cerr.rdbuf());
604  libMesh::err = *newerr;
605  }
606 
607  // Process command line arguments for redirecting stdout/stderr.
608  bool
609  cmdline_has_redirect_stdout = libMesh::on_command_line ("--redirect-stdout"),
610  cmdline_has_redirect_output = libMesh::on_command_line ("--redirect-output");
611 
612  // The --redirect-stdout command-line option has been deprecated in
613  // favor of "--redirect-output basename".
614  if (cmdline_has_redirect_stdout)
615  libmesh_warning("The --redirect-stdout command line option has been deprecated. "
616  "Use '--redirect-output basename' instead.");
617 
618  // Honor the "--redirect-stdout" and "--redirect-output basename"
619  // command-line options. When one of these is specified, each
620  // processor sends libMesh::out/libMesh::err messages to
621  // stdout.processor.#### (default) or basename.processor.####.
622  if (cmdline_has_redirect_stdout || cmdline_has_redirect_output)
623  {
624  std::string basename = "stdout";
625 
626  // Look for following argument if using new API
627  if (cmdline_has_redirect_output)
628  {
629  // Set the cursor to the correct location in the list of command line arguments.
630  command_line->search(1, "--redirect-output");
631 
632  // Get the next option on the command line as a string.
633  std::string next_string = "";
634  next_string = command_line->next(next_string);
635 
636  // If the next string starts with a dash, we assume it's
637  // another flag and not a file basename requested by the
638  // user.
639  if (next_string.size() > 0 && next_string.find_first_of("-") != 0)
640  basename = next_string;
641  }
642 
643  std::ostringstream filename;
644  filename << basename << ".processor." << libMesh::global_processor_id();
645  _ofstream.reset (new std::ofstream (filename.str().c_str()));
646 
647  // Redirect, saving the original streambufs!
648  out_buf = libMesh::out.rdbuf (_ofstream->rdbuf());
649  err_buf = libMesh::err.rdbuf (_ofstream->rdbuf());
650  }
651 
652  // redirect libMesh::out to nothing on all
653  // other processors unless explicitly told
654  // not to via the --keep-cout command-line argument.
655  if (libMesh::global_processor_id() != 0)
656  if (!libMesh::on_command_line ("--keep-cout"))
658 
659  // Similarly, the user can request to drop cerr on all non-0 ranks.
660  // By default, errors are printed on all ranks, but this can lead to
661  // interleaved/unpredictable outputs when doing parallel regression
662  // testing, which this option is designed to support.
663  if (libMesh::global_processor_id() != 0)
664  if (libMesh::on_command_line ("--drop-cerr"))
666 
667  // Check command line to override printing
668  // of reference count information.
669  if (libMesh::on_command_line("--disable-refcount-printing"))
671 
672 #ifdef LIBMESH_ENABLE_EXCEPTIONS
673  // Set our terminate handler to write stack traces in the event of a
674  // crash
675  old_terminate_handler = std::set_terminate(libmesh_terminate_handler);
676 #endif
677 
678 
679  if (libMesh::on_command_line("--enable-fpe"))
680  libMesh::enableFPE(true);
681 
682  if (libMesh::on_command_line("--enable-segv"))
683  libMesh::enableSEGV(true);
684 
685  // The library is now ready for use
687 
688 
689  // Make sure these work. Library methods
690  // depend on these being implemented properly,
691  // so this is a good time to test them!
694 }
695 
696 
697 
699 {
700  // Every processor had better be ready to exit at the same time.
701  // This would be a libmesh_parallel_only() function, except that
702  // libmesh_parallel_only() uses libmesh_assert() which throws an
703  // exception() which causes compilers to scream about exceptions
704  // inside destructors.
705 
706  // Even if we're not doing parallel_only debugging, we don't want
707  // one processor to try to exit until all others are done working.
708  this->comm().barrier();
709 
710  // We can't delete, finalize, etc. more than once without
711  // reinitializing in between
712  libmesh_exceptionless_assert(!libMesh::closed());
713 
714  // Delete reference counted singleton(s)
716 
717  // Clear the thread task manager we started
718  task_scheduler.reset();
719 
720  // Force the \p ReferenceCounter to print
721  // its reference count information. This allows
722  // us to find memory leaks. By default the
723  // \p ReferenceCounter only prints its information
724  // when the last created object has been destroyed.
725  // That does no good if we are leaking memory!
727 
728 
729  // Print an informative message if we detect a memory leak
730  if (ReferenceCounter::n_objects() != 0)
731  {
732  libMesh::err << "Memory leak detected!"
733  << std::endl;
734 
735 #if !defined(LIBMESH_ENABLE_REFERENCE_COUNTING) || defined(NDEBUG)
736 
737  libMesh::err << "Compile in DEBUG mode with --enable-reference-counting"
738  << std::endl
739  << "for more information"
740  << std::endl;
741 #endif
742 
743  }
744 
745  // print the perflog to individual processor's file.
747 
748  // Now clear the logging object, we don't want it to print
749  // a second time during the PerfLog destructor.
751 
752  // Reconnect the output streams
753  // (don't do this, or we will get messages from objects
754  // that go out of scope after the following return)
755  //std::cout.rdbuf(std::cerr.rdbuf());
756 
757 
758  // Set the initialized() flag to false
760 
761  if (libMesh::on_command_line ("--redirect-stdout") ||
762  libMesh::on_command_line ("--redirect-output"))
763  {
764  // If stdout/stderr were redirected to files, reset them now.
765  libMesh::out.rdbuf (out_buf);
766  libMesh::err.rdbuf (err_buf);
767  }
768 
769  // If we built our own output streams, we want to clean them up.
770  if (libMesh::on_command_line ("--separate-libmeshout"))
771  {
772  delete libMesh::out.get();
773  delete libMesh::err.get();
774 
775  libMesh::out.reset(std::cout);
776  libMesh::err.reset(std::cerr);
777  }
778 
779 #ifdef LIBMESH_ENABLE_EXCEPTIONS
780  // Reset the old terminate handler; maybe the user code wants to
781  // keep doing C++ stuff after closing libMesh stuff.
782  std::set_terminate(old_terminate_handler);
783 #endif
784 
785 
786  if (libMesh::on_command_line("--enable-fpe"))
787  libMesh::enableFPE(false);
788 
789 #if defined(LIBMESH_HAVE_PETSC)
790  // Allow the user to bypass PETSc finalization
791  if (!libMesh::on_command_line ("--disable-petsc")
792 #if defined(LIBMESH_HAVE_MPI)
793  && !libMesh::on_command_line ("--disable-mpi")
794 #endif
795  )
796  {
797 # if defined(LIBMESH_HAVE_SLEPC)
798  if (libmesh_initialized_slepc)
799  SlepcFinalize();
800 # else
801  if (libmesh_initialized_petsc)
802  PetscFinalize();
803 # endif
804  }
805 #endif
806 
807 #if defined(LIBMESH_HAVE_MPI) && defined(LIBMESH_HAVE_VTK)
808  _vtk_mpi_controller->Finalize(/*finalized_externally=*/1);
809  _vtk_mpi_controller->Delete();
810 #endif
811 
812 #if defined(LIBMESH_HAVE_MPI)
813  // Allow the user to bypass MPI finalization
814  if (!libMesh::on_command_line ("--disable-mpi"))
815  {
816  this->_comm.clear();
817 #ifndef LIBMESH_DISABLE_COMMWORLD
819 #endif
820 
821  if (libmesh_initialized_mpi)
822  {
823  // We can't just libmesh_assert here because destructor,
824  // but we ought to report any errors
825  unsigned int error_code = MPI_Finalize();
826  if (error_code != MPI_SUCCESS)
827  {
828  char error_string[MPI_MAX_ERROR_STRING+1];
829  int error_string_len;
830  MPI_Error_string(error_code, error_string,
831  &error_string_len);
832  std::cerr << "Failure from MPI_Finalize():\n"
833  << error_string << std::endl;
834  }
835  }
836  }
837 #endif
838 }
OStreamProxy err
FakeCommunicator & Communicator_World
bool closed()
Checks that the library has been closed.
Definition: libmesh.C:281
static unsigned int n_objects()
Prints the number of outstanding (created, but not yet destroyed) objects.
unsigned int n_threads()
Definition: libmesh_base.h:125
unsigned int size() const
Definition: parallel.h:726
streambufT * rdbuf() const
Get the associated stream buffer.
void enableSEGV(bool on)
Toggle libMesh reporting of segmentation faults.
Definition: libmesh.C:891
processor_id_type _n_processors
Total number of processors used.
Definition: libmesh.C:251
Parallel::Communicator _comm
Definition: libmesh.h:86
const class libmesh_nullptr_t libmesh_nullptr
MPI_Comm GLOBAL_COMM_WORLD
MPI Communicator used to initialize libMesh.
MPI_Comm COMM_WORLD
MPI Communicator to be used in the library.
void reset(streamT &target)
Reset the proxy to point to a different target.
int _n_threads
Total number of threads possible.
Definition: libmesh.C:254
vtkMPIController * _vtk_mpi_controller
Definition: libmesh.h:92
static void setup()
Setup function.
EXTERN_C_BEGIN PETSC_EXTERN PetscErrorCode DMCreate_libMesh(DM)
libmesh_assert(j)
tbb::task_scheduler_init task_scheduler_init
Scheduler to manage threads.
Definition: threads_tbb.h:73
T command_line_value(const std::string &, T)
Definition: libmesh.C:932
bool _is_initialized
Flag that tells if init() has been called.
Definition: libmesh.C:255
std::terminate_handler old_terminate_handler
Definition: libmesh.C:288
processor_id_type _processor_id
The local processor id.
Definition: libmesh.C:252
void barrier() const
Pause execution until all processors reach a certain point.
const Parallel::Communicator & comm() const
Definition: libmesh.h:81
static void print_info(std::ostream &out=libMesh::out)
Prints the reference information, by default to libMesh::out.
MPI_Errhandler libmesh_errhandler
Definition: libmesh.C:249
void clear()
Clears all the internal data and restores the data structures to a pristine state.
Definition: perf_log.C:77
void enableFPE(bool on)
Toggle hardware trap floating point exceptions.
Definition: libmesh.C:845
PetscTruth PetscBool
Definition: petsc_macro.h:64
void clear()
Free and reset this communicator.
PetscErrorCode ierr
PerfLog perflog
A PerfLog object to log performance.
bool on_command_line(const std::string &arg)
Definition: libmesh.C:921
OStreamProxy out
processor_id_type global_processor_id()
Definition: libmesh_base.h:114
bool initialized()
Checks that library initialization has been done.
Definition: libmesh.C:274
void libMesh_MPI_Handler(MPI_Comm *, int *,...)
Definition: libmesh.C:162
streamT * get()
Rather than implement every ostream/ios/ios_base function, we&#39;ll be lazy and make esoteric uses go th...
unsigned int rank() const
Definition: parallel.h:724
static void cleanup()
Cleanup function.
void print_log() const
Print the log.
Definition: perf_log.C:684
static void disable_print_counter_info()
void disable_logging()
Disables performance logging for an active object.
Definition: perf_log.h:156
void libmesh_terminate_handler()
Definition: libmesh.C:290
const RemoteElem * remote_elem
Definition: remote_elem.C:57
virtual libMesh::LibMeshInit::~LibMeshInit ( )
virtual

Referenced by LibMeshInit().

Member Function Documentation

const Parallel::Communicator& libMesh::LibMeshInit::comm ( ) const

Definition at line 81 of file libmesh.h.

References _comm.

Referenced by main().

81 { return _comm; }
Parallel::Communicator _comm
Definition: libmesh.h:86
Parallel::Communicator& libMesh::LibMeshInit::comm ( )

Definition at line 83 of file libmesh.h.

References _comm.

83 { return _comm; }
Parallel::Communicator _comm
Definition: libmesh.h:86

Member Data Documentation

Parallel::Communicator libMesh::LibMeshInit::_comm
private

Definition at line 86 of file libmesh.h.

Referenced by comm().

vtkMPIController* libMesh::LibMeshInit::_vtk_mpi_controller
private

Definition at line 92 of file libmesh.h.


The documentation for this class was generated from the following files: