00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef __deal2__partitioner_h
00014 #define __deal2__partitioner_h
00015
00016 #include <deal.II/base/config.h>
00017 #include <deal.II/base/index_set.h>
00018 #include <deal.II/base/mpi.h>
00019 #include <deal.II/base/types.h>
00020 #include <deal.II/base/utilities.h>
00021 #include <deal.II/base/memory_consumption.h>
00022
00023
00024
00025 DEAL_II_NAMESPACE_OPEN
00026
00027 namespace Utilities
00028 {
00029 namespace MPI
00030 {
00061 class Partitioner
00062 {
00063 public:
00067 Partitioner ();
00068
00074 Partitioner (const unsigned int size);
00075
00086 Partitioner (const IndexSet &locally_owned_indices,
00087 const IndexSet &ghost_indices_in,
00088 const MPI_Comm communicator_in);
00089
00099 Partitioner (const IndexSet &locally_owned_indices,
00100 const MPI_Comm communicator_in);
00101
00106 void set_owned_indices (const IndexSet &locally_owned_indices);
00107
00112 void set_ghost_indices (const IndexSet &ghost_indices);
00113
00117 types::global_dof_index size() const;
00118
00124 unsigned int local_size() const;
00125
00134 const IndexSet & locally_owned_range() const;
00135
00142 std::pair<types::global_dof_index,types::global_dof_index>
00143 local_range() const;
00144
00149 bool in_local_range (const types::global_dof_index global_index) const;
00150
00163 unsigned int
00164 global_to_local (const types::global_dof_index global_index) const;
00165
00176 types::global_dof_index
00177 local_to_global (const unsigned int local_index) const;
00178
00186 bool is_ghost_entry (const types::global_dof_index global_index) const;
00187
00192 const IndexSet& ghost_indices() const;
00193
00199 unsigned int n_ghost_indices() const;
00200
00207 const std::vector<std::pair<unsigned int,unsigned int> >&
00208 ghost_targets() const;
00209
00218 const std::vector<std::pair<unsigned int, unsigned int> >&
00219 import_indices() const;
00220
00226 unsigned int n_import_indices() const;
00227
00236 const std::vector<std::pair<unsigned int,unsigned int> >&
00237 import_targets() const;
00238
00256 bool is_compatible (const Partitioner &part) const;
00257
00262 unsigned int this_mpi_process () const;
00263
00269 unsigned int n_mpi_processes () const;
00270
00275 MPI_Comm get_communicator() const;
00276
00281 std::size_t memory_consumption() const;
00282
00286 DeclException2 (ExcIndexNotPresent,
00287 unsigned int, unsigned int,
00288 << "Global index " << arg1
00289 << " neither owned nor ghost on proc " << arg2);
00290
00291 private:
00295 const types::global_dof_index global_size;
00296
00301 IndexSet locally_owned_range_data;
00302
00308 std::pair<types::global_dof_index,types::global_dof_index> local_range_data;
00309
00314 IndexSet ghost_indices_data;
00315
00321 unsigned int n_ghost_indices_data;
00322
00328 std::vector<std::pair<unsigned int,unsigned int> > ghost_targets_data;
00329
00338 std::vector<std::pair<unsigned int, unsigned int> > import_indices_data;
00339
00346 unsigned int n_import_indices_data;
00347
00352 std::vector<std::pair<unsigned int,unsigned int> > import_targets_data;
00353
00358 unsigned int my_pid;
00359
00364 unsigned int n_procs;
00365
00370 const MPI_Comm communicator;
00371 };
00372
00373
00374
00375
00376
00377 #ifndef DOXYGEN
00378
00379 inline
00380 types::global_dof_index Partitioner::size() const
00381 {
00382 return global_size;
00383 }
00384
00385
00386
00387 inline
00388 const IndexSet& Partitioner::locally_owned_range() const
00389 {
00390 return locally_owned_range_data;
00391 }
00392
00393
00394
00395 inline
00396 std::pair<types::global_dof_index,types::global_dof_index>
00397 Partitioner::local_range() const
00398 {
00399 return local_range_data;
00400 }
00401
00402
00403
00404 inline
00405 unsigned int
00406 Partitioner::local_size () const
00407 {
00408 return local_range_data.second - local_range_data.first;
00409 }
00410
00411
00412
00413 inline
00414 bool
00415 Partitioner::in_local_range (const types::global_dof_index global_index) const
00416 {
00417 return (local_range_data.first <= global_index &&
00418 global_index < local_range_data.second);
00419 }
00420
00421
00422
00423 inline
00424 bool
00425 Partitioner::is_ghost_entry (const types::global_dof_index global_index) const
00426 {
00427
00428
00429 if (in_local_range(global_index) == true)
00430 return false;
00431 else
00432 return ghost_indices().is_element(global_index);
00433 }
00434
00435
00436
00437 inline
00438 unsigned int
00439 Partitioner::global_to_local (const types::global_dof_index global_index) const
00440 {
00441 Assert(in_local_range(global_index) || is_ghost_entry (global_index),
00442 ExcIndexNotPresent(global_index, my_pid));
00443 if (in_local_range(global_index))
00444 return global_index - local_range_data.first;
00445 else if (is_ghost_entry (global_index))
00446 return (local_size() +
00447 ghost_indices_data.index_within_set (global_index));
00448 else
00449
00450
00451
00452
00453
00454 return numbers::invalid_unsigned_int;
00455 }
00456
00457
00458
00459 inline
00460 types::global_dof_index
00461 Partitioner::local_to_global (const unsigned int local_index) const
00462 {
00463 AssertIndexRange (local_index, local_size() + n_ghost_indices_data);
00464 if (local_index < local_size())
00465 return local_range_data.first + local_index;
00466 else
00467 return ghost_indices_data.nth_index_in_set (local_index-local_size());
00468 }
00469
00470
00471
00472 inline
00473 const IndexSet& Partitioner::ghost_indices() const
00474 {
00475 return ghost_indices_data;
00476 }
00477
00478
00479
00480 inline
00481 unsigned int
00482 Partitioner::n_ghost_indices() const
00483 {
00484 return n_ghost_indices_data;
00485 }
00486
00487
00488
00489 inline
00490 const std::vector<std::pair<unsigned int,unsigned int> >&
00491 Partitioner::ghost_targets() const
00492 {
00493 return ghost_targets_data;
00494 }
00495
00496
00497 inline
00498 const std::vector<std::pair<unsigned int, unsigned int> >&
00499 Partitioner::import_indices() const
00500 {
00501 return import_indices_data;
00502 }
00503
00504
00505
00506 inline
00507 unsigned int
00508 Partitioner::n_import_indices() const
00509 {
00510 return n_import_indices_data;
00511 }
00512
00513
00514
00515 inline
00516 const std::vector<std::pair<unsigned int,unsigned int> >&
00517 Partitioner::import_targets() const
00518 {
00519 return import_targets_data;
00520 }
00521
00522
00523
00524 inline
00525 bool
00526 Partitioner::is_compatible (const Partitioner &part) const
00527 {
00528
00529
00530 if (&part == this)
00531 return true;
00532 else
00533 return (global_size == part.global_size &&
00534 local_range_data == part.local_range_data &&
00535 ghost_indices_data == part.ghost_indices_data);
00536 }
00537
00538
00539 inline
00540 unsigned int
00541 Partitioner::this_mpi_process() const
00542 {
00543
00544
00545
00546
00547
00548 return my_pid;
00549 }
00550
00551
00552
00553 inline
00554 unsigned int
00555 Partitioner::n_mpi_processes() const
00556 {
00557
00558
00559
00560
00561
00562 return n_procs;
00563 }
00564
00565
00566
00567 inline
00568 MPI_Comm
00569 Partitioner::get_communicator() const
00570 {
00571 return communicator;
00572 }
00573
00574 #endif // ifndef DOXYGEN
00575
00576 }
00577
00578 }
00579
00580
00581 DEAL_II_NAMESPACE_CLOSE
00582
00583 #endif
00584