Line data Source code
1 : // The libMesh Finite Element Library. 2 : // Copyright (C) 2002-2026 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 : 19 : #ifndef LIBMESH_CENTROID_PARTITIONER_H 20 : #define LIBMESH_CENTROID_PARTITIONER_H 21 : 22 : // Local includes 23 : #include "libmesh/partitioner.h" 24 : #include "libmesh/point.h" 25 : 26 : // C++ includes 27 : #include <memory> 28 : #include <utility> // pair 29 : #include <vector> 30 : 31 : namespace libMesh 32 : { 33 : 34 : // Forward declarations 35 : class Elem; 36 : 37 : /** 38 : * Partitions the Mesh based on the locations of element vertex averages. 39 : * You must define what you mean by "less than" for the list of 40 : * element vertex averages, e.g. if you only care about distance in the 41 : * z-direction, you would define "less than" differently than if you 42 : * cared about radial distance. 43 : * 44 : * \note The name of this partitioner is historical: we do not 45 : * partition based on the "true" geometric centroid since the vertex 46 : * average is much easier to compute and works just as well as far as 47 : * partitioning is concerned. 48 : * 49 : * \author John W. Peterson 50 : * \author Benjamin S. Kirk 51 : * \date 2003 52 : */ 53 : class CentroidPartitioner : public Partitioner 54 : { 55 : public: 56 : 57 : /** 58 : * A typedef which controls the sorting method used for ordering the 59 : * vertex averages. If e.g. \p X is chosen, then the vertex averages will be 60 : * sorted according to their x-coordinate. 61 : */ 62 : enum CentroidSortMethod {X=0, 63 : Y, 64 : Z, 65 : RADIAL, 66 : INVALID_METHOD}; 67 : 68 : /** 69 : * Constructor. Takes the \p CentroidSortMethod to use, which 70 : * defaults to \p X ordering. 71 : */ 72 : explicit 73 80 : CentroidPartitioner (const CentroidSortMethod sm=X) : _sort_method(sm) {} 74 : 75 : /** 76 : * Copy/move ctor, copy/move assignment operator, and destructor are 77 : * all explicitly defaulted for this class. 78 : */ 79 56 : CentroidPartitioner (const CentroidPartitioner &) = default; 80 : CentroidPartitioner (CentroidPartitioner &&) = default; 81 : CentroidPartitioner & operator= (const CentroidPartitioner &) = default; 82 : CentroidPartitioner & operator= (CentroidPartitioner &&) = default; 83 144 : virtual ~CentroidPartitioner() = default; 84 : 85 : virtual PartitionerType type () const override; 86 : 87 : /** 88 : * \returns A copy of this partitioner wrapped in a smart pointer. 89 : */ 90 56 : virtual std::unique_ptr<Partitioner> clone () const override 91 : { 92 56 : return std::make_unique<CentroidPartitioner>(*this); 93 : } 94 : 95 : /** 96 : * Elements are assigned from a sort of their vertex averages, with no reference to the 97 : * partitioning the mesh arrives with. 98 : */ 99 301 : virtual bool partitions_from_scratch () const override { return true; } 100 : 101 : /** 102 : * Getter for the current sorting method. 103 : */ 104 196 : CentroidSortMethod sort_method () const { return _sort_method; } 105 : 106 : /** 107 : * Setter for the current sorting method. 108 : */ 109 : void set_sort_method (const CentroidSortMethod sm) { _sort_method = sm; } 110 : 111 : /** 112 : * Called by the SubdomainPartitioner to partition elements in the range (it, end). 113 : */ 114 : virtual void partition_range(MeshBase & mesh, 115 : MeshBase::element_iterator it, 116 : MeshBase::element_iterator end, 117 : const unsigned int n) override; 118 : 119 : protected: 120 : 121 : /** 122 : * Partitions the mesh into n subdomains. 123 : */ 124 : virtual void _do_partition (MeshBase & mesh, 125 : const unsigned int n) override; 126 : 127 : private: 128 : 129 : /** 130 : * Computes a list of element vertex averages for the mesh. 131 : */ 132 : void compute_vertex_avgs (MeshBase::element_iterator it, 133 : MeshBase::element_iterator end); 134 : 135 : /** 136 : * Helper function which sorts by the vertex average's x-coordinate in the 137 : * internal std::sort call. 138 : */ 139 : static bool sort_x (const std::pair<Point, Elem *> & lhs, 140 : const std::pair<Point, Elem *> & rhs); 141 : 142 : /** 143 : * Helper function which sorts by the vertex average's y-coordinate in the 144 : * internal std::sort call. 145 : */ 146 : static bool sort_y (const std::pair<Point, Elem *> & lhs, 147 : const std::pair<Point, Elem *> & rhs); 148 : 149 : /** 150 : * Helper function which sorts by the vertex average's z-coordinate in the 151 : * internal std::sort call. 152 : */ 153 : static bool sort_z (const std::pair<Point, Elem *> & lhs, 154 : const std::pair<Point, Elem *> & rhs); 155 : 156 : /** 157 : * Helper function which sorts by the vertex averages's distance from the 158 : * origin in the internal std::sort call. 159 : */ 160 : static bool sort_radial (const std::pair<Point, Elem *> & lhs, 161 : const std::pair<Point, Elem *> & rhs); 162 : 163 : /** 164 : * Flag indicating the type of sort method we are using. 165 : */ 166 : CentroidSortMethod _sort_method; 167 : 168 : /** 169 : * Vector which holds pairs of vertex averages and their respective 170 : * element pointers. 171 : */ 172 : std::vector<std::pair<Point, Elem *>> _elem_vertex_avgs; 173 : }; 174 : 175 : } // namespace libMesh 176 : 177 : #endif // LIBMESH_CENTROID_PARTITIONER_H