libMesh
centroid_partitioner.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2019 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
22 #include "libmesh/centroid_partitioner.h"
23 #include "libmesh/elem.h"
24 #include "libmesh/int_range.h"
25 
26 namespace libMesh
27 {
28 
29 
33  unsigned int n)
34 {
35  // Check for easy returns
36  if (it == end)
37  return;
38 
39  if (n == 1)
40  {
41  this->single_partition_range (it, end);
42  return;
43  }
44 
45  // Make sure the user has not handed us an
46  // invalid number of partitions.
47  libmesh_assert_greater (n, 0);
48 
49  // We don't yet support distributed meshes with this Partitioner
50  if (!mesh.is_serial())
51  libmesh_not_implemented();
52 
53  // Compute the element centroids. Note: we used to skip this step
54  // if the number of elements was unchanged from the last call, but
55  // that doesn't account for elements that have moved a lot since the
56  // last time the Partitioner was called...
57  this->compute_centroids (it, end);
58 
59  switch (this->sort_method())
60  {
61  case X:
62  {
63  std::sort(_elem_centroids.begin(),
64  _elem_centroids.end(),
66 
67  break;
68  }
69 
70 
71  case Y:
72  {
73  std::sort(_elem_centroids.begin(),
74  _elem_centroids.end(),
76 
77  break;
78 
79  }
80 
81 
82  case Z:
83  {
84  std::sort(_elem_centroids.begin(),
85  _elem_centroids.end(),
87 
88  break;
89  }
90 
91 
92  case RADIAL:
93  {
94  std::sort(_elem_centroids.begin(),
95  _elem_centroids.end(),
97 
98  break;
99  }
100  default:
101  libmesh_error_msg("Unknown sort method: " << this->sort_method());
102  }
103 
104  // Compute target_size, the approximate number of elements on each processor.
105  const dof_id_type target_size = cast_int<dof_id_type>
106  (_elem_centroids.size() / n);
107 
108  for (auto i : index_range(_elem_centroids))
109  {
110  Elem * elem = _elem_centroids[i].second;
111 
112  // FIXME: All "extra" elements go on the last processor... this
113  // could probably be improved.
114  elem->processor_id() =
115  std::min (cast_int<processor_id_type>(i / target_size),
116  cast_int<processor_id_type>(n-1));
117  }
118 }
119 
120 
121 
123  const unsigned int n)
124 {
125  this->partition_range(mesh,
126  mesh.elements_begin(),
127  mesh.elements_end(),
128  n);
129 }
130 
131 
132 
135 {
136  _elem_centroids.clear();
137 
138  for (auto & elem : as_range(it, end))
139  _elem_centroids.push_back(std::make_pair(elem->centroid(), elem));
140 }
141 
142 
143 
144 
145 bool CentroidPartitioner::sort_x (const std::pair<Point, Elem *> & lhs,
146  const std::pair<Point, Elem *> & rhs)
147 {
148  return (lhs.first(0) < rhs.first(0));
149 }
150 
151 
152 
153 
154 bool CentroidPartitioner::sort_y (const std::pair<Point, Elem *> & lhs,
155  const std::pair<Point, Elem *> & rhs)
156 {
157  return (lhs.first(1) < rhs.first(1));
158 }
159 
160 
161 
162 
163 
164 bool CentroidPartitioner::sort_z (const std::pair<Point, Elem *> & lhs,
165  const std::pair<Point, Elem *> & rhs)
166 {
167  return (lhs.first(2) < rhs.first(2));
168 }
169 
170 
171 
172 bool CentroidPartitioner::sort_radial (const std::pair<Point, Elem *> & lhs,
173  const std::pair<Point, Elem *> & rhs)
174 {
175  return (lhs.first.norm() < rhs.first.norm());
176 }
177 
178 } // namespace libMesh
libMesh::Partitioner::single_partition_range
void single_partition_range(MeshBase::element_iterator it, MeshBase::element_iterator end)
Slightly generalized version of single_partition which acts on a range of elements defined by the pai...
Definition: partitioner.C:179
libMesh::dof_id_type
uint8_t dof_id_type
Definition: id_types.h:67
libMesh::MeshBase::element_iterator
The definition of the element_iterator struct.
Definition: mesh_base.h:1873
libMesh::CentroidPartitioner::sort_y
static bool sort_y(const std::pair< Point, Elem * > &lhs, const std::pair< Point, Elem * > &rhs)
Helper function which sorts by the centroid's y-coordinate in the internal std::sort call.
Definition: centroid_partitioner.C:154
libMesh::index_range
IntRange< std::size_t > index_range(const std::vector< T > &vec)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition: int_range.h:106
libMesh
The libMesh namespace provides an interface to certain functionality in the library.
Definition: factoryfunction.C:55
end
IterBase * end
Also have a polymorphic pointer to the end object, this prevents iterating past the end.
Definition: variant_filter_iterator.h:343
mesh
MeshBase & mesh
Definition: mesh_communication.C:1257
libMesh::CentroidPartitioner::compute_centroids
void compute_centroids(MeshBase::element_iterator it, MeshBase::element_iterator end)
Computes a list of element centroids for the mesh.
Definition: centroid_partitioner.C:133
libMesh::DofObject::processor_id
processor_id_type processor_id() const
Definition: dof_object.h:829
libMesh::CentroidPartitioner::sort_radial
static bool sort_radial(const std::pair< Point, Elem * > &lhs, const std::pair< Point, Elem * > &rhs)
Helper function which sorts by the centroid's distance from the origin in the internal std::sort call...
Definition: centroid_partitioner.C:172
libMesh::MeshBase
This is the MeshBase class.
Definition: mesh_base.h:78
libMesh::as_range
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
Helper function that allows us to treat a homogenous pair as a range.
Definition: simple_range.h:57
libMesh::CentroidPartitioner::sort_method
CentroidSortMethod sort_method() const
Getter for the current sorting method.
Definition: centroid_partitioner.h:91
libMesh::CentroidPartitioner::_elem_centroids
std::vector< std::pair< Point, Elem * > > _elem_centroids
Vector which holds pairs of centroids and their respective element pointers.
Definition: centroid_partitioner.h:159
libMesh::Elem
This is the base class from which all geometric element types are derived.
Definition: elem.h:100
libMesh::CentroidPartitioner::sort_x
static bool sort_x(const std::pair< Point, Elem * > &lhs, const std::pair< Point, Elem * > &rhs)
Helper function which sorts by the centroid's x-coordinate in the internal std::sort call.
Definition: centroid_partitioner.C:145
libMesh::CentroidPartitioner::partition_range
virtual void partition_range(MeshBase &mesh, MeshBase::element_iterator it, MeshBase::element_iterator end, const unsigned int n) override
Called by the SubdomainPartitioner to partition elements in the range (it, end).
Definition: centroid_partitioner.C:30
libMesh::CentroidPartitioner::Y
Definition: centroid_partitioner.h:58
libMesh::CentroidPartitioner::RADIAL
Definition: centroid_partitioner.h:60
libMesh::CentroidPartitioner::sort_z
static bool sort_z(const std::pair< Point, Elem * > &lhs, const std::pair< Point, Elem * > &rhs)
Helper function which sorts by the centroid's z-coordinate in the internal std::sort call.
Definition: centroid_partitioner.C:164
libMesh::CentroidPartitioner::X
Definition: centroid_partitioner.h:57
libMesh::CentroidPartitioner::Z
Definition: centroid_partitioner.h:59
libMesh::CentroidPartitioner::_do_partition
virtual void _do_partition(MeshBase &mesh, const unsigned int n) override
Partitions the mesh into n subdomains.
Definition: centroid_partitioner.C:122