deal.II version GIT relicensing-3307-g81a1c05a67 2025-05-12 20:50:00+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: LGPL-2.1-or-later
4// Copyright (C) 1998 - 2024 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Part of the source code is dual licensed under Apache-2.0 WITH
9// LLVM-exception OR LGPL-2.1-or-later. Detailed license information
10// governing the source code and code contributions can be found in
11// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II.
12//
13// ------------------------------------------------------------------------
14
15#ifndef dealii_tria_accessor_h
16#define dealii_tria_accessor_h
17
18
19#include <deal.II/base/config.h>
20
24#include <deal.II/base/point.h>
26
34
35#include <boost/container/small_vector.hpp>
36
37#include <cmath>
38#include <limits>
39#include <utility>
40
41
43
44// Forward declarations
45#ifndef DOXYGEN
46template <int dim, int spacedim>
48class Triangulation;
49template <typename Accessor>
50class TriaRawIterator;
51template <typename Accessor>
52class TriaIterator;
53template <typename Accessor>
55
56namespace parallel
57{
58 template <int dim, int spacedim>
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
95 template <int structdim, int dim>
97 {
98 struct type
99 {
103 type() = default;
104
108 type(const int level)
109 {
111 (void)level; // removes -Wunused-parameter warning in optimized mode
112 }
113
117 operator int() const
118 {
119 return 0;
120 }
121
122 void
124 {
126 }
127
128 void
130 {
132 }
133 };
134 };
135
136
142 template <int dim>
143 struct PresentLevelType<dim, dim>
144 {
145 using type = int;
146 };
147 } // namespace TriaAccessorImplementation
148} // namespace internal
149template <int structdim, int dim, int spacedim>
150class TriaAccessor;
151template <int dim, int spacedim>
152class TriaAccessor<0, dim, spacedim>;
153template <int spacedim>
154class TriaAccessor<0, 1, spacedim>;
155
160{
165 "The operation you are attempting can only be performed for "
166 "(cell, face, or edge) iterators that point to valid "
167 "objects. These objects need not necessarily be active, "
168 "i.e., have no children, but they need to be part of a "
169 "triangulation. (The objects pointed to by an iterator "
170 "may -- after coarsening -- also be objects that used "
171 "to be part of a triangulation, but are now no longer "
172 "used. Their memory location may have been retained "
173 "for re-use upon the next mesh refinement, but is "
174 "currently unused.)");
185 "The operation you are attempting can only be performed for "
186 "(cell, face, or edge) iterators that point to 'active' "
187 "objects. 'Active' objects are those that do not have "
188 "children (in the case of cells), or that are part of "
189 "an active cell (in the case of faces or edges). However, "
190 "the object on which you are trying the current "
191 "operation is not 'active' in this sense.");
198 "The operation you are attempting can only be performed for "
199 "(cell, face, or edge) iterators that have children, "
200 "but the object on which you are trying the current "
201 "operation does not have any.");
209 "The operation you are attempting can only be performed for "
210 "(cell, face, or edge) iterators that have a parent object, "
211 "but the object on which you are trying the current "
212 "operation does not have one -- i.e., it is on the "
213 "coarsest level of the triangulation.");
218 int,
219 << "You can only set the child index if the cell does not "
220 << "currently have children registered; or you can clear it. "
221 << "The given index was " << arg1
222 << " (-1 means: clear children).");
226 template <typename AccessorType>
228 AccessorType,
229 << "You tried to dereference an iterator for which this "
230 << "is not possible. More information on this iterator: "
231 << "index=" << arg1.index() << ", state="
232 << (arg1.state() == IteratorState::valid ?
233 "valid" :
234 (arg1.state() == IteratorState::past_the_end ?
235 "past_the_end" :
236 "invalid")));
241 "Iterators can only be compared if they point to the same "
242 "triangulation, or if neither of them are associated "
243 "with a triangulation.");
244 // TODO: Write documentation!
249 // TODO: Write documentation!
269 // TODO: Write documentation!
275 int,
276 << "You can only set the child index of an even numbered child."
277 << "The number of the child given was " << arg1 << '.');
278} // namespace TriaAccessorExceptions
279
280
306template <int structdim, int dim, int spacedim = dim>
308{
309public:
316 static constexpr unsigned int space_dimension = spacedim;
317
323 static constexpr unsigned int dimension = dim;
324
330 static const unsigned int structure_dimension = structdim;
331
341 void
342 operator=(const TriaAccessorBase *) = delete;
343
344protected:
350 using AccessorData = void;
351
356 const int level = -1,
357 const int index = -1,
358 const AccessorData * = nullptr);
359
364
372 void
374
380
391 bool
392 operator<(const TriaAccessorBase &other) const;
393
394protected:
398 bool
400
404 bool
406
420 void
422
430 void
440 objects() const;
441
442public:
448 using LocalData = void *;
449
473 int
474 level() const;
475
502 int
503 index() const;
504
510 state() const;
511
518
522protected:
527 typename ::internal::TriaAccessorImplementation::
528 PresentLevelType<structdim, dim>::type present_level;
529
535
540
541private:
542 template <typename Accessor>
543 friend class TriaRawIterator;
544 template <typename Accessor>
545 friend class TriaIterator;
546 template <typename Accessor>
547 friend class TriaActiveIterator;
548};
549
550
551
572template <int structdim, int dim, int spacedim = dim>
574{
575public:
582 static constexpr unsigned int space_dimension = spacedim;
583
589 static constexpr unsigned int dimension = dim;
590
596 static const unsigned int structure_dimension = structdim;
597
603 using AccessorData = void;
604
612 InvalidAccessor(const void *parent = nullptr,
613 const int level = -1,
614 const int index = -1,
615 const AccessorData *local_data = nullptr);
616
625
630 template <typename OtherAccessor>
631 InvalidAccessor(const OtherAccessor &);
632
636 void
638
642 bool
644 bool
646
650 void
651 operator++() const;
652 void
653 operator--() const;
654
660 state();
661
662
667 static int
668 level();
669
674 static int
675 index();
676
681 bool
682 used() const;
683
688 bool
690
695 manifold_id() const;
696
700 unsigned int
701 user_index() const;
702
706 void
707 set_user_index(const unsigned int p) const;
708
712 void
714
719 vertex(const unsigned int i) const;
720
725 void *
726 line(const unsigned int i) const;
727
732 void *
733 quad(const unsigned int i) const;
734};
735
736
737
755template <int structdim, int dim, int spacedim>
756class TriaAccessor : public TriaAccessorBase<structdim, dim, spacedim>
757{
758public:
764
769 const int level = -1,
770 const int index = -1,
771 const AccessorData *local_data = nullptr);
772
777 TriaAccessor(const TriaAccessor &) = default;
778
782 TriaAccessor(TriaAccessor &&) = default; // NOLINT
783
796 template <int structdim2, int dim2, int spacedim2>
798
803 template <int structdim2, int dim2, int spacedim2>
805
816 operator=(const TriaAccessor &) = delete;
817
822 operator=(TriaAccessor &&) = default; // NOLINT
823
827 ~TriaAccessor() = default;
828
835 bool
836 used() const;
837
850 vertex_iterator(const unsigned int i) const;
851
867 unsigned int
868 vertex_index(const unsigned int i) const;
869
908 vertex(const unsigned int i) const;
909
913 typename ::internal::TriangulationImplementation::
914 Iterators<dim, spacedim>::line_iterator
915 line(const unsigned int i) const;
916
923 unsigned int
924 line_index(const unsigned int i) const;
925
929 typename ::internal::TriangulationImplementation::
930 Iterators<dim, spacedim>::quad_iterator
931 quad(const unsigned int i) const;
932
939 unsigned int
940 quad_index(const unsigned int i) const;
959 combined_face_orientation(const unsigned int face) const;
960
972 bool
973 face_orientation(const unsigned int face) const;
974
984 bool
985 face_flip(const unsigned int face) const;
986
996 bool
997 face_rotation(const unsigned int face) const;
998
1009 line_orientation(const unsigned int line) const;
1024 bool
1026
1031 unsigned int
1032 n_children() const;
1033
1047 unsigned int
1049
1063 unsigned int
1065
1070 child(const unsigned int i) const;
1071
1076 unsigned int
1079
1089 isotropic_child(const unsigned int i) const;
1090
1096
1102 int
1103 child_index(const unsigned int i) const;
1104
1110 int
1111 isotropic_child_index(const unsigned int i) const;
1135
1163 void
1165
1194 void
1196
1204 bool
1206
1218
1241
1259 void
1261
1275 void
1277
1294 bool
1296
1302 void
1304
1310 void
1312
1318 void
1320
1326 void
1328
1334 void
1336
1348 void
1349 set_user_pointer(void *p) const;
1350
1356 void
1358
1376 void *
1378
1400 void
1402
1409 void
1411
1421 void
1422 set_user_index(const unsigned int p) const;
1423
1429 void
1431
1443 unsigned int
1444 user_index() const;
1445
1463 void
1464 recursively_set_user_index(const unsigned int p) const;
1465
1474 void
1510 double
1511 diameter() const;
1512
1539 std::pair<Point<spacedim>, double>
1541
1552
1562 double
1563 extent_in_direction(const unsigned int axis) const;
1564
1568 double
1570
1585 intermediate_point(const Point<structdim> &coordinates) const;
1586
1611
1647 center(const bool respect_manifold = false,
1648 const bool interpolate_from_surrounding = false) const;
1649
1668 barycenter() const;
1669
1700 double
1701 measure() const;
1702
1717 bool
1720
1726
1730 unsigned int
1731 n_vertices() const;
1732
1736 unsigned int
1737 n_lines() const;
1738
1748 unsigned int
1749 n_faces() const;
1750
1757
1764
1773
1778private:
1783 void
1785
1793 void
1795 const std::initializer_list<int> &new_indices) const;
1796
1800 void
1802 const std::initializer_list<unsigned int> &new_indices) const;
1803
1811 void
1812 set_line_orientation(const unsigned int line,
1813 const types::geometric_orientation orientation) const;
1814
1824 void
1826 const unsigned int face,
1827 const types::geometric_orientation combined_orientation) const;
1828
1832 void
1834
1838 void
1840
1849 void
1851
1859 void
1861
1868 void
1869 set_children(const unsigned int i, const int index) const;
1870
1875 void
1877
1878private:
1879 friend class Triangulation<dim, spacedim>;
1880
1881 friend struct ::internal::TriangulationImplementation::Implementation;
1882 friend struct ::internal::TriangulationImplementation::
1883 ImplementationMixedMesh;
1884 friend struct ::internal::TriaAccessorImplementation::Implementation;
1885};
1886
1887
1888
1907template <int dim, int spacedim>
1908class TriaAccessor<0, dim, spacedim>
1909{
1910public:
1916 static constexpr unsigned int space_dimension = spacedim;
1917
1923 static constexpr unsigned int dimension = dim;
1924
1930 static const unsigned int structure_dimension = 0;
1931
1935 using AccessorData = void;
1936
1942 const unsigned int vertex_index);
1943
1950 const int level = 0,
1951 const int index = 0,
1952 const AccessorData * = nullptr);
1953
1957 template <int structdim2, int dim2, int spacedim2>
1959
1963 template <int structdim2, int dim2, int spacedim2>
1965
1970 state() const;
1971
1976 static int
1978
1983 int
1984 index() const;
1985
1992
2002 void
2004
2008 void
2013 bool
2014 operator==(const TriaAccessor &) const;
2015
2019 bool
2020 operator!=(const TriaAccessor &) const;
2021
2049 unsigned int
2050 vertex_index(const unsigned int i = 0) const;
2051
2058 vertex(const unsigned int i = 0) const;
2059
2064 typename ::internal::TriangulationImplementation::
2065 Iterators<dim, spacedim>::line_iterator static line(const unsigned int);
2066
2070 static unsigned int
2071 line_index(const unsigned int i);
2072
2076 static typename ::internal::TriangulationImplementation::
2077 Iterators<dim, spacedim>::quad_iterator
2078 quad(const unsigned int i);
2079
2083 static unsigned int
2084 quad_index(const unsigned int i);
2085
2101 double
2102 diameter() const;
2103
2111 double
2112 extent_in_direction(const unsigned int axis) const;
2113
2122 center(const bool respect_manifold = false,
2123 const bool interpolate_from_surrounding = false) const;
2124
2133 double
2134 measure() const;
2152 combined_face_orientation(const unsigned int face);
2153
2157 static bool
2158 face_orientation(const unsigned int face);
2159
2163 static bool
2164 face_flip(const unsigned int face);
2165
2169 static bool
2170 face_rotation(const unsigned int face);
2171
2176 line_orientation(const unsigned int line);
2177
2192 static bool
2194
2199 static unsigned int
2201
2206 static unsigned int
2208
2212 static unsigned int
2214
2218 static unsigned int
2220
2225 child(const unsigned int);
2226
2231 isotropic_child(const unsigned int);
2232
2236 static RefinementCase<0>
2238
2242 static int
2243 child_index(const unsigned int i);
2244
2248 static int
2249 isotropic_child_index(const unsigned int i);
2257 bool
2258 used() const;
2259
2260protected:
2268 void
2270
2279 bool
2280 operator<(const TriaAccessor &other) const;
2281
2286
2291
2292private:
2293 template <typename Accessor>
2294 friend class TriaRawIterator;
2295 template <typename Accessor>
2296 friend class TriaIterator;
2297 template <typename Accessor>
2299};
2300
2301
2302
2319template <int spacedim>
2320class TriaAccessor<0, 1, spacedim>
2321{
2322public:
2328 static constexpr unsigned int space_dimension = spacedim;
2329
2335 static constexpr unsigned int dimension = 1;
2336
2342 static const unsigned int structure_dimension = 0;
2343
2347 using AccessorData = void;
2348
2354 {
2366 right_vertex
2368
2381 const VertexKind vertex_kind,
2382 const unsigned int vertex_index);
2383
2390 const int = 0,
2391 const int = 0,
2392 const AccessorData * = nullptr);
2393
2397 template <int structdim2, int dim2, int spacedim2>
2399
2403 template <int structdim2, int dim2, int spacedim2>
2405
2410 void
2412
2418 void
2420
2428
2433 static int
2435
2440 int
2441 index() const;
2442
2449
2460 void
2461 operator++() const;
2462
2467 void
2468 operator--() const;
2472 bool
2473 operator==(const TriaAccessor &) const;
2474
2478 bool
2479 operator!=(const TriaAccessor &) const;
2480
2489 bool
2490 operator<(const TriaAccessor &other) const;
2491
2518 unsigned int
2519 vertex_index(const unsigned int i = 0) const;
2520
2527 vertex(const unsigned int i = 0) const;
2528
2534 center() const;
2535
2540 typename ::internal::TriangulationImplementation::
2541 Iterators<1, spacedim>::line_iterator static line(const unsigned int);
2542
2549 static unsigned int
2550 line_index(const unsigned int i);
2551
2555 static typename ::internal::TriangulationImplementation::
2556 Iterators<1, spacedim>::quad_iterator
2557 quad(const unsigned int i);
2558
2565 static unsigned int
2566 quad_index(const unsigned int i);
2567
2577 bool
2579
2596
2600 const Manifold<1, spacedim> &
2602
2611
2612
2624 bool
2625 user_flag_set() const;
2626
2632 void
2633 set_user_flag() const;
2634
2640 void
2641 clear_user_flag() const;
2642
2648 void
2650
2656 void
2658
2664 void
2665 clear_user_data() const;
2666
2678 void
2679 set_user_pointer(void *p) const;
2680
2686 void
2687 clear_user_pointer() const;
2688
2704 void *
2705 user_pointer() const;
2706
2728 void
2729 recursively_set_user_pointer(void *p) const;
2730
2737 void
2739
2749 void
2750 set_user_index(const unsigned int p) const;
2751
2757 void
2758 clear_user_index() const;
2759
2771 unsigned int
2772 user_index() const;
2773
2791 void
2792 recursively_set_user_index(const unsigned int p) const;
2793
2802 void
2821 combined_face_orientation(const unsigned int face);
2822
2826 static bool
2827 face_orientation(const unsigned int face);
2828
2832 static bool
2833 face_flip(const unsigned int face);
2834
2838 static bool
2839 face_rotation(const unsigned int face);
2840
2845 line_orientation(const unsigned int line);
2846
2861 static bool
2863
2868 static unsigned int
2870
2875 static unsigned int
2877
2881 static unsigned int
2883
2887 static unsigned int
2889
2894 child(const unsigned int);
2895
2900 isotropic_child(const unsigned int);
2901
2905 static RefinementCase<0>
2907
2911 static int
2912 child_index(const unsigned int i);
2913
2917 static int
2918 isotropic_child_index(const unsigned int i);
2949 void
2951
2958 void
2960
2970 void
2972
2984 void
2993 bool
2994 used() const;
2995
3001
3005 unsigned int
3006 n_vertices() const;
3007
3011 unsigned int
3012 n_lines() const;
3013
3020
3027
3028protected:
3033
3039
3044};
3045
3046
3047
3063template <int dim, int spacedim = dim>
3064class CellAccessor : public TriaAccessor<dim, dim, spacedim>
3065{
3066public:
3071
3076
3088 const int level = -1,
3089 const int index = -1,
3090 const AccessorData *local_data = nullptr);
3091
3096
3109 template <int structdim2, int dim2, int spacedim2>
3111
3116 template <int structdim2, int dim2, int spacedim2>
3118
3123
3127 // NOLINTNEXTLINE OSX does not compile with noexcept
3129
3133 ~CellAccessor() = default;
3134
3146
3150 // NOLINTNEXTLINE OSX does not compile with noexcept
3153
3177 as_dof_handler_iterator(const DoFHandler<dim, spacedim> &dof_handler) const;
3178
3189 const DoFHandler<dim, spacedim> &dof_handler) const;
3190
3191
3208 child(const unsigned int i) const;
3209
3213 boost::container::small_vector<TriaIterator<CellAccessor<dim, spacedim>>,
3216
3220 TriaIterator<TriaAccessor<dim - 1, dim, spacedim>>
3221 face(const unsigned int i) const;
3222
3227 unsigned int
3230
3234 boost::container::small_vector<
3235 TriaIterator<TriaAccessor<dim - 1, dim, spacedim>>,
3236#ifndef _MSC_VER // MSVC prior to 2022 cannot use a constexpr function this way
3237 ReferenceCells::max_n_faces<dim>()
3238#else
3240#endif
3241 >
3243
3253 unsigned int
3254 face_index(const unsigned int i) const;
3255
3304 neighbor_child_on_subface(const unsigned int face_no,
3305 const unsigned int subface_no) const;
3306
3355 neighbor(const unsigned int face_no) const;
3356
3364 int
3365 neighbor_index(const unsigned int face_no) const;
3366
3374 int
3375 neighbor_level(const unsigned int face_no) const;
3376
3388 unsigned int
3389 neighbor_of_neighbor(const unsigned int face_no) const;
3390
3401 bool
3402 neighbor_is_coarser(const unsigned int face_no) const;
3403
3418 std::pair<unsigned int, unsigned int>
3419 neighbor_of_coarser_neighbor(const unsigned int neighbor) const;
3420
3427 unsigned int
3428 neighbor_face_no(const unsigned int neighbor) const;
3429
3433 static bool
3435
3449 bool
3450 has_periodic_neighbor(const unsigned int i) const;
3451
3469 periodic_neighbor(const unsigned int i) const;
3470
3479 neighbor_or_periodic_neighbor(const unsigned int i) const;
3480
3496 periodic_neighbor_child_on_subface(const unsigned int face_no,
3497 const unsigned int subface_no) const;
3498
3509 std::pair<unsigned int, unsigned int>
3510 periodic_neighbor_of_coarser_periodic_neighbor(const unsigned face_no) const;
3511
3517 int
3518 periodic_neighbor_index(const unsigned int i) const;
3519
3525 int
3526 periodic_neighbor_level(const unsigned int i) const;
3527
3542 unsigned int
3543 periodic_neighbor_of_periodic_neighbor(const unsigned int i) const;
3544
3550 unsigned int
3551 periodic_neighbor_face_no(const unsigned int i) const;
3552
3559 bool
3560 periodic_neighbor_is_coarser(const unsigned int i) const;
3561
3578 bool
3579 at_boundary(const unsigned int i) const;
3580
3589 bool
3590 at_boundary() const;
3591
3599 bool
3600 has_boundary_lines() const;
3628
3646 void
3649
3653 void
3655
3660 std::uint8_t
3662
3667 void
3668 set_refine_choice(const std::uint8_t refinement_choice = static_cast<char>(
3670
3674 void
3676
3684 bool
3686 const unsigned int face_no,
3687 const RefinementCase<dim - 1> &face_refinement_case =
3689
3695 bool
3696 flag_for_line_refinement(const unsigned int line_no) const;
3697
3707 subface_case(const unsigned int face_no) const;
3708
3712 bool
3714
3719 void
3721
3725 void
3750 material_id() const;
3751
3763 void
3764 set_material_id(const types::material_id new_material_id) const;
3765
3774 void
3775 recursively_set_material_id(const types::material_id new_material_id) const;
3803
3819 void
3820 set_subdomain_id(const types::subdomain_id new_subdomain_id) const;
3821
3832
3837 void
3839 const types::subdomain_id new_level_subdomain_id) const;
3840
3841
3857 void
3859 const types::subdomain_id new_subdomain_id) const;
3883
3893
3910 bool
3911 direction_flag() const;
3912
3938 unsigned int
3940
3948 int
3949 parent_index() const;
3950
3957 parent() const;
3958
3978 bool
3979 is_active() const;
3980
4000 bool
4002
4007 bool
4009
4043 bool
4044 is_ghost() const;
4045
4051 bool
4053
4080 bool
4082
4089 bool
4091
4105 bool
4107
4116 void
4117 set_neighbor(const unsigned int i,
4118 const TriaIterator<CellAccessor<dim, spacedim>> &pointer) const;
4119
4133 CellId
4134 id() const;
4135
4136 using TriaAccessor<dim, dim, spacedim>::diameter;
4137
4141 double
4142 diameter(const Mapping<dim, spacedim> &mapping) const;
4143
4161
4162protected:
4178 unsigned int
4179 neighbor_of_neighbor_internal(const unsigned int neighbor) const;
4180
4186 template <int dim_, int spacedim_>
4187 bool
4188 point_inside_codim(const Point<spacedim_> &p) const;
4189
4190
4191
4192private:
4197 void
4198 set_active_cell_index(const unsigned int active_cell_index) const;
4199
4203 void
4205
4209 void
4211
4215 void
4216 set_parent(const unsigned int parent_index);
4217
4228 void
4229 set_direction_flag(const bool new_direction_flag) const;
4230
4231 friend class Triangulation<dim, spacedim>;
4232
4233 friend class parallel::TriangulationBase<dim, spacedim>;
4234
4235 friend struct ::internal::TriangulationImplementation::Implementation;
4236 friend struct ::internal::TriangulationImplementation::
4237 ImplementationMixedMesh;
4238};
4239
4240
4241
4242/* ----- declaration of explicit specializations and general templates ----- */
4243
4244
4245template <int structdim, int dim, int spacedim>
4246template <typename OtherAccessor>
4248 const OtherAccessor &)
4249{
4250 Assert(false,
4251 ExcMessage("You are attempting an illegal conversion between "
4252 "iterator/accessor types. The constructor you call "
4253 "only exists to make certain template constructs "
4254 "easier to write as dimension independent code but "
4255 "the conversion is not valid in the current context."));
4256}
4257
4258
4259
4260template <int structdim, int dim, int spacedim>
4261template <int structdim2, int dim2, int spacedim2>
4264{
4265 Assert(false,
4266 ExcMessage("You are attempting an illegal conversion between "
4267 "iterator/accessor types. The constructor you call "
4268 "only exists to make certain template constructs "
4269 "easier to write as dimension independent code but "
4270 "the conversion is not valid in the current context."));
4271}
4272
4273
4274
4275template <int dim, int spacedim>
4276template <int structdim2, int dim2, int spacedim2>
4279{
4280 Assert(false,
4281 ExcMessage("You are attempting an illegal conversion between "
4282 "iterator/accessor types. The constructor you call "
4283 "only exists to make certain template constructs "
4284 "easier to write as dimension independent code but "
4285 "the conversion is not valid in the current context."));
4286}
4287
4288
4289
4290template <int structdim, int dim, int spacedim>
4291template <int structdim2, int dim2, int spacedim2>
4294{
4295 Assert(false,
4296 ExcMessage("You are attempting an illegal conversion between "
4297 "iterator/accessor types. The constructor you call "
4298 "only exists to make certain template constructs "
4299 "easier to write as dimension independent code but "
4300 "the conversion is not valid in the current context."));
4301}
4302
4303
4304
4305template <int dim, int spacedim>
4306template <int structdim2, int dim2, int spacedim2>
4309{
4310 Assert(false,
4311 ExcMessage("You are attempting an illegal conversion between "
4312 "iterator/accessor types. The constructor you call "
4313 "only exists to make certain template constructs "
4314 "easier to write as dimension independent code but "
4315 "the conversion is not valid in the current context."));
4316}
4317
4318
4319#ifndef DOXYGEN
4320
4321template <>
4322bool
4324template <>
4325bool
4327template <>
4328bool
4330template <>
4331bool
4333template <>
4334bool
4336template <>
4337bool
4339// -------------------------------------------------------------------
4340
4341template <>
4342void
4344
4345
4346
4347namespace internal
4348{
4349 namespace TriaAccessorImplementation
4350 {
4356 template <int dim, int spacedim>
4357 inline double
4358 diameter(
4359 const boost::container::small_vector<Point<spacedim>,
4361 vertices)
4362 {
4363 const ReferenceCell reference_cell =
4364 ReferenceCell::n_vertices_to_type(dim, vertices.size());
4365
4366 if (reference_cell == ReferenceCells::Line)
4367 // Return the distance between the two vertices
4368 return (vertices[1] - vertices[0]).norm();
4369 else if (reference_cell == ReferenceCells::Triangle)
4370 // Return the longest of the three edges
4371 return std::max({(vertices[1] - vertices[0]).norm(),
4372 (vertices[2] - vertices[1]).norm(),
4373 (vertices[2] - vertices[0]).norm()});
4374 else if (reference_cell == ReferenceCells::Quadrilateral)
4375 // Return the longer one of the two diagonals of the quadrilateral
4376 return std::max({(vertices[3] - vertices[0]).norm(),
4377 (vertices[2] - vertices[1]).norm()});
4378 else if (reference_cell == ReferenceCells::Tetrahedron)
4379 // Return the longest of the six edges of the tetrahedron
4380 return std::max({(vertices[1] - vertices[0]).norm(),
4381 (vertices[2] - vertices[0]).norm(),
4382 (vertices[2] - vertices[1]).norm(),
4383 (vertices[3] - vertices[0]).norm(),
4384 (vertices[3] - vertices[1]).norm(),
4385 (vertices[3] - vertices[2]).norm()});
4386 else if (reference_cell == ReferenceCells::Pyramid)
4387 // Return ...
4388 return std::max({// the longest diagonal of the quadrilateral base
4389 // of the pyramid or ...
4390 (vertices[3] - vertices[0]).norm(),
4391 (vertices[2] - vertices[1]).norm(),
4392 // the longest edge connected with the apex of the
4393 // pyramid
4394 (vertices[4] - vertices[0]).norm(),
4395 (vertices[4] - vertices[1]).norm(),
4396 (vertices[4] - vertices[2]).norm(),
4397 (vertices[4] - vertices[3]).norm()});
4398 else if (reference_cell == ReferenceCells::Wedge)
4399 // Return ...
4400 return std::max({// the longest of the 2*3=6 diagonals of the three
4401 // quadrilateral sides of the wedge or ...
4402 (vertices[4] - vertices[0]).norm(),
4403 (vertices[3] - vertices[1]).norm(),
4404 (vertices[5] - vertices[1]).norm(),
4405 (vertices[4] - vertices[2]).norm(),
4406 (vertices[5] - vertices[0]).norm(),
4407 (vertices[3] - vertices[2]).norm(),
4408 // the longest of the 3*2=6 edges of the two
4409 // triangular faces of the wedge
4410 (vertices[1] - vertices[0]).norm(),
4411 (vertices[2] - vertices[1]).norm(),
4412 (vertices[2] - vertices[0]).norm(),
4413 (vertices[4] - vertices[3]).norm(),
4414 (vertices[5] - vertices[4]).norm(),
4415 (vertices[5] - vertices[3]).norm()});
4416 else if (reference_cell == ReferenceCells::Hexahedron)
4417 // Return the longest of the four diagonals of the hexahedron
4418 return std::max({(vertices[7] - vertices[0]).norm(),
4419 (vertices[6] - vertices[1]).norm(),
4420 (vertices[2] - vertices[5]).norm(),
4421 (vertices[3] - vertices[4]).norm()});
4422
4424 return -1e10;
4425 }
4426 } // namespace TriaAccessorImplementation
4427} // namespace internal
4428
4429
4430/*--------------------- Functions: TriaAccessorBase -------------------------*/
4431
4432template <int structdim, int dim, int spacedim>
4434 const Triangulation<dim, spacedim> *tria,
4435 const int level,
4436 const int index,
4437 const AccessorData *)
4438 : present_level((structdim == dim) ? level : 0)
4439 , present_index(index)
4440 , tria(tria)
4441{
4442 // non-cells have no level, so a 0
4443 // should have been passed, or a -1
4444 // for an end-iterator, or -2 for
4445 // an invalid (default constructed)
4446 // iterator
4447 if (structdim != dim)
4448 {
4449 Assert((level == 0) || (level == -1) || (level == -2),
4451 }
4452}
4453
4454
4455template <int structdim, int dim, int spacedim>
4458 : present_level(a.present_level)
4459 , present_index(a.present_index)
4460 , tria(a.tria)
4461{}
4462
4463
4464template <int structdim, int dim, int spacedim>
4465inline void
4468{
4469 present_level = a.present_level;
4470 present_index = a.present_index;
4471 tria = a.tria;
4472
4473 if (structdim != dim)
4474 {
4475 Assert((present_level == 0) || (present_level == -1) ||
4476 (present_level == -2),
4478 }
4479}
4480
4481
4482
4483template <int structdim, int dim, int spacedim>
4487{
4488 present_level = a.present_level;
4489 present_index = a.present_index;
4490 tria = a.tria;
4491
4492 if (structdim != dim)
4493 {
4494 Assert((present_level == 0) || (present_level == -1) ||
4495 (present_level == -2),
4497 }
4498 return *this;
4499}
4500
4501
4502
4503template <int structdim, int dim, int spacedim>
4504inline bool
4507{
4508 Assert(tria == a.tria || tria == nullptr || a.tria == nullptr,
4510 return ((tria == a.tria) && (present_level == a.present_level) &&
4511 (present_index == a.present_index));
4512}
4513
4514
4515
4516template <int structdim, int dim, int spacedim>
4517inline bool
4520{
4521 Assert(tria == a.tria || tria == nullptr || a.tria == nullptr,
4523 return ((tria != a.tria) || (present_level != a.present_level) ||
4524 (present_index != a.present_index));
4525}
4526
4527
4528
4529template <int structdim, int dim, int spacedim>
4530inline bool
4533{
4535
4536 if (present_level != other.present_level)
4537 return (present_level < other.present_level);
4538
4539 return (present_index < other.present_index);
4540}
4541
4542
4543
4544template <int structdim, int dim, int spacedim>
4545inline int
4547{
4548 // This is always zero or invalid
4549 // if the object is not a cell
4550 return present_level;
4551}
4552
4553
4554
4555template <int structdim, int dim, int spacedim>
4556inline int
4558{
4559 return present_index;
4560}
4561
4562
4563
4564template <int structdim, int dim, int spacedim>
4567{
4568 if ((present_level >= 0) && (present_index >= 0))
4569 return IteratorState::valid;
4570 else if (present_index == -1)
4572 else
4574}
4575
4576
4577
4578template <int structdim, int dim, int spacedim>
4579inline const Triangulation<dim, spacedim> &
4581{
4582 return *tria;
4583}
4584
4585
4586
4587template <int structdim, int dim, int spacedim>
4588inline void
4590{
4591 // this iterator is used for
4592 // objects without level
4593 ++this->present_index;
4594
4595 if (structdim != dim)
4596 {
4597 // is index still in the range of
4598 // the vector? (note that we don't
4599 // have to set the level, since
4600 // dim!=1 and the object therefore
4601 // has no level)
4602 if (this->present_index >= static_cast<int>(objects().n_objects()))
4603 this->present_index = -1;
4604 }
4605 else
4606 {
4607 while (this->present_index >=
4608 static_cast<int>(
4609 this->tria->levels[this->present_level]->cells.n_objects()))
4610 {
4611 // no -> go one level up until we find
4612 // one with more than zero cells
4613 ++this->present_level;
4614 this->present_index = 0;
4615 // highest level reached?
4616 if (this->present_level >=
4617 static_cast<int>(this->tria->levels.size()))
4618 {
4619 // return with past the end pointer
4620 this->present_level = this->present_index = -1;
4621 return;
4622 }
4623 }
4624 }
4625}
4626
4627
4628template <int structdim, int dim, int spacedim>
4629inline void
4631{
4632 // same as operator++
4633 --this->present_index;
4634
4635 if (structdim != dim)
4636 {
4637 if (this->present_index < 0)
4638 this->present_index = -1;
4639 }
4640 else
4641 {
4642 while (this->present_index < 0)
4643 {
4644 // no -> go one level down
4645 --this->present_level;
4646 // lowest level reached?
4647 if (this->present_level == -1)
4648 {
4649 // return with past the end pointer
4650 this->present_level = this->present_index = -1;
4651 return;
4652 }
4653 // else
4654 this->present_index =
4655 this->tria->levels[this->present_level]->cells.n_objects() - 1;
4656 }
4657 }
4658}
4659
4660
4661
4662template <int structdim, int dim, int spacedim>
4663inline ::internal::TriangulationImplementation::TriaObjects &
4665{
4666 if (structdim == dim)
4667 return this->tria->levels[this->present_level]->cells;
4668
4669 if (structdim == 1 && dim > 1)
4670 return this->tria->faces->lines;
4671
4672 if (structdim == 2 && dim > 2)
4673 return this->tria->faces->quads;
4674
4676
4677 return this->tria->levels[this->present_level]->cells;
4678}
4679
4680
4681
4682/*---------------------- Functions: InvalidAccessor -------------------------*/
4683
4684template <int structdim, int dim, int spacedim>
4686 const int,
4687 const int,
4688 const AccessorData *)
4689{
4690 Assert(false,
4691 ExcMessage("You are attempting an invalid conversion between "
4692 "iterator/accessor types. The constructor you call "
4693 "only exists to make certain template constructs "
4694 "easier to write as dimension independent code but "
4695 "the conversion is not valid in the current context."));
4696}
4697
4698
4699
4700template <int structdim, int dim, int spacedim>
4702 const InvalidAccessor &)
4703{
4704 Assert(false,
4705 ExcMessage("You are attempting an invalid conversion between "
4706 "iterator/accessor types. The constructor you call "
4707 "only exists to make certain template constructs "
4708 "easier to write as dimension independent code but "
4709 "the conversion is not valid in the current context."));
4710}
4711
4712
4713
4714template <int structdim, int dim, int spacedim>
4715void
4717{
4718 // nothing to do here. we could
4719 // throw an exception but we can't
4720 // get here without first creating
4721 // an object which would have
4722 // already thrown
4723}
4724
4725
4726
4727template <int structdim, int dim, int spacedim>
4728bool
4730 const InvalidAccessor &) const
4731{
4732 // nothing to do here. we could
4733 // throw an exception but we can't
4734 // get here without first creating
4735 // an object which would have
4736 // already thrown
4737 return false;
4738}
4739
4740
4741
4742template <int structdim, int dim, int spacedim>
4743bool
4745 const InvalidAccessor &) const
4746{
4747 // nothing to do here. we could
4748 // throw an exception but we can't
4749 // get here without first creating
4750 // an object which would have
4751 // already thrown
4752 return true;
4753}
4754
4755
4756
4757template <int structdim, int dim, int spacedim>
4758bool
4760{
4761 // nothing to do here. we could
4762 // throw an exception but we can't
4763 // get here without first creating
4764 // an object which would have
4765 // already thrown
4766 return false;
4767}
4768
4769
4770
4771template <int structdim, int dim, int spacedim>
4772bool
4774{
4775 // nothing to do here. we could
4776 // throw an exception but we can't
4777 // get here without first creating
4778 // an object which would have
4779 // already thrown
4780 return false;
4781}
4782
4783
4784
4785template <int structdim, int dim, int spacedim>
4786void
4788{}
4789
4790
4791
4792template <int structdim, int dim, int spacedim>
4793void
4795{}
4796
4797
4798
4799template <int structdim, int dim, int spacedim>
4802{
4804}
4805
4806
4807
4808template <int structdim, int dim, int spacedim>
4809unsigned int
4811{
4813}
4814
4815
4816
4817template <int structdim, int dim, int spacedim>
4818void
4820 const unsigned int) const
4821{
4822 Assert(false,
4823 ExcMessage("You are trying to set the user index of an "
4824 "invalid object."));
4825}
4826
4827
4828
4829template <int structdim, int dim, int spacedim>
4830void
4832 const types::manifold_id) const
4833{
4834 Assert(false,
4835 ExcMessage("You are trying to set the manifold id of an "
4836 "invalid object."));
4837}
4838
4839
4840
4841template <int structdim, int dim, int spacedim>
4842inline Point<spacedim> &
4844{
4845 // nothing to do here. we could throw an exception but we can't get here
4846 // without first creating an object which would have already thrown
4847 static Point<spacedim> invalid_vertex;
4848 return invalid_vertex;
4849}
4850
4851
4852template <int structdim, int dim, int spacedim>
4853inline void *
4855{
4856 // nothing to do here. we could throw an exception but we can't get here
4857 // without first creating an object which would have already thrown
4858 return nullptr;
4859}
4860
4861
4862
4863template <int structdim, int dim, int spacedim>
4864inline void *
4866{
4867 // nothing to do here. we could throw an exception but we can't get here
4868 // without first creating an object which would have already thrown
4869 return nullptr;
4870}
4871
4872
4873/*------------------------ Functions: TriaAccessor ---------------------------*/
4874
4875
4876namespace internal
4877{
4878 namespace TriaAccessorImplementation
4879 {
4880 // make sure that if in the following we
4881 // write TriaAccessor
4882 // we mean the *class*
4883 // ::TriaAccessor, not the
4884 // enclosing namespace
4885 // ::internal::TriaAccessor
4886 using ::TriaAccessor;
4887
4892 struct Implementation
4893 {
4897 template <int structdim, int dim, int spacedim>
4898 inline static void
4899 set_combined_face_orientation(
4901 const unsigned int face_no,
4902 const types::geometric_orientation combined_orientation)
4903 {
4904 Assert(structdim == dim,
4905 ExcMessage("This function can only be used on objects that are "
4906 "cells and not on objects which bound cells."));
4907 AssertIndexRange(face_no, accessor.n_faces());
4908 AssertIndexRange(combined_orientation,
4910 face_no));
4911
4912 // face_orientations is not set up in 1d
4913 if (dim != 1)
4914 accessor.tria->levels[accessor.present_level]
4915 ->face_orientations.set_combined_orientation(
4916 accessor.present_index * ReferenceCells::max_n_faces<dim>() +
4917 face_no,
4918 combined_orientation);
4919 }
4920
4921
4922
4923 template <int dim, int spacedim>
4924 static std::array<unsigned int, 1>
4925 get_line_indices_of_cell(const TriaAccessor<1, dim, spacedim> &)
4926 {
4928 return {};
4929 }
4930
4931
4932
4933 template <int structdim, int dim, int spacedim>
4934 static std::array<unsigned int, 4>
4935 get_line_indices_of_cell(const TriaAccessor<2, dim, spacedim> &cell)
4936 {
4937 // For 2d cells the access cell->line_orientation() is already
4938 // efficient
4939 std::array<unsigned int, 4> line_indices = {};
4940 for (const unsigned int line : cell.line_indices())
4941 line_indices[line] = cell.line_index(line);
4942 return line_indices;
4943 }
4944
4949 template <int structdim, int dim, int spacedim>
4950 static std::array<unsigned int, 12>
4951 get_line_indices_of_cell(
4953 {
4954 std::array<unsigned int, 12> line_indices = {};
4955
4956 // For hexahedra, the classical access via quads -> lines is too
4957 // inefficient. Unroll this code here to allow the compiler to inline
4958 // the necessary functions.
4959 const auto ref_cell = cell.reference_cell();
4960 if (ref_cell == ReferenceCells::Hexahedron)
4961 {
4962 for (unsigned int f = 4; f < 6; ++f)
4963 {
4964 const auto orientation =
4965 cell.get_triangulation()
4966 .levels[cell.level()]
4967 ->face_orientations.get_combined_orientation(
4968 cell.index() * ReferenceCells::max_n_faces<dim>() + f);
4969
4970 // It might seem superfluous to spell out the four indices
4971 // that get later consumed by a for loop over these four
4972 // elements; however, for the compiler it is easier to inline
4973 // the statement of standard_to_real_face_line() when next to
4974 // each other, as opposed to be interleaved with a
4975 // line_index() call.
4976 const std::array<unsigned int, 4> my_indices{
4977 {ref_cell.standard_to_real_face_line(0, f, orientation),
4978 ref_cell.standard_to_real_face_line(1, f, orientation),
4979 ref_cell.standard_to_real_face_line(2, f, orientation),
4980 ref_cell.standard_to_real_face_line(3, f, orientation)}};
4981 const auto quad = cell.quad(f);
4982 for (unsigned int l = 0; l < 4; ++l)
4983 line_indices[4 * (f - 4) + l] =
4984 quad->line_index(my_indices[l]);
4985 }
4986 for (unsigned int f = 0; f < 2; ++f)
4987 {
4988 const auto orientation =
4989 cell.get_triangulation()
4990 .levels[cell.level()]
4991 ->face_orientations.get_combined_orientation(
4992 cell.index() * ReferenceCells::max_n_faces<dim>() + f);
4993 const std::array<unsigned int, 2> my_indices{
4994 {ref_cell.standard_to_real_face_line(0, f, orientation),
4995 ref_cell.standard_to_real_face_line(1, f, orientation)}};
4996 const auto quad = cell.quad(f);
4997 line_indices[8 + f] = quad->line_index(my_indices[0]);
4998 line_indices[10 + f] = quad->line_index(my_indices[1]);
4999 }
5000 }
5001 else if (ref_cell == ReferenceCells::Tetrahedron)
5002 {
5003 std::array<unsigned int, 3> orientations{
5006 cell.combined_face_orientation(2)}};
5007 const std::array<unsigned int, 6> my_indices{
5008 {ref_cell.standard_to_real_face_line(0, 0, orientations[0]),
5009 ref_cell.standard_to_real_face_line(1, 0, orientations[0]),
5010 ref_cell.standard_to_real_face_line(2, 0, orientations[0]),
5011 ref_cell.standard_to_real_face_line(1, 1, orientations[1]),
5012 ref_cell.standard_to_real_face_line(2, 1, orientations[1]),
5013 ref_cell.standard_to_real_face_line(1, 2, orientations[2])}};
5014 line_indices[0] = cell.quad(0)->line_index(my_indices[0]);
5015 line_indices[1] = cell.quad(0)->line_index(my_indices[1]);
5016 line_indices[2] = cell.quad(0)->line_index(my_indices[2]);
5017 line_indices[3] = cell.quad(1)->line_index(my_indices[3]);
5018 line_indices[4] = cell.quad(1)->line_index(my_indices[4]);
5019 line_indices[5] = cell.quad(2)->line_index(my_indices[5]);
5020 }
5021 else
5022 // For other shapes (wedges, pyramids), we do not currently
5023 // implement an optimized function.
5024 for (unsigned int l = 0; l < std::min(12U, cell.n_lines()); ++l)
5025 line_indices[l] = cell.line_index(l);
5026
5027 return line_indices;
5028 }
5029
5030
5031
5036 template <int dim, int spacedim>
5037 static std::array<types::geometric_orientation, 1>
5038 get_line_orientations_of_cell(const TriaAccessor<1, dim, spacedim> &)
5039 {
5041 return {};
5042 }
5043
5044
5045
5050 template <int dim, int spacedim>
5051 static std::array<types::geometric_orientation, 4>
5052 get_line_orientations_of_cell(const TriaAccessor<2, dim, spacedim> &cell)
5053 {
5054 // For 2d cells the access cell->line_orientation() is already
5055 // efficient
5056 std::array<types::geometric_orientation, 4> line_orientations = {};
5057 for (const unsigned int line : cell.line_indices())
5058 line_orientations[line] = cell.line_orientation(line);
5059 return line_orientations;
5060 }
5061
5062
5063
5068 template <int dim, int spacedim>
5069 static std::array<types::geometric_orientation, 12>
5070 get_line_orientations_of_cell(const TriaAccessor<3, dim, spacedim> &cell)
5071 {
5072 std::array<types::geometric_orientation, 12> line_orientations = {};
5073
5074 // For hexahedra, the classical access via quads -> lines is too
5075 // inefficient. Unroll this code here to allow the compiler to inline
5076 // the necessary functions.
5077 const auto ref_cell = cell.reference_cell();
5078 if (ref_cell == ReferenceCells::Hexahedron)
5079 {
5080 for (unsigned int f = 4; f < 6; ++f)
5081 {
5082 const auto orientation =
5083 cell.get_triangulation()
5084 .levels[cell.level()]
5085 ->face_orientations.get_combined_orientation(
5086 cell.index() * ReferenceCells::max_n_faces<dim>() + f);
5087
5088 // It might seem superfluous to spell out the four indices and
5089 // orientations that get later consumed by a for loop over
5090 // these four elements; however, for the compiler it is easier
5091 // to inline the statement of standard_to_real_face_line()
5092 // when next to each other, as opposed to be interleaved with
5093 // a line_index() call.
5094 const std::array<unsigned int, 4> my_indices{
5095 {ref_cell.standard_to_real_face_line(0, f, orientation),
5096 ref_cell.standard_to_real_face_line(1, f, orientation),
5097 ref_cell.standard_to_real_face_line(2, f, orientation),
5098 ref_cell.standard_to_real_face_line(3, f, orientation)}};
5099 const auto quad = cell.quad(f);
5100 const std::array<types::geometric_orientation, 4>
5101 my_orientations{{ref_cell.face_to_cell_line_orientation(
5102 0,
5103 f,
5104 orientation,
5105 quad->line_orientation(my_indices[0])),
5106 ref_cell.face_to_cell_line_orientation(
5107 1,
5108 f,
5109 orientation,
5110 quad->line_orientation(my_indices[1])),
5111 ref_cell.face_to_cell_line_orientation(
5112 2,
5113 f,
5114 orientation,
5115 quad->line_orientation(my_indices[2])),
5116 ref_cell.face_to_cell_line_orientation(
5117 3,
5118 f,
5119 orientation,
5120 quad->line_orientation(my_indices[3]))}};
5121 for (unsigned int l = 0; l < 4; ++l)
5122 line_orientations[4 * (f - 4) + l] = my_orientations[l];
5123 }
5124 for (unsigned int f = 0; f < 2; ++f)
5125 {
5126 const auto orientation =
5127 cell.get_triangulation()
5128 .levels[cell.level()]
5129 ->face_orientations.get_combined_orientation(
5130 cell.index() * ReferenceCells::max_n_faces<3>() + f);
5131 const std::array<unsigned int, 2> my_indices{
5132 {ref_cell.standard_to_real_face_line(0, f, orientation),
5133 ref_cell.standard_to_real_face_line(1, f, orientation)}};
5134 const auto quad = cell.quad(f);
5135 const std::array<types::geometric_orientation, 2>
5136 my_orientations{{ref_cell.face_to_cell_line_orientation(
5137 0,
5138 f,
5139 orientation,
5140 quad->line_orientation(my_indices[0])),
5141 ref_cell.face_to_cell_line_orientation(
5142 1,
5143 f,
5144 orientation,
5145 quad->line_orientation(my_indices[1]))}};
5146 line_orientations[8 + f] = my_orientations[0];
5147 line_orientations[10 + f] = my_orientations[1];
5148 }
5149 }
5150 else if (ref_cell == ReferenceCells::Tetrahedron)
5151 {
5152 std::array<unsigned int, 3> orientations{
5155 cell.combined_face_orientation(2)}};
5156 const std::array<unsigned int, 6> my_indices{
5157 {ref_cell.standard_to_real_face_line(0, 0, orientations[0]),
5158 ref_cell.standard_to_real_face_line(1, 0, orientations[0]),
5159 ref_cell.standard_to_real_face_line(2, 0, orientations[0]),
5160 ref_cell.standard_to_real_face_line(1, 1, orientations[1]),
5161 ref_cell.standard_to_real_face_line(2, 1, orientations[1]),
5162 ref_cell.standard_to_real_face_line(1, 2, orientations[2])}};
5163 line_orientations[0] = ref_cell.face_to_cell_line_orientation(
5164 0,
5165 0,
5166 orientations[0],
5167 cell.quad(0)->line_orientation(my_indices[0]));
5168 line_orientations[1] = ref_cell.face_to_cell_line_orientation(
5169 1,
5170 0,
5171 orientations[0],
5172 cell.quad(0)->line_orientation(my_indices[1]));
5173 line_orientations[2] = ref_cell.face_to_cell_line_orientation(
5174 2,
5175 0,
5176 orientations[0],
5177 cell.quad(0)->line_orientation(my_indices[2]));
5178 line_orientations[3] = ref_cell.face_to_cell_line_orientation(
5179 1,
5180 1,
5181 orientations[1],
5182 cell.quad(1)->line_orientation(my_indices[3]));
5183 line_orientations[4] = ref_cell.face_to_cell_line_orientation(
5184 2,
5185 1,
5186 orientations[1],
5187 cell.quad(1)->line_orientation(my_indices[4]));
5188 line_orientations[5] = ref_cell.face_to_cell_line_orientation(
5189 1,
5190 2,
5191 orientations[2],
5192 cell.quad(2)->line_orientation(my_indices[5]));
5193 }
5194 else
5195 // For other shapes (wedges, pyramids), we do not currently
5196 // implement an optimized function
5197 for (unsigned int l = 0; l < std::min(12U, cell.n_lines()); ++l)
5198 line_orientations[l] = cell.line_orientation(l);
5199
5200 return line_orientations;
5201 }
5202 };
5203 } // namespace TriaAccessorImplementation
5204} // namespace internal
5205
5206
5207
5208template <int structdim, int dim, int spacedim>
5210 const Triangulation<dim, spacedim> *parent,
5211 const int level,
5212 const int index,
5213 const AccessorData *local_data)
5214 : TriaAccessorBase<structdim, dim, spacedim>(parent, level, index, local_data)
5215{}
5216
5217
5218
5219template <int structdim, int dim, int spacedim>
5220inline bool
5222{
5223 Assert(this->state() == IteratorState::valid,
5224 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5225 *this));
5226 return this->objects().used[this->present_index];
5227}
5228
5229
5230
5231template <int structdim, int dim, int spacedim>
5234 const unsigned int i) const
5235{
5237 0,
5238 vertex_index(i));
5239}
5240
5241
5242
5243template <int structdim, int dim, int spacedim>
5244inline ReferenceCell
5246{
5247 if (structdim == 0)
5249 else if (structdim == 1)
5250 return ReferenceCells::Line;
5251 else if (structdim == dim)
5252 return this->tria->levels[this->present_level]
5253 ->reference_cell[this->present_index];
5254 else
5255 return this->tria->faces->get_quad_type(this->present_index);
5256}
5257
5258
5259
5260template <int structdim, int dim, int spacedim>
5261inline unsigned int
5263 const unsigned int corner) const
5264{
5265 AssertIndexRange(corner, this->n_vertices());
5266
5267 if constexpr (structdim == 1)
5268 {
5269 // This branch needs to be first (and not combined with the structdim ==
5270 // dim branch) so that we can get line vertex indices when setting up the
5271 // cell vertex index cache
5272 return this->objects()
5273 .cells[this->present_index * ReferenceCells::max_n_faces<1>() + corner];
5274 }
5275 else if constexpr (structdim == dim)
5276 {
5277 // This branch should only be used after the cell vertex index cache is
5278 // set up
5279 const auto my_index = static_cast<std::size_t>(this->present_index) *
5280 ReferenceCells::max_n_vertices<dim>();
5281 AssertIndexRange(my_index + corner,
5282 this->tria->levels[this->present_level]
5283 ->cell_vertex_indices_cache.size());
5284 const unsigned int vertex_index =
5285 this->tria->levels[this->present_level]
5286 ->cell_vertex_indices_cache[my_index + corner];
5288 return vertex_index;
5289 }
5290 else if constexpr (structdim == 2)
5291 {
5292 const auto [line_index, vertex_index] =
5293 this->reference_cell().standard_vertex_to_face_and_vertex_index(corner);
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()
5344 .cells[this->present_index * ReferenceCells::max_n_faces<2>() + i];
5345 }
5346 else if constexpr (structdim == 3)
5347 {
5348 const auto [face_index, line_index] =
5349 this->reference_cell().standard_line_to_face_and_line_index(i);
5350 const auto line_within_face_index =
5351 this->reference_cell().standard_to_real_face_line(
5352 line_index, face_index, this->combined_face_orientation(face_index));
5353
5354 return this->quad(face_index)->line_index(line_within_face_index);
5355 }
5356
5359}
5360
5361
5362
5363template <int structdim, int dim, int spacedim>
5364inline typename ::internal::TriangulationImplementation::
5365 Iterators<dim, spacedim>::quad_iterator
5366 TriaAccessor<structdim, dim, spacedim>::quad(const unsigned int i) const
5367{
5368 // checks happen in quad_index
5369 return typename ::internal::TriangulationImplementation::
5370 Iterators<dim, spacedim>::quad_iterator(this->tria, 0, quad_index(i));
5371}
5372
5373
5374
5375template <int structdim, int dim, int spacedim>
5376inline unsigned int
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 i unused except in 3d
5384 (void)i;
5385 if constexpr (structdim == 3)
5386 {
5387 AssertIndexRange(i, n_faces());
5388 return this->tria->levels[this->present_level]
5389 ->cells
5390 .cells[this->present_index * ReferenceCells::max_n_faces<3>() + i];
5391 }
5392 else
5394}
5395
5396
5397
5398template <int structdim, int dim, int spacedim>
5401 const unsigned int face) const
5402{
5404 AssertIndexRange(face, n_faces());
5405 Assert(structdim == dim,
5406 ExcMessage("This function can only be used on objects "
5407 "that are cells, but not on faces or edges "
5408 "that bound cells."));
5409 // work around a bogus GCC-9 warning which considers face unused except in 3d
5410 (void)face;
5411
5412 if constexpr (structdim == 1)
5414 else if constexpr (structdim == 2)
5415 {
5416 // if all elements are quads (or if we have a very special consistently
5417 // oriented triangular mesh) then we do not store this array
5418 if (this->tria->levels[this->present_level]
5419 ->face_orientations.n_objects() == 0)
5421 else
5422 return this->tria->levels[this->present_level]
5423 ->face_orientations.get_combined_orientation(
5424 this->present_index * ReferenceCells::max_n_faces<dim>() + face);
5425 }
5426 else
5427 return this->tria->levels[this->present_level]
5428 ->face_orientations.get_combined_orientation(
5429 this->present_index * ReferenceCells::max_n_faces<dim>() + face);
5430}
5431
5432
5433
5434template <int structdim, int dim, int spacedim>
5435inline bool
5437 const unsigned int face) const
5438{
5440 AssertIndexRange(face, n_faces());
5441 Assert(structdim == dim,
5442 ExcMessage("This function can only be used on objects "
5443 "that are cells, but not on faces or edges "
5444 "that bound cells."));
5445 // work around a bogus GCC-9 warning which considers face unused in 1d
5446 (void)face;
5447
5448 if constexpr (structdim == 1)
5449 // in 1d 'faces' are vertices and those are always consistently oriented
5450 return true;
5451 else if constexpr (structdim == 2)
5452 return this->line_orientation(face) ==
5454 else
5455 return this->tria->levels[this->present_level]
5456 ->face_orientations.get_orientation(
5457 this->present_index * ReferenceCells::max_n_faces<structdim>() + face);
5458}
5459
5460
5461
5462template <int structdim, int dim, int spacedim>
5463inline bool
5464TriaAccessor<structdim, dim, spacedim>::face_flip(const unsigned int face) const
5465{
5467 Assert(structdim == dim,
5468 ExcMessage("This function can only be used on objects "
5469 "that are cells, but not on faces or edges "
5470 "that bound cells."));
5471 AssertIndexRange(face, n_faces());
5472 // work around a bogus GCC-9 warning which considers face unused except in 3d
5473 (void)face;
5474
5475 if constexpr (structdim == 3)
5476 return this->tria->levels[this->present_level]->face_orientations.get_flip(
5477 this->present_index * ReferenceCells::max_n_faces<structdim>() + face);
5478 else
5479 // In 1d and 2d, face_flip is always false as faces can only be
5480 // 'flipped' in 3d.
5481 return false;
5482}
5483
5484
5485template <int structdim, int dim, int spacedim>
5486inline bool
5488 const unsigned int face) const
5489{
5491 Assert(structdim == dim,
5492 ExcMessage("This function can only be used on objects "
5493 "that are cells, but not on faces or edges "
5494 "that bound cells."));
5495 AssertIndexRange(face, n_faces());
5496 // work around a bogus GCC-9 warning which considers face unused except in 3d
5497 (void)face;
5498
5499 if constexpr (structdim == 3)
5500 return this->tria->levels[this->present_level]
5501 ->face_orientations.get_rotation(
5502 this->present_index * ReferenceCells::max_n_faces<structdim>() + face);
5503 else
5504 // In 1d and 2d, face_rotation is always false as faces can only be
5505 // 'rotated' in 3d.
5506 return false;
5507}
5508
5509
5510
5511template <int structdim, int dim, int spacedim>
5514 const unsigned int line) const
5515{
5517 AssertIndexRange(line, this->n_lines());
5518 // work around a bogus GCC-9 warning which considers line unused in 1d
5519 (void)line;
5520
5521 if constexpr (structdim == 1)
5523 else if constexpr (structdim == 2 && dim == 2)
5524 // lines in 2d are faces
5525 {
5526 const auto combined_orientation = combined_face_orientation(line);
5527 Assert(combined_orientation == numbers::default_geometric_orientation ||
5528 combined_orientation == numbers::reverse_line_orientation,
5530 return combined_orientation;
5531 }
5532 else if constexpr (structdim == 2 && dim == 3)
5533 {
5534 // line orientations in 3d are stored in their own array as bools: here
5535 // 'true' is the default orientation and 'false' is the reversed one
5536 // (which matches set_line_orientation())
5537 const auto index =
5538 this->present_index * ReferenceCells::max_n_lines<2>() + line;
5539 Assert(index < this->tria->faces->quads_line_orientations.size(),
5541 return this->tria->faces->quads_line_orientations[index] ?
5544 }
5545 else if constexpr (structdim == 3 && dim == 3)
5546 {
5547 const auto reference_cell = this->reference_cell();
5548 // First pick a face on which this line is a part of, and the
5549 // index of the line within.
5550 const auto [face_index, line_index] =
5551 reference_cell.standard_line_to_face_and_line_index(line);
5552 const auto line_within_face_index =
5553 reference_cell.standard_to_real_face_line(
5554 line_index, face_index, this->combined_face_orientation(face_index));
5555
5556 // Then query how that line is oriented within that face:
5557 return reference_cell.face_to_cell_line_orientation(
5558 line_index,
5559 face_index,
5560 this->combined_face_orientation(face_index),
5561 this->quad(face_index)->line_orientation(line_within_face_index));
5562 }
5563 else
5564 {
5566 return false;
5567 }
5568}
5569
5570
5571
5572template <int structdim, int dim, int spacedim>
5573inline void
5575 const unsigned int line,
5576 const types::geometric_orientation value) const
5577{
5579 AssertIndexRange(line, this->n_lines());
5580 Assert(dim != 1,
5581 ExcMessage("In 1d lines are cells and thus do not need to have their "
5582 "orientations set."));
5583 Assert(dim != 2,
5584 ExcMessage("In 2d lines are faces, and, for compatibility with other "
5585 "dimensions, their orientations should be set via "
5586 "set_combined_face_orientation()."));
5587 // work around a bogus GCC-9 warning which considers line and value unused
5588 // except in 3d
5589 (void)line;
5590 (void)value;
5591
5592 if constexpr (dim == 3)
5593 {
5594 // We set line orientations per face, not per cell, so this only works for
5595 // faces in 3d.
5596 Assert(structdim == 2, ExcNotImplemented());
5597 const auto index =
5598 this->present_index * ReferenceCells::max_n_lines<2>() + line;
5599 Assert(index < this->tria->faces->quads_line_orientations.size(),
5601 this->tria->faces->quads_line_orientations[index] =
5603 }
5604}
5605
5606
5607
5608template <int structdim, int dim, int spacedim>
5609inline void
5611 const unsigned int face,
5612 const types::geometric_orientation combined_orientation) const
5613{
5615 AssertIndexRange(face, this->n_faces());
5616
5617 ::internal::TriaAccessorImplementation::Implementation::
5618 set_combined_face_orientation(*this, face, combined_orientation);
5619}
5620
5621
5622
5623template <int structdim, int dim, int spacedim>
5624void
5626{
5627 Assert(this->state() == IteratorState::valid,
5628 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5629 *this));
5630 this->objects().used[this->present_index] = true;
5631}
5632
5633
5634
5635template <int structdim, int dim, int spacedim>
5636void
5638{
5639 Assert(this->state() == IteratorState::valid,
5640 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5641 *this));
5642 this->objects().used[this->present_index] = false;
5643}
5644
5645
5646template <int structdim, int dim, int spacedim>
5647int
5649{
5651 AssertIndexRange(i, n_children());
5652
5653 // each set of two children are stored
5654 // consecutively, so we only have to find
5655 // the location of the set of children
5656 const unsigned int n_sets_of_two =
5658 return this->objects().children[n_sets_of_two * this->present_index + i / 2] +
5659 i % 2;
5660}
5661
5662
5663
5664template <int structdim, int dim, int spacedim>
5665int
5667 const unsigned int i) const
5668{
5670
5671 switch (structdim)
5672 {
5673 case 1:
5674 return child_index(i);
5675 case 2:
5676 {
5677 const RefinementCase<2> this_refinement_case(
5678 static_cast<std::uint8_t>(refinement_case()));
5679
5680 Assert(this_refinement_case != RefinementCase<2>::no_refinement,
5682
5683 if (this_refinement_case == RefinementCase<2>::cut_xy)
5684 return child_index(i);
5685 else if ((this_refinement_case == RefinementCase<2>::cut_x) &&
5686 (child(i % 2)->refinement_case() ==
5688 return child(i % 2)->child_index(i / 2);
5689 else if ((this_refinement_case == RefinementCase<2>::cut_y) &&
5690 (child(i / 2)->refinement_case() ==
5692 return child(i / 2)->child_index(i % 2);
5693 else
5694 Assert(
5695 false,
5696 ExcMessage(
5697 "This cell has no grandchildren equivalent to isotropic refinement"));
5698 break;
5699 }
5700
5701 case 3:
5703 }
5704 return -1;
5705}
5706
5707
5708
5709template <int structdim, int dim, int spacedim>
5712{
5713 Assert(this->state() == IteratorState::valid,
5714 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5715 *this));
5716
5717 switch (structdim)
5718 {
5719 case 1:
5721 this->objects().children[this->present_index] != -1 ?
5722 // cast the branches
5723 // here first to uchar
5724 // and then (above) to
5725 // RefinementCase<structdim>
5726 // so that the
5727 // conversion is valid
5728 // even for the case
5729 // structdim>1 (for
5730 // which this part of
5731 // the code is dead
5732 // anyway)
5733 static_cast<std::uint8_t>(RefinementCase<1>::cut_x) :
5734 static_cast<std::uint8_t>(RefinementCase<1>::no_refinement)));
5735
5736 default:
5737 Assert(static_cast<unsigned int>(this->present_index) <
5738 this->objects().refinement_cases.size(),
5739 ExcIndexRange(this->present_index,
5740 0,
5741 this->objects().refinement_cases.size()));
5742
5743 return (static_cast<RefinementCase<structdim>>(
5744 this->objects().refinement_cases[this->present_index]));
5745 }
5746}
5747
5748
5749
5750template <int structdim, int dim, int spacedim>
5752TriaAccessor<structdim, dim, spacedim>::child(const unsigned int i) const
5753
5754{
5755 // checking of 'i' happens in child_index
5757 this->tria, (dim == structdim ? this->level() + 1 : 0), child_index(i));
5758
5759 Assert((q.state() == IteratorState::past_the_end) || q->used(),
5761
5762 return q;
5763}
5764
5765
5766
5767template <int structdim, int dim, int spacedim>
5768inline unsigned int
5771{
5772 const auto n_children = this->n_children();
5773 for (unsigned int child_n = 0; child_n < n_children; ++child_n)
5774 if (this->child(child_n) == child)
5775 return child_n;
5776
5777 Assert(false,
5778 ExcMessage("The given child is not a child of the current object."));
5780}
5781
5782
5783
5784template <int structdim, int dim, int spacedim>
5787 const unsigned int i) const
5788{
5789 // checking of 'i' happens in child() or
5790 // child_index() called below
5791 switch (structdim)
5792 {
5793 case 1:
5794 // no anisotropic refinement in 1d
5795 return child(i);
5796
5797 case 2:
5798 {
5799 const RefinementCase<2> this_refinement_case(
5800 static_cast<std::uint8_t>(refinement_case()));
5801
5802 Assert(this_refinement_case != RefinementCase<2>::no_refinement,
5804
5805 if (this_refinement_case == RefinementCase<2>::cut_xy)
5806 return child(i);
5807 else if ((this_refinement_case == RefinementCase<2>::cut_x) &&
5808 (child(i % 2)->refinement_case() ==
5810 return child(i % 2)->child(i / 2);
5811 else if ((this_refinement_case == RefinementCase<2>::cut_y) &&
5812 (child(i / 2)->refinement_case() ==
5814 return child(i / 2)->child(i % 2);
5815 else
5816 Assert(
5817 false,
5818 ExcMessage(
5819 "This cell has no grandchildren equivalent to isotropic refinement"));
5820 break;
5821 }
5822
5823 default:
5825 }
5826 // we don't get here but have to return
5827 // something...
5828 return child(0);
5829}
5830
5831
5832
5833template <int structdim, int dim, int spacedim>
5834inline bool
5836{
5837 Assert(this->state() == IteratorState::valid,
5838 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5839 *this));
5840
5841 // each set of two children are stored
5842 // consecutively, so we only have to find
5843 // the location of the set of children
5844 const unsigned int n_sets_of_two =
5846 return (this->objects().children[n_sets_of_two * this->present_index] != -1);
5847}
5848
5849
5850
5851template <int structdim, int dim, int spacedim>
5852inline unsigned int
5854{
5855 Assert(this->state() == IteratorState::valid,
5856 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5857 *this));
5861 else
5862 return GeometryInfo<structdim>::n_children(refinement_case());
5863}
5864
5865
5866
5867template <int structdim, int dim, int spacedim>
5868inline void
5870 const RefinementCase<structdim> &refinement_case) const
5871{
5872 Assert(this->state() == IteratorState::valid,
5873 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5874 *this));
5875 Assert(static_cast<unsigned int>(this->present_index) <
5876 this->objects().refinement_cases.size(),
5877 ExcIndexRange(this->present_index,
5878 0,
5879 this->objects().refinement_cases.size()));
5880
5881 this->objects().refinement_cases[this->present_index] = refinement_case;
5882}
5883
5884
5885template <int structdim, int dim, int spacedim>
5886inline void
5888{
5889 Assert(this->state() == IteratorState::valid,
5890 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5891 *this));
5892 Assert(static_cast<unsigned int>(this->present_index) <
5893 this->objects().refinement_cases.size(),
5894 ExcIndexRange(this->present_index,
5895 0,
5896 this->objects().refinement_cases.size()));
5897
5898 this->objects().refinement_cases[this->present_index] =
5900}
5901
5902
5903
5904template <int structdim, int dim, int spacedim>
5905void
5907 const int index) const
5908{
5911
5912 // each set of two children are stored
5913 // consecutively, so we only have to find
5914 // the location of the set of children
5915 const unsigned int n_sets_of_two =
5917
5918 Assert(
5919 // clearing the child index for a cell
5920 (index == -1) ||
5921 // if setting the child index for the i'th child (with i==0),
5922 // then the index must be a non-negative number
5923 (i == 0 && !this->has_children() && (index >= 0)) ||
5924 // if setting the child index for the i'th child (with i>0),
5925 // then the previously stored index must be the invalid
5926 // index
5927 (i > 0 && this->has_children() && (index >= 0) &&
5928 this->objects().children[n_sets_of_two * this->present_index + i / 2] ==
5929 -1),
5931
5932 this->objects().children[n_sets_of_two * this->present_index + i / 2] = index;
5933}
5934
5935
5936
5937template <int structdim, int dim, int spacedim>
5938void
5940{
5941 // each set of two children are stored
5942 // consecutively, so we only have to find
5943 // the location of the set of children
5944 const unsigned int n_sets_of_two =
5946
5947 for (unsigned int i = 0; i < n_sets_of_two; ++i)
5948 set_children(2 * i, -1);
5949}
5950
5951
5952
5953template <int structdim, int dim, int spacedim>
5954inline bool
5956{
5958 return this->objects().user_flags[this->present_index];
5959}
5960
5961
5962
5963template <int structdim, int dim, int spacedim>
5964inline void
5966{
5968 this->objects().user_flags[this->present_index] = true;
5969}
5970
5971
5972
5973template <int structdim, int dim, int spacedim>
5974inline void
5976{
5978 this->objects().user_flags[this->present_index] = false;
5979}
5980
5981
5982
5983template <int structdim, int dim, int spacedim>
5984void
5986{
5987 set_user_flag();
5988
5989 if (this->has_children())
5990 for (unsigned int c = 0; c < this->n_children(); ++c)
5991 this->child(c)->recursively_set_user_flag();
5992}
5993
5994
5995
5996template <int structdim, int dim, int spacedim>
5997void
5999{
6000 clear_user_flag();
6001
6002 if (this->has_children())
6003 for (unsigned int c = 0; c < this->n_children(); ++c)
6004 this->child(c)->recursively_clear_user_flag();
6005}
6006
6007
6008
6009template <int structdim, int dim, int spacedim>
6010void
6012{
6014 this->objects().clear_user_data(this->present_index);
6015}
6016
6017
6018
6019template <int structdim, int dim, int spacedim>
6020void
6022{
6024 this->objects().user_pointer(this->present_index) = p;
6025}
6026
6027
6028
6029template <int structdim, int dim, int spacedim>
6030void
6032{
6034 this->objects().user_pointer(this->present_index) = nullptr;
6035}
6036
6037
6038
6039template <int structdim, int dim, int spacedim>
6040void *
6042{
6044 return this->objects().user_pointer(this->present_index);
6045}
6046
6047
6048
6049template <int structdim, int dim, int spacedim>
6050void
6052 void *p) const
6053{
6054 set_user_pointer(p);
6055
6056 if (this->has_children())
6057 for (unsigned int c = 0; c < this->n_children(); ++c)
6058 this->child(c)->recursively_set_user_pointer(p);
6059}
6060
6061
6062
6063template <int structdim, int dim, int spacedim>
6064void
6066{
6067 clear_user_pointer();
6068
6069 if (this->has_children())
6070 for (unsigned int c = 0; c < this->n_children(); ++c)
6071 this->child(c)->recursively_clear_user_pointer();
6072}
6073
6074
6075
6076template <int structdim, int dim, int spacedim>
6077void
6079 const unsigned int p) const
6080{
6082 this->objects().user_index(this->present_index) = p;
6083}
6084
6085
6086
6087template <int structdim, int dim, int spacedim>
6088void
6090{
6092 this->objects().user_index(this->present_index) = 0;
6093}
6094
6095
6096
6097template <int structdim, int dim, int spacedim>
6098unsigned int
6100{
6102 return this->objects().user_index(this->present_index);
6103}
6104
6105
6106
6107template <int structdim, int dim, int spacedim>
6108void
6110 const unsigned int p) const
6111{
6112 set_user_index(p);
6113
6114 if (this->has_children())
6115 for (unsigned int c = 0; c < this->n_children(); ++c)
6116 this->child(c)->recursively_set_user_index(p);
6117}
6118
6119
6120
6121template <int structdim, int dim, int spacedim>
6122void
6124{
6125 clear_user_index();
6126
6127 if (this->has_children())
6128 for (unsigned int c = 0; c < this->n_children(); ++c)
6129 this->child(c)->recursively_clear_user_index();
6130}
6131
6132
6133
6134template <int structdim, int dim, int spacedim>
6135inline unsigned int
6137{
6138 if (!this->has_children())
6139 return 0;
6140
6141 unsigned int max_depth = 1;
6142 for (unsigned int c = 0; c < n_children(); ++c)
6143 max_depth = std::max(max_depth, child(c)->max_refinement_depth() + 1);
6144 return max_depth;
6145}
6146
6147
6148
6149template <int structdim, int dim, int spacedim>
6150unsigned int
6152{
6153 if (!this->has_children())
6154 return 1;
6155 else
6156 {
6157 unsigned int sum = 0;
6158 for (unsigned int c = 0; c < n_children(); ++c)
6159 sum += this->child(c)->n_active_descendants();
6160 return sum;
6161 }
6162}
6163
6164
6165
6166template <int structdim, int dim, int spacedim>
6169{
6170 Assert(structdim < dim, ExcImpossibleInDim(dim));
6172
6173 return this->objects()
6174 .boundary_or_material_id[this->present_index]
6175 .boundary_id;
6176}
6177
6178
6179
6180template <int structdim, int dim, int spacedim>
6181void
6183 const types::boundary_id boundary_ind) const
6184{
6185 Assert(structdim < dim, ExcImpossibleInDim(dim));
6188 ExcMessage("You are trying to set the boundary_id to an invalid "
6189 "value (numbers::internal_face_boundary_id is reserved)."));
6190 Assert(this->at_boundary(),
6191 ExcMessage("You are trying to set the boundary_id of an "
6192 "internal object, which is not allowed!"));
6193
6194 this->objects().boundary_or_material_id[this->present_index].boundary_id =
6195 boundary_ind;
6196}
6197
6198
6199
6200template <int structdim, int dim, int spacedim>
6201void
6203 const types::boundary_id boundary_ind) const
6204{
6205 Assert(structdim < dim, ExcImpossibleInDim(dim));
6207
6208 this->objects().boundary_or_material_id[this->present_index].boundary_id =
6209 boundary_ind;
6210}
6211
6212
6213
6214template <int structdim, int dim, int spacedim>
6215void
6217 const types::boundary_id boundary_ind) const
6218{
6219 set_boundary_id(boundary_ind);
6220
6221 switch (structdim)
6222 {
6223 case 1:
6224 // 1d objects have no sub-objects
6225 // where we have to do anything
6226 break;
6227
6228 case 2:
6229 // for boundary quads also set
6230 // boundary_id of bounding lines
6231 for (unsigned int i = 0; i < this->n_lines(); ++i)
6232 this->line(i)->set_boundary_id(boundary_ind);
6233 break;
6234
6235 default:
6237 }
6238}
6239
6240
6241
6242template <int structdim, int dim, int spacedim>
6243bool
6245{
6246 // error checking is done
6247 // in boundary_id()
6249}
6250
6251
6252
6253template <int structdim, int dim, int spacedim>
6256{
6258 return this->tria->get_manifold(this->manifold_id());
6259}
6260
6261
6262template <int structdim, int dim, int spacedim>
6265{
6267
6268 return this->objects().manifold_id[this->present_index];
6269}
6270
6271
6272
6273template <int structdim, int dim, int spacedim>
6274void
6276 const types::manifold_id manifold_ind) const
6277{
6279
6280 this->objects().manifold_id[this->present_index] = manifold_ind;
6281}
6282
6283
6284template <int structdim, int dim, int spacedim>
6285void
6287 const types::manifold_id manifold_ind) const
6288{
6289 set_manifold_id(manifold_ind);
6290
6291 if (this->has_children())
6292 for (unsigned int c = 0; c < this->n_children(); ++c)
6293 this->child(c)->set_all_manifold_ids(manifold_ind);
6294
6295 switch (structdim)
6296 {
6297 case 1:
6298 if (dim == 1)
6299 {
6300 (*this->tria->vertex_to_manifold_id_map_1d)[vertex_index(0)] =
6301 manifold_ind;
6302 (*this->tria->vertex_to_manifold_id_map_1d)[vertex_index(1)] =
6303 manifold_ind;
6304 }
6305 break;
6306
6307 case 2:
6308 // for quads/simplices also set manifold_id of bounding lines
6309 for (unsigned int i = 0; i < this->n_lines(); ++i)
6310 this->line(i)->set_manifold_id(manifold_ind);
6311 break;
6312 default:
6314 }
6315}
6316
6317
6318
6319template <int structdim, int dim, int spacedim>
6320double
6322{
6323 boost::container::small_vector<Point<spacedim>,
6324# ifndef _MSC_VER
6325 ReferenceCells::max_n_vertices<structdim>()
6326# else
6328# endif
6329 >
6330 vertices(this->n_vertices());
6331
6332 for (unsigned int v = 0; v < vertices.size(); ++v)
6333 vertices[v] = this->vertex(v);
6334
6335 return internal::TriaAccessorImplementation::diameter<structdim, spacedim>(
6336 vertices);
6337}
6338
6339
6340
6341template <int dim, int spacedim>
6342double
6344 const Mapping<dim, spacedim> &mapping) const
6345{
6346 return internal::TriaAccessorImplementation::diameter<dim, spacedim>(
6348 this->tria, this->level(), this->index())));
6349}
6350
6351
6352
6353template <int structdim, int dim, int spacedim>
6354std::pair<Point<spacedim>, double>
6356{
6357 // If the object is one dimensional,
6358 // the enclosing ball is the initial iterate
6359 // i.e., the ball's center and diameter are
6360 // the center and the diameter of the object.
6361 if (structdim == 1)
6362 return std::make_pair((this->vertex(1) + this->vertex(0)) * 0.5,
6363 (this->vertex(1) - this->vertex(0)).norm() * 0.5);
6364
6365 // The list is_initial_guess_vertex contains bool values and has
6366 // the same size as the number of vertices per object.
6367 // The entries of is_initial_guess_vertex are set true only for those
6368 // two vertices corresponding to the largest diagonal which is being used
6369 // to construct the initial ball.
6370 // We employ this mask to skip these two vertices while enlarging the ball.
6371 std::vector<bool> is_initial_guess_vertex(this->n_vertices());
6372
6373 // First let all the vertices be outside
6374 std::fill(is_initial_guess_vertex.begin(),
6375 is_initial_guess_vertex.end(),
6376 false);
6377
6378 // Get an initial guess by looking at the largest diagonal
6379 Point<spacedim> center;
6380 double radius = 0;
6381
6382 switch (structdim)
6383 {
6384 case 2:
6385 {
6386 const Point<spacedim> p30(this->vertex(3) - this->vertex(0));
6387 const Point<spacedim> p21(this->vertex(2) - this->vertex(1));
6388 if (p30.norm() > p21.norm())
6389 {
6390 center = this->vertex(0) + 0.5 * p30;
6391 radius = p30.norm() / 2.;
6392 is_initial_guess_vertex[3] = true;
6393 is_initial_guess_vertex[0] = true;
6394 }
6395 else
6396 {
6397 center = this->vertex(1) + 0.5 * p21;
6398 radius = p21.norm() / 2.;
6399 is_initial_guess_vertex[2] = true;
6400 is_initial_guess_vertex[1] = true;
6401 }
6402 break;
6403 }
6404 case 3:
6405 {
6406 const Point<spacedim> p70(this->vertex(7) - this->vertex(0));
6407 const Point<spacedim> p61(this->vertex(6) - this->vertex(1));
6408 const Point<spacedim> p25(this->vertex(2) - this->vertex(5));
6409 const Point<spacedim> p34(this->vertex(3) - this->vertex(4));
6410 const std::vector<double> diagonals = {p70.norm(),
6411 p61.norm(),
6412 p25.norm(),
6413 p34.norm()};
6414 const std::vector<double>::const_iterator it =
6415 std::max_element(diagonals.begin(), diagonals.end());
6416 if (it == diagonals.begin())
6417 {
6418 center = this->vertex(0) + 0.5 * p70;
6419 is_initial_guess_vertex[7] = true;
6420 is_initial_guess_vertex[0] = true;
6421 }
6422 else if (it == diagonals.begin() + 1)
6423 {
6424 center = this->vertex(1) + 0.5 * p61;
6425 is_initial_guess_vertex[6] = true;
6426 is_initial_guess_vertex[1] = true;
6427 }
6428 else if (it == diagonals.begin() + 2)
6429 {
6430 center = this->vertex(5) + 0.5 * p25;
6431 is_initial_guess_vertex[2] = true;
6432 is_initial_guess_vertex[5] = true;
6433 }
6434 else
6435 {
6436 center = this->vertex(4) + 0.5 * p34;
6437 is_initial_guess_vertex[3] = true;
6438 is_initial_guess_vertex[4] = true;
6439 }
6440 radius = *it * 0.5;
6441 break;
6442 }
6443 default:
6445 return std::pair<Point<spacedim>, double>();
6446 }
6447
6448 // For each vertex that is found to be geometrically outside the ball
6449 // enlarge the ball so that the new ball contains both the previous ball
6450 // and the given vertex.
6451 for (const unsigned int v : this->vertex_indices())
6452 if (!is_initial_guess_vertex[v])
6453 {
6454 const double distance = center.distance(this->vertex(v));
6455 if (distance > radius)
6456 {
6457 // we found a vertex which is outside of the ball
6458 // extend it (move center and change radius)
6459 const Point<spacedim> pCV(center - this->vertex(v));
6460 radius = (distance + radius) * 0.5;
6461 center = this->vertex(v) + pCV * (radius / distance);
6462
6463 // Now the new ball constructed in this block
6464 // encloses the vertex (v) that was found to be geometrically
6465 // outside the old ball.
6466 }
6467 }
6468 if constexpr (running_in_debug_mode())
6469 {
6470 bool all_vertices_within_ball = true;
6471
6472 // Set all_vertices_within_ball false if any of the vertices of the object
6473 // are geometrically outside the ball
6474 for (const unsigned int v : this->vertex_indices())
6475 if (center.distance(this->vertex(v)) >
6476 radius + 100. * std::numeric_limits<double>::epsilon())
6477 {
6478 all_vertices_within_ball = false;
6479 break;
6480 }
6481 // If all the vertices are not within the ball throw error
6482 Assert(all_vertices_within_ball, ExcInternalError());
6483 }
6484 return std::make_pair(center, radius);
6485}
6486
6487
6488template <int structdim, int dim, int spacedim>
6489double
6491{
6492 switch (structdim)
6493 {
6494 case 1:
6495 return (this->vertex(1) - this->vertex(0)).norm();
6496 case 2:
6497 case 3:
6498 {
6499 double min = std::numeric_limits<double>::max();
6500 for (const unsigned int i : this->vertex_indices())
6501 for (unsigned int j = i + 1; j < this->n_vertices(); ++j)
6502 min = std::min(min,
6503 (this->vertex(i) - this->vertex(j)) *
6504 (this->vertex(i) - this->vertex(j)));
6505 return std::sqrt(min);
6506 }
6507 default:
6509 return -1e10;
6510 }
6511}
6512
6513
6514template <int structdim, int dim, int spacedim>
6515bool
6518{
6519 // go through the vertices and check... The
6520 // cell is a translation of the previous
6521 // one in case the distance between the
6522 // individual vertices in the two cell is
6523 // the same for all the vertices. So do the
6524 // check by first getting the distance on
6525 // the first vertex, and then checking
6526 // whether all others have the same down to
6527 // rounding errors (we have to be careful
6528 // here because the calculation of the
6529 // displacement between one cell and the
6530 // next can already result in the loss of
6531 // one or two digits), so we choose 1e-12
6532 // times the distance between the zeroth
6533 // vertices here.
6534 bool is_translation = true;
6535 const Tensor<1, spacedim> dist = o->vertex(0) - this->vertex(0);
6536 const double tol_square = 1e-24 * dist.norm_square();
6537 for (unsigned int i = 1; i < this->n_vertices(); ++i)
6538 {
6539 const Tensor<1, spacedim> dist_new =
6540 (o->vertex(i) - this->vertex(i)) - dist;
6541 if (dist_new.norm_square() > tol_square)
6542 {
6543 is_translation = false;
6544 break;
6545 }
6546 }
6547 return is_translation;
6548}
6549
6550
6551
6552template <int structdim, int dim, int spacedim>
6553unsigned int
6555{
6556 return this->reference_cell().n_vertices();
6557}
6558
6559
6560
6561template <int structdim, int dim, int spacedim>
6562unsigned int
6564{
6565 return this->reference_cell().n_lines();
6566}
6567
6568
6569
6570template <int structdim, int dim, int spacedim>
6571unsigned int
6573{
6574 Assert(structdim == dim,
6575 ExcMessage("This function can only be used on objects "
6576 "that are cells, but not on faces or edges "
6577 "that bound cells."));
6578
6579 return this->reference_cell().n_faces();
6580}
6581
6582
6583
6584template <int structdim, int dim, int spacedim>
6587{
6589 n_vertices());
6590}
6591
6592
6593
6594template <int structdim, int dim, int spacedim>
6597{
6599 n_lines());
6600}
6601
6602
6603
6604template <int structdim, int dim, int spacedim>
6607{
6609 n_faces());
6610}
6611
6612
6613
6614/*----------------- Functions: TriaAccessor<0,dim,spacedim> -----------------*/
6615
6616template <int dim, int spacedim>
6618 const Triangulation<dim, spacedim> *tria,
6619 const unsigned int vertex_index)
6620 : tria(tria)
6621 , global_vertex_index(vertex_index)
6622{}
6623
6624
6625
6626template <int dim, int spacedim>
6628 const Triangulation<dim, spacedim> *tria,
6629 const int /*level*/,
6630 const int index,
6631 const AccessorData *)
6632 : tria(tria)
6634{}
6635
6636
6637
6638template <int dim, int spacedim>
6639template <int structdim2, int dim2, int spacedim2>
6642 : tria(nullptr)
6644{
6645 Assert(false, ExcImpossibleInDim(0));
6646}
6647
6648
6649
6650template <int dim, int spacedim>
6651template <int structdim2, int dim2, int spacedim2>
6654 : tria(nullptr)
6656{
6657 Assert(false, ExcImpossibleInDim(0));
6658}
6659
6660
6661
6662template <int dim, int spacedim>
6663inline void
6665{
6666 tria = t.tria;
6667 global_vertex_index = t.global_vertex_index;
6668}
6669
6670
6671
6672template <int dim, int spacedim>
6673inline bool
6675 const TriaAccessor<0, dim, spacedim> &other) const
6676{
6678
6679 return (global_vertex_index < other.global_vertex_index);
6680}
6681
6682
6683
6684template <int dim, int spacedim>
6687{
6688 if (global_vertex_index != numbers::invalid_unsigned_int)
6689 return IteratorState::valid;
6690 else
6692}
6693
6694
6695
6696template <int dim, int spacedim>
6697inline int
6699{
6700 return 0;
6701}
6702
6703
6704
6705template <int dim, int spacedim>
6706inline int
6708{
6709 return global_vertex_index;
6710}
6711
6712
6713
6714template <int dim, int spacedim>
6715inline const Triangulation<dim, spacedim> &
6717{
6718 return *tria;
6719}
6720
6721
6722
6723template <int dim, int spacedim>
6724inline void
6726{
6728 if (global_vertex_index >= tria->n_vertices())
6730}
6731
6732
6733
6734template <int dim, int spacedim>
6735inline void
6737{
6738 if (global_vertex_index != numbers::invalid_unsigned_int)
6739 {
6740 if (global_vertex_index != 0)
6742 else
6744 }
6745}
6746
6747
6748
6749template <int dim, int spacedim>
6750inline bool
6752{
6753 const bool result =
6754 ((tria == t.tria) && (global_vertex_index == t.global_vertex_index));
6755
6756 return result;
6757}
6758
6759
6760
6761template <int dim, int spacedim>
6762inline bool
6764{
6765 return !(*this == t);
6766}
6767
6768
6769
6770template <int dim, int spacedim>
6771inline unsigned int
6772TriaAccessor<0, dim, spacedim>::vertex_index(const unsigned int) const
6773{
6774 return global_vertex_index;
6775}
6776
6777
6778
6779template <int dim, int spacedim>
6780inline Point<spacedim> &
6781TriaAccessor<0, dim, spacedim>::vertex(const unsigned int) const
6782{
6783 return const_cast<Point<spacedim> &>(
6784 this->tria->vertices[global_vertex_index]);
6785}
6786
6787
6788
6789template <int dim, int spacedim>
6790inline typename ::internal::TriangulationImplementation::
6791 Iterators<dim, spacedim>::line_iterator
6792 TriaAccessor<0, dim, spacedim>::line(const unsigned int)
6793{
6794 return typename ::internal::TriangulationImplementation::
6795 Iterators<dim, spacedim>::line_iterator();
6796}
6797
6798
6799
6800template <int dim, int spacedim>
6801inline unsigned int
6803{
6804 Assert(false, ExcImpossibleInDim(0));
6806}
6807
6808
6809
6810template <int dim, int spacedim>
6811inline typename ::internal::TriangulationImplementation::
6812 Iterators<dim, spacedim>::quad_iterator
6813 TriaAccessor<0, dim, spacedim>::quad(const unsigned int)
6814{
6815 return typename ::internal::TriangulationImplementation::
6816 Iterators<dim, spacedim>::quad_iterator();
6817}
6818
6819
6820
6821template <int dim, int spacedim>
6822inline unsigned int
6824{
6825 Assert(false, ExcImpossibleInDim(0));
6827}
6828
6829
6830
6831template <int dim, int spacedim>
6832inline double
6834{
6835 return 0.;
6836}
6837
6838
6839
6840template <int dim, int spacedim>
6841inline double
6843{
6844 return 0.;
6845}
6846
6847
6848
6849template <int dim, int spacedim>
6850inline Point<spacedim>
6851TriaAccessor<0, dim, spacedim>::center(const bool, const bool) const
6852{
6853 return this->tria->vertices[global_vertex_index];
6854}
6855
6856
6857
6858template <int dim, int spacedim>
6859inline double
6861{
6862 return 0.;
6863}
6864
6865
6866
6867template <int dim, int spacedim>
6870 const unsigned int /*face*/)
6871{
6873}
6874
6875
6876
6877template <int dim, int spacedim>
6878inline bool
6879TriaAccessor<0, dim, spacedim>::face_orientation(const unsigned int /*face*/)
6880{
6881 return false;
6882}
6883
6884
6885
6886template <int dim, int spacedim>
6887inline bool
6888TriaAccessor<0, dim, spacedim>::face_flip(const unsigned int /*face*/)
6889{
6890 return false;
6891}
6892
6893
6894
6895template <int dim, int spacedim>
6896inline bool
6897TriaAccessor<0, dim, spacedim>::face_rotation(const unsigned int /*face*/)
6898{
6899 return false;
6900}
6901
6902
6903
6904template <int dim, int spacedim>
6906TriaAccessor<0, dim, spacedim>::line_orientation(const unsigned int /*line*/)
6907{
6909}
6910
6911
6912
6913template <int dim, int spacedim>
6914inline bool
6916{
6917 return false;
6918}
6919
6920
6921
6922template <int dim, int spacedim>
6923inline unsigned int
6925{
6926 return 0;
6927}
6928
6929
6930
6931template <int dim, int spacedim>
6932inline unsigned int
6934{
6935 return 0;
6936}
6937
6938
6939
6940template <int dim, int spacedim>
6941inline unsigned int
6943{
6944 return 0;
6945}
6946
6947
6948
6949template <int dim, int spacedim>
6950inline unsigned int
6953{
6955}
6956
6957
6958
6959template <int dim, int spacedim>
6961TriaAccessor<0, dim, spacedim>::child(const unsigned int)
6962{
6964}
6965
6966
6967
6968template <int dim, int spacedim>
6971{
6973}
6974
6975
6976
6977template <int dim, int spacedim>
6978inline RefinementCase<0>
6980{
6982}
6983
6984
6985
6986template <int dim, int spacedim>
6987inline int
6989{
6990 return -1;
6991}
6992
6993
6994
6995template <int dim, int spacedim>
6996inline int
6998{
6999 return -1;
7000}
7001
7002
7003
7004template <int dim, int spacedim>
7005inline bool
7007{
7008 return tria->vertex_used(global_vertex_index);
7009}
7010
7011
7012
7013/*------------------- Functions: TriaAccessor<0,1,spacedim> -----------------*/
7014
7015template <int spacedim>
7017 const Triangulation<1, spacedim> *tria,
7018 const VertexKind vertex_kind,
7019 const unsigned int vertex_index)
7020 : tria(tria)
7021 , vertex_kind(vertex_kind)
7022 , global_vertex_index(vertex_index)
7023{}
7024
7025
7026
7027template <int spacedim>
7029 const Triangulation<1, spacedim> *tria,
7030 const int level,
7031 const int index,
7032 const AccessorData *)
7033 : tria(tria)
7034 , vertex_kind(interior_vertex)
7036{
7037 // in general, calling this constructor should yield an error -- users should
7038 // instead call the one immediately above. however, if you create something
7039 // like Triangulation<1>::face_iterator() then this calls the default
7040 // constructor of the iterator which calls the accessor with argument list
7041 // (0,-2,-2,0), so in this particular case accept this call and create an
7042 // object that corresponds to the default constructed (invalid) vertex
7043 // accessor
7044 (void)level;
7045 (void)index;
7046 Assert((level == -2) && (index == -2),
7047 ExcMessage(
7048 "This constructor can not be called for face iterators in 1d, "
7049 "except to default-construct iterator objects."));
7050}
7051
7052
7053
7054template <int spacedim>
7055template <int structdim2, int dim2, int spacedim2>
7058 : tria(nullptr)
7059 , vertex_kind(interior_vertex)
7061{
7062 Assert(false, ExcImpossibleInDim(0));
7063}
7064
7065
7066
7067template <int spacedim>
7068template <int structdim2, int dim2, int spacedim2>
7071 : tria(nullptr)
7072 , vertex_kind(interior_vertex)
7074{
7075 Assert(false, ExcImpossibleInDim(0));
7076}
7077
7078
7079
7080template <int spacedim>
7081inline void
7083{
7084 tria = t.tria;
7085 vertex_kind = t.vertex_kind;
7086 global_vertex_index = t.global_vertex_index;
7087}
7088
7089
7090
7091template <int spacedim>
7092inline void
7095{
7096 // We cannot convert from TriaAccessorBase to
7097 // TriaAccessor<0,1,spacedim> because the latter is not derived from
7098 // the former. We should never get here.
7100}
7101
7102
7103
7104template <int spacedim>
7105inline bool
7107 const TriaAccessor<0, 1, spacedim> &other) const
7108{
7110
7111 return (global_vertex_index < other.global_vertex_index);
7112}
7113
7114
7115
7116template <int spacedim>
7119{
7120 return IteratorState::valid;
7121}
7122
7123
7124template <int spacedim>
7125inline int
7127{
7128 return 0;
7129}
7130
7131
7132
7133template <int spacedim>
7134inline int
7136{
7137 return global_vertex_index;
7138}
7139
7140
7141
7142template <int spacedim>
7143inline const Triangulation<1, spacedim> &
7145{
7146 return *tria;
7147}
7148
7149
7150
7151template <int spacedim>
7152inline void
7154{
7156}
7157
7158
7159template <int spacedim>
7160inline void
7162{
7164}
7165
7166
7167
7168template <int spacedim>
7169inline bool
7171{
7172 const bool result =
7173 ((tria == t.tria) && (global_vertex_index == t.global_vertex_index));
7174 // if we point to the same vertex,
7175 // make sure we know the same about
7176 // it
7177 if (result == true)
7178 Assert(vertex_kind == t.vertex_kind, ExcInternalError());
7179
7180 return result;
7181}
7182
7183
7184
7185template <int spacedim>
7186inline bool
7188{
7189 return !(*this == t);
7190}
7191
7192
7193
7194template <int spacedim>
7195inline unsigned int
7196TriaAccessor<0, 1, spacedim>::vertex_index(const unsigned int i) const
7197{
7198 AssertIndexRange(i, 1);
7199 (void)i;
7200 return global_vertex_index;
7201}
7202
7203
7204
7205template <int spacedim>
7206inline Point<spacedim> &
7207TriaAccessor<0, 1, spacedim>::vertex(const unsigned int i) const
7208{
7209 AssertIndexRange(i, 1);
7210 (void)i;
7211 return const_cast<Point<spacedim> &>(
7212 this->tria->vertices[global_vertex_index]);
7213}
7214
7215
7216
7217template <int spacedim>
7218inline Point<spacedim>
7220{
7221 return this->tria->vertices[global_vertex_index];
7222}
7223
7224
7225
7226template <int spacedim>
7227inline typename ::internal::TriangulationImplementation::
7228 Iterators<1, spacedim>::line_iterator
7229 TriaAccessor<0, 1, spacedim>::line(const unsigned int)
7230{
7231 return {};
7232}
7233
7234
7235template <int spacedim>
7236inline unsigned int
7238{
7239 Assert(false, ExcImpossibleInDim(0));
7241}
7242
7243
7244template <int spacedim>
7245inline typename ::internal::TriangulationImplementation::
7246 Iterators<1, spacedim>::quad_iterator
7247 TriaAccessor<0, 1, spacedim>::quad(const unsigned int)
7248{
7249 return {};
7250}
7251
7252
7253
7254template <int spacedim>
7255inline unsigned int
7257{
7258 Assert(false, ExcImpossibleInDim(0));
7260}
7261
7262
7263template <int spacedim>
7264inline bool
7266{
7267 return vertex_kind != interior_vertex;
7268}
7269
7270
7271template <int spacedim>
7272inline types::boundary_id
7274{
7275 switch (vertex_kind)
7276 {
7277 case left_vertex:
7278 case right_vertex:
7279 {
7281 this->vertex_index()) !=
7282 tria->vertex_to_boundary_id_map_1d->end(),
7284
7285 return (*tria->vertex_to_boundary_id_map_1d)[this->vertex_index()];
7286 }
7287
7288 default:
7290 }
7291}
7292
7293
7294
7295template <int spacedim>
7296inline const Manifold<1, spacedim> &
7298{
7299 return this->tria->get_manifold(this->manifold_id());
7300}
7301
7302
7303
7304template <int spacedim>
7305inline types::manifold_id
7307{
7308 if (tria->vertex_to_manifold_id_map_1d->find(this->vertex_index()) !=
7309 tria->vertex_to_manifold_id_map_1d->end())
7310 return (*tria->vertex_to_manifold_id_map_1d)[this->vertex_index()];
7311 else
7313}
7314
7315
7316template <int spacedim>
7319 const unsigned int /*face*/)
7320{
7322}
7323
7324
7325template <int spacedim>
7326inline bool
7327TriaAccessor<0, 1, spacedim>::face_orientation(const unsigned int /*face*/)
7328{
7329 return false;
7330}
7331
7332
7333
7334template <int spacedim>
7335inline bool
7336TriaAccessor<0, 1, spacedim>::face_flip(const unsigned int /*face*/)
7337{
7338 return false;
7339}
7340
7341
7342
7343template <int spacedim>
7344inline bool
7345TriaAccessor<0, 1, spacedim>::face_rotation(const unsigned int /*face*/)
7346{
7347 return false;
7348}
7349
7350
7351
7352template <int spacedim>
7354TriaAccessor<0, 1, spacedim>::line_orientation(const unsigned int /*line*/)
7355{
7357}
7358
7359
7360
7361template <int spacedim>
7362inline bool
7364{
7365 return false;
7366}
7367
7368
7369
7370template <int spacedim>
7371inline unsigned int
7373{
7374 return 0;
7375}
7376
7377
7378
7379template <int spacedim>
7380inline unsigned int
7382{
7383 return 0;
7384}
7385
7386
7387
7388template <int spacedim>
7389inline unsigned int
7391{
7392 return 0;
7393}
7394
7395
7396
7397template <int spacedim>
7398inline unsigned int
7401{
7403}
7404
7405
7406
7407template <int spacedim>
7409TriaAccessor<0, 1, spacedim>::child(const unsigned int)
7410{
7412}
7413
7414
7415template <int spacedim>
7418{
7420}
7421
7422
7423template <int spacedim>
7424inline RefinementCase<0>
7426{
7428}
7429
7430template <int spacedim>
7431inline int
7433{
7434 return -1;
7435}
7436
7437
7438template <int spacedim>
7439inline int
7441{
7442 return -1;
7443}
7444
7445
7446
7447template <int spacedim>
7448inline void
7450{
7451 Assert(tria->vertex_to_boundary_id_map_1d->find(this->vertex_index()) !=
7452 tria->vertex_to_boundary_id_map_1d->end(),
7453 ExcMessage("You can't set the boundary_id of a face of a cell that is "
7454 "not actually at the boundary."));
7455
7456 (*tria->vertex_to_boundary_id_map_1d)[this->vertex_index()] = b;
7457}
7458
7459
7460
7461template <int spacedim>
7462inline void
7464{
7465 (*tria->vertex_to_manifold_id_map_1d)[this->vertex_index()] = b;
7466}
7467
7468
7469
7470template <int spacedim>
7471inline void
7473 const types::boundary_id b) const
7474{
7475 set_boundary_id(b);
7476}
7477
7478
7479
7480template <int spacedim>
7481inline void
7483{
7484 set_manifold_id(b);
7485}
7486
7487
7488
7489template <int spacedim>
7490inline bool
7492{
7493 return tria->vertex_used(global_vertex_index);
7494}
7495
7496
7497
7498template <int spacedim>
7499inline ReferenceCell
7501{
7503}
7504
7505
7506
7507template <int spacedim>
7508unsigned int
7510{
7511 return 1;
7512}
7513
7514
7515
7516template <int spacedim>
7517unsigned int
7519{
7520 return 0;
7521}
7522
7523
7524
7525template <int spacedim>
7528{
7530 n_vertices());
7531}
7532
7533
7534
7535template <int spacedim>
7538{
7540 n_lines());
7541}
7542
7543/*------------------ Functions: CellAccessor<dim,spacedim> ------------------*/
7544
7545
7546template <int dim, int spacedim>
7548 const Triangulation<dim, spacedim> *parent,
7549 const int level,
7550 const int index,
7551 const AccessorData *local_data)
7552 : TriaAccessor<dim, dim, spacedim>(parent, level, index, local_data)
7553{}
7554
7555
7556
7557template <int dim, int spacedim>
7559 const TriaAccessor<dim, dim, spacedim> &cell_accessor)
7560 : TriaAccessor<dim, dim, spacedim>(
7561 static_cast<const TriaAccessor<dim, dim, spacedim> &>(cell_accessor))
7562{}
7563
7564
7565
7566template <int dim, int spacedim>
7568CellAccessor<dim, spacedim>::child(const unsigned int i) const
7569{
7571 this->present_level + 1,
7572 this->child_index(i));
7573
7574 Assert((q.state() == IteratorState::past_the_end) || q->used(),
7576
7577 return q;
7578}
7579
7580
7581
7582template <int dim, int spacedim>
7583inline boost::container::small_vector<TriaIterator<CellAccessor<dim, spacedim>>,
7586{
7587 boost::container::small_vector<TriaIterator<CellAccessor<dim, spacedim>>,
7589 child_iterators(this->n_children());
7590
7591 for (unsigned int i = 0; i < this->n_children(); ++i)
7592 child_iterators[i] = this->child(i);
7593
7594 return child_iterators;
7595}
7596
7597
7598
7599template <int dim, int spacedim>
7600inline TriaIterator<TriaAccessor<dim - 1, dim, spacedim>>
7601CellAccessor<dim, spacedim>::face(const unsigned int i) const
7602{
7603 AssertIndexRange(i, this->n_faces());
7604 if constexpr (dim == 1)
7605 {
7606 using VertexKind = typename TriaAccessor<0, 1, spacedim>::VertexKind;
7607 VertexKind vertex_kind = VertexKind::interior_vertex;
7608 if (i == 0 && at_boundary(0))
7609 vertex_kind = VertexKind::left_vertex;
7610 if (i == 1 && at_boundary(1))
7611 vertex_kind = VertexKind::right_vertex;
7612 TriaAccessor<0, 1, spacedim> a(&this->get_triangulation(),
7613 vertex_kind,
7614 this->vertex_index(i));
7616 }
7617 else if constexpr (dim == 2)
7618 return this->line(i);
7619 else if constexpr (dim == 3)
7620 return this->quad(i);
7621 else
7622 {
7623 Assert(false, ExcNotImplemented());
7624 return {};
7625 }
7626}
7627
7628
7629
7630template <int dim, int spacedim>
7631inline unsigned int
7634{
7635 for (const unsigned int face_n : this->face_indices())
7636 if (this->face(face_n) == face)
7637 return face_n;
7638
7639 Assert(false,
7640 ExcMessage("The given face is not a face of the current cell."));
7642}
7643
7644
7645
7646template <int dim, int spacedim>
7647inline boost::container::small_vector<
7648 TriaIterator<TriaAccessor<dim - 1, dim, spacedim>>,
7649# ifndef _MSC_VER
7650 ReferenceCells::max_n_faces<dim>()
7651# else
7653# endif
7654 >
7656{
7657 boost::container::small_vector<
7658 TriaIterator<TriaAccessor<dim - 1, dim, spacedim>>,
7659# ifndef _MSC_VER
7660 ReferenceCells::max_n_faces<dim>()
7661# else
7663# endif
7664 >
7665 face_iterators(this->n_faces());
7666
7667 for (const unsigned int i : this->face_indices())
7668 face_iterators[i] = this->face(i);
7669
7670 return face_iterators;
7671}
7672
7673
7674
7675template <int dim, int spacedim>
7676inline unsigned int
7677CellAccessor<dim, spacedim>::face_index(const unsigned int i) const
7678{
7679 switch (dim)
7680 {
7681 case 1:
7682 return this->vertex_index(i);
7683
7684 case 2:
7685 return this->line_index(i);
7686
7687 case 3:
7688 return this->quad_index(i);
7689
7690 default:
7692 }
7693}
7694
7695
7696
7697template <int dim, int spacedim>
7698inline int
7699CellAccessor<dim, spacedim>::neighbor_index(const unsigned int face_no) const
7700{
7701 AssertIndexRange(face_no, this->n_faces());
7702 return this->tria->levels[this->present_level]
7703 ->neighbors[this->present_index * ReferenceCells::max_n_faces<dim>() +
7704 face_no]
7705 .second;
7706}
7707
7708
7709
7710template <int dim, int spacedim>
7711inline int
7712CellAccessor<dim, spacedim>::neighbor_level(const unsigned int face_no) const
7713{
7714 AssertIndexRange(face_no, this->n_faces());
7715 return this->tria->levels[this->present_level]
7716 ->neighbors[this->present_index * ReferenceCells::max_n_faces<dim>() +
7717 face_no]
7718 .first;
7719}
7720
7721
7722
7723template <int dim, int spacedim>
7726{
7728 // cells flagged for refinement must be active
7729 // (the @p set_refine_flag function checks this,
7730 // but activity may change when refinement is
7731 // executed and for some reason the refine
7732 // flag is not cleared).
7733 Assert(this->is_active() || !this->tria->levels[this->present_level]
7734 ->refine_flags[this->present_index],
7735 ExcRefineCellNotActive());
7736 return RefinementCase<dim>(
7737 this->tria->levels[this->present_level]->refine_flags[this->present_index]);
7738}
7739
7740
7741
7742template <int dim, int spacedim>
7743inline void
7745 const RefinementCase<dim> refinement_case) const
7746{
7747 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
7748 Assert(!coarsen_flag_set(), ExcCellFlaggedForCoarsening());
7749
7750 this->tria->levels[this->present_level]->refine_flags[this->present_index] =
7751 refinement_case;
7752}
7753
7754
7755
7756template <int dim, int spacedim>
7757inline void
7759{
7760 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
7761 this->tria->levels[this->present_level]->refine_flags[this->present_index] =
7763}
7764
7765
7766template <int dim, int spacedim>
7767inline std::uint8_t
7769{
7771 if (this->tria->levels[this->present_level]->refine_choice.size() == 0)
7772 return 0U;
7773 return this->tria->levels[this->present_level]
7774 ->refine_choice[this->present_index];
7775}
7776
7777
7778template <int dim, int spacedim>
7779inline void
7781 const std::uint8_t refinement_choice) const
7782{
7783 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
7784 if (this->tria->levels[this->present_level]->refine_choice.size() != 0)
7785 this->tria->levels[this->present_level]
7786 ->refine_choice[this->present_index] = refinement_choice;
7787}
7788
7789
7790template <int dim, int spacedim>
7791inline void
7793{
7794 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
7795 if (this->tria->levels[this->present_level]->refine_choice.size() != 0)
7796 this->tria->levels[this->present_level]
7797 ->refine_choice[this->present_index] =
7799}
7800
7801
7802template <int dim, int spacedim>
7803inline bool
7805 const unsigned int face_no,
7806 const RefinementCase<dim - 1> &face_refinement_case) const
7807{
7808 Assert(dim > 1, ExcImpossibleInDim(dim));
7809 AssertIndexRange(face_no, this->n_faces());
7810 AssertIndexRange(face_refinement_case,
7812
7813 // the new refinement case is a combination
7814 // of the minimum required one for the given
7815 // face refinement and the already existing
7816 // flagged refinement case
7817 RefinementCase<dim> old_ref_case = refine_flag_set();
7818 RefinementCase<dim> new_ref_case =
7819 (old_ref_case |
7821 face_refinement_case,
7822 face_no,
7823 this->face_orientation(face_no),
7824 this->face_flip(face_no),
7825 this->face_rotation(face_no)));
7826 set_refine_flag(new_ref_case);
7827 // return, whether we had to change the
7828 // refinement flag
7829 return new_ref_case != old_ref_case;
7830}
7831
7832
7833
7834template <int dim, int spacedim>
7835inline bool
7837 const unsigned int line_no) const
7838{
7839 Assert(dim > 1, ExcImpossibleInDim(dim));
7840 AssertIndexRange(line_no, this->n_lines());
7841
7842 // the new refinement case is a combination
7843 // of the minimum required one for the given
7844 // line refinement and the already existing
7845 // flagged refinement case
7847 old_ref_case = refine_flag_set(),
7848 new_ref_case =
7849 old_ref_case |
7851 set_refine_flag(new_ref_case);
7852 // return, whether we had to change the
7853 // refinement flag
7854 return new_ref_case != old_ref_case;
7855}
7856
7857
7858
7859template <int dim, int spacedim>
7860inline ::internal::SubfaceCase<dim>
7861CellAccessor<dim, spacedim>::subface_case(const unsigned int face_no) const
7862{
7864 AssertIndexRange(face_no, this->n_faces());
7865
7866 if constexpr (dim == 1)
7867 return ::internal::SubfaceCase<1>::case_none;
7868 else if constexpr (dim == 2)
7869 return ((face(face_no)->has_children()) ?
7871 ::internal::SubfaceCase<2>::case_none);
7872 else if constexpr (dim == 3)
7873 {
7874 switch (static_cast<std::uint8_t>(face(face_no)->refinement_case()))
7875 {
7877 return ::internal::SubfaceCase<3>::case_none;
7879 if (face(face_no)->child(0)->has_children())
7880 {
7881 Assert(face(face_no)->child(0)->refinement_case() ==
7884 if (face(face_no)->child(1)->has_children())
7885 {
7886 Assert(face(face_no)->child(1)->refinement_case() ==
7889 return ::internal::SubfaceCase<3>::case_x1y2y;
7890 }
7891 else
7892 return ::internal::SubfaceCase<3>::case_x1y;
7893 }
7894 else
7895 {
7896 if (face(face_no)->child(1)->has_children())
7897 {
7898 Assert(face(face_no)->child(1)->refinement_case() ==
7901 return ::internal::SubfaceCase<3>::case_x2y;
7902 }
7903 else
7904 return ::internal::SubfaceCase<3>::case_x;
7905 }
7907 if (face(face_no)->child(0)->has_children())
7908 {
7909 Assert(face(face_no)->child(0)->refinement_case() ==
7912 if (face(face_no)->child(1)->has_children())
7913 {
7914 Assert(face(face_no)->child(1)->refinement_case() ==
7917 return ::internal::SubfaceCase<3>::case_y1x2x;
7918 }
7919 else
7920 return ::internal::SubfaceCase<3>::case_y1x;
7921 }
7922 else
7923 {
7924 if (face(face_no)->child(1)->has_children())
7925 {
7926 Assert(face(face_no)->child(1)->refinement_case() ==
7929 return ::internal::SubfaceCase<3>::case_y2x;
7930 }
7931 else
7932 return ::internal::SubfaceCase<3>::case_y;
7933 }
7935 return ::internal::SubfaceCase<3>::case_xy;
7936 default:
7938 }
7939 }
7940
7941 // we should never get here
7943 return ::internal::SubfaceCase<dim>::case_none;
7944}
7945
7946
7947
7948template <int dim, int spacedim>
7949inline bool
7951{
7953 // cells flagged for coarsening must be active
7954 // (the @p set_refine_flag function checks this,
7955 // but activity may change when refinement is
7956 // executed and for some reason the refine
7957 // flag is not cleared).
7958 Assert(this->is_active() || !this->tria->levels[this->present_level]
7959 ->coarsen_flags[this->present_index],
7960 ExcRefineCellNotActive());
7961 return this->tria->levels[this->present_level]
7962 ->coarsen_flags[this->present_index];
7963}
7964
7965
7966
7967template <int dim, int spacedim>
7968inline void
7970{
7971 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
7972 Assert(!refine_flag_set(), ExcCellFlaggedForRefinement());
7973
7974 this->tria->levels[this->present_level]->coarsen_flags[this->present_index] =
7975 true;
7976}
7977
7978
7979
7980template <int dim, int spacedim>
7981inline void
7983{
7984 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
7985 this->tria->levels[this->present_level]->coarsen_flags[this->present_index] =
7986 false;
7987}
7988
7989
7990
7991template <int dim, int spacedim>
7993CellAccessor<dim, spacedim>::neighbor(const unsigned int face_no) const
7994{
7996 neighbor_level(face_no),
7997 neighbor_index(face_no));
7998
7999 Assert((q.state() == IteratorState::past_the_end) || q->used(),
8001
8002 return q;
8003}
8004
8005
8006
8007template <int dim, int spacedim>
8008inline bool
8010{
8011 return !this->has_children();
8012}
8013
8014
8015
8016template <int dim, int spacedim>
8017inline bool
8019{
8020 Assert(this->is_active(),
8021 ExcMessage("is_locally_owned() can only be called on active cells!"));
8022# ifndef DEAL_II_WITH_MPI
8023 return true;
8024# else
8025
8026 // Serial triangulations report invalid_subdomain_id as their locally owned
8027 // subdomain, so the first condition checks whether we have a serial
8028 // triangulation, in which case all cells are locally owned. The second
8029 // condition compares the subdomain id in the parallel case.
8030 const types::subdomain_id locally_owned_subdomain =
8031 this->tria->locally_owned_subdomain();
8032 return (locally_owned_subdomain == numbers::invalid_subdomain_id ||
8033 this->subdomain_id() == locally_owned_subdomain);
8034
8035# endif
8036}
8037
8038
8039template <int dim, int spacedim>
8040inline bool
8042{
8043# ifndef DEAL_II_WITH_MPI
8044 return true;
8045# else
8046
8047 // Serial triangulations report invalid_subdomain_id as their locally owned
8048 // subdomain, so the first condition checks whether we have a serial
8049 // triangulation, in which case all cells are locally owned. The second
8050 // condition compares the subdomain id in the parallel case.
8051 const types::subdomain_id locally_owned_subdomain =
8052 this->tria->locally_owned_subdomain();
8053 return (locally_owned_subdomain == numbers::invalid_subdomain_id ||
8054 this->level_subdomain_id() == locally_owned_subdomain);
8055
8056# endif
8057}
8058
8059
8060template <int dim, int spacedim>
8061inline bool
8063{
8064 Assert(this->is_active(),
8065 ExcMessage("is_ghost() can only be called on active cells!"));
8066 if (this->has_children())
8067 return false;
8068
8069# ifndef DEAL_II_WITH_MPI
8070 return false;
8071# else
8072
8073 // Serial triangulations report invalid_subdomain_id as their locally owned
8074 // subdomain, so the first condition rules out that case as all cells to a
8075 // serial triangulation are locally owned and none is ghosted. The second
8076 // and third conditions check whether the cell's subdomain is not the
8077 // locally owned one and not artificial.
8078 const types::subdomain_id locally_owned_subdomain =
8079 this->tria->locally_owned_subdomain();
8080 const types::subdomain_id subdomain_id = this->subdomain_id();
8081 return (locally_owned_subdomain != numbers::invalid_subdomain_id &&
8082 subdomain_id != locally_owned_subdomain &&
8083 subdomain_id != numbers::artificial_subdomain_id);
8084
8085# endif
8086}
8087
8088
8089template <int dim, int spacedim>
8090inline bool
8092{
8093# ifndef DEAL_II_WITH_MPI
8094 return false;
8095# else
8096
8097 // Serial triangulations report invalid_subdomain_id as their locally owned
8098 // subdomain, so the first condition checks whether we have a serial
8099 // triangulation, in which case all cells are locally owned. The second
8100 // condition compares the subdomain id in the parallel case.
8101 const types::subdomain_id locally_owned_subdomain =
8102 this->tria->locally_owned_subdomain();
8103 const types::subdomain_id subdomain_id = this->level_subdomain_id();
8104 return (locally_owned_subdomain != numbers::invalid_subdomain_id &&
8105 subdomain_id != locally_owned_subdomain &&
8106 subdomain_id != numbers::artificial_subdomain_id);
8107
8108# endif
8109}
8110
8111
8112
8113template <int dim, int spacedim>
8114inline bool
8116{
8117 Assert(this->is_active(),
8118 ExcMessage("is_artificial() can only be called on active cells!"));
8119# ifndef DEAL_II_WITH_MPI
8120 return false;
8121# else
8122
8123 // Serial triangulations report invalid_subdomain_id as their locally owned
8124 // subdomain, so the first condition rules out that case as all cells to a
8125 // serial triangulation are locally owned and none is artificial.
8126 return (this->tria->locally_owned_subdomain() !=
8128 this->subdomain_id() == numbers::artificial_subdomain_id);
8129
8130# endif
8131}
8132
8133
8134
8135template <int dim, int spacedim>
8136inline bool
8138{
8139# ifndef DEAL_II_WITH_MPI
8140 return false;
8141# else
8142 return (this->tria->locally_owned_subdomain() !=
8144 this->level_subdomain_id() == numbers::artificial_subdomain_id);
8145# endif
8146}
8147
8148
8149
8150template <int dim, int spacedim>
8153{
8155 Assert(this->is_active(),
8156 ExcMessage("subdomain_id() can only be called on active cells!"));
8157 return this->tria->levels[this->present_level]
8158 ->subdomain_ids[this->present_index];
8159}
8160
8161
8162
8163template <int dim, int spacedim>
8166{
8168 return this->tria->levels[this->present_level]
8169 ->level_subdomain_ids[this->present_index];
8170}
8171
8172
8173
8174template <int dim, int spacedim>
8175inline unsigned int
8176CellAccessor<dim, spacedim>::neighbor_face_no(const unsigned int neighbor) const
8177{
8178 const unsigned int n2 = neighbor_of_neighbor_internal(neighbor);
8180 // return this value as the
8181 // neighbor is not coarser
8182 return n2;
8183 else
8184 // the neighbor is coarser
8185 return neighbor_of_coarser_neighbor(neighbor).first;
8186}
8187
8188
8189
8190template <int dim, int spacedim>
8191inline bool
8193{
8194 return false;
8195}
8196
8197
8198
8199template <int dim, int spacedim>
8200inline unsigned int
8202{
8204 return this->tria->levels[this->present_level]
8205 ->active_cell_indices[this->present_index];
8206}
8207
8208
8209
8210template <int dim, int spacedim>
8213{
8215 Assert(this->is_active(),
8216 ExcMessage(
8217 "global_active_cell_index() can only be called on active cells!"));
8218
8219 return this->tria->levels[this->present_level]
8220 ->global_active_cell_indices[this->present_index];
8221}
8222
8223
8224
8225template <int dim, int spacedim>
8228{
8229 return this->tria->levels[this->present_level]
8230 ->global_level_cell_indices[this->present_index];
8231}
8232
8233#endif // DOXYGEN
8234
8236
8237
8238#endif
void recursively_set_subdomain_id(const types::subdomain_id new_subdomain_id) const
CellAccessor(const Triangulation< dim, spacedim > *parent=nullptr, const int level=-1, const int index=-1, const AccessorData *local_data=nullptr)
TriaIterator< CellAccessor< dim, spacedim > > parent() const
unsigned int neighbor_face_no(const unsigned int neighbor) const
void set_active_cell_index(const unsigned int active_cell_index) const
unsigned int neighbor_of_neighbor_internal(const unsigned int neighbor) const
TriaIterator< CellAccessor< dim, spacedim > > periodic_neighbor(const unsigned int i) const
types::global_cell_index global_active_cell_index() const
void set_neighbor(const unsigned int i, const TriaIterator< CellAccessor< dim, spacedim > > &pointer) const
TriaIterator< CellAccessor< dim, spacedim > > neighbor(const unsigned int face_no) const
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
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
void set_refine_choice(const std::uint8_t refinement_choice=static_cast< char >(IsotropicRefinementChoice::isotropic_refinement)) const
boost::container::small_vector< TriaIterator< CellAccessor< dim, spacedim > >, GeometryInfo< dim >::max_children_per_cell > child_iterators() const
void set_parent(const unsigned int parent_index)
std::pair< unsigned int, unsigned int > periodic_neighbor_of_coarser_periodic_neighbor(const unsigned face_no) const
CellAccessor(const TriaAccessor< dim, dim, spacedim > &cell_accessor)
bool at_boundary() const
unsigned int active_cell_index() const
static bool is_level_cell()
void clear_refine_flag() const
int neighbor_index(const unsigned int face_no) const
bool point_inside(const Point< spacedim > &p) const
types::subdomain_id subdomain_id() const
bool direction_flag() const
types::material_id material_id() const
bool coarsen_flag_set() const
types::global_cell_index global_level_cell_index() const
bool flag_for_line_refinement(const unsigned int line_no) const
CellId id() const
::internal::SubfaceCase< dim > subface_case(const unsigned int face_no) 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:320
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:113
numbers::NumberTraits< Number >::real_type distance(const Point< dim, Number > &p) const
unsigned int n_vertices() const
unsigned int standard_to_real_face_vertex(const unsigned int vertex, const unsigned int face, const types::geometric_orientation face_orientation) const
std::array< unsigned int, 2 > standard_vertex_to_face_and_vertex_index(const unsigned int vertex) const
std::array< unsigned int, 2 > standard_line_to_face_and_line_index(const unsigned int line) const
unsigned int n_face_orientations(const unsigned int face_no) const
unsigned int n_faces() const
unsigned int n_lines() const
static ReferenceCell n_vertices_to_type(const int dim, const unsigned int n_vertices)
unsigned int standard_to_real_face_line(const unsigned int line, const unsigned int face, const types::geometric_orientation face_orientation) const
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
typename::internal::TriaAccessorImplementation::PresentLevelType< structdim, dim >::type present_level
::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()
ReferenceCell reference_cell() const
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 > &)
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
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
ReferenceCell reference_cell() 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:4572
std::vector< Point< spacedim > > vertices
Definition tria.h:4498
virtual types::subdomain_id locally_owned_subdomain() const
std::unique_ptr< std::map< unsigned int, types::boundary_id > > vertex_to_boundary_id_map_1d
Definition tria.h:4549
std::unique_ptr<::internal::TriangulationImplementation::TriaFaces > faces
Definition tria.h:4492
bool vertex_used(const unsigned int index) const
unsigned int n_vertices() const
std::vector< std::unique_ptr<::internal::TriangulationImplementation::TriaLevel > > levels
Definition tria.h:4484
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:35
constexpr bool running_in_debug_mode()
Definition config.h:73
#define DEAL_II_CXX20_REQUIRES(condition)
Definition config.h:243
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:36
#define DEAL_II_ASSERT_UNREACHABLE()
#define DEAL_II_NOT_IMPLEMENTED()
unsigned int level
Definition grid_out.cc:4635
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.
static types::geometric_orientation combined_face_orientation(const unsigned int face)
Always return 0.
static bool face_rotation(const unsigned int face)
Always return false.
types::geometric_orientation line_orientation(const unsigned int line) const
static bool face_rotation(const unsigned int face)
Always return false.
void set_combined_face_orientation(const unsigned int face, const types::geometric_orientation combined_orientation) const
static types::geometric_orientation line_orientation(const unsigned int line)
Always return numbers::reverse_line_orientation.
static bool face_orientation(const unsigned int face)
Always return false.
bool face_flip(const unsigned int face) const
static types::geometric_orientation combined_face_orientation(const unsigned int face)
Always return 0.
void reference_cell(Triangulation< dim, spacedim > &tria, const ReferenceCell &reference_cell)
@ past_the_end
Iterator reached end of container.
@ valid
Iterator points to a valid object.
@ invalid
Iterator is invalid, probably due to an error.
constexpr char U
double norm(const FEValuesBase< dim > &fe, const ArrayView< const std::vector< Tensor< 1, dim > > > &Du)
Definition divergence.h:471
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
Tensor< 2, dim, Number > l(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
SymmetricTensor< 2, dim, Number > b(const Tensor< 2, dim, Number > &F)
SymmetricTensor< 2, dim, Number > epsilon(const Tensor< 2, dim, Number > &Grad_u)
constexpr ReferenceCell Triangle
constexpr ReferenceCell Hexahedron
constexpr ReferenceCell Pyramid
constexpr ReferenceCell Wedge
constexpr ReferenceCell Vertex
constexpr ReferenceCell Quadrilateral
constexpr ReferenceCell Tetrahedron
constexpr ReferenceCell Line
T sum(const T &t, const MPI_Comm mpi_communicator)
types::geometric_orientation combined_face_orientation(const bool face_orientation, const bool face_rotation, const bool face_flip)
constexpr unsigned int invalid_unsigned_int
Definition types.h:238
constexpr types::boundary_id internal_face_boundary_id
Definition types.h:329
constexpr types::manifold_id flat_manifold_id
Definition types.h:342
constexpr types::subdomain_id artificial_subdomain_id
Definition types.h:402
constexpr types::geometric_orientation reverse_line_orientation
Definition types.h:365
constexpr types::subdomain_id invalid_subdomain_id
Definition types.h:381
constexpr types::geometric_orientation default_geometric_orientation
Definition types.h:352
boost::integer_range< IncrementableType > iota_view
Definition iota_view.h:45
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:173
std::uint64_t global_vertex_index
Definition types.h:57
unsigned int subdomain_id
Definition types.h:52
unsigned char geometric_orientation
Definition types.h:40
unsigned int boundary_id
Definition types.h:161
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)
static unsigned int n_children(const RefinementCase< dim > &refinement_case)