libMesh::Parallel Namespace Reference

Namespaces

namespace  Utils

Classes

class  DataPlusInt
struct  data_type
struct  request
struct  status
struct  communicator
class  MessageTag
class  DataType
class  StandardType
struct  Attributes
class  Status
struct  PostWaitWork
class  Request
class  Communicator
struct  PostWaitCopyBuffer
struct  PostWaitUnpackBuffer
struct  PostWaitDeleteBuffer
class  StandardType< TypeVector< T > >
class  StandardType< VectorValue< T > >
class  StandardType< Point >
class  StandardType< TypeTensor< T > >
class  StandardType< TensorValue< T > >
class  BinSorter
class  StandardType< Hilbert::HilbertIndices >
class  Histogram
class  StandardType< std::pair< T1, T2 > >
class  StandardType< std::complex< T > >
class  Sort

Typedefs

typedef MPI_Datatype data_type
typedef MPI_Request request
typedef MPI_Status status
typedef MPI_Comm communicator

Functions

template<>
unsigned int packed_size (const Elem *, std::vector< int >::const_iterator in)
template<>
unsigned int packable_size (const Elem *elem, const MeshBase *mesh)
template<>
unsigned int packable_size (const Elem *elem, const ParallelMesh *mesh)
template<>
void pack (const Elem *elem, std::vector< int > &data, const MeshBase *mesh)
template<>
void pack (const Elem *elem, std::vector< int > &data, const ParallelMesh *mesh)
template<>
void unpack (std::vector< int >::const_iterator in, Elem **out, MeshBase *mesh)
template<>
void unpack (std::vector< int >::const_iterator in, Elem **out, ParallelMesh *mesh)
template<>
unsigned int packable_size (const Node *node, const MeshBase *mesh)
template<>
unsigned int packed_size (const Node *, std::vector< int >::const_iterator in)
template<>
unsigned int packable_size (const Node *node, const ParallelMesh *mesh)
template<>
void pack (const Node *node, std::vector< int > &data, const MeshBase *mesh)
template<>
void pack (const Node *node, std::vector< int > &data, const ParallelMesh *mesh)
template<>
void unpack (std::vector< int >::const_iterator in, Node **out, MeshBase *mesh)
template<>
void unpack (std::vector< int >::const_iterator in, Node **out, ParallelMesh *mesh)
template<typename T >
data_type dataplusint_type ()
Status wait (Request &r)
void wait (std::vector< Request > &r)
template<typename T , typename Context >
void pack (const T *object, std::vector< int > &data, const Context *context)
template<typename T , typename Context >
unsigned int packable_size (const T *, const Context *)
template<typename T >
unsigned int packed_size (const T *, const std::vector< int >::const_iterator)
template<typename T , typename Context >
void unpack (std::vector< int >::const_iterator in, T **out, Context *)
template<typename Context , typename OutputIter >
void unpack_range (const std::vector< int > &buffer, Context *context, OutputIter out)
template<typename Context , typename Iter >
void pack_range (const Context *context, Iter range_begin, const Iter range_end, std::vector< int > &buffer)
template<typename Iterator , typename DofObjType , typename SyncFunctor >
void sync_dofobject_data_by_xyz (const Iterator &range_begin, const Iterator &range_end, LocationMap< DofObjType > *location_map, SyncFunctor &sync)
template<typename Iterator , typename SyncFunctor >
void sync_dofobject_data_by_id (const Iterator &range_begin, const Iterator &range_end, SyncFunctor &sync)
template<typename Iterator , typename SyncFunctor >
void sync_element_data_by_parent_id (MeshBase &mesh, const Iterator &range_begin, const Iterator &range_end, SyncFunctor &sync)
template<typename Iterator , typename DofObjType , typename SyncFunctor >
void sync_dofobject_data_by_xyz (const Iterator &range_begin, const Iterator &range_end, LocationMap< DofObjType > &location_map, SyncFunctor &sync)
 INT_TYPE (char, MPI_CHAR)
 INT_TYPE (signed char, MPI_SIGNED_CHAR)
 INT_TYPE (unsigned char, MPI_UNSIGNED_CHAR)
 INT_TYPE (short int, MPI_SHORT)
 INT_TYPE (unsigned short int, MPI_UNSIGNED_SHORT)
 INT_TYPE (int, MPI_INT)
 INT_TYPE (unsigned int, MPI_UNSIGNED)
 INT_TYPE (long, MPI_LONG)
 INT_TYPE (unsigned long, MPI_UNSIGNED_LONG)
 FLOAT_TYPE (float, MPI_FLOAT)
 FLOAT_TYPE (double, MPI_DOUBLE)
 FLOAT_TYPE (long double, MPI_LONG_DOUBLE)
 CONTAINER_TYPE (std::set)
 CONTAINER_TYPE (std::vector)
void barrier (const Communicator &comm=Communicator_World)
template<typename T >
bool verify (const T &r, const Communicator &comm=Communicator_World)
template<typename T >
void min (T &r, const Communicator &comm=Communicator_World)
template<typename T , typename U >
void minloc (T &r, U &min_id, const Communicator &comm=Communicator_World)
template<typename T >
void max (T &r, const Communicator &comm=Communicator_World)
template<typename T , typename U >
void maxloc (T &r, U &max_id, const Communicator &comm=Communicator_World)
template<typename T >
void sum (T &r, const Communicator &comm=Communicator_World)
template<typename T >
void set_union (T &data, const unsigned int root_id, const Communicator &comm=Communicator_World)
template<typename T >
void set_union (T &data, const Communicator &comm=Communicator_World)
status probe (const unsigned int src_processor_id, const MessageTag &tag=any_tag, const Communicator &comm=Communicator_World)
template<typename T >
void send (const unsigned int dest_processor_id, T &data, const MessageTag &tag=no_tag, const Communicator &comm=Communicator_World)
template<typename T >
void send (const unsigned int dest_processor_id, T &data, Request &req, const MessageTag &tag=no_tag, const Communicator &comm=Communicator_World)
template<typename T >
void send (const unsigned int dest_processor_id, T &data, const DataType &type, const MessageTag &tag=no_tag, const Communicator &comm=Communicator_World)
template<typename T >
void send (const unsigned int dest_processor_id, T &data, const DataType &type, Request &req, const MessageTag &tag=no_tag, const Communicator &comm=Communicator_World)
template<typename Context , typename Iter >
void send_packed_range (const unsigned int dest_processor_id, const Context *context, Iter range_begin, const Iter range_end, const MessageTag &tag=no_tag, const Communicator &comm=Communicator_World)
template<typename Context , typename Iter >
void send_packed_range (const unsigned int dest_processor_id, const Context *context, Iter range_begin, const Iter range_end, Request &req, const MessageTag &tag=no_tag, const Communicator &comm=Communicator_World)
template<typename T >
void nonblocking_send (const unsigned int dest_processor_id, T &buf, const DataType &type, Request &r, const MessageTag &tag=no_tag, const Communicator &comm=Communicator_World)
template<typename T >
void nonblocking_send (const unsigned int dest_processor_id, T &buf, Request &r, const MessageTag &tag=no_tag, const Communicator &comm=Communicator_World)
template<typename T >
Status receive (const unsigned int src_processor_id, T &buf, const MessageTag &tag=any_tag, const Communicator &comm=Communicator_World)
template<typename T >
void receive (const unsigned int src_processor_id, T &buf, Request &req, const MessageTag &tag=any_tag, const Communicator &comm=Communicator_World)
template<typename T >
Status receive (const unsigned int src_processor_id, T &buf, const DataType &type, const MessageTag &tag=any_tag, const Communicator &comm=Communicator_World)
template<typename T >
void receive (const unsigned int src_processor_id, T &buf, const DataType &type, Request &req, const MessageTag &tag=any_tag, const Communicator &comm=Communicator_World)
template<typename Context , typename OutputIter >
void receive_packed_range (const unsigned int src_processor_id, Context *context, OutputIter out, const MessageTag &tag=any_tag, const Communicator &comm=Communicator_World)
template<typename Context , typename OutputIter >
void receive_packed_range (const unsigned int src_processor_id, Context *context, OutputIter out, Request &req, const MessageTag &tag=any_tag, const Communicator &comm=Communicator_World)
template<typename T >
void nonblocking_receive (const unsigned int src_processor_id, T &buf, const DataType &type, Request &r, const MessageTag &tag=any_tag, const Communicator &comm=Communicator_World)
template<typename T >
void nonblocking_receive (const unsigned int src_processor_id, T &buf, Request &r, const MessageTag &tag=any_tag, const Communicator &comm=Communicator_World)
template<typename T1 , typename T2 >
void send_receive (const unsigned int dest_processor_id, T1 &send, const unsigned int source_processor_id, T2 &recv, const MessageTag &send_tag=no_tag, const MessageTag &recv_tag=any_tag, const Communicator &comm=Communicator_World)
template<typename Context1 , typename RangeIter , typename Context2 , typename OutputIter >
void send_receive_packed_range (const unsigned int dest_processor_id, const Context1 *context1, RangeIter send_begin, const RangeIter send_end, const unsigned int source_processor_id, Context2 *context2, OutputIter out, const MessageTag &send_tag=no_tag, const MessageTag &recv_tag=any_tag, const Communicator &comm=Communicator_World)
template<typename T1 , typename T2 >
void send_receive (const unsigned int dest_processor_id, T1 &send, const DataType &type1, const unsigned int source_processor_id, T2 &recv, const DataType &type2, const MessageTag &send_tag=no_tag, const MessageTag &recv_tag=any_tag, const Communicator &comm=Communicator_World)
template<typename T >
void gather (const unsigned int root_id, T send, std::vector< T > &recv, const Communicator &comm=Communicator_World)
template<typename T >
void gather (const unsigned int root_id, std::vector< T > &r, const Communicator &comm=Communicator_World)
template<typename T >
void allgather (T send, std::vector< T > &recv, const Communicator &comm=Communicator_World)
template<typename T >
void allgather (std::vector< T > &r, const bool identical_buffer_sizes=false, const Communicator &comm=Communicator_World)
template<typename Context , typename Iter , typename OutputIter >
void allgather_packed_range (Context *context, Iter range_begin, const Iter range_end, OutputIter out, const Communicator &comm=Communicator_World)
template<typename T >
void alltoall (std::vector< T > &r, const Communicator &comm=Communicator_World)
template<typename T >
void broadcast (T &data, const unsigned int root_id=0, const Communicator &comm=Communicator_World)
template<typename Context , typename OutputContext , typename Iter , typename OutputIter >
void broadcast_packed_range (const Context *context1, Iter range_begin, const Iter range_end, OutputContext *context2, OutputIter out, const unsigned int root_id=0, const Communicator &comm=Communicator_World)
template<>
data_type dataplusint_type< short int > ()
template<>
data_type dataplusint_type< int > ()
template<>
data_type dataplusint_type< long > ()
template<>
data_type dataplusint_type< float > ()
template<>
data_type dataplusint_type< double > ()
template<>
data_type dataplusint_type< long double > ()

