https://mooseframework.inl.gov
Loading...
Searching...
No Matches
CartesianMeshGenerator.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
11#include "CastUniquePointer.h"
12
13// libMesh includes
14#include "libmesh/mesh_generation.h"
15#include "libmesh/unstructured_mesh.h"
16#include "libmesh/replicated_mesh.h"
17#include "libmesh/point.h"
18#include "libmesh/elem.h"
19#include "libmesh/node.h"
20
22
25{
27 MooseEnum dims("1=1 2 3");
28 params.addRequiredParam<MooseEnum>("dim", dims, "The dimension of the mesh to be generated");
29
30 params.addRequiredParam<std::vector<Real>>("dx", "Intervals in the X direction");
31 params.addParam<std::vector<unsigned int>>(
32 "ix", "Number of grids in all intervals in the X direction (default to all one)");
33 params.addParam<std::vector<Real>>(
34 "max_sizes_in_x",
35 "Maximum element size in the X direction. This can be specified once for all 'dx' intervals "
36 "or specified for each interval. 'ix' is then determined using the ceiling of dx/size");
37 params.addParam<std::vector<Real>>(
38 "dy", "Intervals in the Y direction (required when dim>1 otherwise ignored)");
39 params.addParam<std::vector<unsigned int>>(
40 "iy", "Number of grids in all intervals in the Y direction (default to all one)");
41 params.addParam<std::vector<Real>>(
42 "max_sizes_in_y",
43 "Maximum element size in the Y direction. This can be specified once for all 'dy' intervals "
44 "or specified for each interval. 'iy' is then determined using the ceiling of dy/size");
45 params.addParam<std::vector<Real>>(
46 "dz", "Intervals in the Z direction (required when dim>2 otherwise ignored)");
47 params.addParam<std::vector<unsigned int>>(
48 "iz", "Number of grids in all intervals in the Z direction (default to all one)");
49 params.addParam<std::vector<Real>>(
50 "max_sizes_in_z",
51 "Maximum element size in the Z direction. This can be specified once for all 'dz' intervals "
52 "or specified for each interval. 'iz' is then determined using the ceiling of dz/size");
53 params.addParam<std::vector<unsigned int>>("subdomain_id", "Block IDs (default to all zero)");
54 params.addClassDescription("This CartesianMeshGenerator creates a non-uniform Cartesian mesh.");
55 return params;
56}
57
59 : MeshGenerator(parameters),
60 _dim(getParam<MooseEnum>("dim")),
61 _dx(getParam<std::vector<Real>>("dx"))
62{
63 // get all other parameters if provided and check their sizes
64 if (isParamValid("ix"))
65 {
66 _ix = getParam<std::vector<unsigned int>>("ix");
67 if (_ix.size() != _dx.size())
68 mooseError("ix must be the same size as dx");
69 for (unsigned int i = 0; i < _ix.size(); ++i)
70 if (_ix[i] == 0)
71 mooseError("ix cannot be zero");
72 if (isParamValid("max_sizes_in_x"))
73 paramError("max_sizes_in_x", "Cannot be provided if 'ix' is specified");
74 }
75 else if (isParamValid("max_sizes_in_x"))
76 {
77 _ix.resize(_dx.size());
78 auto max_sizes = getParam<std::vector<Real>>("max_sizes_in_x");
79 if (max_sizes.size() == 1)
80 max_sizes.resize(_dx.size(), max_sizes[0]);
81 if (max_sizes.size() != _dx.size())
82 paramError("max_sizes_in_x", "max_sizes_in_x must be size 1 or the same size as dx");
83 for (const auto i : index_range(_dx))
84 if (max_sizes[i] <= 0)
85 paramError("max_sizes_in_x", "max_sizes_in_x must be strictly positive.");
86 for (const auto i : index_range(_dx))
87 _ix[i] = std::ceil(_dx[i] / max_sizes[i]);
88 }
89 else
90 _ix = std::vector<unsigned int>(_dx.size(), 1);
91
92 for (unsigned int i = 0; i < _dx.size(); ++i)
93 if (_dx[i] <= 0)
94 mooseError("dx must be greater than zero. dx: ", Moose::stringify(_dx));
95
96 if (isParamValid("dy"))
97 {
98 _dy = getParam<std::vector<Real>>("dy");
99 for (unsigned int i = 0; i < _dy.size(); ++i)
100 if (_dy[i] <= 0)
101 mooseError("dy must be greater than zero. dy: ", Moose::stringify(_dy));
102 }
103
104 if (isParamValid("iy"))
105 {
106 _iy = getParam<std::vector<unsigned int>>("iy");
107 if (_iy.size() != _dy.size())
108 mooseError("iy must be the same size as dy");
109 for (unsigned int i = 0; i < _iy.size(); ++i)
110 if (_iy[i] == 0)
111 mooseError("iy cannot be zero");
112 if (isParamValid("max_sizes_in_y"))
113 paramError("max_sizes_in_y", "Cannot be provided if 'iy' is specified");
114 }
115 else if (isParamValid("max_sizes_in_y"))
116 {
117 _iy.resize(_dy.size());
118 auto max_sizes = getParam<std::vector<Real>>("max_sizes_in_y");
119 if (max_sizes.size() == 1)
120 max_sizes.resize(_dy.size(), max_sizes[0]);
121 if (max_sizes.size() != _dy.size())
122 paramError("max_sizes_in_y", "max_sizes_in_y must be size 1 or the same size as dy");
123 for (const auto i : index_range(_dy))
124 if (max_sizes[i] <= 0)
125 paramError("max_sizes_in_y", "max_sizes_in_y must be strictly positive.");
126 for (const auto i : index_range(_dy))
127 _iy[i] = std::ceil(_dy[i] / max_sizes[i]);
128 }
129 else
130 _iy = std::vector<unsigned int>(_dy.size(), 1);
131
132 if (isParamValid("dz"))
133 {
134 _dz = getParam<std::vector<Real>>("dz");
135 for (unsigned int i = 0; i < _dz.size(); ++i)
136 if (_dz[i] <= 0)
137 mooseError("dz must be greater than zero dz: ", Moose::stringify(_dz));
138 }
139
140 if (isParamValid("iz"))
141 {
142 _iz = getParam<std::vector<unsigned int>>("iz");
143 if (_iz.size() != _dz.size())
144 mooseError("iz must be the same size as dz");
145 for (unsigned int i = 0; i < _iz.size(); ++i)
146 if (_iz[i] == 0)
147 mooseError("iz cannot be zero");
148 if (isParamValid("max_sizes_in_z"))
149 paramError("max_sizes_in_z", "Cannot be provided if 'iz' is specified");
150 }
151 else if (isParamValid("max_sizes_in_z"))
152 {
153 _iz.resize(_dz.size());
154 auto max_sizes = getParam<std::vector<Real>>("max_sizes_in_z");
155 if (max_sizes.size() == 1)
156 max_sizes.resize(_dz.size(), max_sizes[0]);
157 if (max_sizes.size() != _dz.size())
158 paramError("max_sizes_in_z", "max_sizes_in_z must be size 1 or the same size as dz");
159 for (const auto i : index_range(_dz))
160 if (max_sizes[i] <= 0)
161 paramError("max_sizes_in_z", "max_sizes_in_z must be strictly positive.");
162 for (const auto i : index_range(_dz))
163 _iz[i] = std::ceil(_dz[i] / max_sizes[i]);
164 }
165 else
166 _iz = std::vector<unsigned int>(_dz.size(), 1);
167
168 if (isParamValid("subdomain_id"))
169 {
170 _subdomain_id = getParam<std::vector<unsigned int>>("subdomain_id");
171 if (isParamValid("dz") && isParamValid("dy"))
172 {
173 if (_subdomain_id.size() != _dx.size() * _dy.size() * _dz.size())
175 "subdomain_id must be the size of the product of sizes of dx, dy and dz. Sizes are '" +
176 std::to_string(_subdomain_id.size()) + "' and '" +
177 std::to_string(_dx.size() * _dy.size() * _dz.size()) + "' respectively");
178 }
179 else if (isParamValid("dy"))
180 {
181 if (_subdomain_id.size() != _dx.size() * _dy.size())
183 "subdomain_id must be the size of the product of sizes of dx and dy. Sizes are '" +
184 std::to_string(_subdomain_id.size()) + "' and '" +
185 std::to_string(_dx.size() * _dy.size()) + "' respectively");
186 }
187 else
188 {
189 if (_subdomain_id.size() != _dx.size())
190 mooseError("subdomain_id must be the size of the product of sizes of dx. Sizes are '" +
191 std::to_string(_subdomain_id.size()) + "' and '" + std::to_string(_dx.size()) +
192 "' respectively");
193 }
194 }
195 else
196 {
197 if (isParamValid("dz"))
198 _subdomain_id = std::vector<unsigned int>(_dx.size() * _dy.size() * _dz.size(), 0);
199 else if (isParamValid("dy"))
200 _subdomain_id = std::vector<unsigned int>(_dx.size() * _dy.size(), 0);
201 else
202 _subdomain_id = std::vector<unsigned int>(_dx.size(), 0);
203 }
204
205 // do dimension checks and expand block IDs for all sub-grids
206 switch (_dim)
207 {
208 case 1:
209 {
210 _nx = 0;
211 for (unsigned int i = 0; i < _dx.size(); ++i)
212 _nx += _ix[i];
213 _ny = 1;
214 _nz = 1;
215
216 std::vector<unsigned int> new_id;
217 for (unsigned int i = 0; i < _dx.size(); ++i)
218 for (unsigned int ii = 0; ii < _ix[i]; ++ii)
219 new_id.push_back(_subdomain_id[i]);
220
221 _subdomain_id = new_id;
222
223 if (isParamValid("dy"))
224 mooseWarning("dy provided for 1D");
225 if (isParamValid("iy"))
226 mooseWarning("iy provided for 1D");
227 if (isParamValid("dz"))
228 mooseWarning("dz provided for 1D");
229 if (isParamValid("iz"))
230 mooseWarning("iz provided for 1D");
231 if (isParamValid("max_sizes_in_y"))
232 paramWarning("max_sizes_in_y", "Should not be provided for 1D");
233 if (isParamValid("max_sizes_in_z"))
234 paramWarning("max_sizes_in_z", "Should not be provided for 1D");
235 break;
236 }
237 case 2:
238 {
239 _nx = 0;
240 for (unsigned int i = 0; i < _dx.size(); ++i)
241 _nx += _ix[i];
242 _ny = 0;
243 for (unsigned int i = 0; i < _dy.size(); ++i)
244 _ny += _iy[i];
245 _nz = 1;
246
247 std::vector<unsigned int> new_id;
248 for (unsigned int j = 0; j < _dy.size(); ++j)
249 for (unsigned int jj = 0; jj < _iy[j]; ++jj)
250 for (unsigned int i = 0; i < _dx.size(); ++i)
251 for (unsigned int ii = 0; ii < _ix[i]; ++ii)
252 new_id.push_back(_subdomain_id[j * _dx.size() + i]);
253
254 _subdomain_id = new_id;
255
256 if (!isParamValid("dy"))
257 mooseError("dy is not provided for 2D");
258 if (isParamValid("dz"))
259 mooseWarning("dz provided for 2D");
260 if (isParamValid("iz"))
261 mooseWarning("iz provided for 2D");
262 if (isParamValid("max_sizes_in_z"))
263 paramWarning("max_sizes_in_z", "Should not be provided for 2D");
264 break;
265 }
266 case 3:
267 {
268 _nx = 0;
269 for (unsigned int i = 0; i < _dx.size(); ++i)
270 _nx += _ix[i];
271 _ny = 0;
272 for (unsigned int i = 0; i < _dy.size(); ++i)
273 _ny += _iy[i];
274 _nz = 0;
275 for (unsigned int i = 0; i < _dz.size(); ++i)
276 _nz += _iz[i];
277
278 std::vector<unsigned int> new_id;
279 for (unsigned int k = 0; k < _dz.size(); ++k)
280 for (unsigned int kk = 0; kk < _iz[k]; ++kk)
281 for (unsigned int j = 0; j < _dy.size(); ++j)
282 for (unsigned int jj = 0; jj < _iy[j]; ++jj)
283 for (unsigned int i = 0; i < _dx.size(); ++i)
284 for (unsigned int ii = 0; ii < _ix[i]; ++ii)
285 new_id.push_back(_subdomain_id[k * _dx.size() * _dy.size() + j * _dx.size() + i]);
286
287 _subdomain_id = new_id;
288
289 if (!isParamValid("dy"))
290 mooseError("dy is not provided for 3D");
291 if (!isParamValid("dz"))
292 mooseError("dz is not provided for 3D");
293 break;
294 }
295 }
296}
297
298std::unique_ptr<MeshBase>
300{
301 auto mesh = buildMeshBaseObject();
302
303 // switching on MooseEnum to generate the reference mesh
304 // Note: element type is fixed
305 switch (_dim)
306 {
307 case 1:
308 MeshTools::Generation::build_line(static_cast<UnstructuredMesh &>(*mesh), _nx, 0, _nx, EDGE2);
309 break;
310 case 2:
311 MeshTools::Generation::build_square(
312 static_cast<UnstructuredMesh &>(*mesh), _nx, _ny, 0, _nx, 0, _ny, QUAD4);
313 break;
314 case 3:
315 MeshTools::Generation::build_cube(
316 static_cast<UnstructuredMesh &>(*mesh), _nx, _ny, _nz, 0, _nx, 0, _ny, 0, _nz, HEX8);
317 break;
318 }
319
320 // assign block IDs
321 MeshBase::element_iterator el = mesh->active_elements_begin();
322 MeshBase::element_iterator el_end = mesh->active_elements_end();
323 for (; el != el_end; ++el)
324 {
325 const Point p = (*el)->vertex_average();
326 unsigned int ix = std::floor(p(0));
327 unsigned int iy = std::floor(p(1));
328 unsigned int iz = std::floor(p(2));
329 unsigned int i = iz * _nx * _ny + iy * _nx + ix;
330 (*el)->subdomain_id() = _subdomain_id[i];
331 }
332
333 // adjust node coordinates
334 switch (_dim)
335 {
336 case 1:
337 {
338 Real base;
339
340 std::vector<Real> mapx;
341 // Note: the starting coordinate is zero
342 base = 0;
343 mapx.push_back(base);
344 for (unsigned int i = 0; i < _dx.size(); ++i)
345 {
346 for (unsigned int j = 1; j <= _ix[i]; ++j)
347 mapx.push_back(base + _dx[i] / _ix[i] * j);
348 base += _dx[i];
349 }
350
351 MeshBase::node_iterator node = mesh->active_nodes_begin();
352 MeshBase::node_iterator node_end = mesh->active_nodes_end();
353 for (; node != node_end; ++node)
354 {
355 unsigned int i = (*(*node))(0) + 0.5;
356 (*(*node))(0) = mapx.at(i);
357 }
358 break;
359 }
360 case 2:
361 {
362 Real base;
363
364 std::vector<Real> mapx;
365 base = 0;
366 mapx.push_back(base);
367 for (unsigned int i = 0; i < _dx.size(); ++i)
368 {
369 for (unsigned int j = 1; j <= _ix[i]; ++j)
370 mapx.push_back(base + _dx[i] / _ix[i] * j);
371 base += _dx[i];
372 }
373
374 std::vector<Real> mapy;
375 base = 0;
376 mapy.push_back(base);
377 for (unsigned int i = 0; i < _dy.size(); ++i)
378 {
379 for (unsigned int j = 1; j <= _iy[i]; ++j)
380 mapy.push_back(base + _dy[i] / _iy[i] * j);
381 base += _dy[i];
382 }
383
384 MeshBase::node_iterator node = mesh->active_nodes_begin();
385 MeshBase::node_iterator node_end = mesh->active_nodes_end();
386 for (; node != node_end; ++node)
387 {
388 unsigned int i = (*(*node))(0) + 0.5;
389 (*(*node))(0) = mapx.at(i);
390 unsigned int j = (*(*node))(1) + 0.5;
391 (*(*node))(1) = mapy.at(j);
392 }
393 break;
394 }
395 case 3:
396 {
397 Real base;
398
399 std::vector<Real> mapx;
400 base = 0;
401 mapx.push_back(base);
402 for (unsigned int i = 0; i < _dx.size(); ++i)
403 {
404 for (unsigned int j = 1; j <= _ix[i]; ++j)
405 mapx.push_back(base + _dx[i] / _ix[i] * j);
406 base += _dx[i];
407 }
408
409 std::vector<Real> mapy;
410 base = 0;
411 mapy.push_back(base);
412 for (unsigned int i = 0; i < _dy.size(); ++i)
413 {
414 for (unsigned int j = 1; j <= _iy[i]; ++j)
415 mapy.push_back(base + _dy[i] / _iy[i] * j);
416 base += _dy[i];
417 }
418
419 std::vector<Real> mapz;
420 base = 0;
421 mapz.push_back(base);
422 for (unsigned int i = 0; i < _dz.size(); ++i)
423 {
424 for (unsigned int j = 1; j <= _iz[i]; ++j)
425 mapz.push_back(base + _dz[i] / _iz[i] * j);
426 base += _dz[i];
427 }
428
429 MeshBase::node_iterator node = mesh->active_nodes_begin();
430 MeshBase::node_iterator node_end = mesh->active_nodes_end();
431 for (; node != node_end; ++node)
432 {
433 unsigned int i = (*(*node))(0) + 0.5;
434 (*(*node))(0) = mapx.at(i);
435 unsigned int j = (*(*node))(1) + 0.5;
436 (*(*node))(1) = mapy.at(j);
437 unsigned int k = (*(*node))(2) + 0.5;
438 (*(*node))(2) = mapz.at(k);
439 }
440 break;
441 }
442 }
443
444 mesh->prepare_for_use();
445 return dynamic_pointer_cast<MeshBase>(mesh);
446}
registerMooseObject("MooseApp", CartesianMeshGenerator)
std::vector< Real > _dy
Intervals in y direction.
std::vector< unsigned int > _iy
Number of grids in all intervals in y direction.
std::vector< unsigned int > _ix
Number of grids in all intervals in x direction.
static InputParameters validParams()
std::vector< unsigned int > _subdomain_id
Block IDs.
int _nx
Number of elements in x, y, z direction.
std::vector< Real > _dz
Intervals in z direction.
std::vector< unsigned int > _iz
Number of grids in all intervals in z direction.
std::vector< Real > _dx
Intervals in x direction.
CartesianMeshGenerator(const InputParameters &parameters)
std::unique_ptr< MeshBase > generate() override
Generate / modify the mesh.
MooseEnum _dim
The dimension of the mesh.
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 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...
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.
MeshGenerators are objects that can modify or add to an existing mesh.
static InputParameters validParams()
std::unique_ptr< MeshBase > buildMeshBaseObject(unsigned int dim=libMesh::invalid_uint)
Build a MeshBase object whose underlying type will be determined by the Mesh input file block.
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 ...
Definition MooseBase.h:457
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
void mooseWarning(Args &&... args) const
void paramWarning(const std::string &param, Args... args) const
MeshBase & mesh
std::string stringify(const T &t)
conversion to string
Definition Conversion.h:64