16 #include <deal.II/distributed/shared_tria.h> 17 #include <deal.II/distributed/tria.h> 19 #include <deal.II/grid/grid_generator.h> 20 #include <deal.II/grid/grid_reordering.h> 21 #include <deal.II/grid/grid_tools.h> 22 #include <deal.II/grid/intergrid_map.h> 23 #include <deal.II/grid/manifold_lib.h> 24 #include <deal.II/grid/tria.h> 25 #include <deal.II/grid/tria_accessor.h> 26 #include <deal.II/grid/tria_iterator.h> 31 DEAL_II_NAMESPACE_OPEN
42 template <
int dim,
int spacedim>
53 for (
unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell; ++f)
54 cell->face(f)->set_boundary_id(f);
60 template <
int spacedim>
70 if (cell->center()(0) > 0)
71 cell->set_material_id(1);
78 template <
int dim,
int spacedim>
96 for (; face != endface; ++face)
97 if (face->at_boundary())
98 if (face->boundary_id() == 0)
102 if (std::abs(center(0) - p1[0]) <
epsilon)
103 face->set_boundary_id(0);
104 else if (std::abs(center(0) - p2[0]) < epsilon)
105 face->set_boundary_id(1);
106 else if (dim > 1 && std::abs(center(1) - p1[1]) < epsilon)
107 face->set_boundary_id(2);
108 else if (dim > 1 && std::abs(center(1) - p2[1]) < epsilon)
109 face->set_boundary_id(3);
110 else if (dim > 2 && std::abs(center(2) - p1[2]) < epsilon)
111 face->set_boundary_id(4);
112 else if (dim > 2 && std::abs(center(2) - p2[2]) < epsilon)
113 face->set_boundary_id(5);
128 for (
unsigned int d = 0;
d < dim; ++
d)
129 if (cell->center()(
d) > 0)
131 cell->set_material_id(
id);
156 cell->face(2)->set_all_boundary_ids(1);
179 cell->face(4)->set_all_boundary_ids(1);
183 cell->face(2)->set_all_boundary_ids(1);
187 cell->face(2)->set_all_boundary_ids(1);
191 cell->face(0)->set_all_boundary_ids(1);
195 cell->face(2)->set_all_boundary_ids(1);
199 cell->face(0)->set_all_boundary_ids(1);
210 cell->face(5)->set_all_boundary_ids(1);
226 unsigned int count = 0;
230 if (cell->face(5)->at_boundary())
232 cell->face(5)->set_all_boundary_ids(1);
250 const double inner_radius,
251 const double outer_radius)
256 double middle = (outer_radius - inner_radius) / 2e0 + inner_radius;
257 double eps = 1
e-3 * middle;
260 for (; cell != tria.
end(); ++cell)
261 for (
unsigned int f = 0; f < GeometryInfo<3>::faces_per_cell; ++f)
263 if (!cell->face(f)->at_boundary())
266 double radius = cell->face(f)->center().norm() - center.
norm();
267 if (std::fabs(cell->face(f)->center()(0)) <
270 cell->face(f)->set_boundary_id(2);
271 for (
unsigned int j = 0; j < GeometryInfo<3>::lines_per_face;
273 if (cell->face(f)->line(j)->at_boundary())
274 if (std::fabs(cell->face(f)->line(j)->vertex(0).norm() -
275 cell->face(f)->line(j)->vertex(1).norm()) >
277 cell->face(f)->line(j)->set_boundary_id(2);
279 else if (std::fabs(cell->face(f)->center()(1)) <
282 cell->face(f)->set_boundary_id(3);
283 for (
unsigned int j = 0; j < GeometryInfo<3>::lines_per_face;
285 if (cell->face(f)->line(j)->at_boundary())
286 if (std::fabs(cell->face(f)->line(j)->vertex(0).norm() -
287 cell->face(f)->line(j)->vertex(1).norm()) >
289 cell->face(f)->line(j)->set_boundary_id(3);
291 else if (std::fabs(cell->face(f)->center()(2)) <
294 cell->face(f)->set_boundary_id(4);
295 for (
unsigned int j = 0; j < GeometryInfo<3>::lines_per_face;
297 if (cell->face(f)->line(j)->at_boundary())
298 if (std::fabs(cell->face(f)->line(j)->vertex(0).norm() -
299 cell->face(f)->line(j)->vertex(1).norm()) >
301 cell->face(f)->line(j)->set_boundary_id(4);
303 else if (radius < middle)
305 cell->face(f)->set_boundary_id(0);
306 for (
unsigned int j = 0; j < GeometryInfo<3>::lines_per_face;
308 if (cell->face(f)->line(j)->at_boundary())
309 if (std::fabs(cell->face(f)->line(j)->vertex(0).norm() -
310 cell->face(f)->line(j)->vertex(1).norm()) <
312 cell->face(f)->line(j)->set_boundary_id(0);
314 else if (radius > middle)
316 cell->face(f)->set_boundary_id(1);
317 for (
unsigned int j = 0; j < GeometryInfo<3>::lines_per_face;
319 if (cell->face(f)->line(j)->at_boundary())
320 if (std::fabs(cell->face(f)->line(j)->vertex(0).norm() -
321 cell->face(f)->line(j)->vertex(1).norm()) <
323 cell->face(f)->line(j)->set_boundary_id(1);
333 template <
int dim,
int spacedim>
344 for (
unsigned int i = 0; i < dim; ++i)
346 p1(i) = std::min(p_1(i), p_2(i));
347 p2(i) = std::max(p_1(i), p_2(i));
358 vertices[0] = vertices[1] = p1;
359 vertices[2] = vertices[3] = p2;
361 vertices[1](0) = p2(0);
362 vertices[2](0) = p1(0);
365 vertices[0] = vertices[1] = vertices[2] = vertices[3] = p1;
366 vertices[4] = vertices[5] = vertices[6] = vertices[7] = p2;
368 vertices[1](0) = p2(0);
369 vertices[2](1) = p2(1);
370 vertices[3](0) = p2(0);
371 vertices[3](1) = p2(1);
373 vertices[4](0) = p1(0);
374 vertices[4](1) = p1(1);
375 vertices[5](1) = p1(1);
376 vertices[6](0) = p1(0);
384 std::vector<CellData<dim>> cells(1);
385 for (
unsigned int i = 0; i < GeometryInfo<dim>::vertices_per_cell; ++i)
386 cells[0].vertices[i] = i;
387 cells[0].material_id = 0;
393 colorize_hyper_rectangle(tria);
397 template <
int dim,
int spacedim>
405 ExcMessage(
"Invalid left-to-right bounds of hypercube"));
408 for (
unsigned int i = 0; i < dim; ++i)
426 for (
unsigned int d = 0; d < dim; ++d)
427 for (
unsigned int c = 1; c <= dim; ++c)
428 vector_matrix[c - 1][d] = vertices[c](d) - vertices[0](d);
430 ExcMessage(
"Vertices of simplex must form a right handed system"));
434 std::vector<Point<dim>> points = vertices;
438 for (
unsigned int i = 0; i <= dim; ++i)
440 points.push_back(0.5 * (points[i] + points[(i + 1) % (dim + 1)]));
446 for (
unsigned int i = 1; i < dim; ++i)
447 points.push_back(0.5 * (points[i - 1] + points[i + 1]));
449 for (
unsigned int i = 0; i <= dim; ++i)
450 points.push_back(1. / 3. *
451 (points[i] + points[(i + 1) % (dim + 1)] +
452 points[(i + 2) % (dim + 1)]));
454 points.push_back((1. / (dim + 1)) * center);
456 std::vector<CellData<dim>> cells(dim + 1);
461 cells[0].vertices[0] = 0;
462 cells[0].vertices[1] = 3;
463 cells[0].vertices[2] = 5;
464 cells[0].vertices[3] = 6;
465 cells[0].material_id = 0;
467 cells[1].vertices[0] = 3;
468 cells[1].vertices[1] = 1;
469 cells[1].vertices[2] = 6;
470 cells[1].vertices[3] = 4;
471 cells[1].material_id = 0;
473 cells[2].vertices[0] = 5;
474 cells[2].vertices[1] = 6;
475 cells[2].vertices[2] = 2;
476 cells[2].vertices[3] = 4;
477 cells[2].material_id = 0;
481 cells[0].vertices[0] = 0;
482 cells[0].vertices[1] = 4;
483 cells[0].vertices[2] = 8;
484 cells[0].vertices[3] = 10;
485 cells[0].vertices[4] = 7;
486 cells[0].vertices[5] = 13;
487 cells[0].vertices[6] = 12;
488 cells[0].vertices[7] = 14;
489 cells[0].material_id = 0;
491 cells[1].vertices[0] = 4;
492 cells[1].vertices[1] = 1;
493 cells[1].vertices[2] = 10;
494 cells[1].vertices[3] = 5;
495 cells[1].vertices[4] = 13;
496 cells[1].vertices[5] = 9;
497 cells[1].vertices[6] = 14;
498 cells[1].vertices[7] = 11;
499 cells[1].material_id = 0;
501 cells[2].vertices[0] = 8;
502 cells[2].vertices[1] = 10;
503 cells[2].vertices[2] = 2;
504 cells[2].vertices[3] = 5;
505 cells[2].vertices[4] = 12;
506 cells[2].vertices[5] = 14;
507 cells[2].vertices[6] = 6;
508 cells[2].vertices[7] = 11;
509 cells[2].material_id = 0;
511 cells[3].vertices[0] = 7;
512 cells[3].vertices[1] = 13;
513 cells[3].vertices[2] = 12;
514 cells[3].vertices[3] = 14;
515 cells[3].vertices[4] = 3;
516 cells[3].vertices[5] = 9;
517 cells[3].vertices[6] = 6;
518 cells[3].vertices[7] = 11;
519 cells[3].material_id = 0;
529 const unsigned int n_cells,
530 const unsigned int n_rotations,
534 const unsigned int dim = 3;
537 "More than 4 cells are needed to create a moebius grid."));
539 ExcMessage(
"Outer and inner radius must be positive."));
541 ExcMessage(
"Outer radius must be greater than inner radius."));
544 std::vector<Point<dim>> vertices(4 * n_cells);
545 double beta_step = n_rotations *
numbers::PI / 2.0 / n_cells;
548 for (
unsigned int i = 0; i < n_cells; ++i)
549 for (
unsigned int j = 0; j < 4; ++j)
551 vertices[4 * i + j][0] =
552 R * std::cos(i * alpha_step) +
553 r * std::cos(i * beta_step + j *
numbers::PI / 2.0) *
554 std::cos(i * alpha_step);
555 vertices[4 * i + j][1] =
556 R * std::sin(i * alpha_step) +
557 r * std::cos(i * beta_step + j *
numbers::PI / 2.0) *
558 std::sin(i * alpha_step);
559 vertices[4 * i + j][2] =
560 r * std::sin(i * beta_step + j *
numbers::PI / 2.0);
563 unsigned int offset = 0;
565 std::vector<CellData<dim>> cells(n_cells);
566 for (
unsigned int i = 0; i < n_cells; ++i)
568 for (
unsigned int j = 0; j < 2; ++j)
570 cells[i].vertices[0 + 4 * j] = offset + 0 + 4 * j;
571 cells[i].vertices[1 + 4 * j] = offset + 3 + 4 * j;
572 cells[i].vertices[2 + 4 * j] = offset + 2 + 4 * j;
573 cells[i].vertices[3 + 4 * j] = offset + 1 + 4 * j;
576 cells[i].material_id = 0;
580 cells[n_cells - 1].vertices[4] = (0 + n_rotations) % 4;
581 cells[n_cells - 1].vertices[5] = (3 + n_rotations) % 4;
582 cells[n_cells - 1].vertices[6] = (2 + n_rotations) % 4;
583 cells[n_cells - 1].vertices[7] = (1 + n_rotations) % 4;
595 ExcMessage(
"Outer radius R must be greater than the inner " 599 const unsigned int dim = 2;
600 const unsigned int spacedim = 3;
601 std::vector<Point<spacedim>> vertices(16);
620 std::vector<CellData<dim>> cells(16);
622 cells[0].vertices[0] = 0;
623 cells[0].vertices[1] = 4;
624 cells[0].vertices[2] = 7;
625 cells[0].vertices[3] = 3;
626 cells[0].material_id = 0;
628 cells[1].vertices[0] = 1;
629 cells[1].vertices[1] = 5;
630 cells[1].vertices[2] = 4;
631 cells[1].vertices[3] = 0;
632 cells[1].material_id = 0;
634 cells[2].vertices[0] = 2;
635 cells[2].vertices[1] = 6;
636 cells[2].vertices[2] = 5;
637 cells[2].vertices[3] = 1;
638 cells[2].material_id = 0;
640 cells[3].vertices[0] = 3;
641 cells[3].vertices[1] = 7;
642 cells[3].vertices[2] = 6;
643 cells[3].vertices[3] = 2;
644 cells[3].material_id = 0;
646 cells[4].vertices[0] = 4;
647 cells[4].vertices[1] = 8;
648 cells[4].vertices[2] = 11;
649 cells[4].vertices[3] = 7;
650 cells[4].material_id = 0;
652 cells[5].vertices[0] = 5;
653 cells[5].vertices[1] = 9;
654 cells[5].vertices[2] = 8;
655 cells[5].vertices[3] = 4;
656 cells[5].material_id = 0;
658 cells[6].vertices[0] = 6;
659 cells[6].vertices[1] = 10;
660 cells[6].vertices[2] = 9;
661 cells[6].vertices[3] = 5;
662 cells[6].material_id = 0;
664 cells[7].vertices[0] = 7;
665 cells[7].vertices[1] = 11;
666 cells[7].vertices[2] = 10;
667 cells[7].vertices[3] = 6;
668 cells[7].material_id = 0;
670 cells[8].vertices[0] = 8;
671 cells[8].vertices[1] = 12;
672 cells[8].vertices[2] = 15;
673 cells[8].vertices[3] = 11;
674 cells[8].material_id = 0;
676 cells[9].vertices[0] = 9;
677 cells[9].vertices[1] = 13;
678 cells[9].vertices[2] = 12;
679 cells[9].vertices[3] = 8;
680 cells[9].material_id = 0;
682 cells[10].vertices[0] = 10;
683 cells[10].vertices[1] = 14;
684 cells[10].vertices[2] = 13;
685 cells[10].vertices[3] = 9;
686 cells[10].material_id = 0;
688 cells[11].vertices[0] = 11;
689 cells[11].vertices[1] = 15;
690 cells[11].vertices[2] = 14;
691 cells[11].vertices[3] = 10;
692 cells[11].material_id = 0;
694 cells[12].vertices[0] = 12;
695 cells[12].vertices[1] = 0;
696 cells[12].vertices[2] = 3;
697 cells[12].vertices[3] = 15;
698 cells[12].material_id = 0;
700 cells[13].vertices[0] = 13;
701 cells[13].vertices[1] = 1;
702 cells[13].vertices[2] = 0;
703 cells[13].vertices[3] = 12;
704 cells[13].material_id = 0;
706 cells[14].vertices[0] = 14;
707 cells[14].vertices[1] = 2;
708 cells[14].vertices[2] = 1;
709 cells[14].vertices[3] = 13;
710 cells[14].material_id = 0;
712 cells[15].vertices[0] = 15;
713 cells[15].vertices[1] = 3;
714 cells[15].vertices[2] = 2;
715 cells[15].vertices[3] = 14;
716 cells[15].material_id = 0;
732 ExcMessage(
"Outer radius R must be greater than the inner " 745 tria.set_all_manifold_ids(1);
746 tria.set_all_manifold_ids_on_boundary(0);
752 template <
int dim,
int spacedim>
766 for (
unsigned int i = 0; i < GeometryInfo<dim>::vertices_per_cell; ++i)
767 cell->vertex(i) = vertices[i];
773 "The volume of the cell is not greater than zero. " 774 "This could be due to the wrong ordering of the vertices."));
802 std::array<Tensor<1, 2>, 2> edges;
803 edges[0] = corners[0];
804 edges[1] = corners[1];
805 std::vector<unsigned int> subdivisions;
806 subdivided_parallelepiped<2, 2>(
807 tria, origin, edges, subdivisions, colorize);
818 unsigned int n_subdivisions[dim];
819 for (
unsigned int i = 0; i < dim; ++i)
820 n_subdivisions[i] = 1;
829 const unsigned int n_subdivisions,
835 unsigned int n_subdivisions_[dim];
836 for (
unsigned int i = 0; i < dim; ++i)
837 n_subdivisions_[i] = n_subdivisions;
847 const unsigned int (&n_subdivisions)[dim],
849 const unsigned int *n_subdivisions,
855 std::vector<unsigned int> subdivisions;
856 std::array<Tensor<1, dim>, dim> edges;
857 for (
unsigned int i = 0; i < dim; ++i)
859 subdivisions.push_back(n_subdivisions[i]);
860 edges[i] = corners[i];
863 subdivided_parallelepiped<dim, dim>(
864 tria, origin, edges, subdivisions, colorize);
875 template <
int dim,
int spacedim>
880 const std::vector<unsigned int> &subdivisions,
883 std::vector<unsigned int> compute_subdivisions = subdivisions;
884 if (compute_subdivisions.size() == 0)
886 compute_subdivisions.resize(dim, 1);
889 Assert(compute_subdivisions.size() == dim,
890 ExcMessage(
"One subdivision must be provided for each dimension."));
892 for (
unsigned int i = 0; i < dim; ++i)
894 Assert(compute_subdivisions[i] > 0,
899 "Edges in subdivided_parallelepiped() must not be degenerate."));
907 bool twisted_data =
false;
912 twisted_data = (edges[0][0] < 0);
919 const double plane_normal =
920 edges[0][0] * edges[1][1] - edges[0][1] * edges[1][0];
921 twisted_data = (plane_normal < 0.0);
929 Assert(std::abs(edges[0] * edges[1] /
930 (edges[0].norm() * edges[1].norm()) -
933 "Edges in subdivided_parallelepiped() must point in" 934 " different directions."));
936 cross_product_3d(edges[0], edges[1]);
950 twisted_data = (plane_normal * edges[2] < 0.0);
960 "The triangulation you are trying to create will consist of cells" 961 " with negative measures. This is usually the result of input data" 962 " that does not define a right-handed coordinate system. The usual" 963 " fix for this is to ensure that in 1D the given point is to the" 964 " right of the origin (or the given edge tensor is positive), in 2D" 965 " that the two edges (and their cross product) obey the right-hand" 966 " rule (which may usually be done by switching the order of the" 967 " points or edge tensors), or in 3D that the edges form a" 968 " right-handed coordinate system (which may also be accomplished by" 969 " switching the order of the first two points or edge tensors)."));
972 for (
unsigned int i = 0; i < dim; ++i)
973 for (
unsigned int j = i + 1; j < dim; ++j)
974 Assert((edges[i] != edges[j]),
976 "Degenerate edges of subdivided_parallelepiped encountered."));
979 std::vector<Point<spacedim>> points;
984 for (
unsigned int x = 0; x <= compute_subdivisions[0]; ++x)
985 points.push_back(origin + edges[0] / compute_subdivisions[0] * x);
989 for (
unsigned int y = 0; y <= compute_subdivisions[1]; ++y)
990 for (
unsigned int x = 0; x <= compute_subdivisions[0]; ++x)
991 points.push_back(origin + edges[0] / compute_subdivisions[0] * x +
992 edges[1] / compute_subdivisions[1] * y);
996 for (
unsigned int z = 0; z <= compute_subdivisions[2]; ++z)
997 for (
unsigned int y = 0; y <= compute_subdivisions[1]; ++y)
998 for (
unsigned int x = 0; x <= compute_subdivisions[0]; ++x)
999 points.push_back(origin +
1000 edges[0] / compute_subdivisions[0] * x +
1001 edges[1] / compute_subdivisions[1] * y +
1002 edges[2] / compute_subdivisions[2] * z);
1010 unsigned int n_cells = 1;
1011 for (
unsigned int i = 0; i < dim; ++i)
1012 n_cells *= compute_subdivisions[i];
1013 std::vector<CellData<dim>> cells(n_cells);
1019 for (
unsigned int x = 0; x < compute_subdivisions[0]; ++x)
1021 cells[x].vertices[0] = x;
1022 cells[x].vertices[1] = x + 1;
1025 cells[x].material_id = 0;
1032 const unsigned int n_dy = compute_subdivisions[1];
1033 const unsigned int n_dx = compute_subdivisions[0];
1035 for (
unsigned int y = 0; y < n_dy; ++y)
1036 for (
unsigned int x = 0; x < n_dx; ++x)
1038 const unsigned int c = y * n_dx + x;
1039 cells[c].vertices[0] = y * (n_dx + 1) + x;
1040 cells[c].vertices[1] = y * (n_dx + 1) + x + 1;
1041 cells[c].vertices[2] = (y + 1) * (n_dx + 1) + x;
1042 cells[c].vertices[3] = (y + 1) * (n_dx + 1) + x + 1;
1045 cells[c].material_id = 0;
1053 const unsigned int n_dz = compute_subdivisions[2];
1054 const unsigned int n_dy = compute_subdivisions[1];
1055 const unsigned int n_dx = compute_subdivisions[0];
1057 for (
unsigned int z = 0; z < n_dz; ++z)
1058 for (
unsigned int y = 0; y < n_dy; ++y)
1059 for (
unsigned int x = 0; x < n_dx; ++x)
1061 const unsigned int c = z * n_dy * n_dx + y * n_dx + x;
1063 cells[c].vertices[0] =
1064 z * (n_dy + 1) * (n_dx + 1) + y * (n_dx + 1) + x;
1065 cells[c].vertices[1] =
1066 z * (n_dy + 1) * (n_dx + 1) + y * (n_dx + 1) + x + 1;
1067 cells[c].vertices[2] =
1068 z * (n_dy + 1) * (n_dx + 1) + (y + 1) * (n_dx + 1) + x;
1069 cells[c].vertices[3] = z * (n_dy + 1) * (n_dx + 1) +
1070 (y + 1) * (n_dx + 1) + x + 1;
1071 cells[c].vertices[4] =
1072 (z + 1) * (n_dy + 1) * (n_dx + 1) + y * (n_dx + 1) + x;
1073 cells[c].vertices[5] = (z + 1) * (n_dy + 1) * (n_dx + 1) +
1074 y * (n_dx + 1) + x + 1;
1075 cells[c].vertices[6] = (z + 1) * (n_dy + 1) * (n_dx + 1) +
1076 (y + 1) * (n_dx + 1) + x;
1077 cells[c].vertices[7] = (z + 1) * (n_dy + 1) * (n_dx + 1) +
1078 (y + 1) * (n_dx + 1) + x + 1;
1081 cells[c].material_id = 0;
1102 for (; cell != endc; ++cell)
1104 for (
unsigned int face = 0;
1105 face < GeometryInfo<dim>::faces_per_cell;
1108 if (cell->face(face)->at_boundary())
1109 cell->face(face)->set_boundary_id(face);
1116 template <
int dim,
int spacedim>
1119 const unsigned int repetitions,
1125 ExcMessage(
"Invalid left-to-right bounds of hypercube"));
1128 for (
unsigned int i = 0; i < dim; ++i)
1134 std::vector<unsigned int> reps(dim, repetitions);
1140 template <
int dim,
int spacedim>
1143 const std::vector<unsigned int> &repetitions,
1146 const bool colorize)
1154 for (
unsigned int i = 0; i < dim; ++i)
1156 p1(i) = std::min(p_1(i), p_2(i));
1157 p2(i) = std::max(p_1(i), p_2(i));
1161 std::vector<Point<spacedim>> delta(dim);
1162 for (
unsigned int i = 0; i < dim; ++i)
1166 delta[i][i] = (p2[i] - p1[i]) / repetitions[i];
1170 "The first dim entries of coordinates of p1 and p2 need to be different."));
1174 std::vector<Point<spacedim>> points;
1178 for (
unsigned int x = 0; x <= repetitions[0]; ++x)
1179 points.push_back(p1 + x * delta[0]);
1183 for (
unsigned int y = 0; y <= repetitions[1]; ++y)
1184 for (
unsigned int x = 0; x <= repetitions[0]; ++x)
1185 points.push_back(p1 + x * delta[0] + y * delta[1]);
1189 for (
unsigned int z = 0; z <= repetitions[2]; ++z)
1190 for (
unsigned int y = 0; y <= repetitions[1]; ++y)
1191 for (
unsigned int x = 0; x <= repetitions[0]; ++x)
1192 points.push_back(p1 + x * delta[0] + y * delta[1] +
1201 std::vector<CellData<dim>> cells;
1206 cells.resize(repetitions[0]);
1207 for (
unsigned int x = 0; x < repetitions[0]; ++x)
1209 cells[x].vertices[0] = x;
1210 cells[x].vertices[1] = x + 1;
1211 cells[x].material_id = 0;
1218 cells.resize(repetitions[1] * repetitions[0]);
1219 for (
unsigned int y = 0; y < repetitions[1]; ++y)
1220 for (
unsigned int x = 0; x < repetitions[0]; ++x)
1222 const unsigned int c = x + y * repetitions[0];
1223 cells[c].vertices[0] = y * (repetitions[0] + 1) + x;
1224 cells[c].vertices[1] = y * (repetitions[0] + 1) + x + 1;
1225 cells[c].vertices[2] = (y + 1) * (repetitions[0] + 1) + x;
1226 cells[c].vertices[3] = (y + 1) * (repetitions[0] + 1) + x + 1;
1227 cells[c].material_id = 0;
1234 const unsigned int n_x = (repetitions[0] + 1);
1235 const unsigned int n_xy =
1236 (repetitions[0] + 1) * (repetitions[1] + 1);
1238 cells.resize(repetitions[2] * repetitions[1] * repetitions[0]);
1239 for (
unsigned int z = 0; z < repetitions[2]; ++z)
1240 for (
unsigned int y = 0; y < repetitions[1]; ++y)
1241 for (
unsigned int x = 0; x < repetitions[0]; ++x)
1243 const unsigned int c = x + y * repetitions[0] +
1244 z * repetitions[0] * repetitions[1];
1245 cells[c].vertices[0] = z * n_xy + y * n_x + x;
1246 cells[c].vertices[1] = z * n_xy + y * n_x + x + 1;
1247 cells[c].vertices[2] = z * n_xy + (y + 1) * n_x + x;
1248 cells[c].vertices[3] = z * n_xy + (y + 1) * n_x + x + 1;
1249 cells[c].vertices[4] = (z + 1) * n_xy + y * n_x + x;
1250 cells[c].vertices[5] = (z + 1) * n_xy + y * n_x + x + 1;
1251 cells[c].vertices[6] = (z + 1) * n_xy + (y + 1) * n_x + x;
1252 cells[c].vertices[7] =
1253 (z + 1) * n_xy + (y + 1) * n_x + x + 1;
1254 cells[c].material_id = 0;
1275 double epsilon = 10;
1276 for (
unsigned int i = 0; i < dim; ++i)
1277 epsilon = std::min(epsilon, 0.01 * delta[i][i]);
1280 "The distance between corner points must be positive."))
1284 colorize_subdivided_hyper_rectangle(tria, p1, p2, epsilon);
1293 const std::vector<std::vector<double>> &step_sz,
1296 const bool colorize)
1308 std::vector<std::vector<double>> step_sizes(step_sz);
1310 for (
unsigned int i = 0; i < dim; ++i)
1315 std::reverse(step_sizes[i].begin(), step_sizes[i].end());
1319 for (
unsigned int j = 0; j < step_sizes.at(i).size(); j++)
1320 x += step_sizes[i][j];
1321 Assert(std::fabs(x - (p2(i) - p1(i))) <= 1e-12 * std::fabs(x),
1323 "The sequence of step sizes in coordinate direction " +
1325 " must be equal to the distance of the two given " 1326 "points in this coordinate direction."));
1332 std::vector<Point<dim>> points;
1338 for (
unsigned int i = 0;; ++i)
1347 if (i == step_sizes[0].size())
1350 x += step_sizes[0][i];
1358 for (
unsigned int j = 0;; ++j)
1361 for (
unsigned int i = 0;; ++i)
1363 points.push_back(
Point<dim>(p1[0] + x, p1[1] + y));
1364 if (i == step_sizes[0].size())
1367 x += step_sizes[0][i];
1370 if (j == step_sizes[1].size())
1373 y += step_sizes[1][j];
1380 for (
unsigned int k = 0;; ++k)
1383 for (
unsigned int j = 0;; ++j)
1386 for (
unsigned int i = 0;; ++i)
1389 Point<dim>(p1[0] + x, p1[1] + y, p1[2] + z));
1390 if (i == step_sizes[0].size())
1393 x += step_sizes[0][i];
1396 if (j == step_sizes[1].size())
1399 y += step_sizes[1][j];
1402 if (k == step_sizes[2].size())
1405 z += step_sizes[2][k];
1416 std::vector<CellData<dim>> cells;
1421 cells.resize(step_sizes[0].size());
1422 for (
unsigned int x = 0; x < step_sizes[0].size(); ++x)
1424 cells[x].vertices[0] = x;
1425 cells[x].vertices[1] = x + 1;
1426 cells[x].material_id = 0;
1433 cells.resize(step_sizes[1].size() * step_sizes[0].size());
1434 for (
unsigned int y = 0; y < step_sizes[1].size(); ++y)
1435 for (
unsigned int x = 0; x < step_sizes[0].size(); ++x)
1437 const unsigned int c = x + y * step_sizes[0].size();
1438 cells[c].vertices[0] = y * (step_sizes[0].size() + 1) + x;
1439 cells[c].vertices[1] = y * (step_sizes[0].size() + 1) + x + 1;
1440 cells[c].vertices[2] =
1441 (y + 1) * (step_sizes[0].size() + 1) + x;
1442 cells[c].vertices[3] =
1443 (y + 1) * (step_sizes[0].size() + 1) + x + 1;
1444 cells[c].material_id = 0;
1451 const unsigned int n_x = (step_sizes[0].size() + 1);
1452 const unsigned int n_xy =
1453 (step_sizes[0].size() + 1) * (step_sizes[1].size() + 1);
1455 cells.resize(step_sizes[2].size() * step_sizes[1].size() *
1456 step_sizes[0].size());
1457 for (
unsigned int z = 0; z < step_sizes[2].size(); ++z)
1458 for (
unsigned int y = 0; y < step_sizes[1].size(); ++y)
1459 for (
unsigned int x = 0; x < step_sizes[0].size(); ++x)
1461 const unsigned int c =
1462 x + y * step_sizes[0].size() +
1463 z * step_sizes[0].size() * step_sizes[1].size();
1464 cells[c].vertices[0] = z * n_xy + y * n_x + x;
1465 cells[c].vertices[1] = z * n_xy + y * n_x + x + 1;
1466 cells[c].vertices[2] = z * n_xy + (y + 1) * n_x + x;
1467 cells[c].vertices[3] = z * n_xy + (y + 1) * n_x + x + 1;
1468 cells[c].vertices[4] = (z + 1) * n_xy + y * n_x + x;
1469 cells[c].vertices[5] = (z + 1) * n_xy + y * n_x + x + 1;
1470 cells[c].vertices[6] = (z + 1) * n_xy + (y + 1) * n_x + x;
1471 cells[c].vertices[7] =
1472 (z + 1) * n_xy + (y + 1) * n_x + x + 1;
1473 cells[c].material_id = 0;
1495 *std::min_element(step_sizes[0].begin(), step_sizes[0].end());
1496 for (
unsigned int i = 1; i < dim; ++i)
1497 min_size = std::min(min_size,
1498 *std::min_element(step_sizes[i].begin(),
1499 step_sizes[i].end()));
1500 const double epsilon = 0.01 * min_size;
1504 colorize_subdivided_hyper_rectangle(tria, p1, p2, epsilon);
1513 const std::vector<std::vector<double>> &spacing,
1516 const bool colorize)
1520 const unsigned int n_cells = material_id.size(0);
1524 double delta = std::numeric_limits<double>::max();
1525 for (
unsigned int i = 0; i < n_cells; i++)
1528 delta = std::min(delta, spacing[0][i]);
1532 std::vector<Point<1>> points;
1534 for (
unsigned int x = 0; x <= n_cells; ++x)
1536 points.emplace_back(ax);
1538 ax += spacing[0][x];
1541 unsigned int n_val_cells = 0;
1542 for (
unsigned int i = 0; i < n_cells; i++)
1546 std::vector<CellData<1>> cells(n_val_cells);
1547 unsigned int id = 0;
1548 for (
unsigned int x = 0; x < n_cells; ++x)
1551 cells[id].vertices[0] = x;
1552 cells[id].vertices[1] = x + 1;
1571 const std::vector<std::vector<double>> &spacing,
1574 const bool colorize)
1578 std::vector<unsigned int> repetitions(2);
1579 unsigned int n_cells = 1;
1580 double delta = std::numeric_limits<double>::max();
1581 for (
unsigned int i = 0; i < 2; i++)
1583 repetitions[i] = spacing[i].size();
1584 n_cells *= repetitions[i];
1585 for (
unsigned int j = 0; j < repetitions[i]; j++)
1588 delta = std::min(delta, spacing[i][j]);
1595 std::vector<Point<2>> points;
1597 for (
unsigned int y = 0; y <= repetitions[1]; ++y)
1600 for (
unsigned int x = 0; x <= repetitions[0]; ++x)
1602 points.emplace_back(ax, ay);
1603 if (x < repetitions[0])
1604 ax += spacing[0][x];
1606 if (y < repetitions[1])
1607 ay += spacing[1][y];
1611 unsigned int n_val_cells = 0;
1612 for (
unsigned int i = 0; i <
material_id.size(0); i++)
1613 for (
unsigned int j = 0; j <
material_id.size(1); j++)
1617 std::vector<CellData<2>> cells(n_val_cells);
1618 unsigned int id = 0;
1619 for (
unsigned int y = 0; y < repetitions[1]; ++y)
1620 for (
unsigned int x = 0; x < repetitions[0]; ++x)
1623 cells[id].vertices[0] = y * (repetitions[0] + 1) + x;
1624 cells[id].vertices[1] = y * (repetitions[0] + 1) + x + 1;
1625 cells[id].vertices[2] = (y + 1) * (repetitions[0] + 1) + x;
1626 cells[id].vertices[3] = (y + 1) * (repetitions[0] + 1) + x + 1;
1640 double eps = 0.01 * delta;
1642 for (; cell != endc; ++cell)
1644 Point<2> cell_center = cell->center();
1645 for (
unsigned int f = 0; f < GeometryInfo<2>::faces_per_cell; ++f)
1646 if (cell->face(f)->boundary_id() == 0)
1648 Point<2> face_center = cell->face(f)->center();
1649 for (
unsigned int i = 0; i < 2; ++i)
1651 if (face_center[i] < cell_center[i] - eps)
1652 cell->face(f)->set_boundary_id(i * 2);
1653 if (face_center[i] > cell_center[i] + eps)
1654 cell->face(f)->set_boundary_id(i * 2 + 1);
1665 const std::vector<std::vector<double>> &spacing,
1668 const bool colorize)
1670 const unsigned int dim = 3;
1674 std::vector<unsigned int> repetitions(dim);
1675 unsigned int n_cells = 1;
1676 double delta = std::numeric_limits<double>::max();
1677 for (
unsigned int i = 0; i < dim; i++)
1679 repetitions[i] = spacing[i].size();
1680 n_cells *= repetitions[i];
1681 for (
unsigned int j = 0; j < repetitions[i]; j++)
1684 delta = std::min(delta, spacing[i][j]);
1691 std::vector<Point<dim>> points;
1693 for (
unsigned int z = 0; z <= repetitions[2]; ++z)
1696 for (
unsigned int y = 0; y <= repetitions[1]; ++y)
1699 for (
unsigned int x = 0; x <= repetitions[0]; ++x)
1701 points.emplace_back(ax, ay, az);
1702 if (x < repetitions[0])
1703 ax += spacing[0][x];
1705 if (y < repetitions[1])
1706 ay += spacing[1][y];
1708 if (z < repetitions[2])
1709 az += spacing[2][z];
1713 unsigned int n_val_cells = 0;
1714 for (
unsigned int i = 0; i <
material_id.size(0); i++)
1715 for (
unsigned int j = 0; j <
material_id.size(1); j++)
1716 for (
unsigned int k = 0; k <
material_id.size(2); k++)
1720 std::vector<CellData<dim>> cells(n_val_cells);
1721 unsigned int id = 0;
1722 const unsigned int n_x = (repetitions[0] + 1);
1723 const unsigned int n_xy = (repetitions[0] + 1) * (repetitions[1] + 1);
1724 for (
unsigned int z = 0; z < repetitions[2]; ++z)
1725 for (
unsigned int y = 0; y < repetitions[1]; ++y)
1726 for (
unsigned int x = 0; x < repetitions[0]; ++x)
1729 cells[id].vertices[0] = z * n_xy + y * n_x + x;
1730 cells[id].vertices[1] = z * n_xy + y * n_x + x + 1;
1731 cells[id].vertices[2] = z * n_xy + (y + 1) * n_x + x;
1732 cells[id].vertices[3] = z * n_xy + (y + 1) * n_x + x + 1;
1733 cells[id].vertices[4] = (z + 1) * n_xy + y * n_x + x;
1734 cells[id].vertices[5] = (z + 1) * n_xy + y * n_x + x + 1;
1735 cells[id].vertices[6] = (z + 1) * n_xy + (y + 1) * n_x + x;
1736 cells[id].vertices[7] = (z + 1) * n_xy + (y + 1) * n_x + x + 1;
1750 double eps = 0.01 * delta;
1753 for (; cell != endc; ++cell)
1756 for (
unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell; ++f)
1757 if (cell->face(f)->boundary_id() == 0)
1759 Point<dim> face_center = cell->face(f)->center();
1760 for (
unsigned int i = 0; i < dim; ++i)
1762 if (face_center[i] < cell_center[i] - eps)
1763 cell->face(f)->set_boundary_id(i * 2);
1764 if (face_center[i] > cell_center[i] + eps)
1765 cell->face(f)->set_boundary_id(i * 2 + 1);
1772 template <
int dim,
int spacedim>
1775 const std::vector<unsigned int> &holes)
1784 for (
unsigned int d = 0; d < dim; ++d)
1791 std::vector<Point<spacedim>> delta(dim);
1792 unsigned int repetitions[dim];
1793 for (
unsigned int i = 0; i < dim; ++i)
1796 ExcMessage(
"At least one hole needed in each direction"));
1797 repetitions[i] = 2 * holes[i] + 1;
1798 delta[i][i] = (p2[i] - p1[i]);
1803 std::vector<Point<spacedim>> points;
1807 for (
unsigned int x = 0; x <= repetitions[0]; ++x)
1808 points.push_back(p1 + x * delta[0]);
1812 for (
unsigned int y = 0; y <= repetitions[1]; ++y)
1813 for (
unsigned int x = 0; x <= repetitions[0]; ++x)
1814 points.push_back(p1 + x * delta[0] + y * delta[1]);
1818 for (
unsigned int z = 0; z <= repetitions[2]; ++z)
1819 for (
unsigned int y = 0; y <= repetitions[1]; ++y)
1820 for (
unsigned int x = 0; x <= repetitions[0]; ++x)
1821 points.push_back(p1 + x * delta[0] + y * delta[1] +
1831 std::vector<CellData<dim>> cells;
1836 cells.resize(repetitions[1] * repetitions[0] - holes[1] * holes[0]);
1838 for (
unsigned int y = 0; y < repetitions[1]; ++y)
1839 for (
unsigned int x = 0; x < repetitions[0]; ++x)
1841 if ((x % 2 == 1) && (y % 2 == 1))
1844 cells[c].vertices[0] = y * (repetitions[0] + 1) + x;
1845 cells[c].vertices[1] = y * (repetitions[0] + 1) + x + 1;
1846 cells[c].vertices[2] = (y + 1) * (repetitions[0] + 1) + x;
1847 cells[c].vertices[3] = (y + 1) * (repetitions[0] + 1) + x + 1;
1848 cells[c].material_id = 0;
1856 const unsigned int n_x = (repetitions[0] + 1);
1857 const unsigned int n_xy =
1858 (repetitions[0] + 1) * (repetitions[1] + 1);
1860 cells.resize(repetitions[2] * repetitions[1] * repetitions[0]);
1863 for (
unsigned int z = 0; z < repetitions[2]; ++z)
1864 for (
unsigned int y = 0; y < repetitions[1]; ++y)
1865 for (
unsigned int x = 0; x < repetitions[0]; ++x)
1868 cells[c].vertices[0] = z * n_xy + y * n_x + x;
1869 cells[c].vertices[1] = z * n_xy + y * n_x + x + 1;
1870 cells[c].vertices[2] = z * n_xy + (y + 1) * n_x + x;
1871 cells[c].vertices[3] = z * n_xy + (y + 1) * n_x + x + 1;
1872 cells[c].vertices[4] = (z + 1) * n_xy + y * n_x + x;
1873 cells[c].vertices[5] = (z + 1) * n_xy + y * n_x + x + 1;
1874 cells[c].vertices[6] = (z + 1) * n_xy + (y + 1) * n_x + x;
1875 cells[c].vertices[7] =
1876 (z + 1) * n_xy + (y + 1) * n_x + x + 1;
1877 cells[c].material_id = 0;
1904 const unsigned int ,
1915 const unsigned int ,
1927 bool inline point_in_2d_box(
const Point<2> &p,
1929 const double radius)
1931 return (std::abs(p[0] - c[0]) < radius) &&
1932 (std::abs(p[1] - c[1]) < radius);
1940 template <
int dim,
int spacedim>
1944 double length = std::numeric_limits<double>::max();
1945 for (
const auto &cell : triangulation.active_cell_iterators())
1946 for (
unsigned int n = 0; n < GeometryInfo<dim>::lines_per_cell; ++n)
1947 length = std::min(length, cell->line(n)->diameter());
1956 const double inner_radius,
1957 const double outer_radius,
1958 const double pad_bottom,
1959 const double pad_top,
1960 const double pad_left,
1961 const double pad_right,
1966 const unsigned int ,
1967 const bool colorize)
1969 const bool with_padding =
1970 pad_bottom > 0 || pad_top > 0 || pad_left > 0 || pad_right > 0;
1980 double length = std::numeric_limits<double>::max();
1982 for (
unsigned int n = 0; n < GeometryInfo<2>::lines_per_cell; ++n)
1983 length = std::min(length, cell->line(n)->diameter());
1989 Triangulation<2> &cylinder_tria = with_padding ? cylinder_tria_maybe : tria;
1999 cell->set_manifold_id(tfi_manifold_id);
2001 const Point<2> bl(-outer_radius - pad_left, -outer_radius - pad_bottom);
2002 const Point<2> tr(outer_radius + pad_right, outer_radius + pad_top);
2008 auto add_sizes = [](std::vector<double> &step_sizes,
2009 const double padding,
2010 const double h) ->
void {
2013 const auto rounded =
2014 static_cast<unsigned int>(std::round(padding / h));
2017 const unsigned int num = (padding > 0. && rounded == 0) ? 1 : rounded;
2018 for (
unsigned int i = 0; i < num; ++i)
2019 step_sizes.push_back(padding / num);
2022 std::vector<std::vector<double>> step_sizes(2);
2025 add_sizes(step_sizes[0], pad_left, outer_radius);
2027 step_sizes[0].push_back(outer_radius);
2028 step_sizes[0].push_back(outer_radius);
2030 add_sizes(step_sizes[0], pad_right, outer_radius);
2033 add_sizes(step_sizes[1], pad_bottom, outer_radius);
2035 step_sizes[1].push_back(outer_radius);
2036 step_sizes[1].push_back(outer_radius);
2038 add_sizes(step_sizes[1], pad_top, outer_radius);
2043 bulk_tria, step_sizes, bl, tr, colorize);
2046 std::set<Triangulation<2>::active_cell_iterator> cells_to_remove;
2048 if (internal::point_in_2d_box(cell->center(), center, outer_radius))
2049 cells_to_remove.insert(cell);
2053 bulk_tria, cells_to_remove, tria_without_cylinder);
2055 const double tolerance =
2056 std::min(min_line_length(tria_without_cylinder),
2057 min_line_length(cylinder_tria)) /
2071 if (cell->manifold_id() == tfi_manifold_id)
2073 for (
unsigned int face_n = 0;
2074 face_n < GeometryInfo<2>::faces_per_cell;
2077 const auto &face = cell->face(face_n);
2078 if (face->at_boundary() &&
2079 internal::point_in_2d_box(face->center(),
2082 face->set_manifold_id(polar_manifold_id);
2084 face->set_manifold_id(tfi_manifold_id);
2095 static constexpr
double tol =
2096 std::numeric_limits<double>::epsilon() * 10000;
2099 for (
unsigned int face_n = 0; face_n < GeometryInfo<2>::faces_per_cell;
2102 const auto face = cell->face(face_n);
2103 if (face->at_boundary())
2105 const Point<2> center = face->center();
2107 if (std::abs(center[0] - bl[0]) < tol * std::abs(bl[0]))
2108 face->set_boundary_id(0);
2110 else if (std::abs(center[0] - tr[0]) < tol * std::abs(tr[0]))
2111 face->set_boundary_id(1);
2113 else if (std::abs(center[1] - bl[1]) < tol * std::abs(bl[1]))
2114 face->set_boundary_id(2);
2116 else if (std::abs(center[1] - tr[1]) < tol * std::abs(tr[1]))
2117 face->set_boundary_id(3);
2121 Assert(cell->manifold_id() == tfi_manifold_id,
2123 face->set_boundary_id(4);
2142 const double inner_radius,
2143 const double outer_radius,
2144 const double pad_bottom,
2145 const double pad_top,
2146 const double pad_left,
2147 const double pad_right,
2152 const unsigned int n_slices,
2153 const bool colorize)
2163 Point<2>(new_center[0], new_center[1]),
2179 direction, new_center);
2182 tria.
set_manifold(polar_manifold_id, cylindrical_manifold);
2190 const double shell_region_width,
2191 const unsigned int n_shells,
2192 const double skewness,
2193 const bool colorize)
2195 Assert(0.0 <= shell_region_width && shell_region_width < 0.05,
2196 ExcMessage(
"The width of the shell region must be less than 0.05 " 2197 "(and preferably close to 0.03)"));
2231 std::set<Triangulation<2>::active_cell_iterator> cells_to_remove;
2235 if ((cell->center() -
Point<2>(0.2, 0.2)).
norm() < 0.15)
2236 cells_to_remove.insert(cell);
2240 for (
unsigned int vertex_n = 0;
2241 vertex_n < GeometryInfo<2>::vertices_per_cell;
2243 if (cell->vertex(vertex_n) ==
Point<2>())
2247 cylinder_triangulation_offset =
2248 2.0 * (cell->vertex(3) -
Point<2>());
2255 bulk_tria, cells_to_remove, tria_without_cylinder);
2262 0.05 + shell_region_width,
2268 for (
unsigned int vertex_n = 0;
2269 vertex_n < GeometryInfo<2>::vertices_per_cell;
2272 if (std::abs(cell->vertex(vertex_n)[0] - -0.41 / 4.0) < 1
e-10)
2273 cell->vertex(vertex_n)[0] = -0.1;
2274 else if (std::abs(cell->vertex(vertex_n)[0] - 0.41 / 4.0) < 1
e-10)
2275 cell->vertex(vertex_n)[0] = 0.1;
2281 cell->set_manifold_id(tfi_manifold_id);
2282 for (
unsigned int face_n = 0; face_n < GeometryInfo<2>::faces_per_cell;
2284 if (!cell->face(face_n)->at_boundary())
2285 cell->face(face_n)->set_manifold_id(tfi_manifold_id);
2287 if (0.0 < shell_region_width)
2290 ExcMessage(
"If the shell region has positive width then " 2291 "there must be at least one shell."));
2296 0.05 + shell_region_width,
2303 const double vertex_tolerance =
2304 std::min(internal::minimal_vertex_distance(shell_tria),
2305 internal::minimal_vertex_distance(cylinder_tria)) *
2311 shell_tria, cylinder_tria, temp, vertex_tolerance,
true);
2312 cylinder_tria = std::move(temp);
2318 const double vertex_tolerance =
2319 std::min(internal::minimal_vertex_distance(tria_without_cylinder),
2320 internal::minimal_vertex_distance(cylinder_tria)) /
2323 tria_without_cylinder, cylinder_tria, tria, vertex_tolerance,
true);
2328 if (cell->manifold_id() == polar_manifold_id)
2334 if (cell->manifold_id() != polar_manifold_id &&
2335 cell->manifold_id() != tfi_manifold_id)
2340 std::vector<Point<2> *> cylinder_pointers;
2342 if (face->manifold_id() == polar_manifold_id)
2344 cylinder_pointers.push_back(&face->vertex(0));
2345 cylinder_pointers.push_back(&face->vertex(1));
2348 std::sort(cylinder_pointers.begin(), cylinder_pointers.end());
2349 cylinder_pointers.erase(std::unique(cylinder_pointers.begin(),
2350 cylinder_pointers.end()),
2351 cylinder_pointers.end());
2355 for (
const Point<2> *
const ptr : cylinder_pointers)
2356 center += *ptr / double(cylinder_pointers.size());
2359 for (
Point<2> *
const ptr : cylinder_pointers)
2360 *ptr +=
Point<2>(0.2, 0.2) - center;
2371 if (face->at_boundary())
2373 const Point<2> center = face->center();
2375 if (std::abs(center[0] - 0.0) < 1e-10)
2376 face->set_boundary_id(0);
2378 else if (std::abs(center[0] - 2.2) < 1e-10)
2379 face->set_boundary_id(1);
2381 else if (face->manifold_id() == polar_manifold_id)
2382 face->set_boundary_id(2);
2386 Assert(std::abs(center[1] - 0.00) < 1.0e-10 ||
2387 std::abs(center[1] - 0.41) < 1.0e-10,
2389 face->set_boundary_id(3);
2398 const double shell_region_width,
2399 const unsigned int n_shells,
2400 const double skewness,
2401 const bool colorize)
2405 tria_2, shell_region_width, n_shells, skewness, colorize);
2421 tria.
set_manifold(cylindrical_manifold_id, cylindrical_manifold);
2429 if (face->boundary_id() == 4 || face->boundary_id() == 5)
2430 face->set_boundary_id(3);
2435 template <
int dim,
int spacedim>
2438 const std::vector<unsigned int> &sizes,
2439 const bool colorize)
2448 for (
unsigned int d = 0; d < dim; ++d)
2451 std::vector<Point<spacedim>> points;
2452 unsigned int n_cells = 1;
2453 for (
unsigned int i = 0; i < GeometryInfo<dim>::faces_per_cell; ++i)
2454 n_cells += sizes[i];
2456 std::vector<CellData<dim>> cells(n_cells);
2458 for (
unsigned int i = 0; i < GeometryInfo<dim>::vertices_per_cell; ++i)
2461 for (
unsigned int d = 0; d < dim; ++d)
2462 p(d) = 0.5 * dimensions[d] *
2465 points.push_back(p);
2466 cells[0].vertices[i] = i;
2468 cells[0].material_id = 0;
2471 unsigned int cell_index = 1;
2473 for (
unsigned int face = 0; face < GeometryInfo<dim>::faces_per_cell;
2480 for (
unsigned int j = 0; j < sizes[face]; ++j, ++cell_index)
2482 const unsigned int last_cell = (j == 0) ? 0U : (cell_index - 1);
2484 for (
unsigned int v = 0; v < GeometryInfo<dim>::vertices_per_face;
2487 const unsigned int cellv =
2489 const unsigned int ocellv =
2492 cells[cell_index].vertices[ocellv] =
2493 cells[last_cell].vertices[cellv];
2496 cells[cell_index].vertices[cellv] = points.size();
2501 points.push_back(p);
2503 cells[cell_index].material_id = (colorize) ? (face + 1U) : 0U;
2629 const double thickness,
2630 const bool colorize)
2633 ExcMessage(
"Invalid left-to-right bounds of enclosed hypercube"));
2635 std::vector<Point<2>> vertices(16);
2637 coords[0] = left - thickness;
2640 coords[3] = right + thickness;
2643 for (
const double y : coords)
2644 for (
const double x : coords)
2649 std::vector<CellData<2>> cells(9);
2651 for (
unsigned int i0 = 0; i0 < 3; ++i0)
2652 for (
unsigned int i1 = 0; i1 < 3; ++i1)
2654 cells[k].vertices[0] = i1 + 4 * i0;
2655 cells[k].vertices[1] = i1 + 4 * i0 + 1;
2656 cells[k].vertices[2] = i1 + 4 * i0 + 4;
2657 cells[k].vertices[3] = i1 + 4 * i0 + 5;
2659 cells[k].material_id = materials[k];
2674 const bool colorize)
2676 const double rl2 = (right + left) / 2;
2687 const int cell_vertices[4][4] = {{0, 1, 3, 2},
2692 for (
unsigned int i = 0; i < 4; ++i)
2694 for (
unsigned int j = 0; j < 4; ++j)
2695 cells[i].vertices[j] = cell_vertices[i][j];
2696 cells[i].material_id = 0;
2699 std::end(vertices)),
2706 cell->face(1)->set_boundary_id(1);
2708 cell->face(0)->set_boundary_id(2);
2716 const double radius_0,
2717 const double radius_1,
2718 const double half_length)
2722 vertices_tmp[0] =
Point<2>(-half_length, -radius_0);
2723 vertices_tmp[1] =
Point<2>(half_length, -radius_1);
2724 vertices_tmp[2] =
Point<2>(-half_length, radius_0);
2725 vertices_tmp[3] =
Point<2>(half_length, radius_1);
2727 const std::vector<Point<2>> vertices(std::begin(vertices_tmp),
2728 std::end(vertices_tmp));
2731 for (
unsigned int i = 0; i < GeometryInfo<2>::vertices_per_cell; ++i)
2732 cell_vertices[0][i] = i;
2736 for (
unsigned int i = 0; i < GeometryInfo<2>::vertices_per_cell; ++i)
2737 cells[0].vertices[i] = cell_vertices[0][i];
2739 cells[0].material_id = 0;
2740 triangulation.create_triangulation(vertices, cells,
SubCellData());
2744 cell->face(0)->set_boundary_id(1);
2745 cell->face(1)->set_boundary_id(2);
2747 for (
unsigned int i = 2; i < 4; ++i)
2748 cell->face(i)->set_boundary_id(0);
2758 const bool colorize)
2768 const int cell_vertices[3][4] = {{0, 1, 3, 4}, {1, 2, 4, 5}, {3, 4, 6, 7}};
2772 for (
unsigned int i = 0; i < 3; ++i)
2774 for (
unsigned int j = 0; j < 4; ++j)
2775 cells[i].vertices[j] = cell_vertices[i][j];
2776 cells[i].material_id = 0;
2780 std::end(vertices)),
2788 cell->face(0)->set_boundary_id(0);
2789 cell->face(2)->set_boundary_id(1);
2792 cell->face(1)->set_boundary_id(2);
2793 cell->face(2)->set_boundary_id(1);
2794 cell->face(3)->set_boundary_id(3);
2797 cell->face(0)->set_boundary_id(0);
2798 cell->face(1)->set_boundary_id(4);
2799 cell->face(3)->set_boundary_id(5);
2809 const double radius,
2810 const bool internal_manifolds)
2815 const double a = 1. / (1 + std::sqrt(2.0));
2817 p +
Point<2>(-1, -1) * (radius / std::sqrt(2.0)),
2818 p +
Point<2>(+1, -1) * (radius / std::sqrt(2.0)),
2819 p +
Point<2>(-1, -1) * (radius / std::sqrt(2.0) * a),
2820 p +
Point<2>(+1, -1) * (radius / std::sqrt(2.0) * a),
2821 p +
Point<2>(-1, +1) * (radius / std::sqrt(2.0) * a),
2822 p +
Point<2>(+1, +1) * (radius / std::sqrt(2.0) * a),
2823 p +
Point<2>(-1, +1) * (radius / std::sqrt(2.0)),
2824 p +
Point<2>(+1, +1) * (radius / std::sqrt(2.0))};
2826 const int cell_vertices[5][4] = {
2827 {0, 1, 2, 3}, {0, 2, 6, 4}, {2, 3, 4, 5}, {1, 7, 3, 5}, {6, 4, 7, 5}};
2831 for (
unsigned int i = 0; i < 5; ++i)
2833 for (
unsigned int j = 0; j < 4; ++j)
2834 cells[i].vertices[j] = cell_vertices[i][j];
2835 cells[i].material_id = 0;
2840 std::end(vertices)),
2845 if (internal_manifolds)
2854 const double inner_radius,
2855 const double outer_radius,
2856 const unsigned int n_cells,
2857 const bool colorize)
2859 Assert((inner_radius > 0) && (inner_radius < outer_radius),
2873 const unsigned int N =
2874 (n_cells == 0 ?
static_cast<unsigned int>(
2875 std::ceil((2 * pi * (outer_radius + inner_radius) / 2) /
2876 (outer_radius - inner_radius))) :
2885 std::vector<Point<2>> vertices(2 * N);
2886 for (
unsigned int i = 0; i < N; ++i)
2889 Point<2>(std::cos(2 * pi * i / N), std::sin(2 * pi * i / N)) *
2891 vertices[i + N] = vertices[i] * (inner_radius / outer_radius);
2893 vertices[i] += center;
2894 vertices[i + N] += center;
2899 for (
unsigned int i = 0; i < N; ++i)
2901 cells[i].vertices[0] = i;
2902 cells[i].vertices[1] = (i + 1) % N;
2903 cells[i].vertices[2] = N + i;
2904 cells[i].vertices[3] = N + ((i + 1) % N);
2906 cells[i].material_id = 0;
2912 colorize_hyper_shell(tria, center, inner_radius, outer_radius);
2922 const double radius,
2923 const double half_length)
2925 Point<2> p1(-half_length, -radius);
2934 switch (f->boundary_id())
2937 f->set_boundary_id(1);
2940 f->set_boundary_id(2);
2943 f->set_boundary_id(0);
2968 const double radius)
2970 const unsigned int dim = 2;
2980 (radius / (2 * std::sqrt(2.0))),
2983 (radius / std::sqrt(2.0))};
2985 const int cell_vertices[3][4] = {{0, 2, 3, 4}, {1, 6, 2, 4}, {5, 3, 6, 4}};
2989 for (
unsigned int i = 0; i < 3; ++i)
2991 for (
unsigned int j = 0; j < 4; ++j)
2992 cells[i].vertices[j] = cell_vertices[i][j];
2993 cells[i].material_id = 0;
2997 std::end(vertices)),
3008 for (
unsigned int i = 0; i < GeometryInfo<dim>::faces_per_cell; ++i)
3010 if (cell->face(i)->boundary_id() ==
3016 if (cell->face(i)->center()(0) < p(0) + 1.e-5 * radius ||
3017 cell->face(i)->center()(1) < p(1) + 1.e-5 * radius)
3019 cell->face(i)->set_boundary_id(1);
3032 const double radius)
3037 const double a = 1. / (1 + std::sqrt(2.0));
3040 p +
Point<2>(+1, -1) * (radius / std::sqrt(2.0)),
3041 p +
Point<2>(0, -1) * (radius / std::sqrt(2.0) * a),
3042 p +
Point<2>(+1, -1) * (radius / std::sqrt(2.0) * a),
3043 p +
Point<2>(0, +1) * (radius / std::sqrt(2.0) * a),
3044 p +
Point<2>(+1, +1) * (radius / std::sqrt(2.0) * a),
3046 p +
Point<2>(+1, +1) * (radius / std::sqrt(2.0))};
3048 const int cell_vertices[5][4] = {{0, 1, 2, 3},
3055 for (
unsigned int i = 0; i < 4; ++i)
3057 for (
unsigned int j = 0; j < 4; ++j)
3058 cells[i].vertices[j] = cell_vertices[i][j];
3059 cells[i].material_id = 0;
3063 std::end(vertices)),
3074 for (
unsigned int i = 0; i < GeometryInfo<2>::faces_per_cell; ++i)
3076 if (cell->face(i)->boundary_id() ==
3081 if (cell->face(i)->center()(0) < p(0) + 1.e-5 * radius)
3083 cell->face(i)->set_boundary_id(1);
3098 const double inner_radius,
3099 const double outer_radius,
3100 const unsigned int n_cells,
3101 const bool colorize)
3103 Assert((inner_radius > 0) && (inner_radius < outer_radius),
3116 const unsigned int N =
3117 (n_cells == 0 ?
static_cast<unsigned int>(
3118 std::ceil((pi * (outer_radius + inner_radius) / 2) /
3119 (outer_radius - inner_radius))) :
3128 std::vector<Point<2>> vertices(2 * (N + 1));
3129 for (
unsigned int i = 0; i <= N; ++i)
3138 Point<2>(((i == 0) || (i == N) ? 0 : std::cos(pi * i / N - pi / 2)),
3139 std::sin(pi * i / N - pi / 2)) *
3141 vertices[i + N + 1] = vertices[i] * (inner_radius / outer_radius);
3143 vertices[i] += center;
3144 vertices[i + N + 1] += center;
3150 for (
unsigned int i = 0; i < N; ++i)
3152 cells[i].vertices[0] = i;
3153 cells[i].vertices[1] = (i + 1) % (N + 1);
3154 cells[i].vertices[2] = N + 1 + i;
3155 cells[i].vertices[3] = N + 1 + ((i + 1) % (N + 1));
3157 cells[i].material_id = 0;
3165 for (; cell != tria.
end(); ++cell)
3167 cell->face(2)->set_boundary_id(1);
3169 tria.
begin()->face(0)->set_boundary_id(3);
3171 tria.
last()->face(1)->set_boundary_id(2);
3181 const double inner_radius,
3182 const double outer_radius,
3183 const unsigned int n_cells,
3184 const bool colorize)
3186 Assert((inner_radius > 0) && (inner_radius < outer_radius),
3199 const unsigned int N =
3200 (n_cells == 0 ?
static_cast<unsigned int>(
3201 std::ceil((pi * (outer_radius + inner_radius) / 4) /
3202 (outer_radius - inner_radius))) :
3211 std::vector<Point<2>> vertices(2 * (N + 1));
3212 for (
unsigned int i = 0; i <= N; ++i)
3219 vertices[i] =
Point<2>(((i == N) ? 0 : std::cos(pi * i / N / 2)),
3220 std::sin(pi * i / N / 2)) *
3222 vertices[i + N + 1] = vertices[i] * (inner_radius / outer_radius);
3224 vertices[i] += center;
3225 vertices[i + N + 1] += center;
3231 for (
unsigned int i = 0; i < N; ++i)
3233 cells[i].vertices[0] = i;
3234 cells[i].vertices[1] = (i + 1) % (N + 1);
3235 cells[i].vertices[2] = N + 1 + i;
3236 cells[i].vertices[3] = N + 1 + ((i + 1) % (N + 1));
3238 cells[i].material_id = 0;
3246 for (; cell != tria.
end(); ++cell)
3248 cell->face(2)->set_boundary_id(1);
3250 tria.
begin()->face(0)->set_boundary_id(3);
3252 tria.
last()->face(1)->set_boundary_id(2);
3266 const bool colorize)
3268 const double rl2 = (right + left) / 2;
3269 const double len = (right - left) / 2.;
3282 const int cell_vertices[4][8] = {{0, 1, 3, 2, 10, 11, 13, 12},
3283 {9, 4, 2, 5, 19, 14, 12, 15},
3284 {3, 2, 7, 6, 13, 12, 17, 16},
3285 {2, 5, 6, 8, 12, 15, 16, 18}};
3287 for (
unsigned int i = 0; i < 4; ++i)
3289 for (
unsigned int j = 0; j < 8; ++j)
3290 cells[i].vertices[j] = cell_vertices[i][j];
3291 cells[i].material_id = 0;
3294 std::end(vertices)),
3301 cell->face(1)->set_boundary_id(1);
3303 cell->face(0)->set_boundary_id(2);
3314 const double thickness,
3315 const bool colorize)
3318 ExcMessage(
"Invalid left-to-right bounds of enclosed hypercube"));
3320 std::vector<Point<3>> vertices(64);
3322 coords[0] = left - thickness;
3325 coords[3] = right + thickness;
3328 for (
const double z : coords)
3329 for (
const double y : coords)
3330 for (
const double x : coords)
3334 24, 26, 5, 4, 6, 1, 0,
3335 2, 9, 8, 10, 37, 36, 38,
3336 33, 32, 34, 41, 40, 42};
3338 std::vector<CellData<3>> cells(27);
3340 for (
unsigned int z = 0; z < 3; ++z)
3341 for (
unsigned int y = 0; y < 3; ++y)
3342 for (
unsigned int x = 0; x < 3; ++x)
3344 cells[k].vertices[0] = x + 4 * y + 16 * z;
3345 cells[k].vertices[1] = x + 4 * y + 16 * z + 1;
3346 cells[k].vertices[2] = x + 4 * y + 16 * z + 4;
3347 cells[k].vertices[3] = x + 4 * y + 16 * z + 5;
3348 cells[k].vertices[4] = x + 4 * y + 16 * z + 16;
3349 cells[k].vertices[5] = x + 4 * y + 16 * z + 17;
3350 cells[k].vertices[6] = x + 4 * y + 16 * z + 20;
3351 cells[k].vertices[7] = x + 4 * y + 16 * z + 21;
3353 cells[k].material_id = materials[k];
3365 const double radius_0,
3366 const double radius_1,
3367 const double half_length)
3369 Assert(triangulation.n_cells() == 0,
3370 ExcMessage(
"The output triangulation object needs to be empty."));
3375 const auto n_slices = 1 +
static_cast<unsigned int>(std::ceil(
3376 half_length / std::max(radius_0, radius_1)));
3389 auto shift_radii = [=](
const Point<3> &p) {
3390 const double slope = (radius_1 / radius_0 - 1.0) / (2.0 * half_length);
3391 const double factor = slope * (p[0] - -half_length) + 1.0;
3392 return Point<3>(p[0], factor * p[1], factor * p[2]);
3398 for (
const auto &face : triangulation.active_face_iterators())
3399 if (face->at_boundary())
3401 if (std::abs(face->center()[0] - -half_length) < 1e-8 * half_length)
3402 face->set_boundary_id(1);
3403 else if (std::abs(face->center()[0] - half_length) <
3405 face->set_boundary_id(2);
3407 face->set_all_manifold_ids(0);
3419 const bool colorize)
3439 Point<3>((a + b) / 2, (a +
b) / 2, (a + b) / 2),
3454 const int cell_vertices[7][8] = {{0, 1, 9, 10, 3, 4, 12, 13},
3455 {1, 2, 10, 11, 4, 5, 13, 14},
3456 {3, 4, 12, 13, 6, 7, 15, 16},
3457 {4, 5, 13, 14, 7, 8, 16, 17},
3458 {9, 10, 18, 19, 12, 13, 21, 22},
3459 {10, 11, 19, 20, 13, 14, 22, 23},
3460 {12, 13, 21, 22, 15, 16, 24, 25}};
3464 for (
unsigned int i = 0; i < 7; ++i)
3466 for (
unsigned int j = 0; j < 8; ++j)
3467 cells[i].vertices[j] = cell_vertices[i][j];
3468 cells[i].material_id = 0;
3472 std::end(vertices)),
3488 const double radius,
3489 const bool internal_manifold)
3492 1. / (1 + std::sqrt(3.0));
3495 const unsigned int n_vertices = 16;
3496 const Point<3> vertices[n_vertices] = {
3499 p +
Point<3>(-1, -1, -1) * (radius / std::sqrt(3.0) * a),
3500 p +
Point<3>(+1, -1, -1) * (radius / std::sqrt(3.0) * a),
3501 p +
Point<3>(+1, -1, +1) * (radius / std::sqrt(3.0) * a),
3502 p +
Point<3>(-1, -1, +1) * (radius / std::sqrt(3.0) * a),
3503 p +
Point<3>(-1, +1, -1) * (radius / std::sqrt(3.0) * a),
3504 p +
Point<3>(+1, +1, -1) * (radius / std::sqrt(3.0) * a),
3505 p +
Point<3>(+1, +1, +1) * (radius / std::sqrt(3.0) * a),
3506 p +
Point<3>(-1, +1, +1) * (radius / std::sqrt(3.0) * a),
3509 p +
Point<3>(-1, -1, -1) * (radius / std::sqrt(3.0)),
3510 p +
Point<3>(+1, -1, -1) * (radius / std::sqrt(3.0)),
3511 p +
Point<3>(+1, -1, +1) * (radius / std::sqrt(3.0)),
3512 p +
Point<3>(-1, -1, +1) * (radius / std::sqrt(3.0)),
3513 p +
Point<3>(-1, +1, -1) * (radius / std::sqrt(3.0)),
3514 p +
Point<3>(+1, +1, -1) * (radius / std::sqrt(3.0)),
3515 p +
Point<3>(+1, +1, +1) * (radius / std::sqrt(3.0)),
3516 p +
Point<3>(-1, +1, +1) * (radius / std::sqrt(3.0)),
3521 const unsigned int n_cells = 7;
3522 const int cell_vertices[n_cells][8] = {
3523 {0, 1, 4, 5, 3, 2, 7, 6},
3524 {8, 9, 12, 13, 0, 1, 4, 5},
3525 {9, 13, 1, 5, 10, 14, 2, 6},
3526 {11, 10, 3, 2, 15, 14, 7, 6},
3527 {8, 0, 12, 4, 11, 3, 15, 7},
3528 {8, 9, 0, 1, 11, 10, 3, 2},
3529 {12, 4, 13, 5, 15, 7, 14, 6}};
3531 std::vector<CellData<3>> cells(n_cells,
CellData<3>());
3533 for (
unsigned int i = 0; i < n_cells; ++i)
3535 for (
unsigned int j = 0; j < GeometryInfo<3>::vertices_per_cell; ++j)
3536 cells[i].vertices[j] = cell_vertices[i][j];
3537 cells[i].material_id = 0;
3542 std::end(vertices)),
3547 if (internal_manifold)
3553 template <
int spacedim>
3556 const double radius)
3560 std::set<types::boundary_id> boundary_ids;
3561 boundary_ids.insert(0);
3572 const double radius,
3573 const double half_length)
3577 const double d = radius / std::sqrt(2.0);
3578 const double a = d / (1 + std::sqrt(2.0));
3606 for (
auto &vertex : vertices)
3608 const double h = vertex(1);
3609 vertex(1) = -vertex(0);
3613 int cell_vertices[10][8] = {{0, 1, 8, 9, 2, 3, 10, 11},
3614 {0, 2, 8, 10, 6, 4, 14, 12},
3615 {2, 3, 10, 11, 4, 5, 12, 13},
3616 {1, 7, 9, 15, 3, 5, 11, 13},
3617 {6, 4, 14, 12, 7, 5, 15, 13}};
3618 for (
unsigned int i = 0; i < 5; ++i)
3619 for (
unsigned int j = 0; j < 8; ++j)
3620 cell_vertices[i + 5][j] = cell_vertices[i][j] + 8;
3622 std::vector<CellData<3>> cells(10,
CellData<3>());
3624 for (
unsigned int i = 0; i < 10; ++i)
3626 for (
unsigned int j = 0; j < 8; ++j)
3627 cells[i].vertices[j] = cell_vertices[i][j];
3628 cells[i].material_id = 0;
3632 std::end(vertices)),
3651 for (; cell != end; ++cell)
3652 for (
unsigned int i = 0; i < GeometryInfo<3>::faces_per_cell; ++i)
3653 if (cell->at_boundary(i))
3655 if (cell->face(i)->center()(0) > half_length - 1.e-5)
3657 cell->face(i)->set_boundary_id(2);
3660 for (
unsigned int e = 0; e < GeometryInfo<3>::lines_per_face;
3662 if ((std::fabs(cell->face(i)->line(e)->vertex(0)[1]) == a) ||
3663 (std::fabs(cell->face(i)->line(e)->vertex(0)[2]) == a) ||
3664 (std::fabs(cell->face(i)->line(e)->vertex(1)[1]) == a) ||
3665 (std::fabs(cell->face(i)->line(e)->vertex(1)[2]) == a))
3667 cell->face(i)->line(e)->set_boundary_id(2);
3668 cell->face(i)->line(e)->set_manifold_id(
3672 else if (cell->face(i)->center()(0) < -half_length + 1.e-5)
3674 cell->face(i)->set_boundary_id(1);
3677 for (
unsigned int e = 0; e < GeometryInfo<3>::lines_per_face;
3679 if ((std::fabs(cell->face(i)->line(e)->vertex(0)[1]) == a) ||
3680 (std::fabs(cell->face(i)->line(e)->vertex(0)[2]) == a) ||
3681 (std::fabs(cell->face(i)->line(e)->vertex(1)[1]) == a) ||
3682 (std::fabs(cell->face(i)->line(e)->vertex(1)[2]) == a))
3684 cell->face(i)->line(e)->set_boundary_id(1);
3685 cell->face(i)->line(e)->set_manifold_id(
3697 const double radius)
3699 const unsigned int dim = 3;
3707 center +
Point<dim>(+1, 0, 0) * (radius / 2.),
3708 center +
Point<dim>(0, +1, 0) * (radius / 2.),
3709 center +
Point<dim>(+1, +1, 0) * (radius / (2 * std::sqrt(2.0))),
3711 center +
Point<dim>(+1, +1, 0) * (radius / std::sqrt(2.0)),
3713 center +
Point<dim>(+1, 0, 1) * radius / std::sqrt(2.0),
3714 center +
Point<dim>(+1, 0, 1) * (radius / (2 * std::sqrt(2.0))),
3715 center +
Point<dim>(0, +1, 1) * (radius / (2 * std::sqrt(2.0))),
3716 center +
Point<dim>(+1, +1, 1) * (radius / (2 * std::sqrt(3.0))),
3717 center +
Point<dim>(0, +1, 1) * radius / std::sqrt(2.0),
3718 center +
Point<dim>(+1, +1, 1) * (radius / (std::sqrt(3.0))),
3720 const int cell_vertices[4][8] = {{0, 2, 3, 4, 7, 9, 10, 11},
3721 {1, 6, 2, 4, 8, 13, 9, 11},
3722 {5, 3, 6, 4, 12, 10, 13, 11},
3723 {7, 9, 10, 11, 14, 8, 12, 13}};
3727 for (
unsigned int i = 0; i < 4; ++i)
3729 for (
unsigned int j = 0; j < 8; ++j)
3730 cells[i].vertices[j] = cell_vertices[i][j];
3731 cells[i].material_id = 0;
3735 std::end(vertices)),
3745 for (
unsigned int i = 0; i < GeometryInfo<dim>::faces_per_cell; ++i)
3747 if (cell->face(i)->boundary_id() ==
3752 if (cell->face(i)->center()(0) < center(0) + 1.e-5 * radius ||
3753 cell->face(i)->center()(1) < center(1) + 1.e-5 * radius ||
3754 cell->face(i)->center()(2) < center(2) + 1.e-5 * radius)
3756 cell->face(i)->set_boundary_id(1);
3760 for (
unsigned int j = 0; j < GeometryInfo<3>::lines_per_face;
3763 const Point<3> line_vertices[2] = {
3764 cell->face(i)->line(j)->vertex(0),
3765 cell->face(i)->line(j)->vertex(1)};
3766 if ((std::fabs(line_vertices[0].distance(center) - radius) >
3768 (std::fabs(line_vertices[1].distance(center) - radius) >
3771 cell->face(i)->line(j)->set_boundary_id(1);
3772 cell->face(i)->line(j)->set_manifold_id(
3788 const double radius)
3791 const double d = radius / std::sqrt(2.0);
3792 const double a =
d / (1 + std::sqrt(2.0));
3794 const double b = a / 2.0;
3795 const double c =
d / 2.0;
3797 const double hb = radius * std::sqrt(3.0) / 4.0;
3798 const double hc = radius * std::sqrt(3.0) / 2.0;
3820 int cell_vertices[6][8] = {{0, 1, 8, 9, 2, 3, 10, 11},
3821 {0, 2, 8, 10, 6, 4, 14, 12},
3822 {2, 3, 10, 11, 4, 5, 12, 13},
3823 {1, 7, 9, 15, 3, 5, 11, 13},
3824 {6, 4, 14, 12, 7, 5, 15, 13},
3825 {8, 10, 9, 11, 14, 12, 15, 13}};
3829 for (
unsigned int i = 0; i < 6; ++i)
3831 for (
unsigned int j = 0; j < 8; ++j)
3832 cells[i].vertices[j] = cell_vertices[i][j];
3833 cells[i].material_id = 0;
3837 std::end(vertices)),
3853 for (
unsigned int i = 0; i < GeometryInfo<3>::faces_per_cell; ++i)
3855 if (!cell->at_boundary(i))
3861 if (cell->face(i)->center()(0) < center(0) + 1.e-5 * radius)
3863 cell->face(i)->set_boundary_id(1);
3865 for (
unsigned int j = 0; j < GeometryInfo<3>::lines_per_face;
3868 const Point<3> line_vertices[2] = {
3869 cell->face(i)->line(j)->vertex(0),
3870 cell->face(i)->line(j)->vertex(1)};
3871 if ((std::fabs(line_vertices[0].distance(center) - radius) >
3873 (std::fabs(line_vertices[1].distance(center) - radius) >
3876 cell->face(i)->line(j)->set_boundary_id(1);
3877 cell->face(i)->line(j)->set_manifold_id(
3892 const double inner_radius,
3893 const double outer_radius,
3894 const unsigned int n_cells,
3895 const bool colorize)
3897 Assert((inner_radius > 0) && (inner_radius < outer_radius),
3900 const unsigned int n = (n_cells == 0) ? 6 : n_cells;
3902 const double irad = inner_radius / std::sqrt(3.0);
3903 const double orad = outer_radius / std::sqrt(3.0);
3904 std::vector<Point<3>> vertices;
3905 std::vector<CellData<3>> cells;
3908 static const std::array<Point<3>, 8> hexahedron = {{{-1, -1, -1},
3921 for (
unsigned int i = 0; i < 8; ++i)
3922 vertices.push_back(p + hexahedron[i] * irad);
3923 for (
unsigned int i = 0; i < 8; ++i)
3924 vertices.push_back(p + hexahedron[i] * orad);
3926 const unsigned int n_cells = 6;
3927 const int cell_vertices[n_cells][8] = {
3928 {8, 9, 10, 11, 0, 1, 2, 3},
3929 {9, 11, 1, 3, 13, 15, 5, 7},
3930 {12, 13, 4, 5, 14, 15, 6, 7},
3931 {8, 0, 10, 2, 12, 4, 14, 6},
3932 {8, 9, 0, 1, 12, 13, 4, 5},
3933 {10, 2, 11, 3, 14, 6, 15, 7}};
3937 for (
unsigned int i = 0; i < n_cells; ++i)
3939 for (
unsigned int j = 0; j < GeometryInfo<3>::vertices_per_cell;
3941 cells[i].vertices[j] = cell_vertices[i][j];
3942 cells[i].material_id = 0;
3954 static const std::array<Point<3>, 6> octahedron = {{{-1, 0, 0},
3961 for (
unsigned int i = 0; i < 8; ++i)
3962 vertices.push_back(p + hexahedron[i] * irad);
3963 for (
unsigned int i = 0; i < 6; ++i)
3964 vertices.push_back(p + octahedron[i] * inner_radius);
3965 for (
unsigned int i = 0; i < 8; ++i)
3966 vertices.push_back(p + hexahedron[i] * orad);
3967 for (
unsigned int i = 0; i < 6; ++i)
3968 vertices.push_back(p + octahedron[i] * outer_radius);
3970 const unsigned int n_cells = 12;
3971 const unsigned int rhombi[n_cells][4] = {{10, 4, 0, 8},
3986 for (
unsigned int i = 0; i < n_cells; ++i)
3988 for (
unsigned int j = 0; j < 4; ++j)
3990 cells[i].vertices[j] = rhombi[i][j];
3991 cells[i].vertices[j + 4] = rhombi[i][j] + 14;
3993 cells[i].material_id = 0;
4005 hyper_shell(tmp, p, inner_radius, outer_radius, 12);
4014 const unsigned int cell_index = cell->active_cell_index();
4015 for (
unsigned int v = 0; v < GeometryInfo<3>::vertices_per_cell;
4017 cells[cell_index].vertices[v] = cell->vertex_index(v);
4018 cells[cell_index].material_id = 0;
4029 colorize_hyper_shell(tria, p, inner_radius, outer_radius);
4040 const double inner_radius,
4041 const double outer_radius,
4042 const unsigned int n,
4043 const bool colorize)
4045 Assert((inner_radius > 0) && (inner_radius < outer_radius),
4051 const double d = outer_radius / std::sqrt(2.0);
4052 const double a = inner_radius / std::sqrt(2.0);
4054 const double b = a / 2.0;
4055 const double c =
d / 2.0;
4057 const double hb = inner_radius * std::sqrt(3.0) / 2.0;
4058 const double hc = outer_radius * std::sqrt(3.0) / 2.0;
4080 int cell_vertices[5][8] = {{0, 1, 8, 9, 2, 3, 10, 11},
4081 {0, 2, 8, 10, 6, 4, 14, 12},
4082 {1, 7, 9, 15, 3, 5, 11, 13},
4083 {6, 4, 14, 12, 7, 5, 15, 13},
4084 {8, 10, 9, 11, 14, 12, 15, 13}};
4088 for (
unsigned int i = 0; i < 5; ++i)
4090 for (
unsigned int j = 0; j < 8; ++j)
4091 cells[i].vertices[j] = cell_vertices[i][j];
4092 cells[i].material_id = 0;
4096 std::end(vertices)),
4110 for (; cell != tria.
end(); ++cell)
4111 for (
unsigned int i = 0; i < GeometryInfo<3>::faces_per_cell; ++i)
4112 if (cell->at_boundary(i))
4113 cell->face(i)->set_all_boundary_ids(2);
4119 for (cell = tria.
begin(); cell != tria.
end(); ++cell)
4120 for (
unsigned int i = 0; i < GeometryInfo<3>::faces_per_cell; ++i)
4121 if (cell->at_boundary(i))
4125 const Point<3> face_center(face->center());
4126 if (std::abs(face_center(0) - center(0)) >
4127 1.e-6 * face_center.
norm())
4129 if (std::abs((face_center - center).
norm() - inner_radius) <
4130 std::abs((face_center - center).
norm() - outer_radius))
4131 face->set_all_boundary_ids(0);
4133 face->set_all_boundary_ids(1);
4146 const double inner_radius,
4147 const double outer_radius,
4148 const unsigned int n,
4149 const bool colorize)
4151 Assert((inner_radius > 0) && (inner_radius < outer_radius),
4153 if (n == 0 || n == 3)
4155 const double a = inner_radius * std::sqrt(2.0) / 2e0;
4156 const double b = outer_radius * std::sqrt(2.0) / 2e0;
4157 const double c = a * std::sqrt(3.0) / 2e0;
4158 const double d =
b * std::sqrt(3.0) / 2e0;
4159 const double e = outer_radius / 2e0;
4160 const double h = inner_radius / 2e0;
4162 std::vector<Point<3>> vertices;
4164 vertices.push_back(center +
Point<3>(0, inner_radius, 0));
4165 vertices.push_back(center +
Point<3>(a, a, 0));
4166 vertices.push_back(center +
Point<3>(b, b, 0));
4167 vertices.push_back(center +
Point<3>(0, outer_radius, 0));
4168 vertices.push_back(center +
Point<3>(0, a, a));
4169 vertices.push_back(center +
Point<3>(c, c, h));
4170 vertices.push_back(center +
Point<3>(d, d, e));
4171 vertices.push_back(center +
Point<3>(0, b, b));
4172 vertices.push_back(center +
Point<3>(inner_radius, 0, 0));
4173 vertices.push_back(center +
Point<3>(outer_radius, 0, 0));
4174 vertices.push_back(center +
Point<3>(a, 0, a));
4175 vertices.push_back(center +
Point<3>(b, 0, b));
4176 vertices.push_back(center +
Point<3>(0, 0, inner_radius));
4177 vertices.push_back(center +
Point<3>(0, 0, outer_radius));
4179 const int cell_vertices[3][8] = {
4180 {0, 1, 3, 2, 4, 5, 7, 6},
4181 {1, 8, 2, 9, 5, 10, 6, 11},
4182 {4, 5, 7, 6, 12, 10, 13, 11},
4184 std::vector<CellData<3>> cells(3);
4186 for (
unsigned int i = 0; i < 3; ++i)
4188 for (
unsigned int j = 0; j < 8; ++j)
4189 cells[i].vertices[j] = cell_vertices[i][j];
4190 cells[i].material_id = 0;
4203 colorize_quarter_hyper_shell(tria, center, inner_radius, outer_radius);
4213 const double length,
4214 const double inner_radius,
4215 const double outer_radius,
4216 const unsigned int n_radial_cells,
4217 const unsigned int n_axial_cells)
4219 Assert((inner_radius > 0) && (inner_radius < outer_radius),
4233 const unsigned int N_r =
4234 (n_radial_cells == 0 ?
static_cast<unsigned int>(std::ceil(
4235 (2 * pi * (outer_radius + inner_radius) / 2) /
4236 (outer_radius - inner_radius))) :
4238 const unsigned int N_z =
4239 (n_axial_cells == 0 ?
4240 static_cast<unsigned int>(std::ceil(
4241 length / (2 * pi * (outer_radius + inner_radius) / 2 / N_r))) :
4250 std::vector<Point<2>> vertices_2d(2 * N_r);
4251 for (
unsigned int i = 0; i < N_r; ++i)
4254 Point<2>(std::cos(2 * pi * i / N_r), std::sin(2 * pi * i / N_r)) *
4256 vertices_2d[i + N_r] = vertices_2d[i] * (inner_radius / outer_radius);
4259 std::vector<Point<3>> vertices_3d;
4260 vertices_3d.reserve(2 * N_r * (N_z + 1));
4261 for (
unsigned int j = 0; j <= N_z; ++j)
4262 for (
unsigned int i = 0; i < 2 * N_r; ++i)
4264 const Point<3> v(vertices_2d[i][0],
4267 vertices_3d.push_back(v);
4270 std::vector<CellData<3>> cells(N_r * N_z,
CellData<3>());
4272 for (
unsigned int j = 0; j < N_z; ++j)
4273 for (
unsigned int i = 0; i < N_r; ++i)
4275 cells[i + j * N_r].vertices[0] = i + (j + 1) * 2 * N_r;
4276 cells[i + j * N_r].vertices[1] = (i + 1) % N_r + (j + 1) * 2 * N_r;
4277 cells[i + j * N_r].vertices[2] = i + j * 2 * N_r;
4278 cells[i + j * N_r].vertices[3] = (i + 1) % N_r + j * 2 * N_r;
4280 cells[i + j * N_r].vertices[4] = N_r + i + (j + 1) * 2 * N_r;
4281 cells[i + j * N_r].vertices[5] =
4282 N_r + ((i + 1) % N_r) + (j + 1) * 2 * N_r;
4283 cells[i + j * N_r].vertices[6] = N_r + i + j * 2 * N_r;
4284 cells[i + j * N_r].vertices[7] = N_r + ((i + 1) % N_r) + j * 2 * N_r;
4286 cells[i + j * N_r].material_id = 0;
4296 template <
int dim,
int spacedim>
4302 const double duplicated_vertex_tolerance,
4303 const bool copy_manifold_ids)
4305 std::vector<Point<spacedim>> vertices;
4306 std::vector<CellData<dim>> cells;
4309 unsigned int n_accumulated_vertices = 0;
4310 for (
const auto triangulation : triangulations)
4312 Assert(triangulation->n_levels() == 1,
4313 ExcMessage(
"The input triangulations must be non-empty " 4314 "and must not be refined."));
4316 std::vector<Point<spacedim>> tria_vertices;
4317 std::vector<CellData<dim>> tria_cells;
4319 std::tie(tria_vertices, tria_cells, tria_subcell_data) =
4322 vertices.insert(vertices.end(),
4323 tria_vertices.begin(),
4324 tria_vertices.end());
4327 for (
unsigned int &vertex_n : cell_data.vertices)
4328 vertex_n += n_accumulated_vertices;
4329 cells.push_back(cell_data);
4333 if (copy_manifold_ids)
4339 for (
unsigned int &vertex_n : line_data.
vertices)
4340 vertex_n += n_accumulated_vertices;
4350 for (
unsigned int &vertex_n : quad_data.
vertices)
4351 vertex_n += n_accumulated_vertices;
4358 n_accumulated_vertices += triangulation->n_vertices();
4362 std::vector<unsigned int> considered_vertices;
4366 considered_vertices,
4367 duplicated_vertex_tolerance);
4378 template <
int dim,
int spacedim>
4383 const double duplicated_vertex_tolerance,
4384 const bool copy_manifold_ids)
4387 if (triangulation_1.
n_cells() == 0)
4392 if (triangulation_2.
n_cells() == 0)
4399 duplicated_vertex_tolerance,
4405 template <
int dim,
int spacedim>
4413 ExcMessage(
"The two input triangulations are not derived from " 4414 "the same coarse mesh as required."));
4417 &triangulation_1) ==
nullptr) &&
4420 &triangulation_2) ==
nullptr),
4421 ExcMessage(
"The source triangulations for this function must both " 4422 "be available entirely locally, and not be distributed " 4423 "triangulations."));
4440 for (
unsigned int iteration = 0; iteration < triangulation_2.
n_levels();
4446 bool any_cell_flagged =
false;
4449 result_cell != result.
end();
4451 if (intergrid_map[result_cell]->has_children())
4453 any_cell_flagged =
true;
4454 result_cell->set_refine_flag();
4457 if (any_cell_flagged ==
false)
4466 template <
int dim,
int spacedim>
4476 std::vector<Point<spacedim>> vertices = input_triangulation.
get_vertices();
4480 std::vector<CellData<dim>> cells;
4483 cell != input_triangulation.
end();
4485 if (cells_to_remove.find(cell) == cells_to_remove.end())
4487 Assert(static_cast<unsigned int>(cell->level()) ==
4488 input_triangulation.
n_levels() - 1,
4490 "Your input triangulation appears to have " 4491 "adaptively refined cells. This is not allowed. You can " 4492 "only call this function on a triangulation in which " 4493 "all cells are on the same refinement level."));
4496 for (
unsigned int v = 0; v < GeometryInfo<dim>::vertices_per_cell;
4498 this_cell.
vertices[v] = cell->vertex_index(v);
4499 this_cell.material_id = cell->material_id();
4500 cells.push_back(this_cell);
4506 std::vector<unsigned int> considered_vertices;
4510 considered_vertices);
4522 const unsigned int n_slices,
4523 const double height,
4525 const bool copy_manifold_ids,
4526 const std::vector<types::manifold_id> &manifold_priorities)
4530 "The input triangulation must be a coarse mesh, i.e., it must " 4531 "not have been refined."));
4533 ExcMessage(
"The output triangulation object needs to be empty."));
4535 ExcMessage(
"The given height for extrusion must be positive."));
4538 "The number of slices for extrusion must be at least 2."));
4540 const double delta_h = height / (n_slices - 1);
4541 std::vector<double> slices_z_values;
4542 for (
unsigned int i = 0; i < n_slices; ++i)
4543 slices_z_values.push_back(i * delta_h);
4545 input, slices_z_values, result, copy_manifold_ids, manifold_priorities);
4553 const std::vector<double> & slice_coordinates,
4555 const bool copy_manifold_ids,
4556 const std::vector<types::manifold_id> &manifold_priorities)
4560 "The input triangulation must be a coarse mesh, i.e., it must " 4561 "not have been refined."));
4563 ExcMessage(
"The output triangulation object needs to be empty."));
4564 Assert(slice_coordinates.size() >= 2,
4566 "The number of slices for extrusion must be at least 2."));
4567 Assert(std::is_sorted(slice_coordinates.begin(), slice_coordinates.end()),
4568 ExcMessage(
"Slice z-coordinates should be in ascending order"));
4570 const auto priorities = [&]() -> std::vector<types::manifold_id> {
4574 if (0 < manifold_priorities.size())
4578 std::vector<types::manifold_id> sorted_manifold_priorities =
4579 manifold_priorities;
4580 std::sort(sorted_manifold_priorities.begin(),
4581 sorted_manifold_priorities.end());
4582 Assert(std::unique(sorted_manifold_priorities.begin(),
4583 sorted_manifold_priorities.end()) ==
4584 sorted_manifold_priorities.end(),
4586 "The given vector of manifold ids may not contain any " 4587 "duplicated entries."));
4588 std::vector<types::manifold_id> sorted_manifold_ids =
4590 std::sort(sorted_manifold_ids.begin(), sorted_manifold_ids.end());
4591 if (sorted_manifold_priorities != sorted_manifold_ids)
4593 std::ostringstream message;
4594 message <<
"The given triangulation has manifold ids {";
4596 if (manifold_id != sorted_manifold_ids.back())
4597 message << manifold_id <<
", ";
4598 message << sorted_manifold_ids.back() <<
"}, but \n" 4599 <<
" the given vector of manifold ids is {";
4601 if (manifold_id != manifold_priorities.back())
4602 message << manifold_id <<
", ";
4604 << manifold_priorities.back() <<
"}.\n" 4605 <<
" These vectors should contain the same elements.\n";
4606 const std::string m = message.str();
4610 return manifold_priorities;
4614 std::vector<types::manifold_id> default_priorities =
4616 const auto first_tfi_it = std::partition(
4617 default_priorities.begin(),
4618 default_priorities.end(),
4623 std::sort(default_priorities.begin(), first_tfi_it);
4624 std::sort(first_tfi_it, default_priorities.end());
4626 return default_priorities;
4629 const std::size_t n_slices = slice_coordinates.size();
4630 std::vector<Point<3>> points(n_slices * input.
n_vertices());
4631 std::vector<CellData<3>> cells;
4636 for (std::size_t slice_n = 0; slice_n < n_slices; ++slice_n)
4638 for (std::size_t vertex_n = 0; vertex_n < input.
n_vertices();
4642 points[slice_n * input.
n_vertices() + vertex_n] =
4643 Point<3>(vertex[0], vertex[1], slice_coordinates[slice_n]);
4651 for (std::size_t slice_n = 0; slice_n < n_slices - 1; ++slice_n)
4654 for (
unsigned int vertex_n = 0;
4655 vertex_n < GeometryInfo<2>::vertices_per_cell;
4659 cell->vertex_index(vertex_n) + slice_n * input.
n_vertices();
4662 cell->vertex_index(vertex_n) +
4667 if (copy_manifold_ids)
4669 cells.push_back(this_cell);
4684 if (face->at_boundary())
4685 max_boundary_id = std::max(max_boundary_id, quad.
boundary_id);
4686 if (copy_manifold_ids)
4688 for (std::size_t slice_n = 0; slice_n < n_slices - 1; ++slice_n)
4691 face->vertex_index(0) + slice_n * input.
n_vertices();
4693 face->vertex_index(1) + slice_n * input.
n_vertices();
4695 face->vertex_index(0) + (slice_n + 1) * input.
n_vertices();
4697 face->vertex_index(1) + (slice_n + 1) * input.
n_vertices();
4698 quads.push_back(quad);
4704 if (copy_manifold_ids)
4710 for (std::size_t slice_n = 1; slice_n < n_slices - 1; ++slice_n)
4713 cell->vertex_index(0) + slice_n * input.
n_vertices();
4715 cell->vertex_index(1) + slice_n * input.
n_vertices();
4717 cell->vertex_index(2) + slice_n * input.
n_vertices();
4719 cell->vertex_index(3) + slice_n * input.
n_vertices();
4720 quads.push_back(quad);
4731 "The input triangulation to this function is using boundary " 4732 "indicators in a range that do not allow using " 4733 "max_boundary_id+1 and max_boundary_id+2 as boundary " 4734 "indicators for the bottom and top faces of the " 4735 "extruded triangulation."));
4742 quad.
vertices[0] = cell->vertex_index(0);
4743 quad.
vertices[1] = cell->vertex_index(1);
4744 quad.
vertices[2] = cell->vertex_index(2);
4745 quad.
vertices[3] = cell->vertex_index(3);
4746 if (copy_manifold_ids)
4748 quads.push_back(quad);
4751 for (
unsigned int &vertex : quad.
vertices)
4752 vertex += (n_slices - 1) * input.
n_vertices();
4753 if (copy_manifold_ids)
4755 quads.push_back(quad);
4768 for (
auto manifold_id_it = priorities.rbegin();
4769 manifold_id_it != priorities.rend();
4772 if (face->manifold_id() == *manifold_id_it)
4773 for (
unsigned int line_n = 0;
4774 line_n < GeometryInfo<3>::lines_per_face;
4776 face->line(line_n)->set_manifold_id(*manifold_id_it);
4795 const double inner_radius,
4796 const double outer_radius,
4799 const bool colorize)
4803 Assert(inner_radius < outer_radius,
4804 ExcMessage(
"outer_radius has to be bigger than inner_radius."));
4808 hyper_shell(triangulation, center, inner_radius, outer_radius, 8);
4811 triangulation.begin_active(),
4812 endc = triangulation.end();
4813 std::vector<bool> treated_vertices(triangulation.n_vertices(),
false);
4814 for (; cell != endc; ++cell)
4816 for (
unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell; ++f)
4817 if (cell->face(f)->at_boundary())
4819 for (
unsigned int v = 0; v < GeometryInfo<dim>::vertices_per_face;
4822 unsigned int vv = cell->face(f)->vertex_index(v);
4823 if (treated_vertices[vv] ==
false)
4825 treated_vertices[vv] =
true;
4829 cell->face(f)->vertex(v) =
4830 center +
Point<dim>(outer_radius, outer_radius);
4833 cell->face(f)->vertex(v) =
4834 center +
Point<dim>(-outer_radius, outer_radius);
4837 cell->face(f)->vertex(v) =
4838 center +
Point<dim>(-outer_radius, -outer_radius);
4841 cell->face(f)->vertex(v) =
4842 center +
Point<dim>(outer_radius, -outer_radius);
4851 double eps = 1
e-3 * outer_radius;
4852 cell = triangulation.begin_active();
4853 for (; cell != endc; ++cell)
4855 for (
unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell; ++f)
4856 if (cell->face(f)->at_boundary())
4858 double dx = cell->face(f)->center()(0) - center(0);
4859 double dy = cell->face(f)->center()(1) - center(1);
4862 if (std::abs(dx + outer_radius) <
eps)
4863 cell->face(f)->set_boundary_id(0);
4864 else if (std::abs(dx - outer_radius) < eps)
4865 cell->face(f)->set_boundary_id(1);
4866 else if (std::abs(dy + outer_radius) < eps)
4867 cell->face(f)->set_boundary_id(2);
4868 else if (std::abs(dy - outer_radius) < eps)
4869 cell->face(f)->set_boundary_id(3);
4872 cell->face(f)->set_boundary_id(4);
4873 cell->face(f)->set_manifold_id(0);
4878 double d = (cell->face(f)->center() - center).
norm();
4879 if (d - inner_radius < 0)
4881 cell->face(f)->set_boundary_id(1);
4882 cell->face(f)->set_manifold_id(0);
4885 cell->face(f)->set_boundary_id(0);
4898 const double inner_radius,
4899 const double outer_radius,
4900 const unsigned int n_shells,
4901 const double skewness,
4902 const unsigned int n_cells,
4903 const bool colorize)
4908 Assert(inner_radius < outer_radius,
4909 ExcMessage(
"outer_radius has to be bigger than inner_radius."));
4913 std::vector<double> radii;
4914 radii.push_back(inner_radius);
4915 for (
unsigned int shell_n = 1; shell_n < n_shells; ++shell_n)
4916 if (skewness == 0.0)
4918 radii.push_back(inner_radius +
4919 (outer_radius - inner_radius) *
4920 (1.0 - (1.0 -
double(shell_n) / n_shells)));
4924 (outer_radius - inner_radius) *
4925 (1.0 - std::tanh(skewness * (1.0 -
double(shell_n) / n_shells)) /
4926 std::tanh(skewness)));
4927 radii.push_back(outer_radius);
4929 double grid_vertex_tolerance = 0.0;
4930 for (
unsigned int shell_n = 0; shell_n < radii.size() - 1; ++shell_n)
4937 n_cells == 0 ? (dim == 2 ? 8 : 12) :
4942 if (grid_vertex_tolerance == 0.0)
4943 grid_vertex_tolerance =
4944 0.5 * internal::minimal_vertex_distance(current_shell);
4947 triangulation.clear();
4951 grid_vertex_tolerance);
4955 triangulation.set_all_manifold_ids(manifold_id);
4963 constexpr
double radial_vertex_tolerance =
4964 100.0 * std::numeric_limits<double>::epsilon();
4965 auto assert_vertex_distance_within_tolerance =
4966 [center, radial_vertex_tolerance](
4968 const double radius) {
4970 (void)radial_vertex_tolerance;
4973 for (
unsigned int vertex_n = 0;
4974 vertex_n < GeometryInfo<dim>::vertices_per_face;
4977 Assert(std::abs((face->vertex(vertex_n) - center).norm() - radius) <
4978 (center.
norm() + radius) * radial_vertex_tolerance,
4983 for (
const auto &cell : triangulation.active_cell_iterators())
4984 for (
unsigned int face_n = 0;
4985 face_n < GeometryInfo<dim>::faces_per_cell;
4988 auto face = cell->face(face_n);
4989 if (face->at_boundary())
4991 if (((face->vertex(0) - center).norm() - inner_radius) <
4992 (center.
norm() + inner_radius) * radial_vertex_tolerance)
4995 assert_vertex_distance_within_tolerance(face, inner_radius);
4996 face->set_all_boundary_ids(0);
5001 assert_vertex_distance_within_tolerance(face, outer_radius);
5002 face->set_all_boundary_ids(1);
5012 const double inner_radius,
5013 const double outer_radius,
5015 const unsigned int Nz,
5016 const bool colorize)
5020 Assert(inner_radius < outer_radius,
5021 ExcMessage(
"outer_radius has to be bigger than inner_radius."));
5025 cylinder_shell(triangulation, L, inner_radius, outer_radius, 8, Nz);
5029 triangulation.begin_active(),
5030 endc = triangulation.end();
5031 std::vector<bool> treated_vertices(triangulation.n_vertices(),
false);
5032 for (; cell != endc; ++cell)
5034 for (
unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell; ++f)
5035 if (cell->face(f)->at_boundary())
5037 for (
unsigned int v = 0; v < GeometryInfo<dim>::vertices_per_face;
5040 unsigned int vv = cell->face(f)->vertex_index(v);
5041 if (treated_vertices[vv] ==
false)
5043 treated_vertices[vv] =
true;
5044 for (
unsigned int i = 0; i <= Nz; ++i)
5046 double d = i * L / Nz;
5047 switch (vv - i * 16)
5050 cell->face(f)->vertex(v) =
5054 cell->face(f)->vertex(v) =
5058 cell->face(f)->vertex(v) =
5062 cell->face(f)->vertex(v) =
5073 double eps = 1
e-3 * outer_radius;
5074 cell = triangulation.begin_active();
5075 for (; cell != endc; ++cell)
5077 for (
unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell; ++f)
5078 if (cell->face(f)->at_boundary())
5080 double dx = cell->face(f)->center()(0);
5081 double dy = cell->face(f)->center()(1);
5082 double dz = cell->face(f)->center()(2);
5086 if (std::abs(dx + outer_radius) <
eps)
5087 cell->face(f)->set_boundary_id(0);
5089 else if (std::abs(dx - outer_radius) < eps)
5090 cell->face(f)->set_boundary_id(1);
5092 else if (std::abs(dy + outer_radius) < eps)
5093 cell->face(f)->set_boundary_id(2);
5095 else if (std::abs(dy - outer_radius) < eps)
5096 cell->face(f)->set_boundary_id(3);
5098 else if (std::abs(dz) < eps)
5099 cell->face(f)->set_boundary_id(4);
5101 else if (std::abs(dz - L) < eps)
5102 cell->face(f)->set_boundary_id(5);
5106 cell->face(f)->set_all_boundary_ids(6);
5114 double d = c.
norm();
5115 if (d - inner_radius < 0)
5117 cell->face(f)->set_all_boundary_ids(1);
5121 cell->face(f)->set_boundary_id(0);
5128 template <
int dim,
int spacedim1,
int spacedim2>
5141 "Cannot use this function on parallel::distributed::Triangulation."));
5143 std::vector<Point<spacedim2>> v;
5144 std::vector<CellData<dim>> cells;
5147 const unsigned int spacedim = std::min(spacedim1, spacedim2);
5148 const std::vector<Point<spacedim1>> &in_vertices = in_tria.
get_vertices();
5150 v.resize(in_vertices.size());
5151 for (
unsigned int i = 0; i < in_vertices.size(); ++i)
5152 for (
unsigned int d = 0; d < spacedim; ++d)
5153 v[i][d] = in_vertices[i][d];
5158 endc = in_tria.
end();
5160 for (
unsigned int id = 0; cell != endc; ++cell, ++id)
5162 for (
unsigned int i = 0; i < GeometryInfo<dim>::vertices_per_cell; ++i)
5163 cells[
id].vertices[i] = cell->vertex_index(i);
5164 cells[id].material_id = cell->material_id();
5165 cells[id].manifold_id = cell->manifold_id();
5181 for (; face != endf; ++face)
5182 if (face->at_boundary())
5184 for (
unsigned int i = 0;
5185 i < GeometryInfo<dim>::vertices_per_face;
5188 face->vertex_index(i);
5190 face->boundary_id();
5192 face->manifold_id();
5201 for (; face != endf; ++face)
5202 if (face->at_boundary())
5204 for (
unsigned int i = 0;
5205 i < GeometryInfo<dim>::vertices_per_face;
5208 face->vertex_index(i);
5210 face->boundary_id();
5212 face->manifold_id();
5227 template <
template <
int,
int>
class MeshType,
int dim,
int spacedim>
5229 std::map<
typename MeshType<dim - 1, spacedim>::cell_iterator,
5230 typename MeshType<dim, spacedim>::face_iterator>
5232 typename ExtractBoundaryMesh<MeshType, dim, spacedim>::return_type
5235 MeshType<dim - 1, spacedim> & surface_mesh,
5236 const std::set<types::boundary_id> &boundary_ids)
5240 &volume_mesh.get_triangulation()) ==
nullptr),
5249 const unsigned int boundary_dim = dim - 1;
5256 std::pair<typename MeshType<dim, spacedim>::face_iterator,
unsigned int>>
5257 temporary_mapping_level0;
5262 std::vector<bool> touched(volume_mesh.get_triangulation().n_vertices(),
5266 std::vector<CellData<boundary_dim>> cells;
5268 std::vector<Point<spacedim>> vertices;
5271 std::map<unsigned int, unsigned int> map_vert_index;
5284 for (
unsigned int i1 = 0; i1 < GeometryInfo<spacedim>::faces_per_cell; i1++)
5286 for (
unsigned int i2 = 0; i2 <
GeometryInfo<dim - 1>::vertices_per_cell;
5288 swap_matrix[i1][i2] = i2;
5294 std::swap(swap_matrix[0][1], swap_matrix[0][2]);
5295 std::swap(swap_matrix[2][1], swap_matrix[2][2]);
5296 std::swap(swap_matrix[4][1], swap_matrix[4][2]);
5300 std::swap(swap_matrix[1][0], swap_matrix[1][1]);
5301 std::swap(swap_matrix[2][0], swap_matrix[2][1]);
5306 for (
typename MeshType<dim, spacedim>::cell_iterator cell =
5307 volume_mesh.
begin(0);
5308 cell != volume_mesh.
end(0);
5310 for (
unsigned int i = 0; i < GeometryInfo<dim>::faces_per_cell; ++i)
5312 const typename MeshType<dim, spacedim>::face_iterator face =
5315 if (face->at_boundary() &&
5316 (boundary_ids.empty() ||
5317 (boundary_ids.find(face->boundary_id()) != boundary_ids.end())))
5321 for (
unsigned int j = 0;
5322 j < GeometryInfo<boundary_dim>::vertices_per_cell;
5325 const unsigned int v_index = face->vertex_index(j);
5327 if (!touched[v_index])
5329 vertices.push_back(face->vertex(j));
5330 map_vert_index[v_index] = vertices.size() - 1;
5331 touched[v_index] =
true;
5334 c_data.
vertices[swap_matrix[i][j]] = map_vert_index[v_index];
5348 for (
unsigned int e = 0; e < 4; ++e)
5354 bool edge_found =
false;
5356 if (((boundary_line.vertices[0] ==
5357 map_vert_index[face->line(e)->vertex_index(0)]) &&
5358 (boundary_line.vertices[1] ==
5359 map_vert_index[face->line(e)->vertex_index(
5361 ((boundary_line.vertices[0] ==
5362 map_vert_index[face->line(e)->vertex_index(1)]) &&
5363 (boundary_line.vertices[1] ==
5364 map_vert_index[face->line(e)->vertex_index(0)])))
5366 boundary_line.boundary_id =
5371 if (edge_found ==
true)
5378 map_vert_index[face->line(e)->vertex_index(0)];
5380 map_vert_index[face->line(e)->vertex_index(1)];
5387 cells.push_back(c_data);
5388 temporary_mapping_level0.push_back(std::make_pair(face, i));
5395 surface_mesh.get_triangulation())
5396 .create_triangulation(vertices, cells, subcell_data);
5402 for (
unsigned int vertex = 0; vertex < 2; vertex++)
5403 if (cell->face(vertex)->at_boundary())
5404 cell->face(vertex)->set_boundary_id(0);
5412 std::vector<std::pair<
5413 const typename MeshType<dim - 1, spacedim>::cell_iterator,
5414 std::pair<typename MeshType<dim, spacedim>::face_iterator,
unsigned int>>>
5415 temporary_map_boundary_cell_face;
5417 temporary_map_boundary_cell_face.push_back(
5418 std::make_pair(cell, temporary_mapping_level0.at(cell->index())));
5430 unsigned int index_cells_deepest_level = 0;
5433 bool changed =
false;
5437 std::vector<unsigned int> cells_refined;
5440 for (
unsigned int cell_n = index_cells_deepest_level;
5441 cell_n < temporary_map_boundary_cell_face.size();
5446 if (temporary_map_boundary_cell_face[cell_n]
5447 .second.first->has_children())
5451 Assert(temporary_map_boundary_cell_face[cell_n]
5452 .second.first->refinement_case() ==
5455 temporary_map_boundary_cell_face[cell_n]
5456 .first->set_refine_flag();
5457 cells_refined.push_back(cell_n);
5468 surface_mesh.get_triangulation())
5469 .execute_coarsening_and_refinement();
5472 index_cells_deepest_level = temporary_map_boundary_cell_face.size();
5473 for (
const auto &refined_cell_n : cells_refined)
5475 const typename MeshType<dim - 1, spacedim>::cell_iterator
5477 temporary_map_boundary_cell_face[refined_cell_n].first;
5478 const typename MeshType<dim,
5479 spacedim>::face_iterator refined_face =
5480 temporary_map_boundary_cell_face[refined_cell_n].second.first;
5481 const unsigned int refined_face_number =
5482 temporary_map_boundary_cell_face[refined_cell_n]
5484 for (
unsigned int child_n = 0;
5485 child_n < refined_cell->n_children();
5490 temporary_map_boundary_cell_face.push_back(
5491 std::make_pair(refined_cell->child(
5492 swap_matrix[refined_face_number][child_n]),
5493 std::make_pair(refined_face->child(child_n),
5494 refined_face_number)));
5504 std::map<
typename MeshType<dim - 1, spacedim>::cell_iterator,
5505 typename MeshType<dim, spacedim>::face_iterator>
5506 surface_to_volume_mapping;
5507 for (
unsigned int i = 0; i < temporary_map_boundary_cell_face.size(); i++)
5508 surface_to_volume_mapping[temporary_map_boundary_cell_face[i].first] =
5509 temporary_map_boundary_cell_face[i].second.first;
5511 return surface_to_volume_mapping;
5517 #include "grid_generator.inst" 5519 DEAL_II_NAMESPACE_CLOSE
std::vector< CellData< 1 > > boundary_lines
unsigned int n_active_cells() const
virtual void copy_triangulation(const Triangulation< dim, spacedim > &other_tria)
void create_union_triangulation(const Triangulation< dim, spacedim > &triangulation_1, const Triangulation< dim, spacedim > &triangulation_2, Triangulation< dim, spacedim > &result)
unsigned int n_vertices() const
static void reorder_cells(std::vector< CellData< dim >> &original_cells, const bool use_new_style_ordering=false)
const types::manifold_id flat_manifold_id
#define AssertDimension(dim1, dim2)
active_face_iterator begin_active_face() const
Number determinant(const SymmetricTensor< 2, dim, Number > &)
virtual void create_triangulation_compatibility(const std::vector< Point< spacedim >> &vertices, const std::vector< CellData< dim >> &cells, const SubCellData &subcelldata)
static unsigned int face_to_cell_vertices(const unsigned int face, const unsigned int vertex, const bool face_orientation=true, const bool face_flip=false, const bool face_rotation=false)
cell_iterator last() const
void simplex(Triangulation< dim, dim > &tria, const std::vector< Point< dim >> &vertices)
Triangulation of a d-simplex with (d+1) vertices and mesh cells.
void channel_with_cylinder(Triangulation< dim > &tria, const double shell_region_width=0.03, const unsigned int n_shells=2, const double skewness=2.0, const bool colorize=false)
unsigned int n_cells() const
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
void concentric_hyper_shells(Triangulation< dim > &triangulation, const Point< dim > ¢er, const double inner_radius=0.125, const double outer_radius=0.25, const unsigned int n_shells=1, const double skewness=0.1, const unsigned int n_cells_per_shell=0, const bool colorize=false)
void general_cell(Triangulation< dim, spacedim > &tria, const std::vector< Point< spacedim >> &vertices, const bool colorize=false)
void truncated_cone(Triangulation< dim > &tria, const double radius_0=1.0, const double radius_1=0.5, const double half_length=1.0)
IteratorRange< active_cell_iterator > active_cell_iterators() const
void hyper_rectangle(Triangulation< dim, spacedim > &tria, const Point< dim > &p1, const Point< dim > &p2, const bool colorize=false)
void moebius(Triangulation< 3, 3 > &tria, const unsigned int n_cells, const unsigned int n_rotations, const double R, const double r)
void flatten_triangulation(const Triangulation< dim, spacedim1 > &in_tria, Triangulation< dim, spacedim2 > &out_tria)
void quarter_hyper_shell(Triangulation< dim > &tria, const Point< dim > ¢er, const double inner_radius, const double outer_radius, const unsigned int n_cells=0, const bool colorize=false)
void enclosed_hyper_cube(Triangulation< dim > &tria, const double left=0., const double right=1., const double thickness=1., const bool colorize=false)
void subdivided_parallelepiped(Triangulation< dim > &tria, const unsigned int n_subdivisions, const Point< dim >(&corners)[dim], const bool colorize=false)
static ::ExceptionBase & ExcInvalidRepetitionsDimension(int arg1)
void parallelogram(Triangulation< dim > &tria, const Point< dim >(&corners)[dim], const bool colorize=false)
double norm(const FEValuesBase< dim > &fe, const ArrayView< const std::vector< Tensor< 1, dim >>> &Du)
active_cell_iterator begin_active(const unsigned int level=0) const
#define AssertThrow(cond, exc)
numbers::NumberTraits< Number >::real_type norm() const
types::boundary_id boundary_id
void hyper_shell(Triangulation< dim > &tria, const Point< dim > ¢er, const double inner_radius, const double outer_radius, const unsigned int n_cells=0, bool colorize=false)
static ::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
static ::ExceptionBase & ExcInvalidInputOrientation()
cell_iterator begin(const unsigned int level=0) const
void cylinder_shell(Triangulation< dim > &tria, const double length, const double inner_radius, const double outer_radius, const unsigned int n_radial_cells=0, const unsigned int n_axial_cells=0)
void initialize(const Triangulation< dim, spacedim > &triangulation)
SymmetricTensor< 2, dim, Number > epsilon(const Tensor< 2, dim, Number > &Grad_u)
unsigned int n_levels() const
void hyper_cross(Triangulation< dim, spacedim > &tria, const std::vector< unsigned int > &sizes, const bool colorize_cells=false)
A center cell with stacks of cell protruding from each surface.
void set_manifold(const types::manifold_id number, const Manifold< dim, spacedim > &manifold_object)
const Point< spacedim > center
void hyper_L(Triangulation< dim > &tria, const double left=-1., const double right=1., const bool colorize=false)
unsigned int n_active_faces() const
cell_iterator end() const
virtual void execute_coarsening_and_refinement()
void half_hyper_ball(Triangulation< dim > &tria, const Point< dim > ¢er=Point< dim >(), const double radius=1.)
unsigned int n_active_lines() const
static ::ExceptionBase & ExcMessage(std::string arg1)
void hyper_sphere(Triangulation< spacedim - 1, spacedim > &tria, const Point< spacedim > ¢er=Point< spacedim >(), const double radius=1.)
void cylinder(Triangulation< dim > &tria, const double radius=1., const double half_length=1.)
virtual void create_triangulation(const std::vector< Point< spacedim >> &vertices, const std::vector< CellData< dim >> &cells, const SubCellData &subcelldata)
#define Assert(cond, exc)
void set_all_manifold_ids(const types::manifold_id number)
const types::boundary_id invalid_boundary_id
void quarter_hyper_ball(Triangulation< dim > &tria, const Point< dim > ¢er=Point< dim >(), const double radius=1.)
types::material_id material_id
const std::vector< Point< spacedim > > & get_vertices() const
void subdivided_hyper_cube(Triangulation< dim, spacedim > &tria, const unsigned int repetitions, const double left=0., const double right=1.)
void create_triangulation_with_removed_cells(const Triangulation< dim, spacedim > &input_triangulation, const std::set< typename Triangulation< dim, spacedim >::active_cell_iterator > &cells_to_remove, Triangulation< dim, spacedim > &result)
void make_mapping(const MeshType &source_grid, const MeshType &destination_grid)
void extrude_triangulation(const Triangulation< 2, 2 > &input, const unsigned int n_slices, const double height, Triangulation< 3, 3 > &result, const bool copy_manifold_ids=false, const std::vector< types::manifold_id > &manifold_priorities={})
IteratorRange< active_face_iterator > active_face_iterators() const
face_iterator begin_face() const
void hyper_cube_slit(Triangulation< dim > &tria, const double left=0., const double right=1., const bool colorize=false)
std::string int_to_string(const unsigned int value, const unsigned int digits=numbers::invalid_unsigned_int)
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
static ::ExceptionBase & ExcLowerRange(int arg1, int arg2)
SymmetricTensor< 2, dim, Number > b(const Tensor< 2, dim, Number > &F)
void subdivided_hyper_rectangle(Triangulation< dim, spacedim > &tria, const std::vector< unsigned int > &repetitions, const Point< dim > &p1, const Point< dim > &p2, const bool colorize=false)
void merge_triangulations(const Triangulation< dim, spacedim > &triangulation_1, const Triangulation< dim, spacedim > &triangulation_2, Triangulation< dim, spacedim > &result, const double duplicated_vertex_tolerance=1.0e-12, const bool copy_manifold_ids=false)
types::manifold_id manifold_id
static ::ExceptionBase & ExcInvalidRadii()
void swap(Vector< Number > &u, Vector< Number > &v)
void cheese(Triangulation< dim, spacedim > &tria, const std::vector< unsigned int > &holes)
Rectangular domain with rectangular pattern of holes.
__global__ void set(Number *val, const Number s, const size_type N)
void parallelepiped(Triangulation< dim > &tria, const Point< dim >(&corners)[dim], const bool colorize=false)
void half_hyper_shell(Triangulation< dim > &tria, const Point< dim > ¢er, const double inner_radius, const double outer_radius, const unsigned int n_cells=0, const bool colorize=false)
static constexpr double PI
std::vector< CellData< 2 > > boundary_quads
void hyper_cube(Triangulation< dim, spacedim > &tria, const double left=0., const double right=1., const bool colorize=false)
std::map< typename MeshType< dim - 1, spacedim >::cell_iterator, typename MeshType< dim, spacedim >::face_iterator > extract_boundary_mesh(const MeshType< dim, spacedim > &volume_mesh, MeshType< dim - 1, spacedim > &surface_mesh, const std::set< types::boundary_id > &boundary_ids=std::set< types::boundary_id >())
void refine_global(const unsigned int times=1)
void hyper_ball(Triangulation< dim > &tria, const Point< dim > ¢er=Point< dim >(), const double radius=1., const bool attach_spherical_manifold_on_boundary_cells=false)
static ::ExceptionBase & ExcNotImplemented()
static void invert_all_cells_of_negative_grid(const std::vector< Point< spacedim >> &all_vertices, std::vector< CellData< dim >> &original_cells)
face_iterator end_face() const
void set_all_manifold_ids_on_boundary(const types::manifold_id number)
const types::boundary_id internal_face_boundary_id
void plate_with_a_hole(Triangulation< dim > &tria, const double inner_radius=0.4, const double outer_radius=1., const double pad_bottom=2., const double pad_top=2., const double pad_left=1., const double pad_right=1., const Point< dim > center=Point< dim >(), const types::manifold_id polar_manifold_id=0, const types::manifold_id tfi_manifold_id=1, const double L=1., const unsigned int n_slices=2, const bool colorize=false)
Rectangular plate with an (offset) cylindrical hole.
void hyper_cube_with_cylindrical_hole(Triangulation< dim > &triangulation, const double inner_radius=.25, const double outer_radius=.5, const double L=.5, const unsigned int repetitions=1, const bool colorize=false)
const types::material_id invalid_material_id
std::vector< types::manifold_id > get_manifold_ids() const
const Manifold< dim, spacedim > & get_manifold(const types::manifold_id number) const
unsigned int vertices[GeometryInfo< structdim >::vertices_per_cell]
static ::ExceptionBase & ExcInvalidRepetitions(int arg1)
static ::ExceptionBase & ExcInternalError()