Line data Source code
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 : 19 : 20 : #ifndef LIBMESH_SUBDOMAIN_PARTITIONER_H 21 : #define LIBMESH_SUBDOMAIN_PARTITIONER_H 22 : 23 : // Local Includes 24 : #include "libmesh/partitioner.h" 25 : 26 : // C++ Includes 27 : #include <memory> 28 : 29 : namespace libMesh 30 : { 31 : 32 : /** 33 : * The \p SubdomainPartitioner partitions the elements in "chunks" of 34 : * user-specified subdomain ids. Once all the chunks are partitioned, 35 : * the overall mesh partitioning is simply the union of the chunk 36 : * partitionings. For example, if the "chunks" vector is given by: 37 : * chunks[0] = {1, 2, 4} 38 : * chunks[1] = {3, 7, 8} 39 : * chunks[2] = {5, 6} 40 : * then we will call the internal Partitioner three times, once for 41 : * subdomains 1, 2, and 4, once for subdomains 3, 7, and 8, and once 42 : * for subdomains 5 and 6. 43 : * 44 : * \note This Partitioner may produce highly non-optimal communication 45 : * patterns and is likely to place geometrically disjoint sets of 46 : * elements on the same processor. Its intended use is to help 47 : * facilitate load balancing. That is, if the user knows that certain 48 : * subdomains (or groups of subdomains) are more expensive to compute 49 : * than others, he/she can ensure that they are partitioned more or 50 : * less evenly among the available processors by specifying them 51 : * together in a single entry of the "chunk" vector. 52 : * 53 : * \author John W. Peterson 54 : * \date 2017 55 : * \brief Independently partitions chunks of subdomains and combines the results. 56 : */ 57 : class SubdomainPartitioner : public Partitioner 58 : { 59 : public: 60 : 61 : /** 62 : * Constructors. The default ctor initializes the internal 63 : * Partitioner object to a MetisPartitioner so the class is usable, 64 : * although this type can be customized later. 65 : */ 66 : SubdomainPartitioner (); 67 : SubdomainPartitioner (const SubdomainPartitioner & other); 68 : 69 : /** 70 : * This class contains a unique_ptr member, so it can't be default 71 : * copy assigned. 72 : */ 73 : SubdomainPartitioner & operator= (const SubdomainPartitioner &) = delete; 74 : 75 : /** 76 : * Move ctor, move assignment operator, and destructor are 77 : * all explicitly defaulted for this class. 78 : */ 79 : SubdomainPartitioner (SubdomainPartitioner &&) = default; 80 : SubdomainPartitioner & operator= (SubdomainPartitioner &&) = default; 81 0 : virtual ~SubdomainPartitioner() = default; 82 : 83 : virtual PartitionerType type () const override; 84 : 85 : /** 86 : * \returns A copy of this partitioner wrapped in a smart pointer. 87 : */ 88 0 : virtual std::unique_ptr<Partitioner> clone () const override 89 : { 90 0 : return std::make_unique<SubdomainPartitioner>(*this); 91 : } 92 : 93 : /** 94 : * Each entry of "chunks" represents a set of subdomains which are 95 : * to be partitioned together. The internal Partitioner will be 96 : * called once for each entry of chunks, and the resulting 97 : * partitioning will simply be the union of all these partitionings. 98 : */ 99 : std::vector<std::set<subdomain_id_type>> chunks; 100 : 101 : /** 102 : * Get a reference to the Partitioner used internally by the 103 : * SubdomainPartitioner. 104 : * 105 : * \note The internal Partitioner cannot also be a 106 : * SubdomainPartitioner, otherwise an infinite loop will result. To 107 : * have this class use e.g. the space-filling curve Partitioner 108 : * internally, one could do: 109 : * 110 : * \code 111 : * SubdomainPartitioner sp; 112 : * sp.internal_partitioner() = std::make_unique<SFCPartitioner>(); 113 : * \endcode 114 : */ 115 : std::unique_ptr<Partitioner> & internal_partitioner() { return _internal_partitioner; } 116 : 117 : protected: 118 : /** 119 : * The internal Partitioner we use. Public access via the 120 : * internal_partitioner() member function. 121 : */ 122 : std::unique_ptr<Partitioner> _internal_partitioner; 123 : 124 : /** 125 : * Partition the \p MeshBase into \p n subdomains. 126 : */ 127 : virtual void _do_partition (MeshBase & mesh, 128 : const unsigned int n) override; 129 : }; 130 : 131 : } // namespace libMesh 132 : 133 : #endif // LIBMESH_SUBDOMAIN_PARTITIONER_H