https://mooseframework.inl.gov
LibmeshPartitioner.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://mooseframework.inl.gov
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
10 #include "LibmeshPartitioner.h"
11 
12 #include "MooseApp.h"
13 #include "MooseMeshUtils.h"
14 
15 #include "libmesh/linear_partitioner.h"
16 #include "libmesh/centroid_partitioner.h"
17 #include "libmesh/parmetis_partitioner.h"
18 #include "libmesh/metis_partitioner.h"
19 #include "libmesh/hilbert_sfc_partitioner.h"
20 #include "libmesh/morton_sfc_partitioner.h"
21 #include "libmesh/subdomain_partitioner.h"
22 
24 
27 {
29  params.addClassDescription("Mesh partitioning using capabilities defined in libMesh.");
30  MooseEnum partitioning(
31  "metis=-2 parmetis=-1 linear=0 centroid hilbert_sfc morton_sfc subdomain_partitioner");
33  "partitioner",
34  partitioning,
35  "Specifies a mesh partitioner to use when splitting the mesh for a parallel computation.");
36  MooseEnum direction("x y z radial");
37  params.addParam<MooseEnum>("centroid_partitioner_direction",
38  direction,
39  "Specifies the sort direction if using the centroid partitioner. "
40  "Available options: x, y, z, radial");
41  params.addParam<std::vector<std::vector<SubdomainName>>>(
42  "blocks", {}, "Block is seperated by ;, and partition mesh block by block. ");
43  return params;
44 }
45 
47  : MoosePartitioner(params),
48  _partitioner_name(getParam<MooseEnum>("partitioner")),
49  _subdomain_blocks(getParam<std::vector<std::vector<SubdomainName>>>("blocks"))
50 {
51  switch (_partitioner_name)
52  {
53  case -2: // metis
54  _partitioner = std::make_unique<libMesh::MetisPartitioner>();
55  break;
56  case -1: // parmetis
57  _partitioner = std::make_unique<libMesh::ParmetisPartitioner>();
58  break;
59 
60  case 0: // linear
61  _partitioner = std::make_unique<libMesh::LinearPartitioner>();
62  break;
63  case 1: // centroid
64  {
65  if (!isParamValid("centroid_partitioner_direction"))
66  mooseError(
67  "If using the centroid partitioner you _must_ specify centroid_partitioner_direction!");
68 
69  MooseEnum direction = getParam<MooseEnum>("centroid_partitioner_direction");
70 
71  if (direction == "x")
72  _partitioner =
73  std::make_unique<libMesh::CentroidPartitioner>(libMesh::CentroidPartitioner::X);
74  else if (direction == "y")
75  _partitioner =
76  std::make_unique<libMesh::CentroidPartitioner>(libMesh::CentroidPartitioner::Y);
77  else if (direction == "z")
78  _partitioner =
79  std::make_unique<libMesh::CentroidPartitioner>(libMesh::CentroidPartitioner::Z);
80  else if (direction == "radial")
81  _partitioner =
82  std::make_unique<libMesh::CentroidPartitioner>(libMesh::CentroidPartitioner::RADIAL);
83  break;
84  }
85  case 2: // hilbert_sfc
86  _partitioner = std::make_unique<libMesh::HilbertSFCPartitioner>();
87  break;
88  case 3: // morton_sfc
89  _partitioner = std::make_unique<libMesh::MortonSFCPartitioner>();
90  break;
91  case 4: // subdomain_partitioner
92  _partitioner = std::make_unique<libMesh::SubdomainPartitioner>();
93  break;
94  }
95 }
96 
98 
99 std::unique_ptr<Partitioner>
101 {
102  switch (_partitioner_name)
103  {
104  case -2: // metis
105  return std::make_unique<libMesh::MetisPartitioner>();
106 
107  case -1: // parmetis
108  return std::make_unique<libMesh::ParmetisPartitioner>();
109 
110  case 0: // linear
111  return std::make_unique<libMesh::LinearPartitioner>();
112 
113  case 1: // centroid
114  {
115  if (!isParamValid("centroid_partitioner_direction"))
116  mooseError(
117  "If using the centroid partitioner you _must_ specify centroid_partitioner_direction!");
118 
119  MooseEnum direction = getParam<MooseEnum>("centroid_partitioner_direction");
120 
121  if (direction == "x")
122  return std::make_unique<libMesh::CentroidPartitioner>(libMesh::CentroidPartitioner::X);
123  else if (direction == "y")
124  return std::make_unique<libMesh::CentroidPartitioner>(libMesh::CentroidPartitioner::Y);
125  else if (direction == "z")
126  return std::make_unique<libMesh::CentroidPartitioner>(libMesh::CentroidPartitioner::Z);
127  else if (direction == "radial")
128  return std::make_unique<libMesh::CentroidPartitioner>(libMesh::CentroidPartitioner::RADIAL);
129  break;
130  }
131  case 2: // hilbert_sfc
132  return std::make_unique<libMesh::HilbertSFCPartitioner>();
133 
134  case 3: // morton_sfc
135  return std::make_unique<libMesh::MortonSFCPartitioner>();
136 
137  case 4: // subdomain_partitioner
138  return _app.getFactory().clone(*this);
139  }
140  // this cannot happen but I need to trick the compiler into
141  // believing me
142  mooseError("Error in LibmeshPartitioner: Supplied partitioner option causes error in clone()");
143  return std::make_unique<libMesh::MetisPartitioner>();
144 }
145 
146 void
148  const MeshBase & mesh, libMesh::SubdomainPartitioner & subdomain_partitioner)
149 {
150  // For making sure all of the blocks exist
151  std::set<subdomain_id_type> mesh_subdomain_ids;
152  mesh.subdomain_ids(mesh_subdomain_ids);
153 
154  // Clear chunks before filling
155  subdomain_partitioner.chunks.clear();
156 
157  // Insert each chunk
158  for (const auto & group : _subdomain_blocks)
159  {
160  const auto subdomain_ids = MooseMeshUtils::getSubdomainIDs(mesh, group);
161  for (const auto id : subdomain_ids)
162  if (!mesh_subdomain_ids.count(id))
163  paramError("blocks", "The block ", id, " was not found on the mesh");
164 
165  std::set<subdomain_id_type> subdomain_ids_set(subdomain_ids.begin(), subdomain_ids.end());
166 
167  subdomain_partitioner.chunks.push_back(subdomain_ids_set);
168  }
169 }
170 
171 void
172 LibmeshPartitioner::partition(MeshBase & mesh, const unsigned int n)
173 {
174  if (_partitioner_name == "subdomain_partitioner")
175  {
176  mooseAssert(_partitioner.get(), "Partitioner is a NULL object");
178  mesh, static_cast<libMesh::SubdomainPartitioner &>(*_partitioner.get()));
179  }
180 
181  _partitioner->partition(mesh, n);
182 }
183 
184 void
186 {
187  if (_partitioner_name == "subdomain_partitioner")
188  {
189  mooseAssert(_partitioner.get(), "Partitioner is a NULL object");
191  mesh, static_cast<libMesh::SubdomainPartitioner &>(*_partitioner.get()));
192  }
193 
194  _partitioner->partition(mesh);
195 }
196 
197 void
198 LibmeshPartitioner::_do_partition(MeshBase & /*mesh*/, const unsigned int /*n*/)
199 {
200 }
static InputParameters validParams()
virtual void prepareBlocksForSubdomainPartitioner(const MeshBase &mesh, libMesh::SubdomainPartitioner &subdomain_partitioner)
static InputParameters validParams()
MeshBase & mesh
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
std::vector< std::set< subdomain_id_type > > chunks
std::vector< subdomain_id_type > getSubdomainIDs(const libMesh::MeshBase &mesh, const std::vector< SubdomainName > &subdomain_name)
Get the associated subdomainIDs for the subdomain names that are passed in.
registerMooseObject("MooseApp", LibmeshPartitioner)
std::unique_ptr< Partitioner > _partitioner
virtual void partition(MeshBase &mesh, const unsigned int n)
void addRequiredParam(const std::string &name, const std::string &doc_string)
This method adds a parameter and documentation string to the InputParameters object that will be extr...
Factory & getFactory()
Retrieve a writable reference to the Factory associated with this App.
Definition: MooseApp.h:424
const std::vector< std::vector< SubdomainName > > & _subdomain_blocks
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition: MooseEnum.h:33
virtual std::unique_ptr< Partitioner > clone() const
MooseApp & _app
The MOOSE application this is associated with.
Definition: MooseBase.h:84
void paramError(const std::string &param, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
Base class for MOOSE partitioner.
virtual void _do_partition(MeshBase &mesh, const unsigned int n)
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type.
void addClassDescription(const std::string &doc_string)
This method adds a description of the class that will be displayed in the input file syntax dump...
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an optional parameter and a documentation string to the InputParameters object...
std::unique_ptr< T > clone(const T &object)
Clones the object object.
Definition: Factory.h:275
LibmeshPartitioner(const InputParameters &params)