$extrastylesheet
00001 // The libMesh Finite Element Library. 00002 // Copyright (C) 2002-2014 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner 00003 00004 // This library is free software; you can redistribute it and/or 00005 // modify it under the terms of the GNU Lesser General Public 00006 // License as published by the Free Software Foundation; either 00007 // version 2.1 of the License, or (at your option) any later version. 00008 00009 // This library is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 // Lesser General Public License for more details. 00013 00014 // You should have received a copy of the GNU Lesser General Public 00015 // License along with this library; if not, write to the Free Software 00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00017 00018 // C++ includes 00019 #include <algorithm> // for std::sort 00020 00021 // Local includes 00022 #include "libmesh/centroid_partitioner.h" 00023 #include "libmesh/mesh_base.h" 00024 #include "libmesh/elem.h" 00025 00026 namespace libMesh 00027 { 00028 00029 00030 //--------------------------------------------------------- 00031 // CentroidPartitioner methods 00032 void CentroidPartitioner::_do_partition (MeshBase& mesh, 00033 const unsigned int n) 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_msg("Unknown sort method: " << this->sort_method()); 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 (cast_int<processor_id_type>(i / target_size), 00114 cast_int<processor_id_type>(n-1)); 00115 } 00116 } 00117 00118 00119 00120 00121 00122 00123 00124 00125 void CentroidPartitioner::compute_centroids (MeshBase& mesh) 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 } 00143 00144 00145 00146 00147 bool CentroidPartitioner::sort_x (const std::pair<Point, Elem*>& lhs, 00148 const std::pair<Point, Elem*>& rhs) 00149 { 00150 return (lhs.first(0) < rhs.first(0)); 00151 } 00152 00153 00154 00155 00156 bool CentroidPartitioner::sort_y (const std::pair<Point, Elem*>& lhs, 00157 const std::pair<Point, Elem*>& rhs) 00158 { 00159 return (lhs.first(1) < rhs.first(1)); 00160 } 00161 00162 00163 00164 00165 00166 bool CentroidPartitioner::sort_z (const std::pair<Point, Elem*>& lhs, 00167 const std::pair<Point, Elem*>& rhs) 00168 { 00169 return (lhs.first(2) < rhs.first(2)); 00170 } 00171 00172 00173 00174 bool CentroidPartitioner::sort_radial (const std::pair<Point, Elem*>& lhs, 00175 const std::pair<Point, Elem*>& rhs) 00176 { 00177 return (lhs.first.size() < rhs.first.size()); 00178 } 00179 00180 } // namespace libMesh