www.mooseframework.org
LibmeshPartitioner.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
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 "MooseMeshUtils.h"
13 #include "libmesh/linear_partitioner.h"
14 #include "libmesh/centroid_partitioner.h"
15 #include "libmesh/parmetis_partitioner.h"
16 #include "libmesh/metis_partitioner.h"
17 #include "libmesh/hilbert_sfc_partitioner.h"
18 #include "libmesh/morton_sfc_partitioner.h"
19 #include "libmesh/subdomain_partitioner.h"
20 
22 
25 {
27  params.addClassDescription("Mesh partitioning using capabilities defined in libMesh.");
28  MooseEnum partitioning(
29  "metis=-2 parmetis=-1 linear=0 centroid hilbert_sfc morton_sfc subdomain_partitioner");
31  "partitioner",
32  partitioning,
33  "Specifies a mesh partitioner to use when splitting the mesh for a parallel computation.");
34  MooseEnum direction("x y z radial");
35  params.addParam<MooseEnum>("centroid_partitioner_direction",
36  direction,
37  "Specifies the sort direction if using the centroid partitioner. "
38  "Available options: x, y, z, radial");
39  params.addParam<std::vector<std::vector<SubdomainName>>>(
40  "blocks", {}, "Block is seperated by ;, and partition mesh block by block. ");
41  return params;
42 }
43 
45  : MoosePartitioner(params),
46  _partitioner_name(getParam<MooseEnum>("partitioner")),
47  _subdomain_blocks(getParam<std::vector<std::vector<SubdomainName>>>("blocks"))
48 {
49  switch (_partitioner_name)
50  {
51  case -2: // metis
52  _partitioner = std::make_unique<MetisPartitioner>();
53  break;
54  case -1: // parmetis
55  _partitioner = std::make_unique<ParmetisPartitioner>();
56  break;
57 
58  case 0: // linear
59  _partitioner = std::make_unique<LinearPartitioner>();
60  break;
61  case 1: // centroid
62  {
63  if (!isParamValid("centroid_partitioner_direction"))
64  mooseError(
65  "If using the centroid partitioner you _must_ specify centroid_partitioner_direction!");
66 
67  MooseEnum direction = getParam<MooseEnum>("centroid_partitioner_direction");
68 
69  if (direction == "x")
70  _partitioner = std::make_unique<CentroidPartitioner>(CentroidPartitioner::X);
71  else if (direction == "y")
72  _partitioner = std::make_unique<CentroidPartitioner>(CentroidPartitioner::Y);
73  else if (direction == "z")
74  _partitioner = std::make_unique<CentroidPartitioner>(CentroidPartitioner::Z);
75  else if (direction == "radial")
76  _partitioner = std::make_unique<CentroidPartitioner>(CentroidPartitioner::RADIAL);
77  break;
78  }
79  case 2: // hilbert_sfc
80  _partitioner = std::make_unique<HilbertSFCPartitioner>();
81  break;
82  case 3: // morton_sfc
83  _partitioner = std::make_unique<MortonSFCPartitioner>();
84  break;
85  case 4: // subdomain_partitioner
86  _partitioner = std::make_unique<SubdomainPartitioner>();
87  break;
88  }
89 }
90 
92 
93 std::unique_ptr<Partitioner>
95 {
96  switch (_partitioner_name)
97  {
98  case -2: // metis
99  return std::make_unique<MetisPartitioner>();
100 
101  case -1: // parmetis
102  return std::make_unique<ParmetisPartitioner>();
103 
104  case 0: // linear
105  return std::make_unique<LinearPartitioner>();
106 
107  case 1: // centroid
108  {
109  if (!isParamValid("centroid_partitioner_direction"))
110  mooseError(
111  "If using the centroid partitioner you _must_ specify centroid_partitioner_direction!");
112 
113  MooseEnum direction = getParam<MooseEnum>("centroid_partitioner_direction");
114 
115  if (direction == "x")
116  return std::make_unique<CentroidPartitioner>(CentroidPartitioner::X);
117  else if (direction == "y")
118  return std::make_unique<CentroidPartitioner>(CentroidPartitioner::Y);
119  else if (direction == "z")
120  return std::make_unique<CentroidPartitioner>(CentroidPartitioner::Z);
121  else if (direction == "radial")
122  return std::make_unique<CentroidPartitioner>(CentroidPartitioner::RADIAL);
123  break;
124  }
125  case 2: // hilbert_sfc
126  return std::make_unique<HilbertSFCPartitioner>();
127 
128  case 3: // morton_sfc
129  return std::make_unique<MortonSFCPartitioner>();
130 
131  case 4: // subdomain_partitioner
132  return std::make_unique<LibmeshPartitioner>(parameters());
133  }
134  // this cannot happen but I need to trick the compiler into
135  // believing me
136  mooseError("Error in LibmeshPartitioner: Supplied partitioner option causes error in clone()");
137  return std::make_unique<MetisPartitioner>();
138 }
139 
140 void
142  const MeshBase & mesh, SubdomainPartitioner & subdomain_partitioner)
143 {
144  // For making sure all of the blocks exist
145  std::set<subdomain_id_type> mesh_subdomain_ids;
146  mesh.subdomain_ids(mesh_subdomain_ids);
147 
148  // Clear chunks before filling
149  subdomain_partitioner.chunks.clear();
150 
151  // Insert each chunk
152  for (const auto & group : _subdomain_blocks)
153  {
154  const auto subdomain_ids = MooseMeshUtils::getSubdomainIDs(mesh, group);
155  for (const auto id : subdomain_ids)
156  if (!mesh_subdomain_ids.count(id))
157  paramError("blocks", "The block ", id, " was not found on the mesh");
158 
159  std::set<subdomain_id_type> subdomain_ids_set(subdomain_ids.begin(), subdomain_ids.end());
160 
161  subdomain_partitioner.chunks.push_back(subdomain_ids_set);
162  }
163 }
164 
165 void
166 LibmeshPartitioner::partition(MeshBase & mesh, const unsigned int n)
167 {
168  if (_partitioner_name == "subdomain_partitioner")
169  {
170  mooseAssert(_partitioner.get(), "Partitioner is a NULL object");
172  static_cast<SubdomainPartitioner &>(*_partitioner.get()));
173  }
174 
175  _partitioner->partition(mesh, n);
176 }
177 
178 void
180 {
181  if (_partitioner_name == "subdomain_partitioner")
182  {
183  mooseAssert(_partitioner.get(), "Partitioner is a NULL object");
185  static_cast<SubdomainPartitioner &>(*_partitioner.get()));
186  }
187 
188  _partitioner->partition(mesh);
189 }
190 
191 void
192 LibmeshPartitioner::_do_partition(MeshBase & /*mesh*/, const unsigned int /*n*/)
193 {
194 }
static InputParameters validParams()
static InputParameters validParams()
virtual void prepareBlocksForSubdomainPartitioner(const MeshBase &mesh, SubdomainPartitioner &subdomain_partitioner)
MeshBase & mesh
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
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...
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:31
virtual std::unique_ptr< Partitioner > clone() const
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...
const InputParameters & parameters() const
Get the parameters of the object.
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an option parameter and a documentation string to the InputParameters object...
LibmeshPartitioner(const InputParameters &params)