22 #ifdef DEAL_II_WITH_CGAL
31 # include <CGAL/Boolean_set_operations_2.h>
32 # include <CGAL/Cartesian.h>
33 # include <CGAL/Circular_kernel_intersections.h>
34 # include <CGAL/Constrained_Delaunay_triangulation_2.h>
35 # include <CGAL/Delaunay_mesh_face_base_2.h>
36 # include <CGAL/Delaunay_mesh_size_criteria_2.h>
37 # include <CGAL/Delaunay_mesher_2.h>
38 # include <CGAL/Delaunay_triangulation_2.h>
39 # include <CGAL/Exact_predicates_exact_constructions_kernel_with_sqrt.h>
40 # include <CGAL/Kernel_traits.h>
41 # include <CGAL/Polygon_2.h>
42 # include <CGAL/Polygon_with_holes_2.h>
43 # include <CGAL/Projection_traits_xy_3.h>
44 # include <CGAL/Segment_3.h>
45 # include <CGAL/Simple_cartesian.h>
46 # include <CGAL/Tetrahedron_3.h>
47 # include <CGAL/Triangle_2.h>
48 # include <CGAL/Triangle_3.h>
49 # include <CGAL/Triangulation_2.h>
50 # include <CGAL/Triangulation_3.h>
51 # include <CGAL/Triangulation_face_base_with_id_2.h>
52 # include <CGAL/Triangulation_face_base_with_info_2.h>
57 # include <type_traits>
64 using K = CGAL::Exact_predicates_exact_constructions_kernel_with_sqrt;
65 using K_exact = CGAL::Exact_predicates_exact_constructions_kernel;
95 using Vb = CGAL::Triangulation_vertex_base_2<K>;
96 using Fbb = CGAL::Triangulation_face_base_with_info_2<FaceInfo2, K>;
97 using CFb = CGAL::Constrained_triangulation_face_base_2<K, Fbb>;
98 using Fb = CGAL::Delaunay_mesh_face_base_2<K, CFb>;
99 using Tds = CGAL::Triangulation_data_structure_2<Vb, Fb>;
100 using Itag = CGAL::Exact_predicates_tag;
101 using CDT = CGAL::Constrained_Delaunay_triangulation_2<K, Tds, Itag>;
102 using Criteria = CGAL::Delaunay_mesh_size_criteria_2<CDT>;
114 template <
typename TargetVariant>
115 struct Repackage : boost::static_visitor<TargetVariant>
117 template <
typename T>
119 operator()(
const T &t)
const
121 return TargetVariant(t);
131 template <
typename... Types>
132 std::optional<std::variant<Types...>>
133 convert_boost_to_std(
const boost::optional<boost::variant<Types...>> &x)
142 using std_variant = std::variant<Types...>;
143 return boost::apply_visitor(Repackage<std_variant>(), *x);
160 std::list<CDT::Edge> &border)
162 if (start->info().nesting_level != -1)
166 std::list<Face_handle> queue;
167 queue.push_back(start);
168 while (!queue.empty())
172 if (fh->info().nesting_level == -1)
174 fh->info().nesting_level = index;
175 for (
int i = 0; i < 3; i++)
179 if (n->info().nesting_level == -1)
181 if (ct.is_constrained(
e))
198 f->info().nesting_level = -1;
200 std::list<CDT::Edge> border;
202 while (!border.empty())
204 CDT::Edge
e = border.front();
207 if (n->info().nesting_level == -1)
209 mark_domains(cdt, n,
e.first->info().nesting_level + 1, border);
226 std::vector<CGALPoint2>>>
234 std::array<CGALPoint2, 3> pts0, pts1;
239 &CGALWrappers::dealii_point_to_cgal_point<CGALPoint2, 2>);
244 &CGALWrappers::dealii_point_to_cgal_point<CGALPoint2, 2>);
248 return convert_boost_to_std(
249 CGAL::intersection(cgal_triangle0, cgal_triangle1));
253 std::optional<std::variant<CGALPoint2, CGALSegment2>>
261 std::array<CGALPoint2, 3> pts0;
262 std::array<CGALPoint2, 2> pts1;
267 &CGALWrappers::dealii_point_to_cgal_point<CGALPoint2, 2>);
272 &CGALWrappers::dealii_point_to_cgal_point<CGALPoint2, 2>);
276 return convert_boost_to_std(
277 CGAL::intersection(cgal_segment, cgal_triangle));
283 std::vector<Polygon_with_holes_2>
290 std::array<CGALPoint2, 4> pts0, pts1;
295 &CGALWrappers::dealii_point_to_cgal_point<CGALPoint2, 2>);
300 &CGALWrappers::dealii_point_to_cgal_point<CGALPoint2, 2>);
302 const CGALPolygon first_poly{pts0.begin(), pts0.end()};
303 const CGALPolygon second_poly{pts1.begin(), pts1.end()};
305 std::vector<Polygon_with_holes_2> poly_list;
306 CGAL::intersection(first_poly,
308 std::back_inserter(poly_list));
314 std::optional<std::variant<CGALPoint3, CGALSegment3>>
319 # if DEAL_II_CGAL_VERSION_GTE(5, 5, 0)
324 std::array<CGALPoint3, 4> pts0;
325 std::array<CGALPoint3, 2> pts1;
330 &CGALWrappers::dealii_point_to_cgal_point<CGALPoint3, 3>);
335 &CGALWrappers::dealii_point_to_cgal_point<CGALPoint3, 3>);
337 CGALTetra cgal_tetrahedron{pts0[0], pts0[1], pts0[2], pts0[3]};
339 return convert_boost_to_std(
340 CGAL::intersection(cgal_segment, cgal_tetrahedron));
345 "This function requires a version of CGAL greater or equal than 5.5."));
357 std::vector<CGALPoint3>>>
362 # if DEAL_II_CGAL_VERSION_GTE(5, 5, 0)
367 std::array<CGALPoint3, 4> pts0;
368 std::array<CGALPoint3, 3> pts1;
373 &CGALWrappers::dealii_point_to_cgal_point<CGALPoint3, 3>);
378 &CGALWrappers::dealii_point_to_cgal_point<CGALPoint3, 3>);
380 CGALTetra cgal_tetrahedron{pts0[0], pts0[1], pts0[2], pts0[3]};
382 return convert_boost_to_std(
383 CGAL::intersection(cgal_triangle, cgal_tetrahedron));
389 "This function requires a version of CGAL greater or equal than 5.5."));
397 std::vector<std::array<Point<2>, 3>>
405 const auto intersection_test =
408 if (!intersection_test.empty())
410 const auto &poly = intersection_test[0].outer_boundary();
411 const unsigned int size_poly = poly.size();
417 {{CGALWrappers::cgal_point_to_dealii_point<2>(poly.vertex(0)),
418 CGALWrappers::cgal_point_to_dealii_point<2>(poly.vertex(1)),
419 CGALWrappers::cgal_point_to_dealii_point<2>(
422 else if (size_poly >= 4)
425 std::vector<std::array<Point<2>, 3>> collection;
428 cdt.insert_constraint(poly.vertices_begin(),
437 if (f->info().in_domain() &&
438 CGAL::to_double(cdt.triangle(f).area()) > tol)
440 collection.push_back(
441 {{CGALWrappers::cgal_point_to_dealii_point<2>(
442 cdt.triangle(f).vertex(0)),
443 CGALWrappers::cgal_point_to_dealii_point<2>(
444 cdt.triangle(f).vertex(1)),
445 CGALWrappers::cgal_point_to_dealii_point<2>(
446 cdt.triangle(f).vertex(2))}});
464 std::vector<std::array<Point<2>, 2>>
472 std::array<CGALPoint2, 4> pts;
477 &CGALWrappers::dealii_point_to_cgal_point<CGALPoint2, 2>);
482 CGALWrappers::dealii_point_to_cgal_point<CGALPoint2>(line[0]),
483 CGALWrappers::dealii_point_to_cgal_point<CGALPoint2>(line[1]));
485 cdt.insert_constraint(poly.vertices_begin(), poly.vertices_end(),
true);
486 std::vector<std::array<Point<2>, 2>>
vertices;
490 if (f->info().in_domain() &&
491 CGAL::to_double(cdt.triangle(f).area()) > tol &&
492 CGAL::do_intersect(segm, cdt.triangle(f)))
494 const auto intersection =
495 CGAL::intersection(segm, cdt.triangle(f));
497 boost::get<CGALSegment2>(&*intersection))
500 {{CGALWrappers::cgal_point_to_dealii_point<2>((*s)[0]),
501 CGALWrappers::cgal_point_to_dealii_point<2>((*s)[1])}});
510 std::vector<std::array<Point<3>, 2>>
515 # if DEAL_II_CGAL_VERSION_GTE(5, 5, 0)
520 std::array<CGALPoint3_exact, 8> pts;
526 &CGALWrappers::dealii_point_to_cgal_point<CGALPoint3_exact, 3>);
529 CGALWrappers::dealii_point_to_cgal_point<CGALPoint3_exact>(line[0]),
530 CGALWrappers::dealii_point_to_cgal_point<CGALPoint3_exact>(line[1]));
534 std::vector<std::array<Point<3>, 2>>
vertices;
536 cgal_triangulation.insert(pts.begin(), pts.end());
537 for (
const auto &c : cgal_triangulation.finite_cell_handles())
539 const auto &cgal_tetrahedron = cgal_triangulation.tetrahedron(c);
540 if (CGAL::do_intersect(cgal_segment, cgal_tetrahedron))
542 const auto intersection =
543 CGAL::intersection(cgal_segment, cgal_tetrahedron);
545 boost::get<CGALSegment3_exact>(&*intersection))
547 if (s->squared_length() > tol * tol)
550 {{CGALWrappers::cgal_point_to_dealii_point<3>(
552 CGALWrappers::cgal_point_to_dealii_point<3>(
563 "This function requires a version of CGAL greater or equal than 5.5."));
571 std::vector<std::array<Point<3>, 3>>
576 # if DEAL_II_CGAL_VERSION_GTE(5, 5, 0)
581 std::array<CGALPoint3_exact, 8> pts_hex;
582 std::array<CGALPoint3_exact, 4> pts_quad;
588 &CGALWrappers::dealii_point_to_cgal_point<CGALPoint3_exact, 3>);
594 &CGALWrappers::dealii_point_to_cgal_point<CGALPoint3_exact, 3>);
597 std::vector<std::array<Point<3>, 3>>
vertices;
599 triangulation_hexa.insert(pts_hex.begin(), pts_hex.end());
603 triangulation_quad.insert(pts_quad.begin(), pts_quad.end());
605 for (
const auto &c : triangulation_hexa.finite_cell_handles())
607 const auto &tet = triangulation_hexa.tetrahedron(c);
609 for (
const auto &f : triangulation_quad.finite_facets())
611 if (CGAL::do_intersect(tet, triangulation_quad.triangle(f)))
613 const auto intersection =
614 CGAL::intersection(triangulation_quad.triangle(f), tet);
617 boost::get<CGALTriangle3_exact>(&*intersection))
619 if (CGAL::to_double(t->squared_area()) > tol * tol)
622 {{cgal_point_to_dealii_point<3>((*t)[0]),
623 cgal_point_to_dealii_point<3>((*t)[1]),
624 cgal_point_to_dealii_point<3>((*t)[2])}});
628 if (
const std::vector<CGALPoint3_exact> *vps =
629 boost::get<std::vector<CGALPoint3_exact>>(
633 tria_inter.insert(vps->begin(), vps->end());
635 for (
auto it = tria_inter.finite_facets_begin();
636 it != tria_inter.finite_facets_end();
639 const auto triangle = tria_inter.triangle(*it);
640 if (CGAL::to_double(triangle.squared_area()) >
643 std::array<Point<3>, 3> verts = {
644 {CGALWrappers::cgal_point_to_dealii_point<3>(
646 CGALWrappers::cgal_point_to_dealii_point<3>(
648 CGALWrappers::cgal_point_to_dealii_point<3>(
664 "This function requires a version of CGAL greater or equal than 5.5."));
672 std::vector<std::array<Point<3>, 4>>
680 std::array<CGALPoint3_exact, 8> pts_hex0;
681 std::array<CGALPoint3_exact, 8> pts_hex1;
687 &CGALWrappers::dealii_point_to_cgal_point<CGALPoint3_exact, 3>);
693 &CGALWrappers::dealii_point_to_cgal_point<CGALPoint3_exact, 3>);
697 std::vector<std::array<Point<3>, 4>>
vertices;
700 tria0.insert(pts_hex0.begin(), pts_hex0.end());
701 tria1.insert(pts_hex1.begin(), pts_hex1.end());
703 for (
const auto &c0 : tria0.finite_cell_handles())
705 const auto &tet0 = tria1.tetrahedron(c0);
706 const auto &tetg0 = CGAL::make_tetrahedron(tet0.vertex(0),
712 for (
const auto &c1 : tria1.finite_cell_handles())
714 const auto &tet1 = tria1.tetrahedron(c1);
715 const auto &tetg1 = CGAL::make_tetrahedron(tet1.vertex(0),
721 namespace PMP = CGAL::Polygon_mesh_processing;
722 const bool test_intersection =
723 PMP::corefine_and_compute_intersection(surf0, surf1, sm);
728 triangulation_hexa.insert(sm.points().begin(),
730 for (
const auto &c : triangulation_hexa.finite_cell_handles())
732 const auto &tet = triangulation_hexa.tetrahedron(c);
734 {{CGALWrappers::cgal_point_to_dealii_point<3>(
736 CGALWrappers::cgal_point_to_dealii_point<3>(
738 CGALWrappers::cgal_point_to_dealii_point<3>(
740 CGALWrappers::cgal_point_to_dealii_point<3>(
755 template <
int dim0,
int dim1,
int spacedim>
756 std::vector<std::array<Point<spacedim>, dim1 + 1>>
762 const unsigned int n_vertices0 = vertices0.size();
763 const unsigned int n_vertices1 = vertices1.size();
766 n_vertices0 > 0 || n_vertices1 > 0,
768 "The intersection cannot be computed as at least one of the two cells has no vertices."));
770 if constexpr (dim0 == 2 && dim1 == 2 && spacedim == 2)
772 if (n_vertices0 == 4 && n_vertices1 == 4)
779 else if constexpr (dim0 == 2 && dim1 == 1 && spacedim == 2)
781 if (n_vertices0 == 4 && n_vertices1 == 2)
788 else if constexpr (dim0 == 3 && dim1 == 1 && spacedim == 3)
790 if (n_vertices0 == 8 && n_vertices1 == 2)
797 else if constexpr (dim0 == 3 && dim1 == 2 && spacedim == 3)
799 if (n_vertices0 == 8 && n_vertices1 == 4)
806 else if constexpr (dim0 == 3 && dim1 == 3 && spacedim == 3)
808 if (n_vertices0 == 8 && n_vertices1 == 8)
825 template <
int dim0,
int dim1,
int spacedim>
826 std::vector<std::array<Point<spacedim>, dim1 + 1>>
835 ReferenceCells::get_hypercube<dim0>().n_vertices(),
838 ReferenceCells::get_hypercube<dim1>().n_vertices(),
841 const auto &vertices0 =
842 CGALWrappers::get_vertices_in_cgal_order(cell0, mapping0);
843 const auto &vertices1 =
844 CGALWrappers::get_vertices_in_cgal_order(cell1, mapping1);
846 return compute_intersection_of_cells<dim0, dim1, spacedim>(vertices0,
851 # include "intersections.inst"
866 std::vector<std::array<Point<spacedim>, dim1 + 1>>
878 template <
int dim0,
int dim1,
int spacedim>
879 std::vector<std::array<Point<spacedim>, dim1 + 1>>
Abstract base class for mapping classes.
virtual boost::container::small_vector< Point< spacedim >, GeometryInfo< dim >::vertices_per_cell > get_vertices(const typename Triangulation< dim, spacedim >::cell_iterator &cell) const
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
#define Assert(cond, exc)
static ::ExceptionBase & ExcNotImplemented()
#define AssertDimension(dim1, dim2)
static ::ExceptionBase & ExcNeedsCGAL()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
std::optional< std::variant< CGALPoint3, CGALSegment3 > > compute_intersection_tetra_segment(const ArrayView< const Point< 3 >> &tetrahedron, const ArrayView< const Point< 3 >> &segment)
std::optional< std::variant< CGALPoint3, CGALSegment3, CGALTriangle3, std::vector< CGALPoint3 > > > compute_intersection_tetra_triangle(const ArrayView< const Point< 3 >> &tetrahedron, const ArrayView< const Point< 3 >> &triangle)
void mark_domains(CDT &ct, Face_handle start, int index, std::list< CDT::Edge > &border)
std::vector< std::array< Point< 3 >, 4 > > compute_intersection_hexa_hexa(const ArrayView< const Point< 3 >> &hexa0, const ArrayView< const Point< 3 >> &hexa1, const double tol)
std::vector< std::array< Point< 2 >, 3 > > compute_intersection_quad_quad(const ArrayView< const Point< 2 >> &quad0, const ArrayView< const Point< 2 >> &quad1, const double tol)
std::vector< Polygon_with_holes_2 > compute_intersection_rect_rect(const ArrayView< const Point< 2 >> &rectangle0, const ArrayView< const Point< 2 >> &rectangle1)
std::vector< std::array< Point< 3 >, 2 > > compute_intersection_hexa_line(const ArrayView< const Point< 3 >> &hexa, const ArrayView< const Point< 3 >> &line, const double tol)
std::optional< std::variant< CGALPoint2, CGALSegment2, CGALTriangle2, std::vector< CGALPoint2 > > > compute_intersection_triangle_triangle(const ArrayView< const Point< 2 >> &triangle0, const ArrayView< const Point< 2 >> &triangle1)
std::vector< std::array< Point< 3 >, 3 > > compute_intersection_hexa_quad(const ArrayView< const Point< 3 >> &hexa, const ArrayView< const Point< 3 >> &quad, const double tol)
std::optional< std::variant< CGALPoint2, CGALSegment2 > > compute_intersection_triangle_segment(const ArrayView< const Point< 2 >> &triangle, const ArrayView< const Point< 2 >> &segment)
std::vector< std::array< Point< 2 >, 2 > > compute_intersection_quad_line(const ArrayView< const Point< 2 >> &quad, const ArrayView< const Point< 2 >> &line, const double tol)
K::Tetrahedron_3 CGALTetra
CGAL::Surface_mesh< K_exact::Point_3 > Surface_mesh
K::Segment_2 CGALSegment2
CGAL::Exact_predicates_tag Itag
K_exact::Tetrahedron_3 CGALTetra_exact
K_exact::Triangle_3 CGALTriangle3_exact
CDT::Vertex_handle Vertex_handle
K::Triangle_3 CGALTriangle3
K::Segment_3 CGALSegment3
CDT::Face_handle Face_handle
CGAL::Triangulation_3< K_exact > Triangulation3_exact
CGAL::Constrained_Delaunay_triangulation_2< K, Tds, Itag > CDT
CGAL::Delaunay_mesh_size_criteria_2< CDT > Criteria
CGAL::Triangulation_vertex_base_2< K > Vb
CGAL::Polygon_with_holes_2< K > Polygon_with_holes_2
CGAL::Triangulation_data_structure_2< Vb, Fb > Tds
std::vector< std::array< Point< spacedim >, dim1+1 > > compute_intersection_of_cells(const typename Triangulation< dim0, spacedim >::cell_iterator &cell0, const typename Triangulation< dim1, spacedim >::cell_iterator &cell1, const Mapping< dim0, spacedim > &mapping0, const Mapping< dim1, spacedim > &mapping1, const double tol=1e-9)
CGAL::Polygon_2< K > CGALPolygon
CGAL::Triangulation_2< K > Triangulation2
CGAL::Exact_predicates_exact_constructions_kernel K_exact
CGAL::Triangulation_3< K > Triangulation3
CGAL::Constrained_triangulation_face_base_2< K, Fbb > CFb
CGAL::Exact_predicates_exact_constructions_kernel_with_sqrt K
K::Triangle_2 CGALTriangle2
CGAL::Delaunay_mesh_face_base_2< K, CFb > Fb
K_exact::Segment_3 CGALSegment3_exact
K_exact::Point_3 CGALPoint3_exact
CGAL::Triangulation_face_base_with_info_2< FaceInfo2, K > Fbb
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
void transform(const InputIterator &begin_in, const InputIterator &end_in, OutputIterator out, const Function &function, const unsigned int grainsize)