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> 32 DEAL_II_NAMESPACE_OPEN
63 template <
int dim,
int spacedim>
74 for (
unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell; ++f)
75 cell->face(f)->set_boundary_id(f);
81 template <
int spacedim>
91 if (cell->center()(0) > 0)
92 cell->set_material_id(1);
99 template <
int dim,
int spacedim>
104 const double epsilon)
117 for (; face != endface; ++face)
118 if (face->at_boundary())
119 if (face->boundary_id() == 0)
123 if (std::abs(center(0) - p1[0]) < epsilon)
124 face->set_boundary_id(0);
125 else if (std::abs(center(0) - p2[0]) < epsilon)
126 face->set_boundary_id(1);
127 else if (dim > 1 && std::abs(center(1) - p1[1]) < epsilon)
128 face->set_boundary_id(2);
129 else if (dim > 1 && std::abs(center(1) - p2[1]) < epsilon)
130 face->set_boundary_id(3);
131 else if (dim > 2 && std::abs(center(2) - p1[2]) < epsilon)
132 face->set_boundary_id(4);
133 else if (dim > 2 && std::abs(center(2) - p2[2]) < epsilon)
134 face->set_boundary_id(5);
149 for (
unsigned int d = 0;
d < dim; ++
d)
150 if (cell->center()(
d) > 0)
152 cell->set_material_id(
id);
177 cell->face(2)->set_all_boundary_ids(1);
200 cell->face(4)->set_all_boundary_ids(1);
204 cell->face(2)->set_all_boundary_ids(1);
208 cell->face(2)->set_all_boundary_ids(1);
212 cell->face(0)->set_all_boundary_ids(1);
216 cell->face(2)->set_all_boundary_ids(1);
220 cell->face(0)->set_all_boundary_ids(1);
231 cell->face(5)->set_all_boundary_ids(1);
247 unsigned int count = 0;
251 if (cell->face(5)->at_boundary())
253 cell->face(5)->set_all_boundary_ids(1);
271 const double inner_radius,
272 const double outer_radius)
277 double middle = (outer_radius - inner_radius) / 2e0 + inner_radius;
278 double eps = 1
e-3 * middle;
281 for (; cell != tria.
end(); ++cell)
282 for (
unsigned int f = 0; f < GeometryInfo<3>::faces_per_cell; ++f)
284 if (!cell->face(f)->at_boundary())
287 double radius = cell->face(f)->center().norm() - center.
norm();
288 if (std::fabs(cell->face(f)->center()(0)) <
291 cell->face(f)->set_boundary_id(2);
292 for (
unsigned int j = 0; j < GeometryInfo<3>::lines_per_face;
294 if (cell->face(f)->line(j)->at_boundary())
295 if (std::fabs(cell->face(f)->line(j)->vertex(0).norm() -
296 cell->face(f)->line(j)->vertex(1).norm()) >
298 cell->face(f)->line(j)->set_boundary_id(2);
300 else if (std::fabs(cell->face(f)->center()(1)) <
303 cell->face(f)->set_boundary_id(3);
304 for (
unsigned int j = 0; j < GeometryInfo<3>::lines_per_face;
306 if (cell->face(f)->line(j)->at_boundary())
307 if (std::fabs(cell->face(f)->line(j)->vertex(0).norm() -
308 cell->face(f)->line(j)->vertex(1).norm()) >
310 cell->face(f)->line(j)->set_boundary_id(3);
312 else if (std::fabs(cell->face(f)->center()(2)) <
315 cell->face(f)->set_boundary_id(4);
316 for (
unsigned int j = 0; j < GeometryInfo<3>::lines_per_face;
318 if (cell->face(f)->line(j)->at_boundary())
319 if (std::fabs(cell->face(f)->line(j)->vertex(0).norm() -
320 cell->face(f)->line(j)->vertex(1).norm()) >
322 cell->face(f)->line(j)->set_boundary_id(4);
324 else if (radius < middle)
326 cell->face(f)->set_boundary_id(0);
327 for (
unsigned int j = 0; j < GeometryInfo<3>::lines_per_face;
329 if (cell->face(f)->line(j)->at_boundary())
330 if (std::fabs(cell->face(f)->line(j)->vertex(0).norm() -
331 cell->face(f)->line(j)->vertex(1).norm()) <
333 cell->face(f)->line(j)->set_boundary_id(0);
335 else if (radius > middle)
337 cell->face(f)->set_boundary_id(1);
338 for (
unsigned int j = 0; j < GeometryInfo<3>::lines_per_face;
340 if (cell->face(f)->line(j)->at_boundary())
341 if (std::fabs(cell->face(f)->line(j)->vertex(0).norm() -
342 cell->face(f)->line(j)->vertex(1).norm()) <
344 cell->face(f)->line(j)->set_boundary_id(1);
354 template <
int dim,
int spacedim>
365 for (
unsigned int i = 0; i < dim; ++i)
367 p1(i) = std::min(p_1(i), p_2(i));
368 p2(i) = std::max(p_1(i), p_2(i));
379 vertices[0] = vertices[1] = p1;
380 vertices[2] = vertices[3] = p2;
382 vertices[1](0) = p2(0);
383 vertices[2](0) = p1(0);
386 vertices[0] = vertices[1] = vertices[2] = vertices[3] = p1;
387 vertices[4] = vertices[5] = vertices[6] = vertices[7] = p2;
389 vertices[1](0) = p2(0);
390 vertices[2](1) = p2(1);
391 vertices[3](0) = p2(0);
392 vertices[3](1) = p2(1);
394 vertices[4](0) = p1(0);
395 vertices[4](1) = p1(1);
396 vertices[5](1) = p1(1);
397 vertices[6](0) = p1(0);
405 std::vector<CellData<dim>> cells(1);
406 for (
unsigned int i = 0; i < GeometryInfo<dim>::vertices_per_cell; ++i)
407 cells[0].vertices[i] = i;
408 cells[0].material_id = 0;
414 colorize_hyper_rectangle(tria);
418 template <
int dim,
int spacedim>
426 ExcMessage(
"Invalid left-to-right bounds of hypercube"));
429 for (
unsigned int i = 0; i < dim; ++i)
447 for (
unsigned int d = 0; d < dim; ++d)
448 for (
unsigned int c = 1; c <= dim; ++c)
449 vector_matrix[c - 1][d] = vertices[c](d) - vertices[0](d);
451 ExcMessage(
"Vertices of simplex must form a right handed system"));
455 std::vector<Point<dim>> points = vertices;
459 for (
unsigned int i = 0; i <= dim; ++i)
461 points.push_back(0.5 * (points[i] + points[(i + 1) % (dim + 1)]));
467 for (
unsigned int i = 1; i < dim; ++i)
468 points.push_back(0.5 * (points[i - 1] + points[i + 1]));
470 for (
unsigned int i = 0; i <= dim; ++i)
471 points.push_back(1. / 3. *
472 (points[i] + points[(i + 1) % (dim + 1)] +
473 points[(i + 2) % (dim + 1)]));
475 points.push_back((1. / (dim + 1)) * center);
477 std::vector<CellData<dim>> cells(dim + 1);
482 cells[0].vertices[0] = 0;
483 cells[0].vertices[1] = 3;
484 cells[0].vertices[2] = 5;
485 cells[0].vertices[3] = 6;
486 cells[0].material_id = 0;
488 cells[1].vertices[0] = 3;
489 cells[1].vertices[1] = 1;
490 cells[1].vertices[2] = 6;
491 cells[1].vertices[3] = 4;
492 cells[1].material_id = 0;
494 cells[2].vertices[0] = 5;
495 cells[2].vertices[1] = 6;
496 cells[2].vertices[2] = 2;
497 cells[2].vertices[3] = 4;
498 cells[2].material_id = 0;
502 cells[0].vertices[0] = 0;
503 cells[0].vertices[1] = 4;
504 cells[0].vertices[2] = 8;
505 cells[0].vertices[3] = 10;
506 cells[0].vertices[4] = 7;
507 cells[0].vertices[5] = 13;
508 cells[0].vertices[6] = 12;
509 cells[0].vertices[7] = 14;
510 cells[0].material_id = 0;
512 cells[1].vertices[0] = 4;
513 cells[1].vertices[1] = 1;
514 cells[1].vertices[2] = 10;
515 cells[1].vertices[3] = 5;
516 cells[1].vertices[4] = 13;
517 cells[1].vertices[5] = 9;
518 cells[1].vertices[6] = 14;
519 cells[1].vertices[7] = 11;
520 cells[1].material_id = 0;
522 cells[2].vertices[0] = 8;
523 cells[2].vertices[1] = 10;
524 cells[2].vertices[2] = 2;
525 cells[2].vertices[3] = 5;
526 cells[2].vertices[4] = 12;
527 cells[2].vertices[5] = 14;
528 cells[2].vertices[6] = 6;
529 cells[2].vertices[7] = 11;
530 cells[2].material_id = 0;
532 cells[3].vertices[0] = 7;
533 cells[3].vertices[1] = 13;
534 cells[3].vertices[2] = 12;
535 cells[3].vertices[3] = 14;
536 cells[3].vertices[4] = 3;
537 cells[3].vertices[5] = 9;
538 cells[3].vertices[6] = 6;
539 cells[3].vertices[7] = 11;
540 cells[3].material_id = 0;
550 const unsigned int n_cells,
551 const unsigned int n_rotations,
555 const unsigned int dim = 3;
558 "More than 4 cells are needed to create a moebius grid."));
560 ExcMessage(
"Outer and inner radius must be positive."));
562 ExcMessage(
"Outer radius must be greater than inner radius."));
565 std::vector<Point<dim>> vertices(4 * n_cells);
566 double beta_step = n_rotations *
numbers::PI / 2.0 / n_cells;
569 for (
unsigned int i = 0; i < n_cells; ++i)
570 for (
unsigned int j = 0; j < 4; ++j)
572 vertices[4 * i + j][0] =
573 R * std::cos(i * alpha_step) +
574 r * std::cos(i * beta_step + j *
numbers::PI / 2.0) *
575 std::cos(i * alpha_step);
576 vertices[4 * i + j][1] =
577 R * std::sin(i * alpha_step) +
578 r * std::cos(i * beta_step + j *
numbers::PI / 2.0) *
579 std::sin(i * alpha_step);
580 vertices[4 * i + j][2] =
581 r * std::sin(i * beta_step + j *
numbers::PI / 2.0);
584 unsigned int offset = 0;
586 std::vector<CellData<dim>> cells(n_cells);
587 for (
unsigned int i = 0; i < n_cells; ++i)
589 for (
unsigned int j = 0; j < 2; ++j)
591 cells[i].vertices[0 + 4 * j] = offset + 0 + 4 * j;
592 cells[i].vertices[1 + 4 * j] = offset + 3 + 4 * j;
593 cells[i].vertices[2 + 4 * j] = offset + 2 + 4 * j;
594 cells[i].vertices[3 + 4 * j] = offset + 1 + 4 * j;
597 cells[i].material_id = 0;
601 cells[n_cells - 1].vertices[4] = (0 + n_rotations) % 4;
602 cells[n_cells - 1].vertices[5] = (3 + n_rotations) % 4;
603 cells[n_cells - 1].vertices[6] = (2 + n_rotations) % 4;
604 cells[n_cells - 1].vertices[7] = (1 + n_rotations) % 4;
616 ExcMessage(
"Outer radius R must be greater than the inner " 620 const unsigned int dim = 2;
621 const unsigned int spacedim = 3;
622 std::vector<Point<spacedim>> vertices(16);
641 std::vector<CellData<dim>> cells(16);
643 cells[0].vertices[0] = 0;
644 cells[0].vertices[1] = 4;
645 cells[0].vertices[2] = 7;
646 cells[0].vertices[3] = 3;
647 cells[0].material_id = 0;
649 cells[1].vertices[0] = 1;
650 cells[1].vertices[1] = 5;
651 cells[1].vertices[2] = 4;
652 cells[1].vertices[3] = 0;
653 cells[1].material_id = 0;
655 cells[2].vertices[0] = 2;
656 cells[2].vertices[1] = 6;
657 cells[2].vertices[2] = 5;
658 cells[2].vertices[3] = 1;
659 cells[2].material_id = 0;
661 cells[3].vertices[0] = 3;
662 cells[3].vertices[1] = 7;
663 cells[3].vertices[2] = 6;
664 cells[3].vertices[3] = 2;
665 cells[3].material_id = 0;
667 cells[4].vertices[0] = 4;
668 cells[4].vertices[1] = 8;
669 cells[4].vertices[2] = 11;
670 cells[4].vertices[3] = 7;
671 cells[4].material_id = 0;
673 cells[5].vertices[0] = 5;
674 cells[5].vertices[1] = 9;
675 cells[5].vertices[2] = 8;
676 cells[5].vertices[3] = 4;
677 cells[5].material_id = 0;
679 cells[6].vertices[0] = 6;
680 cells[6].vertices[1] = 10;
681 cells[6].vertices[2] = 9;
682 cells[6].vertices[3] = 5;
683 cells[6].material_id = 0;
685 cells[7].vertices[0] = 7;
686 cells[7].vertices[1] = 11;
687 cells[7].vertices[2] = 10;
688 cells[7].vertices[3] = 6;
689 cells[7].material_id = 0;
691 cells[8].vertices[0] = 8;
692 cells[8].vertices[1] = 12;
693 cells[8].vertices[2] = 15;
694 cells[8].vertices[3] = 11;
695 cells[8].material_id = 0;
697 cells[9].vertices[0] = 9;
698 cells[9].vertices[1] = 13;
699 cells[9].vertices[2] = 12;
700 cells[9].vertices[3] = 8;
701 cells[9].material_id = 0;
703 cells[10].vertices[0] = 10;
704 cells[10].vertices[1] = 14;
705 cells[10].vertices[2] = 13;
706 cells[10].vertices[3] = 9;
707 cells[10].material_id = 0;
709 cells[11].vertices[0] = 11;
710 cells[11].vertices[1] = 15;
711 cells[11].vertices[2] = 14;
712 cells[11].vertices[3] = 10;
713 cells[11].material_id = 0;
715 cells[12].vertices[0] = 12;
716 cells[12].vertices[1] = 0;
717 cells[12].vertices[2] = 3;
718 cells[12].vertices[3] = 15;
719 cells[12].material_id = 0;
721 cells[13].vertices[0] = 13;
722 cells[13].vertices[1] = 1;
723 cells[13].vertices[2] = 0;
724 cells[13].vertices[3] = 12;
725 cells[13].material_id = 0;
727 cells[14].vertices[0] = 14;
728 cells[14].vertices[1] = 2;
729 cells[14].vertices[2] = 1;
730 cells[14].vertices[3] = 13;
731 cells[14].material_id = 0;
733 cells[15].vertices[0] = 15;
734 cells[15].vertices[1] = 3;
735 cells[15].vertices[2] = 2;
736 cells[15].vertices[3] = 14;
737 cells[15].material_id = 0;
743 tria.create_triangulation_compatibility(vertices, cells,
SubCellData());
745 tria.set_all_manifold_ids(0);
753 ExcMessage(
"Outer radius R must be greater than the inner " 766 tria.set_all_manifold_ids(1);
767 tria.set_all_manifold_ids_on_boundary(0);
787 for (
unsigned int i = 0; i < GeometryInfo<dim>::vertices_per_cell; ++i)
788 cell->vertex(i) = vertices[i];
794 "The volume of the cell is not greater than zero. " 795 "This could be due to the wrong ordering of the vertices."));
823 std::array<Tensor<1, 2>, 2> edges;
824 edges[0] = corners[0];
825 edges[1] = corners[1];
826 std::vector<unsigned int> subdivisions;
827 subdivided_parallelepiped<2, 2>(
828 tria, origin, edges, subdivisions, colorize);
839 unsigned int n_subdivisions[dim];
840 for (
unsigned int i = 0; i < dim; ++i)
841 n_subdivisions[i] = 1;
850 const unsigned int n_subdivisions,
856 unsigned int n_subdivisions_[dim];
857 for (
unsigned int i = 0; i < dim; ++i)
858 n_subdivisions_[i] = n_subdivisions;
868 const unsigned int (&n_subdivisions)[dim],
870 const unsigned int *n_subdivisions,
876 std::vector<unsigned int> subdivisions;
877 std::array<Tensor<1, dim>, dim> edges;
878 for (
unsigned int i = 0; i < dim; ++i)
880 subdivisions.push_back(n_subdivisions[i]);
881 edges[i] = corners[i];
884 subdivided_parallelepiped<dim, dim>(
885 tria, origin, edges, subdivisions, colorize);
896 template <
int dim,
int spacedim>
901 const std::vector<unsigned int> &subdivisions,
904 std::vector<unsigned int> compute_subdivisions = subdivisions;
905 if (compute_subdivisions.size() == 0)
907 compute_subdivisions.resize(dim, 1);
910 Assert(compute_subdivisions.size() == dim,
911 ExcMessage(
"One subdivision must be provided for each dimension."));
913 for (
unsigned int i = 0; i < dim; ++i)
915 Assert(compute_subdivisions[i] > 0,
920 "Edges in subdivided_parallelepiped() must not be degenerate."));
928 bool twisted_data =
false;
933 twisted_data = (edges[0][0] < 0);
940 const double plane_normal =
941 edges[0][0] * edges[1][1] - edges[0][1] * edges[1][0];
942 twisted_data = (plane_normal < 0.0);
950 Assert(std::abs(edges[0] * edges[1] /
951 (edges[0].norm() * edges[1].norm()) -
954 "Edges in subdivided_parallelepiped() must point in" 955 " different directions."));
957 cross_product_3d(edges[0], edges[1]);
971 twisted_data = (plane_normal * edges[2] < 0.0);
981 "The triangulation you are trying to create will consist of cells" 982 " with negative measures. This is usually the result of input data" 983 " that does not define a right-handed coordinate system. The usual" 984 " fix for this is to ensure that in 1D the given point is to the" 985 " right of the origin (or the given edge tensor is positive), in 2D" 986 " that the two edges (and their cross product) obey the right-hand" 987 " rule (which may usually be done by switching the order of the" 988 " points or edge tensors), or in 3D that the edges form a" 989 " right-handed coordinate system (which may also be accomplished by" 990 " switching the order of the first two points or edge tensors)."));
993 for (
unsigned int i = 0; i < dim; ++i)
994 for (
unsigned int j = i + 1; j < dim; ++j)
995 Assert((edges[i] != edges[j]),
997 "Degenerate edges of subdivided_parallelepiped encountered."));
1000 std::vector<Point<spacedim>> points;
1005 for (
unsigned int x = 0; x <= compute_subdivisions[0]; ++x)
1006 points.push_back(origin + edges[0] / compute_subdivisions[0] * x);
1010 for (
unsigned int y = 0; y <= compute_subdivisions[1]; ++y)
1011 for (
unsigned int x = 0; x <= compute_subdivisions[0]; ++x)
1012 points.push_back(origin + edges[0] / compute_subdivisions[0] * x +
1013 edges[1] / compute_subdivisions[1] * y);
1017 for (
unsigned int z = 0; z <= compute_subdivisions[2]; ++z)
1018 for (
unsigned int y = 0; y <= compute_subdivisions[1]; ++y)
1019 for (
unsigned int x = 0; x <= compute_subdivisions[0]; ++x)
1020 points.push_back(origin +
1021 edges[0] / compute_subdivisions[0] * x +
1022 edges[1] / compute_subdivisions[1] * y +
1023 edges[2] / compute_subdivisions[2] * z);
1031 unsigned int n_cells = 1;
1032 for (
unsigned int i = 0; i < dim; ++i)
1033 n_cells *= compute_subdivisions[i];
1034 std::vector<CellData<dim>> cells(n_cells);
1040 for (
unsigned int x = 0; x < compute_subdivisions[0]; ++x)
1042 cells[x].vertices[0] = x;
1043 cells[x].vertices[1] = x + 1;
1046 cells[x].material_id = 0;
1053 const unsigned int n_dy = compute_subdivisions[1];
1054 const unsigned int n_dx = compute_subdivisions[0];
1056 for (
unsigned int y = 0; y < n_dy; ++y)
1057 for (
unsigned int x = 0; x < n_dx; ++x)
1059 const unsigned int c = y * n_dx + x;
1060 cells[c].vertices[0] = y * (n_dx + 1) + x;
1061 cells[c].vertices[1] = y * (n_dx + 1) + x + 1;
1062 cells[c].vertices[2] = (y + 1) * (n_dx + 1) + x;
1063 cells[c].vertices[3] = (y + 1) * (n_dx + 1) + x + 1;
1066 cells[c].material_id = 0;
1074 const unsigned int n_dz = compute_subdivisions[2];
1075 const unsigned int n_dy = compute_subdivisions[1];
1076 const unsigned int n_dx = compute_subdivisions[0];
1078 for (
unsigned int z = 0; z < n_dz; ++z)
1079 for (
unsigned int y = 0; y < n_dy; ++y)
1080 for (
unsigned int x = 0; x < n_dx; ++x)
1082 const unsigned int c = z * n_dy * n_dx + y * n_dx + x;
1084 cells[c].vertices[0] =
1085 z * (n_dy + 1) * (n_dx + 1) + y * (n_dx + 1) + x;
1086 cells[c].vertices[1] =
1087 z * (n_dy + 1) * (n_dx + 1) + y * (n_dx + 1) + x + 1;
1088 cells[c].vertices[2] =
1089 z * (n_dy + 1) * (n_dx + 1) + (y + 1) * (n_dx + 1) + x;
1090 cells[c].vertices[3] = z * (n_dy + 1) * (n_dx + 1) +
1091 (y + 1) * (n_dx + 1) + x + 1;
1092 cells[c].vertices[4] =
1093 (z + 1) * (n_dy + 1) * (n_dx + 1) + y * (n_dx + 1) + x;
1094 cells[c].vertices[5] = (z + 1) * (n_dy + 1) * (n_dx + 1) +
1095 y * (n_dx + 1) + x + 1;
1096 cells[c].vertices[6] = (z + 1) * (n_dy + 1) * (n_dx + 1) +
1097 (y + 1) * (n_dx + 1) + x;
1098 cells[c].vertices[7] = (z + 1) * (n_dy + 1) * (n_dx + 1) +
1099 (y + 1) * (n_dx + 1) + x + 1;
1102 cells[c].material_id = 0;
1123 for (; cell != endc; ++cell)
1125 for (
unsigned int face = 0;
1126 face < GeometryInfo<dim>::faces_per_cell;
1129 if (cell->face(face)->at_boundary())
1130 cell->face(face)->set_boundary_id(face);
1137 template <
int dim,
int spacedim>
1140 const unsigned int repetitions,
1146 ExcMessage(
"Invalid left-to-right bounds of hypercube"));
1149 for (
unsigned int i = 0; i < dim; ++i)
1155 std::vector<unsigned int> reps(dim, repetitions);
1161 template <
int dim,
int spacedim>
1164 const std::vector<unsigned int> &repetitions,
1167 const bool colorize)
1175 for (
unsigned int i = 0; i < dim; ++i)
1177 p1(i) = std::min(p_1(i), p_2(i));
1178 p2(i) = std::max(p_1(i), p_2(i));
1182 std::vector<Point<spacedim>> delta(dim);
1183 for (
unsigned int i = 0; i < dim; ++i)
1187 delta[i][i] = (p2[i] - p1[i]) / repetitions[i];
1191 "The first dim entries of coordinates of p1 and p2 need to be different."));
1195 std::vector<Point<spacedim>> points;
1199 for (
unsigned int x = 0; x <= repetitions[0]; ++x)
1200 points.push_back(p1 + (
double)x * delta[0]);
1204 for (
unsigned int y = 0; y <= repetitions[1]; ++y)
1205 for (
unsigned int x = 0; x <= repetitions[0]; ++x)
1206 points.push_back(p1 + (
double)x * delta[0] +
1207 (
double)y * delta[1]);
1211 for (
unsigned int z = 0; z <= repetitions[2]; ++z)
1212 for (
unsigned int y = 0; y <= repetitions[1]; ++y)
1213 for (
unsigned int x = 0; x <= repetitions[0]; ++x)
1214 points.push_back(p1 + (
double)x * delta[0] +
1215 (
double)y * delta[1] + (
double)z * delta[2]);
1223 std::vector<CellData<dim>> cells;
1228 cells.resize(repetitions[0]);
1229 for (
unsigned int x = 0; x < repetitions[0]; ++x)
1231 cells[x].vertices[0] = x;
1232 cells[x].vertices[1] = x + 1;
1233 cells[x].material_id = 0;
1240 cells.resize(repetitions[1] * repetitions[0]);
1241 for (
unsigned int y = 0; y < repetitions[1]; ++y)
1242 for (
unsigned int x = 0; x < repetitions[0]; ++x)
1244 const unsigned int c = x + y * repetitions[0];
1245 cells[c].vertices[0] = y * (repetitions[0] + 1) + x;
1246 cells[c].vertices[1] = y * (repetitions[0] + 1) + x + 1;
1247 cells[c].vertices[2] = (y + 1) * (repetitions[0] + 1) + x;
1248 cells[c].vertices[3] = (y + 1) * (repetitions[0] + 1) + x + 1;
1249 cells[c].material_id = 0;
1256 const unsigned int n_x = (repetitions[0] + 1);
1257 const unsigned int n_xy =
1258 (repetitions[0] + 1) * (repetitions[1] + 1);
1260 cells.resize(repetitions[2] * repetitions[1] * repetitions[0]);
1261 for (
unsigned int z = 0; z < repetitions[2]; ++z)
1262 for (
unsigned int y = 0; y < repetitions[1]; ++y)
1263 for (
unsigned int x = 0; x < repetitions[0]; ++x)
1265 const unsigned int c = x + y * repetitions[0] +
1266 z * repetitions[0] * repetitions[1];
1267 cells[c].vertices[0] = z * n_xy + y * n_x + x;
1268 cells[c].vertices[1] = z * n_xy + y * n_x + x + 1;
1269 cells[c].vertices[2] = z * n_xy + (y + 1) * n_x + x;
1270 cells[c].vertices[3] = z * n_xy + (y + 1) * n_x + x + 1;
1271 cells[c].vertices[4] = (z + 1) * n_xy + y * n_x + x;
1272 cells[c].vertices[5] = (z + 1) * n_xy + y * n_x + x + 1;
1273 cells[c].vertices[6] = (z + 1) * n_xy + (y + 1) * n_x + x;
1274 cells[c].vertices[7] =
1275 (z + 1) * n_xy + (y + 1) * n_x + x + 1;
1276 cells[c].material_id = 0;
1297 double epsilon = 10;
1298 for (
unsigned int i = 0; i < dim; ++i)
1299 epsilon = std::min(epsilon, 0.01 * delta[i][i]);
1302 "The distance between corner points must be positive."))
1306 colorize_subdivided_hyper_rectangle(tria, p1, p2, epsilon);
1315 const std::vector<std::vector<double>> &step_sz,
1318 const bool colorize)
1330 std::vector<std::vector<double>> step_sizes(step_sz);
1332 for (
unsigned int i = 0; i < dim; ++i)
1337 std::reverse(step_sizes[i].begin(), step_sizes[i].end());
1341 for (
unsigned int j = 0; j < step_sizes.at(i).size(); j++)
1342 x += step_sizes[i][j];
1343 Assert(std::fabs(x - (p2(i) - p1(i))) <= 1e-12 * std::fabs(x),
1345 "The sequence of step sizes in coordinate direction " +
1347 " must be equal to the distance of the two given " 1348 "points in this coordinate direction."));
1354 std::vector<Point<dim>> points;
1360 for (
unsigned int i = 0;; ++i)
1369 if (i == step_sizes[0].size())
1372 x += step_sizes[0][i];
1380 for (
unsigned int j = 0;; ++j)
1383 for (
unsigned int i = 0;; ++i)
1385 points.push_back(
Point<dim>(p1[0] + x, p1[1] + y));
1386 if (i == step_sizes[0].size())
1389 x += step_sizes[0][i];
1392 if (j == step_sizes[1].size())
1395 y += step_sizes[1][j];
1402 for (
unsigned int k = 0;; ++k)
1405 for (
unsigned int j = 0;; ++j)
1408 for (
unsigned int i = 0;; ++i)
1411 Point<dim>(p1[0] + x, p1[1] + y, p1[2] + z));
1412 if (i == step_sizes[0].size())
1415 x += step_sizes[0][i];
1418 if (j == step_sizes[1].size())
1421 y += step_sizes[1][j];
1424 if (k == step_sizes[2].size())
1427 z += step_sizes[2][k];
1438 std::vector<CellData<dim>> cells;
1443 cells.resize(step_sizes[0].size());
1444 for (
unsigned int x = 0; x < step_sizes[0].size(); ++x)
1446 cells[x].vertices[0] = x;
1447 cells[x].vertices[1] = x + 1;
1448 cells[x].material_id = 0;
1455 cells.resize(step_sizes[1].size() * step_sizes[0].size());
1456 for (
unsigned int y = 0; y < step_sizes[1].size(); ++y)
1457 for (
unsigned int x = 0; x < step_sizes[0].size(); ++x)
1459 const unsigned int c = x + y * step_sizes[0].size();
1460 cells[c].vertices[0] = y * (step_sizes[0].size() + 1) + x;
1461 cells[c].vertices[1] = y * (step_sizes[0].size() + 1) + x + 1;
1462 cells[c].vertices[2] =
1463 (y + 1) * (step_sizes[0].size() + 1) + x;
1464 cells[c].vertices[3] =
1465 (y + 1) * (step_sizes[0].size() + 1) + x + 1;
1466 cells[c].material_id = 0;
1473 const unsigned int n_x = (step_sizes[0].size() + 1);
1474 const unsigned int n_xy =
1475 (step_sizes[0].size() + 1) * (step_sizes[1].size() + 1);
1477 cells.resize(step_sizes[2].size() * step_sizes[1].size() *
1478 step_sizes[0].size());
1479 for (
unsigned int z = 0; z < step_sizes[2].size(); ++z)
1480 for (
unsigned int y = 0; y < step_sizes[1].size(); ++y)
1481 for (
unsigned int x = 0; x < step_sizes[0].size(); ++x)
1483 const unsigned int c =
1484 x + y * step_sizes[0].size() +
1485 z * step_sizes[0].size() * step_sizes[1].size();
1486 cells[c].vertices[0] = z * n_xy + y * n_x + x;
1487 cells[c].vertices[1] = z * n_xy + y * n_x + x + 1;
1488 cells[c].vertices[2] = z * n_xy + (y + 1) * n_x + x;
1489 cells[c].vertices[3] = z * n_xy + (y + 1) * n_x + x + 1;
1490 cells[c].vertices[4] = (z + 1) * n_xy + y * n_x + x;
1491 cells[c].vertices[5] = (z + 1) * n_xy + y * n_x + x + 1;
1492 cells[c].vertices[6] = (z + 1) * n_xy + (y + 1) * n_x + x;
1493 cells[c].vertices[7] =
1494 (z + 1) * n_xy + (y + 1) * n_x + x + 1;
1495 cells[c].material_id = 0;
1517 *std::min_element(step_sizes[0].begin(), step_sizes[0].end());
1518 for (
unsigned int i = 1; i < dim; ++i)
1519 min_size = std::min(min_size,
1520 *std::min_element(step_sizes[i].begin(),
1521 step_sizes[i].end()));
1522 const double epsilon = 0.01 * min_size;
1526 colorize_subdivided_hyper_rectangle(tria, p1, p2, epsilon);
1535 const std::vector<std::vector<double>> &spacing,
1538 const bool colorize)
1542 const unsigned int n_cells = material_id.
size(0);
1546 double delta = std::numeric_limits<double>::max();
1547 for (
unsigned int i = 0; i < n_cells; i++)
1550 delta = std::min(delta, spacing[0][i]);
1554 std::vector<Point<1>> points;
1556 for (
unsigned int x = 0; x <= n_cells; ++x)
1558 points.emplace_back(ax);
1560 ax += spacing[0][x];
1563 unsigned int n_val_cells = 0;
1564 for (
unsigned int i = 0; i < n_cells; i++)
1568 std::vector<CellData<1>> cells(n_val_cells);
1569 unsigned int id = 0;
1570 for (
unsigned int x = 0; x < n_cells; ++x)
1573 cells[id].vertices[0] = x;
1574 cells[id].vertices[1] = x + 1;
1575 cells[id].material_id = material_id[x];
1593 const std::vector<std::vector<double>> &spacing,
1596 const bool colorize)
1600 std::vector<unsigned int> repetitions(2);
1601 unsigned int n_cells = 1;
1602 double delta = std::numeric_limits<double>::max();
1603 for (
unsigned int i = 0; i < 2; i++)
1605 repetitions[i] = spacing[i].size();
1606 n_cells *= repetitions[i];
1607 for (
unsigned int j = 0; j < repetitions[i]; j++)
1610 delta = std::min(delta, spacing[i][j]);
1612 Assert(material_id.
size(i) == repetitions[i],
1617 std::vector<Point<2>> points;
1619 for (
unsigned int y = 0; y <= repetitions[1]; ++y)
1622 for (
unsigned int x = 0; x <= repetitions[0]; ++x)
1624 points.emplace_back(ax, ay);
1625 if (x < repetitions[0])
1626 ax += spacing[0][x];
1628 if (y < repetitions[1])
1629 ay += spacing[1][y];
1633 unsigned int n_val_cells = 0;
1634 for (
unsigned int i = 0; i < material_id.
size(0); i++)
1635 for (
unsigned int j = 0; j < material_id.
size(1); j++)
1639 std::vector<CellData<2>> cells(n_val_cells);
1640 unsigned int id = 0;
1641 for (
unsigned int y = 0; y < repetitions[1]; ++y)
1642 for (
unsigned int x = 0; x < repetitions[0]; ++x)
1645 cells[id].vertices[0] = y * (repetitions[0] + 1) + x;
1646 cells[id].vertices[1] = y * (repetitions[0] + 1) + x + 1;
1647 cells[id].vertices[2] = (y + 1) * (repetitions[0] + 1) + x;
1648 cells[id].vertices[3] = (y + 1) * (repetitions[0] + 1) + x + 1;
1649 cells[id].material_id = material_id[x][y];
1662 double eps = 0.01 * delta;
1664 for (; cell != endc; ++cell)
1666 Point<2> cell_center = cell->center();
1667 for (
unsigned int f = 0; f < GeometryInfo<2>::faces_per_cell; ++f)
1668 if (cell->face(f)->boundary_id() == 0)
1670 Point<2> face_center = cell->face(f)->center();
1671 for (
unsigned int i = 0; i < 2; ++i)
1673 if (face_center[i] < cell_center[i] - eps)
1674 cell->face(f)->set_boundary_id(i * 2);
1675 if (face_center[i] > cell_center[i] + eps)
1676 cell->face(f)->set_boundary_id(i * 2 + 1);
1687 const std::vector<std::vector<double>> &spacing,
1690 const bool colorize)
1692 const unsigned int dim = 3;
1696 std::vector<unsigned int> repetitions(dim);
1697 unsigned int n_cells = 1;
1698 double delta = std::numeric_limits<double>::max();
1699 for (
unsigned int i = 0; i < dim; i++)
1701 repetitions[i] = spacing[i].size();
1702 n_cells *= repetitions[i];
1703 for (
unsigned int j = 0; j < repetitions[i]; j++)
1706 delta = std::min(delta, spacing[i][j]);
1708 Assert(material_id.
size(i) == repetitions[i],
1713 std::vector<Point<dim>> points;
1715 for (
unsigned int z = 0; z <= repetitions[2]; ++z)
1718 for (
unsigned int y = 0; y <= repetitions[1]; ++y)
1721 for (
unsigned int x = 0; x <= repetitions[0]; ++x)
1723 points.emplace_back(ax, ay, az);
1724 if (x < repetitions[0])
1725 ax += spacing[0][x];
1727 if (y < repetitions[1])
1728 ay += spacing[1][y];
1730 if (z < repetitions[2])
1731 az += spacing[2][z];
1735 unsigned int n_val_cells = 0;
1736 for (
unsigned int i = 0; i < material_id.
size(0); i++)
1737 for (
unsigned int j = 0; j < material_id.
size(1); j++)
1738 for (
unsigned int k = 0; k < material_id.
size(2); k++)
1742 std::vector<CellData<dim>> cells(n_val_cells);
1743 unsigned int id = 0;
1744 const unsigned int n_x = (repetitions[0] + 1);
1745 const unsigned int n_xy = (repetitions[0] + 1) * (repetitions[1] + 1);
1746 for (
unsigned int z = 0; z < repetitions[2]; ++z)
1747 for (
unsigned int y = 0; y < repetitions[1]; ++y)
1748 for (
unsigned int x = 0; x < repetitions[0]; ++x)
1751 cells[id].vertices[0] = z * n_xy + y * n_x + x;
1752 cells[id].vertices[1] = z * n_xy + y * n_x + x + 1;
1753 cells[id].vertices[2] = z * n_xy + (y + 1) * n_x + x;
1754 cells[id].vertices[3] = z * n_xy + (y + 1) * n_x + x + 1;
1755 cells[id].vertices[4] = (z + 1) * n_xy + y * n_x + x;
1756 cells[id].vertices[5] = (z + 1) * n_xy + y * n_x + x + 1;
1757 cells[id].vertices[6] = (z + 1) * n_xy + (y + 1) * n_x + x;
1758 cells[id].vertices[7] = (z + 1) * n_xy + (y + 1) * n_x + x + 1;
1759 cells[id].material_id = material_id[x][y][z];
1772 double eps = 0.01 * delta;
1775 for (; cell != endc; ++cell)
1778 for (
unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell; ++f)
1779 if (cell->face(f)->boundary_id() == 0)
1781 Point<dim> face_center = cell->face(f)->center();
1782 for (
unsigned int i = 0; i < dim; ++i)
1784 if (face_center[i] < cell_center[i] - eps)
1785 cell->face(f)->set_boundary_id(i * 2);
1786 if (face_center[i] > cell_center[i] + eps)
1787 cell->face(f)->set_boundary_id(i * 2 + 1);
1794 template <
int dim,
int spacedim>
1797 const std::vector<unsigned int> &holes)
1806 for (
unsigned int d = 0; d < dim; ++d)
1813 std::vector<Point<spacedim>> delta(dim);
1814 unsigned int repetitions[dim];
1815 for (
unsigned int i = 0; i < dim; ++i)
1818 ExcMessage(
"At least one hole needed in each direction"));
1819 repetitions[i] = 2 * holes[i] + 1;
1820 delta[i][i] = (p2[i] - p1[i]);
1825 std::vector<Point<spacedim>> points;
1829 for (
unsigned int x = 0; x <= repetitions[0]; ++x)
1830 points.push_back(p1 + (
double)x * delta[0]);
1834 for (
unsigned int y = 0; y <= repetitions[1]; ++y)
1835 for (
unsigned int x = 0; x <= repetitions[0]; ++x)
1836 points.push_back(p1 + (
double)x * delta[0] +
1837 (
double)y * delta[1]);
1841 for (
unsigned int z = 0; z <= repetitions[2]; ++z)
1842 for (
unsigned int y = 0; y <= repetitions[1]; ++y)
1843 for (
unsigned int x = 0; x <= repetitions[0]; ++x)
1844 points.push_back(p1 + (
double)x * delta[0] +
1845 (
double)y * delta[1] + (
double)z * delta[2]);
1854 std::vector<CellData<dim>> cells;
1859 cells.resize(repetitions[1] * repetitions[0] - holes[1] * holes[0]);
1861 for (
unsigned int y = 0; y < repetitions[1]; ++y)
1862 for (
unsigned int x = 0; x < repetitions[0]; ++x)
1864 if ((x % 2 == 1) && (y % 2 == 1))
1867 cells[c].vertices[0] = y * (repetitions[0] + 1) + x;
1868 cells[c].vertices[1] = y * (repetitions[0] + 1) + x + 1;
1869 cells[c].vertices[2] = (y + 1) * (repetitions[0] + 1) + x;
1870 cells[c].vertices[3] = (y + 1) * (repetitions[0] + 1) + x + 1;
1871 cells[c].material_id = 0;
1879 const unsigned int n_x = (repetitions[0] + 1);
1880 const unsigned int n_xy =
1881 (repetitions[0] + 1) * (repetitions[1] + 1);
1883 cells.resize(repetitions[2] * repetitions[1] * repetitions[0]);
1886 for (
unsigned int z = 0; z < repetitions[2]; ++z)
1887 for (
unsigned int y = 0; y < repetitions[1]; ++y)
1888 for (
unsigned int x = 0; x < repetitions[0]; ++x)
1891 cells[c].vertices[0] = z * n_xy + y * n_x + x;
1892 cells[c].vertices[1] = z * n_xy + y * n_x + x + 1;
1893 cells[c].vertices[2] = z * n_xy + (y + 1) * n_x + x;
1894 cells[c].vertices[3] = z * n_xy + (y + 1) * n_x + x + 1;
1895 cells[c].vertices[4] = (z + 1) * n_xy + y * n_x + x;
1896 cells[c].vertices[5] = (z + 1) * n_xy + y * n_x + x + 1;
1897 cells[c].vertices[6] = (z + 1) * n_xy + (y + 1) * n_x + x;
1898 cells[c].vertices[7] =
1899 (z + 1) * n_xy + (y + 1) * n_x + x + 1;
1900 cells[c].material_id = 0;
1927 const unsigned int ,
1937 bool inline point_in_2d_box(
const Point<2> &p,
1939 const double radius)
1941 return (std::abs(p[0] - c[0]) < radius) &&
1942 (std::abs(p[1] - c[1]) < radius);
1947 bool inline point_in_2d_box(
const Point<3> &p,
1949 const double radius)
1951 return point_in_2d_box(
Point<2>(p[0], p[1]),
1962 const double inner_radius,
1963 const double outer_radius,
1964 const double pad_bottom,
1965 const double pad_top,
1966 const double pad_left,
1967 const double pad_right,
1972 const unsigned int ,
1973 const bool colorize)
1975 Assert((pad_bottom > 0 || pad_top > 0 || pad_left > 0 || pad_right > 0),
1976 ExcMessage(
"At least one padding parameter has to be non-zero."));
1985 double length = std::numeric_limits<double>::max();
1987 for (
unsigned int n = 0; n < GeometryInfo<2>::lines_per_cell; ++n)
1988 length = std::min(length, cell->line(n)->diameter());
2004 cell->set_material_id(2);
2009 auto add_sizes = [](std::vector<double> &step_sizes,
2010 const double padding,
2011 const double h) ->
void {
2014 const unsigned int rounded = 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);
2042 const Point<2> bl(-outer_radius - pad_left, -outer_radius - pad_bottom);
2043 const Point<2> tr(outer_radius + pad_right, outer_radius + pad_top);
2045 bulk_tria, step_sizes, bl, tr, colorize);
2048 std::set<Triangulation<2>::active_cell_iterator> cells_to_remove;
2050 if (point_in_2d_box(cell->center(), center, outer_radius))
2051 cells_to_remove.insert(cell);
2055 bulk_tria, cells_to_remove, tria_without_cylinder);
2057 const double tolerance = std::min(min_line_length(tria_without_cylinder),
2058 min_line_length(cylinder_tria)) /
2063 cell->set_material_id(1);
2075 if (cell->material_id() == 2)
2077 cell->set_manifold_id(tfi_manifold_id);
2078 for (
unsigned int face_n = 0;
2079 face_n < GeometryInfo<2>::faces_per_cell;
2082 const auto &face = cell->face(face_n);
2083 if (face->at_boundary() &&
2084 point_in_2d_box(face->center(), center, outer_radius))
2085 face->set_manifold_id(polar_manifold_id);
2087 face->set_manifold_id(tfi_manifold_id);
2098 static constexpr
double tol =
2099 std::numeric_limits<double>::epsilon() * 10000;
2102 for (
unsigned int face_n = 0;
2103 face_n < GeometryInfo<2>::faces_per_cell;
2106 const auto face = cell->face(face_n);
2107 if (face->at_boundary())
2109 const Point<2> center = face->center();
2111 if (std::abs(center[0] - bl[0]) < tol * std::abs(bl[0]))
2112 face->set_boundary_id(0);
2114 else if (std::abs(center[0] - tr[0]) < tol * std::abs(tr[0]))
2115 face->set_boundary_id(1);
2117 else if (std::abs(center[1] - bl[1]) < tol * std::abs(bl[1]))
2118 face->set_boundary_id(2);
2120 else if (std::abs(center[1] - tr[1]) < tol * std::abs(tr[1]))
2121 face->set_boundary_id(3);
2126 face->set_boundary_id(4);
2145 const double inner_radius,
2146 const double outer_radius,
2147 const double pad_bottom,
2148 const double pad_top,
2149 const double pad_left,
2150 const double pad_right,
2155 const unsigned int n_slices,
2156 const bool colorize)
2158 internal::plate_with_a_hole(tria,
2174 cell->set_material_id(0);
2181 const double inner_radius,
2182 const double outer_radius,
2183 const double pad_bottom,
2184 const double pad_top,
2185 const double pad_left,
2186 const double pad_right,
2191 const unsigned int n_slices,
2192 const bool colorize)
2195 internal::plate_with_a_hole(tria_2,
2202 Point<2>(new_center[0], new_center[1]),
2219 if (cell->material_id() == 2)
2221 cell->set_all_manifold_ids(tfi_manifold_id);
2222 for (
unsigned int face_n = 0;
2223 face_n < GeometryInfo<3>::faces_per_cell;
2227 const auto face = cell->face(face_n);
2228 if (face->at_boundary() &&
2229 internal::point_in_2d_box(face->center(),
2235 face->set_manifold_id(polar_manifold_id);
2237 face->set_manifold_id(tfi_manifold_id);
2249 direction, new_center);
2252 tria.
set_manifold(polar_manifold_id, cylindrical_manifold);
2257 cell->set_material_id(0);
2262 template <
int dim,
int spacedim>
2265 const std::vector<unsigned int> &sizes,
2266 const bool colorize)
2275 for (
unsigned int d = 0; d < dim; ++d)
2278 std::vector<Point<spacedim>> points;
2279 unsigned int n_cells = 1;
2280 for (
unsigned int i = 0; i < GeometryInfo<dim>::faces_per_cell; ++i)
2281 n_cells += sizes[i];
2283 std::vector<CellData<dim>> cells(n_cells);
2285 for (
unsigned int i = 0; i < GeometryInfo<dim>::vertices_per_cell; ++i)
2288 for (
unsigned int d = 0; d < dim; ++d)
2289 p(d) = 0.5 * dimensions[d] *
2292 points.push_back(p);
2293 cells[0].vertices[i] = i;
2295 cells[0].material_id = 0;
2298 unsigned int cell_index = 1;
2300 for (
unsigned int face = 0; face < GeometryInfo<dim>::faces_per_cell;
2307 for (
unsigned int j = 0; j < sizes[face]; ++j, ++cell_index)
2309 const unsigned int last_cell = (j == 0) ? 0U : (cell_index - 1);
2311 for (
unsigned int v = 0; v < GeometryInfo<dim>::vertices_per_face;
2314 const unsigned int cellv =
2316 const unsigned int ocellv =
2319 cells[cell_index].vertices[ocellv] =
2320 cells[last_cell].vertices[cellv];
2323 cells[cell_index].vertices[cellv] = points.size();
2328 points.push_back(p);
2330 cells[cell_index].material_id = (colorize) ? (face + 1U) : 0U;
2456 const double thickness,
2457 const bool colorize)
2460 ExcMessage(
"Invalid left-to-right bounds of enclosed hypercube"));
2462 std::vector<Point<2>> vertices(16);
2464 coords[0] = left - thickness;
2467 coords[3] = right + thickness;
2470 for (
unsigned int i0 = 0; i0 < 4; ++i0)
2471 for (
unsigned int i1 = 0; i1 < 4; ++i1)
2472 vertices[k++] =
Point<2>(coords[i1], coords[i0]);
2476 std::vector<CellData<2>> cells(9);
2478 for (
unsigned int i0 = 0; i0 < 3; ++i0)
2479 for (
unsigned int i1 = 0; i1 < 3; ++i1)
2481 cells[k].vertices[0] = i1 + 4 * i0;
2482 cells[k].vertices[1] = i1 + 4 * i0 + 1;
2483 cells[k].vertices[2] = i1 + 4 * i0 + 4;
2484 cells[k].vertices[3] = i1 + 4 * i0 + 5;
2486 cells[k].material_id = materials[k];
2501 const bool colorize)
2503 const double rl2 = (right + left) / 2;
2514 const int cell_vertices[4][4] = {{0, 1, 3, 2},
2519 for (
unsigned int i = 0; i < 4; ++i)
2521 for (
unsigned int j = 0; j < 4; ++j)
2522 cells[i].vertices[j] = cell_vertices[i][j];
2523 cells[i].material_id = 0;
2526 std::end(vertices)),
2533 cell->face(1)->set_boundary_id(1);
2535 cell->face(0)->set_boundary_id(2);
2543 const double radius_0,
2544 const double radius_1,
2545 const double half_length)
2549 vertices_tmp[0] =
Point<2>(-half_length, -radius_0);
2550 vertices_tmp[1] =
Point<2>(half_length, -radius_1);
2551 vertices_tmp[2] =
Point<2>(-half_length, radius_0);
2552 vertices_tmp[3] =
Point<2>(half_length, radius_1);
2554 const std::vector<Point<2>> vertices(std::begin(vertices_tmp),
2555 std::end(vertices_tmp));
2558 for (
unsigned int i = 0; i < GeometryInfo<2>::vertices_per_cell; ++i)
2559 cell_vertices[0][i] = i;
2563 for (
unsigned int i = 0; i < GeometryInfo<2>::vertices_per_cell; ++i)
2564 cells[0].vertices[i] = cell_vertices[0][i];
2566 cells[0].material_id = 0;
2571 cell->face(0)->set_boundary_id(1);
2572 cell->face(1)->set_boundary_id(2);
2574 for (
unsigned int i = 2; i < 4; ++i)
2575 cell->face(i)->set_boundary_id(0);
2585 const bool colorize)
2591 Point<2>((a + b) / 2, (a + b) / 2),
2595 const int cell_vertices[3][4] = {{0, 1, 3, 4}, {1, 2, 4, 5}, {3, 4, 6, 7}};
2599 for (
unsigned int i = 0; i < 3; ++i)
2601 for (
unsigned int j = 0; j < 4; ++j)
2602 cells[i].vertices[j] = cell_vertices[i][j];
2603 cells[i].material_id = 0;
2607 std::end(vertices)),
2615 cell->face(0)->set_boundary_id(0);
2616 cell->face(2)->set_boundary_id(1);
2619 cell->face(1)->set_boundary_id(2);
2620 cell->face(2)->set_boundary_id(1);
2621 cell->face(3)->set_boundary_id(3);
2624 cell->face(0)->set_boundary_id(0);
2625 cell->face(1)->set_boundary_id(4);
2626 cell->face(3)->set_boundary_id(5);
2636 const double radius,
2637 const bool internal_manifolds)
2642 const double a = 1. / (1 + std::sqrt(2.0));
2644 p +
Point<2>(-1, -1) * (radius / std::sqrt(2.0)),
2645 p + Point<2>(+1, -1) * (radius / std::sqrt(2.0)),
2646 p + Point<2>(-1, -1) * (radius / std::sqrt(2.0) * a),
2647 p + Point<2>(+1, -1) * (radius / std::sqrt(2.0) * a),
2648 p + Point<2>(-1, +1) * (radius / std::sqrt(2.0) * a),
2649 p + Point<2>(+1, +1) * (radius / std::sqrt(2.0) * a),
2650 p + Point<2>(-1, +1) * (radius / std::sqrt(2.0)),
2651 p + Point<2>(+1, +1) * (radius / std::sqrt(2.0))};
2653 const int cell_vertices[5][4] = {
2654 {0, 1, 2, 3}, {0, 2, 6, 4}, {2, 3, 4, 5}, {1, 7, 3, 5}, {6, 4, 7, 5}};
2658 for (
unsigned int i = 0; i < 5; ++i)
2660 for (
unsigned int j = 0; j < 4; ++j)
2661 cells[i].vertices[j] = cell_vertices[i][j];
2662 cells[i].material_id = 0;
2667 std::end(vertices)),
2672 if (internal_manifolds)
2681 const double inner_radius,
2682 const double outer_radius,
2683 const unsigned int n_cells,
2684 const bool colorize)
2686 Assert((inner_radius > 0) && (inner_radius < outer_radius),
2700 const unsigned int N =
2701 (n_cells == 0 ?
static_cast<unsigned int>(
2702 std::ceil((2 * pi * (outer_radius + inner_radius) / 2) /
2703 (outer_radius - inner_radius))) :
2712 std::vector<Point<2>> vertices(2 * N);
2713 for (
unsigned int i = 0; i < N; ++i)
2716 Point<2>(std::cos(2 * pi * i / N), std::sin(2 * pi * i / N)) *
2718 vertices[i + N] = vertices[i] * (inner_radius / outer_radius);
2720 vertices[i] += center;
2721 vertices[i + N] += center;
2726 for (
unsigned int i = 0; i < N; ++i)
2728 cells[i].vertices[0] = i;
2729 cells[i].vertices[1] = (i + 1) % N;
2730 cells[i].vertices[2] = N + i;
2731 cells[i].vertices[3] = N + ((i + 1) % N);
2733 cells[i].material_id = 0;
2739 colorize_hyper_shell(tria, center, inner_radius, outer_radius);
2749 const double radius,
2750 const double half_length)
2752 Point<2> p1(-half_length, -radius);
2761 switch (f->boundary_id())
2764 f->set_boundary_id(1);
2767 f->set_boundary_id(2);
2770 f->set_boundary_id(0);
2795 const double radius)
2797 const unsigned int dim = 2;
2803 p + Point<dim>(+1, 0) * radius,
2804 p + Point<dim>(+1, 0) * (radius / 2),
2805 p + Point<dim>(0, +1) * (radius / 2),
2806 p + Point<dim>(+1, +1) *
2807 (radius / (2 * sqrt(2.0))),
2808 p + Point<dim>(0, +1) * radius,
2809 p + Point<dim>(+1, +1) *
2810 (radius / std::sqrt(2.0))};
2812 const int cell_vertices[3][4] = {{0, 2, 3, 4}, {1, 6, 2, 4}, {5, 3, 6, 4}};
2816 for (
unsigned int i = 0; i < 3; ++i)
2818 for (
unsigned int j = 0; j < 4; ++j)
2819 cells[i].vertices[j] = cell_vertices[i][j];
2820 cells[i].material_id = 0;
2824 std::end(vertices)),
2835 for (
unsigned int i = 0; i < GeometryInfo<dim>::faces_per_cell; ++i)
2837 if (cell->face(i)->boundary_id() ==
2843 if (cell->face(i)->center()(0) < p(0) + 1.e-5 * radius ||
2844 cell->face(i)->center()(1) < p(1) + 1.e-5 * radius)
2846 cell->face(i)->set_boundary_id(1);
2859 const double radius)
2864 const double a = 1. / (1 + std::sqrt(2.0));
2867 p + Point<2>(+1, -1) * (radius / std::sqrt(2.0)),
2868 p + Point<2>(0, -1) * (radius / std::sqrt(2.0) * a),
2869 p + Point<2>(+1, -1) * (radius / std::sqrt(2.0) * a),
2870 p + Point<2>(0, +1) * (radius / std::sqrt(2.0) * a),
2871 p + Point<2>(+1, +1) * (radius / std::sqrt(2.0) * a),
2872 p + Point<2>(0, +1) * radius,
2873 p + Point<2>(+1, +1) * (radius / std::sqrt(2.0))};
2875 const int cell_vertices[5][4] = {{0, 1, 2, 3},
2882 for (
unsigned int i = 0; i < 4; ++i)
2884 for (
unsigned int j = 0; j < 4; ++j)
2885 cells[i].vertices[j] = cell_vertices[i][j];
2886 cells[i].material_id = 0;
2890 std::end(vertices)),
2901 for (
unsigned int i = 0; i < GeometryInfo<2>::faces_per_cell; ++i)
2903 if (cell->face(i)->boundary_id() ==
2908 if (cell->face(i)->center()(0) < p(0) + 1.e-5 * radius)
2910 cell->face(i)->set_boundary_id(1);
2925 const double inner_radius,
2926 const double outer_radius,
2927 const unsigned int n_cells,
2928 const bool colorize)
2930 Assert((inner_radius > 0) && (inner_radius < outer_radius),
2943 const unsigned int N =
2944 (n_cells == 0 ?
static_cast<unsigned int>(
2945 std::ceil((pi * (outer_radius + inner_radius) / 2) /
2946 (outer_radius - inner_radius))) :
2955 std::vector<Point<2>> vertices(2 * (N + 1));
2956 for (
unsigned int i = 0; i <= N; ++i)
2965 Point<2>(((i == 0) || (i == N) ? 0 : std::cos(pi * i / N - pi / 2)),
2966 std::sin(pi * i / N - pi / 2)) *
2968 vertices[i + N + 1] = vertices[i] * (inner_radius / outer_radius);
2970 vertices[i] += center;
2971 vertices[i + N + 1] += center;
2977 for (
unsigned int i = 0; i < N; ++i)
2979 cells[i].vertices[0] = i;
2980 cells[i].vertices[1] = (i + 1) % (N + 1);
2981 cells[i].vertices[2] = N + 1 + i;
2982 cells[i].vertices[3] = N + 1 + ((i + 1) % (N + 1));
2984 cells[i].material_id = 0;
2992 for (; cell != tria.
end(); ++cell)
2994 cell->face(2)->set_boundary_id(1);
2996 tria.
begin()->face(0)->set_boundary_id(3);
2998 tria.
last()->face(1)->set_boundary_id(2);
3008 const double inner_radius,
3009 const double outer_radius,
3010 const unsigned int n_cells,
3011 const bool colorize)
3013 Assert((inner_radius > 0) && (inner_radius < outer_radius),
3026 const unsigned int N =
3027 (n_cells == 0 ?
static_cast<unsigned int>(
3028 std::ceil((pi * (outer_radius + inner_radius) / 4) /
3029 (outer_radius - inner_radius))) :
3038 std::vector<Point<2>> vertices(2 * (N + 1));
3039 for (
unsigned int i = 0; i <= N; ++i)
3046 vertices[i] =
Point<2>(((i == N) ? 0 : std::cos(pi * i / N / 2)),
3047 std::sin(pi * i / N / 2)) *
3049 vertices[i + N + 1] = vertices[i] * (inner_radius / outer_radius);
3051 vertices[i] += center;
3052 vertices[i + N + 1] += center;
3058 for (
unsigned int i = 0; i < N; ++i)
3060 cells[i].vertices[0] = i;
3061 cells[i].vertices[1] = (i + 1) % (N + 1);
3062 cells[i].vertices[2] = N + 1 + i;
3063 cells[i].vertices[3] = N + 1 + ((i + 1) % (N + 1));
3065 cells[i].material_id = 0;
3073 for (; cell != tria.
end(); ++cell)
3075 cell->face(2)->set_boundary_id(1);
3077 tria.
begin()->face(0)->set_boundary_id(3);
3079 tria.
last()->face(1)->set_boundary_id(2);
3093 const bool colorize)
3095 const double rl2 = (right + left) / 2;
3096 const double len = (right - left) / 2.;
3109 const int cell_vertices[4][8] = {{0, 1, 3, 2, 10, 11, 13, 12},
3110 {9, 4, 2, 5, 19, 14, 12, 15},
3111 {3, 2, 7, 6, 13, 12, 17, 16},
3112 {2, 5, 6, 8, 12, 15, 16, 18}};
3114 for (
unsigned int i = 0; i < 4; ++i)
3116 for (
unsigned int j = 0; j < 8; ++j)
3117 cells[i].vertices[j] = cell_vertices[i][j];
3118 cells[i].material_id = 0;
3121 std::end(vertices)),
3128 cell->face(1)->set_boundary_id(1);
3130 cell->face(0)->set_boundary_id(2);
3141 const double thickness,
3142 const bool colorize)
3145 ExcMessage(
"Invalid left-to-right bounds of enclosed hypercube"));
3147 std::vector<Point<3>> vertices(64);
3149 coords[0] = left - thickness;
3152 coords[3] = right + thickness;
3155 for (
unsigned int z = 0; z < 4; ++z)
3156 for (
unsigned int y = 0; y < 4; ++y)
3157 for (
unsigned int x = 0; x < 4; ++x)
3158 vertices[k++] =
Point<3>(coords[x], coords[y], coords[z]);
3161 24, 26, 5, 4, 6, 1, 0,
3162 2, 9, 8, 10, 37, 36, 38,
3163 33, 32, 34, 41, 40, 42};
3165 std::vector<CellData<3>> cells(27);
3167 for (
unsigned int z = 0; z < 3; ++z)
3168 for (
unsigned int y = 0; y < 3; ++y)
3169 for (
unsigned int x = 0; x < 3; ++x)
3171 cells[k].vertices[0] = x + 4 * y + 16 * z;
3172 cells[k].vertices[1] = x + 4 * y + 16 * z + 1;
3173 cells[k].vertices[2] = x + 4 * y + 16 * z + 4;
3174 cells[k].vertices[3] = x + 4 * y + 16 * z + 5;
3175 cells[k].vertices[4] = x + 4 * y + 16 * z + 16;
3176 cells[k].vertices[5] = x + 4 * y + 16 * z + 17;
3177 cells[k].vertices[6] = x + 4 * y + 16 * z + 20;
3178 cells[k].vertices[7] = x + 4 * y + 16 * z + 21;
3180 cells[k].material_id = materials[k];
3192 const double radius_0,
3193 const double radius_1,
3194 const double half_length)
3197 const unsigned int n_cells =
static_cast<unsigned int>(
3198 std::ceil(half_length / std::max(radius_0, radius_1)));
3199 const unsigned int n_vertices = 4 * (n_cells + 1);
3200 std::vector<Point<3>> vertices_tmp(n_vertices);
3202 vertices_tmp[0] =
Point<3>(-half_length, 0, -radius_0);
3203 vertices_tmp[1] =
Point<3>(-half_length, radius_0, 0);
3204 vertices_tmp[2] =
Point<3>(-half_length, -radius_0, 0);
3205 vertices_tmp[3] =
Point<3>(-half_length, 0, radius_0);
3207 const double dx = 2 * half_length / n_cells;
3209 for (
unsigned int i = 0; i < n_cells; ++i)
3211 vertices_tmp[4 * (i + 1)] =
3212 vertices_tmp[4 * i] +
3213 Point<3>(dx, 0, 0.5 * (radius_0 - radius_1) * dx / half_length);
3214 vertices_tmp[4 * i + 5] =
3215 vertices_tmp[4 * i + 1] +
3216 Point<3>(dx, 0.5 * (radius_1 - radius_0) * dx / half_length, 0);
3217 vertices_tmp[4 * i + 6] =
3218 vertices_tmp[4 * i + 2] +
3219 Point<3>(dx, 0.5 * (radius_0 - radius_1) * dx / half_length, 0);
3220 vertices_tmp[4 * i + 7] =
3221 vertices_tmp[4 * i + 3] +
3222 Point<3>(dx, 0, 0.5 * (radius_1 - radius_0) * dx / half_length);
3225 const std::vector<Point<3>> vertices(vertices_tmp.begin(),
3226 vertices_tmp.end());
3230 for (
unsigned int i = 0; i < n_cells; ++i)
3231 for (
unsigned int j = 0; j < GeometryInfo<3>::vertices_per_cell; ++j)
3232 cell_vertices[i][j] = 4 * i + j;
3234 std::vector<CellData<3>> cells(n_cells,
CellData<3>());
3236 for (
unsigned int i = 0; i < n_cells; ++i)
3238 for (
unsigned int j = 0; j < GeometryInfo<3>::vertices_per_cell; ++j)
3239 cells[i].vertices[j] = cell_vertices[i][j];
3241 cells[i].material_id = 0;
3248 cell != triangulation.
end();
3251 if (cell->vertex(0)(0) == -half_length)
3253 cell->face(4)->set_boundary_id(1);
3256 for (
unsigned int i = 0; i < 4; ++i)
3257 cell->line(i)->set_boundary_id(0);
3260 if (cell->vertex(4)(0) == half_length)
3262 cell->face(5)->set_boundary_id(2);
3265 for (
unsigned int i = 4; i < 8; ++i)
3266 cell->line(i)->set_boundary_id(0);
3269 for (
unsigned int i = 0; i < 4; ++i)
3270 cell->face(i)->set_boundary_id(0);
3282 const bool colorize)
3292 Point<3>((a + b) / 2, a, (a + b) / 2),
3299 Point<3>((a + b) / 2, (a + b) / 2, a),
3301 Point<3>(a, (a + b) / 2, (a + b) / 2),
3302 Point<3>((a + b) / 2, (a + b) / 2, (a + b) / 2),
3303 Point<3>(b, (a + b) / 2, (a + b) / 2),
3305 Point<3>((a + b) / 2, (a + b) / 2, b),
3313 Point<3>((a + b) / 2, b, (a + b) / 2),
3317 const int cell_vertices[7][8] = {{0, 1, 9, 10, 3, 4, 12, 13},
3318 {1, 2, 10, 11, 4, 5, 13, 14},
3319 {3, 4, 12, 13, 6, 7, 15, 16},
3320 {4, 5, 13, 14, 7, 8, 16, 17},
3321 {9, 10, 18, 19, 12, 13, 21, 22},
3322 {10, 11, 19, 20, 13, 14, 22, 23},
3323 {12, 13, 21, 22, 15, 16, 24, 25}};
3327 for (
unsigned int i = 0; i < 7; ++i)
3329 for (
unsigned int j = 0; j < 8; ++j)
3330 cells[i].vertices[j] = cell_vertices[i][j];
3331 cells[i].material_id = 0;
3335 std::end(vertices)),
3351 const double radius,
3352 const bool internal_manifold)
3355 1. / (1 + std::sqrt(3.0));
3358 const unsigned int n_vertices = 16;
3359 const Point<3> vertices[n_vertices] = {
3362 p +
Point<3>(-1, -1, -1) * (radius / std::sqrt(3.0) * a),
3363 p + Point<3>(+1, -1, -1) * (radius / std::sqrt(3.0) * a),
3364 p + Point<3>(+1, -1, +1) * (radius / std::sqrt(3.0) * a),
3365 p + Point<3>(-1, -1, +1) * (radius / std::sqrt(3.0) * a),
3366 p + Point<3>(-1, +1, -1) * (radius / std::sqrt(3.0) * a),
3367 p + Point<3>(+1, +1, -1) * (radius / std::sqrt(3.0) * a),
3368 p + Point<3>(+1, +1, +1) * (radius / std::sqrt(3.0) * a),
3369 p + Point<3>(-1, +1, +1) * (radius / std::sqrt(3.0) * a),
3372 p + Point<3>(-1, -1, -1) * (radius / std::sqrt(3.0)),
3373 p + Point<3>(+1, -1, -1) * (radius / std::sqrt(3.0)),
3374 p + Point<3>(+1, -1, +1) * (radius / std::sqrt(3.0)),
3375 p + Point<3>(-1, -1, +1) * (radius / std::sqrt(3.0)),
3376 p + Point<3>(-1, +1, -1) * (radius / std::sqrt(3.0)),
3377 p + Point<3>(+1, +1, -1) * (radius / std::sqrt(3.0)),
3378 p + Point<3>(+1, +1, +1) * (radius / std::sqrt(3.0)),
3379 p + Point<3>(-1, +1, +1) * (radius / std::sqrt(3.0)),
3384 const unsigned int n_cells = 7;
3385 const int cell_vertices[n_cells][8] = {
3386 {0, 1, 4, 5, 3, 2, 7, 6},
3387 {8, 9, 12, 13, 0, 1, 4, 5},
3388 {9, 13, 1, 5, 10, 14, 2, 6},
3389 {11, 10, 3, 2, 15, 14, 7, 6},
3390 {8, 0, 12, 4, 11, 3, 15, 7},
3391 {8, 9, 0, 1, 11, 10, 3, 2},
3392 {12, 4, 13, 5, 15, 7, 14, 6}};
3394 std::vector<CellData<3>> cells(n_cells,
CellData<3>());
3396 for (
unsigned int i = 0; i < n_cells; ++i)
3398 for (
unsigned int j = 0; j < GeometryInfo<3>::vertices_per_cell; ++j)
3399 cells[i].vertices[j] = cell_vertices[i][j];
3400 cells[i].material_id = 0;
3405 std::end(vertices)),
3410 if (internal_manifold)
3416 template <
int spacedim>
3419 const double radius)
3423 std::set<types::boundary_id> boundary_ids;
3424 boundary_ids.insert(0);
3435 const double radius,
3436 const double half_length)
3440 const double d = radius / std::sqrt(2.0);
3441 const double a = d / (1 + std::sqrt(2.0));
3469 for (
unsigned int i = 0; i < 24; ++i)
3471 const double h = vertices[i](1);
3472 vertices[i](1) = -vertices[i](0);
3476 int cell_vertices[10][8] = {{0, 1, 8, 9, 2, 3, 10, 11},
3477 {0, 2, 8, 10, 6, 4, 14, 12},
3478 {2, 3, 10, 11, 4, 5, 12, 13},
3479 {1, 7, 9, 15, 3, 5, 11, 13},
3480 {6, 4, 14, 12, 7, 5, 15, 13}};
3481 for (
unsigned int i = 0; i < 5; ++i)
3482 for (
unsigned int j = 0; j < 8; ++j)
3483 cell_vertices[i + 5][j] = cell_vertices[i][j] + 8;
3485 std::vector<CellData<3>> cells(10,
CellData<3>());
3487 for (
unsigned int i = 0; i < 10; ++i)
3489 for (
unsigned int j = 0; j < 8; ++j)
3490 cells[i].vertices[j] = cell_vertices[i][j];
3491 cells[i].material_id = 0;
3495 std::end(vertices)),
3514 for (; cell != end; ++cell)
3515 for (
unsigned int i = 0; i < GeometryInfo<3>::faces_per_cell; ++i)
3516 if (cell->at_boundary(i))
3518 if (cell->face(i)->center()(0) > half_length - 1.e-5)
3520 cell->face(i)->set_boundary_id(2);
3523 for (
unsigned int e = 0; e < GeometryInfo<3>::lines_per_face;
3525 if ((std::fabs(cell->face(i)->line(e)->vertex(0)[1]) == a) ||
3526 (std::fabs(cell->face(i)->line(e)->vertex(0)[2]) == a) ||
3527 (std::fabs(cell->face(i)->line(e)->vertex(1)[1]) == a) ||
3528 (std::fabs(cell->face(i)->line(e)->vertex(1)[2]) == a))
3530 cell->face(i)->line(e)->set_boundary_id(2);
3531 cell->face(i)->line(e)->set_manifold_id(
3535 else if (cell->face(i)->center()(0) < -half_length + 1.e-5)
3537 cell->face(i)->set_boundary_id(1);
3540 for (
unsigned int e = 0; e < GeometryInfo<3>::lines_per_face;
3542 if ((std::fabs(cell->face(i)->line(e)->vertex(0)[1]) == a) ||
3543 (std::fabs(cell->face(i)->line(e)->vertex(0)[2]) == a) ||
3544 (std::fabs(cell->face(i)->line(e)->vertex(1)[1]) == a) ||
3545 (std::fabs(cell->face(i)->line(e)->vertex(1)[2]) == a))
3547 cell->face(i)->line(e)->set_boundary_id(1);
3548 cell->face(i)->line(e)->set_manifold_id(
3560 const double radius)
3562 const unsigned int dim = 3;
3569 center + Point<dim>(+1, 0, 0) * radius,
3570 center + Point<dim>(+1, 0, 0) * (radius / 2.),
3571 center + Point<dim>(0, +1, 0) * (radius / 2.),
3572 center + Point<dim>(+1, +1, 0) * (radius / (2 * sqrt(2.0))),
3573 center + Point<dim>(0, +1, 0) * radius,
3574 center + Point<dim>(+1, +1, 0) * (radius / std::sqrt(2.0)),
3575 center + Point<dim>(0, 0, 1) * radius / 2.,
3576 center + Point<dim>(+1, 0, 1) * radius / std::sqrt(2.0),
3577 center + Point<dim>(+1, 0, 1) * (radius / (2 * std::sqrt(2.0))),
3578 center + Point<dim>(0, +1, 1) * (radius / (2 * std::sqrt(2.0))),
3579 center + Point<dim>(+1, +1, 1) * (radius / (2 * std::sqrt(3.0))),
3580 center + Point<dim>(0, +1, 1) * radius / std::sqrt(2.0),
3581 center + Point<dim>(+1, +1, 1) * (radius / (std::sqrt(3.0))),
3582 center + Point<dim>(0, 0, 1) * radius};
3583 const int cell_vertices[4][8] = {{0, 2, 3, 4, 7, 9, 10, 11},
3584 {1, 6, 2, 4, 8, 13, 9, 11},
3585 {5, 3, 6, 4, 12, 10, 13, 11},
3586 {7, 9, 10, 11, 14, 8, 12, 13}};
3590 for (
unsigned int i = 0; i < 4; ++i)
3592 for (
unsigned int j = 0; j < 8; ++j)
3593 cells[i].vertices[j] = cell_vertices[i][j];
3594 cells[i].material_id = 0;
3598 std::end(vertices)),
3608 for (
unsigned int i = 0; i < GeometryInfo<dim>::faces_per_cell; ++i)
3610 if (cell->face(i)->boundary_id() ==
3615 if (cell->face(i)->center()(0) < center(0) + 1.e-5 * radius ||
3616 cell->face(i)->center()(1) < center(1) + 1.e-5 * radius ||
3617 cell->face(i)->center()(2) < center(2) + 1.e-5 * radius)
3619 cell->face(i)->set_boundary_id(1);
3623 for (
unsigned int j = 0; j < GeometryInfo<3>::lines_per_face;
3626 const Point<3> line_vertices[2] = {
3627 cell->face(i)->line(j)->vertex(0),
3628 cell->face(i)->line(j)->vertex(1)};
3629 if ((std::fabs(line_vertices[0].distance(center) - radius) >
3631 (std::fabs(line_vertices[1].distance(center) - radius) >
3634 cell->face(i)->line(j)->set_boundary_id(1);
3635 cell->face(i)->line(j)->set_manifold_id(
3651 const double radius)
3654 const double d = radius / std::sqrt(2.0);
3655 const double a = d / (1 + std::sqrt(2.0));
3657 const double b = a / 2.0;
3658 const double c = d / 2.0;
3660 const double hb = radius * std::sqrt(3.0) / 4.0;
3661 const double hc = radius * std::sqrt(3.0) / 2.0;
3665 center + Point<3>(0, -d, -d),
3666 center + Point<3>(0, a, -a),
3667 center + Point<3>(0, -a, -a),
3668 center + Point<3>(0, a, a),
3669 center + Point<3>(0, -a, a),
3670 center + Point<3>(0, d, d),
3671 center + Point<3>(0, -d, d),
3673 center + Point<3>(hc, c, -c),
3674 center + Point<3>(hc, -c, -c),
3675 center + Point<3>(hb, b, -b),
3676 center + Point<3>(hb, -b, -b),
3677 center + Point<3>(hb, b, b),
3678 center + Point<3>(hb, -b, b),
3679 center + Point<3>(hc, c, c),
3680 center + Point<3>(hc, -c, c),
3683 int cell_vertices[6][8] = {{0, 1, 8, 9, 2, 3, 10, 11},
3684 {0, 2, 8, 10, 6, 4, 14, 12},
3685 {2, 3, 10, 11, 4, 5, 12, 13},
3686 {1, 7, 9, 15, 3, 5, 11, 13},
3687 {6, 4, 14, 12, 7, 5, 15, 13},
3688 {8, 10, 9, 11, 14, 12, 15, 13}};
3692 for (
unsigned int i = 0; i < 6; ++i)
3694 for (
unsigned int j = 0; j < 8; ++j)
3695 cells[i].vertices[j] = cell_vertices[i][j];
3696 cells[i].material_id = 0;
3700 std::end(vertices)),
3716 for (
unsigned int i = 0; i < GeometryInfo<3>::faces_per_cell; ++i)
3718 if (!cell->at_boundary(i))
3724 if (cell->face(i)->center()(0) < center(0) + 1.e-5 * radius)
3726 cell->face(i)->set_boundary_id(1);
3728 for (
unsigned int j = 0; j < GeometryInfo<3>::lines_per_face;
3731 const Point<3> line_vertices[2] = {
3732 cell->face(i)->line(j)->vertex(0),
3733 cell->face(i)->line(j)->vertex(1)};
3734 if ((std::fabs(line_vertices[0].distance(center) - radius) >
3736 (std::fabs(line_vertices[1].distance(center) - radius) >
3739 cell->face(i)->line(j)->set_boundary_id(1);
3740 cell->face(i)->line(j)->set_manifold_id(
3755 const double inner_radius,
3756 const double outer_radius,
3757 const unsigned int n_cells,
3758 const bool colorize)
3760 Assert((inner_radius > 0) && (inner_radius < outer_radius),
3763 const unsigned int n = (n_cells == 0) ? 6 : n_cells;
3765 const double irad = inner_radius / std::sqrt(3.0);
3766 const double orad = outer_radius / std::sqrt(3.0);
3767 std::vector<Point<3>> vertices;
3768 std::vector<CellData<3>> cells;
3774 for (
unsigned int i = 0; i < 8; ++i)
3775 vertices.push_back(p + hexahedron[i] * irad);
3776 for (
unsigned int i = 0; i < 8; ++i)
3777 vertices.push_back(p + hexahedron[i] * orad);
3779 const unsigned int n_cells = 6;
3780 const int cell_vertices[n_cells][8] = {
3781 {8, 9, 10, 11, 0, 1, 2, 3},
3782 {9, 11, 1, 3, 13, 15, 5, 7},
3783 {12, 13, 4, 5, 14, 15, 6, 7},
3784 {8, 0, 10, 2, 12, 4, 14, 6},
3785 {8, 9, 0, 1, 12, 13, 4, 5},
3786 {10, 2, 11, 3, 14, 6, 15, 7}};
3790 for (
unsigned int i = 0; i < n_cells; ++i)
3792 for (
unsigned int j = 0; j < GeometryInfo<3>::vertices_per_cell;
3794 cells[i].vertices[j] = cell_vertices[i][j];
3795 cells[i].material_id = 0;
3805 for (
unsigned int i = 0; i < 8; ++i)
3806 vertices.push_back(p + hexahedron[i] * irad);
3807 for (
unsigned int i = 0; i < 6; ++i)
3808 vertices.push_back(p + octahedron[i] * inner_radius);
3809 for (
unsigned int i = 0; i < 8; ++i)
3810 vertices.push_back(p + hexahedron[i] * orad);
3811 for (
unsigned int i = 0; i < 6; ++i)
3812 vertices.push_back(p + octahedron[i] * outer_radius);
3814 const unsigned int n_cells = 12;
3815 const unsigned int rhombi[n_cells][4] = {{10, 4, 0, 8},
3830 for (
unsigned int i = 0; i < n_cells; ++i)
3832 for (
unsigned int j = 0; j < 4; ++j)
3834 cells[i].vertices[j] = rhombi[i][j];
3835 cells[i].vertices[j + 4] = rhombi[i][j] + 14;
3837 cells[i].material_id = 0;
3849 hyper_shell(tmp, p, inner_radius, outer_radius, 12);
3858 const unsigned int cell_index = cell->active_cell_index();
3859 for (
unsigned int v = 0; v < GeometryInfo<3>::vertices_per_cell;
3861 cells[cell_index].vertices[v] = cell->vertex_index(v);
3862 cells[cell_index].material_id = 0;
3873 colorize_hyper_shell(tria, p, inner_radius, outer_radius);
3884 const double inner_radius,
3885 const double outer_radius,
3886 const unsigned int n,
3887 const bool colorize)
3889 Assert((inner_radius > 0) && (inner_radius < outer_radius),
3895 const double d = outer_radius / std::sqrt(2.0);
3896 const double a = inner_radius / std::sqrt(2.0);
3898 const double b = a / 2.0;
3899 const double c = d / 2.0;
3901 const double hb = inner_radius * std::sqrt(3.0) / 2.0;
3902 const double hc = outer_radius * std::sqrt(3.0) / 2.0;
3906 center + Point<3>(0, -d, -d),
3907 center + Point<3>(0, a, -a),
3908 center + Point<3>(0, -a, -a),
3909 center + Point<3>(0, a, a),
3910 center + Point<3>(0, -a, a),
3911 center + Point<3>(0, d, d),
3912 center + Point<3>(0, -d, d),
3914 center + Point<3>(hc, c, -c),
3915 center + Point<3>(hc, -c, -c),
3916 center + Point<3>(hb, b, -b),
3917 center + Point<3>(hb, -b, -b),
3918 center + Point<3>(hb, b, b),
3919 center + Point<3>(hb, -b, b),
3920 center + Point<3>(hc, c, c),
3921 center + Point<3>(hc, -c, c),
3924 int cell_vertices[5][8] = {{0, 1, 8, 9, 2, 3, 10, 11},
3925 {0, 2, 8, 10, 6, 4, 14, 12},
3926 {1, 7, 9, 15, 3, 5, 11, 13},
3927 {6, 4, 14, 12, 7, 5, 15, 13},
3928 {8, 10, 9, 11, 14, 12, 15, 13}};
3932 for (
unsigned int i = 0; i < 5; ++i)
3934 for (
unsigned int j = 0; j < 8; ++j)
3935 cells[i].vertices[j] = cell_vertices[i][j];
3936 cells[i].material_id = 0;
3940 std::end(vertices)),
3954 for (; cell != tria.
end(); ++cell)
3955 for (
unsigned int i = 0; i < GeometryInfo<3>::faces_per_cell; ++i)
3956 if (cell->at_boundary(i))
3957 cell->face(i)->set_all_boundary_ids(2);
3963 for (cell = tria.
begin(); cell != tria.
end(); ++cell)
3964 for (
unsigned int i = 0; i < GeometryInfo<3>::faces_per_cell; ++i)
3965 if (cell->at_boundary(i))
3969 const Point<3> face_center(face->center());
3970 if (std::abs(face_center(0) - center(0)) >
3971 1.e-6 * face_center.norm())
3973 if (std::abs((face_center - center).norm() - inner_radius) <
3974 std::abs((face_center - center).norm() - outer_radius))
3975 face->set_all_boundary_ids(0);
3977 face->set_all_boundary_ids(1);
3990 const double inner_radius,
3991 const double outer_radius,
3992 const unsigned int n,
3993 const bool colorize)
3995 Assert((inner_radius > 0) && (inner_radius < outer_radius),
3997 if (n == 0 || n == 3)
3999 const double a = inner_radius * std::sqrt(2.0) / 2e0;
4000 const double b = outer_radius * std::sqrt(2.0) / 2e0;
4001 const double c = a * std::sqrt(3.0) / 2e0;
4002 const double d = b * std::sqrt(3.0) / 2e0;
4003 const double e = outer_radius / 2e0;
4004 const double h = inner_radius / 2e0;
4006 std::vector<Point<3>> vertices;
4008 vertices.push_back(center +
Point<3>(0, inner_radius, 0));
4009 vertices.push_back(center +
Point<3>(a, a, 0));
4010 vertices.push_back(center +
Point<3>(b, b, 0));
4011 vertices.push_back(center +
Point<3>(0, outer_radius, 0));
4012 vertices.push_back(center +
Point<3>(0, a, a));
4013 vertices.push_back(center +
Point<3>(c, c, h));
4014 vertices.push_back(center +
Point<3>(d, d, e));
4015 vertices.push_back(center +
Point<3>(0, b, b));
4016 vertices.push_back(center +
Point<3>(inner_radius, 0, 0));
4017 vertices.push_back(center +
Point<3>(outer_radius, 0, 0));
4018 vertices.push_back(center +
Point<3>(a, 0, a));
4019 vertices.push_back(center +
Point<3>(b, 0, b));
4020 vertices.push_back(center +
Point<3>(0, 0, inner_radius));
4021 vertices.push_back(center +
Point<3>(0, 0, outer_radius));
4023 const int cell_vertices[3][8] = {
4024 {0, 1, 3, 2, 4, 5, 7, 6},
4025 {1, 8, 2, 9, 5, 10, 6, 11},
4026 {4, 5, 7, 6, 12, 10, 13, 11},
4028 std::vector<CellData<3>> cells(3);
4030 for (
unsigned int i = 0; i < 3; ++i)
4032 for (
unsigned int j = 0; j < 8; ++j)
4033 cells[i].vertices[j] = cell_vertices[i][j];
4034 cells[i].material_id = 0;
4047 colorize_quarter_hyper_shell(tria, center, inner_radius, outer_radius);
4057 const double length,
4058 const double inner_radius,
4059 const double outer_radius,
4060 const unsigned int n_radial_cells,
4061 const unsigned int n_axial_cells)
4063 Assert((inner_radius > 0) && (inner_radius < outer_radius),
4077 const unsigned int N_r =
4078 (n_radial_cells == 0 ?
static_cast<unsigned int>(std::ceil(
4079 (2 * pi * (outer_radius + inner_radius) / 2) /
4080 (outer_radius - inner_radius))) :
4082 const unsigned int N_z =
4083 (n_axial_cells == 0 ?
4084 static_cast<unsigned int>(std::ceil(
4085 length / (2 * pi * (outer_radius + inner_radius) / 2 / N_r))) :
4094 std::vector<Point<2>> vertices_2d(2 * N_r);
4095 for (
unsigned int i = 0; i < N_r; ++i)
4098 Point<2>(std::cos(2 * pi * i / N_r), std::sin(2 * pi * i / N_r)) *
4100 vertices_2d[i + N_r] = vertices_2d[i] * (inner_radius / outer_radius);
4103 std::vector<Point<3>> vertices_3d;
4104 vertices_3d.reserve(2 * N_r * (N_z + 1));
4105 for (
unsigned int j = 0; j <= N_z; ++j)
4106 for (
unsigned int i = 0; i < 2 * N_r; ++i)
4108 const Point<3> v(vertices_2d[i][0],
4111 vertices_3d.push_back(v);
4114 std::vector<CellData<3>> cells(N_r * N_z,
CellData<3>());
4116 for (
unsigned int j = 0; j < N_z; ++j)
4117 for (
unsigned int i = 0; i < N_r; ++i)
4119 cells[i + j * N_r].vertices[0] = i + (j + 1) * 2 * N_r;
4120 cells[i + j * N_r].vertices[1] = (i + 1) % N_r + (j + 1) * 2 * N_r;
4121 cells[i + j * N_r].vertices[2] = i + j * 2 * N_r;
4122 cells[i + j * N_r].vertices[3] = (i + 1) % N_r + j * 2 * N_r;
4124 cells[i + j * N_r].vertices[4] = N_r + i + (j + 1) * 2 * N_r;
4125 cells[i + j * N_r].vertices[5] =
4126 N_r + ((i + 1) % N_r) + (j + 1) * 2 * N_r;
4127 cells[i + j * N_r].vertices[6] = N_r + i + j * 2 * N_r;
4128 cells[i + j * N_r].vertices[7] = N_r + ((i + 1) % N_r) + j * 2 * N_r;
4130 cells[i + j * N_r].material_id = 0;
4140 template <
int dim,
int spacedim>
4146 const double duplicated_vertex_tolerance,
4147 const bool copy_manifold_ids)
4149 for (
const auto triangulation : triangulations)
4151 (void)triangulation;
4153 ExcMessage(
"The input triangulations must be non-empty " 4154 "and must not be refined."));
4158 unsigned int n_vertices = 0;
4159 for (
const auto triangulation : triangulations)
4162 std::vector<Point<spacedim>> vertices;
4163 vertices.reserve(n_vertices);
4164 for (
const auto triangulation : triangulations)
4165 vertices.insert(vertices.end(),
4170 std::vector<CellData<dim>> cells;
4171 unsigned int n_cells = 0;
4172 for (
const auto triangulation : triangulations)
4173 n_cells += triangulation->
n_cells();
4175 cells.reserve(n_cells);
4176 unsigned int n_accumulated_vertices = 0;
4177 for (
const auto triangulation : triangulations)
4182 for (
unsigned int v = 0; v < GeometryInfo<dim>::vertices_per_cell;
4185 cell->vertex_index(v) + n_accumulated_vertices;
4188 cells.push_back(std::move(this_cell));
4190 n_accumulated_vertices += triangulation->
n_vertices();
4195 if (copy_manifold_ids)
4204 unsigned int n_boundary_lines = 0;
4205 for (
const auto triangulation : triangulations)
4206 n_boundary_lines += triangulation->
n_lines();
4210 auto copy_line_manifold_ids =
4212 const unsigned int offset) {
4213 for (
typename Triangulation<dim, spacedim>::line_iterator
4221 line->vertex_index(0) + offset;
4223 line->vertex_index(1) + offset;
4230 unsigned int n_accumulated_vertices = 0;
4231 for (
const auto triangulation : triangulations)
4233 copy_line_manifold_ids(*triangulation,
4234 n_accumulated_vertices);
4235 n_accumulated_vertices += triangulation->
n_vertices();
4242 unsigned int n_boundary_quads = 0;
4243 for (
const auto triangulation : triangulations)
4244 n_boundary_quads += triangulation->
n_quads();
4253 auto copy_face_and_line_manifold_ids =
4255 const unsigned int offset) {
4264 face->vertex_index(0) + offset;
4266 face->vertex_index(1) + offset;
4268 face->vertex_index(2) + offset;
4270 face->vertex_index(3) + offset;
4277 for (
unsigned int l = 0; l < 12; ++l)
4278 if (cell->line(l)->manifold_id() !=
4283 cell->line(l)->vertex_index(0) + offset;
4285 cell->line(l)->vertex_index(1) + offset;
4287 cell->line(l)->manifold_id();
4292 unsigned int n_accumulated_vertices = 0;
4293 for (
const auto triangulation : triangulations)
4295 copy_face_and_line_manifold_ids(*triangulation,
4296 n_accumulated_vertices);
4297 n_accumulated_vertices += triangulation->
n_vertices();
4307 std::vector<unsigned int> considered_vertices;
4311 considered_vertices,
4312 duplicated_vertex_tolerance);
4323 template <
int dim,
int spacedim>
4328 const double duplicated_vertex_tolerance,
4329 const bool copy_manifold_ids)
4332 if (triangulation_1.
n_cells() == 0)
4337 if (triangulation_2.
n_cells() == 0)
4344 duplicated_vertex_tolerance,
4350 template <
int dim,
int spacedim>
4358 ExcMessage(
"The two input triangulations are not derived from " 4359 "the same coarse mesh as required."));
4362 &triangulation_1) ==
nullptr) &&
4365 &triangulation_2) ==
nullptr),
4366 ExcMessage(
"The source triangulations for this function must both " 4367 "be available entirely locally, and not be distributed " 4368 "triangulations."));
4385 for (
unsigned int iteration = 0; iteration < triangulation_2.
n_levels();
4391 bool any_cell_flagged =
false;
4394 result_cell != result.
end();
4396 if (intergrid_map[result_cell]->has_children())
4398 any_cell_flagged =
true;
4399 result_cell->set_refine_flag();
4402 if (any_cell_flagged ==
false)
4411 template <
int dim,
int spacedim>
4421 std::vector<Point<spacedim>> vertices = input_triangulation.
get_vertices();
4425 std::vector<CellData<dim>> cells;
4428 cell != input_triangulation.
end();
4430 if (cells_to_remove.find(cell) == cells_to_remove.end())
4432 Assert(static_cast<unsigned int>(cell->level()) ==
4433 input_triangulation.
n_levels() - 1,
4435 "Your input triangulation appears to have " 4436 "adaptively refined cells. This is not allowed. You can " 4437 "only call this function on a triangulation in which " 4438 "all cells are on the same refinement level."));
4441 for (
unsigned int v = 0; v < GeometryInfo<dim>::vertices_per_cell;
4443 this_cell.
vertices[v] = cell->vertex_index(v);
4444 this_cell.material_id = cell->material_id();
4445 cells.push_back(this_cell);
4451 std::vector<unsigned int> considered_vertices;
4455 considered_vertices);
4466 const unsigned int n_slices,
4467 const double height,
4472 "The input triangulation must be a coarse mesh, i.e., it must " 4473 "not have been refined."));
4475 ExcMessage(
"The output triangulation object needs to be empty."));
4477 ExcMessage(
"The given height for extrusion must be positive."));
4480 "The number of slices for extrusion must be at least 2."));
4482 const double delta_h = height / (n_slices - 1);
4483 std::vector<double> slices_z_values;
4484 for (
unsigned int i = 0; i < n_slices; ++i)
4485 slices_z_values.push_back(i * delta_h);
4491 const std::vector<double> &slice_coordinates,
4496 "The input triangulation must be a coarse mesh, i.e., it must " 4497 "not have been refined."));
4499 ExcMessage(
"The output triangulation object needs to be empty."));
4500 Assert(slice_coordinates.size() >= 2,
4502 "The number of slices for extrusion must be at least 2."));
4503 const unsigned int n_slices = slice_coordinates.size();
4504 Assert(std::is_sorted(slice_coordinates.begin(), slice_coordinates.end()),
4505 ExcMessage(
"Slice z-coordinates should be in ascending order"));
4506 std::vector<Point<3>> points(n_slices * input.
n_vertices());
4507 std::vector<CellData<3>> cells;
4512 for (
unsigned int slice = 0; slice < n_slices; ++slice)
4514 for (
unsigned int i = 0; i < input.
n_vertices(); ++i)
4517 points[slice * input.
n_vertices() + i](0) = v(0);
4518 points[slice * input.
n_vertices() + i](1) = v(1);
4520 slice_coordinates[slice];
4527 cell != input.
end();
4530 for (
unsigned int slice = 0; slice < n_slices - 1; ++slice)
4533 for (
unsigned int v = 0; v < GeometryInfo<2>::vertices_per_cell;
4537 cell->vertex_index(v) + slice * input.
n_vertices();
4539 cell->vertex_index(v) + (slice + 1) * input.
n_vertices();
4543 cells.push_back(this_cell);
4556 cell != input.
end();
4560 for (
unsigned int f = 0; f < 4; ++f)
4561 if (cell->at_boundary(f) && (cell->face(f)->boundary_id() != 0))
4564 max_boundary_id = std::max(max_boundary_id, quad.
boundary_id);
4565 for (
unsigned int slice = 0; slice < n_slices - 1; ++slice)
4568 cell->face(f)->vertex_index(0) + slice * input.
n_vertices();
4570 cell->face(f)->vertex_index(1) + slice * input.
n_vertices();
4571 quad.
vertices[2] = cell->face(f)->vertex_index(0) +
4573 quad.
vertices[3] = cell->face(f)->vertex_index(1) +
4587 "The input triangulation to this function is using boundary " 4588 "indicators in a range that do not allow using " 4589 "max_boundary_id+1 and max_boundary_id+2 as boundary " 4590 "indicators for the bottom and top faces of the " 4591 "extruded triangulation."));
4593 cell != input.
end();
4598 quad.
vertices[0] = cell->vertex_index(0);
4599 quad.
vertices[1] = cell->vertex_index(1);
4600 quad.
vertices[2] = cell->vertex_index(2);
4601 quad.
vertices[3] = cell->vertex_index(3);
4605 for (
int i = 0; i < 4; ++i)
4637 const double inner_radius,
4638 const double outer_radius,
4641 const bool colorize)
4645 Assert(inner_radius < outer_radius,
4646 ExcMessage(
"outer_radius has to be bigger than inner_radius."));
4650 hyper_shell(triangulation, center, inner_radius, outer_radius, 8);
4654 endc = triangulation.
end();
4655 std::vector<bool> treated_vertices(triangulation.
n_vertices(),
false);
4656 for (; cell != endc; ++cell)
4658 for (
unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell; ++f)
4659 if (cell->face(f)->at_boundary())
4661 for (
unsigned int v = 0; v < GeometryInfo<dim>::vertices_per_face;
4664 unsigned int vv = cell->face(f)->vertex_index(v);
4665 if (treated_vertices[vv] ==
false)
4667 treated_vertices[vv] =
true;
4671 cell->face(f)->vertex(v) =
4672 center +
Point<dim>(outer_radius, outer_radius);
4675 cell->face(f)->vertex(v) =
4676 center + Point<dim>(-outer_radius, outer_radius);
4679 cell->face(f)->vertex(v) =
4680 center + Point<dim>(-outer_radius, -outer_radius);
4683 cell->face(f)->vertex(v) =
4684 center + Point<dim>(outer_radius, -outer_radius);
4693 double eps = 1e-3 * outer_radius;
4695 for (; cell != endc; ++cell)
4697 for (
unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell; ++f)
4698 if (cell->face(f)->at_boundary())
4700 double dx = cell->face(f)->center()(0) - center(0);
4701 double dy = cell->face(f)->center()(1) - center(1);
4704 if (std::abs(dx + outer_radius) < eps)
4705 cell->face(f)->set_boundary_id(0);
4706 else if (std::abs(dx - outer_radius) < eps)
4707 cell->face(f)->set_boundary_id(1);
4708 else if (std::abs(dy + outer_radius) < eps)
4709 cell->face(f)->set_boundary_id(2);
4710 else if (std::abs(dy - outer_radius) < eps)
4711 cell->face(f)->set_boundary_id(3);
4714 cell->face(f)->set_boundary_id(4);
4715 cell->face(f)->set_manifold_id(0);
4720 double d = (cell->face(f)->center() - center).norm();
4721 if (d - inner_radius < 0)
4723 cell->face(f)->set_boundary_id(1);
4724 cell->face(f)->set_manifold_id(0);
4727 cell->face(f)->set_boundary_id(0);
4740 const double inner_radius,
4741 const double outer_radius,
4742 const unsigned int n_shells,
4743 const double skewness,
4744 const unsigned int n_cells,
4745 const bool colorize)
4750 Assert(inner_radius < outer_radius,
4751 ExcMessage(
"outer_radius has to be bigger than inner_radius."));
4755 std::vector<double> radii;
4756 radii.push_back(inner_radius);
4757 for (
unsigned int shell_n = 1; shell_n < n_shells; ++shell_n)
4758 if (skewness == 0.0)
4760 radii.push_back(inner_radius +
4761 (outer_radius - inner_radius) *
4762 (1.0 - (1.0 -
double(shell_n) / n_shells)));
4766 (outer_radius - inner_radius) *
4767 (1.0 - std::tanh(skewness * (1.0 -
double(shell_n) / n_shells)) /
4768 std::tanh(skewness)));
4769 radii.push_back(outer_radius);
4772 double length = std::numeric_limits<double>::max();
4774 for (
unsigned int n = 0; n < GeometryInfo<dim>::lines_per_cell; ++n)
4775 length = std::min(length, cell->line(n)->diameter());
4779 double grid_vertex_tolerance = 0.0;
4780 for (
unsigned int shell_n = 0; shell_n < radii.size() - 1; ++shell_n)
4787 n_cells == 0 ? (dim == 2 ? 8 : 12) :
4792 if (grid_vertex_tolerance == 0.0)
4793 grid_vertex_tolerance = 0.5 * min_line_length(current_shell);
4796 triangulation.
clear();
4800 grid_vertex_tolerance);
4812 constexpr
double radial_vertex_tolerance =
4813 100.0 * std::numeric_limits<double>::epsilon();
4814 auto assert_vertex_distance_within_tolerance =
4815 [center, radial_vertex_tolerance](
4817 const double radius) {
4819 (void)radial_vertex_tolerance;
4822 for (
unsigned int vertex_n = 0;
4823 vertex_n < GeometryInfo<dim>::vertices_per_face;
4826 Assert(std::abs((face->vertex(vertex_n) - center).norm() - radius) <
4827 (center.
norm() + radius) * radial_vertex_tolerance,
4833 for (
unsigned int face_n = 0;
4834 face_n < GeometryInfo<dim>::faces_per_cell;
4837 auto face = cell->face(face_n);
4838 if (face->at_boundary())
4840 if (((face->vertex(0) - center).norm() - inner_radius) <
4841 (center.
norm() + inner_radius) * radial_vertex_tolerance)
4844 assert_vertex_distance_within_tolerance(face, inner_radius);
4845 face->set_all_boundary_ids(0);
4850 assert_vertex_distance_within_tolerance(face, outer_radius);
4851 face->set_all_boundary_ids(1);
4861 const double inner_radius,
4862 const double outer_radius,
4864 const unsigned int Nz,
4865 const bool colorize)
4869 Assert(inner_radius < outer_radius,
4870 ExcMessage(
"outer_radius has to be bigger than inner_radius."));
4874 cylinder_shell(triangulation, L, inner_radius, outer_radius, 8, Nz);
4879 endc = triangulation.
end();
4880 std::vector<bool> treated_vertices(triangulation.
n_vertices(),
false);
4881 for (; cell != endc; ++cell)
4883 for (
unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell; ++f)
4884 if (cell->face(f)->at_boundary())
4886 for (
unsigned int v = 0; v < GeometryInfo<dim>::vertices_per_face;
4889 unsigned int vv = cell->face(f)->vertex_index(v);
4890 if (treated_vertices[vv] ==
false)
4892 treated_vertices[vv] =
true;
4893 for (
unsigned int i = 0; i <= Nz; ++i)
4895 double d = ((double)i) * L / ((double)Nz);
4896 switch (vv - i * 16)
4899 cell->face(f)->vertex(v) =
4903 cell->face(f)->vertex(v) =
4907 cell->face(f)->vertex(v) =
4911 cell->face(f)->vertex(v) =
4922 double eps = 1e-3 * outer_radius;
4924 for (; cell != endc; ++cell)
4926 for (
unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell; ++f)
4927 if (cell->face(f)->at_boundary())
4929 double dx = cell->face(f)->center()(0);
4930 double dy = cell->face(f)->center()(1);
4931 double dz = cell->face(f)->center()(2);
4935 if (std::abs(dx + outer_radius) < eps)
4936 cell->face(f)->set_boundary_id(0);
4938 else if (std::abs(dx - outer_radius) < eps)
4939 cell->face(f)->set_boundary_id(1);
4941 else if (std::abs(dy + outer_radius) < eps)
4942 cell->face(f)->set_boundary_id(2);
4944 else if (std::abs(dy - outer_radius) < eps)
4945 cell->face(f)->set_boundary_id(3);
4947 else if (std::abs(dz) < eps)
4948 cell->face(f)->set_boundary_id(4);
4950 else if (std::abs(dz - L) < eps)
4951 cell->face(f)->set_boundary_id(5);
4955 cell->face(f)->set_all_boundary_ids(6);
4963 double d = c.
norm();
4964 if (d - inner_radius < 0)
4966 cell->face(f)->set_all_boundary_ids(1);
4970 cell->face(f)->set_boundary_id(0);
4977 template <
int dim,
int spacedim1,
int spacedim2>
4990 "Cannot use this function on parallel::distributed::Triangulation."));
4992 std::vector<Point<spacedim2>> v;
4993 std::vector<CellData<dim>> cells;
4996 const unsigned int spacedim = std::min(spacedim1, spacedim2);
4997 const std::vector<Point<spacedim1>> &in_vertices = in_tria.
get_vertices();
4999 v.resize(in_vertices.size());
5000 for (
unsigned int i = 0; i < in_vertices.size(); ++i)
5001 for (
unsigned int d = 0; d < spacedim; ++d)
5002 v[i][d] = in_vertices[i][d];
5007 endc = in_tria.
end();
5009 for (
unsigned int id = 0; cell != endc; ++cell, ++id)
5011 for (
unsigned int i = 0; i < GeometryInfo<dim>::vertices_per_cell; ++i)
5012 cells[
id].vertices[i] = cell->vertex_index(i);
5013 cells[id].material_id = cell->material_id();
5014 cells[id].manifold_id = cell->manifold_id();
5030 for (; face != endf; ++face)
5031 if (face->at_boundary())
5033 for (
unsigned int i = 0;
5034 i < GeometryInfo<dim>::vertices_per_face;
5037 face->vertex_index(i);
5039 face->boundary_id();
5041 face->manifold_id();
5050 for (; face != endf; ++face)
5051 if (face->at_boundary())
5053 for (
unsigned int i = 0;
5054 i < GeometryInfo<dim>::vertices_per_face;
5057 face->vertex_index(i);
5059 face->boundary_id();
5061 face->manifold_id();
5076 template <
template <
int,
int>
class MeshType,
int dim,
int spacedim>
5078 std::map<
typename MeshType<dim - 1, spacedim>::cell_iterator,
5079 typename MeshType<dim, spacedim>::face_iterator>
5081 typename ExtractBoundaryMesh<MeshType, dim, spacedim>::return_type
5084 MeshType<dim - 1, spacedim> & surface_mesh,
5085 const std::set<types::boundary_id> &boundary_ids)
5089 &volume_mesh.get_triangulation()) ==
nullptr),
5097 std::map<
typename MeshType<dim - 1, spacedim>::cell_iterator,
5098 typename MeshType<dim, spacedim>::face_iterator>
5099 surface_to_volume_mapping;
5101 const unsigned int boundary_dim = dim - 1;
5105 std::vector<typename MeshType<dim, spacedim>::face_iterator>
5109 std::vector<bool> touched(volume_mesh.get_triangulation().n_vertices(),
5111 std::vector<CellData<boundary_dim>> cells;
5113 std::vector<Point<spacedim>> vertices;
5115 std::map<unsigned int, unsigned int>
5118 for (
typename MeshType<dim, spacedim>::cell_iterator cell =
5119 volume_mesh.begin(0);
5120 cell != volume_mesh.end(0);
5122 for (
unsigned int i = 0; i < GeometryInfo<dim>::faces_per_cell; ++i)
5124 const typename MeshType<dim, spacedim>::face_iterator face =
5127 if (face->at_boundary() &&
5128 (boundary_ids.empty() ||
5129 (boundary_ids.find(face->boundary_id()) != boundary_ids.end())))
5133 for (
unsigned int j = 0;
5134 j < GeometryInfo<boundary_dim>::vertices_per_cell;
5137 const unsigned int v_index = face->vertex_index(j);
5139 if (!touched[v_index])
5141 vertices.push_back(face->vertex(j));
5142 map_vert_index[v_index] = vertices.size() - 1;
5143 touched[v_index] =
true;
5146 c_data.
vertices[j] = map_vert_index[v_index];
5179 for (
unsigned int e = 0; e < 4; ++e)
5185 bool edge_found =
false;
5186 for (
unsigned int i = 0;
5190 map_vert_index[face->line(e)->vertex_index(0)]) &&
5192 map_vert_index[face->line(e)->vertex_index(
5195 map_vert_index[face->line(e)->vertex_index(1)]) &&
5197 map_vert_index[face->line(e)->vertex_index(0)])))
5202 if (edge_found ==
true)
5208 map_vert_index[face->line(e)->vertex_index(0)];
5210 map_vert_index[face->line(e)->vertex_index(1)];
5218 cells.push_back(c_data);
5219 mapping.push_back(face);
5226 surface_mesh.get_triangulation())
5227 .create_triangulation(vertices, cells, subcell_data);
5230 for (
typename MeshType<dim - 1, spacedim>::active_cell_iterator cell =
5231 surface_mesh.begin(0);
5232 cell != surface_mesh.end(0);
5234 surface_to_volume_mapping[cell] = mapping.at(cell->index());
5238 bool changed =
false;
5240 for (
typename MeshType<dim - 1, spacedim>::active_cell_iterator cell =
5241 surface_mesh.begin_active();
5242 cell != surface_mesh.end();
5244 if (surface_to_volume_mapping[cell]->has_children() ==
true)
5246 cell->set_refine_flag();
5253 surface_mesh.get_triangulation())
5254 .execute_coarsening_and_refinement();
5256 for (
typename MeshType<dim - 1, spacedim>::cell_iterator
5257 surface_cell = surface_mesh.begin();
5258 surface_cell != surface_mesh.end();
5260 for (
unsigned int c = 0; c < surface_cell->n_children(); c++)
5261 if (surface_to_volume_mapping.find(surface_cell->child(c)) ==
5262 surface_to_volume_mapping.end())
5263 surface_to_volume_mapping[surface_cell->child(c)] =
5264 surface_to_volume_mapping[surface_cell]->child(c);
5271 return surface_to_volume_mapping;
5277 #include "grid_generator.inst" 5279 DEAL_II_NAMESPACE_CLOSE
std::vector< CellData< 1 > > boundary_lines
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)
static void reorder_cells(std::vector< CellData< dim >> &original_cells, const bool use_new_style_ordering=false)
const types::manifold_id flat_manifold_id
virtual Tensor< 1, spacedim > normal_vector(const typename Triangulation< dim, spacedim >::face_iterator &face, const Point< spacedim > &p) const override
#define AssertDimension(dim1, dim2)
Number determinant(const SymmetricTensor< 2, dim, Number > &)
const std::vector< Point< spacedim > > & get_vertices() const
virtual void create_triangulation_compatibility(const std::vector< Point< spacedim >> &vertices, const std::vector< CellData< dim >> &cells, const SubCellData &subcelldata)
cell_iterator end() const
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)
void simplex(Triangulation< dim, dim > &tria, const std::vector< Point< dim >> &vertices)
Triangulation of a d-simplex with (d+1) vertices and mesh cells.
unsigned int n_active_lines() const
active_face_iterator begin_active_face() const
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
IteratorRange< active_cell_iterator > active_cell_iterators() const
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 truncated_cone(Triangulation< dim > &tria, const double radius_0=1.0, const double radius_1=0.5, const double half_length=1.0)
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 extrude_triangulation(const Triangulation< 2, 2 > &input, const unsigned int n_slices, const double height, Triangulation< 3, 3 > &result)
void enclosed_hyper_cube(Triangulation< dim > &tria, const double left=0., const double right=1., const double thickness=1., const bool colorize=false)
face_iterator begin_face() const
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)
cell_iterator last() const
numbers::NumberTraits< Number >::real_type norm() const
#define AssertThrow(cond, exc)
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)
void hyper_sphere(Triangulation< spacedim-1, spacedim > &tria, const Point< spacedim > ¢er=Point< spacedim >(), const double radius=1.)
static::ExceptionBase & ExcInvalidInputOrientation()
cell_iterator begin(const unsigned int level=0) const
unsigned int n_active_cells() 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)
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)
IteratorRange< cell_iterator > cell_iterators() const
void hyper_L(Triangulation< dim > &tria, const double left=-1., const double right=1., const bool colorize=false)
virtual void execute_coarsening_and_refinement()
void half_hyper_ball(Triangulation< dim > &tria, const Point< dim > ¢er=Point< dim >(), const double radius=1.)
static::ExceptionBase & ExcMessage(std::string arg1)
unsigned int n_cells() const
size_type size(const unsigned int i) const
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
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)
unsigned int n_lines() const
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 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)
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.
unsigned int n_active_faces() const
face_iterator end_face() const
void parallelepiped(Triangulation< dim > &tria, const Point< dim >(&corners)[dim], const bool colorize=false)
void general_cell(Triangulation< dim > &tria, const std::vector< Point< dim >> &vertices, 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)
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)
unsigned int n_quads() const
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)
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.
active_cell_iterator begin_active(const unsigned int level=0) const
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
unsigned int n_vertices() const
unsigned int vertices[GeometryInfo< structdim >::vertices_per_cell]
static::ExceptionBase & ExcInvalidRepetitions(int arg1)
static::ExceptionBase & ExcInternalError()