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
| 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 }
| 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 }
| 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().
| 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 }