Variables

const unsigned int any_source
const MessageTag any_tag = MessageTag(MPI_ANY_TAG)
const MessageTag no_tag = MessageTag(0)
CommunicatorCommunicator_World = CommWorld

Detailed Description

The Parallel namespace is for wrapper functions for common general parallel synchronization tasks.

For MPI 1.1 compatibility, temporary buffers are used instead of MPI 2's MPI_IN_PLACE


Typedef Documentation

Communicator object for talking with subsets of processors

Definition at line 104 of file parallel.h.

typedef MPI_Datatype libMesh::Parallel::data_type

Data types for communication

Definition at line 82 of file parallel.h.

typedef MPI_Request libMesh::Parallel::request

Request object for non-blocking I/O

Definition at line 94 of file parallel.h.

typedef MPI_Status libMesh::Parallel::status

Status object for querying messages

Definition at line 99 of file parallel.h.


Function Documentation

template<typename T >
void libMesh::Parallel::allgather ( std::vector< T > &  r,
const bool  identical_buffer_sizes = false,
const Communicator &  comm = Communicator_World 
) [inline]

Definition at line 1016 of file parallel_implementation.h.

References libMesh::Parallel::Communicator::allgather().

01019 { comm.allgather(r, identical_buffer_sizes); }

template<typename T >
void libMesh::Parallel::allgather ( send,
std::vector< T > &  recv,
const Communicator &  comm = Communicator_World 
) [inline]
template<typename Context , typename Iter , typename OutputIter >
void libMesh::Parallel::allgather_packed_range ( Context *  context,
Iter  range_begin,
const Iter  range_end,
OutputIter  out,
const Communicator &  comm = Communicator_World 
) [inline]

Definition at line 1022 of file parallel_implementation.h.

References libMesh::Parallel::Communicator::allgather_packed_range().

01027 { comm.allgather_packed_range(context, range_begin, range_end, out); }

template<typename T >
void libMesh::Parallel::alltoall ( std::vector< T > &  r,
const Communicator &  comm = Communicator_World 
) [inline]

Definition at line 1030 of file parallel_implementation.h.

References libMesh::Parallel::Communicator::alltoall().

01032 { comm.alltoall(r); }

void libMesh::Parallel::barrier ( const Communicator &  comm = Communicator_World  )  [inline]

Definition at line 750 of file parallel_implementation.h.

References libMesh::Parallel::Communicator::barrier().

00751 {
00752   comm.barrier();
00753 }

template<typename T >
void libMesh::Parallel::broadcast ( T &  data,
const unsigned int  root_id = 0,
const Communicator &  comm = Communicator_World 
) [inline]

Definition at line 1035 of file parallel_implementation.h.

References libMesh::Parallel::Communicator::broadcast().

Referenced by libMesh::Parallel::Communicator::broadcast_packed_range().

01037 { comm.broadcast(data, root_id); }

template<typename Context , typename OutputContext , typename Iter , typename OutputIter >
void libMesh::Parallel::broadcast_packed_range ( const Context *  context1,
Iter  range_begin,
const Iter  range_end,
OutputContext *  context2,
OutputIter  out,
const unsigned int  root_id = 0,
const Communicator &  comm = Communicator_World 
) [inline]

Definition at line 1040 of file parallel_implementation.h.

References libMesh::Parallel::Communicator::broadcast_packed_range().

01047 { comm.broadcast_packed_range(context1, range_begin, range_end, context2, out, root_id); }

libMesh::Parallel::CONTAINER_TYPE ( std::vector   ) 
libMesh::Parallel::CONTAINER_TYPE ( std::set   ) 
template<typename T >
data_type libMesh::Parallel::dataplusint_type (  )  [inline]

Templated function to return the appropriate MPI datatype for use with built-in C types when combined with an int

template<>
data_type libMesh::Parallel::dataplusint_type< double > (  )  [inline]
template<>
data_type libMesh::Parallel::dataplusint_type< float > (  )  [inline]
template<>
data_type libMesh::Parallel::dataplusint_type< int > (  )  [inline]
template<>
data_type libMesh::Parallel::dataplusint_type< long > (  )  [inline]
template<>
data_type libMesh::Parallel::dataplusint_type< long double > (  )  [inline]
template<>
data_type libMesh::Parallel::dataplusint_type< short int > (  )  [inline]
libMesh::Parallel::FLOAT_TYPE ( long  double,
MPI_LONG_DOUBLE   
)
libMesh::Parallel::FLOAT_TYPE ( double  ,
MPI_DOUBLE   
)
libMesh::Parallel::FLOAT_TYPE ( float  ,
MPI_FLOAT   
)
template<typename T >
void libMesh::Parallel::gather ( const unsigned int  root_id,
std::vector< T > &  r,
const Communicator &  comm = Communicator_World 
) [inline]

Definition at line 1004 of file parallel_implementation.h.

References libMesh::Parallel::Communicator::gather().

01007 { comm.gather(root_id, r); }

template<typename T >
void libMesh::Parallel::gather ( const unsigned int  root_id,
send,
std::vector< T > &  recv,
const Communicator &  comm = Communicator_World 
) [inline]

Definition at line 997 of file parallel_implementation.h.

References libMesh::Parallel::Communicator::gather().

01001 { comm.gather(root_id, send, recv); }

libMesh::Parallel::INT_TYPE ( unsigned  long,
MPI_UNSIGNED_LONG   
)
libMesh::Parallel::INT_TYPE ( long  ,
MPI_LONG   
)
libMesh::Parallel::INT_TYPE ( unsigned  int,
MPI_UNSIGNED   
)
libMesh::Parallel::INT_TYPE ( int  ,
MPI_INT   
)
libMesh::Parallel::INT_TYPE ( unsigned short  int,
MPI_UNSIGNED_SHORT   
)
libMesh::Parallel::INT_TYPE ( short  int,
MPI_SHORT   
)
libMesh::Parallel::INT_TYPE ( unsigned  char,
MPI_UNSIGNED_CHAR   
)
libMesh::Parallel::INT_TYPE ( signed  char,
MPI_SIGNED_CHAR   
)
libMesh::Parallel::INT_TYPE ( char  ,
MPI_CHAR   
)
template<typename T >
void libMesh::Parallel::max ( T &  r,
const Communicator &  comm = Communicator_World 
) [inline]

Definition at line 791 of file parallel_implementation.h.

References libMesh::Parallel::Communicator::max().

00793 { comm.max(r); }

template<typename T , typename U >
void libMesh::Parallel::maxloc ( T &  r,
U &  max_id,
const Communicator &  comm = Communicator_World 
) [inline]

Definition at line 796 of file parallel_implementation.h.

References libMesh::Parallel::Communicator::maxloc().

00799 { comm.maxloc(r, max_id); }

template<typename T >
void libMesh::Parallel::min ( T &  r,
const Communicator &  comm = Communicator_World 
) [inline]

Definition at line 780 of file parallel_implementation.h.

References libMesh::Parallel::Communicator::min().

00782 { comm.min(r); }

template<typename T , typename U >
void libMesh::Parallel::minloc ( T &  r,
U &  min_id,
const Communicator &  comm = Communicator_World 
) [inline]

Definition at line 785 of file parallel_implementation.h.

References libMesh::Parallel::Communicator::minloc().

00788 { comm.minloc(r, min_id); }

template<typename T >
void libMesh::Parallel::nonblocking_receive ( const unsigned int  src_processor_id,
T &  buf,
Request &  r,
const MessageTag &  tag = any_tag,
const Communicator &  comm = Communicator_World 
) [inline]

Definition at line 951 of file parallel_implementation.h.

References libMesh::Parallel::Communicator::receive().

00956 { comm.receive (src_processor_id, buf, r, tag); }

