51 : airfoil_type(
"NACA")
53 , joukowski_center(-0.1, 0.14)
59 , incline_factor(0.35)
62 , n_subdivision_x_0(3)
63 , n_subdivision_x_1(2)
64 , n_subdivision_x_2(5)
66 , airfoil_sampling_factor(2)
69 airfoil_length <= height,
71 "Mesh is to small to enclose airfoil! Choose larger field or smaller"
73 Assert(incline_factor < 1.0 && incline_factor >= 0.0,
74 ExcMessage(
"incline_factor has to be in [0,1)!"));
87 "Mesh height measured from airfoil nose to horizontal boundaries");
91 "Length measured from airfoil leading edge to vertical outlet boundary");
95 "Define obliqueness of the vertical mesh around the airfoil");
104 "Type of airfoil geometry, either NACA or Joukowski airfoil",
119 "Joukowski circle center coordinates");
122 "Joukowski airfoil length leading to trailing edge");
130 "Number of global refinements");
132 "NumberSubdivisionX0",
134 "Number of subdivisions along the airfoil in blocks with material ID 1 and 4");
136 "NumberSubdivisionX1",
138 "Number of subdivisions along the airfoil in blocks with material ID 2 and 5");
140 "NumberSubdivisionX2",
142 "Number of subdivisions in horizontal direction on the right of the trailing edge, i.e., blocks with material ID 3 and 6");
145 "Number of subdivisions normal to airfoil");
149 "Factor to obtain a finer mesh at the airfoil surface");
164 static const unsigned int id_block_1 = 1;
165 static const unsigned int id_block_2 = 2;
166 static const unsigned int id_block_3 = 3;
167 static const unsigned int id_block_4 = 4;
168 static const unsigned int id_block_5 = 5;
169 static const unsigned int id_block_6 = 6;
174 MeshGenerator(
const AdditionalData &data)
175 : refinements(data.refinements)
176 , n_subdivision_x_0(data.n_subdivision_x_0)
177 , n_subdivision_x_1(data.n_subdivision_x_1)
178 , n_subdivision_x_2(data.n_subdivision_x_2)
179 , n_subdivision_y(data.n_subdivision_y)
180 , height(data.height)
181 , length_b2(data.length_b2)
182 , incline_factor(data.incline_factor)
183 , bias_factor(data.bias_factor)
185 , n_cells_x_0(Utilities::
pow(2, refinements) * n_subdivision_x_0)
186 , n_cells_x_1(Utilities::
pow(2, refinements) * n_subdivision_x_1)
187 , n_cells_x_2(Utilities::
pow(2, refinements) * n_subdivision_x_2)
188 , n_cells_y(Utilities::
pow(2, refinements) * n_subdivision_y)
189 , n_points_on_each_side(n_cells_x_0 + n_cells_x_1 + 1)
191 , airfoil_1D(set_airfoil_length(
193 data.airfoil_type ==
"Joukowski" ?
194 joukowski(data.joukowski_center,
195 n_points_on_each_side,
196 data.airfoil_sampling_factor) :
197 (data.airfoil_type ==
"NACA" ?
199 n_points_on_each_side,
200 data.airfoil_sampling_factor) :
201 std::array<std::vector<Point<2>>, 2>{
202 {std::vector<Point<2>>{Point<2>(0), Point<2>(1)},
203 std::vector<Point<2>>{
207 data.airfoil_length))
208 , end_b0_x_u(airfoil_1D[0][n_cells_x_0][0])
209 , end_b0_x_l(airfoil_1D[1][n_cells_x_0][0])
210 , nose_x(airfoil_1D[0].front()[0])
211 , tail_x(airfoil_1D[0].back()[0])
212 , tail_y(airfoil_1D[0].back()[1])
213 , center_mesh(0.5 *
std::abs(end_b0_x_u + end_b0_x_l))
214 , length_b1_x(tail_x - center_mesh)
216 (edge_length +
std::abs(nose_x - center_mesh))))
220 ,
A(nose_x - edge_length, 0)
223 , D(center_mesh, height)
225 ,
F(center_mesh, -height)
229 , J(tail_x + length_b2, 0)
233 Assert(data.airfoil_type ==
"Joukowski" ||
234 data.airfoil_type ==
"NACA",
243 Triangulation<2> &tria_grid,
244 std::vector<GridTools::PeriodicFacePair<
247 make_coarse_grid(tria_grid);
249 set_boundary_ids(tria_grid);
251 if (periodic_faces !=
nullptr)
254 tria_grid, 5, 4, 1, *periodic_faces);
267 parallel::fullydistributed::Triangulation<2> ¶llel_grid,
268 std::vector<GridTools::PeriodicFacePair<
272 (void)periodic_faces;
279 const unsigned int refinements;
282 const unsigned int n_subdivision_x_0;
285 const unsigned int n_subdivision_x_1;
288 const unsigned int n_subdivision_x_2;
292 const unsigned int n_subdivision_y;
299 const double length_b2;
303 const double incline_factor;
306 const double bias_factor;
309 const double edge_length;
312 const unsigned int n_cells_x_0;
315 const unsigned int n_cells_x_1;
318 const unsigned int n_cells_x_2;
322 const unsigned int n_cells_y;
325 const unsigned int n_points_on_each_side;
329 const std::array<std::vector<Point<2>>, 2> airfoil_1D;
333 const double end_b0_x_u;
337 const double end_b0_x_l;
351 const double center_mesh;
354 const double length_b1_x;
381 const Point<2>
A, B,
C, D,
E,
F, G, H, I, J,
K,
L;
420 static std::array<std::vector<Point<2>>, 2>
421 joukowski(
const Point<2> ¢erpoint,
422 const unsigned int number_points,
423 const unsigned int factor)
425 std::array<std::vector<Point<2>>, 2> airfoil_1D;
426 const unsigned int total_points = 2 * number_points - 2;
427 const unsigned int n_airfoilpoints = factor * total_points;
429 const auto jouk_points =
430 joukowski_transform(joukowski_circle(centerpoint, n_airfoilpoints));
433 std::vector<Point<2>> upper_points;
434 std::vector<Point<2>> lower_points;
438 unsigned int nose_index = 0;
439 unsigned int tail_index = 0;
440 double nose_x_coordinate = 0;
441 double tail_x_coordinate = 0;
445 for (
unsigned int i = 0; i < jouk_points.size(); ++i)
447 if (jouk_points[i][0] < nose_x_coordinate)
449 nose_x_coordinate = jouk_points[i][0];
452 if (jouk_points[i][0] > tail_x_coordinate)
454 tail_x_coordinate = jouk_points[i][0];
460 for (
unsigned int i = tail_index; i < jouk_points.size(); ++i)
461 upper_points.emplace_back(jouk_points[i]);
462 for (
unsigned int i = 0; i <= nose_index; ++i)
463 upper_points.emplace_back(jouk_points[i]);
464 std::reverse(upper_points.begin(), upper_points.end());
467 lower_points.insert(lower_points.end(),
468 jouk_points.begin() + nose_index,
469 jouk_points.begin() + tail_index + 1);
472 airfoil_1D[0] = make_points_equidistant(upper_points, number_points);
473 airfoil_1D[1] = make_points_equidistant(lower_points, number_points);
476 auto move_nose_to_origin = [](std::vector<Point<2>> &vector) {
477 const double nose_x_pos = vector.front()[0];
478 for (
auto &i : vector)
482 move_nose_to_origin(airfoil_1D[1]);
483 move_nose_to_origin(airfoil_1D[0]);
512 static std::vector<Point<2>>
513 joukowski_circle(
const Point<2> ¢er,
514 const unsigned int number_points)
516 std::vector<Point<2>> circle_points;
523 const double radius =
std::sqrt(center[1] * center[1] +
524 (1 - center[0]) * (1 - center[0]));
526 center[1] * center[1] + (1 + center[0]) * (1 + center[0]));
530 radius_test < radius,
532 "Error creating lower circle: Circle for Joukowski-transform does"
533 " not enclose point zeta = -1! Choose different center "
537 const double theta = 2 *
numbers::PI / number_points;
539 circle_points.reserve(number_points);
540 for (
unsigned int i = 0; i < number_points; ++i)
541 circle_points.emplace_back(center[0] - radius *
std::cos(i * theta),
545 return circle_points;
556 static std::vector<Point<2>>
557 joukowski_transform(
const std::vector<Point<2>> &circle_points)
559 std::vector<Point<2>> joukowski_points(circle_points.size());
562 for (
unsigned int i = 0; i < circle_points.size(); ++i)
564 const double chi = circle_points[i][0];
565 const double eta = circle_points[i][1];
566 const std::complex<double> zeta(chi, eta);
567 const std::complex<double> z = zeta + 1. / zeta;
569 joukowski_points[i] = {std::real(z), std::imag(z)};
571 return joukowski_points;
590 static std::array<std::vector<Point<2>>, 2>
591 naca(
const std::string &serialnumber,
592 const unsigned int number_points,
593 const unsigned int factor)
597 const unsigned int n_airfoilpoints = factor * number_points;
600 return {{make_points_equidistant(
601 naca_create_points(serialnumber, n_airfoilpoints,
true),
603 make_points_equidistant(
604 naca_create_points(serialnumber, n_airfoilpoints,
false),
619 static std::vector<Point<2>>
620 naca_create_points(
const std::string &serialnumber,
621 const unsigned int number_points,
624 Assert(serialnumber.size() == 4,
625 ExcMessage(
"This NACA-serial number is not implemented!"));
627 return naca_create_points_4_digits(serialnumber,
646 static std::vector<Point<2>>
647 naca_create_points_4_digits(
const std::string &serialnumber,
648 const unsigned int number_points,
652 const unsigned int digit_0 = (serialnumber[0] -
'0');
653 const unsigned int digit_1 = (serialnumber[1] -
'0');
654 const unsigned int digit_2 = (serialnumber[2] -
'0');
655 const unsigned int digit_3 = (serialnumber[3] -
'0');
657 const unsigned int digit_23 = 10 * digit_2 + digit_3;
660 const double t =
static_cast<double>(digit_23) / 100.0;
662 std::vector<Point<2>> naca_points;
664 if (digit_0 == 0 && digit_1 == 0)
665 for (
unsigned int i = 0; i < number_points; ++i)
667 const double x = i * 1 / (1.0 * number_points - 1);
677 naca_points.emplace_back(x, +y_t);
679 naca_points.emplace_back(x, -y_t);
682 for (
unsigned int i = 0; i < number_points; ++i)
684 const double m = 1.0 * digit_0 / 100;
685 const double p = 1.0 * digit_1 / 10;
686 const double x = i * 1 / (1.0 * number_points - 1);
693 ((1 - 2 * p) + 2 * p * x - Utilities::
fixed_power<2>(x));
697 2 * m / Utilities::
fixed_power<2>(1 - p) * (p - x);
710 naca_points.emplace_back(x - y_t *
std::sin(theta),
713 naca_points.emplace_back(x + y_t *
std::sin(theta),
730 static std::array<std::vector<Point<2>>, 2>
731 set_airfoil_length(
const std::array<std::vector<Point<2>>, 2> &input,
732 const double desired_len)
734 std::array<std::vector<Point<2>>, 2> output;
735 output[0] = set_airfoil_length(input[0], desired_len);
736 output[1] = set_airfoil_length(input[1], desired_len);
748 static std::vector<Point<2>>
749 set_airfoil_length(
const std::vector<Point<2>> &input,
750 const double desired_len)
752 std::vector<Point<2>> output = input;
755 desired_len / input.front().distance(input.back());
757 for (
auto &x : output)
773 static std::vector<Point<2>>
774 make_points_equidistant(
775 const std::vector<Point<2>> &non_equidistant_points,
776 const unsigned int number_points)
778 const unsigned int n_points =
779 non_equidistant_points
783 std::vector<double> arclength_L(non_equidistant_points.size(), 0);
784 for (
unsigned int i = 0; i < non_equidistant_points.size() - 1; ++i)
787 non_equidistant_points[i + 1].distance(non_equidistant_points[i]);
790 const auto airfoil_length =
792 const auto deltaX = airfoil_length / (number_points - 1);
796 std::vector<Point<2>> equidist(
799 equidist[0] = non_equidistant_points[0];
800 equidist[number_points - 1] = non_equidistant_points[n_points - 1];
804 for (
unsigned int j = 0, i = 1; j < n_points - 1; ++j)
807 const auto Lj = arclength_L[j];
808 const auto Ljp = arclength_L[j + 1];
810 while (Lj <= i * deltaX && i * deltaX <= Ljp &&
811 i < number_points - 1)
813 equidist[i] = Point<2>((i * deltaX - Lj) / (Ljp - Lj) *
814 (non_equidistant_points[j + 1] -
815 non_equidistant_points[j]) +
816 non_equidistant_points[j]);
832 make_coarse_grid(Triangulation<2> &tria)
const
836 std::vector<Triangulation<2>> trias(10);
839 auto make = [](Triangulation<2> &tria,
840 const std::vector<Point<2>> &corner_vertices,
841 const std::vector<unsigned int> &repetitions,
853 auto &
point = it->vertex();
854 const double xi =
point[0];
855 const double eta =
point[1];
858 point = 0.25 * ((1 - xi) * (1 - eta) * corner_vertices[0] +
859 (1 + xi) * (1 - eta) * corner_vertices[1] +
860 (1 - xi) * (1 + eta) * corner_vertices[2] +
861 (1 + xi) * (1 + eta) * corner_vertices[3]);
866 cell->set_material_id(material_id);
873 {n_subdivision_y, n_subdivision_x_0},
877 {n_subdivision_y, n_subdivision_x_0},
881 {n_subdivision_x_1, n_subdivision_y},
885 {n_subdivision_x_1, n_subdivision_y},
889 {n_subdivision_x_2, n_subdivision_y},
893 {n_subdivision_x_2, n_subdivision_y},
918 set_boundary_ids(Triangulation<2> &tria)
923 if (cell->face(f)->at_boundary() ==
false)
926 const auto mid = cell->material_id();
928 if ((mid == id_block_1 && f == 0) ||
929 (mid == id_block_4 && f == 0))
930 cell->face(f)->set_boundary_id(0);
931 else if ((mid == id_block_3 && f == 0) ||
932 (mid == id_block_6 && f == 2))
933 cell->face(f)->set_boundary_id(1);
934 else if ((mid == id_block_1 && f == 1) ||
935 (mid == id_block_2 && f == 1))
936 cell->face(f)->set_boundary_id(2);
937 else if ((mid == id_block_4 && f == 1) ||
938 (mid == id_block_5 && f == 3))
939 cell->face(f)->set_boundary_id(3);
940 else if ((mid == id_block_2 && f == 0) ||
941 (mid == id_block_3 && f == 2))
942 cell->face(f)->set_boundary_id(4);
943 else if ((mid == id_block_5 && f == 2) ||
944 (mid == id_block_6 && f == 0))
945 cell->face(f)->set_boundary_id(5);
965 std::vector<bool> vertex_processed(tria.
n_vertices(),
false);
968 const Tensor<2, 2, double> rotation_matrix_1 =
970 const Tensor<2, 2, double> rotation_matrix_2 =
975 const Point<2, double> horizontal_offset(A[0], 0.0);
978 const Point<2, double> trapeze_offset(0.0,
986 if (vertex_processed[cell->vertex_index(v)])
990 vertex_processed[cell->vertex_index(v)] =
true;
992 auto &node = cell->vertex(v);
995 if (cell->material_id() == id_block_1 ||
996 cell->material_id() == id_block_4)
1004 Point<2, double> node_;
1005 if (cell->material_id() == id_block_1)
1007 node_ = Point<2, double>(rotation_matrix_1 *
1008 (node - horizontal_offset) +
1014 else if (cell->material_id() == id_block_4)
1016 node_ = Point<2, double>(rotation_matrix_2 *
1017 (node - horizontal_offset) -
1023 const double trapeze_height =
1025 const double L = height /
std::sin(gamma);
1026 const double l_a =
std::cos(gamma) * edge_length;
1027 const double l_b = trapeze_height *
std::tan(gamma);
1029 const double x2 =
L - l_a - l_b;
1031 const double Dx = x1 + x2 + x3;
1032 const double deltax =
1034 const double dx = Dx / n_cells_x_0;
1035 const double dy = trapeze_height / n_cells_y;
1037 static_cast<int>(std::round((node_[0] - deltax) / dx));
1039 static_cast<int>(std::round(
std::abs(node_[1]) / dy));
1041 node_[0] =
numbers::PI / 2 * (1.0 * ix) / n_cells_x_0;
1042 node_[1] = height * (1.0 * iy) / n_cells_y;
1049 const double dy = height / n_cells_y;
1051 static_cast<int>(std::round(node_[0] / dx));
1053 static_cast<int>(std::round(node_[1] / dy));
1054 const double alpha =
1055 bias_alpha(1 - (1.0 * iy) / n_cells_y);
1056 const double theta = node_[0];
1057 const Point<2> p(-height *
std::cos(theta) + center_mesh,
1058 ((cell->material_id() == id_block_1) ?
1063 (cell->material_id() == id_block_1) ? (0) : (1))]
1069 else if (cell->material_id() == id_block_2 ||
1070 cell->material_id() == id_block_5)
1078 "Points D,C,G and E,F,I are not defined symmetric to "
1079 "x-axis, which is required to interpolate block 2"
1080 " and 5 with same geometric computations."));
1081 const double l_y = D[1] -
C[1];
1082 const double l_h = D[1] - l_y;
1083 const double by = -l_h / length_b1_x * (node[0] - H[0]);
1084 const double dy = (height - by) / n_cells_y;
1085 const int iy =
static_cast<int>(
1086 std::round((
std::abs(node[1]) - by) / dy));
1087 const double dx = length_b1_x / n_cells_x_1;
1088 const int ix =
static_cast<int>(
1089 std::round(
std::abs(node[0] - center_mesh) / dx));
1091 const double alpha = bias_alpha(1 - (1.0 * iy) / n_cells_y);
1095 const Point<2> p(ix * dx + center_mesh +
1096 incline_factor * length_b2 * ix /
1098 ((cell->material_id() == id_block_2) ?
1104 (cell->material_id() == id_block_2) ? (0) : (1))]
1105 [n_cells_x_0 + ix] *
1109 else if (cell->material_id() == id_block_3 ||
1110 cell->material_id() == id_block_6)
1113 const double dx = length_b2 / n_cells_x_2;
1114 const double dy = height / n_cells_y;
1115 const int ix =
static_cast<int>(
1116 std::round(
std::abs(node[0] - H[0]) / dx));
1118 static_cast<int>(std::round(
std::abs(node[1]) / dy));
1120 const double alpha_y = bias_alpha(1 - 1.0 * iy / n_cells_y);
1121 const double alpha_x =
1122 bias_alpha(1 - (
static_cast<double>(ix)) / n_cells_x_2);
1126 const Point<2> p1(J[0] - (1 - incline_factor) * length_b2 *
1128 ((cell->material_id() == id_block_3) ?
1133 const Point<2> p2(J[0] - alpha_x * length_b2, tail_y);
1134 node = p1 * (1 - alpha_y) + p2 * alpha_y;
1154 bias_alpha(
double alpha)
const
1164 internal_create_triangulation(
1168 const AdditionalData &additional_data)
1170 MeshGenerator mesh_generator(additional_data);
1173 if (
auto *parallel_tria =
1176 mesh_generator.create_triangulation(*parallel_tria, periodic_faces);
1177 else if (
auto *parallel_tria =
dynamic_cast<
1180 mesh_generator.create_triangulation(*parallel_tria, periodic_faces);
1182 mesh_generator.create_triangulation(tria, periodic_faces);
1199 const AdditionalData &)
1209 const AdditionalData &additional_data)
1211 internal_create_triangulation(tria,
nullptr, additional_data);
1222 const AdditionalData &additional_data)
1224 internal_create_triangulation(tria, &periodic_faces, additional_data);
1235 const AdditionalData &additional_data)
1239 (void)additional_data;
1240 (void)periodic_faces;
1251 template <
int dim,
int spacedim>
1263 cell->
face(f)->set_boundary_id(f);
1269 template <
int spacedim>
1280 if (cell->
center()[0] > 0)
1288 template <
int dim,
int spacedim>
1293 const double epsilon)
1306 for (; face != endface; ++face)
1307 if (face->at_boundary())
1308 if (face->boundary_id() == 0)
1312 if (
std::abs(center[0] - p1[0]) < epsilon)
1313 face->set_boundary_id(0);
1314 else if (
std::abs(center[0] - p2[0]) < epsilon)
1315 face->set_boundary_id(1);
1316 else if (dim > 1 &&
std::abs(center[1] - p1[1]) < epsilon)
1317 face->set_boundary_id(2);
1318 else if (dim > 1 &&
std::abs(center[1] - p2[1]) < epsilon)
1319 face->set_boundary_id(3);
1320 else if (dim > 2 &&
std::abs(center[2] - p1[2]) < epsilon)
1321 face->set_boundary_id(4);
1322 else if (dim > 2 &&
std::abs(center[2] - p2[2]) < epsilon)
1323 face->set_boundary_id(5);
1335 for (
unsigned int d = 0;
d < dim; ++
d)
1336 if (cell->
center()[d] > 0)
1347 template <
int spacdim>
1360 for (
auto cell = tria.
begin(); cell != tria.
end(); ++cell)
1363 cell->
face(2)->set_all_boundary_ids(1);
1387 cell->
face(4)->set_all_boundary_ids(1);
1391 cell->
face(2)->set_all_boundary_ids(1);
1395 cell->
face(2)->set_all_boundary_ids(1);
1399 cell->
face(0)->set_all_boundary_ids(1);
1403 cell->
face(2)->set_all_boundary_ids(1);
1407 cell->
face(0)->set_all_boundary_ids(1);
1409 else if (tria.
n_cells() == 12)
1418 cell->
face(5)->set_all_boundary_ids(1);
1421 else if (tria.
n_cells() == 96)
1428 unsigned int count = 0;
1430 if (cell->
face(5)->at_boundary())
1432 cell->
face(5)->set_all_boundary_ids(1);
1451 const double inner_radius,
1452 const double outer_radius)
1457 const double middle_radius =
1458 (outer_radius - inner_radius) / 2e0 + inner_radius;
1459 const double eps = 1
e-3 * middle_radius;
1464 const auto face = cell->
face(f);
1465 if (!face->at_boundary())
1468 const double face_center_radius =
1469 (face->center(
true) - center).norm();
1471 if (std::fabs(face->center()[0]) < eps)
1473 face->set_boundary_id(2);
1474 for (
const unsigned int line_no : face->line_indices())
1475 if (face->line(line_no)->at_boundary())
1476 if (std::fabs(face->line(line_no)->vertex(0).norm() -
1477 face->line(line_no)->vertex(1).norm()) > eps)
1478 face->line(line_no)->set_boundary_id(2);
1480 else if (std::fabs(face->center()[1]) < eps)
1482 face->set_boundary_id(3);
1483 for (
const unsigned int line_no : face->line_indices())
1484 if (face->line(line_no)->at_boundary())
1485 if (std::fabs(face->line(line_no)->vertex(0).norm() -
1486 face->line(line_no)->vertex(1).norm()) > eps)
1487 face->line(line_no)->set_boundary_id(3);
1489 else if (std::fabs(face->center()[2]) < eps)
1491 face->set_boundary_id(4);
1492 for (
const unsigned int line_no : face->line_indices())
1493 if (face->line(line_no)->at_boundary())
1494 if (std::fabs(face->line(line_no)->vertex(0).norm() -
1495 face->line(line_no)->vertex(1).norm()) > eps)
1496 face->line(line_no)->set_boundary_id(4);
1498 else if (face_center_radius <
1501 face->set_boundary_id(0);
1502 for (
const unsigned int line_no : face->line_indices())
1503 if (face->line(line_no)->at_boundary())
1504 if (std::fabs(face->line(line_no)->vertex(0).norm() -
1505 face->line(line_no)->vertex(1).norm()) < eps)
1506 face->line(line_no)->set_boundary_id(0);
1508 else if (face_center_radius >
1511 face->set_boundary_id(1);
1512 for (
const unsigned int line_no : face->line_indices())
1513 if (face->line(line_no)->at_boundary())
1514 if (std::fabs(face->line(line_no)->vertex(0).norm() -
1515 face->line(line_no)->vertex(1).norm()) < eps)
1516 face->line(line_no)->set_boundary_id(1);
1526 template <
int dim,
int spacedim>
1531 const bool colorize)
1537 for (
unsigned int i = 0; i < dim; ++i)
1551 vertices[0] = vertices[1] = p1;
1552 vertices[2] = vertices[3] = p2;
1554 vertices[1][0] = p2[0];
1555 vertices[2][0] = p1[0];
1558 vertices[0] = vertices[1] = vertices[2] = vertices[3] = p1;
1559 vertices[4] = vertices[5] = vertices[6] = vertices[7] = p2;
1561 vertices[1][0] = p2[0];
1562 vertices[2][1] = p2[1];
1563 vertices[3][0] = p2[0];
1564 vertices[3][1] = p2[1];
1566 vertices[4][0] = p1[0];
1567 vertices[4][1] = p1[1];
1568 vertices[5][1] = p1[1];
1569 vertices[6][0] = p1[0];
1577 std::vector<CellData<dim>> cells(1);
1579 cells[0].vertices[i] = i;
1580 cells[0].material_id = 0;
1586 colorize_hyper_rectangle(tria);
1591 template <
int dim,
int spacedim>
1596 const bool colorize)
1599 ExcMessage(
"Invalid left-to-right bounds of hypercube"));
1602 for (
unsigned int i = 0; i < dim; ++i)
1623 for (
unsigned int d = 0;
d < dim; ++
d)
1624 for (
unsigned int c = 1; c <= dim; ++c)
1625 vector_matrix[c - 1][d] = vertices[c][d] - vertices[0][d];
1628 "Vertices of simplex must form a right handed system"));
1632 std::vector<Point<dim>> points = vertices;
1636 for (
unsigned int i = 0; i <= dim; ++i)
1638 points.push_back(0.5 * (points[i] + points[(i + 1) % (dim + 1)]));
1639 center += points[i];
1644 for (
unsigned int i = 1; i < dim; ++i)
1645 points.push_back(0.5 * (points[i - 1] + points[i + 1]));
1647 for (
unsigned int i = 0; i <= dim; ++i)
1648 points.push_back(1. / 3. *
1649 (points[i] + points[(i + 1) % (dim + 1)] +
1650 points[(i + 2) % (dim + 1)]));
1652 points.push_back((1. / (dim + 1)) * center);
1654 std::vector<CellData<dim>> cells(dim + 1);
1659 cells[0].vertices[0] = 0;
1660 cells[0].vertices[1] = 3;
1661 cells[0].vertices[2] = 5;
1662 cells[0].vertices[3] = 6;
1663 cells[0].material_id = 0;
1665 cells[1].vertices[0] = 3;
1666 cells[1].vertices[1] = 1;
1667 cells[1].vertices[2] = 6;
1668 cells[1].vertices[3] = 4;
1669 cells[1].material_id = 0;
1671 cells[2].vertices[0] = 5;
1672 cells[2].vertices[1] = 6;
1673 cells[2].vertices[2] = 2;
1674 cells[2].vertices[3] = 4;
1675 cells[2].material_id = 0;
1679 cells[0].vertices[0] = 0;
1680 cells[0].vertices[1] = 4;
1681 cells[0].vertices[2] = 8;
1682 cells[0].vertices[3] = 10;
1683 cells[0].vertices[4] = 7;
1684 cells[0].vertices[5] = 13;
1685 cells[0].vertices[6] = 12;
1686 cells[0].vertices[7] = 14;
1687 cells[0].material_id = 0;
1689 cells[1].vertices[0] = 4;
1690 cells[1].vertices[1] = 1;
1691 cells[1].vertices[2] = 10;
1692 cells[1].vertices[3] = 5;
1693 cells[1].vertices[4] = 13;
1694 cells[1].vertices[5] = 9;
1695 cells[1].vertices[6] = 14;
1696 cells[1].vertices[7] = 11;
1697 cells[1].material_id = 0;
1699 cells[2].vertices[0] = 8;
1700 cells[2].vertices[1] = 10;
1701 cells[2].vertices[2] = 2;
1702 cells[2].vertices[3] = 5;
1703 cells[2].vertices[4] = 12;
1704 cells[2].vertices[5] = 14;
1705 cells[2].vertices[6] = 6;
1706 cells[2].vertices[7] = 11;
1707 cells[2].material_id = 0;
1709 cells[3].vertices[0] = 7;
1710 cells[3].vertices[1] = 13;
1711 cells[3].vertices[2] = 12;
1712 cells[3].vertices[3] = 14;
1713 cells[3].vertices[4] = 3;
1714 cells[3].vertices[5] = 9;
1715 cells[3].vertices[6] = 6;
1716 cells[3].vertices[7] = 11;
1717 cells[3].material_id = 0;
1727 template <
int dim,
int spacedim>
1743 std::vector<Point<spacedim>> vertices(
reference_cell.n_vertices());
1747 for (
unsigned int d = 0;
d < dim; ++
d)
1748 vertices[v][d] = this_vertex[d];
1756 std::vector<CellData<dim>> cells(1);
1759 cells[0].vertices[v] = v;
1768 const unsigned int n_cells,
1769 const unsigned int n_rotations,
1773 const unsigned int dim = 3;
1776 "More than 4 cells are needed to create a moebius grid."));
1778 ExcMessage(
"Outer and inner radius must be positive."));
1780 ExcMessage(
"Outer radius must be greater than inner radius."));
1783 std::vector<Point<dim>> vertices(4 * n_cells);
1787 for (
unsigned int i = 0; i <
n_cells; ++i)
1788 for (
unsigned int j = 0; j < 4; ++j)
1790 vertices[4 * i + j][0] =
1794 vertices[4 * i + j][1] =
1798 vertices[4 * i + j][2] =
1802 unsigned int offset = 0;
1807 static constexpr std::array<unsigned int, 8> local_vertex_numbering{
1808 {0, 1, 5, 4, 2, 3, 7, 6}};
1809 std::vector<CellData<dim>> cells(n_cells);
1810 for (
unsigned int i = 0; i <
n_cells; ++i)
1812 for (
unsigned int j = 0; j < 2; ++j)
1814 cells[i].vertices[local_vertex_numbering[0 + 4 * j]] =
1816 cells[i].vertices[local_vertex_numbering[1 + 4 * j]] =
1818 cells[i].vertices[local_vertex_numbering[2 + 4 * j]] =
1820 cells[i].vertices[local_vertex_numbering[3 + 4 * j]] =
1824 cells[i].material_id = 0;
1828 cells[
n_cells - 1].vertices[local_vertex_numbering[4]] =
1829 (0 + n_rotations) % 4;
1830 cells[
n_cells - 1].vertices[local_vertex_numbering[5]] =
1831 (3 + n_rotations) % 4;
1832 cells[
n_cells - 1].vertices[local_vertex_numbering[6]] =
1833 (2 + n_rotations) % 4;
1834 cells[
n_cells - 1].vertices[local_vertex_numbering[7]] =
1835 (1 + n_rotations) % 4;
1846 const double centerline_radius,
1847 const double inner_radius,
1851 Assert(centerline_radius > inner_radius,
1852 ExcMessage(
"The centerline radius must be greater than the "
1854 Assert(inner_radius > 0.0,
1855 ExcMessage(
"The inner radius must be positive."));
1857 const unsigned int dim = 2;
1858 const unsigned int spacedim = 3;
1859 std::vector<Point<spacedim>> vertices(16);
1861 vertices[0] =
Point<spacedim>(centerline_radius - inner_radius, 0, 0);
1863 vertices[2] =
Point<spacedim>(centerline_radius + inner_radius, 0, 0);
1865 vertices[4] =
Point<spacedim>(0, 0, centerline_radius - inner_radius);
1867 vertices[6] =
Point<spacedim>(0, 0, centerline_radius + inner_radius);
1869 vertices[8] =
Point<spacedim>(-(centerline_radius - inner_radius), 0, 0);
1871 vertices[10] =
Point<spacedim>(-(centerline_radius + inner_radius), 0, 0);
1873 vertices[12] =
Point<spacedim>(0, 0, -(centerline_radius - inner_radius));
1875 vertices[14] =
Point<spacedim>(0, 0, -(centerline_radius + inner_radius));
1878 std::vector<CellData<dim>> cells(16);
1880 cells[0].vertices[0] = 0;
1881 cells[0].vertices[1] = 4;
1882 cells[0].vertices[2] = 3;
1883 cells[0].vertices[3] = 7;
1884 cells[0].material_id = 0;
1886 cells[1].vertices[0] = 1;
1887 cells[1].vertices[1] = 5;
1888 cells[1].vertices[2] = 0;
1889 cells[1].vertices[3] = 4;
1890 cells[1].material_id = 0;
1892 cells[2].vertices[0] = 2;
1893 cells[2].vertices[1] = 6;
1894 cells[2].vertices[2] = 1;
1895 cells[2].vertices[3] = 5;
1896 cells[2].material_id = 0;
1898 cells[3].vertices[0] = 3;
1899 cells[3].vertices[1] = 7;
1900 cells[3].vertices[2] = 2;
1901 cells[3].vertices[3] = 6;
1902 cells[3].material_id = 0;
1904 cells[4].vertices[0] = 4;
1905 cells[4].vertices[1] = 8;
1906 cells[4].vertices[2] = 7;
1907 cells[4].vertices[3] = 11;
1908 cells[4].material_id = 0;
1910 cells[5].vertices[0] = 5;
1911 cells[5].vertices[1] = 9;
1912 cells[5].vertices[2] = 4;
1913 cells[5].vertices[3] = 8;
1914 cells[5].material_id = 0;
1916 cells[6].vertices[0] = 6;
1917 cells[6].vertices[1] = 10;
1918 cells[6].vertices[2] = 5;
1919 cells[6].vertices[3] = 9;
1920 cells[6].material_id = 0;
1922 cells[7].vertices[0] = 7;
1923 cells[7].vertices[1] = 11;
1924 cells[7].vertices[2] = 6;
1925 cells[7].vertices[3] = 10;
1926 cells[7].material_id = 0;
1928 cells[8].vertices[0] = 8;
1929 cells[8].vertices[1] = 12;
1930 cells[8].vertices[2] = 11;
1931 cells[8].vertices[3] = 15;
1932 cells[8].material_id = 0;
1934 cells[9].vertices[0] = 9;
1935 cells[9].vertices[1] = 13;
1936 cells[9].vertices[2] = 8;
1937 cells[9].vertices[3] = 12;
1938 cells[9].material_id = 0;
1940 cells[10].vertices[0] = 10;
1941 cells[10].vertices[1] = 14;
1942 cells[10].vertices[2] = 9;
1943 cells[10].vertices[3] = 13;
1944 cells[10].material_id = 0;
1946 cells[11].vertices[0] = 11;
1947 cells[11].vertices[1] = 15;
1948 cells[11].vertices[2] = 10;
1949 cells[11].vertices[3] = 14;
1950 cells[11].material_id = 0;
1952 cells[12].vertices[0] = 12;
1953 cells[12].vertices[1] = 0;
1954 cells[12].vertices[2] = 15;
1955 cells[12].vertices[3] = 3;
1956 cells[12].material_id = 0;
1958 cells[13].vertices[0] = 13;
1959 cells[13].vertices[1] = 1;
1960 cells[13].vertices[2] = 12;
1961 cells[13].vertices[3] = 0;
1962 cells[13].material_id = 0;
1964 cells[14].vertices[0] = 14;
1965 cells[14].vertices[1] = 2;
1966 cells[14].vertices[2] = 13;
1967 cells[14].vertices[3] = 1;
1968 cells[14].material_id = 0;
1970 cells[15].vertices[0] = 15;
1971 cells[15].vertices[1] = 3;
1972 cells[15].vertices[2] = 14;
1973 cells[15].vertices[3] = 2;
1974 cells[15].material_id = 0;
1987 static constexpr int circle_cell_vertices[5][4] = {{0, 1, 2, 3},
1999 const double centerline_radius,
2000 const double inner_radius,
2001 const unsigned int n_cells_toroidal,
2004 Assert(centerline_radius > inner_radius,
2005 ExcMessage(
"The centerline radius must be greater than the "
2007 Assert(inner_radius > 0.0,
2008 ExcMessage(
"The inner radius must be positive."));
2010 ExcMessage(
"Number of cells in toroidal direction has "
2011 "to be at least 3 for a torus of polar extent 2*pi."));
2017 const double a = 1. / (1 +
std::sqrt(2.0));
2020 const unsigned int additional_layer =
2024 const unsigned int n_point_layers_toroidal =
2025 n_cells_toroidal + additional_layer;
2026 std::vector<Point<3>> vertices(8 * n_point_layers_toroidal);
2038 const double phi_cell = phi / n_cells_toroidal;
2039 for (
unsigned int c = 1; c < n_point_layers_toroidal; ++c)
2041 for (
unsigned int v = 0; v < 8; ++v)
2043 const double inner_radius_2d = vertices[v][0];
2044 vertices[8 * c + v][0] = inner_radius_2d *
std::cos(phi_cell * c);
2045 vertices[8 * c + v][1] = vertices[v][1];
2046 vertices[8 * c + v][2] = inner_radius_2d *
std::sin(phi_cell * c);
2051 std::vector<CellData<3>> cells(5 * n_cells_toroidal);
2052 for (
unsigned int c = 0; c < n_cells_toroidal; ++c)
2054 for (
unsigned int j = 0; j < 2; ++j)
2056 const unsigned int offset =
2057 (8 * (c + j)) % (8 * n_point_layers_toroidal);
2060 for (
unsigned int c2 = 0; c2 < 5; ++c2)
2061 for (
unsigned int i = 0; i < 4; ++i)
2062 cells[5 * c + c2].vertices[i + j * 4] =
2063 offset + circle_cell_vertices[c2][i];
2066 cells[5 * c].material_id = 0;
2068 cells[5 * c + 1].material_id = 0;
2069 cells[5 * c + 2].material_id = 1;
2070 cells[5 * c + 3].material_id = 0;
2071 cells[5 * c + 4].material_id = 0;
2086 if (cell->
face(f)->at_boundary() && f != 4 && f != 5)
2088 cell->
face(f)->set_all_manifold_ids(1);
2114 template <
int dim,
int spacedim>
2118 const bool colorize)
2129 cell->vertex(i) = vertices[i];
2135 "The volume of the cell is not greater than zero. "
2136 "This could be due to the wrong ordering of the vertices."));
2164 const bool colorize)
2167 std::array<Tensor<1, 2>, 2> edges;
2168 edges[0] = corners[0];
2169 edges[1] = corners[1];
2170 std::vector<unsigned int> subdivisions;
2171 subdivided_parallelepiped<2, 2>(
2172 tria, origin, edges, subdivisions, colorize);
2181 const bool colorize)
2183 unsigned int n_subdivisions[dim];
2184 for (
unsigned int i = 0; i < dim; ++i)
2185 n_subdivisions[i] = 1;
2194 const unsigned int n_subdivisions,
2196 const bool colorize)
2200 unsigned int n_subdivisions_[dim];
2201 for (
unsigned int i = 0; i < dim; ++i)
2202 n_subdivisions_[i] = n_subdivisions;
2212 const unsigned int (&n_subdivisions)[dim],
2214 const unsigned int *n_subdivisions,
2217 const bool colorize)
2220 std::vector<unsigned int> subdivisions;
2221 std::array<Tensor<1, dim>, dim> edges;
2222 for (
unsigned int i = 0; i < dim; ++i)
2224 subdivisions.push_back(n_subdivisions[i]);
2225 edges[i] = corners[i];
2228 subdivided_parallelepiped<dim, dim>(
2229 tria, origin, edges, subdivisions, colorize);
2235 template <
int dim,
int spacedim>
2240 const std::vector<unsigned int> &subdivisions,
2241 const bool colorize)
2243 std::vector<unsigned int> compute_subdivisions = subdivisions;
2244 if (compute_subdivisions.empty())
2246 compute_subdivisions.resize(dim, 1);
2249 Assert(compute_subdivisions.size() == dim,
2250 ExcMessage(
"One subdivision must be provided for each dimension."));
2252 for (
unsigned int i = 0; i < dim; ++i)
2254 Assert(compute_subdivisions[i] > 0,
2255 ExcInvalidRepetitions(subdivisions[i]));
2257 edges[i].
norm() > 0,
2259 "Edges in subdivided_parallelepiped() must not be degenerate."));
2267 bool twisted_data =
false;
2272 twisted_data = (edges[0][0] < 0);
2279 const double plane_normal =
2280 edges[0][0] * edges[1][1] - edges[0][1] * edges[1][0];
2281 twisted_data = (plane_normal < 0.0);
2290 (edges[0].
norm() * edges[1].
norm()) -
2293 "Edges in subdivided_parallelepiped() must point in"
2294 " different directions."));
2310 twisted_data = (plane_normal * edges[2] < 0.0);
2318 ExcInvalidInputOrientation(
2319 "The triangulation you are trying to create will consist of cells"
2320 " with negative measures. This is usually the result of input data"
2321 " that does not define a right-handed coordinate system. The usual"
2322 " fix for this is to ensure that in 1d the given point is to the"
2323 " right of the origin (or the given edge tensor is positive), in 2d"
2324 " that the two edges (and their cross product) obey the right-hand"
2325 " rule (which may usually be done by switching the order of the"
2326 " points or edge tensors), or in 3d that the edges form a"
2327 " right-handed coordinate system (which may also be accomplished by"
2328 " switching the order of the first two points or edge tensors)."));
2331 for (
unsigned int i = 0; i < dim; ++i)
2332 for (
unsigned int j = i + 1; j < dim; ++j)
2333 Assert((edges[i] != edges[j]),
2335 "Degenerate edges of subdivided_parallelepiped encountered."));
2338 std::vector<Point<spacedim>> points;
2343 for (
unsigned int x = 0; x <= compute_subdivisions[0]; ++x)
2344 points.push_back(origin + edges[0] / compute_subdivisions[0] * x);
2348 for (
unsigned int y = 0; y <= compute_subdivisions[1]; ++y)
2349 for (
unsigned int x = 0; x <= compute_subdivisions[0]; ++x)
2350 points.push_back(origin + edges[0] / compute_subdivisions[0] * x +
2351 edges[1] / compute_subdivisions[1] * y);
2355 for (
unsigned int z = 0; z <= compute_subdivisions[2]; ++z)
2356 for (
unsigned int y = 0; y <= compute_subdivisions[1]; ++y)
2357 for (
unsigned int x = 0; x <= compute_subdivisions[0]; ++x)
2358 points.push_back(origin +
2359 edges[0] / compute_subdivisions[0] * x +
2360 edges[1] / compute_subdivisions[1] * y +
2361 edges[2] / compute_subdivisions[2] * z);
2370 for (
unsigned int i = 0; i < dim; ++i)
2371 n_cells *= compute_subdivisions[i];
2372 std::vector<CellData<dim>> cells(n_cells);
2378 for (
unsigned int x = 0; x < compute_subdivisions[0]; ++x)
2380 cells[x].vertices[0] = x;
2381 cells[x].vertices[1] = x + 1;
2384 cells[x].material_id = 0;
2391 const unsigned int n_dy = compute_subdivisions[1];
2392 const unsigned int n_dx = compute_subdivisions[0];
2394 for (
unsigned int y = 0; y < n_dy; ++y)
2395 for (
unsigned int x = 0; x < n_dx; ++x)
2397 const unsigned int c = y * n_dx + x;
2398 cells[c].vertices[0] = y * (n_dx + 1) + x;
2399 cells[c].vertices[1] = y * (n_dx + 1) + x + 1;
2400 cells[c].vertices[2] = (y + 1) * (n_dx + 1) + x;
2401 cells[c].vertices[3] = (y + 1) * (n_dx + 1) + x + 1;
2404 cells[c].material_id = 0;
2412 const unsigned int n_dz = compute_subdivisions[2];
2413 const unsigned int n_dy = compute_subdivisions[1];
2414 const unsigned int n_dx = compute_subdivisions[0];
2416 for (
unsigned int z = 0; z < n_dz; ++z)
2417 for (
unsigned int y = 0; y < n_dy; ++y)
2418 for (
unsigned int x = 0; x < n_dx; ++x)
2420 const unsigned int c = z * n_dy * n_dx + y * n_dx + x;
2422 cells[c].vertices[0] =
2423 z * (n_dy + 1) * (n_dx + 1) + y * (n_dx + 1) + x;
2424 cells[c].vertices[1] =
2425 z * (n_dy + 1) * (n_dx + 1) + y * (n_dx + 1) + x + 1;
2426 cells[c].vertices[2] =
2427 z * (n_dy + 1) * (n_dx + 1) + (y + 1) * (n_dx + 1) + x;
2428 cells[c].vertices[3] = z * (n_dy + 1) * (n_dx + 1) +
2429 (y + 1) * (n_dx + 1) + x + 1;
2430 cells[c].vertices[4] =
2431 (z + 1) * (n_dy + 1) * (n_dx + 1) + y * (n_dx + 1) + x;
2432 cells[c].vertices[5] = (z + 1) * (n_dy + 1) * (n_dx + 1) +
2433 y * (n_dx + 1) + x + 1;
2434 cells[c].vertices[6] = (z + 1) * (n_dy + 1) * (n_dx + 1) +
2435 (y + 1) * (n_dx + 1) + x;
2436 cells[c].vertices[7] = (z + 1) * (n_dy + 1) * (n_dx + 1) +
2437 (y + 1) * (n_dx + 1) + x + 1;
2440 cells[c].material_id = 0;
2461 for (; cell != endc; ++cell)
2465 if (cell->face(face)->at_boundary())
2466 cell->face(face)->set_boundary_id(face);
2473 template <
int dim,
int spacedim>
2476 const unsigned int repetitions,
2479 const bool colorize)
2481 Assert(repetitions >= 1, ExcInvalidRepetitions(repetitions));
2483 ExcMessage(
"Invalid left-to-right bounds of hypercube"));
2486 for (
unsigned int i = 0; i < dim; ++i)
2492 std::vector<unsigned int> reps(dim, repetitions);
2498 template <
int dim,
int spacedim>
2501 const std::vector<unsigned int> &repetitions,
2504 const bool colorize)
2506 Assert(repetitions.size() == dim, ExcInvalidRepetitionsDimension(dim));
2512 for (
unsigned int i = 0; i < dim; ++i)
2519 std::array<Point<spacedim>, dim> delta;
2520 for (
unsigned int i = 0; i < dim; ++i)
2522 Assert(repetitions[i] >= 1, ExcInvalidRepetitions(repetitions[i]));
2524 delta[i][i] = (p2[i] - p1[i]) / repetitions[i];
2528 "The first dim entries of coordinates of p1 and p2 need to be different."));
2532 std::vector<Point<spacedim>> points;
2536 for (
unsigned int x = 0; x <= repetitions[0]; ++x)
2537 points.push_back(p1 + x * delta[0]);
2541 for (
unsigned int y = 0; y <= repetitions[1]; ++y)
2542 for (
unsigned int x = 0; x <= repetitions[0]; ++x)
2543 points.push_back(p1 + x * delta[0] + y * delta[1]);
2547 for (
unsigned int z = 0; z <= repetitions[2]; ++z)
2548 for (
unsigned int y = 0; y <= repetitions[1]; ++y)
2549 for (
unsigned int x = 0; x <= repetitions[0]; ++x)
2550 points.push_back(p1 + x * delta[0] + y * delta[1] +
2559 std::vector<CellData<dim>> cells;
2564 cells.resize(repetitions[0]);
2565 for (
unsigned int x = 0; x < repetitions[0]; ++x)
2567 cells[x].vertices[0] = x;
2568 cells[x].vertices[1] = x + 1;
2569 cells[x].material_id = 0;
2576 cells.resize(repetitions[1] * repetitions[0]);
2577 for (
unsigned int y = 0; y < repetitions[1]; ++y)
2578 for (
unsigned int x = 0; x < repetitions[0]; ++x)
2580 const unsigned int c = x + y * repetitions[0];
2581 cells[c].vertices[0] = y * (repetitions[0] + 1) + x;
2582 cells[c].vertices[1] = y * (repetitions[0] + 1) + x + 1;
2583 cells[c].vertices[2] = (y + 1) * (repetitions[0] + 1) + x;
2584 cells[c].vertices[3] = (y + 1) * (repetitions[0] + 1) + x + 1;
2585 cells[c].material_id = 0;
2592 const unsigned int n_x = (repetitions[0] + 1);
2593 const unsigned int n_xy =
2594 (repetitions[0] + 1) * (repetitions[1] + 1);
2596 cells.resize(repetitions[2] * repetitions[1] * repetitions[0]);
2597 for (
unsigned int z = 0; z < repetitions[2]; ++z)
2598 for (
unsigned int y = 0; y < repetitions[1]; ++y)
2599 for (
unsigned int x = 0; x < repetitions[0]; ++x)
2601 const unsigned int c = x + y * repetitions[0] +
2602 z * repetitions[0] * repetitions[1];
2603 cells[c].vertices[0] = z * n_xy + y * n_x + x;
2604 cells[c].vertices[1] = z * n_xy + y * n_x + x + 1;
2605 cells[c].vertices[2] = z * n_xy + (y + 1) * n_x + x;
2606 cells[c].vertices[3] = z * n_xy + (y + 1) * n_x + x + 1;
2607 cells[c].vertices[4] = (z + 1) * n_xy + y * n_x + x;
2608 cells[c].vertices[5] = (z + 1) * n_xy + y * n_x + x + 1;
2609 cells[c].vertices[6] = (z + 1) * n_xy + (y + 1) * n_x + x;
2610 cells[c].vertices[7] =
2611 (z + 1) * n_xy + (y + 1) * n_x + x + 1;
2612 cells[c].material_id = 0;
2633 double epsilon = std::numeric_limits<double>::max();
2634 for (
unsigned int i = 0; i < dim; ++i)
2635 epsilon =
std::min(epsilon, 0.01 * delta[i][i]);
2638 "The distance between corner points must be positive."));
2642 colorize_subdivided_hyper_rectangle(tria, p1, p2, epsilon);
2651 const std::vector<std::vector<double>> &step_sz,
2654 const bool colorize)
2656 Assert(step_sz.size() == dim, ExcInvalidRepetitionsDimension(dim));
2666 std::vector<std::vector<double>> step_sizes(step_sz);
2668 for (
unsigned int i = 0; i < dim; ++i)
2672 std::swap(p1[i], p2[i]);
2673 std::reverse(step_sizes[i].
begin(), step_sizes[i].
end());
2679 for (
unsigned int j = 0; j < step_sizes.at(i).size(); ++j)
2680 x += step_sizes[i][j];
2681 Assert(std::fabs(x - (p2[i] - p1[i])) <= 1e-12 * std::fabs(x),
2683 "The sequence of step sizes in coordinate direction " +
2685 " must be equal to the distance of the two given "
2686 "points in this coordinate direction."));
2693 std::vector<Point<dim>> points;
2699 for (
unsigned int i = 0;; ++i)
2708 if (i == step_sizes[0].size())
2711 x += step_sizes[0][i];
2719 for (
unsigned int j = 0;; ++j)
2722 for (
unsigned int i = 0;; ++i)
2724 points.push_back(
Point<dim>(p1[0] + x, p1[1] + y));
2725 if (i == step_sizes[0].size())
2728 x += step_sizes[0][i];
2731 if (j == step_sizes[1].size())
2734 y += step_sizes[1][j];
2741 for (
unsigned int k = 0;; ++k)
2744 for (
unsigned int j = 0;; ++j)
2747 for (
unsigned int i = 0;; ++i)
2750 Point<dim>(p1[0] + x, p1[1] + y, p1[2] + z));
2751 if (i == step_sizes[0].size())
2754 x += step_sizes[0][i];
2757 if (j == step_sizes[1].size())
2760 y += step_sizes[1][j];
2763 if (k == step_sizes[2].size())
2766 z += step_sizes[2][k];
2777 std::vector<CellData<dim>> cells;
2782 cells.resize(step_sizes[0].size());
2783 for (
unsigned int x = 0; x < step_sizes[0].size(); ++x)
2785 cells[x].vertices[0] = x;
2786 cells[x].vertices[1] = x + 1;
2787 cells[x].material_id = 0;
2794 cells.resize(step_sizes[1].size() * step_sizes[0].size());
2795 for (
unsigned int y = 0; y < step_sizes[1].size(); ++y)
2796 for (
unsigned int x = 0; x < step_sizes[0].size(); ++x)
2798 const unsigned int c = x + y * step_sizes[0].size();
2799 cells[c].vertices[0] = y * (step_sizes[0].size() + 1) + x;
2800 cells[c].vertices[1] = y * (step_sizes[0].size() + 1) + x + 1;
2801 cells[c].vertices[2] =
2802 (y + 1) * (step_sizes[0].size() + 1) + x;
2803 cells[c].vertices[3] =
2804 (y + 1) * (step_sizes[0].size() + 1) + x + 1;
2805 cells[c].material_id = 0;
2812 const unsigned int n_x = (step_sizes[0].size() + 1);
2813 const unsigned int n_xy =
2814 (step_sizes[0].size() + 1) * (step_sizes[1].size() + 1);
2816 cells.resize(step_sizes[2].size() * step_sizes[1].size() *
2817 step_sizes[0].size());
2818 for (
unsigned int z = 0; z < step_sizes[2].size(); ++z)
2819 for (
unsigned int y = 0; y < step_sizes[1].size(); ++y)
2820 for (
unsigned int x = 0; x < step_sizes[0].size(); ++x)
2822 const unsigned int c =
2823 x + y * step_sizes[0].size() +
2824 z * step_sizes[0].size() * step_sizes[1].size();
2825 cells[c].vertices[0] = z * n_xy + y * n_x + x;
2826 cells[c].vertices[1] = z * n_xy + y * n_x + x + 1;
2827 cells[c].vertices[2] = z * n_xy + (y + 1) * n_x + x;
2828 cells[c].vertices[3] = z * n_xy + (y + 1) * n_x + x + 1;
2829 cells[c].vertices[4] = (z + 1) * n_xy + y * n_x + x;
2830 cells[c].vertices[5] = (z + 1) * n_xy + y * n_x + x + 1;
2831 cells[c].vertices[6] = (z + 1) * n_xy + (y + 1) * n_x + x;
2832 cells[c].vertices[7] =
2833 (z + 1) * n_xy + (y + 1) * n_x + x + 1;
2834 cells[c].material_id = 0;
2856 *std::min_element(step_sizes[0].
begin(), step_sizes[0].
end());
2857 for (
unsigned int i = 1; i < dim; ++i)
2859 *std::min_element(step_sizes[i].
begin(),
2860 step_sizes[i].
end()));
2861 const double epsilon = 0.01 * min_size;
2865 colorize_subdivided_hyper_rectangle(tria, p1, p2, epsilon);
2874 const std::vector<std::vector<double>> &spacing,
2877 const bool colorize)
2879 Assert(spacing.size() == 1, ExcInvalidRepetitionsDimension(1));
2883 Assert(spacing[0].size() == n_cells, ExcInvalidRepetitionsDimension(1));
2885 double delta = std::numeric_limits<double>::max();
2886 for (
unsigned int i = 0; i <
n_cells; ++i)
2888 Assert(spacing[0][i] >= 0, ExcInvalidRepetitions(-1));
2889 delta =
std::min(delta, spacing[0][i]);
2893 std::vector<Point<1>> points;
2895 for (
unsigned int x = 0; x <=
n_cells; ++x)
2897 points.emplace_back(ax);
2899 ax += spacing[0][x];
2902 unsigned int n_val_cells = 0;
2903 for (
unsigned int i = 0; i <
n_cells; ++i)
2907 std::vector<CellData<1>> cells(n_val_cells);
2908 unsigned int id = 0;
2909 for (
unsigned int x = 0; x <
n_cells; ++x)
2912 cells[id].vertices[0] = x;
2913 cells[id].vertices[1] = x + 1;
2932 const std::vector<std::vector<double>> &spacing,
2935 const bool colorize)
2937 Assert(spacing.size() == 2, ExcInvalidRepetitionsDimension(2));
2939 std::vector<unsigned int> repetitions(2);
2940 double delta = std::numeric_limits<double>::max();
2941 for (
unsigned int i = 0; i < 2; ++i)
2943 repetitions[i] = spacing[i].size();
2944 for (
unsigned int j = 0; j < repetitions[i]; ++j)
2946 Assert(spacing[i][j] >= 0, ExcInvalidRepetitions(-1));
2947 delta =
std::min(delta, spacing[i][j]);
2950 ExcInvalidRepetitionsDimension(i));
2954 std::vector<Point<2>> points;
2956 for (
unsigned int y = 0; y <= repetitions[1]; ++y)
2959 for (
unsigned int x = 0; x <= repetitions[0]; ++x)
2961 points.emplace_back(ax, ay);
2962 if (x < repetitions[0])
2963 ax += spacing[0][x];
2965 if (y < repetitions[1])
2966 ay += spacing[1][y];
2970 unsigned int n_val_cells = 0;
2971 for (
unsigned int i = 0; i <
material_id.size(0); ++i)
2972 for (
unsigned int j = 0; j <
material_id.size(1); ++j)
2976 std::vector<CellData<2>> cells(n_val_cells);
2977 unsigned int id = 0;
2978 for (
unsigned int y = 0; y < repetitions[1]; ++y)
2979 for (
unsigned int x = 0; x < repetitions[0]; ++x)
2982 cells[id].vertices[0] = y * (repetitions[0] + 1) + x;
2983 cells[id].vertices[1] = y * (repetitions[0] + 1) + x + 1;
2984 cells[id].vertices[2] = (y + 1) * (repetitions[0] + 1) + x;
2985 cells[id].vertices[3] = (y + 1) * (repetitions[0] + 1) + x + 1;
2999 double eps = 0.01 * delta;
3001 for (; cell != endc; ++cell)
3005 if (cell->
face(f)->boundary_id() == 0)
3008 for (
unsigned int i = 0; i < 2; ++i)
3010 if (face_center[i] < cell_center[i] - eps)
3011 cell->
face(f)->set_boundary_id(i * 2);
3012 if (face_center[i] > cell_center[i] + eps)
3013 cell->
face(f)->set_boundary_id(i * 2 + 1);
3024 const std::vector<std::vector<double>> &spacing,
3027 const bool colorize)
3029 const unsigned int dim = 3;
3031 Assert(spacing.size() == dim, ExcInvalidRepetitionsDimension(dim));
3033 std::array<unsigned int, dim> repetitions;
3034 double delta = std::numeric_limits<double>::max();
3035 for (
unsigned int i = 0; i < dim; ++i)
3037 repetitions[i] = spacing[i].size();
3038 for (
unsigned int j = 0; j < repetitions[i]; ++j)
3040 Assert(spacing[i][j] >= 0, ExcInvalidRepetitions(-1));
3041 delta =
std::min(delta, spacing[i][j]);
3044 ExcInvalidRepetitionsDimension(i));
3048 std::vector<Point<dim>> points;
3050 for (
unsigned int z = 0; z <= repetitions[2]; ++z)
3053 for (
unsigned int y = 0; y <= repetitions[1]; ++y)
3056 for (
unsigned int x = 0; x <= repetitions[0]; ++x)
3058 points.emplace_back(ax, ay, az);
3059 if (x < repetitions[0])
3060 ax += spacing[0][x];
3062 if (y < repetitions[1])
3063 ay += spacing[1][y];
3065 if (z < repetitions[2])
3066 az += spacing[2][z];
3070 unsigned int n_val_cells = 0;
3071 for (
unsigned int i = 0; i <
material_id.size(0); ++i)
3072 for (
unsigned int j = 0; j <
material_id.size(1); ++j)
3073 for (
unsigned int k = 0; k <
material_id.size(2); ++k)
3077 std::vector<CellData<dim>> cells(n_val_cells);
3078 unsigned int id = 0;
3079 const unsigned int n_x = (repetitions[0] + 1);
3080 const unsigned int n_xy = (repetitions[0] + 1) * (repetitions[1] + 1);
3081 for (
unsigned int z = 0; z < repetitions[2]; ++z)
3082 for (
unsigned int y = 0; y < repetitions[1]; ++y)
3083 for (
unsigned int x = 0; x < repetitions[0]; ++x)
3086 cells[id].vertices[0] = z * n_xy + y * n_x + x;
3087 cells[id].vertices[1] = z * n_xy + y * n_x + x + 1;
3088 cells[id].vertices[2] = z * n_xy + (y + 1) * n_x + x;
3089 cells[id].vertices[3] = z * n_xy + (y + 1) * n_x + x + 1;
3090 cells[id].vertices[4] = (z + 1) * n_xy + y * n_x + x;
3091 cells[id].vertices[5] = (z + 1) * n_xy + y * n_x + x + 1;
3092 cells[id].vertices[6] = (z + 1) * n_xy + (y + 1) * n_x + x;
3093 cells[id].vertices[7] = (z + 1) * n_xy + (y + 1) * n_x + x + 1;
3107 double eps = 0.01 * delta;
3110 for (; cell != endc; ++cell)
3114 if (cell->
face(f)->boundary_id() == 0)
3117 for (
unsigned int i = 0; i < dim; ++i)
3119 if (face_center[i] < cell_center[i] - eps)
3120 cell->
face(f)->set_boundary_id(i * 2);
3121 if (face_center[i] > cell_center[i] + eps)
3122 cell->
face(f)->set_boundary_id(i * 2 + 1);
3129 template <
int dim,
int spacedim>
3132 const std::vector<unsigned int> &holes)
3141 for (
unsigned int d = 0;
d < dim; ++
d)
3148 std::array<Point<spacedim>, dim> delta;
3149 std::array<unsigned int, dim> repetitions;
3150 for (
unsigned int i = 0; i < dim; ++i)
3153 ExcMessage(
"At least one hole needed in each direction"));
3154 repetitions[i] = 2 * holes[i] + 1;
3155 delta[i][i] = (p2[i] - p1[i]);
3160 std::vector<Point<spacedim>> points;
3164 for (
unsigned int x = 0; x <= repetitions[0]; ++x)
3165 points.push_back(p1 + x * delta[0]);
3169 for (
unsigned int y = 0; y <= repetitions[1]; ++y)
3170 for (
unsigned int x = 0; x <= repetitions[0]; ++x)
3171 points.push_back(p1 + x * delta[0] + y * delta[1]);
3175 for (
unsigned int z = 0; z <= repetitions[2]; ++z)
3176 for (
unsigned int y = 0; y <= repetitions[1]; ++y)
3177 for (
unsigned int x = 0; x <= repetitions[0]; ++x)
3178 points.push_back(p1 + x * delta[0] + y * delta[1] +
3188 std::vector<CellData<dim>> cells;
3193 cells.resize(repetitions[1] * repetitions[0] - holes[1] * holes[0]);
3195 for (
unsigned int y = 0; y < repetitions[1]; ++y)
3196 for (
unsigned int x = 0; x < repetitions[0]; ++x)
3198 if ((x % 2 == 1) && (y % 2 == 1))
3201 cells[c].vertices[0] = y * (repetitions[0] + 1) + x;
3202 cells[c].vertices[1] = y * (repetitions[0] + 1) + x + 1;
3203 cells[c].vertices[2] = (y + 1) * (repetitions[0] + 1) + x;
3204 cells[c].vertices[3] = (y + 1) * (repetitions[0] + 1) + x + 1;
3205 cells[c].material_id = 0;
3213 const unsigned int n_x = (repetitions[0] + 1);
3214 const unsigned int n_xy =
3215 (repetitions[0] + 1) * (repetitions[1] + 1);
3217 cells.resize(repetitions[2] * repetitions[1] * repetitions[0]);
3220 for (
unsigned int z = 0; z < repetitions[2]; ++z)
3221 for (
unsigned int y = 0; y < repetitions[1]; ++y)
3222 for (
unsigned int x = 0; x < repetitions[0]; ++x)
3225 cells[c].vertices[0] = z * n_xy + y * n_x + x;
3226 cells[c].vertices[1] = z * n_xy + y * n_x + x + 1;
3227 cells[c].vertices[2] = z * n_xy + (y + 1) * n_x + x;
3228 cells[c].vertices[3] = z * n_xy + (y + 1) * n_x + x + 1;
3229 cells[c].vertices[4] = (z + 1) * n_xy + y * n_x + x;
3230 cells[c].vertices[5] = (z + 1) * n_xy + y * n_x + x + 1;
3231 cells[c].vertices[6] = (z + 1) * n_xy + (y + 1) * n_x + x;
3232 cells[c].vertices[7] =
3233 (z + 1) * n_xy + (y + 1) * n_x + x + 1;
3234 cells[c].material_id = 0;
3262 const unsigned int ,
3274 const unsigned int ,
3286 bool inline point_in_2d_box(
const Point<2> &p,
3288 const double radius)
3290 return (
std::abs(p[0] - c[0]) < radius) &&
3299 template <
int dim,
int spacedim>
3301 minimal_vertex_distance(
const Triangulation<dim, spacedim> &triangulation)
3303 double length = std::numeric_limits<double>::max();
3305 for (
unsigned int n = 0; n < GeometryInfo<dim>::lines_per_cell; ++n)
3316 const double inner_radius,
3317 const double outer_radius,
3318 const double pad_bottom,
3319 const double pad_top,
3320 const double pad_left,
3321 const double pad_right,
3326 const unsigned int ,
3327 const bool colorize)
3329 const bool with_padding =
3330 pad_bottom > 0 || pad_top > 0 || pad_left > 0 || pad_right > 0;
3340 double length = std::numeric_limits<double>::max();
3342 for (
unsigned int n = 0; n < cell->
n_lines(); ++n)
3349 Triangulation<2> &cylinder_tria = with_padding ? cylinder_tria_maybe : tria;
3361 const Point<2> bl(-outer_radius - pad_left, -outer_radius - pad_bottom);
3362 const Point<2> tr(outer_radius + pad_right, outer_radius + pad_top);
3368 auto add_sizes = [](std::vector<double> &step_sizes,
3369 const double padding,
3370 const double h) ->
void {
3373 const auto rounded =
3374 static_cast<unsigned int>(std::round(padding / h));
3377 const unsigned int num = (padding > 0. && rounded == 0) ? 1 : rounded;
3378 for (
unsigned int i = 0; i < num; ++i)
3379 step_sizes.push_back(padding / num);
3382 std::vector<std::vector<double>> step_sizes(2);
3385 add_sizes(step_sizes[0], pad_left, outer_radius);
3387 step_sizes[0].push_back(outer_radius);
3388 step_sizes[0].push_back(outer_radius);
3390 add_sizes(step_sizes[0], pad_right, outer_radius);
3393 add_sizes(step_sizes[1], pad_bottom, outer_radius);
3395 step_sizes[1].push_back(outer_radius);
3396 step_sizes[1].push_back(outer_radius);
3398 add_sizes(step_sizes[1], pad_top, outer_radius);
3403 bulk_tria, step_sizes, bl, tr, colorize);
3406 std::set<Triangulation<2>::active_cell_iterator> cells_to_remove;
3408 if (internal::point_in_2d_box(cell->
center(), center, outer_radius))
3409 cells_to_remove.insert(cell);
3413 bulk_tria, cells_to_remove, tria_without_cylinder);
3415 const double tolerance =
3416 std::min(min_line_length(tria_without_cylinder),
3417 min_line_length(cylinder_tria)) /
3421 tria_without_cylinder, cylinder_tria, tria, tolerance,
true);
3433 const auto &face = cell->
face(face_n);
3434 if (face->at_boundary() &&
3435 internal::point_in_2d_box(face->center(),
3437 outer_radius * (1. - 1e-12)))
3438 face->set_manifold_id(polar_manifold_id);
3440 face->set_manifold_id(tfi_manifold_id);
3451 static constexpr double tol =
3452 std::numeric_limits<double>::epsilon() * 10000;
3457 const auto face = cell->
face(face_n);
3458 if (face->at_boundary())
3460 const Point<2> center = face->center();
3463 face->set_boundary_id(0);
3466 face->set_boundary_id(1);
3469 face->set_boundary_id(2);
3472 face->set_boundary_id(3);
3478 face->set_boundary_id(4);
3499 const double inner_radius,
3500 const double outer_radius,
3501 const double pad_bottom,
3502 const double pad_top,
3503 const double pad_left,
3504 const double pad_right,
3509 const unsigned int n_slices,
3510 const bool colorize)
3520 Point<2>(new_center[0], new_center[1]),
3543 tria.
set_manifold(polar_manifold_id, cylindrical_manifold);
3552 const double shell_region_width,
3553 const unsigned int n_shells,
3554 const double skewness,
3555 const bool colorize)
3557 Assert(0.0 <= shell_region_width && shell_region_width < 0.05,
3558 ExcMessage(
"The width of the shell region must be less than 0.05 "
3559 "(and preferably close to 0.03)"));
3593 std::set<Triangulation<2>::active_cell_iterator> cells_to_remove;
3598 cells_to_remove.insert(cell);
3602 for (
const unsigned int vertex_n :
3608 cylinder_triangulation_offset =
3616 bulk_tria, cells_to_remove, tria_without_cylinder);
3623 0.05 + shell_region_width,
3632 cell->
vertex(vertex_n)[0] = -0.1;
3633 else if (
std::abs(cell->
vertex(vertex_n)[0] - 0.41 / 4.0) < 1e-10)
3634 cell->
vertex(vertex_n)[0] = 0.1;
3642 if (!cell->
face(face_n)->at_boundary())
3643 cell->
face(face_n)->set_manifold_id(tfi_manifold_id);
3645 if (0.0 < shell_region_width)
3648 ExcMessage(
"If the shell region has positive width then "
3649 "there must be at least one shell."));
3654 0.05 + shell_region_width,
3661 const double vertex_tolerance =
3662 std::min(internal::minimal_vertex_distance(shell_tria),
3663 internal::minimal_vertex_distance(cylinder_tria)) *
3669 shell_tria, cylinder_tria, temp, vertex_tolerance,
true);
3670 cylinder_tria = std::move(temp);
3676 const double vertex_tolerance =
3677 std::min(internal::minimal_vertex_distance(tria_without_cylinder),
3678 internal::minimal_vertex_distance(cylinder_tria)) /
3681 tria_without_cylinder, cylinder_tria, tria, vertex_tolerance,
true);
3694 const double shift =
3695 std::min(0.125 + shell_region_width * 0.5, 0.1 * 4. / 3.);
3723 std::vector<Point<2> *> cylinder_pointers;
3725 if (face->manifold_id() == polar_manifold_id)
3727 cylinder_pointers.push_back(&face->vertex(0));
3728 cylinder_pointers.push_back(&face->vertex(1));
3731 std::sort(cylinder_pointers.begin(), cylinder_pointers.end());
3732 cylinder_pointers.erase(std::unique(cylinder_pointers.begin(),
3733 cylinder_pointers.end()),
3734 cylinder_pointers.end());
3738 for (
const Point<2> *
const ptr : cylinder_pointers)
3739 center += *ptr / double(cylinder_pointers.size());
3742 for (
Point<2> *
const ptr : cylinder_pointers)
3743 *ptr +=
Point<2>(0.2, 0.2) - center;
3756 if (face->at_boundary())
3758 const Point<2> center = face->center();
3760 if (
std::abs(center[0] - 0.0) < 1e-10)
3761 face->set_boundary_id(0);
3763 else if (
std::abs(center[0] - 2.2) < 1e-10)
3764 face->set_boundary_id(1);
3766 else if (face->manifold_id() == polar_manifold_id)
3767 face->set_boundary_id(2);
3772 std::abs(center[1] - 0.41) < 1.0e-10,
3774 face->set_boundary_id(3);
3784 const double shell_region_width,
3785 const unsigned int n_shells,
3786 const double skewness,
3787 const bool colorize)
3791 tria_2, shell_region_width, n_shells, skewness, colorize);
3811 tria.
set_manifold(cylindrical_manifold_id, cylindrical_manifold);
3819 if (face->boundary_id() == 4 || face->boundary_id() == 5)
3820 face->set_boundary_id(3);
3826 const std::vector<unsigned int> &,
3842 const std::vector<unsigned int> &lengths_and_heights,
3845 const double shell_region_radius,
3846 const unsigned int n_shells,
3847 const double skewness,
3848 const bool use_transfinite_region,
3849 const bool colorize)
3855 const double radius = 0.5;
3856 const double box_radius = 1;
3863 const unsigned int length_pre = lengths_and_heights[0];
3864 const unsigned int length_post = lengths_and_heights[1];
3865 const unsigned int height_below = lengths_and_heights[2];
3866 const unsigned int height_above = lengths_and_heights[3];
3868 const unsigned int length_repetitions = length_pre + length_post;
3869 const unsigned int height_repetitions = height_above + height_below;
3876 {(length_repetitions), height_repetitions},
3877 Point<2>(-
double(length_pre), -
double(height_below)),
3878 Point<2>(
double(length_post),
double(height_above)));
3896 std::set<Triangulation<2>::active_cell_iterator> cells_to_remove;
3899 if ((cell->
center() -
Point<2>(0., 0.)).norm() < 1.1 * box_radius)
3900 cells_to_remove.insert(cell);
3905 bulk_tria, cells_to_remove, tria_without_cylinder);
3912 shell_region_radius,
3920 if (!cell->
face(face_n)->at_boundary())
3921 cell->
face(face_n)->set_manifold_id(tfi_manifold_id);
3926 if (radius < shell_region_radius)
3929 ExcMessage(
"If the shell region has positive width then "
3930 "there must be at least one shell."));
3935 shell_region_radius,
3942 const double vertex_tolerance =
3943 std::min(internal::minimal_vertex_distance(shell_tria),
3944 internal::minimal_vertex_distance(cylinder_tria)) *
3950 shell_tria, cylinder_tria, temp, vertex_tolerance,
true);
3951 cylinder_tria = std::move(temp);
3956 const double vertex_tolerance =
3957 std::min(internal::minimal_vertex_distance(tria_without_cylinder),
3958 internal::minimal_vertex_distance(cylinder_tria)) /
3962 tria_without_cylinder, cylinder_tria, tria, vertex_tolerance,
true);
3981 if (use_transfinite_region)
3991 if (face->at_boundary())
3993 const Point<2> center = face->center();
3995 if (
std::abs(center[0] - (-
static_cast<double>(length_pre))) <
3997 face->set_boundary_id(0);
3999 else if (
std::abs(center[0] -
static_cast<double>(length_post)) <
4001 face->set_boundary_id(1);
4003 else if (face->manifold_id() == polar_manifold_id)
4004 face->set_boundary_id(2);
4007 (-
static_cast<double>(height_below))) < 1e-10)
4008 face->set_boundary_id(3);
4011 face->set_boundary_id(4);
4019 const std::vector<unsigned int> &lengths_and_heights,
4021 unsigned int depth_division,
4022 const double shell_region_radius,
4023 const unsigned int n_shells,
4024 const double skewness,
4025 const bool use_transfinite_region,
4026 const bool colorize)
4030 lengths_and_heights,
4033 shell_region_radius,
4036 use_transfinite_region,
4058 tria.
set_manifold(cylindrical_manifold_id, cylindrical_manifold);
4060 if (use_transfinite_region)
4071 template <
int dim,
int spacedim>
4074 const std::vector<unsigned int> &sizes,
4075 const bool colorize)
4084 for (
unsigned int d = 0;
d < dim; ++
d)
4087 std::vector<Point<spacedim>> points;
4092 std::vector<CellData<dim>> cells(n_cells);
4097 for (
unsigned int d = 0;
d < dim; ++
d)
4098 p[d] = 0.5 * dimensions[d] *
4101 points.push_back(p);
4102 cells[0].vertices[i] = i;
4104 cells[0].material_id = 0;
4107 unsigned int cell_index = 1;
4115 for (
unsigned int j = 0; j < sizes[face]; ++j, ++cell_index)
4117 const unsigned int last_cell = (j == 0) ? 0U : (cell_index - 1);
4119 for (
unsigned int v = 0; v < GeometryInfo<dim>::vertices_per_face;
4122 const unsigned int cellv =
4124 const unsigned int ocellv =
4127 cells[cell_index].vertices[ocellv] =
4128 cells[last_cell].vertices[cellv];
4131 cells[cell_index].vertices[cellv] = points.size();
4136 points.push_back(p);
4138 cells[cell_index].material_id = (colorize) ? (face + 1U) : 0
U;
4285 const double thickness,
4286 const bool colorize)
4289 ExcMessage(
"Invalid left-to-right bounds of enclosed hypercube"));
4291 std::vector<Point<2>> vertices(16);
4293 coords[0] = left - thickness;
4296 coords[3] = right + thickness;
4299 for (
const double y : coords)
4300 for (
const double x : coords)
4305 std::vector<CellData<2>> cells(9);
4307 for (
unsigned int i0 = 0; i0 < 3; ++i0)
4308 for (
unsigned int i1 = 0; i1 < 3; ++i1)
4310 cells[k].vertices[0] = i1 + 4 * i0;
4311 cells[k].vertices[1] = i1 + 4 * i0 + 1;
4312 cells[k].vertices[2] = i1 + 4 * i0 + 4;
4313 cells[k].vertices[3] = i1 + 4 * i0 + 5;
4315 cells[k].material_id = materials[k];
4331 const bool colorize)
4333 const double rl2 = (right + left) / 2;
4344 const int cell_vertices[4][4] = {{0, 1, 3, 2},
4349 for (
unsigned int i = 0; i < 4; ++i)
4351 for (
unsigned int j = 0; j < 4; ++j)
4352 cells[i].vertices[j] = cell_vertices[i][j];
4353 cells[i].material_id = 0;
4356 std::end(vertices)),
4363 cell->
face(1)->set_boundary_id(1);
4365 cell->
face(0)->set_boundary_id(2);
4374 const double radius_0,
4375 const double radius_1,
4376 const double half_length)
4380 vertices_tmp[0] =
Point<2>(-half_length, -radius_0);
4381 vertices_tmp[1] =
Point<2>(half_length, -radius_1);
4382 vertices_tmp[2] =
Point<2>(-half_length, radius_0);
4383 vertices_tmp[3] =
Point<2>(half_length, radius_1);
4385 const std::vector<Point<2>> vertices(std::begin(vertices_tmp),
4386 std::end(vertices_tmp));
4390 cell_vertices[0][i] = i;
4395 cells[0].vertices[i] = cell_vertices[0][i];
4397 cells[0].material_id = 0;
4402 cell->
face(0)->set_boundary_id(1);
4403 cell->
face(1)->set_boundary_id(2);
4405 for (
unsigned int i = 2; i < 4; ++i)
4406 cell->
face(i)->set_boundary_id(0);
4417 const bool colorize)
4423 Point<2>((a + b) / 2, (a + b) / 2),
4427 const int cell_vertices[3][4] = {{0, 1, 3, 4}, {1, 2, 4, 5}, {3, 4, 6, 7}};
4431 for (
unsigned int i = 0; i < 3; ++i)
4433 for (
unsigned int j = 0; j < 4; ++j)
4434 cells[i].vertices[j] = cell_vertices[i][j];
4435 cells[i].material_id = 0;
4439 std::end(vertices)),
4447 cell->
face(0)->set_boundary_id(0);
4448 cell->
face(2)->set_boundary_id(1);
4451 cell->
face(1)->set_boundary_id(2);
4452 cell->
face(2)->set_boundary_id(1);
4453 cell->
face(3)->set_boundary_id(3);
4456 cell->
face(0)->set_boundary_id(0);
4457 cell->
face(1)->set_boundary_id(4);
4458 cell->
face(3)->set_boundary_id(5);
4464 template <
int dim,
int spacedim>
4467 const std::vector<unsigned int> &repetitions,
4470 const std::vector<int> &n_cells_to_remove)
4476 for (
unsigned int d = 0;
d < dim; ++
d)
4478 Assert(std::fabs(n_cells_to_remove[d]) <= repetitions[d],
4479 ExcMessage(
"Attempting to cut away too many cells."));
4489 std::array<double, dim> h;
4491 for (
unsigned int d = 0;
d < dim; ++
d)
4494 h[
d] = (top_right[
d] - bottom_left[
d]) / repetitions[d];
4496 if (n_cells_to_remove[d] >= 0)
4500 h[
d] * std::fabs(n_cells_to_remove[d]) + bottom_left[
d];
4505 cut_step[
d] = top_right[
d] - h[
d] * std::fabs(n_cells_to_remove[d]);
4511 std::set<typename Triangulation<dim, spacedim>::active_cell_iterator>
4515 bool remove_cell =
true;
4516 for (
unsigned int d = 0;
d < dim && remove_cell; ++
d)
4517 if ((n_cells_to_remove[d] > 0 && cell->
center()[d] >= cut_step[d]) ||
4518 (n_cells_to_remove[d] < 0 && cell->
center()[d] <= cut_step[d]))
4519 remove_cell =
false;
4521 cells_to_remove.insert(cell);
4531 template <
int dim,
int spacedim>
4535 const double radius,
4536 const bool internal_manifolds)
4538 if constexpr (dim == 2)
4540 const auto embed_point = [](
const double x,
4542 if constexpr (spacedim == 2)
4544 else if constexpr (spacedim == 3)
4553 const double a = 1. / (1 +
std::sqrt(2.0));
4555 p + embed_point(-1., -1.) * (radius /
std::sqrt(2.0)),
4556 p + embed_point(+1., -1.) * (radius /
std::sqrt(2.0)),
4557 p + embed_point(-1., -1.) * (radius /
std::sqrt(2.0) * a),
4558 p + embed_point(+1., -1.) * (radius /
std::sqrt(2.0) * a),
4559 p + embed_point(-1., +1.) * (radius /
std::sqrt(2.0) * a),
4560 p + embed_point(+1., +1.) * (radius /
std::sqrt(2.0) * a),
4561 p + embed_point(-1., +1.) * (radius /
std::sqrt(2.0)),
4562 p + embed_point(+1., +1.) * (radius /
std::sqrt(2.0))};
4566 for (
unsigned int i = 0; i < 5; ++i)
4568 for (
unsigned int j = 0; j < 4; ++j)
4569 cells[i].vertices[j] = circle_cell_vertices[i][j];
4570 cells[i].material_id = 0;
4575 std::begin(vertices), std::end(vertices)),
4580 if (internal_manifolds)
4585 else if constexpr (dim == 3)
4591 const unsigned int n_vertices = 16;
4592 const Point<3> vertices[n_vertices] = {
4617 const unsigned int n_cells = 7;
4618 const int cell_vertices[
n_cells][8] = {
4619 {0, 1, 4, 5, 3, 2, 7, 6},
4620 {8, 9, 12, 13, 0, 1, 4, 5},
4621 {9, 13, 1, 5, 10, 14, 2, 6},
4622 {11, 10, 3, 2, 15, 14, 7, 6},
4623 {8, 0, 12, 4, 11, 3, 15, 7},
4624 {8, 9, 0, 1, 11, 10, 3, 2},
4625 {12, 4, 13, 5, 15, 7, 14, 6}};
4627 std::vector<CellData<3>> cells(n_cells,
CellData<3>());
4629 for (
unsigned int i = 0; i <
n_cells; ++i)
4632 cells[i].vertices[j] = cell_vertices[i][j];
4633 cells[i].material_id = 0;
4638 std::end(vertices)),
4643 if (internal_manifolds)
4654 template <
int spacedim>
4658 const double inner_radius,
4659 const double outer_radius,
4660 const unsigned int n_cells,
4661 const bool colorize)
4663 Assert((inner_radius > 0) && (inner_radius < outer_radius),
4677 const unsigned int N =
4678 (
n_cells == 0 ?
static_cast<unsigned int>(
4679 std::ceil((2 * pi * (outer_radius + inner_radius) / 2) /
4680 (outer_radius - inner_radius))) :
4689 std::vector<Point<spacedim>> vertices(2 * N);
4690 for (
unsigned int i = 0; i <
N; ++i)
4696 vertices[i] =
point * outer_radius;
4697 vertices[i +
N] = vertices[i] * (inner_radius / outer_radius);
4699 vertices[i] += center;
4700 vertices[i +
N] += center;
4705 for (
unsigned int i = 0; i <
N; ++i)
4707 cells[i].vertices[0] = i;
4708 cells[i].vertices[1] = (i + 1) % N;
4709 cells[i].vertices[2] =
N + i;
4710 cells[i].vertices[3] =
N + ((i + 1) %
N);
4712 cells[i].material_id = 0;
4718 colorize_hyper_shell(tria, center, inner_radius, outer_radius);
4730 const double inner_radius,
4731 const double outer_radius,
4732 const unsigned int n_cells,
4733 const bool colorize)
4735 hyper_shell_2D(tria, center, inner_radius, outer_radius, n_cells, colorize);
4744 const double inner_radius,
4745 const double outer_radius,
4746 const unsigned int n_cells,
4747 const bool colorize)
4749 hyper_shell_2D(tria, center, inner_radius, outer_radius, n_cells, colorize);
4759 const double inner_radius,
4760 const double outer_radius,
4761 const unsigned int n_cells)
4764 tria, outer_center, inner_radius, outer_radius, n_cells,
true);
4768 outer_radius - inner_radius > outer_center.
distance(inner_center),
4770 "The inner radius is greater than or equal to the outer radius plus eccentricity."));
4774 std::set<Point<dim> *> vertices_to_move;
4777 if (face->boundary_id() == 0)
4778 for (
unsigned int v = 0; v < GeometryInfo<dim>::vertices_per_face; ++v)
4779 vertices_to_move.insert(&face->vertex(v));
4781 const auto shift = inner_center - outer_center;
4782 for (
const auto &p : vertices_to_move)
4813 const double radius,
4814 const double half_length)
4816 Point<2> p1(-half_length, -radius);
4825 switch (f->boundary_id())
4828 f->set_boundary_id(1);
4831 f->set_boundary_id(2);
4834 f->set_boundary_id(0);
4872 const double radius)
4874 const unsigned int dim = 2;
4888 const int cell_vertices[3][4] = {{0, 2, 3, 4}, {1, 6, 2, 4}, {5, 3, 6, 4}};
4892 for (
unsigned int i = 0; i < 3; ++i)
4894 for (
unsigned int j = 0; j < 4; ++j)
4895 cells[i].vertices[j] = cell_vertices[i][j];
4896 cells[i].material_id = 0;
4900 std::end(vertices)),
4913 if (cell->
face(i)->boundary_id() ==
4919 if (cell->
face(i)->center()[0] < p[0] + 1.e-5 * radius ||
4920 cell->
face(i)->center()[1] < p[1] + 1.e-5 * radius)
4922 cell->
face(i)->set_boundary_id(1);
4936 const double radius)
4941 const double a = 1. / (1 +
std::sqrt(2.0));
4952 const int cell_vertices[5][4] = {{0, 1, 2, 3},
4959 for (
unsigned int i = 0; i < 4; ++i)
4961 for (
unsigned int j = 0; j < 4; ++j)
4962 cells[i].vertices[j] = cell_vertices[i][j];
4963 cells[i].material_id = 0;
4967 std::end(vertices)),
4980 if (cell->
face(i)->boundary_id() ==
4985 if (cell->
face(i)->center()[0] < p[0] + 1.e-5 * radius)
4987 cell->
face(i)->set_boundary_id(1);
5003 const double inner_radius,
5004 const double outer_radius,
5005 const unsigned int n_cells,
5006 const bool colorize)
5008 Assert((inner_radius > 0) && (inner_radius < outer_radius),
5021 const unsigned int N =
5022 (
n_cells == 0 ?
static_cast<unsigned int>(
5023 std::ceil((pi * (outer_radius + inner_radius) / 2) /
5024 (outer_radius - inner_radius))) :
5033 std::vector<Point<2>> vertices(2 * (N + 1));
5034 for (
unsigned int i = 0; i <=
N; ++i)
5046 vertices[i +
N + 1] = vertices[i] * (inner_radius / outer_radius);
5048 vertices[i] += center;
5049 vertices[i +
N + 1] += center;
5055 for (
unsigned int i = 0; i <
N; ++i)
5057 cells[i].vertices[0] = i;
5058 cells[i].vertices[1] = (i + 1) % (N + 1);
5059 cells[i].vertices[2] =
N + 1 + i;
5060 cells[i].vertices[3] =
N + 1 + ((i + 1) % (
N + 1));
5062 cells[i].material_id = 0;
5070 for (; cell != tria.
end(); ++cell)
5072 cell->
face(2)->set_boundary_id(1);
5074 tria.
begin()->
face(0)->set_boundary_id(3);
5076 tria.
last()->
face(1)->set_boundary_id(2);
5087 const double inner_radius,
5088 const double outer_radius,
5089 const unsigned int n_cells,
5090 const bool colorize)
5092 Assert((inner_radius > 0) && (inner_radius < outer_radius),
5105 const unsigned int N =
5106 (
n_cells == 0 ?
static_cast<unsigned int>(
5107 std::ceil((pi * (outer_radius + inner_radius) / 4) /
5108 (outer_radius - inner_radius))) :
5117 std::vector<Point<2>> vertices(2 * (N + 1));
5118 for (
unsigned int i = 0; i <=
N; ++i)
5128 vertices[i +
N + 1] = vertices[i] * (inner_radius / outer_radius);
5130 vertices[i] += center;
5131 vertices[i +
N + 1] += center;
5137 for (
unsigned int i = 0; i <
N; ++i)
5139 cells[i].vertices[0] = i;
5140 cells[i].vertices[1] = (i + 1) % (N + 1);
5141 cells[i].vertices[2] =
N + 1 + i;
5142 cells[i].vertices[3] =
N + 1 + ((i + 1) % (
N + 1));
5144 cells[i].material_id = 0;
5152 for (; cell != tria.
end(); ++cell)
5154 cell->
face(2)->set_boundary_id(1);
5156 tria.
begin()->
face(0)->set_boundary_id(3);
5158 tria.
last()->
face(1)->set_boundary_id(2);
5173 const bool colorize)
5175 const double rl2 = (right + left) / 2;
5176 const double len = (right - left) / 2.;
5189 const int cell_vertices[4][8] = {{0, 1, 3, 2, 10, 11, 13, 12},
5190 {9, 4, 2, 5, 19, 14, 12, 15},
5191 {3, 2, 7, 6, 13, 12, 17, 16},
5192 {2, 5, 6, 8, 12, 15, 16, 18}};
5194 for (
unsigned int i = 0; i < 4; ++i)
5196 for (
unsigned int j = 0; j < 8; ++j)
5197 cells[i].vertices[j] = cell_vertices[i][j];
5198 cells[i].material_id = 0;
5201 std::end(vertices)),
5208 cell->
face(1)->set_boundary_id(1);
5210 cell->
face(0)->set_boundary_id(2);
5222 const double thickness,
5223 const bool colorize)
5226 ExcMessage(
"Invalid left-to-right bounds of enclosed hypercube"));
5228 std::vector<Point<3>> vertices(64);
5230 coords[0] = left - thickness;
5233 coords[3] = right + thickness;
5236 for (
const double z : coords)
5237 for (
const double y : coords)
5238 for (
const double x : coords)
5242 24, 26, 5, 4, 6, 1, 0,
5243 2, 9, 8, 10, 37, 36, 38,
5244 33, 32, 34, 41, 40, 42};
5246 std::vector<CellData<3>> cells(27);
5248 for (
unsigned int z = 0; z < 3; ++z)
5249 for (
unsigned int y = 0; y < 3; ++y)
5250 for (
unsigned int x = 0; x < 3; ++x)
5252 cells[k].vertices[0] = x + 4 * y + 16 * z;
5253 cells[k].vertices[1] = x + 4 * y + 16 * z + 1;
5254 cells[k].vertices[2] = x + 4 * y + 16 * z + 4;
5255 cells[k].vertices[3] = x + 4 * y + 16 * z + 5;
5256 cells[k].vertices[4] = x + 4 * y + 16 * z + 16;
5257 cells[k].vertices[5] = x + 4 * y + 16 * z + 17;
5258 cells[k].vertices[6] = x + 4 * y + 16 * z + 20;
5259 cells[k].vertices[7] = x + 4 * y + 16 * z + 21;
5261 cells[k].material_id = materials[k];
5274 const double radius_0,
5275 const double radius_1,
5276 const double half_length)
5279 ExcMessage(
"The output triangulation object needs to be empty."));
5284 const auto n_slices = 1 +
static_cast<unsigned int>(std::ceil(
5285 half_length /
std::max(radius_0, radius_1)));
5298 auto shift_radii = [=](
const Point<3> &p) {
5299 const double slope = (radius_1 / radius_0 - 1.0) / (2.0 * half_length);
5300 const double factor = slope * (p[0] - -half_length) + 1.0;
5301 return Point<3>(p[0], factor * p[1], factor * p[2]);
5308 if (face->at_boundary())
5310 if (
std::abs(face->center()[0] - -half_length) < 1e-8 * half_length)
5311 face->set_boundary_id(1);
5312 else if (
std::abs(face->center()[0] - half_length) <
5314 face->set_boundary_id(2);
5316 face->set_all_manifold_ids(0);
5329 const bool colorize)
5339 Point<3>((a + b) / 2, a, (a + b) / 2),
5346 Point<3>((a + b) / 2, (a + b) / 2, a),
5348 Point<3>(a, (a + b) / 2, (a + b) / 2),
5349 Point<3>((a + b) / 2, (a + b) / 2, (a + b) / 2),
5350 Point<3>(b, (a + b) / 2, (a + b) / 2),
5352 Point<3>((a + b) / 2, (a + b) / 2, b),
5360 Point<3>((a + b) / 2, b, (a + b) / 2),
5364 const int cell_vertices[7][8] = {{0, 1, 9, 10, 3, 4, 12, 13},
5365 {1, 2, 10, 11, 4, 5, 13, 14},
5366 {3, 4, 12, 13, 6, 7, 15, 16},
5367 {4, 5, 13, 14, 7, 8, 16, 17},
5368 {9, 10, 18, 19, 12, 13, 21, 22},
5369 {10, 11, 19, 20, 13, 14, 22, 23},
5370 {12, 13, 21, 22, 15, 16, 24, 25}};
5374 for (
unsigned int i = 0; i < 7; ++i)
5376 for (
unsigned int j = 0; j < 8; ++j)
5377 cells[i].vertices[j] = cell_vertices[i][j];
5378 cells[i].material_id = 0;
5382 std::end(vertices)),
5396 const unsigned int n_rotate_middle_square)
5399 ExcMessage(
"The number of rotation by pi/2 of the right square "
5400 "must be in the half-open range [0,4)."));
5402 constexpr unsigned int dim = 2;
5404 const unsigned int n_cells = 5;
5405 std::vector<CellData<dim>> cells(n_cells);
5408 const std::vector<Point<dim>> vertices = {
Point<dim>(0, 0),
5423 unsigned int cell_vertices[
n_cells][4] = {{0, 1, 2, 3},
5429 switch (n_rotate_middle_square)
5433 cell_vertices[1][0] = 4;
5434 cell_vertices[1][1] = 5;
5435 cell_vertices[1][2] = 1;
5436 cell_vertices[1][3] = 3;
5442 cell_vertices[1][0] = 5;
5443 cell_vertices[1][1] = 3;
5444 cell_vertices[1][2] = 4;
5445 cell_vertices[1][3] = 1;
5451 cell_vertices[1][0] = 3;
5452 cell_vertices[1][1] = 1;
5453 cell_vertices[1][2] = 5;
5454 cell_vertices[1][3] = 4;
5464 for (
unsigned int cell_index = 0; cell_index <
n_cells; ++cell_index)
5466 for (
const unsigned int vertex_index :
5469 cells[cell_index].vertices[vertex_index] =
5470 cell_vertices[cell_index][vertex_index];
5471 cells[cell_index].material_id = 0;
5481 const bool face_orientation,
5482 const bool face_flip,
5483 const bool face_rotation,
5484 const bool manipulate_left_cube)
5486 constexpr unsigned int dim = 3;
5488 const unsigned int n_cells = 2;
5489 std::vector<CellData<dim>> cells(n_cells);
5492 const std::vector<Point<dim>> vertices = {
Point<dim>(0, 0, 0),
5505 unsigned int cell_vertices[
n_cells][8] = {
5506 {0, 1, 2, 3, 4, 5, 6, 7},
5507 {1, 8, 3, 9, 5, 10, 7, 11}};
5510 const unsigned int this_case = 4 *
static_cast<int>(face_orientation) +
5511 2 *
static_cast<int>(face_flip) +
5512 static_cast<int>(face_rotation);
5514 if (manipulate_left_cube)
5520 cell_vertices[0][0] = 1;
5521 cell_vertices[0][1] = 0;
5522 cell_vertices[0][2] = 5;
5523 cell_vertices[0][3] = 4;
5524 cell_vertices[0][4] = 3;
5525 cell_vertices[0][5] = 2;
5526 cell_vertices[0][6] = 7;
5527 cell_vertices[0][7] = 6;
5533 cell_vertices[0][0] = 5;
5534 cell_vertices[0][1] = 4;
5535 cell_vertices[0][2] = 7;
5536 cell_vertices[0][3] = 6;
5537 cell_vertices[0][4] = 1;
5538 cell_vertices[0][5] = 0;
5539 cell_vertices[0][6] = 3;
5540 cell_vertices[0][7] = 2;
5546 cell_vertices[0][0] = 7;
5547 cell_vertices[0][1] = 6;
5548 cell_vertices[0][2] = 3;
5549 cell_vertices[0][3] = 2;
5550 cell_vertices[0][4] = 5;
5551 cell_vertices[0][5] = 4;
5552 cell_vertices[0][6] = 1;
5553 cell_vertices[0][7] = 0;
5558 cell_vertices[0][0] = 3;
5559 cell_vertices[0][1] = 2;
5560 cell_vertices[0][2] = 1;
5561 cell_vertices[0][3] = 0;
5562 cell_vertices[0][4] = 7;
5563 cell_vertices[0][5] = 6;
5564 cell_vertices[0][6] = 5;
5565 cell_vertices[0][7] = 4;
5571 cell_vertices[0][0] = 0;
5572 cell_vertices[0][1] = 1;
5573 cell_vertices[0][2] = 2;
5574 cell_vertices[0][3] = 3;
5575 cell_vertices[0][4] = 4;
5576 cell_vertices[0][5] = 5;
5577 cell_vertices[0][6] = 6;
5578 cell_vertices[0][7] = 7;
5584 cell_vertices[0][0] = 2;
5585 cell_vertices[0][1] = 3;
5586 cell_vertices[0][2] = 6;
5587 cell_vertices[0][3] = 7;
5588 cell_vertices[0][4] = 0;
5589 cell_vertices[0][5] = 1;
5590 cell_vertices[0][6] = 4;
5591 cell_vertices[0][7] = 5;
5597 cell_vertices[0][0] = 6;
5598 cell_vertices[0][1] = 7;
5599 cell_vertices[0][2] = 4;
5600 cell_vertices[0][3] = 5;
5601 cell_vertices[0][4] = 2;
5602 cell_vertices[0][5] = 3;
5603 cell_vertices[0][6] = 0;
5604 cell_vertices[0][7] = 1;
5610 cell_vertices[0][0] = 4;
5611 cell_vertices[0][1] = 5;
5612 cell_vertices[0][2] = 0;
5613 cell_vertices[0][3] = 1;
5614 cell_vertices[0][4] = 6;
5615 cell_vertices[0][5] = 7;
5616 cell_vertices[0][6] = 2;
5617 cell_vertices[0][7] = 3;
5628 cell_vertices[1][0] = 8;
5629 cell_vertices[1][1] = 1;
5630 cell_vertices[1][2] = 10;
5631 cell_vertices[1][3] = 5;
5632 cell_vertices[1][4] = 9;
5633 cell_vertices[1][5] = 3;
5634 cell_vertices[1][6] = 11;
5635 cell_vertices[1][7] = 7;
5641 cell_vertices[1][0] = 10;
5642 cell_vertices[1][1] = 5;
5643 cell_vertices[1][2] = 11;
5644 cell_vertices[1][3] = 7;
5645 cell_vertices[1][4] = 8;
5646 cell_vertices[1][5] = 1;
5647 cell_vertices[1][6] = 9;
5648 cell_vertices[1][7] = 3;
5654 cell_vertices[1][0] = 11;
5655 cell_vertices[1][1] = 7;
5656 cell_vertices[1][2] = 9;
5657 cell_vertices[1][3] = 3;
5658 cell_vertices[1][4] = 10;
5659 cell_vertices[1][5] = 5;
5660 cell_vertices[1][6] = 8;
5661 cell_vertices[1][7] = 1;
5667 cell_vertices[1][0] = 9;
5668 cell_vertices[1][1] = 3;
5669 cell_vertices[1][2] = 8;
5670 cell_vertices[1][3] = 1;
5671 cell_vertices[1][4] = 11;
5672 cell_vertices[1][5] = 7;
5673 cell_vertices[1][6] = 10;
5674 cell_vertices[1][7] = 5;
5680 cell_vertices[1][0] = 1;
5681 cell_vertices[1][1] = 8;
5682 cell_vertices[1][2] = 3;
5683 cell_vertices[1][3] = 9;
5684 cell_vertices[1][4] = 5;
5685 cell_vertices[1][5] = 10;
5686 cell_vertices[1][6] = 7;
5687 cell_vertices[1][7] = 11;
5693 cell_vertices[1][0] = 5;
5694 cell_vertices[1][1] = 10;
5695 cell_vertices[1][2] = 1;
5696 cell_vertices[1][3] = 8;
5697 cell_vertices[1][4] = 7;
5698 cell_vertices[1][5] = 11;
5699 cell_vertices[1][6] = 3;
5700 cell_vertices[1][7] = 9;
5706 cell_vertices[1][0] = 7;
5707 cell_vertices[1][1] = 11;
5708 cell_vertices[1][2] = 5;
5709 cell_vertices[1][3] = 10;
5710 cell_vertices[1][4] = 3;
5711 cell_vertices[1][5] = 9;
5712 cell_vertices[1][6] = 1;
5713 cell_vertices[1][7] = 8;
5719 cell_vertices[1][0] = 3;
5720 cell_vertices[1][1] = 9;
5721 cell_vertices[1][2] = 7;
5722 cell_vertices[1][3] = 11;
5723 cell_vertices[1][4] = 1;
5724 cell_vertices[1][5] = 8;
5725 cell_vertices[1][6] = 5;
5726 cell_vertices[1][7] = 10;
5734 for (
unsigned int cell_index = 0; cell_index <
n_cells; ++cell_index)
5736 for (
const unsigned int vertex_index :
5739 cells[cell_index].vertices[vertex_index] =
5740 cell_vertices[cell_index][vertex_index];
5741 cells[cell_index].material_id = 0;
5750 template <
int spacedim>
5754 const double radius)
5758 const std::set<types::boundary_id> boundary_ids = {0};
5770 const unsigned int x_subdivisions,
5771 const double radius,
5772 const double half_length)
5779 std::vector<Point<3>> vertices;
5780 const double initial_height = -half_length;
5781 const double height_increment = 2. * half_length / x_subdivisions;
5783 for (
unsigned int rep = 0; rep < (x_subdivisions + 1); ++rep)
5785 const double height = initial_height + height_increment * rep;
5787 vertices.emplace_back(-d, height, -d);
5788 vertices.emplace_back(d, height, -d);
5789 vertices.emplace_back(-a, height, -a);
5790 vertices.emplace_back(a, height, -a);
5791 vertices.emplace_back(-a, height, a);
5792 vertices.emplace_back(a, height, a);
5793 vertices.emplace_back(-d, height, d);
5794 vertices.emplace_back(d, height, d);
5798 for (
auto &vertex : vertices)
5800 const double h = vertex[1];
5801 vertex[1] = -vertex[0];
5805 std::vector<std::vector<int>> cell_vertices;
5806 cell_vertices.push_back({0, 1, 8, 9, 2, 3, 10, 11});
5807 cell_vertices.push_back({0, 2, 8, 10, 6, 4, 14, 12});
5808 cell_vertices.push_back({2, 3, 10, 11, 4, 5, 12, 13});
5809 cell_vertices.push_back({1, 7, 9, 15, 3, 5, 11, 13});
5810 cell_vertices.push_back({6, 4, 14, 12, 7, 5, 15, 13});
5812 for (
unsigned int rep = 1; rep < x_subdivisions; ++rep)
5814 for (
unsigned int i = 0; i < 5; ++i)
5816 std::vector<int> new_cell_vertices(8);
5817 for (
unsigned int j = 0; j < 8; ++j)
5818 new_cell_vertices[j] = cell_vertices[i][j] + 8 * rep;
5819 cell_vertices.push_back(new_cell_vertices);
5823 unsigned int n_cells = x_subdivisions * 5;
5825 std::vector<CellData<3>> cells(n_cells,
CellData<3>());
5827 for (
unsigned int i = 0; i <
n_cells; ++i)
5829 for (
unsigned int j = 0; j < 8; ++j)
5830 cells[i].vertices[j] = cell_vertices[i][j];
5831 cells[i].material_id = 0;
5835 std::end(vertices)),
5853 const double tolerance = 1
e-5 *
std::min(radius, half_length);
5859 if (cell->
face(i)->center()[0] > half_length - tolerance)
5861 cell->
face(i)->set_boundary_id(2);
5864 for (
unsigned int e = 0; e < GeometryInfo<3>::lines_per_face;
5866 if ((std::fabs(cell->
face(i)->line(e)->vertex(0)[1]) == a) ||
5867 (std::fabs(cell->
face(i)->line(e)->vertex(0)[2]) == a) ||
5868 (std::fabs(cell->
face(i)->line(e)->vertex(1)[1]) == a) ||
5869 (std::fabs(cell->
face(i)->line(e)->vertex(1)[2]) == a))
5871 cell->
face(i)->line(e)->set_boundary_id(2);
5872 cell->
face(i)->line(e)->set_manifold_id(
5876 else if (cell->
face(i)->center()[0] < -half_length + tolerance)
5878 cell->
face(i)->set_boundary_id(1);
5881 for (
unsigned int e = 0; e < GeometryInfo<3>::lines_per_face;
5883 if ((std::fabs(cell->
face(i)->line(e)->vertex(0)[1]) == a) ||
5884 (std::fabs(cell->
face(i)->line(e)->vertex(0)[2]) == a) ||
5885 (std::fabs(cell->
face(i)->line(e)->vertex(1)[1]) == a) ||
5886 (std::fabs(cell->
face(i)->line(e)->vertex(1)[2]) == a))
5888 cell->
face(i)->line(e)->set_boundary_id(1);
5889 cell->
face(i)->line(e)->set_manifold_id(
5901 const double radius,
5902 const double half_length)
5911 const double radius)
5913 const unsigned int dim = 3;
5921 const double a = 0.528;
5922 const double b = 0.4533;
5923 const double c = 0.3752;
5927 center +
Point<dim>(+1, 0, 0) * (radius * a),
5928 center +
Point<dim>(0, +1, 0) * (radius * a),
5936 center +
Point<dim>(+1, +1, 1) * (radius * c),
5940 const int cell_vertices[4][8] = {{0, 2, 3, 4, 7, 9, 10, 11},
5941 {1, 6, 2, 4, 8, 13, 9, 11},
5942 {5, 3, 6, 4, 12, 10, 13, 11},
5943 {7, 9, 10, 11, 14, 8, 12, 13}};
5947 for (
unsigned int i = 0; i < 4; ++i)
5949 for (
unsigned int j = 0; j < 8; ++j)
5950 cells[i].vertices[j] = cell_vertices[i][j];
5951 cells[i].material_id = 0;
5955 std::end(vertices)),
5967 if (cell->
face(i)->boundary_id() ==
5972 if (cell->
face(i)->center()[0] < center[0] + 1.e-5 * radius ||
5973 cell->
face(i)->center()[1] < center[1] + 1.e-5 * radius ||
5974 cell->
face(i)->center()[2] < center[2] + 1.e-5 * radius)
5976 cell->
face(i)->set_boundary_id(1);
5980 for (
unsigned int j = 0; j < GeometryInfo<3>::lines_per_face;
5983 const Point<3> line_vertices[2] = {
5984 cell->
face(i)->line(j)->vertex(0),
5985 cell->
face(i)->line(j)->vertex(1)};
5986 if ((std::fabs(line_vertices[0].distance(center) - radius) >
5988 (std::fabs(line_vertices[1].distance(center) - radius) >
5991 cell->
face(i)->line(j)->set_boundary_id(1);
5992 cell->
face(i)->line(j)->set_manifold_id(
6010 const double radius)
6016 const double b = a / 2.0;
6017 const double c =
d / 2.0;
6019 const double hb = radius *
std::sqrt(3.0) / 4.0;
6020 const double hc = radius *
std::sqrt(3.0) / 2.0;
6042 int cell_vertices[6][8] = {{0, 1, 8, 9, 2, 3, 10, 11},
6043 {0, 2, 8, 10, 6, 4, 14, 12},
6044 {2, 3, 10, 11, 4, 5, 12, 13},
6045 {1, 7, 9, 15, 3, 5, 11, 13},
6046 {6, 4, 14, 12, 7, 5, 15, 13},
6047 {8, 10, 9, 11, 14, 12, 15, 13}};
6051 for (
unsigned int i = 0; i < 6; ++i)
6053 for (
unsigned int j = 0; j < 8; ++j)
6054 cells[i].vertices[j] = cell_vertices[i][j];
6055 cells[i].material_id = 0;
6059 std::end(vertices)),
6083 if (cell->
face(i)->center()[0] < center[0] + 1.e-5 * radius)
6085 cell->
face(i)->set_boundary_id(1);
6087 for (
unsigned int j = 0; j < GeometryInfo<3>::lines_per_face;
6090 const Point<3> line_vertices[2] = {
6091 cell->
face(i)->line(j)->vertex(0),
6092 cell->
face(i)->line(j)->vertex(1)};
6093 if ((std::fabs(line_vertices[0].distance(center) - radius) >
6095 (std::fabs(line_vertices[1].distance(center) - radius) >
6098 cell->
face(i)->line(j)->set_boundary_id(1);
6099 cell->
face(i)->line(j)->set_manifold_id(
6116 const double radius)
6129 for (
unsigned int round = 0; round < dim; ++round)
6134 std::vector<Point<dim>> new_points(tria_copy.
n_vertices());
6136 for (
unsigned int v = 0; v < tria_copy.
n_vertices(); ++v)
6144 else if (round == 1)
6146 for (
unsigned int v = 0; v < tria_copy.
n_vertices(); ++v)
6155 else if (round == 2)
6156 for (
unsigned int v = 0; v < tria_copy.
n_vertices(); ++v)
6169 std::vector<CellData<dim>> cells;
6170 cells.reserve(tria_copy.
n_cells());
6178 cells.push_back(data);
6186 if (round == dim - 1)
6216 hyper_shell_6(Triangulation<3> &tria,
6218 const double inner_radius,
6219 const double outer_radius)
6221 std::vector<Point<3>> vertices;
6222 std::vector<CellData<3>> cells;
6224 const double irad = inner_radius /
std::sqrt(3.0);
6225 const double orad = outer_radius /
std::sqrt(3.0);
6228 static const std::array<Point<3>, 8> hexahedron = {{{-1, -1, -1},
6238 vertices.reserve(8);
6239 for (
unsigned int i = 0; i < 8; ++i)
6240 vertices.push_back(p + hexahedron[i] * irad);
6241 for (
unsigned int i = 0; i < 8; ++i)
6242 vertices.push_back(p + hexahedron[i] * orad);
6244 const unsigned int n_cells = 6;
6245 const int cell_vertices[
n_cells][8] = {
6246 {8, 9, 10, 11, 0, 1, 2, 3},
6247 {9, 11, 1, 3, 13, 15, 5, 7},
6248 {12, 13, 4, 5, 14, 15, 6, 7},
6249 {8, 0, 10, 2, 12, 4, 14, 6},
6250 {8, 9, 0, 1, 12, 13, 4, 5},
6251 {10, 2, 11, 3, 14, 6, 15, 7}};
6253 cells.resize(n_cells, CellData<3>());
6255 for (
unsigned int i = 0; i <
n_cells; ++i)
6258 cells[i].vertices[j] = cell_vertices[i][j];
6259 cells[i].material_id = 0;
6268 hyper_shell_12(Triangulation<3> &tria,
6270 const double inner_radius,
6271 const double outer_radius)
6273 std::vector<Point<3>> vertices;
6274 std::vector<CellData<3>> cells;
6276 const double irad = inner_radius /
std::sqrt(3.0);
6277 const double orad = outer_radius /
std::sqrt(3.0);
6283 static const std::array<Point<3>, 6> octahedron = {{{-1, 0, 0},
6291 static const std::array<Point<3>, 8> hexahedron = {{{-1, -1, -1},
6300 vertices.reserve(8);
6301 for (
unsigned int i = 0; i < 8; ++i)
6302 vertices.push_back(p + hexahedron[i] * irad);
6303 for (
unsigned int i = 0; i < 6; ++i)
6304 vertices.push_back(p + octahedron[i] * inner_radius);
6305 for (
unsigned int i = 0; i < 8; ++i)
6306 vertices.push_back(p + hexahedron[i] * orad);
6307 for (
unsigned int i = 0; i < 6; ++i)
6308 vertices.push_back(p + octahedron[i] * outer_radius);
6310 const unsigned int n_cells = 12;
6311 const unsigned int rhombi[
n_cells][4] = {{10, 4, 0, 8},
6324 cells.resize(n_cells, CellData<3>());
6326 for (
unsigned int i = 0; i <
n_cells; ++i)
6328 for (
unsigned int j = 0; j < 4; ++j)
6330 cells[i].vertices[j] = rhombi[i][j];
6331 cells[i].vertices[j + 4] = rhombi[i][j] + 14;
6333 cells[i].material_id = 0;
6342 hyper_shell_24_48(Triangulation<3> &tria,
6343 const unsigned int n,
6344 const unsigned int n_refinement_steps,
6346 const double inner_radius,
6347 const double outer_radius)
6359 Triangulation<3> tmp;
6360 const unsigned int outer_radius_factor = 1 << n_refinement_steps;
6365 outer_radius_factor * outer_radius -
6366 (outer_radius_factor - 1) * inner_radius);
6371 outer_radius_factor * outer_radius -
6372 (outer_radius_factor - 1) * inner_radius);
6375 for (
unsigned int r = 0; r < n_refinement_steps; ++r)
6378 std::set<Triangulation<3>::active_cell_iterator> cells_to_remove;
6384 unsigned int n_vertices_inside = 0;
6386 if ((cell->
vertex(v) - p).norm_square() <
6387 inner_radius * inner_radius * (1 + 1e-12))
6388 ++n_vertices_inside;
6389 if (n_vertices_inside < 4)
6390 cells_to_remove.insert(cell);
6394 if (r == n_refinement_steps - 1)
6400 Triangulation<3>
copy;
6404 tmp = std::move(copy);
6422 const double inner_radius,
6423 const double outer_radius,
6424 const unsigned int n_cells,
6425 const bool colorize)
6427 Assert((inner_radius > 0) && (inner_radius < outer_radius),
6430 unsigned int n_refinement_steps = 0;
6431 unsigned int n_cells_coarsened =
n_cells;
6432 if (n_cells != 96 && n_cells > 12)
6433 while (n_cells_coarsened > 12 && n_cells_coarsened % 4 == 0)
6435 ++n_refinement_steps;
6436 n_cells_coarsened /= 4;
6438 Assert(n_cells == 0 || n_cells == 6 || n_cells == 12 || n_cells == 96 ||
6439 (n_refinement_steps > 0 &&
6440 (n_cells_coarsened == 6 || n_cells_coarsened == 12)),
6441 ExcMessage(
"Invalid number of coarse mesh cells"));
6443 const unsigned int n = n_refinement_steps > 0 ?
6444 4 * n_cells_coarsened :
6450 internal::hyper_shell_6(tria, p, inner_radius, outer_radius);
6453 internal::hyper_shell_12(tria, p, inner_radius, outer_radius);
6457 internal::hyper_shell_24_48(
6458 tria, n, n_refinement_steps, p, inner_radius, outer_radius);
6467 internal::hyper_shell_12(tmp, p, inner_radius, outer_radius);
6484 colorize_hyper_shell(tria, p, inner_radius, outer_radius);
6494 const double inner_radius,
6495 const double outer_radius,
6496 const unsigned int ,
6497 const bool colorize)
6499 Assert((inner_radius > 0) && (inner_radius < outer_radius),
6503 const double d = outer_radius /
std::sqrt(2.0);
6504 const double a = inner_radius /
std::sqrt(2.0);
6506 const double b = a / 2.0;
6507 const double c =
d / 2.0;
6509 const double hb = inner_radius *
std::sqrt(3.0) / 2.0;
6510 const double hc = outer_radius *
std::sqrt(3.0) / 2.0;
6532 int cell_vertices[5][8] = {{0, 1, 8, 9, 2, 3, 10, 11},
6533 {0, 2, 8, 10, 6, 4, 14, 12},
6534 {1, 7, 9, 15, 3, 5, 11, 13},
6535 {6, 4, 14, 12, 7, 5, 15, 13},
6536 {8, 10, 9, 11, 14, 12, 15, 13}};
6540 for (
unsigned int i = 0; i < 5; ++i)
6542 for (
unsigned int j = 0; j < 8; ++j)
6543 cells[i].vertices[j] = cell_vertices[i][j];
6544 cells[i].material_id = 0;
6548 std::end(vertices)),
6563 cell->
face(f)->set_all_boundary_ids(2);
6574 const Point<3> face_center(face->center(
true));
6576 if (
std::abs(face_center[0] - center[0]) >
6577 1.e-6 * face_center.
norm())
6579 if (
std::abs((face_center - center).
norm() - inner_radius) <
6580 std::abs((face_center - center).
norm() - outer_radius))
6581 face->set_all_boundary_ids(0);
6583 face->set_all_boundary_ids(1);
6595 const double inner_radius,
6596 const double outer_radius,
6597 const unsigned int n,
6598 const bool colorize)
6600 Assert((inner_radius > 0) && (inner_radius < outer_radius),
6602 if (n == 0 || n == 3)
6604 const double a = inner_radius *
std::sqrt(2.0) / 2e0;
6605 const double b = outer_radius *
std::sqrt(2.0) / 2e0;
6606 const double c = a *
std::sqrt(3.0) / 2e0;
6608 const double e = outer_radius / 2e0;
6609 const double h = inner_radius / 2e0;
6611 std::vector<Point<3>> vertices;
6613 vertices.push_back(center +
Point<3>(0, inner_radius, 0));
6614 vertices.push_back(center +
Point<3>(a, a, 0));
6615 vertices.push_back(center +
Point<3>(b, b, 0));
6616 vertices.push_back(center +
Point<3>(0, outer_radius, 0));
6617 vertices.push_back(center +
Point<3>(0, a, a));
6618 vertices.push_back(center +
Point<3>(c, c, h));
6619 vertices.push_back(center +
Point<3>(d, d, e));
6620 vertices.push_back(center +
Point<3>(0, b, b));
6621 vertices.push_back(center +
Point<3>(inner_radius, 0, 0));
6622 vertices.push_back(center +
Point<3>(outer_radius, 0, 0));
6623 vertices.push_back(center +
Point<3>(a, 0, a));
6624 vertices.push_back(center +
Point<3>(b, 0, b));
6625 vertices.push_back(center +
Point<3>(0, 0, inner_radius));
6626 vertices.push_back(center +
Point<3>(0, 0, outer_radius));
6628 const int cell_vertices[3][8] = {
6629 {0, 1, 3, 2, 4, 5, 7, 6},
6630 {1, 8, 2, 9, 5, 10, 6, 11},
6631 {4, 5, 7, 6, 12, 10, 13, 11},
6633 std::vector<CellData<3>> cells(3);
6635 for (
unsigned int i = 0; i < 3; ++i)
6637 for (
unsigned int j = 0; j < 8; ++j)
6638 cells[i].vertices[j] = cell_vertices[i][j];
6639 cells[i].material_id = 0;
6655 colorize_quarter_hyper_shell(tria, center, inner_radius, outer_radius);
6663 const double length,
6664 const double inner_radius,
6665 const double outer_radius,
6666 const unsigned int n_radial_cells,
6667 const unsigned int n_axial_cells,
6668 const bool colorize)
6670 Assert((inner_radius > 0) && (inner_radius < outer_radius),
6684 const unsigned int N_r =
6685 (n_radial_cells == 0 ?
static_cast<unsigned int>(std::ceil(
6686 (2 * pi * (outer_radius + inner_radius) / 2) /
6687 (outer_radius - inner_radius))) :
6689 const unsigned int N_z =
6690 (n_axial_cells == 0 ?
6691 static_cast<unsigned int>(std::ceil(
6692 length / (2 * pi * (outer_radius + inner_radius) / 2 / N_r))) :
6701 std::vector<Point<2>> vertices_2d(2 * N_r);
6702 for (
unsigned int i = 0; i < N_r; ++i)
6707 vertices_2d[i + N_r] = vertices_2d[i] * (inner_radius / outer_radius);
6710 std::vector<Point<3>> vertices_3d;
6711 vertices_3d.reserve(2 * N_r * (N_z + 1));
6712 for (
unsigned int j = 0; j <= N_z; ++j)
6713 for (
unsigned int i = 0; i < 2 * N_r; ++i)
6715 const Point<3> v(vertices_2d[i][0],
6718 vertices_3d.push_back(v);
6721 std::vector<CellData<3>> cells(N_r * N_z,
CellData<3>());
6723 for (
unsigned int j = 0; j < N_z; ++j)
6724 for (
unsigned int i = 0; i < N_r; ++i)
6726 cells[i + j * N_r].vertices[0] = i + (j + 1) * 2 * N_r;
6727 cells[i + j * N_r].vertices[1] = (i + 1) % N_r + (j + 1) * 2 * N_r;
6728 cells[i + j * N_r].vertices[2] = i + j * 2 * N_r;
6729 cells[i + j * N_r].vertices[3] = (i + 1) % N_r + j * 2 * N_r;
6731 cells[i + j * N_r].vertices[4] = N_r + i + (j + 1) * 2 * N_r;
6732 cells[i + j * N_r].vertices[5] =
6733 N_r + ((i + 1) % N_r) + (j + 1) * 2 * N_r;
6734 cells[i + j * N_r].vertices[6] = N_r + i + j * 2 * N_r;
6735 cells[i + j * N_r].vertices[7] = N_r + ((i + 1) % N_r) + j * 2 * N_r;
6737 cells[i + j * N_r].material_id = 0;
6756 double eps_z = 1
e-6 * length;
6761 double face_inner_radius = std::numeric_limits<double>::max();
6762 double face_outer_radius = 0.;
6770 if (!cell->
face(f)->at_boundary())
6773 const auto face_center = cell->
face(f)->center();
6774 const double z = face_center[2];
6776 if ((std::fabs(z) > eps_z) &&
6777 (std::fabs(z - length) > eps_z))
6779 const double radius =
std::sqrt(face_center[0] * face_center[0] +
6780 face_center[1] * face_center[1]);
6781 face_inner_radius =
std::min(face_inner_radius, radius);
6782 face_outer_radius =
std::max(face_outer_radius, radius);
6786 double mid_radial_distance = 0.5 * (face_outer_radius - face_inner_radius);
6791 if (cell->
face(f)->at_boundary())
6793 const auto face_center = cell->
face(f)->center();
6795 const double radius =
std::sqrt(face_center[0] * face_center[0] +
6796 face_center[1] * face_center[1]);
6798 const double z = face_center[2];
6800 if (std::fabs(z) < eps_z)
6802 cell->
face(f)->set_boundary_id(2);
6804 else if (std::fabs(z - length) <
6807 cell->
face(f)->set_boundary_id(3);
6809 else if (std::fabs(radius - face_inner_radius) >
6810 mid_radial_distance)
6812 cell->
face(f)->set_boundary_id(1);
6814 else if (std::fabs(radius - face_inner_radius) <
6815 mid_radial_distance)
6817 cell->
face(f)->set_boundary_id(0);
6826 template <
int dim,
int spacedim>
6831 const double duplicated_vertex_tolerance,
6832 const bool copy_manifold_ids,
6833 const bool copy_boundary_ids)
6835 std::vector<Point<spacedim>> vertices;
6836 std::vector<CellData<dim>> cells;
6839 unsigned int n_accumulated_vertices = 0;
6840 for (
const auto triangulation : triangulations)
6843 ExcMessage(
"The input triangulations must be non-empty "
6844 "and must not be refined."));
6846 auto [tria_vertices, tria_cells, tria_subcell_data] =
6856 vertices.insert(vertices.end(),
6857 tria_vertices.begin(),
6858 tria_vertices.end());
6861 for (
unsigned int &vertex_n : cell_data.vertices)
6862 vertex_n += n_accumulated_vertices;
6863 cells.push_back(cell_data);
6867 if (copy_manifold_ids)
6869 for (
CellData<1> &line_data : tria_subcell_data.boundary_lines)
6873 for (
unsigned int &vertex_n : line_data.
vertices)
6874 vertex_n += n_accumulated_vertices;
6880 for (
CellData<2> &quad_data : tria_subcell_data.boundary_quads)
6884 for (
unsigned int &vertex_n : quad_data.
vertices)
6885 vertex_n += n_accumulated_vertices;
6892 n_accumulated_vertices += triangulation->
n_vertices();
6896 std::vector<unsigned int> considered_vertices;
6900 considered_vertices,
6901 duplicated_vertex_tolerance);
6905 if (std::all_of(cells.begin(), cells.end(), [](
const auto &cell) {
6906 return cell.vertices.size() ==
6907 ReferenceCells::get_hypercube<dim>().n_vertices();
6913 if (!copy_manifold_ids)
6916 if (copy_boundary_ids)
6918 auto result_cell = result.
begin();
6919 for (
const auto &tria : triangulations)
6924 if (result_cell->face(f)->at_boundary())
6925 result_cell->face(f)->set_boundary_id(
6926 cell->
face(f)->boundary_id());
6932 Assert(duplicated_vertex_tolerance > 0.0 ||
6933 n_accumulated_vertices == result.
n_vertices(),
6939 template <
int dim,
int spacedim>
6944 const double duplicated_vertex_tolerance,
6945 const bool copy_manifold_ids,
6946 const bool copy_boundary_ids)
6949 if (triangulation_1.
n_cells() == 0)
6951 if (&result != &triangulation_2)
6954 else if (triangulation_2.
n_cells() == 0)
6956 if (&result != &triangulation_1)
6962 duplicated_vertex_tolerance,
6992 template <
int structdim>
6996 static_assert(structdim == 1 || structdim == 2,
6997 "This function is only implemented for lines and "
7005 std::sort(std::begin(cell_data.vertices),
7006 std::end(cell_data.vertices));
7007 else if (structdim == 2)
7010 std::array<unsigned int, 4> renumbering{};
7011 std::copy(std::begin(cell_data.vertices),
7012 std::end(cell_data.vertices),
7013 renumbering.begin());
7024 std::swap(renumbering[2], renumbering[3]);
7025 std::rotate(renumbering.begin(),
7026 std::min_element(renumbering.begin(),
7030 std::swap(renumbering[2], renumbering[3]);
7038 if (renumbering[1] > renumbering[2])
7039 std::swap(renumbering[1], renumbering[2]);
7040 std::copy(renumbering.begin(),
7042 std::begin(cell_data.vertices));
7049 return std::lexicographical_compare(std::begin(a.
vertices),
7051 std::begin(
b.vertices),
7052 std::end(
b.vertices));
7054 std::sort(subcell_data.begin(), subcell_data.end(), compare);
7059 auto left = subcell_data.begin();
7060 while (left != subcell_data.end())
7063 std::upper_bound(left, subcell_data.end(), *left, compare);
7066 if (left + 1 != right)
7067 for (
auto it = left; it != right; ++it)
7070 Assert(it->manifold_id == left->manifold_id,
7072 "In the process of grid generation a single "
7073 "line or quadrilateral has been assigned two "
7074 "different manifold ids. This can happen when "
7075 "a Triangulation is copied, e.g., via "
7076 "GridGenerator::replicate_triangulation() and "
7077 "not all external boundary faces have the same "
7078 "manifold id. Double check that all faces "
7079 "which you expect to be merged together have "
7080 "the same manifold id."));
7085 subcell_data.erase(std::unique(subcell_data.begin(), subcell_data.end()),
7086 subcell_data.end());
7092 template <
int dim,
int spacedim>
7095 const std::vector<unsigned int> &extents,
7101 for (
const auto &extent : extents)
7104 "The Triangulation must be copied at least one time in "
7105 "each coordinate dimension."));
7108 const auto &
min = bbox.get_boundary_points().first;
7109 const auto &
max = bbox.get_boundary_points().second;
7111 std::array<Tensor<1, spacedim>, dim> offsets;
7112 for (
unsigned int d = 0;
d < dim; ++
d)
7113 offsets[d][d] = max[d] - min[d];
7117 for (
unsigned int d = 0;
d < dim; ++
d)
7119 auto [input_vertices, input_cell_data, input_subcell_data] =
7122 std::vector<Point<spacedim>> output_vertices = input_vertices;
7123 std::vector<CellData<dim>> output_cell_data = input_cell_data;
7124 SubCellData output_subcell_data = input_subcell_data;
7126 for (
unsigned int k = 1; k < extents[
d]; ++k)
7128 const std::size_t vertex_offset = k * input_vertices.size();
7131 output_vertices.push_back(point +
double(k) * offsets[d]);
7135 output_cell_data.push_back(cell_data);
7136 for (
unsigned int &vertex : output_cell_data.back().vertices)
7137 vertex += vertex_offset;
7141 input_subcell_data.boundary_lines)
7144 for (
unsigned int &vertex :
7146 vertex += vertex_offset;
7149 input_subcell_data.boundary_quads)
7152 for (
unsigned int &vertex :
7154 vertex += vertex_offset;
7159 std::vector<unsigned int> boundary_vertices;
7163 output_subcell_data,
7184 tria_to_replicate.
clear();
7187 output_subcell_data);
7195 template <
int dim,
int spacedim>
7203 ExcMessage(
"The two input triangulations are not derived from "
7204 "the same coarse mesh as required."));
7207 &triangulation_1) ==
nullptr) &&
7210 &triangulation_2) ==
nullptr),
7211 ExcMessage(
"The source triangulations for this function must both "
7212 "be available entirely locally, and not be distributed "
7213 "triangulations."));
7230 for (
unsigned int iteration = 0; iteration < triangulation_2.
n_levels();
7236 bool any_cell_flagged =
false;
7238 if (intergrid_map[result_cell]->has_children())
7240 any_cell_flagged =
true;
7241 result_cell->set_refine_flag();
7244 if (any_cell_flagged ==
false)
7253 template <
int dim,
int spacedim>
7263 std::vector<Point<spacedim>> vertices = input_triangulation.
get_vertices();
7267 std::vector<CellData<dim>> cells;
7269 if (cells_to_remove.find(cell) == cells_to_remove.end())
7271 Assert(
static_cast<unsigned int>(cell->
level()) ==
7272 input_triangulation.
n_levels() - 1,
7274 "Your input triangulation appears to have "
7275 "adaptively refined cells. This is not allowed. You can "
7276 "only call this function on a triangulation in which "
7277 "all cells are on the same refinement level."));
7283 cells.push_back(this_cell);
7289 std::vector<unsigned int> considered_vertices;
7293 considered_vertices);
7305 const unsigned int n_slices,
7306 const double height,
7308 const bool copy_manifold_ids,
7309 const std::vector<types::manifold_id> &manifold_priorities)
7313 "The input triangulation must be a coarse mesh, i.e., it must "
7314 "not have been refined."));
7316 ExcMessage(
"The output triangulation object needs to be empty."));
7318 ExcMessage(
"The given height for extrusion must be positive."));
7321 "The number of slices for extrusion must be at least 2."));
7323 const double delta_h = height / (n_slices - 1);
7324 std::vector<double> slices_z_values;
7325 slices_z_values.reserve(n_slices);
7326 for (
unsigned int i = 0; i < n_slices; ++i)
7327 slices_z_values.push_back(i * delta_h);
7329 input, slices_z_values, result, copy_manifold_ids, manifold_priorities);
7337 const unsigned int n_slices,
7338 const double height,
7340 const bool copy_manifold_ids,
7341 const std::vector<types::manifold_id> &manifold_priorities)
7347 (void)copy_manifold_ids;
7348 (void)manifold_priorities;
7352 "GridTools::extrude_triangulation() is only available "
7353 "for Triangulation<3, 3> as output triangulation."));
7361 const std::vector<double> &slice_coordinates,
7363 const bool copy_manifold_ids,
7364 const std::vector<types::manifold_id> &manifold_priorities)
7368 "The input triangulation must be a coarse mesh, i.e., it must "
7369 "not have been refined."));
7371 ExcMessage(
"The output triangulation object needs to be empty."));
7372 Assert(slice_coordinates.size() >= 2,
7374 "The number of slices for extrusion must be at least 2."));
7375 Assert(std::is_sorted(slice_coordinates.begin(), slice_coordinates.end()),
7376 ExcMessage(
"Slice z-coordinates should be in ascending order"));
7379 "This function is only implemented for quadrilateral meshes."));
7381 const auto priorities = [&]() -> std::vector<types::manifold_id> {
7385 if (0 < manifold_priorities.size())
7390 std::vector<types::manifold_id> sorted_manifold_priorities =
7391 manifold_priorities;
7392 std::sort(sorted_manifold_priorities.begin(),
7393 sorted_manifold_priorities.end());
7394 Assert(std::unique(sorted_manifold_priorities.begin(),
7395 sorted_manifold_priorities.end()) ==
7396 sorted_manifold_priorities.end(),
7398 "The given vector of manifold ids may not contain any "
7399 "duplicated entries."));
7400 std::vector<types::manifold_id> sorted_manifold_ids =
7402 std::sort(sorted_manifold_ids.begin(), sorted_manifold_ids.end());
7403 if (sorted_manifold_priorities != sorted_manifold_ids)
7405 std::ostringstream message;
7406 message <<
"The given triangulation has manifold ids {";
7408 sorted_manifold_ids)
7409 if (manifold_id != sorted_manifold_ids.back())
7411 message << sorted_manifold_ids.back() <<
"}, but \n"
7412 <<
" the given vector of manifold ids is {";
7414 manifold_priorities)
7415 if (manifold_id != manifold_priorities.back())
7418 << manifold_priorities.back() <<
"}.\n"
7419 <<
" These vectors should contain the same elements.\n";
7420 const std::string m = message.str();
7424 return manifold_priorities;
7428 std::vector<types::manifold_id> default_priorities =
7430 const auto first_tfi_it = std::partition(
7431 default_priorities.begin(),
7432 default_priorities.end(),
7434 return dynamic_cast<const TransfiniteInterpolationManifold<2, 2> *>(
7435 &input.get_manifold(id)) == nullptr;
7437 std::sort(default_priorities.begin(), first_tfi_it);
7438 std::sort(first_tfi_it, default_priorities.end());
7440 return default_priorities;
7443 const std::size_t n_slices = slice_coordinates.size();
7444 std::vector<Point<3>> points(n_slices * input.
n_vertices());
7445 std::vector<CellData<3>> cells;
7450 for (std::size_t slice_n = 0; slice_n < n_slices; ++slice_n)
7452 for (std::size_t vertex_n = 0; vertex_n < input.
n_vertices();
7456 points[slice_n * input.
n_vertices() + vertex_n] =
7457 Point<3>(vertex[0], vertex[1], slice_coordinates[slice_n]);
7465 for (std::size_t slice_n = 0; slice_n < n_slices - 1; ++slice_n)
7468 for (
const unsigned int vertex_n :
7480 if (copy_manifold_ids)
7482 cells.push_back(this_cell);
7497 if (face->at_boundary())
7499 if (copy_manifold_ids)
7501 for (std::size_t slice_n = 0; slice_n < n_slices - 1; ++slice_n)
7504 face->vertex_index(0) + slice_n * input.
n_vertices();
7506 face->vertex_index(1) + slice_n * input.
n_vertices();
7508 face->vertex_index(0) + (slice_n + 1) * input.
n_vertices();
7510 face->vertex_index(1) + (slice_n + 1) * input.
n_vertices();
7511 quads.push_back(quad);
7517 if (copy_manifold_ids)
7523 for (std::size_t slice_n = 1; slice_n < n_slices - 1; ++slice_n)
7533 quads.push_back(quad);
7544 "The input triangulation to this function is using boundary "
7545 "indicators in a range that do not allow using "
7546 "max_boundary_id+1 and max_boundary_id+2 as boundary "
7547 "indicators for the bottom and top faces of the "
7548 "extruded triangulation."));
7559 if (copy_manifold_ids)
7561 quads.push_back(quad);
7564 for (
unsigned int &vertex : quad.
vertices)
7565 vertex += (n_slices - 1) * input.
n_vertices();
7566 if (copy_manifold_ids)
7568 quads.push_back(quad);
7581 for (
auto manifold_id_it = priorities.rbegin();
7582 manifold_id_it != priorities.rend();
7585 if (face->manifold_id() == *manifold_id_it)
7586 for (
unsigned int line_n = 0;
7587 line_n < GeometryInfo<3>::lines_per_face;
7589 face->line(line_n)->set_manifold_id(*manifold_id_it);
7597 const std::vector<double> &slice_coordinates,
7599 const bool copy_manifold_ids,
7600 const std::vector<types::manifold_id> &manifold_priorities)
7603 (void)slice_coordinates;
7605 (void)copy_manifold_ids;
7606 (void)manifold_priorities;
7610 "GridTools::extrude_triangulation() is only available "
7611 "for Triangulation<3, 3> as output triangulation."));
7630 template <
int spacedim>
7633 const double inner_radius,
7634 const double outer_radius,
7637 const bool colorize)
7641 Assert(inner_radius < outer_radius,
7642 ExcMessage(
"outer_radius has to be bigger than inner_radius."));
7649 hyper_shell(triangulation, center, inner_radius, outer_radius, 8);
7651 std::vector<bool> treated_vertices(triangulation.
n_vertices(),
false);
7655 if (cell->
face(f)->at_boundary())
7656 for (
const unsigned int v : cell->
face(f)->vertex_indices())
7658 (std::fabs(cell->
face(f)->vertex(v).norm() - outer_radius) <
7659 1e-12 * outer_radius)
7663 (std::fabs(std::fabs(cell->
face(f)->vertex(v)[0]) -
7664 std::fabs(cell->
face(f)->vertex(v)[1])) <
7665 1e-12 * outer_radius))
7668 const double eps = 1
e-3 * outer_radius;
7672 if (cell->
face(f)->at_boundary())
7674 const double dx = cell->
face(f)->center()[0] - center[0];
7675 const double dy = cell->
face(f)->center()[1] - center[1];
7678 if (
std::abs(dx + outer_radius) < eps)
7679 cell->
face(f)->set_boundary_id(0);
7680 else if (
std::abs(dx - outer_radius) < eps)
7681 cell->
face(f)->set_boundary_id(1);
7682 else if (
std::abs(dy + outer_radius) < eps)
7683 cell->
face(f)->set_boundary_id(2);
7684 else if (
std::abs(dy - outer_radius) < eps)
7685 cell->
face(f)->set_boundary_id(3);
7688 cell->
face(f)->set_boundary_id(4);
7689 cell->
face(f)->set_manifold_id(0);
7694 const double d = (cell->
face(f)->center() - center).norm();
7695 if (d - inner_radius < 0)
7697 cell->
face(f)->set_boundary_id(1);
7698 cell->
face(f)->set_manifold_id(0);
7701 cell->
face(f)->set_boundary_id(0);
7713 const double inner_radius,
7714 const double outer_radius,
7716 const unsigned int width_repetition,
7717 const bool colorize)
7719 hyper_cube_with_cylindrical_hole_2D(triangulation,
7732 const double inner_radius,
7733 const double outer_radius,
7735 const unsigned int width_repetition,
7736 const bool colorize)
7738 hyper_cube_with_cylindrical_hole_2D(triangulation,
7752 const double inner_radius,
7753 const double outer_radius,
7754 const unsigned int n_shells,
7755 const double skewness,
7756 const unsigned int n_cells,
7757 const bool colorize)
7760 Assert(inner_radius < outer_radius,
7761 ExcMessage(
"outer_radius has to be bigger than inner_radius."));
7765 std::vector<double> radii;
7766 radii.push_back(inner_radius);
7767 for (
unsigned int shell_n = 1; shell_n < n_shells; ++shell_n)
7768 if (skewness == 0.0)
7770 radii.push_back(inner_radius +
7771 (outer_radius - inner_radius) *
7772 (1.0 - (1.0 -
double(shell_n) / n_shells)));
7776 (outer_radius - inner_radius) *
7777 (1.0 -
std::tanh(skewness * (1.0 -
double(shell_n) / n_shells)) /
7779 radii.push_back(outer_radius);
7781 double grid_vertex_tolerance = 0.0;
7782 for (
unsigned int shell_n = 0; shell_n < radii.size() - 1; ++shell_n)
7789 n_cells == 0 ? (dim == 2 ? 8 : 12) :
7794 if (grid_vertex_tolerance == 0.0)
7795 grid_vertex_tolerance =
7796 0.5 * internal::minimal_vertex_distance(current_shell);
7799 triangulation.
clear();
7803 grid_vertex_tolerance);
7815 constexpr double radial_vertex_tolerance =
7816 100.0 * std::numeric_limits<double>::epsilon();
7817 auto assert_vertex_distance_within_tolerance =
7818 [center, radial_vertex_tolerance](
7820 const double radius) {
7822 (void)radial_vertex_tolerance;
7823 for (
unsigned int vertex_n = 0;
7824 vertex_n < GeometryInfo<dim>::vertices_per_face;
7827 Assert(
std::abs((face->vertex(vertex_n) - center).norm() - radius) <
7828 (center.
norm() + radius) * radial_vertex_tolerance,
7836 auto face = cell->
face(face_n);
7837 if (face->at_boundary())
7839 if (((face->vertex(0) - center).norm() - inner_radius) <
7840 (center.
norm() + inner_radius) * radial_vertex_tolerance)
7843 assert_vertex_distance_within_tolerance(face, inner_radius);
7844 face->set_all_boundary_ids(0);
7849 assert_vertex_distance_within_tolerance(face, outer_radius);
7850 face->set_all_boundary_ids(1);
7861 const double inner_radius,
7862 const double outer_radius,
7864 const unsigned int Nz,
7865 const bool colorize)
7869 Assert(inner_radius < outer_radius,
7870 ExcMessage(
"outer_radius has to be bigger than inner_radius."));
7876 cylinder_shell(triangulation, L, inner_radius, outer_radius, 8, Nz,
false);
7884 std::vector<bool> treated_vertices(triangulation.
n_vertices(),
false);
7888 if (cell->
face(f)->at_boundary())
7890 for (
const unsigned int v : cell->
face(f)->vertex_indices())
7892 const unsigned int vv = cell->
face(f)->vertex_index(v);
7893 if (treated_vertices[vv] ==
false)
7895 treated_vertices[vv] =
true;
7905 cell->
face(f)->vertex(v);
7906 if ((std::fabs(std::fabs(vertex_location[0]) -
7907 std::fabs(vertex_location[1])) <
7908 1e-12 * outer_radius) &&
7909 (std::fabs(vertex_location[0] * vertex_location[0] +
7910 vertex_location[1] * vertex_location[1] -
7911 outer_radius * outer_radius) <
7912 1e-12 * outer_radius))
7913 cell->
face(f)->vertex(v) =
7916 vertex_location[2]);
7921 double eps = 1
e-3 * outer_radius;
7925 if (cell->
face(f)->at_boundary())
7927 const double dx = cell->
face(f)->center()[0];
7928 const double dy = cell->
face(f)->center()[1];
7929 const double dz = cell->
face(f)->center()[2];
7933 if (
std::abs(dx + outer_radius) < eps)
7934 cell->
face(f)->set_boundary_id(0);
7936 else if (
std::abs(dx - outer_radius) < eps)
7937 cell->
face(f)->set_boundary_id(1);
7939 else if (
std::abs(dy + outer_radius) < eps)
7940 cell->
face(f)->set_boundary_id(2);
7942 else if (
std::abs(dy - outer_radius) < eps)
7943 cell->
face(f)->set_boundary_id(3);
7946 cell->
face(f)->set_boundary_id(4);
7949 cell->
face(f)->set_boundary_id(5);
7953 cell->
face(f)->set_all_boundary_ids(6);
7954 cell->
face(f)->set_all_manifold_ids(0);
7961 const double d = c.
norm();
7962 if (d - inner_radius < 0)
7964 cell->
face(f)->set_all_boundary_ids(1);
7965 cell->
face(f)->set_all_manifold_ids(0);
7968 cell->
face(f)->set_boundary_id(0);
7977 template <
int dim,
int spacedim1,
int spacedim2>
7984 &in_tria) ==
nullptr),
7986 "This function cannot be used on "
7987 "parallel::distributed::Triangulation objects as inputs."));
7989 ExcMessage(
"This function does not work for meshes that have "
7993 const unsigned int spacedim =
std::min(spacedim1, spacedim2);
7994 const std::vector<Point<spacedim1>> &in_vertices = in_tria.
get_vertices();
7998 std::vector<Point<spacedim2>> v(in_vertices.size());
7999 for (
unsigned int i = 0; i < in_vertices.size(); ++i)
8000 for (
unsigned int d = 0;
d < spacedim; ++
d)
8001 v[i][d] = in_vertices[i][d];
8008 cells[id].vertices.resize(cell->
n_vertices());
8026 std::vector<bool> user_flags_line;
8029 .clear_user_flags_line();
8035 if (face->at_boundary())
8039 boundary_line.
vertices.resize(face->n_vertices());
8040 for (
const auto i : face->vertex_indices())
8041 boundary_line.
vertices[i] = face->vertex_index(i);
8046 std::move(boundary_line));
8059 if ((face->user_flag_set() ==
false) &&
8064 boundary_line.
vertices.resize(face->n_vertices());
8065 for (
const auto i : face->vertex_indices())
8066 boundary_line.
vertices[i] = face->vertex_index(i);
8072 std::move(boundary_line));
8074 face->set_user_flag();
8080 .load_user_flags_line(user_flags_line);
8087 std::vector<bool> user_flags_line;
8090 .clear_user_flags_line();
8092 std::vector<bool> user_flags_quad;
8095 .clear_user_flags_quad();
8101 if (face->at_boundary())
8105 boundary_face.
vertices.resize(face->n_vertices());
8106 for (
const auto i : face->vertex_indices())
8107 boundary_face.
vertices[i] = face->vertex_index(i);
8112 std::move(boundary_face));
8119 for (
unsigned int e = 0;
e < face->n_lines(); ++
e)
8120 if (face->line(e)->user_flag_set() ==
false)
8123 spacedim1>::line_iterator
8124 edge = face->line(e);
8127 boundary_edge.
vertices.resize(edge->n_vertices());
8128 for (
const auto i : edge->vertex_indices())
8129 boundary_edge.
vertices[i] = edge->vertex_index(i);
8134 std::move(boundary_edge));
8136 edge->set_user_flag();
8154 if (face->user_flag_set() ==
false)
8160 boundary_face.
vertices.resize(face->n_vertices());
8161 for (
const auto i : face->vertex_indices())
8162 boundary_face.
vertices[i] = face->vertex_index(i);
8168 std::move(boundary_face));
8170 face->set_user_flag();
8179 for (
unsigned int e = 0;
e < face->n_lines(); ++
e)
8180 if (face->line(e)->at_boundary() ==
false)
8181 if (face->line(e)->user_flag_set() ==
false)
8184 line_iterator edge = face->line(e);
8188 for (
const auto i : edge->vertex_indices())
8190 edge->vertex_index(i);
8196 std::move(boundary_edge));
8198 edge->set_user_flag();
8205 .load_user_flags_line(user_flags_line);
8207 .load_user_flags_quad(user_flags_quad);
8224 template <
int dim,
int spacedim>
8228 const unsigned int n_divisions)
8237 n_divisions == 2 || n_divisions == 8,
8239 "Quadrilaterals must be split into either 2 or 8 triangles."));
8241 AssertThrow(n_divisions == 6 || n_divisions == 24,
8243 "Hexahedra must be split into either 6 or 24 tetrahedra."));
8247 "GridGenerator::convert_hypercube_to_simplex_mesh() expects "
8248 "a Triangulation that consists only of quads/hexes."));
8266 {{{0, 1, 2}}, {{3, 2, 1}}}};
8276 const auto vertex_ids_for_cells_2d =
8289 {{{0, 1, 12, 10}}, {{2, 3, 11, 12}}, {{7, 6, 11, 13}},
8290 {{5, 4, 13, 10}}, {{0, 2, 8, 12}}, {{4, 6, 13, 8}},
8291 {{5, 13, 7, 9}}, {{1, 9, 3, 12}}, {{0, 8, 4, 10}},
8292 {{1, 5, 9, 10}}, {{3, 7, 11, 9}}, {{2, 6, 8, 11}},
8293 {{12, 13, 10, 9}}, {{12, 13, 9, 11}}, {{12, 13, 11, 8}},
8294 {{12, 13, 8, 10}}, {{13, 8, 10, 4}}, {{13, 10, 9, 5}},
8295 {{13, 9, 11, 7}}, {{13, 11, 8, 6}}, {{10, 12, 9, 1}},
8296 {{9, 12, 11, 3}}, {{11, 12, 8, 2}}, {{8, 12, 10, 0}}}};
8298 const auto vertex_ids_for_cells_3d =
8305 array<std::pair<unsigned int, std::array<unsigned int, 2>>, 4>
8306 vertex_ids_for_boundary_faces_2d_2 = {
8307 {{0, {{0, 2}}}, {1, {{1, 3}}}, {2, {{0, 1}}}, {3, {{2, 3}}}}};
8312 array<std::pair<unsigned int, std::array<unsigned int, 2>>, 8>
8313 vertex_ids_for_boundary_faces_2d_8 = {{{0, {{0, 4}}},
8321 const auto vertex_ids_for_boundary_faces_2d =
8322 n_divisions == 2 ?
make_array_view(vertex_ids_for_boundary_faces_2d_2) :
8328 array<std::pair<unsigned int, std::array<unsigned int, 3>>, 12>
8329 vertex_ids_for_boundary_faces_3d_6 = {{{0, {{2, 6, 0}}},
8345 array<std::pair<unsigned int, std::array<unsigned int, 3>>, 24>
8346 vertex_ids_for_boundary_faces_3d_24 = {
8347 {{0, {{0, 4, 8}}}, {0, {{4, 8, 6}}}, {0, {{8, 6, 2}}},
8348 {0, {{0, 2, 8}}}, {1, {{1, 3, 9}}}, {1, {{3, 9, 7}}},
8349 {1, {{9, 7, 5}}}, {1, {{1, 9, 5}}}, {2, {{0, 1, 10}}},
8350 {2, {{1, 10, 5}}}, {2, {{10, 5, 4}}}, {2, {{0, 10, 4}}},
8351 {3, {{2, 3, 11}}}, {3, {{3, 11, 7}}}, {3, {{11, 7, 6}}},
8352 {3, {{2, 11, 6}}}, {4, {{0, 1, 12}}}, {4, {{1, 12, 3}}},
8353 {4, {{12, 3, 2}}}, {4, {{0, 12, 2}}}, {5, {{4, 5, 13}}},
8354 {5, {{5, 13, 7}}}, {5, {{13, 7, 6}}}, {5, {{4, 13, 6}}}}};
8355 const auto vertex_ids_for_boundary_faces_3d =
8356 n_divisions == 6 ?
make_array_view(vertex_ids_for_boundary_faces_3d_6) :
8374 const auto vertex_ids_for_inner_faces_2d =
8393 {{0, 12, 10}}, {{12, 1, 10}}, {{12, 1, 9}}, {{12, 3, 9}},
8394 {{12, 2, 11}}, {{12, 3, 11}}, {{12, 0, 8}}, {{12, 2, 8}},
8395 {{9, 13, 5}}, {{13, 7, 9}}, {{11, 7, 13}}, {{11, 6, 13}},
8396 {{4, 8, 13}}, {{6, 8, 13}}, {{4, 13, 10}}, {{13, 5, 10}},
8397 {{10, 9, 5}}, {{10, 9, 1}}, {{11, 9, 7}}, {{11, 9, 3}},
8398 {{8, 11, 2}}, {{8, 11, 6}}, {{8, 10, 0}}, {{8, 10, 4}},
8399 {{12, 3, 9}}, {{12, 9, 11}}, {{12, 3, 11}}, {{3, 9, 11}},
8400 {{2, 12, 8}}, {{2, 12, 11}}, {{2, 11, 8}}, {{8, 12, 11}},
8401 {{0, 12, 10}}, {{0, 12, 8}}, {{0, 8, 10}}, {{8, 10, 12}},
8402 {{12, 1, 10}}, {{12, 1, 9}}, {{1, 10, 9}}, {{10, 9, 12}},
8403 {{10, 8, 4}}, {{10, 8, 13}}, {{4, 13, 8}}, {{4, 13, 10}},
8404 {{10, 9, 13}}, {{10, 9, 5}}, {{13, 5, 10}}, {{13, 5, 9}},
8405 {{13, 7, 9}}, {{13, 7, 11}}, {{9, 11, 13}}, {{9, 11, 7}},
8406 {{8, 11, 13}}, {{8, 11, 6}}, {{6, 13, 8}}, {{6, 13, 11}},
8407 {{12, 13, 10}}, {{12, 13, 8}}, {{8, 10, 13}}, {{8, 10, 12}},
8408 {{12, 13, 10}}, {{12, 13, 9}}, {{10, 9, 13}}, {{10, 9, 12}},
8409 {{12, 13, 9}}, {{12, 13, 11}}, {{9, 11, 13}}, {{9, 11, 12}},
8410 {{12, 13, 11}}, {{12, 13, 8}}, {{8, 11, 13}}, {{8, 11, 12}},
8412 const auto vertex_ids_for_inner_faces_3d =
8423 {{{{12, 10}}, {{12, 9}}, {{12, 11}}, {{12, 8}}, {{9, 13}}, {{11, 13}},
8424 {{8, 13}}, {{10, 13}}, {{10, 9}}, {{9, 11}}, {{11, 8}}, {{8, 10}},
8425 {{12, 9}}, {{12, 11}}, {{11, 9}}, {{12, 8}}, {{12, 11}}, {{11, 8}},
8426 {{12, 8}}, {{12, 10}}, {{10, 8}}, {{12, 10}}, {{12, 9}}, {{9, 10}},
8427 {{13, 10}}, {{13, 8}}, {{8, 10}}, {{13, 10}}, {{13, 9}}, {{9, 10}},
8428 {{13, 11}}, {{13, 9}}, {{11, 9}}, {{13, 11}}, {{13, 8}}, {{11, 8}},
8429 {{12, 13}}, {{8, 10}}, {{8, 13}}, {{10, 13}}, {{8, 12}}, {{10, 12}},
8430 {{12, 13}}, {{10, 9}}, {{10, 13}}, {{9, 13}}, {{10, 12}}, {{9, 12}},
8431 {{12, 13}}, {{9, 11}}, {{9, 13}}, {{11, 13}}, {{9, 12}}, {{11, 12}},
8432 {{12, 13}}, {{11, 8}}, {{11, 13}}, {{8, 13}}, {{11, 12}}, {{8, 12}}}};
8433 const auto vertex_ids_for_inner_edges_3d =
8445 array<std::pair<unsigned int, std::array<unsigned int, 2>>, 6>
8446 vertex_ids_for_new_boundary_edges_3d_6 = {{{0, {{0, 6}}},
8461 array<std::pair<unsigned int, std::array<unsigned int, 2>>, 24>
8462 vertex_ids_for_new_boundary_edges_3d_24 = {
8463 {{0, {{4, 8}}}, {0, {{6, 8}}}, {0, {{0, 8}}}, {0, {{2, 8}}},
8464 {1, {{5, 9}}}, {1, {{7, 9}}}, {1, {{1, 9}}}, {1, {{3, 9}}},
8465 {2, {{4, 10}}}, {2, {{5, 10}}}, {2, {{0, 10}}}, {2, {{1, 10}}},
8466 {3, {{6, 11}}}, {3, {{7, 11}}}, {3, {{2, 11}}}, {3, {{3, 11}}},
8467 {4, {{2, 12}}}, {4, {{3, 12}}}, {4, {{0, 12}}}, {4, {{1, 12}}},
8468 {5, {{6, 13}}}, {5, {{7, 13}}}, {5, {{4, 13}}}, {5, {{5, 13}}}}};
8469 const auto vertex_ids_for_new_boundary_edges_3d =
8474 std::vector<Point<spacedim>> vertices;
8475 std::vector<CellData<dim>> cells;
8480 std::vector<unsigned int> old_to_new_vertex_indices(
8482 std::vector<unsigned int> face_to_new_vertex_indices(
8496 std::array<unsigned int, dim == 2 ? 9 : 14> local_vertex_indices;
8504 if (old_to_new_vertex_indices[v_global] ==
8507 old_to_new_vertex_indices[v_global] = vertices.size();
8508 vertices.push_back(cell->
vertex(v));
8512 local_vertex_indices[v] = old_to_new_vertex_indices[v_global];
8516 if constexpr (dim > 1)
8521 if (face_to_new_vertex_indices[f_global] ==
8524 face_to_new_vertex_indices[f_global] = vertices.size();
8526 cell->
face(f)->center(
true));
8530 local_vertex_indices.size());
8531 local_vertex_indices[cell->
n_vertices() + f] =
8532 face_to_new_vertex_indices[f_global];
8539 local_vertex_indices.size());
8542 vertices.push_back(cell->
center(
true));
8546 const auto add_cell = [&](
const unsigned int struct_dim,
8547 const auto &index_vertices,
8548 const unsigned int material_or_boundary_id,
8552 if (struct_dim < dim &&
8557 if (struct_dim == dim)
8562 cell_data.material_id =
8563 material_or_boundary_id;
8565 for (
unsigned int i = 0; i < index_vertices.size(); ++i)
8568 local_vertex_indices.size());
8569 cell_data.vertices[i] =
8570 local_vertex_indices[index_vertices[i]];
8572 cells.push_back(cell_data);
8574 else if (dim == 2 && struct_dim == 1)
8578 boundary_line.
boundary_id = material_or_boundary_id;
8580 for (
unsigned int i = 0; i < index_vertices.size(); ++i)
8583 local_vertex_indices.size());
8585 local_vertex_indices[index_vertices[i]];
8589 else if (dim == 3 && struct_dim == 2)
8593 boundary_quad.
material_id = material_or_boundary_id;
8595 for (
unsigned int i = 0; i < index_vertices.size(); ++i)
8598 local_vertex_indices.size());
8600 local_vertex_indices[index_vertices[i]];
8604 else if (dim == 3 && struct_dim == 1)
8608 boundary_line.
boundary_id = material_or_boundary_id;
8610 for (
unsigned int i = 0; i < index_vertices.size(); ++i)
8613 local_vertex_indices.size());
8615 local_vertex_indices[index_vertices[i]];
8625 const auto material_id_cell = cell->
material_id();
8631 const auto manifold_id_cell = cell->
manifold_id();
8633 for (
const auto &cell_vertices : vertex_ids_for_cells_2d)
8634 add_cell(dim, cell_vertices, material_id_cell, manifold_id_cell);
8637 for (
const auto &face_vertices : vertex_ids_for_inner_faces_2d)
8649 const auto manifold_id_cell = cell->
manifold_id();
8651 for (
const auto &cell_vertices : vertex_ids_for_cells_3d)
8652 add_cell(dim, cell_vertices, material_id_cell, manifold_id_cell);
8656 for (
const auto &face_vertices : vertex_ids_for_inner_faces_3d)
8664 for (
const auto &edge_vertices : vertex_ids_for_inner_edges_3d)
8676 for (
const auto &[quad_face_no, tri_face_vertices] :
8677 vertex_ids_for_boundary_faces_2d)
8679 const auto face = cell->
face(quad_face_no);
8682 face->boundary_id(),
8683 face->manifold_id());
8688 for (
const auto &[hex_face_no, tet_face_vertices] :
8689 vertex_ids_for_boundary_faces_3d)
8691 const auto face = cell->
face(hex_face_no);
8694 face->boundary_id(),
8695 face->manifold_id());
8698 for (
const auto &[hex_face_no, tet_edge_vertices] :
8699 vertex_ids_for_new_boundary_edges_3d)
8701 const auto face = cell->
face(hex_face_no);
8704 face->boundary_id(),
8705 face->manifold_id());
8717 auto edge = cell->
line(e);
8723 old_to_new_vertex_indices[edge->vertex_index(0)];
8725 old_to_new_vertex_indices[edge->vertex_index(1)];
8744 template <
int dim,
int spacedim>
8760 {{{0, 1, 3}}, {{1, 2, 3}}, {{2, 0, 3}}}};
8765 vertex_ids_for_boundary_faces_2d = {
8766 {{{{{0, 1}}}}, {{{{1, 2}}}}, {{{{2, 0}}}}}};
8770 {{{0, 1, 2, 4}}, {{1, 0, 3, 4}}, {{0, 2, 3, 4}}, {{2, 1, 3, 4}}}};
8775 vertex_ids_for_boundary_faces_3d = {
8776 {{{{{0, 1, 2}}}}, {{{{1, 0, 3}}}}, {{{{0, 2, 3}}}}, {{{{2, 1, 3}}}}}};
8782 vertex_ids_for_boundary_lines_3d = {{{{{{0, 1}}}},
8789 std::vector<Point<spacedim>> vertices;
8790 std::vector<CellData<dim>> cells;
8795 std::vector<unsigned int> old_to_new_vertex_indices(
8808 "Cell with invalid ReferenceCell encountered. GridGenerator::alfeld_split_of_simplex_mesh() "
8809 "only supports simplex meshes as input."));
8813 std::array<
unsigned int, (dim == 3) ? 5 : 4> local_vertex_indices;
8821 if (old_to_new_vertex_indices[v_global] ==
8824 old_to_new_vertex_indices[v_global] = vertices.size();
8825 vertices.push_back(cell->
vertex(v));
8829 local_vertex_indices[v] = old_to_new_vertex_indices[v_global];
8835 local_vertex_indices[local_vertex_indices.size() - 1] = vertices.size();
8836 vertices.push_back(barycenter /
static_cast<double>(dim + 1));
8839 const auto add_cell = [&](
const unsigned int struct_dim,
8840 const auto &index_vertices,
8841 const unsigned int material_or_boundary_id,
8845 if (struct_dim < dim &&
8850 if (struct_dim == dim)
8855 for (
unsigned int i = 0; i < index_vertices.size(); ++i)
8858 local_vertex_indices.size());
8859 cell_data.vertices[i] =
8860 local_vertex_indices[index_vertices[i]];
8862 cell_data.material_id =
8863 material_or_boundary_id;
8865 cells.push_back(cell_data);
8867 else if (dim == 2 && struct_dim == 1)
8871 boundary_line.
boundary_id = material_or_boundary_id;
8873 for (
unsigned int i = 0; i < index_vertices.size(); ++i)
8876 local_vertex_indices.size());
8878 local_vertex_indices[index_vertices[i]];
8882 else if (dim == 3 && struct_dim == 2)
8886 boundary_quad.
material_id = material_or_boundary_id;
8888 for (
unsigned int i = 0; i < index_vertices.size(); ++i)
8891 local_vertex_indices.size());
8893 local_vertex_indices[index_vertices[i]];
8897 else if (dim == 3 && struct_dim == 1)
8901 boundary_line.
boundary_id = material_or_boundary_id;
8903 for (
unsigned int i = 0; i < index_vertices.size(); ++i)
8906 local_vertex_indices.size());
8908 local_vertex_indices[index_vertices[i]];
8918 const auto material_id_cell = cell->
material_id();
8919 const auto manifold_id_cell = cell->
manifold_id();
8924 for (
const auto &cell_vertices : vertex_ids_for_cells_2d)
8925 add_cell(dim, cell_vertices, material_id_cell, manifold_id_cell);
8929 for (
const auto &cell_vertices : vertex_ids_for_cells_3d)
8930 add_cell(dim, cell_vertices, material_id_cell, manifold_id_cell);
8938 const auto bid = cell->
face(f)->boundary_id();
8939 const auto mid = cell->
face(f)->manifold_id();
8944 for (
const auto &face_vertices :
8945 vertex_ids_for_boundary_faces_2d[f])
8946 add_cell(1, face_vertices, bid, mid);
8950 for (
const auto &face_vertices :
8951 vertex_ids_for_boundary_faces_3d[f])
8952 add_cell(2, face_vertices, bid, mid);
8963 const auto bid = cell->
line(l)->boundary_id();
8964 const auto mid = cell->
line(l)->manifold_id();
8966 for (
const auto &line_vertices :
8967 vertex_ids_for_boundary_lines_3d[l])
8968 add_cell(1, line_vertices, bid, mid);
8983 template <
template <
int,
int>
class MeshType,
int dim,
int spacedim>
8987 std::map<
typename MeshType<dim - 1, spacedim>::cell_iterator,
8988 typename MeshType<dim, spacedim>::face_iterator>
8990 typename ExtractBoundaryMesh<MeshType, dim, spacedim>::return_type
8993 MeshType<dim - 1, spacedim> &surface_mesh,
8994 const std::set<types::boundary_id> &boundary_ids)
8998 &volume_mesh.get_triangulation()) ==
nullptr),
9007 const unsigned int boundary_dim = dim - 1;
9014 std::pair<typename MeshType<dim, spacedim>::face_iterator,
unsigned int>>
9015 temporary_mapping_level0;
9020 std::vector<bool> touched(volume_mesh.get_triangulation().n_vertices(),
9024 std::vector<CellData<boundary_dim>> cells;
9026 std::vector<Point<spacedim>> vertices;
9029 std::map<unsigned int, unsigned int> map_vert_index;
9042 for (
unsigned int i1 = 0; i1 < GeometryInfo<spacedim>::faces_per_cell; ++i1)
9046 swap_matrix[i1][i2] = i2;
9052 std::swap(swap_matrix[0][1], swap_matrix[0][2]);
9053 std::swap(swap_matrix[2][1], swap_matrix[2][2]);
9054 std::swap(swap_matrix[4][1], swap_matrix[4][2]);
9058 std::swap(swap_matrix[1][0], swap_matrix[1][1]);
9059 std::swap(swap_matrix[2][0], swap_matrix[2][1]);
9064 for (
typename MeshType<dim, spacedim>::cell_iterator cell =
9065 volume_mesh.begin(0);
9066 cell != volume_mesh.end(0);
9070 const typename MeshType<dim, spacedim>::face_iterator face =
9073 if (face->at_boundary() &&
9074 (boundary_ids.empty() ||
9075 (boundary_ids.find(face->boundary_id()) != boundary_ids.end())))
9079 for (
const unsigned int j :
9082 const unsigned int v_index = face->vertex_index(j);
9084 if (!touched[v_index])
9086 vertices.push_back(face->vertex(j));
9087 map_vert_index[v_index] = vertices.size() - 1;
9088 touched[v_index] =
true;
9091 c_data.
vertices[swap_matrix[i][j]] = map_vert_index[v_index];
9105 for (
unsigned int e = 0;
e < 4; ++
e)
9111 bool edge_found =
false;
9114 map_vert_index[face->line(e)->vertex_index(0)]) &&
9116 map_vert_index[face->line(e)->vertex_index(
9119 map_vert_index[face->line(e)->vertex_index(1)]) &&
9121 map_vert_index[face->line(e)->vertex_index(0)])))
9128 if (edge_found ==
true)
9135 map_vert_index[face->line(e)->vertex_index(0)];
9137 map_vert_index[face->line(e)->vertex_index(1)];
9144 cells.push_back(c_data);
9145 temporary_mapping_level0.push_back(std::make_pair(face, i));
9152 surface_mesh.get_triangulation())
9158 for (
const auto &cell : surface_mesh.active_cell_iterators())
9159 for (
unsigned int vertex = 0; vertex < 2; ++vertex)
9160 if (cell->
face(vertex)->at_boundary())
9161 cell->
face(vertex)->set_boundary_id(0);
9169 std::vector<std::pair<
9170 const typename MeshType<dim - 1, spacedim>::cell_iterator,
9171 std::pair<typename MeshType<dim, spacedim>::face_iterator,
unsigned int>>>
9172 temporary_map_boundary_cell_face;
9173 for (
const auto &cell : surface_mesh.active_cell_iterators())
9174 temporary_map_boundary_cell_face.push_back(
9175 std::make_pair(cell, temporary_mapping_level0.at(cell->
index())));
9187 unsigned int index_cells_deepest_level = 0;
9190 bool changed =
false;
9194 std::vector<unsigned int> cells_refined;
9197 for (
unsigned int cell_n = index_cells_deepest_level;
9198 cell_n < temporary_map_boundary_cell_face.size();
9203 if (temporary_map_boundary_cell_face[cell_n]
9204 .second.first->has_children())
9208 Assert(temporary_map_boundary_cell_face[cell_n]
9209 .second.first->refinement_case() ==
9212 temporary_map_boundary_cell_face[cell_n]
9213 .first->set_refine_flag();
9214 cells_refined.push_back(cell_n);
9225 surface_mesh.get_triangulation())
9229 index_cells_deepest_level = temporary_map_boundary_cell_face.size();
9230 for (
const auto &refined_cell_n : cells_refined)
9232 const typename MeshType<dim - 1, spacedim>::cell_iterator
9234 temporary_map_boundary_cell_face[refined_cell_n].first;
9235 const typename MeshType<dim,
9236 spacedim>::face_iterator refined_face =
9237 temporary_map_boundary_cell_face[refined_cell_n].second.first;
9238 const unsigned int refined_face_number =
9239 temporary_map_boundary_cell_face[refined_cell_n]
9241 for (
unsigned int child_n = 0;
9242 child_n < refined_cell->n_children();
9247 temporary_map_boundary_cell_face.push_back(
9248 std::make_pair(refined_cell->child(
9249 swap_matrix[refined_face_number][child_n]),
9250 std::make_pair(refined_face->child(child_n),
9251 refined_face_number)));
9261 std::map<
typename MeshType<dim - 1, spacedim>::cell_iterator,
9262 typename MeshType<dim, spacedim>::face_iterator>
9263 surface_to_volume_mapping;
9264 for (
unsigned int i = 0; i < temporary_map_boundary_cell_face.size(); ++i)
9265 surface_to_volume_mapping[temporary_map_boundary_cell_face[i].first] =
9266 temporary_map_boundary_cell_face[i].second.first;
9269 const auto attached_mids =
9270 surface_mesh.get_triangulation().get_manifold_ids();
9271 for (
const auto i : volume_mesh.get_triangulation().get_manifold_ids())
9273 std::find(attached_mids.begin(), attached_mids.end(), i) ==
9274 attached_mids.end())
9276 surface_mesh.get_triangulation())
9279 return surface_to_volume_mapping;
9284 template <
int dim,
int spacedim>
9288 const std::vector<unsigned int> &repetitions,
9291 const bool colorize)
9295 std::vector<Point<spacedim>> vertices;
9296 std::vector<CellData<dim>> cells;
9302 (p2[1] - p1[1]) / repetitions[1]);
9305 for (
unsigned int j = 0; j <= repetitions[1]; ++j)
9306 for (
unsigned int i = 0; i <= repetitions[0]; ++i)
9311 for (
unsigned int j = 0; j < repetitions[1]; ++j)
9312 for (
unsigned int i = 0; i < repetitions[0]; ++i)
9315 std::array<unsigned int, 4> quad{{
9316 (j + 0) * (repetitions[0] + 1) + i + 0,
9317 (j + 0) * (repetitions[0] + 1) + i + 1,
9318 (j + 1) * (repetitions[0] + 1) + i + 0,
9319 (j + 1) * (repetitions[0] + 1) + i + 1
9325 tri.
vertices = {quad[0], quad[1], quad[2]};
9326 cells.push_back(tri);
9332 tri.
vertices = {quad[3], quad[2], quad[1]};
9333 cells.push_back(tri);
9341 (p2[1] - p1[1]) / repetitions[1],
9342 (p2[2] - p1[2]) / repetitions[2]);
9345 for (
unsigned int k = 0; k <= repetitions[2]; ++k)
9346 for (
unsigned int j = 0; j <= repetitions[1]; ++j)
9347 for (
unsigned int i = 0; i <= repetitions[0]; ++i)
9350 p1[2] + dx[2] * k));
9353 for (
unsigned int k = 0; k < repetitions[2]; ++k)
9354 for (
unsigned int j = 0; j < repetitions[1]; ++j)
9355 for (
unsigned int i = 0; i < repetitions[0]; ++i)
9358 std::array<unsigned int, 8> quad{
9359 {(k + 0) * (repetitions[0] + 1) * (repetitions[1] + 1) +
9360 (j + 0) * (repetitions[0] + 1) + i + 0,
9361 (k + 0) * (repetitions[0] + 1) * (repetitions[1] + 1) +
9362 (j + 0) * (repetitions[0] + 1) + i + 1,
9363 (k + 0) * (repetitions[0] + 1) * (repetitions[1] + 1) +
9364 (j + 1) * (repetitions[0] + 1) + i + 0,
9365 (k + 0) * (repetitions[0] + 1) * (repetitions[1] + 1) +
9366 (j + 1) * (repetitions[0] + 1) + i + 1,
9367 (k + 1) * (repetitions[0] + 1) * (repetitions[1] + 1) +
9368 (j + 0) * (repetitions[0] + 1) + i + 0,
9369 (k + 1) * (repetitions[0] + 1) * (repetitions[1] + 1) +
9370 (j + 0) * (repetitions[0] + 1) + i + 1,
9371 (k + 1) * (repetitions[0] + 1) * (repetitions[1] + 1) +
9372 (j + 1) * (repetitions[0] + 1) + i + 0,
9373 (k + 1) * (repetitions[0] + 1) * (repetitions[1] + 1) +
9374 (j + 1) * (repetitions[0] + 1) + i + 1}};
9379 if (((i % 2) + (j % 2) + (k % 2)) % 2 == 0)
9380 cell.
vertices = {{quad[0], quad[1], quad[2], quad[4]}};
9382 cell.
vertices = {{quad[0], quad[1], quad[3], quad[5]}};
9384 cells.push_back(cell);
9390 if (((i % 2) + (j % 2) + (k % 2)) % 2 == 0)
9391 cell.
vertices = {{quad[2], quad[1], quad[3], quad[7]}};
9393 cell.
vertices = {{quad[0], quad[3], quad[2], quad[6]}};
9394 cells.push_back(cell);
9400 if (((i % 2) + (j % 2) + (k % 2)) % 2 == 0)
9401 cell.
vertices = {{quad[1], quad[4], quad[5], quad[7]}};
9403 cell.
vertices = {{quad[0], quad[4], quad[5], quad[6]}};
9404 cells.push_back(cell);
9410 if (((i % 2) + (j % 2) + (k % 2)) % 2 == 0)
9411 cell.
vertices = {{quad[2], quad[4], quad[7], quad[6]}};
9413 cell.
vertices = {{quad[3], quad[5], quad[7], quad[6]}};
9414 cells.push_back(cell);
9420 if (((i % 2) + (j % 2) + (k % 2)) % 2 == 0)
9421 cell.
vertices = {{quad[1], quad[2], quad[4], quad[7]}};
9423 cell.
vertices = {{quad[0], quad[3], quad[6], quad[5]}};
9424 cells.push_back(cell);
9446 double epsilon = std::numeric_limits<double>::max();
9447 for (
unsigned int i = 0; i < dim; ++i)
9449 0.01 * (
std::abs(p2[i] - p1[i]) / repetitions[i]));
9452 "The distance between corner points must be positive."));
9456 colorize_subdivided_hyper_rectangle(tria, p1, p2, epsilon);
9462 template <
int dim,
int spacedim>
9465 const unsigned int repetitions,
9468 const bool colorize)
9473 tria, {{repetitions, repetitions}}, {p1, p1}, {p2, p2}, colorize);
9479 {{repetitions, repetitions, repetitions}},
9492# include "grid/grid_generator.inst"
ArrayView< std::remove_reference_t< typename std::iterator_traits< Iterator >::reference >, MemorySpaceType > make_array_view(const Iterator begin, const Iterator end)
unsigned int face_index(const unsigned int i) const
bool at_boundary(const unsigned int i) const
TriaIterator< TriaAccessor< dim - 1, dim, spacedim > > face(const unsigned int i) const
void set_material_id(const types::material_id new_material_id) const
unsigned int active_cell_index() const
types::material_id material_id() const
void make_mapping(const MeshType &source_grid, const MeshType &destination_grid)
void add_parameter(const std::string &entry, ParameterType ¶meter, const std::string &documentation="", const Patterns::PatternBase &pattern= *Patterns::Tools::Convert< ParameterType >::to_pattern(), const bool has_to_be_set=false)
void enter_subsection(const std::string &subsection, const bool create_path_if_needed=true)
numbers::NumberTraits< Number >::real_type distance(const Point< dim, Number > &p) const
const Point< spacedim > & get_center() const
std_cxx20::ranges::iota_view< unsigned int, unsigned int > face_indices() const
numbers::NumberTraits< Number >::real_type norm() const
constexpr numbers::NumberTraits< double >::real_type norm_square() const
void initialize(const Triangulation< dim, spacedim > &triangulation)
std_cxx20::ranges::iota_view< unsigned int, unsigned int > vertex_indices() const
unsigned int n_lines() const
unsigned int n_vertices() const
std_cxx20::ranges::iota_view< unsigned int, unsigned int > line_indices() const
void set_all_manifold_ids(const types::manifold_id manifold_ind) const
std_cxx20::ranges::iota_view< unsigned int, unsigned int > face_indices() const
types::manifold_id manifold_id() const
unsigned int vertex_index(const unsigned int i) const
Point< spacedim > center(const bool respect_manifold=false, const bool interpolate_from_surrounding=false) const
Point< spacedim > & vertex(const unsigned int i) const
ReferenceCell reference_cell() const
typename::internal::TriangulationImplementation::Iterators< dim, spacedim >::line_iterator line(const unsigned int i) const
unsigned int n_faces() const
virtual void add_periodicity(const std::vector< GridTools::PeriodicFacePair< cell_iterator > > &)
virtual types::global_cell_index n_global_active_cells() const
virtual void copy_triangulation(const Triangulation< dim, spacedim > &other_tria)
unsigned int n_faces() const
bool all_reference_cells_are_hyper_cube() const
void save_user_flags_line(std::ostream &out) const
face_iterator end_face() const
cell_iterator begin(const unsigned int level=0) const
virtual void create_triangulation(const std::vector< Point< spacedim > > &vertices, const std::vector< CellData< dim > > &cells, const SubCellData &subcelldata)
unsigned int n_active_cells() const
void refine_global(const unsigned int times=1)
const std::vector< Point< spacedim > > & get_vertices() const
unsigned int n_active_lines() const
unsigned int n_levels() const
cell_iterator end() const
virtual bool has_hanging_nodes() const
vertex_iterator begin_vertex() const
vertex_iterator end_vertex() const
virtual void execute_coarsening_and_refinement()
virtual unsigned int n_global_levels() const
cell_iterator last() const
face_iterator begin_face() const
unsigned int n_cells() const
void save_user_flags_quad(std::ostream &out) const
unsigned int n_vertices() const
active_cell_iterator begin_active(const unsigned int level=0) const
#define DEAL_II_NAMESPACE_OPEN
constexpr bool running_in_debug_mode()
#define DEAL_II_CXX20_REQUIRES(condition)
#define DEAL_II_NAMESPACE_CLOSE
#define DEAL_II_ASSERT_UNREACHABLE()
#define DEAL_II_NOT_IMPLEMENTED()
constexpr unsigned int GeometryInfo< dim >::vertices_per_cell
IteratorRange< active_face_iterator > active_face_iterators() const
IteratorRange< active_cell_iterator > active_cell_iterators() const
IteratorRange< cell_iterator > cell_iterators() const
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
static ::ExceptionBase & ExcLowerRange(int arg1, int arg2)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcIndexRange(std::size_t arg1, std::size_t arg2, std::size_t arg3)
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
TriaActiveIterator< CellAccessor< dim, spacedim > > active_cell_iterator
TriaIterator< TriaAccessor< dim - 1, dim, spacedim > > face_iterator
TriaIterator< CellAccessor< dim, spacedim > > cell_iterator
void set_all_manifold_ids_on_boundary(const types::manifold_id number)
const Manifold< dim, spacedim > & get_manifold(const types::manifold_id number) const
void copy_boundary_to_manifold_id(Triangulation< dim, spacedim > &tria, const bool reset_boundary_ids=false)
virtual std::vector< types::manifold_id > get_manifold_ids() const
void set_manifold(const types::manifold_id number, const Manifold< dim, spacedim > &manifold_object)
void reset_all_manifolds()
void set_all_manifold_ids(const types::manifold_id number)
void set_manifold_id(const types::manifold_id) const
void consistently_order_cells(std::vector< CellData< dim > > &cells)
const Mapping< dim, spacedim > & get_default_linear_mapping(const Triangulation< dim, spacedim > &triangulation)
CGAL::Exact_predicates_exact_constructions_kernel_with_sqrt K
void create_triangulation(Triangulation< dim, dim > &tria, const AdditionalData &additional_data=AdditionalData())
void subdivided_hyper_cube_with_simplices(Triangulation< dim, spacedim > &tria, const unsigned int repetitions, const double p1=0.0, const double p2=1.0, const bool colorize=false)
void parallelepiped(Triangulation< dim > &tria, const Point< dim >(&corners)[dim], const bool colorize=false)
void hyper_cross(Triangulation< dim, spacedim > &tria, const std::vector< unsigned int > &sizes, const bool colorize_cells=false)
A center cell with stacks of cell protruding from each surface.
void hyper_cube_with_cylindrical_hole(Triangulation< dim, spacedim > &triangulation, const double inner_radius=.25, const double outer_radius=.5, const double L=.5, const unsigned int repetitions=1, const bool colorize=false)
void hyper_ball_balanced(Triangulation< dim > &tria, const Point< dim > ¢er=Point< dim >(), const double radius=1.)
void plate_with_a_hole(Triangulation< dim > &tria, const double inner_radius=0.4, const double outer_radius=1., const double pad_bottom=2., const double pad_top=2., const double pad_left=1., const double pad_right=1., const Point< dim > ¢er=Point< dim >(), const types::manifold_id polar_manifold_id=0, const types::manifold_id tfi_manifold_id=1, const double L=1., const unsigned int n_slices=2, const bool colorize=false)
Rectangular plate with an (offset) cylindrical hole.
void enclosed_hyper_cube(Triangulation< dim > &tria, const double left=0., const double right=1., const double thickness=1., const bool colorize=false)
void replicate_triangulation(const Triangulation< dim, spacedim > &input, const std::vector< unsigned int > &extents, Triangulation< dim, spacedim > &result)
Replicate a given triangulation in multiple coordinate axes.
void parallelogram(Triangulation< dim > &tria, const Point< dim >(&corners)[dim], const bool colorize=false)
void general_cell(Triangulation< dim, spacedim > &tria, const std::vector< Point< spacedim > > &vertices, const bool colorize=false)
void subdivided_hyper_cube(Triangulation< dim, spacedim > &tria, const unsigned int repetitions, const double left=0., const double right=1., const bool colorize=false)
void hyper_shell(Triangulation< dim, spacedim > &tria, const Point< spacedim > ¢er, const double inner_radius, const double outer_radius, const unsigned int n_cells=0, bool colorize=false)
void hyper_L(Triangulation< dim > &tria, const double left=-1., const double right=1., const bool colorize=false)
void hyper_cube_slit(Triangulation< dim > &tria, const double left=0., const double right=1., const bool colorize=false)
void eccentric_hyper_shell(Triangulation< dim > &triangulation, const Point< dim > &inner_center, const Point< dim > &outer_center, const double inner_radius, const double outer_radius, const unsigned int n_cells)
void hyper_rectangle(Triangulation< dim, spacedim > &tria, const Point< dim > &p1, const Point< dim > &p2, const bool colorize=false)
void uniform_channel_with_cylinder(Triangulation< dim > &tria, const std::vector< unsigned int > &lengths_and_heights, const double depth=1, const unsigned int depth_division=1, const double shell_region_radius=0.75, const unsigned int n_shells=2, const double skewness=2.0, const bool use_transfinite_region=false, const bool colorize=false)
void cylinder(Triangulation< dim > &tria, const double radius=1., const double half_length=1.)
void moebius(Triangulation< 3, 3 > &tria, const unsigned int n_cells, const unsigned int n_rotations, const double R, const double r)
void extrude_triangulation(const Triangulation< 2, 2 > &input, const unsigned int n_slices, const double height, Triangulation< 3, 3 > &result, const bool copy_manifold_ids=false, const std::vector< types::manifold_id > &manifold_priorities={})
void half_hyper_shell(Triangulation< dim > &tria, const Point< dim > ¢er, const double inner_radius, const double outer_radius, const unsigned int n_cells=0, const bool colorize=false)
void quarter_hyper_ball(Triangulation< dim > &tria, const Point< dim > ¢er=Point< dim >(), const double radius=1.)
void cheese(Triangulation< dim, spacedim > &tria, const std::vector< unsigned int > &holes)
Rectangular domain with rectangular pattern of holes.
void create_union_triangulation(const Triangulation< dim, spacedim > &triangulation_1, const Triangulation< dim, spacedim > &triangulation_2, Triangulation< dim, spacedim > &result)
void hyper_ball(Triangulation< dim, spacedim > &tria, const Point< spacedim > ¢er={}, const double radius=1., const bool attach_spherical_manifold_on_boundary_cells=false)
void subdivided_hyper_rectangle_with_simplices(Triangulation< dim, spacedim > &tria, const std::vector< unsigned int > &repetitions, const Point< dim > &p1, const Point< dim > &p2, const bool colorize=false)
void non_standard_orientation_mesh(Triangulation< 2 > &tria, const unsigned int n_rotate_middle_square)
return_type extract_boundary_mesh(const MeshType< dim, spacedim > &volume_mesh, MeshType< dim - 1, spacedim > &surface_mesh, const std::set< types::boundary_id > &boundary_ids=std::set< types::boundary_id >())
void alfeld_split_of_simplex_mesh(const Triangulation< dim, spacedim > &in_tria, Triangulation< dim, spacedim > &out_tria)
void subdivided_parallelepiped(Triangulation< dim > &tria, const unsigned int n_subdivisions, const Point< dim >(&corners)[dim], const bool colorize=false)
void subdivided_cylinder(Triangulation< dim > &tria, const unsigned int x_subdivisions, const double radius=1., const double half_length=1.)
void convert_hypercube_to_simplex_mesh(const Triangulation< dim, spacedim > &in_tria, Triangulation< dim, spacedim > &out_tria, const unsigned int n_divisions=(dim==2 ? 8u :24u))
void channel_with_cylinder(Triangulation< dim > &tria, const double shell_region_width=0.03, const unsigned int n_shells=2, const double skewness=2.0, const bool colorize=false)
void subdivided_hyper_L(Triangulation< dim, spacedim > &tria, const std::vector< unsigned int > &repetitions, const Point< dim > &bottom_left, const Point< dim > &top_right, const std::vector< int > &n_cells_to_remove)
void hyper_sphere(Triangulation< spacedim - 1, spacedim > &tria, const Point< spacedim > ¢er=Point< spacedim >(), const double radius=1.)
void concentric_hyper_shells(Triangulation< dim > &triangulation, const Point< dim > ¢er, const double inner_radius=0.125, const double outer_radius=0.25, const unsigned int n_shells=1, const double skewness=0.1, const unsigned int n_cells_per_shell=0, const bool colorize=false)
void subdivided_hyper_rectangle(Triangulation< dim, spacedim > &tria, const std::vector< unsigned int > &repetitions, const Point< dim > &p1, const Point< dim > &p2, const bool colorize=false)
void quarter_hyper_shell(Triangulation< dim > &tria, const Point< dim > ¢er, const double inner_radius, const double outer_radius, const unsigned int n_cells=0, const bool colorize=false)
void hyper_cube(Triangulation< dim, spacedim > &tria, const double left=0., const double right=1., const bool colorize=false)
void create_triangulation_with_removed_cells(const Triangulation< dim, spacedim > &input_triangulation, const std::set< typename Triangulation< dim, spacedim >::active_cell_iterator > &cells_to_remove, Triangulation< dim, spacedim > &result)
void simplex(Triangulation< dim, dim > &tria, const std::vector< Point< dim > > &vertices)
void truncated_cone(Triangulation< dim > &tria, const double radius_0=1.0, const double radius_1=0.5, const double half_length=1.0)
void merge_triangulations(const Triangulation< dim, spacedim > &triangulation_1, const Triangulation< dim, spacedim > &triangulation_2, Triangulation< dim, spacedim > &result, const double duplicated_vertex_tolerance=1.0e-12, const bool copy_manifold_ids=false, const bool copy_boundary_ids=false)
void reference_cell(Triangulation< dim, spacedim > &tria, const ReferenceCell &reference_cell)
void half_hyper_ball(Triangulation< dim > &tria, const Point< dim > ¢er=Point< dim >(), const double radius=1.)
void cylinder_shell(Triangulation< dim > &tria, const double length, const double inner_radius, const double outer_radius, const unsigned int n_radial_cells=0, const unsigned int n_axial_cells=0, const bool colorize=false)
void flatten_triangulation(const Triangulation< dim, spacedim1 > &in_tria, Triangulation< dim, spacedim2 > &out_tria)
double norm(const FEValuesBase< dim > &fe, const ArrayView< const std::vector< Tensor< 1, dim > > > &Du)
Point< spacedim > point(const gp_Pnt &p, const double tolerance=1e-10)
SymmetricTensor< 2, dim, Number > C(const Tensor< 2, dim, Number > &F)
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
SymmetricTensor< 2, dim, Number > b(const Tensor< 2, dim, Number > &F)
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
SymmetricTensor< 2, dim, Number > epsilon(const Tensor< 2, dim, Number > &Grad_u)
Tensor< 2, dim, Number > F(const Tensor< 2, dim, Number > &Grad_u)
constexpr const ReferenceCell & get_hypercube()
VectorType::value_type * end(VectorType &V)
VectorType::value_type * begin(VectorType &V)
constexpr T fixed_power(const T t)
std::string int_to_string(const unsigned int value, const unsigned int digits=numbers::invalid_unsigned_int)
long double gamma(const unsigned int n)
unsigned int n_cells(const internal::TriangulationImplementation::NumberCache< 1 > &c)
void copy(const T *begin, const T *end, U *dest)
constexpr unsigned int invalid_unsigned_int
constexpr types::boundary_id internal_face_boundary_id
constexpr types::boundary_id invalid_boundary_id
constexpr types::manifold_id flat_manifold_id
constexpr types::material_id invalid_material_id
::VectorizedArray< Number, width > tan(const ::VectorizedArray< Number, width > &)
inline ::VectorizedArray< Number, width > tanh(const ::VectorizedArray< Number, width > &x)
::VectorizedArray< Number, width > min(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > max(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > cos(const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > sin(const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > sqrt(const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > pow(const ::VectorizedArray< Number, width > &, const Number p)
inline ::VectorizedArray< Number, width > atan(const ::VectorizedArray< Number, width > &x)
::VectorizedArray< Number, width > abs(const ::VectorizedArray< Number, width > &)
typename internal::ndarray::HelperArray< T, Ns... >::type ndarray
std::vector< unsigned int > vertices
types::manifold_id manifold_id
types::material_id material_id
types::boundary_id boundary_id
static unsigned int face_to_cell_vertices(const unsigned int face, const unsigned int vertex, const bool face_orientation=true, const bool face_flip=false, const bool face_rotation=false)
static constexpr unsigned int vertices_per_cell
static constexpr std::array< int, faces_per_cell > unit_normal_orientation
static constexpr ndarray< unsigned int, vertices_per_cell, dim > vertex_to_face
static constexpr unsigned int faces_per_cell
static std_cxx20::ranges::iota_view< unsigned int, unsigned int > face_indices()
static constexpr std::array< unsigned int, faces_per_cell > unit_normal_direction
static constexpr std::array< unsigned int, faces_per_cell > opposite_face
static std_cxx20::ranges::iota_view< unsigned int, unsigned int > vertex_indices()
std::vector< CellData< 2 > > boundary_quads
std::vector< CellData< 1 > > boundary_lines
DEAL_II_HOST constexpr Number determinant(const SymmetricTensor< 2, dim, Number > &)
constexpr Tensor< 1, dim, typename ProductType< Number1, Number2 >::type > cross_product_3d(const Tensor< 1, dim, Number1 > &src1, const Tensor< 1, dim, Number2 > &src2)