https://mooseframework.inl.gov
Loading...
Searching...
No Matches
GridPartitioner.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 "GridPartitioner.h"
11
12#include "GeneratedMesh.h"
13#include "MooseApp.h"
14
15#include "libmesh/mesh_tools.h"
16#include "libmesh/elem.h"
17
19
20#include <memory>
21
24{
26
27 MooseEnum method("manual automatic", "manual");
28 params.addParam<MooseEnum>(
29 "grid_computation",
30 method,
31 "Whether to determine the grid manually (using nx, ny and nz) or automatically. When using "
32 "the automatic mode, the user can impose a certain value for nx, ny or nz, and the automatic "
33 "factorization will adjust the number of processors in the other directions.");
34
35 // Users specify how many processors they need along each direction
36 params.addParam<unsigned int>(
37 "nx", "Number of processors in the X direction. Defaults to 1 in manual mode");
38 params.addParam<unsigned int>(
39 "ny", "Number of processors in the Y direction. Defaults to 1 in manual mode");
40 params.addParam<unsigned int>(
41 "nz", "Number of processors in the Z direction. Defaults to 1 in manual mode");
42
43 params.addClassDescription("Create a uniform grid that overlays the mesh to be partitioned. "
44 "Assign all elements within each cell of the grid to the same "
45 "processor.");
46
47 return params;
48}
49
51 : MoosePartitioner(params), _mesh(*getCheckedPointerParam<MooseMesh *>("mesh"))
52{
53}
54
56
57std::unique_ptr<Partitioner>
59{
60 return _app.getFactory().clone(*this);
61}
62
63void
64GridPartitioner::_do_partition(MeshBase & mesh, const unsigned int /*n*/)
65{
66 // By default, there are one processor along each direction
67 // nx: the number of processors along x direction
68 // ny: the number of processors along y direction
69 // nz: the number of processors along z direction
70 unsigned int nx = 1, ny = 1, nz = 1;
71
72 // Figure out the physical bounds of the given mesh
73 auto bounding_box = MeshTools::create_bounding_box(mesh);
74 const auto & min = bounding_box.min();
75 const auto & max = bounding_box.max();
76
77 auto dim = mesh.mesh_dimension();
78
79 // Gather user parameters
80 nx = isParamValid("nx") ? getParam<unsigned int>("nx") : nx;
81 if (dim >= 2)
82 ny = isParamValid("ny") ? getParam<unsigned int>("ny") : ny;
83 if (dim == 3)
84 nz = isParamValid("nz") ? getParam<unsigned int>("nz") : nz;
85
86 // simple info message unused parameters as this can be normal: we could be partitioning
87 // a 2D mesh before extruding it to 3D. The nz parameter is needed for the 3D mesh
88 if (dim < 2 && isParamValid("ny") && getParam<unsigned int>("ny") > 1)
89 paramInfo("ny", "Parameter ignored as mesh is currently of dimension less than 2.");
90 if (dim < 3 && isParamValid("nz") && getParam<unsigned int>("nz") > 1)
91 paramInfo("nz", "Parameter ignored as mesh is currently of dimension less than 3.");
92
93 // User parameters, which should match the number of partitions needed
94 if (getParam<MooseEnum>("grid_computation") == "manual")
95 {
96 // Need to make sure the number of grid cells matches the number of procs to partition for
97 if ((nx * ny * nz) != mesh.n_partitions())
98 mooseError("Number of grid cells (" + std::to_string(nx * ny * nz) +
99 ") does not match the number of MPI processes (" +
100 std::to_string(mesh.n_partitions()) + ")");
101 }
102
103 else if (getParam<MooseEnum>("grid_computation") == "automatic")
104 {
105 // remove over-constraint and tell user
106 if (nx * ny * nz > mesh.n_partitions())
107 {
108 nx = 0;
109 ny = 0;
110 nz = 0;
111 paramWarning("grid_computation",
112 "User specified (nx,ny,nz) grid exceeded number of partitions, these parameters "
113 "will be ignored.");
114 }
115 // 0 means no restriction on which number to choose
116 int dims[] = {isParamValid("nx") ? int(nx) : 0,
117 isParamValid("ny") ? int(ny) : 0,
118 isParamValid("nz") ? int(nz) : 0};
119
120 if ((dims[0] > 0 && dim == 1 && dims[0] != int(mesh.n_partitions())) ||
121 (dims[0] > 0 && dims[1] > 0 && dim == 2 && dims[0] * dims[1] != int(mesh.n_partitions())) ||
122 (dims[0] > 0 && dims[1] > 0 && dims[2] > 0 && dim == 3 &&
123 dims[0] * dims[1] * dims[2] != int(mesh.n_partitions())))
124 {
125 dims[0] = 0;
126 dims[1] = 0;
127 dims[2] = 0;
128 paramWarning("grid_computation",
129 "User specified grid for the current dimension of the mesh (" +
130 std::to_string(dim) + ") does not fit the number of partitions (" +
131 std::to_string(mesh.n_partitions()) +
132 ") and constrain the grid partitioner in every direction, these parameters "
133 "will be ignored.");
134 }
135
136 // This will error if the factorization is not possible
137 MPI_Dims_create(mesh.n_partitions(), dim, dims);
138
139 nx = dims[0];
140 if (dim >= 2)
141 ny = dims[1];
142 if (dim == 3)
143 nz = dims[2];
144 }
145
146 // hx: grid interval along x direction
147 // hy: grid interval along y direction
148 // hz: grid interval along z direction
149 // Lx: domain length along x direction
150 // Ly: domain length along y direction
151 // Lz: domain length along z direction
152 Real hx = 1., hy = 1., hz = 1., Lx = 1., Ly = 1., Lz = 1.;
153 Lx = max(0) - min(0);
154 hx = Lx / nx;
155 if (dim >= 2)
156 {
157 Ly = max(1) - min(1);
158 hy = Ly / ny;
159 }
160
161 if (dim == 3)
162 {
163 Lz = max(2) - min(2);
164 hz = Lz / nz;
165 }
166
167 // Processor coordinates along x, y, z directions
168 unsigned int k = 0, j = 0, i = 0;
169 // Coordinates for current element centroid
170 Real coordx = 0, coordy = 0, coordz = 0;
171
172 // Loop over all of the elements in the given mesh
173 for (auto & elem_ptr : mesh.active_element_ptr_range())
174 {
175 // Find the element it lands in in the GeneratedMesh
176 auto centroid = elem_ptr->vertex_average();
177
178 coordx = centroid(0);
179 mooseAssert(coordx >= min(0) && coordy <= max(0),
180 "element is outside of bounding box along x direction");
181 if (dim >= 2)
182 {
183 coordy = centroid(1);
184 mooseAssert(coordy >= min(1) && coordy <= max(1),
185 "element is outside of bounding box along y direction");
186 }
187 if (dim == 3)
188 {
189 coordz = centroid(2);
190 mooseAssert(coordz >= min(2) && coordz <= max(2),
191 "element is outside of bounding box along z direction");
192 }
193
194 // Compute processor coordinates
195 j = k = 0;
196 i = (coordx - min(0)) / hx;
197 if (dim >= 2)
198 j = (coordy - min(1)) / hy;
199 if (dim == 3)
200 k = (coordz - min(2)) / hz;
201
202 mooseAssert(i < nx, "Index calculation is wrong along x direction");
203 mooseAssert(j < ny || ny == 0, "Index calculation is wrong along y direction");
204 mooseAssert(k < nz || nz == 0, "Index calculation is wrong along z direction");
205 // Assign processor ID to current element
206 elem_ptr->processor_id() = k * nx * ny + j * nx + i;
207 }
208}
registerMooseObject("MooseApp", GridPartitioner)
unsigned int dim
void ErrorVector unsigned int
std::unique_ptr< T > clone(const T &object)
Clones the object object.
Definition Factory.h:323
Partitions a mesh using a regular grid.
virtual ~GridPartitioner()
virtual std::unique_ptr< Partitioner > clone() const override
virtual void _do_partition(MeshBase &mesh, const unsigned int n) override
static InputParameters validParams()
GridPartitioner(const InputParameters &params)
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
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.
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.
Factory & getFactory()
Retrieve a writable reference to the Factory associated with this App.
Definition MooseApp.h:407
void paramInfo(const std::string &param, Args... args) const
Emits an informational message prefixed with the file and line number of the given param (from the in...
Definition MooseBase.h:471
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type and optionally a file path to the top-level block p...
Definition MooseBase.h:271
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
Definition MooseBase.h:199
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition MooseEnum.h:55
MooseMesh wraps a libMesh::Mesh object and enhances its capabilities by caching additional data and s...
Definition MooseMesh.h:95
MooseApp & _app
The MOOSE application this is associated with.
Definition MooseBase.h:375
Base class for MOOSE partitioner.
static InputParameters validParams()
void paramWarning(const std::string &param, Args... args) const
MeshBase & mesh
libMesh::BoundingBox create_bounding_box(const MeshBase &mesh)