template<typename T >
void libMesh::Parallel::nonblocking_receive ( const unsigned int  src_processor_id,
T &  buf,
const DataType &  type,
Request &  r,
const MessageTag &  tag = any_tag,
const Communicator &  comm = Communicator_World 
) [inline]

Definition at line 942 of file parallel_implementation.h.

References libMesh::Parallel::Communicator::receive().

00948 { comm.receive (src_processor_id, buf, type, r, tag); }

template<typename T >
void libMesh::Parallel::nonblocking_send ( const unsigned int  dest_processor_id,
T &  buf,
Request &  r,
const MessageTag &  tag = no_tag,
const Communicator &  comm = Communicator_World 
) [inline]

Definition at line 885 of file parallel_implementation.h.

References libMesh::Parallel::Communicator::send().

00890 { comm.send (dest_processor_id, buf, r, tag); }

template<typename T >
void libMesh::Parallel::nonblocking_send ( const unsigned int  dest_processor_id,
T &  buf,
const DataType &  type,
Request &  r,
const MessageTag &  tag = no_tag,
const Communicator &  comm = Communicator_World 
) [inline]

Definition at line 876 of file parallel_implementation.h.

References libMesh::Parallel::Communicator::send().

00882 { comm.send (dest_processor_id, buf, type, r, tag); }

template<typename T , typename Context >
void libMesh::Parallel::pack ( const T *  object,
std::vector< int > &  data,
const Context *  context 
) [inline]

Encode a potentially-variable-size object at the end of a data array.

Parallel::pack() has no default implementation, and must be specialized for each class which is to be communicated via packed ranges.

template<>
void libMesh::Parallel::pack ( const Node node,
std::vector< int > &  data,
const ParallelMesh mesh 
) [inline]

Definition at line 153 of file parallel_node.C.

References pack().

00156 {
00157   pack(node, data, static_cast<const MeshBase*>(mesh));
00158 }

template<>
void libMesh::Parallel::pack ( const Node node,
std::vector< int > &  data,
const MeshBase mesh 
) [inline]

Definition at line 98 of file parallel_node.C.

References libMesh::MeshBase::boundary_info, libMesh::DofObject::id(), libMesh::DofObject::pack_indexing(), libMesh::DofObject::packed_indexing_size(), libMesh::DofObject::processor_id(), libMesh::Real, and libMesh::DofObject::unpackable_indexing_size().

00101 {
00102   libmesh_assert(node);
00103 
00104   // This should be redundant when used with Parallel::pack_range()
00105   // data.reserve (data.size() + Parallel::packable_size(node, mesh));
00106 
00107 #ifndef NDEBUG
00108   data.push_back (node_magic_header);
00109 #endif
00110 
00111   data.push_back (static_cast<int>(node->processor_id()));
00112   data.push_back (static_cast<int>(node->id()));
00113 
00114   // use "(a+b-1)/b" trick to get a/b to round up
00115   static const unsigned int ints_per_Real = 
00116     (sizeof(Real) + sizeof(int) - 1) / sizeof(int);
00117 
00118   for (unsigned int i=0; i != LIBMESH_DIM; ++i)
00119     {
00120       const int* Real_as_ints = reinterpret_cast<const int*>(&((*node)(i)));
00121       for (unsigned int j=0; j != ints_per_Real; ++j)
00122         {
00123           data.push_back(Real_as_ints[j]);
00124         }
00125     }
00126 
00127 #ifndef NDEBUG
00128   const int start_indices = data.size();
00129 #endif
00130   // Add any DofObject indices
00131   node->pack_indexing(std::back_inserter(data));
00132 
00133   libmesh_assert(node->packed_indexing_size() == 
00134                  DofObject::unpackable_indexing_size(data.begin() +
00135                                                      start_indices));
00136 
00137   libmesh_assert_equal_to (node->packed_indexing_size(),
00138                           data.size() - start_indices);
00139 
00140   // Add any nodal boundary condition ids
00141   std::vector<boundary_id_type> bcs =
00142     mesh->boundary_info->boundary_ids(node);
00143 
00144   data.push_back(bcs.size());
00145 
00146   for(unsigned int bc_it=0; bc_it < bcs.size(); bc_it++)
00147     data.push_back(bcs[bc_it]);
00148 }

template<>
void libMesh::Parallel::pack ( const Elem *  elem,
std::vector< int > &  data,
const ParallelMesh *  mesh 
) [inline]

Definition at line 223 of file parallel_elem.C.

References pack().

00226 {
00227   pack(elem, data, static_cast<const MeshBase*>(mesh));
00228 }

template<>
void libMesh::Parallel::pack ( const Elem *  elem,
std::vector< int > &  data,
const MeshBase *  mesh 
) [inline]

Definition at line 133 of file parallel_elem.C.

References libMesh::MeshBase::boundary_info, libMesh::DofObject::id(), libMesh::Elem::level(), libMesh::Elem::n_neighbors(), libMesh::Elem::n_nodes(), libMesh::Elem::n_sides(), libMesh::Elem::neighbor(), libMesh::Elem::node(), libMesh::Elem::p_level(), libMesh::Elem::p_refinement_flag(), libMesh::DofObject::pack_indexing(), libMesh::DofObject::packed_indexing_size(), libMesh::Elem::parent(), libMesh::DofObject::processor_id(), libMesh::Elem::refinement_flag(), libMesh::Elem::subdomain_id(), libMesh::Elem::type(), libMesh::DofObject::unpackable_indexing_size(), and libMesh::Elem::which_child_am_i().

Referenced by pack(), and pack_range().

00136 {
00137   libmesh_assert(elem);
00138 
00139   // This should be redundant when used with Parallel::pack_range()
00140   // data.reserve (data.size() + Parallel::packable_size(elem, mesh));
00141 
00142 #ifndef NDEBUG
00143   data.push_back (elem_magic_header);
00144 #endif
00145 
00146 #ifdef LIBMESH_ENABLE_AMR
00147   data.push_back (static_cast<int>(elem->level()));
00148   data.push_back (static_cast<int>(elem->p_level()));
00149   data.push_back (static_cast<int>(elem->refinement_flag()));
00150   data.push_back (static_cast<int>(elem->p_refinement_flag()));
00151 #else
00152   data.push_back (0);
00153   data.push_back (0);
00154   data.push_back (0);
00155   data.push_back (0);
00156 #endif
00157   data.push_back (static_cast<int>(elem->type()));
00158   data.push_back (elem->processor_id());
00159   data.push_back (elem->subdomain_id());
00160   data.push_back (elem->id());
00161 
00162 #ifdef LIBMESH_ENABLE_AMR
00163   // use parent_ID of -1 to indicate a level 0 element
00164   if (elem->level() == 0)
00165     {
00166       data.push_back(-1);
00167       data.push_back(-1);
00168     }
00169   else
00170     {
00171       data.push_back(elem->parent()->id());
00172       data.push_back(elem->parent()->which_child_am_i(elem));
00173     }
00174 #else
00175   data.push_back (-1);
00176   data.push_back (-1);
00177 #endif
00178 
00179   for (unsigned int n=0; n<elem->n_nodes(); n++)
00180     data.push_back (elem->node(n));
00181 
00182   for (unsigned int n=0; n<elem->n_neighbors(); n++)
00183     {
00184       const Elem *neigh = elem->neighbor(n);
00185       if (neigh)
00186         data.push_back (neigh->id());
00187       else
00188         data.push_back (-1);
00189     }
00190 
00191 #ifndef NDEBUG
00192   const int start_indices = data.size();
00193 #endif
00194   // Add any DofObject indices
00195   elem->pack_indexing(std::back_inserter(data));
00196 
00197   libmesh_assert(elem->packed_indexing_size() == 
00198                  DofObject::unpackable_indexing_size(data.begin() +
00199                                                      start_indices));
00200 
00201   libmesh_assert_equal_to (elem->packed_indexing_size(),
00202                           data.size() - start_indices);
00203 
00204 
00205   // If this is a coarse element,
00206   // Add any element side boundary condition ids
00207   if (elem->level() == 0)
00208     for (unsigned int s = 0; s != elem->n_sides(); ++s)
00209       {
00210         std::vector<boundary_id_type> bcs =
00211           mesh->boundary_info->boundary_ids(elem, s);
00212 
00213         data.push_back(bcs.size());
00214 
00215         for(unsigned int bc_it=0; bc_it < bcs.size(); bc_it++)
00216           data.push_back(bcs[bc_it]);
00217       }
00218 }

template<typename Context , typename Iter >
void libMesh::Parallel::pack_range ( const Context *  context,
Iter  range_begin,
const Iter  range_end,
std::vector< int > &  buffer 
) [inline]

Encode a range of potentially-variable-size objects to a data array.

Helper function for range packing

Definition at line 357 of file parallel_implementation.h.

References pack(), packable_size(), and packed_size().

Referenced by libMesh::Parallel::Communicator::allgather_packed_range(), libMesh::Parallel::Communicator::broadcast_packed_range(), and libMesh::Parallel::Communicator::send_packed_range().

