Parallel Namespace Reference


Namespaces

namespace  Utils

Classes

class  BinSorter
class  Histogram
class  Sort

Functions

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)

Function Documentation

template<typename Iterator , typename SyncFunctor >
void 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::datatype<sync::datum> if sync::datum isn't a built-in type.

Definition at line 230 of file parallel_ghost_sync.h.

References DofObject::id(), DofObject::invalid_processor_id, libMesh::n_processors(), libMesh::processor_id(), and DofObject::processor_id().

Referenced by MeshRefinement::make_flags_parallel_consistent().

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

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

Definition at line 110 of file parallel_ghost_sync.h.

References LocationMap< T >::empty(), LocationMap< T >::find(), DofObject::invalid_processor_id, std::max(), libMesh::n_processors(), LocationMap< T >::point_of(), and libMesh::processor_id().

00114 {
00115   // This function must be run on all processors at once
00116   parallel_only();
00117 
00118   // We need a valid location_map
00119 #ifdef DEBUG
00120   bool need_map_update = (range_begin != range_end && location_map.empty());
00121   Parallel::max(need_map_update);
00122   libmesh_assert(!need_map_update);
00123 #endif
00124 
00125   // Count the objectss to ask each processor about
00126   std::vector<unsigned int>
00127     ghost_objects_from_proc(libMesh::n_processors(), 0);
00128 
00129   for (Iterator it = range_begin; it != range_end; ++it)
00130     {
00131       DofObjType *obj = *it;
00132       libmesh_assert (obj);
00133       unsigned int obj_procid = obj->processor_id();
00134       libmesh_assert (obj_procid != DofObject::invalid_processor_id);
00135 
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<unsigned int> >
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 (unsigned int 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       unsigned int obj_procid = obj->processor_id();
00162       if (obj_procid == libMesh::processor_id())
00163         continue;
00164 
00165       Point p = location_map.point_of(*obj);
00166       requested_objs_x[obj_procid].push_back(p(0));
00167       requested_objs_y[obj_procid].push_back(p(1));
00168       requested_objs_z[obj_procid].push_back(p(2));
00169       requested_objs_id[obj_procid].push_back(obj->id());
00170     }
00171 
00172   // Trade requests with other processors
00173   for (unsigned int p=1; p != libMesh::n_processors(); ++p)
00174     {
00175       // Trade my requests with processor procup and procdown
00176       unsigned int procup = (libMesh::processor_id() + p) %
00177                              libMesh::n_processors();
00178       unsigned int procdown = (libMesh::n_processors() +
00179                                libMesh::processor_id() - p) %
00180                                libMesh::n_processors();
00181       std::vector<Real> request_to_fill_x,
00182                         request_to_fill_y,
00183                         request_to_fill_z;
00184       Parallel::send_receive(procup, requested_objs_x[procup],
00185                              procdown, request_to_fill_x);
00186       Parallel::send_receive(procup, requested_objs_y[procup],
00187                              procdown, request_to_fill_y);
00188       Parallel::send_receive(procup, requested_objs_z[procup],
00189                              procdown, request_to_fill_z);
00190 
00191       // Find the local id of each requested object
00192       std::vector<unsigned int> request_to_fill_id(request_to_fill_x.size());
00193       for (unsigned int i=0; i != request_to_fill_x.size(); ++i)
00194         {
00195           Point p(request_to_fill_x[i],
00196                   request_to_fill_y[i],
00197                   request_to_fill_z[i]);
00198 
00199           // Look for this object in the multimap
00200           DofObjType *obj = location_map.find(p);
00201 
00202           // We'd better find every object we're asked for
00203           libmesh_assert (obj);
00204 
00205           // Return the object's correct processor id,
00206           // and our (correct if it's local) id for it.
00207           request_to_fill_id[i] = obj->id();
00208         }
00209 
00210       // Gather whatever data the user wants
00211       std::vector<typename SyncFunctor::datum> data;
00212       sync.gather_data(request_to_fill_id, data);
00213 
00214       // Trade back the results
00215       std::vector<typename SyncFunctor::datum> received_data;
00216       Parallel::send_receive(procdown, data,
00217                              procup, received_data);
00218       libmesh_assert(requested_objs_x[procup].size() ==
00219                      received_data.size());
00220 
00221       // Let the user process the results
00222       sync.act_on_data(requested_objs_id[procup], received_data);
00223     }
00224 }

template<typename Iterator , typename DofObjType , typename SyncFunctor >
void 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::datatype<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 MeshCommunication::make_node_ids_parallel_consistent(), and MeshCommunication::make_node_proc_ids_parallel_consistent().

template<typename Iterator , typename SyncFunctor >
void 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::datatype<sync::datum> if sync::datum isn't a built-in type.

Definition at line 307 of file parallel_ghost_sync.h.

References Elem::active(), Elem::child(), MeshBase::elem(), Elem::has_children(), DofObject::id(), DofObject::invalid_processor_id, libMesh::n_processors(), Elem::parent(), libMesh::processor_id(), DofObject::processor_id(), and Elem::which_child_am_i().

Referenced by MeshCommunication::make_elems_parallel_consistent().

00311 {
00312   // This function must be run on all processors at once
00313   parallel_only();
00314 
00315   // Count the objects to ask each processor about
00316   std::vector<unsigned int>
00317     ghost_objects_from_proc(libMesh::n_processors(), 0);
00318 
00319   for (Iterator it = range_begin; it != range_end; ++it)
00320     {
00321       DofObject *obj = *it;
00322       libmesh_assert (obj);
00323       unsigned int obj_procid = obj->processor_id();
00324       libmesh_assert (obj_procid != DofObject::invalid_processor_id);
00325 
00326       ghost_objects_from_proc[obj_procid]++;
00327     }
00328 
00329   // Request sets to send to each processor
00330   std::vector<std::vector<unsigned int> >
00331     requested_objs_id(libMesh::n_processors()),
00332     requested_objs_parent_id(libMesh::n_processors()),
00333     requested_objs_child_num(libMesh::n_processors());
00334 
00335   // We know how many objects live on each processor, so reserve()
00336   // space for each.
00337   for (unsigned int p=0; p != libMesh::n_processors(); ++p)
00338     if (p != libMesh::processor_id())
00339       {
00340         requested_objs_id[p].reserve(ghost_objects_from_proc[p]);
00341         requested_objs_parent_id[p].reserve(ghost_objects_from_proc[p]);
00342         requested_objs_child_num[p].reserve(ghost_objects_from_proc[p]);
00343       }
00344 
00345   for (Iterator it = range_begin; it != range_end; ++it)
00346     {
00347       Elem *elem = *it;
00348       unsigned int obj_procid = elem->processor_id();
00349       if (obj_procid == libMesh::processor_id())
00350         continue;
00351       const Elem *parent = elem->parent();
00352       if (!parent || !elem->active())
00353         continue;
00354 
00355       requested_objs_id[obj_procid].push_back(elem->id());
00356       requested_objs_parent_id[obj_procid].push_back(parent->id());
00357       requested_objs_child_num[obj_procid].push_back
00358         (parent->which_child_am_i(elem));
00359     }
00360 
00361   // Trade requests with other processors
00362   for (unsigned int p=1; p != libMesh::n_processors(); ++p)
00363     {
00364       // Trade my requests with processor procup and procdown
00365       unsigned int procup = (libMesh::processor_id() + p) %
00366                              libMesh::n_processors();
00367       unsigned int procdown = (libMesh::n_processors() +
00368                                libMesh::processor_id() - p) %
00369                                libMesh::n_processors();
00370       std::vector<unsigned int> request_to_fill_parent_id,
00371                                 request_to_fill_child_num;
00372       Parallel::send_receive(procup, requested_objs_parent_id[procup],
00373                              procdown, request_to_fill_parent_id);
00374       Parallel::send_receive(procup, requested_objs_child_num[procup],
00375                              procdown, request_to_fill_child_num);
00376 
00377       // Find the id of each requested element
00378       unsigned int request_size = request_to_fill_parent_id.size();
00379       std::vector<unsigned int> request_to_fill_id(request_size);
00380       for (unsigned int i=0; i != request_size; ++i)
00381         {
00382           Elem *parent = mesh.elem(request_to_fill_parent_id[i]);
00383           libmesh_assert(parent);
00384           libmesh_assert(parent->has_children());
00385           Elem *child = parent->child(request_to_fill_child_num[i]);
00386           libmesh_assert(child);
00387           libmesh_assert(child->active());
00388           request_to_fill_id[i] = child->id();
00389         }
00390 
00391       // Gather whatever data the user wants
00392       std::vector<typename SyncFunctor::datum> data;
00393       sync.gather_data(request_to_fill_id, data);
00394 
00395       // Trade back the results
00396       std::vector<typename SyncFunctor::datum> received_data;
00397       Parallel::send_receive(procdown, data,
00398                              procup, received_data);
00399       libmesh_assert(requested_objs_id[procup].size() ==
00400                      received_data.size());
00401 
00402       // Let the user process the results
00403       sync.act_on_data(requested_objs_id[procup], received_data);
00404     }
00405 }


Site Created By: libMesh Developers
Last modified: November 25 2009 03:45:16.

Hosted By:
SourceForge.net Logo