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