00361 {
00362   // Count the total size of and preallocate buffer for efficiency
00363   unsigned int buffer_size = 0;
00364   for (Iter range_count = range_begin;
00365        range_count != range_end;
00366        ++range_count)
00367     {
00368       buffer_size += Parallel::packable_size(*range_count, context);
00369     }
00370   buffer.reserve(buffer.size() + buffer_size);
00371 
00372   // Pack the objects into the buffer
00373   for (; range_begin != range_end; ++range_begin)
00374     {
00375 #ifndef NDEBUG
00376       std::size_t old_size = buffer.size();
00377 #endif
00378 
00379       Parallel::pack(*range_begin, buffer, context);
00380 
00381 #ifndef NDEBUG
00382       unsigned int my_packable_size = 
00383         Parallel::packable_size(*range_begin, context);
00384       unsigned int my_packed_size = 
00385         Parallel::packed_size (*range_begin, buffer.begin() +
00386                                old_size);
00387       libmesh_assert_equal_to (my_packable_size, my_packed_size);
00388       libmesh_assert_equal_to (buffer.size(), old_size + my_packable_size);
00389 #endif
00390     }
00391 }

template<typename T , typename Context >
unsigned int libMesh::Parallel::packable_size ( const T *  ,
const Context *   
) [inline]

Output the number of integers required to encode a potentially-variable-size object into a data array.

Parallel::packable_size() has no default implementation, and must be specialized for each class which is to be communicated via packed ranges.

template<>
unsigned int libMesh::Parallel::packable_size ( const Node node,
const ParallelMesh mesh 
) [inline]

Definition at line 90 of file parallel_node.C.

References packable_size().

00091 {
00092   return packable_size(node, static_cast<const MeshBase*>(mesh));
00093 }

template<>
unsigned int libMesh::Parallel::packable_size ( const Node node,
const MeshBase mesh 
) [inline]

Definition at line 54 of file parallel_node.C.

References libMesh::MeshBase::boundary_info, and libMesh::DofObject::packed_indexing_size().

00055 {
00056   return
00057 #ifndef NDEBUG
00058          1 + // add an int for the magic header when testing
00059 #endif
00060          header_size + LIBMESH_DIM*ints_per_Real +
00061          node->packed_indexing_size() +
00062          1 + mesh->boundary_info->n_boundary_ids(node);
00063 }

template<>
unsigned int libMesh::Parallel::packable_size ( const Elem *  elem,
const ParallelMesh *  mesh 
) [inline]

Definition at line 125 of file parallel_elem.C.

References packable_size().

00126 {
00127   return packable_size(elem, static_cast<const MeshBase*>(mesh));
00128 }

template<>
unsigned int libMesh::Parallel::packable_size ( const Elem *  elem,
const MeshBase *  mesh 
) [inline]

Definition at line 103 of file parallel_elem.C.

References libMesh::MeshBase::boundary_info, libMesh::Elem::level(), libMesh::Elem::n_neighbors(), libMesh::Elem::n_nodes(), libMesh::Elem::n_sides(), and libMesh::DofObject::packed_indexing_size().

Referenced by pack_range(), and packable_size().

00104 {
00105   unsigned int total_packed_bcs = 0;
00106   if (elem->level() == 0)
00107     {
00108       total_packed_bcs += elem->n_sides();
00109       for (unsigned int s = 0; s != elem->n_sides(); ++s)
00110         total_packed_bcs += mesh->boundary_info->n_boundary_ids(elem,s);
00111     }
00112 
00113   return
00114 #ifndef NDEBUG
00115          1 + // add an int for the magic header when testing
00116 #endif
00117          header_size + elem->n_nodes() +
00118          elem->n_neighbors() +
00119          elem->packed_indexing_size() + total_packed_bcs;
00120 }

template<typename T >
unsigned int libMesh::Parallel::packed_size ( const T *  ,
const std::vector< int >::const_iterator   
) [inline]

Output the number of integers that were used to encode the next variable-size object in the data array.

Parallel::packed_size() has no default implementation, and must be specialized for each class which is to be communicated via packed ranges.

The output of this method should be based *only* on the data array; the T* argument is solely for function specialization.

template<>
unsigned int libMesh::Parallel::packed_size ( const Node ,
std::vector< int >::const_iterator  in 
) [inline]

Definition at line 68 of file parallel_node.C.

References libMesh::DofObject::unpackable_indexing_size().

00070 {
00071   const unsigned int pre_indexing_size = 
00072 #ifndef NDEBUG
00073     1 + // add an int for the magic header when testing
00074 #endif
00075     header_size + LIBMESH_DIM*ints_per_Real;
00076 
00077   const unsigned int indexing_size = 
00078     DofObject::unpackable_indexing_size(in+pre_indexing_size);
00079 
00080   const int n_bcs =
00081     *(in + pre_indexing_size + indexing_size);
00082   libmesh_assert_greater_equal (n_bcs, 0);
00083 
00084   return pre_indexing_size + indexing_size + 1 + n_bcs;
00085 }

template<>
unsigned int libMesh::Parallel::packed_size ( const Elem *  ,
std::vector< int >::const_iterator  in 
) [inline]

Definition at line 49 of file parallel_elem.C.

References libMeshEnums::INVALID_ELEM, n_nodes, libMesh::Elem::type_to_n_nodes_map, libMesh::Elem::type_to_n_sides_map, and libMesh::DofObject::unpackable_indexing_size().

Referenced by pack_range(), unpack(), and unpack_range().

00051 {
00052 #ifndef NDEBUG
00053   const int packed_header = *in++;
00054   libmesh_assert_equal_to (packed_header, elem_magic_header);
00055 #endif
00056 
00057   // int 0: level
00058   const unsigned int level =
00059     static_cast<unsigned int>(*in);
00060 
00061   // int 4: element type
00062   const int typeint = *(in+4);
00063   libmesh_assert_greater_equal (typeint, 0);
00064   libmesh_assert_less (typeint, INVALID_ELEM);
00065   const ElemType type =
00066     static_cast<ElemType>(typeint);
00067 
00068   const unsigned int n_nodes = 
00069     Elem::type_to_n_nodes_map[type];
00070 
00071   const unsigned int n_sides = 
00072     Elem::type_to_n_sides_map[type];
00073 
00074   const unsigned int pre_indexing_size = 
00075     header_size + n_nodes + n_sides;
00076 
00077   const unsigned int indexing_size = 
00078     DofObject::unpackable_indexing_size(in+pre_indexing_size);
00079 
00080   unsigned int total_packed_bc_data = 0;
00081   if (level == 0)
00082     {
00083       for (unsigned int s = 0; s != n_sides; ++s)
00084         {
00085           const int n_bcs = 
00086             *(in + pre_indexing_size + indexing_size +
00087               total_packed_bc_data++);
00088           libmesh_assert_greater_equal (n_bcs, 0);
00089           total_packed_bc_data += n_bcs;
00090         }
00091     }
00092 
00093   return 
00094 #ifndef NDEBUG
00095     1 + // Account for magic header
00096 #endif
00097     pre_indexing_size + indexing_size + total_packed_bc_data;
00098 }

status libMesh::Parallel::probe ( const unsigned int  src_processor_id,
const MessageTag &  tag = any_tag,
const Communicator &  comm = Communicator_World 
) [inline]

Definition at line 816 of file parallel_implementation.h.

References libMesh::Parallel::Communicator::probe().

00819 { return comm.probe(src_processor_id, tag); }

template<typename T >
void libMesh::Parallel::receive ( const unsigned int  src_processor_id,
T &  buf,
const DataType &  type,
Request &  req,
const MessageTag &  tag = any_tag,
const Communicator &  comm = Communicator_World 
) [inline]

Definition at line 916 of file parallel_implementation.h.

References libMesh::Parallel::Communicator::receive().

00922 { comm.receive (src_processor_id, buf, type, req, tag); }

template<typename T >
Status libMesh::Parallel::receive ( const unsigned int  src_processor_id,
T &  buf,
const DataType &  type,
const MessageTag &  tag = any_tag,
const Communicator &  comm = Communicator_World 
) [inline]

Definition at line 908 of file parallel_implementation.h.

References libMesh::Parallel::Communicator::receive().

00913 { return comm.receive (src_processor_id, buf, type, tag); }

template<typename T >
void libMesh::Parallel::receive ( const unsigned int  src_processor_id,
T &  buf,
Request &  req,
const MessageTag &  tag = any_tag,
const Communicator &  comm = Communicator_World 
) [inline]

Definition at line 900 of file parallel_implementation.h.

References libMesh::Parallel::Communicator::receive().

00905 { comm.receive (src_processor_id, buf, req, tag); }

template<typename T >
Status libMesh::Parallel::receive ( const unsigned int  src_processor_id,
T &  buf,
const MessageTag &  tag = any_tag,
const Communicator &  comm = Communicator_World 
) [inline]

Definition at line 893 of file parallel_implementation.h.

References libMesh::Parallel::Communicator::receive().

00897 { return comm.receive (src_processor_id, buf, tag); }

template<typename Context , typename OutputIter >
void libMesh::Parallel::receive_packed_range ( const unsigned int  src_processor_id,
Context *  context,
OutputIter  out,
Request &  req,
const MessageTag &  tag = any_tag,
const Communicator &  comm = Communicator_World 
) [inline]

Definition at line 933 of file parallel_implementation.h.

References libMesh::Parallel::Communicator::receive_packed_range().

00939 { comm.receive_packed_range (src_processor_id, context, out, req, tag); }

template<typename Context , typename OutputIter >
void libMesh::Parallel::receive_packed_range ( const unsigned int  src_processor_id,
Context *  context,
OutputIter  out,
const MessageTag &  tag = any_tag,
const Communicator &  comm = Communicator_World 
) [inline]

Definition at line 925 of file parallel_implementation.h.

References libMesh::Parallel::Communicator::receive_packed_range().

