deal.II version GIT relicensing-6834-g5b78e6bcdf 2026-10-01 11:20:01+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Loading...
Searching...
No Matches
intersections.cc
Go to the documentation of this file.
1// -----------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception OR LGPL-2.1-or-later
4// Copyright (C) 2022 - 2026 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Detailed license information governing the source code and contributions
9// can be found in LICENSE.md and CONTRIBUTING.md at the top level directory.
10//
11// -----------------------------------------------------------------------------
12
13#include <deal.II/base/config.h>
14
17
19
20#include <deal.II/fe/mapping.h>
21
22#include <deal.II/grid/tria.h>
23
24#include <algorithm>
25
27#include <CGAL/Boolean_set_operations_2.h>
29
31
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/Surface_mesh/Surface_mesh.h>
47#include <CGAL/Tetrahedron_3.h>
48#include <CGAL/Triangle_2.h>
49#include <CGAL/Triangle_3.h>
50#include <CGAL/Triangulation_2.h>
51#include <CGAL/Triangulation_3.h>
52#include <CGAL/Triangulation_face_base_with_id_2.h>
53#include <CGAL/Triangulation_face_base_with_info_2.h>
54
55#include <optional>
56#include <variant>
57
59
60namespace CGALWrappers
61{
62 using K = CGAL::Exact_predicates_exact_constructions_kernel_with_sqrt;
63 using K_exact = CGAL::Exact_predicates_exact_constructions_kernel;
64 using CGALPolygon = CGAL::Polygon_2<K>;
65 using Polygon_with_holes_2 = CGAL::Polygon_with_holes_2<K>;
66 using CGALTriangle2 = K::Triangle_2;
67 using CGALTriangle3 = K::Triangle_3;
68 using CGALTriangle3_exact = K_exact::Triangle_3;
69 using CGALPoint2 = K::Point_2;
70 using CGALPoint3 = K::Point_3;
71 using CGALPoint3_exact = K_exact::Point_3;
72 using CGALSegment2 = K::Segment_2;
73 using Surface_mesh = CGAL::Surface_mesh<K_exact::Point_3>;
74 using CGALSegment3 = K::Segment_3;
75 using CGALSegment3_exact = K_exact::Segment_3;
76 using CGALTetra = K::Tetrahedron_3;
77 using CGALTetra_exact = K_exact::Tetrahedron_3;
78 using Triangulation2 = CGAL::Triangulation_2<K>;
79 using Triangulation3 = CGAL::Triangulation_3<K>;
80 using Triangulation3_exact = CGAL::Triangulation_3<K_exact>;
81
82 struct FaceInfo2
83 {
84 FaceInfo2() = default;
86 bool
88 {
89 return nesting_level % 2 == 1;
90 }
91 };
92
93 using Vb = CGAL::Triangulation_vertex_base_2<K>;
94 using Fbb = CGAL::Triangulation_face_base_with_info_2<FaceInfo2, K>;
95 using CFb = CGAL::Constrained_triangulation_face_base_2<K, Fbb>;
96 using Fb = CGAL::Delaunay_mesh_face_base_2<K, CFb>;
97 using Tds = CGAL::Triangulation_data_structure_2<Vb, Fb>;
98 using Itag = CGAL::Exact_predicates_tag;
99 using CDT = CGAL::Constrained_Delaunay_triangulation_2<K, Tds, Itag>;
100 using Criteria = CGAL::Delaunay_mesh_size_criteria_2<CDT>;
101 using Vertex_handle = CDT::Vertex_handle;
102 using Face_handle = CDT::Face_handle;
103
104 template <class T, class... Types>
105 const T *
106 get_if_(const std::variant<Types...> *v)
107 {
108 return std::get_if<T>(v);
109 }
110
111 template <class T, class... Types>
112 const T *
113 get_if_(const boost::variant<Types...> *v)
114 {
115 return boost::get<T>(v);
116 }
117
118 namespace internal
119 {
120 namespace
121 {
126 template <typename TargetVariant>
127 struct Repackage : boost::static_visitor<TargetVariant>
128 {
129 template <typename T>
130 TargetVariant
131 operator()(const T &t) const
132 {
133 return TargetVariant(t);
134 }
135 };
136
143 template <typename... Types>
144 std::optional<std::variant<Types...>>
145 convert_boost_to_std(const boost::optional<boost::variant<Types...>> &x)
146 {
147 if (x)
148 {
149 // The boost::optional object contains an object of type
150 // boost::variant. We need to unpack which type the
151 // variant contains, and re-package that into a
152 // std::variant. This is easily done using a visitor
153 // object.
154 using std_variant = std::variant<Types...>;
155 return boost::apply_visitor(Repackage<std_variant>(), *x);
156 }
157 else
158 {
159 // The boost::optional object was empty. Return an empty
160 // std::optional object.
161 return {};
162 }
163 }
164
165 template <typename... Types>
166 const std::optional<std::variant<Types...>> &
167 convert_boost_to_std(const std::optional<std::variant<Types...>> &opt)
168 {
169 return opt;
170 }
171 } // namespace
172
173
174
175 void
177 Face_handle start,
178 int index,
179 std::list<CDT::Edge> &border)
180 {
181 if (start->info().nesting_level != -1)
182 {
183 return;
184 }
185 std::list<Face_handle> queue;
186 queue.push_back(start);
187 while (!queue.empty())
188 {
189 Face_handle fh = queue.front();
190 queue.pop_front();
191 if (fh->info().nesting_level == -1)
192 {
193 fh->info().nesting_level = index;
194 for (int i = 0; i < 3; i++)
195 {
196 CDT::Edge e(fh, i);
197 Face_handle n = fh->neighbor(i);
198 if (n->info().nesting_level == -1)
199 {
200 if (ct.is_constrained(e))
201 border.push_back(e);
202 else
203 queue.push_back(n);
204 }
205 }
206 }
207 }
208 }
209
210
211
212 void
214 {
215 for (CDT::Face_handle f : cdt.all_face_handles())
216 {
217 f->info().nesting_level = -1;
218 }
219 std::list<CDT::Edge> border;
220 mark_domains(cdt, cdt.infinite_face(), 0, border);
221 while (!border.empty())
222 {
223 CDT::Edge e = border.front();
224 border.pop_front();
225 Face_handle n = e.first->neighbor(e.second);
226 if (n->info().nesting_level == -1)
227 {
228 mark_domains(cdt, n, e.first->info().nesting_level + 1, border);
229 }
230 }
231 }
232
233 // Collection of utilities that compute intersection between simplices
234 // identified by array of points. The return type is the one of
235 // CGAL::intersection(), i.e. a std::optional<std::variant<>>.
236 // Intersection between 2d and 3d objects and 1d/3d objects are available
237 // only with CGAL versions greater or equal than 5.5, hence the
238 // corresponding functions are guarded by #ifdef directives. All the
239 // signatures follow the convection that the first entity has an intrinsic
240 // dimension higher than the second one.
241
242 std::optional<std::variant<CGALPoint2,
245 std::vector<CGALPoint2>>>
247 const ArrayView<const Point<2>> &triangle0,
248 const ArrayView<const Point<2>> &triangle1)
249 {
250 AssertDimension(triangle0.size(), 3);
251 AssertDimension(triangle0.size(), triangle1.size());
252
253 std::array<CGALPoint2, 3> pts0, pts1;
254
255 std::transform(triangle0.begin(),
256 triangle0.end(),
257 pts0.begin(),
258 &CGALWrappers::dealii_point_to_cgal_point<CGALPoint2, 2>);
259
260 std::transform(triangle1.begin(),
261 triangle1.end(),
262 pts1.begin(),
263 &CGALWrappers::dealii_point_to_cgal_point<CGALPoint2, 2>);
264
265 CGALTriangle2 cgal_triangle0{pts0[0], pts0[1], pts0[2]};
266 CGALTriangle2 cgal_triangle1{pts1[0], pts1[1], pts1[2]};
267 return convert_boost_to_std(
268 CGAL::intersection(cgal_triangle0, cgal_triangle1));
269 }
270
271
272 std::optional<std::variant<CGALPoint2, CGALSegment2>>
274 const ArrayView<const Point<2>> &triangle,
275 const ArrayView<const Point<2>> &segment)
276 {
277 AssertDimension(triangle.size(), 3);
278 AssertDimension(segment.size(), 2);
279
280 std::array<CGALPoint2, 3> pts0;
281 std::array<CGALPoint2, 2> pts1;
282
283 std::transform(triangle.begin(),
284 triangle.end(),
285 pts0.begin(),
286 &CGALWrappers::dealii_point_to_cgal_point<CGALPoint2, 2>);
287
288 std::transform(segment.begin(),
289 segment.end(),
290 pts1.begin(),
291 &CGALWrappers::dealii_point_to_cgal_point<CGALPoint2, 2>);
292
293 CGALTriangle2 cgal_triangle{pts0[0], pts0[1], pts0[2]};
294 CGALSegment2 cgal_segment{pts1[0], pts1[1]};
295 return convert_boost_to_std(
296 CGAL::intersection(cgal_segment, cgal_triangle));
297 }
298
299
300
301 // rectangle-rectangle
302 std::vector<Polygon_with_holes_2>
304 const ArrayView<const Point<2>> &rectangle1)
305 {
306 AssertDimension(rectangle0.size(), 4);
307 AssertDimension(rectangle0.size(), rectangle1.size());
308
309 std::array<CGALPoint2, 4> pts0, pts1;
310
311 std::transform(rectangle0.begin(),
312 rectangle0.end(),
313 pts0.begin(),
314 &CGALWrappers::dealii_point_to_cgal_point<CGALPoint2, 2>);
315
316 std::transform(rectangle1.begin(),
317 rectangle1.end(),
318 pts1.begin(),
319 &CGALWrappers::dealii_point_to_cgal_point<CGALPoint2, 2>);
320
321 const CGALPolygon first_poly{pts0.begin(), pts0.end()};
322 const CGALPolygon second_poly{pts1.begin(), pts1.end()};
323
324 std::vector<Polygon_with_holes_2> poly_list;
325 CGAL::intersection(first_poly,
326 second_poly,
327 std::back_inserter(poly_list));
328 return poly_list;
329 }
330
331
332
333 std::optional<std::variant<CGALPoint3, CGALSegment3>>
335 const ArrayView<const Point<3>> &tetrahedron,
336 const ArrayView<const Point<3>> &segment)
337 {
338#if DEAL_II_CGAL_VERSION_GTE(5, 5, 0)
339
340 AssertDimension(tetrahedron.size(), 4);
341 AssertDimension(segment.size(), 2);
342
343 std::array<CGALPoint3, 4> pts0;
344 std::array<CGALPoint3, 2> pts1;
345
346 std::transform(tetrahedron.begin(),
347 tetrahedron.end(),
348 pts0.begin(),
349 &CGALWrappers::dealii_point_to_cgal_point<CGALPoint3, 3>);
350
351 std::transform(segment.begin(),
352 segment.end(),
353 pts1.begin(),
354 &CGALWrappers::dealii_point_to_cgal_point<CGALPoint3, 3>);
355
356 CGALTetra cgal_tetrahedron{pts0[0], pts0[1], pts0[2], pts0[3]};
357 CGALSegment3 cgal_segment{pts1[0], pts1[1]};
358 return convert_boost_to_std(
359 CGAL::intersection(cgal_segment, cgal_tetrahedron));
360#else
361 Assert(
362 false,
364 "This function requires a version of CGAL greater or equal than 5.5."));
365 (void)tetrahedron;
366 (void)segment;
367 return {};
368#endif
369 }
370
371
372 // tetra, triangle
373 std::optional<std::variant<CGALPoint3,
376 std::vector<CGALPoint3>>>
378 const ArrayView<const Point<3>> &tetrahedron,
379 const ArrayView<const Point<3>> &triangle)
380 {
381#if DEAL_II_CGAL_VERSION_GTE(5, 5, 0)
382
383 AssertDimension(tetrahedron.size(), 4);
384 AssertDimension(triangle.size(), 3);
385
386 std::array<CGALPoint3, 4> pts0;
387 std::array<CGALPoint3, 3> pts1;
388
389 std::transform(tetrahedron.begin(),
390 tetrahedron.end(),
391 pts0.begin(),
392 &CGALWrappers::dealii_point_to_cgal_point<CGALPoint3, 3>);
393
394 std::transform(triangle.begin(),
395 triangle.end(),
396 pts1.begin(),
397 &CGALWrappers::dealii_point_to_cgal_point<CGALPoint3, 3>);
398
399 CGALTetra cgal_tetrahedron{pts0[0], pts0[1], pts0[2], pts0[3]};
400 CGALTriangle3 cgal_triangle{pts1[0], pts1[1], pts1[2]};
401 return convert_boost_to_std(
402 CGAL::intersection(cgal_triangle, cgal_tetrahedron));
403#else
404
405 Assert(
406 false,
408 "This function requires a version of CGAL greater or equal than 5.5."));
409 (void)tetrahedron;
410 (void)triangle;
411 return {};
412#endif
413 }
414
415 // quad-quad
416 std::vector<std::array<Point<2>, 3>>
418 const ArrayView<const Point<2>> &quad1,
419 const double tol)
420 {
421 AssertDimension(quad0.size(), 4);
422 AssertDimension(quad0.size(), quad1.size());
423
424 const auto intersection_test =
426
427 if (!intersection_test.empty())
428 {
429 const auto &poly = intersection_test[0].outer_boundary();
430 const unsigned int size_poly = poly.size();
431 if (size_poly == 3)
432 {
433 // intersection is a triangle itself, so directly return its
434 // vertices.
435 return {
436 {{CGALWrappers::cgal_point_to_dealii_point<2>(poly.vertex(0)),
437 CGALWrappers::cgal_point_to_dealii_point<2>(poly.vertex(1)),
438 CGALWrappers::cgal_point_to_dealii_point<2>(
439 poly.vertex(2))}}};
440 }
441 else if (size_poly >= 4)
442 {
443 // intersection is a polygon, need to triangulate it.
444 std::vector<std::array<Point<2>, 3>> collection;
445
446 CDT cdt;
447 cdt.insert_constraint(poly.vertices_begin(),
448 poly.vertices_end(),
449 true);
450
452
453 for (Face_handle f : cdt.finite_face_handles())
454 {
455 if (f->info().in_domain() &&
456 CGAL::to_double(cdt.triangle(f).area()) > tol)
457 {
458 collection.push_back(
459 {{CGALWrappers::cgal_point_to_dealii_point<2>(
460 cdt.triangle(f).vertex(0)),
461 CGALWrappers::cgal_point_to_dealii_point<2>(
462 cdt.triangle(f).vertex(1)),
463 CGALWrappers::cgal_point_to_dealii_point<2>(
464 cdt.triangle(f).vertex(2))}});
465 }
466 }
467 return collection;
468 }
469 else
470 {
471 Assert(false, ExcMessage("The polygon is degenerate."));
472 return {};
473 }
474 }
475 else
476 {
477 return {};
478 }
479 }
480
481 // Specialization for quad \cap line
482 std::vector<std::array<Point<2>, 2>>
484 const ArrayView<const Point<2>> &line,
485 const double tol)
486 {
487 AssertDimension(quad.size(), 4);
488 AssertDimension(line.size(), 2);
489
490 std::array<CGALPoint2, 4> pts;
491
492 std::transform(quad.begin(),
493 quad.end(),
494 pts.begin(),
495 &CGALWrappers::dealii_point_to_cgal_point<CGALPoint2, 2>);
496
497 CGALPolygon poly(pts.begin(), pts.end());
498
499 CGALSegment2 segm(
500 CGALWrappers::dealii_point_to_cgal_point<CGALPoint2>(line[0]),
501 CGALWrappers::dealii_point_to_cgal_point<CGALPoint2>(line[1]));
502 CDT cdt;
503 cdt.insert_constraint(poly.vertices_begin(), poly.vertices_end(), true);
504 std::vector<std::array<Point<2>, 2>> vertices;
506 for (Face_handle f : cdt.finite_face_handles())
507 {
508 if (f->info().in_domain() &&
509 CGAL::to_double(cdt.triangle(f).area()) > tol &&
510 CGAL::do_intersect(segm, cdt.triangle(f)))
511 {
512 const auto intersection =
513 CGAL::intersection(segm, cdt.triangle(f));
514 if (const CGALSegment2 *s = get_if_<CGALSegment2>(&*intersection))
515 {
516 vertices.push_back(
517 {{CGALWrappers::cgal_point_to_dealii_point<2>((*s)[0]),
518 CGALWrappers::cgal_point_to_dealii_point<2>((*s)[1])}});
519 }
520 }
521 }
522
523 return vertices;
524 }
525
526 // specialization for hex \cap line
527 std::vector<std::array<Point<3>, 2>>
529 const ArrayView<const Point<3>> &line,
530 const double tol)
531 {
532#if DEAL_II_CGAL_VERSION_GTE(5, 5, 0)
533
534 AssertDimension(hexa.size(), 8);
535 AssertDimension(line.size(), 2);
536
537 std::array<CGALPoint3_exact, 8> pts;
538
539 std::transform(
540 hexa.begin(),
541 hexa.end(),
542 pts.begin(),
543 &CGALWrappers::dealii_point_to_cgal_point<CGALPoint3_exact, 3>);
544
545 CGALSegment3_exact cgal_segment(
546 CGALWrappers::dealii_point_to_cgal_point<CGALPoint3_exact>(line[0]),
547 CGALWrappers::dealii_point_to_cgal_point<CGALPoint3_exact>(line[1]));
548
549 // Subdivide the hex into tetrahedrons, and intersect each one of them
550 // with the line
551 std::vector<std::array<Point<3>, 2>> vertices;
552 Triangulation3_exact cgal_triangulation;
553 cgal_triangulation.insert(pts.begin(), pts.end());
554 for (const auto &c : cgal_triangulation.finite_cell_handles())
555 {
556 const auto &cgal_tetrahedron = cgal_triangulation.tetrahedron(c);
557 if (CGAL::do_intersect(cgal_segment, cgal_tetrahedron))
558 {
559 const auto intersection =
560 CGAL::intersection(cgal_segment, cgal_tetrahedron);
561 if (const CGALSegment3_exact *s =
562 get_if_<CGALSegment3_exact>(&*intersection))
563 {
564 if (s->squared_length() > tol * tol)
565 {
566 vertices.push_back(
567 {{CGALWrappers::cgal_point_to_dealii_point<3>(
568 s->vertex(0)),
569 CGALWrappers::cgal_point_to_dealii_point<3>(
570 s->vertex(1))}});
571 }
572 }
573 }
574 }
575 return vertices;
576#else
577 Assert(
578 false,
580 "This function requires a version of CGAL greater or equal than 5.5."));
581 (void)hexa;
582 (void)line;
583 (void)tol;
584 return {};
585#endif
586 }
587
588 std::vector<std::array<Point<3>, 3>>
590 const ArrayView<const Point<3>> &quad,
591 const double tol)
592 {
593#if DEAL_II_CGAL_VERSION_GTE(5, 5, 0)
594
595 AssertDimension(hexa.size(), 8);
596 AssertDimension(quad.size(), 4);
597
598 std::array<CGALPoint3_exact, 8> pts_hex;
599 std::array<CGALPoint3_exact, 4> pts_quad;
600
601 std::transform(
602 hexa.begin(),
603 hexa.end(),
604 pts_hex.begin(),
605 &CGALWrappers::dealii_point_to_cgal_point<CGALPoint3_exact, 3>);
606
607 std::transform(
608 quad.begin(),
609 quad.end(),
610 pts_quad.begin(),
611 &CGALWrappers::dealii_point_to_cgal_point<CGALPoint3_exact, 3>);
612
613 // Subdivide hex into tetrahedrons
614 std::vector<std::array<Point<3>, 3>> vertices;
615 Triangulation3_exact triangulation_hexa;
616 triangulation_hexa.insert(pts_hex.begin(), pts_hex.end());
617
618 // Subdivide quad into triangles
619 Triangulation3_exact triangulation_quad;
620 triangulation_quad.insert(pts_quad.begin(), pts_quad.end());
621
622 for (const auto &c : triangulation_hexa.finite_cell_handles())
623 {
624 const auto &tet = triangulation_hexa.tetrahedron(c);
625
626 for (const auto &f : triangulation_quad.finite_facets())
627 {
628 if (CGAL::do_intersect(tet, triangulation_quad.triangle(f)))
629 {
630 const auto intersection =
631 CGAL::intersection(triangulation_quad.triangle(f), tet);
632
633 if (const CGALTriangle3_exact *t =
634 get_if_<CGALTriangle3_exact>(&*intersection))
635 {
636 if (CGAL::to_double(t->squared_area()) > tol * tol)
637 {
638 vertices.push_back(
639 {{cgal_point_to_dealii_point<3>((*t)[0]),
640 cgal_point_to_dealii_point<3>((*t)[1]),
641 cgal_point_to_dealii_point<3>((*t)[2])}});
642 }
643 }
644
645 if (const std::vector<CGALPoint3_exact> *vps =
646 get_if_<std::vector<CGALPoint3_exact>>(&*intersection))
647 {
648 Triangulation3_exact tria_inter;
649 tria_inter.insert(vps->begin(), vps->end());
650
651 for (auto it = tria_inter.finite_facets_begin();
652 it != tria_inter.finite_facets_end();
653 ++it)
654 {
655 const auto triangle = tria_inter.triangle(*it);
656 if (CGAL::to_double(triangle.squared_area()) >
657 tol * tol)
658 {
659 std::array<Point<3>, 3> verts = {
660 {CGALWrappers::cgal_point_to_dealii_point<3>(
661 triangle[0]),
662 CGALWrappers::cgal_point_to_dealii_point<3>(
663 triangle[1]),
664 CGALWrappers::cgal_point_to_dealii_point<3>(
665 triangle[2])}};
666
667 vertices.push_back(verts);
668 }
669 }
670 }
671 }
672 }
673 }
674
675 return vertices;
676#else
677 Assert(
678 false,
680 "This function requires a version of CGAL greater or equal than 5.5."));
681 (void)hexa;
682 (void)quad;
683 (void)tol;
684 return {};
685#endif
686 }
687
688 std::vector<std::array<Point<3>, 4>>
690 const ArrayView<const Point<3>> &hexa1,
691 const double tol)
692 {
693 AssertDimension(hexa0.size(), 8);
694 AssertDimension(hexa0.size(), hexa1.size());
695
696 std::array<CGALPoint3_exact, 8> pts_hex0;
697 std::array<CGALPoint3_exact, 8> pts_hex1;
698
699 std::transform(
700 hexa0.begin(),
701 hexa0.end(),
702 pts_hex0.begin(),
703 &CGALWrappers::dealii_point_to_cgal_point<CGALPoint3_exact, 3>);
704
705 std::transform(
706 hexa1.begin(),
707 hexa1.end(),
708 pts_hex1.begin(),
709 &CGALWrappers::dealii_point_to_cgal_point<CGALPoint3_exact, 3>);
710
711 Surface_mesh surf0, surf1, sm;
712 // Subdivide hex into tetrahedrons
713 std::vector<std::array<Point<3>, 4>> vertices;
714 Triangulation3_exact tria0, tria1;
715
716 tria0.insert(pts_hex0.begin(), pts_hex0.end());
717 tria1.insert(pts_hex1.begin(), pts_hex1.end());
718
719 for (const auto &c0 : tria0.finite_cell_handles())
720 {
721 const auto &tet0 = tria1.tetrahedron(c0);
722 const auto &tetg0 = CGAL::make_tetrahedron(tet0.vertex(0),
723 tet0.vertex(1),
724 tet0.vertex(2),
725 tet0.vertex(3),
726 surf0);
727 (void)tetg0; // instead of C++ 17s [[maybe unused]]
728 for (const auto &c1 : tria1.finite_cell_handles())
729 {
730 const auto &tet1 = tria1.tetrahedron(c1);
731 const auto &tetg1 = CGAL::make_tetrahedron(tet1.vertex(0),
732 tet1.vertex(1),
733 tet1.vertex(2),
734 tet1.vertex(3),
735 surf1);
736 (void)tetg1; // instead of C++ 17s [[maybe unused]]
737 namespace PMP = CGAL::Polygon_mesh_processing;
738 const bool test_intersection =
739 PMP::corefine_and_compute_intersection(surf0, surf1, sm);
740 if (PMP::volume(sm) > tol && test_intersection)
741 {
742 // Collect tetrahedrons
743 Triangulation3_exact triangulation_hexa;
744 triangulation_hexa.insert(sm.points().begin(),
745 sm.points().end());
746 for (const auto &c : triangulation_hexa.finite_cell_handles())
747 {
748 const auto &tet = triangulation_hexa.tetrahedron(c);
749 vertices.push_back(
750 {{CGALWrappers::cgal_point_to_dealii_point<3>(
751 tet.vertex(0)),
752 CGALWrappers::cgal_point_to_dealii_point<3>(
753 tet.vertex(1)),
754 CGALWrappers::cgal_point_to_dealii_point<3>(
755 tet.vertex(2)),
756 CGALWrappers::cgal_point_to_dealii_point<3>(
757 tet.vertex(3))}});
758 }
759 }
760 surf1.clear();
761 sm.clear();
762 }
763 surf0.clear();
764 }
765 return vertices;
766 }
767
768 } // namespace internal
769
770
771 template <int structdim0, int structdim1, int spacedim>
772 std::vector<std::array<Point<spacedim>, structdim1 + 1>>
774 const ArrayView<const Point<spacedim>> &vertices0,
775 const ArrayView<const Point<spacedim>> &vertices1,
776 const double tol)
777 {
778 const unsigned int n_vertices0 = vertices0.size();
779 const unsigned int n_vertices1 = vertices1.size();
780
781 Assert(
782 n_vertices0 > 0 || n_vertices1 > 0,
784 "The intersection cannot be computed as at least one of the two cells has no vertices."));
785
786 if constexpr (structdim0 == 2 && structdim1 == 2 && spacedim == 2)
787 {
788 if (n_vertices0 == 4 && n_vertices1 == 4)
789 {
791 vertices1,
792 tol);
793 }
794 }
795 else if constexpr (structdim0 == 2 && structdim1 == 1 && spacedim == 2)
796 {
797 if (n_vertices0 == 4 && n_vertices1 == 2)
798 {
800 vertices1,
801 tol);
802 }
803 }
804 else if constexpr (structdim0 == 3 && structdim1 == 1 && spacedim == 3)
805 {
806 if (n_vertices0 == 8 && n_vertices1 == 2)
807 {
809 vertices1,
810 tol);
811 }
812 }
813 else if constexpr (structdim0 == 3 && structdim1 == 2 && spacedim == 3)
814 {
815 if (n_vertices0 == 8 && n_vertices1 == 4)
816 {
818 vertices1,
819 tol);
820 }
821 }
822 else if constexpr (structdim0 == 3 && structdim1 == 3 && spacedim == 3)
823 {
824 if (n_vertices0 == 8 && n_vertices1 == 8)
825 {
827 vertices1,
828 tol);
829 }
830 }
831 else
832 {
834 return {};
835 }
836 (void)tol;
837 return {};
838 }
839
840
841 template <int structdim0, int structdim1, int spacedim>
842 std::vector<std::array<Point<spacedim>, structdim1 + 1>>
846 const Mapping<structdim0, spacedim> &mapping0,
847 const Mapping<structdim1, spacedim> &mapping1,
848 const double tol)
849 {
850 Assert(mapping0.get_vertices(cell0).size() ==
851 ReferenceCells::get_hypercube<structdim0>().n_vertices(),
853 Assert(mapping1.get_vertices(cell1).size() ==
854 ReferenceCells::get_hypercube<structdim1>().n_vertices(),
856
857 const auto &vertices0 =
858 CGALWrappers::get_vertices_in_cgal_order(cell0, mapping0);
859 const auto &vertices1 =
860 CGALWrappers::get_vertices_in_cgal_order(cell1, mapping1);
861
862 return compute_intersection_of_cells<structdim0, structdim1, spacedim>(
863 vertices0, vertices1, tol);
864 }
865
866// Explicit instantiations.
867//
868// We don't build the instantiations.inst file if deal.II isn't
869// configured with CGAL, but doxygen doesn't know that and tries to
870// find that file anyway for parsing -- which then of course it fails
871// on. So exclude the following from doxygen consideration.
872#ifndef DOXYGEN
873# include "cgal/intersections.inst"
874#endif
875
876} // namespace CGALWrappers
877
*  *  Point< dim > operator()(const Point< dim > &p) const * 
Abstract base class for mapping classes.
Definition mapping.h:318
virtual boost::container::small_vector< Point< spacedim >, ReferenceCells::max_n_vertices< dim >() > get_vertices(const typename Triangulation< dim, spacedim >::cell_iterator &cell) const
Definition point.h:111
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_DISABLE_EXTRA_DIAGNOSTICS
Definition config.h:636
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
#define DEAL_II_ENABLE_EXTRA_DIAGNOSTICS
Definition config.h:680
#define DEAL_II_NOT_IMPLEMENTED()
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
static ::ExceptionBase & ExcMessage(std::string arg1)
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)
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)
void mark_domains(CDT &ct, Face_handle start, int index, std::list< CDT::Edge > &border)
std::optional< std::variant< CGALPoint3, CGALSegment3 > > compute_intersection_tetra_segment(const ArrayView< const Point< 3 > > &tetrahedron, const ArrayView< const Point< 3 > > &segment)
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 >, 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< 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< CGALPoint3, CGALSegment3, CGALTriangle3, std::vector< CGALPoint3 > > > compute_intersection_tetra_triangle(const ArrayView< const Point< 3 > > &tetrahedron, const ArrayView< const Point< 3 > > &triangle)
std::optional< std::variant< CGALPoint2, CGALSegment2 > > compute_intersection_triangle_segment(const ArrayView< const Point< 2 > > &triangle, const ArrayView< const Point< 2 > > &segment)
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< 2 >, 3 > > compute_intersection_quad_quad(const ArrayView< const Point< 2 > > &quad0, const ArrayView< const Point< 2 > > &quad1, const double tol)
K::Tetrahedron_3 CGALTetra
CGAL::Surface_mesh< K_exact::Point_3 > Surface_mesh
K::Segment_2 CGALSegment2
const T * get_if_(const std::variant< Types... > *v)
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
K::Point_3 CGALPoint3
CGAL::Triangulation_3< K_exact > Triangulation3_exact
CGAL::Constrained_Delaunay_triangulation_2< K, Tds, Itag > CDT
std::vector< std::array< Point< spacedim >, structdim1+1 > > compute_intersection_of_cells(const typename Triangulation< structdim0, spacedim >::cell_iterator &cell0, const typename Triangulation< structdim1, spacedim >::cell_iterator &cell1, const Mapping< structdim0, spacedim > &mapping0, const Mapping< structdim1, spacedim > &mapping1, const double tol=1e-9)
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
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
K::Point_2 CGALPoint2
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