OGS
MeshGenerator.cpp
Go to the documentation of this file.
1
11#include "MeshGenerator.h"
12
13#include <memory>
14#include <numeric>
15
22#include "MeshLib/Node.h"
25
26namespace MeshToolsLib
27{
28std::vector<MeshLib::Node*> MeshGenerator::generateRegularNodes(
29 const std::vector<const std::vector<double>*>& vec_xyz_coords,
30 const MathLib::Point3d& origin)
31{
32 auto const shift_coordinates =
33 [](auto const& in, auto& out, auto const& shift)
34 {
35 std::transform(in.begin(), in.end(), std::back_inserter(out),
36 [&shift](auto const& v) { return v + shift; });
37 };
38 std::array<std::vector<double>, 3> coords;
39 for (std::size_t i = 0; i < 3; ++i)
40 {
41 coords[i].reserve(vec_xyz_coords[i]->size());
42 shift_coordinates(*vec_xyz_coords[i], coords[i], origin[i]);
43 }
44
45 std::vector<MeshLib::Node*> nodes;
46 nodes.reserve(coords[0].size() * coords[1].size() * coords[2].size());
47
48 for (auto const z : coords[2])
49 {
50 for (auto const y : coords[1])
51 {
52 std::transform(coords[0].begin(), coords[0].end(),
53 std::back_inserter(nodes),
54 [&y, &z](double const& x)
55 { return new MeshLib::Node(x, y, z); });
56 }
57 }
58 return nodes;
59}
60
61std::vector<MeshLib::Node*> MeshGenerator::generateRegularNodes(
62 const std::vector<double>& vec_x_coords, const MathLib::Point3d& origin)
63{
64 std::vector<const std::vector<double>*> vec_xyz_coords;
65 vec_xyz_coords.push_back(&vec_x_coords);
66 std::vector<double> dummy(1, 0.0);
67 for (unsigned i = vec_xyz_coords.size() - 1; i < 3u; i++)
68 {
69 vec_xyz_coords.push_back(&dummy);
70 }
71 return generateRegularNodes(vec_xyz_coords, origin);
72}
73
74std::vector<MeshLib::Node*> MeshGenerator::generateRegularNodes(
75 std::vector<double>& vec_x_coords,
76 std::vector<double>& vec_y_coords,
77 const MathLib::Point3d& origin)
78{
79 std::vector<const std::vector<double>*> vec_xyz_coords;
80 vec_xyz_coords.push_back(&vec_x_coords);
81 vec_xyz_coords.push_back(&vec_y_coords);
82 std::vector<double> dummy(1, 0.0);
83 for (unsigned i = vec_xyz_coords.size() - 1; i < 3u; i++)
84 {
85 vec_xyz_coords.push_back(&dummy);
86 }
87 return generateRegularNodes(vec_xyz_coords, origin);
88}
89
90std::vector<MeshLib::Node*> MeshGenerator::generateRegularNodes(
91 std::vector<double>& vec_x_coords,
92 std::vector<double>& vec_y_coords,
93 std::vector<double>& vec_z_coords,
94 const MathLib::Point3d& origin)
95{
96 std::vector<const std::vector<double>*> vec_xyz_coords;
97 vec_xyz_coords.push_back(&vec_x_coords);
98 vec_xyz_coords.push_back(&vec_y_coords);
99 vec_xyz_coords.push_back(&vec_z_coords);
100 return generateRegularNodes(vec_xyz_coords, origin);
101}
102
103std::vector<MeshLib::Node*> MeshGenerator::generateRegularNodes(
104 const std::array<unsigned, 3>& n_cells,
105 const std::array<double, 3>& cell_size,
106 const MathLib::Point3d& origin)
107{
108 std::vector<MeshLib::Node*> nodes;
109 nodes.reserve((n_cells[0] + 1) * (n_cells[1] + 1) * (n_cells[2] + 1));
110
111 for (std::size_t i = 0; i < n_cells[2] + 1; i++)
112 {
113 const double z(origin[2] + cell_size[2] * i);
114 for (std::size_t j = 0; j < n_cells[1] + 1; j++)
115 {
116 const double y(origin[1] + cell_size[1] * j);
117 for (std::size_t k = 0; k < n_cells[0] + 1; k++)
118 {
119 nodes.push_back(
120 new MeshLib::Node(origin[0] + cell_size[0] * k, y, z));
121 }
122 }
123 }
124 return nodes;
125}
126
127namespace MeshGenerator
128{
129std::vector<MeshLib::Node*> generateRegularPyramidTopNodes(
130 std::vector<double> const& x_coords,
131 std::vector<double> const& y_coords,
132 std::vector<double> const& z_coords,
133 const MathLib::Point3d& origin)
134{
135 std::vector<MeshLib::Node*> nodes;
136 nodes.reserve((x_coords.size() - 1) * (y_coords.size() - 1) *
137 (z_coords.size() - 1));
138
139 auto const n_x_coords = x_coords.size() - 1;
140 auto const n_y_coords = y_coords.size() - 1;
141 auto const n_z_coords = z_coords.size() - 1;
142
143 for (std::size_t i = 0; i < n_z_coords; i++)
144 {
145 const double z((z_coords[i] + z_coords[i + 1]) / 2 + origin[2]);
146 for (std::size_t j = 0; j < n_y_coords; j++)
147 {
148 const double y((y_coords[j] + y_coords[j + 1]) / 2 + origin[1]);
149 for (std::size_t k = 0; k < n_x_coords; k++)
150 {
151 const double x((x_coords[k] + x_coords[k + 1]) / 2 + origin[0]);
152 nodes.push_back(new MeshLib::Node(x, y, z));
153 }
154 }
155 }
156 return nodes;
157}
158} // end namespace MeshGenerator
159
161 const std::size_t subdivision,
162 const MathLib::Point3d& origin,
163 std::string const& mesh_name)
164{
165 return generateLineMesh(subdivision, length / subdivision, origin,
166 mesh_name);
167}
168
170 const double cell_size,
171 MathLib::Point3d const& origin,
172 std::string const& mesh_name)
173{
174 return generateLineMesh(
175 BaseLib::UniformSubdivision(n_cells * cell_size, n_cells), origin,
176 mesh_name);
177}
178
180 MathLib::Point3d const& origin,
181 std::string const& mesh_name)
182{
183 const std::vector<double> vec_x(div());
184 std::vector<MeshLib::Node*> nodes(generateRegularNodes(vec_x, origin));
185
186 // elements
187 const std::size_t n_cells = nodes.size() - 1;
188 std::vector<MeshLib::Element*> elements;
189 elements.reserve(n_cells);
190
191 for (std::size_t i = 0; i < n_cells; i++)
192 {
193 elements.push_back(new MeshLib::Line({nodes[i], nodes[i + 1]}));
194 }
195
196 return new MeshLib::Mesh(mesh_name, nodes, elements,
197 true /* compute_element_neighbors */);
198}
199
201 const double length,
202 const std::size_t subdivision,
203 const MathLib::Point3d& origin,
204 std::string const& mesh_name)
205{
206 return generateRegularQuadMesh(subdivision, subdivision,
207 length / subdivision, length / subdivision,
208 origin, mesh_name);
209}
210
212 const double x_length,
213 const double y_length,
214 const std::size_t x_subdivision,
215 const std::size_t y_subdivision,
216 const MathLib::Point3d& origin,
217 std::string const& mesh_name)
218{
219 return generateRegularQuadMesh(x_subdivision, y_subdivision,
220 x_length / x_subdivision,
221 y_length / y_subdivision, origin, mesh_name);
222}
223
225 const unsigned n_x_cells,
226 const unsigned n_y_cells,
227 const double cell_size,
228 MathLib::Point3d const& origin,
229 std::string const& mesh_name)
230{
231 return generateRegularQuadMesh(n_x_cells, n_y_cells, cell_size, cell_size,
232 origin, mesh_name);
233}
234
236 const unsigned n_x_cells,
237 const unsigned n_y_cells,
238 const double cell_size_x,
239 const double cell_size_y,
240 MathLib::Point3d const& origin,
241 std::string const& mesh_name)
242{
244 BaseLib::UniformSubdivision(n_x_cells * cell_size_x, n_x_cells),
245 BaseLib::UniformSubdivision(n_y_cells * cell_size_y, n_y_cells), origin,
246 mesh_name);
247}
248
250 const BaseLib::ISubdivision& div_x,
251 const BaseLib::ISubdivision& div_y,
252 MathLib::Point3d const& origin,
253 std::string const& mesh_name)
254{
255 std::vector<double> vec_x(div_x());
256 std::vector<double> vec_y(div_y());
257 std::vector<MeshLib::Node*> nodes(
258 generateRegularNodes(vec_x, vec_y, origin));
259 const unsigned n_x_nodes(vec_x.size());
260
261 // elements
262 std::vector<MeshLib::Element*> elements;
263 const unsigned n_x_cells(vec_x.size() - 1);
264 const unsigned n_y_cells(vec_y.size() - 1);
265 elements.reserve(n_x_cells * n_y_cells);
266
267 for (std::size_t j = 0; j < n_y_cells; j++)
268 {
269 const std::size_t offset_y1 = j * n_x_nodes;
270 const std::size_t offset_y2 = (j + 1) * n_x_nodes;
271 for (std::size_t k = 0; k < n_x_cells; k++)
272 {
273 elements.push_back(new MeshLib::Quad(
274 {nodes[offset_y1 + k], nodes[offset_y1 + k + 1],
275 nodes[offset_y2 + k + 1], nodes[offset_y2 + k]}));
276 }
277 }
278
279 return new MeshLib::Mesh(mesh_name, nodes, elements,
280 true /* compute_element_neighbors */);
281}
282
284 const double length,
285 const std::size_t subdivision,
286 const MathLib::Point3d& origin,
287 std::string const& mesh_name)
288{
290 subdivision, subdivision, subdivision, length / subdivision, origin,
291 mesh_name);
292}
293
295 const double x_length,
296 const double y_length,
297 const double z_length,
298 const std::size_t x_subdivision,
299 const std::size_t y_subdivision,
300 const std::size_t z_subdivision,
301 const MathLib::Point3d& origin,
302 std::string const& mesh_name)
303{
305 x_subdivision, y_subdivision, z_subdivision, x_length / x_subdivision,
306 y_length / y_subdivision, z_length / z_subdivision, origin, mesh_name);
307}
308
310 const unsigned n_x_cells,
311 const unsigned n_y_cells,
312 const unsigned n_z_cells,
313 const double cell_size,
314 MathLib::Point3d const& origin,
315 std::string const& mesh_name)
316{
318 n_x_cells, n_y_cells, n_z_cells, cell_size, cell_size, cell_size,
319 origin, mesh_name);
320}
321
323 const unsigned n_x_cells,
324 const unsigned n_y_cells,
325 const unsigned n_z_cells,
326 const double cell_size_x,
327 const double cell_size_y,
328 const double cell_size_z,
329 MathLib::Point3d const& origin,
330 std::string const& mesh_name)
331{
333 BaseLib::UniformSubdivision(n_x_cells * cell_size_x, n_x_cells),
334 BaseLib::UniformSubdivision(n_y_cells * cell_size_y, n_y_cells),
335 BaseLib::UniformSubdivision(n_z_cells * cell_size_z, n_z_cells), origin,
336 mesh_name);
337}
338
340 const BaseLib::ISubdivision& div_x,
341 const BaseLib::ISubdivision& div_y,
342 const BaseLib::ISubdivision& div_z,
343 MathLib::Point3d const& origin,
344 std::string const& mesh_name)
345{
346 std::vector<double> vec_x(div_x());
347 std::vector<double> vec_y(div_y());
348 std::vector<double> vec_z(div_z());
349 std::vector<MeshLib::Node*> nodes(
350 generateRegularNodes(vec_x, vec_y, vec_z, origin));
351
352 const unsigned n_x_nodes(vec_x.size());
353 const unsigned n_y_nodes(vec_y.size());
354 const unsigned n_x_cells(vec_x.size() - 1);
355 const unsigned n_y_cells(vec_y.size() - 1);
356 const unsigned n_z_cells(vec_z.size() - 1);
357
358 // elements
359 std::vector<MeshLib::Element*> elements;
360 elements.reserve(n_x_cells * n_y_cells * n_z_cells);
361
362 for (std::size_t i = 0; i < n_z_cells; i++)
363 {
364 const std::size_t offset_z1 = i * n_x_nodes * n_y_nodes; // bottom
365 const std::size_t offset_z2 = (i + 1) * n_x_nodes * n_y_nodes; // top
366 for (std::size_t j = 0; j < n_y_cells; j++)
367 {
368 const std::size_t offset_y1 = j * n_x_nodes;
369 const std::size_t offset_y2 = (j + 1) * n_x_nodes;
370 for (std::size_t k = 0; k < n_x_cells; k++)
371 {
372 elements.push_back(
373 new MeshLib::Hex({// bottom
374 nodes[offset_z1 + offset_y1 + k],
375 nodes[offset_z1 + offset_y1 + k + 1],
376 nodes[offset_z1 + offset_y2 + k + 1],
377 nodes[offset_z1 + offset_y2 + k],
378 // top
379 nodes[offset_z2 + offset_y1 + k],
380 nodes[offset_z2 + offset_y1 + k + 1],
381 nodes[offset_z2 + offset_y2 + k + 1],
382 nodes[offset_z2 + offset_y2 + k]}));
383 }
384 }
385 }
386
387 return new MeshLib::Mesh(mesh_name, nodes, elements,
388 true /* compute_element_neighbors */);
389}
390
392 const BaseLib::ISubdivision& div_x,
393 const BaseLib::ISubdivision& div_y,
394 const BaseLib::ISubdivision& div_z,
395 MathLib::Point3d const& origin,
396 std::string const& mesh_name)
397{
398 std::vector<double> vec_x(div_x());
399 std::vector<double> vec_y(div_y());
400 std::vector<double> vec_z(div_z());
401 std::vector<MeshLib::Node*> nodes(
402 generateRegularNodes(vec_x, vec_y, vec_z, origin));
403 std::vector<MeshLib::Node*> const top_nodes(
404 generateRegularPyramidTopNodes(vec_x, vec_y, vec_z, origin));
405
406 nodes.insert(nodes.end(), top_nodes.begin(), top_nodes.end());
407
408 const unsigned n_x_nodes(vec_x.size());
409 const unsigned n_y_nodes(vec_y.size());
410 const unsigned n_z_nodes(vec_z.size());
411 const unsigned n_x_cells(vec_x.size() - 1);
412 const unsigned n_y_cells(vec_y.size() - 1);
413 const unsigned n_z_cells(vec_z.size() - 1);
414
415 // elements
416 std::vector<MeshLib::Element*> elements;
417 auto const top_node_offset(n_x_nodes * n_y_nodes * n_z_nodes);
418 elements.reserve(n_x_cells * n_y_cells * n_z_cells);
419
420 for (std::size_t i = 0; i < n_z_cells; i++)
421 {
422 const std::size_t offset_z1 = i * n_x_nodes * n_y_nodes; // bottom
423 const std::size_t offset_z2 = (i + 1) * n_x_nodes * n_y_nodes; // top
424 for (std::size_t j = 0; j < n_y_cells; j++)
425 {
426 const std::size_t offset_y1 = j * n_x_nodes;
427 const std::size_t offset_y2 = (j + 1) * n_x_nodes;
428 for (std::size_t k = 0; k < n_x_cells; k++)
429 {
430 // generate 6 pyramids within the virtual hexahedron cell
431 int const pyramid_top_index(i * n_x_cells * n_y_cells +
432 j * n_x_cells + k +
433 top_node_offset);
434 elements.push_back(
435 new MeshLib::Pyramid{{// bottom 'hexahedron' face
436 nodes[offset_z1 + offset_y1 + k],
437 nodes[offset_z1 + offset_y1 + k + 1],
438 nodes[offset_z1 + offset_y2 + k + 1],
439 nodes[offset_z1 + offset_y2 + k],
440 // top
441 nodes[pyramid_top_index]}});
442 elements.push_back(new MeshLib::Pyramid{
443 {// top 'hexahedron' face
444 nodes[offset_z2 + offset_y1 + k + 1],
445 nodes[offset_z2 + offset_y1 + k],
446 nodes[offset_z2 + offset_y2 + k],
447 nodes[offset_z2 + offset_y2 + k + 1],
448 // top of pyramid directed towards the bottom
449 nodes[pyramid_top_index]}});
450 elements.push_back(new MeshLib::Pyramid{
451 {// right 'hexahedron' face
452 nodes[offset_z1 + offset_y1 + k + 1],
453 nodes[offset_z2 + offset_y1 + k + 1],
454 nodes[offset_z2 + offset_y2 + k + 1],
455 nodes[offset_z1 + offset_y2 + k + 1],
456 // top of pyramid directed towards the bottom
457 nodes[pyramid_top_index]}});
458 elements.push_back(new MeshLib::Pyramid{
459 {// left 'hexahedron' face
460 nodes[offset_z2 + offset_y1 + k],
461 nodes[offset_z1 + offset_y1 + k],
462 nodes[offset_z1 + offset_y2 + k],
463 nodes[offset_z2 + offset_y2 + k],
464 // top of pyramid directed towards the bottom
465 nodes[pyramid_top_index]}});
466 elements.push_back(new MeshLib::Pyramid{
467 {// front 'hexahedron' face
468 nodes[offset_z2 + offset_y1 + k],
469 nodes[offset_z2 + offset_y1 + k + 1],
470 nodes[offset_z1 + offset_y1 + k + 1],
471 nodes[offset_z1 + offset_y1 + k],
472 // top of pyramid directed towards the bottom
473 nodes[pyramid_top_index]}});
474 elements.push_back(new MeshLib::Pyramid{
475 {// back 'hexahedron' face
476 nodes[offset_z1 + offset_y2 + k],
477 nodes[offset_z1 + offset_y2 + k + 1],
478 nodes[offset_z2 + offset_y2 + k + 1],
479 nodes[offset_z2 + offset_y2 + k],
480 // top of pyramid directed towards the bottom
481 nodes[pyramid_top_index]}});
482 }
483 }
484 }
485 return new MeshLib::Mesh(mesh_name, nodes, elements,
486 true /* compute_element_neighbors */);
487}
488
490 const double length,
491 const std::size_t subdivision,
492 const MathLib::Point3d& origin,
493 std::string const& mesh_name)
494{
495 return generateRegularTriMesh(subdivision, subdivision,
496 length / subdivision, origin, mesh_name);
497}
498
500 const double x_length,
501 const double y_length,
502 const std::size_t x_subdivision,
503 const std::size_t y_subdivision,
504 const MathLib::Point3d& origin,
505 std::string const& mesh_name)
506{
507 return generateRegularTriMesh(x_subdivision, y_subdivision,
508 x_length / x_subdivision,
509 y_length / y_subdivision, origin, mesh_name);
510}
511
513 const unsigned n_x_cells,
514 const unsigned n_y_cells,
515 const double cell_size,
516 MathLib::Point3d const& origin,
517 std::string const& mesh_name)
518{
519 return generateRegularTriMesh(n_x_cells, n_y_cells, cell_size, cell_size,
520 origin, mesh_name);
521}
522
524 const unsigned n_x_cells,
525 const unsigned n_y_cells,
526 const double cell_size_x,
527 const double cell_size_y,
528 MathLib::Point3d const& origin,
529 std::string const& mesh_name)
530{
532 BaseLib::UniformSubdivision(n_x_cells * cell_size_x, n_x_cells),
533 BaseLib::UniformSubdivision(n_y_cells * cell_size_y, n_y_cells), origin,
534 mesh_name);
535}
536
538 const BaseLib::ISubdivision& div_x,
539 const BaseLib::ISubdivision& div_y,
540 MathLib::Point3d const& origin,
541 std::string const& mesh_name)
542{
543 std::vector<double> vec_x(div_x());
544 std::vector<double> vec_y(div_y());
545 std::vector<MeshLib::Node*> nodes(
546 generateRegularNodes(vec_x, vec_y, origin));
547 const unsigned n_x_nodes(vec_x.size());
548 const unsigned n_x_cells(vec_x.size() - 1);
549 const unsigned n_y_cells(vec_y.size() - 1);
550
551 // elements
552 std::vector<MeshLib::Element*> elements;
553 elements.reserve(n_x_cells * n_y_cells * 2);
554
555 for (std::size_t j = 0; j < n_y_cells; j++)
556 {
557 const std::size_t offset_y1 = j * n_x_nodes;
558 const std::size_t offset_y2 = (j + 1) * n_x_nodes;
559 for (std::size_t k = 0; k < n_x_cells; k++)
560 {
561 elements.push_back(new MeshLib::Tri({nodes[offset_y1 + k],
562 nodes[offset_y2 + k + 1],
563 nodes[offset_y2 + k]}));
564
565 elements.push_back(new MeshLib::Tri({nodes[offset_y1 + k],
566 nodes[offset_y1 + k + 1],
567 nodes[offset_y2 + k + 1]}));
568 }
569 }
570
571 return new MeshLib::Mesh(mesh_name, nodes, elements,
572 true /* compute_element_neighbors */);
573}
574
576 const double x_length,
577 const double y_length,
578 const double z_length,
579 const std::size_t x_subdivision,
580 const std::size_t y_subdivision,
581 const std::size_t z_subdivision,
582 const MathLib::Point3d& origin,
583 std::string const& mesh_name)
584{
586 x_subdivision, y_subdivision, z_subdivision, x_length / x_subdivision,
587 y_length / y_subdivision, z_length / z_subdivision, origin, mesh_name);
588}
589
591 const unsigned n_x_cells,
592 const unsigned n_y_cells,
593 const unsigned n_z_cells,
594 const double cell_size,
595 MathLib::Point3d const& origin,
596 std::string const& mesh_name)
597{
598 return generateRegularPrismMesh(n_x_cells, n_y_cells, n_z_cells, cell_size,
599 cell_size, cell_size, origin, mesh_name);
600}
601
603 const unsigned n_x_cells,
604 const unsigned n_y_cells,
605 const unsigned n_z_cells,
606 const double cell_size_x,
607 const double cell_size_y,
608 const double cell_size_z,
609 MathLib::Point3d const& origin,
610 std::string const& mesh_name)
611{
612 std::unique_ptr<MeshLib::Mesh> mesh(generateRegularTriMesh(
613 n_x_cells, n_y_cells, cell_size_x, cell_size_y, origin, mesh_name));
614 std::size_t const n_tris(mesh->getNumberOfElements());
615 bool const copy_material_ids = false;
616 for (std::size_t i = 0; i < n_z_cells; ++i)
617 {
618 mesh.reset(MeshToolsLib::addLayerToMesh(*mesh, cell_size_z, mesh_name,
619 true, copy_material_ids,
620 std::nullopt));
621 }
622 std::vector<std::size_t> elem_ids(n_tris);
623 std::iota(elem_ids.begin(), elem_ids.end(), 0);
624 return MeshToolsLib::removeElements(*mesh, elem_ids, mesh_name);
625}
626
628 const double x_length,
629 const double y_length,
630 const double z_length,
631 const std::size_t x_subdivision,
632 const std::size_t y_subdivision,
633 const std::size_t z_subdivision,
634 const MathLib::Point3d& origin,
635 std::string const& mesh_name)
636{
638 x_subdivision, y_subdivision, z_subdivision, x_length / x_subdivision,
639 y_length / y_subdivision, z_length / z_subdivision, origin, mesh_name);
640}
641
643 const unsigned n_x_cells,
644 const unsigned n_y_cells,
645 const unsigned n_z_cells,
646 const double cell_size_x,
647 const double cell_size_y,
648 const double cell_size_z,
649 MathLib::Point3d const& origin,
650 std::string const& mesh_name)
651{
653 BaseLib::UniformSubdivision(n_x_cells * cell_size_x, n_x_cells),
654 BaseLib::UniformSubdivision(n_y_cells * cell_size_y, n_y_cells),
655 BaseLib::UniformSubdivision(n_z_cells * cell_size_z, n_z_cells), origin,
656 mesh_name);
657}
658
660 const BaseLib::ISubdivision& div_x,
661 const BaseLib::ISubdivision& div_y,
662 const BaseLib::ISubdivision& div_z,
663 MathLib::Point3d const& origin,
664 std::string const& mesh_name)
665{
666 std::vector<double> vec_x(div_x());
667 std::vector<double> vec_y(div_y());
668 std::vector<double> vec_z(div_z());
669 std::vector<MeshLib::Node*> nodes(
670 generateRegularNodes(vec_x, vec_y, vec_z, origin));
671
672 const unsigned n_x_nodes(vec_x.size());
673 const unsigned n_y_nodes(vec_y.size());
674 const unsigned n_x_cells(vec_x.size() - 1);
675 const unsigned n_y_cells(vec_y.size() - 1);
676 const unsigned n_z_cells(vec_z.size() - 1);
677
678 // elements
679 std::vector<MeshLib::Element*> elements;
680 elements.reserve(n_x_cells * n_y_cells * n_z_cells * 6);
681
682 for (std::size_t i = 0; i < n_z_cells; i++)
683 {
684 const std::size_t offset_z1 = i * n_x_nodes * n_y_nodes; // bottom
685 const std::size_t offset_z2 = (i + 1) * n_x_nodes * n_y_nodes; // top
686 for (std::size_t j = 0; j < n_y_cells; j++)
687 {
688 const std::size_t offset_y1 = j * n_x_nodes;
689 const std::size_t offset_y2 = (j + 1) * n_x_nodes;
690 for (std::size_t k = 0; k < n_x_cells; k++)
691 {
692 // tet 1
693 elements.push_back(
694 new MeshLib::Tet({// bottom
695 nodes[offset_z1 + offset_y1 + k],
696 nodes[offset_z1 + offset_y2 + k + 1],
697 nodes[offset_z1 + offset_y2 + k],
698 // top
699 nodes[offset_z2 + offset_y1 + k]}));
700 // tet 2
701 elements.push_back(
702 new MeshLib::Tet({// bottom
703 nodes[offset_z1 + offset_y2 + k + 1],
704 nodes[offset_z1 + offset_y2 + k],
705 // top
706 nodes[offset_z2 + offset_y1 + k],
707 nodes[offset_z2 + offset_y2 + k + 1]}));
708 // tet 3
709 elements.push_back(
710 new MeshLib::Tet({// bottom
711 nodes[offset_z1 + offset_y2 + k],
712 // top
713 nodes[offset_z2 + offset_y1 + k],
714 nodes[offset_z2 + offset_y2 + k + 1],
715 nodes[offset_z2 + offset_y2 + k]}));
716 // tet 4
717 elements.push_back(
718 new MeshLib::Tet({// bottom
719 nodes[offset_z1 + offset_y1 + k],
720 nodes[offset_z1 + offset_y1 + k + 1],
721 nodes[offset_z1 + offset_y2 + k + 1],
722 // top
723 nodes[offset_z2 + offset_y1 + k + 1]}));
724 // tet 5
725 elements.push_back(
726 new MeshLib::Tet({// bottom
727 nodes[offset_z1 + offset_y1 + k],
728 nodes[offset_z1 + offset_y2 + k + 1],
729 // top
730 nodes[offset_z2 + offset_y1 + k],
731 nodes[offset_z2 + offset_y1 + k + 1]}));
732 // tet 6
733 elements.push_back(
734 new MeshLib::Tet({// bottom
735 nodes[offset_z1 + offset_y2 + k + 1],
736 // top
737 nodes[offset_z2 + offset_y1 + k],
738 nodes[offset_z2 + offset_y1 + k + 1],
739 nodes[offset_z2 + offset_y2 + k + 1]}));
740 }
741 }
742 }
743
744 return new MeshLib::Mesh(mesh_name, nodes, elements,
745 true /* compute_element_neighbors */);
746}
747
749 std::string const& mesh_name, MathLib::Point3d const& ll,
750 MathLib::Point3d const& ur, std::array<std::size_t, 2> const& n_steps,
751 const std::function<double(double, double)>& f)
752{
753 std::array<double, 2> const step_size{{(ur[0] - ll[0]) / (n_steps[0] - 1),
754 (ur[1] - ll[1]) / (n_steps[1] - 1)}};
755
756 std::vector<MeshLib::Node*> nodes;
757 for (std::size_t j(0); j < n_steps[1]; ++j)
758 {
759 for (std::size_t i(0); i < n_steps[0]; ++i)
760 {
761 std::size_t const id = i + j * n_steps[1];
762 double const x = ll[0] + i * step_size[0];
763 double const y = ll[1] + j * step_size[1];
764
765 nodes.push_back(new MeshLib::Node({x, y, f(x, y)}, id));
766 }
767 }
768
769 std::vector<MeshLib::Element*> sfc_eles;
770 for (std::size_t j(0); j < n_steps[1] - 1; ++j)
771 {
772 for (std::size_t i(0); i < n_steps[0] - 1; ++i)
773 {
774 std::size_t id_ll(i + j * n_steps[0]);
775 std::size_t id_lr(i + 1 + j * n_steps[0]);
776 std::size_t id_ul(i + (j + 1) * n_steps[0]);
777 std::size_t id_ur(i + 1 + (j + 1) * n_steps[0]);
778 sfc_eles.push_back(
779 new MeshLib::Tri({nodes[id_ll], nodes[id_lr], nodes[id_ur]}));
780 sfc_eles.push_back(
781 new MeshLib::Tri({nodes[id_ll], nodes[id_ur], nodes[id_ul]}));
782 }
783 }
784
785 return new MeshLib::Mesh(mesh_name, nodes, sfc_eles,
786 true /* compute_element_neighbors */);
787}
788
789} // namespace MeshToolsLib
Definition of AddLayerToMesh class.
Definition of the Hex class.
Definition of the Line class.
Definition of the Node class.
Definition of the Pyramid class.
Definition of the Quad class.
Definition of the Tet class.
Definition of the Tri class.
MeshLib::Mesh * generateLineMesh(const BaseLib::ISubdivision &div, MathLib::Point3d const &origin=MathLib::ORIGIN, std::string const &mesh_name="mesh")
MeshLib::Mesh * generateRegularPyramidMesh(const BaseLib::ISubdivision &div_x, const BaseLib::ISubdivision &div_y, const BaseLib::ISubdivision &div_z, MathLib::Point3d const &origin=MathLib::ORIGIN, std::string const &mesh_name="mesh")
MeshLib::Mesh * generateRegularTetMesh(const BaseLib::ISubdivision &div_x, const BaseLib::ISubdivision &div_y, const BaseLib::ISubdivision &div_z, MathLib::Point3d const &origin=MathLib::ORIGIN, std::string const &mesh_name="mesh")
MeshLib::Mesh * generateRegularQuadMesh(const BaseLib::ISubdivision &div_x, const BaseLib::ISubdivision &div_y, MathLib::Point3d const &origin=MathLib::ORIGIN, std::string const &mesh_name="mesh")
MeshLib::Mesh * generateRegularPrismMesh(const double x_length, const double y_length, const double z_length, const std::size_t x_subdivision, const std::size_t y_subdivision, const std::size_t z_subdivision, MathLib::Point3d const &origin=MathLib::ORIGIN, std::string const &mesh_name="mesh")
std::vector< MeshLib::Node * > generateRegularNodes(const std::vector< const std::vector< double > * > &vec_xyz_coords, const MathLib::Point3d &origin=MathLib::ORIGIN)
MeshLib::Mesh * createSurfaceMesh(std::string const &mesh_name, MathLib::Point3d const &ll, MathLib::Point3d const &ur, std::array< std::size_t, 2 > const &n_steps, const std::function< double(double, double)> &f)
MeshLib::Mesh * generateRegularTriMesh(const BaseLib::ISubdivision &div_x, const BaseLib::ISubdivision &div_y, MathLib::Point3d const &origin=MathLib::ORIGIN, std::string const &mesh_name="mesh")
std::vector< MeshLib::Node * > generateRegularPyramidTopNodes(std::vector< double > const &x_coords, std::vector< double > const &y_coords, std::vector< double > const &z_coords, const MathLib::Point3d &origin)
MeshLib::Mesh * generateRegularHexMesh(const BaseLib::ISubdivision &div_x, const BaseLib::ISubdivision &div_y, const BaseLib::ISubdivision &div_z, MathLib::Point3d const &origin=MathLib::ORIGIN, std::string const &mesh_name="mesh")
MeshLib::Mesh * addLayerToMesh(MeshLib::Mesh const &mesh, double const thickness, std::string const &name, bool const on_top, bool const copy_material_ids, std::optional< int > const layer_id)
MeshLib::Mesh * removeElements(const MeshLib::Mesh &mesh, const std::vector< std::size_t > &removed_element_ids, const std::string &new_mesh_name)