Referenced by libMesh::Parallel::Communicator::send_receive_packed_range().

00930 { comm.receive_packed_range (src_processor_id, context, out, tag); }

template<typename T >
void libMesh::Parallel::send ( const unsigned int  dest_processor_id,
T &  data,
const DataType &  type,
Request &  req,
const MessageTag &  tag = no_tag,
const Communicator &  comm = Communicator_World 
) [inline]

Definition at line 845 of file parallel_implementation.h.

References libMesh::Parallel::Communicator::send().

00851 { comm.send(dest_processor_id, data, type, req, tag); }

template<typename T >
void libMesh::Parallel::send ( const unsigned int  dest_processor_id,
T &  data,
const DataType &  type,
const MessageTag &  tag = no_tag,
const Communicator &  comm = Communicator_World 
) [inline]

Definition at line 837 of file parallel_implementation.h.

References libMesh::Parallel::Communicator::send().

00842 { comm.send(dest_processor_id, data, type, tag); }

template<typename T >
void libMesh::Parallel::send ( const unsigned int  dest_processor_id,
T &  data,
Request &  req,
const MessageTag &  tag = no_tag,
const Communicator &  comm = Communicator_World 
) [inline]

Definition at line 829 of file parallel_implementation.h.

References libMesh::Parallel::Communicator::send().

00834 { comm.send(dest_processor_id, data, req, tag); }

template<typename T >
void libMesh::Parallel::send ( const unsigned int  dest_processor_id,
T &  data,
const MessageTag &  tag = no_tag,
const Communicator &  comm = Communicator_World 
) [inline]

Definition at line 822 of file parallel_implementation.h.

References libMesh::Parallel::Communicator::send().

00826 { comm.send(dest_processor_id, data, tag); }

template<typename Context , typename Iter >
void libMesh::Parallel::send_packed_range ( const unsigned int  dest_processor_id,
const Context *  context,
Iter  range_begin,
const Iter  range_end,
Request &  req,
const MessageTag &  tag = no_tag,
const Communicator &  comm = Communicator_World 
) [inline]

Definition at line 865 of file parallel_implementation.h.

References libMesh::Parallel::Communicator::send_packed_range().

00872 { comm.send_packed_range(dest_processor_id, context, range_begin, range_end, req, tag); }

template<typename Context , typename Iter >
void libMesh::Parallel::send_packed_range ( const unsigned int  dest_processor_id,
const Context *  context,
Iter  range_begin,
const Iter  range_end,
const MessageTag &  tag = no_tag,
const Communicator &  comm = Communicator_World 
) [inline]

Definition at line 855 of file parallel_implementation.h.

References libMesh::Parallel::Communicator::send_packed_range().

Referenced by libMesh::Parallel::Communicator::send_receive_packed_range().

00861 { comm.send_packed_range(dest_processor_id, context, range_begin, range_end, tag); }

template<typename T1 , typename T2 >
void libMesh::Parallel::send_receive ( const unsigned int  dest_processor_id,
T1 &  send,
const DataType &  type1,
const unsigned int  source_processor_id,
T2 &  recv,
const DataType &  type2,
const MessageTag &  send_tag = no_tag,
const MessageTag &  recv_tag = any_tag,
const Communicator &  comm = Communicator_World 
) [inline]

Definition at line 984 of file parallel_implementation.h.

References libMesh::Parallel::Communicator::send_receive().

00993 { comm.send_receive(dest_processor_id, send, type1, source_processor_id,
00994                     recv, type2, send_tag, recv_tag); }

template<typename T1 , typename T2 >
void libMesh::Parallel::send_receive ( const unsigned int  dest_processor_id,
T1 &  send,
const unsigned int  source_processor_id,
T2 &  recv,
const MessageTag &  send_tag = no_tag,
const MessageTag &  recv_tag = any_tag,
const Communicator &  comm = Communicator_World 
) [inline]

Definition at line 959 of file parallel_implementation.h.

References libMesh::Parallel::Communicator::send_receive().

00966 { comm.send_receive(dest_processor_id, send, source_processor_id, recv,
00967                     send_tag, recv_tag); }

template<typename Context1 , typename RangeIter , typename Context2 , typename OutputIter >
void libMesh::Parallel::send_receive_packed_range ( const unsigned int  dest_processor_id,
const Context1 *  context1,
RangeIter  send_begin,
const RangeIter  send_end,
const unsigned int  source_processor_id,
Context2 *  context2,
OutputIter  out,
const MessageTag &  send_tag = no_tag,
const MessageTag &  recv_tag = any_tag,
const Communicator &  comm = Communicator_World 
) [inline]

Definition at line 970 of file parallel_implementation.h.

References libMesh::Parallel::Communicator::send_receive_packed_range().

00980 { comm.send_receive_packed_range(dest_processor_id, context1, send_begin, send_end,
00981                                  source_processor_id, context2, out, send_tag, recv_tag); }

template<typename T >
void libMesh::Parallel::set_union ( T &  data,
const Communicator &  comm = Communicator_World 
) [inline]

Definition at line 812 of file parallel_implementation.h.

References libMesh::Parallel::Communicator::set_union().

00814 { comm.set_union(data); }

template<typename T >
void libMesh::Parallel::set_union ( T &  data,
const unsigned int  root_id,
const Communicator &  comm = Communicator_World 
) [inline]

Definition at line 807 of file parallel_implementation.h.

References libMesh::Parallel::Communicator::set_union().

Referenced by libMesh::Nemesis_IO_Helper::compute_border_node_ids().

00809 { comm.set_union(data, root_id); }

template<typename T >
void libMesh::Parallel::sum ( T &  r,
const Communicator &  comm = Communicator_World 
) [inline]
template<typename Iterator , typename SyncFunctor >
void libMesh::Parallel::sync_dofobject_data_by_id ( const Iterator &  range_begin,
const Iterator &  range_end,
SyncFunctor &  sync 
) [inline]

Request data about a range of ghost dofobjects uniquely identified by their id. Fulfill requests with sync.gather_data(const std::vector<unsigned int>& ids, std::vector<sync::datum>& data), by resizing and setting the values of the data vector. Respond to fulfillment with sync.act_on_data(const std::vector<unsigned int>& ids, std::vector<sync::datum>& data) The user must define Parallel::StandardType<sync::datum> if sync::datum isn't a built-in type.

Definition at line 233 of file parallel_ghost_sync.h.

References libMesh::CommWorld, data, libMesh::DofObject::id(), libMesh::DofObject::invalid_processor_id, libMesh::n_processors(), libMesh::processor_id(), libMesh::DofObject::processor_id(), and libMesh::Parallel::Communicator::send_receive().

Referenced by libMesh::MeshRefinement::make_flags_parallel_consistent(), libMesh::FEMSystem::mesh_position_set(), and libMesh::LaplaceMeshSmoother::smooth().

00236 {
00237   // This function must be run on all processors at once
00238   parallel_only();
00239 
00240   // Count the objects to ask each processor about
00241   std::vector<dof_id_type>
00242     ghost_objects_from_proc(libMesh::n_processors(), 0);
00243 
00244   for (Iterator it = range_begin; it != range_end; ++it)
00245     {
00246       DofObject *obj = *it;
00247       libmesh_assert (obj);
00248       processor_id_type obj_procid = obj->processor_id();
00249       if (obj_procid != DofObject::invalid_processor_id)
00250         ghost_objects_from_proc[obj_procid]++;
00251     }
00252 
00253   // Request sets to send to each processor
00254   std::vector<std::vector<dof_id_type> >
00255     requested_objs_id(libMesh::n_processors());
00256 
00257   // We know how many objects live on each processor, so reserve()
00258   // space for each.
00259   for (processor_id_type p=0; p != libMesh::n_processors(); ++p)
00260     if (p != libMesh::processor_id())
00261       {
00262         requested_objs_id[p].reserve(ghost_objects_from_proc[p]);
00263       }
00264   for (Iterator it = range_begin; it != range_end; ++it)
00265     {
00266       DofObject *obj = *it;
00267       processor_id_type obj_procid = obj->processor_id();
00268       if (obj_procid == libMesh::processor_id() ||
00269           obj_procid == DofObject::invalid_processor_id)
00270         continue;
00271 
00272       requested_objs_id[obj_procid].push_back(obj->id());
00273     }
00274 
00275   // Trade requests with other processors
00276   for (processor_id_type p=1; p != libMesh::n_processors(); ++p)
00277     {
00278       // Trade my requests with processor procup and procdown
00279       const processor_id_type procup =
00280         libmesh_cast_int<processor_id_type>
00281           (libMesh::processor_id() + p) % libMesh::n_processors();
00282       const processor_id_type procdown =
00283         libmesh_cast_int<processor_id_type>
00284           ((libMesh::n_processors() + libMesh::processor_id() - p) %
00285            libMesh::n_processors());
00286       std::vector<dof_id_type> request_to_fill_id;
00287       CommWorld.send_receive(procup, requested_objs_id[procup],
00288                              procdown, request_to_fill_id);
00289 
00290       // Gather whatever data the user wants
00291       std::vector<typename SyncFunctor::datum> data;
00292       sync.gather_data(request_to_fill_id, data);
00293 
00294       // Trade back the results
00295       std::vector<typename SyncFunctor::datum> received_data;
00296       CommWorld.send_receive(procdown, data,
00297                              procup, received_data);
00298       libmesh_assert_equal_to (requested_objs_id[procup].size(),
00299                                received_data.size());
00300 
00301       // Let the user process the results
00302       sync.act_on_data(requested_objs_id[procup], received_data);
00303     }
00304 }

