45 : airfoil_type(
"NACA")
47 , joukowski_center(-0.1, 0.14)
53 , incline_factor(0.35)
56 , n_subdivision_x_0(3)
57 , n_subdivision_x_1(2)
58 , n_subdivision_x_2(5)
60 , airfoil_sampling_factor(2)
63 airfoil_length <= height,
65 "Mesh is to small to enclose airfoil! Choose larger field or smaller"
67 Assert(incline_factor < 1.0 && incline_factor >= 0.0,
68 ExcMessage(
"incline_factor has to be in [0,1)!"));
81 "Mesh height measured from airfoil nose to horizontal boundaries");
85 "Length measured from airfoil leading edge to vertical outlet boundary");
89 "Define obliqueness of the vertical mesh around the airfoil");
98 "Type of airfoil geometry, either NACA or Joukowski airfoil",
113 "Joukowski circle center coordinates");
116 "Joukowski airfoil length leading to trailing edge");
124 "Number of global refinements");
126 "NumberSubdivisionX0",
128 "Number of subdivisions along the airfoil in blocks with material ID 1 and 4");
130 "NumberSubdivisionX1",
132 "Number of subdivisions along the airfoil in blocks with material ID 2 and 5");
134 "NumberSubdivisionX2",
136 "Number of subdivisions in horizontal direction on the right of the trailing edge, i.e., blocks with material ID 3 and 6");
139 "Number of subdivisions normal to airfoil");
143 "Factor to obtain a finer mesh at the airfoil surface");
158 static const unsigned int id_block_1 = 1;
159 static const unsigned int id_block_2 = 2;
160 static const unsigned int id_block_3 = 3;
161 static const unsigned int id_block_4 = 4;
162 static const unsigned int id_block_5 = 5;
163 static const unsigned int id_block_6 = 6;
168 MeshGenerator(
const AdditionalData &data)
169 : refinements(data.refinements)
170 , n_subdivision_x_0(data.n_subdivision_x_0)
171 , n_subdivision_x_1(data.n_subdivision_x_1)
172 , n_subdivision_x_2(data.n_subdivision_x_2)
173 , n_subdivision_y(data.n_subdivision_y)
174 , height(data.height)
175 , length_b2(data.length_b2)
176 , incline_factor(data.incline_factor)
177 , bias_factor(data.bias_factor)
179 , n_cells_x_0(
Utilities::
pow(2, refinements) * n_subdivision_x_0)
180 , n_cells_x_1(
Utilities::
pow(2, refinements) * n_subdivision_x_1)
181 , n_cells_x_2(
Utilities::
pow(2, refinements) * n_subdivision_x_2)
182 , n_cells_y(
Utilities::
pow(2, refinements) * n_subdivision_y)
183 , n_points_on_each_side(n_cells_x_0 + n_cells_x_1 + 1)
185 , airfoil_1D(set_airfoil_length(
187 data.airfoil_type ==
"Joukowski" ?
188 joukowski(data.joukowski_center,
189 n_points_on_each_side,
190 data.airfoil_sampling_factor) :
191 (data.airfoil_type ==
"NACA" ?
193 n_points_on_each_side,
194 data.airfoil_sampling_factor) :
195 std::array<std::vector<
Point<2>>, 2>{
197 std::vector<Point<2>>{
201 data.airfoil_length))
202 , end_b0_x_u(airfoil_1D[0][n_cells_x_0](0))
203 , end_b0_x_l(airfoil_1D[1][n_cells_x_0](0))
204 , nose_x(airfoil_1D[0].front()(0))
205 , tail_x(airfoil_1D[0].back()(0))
206 , tail_y(airfoil_1D[0].back()(1))
207 , center_mesh(0.5 * std::abs(end_b0_x_u + end_b0_x_l))
208 , length_b1_x(tail_x - center_mesh)
210 (edge_length + std::abs(nose_x - center_mesh))))
214 ,
A(nose_x - edge_length, 0)
216 ,
C(center_mesh, +std::abs(nose_x - center_mesh) * std::tan(
gamma))
217 , D(center_mesh, height)
218 ,
E(center_mesh, -std::abs(nose_x - center_mesh) * std::tan(
gamma))
219 ,
F(center_mesh, -height)
223 , J(tail_x + length_b2, 0)
227 Assert(data.airfoil_type ==
"Joukowski" ||
228 data.airfoil_type ==
"NACA",
240 make_coarse_grid(tria_grid);
242 set_boundary_ids(tria_grid);
244 if (periodic_faces !=
nullptr)
247 tria_grid, 5, 4, 1, *periodic_faces);
264 (void)periodic_faces;
271 const unsigned int refinements;
274 const unsigned int n_subdivision_x_0;
277 const unsigned int n_subdivision_x_1;
280 const unsigned int n_subdivision_x_2;
284 const unsigned int n_subdivision_y;
291 const double length_b2;
295 const double incline_factor;
298 const double bias_factor;
301 const double edge_length;
304 const unsigned int n_cells_x_0;
307 const unsigned int n_cells_x_1;
310 const unsigned int n_cells_x_2;
314 const unsigned int n_cells_y;
317 const unsigned int n_points_on_each_side;
321 const std::array<std::vector<Point<2>>, 2> airfoil_1D;
325 const double end_b0_x_u;
329 const double end_b0_x_l;
343 const double center_mesh;
346 const double length_b1_x;
373 const Point<2> A, B,
C, D,
E,
F, G, H, I, J, K,
L;
412 static std::array<std::vector<Point<2>>, 2>
413 joukowski(
const Point<2> centerpoint,
414 const unsigned int number_points,
415 const unsigned int factor)
417 std::array<std::vector<Point<2>>, 2> airfoil_1D;
418 const unsigned int total_points = 2 * number_points - 2;
419 const unsigned int n_airfoilpoints = factor * total_points;
421 const auto jouk_points =
422 joukowski_transform(joukowski_circle(centerpoint, n_airfoilpoints));
425 std::vector<Point<2>> upper_points;
426 std::vector<Point<2>> lower_points;
430 unsigned int nose_index = 0;
431 unsigned int tail_index = 0;
432 double nose_x_coordinate = 0;
433 double tail_x_coordinate = 0;
437 for (
unsigned int i = 0; i < jouk_points.size(); i++)
439 if (jouk_points[i](0) < nose_x_coordinate)
441 nose_x_coordinate = jouk_points[i](0);
444 if (jouk_points[i](0) > tail_x_coordinate)
446 tail_x_coordinate = jouk_points[i](0);
452 for (
unsigned int i = tail_index; i < jouk_points.size(); i++)
453 upper_points.emplace_back(jouk_points[i]);
454 for (
unsigned int i = 0; i <= nose_index; i++)
455 upper_points.emplace_back(jouk_points[i]);
456 std::reverse(upper_points.begin(), upper_points.end());
459 lower_points.insert(lower_points.end(),
460 jouk_points.begin() + nose_index,
461 jouk_points.begin() + tail_index + 1);
464 airfoil_1D[0] = make_points_equidistant(upper_points, number_points);
465 airfoil_1D[1] = make_points_equidistant(lower_points, number_points);
468 auto move_nose_to_origin = [](std::vector<Point<2>> &vector) {
469 const double nose_x_pos = vector.front()(0);
470 for (
auto &i : vector)
474 move_nose_to_origin(airfoil_1D[1]);
475 move_nose_to_origin(airfoil_1D[0]);
504 static std::vector<Point<2>>
506 const unsigned int number_points)
508 std::vector<Point<2>> circle_points;
522 radius_test < radius,
524 "Error creating lower circle: Circle for Joukowski-transform does"
525 " not enclose point zeta = -1! Choose different center "
529 const double theta = 2 *
numbers::PI / number_points;
531 for (
unsigned int i = 0; i < number_points; i++)
532 circle_points.emplace_back(
center[0] - radius *
cos(i * theta),
535 return circle_points;
546 static std::vector<Point<2>>
547 joukowski_transform(
const std::vector<
Point<2>> &circle_points)
549 std::vector<Point<2>> joukowski_points(circle_points.size());
552 for (
unsigned int i = 0; i < circle_points.size(); i++)
554 const double chi = circle_points[i](0);
555 const double eta = circle_points[i](1);
556 const std::complex<double> zeta(chi, eta);
557 const std::complex<double> z = zeta + 1. / zeta;
559 joukowski_points[i] = {real(z), imag(z)};
561 return joukowski_points;
580 static std::array<std::vector<Point<2>>, 2>
581 naca(
const std::string &serialnumber,
582 const unsigned int number_points,
583 const unsigned int factor)
587 const unsigned int n_airfoilpoints = factor * number_points;
590 return {{make_points_equidistant(
591 naca_create_points(serialnumber, n_airfoilpoints,
true),
593 make_points_equidistant(
594 naca_create_points(serialnumber, n_airfoilpoints,
false),
609 static std::vector<Point<2>>
610 naca_create_points(
const std::string &serialnumber,
611 const unsigned int number_points,
614 Assert(serialnumber.length() == 4,
615 ExcMessage(
"This NACA-serial number is not implemented!"));
617 return naca_create_points_4_digits(serialnumber,
636 static std::vector<Point<2>>
637 naca_create_points_4_digits(
const std::string &serialnumber,
638 const unsigned int number_points,
642 const unsigned int digit_0 = (serialnumber[0] -
'0');
643 const unsigned int digit_1 = (serialnumber[1] -
'0');
644 const unsigned int digit_2 = (serialnumber[2] -
'0');
645 const unsigned int digit_3 = (serialnumber[3] -
'0');
647 const unsigned int digit_23 = 10 * digit_2 + digit_3;
650 const double t =
static_cast<double>(digit_23) / 100.0;
652 std::vector<Point<2>> naca_points;
654 if (digit_0 == 0 && digit_1 == 0)
655 for (
unsigned int i = 0; i < number_points; i++)
657 const double x = i * 1 / (1.0 * number_points - 1);
660 (0.2969 *
std::pow(x, 0.5) - 0.126 * x -
665 naca_points.emplace_back(x, +y_t);
667 naca_points.emplace_back(x, -y_t);
670 for (
unsigned int i = 0; i < number_points; i++)
672 const double m = 1.0 * digit_0 / 100;
673 const double p = 1.0 * digit_1 / 10;
674 const double x = i * 1 / (1.0 * number_points - 1);
677 (x <= p) ? m / std::pow(p, 2) * (2 * p * x -
std::pow(x, 2)) :
678 m / std::pow(1 - p, 2) *
679 ((1 - 2 * p) + 2 * p * x - std::pow(x, 2));
681 const double dy_c = (x <= p) ?
682 2 * m / std::pow(p, 2) * (p - x) :
683 2 * m / std::pow(1 - p, 2) * (p - x);
687 (0.2969 *
std::pow(x, 0.5) - 0.126 * x -
694 naca_points.emplace_back(x - y_t * std::sin(theta),
695 y_c + y_t * std::cos(theta));
697 naca_points.emplace_back(x + y_t * std::sin(theta),
698 y_c - y_t * std::cos(theta));
714 static std::array<std::vector<Point<2>>, 2>
715 set_airfoil_length(
const std::array<std::vector<
Point<2>>, 2> &input,
716 const double desired_len)
718 std::array<std::vector<Point<2>>, 2> output;
719 output[0] = set_airfoil_length(input[0], desired_len);
720 output[1] = set_airfoil_length(input[1], desired_len);
732 static std::vector<Point<2>>
733 set_airfoil_length(
const std::vector<
Point<2>> &input,
734 const double desired_len)
736 std::vector<Point<2>> output = input;
739 desired_len / input.front().distance(input.back());
741 for (
auto &x : output)
757 static std::vector<Point<2>>
758 make_points_equidistant(
759 const std::vector<
Point<2>> &non_equidistant_points,
760 const unsigned int number_points)
762 const unsigned int n_points =
763 non_equidistant_points
767 std::vector<double> arclength_L(non_equidistant_points.size(), 0);
768 for (
unsigned int i = 0; i < non_equidistant_points.size() - 1; i++)
771 non_equidistant_points[i + 1].distance(non_equidistant_points[i]);
774 const auto airfoil_length =
776 const auto deltaX = airfoil_length / (number_points - 1);
780 std::vector<Point<2>> equidist(
783 equidist[0] = non_equidistant_points[0];
784 equidist[number_points - 1] = non_equidistant_points[n_points - 1];
788 for (
unsigned int j = 0, i = 1; j < n_points - 1; j++)
791 const auto Lj = arclength_L[j];
792 const auto Ljp = arclength_L[j + 1];
794 while (Lj <= i * deltaX && i * deltaX <= Ljp &&
795 i < number_points - 1)
797 equidist[i] =
Point<2>((i * deltaX - Lj) / (Ljp - Lj) *
798 (non_equidistant_points[j + 1] -
799 non_equidistant_points[j]) +
800 non_equidistant_points[j]);
819 std::vector<Triangulation<2>> trias(10);
823 const std::vector<Point<2>> & corner_vertices,
824 const std::vector<unsigned int> &repetitions,
836 auto &
point = it->vertex();
837 const double xi =
point(0);
838 const double eta =
point(1);
841 point = 0.25 * ((1 - xi) * (1 - eta) * corner_vertices[0] +
842 (1 + xi) * (1 - eta) * corner_vertices[1] +
843 (1 - xi) * (1 + eta) * corner_vertices[2] +
844 (1 + xi) * (1 + eta) * corner_vertices[3]);
856 {n_subdivision_y, n_subdivision_x_0},
860 {n_subdivision_y, n_subdivision_x_0},
864 {n_subdivision_x_1, n_subdivision_y},
868 {n_subdivision_x_1, n_subdivision_y},
872 {n_subdivision_x_2, n_subdivision_y},
876 {n_subdivision_x_2, n_subdivision_y},
905 if (cell->face(f)->at_boundary() ==
false)
908 const auto mid = cell->material_id();
910 if ((mid == id_block_1 && f == 0) ||
911 (mid == id_block_4 && f == 0))
912 cell->face(f)->set_boundary_id(0);
913 else if ((mid == id_block_3 && f == 0) ||
914 (mid == id_block_6 && f == 2))
915 cell->face(f)->set_boundary_id(1);
916 else if ((mid == id_block_1 && f == 1) ||
917 (mid == id_block_2 && f == 1))
918 cell->face(f)->set_boundary_id(2);
919 else if ((mid == id_block_4 && f == 1) ||
920 (mid == id_block_5 && f == 3))
921 cell->face(f)->set_boundary_id(3);
922 else if ((mid == id_block_2 && f == 0) ||
923 (mid == id_block_3 && f == 2))
924 cell->face(f)->set_boundary_id(4);
925 else if ((mid == id_block_5 && f == 2) ||
926 (mid == id_block_6 && f == 0))
927 cell->face(f)->set_boundary_id(5);
946 std::vector<bool> vertex_processed(tria.
n_vertices(),
false);
956 rotation_matrix_2 =
transpose(rotation_matrix_1);
964 std::sin(
gamma) * edge_length);
967 for (
auto &cell : tria)
971 if (vertex_processed[cell.vertex_index(v)])
975 vertex_processed[cell.vertex_index(v)] =
true;
977 auto &node = cell.vertex(v);
980 if (cell.material_id() == id_block_1 ||
981 cell.material_id() == id_block_4)
990 if (cell.material_id() == id_block_1)
993 (node - horizontal_offset) +
999 else if (cell.material_id() == id_block_4)
1002 (node - horizontal_offset) -
1008 const double trapeze_height =
1014 const double x2 =
L - l_a - l_b;
1016 const double Dx = x1 + x2 + x3;
1017 const double deltax =
1019 const double dx = Dx / n_cells_x_0;
1020 const double dy = trapeze_height / n_cells_y;
1022 static_cast<int>(std::round((node_(0) - deltax) /
dx));
1024 static_cast<int>(std::round(std::abs(node_(1)) / dy));
1026 node_(0) =
numbers::PI / 2 * (1.0 * ix) / n_cells_x_0;
1027 node_(1) = height * (1.0 * iy) / n_cells_y;
1034 const double dy = height / n_cells_y;
1036 static_cast<int>(std::round(node_(0) /
dx));
1038 static_cast<int>(std::round(node_(1) / dy));
1039 const double alpha =
1040 bias_alpha(1 - (1.0 * iy) / n_cells_y);
1041 const double theta = node_(0);
1042 const Point<2> p(-height * std::cos(theta) + center_mesh,
1043 ((cell.material_id() == id_block_1) ?
1049 (cell.material_id() == id_block_1) ? (0) : (1))][ix] *
1054 else if (cell.material_id() == id_block_2 ||
1055 cell.material_id() == id_block_5)
1059 (std::abs(D(1) -
C(1)) == std::abs(
F(1) -
E(1))) &&
1060 (std::abs(
C(1)) == std::abs(
E(1))) &&
1061 (std::abs(G(1)) == std::abs(I(1))),
1063 "Points D,C,G and E,F,I are not defined symmetric to "
1064 "x-axis, which is required to interpolate block 2"
1065 " and 5 with same geometric computations."));
1066 const double l_y = D(1) -
C(1);
1067 const double l_h = D(1) - l_y;
1068 const double by = -l_h / length_b1_x * (node(0) - H(0));
1069 const double dy = (height - by) / n_cells_y;
1070 const int iy =
static_cast<int>(
1071 std::round((std::abs(node(1)) - by) / dy));
1072 const double dx = length_b1_x / n_cells_x_1;
1073 const int ix =
static_cast<int>(
1074 std::round(std::abs(node(0) - center_mesh) /
dx));
1076 const double alpha = bias_alpha(1 - (1.0 * iy) / n_cells_y);
1081 incline_factor * length_b2 * ix /
1083 ((cell.material_id() == id_block_2) ?
1089 (cell.material_id() == id_block_2) ? (0) : (1))]
1090 [n_cells_x_0 + ix] *
1094 else if (cell.material_id() == id_block_3 ||
1095 cell.material_id() == id_block_6)
1098 const double dx = length_b2 / n_cells_x_2;
1099 const double dy = height / n_cells_y;
1100 const int ix =
static_cast<int>(
1101 std::round(std::abs(node(0) - H(0)) /
dx));
1103 static_cast<int>(std::round(std::abs(node(1)) / dy));
1105 const double alpha_y = bias_alpha(1 - 1.0 * iy / n_cells_y);
1106 const double alpha_x =
1107 bias_alpha(1 - (
static_cast<double>(ix)) / n_cells_x_2);
1111 const Point<2> p1(J(0) - (1 - incline_factor) * length_b2 *
1113 ((cell.material_id() == id_block_3) ?
1118 const Point<2> p2(J(0) - alpha_x * length_b2, tail_y);
1119 node = p1 * (1 - alpha_y) + p2 * alpha_y;
1139 bias_alpha(
double alpha)
const
1148 void internal_create_triangulation(
1152 const AdditionalData & additional_data)
1154 MeshGenerator mesh_generator(additional_data);
1157 if (
auto parallel_tria =
1160 mesh_generator.create_triangulation(*parallel_tria, periodic_faces);
1161 else if (
auto parallel_tria =
dynamic_cast<
1164 mesh_generator.create_triangulation(*parallel_tria, periodic_faces);
1166 mesh_generator.create_triangulation(tria, periodic_faces);
1181 const AdditionalData &)
1190 const AdditionalData &additional_data)
1192 internal_create_triangulation(tria,
nullptr, additional_data);
1202 const AdditionalData & additional_data)
1204 internal_create_triangulation(tria, &periodic_faces, additional_data);
1214 const AdditionalData & additional_data)
1218 (void)additional_data;
1219 (void)periodic_faces;
1230 template <
int dim,
int spacedim>
1242 cell->face(f)->set_boundary_id(f);
1248 template <
int spacedim>
1258 if (cell->center()(0) > 0)
1259 cell->set_material_id(1);
1266 template <
int dim,
int spacedim>
1284 for (; face != endface; ++face)
1285 if (face->at_boundary())
1286 if (face->boundary_id() == 0)
1291 face->set_boundary_id(0);
1293 face->set_boundary_id(1);
1295 face->set_boundary_id(2);
1297 face->set_boundary_id(3);
1299 face->set_boundary_id(4);
1301 face->set_boundary_id(5);
1316 for (
unsigned int d = 0;
d < dim; ++
d)
1317 if (cell->center()(
d) > 0)
1319 cell->set_material_id(
id);
1344 cell->face(2)->set_all_boundary_ids(1);
1367 cell->face(4)->set_all_boundary_ids(1);
1371 cell->face(2)->set_all_boundary_ids(1);
1375 cell->face(2)->set_all_boundary_ids(1);
1379 cell->face(0)->set_all_boundary_ids(1);
1383 cell->face(2)->set_all_boundary_ids(1);
1387 cell->face(0)->set_all_boundary_ids(1);
1389 else if (tria.
n_cells() == 12)
1398 cell->face(5)->set_all_boundary_ids(1);
1401 else if (tria.
n_cells() == 96)
1414 unsigned int count = 0;
1418 if (cell->face(5)->at_boundary())
1420 cell->face(5)->set_all_boundary_ids(1);
1438 const double inner_radius,
1439 const double outer_radius)
1444 double middle = (outer_radius - inner_radius) / 2e0 + inner_radius;
1445 double eps = 1
e-3 * middle;
1448 for (; cell != tria.
end(); ++cell)
1451 if (!cell->face(f)->at_boundary())
1454 double radius = cell->face(f)->center().norm() -
center.
norm();
1455 if (
std::fabs(cell->face(f)->center()(0)) <
1458 cell->face(f)->set_boundary_id(2);
1459 for (
unsigned int j = 0; j < GeometryInfo<3>::lines_per_face;
1461 if (cell->face(f)->line(j)->at_boundary())
1462 if (
std::fabs(cell->face(f)->line(j)->vertex(0).norm() -
1463 cell->face(f)->line(j)->vertex(1).norm()) >
1465 cell->face(f)->line(j)->set_boundary_id(2);
1467 else if (
std::fabs(cell->face(f)->center()(1)) <
1470 cell->face(f)->set_boundary_id(3);
1471 for (
unsigned int j = 0; j < GeometryInfo<3>::lines_per_face;
1473 if (cell->face(f)->line(j)->at_boundary())
1474 if (
std::fabs(cell->face(f)->line(j)->vertex(0).norm() -
1475 cell->face(f)->line(j)->vertex(1).norm()) >
1477 cell->face(f)->line(j)->set_boundary_id(3);
1479 else if (
std::fabs(cell->face(f)->center()(2)) <
1482 cell->face(f)->set_boundary_id(4);
1483 for (
unsigned int j = 0; j < GeometryInfo<3>::lines_per_face;
1485 if (cell->face(f)->line(j)->at_boundary())
1486 if (
std::fabs(cell->face(f)->line(j)->vertex(0).norm() -
1487 cell->face(f)->line(j)->vertex(1).norm()) >
1489 cell->face(f)->line(j)->set_boundary_id(4);
1491 else if (radius < middle)
1493 cell->face(f)->set_boundary_id(0);
1494 for (
unsigned int j = 0; j < GeometryInfo<3>::lines_per_face;
1496 if (cell->face(f)->line(j)->at_boundary())
1497 if (
std::fabs(cell->face(f)->line(j)->vertex(0).norm() -
1498 cell->face(f)->line(j)->vertex(1).norm()) <
1500 cell->face(f)->line(j)->set_boundary_id(0);
1502 else if (radius > middle)
1504 cell->face(f)->set_boundary_id(1);
1505 for (
unsigned int j = 0; j < GeometryInfo<3>::lines_per_face;
1507 if (cell->face(f)->line(j)->at_boundary())
1508 if (
std::fabs(cell->face(f)->line(j)->vertex(0).norm() -
1509 cell->face(f)->line(j)->vertex(1).norm()) <
1511 cell->face(f)->line(j)->set_boundary_id(1);
1521 template <
int dim,
int spacedim>
1532 for (
unsigned int i = 0; i < dim; ++i)
1572 std::vector<CellData<dim>> cells(1);
1574 cells[0].vertices[i] = i;
1575 cells[0].material_id = 0;
1581 colorize_hyper_rectangle(tria);
1585 template <
int dim,
int spacedim>
1593 ExcMessage(
"Invalid left-to-right bounds of hypercube"));
1596 for (
unsigned int i = 0; i < dim; ++i)
1614 for (
unsigned int d = 0;
d < dim; ++
d)
1615 for (
unsigned int c = 1; c <= dim; ++c)
1618 ExcMessage(
"Vertices of simplex must form a right handed system"));
1622 std::vector<Point<dim>> points =
vertices;
1626 for (
unsigned int i = 0; i <= dim; ++i)
1628 points.push_back(0.5 * (points[i] + points[(i + 1) % (dim + 1)]));
1634 for (
unsigned int i = 1; i < dim; ++i)
1635 points.push_back(0.5 * (points[i - 1] + points[i + 1]));
1637 for (
unsigned int i = 0; i <= dim; ++i)
1638 points.push_back(1. / 3. *
1639 (points[i] + points[(i + 1) % (dim + 1)] +
1640 points[(i + 2) % (dim + 1)]));
1642 points.push_back((1. / (dim + 1)) *
center);
1644 std::vector<CellData<dim>> cells(dim + 1);
1649 cells[0].vertices[0] = 0;
1650 cells[0].vertices[1] = 3;
1651 cells[0].vertices[2] = 5;
1652 cells[0].vertices[3] = 6;
1653 cells[0].material_id = 0;
1655 cells[1].vertices[0] = 3;
1656 cells[1].vertices[1] = 1;
1657 cells[1].vertices[2] = 6;
1658 cells[1].vertices[3] = 4;
1659 cells[1].material_id = 0;
1661 cells[2].vertices[0] = 5;
1662 cells[2].vertices[1] = 6;
1663 cells[2].vertices[2] = 2;
1664 cells[2].vertices[3] = 4;
1665 cells[2].material_id = 0;
1669 cells[0].vertices[0] = 0;
1670 cells[0].vertices[1] = 4;
1671 cells[0].vertices[2] = 8;
1672 cells[0].vertices[3] = 10;
1673 cells[0].vertices[4] = 7;
1674 cells[0].vertices[5] = 13;
1675 cells[0].vertices[6] = 12;
1676 cells[0].vertices[7] = 14;
1677 cells[0].material_id = 0;
1679 cells[1].vertices[0] = 4;
1680 cells[1].vertices[1] = 1;
1681 cells[1].vertices[2] = 10;
1682 cells[1].vertices[3] = 5;
1683 cells[1].vertices[4] = 13;
1684 cells[1].vertices[5] = 9;
1685 cells[1].vertices[6] = 14;
1686 cells[1].vertices[7] = 11;
1687 cells[1].material_id = 0;
1689 cells[2].vertices[0] = 8;
1690 cells[2].vertices[1] = 10;
1691 cells[2].vertices[2] = 2;
1692 cells[2].vertices[3] = 5;
1693 cells[2].vertices[4] = 12;
1694 cells[2].vertices[5] = 14;
1695 cells[2].vertices[6] = 6;
1696 cells[2].vertices[7] = 11;
1697 cells[2].material_id = 0;
1699 cells[3].vertices[0] = 7;
1700 cells[3].vertices[1] = 13;
1701 cells[3].vertices[2] = 12;
1702 cells[3].vertices[3] = 14;
1703 cells[3].vertices[4] = 3;
1704 cells[3].vertices[5] = 9;
1705 cells[3].vertices[6] = 6;
1706 cells[3].vertices[7] = 11;
1707 cells[3].material_id = 0;
1718 const unsigned int n_rotations,
1722 const unsigned int dim = 3;
1725 "More than 4 cells are needed to create a moebius grid."));
1727 ExcMessage(
"Outer and inner radius must be positive."));
1729 ExcMessage(
"Outer radius must be greater than inner radius."));
1736 for (
unsigned int i = 0; i <
n_cells; ++i)
1737 for (
unsigned int j = 0; j < 4; ++j)
1751 unsigned int offset = 0;
1753 std::vector<CellData<dim>> cells(
n_cells);
1754 for (
unsigned int i = 0; i <
n_cells; ++i)
1756 for (
unsigned int j = 0; j < 2; ++j)
1758 cells[i].vertices[0 + 4 * j] = offset + 0 + 4 * j;
1759 cells[i].vertices[1 + 4 * j] = offset + 3 + 4 * j;
1760 cells[i].vertices[2 + 4 * j] = offset + 2 + 4 * j;
1761 cells[i].vertices[3 + 4 * j] = offset + 1 + 4 * j;
1764 cells[i].material_id = 0;
1768 cells[
n_cells - 1].vertices[4] = (0 + n_rotations) % 4;
1769 cells[
n_cells - 1].vertices[5] = (3 + n_rotations) % 4;
1770 cells[
n_cells - 1].vertices[6] = (2 + n_rotations) % 4;
1771 cells[
n_cells - 1].vertices[7] = (1 + n_rotations) % 4;
1787 ExcMessage(
"Outer radius R must be greater than the inner "
1791 const unsigned int dim = 2;
1792 const unsigned int spacedim = 3;
1793 std::vector<Point<spacedim>>
vertices(16);
1812 std::vector<CellData<dim>> cells(16);
1814 cells[0].vertices[0] = 0;
1815 cells[0].vertices[1] = 4;
1816 cells[0].vertices[2] = 7;
1817 cells[0].vertices[3] = 3;
1818 cells[0].material_id = 0;
1820 cells[1].vertices[0] = 1;
1821 cells[1].vertices[1] = 5;
1822 cells[1].vertices[2] = 4;
1823 cells[1].vertices[3] = 0;
1824 cells[1].material_id = 0;
1826 cells[2].vertices[0] = 2;
1827 cells[2].vertices[1] = 6;
1828 cells[2].vertices[2] = 5;
1829 cells[2].vertices[3] = 1;
1830 cells[2].material_id = 0;
1832 cells[3].vertices[0] = 3;
1833 cells[3].vertices[1] = 7;
1834 cells[3].vertices[2] = 6;
1835 cells[3].vertices[3] = 2;
1836 cells[3].material_id = 0;
1838 cells[4].vertices[0] = 4;
1839 cells[4].vertices[1] = 8;
1840 cells[4].vertices[2] = 11;
1841 cells[4].vertices[3] = 7;
1842 cells[4].material_id = 0;
1844 cells[5].vertices[0] = 5;
1845 cells[5].vertices[1] = 9;
1846 cells[5].vertices[2] = 8;
1847 cells[5].vertices[3] = 4;
1848 cells[5].material_id = 0;
1850 cells[6].vertices[0] = 6;
1851 cells[6].vertices[1] = 10;
1852 cells[6].vertices[2] = 9;
1853 cells[6].vertices[3] = 5;
1854 cells[6].material_id = 0;
1856 cells[7].vertices[0] = 7;
1857 cells[7].vertices[1] = 11;
1858 cells[7].vertices[2] = 10;
1859 cells[7].vertices[3] = 6;
1860 cells[7].material_id = 0;
1862 cells[8].vertices[0] = 8;
1863 cells[8].vertices[1] = 12;
1864 cells[8].vertices[2] = 15;
1865 cells[8].vertices[3] = 11;
1866 cells[8].material_id = 0;
1868 cells[9].vertices[0] = 9;
1869 cells[9].vertices[1] = 13;
1870 cells[9].vertices[2] = 12;
1871 cells[9].vertices[3] = 8;
1872 cells[9].material_id = 0;
1874 cells[10].vertices[0] = 10;
1875 cells[10].vertices[1] = 14;
1876 cells[10].vertices[2] = 13;
1877 cells[10].vertices[3] = 9;
1878 cells[10].material_id = 0;
1880 cells[11].vertices[0] = 11;
1881 cells[11].vertices[1] = 15;
1882 cells[11].vertices[2] = 14;
1883 cells[11].vertices[3] = 10;
1884 cells[11].material_id = 0;
1886 cells[12].vertices[0] = 12;
1887 cells[12].vertices[1] = 0;
1888 cells[12].vertices[2] = 3;
1889 cells[12].vertices[3] = 15;
1890 cells[12].material_id = 0;
1892 cells[13].vertices[0] = 13;
1893 cells[13].vertices[1] = 1;
1894 cells[13].vertices[2] = 0;
1895 cells[13].vertices[3] = 12;
1896 cells[13].material_id = 0;
1898 cells[14].vertices[0] = 14;
1899 cells[14].vertices[1] = 2;
1900 cells[14].vertices[2] = 1;
1901 cells[14].vertices[3] = 13;
1902 cells[14].material_id = 0;
1904 cells[15].vertices[0] = 15;
1905 cells[15].vertices[1] = 3;
1906 cells[15].vertices[2] = 2;
1907 cells[15].vertices[3] = 14;
1908 cells[15].material_id = 0;
1926 const unsigned int n_cells_toroidal,
1930 ExcMessage(
"Outer radius R must be greater than the inner "
1933 Assert(n_cells_toroidal > 2,
1934 ExcMessage(
"Number of cells in toroidal direction has "
1935 "to be at least 3."));
1941 double const a = 1. / (1 +
std::sqrt(2.0));
1944 const unsigned int additional_layer =
1948 const unsigned int n_point_layers_toroidal =
1949 n_cells_toroidal + additional_layer;
1950 std::vector<Point<3>>
vertices(8 * n_point_layers_toroidal);
1962 double const phi_cell = phi / n_cells_toroidal;
1963 for (
unsigned int c = 1; c < n_point_layers_toroidal; ++c)
1965 for (
unsigned int v = 0; v < 8; ++v)
1967 double const r_2d =
vertices[v][0];
1975 std::vector<CellData<3>> cells(5 * n_cells_toroidal);
1976 for (
unsigned int c = 0; c < n_cells_toroidal; ++c)
1978 for (
unsigned int j = 0; j < 2; ++j)
1980 const unsigned int offset =
1981 (8 * (c + j)) % (8 * n_point_layers_toroidal);
1984 cells[5 * c].vertices[0 + j * 4] = offset + 0;
1985 cells[5 * c].vertices[1 + j * 4] = offset + 1;
1986 cells[5 * c].vertices[2 + j * 4] = offset + 2;
1987 cells[5 * c].vertices[3 + j * 4] = offset + 3;
1989 cells[5 * c + 1].vertices[0 + j * 4] = offset + 2;
1990 cells[5 * c + 1].vertices[1 + j * 4] = offset + 3;
1991 cells[5 * c + 1].vertices[2 + j * 4] = offset + 4;
1992 cells[5 * c + 1].vertices[3 + j * 4] = offset + 5;
1994 cells[5 * c + 2].vertices[0 + j * 4] = offset + 4;
1995 cells[5 * c + 2].vertices[1 + j * 4] = offset + 5;
1996 cells[5 * c + 2].vertices[2 + j * 4] = offset + 6;
1997 cells[5 * c + 2].vertices[3 + j * 4] = offset + 7;
1999 cells[5 * c + 3].vertices[0 + j * 4] = offset + 0;
2000 cells[5 * c + 3].vertices[1 + j * 4] = offset + 2;
2001 cells[5 * c + 3].vertices[2 + j * 4] = offset + 6;
2002 cells[5 * c + 3].vertices[3 + j * 4] = offset + 4;
2004 cells[5 * c + 4].vertices[0 + j * 4] = offset + 3;
2005 cells[5 * c + 4].vertices[1 + j * 4] = offset + 1;
2006 cells[5 * c + 4].vertices[2 + j * 4] = offset + 5;
2007 cells[5 * c + 4].vertices[3 + j * 4] = offset + 7;
2010 cells[5 * c].material_id = 0;
2012 cells[5 * c + 1].material_id = 1;
2013 cells[5 * c + 2].material_id = 0;
2014 cells[5 * c + 3].material_id = 0;
2015 cells[5 * c + 4].material_id = 0;
2030 if (cell->face(f)->at_boundary() && f != 4 && f != 5)
2032 cell->face(f)->set_all_manifold_ids(1);
2037 if (cell->material_id() == 1)
2039 cell->set_all_manifold_ids(2);
2041 cell->set_material_id(0);
2056 template <
int dim,
int spacedim>
2077 "The volume of the cell is not greater than zero. "
2078 "This could be due to the wrong ordering of the vertices."));
2106 std::array<Tensor<1, 2>, 2> edges;
2107 edges[0] = corners[0];
2108 edges[1] = corners[1];
2109 std::vector<unsigned int> subdivisions;
2110 subdivided_parallelepiped<2, 2>(
2111 tria, origin, edges, subdivisions,
colorize);
2122 unsigned int n_subdivisions[dim];
2123 for (
unsigned int i = 0; i < dim; ++i)
2124 n_subdivisions[i] = 1;
2133 const unsigned int n_subdivisions,
2139 unsigned int n_subdivisions_[dim];
2140 for (
unsigned int i = 0; i < dim; ++i)
2141 n_subdivisions_[i] = n_subdivisions;
2151 const unsigned int (&n_subdivisions)[dim],
2153 const unsigned int *n_subdivisions,
2159 std::vector<unsigned int> subdivisions;
2160 std::array<Tensor<1, dim>, dim> edges;
2161 for (
unsigned int i = 0; i < dim; ++i)
2163 subdivisions.push_back(n_subdivisions[i]);
2164 edges[i] = corners[i];
2167 subdivided_parallelepiped<dim, dim>(
2168 tria, origin, edges, subdivisions,
colorize);
2179 template <
int dim,
int spacedim>
2184 const std::vector<unsigned int> &subdivisions,
2187 std::vector<unsigned int> compute_subdivisions = subdivisions;
2188 if (compute_subdivisions.size() == 0)
2190 compute_subdivisions.resize(dim, 1);
2193 Assert(compute_subdivisions.size() == dim,
2194 ExcMessage(
"One subdivision must be provided for each dimension."));
2196 for (
unsigned int i = 0; i < dim; ++i)
2198 Assert(compute_subdivisions[i] > 0,
2201 edges[i].
norm() > 0,
2203 "Edges in subdivided_parallelepiped() must not be degenerate."));
2211 bool twisted_data =
false;
2216 twisted_data = (edges[0][0] < 0);
2223 const double plane_normal =
2224 edges[0][0] * edges[1][1] - edges[0][1] * edges[1][0];
2225 twisted_data = (plane_normal < 0.0);
2233 Assert(std::abs(edges[0] * edges[1] /
2234 (edges[0].
norm() * edges[1].
norm()) -
2237 "Edges in subdivided_parallelepiped() must point in"
2238 " different directions."));
2254 twisted_data = (plane_normal * edges[2] < 0.0);
2264 "The triangulation you are trying to create will consist of cells"
2265 " with negative measures. This is usually the result of input data"
2266 " that does not define a right-handed coordinate system. The usual"
2267 " fix for this is to ensure that in 1D the given point is to the"
2268 " right of the origin (or the given edge tensor is positive), in 2D"
2269 " that the two edges (and their cross product) obey the right-hand"
2270 " rule (which may usually be done by switching the order of the"
2271 " points or edge tensors), or in 3D that the edges form a"
2272 " right-handed coordinate system (which may also be accomplished by"
2273 " switching the order of the first two points or edge tensors)."));
2276 for (
unsigned int i = 0; i < dim; ++i)
2277 for (
unsigned int j = i + 1; j < dim; ++j)
2278 Assert((edges[i] != edges[j]),
2280 "Degenerate edges of subdivided_parallelepiped encountered."));
2283 std::vector<Point<spacedim>> points;
2288 for (
unsigned int x = 0; x <= compute_subdivisions[0]; ++x)
2289 points.push_back(origin + edges[0] / compute_subdivisions[0] * x);
2293 for (
unsigned int y = 0; y <= compute_subdivisions[1]; ++y)
2294 for (
unsigned int x = 0; x <= compute_subdivisions[0]; ++x)
2295 points.push_back(origin + edges[0] / compute_subdivisions[0] * x +
2296 edges[1] / compute_subdivisions[1] * y);
2300 for (
unsigned int z = 0; z <= compute_subdivisions[2]; ++z)
2301 for (
unsigned int y = 0; y <= compute_subdivisions[1]; ++y)
2302 for (
unsigned int x = 0; x <= compute_subdivisions[0]; ++x)
2303 points.push_back(origin +
2304 edges[0] / compute_subdivisions[0] * x +
2305 edges[1] / compute_subdivisions[1] * y +
2306 edges[2] / compute_subdivisions[2] * z);
2315 for (
unsigned int i = 0; i < dim; ++i)
2316 n_cells *= compute_subdivisions[i];
2317 std::vector<CellData<dim>> cells(
n_cells);
2323 for (
unsigned int x = 0; x < compute_subdivisions[0]; ++x)
2325 cells[x].vertices[0] = x;
2326 cells[x].vertices[1] = x + 1;
2329 cells[x].material_id = 0;
2336 const unsigned int n_dy = compute_subdivisions[1];
2337 const unsigned int n_dx = compute_subdivisions[0];
2339 for (
unsigned int y = 0; y < n_dy; ++y)
2340 for (
unsigned int x = 0; x < n_dx; ++x)
2342 const unsigned int c = y * n_dx + x;
2343 cells[c].vertices[0] = y * (n_dx + 1) + x;
2344 cells[c].vertices[1] = y * (n_dx + 1) + x + 1;
2345 cells[c].vertices[2] = (y + 1) * (n_dx + 1) + x;
2346 cells[c].vertices[3] = (y + 1) * (n_dx + 1) + x + 1;
2349 cells[c].material_id = 0;
2357 const unsigned int n_dz = compute_subdivisions[2];
2358 const unsigned int n_dy = compute_subdivisions[1];
2359 const unsigned int n_dx = compute_subdivisions[0];
2361 for (
unsigned int z = 0; z < n_dz; ++z)
2362 for (
unsigned int y = 0; y < n_dy; ++y)
2363 for (
unsigned int x = 0; x < n_dx; ++x)
2365 const unsigned int c = z * n_dy * n_dx + y * n_dx + x;
2367 cells[c].vertices[0] =
2368 z * (n_dy + 1) * (n_dx + 1) + y * (n_dx + 1) + x;
2369 cells[c].vertices[1] =
2370 z * (n_dy + 1) * (n_dx + 1) + y * (n_dx + 1) + x + 1;
2371 cells[c].vertices[2] =
2372 z * (n_dy + 1) * (n_dx + 1) + (y + 1) * (n_dx + 1) + x;
2373 cells[c].vertices[3] = z * (n_dy + 1) * (n_dx + 1) +
2374 (y + 1) * (n_dx + 1) + x + 1;
2375 cells[c].vertices[4] =
2376 (z + 1) * (n_dy + 1) * (n_dx + 1) + y * (n_dx + 1) + x;
2377 cells[c].vertices[5] = (z + 1) * (n_dy + 1) * (n_dx + 1) +
2378 y * (n_dx + 1) + x + 1;
2379 cells[c].vertices[6] = (z + 1) * (n_dy + 1) * (n_dx + 1) +
2380 (y + 1) * (n_dx + 1) + x;
2381 cells[c].vertices[7] = (z + 1) * (n_dy + 1) * (n_dx + 1) +
2382 (y + 1) * (n_dx + 1) + x + 1;
2385 cells[c].material_id = 0;
2406 for (; cell != endc; ++cell)
2410 if (cell->face(face)->at_boundary())
2411 cell->face(face)->set_boundary_id(face);
2418 template <
int dim,
int spacedim>
2421 const unsigned int repetitions,
2428 ExcMessage(
"Invalid left-to-right bounds of hypercube"));
2431 for (
unsigned int i = 0; i < dim; ++i)
2437 std::vector<unsigned int> reps(dim, repetitions);
2443 template <
int dim,
int spacedim>
2446 const std::vector<unsigned int> &repetitions,
2457 for (
unsigned int i = 0; i < dim; ++i)
2464 std::vector<Point<spacedim>> delta(dim);
2465 for (
unsigned int i = 0; i < dim; ++i)
2469 delta[i][i] = (p2[i] - p1[i]) / repetitions[i];
2473 "The first dim entries of coordinates of p1 and p2 need to be different."));
2477 std::vector<Point<spacedim>> points;
2481 for (
unsigned int x = 0; x <= repetitions[0]; ++x)
2482 points.push_back(p1 + x * delta[0]);
2486 for (
unsigned int y = 0; y <= repetitions[1]; ++y)
2487 for (
unsigned int x = 0; x <= repetitions[0]; ++x)
2488 points.push_back(p1 + x * delta[0] + y * delta[1]);
2492 for (
unsigned int z = 0; z <= repetitions[2]; ++z)
2493 for (
unsigned int y = 0; y <= repetitions[1]; ++y)
2494 for (
unsigned int x = 0; x <= repetitions[0]; ++x)
2495 points.push_back(p1 + x * delta[0] + y * delta[1] +
2504 std::vector<CellData<dim>> cells;
2509 cells.resize(repetitions[0]);
2510 for (
unsigned int x = 0; x < repetitions[0]; ++x)
2512 cells[x].vertices[0] = x;
2513 cells[x].vertices[1] = x + 1;
2514 cells[x].material_id = 0;
2521 cells.resize(repetitions[1] * repetitions[0]);
2522 for (
unsigned int y = 0; y < repetitions[1]; ++y)
2523 for (
unsigned int x = 0; x < repetitions[0]; ++x)
2525 const unsigned int c = x + y * repetitions[0];
2526 cells[c].vertices[0] = y * (repetitions[0] + 1) + x;
2527 cells[c].vertices[1] = y * (repetitions[0] + 1) + x + 1;
2528 cells[c].vertices[2] = (y + 1) * (repetitions[0] + 1) + x;
2529 cells[c].vertices[3] = (y + 1) * (repetitions[0] + 1) + x + 1;
2530 cells[c].material_id = 0;
2537 const unsigned int n_x = (repetitions[0] + 1);
2538 const unsigned int n_xy =
2539 (repetitions[0] + 1) * (repetitions[1] + 1);
2541 cells.resize(repetitions[2] * repetitions[1] * repetitions[0]);
2542 for (
unsigned int z = 0; z < repetitions[2]; ++z)
2543 for (
unsigned int y = 0; y < repetitions[1]; ++y)
2544 for (
unsigned int x = 0; x < repetitions[0]; ++x)
2546 const unsigned int c = x + y * repetitions[0] +
2547 z * repetitions[0] * repetitions[1];
2548 cells[c].vertices[0] = z * n_xy + y * n_x + x;
2549 cells[c].vertices[1] = z * n_xy + y * n_x + x + 1;
2550 cells[c].vertices[2] = z * n_xy + (y + 1) * n_x + x;
2551 cells[c].vertices[3] = z * n_xy + (y + 1) * n_x + x + 1;
2552 cells[c].vertices[4] = (z + 1) * n_xy + y * n_x + x;
2553 cells[c].vertices[5] = (z + 1) * n_xy + y * n_x + x + 1;
2554 cells[c].vertices[6] = (z + 1) * n_xy + (y + 1) * n_x + x;
2555 cells[c].vertices[7] =
2556 (z + 1) * n_xy + (y + 1) * n_x + x + 1;
2557 cells[c].material_id = 0;
2579 for (
unsigned int i = 0; i < dim; ++i)
2583 "The distance between corner points must be positive."))
2587 colorize_subdivided_hyper_rectangle(tria, p1, p2,
epsilon);
2596 const std::vector<std::vector<
double>> &step_sz,
2597 const
Point<dim> & p_1,
2598 const
Point<dim> & p_2,
2611 std::vector<std::vector<double>> step_sizes(step_sz);
2613 for (
unsigned int i = 0; i < dim; ++i)
2618 std::reverse(step_sizes[i].
begin(), step_sizes[i].
end());
2622 for (
unsigned int j = 0; j < step_sizes.at(i).size(); j++)
2623 x += step_sizes[i][j];
2626 "The sequence of step sizes in coordinate direction " +
2628 " must be equal to the distance of the two given "
2629 "points in this coordinate direction."));
2635 std::vector<Point<dim>> points;
2641 for (
unsigned int i = 0;; ++i)
2650 if (i == step_sizes[0].size())
2653 x += step_sizes[0][i];
2661 for (
unsigned int j = 0;; ++j)
2664 for (
unsigned int i = 0;; ++i)
2666 points.push_back(
Point<dim>(p1[0] + x, p1[1] + y));
2667 if (i == step_sizes[0].size())
2670 x += step_sizes[0][i];
2673 if (j == step_sizes[1].size())
2676 y += step_sizes[1][j];
2683 for (
unsigned int k = 0;; ++k)
2686 for (
unsigned int j = 0;; ++j)
2689 for (
unsigned int i = 0;; ++i)
2692 Point<dim>(p1[0] + x, p1[1] + y, p1[2] + z));
2693 if (i == step_sizes[0].size())
2696 x += step_sizes[0][i];
2699 if (j == step_sizes[1].size())
2702 y += step_sizes[1][j];
2705 if (k == step_sizes[2].size())
2708 z += step_sizes[2][k];
2719 std::vector<CellData<dim>> cells;
2724 cells.resize(step_sizes[0].size());
2725 for (
unsigned int x = 0; x < step_sizes[0].size(); ++x)
2727 cells[x].vertices[0] = x;
2728 cells[x].vertices[1] = x + 1;
2729 cells[x].material_id = 0;
2736 cells.resize(step_sizes[1].size() * step_sizes[0].size());
2737 for (
unsigned int y = 0; y < step_sizes[1].size(); ++y)
2738 for (
unsigned int x = 0; x < step_sizes[0].size(); ++x)
2740 const unsigned int c = x + y * step_sizes[0].size();
2741 cells[c].vertices[0] = y * (step_sizes[0].size() + 1) + x;
2742 cells[c].vertices[1] = y * (step_sizes[0].size() + 1) + x + 1;
2743 cells[c].vertices[2] =
2744 (y + 1) * (step_sizes[0].size() + 1) + x;
2745 cells[c].vertices[3] =
2746 (y + 1) * (step_sizes[0].size() + 1) + x + 1;
2747 cells[c].material_id = 0;
2754 const unsigned int n_x = (step_sizes[0].size() + 1);
2755 const unsigned int n_xy =
2756 (step_sizes[0].size() + 1) * (step_sizes[1].size() + 1);
2758 cells.resize(step_sizes[2].size() * step_sizes[1].size() *
2759 step_sizes[0].size());
2760 for (
unsigned int z = 0; z < step_sizes[2].size(); ++z)
2761 for (
unsigned int y = 0; y < step_sizes[1].size(); ++y)
2762 for (
unsigned int x = 0; x < step_sizes[0].size(); ++x)
2764 const unsigned int c =
2765 x + y * step_sizes[0].size() +
2766 z * step_sizes[0].size() * step_sizes[1].size();
2767 cells[c].vertices[0] = z * n_xy + y * n_x + x;
2768 cells[c].vertices[1] = z * n_xy + y * n_x + x + 1;
2769 cells[c].vertices[2] = z * n_xy + (y + 1) * n_x + x;
2770 cells[c].vertices[3] = z * n_xy + (y + 1) * n_x + x + 1;
2771 cells[c].vertices[4] = (z + 1) * n_xy + y * n_x + x;
2772 cells[c].vertices[5] = (z + 1) * n_xy + y * n_x + x + 1;
2773 cells[c].vertices[6] = (z + 1) * n_xy + (y + 1) * n_x + x;
2774 cells[c].vertices[7] =
2775 (z + 1) * n_xy + (y + 1) * n_x + x + 1;
2776 cells[c].material_id = 0;
2785 tria.create_triangulation(points, cells,
SubCellData());
2798 *std::min_element(step_sizes[0].
begin(), step_sizes[0].
end());
2799 for (
unsigned int i = 1; i < dim; ++i)
2801 *std::min_element(step_sizes[i].
begin(),
2802 step_sizes[i].
end()));
2803 const double epsilon = 0.01 * min_size;
2807 colorize_subdivided_hyper_rectangle(tria, p1, p2,
epsilon);
2816 const std::vector<std::vector<double>> &spacing,
2828 for (
unsigned int i = 0; i <
n_cells; i++)
2831 delta =
std::min(delta, spacing[0][i]);
2835 std::vector<Point<1>> points;
2837 for (
unsigned int x = 0; x <=
n_cells; ++x)
2839 points.emplace_back(ax);
2841 ax += spacing[0][x];
2844 unsigned int n_val_cells = 0;
2845 for (
unsigned int i = 0; i <
n_cells; i++)
2849 std::vector<CellData<1>> cells(n_val_cells);
2850 unsigned int id = 0;
2851 for (
unsigned int x = 0; x <
n_cells; ++x)
2854 cells[id].vertices[0] = x;
2855 cells[id].vertices[1] = x + 1;
2874 const std::vector<std::vector<double>> &spacing,
2881 std::vector<unsigned int> repetitions(2);
2884 for (
unsigned int i = 0; i < 2; i++)
2886 repetitions[i] = spacing[i].size();
2888 for (
unsigned int j = 0; j < repetitions[i]; j++)
2891 delta =
std::min(delta, spacing[i][j]);
2898 std::vector<Point<2>> points;
2900 for (
unsigned int y = 0; y <= repetitions[1]; ++y)
2903 for (
unsigned int x = 0; x <= repetitions[0]; ++x)
2905 points.emplace_back(ax, ay);
2906 if (x < repetitions[0])
2907 ax += spacing[0][x];
2909 if (y < repetitions[1])
2910 ay += spacing[1][y];
2914 unsigned int n_val_cells = 0;
2915 for (
unsigned int i = 0; i <
material_id.size(0); i++)
2916 for (
unsigned int j = 0; j <
material_id.size(1); j++)
2920 std::vector<CellData<2>> cells(n_val_cells);
2921 unsigned int id = 0;
2922 for (
unsigned int y = 0; y < repetitions[1]; ++y)
2923 for (
unsigned int x = 0; x < repetitions[0]; ++x)
2926 cells[id].vertices[0] = y * (repetitions[0] + 1) + x;
2927 cells[id].vertices[1] = y * (repetitions[0] + 1) + x + 1;
2928 cells[id].vertices[2] = (y + 1) * (repetitions[0] + 1) + x;
2929 cells[id].vertices[3] = (y + 1) * (repetitions[0] + 1) + x + 1;
2943 double eps = 0.01 * delta;
2945 for (; cell != endc; ++cell)
2947 Point<2> cell_center = cell->center();
2949 if (cell->face(f)->boundary_id() == 0)
2951 Point<2> face_center = cell->face(f)->center();
2952 for (
unsigned int i = 0; i < 2; ++i)
2954 if (face_center[i] < cell_center[i] -
eps)
2955 cell->face(f)->set_boundary_id(i * 2);
2956 if (face_center[i] > cell_center[i] +
eps)
2957 cell->face(f)->set_boundary_id(i * 2 + 1);
2968 const std::vector<std::vector<double>> &spacing,
2973 const unsigned int dim = 3;
2977 std::vector<unsigned int> repetitions(dim);
2980 for (
unsigned int i = 0; i < dim; i++)
2982 repetitions[i] = spacing[i].size();
2984 for (
unsigned int j = 0; j < repetitions[i]; j++)
2987 delta =
std::min(delta, spacing[i][j]);
2994 std::vector<Point<dim>> points;
2996 for (
unsigned int z = 0; z <= repetitions[2]; ++z)
2999 for (
unsigned int y = 0; y <= repetitions[1]; ++y)
3002 for (
unsigned int x = 0; x <= repetitions[0]; ++x)
3004 points.emplace_back(ax, ay, az);
3005 if (x < repetitions[0])
3006 ax += spacing[0][x];
3008 if (y < repetitions[1])
3009 ay += spacing[1][y];
3011 if (z < repetitions[2])
3012 az += spacing[2][z];
3016 unsigned int n_val_cells = 0;
3017 for (
unsigned int i = 0; i <
material_id.size(0); i++)
3018 for (
unsigned int j = 0; j <
material_id.size(1); j++)
3019 for (
unsigned int k = 0; k <
material_id.size(2); k++)
3023 std::vector<CellData<dim>> cells(n_val_cells);
3024 unsigned int id = 0;
3025 const unsigned int n_x = (repetitions[0] + 1);
3026 const unsigned int n_xy = (repetitions[0] + 1) * (repetitions[1] + 1);
3027 for (
unsigned int z = 0; z < repetitions[2]; ++z)
3028 for (
unsigned int y = 0; y < repetitions[1]; ++y)
3029 for (
unsigned int x = 0; x < repetitions[0]; ++x)
3032 cells[id].vertices[0] = z * n_xy + y * n_x + x;
3033 cells[id].vertices[1] = z * n_xy + y * n_x + x + 1;
3034 cells[id].vertices[2] = z * n_xy + (y + 1) * n_x + x;
3035 cells[id].vertices[3] = z * n_xy + (y + 1) * n_x + x + 1;
3036 cells[id].vertices[4] = (z + 1) * n_xy + y * n_x + x;
3037 cells[id].vertices[5] = (z + 1) * n_xy + y * n_x + x + 1;
3038 cells[id].vertices[6] = (z + 1) * n_xy + (y + 1) * n_x + x;
3039 cells[id].vertices[7] = (z + 1) * n_xy + (y + 1) * n_x + x + 1;
3053 double eps = 0.01 * delta;
3056 for (; cell != endc; ++cell)
3060 if (cell->face(f)->boundary_id() == 0)
3062 Point<dim> face_center = cell->face(f)->center();
3063 for (
unsigned int i = 0; i < dim; ++i)
3065 if (face_center[i] < cell_center[i] -
eps)
3066 cell->face(f)->set_boundary_id(i * 2);
3067 if (face_center[i] > cell_center[i] +
eps)
3068 cell->face(f)->set_boundary_id(i * 2 + 1);
3075 template <
int dim,
int spacedim>
3078 const std::vector<unsigned int> &holes)
3087 for (
unsigned int d = 0;
d < dim; ++
d)
3094 std::vector<Point<spacedim>> delta(dim);
3095 unsigned int repetitions[dim];
3096 for (
unsigned int i = 0; i < dim; ++i)
3099 ExcMessage(
"At least one hole needed in each direction"));
3100 repetitions[i] = 2 * holes[i] + 1;
3101 delta[i][i] = (p2[i] - p1[i]);
3106 std::vector<Point<spacedim>> points;
3110 for (
unsigned int x = 0; x <= repetitions[0]; ++x)
3111 points.push_back(p1 + x * delta[0]);
3115 for (
unsigned int y = 0; y <= repetitions[1]; ++y)
3116 for (
unsigned int x = 0; x <= repetitions[0]; ++x)
3117 points.push_back(p1 + x * delta[0] + y * delta[1]);
3121 for (
unsigned int z = 0; z <= repetitions[2]; ++z)
3122 for (
unsigned int y = 0; y <= repetitions[1]; ++y)
3123 for (
unsigned int x = 0; x <= repetitions[0]; ++x)
3124 points.push_back(p1 + x * delta[0] + y * delta[1] +
3134 std::vector<CellData<dim>> cells;
3139 cells.resize(repetitions[1] * repetitions[0] - holes[1] * holes[0]);
3141 for (
unsigned int y = 0; y < repetitions[1]; ++y)
3142 for (
unsigned int x = 0; x < repetitions[0]; ++x)
3144 if ((x % 2 == 1) && (y % 2 == 1))
3147 cells[c].vertices[0] = y * (repetitions[0] + 1) + x;
3148 cells[c].vertices[1] = y * (repetitions[0] + 1) + x + 1;
3149 cells[c].vertices[2] = (y + 1) * (repetitions[0] + 1) + x;
3150 cells[c].vertices[3] = (y + 1) * (repetitions[0] + 1) + x + 1;
3151 cells[c].material_id = 0;
3159 const unsigned int n_x = (repetitions[0] + 1);
3160 const unsigned int n_xy =
3161 (repetitions[0] + 1) * (repetitions[1] + 1);
3163 cells.resize(repetitions[2] * repetitions[1] * repetitions[0]);
3166 for (
unsigned int z = 0; z < repetitions[2]; ++z)
3167 for (
unsigned int y = 0; y < repetitions[1]; ++y)
3168 for (
unsigned int x = 0; x < repetitions[0]; ++x)
3171 cells[c].vertices[0] = z * n_xy + y * n_x + x;
3172 cells[c].vertices[1] = z * n_xy + y * n_x + x + 1;
3173 cells[c].vertices[2] = z * n_xy + (y + 1) * n_x + x;
3174 cells[c].vertices[3] = z * n_xy + (y + 1) * n_x + x + 1;
3175 cells[c].vertices[4] = (z + 1) * n_xy + y * n_x + x;
3176 cells[c].vertices[5] = (z + 1) * n_xy + y * n_x + x + 1;
3177 cells[c].vertices[6] = (z + 1) * n_xy + (y + 1) * n_x + x;
3178 cells[c].vertices[7] =
3179 (z + 1) * n_xy + (y + 1) * n_x + x + 1;
3180 cells[c].material_id = 0;
3207 const unsigned int ,
3218 const unsigned int ,
3230 bool inline point_in_2d_box(
const Point<2> &p,
3232 const double radius)
3234 return (std::abs(p[0] - c[0]) < radius) &&
3243 template <
int dim,
int spacedim>
3248 for (
const auto &cell :
triangulation.active_cell_iterators())
3249 for (
unsigned int n = 0; n < GeometryInfo<dim>::lines_per_cell; ++n)
3250 length =
std::min(length, cell->line(n)->diameter());
3259 const double inner_radius,
3260 const double outer_radius,
3261 const double pad_bottom,
3262 const double pad_top,
3263 const double pad_left,
3264 const double pad_right,
3269 const unsigned int ,
3272 const bool with_padding =
3273 pad_bottom > 0 || pad_top > 0 || pad_left > 0 || pad_right > 0;
3285 for (
unsigned int n = 0; n < GeometryInfo<2>::lines_per_cell; ++n)
3286 length =
std::min(length, cell->line(n)->diameter());
3292 Triangulation<2> &cylinder_tria = with_padding ? cylinder_tria_maybe : tria;
3302 cell->set_manifold_id(tfi_manifold_id);
3304 const Point<2> bl(-outer_radius - pad_left, -outer_radius - pad_bottom);
3305 const Point<2> tr(outer_radius + pad_right, outer_radius + pad_top);
3311 auto add_sizes = [](std::vector<double> &step_sizes,
3312 const double padding,
3313 const double h) ->
void {
3316 const auto rounded =
3317 static_cast<unsigned int>(std::round(padding / h));
3320 const unsigned int num = (padding > 0. && rounded == 0) ? 1 : rounded;
3321 for (
unsigned int i = 0; i < num; ++i)
3322 step_sizes.push_back(padding / num);
3325 std::vector<std::vector<double>> step_sizes(2);
3328 add_sizes(step_sizes[0], pad_left, outer_radius);
3330 step_sizes[0].push_back(outer_radius);
3331 step_sizes[0].push_back(outer_radius);
3333 add_sizes(step_sizes[0], pad_right, outer_radius);
3336 add_sizes(step_sizes[1], pad_bottom, outer_radius);
3338 step_sizes[1].push_back(outer_radius);
3339 step_sizes[1].push_back(outer_radius);
3341 add_sizes(step_sizes[1], pad_top, outer_radius);
3346 bulk_tria, step_sizes, bl, tr,
colorize);
3349 std::set<Triangulation<2>::active_cell_iterator> cells_to_remove;
3351 if (internal::point_in_2d_box(cell->center(),
center, outer_radius))
3352 cells_to_remove.insert(cell);
3356 bulk_tria, cells_to_remove, tria_without_cylinder);
3358 const double tolerance =
3359 std::min(min_line_length(tria_without_cylinder),
3360 min_line_length(cylinder_tria)) /
3374 if (cell->manifold_id() == tfi_manifold_id)
3378 const auto &face = cell->face(face_n);
3379 if (face->at_boundary() &&
3380 internal::point_in_2d_box(face->center(),
3383 face->set_manifold_id(polar_manifold_id);
3385 face->set_manifold_id(tfi_manifold_id);
3396 static constexpr
double tol =
3402 const auto face = cell->face(face_n);
3403 if (face->at_boundary())
3407 if (std::abs(
center[0] - bl[0]) < tol * std::abs(bl[0]))
3408 face->set_boundary_id(0);
3410 else if (std::abs(
center[0] - tr[0]) < tol * std::abs(tr[0]))
3411 face->set_boundary_id(1);
3413 else if (std::abs(
center[1] - bl[1]) < tol * std::abs(bl[1]))
3414 face->set_boundary_id(2);
3416 else if (std::abs(
center[1] - tr[1]) < tol * std::abs(tr[1]))
3417 face->set_boundary_id(3);
3421 Assert(cell->manifold_id() == tfi_manifold_id,
3423 face->set_boundary_id(4);
3442 const double inner_radius,
3443 const double outer_radius,
3444 const double pad_bottom,
3445 const double pad_top,
3446 const double pad_left,
3447 const double pad_right,
3452 const unsigned int n_slices,
3463 Point<2>(new_center[0], new_center[1]),
3483 tria.
set_manifold(polar_manifold_id, cylindrical_manifold);
3491 const double shell_region_width,
3492 const unsigned int n_shells,
3493 const double skewness,
3496 Assert(0.0 <= shell_region_width && shell_region_width < 0.05,
3497 ExcMessage(
"The width of the shell region must be less than 0.05 "
3498 "(and preferably close to 0.03)"));
3532 std::set<Triangulation<2>::active_cell_iterator> cells_to_remove;
3536 if ((cell->center() -
Point<2>(0.2, 0.2)).norm() < 0.15)
3537 cells_to_remove.insert(cell);
3541 for (
const unsigned int vertex_n :
3543 if (cell->vertex(vertex_n) ==
Point<2>())
3547 cylinder_triangulation_offset =
3548 2.0 * (cell->vertex(3) -
Point<2>());
3555 bulk_tria, cells_to_remove, tria_without_cylinder);
3562 0.05 + shell_region_width,
3570 if (std::abs(cell->vertex(vertex_n)[0] - -0.41 / 4.0) < 1
e-10)
3571 cell->vertex(vertex_n)[0] = -0.1;
3572 else if (std::abs(cell->vertex(vertex_n)[0] - 0.41 / 4.0) < 1
e-10)
3573 cell->vertex(vertex_n)[0] = 0.1;
3579 cell->set_manifold_id(tfi_manifold_id);
3581 if (!cell->face(face_n)->at_boundary())
3582 cell->face(face_n)->set_manifold_id(tfi_manifold_id);
3584 if (0.0 < shell_region_width)
3587 ExcMessage(
"If the shell region has positive width then "
3588 "there must be at least one shell."));
3593 0.05 + shell_region_width,
3600 const double vertex_tolerance =
3601 std::min(internal::minimal_vertex_distance(shell_tria),
3602 internal::minimal_vertex_distance(cylinder_tria)) *
3608 shell_tria, cylinder_tria, temp, vertex_tolerance,
true);
3609 cylinder_tria = std::move(temp);
3615 const double vertex_tolerance =
3616 std::min(internal::minimal_vertex_distance(tria_without_cylinder),
3617 internal::minimal_vertex_distance(cylinder_tria)) /
3620 tria_without_cylinder, cylinder_tria, tria, vertex_tolerance,
true);
3633 const double shift =
3634 std::min(0.125 + shell_region_width * 0.5, 0.1 * 4. / 3.);
3637 if (cell->vertex(v).distance(
Point<2>(0.1, 0.205)) < 1
e-10)
3639 else if (cell->vertex(v).distance(
Point<2>(0.3, 0.205)) < 1
e-10)
3641 else if (cell->vertex(v).distance(
Point<2>(0.2, 0.1025)) < 1
e-10)
3643 else if (cell->vertex(v).distance(
Point<2>(0.2, 0.3075)) < 1
e-10)
3650 if (cell->manifold_id() == polar_manifold_id)
3656 if (cell->manifold_id() != polar_manifold_id &&
3657 cell->manifold_id() != tfi_manifold_id)
3662 std::vector<Point<2> *> cylinder_pointers;
3664 if (face->manifold_id() == polar_manifold_id)
3666 cylinder_pointers.push_back(&face->vertex(0));
3667 cylinder_pointers.push_back(&face->vertex(1));
3670 std::sort(cylinder_pointers.begin(), cylinder_pointers.end());
3671 cylinder_pointers.erase(std::unique(cylinder_pointers.begin(),
3672 cylinder_pointers.end()),
3673 cylinder_pointers.end());
3677 for (
const Point<2> *
const ptr : cylinder_pointers)
3681 for (
Point<2> *
const ptr : cylinder_pointers)
3693 if (face->at_boundary())
3697 if (std::abs(
center[0] - 0.0) < 1
e-10)
3698 face->set_boundary_id(0);
3700 else if (std::abs(
center[0] - 2.2) < 1
e-10)
3701 face->set_boundary_id(1);
3703 else if (face->manifold_id() == polar_manifold_id)
3704 face->set_boundary_id(2);
3709 std::abs(
center[1] - 0.41) < 1.0
e-10,
3711 face->set_boundary_id(3);
3720 const double shell_region_width,
3721 const unsigned int n_shells,
3722 const double skewness,
3727 tria_2, shell_region_width, n_shells, skewness,
colorize);
3743 tria.
set_manifold(cylindrical_manifold_id, cylindrical_manifold);
3751 if (face->boundary_id() == 4 || face->boundary_id() == 5)
3752 face->set_boundary_id(3);
3757 template <
int dim,
int spacedim>
3760 const std::vector<unsigned int> &sizes,
3770 for (
unsigned int d = 0;
d < dim; ++
d)
3773 std::vector<Point<spacedim>> points;
3778 std::vector<CellData<dim>> cells(
n_cells);
3783 for (
unsigned int d = 0;
d < dim; ++
d)
3784 p(
d) = 0.5 * dimensions[
d] *
3787 points.push_back(p);
3788 cells[0].vertices[i] = i;
3790 cells[0].material_id = 0;
3793 unsigned int cell_index = 1;
3801 for (
unsigned int j = 0; j < sizes[face]; ++j, ++cell_index)
3803 const unsigned int last_cell = (j == 0) ? 0
U : (cell_index - 1);
3805 for (
unsigned int v = 0; v < GeometryInfo<dim>::vertices_per_face;
3808 const unsigned int cellv =
3810 const unsigned int ocellv =
3813 cells[cell_index].vertices[ocellv] =
3814 cells[last_cell].vertices[cellv];
3817 cells[cell_index].vertices[cellv] = points.size();
3822 points.push_back(p);
3824 cells[cell_index].material_id = (
colorize) ? (face + 1
U) : 0
U;
3949 const double thickness,
3953 ExcMessage(
"Invalid left-to-right bounds of enclosed hypercube"));
3955 std::vector<Point<2>>
vertices(16);
3957 coords[0] = left - thickness;
3960 coords[3] = right + thickness;
3963 for (
const double y : coords)
3964 for (
const double x : coords)
3969 std::vector<CellData<2>> cells(9);
3971 for (
unsigned int i0 = 0; i0 < 3; ++i0)
3972 for (
unsigned int i1 = 0; i1 < 3; ++i1)
3974 cells[k].vertices[0] = i1 + 4 * i0;
3975 cells[k].vertices[1] = i1 + 4 * i0 + 1;
3976 cells[k].vertices[2] = i1 + 4 * i0 + 4;
3977 cells[k].vertices[3] = i1 + 4 * i0 + 5;
3979 cells[k].material_id = materials[k];
3996 const double rl2 = (right + left) / 2;
4007 const int cell_vertices[4][4] = {{0, 1, 3, 2},
4012 for (
unsigned int i = 0; i < 4; ++i)
4014 for (
unsigned int j = 0; j < 4; ++j)
4015 cells[i].
vertices[j] = cell_vertices[i][j];
4016 cells[i].material_id = 0;
4026 cell->face(1)->set_boundary_id(1);
4028 cell->face(0)->set_boundary_id(2);
4036 const double radius_0,
4037 const double radius_1,
4038 const double half_length)
4042 vertices_tmp[0] =
Point<2>(-half_length, -radius_0);
4043 vertices_tmp[1] =
Point<2>(half_length, -radius_1);
4044 vertices_tmp[2] =
Point<2>(-half_length, radius_0);
4045 vertices_tmp[3] =
Point<2>(half_length, radius_1);
4052 cell_vertices[0][i] = i;
4057 cells[0].vertices[i] = cell_vertices[0][i];
4059 cells[0].material_id = 0;
4064 cell->face(0)->set_boundary_id(1);
4065 cell->face(1)->set_boundary_id(2);
4067 for (
unsigned int i = 2; i < 4; ++i)
4068 cell->face(i)->set_boundary_id(0);
4088 const int cell_vertices[3][4] = {{0, 1, 3, 4}, {1, 2, 4, 5}, {3, 4, 6, 7}};
4092 for (
unsigned int i = 0; i < 3; ++i)
4094 for (
unsigned int j = 0; j < 4; ++j)
4095 cells[i].
vertices[j] = cell_vertices[i][j];
4096 cells[i].material_id = 0;
4108 cell->face(0)->set_boundary_id(0);
4109 cell->face(2)->set_boundary_id(1);
4112 cell->face(1)->set_boundary_id(2);
4113 cell->face(2)->set_boundary_id(1);
4114 cell->face(3)->set_boundary_id(3);
4117 cell->face(0)->set_boundary_id(0);
4118 cell->face(1)->set_boundary_id(4);
4119 cell->face(3)->set_boundary_id(5);
4125 template <
int dim,
int spacedim>
4128 const std::vector<unsigned int> &repetitions,
4131 const std::vector<int> & n_cells_to_remove)
4137 for (
unsigned int d = 0;
d < dim; ++
d)
4140 ExcMessage(
"Attempting to cut away too many cells."));
4150 std::array<double, dim> h;
4152 for (
unsigned int d = 0;
d < dim; ++
d)
4155 h[
d] = (top_right[
d] - bottom_left[
d]) / repetitions[
d];
4157 if (n_cells_to_remove[
d] >= 0)
4161 h[
d] *
std::fabs(n_cells_to_remove[
d]) + bottom_left[
d];
4166 cut_step[
d] = top_right[
d] - h[
d] *
std::fabs(n_cells_to_remove[
d]);
4172 std::set<typename Triangulation<dim, spacedim>::active_cell_iterator>
4177 std::inserter(cells_to_remove, cells_to_remove.end()),
4181 for (unsigned int d = 0; d < dim; ++d)
4182 if ((n_cells_to_remove[d] > 0 && cell->center()[d] >= cut_step[d]) ||
4183 (n_cells_to_remove[d] < 0 && cell->center()[d] <= cut_step[d]))
4200 const double radius,
4201 const bool internal_manifolds)
4206 const double a = 1. / (1 +
std::sqrt(2.0));
4217 const int cell_vertices[5][4] = {
4218 {0, 1, 2, 3}, {0, 2, 6, 4}, {2, 3, 4, 5}, {1, 7, 3, 5}, {6, 4, 7, 5}};
4222 for (
unsigned int i = 0; i < 5; ++i)
4224 for (
unsigned int j = 0; j < 4; ++j)
4225 cells[i].
vertices[j] = cell_vertices[i][j];
4226 cells[i].material_id = 0;
4236 if (internal_manifolds)
4245 const double inner_radius,
4246 const double outer_radius,
4250 Assert((inner_radius > 0) && (inner_radius < outer_radius),
4264 const unsigned int N =
4265 (
n_cells == 0 ?
static_cast<unsigned int>(
4266 std::ceil((2 * pi * (outer_radius + inner_radius) / 2) /
4267 (outer_radius - inner_radius))) :
4277 for (
unsigned int i = 0; i <
N; ++i)
4280 Point<2>(std::cos(2 * pi * i /
N), std::sin(2 * pi * i /
N)) *
4290 for (
unsigned int i = 0; i <
N; ++i)
4292 cells[i].vertices[0] = i;
4293 cells[i].vertices[1] = (i + 1) %
N;
4294 cells[i].vertices[2] =
N + i;
4295 cells[i].vertices[3] =
N + ((i + 1) %
N);
4297 cells[i].material_id = 0;
4303 colorize_hyper_shell(tria,
center, inner_radius, outer_radius);
4316 const double inner_radius,
4317 const double outer_radius,
4321 tria, outer_center, inner_radius, outer_radius,
n_cells,
true);
4325 outer_radius - inner_radius > outer_center.
distance(inner_center),
4327 "The inner radius is greater than or equal to the outer radius plus eccentricity."));
4331 std::set<Point<dim> *> vertices_to_move;
4334 if (face->boundary_id() == 0)
4335 for (
unsigned int v = 0; v < GeometryInfo<dim>::vertices_per_face; ++v)
4336 vertices_to_move.insert(&face->vertex(v));
4338 const auto shift = inner_center - outer_center;
4339 for (
const auto &p : vertices_to_move)
4366 const double radius,
4367 const double half_length)
4369 Point<2> p1(-half_length, -radius);
4378 switch (f->boundary_id())
4381 f->set_boundary_id(1);
4384 f->set_boundary_id(2);
4387 f->set_boundary_id(0);
4412 const double radius)
4414 const unsigned int dim = 2;
4428 const int cell_vertices[3][4] = {{0, 2, 3, 4}, {1, 6, 2, 4}, {5, 3, 6, 4}};
4432 for (
unsigned int i = 0; i < 3; ++i)
4434 for (
unsigned int j = 0; j < 4; ++j)
4435 cells[i].
vertices[j] = cell_vertices[i][j];
4436 cells[i].material_id = 0;
4453 if (cell->face(i)->boundary_id() ==
4459 if (cell->face(i)->center()(0) < p(0) + 1.
e-5 * radius ||
4460 cell->face(i)->center()(1) < p(1) + 1.
e-5 * radius)
4462 cell->face(i)->set_boundary_id(1);
4475 const double radius)
4480 const double a = 1. / (1 +
std::sqrt(2.0));
4491 const int cell_vertices[5][4] = {{0, 1, 2, 3},
4498 for (
unsigned int i = 0; i < 4; ++i)
4500 for (
unsigned int j = 0; j < 4; ++j)
4501 cells[i].
vertices[j] = cell_vertices[i][j];
4502 cells[i].material_id = 0;
4519 if (cell->face(i)->boundary_id() ==
4524 if (cell->face(i)->center()(0) < p(0) + 1.
e-5 * radius)
4526 cell->face(i)->set_boundary_id(1);
4541 const double inner_radius,
4542 const double outer_radius,
4546 Assert((inner_radius > 0) && (inner_radius < outer_radius),
4559 const unsigned int N =
4560 (
n_cells == 0 ?
static_cast<unsigned int>(
4561 std::ceil((pi * (outer_radius + inner_radius) / 2) /
4562 (outer_radius - inner_radius))) :
4571 std::vector<Point<2>>
vertices(2 * (
N + 1));
4572 for (
unsigned int i = 0; i <=
N; ++i)
4581 Point<2>(((i == 0) || (i ==
N) ? 0 : std::cos(pi * i /
N - pi / 2)),
4582 std::sin(pi * i /
N - pi / 2)) *
4593 for (
unsigned int i = 0; i <
N; ++i)
4595 cells[i].vertices[0] = i;
4596 cells[i].vertices[1] = (i + 1) % (
N + 1);
4597 cells[i].vertices[2] =
N + 1 + i;
4598 cells[i].vertices[3] =
N + 1 + ((i + 1) % (
N + 1));
4600 cells[i].material_id = 0;
4608 for (; cell != tria.
end(); ++cell)
4610 cell->face(2)->set_boundary_id(1);
4612 tria.
begin()->face(0)->set_boundary_id(3);
4614 tria.
last()->face(1)->set_boundary_id(2);
4624 const double inner_radius,
4625 const double outer_radius,
4629 Assert((inner_radius > 0) && (inner_radius < outer_radius),
4642 const unsigned int N =
4643 (
n_cells == 0 ?
static_cast<unsigned int>(
4644 std::ceil((pi * (outer_radius + inner_radius) / 4) /
4645 (outer_radius - inner_radius))) :
4654 std::vector<Point<2>>
vertices(2 * (
N + 1));
4655 for (
unsigned int i = 0; i <=
N; ++i)
4663 std::sin(pi * i /
N / 2)) *
4674 for (
unsigned int i = 0; i <
N; ++i)
4676 cells[i].vertices[0] = i;
4677 cells[i].vertices[1] = (i + 1) % (
N + 1);
4678 cells[i].vertices[2] =
N + 1 + i;
4679 cells[i].vertices[3] =
N + 1 + ((i + 1) % (
N + 1));
4681 cells[i].material_id = 0;
4689 for (; cell != tria.
end(); ++cell)
4691 cell->face(2)->set_boundary_id(1);
4693 tria.
begin()->face(0)->set_boundary_id(3);
4695 tria.
last()->face(1)->set_boundary_id(2);
4711 const double rl2 = (right + left) / 2;
4712 const double len = (right - left) / 2.;
4725 const int cell_vertices[4][8] = {{0, 1, 3, 2, 10, 11, 13, 12},
4726 {9, 4, 2, 5, 19, 14, 12, 15},
4727 {3, 2, 7, 6, 13, 12, 17, 16},
4728 {2, 5, 6, 8, 12, 15, 16, 18}};
4730 for (
unsigned int i = 0; i < 4; ++i)
4732 for (
unsigned int j = 0; j < 8; ++j)
4733 cells[i].
vertices[j] = cell_vertices[i][j];
4734 cells[i].material_id = 0;
4744 cell->face(1)->set_boundary_id(1);
4746 cell->face(0)->set_boundary_id(2);
4757 const double thickness,
4761 ExcMessage(
"Invalid left-to-right bounds of enclosed hypercube"));
4763 std::vector<Point<3>>
vertices(64);
4765 coords[0] = left - thickness;
4768 coords[3] = right + thickness;
4771 for (
const double z : coords)
4772 for (
const double y : coords)
4773 for (
const double x : coords)
4777 24, 26, 5, 4, 6, 1, 0,
4778 2, 9, 8, 10, 37, 36, 38,
4779 33, 32, 34, 41, 40, 42};
4781 std::vector<CellData<3>> cells(27);
4783 for (
unsigned int z = 0; z < 3; ++z)
4784 for (
unsigned int y = 0; y < 3; ++y)
4785 for (
unsigned int x = 0; x < 3; ++x)
4787 cells[k].vertices[0] = x + 4 * y + 16 * z;
4788 cells[k].vertices[1] = x + 4 * y + 16 * z + 1;
4789 cells[k].vertices[2] = x + 4 * y + 16 * z + 4;
4790 cells[k].vertices[3] = x + 4 * y + 16 * z + 5;
4791 cells[k].vertices[4] = x + 4 * y + 16 * z + 16;
4792 cells[k].vertices[5] = x + 4 * y + 16 * z + 17;
4793 cells[k].vertices[6] = x + 4 * y + 16 * z + 20;
4794 cells[k].vertices[7] = x + 4 * y + 16 * z + 21;
4796 cells[k].material_id = materials[k];
4808 const double radius_0,
4809 const double radius_1,
4810 const double half_length)
4813 ExcMessage(
"The output triangulation object needs to be empty."));
4818 const auto n_slices = 1 +
static_cast<unsigned int>(
std::ceil(
4819 half_length /
std::max(radius_0, radius_1)));
4832 auto shift_radii = [=](
const Point<3> &p) {
4833 const double slope = (radius_1 / radius_0 - 1.0) / (2.0 * half_length);
4834 const double factor = slope * (p[0] - -half_length) + 1.0;
4835 return Point<3>(p[0], factor * p[1], factor * p[2]);
4841 for (
const auto &face :
triangulation.active_face_iterators())
4842 if (face->at_boundary())
4844 if (std::abs(face->center()[0] - -half_length) < 1
e-8 * half_length)
4845 face->set_boundary_id(1);
4846 else if (std::abs(face->center()[0] - half_length) <
4848 face->set_boundary_id(2);
4850 face->set_all_manifold_ids(0);
4897 const int cell_vertices[7][8] = {{0, 1, 9, 10, 3, 4, 12, 13},
4898 {1, 2, 10, 11, 4, 5, 13, 14},
4899 {3, 4, 12, 13, 6, 7, 15, 16},
4900 {4, 5, 13, 14, 7, 8, 16, 17},
4901 {9, 10, 18, 19, 12, 13, 21, 22},
4902 {10, 11, 19, 20, 13, 14, 22, 23},
4903 {12, 13, 21, 22, 15, 16, 24, 25}};
4907 for (
unsigned int i = 0; i < 7; ++i)
4909 for (
unsigned int j = 0; j < 8; ++j)
4910 cells[i].
vertices[j] = cell_vertices[i][j];
4911 cells[i].material_id = 0;
4931 const double radius,
4932 const bool internal_manifold)
4938 const unsigned int n_vertices = 16;
4964 const unsigned int n_cells = 7;
4965 const int cell_vertices[
n_cells][8] = {
4966 {0, 1, 4, 5, 3, 2, 7, 6},
4967 {8, 9, 12, 13, 0, 1, 4, 5},
4968 {9, 13, 1, 5, 10, 14, 2, 6},
4969 {11, 10, 3, 2, 15, 14, 7, 6},
4970 {8, 0, 12, 4, 11, 3, 15, 7},
4971 {8, 9, 0, 1, 11, 10, 3, 2},
4972 {12, 4, 13, 5, 15, 7, 14, 6}};
4976 for (
unsigned int i = 0; i <
n_cells; ++i)
4979 cells[i].vertices[j] = cell_vertices[i][j];
4980 cells[i].material_id = 0;
4990 if (internal_manifold)
4996 template <
int spacedim>
4999 const double radius)
5003 std::set<types::boundary_id> boundary_ids;
5004 boundary_ids.insert(0);
5015 const double radius,
5016 const double half_length)
5051 const double h = vertex(1);
5052 vertex(1) = -vertex(0);
5056 int cell_vertices[10][8] = {{0, 1, 8, 9, 2, 3, 10, 11},
5057 {0, 2, 8, 10, 6, 4, 14, 12},
5058 {2, 3, 10, 11, 4, 5, 12, 13},
5059 {1, 7, 9, 15, 3, 5, 11, 13},
5060 {6, 4, 14, 12, 7, 5, 15, 13}};
5061 for (
unsigned int i = 0; i < 5; ++i)
5062 for (
unsigned int j = 0; j < 8; ++j)
5063 cell_vertices[i + 5][j] = cell_vertices[i][j] + 8;
5065 std::vector<CellData<3>> cells(10,
CellData<3>());
5067 for (
unsigned int i = 0; i < 10; ++i)
5069 for (
unsigned int j = 0; j < 8; ++j)
5070 cells[i].
vertices[j] = cell_vertices[i][j];
5071 cells[i].material_id = 0;
5094 for (; cell !=
end; ++cell)
5096 if (cell->at_boundary(i))
5098 if (cell->face(i)->center()(0) > half_length - 1.e-5)
5100 cell->face(i)->set_boundary_id(2);
5103 for (
unsigned int e = 0; e < GeometryInfo<3>::lines_per_face;
5105 if ((
std::fabs(cell->face(i)->line(
e)->vertex(0)[1]) == a) ||
5106 (
std::fabs(cell->face(i)->line(
e)->vertex(0)[2]) == a) ||
5107 (
std::fabs(cell->face(i)->line(
e)->vertex(1)[1]) == a) ||
5108 (
std::fabs(cell->face(i)->line(
e)->vertex(1)[2]) == a))
5110 cell->face(i)->line(
e)->set_boundary_id(2);
5111 cell->face(i)->line(
e)->set_manifold_id(
5115 else if (cell->face(i)->center()(0) < -half_length + 1.e-5)
5117 cell->face(i)->set_boundary_id(1);
5120 for (
unsigned int e = 0; e < GeometryInfo<3>::lines_per_face;
5122 if ((
std::fabs(cell->face(i)->line(
e)->vertex(0)[1]) == a) ||
5123 (
std::fabs(cell->face(i)->line(
e)->vertex(0)[2]) == a) ||
5124 (
std::fabs(cell->face(i)->line(
e)->vertex(1)[1]) == a) ||
5125 (
std::fabs(cell->face(i)->line(
e)->vertex(1)[2]) == a))
5127 cell->face(i)->line(
e)->set_boundary_id(1);
5128 cell->face(i)->line(
e)->set_manifold_id(
5140 const double radius)
5142 const unsigned int dim = 3;
5150 const double a = 0.528;
5151 const double b = 0.4533;
5152 const double c = 0.3752;
5169 const int cell_vertices[4][8] = {{0, 2, 3, 4, 7, 9, 10, 11},
5170 {1, 6, 2, 4, 8, 13, 9, 11},
5171 {5, 3, 6, 4, 12, 10, 13, 11},
5172 {7, 9, 10, 11, 14, 8, 12, 13}};
5176 for (
unsigned int i = 0; i < 4; ++i)
5178 for (
unsigned int j = 0; j < 8; ++j)
5179 cells[i].
vertices[j] = cell_vertices[i][j];
5180 cells[i].material_id = 0;
5196 if (cell->face(i)->boundary_id() ==
5201 if (cell->face(i)->center()(0) <
center(0) + 1.
e-5 * radius ||
5202 cell->face(i)->center()(1) <
center(1) + 1.
e-5 * radius ||
5203 cell->face(i)->center()(2) <
center(2) + 1.
e-5 * radius)
5205 cell->face(i)->set_boundary_id(1);
5209 for (
unsigned int j = 0; j < GeometryInfo<3>::lines_per_face;
5212 const Point<3> line_vertices[2] = {
5213 cell->face(i)->line(j)->vertex(0),
5214 cell->face(i)->line(j)->vertex(1)};
5220 cell->face(i)->line(j)->set_boundary_id(1);
5221 cell->face(i)->line(j)->set_manifold_id(
5238 const double radius)
5244 const double b = a / 2.0;
5245 const double c =
d / 2.0;
5247 const double hb = radius *
std::sqrt(3.0) / 4.0;
5248 const double hc = radius *
std::sqrt(3.0) / 2.0;
5270 int cell_vertices[6][8] = {{0, 1, 8, 9, 2, 3, 10, 11},
5271 {0, 2, 8, 10, 6, 4, 14, 12},
5272 {2, 3, 10, 11, 4, 5, 12, 13},
5273 {1, 7, 9, 15, 3, 5, 11, 13},
5274 {6, 4, 14, 12, 7, 5, 15, 13},
5275 {8, 10, 9, 11, 14, 12, 15, 13}};
5279 for (
unsigned int i = 0; i < 6; ++i)
5281 for (
unsigned int j = 0; j < 8; ++j)
5282 cells[i].
vertices[j] = cell_vertices[i][j];
5283 cells[i].material_id = 0;
5305 if (!cell->at_boundary(i))
5311 if (cell->face(i)->center()(0) <
center(0) + 1.
e-5 * radius)
5313 cell->face(i)->set_boundary_id(1);
5315 for (
unsigned int j = 0; j < GeometryInfo<3>::lines_per_face;
5318 const Point<3> line_vertices[2] = {
5319 cell->face(i)->line(j)->vertex(0),
5320 cell->face(i)->line(j)->vertex(1)};
5326 cell->face(i)->line(j)->set_boundary_id(1);
5327 cell->face(i)->line(j)->set_manifold_id(
5344 const double radius)
5354 for (
unsigned int round = 0; round < dim; ++round)
5359 std::vector<Point<dim>> new_points(tria_copy.
n_vertices());
5361 for (
unsigned int v = 0; v < tria_copy.
n_vertices(); ++v)
5369 else if (round == 1)
5371 for (
unsigned int v = 0; v < tria_copy.
n_vertices(); ++v)
5380 else if (round == 2)
5381 for (
unsigned int v = 0; v < tria_copy.
n_vertices(); ++v)
5394 std::vector<CellData<dim>> cells;
5395 cells.reserve(tria_copy.
n_cells());
5400 data.
vertices[v] = cell->vertex_index(v);
5403 cells.push_back(data);
5411 if (round == dim - 1)
5421 if (cell->center().norm_square() > 0.4 * radius)
5422 cell->set_manifold_id(1);
5435 const double inner_radius,
5436 const double outer_radius,
5440 Assert((inner_radius > 0) && (inner_radius < outer_radius),
5443 unsigned int n_refinement_steps = 0;
5444 unsigned int n_cells_coarsened =
n_cells;
5446 while (n_cells_coarsened > 12 && n_cells_coarsened % 4 == 0)
5448 ++n_refinement_steps;
5449 n_cells_coarsened /= 4;
5452 (n_refinement_steps > 0 &&
5453 (n_cells_coarsened == 6 || n_cells_coarsened == 12)),
5454 ExcMessage(
"Invalid number of coarse mesh cells"));
5456 const unsigned int n = n_refinement_steps > 0 ?
5457 4 * n_cells_coarsened :
5460 const double irad = inner_radius /
std::sqrt(3.0);
5461 const double orad = outer_radius /
std::sqrt(3.0);
5463 std::vector<CellData<3>> cells;
5466 static const std::array<Point<3>, 8> hexahedron = {{{-1, -1, -1},
5480 for (
unsigned int i = 0; i < 8; ++i)
5481 vertices.push_back(p + hexahedron[i] * irad);
5482 for (
unsigned int i = 0; i < 8; ++i)
5483 vertices.push_back(p + hexahedron[i] * orad);
5485 const unsigned int n_cells = 6;
5486 const int cell_vertices[
n_cells][8] = {
5487 {8, 9, 10, 11, 0, 1, 2, 3},
5488 {9, 11, 1, 3, 13, 15, 5, 7},
5489 {12, 13, 4, 5, 14, 15, 6, 7},
5490 {8, 0, 10, 2, 12, 4, 14, 6},
5491 {8, 9, 0, 1, 12, 13, 4, 5},
5492 {10, 2, 11, 3, 14, 6, 15, 7}};
5496 for (
unsigned int i = 0; i <
n_cells; ++i)
5499 cells[i].vertices[j] = cell_vertices[i][j];
5500 cells[i].material_id = 0;
5512 static const std::array<Point<3>, 6> octahedron = {{{-1, 0, 0},
5519 for (
unsigned int i = 0; i < 8; ++i)
5520 vertices.push_back(p + hexahedron[i] * irad);
5521 for (
unsigned int i = 0; i < 6; ++i)
5522 vertices.push_back(p + octahedron[i] * inner_radius);
5523 for (
unsigned int i = 0; i < 8; ++i)
5524 vertices.push_back(p + hexahedron[i] * orad);
5525 for (
unsigned int i = 0; i < 6; ++i)
5526 vertices.push_back(p + octahedron[i] * outer_radius);
5528 const unsigned int n_cells = 12;
5529 const unsigned int rhombi[
n_cells][4] = {{10, 4, 0, 8},
5544 for (
unsigned int i = 0; i <
n_cells; ++i)
5546 for (
unsigned int j = 0; j < 4; ++j)
5548 cells[i].vertices[j] = rhombi[i][j];
5549 cells[i].vertices[j + 4] = rhombi[i][j] + 14;
5551 cells[i].material_id = 0;
5572 const unsigned int outer_radius_factor = 1 << n_refinement_steps;
5576 outer_radius_factor * outer_radius -
5577 (outer_radius_factor - 1) * inner_radius,
5579 for (
unsigned int r = 0; r < n_refinement_steps; ++r)
5582 std::set<Triangulation<3>::active_cell_iterator>
5589 unsigned int n_vertices_inside = 0;
5591 if ((cell->vertex(v) - p).norm_square() <
5592 inner_radius * inner_radius * (1 + 1
e-12))
5593 ++n_vertices_inside;
5594 if (n_vertices_inside < 4)
5595 cells_to_remove.insert(cell);
5600 if (r == n_refinement_steps - 1)
5610 tmp = std::move(
copy);
5624 hyper_shell(tmp, p, inner_radius, outer_radius, 12);
5639 colorize_hyper_shell(tria, p, inner_radius, outer_radius);
5650 const double inner_radius,
5651 const double outer_radius,
5652 const unsigned int ,
5655 Assert((inner_radius > 0) && (inner_radius < outer_radius),
5659 const double d = outer_radius /
std::sqrt(2.0);
5660 const double a = inner_radius /
std::sqrt(2.0);
5662 const double b = a / 2.0;
5663 const double c =
d / 2.0;
5665 const double hb = inner_radius *
std::sqrt(3.0) / 2.0;
5666 const double hc = outer_radius *
std::sqrt(3.0) / 2.0;
5688 int cell_vertices[5][8] = {{0, 1, 8, 9, 2, 3, 10, 11},
5689 {0, 2, 8, 10, 6, 4, 14, 12},
5690 {1, 7, 9, 15, 3, 5, 11, 13},
5691 {6, 4, 14, 12, 7, 5, 15, 13},
5692 {8, 10, 9, 11, 14, 12, 15, 13}};
5696 for (
unsigned int i = 0; i < 5; ++i)
5698 for (
unsigned int j = 0; j < 8; ++j)
5699 cells[i].
vertices[j] = cell_vertices[i][j];
5700 cells[i].material_id = 0;
5714 for (; cell != tria.
end(); ++cell)
5716 if (cell->at_boundary(i))
5717 cell->face(i)->set_all_boundary_ids(2);
5723 for (cell = tria.
begin(); cell != tria.
end(); ++cell)
5725 if (cell->at_boundary(i))
5729 const Point<3> face_center(face->center());
5730 if (std::abs(face_center(0) -
center(0)) >
5731 1.
e-6 * face_center.
norm())
5733 if (std::abs((face_center -
center).
norm() - inner_radius) <
5734 std::abs((face_center -
center).
norm() - outer_radius))
5735 face->set_all_boundary_ids(0);
5737 face->set_all_boundary_ids(1);
5750 const double inner_radius,
5751 const double outer_radius,
5752 const unsigned int n,
5755 Assert((inner_radius > 0) && (inner_radius < outer_radius),
5757 if (n == 0 || n == 3)
5759 const double a = inner_radius *
std::sqrt(2.0) / 2e0;
5760 const double b = outer_radius *
std::sqrt(2.0) / 2e0;
5761 const double c = a *
std::sqrt(3.0) / 2e0;
5763 const double e = outer_radius / 2e0;
5764 const double h = inner_radius / 2e0;
5783 const int cell_vertices[3][8] = {
5784 {0, 1, 3, 2, 4, 5, 7, 6},
5785 {1, 8, 2, 9, 5, 10, 6, 11},
5786 {4, 5, 7, 6, 12, 10, 13, 11},
5788 std::vector<CellData<3>> cells(3);
5790 for (
unsigned int i = 0; i < 3; ++i)
5792 for (
unsigned int j = 0; j < 8; ++j)
5793 cells[i].
vertices[j] = cell_vertices[i][j];
5794 cells[i].material_id = 0;
5807 colorize_quarter_hyper_shell(tria,
center, inner_radius, outer_radius);
5817 const double length,
5818 const double inner_radius,
5819 const double outer_radius,
5820 const unsigned int n_radial_cells,
5821 const unsigned int n_axial_cells)
5823 Assert((inner_radius > 0) && (inner_radius < outer_radius),
5837 const unsigned int N_r =
5838 (n_radial_cells == 0 ?
static_cast<unsigned int>(
std::ceil(
5839 (2 * pi * (outer_radius + inner_radius) / 2) /
5840 (outer_radius - inner_radius))) :
5842 const unsigned int N_z =
5843 (n_axial_cells == 0 ?
5845 length / (2 * pi * (outer_radius + inner_radius) / 2 / N_r))) :
5854 std::vector<Point<2>> vertices_2d(2 * N_r);
5855 for (
unsigned int i = 0; i < N_r; ++i)
5858 Point<2>(std::cos(2 * pi * i / N_r), std::sin(2 * pi * i / N_r)) *
5860 vertices_2d[i + N_r] = vertices_2d[i] * (inner_radius / outer_radius);
5863 std::vector<Point<3>> vertices_3d;
5864 vertices_3d.reserve(2 * N_r * (N_z + 1));
5865 for (
unsigned int j = 0; j <= N_z; ++j)
5866 for (
unsigned int i = 0; i < 2 * N_r; ++i)
5868 const Point<3> v(vertices_2d[i][0],
5871 vertices_3d.push_back(v);
5874 std::vector<CellData<3>> cells(N_r * N_z,
CellData<3>());
5876 for (
unsigned int j = 0; j < N_z; ++j)
5877 for (
unsigned int i = 0; i < N_r; ++i)
5879 cells[i + j * N_r].vertices[0] = i + (j + 1) * 2 * N_r;
5880 cells[i + j * N_r].vertices[1] = (i + 1) % N_r + (j + 1) * 2 * N_r;
5881 cells[i + j * N_r].vertices[2] = i + j * 2 * N_r;
5882 cells[i + j * N_r].vertices[3] = (i + 1) % N_r + j * 2 * N_r;
5884 cells[i + j * N_r].vertices[4] = N_r + i + (j + 1) * 2 * N_r;
5885 cells[i + j * N_r].vertices[5] =
5886 N_r + ((i + 1) % N_r) + (j + 1) * 2 * N_r;
5887 cells[i + j * N_r].vertices[6] = N_r + i + j * 2 * N_r;
5888 cells[i + j * N_r].vertices[7] = N_r + ((i + 1) % N_r) + j * 2 * N_r;
5890 cells[i + j * N_r].material_id = 0;
5900 template <
int dim,
int spacedim>
5905 const double duplicated_vertex_tolerance,
5906 const bool copy_manifold_ids)
5908 std::vector<Point<spacedim>>
vertices;
5909 std::vector<CellData<dim>> cells;
5912 unsigned int n_accumulated_vertices = 0;
5916 ExcMessage(
"The input triangulations must be non-empty "
5917 "and must not be refined."));
5919 std::vector<Point<spacedim>> tria_vertices;
5920 std::vector<CellData<dim>> tria_cells;
5922 std::tie(tria_vertices, tria_cells, tria_subcell_data) =
5926 tria_vertices.begin(),
5927 tria_vertices.end());
5930 for (
unsigned int &vertex_n : cell_data.vertices)
5931 vertex_n += n_accumulated_vertices;
5932 cells.push_back(cell_data);
5936 if (copy_manifold_ids)
5942 for (
unsigned int &vertex_n : line_data.
vertices)
5943 vertex_n += n_accumulated_vertices;
5953 for (
unsigned int &vertex_n : quad_data.
vertices)
5954 vertex_n += n_accumulated_vertices;
5965 std::vector<unsigned int> considered_vertices;
5969 considered_vertices,
5970 duplicated_vertex_tolerance);
5981 template <
int dim,
int spacedim>
5986 const double duplicated_vertex_tolerance,
5987 const bool copy_manifold_ids)
5990 if (triangulation_1.
n_cells() == 0)
5995 if (triangulation_2.
n_cells() == 0)
6002 duplicated_vertex_tolerance,
6031 template <
int structdim>
6035 static_assert(structdim == 1 || structdim == 2,
6036 "This function is only implemented for lines and "
6046 else if (structdim == 2)
6049 std::array<unsigned int, 4> renumbering;
6052 renumbering.begin());
6063 std::swap(renumbering[2], renumbering[3]);
6065 std::min_element(renumbering.begin(),
6069 std::swap(renumbering[2], renumbering[3]);
6077 if (renumbering[1] > renumbering[2])
6078 std::swap(renumbering[1], renumbering[2]);
6093 std::sort(subcell_data.begin(), subcell_data.end(), compare);
6098 auto left = subcell_data.begin();
6099 while (left != subcell_data.end())
6102 std::upper_bound(left, subcell_data.end(), *left, compare);
6105 if (left + 1 != right)
6106 for (
auto it = left; it != right; ++it)
6109 Assert(it->manifold_id == left->manifold_id,
6111 "In the process of grid generation a single "
6112 "line or quadrilateral has been assigned two "
6113 "different manifold ids. This can happen when "
6114 "a Triangulation is copied, e.g., via "
6115 "GridGenerator::replicate_triangulation() and "
6116 "not all external boundary faces have the same "
6117 "manifold id. Double check that all faces "
6118 "which you expect to be merged together have "
6119 "the same manifold id."));
6124 subcell_data.erase(std::unique(subcell_data.begin(), subcell_data.end()),
6125 subcell_data.end());
6131 template <
int dim,
int spacedim>
6134 const std::vector<unsigned int> & extents,
6139 for (
const auto &extent : extents)
6141 ExcMessage(
"The Triangulation must be copied at least one time in "
6142 "each coordinate dimension."));
6145 const auto &
min = bbox.get_boundary_points().first;
6146 const auto &
max = bbox.get_boundary_points().second;
6148 std::array<Tensor<1, spacedim>, dim> offsets;
6149 for (
unsigned int d = 0;
d < dim; ++
d)
6154 for (
unsigned int d = 0;
d < dim; ++
d)
6156 std::vector<Point<spacedim>> input_vertices;
6157 std::vector<CellData<dim>> input_cell_data;
6159 std::tie(input_vertices, input_cell_data, input_subcell_data) =
6161 std::vector<Point<spacedim>> output_vertices = input_vertices;
6162 std::vector<CellData<dim>> output_cell_data = input_cell_data;
6163 SubCellData output_subcell_data = input_subcell_data;
6165 for (
unsigned int k = 1; k < extents[
d]; ++k)
6167 const std::size_t vertex_offset = k * input_vertices.size();
6170 output_vertices.push_back(
point +
double(k) * offsets[
d]);
6174 output_cell_data.push_back(cell_data);
6175 for (
unsigned int &vertex : output_cell_data.back().vertices)
6176 vertex += vertex_offset;
6183 for (
unsigned int &vertex :
6185 vertex += vertex_offset;
6191 for (
unsigned int &vertex :
6193 vertex += vertex_offset;
6198 std::vector<unsigned int> boundary_vertices;
6202 output_subcell_data,
6223 tria_to_replicate.
clear();
6226 output_subcell_data);
6234 template <
int dim,
int spacedim>
6242 ExcMessage(
"The two input triangulations are not derived from "
6243 "the same coarse mesh as required."));
6246 &triangulation_1) ==
nullptr) &&
6249 &triangulation_2) ==
nullptr),
6250 ExcMessage(
"The source triangulations for this function must both "
6251 "be available entirely locally, and not be distributed "
6252 "triangulations."));
6269 for (
unsigned int iteration = 0; iteration < triangulation_2.
n_levels();
6275 bool any_cell_flagged =
false;
6277 if (intergrid_map[result_cell]->has_children())
6279 any_cell_flagged =
true;
6280 result_cell->set_refine_flag();
6283 if (any_cell_flagged ==
false)
6292 template <
int dim,
int spacedim>
6306 std::vector<CellData<dim>> cells;
6308 if (cells_to_remove.find(cell) == cells_to_remove.end())
6310 Assert(
static_cast<unsigned int>(cell->level()) ==
6311 input_triangulation.
n_levels() - 1,
6313 "Your input triangulation appears to have "
6314 "adaptively refined cells. This is not allowed. You can "
6315 "only call this function on a triangulation in which "
6316 "all cells are on the same refinement level."));
6320 this_cell.
vertices[v] = cell->vertex_index(v);
6322 cells.push_back(this_cell);
6328 std::vector<unsigned int> considered_vertices;
6332 considered_vertices);
6344 const unsigned int n_slices,
6345 const double height,
6347 const bool copy_manifold_ids,
6348 const std::vector<types::manifold_id> &manifold_priorities)
6352 "The input triangulation must be a coarse mesh, i.e., it must "
6353 "not have been refined."));
6355 ExcMessage(
"The output triangulation object needs to be empty."));
6357 ExcMessage(
"The given height for extrusion must be positive."));
6360 "The number of slices for extrusion must be at least 2."));
6362 const double delta_h = height / (n_slices - 1);
6363 std::vector<double> slices_z_values;
6364 for (
unsigned int i = 0; i < n_slices; ++i)
6365 slices_z_values.push_back(i * delta_h);
6367 input, slices_z_values, result, copy_manifold_ids, manifold_priorities);
6375 const unsigned int n_slices,
6376 const double height,
6378 const bool copy_manifold_ids,
6379 const std::vector<types::manifold_id> &manifold_priorities)
6385 (void)copy_manifold_ids;
6386 (void)manifold_priorities;
6390 "GridTools::extrude_triangulation() is only available "
6391 "for Triangulation<3, 3> as output triangulation."));
6399 const std::vector<double> & slice_coordinates,
6401 const bool copy_manifold_ids,
6402 const std::vector<types::manifold_id> &manifold_priorities)
6406 "The input triangulation must be a coarse mesh, i.e., it must "
6407 "not have been refined."));
6409 ExcMessage(
"The output triangulation object needs to be empty."));
6410 Assert(slice_coordinates.size() >= 2,
6412 "The number of slices for extrusion must be at least 2."));
6413 Assert(std::is_sorted(slice_coordinates.begin(), slice_coordinates.end()),
6414 ExcMessage(
"Slice z-coordinates should be in ascending order"));
6416 const auto priorities = [&]() -> std::vector<types::manifold_id> {
6420 if (0 < manifold_priorities.size())
6424 std::vector<types::manifold_id> sorted_manifold_priorities =
6425 manifold_priorities;
6426 std::sort(sorted_manifold_priorities.begin(),
6427 sorted_manifold_priorities.end());
6428 Assert(std::unique(sorted_manifold_priorities.begin(),
6429 sorted_manifold_priorities.end()) ==
6430 sorted_manifold_priorities.end(),
6432 "The given vector of manifold ids may not contain any "
6433 "duplicated entries."));
6434 std::vector<types::manifold_id> sorted_manifold_ids =
6436 std::sort(sorted_manifold_ids.begin(), sorted_manifold_ids.end());
6437 if (sorted_manifold_priorities != sorted_manifold_ids)
6439 std::ostringstream message;
6440 message <<
"The given triangulation has manifold ids {";
6444 message << sorted_manifold_ids.back() <<
"}, but \n"
6445 <<
" the given vector of manifold ids is {";
6450 << manifold_priorities.back() <<
"}.\n"
6451 <<
" These vectors should contain the same elements.\n";
6452 const std::string m = message.str();
6456 return manifold_priorities;
6460 std::vector<types::manifold_id> default_priorities =
6463 default_priorities.begin(),
6464 default_priorities.end(),
6466 return dynamic_cast<const TransfiniteInterpolationManifold<2, 2> *>(
6467 &input.get_manifold(id)) == nullptr;
6469 std::sort(default_priorities.begin(), first_tfi_it);
6470 std::sort(first_tfi_it, default_priorities.end());
6472 return default_priorities;
6475 const std::size_t n_slices = slice_coordinates.size();
6476 std::vector<Point<3>> points(n_slices * input.
n_vertices());
6477 std::vector<CellData<3>> cells;
6482 for (std::size_t slice_n = 0; slice_n < n_slices; ++slice_n)
6484 for (std::size_t vertex_n = 0; vertex_n < input.
n_vertices();
6488 points[slice_n * input.
n_vertices() + vertex_n] =
6489 Point<3>(vertex[0], vertex[1], slice_coordinates[slice_n]);
6497 for (std::size_t slice_n = 0; slice_n < n_slices - 1; ++slice_n)
6500 for (
const unsigned int vertex_n :
6504 cell->vertex_index(vertex_n) + slice_n * input.
n_vertices();
6507 cell->vertex_index(vertex_n) +
6512 if (copy_manifold_ids)
6514 cells.push_back(this_cell);
6529 if (face->at_boundary())
6531 if (copy_manifold_ids)
6533 for (std::size_t slice_n = 0; slice_n < n_slices - 1; ++slice_n)
6536 face->vertex_index(0) + slice_n * input.
n_vertices();
6538 face->vertex_index(1) + slice_n * input.
n_vertices();
6540 face->vertex_index(0) + (slice_n + 1) * input.
n_vertices();
6542 face->vertex_index(1) + (slice_n + 1) * input.
n_vertices();
6543 quads.push_back(quad);
6549 if (copy_manifold_ids)
6555 for (std::size_t slice_n = 1; slice_n < n_slices - 1; ++slice_n)
6558 cell->vertex_index(0) + slice_n * input.
n_vertices();
6560 cell->vertex_index(1) + slice_n * input.
n_vertices();
6562 cell->vertex_index(2) + slice_n * input.
n_vertices();
6564 cell->vertex_index(3) + slice_n * input.
n_vertices();
6565 quads.push_back(quad);
6576 "The input triangulation to this function is using boundary "
6577 "indicators in a range that do not allow using "
6578 "max_boundary_id+1 and max_boundary_id+2 as boundary "
6579 "indicators for the bottom and top faces of the "
6580 "extruded triangulation."));
6587 quad.
vertices[0] = cell->vertex_index(0);
6588 quad.
vertices[1] = cell->vertex_index(1);
6589 quad.
vertices[2] = cell->vertex_index(2);
6590 quad.
vertices[3] = cell->vertex_index(3);
6591 if (copy_manifold_ids)
6593 quads.push_back(quad);
6596 for (
unsigned int &vertex : quad.
vertices)
6597 vertex += (n_slices - 1) * input.
n_vertices();
6598 if (copy_manifold_ids)
6600 quads.push_back(quad);
6613 for (
auto manifold_id_it = priorities.rbegin();
6614 manifold_id_it != priorities.rend();
6617 if (face->manifold_id() == *manifold_id_it)
6618 for (
unsigned int line_n = 0;
6619 line_n < GeometryInfo<3>::lines_per_face;
6621 face->line(line_n)->set_manifold_id(*manifold_id_it);
6629 const std::vector<double> & slice_coordinates,
6631 const bool copy_manifold_ids,
6632 const std::vector<types::manifold_id> &manifold_priorities)
6635 (void)slice_coordinates;
6637 (void)copy_manifold_ids;
6638 (void)manifold_priorities;
6642 "GridTools::extrude_triangulation() is only available "
6643 "for Triangulation<3, 3> as output triangulation."));
6663 const double inner_radius,
6664 const double outer_radius,
6671 Assert(inner_radius < outer_radius,
6672 ExcMessage(
"outer_radius has to be bigger than inner_radius."));
6681 std::vector<bool> treated_vertices(
triangulation.n_vertices(),
false);
6682 for (; cell != endc; ++cell)
6685 if (cell->face(f)->at_boundary())
6687 for (
unsigned int v = 0; v < GeometryInfo<dim>::vertices_per_face;
6690 unsigned int vv = cell->face(f)->vertex_index(v);
6691 if (treated_vertices[vv] ==
false)
6693 treated_vertices[vv] =
true;
6697 cell->face(f)->vertex(v) =
6701 cell->face(f)->vertex(v) =
6705 cell->face(f)->vertex(v) =
6709 cell->face(f)->vertex(v) =
6719 double eps = 1
e-3 * outer_radius;
6721 for (; cell != endc; ++cell)
6724 if (cell->face(f)->at_boundary())
6726 double dx = cell->face(f)->center()(0) -
center(0);
6727 double dy = cell->face(f)->center()(1) -
center(1);
6730 if (std::abs(
dx + outer_radius) <
eps)
6731 cell->face(f)->set_boundary_id(0);
6732 else if (std::abs(
dx - outer_radius) <
eps)
6733 cell->face(f)->set_boundary_id(1);
6734 else if (std::abs(dy + outer_radius) <
eps)
6735 cell->face(f)->set_boundary_id(2);
6736 else if (std::abs(dy - outer_radius) <
eps)
6737 cell->face(f)->set_boundary_id(3);
6740 cell->face(f)->set_boundary_id(4);
6741 cell->face(f)->set_manifold_id(0);
6746 double d = (cell->face(f)->center() -
center).
norm();
6747 if (
d - inner_radius < 0)
6749 cell->face(f)->set_boundary_id(1);
6750 cell->face(f)->set_manifold_id(0);
6753 cell->face(f)->set_boundary_id(0);
6766 const double inner_radius,
6767 const double outer_radius,
6768 const unsigned int n_shells,
6769 const double skewness,
6776 Assert(inner_radius < outer_radius,
6777 ExcMessage(
"outer_radius has to be bigger than inner_radius."));
6781 std::vector<double> radii;
6782 radii.push_back(inner_radius);
6783 for (
unsigned int shell_n = 1; shell_n < n_shells; ++shell_n)
6784 if (skewness == 0.0)
6786 radii.push_back(inner_radius +
6787 (outer_radius - inner_radius) *
6788 (1.0 - (1.0 -
double(shell_n) / n_shells)));
6792 (outer_radius - inner_radius) *
6793 (1.0 -
std::tanh(skewness * (1.0 -
double(shell_n) / n_shells)) /
6795 radii.push_back(outer_radius);
6797 double grid_vertex_tolerance = 0.0;
6798 for (
unsigned int shell_n = 0; shell_n < radii.size() - 1; ++shell_n)
6805 n_cells == 0 ? (dim == 2 ? 8 : 12) :
6810 if (grid_vertex_tolerance == 0.0)
6811 grid_vertex_tolerance =
6812 0.5 * internal::minimal_vertex_distance(current_shell);
6819 grid_vertex_tolerance);
6831 constexpr
double radial_vertex_tolerance =
6833 auto assert_vertex_distance_within_tolerance =
6834 [
center, radial_vertex_tolerance](
6836 const double radius) {
6838 (void)radial_vertex_tolerance;
6841 for (
unsigned int vertex_n = 0;
6842 vertex_n < GeometryInfo<dim>::vertices_per_face;
6845 Assert(std::abs((face->vertex(vertex_n) -
center).norm() - radius) <
6846 (
center.
norm() + radius) * radial_vertex_tolerance,
6851 for (
const auto &cell :
triangulation.active_cell_iterators())
6854 auto face = cell->face(face_n);
6855 if (face->at_boundary())
6857 if (((face->vertex(0) -
center).norm() - inner_radius) <
6858 (
center.
norm() + inner_radius) * radial_vertex_tolerance)
6861 assert_vertex_distance_within_tolerance(face, inner_radius);
6862 face->set_all_boundary_ids(0);
6867 assert_vertex_distance_within_tolerance(face, outer_radius);
6868 face->set_all_boundary_ids(1);
6878 const double inner_radius,
6879 const double outer_radius,
6881 const unsigned int Nz,
6886 Assert(inner_radius < outer_radius,
6887 ExcMessage(
"outer_radius has to be bigger than inner_radius."));
6897 std::vector<bool> treated_vertices(
triangulation.n_vertices(),
false);
6898 for (; cell != endc; ++cell)
6901 if (cell->face(f)->at_boundary())
6903 for (
unsigned int v = 0; v < GeometryInfo<dim>::vertices_per_face;
6906 unsigned int vv = cell->face(f)->vertex_index(v);
6907 if (treated_vertices[vv] ==
false)
6909 treated_vertices[vv] =
true;
6910 for (
unsigned int i = 0; i <= Nz; ++i)
6912 double d = i *
L / Nz;
6913 switch (vv - i * 16)
6916 cell->face(f)->vertex(v) =
6920 cell->face(f)->vertex(v) =
6924 cell->face(f)->vertex(v) =
6928 cell->face(f)->vertex(v) =
6939 double eps = 1
e-3 * outer_radius;
6941 for (; cell != endc; ++cell)
6944 if (cell->face(f)->at_boundary())
6946 double dx = cell->face(f)->center()(0);
6947 double dy = cell->face(f)->center()(1);
6948 double dz = cell->face(f)->center()(2);
6952 if (std::abs(
dx + outer_radius) <
eps)
6953 cell->face(f)->set_boundary_id(0);
6955 else if (std::abs(
dx - outer_radius) <
eps)
6956 cell->face(f)->set_boundary_id(1);
6958 else if (std::abs(dy + outer_radius) <
eps)
6959 cell->face(f)->set_boundary_id(2);
6961 else if (std::abs(dy - outer_radius) <
eps)
6962 cell->face(f)->set_boundary_id(3);
6964 else if (std::abs(dz) <
eps)
6965 cell->face(f)->set_boundary_id(4);
6967 else if (std::abs(dz -
L) <
eps)
6968 cell->face(f)->set_boundary_id(5);
6972 cell->face(f)->set_all_boundary_ids(6);
6980 double d = c.
norm();
6981 if (
d - inner_radius < 0)
6983 cell->face(f)->set_all_boundary_ids(1);
6987 cell->face(f)->set_boundary_id(0);
6994 template <
int dim,
int spacedim1,
int spacedim2>
7007 "Cannot use this function on parallel::distributed::Triangulation."));
7009 std::vector<Point<spacedim2>> v;
7010 std::vector<CellData<dim>> cells;
7013 const unsigned int spacedim =
std::min(spacedim1, spacedim2);
7014 const std::vector<Point<spacedim1>> &in_vertices = in_tria.
get_vertices();
7016 v.resize(in_vertices.size());
7017 for (
unsigned int i = 0; i < in_vertices.size(); ++i)
7018 for (
unsigned int d = 0;
d < spacedim; ++
d)
7019 v[i][
d] = in_vertices[i][
d];
7024 endc = in_tria.
end();
7026 for (
unsigned int id = 0; cell != endc; ++cell, ++id)
7029 cells[id].vertices[i] = cell->vertex_index(i);
7030 cells[id].material_id = cell->material_id();
7031 cells[id].manifold_id = cell->manifold_id();
7047 for (; face != endf; ++face)
7048 if (face->at_boundary())
7050 for (
unsigned int i = 0;
7051 i < GeometryInfo<dim>::vertices_per_face;
7054 face->vertex_index(i);
7056 face->boundary_id();
7058 face->manifold_id();
7067 for (; face != endf; ++face)
7068 if (face->at_boundary())
7070 for (
unsigned int i = 0;
7071 i < GeometryInfo<dim>::vertices_per_face;
7074 face->vertex_index(i);
7076 face->boundary_id();
7078 face->manifold_id();
7093 template <
template <
int,
int>
class MeshType,
int dim,
int spacedim>
7095 std::map<
typename MeshType<dim - 1, spacedim>::cell_iterator,
7096 typename MeshType<dim, spacedim>::face_iterator>
7098 typename ExtractBoundaryMesh<MeshType, dim, spacedim>::return_type
7101 MeshType<dim - 1, spacedim> & surface_mesh,
7102 const std::set<types::boundary_id> &boundary_ids)
7106 &volume_mesh.get_triangulation()) ==
nullptr),
7115 const unsigned int boundary_dim = dim - 1;
7122 std::pair<typename MeshType<dim, spacedim>::face_iterator,
unsigned int>>
7123 temporary_mapping_level0;
7128 std::vector<bool> touched(volume_mesh.get_triangulation().n_vertices(),
7132 std::vector<CellData<boundary_dim>> cells;
7134 std::vector<Point<spacedim>>
vertices;
7137 std::map<unsigned int, unsigned int> map_vert_index;
7150 for (
unsigned int i1 = 0; i1 < GeometryInfo<spacedim>::faces_per_cell; i1++)
7152 for (
unsigned int i2 = 0; i2 <
GeometryInfo<dim - 1>::vertices_per_cell;
7154 swap_matrix[i1][i2] = i2;
7160 std::swap(swap_matrix[0][1], swap_matrix[0][2]);
7161 std::swap(swap_matrix[2][1], swap_matrix[2][2]);
7162 std::swap(swap_matrix[4][1], swap_matrix[4][2]);
7166 std::swap(swap_matrix[1][0], swap_matrix[1][1]);
7167 std::swap(swap_matrix[2][0], swap_matrix[2][1]);
7172 for (
typename MeshType<dim, spacedim>::cell_iterator cell =
7173 volume_mesh.begin(0);
7174 cell != volume_mesh.end(0);
7178 const typename MeshType<dim, spacedim>::face_iterator face =
7181 if (face->at_boundary() &&
7182 (boundary_ids.empty() ||
7183 (boundary_ids.find(face->boundary_id()) != boundary_ids.end())))
7187 for (
const unsigned int j :
7190 const unsigned int v_index = face->vertex_index(j);
7192 if (!touched[v_index])
7194 vertices.push_back(face->vertex(j));
7195 map_vert_index[v_index] =
vertices.size() - 1;
7196 touched[v_index] =
true;
7199 c_data.
vertices[swap_matrix[i][j]] = map_vert_index[v_index];
7213 for (
unsigned int e = 0;
e < 4; ++
e)
7219 bool edge_found =
false;
7222 map_vert_index[face->line(
e)->vertex_index(0)]) &&
7224 map_vert_index[face->line(
e)->vertex_index(
7227 map_vert_index[face->line(
e)->vertex_index(1)]) &&
7229 map_vert_index[face->line(
e)->vertex_index(0)])))
7236 if (edge_found ==
true)
7243 map_vert_index[face->line(
e)->vertex_index(0)];
7245 map_vert_index[face->line(
e)->vertex_index(1)];
7252 cells.push_back(c_data);
7253 temporary_mapping_level0.push_back(std::make_pair(face, i));
7260 surface_mesh.get_triangulation())
7266 for (
const auto &cell : surface_mesh.active_cell_iterators())
7267 for (
unsigned int vertex = 0; vertex < 2; vertex++)
7268 if (cell->face(vertex)->at_boundary())
7269 cell->face(vertex)->set_boundary_id(0);
7277 std::vector<std::pair<
7278 const typename MeshType<dim - 1, spacedim>::cell_iterator,
7279 std::pair<typename MeshType<dim, spacedim>::face_iterator,
unsigned int>>>
7280 temporary_map_boundary_cell_face;
7281 for (
const auto &cell : surface_mesh.active_cell_iterators())
7282 temporary_map_boundary_cell_face.push_back(
7283 std::make_pair(cell, temporary_mapping_level0.at(cell->index())));
7295 unsigned int index_cells_deepest_level = 0;
7298 bool changed =
false;
7302 std::vector<unsigned int> cells_refined;
7305 for (
unsigned int cell_n = index_cells_deepest_level;
7306 cell_n < temporary_map_boundary_cell_face.size();
7311 if (temporary_map_boundary_cell_face[cell_n]
7312 .
second.first->has_children())
7316 Assert(temporary_map_boundary_cell_face[cell_n]
7317 .
second.first->refinement_case() ==
7320 temporary_map_boundary_cell_face[cell_n]
7321 .first->set_refine_flag();
7322 cells_refined.push_back(cell_n);
7333 surface_mesh.get_triangulation())
7334 .execute_coarsening_and_refinement();
7337 index_cells_deepest_level = temporary_map_boundary_cell_face.size();
7338 for (
const auto &refined_cell_n : cells_refined)
7340 const typename MeshType<dim - 1, spacedim>::cell_iterator
7342 temporary_map_boundary_cell_face[refined_cell_n].first;
7343 const typename MeshType<dim,
7344 spacedim>::face_iterator refined_face =
7345 temporary_map_boundary_cell_face[refined_cell_n].second.first;
7346 const unsigned int refined_face_number =
7347 temporary_map_boundary_cell_face[refined_cell_n]
7349 for (
unsigned int child_n = 0;
7350 child_n < refined_cell->n_children();
7355 temporary_map_boundary_cell_face.push_back(
7356 std::make_pair(refined_cell->child(
7357 swap_matrix[refined_face_number][child_n]),
7358 std::make_pair(refined_face->child(child_n),
7359 refined_face_number)));
7369 std::map<
typename MeshType<dim - 1, spacedim>::cell_iterator,
7370 typename MeshType<dim, spacedim>::face_iterator>
7371 surface_to_volume_mapping;
7372 for (
unsigned int i = 0; i < temporary_map_boundary_cell_face.size(); i++)
7373 surface_to_volume_mapping[temporary_map_boundary_cell_face[i].
first] =
7374 temporary_map_boundary_cell_face[i].
second.first;
7376 return surface_to_volume_mapping;
7382 # include "grid_generator.inst"