deal.II version GIT relicensing-2287-g6548a49e0a 2024-12-20 18:30: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
29#include <deal.II/grid/tria.h>
32#include <deal.II/grid/tria_iterator.templates.h>
36
37#include <boost/container/small_vector.hpp>
38
39#include <cmath>
40#include <limits>
41#include <utility>
42
43
45
46// Forward declarations
47#ifndef DOXYGEN
48template <int dim, int spacedim>
50class Triangulation;
51template <typename Accessor>
52class TriaRawIterator;
53template <typename Accessor>
54class TriaIterator;
55template <typename Accessor>
57
58namespace parallel
59{
60 template <int dim, int spacedim>
62 class TriangulationBase;
63}
64
65template <int dim, int spacedim>
67class DoFHandler;
68template <int dim, int spacedim, bool lda>
69class DoFCellAccessor;
70
71
72template <int dim, int spacedim>
73class Manifold;
74
75template <int dim, int spacedim>
76class Mapping;
77#endif
78
79namespace internal
80{
81 namespace TriangulationImplementation
82 {
83 class TriaObjects;
84 struct Implementation;
85 struct ImplementationMixedMesh;
86 } // namespace TriangulationImplementation
87
88 namespace TriaAccessorImplementation
89 {
90 struct Implementation;
91
97 template <int structdim, int dim>
99 {
100 struct type
101 {
105 type() = default;
106
110 type(const int level)
111 {
113 (void)level; // removes -Wunused-parameter warning in optimized mode
114 }
115
119 operator int() const
120 {
121 return 0;
122 }
123
124 void
126 {
128 }
129
130 void
132 {
134 }
135 };
136 };
137
138
144 template <int dim>
145 struct PresentLevelType<dim, dim>
146 {
147 using type = int;
148 };
149 } // namespace TriaAccessorImplementation
150} // namespace internal
151template <int structdim, int dim, int spacedim>
152class TriaAccessor;
153template <int dim, int spacedim>
154class TriaAccessor<0, dim, spacedim>;
155template <int spacedim>
156class TriaAccessor<0, 1, spacedim>;
157
158// note: the file tria_accessor.templates.h is included at the end of
159// this file. this includes a lot of templates. originally, this was
160// only done in debug mode, but led to cyclic reduction problems and
161// so is now on by default.
162
163
168{
173 "The operation you are attempting can only be performed for "
174 "(cell, face, or edge) iterators that point to valid "
175 "objects. These objects need not necessarily be active, "
176 "i.e., have no children, but they need to be part of a "
177 "triangulation. (The objects pointed to by an iterator "
178 "may -- after coarsening -- also be objects that used "
179 "to be part of a triangulation, but are now no longer "
180 "used. Their memory location may have been retained "
181 "for re-use upon the next mesh refinement, but is "
182 "currently unused.)");
193 "The operation you are attempting can only be performed for "
194 "(cell, face, or edge) iterators that point to 'active' "
195 "objects. 'Active' objects are those that do not have "
196 "children (in the case of cells), or that are part of "
197 "an active cell (in the case of faces or edges). However, "
198 "the object on which you are trying the current "
199 "operation is not 'active' in this sense.");
206 "The operation you are attempting can only be performed for "
207 "(cell, face, or edge) iterators that have children, "
208 "but the object on which you are trying the current "
209 "operation does not have any.");
217 "The operation you are attempting can only be performed for "
218 "(cell, face, or edge) iterators that have a parent object, "
219 "but the object on which you are trying the current "
220 "operation does not have one -- i.e., it is on the "
221 "coarsest level of the triangulation.");
226 int,
227 << "You can only set the child index if the cell does not "
228 << "currently have children registered; or you can clear it. "
229 << "The given index was " << arg1
230 << " (-1 means: clear children).");
234 template <typename AccessorType>
236 AccessorType,
237 << "You tried to dereference an iterator for which this "
238 << "is not possible. More information on this iterator: "
239 << "index=" << arg1.index() << ", state="
240 << (arg1.state() == IteratorState::valid ?
241 "valid" :
242 (arg1.state() == IteratorState::past_the_end ?
243 "past_the_end" :
244 "invalid")));
249 "Iterators can only be compared if they point to the same "
250 "triangulation, or if neither of them are associated "
251 "with a triangulation.");
252 // TODO: Write documentation!
257 // TODO: Write documentation!
277 // TODO: Write documentation!
283 int,
284 << "You can only set the child index of an even numbered child."
285 << "The number of the child given was " << arg1 << '.');
286} // namespace TriaAccessorExceptions
287
288
314template <int structdim, int dim, int spacedim = dim>
316{
317public:
324 static constexpr unsigned int space_dimension = spacedim;
325
331 static constexpr unsigned int dimension = dim;
332
338 static const unsigned int structure_dimension = structdim;
339
349 void
350 operator=(const TriaAccessorBase *) = delete;
351
352protected:
358 using AccessorData = void;
359
364 const int level = -1,
365 const int index = -1,
366 const AccessorData * = nullptr);
367
372
380 void
382
388
399 bool
400 operator<(const TriaAccessorBase &other) const;
401
402protected:
406 bool
408
412 bool
414
428 void
430
438 void
448 objects() const;
449
450public:
456 using LocalData = void *;
457
481 int
482 level() const;
483
510 int
511 index() const;
512
518 state() const;
519
526
530protected:
535 typename ::internal::TriaAccessorImplementation::
536 PresentLevelType<structdim, dim>::type present_level;
537
543
548
549private:
550 template <typename Accessor>
551 friend class TriaRawIterator;
552 template <typename Accessor>
553 friend class TriaIterator;
554 template <typename Accessor>
555 friend class TriaActiveIterator;
556};
557
558
559
580template <int structdim, int dim, int spacedim = dim>
582{
583public:
590 static constexpr unsigned int space_dimension = spacedim;
591
597 static constexpr unsigned int dimension = dim;
598
604 static const unsigned int structure_dimension = structdim;
605
611 using AccessorData = void;
612
620 InvalidAccessor(const void *parent = nullptr,
621 const int level = -1,
622 const int index = -1,
623 const AccessorData *local_data = nullptr);
624
633
638 template <typename OtherAccessor>
639 InvalidAccessor(const OtherAccessor &);
640
644 void
646
650 bool
652 bool
654
658 void
659 operator++() const;
660 void
661 operator--() const;
662
668 state();
669
670
675 static int
676 level();
677
682 static int
683 index();
684
689 bool
690 used() const;
691
696 bool
698
703 manifold_id() const;
704
708 unsigned int
709 user_index() const;
710
714 void
715 set_user_index(const unsigned int p) const;
716
720 void
722
727 vertex(const unsigned int i) const;
728
733 void *
734 line(const unsigned int i) const;
735
740 void *
741 quad(const unsigned int i) const;
742};
743
744
745
763template <int structdim, int dim, int spacedim>
764class TriaAccessor : public TriaAccessorBase<structdim, dim, spacedim>
765{
766public:
772
777 const int level = -1,
778 const int index = -1,
779 const AccessorData *local_data = nullptr);
780
785 TriaAccessor(const TriaAccessor &) = default;
786
790 TriaAccessor(TriaAccessor &&) = default; // NOLINT
791
804 template <int structdim2, int dim2, int spacedim2>
806
811 template <int structdim2, int dim2, int spacedim2>
813
824 operator=(const TriaAccessor &) = delete;
825
830 operator=(TriaAccessor &&) = default; // NOLINT
831
835 ~TriaAccessor() = default;
836
843 bool
844 used() const;
845
858 vertex_iterator(const unsigned int i) const;
859
875 unsigned int
876 vertex_index(const unsigned int i) const;
877
916 vertex(const unsigned int i) const;
917
921 typename ::internal::TriangulationImplementation::
922 Iterators<dim, spacedim>::line_iterator
923 line(const unsigned int i) const;
924
931 unsigned int
932 line_index(const unsigned int i) const;
933
937 typename ::internal::TriangulationImplementation::
938 Iterators<dim, spacedim>::quad_iterator
939 quad(const unsigned int i) const;
940
947 unsigned int
948 quad_index(const unsigned int i) const;
966 unsigned char
967 combined_face_orientation(const unsigned int face) const;
968
980 bool
981 face_orientation(const unsigned int face) const;
982
992 bool
993 face_flip(const unsigned int face) const;
994
1004 bool
1005 face_rotation(const unsigned int face) const;
1006
1019 bool
1020 line_orientation(const unsigned int line) const;
1035 bool
1037
1042 unsigned int
1043 n_children() const;
1044
1058 unsigned int
1060
1074 unsigned int
1076
1081 child(const unsigned int i) const;
1082
1087 unsigned int
1090
1100 isotropic_child(const unsigned int i) const;
1101
1107
1113 int
1114 child_index(const unsigned int i) const;
1115
1121 int
1122 isotropic_child_index(const unsigned int i) const;
1146
1174 void
1176
1205 void
1207
1215 bool
1217
1229
1252
1270 void
1272
1286 void
1288
1305 bool
1307
1313 void
1315
1321 void
1323
1329 void
1331
1337 void
1339
1345 void
1347
1359 void
1360 set_user_pointer(void *p) const;
1361
1367 void
1369
1387 void *
1389
1411 void
1413
1420 void
1422
1432 void
1433 set_user_index(const unsigned int p) const;
1434
1440 void
1442
1454 unsigned int
1455 user_index() const;
1456
1474 void
1475 recursively_set_user_index(const unsigned int p) const;
1476
1485 void
1521 double
1522 diameter() const;
1523
1550 std::pair<Point<spacedim>, double>
1552
1563
1573 double
1574 extent_in_direction(const unsigned int axis) const;
1575
1579 double
1581
1596 intermediate_point(const Point<structdim> &coordinates) const;
1597
1622
1658 center(const bool respect_manifold = false,
1659 const bool interpolate_from_surrounding = false) const;
1660
1679 barycenter() const;
1680
1711 double
1712 measure() const;
1713
1728 bool
1731
1737
1741 unsigned int
1742 n_vertices() const;
1743
1747 unsigned int
1748 n_lines() const;
1749
1759 unsigned int
1760 n_faces() const;
1761
1768
1775
1784
1789private:
1794 void
1796
1804 void
1806 const std::initializer_list<int> &new_indices) const;
1807
1811 void
1813 const std::initializer_list<unsigned int> &new_indices) const;
1814
1822 void
1823 set_line_orientation(const unsigned int line, const bool orientation) const;
1824
1832 void
1833 set_combined_face_orientation(const unsigned int face,
1834 const unsigned char combined_orientation) const;
1835
1839 void
1841
1845 void
1847
1856 void
1858
1866 void
1868
1875 void
1876 set_children(const unsigned int i, const int index) const;
1877
1882 void
1884
1885private:
1886 friend class Triangulation<dim, spacedim>;
1887
1888 friend struct ::internal::TriangulationImplementation::Implementation;
1889 friend struct ::internal::TriangulationImplementation::
1890 ImplementationMixedMesh;
1891 friend struct ::internal::TriaAccessorImplementation::Implementation;
1892};
1893
1894
1895
1914template <int dim, int spacedim>
1915class TriaAccessor<0, dim, spacedim>
1916{
1917public:
1923 static constexpr unsigned int space_dimension = spacedim;
1924
1930 static constexpr unsigned int dimension = dim;
1931
1937 static const unsigned int structure_dimension = 0;
1938
1942 using AccessorData = void;
1943
1949 const unsigned int vertex_index);
1950
1957 const int level = 0,
1958 const int index = 0,
1959 const AccessorData * = nullptr);
1960
1964 template <int structdim2, int dim2, int spacedim2>
1966
1970 template <int structdim2, int dim2, int spacedim2>
1972
1977 state() const;
1978
1983 static int
1985
1990 int
1991 index() const;
1992
1999
2009 void
2011
2015 void
2020 bool
2021 operator==(const TriaAccessor &) const;
2022
2026 bool
2027 operator!=(const TriaAccessor &) const;
2028
2056 unsigned int
2057 vertex_index(const unsigned int i = 0) const;
2058
2065 vertex(const unsigned int i = 0) const;
2066
2071 typename ::internal::TriangulationImplementation::
2072 Iterators<dim, spacedim>::line_iterator static line(const unsigned int);
2073
2077 static unsigned int
2078 line_index(const unsigned int i);
2079
2083 static typename ::internal::TriangulationImplementation::
2084 Iterators<dim, spacedim>::quad_iterator
2085 quad(const unsigned int i);
2086
2090 static unsigned int
2091 quad_index(const unsigned int i);
2092
2108 double
2109 diameter() const;
2110
2118 double
2119 extent_in_direction(const unsigned int axis) const;
2120
2129 center(const bool respect_manifold = false,
2130 const bool interpolate_from_surrounding = false) const;
2131
2140 double
2141 measure() const;
2158 static unsigned char
2159 combined_face_orientation(const unsigned int face);
2160
2164 static bool
2165 face_orientation(const unsigned int face);
2166
2170 static bool
2171 face_flip(const unsigned int face);
2172
2176 static bool
2177 face_rotation(const unsigned int face);
2178
2182 static bool
2183 line_orientation(const unsigned int line);
2184
2199 static bool
2201
2206 static unsigned int
2208
2213 static unsigned int
2215
2219 static unsigned int
2221
2225 static unsigned int
2227
2232 child(const unsigned int);
2233
2238 isotropic_child(const unsigned int);
2239
2243 static RefinementCase<0>
2245
2249 static int
2250 child_index(const unsigned int i);
2251
2255 static int
2256 isotropic_child_index(const unsigned int i);
2264 bool
2265 used() const;
2266
2267protected:
2275 void
2277
2286 bool
2287 operator<(const TriaAccessor &other) const;
2288
2293
2298
2299private:
2300 template <typename Accessor>
2301 friend class TriaRawIterator;
2302 template <typename Accessor>
2303 friend class TriaIterator;
2304 template <typename Accessor>
2306};
2307
2308
2309
2326template <int spacedim>
2327class TriaAccessor<0, 1, spacedim>
2328{
2329public:
2335 static constexpr unsigned int space_dimension = spacedim;
2336
2342 static constexpr unsigned int dimension = 1;
2343
2349 static const unsigned int structure_dimension = 0;
2350
2354 using AccessorData = void;
2355
2361 {
2373 right_vertex
2375
2388 const VertexKind vertex_kind,
2389 const unsigned int vertex_index);
2390
2397 const int = 0,
2398 const int = 0,
2399 const AccessorData * = nullptr);
2400
2404 template <int structdim2, int dim2, int spacedim2>
2406
2410 template <int structdim2, int dim2, int spacedim2>
2412
2417 void
2419
2425 void
2427
2435
2440 static int
2442
2447 int
2448 index() const;
2449
2456
2467 void
2468 operator++() const;
2469
2474 void
2475 operator--() const;
2479 bool
2480 operator==(const TriaAccessor &) const;
2481
2485 bool
2486 operator!=(const TriaAccessor &) const;
2487
2496 bool
2497 operator<(const TriaAccessor &other) const;
2498
2525 unsigned int
2526 vertex_index(const unsigned int i = 0) const;
2527
2534 vertex(const unsigned int i = 0) const;
2535
2541 center() const;
2542
2547 typename ::internal::TriangulationImplementation::
2548 Iterators<1, spacedim>::line_iterator static line(const unsigned int);
2549
2556 static unsigned int
2557 line_index(const unsigned int i);
2558
2562 static typename ::internal::TriangulationImplementation::
2563 Iterators<1, spacedim>::quad_iterator
2564 quad(const unsigned int i);
2565
2572 static unsigned int
2573 quad_index(const unsigned int i);
2574
2584 bool
2586
2603
2607 const Manifold<1, spacedim> &
2609
2618
2619
2631 bool
2632 user_flag_set() const;
2633
2639 void
2640 set_user_flag() const;
2641
2647 void
2648 clear_user_flag() const;
2649
2655 void
2657
2663 void
2665
2671 void
2672 clear_user_data() const;
2673
2685 void
2686 set_user_pointer(void *p) const;
2687
2693 void
2694 clear_user_pointer() const;
2695
2711 void *
2712 user_pointer() const;
2713
2735 void
2736 recursively_set_user_pointer(void *p) const;
2737
2744 void
2746
2756 void
2757 set_user_index(const unsigned int p) const;
2758
2764 void
2765 clear_user_index() const;
2766
2778 unsigned int
2779 user_index() const;
2780
2798 void
2799 recursively_set_user_index(const unsigned int p) const;
2800
2809 void
2827 static unsigned char
2828 combined_face_orientation(const unsigned int face);
2829
2833 static bool
2834 face_orientation(const unsigned int face);
2835
2839 static bool
2840 face_flip(const unsigned int face);
2841
2845 static bool
2846 face_rotation(const unsigned int face);
2847
2851 static bool
2852 line_orientation(const unsigned int line);
2853
2868 static bool
2870
2875 static unsigned int
2877
2882 static unsigned int
2884
2888 static unsigned int
2890
2894 static unsigned int
2896
2901 child(const unsigned int);
2902
2907 isotropic_child(const unsigned int);
2908
2912 static RefinementCase<0>
2914
2918 static int
2919 child_index(const unsigned int i);
2920
2924 static int
2925 isotropic_child_index(const unsigned int i);
2956 void
2958
2965 void
2967
2977 void
2979
2991 void
3000 bool
3001 used() const;
3002
3008
3012 unsigned int
3013 n_vertices() const;
3014
3018 unsigned int
3019 n_lines() const;
3020
3027
3034
3035protected:
3040
3046
3051};
3052
3053
3054
3070template <int dim, int spacedim = dim>
3071class CellAccessor : public TriaAccessor<dim, dim, spacedim>
3072{
3073public:
3078
3083
3095 const int level = -1,
3096 const int index = -1,
3097 const AccessorData *local_data = nullptr);
3098
3103
3116 template <int structdim2, int dim2, int spacedim2>
3118
3123 template <int structdim2, int dim2, int spacedim2>
3125
3130
3134 // NOLINTNEXTLINE OSX does not compile with noexcept
3136
3140 ~CellAccessor() = default;
3141
3153
3157 // NOLINTNEXTLINE OSX does not compile with noexcept
3160
3184 as_dof_handler_iterator(const DoFHandler<dim, spacedim> &dof_handler) const;
3185
3196 const DoFHandler<dim, spacedim> &dof_handler) const;
3197
3198
3215 child(const unsigned int i) const;
3216
3220 boost::container::small_vector<TriaIterator<CellAccessor<dim, spacedim>>,
3223
3227 TriaIterator<TriaAccessor<dim - 1, dim, spacedim>>
3228 face(const unsigned int i) const;
3229
3234 unsigned int
3237
3241 boost::container::small_vector<
3242 TriaIterator<TriaAccessor<dim - 1, dim, spacedim>>,
3245
3255 unsigned int
3256 face_index(const unsigned int i) const;
3257
3306 neighbor_child_on_subface(const unsigned int face_no,
3307 const unsigned int subface_no) const;
3308
3357 neighbor(const unsigned int face_no) const;
3358
3366 int
3367 neighbor_index(const unsigned int face_no) const;
3368
3376 int
3377 neighbor_level(const unsigned int face_no) const;
3378
3390 unsigned int
3391 neighbor_of_neighbor(const unsigned int face_no) const;
3392
3403 bool
3404 neighbor_is_coarser(const unsigned int face_no) const;
3405
3420 std::pair<unsigned int, unsigned int>
3421 neighbor_of_coarser_neighbor(const unsigned int neighbor) const;
3422
3429 unsigned int
3430 neighbor_face_no(const unsigned int neighbor) const;
3431
3435 static bool
3437
3451 bool
3452 has_periodic_neighbor(const unsigned int i) const;
3453
3471 periodic_neighbor(const unsigned int i) const;
3472
3481 neighbor_or_periodic_neighbor(const unsigned int i) const;
3482
3498 periodic_neighbor_child_on_subface(const unsigned int face_no,
3499 const unsigned int subface_no) const;
3500
3511 std::pair<unsigned int, unsigned int>
3512 periodic_neighbor_of_coarser_periodic_neighbor(const unsigned face_no) const;
3513
3519 int
3520 periodic_neighbor_index(const unsigned int i) const;
3521
3527 int
3528 periodic_neighbor_level(const unsigned int i) const;
3529
3544 unsigned int
3545 periodic_neighbor_of_periodic_neighbor(const unsigned int i) const;
3546
3552 unsigned int
3553 periodic_neighbor_face_no(const unsigned int i) const;
3554
3561 bool
3562 periodic_neighbor_is_coarser(const unsigned int i) const;
3563
3580 bool
3581 at_boundary(const unsigned int i) const;
3582
3591 bool
3592 at_boundary() const;
3593
3601 bool
3602 has_boundary_lines() const;
3630
3648 void
3651
3655 void
3657
3662 std::uint8_t
3664
3669 void
3670 set_refine_choice(const std::uint8_t refinement_choice = static_cast<char>(
3672
3676 void
3678
3686 bool
3688 const unsigned int face_no,
3689 const RefinementCase<dim - 1> &face_refinement_case =
3691
3697 bool
3698 flag_for_line_refinement(const unsigned int line_no) const;
3699
3709 subface_case(const unsigned int face_no) const;
3710
3714 bool
3716
3721 void
3723
3727 void
3752 material_id() const;
3753
3765 void
3766 set_material_id(const types::material_id new_material_id) const;
3767
3776 void
3777 recursively_set_material_id(const types::material_id new_material_id) const;
3805
3821 void
3822 set_subdomain_id(const types::subdomain_id new_subdomain_id) const;
3823
3834
3839 void
3841 const types::subdomain_id new_level_subdomain_id) const;
3842
3843
3859 void
3861 const types::subdomain_id new_subdomain_id) const;
3885
3895
3912 bool
3913 direction_flag() const;
3914
3940 unsigned int
3942
3950 int
3951 parent_index() const;
3952
3959 parent() const;
3960
3980 bool
3981 is_active() const;
3982
4002 bool
4004
4009 bool
4011
4045 bool
4046 is_ghost() const;
4047
4053 bool
4055
4082 bool
4084
4091 bool
4093
4107 bool
4109
4118 void
4119 set_neighbor(const unsigned int i,
4120 const TriaIterator<CellAccessor<dim, spacedim>> &pointer) const;
4121
4135 CellId
4136 id() const;
4137
4138 using TriaAccessor<dim, dim, spacedim>::diameter;
4139
4143 double
4144 diameter(const Mapping<dim, spacedim> &mapping) const;
4145
4163
4164protected:
4180 unsigned int
4181 neighbor_of_neighbor_internal(const unsigned int neighbor) const;
4182
4188 template <int dim_, int spacedim_>
4189 bool
4190 point_inside_codim(const Point<spacedim_> &p) const;
4191
4192
4193
4194private:
4199 void
4200 set_active_cell_index(const unsigned int active_cell_index) const;
4201
4205 void
4207
4211 void
4213
4217 void
4218 set_parent(const unsigned int parent_index);
4219
4230 void
4231 set_direction_flag(const bool new_direction_flag) const;
4232
4233 friend class Triangulation<dim, spacedim>;
4234
4235 friend class parallel::TriangulationBase<dim, spacedim>;
4236
4237 friend struct ::internal::TriangulationImplementation::Implementation;
4238 friend struct ::internal::TriangulationImplementation::
4239 ImplementationMixedMesh;
4240};
4241
4242
4243
4244/* ----- declaration of explicit specializations and general templates ----- */
4245
4246
4247template <int structdim, int dim, int spacedim>
4248template <typename OtherAccessor>
4250 const OtherAccessor &)
4251{
4252 Assert(false,
4253 ExcMessage("You are attempting an illegal conversion between "
4254 "iterator/accessor types. The constructor you call "
4255 "only exists to make certain template constructs "
4256 "easier to write as dimension independent code but "
4257 "the conversion is not valid in the current context."));
4258}
4259
4260
4261
4262template <int structdim, int dim, int spacedim>
4263template <int structdim2, int dim2, int spacedim2>
4266{
4267 Assert(false,
4268 ExcMessage("You are attempting an illegal conversion between "
4269 "iterator/accessor types. The constructor you call "
4270 "only exists to make certain template constructs "
4271 "easier to write as dimension independent code but "
4272 "the conversion is not valid in the current context."));
4273}
4274
4275
4276
4277template <int dim, int spacedim>
4278template <int structdim2, int dim2, int spacedim2>
4281{
4282 Assert(false,
4283 ExcMessage("You are attempting an illegal conversion between "
4284 "iterator/accessor types. The constructor you call "
4285 "only exists to make certain template constructs "
4286 "easier to write as dimension independent code but "
4287 "the conversion is not valid in the current context."));
4288}
4289
4290
4291
4292template <int structdim, int dim, int spacedim>
4293template <int structdim2, int dim2, int spacedim2>
4296{
4297 Assert(false,
4298 ExcMessage("You are attempting an illegal conversion between "
4299 "iterator/accessor types. The constructor you call "
4300 "only exists to make certain template constructs "
4301 "easier to write as dimension independent code but "
4302 "the conversion is not valid in the current context."));
4303}
4304
4305
4306
4307template <int dim, int spacedim>
4308template <int structdim2, int dim2, int spacedim2>
4311{
4312 Assert(false,
4313 ExcMessage("You are attempting an illegal conversion between "
4314 "iterator/accessor types. The constructor you call "
4315 "only exists to make certain template constructs "
4316 "easier to write as dimension independent code but "
4317 "the conversion is not valid in the current context."));
4318}
4319
4320
4321#ifndef DOXYGEN
4322
4323template <>
4324bool
4326template <>
4327bool
4329template <>
4330bool
4332template <>
4333bool
4335template <>
4336bool
4338template <>
4339bool
4341// -------------------------------------------------------------------
4342
4343template <>
4344void
4346
4347
4348
4349namespace internal
4350{
4351 namespace TriaAccessorImplementation
4352 {
4358 template <int dim, int spacedim>
4359 inline double
4360 diameter(
4361 const boost::container::small_vector<Point<spacedim>,
4363 vertices)
4364 {
4365 const ReferenceCell reference_cell =
4366 ReferenceCell::n_vertices_to_type(dim, vertices.size());
4367
4368 if (reference_cell == ReferenceCells::Line)
4369 // Return the distance between the two vertices
4370 return (vertices[1] - vertices[0]).norm();
4371 else if (reference_cell == ReferenceCells::Triangle)
4372 // Return the longest of the three edges
4373 return std::max({(vertices[1] - vertices[0]).norm(),
4374 (vertices[2] - vertices[1]).norm(),
4375 (vertices[2] - vertices[0]).norm()});
4376 else if (reference_cell == ReferenceCells::Quadrilateral)
4377 // Return the longer one of the two diagonals of the quadrilateral
4378 return std::max({(vertices[3] - vertices[0]).norm(),
4379 (vertices[2] - vertices[1]).norm()});
4380 else if (reference_cell == ReferenceCells::Tetrahedron)
4381 // Return the longest of the six edges of the tetrahedron
4382 return std::max({(vertices[1] - vertices[0]).norm(),
4383 (vertices[2] - vertices[0]).norm(),
4384 (vertices[2] - vertices[1]).norm(),
4385 (vertices[3] - vertices[0]).norm(),
4386 (vertices[3] - vertices[1]).norm(),
4387 (vertices[3] - vertices[2]).norm()});
4388 else if (reference_cell == ReferenceCells::Pyramid)
4389 // Return ...
4390 return std::max({// the longest diagonal of the quadrilateral base
4391 // of the pyramid or ...
4392 (vertices[3] - vertices[0]).norm(),
4393 (vertices[2] - vertices[1]).norm(),
4394 // the longest edge connected with the apex of the
4395 // pyramid
4396 (vertices[4] - vertices[0]).norm(),
4397 (vertices[4] - vertices[1]).norm(),
4398 (vertices[4] - vertices[2]).norm(),
4399 (vertices[4] - vertices[3]).norm()});
4400 else if (reference_cell == ReferenceCells::Wedge)
4401 // Return ...
4402 return std::max({// the longest of the 2*3=6 diagonals of the three
4403 // quadrilateral sides of the wedge or ...
4404 (vertices[4] - vertices[0]).norm(),
4405 (vertices[3] - vertices[1]).norm(),
4406 (vertices[5] - vertices[1]).norm(),
4407 (vertices[4] - vertices[2]).norm(),
4408 (vertices[5] - vertices[0]).norm(),
4409 (vertices[3] - vertices[2]).norm(),
4410 // the longest of the 3*2=6 edges of the two
4411 // triangular faces of the wedge
4412 (vertices[1] - vertices[0]).norm(),
4413 (vertices[2] - vertices[1]).norm(),
4414 (vertices[2] - vertices[0]).norm(),
4415 (vertices[4] - vertices[3]).norm(),
4416 (vertices[5] - vertices[4]).norm(),
4417 (vertices[5] - vertices[3]).norm()});
4418 else if (reference_cell == ReferenceCells::Hexahedron)
4419 // Return the longest of the four diagonals of the hexahedron
4420 return std::max({(vertices[7] - vertices[0]).norm(),
4421 (vertices[6] - vertices[1]).norm(),
4422 (vertices[2] - vertices[5]).norm(),
4423 (vertices[3] - vertices[4]).norm()});
4424
4426 return -1e10;
4427 }
4428 } // namespace TriaAccessorImplementation
4429} // namespace internal
4430
4431
4432/*--------------------- Functions: TriaAccessorBase -------------------------*/
4433
4434template <int structdim, int dim, int spacedim>
4436 const Triangulation<dim, spacedim> *tria,
4437 const int level,
4438 const int index,
4439 const AccessorData *)
4440 : present_level((structdim == dim) ? level : 0)
4441 , present_index(index)
4442 , tria(tria)
4443{
4444 // non-cells have no level, so a 0
4445 // should have been passed, or a -1
4446 // for an end-iterator, or -2 for
4447 // an invalid (default constructed)
4448 // iterator
4449 if (structdim != dim)
4450 {
4451 Assert((level == 0) || (level == -1) || (level == -2),
4453 }
4454}
4455
4456
4457template <int structdim, int dim, int spacedim>
4460 : present_level(a.present_level)
4461 , present_index(a.present_index)
4462 , tria(a.tria)
4463{}
4464
4465
4466template <int structdim, int dim, int spacedim>
4467inline void
4470{
4471 present_level = a.present_level;
4472 present_index = a.present_index;
4473 tria = a.tria;
4474
4475 if (structdim != dim)
4476 {
4477 Assert((present_level == 0) || (present_level == -1) ||
4478 (present_level == -2),
4480 }
4481}
4482
4483
4484
4485template <int structdim, int dim, int spacedim>
4489{
4490 present_level = a.present_level;
4491 present_index = a.present_index;
4492 tria = a.tria;
4493
4494 if (structdim != dim)
4495 {
4496 Assert((present_level == 0) || (present_level == -1) ||
4497 (present_level == -2),
4499 }
4500 return *this;
4501}
4502
4503
4504
4505template <int structdim, int dim, int spacedim>
4506inline bool
4509{
4510 Assert(tria == a.tria || tria == nullptr || a.tria == nullptr,
4512 return ((tria == a.tria) && (present_level == a.present_level) &&
4513 (present_index == a.present_index));
4514}
4515
4516
4517
4518template <int structdim, int dim, int spacedim>
4519inline bool
4522{
4523 Assert(tria == a.tria || tria == nullptr || a.tria == nullptr,
4525 return ((tria != a.tria) || (present_level != a.present_level) ||
4526 (present_index != a.present_index));
4527}
4528
4529
4530
4531template <int structdim, int dim, int spacedim>
4532inline bool
4535{
4537
4538 if (present_level != other.present_level)
4539 return (present_level < other.present_level);
4540
4541 return (present_index < other.present_index);
4542}
4543
4544
4545
4546template <int structdim, int dim, int spacedim>
4547inline int
4549{
4550 // This is always zero or invalid
4551 // if the object is not a cell
4552 return present_level;
4553}
4554
4555
4556
4557template <int structdim, int dim, int spacedim>
4558inline int
4560{
4561 return present_index;
4562}
4563
4564
4565
4566template <int structdim, int dim, int spacedim>
4569{
4570 if ((present_level >= 0) && (present_index >= 0))
4571 return IteratorState::valid;
4572 else if (present_index == -1)
4574 else
4576}
4577
4578
4579
4580template <int structdim, int dim, int spacedim>
4581inline const Triangulation<dim, spacedim> &
4583{
4584 return *tria;
4585}
4586
4587
4588
4589template <int structdim, int dim, int spacedim>
4590inline void
4592{
4593 // this iterator is used for
4594 // objects without level
4595 ++this->present_index;
4596
4597 if (structdim != dim)
4598 {
4599 // is index still in the range of
4600 // the vector? (note that we don't
4601 // have to set the level, since
4602 // dim!=1 and the object therefore
4603 // has no level)
4604 if (this->present_index >= static_cast<int>(objects().n_objects()))
4605 this->present_index = -1;
4606 }
4607 else
4608 {
4609 while (this->present_index >=
4610 static_cast<int>(
4611 this->tria->levels[this->present_level]->cells.n_objects()))
4612 {
4613 // no -> go one level up until we find
4614 // one with more than zero cells
4615 ++this->present_level;
4616 this->present_index = 0;
4617 // highest level reached?
4618 if (this->present_level >=
4619 static_cast<int>(this->tria->levels.size()))
4620 {
4621 // return with past the end pointer
4622 this->present_level = this->present_index = -1;
4623 return;
4624 }
4625 }
4626 }
4627}
4628
4629
4630template <int structdim, int dim, int spacedim>
4631inline void
4633{
4634 // same as operator++
4635 --this->present_index;
4636
4637 if (structdim != dim)
4638 {
4639 if (this->present_index < 0)
4640 this->present_index = -1;
4641 }
4642 else
4643 {
4644 while (this->present_index < 0)
4645 {
4646 // no -> go one level down
4647 --this->present_level;
4648 // lowest level reached?
4649 if (this->present_level == -1)
4650 {
4651 // return with past the end pointer
4652 this->present_level = this->present_index = -1;
4653 return;
4654 }
4655 // else
4656 this->present_index =
4657 this->tria->levels[this->present_level]->cells.n_objects() - 1;
4658 }
4659 }
4660}
4661
4662
4663
4664template <int structdim, int dim, int spacedim>
4665inline ::internal::TriangulationImplementation::TriaObjects &
4667{
4668 if (structdim == dim)
4669 return this->tria->levels[this->present_level]->cells;
4670
4671 if (structdim == 1 && dim > 1)
4672 return this->tria->faces->lines;
4673
4674 if (structdim == 2 && dim > 2)
4675 return this->tria->faces->quads;
4676
4678
4679 return this->tria->levels[this->present_level]->cells;
4680}
4681
4682
4683
4684/*---------------------- Functions: InvalidAccessor -------------------------*/
4685
4686template <int structdim, int dim, int spacedim>
4688 const int,
4689 const int,
4690 const AccessorData *)
4691{
4692 Assert(false,
4693 ExcMessage("You are attempting an invalid conversion between "
4694 "iterator/accessor types. The constructor you call "
4695 "only exists to make certain template constructs "
4696 "easier to write as dimension independent code but "
4697 "the conversion is not valid in the current context."));
4698}
4699
4700
4701
4702template <int structdim, int dim, int spacedim>
4704 const InvalidAccessor &)
4705{
4706 Assert(false,
4707 ExcMessage("You are attempting an invalid conversion between "
4708 "iterator/accessor types. The constructor you call "
4709 "only exists to make certain template constructs "
4710 "easier to write as dimension independent code but "
4711 "the conversion is not valid in the current context."));
4712}
4713
4714
4715
4716template <int structdim, int dim, int spacedim>
4717void
4719{
4720 // nothing to do here. we could
4721 // throw an exception but we can't
4722 // get here without first creating
4723 // an object which would have
4724 // already thrown
4725}
4726
4727
4728
4729template <int structdim, int dim, int spacedim>
4730bool
4732 const InvalidAccessor &) const
4733{
4734 // nothing to do here. we could
4735 // throw an exception but we can't
4736 // get here without first creating
4737 // an object which would have
4738 // already thrown
4739 return false;
4740}
4741
4742
4743
4744template <int structdim, int dim, int spacedim>
4745bool
4747 const InvalidAccessor &) const
4748{
4749 // nothing to do here. we could
4750 // throw an exception but we can't
4751 // get here without first creating
4752 // an object which would have
4753 // already thrown
4754 return true;
4755}
4756
4757
4758
4759template <int structdim, int dim, int spacedim>
4760bool
4762{
4763 // nothing to do here. we could
4764 // throw an exception but we can't
4765 // get here without first creating
4766 // an object which would have
4767 // already thrown
4768 return false;
4769}
4770
4771
4772
4773template <int structdim, int dim, int spacedim>
4774bool
4776{
4777 // nothing to do here. we could
4778 // throw an exception but we can't
4779 // get here without first creating
4780 // an object which would have
4781 // already thrown
4782 return false;
4783}
4784
4785
4786
4787template <int structdim, int dim, int spacedim>
4788void
4790{}
4791
4792
4793
4794template <int structdim, int dim, int spacedim>
4795void
4797{}
4798
4799
4800
4801template <int structdim, int dim, int spacedim>
4804{
4806}
4807
4808
4809
4810template <int structdim, int dim, int spacedim>
4811unsigned int
4813{
4815}
4816
4817
4818
4819template <int structdim, int dim, int spacedim>
4820void
4822 const unsigned int) const
4823{
4824 Assert(false,
4825 ExcMessage("You are trying to set the user index of an "
4826 "invalid object."));
4827}
4828
4829
4830
4831template <int structdim, int dim, int spacedim>
4832void
4834 const types::manifold_id) const
4835{
4836 Assert(false,
4837 ExcMessage("You are trying to set the manifold id of an "
4838 "invalid object."));
4839}
4840
4841
4842
4843template <int structdim, int dim, int spacedim>
4844inline Point<spacedim> &
4846{
4847 // nothing to do here. we could throw an exception but we can't get here
4848 // without first creating an object which would have already thrown
4849 static Point<spacedim> invalid_vertex;
4850 return invalid_vertex;
4851}
4852
4853
4854template <int structdim, int dim, int spacedim>
4855inline void *
4857{
4858 // nothing to do here. we could throw an exception but we can't get here
4859 // without first creating an object which would have already thrown
4860 return nullptr;
4861}
4862
4863
4864
4865template <int structdim, int dim, int spacedim>
4866inline void *
4868{
4869 // nothing to do here. we could throw an exception but we can't get here
4870 // without first creating an object which would have already thrown
4871 return nullptr;
4872}
4873
4874
4875/*------------------------ Functions: TriaAccessor ---------------------------*/
4876
4877
4878namespace internal
4879{
4880 namespace TriaAccessorImplementation
4881 {
4882 // make sure that if in the following we
4883 // write TriaAccessor
4884 // we mean the *class*
4885 // ::TriaAccessor, not the
4886 // enclosing namespace
4887 // ::internal::TriaAccessor
4888 using ::TriaAccessor;
4889
4894 struct Implementation
4895 {
4899 template <int dim, int spacedim>
4900 inline static unsigned int
4901 line_index(const TriaAccessor<1, dim, spacedim> &, const unsigned int)
4902 {
4903 Assert(false,
4904 ExcMessage("You can't ask for the index of a line bounding "
4905 "a one-dimensional cell because it is not "
4906 "bounded by lines."));
4908 }
4909
4910
4911 template <int dim, int spacedim>
4912 inline static unsigned int
4913 line_index(const TriaAccessor<2, dim, spacedim> &accessor,
4914 const unsigned int i)
4915 {
4916 constexpr unsigned int max_faces_per_cell = 4;
4917 return accessor.objects()
4918 .cells[accessor.present_index * max_faces_per_cell + i];
4919 }
4920
4921
4922 inline static unsigned int
4923 line_index(const TriaAccessor<3, 3, 3> &accessor, const unsigned int i)
4924 {
4925 const auto [face_index, line_index] =
4927 const auto line_within_face_index =
4929 line_index,
4930 face_index,
4931 accessor.combined_face_orientation(face_index));
4932
4933 return accessor.quad(face_index)->line_index(line_within_face_index);
4934 }
4935
4936
4937
4941 template <int structdim, int dim, int spacedim>
4942 inline static unsigned int
4943 quad_index(const TriaAccessor<structdim, dim, spacedim> &,
4944 const unsigned int)
4945 {
4946 Assert(false,
4947 ExcMessage("You can't ask for the index of a quad bounding "
4948 "a one- or two-dimensional cell because it is not "
4949 "bounded by quads."));
4951 }
4952
4953
4954 inline static unsigned int
4955 quad_index(const TriaAccessor<3, 3, 3> &accessor, const unsigned int i)
4956 {
4957 constexpr unsigned int max_faces_per_cell = 6;
4958 return accessor.tria->levels[accessor.present_level]
4959 ->cells.cells[accessor.present_index * max_faces_per_cell + i];
4960 }
4961
4962
4963
4967 template <int structdim, int dim, int spacedim>
4968 inline static void
4969 set_combined_face_orientation(
4971 const unsigned int face,
4972 const unsigned char combined_orientation)
4973 {
4974 Assert(structdim == dim,
4975 ExcMessage("This function can only be used on objects that are "
4976 "cells and not on objects which bound cells."));
4977 AssertIndexRange(face, accessor.n_faces());
4978
4979 if (dim == 1)
4980 Assert(combined_orientation ==
4982 ExcMessage("In 1d, faces do not have an orientation, so the "
4983 "only valid value is the default."));
4984 else if (dim == 2)
4985 Assert(combined_orientation ==
4987 combined_orientation ==
4989 ExcMessage(
4990 "In 2d, the only valid values of the combined orientation "
4991 "are the standard orientation or the reversed line "
4992 "orientation."));
4993
4994 // face_orientations is not set up in 1d
4995 if (dim != 1)
4996 accessor.tria->levels[accessor.present_level]
4997 ->face_orientations.set_combined_orientation(
4999 combined_orientation);
5000 }
5001
5005 template <int dim, int spacedim>
5006 inline static void
5007 set_line_orientation(const TriaAccessor<1, dim, spacedim> &,
5008 const unsigned int,
5009 const bool)
5010 {
5012 }
5013
5014
5015 template <int spacedim>
5016 inline static void
5017 set_line_orientation(const TriaAccessor<2, 2, spacedim> &,
5018 const unsigned int,
5019 const bool)
5020 {
5021 // quads in 2d have no
5022 // non-standard orientation
5024 }
5025
5026
5027 template <int spacedim>
5028 inline static void
5029 set_line_orientation(const TriaAccessor<2, 3, spacedim> &accessor,
5030 const unsigned int line,
5031 const bool value)
5032 {
5034 AssertIndexRange(line, accessor.n_lines());
5036 accessor.tria->faces->quads_line_orientations.size(),
5038
5039 // quads as part of 3d hexes can have non-standard orientation
5040 accessor.tria->faces->quads_line_orientations
5042 value;
5043 }
5044
5045
5046 inline static void
5047 set_line_orientation(const TriaAccessor<3, 3, 3> &,
5048 const unsigned int,
5049 const bool)
5050 {
5051 // it seems like we don't need this
5052 // one
5054 }
5055
5056
5060 template <int dim, int spacedim>
5061 inline static unsigned int
5062 vertex_index(const TriaAccessor<1, dim, spacedim> &accessor,
5063 const unsigned int corner)
5064 {
5065 constexpr unsigned int max_faces_per_cell = 2;
5066 return accessor.objects()
5067 .cells[accessor.present_index * max_faces_per_cell + corner];
5068 }
5069
5070
5071 template <int dim, int spacedim>
5072 inline static unsigned int
5073 vertex_index(const TriaAccessor<2, dim, spacedim> &accessor,
5074 const unsigned int corner)
5075 {
5076 const auto [line_index, vertex_index] =
5078 corner);
5079 const auto vertex_within_line_index =
5081 vertex_index,
5082 line_index,
5083 accessor.line_orientation(line_index) == true ?
5085 ReferenceCell::reversed_combined_line_orientation());
5086
5087 return accessor.line(line_index)
5088 ->vertex_index(vertex_within_line_index);
5089 }
5090
5091
5092
5093 inline static unsigned int
5094 vertex_index(const TriaAccessor<3, 3, 3> &accessor,
5095 const unsigned int corner)
5096 {
5097 const auto [face_index, vertex_index] =
5099 corner);
5100 const auto vertex_within_face_index =
5102 vertex_index,
5103 face_index,
5104 accessor.combined_face_orientation(face_index));
5105
5106 return accessor.quad(face_index)
5107 ->vertex_index(vertex_within_face_index);
5108 }
5109
5110
5111
5112 template <int dim, int spacedim>
5113 static std::array<unsigned int, 1>
5114 get_line_indices_of_cell(const TriaAccessor<1, dim, spacedim> &)
5115 {
5117 return {};
5118 }
5119
5120
5121
5122 template <int structdim, int dim, int spacedim>
5123 static std::array<unsigned int, 4>
5124 get_line_indices_of_cell(const TriaAccessor<2, dim, spacedim> &cell)
5125 {
5126 // For 2d cells the access cell->line_orientation() is already
5127 // efficient
5128 std::array<unsigned int, 4> line_indices = {};
5129 for (const unsigned int line : cell.line_indices())
5130 line_indices[line] = cell.line_index(line);
5131 return line_indices;
5132 }
5133
5138 template <int structdim, int dim, int spacedim>
5139 static std::array<unsigned int, 12>
5140 get_line_indices_of_cell(
5142 {
5143 std::array<unsigned int, 12> line_indices = {};
5144
5145 // For hexahedra, the classical access via quads -> lines is too
5146 // inefficient. Unroll this code here to allow the compiler to inline
5147 // the necessary functions.
5148 const auto ref_cell = cell.reference_cell();
5149 if (ref_cell == ReferenceCells::Hexahedron)
5150 {
5151 for (unsigned int f = 4; f < 6; ++f)
5152 {
5153 const unsigned char orientation =
5154 cell.get_triangulation()
5155 .levels[cell.level()]
5156 ->face_orientations.get_combined_orientation(
5158
5159 // It might seem superfluous to spell out the four indices
5160 // that get later consumed by a for loop over these four
5161 // elements; however, for the compiler it is easier to inline
5162 // the statement of standard_to_real_face_line() when next to
5163 // each other, as opposed to be interleaved with a
5164 // line_index() call.
5165 const std::array<unsigned int, 4> my_indices{
5166 {ref_cell.standard_to_real_face_line(0, f, orientation),
5167 ref_cell.standard_to_real_face_line(1, f, orientation),
5168 ref_cell.standard_to_real_face_line(2, f, orientation),
5169 ref_cell.standard_to_real_face_line(3, f, orientation)}};
5170 const auto quad = cell.quad(f);
5171 for (unsigned int l = 0; l < 4; ++l)
5172 line_indices[4 * (f - 4) + l] =
5173 quad->line_index(my_indices[l]);
5174 }
5175 for (unsigned int f = 0; f < 2; ++f)
5176 {
5177 const unsigned char orientation =
5178 cell.get_triangulation()
5179 .levels[cell.level()]
5180 ->face_orientations.get_combined_orientation(
5182 const std::array<unsigned int, 2> my_indices{
5183 {ref_cell.standard_to_real_face_line(0, f, orientation),
5184 ref_cell.standard_to_real_face_line(1, f, orientation)}};
5185 const auto quad = cell.quad(f);
5186 line_indices[8 + f] = quad->line_index(my_indices[0]);
5187 line_indices[10 + f] = quad->line_index(my_indices[1]);
5188 }
5189 }
5190 else if (ref_cell == ReferenceCells::Tetrahedron)
5191 {
5192 std::array<unsigned int, 3> orientations{
5195 cell.combined_face_orientation(2)}};
5196 const std::array<unsigned int, 6> my_indices{
5197 {ref_cell.standard_to_real_face_line(0, 0, orientations[0]),
5198 ref_cell.standard_to_real_face_line(1, 0, orientations[0]),
5199 ref_cell.standard_to_real_face_line(2, 0, orientations[0]),
5200 ref_cell.standard_to_real_face_line(1, 1, orientations[1]),
5201 ref_cell.standard_to_real_face_line(2, 1, orientations[1]),
5202 ref_cell.standard_to_real_face_line(1, 2, orientations[2])}};
5203 line_indices[0] = cell.quad(0)->line_index(my_indices[0]);
5204 line_indices[1] = cell.quad(0)->line_index(my_indices[1]);
5205 line_indices[2] = cell.quad(0)->line_index(my_indices[2]);
5206 line_indices[3] = cell.quad(1)->line_index(my_indices[3]);
5207 line_indices[4] = cell.quad(1)->line_index(my_indices[4]);
5208 line_indices[5] = cell.quad(2)->line_index(my_indices[5]);
5209 }
5210 else
5211 // For other shapes (wedges, pyramids), we do not currently
5212 // implement an optimized function.
5213 for (unsigned int l = 0; l < std::min(12U, cell.n_lines()); ++l)
5214 line_indices[l] = cell.line_index(l);
5215
5216 return line_indices;
5217 }
5218
5219
5220
5225 template <int dim, int spacedim>
5226 static std::array<unsigned char, 1>
5227 get_line_orientations_of_cell(const TriaAccessor<1, dim, spacedim> &)
5228 {
5230 return {};
5231 }
5232
5233
5234
5239 template <int dim, int spacedim>
5240 static std::array<unsigned char, 4>
5241 get_line_orientations_of_cell(const TriaAccessor<2, dim, spacedim> &cell)
5242 {
5243 // For 2d cells the access cell->line_orientation() is already
5244 // efficient
5245 std::array<unsigned char, 4> line_orientations = {};
5246 for (const unsigned int line : cell.line_indices())
5247 line_orientations[line] =
5248 cell.line_orientation(line) == true ?
5249 ReferenceCell::default_combined_face_orientation() :
5250 ReferenceCell::reversed_combined_line_orientation();
5251 return line_orientations;
5252 }
5253
5254
5255
5260 template <int dim, int spacedim>
5261 static std::array<unsigned char, 12>
5262 get_line_orientations_of_cell(const TriaAccessor<3, dim, spacedim> &cell)
5263 {
5264 std::array<unsigned char, 12> line_orientations = {};
5265
5266 // For hexahedra, the classical access via quads -> lines is too
5267 // inefficient. Unroll this code here to allow the compiler to inline
5268 // the necessary functions.
5269 const auto ref_cell = cell.reference_cell();
5270 if (ref_cell == ReferenceCells::Hexahedron)
5271 {
5272 for (unsigned int f = 4; f < 6; ++f)
5273 {
5274 const unsigned char orientation =
5275 cell.get_triangulation()
5276 .levels[cell.level()]
5277 ->face_orientations.get_combined_orientation(
5279
5280 // It might seem superfluous to spell out the four indices and
5281 // orientations that get later consumed by a for loop over
5282 // these four elements; however, for the compiler it is easier
5283 // to inline the statement of standard_to_real_face_line()
5284 // when next to each other, as opposed to be interleaved with
5285 // a line_index() call.
5286 const std::array<unsigned int, 4> my_indices{
5287 {ref_cell.standard_to_real_face_line(0, f, orientation),
5288 ref_cell.standard_to_real_face_line(1, f, orientation),
5289 ref_cell.standard_to_real_face_line(2, f, orientation),
5290 ref_cell.standard_to_real_face_line(3, f, orientation)}};
5291 const auto quad = cell.quad(f);
5292 const std::array<bool, 4> my_orientations{
5293 {ref_cell.standard_vs_true_line_orientation(
5294 0, f, orientation, quad->line_orientation(my_indices[0])),
5295 ref_cell.standard_vs_true_line_orientation(
5296 1, f, orientation, quad->line_orientation(my_indices[1])),
5297 ref_cell.standard_vs_true_line_orientation(
5298 2, f, orientation, quad->line_orientation(my_indices[2])),
5299 ref_cell.standard_vs_true_line_orientation(
5300 3,
5301 f,
5302 orientation,
5303 quad->line_orientation(my_indices[3]))}};
5304 for (unsigned int l = 0; l < 4; ++l)
5305 line_orientations[4 * (f - 4) + l] = my_orientations[l];
5306 }
5307 for (unsigned int f = 0; f < 2; ++f)
5308 {
5309 const unsigned char orientation =
5310 cell.get_triangulation()
5311 .levels[cell.level()]
5312 ->face_orientations.get_combined_orientation(
5314 const std::array<unsigned int, 2> my_indices{
5315 {ref_cell.standard_to_real_face_line(0, f, orientation),
5316 ref_cell.standard_to_real_face_line(1, f, orientation)}};
5317 const auto quad = cell.quad(f);
5318 const std::array<bool, 2> my_orientations{
5319 {ref_cell.standard_vs_true_line_orientation(
5320 0, f, orientation, quad->line_orientation(my_indices[0])),
5321 ref_cell.standard_vs_true_line_orientation(
5322 1,
5323 f,
5324 orientation,
5325 quad->line_orientation(my_indices[1]))}};
5326 line_orientations[8 + f] = my_orientations[0];
5327 line_orientations[10 + f] = my_orientations[1];
5328 }
5329 }
5330 else if (ref_cell == ReferenceCells::Tetrahedron)
5331 {
5332 std::array<unsigned int, 3> orientations{
5335 cell.combined_face_orientation(2)}};
5336 const std::array<unsigned int, 6> my_indices{
5337 {ref_cell.standard_to_real_face_line(0, 0, orientations[0]),
5338 ref_cell.standard_to_real_face_line(1, 0, orientations[0]),
5339 ref_cell.standard_to_real_face_line(2, 0, orientations[0]),
5340 ref_cell.standard_to_real_face_line(1, 1, orientations[1]),
5341 ref_cell.standard_to_real_face_line(2, 1, orientations[1]),
5342 ref_cell.standard_to_real_face_line(1, 2, orientations[2])}};
5343 line_orientations[0] = ref_cell.standard_vs_true_line_orientation(
5344 0,
5345 0,
5346 orientations[0],
5347 cell.quad(0)->line_orientation(my_indices[0]));
5348 line_orientations[1] = ref_cell.standard_vs_true_line_orientation(
5349 1,
5350 0,
5351 orientations[0],
5352 cell.quad(0)->line_orientation(my_indices[1]));
5353 line_orientations[2] = ref_cell.standard_vs_true_line_orientation(
5354 2,
5355 0,
5356 orientations[0],
5357 cell.quad(0)->line_orientation(my_indices[2]));
5358 line_orientations[3] = ref_cell.standard_vs_true_line_orientation(
5359 1,
5360 1,
5361 orientations[1],
5362 cell.quad(1)->line_orientation(my_indices[3]));
5363 line_orientations[4] = ref_cell.standard_vs_true_line_orientation(
5364 2,
5365 1,
5366 orientations[1],
5367 cell.quad(1)->line_orientation(my_indices[4]));
5368 line_orientations[5] = ref_cell.standard_vs_true_line_orientation(
5369 1,
5370 2,
5371 orientations[2],
5372 cell.quad(2)->line_orientation(my_indices[5]));
5373 }
5374 else
5375 // For other shapes (wedges, pyramids), we do not currently
5376 // implement an optimized function
5377 for (unsigned int l = 0; l < std::min(12U, cell.n_lines()); ++l)
5378 line_orientations[l] = cell.line_orientation(l);
5379
5380 return line_orientations;
5381 }
5382 };
5383 } // namespace TriaAccessorImplementation
5384} // namespace internal
5385
5386
5387
5388template <int structdim, int dim, int spacedim>
5390 const Triangulation<dim, spacedim> *parent,
5391 const int level,
5392 const int index,
5393 const AccessorData *local_data)
5394 : TriaAccessorBase<structdim, dim, spacedim>(parent, level, index, local_data)
5395{}
5396
5397
5398
5399template <int structdim, int dim, int spacedim>
5400inline bool
5402{
5403 Assert(this->state() == IteratorState::valid,
5404 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5405 *this));
5406 return this->objects().used[this->present_index];
5407}
5408
5409
5410
5411template <int structdim, int dim, int spacedim>
5414 const unsigned int i) const
5415{
5417 0,
5418 vertex_index(i));
5419}
5420
5421
5422
5423template <int structdim, int dim, int spacedim>
5424inline ReferenceCell
5426{
5427 if (structdim == 0)
5429 else if (structdim == 1)
5430 return ReferenceCells::Line;
5431 else if (structdim == dim)
5432 return this->tria->levels[this->present_level]
5433 ->reference_cell[this->present_index];
5434 else
5435 return this->tria->faces->get_quad_type(this->present_index);
5436}
5437
5438
5439
5440template <int structdim, int dim, int spacedim>
5441inline unsigned int
5443 const unsigned int corner) const
5444{
5445 AssertIndexRange(corner, this->n_vertices());
5446
5447 if (structdim == dim)
5448 {
5449 constexpr unsigned int max_vertices_per_cell = 1 << dim;
5450 const std::size_t my_index =
5451 static_cast<std::size_t>(this->present_index) * max_vertices_per_cell;
5452 AssertIndexRange(my_index + corner,
5453 this->tria->levels[this->present_level]
5454 ->cell_vertex_indices_cache.size());
5455 const unsigned int vertex_index =
5456 this->tria->levels[this->present_level]
5457 ->cell_vertex_indices_cache[my_index + corner];
5459 return vertex_index;
5460 }
5461 else
5462 return ::internal::TriaAccessorImplementation::Implementation::
5463 vertex_index(*this, corner);
5464}
5465
5466
5467
5468template <int structdim, int dim, int spacedim>
5469inline Point<spacedim> &
5470TriaAccessor<structdim, dim, spacedim>::vertex(const unsigned int i) const
5471{
5472 return const_cast<Point<spacedim> &>(this->tria->vertices[vertex_index(i)]);
5473}
5474
5475
5476
5477template <int structdim, int dim, int spacedim>
5478inline typename ::internal::TriangulationImplementation::
5479 Iterators<dim, spacedim>::line_iterator
5480 TriaAccessor<structdim, dim, spacedim>::line(const unsigned int i) const
5481{
5482 // checks happen in line_index
5483 return typename ::internal::TriangulationImplementation::
5484 Iterators<dim, spacedim>::line_iterator(this->tria, 0, line_index(i));
5485}
5486
5487
5488
5489template <int structdim, int dim, int spacedim>
5490inline unsigned int
5492{
5493 AssertIndexRange(i, this->n_lines());
5494
5495 return ::internal::TriaAccessorImplementation::Implementation::
5496 line_index(*this, i);
5497}
5498
5499
5500
5501template <int structdim, int dim, int spacedim>
5502inline typename ::internal::TriangulationImplementation::
5503 Iterators<dim, spacedim>::quad_iterator
5504 TriaAccessor<structdim, dim, spacedim>::quad(const unsigned int i) const
5505{
5506 // checks happen in quad_index
5507 return typename ::internal::TriangulationImplementation::
5508 Iterators<dim, spacedim>::quad_iterator(this->tria, 0, quad_index(i));
5509}
5510
5511
5512
5513template <int structdim, int dim, int spacedim>
5514inline unsigned int
5516{
5517 return ::internal::TriaAccessorImplementation::Implementation::
5518 quad_index(*this, i);
5519}
5520
5521
5522
5523template <int structdim, int dim, int spacedim>
5524inline unsigned char
5526 const unsigned int face) const
5527{
5529 AssertIndexRange(face, n_faces());
5530 Assert(structdim == dim,
5531 ExcMessage("This function can only be used on objects "
5532 "that are cells, but not on faces or edges "
5533 "that bound cells."));
5534 // work around a bogus GCC-9 warning which considers face unused except in 3d
5535 (void)face;
5536
5537 if constexpr (structdim == 1)
5539 else if constexpr (structdim == 2)
5540 return this->line_orientation(face) == true ?
5542 ReferenceCell::reversed_combined_line_orientation();
5543 else
5544 return this->tria->levels[this->present_level]
5545 ->face_orientations.get_combined_orientation(
5546 this->present_index * GeometryInfo<structdim>::faces_per_cell + face);
5547}
5548
5549
5550
5551template <int structdim, int dim, int spacedim>
5552inline bool
5554 const unsigned int face) const
5555{
5557 AssertIndexRange(face, n_faces());
5558 Assert(structdim == dim,
5559 ExcMessage("This function can only be used on objects "
5560 "that are cells, but not on faces or edges "
5561 "that bound cells."));
5562 // work around a bogus GCC-9 warning which considers face unused in 1d
5563 (void)face;
5564
5565 if constexpr (structdim == 1)
5566 // in 1d 'faces' are vertices and those are always consistently oriented
5567 return true;
5568 else if constexpr (structdim == 2)
5569 return this->line_orientation(face);
5570 else
5571 return this->tria->levels[this->present_level]
5572 ->face_orientations.get_orientation(
5573 this->present_index * GeometryInfo<structdim>::faces_per_cell + face);
5574}
5575
5576
5577
5578template <int structdim, int dim, int spacedim>
5579inline bool
5580TriaAccessor<structdim, dim, spacedim>::face_flip(const unsigned int face) const
5581{
5583 Assert(structdim == dim,
5584 ExcMessage("This function can only be used on objects "
5585 "that are cells, but not on faces or edges "
5586 "that bound cells."));
5587 AssertIndexRange(face, n_faces());
5588 // work around a bogus GCC-9 warning which considers face unused except in 3d
5589 (void)face;
5590
5591 if constexpr (structdim == 3)
5592 return this->tria->levels[this->present_level]->face_orientations.get_flip(
5593 this->present_index * GeometryInfo<3>::faces_per_cell + face);
5594 else
5595 // In 1d and 2d, face_flip is always false as faces can only be
5596 // 'flipped' in 3d.
5597 return false;
5598}
5599
5600
5601template <int structdim, int dim, int spacedim>
5602inline bool
5604 const unsigned int face) const
5605{
5607 Assert(structdim == dim,
5608 ExcMessage("This function can only be used on objects "
5609 "that are cells, but not on faces or edges "
5610 "that bound cells."));
5611 AssertIndexRange(face, n_faces());
5612 // work around a bogus GCC-9 warning which considers face unused except in 3d
5613 (void)face;
5614
5615 if constexpr (structdim == 3)
5616 return this->tria->levels[this->present_level]
5617 ->face_orientations.get_rotation(
5618 this->present_index * GeometryInfo<3>::faces_per_cell + face);
5619 else
5620 // In 1d and 2d, face_rotation is always false as faces can only be
5621 // 'rotated' in 3d.
5622 return false;
5623}
5624
5625
5626
5627template <int structdim, int dim, int spacedim>
5628inline bool
5630 const unsigned int line) const
5631{
5633 AssertIndexRange(line, this->n_lines());
5634 // work around a bogus GCC-9 warning which considers line unused in 1d
5635 (void)line;
5636
5637 if constexpr (structdim == 1)
5638 return true;
5639 else if constexpr (structdim == 2 && dim == 2)
5640 // lines in 2d are faces
5641 {
5642 // if all elements are quads (or if we have a very special consistently
5643 // oriented triangular mesh) then we do not store this array
5644 if (this->tria->levels[this->present_level]
5645 ->face_orientations.n_objects() == 0)
5646 {
5647 return true;
5648 }
5649 else
5650 {
5651 return this->tria->levels[this->present_level]
5652 ->face_orientations.get_orientation(
5653 this->present_index * GeometryInfo<structdim>::faces_per_cell +
5654 line);
5655 }
5656 }
5657 else if constexpr (structdim == 2 && dim == 3)
5658 {
5659 // line orientations in 3d are stored in their own array
5660 Assert(this->present_index * GeometryInfo<3>::lines_per_face + line <
5661 this->tria->faces->quads_line_orientations.size(),
5663 return this->tria->faces->quads_line_orientations
5664 [this->present_index * GeometryInfo<3>::lines_per_face + line];
5665 }
5666 else if constexpr (structdim == 3 && dim == 3)
5667 {
5668 const auto reference_cell = this->reference_cell();
5669 // First pick a face on which this line is a part of, and the
5670 // index of the line within.
5671 const auto [face_index, line_index] =
5672 reference_cell.standard_line_to_face_and_line_index(line);
5673 const auto line_within_face_index =
5674 reference_cell.standard_to_real_face_line(
5675 line_index, face_index, this->combined_face_orientation(face_index));
5676
5677 // Then query how that line is oriented within that face:
5678 return reference_cell.standard_vs_true_line_orientation(
5679 line_index,
5680 face_index,
5681 this->combined_face_orientation(face_index),
5682 this->quad(face_index)->line_orientation(line_within_face_index));
5683 }
5684 else
5685 {
5687 return false;
5688 }
5689}
5690
5691
5692
5693template <int structdim, int dim, int spacedim>
5694inline void
5696 const unsigned int line,
5697 const bool value) const
5698{
5700 AssertIndexRange(line, this->n_lines());
5701
5702 ::internal::TriaAccessorImplementation::Implementation::
5703 set_line_orientation(*this, line, value);
5704}
5705
5706
5707
5708template <int structdim, int dim, int spacedim>
5709inline void
5711 const unsigned int face,
5712 const unsigned char combined_orientation) const
5713{
5715 AssertIndexRange(face, this->n_faces());
5716
5717 ::internal::TriaAccessorImplementation::Implementation::
5718 set_combined_face_orientation(*this, face, combined_orientation);
5719}
5720
5721
5722
5723template <int structdim, int dim, int spacedim>
5724void
5726{
5727 Assert(this->state() == IteratorState::valid,
5728 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5729 *this));
5730 this->objects().used[this->present_index] = true;
5731}
5732
5733
5734
5735template <int structdim, int dim, int spacedim>
5736void
5738{
5739 Assert(this->state() == IteratorState::valid,
5740 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5741 *this));
5742 this->objects().used[this->present_index] = false;
5743}
5744
5745
5746template <int structdim, int dim, int spacedim>
5747int
5749{
5751 AssertIndexRange(i, n_children());
5752
5753 // each set of two children are stored
5754 // consecutively, so we only have to find
5755 // the location of the set of children
5756 const unsigned int n_sets_of_two =
5758 return this->objects().children[n_sets_of_two * this->present_index + i / 2] +
5759 i % 2;
5760}
5761
5762
5763
5764template <int structdim, int dim, int spacedim>
5765int
5767 const unsigned int i) const
5768{
5770
5771 switch (structdim)
5772 {
5773 case 1:
5774 return child_index(i);
5775 case 2:
5776 {
5777 const RefinementCase<2> this_refinement_case(
5778 static_cast<std::uint8_t>(refinement_case()));
5779
5780 Assert(this_refinement_case != RefinementCase<2>::no_refinement,
5782
5783 if (this_refinement_case == RefinementCase<2>::cut_xy)
5784 return child_index(i);
5785 else if ((this_refinement_case == RefinementCase<2>::cut_x) &&
5786 (child(i % 2)->refinement_case() ==
5788 return child(i % 2)->child_index(i / 2);
5789 else if ((this_refinement_case == RefinementCase<2>::cut_y) &&
5790 (child(i / 2)->refinement_case() ==
5792 return child(i / 2)->child_index(i % 2);
5793 else
5794 Assert(
5795 false,
5796 ExcMessage(
5797 "This cell has no grandchildren equivalent to isotropic refinement"));
5798 break;
5799 }
5800
5801 case 3:
5803 }
5804 return -1;
5805}
5806
5807
5808
5809template <int structdim, int dim, int spacedim>
5812{
5813 Assert(this->state() == IteratorState::valid,
5814 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5815 *this));
5816
5817 switch (structdim)
5818 {
5819 case 1:
5821 this->objects().children[this->present_index] != -1 ?
5822 // cast the branches
5823 // here first to uchar
5824 // and then (above) to
5825 // RefinementCase<structdim>
5826 // so that the
5827 // conversion is valid
5828 // even for the case
5829 // structdim>1 (for
5830 // which this part of
5831 // the code is dead
5832 // anyway)
5833 static_cast<std::uint8_t>(RefinementCase<1>::cut_x) :
5834 static_cast<std::uint8_t>(RefinementCase<1>::no_refinement)));
5835
5836 default:
5837 Assert(static_cast<unsigned int>(this->present_index) <
5838 this->objects().refinement_cases.size(),
5839 ExcIndexRange(this->present_index,
5840 0,
5841 this->objects().refinement_cases.size()));
5842
5843 return (static_cast<RefinementCase<structdim>>(
5844 this->objects().refinement_cases[this->present_index]));
5845 }
5846}
5847
5848
5849
5850template <int structdim, int dim, int spacedim>
5852TriaAccessor<structdim, dim, spacedim>::child(const unsigned int i) const
5853
5854{
5855 // checking of 'i' happens in child_index
5857 this->tria, (dim == structdim ? this->level() + 1 : 0), child_index(i));
5858
5859 Assert((q.state() == IteratorState::past_the_end) || q->used(),
5861
5862 return q;
5863}
5864
5865
5866
5867template <int structdim, int dim, int spacedim>
5868inline unsigned int
5871{
5872 const auto n_children = this->n_children();
5873 for (unsigned int child_n = 0; child_n < n_children; ++child_n)
5874 if (this->child(child_n) == child)
5875 return child_n;
5876
5877 Assert(false,
5878 ExcMessage("The given child is not a child of the current object."));
5880}
5881
5882
5883
5884template <int structdim, int dim, int spacedim>
5887 const unsigned int i) const
5888{
5889 // checking of 'i' happens in child() or
5890 // child_index() called below
5891 switch (structdim)
5892 {
5893 case 1:
5894 // no anisotropic refinement in 1d
5895 return child(i);
5896
5897 case 2:
5898 {
5899 const RefinementCase<2> this_refinement_case(
5900 static_cast<std::uint8_t>(refinement_case()));
5901
5902 Assert(this_refinement_case != RefinementCase<2>::no_refinement,
5904
5905 if (this_refinement_case == RefinementCase<2>::cut_xy)
5906 return child(i);
5907 else if ((this_refinement_case == RefinementCase<2>::cut_x) &&
5908 (child(i % 2)->refinement_case() ==
5910 return child(i % 2)->child(i / 2);
5911 else if ((this_refinement_case == RefinementCase<2>::cut_y) &&
5912 (child(i / 2)->refinement_case() ==
5914 return child(i / 2)->child(i % 2);
5915 else
5916 Assert(
5917 false,
5918 ExcMessage(
5919 "This cell has no grandchildren equivalent to isotropic refinement"));
5920 break;
5921 }
5922
5923 default:
5925 }
5926 // we don't get here but have to return
5927 // something...
5928 return child(0);
5929}
5930
5931
5932
5933template <int structdim, int dim, int spacedim>
5934inline bool
5936{
5937 Assert(this->state() == IteratorState::valid,
5938 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5939 *this));
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 return (this->objects().children[n_sets_of_two * this->present_index] != -1);
5947}
5948
5949
5950
5951template <int structdim, int dim, int spacedim>
5952inline unsigned int
5954{
5955 Assert(this->state() == IteratorState::valid,
5956 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5957 *this));
5961 else
5962 return GeometryInfo<structdim>::n_children(refinement_case());
5963}
5964
5965
5966
5967template <int structdim, int dim, int spacedim>
5968inline void
5970 const RefinementCase<structdim> &refinement_case) const
5971{
5972 Assert(this->state() == IteratorState::valid,
5973 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5974 *this));
5975 Assert(static_cast<unsigned int>(this->present_index) <
5976 this->objects().refinement_cases.size(),
5977 ExcIndexRange(this->present_index,
5978 0,
5979 this->objects().refinement_cases.size()));
5980
5981 this->objects().refinement_cases[this->present_index] = refinement_case;
5982}
5983
5984
5985template <int structdim, int dim, int spacedim>
5986inline void
5988{
5989 Assert(this->state() == IteratorState::valid,
5990 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5991 *this));
5992 Assert(static_cast<unsigned int>(this->present_index) <
5993 this->objects().refinement_cases.size(),
5994 ExcIndexRange(this->present_index,
5995 0,
5996 this->objects().refinement_cases.size()));
5997
5998 this->objects().refinement_cases[this->present_index] =
6000}
6001
6002
6003
6004template <int structdim, int dim, int spacedim>
6005void
6007 const int index) const
6008{
6011
6012 // each set of two children are stored
6013 // consecutively, so we only have to find
6014 // the location of the set of children
6015 const unsigned int n_sets_of_two =
6017
6018 Assert(
6019 // clearing the child index for a cell
6020 (index == -1) ||
6021 // if setting the child index for the i'th child (with i==0),
6022 // then the index must be a non-negative number
6023 (i == 0 && !this->has_children() && (index >= 0)) ||
6024 // if setting the child index for the i'th child (with i>0),
6025 // then the previously stored index must be the invalid
6026 // index
6027 (i > 0 && this->has_children() && (index >= 0) &&
6028 this->objects().children[n_sets_of_two * this->present_index + i / 2] ==
6029 -1),
6031
6032 this->objects().children[n_sets_of_two * this->present_index + i / 2] = index;
6033}
6034
6035
6036
6037template <int structdim, int dim, int spacedim>
6038void
6040{
6041 // each set of two children are stored
6042 // consecutively, so we only have to find
6043 // the location of the set of children
6044 const unsigned int n_sets_of_two =
6046
6047 for (unsigned int i = 0; i < n_sets_of_two; ++i)
6048 set_children(2 * i, -1);
6049}
6050
6051
6052
6053template <int structdim, int dim, int spacedim>
6054inline bool
6056{
6058 return this->objects().user_flags[this->present_index];
6059}
6060
6061
6062
6063template <int structdim, int dim, int spacedim>
6064inline void
6066{
6068 this->objects().user_flags[this->present_index] = true;
6069}
6070
6071
6072
6073template <int structdim, int dim, int spacedim>
6074inline void
6076{
6078 this->objects().user_flags[this->present_index] = false;
6079}
6080
6081
6082
6083template <int structdim, int dim, int spacedim>
6084void
6086{
6087 set_user_flag();
6088
6089 if (this->has_children())
6090 for (unsigned int c = 0; c < this->n_children(); ++c)
6091 this->child(c)->recursively_set_user_flag();
6092}
6093
6094
6095
6096template <int structdim, int dim, int spacedim>
6097void
6099{
6100 clear_user_flag();
6101
6102 if (this->has_children())
6103 for (unsigned int c = 0; c < this->n_children(); ++c)
6104 this->child(c)->recursively_clear_user_flag();
6105}
6106
6107
6108
6109template <int structdim, int dim, int spacedim>
6110void
6112{
6114 this->objects().clear_user_data(this->present_index);
6115}
6116
6117
6118
6119template <int structdim, int dim, int spacedim>
6120void
6122{
6124 this->objects().user_pointer(this->present_index) = p;
6125}
6126
6127
6128
6129template <int structdim, int dim, int spacedim>
6130void
6132{
6134 this->objects().user_pointer(this->present_index) = nullptr;
6135}
6136
6137
6138
6139template <int structdim, int dim, int spacedim>
6140void *
6142{
6144 return this->objects().user_pointer(this->present_index);
6145}
6146
6147
6148
6149template <int structdim, int dim, int spacedim>
6150void
6152 void *p) const
6153{
6154 set_user_pointer(p);
6155
6156 if (this->has_children())
6157 for (unsigned int c = 0; c < this->n_children(); ++c)
6158 this->child(c)->recursively_set_user_pointer(p);
6159}
6160
6161
6162
6163template <int structdim, int dim, int spacedim>
6164void
6166{
6167 clear_user_pointer();
6168
6169 if (this->has_children())
6170 for (unsigned int c = 0; c < this->n_children(); ++c)
6171 this->child(c)->recursively_clear_user_pointer();
6172}
6173
6174
6175
6176template <int structdim, int dim, int spacedim>
6177void
6179 const unsigned int p) const
6180{
6182 this->objects().user_index(this->present_index) = p;
6183}
6184
6185
6186
6187template <int structdim, int dim, int spacedim>
6188void
6190{
6192 this->objects().user_index(this->present_index) = 0;
6193}
6194
6195
6196
6197template <int structdim, int dim, int spacedim>
6198unsigned int
6200{
6202 return this->objects().user_index(this->present_index);
6203}
6204
6205
6206
6207template <int structdim, int dim, int spacedim>
6208void
6210 const unsigned int p) const
6211{
6212 set_user_index(p);
6213
6214 if (this->has_children())
6215 for (unsigned int c = 0; c < this->n_children(); ++c)
6216 this->child(c)->recursively_set_user_index(p);
6217}
6218
6219
6220
6221template <int structdim, int dim, int spacedim>
6222void
6224{
6225 clear_user_index();
6226
6227 if (this->has_children())
6228 for (unsigned int c = 0; c < this->n_children(); ++c)
6229 this->child(c)->recursively_clear_user_index();
6230}
6231
6232
6233
6234template <int structdim, int dim, int spacedim>
6235inline unsigned int
6237{
6238 if (!this->has_children())
6239 return 0;
6240
6241 unsigned int max_depth = 1;
6242 for (unsigned int c = 0; c < n_children(); ++c)
6243 max_depth = std::max(max_depth, child(c)->max_refinement_depth() + 1);
6244 return max_depth;
6245}
6246
6247
6248
6249template <int structdim, int dim, int spacedim>
6250unsigned int
6252{
6253 if (!this->has_children())
6254 return 1;
6255 else
6256 {
6257 unsigned int sum = 0;
6258 for (unsigned int c = 0; c < n_children(); ++c)
6259 sum += this->child(c)->n_active_descendants();
6260 return sum;
6261 }
6262}
6263
6264
6265
6266template <int structdim, int dim, int spacedim>
6269{
6270 Assert(structdim < dim, ExcImpossibleInDim(dim));
6272
6273 return this->objects()
6274 .boundary_or_material_id[this->present_index]
6275 .boundary_id;
6276}
6277
6278
6279
6280template <int structdim, int dim, int spacedim>
6281void
6283 const types::boundary_id boundary_ind) const
6284{
6285 Assert(structdim < dim, ExcImpossibleInDim(dim));
6288 ExcMessage("You are trying to set the boundary_id to an invalid "
6289 "value (numbers::internal_face_boundary_id is reserved)."));
6290 Assert(this->at_boundary(),
6291 ExcMessage("You are trying to set the boundary_id of an "
6292 "internal object, which is not allowed!"));
6293
6294 this->objects().boundary_or_material_id[this->present_index].boundary_id =
6295 boundary_ind;
6296}
6297
6298
6299
6300template <int structdim, int dim, int spacedim>
6301void
6303 const types::boundary_id boundary_ind) const
6304{
6305 Assert(structdim < dim, ExcImpossibleInDim(dim));
6307
6308 this->objects().boundary_or_material_id[this->present_index].boundary_id =
6309 boundary_ind;
6310}
6311
6312
6313
6314template <int structdim, int dim, int spacedim>
6315void
6317 const types::boundary_id boundary_ind) const
6318{
6319 set_boundary_id(boundary_ind);
6320
6321 switch (structdim)
6322 {
6323 case 1:
6324 // 1d objects have no sub-objects
6325 // where we have to do anything
6326 break;
6327
6328 case 2:
6329 // for boundary quads also set
6330 // boundary_id of bounding lines
6331 for (unsigned int i = 0; i < this->n_lines(); ++i)
6332 this->line(i)->set_boundary_id(boundary_ind);
6333 break;
6334
6335 default:
6337 }
6338}
6339
6340
6341
6342template <int structdim, int dim, int spacedim>
6343bool
6345{
6346 // error checking is done
6347 // in boundary_id()
6349}
6350
6351
6352
6353template <int structdim, int dim, int spacedim>
6356{
6358 return this->tria->get_manifold(this->manifold_id());
6359}
6360
6361
6362template <int structdim, int dim, int spacedim>
6365{
6367
6368 return this->objects().manifold_id[this->present_index];
6369}
6370
6371
6372
6373template <int structdim, int dim, int spacedim>
6374void
6376 const types::manifold_id manifold_ind) const
6377{
6379
6380 this->objects().manifold_id[this->present_index] = manifold_ind;
6381}
6382
6383
6384template <int structdim, int dim, int spacedim>
6385void
6387 const types::manifold_id manifold_ind) const
6388{
6389 set_manifold_id(manifold_ind);
6390
6391 if (this->has_children())
6392 for (unsigned int c = 0; c < this->n_children(); ++c)
6393 this->child(c)->set_all_manifold_ids(manifold_ind);
6394
6395 switch (structdim)
6396 {
6397 case 1:
6398 if (dim == 1)
6399 {
6400 (*this->tria->vertex_to_manifold_id_map_1d)[vertex_index(0)] =
6401 manifold_ind;
6402 (*this->tria->vertex_to_manifold_id_map_1d)[vertex_index(1)] =
6403 manifold_ind;
6404 }
6405 break;
6406
6407 case 2:
6408 // for quads/simplices also set manifold_id of bounding lines
6409 for (unsigned int i = 0; i < this->n_lines(); ++i)
6410 this->line(i)->set_manifold_id(manifold_ind);
6411 break;
6412 default:
6414 }
6415}
6416
6417
6418
6419template <int structdim, int dim, int spacedim>
6420double
6422{
6423 boost::container::small_vector<Point<spacedim>,
6425 vertices(this->n_vertices());
6426
6427 for (unsigned int v = 0; v < vertices.size(); ++v)
6428 vertices[v] = this->vertex(v);
6429
6430 return internal::TriaAccessorImplementation::diameter<structdim, spacedim>(
6431 vertices);
6432}
6433
6434
6435
6436template <int dim, int spacedim>
6437double
6439 const Mapping<dim, spacedim> &mapping) const
6440{
6441 return internal::TriaAccessorImplementation::diameter<dim, spacedim>(
6443 this->tria, this->level(), this->index())));
6444}
6445
6446
6447
6448template <int structdim, int dim, int spacedim>
6449std::pair<Point<spacedim>, double>
6451{
6452 // If the object is one dimensional,
6453 // the enclosing ball is the initial iterate
6454 // i.e., the ball's center and diameter are
6455 // the center and the diameter of the object.
6456 if (structdim == 1)
6457 return std::make_pair((this->vertex(1) + this->vertex(0)) * 0.5,
6458 (this->vertex(1) - this->vertex(0)).norm() * 0.5);
6459
6460 // The list is_initial_guess_vertex contains bool values and has
6461 // the same size as the number of vertices per object.
6462 // The entries of is_initial_guess_vertex are set true only for those
6463 // two vertices corresponding to the largest diagonal which is being used
6464 // to construct the initial ball.
6465 // We employ this mask to skip these two vertices while enlarging the ball.
6466 std::vector<bool> is_initial_guess_vertex(this->n_vertices());
6467
6468 // First let all the vertices be outside
6469 std::fill(is_initial_guess_vertex.begin(),
6470 is_initial_guess_vertex.end(),
6471 false);
6472
6473 // Get an initial guess by looking at the largest diagonal
6474 Point<spacedim> center;
6475 double radius = 0;
6476
6477 switch (structdim)
6478 {
6479 case 2:
6480 {
6481 const Point<spacedim> p30(this->vertex(3) - this->vertex(0));
6482 const Point<spacedim> p21(this->vertex(2) - this->vertex(1));
6483 if (p30.norm() > p21.norm())
6484 {
6485 center = this->vertex(0) + 0.5 * p30;
6486 radius = p30.norm() / 2.;
6487 is_initial_guess_vertex[3] = true;
6488 is_initial_guess_vertex[0] = true;
6489 }
6490 else
6491 {
6492 center = this->vertex(1) + 0.5 * p21;
6493 radius = p21.norm() / 2.;
6494 is_initial_guess_vertex[2] = true;
6495 is_initial_guess_vertex[1] = true;
6496 }
6497 break;
6498 }
6499 case 3:
6500 {
6501 const Point<spacedim> p70(this->vertex(7) - this->vertex(0));
6502 const Point<spacedim> p61(this->vertex(6) - this->vertex(1));
6503 const Point<spacedim> p25(this->vertex(2) - this->vertex(5));
6504 const Point<spacedim> p34(this->vertex(3) - this->vertex(4));
6505 const std::vector<double> diagonals = {p70.norm(),
6506 p61.norm(),
6507 p25.norm(),
6508 p34.norm()};
6509 const std::vector<double>::const_iterator it =
6510 std::max_element(diagonals.begin(), diagonals.end());
6511 if (it == diagonals.begin())
6512 {
6513 center = this->vertex(0) + 0.5 * p70;
6514 is_initial_guess_vertex[7] = true;
6515 is_initial_guess_vertex[0] = true;
6516 }
6517 else if (it == diagonals.begin() + 1)
6518 {
6519 center = this->vertex(1) + 0.5 * p61;
6520 is_initial_guess_vertex[6] = true;
6521 is_initial_guess_vertex[1] = true;
6522 }
6523 else if (it == diagonals.begin() + 2)
6524 {
6525 center = this->vertex(5) + 0.5 * p25;
6526 is_initial_guess_vertex[2] = true;
6527 is_initial_guess_vertex[5] = true;
6528 }
6529 else
6530 {
6531 center = this->vertex(4) + 0.5 * p34;
6532 is_initial_guess_vertex[3] = true;
6533 is_initial_guess_vertex[4] = true;
6534 }
6535 radius = *it * 0.5;
6536 break;
6537 }
6538 default:
6540 return std::pair<Point<spacedim>, double>();
6541 }
6542
6543 // For each vertex that is found to be geometrically outside the ball
6544 // enlarge the ball so that the new ball contains both the previous ball
6545 // and the given vertex.
6546 for (const unsigned int v : this->vertex_indices())
6547 if (!is_initial_guess_vertex[v])
6548 {
6549 const double distance = center.distance(this->vertex(v));
6550 if (distance > radius)
6551 {
6552 // we found a vertex which is outside of the ball
6553 // extend it (move center and change radius)
6554 const Point<spacedim> pCV(center - this->vertex(v));
6555 radius = (distance + radius) * 0.5;
6556 center = this->vertex(v) + pCV * (radius / distance);
6557
6558 // Now the new ball constructed in this block
6559 // encloses the vertex (v) that was found to be geometrically
6560 // outside the old ball.
6561 }
6562 }
6563# ifdef DEBUG
6564 bool all_vertices_within_ball = true;
6565
6566 // Set all_vertices_within_ball false if any of the vertices of the object
6567 // are geometrically outside the ball
6568 for (const unsigned int v : this->vertex_indices())
6569 if (center.distance(this->vertex(v)) >
6570 radius + 100. * std::numeric_limits<double>::epsilon())
6571 {
6572 all_vertices_within_ball = false;
6573 break;
6574 }
6575 // If all the vertices are not within the ball throw error
6576 Assert(all_vertices_within_ball, ExcInternalError());
6577# endif
6578 return std::make_pair(center, radius);
6579}
6580
6581
6582template <int structdim, int dim, int spacedim>
6583double
6585{
6586 switch (structdim)
6587 {
6588 case 1:
6589 return (this->vertex(1) - this->vertex(0)).norm();
6590 case 2:
6591 case 3:
6592 {
6593 double min = std::numeric_limits<double>::max();
6594 for (const unsigned int i : this->vertex_indices())
6595 for (unsigned int j = i + 1; j < this->n_vertices(); ++j)
6596 min = std::min(min,
6597 (this->vertex(i) - this->vertex(j)) *
6598 (this->vertex(i) - this->vertex(j)));
6599 return std::sqrt(min);
6600 }
6601 default:
6603 return -1e10;
6604 }
6605}
6606
6607
6608template <int structdim, int dim, int spacedim>
6609bool
6612{
6613 // go through the vertices and check... The
6614 // cell is a translation of the previous
6615 // one in case the distance between the
6616 // individual vertices in the two cell is
6617 // the same for all the vertices. So do the
6618 // check by first getting the distance on
6619 // the first vertex, and then checking
6620 // whether all others have the same down to
6621 // rounding errors (we have to be careful
6622 // here because the calculation of the
6623 // displacement between one cell and the
6624 // next can already result in the loss of
6625 // one or two digits), so we choose 1e-12
6626 // times the distance between the zeroth
6627 // vertices here.
6628 bool is_translation = true;
6629 const Tensor<1, spacedim> dist = o->vertex(0) - this->vertex(0);
6630 const double tol_square = 1e-24 * dist.norm_square();
6631 for (unsigned int i = 1; i < this->n_vertices(); ++i)
6632 {
6633 const Tensor<1, spacedim> dist_new =
6634 (o->vertex(i) - this->vertex(i)) - dist;
6635 if (dist_new.norm_square() > tol_square)
6636 {
6637 is_translation = false;
6638 break;
6639 }
6640 }
6641 return is_translation;
6642}
6643
6644
6645
6646template <int structdim, int dim, int spacedim>
6647unsigned int
6649{
6650 return this->reference_cell().n_vertices();
6651}
6652
6653
6654
6655template <int structdim, int dim, int spacedim>
6656unsigned int
6658{
6659 return this->reference_cell().n_lines();
6660}
6661
6662
6663
6664template <int structdim, int dim, int spacedim>
6665unsigned int
6667{
6668 Assert(structdim == dim,
6669 ExcMessage("This function can only be used on objects "
6670 "that are cells, but not on faces or edges "
6671 "that bound cells."));
6672
6673 return this->reference_cell().n_faces();
6674}
6675
6676
6677
6678template <int structdim, int dim, int spacedim>
6681{
6682 return {0U, n_vertices()};
6683}
6684
6685
6686
6687template <int structdim, int dim, int spacedim>
6690{
6691 return {0U, n_lines()};
6692}
6693
6694
6695
6696template <int structdim, int dim, int spacedim>
6699{
6700 return {0U, n_faces()};
6701}
6702
6703
6704
6705/*----------------- Functions: TriaAccessor<0,dim,spacedim> -----------------*/
6706
6707template <int dim, int spacedim>
6709 const Triangulation<dim, spacedim> *tria,
6710 const unsigned int vertex_index)
6711 : tria(tria)
6712 , global_vertex_index(vertex_index)
6713{}
6714
6715
6716
6717template <int dim, int spacedim>
6719 const Triangulation<dim, spacedim> *tria,
6720 const int /*level*/,
6721 const int index,
6722 const AccessorData *)
6723 : tria(tria)
6725{}
6726
6727
6728
6729template <int dim, int spacedim>
6730template <int structdim2, int dim2, int spacedim2>
6733 : tria(nullptr)
6734 , global_vertex_index(numbers::invalid_unsigned_int)
6735{
6736 Assert(false, ExcImpossibleInDim(0));
6737}
6738
6739
6740
6741template <int dim, int spacedim>
6742template <int structdim2, int dim2, int spacedim2>
6745 : tria(nullptr)
6746 , global_vertex_index(numbers::invalid_unsigned_int)
6747{
6748 Assert(false, ExcImpossibleInDim(0));
6749}
6750
6751
6752
6753template <int dim, int spacedim>
6754inline void
6756{
6757 tria = t.tria;
6758 global_vertex_index = t.global_vertex_index;
6759}
6760
6761
6762
6763template <int dim, int spacedim>
6764inline bool
6766 const TriaAccessor<0, dim, spacedim> &other) const
6767{
6769
6770 return (global_vertex_index < other.global_vertex_index);
6771}
6772
6773
6774
6775template <int dim, int spacedim>
6778{
6779 if (global_vertex_index != numbers::invalid_unsigned_int)
6780 return IteratorState::valid;
6781 else
6783}
6784
6785
6786
6787template <int dim, int spacedim>
6788inline int
6790{
6791 return 0;
6792}
6793
6794
6795
6796template <int dim, int spacedim>
6797inline int
6799{
6800 return global_vertex_index;
6801}
6802
6803
6804
6805template <int dim, int spacedim>
6806inline const Triangulation<dim, spacedim> &
6808{
6809 return *tria;
6810}
6811
6812
6813
6814template <int dim, int spacedim>
6815inline void
6817{
6819 if (global_vertex_index >= tria->n_vertices())
6821}
6822
6823
6824
6825template <int dim, int spacedim>
6826inline void
6828{
6829 if (global_vertex_index != numbers::invalid_unsigned_int)
6830 {
6831 if (global_vertex_index != 0)
6833 else
6835 }
6836}
6837
6838
6839
6840template <int dim, int spacedim>
6841inline bool
6843{
6844 const bool result =
6845 ((tria == t.tria) && (global_vertex_index == t.global_vertex_index));
6846
6847 return result;
6848}
6849
6850
6851
6852template <int dim, int spacedim>
6853inline bool
6855{
6856 return !(*this == t);
6857}
6858
6859
6860
6861template <int dim, int spacedim>
6862inline unsigned int
6863TriaAccessor<0, dim, spacedim>::vertex_index(const unsigned int) const
6864{
6865 return global_vertex_index;
6866}
6867
6868
6869
6870template <int dim, int spacedim>
6871inline Point<spacedim> &
6872TriaAccessor<0, dim, spacedim>::vertex(const unsigned int) const
6873{
6874 return const_cast<Point<spacedim> &>(
6875 this->tria->vertices[global_vertex_index]);
6876}
6877
6878
6879
6880template <int dim, int spacedim>
6881inline typename ::internal::TriangulationImplementation::
6882 Iterators<dim, spacedim>::line_iterator
6883 TriaAccessor<0, dim, spacedim>::line(const unsigned int)
6884{
6885 return typename ::internal::TriangulationImplementation::
6886 Iterators<dim, spacedim>::line_iterator();
6887}
6888
6889
6890
6891template <int dim, int spacedim>
6892inline unsigned int
6894{
6895 Assert(false, ExcImpossibleInDim(0));
6897}
6898
6899
6900
6901template <int dim, int spacedim>
6902inline typename ::internal::TriangulationImplementation::
6903 Iterators<dim, spacedim>::quad_iterator
6904 TriaAccessor<0, dim, spacedim>::quad(const unsigned int)
6905{
6906 return typename ::internal::TriangulationImplementation::
6907 Iterators<dim, spacedim>::quad_iterator();
6908}
6909
6910
6911
6912template <int dim, int spacedim>
6913inline unsigned int
6915{
6916 Assert(false, ExcImpossibleInDim(0));
6918}
6919
6920
6921
6922template <int dim, int spacedim>
6923inline double
6925{
6926 return 0.;
6927}
6928
6929
6930
6931template <int dim, int spacedim>
6932inline double
6934{
6935 return 0.;
6936}
6937
6938
6939
6940template <int dim, int spacedim>
6941inline Point<spacedim>
6942TriaAccessor<0, dim, spacedim>::center(const bool, const bool) const
6943{
6944 return this->tria->vertices[global_vertex_index];
6945}
6946
6947
6948
6949template <int dim, int spacedim>
6950inline double
6952{
6953 return 0.;
6954}
6955
6956
6957
6958template <int dim, int spacedim>
6959inline unsigned char
6961 const unsigned int /*face*/)
6962{
6963 return 0;
6964}
6965
6966
6967
6968template <int dim, int spacedim>
6969inline bool
6970TriaAccessor<0, dim, spacedim>::face_orientation(const unsigned int /*face*/)
6971{
6972 return false;
6973}
6974
6975
6976
6977template <int dim, int spacedim>
6978inline bool
6979TriaAccessor<0, dim, spacedim>::face_flip(const unsigned int /*face*/)
6980{
6981 return false;
6982}
6983
6984
6985
6986template <int dim, int spacedim>
6987inline bool
6988TriaAccessor<0, dim, spacedim>::face_rotation(const unsigned int /*face*/)
6989{
6990 return false;
6991}
6992
6993
6994
6995template <int dim, int spacedim>
6996inline bool
6997TriaAccessor<0, dim, spacedim>::line_orientation(const unsigned int /*line*/)
6998{
6999 return false;
7000}
7001
7002
7003
7004template <int dim, int spacedim>
7005inline bool
7007{
7008 return false;
7009}
7010
7011
7012
7013template <int dim, int spacedim>
7014inline unsigned int
7016{
7017 return 0;
7018}
7019
7020
7021
7022template <int dim, int spacedim>
7023inline unsigned int
7025{
7026 return 0;
7027}
7028
7029
7030
7031template <int dim, int spacedim>
7032inline unsigned int
7034{
7035 return 0;
7036}
7037
7038
7039
7040template <int dim, int spacedim>
7041inline unsigned int
7044{
7046}
7047
7048
7049
7050template <int dim, int spacedim>
7052TriaAccessor<0, dim, spacedim>::child(const unsigned int)
7053{
7055}
7056
7057
7058
7059template <int dim, int spacedim>
7062{
7064}
7065
7066
7067
7068template <int dim, int spacedim>
7069inline RefinementCase<0>
7071{
7073}
7074
7075
7076
7077template <int dim, int spacedim>
7078inline int
7080{
7081 return -1;
7082}
7083
7084
7085
7086template <int dim, int spacedim>
7087inline int
7089{
7090 return -1;
7091}
7092
7093
7094
7095template <int dim, int spacedim>
7096inline bool
7098{
7099 return tria->vertex_used(global_vertex_index);
7100}
7101
7102
7103
7104/*------------------- Functions: TriaAccessor<0,1,spacedim> -----------------*/
7105
7106template <int spacedim>
7108 const Triangulation<1, spacedim> *tria,
7109 const VertexKind vertex_kind,
7110 const unsigned int vertex_index)
7111 : tria(tria)
7112 , vertex_kind(vertex_kind)
7113 , global_vertex_index(vertex_index)
7114{}
7115
7116
7117
7118template <int spacedim>
7120 const Triangulation<1, spacedim> *tria,
7121 const int level,
7122 const int index,
7123 const AccessorData *)
7124 : tria(tria)
7125 , vertex_kind(interior_vertex)
7126 , global_vertex_index(numbers::invalid_unsigned_int)
7127{
7128 // in general, calling this constructor should yield an error -- users should
7129 // instead call the one immediately above. however, if you create something
7130 // like Triangulation<1>::face_iterator() then this calls the default
7131 // constructor of the iterator which calls the accessor with argument list
7132 // (0,-2,-2,0), so in this particular case accept this call and create an
7133 // object that corresponds to the default constructed (invalid) vertex
7134 // accessor
7135 (void)level;
7136 (void)index;
7137 Assert((level == -2) && (index == -2),
7138 ExcMessage(
7139 "This constructor can not be called for face iterators in 1d, "
7140 "except to default-construct iterator objects."));
7141}
7142
7143
7144
7145template <int spacedim>
7146template <int structdim2, int dim2, int spacedim2>
7149 : tria(nullptr)
7150 , vertex_kind(interior_vertex)
7151 , global_vertex_index(numbers::invalid_unsigned_int)
7152{
7153 Assert(false, ExcImpossibleInDim(0));
7154}
7155
7156
7157
7158template <int spacedim>
7159template <int structdim2, int dim2, int spacedim2>
7162 : tria(nullptr)
7163 , vertex_kind(interior_vertex)
7164 , global_vertex_index(numbers::invalid_unsigned_int)
7165{
7166 Assert(false, ExcImpossibleInDim(0));
7167}
7168
7169
7170
7171template <int spacedim>
7172inline void
7174{
7175 tria = t.tria;
7176 vertex_kind = t.vertex_kind;
7177 global_vertex_index = t.global_vertex_index;
7178}
7179
7180
7181
7182template <int spacedim>
7183inline void
7186{
7187 // We cannot convert from TriaAccessorBase to
7188 // TriaAccessor<0,1,spacedim> because the latter is not derived from
7189 // the former. We should never get here.
7191}
7192
7193
7194
7195template <int spacedim>
7196inline bool
7198 const TriaAccessor<0, 1, spacedim> &other) const
7199{
7201
7202 return (global_vertex_index < other.global_vertex_index);
7203}
7204
7205
7206
7207template <int spacedim>
7210{
7211 return IteratorState::valid;
7212}
7213
7214
7215template <int spacedim>
7216inline int
7218{
7219 return 0;
7220}
7221
7222
7223
7224template <int spacedim>
7225inline int
7227{
7228 return global_vertex_index;
7229}
7230
7231
7232
7233template <int spacedim>
7234inline const Triangulation<1, spacedim> &
7236{
7237 return *tria;
7238}
7239
7240
7241
7242template <int spacedim>
7243inline void
7245{
7247}
7248
7249
7250template <int spacedim>
7251inline void
7253{
7255}
7256
7257
7258
7259template <int spacedim>
7260inline bool
7262{
7263 const bool result =
7264 ((tria == t.tria) && (global_vertex_index == t.global_vertex_index));
7265 // if we point to the same vertex,
7266 // make sure we know the same about
7267 // it
7268 if (result == true)
7269 Assert(vertex_kind == t.vertex_kind, ExcInternalError());
7270
7271 return result;
7272}
7273
7274
7275
7276template <int spacedim>
7277inline bool
7279{
7280 return !(*this == t);
7281}
7282
7283
7284
7285template <int spacedim>
7286inline unsigned int
7287TriaAccessor<0, 1, spacedim>::vertex_index(const unsigned int i) const
7288{
7289 AssertIndexRange(i, 1);
7290 (void)i;
7291 return global_vertex_index;
7292}
7293
7294
7295
7296template <int spacedim>
7297inline Point<spacedim> &
7298TriaAccessor<0, 1, spacedim>::vertex(const unsigned int i) const
7299{
7300 AssertIndexRange(i, 1);
7301 (void)i;
7302 return const_cast<Point<spacedim> &>(
7303 this->tria->vertices[global_vertex_index]);
7304}
7305
7306
7307
7308template <int spacedim>
7309inline Point<spacedim>
7311{
7312 return this->tria->vertices[global_vertex_index];
7313}
7314
7315
7316
7317template <int spacedim>
7318inline typename ::internal::TriangulationImplementation::
7319 Iterators<1, spacedim>::line_iterator
7320 TriaAccessor<0, 1, spacedim>::line(const unsigned int)
7321{
7322 return {};
7323}
7324
7325
7326template <int spacedim>
7327inline unsigned int
7329{
7330 Assert(false, ExcImpossibleInDim(0));
7332}
7333
7334
7335template <int spacedim>
7336inline typename ::internal::TriangulationImplementation::
7337 Iterators<1, spacedim>::quad_iterator
7338 TriaAccessor<0, 1, spacedim>::quad(const unsigned int)
7339{
7340 return {};
7341}
7342
7343
7344
7345template <int spacedim>
7346inline unsigned int
7348{
7349 Assert(false, ExcImpossibleInDim(0));
7351}
7352
7353
7354template <int spacedim>
7355inline bool
7357{
7358 return vertex_kind != interior_vertex;
7359}
7360
7361
7362template <int spacedim>
7363inline types::boundary_id
7365{
7366 switch (vertex_kind)
7367 {
7368 case left_vertex:
7369 case right_vertex:
7370 {
7372 this->vertex_index()) !=
7373 tria->vertex_to_boundary_id_map_1d->end(),
7375
7376 return (*tria->vertex_to_boundary_id_map_1d)[this->vertex_index()];
7377 }
7378
7379 default:
7381 }
7382}
7383
7384
7385
7386template <int spacedim>
7387inline const Manifold<1, spacedim> &
7389{
7390 return this->tria->get_manifold(this->manifold_id());
7391}
7392
7393
7394
7395template <int spacedim>
7396inline types::manifold_id
7398{
7399 if (tria->vertex_to_manifold_id_map_1d->find(this->vertex_index()) !=
7400 tria->vertex_to_manifold_id_map_1d->end())
7401 return (*tria->vertex_to_manifold_id_map_1d)[this->vertex_index()];
7402 else
7404}
7405
7406
7407template <int spacedim>
7408inline unsigned char
7410 const unsigned int /*face*/)
7411{
7412 return 0;
7413}
7414
7415
7416template <int spacedim>
7417inline bool
7418TriaAccessor<0, 1, spacedim>::face_orientation(const unsigned int /*face*/)
7419{
7420 return false;
7421}
7422
7423
7424
7425template <int spacedim>
7426inline bool
7427TriaAccessor<0, 1, spacedim>::face_flip(const unsigned int /*face*/)
7428{
7429 return false;
7430}
7431
7432
7433
7434template <int spacedim>
7435inline bool
7436TriaAccessor<0, 1, spacedim>::face_rotation(const unsigned int /*face*/)
7437{
7438 return false;
7439}
7440
7441
7442
7443template <int spacedim>
7444inline bool
7445TriaAccessor<0, 1, spacedim>::line_orientation(const unsigned int /*line*/)
7446{
7447 return false;
7448}
7449
7450
7451
7452template <int spacedim>
7453inline bool
7455{
7456 return false;
7457}
7458
7459
7460
7461template <int spacedim>
7462inline unsigned int
7464{
7465 return 0;
7466}
7467
7468
7469
7470template <int spacedim>
7471inline unsigned int
7473{
7474 return 0;
7475}
7476
7477
7478
7479template <int spacedim>
7480inline unsigned int
7482{
7483 return 0;
7484}
7485
7486
7487
7488template <int spacedim>
7489inline unsigned int
7492{
7494}
7495
7496
7497
7498template <int spacedim>
7500TriaAccessor<0, 1, spacedim>::child(const unsigned int)
7501{
7503}
7504
7505
7506template <int spacedim>
7509{
7511}
7512
7513
7514template <int spacedim>
7515inline RefinementCase<0>
7517{
7519}
7520
7521template <int spacedim>
7522inline int
7524{
7525 return -1;
7526}
7527
7528
7529template <int spacedim>
7530inline int
7532{
7533 return -1;
7534}
7535
7536
7537
7538template <int spacedim>
7539inline void
7541{
7542 Assert(tria->vertex_to_boundary_id_map_1d->find(this->vertex_index()) !=
7543 tria->vertex_to_boundary_id_map_1d->end(),
7544 ExcMessage("You can't set the boundary_id of a face of a cell that is "
7545 "not actually at the boundary."));
7546
7547 (*tria->vertex_to_boundary_id_map_1d)[this->vertex_index()] = b;
7548}
7549
7550
7551
7552template <int spacedim>
7553inline void
7555{
7556 (*tria->vertex_to_manifold_id_map_1d)[this->vertex_index()] = b;
7557}
7558
7559
7560
7561template <int spacedim>
7562inline void
7564 const types::boundary_id b) const
7565{
7566 set_boundary_id(b);
7567}
7568
7569
7570
7571template <int spacedim>
7572inline void
7574{
7575 set_manifold_id(b);
7576}
7577
7578
7579
7580template <int spacedim>
7581inline bool
7583{
7584 return tria->vertex_used(global_vertex_index);
7585}
7586
7587
7588
7589template <int spacedim>
7590inline ReferenceCell
7592{
7594}
7595
7596
7597
7598template <int spacedim>
7599unsigned int
7601{
7602 return 1;
7603}
7604
7605
7606
7607template <int spacedim>
7608unsigned int
7610{
7611 return 0;
7612}
7613
7614
7615
7616template <int spacedim>
7619{
7620 return {0U, n_vertices()};
7621}
7622
7623
7624
7625template <int spacedim>
7628{
7629 return {0U, n_lines()};
7630}
7631
7632/*------------------ Functions: CellAccessor<dim,spacedim> ------------------*/
7633
7634
7635template <int dim, int spacedim>
7637 const Triangulation<dim, spacedim> *parent,
7638 const int level,
7639 const int index,
7640 const AccessorData *local_data)
7641 : TriaAccessor<dim, dim, spacedim>(parent, level, index, local_data)
7642{}
7643
7644
7645
7646template <int dim, int spacedim>
7648 const TriaAccessor<dim, dim, spacedim> &cell_accessor)
7649 : TriaAccessor<dim, dim, spacedim>(
7650 static_cast<const TriaAccessor<dim, dim, spacedim> &>(cell_accessor))
7651{}
7652
7653
7654
7655template <int dim, int spacedim>
7657CellAccessor<dim, spacedim>::child(const unsigned int i) const
7658{
7660 this->present_level + 1,
7661 this->child_index(i));
7662
7663 Assert((q.state() == IteratorState::past_the_end) || q->used(),
7665
7666 return q;
7667}
7668
7669
7670
7671template <int dim, int spacedim>
7672inline boost::container::small_vector<TriaIterator<CellAccessor<dim, spacedim>>,
7675{
7676 boost::container::small_vector<TriaIterator<CellAccessor<dim, spacedim>>,
7678 child_iterators(this->n_children());
7679
7680 for (unsigned int i = 0; i < this->n_children(); ++i)
7681 child_iterators[i] = this->child(i);
7682
7683 return child_iterators;
7684}
7685
7686
7687
7688template <int dim, int spacedim>
7689inline TriaIterator<TriaAccessor<dim - 1, dim, spacedim>>
7690CellAccessor<dim, spacedim>::face(const unsigned int i) const
7691{
7692 AssertIndexRange(i, this->n_faces());
7693 if constexpr (dim == 1)
7694 {
7696 &this->get_triangulation(),
7697 ((i == 0) && at_boundary(0) ?
7699 ((i == 1) && at_boundary(1) ?
7700 TriaAccessor<0, 1, spacedim>::right_vertex :
7701 TriaAccessor<0, 1, spacedim>::interior_vertex)),
7702 internal::TriaAccessorImplementation::Implementation::vertex_index(
7703 *this, i));
7705 }
7706 else if constexpr (dim == 2)
7707 return this->line(i);
7708 else if constexpr (dim == 3)
7709 return this->quad(i);
7710 else
7711 {
7712 Assert(false, ExcNotImplemented());
7713 return {};
7714 }
7715}
7716
7717
7718
7719template <int dim, int spacedim>
7720inline unsigned int
7723{
7724 for (const unsigned int face_n : this->face_indices())
7725 if (this->face(face_n) == face)
7726 return face_n;
7727
7728 Assert(false,
7729 ExcMessage("The given face is not a face of the current cell."));
7731}
7732
7733
7734
7735template <int dim, int spacedim>
7736inline boost::container::small_vector<
7737 TriaIterator<TriaAccessor<dim - 1, dim, spacedim>>,
7740{
7741 boost::container::small_vector<
7742 TriaIterator<TriaAccessor<dim - 1, dim, spacedim>>,
7744 face_iterators(this->n_faces());
7745
7746 for (const unsigned int i : this->face_indices())
7747 face_iterators[i] = this->face(i);
7748
7749 return face_iterators;
7750}
7751
7752
7753
7754template <int dim, int spacedim>
7755inline unsigned int
7756CellAccessor<dim, spacedim>::face_index(const unsigned int i) const
7757{
7758 switch (dim)
7759 {
7760 case 1:
7761 {
7762 return this->vertex_index(i);
7763 }
7764
7765 case 2:
7766 return this->line_index(i);
7767
7768 case 3:
7769 return this->quad_index(i);
7770
7771 default:
7773 }
7774}
7775
7776
7777
7778template <int dim, int spacedim>
7779inline int
7780CellAccessor<dim, spacedim>::neighbor_index(const unsigned int face_no) const
7781{
7782 AssertIndexRange(face_no, this->n_faces());
7783 return this->tria->levels[this->present_level]
7784 ->neighbors[this->present_index * GeometryInfo<dim>::faces_per_cell +
7785 face_no]
7786 .second;
7787}
7788
7789
7790
7791template <int dim, int spacedim>
7792inline int
7793CellAccessor<dim, spacedim>::neighbor_level(const unsigned int face_no) const
7794{
7795 AssertIndexRange(face_no, this->n_faces());
7796 return this->tria->levels[this->present_level]
7797 ->neighbors[this->present_index * GeometryInfo<dim>::faces_per_cell +
7798 face_no]
7799 .first;
7800}
7801
7802
7803
7804template <int dim, int spacedim>
7807{
7809 // cells flagged for refinement must be active
7810 // (the @p set_refine_flag function checks this,
7811 // but activity may change when refinement is
7812 // executed and for some reason the refine
7813 // flag is not cleared).
7814 Assert(this->is_active() || !this->tria->levels[this->present_level]
7815 ->refine_flags[this->present_index],
7816 ExcRefineCellNotActive());
7817 return RefinementCase<dim>(
7818 this->tria->levels[this->present_level]->refine_flags[this->present_index]);
7819}
7820
7821
7822
7823template <int dim, int spacedim>
7824inline void
7826 const RefinementCase<dim> refinement_case) const
7827{
7828 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
7829 Assert(!coarsen_flag_set(), ExcCellFlaggedForCoarsening());
7830
7831 this->tria->levels[this->present_level]->refine_flags[this->present_index] =
7832 refinement_case;
7833}
7834
7835
7836
7837template <int dim, int spacedim>
7838inline void
7840{
7841 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
7842 this->tria->levels[this->present_level]->refine_flags[this->present_index] =
7844}
7845
7846
7847template <int dim, int spacedim>
7848inline std::uint8_t
7850{
7852 if (this->tria->levels[this->present_level]->refine_choice.size() == 0)
7853 return 0U;
7854 return this->tria->levels[this->present_level]
7855 ->refine_choice[this->present_index];
7856}
7857
7858
7859template <int dim, int spacedim>
7860inline void
7862 const std::uint8_t refinement_choice) const
7863{
7864 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
7865 if (this->tria->levels[this->present_level]->refine_choice.size() != 0)
7866 this->tria->levels[this->present_level]
7867 ->refine_choice[this->present_index] = refinement_choice;
7868}
7869
7870
7871template <int dim, int spacedim>
7872inline void
7874{
7875 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
7876 if (this->tria->levels[this->present_level]->refine_choice.size() != 0)
7877 this->tria->levels[this->present_level]
7878 ->refine_choice[this->present_index] =
7880}
7881
7882
7883template <int dim, int spacedim>
7884inline bool
7886 const unsigned int face_no,
7887 const RefinementCase<dim - 1> &face_refinement_case) const
7888{
7889 Assert(dim > 1, ExcImpossibleInDim(dim));
7890 AssertIndexRange(face_no, this->n_faces());
7891 AssertIndexRange(face_refinement_case,
7893
7894 // the new refinement case is a combination
7895 // of the minimum required one for the given
7896 // face refinement and the already existing
7897 // flagged refinement case
7898 RefinementCase<dim> old_ref_case = refine_flag_set();
7899 RefinementCase<dim> new_ref_case =
7900 (old_ref_case |
7902 face_refinement_case,
7903 face_no,
7904 this->face_orientation(face_no),
7905 this->face_flip(face_no),
7906 this->face_rotation(face_no)));
7907 set_refine_flag(new_ref_case);
7908 // return, whether we had to change the
7909 // refinement flag
7910 return new_ref_case != old_ref_case;
7911}
7912
7913
7914
7915template <int dim, int spacedim>
7916inline bool
7918 const unsigned int line_no) const
7919{
7920 Assert(dim > 1, ExcImpossibleInDim(dim));
7921 AssertIndexRange(line_no, this->n_lines());
7922
7923 // the new refinement case is a combination
7924 // of the minimum required one for the given
7925 // line refinement and the already existing
7926 // flagged refinement case
7928 old_ref_case = refine_flag_set(),
7929 new_ref_case =
7930 old_ref_case |
7932 set_refine_flag(new_ref_case);
7933 // return, whether we had to change the
7934 // refinement flag
7935 return new_ref_case != old_ref_case;
7936}
7937
7938
7939
7940template <>
7941inline ::internal::SubfaceCase<1>
7942CellAccessor<1>::subface_case(const unsigned int) const
7943{
7944 return ::internal::SubfaceCase<1>::case_none;
7945}
7946
7947template <>
7948inline ::internal::SubfaceCase<1>
7949CellAccessor<1, 2>::subface_case(const unsigned int) const
7950{
7951 return ::internal::SubfaceCase<1>::case_none;
7952}
7953
7954
7955template <>
7956inline ::internal::SubfaceCase<1>
7957CellAccessor<1, 3>::subface_case(const unsigned int) const
7958{
7959 return ::internal::SubfaceCase<1>::case_none;
7960}
7961
7962
7963template <>
7964inline ::internal::SubfaceCase<2>
7965CellAccessor<2>::subface_case(const unsigned int face_no) const
7966{
7968 AssertIndexRange(face_no, this->n_faces());
7969 return ((face(face_no)->has_children()) ?
7971 ::internal::SubfaceCase<2>::case_none);
7972}
7973
7974template <>
7975inline ::internal::SubfaceCase<2>
7976CellAccessor<2, 3>::subface_case(const unsigned int face_no) const
7977{
7979 AssertIndexRange(face_no, this->n_faces());
7980 return ((face(face_no)->has_children()) ?
7982 ::internal::SubfaceCase<2>::case_none);
7983}
7984
7985
7986template <>
7987inline ::internal::SubfaceCase<3>
7988CellAccessor<3>::subface_case(const unsigned int face_no) const
7989{
7991 AssertIndexRange(face_no, this->n_faces());
7992 switch (static_cast<std::uint8_t>(face(face_no)->refinement_case()))
7993 {
7995 return ::internal::SubfaceCase<3>::case_none;
7997 if (face(face_no)->child(0)->has_children())
7998 {
7999 Assert(face(face_no)->child(0)->refinement_case() ==
8002 if (face(face_no)->child(1)->has_children())
8003 {
8004 Assert(face(face_no)->child(1)->refinement_case() ==
8007 return ::internal::SubfaceCase<3>::case_x1y2y;
8008 }
8009 else
8010 return ::internal::SubfaceCase<3>::case_x1y;
8011 }
8012 else
8013 {
8014 if (face(face_no)->child(1)->has_children())
8015 {
8016 Assert(face(face_no)->child(1)->refinement_case() ==
8019 return ::internal::SubfaceCase<3>::case_x2y;
8020 }
8021 else
8022 return ::internal::SubfaceCase<3>::case_x;
8023 }
8025 if (face(face_no)->child(0)->has_children())
8026 {
8027 Assert(face(face_no)->child(0)->refinement_case() ==
8030 if (face(face_no)->child(1)->has_children())
8031 {
8032 Assert(face(face_no)->child(1)->refinement_case() ==
8035 return ::internal::SubfaceCase<3>::case_y1x2x;
8036 }
8037 else
8038 return ::internal::SubfaceCase<3>::case_y1x;
8039 }
8040 else
8041 {
8042 if (face(face_no)->child(1)->has_children())
8043 {
8044 Assert(face(face_no)->child(1)->refinement_case() ==
8047 return ::internal::SubfaceCase<3>::case_y2x;
8048 }
8049 else
8050 return ::internal::SubfaceCase<3>::case_y;
8051 }
8053 return ::internal::SubfaceCase<3>::case_xy;
8054 default:
8056 }
8057 // we should never get here
8058 return ::internal::SubfaceCase<3>::case_none;
8059}
8060
8061
8062
8063template <int dim, int spacedim>
8064inline bool
8066{
8068 // cells flagged for coarsening must be active
8069 // (the @p set_refine_flag function checks this,
8070 // but activity may change when refinement is
8071 // executed and for some reason the refine
8072 // flag is not cleared).
8073 Assert(this->is_active() || !this->tria->levels[this->present_level]
8074 ->coarsen_flags[this->present_index],
8075 ExcRefineCellNotActive());
8076 return this->tria->levels[this->present_level]
8077 ->coarsen_flags[this->present_index];
8078}
8079
8080
8081
8082template <int dim, int spacedim>
8083inline void
8085{
8086 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
8087 Assert(!refine_flag_set(), ExcCellFlaggedForRefinement());
8088
8089 this->tria->levels[this->present_level]->coarsen_flags[this->present_index] =
8090 true;
8091}
8092
8093
8094
8095template <int dim, int spacedim>
8096inline void
8098{
8099 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
8100 this->tria->levels[this->present_level]->coarsen_flags[this->present_index] =
8101 false;
8102}
8103
8104
8105
8106template <int dim, int spacedim>
8108CellAccessor<dim, spacedim>::neighbor(const unsigned int face_no) const
8109{
8111 neighbor_level(face_no),
8112 neighbor_index(face_no));
8113
8114 Assert((q.state() == IteratorState::past_the_end) || q->used(),
8116
8117 return q;
8118}
8119
8120
8121
8122template <int dim, int spacedim>
8123inline bool
8125{
8126 return !this->has_children();
8127}
8128
8129
8130
8131template <int dim, int spacedim>
8132inline bool
8134{
8135 Assert(this->is_active(),
8136 ExcMessage("is_locally_owned() can only be called on active cells!"));
8137# ifndef DEAL_II_WITH_MPI
8138 return true;
8139# else
8140
8141 // Serial triangulations report invalid_subdomain_id as their locally owned
8142 // subdomain, so the first condition checks whether we have a serial
8143 // triangulation, in which case all cells are locally owned. The second
8144 // condition compares the subdomain id in the parallel case.
8145 const types::subdomain_id locally_owned_subdomain =
8146 this->tria->locally_owned_subdomain();
8147 return (locally_owned_subdomain == numbers::invalid_subdomain_id ||
8148 this->subdomain_id() == locally_owned_subdomain);
8149
8150# endif
8151}
8152
8153
8154template <int dim, int spacedim>
8155inline bool
8157{
8158# ifndef DEAL_II_WITH_MPI
8159 return true;
8160# else
8161
8162 // Serial triangulations report invalid_subdomain_id as their locally owned
8163 // subdomain, so the first condition checks whether we have a serial
8164 // triangulation, in which case all cells are locally owned. The second
8165 // condition compares the subdomain id in the parallel case.
8166 const types::subdomain_id locally_owned_subdomain =
8167 this->tria->locally_owned_subdomain();
8168 return (locally_owned_subdomain == numbers::invalid_subdomain_id ||
8169 this->level_subdomain_id() == locally_owned_subdomain);
8170
8171# endif
8172}
8173
8174
8175template <int dim, int spacedim>
8176inline bool
8178{
8179 Assert(this->is_active(),
8180 ExcMessage("is_ghost() can only be called on active cells!"));
8181 if (this->has_children())
8182 return false;
8183
8184# ifndef DEAL_II_WITH_MPI
8185 return false;
8186# else
8187
8188 // Serial triangulations report invalid_subdomain_id as their locally owned
8189 // subdomain, so the first condition rules out that case as all cells to a
8190 // serial triangulation are locally owned and none is ghosted. The second
8191 // and third conditions check whether the cell's subdomain is not the
8192 // locally owned one and not artificial.
8193 const types::subdomain_id locally_owned_subdomain =
8194 this->tria->locally_owned_subdomain();
8195 const types::subdomain_id subdomain_id = this->subdomain_id();
8196 return (locally_owned_subdomain != numbers::invalid_subdomain_id &&
8197 subdomain_id != locally_owned_subdomain &&
8198 subdomain_id != numbers::artificial_subdomain_id);
8199
8200# endif
8201}
8202
8203
8204template <int dim, int spacedim>
8205inline bool
8207{
8208# ifndef DEAL_II_WITH_MPI
8209 return false;
8210# else
8211
8212 // Serial triangulations report invalid_subdomain_id as their locally owned
8213 // subdomain, so the first condition checks whether we have a serial
8214 // triangulation, in which case all cells are locally owned. The second
8215 // condition compares the subdomain id in the parallel case.
8216 const types::subdomain_id locally_owned_subdomain =
8217 this->tria->locally_owned_subdomain();
8218 const types::subdomain_id subdomain_id = this->level_subdomain_id();
8219 return (locally_owned_subdomain != numbers::invalid_subdomain_id &&
8220 subdomain_id != locally_owned_subdomain &&
8221 subdomain_id != numbers::artificial_subdomain_id);
8222
8223# endif
8224}
8225
8226
8227
8228template <int dim, int spacedim>
8229inline bool
8231{
8232 Assert(this->is_active(),
8233 ExcMessage("is_artificial() can only be called on active cells!"));
8234# ifndef DEAL_II_WITH_MPI
8235 return false;
8236# else
8237
8238 // Serial triangulations report invalid_subdomain_id as their locally owned
8239 // subdomain, so the first condition rules out that case as all cells to a
8240 // serial triangulation are locally owned and none is artificial.
8241 return (this->tria->locally_owned_subdomain() !=
8243 this->subdomain_id() == numbers::artificial_subdomain_id);
8244
8245# endif
8246}
8247
8248
8249
8250template <int dim, int spacedim>
8251inline bool
8253{
8254# ifndef DEAL_II_WITH_MPI
8255 return false;
8256# else
8257 return (this->tria->locally_owned_subdomain() !=
8259 this->level_subdomain_id() == numbers::artificial_subdomain_id);
8260# endif
8261}
8262
8263
8264
8265template <int dim, int spacedim>
8268{
8270 Assert(this->is_active(),
8271 ExcMessage("subdomain_id() can only be called on active cells!"));
8272 return this->tria->levels[this->present_level]
8273 ->subdomain_ids[this->present_index];
8274}
8275
8276
8277
8278template <int dim, int spacedim>
8281{
8283 return this->tria->levels[this->present_level]
8284 ->level_subdomain_ids[this->present_index];
8285}
8286
8287
8288
8289template <int dim, int spacedim>
8290inline unsigned int
8291CellAccessor<dim, spacedim>::neighbor_face_no(const unsigned int neighbor) const
8292{
8293 const unsigned int n2 = neighbor_of_neighbor_internal(neighbor);
8295 // return this value as the
8296 // neighbor is not coarser
8297 return n2;
8298 else
8299 // the neighbor is coarser
8300 return neighbor_of_coarser_neighbor(neighbor).first;
8301}
8302
8303
8304
8305template <int dim, int spacedim>
8306inline bool
8308{
8309 return false;
8310}
8311
8312
8313
8314template <int dim, int spacedim>
8315inline unsigned int
8317{
8319 return this->tria->levels[this->present_level]
8320 ->active_cell_indices[this->present_index];
8321}
8322
8323
8324
8325template <int dim, int spacedim>
8328{
8330 Assert(this->is_active(),
8331 ExcMessage(
8332 "global_active_cell_index() can only be called on active cells!"));
8333
8334 return this->tria->levels[this->present_level]
8335 ->global_active_cell_indices[this->present_index];
8336}
8337
8338
8339
8340template <int dim, int spacedim>
8343{
8344 return this->tria->levels[this->present_level]
8345 ->global_level_cell_indices[this->present_index];
8346}
8347
8348#endif // DOXYGEN
8349
8351
8352
8353#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
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
boost::container::small_vector< TriaIterator< TriaAccessor< dim - 1, dim, spacedim > >, GeometryInfo< dim >::faces_per_cell > face_iterators() const
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:318
virtual boost::container::small_vector< Point< spacedim >, GeometryInfo< dim >::vertices_per_cell > get_vertices(const typename Triangulation< dim, spacedim >::cell_iterator &cell) const
Definition point.h:111
numbers::NumberTraits< Number >::real_type distance(const Point< dim, Number > &p) const
unsigned int n_vertices() const
static constexpr unsigned char default_combined_face_orientation()
std::array< unsigned int, 2 > standard_vertex_to_face_and_vertex_index(const unsigned int vertex) const
unsigned int standard_to_real_face_vertex(const unsigned int vertex, const unsigned int face, const unsigned char face_orientation) const
std::array< unsigned int, 2 > standard_line_to_face_and_line_index(const unsigned int line) const
unsigned int n_faces() const
static constexpr unsigned char reversed_combined_line_orientation()
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 unsigned char 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 bool 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:4570
std::vector< Point< spacedim > > vertices
Definition tria.h:4496
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:4547
std::unique_ptr<::internal::TriangulationImplementation::TriaFaces > faces
Definition tria.h:4490
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:4482
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:498
#define DEAL_II_CXX20_REQUIRES(condition)
Definition config.h:175
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:499
unsigned int level
Definition grid_out.cc:4632
unsigned int vertex_indices[2]
static ::ExceptionBase & ExcCantCompareIterators()
#define DeclException0(Exception0)
Definition exceptions.h:466
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)
Definition exceptions.h:489
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)
Definition exceptions.h:511
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
bool line_orientation(const unsigned int line) const
static bool face_orientation(const unsigned int face)
Always return false.
unsigned char combined_face_orientation(const unsigned int face) const
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.
static bool line_orientation(const unsigned int line)
Always return false.
static unsigned char combined_face_orientation(const unsigned int face)
Always return 0.
static bool face_flip(const unsigned int face)
Always return false.
static bool line_orientation(const unsigned int line)
Always return false.
static bool face_rotation(const unsigned int face)
Always return false.
static bool face_rotation(const unsigned int face)
Always return false.
static bool face_orientation(const unsigned int face)
Always return false.
static unsigned char combined_face_orientation(const unsigned int face)
Always return 0.
bool face_flip(const unsigned int face) const
void set_combined_face_orientation(const unsigned int face, const unsigned char combined_orientation) const
#define DEAL_II_ASSERT_UNREACHABLE()
#define DEAL_II_NOT_IMPLEMENTED()
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.
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 const ReferenceCell Tetrahedron
constexpr const ReferenceCell Quadrilateral
constexpr const ReferenceCell Wedge
constexpr const ReferenceCell Pyramid
constexpr const ReferenceCell Triangle
constexpr const ReferenceCell Hexahedron
constexpr const ReferenceCell Vertex
constexpr const ReferenceCell Line
T sum(const T &t, const MPI_Comm mpi_communicator)
unsigned char combined_face_orientation(const bool face_orientation, const bool face_rotation, const bool face_flip)
const types::boundary_id internal_face_boundary_id
Definition types.h:312
const types::subdomain_id artificial_subdomain_id
Definition types.h:362
const types::subdomain_id invalid_subdomain_id
Definition types.h:341
static const unsigned int invalid_unsigned_int
Definition types.h:220
const types::manifold_id flat_manifold_id
Definition types.h:325
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:156
std::uint64_t global_vertex_index
Definition types.h:48
unsigned int subdomain_id
Definition types.h:43
unsigned int boundary_id
Definition types.h:144
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)