template<typename Iterator , typename DofObjType , typename SyncFunctor >
void libMesh::Parallel::sync_dofobject_data_by_xyz ( const Iterator &  range_begin,
const Iterator &  range_end,
LocationMap< DofObjType > &  location_map,
SyncFunctor &  sync 
) [inline]

Definition at line 111 of file parallel_ghost_sync.h.

References libMesh::CommWorld, data, libMesh::LocationMap< T >::empty(), libMesh::LocationMap< T >::find(), libMesh::DofObject::invalid_processor_id, libMesh::Parallel::Communicator::max(), libMesh::n_processors(), libMesh::LocationMap< T >::point_of(), libMesh::processor_id(), and libMesh::Parallel::Communicator::send_receive().

00115 {
00116   // This function must be run on all processors at once
00117   parallel_only();
00118 
00119   // We need a valid location_map
00120 #ifdef DEBUG
00121   bool need_map_update = (range_begin != range_end && location_map.empty());
00122   CommWorld.max(need_map_update);
00123   libmesh_assert(!need_map_update);
00124 #endif
00125 
00126   // Count the objectss to ask each processor about
00127   std::vector<dof_id_type>
00128     ghost_objects_from_proc(libMesh::n_processors(), 0);
00129 
00130   for (Iterator it = range_begin; it != range_end; ++it)
00131     {
00132       DofObjType *obj = *it;
00133       libmesh_assert (obj);
00134       processor_id_type obj_procid = obj->processor_id();
00135       if (obj_procid != DofObject::invalid_processor_id)
00136         ghost_objects_from_proc[obj_procid]++;
00137     }
00138 
00139   // Request sets to send to each processor
00140   std::vector<std::vector<Real> >
00141     requested_objs_x(libMesh::n_processors()),
00142     requested_objs_y(libMesh::n_processors()),
00143     requested_objs_z(libMesh::n_processors());
00144   // Corresponding ids to keep track of
00145   std::vector<std::vector<dof_id_type> >
00146     requested_objs_id(libMesh::n_processors());
00147 
00148   // We know how many objects live on each processor, so reserve()
00149   // space for each.
00150   for (processor_id_type p=0; p != libMesh::n_processors(); ++p)
00151     if (p != libMesh::processor_id())
00152       {
00153         requested_objs_x[p].reserve(ghost_objects_from_proc[p]);
00154         requested_objs_y[p].reserve(ghost_objects_from_proc[p]);
00155         requested_objs_z[p].reserve(ghost_objects_from_proc[p]);
00156         requested_objs_id[p].reserve(ghost_objects_from_proc[p]);
00157       }
00158   for (Iterator it = range_begin; it != range_end; ++it)
00159     {
00160       DofObjType *obj = *it;
00161       processor_id_type obj_procid = obj->processor_id();
00162       if (obj_procid == libMesh::processor_id() ||
00163           obj_procid == DofObject::invalid_processor_id)
00164         continue;
00165 
00166       Point p = location_map.point_of(*obj);
00167       requested_objs_x[obj_procid].push_back(p(0));
00168       requested_objs_y[obj_procid].push_back(p(1));
00169       requested_objs_z[obj_procid].push_back(p(2));
00170       requested_objs_id[obj_procid].push_back(obj->id());
00171     }
00172 
00173   // Trade requests with other processors
00174   for (processor_id_type p=1; p != libMesh::n_processors(); ++p)
00175     {
00176       // Trade my requests with processor procup and procdown
00177       const processor_id_type procup =
00178         libmesh_cast_int<processor_id_type>
00179           ((libMesh::processor_id() + p) % libMesh::n_processors());
00180       const processor_id_type procdown =
00181         libmesh_cast_int<processor_id_type>
00182           ((libMesh::n_processors() + libMesh::processor_id() - p) %
00183            libMesh::n_processors());
00184       std::vector<Real> request_to_fill_x,
00185                         request_to_fill_y,
00186                         request_to_fill_z;
00187       CommWorld.send_receive(procup, requested_objs_x[procup],
00188                              procdown, request_to_fill_x);
00189       CommWorld.send_receive(procup, requested_objs_y[procup],
00190                              procdown, request_to_fill_y);
00191       CommWorld.send_receive(procup, requested_objs_z[procup],
00192                              procdown, request_to_fill_z);
00193 
00194       // Find the local id of each requested object
00195       std::vector<dof_id_type> request_to_fill_id(request_to_fill_x.size());
00196       for (std::size_t i=0; i != request_to_fill_x.size(); ++i)
00197         {
00198           Point pt(request_to_fill_x[i],
00199                    request_to_fill_y[i],
00200                    request_to_fill_z[i]);
00201 
00202           // Look for this object in the multimap
00203           DofObjType *obj = location_map.find(pt);
00204 
00205           // We'd better find every object we're asked for
00206           libmesh_assert (obj);
00207 
00208           // Return the object's correct processor id,
00209           // and our (correct if it's local) id for it.
00210           request_to_fill_id[i] = obj->id();
00211         }
00212 
00213       // Gather whatever data the user wants
00214       std::vector<typename SyncFunctor::datum> data;
00215       sync.gather_data(request_to_fill_id, data);
00216 
00217       // Trade back the results
00218       std::vector<typename SyncFunctor::datum> received_data;
00219       CommWorld.send_receive(procdown, data,
00220                              procup, received_data);
00221       libmesh_assert_equal_to (requested_objs_x[procup].size(),
00222                                received_data.size());
00223 
00224       // Let the user process the results
00225       sync.act_on_data(requested_objs_id[procup], received_data);
00226     }
00227 }

template<typename Iterator , typename DofObjType , typename SyncFunctor >
void libMesh::Parallel::sync_dofobject_data_by_xyz ( const Iterator &  range_begin,
const Iterator &  range_end,
LocationMap< DofObjType > *  location_map,
SyncFunctor &  sync 
) [inline]

Request data about a range of ghost nodes uniquely identified by their xyz location or a range of active ghost elements uniquely identified by their centroids' xyz location. Fulfill requests with sync.gather_data(const std::vector<unsigned int>& ids, std::vector<sync::datum>& data), by resizing and setting the values of the data vector. Respond to fulfillment with sync.act_on_data(const std::vector<unsigned int>& ids, std::vector<sync::datum>& data) The user must define Parallel::StandardType<sync::datum> if sync::datum isn't a built-in type. The user-provided location_map will be used and left unchanged if it is provided, or filled and cleared if it is empty.

Referenced by libMesh::MeshCommunication::make_node_ids_parallel_consistent(), and libMesh::MeshCommunication::make_node_proc_ids_parallel_consistent().

template<typename Iterator , typename SyncFunctor >
void libMesh::Parallel::sync_element_data_by_parent_id ( MeshBase &  mesh,
const Iterator &  range_begin,
const Iterator &  range_end,
SyncFunctor &  sync 
) [inline]

Request data about a range of ghost elements uniquely identified by their parent id and which child they are. Fulfill requests with sync.gather_data(const std::vector<unsigned int>& ids, std::vector<sync::datum>& data), by resizing and setting the values of the data vector. Respond to fulfillment with sync.act_on_data(const std::vector<unsigned int>& ids, std::vector<sync::datum>& data) The user must define Parallel::StandardType<sync::datum> if sync::datum isn't a built-in type.

Definition at line 418 of file parallel_ghost_sync.h.

Referenced by libMesh::MeshCommunication::make_elems_parallel_consistent().

00422 {
00423 }

template<typename T , typename Context >
void libMesh::Parallel::unpack ( std::vector< int >::const_iterator  in,
T **  out,
Context *   
) [inline]

Decode a potentially-variable-size object from a subsequence of a data array.

Parallel::unpack() has no default implementation, and must be specialized for each class which is to be communicated via packed ranges.

template<>
void libMesh::Parallel::unpack ( std::vector< int >::const_iterator  in,
Node **  out,
ParallelMesh mesh 
) [inline]

Definition at line 258 of file parallel_node.C.

References unpack().

00261 {
00262   unpack(in, out, static_cast<MeshBase*>(mesh));
00263 }

template<>
void libMesh::Parallel::unpack ( std::vector< int >::const_iterator  in,
Node **  out,
MeshBase mesh 
) [inline]

Definition at line 163 of file parallel_node.C.

References libMesh::MeshBase::boundary_info, libMesh::DofObject::has_dofs(), libMesh::DofObject::invalid_processor_id, libMesh::n_processors(), libMesh::DofObject::packed_indexing_size(), packed_size(), libMesh::DofObject::processor_id(), libMesh::processor_id(), libMesh::MeshBase::query_node_ptr(), libMesh::Real, libMesh::DofObject::set_id(), libMesh::DofObject::unpack_indexing(), and libMesh::DofObject::unpackable_indexing_size().

