libMesh::CentroidPartitioner Class Reference
#include <centroid_partitioner.h>

Public Types | |
| enum | CentroidSortMethod { X = 0, Y, Z, RADIAL, INVALID_METHOD } |
Public Member Functions | |
| CentroidPartitioner (const CentroidSortMethod sm=X) | |
| virtual AutoPtr< Partitioner > | clone () const |
| CentroidSortMethod | sort_method () const |
| void | set_sort_method (const CentroidSortMethod sm) |
| void | partition (MeshBase &mesh, const unsigned int n=libMesh::n_processors()) |
| void | repartition (MeshBase &mesh, const unsigned int n=libMesh::n_processors()) |
| virtual void | attach_weights (ErrorVector *) |
Static Public Member Functions | |
| static void | partition_unpartitioned_elements (MeshBase &mesh, const unsigned int n=libMesh::n_processors()) |
| static void | set_parent_processor_ids (MeshBase &mesh) |
| static void | set_node_processor_ids (MeshBase &mesh) |
Protected Member Functions | |
| virtual void | _do_partition (MeshBase &mesh, const unsigned int n) |
| void | single_partition (MeshBase &mesh) |
| virtual void | _do_repartition (MeshBase &mesh, const unsigned int n) |
Protected Attributes | |
| ErrorVector * | _weights |
Static Protected Attributes | |
| static const dof_id_type | communication_blocksize = 1000000 |
Private Member Functions | |
| void | compute_centroids (MeshBase &mesh) |
Static Private Member Functions | |
| static bool | sort_x (const std::pair< Point, Elem * > &lhs, const std::pair< Point, Elem * > &rhs) |
| static bool | sort_y (const std::pair< Point, Elem * > &lhs, const std::pair< Point, Elem * > &rhs) |
| static bool | sort_z (const std::pair< Point, Elem * > &lhs, const std::pair< Point, Elem * > &rhs) |
| static bool | sort_radial (const std::pair< Point, Elem * > &lhs, const std::pair< Point, Elem * > &rhs) |
Private Attributes | |
| CentroidSortMethod | _sort_method |
| std::vector< std::pair< Point, Elem * > > | _elem_centroids |
Detailed Description
The centroid partitioner partitions simply based on the locations of element centroids. You must define what you mean by "less than" for the list of element centroids, e.g. if you only care about distance in the z-direction, you would define "less than" differently than if you cared about radial distance.
Definition at line 52 of file centroid_partitioner.h.
Member Enumeration Documentation
A typedef which is reserved only for use within this class. If X is chosen, then centroid locations will be sorted according to their X-location, etc...
Definition at line 62 of file centroid_partitioner.h.
00062 {X=0, 00063 Y, 00064 Z, 00065 RADIAL, 00066 INVALID_METHOD};
Constructor & Destructor Documentation
| libMesh::CentroidPartitioner::CentroidPartitioner | ( | const CentroidSortMethod | sm = X |
) | [inline, explicit] |
Constructor. Takes the CentroidSortMethod to use, which defaults to X ordering.
Definition at line 73 of file centroid_partitioner.h.
Referenced by clone().
00073 : _sort_method(sm) {}
Member Function Documentation
| void libMesh::CentroidPartitioner::_do_partition | ( | MeshBase & | mesh, | |
| const unsigned int | n | |||
| ) | [protected, virtual] |
Partitions the mesh into n subdomains. This is a required interface for the class.
Implements libMesh::Partitioner.
Definition at line 32 of file centroid_partitioner.C.
References _elem_centroids, compute_centroids(), std::min(), libMesh::MeshTools::n_elem(), libMesh::MeshBase::n_elem(), libMesh::DofObject::processor_id(), RADIAL, libMesh::Partitioner::single_partition(), sort_method(), sort_radial(), sort_x(), sort_y(), sort_z(), X, Y, and Z.
00034 { 00035 // Check for an easy return 00036 if (n == 1) 00037 { 00038 this->single_partition (mesh); 00039 return; 00040 } 00041 00042 00043 // Possibly reconstruct centroids 00044 if (mesh.n_elem() != _elem_centroids.size()) 00045 this->compute_centroids (mesh); 00046 00047 00048 00049 switch (this->sort_method()) 00050 { 00051 case X: 00052 { 00053 std::sort(_elem_centroids.begin(), 00054 _elem_centroids.end(), 00055 CentroidPartitioner::sort_x); 00056 00057 break; 00058 } 00059 00060 00061 case Y: 00062 { 00063 std::sort(_elem_centroids.begin(), 00064 _elem_centroids.end(), 00065 CentroidPartitioner::sort_y); 00066 00067 break; 00068 00069 } 00070 00071 00072 case Z: 00073 { 00074 std::sort(_elem_centroids.begin(), 00075 _elem_centroids.end(), 00076 CentroidPartitioner::sort_z); 00077 00078 break; 00079 } 00080 00081 00082 case RADIAL: 00083 { 00084 std::sort(_elem_centroids.begin(), 00085 _elem_centroids.end(), 00086 CentroidPartitioner::sort_radial); 00087 00088 break; 00089 } 00090 default: 00091 libmesh_error(); 00092 } 00093 00094 00095 // Make sure the user has not handed us an 00096 // invalid number of partitions. 00097 libmesh_assert_greater (n, 0); 00098 00099 // the number of elements, e.g. 1000 00100 const dof_id_type n_elem = mesh.n_elem(); 00101 // the number of elements per processor, e.g 400 00102 const dof_id_type target_size = n_elem / n; 00103 00104 // Make sure the mesh hasn't changed since the 00105 // last time we computed the centroids. 00106 libmesh_assert_equal_to (mesh.n_elem(), _elem_centroids.size()); 00107 00108 for (dof_id_type i=0; i<n_elem; i++) 00109 { 00110 Elem* elem = _elem_centroids[i].second; 00111 00112 elem->processor_id() = 00113 std::min (libmesh_cast_int<processor_id_type>(i / target_size), 00114 libmesh_cast_int<processor_id_type>(n-1)); 00115 } 00116 }
| virtual void libMesh::Partitioner::_do_repartition | ( | MeshBase & | mesh, | |
| const unsigned int | n | |||
| ) | [inline, protected, virtual, inherited] |
This is the actual re-partitioning method which can be overloaded in derived classes. Note that the default behavior is to simply call the partition function.
Reimplemented in libMesh::ParmetisPartitioner.
Definition at line 143 of file partitioner.h.
References libMesh::Partitioner::_do_partition().
Referenced by libMesh::Partitioner::repartition().
00144 { this->_do_partition (mesh, n); }
| virtual void libMesh::Partitioner::attach_weights | ( | ErrorVector * | ) | [inline, virtual, inherited] |
Attach weights that can be used for partitioning. This ErrorVector should be _exactly_ the same on every processor and should have mesh->max_elem_id() entries.
Reimplemented in libMesh::MetisPartitioner.
Definition at line 118 of file partitioner.h.
| virtual AutoPtr<Partitioner> libMesh::CentroidPartitioner::clone | ( | ) | const [inline, virtual] |
Creates a new partitioner of this type and returns it in an AutoPtr.
Implements libMesh::Partitioner.
Definition at line 79 of file centroid_partitioner.h.
References CentroidPartitioner(), and sort_method().
00079 { 00080 AutoPtr<Partitioner> cloned_partitioner 00081 (new CentroidPartitioner(sort_method())); 00082 return cloned_partitioner; 00083 }
| void libMesh::CentroidPartitioner::compute_centroids | ( | MeshBase & | mesh | ) | [private] |
Computes a list of element centroids for the mesh. This list will be kept around in case a repartition is desired.
Definition at line 125 of file centroid_partitioner.C.
References _elem_centroids, libMesh::Elem::centroid(), libMesh::MeshBase::elements_begin(), libMesh::MeshBase::elements_end(), and libMesh::MeshBase::n_elem().
Referenced by _do_partition().
00126 { 00127 _elem_centroids.clear(); 00128 _elem_centroids.reserve(mesh.n_elem()); 00129 00130 // elem_iterator it(mesh.elements_begin()); 00131 // const elem_iterator it_end(mesh.elements_end()); 00132 00133 MeshBase::element_iterator it = mesh.elements_begin(); 00134 const MeshBase::element_iterator it_end = mesh.elements_end(); 00135 00136 for (; it != it_end; ++it) 00137 { 00138 Elem* elem = *it; 00139 00140 _elem_centroids.push_back(std::make_pair(elem->centroid(), elem)); 00141 } 00142 }
| void libMesh::Partitioner::partition | ( | MeshBase & | mesh, | |
| const unsigned int | n = libMesh::n_processors() | |||
| ) | [inherited] |
Partition the MeshBase into n parts. If the user does not specify a number of pieces into which the mesh should be partitioned, then the default behavior of the partitioner is to partition according to the number of processors defined in libMesh::n_processors(). The partitioner currently does not modify the subdomain_id of each element. This number is reserved for things like material properties, etc.
Definition at line 48 of file partitioner.C.
References libMesh::Partitioner::_do_partition(), libMesh::MeshTools::libmesh_assert_valid_procids< Elem >(), libMesh::MeshTools::libmesh_assert_valid_remote_elems(), std::min(), libMesh::MeshBase::n_active_elem(), libMesh::Partitioner::partition_unpartitioned_elements(), libMesh::MeshBase::redistribute(), libMesh::MeshBase::set_n_partitions(), libMesh::Partitioner::set_node_processor_ids(), libMesh::Partitioner::set_parent_processor_ids(), libMesh::Partitioner::single_partition(), and libMesh::MeshBase::update_post_partitioning().
Referenced by libMesh::SFCPartitioner::_do_partition(), libMesh::MetisPartitioner::_do_partition(), and libMesh::ParmetisPartitioner::_do_repartition().
00050 { 00051 parallel_only(); 00052 00053 // BSK - temporary fix while redistribution is integrated 6/26/2008 00054 // Uncomment this to not repartition in parallel 00055 // if (!mesh.is_serial()) 00056 // return; 00057 00058 // we cannot partition into more pieces than we have 00059 // active elements! 00060 const unsigned int n_parts = 00061 static_cast<unsigned int> 00062 (std::min(mesh.n_active_elem(), static_cast<dof_id_type>(n))); 00063 00064 // Set the number of partitions in the mesh 00065 mesh.set_n_partitions()=n_parts; 00066 00067 if (n_parts == 1) 00068 { 00069 this->single_partition (mesh); 00070 return; 00071 } 00072 00073 // First assign a temporary partitioning to any unpartitioned elements 00074 Partitioner::partition_unpartitioned_elements(mesh, n_parts); 00075 00076 // Call the partitioning function 00077 this->_do_partition(mesh,n_parts); 00078 00079 // Set the parent's processor ids 00080 Partitioner::set_parent_processor_ids(mesh); 00081 00082 // Redistribute elements if necessary, before setting node processor 00083 // ids, to make sure those will be set consistently 00084 mesh.redistribute(); 00085 00086 #ifdef DEBUG 00087 MeshTools::libmesh_assert_valid_remote_elems(mesh); 00088 00089 // Messed up elem processor_id()s can leave us without the child 00090 // elements we need to restrict vectors on a distributed mesh 00091 MeshTools::libmesh_assert_valid_procids<Elem>(mesh); 00092 #endif 00093 00094 // Set the node's processor ids 00095 Partitioner::set_node_processor_ids(mesh); 00096 00097 #ifdef DEBUG 00098 MeshTools::libmesh_assert_valid_procids<Elem>(mesh); 00099 #endif 00100 00101 // Give derived Mesh classes a chance to update any cached data to 00102 // reflect the new partitioning 00103 mesh.update_post_partitioning(); 00104 }
| void libMesh::Partitioner::partition_unpartitioned_elements | ( | MeshBase & | mesh, | |
| const unsigned int | n = libMesh::n_processors() | |||
| ) | [static, inherited] |
This function
Definition at line 168 of file partitioner.C.
References libMesh::MeshTools::bounding_box(), end, libMesh::MeshTools::n_elem(), libMesh::n_processors(), libMesh::DofObject::processor_id(), libMesh::MeshBase::unpartitioned_elements_begin(), and libMesh::MeshBase::unpartitioned_elements_end().
Referenced by libMesh::Partitioner::partition(), and libMesh::Partitioner::repartition().
00170 { 00171 MeshBase::element_iterator it = mesh.unpartitioned_elements_begin(); 00172 const MeshBase::element_iterator end = mesh.unpartitioned_elements_end(); 00173 00174 const dof_id_type n_unpartitioned_elements = MeshTools::n_elem (it, end); 00175 00176 // the unpartitioned elements must exist on all processors. If the range is empty on one 00177 // it is empty on all, and we can quit right here. 00178 if (!n_unpartitioned_elements) return; 00179 00180 // find the target subdomain sizes 00181 std::vector<dof_id_type> subdomain_bounds(libMesh::n_processors()); 00182 00183 for (processor_id_type pid=0; pid<libMesh::n_processors(); pid++) 00184 { 00185 dof_id_type tgt_subdomain_size = 0; 00186 00187 // watch out for the case that n_subdomains < n_processors 00188 if (pid < n_subdomains) 00189 { 00190 tgt_subdomain_size = n_unpartitioned_elements/n_subdomains; 00191 00192 if (pid < n_unpartitioned_elements%n_subdomains) 00193 tgt_subdomain_size++; 00194 00195 } 00196 00197 //libMesh::out << "pid, #= " << pid << ", " << tgt_subdomain_size << std::endl; 00198 if (pid == 0) 00199 subdomain_bounds[0] = tgt_subdomain_size; 00200 else 00201 subdomain_bounds[pid] = subdomain_bounds[pid-1] + tgt_subdomain_size; 00202 } 00203 00204 libmesh_assert_equal_to (subdomain_bounds.back(), n_unpartitioned_elements); 00205 00206 // create the unique mapping for all unpartitioned elements independent of partitioning 00207 // determine the global indexing for all the unpartitoned elements 00208 std::vector<dof_id_type> global_indices; 00209 00210 // Calling this on all processors a unique range in [0,n_unpartitioned_elements) is constructed. 00211 // Only the indices for the elements we pass in are returned in the array. 00212 MeshCommunication().find_global_indices (MeshTools::bounding_box(mesh), it, end, 00213 global_indices); 00214 00215 for (dof_id_type cnt=0; it != end; ++it) 00216 { 00217 Elem *elem = *it; 00218 00219 libmesh_assert_less (cnt, global_indices.size()); 00220 const dof_id_type global_index = 00221 global_indices[cnt++]; 00222 00223 libmesh_assert_less (global_index, subdomain_bounds.back()); 00224 libmesh_assert_less (global_index, n_unpartitioned_elements); 00225 00226 const processor_id_type subdomain_id = 00227 libmesh_cast_int<processor_id_type> 00228 (std::distance(subdomain_bounds.begin(), 00229 std::upper_bound(subdomain_bounds.begin(), 00230 subdomain_bounds.end(), 00231 global_index))); 00232 libmesh_assert_less (subdomain_id, n_subdomains); 00233 00234 elem->processor_id() = subdomain_id; 00235 //libMesh::out << "assigning " << global_index << " to " << subdomain_id << std::endl; 00236 } 00237 }
| void libMesh::Partitioner::repartition | ( | MeshBase & | mesh, | |
| const unsigned int | n = libMesh::n_processors() | |||
| ) | [inherited] |
Repartitions the MeshBase into n parts. This is required since some partitoning algorithms can repartition more efficiently than computing a new partitioning from scratch. The default behavior is to simply call this->partition(n)
Definition at line 110 of file partitioner.C.
References libMesh::Partitioner::_do_repartition(), std::min(), libMesh::MeshBase::n_active_elem(), libMesh::Partitioner::partition_unpartitioned_elements(), libMesh::MeshBase::set_n_partitions(), libMesh::Partitioner::set_node_processor_ids(), libMesh::Partitioner::set_parent_processor_ids(), and libMesh::Partitioner::single_partition().
00112 { 00113 // we cannot partition into more pieces than we have 00114 // active elements! 00115 const unsigned int n_parts = 00116 static_cast<unsigned int> 00117 (std::min(mesh.n_active_elem(), static_cast<dof_id_type>(n))); 00118 00119 // Set the number of partitions in the mesh 00120 mesh.set_n_partitions()=n_parts; 00121 00122 if (n_parts == 1) 00123 { 00124 this->single_partition (mesh); 00125 return; 00126 } 00127 00128 // First assign a temporary partitioning to any unpartitioned elements 00129 Partitioner::partition_unpartitioned_elements(mesh, n_parts); 00130 00131 // Call the partitioning function 00132 this->_do_repartition(mesh,n_parts); 00133 00134 // Set the parent's processor ids 00135 Partitioner::set_parent_processor_ids(mesh); 00136 00137 // Set the node's processor ids 00138 Partitioner::set_node_processor_ids(mesh); 00139 }
| void libMesh::Partitioner::set_node_processor_ids | ( | MeshBase & | mesh | ) | [static, inherited] |
This function is called after partitioning to set the processor IDs for the nodes. By definition, a Node's processor ID is the minimum processor ID for all of the elements which share the node.
Definition at line 419 of file partitioner.C.
References libMesh::MeshBase::active_elements_begin(), libMesh::MeshBase::active_elements_end(), libMesh::CommWorld, libMesh::Elem::get_node(), libMesh::DofObject::id(), libMesh::DofObject::invalid_processor_id, libMesh::DofObject::invalidate_processor_id(), libMesh::MeshTools::libmesh_assert_valid_procids< Node >(), std::min(), libMesh::MeshTools::n_elem(), libMesh::Elem::n_nodes(), libMesh::MeshBase::n_partitions(), libMesh::n_processors(), libMesh::MeshBase::node_ptr(), libMesh::MeshBase::nodes_begin(), libMesh::MeshBase::nodes_end(), libMesh::MeshBase::not_active_elements_begin(), libMesh::MeshBase::not_active_elements_end(), libMesh::processor_id(), libMesh::DofObject::processor_id(), libMesh::Parallel::Communicator::send_receive(), libMesh::MeshBase::subactive_elements_begin(), libMesh::MeshBase::subactive_elements_end(), libMesh::MeshBase::unpartitioned_elements_begin(), and libMesh::MeshBase::unpartitioned_elements_end().
Referenced by libMesh::UnstructuredMesh::all_first_order(), libMesh::Partitioner::partition(), libMesh::XdrIO::read(), libMesh::Partitioner::repartition(), and libMesh::BoundaryInfo::sync().
00420 { 00421 START_LOG("set_node_processor_ids()","Partitioner"); 00422 00423 // This function must be run on all processors at once 00424 parallel_only(); 00425 00426 // If we have any unpartitioned elements at this 00427 // stage there is a problem 00428 libmesh_assert (MeshTools::n_elem(mesh.unpartitioned_elements_begin(), 00429 mesh.unpartitioned_elements_end()) == 0); 00430 00431 00432 // const dof_id_type orig_n_local_nodes = mesh.n_local_nodes(); 00433 00434 // libMesh::err << "[" << libMesh::processor_id() << "]: orig_n_local_nodes=" 00435 // << orig_n_local_nodes << std::endl; 00436 00437 // Build up request sets. Each node is currently owned by a processor because 00438 // it is connected to an element owned by that processor. However, during the 00439 // repartitioning phase that element may have been assigned a new processor id, but 00440 // it is still resident on the original processor. We need to know where to look 00441 // for new ids before assigning new ids, otherwise we may be asking the wrong processors 00442 // for the wrong information. 00443 // 00444 // The only remaining issue is what to do with unpartitioned nodes. Since they are required 00445 // to live on all processors we can simply rely on ourselves to number them properly. 00446 std::vector<std::vector<dof_id_type> > 00447 requested_node_ids(libMesh::n_processors()); 00448 00449 // Loop over all the nodes, count the ones on each processor. We can skip ourself 00450 std::vector<dof_id_type> ghost_nodes_from_proc(libMesh::n_processors(), 0); 00451 00452 MeshBase::node_iterator node_it = mesh.nodes_begin(); 00453 const MeshBase::node_iterator node_end = mesh.nodes_end(); 00454 00455 for (; node_it != node_end; ++node_it) 00456 { 00457 Node *node = *node_it; 00458 libmesh_assert(node); 00459 const processor_id_type current_pid = node->processor_id(); 00460 if (current_pid != libMesh::processor_id() && 00461 current_pid != DofObject::invalid_processor_id) 00462 { 00463 libmesh_assert_less (current_pid, ghost_nodes_from_proc.size()); 00464 ghost_nodes_from_proc[current_pid]++; 00465 } 00466 } 00467 00468 // We know how many objects live on each processor, so reserve() 00469 // space for each. 00470 for (processor_id_type pid=0; pid != libMesh::n_processors(); ++pid) 00471 requested_node_ids[pid].reserve(ghost_nodes_from_proc[pid]); 00472 00473 // We need to get the new pid for each node from the processor 00474 // which *currently* owns the node. We can safely skip ourself 00475 for (node_it = mesh.nodes_begin(); node_it != node_end; ++node_it) 00476 { 00477 Node *node = *node_it; 00478 libmesh_assert(node); 00479 const processor_id_type current_pid = node->processor_id(); 00480 if (current_pid != libMesh::processor_id() && 00481 current_pid != DofObject::invalid_processor_id) 00482 { 00483 libmesh_assert_less (current_pid, requested_node_ids.size()); 00484 libmesh_assert_less (requested_node_ids[current_pid].size(), 00485 ghost_nodes_from_proc[current_pid]); 00486 requested_node_ids[current_pid].push_back(node->id()); 00487 } 00488 00489 // Unset any previously-set node processor ids 00490 node->invalidate_processor_id(); 00491 } 00492 00493 // Loop over all the active elements 00494 MeshBase::element_iterator elem_it = mesh.active_elements_begin(); 00495 const MeshBase::element_iterator elem_end = mesh.active_elements_end(); 00496 00497 for ( ; elem_it != elem_end; ++elem_it) 00498 { 00499 Elem* elem = *elem_it; 00500 libmesh_assert(elem); 00501 00502 libmesh_assert_not_equal_to (elem->processor_id(), DofObject::invalid_processor_id); 00503 00504 // For each node, set the processor ID to the min of 00505 // its current value and this Element's processor id. 00506 // 00507 // TODO: we would probably get better parallel partitioning if 00508 // we did something like "min for even numbered nodes, max for 00509 // odd numbered". We'd need to be careful about how that would 00510 // affect solution ordering for I/O, though. 00511 for (unsigned int n=0; n<elem->n_nodes(); ++n) 00512 elem->get_node(n)->processor_id() = std::min(elem->get_node(n)->processor_id(), 00513 elem->processor_id()); 00514 } 00515 00516 // And loop over the subactive elements, but don't reassign 00517 // nodes that are already active on another processor. 00518 MeshBase::element_iterator sub_it = mesh.subactive_elements_begin(); 00519 const MeshBase::element_iterator sub_end = mesh.subactive_elements_end(); 00520 00521 for ( ; sub_it != sub_end; ++sub_it) 00522 { 00523 Elem* elem = *sub_it; 00524 libmesh_assert(elem); 00525 00526 libmesh_assert_not_equal_to (elem->processor_id(), DofObject::invalid_processor_id); 00527 00528 for (unsigned int n=0; n<elem->n_nodes(); ++n) 00529 if (elem->get_node(n)->processor_id() == DofObject::invalid_processor_id) 00530 elem->get_node(n)->processor_id() = elem->processor_id(); 00531 } 00532 00533 // Same for the inactive elements -- we will have already gotten most of these 00534 // nodes, *except* for the case of a parent with a subset of children which are 00535 // ghost elements. In that case some of the parent nodes will not have been 00536 // properly handled yet 00537 MeshBase::element_iterator not_it = mesh.not_active_elements_begin(); 00538 const MeshBase::element_iterator not_end = mesh.not_active_elements_end(); 00539 00540 for ( ; not_it != not_end; ++not_it) 00541 { 00542 Elem* elem = *not_it; 00543 libmesh_assert(elem); 00544 00545 libmesh_assert_not_equal_to (elem->processor_id(), DofObject::invalid_processor_id); 00546 00547 for (unsigned int n=0; n<elem->n_nodes(); ++n) 00548 if (elem->get_node(n)->processor_id() == DofObject::invalid_processor_id) 00549 elem->get_node(n)->processor_id() = elem->processor_id(); 00550 } 00551 00552 // We can't assert that all nodes are connected to elements, because 00553 // a ParallelMesh with NodeConstraints might have pulled in some 00554 // remote nodes solely for evaluating those constraints. 00555 // MeshTools::libmesh_assert_connected_nodes(mesh); 00556 00557 // For such nodes, we'll do a sanity check later when making sure 00558 // that we successfully reset their processor ids to something 00559 // valid. 00560 00561 // Next set node ids from other processors, excluding self 00562 for (processor_id_type p=1; p != libMesh::n_processors(); ++p) 00563 { 00564 // Trade my requests with processor procup and procdown 00565 processor_id_type procup = (libMesh::processor_id() + p) % 00566 libMesh::n_processors(); 00567 processor_id_type procdown = (libMesh::n_processors() + 00568 libMesh::processor_id() - p) % 00569 libMesh::n_processors(); 00570 std::vector<dof_id_type> request_to_fill; 00571 CommWorld.send_receive(procup, requested_node_ids[procup], 00572 procdown, request_to_fill); 00573 00574 // Fill those requests in-place 00575 for (std::size_t i=0; i != request_to_fill.size(); ++i) 00576 { 00577 Node *node = mesh.node_ptr(request_to_fill[i]); 00578 libmesh_assert(node); 00579 const processor_id_type new_pid = node->processor_id(); 00580 libmesh_assert_not_equal_to (new_pid, DofObject::invalid_processor_id); 00581 libmesh_assert_less (new_pid, mesh.n_partitions()); // this is the correct test -- 00582 request_to_fill[i] = new_pid; // the number of partitions may 00583 } // not equal the number of processors 00584 00585 // Trade back the results 00586 std::vector<dof_id_type> filled_request; 00587 CommWorld.send_receive(procdown, request_to_fill, 00588 procup, filled_request); 00589 libmesh_assert_equal_to (filled_request.size(), requested_node_ids[procup].size()); 00590 00591 // And copy the id changes we've now been informed of 00592 for (std::size_t i=0; i != filled_request.size(); ++i) 00593 { 00594 Node *node = mesh.node_ptr(requested_node_ids[procup][i]); 00595 libmesh_assert(node); 00596 libmesh_assert_less (filled_request[i], mesh.n_partitions()); // this is the correct test -- 00597 node->processor_id(filled_request[i]); // the number of partitions may 00598 } // not equal the number of processors 00599 } 00600 00601 #ifdef DEBUG 00602 MeshTools::libmesh_assert_valid_procids<Node>(mesh); 00603 #endif 00604 00605 STOP_LOG("set_node_processor_ids()","Partitioner"); 00606 }
| static void libMesh::Partitioner::set_parent_processor_ids | ( | MeshBase & | mesh | ) | [static, inherited] |
This function is called after partitioning to set the processor IDs for the inactive parent elements. A Parent's processor ID is the same as its first child.
Referenced by libMesh::Partitioner::partition(), and libMesh::Partitioner::repartition().
| void libMesh::CentroidPartitioner::set_sort_method | ( | const CentroidSortMethod | sm | ) | [inline] |
Change how the elements will be sorted.
Definition at line 93 of file centroid_partitioner.h.
References _sort_method.
00093 {_sort_method = sm; }
| void libMesh::Partitioner::single_partition | ( | MeshBase & | mesh | ) | [protected, inherited] |
Trivially "partitions" the mesh for one processor. Simply loops through the elements and assigns all of them to processor 0. Is is provided as a separate function so that derived classes may use it without reimplementing it.
Definition at line 145 of file partitioner.C.
References libMesh::MeshBase::elements_begin(), libMesh::MeshBase::elements_end(), libMesh::MeshBase::nodes_begin(), and libMesh::MeshBase::nodes_end().
Referenced by libMesh::SFCPartitioner::_do_partition(), libMesh::MetisPartitioner::_do_partition(), libMesh::LinearPartitioner::_do_partition(), _do_partition(), libMesh::ParmetisPartitioner::_do_repartition(), libMesh::Partitioner::partition(), and libMesh::Partitioner::repartition().
00146 { 00147 START_LOG("single_partition()","Partitioner"); 00148 00149 // Loop over all the elements and assign them to processor 0. 00150 MeshBase::element_iterator elem_it = mesh.elements_begin(); 00151 const MeshBase::element_iterator elem_end = mesh.elements_end(); 00152 00153 for ( ; elem_it != elem_end; ++elem_it) 00154 (*elem_it)->processor_id() = 0; 00155 00156 // For a single partition, all the nodes are on processor 0 00157 MeshBase::node_iterator node_it = mesh.nodes_begin(); 00158 const MeshBase::node_iterator node_end = mesh.nodes_end(); 00159 00160 for ( ; node_it != node_end; ++node_it) 00161 (*node_it)->processor_id() = 0; 00162 00163 STOP_LOG("single_partition()","Partitioner"); 00164 }
| CentroidSortMethod libMesh::CentroidPartitioner::sort_method | ( | ) | const [inline] |
Specifies how the elements will be sorted.
Definition at line 88 of file centroid_partitioner.h.
References _sort_method.
Referenced by _do_partition(), and clone().
00088 { return _sort_method; }
| bool libMesh::CentroidPartitioner::sort_radial | ( | const std::pair< Point, Elem * > & | lhs, | |
| const std::pair< Point, Elem * > & | rhs | |||
| ) | [static, private] |
Partition the list of centroids based on the radial position of the centroid. This provides a function which may be passed to the std::sort routine for sorting the elements by centroid.
Definition at line 174 of file centroid_partitioner.C.
Referenced by _do_partition().
| bool libMesh::CentroidPartitioner::sort_x | ( | const std::pair< Point, Elem * > & | lhs, | |
| const std::pair< Point, Elem * > & | rhs | |||
| ) | [static, private] |
Partition the list of centroids based on the x-coordinate of the centroid. This provides a function which may be passed to the std::sort routine for sorting the elements by centroid.
Definition at line 147 of file centroid_partitioner.C.
Referenced by _do_partition().
| bool libMesh::CentroidPartitioner::sort_y | ( | const std::pair< Point, Elem * > & | lhs, | |
| const std::pair< Point, Elem * > & | rhs | |||
| ) | [static, private] |
Partition the list of centroids based on the y-coordinate of the centroid. This provides a function which may be passed to the std::sort routine for sorting the elements by centroid.
Definition at line 156 of file centroid_partitioner.C.
Referenced by _do_partition().
| bool libMesh::CentroidPartitioner::sort_z | ( | const std::pair< Point, Elem * > & | lhs, | |
| const std::pair< Point, Elem * > & | rhs | |||
| ) | [static, private] |
Partition the list of centroids based on the z-coordinate of the centroid. This provides a function which may be passed to the std::sort routine for sorting the elements by centroid.
Definition at line 166 of file centroid_partitioner.C.
Referenced by _do_partition().
Member Data Documentation
std::vector<std::pair<Point, Elem*> > libMesh::CentroidPartitioner::_elem_centroids [private] |
Vector which holds pairs of centroids and their respective element pointers.
Definition at line 160 of file centroid_partitioner.h.
Referenced by _do_partition(), and compute_centroids().
Store a flag which tells which type of sort method we are using.
Definition at line 154 of file centroid_partitioner.h.
Referenced by set_sort_method(), and sort_method().
ErrorVector* libMesh::Partitioner::_weights [protected, inherited] |
The weights that might be used for partitioning.
Definition at line 155 of file partitioner.h.
Referenced by libMesh::MetisPartitioner::_do_partition(), and libMesh::MetisPartitioner::attach_weights().
const dof_id_type libMesh::Partitioner::communication_blocksize = 1000000 [static, protected, inherited] |
The blocksize to use when doing blocked parallel communication. This limits the maximum vector size which can be used in a single communication step.
Definition at line 150 of file partitioner.h.
The documentation for this class was generated from the following files:
Site Created By: libMesh Developers
Last modified: February 05 2013 19:55:12 UTC
Hosted By: