include/deal.II/base/partitioner.h

00001 //---------------------------------------------------------------------------
00002 //    @f$Id: partitioner.h 25345 2012-03-31 08:37:04Z bangerth @f$
00003 //    Version: @f$Name@f$
00004 //
00005 //    Copyright (C) 2011, 2012 by deal.II authors
00006 //
00007 //    This file is subject to QPL and may not be  distributed
00008 //    without copyright and license information. Please refer
00009 //    to the file deal.II/doc/license.html for the  text  and
00010 //    further information on this license.
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 /*----------------------- Inline functions ----------------------------------*/
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                                 // if the index is in the global range, it is
00428                                 // trivially not a ghost
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                                 // should only end up here in
00450                                 // optimized mode, when we use this
00451                                 // large number to trigger a segfault
00452                                 // when using this method for array
00453                                 // access
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                                 // is the partitioner points to the same
00529                                 // memory location as the calling processor
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                                 // return the id from the variable stored in
00544                                 // this class instead of
00545                                 // Utilities::MPI::this_mpi_process() in order
00546                                 // to make this query also work when MPI is
00547                                 // not initialized.
00548       return my_pid;
00549     }
00550 
00551 
00552 
00553     inline
00554     unsigned int
00555     Partitioner::n_mpi_processes() const
00556     {
00557                                 // return the number of MPI processes from the
00558                                 // variable stored in this class instead of
00559                                 // Utilities::MPI::n_mpi_processes() in order
00560                                 // to make this query also work when MPI is
00561                                 // not initialized.
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   } // end of namespace MPI
00577 
00578 } // end of namespace Utilities
00579 
00580 
00581 DEAL_II_NAMESPACE_CLOSE
00582 
00583 #endif
00584 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

deal.II documentation generated on Wed May 23 2012 06:07:31 by doxygen 1.7.3