21 #include "libmesh/mesh_generation.h" 22 #include "libmesh/unstructured_mesh.h" 23 #include "libmesh/mesh_refinement.h" 24 #include "libmesh/edge_edge2.h" 25 #include "libmesh/edge_edge3.h" 26 #include "libmesh/edge_edge4.h" 27 #include "libmesh/face_tri3.h" 28 #include "libmesh/face_tri6.h" 29 #include "libmesh/face_tri7.h" 30 #include "libmesh/face_quad4.h" 31 #include "libmesh/face_quad8.h" 32 #include "libmesh/face_quad9.h" 33 #include "libmesh/face_c0polygon.h" 34 #include "libmesh/cell_hex8.h" 35 #include "libmesh/cell_hex20.h" 36 #include "libmesh/cell_hex27.h" 37 #include "libmesh/cell_prism6.h" 38 #include "libmesh/cell_prism15.h" 39 #include "libmesh/cell_prism18.h" 40 #include "libmesh/cell_prism20.h" 41 #include "libmesh/cell_prism21.h" 42 #include "libmesh/cell_tet4.h" 43 #include "libmesh/cell_pyramid5.h" 44 #include "libmesh/libmesh_logging.h" 45 #include "libmesh/boundary_info.h" 46 #include "libmesh/remote_elem.h" 47 #include "libmesh/sphere.h" 48 #include "libmesh/mesh_modification.h" 49 #include "libmesh/mesh_smoother_laplace.h" 50 #include "libmesh/node_elem.h" 51 #include "libmesh/vector_value.h" 52 #include "libmesh/function_base.h" 53 #include "libmesh/enum_order.h" 54 #include "libmesh/int_range.h" 55 #include "libmesh/parallel.h" 56 #include "libmesh/parallel_ghost_sync.h" 57 #include "libmesh/enum_to_string.h" 62 #include <unordered_set> 69 namespace Generation {
80 const unsigned int nx,
102 return i + j*(2*nx+1);
117 const unsigned int nx,
118 const unsigned int ny,
119 const unsigned int i,
120 const unsigned int j,
121 const unsigned int k)
129 return i + (nx+1)*(j + k*(ny+1));
146 return i + (2*nx+1)*(j + k*(2*ny+1));
196 for (
unsigned dir=0; dir<3; ++dir)
218 virtual std::unique_ptr<FunctionBase<Real>>
clone ()
const override 220 return std::make_unique<GaussLobattoRedistributionFunction>(*this);
234 for (
unsigned dir=0; dir<3; ++dir)
241 Real integer_part_f = 0;
242 const Real fractional_part = std::modf(float_index, &integer_part_f);
244 const int integer_part =
int(integer_part_f);
247 if (std::abs(fractional_part) <
TOLERANCE || std::abs(fractional_part - 1.0) <
TOLERANCE)
249 int index =
int(round(float_index));
256 else if (std::abs(fractional_part - 0.5) <
TOLERANCE)
265 else if (std::abs(fractional_part - 1./3.) <
TOLERANCE)
270 (1.0 - 2./3.*
_cosines[dir][integer_part] - 1./3.*
_cosines[dir][integer_part+1]);
274 else if (std::abs(fractional_part - 2./3.) <
TOLERANCE)
279 (1.0 - 1./3.*
_cosines[dir][integer_part] - 2./3.*
_cosines[dir][integer_part+1]);
283 libmesh_error_msg(
"Cannot redistribute node: " << p);
292 const Real )
override 294 libmesh_not_implemented();
315 const unsigned int nx,
316 const unsigned int ny,
317 const unsigned int nz,
322 const bool gauss_lobatto_grid)
324 LOG_SCOPE(
"build_cube()",
"MeshTools::Generation");
333 using namespace MeshTools::Generation::Private;
342 mesh.set_mesh_dimension(3);
343 mesh.set_spatial_dimension(3);
347 mesh.set_mesh_dimension(2);
348 mesh.set_spatial_dimension(2);
352 mesh.set_mesh_dimension(1);
353 mesh.set_spatial_dimension(1);
358 mesh.set_mesh_dimension(0);
359 mesh.set_spatial_dimension(0);
362 switch (
mesh.mesh_dimension())
368 libmesh_assert_equal_to (nx, 0);
369 libmesh_assert_equal_to (ny, 0);
370 libmesh_assert_equal_to (nz, 0);
388 libmesh_assert_not_equal_to (nx, 0);
389 libmesh_assert_equal_to (ny, 0);
390 libmesh_assert_equal_to (nz, 0);
391 libmesh_assert_less (xmin, xmax);
401 mesh.reserve_elem (nx);
415 mesh.reserve_nodes(nx+1);
421 mesh.reserve_nodes(2*nx+1);
427 mesh.reserve_nodes(3*nx+1);
438 unsigned int node_id = 0;
444 for (
unsigned int i=0; i<=nx; i++)
446 const Node *
const node =
mesh.add_point (
Point(static_cast<Real>(i)/nx, 0, 0), node_id++);
458 for (
unsigned int i=0; i<=2*nx; i++)
460 const Node *
const node =
mesh.add_point (
Point(static_cast<Real>(i)/(2*nx), 0, 0), node_id++);
471 for (
unsigned int i=0; i<=3*nx; i++)
473 const Node *
const node =
mesh.add_point (
Point(static_cast<Real>(i)/(3*nx), 0, 0), node_id++);
494 for (
unsigned int i=0; i<nx; i++)
512 for (
unsigned int i=0; i<nx; i++)
530 for (
unsigned int i=0; i<nx; i++)
552 if (gauss_lobatto_grid)
554 GaussLobattoRedistributionFunction func(nx, xmin, xmax);
559 for (
Node * node :
mesh.node_ptr_range())
560 (*node)(0) = (*node)(0)*(xmax-xmin) + xmin;
587 libmesh_assert_not_equal_to (nx, 0);
588 libmesh_assert_not_equal_to (ny, 0);
589 libmesh_assert_equal_to (nz, 0);
590 libmesh_assert_less (xmin, xmax);
591 libmesh_assert_less (ymin, ymax);
605 mesh.reserve_elem (nx*ny);
614 mesh.reserve_elem (2*nx*ny);
620 mesh.reserve_elem ((nx + 1) * (ny + 1));
640 mesh.reserve_nodes( (nx+1)*(ny+1) );
650 mesh.reserve_nodes( (2*nx+1)*(2*ny+1) );
656 mesh.reserve_nodes( (2*nx+1)*(2*ny+1) + 2*nx*ny );
661 mesh.reserve_nodes (4 + 3*nx*ny + 2*nx + 2*ny);
674 unsigned int node_id = 0;
683 for (
unsigned int j=0; j<=ny; j++)
684 for (
unsigned int i=0; i<=nx; i++)
686 const Node *
const node =
687 mesh.add_point(
Point(static_cast<Real>(i) / static_cast<Real>(nx),
688 static_cast<Real>(j) / static_cast<Real>(ny),
711 for (
unsigned int j=0; j<=(2*ny); j++)
712 for (
unsigned int i=0; i<=(2*nx); i++)
714 const Node *
const node =
715 mesh.add_point(
Point(static_cast<Real>(i) / static_cast<Real>(2 * nx),
716 static_cast<Real>(j) / static_cast<Real>(2 * ny),
732 for (
unsigned int j=0; j<(3*ny); j += 3)
733 for (
unsigned int i=0; i<(3*nx); i += 3)
736 mesh.add_point(
Point(static_cast<Real>(i+2) / static_cast<Real>(3 * nx),
737 static_cast<Real>(j+1) / static_cast<Real>(3 * ny),
741 mesh.add_point(
Point(static_cast<Real>(i+1) / static_cast<Real>(3 * nx),
742 static_cast<Real>(j+2) / static_cast<Real>(3 * ny),
766 unsigned int elem_id = 0;
774 for (
unsigned int j=0; j<ny; j++)
775 for (
unsigned int i=0; i<nx; i++)
802 for (
unsigned int j=0; j<ny; j++)
803 for (
unsigned int i=0; i<nx; i++)
839 for (
unsigned int j=0; j<(2*ny); j += 2)
840 for (
unsigned int i=0; i<(2*nx); i += 2)
874 for (
unsigned int j=0; j<(2*ny); j += 2)
875 for (
unsigned int i=0; i<(2*nx); i += 2)
921 std::vector<Node *> node_list;
924 const auto dx_tri = (xmax - xmin) / (nx);
925 const auto dy_tri = (ymax - ymin) / (ny + 1);
926 std::unique_ptr<Elem> new_elem;
930 Node *node0, *node1, *node2;
933 node0 =
mesh.add_point(
Point(0., 0, 0.));
934 node1 =
mesh.add_point(
Point(0., dy_tri / 2., 0.));
935 node2 =
mesh.add_point(
Point(dx_tri / 2., 0., 0.));
936 node_list.push_back(node0);
937 node_list.push_back(node1);
938 node_list.push_back(node2);
942 node0 = node_list.back();
943 node1 =
mesh.add_point(
Point((i)*dx_tri, dy_tri / 2., 0.));
944 node2 =
mesh.add_point(
Point((i + 1. / 2.) * dx_tri, 0., 0.));
945 node_list.push_back(node1);
946 node_list.push_back(node2);
950 node0 = node_list.back();
951 node1 =
mesh.add_point(
Point((i)*dx_tri, dy_tri / 2., 0.));
952 node2 =
mesh.add_point(
Point((i)*dx_tri, 0., 0.));
953 node_list.push_back(node1);
954 node_list.push_back(node2);
957 new_elem = std::make_unique<C0Polygon>(3);
959 new_elem->set_node(0, node0);
960 new_elem->set_node(1, node1);
961 new_elem->set_node(2, node2);
962 auto * elem =
mesh.add_elem(std::move(new_elem));
972 unsigned int running_index = 1;
975 const auto hex_side =
976 (ymax - ymin - (ny == 1 ? dy_tri : (1. + (ny - 1) / 2.) * dy_tri)) / ny;
981 if ((j % 2 == 0) || ((i > 0) && (i < nx)))
983 Node *n0, *n1, *n2, *n3, *n4, *n5;
984 n0 = node_list[running_index++];
985 n1 = node_list[running_index++];
986 n2 = node_list[running_index];
991 node_list.push_back(n3);
994 n3 = node_list.back();
998 node_list.push_back(n4);
999 node_list.push_back(n5);
1001 new_elem = std::make_unique<libMesh::C0Polygon>(6);
1002 new_elem->set_node(0, n0);
1003 new_elem->set_node(1, n1);
1004 new_elem->set_node(2, n2);
1005 new_elem->set_node(3, n5);
1006 new_elem->set_node(4, n4);
1007 new_elem->set_node(5, n3);
1008 auto * elem =
mesh.add_elem(std::move(new_elem));
1012 boundary_info.
add_side(elem, 5, 3);
1014 boundary_info.
add_side(elem, 2, 1);
1017 else if (i == 0 || i == nx)
1019 Node *n0, *n1, *n2, *n3;
1020 n0 = node_list[running_index++];
1021 n1 = node_list[running_index];
1026 node_list.push_back(n2);
1031 n2 = node_list.back();
1034 node_list.push_back(n3);
1036 new_elem = std::make_unique<C0Polygon>(4);
1038 new_elem->set_node(0, n0);
1039 new_elem->set_node(1, n1);
1040 new_elem->set_node(3, n2);
1041 new_elem->set_node(2, n3);
1042 auto * elem =
mesh.add_elem(std::move(new_elem));
1046 boundary_info.
add_side(elem, 3, 3);
1048 boundary_info.
add_side(elem, 1, 1);
1062 const bool ny_odd = (ny % 2 == 1);
1066 Node *node0, *node1, *node2;
1067 if (i == 0 && ny_odd)
1069 node0 =
mesh.add_point(
Point(0., ymax, 0.));
1070 node1 = node_list[running_index++];
1071 node2 = node_list[running_index];
1075 node0 = node_list[running_index++];
1076 node1 = node_list[running_index++];
1077 node2 = node_list[running_index];
1082 node0 = node_list[running_index++];
1083 node1 = node_list[running_index];
1084 node2 =
mesh.add_point(
Point(xmax, ymax, 0.));
1087 new_elem = std::make_unique<C0Polygon>(3);
1089 new_elem->set_node(0, node0);
1090 new_elem->set_node(1, node1);
1091 new_elem->set_node(2, node2);
1092 auto * elem =
mesh.add_elem(std::move(new_elem));
1096 boundary_info.
add_side(elem, 0, 3);
1098 boundary_info.
add_side(elem, 1, 1);
1099 boundary_info.
add_side(elem, 2, 2);
1114 if (gauss_lobatto_grid)
1116 GaussLobattoRedistributionFunction func(nx, xmin, xmax,
1122 for (
Node * node :
mesh.node_ptr_range())
1124 (*node)(0) = ((*node)(0))*(xmax-xmin) + xmin;
1125 (*node)(1) = ((*node)(1))*(ymax-ymin) + ymin;
1158 libmesh_assert_not_equal_to (nx, 0);
1159 libmesh_assert_not_equal_to (ny, 0);
1160 libmesh_assert_not_equal_to (nz, 0);
1161 libmesh_assert_less (xmin, xmax);
1162 libmesh_assert_less (ymin, ymax);
1163 libmesh_assert_less (zmin, zmax);
1182 mesh.reserve_elem(nx*ny*nz);
1192 mesh.reserve_elem(2*nx*ny*nz);
1211 mesh.reserve_nodes( (nx+1)*(ny+1)*(nz+1) );
1230 mesh.reserve_nodes( (2*nx+1)*(2*ny+1)*(2*nz+1) );
1236 mesh.reserve_nodes( (2*nx+1)*(2*ny+1)*(2*nz+1) +
1238 4*(nx*ny + ny*nz + nx*nz) );
1244 mesh.reserve_nodes( (2*nx+1)*(2*ny+1)*(2*nz+1) +
1251 mesh.reserve_nodes( (2*nx+1)*(2*ny+1)*(2*nz+1) +
1264 unsigned int node_id = 0;
1271 for (
unsigned int k=0; k<=nz; k++)
1272 for (
unsigned int j=0; j<=ny; j++)
1273 for (
unsigned int i=0; i<=nx; i++)
1275 const Node *
const node =
1276 mesh.add_point(
Point(static_cast<Real>(i) / static_cast<Real>(nx),
1277 static_cast<Real>(j) / static_cast<Real>(ny),
1278 static_cast<Real>(k) / static_cast<Real>(nz)),
1311 for (
unsigned int k=0; k<=(2*nz); k++)
1312 for (
unsigned int j=0; j<=(2*ny); j++)
1313 for (
unsigned int i=0; i<=(2*nx); i++)
1315 const Node *
const node =
1316 mesh.add_point(
Point(static_cast<Real>(i) / static_cast<Real>(2 * nx),
1317 static_cast<Real>(j) / static_cast<Real>(2 * ny),
1318 static_cast<Real>(k) / static_cast<Real>(2 * nz)),
1337 const unsigned int kmax = (type ==
PRISM20) ? nz : 2*nz;
1338 for (
unsigned int k=0; k<=kmax; k++)
1339 for (
unsigned int j=0; j<ny; j++)
1340 for (
unsigned int i=0; i<nx; i++)
1342 const Node *
const node1 =
1343 mesh.add_point(
Point((static_cast<Real>(i)+1/
Real(3)) / static_cast<Real>(nx),
1344 (static_cast<Real>(j)+1/
Real(3)) / static_cast<Real>(ny),
1345 static_cast<Real>(k) / static_cast<Real>(kmax)),
1352 const Node *
const node2 =
1353 mesh.add_point(
Point((static_cast<Real>(i)+2/
Real(3)) / static_cast<Real>(nx),
1354 (static_cast<Real>(j)+2/
Real(3)) / static_cast<Real>(ny),
1355 static_cast<Real>(k) / static_cast<Real>(kmax)),
1376 unsigned int elem_id = 0;
1382 for (
unsigned int k=0; k<nz; k++)
1383 for (
unsigned int j=0; j<ny; j++)
1384 for (
unsigned int i=0; i<nx; i++)
1397 boundary_info.
add_side(elem, 0, 0);
1400 boundary_info.
add_side(elem, 5, 5);
1403 boundary_info.
add_side(elem, 1, 1);
1406 boundary_info.
add_side(elem, 3, 3);
1409 boundary_info.
add_side(elem, 4, 4);
1412 boundary_info.
add_side(elem, 2, 2);
1422 for (
unsigned int k=0; k<nz; k++)
1423 for (
unsigned int j=0; j<ny; j++)
1424 for (
unsigned int i=0; i<nx; i++)
1437 boundary_info.
add_side(elem, 3, 4);
1440 boundary_info.
add_side(elem, 1, 1);
1443 boundary_info.
add_side(elem, 0, 0);
1446 boundary_info.
add_side(elem, 4, 5);
1459 boundary_info.
add_side(elem, 1, 2);
1462 boundary_info.
add_side(elem, 2, 3);
1465 boundary_info.
add_side(elem, 0, 0);
1468 boundary_info.
add_side(elem, 4, 5);
1488 for (
unsigned int k=0; k<(2*nz); k += 2)
1489 for (
unsigned int j=0; j<(2*ny); j += 2)
1490 for (
unsigned int i=0; i<(2*nx); i += 2)
1530 boundary_info.
add_side(elem, 0, 0);
1533 boundary_info.
add_side(elem, 5, 5);
1536 boundary_info.
add_side(elem, 1, 1);
1539 boundary_info.
add_side(elem, 3, 3);
1542 boundary_info.
add_side(elem, 4, 4);
1545 boundary_info.
add_side(elem, 2, 2);
1558 for (
unsigned int k=0; k<(2*nz); k += 2)
1559 for (
unsigned int j=0; j<(2*ny); j += 2)
1560 for (
unsigned int i=0; i<(2*nx); i += 2)
1591 const dof_id_type base_idx = (2*nx+1)*(2*ny+1)*(2*nz+1);
1592 elem->
set_node(18,
mesh.node_ptr(base_idx+((k/2)*(nx*ny)+j/2*nx+i/2)*2));
1593 elem->
set_node(19,
mesh.node_ptr(base_idx+(((k/2)+1)*(nx*ny)+j/2*nx+i/2)*2));
1598 const dof_id_type base_idx = (2*nx+1)*(2*ny+1)*(2*nz+1);
1599 elem->
set_node(18,
mesh.node_ptr(base_idx+(k*(nx*ny)+j/2*nx+i/2)*2));
1600 elem->
set_node(19,
mesh.node_ptr(base_idx+((k+2)*(nx*ny)+j/2*nx+i/2)*2));
1601 elem->
set_node(20,
mesh.node_ptr(base_idx+((k+1)*(nx*ny)+j/2*nx+i/2)*2));
1606 boundary_info.
add_side(elem, 3, 4);
1609 boundary_info.
add_side(elem, 1, 1);
1612 boundary_info.
add_side(elem, 0, 0);
1615 boundary_info.
add_side(elem, 4, 5);
1647 const dof_id_type base_idx = (2*nx+1)*(2*ny+1)*(2*nz+1);
1648 elem->
set_node(18,
mesh.node_ptr(base_idx+((k/2)*(nx*ny)+j/2*nx+i/2)*2+1));
1649 elem->
set_node(19,
mesh.node_ptr(base_idx+(((k/2)+1)*(nx*ny)+j/2*nx+i/2)*2+1));
1654 const dof_id_type base_idx = (2*nx+1)*(2*ny+1)*(2*nz+1);
1655 elem->
set_node(18,
mesh.node_ptr(base_idx+(k*(nx*ny)+j/2*nx+i/2)*2+1));
1656 elem->
set_node(19,
mesh.node_ptr(base_idx+((k+2)*(nx*ny)+j/2*nx+i/2)*2+1));
1657 elem->
set_node(20,
mesh.node_ptr(base_idx+((k+1)*(nx*ny)+j/2*nx+i/2)*2+1));
1662 boundary_info.
add_side(elem, 1, 2);
1665 boundary_info.
add_side(elem, 2, 3);
1668 boundary_info.
add_side(elem, 0, 0);
1671 boundary_info.
add_side(elem, 4, 5);
1690 if (gauss_lobatto_grid)
1692 GaussLobattoRedistributionFunction func(nx, xmin, xmax,
1699 for (
unsigned int p=0; p<
mesh.n_nodes(); p++)
1701 mesh.node_ref(p)(0) = (
mesh.node_ref(p)(0))*(xmax-xmin) + xmin;
1702 mesh.node_ref(p)(1) = (
mesh.node_ref(p)(1))*(ymax-ymin) + ymin;
1703 mesh.node_ref(p)(2) = (
mesh.node_ref(p)(2))*(zmax-zmin) + zmin;
1716 if ((type ==
TET4) ||
1725 std::vector<std::unique_ptr<Elem>> new_elements;
1728 std::unique_ptr<Elem> side;
1731 new_elements.reserve(24*
mesh.n_elem());
1733 new_elements.reserve(6*
mesh.n_elem());
1736 for (
auto & base_hex :
mesh.element_ptr_range())
1739 Node * apex_node = base_hex->node_ptr(26);
1742 std::vector<boundary_id_type> ids;
1744 for (
auto s : base_hex->side_index_range())
1756 base_hex->build_side_ptr(side, s);
1761 for (
unsigned int sub_tet=0; sub_tet<4; ++sub_tet)
1764 auto & sub_elem = new_elements.back();
1765 sub_elem->set_node(0, side->node_ptr(sub_tet));
1766 sub_elem->set_node(1, side->node_ptr(8));
1767 sub_elem->set_node(2, side->node_ptr(sub_tet==3 ? 0 : sub_tet+1 ));
1768 sub_elem->set_node(3, apex_node);
1774 boundary_info.
add_side(sub_elem.get(), 0, b_id);
1782 auto & sub_elem = new_elements.back();
1787 sub_elem->set_node(0, side->node_ptr(0));
1788 sub_elem->set_node(1, side->node_ptr(3));
1789 sub_elem->set_node(2, side->node_ptr(2));
1790 sub_elem->set_node(3, side->node_ptr(1));
1793 sub_elem->set_node(4, apex_node);
1798 boundary_info.
add_side(sub_elem.get(), 4, b_id);
1805 for (
auto & elem :
mesh.element_ptr_range())
1807 boundary_info.
remove(elem);
1808 mesh.delete_elem(elem);
1814 new_elements[i]->set_id(i);
1815 mesh.add_elem( std::move(new_elements[i]) );
1823 mesh.all_second_order();
1826 mesh.all_second_order(
false);
1829 mesh.all_complete_order();
1852 libmesh_error_msg(
"Unknown dimension " <<
mesh.mesh_dimension());
1856 mesh.prepare_for_use ();
1863 const bool gauss_lobatto_grid)
1875 gauss_lobatto_grid);
1880 const unsigned int nx,
1883 const bool gauss_lobatto_grid)
1895 gauss_lobatto_grid);
1901 const unsigned int nx,
1902 const unsigned int ny,
1906 const bool gauss_lobatto_grid)
1919 gauss_lobatto_grid);
1930 #ifndef LIBMESH_ENABLE_AMR 1938 libmesh_error_msg(
"Building a circle/sphere only works with AMR.");
1945 const unsigned int nr,
1947 const unsigned int n_smooth,
1950 libmesh_assert_greater (rad, 0.);
1953 LOG_SCOPE(
"build_sphere()",
"MeshTools::Generation");
1959 unsigned char orig_mesh_dimension =
2001 libmesh_error_msg(
"build_sphere(): Please specify a mesh dimension or a valid ElemType (EDGE{2,3,4}, TRI{3,6,7}, QUAD{4,8,9}, HEX{8,27}, TET{4,10,14})");
2013 const Sphere sphere (cent, rad);
2037 unsigned node_id = 0;
2041 const Real sqrt_2 = std::sqrt(2.);
2042 const Real rad_2 = .25*rad;
2043 const Real rad_sqrt_2 = rad/sqrt_2;
2046 std::vector<Node *> nodes(8);
2049 nodes[0] =
mesh.
add_point (Point(-rad_2,-rad_2, 0.), node_id++);
2052 nodes[1] =
mesh.
add_point (Point( rad_2,-rad_2, 0.), node_id++);
2055 nodes[2] =
mesh.
add_point (Point( rad_2, rad_2, 0.), node_id++);
2058 nodes[3] =
mesh.
add_point (Point(-rad_2, rad_2, 0.), node_id++);
2061 nodes[4] =
mesh.
add_point (Point(-rad_sqrt_2,-rad_sqrt_2, 0.), node_id++);
2064 nodes[5] =
mesh.
add_point (Point( rad_sqrt_2,-rad_sqrt_2, 0.), node_id++);
2067 nodes[6] =
mesh.
add_point (Point( rad_sqrt_2, rad_sqrt_2, 0.), node_id++);
2070 nodes[7] =
mesh.
add_point (Point(-rad_sqrt_2, rad_sqrt_2, 0.), node_id++);
2078 elem0->set_node(1, nodes[1]);
2079 elem0->set_node(2, nodes[2]);
2080 elem0->set_node(3, nodes[3]);
2087 elem1->set_node(1, nodes[0]);
2088 elem1->set_node(2, nodes[3]);
2089 elem1->set_node(3, nodes[7]);
2096 elem2->set_node(1, nodes[5]);
2097 elem2->set_node(2, nodes[1]);
2098 elem2->set_node(3, nodes[0]);
2105 elem3->set_node(1, nodes[5]);
2106 elem3->set_node(2, nodes[6]);
2107 elem3->set_node(3, nodes[2]);
2114 elem4->set_node(1, nodes[2]);
2115 elem4->set_node(2, nodes[6]);
2116 elem4->set_node(3, nodes[7]);
2123 Real t = 0.5 * (1 + std::sqrt(5.0));
2124 Real s = rad / std::sqrt(1 + t*t);
2143 static const unsigned int idx1 [6] = {11, 5, 1, 7, 10, 11};
2144 static const unsigned int idx2 [6] = {9, 4, 2, 6, 8, 9};
2145 static const unsigned int idx3 [6] = {1, 5, 11, 10, 7, 1};
2147 for (
unsigned int i = 0; i < 5; ++i)
2187 if (!((type ==
HEX8) || (type ==
HEX27) || (type ==
TET4) ||
2190 libmesh_error_msg(
"Error: Only HEX8/27 and TET4/10/14 are currently supported in 3D.");
2197 r_med = (0.125*std::sqrt(2.)+0.5)*rad;
2200 std::vector<Node *> nodes(16);
2206 unsigned node_id = 0;
2209 nodes[0] =
mesh.
add_point (Point(-r_small,-r_small, -r_small), node_id++);
2210 nodes[1] =
mesh.
add_point (Point( r_small,-r_small, -r_small), node_id++);
2211 nodes[2] =
mesh.
add_point (Point( r_small, r_small, -r_small), node_id++);
2212 nodes[3] =
mesh.
add_point (Point(-r_small, r_small, -r_small), node_id++);
2213 nodes[4] =
mesh.
add_point (Point(-r_small,-r_small, r_small), node_id++);
2214 nodes[5] =
mesh.
add_point (Point( r_small,-r_small, r_small), node_id++);
2215 nodes[6] =
mesh.
add_point (Point( r_small, r_small, r_small), node_id++);
2216 nodes[7] =
mesh.
add_point (Point(-r_small, r_small, r_small), node_id++);
2219 nodes[8] =
mesh.
add_point (Point(-r_med,-r_med, -r_med), node_id++);
2220 nodes[9] =
mesh.
add_point (Point( r_med,-r_med, -r_med), node_id++);
2221 nodes[10] =
mesh.
add_point (Point( r_med, r_med, -r_med), node_id++);
2222 nodes[11] =
mesh.
add_point (Point(-r_med, r_med, -r_med), node_id++);
2223 nodes[12] =
mesh.
add_point (Point(-r_med,-r_med, r_med), node_id++);
2224 nodes[13] =
mesh.
add_point (Point( r_med,-r_med, r_med), node_id++);
2225 nodes[14] =
mesh.
add_point (Point( r_med, r_med, r_med), node_id++);
2226 nodes[15] =
mesh.
add_point (Point(-r_med, r_med, r_med), node_id++);
2233 elem0->set_node(1, nodes[1]);
2234 elem0->set_node(2, nodes[2]);
2235 elem0->set_node(3, nodes[3]);
2236 elem0->set_node(4, nodes[4]);
2237 elem0->set_node(5, nodes[5]);
2238 elem0->set_node(6, nodes[6]);
2239 elem0->set_node(7, nodes[7]);
2246 elem1->set_node(1, nodes[9]);
2247 elem1->set_node(2, nodes[10]);
2248 elem1->set_node(3, nodes[11]);
2249 elem1->set_node(4, nodes[0]);
2250 elem1->set_node(5, nodes[1]);
2251 elem1->set_node(6, nodes[2]);
2252 elem1->set_node(7, nodes[3]);
2259 elem2->set_node(1, nodes[9]);
2260 elem2->set_node(2, nodes[1]);
2261 elem2->set_node(3, nodes[0]);
2262 elem2->set_node(4, nodes[12]);
2263 elem2->set_node(5, nodes[13]);
2264 elem2->set_node(6, nodes[5]);
2265 elem2->set_node(7, nodes[4]);
2272 elem3->set_node(1, nodes[9]);
2273 elem3->set_node(2, nodes[10]);
2274 elem3->set_node(3, nodes[2]);
2275 elem3->set_node(4, nodes[5]);
2276 elem3->set_node(5, nodes[13]);
2277 elem3->set_node(6, nodes[14]);
2278 elem3->set_node(7, nodes[6]);
2285 elem4->set_node(1, nodes[2]);
2286 elem4->set_node(2, nodes[10]);
2287 elem4->set_node(3, nodes[11]);
2288 elem4->set_node(4, nodes[7]);
2289 elem4->set_node(5, nodes[6]);
2290 elem4->set_node(6, nodes[14]);
2291 elem4->set_node(7, nodes[15]);
2298 elem5->set_node(1, nodes[0]);
2299 elem5->set_node(2, nodes[3]);
2300 elem5->set_node(3, nodes[11]);
2301 elem5->set_node(4, nodes[12]);
2302 elem5->set_node(5, nodes[4]);
2303 elem5->set_node(6, nodes[7]);
2304 elem5->set_node(7, nodes[15]);
2311 elem6->set_node(1, nodes[5]);
2312 elem6->set_node(2, nodes[6]);
2313 elem6->set_node(3, nodes[7]);
2314 elem6->set_node(4, nodes[12]);
2315 elem6->set_node(5, nodes[13]);
2316 elem6->set_node(6, nodes[14]);
2317 elem6->set_node(7, nodes[15]);
2333 MeshRefinement mesh_refinement (
mesh);
2336 std::unique_ptr<Elem> side;
2339 for (
unsigned int r=0; r<nr; r++)
2343 std::unordered_set<dof_id_type> moved_ghost_nodes;
2347 mesh_refinement.uniformly_refine(1);
2349 for (
const auto & elem :
mesh.active_element_ptr_range())
2350 for (
auto s : elem->side_index_range())
2353 elem->build_side_ptr(side, s);
2358 for (
auto n : side->node_index_range())
2360 Node & side_node = side->node_ref(n);
2362 sphere.closest_point(side->point(n));
2364 if (!is_replicated &&
2366 moved_ghost_nodes.insert(side_node.id());
2372 std::map<processor_id_type, std::vector<dof_id_type>> moved_nodes_map;
2373 for (
auto id : moved_ghost_nodes)
2376 moved_nodes_map[node.processor_id()].push_back(node.id());
2379 auto action_functor =
2382 const std::vector<dof_id_type> & my_moved_nodes)
2384 for (
auto id : my_moved_nodes)
2387 node = sphere.closest_point(node);
2392 Parallel::push_parallel_vector_data
2393 (
mesh.
comm(), moved_nodes_map, action_functor);
2396 SyncNodalPositions sync_object(
mesh);
2414 if ((type ==
TRI7) || (type ==
TRI6) || (type ==
TRI3) ||
2435 bool full_ordered = !((type==
QUAD8) || (type==
HEX20));
2440 for (
const auto & elem :
mesh.active_element_ptr_range())
2441 for (
auto s : elem->side_index_range())
2442 if (elem->neighbor_ptr(s) ==
nullptr)
2444 elem->build_side_ptr(side, s);
2447 for (
auto n : side->node_index_range())
2449 sphere.closest_point(side->point(n));
2457 LaplaceMeshSmoother smoother(
mesh, n_smooth);
2462 for (
const auto & elem :
mesh.active_element_ptr_range())
2463 for (
auto s : elem->side_index_range())
2464 if (!elem->neighbor_ptr(s))
2465 boundary_info.add_side(elem, s, 0);
2471 #endif // #ifndef LIBMESH_ENABLE_AMR 2477 const unsigned int nz,
2481 LOG_SCOPE(
"build_extrusion()",
"MeshTools::Generation");
2483 if (!cross_section.
n_elem())
2489 #ifdef LIBMESH_ENABLE_UNIQUE_ID 2493 unsigned int order = 1;
2514 if (cross_section.elements_begin() != cross_section.elements_end() &&
2515 (*cross_section.elements_begin())->default_order() ==
SECOND)
2522 std::vector<boundary_id_type> ids_to_copy;
2524 for (
const auto & node : cross_section.node_ptr_range())
2526 for (
unsigned int k=0; k != order*nz+1; ++k)
2528 const dof_id_type new_node_id = node->id() + k * orig_nodes;
2533 (*node + (extrusion_vector * k / nz / order),
2535 new_node->processor_id() = node->processor_id();
2537 #ifdef LIBMESH_ENABLE_UNIQUE_ID 2543 orig_unique_ids + (k-1)*(orig_nodes + orig_elem) + node->id();
2545 new_node->set_unique_id(uid);
2548 cross_section_boundary_info.
boundary_ids(node, ids_to_copy);
2549 boundary_info.
add_node(new_node.get(), ids_to_copy);
2556 const std::set<boundary_id_type> & side_ids =
2560 0 : cast_int<boundary_id_type>(*side_ids.rbegin() + 1);
2565 cross_section.
comm().
max(next_side_id);
2567 for (
const auto & elem : cross_section.element_ptr_range())
2569 const ElemType etype = elem->type();
2574 for (
unsigned int k=0; k != nz; ++k)
2576 std::unique_ptr<Elem> new_elem;
2582 new_elem->set_node(0,
mesh.
node_ptr(elem->node_ptr(0)->id() + (k * orig_nodes)));
2583 new_elem->set_node(1,
mesh.
node_ptr(elem->node_ptr(1)->id() + (k * orig_nodes)));
2584 new_elem->set_node(2,
mesh.
node_ptr(elem->node_ptr(1)->id() + ((k+1) * orig_nodes)));
2585 new_elem->set_node(3,
mesh.
node_ptr(elem->node_ptr(0)->id() + ((k+1) * orig_nodes)));
2588 new_elem->set_neighbor(3, const_cast<RemoteElem *>(
remote_elem));
2590 new_elem->set_neighbor(1, const_cast<RemoteElem *>(
remote_elem));
2597 new_elem->set_node(0,
mesh.
node_ptr(elem->node_ptr(0)->id() + (2*k * orig_nodes)));
2598 new_elem->set_node(1,
mesh.
node_ptr(elem->node_ptr(1)->id() + (2*k * orig_nodes)));
2599 new_elem->set_node(2,
mesh.
node_ptr(elem->node_ptr(1)->id() + ((2*k+2) * orig_nodes)));
2600 new_elem->set_node(3,
mesh.
node_ptr(elem->node_ptr(0)->id() + ((2*k+2) * orig_nodes)));
2601 new_elem->set_node(4,
mesh.
node_ptr(elem->node_ptr(2)->id() + (2*k * orig_nodes)));
2602 new_elem->set_node(5,
mesh.
node_ptr(elem->node_ptr(1)->id() + ((2*k+1) * orig_nodes)));
2603 new_elem->set_node(6,
mesh.
node_ptr(elem->node_ptr(2)->id() + ((2*k+2) * orig_nodes)));
2604 new_elem->set_node(7,
mesh.
node_ptr(elem->node_ptr(0)->id() + ((2*k+1) * orig_nodes)));
2605 new_elem->set_node(8,
mesh.
node_ptr(elem->node_ptr(2)->id() + ((2*k+1) * orig_nodes)));
2608 new_elem->set_neighbor(3, const_cast<RemoteElem *>(
remote_elem));
2610 new_elem->set_neighbor(1, const_cast<RemoteElem *>(
remote_elem));
2617 new_elem->set_node(0,
mesh.
node_ptr(elem->node_ptr(0)->id() + (k * orig_nodes)));
2618 new_elem->set_node(1,
mesh.
node_ptr(elem->node_ptr(1)->id() + (k * orig_nodes)));
2619 new_elem->set_node(2,
mesh.
node_ptr(elem->node_ptr(2)->id() + (k * orig_nodes)));
2620 new_elem->set_node(3,
mesh.
node_ptr(elem->node_ptr(0)->id() + ((k+1) * orig_nodes)));
2621 new_elem->set_node(4,
mesh.
node_ptr(elem->node_ptr(1)->id() + ((k+1) * orig_nodes)));
2622 new_elem->set_node(5,
mesh.
node_ptr(elem->node_ptr(2)->id() + ((k+1) * orig_nodes)));
2625 new_elem->set_neighbor(1, const_cast<RemoteElem *>(
remote_elem));
2627 new_elem->set_neighbor(2, const_cast<RemoteElem *>(
remote_elem));
2629 new_elem->set_neighbor(3, const_cast<RemoteElem *>(
remote_elem));
2636 new_elem->set_node(0,
mesh.
node_ptr(elem->node_ptr(0)->id() + (2*k * orig_nodes)));
2637 new_elem->set_node(1,
mesh.
node_ptr(elem->node_ptr(1)->id() + (2*k * orig_nodes)));
2638 new_elem->set_node(2,
mesh.
node_ptr(elem->node_ptr(2)->id() + (2*k * orig_nodes)));
2639 new_elem->set_node(3,
mesh.
node_ptr(elem->node_ptr(0)->id() + ((2*k+2) * orig_nodes)));
2640 new_elem->set_node(4,
mesh.
node_ptr(elem->node_ptr(1)->id() + ((2*k+2) * orig_nodes)));
2641 new_elem->set_node(5,
mesh.
node_ptr(elem->node_ptr(2)->id() + ((2*k+2) * orig_nodes)));
2642 new_elem->set_node(6,
mesh.
node_ptr(elem->node_ptr(3)->id() + (2*k * orig_nodes)));
2643 new_elem->set_node(7,
mesh.
node_ptr(elem->node_ptr(4)->id() + (2*k * orig_nodes)));
2644 new_elem->set_node(8,
mesh.
node_ptr(elem->node_ptr(5)->id() + (2*k * orig_nodes)));
2645 new_elem->set_node(9,
mesh.
node_ptr(elem->node_ptr(0)->id() + ((2*k+1) * orig_nodes)));
2646 new_elem->set_node(10,
mesh.
node_ptr(elem->node_ptr(1)->id() + ((2*k+1) * orig_nodes)));
2647 new_elem->set_node(11,
mesh.
node_ptr(elem->node_ptr(2)->id() + ((2*k+1) * orig_nodes)));
2648 new_elem->set_node(12,
mesh.
node_ptr(elem->node_ptr(3)->id() + ((2*k+2) * orig_nodes)));
2649 new_elem->set_node(13,
mesh.
node_ptr(elem->node_ptr(4)->id() + ((2*k+2) * orig_nodes)));
2650 new_elem->set_node(14,
mesh.
node_ptr(elem->node_ptr(5)->id() + ((2*k+2) * orig_nodes)));
2651 new_elem->set_node(15,
mesh.
node_ptr(elem->node_ptr(3)->id() + ((2*k+1) * orig_nodes)));
2652 new_elem->set_node(16,
mesh.
node_ptr(elem->node_ptr(4)->id() + ((2*k+1) * orig_nodes)));
2653 new_elem->set_node(17,
mesh.
node_ptr(elem->node_ptr(5)->id() + ((2*k+1) * orig_nodes)));
2656 new_elem->set_neighbor(1, const_cast<RemoteElem *>(
remote_elem));
2658 new_elem->set_neighbor(2, const_cast<RemoteElem *>(
remote_elem));
2660 new_elem->set_neighbor(3, const_cast<RemoteElem *>(
remote_elem));
2667 new_elem->set_node(0,
mesh.
node_ptr(elem->node_ptr(0)->id() + (2*k * orig_nodes)));
2668 new_elem->set_node(1,
mesh.
node_ptr(elem->node_ptr(1)->id() + (2*k * orig_nodes)));
2669 new_elem->set_node(2,
mesh.
node_ptr(elem->node_ptr(2)->id() + (2*k * orig_nodes)));
2670 new_elem->set_node(3,
mesh.
node_ptr(elem->node_ptr(0)->id() + ((2*k+2) * orig_nodes)));
2671 new_elem->set_node(4,
mesh.
node_ptr(elem->node_ptr(1)->id() + ((2*k+2) * orig_nodes)));
2672 new_elem->set_node(5,
mesh.
node_ptr(elem->node_ptr(2)->id() + ((2*k+2) * orig_nodes)));
2673 new_elem->set_node(6,
mesh.
node_ptr(elem->node_ptr(3)->id() + (2*k * orig_nodes)));
2674 new_elem->set_node(7,
mesh.
node_ptr(elem->node_ptr(4)->id() + (2*k * orig_nodes)));
2675 new_elem->set_node(8,
mesh.
node_ptr(elem->node_ptr(5)->id() + (2*k * orig_nodes)));
2676 new_elem->set_node(9,
mesh.
node_ptr(elem->node_ptr(0)->id() + ((2*k+1) * orig_nodes)));
2677 new_elem->set_node(10,
mesh.
node_ptr(elem->node_ptr(1)->id() + ((2*k+1) * orig_nodes)));
2678 new_elem->set_node(11,
mesh.
node_ptr(elem->node_ptr(2)->id() + ((2*k+1) * orig_nodes)));
2679 new_elem->set_node(12,
mesh.
node_ptr(elem->node_ptr(3)->id() + ((2*k+2) * orig_nodes)));
2680 new_elem->set_node(13,
mesh.
node_ptr(elem->node_ptr(4)->id() + ((2*k+2) * orig_nodes)));
2681 new_elem->set_node(14,
mesh.
node_ptr(elem->node_ptr(5)->id() + ((2*k+2) * orig_nodes)));
2682 new_elem->set_node(15,
mesh.
node_ptr(elem->node_ptr(3)->id() + ((2*k+1) * orig_nodes)));
2683 new_elem->set_node(16,
mesh.
node_ptr(elem->node_ptr(4)->id() + ((2*k+1) * orig_nodes)));
2684 new_elem->set_node(17,
mesh.
node_ptr(elem->node_ptr(5)->id() + ((2*k+1) * orig_nodes)));
2686 new_elem->set_node(18,
mesh.
node_ptr(elem->node_ptr(6)->id() + (2*k * orig_nodes)));
2687 new_elem->set_node(19,
mesh.
node_ptr(elem->node_ptr(6)->id() + ((2*k+2) * orig_nodes)));
2688 new_elem->set_node(20,
mesh.
node_ptr(elem->node_ptr(6)->id() + ((2*k+1) * orig_nodes)));
2691 new_elem->set_neighbor(1, const_cast<RemoteElem *>(
remote_elem));
2693 new_elem->set_neighbor(2, const_cast<RemoteElem *>(
remote_elem));
2695 new_elem->set_neighbor(3, const_cast<RemoteElem *>(
remote_elem));
2702 new_elem->set_node(0,
mesh.
node_ptr(elem->node_ptr(0)->id() + (k * orig_nodes)));
2703 new_elem->set_node(1,
mesh.
node_ptr(elem->node_ptr(1)->id() + (k * orig_nodes)));
2704 new_elem->set_node(2,
mesh.
node_ptr(elem->node_ptr(2)->id() + (k * orig_nodes)));
2705 new_elem->set_node(3,
mesh.
node_ptr(elem->node_ptr(3)->id() + (k * orig_nodes)));
2706 new_elem->set_node(4,
mesh.
node_ptr(elem->node_ptr(0)->id() + ((k+1) * orig_nodes)));
2707 new_elem->set_node(5,
mesh.
node_ptr(elem->node_ptr(1)->id() + ((k+1) * orig_nodes)));
2708 new_elem->set_node(6,
mesh.
node_ptr(elem->node_ptr(2)->id() + ((k+1) * orig_nodes)));
2709 new_elem->set_node(7,
mesh.
node_ptr(elem->node_ptr(3)->id() + ((k+1) * orig_nodes)));
2712 new_elem->set_neighbor(1, const_cast<RemoteElem *>(
remote_elem));
2714 new_elem->set_neighbor(2, const_cast<RemoteElem *>(
remote_elem));
2716 new_elem->set_neighbor(3, const_cast<RemoteElem *>(
remote_elem));
2718 new_elem->set_neighbor(4, const_cast<RemoteElem *>(
remote_elem));
2725 new_elem->set_node(0,
mesh.
node_ptr(elem->node_ptr(0)->id() + (2*k * orig_nodes)));
2726 new_elem->set_node(1,
mesh.
node_ptr(elem->node_ptr(1)->id() + (2*k * orig_nodes)));
2727 new_elem->set_node(2,
mesh.
node_ptr(elem->node_ptr(2)->id() + (2*k * orig_nodes)));
2728 new_elem->set_node(3,
mesh.
node_ptr(elem->node_ptr(3)->id() + (2*k * orig_nodes)));
2729 new_elem->set_node(4,
mesh.
node_ptr(elem->node_ptr(0)->id() + ((2*k+2) * orig_nodes)));
2730 new_elem->set_node(5,
mesh.
node_ptr(elem->node_ptr(1)->id() + ((2*k+2) * orig_nodes)));
2731 new_elem->set_node(6,
mesh.
node_ptr(elem->node_ptr(2)->id() + ((2*k+2) * orig_nodes)));
2732 new_elem->set_node(7,
mesh.
node_ptr(elem->node_ptr(3)->id() + ((2*k+2) * orig_nodes)));
2733 new_elem->set_node(8,
mesh.
node_ptr(elem->node_ptr(4)->id() + (2*k * orig_nodes)));
2734 new_elem->set_node(9,
mesh.
node_ptr(elem->node_ptr(5)->id() + (2*k * orig_nodes)));
2735 new_elem->set_node(10,
mesh.
node_ptr(elem->node_ptr(6)->id() + (2*k * orig_nodes)));
2736 new_elem->set_node(11,
mesh.
node_ptr(elem->node_ptr(7)->id() + (2*k * orig_nodes)));
2737 new_elem->set_node(12,
mesh.
node_ptr(elem->node_ptr(0)->id() + ((2*k+1) * orig_nodes)));
2738 new_elem->set_node(13,
mesh.
node_ptr(elem->node_ptr(1)->id() + ((2*k+1) * orig_nodes)));
2739 new_elem->set_node(14,
mesh.
node_ptr(elem->node_ptr(2)->id() + ((2*k+1) * orig_nodes)));
2740 new_elem->set_node(15,
mesh.
node_ptr(elem->node_ptr(3)->id() + ((2*k+1) * orig_nodes)));
2741 new_elem->set_node(16,
mesh.
node_ptr(elem->node_ptr(4)->id() + ((2*k+2) * orig_nodes)));
2742 new_elem->set_node(17,
mesh.
node_ptr(elem->node_ptr(5)->id() + ((2*k+2) * orig_nodes)));
2743 new_elem->set_node(18,
mesh.
node_ptr(elem->node_ptr(6)->id() + ((2*k+2) * orig_nodes)));
2744 new_elem->set_node(19,
mesh.
node_ptr(elem->node_ptr(7)->id() + ((2*k+2) * orig_nodes)));
2745 new_elem->set_node(20,
mesh.
node_ptr(elem->node_ptr(8)->id() + (2*k * orig_nodes)));
2746 new_elem->set_node(21,
mesh.
node_ptr(elem->node_ptr(4)->id() + ((2*k+1) * orig_nodes)));
2747 new_elem->set_node(22,
mesh.
node_ptr(elem->node_ptr(5)->id() + ((2*k+1) * orig_nodes)));
2748 new_elem->set_node(23,
mesh.
node_ptr(elem->node_ptr(6)->id() + ((2*k+1) * orig_nodes)));
2749 new_elem->set_node(24,
mesh.
node_ptr(elem->node_ptr(7)->id() + ((2*k+1) * orig_nodes)));
2750 new_elem->set_node(25,
mesh.
node_ptr(elem->node_ptr(8)->id() + ((2*k+2) * orig_nodes)));
2751 new_elem->set_node(26,
mesh.
node_ptr(elem->node_ptr(8)->id() + ((2*k+1) * orig_nodes)));
2754 new_elem->set_neighbor(1, const_cast<RemoteElem *>(
remote_elem));
2756 new_elem->set_neighbor(2, const_cast<RemoteElem *>(
remote_elem));
2758 new_elem->set_neighbor(3, const_cast<RemoteElem *>(
remote_elem));
2760 new_elem->set_neighbor(4, const_cast<RemoteElem *>(
remote_elem));
2766 libmesh_not_implemented();
2771 new_elem->set_id(elem->id() + (k * orig_elem));
2772 new_elem->processor_id() = elem->processor_id();
2774 #ifdef LIBMESH_ENABLE_UNIQUE_ID 2780 orig_unique_ids + (k-1)*(orig_nodes + orig_elem) + orig_nodes + elem->id();
2782 new_elem->set_unique_id(uid);
2785 if (!elem_subdomain)
2787 new_elem->subdomain_id() = elem->subdomain_id();
2795 for (
auto s : elem->side_index_range())
2797 cross_section_boundary_info.
boundary_ids(elem, s, ids_to_copy);
2799 if (added_elem->
dim() == 3)
2806 cast_int<unsigned short>(s+1),
2815 libmesh_assert_less(s, 2);
2816 const unsigned short sidemap[2] = {3, 1};
2817 boundary_info.
add_side(added_elem, sidemap[s], ids_to_copy);
2823 boundary_info.
add_side(added_elem, 0, next_side_id);
2829 const unsigned short top_id = added_elem->
dim() == 3 ?
2830 cast_int<unsigned short>(elem->n_sides()+1) : 2;
2833 cast_int<boundary_id_type>(next_side_id+1));
2845 #if defined(LIBMESH_HAVE_TRIANGLE) && LIBMESH_DIM > 1 2849 const unsigned int nx,
2850 const unsigned int ny,
2854 const std::vector<TriangleInterface::Hole*> * holes)
2857 libmesh_assert_greater_equal (nx, 1);
2858 libmesh_assert_greater_equal (ny, 1);
2859 libmesh_assert_less (xmin, xmax);
2860 libmesh_assert_less (ymin, ymax);
2871 const Real delta_x = (xmax-xmin) / static_cast<Real>(nx);
2872 const Real delta_y = (ymax-ymin) / static_cast<Real>(ny);
2875 for (
unsigned int p=0; p<=nx; ++p)
2879 for (
unsigned int p=1; p<ny; ++p)
2883 for (
unsigned int p=0; p<=nx; ++p)
2887 for (
unsigned int p=1; p<ny; ++p)
2891 libmesh_assert_equal_to (
mesh.
n_nodes(), 2*(nx+ny));
2897 t.
desired_area() = 0.5 * (xmax-xmin)*(ymax-ymin) /
static_cast<Real>(nx*ny);
2901 if (holes !=
nullptr)
2908 std::unique_ptr<const Elem> side;
2913 for (
auto & elem :
mesh.element_ptr_range())
2914 for (
auto s : elem->side_index_range())
2915 if (elem->neighbor_ptr(s) ==
nullptr)
2917 elem->build_side_ptr(side, s);
2923 Point side_midpoint= 0.5f*( side->point(0) + side->point(1) );
2934 if (std::fabs(side_midpoint(1) - ymin) <
TOLERANCE)
2938 else if (std::fabs(side_midpoint(0) - xmax) <
TOLERANCE)
2942 else if (std::fabs(side_midpoint(1) - ymax) <
TOLERANCE)
2946 else if (std::fabs(side_midpoint(0) - xmin) <
TOLERANCE)
2953 boundary_info.
add_side(elem->id(), s, bc_id);
2958 #endif // LIBMESH_HAVE_TRIANGLE && LIBMESH_DIM > 1 2968 const Real xavg = (xmin + xmax)/2;
2969 const Real yavg = (ymin + ymax)/2;
2970 const Real zavg = (zmin + zmax)/2;
2978 auto add_tri = [&
mesh, flip_tris](std::array<dof_id_type,3> nodes)
ElemType
Defines an enum for geometric element types.
Class for receiving the callback during extrusion generation and providing user-defined subdomains ba...
virtual void reserve_nodes(const dof_id_type nn)=0
Reserves space for a known number of nodes.
virtual void triangulate() override
Internally, this calls Triangle's triangulate routine.
const std::set< boundary_id_type > & get_side_boundary_ids() const
virtual Node *& set_node(const unsigned int i)
A Node is like a Point, but with more information.
virtual unique_id_type parallel_max_unique_id() const =0
std::string & nodeset_name(boundary_id_type id)
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value for an unsigned int...
VectorValue< Real > RealVectorValue
Useful typedefs to allow transparent switching between Real and Complex data types.
static constexpr Real TOLERANCE
void resize(const unsigned int n)
Resize the vector.
void prepare_for_use(const bool skip_renumber_nodes_and_elements, const bool skip_find_neighbors)
Prepare a newly created (or read) mesh for use.
void remove(const Node *node)
Removes the boundary conditions associated with node node, if any exist.
const std::map< boundary_id_type, std::string > & get_sideset_name_map() const
This is the base class from which all geometric element types are derived.
const Parallel::Communicator & comm() const
void boundary_ids(const Node *node, std::vector< boundary_id_type > &vec_to_fill) const
Fills a user-provided std::vector with the boundary ids associated with Node node.
The libMesh namespace provides an interface to certain functionality in the library.
ElemType & elem_type()
Sets and/or gets the desired element type.
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
virtual Node * add_point(const Point &p, const dof_id_type id=DofObject::invalid_id, const processor_id_type proc_id=DofObject::invalid_processor_id)=0
Add a new Node at Point p to the end of the vertex array, with processor_id procid.
This is the MeshBase class.
TriangulationType & triangulation_type()
Sets and/or gets the desired triangulation type.
uint8_t processor_id_type
std::map< boundary_id_type, std::string > & set_sideset_name_map()
virtual bool is_serial() const
void add_node(const Node *node, const boundary_id_type id)
Add Node node with boundary id id to the boundary information data structures.
const std::map< boundary_id_type, std::string > & get_nodeset_name_map() const
static const boundary_id_type invalid_id
Number used for internal use.
void attach_hole_list(const std::vector< Hole *> *holes)
Attaches a vector of Hole* pointers which will be meshed around.
The UnstructuredMesh class is derived from the MeshBase class.
virtual Elem * add_elem(Elem *e)=0
Add elem e to the end of the element array.
static std::unique_ptr< Elem > build(const ElemType type, Elem *p=nullptr)
virtual const Node * query_node_ptr(const dof_id_type i) const =0
const std::map< boundary_id_type, std::string > & get_edgeset_name_map() const
The BoundaryInfo class contains information relevant to boundary conditions including storing faces...
void set_mesh_dimension(unsigned char d)
Resets the logical dimension of the mesh.
void sync_dofobject_data_by_id(const Communicator &comm, const Iterator &range_begin, const Iterator &range_end, SyncFunctor &sync)
Request data about a range of ghost dofobjects uniquely identified by their id.
virtual void clear()
Deletes all the element and node data that is currently stored.
std::string & sideset_name(boundary_id_type id)
const boundary_id_type top_id
std::string enum_to_string(const T e)
Real & desired_area()
Sets and/or gets the desired triangle area.
virtual Node * add_node(Node *n)=0
Add Node n to the end of the vertex array.
Triangulate the interior of a Planar Straight Line Graph, which is defined implicitly by the order of...
static std::unique_ptr< Node > build(const Node &n)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void max(const T &r, T &o, Request &req) const
virtual unsigned short dim() const =0
virtual void all_complete_order()
Calls the range-based version of this function with a range consisting of all elements in the mesh...
std::map< boundary_id_type, std::string > & set_nodeset_name_map()
static std::unique_ptr< Elem > build_with_id(const ElemType type, dof_id_type id)
Calls the build() method above with a nullptr parent, and additionally sets the newly-created Elem's ...
virtual bool is_replicated() const
void add_side(const dof_id_type elem, const unsigned short int side, const boundary_id_type id)
Add side side of element number elem with boundary id id to the boundary information data structure...
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
void all_second_order(const bool full_ordered=true)
Calls the range-based version of this function with a range consisting of all elements in the mesh...
unsigned int mesh_dimension() const
virtual const Node & node_ref(const dof_id_type i) const
Defines a dense vector for use in Finite Element-type computations.
virtual void delete_remote_elements()
When supported, deletes all nonlocal elements of the mesh except for "ghosts" which touch a local ele...
virtual subdomain_id_type get_subdomain_for_layer(const Elem *old_elem, unsigned int layer)=0
virtual dof_id_type n_elem() const =0
virtual const Node * node_ptr(const dof_id_type i) const =0
Base class for functors that can be evaluated at a point and (optionally) time.
processor_id_type processor_id() const
A C++ interface between LibMesh and the Triangle library written by J.R.
A Point defines a location in LIBMESH_DIM dimensional Real space.
virtual void reserve_elem(const dof_id_type ne)=0
Reserves space for a known number of elements.
void ErrorVector unsigned int
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
virtual dof_id_type n_nodes() const =0
std::map< boundary_id_type, std::string > & set_edgeset_name_map()
const RemoteElem * remote_elem