libmesh.C
Go to the documentation of this file.00001 // The libMesh Finite Element Library. 00002 // Copyright (C) 2002-2012 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner 00003 00004 // This library is free software; you can redistribute it and/or 00005 // modify it under the terms of the GNU Lesser General Public 00006 // License as published by the Free Software Foundation; either 00007 // version 2.1 of the License, or (at your option) any later version. 00008 00009 // This library is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 // Lesser General Public License for more details. 00013 00014 // You should have received a copy of the GNU Lesser General Public 00015 // License along with this library; if not, write to the Free Software 00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00017 00018 00019 // Local includes 00020 #include "libmesh/libmesh.h" 00021 #include "libmesh/auto_ptr.h" 00022 #include "libmesh/getpot.h" 00023 #include "libmesh/parallel.h" 00024 #include "libmesh/reference_counter.h" 00025 #include "libmesh/remote_elem.h" 00026 #include "libmesh/threads.h" 00027 00028 00029 // C/C++ includes 00030 #include <iostream> 00031 #include <fstream> 00032 00033 #ifdef LIBMESH_ENABLE_EXCEPTIONS 00034 #include <exception> 00035 #endif 00036 00037 #include "signal.h" 00038 00039 00040 // floating-point exceptions 00041 #ifdef LIBMESH_HAVE_FENV_H 00042 # include <fenv.h> 00043 #endif 00044 #ifdef LIBMESH_HAVE_XMMINTRIN_H 00045 # include <xmmintrin.h> 00046 #endif 00047 00048 00049 #if defined(LIBMESH_HAVE_MPI) 00050 # include "libmesh/ignore_warnings.h" 00051 # include <mpi.h> 00052 # include "libmesh/restore_warnings.h" 00053 #endif // #if defined(LIBMESH_HAVE_MPI) 00054 00055 #if defined(LIBMESH_HAVE_PETSC) 00056 # include "libmesh/petsc_macro.h" 00057 EXTERN_C_FOR_PETSC_BEGIN 00058 # include <petsc.h> 00059 # include <petscerror.h> 00060 EXTERN_C_FOR_PETSC_END 00061 # if defined(LIBMESH_HAVE_SLEPC) 00062 # include "libmesh/slepc_macro.h" 00063 EXTERN_C_FOR_PETSC_BEGIN 00064 # include <slepc.h> 00065 EXTERN_C_FOR_PETSC_END 00066 # endif // #if defined(LIBMESH_HAVE_SLEPC) 00067 #endif // #if defined(LIBMESH_HAVE_PETSC) 00068 00069 00070 // -------------------------------------------------------- 00071 // Local anonymous namespace to hold miscelaneous bits 00072 namespace { 00073 00074 using libMesh::AutoPtr; 00075 00076 AutoPtr<GetPot> command_line (NULL); 00077 AutoPtr<std::ofstream> _ofstream (NULL); 00078 // If std::cout and std::cerr are redirected, we need to 00079 // be a little careful and save the original streambuf objects, 00080 // replacing them in the destructor before program termination. 00081 std::streambuf* out_buf (NULL); 00082 std::streambuf* err_buf (NULL); 00083 00084 AutoPtr<libMesh::Threads::task_scheduler_init> task_scheduler (NULL); 00085 #if defined(LIBMESH_HAVE_MPI) 00086 bool libmesh_initialized_mpi = false; 00087 #endif 00088 #if defined(LIBMESH_HAVE_PETSC) 00089 bool libmesh_initialized_petsc = false; 00090 #endif 00091 #if defined(LIBMESH_HAVE_SLEPC) 00092 bool libmesh_initialized_slepc = false; 00093 #endif 00094 00095 00096 00100 void libmesh_handleFPE(int /*signo*/, siginfo_t *info, void * /*context*/) 00101 { 00102 std::cout << std::endl; 00103 std::cout << "Floating point exception signaled ("; 00104 switch (info->si_code) 00105 { 00106 case FPE_INTDIV: std::cerr << "integer divide by zero"; break; 00107 case FPE_INTOVF: std::cerr << "integer overflow"; break; 00108 case FPE_FLTDIV: std::cerr << "floating point divide by zero"; break; 00109 case FPE_FLTOVF: std::cerr << "floating point overflow"; break; 00110 case FPE_FLTUND: std::cerr << "floating point underflow"; break; 00111 case FPE_FLTRES: std::cerr << "floating point inexact result"; break; 00112 case FPE_FLTINV: std::cerr << "invalid floating point operation"; break; 00113 case FPE_FLTSUB: std::cerr << "subscript out of range"; break; 00114 default: std::cerr << "unrecognized"; break; 00115 } 00116 std::cout << ")!" << std::endl; 00117 00118 std::cout << std::endl; 00119 std::cout << "To track this down, compile debug version, start debugger, set breakpoint for 'libmesh_handleFPE' and run" << std::endl; 00120 std::cout << "In gdb do:" << std::endl; 00121 std::cout << " break libmesh_handleFPE" << std::endl; 00122 std::cout << " run ..." << std::endl; 00123 std::cout << " bt" << std::endl; 00124 00125 libmesh_error(); 00126 } 00127 00128 00129 00133 void enableFPE(bool on) 00134 { 00135 #if !defined(LIBMESH_HAVE_FEENABLEEXCEPT) && defined(LIBMESH_HAVE_XMMINTRIN_H) 00136 static int flags = 0; 00137 #endif 00138 00139 if (on) 00140 { 00141 struct sigaction new_action, old_action; 00142 00143 #ifdef LIBMESH_HAVE_FEENABLEEXCEPT 00144 feenableexcept(FE_DIVBYZERO | FE_INVALID); 00145 #elif LIBMESH_HAVE_XMMINTRIN_H 00146 # ifndef __SUNPRO_CC 00147 flags = _MM_GET_EXCEPTION_MASK(); // store the flags 00148 _MM_SET_EXCEPTION_MASK(flags & ~_MM_MASK_INVALID); 00149 # endif 00150 #endif 00151 00152 00153 // Set up the structure to specify the new action. 00154 new_action.sa_sigaction = libmesh_handleFPE; 00155 sigemptyset (&new_action.sa_mask); 00156 new_action.sa_flags = SA_SIGINFO; 00157 00158 sigaction (SIGFPE, NULL, &old_action); 00159 if (old_action.sa_handler != SIG_IGN) 00160 sigaction (SIGFPE, &new_action, NULL); 00161 } 00162 else 00163 { 00164 #ifdef LIBMESH_HAVE_FEDISABLEEXCEPT 00165 fedisableexcept(FE_DIVBYZERO | FE_INVALID); 00166 #elif LIBMESH_HAVE_XMMINTRIN_H 00167 # ifndef __SUNPRO_CC 00168 _MM_SET_EXCEPTION_MASK(flags); 00169 # endif 00170 #endif 00171 signal(SIGFPE, 0); 00172 } 00173 } 00174 00175 } 00176 00177 00178 00179 #ifdef LIBMESH_HAVE_MPI 00180 void libMesh_MPI_Handler (MPI_Comm *, int *, ...) 00181 { 00182 libmesh_error(); 00183 } 00184 #endif 00185 00186 00187 namespace libMesh 00188 { 00189 00197 namespace libMeshPrivateData { 00198 00202 extern bool _is_initialized; 00203 00207 extern SolverPackage _solver_package; 00208 } 00209 00210 00211 // ------------------------------------------------------------ 00212 // libMeshdata initialization 00213 #ifdef LIBMESH_HAVE_MPI 00214 MPI_Comm COMM_WORLD = MPI_COMM_NULL; 00215 #else 00216 int COMM_WORLD = 0; 00217 #endif 00218 00219 Parallel::Communicator CommWorld; 00220 Parallel::Communicator& Parallel::Communicator_World = CommWorld; 00221 00222 00223 OStreamProxy out(std::cout); 00224 OStreamProxy err(std::cerr); 00225 00226 00227 PerfLog perflog ("libMesh", 00228 #ifdef LIBMESH_ENABLE_PERFORMANCE_LOGGING 00229 true 00230 #else 00231 false 00232 #endif 00233 ); 00234 00235 00236 // const Real pi = 3.1415926535897932384626433832795029L; 00237 00238 #ifdef LIBMESH_USE_COMPLEX_NUMBERS 00239 const Number imaginary (0., 1.); 00240 // const Number zero (0., 0.); 00241 #else 00242 // const Number zero = 0.; 00243 #endif 00244 00245 // This is now a static constant in the header; no reason not to let 00246 // the compiler inline it. 00247 00248 // const unsigned int invalid_uint = static_cast<unsigned int>(-1); 00249 00250 00251 00252 // ------------------------------------------------------------ 00253 // libMesh::libMeshPrivateData data initialization 00254 #ifdef LIBMESH_HAVE_MPI 00255 MPI_Errhandler libmesh_errhandler; 00256 00257 processor_id_type libMesh::libMeshPrivateData::_n_processors = 1; 00258 processor_id_type libMesh::libMeshPrivateData::_processor_id = 0; 00259 #endif 00260 int libMesh::libMeshPrivateData::_n_threads = 1; /* Threads::task_scheduler_init::automatic; */ 00261 bool libMesh::libMeshPrivateData::_is_initialized = false; 00262 SolverPackage libMesh::libMeshPrivateData::_solver_package = 00263 #if defined(LIBMESH_HAVE_PETSC) // PETSc is the default 00264 PETSC_SOLVERS; 00265 #elif defined(LIBMESH_HAVE_TRILINOS) // Use Trilinos if PETSc isn't there 00266 TRILINOS_SOLVERS; 00267 #elif defined(LIBMESH_HAVE_LASPACK) // Use LASPACK if neither are there 00268 LASPACK_SOLVERS; 00269 #else // No valid linear solver package at compile time 00270 INVALID_SOLVER_PACKAGE; 00271 #endif 00272 00273 00274 00275 // ------------------------------------------------------------ 00276 // libMesh functions 00277 00278 bool initialized() 00279 { 00280 return libMeshPrivateData::_is_initialized; 00281 } 00282 00283 00284 00285 bool closed() 00286 { 00287 return !libMeshPrivateData::_is_initialized; 00288 } 00289 00290 00291 #ifdef LIBMESH_ENABLE_EXCEPTIONS 00292 std::terminate_handler old_terminate_handler; 00293 00294 void libmesh_terminate_handler() 00295 { 00296 // If this got called then we're probably crashing; let's print a 00297 // stack trace. 00298 libmesh_write_traceout(); 00299 00300 // The system terminate_handler may do useful things like printing 00301 // uncaught exception information, or the user may have created 00302 // their own terminate handler that we want to call. 00303 old_terminate_handler(); 00304 } 00305 #endif 00306 00307 00308 00309 #ifndef LIBMESH_HAVE_MPI 00310 void _init (int &argc, char** & argv) 00311 #else 00312 void _init (int &argc, char** & argv, 00313 MPI_Comm COMM_WORLD_IN) 00314 #endif 00315 { 00316 // should _not_ be initialized already. 00317 libmesh_assert (!libMesh::initialized()); 00318 00319 // Build a command-line parser. 00320 command_line.reset (new GetPot (argc, argv)); 00321 00322 // Disable performance logging upon request 00323 { 00324 if (libMesh::on_command_line ("--disable-perflog")) 00325 libMesh::perflog.disable_logging(); 00326 } 00327 00328 // Build a task scheduler 00329 { 00330 // Get the requested number of threads, defaults to 1 to avoid MPI and 00331 // multithreading competition. If you would like to use MPI and multithreading 00332 // at the same time then (n_mpi_processes_per_node)x(n_threads) should be the 00333 // number of processing cores per node. 00334 std::vector<std::string> n_threads(2); 00335 n_threads[0] = "--n_threads"; 00336 n_threads[1] = "--n-threads"; 00337 libMesh::libMeshPrivateData::_n_threads = 00338 libMesh::command_line_value (n_threads, 1); 00339 00340 task_scheduler.reset (new Threads::task_scheduler_init(libMesh::n_threads())); 00341 } 00342 00343 // Construct singletons who may be at risk of the 00344 // "static initialization order fiasco" 00345 // 00346 // RemoteElem depends on static reference counting data 00347 remote_elem = new RemoteElem(); 00348 00349 #if defined(LIBMESH_HAVE_MPI) 00350 00351 // Allow the user to bypass MPI initialization 00352 if (!libMesh::on_command_line ("--disable-mpi")) 00353 { 00354 // Check whether the calling program has already initialized 00355 // MPI, and avoid duplicate Init/Finalize 00356 int flag; 00357 MPI_Initialized (&flag); 00358 00359 if (!flag) 00360 { 00361 MPI_Init (&argc, &argv); 00362 libmesh_initialized_mpi = true; 00363 } 00364 00365 // Duplicate the input communicator for internal use 00366 MPI_Comm_dup (COMM_WORLD_IN, &libMesh::COMM_WORLD); 00367 00368 // And get a Parallel::Communicator copy too, to use 00369 // as a default for that API 00370 Parallel::Communicator_World = COMM_WORLD_IN; 00371 00372 //MPI_Comm_set_name not supported in at least SGI MPT's MPI implementation 00373 //MPI_Comm_set_name (libMesh::COMM_WORLD, "libMesh::COMM_WORLD"); 00374 00375 libMeshPrivateData::_processor_id = 00376 libmesh_cast_int<processor_id_type>(Parallel::Communicator_World.rank()); 00377 libMeshPrivateData::_n_processors = 00378 libmesh_cast_int<processor_id_type>(Parallel::Communicator_World.size()); 00379 00380 // Set up an MPI error handler if requested. This helps us get 00381 // into a debugger with a proper stack when an MPI error occurs. 00382 if (libMesh::on_command_line ("--handle-mpi-errors")) 00383 { 00384 MPI_Errhandler_create(libMesh_MPI_Handler, &libmesh_errhandler); 00385 MPI_Errhandler_set(libMesh::COMM_WORLD, libmesh_errhandler); 00386 MPI_Errhandler_set(MPI_COMM_WORLD, libmesh_errhandler); 00387 } 00388 } 00389 00390 // Could we have gotten bad values from the above calls? 00391 libmesh_assert_greater (libMeshPrivateData::_n_processors, 0); 00392 00393 // The libmesh_cast_int already tested _processor_id>=0 00394 // libmesh_assert_greater_equal (libMeshPrivateData::_processor_id, 0); 00395 00396 // Let's be sure we properly initialize on every processor at once: 00397 parallel_only(); 00398 00399 #endif 00400 00401 #if defined(LIBMESH_HAVE_PETSC) 00402 00403 // Allow the user to bypass PETSc initialization 00404 if (!libMesh::on_command_line ("--disable-petsc") 00405 00406 #if defined(LIBMESH_HAVE_MPI) 00407 // If the user bypassed MPI, we'd better be safe and assume that 00408 // PETSc was built to require it; otherwise PETSc initialization 00409 // dies. 00410 && !libMesh::on_command_line ("--disable-mpi") 00411 #endif 00412 ) 00413 { 00414 int ierr=0; 00415 00416 PETSC_COMM_WORLD = libMesh::COMM_WORLD; 00417 00418 // Check whether the calling program has already initialized 00419 // PETSc, and avoid duplicate Initialize/Finalize 00420 PetscBool petsc_already_initialized; 00421 ierr = PetscInitialized(&petsc_already_initialized); 00422 CHKERRABORT(libMesh::COMM_WORLD,ierr); 00423 if (petsc_already_initialized != PETSC_TRUE) 00424 libmesh_initialized_petsc = true; 00425 # if defined(LIBMESH_HAVE_SLEPC) 00426 00427 // If SLEPc allows us to check whether the calling program 00428 // has already initialized it, we do that, and avoid 00429 // duplicate Initialize/Finalize. 00430 // We assume that SLEPc will handle PETSc appropriately, 00431 // which it does in the versions we've checked. 00432 # if !SLEPC_VERSION_LESS_THAN(2,3,3) 00433 if (!SlepcInitializeCalled) 00434 # endif 00435 { 00436 ierr = SlepcInitialize (&argc, &argv, NULL, NULL); 00437 CHKERRABORT(libMesh::COMM_WORLD,ierr); 00438 libmesh_initialized_slepc = true; 00439 } 00440 # else 00441 if (libmesh_initialized_petsc) 00442 { 00443 ierr = PetscInitialize (&argc, &argv, NULL, NULL); 00444 CHKERRABORT(libMesh::COMM_WORLD,ierr); 00445 } 00446 # endif 00447 } 00448 #endif 00449 00450 // Re-parse the command-line arguments. Note that PETSc and MPI 00451 // initialization above may have removed command line arguments 00452 // that are not relevant to this application in the above calls. 00453 // We don't want a false-positive by detecting those arguments. 00454 command_line->parse_command_line (argc, argv); 00455 00456 // The following line is an optimization when simultaneous 00457 // C and C++ style access to output streams is not required. 00458 // The amount of benefit which occurs is probably implementation 00459 // defined, and may be nothing. On the other hand, I have seen 00460 // some IO tests where IO peformance improves by a factor of two. 00461 if (!libMesh::on_command_line ("--sync-with-stdio")) 00462 std::ios::sync_with_stdio(false); 00463 00464 // Honor the --separate-libmeshout command-line option. 00465 // When this is specified, the library uses an independent ostream 00466 // for libMesh::out/libMesh::err messages, and 00467 // std::cout and std::cerr are untouched by any other options 00468 if (libMesh::on_command_line ("--separate-libmeshout")) 00469 { 00470 // Redirect. We'll share streambufs with cout/cerr for now, but 00471 // presumably anyone using this option will want to replace the 00472 // bufs later. 00473 std::ostream* newout = new std::ostream(std::cout.rdbuf()); 00474 libMesh::out = *newout; 00475 std::ostream* newerr = new std::ostream(std::cerr.rdbuf()); 00476 libMesh::err = *newerr; 00477 } 00478 00479 // Honor the --redirect-stdout command-line option. 00480 // When this is specified each processor sends 00481 // libMesh::out/libMesh::err messages to 00482 // stdout.processor.#### 00483 if (libMesh::on_command_line ("--redirect-stdout")) 00484 { 00485 char filechar[80]; 00486 sprintf (filechar, "stdout.processor.%04d", 00487 libMesh::processor_id()); 00488 _ofstream.reset (new std::ofstream (filechar)); 00489 // Redirect, saving the original streambufs! 00490 out_buf = libMesh::out.rdbuf (_ofstream->rdbuf()); 00491 err_buf = libMesh::err.rdbuf (_ofstream->rdbuf()); 00492 } 00493 00494 // redirect libMesh::out to nothing on all 00495 // other processors unless explicitly told 00496 // not to via the --keep-cout command-line argument. 00497 if (libMesh::processor_id() != 0) 00498 if (!libMesh::on_command_line ("--keep-cout")) 00499 libMesh::out.rdbuf (NULL); 00500 00501 // Check command line to override printing 00502 // of reference count information. 00503 if(libMesh::on_command_line("--disable-refcount-printing") ) 00504 ReferenceCounter::disable_print_counter_info(); 00505 00506 #ifdef LIBMESH_ENABLE_EXCEPTIONS 00507 // Set our terminate handler to write stack traces in the event of a 00508 // crash 00509 old_terminate_handler = std::set_terminate(libmesh_terminate_handler); 00510 #endif 00511 00512 00513 if (libMesh::on_command_line("--enable-fpe")) 00514 enableFPE(true); 00515 00516 // The library is now ready for use 00517 libMeshPrivateData::_is_initialized = true; 00518 00519 00520 // Make sure these work. Library methods 00521 // depend on these being implemented properly, 00522 // so this is a good time to test them! 00523 libmesh_assert (libMesh::initialized()); 00524 libmesh_assert (!libMesh::closed()); 00525 } 00526 00527 00528 00529 int _close () 00530 { 00531 // We can't delete, finalize, etc. more than once without 00532 // reinitializing in between 00533 libmesh_assert(!libMesh::closed()); 00534 00535 // Delete reference counted singleton(s) 00536 delete remote_elem; 00537 00538 // Clear the thread task manager we started 00539 task_scheduler.reset(); 00540 00541 // Let's be sure we properly close on every processor at once: 00542 parallel_only(); 00543 00544 #if defined(LIBMESH_HAVE_MPI) 00545 // We may be here in only one process, 00546 // because an uncaught libmesh_error() exception 00547 // called the LibMeshInit destructor. 00548 // 00549 // If that's the case, we need to MPI_Abort(), 00550 // not just wait for other processes that 00551 // might never get to MPI_Finalize() 00552 if (libmesh_initialized_mpi && 00553 std::uncaught_exception()) 00554 { 00555 libMesh::err << "Uncaught exception - aborting" << std::endl; 00556 if (libMesh::on_command_line ("--disable-mpi")) 00557 exit(1); 00558 else 00559 MPI_Abort(libMesh::COMM_WORLD,1); 00560 } 00561 #endif 00562 00563 #if defined(LIBMESH_HAVE_PETSC) 00564 // Allow the user to bypass PETSc finalization 00565 if (!libMesh::on_command_line ("--disable-petsc") 00566 #if defined(LIBMESH_HAVE_MPI) 00567 && !libMesh::on_command_line ("--disable-mpi") 00568 #endif 00569 ) 00570 { 00571 # if defined(LIBMESH_HAVE_SLEPC) 00572 if (libmesh_initialized_slepc) 00573 SlepcFinalize(); 00574 # else 00575 if (libmesh_initialized_petsc) 00576 PetscFinalize(); 00577 # endif 00578 } 00579 #endif 00580 00581 #if defined(LIBMESH_HAVE_MPI) 00582 // Allow the user to bypass MPI finalization 00583 if (!libMesh::on_command_line ("--disable-mpi")) 00584 { 00585 Parallel::Communicator_World.clear(); 00586 MPI_Comm_free (&libMesh::COMM_WORLD); 00587 00588 if (libmesh_initialized_mpi) 00589 MPI_Finalize(); 00590 } 00591 #endif 00592 00593 // Force the \p ReferenceCounter to print 00594 // its reference count information. This allows 00595 // us to find memory leaks. By default the 00596 // \p ReferenceCounter only prints its information 00597 // when the last created object has been destroyed. 00598 // That does no good if we are leaking memory! 00599 ReferenceCounter::print_info (); 00600 00601 00602 // Print an informative message if we detect a memory leak 00603 if (ReferenceCounter::n_objects() != 0) 00604 { 00605 libMesh::err << "Memory leak detected!" 00606 << std::endl; 00607 00608 #if !defined(LIBMESH_ENABLE_REFERENCE_COUNTING) || defined(NDEBUG) 00609 00610 libMesh::err << "Compile in DEBUG mode with --enable-reference-counting" 00611 << std::endl 00612 << "for more information" 00613 << std::endl; 00614 #endif 00615 00616 } 00617 00618 00619 // Reconnect the output streams 00620 // (don't do this, or we will get messages from objects 00621 // that go out of scope after the following return) 00622 //std::cout.rdbuf(std::cerr.rdbuf()); 00623 00624 00625 // Set the initialized() flag to false 00626 libMeshPrivateData::_is_initialized = false; 00627 00628 if (libMesh::on_command_line ("--redirect-stdout")) 00629 { 00630 // Before handing back the std stream buffers, print the 00631 // perflog to the individual processor's files. 00632 libMesh::perflog.print_log(); 00633 00634 // Now clear the logging object, we don't want it to print 00635 // a second time during the PerfLog destructor. 00636 libMesh::perflog.clear(); 00637 00638 // If stdout/stderr were redirected to files, reset them now. 00639 libMesh::out.rdbuf (out_buf); 00640 libMesh::err.rdbuf (err_buf); 00641 } 00642 00643 // If we built our own output streams, we want to clean them up. 00644 if (libMesh::on_command_line ("--separate-libmeshout")) 00645 { 00646 delete libMesh::out.get(); 00647 delete libMesh::err.get(); 00648 00649 libMesh::out.reset(std::cout); 00650 libMesh::err.reset(std::cerr); 00651 } 00652 00653 #ifdef LIBMESH_ENABLE_EXCEPTIONS 00654 // Reset the old terminate handler; maybe the user code wants to 00655 // keep doing C++ stuff after closing libMesh stuff. 00656 std::set_terminate(old_terminate_handler); 00657 #endif 00658 00659 00660 if (libMesh::on_command_line("--enable-fpe")) 00661 enableFPE(false); 00662 00663 00664 // Return the number of outstanding objects. 00665 // This is equivalent to return 0 if all of 00666 // the reference counted objects have been 00667 // deleted. 00668 return static_cast<int>(ReferenceCounter::n_objects()); 00669 } 00670 00671 00672 00673 #ifndef LIBMESH_HAVE_MPI 00674 void init (int &argc, char** & argv) 00675 { 00676 libmesh_deprecated(); // Use LibMeshInit instead 00677 libMesh::_init(argc, argv); 00678 } 00679 #else 00680 void init (int &argc, char** & argv, 00681 MPI_Comm COMM_WORLD_IN) 00682 { 00683 libmesh_deprecated(); // Use LibMeshInit instead 00684 libMesh::_init(argc, argv, COMM_WORLD_IN); 00685 } 00686 #endif 00687 00688 00689 00690 00691 int close () 00692 { 00693 libmesh_deprecated(); // Use LibMeshInit instead 00694 return libMesh::_close(); 00695 } 00696 00697 00698 00699 #ifndef LIBMESH_HAVE_MPI 00700 LibMeshInit::LibMeshInit (int &argc, char** & argv) 00701 { 00702 libMesh::_init(argc, argv); 00703 } 00704 #else 00705 LibMeshInit::LibMeshInit (int &argc, char** & argv, 00706 MPI_Comm COMM_WORLD_IN) 00707 { 00708 libMesh::_init(argc, argv, COMM_WORLD_IN); 00709 } 00710 #endif 00711 00712 LibMeshInit::~LibMeshInit() 00713 { 00714 libMesh::_close(); 00715 } 00716 00717 00718 00719 00720 bool on_command_line (const std::string& arg) 00721 { 00722 // Make sure the command line parser is ready for use 00723 libmesh_assert(command_line.get()); 00724 00725 return command_line->search (arg); 00726 } 00727 00728 00729 00730 template <typename T> 00731 T command_line_value (const std::string &name, T value) 00732 { 00733 // Make sure the command line parser is ready for use 00734 libmesh_assert(command_line.get()); 00735 00736 // only if the variable exists in the file 00737 if (command_line->have_variable(name.c_str())) 00738 value = (*command_line)(name.c_str(), value); 00739 00740 return value; 00741 } 00742 00743 template <typename T> 00744 T command_line_value (const std::vector<std::string> &name, T value) 00745 { 00746 // Make sure the command line parser is ready for use 00747 libmesh_assert(command_line.get()); 00748 00749 // Check for multiple options (return the first that matches) 00750 for (std::vector<std::string>::const_iterator i=name.begin(); i != name.end(); ++i) 00751 if (command_line->have_variable(i->c_str())) 00752 { 00753 value = (*command_line)(i->c_str(), value); 00754 break; 00755 } 00756 00757 return value; 00758 } 00759 00760 00761 00762 00763 template <typename T> 00764 void command_line_vector (const std::string &name, std::vector<T>& vec) 00765 { 00766 // Make sure the command line parser is ready for use 00767 libmesh_assert(command_line.get()); 00768 00769 // only if the variable exists on the command line 00770 if (command_line->have_variable(name.c_str())) 00771 { 00772 unsigned size = command_line->vector_variable_size(name.c_str()); 00773 vec.resize(size); 00774 00775 for (unsigned i=0; i<size; ++i) 00776 vec[i] = (*command_line)(name.c_str(), vec[i], i); 00777 } 00778 } 00779 00780 00781 SolverPackage default_solver_package () 00782 { 00783 libmesh_assert (libMesh::initialized()); 00784 00785 static bool called = false; 00786 00787 // Check the command line. Since the command line is 00788 // unchanging it is sufficient to do this only once. 00789 if (!called) 00790 { 00791 called = true; 00792 00793 #ifdef LIBMESH_HAVE_PETSC 00794 if (libMesh::on_command_line ("--use-petsc")) 00795 libMeshPrivateData::_solver_package = PETSC_SOLVERS; 00796 #endif 00797 00798 #ifdef LIBMESH_HAVE_TRILINOS 00799 if (libMesh::on_command_line ("--use-trilinos") || 00800 libMesh::on_command_line ("--disable-petsc")) 00801 libMeshPrivateData::_solver_package = TRILINOS_SOLVERS; 00802 #endif 00803 00804 #ifdef LIBMESH_HAVE_LASPACK 00805 if (libMesh::on_command_line ("--use-laspack" ) || 00806 #if defined(LIBMESH_HAVE_MPI) 00807 // If the user bypassed MPI, we disable PETSc and Trilinos 00808 // too 00809 libMesh::on_command_line ("--disable-mpi") || 00810 #endif 00811 libMesh::on_command_line ("--disable-petsc")) 00812 libMeshPrivateData::_solver_package = LASPACK_SOLVERS; 00813 #endif 00814 00815 if (libMesh::on_command_line ("--disable-laspack") && 00816 libMesh::on_command_line ("--disable-trilinos") && 00817 ( 00818 #if defined(LIBMESH_HAVE_MPI) 00819 // If the user bypassed MPI, we disable PETSc too 00820 libMesh::on_command_line ("--disable-mpi") || 00821 #endif 00822 libMesh::on_command_line ("--disable-petsc"))) 00823 libMeshPrivateData::_solver_package = INVALID_SOLVER_PACKAGE; 00824 } 00825 00826 00827 return libMeshPrivateData::_solver_package; 00828 } 00829 00830 00831 00832 //------------------------------------------------------------------------------- 00833 template int command_line_value<int> (const std::string&, int); 00834 template float command_line_value<float> (const std::string&, float); 00835 template double command_line_value<double> (const std::string&, double); 00836 template long double command_line_value<long double> (const std::string&, long double); 00837 template std::string command_line_value<std::string> (const std::string&, std::string); 00838 00839 template void command_line_vector<int> (const std::string&, std::vector<int>&); 00840 template void command_line_vector<float> (const std::string&, std::vector<float>&); 00841 template void command_line_vector<double> (const std::string&, std::vector<double>&); 00842 template void command_line_vector<long double> (const std::string&, std::vector<long double>&); 00843 00844 } // namespace libMesh
Site Created By: libMesh Developers
Last modified: February 05 2013 19:54:47 UTC
Hosted By: