deal.II version 9.8.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: Apache-2.0 WITH LLVM-exception OR LGPL-2.1-or-later
4// Copyright (C) 1998 - 2026 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Detailed license information governing the source code and contributions
9// can be found in LICENSE.md and CONTRIBUTING.md at the top level directory.
10//
11// -----------------------------------------------------------------------------
12
13#ifndef dealii_tria_accessor_h
14#define dealii_tria_accessor_h
15
16
17#include <deal.II/base/config.h>
18
22#include <deal.II/base/point.h>
24
32
33#include <boost/container/small_vector.hpp>
34
35#include <cmath>
36#include <limits>
37#include <set>
38#include <utility>
39
40
42
43// Forward declarations
44#ifndef DOXYGEN
45template <int dim, int spacedim>
47class Triangulation;
48template <typename Accessor>
49class TriaRawIterator;
50template <typename Accessor>
51class TriaIterator;
52template <typename Accessor>
54
55namespace parallel
56{
57 template <int dim, int spacedim>
58 DEAL_II_CXX20_REQUIRES((concepts::is_valid_dim_spacedim<dim, spacedim>))
60}
61
62template <int dim, int spacedim>
64class DoFHandler;
65template <int dim, int spacedim, bool lda>
66class DoFCellAccessor;
67
68
69template <int dim, int spacedim>
70class Manifold;
71
72template <int dim, int spacedim>
73class Mapping;
74#endif
75
76namespace internal
77{
79 {
80 class TriaObjects;
81 struct Implementation;
83 } // namespace TriangulationImplementation
84
86 {
87 struct Implementation;
88
102 template <bool level_access>
104 {};
105
109 template <>
110 class LevelAccessor<true>
111 {
112 public:
113 LevelAccessor(const int level)
114 : present_level(level)
115 {}
116
117 void
118 set_level(const int level)
119 {
120 present_level = level;
121 }
122
123 int
124 get_level() const
125 {
126 return present_level;
127 }
128
129 private:
131 };
132
136 template <>
137 class LevelAccessor<false>
138 {
139 public:
140 LevelAccessor(const int level)
141 {
142 Assert(level == 0, ExcInternalError());
143 }
144
145 static void
146 set_level(const int level)
147 {
148 Assert(level == 0, ExcInternalError());
149 }
150
151 static int
153 {
154 return 0;
155 }
156 };
157 } // namespace TriaAccessorImplementation
158} // namespace internal
159template <int structdim, int dim, int spacedim>
160class TriaAccessor;
161template <int dim, int spacedim>
162class TriaAccessor<0, dim, spacedim>;
163template <int spacedim>
164class TriaAccessor<0, 1, spacedim>;
165
170{
175 "The operation you are attempting can only be performed for "
176 "(cell, face, or edge) iterators that point to valid "
177 "objects. These objects need not necessarily be active, "
178 "i.e., have no children, but they need to be part of a "
179 "triangulation. (The objects pointed to by an iterator "
180 "may -- after coarsening -- also be objects that used "
181 "to be part of a triangulation, but are now no longer "
182 "used. Their memory location may have been retained "
183 "for re-use upon the next mesh refinement, but is "
184 "currently unused.)");
195 "The operation you are attempting can only be performed for "
196 "(cell, face, or edge) iterators that point to 'active' "
197 "objects. 'Active' objects are those that do not have "
198 "children (in the case of cells), or that are part of "
199 "an active cell (in the case of faces or edges). However, "
200 "the object on which you are trying the current "
201 "operation is not 'active' in this sense.");
208 "The operation you are attempting can only be performed for "
209 "(cell, face, or edge) iterators that have children, "
210 "but the object on which you are trying the current "
211 "operation does not have any.");
219 "The operation you are attempting can only be performed for "
220 "(cell, face, or edge) iterators that have a parent object, "
221 "but the object on which you are trying the current "
222 "operation does not have one -- i.e., it is on the "
223 "coarsest level of the triangulation.");
228 int,
229 << "You can only set the child index if the cell does not "
230 << "currently have children registered; or you can clear it. "
231 << "The given index was " << arg1
232 << " (-1 means: clear children).");
236 template <typename AccessorType>
238 AccessorType,
239 << "You tried to dereference an iterator for which this "
240 << "is not possible. More information on this iterator: "
241 << "index=" << arg1.index() << ", state="
242 << (arg1.state() == IteratorState::valid ?
243 "valid" :
244 (arg1.state() == IteratorState::past_the_end ?
245 "past_the_end" :
246 "invalid")));
251 "Iterators can only be compared if they point to the same "
252 "triangulation, or if neither of them are associated "
253 "with a triangulation.");
254 // TODO: Write documentation!
259 // TODO: Write documentation!
286 int,
287 << "You can only set the child index of an even numbered child."
288 << "The number of the child given was " << arg1 << '.');
289} // namespace TriaAccessorExceptions
290
291
317template <int structdim, int dim, int spacedim = dim>
320 dim>
321{
322public:
329 static constexpr unsigned int space_dimension = spacedim;
330
336 static constexpr unsigned int dimension = dim;
337
343 static const unsigned int structure_dimension = structdim;
344
354 void
355 operator=(const TriaAccessorBase *) = delete;
356
357protected:
363 using AccessorData = void;
364
369 const int level = -1,
370 const int index = -1,
371 const AccessorData * = nullptr);
372
377
385 void
387
393
404 bool
405 operator<(const TriaAccessorBase &other) const;
406
407protected:
411 bool
413
417 bool
419
433 void
435
443 void
448
453 objects() const;
454
455public:
461 using LocalData = void *;
462
469
486 int
487 level() const;
488
515 int
516 index() const;
517
523 state() const;
524
531
535protected:
541
546
547private:
548 template <typename Accessor>
549 friend class TriaRawIterator;
550 template <typename Accessor>
551 friend class TriaIterator;
552 template <typename Accessor>
553 friend class TriaActiveIterator;
554};
555
556
557
578template <int structdim, int dim, int spacedim = dim>
580{
581public:
588 static constexpr unsigned int space_dimension = spacedim;
589
595 static constexpr unsigned int dimension = dim;
596
602 static const unsigned int structure_dimension = structdim;
603
609 using AccessorData = void;
610
618 InvalidAccessor(const void *parent = nullptr,
619 const int level = -1,
620 const int index = -1,
621 const AccessorData *local_data = nullptr);
622
631
636 template <typename OtherAccessor>
637 InvalidAccessor(const OtherAccessor &);
638
642 void
644
648 bool
650 bool
652
656 void
657 operator++() const;
658 void
659 operator--() const;
660
666 state();
667
668
673 static int
674 level();
675
680 static int
681 index();
682
687 bool
688 used() const;
689
694 bool
696
701 manifold_id() const;
702
706 unsigned int
707 user_index() const;
708
712 void
713 set_user_index(const unsigned int p) const;
714
718 void
720
725 vertex(const unsigned int i) const;
726
731 void *
732 line(const unsigned int i) const;
733
738 void *
739 quad(const unsigned int i) const;
740};
741
742
743
761template <int structdim, int dim, int spacedim>
762class TriaAccessor : public TriaAccessorBase<structdim, dim, spacedim>
763{
764public:
770
775 const int level = -1,
776 const int index = -1,
777 const AccessorData *local_data = nullptr);
778
783 TriaAccessor(const TriaAccessor &) = default;
784
788 TriaAccessor(TriaAccessor &&) = default; // NOLINT
789
802 template <int structdim2, int dim2, int spacedim2>
804
809 template <int structdim2, int dim2, int spacedim2>
811
822 operator=(const TriaAccessor &) = delete;
823
828 operator=(TriaAccessor &&) = default; // NOLINT
829
833 ~TriaAccessor() = default;
834
841 bool
842 used() const;
843
850
856 vertex_iterator(const unsigned int i) const;
857
873 unsigned int
874 vertex_index(const unsigned int i) const;
875
914 vertex(const unsigned int i) const;
915
919 typename ::internal::TriangulationImplementation::
920 Iterators<dim, spacedim>::line_iterator
921 line(const unsigned int i) const;
922
929 unsigned int
930 line_index(const unsigned int i) const;
931
935 typename ::internal::TriangulationImplementation::
936 Iterators<dim, spacedim>::quad_iterator
937 quad(const unsigned int i) const;
938
945 unsigned int
946 quad_index(const unsigned int i) const;
950
957
965 combined_face_orientation(const unsigned int face) const;
966
978 bool
979 face_orientation(const unsigned int face) const;
980
990 bool
991 face_flip(const unsigned int face) const;
992
1002 bool
1003 face_rotation(const unsigned int face) const;
1004
1015 line_orientation(const unsigned int line) const;
1019
1026
1030 bool
1032
1037 unsigned int
1038 n_children() const;
1039
1053 unsigned int
1055
1069 unsigned int
1071
1076 child(const unsigned int i) const;
1077
1082 unsigned int
1085
1095 isotropic_child(const unsigned int i) const;
1096
1102
1108 int
1109 child_index(const unsigned int i) const;
1110
1116 int
1117 isotropic_child_index(const unsigned int i) const;
1121
1128
1141
1169 void
1171
1200 void
1202
1210 bool
1212
1224
1228
1235
1247
1265 void
1267
1281 void
1283
1287
1288
1300 bool
1302
1308 void
1310
1316 void
1318
1324 void
1326
1332 void
1334
1340 void
1342
1354 void
1355 set_user_pointer(void *p) const;
1356
1362 void
1364
1382 void *
1384
1406 void
1408
1415 void
1417
1427 void
1428 set_user_index(const unsigned int p) const;
1429
1435 void
1437
1449 unsigned int
1450 user_index() const;
1451
1469 void
1470 recursively_set_user_index(const unsigned int p) const;
1471
1480 void
1485
1492
1516 double
1517 diameter() const;
1518
1545 std::pair<Point<spacedim>, double>
1547
1558
1568 double
1569 extent_in_direction(const unsigned int axis) const;
1570
1574 double
1576
1591 intermediate_point(const Point<structdim> &coordinates) const;
1592
1617
1653 center(const bool respect_manifold = false,
1654 const bool interpolate_from_surrounding = false) const;
1655
1674 barycenter() const;
1675
1709 double
1710 measure() const;
1711
1726 bool
1729
1735
1739 unsigned int
1740 n_vertices() const;
1741
1745 unsigned int
1746 n_lines() const;
1747
1757 unsigned int
1758 n_faces() const;
1759
1764 std_cxx20::ranges::iota_view<unsigned int, unsigned int>
1766
1771 std_cxx20::ranges::iota_view<unsigned int, unsigned int>
1773
1780 std_cxx20::ranges::iota_view<unsigned int, unsigned int>
1782
1786
1787private:
1792 void
1794
1802 void
1804 const std::initializer_list<int> &new_indices) const;
1805
1809 void
1811 const std::initializer_list<unsigned int> &new_indices) const;
1812
1820 void
1821 set_line_orientation(const unsigned int line,
1822 const types::geometric_orientation orientation) const;
1823
1833 void
1835 const unsigned int face_no,
1836 const types::geometric_orientation combined_orientation) const;
1837
1841 void
1843
1847 void
1849
1858 void
1860
1868 void
1870
1877 void
1878 set_children(const unsigned int i, const int index) const;
1879
1884 void
1886
1887private:
1888 friend class Triangulation<dim, spacedim>;
1889
1890 friend struct ::internal::TriangulationImplementation::Implementation;
1891 friend struct ::internal::TriangulationImplementation::
1892 ImplementationMixedMesh;
1893 friend struct ::internal::TriaAccessorImplementation::Implementation;
1894};
1895
1896
1897
1916template <int dim, int spacedim>
1917class TriaAccessor<0, dim, spacedim>
1918{
1919public:
1925 static constexpr unsigned int space_dimension = spacedim;
1926
1932 static constexpr unsigned int dimension = dim;
1933
1939 static const unsigned int structure_dimension = 0;
1940
1944 using AccessorData = void;
1945
1951 const unsigned int vertex_index);
1952
1959 const int level = 0,
1960 const int index = 0,
1961 const AccessorData * = nullptr);
1962
1966 template <int structdim2, int dim2, int spacedim2>
1968
1972 template <int structdim2, int dim2, int spacedim2>
1974
1979 state() const;
1980
1985 static int
1987
1992 int
1993 index() const;
1994
2001
2011 void
2013
2017 void
2022 bool
2023 operator==(const TriaAccessor &) const;
2024
2028 bool
2029 operator!=(const TriaAccessor &) const;
2030
2034
2035
2042
2058 unsigned int
2059 vertex_index(const unsigned int i = 0) const;
2060
2067 vertex(const unsigned int i = 0) const;
2068
2073 typename ::internal::TriangulationImplementation::
2074 Iterators<dim, spacedim>::line_iterator static line(const unsigned int);
2075
2079 static unsigned int
2080 line_index(const unsigned int i);
2081
2085 static typename ::internal::TriangulationImplementation::
2086 Iterators<dim, spacedim>::quad_iterator
2087 quad(const unsigned int i);
2088
2092 static unsigned int
2093 quad_index(const unsigned int i);
2094
2098
2099
2106
2110 double
2111 diameter() const;
2112
2120 double
2121 extent_in_direction(const unsigned int axis) const;
2122
2131 center(const bool respect_manifold = false,
2132 const bool interpolate_from_surrounding = false) const;
2133
2141 double
2142 measure() const;
2146
2153
2160 combined_face_orientation(const unsigned int face);
2161
2165 static bool
2166 face_orientation(const unsigned int face);
2167
2171 static bool
2172 face_flip(const unsigned int face);
2173
2177 static bool
2178 face_rotation(const unsigned int face);
2179
2184 line_orientation(const unsigned int line);
2185
2189
2196
2200 static bool
2202
2207 static unsigned int
2209
2214 static unsigned int
2216
2220 static unsigned int
2222
2226 static unsigned int
2228
2233 child(const unsigned int);
2234
2239 isotropic_child(const unsigned int);
2240
2244 static RefinementCase<0>
2246
2250 static int
2251 child_index(const unsigned int i);
2252
2256 static int
2257 isotropic_child_index(const unsigned int i);
2261
2265 bool
2266 used() const;
2267
2268protected:
2276 void
2278
2287 bool
2288 operator<(const TriaAccessor &other) const;
2289
2294
2299
2300private:
2301 template <typename Accessor>
2302 friend class TriaRawIterator;
2303 template <typename Accessor>
2304 friend class TriaIterator;
2305 template <typename Accessor>
2307};
2308
2309
2310
2327template <int spacedim>
2328class TriaAccessor<0, 1, spacedim>
2329{
2330public:
2336 static constexpr unsigned int space_dimension = spacedim;
2337
2343 static constexpr unsigned int dimension = 1;
2344
2350 static const unsigned int structure_dimension = 0;
2351
2355 using AccessorData = void;
2356
2376
2389 const VertexKind vertex_kind,
2390 const unsigned int vertex_index);
2391
2398 const int = 0,
2399 const int = 0,
2400 const AccessorData * = nullptr);
2401
2405 template <int structdim2, int dim2, int spacedim2>
2407
2411 template <int structdim2, int dim2, int spacedim2>
2413
2418 void
2420
2426 void
2428
2436
2441 static int
2443
2448 int
2449 index() const;
2450
2457
2468 void
2469 operator++() const;
2470
2475 void
2476 operator--() const;
2480 bool
2481 operator==(const TriaAccessor &) const;
2482
2486 bool
2487 operator!=(const TriaAccessor &) const;
2488
2497 bool
2498 operator<(const TriaAccessor &other) const;
2499
2503
2510
2526 unsigned int
2527 vertex_index(const unsigned int i = 0) const;
2528
2535 vertex(const unsigned int i = 0) const;
2536
2542 center() const;
2543
2548 typename ::internal::TriangulationImplementation::
2549 Iterators<1, spacedim>::line_iterator static line(const unsigned int);
2550
2557 static unsigned int
2558 line_index(const unsigned int i);
2559
2563 static typename ::internal::TriangulationImplementation::
2564 Iterators<1, spacedim>::quad_iterator
2565 quad(const unsigned int i);
2566
2573 static unsigned int
2574 quad_index(const unsigned int i);
2575
2579
2586
2593 static double
2595
2599
2604 bool
2606
2623
2627 const Manifold<1, spacedim> &
2629
2638
2639
2651 bool
2652 user_flag_set() const;
2653
2659 void
2660 set_user_flag() const;
2661
2667 void
2668 clear_user_flag() const;
2669
2675 void
2677
2683 void
2685
2691 void
2692 clear_user_data() const;
2693
2705 void
2706 set_user_pointer(void *p) const;
2707
2713 void
2714 clear_user_pointer() const;
2715
2731 void *
2732 user_pointer() const;
2733
2755 void
2756 recursively_set_user_pointer(void *p) const;
2757
2764 void
2766
2776 void
2777 set_user_index(const unsigned int p) const;
2778
2784 void
2785 clear_user_index() const;
2786
2798 unsigned int
2799 user_index() const;
2800
2818 void
2819 recursively_set_user_index(const unsigned int p) const;
2820
2829 void
2834
2841
2848 combined_face_orientation(const unsigned int face);
2849
2853 static bool
2854 face_orientation(const unsigned int face);
2855
2859 static bool
2860 face_flip(const unsigned int face);
2861
2865 static bool
2866 face_rotation(const unsigned int face);
2867
2872 line_orientation(const unsigned int line);
2873
2877
2884
2888 static bool
2890
2895 static unsigned int
2897
2902 static unsigned int
2904
2908 static unsigned int
2910
2914 static unsigned int
2916
2921 child(const unsigned int);
2922
2927 isotropic_child(const unsigned int);
2928
2932 static RefinementCase<0>
2934
2938 static int
2939 child_index(const unsigned int i);
2940
2944 static int
2945 isotropic_child_index(const unsigned int i);
2949
2956
2976 void
2978
2985 void
2987
2997 void
2999
3011 void
3016
3020 bool
3021 used() const;
3022
3028
3032 unsigned int
3033 n_vertices() const;
3034
3038 unsigned int
3039 n_lines() const;
3040
3045 std_cxx20::ranges::iota_view<unsigned int, unsigned int>
3047
3052 std_cxx20::ranges::iota_view<unsigned int, unsigned int>
3054
3055protected:
3060
3066
3071};
3072
3073
3074
3090template <int dim, int spacedim = dim>
3091class CellAccessor : public TriaAccessor<dim, dim, spacedim>
3092{
3093public:
3098
3103
3110
3115 const int level = -1,
3116 const int index = -1,
3117 const AccessorData *local_data = nullptr);
3118
3123
3136 template <int structdim2, int dim2, int spacedim2>
3138
3143 template <int structdim2, int dim2, int spacedim2>
3145
3150
3154 // NOLINTNEXTLINE OSX does not compile with noexcept
3156
3160 ~CellAccessor() = default;
3161
3173
3177 // NOLINTNEXTLINE OSX does not compile with noexcept
3180
3184
3191
3205
3216 const DoFHandler<dim, spacedim> &dof_handler) const;
3217
3218
3222
3229
3235 child(const unsigned int i) const;
3236
3240 boost::container::small_vector<TriaIterator<CellAccessor<dim, spacedim>>,
3243
3247 TriaIterator<TriaAccessor<dim - 1, dim, spacedim>>
3248 face(const unsigned int i) const;
3249
3254 unsigned int
3257
3261 boost::container::small_vector<
3262 TriaIterator<TriaAccessor<dim - 1, dim, spacedim>>,
3263#ifndef _MSC_VER // MSVC prior to 2022 cannot use a constexpr function this way
3265#else
3267#endif
3268 >
3270
3280 unsigned int
3281 face_index(const unsigned int i) const;
3282
3331 neighbor_child_on_subface(const unsigned int face_no,
3332 const unsigned int subface_no) const;
3333
3382 neighbor(const unsigned int face_no) const;
3383
3391 int
3392 neighbor_index(const unsigned int face_no) const;
3393
3401 int
3402 neighbor_level(const unsigned int face_no) const;
3403
3415 unsigned int
3416 neighbor_of_neighbor(const unsigned int face_no) const;
3417
3428 bool
3429 neighbor_is_coarser(const unsigned int face_no) const;
3430
3445 std::pair<unsigned int, unsigned int>
3446 neighbor_of_coarser_neighbor(const unsigned int neighbor) const;
3447
3454 unsigned int
3455 neighbor_face_no(const unsigned int neighbor) const;
3456
3460 static bool
3462
3476 bool
3477 has_periodic_neighbor(const unsigned int i) const;
3478
3496 periodic_neighbor(const unsigned int i) const;
3497
3506 neighbor_or_periodic_neighbor(const unsigned int i) const;
3507
3523 periodic_neighbor_child_on_subface(const unsigned int face_no,
3524 const unsigned int subface_no) const;
3525
3536 std::pair<unsigned int, unsigned int>
3538
3544 int
3545 periodic_neighbor_index(const unsigned int i) const;
3546
3552 int
3553 periodic_neighbor_level(const unsigned int i) const;
3554
3569 unsigned int
3570 periodic_neighbor_of_periodic_neighbor(const unsigned int i) const;
3571
3577 unsigned int
3578 periodic_neighbor_face_no(const unsigned int i) const;
3579
3586 bool
3587 periodic_neighbor_is_coarser(const unsigned int i) const;
3588
3592
3599
3605 bool
3606 at_boundary(const unsigned int i) const;
3607
3616 bool
3618
3626 bool
3631
3638
3655
3673 void
3676
3680 void
3682
3687 std::uint8_t
3689
3694 void
3695 set_refine_choice(const std::uint8_t refinement_choice = static_cast<char>(
3697
3701 void
3703
3711 bool
3713 const unsigned int face_no,
3714 const RefinementCase<dim - 1> &face_refinement_case =
3716
3722 bool
3723 flag_for_line_refinement(const unsigned int line_no) const;
3724
3734 subface_case(const unsigned int face_no) const;
3735
3739 bool
3741
3746 void
3748
3752 void
3757
3764
3778
3790 void
3791 set_material_id(const types::material_id new_material_id) const;
3792
3801 void
3806
3813
3830
3846 void
3847 set_subdomain_id(const types::subdomain_id new_subdomain_id) const;
3848
3859
3864 void
3866 const types::subdomain_id new_level_subdomain_id) const;
3867
3868
3884 void
3886 const types::subdomain_id new_subdomain_id) const;
3890
3910
3920
3946 unsigned int
3948
3956 int
3958
3965 parent() const;
3966
3973
3983 bool
3985
3989
3996
4005 bool
4006 is_active() const;
4007
4027 bool
4029
4034 bool
4036
4070 bool
4071 is_ghost() const;
4072
4078 bool
4080
4107 bool
4109
4116 bool
4118
4132 bool
4134
4143 void
4144 set_neighbor(const unsigned int i,
4146
4147
4164 std::set<TriaActiveIterator<CellAccessor<dim, spacedim>>>
4165 get_cells_adjacent_to_line(const unsigned int i) const;
4166
4180 CellId
4181 id() const;
4182
4183 using TriaAccessor<dim, dim, spacedim>::diameter;
4184
4188 double
4190
4194
4195
4208
4209protected:
4225 unsigned int
4226 neighbor_of_neighbor_internal(const unsigned int neighbor) const;
4227
4233 template <int dim_, int spacedim_>
4234 bool
4236
4237
4238
4239private:
4244 void
4245 set_active_cell_index(const unsigned int active_cell_index) const;
4246
4250 void
4252
4256 void
4258
4262 void
4263 set_parent(const unsigned int parent_index);
4264
4275 void
4276 set_direction_flag(const bool new_direction_flag) const;
4277
4278 friend class Triangulation<dim, spacedim>;
4279
4280 friend class parallel::TriangulationBase<dim, spacedim>;
4281
4282 friend struct ::internal::TriangulationImplementation::Implementation;
4283 friend struct ::internal::TriangulationImplementation::
4284 ImplementationMixedMesh;
4285};
4286
4287
4288
4289/* ----- declaration of explicit specializations and general templates ----- */
4290
4291
4292template <int structdim, int dim, int spacedim>
4293template <typename OtherAccessor>
4295 const OtherAccessor &)
4296{
4297 Assert(false,
4298 ExcMessage("You are attempting an illegal conversion between "
4299 "iterator/accessor types. The constructor you call "
4300 "only exists to make certain template constructs "
4301 "easier to write as dimension independent code but "
4302 "the conversion is not valid in the current context."));
4303}
4304
4305
4306
4307template <int structdim, int dim, int spacedim>
4308template <int structdim2, int dim2, int spacedim2>
4311{
4312 Assert(false,
4313 ExcMessage("You are attempting an illegal conversion between "
4314 "iterator/accessor types. The constructor you call "
4315 "only exists to make certain template constructs "
4316 "easier to write as dimension independent code but "
4317 "the conversion is not valid in the current context."));
4318}
4319
4320
4321
4322template <int dim, int spacedim>
4323template <int structdim2, int dim2, int spacedim2>
4326{
4327 Assert(false,
4328 ExcMessage("You are attempting an illegal conversion between "
4329 "iterator/accessor types. The constructor you call "
4330 "only exists to make certain template constructs "
4331 "easier to write as dimension independent code but "
4332 "the conversion is not valid in the current context."));
4333}
4334
4335
4336
4337template <int structdim, int dim, int spacedim>
4338template <int structdim2, int dim2, int spacedim2>
4341{
4342 Assert(false,
4343 ExcMessage("You are attempting an illegal conversion between "
4344 "iterator/accessor types. The constructor you call "
4345 "only exists to make certain template constructs "
4346 "easier to write as dimension independent code but "
4347 "the conversion is not valid in the current context."));
4348}
4349
4350
4351
4352template <int dim, int spacedim>
4353template <int structdim2, int dim2, int spacedim2>
4356{
4357 Assert(false,
4358 ExcMessage("You are attempting an illegal conversion between "
4359 "iterator/accessor types. The constructor you call "
4360 "only exists to make certain template constructs "
4361 "easier to write as dimension independent code but "
4362 "the conversion is not valid in the current context."));
4363}
4364
4365
4366#ifndef DOXYGEN
4367
4368template <>
4369bool
4371template <>
4372bool
4374template <>
4375bool
4377template <>
4378bool
4380template <>
4381bool
4383template <>
4384bool
4386// -------------------------------------------------------------------
4387
4388template <>
4389void
4391
4392
4393
4394namespace internal
4395{
4396 namespace TriaAccessorImplementation
4397 {
4403 template <int dim, int spacedim>
4404 inline double
4405 diameter(
4406 const boost::container::small_vector<Point<spacedim>,
4408 vertices)
4409 {
4410 const ReferenceCell<dim> reference_cell =
4412
4413 if (reference_cell == ReferenceCells::Line)
4414 // Return the distance between the two vertices
4415 return (vertices[1] - vertices[0]).norm();
4416 else if (reference_cell == ReferenceCells::Triangle)
4417 // Return the longest of the three edges
4418 return std::max({(vertices[1] - vertices[0]).norm(),
4419 (vertices[2] - vertices[1]).norm(),
4420 (vertices[2] - vertices[0]).norm()});
4421 else if (reference_cell == ReferenceCells::Quadrilateral)
4422 // Return the longer one of the two diagonals of the quadrilateral
4423 return std::max({(vertices[3] - vertices[0]).norm(),
4424 (vertices[2] - vertices[1]).norm()});
4425 else if (reference_cell == ReferenceCells::Tetrahedron)
4426 // Return the longest of the six edges of the tetrahedron
4427 return std::max({(vertices[1] - vertices[0]).norm(),
4428 (vertices[2] - vertices[0]).norm(),
4429 (vertices[2] - vertices[1]).norm(),
4430 (vertices[3] - vertices[0]).norm(),
4431 (vertices[3] - vertices[1]).norm(),
4432 (vertices[3] - vertices[2]).norm()});
4433 else if (reference_cell == ReferenceCells::Pyramid)
4434 // Return ...
4435 return std::max({// the longest diagonal of the quadrilateral base
4436 // of the pyramid or ...
4437 (vertices[3] - vertices[0]).norm(),
4438 (vertices[2] - vertices[1]).norm(),
4439 // the longest edge connected with the apex of the
4440 // pyramid
4441 (vertices[4] - vertices[0]).norm(),
4442 (vertices[4] - vertices[1]).norm(),
4443 (vertices[4] - vertices[2]).norm(),
4444 (vertices[4] - vertices[3]).norm()});
4445 else if (reference_cell == ReferenceCells::Wedge)
4446 // Return ...
4447 return std::max({// the longest of the 2*3=6 diagonals of the three
4448 // quadrilateral sides of the wedge or ...
4449 (vertices[4] - vertices[0]).norm(),
4450 (vertices[3] - vertices[1]).norm(),
4451 (vertices[5] - vertices[1]).norm(),
4452 (vertices[4] - vertices[2]).norm(),
4453 (vertices[5] - vertices[0]).norm(),
4454 (vertices[3] - vertices[2]).norm(),
4455 // the longest of the 3*2=6 edges of the two
4456 // triangular faces of the wedge
4457 (vertices[1] - vertices[0]).norm(),
4458 (vertices[2] - vertices[1]).norm(),
4459 (vertices[2] - vertices[0]).norm(),
4460 (vertices[4] - vertices[3]).norm(),
4461 (vertices[5] - vertices[4]).norm(),
4462 (vertices[5] - vertices[3]).norm()});
4463 else if (reference_cell == ReferenceCells::Hexahedron)
4464 // Return the longest of the four diagonals of the hexahedron
4465 return std::max({(vertices[7] - vertices[0]).norm(),
4466 (vertices[6] - vertices[1]).norm(),
4467 (vertices[2] - vertices[5]).norm(),
4468 (vertices[3] - vertices[4]).norm()});
4469
4471 return -1e10;
4472 }
4473 } // namespace TriaAccessorImplementation
4474} // namespace internal
4475
4476
4477/*--------------------- Functions: TriaAccessorBase -------------------------*/
4478
4479template <int structdim, int dim, int spacedim>
4481 const Triangulation<dim, spacedim> *tria,
4482 const int level,
4483 const int index,
4484 const AccessorData *)
4485 : internal::TriaAccessorImplementation::LevelAccessor<dim == structdim>(
4486 (structdim == dim) ? level : 0)
4487 , present_index(index)
4488 , tria(tria)
4489{
4490 // non-cells have no level, so a 0 should have been passed, or a -1 for an
4491 // end-iterator, or -2 for an invalid (default constructed) iterator
4492 if (structdim != dim)
4493 Assert((level == 0) || (level == -1) || (level == -2), ExcInternalError());
4494}
4495
4496
4497template <int structdim, int dim, int spacedim>
4500 : internal::TriaAccessorImplementation::LevelAccessor<dim == structdim>(
4501 a.level())
4502 , present_index(a.present_index)
4503 , tria(a.tria)
4504{}
4505
4506
4507template <int structdim, int dim, int spacedim>
4508inline void
4511{
4512 this->set_level(a.level());
4513 present_index = a.present_index;
4514 tria = a.tria;
4515
4516 if (structdim != dim)
4517 Assert(level() == 0, ExcInternalError());
4518}
4519
4520
4521
4522template <int structdim, int dim, int spacedim>
4526{
4527 this->set_level(a.level());
4528 present_index = a.present_index;
4529 tria = a.tria;
4530
4531 if (structdim != dim)
4532 Assert(level() == 0, ExcInternalError());
4533 return *this;
4534}
4535
4536
4537
4538template <int structdim, int dim, int spacedim>
4539inline bool
4542{
4543 Assert(tria == a.tria || tria == nullptr || a.tria == nullptr,
4545 return ((tria == a.tria) && (level() == a.level()) &&
4546 (present_index == a.present_index));
4547}
4548
4549
4550
4551template <int structdim, int dim, int spacedim>
4552inline bool
4555{
4556 Assert(tria == a.tria || tria == nullptr || a.tria == nullptr,
4558 return ((tria != a.tria) || (level() != a.level()) ||
4559 (present_index != a.present_index));
4560}
4561
4562
4563
4564template <int structdim, int dim, int spacedim>
4565inline bool
4568{
4570
4571 if (level() != other.level())
4572 return (level() < other.level());
4573
4574 return (present_index < other.present_index);
4575}
4576
4577
4578
4579template <int structdim, int dim, int spacedim>
4580inline int
4582{
4583 // This is always zero or invalid
4584 // if the object is not a cell
4585 return this->get_level();
4586}
4587
4588
4589
4590template <int structdim, int dim, int spacedim>
4591inline int
4593{
4594 return present_index;
4595}
4596
4597
4598
4599template <int structdim, int dim, int spacedim>
4602{
4603 if ((level() >= 0) && (present_index >= 0))
4604 return IteratorState::valid;
4605 else if (present_index == -1)
4607 else
4609}
4610
4611
4612
4613template <int structdim, int dim, int spacedim>
4614inline const Triangulation<dim, spacedim> &
4616{
4617 return *tria;
4618}
4619
4620
4621
4622template <int structdim, int dim, int spacedim>
4623inline void
4625{
4626 // this iterator is used for
4627 // objects without level
4628 ++this->present_index;
4629
4630 if (structdim != dim)
4631 {
4632 // is index still in the range of
4633 // the vector? (note that we don't
4634 // have to set the level, since
4635 // dim!=1 and the object therefore
4636 // has no level)
4637 if (this->present_index >= static_cast<int>(objects().n_objects()))
4638 this->present_index = -1;
4639 }
4640 else
4641 {
4642 while (this->present_index >=
4643 static_cast<int>(this->tria->levels[level()]->cells.n_objects()))
4644 {
4645 // no -> go one level up until we find
4646 // one with more than zero cells
4647 this->set_level(level() + 1);
4648 this->present_index = 0;
4649 // highest level reached?
4650 if (level() >= static_cast<int>(this->tria->levels.size()))
4651 {
4652 // return with past the end pointer
4653 this->set_level(-1);
4654 this->present_index = -1;
4655 return;
4656 }
4657 }
4658 }
4659}
4660
4661
4662template <int structdim, int dim, int spacedim>
4663inline void
4665{
4666 // same as operator++
4667 --this->present_index;
4668
4669 if (structdim != dim)
4670 {
4671 if (this->present_index < 0)
4672 this->present_index = -1;
4673 }
4674 else
4675 {
4676 while (this->present_index < 0)
4677 {
4678 // no -> go one level down
4679 this->set_level(level() - 1);
4680 // lowest level reached?
4681 if (level() == -1)
4682 {
4683 // return with past the end pointer
4684 this->set_level(-1);
4685 this->present_index = -1;
4686 return;
4687 }
4688 // else
4689 this->present_index =
4690 this->tria->levels[level()]->cells.n_objects() - 1;
4691 }
4692 }
4693}
4694
4695
4696
4697template <int structdim, int dim, int spacedim>
4698inline ::internal::TriangulationImplementation::TriaObjects &
4700{
4701 if (structdim == dim)
4702 return this->tria->levels[level()]->cells;
4703
4704 if (structdim == 1 && dim > 1)
4705 return this->tria->faces->lines;
4706
4707 if (structdim == 2 && dim > 2)
4708 return this->tria->faces->quads;
4709
4711
4712 return this->tria->levels[level()]->cells;
4713}
4714
4715
4716
4717/*---------------------- Functions: InvalidAccessor -------------------------*/
4718
4719template <int structdim, int dim, int spacedim>
4721 const int,
4722 const int,
4723 const AccessorData *)
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>
4737 const InvalidAccessor &)
4738{
4739 Assert(false,
4740 ExcMessage("You are attempting an invalid conversion between "
4741 "iterator/accessor types. The constructor you call "
4742 "only exists to make certain template constructs "
4743 "easier to write as dimension independent code but "
4744 "the conversion is not valid in the current context."));
4745}
4746
4747
4748
4749template <int structdim, int dim, int spacedim>
4750void
4752{
4753 // nothing to do here. we could throw an exception but we can't get here
4754 // without first creating an object which would have already thrown.
4755}
4756
4757
4758
4759template <int structdim, int dim, int spacedim>
4760bool
4762 const InvalidAccessor &) const
4763{
4764 // nothing to do here. we could throw an exception but we can't get here
4765 // without first creating an object which would have already thrown.
4766 return false;
4767}
4768
4769
4770
4771template <int structdim, int dim, int spacedim>
4772bool
4774 const InvalidAccessor &) const
4775{
4776 // nothing to do here. we could throw an exception but we can't get here
4777 // without first creating an object which would have already thrown.
4778 return true;
4779}
4780
4781
4782
4783template <int structdim, int dim, int spacedim>
4784bool
4786{
4787 // nothing to do here. we could throw an exception but we can't get here
4788 // without first creating an object which would have already thrown.
4789 return false;
4790}
4791
4792
4793
4794template <int structdim, int dim, int spacedim>
4795bool
4797{
4798 // nothing to do here. we could throw an exception but we can't get here
4799 // without first creating an object which would have already thrown.
4800 return false;
4801}
4802
4803
4804
4805template <int structdim, int dim, int spacedim>
4806void
4808{}
4809
4810
4811
4812template <int structdim, int dim, int spacedim>
4813void
4815{}
4816
4817
4818
4819template <int structdim, int dim, int spacedim>
4822{
4824}
4825
4826
4827
4828template <int structdim, int dim, int spacedim>
4829unsigned int
4831{
4833}
4834
4835
4836
4837template <int structdim, int dim, int spacedim>
4838void
4840 const unsigned int) const
4841{
4842 Assert(false,
4843 ExcMessage("You are trying to set the user index of an "
4844 "invalid object."));
4845}
4846
4847
4848
4849template <int structdim, int dim, int spacedim>
4850void
4852 const types::manifold_id) const
4853{
4854 Assert(false,
4855 ExcMessage("You are trying to set the manifold id of an "
4856 "invalid object."));
4857}
4858
4859
4860
4861template <int structdim, int dim, int spacedim>
4862inline Point<spacedim> &
4864{
4865 // nothing to do here. we could throw an exception but we can't get here
4866 // without first creating an object which would have already thrown
4867 static Point<spacedim> invalid_vertex;
4868 return invalid_vertex;
4869}
4870
4871
4872template <int structdim, int dim, int spacedim>
4873inline void *
4875{
4876 // nothing to do here. we could throw an exception but we can't get here
4877 // without first creating an object which would have already thrown
4878 return nullptr;
4879}
4880
4881
4882
4883template <int structdim, int dim, int spacedim>
4884inline void *
4886{
4887 // nothing to do here. we could throw an exception but we can't get here
4888 // without first creating an object which would have already thrown
4889 return nullptr;
4890}
4891
4892
4893/*------------------------ Functions: TriaAccessor ---------------------------*/
4894
4895
4896namespace internal
4897{
4899 {
4900 // make sure that if in the following we write TriaAccessor we mean the
4901 // *class* ::TriaAccessor, not the enclosing namespace
4902 // ::internal::TriaAccessor
4903 using ::TriaAccessor;
4904
4909 struct Implementation
4910 {
4911 template <int dim, int spacedim>
4912 static std::array<unsigned int, 1>
4913 get_line_indices_of_cell(const TriaAccessor<1, dim, spacedim> &)
4914 {
4916 return {};
4917 }
4918
4919
4920
4921 template <int structdim, int dim, int spacedim>
4922 static std::array<unsigned int, 4>
4923 get_line_indices_of_cell(const TriaAccessor<2, dim, spacedim> &cell)
4924 {
4925 // For 2d cells the access cell->line_orientation() is already
4926 // efficient
4927 std::array<unsigned int, 4> line_indices = {};
4928 for (const unsigned int line : cell.line_indices())
4929 line_indices[line] = cell.line_index(line);
4930 return line_indices;
4931 }
4932
4937 template <int structdim, int dim, int spacedim>
4938 static std::array<unsigned int, 12>
4939 get_line_indices_of_cell(
4940 const TriaAccessor<structdim, dim, spacedim> &cell)
4941 {
4942 std::array<unsigned int, 12> line_indices = {};
4943
4944 // For hexahedra, the classical access via quads -> lines is too
4945 // inefficient. Unroll this code here to allow the compiler to inline
4946 // the necessary functions.
4947 const auto ref_cell = cell.reference_cell();
4948 if (ref_cell == ReferenceCells::Hexahedron)
4949 {
4950 for (unsigned int f = 4; f < 6; ++f)
4951 {
4952 const auto orientation = cell.combined_face_orientation(f);
4953
4954 // It might seem superfluous to spell out the four indices
4955 // that get later consumed by a for loop over these four
4956 // elements; however, for the compiler it is easier to inline
4957 // the statement of standard_to_real_face_line() when next to
4958 // each other, as opposed to be interleaved with a
4959 // line_index() call.
4960 const std::array<unsigned int, 4> my_indices{
4961 {ref_cell.standard_to_real_face_line(0, f, orientation),
4962 ref_cell.standard_to_real_face_line(1, f, orientation),
4963 ref_cell.standard_to_real_face_line(2, f, orientation),
4964 ref_cell.standard_to_real_face_line(3, f, orientation)}};
4965 const auto quad = cell.quad(f);
4966 for (unsigned int l = 0; l < 4; ++l)
4967 line_indices[4 * (f - 4) + l] =
4968 quad->line_index(my_indices[l]);
4969 }
4970 for (unsigned int f = 0; f < 2; ++f)
4971 {
4972 const auto orientation =
4973 cell.get_triangulation()
4974 .levels[cell.level()]
4975 ->face_orientations.get_combined_orientation(cell.index(),
4976 f);
4977 const std::array<unsigned int, 2> my_indices{
4978 {ref_cell.standard_to_real_face_line(0, f, orientation),
4979 ref_cell.standard_to_real_face_line(1, f, orientation)}};
4980 const auto quad = cell.quad(f);
4981 line_indices[8 + f] = quad->line_index(my_indices[0]);
4982 line_indices[10 + f] = quad->line_index(my_indices[1]);
4983 }
4984 }
4985 else if (ref_cell == ReferenceCells::Tetrahedron)
4986 {
4987 std::array<unsigned int, 3> orientations{
4990 cell.combined_face_orientation(2)}};
4991 const std::array<unsigned int, 6> my_indices{
4992 {ref_cell.standard_to_real_face_line(0, 0, orientations[0]),
4993 ref_cell.standard_to_real_face_line(1, 0, orientations[0]),
4994 ref_cell.standard_to_real_face_line(2, 0, orientations[0]),
4995 ref_cell.standard_to_real_face_line(1, 1, orientations[1]),
4996 ref_cell.standard_to_real_face_line(2, 1, orientations[1]),
4997 ref_cell.standard_to_real_face_line(1, 2, orientations[2])}};
4998 line_indices[0] = cell.quad(0)->line_index(my_indices[0]);
4999 line_indices[1] = cell.quad(0)->line_index(my_indices[1]);
5000 line_indices[2] = cell.quad(0)->line_index(my_indices[2]);
5001 line_indices[3] = cell.quad(1)->line_index(my_indices[3]);
5002 line_indices[4] = cell.quad(1)->line_index(my_indices[4]);
5003 line_indices[5] = cell.quad(2)->line_index(my_indices[5]);
5004 }
5005 else
5006 // For other shapes (wedges, pyramids), we do not currently
5007 // implement an optimized function.
5008 for (unsigned int l = 0; l < std::min(12U, cell.n_lines()); ++l)
5009 line_indices[l] = cell.line_index(l);
5010
5011 return line_indices;
5012 }
5013
5014
5015
5020 template <int dim, int spacedim>
5021 static std::array<types::geometric_orientation, 1>
5022 get_line_orientations_of_cell(const TriaAccessor<1, dim, spacedim> &)
5023 {
5025 return {};
5026 }
5027
5028
5029
5034 template <int dim, int spacedim>
5035 static std::array<types::geometric_orientation, 4>
5036 get_line_orientations_of_cell(const TriaAccessor<2, dim, spacedim> &cell)
5037 {
5038 // For 2d cells the access cell->line_orientation() is already
5039 // efficient
5040 std::array<types::geometric_orientation, 4> line_orientations = {};
5041 for (const unsigned int line : cell.line_indices())
5042 line_orientations[line] = cell.line_orientation(line);
5043 return line_orientations;
5044 }
5045
5046
5047
5052 template <int dim, int spacedim>
5053 static std::array<types::geometric_orientation, 12>
5054 get_line_orientations_of_cell(const TriaAccessor<3, dim, spacedim> &cell)
5055 {
5056 std::array<types::geometric_orientation, 12> line_orientations = {};
5057
5058 // For hexahedra, the classical access via quads -> lines is too
5059 // inefficient. Unroll this code here to allow the compiler to inline
5060 // the necessary functions.
5061 const auto ref_cell = cell.reference_cell();
5062 if (ref_cell == ReferenceCells::Hexahedron)
5063 {
5064 for (unsigned int f = 4; f < 6; ++f)
5065 {
5066 const auto orientation =
5067 cell.get_triangulation()
5068 .levels[cell.level()]
5069 ->face_orientations.get_combined_orientation(cell.index(),
5070 f);
5071
5072 // It might seem superfluous to spell out the four indices and
5073 // orientations that get later consumed by a for loop over
5074 // these four elements; however, for the compiler it is easier
5075 // to inline the statement of standard_to_real_face_line()
5076 // when next to each other, as opposed to be interleaved with
5077 // a line_index() call.
5078 const std::array<unsigned int, 4> my_indices{
5079 {ref_cell.standard_to_real_face_line(0, f, orientation),
5080 ref_cell.standard_to_real_face_line(1, f, orientation),
5081 ref_cell.standard_to_real_face_line(2, f, orientation),
5082 ref_cell.standard_to_real_face_line(3, f, orientation)}};
5083 const auto quad = cell.quad(f);
5084 const std::array<types::geometric_orientation, 4>
5085 my_orientations{{ref_cell.face_to_cell_line_orientation(
5086 0,
5087 f,
5088 orientation,
5089 quad->line_orientation(my_indices[0])),
5090 ref_cell.face_to_cell_line_orientation(
5091 1,
5092 f,
5093 orientation,
5094 quad->line_orientation(my_indices[1])),
5095 ref_cell.face_to_cell_line_orientation(
5096 2,
5097 f,
5098 orientation,
5099 quad->line_orientation(my_indices[2])),
5100 ref_cell.face_to_cell_line_orientation(
5101 3,
5102 f,
5103 orientation,
5104 quad->line_orientation(my_indices[3]))}};
5105 for (unsigned int l = 0; l < 4; ++l)
5106 line_orientations[4 * (f - 4) + l] = my_orientations[l];
5107 }
5108 for (unsigned int f = 0; f < 2; ++f)
5109 {
5110 const auto orientation =
5111 cell.get_triangulation()
5112 .levels[cell.level()]
5113 ->face_orientations.get_combined_orientation(cell.index(),
5114 f);
5115 const std::array<unsigned int, 2> 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 const auto quad = cell.quad(f);
5119 const std::array<types::geometric_orientation, 2>
5120 my_orientations{{ref_cell.face_to_cell_line_orientation(
5121 0,
5122 f,
5123 orientation,
5124 quad->line_orientation(my_indices[0])),
5125 ref_cell.face_to_cell_line_orientation(
5126 1,
5127 f,
5128 orientation,
5129 quad->line_orientation(my_indices[1]))}};
5130 line_orientations[8 + f] = my_orientations[0];
5131 line_orientations[10 + f] = my_orientations[1];
5132 }
5133 }
5134 else if (ref_cell == ReferenceCells::Tetrahedron)
5135 {
5136 std::array<unsigned int, 3> orientations{
5139 cell.combined_face_orientation(2)}};
5140 const std::array<unsigned int, 6> my_indices{
5141 {ref_cell.standard_to_real_face_line(0, 0, orientations[0]),
5142 ref_cell.standard_to_real_face_line(1, 0, orientations[0]),
5143 ref_cell.standard_to_real_face_line(2, 0, orientations[0]),
5144 ref_cell.standard_to_real_face_line(1, 1, orientations[1]),
5145 ref_cell.standard_to_real_face_line(2, 1, orientations[1]),
5146 ref_cell.standard_to_real_face_line(1, 2, orientations[2])}};
5147 line_orientations[0] = ref_cell.face_to_cell_line_orientation(
5148 0,
5149 0,
5150 orientations[0],
5151 cell.quad(0)->line_orientation(my_indices[0]));
5152 line_orientations[1] = ref_cell.face_to_cell_line_orientation(
5153 1,
5154 0,
5155 orientations[0],
5156 cell.quad(0)->line_orientation(my_indices[1]));
5157 line_orientations[2] = ref_cell.face_to_cell_line_orientation(
5158 2,
5159 0,
5160 orientations[0],
5161 cell.quad(0)->line_orientation(my_indices[2]));
5162 line_orientations[3] = ref_cell.face_to_cell_line_orientation(
5163 1,
5164 1,
5165 orientations[1],
5166 cell.quad(1)->line_orientation(my_indices[3]));
5167 line_orientations[4] = ref_cell.face_to_cell_line_orientation(
5168 2,
5169 1,
5170 orientations[1],
5171 cell.quad(1)->line_orientation(my_indices[4]));
5172 line_orientations[5] = ref_cell.face_to_cell_line_orientation(
5173 1,
5174 2,
5175 orientations[2],
5176 cell.quad(2)->line_orientation(my_indices[5]));
5177 }
5178 else
5179 // For other shapes (wedges, pyramids), we do not currently implement
5180 // an optimized function
5181 for (unsigned int l = 0; l < std::min(12U, cell.n_lines()); ++l)
5182 line_orientations[l] = cell.line_orientation(l);
5183
5184 return line_orientations;
5185 }
5186 };
5187 } // namespace TriaAccessorImplementation
5188} // namespace internal
5189
5190
5191
5192template <int structdim, int dim, int spacedim>
5194 const Triangulation<dim, spacedim> *parent,
5195 const int level,
5196 const int index,
5197 const AccessorData *local_data)
5198 : TriaAccessorBase<structdim, dim, spacedim>(parent, level, index, local_data)
5199{}
5200
5201
5202
5203template <int structdim, int dim, int spacedim>
5204inline bool
5206{
5207 Assert(this->state() == IteratorState::valid,
5209 *this));
5210 return this->objects().used[this->present_index];
5211}
5212
5213
5214
5215template <int structdim, int dim, int spacedim>
5218 const unsigned int i) const
5219{
5221 0,
5222 vertex_index(i));
5223}
5224
5225
5226
5227template <int structdim, int dim, int spacedim>
5230{
5231 if constexpr (structdim == 0)
5233 else if constexpr (structdim == 1)
5234 return ReferenceCells::Line;
5235 else if constexpr (structdim == dim)
5236 return this->tria->levels[this->level()]
5237 ->reference_cell[this->present_index];
5238 else
5239 return this->tria->faces->get_quad_type(this->present_index);
5240}
5241
5242
5243
5244template <int structdim, int dim, int spacedim>
5245inline unsigned int
5247 const unsigned int vertex_no) const
5248{
5249 AssertIndexRange(vertex_no, this->n_vertices());
5250
5251 if constexpr (structdim == 1)
5252 {
5253 // This branch needs to be first (and not combined with the structdim ==
5254 // dim branch) so that we can get line vertex indices when setting up the
5255 // cell vertex index cache
5256 return this->objects().get_bounding_object(this->present_index,
5257 vertex_no);
5258 }
5259 else if constexpr (structdim == dim)
5260 {
5261 // This branch should only be used after the cell vertex index cache is
5262 // set up
5263 const auto vertex_index =
5264 this->tria->levels[this->level()]->cached_vertex_index(
5265 this->present_index, vertex_no);
5266 Assert(
5267 vertex_index != numbers::invalid_unsigned_int,
5268 ExcMessage(
5269 "The present vertex's vertex_index is not valid. This is typically "
5270 "caused by calling cell->vertex_index() during grid refinement for "
5271 "a newly created cell, since the cell vertex index cache is not "
5272 "complete at that point."));
5273 return vertex_index;
5274 }
5275 else if constexpr (structdim == 2)
5276 {
5277 const auto [line_index, vertex_index] =
5278 this->reference_cell().standard_vertex_to_face_and_vertex_index(
5279 vertex_no);
5280 const auto vertex_within_line_index =
5281 this->reference_cell().standard_to_real_face_vertex(
5282 vertex_index, line_index, this->line_orientation(line_index));
5283
5284 return this->line(line_index)->vertex_index(vertex_within_line_index);
5285 }
5286 else
5287 {
5290 }
5291}
5292
5293
5294
5295template <int structdim, int dim, int spacedim>
5296inline Point<spacedim> &
5297TriaAccessor<structdim, dim, spacedim>::vertex(const unsigned int i) const
5298{
5299 return const_cast<Point<spacedim> &>(this->tria->vertices[vertex_index(i)]);
5300}
5301
5302
5303
5304template <int structdim, int dim, int spacedim>
5305inline typename ::internal::TriangulationImplementation::
5306 Iterators<dim, spacedim>::line_iterator
5307 TriaAccessor<structdim, dim, spacedim>::line(const unsigned int i) const
5308{
5309 // checks happen in line_index
5310 return typename ::internal::TriangulationImplementation::
5311 Iterators<dim, spacedim>::line_iterator(this->tria, 0, line_index(i));
5312}
5313
5314
5315
5316template <int structdim, int dim, int spacedim>
5317inline unsigned int
5319{
5320 (void)i;
5321 AssertIndexRange(i, this->n_lines());
5322 Assert(structdim != 1,
5323 ExcMessage("You can't ask for the index of a line bounding a "
5324 "one-dimensional cell because it is not bounded by "
5325 "lines."));
5326
5327 if constexpr (structdim == 2)
5328 {
5329 return this->objects().get_bounding_object(this->present_index, i);
5330 }
5331 else if constexpr (structdim == 3)
5332 {
5333 const auto [face_index, line_index] =
5334 this->reference_cell().standard_line_to_face_and_line_index(i);
5335 const auto line_within_face_index =
5336 this->reference_cell().standard_to_real_face_line(
5337 line_index, face_index, this->combined_face_orientation(face_index));
5338
5339 return this->quad(face_index)->line_index(line_within_face_index);
5340 }
5341
5344}
5345
5346
5347
5348template <int structdim, int dim, int spacedim>
5349inline typename ::internal::TriangulationImplementation::
5350 Iterators<dim, spacedim>::quad_iterator
5351 TriaAccessor<structdim, dim, spacedim>::quad(const unsigned int i) const
5352{
5353 // checks happen in quad_index
5354 return typename ::internal::TriangulationImplementation::
5355 Iterators<dim, spacedim>::quad_iterator(this->tria, 0, quad_index(i));
5356}
5357
5358
5359
5360template <int structdim, int dim, int spacedim>
5361inline unsigned int
5363 const unsigned int face_no) const
5364{
5365 Assert(structdim == 3,
5366 ExcMessage("You can't ask for the index of a quad bounding "
5367 "a one- or two-dimensional cell because it is not "
5368 "bounded by quads."));
5369 // work around a bogus GCC-9 warning which considers face_no unused except in
5370 // 3d
5371 (void)face_no;
5372 if constexpr (structdim == 3)
5373 return this->objects().get_bounding_object(this->present_index, face_no);
5374 else
5376}
5377
5378
5379
5380template <int structdim, int dim, int spacedim>
5383 const unsigned int face) const
5384{
5386 AssertIndexRange(face, n_faces());
5387 Assert(structdim == dim,
5388 ExcMessage("This function can only be used on objects "
5389 "that are cells, but not on faces or edges "
5390 "that bound cells."));
5391 // work around a bogus GCC-9 warning which considers face unused except in 3d
5392 (void)face;
5393
5394 if constexpr (structdim == 1)
5396 else if constexpr (structdim == 2)
5397 {
5398 // if all elements are quads (or if we have a very special consistently
5399 // oriented triangular mesh) then we do not store this array
5400 if (this->tria->levels[this->level()]->face_orientations.n_objects() == 0)
5402 else
5403 return this->tria->levels[this->level()]
5404 ->face_orientations.get_combined_orientation(this->present_index,
5405 face);
5406 }
5407 else
5408 return this->tria->levels[this->level()]
5409 ->face_orientations.get_combined_orientation(this->present_index, face);
5410}
5411
5412
5413
5414template <int structdim, int dim, int spacedim>
5415inline bool
5417 const unsigned int face) const
5418{
5420 AssertIndexRange(face, n_faces());
5421 Assert(structdim == dim,
5422 ExcMessage("This function can only be used on objects "
5423 "that are cells, but not on faces or edges "
5424 "that bound cells."));
5425 // work around a bogus GCC-9 warning which considers face unused in 1d
5426 (void)face;
5427
5428 if constexpr (structdim == 1)
5429 // in 1d 'faces' are vertices and those are always consistently oriented
5430 return true;
5431 else if constexpr (structdim == 2)
5432 return this->line_orientation(face) ==
5434 else
5435 return this->tria->levels[this->level()]->face_orientations.get_orientation(
5436 this->present_index, face);
5437}
5438
5439
5440
5441template <int structdim, int dim, int spacedim>
5442inline bool
5443TriaAccessor<structdim, dim, spacedim>::face_flip(const unsigned int face) const
5444{
5446 Assert(structdim == dim,
5447 ExcMessage("This function can only be used on objects "
5448 "that are cells, but not on faces or edges "
5449 "that bound cells."));
5450 AssertIndexRange(face, n_faces());
5451 // work around a bogus GCC-9 warning which considers face unused except in 3d
5452 (void)face;
5453
5454 if constexpr (structdim == 3)
5455 return this->tria->levels[this->level()]->face_orientations.get_flip(
5456 this->present_index, face);
5457 else
5458 // In 1d and 2d, face_flip is always false as faces can only be
5459 // 'flipped' in 3d.
5460 return false;
5461}
5462
5463
5464template <int structdim, int dim, int spacedim>
5465inline bool
5467 const unsigned int face) const
5468{
5470 Assert(structdim == dim,
5471 ExcMessage("This function can only be used on objects "
5472 "that are cells, but not on faces or edges "
5473 "that bound cells."));
5474 AssertIndexRange(face, n_faces());
5475 // work around a bogus GCC-9 warning which considers face unused except in 3d
5476 (void)face;
5477
5478 if constexpr (structdim == 3)
5479 return this->tria->levels[this->level()]->face_orientations.get_rotation(
5480 this->present_index, face);
5481 else
5482 // In 1d and 2d, face_rotation is always false as faces can only be
5483 // 'rotated' in 3d.
5484 return false;
5485}
5486
5487
5488
5489template <int structdim, int dim, int spacedim>
5492 const unsigned int line) const
5493{
5495 AssertIndexRange(line, this->n_lines());
5496 // work around a bogus GCC-9 warning which considers line unused in 1d
5497 (void)line;
5498
5499 if constexpr (structdim == 1)
5501 else if constexpr (structdim == 2 && dim == 2)
5502 // lines in 2d are faces
5503 {
5504 const auto combined_orientation = combined_face_orientation(line);
5505 Assert(combined_orientation == numbers::default_geometric_orientation ||
5506 combined_orientation == numbers::reverse_line_orientation,
5508 return combined_orientation;
5509 }
5510 else if constexpr (structdim == 2 && dim == 3)
5511 {
5512 return this->tria->faces->get_line_orientation(this->present_index, line);
5513 }
5514 else if constexpr (structdim == 3 && dim == 3)
5515 {
5516 const auto reference_cell = this->reference_cell();
5517 // First pick a face on which this line is a part of, and the
5518 // index of the line within.
5519 const auto [face_index, line_index] =
5520 reference_cell.standard_line_to_face_and_line_index(line);
5521 const auto line_within_face_index =
5522 reference_cell.standard_to_real_face_line(
5523 line_index, face_index, this->combined_face_orientation(face_index));
5524
5525 // Then query how that line is oriented within that face:
5526 return reference_cell.face_to_cell_line_orientation(
5527 line_index,
5528 face_index,
5529 this->combined_face_orientation(face_index),
5530 this->quad(face_index)->line_orientation(line_within_face_index));
5531 }
5532 else
5533 {
5536 }
5537}
5538
5539
5540
5541template <int structdim, int dim, int spacedim>
5542inline void
5544 const unsigned int line,
5546{
5548 AssertIndexRange(line, this->n_lines());
5549 Assert(dim != 1,
5550 ExcMessage("In 1d lines are cells and thus do not need to have their "
5551 "orientations set."));
5552 Assert(dim != 2,
5553 ExcMessage("In 2d lines are faces, and, for compatibility with other "
5554 "dimensions, their orientations should be set via "
5555 "set_combined_face_orientation()."));
5556 // work around a bogus GCC-9 warning which considers line and value unused
5557 // except in 3d
5558 (void)line;
5559 (void)value;
5560
5561 if constexpr (dim == 3)
5562 {
5563 // We set line orientations per face, not per cell, so this only works for
5564 // faces in 3d.
5565 Assert(structdim == 2, ExcNotImplemented());
5566 this->tria->faces->set_line_orientation(this->present_index, line, value);
5567 }
5568}
5569
5570
5571
5572template <int structdim, int dim, int spacedim>
5573inline void
5575 const unsigned int face_no,
5576 const types::geometric_orientation combined_orientation) const
5577{
5579 AssertIndexRange(face_no, this->n_faces());
5580 Assert(structdim == dim,
5581 ExcMessage("This function can only be used on objects that are cells "
5582 "and not on objects which bound cells."));
5583 AssertIndexRange(combined_orientation,
5584 reference_cell().n_face_orientations(face_no));
5585
5586 // face_orientations is not set up in 1d
5587 if (dim > 1)
5588 this->tria->levels[this->level()]
5589 ->face_orientations.set_combined_orientation(this->present_index,
5590 face_no,
5591 combined_orientation);
5592}
5593
5594
5595
5596template <int structdim, int dim, int spacedim>
5597void
5599{
5600 Assert(this->state() == IteratorState::valid,
5602 *this));
5603 this->objects().used[this->present_index] = true;
5604}
5605
5606
5607
5608template <int structdim, int dim, int spacedim>
5609void
5611{
5612 Assert(this->state() == IteratorState::valid,
5614 *this));
5615 this->objects().used[this->present_index] = false;
5616}
5617
5618
5619template <int structdim, int dim, int spacedim>
5620int
5622{
5624 AssertIndexRange(i, n_children());
5625
5626 // each set of two children are stored
5627 // consecutively, so we only have to find
5628 // the location of the set of children
5629 const auto &objects = this->objects();
5630 const unsigned int n_sets_of_two = objects.children_per_object / 2;
5631 return objects.children[n_sets_of_two * this->present_index + i / 2] + i % 2;
5632}
5633
5634
5635
5636template <int structdim, int dim, int spacedim>
5637int
5639 const unsigned int i) const
5640{
5641 AssertIndexRange(i, this->objects().children_per_object);
5642
5643 switch (structdim)
5644 {
5645 case 1:
5646 return child_index(i);
5647 case 2:
5648 {
5649 const RefinementCase<2> this_refinement_case(
5650 static_cast<std::uint8_t>(refinement_case()));
5651
5652 Assert(this_refinement_case != RefinementCase<2>::no_refinement,
5654
5655 if (this_refinement_case == RefinementCase<2>::cut_xy)
5656 return child_index(i);
5657 else if ((this_refinement_case == RefinementCase<2>::cut_x) &&
5658 (child(i % 2)->refinement_case() ==
5660 return child(i % 2)->child_index(i / 2);
5661 else if ((this_refinement_case == RefinementCase<2>::cut_y) &&
5662 (child(i / 2)->refinement_case() ==
5664 return child(i / 2)->child_index(i % 2);
5665 else
5666 Assert(
5667 false,
5668 ExcMessage(
5669 "This cell has no grandchildren equivalent to isotropic refinement"));
5670 break;
5671 }
5672
5673 case 3:
5675 }
5676 return -1;
5677}
5678
5679
5680
5681template <int structdim, int dim, int spacedim>
5684{
5685 Assert(this->state() == IteratorState::valid,
5687 *this));
5688
5689 switch (structdim)
5690 {
5691 case 1:
5693 this->objects().children[this->present_index] != -1 ?
5694 // cast the branches here first to uchar and then (above) to
5695 // RefinementCase<structdim> so that the conversion is valid even
5696 // for the case structdim>1 (for which this part of the code is dead
5697 // anyway)
5698 static_cast<std::uint8_t>(RefinementCase<1>::cut_x) :
5699 static_cast<std::uint8_t>(RefinementCase<1>::no_refinement)));
5700
5701 default:
5702 Assert(static_cast<unsigned int>(this->present_index) <
5703 this->objects().refinement_cases.size(),
5704 ExcIndexRange(this->present_index,
5705 0,
5706 this->objects().refinement_cases.size()));
5707
5708 return (static_cast<RefinementCase<structdim>>(
5709 this->objects().refinement_cases[this->present_index]));
5710 }
5711}
5712
5713
5714
5715template <int structdim, int dim, int spacedim>
5717TriaAccessor<structdim, dim, spacedim>::child(const unsigned int i) const
5718
5719{
5720 // checking of 'i' happens in child_index
5722 this->tria, (dim == structdim ? this->level() + 1 : 0), child_index(i));
5723
5724 Assert((q.state() == IteratorState::past_the_end) || q->used(),
5726
5727 return q;
5728}
5729
5730
5731
5732template <int structdim, int dim, int spacedim>
5733inline unsigned int
5736{
5737 const auto n_children = this->n_children();
5738 for (unsigned int child_n = 0; child_n < n_children; ++child_n)
5739 if (this->child(child_n) == child)
5740 return child_n;
5741
5742 Assert(false,
5743 ExcMessage("The given child is not a child of the current object."));
5745}
5746
5747
5748
5749template <int structdim, int dim, int spacedim>
5752 const unsigned int i) const
5753{
5754 // checking of 'i' happens in child() or child_index() called below
5755 switch (structdim)
5756 {
5757 case 1:
5758 // no anisotropic refinement in 1d
5759 return child(i);
5760
5761 case 2:
5762 {
5763 const RefinementCase<2> this_refinement_case(
5764 static_cast<std::uint8_t>(refinement_case()));
5765
5766 Assert(this_refinement_case != RefinementCase<2>::no_refinement,
5768
5769 if (this_refinement_case == RefinementCase<2>::cut_xy)
5770 return child(i);
5771 else if ((this_refinement_case == RefinementCase<2>::cut_x) &&
5772 (child(i % 2)->refinement_case() ==
5774 return child(i % 2)->child(i / 2);
5775 else if ((this_refinement_case == RefinementCase<2>::cut_y) &&
5776 (child(i / 2)->refinement_case() ==
5778 return child(i / 2)->child(i % 2);
5779 else
5780 Assert(
5781 false,
5782 ExcMessage(
5783 "This cell has no grandchildren equivalent to isotropic refinement"));
5784 break;
5785 }
5786
5787 default:
5789 }
5790 // we don't get here but have to return
5791 // something...
5792 return child(0);
5793}
5794
5795
5796
5797template <int structdim, int dim, int spacedim>
5798inline bool
5800{
5801 Assert(this->state() == IteratorState::valid,
5803 *this));
5804
5805 // each set of two children are stored consecutively, so we only have to find
5806 // the location of the set of children
5807 const auto &objects = this->objects();
5808 const unsigned int n_sets_of_two = objects.children_per_object / 2;
5809 return (objects.children[n_sets_of_two * this->present_index] != -1);
5810}
5811
5812
5813
5814template <int structdim, int dim, int spacedim>
5815inline unsigned int
5817{
5818 Assert(this->state() == IteratorState::valid,
5820 *this));
5821
5822 return reference_cell().n_children(refinement_case());
5823}
5824
5825
5826
5827template <int structdim, int dim, int spacedim>
5828inline void
5830 const RefinementCase<structdim> &refinement_case) const
5831{
5832 Assert(this->state() == IteratorState::valid,
5834 *this));
5835 Assert(static_cast<unsigned int>(this->present_index) <
5836 this->objects().refinement_cases.size(),
5837 ExcIndexRange(this->present_index,
5838 0,
5839 this->objects().refinement_cases.size()));
5840
5841 this->objects().refinement_cases[this->present_index] = refinement_case;
5842}
5843
5844
5845template <int structdim, int dim, int spacedim>
5846inline void
5848{
5849 Assert(this->state() == IteratorState::valid,
5851 *this));
5852 Assert(static_cast<unsigned int>(this->present_index) <
5853 this->objects().refinement_cases.size(),
5854 ExcIndexRange(this->present_index,
5855 0,
5856 this->objects().refinement_cases.size()));
5857
5858 this->objects().refinement_cases[this->present_index] =
5860}
5861
5862
5863
5864template <int structdim, int dim, int spacedim>
5865void
5867 const int index) const
5868{
5871
5872 // each set of two children are stored consecutively, so we only have to find
5873 // the location of the set of children
5874 auto &objects = this->objects();
5875 const unsigned int n_sets_of_two = objects.children_per_object / 2;
5876 Assert(
5877 // clearing the child index for a cell
5878 (index == -1) ||
5879 // if setting the child index for the i'th child (with i==0), then the
5880 // index must be a non-negative number
5881 (i == 0 && !this->has_children() && (index >= 0)) ||
5882 // if setting the child index for the i'th child (with i>0), then the
5883 // previously stored index must be the invalid index
5884 (i > 0 && this->has_children() && (index >= 0) &&
5885 objects.children[n_sets_of_two * this->present_index + i / 2] == -1),
5887
5888 objects.children[n_sets_of_two * this->present_index + i / 2] = index;
5889}
5890
5891
5892
5893template <int structdim, int dim, int spacedim>
5894void
5896{
5897 // each set of two children are stored consecutively, so we only have to find
5898 // the location of the set of children
5899 const auto &objects = this->objects();
5900 const unsigned int n_sets_of_two = objects.children_per_object / 2;
5901 for (unsigned int i = 0; i < n_sets_of_two; ++i)
5902 set_children(2 * i, -1);
5903}
5904
5905
5906
5907template <int structdim, int dim, int spacedim>
5908inline bool
5910{
5912 return this->objects().user_flags[this->present_index];
5913}
5914
5915
5916
5917template <int structdim, int dim, int spacedim>
5918inline void
5920{
5922 this->objects().user_flags[this->present_index] = true;
5923}
5924
5925
5926
5927template <int structdim, int dim, int spacedim>
5928inline void
5930{
5932 this->objects().user_flags[this->present_index] = false;
5933}
5934
5935
5936
5937template <int structdim, int dim, int spacedim>
5938void
5940{
5941 set_user_flag();
5942
5943 if (this->has_children())
5944 for (unsigned int c = 0; c < this->n_children(); ++c)
5945 this->child(c)->recursively_set_user_flag();
5946}
5947
5948
5949
5950template <int structdim, int dim, int spacedim>
5951void
5953{
5954 clear_user_flag();
5955
5956 if (this->has_children())
5957 for (unsigned int c = 0; c < this->n_children(); ++c)
5958 this->child(c)->recursively_clear_user_flag();
5959}
5960
5961
5962
5963template <int structdim, int dim, int spacedim>
5964void
5966{
5968 this->objects().clear_user_data(this->present_index);
5969}
5970
5971
5972
5973template <int structdim, int dim, int spacedim>
5974void
5976{
5978 this->objects().user_pointer(this->present_index) = p;
5979}
5980
5981
5982
5983template <int structdim, int dim, int spacedim>
5984void
5986{
5988 this->objects().user_pointer(this->present_index) = nullptr;
5989}
5990
5991
5992
5993template <int structdim, int dim, int spacedim>
5994void *
5996{
5998 return this->objects().user_pointer(this->present_index);
5999}
6000
6001
6002
6003template <int structdim, int dim, int spacedim>
6004void
6006 void *p) const
6007{
6008 set_user_pointer(p);
6009
6010 if (this->has_children())
6011 for (unsigned int c = 0; c < this->n_children(); ++c)
6012 this->child(c)->recursively_set_user_pointer(p);
6013}
6014
6015
6016
6017template <int structdim, int dim, int spacedim>
6018void
6020{
6021 clear_user_pointer();
6022
6023 if (this->has_children())
6024 for (unsigned int c = 0; c < this->n_children(); ++c)
6025 this->child(c)->recursively_clear_user_pointer();
6026}
6027
6028
6029
6030template <int structdim, int dim, int spacedim>
6031void
6033 const unsigned int p) const
6034{
6036 this->objects().user_index(this->present_index) = p;
6037}
6038
6039
6040
6041template <int structdim, int dim, int spacedim>
6042void
6044{
6046 this->objects().user_index(this->present_index) = 0;
6047}
6048
6049
6050
6051template <int structdim, int dim, int spacedim>
6052unsigned int
6054{
6056 return this->objects().user_index(this->present_index);
6057}
6058
6059
6060
6061template <int structdim, int dim, int spacedim>
6062void
6064 const unsigned int p) const
6065{
6066 set_user_index(p);
6067
6068 if (this->has_children())
6069 for (unsigned int c = 0; c < this->n_children(); ++c)
6070 this->child(c)->recursively_set_user_index(p);
6071}
6072
6073
6074
6075template <int structdim, int dim, int spacedim>
6076void
6078{
6079 clear_user_index();
6080
6081 if (this->has_children())
6082 for (unsigned int c = 0; c < this->n_children(); ++c)
6083 this->child(c)->recursively_clear_user_index();
6084}
6085
6086
6087
6088template <int structdim, int dim, int spacedim>
6089inline unsigned int
6091{
6092 if (!this->has_children())
6093 return 0;
6094
6095 unsigned int max_depth = 1;
6096 for (unsigned int c = 0; c < n_children(); ++c)
6097 max_depth = std::max(max_depth, child(c)->max_refinement_depth() + 1);
6098 return max_depth;
6099}
6100
6101
6102
6103template <int structdim, int dim, int spacedim>
6104unsigned int
6106{
6107 if (!this->has_children())
6108 return 1;
6109 else
6110 {
6111 unsigned int sum = 0;
6112 for (unsigned int c = 0; c < n_children(); ++c)
6113 sum += this->child(c)->n_active_descendants();
6114 return sum;
6115 }
6116}
6117
6118
6119
6120template <int structdim, int dim, int spacedim>
6123{
6124 Assert(structdim < dim, ExcImpossibleInDim(dim));
6126
6127 return this->objects()
6128 .boundary_or_material_id[this->present_index]
6129 .boundary_id;
6130}
6131
6132
6133
6134template <int structdim, int dim, int spacedim>
6135void
6137 const types::boundary_id boundary_ind) const
6138{
6139 Assert(structdim < dim, ExcImpossibleInDim(dim));
6142 ExcMessage("You are trying to set the boundary_id to an invalid "
6143 "value (numbers::internal_face_boundary_id is reserved)."));
6144 Assert(this->at_boundary(),
6145 ExcMessage("You are trying to set the boundary_id of an "
6146 "internal object, which is not allowed!"));
6147
6148 this->objects().boundary_or_material_id[this->present_index].boundary_id =
6149 boundary_ind;
6150}
6151
6152
6153
6154template <int structdim, int dim, int spacedim>
6155void
6157 const types::boundary_id boundary_ind) const
6158{
6159 Assert(structdim < dim, ExcImpossibleInDim(dim));
6161
6162 this->objects().boundary_or_material_id[this->present_index].boundary_id =
6163 boundary_ind;
6164}
6165
6166
6167
6168template <int structdim, int dim, int spacedim>
6169void
6171 const types::boundary_id boundary_ind) const
6172{
6173 set_boundary_id(boundary_ind);
6174
6175 switch (structdim)
6176 {
6177 case 1:
6178 // 1d objects have no sub-objects where we have to do anything
6179 break;
6180
6181 case 2:
6182 // for boundary quads also set boundary_id of bounding lines
6183 for (unsigned int i = 0; i < this->n_lines(); ++i)
6184 this->line(i)->set_boundary_id(boundary_ind);
6185 break;
6186
6187 default:
6189 }
6190}
6191
6192
6193
6194template <int structdim, int dim, int spacedim>
6195bool
6197{
6198 // error checking is done in boundary_id()
6200}
6201
6202
6203
6204template <int structdim, int dim, int spacedim>
6207{
6209 return this->tria->get_manifold(this->manifold_id());
6210}
6211
6212
6213template <int structdim, int dim, int spacedim>
6216{
6218
6219 return this->objects().manifold_id[this->present_index];
6220}
6221
6222
6223
6224template <int structdim, int dim, int spacedim>
6225void
6227 const types::manifold_id manifold_ind) const
6228{
6230
6231 this->objects().manifold_id[this->present_index] = manifold_ind;
6232}
6233
6234
6235template <int structdim, int dim, int spacedim>
6236void
6238 const types::manifold_id manifold_ind) const
6239{
6240 set_manifold_id(manifold_ind);
6241
6242 if (this->has_children())
6243 for (unsigned int c = 0; c < this->n_children(); ++c)
6244 this->child(c)->set_all_manifold_ids(manifold_ind);
6245
6246 switch (structdim)
6247 {
6248 case 1:
6249 if (dim == 1)
6250 {
6251 (*this->tria->vertex_to_manifold_id_map_1d)[vertex_index(0)] =
6252 manifold_ind;
6253 (*this->tria->vertex_to_manifold_id_map_1d)[vertex_index(1)] =
6254 manifold_ind;
6255 }
6256 break;
6257
6258 case 2:
6259 // for quads/simplices also set manifold_id of bounding lines
6260 for (unsigned int i = 0; i < this->n_lines(); ++i)
6261 this->line(i)->set_manifold_id(manifold_ind);
6262 break;
6263 default:
6265 }
6266}
6267
6268
6269
6270template <int structdim, int dim, int spacedim>
6271double
6273{
6274 boost::container::small_vector<Point<spacedim>,
6275# ifndef _MSC_VER
6277# else
6279# endif
6280 >
6281 vertices(this->n_vertices());
6282
6283 for (unsigned int v = 0; v < vertices.size(); ++v)
6284 vertices[v] = this->vertex(v);
6285
6286 return internal::TriaAccessorImplementation::diameter<structdim, spacedim>(
6287 vertices);
6288}
6289
6290
6291
6292template <int dim, int spacedim>
6293double
6295 const Mapping<dim, spacedim> &mapping) const
6296{
6297 return internal::TriaAccessorImplementation::diameter<dim, spacedim>(
6299 this->tria, this->level(), this->index())));
6300}
6301
6302
6303
6304template <int structdim, int dim, int spacedim>
6305std::pair<Point<spacedim>, double>
6307{
6308 // If the object is one dimensional, the enclosing ball is the initial iterate
6309 // i.e., the ball's center and diameter are the center and the diameter of the
6310 // object.
6311 if (structdim == 1)
6312 return std::make_pair((this->vertex(1) + this->vertex(0)) * 0.5,
6313 (this->vertex(1) - this->vertex(0)).norm() * 0.5);
6314
6315 // The list is_initial_guess_vertex contains bool values and has the same size
6316 // as the number of vertices per object. The entries of
6317 // is_initial_guess_vertex are set true only for those two vertices
6318 // corresponding to the largest diagonal which is being used to construct the
6319 // initial ball. We employ this mask to skip these two vertices while
6320 // enlarging the ball.
6321 std::vector<bool> is_initial_guess_vertex(this->n_vertices());
6322
6323 // First let all the vertices be outside
6324 std::fill(is_initial_guess_vertex.begin(),
6325 is_initial_guess_vertex.end(),
6326 false);
6327
6328 // Get an initial guess by looking at the largest diagonal
6329 Point<spacedim> center;
6330 double radius = 0;
6331
6332 switch (structdim)
6333 {
6334 case 2:
6335 {
6336 const Point<spacedim> p30(this->vertex(3) - this->vertex(0));
6337 const Point<spacedim> p21(this->vertex(2) - this->vertex(1));
6338 if (p30.norm() > p21.norm())
6339 {
6340 center = this->vertex(0) + 0.5 * p30;
6341 radius = p30.norm() / 2.;
6342 is_initial_guess_vertex[3] = true;
6343 is_initial_guess_vertex[0] = true;
6344 }
6345 else
6346 {
6347 center = this->vertex(1) + 0.5 * p21;
6348 radius = p21.norm() / 2.;
6349 is_initial_guess_vertex[2] = true;
6350 is_initial_guess_vertex[1] = true;
6351 }
6352 break;
6353 }
6354 case 3:
6355 {
6356 const Point<spacedim> p70(this->vertex(7) - this->vertex(0));
6357 const Point<spacedim> p61(this->vertex(6) - this->vertex(1));
6358 const Point<spacedim> p25(this->vertex(2) - this->vertex(5));
6359 const Point<spacedim> p34(this->vertex(3) - this->vertex(4));
6360 const std::vector<double> diagonals = {p70.norm(),
6361 p61.norm(),
6362 p25.norm(),
6363 p34.norm()};
6364 const std::vector<double>::const_iterator it =
6365 std::max_element(diagonals.begin(), diagonals.end());
6366 if (it == diagonals.begin())
6367 {
6368 center = this->vertex(0) + 0.5 * p70;
6369 is_initial_guess_vertex[7] = true;
6370 is_initial_guess_vertex[0] = true;
6371 }
6372 else if (it == diagonals.begin() + 1)
6373 {
6374 center = this->vertex(1) + 0.5 * p61;
6375 is_initial_guess_vertex[6] = true;
6376 is_initial_guess_vertex[1] = true;
6377 }
6378 else if (it == diagonals.begin() + 2)
6379 {
6380 center = this->vertex(5) + 0.5 * p25;
6381 is_initial_guess_vertex[2] = true;
6382 is_initial_guess_vertex[5] = true;
6383 }
6384 else
6385 {
6386 center = this->vertex(4) + 0.5 * p34;
6387 is_initial_guess_vertex[3] = true;
6388 is_initial_guess_vertex[4] = true;
6389 }
6390 radius = *it * 0.5;
6391 break;
6392 }
6393 default:
6395 return std::pair<Point<spacedim>, double>();
6396 }
6397
6398 // For each vertex that is found to be geometrically outside the ball
6399 // enlarge the ball so that the new ball contains both the previous ball
6400 // and the given vertex.
6401 for (const unsigned int v : this->vertex_indices())
6402 if (!is_initial_guess_vertex[v])
6403 {
6404 const double distance = center.distance(this->vertex(v));
6405 if (distance > radius)
6406 {
6407 // we found a vertex which is outside of the ball extend it (move
6408 // center and change radius)
6409 const Point<spacedim> pCV(center - this->vertex(v));
6410 radius = (distance + radius) * 0.5;
6411 center = this->vertex(v) + pCV * (radius / distance);
6412
6413 // Now the new ball constructed in this block encloses the vertex
6414 // (v) that was found to be geometrically outside the old ball.
6415 }
6416 }
6417 if constexpr (running_in_debug_mode())
6418 {
6419 bool all_vertices_within_ball = true;
6420
6421 // Set all_vertices_within_ball false if any of the vertices of the object
6422 // are geometrically outside the ball
6423 for (const unsigned int v : this->vertex_indices())
6424 if (center.distance(this->vertex(v)) >
6425 radius + 100. * std::numeric_limits<double>::epsilon())
6426 {
6427 all_vertices_within_ball = false;
6428 break;
6429 }
6430 // If all the vertices are not within the ball throw error
6431 Assert(all_vertices_within_ball, ExcInternalError());
6432 }
6433 return std::make_pair(center, radius);
6434}
6435
6436
6437template <int structdim, int dim, int spacedim>
6438double
6440{
6441 switch (structdim)
6442 {
6443 case 1:
6444 return (this->vertex(1) - this->vertex(0)).norm();
6445 case 2:
6446 case 3:
6447 {
6448 double min = std::numeric_limits<double>::max();
6449 for (const unsigned int i : this->vertex_indices())
6450 for (unsigned int j = i + 1; j < this->n_vertices(); ++j)
6451 min = std::min(min,
6452 (this->vertex(i) - this->vertex(j)) *
6453 (this->vertex(i) - this->vertex(j)));
6454 return std::sqrt(min);
6455 }
6456 default:
6458 return -1e10;
6459 }
6460}
6461
6462
6463template <int structdim, int dim, int spacedim>
6464bool
6467{
6468 // go through the vertices and check... The cell is a translation of the
6469 // previous one in case the distance between the individual vertices in the
6470 // two cell is the same for all the vertices. So do the check by first getting
6471 // the distance on the first vertex, and then checking whether all others have
6472 // the same down to rounding errors (we have to be careful here because the
6473 // calculation of the displacement between one cell and the next can already
6474 // result in the loss of one or two digits), so we choose 1e-12 times the
6475 // distance between the zeroth vertices here.
6476 bool is_translation = true;
6477 const Tensor<1, spacedim> dist = o->vertex(0) - this->vertex(0);
6478 const double tol_square = 1e-24 * dist.norm_square();
6479 for (unsigned int i = 1; i < this->n_vertices(); ++i)
6480 {
6481 const Tensor<1, spacedim> dist_new =
6482 (o->vertex(i) - this->vertex(i)) - dist;
6483 if (dist_new.norm_square() > tol_square)
6484 {
6485 is_translation = false;
6486 break;
6487 }
6488 }
6489 return is_translation;
6490}
6491
6492
6493
6494template <int structdim, int dim, int spacedim>
6495unsigned int
6497{
6498 return this->reference_cell().n_vertices();
6499}
6500
6501
6502
6503template <int structdim, int dim, int spacedim>
6504unsigned int
6506{
6507 return this->reference_cell().n_lines();
6508}
6509
6510
6511
6512template <int structdim, int dim, int spacedim>
6513unsigned int
6515{
6516 Assert(structdim == dim,
6517 ExcMessage("This function can only be used on objects "
6518 "that are cells, but not on faces or edges "
6519 "that bound cells."));
6520
6521 return this->reference_cell().n_faces();
6522}
6523
6524
6525
6526template <int structdim, int dim, int spacedim>
6527std_cxx20::ranges::iota_view<unsigned int, unsigned int>
6529{
6530 return std_cxx20::ranges::iota_view<unsigned int, unsigned int>(0U,
6531 n_vertices());
6532}
6533
6534
6535
6536template <int structdim, int dim, int spacedim>
6537std_cxx20::ranges::iota_view<unsigned int, unsigned int>
6539{
6540 return std_cxx20::ranges::iota_view<unsigned int, unsigned int>(0U,
6541 n_lines());
6542}
6543
6544
6545
6546template <int structdim, int dim, int spacedim>
6547std_cxx20::ranges::iota_view<unsigned int, unsigned int>
6549{
6550 return std_cxx20::ranges::iota_view<unsigned int, unsigned int>(0U,
6551 n_faces());
6552}
6553
6554
6555
6556/*----------------- Functions: TriaAccessor<0,dim,spacedim> -----------------*/
6557
6558template <int dim, int spacedim>
6560 const Triangulation<dim, spacedim> *tria,
6561 const unsigned int vertex_index)
6562 : tria(tria)
6563 , global_vertex_index(vertex_index)
6564{}
6565
6566
6567
6568template <int dim, int spacedim>
6570 const Triangulation<dim, spacedim> *tria,
6571 const int /*level*/,
6572 const int index,
6573 const AccessorData *)
6574 : tria(tria)
6576{}
6577
6578
6579
6580template <int dim, int spacedim>
6581template <int structdim2, int dim2, int spacedim2>
6584 : tria(nullptr)
6586{
6587 Assert(false, ExcImpossibleInDim(0));
6588}
6589
6590
6591
6592template <int dim, int spacedim>
6593template <int structdim2, int dim2, int spacedim2>
6596 : tria(nullptr)
6598{
6599 Assert(false, ExcImpossibleInDim(0));
6600}
6601
6602
6603
6604template <int dim, int spacedim>
6605inline void
6607{
6608 tria = t.tria;
6609 global_vertex_index = t.global_vertex_index;
6610}
6611
6612
6613
6614template <int dim, int spacedim>
6615inline bool
6617 const TriaAccessor<0, dim, spacedim> &other) const
6618{
6620
6621 return (global_vertex_index < other.global_vertex_index);
6622}
6623
6624
6625
6626template <int dim, int spacedim>
6629{
6630 if (global_vertex_index != numbers::invalid_unsigned_int)
6631 return IteratorState::valid;
6632 else
6634}
6635
6636
6637
6638template <int dim, int spacedim>
6639inline int
6641{
6642 return 0;
6643}
6644
6645
6646
6647template <int dim, int spacedim>
6648inline int
6650{
6651 return global_vertex_index;
6652}
6653
6654
6655
6656template <int dim, int spacedim>
6657inline const Triangulation<dim, spacedim> &
6659{
6660 return *tria;
6661}
6662
6663
6664
6665template <int dim, int spacedim>
6666inline void
6668{
6670 if (global_vertex_index >= tria->n_vertices())
6672}
6673
6674
6675
6676template <int dim, int spacedim>
6677inline void
6679{
6680 if (global_vertex_index != numbers::invalid_unsigned_int)
6681 {
6682 if (global_vertex_index != 0)
6684 else
6686 }
6687}
6688
6689
6690
6691template <int dim, int spacedim>
6692inline bool
6694{
6695 const bool result =
6696 ((tria == t.tria) && (global_vertex_index == t.global_vertex_index));
6697
6698 return result;
6699}
6700
6701
6702
6703template <int dim, int spacedim>
6704inline bool
6706{
6707 return !(*this == t);
6708}
6709
6710
6711
6712template <int dim, int spacedim>
6713inline unsigned int
6714TriaAccessor<0, dim, spacedim>::vertex_index(const unsigned int) const
6715{
6716 return global_vertex_index;
6717}
6718
6719
6720
6721template <int dim, int spacedim>
6722inline Point<spacedim> &
6723TriaAccessor<0, dim, spacedim>::vertex(const unsigned int) const
6724{
6725 return const_cast<Point<spacedim> &>(
6726 this->tria->vertices[global_vertex_index]);
6727}
6728
6729
6730
6731template <int dim, int spacedim>
6732inline typename ::internal::TriangulationImplementation::
6733 Iterators<dim, spacedim>::line_iterator
6734 TriaAccessor<0, dim, spacedim>::line(const unsigned int)
6735{
6736 return typename ::internal::TriangulationImplementation::
6737 Iterators<dim, spacedim>::line_iterator();
6738}
6739
6740
6741
6742template <int dim, int spacedim>
6743inline unsigned int
6745{
6746 Assert(false, ExcImpossibleInDim(0));
6748}
6749
6750
6751
6752template <int dim, int spacedim>
6753inline typename ::internal::TriangulationImplementation::
6754 Iterators<dim, spacedim>::quad_iterator
6755 TriaAccessor<0, dim, spacedim>::quad(const unsigned int)
6756{
6757 return typename ::internal::TriangulationImplementation::
6758 Iterators<dim, spacedim>::quad_iterator();
6759}
6760
6761
6762
6763template <int dim, int spacedim>
6764inline unsigned int
6766{
6767 Assert(false, ExcImpossibleInDim(0));
6769}
6770
6771
6772
6773template <int dim, int spacedim>
6774inline double
6776{
6777 return 0.;
6778}
6779
6780
6781
6782template <int dim, int spacedim>
6783inline double
6785{
6786 return 0.;
6787}
6788
6789
6790
6791template <int dim, int spacedim>
6792inline Point<spacedim>
6793TriaAccessor<0, dim, spacedim>::center(const bool, const bool) const
6794{
6795 return this->tria->vertices[global_vertex_index];
6796}
6797
6798
6799
6800template <int dim, int spacedim>
6801inline double
6803{
6804 return 1.0;
6805}
6806
6807
6808
6809template <int dim, int spacedim>
6812 const unsigned int /*face*/)
6813{
6815}
6816
6817
6818
6819template <int dim, int spacedim>
6820inline bool
6821TriaAccessor<0, dim, spacedim>::face_orientation(const unsigned int /*face*/)
6822{
6823 return false;
6824}
6825
6826
6827
6828template <int dim, int spacedim>
6829inline bool
6830TriaAccessor<0, dim, spacedim>::face_flip(const unsigned int /*face*/)
6831{
6832 return false;
6833}
6834
6835
6836
6837template <int dim, int spacedim>
6838inline bool
6839TriaAccessor<0, dim, spacedim>::face_rotation(const unsigned int /*face*/)
6840{
6841 return false;
6842}
6843
6844
6845
6846template <int dim, int spacedim>
6848TriaAccessor<0, dim, spacedim>::line_orientation(const unsigned int /*line*/)
6849{
6851}
6852
6853
6854
6855template <int dim, int spacedim>
6856inline bool
6858{
6859 return false;
6860}
6861
6862
6863
6864template <int dim, int spacedim>
6865inline unsigned int
6867{
6868 return 0;
6869}
6870
6871
6872
6873template <int dim, int spacedim>
6874inline unsigned int
6876{
6877 return 0;
6878}
6879
6880
6881
6882template <int dim, int spacedim>
6883inline unsigned int
6885{
6886 return 0;
6887}
6888
6889
6890
6891template <int dim, int spacedim>
6892inline unsigned int
6895{
6897}
6898
6899
6900
6901template <int dim, int spacedim>
6903TriaAccessor<0, dim, spacedim>::child(const unsigned int)
6904{
6906}
6907
6908
6909
6910template <int dim, int spacedim>
6913{
6915}
6916
6917
6918
6919template <int dim, int spacedim>
6920inline RefinementCase<0>
6922{
6924}
6925
6926
6927
6928template <int dim, int spacedim>
6929inline int
6931{
6932 return -1;
6933}
6934
6935
6936
6937template <int dim, int spacedim>
6938inline int
6940{
6941 return -1;
6942}
6943
6944
6945
6946template <int dim, int spacedim>
6947inline bool
6949{
6950 return tria->vertex_used(global_vertex_index);
6951}
6952
6953
6954
6955/*------------------- Functions: TriaAccessor<0,1,spacedim> -----------------*/
6956
6957template <int spacedim>
6959 const Triangulation<1, spacedim> *tria,
6960 const VertexKind vertex_kind,
6961 const unsigned int vertex_index)
6962 : tria(tria)
6963 , vertex_kind(vertex_kind)
6964 , global_vertex_index(vertex_index)
6965{}
6966
6967
6968
6969template <int spacedim>
6971 const Triangulation<1, spacedim> *tria,
6972 const int level,
6973 const int index,
6974 const AccessorData *)
6975 : tria(tria)
6976 , vertex_kind(interior_vertex)
6978{
6979 // in general, calling this constructor should yield an error -- users should
6980 // instead call the one immediately above. however, if you create something
6981 // like Triangulation<1>::face_iterator() then this calls the default
6982 // constructor of the iterator which calls the accessor with argument list
6983 // (0,-2,-2,0), so in this particular case accept this call and create an
6984 // object that corresponds to the default constructed (invalid) vertex
6985 // accessor
6986 (void)level;
6987 (void)index;
6988 Assert((level == -2) && (index == -2),
6989 ExcMessage(
6990 "This constructor can not be called for face iterators in 1d, "
6991 "except to default-construct iterator objects."));
6992}
6993
6994
6995
6996template <int spacedim>
6997template <int structdim2, int dim2, int spacedim2>
7000 : tria(nullptr)
7001 , vertex_kind(interior_vertex)
7003{
7004 Assert(false, ExcImpossibleInDim(0));
7005}
7006
7007
7008
7009template <int spacedim>
7010template <int structdim2, int dim2, int spacedim2>
7013 : tria(nullptr)
7014 , vertex_kind(interior_vertex)
7016{
7017 Assert(false, ExcImpossibleInDim(0));
7018}
7019
7020
7021
7022template <int spacedim>
7023inline void
7025{
7026 tria = t.tria;
7027 vertex_kind = t.vertex_kind;
7028 global_vertex_index = t.global_vertex_index;
7029}
7030
7031
7032
7033template <int spacedim>
7034inline void
7037{
7038 // We cannot convert from TriaAccessorBase to
7039 // TriaAccessor<0,1,spacedim> because the latter is not derived from
7040 // the former. We should never get here.
7042}
7043
7044
7045
7046template <int spacedim>
7047inline bool
7049 const TriaAccessor<0, 1, spacedim> &other) const
7050{
7052
7053 return (global_vertex_index < other.global_vertex_index);
7054}
7055
7056
7057
7058template <int spacedim>
7061{
7062 return IteratorState::valid;
7063}
7064
7065
7066template <int spacedim>
7067inline int
7069{
7070 return 0;
7071}
7072
7073
7074
7075template <int spacedim>
7076inline int
7078{
7079 return global_vertex_index;
7080}
7081
7082
7083
7084template <int spacedim>
7085inline const Triangulation<1, spacedim> &
7087{
7088 return *tria;
7089}
7090
7091
7092
7093template <int spacedim>
7094inline void
7096{
7098}
7099
7100
7101template <int spacedim>
7102inline void
7104{
7106}
7107
7108
7109
7110template <int spacedim>
7111inline bool
7113{
7114 const bool result =
7115 ((tria == t.tria) && (global_vertex_index == t.global_vertex_index));
7116 // if we point to the same vertex, make sure we know the same about it
7117 if (result == true)
7118 Assert(vertex_kind == t.vertex_kind, ExcInternalError());
7119
7120 return result;
7121}
7122
7123
7124
7125template <int spacedim>
7126inline bool
7128{
7129 return !(*this == t);
7130}
7131
7132
7133
7134template <int spacedim>
7135inline unsigned int
7136TriaAccessor<0, 1, spacedim>::vertex_index(const unsigned int i) const
7137{
7138 AssertIndexRange(i, 1);
7139 (void)i;
7140 return global_vertex_index;
7141}
7142
7143
7144
7145template <int spacedim>
7146inline Point<spacedim> &
7147TriaAccessor<0, 1, spacedim>::vertex(const unsigned int i) const
7148{
7149 AssertIndexRange(i, 1);
7150 (void)i;
7151 return const_cast<Point<spacedim> &>(
7152 this->tria->vertices[global_vertex_index]);
7153}
7154
7155
7156
7157template <int spacedim>
7158inline Point<spacedim>
7160{
7161 return this->tria->vertices[global_vertex_index];
7162}
7163
7164
7165
7166template <int spacedim>
7167inline typename ::internal::TriangulationImplementation::
7168 Iterators<1, spacedim>::line_iterator
7169 TriaAccessor<0, 1, spacedim>::line(const unsigned int)
7170{
7171 return {};
7172}
7173
7174
7175template <int spacedim>
7176inline unsigned int
7178{
7179 Assert(false, ExcImpossibleInDim(0));
7181}
7182
7183
7184template <int spacedim>
7185inline typename ::internal::TriangulationImplementation::
7186 Iterators<1, spacedim>::quad_iterator
7187 TriaAccessor<0, 1, spacedim>::quad(const unsigned int)
7188{
7189 return {};
7190}
7191
7192
7193
7194template <int spacedim>
7195inline unsigned int
7197{
7198 Assert(false, ExcImpossibleInDim(0));
7200}
7201
7202
7203
7204template <int spacedim>
7205inline double
7207{
7208 return 1.0;
7209}
7210
7211
7212
7213template <int spacedim>
7214inline bool
7216{
7217 return vertex_kind != interior_vertex;
7218}
7219
7220
7221template <int spacedim>
7222inline types::boundary_id
7224{
7225 switch (vertex_kind)
7226 {
7227 case left_vertex:
7228 case right_vertex:
7229 {
7231 this->vertex_index()) !=
7232 tria->vertex_to_boundary_id_map_1d->end(),
7234
7235 return (*tria->vertex_to_boundary_id_map_1d)[this->vertex_index()];
7236 }
7237
7238 default:
7240 }
7241}
7242
7243
7244
7245template <int spacedim>
7246inline const Manifold<1, spacedim> &
7248{
7249 return this->tria->get_manifold(this->manifold_id());
7250}
7251
7252
7253
7254template <int spacedim>
7255inline types::manifold_id
7257{
7258 if (tria->vertex_to_manifold_id_map_1d->find(this->vertex_index()) !=
7259 tria->vertex_to_manifold_id_map_1d->end())
7260 return (*tria->vertex_to_manifold_id_map_1d)[this->vertex_index()];
7261 else
7263}
7264
7265
7266template <int spacedim>
7269 const unsigned int /*face*/)
7270{
7272}
7273
7274
7275template <int spacedim>
7276inline bool
7277TriaAccessor<0, 1, spacedim>::face_orientation(const unsigned int /*face*/)
7278{
7279 return false;
7280}
7281
7282
7283
7284template <int spacedim>
7285inline bool
7286TriaAccessor<0, 1, spacedim>::face_flip(const unsigned int /*face*/)
7287{
7288 return false;
7289}
7290
7291
7292
7293template <int spacedim>
7294inline bool
7295TriaAccessor<0, 1, spacedim>::face_rotation(const unsigned int /*face*/)
7296{
7297 return false;
7298}
7299
7300
7301
7302template <int spacedim>
7304TriaAccessor<0, 1, spacedim>::line_orientation(const unsigned int /*line*/)
7305{
7307}
7308
7309
7310
7311template <int spacedim>
7312inline bool
7314{
7315 return false;
7316}
7317
7318
7319
7320template <int spacedim>
7321inline unsigned int
7323{
7324 return 0;
7325}
7326
7327
7328
7329template <int spacedim>
7330inline unsigned int
7332{
7333 return 0;
7334}
7335
7336
7337
7338template <int spacedim>
7339inline unsigned int
7341{
7342 return 0;
7343}
7344
7345
7346
7347template <int spacedim>
7348inline unsigned int
7351{
7353}
7354
7355
7356
7357template <int spacedim>
7359TriaAccessor<0, 1, spacedim>::child(const unsigned int)
7360{
7362}
7363
7364
7365template <int spacedim>
7368{
7370}
7371
7372
7373template <int spacedim>
7374inline RefinementCase<0>
7376{
7378}
7379
7380template <int spacedim>
7381inline int
7383{
7384 return -1;
7385}
7386
7387
7388template <int spacedim>
7389inline int
7391{
7392 return -1;
7393}
7394
7395
7396
7397template <int spacedim>
7398inline void
7400{
7401 Assert(tria->vertex_to_boundary_id_map_1d->find(this->vertex_index()) !=
7402 tria->vertex_to_boundary_id_map_1d->end(),
7403 ExcMessage("You can't set the boundary_id of a face of a cell that is "
7404 "not actually at the boundary."));
7405
7406 (*tria->vertex_to_boundary_id_map_1d)[this->vertex_index()] = b;
7407}
7408
7409
7410
7411template <int spacedim>
7412inline void
7414{
7415 (*tria->vertex_to_manifold_id_map_1d)[this->vertex_index()] = b;
7416}
7417
7418
7419
7420template <int spacedim>
7421inline void
7423 const types::boundary_id b) const
7424{
7425 set_boundary_id(b);
7426}
7427
7428
7429
7430template <int spacedim>
7431inline void
7433{
7434 set_manifold_id(b);
7435}
7436
7437
7438
7439template <int spacedim>
7440inline bool
7442{
7443 return tria->vertex_used(global_vertex_index);
7444}
7445
7446
7447
7448template <int spacedim>
7449inline ReferenceCell<0>
7451{
7453}
7454
7455
7456
7457template <int spacedim>
7458unsigned int
7460{
7461 return 1;
7462}
7463
7464
7465
7466template <int spacedim>
7467unsigned int
7469{
7470 return 0;
7471}
7472
7473
7474
7475template <int spacedim>
7476std_cxx20::ranges::iota_view<unsigned int, unsigned int>
7478{
7479 return std_cxx20::ranges::iota_view<unsigned int, unsigned int>(0U,
7480 n_vertices());
7481}
7482
7483
7484
7485template <int spacedim>
7486std_cxx20::ranges::iota_view<unsigned int, unsigned int>
7488{
7489 return std_cxx20::ranges::iota_view<unsigned int, unsigned int>(0U,
7490 n_lines());
7491}
7492
7493/*------------------ Functions: CellAccessor<dim,spacedim> ------------------*/
7494
7495
7496template <int dim, int spacedim>
7498 const Triangulation<dim, spacedim> *parent,
7499 const int level,
7500 const int index,
7501 const AccessorData *local_data)
7502 : TriaAccessor<dim, dim, spacedim>(parent, level, index, local_data)
7503{}
7504
7505
7506
7507template <int dim, int spacedim>
7509 const TriaAccessor<dim, dim, spacedim> &cell_accessor)
7510 : TriaAccessor<dim, dim, spacedim>(
7511 static_cast<const TriaAccessor<dim, dim, spacedim> &>(cell_accessor))
7512{}
7513
7514
7515
7516template <int dim, int spacedim>
7518CellAccessor<dim, spacedim>::child(const unsigned int i) const
7519{
7521 this->level() + 1,
7522 this->child_index(i));
7523
7524 Assert((q.state() == IteratorState::past_the_end) || q->used(),
7526
7527 return q;
7528}
7529
7530
7531
7532template <int dim, int spacedim>
7533inline boost::container::small_vector<TriaIterator<CellAccessor<dim, spacedim>>,
7536{
7537 boost::container::small_vector<TriaIterator<CellAccessor<dim, spacedim>>,
7539 child_iterators(this->n_children());
7540
7541 for (unsigned int i = 0; i < this->n_children(); ++i)
7542 child_iterators[i] = this->child(i);
7543
7544 return child_iterators;
7545}
7546
7547
7548
7549template <int dim, int spacedim>
7550inline TriaIterator<TriaAccessor<dim - 1, dim, spacedim>>
7551CellAccessor<dim, spacedim>::face(const unsigned int i) const
7552{
7553 AssertIndexRange(i, this->n_faces());
7554 if constexpr (dim == 1)
7555 {
7556 using VertexKind = typename TriaAccessor<0, 1, spacedim>::VertexKind;
7557 VertexKind vertex_kind = VertexKind::interior_vertex;
7558 if (i == 0 && at_boundary(0))
7559 vertex_kind = VertexKind::left_vertex;
7560 if (i == 1 && at_boundary(1))
7561 vertex_kind = VertexKind::right_vertex;
7562 TriaAccessor<0, 1, spacedim> a(&this->get_triangulation(),
7563 vertex_kind,
7564 this->vertex_index(i));
7566 }
7567 else if constexpr (dim == 2)
7568 return this->line(i);
7569 else if constexpr (dim == 3)
7570 return this->quad(i);
7571 else
7572 {
7573 Assert(false, ExcNotImplemented());
7574 return {};
7575 }
7576}
7577
7578
7579
7580template <int dim, int spacedim>
7581inline unsigned int
7584{
7585 for (const unsigned int face_n : this->face_indices())
7586 if (this->face(face_n) == face)
7587 return face_n;
7588
7589 Assert(false,
7590 ExcMessage("The given face is not a face of the current cell."));
7592}
7593
7594
7595
7596template <int dim, int spacedim>
7597inline boost::container::small_vector<
7598 TriaIterator<TriaAccessor<dim - 1, dim, spacedim>>,
7599# ifndef _MSC_VER
7601# else
7603# endif
7604 >
7606{
7607 boost::container::small_vector<
7608 TriaIterator<TriaAccessor<dim - 1, dim, spacedim>>,
7609# ifndef _MSC_VER
7611# else
7613# endif
7614 >
7615 face_iterators(this->n_faces());
7616
7617 for (const unsigned int i : this->face_indices())
7618 face_iterators[i] = this->face(i);
7619
7620 return face_iterators;
7621}
7622
7623
7624
7625template <int dim, int spacedim>
7626inline unsigned int
7627CellAccessor<dim, spacedim>::face_index(const unsigned int i) const
7628{
7629 switch (dim)
7630 {
7631 case 1:
7632 return this->vertex_index(i);
7633
7634 case 2:
7635 return this->line_index(i);
7636
7637 case 3:
7638 return this->quad_index(i);
7639
7640 default:
7642 }
7643}
7644
7645
7646
7647template <int dim, int spacedim>
7648inline int
7649CellAccessor<dim, spacedim>::neighbor_index(const unsigned int face_no) const
7650{
7651 AssertIndexRange(face_no, this->n_faces());
7652 return this->tria->levels[this->level()]->neighbor_index(this->present_index,
7653 face_no);
7654}
7655
7656
7657
7658template <int dim, int spacedim>
7659inline int
7660CellAccessor<dim, spacedim>::neighbor_level(const unsigned int face_no) const
7661{
7662 AssertIndexRange(face_no, this->n_faces());
7663 return this->tria->levels[this->level()]->neighbor_level(this->present_index,
7664 face_no);
7665}
7666
7667
7668
7669template <int dim, int spacedim>
7672{
7674 // cells flagged for refinement must be active (the @p set_refine_flag
7675 // function checks this, but activity may change when refinement is executed
7676 // and for some reason the refine flag is not cleared).
7677 Assert(
7678 this->is_active() ||
7679 !this->tria->levels[this->level()]->refine_flags[this->present_index],
7680 ExcRefineCellNotActive());
7681 return RefinementCase<dim>(
7682 this->tria->levels[this->level()]->refine_flags[this->present_index]);
7683}
7684
7685
7686
7687template <int dim, int spacedim>
7688inline void
7690 const RefinementCase<dim> refinement_case) const
7691{
7692 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
7693 Assert(!coarsen_flag_set(), ExcCellFlaggedForCoarsening());
7694
7695 this->tria->levels[this->level()]->refine_flags[this->present_index] =
7696 refinement_case;
7697}
7698
7699
7700
7701template <int dim, int spacedim>
7702inline void
7704{
7705 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
7706 this->tria->levels[this->level()]->refine_flags[this->present_index] =
7708}
7709
7710
7711template <int dim, int spacedim>
7712inline std::uint8_t
7714{
7716 if (this->tria->levels[this->level()]->refine_choice.size() == 0)
7717 return 0U;
7718 return this->tria->levels[this->level()]->refine_choice[this->present_index];
7719}
7720
7721
7722template <int dim, int spacedim>
7723inline void
7725 const std::uint8_t refinement_choice) const
7726{
7727 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
7728 if (this->tria->levels[this->level()]->refine_choice.size() != 0)
7729 this->tria->levels[this->level()]->refine_choice[this->present_index] =
7730 refinement_choice;
7731}
7732
7733
7734template <int dim, int spacedim>
7735inline void
7737{
7738 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
7739 if (this->tria->levels[this->level()]->refine_choice.size() != 0)
7740 this->tria->levels[this->level()]->refine_choice[this->present_index] =
7742}
7743
7744
7745template <int dim, int spacedim>
7746inline bool
7748 const unsigned int face_no,
7749 const RefinementCase<dim - 1> &face_refinement_case) const
7750{
7751 Assert(dim > 1, ExcImpossibleInDim(dim));
7752 AssertIndexRange(face_no, this->n_faces());
7753 AssertIndexRange(face_refinement_case,
7755
7756 // the new refinement case is a combination of the minimum required one for
7757 // the given face refinement and the already existing flagged refinement case
7758 RefinementCase<dim> old_ref_case = refine_flag_set();
7759 RefinementCase<dim> new_ref_case =
7760 (old_ref_case |
7762 face_refinement_case,
7763 face_no,
7764 this->face_orientation(face_no),
7765 this->face_flip(face_no),
7766 this->face_rotation(face_no)));
7767 set_refine_flag(new_ref_case);
7768 // return, whether we had to change the refinement flag
7769 return new_ref_case != old_ref_case;
7770}
7771
7772
7773
7774template <int dim, int spacedim>
7775inline bool
7777 const unsigned int line_no) const
7778{
7779 Assert(dim > 1, ExcImpossibleInDim(dim));
7780 AssertIndexRange(line_no, this->n_lines());
7781
7782 // the new refinement case is a combination of the minimum required one for
7783 // the given line refinement and the already existing flagged refinement case
7785 old_ref_case = refine_flag_set(),
7786 new_ref_case =
7787 old_ref_case |
7789 set_refine_flag(new_ref_case);
7790 // return, whether we had to change the refinement flag
7791 return new_ref_case != old_ref_case;
7792}
7793
7794
7795
7796template <int dim, int spacedim>
7798CellAccessor<dim, spacedim>::subface_case(const unsigned int face_no) const
7799{
7801 AssertIndexRange(face_no, this->n_faces());
7802
7803 if constexpr (dim == 1)
7805 else if constexpr (dim == 2)
7806 return ((face(face_no)->has_children()) ?
7809 else if constexpr (dim == 3)
7810 {
7811 switch (static_cast<std::uint8_t>(face(face_no)->refinement_case()))
7812 {
7816 if (face(face_no)->child(0)->has_children())
7817 {
7818 Assert(face(face_no)->child(0)->refinement_case() ==
7821 if (face(face_no)->child(1)->has_children())
7822 {
7823 Assert(face(face_no)->child(1)->refinement_case() ==
7827 }
7828 else
7830 }
7831 else
7832 {
7833 if (face(face_no)->child(1)->has_children())
7834 {
7835 Assert(face(face_no)->child(1)->refinement_case() ==
7839 }
7840 else
7842 }
7844 if (face(face_no)->child(0)->has_children())
7845 {
7846 Assert(face(face_no)->child(0)->refinement_case() ==
7849 if (face(face_no)->child(1)->has_children())
7850 {
7851 Assert(face(face_no)->child(1)->refinement_case() ==
7855 }
7856 else
7858 }
7859 else
7860 {
7861 if (face(face_no)->child(1)->has_children())
7862 {
7863 Assert(face(face_no)->child(1)->refinement_case() ==
7867 }
7868 else
7870 }
7873 default:
7875 }
7876 }
7877
7878 // we should never get here
7881}
7882
7883
7884
7885template <int dim, int spacedim>
7886inline bool
7888{
7890 // cells flagged for coarsening must be active (the @p set_refine_flag
7891 // function checks this, but activity may change when refinement is executed
7892 // and for some reason the refine flag is not cleared).
7893 Assert(
7894 this->is_active() ||
7895 !this->tria->levels[this->level()]->coarsen_flags[this->present_index],
7896 ExcRefineCellNotActive());
7897 return this->tria->levels[this->level()]->coarsen_flags[this->present_index];
7898}
7899
7900
7901
7902template <int dim, int spacedim>
7903inline void
7905{
7906 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
7907 Assert(!refine_flag_set(), ExcCellFlaggedForRefinement());
7908
7909 this->tria->levels[this->level()]->coarsen_flags[this->present_index] = true;
7910}
7911
7912
7913
7914template <int dim, int spacedim>
7915inline void
7917{
7918 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
7919 this->tria->levels[this->level()]->coarsen_flags[this->present_index] = false;
7920}
7921
7922
7923
7924template <int dim, int spacedim>
7926CellAccessor<dim, spacedim>::neighbor(const unsigned int face_no) const
7927{
7929 neighbor_level(face_no),
7930 neighbor_index(face_no));
7931
7932 Assert((q.state() == IteratorState::past_the_end) || q->used(),
7934
7935 return q;
7936}
7937
7938
7939
7940template <int dim, int spacedim>
7941inline bool
7943{
7944 return !this->has_children();
7945}
7946
7947
7948
7949template <int dim, int spacedim>
7950inline bool
7952{
7953 Assert(this->is_active(),
7954 ExcMessage("is_locally_owned() can only be called on active cells!"));
7955# ifndef DEAL_II_WITH_MPI
7956 return true;
7957# else
7958
7959 // Serial triangulations report invalid_subdomain_id as their locally owned
7960 // subdomain, so the first condition checks whether we have a serial
7961 // triangulation, in which case all cells are locally owned. The second
7962 // condition compares the subdomain id in the parallel case.
7963 const types::subdomain_id locally_owned_subdomain =
7964 this->tria->locally_owned_subdomain();
7965 return (locally_owned_subdomain == numbers::invalid_subdomain_id ||
7966 this->subdomain_id() == locally_owned_subdomain);
7967
7968# endif
7969}
7970
7971
7972template <int dim, int spacedim>
7973inline bool
7975{
7976# ifndef DEAL_II_WITH_MPI
7977 return true;
7978# else
7979
7980 // Serial triangulations report invalid_subdomain_id as their locally owned
7981 // subdomain, so the first condition checks whether we have a serial
7982 // triangulation, in which case all cells are locally owned. The second
7983 // condition compares the subdomain id in the parallel case.
7984 const types::subdomain_id locally_owned_subdomain =
7985 this->tria->locally_owned_subdomain();
7986 return (locally_owned_subdomain == numbers::invalid_subdomain_id ||
7987 this->level_subdomain_id() == locally_owned_subdomain);
7988
7989# endif
7990}
7991
7992
7993template <int dim, int spacedim>
7994inline bool
7996{
7997 Assert(this->is_active(),
7998 ExcMessage("is_ghost() can only be called on active cells!"));
7999 if (this->has_children())
8000 return false;
8001
8002# ifndef DEAL_II_WITH_MPI
8003 return false;
8004# else
8005
8006 // Serial triangulations report invalid_subdomain_id as their locally owned
8007 // subdomain, so the first condition rules out that case as all cells to a
8008 // serial triangulation are locally owned and none is ghosted. The second
8009 // and third conditions check whether the cell's subdomain is not the
8010 // locally owned one and not artificial.
8011 const types::subdomain_id locally_owned_subdomain =
8012 this->tria->locally_owned_subdomain();
8013 const types::subdomain_id subdomain_id = this->subdomain_id();
8014 return (locally_owned_subdomain != numbers::invalid_subdomain_id &&
8015 subdomain_id != locally_owned_subdomain &&
8016 subdomain_id != numbers::artificial_subdomain_id);
8017
8018# endif
8019}
8020
8021
8022template <int dim, int spacedim>
8023inline bool
8025{
8026# ifndef DEAL_II_WITH_MPI
8027 return false;
8028# else
8029
8030 // Serial triangulations report invalid_subdomain_id as their locally owned
8031 // subdomain, so the first condition checks whether we have a serial
8032 // triangulation, in which case all cells are locally owned. The second
8033 // condition compares the subdomain id in the parallel case.
8034 const types::subdomain_id locally_owned_subdomain =
8035 this->tria->locally_owned_subdomain();
8036 const types::subdomain_id subdomain_id = this->level_subdomain_id();
8037 return (locally_owned_subdomain != numbers::invalid_subdomain_id &&
8038 subdomain_id != locally_owned_subdomain &&
8039 subdomain_id != numbers::artificial_subdomain_id);
8040
8041# endif
8042}
8043
8044
8045
8046template <int dim, int spacedim>
8047inline bool
8049{
8050 Assert(this->is_active(),
8051 ExcMessage("is_artificial() can only be called on active cells!"));
8052# ifndef DEAL_II_WITH_MPI
8053 return false;
8054# else
8055
8056 // Serial triangulations report invalid_subdomain_id as their locally owned
8057 // subdomain, so the first condition rules out that case as all cells to a
8058 // serial triangulation are locally owned and none is artificial.
8059 return (this->tria->locally_owned_subdomain() !=
8061 this->subdomain_id() == numbers::artificial_subdomain_id);
8062
8063# endif
8064}
8065
8066
8067
8068template <int dim, int spacedim>
8069inline bool
8071{
8072# ifndef DEAL_II_WITH_MPI
8073 return false;
8074# else
8075 return (this->tria->locally_owned_subdomain() !=
8077 this->level_subdomain_id() == numbers::artificial_subdomain_id);
8078# endif
8079}
8080
8081
8082
8083template <int dim, int spacedim>
8084inline types::material_id
8086{
8088 return this->tria->levels[this->level()]
8089 ->cells.boundary_or_material_id[this->present_index]
8090 .material_id;
8091}
8092
8093
8094
8095template <int dim, int spacedim>
8098{
8100 Assert(this->is_active(),
8101 ExcMessage("subdomain_id() can only be called on active cells!"));
8102 return this->tria->levels[this->level()]->subdomain_ids[this->present_index];
8103}
8104
8105
8106
8107template <int dim, int spacedim>
8110{
8112 return this->tria->levels[this->level()]
8113 ->level_subdomain_ids[this->present_index];
8114}
8115
8116
8117
8118template <int dim, int spacedim>
8119inline unsigned int
8120CellAccessor<dim, spacedim>::neighbor_face_no(const unsigned int neighbor) const
8121{
8122 const unsigned int n2 = neighbor_of_neighbor_internal(neighbor);
8124 // return this value as the neighbor is not coarser
8125 return n2;
8126 else
8127 // the neighbor is coarser
8128 return neighbor_of_coarser_neighbor(neighbor).first;
8129}
8130
8131
8132
8133template <int dim, int spacedim>
8134inline bool
8136{
8137 return false;
8138}
8139
8140
8141
8142template <int dim, int spacedim>
8143inline unsigned int
8145{
8147 return this->tria->levels[this->level()]
8148 ->active_cell_indices[this->present_index];
8149}
8150
8151
8152
8153template <int dim, int spacedim>
8156{
8158 Assert(this->is_active(),
8159 ExcMessage(
8160 "global_active_cell_index() can only be called on active cells!"));
8161
8162 return this->tria->levels[this->level()]
8163 ->global_active_cell_indices[this->present_index];
8164}
8165
8166
8167
8168template <int dim, int spacedim>
8171{
8172 return this->tria->levels[this->level()]
8173 ->global_level_cell_indices[this->present_index];
8174}
8175
8176
8177
8178template <int dim, int spacedim>
8179inline bool
8181{
8183 if constexpr (dim == spacedim)
8184 return true;
8185 else if constexpr (dim == spacedim - 1)
8186 return this->tria->levels[this->level()]
8187 ->direction_flags[this->present_index];
8188 else
8189 {
8190 Assert(false,
8191 ExcMessage("This function cannot be called if dim<spacedim-1."));
8192 return true;
8193 }
8194}
8195
8196#endif // DOXYGEN
8197
8199
8200
8201#endif
*  const Number radius
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
boost::container::small_vector< TriaIterator< CellAccessor< dim, spacedim > >, ReferenceCells::max_n_children< dim >()> child_iterators() 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
std::set< TriaActiveIterator< CellAccessor< dim, spacedim > > > get_cells_adjacent_to_line(const unsigned int i) const
void set_refine_choice(const std::uint8_t refinement_choice=static_cast< char >(IsotropicRefinementChoice::isotropic_refinement)) 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:318
Definition point.h:111
numbers::NumberTraits< Number >::real_type distance(const Point< dim, Number > &p) const
constexpr unsigned int n_vertices() const
std::array< unsigned int, 2 > standard_vertex_to_face_and_vertex_index(const unsigned int vertex) const
constexpr unsigned int n_faces() const
unsigned int standard_to_real_face_line(const unsigned int line, const unsigned int face, const types::geometric_orientation face_orientation) const
constexpr unsigned int n_lines() 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_line_to_face_and_line_index(const unsigned int line) 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
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
static TriaIterator< TriaAccessor< 0, 1, spacedim > > isotropic_child(const unsigned int)
Return an invalid object.
static unsigned int line_index(const unsigned int i)
std_cxx20::ranges::iota_view< unsigned int, unsigned int > vertex_indices() const
static unsigned int child_iterator_to_index(const TriaIterator< TriaAccessor< 0, 1, spacedim > > &)
Return an invalid unsigned integer.
static unsigned int max_refinement_depth()
static unsigned int quad_index(const unsigned int i)
static typename::internal::TriangulationImplementation::Iterators< 1, spacedim >::quad_iterator quad(const unsigned int i)
const Manifold< 1, spacedim > & get_manifold() const
TriaAccessor(const InvalidAccessor< structdim2, dim2, spacedim2 > &)
TriaAccessor(const Triangulation< 1, spacedim > *tria, const VertexKind vertex_kind, const unsigned int vertex_index)
static TriaIterator< TriaAccessor< 0, 1, spacedim > > child(const unsigned int)
Return an invalid object.
unsigned int n_lines() const
const Triangulation< 1, spacedim > & get_triangulation() const
bool operator!=(const TriaAccessor &) const
TriaAccessor(const Triangulation< 1, spacedim > *tria=nullptr, const int=0, const int=0, const AccessorData *=nullptr)
static unsigned int n_active_descendants()
static int isotropic_child_index(const unsigned int i)
Returns -1.
types::boundary_id boundary_id() const
static typename::internal::TriangulationImplementation::Iterators< 1, spacedim >::line_iterator line(const unsigned int)
static RefinementCase< 0 > refinement_case()
std_cxx20::ranges::iota_view< unsigned int, unsigned int > line_indices() const
unsigned int vertex_index(const unsigned int i=0) const
void copy_from(const TriaAccessor &)
void set_all_boundary_ids(const types::boundary_id) const
static IteratorState::IteratorStates state()
Point< spacedim > center() const
static int child_index(const unsigned int i)
Returns -1.
types::manifold_id manifold_id() const
static constexpr unsigned int space_dimension
static unsigned int n_children()
TriaAccessor(const TriaAccessor< structdim2, dim2, spacedim2 > &)
void set_boundary_id(const types::boundary_id) const
Point< spacedim > & vertex(const unsigned int i=0) const
static const unsigned int structure_dimension
unsigned int n_vertices() const
void set_manifold_id(const types::manifold_id)
static constexpr unsigned int dimension
void copy_from(const TriaAccessorBase< 0, 1, spacedim > &)
ReferenceCell< 0 > reference_cell() const
bool operator==(const TriaAccessor &) const
const Triangulation< 1, spacedim > * tria
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
void set_user_index(const unsigned int p) const
TriaAccessor(TriaAccessor &&)=default
void clear_user_pointer() const
unsigned int n_active_descendants() const
void recursively_set_user_index(const unsigned int p) const
TriaIterator< TriaAccessor< 0, dim, spacedim > > vertex_iterator(const unsigned int i) const
void clear_user_data() const
Point< structdim > real_to_unit_cell_affine_approximation(const Point< spacedim > &point) const
void recursively_clear_user_index() const
unsigned int line_index(const unsigned int i) const
const Manifold< dim, spacedim > & get_manifold() const
void recursively_set_user_pointer(void *p) 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
void recursively_clear_user_flag() const
std_cxx20::ranges::iota_view< unsigned int, unsigned int > line_indices() const
Point< spacedim > barycenter() const
BoundingBox< spacedim > bounding_box() const
void set_bounding_object_indices(const std::initializer_list< unsigned int > &new_indices) const
void clear_user_flag() 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 recursively_set_user_flag() const
void set_boundary_id(const types::boundary_id) const
bool is_translation_of(const TriaIterator< TriaAccessor< structdim, dim, spacedim > > &o) const
bool user_flag_set() const
void set_used_flag() const
types::manifold_id manifold_id() const
void set_user_flag() const
TriaAccessor(const TriaAccessor &)=default
void clear_used_flag() const
std::pair< Point< spacedim >, double > enclosing_ball() const
unsigned int vertex_index(const unsigned int i) const
void * user_pointer() 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
ReferenceCell< structdim > reference_cell() const
void set_refinement_case(const RefinementCase< structdim > &ref_case) const
void clear_user_index() const
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
unsigned int max_refinement_depth() const
Point< spacedim > & vertex(const unsigned int i) const
void set_line_orientation(const unsigned int line, const types::geometric_orientation orientation) const
unsigned int quad_index(const unsigned int i) const
TriaAccessor & operator=(const TriaAccessor &)=delete
unsigned int user_index() const
int child_index(const unsigned int i) const
void set_user_pointer(void *p) const
void recursively_clear_user_pointer() const
RefinementCase< structdim > refinement_case() const
typename::internal::TriangulationImplementation::Iterators< dim, spacedim >::line_iterator line(const unsigned int i) const
TriaAccessor(const Triangulation< dim, spacedim > *parent=nullptr, const int level=-1, const int index=-1, const AccessorData *local_data=nullptr)
typename TriaAccessorBase< structdim, dim, spacedim >::AccessorData AccessorData
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 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
std::unique_ptr< std::map< unsigned int, types::manifold_id > > vertex_to_manifold_id_map_1d
Definition tria.h:4690
std::unique_ptr<::internal::TriangulationImplementation::TriaFaces< dim > > faces
Definition tria.h:4602
std::vector< Point< spacedim > > vertices
Definition tria.h:4608
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:4667
std::vector< std::unique_ptr< ::internal::TriangulationImplementation::TriaLevel< dim, spacedim > > > levels
Definition tria.h:4594
bool vertex_used(const unsigned int index) const
unsigned int n_vertices() const
#define DEAL_II_DEPRECATED
Definition config.h:286
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
constexpr bool running_in_debug_mode()
Definition config.h:76
#define DEAL_II_CXX20_REQUIRES(condition)
Definition config.h:246
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
#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:1624
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.
void set_combined_face_orientation(const unsigned int face_no, const types::geometric_orientation combined_orientation) const
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.
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:101
void reference_cell(Triangulation< dim, spacedim > &tria, const ReferenceCell< dim > &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:469
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)
*  *  *  *  std::vector< Number > ThermoPlasticMaterial< dim, ViscoplasticYieldLaw, Number >::get_state_parameters   const
constexpr unsigned int max_n_children()
constexpr ReferenceCell< 3 > Hexahedron
constexpr ReferenceCell< 2 > Quadrilateral
ReferenceCell< dim > n_vertices_to_reference_cell(const unsigned int n_vertices)
constexpr ReferenceCell< 1 > Line
constexpr ReferenceCell< 2 > Triangle
constexpr unsigned int max_n_vertices()
constexpr ReferenceCell< 3 > Tetrahedron
constexpr unsigned int max_n_faces()
constexpr ReferenceCell< 3 > Pyramid
constexpr ReferenceCell< 3 > Wedge
constexpr ReferenceCell< 0 > Vertex
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 types::geometric_orientation invalid_geometric_orientation
Definition types.h:377
constexpr unsigned int invalid_unsigned_int
Definition types.h:236
constexpr types::boundary_id internal_face_boundary_id
Definition types.h:327
constexpr types::manifold_id flat_manifold_id
Definition types.h:340
constexpr types::subdomain_id artificial_subdomain_id
Definition types.h:414
constexpr types::geometric_orientation reverse_line_orientation
Definition types.h:363
constexpr types::subdomain_id invalid_subdomain_id
Definition types.h:393
constexpr types::geometric_orientation default_geometric_orientation
Definition types.h:350
::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:182
unsigned int boundary_id
Definition types.h:159
unsigned int subdomain_id
Definition types.h:50
std::uint64_t global_vertex_index
Definition types.h:55
unsigned int manifold_id
Definition types.h:171
std::uint8_t geometric_orientation
Definition types.h:38
unsigned int global_cell_index
Definition types.h:136
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)