centroid_partitioner.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2018 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 // C++ includes
19 #include <algorithm> // for std::sort
20 
21 // Local includes
23 #include "libmesh/elem.h"
24 
25 namespace libMesh
26 {
27 
28 
32  unsigned int n)
33 {
34  // Check for easy returns
35  if (it == end)
36  return;
37 
38  if (n == 1)
39  {
40  this->single_partition_range (it, end);
41  return;
42  }
43 
44  // Make sure the user has not handed us an
45  // invalid number of partitions.
46  libmesh_assert_greater (n, 0);
47 
48  // We don't yet support distributed meshes with this Partitioner
49  if (!mesh.is_serial())
50  libmesh_not_implemented();
51 
52  // Compute the element centroids. Note: we used to skip this step
53  // if the number of elements was unchanged from the last call, but
54  // that doesn't account for elements that have moved a lot since the
55  // last time the Partitioner was called...
56  this->compute_centroids (it, end);
57 
58  switch (this->sort_method())
59  {
60  case X:
61  {
62  std::sort(_elem_centroids.begin(),
63  _elem_centroids.end(),
65 
66  break;
67  }
68 
69 
70  case Y:
71  {
72  std::sort(_elem_centroids.begin(),
73  _elem_centroids.end(),
75 
76  break;
77 
78  }
79 
80 
81  case Z:
82  {
83  std::sort(_elem_centroids.begin(),
84  _elem_centroids.end(),
86 
87  break;
88  }
89 
90 
91  case RADIAL:
92  {
93  std::sort(_elem_centroids.begin(),
94  _elem_centroids.end(),
96 
97  break;
98  }
99  default:
100  libmesh_error_msg("Unknown sort method: " << this->sort_method());
101  }
102 
103  // Compute target_size, the approximate number of elements on each processor.
104  const dof_id_type target_size = cast_int<dof_id_type>
105  (_elem_centroids.size() / n);
106 
107  for (dof_id_type i=0; i<_elem_centroids.size(); i++)
108  {
109  Elem * elem = _elem_centroids[i].second;
110 
111  // FIXME: All "extra" elements go on the last processor... this
112  // could probably be improved.
113  elem->processor_id() =
114  std::min (cast_int<processor_id_type>(i / target_size),
115  cast_int<processor_id_type>(n-1));
116  }
117 }
118 
119 
120 
122  const unsigned int n)
123 {
124  this->partition_range(mesh,
125  mesh.elements_begin(),
126  mesh.elements_end(),
127  n);
128 }
129 
130 
131 
134 {
135  _elem_centroids.clear();
136 
137  for (auto & elem : as_range(it, end))
138  _elem_centroids.push_back(std::make_pair(elem->centroid(), elem));
139 }
140 
141 
142 
143 
144 bool CentroidPartitioner::sort_x (const std::pair<Point, Elem *> & lhs,
145  const std::pair<Point, Elem *> & rhs)
146 {
147  return (lhs.first(0) < rhs.first(0));
148 }
149 
150 
151 
152 
153 bool CentroidPartitioner::sort_y (const std::pair<Point, Elem *> & lhs,
154  const std::pair<Point, Elem *> & rhs)
155 {
156  return (lhs.first(1) < rhs.first(1));
157 }
158 
159 
160 
161 
162 
163 bool CentroidPartitioner::sort_z (const std::pair<Point, Elem *> & lhs,
164  const std::pair<Point, Elem *> & rhs)
165 {
166  return (lhs.first(2) < rhs.first(2));
167 }
168 
169 
170 
171 bool CentroidPartitioner::sort_radial (const std::pair<Point, Elem *> & lhs,
172  const std::pair<Point, Elem *> & rhs)
173 {
174  return (lhs.first.norm() < rhs.first.norm());
175 }
176 
177 } // namespace libMesh
virtual void _do_partition(MeshBase &mesh, const unsigned int n) override
std::vector< std::pair< Point, Elem * > > _elem_centroids
The base class for all geometric element types.
Definition: elem.h:100
MeshBase & mesh
IterBase * end
Base class for Mesh.
Definition: mesh_base.h:77
virtual void partition_range(MeshBase &mesh, MeshBase::element_iterator it, MeshBase::element_iterator end, const unsigned int n) override
void single_partition_range(MeshBase::element_iterator it, MeshBase::element_iterator end)
Definition: partitioner.C:172
SimpleRange< I > as_range(const std::pair< I, I > &p)
Definition: simple_range.h:57
static bool sort_radial(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)
CentroidSortMethod sort_method() const
static bool sort_x(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)
processor_id_type processor_id() const
Definition: dof_object.h:717
long double min(long double a, double b)
uint8_t dof_id_type
Definition: id_types.h:64
void compute_centroids(MeshBase::element_iterator it, MeshBase::element_iterator end)