00166 {
00167 #ifndef NDEBUG
00168   const std::vector<int>::const_iterator original_in = in;
00169   const int incoming_header = *in++;
00170   libmesh_assert_equal_to (incoming_header, node_magic_header);
00171 #endif
00172 
00173   const unsigned int processor_id = static_cast<unsigned int>(*in++);
00174   libmesh_assert(processor_id == DofObject::invalid_processor_id ||
00175                  processor_id < libMesh::n_processors());
00176 
00177   const unsigned int id = static_cast<unsigned int>(*in++);
00178 
00179   Node *node = mesh->query_node_ptr(id);
00180 
00181   if (node)
00182     {
00183       libmesh_assert_equal_to (node->processor_id(), processor_id);
00184 
00185       // We currently don't communicate mesh motion via packed Nodes,
00186       // so it should be safe to assume (and assert) that Node
00187       // locations are consistent between processors
00188 #ifndef NDEBUG
00189       for (unsigned int i=0; i != LIBMESH_DIM; ++i)
00190         {
00191           const Real* ints_as_Real = reinterpret_cast<const Real*>(&(*in));
00192           libmesh_assert_equal_to ((*node)(i), *ints_as_Real);
00193           in += ints_per_Real;
00194         }
00195 #else
00196       in += LIBMESH_DIM * ints_per_Real;
00197 #endif // !NDEBUG
00198 
00199       if (!node->has_dofs())
00200         {
00201           node->unpack_indexing(in);
00202           libmesh_assert_equal_to (DofObject::unpackable_indexing_size(in),
00203                                    node->packed_indexing_size());
00204           in += node->packed_indexing_size();
00205         }
00206       else
00207         {
00208           // FIXME: We should add some debug mode tests to ensure that
00209           // the encoded indexing is consistent
00210           in += DofObject::unpackable_indexing_size(in);
00211         }
00212 
00213       *out = node;
00214     }
00215   else
00216     {
00217       // If we don't already have it, we need to allocate it
00218       node = new Node();
00219 
00220       for (unsigned int i=0; i != LIBMESH_DIM; ++i)
00221         {
00222           const Real* ints_as_Real = reinterpret_cast<const Real*>(&(*in));
00223           (*node)(i) = *ints_as_Real;
00224           in += ints_per_Real;
00225         }
00226 
00227       node->set_id() = id;
00228       node->processor_id() = processor_id;
00229 
00230       node->unpack_indexing(in);
00231       libmesh_assert_equal_to (DofObject::unpackable_indexing_size(in),
00232                                node->packed_indexing_size());
00233       in += node->packed_indexing_size();
00234     }
00235 
00236   // FIXME: We should add some debug mode tests to ensure that the
00237   // encoded boundary conditions are consistent
00238 
00239   // Add any nodal boundary condition ids
00240   const int num_bcs = *in++;
00241   libmesh_assert_greater_equal (num_bcs, 0);
00242 
00243   for(int bc_it=0; bc_it < num_bcs; bc_it++)
00244     mesh->boundary_info->add_node (node, *in++);
00245 
00246   *out = node;
00247 
00248 #ifndef NDEBUG
00249   libmesh_assert (in - original_in == 
00250                   static_cast<int>
00251                     (Parallel::packed_size(node, original_in)));
00252 #endif
00253 }

template<>
void libMesh::Parallel::unpack ( std::vector< int >::const_iterator  in,
Elem **  out,
ParallelMesh *  mesh 
) [inline]

Definition at line 529 of file parallel_elem.C.

References unpack().

00532 {
00533   unpack(in, out, static_cast<MeshBase*>(mesh));
00534 }

template<>
void libMesh::Parallel::unpack ( std::vector< int >::const_iterator  in,
Elem **  out,
MeshBase *  mesh 
) [inline]

Definition at line 234 of file parallel_elem.C.

References libMesh::Elem::active(), libMesh::Elem::add_child(), libMesh::MeshBase::boundary_info, libMesh::Elem::build(), libMesh::Elem::child(), libMesh::MeshBase::elem(), libMesh::DofObject::id(), libMeshEnums::INVALID_ELEM, libMesh::DofObject::invalid_id, libMesh::DofObject::invalid_processor_id, libMesh::Elem::INVALID_REFINEMENTSTATE, libMesh::Elem::level(), libMesh::Elem::make_links_to_me_local(), libMesh::Elem::n_children(), libMesh::Elem::n_neighbors(), libMesh::Elem::n_nodes(), n_nodes, libMesh::n_processors(), libMesh::Elem::n_sides(), libMesh::Elem::neighbor(), libMesh::Elem::node(), libMesh::MeshBase::node_ptr(), libMesh::Elem::p_level(), libMesh::Elem::p_refinement_flag(), libMesh::DofObject::packed_indexing_size(), libMesh::Elem::parent(), libMesh::DofObject::processor_id(), libMesh::processor_id(), libMesh::MeshBase::query_elem(), libMesh::Elem::refinement_flag(), libMesh::AutoPtr< Tp >::release(), libMesh::remote_elem, libMesh::DofObject::set_id(), libMesh::Elem::set_neighbor(), libMesh::Elem::set_node(), libMesh::Elem::set_p_level(), libMesh::Elem::set_p_refinement_flag(), libMesh::Elem::set_refinement_flag(), libMesh::Elem::subdomain_id(), libMesh::Elem::type(), libMesh::Elem::type_to_n_nodes_map, and libMesh::DofObject::unpack_indexing().

Referenced by unpack(), and unpack_range().

