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}
198
200 const double length,
201 const std::size_t subdivision,
202 const MathLib::Point3d& origin,
203 std::string const& mesh_name)
204{
205 return generateRegularQuadMesh(subdivision, subdivision,
206 length / subdivision, length / subdivision,
207 origin, mesh_name);
208}
209
211 const double x_length,
212 const double y_length,
213 const std::size_t x_subdivision,
214 const std::size_t y_subdivision,
215 const MathLib::Point3d& origin,
216 std::string const& mesh_name)
217{
218 return generateRegularQuadMesh(x_subdivision, y_subdivision,
219 x_length / x_subdivision,
220 y_length / y_subdivision, origin, mesh_name);
221}
222
224 const unsigned n_x_cells,
225 const unsigned n_y_cells,
226 const double cell_size,
227 MathLib::Point3d const& origin,
228 std::string const& mesh_name)
229{
230 return generateRegularQuadMesh(n_x_cells, n_y_cells, cell_size, cell_size,
231 origin, mesh_name);
232}
233
235 const unsigned n_x_cells,
236 const unsigned n_y_cells,
237 const double cell_size_x,
238 const double cell_size_y,
239 MathLib::Point3d const& origin,
240 std::string const& mesh_name)
241{
243 BaseLib::UniformSubdivision(n_x_cells * cell_size_x, n_x_cells),
244 BaseLib::UniformSubdivision(n_y_cells * cell_size_y, n_y_cells), origin,
245 mesh_name);
246}
247
249 const BaseLib::ISubdivision& div_x,
250 const BaseLib::ISubdivision& div_y,
251 MathLib::Point3d const& origin,
252 std::string const& mesh_name)
253{
254 std::vector<double> vec_x(div_x());
255 std::vector<double> vec_y(div_y());
256 std::vector<MeshLib::Node*> nodes(
257 generateRegularNodes(vec_x, vec_y, origin));
258 const unsigned n_x_nodes(vec_x.size());
259
260 // elements
261 std::vector<MeshLib::Element*> elements;
262 const unsigned n_x_cells(vec_x.size() - 1);
263 const unsigned n_y_cells(vec_y.size() - 1);
264 elements.reserve(n_x_cells * n_y_cells);
265
266 for (std::size_t j = 0; j < n_y_cells; j++)
267 {
268 const std::size_t offset_y1 = j * n_x_nodes;
269 const std::size_t offset_y2 = (j + 1) * n_x_nodes;
270 for (std::size_t k = 0; k < n_x_cells; k++)
271 {
272 elements.push_back(new MeshLib::Quad(
273 {nodes[offset_y1 + k], nodes[offset_y1 + k + 1],
274 nodes[offset_y2 + k + 1], nodes[offset_y2 + k]}));
275 }
276 }
277
278 return new MeshLib::Mesh(mesh_name, nodes, elements);
279}
280
282 const double length,
283 const std::size_t subdivision,
284 const MathLib::Point3d& origin,
285 std::string const& mesh_name)
286{
288 subdivision, subdivision, subdivision, length / subdivision, origin,
289 mesh_name);
290}
291
293 const double x_length,
294 const double y_length,
295 const double z_length,
296 const std::size_t x_subdivision,
297 const std::size_t y_subdivision,
298 const std::size_t z_subdivision,
299 const MathLib::Point3d& origin,
300 std::string const& mesh_name)
301{
303 x_subdivision, y_subdivision, z_subdivision, x_length / x_subdivision,
304 y_length / y_subdivision, z_length / z_subdivision, origin, mesh_name);
305}
306
308 const unsigned n_x_cells,
309 const unsigned n_y_cells,
310 const unsigned n_z_cells,
311 const double cell_size,
312 MathLib::Point3d const& origin,
313 std::string const& mesh_name)
314{
316 n_x_cells, n_y_cells, n_z_cells, cell_size, cell_size, cell_size,
317 origin, mesh_name);
318}
319
321 const unsigned n_x_cells,
322 const unsigned n_y_cells,
323 const unsigned n_z_cells,
324 const double cell_size_x,
325 const double cell_size_y,
326 const double cell_size_z,
327 MathLib::Point3d const& origin,
328 std::string const& mesh_name)
329{
331 BaseLib::UniformSubdivision(n_x_cells * cell_size_x, n_x_cells),
332 BaseLib::UniformSubdivision(n_y_cells * cell_size_y, n_y_cells),
333 BaseLib::UniformSubdivision(n_z_cells * cell_size_z, n_z_cells), origin,
334 mesh_name);
335}
336
338 const BaseLib::ISubdivision& div_x,
339 const BaseLib::ISubdivision& div_y,
340 const BaseLib::ISubdivision& div_z,
341 MathLib::Point3d const& origin,
342 std::string const& mesh_name)
343{
344 std::vector<double> vec_x(div_x());
345 std::vector<double> vec_y(div_y());
346 std::vector<double> vec_z(div_z());
347 std::vector<MeshLib::Node*> nodes(
348 generateRegularNodes(vec_x, vec_y, vec_z, origin));
349
350 const unsigned n_x_nodes(vec_x.size());
351 const unsigned n_y_nodes(vec_y.size());
352 const unsigned n_x_cells(vec_x.size() - 1);
353 const unsigned n_y_cells(vec_y.size() - 1);
354 const unsigned n_z_cells(vec_z.size() - 1);
355
356 // elements
357 std::vector<MeshLib::Element*> elements;
358 elements.reserve(n_x_cells * n_y_cells * n_z_cells);
359
360 for (std::size_t i = 0; i < n_z_cells; i++)
361 {
362 const std::size_t offset_z1 = i * n_x_nodes * n_y_nodes; // bottom
363 const std::size_t offset_z2 = (i + 1) * n_x_nodes * n_y_nodes; // top
364 for (std::size_t j = 0; j < n_y_cells; j++)
365 {
366 const std::size_t offset_y1 = j * n_x_nodes;
367 const std::size_t offset_y2 = (j + 1) * n_x_nodes;
368 for (std::size_t k = 0; k < n_x_cells; k++)
369 {
370 elements.push_back(
371 new MeshLib::Hex({// bottom
372 nodes[offset_z1 + offset_y1 + k],
373 nodes[offset_z1 + offset_y1 + k + 1],
374 nodes[offset_z1 + offset_y2 + k + 1],
375 nodes[offset_z1 + offset_y2 + k],
376 // top
377 nodes[offset_z2 + offset_y1 + k],
378 nodes[offset_z2 + offset_y1 + k + 1],
379 nodes[offset_z2 + offset_y2 + k + 1],
380 nodes[offset_z2 + offset_y2 + k]}));
381 }
382 }
383 }
384
385 return new MeshLib::Mesh(mesh_name, nodes, elements);
386}
387
389 const BaseLib::ISubdivision& div_x,
390 const BaseLib::ISubdivision& div_y,
391 const BaseLib::ISubdivision& div_z,
392 MathLib::Point3d const& origin,
393 std::string const& mesh_name)
394{
395 std::vector<double> vec_x(div_x());
396 std::vector<double> vec_y(div_y());
397 std::vector<double> vec_z(div_z());
398 std::vector<MeshLib::Node*> nodes(
399 generateRegularNodes(vec_x, vec_y, vec_z, origin));
400 std::vector<MeshLib::Node*> const top_nodes(
401 generateRegularPyramidTopNodes(vec_x, vec_y, vec_z, origin));
402
403 nodes.insert(nodes.end(), top_nodes.begin(), top_nodes.end());
404
405 const unsigned n_x_nodes(vec_x.size());
406 const unsigned n_y_nodes(vec_y.size());
407 const unsigned n_z_nodes(vec_z.size());
408 const unsigned n_x_cells(vec_x.size() - 1);
409 const unsigned n_y_cells(vec_y.size() - 1);
410 const unsigned n_z_cells(vec_z.size() - 1);
411
412 // elements
413 std::vector<MeshLib::Element*> elements;
414 auto const top_node_offset(n_x_nodes * n_y_nodes * n_z_nodes);
415 elements.reserve(n_x_cells * n_y_cells * n_z_cells);
416
417 for (std::size_t i = 0; i < n_z_cells; i++)
418 {
419 const std::size_t offset_z1 = i * n_x_nodes * n_y_nodes; // bottom
420 const std::size_t offset_z2 = (i + 1) * n_x_nodes * n_y_nodes; // top
421 for (std::size_t j = 0; j < n_y_cells; j++)
422 {
423 const std::size_t offset_y1 = j * n_x_nodes;
424 const std::size_t offset_y2 = (j + 1) * n_x_nodes;
425 for (std::size_t k = 0; k < n_x_cells; k++)
426 {
427 // generate 6 pyramids within the virtual hexahedron cell
428 int const pyramid_top_index(i * n_x_cells * n_y_cells +
429 j * n_x_cells + k +
430 top_node_offset);
431 elements.push_back(
432 new MeshLib::Pyramid{{// bottom 'hexahedron' face
433 nodes[offset_z1 + offset_y1 + k],
434 nodes[offset_z1 + offset_y1 + k + 1],
435 nodes[offset_z1 + offset_y2 + k + 1],
436 nodes[offset_z1 + offset_y2 + k],
437 // top
438 nodes[pyramid_top_index]}});
439 elements.push_back(new MeshLib::Pyramid{
440 {// top 'hexahedron' face
441 nodes[offset_z2 + offset_y1 + k + 1],
442 nodes[offset_z2 + offset_y1 + k],
443 nodes[offset_z2 + offset_y2 + k],
444 nodes[offset_z2 + offset_y2 + k + 1],
445 // top of pyramid directed towards the bottom
446 nodes[pyramid_top_index]}});
447 elements.push_back(new MeshLib::Pyramid{
448 {// right 'hexahedron' face
449 nodes[offset_z1 + offset_y1 + k + 1],
450 nodes[offset_z2 + offset_y1 + k + 1],
451 nodes[offset_z2 + offset_y2 + k + 1],
452 nodes[offset_z1 + offset_y2 + k + 1],
453 // top of pyramid directed towards the bottom
454 nodes[pyramid_top_index]}});
455 elements.push_back(new MeshLib::Pyramid{
456 {// left 'hexahedron' face
457 nodes[offset_z2 + offset_y1 + k],
458 nodes[offset_z1 + offset_y1 + k],
459 nodes[offset_z1 + offset_y2 + k],
460 nodes[offset_z2 + offset_y2 + k],
461 // top of pyramid directed towards the bottom
462 nodes[pyramid_top_index]}});
463 elements.push_back(new MeshLib::Pyramid{
464 {// front 'hexahedron' face
465 nodes[offset_z2 + offset_y1 + k],
466 nodes[offset_z2 + offset_y1 + k + 1],
467 nodes[offset_z1 + offset_y1 + k + 1],
468 nodes[offset_z1 + offset_y1 + k],
469 // top of pyramid directed towards the bottom
470 nodes[pyramid_top_index]}});
471 elements.push_back(new MeshLib::Pyramid{
472 {// back 'hexahedron' face
473 nodes[offset_z1 + offset_y2 + k],
474 nodes[offset_z1 + offset_y2 + k + 1],
475 nodes[offset_z2 + offset_y2 + k + 1],
476 nodes[offset_z2 + offset_y2 + k],
477 // top of pyramid directed towards the bottom
478 nodes[pyramid_top_index]}});
479 }
480 }
481 }
482 return new MeshLib::Mesh(mesh_name, nodes, elements);
483}
484
486 const double length,
487 const std::size_t subdivision,
488 const MathLib::Point3d& origin,
489 std::string const& mesh_name)
490{
491 return generateRegularTriMesh(subdivision, subdivision,
492 length / subdivision, origin, mesh_name);
493}
494
496 const double x_length,
497 const double y_length,
498 const std::size_t x_subdivision,
499 const std::size_t y_subdivision,
500 const MathLib::Point3d& origin,
501 std::string const& mesh_name)
502{
503 return generateRegularTriMesh(x_subdivision, y_subdivision,
504 x_length / x_subdivision,
505 y_length / y_subdivision, origin, mesh_name);
506}
507
509 const unsigned n_x_cells,
510 const unsigned n_y_cells,
511 const double cell_size,
512 MathLib::Point3d const& origin,
513 std::string const& mesh_name)
514{
515 return generateRegularTriMesh(n_x_cells, n_y_cells, cell_size, cell_size,
516 origin, mesh_name);
517}
518
520 const unsigned n_x_cells,
521 const unsigned n_y_cells,
522 const double cell_size_x,
523 const double cell_size_y,
524 MathLib::Point3d const& origin,
525 std::string const& mesh_name)
526{
528 BaseLib::UniformSubdivision(n_x_cells * cell_size_x, n_x_cells),
529 BaseLib::UniformSubdivision(n_y_cells * cell_size_y, n_y_cells), origin,
530 mesh_name);
531}
532
534 const BaseLib::ISubdivision& div_x,
535 const BaseLib::ISubdivision& div_y,
536 MathLib::Point3d const& origin,
537 std::string const& mesh_name)
538{
539 std::vector<double> vec_x(div_x());
540 std::vector<double> vec_y(div_y());
541 std::vector<MeshLib::Node*> nodes(
542 generateRegularNodes(vec_x, vec_y, origin));
543 const unsigned n_x_nodes(vec_x.size());
544 const unsigned n_x_cells(vec_x.size() - 1);
545 const unsigned n_y_cells(vec_y.size() - 1);
546
547 // elements
548 std::vector<MeshLib::Element*> elements;
549 elements.reserve(n_x_cells * n_y_cells * 2);
550
551 for (std::size_t j = 0; j < n_y_cells; j++)
552 {
553 const std::size_t offset_y1 = j * n_x_nodes;
554 const std::size_t offset_y2 = (j + 1) * n_x_nodes;
555 for (std::size_t k = 0; k < n_x_cells; k++)
556 {
557 elements.push_back(new MeshLib::Tri({nodes[offset_y1 + k],
558 nodes[offset_y2 + k + 1],
559 nodes[offset_y2 + k]}));
560
561 elements.push_back(new MeshLib::Tri({nodes[offset_y1 + k],
562 nodes[offset_y1 + k + 1],
563 nodes[offset_y2 + k + 1]}));
564 }
565 }
566
567 return new MeshLib::Mesh(mesh_name, nodes, elements);
568}
569
571 const double x_length,
572 const double y_length,
573 const double z_length,
574 const std::size_t x_subdivision,
575 const std::size_t y_subdivision,
576 const std::size_t z_subdivision,
577 const MathLib::Point3d& origin,
578 std::string const& mesh_name)
579{
581 x_subdivision, y_subdivision, z_subdivision, x_length / x_subdivision,
582 y_length / y_subdivision, z_length / z_subdivision, origin, mesh_name);
583}
584
586 const unsigned n_x_cells,
587 const unsigned n_y_cells,
588 const unsigned n_z_cells,
589 const double cell_size,
590 MathLib::Point3d const& origin,
591 std::string const& mesh_name)
592{
593 return generateRegularPrismMesh(n_x_cells, n_y_cells, n_z_cells, cell_size,
594 cell_size, cell_size, origin, mesh_name);
595}
596
598 const unsigned n_x_cells,
599 const unsigned n_y_cells,
600 const unsigned n_z_cells,
601 const double cell_size_x,
602 const double cell_size_y,
603 const double cell_size_z,
604 MathLib::Point3d const& origin,
605 std::string const& mesh_name)
606{
607 std::unique_ptr<MeshLib::Mesh> mesh(generateRegularTriMesh(
608 n_x_cells, n_y_cells, cell_size_x, cell_size_y, origin, mesh_name));
609 std::size_t const n_tris(mesh->getNumberOfElements());
610 bool const copy_material_ids = false;
611 for (std::size_t i = 0; i < n_z_cells; ++i)
612 {
613 mesh.reset(MeshToolsLib::addLayerToMesh(*mesh, cell_size_z, mesh_name,
614 true, copy_material_ids));
615 }
616 std::vector<std::size_t> elem_ids(n_tris);
617 std::iota(elem_ids.begin(), elem_ids.end(), 0);
618 return MeshToolsLib::removeElements(*mesh, elem_ids, mesh_name);
619}
620
622 const double x_length,
623 const double y_length,
624 const double z_length,
625 const std::size_t x_subdivision,
626 const std::size_t y_subdivision,
627 const std::size_t z_subdivision,
628 const MathLib::Point3d& origin,
629 std::string const& mesh_name)
630{
632 x_subdivision, y_subdivision, z_subdivision, x_length / x_subdivision,
633 y_length / y_subdivision, z_length / z_subdivision, origin, mesh_name);
634}
635
637 const unsigned n_x_cells,
638 const unsigned n_y_cells,
639 const unsigned n_z_cells,
640 const double cell_size_x,
641 const double cell_size_y,
642 const double cell_size_z,
643 MathLib::Point3d const& origin,
644 std::string const& mesh_name)
645{
647 BaseLib::UniformSubdivision(n_x_cells * cell_size_x, n_x_cells),
648 BaseLib::UniformSubdivision(n_y_cells * cell_size_y, n_y_cells),
649 BaseLib::UniformSubdivision(n_z_cells * cell_size_z, n_z_cells), origin,
650 mesh_name);
651}
652
654 const BaseLib::ISubdivision& div_x,
655 const BaseLib::ISubdivision& div_y,
656 const BaseLib::ISubdivision& div_z,
657 MathLib::Point3d const& origin,
658 std::string const& mesh_name)
659{
660 std::vector<double> vec_x(div_x());
661 std::vector<double> vec_y(div_y());
662 std::vector<double> vec_z(div_z());
663 std::vector<MeshLib::Node*> nodes(
664 generateRegularNodes(vec_x, vec_y, vec_z, origin));
665
666 const unsigned n_x_nodes(vec_x.size());
667 const unsigned n_y_nodes(vec_y.size());
668 const unsigned n_x_cells(vec_x.size() - 1);
669 const unsigned n_y_cells(vec_y.size() - 1);
670 const unsigned n_z_cells(vec_z.size() - 1);
671
672 // elements
673 std::vector<MeshLib::Element*> elements;
674 elements.reserve(n_x_cells * n_y_cells * n_z_cells * 6);
675
676 for (std::size_t i = 0; i < n_z_cells; i++)
677 {
678 const std::size_t offset_z1 = i * n_x_nodes * n_y_nodes; // bottom
679 const std::size_t offset_z2 = (i + 1) * n_x_nodes * n_y_nodes; // top
680 for (std::size_t j = 0; j < n_y_cells; j++)
681 {
682 const std::size_t offset_y1 = j * n_x_nodes;
683 const std::size_t offset_y2 = (j + 1) * n_x_nodes;
684 for (std::size_t k = 0; k < n_x_cells; k++)
685 {
686 // tet 1
687 elements.push_back(
688 new MeshLib::Tet({// bottom
689 nodes[offset_z1 + offset_y1 + k],
690 nodes[offset_z1 + offset_y2 + k + 1],
691 nodes[offset_z1 + offset_y2 + k],
692 // top
693 nodes[offset_z2 + offset_y1 + k]}));
694 // tet 2
695 elements.push_back(
696 new MeshLib::Tet({// bottom
697 nodes[offset_z1 + offset_y2 + k + 1],
698 nodes[offset_z1 + offset_y2 + k],
699 // top
700 nodes[offset_z2 + offset_y1 + k],
701 nodes[offset_z2 + offset_y2 + k + 1]}));
702 // tet 3
703 elements.push_back(
704 new MeshLib::Tet({// bottom
705 nodes[offset_z1 + offset_y2 + k],
706 // top
707 nodes[offset_z2 + offset_y1 + k],
708 nodes[offset_z2 + offset_y2 + k + 1],
709 nodes[offset_z2 + offset_y2 + k]}));
710 // tet 4
711 elements.push_back(
712 new MeshLib::Tet({// bottom
713 nodes[offset_z1 + offset_y1 + k],
714 nodes[offset_z1 + offset_y1 + k + 1],
715 nodes[offset_z1 + offset_y2 + k + 1],
716 // top
717 nodes[offset_z2 + offset_y1 + k + 1]}));
718 // tet 5
719 elements.push_back(
720 new MeshLib::Tet({// bottom
721 nodes[offset_z1 + offset_y1 + k],
722 nodes[offset_z1 + offset_y2 + k + 1],
723 // top
724 nodes[offset_z2 + offset_y1 + k],
725 nodes[offset_z2 + offset_y1 + k + 1]}));
726 // tet 6
727 elements.push_back(
728 new MeshLib::Tet({// bottom
729 nodes[offset_z1 + offset_y2 + k + 1],
730 // top
731 nodes[offset_z2 + offset_y1 + k],
732 nodes[offset_z2 + offset_y1 + k + 1],
733 nodes[offset_z2 + offset_y2 + k + 1]}));
734 }
735 }
736 }
737
738 return new MeshLib::Mesh(mesh_name, nodes, elements);
739}
740
742 std::string const& mesh_name, MathLib::Point3d const& ll,
743 MathLib::Point3d const& ur, std::array<std::size_t, 2> const& n_steps,
744 const std::function<double(double, double)>& f)
745{
746 std::array<double, 2> const step_size{{(ur[0] - ll[0]) / (n_steps[0] - 1),
747 (ur[1] - ll[1]) / (n_steps[1] - 1)}};
748
749 std::vector<MeshLib::Node*> nodes;
750 for (std::size_t j(0); j < n_steps[1]; ++j)
751 {
752 for (std::size_t i(0); i < n_steps[0]; ++i)
753 {
754 std::size_t const id = i + j * n_steps[1];
755 double const x = ll[0] + i * step_size[0];
756 double const y = ll[1] + j * step_size[1];
757
758 nodes.push_back(new MeshLib::Node({x, y, f(x, y)}, id));
759 }
760 }
761
762 std::vector<MeshLib::Element*> sfc_eles;
763 for (std::size_t j(0); j < n_steps[1] - 1; ++j)
764 {
765 for (std::size_t i(0); i < n_steps[0] - 1; ++i)
766 {
767 std::size_t id_ll(i + j * n_steps[0]);
768 std::size_t id_lr(i + 1 + j * n_steps[0]);
769 std::size_t id_ul(i + (j + 1) * n_steps[0]);
770 std::size_t id_ur(i + 1 + (j + 1) * n_steps[0]);
771 sfc_eles.push_back(
772 new MeshLib::Tri({nodes[id_ll], nodes[id_lr], nodes[id_ur]}));
773 sfc_eles.push_back(
774 new MeshLib::Tri({nodes[id_ll], nodes[id_ur], nodes[id_ul]}));
775 }
776 }
777
778 return new MeshLib::Mesh(mesh_name, nodes, sfc_eles);
779}
780
781} // 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 thickness, std::string const &name, bool on_top, bool copy_material_ids)
MeshLib::Mesh * removeElements(const MeshLib::Mesh &mesh, const std::vector< std::size_t > &removed_element_ids, const std::string &new_mesh_name)