deal.II version GIT relicensing-6809-ge913b9bb34 2026-09-25 17:20:01+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Loading...
Searching...
No Matches
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>
25
33
34#include <boost/container/small_vector.hpp>
35
36#include <cmath>
37#include <limits>
38#include <set>
39#include <utility>
40
41
43
44// Forward declarations
45#ifndef DOXYGEN
46template <int dim, int spacedim>
48class Triangulation;
49template <typename Accessor>
50class TriaRawIterator;
51template <typename Accessor>
52class TriaIterator;
53template <typename Accessor>
55
56namespace parallel
57{
58 template <int dim, int spacedim>
60 class TriangulationBase;
61}
62
63template <int dim, int spacedim>
65class DoFHandler;
66template <int dim, int spacedim, bool lda>
67class DoFCellAccessor;
68
69
70template <int dim, int spacedim>
71class Manifold;
72
73template <int dim, int spacedim>
74class Mapping;
75#endif
76
77namespace internal
78{
79 namespace TriangulationImplementation
80 {
81 class TriaObjects;
82 struct Implementation;
83 struct ImplementationMixedMesh;
84 } // namespace TriangulationImplementation
85
86 namespace TriaAccessorImplementation
87 {
88 struct Implementation;
89
103 template <bool level_access>
105 {};
106
110 template <>
111 class LevelAccessor<true>
112 {
113 public:
115 : present_level(level)
116 {}
117
118 void
119 set_level(const int level)
120 {
121 present_level = level;
122 }
123
124 int
125 get_level() const
126 {
127 return present_level;
128 }
129
130 private:
132 };
133
137 template <>
138 class LevelAccessor<false>
139 {
140 public:
142 {
144 }
145
146 static void
147 set_level(const int level)
148 {
150 }
151
152 static int
154 {
155 return 0;
156 }
157 };
158 } // namespace TriaAccessorImplementation
159} // namespace internal
160template <int structdim, int dim, int spacedim>
161class TriaAccessor;
162template <int dim, int spacedim>
163class TriaAccessor<0, dim, spacedim>;
164template <int spacedim>
165class TriaAccessor<0, 1, spacedim>;
166
171{
176 "The operation you are attempting can only be performed for "
177 "(cell, face, or edge) iterators that point to valid "
178 "objects. These objects need not necessarily be active, "
179 "i.e., have no children, but they need to be part of a "
180 "triangulation. (The objects pointed to by an iterator "
181 "may -- after coarsening -- also be objects that used "
182 "to be part of a triangulation, but are now no longer "
183 "used. Their memory location may have been retained "
184 "for re-use upon the next mesh refinement, but is "
185 "currently unused.)");
196 "The operation you are attempting can only be performed for "
197 "(cell, face, or edge) iterators that point to 'active' "
198 "objects. 'Active' objects are those that do not have "
199 "children (in the case of cells), or that are part of "
200 "an active cell (in the case of faces or edges). However, "
201 "the object on which you are trying the current "
202 "operation is not 'active' in this sense.");
209 "The operation you are attempting can only be performed for "
210 "(cell, face, or edge) iterators that have children, "
211 "but the object on which you are trying the current "
212 "operation does not have any.");
220 "The operation you are attempting can only be performed for "
221 "(cell, face, or edge) iterators that have a parent object, "
222 "but the object on which you are trying the current "
223 "operation does not have one -- i.e., it is on the "
224 "coarsest level of the triangulation.");
229 int,
230 << "You can only set the child index if the cell does not "
231 << "currently have children registered; or you can clear it. "
232 << "The given index was " << arg1
233 << " (-1 means: clear children).");
237 template <typename AccessorType>
239 AccessorType,
240 << "You tried to dereference an iterator for which this "
241 << "is not possible. More information on this iterator: "
242 << "index=" << arg1.index() << ", state="
243 << (arg1.state() == IteratorState::valid ?
244 "valid" :
245 (arg1.state() == IteratorState::past_the_end ?
246 "past_the_end" :
247 "invalid")));
252 "Iterators can only be compared if they point to the same "
253 "triangulation, or if neither of them are associated "
254 "with a triangulation.");
255 // TODO: Write documentation!
260 // TODO: Write documentation!
287 int,
288 << "You can only set the child index of an even numbered child."
289 << "The number of the child given was " << arg1 << '.');
290} // namespace TriaAccessorExceptions
291
292
318template <int structdim, int dim, int spacedim = dim>
321 dim>
322{
323public:
330 static constexpr unsigned int space_dimension = spacedim;
331
337 static constexpr unsigned int dimension = dim;
338
344 static const unsigned int structure_dimension = structdim;
345
355 void
356 operator=(const TriaAccessorBase *) = delete;
357
358protected:
364 using AccessorData = void;
365
370 const int level = -1,
371 const int index = -1,
372 const AccessorData * = nullptr);
373
378
386 void
388
394
405 bool
406 operator<(const TriaAccessorBase &other) const;
407
408protected:
412 bool
414
418 bool
420
434 void
436
444 void
454 objects() const;
455
456public:
462 using LocalData = void *;
463
487 int
488 level() const;
489
516 int
517 index() const;
518
524 state() const;
525
532
536protected:
542
547
548private:
549 template <typename Accessor>
550 friend class TriaRawIterator;
551 template <typename Accessor>
552 friend class TriaIterator;
553 template <typename Accessor>
554 friend class TriaActiveIterator;
555};
556
557
558
579template <int structdim, int dim, int spacedim = dim>
581{
582public:
589 static constexpr unsigned int space_dimension = spacedim;
590
596 static constexpr unsigned int dimension = dim;
597
603 static const unsigned int structure_dimension = structdim;
604
610 using AccessorData = void;
611
619 InvalidAccessor(const void *parent = nullptr,
620 const int level = -1,
621 const int index = -1,
622 const AccessorData *local_data = nullptr);
623
632
637 template <typename OtherAccessor>
638 InvalidAccessor(const OtherAccessor &);
639
643 void
645
649 bool
651 bool
653
657 void
658 operator++() const;
659 void
660 operator--() const;
661
667 state();
668
669
674 static int
675 level();
676
681 static int
682 index();
683
688 bool
689 used() const;
690
695 bool
697
702 manifold_id() const;
703
707 unsigned int
708 user_index() const;
709
713 void
714 set_user_index(const unsigned int p) const;
715
719 void
721
726 vertex(const unsigned int i) const;
727
732 void *
733 line(const unsigned int i) const;
734
739 void *
740 quad(const unsigned int i) const;
741};
742
743
744
762template <int structdim, int dim, int spacedim>
763class TriaAccessor : public TriaAccessorBase<structdim, dim, spacedim>
764{
765public:
771
776 const int level = -1,
777 const int index = -1,
778 const AccessorData *local_data = nullptr);
779
784 TriaAccessor(const TriaAccessor &) = default;
785
789 TriaAccessor(TriaAccessor &&) = default; // NOLINT
790
803 template <int structdim2, int dim2, int spacedim2>
805
810 template <int structdim2, int dim2, int spacedim2>
812
823 operator=(const TriaAccessor &) = delete;
824
829 operator=(TriaAccessor &&) = default; // NOLINT
830
834 ~TriaAccessor() = default;
835
842 bool
843 used() const;
844
857 vertex_iterator(const unsigned int i) const;
858
874 unsigned int
875 vertex_index(const unsigned int i) const;
876
915 vertex(const unsigned int i) const;
916
920 typename ::internal::TriangulationImplementation::
921 Iterators<dim, spacedim>::line_iterator
922 line(const unsigned int i) const;
923
930 unsigned int
931 line_index(const unsigned int i) const;
932
936 typename ::internal::TriangulationImplementation::
937 Iterators<dim, spacedim>::quad_iterator
938 quad(const unsigned int i) const;
939
946 unsigned int
947 quad_index(const unsigned int i) const;
966 combined_face_orientation(const unsigned int face) const;
967
979 bool
980 face_orientation(const unsigned int face) const;
981
991 bool
992 face_flip(const unsigned int face) const;
993
1003 bool
1004 face_rotation(const unsigned int face) const;
1005
1016 line_orientation(const unsigned int line) const;
1031 bool
1033
1038 unsigned int
1039 n_children() const;
1040
1054 unsigned int
1056
1070 unsigned int
1072
1077 child(const unsigned int i) const;
1078
1083 unsigned int
1086
1096 isotropic_child(const unsigned int i) const;
1097
1103
1109 int
1110 child_index(const unsigned int i) const;
1111
1117 int
1118 isotropic_child_index(const unsigned int i) const;
1142
1170 void
1172
1201 void
1203
1211 bool
1213
1225
1248
1266 void
1268
1282 void
1284
1301 bool
1303
1309 void
1311
1317 void
1319
1325 void
1327
1333 void
1335
1341 void
1343
1355 void
1356 set_user_pointer(void *p) const;
1357
1363 void
1365
1383 void *
1385
1407 void
1409
1416 void
1418
1428 void
1429 set_user_index(const unsigned int p) const;
1430
1436 void
1438
1450 unsigned int
1451 user_index() const;
1452
1470 void
1471 recursively_set_user_index(const unsigned int p) const;
1472
1481 void
1517 double
1518 diameter() const;
1519
1546 std::pair<Point<spacedim>, double>
1548
1559
1569 double
1570 extent_in_direction(const unsigned int axis) const;
1571
1575 double
1577
1592 intermediate_point(const Point<structdim> &coordinates) const;
1593
1618
1654 center(const bool respect_manifold = false,
1655 const bool interpolate_from_surrounding = false) const;
1656
1675 barycenter() const;
1676
1710 double
1711 measure() const;
1712
1727 bool
1730
1736
1740 unsigned int
1741 n_vertices() const;
1742
1746 unsigned int
1747 n_lines() const;
1748
1758 unsigned int
1759 n_faces() const;
1760
1767
1774
1783
1788private:
1793 void
1795
1803 void
1805 const std::initializer_list<int> &new_indices) const;
1806
1810 void
1812 const std::initializer_list<unsigned int> &new_indices) const;
1813
1821 void
1822 set_line_orientation(const unsigned int line,
1823 const types::geometric_orientation orientation) const;
1824
1834 void
1836 const unsigned int face_no,
1837 const types::geometric_orientation combined_orientation) const;
1838
1842 void
1844
1848 void
1850
1859 void
1861
1869 void
1871
1878 void
1879 set_children(const unsigned int i, const int index) const;
1880
1885 void
1887
1888private:
1889 friend class Triangulation<dim, spacedim>;
1890
1891 friend struct ::internal::TriangulationImplementation::Implementation;
1892 friend struct ::internal::TriangulationImplementation::
1893 ImplementationMixedMesh;
1894 friend struct ::internal::TriaAccessorImplementation::Implementation;
1895};
1896
1897
1898
1917template <int dim, int spacedim>
1918class TriaAccessor<0, dim, spacedim>
1919{
1920public:
1926 static constexpr unsigned int space_dimension = spacedim;
1927
1933 static constexpr unsigned int dimension = dim;
1934
1940 static const unsigned int structure_dimension = 0;
1941
1945 using AccessorData = void;
1946
1952 const unsigned int vertex_index);
1953
1960 const int level = 0,
1961 const int index = 0,
1962 const AccessorData * = nullptr);
1963
1967 template <int structdim2, int dim2, int spacedim2>
1969
1973 template <int structdim2, int dim2, int spacedim2>
1975
1980 state() const;
1981
1986 static int
1988
1993 int
1994 index() const;
1995
2002
2012 void
2014
2018 void
2023 bool
2024 operator==(const TriaAccessor &) const;
2025
2029 bool
2030 operator!=(const TriaAccessor &) const;
2031
2059 unsigned int
2060 vertex_index(const unsigned int i = 0) const;
2061
2068 vertex(const unsigned int i = 0) const;
2069
2074 typename ::internal::TriangulationImplementation::
2075 Iterators<dim, spacedim>::line_iterator static line(const unsigned int);
2076
2080 static unsigned int
2081 line_index(const unsigned int i);
2082
2086 static typename ::internal::TriangulationImplementation::
2087 Iterators<dim, spacedim>::quad_iterator
2088 quad(const unsigned int i);
2089
2093 static unsigned int
2094 quad_index(const unsigned int i);
2095
2111 double
2112 diameter() const;
2113
2121 double
2122 extent_in_direction(const unsigned int axis) const;
2123
2132 center(const bool respect_manifold = false,
2133 const bool interpolate_from_surrounding = false) const;
2134
2142 double
2143 measure() const;
2161 combined_face_orientation(const unsigned int face);
2162
2166 static bool
2167 face_orientation(const unsigned int face);
2168
2172 static bool
2173 face_flip(const unsigned int face);
2174
2178 static bool
2179 face_rotation(const unsigned int face);
2180
2185 line_orientation(const unsigned int line);
2186
2201 static bool
2203
2208 static unsigned int
2210
2215 static unsigned int
2217
2221 static unsigned int
2223
2227 static unsigned int
2229
2234 child(const unsigned int);
2235
2240 isotropic_child(const unsigned int);
2241
2245 static RefinementCase<0>
2247
2251 static int
2252 child_index(const unsigned int i);
2253
2257 static int
2258 isotropic_child_index(const unsigned int i);
2266 bool
2267 used() const;
2268
2269protected:
2277 void
2279
2288 bool
2289 operator<(const TriaAccessor &other) const;
2290
2295
2300
2301private:
2302 template <typename Accessor>
2303 friend class TriaRawIterator;
2304 template <typename Accessor>
2305 friend class TriaIterator;
2306 template <typename Accessor>
2308};
2309
2310
2311
2328template <int spacedim>
2329class TriaAccessor<0, 1, spacedim>
2330{
2331public:
2337 static constexpr unsigned int space_dimension = spacedim;
2338
2344 static constexpr unsigned int dimension = 1;
2345
2351 static const unsigned int structure_dimension = 0;
2352
2356 using AccessorData = void;
2357
2363 {
2375 right_vertex
2377
2390 const VertexKind vertex_kind,
2391 const unsigned int vertex_index);
2392
2399 const int = 0,
2400 const int = 0,
2401 const AccessorData * = nullptr);
2402
2406 template <int structdim2, int dim2, int spacedim2>
2408
2412 template <int structdim2, int dim2, int spacedim2>
2414
2419 void
2421
2427 void
2429
2437
2442 static int
2444
2449 int
2450 index() const;
2451
2458
2469 void
2470 operator++() const;
2471
2476 void
2477 operator--() const;
2481 bool
2482 operator==(const TriaAccessor &) const;
2483
2487 bool
2488 operator!=(const TriaAccessor &) const;
2489
2498 bool
2499 operator<(const TriaAccessor &other) const;
2500
2527 unsigned int
2528 vertex_index(const unsigned int i = 0) const;
2529
2536 vertex(const unsigned int i = 0) const;
2537
2543 center() const;
2544
2549 typename ::internal::TriangulationImplementation::
2550 Iterators<1, spacedim>::line_iterator static line(const unsigned int);
2551
2558 static unsigned int
2559 line_index(const unsigned int i);
2560
2564 static typename ::internal::TriangulationImplementation::
2565 Iterators<1, spacedim>::quad_iterator
2566 quad(const unsigned int i);
2567
2574 static unsigned int
2575 quad_index(const unsigned int i);
2576
2594 static double
2596
2605 bool
2607
2624
2628 const Manifold<1, spacedim> &
2630
2639
2640
2652 bool
2653 user_flag_set() const;
2654
2660 void
2661 set_user_flag() const;
2662
2668 void
2669 clear_user_flag() const;
2670
2676 void
2678
2684 void
2686
2692 void
2693 clear_user_data() const;
2694
2706 void
2707 set_user_pointer(void *p) const;
2708
2714 void
2715 clear_user_pointer() const;
2716
2732 void *
2733 user_pointer() const;
2734
2756 void
2757 recursively_set_user_pointer(void *p) const;
2758
2765 void
2767
2777 void
2778 set_user_index(const unsigned int p) const;
2779
2785 void
2786 clear_user_index() const;
2787
2799 unsigned int
2800 user_index() const;
2801
2819 void
2820 recursively_set_user_index(const unsigned int p) const;
2821
2830 void
2849 combined_face_orientation(const unsigned int face);
2850
2854 static bool
2855 face_orientation(const unsigned int face);
2856
2860 static bool
2861 face_flip(const unsigned int face);
2862
2866 static bool
2867 face_rotation(const unsigned int face);
2868
2873 line_orientation(const unsigned int line);
2874
2889 static bool
2891
2896 static unsigned int
2898
2903 static unsigned int
2905
2909 static unsigned int
2911
2915 static unsigned int
2917
2922 child(const unsigned int);
2923
2928 isotropic_child(const unsigned int);
2929
2933 static RefinementCase<0>
2935
2939 static int
2940 child_index(const unsigned int i);
2941
2945 static int
2946 isotropic_child_index(const unsigned int i);
2977 void
2979
2986 void
2988
2998 void
3000
3012 void
3021 bool
3022 used() const;
3023
3029
3033 unsigned int
3034 n_vertices() const;
3035
3039 unsigned int
3040 n_lines() const;
3041
3048
3055
3056protected:
3061
3067
3072};
3073
3074
3075
3091template <int dim, int spacedim = dim>
3092class CellAccessor : public TriaAccessor<dim, dim, spacedim>
3093{
3094public:
3099
3104
3116 const int level = -1,
3117 const int index = -1,
3118 const AccessorData *local_data = nullptr);
3119
3124
3137 template <int structdim2, int dim2, int spacedim2>
3139
3144 template <int structdim2, int dim2, int spacedim2>
3146
3151
3155 // NOLINTNEXTLINE OSX does not compile with noexcept
3157
3161 ~CellAccessor() = default;
3162
3174
3178 // NOLINTNEXTLINE OSX does not compile with noexcept
3181
3205 as_dof_handler_iterator(const DoFHandler<dim, spacedim> &dof_handler) const;
3206
3217 const DoFHandler<dim, spacedim> &dof_handler) const;
3218
3219
3236 child(const unsigned int i) const;
3237
3241 boost::container::small_vector<TriaIterator<CellAccessor<dim, spacedim>>,
3242 ReferenceCells::max_n_children<dim>()>
3244
3248 TriaIterator<TriaAccessor<dim - 1, dim, spacedim>>
3249 face(const unsigned int i) const;
3250
3255 unsigned int
3258
3262 boost::container::small_vector<
3263 TriaIterator<TriaAccessor<dim - 1, dim, spacedim>>,
3264#ifndef _MSC_VER // MSVC prior to 2022 cannot use a constexpr function this way
3265 ReferenceCells::max_n_faces<dim>()
3266#else
3268#endif
3269 >
3271
3281 unsigned int
3282 face_index(const unsigned int i) const;
3283
3332 neighbor_child_on_subface(const unsigned int face_no,
3333 const unsigned int subface_no) const;
3334
3383 neighbor(const unsigned int face_no) const;
3384
3392 int
3393 neighbor_index(const unsigned int face_no) const;
3394
3402 int
3403 neighbor_level(const unsigned int face_no) const;
3404
3416 unsigned int
3417 neighbor_of_neighbor(const unsigned int face_no) const;
3418
3429 bool
3430 neighbor_is_coarser(const unsigned int face_no) const;
3431
3446 std::pair<unsigned int, unsigned int>
3447 neighbor_of_coarser_neighbor(const unsigned int neighbor) const;
3448
3455 unsigned int
3456 neighbor_face_no(const unsigned int neighbor) const;
3457
3461 static bool
3463
3477 bool
3478 has_periodic_neighbor(const unsigned int i) const;
3479
3497 periodic_neighbor(const unsigned int i) const;
3498
3507 neighbor_or_periodic_neighbor(const unsigned int i) const;
3508
3524 periodic_neighbor_child_on_subface(const unsigned int face_no,
3525 const unsigned int subface_no) const;
3526
3537 std::pair<unsigned int, unsigned int>
3538 periodic_neighbor_of_coarser_periodic_neighbor(const unsigned face_no) const;
3539
3545 int
3546 periodic_neighbor_index(const unsigned int i) const;
3547
3553 int
3554 periodic_neighbor_level(const unsigned int i) const;
3555
3570 unsigned int
3571 periodic_neighbor_of_periodic_neighbor(const unsigned int i) const;
3572
3578 unsigned int
3579 periodic_neighbor_face_no(const unsigned int i) const;
3580
3587 bool
3588 periodic_neighbor_is_coarser(const unsigned int i) const;
3589
3606 bool
3607 at_boundary(const unsigned int i) const;
3608
3617 bool
3618 at_boundary() const;
3619
3627 bool
3628 has_boundary_lines() const;
3656
3674 void
3677
3681 void
3683
3688 std::uint8_t
3690
3695 void
3696 set_refine_choice(const std::uint8_t refinement_choice = static_cast<char>(
3698
3702 void
3704
3712 bool
3714 const unsigned int face_no,
3715 const RefinementCase<dim - 1> &face_refinement_case =
3717
3723 bool
3724 flag_for_line_refinement(const unsigned int line_no) const;
3725
3735 subface_case(const unsigned int face_no) const;
3736
3740 bool
3742
3747 void
3749
3753 void
3779
3791 void
3792 set_material_id(const types::material_id new_material_id) const;
3793
3802 void
3803 recursively_set_material_id(const types::material_id new_material_id) const;
3831
3847 void
3848 set_subdomain_id(const types::subdomain_id new_subdomain_id) const;
3849
3860
3865 void
3867 const types::subdomain_id new_level_subdomain_id) const;
3868
3869
3885 void
3887 const types::subdomain_id new_subdomain_id) const;
3911
3921
3947 unsigned int
3949
3957 int
3958 parent_index() const;
3959
3966 parent() const;
3967
3984 bool
3986
4006 bool
4007 is_active() const;
4008
4028 bool
4030
4035 bool
4037
4071 bool
4072 is_ghost() const;
4073
4079 bool
4081
4108 bool
4110
4117 bool
4119
4133 bool
4135
4152 std::set<TriaActiveIterator<CellAccessor<dim, spacedim>>>
4153 get_cells_adjacent_to_line(const unsigned int i) const;
4154
4168 CellId
4169 id() const;
4170
4171 using TriaAccessor<dim, dim, spacedim>::diameter;
4172
4176 double
4177 diameter(const Mapping<dim, spacedim> &mapping) const;
4178
4196
4197protected:
4205 void
4206 set_neighbor(const unsigned int face_no,
4208
4224 unsigned int
4225 neighbor_of_neighbor_internal(const unsigned int neighbor) const;
4226
4232 template <int dim_, int spacedim_>
4233 bool
4234 point_inside_codim(const Point<spacedim_> &p) const;
4235
4236
4237
4238private:
4243 void
4244 set_active_cell_index(const unsigned int active_cell_index) const;
4245
4249 void
4251
4255 void
4257
4261 void
4262 set_parent(const unsigned int parent_index);
4263
4274 void
4275 set_direction_flag(const bool new_direction_flag) const;
4276
4277 friend class Triangulation<dim, spacedim>;
4278
4279 friend class parallel::TriangulationBase<dim, spacedim>;
4280
4281 friend struct ::internal::TriangulationImplementation::Implementation;
4282 friend struct ::internal::TriangulationImplementation::
4283 ImplementationMixedMesh;
4284};
4285
4286
4287
4288/* ----- declaration of explicit specializations and general templates ----- */
4289
4290
4291template <int structdim, int dim, int spacedim>
4292template <typename OtherAccessor>
4294 const OtherAccessor &)
4295{
4296 Assert(false,
4297 ExcMessage("You are attempting an illegal conversion between "
4298 "iterator/accessor types. The constructor you call "
4299 "only exists to make certain template constructs "
4300 "easier to write as dimension independent code but "
4301 "the conversion is not valid in the current context."));
4302}
4303
4304
4305
4306template <int structdim, int dim, int spacedim>
4307template <int structdim2, int dim2, int spacedim2>
4310{
4311 Assert(false,
4312 ExcMessage("You are attempting an illegal conversion between "
4313 "iterator/accessor types. The constructor you call "
4314 "only exists to make certain template constructs "
4315 "easier to write as dimension independent code but "
4316 "the conversion is not valid in the current context."));
4317}
4318
4319
4320
4321template <int dim, int spacedim>
4322template <int structdim2, int dim2, int spacedim2>
4325{
4326 Assert(false,
4327 ExcMessage("You are attempting an illegal conversion between "
4328 "iterator/accessor types. The constructor you call "
4329 "only exists to make certain template constructs "
4330 "easier to write as dimension independent code but "
4331 "the conversion is not valid in the current context."));
4332}
4333
4334
4335
4336template <int structdim, int dim, int spacedim>
4337template <int structdim2, int dim2, int spacedim2>
4340{
4341 Assert(false,
4342 ExcMessage("You are attempting an illegal conversion between "
4343 "iterator/accessor types. The constructor you call "
4344 "only exists to make certain template constructs "
4345 "easier to write as dimension independent code but "
4346 "the conversion is not valid in the current context."));
4347}
4348
4349
4350
4351template <int dim, int spacedim>
4352template <int structdim2, int dim2, int spacedim2>
4355{
4356 Assert(false,
4357 ExcMessage("You are attempting an illegal conversion between "
4358 "iterator/accessor types. The constructor you call "
4359 "only exists to make certain template constructs "
4360 "easier to write as dimension independent code but "
4361 "the conversion is not valid in the current context."));
4362}
4363
4364
4365#ifndef DOXYGEN
4366
4367template <>
4368bool
4370template <>
4371bool
4373template <>
4374bool
4376template <>
4377bool
4379template <>
4380bool
4382template <>
4383bool
4385// -------------------------------------------------------------------
4386
4387template <>
4388void
4390
4391
4392
4393namespace internal
4394{
4395 namespace TriaAccessorImplementation
4396 {
4402 template <int dim, int spacedim>
4403 inline double
4404 diameter(const ArrayView<const Point<spacedim>> &vertices)
4405 {
4406 const ReferenceCell<dim> reference_cell =
4407 ReferenceCells::n_vertices_to_reference_cell<dim>(vertices.size());
4408
4409 if constexpr (dim == 1)
4410 {
4411 Assert(reference_cell == ReferenceCells::Line, ExcInternalError());
4412 // Return the distance between the two vertices
4413 return (vertices[1] - vertices[0]).norm();
4414 }
4415 else if constexpr (dim == 2)
4416 {
4417 if (reference_cell == ReferenceCells::Triangle)
4418 // Return the longest of the three edges
4419 return std::max({(vertices[1] - vertices[0]).norm(),
4420 (vertices[2] - vertices[1]).norm(),
4421 (vertices[2] - vertices[0]).norm()});
4422 else if (reference_cell == ReferenceCells::Quadrilateral)
4423 // Return the longer one of the two diagonals of the quadrilateral
4424 return std::max({(vertices[3] - vertices[0]).norm(),
4425 (vertices[2] - vertices[1]).norm()});
4426 }
4427 else if constexpr (dim == 3)
4428 {
4429 if (reference_cell == ReferenceCells::Tetrahedron)
4430 // Return the longest of the six edges of the tetrahedron
4431 return std::max({(vertices[1] - vertices[0]).norm(),
4432 (vertices[2] - vertices[0]).norm(),
4433 (vertices[2] - vertices[1]).norm(),
4434 (vertices[3] - vertices[0]).norm(),
4435 (vertices[3] - vertices[1]).norm(),
4436 (vertices[3] - vertices[2]).norm()});
4437 else if (reference_cell == ReferenceCells::Pyramid)
4438 // Return ...
4439 return std::max({// the longest diagonal of the quadrilateral base
4440 // of the pyramid or ...
4441 (vertices[3] - vertices[0]).norm(),
4442 (vertices[2] - vertices[1]).norm(),
4443 // the longest edge connected with the apex of the
4444 // pyramid
4445 (vertices[4] - vertices[0]).norm(),
4446 (vertices[4] - vertices[1]).norm(),
4447 (vertices[4] - vertices[2]).norm(),
4448 (vertices[4] - vertices[3]).norm()});
4449 else if (reference_cell == ReferenceCells::Wedge)
4450 // Return ...
4451 return std::max({// the longest of the 2*3=6 diagonals of the three
4452 // quadrilateral sides of the wedge or ...
4453 (vertices[4] - vertices[0]).norm(),
4454 (vertices[3] - vertices[1]).norm(),
4455 (vertices[5] - vertices[1]).norm(),
4456 (vertices[4] - vertices[2]).norm(),
4457 (vertices[5] - vertices[0]).norm(),
4458 (vertices[3] - vertices[2]).norm(),
4459 // the longest of the 3*2=6 edges of the two
4460 // triangular faces of the wedge
4461 (vertices[1] - vertices[0]).norm(),
4462 (vertices[2] - vertices[1]).norm(),
4463 (vertices[2] - vertices[0]).norm(),
4464 (vertices[4] - vertices[3]).norm(),
4465 (vertices[5] - vertices[4]).norm(),
4466 (vertices[5] - vertices[3]).norm()});
4467 else if (reference_cell == ReferenceCells::Hexahedron)
4468 // Return the longest of the four diagonals of the hexahedron
4469 return std::max({(vertices[7] - vertices[0]).norm(),
4470 (vertices[6] - vertices[1]).norm(),
4471 (vertices[2] - vertices[5]).norm(),
4472 (vertices[3] - vertices[4]).norm()});
4473 }
4474
4476 return -1e10;
4477 }
4478 } // namespace TriaAccessorImplementation
4479} // namespace internal
4480
4481
4482/*--------------------- Functions: TriaAccessorBase -------------------------*/
4483
4484template <int structdim, int dim, int spacedim>
4486 const Triangulation<dim, spacedim> *tria,
4487 const int level,
4488 const int index,
4489 const AccessorData *)
4490 : internal::TriaAccessorImplementation::LevelAccessor<dim == structdim>(
4491 (structdim == dim) ? level : 0)
4492 , present_index(index)
4493 , tria(tria)
4494{
4495 // non-cells have no level, so a 0 should have been passed, or a -1 for an
4496 // end-iterator, or -2 for an invalid (default constructed) iterator
4497 if (structdim != dim)
4498 Assert((level == 0) || (level == -1) || (level == -2), ExcInternalError());
4499}
4500
4501
4502template <int structdim, int dim, int spacedim>
4505 : internal::TriaAccessorImplementation::LevelAccessor<dim == structdim>(
4506 a.level())
4507 , present_index(a.present_index)
4508 , tria(a.tria)
4509{}
4510
4511
4512template <int structdim, int dim, int spacedim>
4513inline void
4516{
4517 this->set_level(a.level());
4518 present_index = a.present_index;
4519 tria = a.tria;
4520
4521 if (structdim != dim)
4522 Assert(level() == 0, ExcInternalError());
4523}
4524
4525
4526
4527template <int structdim, int dim, int spacedim>
4531{
4532 this->set_level(a.level());
4533 present_index = a.present_index;
4534 tria = a.tria;
4535
4536 if (structdim != dim)
4537 Assert(level() == 0, ExcInternalError());
4538 return *this;
4539}
4540
4541
4542
4543template <int structdim, int dim, int spacedim>
4544inline bool
4547{
4548 Assert(tria == a.tria || tria == nullptr || a.tria == nullptr,
4550 return ((tria == a.tria) && (level() == a.level()) &&
4551 (present_index == a.present_index));
4552}
4553
4554
4555
4556template <int structdim, int dim, int spacedim>
4557inline bool
4560{
4561 Assert(tria == a.tria || tria == nullptr || a.tria == nullptr,
4563 return ((tria != a.tria) || (level() != a.level()) ||
4564 (present_index != a.present_index));
4565}
4566
4567
4568
4569template <int structdim, int dim, int spacedim>
4570inline bool
4573{
4575
4576 if (level() != other.level())
4577 return (level() < other.level());
4578
4579 return (present_index < other.present_index);
4580}
4581
4582
4583
4584template <int structdim, int dim, int spacedim>
4585inline int
4587{
4588 // This is always zero or invalid
4589 // if the object is not a cell
4590 return this->get_level();
4591}
4592
4593
4594
4595template <int structdim, int dim, int spacedim>
4596inline int
4598{
4599 return present_index;
4600}
4601
4602
4603
4604template <int structdim, int dim, int spacedim>
4607{
4608 if ((level() >= 0) && (present_index >= 0))
4609 return IteratorState::valid;
4610 else if (present_index == -1)
4612 else
4614}
4615
4616
4617
4618template <int structdim, int dim, int spacedim>
4619inline const Triangulation<dim, spacedim> &
4621{
4622 return *tria;
4623}
4624
4625
4626
4627template <int structdim, int dim, int spacedim>
4628inline void
4630{
4631 // this iterator is used for
4632 // objects without level
4633 ++this->present_index;
4634
4635 if (structdim != dim)
4636 {
4637 // is index still in the range of
4638 // the vector? (note that we don't
4639 // have to set the level, since
4640 // dim!=1 and the object therefore
4641 // has no level)
4642 if (this->present_index >= static_cast<int>(objects().n_objects()))
4643 this->present_index = -1;
4644 }
4645 else
4646 {
4647 while (this->present_index >=
4648 static_cast<int>(this->tria->levels[level()]->cells.n_objects()))
4649 {
4650 // no -> go one level up until we find
4651 // one with more than zero cells
4652 this->set_level(level() + 1);
4653 this->present_index = 0;
4654 // highest level reached?
4655 if (level() >= static_cast<int>(this->tria->levels.size()))
4656 {
4657 // return with past the end pointer
4658 this->set_level(-1);
4659 this->present_index = -1;
4660 return;
4661 }
4662 }
4663 }
4664}
4665
4666
4667template <int structdim, int dim, int spacedim>
4668inline void
4670{
4671 // same as operator++
4672 --this->present_index;
4673
4674 if (structdim != dim)
4675 {
4676 if (this->present_index < 0)
4677 this->present_index = -1;
4678 }
4679 else
4680 {
4681 while (this->present_index < 0)
4682 {
4683 // no -> go one level down
4684 this->set_level(level() - 1);
4685 // lowest level reached?
4686 if (level() == -1)
4687 {
4688 // return with past the end pointer
4689 this->set_level(-1);
4690 this->present_index = -1;
4691 return;
4692 }
4693 // else
4694 this->present_index =
4695 this->tria->levels[level()]->cells.n_objects() - 1;
4696 }
4697 }
4698}
4699
4700
4701
4702template <int structdim, int dim, int spacedim>
4703inline ::internal::TriangulationImplementation::TriaObjects &
4705{
4706 if (structdim == dim)
4707 return this->tria->levels[level()]->cells;
4708
4709 if (structdim == 1 && dim > 1)
4710 return this->tria->faces->lines;
4711
4712 if (structdim == 2 && dim > 2)
4713 return this->tria->faces->quads;
4714
4716
4717 return this->tria->levels[level()]->cells;
4718}
4719
4720
4721
4722/*---------------------- Functions: InvalidAccessor -------------------------*/
4723
4724template <int structdim, int dim, int spacedim>
4726 const int,
4727 const int,
4728 const AccessorData *)
4729{
4730 Assert(false,
4731 ExcMessage("You are attempting an invalid conversion between "
4732 "iterator/accessor types. The constructor you call "
4733 "only exists to make certain template constructs "
4734 "easier to write as dimension independent code but "
4735 "the conversion is not valid in the current context."));
4736}
4737
4738
4739
4740template <int structdim, int dim, int spacedim>
4742 const InvalidAccessor &)
4743{
4744 Assert(false,
4745 ExcMessage("You are attempting an invalid conversion between "
4746 "iterator/accessor types. The constructor you call "
4747 "only exists to make certain template constructs "
4748 "easier to write as dimension independent code but "
4749 "the conversion is not valid in the current context."));
4750}
4751
4752
4753
4754template <int structdim, int dim, int spacedim>
4755void
4757{
4758 // nothing to do here. we could throw an exception but we can't get here
4759 // without first creating an object which would have already thrown.
4760}
4761
4762
4763
4764template <int structdim, int dim, int spacedim>
4765bool
4767 const InvalidAccessor &) const
4768{
4769 // nothing to do here. we could throw an exception but we can't get here
4770 // without first creating an object which would have already thrown.
4771 return false;
4772}
4773
4774
4775
4776template <int structdim, int dim, int spacedim>
4777bool
4779 const InvalidAccessor &) const
4780{
4781 // nothing to do here. we could throw an exception but we can't get here
4782 // without first creating an object which would have already thrown.
4783 return true;
4784}
4785
4786
4787
4788template <int structdim, int dim, int spacedim>
4789bool
4791{
4792 // nothing to do here. we could throw an exception but we can't get here
4793 // without first creating an object which would have already thrown.
4794 return false;
4795}
4796
4797
4798
4799template <int structdim, int dim, int spacedim>
4800bool
4802{
4803 // nothing to do here. we could throw an exception but we can't get here
4804 // without first creating an object which would have already thrown.
4805 return false;
4806}
4807
4808
4809
4810template <int structdim, int dim, int spacedim>
4811void
4813{}
4814
4815
4816
4817template <int structdim, int dim, int spacedim>
4818void
4820{}
4821
4822
4823
4824template <int structdim, int dim, int spacedim>
4827{
4829}
4830
4831
4832
4833template <int structdim, int dim, int spacedim>
4834unsigned int
4836{
4838}
4839
4840
4841
4842template <int structdim, int dim, int spacedim>
4843void
4845 const unsigned int) const
4846{
4847 Assert(false,
4848 ExcMessage("You are trying to set the user index of an "
4849 "invalid object."));
4850}
4851
4852
4853
4854template <int structdim, int dim, int spacedim>
4855void
4857 const types::manifold_id) const
4858{
4859 Assert(false,
4860 ExcMessage("You are trying to set the manifold id of an "
4861 "invalid object."));
4862}
4863
4864
4865
4866template <int structdim, int dim, int spacedim>
4867inline Point<spacedim> &
4869{
4870 // nothing to do here. we could throw an exception but we can't get here
4871 // without first creating an object which would have already thrown
4872 static Point<spacedim> invalid_vertex;
4873 return invalid_vertex;
4874}
4875
4876
4877template <int structdim, int dim, int spacedim>
4878inline void *
4880{
4881 // nothing to do here. we could throw an exception but we can't get here
4882 // without first creating an object which would have already thrown
4883 return nullptr;
4884}
4885
4886
4887
4888template <int structdim, int dim, int spacedim>
4889inline void *
4891{
4892 // nothing to do here. we could throw an exception but we can't get here
4893 // without first creating an object which would have already thrown
4894 return nullptr;
4895}
4896
4897
4898/*------------------------ Functions: TriaAccessor ---------------------------*/
4899
4900
4901namespace internal
4902{
4903 namespace TriaAccessorImplementation
4904 {
4905 // make sure that if in the following we write TriaAccessor we mean the
4906 // *class* ::TriaAccessor, not the enclosing namespace
4907 // ::internal::TriaAccessor
4908 using ::TriaAccessor;
4909
4914 struct Implementation
4915 {
4916 template <int dim, int spacedim>
4917 static std::array<unsigned int, 1>
4918 get_line_indices_of_cell(const TriaAccessor<1, dim, spacedim> &)
4919 {
4921 return {};
4922 }
4923
4924
4925
4926 template <int structdim, int dim, int spacedim>
4927 static std::array<unsigned int, 4>
4928 get_line_indices_of_cell(const TriaAccessor<2, dim, spacedim> &cell)
4929 {
4930 // For 2d cells the access cell->line_orientation() is already
4931 // efficient
4932 std::array<unsigned int, 4> line_indices = {};
4933 for (const unsigned int line : cell.line_indices())
4934 line_indices[line] = cell.line_index(line);
4935 return line_indices;
4936 }
4937
4942 template <int structdim, int dim, int spacedim>
4943 static std::array<unsigned int, 12>
4944 get_line_indices_of_cell(
4946 {
4947 std::array<unsigned int, 12> line_indices = {};
4948
4949 // For hexahedra, the classical access via quads -> lines is too
4950 // inefficient. Unroll this code here to allow the compiler to inline
4951 // the necessary functions.
4952 const auto cell_reference_cell = cell.reference_cell();
4953 if (cell_reference_cell == ReferenceCells::Hexahedron)
4954 {
4956 for (unsigned int f = 4; f < 6; ++f)
4957 {
4958 const auto orientation = cell.combined_face_orientation(f);
4959
4960 // It might seem superfluous to spell out the four indices
4961 // that get later consumed by a for loop over these four
4962 // elements; however, for the compiler it is easier to inline
4963 // the statement of standard_to_real_face_line() when next to
4964 // each other, as opposed to be interleaved with a
4965 // line_index() call.
4966 const std::array<unsigned int, 4> my_indices{{
4967 reference_cell.standard_to_real_face_line(0, f, orientation),
4968 reference_cell.standard_to_real_face_line(1, f, orientation),
4969 reference_cell.standard_to_real_face_line(2, f, orientation),
4970 reference_cell.standard_to_real_face_line(3, f, orientation),
4971 }};
4972 const auto quad = cell.quad(f);
4973 for (unsigned int l = 0; l < 4; ++l)
4974 line_indices[4 * (f - 4) + l] =
4975 quad->line_index(my_indices[l]);
4976 }
4977 for (unsigned int f = 0; f < 2; ++f)
4978 {
4979 const auto orientation =
4980 cell.get_triangulation()
4981 .levels[cell.level()]
4982 ->face_orientations.get_combined_orientation(cell.index(),
4983 f);
4984 const std::array<unsigned int, 2> my_indices{{
4985 reference_cell.standard_to_real_face_line(0, f, orientation),
4986 reference_cell.standard_to_real_face_line(1, f, orientation),
4987 }};
4988 const auto quad = cell.quad(f);
4989 line_indices[8 + f] = quad->line_index(my_indices[0]);
4990 line_indices[10 + f] = quad->line_index(my_indices[1]);
4991 }
4992 }
4993 else if (cell_reference_cell == ReferenceCells::Tetrahedron)
4994 {
4996 const std::array<unsigned int, 3> orientations{
4999 cell.combined_face_orientation(2)}};
5000 const std::array<unsigned int, 6> my_indices{{
5001 reference_cell.standard_to_real_face_line(0, 0, orientations[0]),
5002 reference_cell.standard_to_real_face_line(1, 0, orientations[0]),
5003 reference_cell.standard_to_real_face_line(2, 0, orientations[0]),
5004 reference_cell.standard_to_real_face_line(1, 1, orientations[1]),
5005 reference_cell.standard_to_real_face_line(2, 1, orientations[1]),
5006 reference_cell.standard_to_real_face_line(1, 2, orientations[2]),
5007 }};
5008 const std::array<decltype(cell.quad(0)), 3> quads{
5009 {cell.quad(0), cell.quad(1), cell.quad(2)}};
5010 line_indices[0] = quads[0]->line_index(my_indices[0]);
5011 line_indices[1] = quads[0]->line_index(my_indices[1]);
5012 line_indices[2] = quads[0]->line_index(my_indices[2]);
5013 line_indices[3] = quads[1]->line_index(my_indices[3]);
5014 line_indices[4] = quads[1]->line_index(my_indices[4]);
5015 line_indices[5] = quads[2]->line_index(my_indices[5]);
5016 }
5017 else
5018 // For other shapes (wedges, pyramids), we do not currently
5019 // implement an optimized function.
5020 for (unsigned int l = 0; l < std::min(12U, cell.n_lines()); ++l)
5021 line_indices[l] = cell.line_index(l);
5022
5023 return line_indices;
5024 }
5025
5026
5027
5036 template <int dim, int spacedim>
5037 static std::pair<std::array<unsigned int, 1>,
5038 std::array<types::geometric_orientation, 1>>
5039 get_line_indices_and_orientations_of_cell(
5041 {
5043 return {};
5044 }
5045
5046
5047
5054 template <int dim, int spacedim>
5055 static std::pair<std::array<unsigned int, 4>,
5056 std::array<types::geometric_orientation, 4>>
5057 get_line_indices_and_orientations_of_cell(
5059 {
5060 // For 2d cells the access cell->line_orientation() is already
5061 // efficient
5062 std::array<types::geometric_orientation, 4> line_orientations = {};
5063 std::array<unsigned int, 4> line_indices = {};
5064 for (const unsigned int line : cell.line_indices())
5065 {
5066 line_orientations[line] = cell.line_orientation(line);
5067 line_indices[line] = cell.line_index(line);
5068 }
5069 return std::make_pair(line_indices, line_orientations);
5070 }
5071
5072
5073
5080 template <int dim, int spacedim>
5081 static std::pair<std::array<unsigned int, 12>,
5082 std::array<types::geometric_orientation, 12>>
5083 get_line_indices_and_orientations_of_cell(
5085 {
5086 std::array<types::geometric_orientation, 12> line_orientations = {};
5087 std::array<unsigned int, 12> line_indices = {};
5088
5089 // For hexahedra, the classical access via quads -> lines is too
5090 // inefficient. Unroll this code here to allow the compiler to inline
5091 // the necessary functions.
5092 const auto cell_reference_cell = cell.reference_cell();
5093 if (cell_reference_cell == ReferenceCells::Hexahedron)
5094 {
5096 for (unsigned int f = 4; f < 6; ++f)
5097 {
5098 const auto orientation = cell.combined_face_orientation(f);
5099
5100 // It might seem superfluous to spell out the four indices and
5101 // orientations that get later consumed by a for loop over
5102 // these four elements; however, for the compiler it is easier
5103 // to inline the statement of standard_to_real_face_line()
5104 // when next to each other, as opposed to be interleaved with
5105 // a line_index() call.
5106 const std::array<unsigned int, 4> my_indices{{
5107 reference_cell.standard_to_real_face_line(0, f, orientation),
5108 reference_cell.standard_to_real_face_line(1, f, orientation),
5109 reference_cell.standard_to_real_face_line(2, f, orientation),
5110 reference_cell.standard_to_real_face_line(3, f, orientation),
5111 }};
5112 const auto quad = cell.quad(f);
5113 for (unsigned int l = 0; l < 4; ++l)
5114 line_indices[4 * (f - 4) + l] =
5115 quad->line_index(my_indices[l]);
5116 const std::array<types::geometric_orientation, 4>
5117 my_orientations{{
5118 reference_cell.face_to_cell_line_orientation(
5119 0, f, orientation, quad->line_orientation(my_indices[0])),
5120 reference_cell.face_to_cell_line_orientation(
5121 1, f, orientation, quad->line_orientation(my_indices[1])),
5122 reference_cell.face_to_cell_line_orientation(
5123 2, f, orientation, quad->line_orientation(my_indices[2])),
5124 reference_cell.face_to_cell_line_orientation(
5125 3, f, orientation, quad->line_orientation(my_indices[3])),
5126 }};
5127 for (unsigned int l = 0; l < 4; ++l)
5128 line_orientations[4 * (f - 4) + l] = my_orientations[l];
5129 }
5130 for (unsigned int f = 0; f < 2; ++f)
5131 {
5132 const auto orientation = cell.combined_face_orientation(f);
5133
5134 const std::array<unsigned int, 2> my_indices{{
5135 reference_cell.standard_to_real_face_line(0, f, orientation),
5136 reference_cell.standard_to_real_face_line(1, f, orientation),
5137 }};
5138 const auto quad = cell.quad(f);
5139 line_indices[8 + f] = quad->line_index(my_indices[0]);
5140 line_indices[10 + f] = quad->line_index(my_indices[1]);
5141 const std::array<types::geometric_orientation, 2>
5142 my_orientations{{
5143 reference_cell.face_to_cell_line_orientation(
5144 0, f, orientation, quad->line_orientation(my_indices[0])),
5145 reference_cell.face_to_cell_line_orientation(
5146 1, f, orientation, quad->line_orientation(my_indices[1])),
5147 }};
5148 line_orientations[8 + f] = my_orientations[0];
5149 line_orientations[10 + f] = my_orientations[1];
5150 }
5151 }
5152 else if (cell_reference_cell == ReferenceCells::Tetrahedron)
5153 {
5155 const std::array<types::geometric_orientation, 3> orientations{
5158 cell.combined_face_orientation(2)}};
5159 const std::array<unsigned int, 6> my_indices{{
5160 reference_cell.standard_to_real_face_line(0, 0, orientations[0]),
5161 reference_cell.standard_to_real_face_line(1, 0, orientations[0]),
5162 reference_cell.standard_to_real_face_line(2, 0, orientations[0]),
5163 reference_cell.standard_to_real_face_line(1, 1, orientations[1]),
5164 reference_cell.standard_to_real_face_line(2, 1, orientations[1]),
5165 reference_cell.standard_to_real_face_line(1, 2, orientations[2]),
5166 }};
5167 const std::array<decltype(cell.quad(0)), 3> quads{
5168 {cell.quad(0), cell.quad(1), cell.quad(2)}};
5169 line_indices[0] = quads[0]->line_index(my_indices[0]);
5170 line_indices[1] = quads[0]->line_index(my_indices[1]);
5171 line_indices[2] = quads[0]->line_index(my_indices[2]);
5172 line_indices[3] = quads[1]->line_index(my_indices[3]);
5173 line_indices[4] = quads[1]->line_index(my_indices[4]);
5174 line_indices[5] = quads[2]->line_index(my_indices[5]);
5175
5176 line_orientations[0] = reference_cell.face_to_cell_line_orientation(
5177 0, 0, orientations[0], quads[0]->line_orientation(my_indices[0]));
5178 line_orientations[1] = reference_cell.face_to_cell_line_orientation(
5179 1, 0, orientations[0], quads[0]->line_orientation(my_indices[1]));
5180 line_orientations[2] = reference_cell.face_to_cell_line_orientation(
5181 2, 0, orientations[0], quads[0]->line_orientation(my_indices[2]));
5182 line_orientations[3] = reference_cell.face_to_cell_line_orientation(
5183 1, 1, orientations[1], quads[1]->line_orientation(my_indices[3]));
5184 line_orientations[4] = reference_cell.face_to_cell_line_orientation(
5185 2, 1, orientations[1], quads[1]->line_orientation(my_indices[4]));
5186 line_orientations[5] = reference_cell.face_to_cell_line_orientation(
5187 1, 2, orientations[2], quads[2]->line_orientation(my_indices[5]));
5188 }
5189 else
5190 // For other shapes (wedges, pyramids), we do not currently implement
5191 // an optimized function
5192 for (unsigned int l = 0; l < std::min(12U, cell.n_lines()); ++l)
5193 {
5194 line_indices[l] = cell.line_index(l);
5195 line_orientations[l] = cell.line_orientation(l);
5196 }
5197
5198 return std::make_pair(line_indices, line_orientations);
5199 }
5200 };
5201 } // namespace TriaAccessorImplementation
5202} // namespace internal
5203
5204
5205
5206template <int structdim, int dim, int spacedim>
5208 const Triangulation<dim, spacedim> *parent,
5209 const int level,
5210 const int index,
5211 const AccessorData *local_data)
5212 : TriaAccessorBase<structdim, dim, spacedim>(parent, level, index, local_data)
5213{}
5214
5215
5216
5217template <int structdim, int dim, int spacedim>
5218inline bool
5220{
5221 Assert(this->state() == IteratorState::valid,
5222 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5223 *this));
5224 return this->objects().used[this->present_index];
5225}
5226
5227
5228
5229template <int structdim, int dim, int spacedim>
5232 const unsigned int i) const
5233{
5235 0,
5236 vertex_index(i));
5237}
5238
5239
5240
5241template <int structdim, int dim, int spacedim>
5244{
5245 if constexpr (structdim == 0)
5247 else if constexpr (structdim == 1)
5248 return ReferenceCells::Line;
5249 else if constexpr (structdim == dim)
5250 return this->tria->levels[this->level()]
5251 ->reference_cell[this->present_index];
5252 else
5253 return this->tria->faces->get_quad_type(this->present_index);
5254}
5255
5256
5257
5258template <int structdim, int dim, int spacedim>
5259inline unsigned int
5261 const unsigned int vertex_no) const
5262{
5263 AssertIndexRange(vertex_no, this->n_vertices());
5264
5265 if constexpr (structdim == 1)
5266 {
5267 // This branch needs to be first (and not combined with the structdim ==
5268 // dim branch) so that we can get line vertex indices when setting up the
5269 // cell vertex index cache
5270 return this->objects().get_bounding_object(this->present_index,
5271 vertex_no);
5272 }
5273 else if constexpr (structdim == dim)
5274 {
5275 // This branch should only be used after the cell vertex index cache is
5276 // set up
5277 const auto vertex_index =
5278 this->tria->levels[this->level()]->cached_vertex_index(
5279 this->present_index, vertex_no);
5280 Assert(
5281 vertex_index != numbers::invalid_unsigned_int,
5282 ExcMessage(
5283 "The present vertex's vertex_index is not valid. This is typically "
5284 "caused by calling cell->vertex_index() during grid refinement for "
5285 "a newly created cell, since the cell vertex index cache is not "
5286 "complete at that point."));
5287 return vertex_index;
5288 }
5289 else if constexpr (structdim == 2)
5290 {
5291 const auto [line_index, vertex_index] =
5292 this->reference_cell().standard_vertex_to_face_and_vertex_index(
5293 vertex_no);
5294 const auto vertex_within_line_index =
5295 this->reference_cell().standard_to_real_face_vertex(
5296 vertex_index, line_index, this->line_orientation(line_index));
5297
5298 return this->line(line_index)->vertex_index(vertex_within_line_index);
5299 }
5300 else
5301 {
5304 }
5305}
5306
5307
5308
5309template <int structdim, int dim, int spacedim>
5310inline Point<spacedim> &
5311TriaAccessor<structdim, dim, spacedim>::vertex(const unsigned int i) const
5312{
5313 return const_cast<Point<spacedim> &>(this->tria->vertices[vertex_index(i)]);
5314}
5315
5316
5317
5318template <int structdim, int dim, int spacedim>
5319inline typename ::internal::TriangulationImplementation::
5320 Iterators<dim, spacedim>::line_iterator
5321 TriaAccessor<structdim, dim, spacedim>::line(const unsigned int i) const
5322{
5323 // checks happen in line_index
5324 return typename ::internal::TriangulationImplementation::
5325 Iterators<dim, spacedim>::line_iterator(this->tria, 0, line_index(i));
5326}
5327
5328
5329
5330template <int structdim, int dim, int spacedim>
5331inline unsigned int
5333{
5334 (void)i;
5335 AssertIndexRange(i, this->n_lines());
5336 Assert(structdim != 1,
5337 ExcMessage("You can't ask for the index of a line bounding a "
5338 "one-dimensional cell because it is not bounded by "
5339 "lines."));
5340
5341 if constexpr (structdim == 2)
5342 {
5343 return this->objects().get_bounding_object(this->present_index, i);
5344 }
5345 else if constexpr (structdim == 3)
5346 {
5347 const auto [face_index, line_index] =
5348 this->reference_cell().standard_line_to_face_and_line_index(i);
5349 const auto line_within_face_index =
5350 this->reference_cell().standard_to_real_face_line(
5351 line_index, face_index, this->combined_face_orientation(face_index));
5352
5353 return this->quad(face_index)->line_index(line_within_face_index);
5354 }
5355
5358}
5359
5360
5361
5362template <int structdim, int dim, int spacedim>
5363inline typename ::internal::TriangulationImplementation::
5364 Iterators<dim, spacedim>::quad_iterator
5365 TriaAccessor<structdim, dim, spacedim>::quad(const unsigned int i) const
5366{
5367 // checks happen in quad_index
5368 return typename ::internal::TriangulationImplementation::
5369 Iterators<dim, spacedim>::quad_iterator(this->tria, 0, quad_index(i));
5370}
5371
5372
5373
5374template <int structdim, int dim, int spacedim>
5375inline unsigned int
5377 const unsigned int face_no) const
5378{
5379 Assert(structdim == 3,
5380 ExcMessage("You can't ask for the index of a quad bounding "
5381 "a one- or two-dimensional cell because it is not "
5382 "bounded by quads."));
5383 // work around a bogus GCC-9 warning which considers face_no unused except in
5384 // 3d
5385 (void)face_no;
5386 if constexpr (structdim == 3)
5387 return this->objects().get_bounding_object(this->present_index, face_no);
5388 else
5390}
5391
5392
5393
5394template <int structdim, int dim, int spacedim>
5397 const unsigned int face) const
5398{
5400 AssertIndexRange(face, n_faces());
5401 Assert(structdim == dim,
5402 ExcMessage("This function can only be used on objects "
5403 "that are cells, but not on faces or edges "
5404 "that bound cells."));
5405 // work around a bogus GCC-9 warning which considers face unused except in 3d
5406 (void)face;
5407
5408 if constexpr (structdim == 1)
5410 else if constexpr (structdim == 2)
5411 {
5412 // if all elements are quads (or if we have a very special consistently
5413 // oriented triangular mesh) then we do not store this array
5414 if (this->tria->levels[this->level()]->face_orientations.n_objects() == 0)
5416 else
5417 return this->tria->levels[this->level()]
5418 ->face_orientations.get_combined_orientation(this->present_index,
5419 face);
5420 }
5421 else
5422 return this->tria->levels[this->level()]
5423 ->face_orientations.get_combined_orientation(this->present_index, face);
5424}
5425
5426
5427
5428template <int structdim, int dim, int spacedim>
5429inline bool
5431 const unsigned int face) const
5432{
5434 AssertIndexRange(face, n_faces());
5435 Assert(structdim == dim,
5436 ExcMessage("This function can only be used on objects "
5437 "that are cells, but not on faces or edges "
5438 "that bound cells."));
5439 // work around a bogus GCC-9 warning which considers face unused in 1d
5440 (void)face;
5441
5442 if constexpr (structdim == 1)
5443 // in 1d 'faces' are vertices and those are always consistently oriented
5444 return true;
5445 else if constexpr (structdim == 2)
5446 return this->line_orientation(face) ==
5448 else
5449 return this->tria->levels[this->level()]->face_orientations.get_orientation(
5450 this->present_index, face);
5451}
5452
5453
5454
5455template <int structdim, int dim, int spacedim>
5456inline bool
5457TriaAccessor<structdim, dim, spacedim>::face_flip(const unsigned int face) const
5458{
5460 Assert(structdim == dim,
5461 ExcMessage("This function can only be used on objects "
5462 "that are cells, but not on faces or edges "
5463 "that bound cells."));
5464 AssertIndexRange(face, n_faces());
5465 // work around a bogus GCC-9 warning which considers face unused except in 3d
5466 (void)face;
5467
5468 if constexpr (structdim == 3)
5469 return this->tria->levels[this->level()]->face_orientations.get_flip(
5470 this->present_index, face);
5471 else
5472 // In 1d and 2d, face_flip is always false as faces can only be
5473 // 'flipped' in 3d.
5474 return false;
5475}
5476
5477
5478template <int structdim, int dim, int spacedim>
5479inline bool
5481 const unsigned int face) const
5482{
5484 Assert(structdim == dim,
5485 ExcMessage("This function can only be used on objects "
5486 "that are cells, but not on faces or edges "
5487 "that bound cells."));
5488 AssertIndexRange(face, n_faces());
5489 // work around a bogus GCC-9 warning which considers face unused except in 3d
5490 (void)face;
5491
5492 if constexpr (structdim == 3)
5493 return this->tria->levels[this->level()]->face_orientations.get_rotation(
5494 this->present_index, face);
5495 else
5496 // In 1d and 2d, face_rotation is always false as faces can only be
5497 // 'rotated' in 3d.
5498 return false;
5499}
5500
5501
5502
5503template <int structdim, int dim, int spacedim>
5506 const unsigned int line) const
5507{
5509 AssertIndexRange(line, this->n_lines());
5510 // work around a bogus GCC-9 warning which considers line unused in 1d
5511 (void)line;
5512
5513 if constexpr (structdim == 1)
5515 else if constexpr (structdim == 2 && dim == 2)
5516 // lines in 2d are faces
5517 {
5518 const auto combined_orientation = combined_face_orientation(line);
5519 Assert(combined_orientation == numbers::default_geometric_orientation ||
5520 combined_orientation == numbers::reverse_line_orientation,
5522 return combined_orientation;
5523 }
5524 else if constexpr (structdim == 2 && dim == 3)
5525 {
5526 return this->tria->faces->get_line_orientation(this->present_index, line);
5527 }
5528 else if constexpr (structdim == 3 && dim == 3)
5529 {
5530 const auto reference_cell = this->reference_cell();
5531 // First pick a face on which this line is a part of, and the
5532 // index of the line within.
5533 const auto [face_index, line_index] =
5534 reference_cell.standard_line_to_face_and_line_index(line);
5535 const auto line_within_face_index =
5536 reference_cell.standard_to_real_face_line(
5537 line_index, face_index, this->combined_face_orientation(face_index));
5538
5539 // Then query how that line is oriented within that face:
5540 return reference_cell.face_to_cell_line_orientation(
5541 line_index,
5542 face_index,
5543 this->combined_face_orientation(face_index),
5544 this->quad(face_index)->line_orientation(line_within_face_index));
5545 }
5546 else
5547 {
5550 }
5551}
5552
5553
5554
5555template <int structdim, int dim, int spacedim>
5556inline void
5558 const unsigned int line,
5559 const types::geometric_orientation value) const
5560{
5562 AssertIndexRange(line, this->n_lines());
5563 Assert(dim != 1,
5564 ExcMessage("In 1d lines are cells and thus do not need to have their "
5565 "orientations set."));
5566 Assert(dim != 2,
5567 ExcMessage("In 2d lines are faces, and, for compatibility with other "
5568 "dimensions, their orientations should be set via "
5569 "set_combined_face_orientation()."));
5570 // work around a bogus GCC-9 warning which considers line and value unused
5571 // except in 3d
5572 (void)line;
5573 (void)value;
5574
5575 if constexpr (dim == 3)
5576 {
5577 // We set line orientations per face, not per cell, so this only works for
5578 // faces in 3d.
5579 Assert(structdim == 2, ExcNotImplemented());
5580 this->tria->faces->set_line_orientation(this->present_index, line, value);
5581 }
5582}
5583
5584
5585
5586template <int structdim, int dim, int spacedim>
5587inline void
5589 const unsigned int face_no,
5590 const types::geometric_orientation combined_orientation) const
5591{
5593 AssertIndexRange(face_no, this->n_faces());
5594 Assert(structdim == dim,
5595 ExcMessage("This function can only be used on objects that are cells "
5596 "and not on objects which bound cells."));
5597 AssertIndexRange(combined_orientation,
5598 reference_cell().n_face_orientations(face_no));
5599
5600 // face_orientations is not set up in 1d
5601 if (dim > 1)
5602 this->tria->levels[this->level()]
5603 ->face_orientations.set_combined_orientation(this->present_index,
5604 face_no,
5605 combined_orientation);
5606}
5607
5608
5609
5610template <int structdim, int dim, int spacedim>
5611void
5613{
5614 Assert(this->state() == IteratorState::valid,
5615 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5616 *this));
5617 this->objects().used[this->present_index] = true;
5618}
5619
5620
5621
5622template <int structdim, int dim, int spacedim>
5623void
5625{
5626 Assert(this->state() == IteratorState::valid,
5627 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5628 *this));
5629 this->objects().used[this->present_index] = false;
5630}
5631
5632
5633template <int structdim, int dim, int spacedim>
5634int
5636{
5638 AssertIndexRange(i, n_children());
5639
5640 // each set of two children are stored
5641 // consecutively, so we only have to find
5642 // the location of the set of children
5643 const auto &objects = this->objects();
5644 const unsigned int n_sets_of_two = objects.children_per_object / 2;
5645 return objects.children[n_sets_of_two * this->present_index + i / 2] + i % 2;
5646}
5647
5648
5649
5650template <int structdim, int dim, int spacedim>
5651int
5653 const unsigned int i) const
5654{
5655 AssertIndexRange(i, this->objects().children_per_object);
5656
5657 switch (structdim)
5658 {
5659 case 1:
5660 return child_index(i);
5661 case 2:
5662 {
5663 const RefinementCase<2> this_refinement_case(
5664 static_cast<std::uint8_t>(refinement_case()));
5665
5666 Assert(this_refinement_case != RefinementCase<2>::no_refinement,
5668
5669 if (this_refinement_case == RefinementCase<2>::cut_xy)
5670 return child_index(i);
5671 else if ((this_refinement_case == RefinementCase<2>::cut_x) &&
5672 (child(i % 2)->refinement_case() ==
5674 return child(i % 2)->child_index(i / 2);
5675 else if ((this_refinement_case == RefinementCase<2>::cut_y) &&
5676 (child(i / 2)->refinement_case() ==
5678 return child(i / 2)->child_index(i % 2);
5679 else
5680 Assert(
5681 false,
5682 ExcMessage(
5683 "This cell has no grandchildren equivalent to isotropic refinement"));
5684 break;
5685 }
5686
5687 case 3:
5689 }
5690 return -1;
5691}
5692
5693
5694
5695template <int structdim, int dim, int spacedim>
5698{
5699 Assert(this->state() == IteratorState::valid,
5700 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5701 *this));
5702
5703 switch (structdim)
5704 {
5705 case 1:
5707 this->objects().children[this->present_index] != -1 ?
5708 // cast the branches here first to uchar and then (above) to
5709 // RefinementCase<structdim> so that the conversion is valid even
5710 // for the case structdim>1 (for which this part of the code is dead
5711 // anyway)
5712 static_cast<std::uint8_t>(RefinementCase<1>::cut_x) :
5713 static_cast<std::uint8_t>(RefinementCase<1>::no_refinement)));
5714
5715 default:
5716 Assert(static_cast<unsigned int>(this->present_index) <
5717 this->objects().refinement_cases.size(),
5718 ExcIndexRange(this->present_index,
5719 0,
5720 this->objects().refinement_cases.size()));
5721
5722 return (static_cast<RefinementCase<structdim>>(
5723 this->objects().refinement_cases[this->present_index]));
5724 }
5725}
5726
5727
5728
5729template <int structdim, int dim, int spacedim>
5731TriaAccessor<structdim, dim, spacedim>::child(const unsigned int i) const
5732
5733{
5734 // checking of 'i' happens in child_index
5736 this->tria, (dim == structdim ? this->level() + 1 : 0), child_index(i));
5737
5738 Assert((q.state() == IteratorState::past_the_end) || q->used(),
5740
5741 return q;
5742}
5743
5744
5745
5746template <int structdim, int dim, int spacedim>
5747inline unsigned int
5750{
5751 const auto n_children = this->n_children();
5752 for (unsigned int child_n = 0; child_n < n_children; ++child_n)
5753 if (this->child(child_n) == child)
5754 return child_n;
5755
5756 Assert(false,
5757 ExcMessage("The given child is not a child of the current object."));
5759}
5760
5761
5762
5763template <int structdim, int dim, int spacedim>
5766 const unsigned int i) const
5767{
5768 // checking of 'i' happens in child() or child_index() called below
5769 switch (structdim)
5770 {
5771 case 1:
5772 // no anisotropic refinement in 1d
5773 return child(i);
5774
5775 case 2:
5776 {
5777 const RefinementCase<2> this_refinement_case(
5778 static_cast<std::uint8_t>(refinement_case()));
5779
5780 Assert(this_refinement_case != RefinementCase<2>::no_refinement,
5782
5783 if (this_refinement_case == RefinementCase<2>::cut_xy)
5784 return child(i);
5785 else if ((this_refinement_case == RefinementCase<2>::cut_x) &&
5786 (child(i % 2)->refinement_case() ==
5788 return child(i % 2)->child(i / 2);
5789 else if ((this_refinement_case == RefinementCase<2>::cut_y) &&
5790 (child(i / 2)->refinement_case() ==
5792 return child(i / 2)->child(i % 2);
5793 else
5794 Assert(
5795 false,
5796 ExcMessage(
5797 "This cell has no grandchildren equivalent to isotropic refinement"));
5798 break;
5799 }
5800
5801 default:
5803 }
5804 // we don't get here but have to return
5805 // something...
5806 return child(0);
5807}
5808
5809
5810
5811template <int structdim, int dim, int spacedim>
5812inline bool
5814{
5815 Assert(this->state() == IteratorState::valid,
5816 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5817 *this));
5818
5819 // each set of two children are stored consecutively, so we only have to find
5820 // the location of the set of children
5821 const auto &objects = this->objects();
5822 const unsigned int n_sets_of_two = objects.children_per_object / 2;
5823 return (objects.children[n_sets_of_two * this->present_index] != -1);
5824}
5825
5826
5827
5828template <int structdim, int dim, int spacedim>
5829inline unsigned int
5831{
5832 Assert(this->state() == IteratorState::valid,
5833 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5834 *this));
5835
5836 return reference_cell().n_children(refinement_case());
5837}
5838
5839
5840
5841template <int structdim, int dim, int spacedim>
5842inline void
5844 const RefinementCase<structdim> &refinement_case) const
5845{
5846 Assert(this->state() == IteratorState::valid,
5847 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5848 *this));
5849 Assert(static_cast<unsigned int>(this->present_index) <
5850 this->objects().refinement_cases.size(),
5851 ExcIndexRange(this->present_index,
5852 0,
5853 this->objects().refinement_cases.size()));
5854
5855 this->objects().refinement_cases[this->present_index] = refinement_case;
5856}
5857
5858
5859template <int structdim, int dim, int spacedim>
5860inline void
5862{
5863 Assert(this->state() == IteratorState::valid,
5864 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5865 *this));
5866 Assert(static_cast<unsigned int>(this->present_index) <
5867 this->objects().refinement_cases.size(),
5868 ExcIndexRange(this->present_index,
5869 0,
5870 this->objects().refinement_cases.size()));
5871
5872 this->objects().refinement_cases[this->present_index] =
5874}
5875
5876
5877
5878template <int structdim, int dim, int spacedim>
5879void
5881 const int index) const
5882{
5885
5886 // each set of two children are stored consecutively, so we only have to find
5887 // the location of the set of children
5888 auto &objects = this->objects();
5889 const unsigned int n_sets_of_two = objects.children_per_object / 2;
5890 Assert(
5891 // clearing the child index for a cell
5892 (index == -1) ||
5893 // if setting the child index for the i'th child (with i==0), then the
5894 // index must be a non-negative number
5895 (i == 0 && !this->has_children() && (index >= 0)) ||
5896 // if setting the child index for the i'th child (with i>0), then the
5897 // previously stored index must be the invalid index
5898 (i > 0 && this->has_children() && (index >= 0) &&
5899 objects.children[n_sets_of_two * this->present_index + i / 2] == -1),
5901
5902 objects.children[n_sets_of_two * this->present_index + i / 2] = index;
5903}
5904
5905
5906
5907template <int structdim, int dim, int spacedim>
5908void
5910{
5911 // each set of two children are stored consecutively, so we only have to find
5912 // the location of the set of children
5913 const auto &objects = this->objects();
5914 const unsigned int n_sets_of_two = objects.children_per_object / 2;
5915 for (unsigned int i = 0; i < n_sets_of_two; ++i)
5916 set_children(2 * i, -1);
5917}
5918
5919
5920
5921template <int structdim, int dim, int spacedim>
5922inline bool
5924{
5926 return this->objects().user_flags[this->present_index];
5927}
5928
5929
5930
5931template <int structdim, int dim, int spacedim>
5932inline void
5934{
5936 this->objects().user_flags[this->present_index] = true;
5937}
5938
5939
5940
5941template <int structdim, int dim, int spacedim>
5942inline void
5944{
5946 this->objects().user_flags[this->present_index] = false;
5947}
5948
5949
5950
5951template <int structdim, int dim, int spacedim>
5952void
5954{
5955 set_user_flag();
5956
5957 if (this->has_children())
5958 for (unsigned int c = 0; c < this->n_children(); ++c)
5959 this->child(c)->recursively_set_user_flag();
5960}
5961
5962
5963
5964template <int structdim, int dim, int spacedim>
5965void
5967{
5968 clear_user_flag();
5969
5970 if (this->has_children())
5971 for (unsigned int c = 0; c < this->n_children(); ++c)
5972 this->child(c)->recursively_clear_user_flag();
5973}
5974
5975
5976
5977template <int structdim, int dim, int spacedim>
5978void
5980{
5982 this->objects().clear_user_data(this->present_index);
5983}
5984
5985
5986
5987template <int structdim, int dim, int spacedim>
5988void
5990{
5992 this->objects().user_pointer(this->present_index) = p;
5993}
5994
5995
5996
5997template <int structdim, int dim, int spacedim>
5998void
6000{
6002 this->objects().user_pointer(this->present_index) = nullptr;
6003}
6004
6005
6006
6007template <int structdim, int dim, int spacedim>
6008void *
6010{
6012 return this->objects().user_pointer(this->present_index);
6013}
6014
6015
6016
6017template <int structdim, int dim, int spacedim>
6018void
6020 void *p) const
6021{
6022 set_user_pointer(p);
6023
6024 if (this->has_children())
6025 for (unsigned int c = 0; c < this->n_children(); ++c)
6026 this->child(c)->recursively_set_user_pointer(p);
6027}
6028
6029
6030
6031template <int structdim, int dim, int spacedim>
6032void
6034{
6035 clear_user_pointer();
6036
6037 if (this->has_children())
6038 for (unsigned int c = 0; c < this->n_children(); ++c)
6039 this->child(c)->recursively_clear_user_pointer();
6040}
6041
6042
6043
6044template <int structdim, int dim, int spacedim>
6045void
6047 const unsigned int p) const
6048{
6050 this->objects().user_index(this->present_index) = p;
6051}
6052
6053
6054
6055template <int structdim, int dim, int spacedim>
6056void
6058{
6060 this->objects().user_index(this->present_index) = 0;
6061}
6062
6063
6064
6065template <int structdim, int dim, int spacedim>
6066unsigned int
6068{
6070 return this->objects().user_index(this->present_index);
6071}
6072
6073
6074
6075template <int structdim, int dim, int spacedim>
6076void
6078 const unsigned int p) const
6079{
6080 set_user_index(p);
6081
6082 if (this->has_children())
6083 for (unsigned int c = 0; c < this->n_children(); ++c)
6084 this->child(c)->recursively_set_user_index(p);
6085}
6086
6087
6088
6089template <int structdim, int dim, int spacedim>
6090void
6092{
6093 clear_user_index();
6094
6095 if (this->has_children())
6096 for (unsigned int c = 0; c < this->n_children(); ++c)
6097 this->child(c)->recursively_clear_user_index();
6098}
6099
6100
6101
6102template <int structdim, int dim, int spacedim>
6103inline unsigned int
6105{
6106 if (!this->has_children())
6107 return 0;
6108
6109 unsigned int max_depth = 1;
6110 for (unsigned int c = 0; c < n_children(); ++c)
6111 max_depth = std::max(max_depth, child(c)->max_refinement_depth() + 1);
6112 return max_depth;
6113}
6114
6115
6116
6117template <int structdim, int dim, int spacedim>
6118unsigned int
6120{
6121 if (!this->has_children())
6122 return 1;
6123 else
6124 {
6125 unsigned int sum = 0;
6126 for (unsigned int c = 0; c < n_children(); ++c)
6127 sum += this->child(c)->n_active_descendants();
6128 return sum;
6129 }
6130}
6131
6132
6133
6134template <int structdim, int dim, int spacedim>
6137{
6138 Assert(structdim < dim, ExcImpossibleInDim(dim));
6140
6141 return this->objects()
6142 .boundary_or_material_id[this->present_index]
6143 .boundary_id;
6144}
6145
6146
6147
6148template <int structdim, int dim, int spacedim>
6149void
6151 const types::boundary_id boundary_ind) const
6152{
6153 Assert(structdim < dim, ExcImpossibleInDim(dim));
6156 ExcMessage("You are trying to set the boundary_id to an invalid "
6157 "value (numbers::internal_face_boundary_id is reserved)."));
6158 Assert(this->at_boundary(),
6159 ExcMessage("You are trying to set the boundary_id of an "
6160 "internal object, which is not allowed!"));
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 Assert(structdim < dim, ExcImpossibleInDim(dim));
6175
6176 this->objects().boundary_or_material_id[this->present_index].boundary_id =
6177 boundary_ind;
6178}
6179
6180
6181
6182template <int structdim, int dim, int spacedim>
6183void
6185 const types::boundary_id boundary_ind) const
6186{
6187 set_boundary_id(boundary_ind);
6188
6189 switch (structdim)
6190 {
6191 case 1:
6192 // 1d objects have no sub-objects where we have to do anything
6193 break;
6194
6195 case 2:
6196 // for boundary quads also set boundary_id of bounding lines
6197 for (unsigned int i = 0; i < this->n_lines(); ++i)
6198 this->line(i)->set_boundary_id(boundary_ind);
6199 break;
6200
6201 default:
6203 }
6204}
6205
6206
6207
6208template <int structdim, int dim, int spacedim>
6209bool
6211{
6212 // error checking is done in boundary_id()
6214}
6215
6216
6217
6218template <int structdim, int dim, int spacedim>
6221{
6223 return this->tria->get_manifold(this->manifold_id());
6224}
6225
6226
6227template <int structdim, int dim, int spacedim>
6230{
6232
6233 return this->objects().manifold_id[this->present_index];
6234}
6235
6236
6237
6238template <int structdim, int dim, int spacedim>
6239void
6241 const types::manifold_id manifold_ind) const
6242{
6244
6245 this->objects().manifold_id[this->present_index] = manifold_ind;
6246}
6247
6248
6249template <int structdim, int dim, int spacedim>
6250void
6252 const types::manifold_id manifold_ind) const
6253{
6254 set_manifold_id(manifold_ind);
6255
6256 if (this->has_children())
6257 for (unsigned int c = 0; c < this->n_children(); ++c)
6258 this->child(c)->set_all_manifold_ids(manifold_ind);
6259
6260 switch (structdim)
6261 {
6262 case 1:
6263 if (dim == 1)
6264 {
6265 (*this->tria->vertex_to_manifold_id_map_1d)[vertex_index(0)] =
6266 manifold_ind;
6267 (*this->tria->vertex_to_manifold_id_map_1d)[vertex_index(1)] =
6268 manifold_ind;
6269 }
6270 break;
6271
6272 case 2:
6273 // for quads/simplices also set manifold_id of bounding lines
6274 for (unsigned int i = 0; i < this->n_lines(); ++i)
6275 this->line(i)->set_manifold_id(manifold_ind);
6276 break;
6277 default:
6279 }
6280}
6281
6282
6283
6284template <int structdim, int dim, int spacedim>
6285double
6287{
6289# ifndef _MSC_VER
6290 ReferenceCells::max_n_vertices<structdim>()
6291# else
6293# endif
6294 >
6295 vertices(this->n_vertices());
6296
6297 for (unsigned int v = 0; v < vertices.size(); ++v)
6298 vertices[v] = this->vertex(v);
6299
6300 return internal::TriaAccessorImplementation::diameter<structdim, spacedim>(
6301 vertices);
6302}
6303
6304
6305
6306template <int dim, int spacedim>
6307double
6309 const Mapping<dim, spacedim> &mapping) const
6310{
6311 return internal::TriaAccessorImplementation::diameter<dim, spacedim>(
6313 this->tria, this->level(), this->index())));
6314}
6315
6316
6317
6318template <int structdim, int dim, int spacedim>
6319std::pair<Point<spacedim>, double>
6321{
6322 // If the object is one dimensional, the enclosing ball is the initial iterate
6323 // i.e., the ball's center and diameter are the center and the diameter of the
6324 // object.
6325 if (structdim == 1)
6326 return std::make_pair((this->vertex(1) + this->vertex(0)) * 0.5,
6327 (this->vertex(1) - this->vertex(0)).norm() * 0.5);
6328
6329 // The list is_initial_guess_vertex contains bool values and has the same size
6330 // as the number of vertices per object. The entries of
6331 // is_initial_guess_vertex are set true only for those two vertices
6332 // corresponding to the largest diagonal which is being used to construct the
6333 // initial ball. We employ this mask to skip these two vertices while
6334 // enlarging the ball.
6335 std::vector<bool> is_initial_guess_vertex(this->n_vertices());
6336
6337 // First let all the vertices be outside
6338 std::fill(is_initial_guess_vertex.begin(),
6339 is_initial_guess_vertex.end(),
6340 false);
6341
6342 // Get an initial guess by looking at the largest diagonal
6343 Point<spacedim> center;
6344 double radius = 0;
6345
6346 switch (structdim)
6347 {
6348 case 2:
6349 {
6350 const Point<spacedim> p30(this->vertex(3) - this->vertex(0));
6351 const Point<spacedim> p21(this->vertex(2) - this->vertex(1));
6352 if (p30.norm() > p21.norm())
6353 {
6354 center = this->vertex(0) + 0.5 * p30;
6355 radius = p30.norm() / 2.;
6356 is_initial_guess_vertex[3] = true;
6357 is_initial_guess_vertex[0] = true;
6358 }
6359 else
6360 {
6361 center = this->vertex(1) + 0.5 * p21;
6362 radius = p21.norm() / 2.;
6363 is_initial_guess_vertex[2] = true;
6364 is_initial_guess_vertex[1] = true;
6365 }
6366 break;
6367 }
6368 case 3:
6369 {
6370 const Point<spacedim> p70(this->vertex(7) - this->vertex(0));
6371 const Point<spacedim> p61(this->vertex(6) - this->vertex(1));
6372 const Point<spacedim> p25(this->vertex(2) - this->vertex(5));
6373 const Point<spacedim> p34(this->vertex(3) - this->vertex(4));
6374 const std::vector<double> diagonals = {p70.norm(),
6375 p61.norm(),
6376 p25.norm(),
6377 p34.norm()};
6378 const std::vector<double>::const_iterator it =
6379 std::max_element(diagonals.begin(), diagonals.end());
6380 if (it == diagonals.begin())
6381 {
6382 center = this->vertex(0) + 0.5 * p70;
6383 is_initial_guess_vertex[7] = true;
6384 is_initial_guess_vertex[0] = true;
6385 }
6386 else if (it == diagonals.begin() + 1)
6387 {
6388 center = this->vertex(1) + 0.5 * p61;
6389 is_initial_guess_vertex[6] = true;
6390 is_initial_guess_vertex[1] = true;
6391 }
6392 else if (it == diagonals.begin() + 2)
6393 {
6394 center = this->vertex(5) + 0.5 * p25;
6395 is_initial_guess_vertex[2] = true;
6396 is_initial_guess_vertex[5] = true;
6397 }
6398 else
6399 {
6400 center = this->vertex(4) + 0.5 * p34;
6401 is_initial_guess_vertex[3] = true;
6402 is_initial_guess_vertex[4] = true;
6403 }
6404 radius = *it * 0.5;
6405 break;
6406 }
6407 default:
6409 return std::pair<Point<spacedim>, double>();
6410 }
6411
6412 // For each vertex that is found to be geometrically outside the ball
6413 // enlarge the ball so that the new ball contains both the previous ball
6414 // and the given vertex.
6415 for (const unsigned int v : this->vertex_indices())
6416 if (!is_initial_guess_vertex[v])
6417 {
6418 const double distance = center.distance(this->vertex(v));
6419 if (distance > radius)
6420 {
6421 // we found a vertex which is outside of the ball extend it (move
6422 // center and change radius)
6423 const Point<spacedim> pCV(center - this->vertex(v));
6424 radius = (distance + radius) * 0.5;
6425 center = this->vertex(v) + pCV * (radius / distance);
6426
6427 // Now the new ball constructed in this block encloses the vertex
6428 // (v) that was found to be geometrically outside the old ball.
6429 }
6430 }
6431 if constexpr (running_in_debug_mode())
6432 {
6433 bool all_vertices_within_ball = true;
6434
6435 // Set all_vertices_within_ball false if any of the vertices of the object
6436 // are geometrically outside the ball
6437 for (const unsigned int v : this->vertex_indices())
6438 if (center.distance(this->vertex(v)) >
6439 radius + 100. * std::numeric_limits<double>::epsilon())
6440 {
6441 all_vertices_within_ball = false;
6442 break;
6443 }
6444 // If all the vertices are not within the ball throw error
6445 Assert(all_vertices_within_ball, ExcInternalError());
6446 }
6447 return std::make_pair(center, radius);
6448}
6449
6450
6451template <int structdim, int dim, int spacedim>
6452double
6454{
6455 switch (structdim)
6456 {
6457 case 1:
6458 return (this->vertex(1) - this->vertex(0)).norm();
6459 case 2:
6460 case 3:
6461 {
6462 double min = std::numeric_limits<double>::max();
6463 for (const unsigned int i : this->vertex_indices())
6464 for (unsigned int j = i + 1; j < this->n_vertices(); ++j)
6465 min = std::min(min,
6466 (this->vertex(i) - this->vertex(j)) *
6467 (this->vertex(i) - this->vertex(j)));
6468 return std::sqrt(min);
6469 }
6470 default:
6472 return -1e10;
6473 }
6474}
6475
6476
6477template <int structdim, int dim, int spacedim>
6478bool
6481{
6482 // go through the vertices and check... The cell is a translation of the
6483 // previous one in case the distance between the individual vertices in the
6484 // two cell is the same for all the vertices. So do the check by first getting
6485 // the distance on the first vertex, and then checking whether all others have
6486 // the same down to rounding errors (we have to be careful here because the
6487 // calculation of the displacement between one cell and the next can already
6488 // result in the loss of one or two digits), so we choose 1e-12 times the
6489 // distance between the zeroth vertices here.
6490 bool is_translation = true;
6491 const Tensor<1, spacedim> dist = o->vertex(0) - this->vertex(0);
6492 const double tol_square = 1e-24 * dist.norm_square();
6493 for (unsigned int i = 1; i < this->n_vertices(); ++i)
6494 {
6495 const Tensor<1, spacedim> dist_new =
6496 (o->vertex(i) - this->vertex(i)) - dist;
6497 if (dist_new.norm_square() > tol_square)
6498 {
6499 is_translation = false;
6500 break;
6501 }
6502 }
6503 return is_translation;
6504}
6505
6506
6507
6508template <int structdim, int dim, int spacedim>
6509unsigned int
6511{
6512 return this->reference_cell().n_vertices();
6513}
6514
6515
6516
6517template <int structdim, int dim, int spacedim>
6518unsigned int
6520{
6521 return this->reference_cell().n_lines();
6522}
6523
6524
6525
6526template <int structdim, int dim, int spacedim>
6527unsigned int
6529{
6530 Assert(structdim == dim,
6531 ExcMessage("This function can only be used on objects "
6532 "that are cells, but not on faces or edges "
6533 "that bound cells."));
6534
6535 return this->reference_cell().n_faces();
6536}
6537
6538
6539
6540template <int structdim, int dim, int spacedim>
6543{
6545 n_vertices());
6546}
6547
6548
6549
6550template <int structdim, int dim, int spacedim>
6553{
6555 n_lines());
6556}
6557
6558
6559
6560template <int structdim, int dim, int spacedim>
6563{
6565 n_faces());
6566}
6567
6568
6569
6570/*----------------- Functions: TriaAccessor<0,dim,spacedim> -----------------*/
6571
6572template <int dim, int spacedim>
6574 const Triangulation<dim, spacedim> *tria,
6575 const unsigned int vertex_index)
6576 : tria(tria)
6577 , global_vertex_index(vertex_index)
6578{}
6579
6580
6581
6582template <int dim, int spacedim>
6584 const Triangulation<dim, spacedim> *tria,
6585 const int /*level*/,
6586 const int index,
6587 const AccessorData *)
6588 : tria(tria)
6590{}
6591
6592
6593
6594template <int dim, int spacedim>
6595template <int structdim2, int dim2, int spacedim2>
6598 : tria(nullptr)
6600{
6601 Assert(false, ExcImpossibleInDim(0));
6602}
6603
6604
6605
6606template <int dim, int spacedim>
6607template <int structdim2, int dim2, int spacedim2>
6610 : tria(nullptr)
6612{
6613 Assert(false, ExcImpossibleInDim(0));
6614}
6615
6616
6617
6618template <int dim, int spacedim>
6619inline void
6621{
6622 tria = t.tria;
6623 global_vertex_index = t.global_vertex_index;
6624}
6625
6626
6627
6628template <int dim, int spacedim>
6629inline bool
6631 const TriaAccessor<0, dim, spacedim> &other) const
6632{
6634
6635 return (global_vertex_index < other.global_vertex_index);
6636}
6637
6638
6639
6640template <int dim, int spacedim>
6643{
6644 if (global_vertex_index != numbers::invalid_unsigned_int)
6645 return IteratorState::valid;
6646 else
6648}
6649
6650
6651
6652template <int dim, int spacedim>
6653inline int
6655{
6656 return 0;
6657}
6658
6659
6660
6661template <int dim, int spacedim>
6662inline int
6664{
6665 return global_vertex_index;
6666}
6667
6668
6669
6670template <int dim, int spacedim>
6671inline const Triangulation<dim, spacedim> &
6673{
6674 return *tria;
6675}
6676
6677
6678
6679template <int dim, int spacedim>
6680inline void
6682{
6684 if (global_vertex_index >= tria->n_vertices())
6686}
6687
6688
6689
6690template <int dim, int spacedim>
6691inline void
6693{
6694 if (global_vertex_index != numbers::invalid_unsigned_int)
6695 {
6696 if (global_vertex_index != 0)
6698 else
6700 }
6701}
6702
6703
6704
6705template <int dim, int spacedim>
6706inline bool
6708{
6709 const bool result =
6710 ((tria == t.tria) && (global_vertex_index == t.global_vertex_index));
6711
6712 return result;
6713}
6714
6715
6716
6717template <int dim, int spacedim>
6718inline bool
6720{
6721 return !(*this == t);
6722}
6723
6724
6725
6726template <int dim, int spacedim>
6727inline unsigned int
6728TriaAccessor<0, dim, spacedim>::vertex_index(const unsigned int) const
6729{
6730 return global_vertex_index;
6731}
6732
6733
6734
6735template <int dim, int spacedim>
6736inline Point<spacedim> &
6737TriaAccessor<0, dim, spacedim>::vertex(const unsigned int) const
6738{
6739 return const_cast<Point<spacedim> &>(
6740 this->tria->vertices[global_vertex_index]);
6741}
6742
6743
6744
6745template <int dim, int spacedim>
6746inline typename ::internal::TriangulationImplementation::
6747 Iterators<dim, spacedim>::line_iterator
6748 TriaAccessor<0, dim, spacedim>::line(const unsigned int)
6749{
6750 return typename ::internal::TriangulationImplementation::
6751 Iterators<dim, spacedim>::line_iterator();
6752}
6753
6754
6755
6756template <int dim, int spacedim>
6757inline unsigned int
6759{
6760 Assert(false, ExcImpossibleInDim(0));
6762}
6763
6764
6765
6766template <int dim, int spacedim>
6767inline typename ::internal::TriangulationImplementation::
6768 Iterators<dim, spacedim>::quad_iterator
6769 TriaAccessor<0, dim, spacedim>::quad(const unsigned int)
6770{
6771 return typename ::internal::TriangulationImplementation::
6772 Iterators<dim, spacedim>::quad_iterator();
6773}
6774
6775
6776
6777template <int dim, int spacedim>
6778inline unsigned int
6780{
6781 Assert(false, ExcImpossibleInDim(0));
6783}
6784
6785
6786
6787template <int dim, int spacedim>
6788inline double
6790{
6791 return 0.;
6792}
6793
6794
6795
6796template <int dim, int spacedim>
6797inline double
6799{
6800 return 0.;
6801}
6802
6803
6804
6805template <int dim, int spacedim>
6806inline Point<spacedim>
6807TriaAccessor<0, dim, spacedim>::center(const bool, const bool) const
6808{
6809 return this->tria->vertices[global_vertex_index];
6810}
6811
6812
6813
6814template <int dim, int spacedim>
6815inline double
6817{
6818 return 1.0;
6819}
6820
6821
6822
6823template <int dim, int spacedim>
6826 const unsigned int /*face*/)
6827{
6829}
6830
6831
6832
6833template <int dim, int spacedim>
6834inline bool
6835TriaAccessor<0, dim, spacedim>::face_orientation(const unsigned int /*face*/)
6836{
6837 return false;
6838}
6839
6840
6841
6842template <int dim, int spacedim>
6843inline bool
6844TriaAccessor<0, dim, spacedim>::face_flip(const unsigned int /*face*/)
6845{
6846 return false;
6847}
6848
6849
6850
6851template <int dim, int spacedim>
6852inline bool
6853TriaAccessor<0, dim, spacedim>::face_rotation(const unsigned int /*face*/)
6854{
6855 return false;
6856}
6857
6858
6859
6860template <int dim, int spacedim>
6862TriaAccessor<0, dim, spacedim>::line_orientation(const unsigned int /*line*/)
6863{
6865}
6866
6867
6868
6869template <int dim, int spacedim>
6870inline bool
6872{
6873 return false;
6874}
6875
6876
6877
6878template <int dim, int spacedim>
6879inline unsigned int
6881{
6882 return 0;
6883}
6884
6885
6886
6887template <int dim, int spacedim>
6888inline unsigned int
6890{
6891 return 0;
6892}
6893
6894
6895
6896template <int dim, int spacedim>
6897inline unsigned int
6899{
6900 return 0;
6901}
6902
6903
6904
6905template <int dim, int spacedim>
6906inline unsigned int
6909{
6911}
6912
6913
6914
6915template <int dim, int spacedim>
6917TriaAccessor<0, dim, spacedim>::child(const unsigned int)
6918{
6920}
6921
6922
6923
6924template <int dim, int spacedim>
6927{
6929}
6930
6931
6932
6933template <int dim, int spacedim>
6934inline RefinementCase<0>
6936{
6938}
6939
6940
6941
6942template <int dim, int spacedim>
6943inline int
6945{
6946 return -1;
6947}
6948
6949
6950
6951template <int dim, int spacedim>
6952inline int
6954{
6955 return -1;
6956}
6957
6958
6959
6960template <int dim, int spacedim>
6961inline bool
6963{
6964 return tria->vertex_used(global_vertex_index);
6965}
6966
6967
6968
6969/*------------------- Functions: TriaAccessor<0,1,spacedim> -----------------*/
6970
6971template <int spacedim>
6973 const Triangulation<1, spacedim> *tria,
6974 const VertexKind vertex_kind,
6975 const unsigned int vertex_index)
6976 : tria(tria)
6977 , vertex_kind(vertex_kind)
6978 , global_vertex_index(vertex_index)
6979{}
6980
6981
6982
6983template <int spacedim>
6985 const Triangulation<1, spacedim> *tria,
6986 const int level,
6987 const int index,
6988 const AccessorData *)
6989 : tria(tria)
6990 , vertex_kind(interior_vertex)
6992{
6993 // in general, calling this constructor should yield an error -- users should
6994 // instead call the one immediately above. however, if you create something
6995 // like Triangulation<1>::face_iterator() then this calls the default
6996 // constructor of the iterator which calls the accessor with argument list
6997 // (0,-2,-2,0), so in this particular case accept this call and create an
6998 // object that corresponds to the default constructed (invalid) vertex
6999 // accessor
7000 (void)level;
7001 (void)index;
7002 Assert((level == -2) && (index == -2),
7003 ExcMessage(
7004 "This constructor can not be called for face iterators in 1d, "
7005 "except to default-construct iterator objects."));
7006}
7007
7008
7009
7010template <int spacedim>
7011template <int structdim2, int dim2, int spacedim2>
7014 : tria(nullptr)
7015 , vertex_kind(interior_vertex)
7017{
7018 Assert(false, ExcImpossibleInDim(0));
7019}
7020
7021
7022
7023template <int spacedim>
7024template <int structdim2, int dim2, int spacedim2>
7027 : tria(nullptr)
7028 , vertex_kind(interior_vertex)
7030{
7031 Assert(false, ExcImpossibleInDim(0));
7032}
7033
7034
7035
7036template <int spacedim>
7037inline void
7039{
7040 tria = t.tria;
7041 vertex_kind = t.vertex_kind;
7042 global_vertex_index = t.global_vertex_index;
7043}
7044
7045
7046
7047template <int spacedim>
7048inline void
7051{
7052 // We cannot convert from TriaAccessorBase to
7053 // TriaAccessor<0,1,spacedim> because the latter is not derived from
7054 // the former. We should never get here.
7056}
7057
7058
7059
7060template <int spacedim>
7061inline bool
7063 const TriaAccessor<0, 1, spacedim> &other) const
7064{
7066
7067 return (global_vertex_index < other.global_vertex_index);
7068}
7069
7070
7071
7072template <int spacedim>
7075{
7076 return IteratorState::valid;
7077}
7078
7079
7080template <int spacedim>
7081inline int
7083{
7084 return 0;
7085}
7086
7087
7088
7089template <int spacedim>
7090inline int
7092{
7093 return global_vertex_index;
7094}
7095
7096
7097
7098template <int spacedim>
7099inline const Triangulation<1, spacedim> &
7101{
7102 return *tria;
7103}
7104
7105
7106
7107template <int spacedim>
7108inline void
7110{
7112}
7113
7114
7115template <int spacedim>
7116inline void
7118{
7120}
7121
7122
7123
7124template <int spacedim>
7125inline bool
7127{
7128 const bool result =
7129 ((tria == t.tria) && (global_vertex_index == t.global_vertex_index));
7130 // if we point to the same vertex, make sure we know the same about it
7131 if (result == true)
7132 Assert(vertex_kind == t.vertex_kind, ExcInternalError());
7133
7134 return result;
7135}
7136
7137
7138
7139template <int spacedim>
7140inline bool
7142{
7143 return !(*this == t);
7144}
7145
7146
7147
7148template <int spacedim>
7149inline unsigned int
7150TriaAccessor<0, 1, spacedim>::vertex_index(const unsigned int i) const
7151{
7152 AssertIndexRange(i, 1);
7153 (void)i;
7154 return global_vertex_index;
7155}
7156
7157
7158
7159template <int spacedim>
7160inline Point<spacedim> &
7161TriaAccessor<0, 1, spacedim>::vertex(const unsigned int i) const
7162{
7163 AssertIndexRange(i, 1);
7164 (void)i;
7165 return const_cast<Point<spacedim> &>(
7166 this->tria->vertices[global_vertex_index]);
7167}
7168
7169
7170
7171template <int spacedim>
7172inline Point<spacedim>
7174{
7175 return this->tria->vertices[global_vertex_index];
7176}
7177
7178
7179
7180template <int spacedim>
7181inline typename ::internal::TriangulationImplementation::
7182 Iterators<1, spacedim>::line_iterator
7183 TriaAccessor<0, 1, spacedim>::line(const unsigned int)
7184{
7185 return {};
7186}
7187
7188
7189template <int spacedim>
7190inline unsigned int
7192{
7193 Assert(false, ExcImpossibleInDim(0));
7195}
7196
7197
7198template <int spacedim>
7199inline typename ::internal::TriangulationImplementation::
7200 Iterators<1, spacedim>::quad_iterator
7201 TriaAccessor<0, 1, spacedim>::quad(const unsigned int)
7202{
7203 return {};
7204}
7205
7206
7207
7208template <int spacedim>
7209inline unsigned int
7211{
7212 Assert(false, ExcImpossibleInDim(0));
7214}
7215
7216
7217
7218template <int spacedim>
7219inline double
7221{
7222 return 1.0;
7223}
7224
7225
7226
7227template <int spacedim>
7228inline bool
7230{
7231 return vertex_kind != interior_vertex;
7232}
7233
7234
7235template <int spacedim>
7236inline types::boundary_id
7238{
7239 switch (vertex_kind)
7240 {
7241 case left_vertex:
7242 case right_vertex:
7243 {
7245 this->vertex_index()) !=
7246 tria->vertex_to_boundary_id_map_1d->end(),
7248
7249 return (*tria->vertex_to_boundary_id_map_1d)[this->vertex_index()];
7250 }
7251
7252 default:
7254 }
7255}
7256
7257
7258
7259template <int spacedim>
7260inline const Manifold<1, spacedim> &
7262{
7263 return this->tria->get_manifold(this->manifold_id());
7264}
7265
7266
7267
7268template <int spacedim>
7269inline types::manifold_id
7271{
7272 if (tria->vertex_to_manifold_id_map_1d->find(this->vertex_index()) !=
7273 tria->vertex_to_manifold_id_map_1d->end())
7274 return (*tria->vertex_to_manifold_id_map_1d)[this->vertex_index()];
7275 else
7277}
7278
7279
7280template <int spacedim>
7283 const unsigned int /*face*/)
7284{
7286}
7287
7288
7289template <int spacedim>
7290inline bool
7291TriaAccessor<0, 1, spacedim>::face_orientation(const unsigned int /*face*/)
7292{
7293 return false;
7294}
7295
7296
7297
7298template <int spacedim>
7299inline bool
7300TriaAccessor<0, 1, spacedim>::face_flip(const unsigned int /*face*/)
7301{
7302 return false;
7303}
7304
7305
7306
7307template <int spacedim>
7308inline bool
7309TriaAccessor<0, 1, spacedim>::face_rotation(const unsigned int /*face*/)
7310{
7311 return false;
7312}
7313
7314
7315
7316template <int spacedim>
7318TriaAccessor<0, 1, spacedim>::line_orientation(const unsigned int /*line*/)
7319{
7321}
7322
7323
7324
7325template <int spacedim>
7326inline bool
7328{
7329 return false;
7330}
7331
7332
7333
7334template <int spacedim>
7335inline unsigned int
7337{
7338 return 0;
7339}
7340
7341
7342
7343template <int spacedim>
7344inline unsigned int
7346{
7347 return 0;
7348}
7349
7350
7351
7352template <int spacedim>
7353inline unsigned int
7355{
7356 return 0;
7357}
7358
7359
7360
7361template <int spacedim>
7362inline unsigned int
7365{
7367}
7368
7369
7370
7371template <int spacedim>
7373TriaAccessor<0, 1, spacedim>::child(const unsigned int)
7374{
7376}
7377
7378
7379template <int spacedim>
7382{
7384}
7385
7386
7387template <int spacedim>
7388inline RefinementCase<0>
7390{
7392}
7393
7394template <int spacedim>
7395inline int
7397{
7398 return -1;
7399}
7400
7401
7402template <int spacedim>
7403inline int
7405{
7406 return -1;
7407}
7408
7409
7410
7411template <int spacedim>
7412inline void
7414{
7415 Assert(tria->vertex_to_boundary_id_map_1d->find(this->vertex_index()) !=
7416 tria->vertex_to_boundary_id_map_1d->end(),
7417 ExcMessage("You can't set the boundary_id of a face of a cell that is "
7418 "not actually at the boundary."));
7419
7420 (*tria->vertex_to_boundary_id_map_1d)[this->vertex_index()] = b;
7421}
7422
7423
7424
7425template <int spacedim>
7426inline void
7428{
7429 (*tria->vertex_to_manifold_id_map_1d)[this->vertex_index()] = b;
7430}
7431
7432
7433
7434template <int spacedim>
7435inline void
7437 const types::boundary_id b) const
7438{
7439 set_boundary_id(b);
7440}
7441
7442
7443
7444template <int spacedim>
7445inline void
7447{
7448 set_manifold_id(b);
7449}
7450
7451
7452
7453template <int spacedim>
7454inline bool
7456{
7457 return tria->vertex_used(global_vertex_index);
7458}
7459
7460
7461
7462template <int spacedim>
7463inline ReferenceCell<0>
7465{
7467}
7468
7469
7470
7471template <int spacedim>
7472unsigned int
7474{
7475 return 1;
7476}
7477
7478
7479
7480template <int spacedim>
7481unsigned int
7483{
7484 return 0;
7485}
7486
7487
7488
7489template <int spacedim>
7492{
7494 n_vertices());
7495}
7496
7497
7498
7499template <int spacedim>
7502{
7504 n_lines());
7505}
7506
7507/*------------------ Functions: CellAccessor<dim,spacedim> ------------------*/
7508
7509
7510template <int dim, int spacedim>
7512 const Triangulation<dim, spacedim> *parent,
7513 const int level,
7514 const int index,
7515 const AccessorData *local_data)
7516 : TriaAccessor<dim, dim, spacedim>(parent, level, index, local_data)
7517{}
7518
7519
7520
7521template <int dim, int spacedim>
7523 const TriaAccessor<dim, dim, spacedim> &cell_accessor)
7524 : TriaAccessor<dim, dim, spacedim>(
7525 static_cast<const TriaAccessor<dim, dim, spacedim> &>(cell_accessor))
7526{}
7527
7528
7529
7530template <int dim, int spacedim>
7532CellAccessor<dim, spacedim>::child(const unsigned int i) const
7533{
7535 this->level() + 1,
7536 this->child_index(i));
7537
7538 Assert((q.state() == IteratorState::past_the_end) || q->used(),
7540
7541 return q;
7542}
7543
7544
7545
7546template <int dim, int spacedim>
7547inline boost::container::small_vector<TriaIterator<CellAccessor<dim, spacedim>>,
7548 ReferenceCells::max_n_children<dim>()>
7550{
7551 boost::container::small_vector<TriaIterator<CellAccessor<dim, spacedim>>,
7552 ReferenceCells::max_n_children<dim>()>
7553 child_iterators(this->n_children());
7554
7555 for (unsigned int i = 0; i < this->n_children(); ++i)
7556 child_iterators[i] = this->child(i);
7557
7558 return child_iterators;
7559}
7560
7561
7562
7563template <int dim, int spacedim>
7564inline TriaIterator<TriaAccessor<dim - 1, dim, spacedim>>
7565CellAccessor<dim, spacedim>::face(const unsigned int i) const
7566{
7567 AssertIndexRange(i, this->n_faces());
7568 if constexpr (dim == 1)
7569 {
7570 using VertexKind = typename TriaAccessor<0, 1, spacedim>::VertexKind;
7571 VertexKind vertex_kind = VertexKind::interior_vertex;
7572 if (i == 0 && at_boundary(0))
7573 vertex_kind = VertexKind::left_vertex;
7574 if (i == 1 && at_boundary(1))
7575 vertex_kind = VertexKind::right_vertex;
7576 TriaAccessor<0, 1, spacedim> a(&this->get_triangulation(),
7577 vertex_kind,
7578 this->vertex_index(i));
7580 }
7581 else if constexpr (dim == 2)
7582 return this->line(i);
7583 else if constexpr (dim == 3)
7584 return this->quad(i);
7585 else
7586 {
7587 Assert(false, ExcNotImplemented());
7588 return {};
7589 }
7590}
7591
7592
7593
7594template <int dim, int spacedim>
7595inline unsigned int
7598{
7599 for (const unsigned int face_n : this->face_indices())
7600 if (this->face(face_n) == face)
7601 return face_n;
7602
7603 Assert(false,
7604 ExcMessage("The given face is not a face of the current cell."));
7606}
7607
7608
7609
7610template <int dim, int spacedim>
7611inline boost::container::small_vector<
7612 TriaIterator<TriaAccessor<dim - 1, dim, spacedim>>,
7613# ifndef _MSC_VER
7614 ReferenceCells::max_n_faces<dim>()
7615# else
7617# endif
7618 >
7620{
7621 boost::container::small_vector<
7622 TriaIterator<TriaAccessor<dim - 1, dim, spacedim>>,
7623# ifndef _MSC_VER
7624 ReferenceCells::max_n_faces<dim>()
7625# else
7627# endif
7628 >
7629 face_iterators(this->n_faces());
7630
7631 for (const unsigned int i : this->face_indices())
7632 face_iterators[i] = this->face(i);
7633
7634 return face_iterators;
7635}
7636
7637
7638
7639template <int dim, int spacedim>
7640inline unsigned int
7641CellAccessor<dim, spacedim>::face_index(const unsigned int i) const
7642{
7643 switch (dim)
7644 {
7645 case 1:
7646 return this->vertex_index(i);
7647
7648 case 2:
7649 return this->line_index(i);
7650
7651 case 3:
7652 return this->quad_index(i);
7653
7654 default:
7656 }
7657}
7658
7659
7660
7661template <int dim, int spacedim>
7662inline int
7663CellAccessor<dim, spacedim>::neighbor_index(const unsigned int face_no) const
7664{
7665 AssertIndexRange(face_no, this->n_faces());
7666 return this->tria->levels[this->level()]->neighbor_index(this->present_index,
7667 face_no);
7668}
7669
7670
7671
7672template <int dim, int spacedim>
7673inline int
7674CellAccessor<dim, spacedim>::neighbor_level(const unsigned int face_no) const
7675{
7676 AssertIndexRange(face_no, this->n_faces());
7677 return this->tria->levels[this->level()]->neighbor_level(this->present_index,
7678 face_no);
7679}
7680
7681
7682
7683template <int dim, int spacedim>
7686{
7688 // cells flagged for refinement must be active (the @p set_refine_flag
7689 // function checks this, but activity may change when refinement is executed
7690 // and for some reason the refine flag is not cleared).
7691 Assert(
7692 this->is_active() ||
7693 !this->tria->levels[this->level()]->refine_flags[this->present_index],
7694 ExcRefineCellNotActive());
7695 return RefinementCase<dim>(
7696 this->tria->levels[this->level()]->refine_flags[this->present_index]);
7697}
7698
7699
7700
7701template <int dim, int spacedim>
7702inline void
7704 const RefinementCase<dim> refinement_case) const
7705{
7706 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
7707 Assert(!coarsen_flag_set(), ExcCellFlaggedForCoarsening());
7708
7709 this->tria->levels[this->level()]->refine_flags[this->present_index] =
7710 refinement_case;
7711}
7712
7713
7714
7715template <int dim, int spacedim>
7716inline void
7718{
7719 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
7720 this->tria->levels[this->level()]->refine_flags[this->present_index] =
7722}
7723
7724
7725template <int dim, int spacedim>
7726inline std::uint8_t
7728{
7730 if (this->tria->levels[this->level()]->refine_choice.size() == 0)
7731 return 0U;
7732 return this->tria->levels[this->level()]->refine_choice[this->present_index];
7733}
7734
7735
7736template <int dim, int spacedim>
7737inline void
7739 const std::uint8_t refinement_choice) const
7740{
7741 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
7742 if (this->tria->levels[this->level()]->refine_choice.size() != 0)
7743 this->tria->levels[this->level()]->refine_choice[this->present_index] =
7744 refinement_choice;
7745}
7746
7747
7748template <int dim, int spacedim>
7749inline void
7751{
7752 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
7753 if (this->tria->levels[this->level()]->refine_choice.size() != 0)
7754 this->tria->levels[this->level()]->refine_choice[this->present_index] =
7756}
7757
7758
7759template <int dim, int spacedim>
7760inline bool
7762 const unsigned int face_no,
7763 const RefinementCase<dim - 1> &face_refinement_case) const
7764{
7765 Assert(dim > 1, ExcImpossibleInDim(dim));
7766 AssertIndexRange(face_no, this->n_faces());
7767 AssertIndexRange(face_refinement_case,
7769
7770 // the new refinement case is a combination of the minimum required one for
7771 // the given face refinement and the already existing flagged refinement case
7772 RefinementCase<dim> old_ref_case = refine_flag_set();
7773 RefinementCase<dim> new_ref_case =
7774 (old_ref_case |
7776 face_refinement_case,
7777 face_no,
7778 this->face_orientation(face_no),
7779 this->face_flip(face_no),
7780 this->face_rotation(face_no)));
7781 set_refine_flag(new_ref_case);
7782 // return, whether we had to change the refinement flag
7783 return new_ref_case != old_ref_case;
7784}
7785
7786
7787
7788template <int dim, int spacedim>
7789inline bool
7791 const unsigned int line_no) const
7792{
7793 Assert(dim > 1, ExcImpossibleInDim(dim));
7794 AssertIndexRange(line_no, this->n_lines());
7795
7796 // the new refinement case is a combination of the minimum required one for
7797 // the given line refinement and the already existing flagged refinement case
7799 old_ref_case = refine_flag_set(),
7800 new_ref_case =
7801 old_ref_case |
7803 set_refine_flag(new_ref_case);
7804 // return, whether we had to change the refinement flag
7805 return new_ref_case != old_ref_case;
7806}
7807
7808
7809
7810template <int dim, int spacedim>
7812CellAccessor<dim, spacedim>::subface_case(const unsigned int face_no) const
7813{
7815 AssertIndexRange(face_no, this->n_faces());
7816
7817 if constexpr (dim == 1)
7819 else if constexpr (dim == 2)
7820 return ((face(face_no)->has_children()) ?
7822 internal::SubfaceCase<2>::case_none);
7823 else if constexpr (dim == 3)
7824 {
7825 switch (static_cast<std::uint8_t>(face(face_no)->refinement_case()))
7826 {
7830 if (face(face_no)->child(0)->has_children())
7831 {
7832 Assert(face(face_no)->child(0)->refinement_case() ==
7835 if (face(face_no)->child(1)->has_children())
7836 {
7837 Assert(face(face_no)->child(1)->refinement_case() ==
7841 }
7842 else
7844 }
7845 else
7846 {
7847 if (face(face_no)->child(1)->has_children())
7848 {
7849 Assert(face(face_no)->child(1)->refinement_case() ==
7853 }
7854 else
7856 }
7858 if (face(face_no)->child(0)->has_children())
7859 {
7860 Assert(face(face_no)->child(0)->refinement_case() ==
7863 if (face(face_no)->child(1)->has_children())
7864 {
7865 Assert(face(face_no)->child(1)->refinement_case() ==
7869 }
7870 else
7872 }
7873 else
7874 {
7875 if (face(face_no)->child(1)->has_children())
7876 {
7877 Assert(face(face_no)->child(1)->refinement_case() ==
7881 }
7882 else
7884 }
7887 default:
7889 }
7890 }
7891
7892 // we should never get here
7895}
7896
7897
7898
7899template <int dim, int spacedim>
7900inline bool
7902{
7904 // cells flagged for coarsening must be active (the @p set_refine_flag
7905 // function checks this, but activity may change when refinement is executed
7906 // and for some reason the refine flag is not cleared).
7907 Assert(
7908 this->is_active() ||
7909 !this->tria->levels[this->level()]->coarsen_flags[this->present_index],
7910 ExcRefineCellNotActive());
7911 return this->tria->levels[this->level()]->coarsen_flags[this->present_index];
7912}
7913
7914
7915
7916template <int dim, int spacedim>
7917inline void
7919{
7920 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
7921 Assert(!refine_flag_set(), ExcCellFlaggedForRefinement());
7922
7923 this->tria->levels[this->level()]->coarsen_flags[this->present_index] = true;
7924}
7925
7926
7927
7928template <int dim, int spacedim>
7929inline void
7931{
7932 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
7933 this->tria->levels[this->level()]->coarsen_flags[this->present_index] = false;
7934}
7935
7936
7937
7938template <int dim, int spacedim>
7940CellAccessor<dim, spacedim>::neighbor(const unsigned int face_no) const
7941{
7943 neighbor_level(face_no),
7944 neighbor_index(face_no));
7945
7946 Assert((q.state() == IteratorState::past_the_end) || q->used(),
7948
7949 return q;
7950}
7951
7952
7953
7954template <int dim, int spacedim>
7955inline bool
7957{
7958 return !this->has_children();
7959}
7960
7961
7962
7963template <int dim, int spacedim>
7964inline bool
7966{
7967 Assert(this->is_active(),
7968 ExcMessage("is_locally_owned() can only be called on active cells!"));
7969# ifndef DEAL_II_WITH_MPI
7970 return true;
7971# else
7972
7973 // Serial triangulations report invalid_subdomain_id as their locally owned
7974 // subdomain, so the first condition checks whether we have a serial
7975 // triangulation, in which case all cells are locally owned. The second
7976 // condition compares the subdomain id in the parallel case.
7977 const types::subdomain_id locally_owned_subdomain =
7978 this->tria->locally_owned_subdomain();
7979 return (locally_owned_subdomain == numbers::invalid_subdomain_id ||
7980 this->subdomain_id() == locally_owned_subdomain);
7981
7982# endif
7983}
7984
7985
7986template <int dim, int spacedim>
7987inline bool
7989{
7990# ifndef DEAL_II_WITH_MPI
7991 return true;
7992# else
7993
7994 // Serial triangulations report invalid_subdomain_id as their locally owned
7995 // subdomain, so the first condition checks whether we have a serial
7996 // triangulation, in which case all cells are locally owned. The second
7997 // condition compares the subdomain id in the parallel case.
7998 const types::subdomain_id locally_owned_subdomain =
7999 this->tria->locally_owned_subdomain();
8000 return (locally_owned_subdomain == numbers::invalid_subdomain_id ||
8001 this->level_subdomain_id() == locally_owned_subdomain);
8002
8003# endif
8004}
8005
8006
8007template <int dim, int spacedim>
8008inline bool
8010{
8011 Assert(this->is_active(),
8012 ExcMessage("is_ghost() can only be called on active cells!"));
8013 if (this->has_children())
8014 return false;
8015
8016# ifndef DEAL_II_WITH_MPI
8017 return false;
8018# else
8019
8020 // Serial triangulations report invalid_subdomain_id as their locally owned
8021 // subdomain, so the first condition rules out that case as all cells to a
8022 // serial triangulation are locally owned and none is ghosted. The second
8023 // and third conditions check whether the cell's subdomain is not the
8024 // locally owned one and not artificial.
8025 const types::subdomain_id locally_owned_subdomain =
8026 this->tria->locally_owned_subdomain();
8027 const types::subdomain_id subdomain_id = this->subdomain_id();
8028 return (locally_owned_subdomain != numbers::invalid_subdomain_id &&
8029 subdomain_id != locally_owned_subdomain &&
8030 subdomain_id != numbers::artificial_subdomain_id);
8031
8032# endif
8033}
8034
8035
8036template <int dim, int spacedim>
8037inline bool
8039{
8040# ifndef DEAL_II_WITH_MPI
8041 return false;
8042# else
8043
8044 // Serial triangulations report invalid_subdomain_id as their locally owned
8045 // subdomain, so the first condition checks whether we have a serial
8046 // triangulation, in which case all cells are locally owned. The second
8047 // condition compares the subdomain id in the parallel case.
8048 const types::subdomain_id locally_owned_subdomain =
8049 this->tria->locally_owned_subdomain();
8050 const types::subdomain_id subdomain_id = this->level_subdomain_id();
8051 return (locally_owned_subdomain != numbers::invalid_subdomain_id &&
8052 subdomain_id != locally_owned_subdomain &&
8053 subdomain_id != numbers::artificial_subdomain_id);
8054
8055# endif
8056}
8057
8058
8059
8060template <int dim, int spacedim>
8061inline bool
8063{
8064 Assert(this->is_active(),
8065 ExcMessage("is_artificial() can only be called on active cells!"));
8066# ifndef DEAL_II_WITH_MPI
8067 return false;
8068# else
8069
8070 // Serial triangulations report invalid_subdomain_id as their locally owned
8071 // subdomain, so the first condition rules out that case as all cells to a
8072 // serial triangulation are locally owned and none is artificial.
8073 return (this->tria->locally_owned_subdomain() !=
8075 this->subdomain_id() == numbers::artificial_subdomain_id);
8076
8077# endif
8078}
8079
8080
8081
8082template <int dim, int spacedim>
8083inline bool
8085{
8086# ifndef DEAL_II_WITH_MPI
8087 return false;
8088# else
8089 return (this->tria->locally_owned_subdomain() !=
8091 this->level_subdomain_id() == numbers::artificial_subdomain_id);
8092# endif
8093}
8094
8095
8096
8097template <int dim, int spacedim>
8098inline void
8100 const unsigned int face_no,
8101 const TriaIterator<CellAccessor<dim, spacedim>> &neighbor) const
8102{
8103 AssertIndexRange(face_no, this->n_faces());
8104
8105 Assert(neighbor.state() != IteratorState::invalid,
8106 ExcMessage("The provided neighbor must be either a valid iterator or "
8107 "an end iterator (to indicate a boundary face)"));
8108 auto &level = this->tria->levels[this->level()];
8109 level->set_neighbor(this->present_index,
8110 face_no,
8111 neighbor->level(),
8112 neighbor->index());
8113}
8114
8115
8116
8117template <int dim, int spacedim>
8118inline types::material_id
8120{
8122 return this->tria->levels[this->level()]
8123 ->cells.boundary_or_material_id[this->present_index]
8124 .material_id;
8125}
8126
8127
8128
8129template <int dim, int spacedim>
8132{
8134 Assert(this->is_active(),
8135 ExcMessage("subdomain_id() can only be called on active cells!"));
8136 return this->tria->levels[this->level()]->subdomain_ids[this->present_index];
8137}
8138
8139
8140
8141template <int dim, int spacedim>
8144{
8146 return this->tria->levels[this->level()]
8147 ->level_subdomain_ids[this->present_index];
8148}
8149
8150
8151
8152template <int dim, int spacedim>
8153inline unsigned int
8154CellAccessor<dim, spacedim>::neighbor_face_no(const unsigned int neighbor) const
8155{
8156 const unsigned int n2 = neighbor_of_neighbor_internal(neighbor);
8158 // return this value as the neighbor is not coarser
8159 return n2;
8160 else
8161 // the neighbor is coarser
8162 return neighbor_of_coarser_neighbor(neighbor).first;
8163}
8164
8165
8166
8167template <int dim, int spacedim>
8168inline bool
8170{
8171 return false;
8172}
8173
8174
8175
8176template <int dim, int spacedim>
8177inline unsigned int
8179{
8181 return this->tria->levels[this->level()]
8182 ->active_cell_indices[this->present_index];
8183}
8184
8185
8186
8187template <int dim, int spacedim>
8190{
8192 Assert(this->is_active(),
8193 ExcMessage(
8194 "global_active_cell_index() can only be called on active cells!"));
8195
8196 return this->tria->levels[this->level()]
8197 ->global_active_cell_indices[this->present_index];
8198}
8199
8200
8201
8202template <int dim, int spacedim>
8205{
8206 return this->tria->levels[this->level()]
8207 ->global_level_cell_indices[this->present_index];
8208}
8209
8210
8211
8212template <int dim, int spacedim>
8213inline bool
8215{
8217 if constexpr (dim == spacedim)
8218 return true;
8219 else if constexpr (dim == spacedim - 1)
8220 return this->tria->levels[this->level()]
8221 ->direction_flags[this->present_index];
8222 else
8223 {
8224 Assert(false,
8225 ExcMessage("This function cannot be called if dim<spacedim-1."));
8226 return true;
8227 }
8228}
8229
8230#endif // DOXYGEN
8231
8233
8234
8235#endif
*  *  for(const auto &cell :triangulation.active_cell_iterators())
*  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
TriaIterator< CellAccessor< dim, spacedim > > periodic_neighbor(const unsigned int i) const
types::global_cell_index global_active_cell_index() 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
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
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
void set_neighbor(const unsigned int face_no, const TriaIterator< CellAccessor< dim, spacedim > > &neighbor) 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
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
InvalidAccessor(const OtherAccessor &)
Abstract base class for mapping classes.
Definition mapping.h:318
virtual boost::container::small_vector< Point< spacedim >, ReferenceCells::max_n_vertices< dim >() > get_vertices(const typename Triangulation< dim, spacedim >::cell_iterator &cell) const
Definition point.h:111
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
numbers::NumberTraits< Number >::real_type norm() 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 &)
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 &)
const Triangulation< dim, spacedim > & get_triangulation() const
IteratorState::IteratorStates state() const
int index() const
bool operator<(const TriaAccessorBase &other) const
::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 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
unsigned int n_vertices() const
void set_manifold_id(const types::manifold_id)
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)
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.
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
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
TriaAccessor(const TriaAccessor< structdim2, dim2, spacedim2 > &)
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
typename TriaAccessorBase< structdim, dim, spacedim >::AccessorData AccessorData
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)
unsigned int child_iterator_to_index(const TriaIterator< TriaAccessor< structdim, dim, spacedim > > &child) const
TriaAccessor(const InvalidAccessor< structdim2, dim2, spacedim2 > &)
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
IteratorState::IteratorStates state() const
std::unique_ptr< std::map< unsigned int, types::manifold_id > > vertex_to_manifold_id_map_1d
Definition tria.h:4691
std::unique_ptr<::internal::TriangulationImplementation::TriaFaces< dim > > faces
Definition tria.h:4603
std::vector< Point< spacedim > > vertices
Definition tria.h:4609
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:4668
std::vector< std::unique_ptr< ::internal::TriangulationImplementation::TriaLevel< dim, spacedim > > > levels
Definition tria.h:4595
bool vertex_used(const unsigned int index) const
unsigned int n_vertices() const
#define DEAL_II_DEPRECATED
Definition config.h:294
#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:249
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
#define DEAL_II_ASSERT_UNREACHABLE()
#define DEAL_II_NOT_IMPLEMENTED()
unsigned int level
Definition grid_out.cc:4642
unsigned int vertex_indices[2]
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()
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.
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)
SymmetricTensor< 2, dim, Number > epsilon(const Tensor< 2, dim, Number > &Grad_u)
*  *  if(update_pressure &update_flags) *  compute_pressure(constitutive_request
*  *  *  *  std::vector< Number > ThermoPlasticMaterial< dim, ViscoplasticYieldLaw, Number >::get_state_parameters   const
constexpr ReferenceCell< 3 > Hexahedron
constexpr ReferenceCell< 2 > Quadrilateral
constexpr ReferenceCell< 1 > Line
constexpr ReferenceCell< 2 > Triangle
constexpr ReferenceCell< 3 > Tetrahedron
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:369
constexpr unsigned int invalid_unsigned_int
Definition types.h:228
constexpr types::boundary_id internal_face_boundary_id
Definition types.h:319
constexpr types::manifold_id flat_manifold_id
Definition types.h:332
constexpr types::subdomain_id artificial_subdomain_id
Definition types.h:406
constexpr types::geometric_orientation reverse_line_orientation
Definition types.h:355
constexpr types::subdomain_id invalid_subdomain_id
Definition types.h:385
constexpr types::geometric_orientation default_geometric_orientation
Definition types.h:342
boost::integer_range< IncrementableType > iota_view
Definition iota_view.h:43
STL namespace.
::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 manifold_id
Definition types.h:171
std::uint64_t global_vertex_index
Definition types.h:55
unsigned int subdomain_id
Definition types.h:50
unsigned int boundary_id
Definition types.h:159
std::uint8_t geometric_orientation
Definition types.h:38
static RefinementCase< dim > min_cell_refinement_case_for_line_refinement(const unsigned int line_no)
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)