00237 {
00238 #ifndef NDEBUG
00239   const std::vector<int>::const_iterator original_in = in;
00240 
00241   const int incoming_header = *in++;
00242   libmesh_assert_equal_to (incoming_header, elem_magic_header);
00243 #endif
00244 
00245   // int 0: level
00246   const unsigned int level =
00247     static_cast<unsigned int>(*in++);
00248 
00249 #ifdef LIBMESH_ENABLE_AMR
00250   // int 1: p level
00251   const unsigned int p_level =
00252     static_cast<unsigned int>(*in++);
00253 
00254   // int 2: refinement flag
00255   const int rflag = *in++;
00256   libmesh_assert_greater_equal (rflag, 0);
00257   libmesh_assert_less (rflag, Elem::INVALID_REFINEMENTSTATE);
00258   const Elem::RefinementState refinement_flag =
00259     static_cast<Elem::RefinementState>(rflag);
00260 
00261   // int 3: p refinement flag
00262   const int pflag = *in++;
00263   libmesh_assert_greater_equal (pflag, 0);
00264   libmesh_assert_less (pflag, Elem::INVALID_REFINEMENTSTATE);
00265   const Elem::RefinementState p_refinement_flag =
00266     static_cast<Elem::RefinementState>(pflag);
00267 #else
00268   in += 3;
00269 #endif // LIBMESH_ENABLE_AMR
00270 
00271   // int 4: element type
00272   const int typeint = *in++;
00273   libmesh_assert_greater_equal (typeint, 0);
00274   libmesh_assert_less (typeint, INVALID_ELEM);
00275   const ElemType type =
00276     static_cast<ElemType>(typeint);
00277 
00278   const unsigned int n_nodes = 
00279     Elem::type_to_n_nodes_map[type];
00280 
00281   // int 5: processor id
00282   const unsigned int processor_id = 
00283     static_cast<unsigned int>(*in++);
00284   libmesh_assert (processor_id < libMesh::n_processors() ||
00285                   processor_id == DofObject::invalid_processor_id);
00286 
00287   // int 6: subdomain id
00288   const unsigned int subdomain_id = 
00289     static_cast<unsigned int>(*in++);
00290 
00291   // int 7: dof object id
00292   const dof_id_type id = 
00293     static_cast<dof_id_type>(*in++);
00294   libmesh_assert_not_equal_to (id, DofObject::invalid_id);
00295 
00296 #ifdef LIBMESH_ENABLE_AMR
00297   // int 8: parent dof object id
00298   const dof_id_type parent_id = 
00299     static_cast<dof_id_type>(*in++);
00300   libmesh_assert (level == 0 || parent_id != DofObject::invalid_id);
00301   libmesh_assert (level != 0 || parent_id == DofObject::invalid_id);
00302 
00303   // int 9: local child id
00304   const unsigned int which_child_am_i = 
00305     static_cast<unsigned int>(*in++);
00306 #else
00307   in += 2;
00308 #endif // LIBMESH_ENABLE_AMR
00309 
00310   // Make sure we don't miscount above when adding the "magic" header
00311   // plus the real data header
00312   libmesh_assert_equal_to (in - original_in, header_size + 1);
00313 
00314   Elem *elem = mesh->query_elem(id);
00315 
00316   // if we already have this element, make sure its
00317   // properties match, and update any missing neighbor
00318   // links, but then go on
00319   if (elem) 
00320     {
00321       libmesh_assert_equal_to (elem->level(), level);
00322       libmesh_assert_equal_to (elem->id(), id);
00323       libmesh_assert_equal_to (elem->processor_id(), processor_id);
00324       libmesh_assert_equal_to (elem->subdomain_id(), subdomain_id);
00325       libmesh_assert_equal_to (elem->type(), type);
00326       libmesh_assert_equal_to (elem->n_nodes(), n_nodes);
00327 
00328 #ifndef NDEBUG
00329       // All our nodes should be correct
00330       for (unsigned int i=0; i != n_nodes; ++i)
00331         libmesh_assert(elem->node(i) == 
00332                        static_cast<unsigned int>(*in++));
00333 #else
00334       in += n_nodes;
00335 #endif
00336 
00337 #ifdef LIBMESH_ENABLE_AMR
00338       libmesh_assert_equal_to (elem->p_level(), p_level);
00339       libmesh_assert_equal_to (elem->refinement_flag(), refinement_flag);
00340       libmesh_assert_equal_to (elem->p_refinement_flag(), p_refinement_flag);
00341 
00342       libmesh_assert (!level || elem->parent() != NULL);
00343       libmesh_assert (!level || elem->parent()->id() == parent_id);
00344       libmesh_assert (!level || elem->parent()->child(which_child_am_i) == elem);
00345 #endif
00346 
00347       // Our neighbor links should be "close to" correct - we may have
00348       // to update them, but we can check for some inconsistencies.
00349       for (unsigned int n=0; n != elem->n_neighbors(); ++n)
00350         {
00351           const dof_id_type neighbor_id =
00352             static_cast<dof_id_type>(*in++);
00353 
00354           // If the sending processor sees a domain boundary here,
00355           // we'd better agree.
00356           if (neighbor_id == DofObject::invalid_id)
00357             {
00358               libmesh_assert (!(elem->neighbor(n)));
00359               continue;
00360             }
00361 
00362           // If the sending processor has a remote_elem neighbor here,
00363           // then all we know is that we'd better *not* have a domain
00364           // boundary.
00365           if (neighbor_id == remote_elem->id())
00366             {
00367               libmesh_assert(elem->neighbor(n));
00368               continue;
00369             }
00370 
00371           Elem *neigh = mesh->query_elem(neighbor_id);
00372 
00373           // The sending processor sees a neighbor here, so if we
00374           // don't have that neighboring element, then we'd better
00375           // have a remote_elem signifying that fact.
00376           if (!neigh)
00377             {
00378               libmesh_assert_equal_to (elem->neighbor(n), remote_elem);
00379               continue;
00380             }
00381 
00382           // The sending processor has a neighbor here, and we have
00383           // that element, but that does *NOT* mean we're already
00384           // linking to it.  Perhaps we initially received both elem
00385           // and neigh from processors on which their mutual link was
00386           // remote?
00387           libmesh_assert(elem->neighbor(n) == neigh ||
00388                          elem->neighbor(n) == remote_elem);
00389 
00390           // If the link was originally remote, we should update it,
00391           // and make sure the appropriate parts of its family link
00392           // back to us.
00393           if (elem->neighbor(n) == remote_elem)
00394             {
00395               elem->set_neighbor(n, neigh); 
00396 
00397               elem->make_links_to_me_local(n); 
00398             }
00399         }
00400 
00401       // FIXME: We should add some debug mode tests to ensure that the
00402       // encoded indexing and boundary conditions are consistent.
00403     }
00404   else
00405     {
00406       // We don't already have the element, so we need to create it.
00407 
00408       // Find the parent if necessary
00409       Elem *parent = NULL;
00410 #ifdef LIBMESH_ENABLE_AMR
00411       // Find a child element's parent
00412       if (level > 0)
00413         {
00414           // Note that we must be very careful to construct the send
00415           // connectivity so that parents are encountered before
00416           // children.  If we get here and can't find the parent that
00417           // is a fatal error.
00418           parent = mesh->elem(parent_id);
00419         }
00420       // Or assert that the sending processor sees no parent
00421       else
00422         libmesh_assert_equal_to (parent_id, static_cast<unsigned int>(-1));
00423 #else
00424       // No non-level-0 elements without AMR
00425       libmesh_assert_equal_to (level, 0);
00426 #endif
00427 
00428       elem = Elem::build(type,parent).release();
00429       libmesh_assert (elem);
00430 
00431 #ifdef LIBMESH_ENABLE_AMR
00432       if (level != 0)
00433         {
00434           // Since this is a newly created element, the parent must
00435           // have previously thought of this child as a remote element.
00436           libmesh_assert_equal_to (parent->child(which_child_am_i), remote_elem);
00437 
00438           parent->add_child(elem, which_child_am_i);
00439         }
00440 
00441       // Assign the refinement flags and levels
00442       elem->set_p_level(p_level);
00443       elem->set_refinement_flag(refinement_flag);
00444       elem->set_p_refinement_flag(p_refinement_flag);
00445       libmesh_assert_equal_to (elem->level(), level);
00446 
00447       // If this element definitely should have children, assign
00448       // remote_elem to all of them for now, for consistency.  Later
00449       // unpacked elements may overwrite that.
00450       if (!elem->active())
00451         for (unsigned int c=0; c != elem->n_children(); ++c)
00452           elem->add_child(const_cast<RemoteElem*>(remote_elem), c);
00453 
00454 #endif // LIBMESH_ENABLE_AMR
00455 
00456       // Assign the IDs
00457       elem->subdomain_id() = subdomain_id;
00458       elem->processor_id() = processor_id;
00459       elem->set_id()       = id;
00460 
00461       // Assign the connectivity
00462       libmesh_assert_equal_to (elem->n_nodes(), n_nodes);
00463 
00464       for (unsigned int n=0; n != n_nodes; n++)
00465         elem->set_node(n) =
00466           mesh->node_ptr
00467             (static_cast<unsigned int>(*in++));
00468 
00469       for (unsigned int n=0; n<elem->n_neighbors(); n++)
00470         {
00471           const dof_id_type neighbor_id =
00472             static_cast<dof_id_type>(*in++);
00473 
00474           if (neighbor_id == DofObject::invalid_id)
00475             continue;
00476 
00477           // We may be unpacking an element that was a ghost element on the
00478           // sender, in which case the element's neighbors may not all be
00479           // known by the packed element.  We'll have to set such
00480           // neighbors to remote_elem ourselves and wait for a later
00481           // packed element to give us better information.
00482           if (neighbor_id == remote_elem->id())
00483             {
00484               elem->set_neighbor(n, const_cast<RemoteElem*>(remote_elem));
00485               continue;
00486             }
00487 
00488           // If we don't have the neighbor element, then it's a
00489           // remote_elem until we get it.
00490           Elem *neigh = mesh->query_elem(neighbor_id);
00491           if (!neigh)
00492             {
00493               elem->set_neighbor(n, const_cast<RemoteElem*>(remote_elem));
00494               continue;
00495             }
00496 
00497           // If we have the neighbor element, then link to it, and
00498           // make sure the appropriate parts of its family link back
00499           // to us.
00500           elem->set_neighbor(n, neigh);
00501 
00502           elem->make_links_to_me_local(n);
00503         }
00504 
00505       elem->unpack_indexing(in);
00506     }
00507 
00508   in += elem->packed_indexing_size();
00509 
00510   // If this is a coarse element,
00511   // add any element side boundary condition ids
00512   if (level == 0)
00513     for (unsigned int s = 0; s != elem->n_sides(); ++s)
00514       {
00515         const int num_bcs = *in++;
00516         libmesh_assert_greater_equal (num_bcs, 0);
00517 
00518         for(int bc_it=0; bc_it < num_bcs; bc_it++)
00519           mesh->boundary_info->add_side (elem, s, *in++);
00520       }
00521 
00522   // Return the new element
00523   *out = elem;
00524 }

template<typename Context , typename OutputIter >
void libMesh::Parallel::unpack_range ( const std::vector< int > &  buffer,
Context *  context,
OutputIter  out 
) [inline]

Decode a range of potentially-variable-size objects from a data array.

Helper function for range unpacking

Definition at line 399 of file parallel_implementation.h.

References packed_size(), and unpack().

Referenced by libMesh::Parallel::Communicator::allgather_packed_range(), libMesh::Parallel::Communicator::broadcast_packed_range(), libMesh::Parallel::Communicator::receive_packed_range(), and libMesh::Parallel::PostWaitUnpackBuffer< Container, Context, OutputIter >::run().

00402 {
00403   // Our objects should be of the correct type to be assigned to the
00404   // output iterator
00405   typedef typename std::iterator_traits<OutputIter>::value_type T;
00406 
00407   // Loop through the buffer and unpack each object, returning the
00408   // object pointer via the output iterator
00409   std::vector<int>::const_iterator next_object_start = buffer.begin();
00410 
00411   while (next_object_start < buffer.end())
00412     {
00413       T* obj;
00414       Parallel::unpack(next_object_start, &obj, context);
00415       libmesh_assert(obj);
00416       next_object_start += Parallel::packed_size(obj, next_object_start);
00417       *out++ = obj;
00418     }
00419 
00420   // We should have used up the exact amount of data in the buffer
00421   libmesh_assert (next_object_start == buffer.end());
00422 }

template<typename T >
bool libMesh::Parallel::verify ( const T &  r,
const Communicator &  comm = Communicator_World 
) [inline]

Definition at line 775 of file parallel_implementation.h.

References libMesh::Parallel::Communicator::verify().

Referenced by libMesh::Parallel::Communicator::allgather().

00777 { return comm.verify(r); }

void libMesh::Parallel::wait ( std::vector< Request > &  r  )  [inline]

Wait for a non-blocking send or receive to finish

Definition at line 420 of file parallel.h.

References wait().

00421   { for (unsigned int i=0; i<r.size(); i++) r[i].wait(); }

Status libMesh::Parallel::wait ( Request &  r  )  [inline]

Variable Documentation

const unsigned int libMesh::Parallel::any_source
Initial value:
    static_cast<unsigned int>(MPI_ANY_SOURCE)

Accept from any source

Definition at line 127 of file parallel.h.

Referenced by libMesh::Nemesis_IO::read(), libMesh::System::read_serialized_blocked_dof_objects(), and libMesh::System::write_serialized_blocked_dof_objects().

Default message tag ids

Definition at line 200 of file parallel.h.

Referenced by libMesh::Parallel::Communicator::send_receive().


Site Created By: libMesh Developers
Last modified: February 05 2013 19:55:44 UTC

Hosted By:
SourceForge.net Logo