26 #include "libmesh/mesh_generation.h"
27 #include "libmesh/unstructured_mesh.h"
28 #include "libmesh/mesh_refinement.h"
29 #include "libmesh/edge_edge2.h"
30 #include "libmesh/edge_edge3.h"
31 #include "libmesh/edge_edge4.h"
32 #include "libmesh/face_tri3.h"
33 #include "libmesh/face_tri6.h"
34 #include "libmesh/face_quad4.h"
35 #include "libmesh/face_quad8.h"
36 #include "libmesh/face_quad9.h"
37 #include "libmesh/cell_hex8.h"
38 #include "libmesh/cell_hex20.h"
39 #include "libmesh/cell_hex27.h"
40 #include "libmesh/cell_prism6.h"
41 #include "libmesh/cell_prism15.h"
42 #include "libmesh/cell_prism18.h"
43 #include "libmesh/cell_tet4.h"
44 #include "libmesh/cell_pyramid5.h"
45 #include "libmesh/libmesh_logging.h"
46 #include "libmesh/boundary_info.h"
47 #include "libmesh/remote_elem.h"
48 #include "libmesh/sphere.h"
49 #include "libmesh/mesh_modification.h"
50 #include "libmesh/mesh_smoother_laplace.h"
51 #include "libmesh/node_elem.h"
52 #include "libmesh/vector_value.h"
53 #include "libmesh/function_base.h"
54 #include "libmesh/enum_order.h"
55 #include "libmesh/int_range.h"
56 #include "libmesh/parallel.h"
62 namespace Generation {
73 const unsigned int nx,
90 return i + j*(2*nx+1);
94 libmesh_error_msg(
"ERROR: Unrecognized 2D element type.");
105 const unsigned int nx,
106 const unsigned int ny,
107 const unsigned int i,
108 const unsigned int j,
109 const unsigned int k)
117 return i + (nx+1)*(j + k*(ny+1));
130 return i + (2*nx+1)*(j + k*(2*ny+1));
134 libmesh_error_msg(
"ERROR: Unrecognized element type.");
180 for (
unsigned dir=0; dir<3; ++dir)
202 virtual std::unique_ptr<FunctionBase<Real>>
clone ()
const override
204 return libmesh_make_unique<GaussLobattoRedistributionFunction>(*
this);
218 for (
unsigned dir=0; dir<3; ++dir)
225 Real integer_part_f = 0;
226 const Real fractional_part = std::modf(float_index, &integer_part_f);
228 const int integer_part =
int(integer_part_f);
233 int index =
int(round(float_index));
254 (1.0 - 2./3.*
_cosines[dir][integer_part] - 1./3.*
_cosines[dir][integer_part+1]);
263 (1.0 - 1./3.*
_cosines[dir][integer_part] - 2./3.*
_cosines[dir][integer_part+1]);
267 libmesh_error_msg(
"Cannot redistribute node: " << p);
276 const Real )
override
278 libmesh_not_implemented();
299 const unsigned int nx,
300 const unsigned int ny,
301 const unsigned int nz,
306 const bool gauss_lobatto_grid)
308 START_LOG(
"build_cube()",
"MeshTools::Generation");
317 using namespace MeshTools::Generation::Private;
326 mesh.set_mesh_dimension(3);
327 mesh.set_spatial_dimension(3);
331 mesh.set_mesh_dimension(2);
332 mesh.set_spatial_dimension(2);
336 mesh.set_mesh_dimension(1);
337 mesh.set_spatial_dimension(1);
342 mesh.set_mesh_dimension(0);
343 mesh.set_spatial_dimension(0);
346 switch (
mesh.mesh_dimension())
352 libmesh_assert_equal_to (nx, 0);
353 libmesh_assert_equal_to (ny, 0);
354 libmesh_assert_equal_to (nz, 0);
372 libmesh_assert_not_equal_to (nx, 0);
373 libmesh_assert_equal_to (ny, 0);
374 libmesh_assert_equal_to (nz, 0);
375 libmesh_assert_less (xmin, xmax);
385 mesh.reserve_elem (nx);
390 libmesh_error_msg(
"ERROR: Unrecognized 1D element type.");
399 mesh.reserve_nodes(nx+1);
405 mesh.reserve_nodes(2*nx+1);
411 mesh.reserve_nodes(3*nx+1);
416 libmesh_error_msg(
"ERROR: Unrecognized 1D element type.");
422 unsigned int node_id = 0;
428 for (
unsigned int i=0; i<=nx; i++)
429 mesh.add_point (
Point(static_cast<Real>(i)/nx, 0, 0), node_id++);
436 for (
unsigned int i=0; i<=2*nx; i++)
437 mesh.add_point (
Point(static_cast<Real>(i)/(2*nx), 0, 0), node_id++);
443 for (
unsigned int i=0; i<=3*nx; i++)
444 mesh.add_point (
Point(static_cast<Real>(i)/(3*nx), 0, 0), node_id++);
450 libmesh_error_msg(
"ERROR: Unrecognized 1D element type.");
460 for (
unsigned int i=0; i<nx; i++)
464 elem =
mesh.add_elem (elem);
479 for (
unsigned int i=0; i<nx; i++)
483 elem =
mesh.add_elem (elem);
499 for (
unsigned int i=0; i<nx; i++)
503 elem =
mesh.add_elem (elem);
519 libmesh_error_msg(
"ERROR: Unrecognized 1D element type.");
523 if (gauss_lobatto_grid)
525 GaussLobattoRedistributionFunction func(nx, xmin, xmax);
530 for (
Node * node :
mesh.node_ptr_range())
531 (*node)(0) = (*node)(0)*(xmax-xmin) + xmin;
558 libmesh_assert_not_equal_to (nx, 0);
559 libmesh_assert_not_equal_to (ny, 0);
560 libmesh_assert_equal_to (nz, 0);
561 libmesh_assert_less (xmin, xmax);
562 libmesh_assert_less (ymin, ymax);
573 mesh.reserve_elem (nx*ny);
580 mesh.reserve_elem (2*nx*ny);
585 libmesh_error_msg(
"ERROR: Unrecognized 2D element type.");
598 mesh.reserve_nodes( (nx+1)*(ny+1) );
606 mesh.reserve_nodes( (2*nx+1)*(2*ny+1) );
612 libmesh_error_msg(
"ERROR: Unrecognized 2D element type.");
620 unsigned int node_id = 0;
627 for (
unsigned int j=0; j<=ny; j++)
628 for (
unsigned int i=0; i<=nx; i++)
629 mesh.add_point (
Point(static_cast<Real>(i)/static_cast<Real>(nx),
630 static_cast<Real>(j)/static_cast<Real>(ny),
640 for (
unsigned int j=0; j<=(2*ny); j++)
641 for (
unsigned int i=0; i<=(2*nx); i++)
642 mesh.add_point (
Point(static_cast<Real>(i)/static_cast<Real>(2*nx),
643 static_cast<Real>(j)/static_cast<Real>(2*ny),
651 libmesh_error_msg(
"ERROR: Unrecognized 2D element type.");
660 unsigned int elem_id = 0;
667 for (
unsigned int j=0; j<ny; j++)
668 for (
unsigned int i=0; i<nx; i++)
672 elem =
mesh.add_elem (elem);
697 for (
unsigned int j=0; j<ny; j++)
698 for (
unsigned int i=0; i<nx; i++)
703 elem =
mesh.add_elem (elem);
718 elem =
mesh.add_elem (elem);
738 for (
unsigned int j=0; j<(2*ny); j += 2)
739 for (
unsigned int i=0; i<(2*nx); i += 2)
742 static_cast<Elem *>(
new Quad8) :
743 static_cast<Elem *>(
new Quad9);
745 elem =
mesh.add_elem (elem);
777 for (
unsigned int j=0; j<(2*ny); j += 2)
778 for (
unsigned int i=0; i<(2*nx); i += 2)
783 elem =
mesh.add_elem (elem);
801 elem =
mesh.add_elem (elem);
822 libmesh_error_msg(
"ERROR: Unrecognized 2D element type.");
829 if (gauss_lobatto_grid)
831 GaussLobattoRedistributionFunction func(nx, xmin, xmax,
837 for (
Node * node :
mesh.node_ptr_range())
839 (*node)(0) = ((*node)(0))*(xmax-xmin) + xmin;
840 (*node)(1) = ((*node)(1))*(ymax-ymin) + ymin;
873 libmesh_assert_not_equal_to (nx, 0);
874 libmesh_assert_not_equal_to (ny, 0);
875 libmesh_assert_not_equal_to (nz, 0);
876 libmesh_assert_less (xmin, xmax);
877 libmesh_assert_less (ymin, ymax);
878 libmesh_assert_less (zmin, zmax);
895 mesh.reserve_elem(nx*ny*nz);
903 mesh.reserve_elem(2*nx*ny*nz);
908 libmesh_error_msg(
"ERROR: Unrecognized 3D element type.");
922 mesh.reserve_nodes( (nx+1)*(ny+1)*(nz+1) );
940 mesh.reserve_nodes( (2*nx+1)*(2*ny+1)*(2*nz+1) );
945 libmesh_error_msg(
"ERROR: Unrecognized 3D element type.");
952 unsigned int node_id = 0;
959 for (
unsigned int k=0; k<=nz; k++)
960 for (
unsigned int j=0; j<=ny; j++)
961 for (
unsigned int i=0; i<=nx; i++)
962 mesh.add_point(
Point(static_cast<Real>(i)/static_cast<Real>(nx),
963 static_cast<Real>(j)/static_cast<Real>(ny),
964 static_cast<Real>(k)/static_cast<Real>(nz)), node_id++);
979 for (
unsigned int k=0; k<=(2*nz); k++)
980 for (
unsigned int j=0; j<=(2*ny); j++)
981 for (
unsigned int i=0; i<=(2*nx); i++)
982 mesh.add_point(
Point(static_cast<Real>(i)/static_cast<Real>(2*nx),
983 static_cast<Real>(j)/static_cast<Real>(2*ny),
984 static_cast<Real>(k)/static_cast<Real>(2*nz)), node_id++);
991 libmesh_error_msg(
"ERROR: Unrecognized 3D element type.");
998 unsigned int elem_id = 0;
1004 for (
unsigned int k=0; k<nz; k++)
1005 for (
unsigned int j=0; j<ny; j++)
1006 for (
unsigned int i=0; i<nx; i++)
1010 elem =
mesh.add_elem (elem);
1022 boundary_info.
add_side(elem, 0, 0);
1025 boundary_info.
add_side(elem, 5, 5);
1028 boundary_info.
add_side(elem, 1, 1);
1031 boundary_info.
add_side(elem, 3, 3);
1034 boundary_info.
add_side(elem, 4, 4);
1037 boundary_info.
add_side(elem, 2, 2);
1047 for (
unsigned int k=0; k<nz; k++)
1048 for (
unsigned int j=0; j<ny; j++)
1049 for (
unsigned int i=0; i<nx; i++)
1054 elem =
mesh.add_elem (elem);
1065 boundary_info.
add_side(elem, 3, 4);
1068 boundary_info.
add_side(elem, 1, 1);
1071 boundary_info.
add_side(elem, 0, 0);
1074 boundary_info.
add_side(elem, 4, 5);
1079 elem =
mesh.add_elem (elem);
1090 boundary_info.
add_side(elem, 1, 2);
1093 boundary_info.
add_side(elem, 2, 3);
1096 boundary_info.
add_side(elem, 0, 0);
1099 boundary_info.
add_side(elem, 4, 5);
1117 for (
unsigned int k=0; k<(2*nz); k += 2)
1118 for (
unsigned int j=0; j<(2*ny); j += 2)
1119 for (
unsigned int i=0; i<(2*nx); i += 2)
1122 static_cast<Elem *>(
new Hex20) :
1123 static_cast<Elem *>(
new Hex27);
1125 elem =
mesh.add_elem (elem);
1161 boundary_info.
add_side(elem, 0, 0);
1164 boundary_info.
add_side(elem, 5, 5);
1167 boundary_info.
add_side(elem, 1, 1);
1170 boundary_info.
add_side(elem, 3, 3);
1173 boundary_info.
add_side(elem, 4, 4);
1176 boundary_info.
add_side(elem, 2, 2);
1187 for (
unsigned int k=0; k<(2*nz); k += 2)
1188 for (
unsigned int j=0; j<(2*ny); j += 2)
1189 for (
unsigned int i=0; i<(2*nx); i += 2)
1193 static_cast<Elem *>(
new Prism15) :
1194 static_cast<Elem *>(
new Prism18);
1196 elem =
mesh.add_elem (elem);
1222 boundary_info.
add_side(elem, 3, 4);
1225 boundary_info.
add_side(elem, 1, 1);
1228 boundary_info.
add_side(elem, 0, 0);
1231 boundary_info.
add_side(elem, 4, 5);
1236 static_cast<Elem *>(
new Prism15) :
1237 static_cast<Elem *>(
new Prism18);
1239 elem =
mesh.add_elem (elem);
1265 boundary_info.
add_side(elem, 1, 2);
1268 boundary_info.
add_side(elem, 2, 3);
1271 boundary_info.
add_side(elem, 0, 0);
1274 boundary_info.
add_side(elem, 4, 5);
1285 libmesh_error_msg(
"ERROR: Unrecognized 3D element type.");
1293 if (gauss_lobatto_grid)
1295 GaussLobattoRedistributionFunction func(nx, xmin, xmax,
1302 for (
unsigned int p=0; p<
mesh.n_nodes(); p++)
1304 mesh.node_ref(p)(0) = (
mesh.node_ref(p)(0))*(xmax-xmin) + xmin;
1305 mesh.node_ref(p)(1) = (
mesh.node_ref(p)(1))*(ymax-ymin) + ymin;
1306 mesh.node_ref(p)(2) = (
mesh.node_ref(p)(2))*(zmax-zmin) + zmin;
1319 if ((type ==
TET4) ||
1326 std::vector<Elem *> new_elements;
1329 new_elements.reserve(24*
mesh.n_elem());
1331 new_elements.reserve(6*
mesh.n_elem());
1334 for (
auto & base_hex :
mesh.element_ptr_range())
1337 Node * apex_node = base_hex->node_ptr(26);
1340 std::vector<boundary_id_type> ids;
1342 for (
auto s : base_hex->side_index_range())
1354 std::unique_ptr<Elem> side = base_hex->build_side_ptr(s);
1359 for (
unsigned int sub_tet=0; sub_tet<4; ++sub_tet)
1361 new_elements.push_back(
new Tet4 );
1362 Elem * sub_elem = new_elements.back();
1363 sub_elem->
set_node(0) = side->node_ptr(sub_tet);
1364 sub_elem->
set_node(1) = side->node_ptr(8);
1365 sub_elem->
set_node(2) = side->node_ptr(sub_tet==3 ? 0 : sub_tet+1 );
1372 boundary_info.
add_side(sub_elem, 0, b_id);
1379 new_elements.push_back(
new Pyramid5);
1380 Elem * sub_elem = new_elements.back();
1385 sub_elem->
set_node(0) = side->node_ptr(0);
1386 sub_elem->
set_node(1) = side->node_ptr(3);
1387 sub_elem->
set_node(2) = side->node_ptr(2);
1388 sub_elem->
set_node(3) = side->node_ptr(1);
1396 boundary_info.
add_side(sub_elem, 4, b_id);
1403 for (
auto & elem :
mesh.element_ptr_range())
1405 boundary_info.
remove(elem);
1406 mesh.delete_elem(elem);
1411 n_new = cast_int<dof_id_type>(new_elements.size());
1414 new_elements[i]->set_id(i);
1415 mesh.add_elem(new_elements[i]);
1423 mesh.all_second_order();
1426 mesh.all_second_order(
false);
1449 libmesh_error_msg(
"Unknown dimension " <<
mesh.mesh_dimension());
1452 STOP_LOG(
"build_cube()",
"MeshTools::Generation");
1457 mesh.prepare_for_use (
false);
1464 const bool gauss_lobatto_grid)
1476 gauss_lobatto_grid);
1481 const unsigned int nx,
1484 const bool gauss_lobatto_grid)
1496 gauss_lobatto_grid);
1502 const unsigned int nx,
1503 const unsigned int ny,
1507 const bool gauss_lobatto_grid)
1520 gauss_lobatto_grid);
1531 #ifndef LIBMESH_ENABLE_AMR
1539 libmesh_error_msg(
"Building a circle/sphere only works with AMR.");
1546 const unsigned int nr,
1548 const unsigned int n_smooth,
1551 libmesh_assert_greater (rad, 0.);
1554 START_LOG(
"build_sphere()",
"MeshTools::Generation");
1560 unsigned char orig_mesh_dimension =
1583 libmesh_error_msg(
"build_sphere(): Please specify a mesh dimension or a valid ElemType (EDGE{2,3,4}, TRI3, QUAD4, HEX{8,27})");
1591 const Sphere sphere (cent, rad);
1615 unsigned node_id = 0;
1620 const Real rad_2 = .25*rad;
1621 const Real rad_sqrt_2 = rad/sqrt_2;
1624 std::vector<Node *> nodes(8);
1627 nodes[0] =
mesh.
add_point (Point(-rad_2,-rad_2, 0.), node_id++);
1630 nodes[1] =
mesh.
add_point (Point( rad_2,-rad_2, 0.), node_id++);
1633 nodes[2] =
mesh.
add_point (Point( rad_2, rad_2, 0.), node_id++);
1636 nodes[3] =
mesh.
add_point (Point(-rad_2, rad_2, 0.), node_id++);
1639 nodes[4] =
mesh.
add_point (Point(-rad_sqrt_2,-rad_sqrt_2, 0.), node_id++);
1642 nodes[5] =
mesh.
add_point (Point( rad_sqrt_2,-rad_sqrt_2, 0.), node_id++);
1645 nodes[6] =
mesh.
add_point (Point( rad_sqrt_2, rad_sqrt_2, 0.), node_id++);
1648 nodes[7] =
mesh.
add_point (Point(-rad_sqrt_2, rad_sqrt_2, 0.), node_id++);
1656 elem0->set_node(1) = nodes[1];
1657 elem0->set_node(2) = nodes[2];
1658 elem0->set_node(3) = nodes[3];
1665 elem1->set_node(1) = nodes[0];
1666 elem1->set_node(2) = nodes[3];
1667 elem1->set_node(3) = nodes[7];
1674 elem2->set_node(1) = nodes[5];
1675 elem2->set_node(2) = nodes[1];
1676 elem2->set_node(3) = nodes[0];
1683 elem3->set_node(1) = nodes[5];
1684 elem3->set_node(2) = nodes[6];
1685 elem3->set_node(3) = nodes[2];
1692 elem4->set_node(1) = nodes[2];
1693 elem4->set_node(2) = nodes[6];
1694 elem4->set_node(3) = nodes[7];
1721 static const unsigned int idx1 [6] = {11, 5, 1, 7, 10, 11};
1722 static const unsigned int idx2 [6] = {9, 4, 2, 6, 8, 9};
1723 static const unsigned int idx3 [6] = {1, 5, 11, 10, 7, 1};
1725 for (
unsigned int i = 0; i < 5; ++i)
1765 if (!((type ==
HEX8) || (type ==
HEX27)))
1769 libmesh_error_msg(
"Error: Only HEX8/27 currently supported.");
1779 std::vector<Node *> nodes(16);
1785 unsigned node_id = 0;
1788 nodes[0] =
mesh.
add_point (Point(-r_small,-r_small, -r_small), node_id++);
1789 nodes[1] =
mesh.
add_point (Point( r_small,-r_small, -r_small), node_id++);
1790 nodes[2] =
mesh.
add_point (Point( r_small, r_small, -r_small), node_id++);
1791 nodes[3] =
mesh.
add_point (Point(-r_small, r_small, -r_small), node_id++);
1792 nodes[4] =
mesh.
add_point (Point(-r_small,-r_small, r_small), node_id++);
1793 nodes[5] =
mesh.
add_point (Point( r_small,-r_small, r_small), node_id++);
1794 nodes[6] =
mesh.
add_point (Point( r_small, r_small, r_small), node_id++);
1795 nodes[7] =
mesh.
add_point (Point(-r_small, r_small, r_small), node_id++);
1798 nodes[8] =
mesh.
add_point (Point(-r_med,-r_med, -r_med), node_id++);
1799 nodes[9] =
mesh.
add_point (Point( r_med,-r_med, -r_med), node_id++);
1800 nodes[10] =
mesh.
add_point (Point( r_med, r_med, -r_med), node_id++);
1801 nodes[11] =
mesh.
add_point (Point(-r_med, r_med, -r_med), node_id++);
1802 nodes[12] =
mesh.
add_point (Point(-r_med,-r_med, r_med), node_id++);
1803 nodes[13] =
mesh.
add_point (Point( r_med,-r_med, r_med), node_id++);
1804 nodes[14] =
mesh.
add_point (Point( r_med, r_med, r_med), node_id++);
1805 nodes[15] =
mesh.
add_point (Point(-r_med, r_med, r_med), node_id++);
1812 elem0->set_node(1) = nodes[1];
1813 elem0->set_node(2) = nodes[2];
1814 elem0->set_node(3) = nodes[3];
1815 elem0->set_node(4) = nodes[4];
1816 elem0->set_node(5) = nodes[5];
1817 elem0->set_node(6) = nodes[6];
1818 elem0->set_node(7) = nodes[7];
1825 elem1->set_node(1) = nodes[9];
1826 elem1->set_node(2) = nodes[10];
1827 elem1->set_node(3) = nodes[11];
1828 elem1->set_node(4) = nodes[0];
1829 elem1->set_node(5) = nodes[1];
1830 elem1->set_node(6) = nodes[2];
1831 elem1->set_node(7) = nodes[3];
1838 elem2->set_node(1) = nodes[9];
1839 elem2->set_node(2) = nodes[1];
1840 elem2->set_node(3) = nodes[0];
1841 elem2->set_node(4) = nodes[12];
1842 elem2->set_node(5) = nodes[13];
1843 elem2->set_node(6) = nodes[5];
1844 elem2->set_node(7) = nodes[4];
1851 elem3->set_node(1) = nodes[9];
1852 elem3->set_node(2) = nodes[10];
1853 elem3->set_node(3) = nodes[2];
1854 elem3->set_node(4) = nodes[5];
1855 elem3->set_node(5) = nodes[13];
1856 elem3->set_node(6) = nodes[14];
1857 elem3->set_node(7) = nodes[6];
1864 elem4->set_node(1) = nodes[2];
1865 elem4->set_node(2) = nodes[10];
1866 elem4->set_node(3) = nodes[11];
1867 elem4->set_node(4) = nodes[7];
1868 elem4->set_node(5) = nodes[6];
1869 elem4->set_node(6) = nodes[14];
1870 elem4->set_node(7) = nodes[15];
1877 elem5->set_node(1) = nodes[0];
1878 elem5->set_node(2) = nodes[3];
1879 elem5->set_node(3) = nodes[11];
1880 elem5->set_node(4) = nodes[12];
1881 elem5->set_node(5) = nodes[4];
1882 elem5->set_node(6) = nodes[7];
1883 elem5->set_node(7) = nodes[15];
1890 elem6->set_node(1) = nodes[5];
1891 elem6->set_node(2) = nodes[6];
1892 elem6->set_node(3) = nodes[7];
1893 elem6->set_node(4) = nodes[12];
1894 elem6->set_node(5) = nodes[13];
1895 elem6->set_node(6) = nodes[14];
1896 elem6->set_node(7) = nodes[15];
1912 MeshRefinement mesh_refinement (
mesh);
1915 for (
unsigned int r=0; r<nr; r++)
1917 mesh_refinement.uniformly_refine(1);
1920 for (
auto s : elem->side_index_range())
1923 std::unique_ptr<Elem> side(elem->build_side_ptr(s));
1926 for (
auto n : side->node_index_range())
1928 sphere.closest_point(side->point(n));
1941 if ((type ==
TRI6) || (type ==
TRI3))
1955 bool full_ordered = !((type==
QUAD8) || (type==
HEX20));
1960 for (
auto s : elem->side_index_range())
1961 if (elem->neighbor_ptr(s) ==
nullptr)
1963 std::unique_ptr<Elem> side(elem->build_side_ptr(s));
1966 for (
auto n : side->node_index_range())
1968 sphere.closest_point(side->point(n));
1974 LaplaceMeshSmoother smoother(
mesh);
1975 smoother.smooth(n_smooth);
1979 for (
auto s : elem->side_index_range())
1980 if (!elem->neighbor_ptr(s))
1981 boundary_info.
add_side(elem, s, 0);
1983 STOP_LOG(
"build_sphere()",
"MeshTools::Generation");
1990 #endif // #ifndef LIBMESH_ENABLE_AMR
1996 const unsigned int nz,
2000 if (!cross_section.
n_elem())
2003 START_LOG(
"build_extrusion()",
"MeshTools::Generation");
2008 #ifdef LIBMESH_ENABLE_UNIQUE_ID
2012 unsigned int order = 1;
2034 std::vector<boundary_id_type> ids_to_copy;
2038 for (
unsigned int k=0; k != order*nz+1; ++k)
2042 (extrusion_vector * k / nz / order),
2043 node->id() + (k * orig_nodes),
2044 node->processor_id());
2046 #ifdef LIBMESH_ENABLE_UNIQUE_ID
2052 orig_unique_ids + (k-1)*(orig_nodes + orig_elem) + node->id();
2057 cross_section_boundary_info.
boundary_ids(node, ids_to_copy);
2058 boundary_info.
add_node(new_node, ids_to_copy);
2062 const std::set<boundary_id_type> & side_ids =
2066 0 : cast_int<boundary_id_type>(*side_ids.rbegin() + 1);
2071 cross_section.
comm().max(next_side_id);
2075 const ElemType etype = elem->type();
2080 for (
unsigned int k=0; k != nz; ++k)
2087 new_elem =
new Quad4;
2102 new_elem =
new Quad9;
2172 new_elem =
new Hex8;
2195 new_elem =
new Hex27;
2237 libmesh_not_implemented();
2242 new_elem->
set_id(elem->id() + (k * orig_elem));
2245 #ifdef LIBMESH_ENABLE_UNIQUE_ID
2251 orig_unique_ids + (k-1)*(orig_nodes + orig_elem) + orig_nodes + elem->id();
2256 if (!elem_subdomain)
2266 for (
auto s : elem->side_index_range())
2268 cross_section_boundary_info.
boundary_ids(elem, s, ids_to_copy);
2270 if (new_elem->
dim() == 3)
2277 cast_int<unsigned short>(s+1),
2286 libmesh_assert_less(s, 2);
2287 const unsigned short sidemap[2] = {3, 1};
2288 boundary_info.
add_side(new_elem, sidemap[s], ids_to_copy);
2294 boundary_info.
add_side(new_elem, 0, next_side_id);
2300 const unsigned short top_id = new_elem->
dim() == 3 ?
2301 cast_int<unsigned short>(elem->n_sides()+1) : 2;
2304 cast_int<boundary_id_type>(next_side_id+1));
2309 STOP_LOG(
"build_extrusion()",
"MeshTools::Generation");
2318 #if defined(LIBMESH_HAVE_TRIANGLE) && LIBMESH_DIM > 1
2322 const unsigned int nx,
2323 const unsigned int ny,
2327 const std::vector<TriangleInterface::Hole*> * holes)
2330 libmesh_assert_greater_equal (nx, 1);
2331 libmesh_assert_greater_equal (ny, 1);
2332 libmesh_assert_less (xmin, xmax);
2333 libmesh_assert_less (ymin, ymax);
2344 const Real delta_x = (xmax-xmin) / static_cast<Real>(nx);
2345 const Real delta_y = (ymax-ymin) / static_cast<Real>(ny);
2348 for (
unsigned int p=0; p<=nx; ++p)
2352 for (
unsigned int p=1; p<ny; ++p)
2356 for (
unsigned int p=0; p<=nx; ++p)
2360 for (
unsigned int p=1; p<ny; ++p)
2364 libmesh_assert_equal_to (
mesh.
n_nodes(), 2*(nx+ny));
2370 t.
desired_area() = 0.5 * (xmax-xmin)*(ymax-ymin) / static_cast<Real>(nx*ny);
2374 if (holes !=
nullptr)
2384 for (
auto s : elem->side_index_range())
2385 if (elem->neighbor_ptr(s) ==
nullptr)
2387 std::unique_ptr<const Elem> side (elem->build_side_ptr(s));
2393 Point side_midpoint= 0.5f*( side->point(0) + side->point(1) );
2404 if (std::fabs(side_midpoint(1) - ymin) <
TOLERANCE)
2408 else if (std::fabs(side_midpoint(0) - xmax) <
TOLERANCE)
2412 else if (std::fabs(side_midpoint(1) - ymax) <
TOLERANCE)
2416 else if (std::fabs(side_midpoint(0) - xmin) <
TOLERANCE)
2423 boundary_info.
add_side(elem->id(), s, bc_id);
2428 #endif // LIBMESH_HAVE_TRIANGLE && LIBMESH_DIM > 1