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 "MooseMesh.h"
11 
12 #include "LibmeshPartitioner.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 
23 template <>
26 {
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  _mesh(*getParam<MooseMesh *>("mesh"))
49 {
50  switch (_partitioner_name)
51  {
52  case -2: // metis
53  _partitioner = libmesh_make_unique<MetisPartitioner>();
54  break;
55  case -1: // parmetis
56  _partitioner = libmesh_make_unique<ParmetisPartitioner>();
57  break;
58 
59  case 0: // linear
60  _partitioner = libmesh_make_unique<LinearPartitioner>();
61  break;
62  case 1: // centroid
63  {
64  if (!isParamValid("centroid_partitioner_direction"))
65  mooseError(
66  "If using the centroid partitioner you _must_ specify centroid_partitioner_direction!");
67 
68  MooseEnum direction = getParam<MooseEnum>("centroid_partitioner_direction");
69 
70  if (direction == "x")
71  _partitioner = libmesh_make_unique<CentroidPartitioner>(CentroidPartitioner::X);
72  else if (direction == "y")
73  _partitioner = libmesh_make_unique<CentroidPartitioner>(CentroidPartitioner::Y);
74  else if (direction == "z")
75  _partitioner = libmesh_make_unique<CentroidPartitioner>(CentroidPartitioner::Z);
76  else if (direction == "radial")
77  _partitioner = libmesh_make_unique<CentroidPartitioner>(CentroidPartitioner::RADIAL);
78  break;
79  }
80  case 2: // hilbert_sfc
81  _partitioner = libmesh_make_unique<HilbertSFCPartitioner>();
82  break;
83  case 3: // morton_sfc
84  _partitioner = libmesh_make_unique<MortonSFCPartitioner>();
85  break;
86  case 4: // subdomain_partitioner
87  _partitioner = libmesh_make_unique<SubdomainPartitioner>();
88  break;
89  }
90 }
91 
93 
94 std::unique_ptr<Partitioner>
96 {
97  switch (_partitioner_name)
98  {
99  case -2: // metis
100  return libmesh_make_unique<MetisPartitioner>();
101  break;
102  case -1: // parmetis
103  return libmesh_make_unique<ParmetisPartitioner>();
104  break;
105 
106  case 0: // linear
107  return libmesh_make_unique<LinearPartitioner>();
108  break;
109  case 1: // centroid
110  {
111  if (!isParamValid("centroid_partitioner_direction"))
112  mooseError(
113  "If using the centroid partitioner you _must_ specify centroid_partitioner_direction!");
114 
115  MooseEnum direction = getParam<MooseEnum>("centroid_partitioner_direction");
116 
117  if (direction == "x")
118  return libmesh_make_unique<CentroidPartitioner>(CentroidPartitioner::X);
119  else if (direction == "y")
120  return libmesh_make_unique<CentroidPartitioner>(CentroidPartitioner::Y);
121  else if (direction == "z")
122  return libmesh_make_unique<CentroidPartitioner>(CentroidPartitioner::Z);
123  else if (direction == "radial")
124  return libmesh_make_unique<CentroidPartitioner>(CentroidPartitioner::RADIAL);
125  break;
126  }
127  case 2: // hilbert_sfc
128  return libmesh_make_unique<HilbertSFCPartitioner>();
129  break;
130  case 3: // morton_sfc
131  return libmesh_make_unique<MortonSFCPartitioner>();
132  break;
133  case 4: // subdomain_partitioner
134  return libmesh_make_unique<LibmeshPartitioner>(parameters());
135  break;
136  }
137  // this cannot happen but I need to trick the compiler into
138  // believing me
139  mooseError("Error in LibmeshPartitioner: Supplied partitioner option causes error in clone()");
140  return libmesh_make_unique<MetisPartitioner>();
141 }
142 
143 void
145  SubdomainPartitioner & subdomain_partitioner)
146 {
147  auto group_begin = _subdomain_blocks.begin();
148  auto group_end = _subdomain_blocks.end();
149 
150  subdomain_partitioner.chunks.clear();
151  for (auto group = group_begin; group != group_end; ++group)
152  {
153  std::set<subdomain_id_type> subdomain_ids;
154  auto subdomain_ids_vec = _mesh.getSubdomainIDs(*group);
155  auto subdomain_begin = subdomain_ids_vec.begin();
156  auto subdomain_end = subdomain_ids_vec.end();
157  for (auto subdomain_id = subdomain_begin; subdomain_id != subdomain_end; ++subdomain_id)
158  {
159  subdomain_ids.insert(*subdomain_id);
160  }
161  subdomain_partitioner.chunks.push_back(subdomain_ids);
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(), "Paritioner 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(), "Paritioner 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 }
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
virtual void prepare_blocks_for_subdomain_partitioner(SubdomainPartitioner &subdomain_partitioner)
void mooseError(Args &&... args) const
Definition: MooseObject.h:147
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
const InputParameters & parameters() const
Get the parameters of the object.
Definition: MooseObject.h:65
MooseMesh wraps a libMesh::Mesh object and enhances its capabilities by caching additional data and s...
Definition: MooseMesh.h:74
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
PetscInt n
Base class for MOOSE partitioner.
virtual void _do_partition(MeshBase &mesh, const unsigned int n)
InputParameters validParams< LibmeshPartitioner >()
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...
std::vector< SubdomainID > getSubdomainIDs(const std::vector< SubdomainName > &subdomain_name) const
Get the associated subdomainIDs for the subdomain names that are passed in.
Definition: MooseMesh.C:1090
LibmeshPartitioner(const InputParameters &params)
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
Definition: MooseObject.h:89
InputParameters validParams< MoosePartitioner >()