14 #include "libmesh/mesh_generation.h" 15 #include "libmesh/unstructured_mesh.h" 16 #include "libmesh/point.h" 17 #include "libmesh/elem.h" 18 #include "libmesh/node.h" 19 #include "libmesh/boundary_info.h" 20 #include "libmesh/face_quad4.h" 21 #include "libmesh/face_quad8.h" 22 #include "libmesh/cell_hex8.h" 23 #include "libmesh/cell_hex20.h" 24 #include "libmesh/utility.h" 39 "The dimension of the mesh to be generated. Patch meshes are only " 40 "valid in 2 or 3 dimensions.");
45 "The type of element from libMesh to " 46 "generate (default: linear element for " 47 "requested dimension)");
48 params.
addParam<
Real>(
"x_length", 0.24,
"Length of the domain in the x direction.");
49 params.
addParam<
Real>(
"y_length", 0.12,
"Length of the domain in the y direction.");
50 params.
addParam<
Real>(
"z_length", 0.0,
"Length of the domain in the z direction.");
51 params.
addParam<
Real>(
"x_offset", 0.0,
"Offset of the Cartesian origin in the x direction.");
52 params.
addParam<
Real>(
"y_offset", 0.0,
"Offset of the Cartesian origin in the y direction.");
53 params.
addParam<
Real>(
"z_offset", 0.0,
"Offset of the Cartesian origin in the z direction.");
61 _elem_type(getParam<
MooseEnum>(
"elem_type")),
62 _xlength(getParam<
Real>(
"x_length")),
63 _ylength(getParam<
Real>(
"y_length")),
64 _zlength(getParam<
Real>(
"z_length")),
65 _xoffset(getParam<
Real>(
"x_offset")),
66 _yoffset(getParam<
Real>(
"y_offset")),
67 _zoffset(getParam<
Real>(
"z_offset"))
70 paramError(
"x_length",
"Must be greater than zero");
73 paramError(
"y_length",
"Must be greater than zero");
76 paramError(
"elem_type",
"Must be QUAD4 or QUAD8 for 2-dimensional meshes.");
79 paramError(
"z_length",
"Must be zero for 2-dimensional meshes");
85 paramError(
"elem_type",
"Must be HEX8 or HEX20 for 3-dimensional meshes.");
100 paramError(
"z_length",
"Must be greater than zero for 3-dimensional meshes");
103 std::unique_ptr<MeshBase>
107 BoundaryInfo & boundary_info =
mesh->get_boundary_info();
109 unsigned num_nodes = 0;
119 std::vector<Node *> nodes(num_nodes);
127 const std::vector<Real> x_interior_fractions{1.0 / 6.0, 3.0 / 4.0, 2.0 / 3.0, 1.0 / 3.0};
128 const std::vector<Real> y_interior_fractions{1.0 / 6.0, 1.0 / 4.0, 2.0 / 3.0, 2.0 / 3.0};
136 for (
unsigned i = 0; i < x_interior_fractions.size(); ++i)
137 node_positions.push_back({_xoffset + x_interior_fractions[i] * _xlength,
138 _yoffset + y_interior_fractions[i] * _ylength,
144 for (
unsigned i = 0; i < 4; ++i)
145 node_positions.push_back(0.5 * (node_positions[i] + node_positions[(i + 1) % 4]));
148 for (
unsigned i = 0; i < 4; ++i)
149 node_positions.push_back(0.5 * (node_positions[i] + node_positions[i + 4]));
152 for (
unsigned i = 4; i < 8; ++i)
153 node_positions.push_back(0.5 * (node_positions[i] + node_positions[(i + 1) % 4 + 4]));
156 for (
unsigned node_id = 0; node_id < num_nodes; ++node_id)
157 nodes[node_id] =
mesh->add_point(node_positions[node_id], node_id);
164 boundary_info.sideset_name(1) =
"bottom";
165 boundary_info.sideset_name(2) =
"right";
166 boundary_info.sideset_name(3) =
"top";
167 boundary_info.sideset_name(4) =
"left";
169 boundary_info.nodeset_name(100) =
"bottom_left";
170 boundary_info.nodeset_name(101) =
"bottom_right";
171 boundary_info.nodeset_name(102) =
"top_right";
172 boundary_info.nodeset_name(103) =
"top_left";
176 const std::vector<Real> x_interior_fractions{
177 0.249, 0.826, 0.850, 0.273, 0.320, 0.677, 0.788, 0.165};
178 const std::vector<Real> y_interior_fractions{
179 0.342, 0.288, 0.649, 0.750, 0.186, 0.305, 0.693, 0.745};
180 const std::vector<Real> z_interior_fractions{
181 0.192, 0.288, 0.263, 0.230, 0.643, 0.683, 0.644, 0.702};
194 for (
unsigned i = 0; i < x_interior_fractions.size(); ++i)
195 node_positions.push_back({_xoffset + x_interior_fractions[i] * _xlength,
196 _yoffset + y_interior_fractions[i] * _ylength,
197 _zoffset + z_interior_fractions[i] * _zlength});
204 for (
unsigned i = 0; i < 4; ++i)
205 node_positions.push_back(0.5 * (node_positions[i] + node_positions[(i + 1) % 4]));
208 for (
unsigned i = 4; i < 8; ++i)
209 node_positions.push_back(0.5 * (node_positions[i] + node_positions[(i + 1) % 4 + 4]));
212 for (
unsigned i = 0; i < 4; ++i)
213 node_positions.push_back(0.5 * (node_positions[i] + node_positions[i + 4]));
216 for (
unsigned i = 8; i < 12; ++i)
217 node_positions.push_back(0.5 * (node_positions[i] + node_positions[(i + 1) % 4 + 8]));
220 for (
unsigned i = 12; i < 16; ++i)
221 node_positions.push_back(0.5 * (node_positions[i] + node_positions[(i + 1) % 4 + 12]));
224 for (
unsigned i = 8; i < 12; ++i)
225 node_positions.push_back(0.5 * (node_positions[i] + node_positions[i + 4]));
228 for (
unsigned i = 0; i < 8; ++i)
229 node_positions.push_back(0.5 * (node_positions[i] + node_positions[i + 8]));
232 for (
unsigned node_id = 0; node_id < num_nodes; ++node_id)
233 nodes[node_id] =
mesh->add_point(node_positions[node_id], node_id);
240 boundary_info.sideset_name(1) =
"front";
241 boundary_info.sideset_name(2) =
"bottom";
242 boundary_info.sideset_name(3) =
"left";
243 boundary_info.sideset_name(4) =
"right";
244 boundary_info.sideset_name(5) =
"top";
245 boundary_info.sideset_name(6) =
"back";
247 boundary_info.nodeset_name(100) =
"bottom_back_left";
248 boundary_info.nodeset_name(101) =
"bottom_back_right";
249 boundary_info.nodeset_name(102) =
"top_back_right";
250 boundary_info.nodeset_name(103) =
"top_back_left";
251 boundary_info.nodeset_name(104) =
"bottom_front_left";
252 boundary_info.nodeset_name(105) =
"bottom_front_right";
253 boundary_info.nodeset_name(106) =
"top_front_right";
254 boundary_info.nodeset_name(107) =
"top_front_left";
257 mesh->prepare_for_use();
265 BoundaryInfo & boundary_info =
mesh.get_boundary_info();
266 std::vector<std::vector<int>> element_connectivity{
267 {0, 1, 5, 4}, {1, 2, 6, 5}, {2, 3, 7, 6}, {3, 0, 4, 7}, {4, 5, 6, 7}};
268 for (
unsigned i = 0; i < 5; ++i)
270 Elem * elem =
mesh.add_elem(
new Quad4);
271 for (
unsigned j = 0; j < 4; ++j)
272 elem->set_node(j, nodes[element_connectivity[i][j]]);
274 elem->subdomain_id() = i + 1;
278 boundary_info.add_node(i, i + 100);
279 boundary_info.add_side(elem, 0, i + 1);
287 BoundaryInfo & boundary_info =
mesh.get_boundary_info();
288 std::vector<std::vector<int>> element_connectivity{{0, 1, 5, 4, 8, 13, 16, 12},
289 {1, 2, 6, 5, 9, 14, 17, 13},
290 {2, 3, 7, 6, 10, 15, 18, 14},
291 {3, 0, 4, 7, 11, 12, 19, 15},
292 {4, 5, 6, 7, 16, 17, 18, 19}};
293 for (
unsigned i = 0; i < 5; ++i)
295 Elem * elem =
mesh.add_elem(
new Quad8);
296 for (
unsigned j = 0; j < 8; ++j)
297 elem->set_node(j, nodes[element_connectivity[i][j]]);
299 elem->subdomain_id() = i + 1;
303 boundary_info.add_node(i, i + 100);
304 boundary_info.add_side(elem, 0, i + 1);
312 BoundaryInfo & boundary_info =
mesh.get_boundary_info();
313 std::vector<std::vector<int>> element_connectivity{{12, 13, 14, 15, 4, 5, 6, 7},
314 {8, 9, 13, 12, 0, 1, 5, 4},
315 {8, 12, 15, 11, 0, 4, 7, 3},
316 {9, 10, 14, 13, 1, 2, 6, 5},
317 {10, 11, 15, 14, 2, 3, 7, 6},
318 {8, 11, 10, 9, 0, 3, 2, 1},
319 {8, 9, 10, 11, 12, 13, 14, 15}};
321 for (
unsigned i = 0; i < 7; ++i)
323 Elem * elem =
mesh.add_elem(
new Hex8);
324 for (
unsigned j = 0; j < 8; ++j)
325 elem->set_node(j, nodes[element_connectivity[i][j]]);
327 elem->subdomain_id() = i + 1;
329 boundary_info.add_side(elem, 5, i + 1);
331 for (
unsigned i = 0; i < 8; ++i)
332 boundary_info.add_node(i, i + 100);
338 BoundaryInfo & boundary_info =
mesh.get_boundary_info();
339 std::vector<std::vector<int>> element_connectivity{
340 {12, 13, 14, 15, 4, 5, 6, 7, 32, 33, 34, 35, 44, 45, 46, 47, 20, 21, 22, 23},
341 {8, 9, 13, 12, 0, 1, 5, 4, 28, 37, 32, 36, 40, 41, 45, 44, 16, 25, 20, 24},
342 {8, 12, 15, 11, 0, 4, 7, 3, 36, 35, 39, 31, 40, 44, 47, 43, 24, 23, 27, 19},
343 {9, 10, 14, 13, 1, 2, 6, 5, 29, 38, 33, 37, 41, 42, 46, 45, 17, 26, 21, 25},
344 {10, 11, 15, 14, 2, 3, 7, 6, 30, 39, 34, 38, 42, 43, 47, 46, 18, 27, 22, 26},
345 {8, 11, 10, 9, 0, 3, 2, 1, 31, 30, 29, 28, 40, 43, 42, 41, 19, 18, 17, 16},
346 {8, 9, 10, 11, 12, 13, 14, 15, 28, 29, 30, 31, 36, 37, 38, 39, 32, 33, 34, 35}};
348 for (
unsigned i = 0; i < 7; ++i)
350 Elem * elem =
mesh.add_elem(
new Hex20);
351 for (
unsigned j = 0; j < 20; ++j)
352 elem->set_node(j, nodes[element_connectivity[i][j]]);
354 elem->subdomain_id() = i + 1;
356 boundary_info.add_side(elem, 5, i + 1);
358 for (
unsigned i = 0; i < 8; ++i)
359 boundary_info.add_node(i, i + 100);
const Real _xoffset
Offsets in the x, y, and z directions of the origin node (default location: (0,0,0)) ...
std::unique_ptr< MeshBase > generate() override
Generate / modify the mesh.
void makeQuad8Elems(MeshBase &mesh, const std::vector< Node *> &nodes)
registerMooseObject("MooseApp", ExamplePatchMeshGenerator)
std::unique_ptr< T_DEST, T_DELETER > dynamic_pointer_cast(std::unique_ptr< T_SRC, T_DELETER > &src)
These are reworked from https://stackoverflow.com/a/11003103.
void makeQuad4Elems(MeshBase &mesh, const std::vector< Node *> &nodes)
MooseEnum _elem_type
The element type used.
MooseEnum _dim
The dimension of the mesh.
registerMooseObjectRenamed("MooseApp", PatchMeshGenerator, "06/30/2025 24:00", ExamplePatchMeshGenerator)
Real _xlength
Edge length of the domain in the x, y, and z directions.
void makeHex20Elems(MeshBase &mesh, const std::vector< Node *> &nodes)
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
void paramError(const std::string ¶m, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
static InputParameters validParams()
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
static InputParameters validParams()
const InputParameters & parameters() const
Get the parameters of the object.
ExamplePatchMeshGenerator(const InputParameters ¶meters)
void makeHex8Elems(MeshBase &mesh, const std::vector< Node *> &nodes)
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...
MeshGenerators are objects that can modify or add to an existing mesh.