deal.II version 9.7.0
\(\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
tria_accessor.h
Go to the documentation of this file.
1// ------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: LGPL-2.1-or-later
4// Copyright (C) 1998 - 2025 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Part of the source code is dual licensed under Apache-2.0 WITH
9// LLVM-exception OR LGPL-2.1-or-later. Detailed license information
10// governing the source code and code contributions can be found in
11// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II.
12//
13// ------------------------------------------------------------------------
14
15#ifndef dealii_tria_accessor_h
16#define dealii_tria_accessor_h
17
18
19#include <deal.II/base/config.h>
20
24#include <deal.II/base/point.h>
26
34
35#include <boost/container/small_vector.hpp>
36
37#include <cmath>
38#include <limits>
39#include <utility>
40
41
43
44// Forward declarations
45#ifndef DOXYGEN
46template <int dim, int spacedim>
48class Triangulation;
49template <typename Accessor>
50class TriaRawIterator;
51template <typename Accessor>
52class TriaIterator;
53template <typename Accessor>
55
56namespace parallel
57{
58 template <int dim, int spacedim>
59 DEAL_II_CXX20_REQUIRES((concepts::is_valid_dim_spacedim<dim, spacedim>))
61}
62
63template <int dim, int spacedim>
65class DoFHandler;
66template <int dim, int spacedim, bool lda>
67class DoFCellAccessor;
68
69
70template <int dim, int spacedim>
71class Manifold;
72
73template <int dim, int spacedim>
74class Mapping;
75#endif
76
77namespace internal
78{
80 {
81 class TriaObjects;
82 struct Implementation;
84 } // namespace TriangulationImplementation
85
87 {
88 struct Implementation;
89
95 template <int structdim, int dim>
97 {
98 struct type
99 {
103 type() = default;
104
108 type(const int level)
109 {
110 Assert(level == 0, ExcInternalError());
111 (void)level; // removes -Wunused-parameter warning in optimized mode
112 }
113
117 operator int() const
118 {
119 return 0;
120 }
121
122 void
124 {
126 }
127
128 void
130 {
132 }
133 };
134 };
135
136
142 template <int dim>
143 struct PresentLevelType<dim, dim>
144 {
145 using type = int;
146 };
147 } // namespace TriaAccessorImplementation
148} // namespace internal
149template <int structdim, int dim, int spacedim>
150class TriaAccessor;
151template <int dim, int spacedim>
152class TriaAccessor<0, dim, spacedim>;
153template <int spacedim>
154class TriaAccessor<0, 1, spacedim>;
155
160{
165 "The operation you are attempting can only be performed for "
166 "(cell, face, or edge) iterators that point to valid "
167 "objects. These objects need not necessarily be active, "
168 "i.e., have no children, but they need to be part of a "
169 "triangulation. (The objects pointed to by an iterator "
170 "may -- after coarsening -- also be objects that used "
171 "to be part of a triangulation, but are now no longer "
172 "used. Their memory location may have been retained "
173 "for re-use upon the next mesh refinement, but is "
174 "currently unused.)");
185 "The operation you are attempting can only be performed for "
186 "(cell, face, or edge) iterators that point to 'active' "
187 "objects. 'Active' objects are those that do not have "
188 "children (in the case of cells), or that are part of "
189 "an active cell (in the case of faces or edges). However, "
190 "the object on which you are trying the current "
191 "operation is not 'active' in this sense.");
198 "The operation you are attempting can only be performed for "
199 "(cell, face, or edge) iterators that have children, "
200 "but the object on which you are trying the current "
201 "operation does not have any.");
209 "The operation you are attempting can only be performed for "
210 "(cell, face, or edge) iterators that have a parent object, "
211 "but the object on which you are trying the current "
212 "operation does not have one -- i.e., it is on the "
213 "coarsest level of the triangulation.");
218 int,
219 << "You can only set the child index if the cell does not "
220 << "currently have children registered; or you can clear it. "
221 << "The given index was " << arg1
222 << " (-1 means: clear children).");
226 template <typename AccessorType>
228 AccessorType,
229 << "You tried to dereference an iterator for which this "
230 << "is not possible. More information on this iterator: "
231 << "index=" << arg1.index() << ", state="
232 << (arg1.state() == IteratorState::valid ?
233 "valid" :
234 (arg1.state() == IteratorState::past_the_end ?
235 "past_the_end" :
236 "invalid")));
241 "Iterators can only be compared if they point to the same "
242 "triangulation, or if neither of them are associated "
243 "with a triangulation.");
244 // TODO: Write documentation!
249 // TODO: Write documentation!
269 // TODO: Write documentation!
275 int,
276 << "You can only set the child index of an even numbered child."
277 << "The number of the child given was " << arg1 << '.');
278} // namespace TriaAccessorExceptions
279
280
306template <int structdim, int dim, int spacedim = dim>
308{
309public:
316 static constexpr unsigned int space_dimension = spacedim;
317
323 static constexpr unsigned int dimension = dim;
324
330 static const unsigned int structure_dimension = structdim;
331
341 void
342 operator=(const TriaAccessorBase *) = delete;
343
344protected:
350 using AccessorData = void;
351
356 const int level = -1,
357 const int index = -1,
358 const AccessorData * = nullptr);
359
364
372 void
374
380
391 bool
392 operator<(const TriaAccessorBase &other) const;
393
394protected:
398 bool
400
404 bool
406
420 void
422
430 void
435
440 objects() const;
441
442public:
448 using LocalData = void *;
449
456
473 int
474 level() const;
475
502 int
503 index() const;
504
510 state() const;
511
518
522protected:
527 typename ::internal::TriaAccessorImplementation::
528 PresentLevelType<structdim, dim>::type present_level;
529
535
540
541private:
542 template <typename Accessor>
543 friend class TriaRawIterator;
544 template <typename Accessor>
545 friend class TriaIterator;
546 template <typename Accessor>
547 friend class TriaActiveIterator;
548};
549
550
551
572template <int structdim, int dim, int spacedim = dim>
574{
575public:
582 static constexpr unsigned int space_dimension = spacedim;
583
589 static constexpr unsigned int dimension = dim;
590
596 static const unsigned int structure_dimension = structdim;
597
603 using AccessorData = void;
604
612 InvalidAccessor(const void *parent = nullptr,
613 const int level = -1,
614 const int index = -1,
615 const AccessorData *local_data = nullptr);
616
625
630 template <typename OtherAccessor>
631 InvalidAccessor(const OtherAccessor &);
632
636 void
638
642 bool
644 bool
646
650 void
651 operator++() const;
652 void
653 operator--() const;
654
660 state();
661
662
667 static int
668 level();
669
674 static int
675 index();
676
681 bool
682 used() const;
683
688 bool
690
695 manifold_id() const;
696
700 unsigned int
701 user_index() const;
702
706 void
707 set_user_index(const unsigned int p) const;
708
712 void
714
719 vertex(const unsigned int i) const;
720
725 void *
726 line(const unsigned int i) const;
727
732 void *
733 quad(const unsigned int i) const;
734};
735
736
737
755template <int structdim, int dim, int spacedim>
756class TriaAccessor : public TriaAccessorBase<structdim, dim, spacedim>
757{
758public:
764
769 const int level = -1,
770 const int index = -1,
771 const AccessorData *local_data = nullptr);
772
777 TriaAccessor(const TriaAccessor &) = default;
778
782 TriaAccessor(TriaAccessor &&) = default; // NOLINT
783
796 template <int structdim2, int dim2, int spacedim2>
798
803 template <int structdim2, int dim2, int spacedim2>
805
816 operator=(const TriaAccessor &) = delete;
817
822 operator=(TriaAccessor &&) = default; // NOLINT
823
827 ~TriaAccessor() = default;
828
835 bool
836 used() const;
837
844
850 vertex_iterator(const unsigned int i) const;
851
867 unsigned int
868 vertex_index(const unsigned int i) const;
869
908 vertex(const unsigned int i) const;
909
913 typename ::internal::TriangulationImplementation::
914 Iterators<dim, spacedim>::line_iterator
915 line(const unsigned int i) const;
916
923 unsigned int
924 line_index(const unsigned int i) const;
925
929 typename ::internal::TriangulationImplementation::
930 Iterators<dim, spacedim>::quad_iterator
931 quad(const unsigned int i) const;
932
939 unsigned int
940 quad_index(const unsigned int i) const;
944
951
959 combined_face_orientation(const unsigned int face) const;
960
972 bool
973 face_orientation(const unsigned int face) const;
974
984 bool
985 face_flip(const unsigned int face) const;
986
996 bool
997 face_rotation(const unsigned int face) const;
998
1009 line_orientation(const unsigned int line) const;
1013
1020
1024 bool
1026
1031 unsigned int
1032 n_children() const;
1033
1047 unsigned int
1049
1063 unsigned int
1065
1070 child(const unsigned int i) const;
1071
1076 unsigned int
1079
1089 isotropic_child(const unsigned int i) const;
1090
1096
1102 int
1103 child_index(const unsigned int i) const;
1104
1110 int
1111 isotropic_child_index(const unsigned int i) const;
1115
1122
1135
1163 void
1165
1194 void
1196
1204 bool
1206
1218
1222
1229
1241
1259 void
1261
1275 void
1277
1281
1282
1294 bool
1295 user_flag_set() const;
1296
1302 void
1303 set_user_flag() const;
1304
1310 void
1311 clear_user_flag() const;
1312
1318 void
1320
1326 void
1328
1334 void
1335 clear_user_data() const;
1336
1348 void
1349 set_user_pointer(void *p) const;
1350
1356 void
1357 clear_user_pointer() const;
1358
1376 void *
1377 user_pointer() const;
1378
1400 void
1401 recursively_set_user_pointer(void *p) const;
1402
1409 void
1411
1421 void
1422 set_user_index(const unsigned int p) const;
1423
1429 void
1430 clear_user_index() const;
1431
1443 unsigned int
1444 user_index() const;
1445
1463 void
1464 recursively_set_user_index(const unsigned int p) const;
1465
1474 void
1479
1486
1510 double
1511 diameter() const;
1512
1539 std::pair<Point<spacedim>, double>
1541
1552
1562 double
1563 extent_in_direction(const unsigned int axis) const;
1564
1568 double
1570
1585 intermediate_point(const Point<structdim> &coordinates) const;
1586
1611
1647 center(const bool respect_manifold = false,
1648 const bool interpolate_from_surrounding = false) const;
1649
1668 barycenter() const;
1669
1703 double
1704 measure() const;
1705
1720 bool
1723
1729
1733 unsigned int
1734 n_vertices() const;
1735
1739 unsigned int
1740 n_lines() const;
1741
1751 unsigned int
1752 n_faces() const;
1753
1760
1767
1776
1780
1781private:
1786 void
1788
1796 void
1798 const std::initializer_list<int> &new_indices) const;
1799
1803 void
1805 const std::initializer_list<unsigned int> &new_indices) const;
1806
1814 void
1815 set_line_orientation(const unsigned int line,
1816 const types::geometric_orientation orientation) const;
1817
1827 void
1829 const unsigned int face,
1830 const types::geometric_orientation combined_orientation) const;
1831
1835 void
1837
1841 void
1843
1852 void
1854
1862 void
1864
1871 void
1872 set_children(const unsigned int i, const int index) const;
1873
1878 void
1880
1881private:
1882 friend class Triangulation<dim, spacedim>;
1883
1884 friend struct ::internal::TriangulationImplementation::Implementation;
1885 friend struct ::internal::TriangulationImplementation::
1886 ImplementationMixedMesh;
1887 friend struct ::internal::TriaAccessorImplementation::Implementation;
1888};
1889
1890
1891
1910template <int dim, int spacedim>
1911class TriaAccessor<0, dim, spacedim>
1912{
1913public:
1919 static constexpr unsigned int space_dimension = spacedim;
1920
1926 static constexpr unsigned int dimension = dim;
1927
1933 static const unsigned int structure_dimension = 0;
1934
1938 using AccessorData = void;
1939
1945 const unsigned int vertex_index);
1946
1953 const int level = 0,
1954 const int index = 0,
1955 const AccessorData * = nullptr);
1956
1960 template <int structdim2, int dim2, int spacedim2>
1962
1966 template <int structdim2, int dim2, int spacedim2>
1968
1973 state() const;
1974
1979 static int
1981
1986 int
1987 index() const;
1988
1995
2005 void
2007
2011 void
2016 bool
2017 operator==(const TriaAccessor &) const;
2018
2022 bool
2023 operator!=(const TriaAccessor &) const;
2024
2028
2029
2036
2052 unsigned int
2053 vertex_index(const unsigned int i = 0) const;
2054
2061 vertex(const unsigned int i = 0) const;
2062
2067 typename ::internal::TriangulationImplementation::
2068 Iterators<dim, spacedim>::line_iterator static line(const unsigned int);
2069
2073 static unsigned int
2074 line_index(const unsigned int i);
2075
2079 static typename ::internal::TriangulationImplementation::
2080 Iterators<dim, spacedim>::quad_iterator
2081 quad(const unsigned int i);
2082
2086 static unsigned int
2087 quad_index(const unsigned int i);
2088
2092
2093
2100
2104 double
2105 diameter() const;
2106
2114 double
2115 extent_in_direction(const unsigned int axis) const;
2116
2125 center(const bool respect_manifold = false,
2126 const bool interpolate_from_surrounding = false) const;
2127
2135 double
2136 measure() const;
2140
2147
2154 combined_face_orientation(const unsigned int face);
2155
2159 static bool
2160 face_orientation(const unsigned int face);
2161
2165 static bool
2166 face_flip(const unsigned int face);
2167
2171 static bool
2172 face_rotation(const unsigned int face);
2173
2178 line_orientation(const unsigned int line);
2179
2183
2190
2194 static bool
2196
2201 static unsigned int
2203
2208 static unsigned int
2210
2214 static unsigned int
2216
2220 static unsigned int
2222
2227 child(const unsigned int);
2228
2233 isotropic_child(const unsigned int);
2234
2238 static RefinementCase<0>
2240
2244 static int
2245 child_index(const unsigned int i);
2246
2250 static int
2251 isotropic_child_index(const unsigned int i);
2255
2259 bool
2260 used() const;
2261
2262protected:
2270 void
2272
2281 bool
2282 operator<(const TriaAccessor &other) const;
2283
2288
2293
2294private:
2295 template <typename Accessor>
2296 friend class TriaRawIterator;
2297 template <typename Accessor>
2298 friend class TriaIterator;
2299 template <typename Accessor>
2301};
2302
2303
2304
2321template <int spacedim>
2322class TriaAccessor<0, 1, spacedim>
2323{
2324public:
2330 static constexpr unsigned int space_dimension = spacedim;
2331
2337 static constexpr unsigned int dimension = 1;
2338
2344 static const unsigned int structure_dimension = 0;
2345
2349 using AccessorData = void;
2350
2355 enum VertexKind
2356 {
2360 left_vertex,
2364 interior_vertex,
2368 right_vertex
2369 };
2370
2382 TriaAccessor(const Triangulation<1, spacedim> *tria,
2383 const VertexKind vertex_kind,
2384 const unsigned int vertex_index);
2385
2391 TriaAccessor(const Triangulation<1, spacedim> *tria = nullptr,
2392 const int = 0,
2393 const int = 0,
2394 const AccessorData * = nullptr);
2395
2399 template <int structdim2, int dim2, int spacedim2>
2401
2405 template <int structdim2, int dim2, int spacedim2>
2406 TriaAccessor(const InvalidAccessor<structdim2, dim2, spacedim2> &);
2407
2412 void
2413 copy_from(const TriaAccessor &);
2414
2420 void
2422
2429 state();
2430
2435 static int
2436 level();
2437
2442 int
2443 index() const;
2444
2449 const Triangulation<1, spacedim> &
2450 get_triangulation() const;
2451
2462 void
2463 operator++() const;
2464
2469 void
2470 operator--() const;
2474 bool
2475 operator==(const TriaAccessor &) const;
2476
2480 bool
2481 operator!=(const TriaAccessor &) const;
2482
2491 bool
2492 operator<(const TriaAccessor &other) const;
2493
2497
2504
2520 unsigned int
2521 vertex_index(const unsigned int i = 0) const;
2522
2528 Point<spacedim> &
2529 vertex(const unsigned int i = 0) const;
2530
2535 Point<spacedim>
2536 center() const;
2537
2542 typename ::internal::TriangulationImplementation::
2543 Iterators<1, spacedim>::line_iterator static line(const unsigned int);
2544
2551 static unsigned int
2552 line_index(const unsigned int i);
2553
2557 static typename ::internal::TriangulationImplementation::
2558 Iterators<1, spacedim>::quad_iterator
2559 quad(const unsigned int i);
2560
2567 static unsigned int
2568 quad_index(const unsigned int i);
2569
2573
2580
2587 static double
2588 measure();
2589
2593
2598 bool
2599 at_boundary() const;
2600
2616 boundary_id() const;
2617
2621 const Manifold<1, spacedim> &
2622 get_manifold() const;
2623
2631 manifold_id() const;
2632
2633
2645 bool
2646 user_flag_set() const;
2647
2653 void
2654 set_user_flag() const;
2655
2661 void
2662 clear_user_flag() const;
2663
2669 void
2671
2677 void
2679
2685 void
2686 clear_user_data() const;
2687
2699 void
2700 set_user_pointer(void *p) const;
2701
2707 void
2708 clear_user_pointer() const;
2709
2725 void *
2726 user_pointer() const;
2727
2749 void
2750 recursively_set_user_pointer(void *p) const;
2751
2758 void
2760
2770 void
2771 set_user_index(const unsigned int p) const;
2772
2778 void
2779 clear_user_index() const;
2780
2792 unsigned int
2793 user_index() const;
2794
2812 void
2813 recursively_set_user_index(const unsigned int p) const;
2814
2823 void
2828
2835
2842 combined_face_orientation(const unsigned int face);
2843
2847 static bool
2848 face_orientation(const unsigned int face);
2849
2853 static bool
2854 face_flip(const unsigned int face);
2855
2859 static bool
2860 face_rotation(const unsigned int face);
2861
2866 line_orientation(const unsigned int line);
2867
2871
2878
2882 static bool
2883 has_children();
2884
2889 static unsigned int
2890 n_children();
2891
2896 static unsigned int
2898
2902 static unsigned int
2904
2908 static unsigned int
2909 child_iterator_to_index(const TriaIterator<TriaAccessor<0, 1, spacedim>> &);
2910
2915 child(const unsigned int);
2916
2921 isotropic_child(const unsigned int);
2922
2926 static RefinementCase<0>
2928
2932 static int
2933 child_index(const unsigned int i);
2934
2938 static int
2939 isotropic_child_index(const unsigned int i);
2943
2950
2970 void
2972
2979 void
2981
2991 void
2993
3005 void
3010
3014 bool
3015 used() const;
3016
3021 reference_cell() const;
3022
3026 unsigned int
3027 n_vertices() const;
3028
3032 unsigned int
3033 n_lines() const;
3034
3040 vertex_indices() const;
3041
3047 line_indices() const;
3048
3049protected:
3053 const Triangulation<1, spacedim> *tria;
3054
3059 VertexKind vertex_kind;
3060
3064 unsigned int global_vertex_index;
3065};
3066
3067
3068
3084template <int dim, int spacedim = dim>
3085class CellAccessor : public TriaAccessor<dim, dim, spacedim>
3086{
3087public:
3092
3097
3104
3109 const int level = -1,
3110 const int index = -1,
3111 const AccessorData *local_data = nullptr);
3112
3117
3130 template <int structdim2, int dim2, int spacedim2>
3132
3137 template <int structdim2, int dim2, int spacedim2>
3139
3144
3148 // NOLINTNEXTLINE OSX does not compile with noexcept
3150
3154 ~CellAccessor() = default;
3155
3167
3171 // NOLINTNEXTLINE OSX does not compile with noexcept
3174
3178
3185
3199
3210 const DoFHandler<dim, spacedim> &dof_handler) const;
3211
3212
3216
3223
3229 child(const unsigned int i) const;
3230
3234 boost::container::small_vector<TriaIterator<CellAccessor<dim, spacedim>>,
3237
3241 TriaIterator<TriaAccessor<dim - 1, dim, spacedim>>
3242 face(const unsigned int i) const;
3243
3248 unsigned int
3251
3255 boost::container::small_vector<
3256 TriaIterator<TriaAccessor<dim - 1, dim, spacedim>>,
3257#ifndef _MSC_VER // MSVC prior to 2022 cannot use a constexpr function this way
3259#else
3261#endif
3262 >
3264
3274 unsigned int
3275 face_index(const unsigned int i) const;
3276
3325 neighbor_child_on_subface(const unsigned int face_no,
3326 const unsigned int subface_no) const;
3327
3376 neighbor(const unsigned int face_no) const;
3377
3385 int
3386 neighbor_index(const unsigned int face_no) const;
3387
3395 int
3396 neighbor_level(const unsigned int face_no) const;
3397
3409 unsigned int
3410 neighbor_of_neighbor(const unsigned int face_no) const;
3411
3422 bool
3423 neighbor_is_coarser(const unsigned int face_no) const;
3424
3439 std::pair<unsigned int, unsigned int>
3440 neighbor_of_coarser_neighbor(const unsigned int neighbor) const;
3441
3448 unsigned int
3449 neighbor_face_no(const unsigned int neighbor) const;
3450
3454 static bool
3456
3470 bool
3471 has_periodic_neighbor(const unsigned int i) const;
3472
3490 periodic_neighbor(const unsigned int i) const;
3491
3500 neighbor_or_periodic_neighbor(const unsigned int i) const;
3501
3517 periodic_neighbor_child_on_subface(const unsigned int face_no,
3518 const unsigned int subface_no) const;
3519
3530 std::pair<unsigned int, unsigned int>
3532
3538 int
3539 periodic_neighbor_index(const unsigned int i) const;
3540
3546 int
3547 periodic_neighbor_level(const unsigned int i) const;
3548
3563 unsigned int
3564 periodic_neighbor_of_periodic_neighbor(const unsigned int i) const;
3565
3571 unsigned int
3572 periodic_neighbor_face_no(const unsigned int i) const;
3573
3580 bool
3581 periodic_neighbor_is_coarser(const unsigned int i) const;
3582
3586
3593
3599 bool
3600 at_boundary(const unsigned int i) const;
3601
3610 bool
3612
3620 bool
3625
3632
3649
3667 void
3670
3674 void
3676
3681 std::uint8_t
3683
3688 void
3689 set_refine_choice(const std::uint8_t refinement_choice = static_cast<char>(
3691
3695 void
3697
3705 bool
3707 const unsigned int face_no,
3708 const RefinementCase<dim - 1> &face_refinement_case =
3710
3716 bool
3717 flag_for_line_refinement(const unsigned int line_no) const;
3718
3728 subface_case(const unsigned int face_no) const;
3729
3733 bool
3735
3740 void
3742
3746 void
3751
3758
3772
3784 void
3785 set_material_id(const types::material_id new_material_id) const;
3786
3795 void
3800
3807
3824
3840 void
3841 set_subdomain_id(const types::subdomain_id new_subdomain_id) const;
3842
3853
3858 void
3860 const types::subdomain_id new_level_subdomain_id) const;
3861
3862
3878 void
3880 const types::subdomain_id new_subdomain_id) const;
3884
3904
3914
3921
3931 bool
3933
3959 unsigned int
3961
3969 int
3971
3978 parent() const;
3979
3983
3990
3999 bool
4000 is_active() const;
4001
4021 bool
4023
4028 bool
4030
4064 bool
4065 is_ghost() const;
4066
4072 bool
4074
4101 bool
4103
4110 bool
4112
4126 bool
4128
4137 void
4138 set_neighbor(const unsigned int i,
4139 const TriaIterator<CellAccessor<dim, spacedim>> &pointer) const;
4140
4154 CellId
4155 id() const;
4156
4157 using TriaAccessor<dim, dim, spacedim>::diameter;
4158
4162 double
4164
4168
4169
4182
4183protected:
4199 unsigned int
4200 neighbor_of_neighbor_internal(const unsigned int neighbor) const;
4201
4207 template <int dim_, int spacedim_>
4208 bool
4210
4211
4212
4213private:
4218 void
4219 set_active_cell_index(const unsigned int active_cell_index) const;
4220
4224 void
4226
4230 void
4232
4236 void
4237 set_parent(const unsigned int parent_index);
4238
4249 void
4250 set_direction_flag(const bool new_direction_flag) const;
4251
4252 friend class Triangulation<dim, spacedim>;
4253
4254 friend class parallel::TriangulationBase<dim, spacedim>;
4255
4256 friend struct ::internal::TriangulationImplementation::Implementation;
4257 friend struct ::internal::TriangulationImplementation::
4258 ImplementationMixedMesh;
4259};
4260
4261
4262
4263/* ----- declaration of explicit specializations and general templates ----- */
4264
4265
4266template <int structdim, int dim, int spacedim>
4267template <typename OtherAccessor>
4269 const OtherAccessor &)
4270{
4271 Assert(false,
4272 ExcMessage("You are attempting an illegal conversion between "
4273 "iterator/accessor types. The constructor you call "
4274 "only exists to make certain template constructs "
4275 "easier to write as dimension independent code but "
4276 "the conversion is not valid in the current context."));
4277}
4278
4279
4280
4281template <int structdim, int dim, int spacedim>
4282template <int structdim2, int dim2, int spacedim2>
4285{
4286 Assert(false,
4287 ExcMessage("You are attempting an illegal conversion between "
4288 "iterator/accessor types. The constructor you call "
4289 "only exists to make certain template constructs "
4290 "easier to write as dimension independent code but "
4291 "the conversion is not valid in the current context."));
4292}
4293
4294
4295
4296template <int dim, int spacedim>
4297template <int structdim2, int dim2, int spacedim2>
4300{
4301 Assert(false,
4302 ExcMessage("You are attempting an illegal conversion between "
4303 "iterator/accessor types. The constructor you call "
4304 "only exists to make certain template constructs "
4305 "easier to write as dimension independent code but "
4306 "the conversion is not valid in the current context."));
4307}
4308
4309
4310
4311template <int structdim, int dim, int spacedim>
4312template <int structdim2, int dim2, int spacedim2>
4315{
4316 Assert(false,
4317 ExcMessage("You are attempting an illegal conversion between "
4318 "iterator/accessor types. The constructor you call "
4319 "only exists to make certain template constructs "
4320 "easier to write as dimension independent code but "
4321 "the conversion is not valid in the current context."));
4322}
4323
4324
4325
4326template <int dim, int spacedim>
4327template <int structdim2, int dim2, int spacedim2>
4330{
4331 Assert(false,
4332 ExcMessage("You are attempting an illegal conversion between "
4333 "iterator/accessor types. The constructor you call "
4334 "only exists to make certain template constructs "
4335 "easier to write as dimension independent code but "
4336 "the conversion is not valid in the current context."));
4337}
4338
4339
4340#ifndef DOXYGEN
4341
4342template <>
4343bool
4345template <>
4346bool
4348template <>
4349bool
4351template <>
4352bool
4354template <>
4355bool
4357template <>
4358bool
4360// -------------------------------------------------------------------
4361
4362template <>
4363void
4365
4366
4367
4368namespace internal
4369{
4370 namespace TriaAccessorImplementation
4371 {
4377 template <int dim, int spacedim>
4378 inline double
4379 diameter(
4380 const boost::container::small_vector<Point<spacedim>,
4382 vertices)
4383 {
4384 const ReferenceCell reference_cell =
4385 ReferenceCell::n_vertices_to_type(dim, vertices.size());
4386
4387 if (reference_cell == ReferenceCells::Line)
4388 // Return the distance between the two vertices
4389 return (vertices[1] - vertices[0]).norm();
4390 else if (reference_cell == ReferenceCells::Triangle)
4391 // Return the longest of the three edges
4392 return std::max({(vertices[1] - vertices[0]).norm(),
4393 (vertices[2] - vertices[1]).norm(),
4394 (vertices[2] - vertices[0]).norm()});
4395 else if (reference_cell == ReferenceCells::Quadrilateral)
4396 // Return the longer one of the two diagonals of the quadrilateral
4397 return std::max({(vertices[3] - vertices[0]).norm(),
4398 (vertices[2] - vertices[1]).norm()});
4399 else if (reference_cell == ReferenceCells::Tetrahedron)
4400 // Return the longest of the six edges of the tetrahedron
4401 return std::max({(vertices[1] - vertices[0]).norm(),
4402 (vertices[2] - vertices[0]).norm(),
4403 (vertices[2] - vertices[1]).norm(),
4404 (vertices[3] - vertices[0]).norm(),
4405 (vertices[3] - vertices[1]).norm(),
4406 (vertices[3] - vertices[2]).norm()});
4407 else if (reference_cell == ReferenceCells::Pyramid)
4408 // Return ...
4409 return std::max({// the longest diagonal of the quadrilateral base
4410 // of the pyramid or ...
4411 (vertices[3] - vertices[0]).norm(),
4412 (vertices[2] - vertices[1]).norm(),
4413 // the longest edge connected with the apex of the
4414 // pyramid
4415 (vertices[4] - vertices[0]).norm(),
4416 (vertices[4] - vertices[1]).norm(),
4417 (vertices[4] - vertices[2]).norm(),
4418 (vertices[4] - vertices[3]).norm()});
4419 else if (reference_cell == ReferenceCells::Wedge)
4420 // Return ...
4421 return std::max({// the longest of the 2*3=6 diagonals of the three
4422 // quadrilateral sides of the wedge or ...
4423 (vertices[4] - vertices[0]).norm(),
4424 (vertices[3] - vertices[1]).norm(),
4425 (vertices[5] - vertices[1]).norm(),
4426 (vertices[4] - vertices[2]).norm(),
4427 (vertices[5] - vertices[0]).norm(),
4428 (vertices[3] - vertices[2]).norm(),
4429 // the longest of the 3*2=6 edges of the two
4430 // triangular faces of the wedge
4431 (vertices[1] - vertices[0]).norm(),
4432 (vertices[2] - vertices[1]).norm(),
4433 (vertices[2] - vertices[0]).norm(),
4434 (vertices[4] - vertices[3]).norm(),
4435 (vertices[5] - vertices[4]).norm(),
4436 (vertices[5] - vertices[3]).norm()});
4437 else if (reference_cell == ReferenceCells::Hexahedron)
4438 // Return the longest of the four diagonals of the hexahedron
4439 return std::max({(vertices[7] - vertices[0]).norm(),
4440 (vertices[6] - vertices[1]).norm(),
4441 (vertices[2] - vertices[5]).norm(),
4442 (vertices[3] - vertices[4]).norm()});
4443
4445 return -1e10;
4446 }
4447 } // namespace TriaAccessorImplementation
4448} // namespace internal
4449
4450
4451/*--------------------- Functions: TriaAccessorBase -------------------------*/
4452
4453template <int structdim, int dim, int spacedim>
4455 const Triangulation<dim, spacedim> *tria,
4456 const int level,
4457 const int index,
4458 const AccessorData *)
4459 : present_level((structdim == dim) ? level : 0)
4460 , present_index(index)
4461 , tria(tria)
4462{
4463 // non-cells have no level, so a 0
4464 // should have been passed, or a -1
4465 // for an end-iterator, or -2 for
4466 // an invalid (default constructed)
4467 // iterator
4468 if (structdim != dim)
4469 {
4470 Assert((level == 0) || (level == -1) || (level == -2),
4472 }
4473}
4474
4475
4476template <int structdim, int dim, int spacedim>
4479 : present_level(a.present_level)
4480 , present_index(a.present_index)
4481 , tria(a.tria)
4482{}
4483
4484
4485template <int structdim, int dim, int spacedim>
4486inline void
4489{
4490 present_level = a.present_level;
4491 present_index = a.present_index;
4492 tria = a.tria;
4493
4494 if (structdim != dim)
4495 {
4496 Assert((present_level == 0) || (present_level == -1) ||
4497 (present_level == -2),
4499 }
4500}
4501
4502
4503
4504template <int structdim, int dim, int spacedim>
4508{
4509 present_level = a.present_level;
4510 present_index = a.present_index;
4511 tria = a.tria;
4512
4513 if (structdim != dim)
4514 {
4515 Assert((present_level == 0) || (present_level == -1) ||
4516 (present_level == -2),
4518 }
4519 return *this;
4520}
4521
4522
4523
4524template <int structdim, int dim, int spacedim>
4525inline bool
4528{
4529 Assert(tria == a.tria || tria == nullptr || a.tria == nullptr,
4531 return ((tria == a.tria) && (present_level == a.present_level) &&
4532 (present_index == a.present_index));
4533}
4534
4535
4536
4537template <int structdim, int dim, int spacedim>
4538inline bool
4541{
4542 Assert(tria == a.tria || tria == nullptr || a.tria == nullptr,
4544 return ((tria != a.tria) || (present_level != a.present_level) ||
4545 (present_index != a.present_index));
4546}
4547
4548
4549
4550template <int structdim, int dim, int spacedim>
4551inline bool
4554{
4556
4557 if (present_level != other.present_level)
4558 return (present_level < other.present_level);
4559
4560 return (present_index < other.present_index);
4561}
4562
4563
4564
4565template <int structdim, int dim, int spacedim>
4566inline int
4568{
4569 // This is always zero or invalid
4570 // if the object is not a cell
4571 return present_level;
4572}
4573
4574
4575
4576template <int structdim, int dim, int spacedim>
4577inline int
4579{
4580 return present_index;
4581}
4582
4583
4584
4585template <int structdim, int dim, int spacedim>
4588{
4589 if ((present_level >= 0) && (present_index >= 0))
4590 return IteratorState::valid;
4591 else if (present_index == -1)
4593 else
4595}
4596
4597
4598
4599template <int structdim, int dim, int spacedim>
4600inline const Triangulation<dim, spacedim> &
4602{
4603 return *tria;
4604}
4605
4606
4607
4608template <int structdim, int dim, int spacedim>
4609inline void
4611{
4612 // this iterator is used for
4613 // objects without level
4614 ++this->present_index;
4615
4616 if (structdim != dim)
4617 {
4618 // is index still in the range of
4619 // the vector? (note that we don't
4620 // have to set the level, since
4621 // dim!=1 and the object therefore
4622 // has no level)
4623 if (this->present_index >= static_cast<int>(objects().n_objects()))
4624 this->present_index = -1;
4625 }
4626 else
4627 {
4628 while (this->present_index >=
4629 static_cast<int>(
4630 this->tria->levels[this->present_level]->cells.n_objects()))
4631 {
4632 // no -> go one level up until we find
4633 // one with more than zero cells
4634 ++this->present_level;
4635 this->present_index = 0;
4636 // highest level reached?
4637 if (this->present_level >=
4638 static_cast<int>(this->tria->levels.size()))
4639 {
4640 // return with past the end pointer
4641 this->present_level = this->present_index = -1;
4642 return;
4643 }
4644 }
4645 }
4646}
4647
4648
4649template <int structdim, int dim, int spacedim>
4650inline void
4652{
4653 // same as operator++
4654 --this->present_index;
4655
4656 if (structdim != dim)
4657 {
4658 if (this->present_index < 0)
4659 this->present_index = -1;
4660 }
4661 else
4662 {
4663 while (this->present_index < 0)
4664 {
4665 // no -> go one level down
4666 --this->present_level;
4667 // lowest level reached?
4668 if (this->present_level == -1)
4669 {
4670 // return with past the end pointer
4671 this->present_level = this->present_index = -1;
4672 return;
4673 }
4674 // else
4675 this->present_index =
4676 this->tria->levels[this->present_level]->cells.n_objects() - 1;
4677 }
4678 }
4679}
4680
4681
4682
4683template <int structdim, int dim, int spacedim>
4684inline ::internal::TriangulationImplementation::TriaObjects &
4686{
4687 if (structdim == dim)
4688 return this->tria->levels[this->present_level]->cells;
4689
4690 if (structdim == 1 && dim > 1)
4691 return this->tria->faces->lines;
4692
4693 if (structdim == 2 && dim > 2)
4694 return this->tria->faces->quads;
4695
4697
4698 return this->tria->levels[this->present_level]->cells;
4699}
4700
4701
4702
4703/*---------------------- Functions: InvalidAccessor -------------------------*/
4704
4705template <int structdim, int dim, int spacedim>
4707 const int,
4708 const int,
4709 const AccessorData *)
4710{
4711 Assert(false,
4712 ExcMessage("You are attempting an invalid conversion between "
4713 "iterator/accessor types. The constructor you call "
4714 "only exists to make certain template constructs "
4715 "easier to write as dimension independent code but "
4716 "the conversion is not valid in the current context."));
4717}
4718
4719
4720
4721template <int structdim, int dim, int spacedim>
4723 const InvalidAccessor &)
4724{
4725 Assert(false,
4726 ExcMessage("You are attempting an invalid conversion between "
4727 "iterator/accessor types. The constructor you call "
4728 "only exists to make certain template constructs "
4729 "easier to write as dimension independent code but "
4730 "the conversion is not valid in the current context."));
4731}
4732
4733
4734
4735template <int structdim, int dim, int spacedim>
4736void
4738{
4739 // nothing to do here. we could
4740 // throw an exception but we can't
4741 // get here without first creating
4742 // an object which would have
4743 // already thrown
4744}
4745
4746
4747
4748template <int structdim, int dim, int spacedim>
4749bool
4751 const InvalidAccessor &) const
4752{
4753 // nothing to do here. we could
4754 // throw an exception but we can't
4755 // get here without first creating
4756 // an object which would have
4757 // already thrown
4758 return false;
4759}
4760
4761
4762
4763template <int structdim, int dim, int spacedim>
4764bool
4766 const InvalidAccessor &) const
4767{
4768 // nothing to do here. we could
4769 // throw an exception but we can't
4770 // get here without first creating
4771 // an object which would have
4772 // already thrown
4773 return true;
4774}
4775
4776
4777
4778template <int structdim, int dim, int spacedim>
4779bool
4781{
4782 // nothing to do here. we could
4783 // throw an exception but we can't
4784 // get here without first creating
4785 // an object which would have
4786 // already thrown
4787 return false;
4788}
4789
4790
4791
4792template <int structdim, int dim, int spacedim>
4793bool
4795{
4796 // nothing to do here. we could
4797 // throw an exception but we can't
4798 // get here without first creating
4799 // an object which would have
4800 // already thrown
4801 return false;
4802}
4803
4804
4805
4806template <int structdim, int dim, int spacedim>
4807void
4809{}
4810
4811
4812
4813template <int structdim, int dim, int spacedim>
4814void
4816{}
4817
4818
4819
4820template <int structdim, int dim, int spacedim>
4823{
4825}
4826
4827
4828
4829template <int structdim, int dim, int spacedim>
4830unsigned int
4832{
4834}
4835
4836
4837
4838template <int structdim, int dim, int spacedim>
4839void
4841 const unsigned int) const
4842{
4843 Assert(false,
4844 ExcMessage("You are trying to set the user index of an "
4845 "invalid object."));
4846}
4847
4848
4849
4850template <int structdim, int dim, int spacedim>
4851void
4853 const types::manifold_id) const
4854{
4855 Assert(false,
4856 ExcMessage("You are trying to set the manifold id of an "
4857 "invalid object."));
4858}
4859
4860
4861
4862template <int structdim, int dim, int spacedim>
4863inline Point<spacedim> &
4865{
4866 // nothing to do here. we could throw an exception but we can't get here
4867 // without first creating an object which would have already thrown
4868 static Point<spacedim> invalid_vertex;
4869 return invalid_vertex;
4870}
4871
4872
4873template <int structdim, int dim, int spacedim>
4874inline void *
4876{
4877 // nothing to do here. we could throw an exception but we can't get here
4878 // without first creating an object which would have already thrown
4879 return nullptr;
4880}
4881
4882
4883
4884template <int structdim, int dim, int spacedim>
4885inline void *
4887{
4888 // nothing to do here. we could throw an exception but we can't get here
4889 // without first creating an object which would have already thrown
4890 return nullptr;
4891}
4892
4893
4894/*------------------------ Functions: TriaAccessor ---------------------------*/
4895
4896
4897namespace internal
4898{
4900 {
4901 // make sure that if in the following we
4902 // write TriaAccessor
4903 // we mean the *class*
4904 // ::TriaAccessor, not the
4905 // enclosing namespace
4906 // ::internal::TriaAccessor
4907 using ::TriaAccessor;
4908
4913 struct Implementation
4914 {
4918 template <int structdim, int dim, int spacedim>
4919 inline static void
4920 set_combined_face_orientation(
4921 const TriaAccessor<structdim, dim, spacedim> &accessor,
4922 const unsigned int face_no,
4923 const types::geometric_orientation combined_orientation)
4924 {
4925 Assert(structdim == dim,
4926 ExcMessage("This function can only be used on objects that are "
4927 "cells and not on objects which bound cells."));
4928 AssertIndexRange(face_no, accessor.n_faces());
4929 AssertIndexRange(combined_orientation,
4931 face_no));
4932
4933 // face_orientations is not set up in 1d
4934 if (dim != 1)
4935 accessor.tria->levels[accessor.present_level]
4936 ->face_orientations.set_combined_orientation(
4938 face_no,
4939 combined_orientation);
4940 }
4941
4942
4943
4944 template <int dim, int spacedim>
4945 static std::array<unsigned int, 1>
4946 get_line_indices_of_cell(const TriaAccessor<1, dim, spacedim> &)
4947 {
4949 return {};
4950 }
4951
4952
4953
4954 template <int structdim, int dim, int spacedim>
4955 static std::array<unsigned int, 4>
4956 get_line_indices_of_cell(const TriaAccessor<2, dim, spacedim> &cell)
4957 {
4958 // For 2d cells the access cell->line_orientation() is already
4959 // efficient
4960 std::array<unsigned int, 4> line_indices = {};
4961 for (const unsigned int line : cell.line_indices())
4962 line_indices[line] = cell.line_index(line);
4963 return line_indices;
4964 }
4965
4970 template <int structdim, int dim, int spacedim>
4971 static std::array<unsigned int, 12>
4972 get_line_indices_of_cell(
4973 const TriaAccessor<structdim, dim, spacedim> &cell)
4974 {
4975 std::array<unsigned int, 12> line_indices = {};
4976
4977 // For hexahedra, the classical access via quads -> lines is too
4978 // inefficient. Unroll this code here to allow the compiler to inline
4979 // the necessary functions.
4980 const auto ref_cell = cell.reference_cell();
4981 if (ref_cell == ReferenceCells::Hexahedron)
4982 {
4983 for (unsigned int f = 4; f < 6; ++f)
4984 {
4985 const auto orientation =
4986 cell.get_triangulation()
4987 .levels[cell.level()]
4988 ->face_orientations.get_combined_orientation(
4990
4991 // It might seem superfluous to spell out the four indices
4992 // that get later consumed by a for loop over these four
4993 // elements; however, for the compiler it is easier to inline
4994 // the statement of standard_to_real_face_line() when next to
4995 // each other, as opposed to be interleaved with a
4996 // line_index() call.
4997 const std::array<unsigned int, 4> my_indices{
4998 {ref_cell.standard_to_real_face_line(0, f, orientation),
4999 ref_cell.standard_to_real_face_line(1, f, orientation),
5000 ref_cell.standard_to_real_face_line(2, f, orientation),
5001 ref_cell.standard_to_real_face_line(3, f, orientation)}};
5002 const auto quad = cell.quad(f);
5003 for (unsigned int l = 0; l < 4; ++l)
5004 line_indices[4 * (f - 4) + l] =
5005 quad->line_index(my_indices[l]);
5006 }
5007 for (unsigned int f = 0; f < 2; ++f)
5008 {
5009 const auto orientation =
5010 cell.get_triangulation()
5011 .levels[cell.level()]
5012 ->face_orientations.get_combined_orientation(
5014 const std::array<unsigned int, 2> my_indices{
5015 {ref_cell.standard_to_real_face_line(0, f, orientation),
5016 ref_cell.standard_to_real_face_line(1, f, orientation)}};
5017 const auto quad = cell.quad(f);
5018 line_indices[8 + f] = quad->line_index(my_indices[0]);
5019 line_indices[10 + f] = quad->line_index(my_indices[1]);
5020 }
5021 }
5022 else if (ref_cell == ReferenceCells::Tetrahedron)
5023 {
5024 std::array<unsigned int, 3> orientations{
5027 cell.combined_face_orientation(2)}};
5028 const std::array<unsigned int, 6> my_indices{
5029 {ref_cell.standard_to_real_face_line(0, 0, orientations[0]),
5030 ref_cell.standard_to_real_face_line(1, 0, orientations[0]),
5031 ref_cell.standard_to_real_face_line(2, 0, orientations[0]),
5032 ref_cell.standard_to_real_face_line(1, 1, orientations[1]),
5033 ref_cell.standard_to_real_face_line(2, 1, orientations[1]),
5034 ref_cell.standard_to_real_face_line(1, 2, orientations[2])}};
5035 line_indices[0] = cell.quad(0)->line_index(my_indices[0]);
5036 line_indices[1] = cell.quad(0)->line_index(my_indices[1]);
5037 line_indices[2] = cell.quad(0)->line_index(my_indices[2]);
5038 line_indices[3] = cell.quad(1)->line_index(my_indices[3]);
5039 line_indices[4] = cell.quad(1)->line_index(my_indices[4]);
5040 line_indices[5] = cell.quad(2)->line_index(my_indices[5]);
5041 }
5042 else
5043 // For other shapes (wedges, pyramids), we do not currently
5044 // implement an optimized function.
5045 for (unsigned int l = 0; l < std::min(12U, cell.n_lines()); ++l)
5046 line_indices[l] = cell.line_index(l);
5047
5048 return line_indices;
5049 }
5050
5051
5052
5057 template <int dim, int spacedim>
5058 static std::array<types::geometric_orientation, 1>
5059 get_line_orientations_of_cell(const TriaAccessor<1, dim, spacedim> &)
5060 {
5062 return {};
5063 }
5064
5065
5066
5071 template <int dim, int spacedim>
5072 static std::array<types::geometric_orientation, 4>
5073 get_line_orientations_of_cell(const TriaAccessor<2, dim, spacedim> &cell)
5074 {
5075 // For 2d cells the access cell->line_orientation() is already
5076 // efficient
5077 std::array<types::geometric_orientation, 4> line_orientations = {};
5078 for (const unsigned int line : cell.line_indices())
5079 line_orientations[line] = cell.line_orientation(line);
5080 return line_orientations;
5081 }
5082
5083
5084
5089 template <int dim, int spacedim>
5090 static std::array<types::geometric_orientation, 12>
5091 get_line_orientations_of_cell(const TriaAccessor<3, dim, spacedim> &cell)
5092 {
5093 std::array<types::geometric_orientation, 12> line_orientations = {};
5094
5095 // For hexahedra, the classical access via quads -> lines is too
5096 // inefficient. Unroll this code here to allow the compiler to inline
5097 // the necessary functions.
5098 const auto ref_cell = cell.reference_cell();
5099 if (ref_cell == ReferenceCells::Hexahedron)
5100 {
5101 for (unsigned int f = 4; f < 6; ++f)
5102 {
5103 const auto orientation =
5104 cell.get_triangulation()
5105 .levels[cell.level()]
5106 ->face_orientations.get_combined_orientation(
5108
5109 // It might seem superfluous to spell out the four indices and
5110 // orientations that get later consumed by a for loop over
5111 // these four elements; however, for the compiler it is easier
5112 // to inline the statement of standard_to_real_face_line()
5113 // when next to each other, as opposed to be interleaved with
5114 // a line_index() call.
5115 const std::array<unsigned int, 4> my_indices{
5116 {ref_cell.standard_to_real_face_line(0, f, orientation),
5117 ref_cell.standard_to_real_face_line(1, f, orientation),
5118 ref_cell.standard_to_real_face_line(2, f, orientation),
5119 ref_cell.standard_to_real_face_line(3, f, orientation)}};
5120 const auto quad = cell.quad(f);
5121 const std::array<types::geometric_orientation, 4>
5122 my_orientations{{ref_cell.face_to_cell_line_orientation(
5123 0,
5124 f,
5125 orientation,
5126 quad->line_orientation(my_indices[0])),
5127 ref_cell.face_to_cell_line_orientation(
5128 1,
5129 f,
5130 orientation,
5131 quad->line_orientation(my_indices[1])),
5132 ref_cell.face_to_cell_line_orientation(
5133 2,
5134 f,
5135 orientation,
5136 quad->line_orientation(my_indices[2])),
5137 ref_cell.face_to_cell_line_orientation(
5138 3,
5139 f,
5140 orientation,
5141 quad->line_orientation(my_indices[3]))}};
5142 for (unsigned int l = 0; l < 4; ++l)
5143 line_orientations[4 * (f - 4) + l] = my_orientations[l];
5144 }
5145 for (unsigned int f = 0; f < 2; ++f)
5146 {
5147 const auto orientation =
5148 cell.get_triangulation()
5149 .levels[cell.level()]
5150 ->face_orientations.get_combined_orientation(
5151 cell.index() * ReferenceCells::max_n_faces<3>() + f);
5152 const std::array<unsigned int, 2> my_indices{
5153 {ref_cell.standard_to_real_face_line(0, f, orientation),
5154 ref_cell.standard_to_real_face_line(1, f, orientation)}};
5155 const auto quad = cell.quad(f);
5156 const std::array<types::geometric_orientation, 2>
5157 my_orientations{{ref_cell.face_to_cell_line_orientation(
5158 0,
5159 f,
5160 orientation,
5161 quad->line_orientation(my_indices[0])),
5162 ref_cell.face_to_cell_line_orientation(
5163 1,
5164 f,
5165 orientation,
5166 quad->line_orientation(my_indices[1]))}};
5167 line_orientations[8 + f] = my_orientations[0];
5168 line_orientations[10 + f] = my_orientations[1];
5169 }
5170 }
5171 else if (ref_cell == ReferenceCells::Tetrahedron)
5172 {
5173 std::array<unsigned int, 3> orientations{
5176 cell.combined_face_orientation(2)}};
5177 const std::array<unsigned int, 6> my_indices{
5178 {ref_cell.standard_to_real_face_line(0, 0, orientations[0]),
5179 ref_cell.standard_to_real_face_line(1, 0, orientations[0]),
5180 ref_cell.standard_to_real_face_line(2, 0, orientations[0]),
5181 ref_cell.standard_to_real_face_line(1, 1, orientations[1]),
5182 ref_cell.standard_to_real_face_line(2, 1, orientations[1]),
5183 ref_cell.standard_to_real_face_line(1, 2, orientations[2])}};
5184 line_orientations[0] = ref_cell.face_to_cell_line_orientation(
5185 0,
5186 0,
5187 orientations[0],
5188 cell.quad(0)->line_orientation(my_indices[0]));
5189 line_orientations[1] = ref_cell.face_to_cell_line_orientation(
5190 1,
5191 0,
5192 orientations[0],
5193 cell.quad(0)->line_orientation(my_indices[1]));
5194 line_orientations[2] = ref_cell.face_to_cell_line_orientation(
5195 2,
5196 0,
5197 orientations[0],
5198 cell.quad(0)->line_orientation(my_indices[2]));
5199 line_orientations[3] = ref_cell.face_to_cell_line_orientation(
5200 1,
5201 1,
5202 orientations[1],
5203 cell.quad(1)->line_orientation(my_indices[3]));
5204 line_orientations[4] = ref_cell.face_to_cell_line_orientation(
5205 2,
5206 1,
5207 orientations[1],
5208 cell.quad(1)->line_orientation(my_indices[4]));
5209 line_orientations[5] = ref_cell.face_to_cell_line_orientation(
5210 1,
5211 2,
5212 orientations[2],
5213 cell.quad(2)->line_orientation(my_indices[5]));
5214 }
5215 else
5216 // For other shapes (wedges, pyramids), we do not currently
5217 // implement an optimized function
5218 for (unsigned int l = 0; l < std::min(12U, cell.n_lines()); ++l)
5219 line_orientations[l] = cell.line_orientation(l);
5220
5221 return line_orientations;
5222 }
5223 };
5224 } // namespace TriaAccessorImplementation
5225} // namespace internal
5226
5227
5228
5229template <int structdim, int dim, int spacedim>
5231 const Triangulation<dim, spacedim> *parent,
5232 const int level,
5233 const int index,
5234 const AccessorData *local_data)
5235 : TriaAccessorBase<structdim, dim, spacedim>(parent, level, index, local_data)
5236{}
5237
5238
5239
5240template <int structdim, int dim, int spacedim>
5241inline bool
5243{
5244 Assert(this->state() == IteratorState::valid,
5246 *this));
5247 return this->objects().used[this->present_index];
5248}
5249
5250
5251
5252template <int structdim, int dim, int spacedim>
5255 const unsigned int i) const
5256{
5258 0,
5259 vertex_index(i));
5260}
5261
5262
5263
5264template <int structdim, int dim, int spacedim>
5265inline ReferenceCell
5267{
5268 if (structdim == 0)
5270 else if (structdim == 1)
5271 return ReferenceCells::Line;
5272 else if (structdim == dim)
5273 return this->tria->levels[this->present_level]
5274 ->reference_cell[this->present_index];
5275 else
5276 return this->tria->faces->get_quad_type(this->present_index);
5277}
5278
5279
5280
5281template <int structdim, int dim, int spacedim>
5282inline unsigned int
5284 const unsigned int corner) const
5285{
5286 AssertIndexRange(corner, this->n_vertices());
5287
5288 if constexpr (structdim == 1)
5289 {
5290 // This branch needs to be first (and not combined with the structdim ==
5291 // dim branch) so that we can get line vertex indices when setting up the
5292 // cell vertex index cache
5293 return this->objects()
5294 .cells[this->present_index * ReferenceCells::max_n_faces<1>() + corner];
5295 }
5296 else if constexpr (structdim == dim)
5297 {
5298 // This branch should only be used after the cell vertex index cache is
5299 // set up
5300 const auto my_index = static_cast<std::size_t>(this->present_index) *
5302 AssertIndexRange(my_index + corner,
5303 this->tria->levels[this->present_level]
5304 ->cell_vertex_indices_cache.size());
5305 const unsigned int vertex_index =
5306 this->tria->levels[this->present_level]
5307 ->cell_vertex_indices_cache[my_index + corner];
5309 return vertex_index;
5310 }
5311 else if constexpr (structdim == 2)
5312 {
5313 const auto [line_index, vertex_index] =
5314 this->reference_cell().standard_vertex_to_face_and_vertex_index(corner);
5315 const auto vertex_within_line_index =
5316 this->reference_cell().standard_to_real_face_vertex(
5317 vertex_index, line_index, this->line_orientation(line_index));
5318
5319 return this->line(line_index)->vertex_index(vertex_within_line_index);
5320 }
5321 else
5322 {
5325 }
5326}
5327
5328
5329
5330template <int structdim, int dim, int spacedim>
5331inline Point<spacedim> &
5332TriaAccessor<structdim, dim, spacedim>::vertex(const unsigned int i) const
5333{
5334 return const_cast<Point<spacedim> &>(this->tria->vertices[vertex_index(i)]);
5335}
5336
5337
5338
5339template <int structdim, int dim, int spacedim>
5340inline typename ::internal::TriangulationImplementation::
5341 Iterators<dim, spacedim>::line_iterator
5342 TriaAccessor<structdim, dim, spacedim>::line(const unsigned int i) const
5343{
5344 // checks happen in line_index
5345 return typename ::internal::TriangulationImplementation::
5346 Iterators<dim, spacedim>::line_iterator(this->tria, 0, line_index(i));
5347}
5348
5349
5350
5351template <int structdim, int dim, int spacedim>
5352inline unsigned int
5354{
5355 (void)i;
5356 AssertIndexRange(i, this->n_lines());
5357 Assert(structdim != 1,
5358 ExcMessage("You can't ask for the index of a line bounding a "
5359 "one-dimensional cell because it is not bounded by "
5360 "lines."));
5361
5362 if constexpr (structdim == 2)
5363 {
5364 return this->objects()
5365 .cells[this->present_index * ReferenceCells::max_n_faces<2>() + i];
5366 }
5367 else if constexpr (structdim == 3)
5368 {
5369 const auto [face_index, line_index] =
5370 this->reference_cell().standard_line_to_face_and_line_index(i);
5371 const auto line_within_face_index =
5372 this->reference_cell().standard_to_real_face_line(
5373 line_index, face_index, this->combined_face_orientation(face_index));
5374
5375 return this->quad(face_index)->line_index(line_within_face_index);
5376 }
5377
5380}
5381
5382
5383
5384template <int structdim, int dim, int spacedim>
5385inline typename ::internal::TriangulationImplementation::
5386 Iterators<dim, spacedim>::quad_iterator
5387 TriaAccessor<structdim, dim, spacedim>::quad(const unsigned int i) const
5388{
5389 // checks happen in quad_index
5390 return typename ::internal::TriangulationImplementation::
5391 Iterators<dim, spacedim>::quad_iterator(this->tria, 0, quad_index(i));
5392}
5393
5394
5395
5396template <int structdim, int dim, int spacedim>
5397inline unsigned int
5399{
5400 Assert(structdim == 3,
5401 ExcMessage("You can't ask for the index of a quad bounding "
5402 "a one- or two-dimensional cell because it is not "
5403 "bounded by quads."));
5404 // work around a bogus GCC-9 warning which considers i unused except in 3d
5405 (void)i;
5406 if constexpr (structdim == 3)
5407 {
5408 AssertIndexRange(i, n_faces());
5409 return this->tria->levels[this->present_level]
5410 ->cells
5411 .cells[this->present_index * ReferenceCells::max_n_faces<3>() + i];
5412 }
5413 else
5415}
5416
5417
5418
5419template <int structdim, int dim, int spacedim>
5422 const unsigned int face) const
5423{
5425 AssertIndexRange(face, n_faces());
5426 Assert(structdim == dim,
5427 ExcMessage("This function can only be used on objects "
5428 "that are cells, but not on faces or edges "
5429 "that bound cells."));
5430 // work around a bogus GCC-9 warning which considers face unused except in 3d
5431 (void)face;
5432
5433 if constexpr (structdim == 1)
5435 else if constexpr (structdim == 2)
5436 {
5437 // if all elements are quads (or if we have a very special consistently
5438 // oriented triangular mesh) then we do not store this array
5439 if (this->tria->levels[this->present_level]
5440 ->face_orientations.n_objects() == 0)
5442 else
5443 return this->tria->levels[this->present_level]
5444 ->face_orientations.get_combined_orientation(
5445 this->present_index * ReferenceCells::max_n_faces<dim>() + face);
5446 }
5447 else
5448 return this->tria->levels[this->present_level]
5449 ->face_orientations.get_combined_orientation(
5450 this->present_index * ReferenceCells::max_n_faces<dim>() + face);
5451}
5452
5453
5454
5455template <int structdim, int dim, int spacedim>
5456inline bool
5458 const unsigned int face) const
5459{
5461 AssertIndexRange(face, n_faces());
5462 Assert(structdim == dim,
5463 ExcMessage("This function can only be used on objects "
5464 "that are cells, but not on faces or edges "
5465 "that bound cells."));
5466 // work around a bogus GCC-9 warning which considers face unused in 1d
5467 (void)face;
5468
5469 if constexpr (structdim == 1)
5470 // in 1d 'faces' are vertices and those are always consistently oriented
5471 return true;
5472 else if constexpr (structdim == 2)
5473 return this->line_orientation(face) ==
5475 else
5476 return this->tria->levels[this->present_level]
5477 ->face_orientations.get_orientation(
5478 this->present_index * ReferenceCells::max_n_faces<structdim>() + face);
5479}
5480
5481
5482
5483template <int structdim, int dim, int spacedim>
5484inline bool
5485TriaAccessor<structdim, dim, spacedim>::face_flip(const unsigned int face) const
5486{
5488 Assert(structdim == dim,
5489 ExcMessage("This function can only be used on objects "
5490 "that are cells, but not on faces or edges "
5491 "that bound cells."));
5492 AssertIndexRange(face, n_faces());
5493 // work around a bogus GCC-9 warning which considers face unused except in 3d
5494 (void)face;
5495
5496 if constexpr (structdim == 3)
5497 return this->tria->levels[this->present_level]->face_orientations.get_flip(
5498 this->present_index * ReferenceCells::max_n_faces<structdim>() + face);
5499 else
5500 // In 1d and 2d, face_flip is always false as faces can only be
5501 // 'flipped' in 3d.
5502 return false;
5503}
5504
5505
5506template <int structdim, int dim, int spacedim>
5507inline bool
5509 const unsigned int face) const
5510{
5512 Assert(structdim == dim,
5513 ExcMessage("This function can only be used on objects "
5514 "that are cells, but not on faces or edges "
5515 "that bound cells."));
5516 AssertIndexRange(face, n_faces());
5517 // work around a bogus GCC-9 warning which considers face unused except in 3d
5518 (void)face;
5519
5520 if constexpr (structdim == 3)
5521 return this->tria->levels[this->present_level]
5522 ->face_orientations.get_rotation(
5523 this->present_index * ReferenceCells::max_n_faces<structdim>() + face);
5524 else
5525 // In 1d and 2d, face_rotation is always false as faces can only be
5526 // 'rotated' in 3d.
5527 return false;
5528}
5529
5530
5531
5532template <int structdim, int dim, int spacedim>
5535 const unsigned int line) const
5536{
5538 AssertIndexRange(line, this->n_lines());
5539 // work around a bogus GCC-9 warning which considers line unused in 1d
5540 (void)line;
5541
5542 if constexpr (structdim == 1)
5544 else if constexpr (structdim == 2 && dim == 2)
5545 // lines in 2d are faces
5546 {
5547 const auto combined_orientation = combined_face_orientation(line);
5548 Assert(combined_orientation == numbers::default_geometric_orientation ||
5549 combined_orientation == numbers::reverse_line_orientation,
5551 return combined_orientation;
5552 }
5553 else if constexpr (structdim == 2 && dim == 3)
5554 {
5555 // line orientations in 3d are stored in their own array as bools: here
5556 // 'true' is the default orientation and 'false' is the reversed one
5557 // (which matches set_line_orientation())
5558 const auto index =
5559 this->present_index * ReferenceCells::max_n_lines<2>() + line;
5560 Assert(index < this->tria->faces->quads_line_orientations.size(),
5562 return this->tria->faces->quads_line_orientations[index] ?
5565 }
5566 else if constexpr (structdim == 3 && dim == 3)
5567 {
5568 const auto reference_cell = this->reference_cell();
5569 // First pick a face on which this line is a part of, and the
5570 // index of the line within.
5571 const auto [face_index, line_index] =
5572 reference_cell.standard_line_to_face_and_line_index(line);
5573 const auto line_within_face_index =
5574 reference_cell.standard_to_real_face_line(
5575 line_index, face_index, this->combined_face_orientation(face_index));
5576
5577 // Then query how that line is oriented within that face:
5578 return reference_cell.face_to_cell_line_orientation(
5579 line_index,
5580 face_index,
5581 this->combined_face_orientation(face_index),
5582 this->quad(face_index)->line_orientation(line_within_face_index));
5583 }
5584 else
5585 {
5587 return false;
5588 }
5589}
5590
5591
5592
5593template <int structdim, int dim, int spacedim>
5594inline void
5596 const unsigned int line,
5598{
5600 AssertIndexRange(line, this->n_lines());
5601 Assert(dim != 1,
5602 ExcMessage("In 1d lines are cells and thus do not need to have their "
5603 "orientations set."));
5604 Assert(dim != 2,
5605 ExcMessage("In 2d lines are faces, and, for compatibility with other "
5606 "dimensions, their orientations should be set via "
5607 "set_combined_face_orientation()."));
5608 // work around a bogus GCC-9 warning which considers line and value unused
5609 // except in 3d
5610 (void)line;
5611 (void)value;
5612
5613 if constexpr (dim == 3)
5614 {
5615 // We set line orientations per face, not per cell, so this only works for
5616 // faces in 3d.
5617 Assert(structdim == 2, ExcNotImplemented());
5618 const auto index =
5619 this->present_index * ReferenceCells::max_n_lines<2>() + line;
5620 Assert(index < this->tria->faces->quads_line_orientations.size(),
5622 this->tria->faces->quads_line_orientations[index] =
5624 }
5625}
5626
5627
5628
5629template <int structdim, int dim, int spacedim>
5630inline void
5632 const unsigned int face,
5633 const types::geometric_orientation combined_orientation) const
5634{
5636 AssertIndexRange(face, this->n_faces());
5637
5638 ::internal::TriaAccessorImplementation::Implementation::
5639 set_combined_face_orientation(*this, face, combined_orientation);
5640}
5641
5642
5643
5644template <int structdim, int dim, int spacedim>
5645void
5647{
5648 Assert(this->state() == IteratorState::valid,
5650 *this));
5651 this->objects().used[this->present_index] = true;
5652}
5653
5654
5655
5656template <int structdim, int dim, int spacedim>
5657void
5659{
5660 Assert(this->state() == IteratorState::valid,
5662 *this));
5663 this->objects().used[this->present_index] = false;
5664}
5665
5666
5667template <int structdim, int dim, int spacedim>
5668int
5670{
5672 AssertIndexRange(i, n_children());
5673
5674 // each set of two children are stored
5675 // consecutively, so we only have to find
5676 // the location of the set of children
5677 const unsigned int n_sets_of_two =
5679 return this->objects().children[n_sets_of_two * this->present_index + i / 2] +
5680 i % 2;
5681}
5682
5683
5684
5685template <int structdim, int dim, int spacedim>
5686int
5688 const unsigned int i) const
5689{
5691
5692 switch (structdim)
5693 {
5694 case 1:
5695 return child_index(i);
5696 case 2:
5697 {
5698 const RefinementCase<2> this_refinement_case(
5699 static_cast<std::uint8_t>(refinement_case()));
5700
5701 Assert(this_refinement_case != RefinementCase<2>::no_refinement,
5703
5704 if (this_refinement_case == RefinementCase<2>::cut_xy)
5705 return child_index(i);
5706 else if ((this_refinement_case == RefinementCase<2>::cut_x) &&
5707 (child(i % 2)->refinement_case() ==
5709 return child(i % 2)->child_index(i / 2);
5710 else if ((this_refinement_case == RefinementCase<2>::cut_y) &&
5711 (child(i / 2)->refinement_case() ==
5713 return child(i / 2)->child_index(i % 2);
5714 else
5715 Assert(
5716 false,
5717 ExcMessage(
5718 "This cell has no grandchildren equivalent to isotropic refinement"));
5719 break;
5720 }
5721
5722 case 3:
5724 }
5725 return -1;
5726}
5727
5728
5729
5730template <int structdim, int dim, int spacedim>
5733{
5734 Assert(this->state() == IteratorState::valid,
5736 *this));
5737
5738 switch (structdim)
5739 {
5740 case 1:
5742 this->objects().children[this->present_index] != -1 ?
5743 // cast the branches
5744 // here first to uchar
5745 // and then (above) to
5746 // RefinementCase<structdim>
5747 // so that the
5748 // conversion is valid
5749 // even for the case
5750 // structdim>1 (for
5751 // which this part of
5752 // the code is dead
5753 // anyway)
5754 static_cast<std::uint8_t>(RefinementCase<1>::cut_x) :
5755 static_cast<std::uint8_t>(RefinementCase<1>::no_refinement)));
5756
5757 default:
5758 Assert(static_cast<unsigned int>(this->present_index) <
5759 this->objects().refinement_cases.size(),
5760 ExcIndexRange(this->present_index,
5761 0,
5762 this->objects().refinement_cases.size()));
5763
5764 return (static_cast<RefinementCase<structdim>>(
5765 this->objects().refinement_cases[this->present_index]));
5766 }
5767}
5768
5769
5770
5771template <int structdim, int dim, int spacedim>
5773TriaAccessor<structdim, dim, spacedim>::child(const unsigned int i) const
5774
5775{
5776 // checking of 'i' happens in child_index
5778 this->tria, (dim == structdim ? this->level() + 1 : 0), child_index(i));
5779
5780 Assert((q.state() == IteratorState::past_the_end) || q->used(),
5782
5783 return q;
5784}
5785
5786
5787
5788template <int structdim, int dim, int spacedim>
5789inline unsigned int
5792{
5793 const auto n_children = this->n_children();
5794 for (unsigned int child_n = 0; child_n < n_children; ++child_n)
5795 if (this->child(child_n) == child)
5796 return child_n;
5797
5798 Assert(false,
5799 ExcMessage("The given child is not a child of the current object."));
5801}
5802
5803
5804
5805template <int structdim, int dim, int spacedim>
5808 const unsigned int i) const
5809{
5810 // checking of 'i' happens in child() or
5811 // child_index() called below
5812 switch (structdim)
5813 {
5814 case 1:
5815 // no anisotropic refinement in 1d
5816 return child(i);
5817
5818 case 2:
5819 {
5820 const RefinementCase<2> this_refinement_case(
5821 static_cast<std::uint8_t>(refinement_case()));
5822
5823 Assert(this_refinement_case != RefinementCase<2>::no_refinement,
5825
5826 if (this_refinement_case == RefinementCase<2>::cut_xy)
5827 return child(i);
5828 else if ((this_refinement_case == RefinementCase<2>::cut_x) &&
5829 (child(i % 2)->refinement_case() ==
5831 return child(i % 2)->child(i / 2);
5832 else if ((this_refinement_case == RefinementCase<2>::cut_y) &&
5833 (child(i / 2)->refinement_case() ==
5835 return child(i / 2)->child(i % 2);
5836 else
5837 Assert(
5838 false,
5839 ExcMessage(
5840 "This cell has no grandchildren equivalent to isotropic refinement"));
5841 break;
5842 }
5843
5844 default:
5846 }
5847 // we don't get here but have to return
5848 // something...
5849 return child(0);
5850}
5851
5852
5853
5854template <int structdim, int dim, int spacedim>
5855inline bool
5857{
5858 Assert(this->state() == IteratorState::valid,
5860 *this));
5861
5862 // each set of two children are stored
5863 // consecutively, so we only have to find
5864 // the location of the set of children
5865 const unsigned int n_sets_of_two =
5867 return (this->objects().children[n_sets_of_two * this->present_index] != -1);
5868}
5869
5870
5871
5872template <int structdim, int dim, int spacedim>
5873inline unsigned int
5875{
5876 Assert(this->state() == IteratorState::valid,
5878 *this));
5882 else
5883 return GeometryInfo<structdim>::n_children(refinement_case());
5884}
5885
5886
5887
5888template <int structdim, int dim, int spacedim>
5889inline void
5891 const RefinementCase<structdim> &refinement_case) const
5892{
5893 Assert(this->state() == IteratorState::valid,
5895 *this));
5896 Assert(static_cast<unsigned int>(this->present_index) <
5897 this->objects().refinement_cases.size(),
5898 ExcIndexRange(this->present_index,
5899 0,
5900 this->objects().refinement_cases.size()));
5901
5902 this->objects().refinement_cases[this->present_index] = refinement_case;
5903}
5904
5905
5906template <int structdim, int dim, int spacedim>
5907inline void
5909{
5910 Assert(this->state() == IteratorState::valid,
5912 *this));
5913 Assert(static_cast<unsigned int>(this->present_index) <
5914 this->objects().refinement_cases.size(),
5915 ExcIndexRange(this->present_index,
5916 0,
5917 this->objects().refinement_cases.size()));
5918
5919 this->objects().refinement_cases[this->present_index] =
5921}
5922
5923
5924
5925template <int structdim, int dim, int spacedim>
5926void
5928 const int index) const
5929{
5932
5933 // each set of two children are stored
5934 // consecutively, so we only have to find
5935 // the location of the set of children
5936 const unsigned int n_sets_of_two =
5938
5939 Assert(
5940 // clearing the child index for a cell
5941 (index == -1) ||
5942 // if setting the child index for the i'th child (with i==0),
5943 // then the index must be a non-negative number
5944 (i == 0 && !this->has_children() && (index >= 0)) ||
5945 // if setting the child index for the i'th child (with i>0),
5946 // then the previously stored index must be the invalid
5947 // index
5948 (i > 0 && this->has_children() && (index >= 0) &&
5949 this->objects().children[n_sets_of_two * this->present_index + i / 2] ==
5950 -1),
5952
5953 this->objects().children[n_sets_of_two * this->present_index + i / 2] = index;
5954}
5955
5956
5957
5958template <int structdim, int dim, int spacedim>
5959void
5961{
5962 // each set of two children are stored
5963 // consecutively, so we only have to find
5964 // the location of the set of children
5965 const unsigned int n_sets_of_two =
5967
5968 for (unsigned int i = 0; i < n_sets_of_two; ++i)
5969 set_children(2 * i, -1);
5970}
5971
5972
5973
5974template <int structdim, int dim, int spacedim>
5975inline bool
5977{
5979 return this->objects().user_flags[this->present_index];
5980}
5981
5982
5983
5984template <int structdim, int dim, int spacedim>
5985inline void
5987{
5989 this->objects().user_flags[this->present_index] = true;
5990}
5991
5992
5993
5994template <int structdim, int dim, int spacedim>
5995inline void
5997{
5999 this->objects().user_flags[this->present_index] = false;
6000}
6001
6002
6003
6004template <int structdim, int dim, int spacedim>
6005void
6007{
6008 set_user_flag();
6009
6010 if (this->has_children())
6011 for (unsigned int c = 0; c < this->n_children(); ++c)
6012 this->child(c)->recursively_set_user_flag();
6013}
6014
6015
6016
6017template <int structdim, int dim, int spacedim>
6018void
6020{
6021 clear_user_flag();
6022
6023 if (this->has_children())
6024 for (unsigned int c = 0; c < this->n_children(); ++c)
6025 this->child(c)->recursively_clear_user_flag();
6026}
6027
6028
6029
6030template <int structdim, int dim, int spacedim>
6031void
6033{
6035 this->objects().clear_user_data(this->present_index);
6036}
6037
6038
6039
6040template <int structdim, int dim, int spacedim>
6041void
6043{
6045 this->objects().user_pointer(this->present_index) = p;
6046}
6047
6048
6049
6050template <int structdim, int dim, int spacedim>
6051void
6053{
6055 this->objects().user_pointer(this->present_index) = nullptr;
6056}
6057
6058
6059
6060template <int structdim, int dim, int spacedim>
6061void *
6063{
6065 return this->objects().user_pointer(this->present_index);
6066}
6067
6068
6069
6070template <int structdim, int dim, int spacedim>
6071void
6073 void *p) const
6074{
6075 set_user_pointer(p);
6076
6077 if (this->has_children())
6078 for (unsigned int c = 0; c < this->n_children(); ++c)
6079 this->child(c)->recursively_set_user_pointer(p);
6080}
6081
6082
6083
6084template <int structdim, int dim, int spacedim>
6085void
6087{
6088 clear_user_pointer();
6089
6090 if (this->has_children())
6091 for (unsigned int c = 0; c < this->n_children(); ++c)
6092 this->child(c)->recursively_clear_user_pointer();
6093}
6094
6095
6096
6097template <int structdim, int dim, int spacedim>
6098void
6100 const unsigned int p) const
6101{
6103 this->objects().user_index(this->present_index) = p;
6104}
6105
6106
6107
6108template <int structdim, int dim, int spacedim>
6109void
6111{
6113 this->objects().user_index(this->present_index) = 0;
6114}
6115
6116
6117
6118template <int structdim, int dim, int spacedim>
6119unsigned int
6121{
6123 return this->objects().user_index(this->present_index);
6124}
6125
6126
6127
6128template <int structdim, int dim, int spacedim>
6129void
6131 const unsigned int p) const
6132{
6133 set_user_index(p);
6134
6135 if (this->has_children())
6136 for (unsigned int c = 0; c < this->n_children(); ++c)
6137 this->child(c)->recursively_set_user_index(p);
6138}
6139
6140
6141
6142template <int structdim, int dim, int spacedim>
6143void
6145{
6146 clear_user_index();
6147
6148 if (this->has_children())
6149 for (unsigned int c = 0; c < this->n_children(); ++c)
6150 this->child(c)->recursively_clear_user_index();
6151}
6152
6153
6154
6155template <int structdim, int dim, int spacedim>
6156inline unsigned int
6158{
6159 if (!this->has_children())
6160 return 0;
6161
6162 unsigned int max_depth = 1;
6163 for (unsigned int c = 0; c < n_children(); ++c)
6164 max_depth = std::max(max_depth, child(c)->max_refinement_depth() + 1);
6165 return max_depth;
6166}
6167
6168
6169
6170template <int structdim, int dim, int spacedim>
6171unsigned int
6173{
6174 if (!this->has_children())
6175 return 1;
6176 else
6177 {
6178 unsigned int sum = 0;
6179 for (unsigned int c = 0; c < n_children(); ++c)
6180 sum += this->child(c)->n_active_descendants();
6181 return sum;
6182 }
6183}
6184
6185
6186
6187template <int structdim, int dim, int spacedim>
6190{
6191 Assert(structdim < dim, ExcImpossibleInDim(dim));
6193
6194 return this->objects()
6195 .boundary_or_material_id[this->present_index]
6196 .boundary_id;
6197}
6198
6199
6200
6201template <int structdim, int dim, int spacedim>
6202void
6204 const types::boundary_id boundary_ind) const
6205{
6206 Assert(structdim < dim, ExcImpossibleInDim(dim));
6209 ExcMessage("You are trying to set the boundary_id to an invalid "
6210 "value (numbers::internal_face_boundary_id is reserved)."));
6211 Assert(this->at_boundary(),
6212 ExcMessage("You are trying to set the boundary_id of an "
6213 "internal object, which is not allowed!"));
6214
6215 this->objects().boundary_or_material_id[this->present_index].boundary_id =
6216 boundary_ind;
6217}
6218
6219
6220
6221template <int structdim, int dim, int spacedim>
6222void
6224 const types::boundary_id boundary_ind) const
6225{
6226 Assert(structdim < dim, ExcImpossibleInDim(dim));
6228
6229 this->objects().boundary_or_material_id[this->present_index].boundary_id =
6230 boundary_ind;
6231}
6232
6233
6234
6235template <int structdim, int dim, int spacedim>
6236void
6238 const types::boundary_id boundary_ind) const
6239{
6240 set_boundary_id(boundary_ind);
6241
6242 switch (structdim)
6243 {
6244 case 1:
6245 // 1d objects have no sub-objects
6246 // where we have to do anything
6247 break;
6248
6249 case 2:
6250 // for boundary quads also set
6251 // boundary_id of bounding lines
6252 for (unsigned int i = 0; i < this->n_lines(); ++i)
6253 this->line(i)->set_boundary_id(boundary_ind);
6254 break;
6255
6256 default:
6258 }
6259}
6260
6261
6262
6263template <int structdim, int dim, int spacedim>
6264bool
6266{
6267 // error checking is done
6268 // in boundary_id()
6270}
6271
6272
6273
6274template <int structdim, int dim, int spacedim>
6277{
6279 return this->tria->get_manifold(this->manifold_id());
6280}
6281
6282
6283template <int structdim, int dim, int spacedim>
6286{
6288
6289 return this->objects().manifold_id[this->present_index];
6290}
6291
6292
6293
6294template <int structdim, int dim, int spacedim>
6295void
6297 const types::manifold_id manifold_ind) const
6298{
6300
6301 this->objects().manifold_id[this->present_index] = manifold_ind;
6302}
6303
6304
6305template <int structdim, int dim, int spacedim>
6306void
6308 const types::manifold_id manifold_ind) const
6309{
6310 set_manifold_id(manifold_ind);
6311
6312 if (this->has_children())
6313 for (unsigned int c = 0; c < this->n_children(); ++c)
6314 this->child(c)->set_all_manifold_ids(manifold_ind);
6315
6316 switch (structdim)
6317 {
6318 case 1:
6319 if (dim == 1)
6320 {
6321 (*this->tria->vertex_to_manifold_id_map_1d)[vertex_index(0)] =
6322 manifold_ind;
6323 (*this->tria->vertex_to_manifold_id_map_1d)[vertex_index(1)] =
6324 manifold_ind;
6325 }
6326 break;
6327
6328 case 2:
6329 // for quads/simplices also set manifold_id of bounding lines
6330 for (unsigned int i = 0; i < this->n_lines(); ++i)
6331 this->line(i)->set_manifold_id(manifold_ind);
6332 break;
6333 default:
6335 }
6336}
6337
6338
6339
6340template <int structdim, int dim, int spacedim>
6341double
6343{
6344 boost::container::small_vector<Point<spacedim>,
6345# ifndef _MSC_VER
6347# else
6349# endif
6350 >
6351 vertices(this->n_vertices());
6352
6353 for (unsigned int v = 0; v < vertices.size(); ++v)
6354 vertices[v] = this->vertex(v);
6355
6356 return internal::TriaAccessorImplementation::diameter<structdim, spacedim>(
6357 vertices);
6358}
6359
6360
6361
6362template <int dim, int spacedim>
6363double
6365 const Mapping<dim, spacedim> &mapping) const
6366{
6367 return internal::TriaAccessorImplementation::diameter<dim, spacedim>(
6369 this->tria, this->level(), this->index())));
6370}
6371
6372
6373
6374template <int structdim, int dim, int spacedim>
6375std::pair<Point<spacedim>, double>
6377{
6378 // If the object is one dimensional,
6379 // the enclosing ball is the initial iterate
6380 // i.e., the ball's center and diameter are
6381 // the center and the diameter of the object.
6382 if (structdim == 1)
6383 return std::make_pair((this->vertex(1) + this->vertex(0)) * 0.5,
6384 (this->vertex(1) - this->vertex(0)).norm() * 0.5);
6385
6386 // The list is_initial_guess_vertex contains bool values and has
6387 // the same size as the number of vertices per object.
6388 // The entries of is_initial_guess_vertex are set true only for those
6389 // two vertices corresponding to the largest diagonal which is being used
6390 // to construct the initial ball.
6391 // We employ this mask to skip these two vertices while enlarging the ball.
6392 std::vector<bool> is_initial_guess_vertex(this->n_vertices());
6393
6394 // First let all the vertices be outside
6395 std::fill(is_initial_guess_vertex.begin(),
6396 is_initial_guess_vertex.end(),
6397 false);
6398
6399 // Get an initial guess by looking at the largest diagonal
6400 Point<spacedim> center;
6401 double radius = 0;
6402
6403 switch (structdim)
6404 {
6405 case 2:
6406 {
6407 const Point<spacedim> p30(this->vertex(3) - this->vertex(0));
6408 const Point<spacedim> p21(this->vertex(2) - this->vertex(1));
6409 if (p30.norm() > p21.norm())
6410 {
6411 center = this->vertex(0) + 0.5 * p30;
6412 radius = p30.norm() / 2.;
6413 is_initial_guess_vertex[3] = true;
6414 is_initial_guess_vertex[0] = true;
6415 }
6416 else
6417 {
6418 center = this->vertex(1) + 0.5 * p21;
6419 radius = p21.norm() / 2.;
6420 is_initial_guess_vertex[2] = true;
6421 is_initial_guess_vertex[1] = true;
6422 }
6423 break;
6424 }
6425 case 3:
6426 {
6427 const Point<spacedim> p70(this->vertex(7) - this->vertex(0));
6428 const Point<spacedim> p61(this->vertex(6) - this->vertex(1));
6429 const Point<spacedim> p25(this->vertex(2) - this->vertex(5));
6430 const Point<spacedim> p34(this->vertex(3) - this->vertex(4));
6431 const std::vector<double> diagonals = {p70.norm(),
6432 p61.norm(),
6433 p25.norm(),
6434 p34.norm()};
6435 const std::vector<double>::const_iterator it =
6436 std::max_element(diagonals.begin(), diagonals.end());
6437 if (it == diagonals.begin())
6438 {
6439 center = this->vertex(0) + 0.5 * p70;
6440 is_initial_guess_vertex[7] = true;
6441 is_initial_guess_vertex[0] = true;
6442 }
6443 else if (it == diagonals.begin() + 1)
6444 {
6445 center = this->vertex(1) + 0.5 * p61;
6446 is_initial_guess_vertex[6] = true;
6447 is_initial_guess_vertex[1] = true;
6448 }
6449 else if (it == diagonals.begin() + 2)
6450 {
6451 center = this->vertex(5) + 0.5 * p25;
6452 is_initial_guess_vertex[2] = true;
6453 is_initial_guess_vertex[5] = true;
6454 }
6455 else
6456 {
6457 center = this->vertex(4) + 0.5 * p34;
6458 is_initial_guess_vertex[3] = true;
6459 is_initial_guess_vertex[4] = true;
6460 }
6461 radius = *it * 0.5;
6462 break;
6463 }
6464 default:
6466 return std::pair<Point<spacedim>, double>();
6467 }
6468
6469 // For each vertex that is found to be geometrically outside the ball
6470 // enlarge the ball so that the new ball contains both the previous ball
6471 // and the given vertex.
6472 for (const unsigned int v : this->vertex_indices())
6473 if (!is_initial_guess_vertex[v])
6474 {
6475 const double distance = center.distance(this->vertex(v));
6476 if (distance > radius)
6477 {
6478 // we found a vertex which is outside of the ball
6479 // extend it (move center and change radius)
6480 const Point<spacedim> pCV(center - this->vertex(v));
6481 radius = (distance + radius) * 0.5;
6482 center = this->vertex(v) + pCV * (radius / distance);
6483
6484 // Now the new ball constructed in this block
6485 // encloses the vertex (v) that was found to be geometrically
6486 // outside the old ball.
6487 }
6488 }
6489 if constexpr (running_in_debug_mode())
6490 {
6491 bool all_vertices_within_ball = true;
6492
6493 // Set all_vertices_within_ball false if any of the vertices of the object
6494 // are geometrically outside the ball
6495 for (const unsigned int v : this->vertex_indices())
6496 if (center.distance(this->vertex(v)) >
6497 radius + 100. * std::numeric_limits<double>::epsilon())
6498 {
6499 all_vertices_within_ball = false;
6500 break;
6501 }
6502 // If all the vertices are not within the ball throw error
6503 Assert(all_vertices_within_ball, ExcInternalError());
6504 }
6505 return std::make_pair(center, radius);
6506}
6507
6508
6509template <int structdim, int dim, int spacedim>
6510double
6512{
6513 switch (structdim)
6514 {
6515 case 1:
6516 return (this->vertex(1) - this->vertex(0)).norm();
6517 case 2:
6518 case 3:
6519 {
6520 double min = std::numeric_limits<double>::max();
6521 for (const unsigned int i : this->vertex_indices())
6522 for (unsigned int j = i + 1; j < this->n_vertices(); ++j)
6523 min = std::min(min,
6524 (this->vertex(i) - this->vertex(j)) *
6525 (this->vertex(i) - this->vertex(j)));
6526 return std::sqrt(min);
6527 }
6528 default:
6530 return -1e10;
6531 }
6532}
6533
6534
6535template <int structdim, int dim, int spacedim>
6536bool
6539{
6540 // go through the vertices and check... The
6541 // cell is a translation of the previous
6542 // one in case the distance between the
6543 // individual vertices in the two cell is
6544 // the same for all the vertices. So do the
6545 // check by first getting the distance on
6546 // the first vertex, and then checking
6547 // whether all others have the same down to
6548 // rounding errors (we have to be careful
6549 // here because the calculation of the
6550 // displacement between one cell and the
6551 // next can already result in the loss of
6552 // one or two digits), so we choose 1e-12
6553 // times the distance between the zeroth
6554 // vertices here.
6555 bool is_translation = true;
6556 const Tensor<1, spacedim> dist = o->vertex(0) - this->vertex(0);
6557 const double tol_square = 1e-24 * dist.norm_square();
6558 for (unsigned int i = 1; i < this->n_vertices(); ++i)
6559 {
6560 const Tensor<1, spacedim> dist_new =
6561 (o->vertex(i) - this->vertex(i)) - dist;
6562 if (dist_new.norm_square() > tol_square)
6563 {
6564 is_translation = false;
6565 break;
6566 }
6567 }
6568 return is_translation;
6569}
6570
6571
6572
6573template <int structdim, int dim, int spacedim>
6574unsigned int
6576{
6577 return this->reference_cell().n_vertices();
6578}
6579
6580
6581
6582template <int structdim, int dim, int spacedim>
6583unsigned int
6585{
6586 return this->reference_cell().n_lines();
6587}
6588
6589
6590
6591template <int structdim, int dim, int spacedim>
6592unsigned int
6594{
6595 Assert(structdim == dim,
6596 ExcMessage("This function can only be used on objects "
6597 "that are cells, but not on faces or edges "
6598 "that bound cells."));
6599
6600 return this->reference_cell().n_faces();
6601}
6602
6603
6604
6605template <int structdim, int dim, int spacedim>
6608{
6610 n_vertices());
6611}
6612
6613
6614
6615template <int structdim, int dim, int spacedim>
6618{
6620 n_lines());
6621}
6622
6623
6624
6625template <int structdim, int dim, int spacedim>
6628{
6630 n_faces());
6631}
6632
6633
6634
6635/*----------------- Functions: TriaAccessor<0,dim,spacedim> -----------------*/
6636
6637template <int dim, int spacedim>
6639 const Triangulation<dim, spacedim> *tria,
6640 const unsigned int vertex_index)
6641 : tria(tria)
6642 , global_vertex_index(vertex_index)
6643{}
6644
6645
6646
6647template <int dim, int spacedim>
6649 const Triangulation<dim, spacedim> *tria,
6650 const int /*level*/,
6651 const int index,
6652 const AccessorData *)
6653 : tria(tria)
6655{}
6656
6657
6658
6659template <int dim, int spacedim>
6660template <int structdim2, int dim2, int spacedim2>
6663 : tria(nullptr)
6665{
6666 Assert(false, ExcImpossibleInDim(0));
6667}
6668
6669
6670
6671template <int dim, int spacedim>
6672template <int structdim2, int dim2, int spacedim2>
6675 : tria(nullptr)
6677{
6678 Assert(false, ExcImpossibleInDim(0));
6679}
6680
6681
6682
6683template <int dim, int spacedim>
6684inline void
6686{
6687 tria = t.tria;
6688 global_vertex_index = t.global_vertex_index;
6689}
6690
6691
6692
6693template <int dim, int spacedim>
6694inline bool
6696 const TriaAccessor<0, dim, spacedim> &other) const
6697{
6699
6700 return (global_vertex_index < other.global_vertex_index);
6701}
6702
6703
6704
6705template <int dim, int spacedim>
6708{
6709 if (global_vertex_index != numbers::invalid_unsigned_int)
6710 return IteratorState::valid;
6711 else
6713}
6714
6715
6716
6717template <int dim, int spacedim>
6718inline int
6720{
6721 return 0;
6722}
6723
6724
6725
6726template <int dim, int spacedim>
6727inline int
6729{
6730 return global_vertex_index;
6731}
6732
6733
6734
6735template <int dim, int spacedim>
6736inline const Triangulation<dim, spacedim> &
6738{
6739 return *tria;
6740}
6741
6742
6743
6744template <int dim, int spacedim>
6745inline void
6747{
6749 if (global_vertex_index >= tria->n_vertices())
6751}
6752
6753
6754
6755template <int dim, int spacedim>
6756inline void
6758{
6759 if (global_vertex_index != numbers::invalid_unsigned_int)
6760 {
6761 if (global_vertex_index != 0)
6763 else
6765 }
6766}
6767
6768
6769
6770template <int dim, int spacedim>
6771inline bool
6773{
6774 const bool result =
6775 ((tria == t.tria) && (global_vertex_index == t.global_vertex_index));
6776
6777 return result;
6778}
6779
6780
6781
6782template <int dim, int spacedim>
6783inline bool
6785{
6786 return !(*this == t);
6787}
6788
6789
6790
6791template <int dim, int spacedim>
6792inline unsigned int
6793TriaAccessor<0, dim, spacedim>::vertex_index(const unsigned int) const
6794{
6795 return global_vertex_index;
6796}
6797
6798
6799
6800template <int dim, int spacedim>
6801inline Point<spacedim> &
6802TriaAccessor<0, dim, spacedim>::vertex(const unsigned int) const
6803{
6804 return const_cast<Point<spacedim> &>(
6805 this->tria->vertices[global_vertex_index]);
6806}
6807
6808
6809
6810template <int dim, int spacedim>
6811inline typename ::internal::TriangulationImplementation::
6812 Iterators<dim, spacedim>::line_iterator
6813 TriaAccessor<0, dim, spacedim>::line(const unsigned int)
6814{
6815 return typename ::internal::TriangulationImplementation::
6816 Iterators<dim, spacedim>::line_iterator();
6817}
6818
6819
6820
6821template <int dim, int spacedim>
6822inline unsigned int
6824{
6825 Assert(false, ExcImpossibleInDim(0));
6827}
6828
6829
6830
6831template <int dim, int spacedim>
6832inline typename ::internal::TriangulationImplementation::
6833 Iterators<dim, spacedim>::quad_iterator
6834 TriaAccessor<0, dim, spacedim>::quad(const unsigned int)
6835{
6836 return typename ::internal::TriangulationImplementation::
6837 Iterators<dim, spacedim>::quad_iterator();
6838}
6839
6840
6841
6842template <int dim, int spacedim>
6843inline unsigned int
6845{
6846 Assert(false, ExcImpossibleInDim(0));
6848}
6849
6850
6851
6852template <int dim, int spacedim>
6853inline double
6855{
6856 return 0.;
6857}
6858
6859
6860
6861template <int dim, int spacedim>
6862inline double
6864{
6865 return 0.;
6866}
6867
6868
6869
6870template <int dim, int spacedim>
6871inline Point<spacedim>
6872TriaAccessor<0, dim, spacedim>::center(const bool, const bool) const
6873{
6874 return this->tria->vertices[global_vertex_index];
6875}
6876
6877
6878
6879template <int dim, int spacedim>
6880inline double
6882{
6883 return 1.0;
6884}
6885
6886
6887
6888template <int dim, int spacedim>
6891 const unsigned int /*face*/)
6892{
6894}
6895
6896
6897
6898template <int dim, int spacedim>
6899inline bool
6900TriaAccessor<0, dim, spacedim>::face_orientation(const unsigned int /*face*/)
6901{
6902 return false;
6903}
6904
6905
6906
6907template <int dim, int spacedim>
6908inline bool
6909TriaAccessor<0, dim, spacedim>::face_flip(const unsigned int /*face*/)
6910{
6911 return false;
6912}
6913
6914
6915
6916template <int dim, int spacedim>
6917inline bool
6918TriaAccessor<0, dim, spacedim>::face_rotation(const unsigned int /*face*/)
6919{
6920 return false;
6921}
6922
6923
6924
6925template <int dim, int spacedim>
6927TriaAccessor<0, dim, spacedim>::line_orientation(const unsigned int /*line*/)
6928{
6930}
6931
6932
6933
6934template <int dim, int spacedim>
6935inline bool
6937{
6938 return false;
6939}
6940
6941
6942
6943template <int dim, int spacedim>
6944inline unsigned int
6946{
6947 return 0;
6948}
6949
6950
6951
6952template <int dim, int spacedim>
6953inline unsigned int
6955{
6956 return 0;
6957}
6958
6959
6960
6961template <int dim, int spacedim>
6962inline unsigned int
6964{
6965 return 0;
6966}
6967
6968
6969
6970template <int dim, int spacedim>
6971inline unsigned int
6974{
6976}
6977
6978
6979
6980template <int dim, int spacedim>
6982TriaAccessor<0, dim, spacedim>::child(const unsigned int)
6983{
6985}
6986
6987
6988
6989template <int dim, int spacedim>
6992{
6994}
6995
6996
6997
6998template <int dim, int spacedim>
6999inline RefinementCase<0>
7001{
7003}
7004
7005
7006
7007template <int dim, int spacedim>
7008inline int
7010{
7011 return -1;
7012}
7013
7014
7015
7016template <int dim, int spacedim>
7017inline int
7019{
7020 return -1;
7021}
7022
7023
7024
7025template <int dim, int spacedim>
7026inline bool
7028{
7029 return tria->vertex_used(global_vertex_index);
7030}
7031
7032
7033
7034/*------------------- Functions: TriaAccessor<0,1,spacedim> -----------------*/
7035
7036template <int spacedim>
7038 const Triangulation<1, spacedim> *tria,
7039 const VertexKind vertex_kind,
7040 const unsigned int vertex_index)
7041 : tria(tria)
7042 , vertex_kind(vertex_kind)
7043 , global_vertex_index(vertex_index)
7044{}
7045
7046
7047
7048template <int spacedim>
7050 const Triangulation<1, spacedim> *tria,
7051 const int level,
7052 const int index,
7053 const AccessorData *)
7054 : tria(tria)
7055 , vertex_kind(interior_vertex)
7057{
7058 // in general, calling this constructor should yield an error -- users should
7059 // instead call the one immediately above. however, if you create something
7060 // like Triangulation<1>::face_iterator() then this calls the default
7061 // constructor of the iterator which calls the accessor with argument list
7062 // (0,-2,-2,0), so in this particular case accept this call and create an
7063 // object that corresponds to the default constructed (invalid) vertex
7064 // accessor
7065 (void)level;
7066 (void)index;
7067 Assert((level == -2) && (index == -2),
7068 ExcMessage(
7069 "This constructor can not be called for face iterators in 1d, "
7070 "except to default-construct iterator objects."));
7071}
7072
7073
7074
7075template <int spacedim>
7076template <int structdim2, int dim2, int spacedim2>
7079 : tria(nullptr)
7080 , vertex_kind(interior_vertex)
7082{
7083 Assert(false, ExcImpossibleInDim(0));
7084}
7085
7086
7087
7088template <int spacedim>
7089template <int structdim2, int dim2, int spacedim2>
7092 : tria(nullptr)
7093 , vertex_kind(interior_vertex)
7095{
7096 Assert(false, ExcImpossibleInDim(0));
7097}
7098
7099
7100
7101template <int spacedim>
7102inline void
7104{
7105 tria = t.tria;
7106 vertex_kind = t.vertex_kind;
7107 global_vertex_index = t.global_vertex_index;
7108}
7109
7110
7111
7112template <int spacedim>
7113inline void
7116{
7117 // We cannot convert from TriaAccessorBase to
7118 // TriaAccessor<0,1,spacedim> because the latter is not derived from
7119 // the former. We should never get here.
7121}
7122
7123
7124
7125template <int spacedim>
7126inline bool
7128 const TriaAccessor<0, 1, spacedim> &other) const
7129{
7131
7132 return (global_vertex_index < other.global_vertex_index);
7133}
7134
7135
7136
7137template <int spacedim>
7140{
7141 return IteratorState::valid;
7142}
7143
7144
7145template <int spacedim>
7146inline int
7148{
7149 return 0;
7150}
7151
7152
7153
7154template <int spacedim>
7155inline int
7157{
7158 return global_vertex_index;
7159}
7160
7161
7162
7163template <int spacedim>
7164inline const Triangulation<1, spacedim> &
7166{
7167 return *tria;
7168}
7169
7170
7171
7172template <int spacedim>
7173inline void
7175{
7177}
7178
7179
7180template <int spacedim>
7181inline void
7183{
7185}
7186
7187
7188
7189template <int spacedim>
7190inline bool
7192{
7193 const bool result =
7194 ((tria == t.tria) && (global_vertex_index == t.global_vertex_index));
7195 // if we point to the same vertex,
7196 // make sure we know the same about
7197 // it
7198 if (result == true)
7199 Assert(vertex_kind == t.vertex_kind, ExcInternalError());
7200
7201 return result;
7202}
7203
7204
7205
7206template <int spacedim>
7207inline bool
7209{
7210 return !(*this == t);
7211}
7212
7213
7214
7215template <int spacedim>
7216inline unsigned int
7217TriaAccessor<0, 1, spacedim>::vertex_index(const unsigned int i) const
7218{
7219 AssertIndexRange(i, 1);
7220 (void)i;
7221 return global_vertex_index;
7222}
7223
7224
7225
7226template <int spacedim>
7227inline Point<spacedim> &
7228TriaAccessor<0, 1, spacedim>::vertex(const unsigned int i) const
7229{
7230 AssertIndexRange(i, 1);
7231 (void)i;
7232 return const_cast<Point<spacedim> &>(
7233 this->tria->vertices[global_vertex_index]);
7234}
7235
7236
7237
7238template <int spacedim>
7239inline Point<spacedim>
7241{
7242 return this->tria->vertices[global_vertex_index];
7243}
7244
7245
7246
7247template <int spacedim>
7248inline typename ::internal::TriangulationImplementation::
7249 Iterators<1, spacedim>::line_iterator
7250 TriaAccessor<0, 1, spacedim>::line(const unsigned int)
7251{
7252 return {};
7253}
7254
7255
7256template <int spacedim>
7257inline unsigned int
7259{
7260 Assert(false, ExcImpossibleInDim(0));
7262}
7263
7264
7265template <int spacedim>
7266inline typename ::internal::TriangulationImplementation::
7267 Iterators<1, spacedim>::quad_iterator
7268 TriaAccessor<0, 1, spacedim>::quad(const unsigned int)
7269{
7270 return {};
7271}
7272
7273
7274
7275template <int spacedim>
7276inline unsigned int
7278{
7279 Assert(false, ExcImpossibleInDim(0));
7281}
7282
7283
7284
7285template <int spacedim>
7286inline double
7288{
7289 return 1.0;
7290}
7291
7292
7293
7294template <int spacedim>
7295inline bool
7297{
7298 return vertex_kind != interior_vertex;
7299}
7300
7301
7302template <int spacedim>
7303inline types::boundary_id
7305{
7306 switch (vertex_kind)
7307 {
7308 case left_vertex:
7309 case right_vertex:
7310 {
7312 this->vertex_index()) !=
7313 tria->vertex_to_boundary_id_map_1d->end(),
7315
7316 return (*tria->vertex_to_boundary_id_map_1d)[this->vertex_index()];
7317 }
7318
7319 default:
7321 }
7322}
7323
7324
7325
7326template <int spacedim>
7327inline const Manifold<1, spacedim> &
7329{
7330 return this->tria->get_manifold(this->manifold_id());
7331}
7332
7333
7334
7335template <int spacedim>
7336inline types::manifold_id
7338{
7339 if (tria->vertex_to_manifold_id_map_1d->find(this->vertex_index()) !=
7340 tria->vertex_to_manifold_id_map_1d->end())
7341 return (*tria->vertex_to_manifold_id_map_1d)[this->vertex_index()];
7342 else
7344}
7345
7346
7347template <int spacedim>
7350 const unsigned int /*face*/)
7351{
7353}
7354
7355
7356template <int spacedim>
7357inline bool
7358TriaAccessor<0, 1, spacedim>::face_orientation(const unsigned int /*face*/)
7359{
7360 return false;
7361}
7362
7363
7364
7365template <int spacedim>
7366inline bool
7367TriaAccessor<0, 1, spacedim>::face_flip(const unsigned int /*face*/)
7368{
7369 return false;
7370}
7371
7372
7373
7374template <int spacedim>
7375inline bool
7376TriaAccessor<0, 1, spacedim>::face_rotation(const unsigned int /*face*/)
7377{
7378 return false;
7379}
7380
7381
7382
7383template <int spacedim>
7385TriaAccessor<0, 1, spacedim>::line_orientation(const unsigned int /*line*/)
7386{
7388}
7389
7390
7391
7392template <int spacedim>
7393inline bool
7395{
7396 return false;
7397}
7398
7399
7400
7401template <int spacedim>
7402inline unsigned int
7404{
7405 return 0;
7406}
7407
7408
7409
7410template <int spacedim>
7411inline unsigned int
7413{
7414 return 0;
7415}
7416
7417
7418
7419template <int spacedim>
7420inline unsigned int
7422{
7423 return 0;
7424}
7425
7426
7427
7428template <int spacedim>
7429inline unsigned int
7432{
7434}
7435
7436
7437
7438template <int spacedim>
7440TriaAccessor<0, 1, spacedim>::child(const unsigned int)
7441{
7443}
7444
7445
7446template <int spacedim>
7449{
7451}
7452
7453
7454template <int spacedim>
7455inline RefinementCase<0>
7457{
7459}
7460
7461template <int spacedim>
7462inline int
7464{
7465 return -1;
7466}
7467
7468
7469template <int spacedim>
7470inline int
7472{
7473 return -1;
7474}
7475
7476
7477
7478template <int spacedim>
7479inline void
7481{
7482 Assert(tria->vertex_to_boundary_id_map_1d->find(this->vertex_index()) !=
7483 tria->vertex_to_boundary_id_map_1d->end(),
7484 ExcMessage("You can't set the boundary_id of a face of a cell that is "
7485 "not actually at the boundary."));
7486
7487 (*tria->vertex_to_boundary_id_map_1d)[this->vertex_index()] = b;
7488}
7489
7490
7491
7492template <int spacedim>
7493inline void
7495{
7496 (*tria->vertex_to_manifold_id_map_1d)[this->vertex_index()] = b;
7497}
7498
7499
7500
7501template <int spacedim>
7502inline void
7504 const types::boundary_id b) const
7505{
7506 set_boundary_id(b);
7507}
7508
7509
7510
7511template <int spacedim>
7512inline void
7514{
7515 set_manifold_id(b);
7516}
7517
7518
7519
7520template <int spacedim>
7521inline bool
7523{
7524 return tria->vertex_used(global_vertex_index);
7525}
7526
7527
7528
7529template <int spacedim>
7530inline ReferenceCell
7532{
7534}
7535
7536
7537
7538template <int spacedim>
7539unsigned int
7541{
7542 return 1;
7543}
7544
7545
7546
7547template <int spacedim>
7548unsigned int
7550{
7551 return 0;
7552}
7553
7554
7555
7556template <int spacedim>
7559{
7561 n_vertices());
7562}
7563
7564
7565
7566template <int spacedim>
7569{
7571 n_lines());
7572}
7573
7574/*------------------ Functions: CellAccessor<dim,spacedim> ------------------*/
7575
7576
7577template <int dim, int spacedim>
7579 const Triangulation<dim, spacedim> *parent,
7580 const int level,
7581 const int index,
7582 const AccessorData *local_data)
7583 : TriaAccessor<dim, dim, spacedim>(parent, level, index, local_data)
7584{}
7585
7586
7587
7588template <int dim, int spacedim>
7590 const TriaAccessor<dim, dim, spacedim> &cell_accessor)
7591 : TriaAccessor<dim, dim, spacedim>(
7592 static_cast<const TriaAccessor<dim, dim, spacedim> &>(cell_accessor))
7593{}
7594
7595
7596
7597template <int dim, int spacedim>
7599CellAccessor<dim, spacedim>::child(const unsigned int i) const
7600{
7602 this->present_level + 1,
7603 this->child_index(i));
7604
7605 Assert((q.state() == IteratorState::past_the_end) || q->used(),
7607
7608 return q;
7609}
7610
7611
7612
7613template <int dim, int spacedim>
7614inline boost::container::small_vector<TriaIterator<CellAccessor<dim, spacedim>>,
7617{
7618 boost::container::small_vector<TriaIterator<CellAccessor<dim, spacedim>>,
7620 child_iterators(this->n_children());
7621
7622 for (unsigned int i = 0; i < this->n_children(); ++i)
7623 child_iterators[i] = this->child(i);
7624
7625 return child_iterators;
7626}
7627
7628
7629
7630template <int dim, int spacedim>
7631inline TriaIterator<TriaAccessor<dim - 1, dim, spacedim>>
7632CellAccessor<dim, spacedim>::face(const unsigned int i) const
7633{
7634 AssertIndexRange(i, this->n_faces());
7635 if constexpr (dim == 1)
7636 {
7637 using VertexKind = typename TriaAccessor<0, 1, spacedim>::VertexKind;
7638 VertexKind vertex_kind = VertexKind::interior_vertex;
7639 if (i == 0 && at_boundary(0))
7640 vertex_kind = VertexKind::left_vertex;
7641 if (i == 1 && at_boundary(1))
7642 vertex_kind = VertexKind::right_vertex;
7643 TriaAccessor<0, 1, spacedim> a(&this->get_triangulation(),
7644 vertex_kind,
7645 this->vertex_index(i));
7647 }
7648 else if constexpr (dim == 2)
7649 return this->line(i);
7650 else if constexpr (dim == 3)
7651 return this->quad(i);
7652 else
7653 {
7654 Assert(false, ExcNotImplemented());
7655 return {};
7656 }
7657}
7658
7659
7660
7661template <int dim, int spacedim>
7662inline unsigned int
7665{
7666 for (const unsigned int face_n : this->face_indices())
7667 if (this->face(face_n) == face)
7668 return face_n;
7669
7670 Assert(false,
7671 ExcMessage("The given face is not a face of the current cell."));
7673}
7674
7675
7676
7677template <int dim, int spacedim>
7678inline boost::container::small_vector<
7679 TriaIterator<TriaAccessor<dim - 1, dim, spacedim>>,
7680# ifndef _MSC_VER
7682# else
7684# endif
7685 >
7687{
7688 boost::container::small_vector<
7689 TriaIterator<TriaAccessor<dim - 1, dim, spacedim>>,
7690# ifndef _MSC_VER
7692# else
7694# endif
7695 >
7696 face_iterators(this->n_faces());
7697
7698 for (const unsigned int i : this->face_indices())
7699 face_iterators[i] = this->face(i);
7700
7701 return face_iterators;
7702}
7703
7704
7705
7706template <int dim, int spacedim>
7707inline unsigned int
7708CellAccessor<dim, spacedim>::face_index(const unsigned int i) const
7709{
7710 switch (dim)
7711 {
7712 case 1:
7713 return this->vertex_index(i);
7714
7715 case 2:
7716 return this->line_index(i);
7717
7718 case 3:
7719 return this->quad_index(i);
7720
7721 default:
7723 }
7724}
7725
7726
7727
7728template <int dim, int spacedim>
7729inline int
7730CellAccessor<dim, spacedim>::neighbor_index(const unsigned int face_no) const
7731{
7732 AssertIndexRange(face_no, this->n_faces());
7733 return this->tria->levels[this->present_level]
7734 ->neighbors[this->present_index * ReferenceCells::max_n_faces<dim>() +
7735 face_no]
7736 .second;
7737}
7738
7739
7740
7741template <int dim, int spacedim>
7742inline int
7743CellAccessor<dim, spacedim>::neighbor_level(const unsigned int face_no) const
7744{
7745 AssertIndexRange(face_no, this->n_faces());
7746 return this->tria->levels[this->present_level]
7747 ->neighbors[this->present_index * ReferenceCells::max_n_faces<dim>() +
7748 face_no]
7749 .first;
7750}
7751
7752
7753
7754template <int dim, int spacedim>
7757{
7759 // cells flagged for refinement must be active
7760 // (the @p set_refine_flag function checks this,
7761 // but activity may change when refinement is
7762 // executed and for some reason the refine
7763 // flag is not cleared).
7764 Assert(this->is_active() || !this->tria->levels[this->present_level]
7765 ->refine_flags[this->present_index],
7766 ExcRefineCellNotActive());
7767 return RefinementCase<dim>(
7768 this->tria->levels[this->present_level]->refine_flags[this->present_index]);
7769}
7770
7771
7772
7773template <int dim, int spacedim>
7774inline void
7776 const RefinementCase<dim> refinement_case) const
7777{
7778 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
7779 Assert(!coarsen_flag_set(), ExcCellFlaggedForCoarsening());
7780
7781 this->tria->levels[this->present_level]->refine_flags[this->present_index] =
7782 refinement_case;
7783}
7784
7785
7786
7787template <int dim, int spacedim>
7788inline void
7790{
7791 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
7792 this->tria->levels[this->present_level]->refine_flags[this->present_index] =
7794}
7795
7796
7797template <int dim, int spacedim>
7798inline std::uint8_t
7800{
7802 if (this->tria->levels[this->present_level]->refine_choice.size() == 0)
7803 return 0U;
7804 return this->tria->levels[this->present_level]
7805 ->refine_choice[this->present_index];
7806}
7807
7808
7809template <int dim, int spacedim>
7810inline void
7812 const std::uint8_t refinement_choice) const
7813{
7814 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
7815 if (this->tria->levels[this->present_level]->refine_choice.size() != 0)
7816 this->tria->levels[this->present_level]
7817 ->refine_choice[this->present_index] = refinement_choice;
7818}
7819
7820
7821template <int dim, int spacedim>
7822inline void
7824{
7825 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
7826 if (this->tria->levels[this->present_level]->refine_choice.size() != 0)
7827 this->tria->levels[this->present_level]
7828 ->refine_choice[this->present_index] =
7830}
7831
7832
7833template <int dim, int spacedim>
7834inline bool
7836 const unsigned int face_no,
7837 const RefinementCase<dim - 1> &face_refinement_case) const
7838{
7839 Assert(dim > 1, ExcImpossibleInDim(dim));
7840 AssertIndexRange(face_no, this->n_faces());
7841 AssertIndexRange(face_refinement_case,
7843
7844 // the new refinement case is a combination
7845 // of the minimum required one for the given
7846 // face refinement and the already existing
7847 // flagged refinement case
7848 RefinementCase<dim> old_ref_case = refine_flag_set();
7849 RefinementCase<dim> new_ref_case =
7850 (old_ref_case |
7852 face_refinement_case,
7853 face_no,
7854 this->face_orientation(face_no),
7855 this->face_flip(face_no),
7856 this->face_rotation(face_no)));
7857 set_refine_flag(new_ref_case);
7858 // return, whether we had to change the
7859 // refinement flag
7860 return new_ref_case != old_ref_case;
7861}
7862
7863
7864
7865template <int dim, int spacedim>
7866inline bool
7868 const unsigned int line_no) const
7869{
7870 Assert(dim > 1, ExcImpossibleInDim(dim));
7871 AssertIndexRange(line_no, this->n_lines());
7872
7873 // the new refinement case is a combination
7874 // of the minimum required one for the given
7875 // line refinement and the already existing
7876 // flagged refinement case
7878 old_ref_case = refine_flag_set(),
7879 new_ref_case =
7880 old_ref_case |
7882 set_refine_flag(new_ref_case);
7883 // return, whether we had to change the
7884 // refinement flag
7885 return new_ref_case != old_ref_case;
7886}
7887
7888
7889
7890template <int dim, int spacedim>
7892CellAccessor<dim, spacedim>::subface_case(const unsigned int face_no) const
7893{
7895 AssertIndexRange(face_no, this->n_faces());
7896
7897 if constexpr (dim == 1)
7899 else if constexpr (dim == 2)
7900 return ((face(face_no)->has_children()) ?
7903 else if constexpr (dim == 3)
7904 {
7905 switch (static_cast<std::uint8_t>(face(face_no)->refinement_case()))
7906 {
7910 if (face(face_no)->child(0)->has_children())
7911 {
7912 Assert(face(face_no)->child(0)->refinement_case() ==
7915 if (face(face_no)->child(1)->has_children())
7916 {
7917 Assert(face(face_no)->child(1)->refinement_case() ==
7921 }
7922 else
7924 }
7925 else
7926 {
7927 if (face(face_no)->child(1)->has_children())
7928 {
7929 Assert(face(face_no)->child(1)->refinement_case() ==
7933 }
7934 else
7936 }
7938 if (face(face_no)->child(0)->has_children())
7939 {
7940 Assert(face(face_no)->child(0)->refinement_case() ==
7943 if (face(face_no)->child(1)->has_children())
7944 {
7945 Assert(face(face_no)->child(1)->refinement_case() ==
7949 }
7950 else
7952 }
7953 else
7954 {
7955 if (face(face_no)->child(1)->has_children())
7956 {
7957 Assert(face(face_no)->child(1)->refinement_case() ==
7961 }
7962 else
7964 }
7967 default:
7969 }
7970 }
7971
7972 // we should never get here
7975}
7976
7977
7978
7979template <int dim, int spacedim>
7980inline bool
7982{
7984 // cells flagged for coarsening must be active
7985 // (the @p set_refine_flag function checks this,
7986 // but activity may change when refinement is
7987 // executed and for some reason the refine
7988 // flag is not cleared).
7989 Assert(this->is_active() || !this->tria->levels[this->present_level]
7990 ->coarsen_flags[this->present_index],
7991 ExcRefineCellNotActive());
7992 return this->tria->levels[this->present_level]
7993 ->coarsen_flags[this->present_index];
7994}
7995
7996
7997
7998template <int dim, int spacedim>
7999inline void
8001{
8002 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
8003 Assert(!refine_flag_set(), ExcCellFlaggedForRefinement());
8004
8005 this->tria->levels[this->present_level]->coarsen_flags[this->present_index] =
8006 true;
8007}
8008
8009
8010
8011template <int dim, int spacedim>
8012inline void
8014{
8015 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
8016 this->tria->levels[this->present_level]->coarsen_flags[this->present_index] =
8017 false;
8018}
8019
8020
8021
8022template <int dim, int spacedim>
8024CellAccessor<dim, spacedim>::neighbor(const unsigned int face_no) const
8025{
8027 neighbor_level(face_no),
8028 neighbor_index(face_no));
8029
8030 Assert((q.state() == IteratorState::past_the_end) || q->used(),
8032
8033 return q;
8034}
8035
8036
8037
8038template <int dim, int spacedim>
8039inline bool
8041{
8042 return !this->has_children();
8043}
8044
8045
8046
8047template <int dim, int spacedim>
8048inline bool
8050{
8051 Assert(this->is_active(),
8052 ExcMessage("is_locally_owned() can only be called on active cells!"));
8053# ifndef DEAL_II_WITH_MPI
8054 return true;
8055# else
8056
8057 // Serial triangulations report invalid_subdomain_id as their locally owned
8058 // subdomain, so the first condition checks whether we have a serial
8059 // triangulation, in which case all cells are locally owned. The second
8060 // condition compares the subdomain id in the parallel case.
8061 const types::subdomain_id locally_owned_subdomain =
8062 this->tria->locally_owned_subdomain();
8063 return (locally_owned_subdomain == numbers::invalid_subdomain_id ||
8064 this->subdomain_id() == locally_owned_subdomain);
8065
8066# endif
8067}
8068
8069
8070template <int dim, int spacedim>
8071inline bool
8073{
8074# ifndef DEAL_II_WITH_MPI
8075 return true;
8076# else
8077
8078 // Serial triangulations report invalid_subdomain_id as their locally owned
8079 // subdomain, so the first condition checks whether we have a serial
8080 // triangulation, in which case all cells are locally owned. The second
8081 // condition compares the subdomain id in the parallel case.
8082 const types::subdomain_id locally_owned_subdomain =
8083 this->tria->locally_owned_subdomain();
8084 return (locally_owned_subdomain == numbers::invalid_subdomain_id ||
8085 this->level_subdomain_id() == locally_owned_subdomain);
8086
8087# endif
8088}
8089
8090
8091template <int dim, int spacedim>
8092inline bool
8094{
8095 Assert(this->is_active(),
8096 ExcMessage("is_ghost() can only be called on active cells!"));
8097 if (this->has_children())
8098 return false;
8099
8100# ifndef DEAL_II_WITH_MPI
8101 return false;
8102# else
8103
8104 // Serial triangulations report invalid_subdomain_id as their locally owned
8105 // subdomain, so the first condition rules out that case as all cells to a
8106 // serial triangulation are locally owned and none is ghosted. The second
8107 // and third conditions check whether the cell's subdomain is not the
8108 // locally owned one and not artificial.
8109 const types::subdomain_id locally_owned_subdomain =
8110 this->tria->locally_owned_subdomain();
8111 const types::subdomain_id subdomain_id = this->subdomain_id();
8112 return (locally_owned_subdomain != numbers::invalid_subdomain_id &&
8113 subdomain_id != locally_owned_subdomain &&
8114 subdomain_id != numbers::artificial_subdomain_id);
8115
8116# endif
8117}
8118
8119
8120template <int dim, int spacedim>
8121inline bool
8123{
8124# ifndef DEAL_II_WITH_MPI
8125 return false;
8126# else
8127
8128 // Serial triangulations report invalid_subdomain_id as their locally owned
8129 // subdomain, so the first condition checks whether we have a serial
8130 // triangulation, in which case all cells are locally owned. The second
8131 // condition compares the subdomain id in the parallel case.
8132 const types::subdomain_id locally_owned_subdomain =
8133 this->tria->locally_owned_subdomain();
8134 const types::subdomain_id subdomain_id = this->level_subdomain_id();
8135 return (locally_owned_subdomain != numbers::invalid_subdomain_id &&
8136 subdomain_id != locally_owned_subdomain &&
8137 subdomain_id != numbers::artificial_subdomain_id);
8138
8139# endif
8140}
8141
8142
8143
8144template <int dim, int spacedim>
8145inline bool
8147{
8148 Assert(this->is_active(),
8149 ExcMessage("is_artificial() can only be called on active cells!"));
8150# ifndef DEAL_II_WITH_MPI
8151 return false;
8152# else
8153
8154 // Serial triangulations report invalid_subdomain_id as their locally owned
8155 // subdomain, so the first condition rules out that case as all cells to a
8156 // serial triangulation are locally owned and none is artificial.
8157 return (this->tria->locally_owned_subdomain() !=
8159 this->subdomain_id() == numbers::artificial_subdomain_id);
8160
8161# endif
8162}
8163
8164
8165
8166template <int dim, int spacedim>
8167inline bool
8169{
8170# ifndef DEAL_II_WITH_MPI
8171 return false;
8172# else
8173 return (this->tria->locally_owned_subdomain() !=
8175 this->level_subdomain_id() == numbers::artificial_subdomain_id);
8176# endif
8177}
8178
8179
8180
8181template <int dim, int spacedim>
8184{
8186 Assert(this->is_active(),
8187 ExcMessage("subdomain_id() can only be called on active cells!"));
8188 return this->tria->levels[this->present_level]
8189 ->subdomain_ids[this->present_index];
8190}
8191
8192
8193
8194template <int dim, int spacedim>
8197{
8199 return this->tria->levels[this->present_level]
8200 ->level_subdomain_ids[this->present_index];
8201}
8202
8203
8204
8205template <int dim, int spacedim>
8206inline unsigned int
8207CellAccessor<dim, spacedim>::neighbor_face_no(const unsigned int neighbor) const
8208{
8209 const unsigned int n2 = neighbor_of_neighbor_internal(neighbor);
8211 // return this value as the
8212 // neighbor is not coarser
8213 return n2;
8214 else
8215 // the neighbor is coarser
8216 return neighbor_of_coarser_neighbor(neighbor).first;
8217}
8218
8219
8220
8221template <int dim, int spacedim>
8222inline bool
8224{
8225 return false;
8226}
8227
8228
8229
8230template <int dim, int spacedim>
8231inline unsigned int
8233{
8235 return this->tria->levels[this->present_level]
8236 ->active_cell_indices[this->present_index];
8237}
8238
8239
8240
8241template <int dim, int spacedim>
8244{
8246 Assert(this->is_active(),
8247 ExcMessage(
8248 "global_active_cell_index() can only be called on active cells!"));
8249
8250 return this->tria->levels[this->present_level]
8251 ->global_active_cell_indices[this->present_index];
8252}
8253
8254
8255
8256template <int dim, int spacedim>
8259{
8260 return this->tria->levels[this->present_level]
8261 ->global_level_cell_indices[this->present_index];
8262}
8263
8264#endif // DOXYGEN
8265
8267
8268
8269#endif
void recursively_set_subdomain_id(const types::subdomain_id new_subdomain_id) const
CellAccessor(const Triangulation< dim, spacedim > *parent=nullptr, const int level=-1, const int index=-1, const AccessorData *local_data=nullptr)
TriaIterator< CellAccessor< dim, spacedim > > parent() const
unsigned int neighbor_face_no(const unsigned int neighbor) const
void set_active_cell_index(const unsigned int active_cell_index) const
unsigned int neighbor_of_neighbor_internal(const unsigned int neighbor) const
Triangulation< dim, spacedim > Container
TriaIterator< CellAccessor< dim, spacedim > > periodic_neighbor(const unsigned int i) const
types::global_cell_index global_active_cell_index() const
void set_neighbor(const unsigned int i, const TriaIterator< CellAccessor< dim, spacedim > > &pointer) const
TriaIterator< CellAccessor< dim, spacedim > > neighbor(const unsigned int face_no) const
internal::SubfaceCase< dim > subface_case(const unsigned int face_no) const
boost::container::small_vector< TriaIterator< TriaAccessor< dim - 1, dim, spacedim > >, ReferenceCells::max_n_faces< dim >() > face_iterators() const
bool is_artificial_on_level() const
void set_direction_flag(const bool new_direction_flag) const
void recursively_set_material_id(const types::material_id new_material_id) const
void set_level_subdomain_id(const types::subdomain_id new_level_subdomain_id) const
types::subdomain_id level_subdomain_id() const
std::uint8_t refine_choice() const
RefinementCase< dim > refine_flag_set() const
bool flag_for_face_refinement(const unsigned int face_no, const RefinementCase< dim - 1 > &face_refinement_case=RefinementCase< dim - 1 >::isotropic_refinement) const
unsigned int face_index(const unsigned int i) const
double diameter(const Mapping< dim, spacedim > &mapping) const
TriaActiveIterator< DoFCellAccessor< dim, spacedim, false > > as_dof_handler_iterator(const DoFHandler< dim, spacedim > &dof_handler) const
bool at_boundary(const unsigned int i) const
CellAccessor< dim, spacedim > & operator=(CellAccessor< dim, spacedim > &&)=default
bool is_active() const
bool is_ghost() const
TriaIterator< CellAccessor< dim, spacedim > > neighbor_child_on_subface(const unsigned int face_no, const unsigned int subface_no) const
void set_subdomain_id(const types::subdomain_id new_subdomain_id) const
bool neighbor_is_coarser(const unsigned int face_no) const
TriaIterator< CellAccessor< dim, spacedim > > child(const unsigned int i) const
void set_global_level_cell_index(const types::global_cell_index index) const
bool has_periodic_neighbor(const unsigned int i) const
void clear_refine_choice() const
int periodic_neighbor_level(const unsigned int i) const
std::pair< unsigned int, unsigned int > neighbor_of_coarser_neighbor(const unsigned int neighbor) const
~CellAccessor()=default
CellAccessor(const CellAccessor< dim, spacedim > &)=default
void set_coarsen_flag() const
TriaIterator< TriaAccessor< dim - 1, dim, spacedim > > face(const unsigned int i) const
CellAccessor< dim, spacedim > & operator=(const CellAccessor< dim, spacedim > &)=delete
unsigned int neighbor_of_neighbor(const unsigned int face_no) const
unsigned int face_iterator_to_index(const TriaIterator< TriaAccessor< dim - 1, dim, spacedim > > &face) const
void set_material_id(const types::material_id new_material_id) const
bool is_locally_owned() const
void set_refine_flag(const RefinementCase< dim > ref_case=RefinementCase< dim >::isotropic_refinement) const
CellAccessor(CellAccessor< dim, spacedim > &&)=default
bool point_inside_codim(const Point< spacedim_ > &p) const
typename TriaAccessor< dim, dim, spacedim >::AccessorData AccessorData
bool is_locally_owned_on_level() const
bool has_boundary_lines() const
TriaIterator< CellAccessor< dim, spacedim > > periodic_neighbor_child_on_subface(const unsigned int face_no, const unsigned int subface_no) const
int neighbor_level(const unsigned int face_no) const
int periodic_neighbor_index(const unsigned int i) const
CellAccessor(const InvalidAccessor< structdim2, dim2, spacedim2 > &)
bool periodic_neighbor_is_coarser(const unsigned int i) const
void set_global_active_cell_index(const types::global_cell_index index) const
void clear_coarsen_flag() const
void set_refine_choice(const std::uint8_t refinement_choice=static_cast< char >(IsotropicRefinementChoice::isotropic_refinement)) const
boost::container::small_vector< TriaIterator< CellAccessor< dim, spacedim > >, GeometryInfo< dim >::max_children_per_cell > child_iterators() const
void set_parent(const unsigned int parent_index)
std::pair< unsigned int, unsigned int > periodic_neighbor_of_coarser_periodic_neighbor(const unsigned face_no) const
CellAccessor(const TriaAccessor< dim, dim, spacedim > &cell_accessor)
bool at_boundary() const
unsigned int active_cell_index() const
static bool is_level_cell()
void clear_refine_flag() const
int neighbor_index(const unsigned int face_no) const
bool point_inside(const Point< spacedim > &p) const
types::subdomain_id subdomain_id() const
bool direction_flag() const
types::material_id material_id() const
bool coarsen_flag_set() const
types::global_cell_index global_level_cell_index() const
bool flag_for_line_refinement(const unsigned int line_no) const
CellAccessor(const TriaAccessor< structdim2, dim2, spacedim2 > &)
CellId id() const
bool is_artificial() const
TriaIterator< DoFCellAccessor< dim, spacedim, true > > as_dof_handler_level_iterator(const DoFHandler< dim, spacedim > &dof_handler) const
bool is_ghost_on_level() const
TriaIterator< CellAccessor< dim, spacedim > > neighbor_or_periodic_neighbor(const unsigned int i) const
int parent_index() const
unsigned int periodic_neighbor_of_periodic_neighbor(const unsigned int i) const
unsigned int periodic_neighbor_face_no(const unsigned int i) const
void set_manifold_id(const types::manifold_id) const
InvalidAccessor(const InvalidAccessor &)
static constexpr unsigned int space_dimension
static int level()
bool operator==(const InvalidAccessor &) const
Point< spacedim > & vertex(const unsigned int i) const
void * quad(const unsigned int i) const
void operator++() const
void * line(const unsigned int i) const
static IteratorState::IteratorStates state()
bool operator!=(const InvalidAccessor &) const
bool has_children() const
unsigned int user_index() const
static const unsigned int structure_dimension
void copy_from(const InvalidAccessor &)
void set_user_index(const unsigned int p) const
static int index()
types::manifold_id manifold_id() const
InvalidAccessor(const void *parent=nullptr, const int level=-1, const int index=-1, const AccessorData *local_data=nullptr)
static constexpr unsigned int dimension
void operator--() const
bool used() const
Abstract base class for mapping classes.
Definition mapping.h:320
Definition point.h:113
numbers::NumberTraits< Number >::real_type distance(const Point< dim, Number > &p) const
unsigned int n_vertices() const
unsigned int standard_to_real_face_vertex(const unsigned int vertex, const unsigned int face, const types::geometric_orientation face_orientation) const
std::array< unsigned int, 2 > standard_vertex_to_face_and_vertex_index(const unsigned int vertex) const
std::array< unsigned int, 2 > standard_line_to_face_and_line_index(const unsigned int line) const
unsigned int n_face_orientations(const unsigned int face_no) const
unsigned int n_faces() const
unsigned int n_lines() const
static ReferenceCell n_vertices_to_type(const int dim, const unsigned int n_vertices)
unsigned int standard_to_real_face_line(const unsigned int line, const unsigned int face, const types::geometric_orientation face_orientation) const
constexpr numbers::NumberTraits< Number >::real_type norm_square() const
bool operator!=(const TriaAccessorBase &) const
static constexpr unsigned int space_dimension
static constexpr unsigned int dimension
TriaAccessorBase(const TriaAccessorBase &)
friend class TriaIterator
void operator=(const TriaAccessorBase *)=delete
static const unsigned int structure_dimension
TriaAccessorBase(const Triangulation< dim, spacedim > *parent=nullptr, const int level=-1, const int index=-1, const AccessorData *=nullptr)
void copy_from(const TriaAccessorBase &)
friend class TriaActiveIterator
const Triangulation< dim, spacedim > & get_triangulation() const
IteratorState::IteratorStates state() const
int index() const
bool operator<(const TriaAccessorBase &other) const
typename::internal::TriaAccessorImplementation::PresentLevelType< structdim, dim >::type present_level
friend class TriaRawIterator
::internal::TriangulationImplementation::TriaObjects & objects() const
TriaAccessorBase & operator=(const TriaAccessorBase &)
int level() const
const Triangulation< dim, spacedim > * tria
bool operator==(const TriaAccessorBase &) const
double extent_in_direction(const unsigned int axis) const
TriaAccessor(const Triangulation< dim, spacedim > *tria, const unsigned int vertex_index)
static constexpr unsigned int space_dimension
Point< spacedim > & vertex(const unsigned int i=0) const
static typename::internal::TriangulationImplementation::Iterators< dim, spacedim >::line_iterator line(const unsigned int)
bool operator!=(const TriaAccessor &) const
static RefinementCase< 0 > refinement_case()
void copy_from(const TriaAccessor &)
static TriaIterator< TriaAccessor< 0, dim, spacedim > > child(const unsigned int)
Return an invalid object.
static const unsigned int structure_dimension
TriaAccessor(const InvalidAccessor< structdim2, dim2, spacedim2 > &)
static int child_index(const unsigned int i)
Returns -1.
bool operator==(const TriaAccessor &) const
static unsigned int line_index(const unsigned int i)
static TriaIterator< TriaAccessor< 0, dim, spacedim > > isotropic_child(const unsigned int)
Return an invalid object.
static typename::internal::TriangulationImplementation::Iterators< dim, spacedim >::quad_iterator quad(const unsigned int i)
unsigned int vertex_index(const unsigned int i=0) const
const Triangulation< dim, spacedim > * tria
static int isotropic_child_index(const unsigned int i)
Returns -1.
TriaAccessor(const Triangulation< dim, spacedim > *tria=nullptr, const int level=0, const int index=0, const AccessorData *=nullptr)
static unsigned int n_children()
const Triangulation< dim, spacedim > & get_triangulation() const
static unsigned int child_iterator_to_index(const TriaIterator< TriaAccessor< 0, dim, spacedim > > &)
Return an invalid unsigned integer.
static unsigned int max_refinement_depth()
static unsigned int quad_index(const unsigned int i)
static unsigned int n_active_descendants()
TriaAccessor(const TriaAccessor< structdim2, dim2, spacedim2 > &)
Point< spacedim > center(const bool respect_manifold=false, const bool interpolate_from_surrounding=false) const
IteratorState::IteratorStates state() const
static constexpr unsigned int dimension
std_cxx20::ranges::iota_view< unsigned int, unsigned int > vertex_indices() const
void clear_children() const
void set_boundary_id_internal(const types::boundary_id id) const
TriaAccessor(TriaAccessor &&)=default
unsigned int n_active_descendants() const
void * user_pointer() const
TriaIterator< TriaAccessor< 0, dim, spacedim > > vertex_iterator(const unsigned int i) const
Point< structdim > real_to_unit_cell_affine_approximation(const Point< spacedim > &point) const
unsigned int line_index(const unsigned int i) const
const Manifold< dim, spacedim > & get_manifold() const
unsigned int n_lines() const
double extent_in_direction(const unsigned int axis) const
Point< spacedim > intermediate_point(const Point< structdim > &coordinates) const
unsigned int n_vertices() const
bool has_children() const
std_cxx20::ranges::iota_view< unsigned int, unsigned int > line_indices() const
Point< spacedim > barycenter() const
BoundingBox< spacedim > bounding_box() const
void recursively_set_user_index(const unsigned int p) const
void set_bounding_object_indices(const std::initializer_list< unsigned int > &new_indices) const
TriaIterator< TriaAccessor< structdim, dim, spacedim > > child(const unsigned int i) const
unsigned int n_children() const
std_cxx20::ranges::iota_view< unsigned int, unsigned int > face_indices() const
void set_boundary_id(const types::boundary_id) const
bool is_translation_of(const TriaIterator< TriaAccessor< structdim, dim, spacedim > > &o) const
void recursively_set_user_pointer(void *p) const
void clear_user_index() const
void set_used_flag() const
types::manifold_id manifold_id() const
TriaAccessor(const TriaAccessor &)=default
void recursively_clear_user_pointer() const
void clear_used_flag() const
std::pair< Point< spacedim >, double > enclosing_ball() const
unsigned int vertex_index(const unsigned int i) const
void set_user_pointer(void *p) const
int isotropic_child_index(const unsigned int i) const
Point< spacedim > center(const bool respect_manifold=false, const bool interpolate_from_surrounding=false) const
~TriaAccessor()=default
void set_refinement_case(const RefinementCase< structdim > &ref_case) const
typename TriaAccessorBase< structdim, dim, spacedim >::AccessorData AccessorData
double minimum_vertex_distance() const
double measure() const
void set_all_boundary_ids(const types::boundary_id) const
void set_bounding_object_indices(const std::initializer_list< int > &new_indices) const
void clear_user_flag() const
unsigned int max_refinement_depth() const
void clear_user_pointer() const
void recursively_set_user_flag() const
void set_user_index(const unsigned int p) const
void clear_user_data() const
Point< spacedim > & vertex(const unsigned int i) const
void set_user_flag() const
void set_line_orientation(const unsigned int line, const types::geometric_orientation orientation) const
bool user_flag_set() const
unsigned int quad_index(const unsigned int i) const
TriaAccessor & operator=(const TriaAccessor &)=delete
int child_index(const unsigned int i) const
ReferenceCell reference_cell() const
RefinementCase< structdim > refinement_case() const
typename::internal::TriangulationImplementation::Iterators< dim, spacedim >::line_iterator line(const unsigned int i) const
void recursively_clear_user_flag() const
TriaAccessor(const Triangulation< dim, spacedim > *parent=nullptr, const int level=-1, const int index=-1, const AccessorData *local_data=nullptr)
unsigned int child_iterator_to_index(const TriaIterator< TriaAccessor< structdim, dim, spacedim > > &child) const
bool used() const
void set_children(const unsigned int i, const int index) const
void recursively_clear_user_index() const
void clear_refinement_case() const
double diameter() const
bool at_boundary() const
types::boundary_id boundary_id() const
unsigned int n_faces() const
TriaAccessor & operator=(TriaAccessor &&)=default
TriaIterator< TriaAccessor< structdim, dim, spacedim > > isotropic_child(const unsigned int i) const
typename::internal::TriangulationImplementation::Iterators< dim, spacedim >::quad_iterator quad(const unsigned int i) const
unsigned int user_index() const
std::unique_ptr< std::map< unsigned int, types::manifold_id > > vertex_to_manifold_id_map_1d
Definition tria.h:4572
std::vector< Point< spacedim > > vertices
Definition tria.h:4498
virtual types::subdomain_id locally_owned_subdomain() const
std::unique_ptr< std::map< unsigned int, types::boundary_id > > vertex_to_boundary_id_map_1d
Definition tria.h:4549
std::unique_ptr<::internal::TriangulationImplementation::TriaFaces > faces
Definition tria.h:4492
bool vertex_used(const unsigned int index) const
unsigned int n_vertices() const
std::vector< std::unique_ptr<::internal::TriangulationImplementation::TriaLevel > > levels
Definition tria.h:4484
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:40
constexpr bool running_in_debug_mode()
Definition config.h:78
#define DEAL_II_CXX20_REQUIRES(condition)
Definition config.h:248
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:41
const unsigned int DoFAccessor< structdim, dim, spacedim, level_dof_access >::space_dimension
const unsigned int DoFAccessor< structdim, dim, spacedim, level_dof_access >::dimension
#define DEAL_II_ASSERT_UNREACHABLE()
#define DEAL_II_NOT_IMPLEMENTED()
static ::ExceptionBase & ExcCantCompareIterators()
#define DeclException0(Exception0)
static ::ExceptionBase & ExcCellHasNoParent()
static ::ExceptionBase & ExcCellFlaggedForRefinement()
static ::ExceptionBase & ExcCellHasNoChildren()
static ::ExceptionBase & ExcNotImplemented()
static ::ExceptionBase & ExcCellNotUsed()
static ::ExceptionBase & ExcNoPeriodicNeighbor()
static ::ExceptionBase & ExcCantSetChildren(int arg1)
#define Assert(cond, exc)
static ::ExceptionBase & ExcImpossibleInDim(int arg1)
static ::ExceptionBase & ExcNeighborIsNotCoarser()
static ::ExceptionBase & ExcSetOnlyEvenChildren(int arg1)
static ::ExceptionBase & ExcNeighborIsCoarser()
#define AssertIndexRange(index, range)
#define DeclExceptionMsg(Exception, defaulttext)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcFacesHaveNoLevel()
static ::ExceptionBase & ExcDereferenceInvalidObject(AccessorType arg1)
static ::ExceptionBase & ExcCellFlaggedForCoarsening()
static ::ExceptionBase & ExcIndexRange(std::size_t arg1, std::size_t arg2, std::size_t arg3)
#define DeclException1(Exception1, type1, outsequence)
static ::ExceptionBase & ExcRefineCellNotActive()
static ::ExceptionBase & ExcMessage(std::string arg1)
static ::ExceptionBase & ExcCellNotActive()
TriaIterator< CellAccessor< dim, spacedim > > cell_iterator
Definition tria.h:1557
const bool IsBlockVector< VectorType >::value
void set_all_manifold_ids(const types::manifold_id) const
const Manifold< dim, spacedim > & get_manifold(const types::manifold_id number) const
void set_all_manifold_ids(const types::manifold_id)
void set_manifold_id(const types::manifold_id) const
static bool face_orientation(const unsigned int face)
Always return false.
static types::geometric_orientation line_orientation(const unsigned int line)
Always return numbers::reverse_line_orientation.
bool face_rotation(const unsigned int face) const
bool face_orientation(const unsigned int face) const
static bool face_flip(const unsigned int face)
Always return false.
types::geometric_orientation combined_face_orientation(const unsigned int face) const
static bool face_flip(const unsigned int face)
Always return false.
static types::geometric_orientation combined_face_orientation(const unsigned int face)
Always return 0.
static bool face_rotation(const unsigned int face)
Always return false.
types::geometric_orientation line_orientation(const unsigned int line) const
static bool face_rotation(const unsigned int face)
Always return false.
void set_combined_face_orientation(const unsigned int face, const types::geometric_orientation combined_orientation) const
static types::geometric_orientation line_orientation(const unsigned int line)
Always return numbers::reverse_line_orientation.
static bool face_orientation(const unsigned int face)
Always return false.
bool face_flip(const unsigned int face) const
static types::geometric_orientation combined_face_orientation(const unsigned int face)
Always return 0.
MappingQ< dim, spacedim > StaticMappingQ1< dim, spacedim >::mapping
Definition mapping_q1.h:104
void reference_cell(Triangulation< dim, spacedim > &tria, const ReferenceCell &reference_cell)
@ past_the_end
Iterator reached end of container.
@ valid
Iterator points to a valid object.
@ invalid
Iterator is invalid, probably due to an error.
constexpr char U
double norm(const FEValuesBase< dim > &fe, const ArrayView< const std::vector< Tensor< 1, dim > > > &Du)
Definition divergence.h:471
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
Tensor< 2, dim, Number > l(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
SymmetricTensor< 2, dim, Number > b(const Tensor< 2, dim, Number > &F)
constexpr ReferenceCell Triangle
constexpr ReferenceCell Hexahedron
constexpr ReferenceCell Pyramid
constexpr ReferenceCell Wedge
constexpr ReferenceCell Vertex
constexpr unsigned int max_n_lines()
constexpr unsigned int max_n_vertices()
constexpr unsigned int max_n_faces()
constexpr ReferenceCell Quadrilateral
constexpr ReferenceCell Tetrahedron
constexpr ReferenceCell Line
T sum(const T &t, const MPI_Comm mpi_communicator)
types::geometric_orientation combined_face_orientation(const bool face_orientation, const bool face_rotation, const bool face_flip)
constexpr unsigned int invalid_unsigned_int
Definition types.h:238
constexpr types::boundary_id internal_face_boundary_id
Definition types.h:329
constexpr types::manifold_id flat_manifold_id
Definition types.h:342
constexpr types::subdomain_id artificial_subdomain_id
Definition types.h:402
constexpr types::geometric_orientation reverse_line_orientation
Definition types.h:365
constexpr types::subdomain_id invalid_subdomain_id
Definition types.h:381
constexpr types::geometric_orientation default_geometric_orientation
Definition types.h:352
boost::integer_range< IncrementableType > iota_view
Definition iota_view.h:45
::VectorizedArray< Number, width > min(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > max(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > sqrt(const ::VectorizedArray< Number, width > &)
unsigned int material_id
Definition types.h:184
unsigned int boundary_id
Definition types.h:161
unsigned int subdomain_id
Definition types.h:52
std::uint64_t global_vertex_index
Definition types.h:57
unsigned int manifold_id
Definition types.h:173
unsigned char geometric_orientation
Definition types.h:40
unsigned int global_cell_index
Definition types.h:138
static RefinementCase< dim > min_cell_refinement_case_for_line_refinement(const unsigned int line_no)
static constexpr unsigned int vertices_per_cell
static constexpr unsigned int faces_per_cell
static RefinementCase< dim > min_cell_refinement_case_for_face_refinement(const RefinementCase< dim - 1 > &face_refinement_case, const unsigned int face_no, const bool face_orientation=true, const bool face_flip=false, const bool face_rotation=false)
static unsigned int n_children(const RefinementCase< dim > &refinement_case)
static constexpr unsigned int max_children_per_cell