deal.II version GIT relicensing-6917-gb466a1809f 2026-10-16 06:30:01+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Loading...
Searching...
No Matches
tria_accessor.h
Go to the documentation of this file.
1// -----------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception OR LGPL-2.1-or-later
4// Copyright (C) 1998 - 2026 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Detailed license information governing the source code and contributions
9// can be found in LICENSE.md and CONTRIBUTING.md at the top level directory.
10//
11// -----------------------------------------------------------------------------
12
13#ifndef dealii_tria_accessor_h
14#define dealii_tria_accessor_h
15
16
17#include <deal.II/base/config.h>
18
22#include <deal.II/base/point.h>
25
33
34#include <boost/container/small_vector.hpp>
35
36#include <cmath>
37#include <limits>
38#include <set>
39#include <utility>
40
41
43
44// Forward declarations
45#ifndef DOXYGEN
46template <int dim, int spacedim>
48class Triangulation;
49template <typename Accessor>
50class TriaRawIterator;
51template <typename Accessor>
52class TriaIterator;
53template <typename Accessor>
55
56namespace parallel
57{
58 template <int dim, int spacedim>
60 class TriangulationBase;
61}
62
63template <int dim, int spacedim>
65class DoFHandler;
66template <int dim, int spacedim, bool lda>
67class DoFCellAccessor;
68
69
70template <int dim, int spacedim>
71class Manifold;
72
73template <int dim, int spacedim>
74class Mapping;
75#endif
76
77namespace internal
78{
79 namespace TriangulationImplementation
80 {
81 class TriaObjects;
82 struct Implementation;
83 struct ImplementationMixedMesh;
84 } // namespace TriangulationImplementation
85
86 namespace TriaAccessorImplementation
87 {
88 struct Implementation;
89 } // namespace TriaAccessorImplementation
90} // namespace internal
91template <int structdim, int dim, int spacedim>
92class TriaAccessor;
93template <int dim, int spacedim>
94class TriaAccessor<0, dim, spacedim>;
95template <int spacedim>
96class TriaAccessor<0, 1, spacedim>;
97
102{
107 "The operation you are attempting can only be performed for "
108 "(cell, face, or edge) iterators that point to valid "
109 "objects. These objects need not necessarily be active, "
110 "i.e., have no children, but they need to be part of a "
111 "triangulation. (The objects pointed to by an iterator "
112 "may -- after coarsening -- also be objects that used "
113 "to be part of a triangulation, but are now no longer "
114 "used. Their memory location may have been retained "
115 "for re-use upon the next mesh refinement, but is "
116 "currently unused.)");
127 "The operation you are attempting can only be performed for "
128 "(cell, face, or edge) iterators that point to 'active' "
129 "objects. 'Active' objects are those that do not have "
130 "children (in the case of cells), or that are part of "
131 "an active cell (in the case of faces or edges). However, "
132 "the object on which you are trying the current "
133 "operation is not 'active' in this sense.");
140 "The operation you are attempting can only be performed for "
141 "(cell, face, or edge) iterators that have children, "
142 "but the object on which you are trying the current "
143 "operation does not have any.");
151 "The operation you are attempting can only be performed for "
152 "(cell, face, or edge) iterators that have a parent object, "
153 "but the object on which you are trying the current "
154 "operation does not have one -- i.e., it is on the "
155 "coarsest level of the triangulation.");
160 int,
161 << "You can only set the child index if the cell does not "
162 << "currently have children registered; or you can clear it. "
163 << "The given index was " << arg1
164 << " (-1 means: clear children).");
168 template <typename AccessorType>
170 AccessorType,
171 << "You tried to dereference an iterator for which this "
172 << "is not possible. More information on this iterator: "
173 << "index=" << arg1.index() << ", state="
174 << (arg1.state() == IteratorState::valid ?
175 "valid" :
176 (arg1.state() == IteratorState::past_the_end ?
177 "past_the_end" :
178 "invalid")));
183 "Iterators can only be compared if they point to the same "
184 "triangulation, or if neither of them are associated "
185 "with a triangulation.");
186 // TODO: Write documentation!
191 // TODO: Write documentation!
218 int,
219 << "You can only set the child index of an even numbered child."
220 << "The number of the child given was " << arg1 << '.');
221} // namespace TriaAccessorExceptions
222
223
249template <int structdim, int dim, int spacedim = dim>
251{
252public:
259 static constexpr unsigned int space_dimension = spacedim;
260
266 static constexpr unsigned int dimension = dim;
267
273 static const unsigned int structure_dimension = structdim;
274
284 void
285 operator=(const TriaAccessorBase *) = delete;
286
287protected:
293 using AccessorData = void;
294
299 const int level = -1,
300 const int index = -1,
301 const AccessorData * = nullptr);
302
307
312 void
313 set_level(const int level);
314
322 void
324
330
341 bool
342 operator<(const TriaAccessorBase &other) const;
343
344protected:
348 bool
350
354 bool
356
370 void
372
380 void
390 objects() const;
391
392public:
398 using LocalData = void *;
399
423 int
424 level() const;
425
452 int
453 index() const;
454
460 state() const;
461
468
472protected:
478 struct Empty
479 {};
480
484 std::conditional_t<structdim == dim, int, Empty> present_level;
485
491
496
497private:
498 template <typename Accessor>
499 friend class TriaRawIterator;
500 template <typename Accessor>
501 friend class TriaIterator;
502 template <typename Accessor>
503 friend class TriaActiveIterator;
504};
505
506
507
528template <int structdim, int dim, int spacedim = dim>
530{
531public:
538 static constexpr unsigned int space_dimension = spacedim;
539
545 static constexpr unsigned int dimension = dim;
546
552 static const unsigned int structure_dimension = structdim;
553
559 using AccessorData = void;
560
568 InvalidAccessor(const void *parent = nullptr,
569 const int level = -1,
570 const int index = -1,
571 const AccessorData *local_data = nullptr);
572
581
586 template <typename OtherAccessor>
587 InvalidAccessor(const OtherAccessor &);
588
592 void
594
598 bool
600 bool
602
606 void
607 operator++() const;
608 void
609 operator--() const;
610
616 state();
617
618
623 static int
624 level();
625
630 static int
631 index();
632
637 bool
638 used() const;
639
644 bool
646
651 manifold_id() const;
652
656 unsigned int
657 user_index() const;
658
662 void
663 set_user_index(const unsigned int p) const;
664
668 void
670
675 vertex(const unsigned int i) const;
676
681 void *
682 line(const unsigned int i) const;
683
688 void *
689 quad(const unsigned int i) const;
690};
691
692
693
711template <int structdim, int dim, int spacedim>
712class TriaAccessor : public TriaAccessorBase<structdim, dim, spacedim>
713{
714public:
720
725 const int level = -1,
726 const int index = -1,
727 const AccessorData *local_data = nullptr);
728
733 TriaAccessor(const TriaAccessor &) = default;
734
738 TriaAccessor(TriaAccessor &&) = default; // NOLINT
739
752 template <int structdim2, int dim2, int spacedim2>
754
759 template <int structdim2, int dim2, int spacedim2>
761
772 operator=(const TriaAccessor &) = delete;
773
778 operator=(TriaAccessor &&) = default; // NOLINT
779
783 ~TriaAccessor() = default;
784
791 bool
792 used() const;
793
806 vertex_iterator(const unsigned int i) const;
807
823 unsigned int
824 vertex_index(const unsigned int i) const;
825
864 vertex(const unsigned int i) const;
865
869 typename ::internal::TriangulationImplementation::
870 Iterators<dim, spacedim>::line_iterator
871 line(const unsigned int i) const;
872
879 unsigned int
880 line_index(const unsigned int i) const;
881
885 typename ::internal::TriangulationImplementation::
886 Iterators<dim, spacedim>::quad_iterator
887 quad(const unsigned int i) const;
888
895 unsigned int
896 quad_index(const unsigned int i) const;
915 combined_face_orientation(const unsigned int face) const;
916
928 bool
929 face_orientation(const unsigned int face) const;
930
940 bool
941 face_flip(const unsigned int face) const;
942
952 bool
953 face_rotation(const unsigned int face) const;
954
965 line_orientation(const unsigned int line) const;
980 bool
982
987 unsigned int
988 n_children() const;
989
1003 unsigned int
1005
1019 unsigned int
1021
1026 child(const unsigned int i) const;
1027
1032 unsigned int
1035
1045 isotropic_child(const unsigned int i) const;
1046
1052
1058 int
1059 child_index(const unsigned int i) const;
1060
1066 int
1067 isotropic_child_index(const unsigned int i) const;
1091
1119 void
1121
1150 void
1152
1160 bool
1162
1174
1197
1215 void
1217
1231 void
1233
1250 bool
1252
1258 void
1260
1266 void
1268
1274 void
1276
1282 void
1284
1290 void
1292
1304 void
1305 set_user_pointer(void *p) const;
1306
1312 void
1314
1332 void *
1334
1356 void
1358
1365 void
1367
1377 void
1378 set_user_index(const unsigned int p) const;
1379
1385 void
1387
1399 unsigned int
1400 user_index() const;
1401
1419 void
1420 recursively_set_user_index(const unsigned int p) const;
1421
1430 void
1466 double
1467 diameter() const;
1468
1495 std::pair<Point<spacedim>, double>
1497
1508
1518 double
1519 extent_in_direction(const unsigned int axis) const;
1520
1524 double
1526
1541 intermediate_point(const Point<structdim> &coordinates) const;
1542
1567
1603 center(const bool respect_manifold = false,
1604 const bool interpolate_from_surrounding = false) const;
1605
1624 barycenter() const;
1625
1659 double
1660 measure() const;
1661
1676 bool
1679
1685
1689 unsigned int
1690 n_vertices() const;
1691
1695 unsigned int
1696 n_lines() const;
1697
1707 unsigned int
1708 n_faces() const;
1709
1716
1723
1732
1737private:
1742 void
1744
1752 void
1754 const std::initializer_list<int> &new_indices) const;
1755
1759 void
1761 const std::initializer_list<unsigned int> &new_indices) const;
1762
1770 void
1771 set_line_orientation(const unsigned int line,
1772 const types::geometric_orientation orientation) const;
1773
1783 void
1785 const unsigned int face_no,
1786 const types::geometric_orientation combined_orientation) const;
1787
1791 void
1793
1797 void
1799
1808 void
1810
1818 void
1820
1827 void
1828 set_children(const unsigned int i, const int index) const;
1829
1834 void
1836
1837private:
1838 friend class Triangulation<dim, spacedim>;
1839
1840 friend struct ::internal::TriangulationImplementation::Implementation;
1841 friend struct ::internal::TriangulationImplementation::
1842 ImplementationMixedMesh;
1843 friend struct ::internal::TriaAccessorImplementation::Implementation;
1844};
1845
1846
1847
1866template <int dim, int spacedim>
1867class TriaAccessor<0, dim, spacedim>
1868{
1869public:
1875 static constexpr unsigned int space_dimension = spacedim;
1876
1882 static constexpr unsigned int dimension = dim;
1883
1889 static const unsigned int structure_dimension = 0;
1890
1894 using AccessorData = void;
1895
1901 const unsigned int vertex_index);
1902
1909 const int level = 0,
1910 const int index = 0,
1911 const AccessorData * = nullptr);
1912
1916 template <int structdim2, int dim2, int spacedim2>
1918
1922 template <int structdim2, int dim2, int spacedim2>
1924
1929 state() const;
1930
1935 static int
1937
1942 int
1943 index() const;
1944
1951
1961 void
1963
1967 void
1972 bool
1973 operator==(const TriaAccessor &) const;
1974
1978 bool
1979 operator!=(const TriaAccessor &) const;
1980
2008 unsigned int
2009 vertex_index(const unsigned int i = 0) const;
2010
2017 vertex(const unsigned int i = 0) const;
2018
2023 typename ::internal::TriangulationImplementation::
2024 Iterators<dim, spacedim>::line_iterator static line(const unsigned int);
2025
2029 static unsigned int
2030 line_index(const unsigned int i);
2031
2035 static typename ::internal::TriangulationImplementation::
2036 Iterators<dim, spacedim>::quad_iterator
2037 quad(const unsigned int i);
2038
2042 static unsigned int
2043 quad_index(const unsigned int i);
2044
2060 double
2061 diameter() const;
2062
2070 double
2071 extent_in_direction(const unsigned int axis) const;
2072
2081 center(const bool respect_manifold = false,
2082 const bool interpolate_from_surrounding = false) const;
2083
2091 double
2092 measure() const;
2110 combined_face_orientation(const unsigned int face);
2111
2115 static bool
2116 face_orientation(const unsigned int face);
2117
2121 static bool
2122 face_flip(const unsigned int face);
2123
2127 static bool
2128 face_rotation(const unsigned int face);
2129
2134 line_orientation(const unsigned int line);
2135
2150 static bool
2152
2157 static unsigned int
2159
2164 static unsigned int
2166
2170 static unsigned int
2172
2176 static unsigned int
2178
2183 child(const unsigned int);
2184
2189 isotropic_child(const unsigned int);
2190
2194 static RefinementCase<0>
2196
2200 static int
2201 child_index(const unsigned int i);
2202
2206 static int
2207 isotropic_child_index(const unsigned int i);
2215 bool
2216 used() const;
2217
2218protected:
2226 void
2228
2237 bool
2238 operator<(const TriaAccessor &other) const;
2239
2244
2249
2250private:
2251 template <typename Accessor>
2252 friend class TriaRawIterator;
2253 template <typename Accessor>
2254 friend class TriaIterator;
2255 template <typename Accessor>
2257};
2258
2259
2260
2277template <int spacedim>
2278class TriaAccessor<0, 1, spacedim>
2279{
2280public:
2286 static constexpr unsigned int space_dimension = spacedim;
2287
2293 static constexpr unsigned int dimension = 1;
2294
2300 static const unsigned int structure_dimension = 0;
2301
2305 using AccessorData = void;
2306
2312 {
2324 right_vertex
2326
2339 const VertexKind vertex_kind,
2340 const unsigned int vertex_index);
2341
2348 const int = 0,
2349 const int = 0,
2350 const AccessorData * = nullptr);
2351
2355 template <int structdim2, int dim2, int spacedim2>
2357
2361 template <int structdim2, int dim2, int spacedim2>
2363
2368 void
2370
2376 void
2378
2386
2391 static int
2393
2398 int
2399 index() const;
2400
2407
2418 void
2419 operator++() const;
2420
2425 void
2426 operator--() const;
2430 bool
2431 operator==(const TriaAccessor &) const;
2432
2436 bool
2437 operator!=(const TriaAccessor &) const;
2438
2447 bool
2448 operator<(const TriaAccessor &other) const;
2449
2476 unsigned int
2477 vertex_index(const unsigned int i = 0) const;
2478
2485 vertex(const unsigned int i = 0) const;
2486
2492 center() const;
2493
2498 typename ::internal::TriangulationImplementation::
2499 Iterators<1, spacedim>::line_iterator static line(const unsigned int);
2500
2507 static unsigned int
2508 line_index(const unsigned int i);
2509
2513 static typename ::internal::TriangulationImplementation::
2514 Iterators<1, spacedim>::quad_iterator
2515 quad(const unsigned int i);
2516
2523 static unsigned int
2524 quad_index(const unsigned int i);
2525
2543 static double
2545
2554 bool
2556
2573
2577 const Manifold<1, spacedim> &
2579
2588
2589
2601 bool
2602 user_flag_set() const;
2603
2609 void
2610 set_user_flag() const;
2611
2617 void
2618 clear_user_flag() const;
2619
2625 void
2627
2633 void
2635
2641 void
2642 clear_user_data() const;
2643
2655 void
2656 set_user_pointer(void *p) const;
2657
2663 void
2664 clear_user_pointer() const;
2665
2681 void *
2682 user_pointer() const;
2683
2705 void
2706 recursively_set_user_pointer(void *p) const;
2707
2714 void
2716
2726 void
2727 set_user_index(const unsigned int p) const;
2728
2734 void
2735 clear_user_index() const;
2736
2748 unsigned int
2749 user_index() const;
2750
2768 void
2769 recursively_set_user_index(const unsigned int p) const;
2770
2779 void
2798 combined_face_orientation(const unsigned int face);
2799
2803 static bool
2804 face_orientation(const unsigned int face);
2805
2809 static bool
2810 face_flip(const unsigned int face);
2811
2815 static bool
2816 face_rotation(const unsigned int face);
2817
2822 line_orientation(const unsigned int line);
2823
2838 static bool
2840
2845 static unsigned int
2847
2852 static unsigned int
2854
2858 static unsigned int
2860
2864 static unsigned int
2866
2871 child(const unsigned int);
2872
2877 isotropic_child(const unsigned int);
2878
2882 static RefinementCase<0>
2884
2888 static int
2889 child_index(const unsigned int i);
2890
2894 static int
2895 isotropic_child_index(const unsigned int i);
2926 void
2928
2935 void
2937
2947 void
2949
2961 void
2970 bool
2971 used() const;
2972
2978
2982 unsigned int
2983 n_vertices() const;
2984
2988 unsigned int
2989 n_lines() const;
2990
2997
3004
3005protected:
3010
3016
3021};
3022
3023
3024
3040template <int dim, int spacedim = dim>
3041class CellAccessor : public TriaAccessor<dim, dim, spacedim>
3042{
3043public:
3048
3053
3065 const int level = -1,
3066 const int index = -1,
3067 const AccessorData *local_data = nullptr);
3068
3073
3086 template <int structdim2, int dim2, int spacedim2>
3088
3093 template <int structdim2, int dim2, int spacedim2>
3095
3100
3104 // NOLINTNEXTLINE OSX does not compile with noexcept
3106
3110 ~CellAccessor() = default;
3111
3123
3127 // NOLINTNEXTLINE OSX does not compile with noexcept
3130
3154 as_dof_handler_iterator(const DoFHandler<dim, spacedim> &dof_handler) const;
3155
3166 const DoFHandler<dim, spacedim> &dof_handler) const;
3167
3168
3185 child(const unsigned int i) const;
3186
3190 boost::container::small_vector<TriaIterator<CellAccessor<dim, spacedim>>,
3191 ReferenceCells::max_n_children<dim>()>
3193
3197 TriaIterator<TriaAccessor<dim - 1, dim, spacedim>>
3198 face(const unsigned int i) const;
3199
3204 unsigned int
3207
3211 boost::container::small_vector<
3212 TriaIterator<TriaAccessor<dim - 1, dim, spacedim>>,
3213#ifndef _MSC_VER // MSVC prior to 2022 cannot use a constexpr function this way
3214 ReferenceCells::max_n_faces<dim>()
3215#else
3217#endif
3218 >
3220
3230 unsigned int
3231 face_index(const unsigned int i) const;
3232
3281 neighbor_child_on_subface(const unsigned int face_no,
3282 const unsigned int subface_no) const;
3283
3332 neighbor(const unsigned int face_no) const;
3333
3341 int
3342 neighbor_index(const unsigned int face_no) const;
3343
3351 int
3352 neighbor_level(const unsigned int face_no) const;
3353
3365 unsigned int
3366 neighbor_of_neighbor(const unsigned int face_no) const;
3367
3378 bool
3379 neighbor_is_coarser(const unsigned int face_no) const;
3380
3395 std::pair<unsigned int, unsigned int>
3396 neighbor_of_coarser_neighbor(const unsigned int neighbor) const;
3397
3404 unsigned int
3405 neighbor_face_no(const unsigned int neighbor) const;
3406
3410 static bool
3412
3426 bool
3427 has_periodic_neighbor(const unsigned int i) const;
3428
3446 periodic_neighbor(const unsigned int i) const;
3447
3456 neighbor_or_periodic_neighbor(const unsigned int i) const;
3457
3473 periodic_neighbor_child_on_subface(const unsigned int face_no,
3474 const unsigned int subface_no) const;
3475
3486 std::pair<unsigned int, unsigned int>
3487 periodic_neighbor_of_coarser_periodic_neighbor(const unsigned face_no) const;
3488
3494 int
3495 periodic_neighbor_index(const unsigned int i) const;
3496
3502 int
3503 periodic_neighbor_level(const unsigned int i) const;
3504
3519 unsigned int
3520 periodic_neighbor_of_periodic_neighbor(const unsigned int i) const;
3521
3527 unsigned int
3528 periodic_neighbor_face_no(const unsigned int i) const;
3529
3536 bool
3537 periodic_neighbor_is_coarser(const unsigned int i) const;
3538
3555 bool
3556 at_boundary(const unsigned int i) const;
3557
3566 bool
3567 at_boundary() const;
3568
3576 bool
3577 has_boundary_lines() const;
3605
3623 void
3626
3630 void
3632
3637 std::uint8_t
3639
3644 void
3645 set_refine_choice(const std::uint8_t refinement_choice = static_cast<char>(
3647
3651 void
3653
3661 bool
3663 const unsigned int face_no,
3664 const RefinementCase<dim - 1> &face_refinement_case =
3666
3672 bool
3673 flag_for_line_refinement(const unsigned int line_no) const;
3674
3684 subface_case(const unsigned int face_no) const;
3685
3689 bool
3691
3696 void
3698
3702 void
3728
3740 void
3741 set_material_id(const types::material_id new_material_id) const;
3742
3751 void
3752 recursively_set_material_id(const types::material_id new_material_id) const;
3780
3796 void
3797 set_subdomain_id(const types::subdomain_id new_subdomain_id) const;
3798
3809
3814 void
3816 const types::subdomain_id new_level_subdomain_id) const;
3817
3818
3834 void
3836 const types::subdomain_id new_subdomain_id) const;
3860
3870
3896 unsigned int
3898
3906 int
3907 parent_index() const;
3908
3915 parent() const;
3916
3933 bool
3935
3955 bool
3956 is_active() const;
3957
3977 bool
3979
3984 bool
3986
4020 bool
4021 is_ghost() const;
4022
4028 bool
4030
4057 bool
4059
4066 bool
4068
4082 bool
4084
4101 std::set<TriaActiveIterator<CellAccessor<dim, spacedim>>>
4102 get_cells_adjacent_to_line(const unsigned int i) const;
4103
4117 CellId
4118 id() const;
4119
4120 using TriaAccessor<dim, dim, spacedim>::diameter;
4121
4125 double
4126 diameter(const Mapping<dim, spacedim> &mapping) const;
4127
4145
4146protected:
4154 void
4155 set_neighbor(const unsigned int face_no,
4157
4173 unsigned int
4174 neighbor_of_neighbor_internal(const unsigned int neighbor) const;
4175
4181 template <int dim_, int spacedim_>
4182 bool
4183 point_inside_codim(const Point<spacedim_> &p) const;
4184
4185
4186
4187private:
4192 void
4193 set_active_cell_index(const unsigned int active_cell_index) const;
4194
4198 void
4200
4204 void
4206
4210 void
4211 set_parent(const unsigned int parent_index);
4212
4223 void
4224 set_direction_flag(const bool new_direction_flag) const;
4225
4226 friend class Triangulation<dim, spacedim>;
4227
4228 friend class parallel::TriangulationBase<dim, spacedim>;
4229
4230 friend struct ::internal::TriangulationImplementation::Implementation;
4231 friend struct ::internal::TriangulationImplementation::
4232 ImplementationMixedMesh;
4233};
4234
4235
4236
4237/* ----- declaration of explicit specializations and general templates ----- */
4238
4239
4240template <int structdim, int dim, int spacedim>
4241template <typename OtherAccessor>
4243 const OtherAccessor &)
4244{
4245 Assert(false,
4246 ExcMessage("You are attempting an illegal conversion between "
4247 "iterator/accessor types. The constructor you call "
4248 "only exists to make certain template constructs "
4249 "easier to write as dimension independent code but "
4250 "the conversion is not valid in the current context."));
4251}
4252
4253
4254
4255template <int structdim, int dim, int spacedim>
4256template <int structdim2, int dim2, int spacedim2>
4259{
4260 Assert(false,
4261 ExcMessage("You are attempting an illegal conversion between "
4262 "iterator/accessor types. The constructor you call "
4263 "only exists to make certain template constructs "
4264 "easier to write as dimension independent code but "
4265 "the conversion is not valid in the current context."));
4266}
4267
4268
4269
4270template <int dim, int spacedim>
4271template <int structdim2, int dim2, int spacedim2>
4274{
4275 Assert(false,
4276 ExcMessage("You are attempting an illegal conversion between "
4277 "iterator/accessor types. The constructor you call "
4278 "only exists to make certain template constructs "
4279 "easier to write as dimension independent code but "
4280 "the conversion is not valid in the current context."));
4281}
4282
4283
4284
4285template <int structdim, int dim, int spacedim>
4286template <int structdim2, int dim2, int spacedim2>
4289{
4290 Assert(false,
4291 ExcMessage("You are attempting an illegal conversion between "
4292 "iterator/accessor types. The constructor you call "
4293 "only exists to make certain template constructs "
4294 "easier to write as dimension independent code but "
4295 "the conversion is not valid in the current context."));
4296}
4297
4298
4299
4300template <int dim, int spacedim>
4301template <int structdim2, int dim2, int spacedim2>
4304{
4305 Assert(false,
4306 ExcMessage("You are attempting an illegal conversion between "
4307 "iterator/accessor types. The constructor you call "
4308 "only exists to make certain template constructs "
4309 "easier to write as dimension independent code but "
4310 "the conversion is not valid in the current context."));
4311}
4312
4313
4314#ifndef DOXYGEN
4315
4316template <>
4317bool
4319template <>
4320bool
4322template <>
4323bool
4325template <>
4326bool
4328template <>
4329bool
4331template <>
4332bool
4334// -------------------------------------------------------------------
4335
4336template <>
4337void
4339
4340
4341
4342namespace internal
4343{
4344 namespace TriaAccessorImplementation
4345 {
4351 template <int dim, int spacedim>
4352 inline double
4353 diameter(const ArrayView<const Point<spacedim>> &vertices)
4354 {
4355 const ReferenceCell<dim> reference_cell =
4356 ReferenceCells::n_vertices_to_reference_cell<dim>(vertices.size());
4357
4358 if constexpr (dim == 1)
4359 {
4360 Assert(reference_cell == ReferenceCells::Line, ExcInternalError());
4361 // Return the distance between the two vertices
4362 return (vertices[1] - vertices[0]).norm();
4363 }
4364 else if constexpr (dim == 2)
4365 {
4366 if (reference_cell == ReferenceCells::Triangle)
4367 // Return the longest of the three edges
4368 return std::max({(vertices[1] - vertices[0]).norm(),
4369 (vertices[2] - vertices[1]).norm(),
4370 (vertices[2] - vertices[0]).norm()});
4371 else if (reference_cell == ReferenceCells::Quadrilateral)
4372 // Return the longer one of the two diagonals of the quadrilateral
4373 return std::max({(vertices[3] - vertices[0]).norm(),
4374 (vertices[2] - vertices[1]).norm()});
4375 }
4376 else if constexpr (dim == 3)
4377 {
4378 if (reference_cell == ReferenceCells::Tetrahedron)
4379 // Return the longest of the six edges of the tetrahedron
4380 return std::max({(vertices[1] - vertices[0]).norm(),
4381 (vertices[2] - vertices[0]).norm(),
4382 (vertices[2] - vertices[1]).norm(),
4383 (vertices[3] - vertices[0]).norm(),
4384 (vertices[3] - vertices[1]).norm(),
4385 (vertices[3] - vertices[2]).norm()});
4386 else if (reference_cell == ReferenceCells::Pyramid)
4387 // Return ...
4388 return std::max({// the longest diagonal of the quadrilateral base
4389 // of the pyramid or ...
4390 (vertices[3] - vertices[0]).norm(),
4391 (vertices[2] - vertices[1]).norm(),
4392 // the longest edge connected with the apex of the
4393 // pyramid
4394 (vertices[4] - vertices[0]).norm(),
4395 (vertices[4] - vertices[1]).norm(),
4396 (vertices[4] - vertices[2]).norm(),
4397 (vertices[4] - vertices[3]).norm()});
4398 else if (reference_cell == ReferenceCells::Wedge)
4399 // Return ...
4400 return std::max({// the longest of the 2*3=6 diagonals of the three
4401 // quadrilateral sides of the wedge or ...
4402 (vertices[4] - vertices[0]).norm(),
4403 (vertices[3] - vertices[1]).norm(),
4404 (vertices[5] - vertices[1]).norm(),
4405 (vertices[4] - vertices[2]).norm(),
4406 (vertices[5] - vertices[0]).norm(),
4407 (vertices[3] - vertices[2]).norm(),
4408 // the longest of the 3*2=6 edges of the two
4409 // triangular faces of the wedge
4410 (vertices[1] - vertices[0]).norm(),
4411 (vertices[2] - vertices[1]).norm(),
4412 (vertices[2] - vertices[0]).norm(),
4413 (vertices[4] - vertices[3]).norm(),
4414 (vertices[5] - vertices[4]).norm(),
4415 (vertices[5] - vertices[3]).norm()});
4416 else if (reference_cell == ReferenceCells::Hexahedron)
4417 // Return the longest of the four diagonals of the hexahedron
4418 return std::max({(vertices[7] - vertices[0]).norm(),
4419 (vertices[6] - vertices[1]).norm(),
4420 (vertices[2] - vertices[5]).norm(),
4421 (vertices[3] - vertices[4]).norm()});
4422 }
4423
4425 return -1e10;
4426 }
4427 } // namespace TriaAccessorImplementation
4428} // namespace internal
4429
4430
4431/*--------------------- Functions: TriaAccessorBase -------------------------*/
4432
4433template <int structdim, int dim, int spacedim>
4435 const Triangulation<dim, spacedim> *tria,
4436 const int level,
4437 const int index,
4438 const AccessorData *)
4439 : present_level()
4440 , present_index(index)
4441 , tria(tria)
4442{
4443 set_level(structdim == dim ? level : 0);
4444 // non-cells have no level, so a 0 should have been passed, or a -1 for an
4445 // end-iterator, or -2 for an invalid (default constructed) iterator
4446 if (structdim != dim)
4447 Assert((level == 0) || (level == -1) || (level == -2), ExcInternalError());
4448}
4449
4450
4451
4452template <int structdim, int dim, int spacedim>
4455 : present_level()
4456 , present_index(a.present_index)
4457 , tria(a.tria)
4458{
4459 set_level(a.level());
4460}
4461
4462
4463
4464template <int structdim, int dim, int spacedim>
4465inline void
4467{
4468 if constexpr (structdim == dim)
4469 this->present_level = level;
4470 else
4471 Assert(level == 0,
4472 ExcMessage("Lower-dimensional objects must be on level 0."));
4473}
4474
4475
4476
4477template <int structdim, int dim, int spacedim>
4478inline void
4481{
4482 this->set_level(a.level());
4483 present_index = a.present_index;
4484 tria = a.tria;
4485
4486 if (structdim != dim)
4487 Assert(level() == 0, ExcInternalError());
4488}
4489
4490
4491
4492template <int structdim, int dim, int spacedim>
4496{
4497 this->set_level(a.level());
4498 present_index = a.present_index;
4499 tria = a.tria;
4500
4501 if (structdim != dim)
4502 Assert(level() == 0, ExcInternalError());
4503 return *this;
4504}
4505
4506
4507
4508template <int structdim, int dim, int spacedim>
4509inline bool
4512{
4513 Assert(tria == a.tria || tria == nullptr || a.tria == nullptr,
4515 return ((tria == a.tria) && (level() == a.level()) &&
4516 (present_index == a.present_index));
4517}
4518
4519
4520
4521template <int structdim, int dim, int spacedim>
4522inline bool
4525{
4526 Assert(tria == a.tria || tria == nullptr || a.tria == nullptr,
4528 return ((tria != a.tria) || (level() != a.level()) ||
4529 (present_index != a.present_index));
4530}
4531
4532
4533
4534template <int structdim, int dim, int spacedim>
4535inline bool
4538{
4540
4541 if (level() != other.level())
4542 return (level() < other.level());
4543
4544 return (present_index < other.present_index);
4545}
4546
4547
4548
4549template <int structdim, int dim, int spacedim>
4550inline int
4552{
4553 if constexpr (structdim == dim)
4554 return this->present_level;
4555 else
4556 return 0;
4557}
4558
4559
4560
4561template <int structdim, int dim, int spacedim>
4562inline int
4564{
4565 return present_index;
4566}
4567
4568
4569
4570template <int structdim, int dim, int spacedim>
4573{
4574 if ((level() >= 0) && (present_index >= 0))
4575 return IteratorState::valid;
4576 else if (present_index == -1)
4578 else
4580}
4581
4582
4583
4584template <int structdim, int dim, int spacedim>
4585inline const Triangulation<dim, spacedim> &
4587{
4588 return *tria;
4589}
4590
4591
4592
4593template <int structdim, int dim, int spacedim>
4594inline void
4596{
4597 // this iterator is used for
4598 // objects without level
4599 ++this->present_index;
4600
4601 if (structdim != dim)
4602 {
4603 // is index still in the range of
4604 // the vector? (note that we don't
4605 // have to set the level, since
4606 // dim!=1 and the object therefore
4607 // has no level)
4608 if (this->present_index >= static_cast<int>(objects().n_objects()))
4609 this->present_index = -1;
4610 }
4611 else
4612 {
4613 while (this->present_index >=
4614 static_cast<int>(this->tria->levels[level()]->cells.n_objects()))
4615 {
4616 // no -> go one level up until we find
4617 // one with more than zero cells
4618 this->set_level(level() + 1);
4619 this->present_index = 0;
4620 // highest level reached?
4621 if (level() >= static_cast<int>(this->tria->levels.size()))
4622 {
4623 // return with past the end pointer
4624 this->set_level(-1);
4625 this->present_index = -1;
4626 return;
4627 }
4628 }
4629 }
4630}
4631
4632
4633template <int structdim, int dim, int spacedim>
4634inline void
4636{
4637 // same as operator++
4638 --this->present_index;
4639
4640 if (structdim != dim)
4641 {
4642 if (this->present_index < 0)
4643 this->present_index = -1;
4644 }
4645 else
4646 {
4647 while (this->present_index < 0)
4648 {
4649 // no -> go one level down
4650 this->set_level(level() - 1);
4651 // lowest level reached?
4652 if (level() == -1)
4653 {
4654 // return with past the end pointer
4655 this->set_level(-1);
4656 this->present_index = -1;
4657 return;
4658 }
4659 // else
4660 this->present_index =
4661 this->tria->levels[level()]->cells.n_objects() - 1;
4662 }
4663 }
4664}
4665
4666
4667
4668template <int structdim, int dim, int spacedim>
4669inline ::internal::TriangulationImplementation::TriaObjects &
4671{
4672 if (structdim == dim)
4673 return this->tria->levels[level()]->cells;
4674
4675 if (structdim == 1 && dim > 1)
4676 return this->tria->faces->lines;
4677
4678 if (structdim == 2 && dim > 2)
4679 return this->tria->faces->quads;
4680
4682
4683 return this->tria->levels[level()]->cells;
4684}
4685
4686
4687
4688/*---------------------- Functions: InvalidAccessor -------------------------*/
4689
4690template <int structdim, int dim, int spacedim>
4692 const int,
4693 const int,
4694 const AccessorData *)
4695{
4696 Assert(false,
4697 ExcMessage("You are attempting an invalid conversion between "
4698 "iterator/accessor types. The constructor you call "
4699 "only exists to make certain template constructs "
4700 "easier to write as dimension independent code but "
4701 "the conversion is not valid in the current context."));
4702}
4703
4704
4705
4706template <int structdim, int dim, int spacedim>
4708 const InvalidAccessor &)
4709{
4710 Assert(false,
4711 ExcMessage("You are attempting an invalid conversion between "
4712 "iterator/accessor types. The constructor you call "
4713 "only exists to make certain template constructs "
4714 "easier to write as dimension independent code but "
4715 "the conversion is not valid in the current context."));
4716}
4717
4718
4719
4720template <int structdim, int dim, int spacedim>
4721void
4723{
4724 // nothing to do here. we could throw an exception but we can't get here
4725 // without first creating an object which would have already thrown.
4726}
4727
4728
4729
4730template <int structdim, int dim, int spacedim>
4731bool
4733 const InvalidAccessor &) const
4734{
4735 // nothing to do here. we could throw an exception but we can't get here
4736 // without first creating an object which would have already thrown.
4737 return false;
4738}
4739
4740
4741
4742template <int structdim, int dim, int spacedim>
4743bool
4745 const InvalidAccessor &) const
4746{
4747 // nothing to do here. we could throw an exception but we can't get here
4748 // without first creating an object which would have already thrown.
4749 return true;
4750}
4751
4752
4753
4754template <int structdim, int dim, int spacedim>
4755bool
4757{
4758 // nothing to do here. we could throw an exception but we can't get here
4759 // without first creating an object which would have already thrown.
4760 return false;
4761}
4762
4763
4764
4765template <int structdim, int dim, int spacedim>
4766bool
4768{
4769 // nothing to do here. we could throw an exception but we can't get here
4770 // without first creating an object which would have already thrown.
4771 return false;
4772}
4773
4774
4775
4776template <int structdim, int dim, int spacedim>
4777void
4779{}
4780
4781
4782
4783template <int structdim, int dim, int spacedim>
4784void
4786{}
4787
4788
4789
4790template <int structdim, int dim, int spacedim>
4793{
4795}
4796
4797
4798
4799template <int structdim, int dim, int spacedim>
4800unsigned int
4802{
4804}
4805
4806
4807
4808template <int structdim, int dim, int spacedim>
4809void
4811 const unsigned int) const
4812{
4813 Assert(false,
4814 ExcMessage("You are trying to set the user index of an "
4815 "invalid object."));
4816}
4817
4818
4819
4820template <int structdim, int dim, int spacedim>
4821void
4823 const types::manifold_id) const
4824{
4825 Assert(false,
4826 ExcMessage("You are trying to set the manifold id of an "
4827 "invalid object."));
4828}
4829
4830
4831
4832template <int structdim, int dim, int spacedim>
4833inline Point<spacedim> &
4835{
4836 // nothing to do here. we could throw an exception but we can't get here
4837 // without first creating an object which would have already thrown
4838 static Point<spacedim> invalid_vertex;
4839 return invalid_vertex;
4840}
4841
4842
4843template <int structdim, int dim, int spacedim>
4844inline void *
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 return nullptr;
4850}
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/*------------------------ Functions: TriaAccessor ---------------------------*/
4865
4866
4867namespace internal
4868{
4869 namespace TriaAccessorImplementation
4870 {
4871 // make sure that if in the following we write TriaAccessor we mean the
4872 // *class* ::TriaAccessor, not the enclosing namespace
4873 // ::internal::TriaAccessor
4874 using ::TriaAccessor;
4875
4880 struct Implementation
4881 {
4882 template <int dim, int spacedim>
4883 static std::array<unsigned int, 1>
4884 get_line_indices_of_cell(const TriaAccessor<1, dim, spacedim> &)
4885 {
4887 return {};
4888 }
4889
4890
4891
4892 template <int structdim, int dim, int spacedim>
4893 static std::array<unsigned int, 4>
4894 get_line_indices_of_cell(const TriaAccessor<2, dim, spacedim> &cell)
4895 {
4896 // For 2d cells the access cell->line_orientation() is already
4897 // efficient
4898 std::array<unsigned int, 4> line_indices = {};
4899 for (const unsigned int line : cell.line_indices())
4900 line_indices[line] = cell.line_index(line);
4901 return line_indices;
4902 }
4903
4908 template <int structdim, int dim, int spacedim>
4909 static std::array<unsigned int, 12>
4910 get_line_indices_of_cell(
4912 {
4913 std::array<unsigned int, 12> line_indices = {};
4914
4915 // For hexahedra, the classical access via quads -> lines is too
4916 // inefficient. Unroll this code here to allow the compiler to inline
4917 // the necessary functions.
4918 const auto cell_reference_cell = cell.reference_cell();
4919 if (cell_reference_cell == ReferenceCells::Hexahedron)
4920 {
4922 for (unsigned int f = 4; f < 6; ++f)
4923 {
4924 const auto orientation = cell.combined_face_orientation(f);
4925
4926 // It might seem superfluous to spell out the four indices
4927 // that get later consumed by a for loop over these four
4928 // elements; however, for the compiler it is easier to inline
4929 // the statement of standard_to_real_face_line() when next to
4930 // each other, as opposed to be interleaved with a
4931 // line_index() call.
4932 const std::array<unsigned int, 4> my_indices{{
4933 reference_cell.standard_to_real_face_line(0, f, orientation),
4934 reference_cell.standard_to_real_face_line(1, f, orientation),
4935 reference_cell.standard_to_real_face_line(2, f, orientation),
4936 reference_cell.standard_to_real_face_line(3, f, orientation),
4937 }};
4938 const auto quad = cell.quad(f);
4939 for (unsigned int l = 0; l < 4; ++l)
4940 line_indices[4 * (f - 4) + l] =
4941 quad->line_index(my_indices[l]);
4942 }
4943 for (unsigned int f = 0; f < 2; ++f)
4944 {
4945 const auto orientation =
4946 cell.get_triangulation()
4947 .levels[cell.level()]
4948 ->face_orientations.get_combined_orientation(cell.index(),
4949 f);
4950 const std::array<unsigned int, 2> my_indices{{
4951 reference_cell.standard_to_real_face_line(0, f, orientation),
4952 reference_cell.standard_to_real_face_line(1, f, orientation),
4953 }};
4954 const auto quad = cell.quad(f);
4955 line_indices[8 + f] = quad->line_index(my_indices[0]);
4956 line_indices[10 + f] = quad->line_index(my_indices[1]);
4957 }
4958 }
4959 else if (cell_reference_cell == ReferenceCells::Tetrahedron)
4960 {
4962 const std::array<unsigned int, 3> orientations{
4965 cell.combined_face_orientation(2)}};
4966 const std::array<unsigned int, 6> my_indices{{
4967 reference_cell.standard_to_real_face_line(0, 0, orientations[0]),
4968 reference_cell.standard_to_real_face_line(1, 0, orientations[0]),
4969 reference_cell.standard_to_real_face_line(2, 0, orientations[0]),
4970 reference_cell.standard_to_real_face_line(1, 1, orientations[1]),
4971 reference_cell.standard_to_real_face_line(2, 1, orientations[1]),
4972 reference_cell.standard_to_real_face_line(1, 2, orientations[2]),
4973 }};
4974 const std::array<decltype(cell.quad(0)), 3> quads{
4975 {cell.quad(0), cell.quad(1), cell.quad(2)}};
4976 line_indices[0] = quads[0]->line_index(my_indices[0]);
4977 line_indices[1] = quads[0]->line_index(my_indices[1]);
4978 line_indices[2] = quads[0]->line_index(my_indices[2]);
4979 line_indices[3] = quads[1]->line_index(my_indices[3]);
4980 line_indices[4] = quads[1]->line_index(my_indices[4]);
4981 line_indices[5] = quads[2]->line_index(my_indices[5]);
4982 }
4983 else
4984 // For other shapes (wedges, pyramids), we do not currently
4985 // implement an optimized function.
4986 for (unsigned int l = 0; l < std::min(12U, cell.n_lines()); ++l)
4987 line_indices[l] = cell.line_index(l);
4988
4989 return line_indices;
4990 }
4991
4992
4993
5002 template <int dim, int spacedim>
5003 static std::pair<std::array<unsigned int, 1>,
5004 std::array<types::geometric_orientation, 1>>
5005 get_line_indices_and_orientations_of_cell(
5007 {
5009 return {};
5010 }
5011
5012
5013
5020 template <int dim, int spacedim>
5021 static std::pair<std::array<unsigned int, 4>,
5022 std::array<types::geometric_orientation, 4>>
5023 get_line_indices_and_orientations_of_cell(
5025 {
5026 // For 2d cells the access cell->line_orientation() is already
5027 // efficient
5028 std::array<types::geometric_orientation, 4> line_orientations = {};
5029 std::array<unsigned int, 4> line_indices = {};
5030 for (const unsigned int line : cell.line_indices())
5031 {
5032 line_orientations[line] = cell.line_orientation(line);
5033 line_indices[line] = cell.line_index(line);
5034 }
5035 return std::make_pair(line_indices, line_orientations);
5036 }
5037
5038
5039
5046 template <int dim, int spacedim>
5047 static std::pair<std::array<unsigned int, 12>,
5048 std::array<types::geometric_orientation, 12>>
5049 get_line_indices_and_orientations_of_cell(
5051 {
5052 std::array<types::geometric_orientation, 12> line_orientations = {};
5053 std::array<unsigned int, 12> line_indices = {};
5054
5055 // For hexahedra, the classical access via quads -> lines is too
5056 // inefficient. Unroll this code here to allow the compiler to inline
5057 // the necessary functions.
5058 const auto cell_reference_cell = cell.reference_cell();
5059 if (cell_reference_cell == ReferenceCells::Hexahedron)
5060 {
5062 for (unsigned int f = 4; f < 6; ++f)
5063 {
5064 const auto orientation = cell.combined_face_orientation(f);
5065
5066 // It might seem superfluous to spell out the four indices and
5067 // orientations that get later consumed by a for loop over
5068 // these four elements; however, for the compiler it is easier
5069 // to inline the statement of standard_to_real_face_line()
5070 // when next to each other, as opposed to be interleaved with
5071 // a line_index() call.
5072 const std::array<unsigned int, 4> my_indices{{
5073 reference_cell.standard_to_real_face_line(0, f, orientation),
5074 reference_cell.standard_to_real_face_line(1, f, orientation),
5075 reference_cell.standard_to_real_face_line(2, f, orientation),
5076 reference_cell.standard_to_real_face_line(3, f, orientation),
5077 }};
5078 const auto quad = cell.quad(f);
5079 for (unsigned int l = 0; l < 4; ++l)
5080 line_indices[4 * (f - 4) + l] =
5081 quad->line_index(my_indices[l]);
5082 const std::array<types::geometric_orientation, 4>
5083 my_orientations{{
5084 reference_cell.face_to_cell_line_orientation(
5085 0, f, orientation, quad->line_orientation(my_indices[0])),
5086 reference_cell.face_to_cell_line_orientation(
5087 1, f, orientation, quad->line_orientation(my_indices[1])),
5088 reference_cell.face_to_cell_line_orientation(
5089 2, f, orientation, quad->line_orientation(my_indices[2])),
5090 reference_cell.face_to_cell_line_orientation(
5091 3, f, orientation, quad->line_orientation(my_indices[3])),
5092 }};
5093 for (unsigned int l = 0; l < 4; ++l)
5094 line_orientations[4 * (f - 4) + l] = my_orientations[l];
5095 }
5096 for (unsigned int f = 0; f < 2; ++f)
5097 {
5098 const auto orientation = cell.combined_face_orientation(f);
5099
5100 const std::array<unsigned int, 2> my_indices{{
5101 reference_cell.standard_to_real_face_line(0, f, orientation),
5102 reference_cell.standard_to_real_face_line(1, f, orientation),
5103 }};
5104 const auto quad = cell.quad(f);
5105 line_indices[8 + f] = quad->line_index(my_indices[0]);
5106 line_indices[10 + f] = quad->line_index(my_indices[1]);
5107 const std::array<types::geometric_orientation, 2>
5108 my_orientations{{
5109 reference_cell.face_to_cell_line_orientation(
5110 0, f, orientation, quad->line_orientation(my_indices[0])),
5111 reference_cell.face_to_cell_line_orientation(
5112 1, f, orientation, quad->line_orientation(my_indices[1])),
5113 }};
5114 line_orientations[8 + f] = my_orientations[0];
5115 line_orientations[10 + f] = my_orientations[1];
5116 }
5117 }
5118 else if (cell_reference_cell == ReferenceCells::Tetrahedron)
5119 {
5121 const std::array<types::geometric_orientation, 3> orientations{
5124 cell.combined_face_orientation(2)}};
5125 const std::array<unsigned int, 6> my_indices{{
5126 reference_cell.standard_to_real_face_line(0, 0, orientations[0]),
5127 reference_cell.standard_to_real_face_line(1, 0, orientations[0]),
5128 reference_cell.standard_to_real_face_line(2, 0, orientations[0]),
5129 reference_cell.standard_to_real_face_line(1, 1, orientations[1]),
5130 reference_cell.standard_to_real_face_line(2, 1, orientations[1]),
5131 reference_cell.standard_to_real_face_line(1, 2, orientations[2]),
5132 }};
5133 const std::array<decltype(cell.quad(0)), 3> quads{
5134 {cell.quad(0), cell.quad(1), cell.quad(2)}};
5135 line_indices[0] = quads[0]->line_index(my_indices[0]);
5136 line_indices[1] = quads[0]->line_index(my_indices[1]);
5137 line_indices[2] = quads[0]->line_index(my_indices[2]);
5138 line_indices[3] = quads[1]->line_index(my_indices[3]);
5139 line_indices[4] = quads[1]->line_index(my_indices[4]);
5140 line_indices[5] = quads[2]->line_index(my_indices[5]);
5141
5142 line_orientations[0] = reference_cell.face_to_cell_line_orientation(
5143 0, 0, orientations[0], quads[0]->line_orientation(my_indices[0]));
5144 line_orientations[1] = reference_cell.face_to_cell_line_orientation(
5145 1, 0, orientations[0], quads[0]->line_orientation(my_indices[1]));
5146 line_orientations[2] = reference_cell.face_to_cell_line_orientation(
5147 2, 0, orientations[0], quads[0]->line_orientation(my_indices[2]));
5148 line_orientations[3] = reference_cell.face_to_cell_line_orientation(
5149 1, 1, orientations[1], quads[1]->line_orientation(my_indices[3]));
5150 line_orientations[4] = reference_cell.face_to_cell_line_orientation(
5151 2, 1, orientations[1], quads[1]->line_orientation(my_indices[4]));
5152 line_orientations[5] = reference_cell.face_to_cell_line_orientation(
5153 1, 2, orientations[2], quads[2]->line_orientation(my_indices[5]));
5154 }
5155 else
5156 // For other shapes (wedges, pyramids), we do not currently implement
5157 // an optimized function
5158 for (unsigned int l = 0; l < std::min(12U, cell.n_lines()); ++l)
5159 {
5160 line_indices[l] = cell.line_index(l);
5161 line_orientations[l] = cell.line_orientation(l);
5162 }
5163
5164 return std::make_pair(line_indices, line_orientations);
5165 }
5166 };
5167 } // namespace TriaAccessorImplementation
5168} // namespace internal
5169
5170
5171
5172template <int structdim, int dim, int spacedim>
5174 const Triangulation<dim, spacedim> *parent,
5175 const int level,
5176 const int index,
5177 const AccessorData *local_data)
5178 : TriaAccessorBase<structdim, dim, spacedim>(parent, level, index, local_data)
5179{}
5180
5181
5182
5183template <int structdim, int dim, int spacedim>
5184inline bool
5186{
5187 Assert(this->state() == IteratorState::valid,
5188 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5189 *this));
5190 return this->objects().used[this->present_index];
5191}
5192
5193
5194
5195template <int structdim, int dim, int spacedim>
5198 const unsigned int i) const
5199{
5201 0,
5202 vertex_index(i));
5203}
5204
5205
5206
5207template <int structdim, int dim, int spacedim>
5210{
5211 if constexpr (structdim == 0)
5213 else if constexpr (structdim == 1)
5214 return ReferenceCells::Line;
5215 else if constexpr (structdim == dim)
5216 return this->tria->levels[this->level()]
5217 ->reference_cell[this->present_index];
5218 else
5219 return this->tria->faces->get_quad_type(this->present_index);
5220}
5221
5222
5223
5224template <int structdim, int dim, int spacedim>
5225inline unsigned int
5227 const unsigned int vertex_no) const
5228{
5229 AssertIndexRange(vertex_no, this->n_vertices());
5230
5231 if constexpr (structdim == 1)
5232 {
5233 // This branch needs to be first (and not combined with the structdim ==
5234 // dim branch) so that we can get line vertex indices when setting up the
5235 // cell vertex index cache
5236 return this->objects().get_bounding_object(this->present_index,
5237 vertex_no);
5238 }
5239 else if constexpr (structdim == dim)
5240 {
5241 // This branch should only be used after the cell vertex index cache is
5242 // set up
5243 const auto vertex_index =
5244 this->tria->levels[this->level()]->cached_vertex_index(
5245 this->present_index, vertex_no);
5246 Assert(
5247 vertex_index != numbers::invalid_unsigned_int,
5248 ExcMessage(
5249 "The present vertex's vertex_index is not valid. This is typically "
5250 "caused by calling cell->vertex_index() during grid refinement for "
5251 "a newly created cell, since the cell vertex index cache is not "
5252 "complete at that point."));
5253 return vertex_index;
5254 }
5255 else if constexpr (structdim == 2)
5256 {
5257 const auto [line_index, vertex_index] =
5258 this->reference_cell().standard_vertex_to_face_and_vertex_index(
5259 vertex_no);
5260 const auto vertex_within_line_index =
5261 this->reference_cell().standard_to_real_face_vertex(
5262 vertex_index, line_index, this->line_orientation(line_index));
5263
5264 return this->line(line_index)->vertex_index(vertex_within_line_index);
5265 }
5266 else
5267 {
5270 }
5271}
5272
5273
5274
5275template <int structdim, int dim, int spacedim>
5276inline Point<spacedim> &
5277TriaAccessor<structdim, dim, spacedim>::vertex(const unsigned int i) const
5278{
5279 return const_cast<Point<spacedim> &>(this->tria->vertices[vertex_index(i)]);
5280}
5281
5282
5283
5284template <int structdim, int dim, int spacedim>
5285inline typename ::internal::TriangulationImplementation::
5286 Iterators<dim, spacedim>::line_iterator
5287 TriaAccessor<structdim, dim, spacedim>::line(const unsigned int i) const
5288{
5289 // checks happen in line_index
5290 return typename ::internal::TriangulationImplementation::
5291 Iterators<dim, spacedim>::line_iterator(this->tria, 0, line_index(i));
5292}
5293
5294
5295
5296template <int structdim, int dim, int spacedim>
5297inline unsigned int
5299{
5300 (void)i;
5301 AssertIndexRange(i, this->n_lines());
5302 Assert(structdim != 1,
5303 ExcMessage("You can't ask for the index of a line bounding a "
5304 "one-dimensional cell because it is not bounded by "
5305 "lines."));
5306
5307 if constexpr (structdim == 2)
5308 {
5309 return this->objects().get_bounding_object(this->present_index, i);
5310 }
5311 else if constexpr (structdim == 3)
5312 {
5313 const auto [face_index, line_index] =
5314 this->reference_cell().standard_line_to_face_and_line_index(i);
5315 const auto line_within_face_index =
5316 this->reference_cell().standard_to_real_face_line(
5317 line_index, face_index, this->combined_face_orientation(face_index));
5318
5319 return this->quad(face_index)->line_index(line_within_face_index);
5320 }
5321
5324}
5325
5326
5327
5328template <int structdim, int dim, int spacedim>
5329inline typename ::internal::TriangulationImplementation::
5330 Iterators<dim, spacedim>::quad_iterator
5331 TriaAccessor<structdim, dim, spacedim>::quad(const unsigned int i) const
5332{
5333 // checks happen in quad_index
5334 return typename ::internal::TriangulationImplementation::
5335 Iterators<dim, spacedim>::quad_iterator(this->tria, 0, quad_index(i));
5336}
5337
5338
5339
5340template <int structdim, int dim, int spacedim>
5341inline unsigned int
5343 const unsigned int face_no) const
5344{
5345 Assert(structdim == 3,
5346 ExcMessage("You can't ask for the index of a quad bounding "
5347 "a one- or two-dimensional cell because it is not "
5348 "bounded by quads."));
5349 // work around a bogus GCC-9 warning which considers face_no unused except in
5350 // 3d
5351 (void)face_no;
5352 if constexpr (structdim == 3)
5353 return this->objects().get_bounding_object(this->present_index, face_no);
5354 else
5356}
5357
5358
5359
5360template <int structdim, int dim, int spacedim>
5363 const unsigned int face) const
5364{
5366 AssertIndexRange(face, n_faces());
5367 Assert(structdim == dim,
5368 ExcMessage("This function can only be used on objects "
5369 "that are cells, but not on faces or edges "
5370 "that bound cells."));
5371 // work around a bogus GCC-9 warning which considers face unused except in 3d
5372 (void)face;
5373
5374 if constexpr (structdim == 1)
5376 else if constexpr (structdim == 2)
5377 {
5378 // if all elements are quads (or if we have a very special consistently
5379 // oriented triangular mesh) then we do not store this array
5380 if (this->tria->levels[this->level()]->face_orientations.n_objects() == 0)
5382 else
5383 return this->tria->levels[this->level()]
5384 ->face_orientations.get_combined_orientation(this->present_index,
5385 face);
5386 }
5387 else
5388 return this->tria->levels[this->level()]
5389 ->face_orientations.get_combined_orientation(this->present_index, face);
5390}
5391
5392
5393
5394template <int structdim, int dim, int spacedim>
5395inline bool
5397 const unsigned int face) const
5398{
5400 AssertIndexRange(face, n_faces());
5401 Assert(structdim == dim,
5402 ExcMessage("This function can only be used on objects "
5403 "that are cells, but not on faces or edges "
5404 "that bound cells."));
5405 // work around a bogus GCC-9 warning which considers face unused in 1d
5406 (void)face;
5407
5408 if constexpr (structdim == 1)
5409 // in 1d 'faces' are vertices and those are always consistently oriented
5410 return true;
5411 else if constexpr (structdim == 2)
5412 return this->line_orientation(face) ==
5414 else
5415 return this->tria->levels[this->level()]->face_orientations.get_orientation(
5416 this->present_index, face);
5417}
5418
5419
5420
5421template <int structdim, int dim, int spacedim>
5422inline bool
5423TriaAccessor<structdim, dim, spacedim>::face_flip(const unsigned int face) const
5424{
5426 Assert(structdim == dim,
5427 ExcMessage("This function can only be used on objects "
5428 "that are cells, but not on faces or edges "
5429 "that bound cells."));
5430 AssertIndexRange(face, n_faces());
5431 // work around a bogus GCC-9 warning which considers face unused except in 3d
5432 (void)face;
5433
5434 if constexpr (structdim == 3)
5435 return this->tria->levels[this->level()]->face_orientations.get_flip(
5436 this->present_index, face);
5437 else
5438 // In 1d and 2d, face_flip is always false as faces can only be
5439 // 'flipped' in 3d.
5440 return false;
5441}
5442
5443
5444template <int structdim, int dim, int spacedim>
5445inline bool
5447 const unsigned int face) const
5448{
5450 Assert(structdim == dim,
5451 ExcMessage("This function can only be used on objects "
5452 "that are cells, but not on faces or edges "
5453 "that bound cells."));
5454 AssertIndexRange(face, n_faces());
5455 // work around a bogus GCC-9 warning which considers face unused except in 3d
5456 (void)face;
5457
5458 if constexpr (structdim == 3)
5459 return this->tria->levels[this->level()]->face_orientations.get_rotation(
5460 this->present_index, face);
5461 else
5462 // In 1d and 2d, face_rotation is always false as faces can only be
5463 // 'rotated' in 3d.
5464 return false;
5465}
5466
5467
5468
5469template <int structdim, int dim, int spacedim>
5472 const unsigned int line) const
5473{
5475 AssertIndexRange(line, this->n_lines());
5476 // work around a bogus GCC-9 warning which considers line unused in 1d
5477 (void)line;
5478
5479 if constexpr (structdim == 1)
5481 else if constexpr (structdim == 2 && dim == 2)
5482 // lines in 2d are faces
5483 {
5484 const auto combined_orientation = combined_face_orientation(line);
5485 Assert(combined_orientation == numbers::default_geometric_orientation ||
5486 combined_orientation == numbers::reverse_line_orientation,
5488 return combined_orientation;
5489 }
5490 else if constexpr (structdim == 2 && dim == 3)
5491 {
5492 return this->tria->faces->get_line_orientation(this->present_index, line);
5493 }
5494 else if constexpr (structdim == 3 && dim == 3)
5495 {
5496 const auto reference_cell = this->reference_cell();
5497 // First pick a face on which this line is a part of, and the
5498 // index of the line within.
5499 const auto [face_index, line_index] =
5500 reference_cell.standard_line_to_face_and_line_index(line);
5501 const auto line_within_face_index =
5502 reference_cell.standard_to_real_face_line(
5503 line_index, face_index, this->combined_face_orientation(face_index));
5504
5505 // Then query how that line is oriented within that face:
5506 return reference_cell.face_to_cell_line_orientation(
5507 line_index,
5508 face_index,
5509 this->combined_face_orientation(face_index),
5510 this->quad(face_index)->line_orientation(line_within_face_index));
5511 }
5512 else
5513 {
5516 }
5517}
5518
5519
5520
5521template <int structdim, int dim, int spacedim>
5522inline void
5524 const unsigned int line,
5525 const types::geometric_orientation value) const
5526{
5528 AssertIndexRange(line, this->n_lines());
5529 Assert(dim != 1,
5530 ExcMessage("In 1d lines are cells and thus do not need to have their "
5531 "orientations set."));
5532 Assert(dim != 2,
5533 ExcMessage("In 2d lines are faces, and, for compatibility with other "
5534 "dimensions, their orientations should be set via "
5535 "set_combined_face_orientation()."));
5536 // work around a bogus GCC-9 warning which considers line and value unused
5537 // except in 3d
5538 (void)line;
5539 (void)value;
5540
5541 if constexpr (dim == 3)
5542 {
5543 // We set line orientations per face, not per cell, so this only works for
5544 // faces in 3d.
5545 Assert(structdim == 2, ExcNotImplemented());
5546 this->tria->faces->set_line_orientation(this->present_index, line, value);
5547 }
5548}
5549
5550
5551
5552template <int structdim, int dim, int spacedim>
5553inline void
5555 const unsigned int face_no,
5556 const types::geometric_orientation combined_orientation) const
5557{
5559 AssertIndexRange(face_no, this->n_faces());
5560 Assert(structdim == dim,
5561 ExcMessage("This function can only be used on objects that are cells "
5562 "and not on objects which bound cells."));
5563 AssertIndexRange(combined_orientation,
5564 reference_cell().n_face_orientations(face_no));
5565
5566 // face_orientations is not set up in 1d
5567 if (dim > 1)
5568 this->tria->levels[this->level()]
5569 ->face_orientations.set_combined_orientation(this->present_index,
5570 face_no,
5571 combined_orientation);
5572}
5573
5574
5575
5576template <int structdim, int dim, int spacedim>
5577void
5579{
5580 Assert(this->state() == IteratorState::valid,
5581 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5582 *this));
5583 this->objects().used[this->present_index] = true;
5584}
5585
5586
5587
5588template <int structdim, int dim, int spacedim>
5589void
5591{
5592 Assert(this->state() == IteratorState::valid,
5593 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5594 *this));
5595 this->objects().used[this->present_index] = false;
5596}
5597
5598
5599template <int structdim, int dim, int spacedim>
5600int
5602{
5604 AssertIndexRange(i, n_children());
5605
5606 // each set of two children are stored
5607 // consecutively, so we only have to find
5608 // the location of the set of children
5609 const auto &objects = this->objects();
5610 const unsigned int n_sets_of_two = objects.children_per_object / 2;
5611 return objects.children[n_sets_of_two * this->present_index + i / 2] + i % 2;
5612}
5613
5614
5615
5616template <int structdim, int dim, int spacedim>
5617int
5619 const unsigned int i) const
5620{
5621 AssertIndexRange(i, this->objects().children_per_object);
5622
5623 switch (structdim)
5624 {
5625 case 1:
5626 return child_index(i);
5627 case 2:
5628 {
5629 const RefinementCase<2> this_refinement_case(
5630 static_cast<std::uint8_t>(refinement_case()));
5631
5632 Assert(this_refinement_case != RefinementCase<2>::no_refinement,
5634
5635 if (this_refinement_case == RefinementCase<2>::cut_xy)
5636 return child_index(i);
5637 else if ((this_refinement_case == RefinementCase<2>::cut_x) &&
5638 (child(i % 2)->refinement_case() ==
5640 return child(i % 2)->child_index(i / 2);
5641 else if ((this_refinement_case == RefinementCase<2>::cut_y) &&
5642 (child(i / 2)->refinement_case() ==
5644 return child(i / 2)->child_index(i % 2);
5645 else
5646 Assert(
5647 false,
5648 ExcMessage(
5649 "This cell has no grandchildren equivalent to isotropic refinement"));
5650 break;
5651 }
5652
5653 case 3:
5655 }
5656 return -1;
5657}
5658
5659
5660
5661template <int structdim, int dim, int spacedim>
5664{
5665 Assert(this->state() == IteratorState::valid,
5666 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5667 *this));
5668
5669 switch (structdim)
5670 {
5671 case 1:
5673 this->objects().children[this->present_index] != -1 ?
5674 // cast the branches here first to uchar and then (above) to
5675 // RefinementCase<structdim> so that the conversion is valid even
5676 // for the case structdim>1 (for which this part of the code is dead
5677 // anyway)
5678 static_cast<std::uint8_t>(RefinementCase<1>::cut_x) :
5679 static_cast<std::uint8_t>(RefinementCase<1>::no_refinement)));
5680
5681 default:
5682 Assert(static_cast<unsigned int>(this->present_index) <
5683 this->objects().refinement_cases.size(),
5684 ExcIndexRange(this->present_index,
5685 0,
5686 this->objects().refinement_cases.size()));
5687
5688 return (static_cast<RefinementCase<structdim>>(
5689 this->objects().refinement_cases[this->present_index]));
5690 }
5691}
5692
5693
5694
5695template <int structdim, int dim, int spacedim>
5697TriaAccessor<structdim, dim, spacedim>::child(const unsigned int i) const
5698
5699{
5700 // checking of 'i' happens in child_index
5702 this->tria, (dim == structdim ? this->level() + 1 : 0), child_index(i));
5703
5704 Assert((q.state() == IteratorState::past_the_end) || q->used(),
5706
5707 return q;
5708}
5709
5710
5711
5712template <int structdim, int dim, int spacedim>
5713inline unsigned int
5716{
5717 const auto n_children = this->n_children();
5718 for (unsigned int child_n = 0; child_n < n_children; ++child_n)
5719 if (this->child(child_n) == child)
5720 return child_n;
5721
5722 Assert(false,
5723 ExcMessage("The given child is not a child of the current object."));
5725}
5726
5727
5728
5729template <int structdim, int dim, int spacedim>
5732 const unsigned int i) const
5733{
5734 // checking of 'i' happens in child() or child_index() called below
5735 switch (structdim)
5736 {
5737 case 1:
5738 // no anisotropic refinement in 1d
5739 return child(i);
5740
5741 case 2:
5742 {
5743 const RefinementCase<2> this_refinement_case(
5744 static_cast<std::uint8_t>(refinement_case()));
5745
5746 Assert(this_refinement_case != RefinementCase<2>::no_refinement,
5748
5749 if (this_refinement_case == RefinementCase<2>::cut_xy)
5750 return child(i);
5751 else if ((this_refinement_case == RefinementCase<2>::cut_x) &&
5752 (child(i % 2)->refinement_case() ==
5754 return child(i % 2)->child(i / 2);
5755 else if ((this_refinement_case == RefinementCase<2>::cut_y) &&
5756 (child(i / 2)->refinement_case() ==
5758 return child(i / 2)->child(i % 2);
5759 else
5760 Assert(
5761 false,
5762 ExcMessage(
5763 "This cell has no grandchildren equivalent to isotropic refinement"));
5764 break;
5765 }
5766
5767 default:
5769 }
5770 // we don't get here but have to return
5771 // something...
5772 return child(0);
5773}
5774
5775
5776
5777template <int structdim, int dim, int spacedim>
5778inline bool
5780{
5781 Assert(this->state() == IteratorState::valid,
5782 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5783 *this));
5784
5785 // each set of two children are stored consecutively, so we only have to find
5786 // the location of the set of children
5787 const auto &objects = this->objects();
5788 const unsigned int n_sets_of_two = objects.children_per_object / 2;
5789 return (objects.children[n_sets_of_two * this->present_index] != -1);
5790}
5791
5792
5793
5794template <int structdim, int dim, int spacedim>
5795inline unsigned int
5797{
5798 Assert(this->state() == IteratorState::valid,
5799 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5800 *this));
5801
5802 return reference_cell().n_children(refinement_case());
5803}
5804
5805
5806
5807template <int structdim, int dim, int spacedim>
5808inline void
5810 const RefinementCase<structdim> &refinement_case) const
5811{
5812 Assert(this->state() == IteratorState::valid,
5813 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5814 *this));
5815 Assert(static_cast<unsigned int>(this->present_index) <
5816 this->objects().refinement_cases.size(),
5817 ExcIndexRange(this->present_index,
5818 0,
5819 this->objects().refinement_cases.size()));
5820
5821 this->objects().refinement_cases[this->present_index] = refinement_case;
5822}
5823
5824
5825template <int structdim, int dim, int spacedim>
5826inline void
5828{
5829 Assert(this->state() == IteratorState::valid,
5830 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5831 *this));
5832 Assert(static_cast<unsigned int>(this->present_index) <
5833 this->objects().refinement_cases.size(),
5834 ExcIndexRange(this->present_index,
5835 0,
5836 this->objects().refinement_cases.size()));
5837
5838 this->objects().refinement_cases[this->present_index] =
5840}
5841
5842
5843
5844template <int structdim, int dim, int spacedim>
5845void
5847 const int index) const
5848{
5851
5852 // each set of two children are stored consecutively, so we only have to find
5853 // the location of the set of children
5854 auto &objects = this->objects();
5855 const unsigned int n_sets_of_two = objects.children_per_object / 2;
5856 Assert(
5857 // clearing the child index for a cell
5858 (index == -1) ||
5859 // if setting the child index for the i'th child (with i==0), then the
5860 // index must be a non-negative number
5861 (i == 0 && !this->has_children() && (index >= 0)) ||
5862 // if setting the child index for the i'th child (with i>0), then the
5863 // previously stored index must be the invalid index
5864 (i > 0 && this->has_children() && (index >= 0) &&
5865 objects.children[n_sets_of_two * this->present_index + i / 2] == -1),
5867
5868 objects.children[n_sets_of_two * this->present_index + i / 2] = index;
5869}
5870
5871
5872
5873template <int structdim, int dim, int spacedim>
5874void
5876{
5877 // each set of two children are stored consecutively, so we only have to find
5878 // the location of the set of children
5879 const auto &objects = this->objects();
5880 const unsigned int n_sets_of_two = objects.children_per_object / 2;
5881 for (unsigned int i = 0; i < n_sets_of_two; ++i)
5882 set_children(2 * i, -1);
5883}
5884
5885
5886
5887template <int structdim, int dim, int spacedim>
5888inline bool
5890{
5892 return this->objects().user_flags[this->present_index];
5893}
5894
5895
5896
5897template <int structdim, int dim, int spacedim>
5898inline void
5900{
5902 this->objects().user_flags[this->present_index] = true;
5903}
5904
5905
5906
5907template <int structdim, int dim, int spacedim>
5908inline void
5910{
5912 this->objects().user_flags[this->present_index] = false;
5913}
5914
5915
5916
5917template <int structdim, int dim, int spacedim>
5918void
5920{
5921 set_user_flag();
5922
5923 if (this->has_children())
5924 for (unsigned int c = 0; c < this->n_children(); ++c)
5925 this->child(c)->recursively_set_user_flag();
5926}
5927
5928
5929
5930template <int structdim, int dim, int spacedim>
5931void
5933{
5934 clear_user_flag();
5935
5936 if (this->has_children())
5937 for (unsigned int c = 0; c < this->n_children(); ++c)
5938 this->child(c)->recursively_clear_user_flag();
5939}
5940
5941
5942
5943template <int structdim, int dim, int spacedim>
5944void
5946{
5948 this->objects().clear_user_data(this->present_index);
5949}
5950
5951
5952
5953template <int structdim, int dim, int spacedim>
5954void
5956{
5958 this->objects().user_pointer(this->present_index) = p;
5959}
5960
5961
5962
5963template <int structdim, int dim, int spacedim>
5964void
5966{
5968 this->objects().user_pointer(this->present_index) = nullptr;
5969}
5970
5971
5972
5973template <int structdim, int dim, int spacedim>
5974void *
5976{
5978 return this->objects().user_pointer(this->present_index);
5979}
5980
5981
5982
5983template <int structdim, int dim, int spacedim>
5984void
5986 void *p) const
5987{
5988 set_user_pointer(p);
5989
5990 if (this->has_children())
5991 for (unsigned int c = 0; c < this->n_children(); ++c)
5992 this->child(c)->recursively_set_user_pointer(p);
5993}
5994
5995
5996
5997template <int structdim, int dim, int spacedim>
5998void
6000{
6001 clear_user_pointer();
6002
6003 if (this->has_children())
6004 for (unsigned int c = 0; c < this->n_children(); ++c)
6005 this->child(c)->recursively_clear_user_pointer();
6006}
6007
6008
6009
6010template <int structdim, int dim, int spacedim>
6011void
6013 const unsigned int p) const
6014{
6016 this->objects().user_index(this->present_index) = p;
6017}
6018
6019
6020
6021template <int structdim, int dim, int spacedim>
6022void
6024{
6026 this->objects().user_index(this->present_index) = 0;
6027}
6028
6029
6030
6031template <int structdim, int dim, int spacedim>
6032unsigned int
6034{
6036 return this->objects().user_index(this->present_index);
6037}
6038
6039
6040
6041template <int structdim, int dim, int spacedim>
6042void
6044 const unsigned int p) const
6045{
6046 set_user_index(p);
6047
6048 if (this->has_children())
6049 for (unsigned int c = 0; c < this->n_children(); ++c)
6050 this->child(c)->recursively_set_user_index(p);
6051}
6052
6053
6054
6055template <int structdim, int dim, int spacedim>
6056void
6058{
6059 clear_user_index();
6060
6061 if (this->has_children())
6062 for (unsigned int c = 0; c < this->n_children(); ++c)
6063 this->child(c)->recursively_clear_user_index();
6064}
6065
6066
6067
6068template <int structdim, int dim, int spacedim>
6069inline unsigned int
6071{
6072 if (!this->has_children())
6073 return 0;
6074
6075 unsigned int max_depth = 1;
6076 for (unsigned int c = 0; c < n_children(); ++c)
6077 max_depth = std::max(max_depth, child(c)->max_refinement_depth() + 1);
6078 return max_depth;
6079}
6080
6081
6082
6083template <int structdim, int dim, int spacedim>
6084unsigned int
6086{
6087 if (!this->has_children())
6088 return 1;
6089 else
6090 {
6091 unsigned int sum = 0;
6092 for (unsigned int c = 0; c < n_children(); ++c)
6093 sum += this->child(c)->n_active_descendants();
6094 return sum;
6095 }
6096}
6097
6098
6099
6100template <int structdim, int dim, int spacedim>
6103{
6104 Assert(structdim < dim, ExcImpossibleInDim(dim));
6106
6107 return this->objects()
6108 .boundary_or_material_id[this->present_index]
6109 .boundary_id;
6110}
6111
6112
6113
6114template <int structdim, int dim, int spacedim>
6115void
6117 const types::boundary_id boundary_ind) const
6118{
6119 Assert(structdim < dim, ExcImpossibleInDim(dim));
6122 ExcMessage("You are trying to set the boundary_id to an invalid "
6123 "value (numbers::internal_face_boundary_id is reserved)."));
6124 Assert(this->at_boundary(),
6125 ExcMessage("You are trying to set the boundary_id of an "
6126 "internal object, which is not allowed!"));
6127
6128 this->objects().boundary_or_material_id[this->present_index].boundary_id =
6129 boundary_ind;
6130}
6131
6132
6133
6134template <int structdim, int dim, int spacedim>
6135void
6137 const types::boundary_id boundary_ind) const
6138{
6139 Assert(structdim < dim, ExcImpossibleInDim(dim));
6141
6142 this->objects().boundary_or_material_id[this->present_index].boundary_id =
6143 boundary_ind;
6144}
6145
6146
6147
6148template <int structdim, int dim, int spacedim>
6149void
6151 const types::boundary_id boundary_ind) const
6152{
6153 set_boundary_id(boundary_ind);
6154
6155 switch (structdim)
6156 {
6157 case 1:
6158 // 1d objects have no sub-objects where we have to do anything
6159 break;
6160
6161 case 2:
6162 // for boundary quads also set boundary_id of bounding lines
6163 for (unsigned int i = 0; i < this->n_lines(); ++i)
6164 this->line(i)->set_boundary_id(boundary_ind);
6165 break;
6166
6167 default:
6169 }
6170}
6171
6172
6173
6174template <int structdim, int dim, int spacedim>
6175bool
6177{
6178 // error checking is done in boundary_id()
6180}
6181
6182
6183
6184template <int structdim, int dim, int spacedim>
6187{
6189 return this->tria->get_manifold(this->manifold_id());
6190}
6191
6192
6193template <int structdim, int dim, int spacedim>
6196{
6198
6199 return this->objects().manifold_id[this->present_index];
6200}
6201
6202
6203
6204template <int structdim, int dim, int spacedim>
6205void
6207 const types::manifold_id manifold_ind) const
6208{
6210
6211 this->objects().manifold_id[this->present_index] = manifold_ind;
6212}
6213
6214
6215template <int structdim, int dim, int spacedim>
6216void
6218 const types::manifold_id manifold_ind) const
6219{
6220 set_manifold_id(manifold_ind);
6221
6222 if (this->has_children())
6223 for (unsigned int c = 0; c < this->n_children(); ++c)
6224 this->child(c)->set_all_manifold_ids(manifold_ind);
6225
6226 switch (structdim)
6227 {
6228 case 1:
6229 if (dim == 1)
6230 {
6231 (*this->tria->vertex_to_manifold_id_map_1d)[vertex_index(0)] =
6232 manifold_ind;
6233 (*this->tria->vertex_to_manifold_id_map_1d)[vertex_index(1)] =
6234 manifold_ind;
6235 }
6236 break;
6237
6238 case 2:
6239 // for quads/simplices also set manifold_id of bounding lines
6240 for (unsigned int i = 0; i < this->n_lines(); ++i)
6241 this->line(i)->set_manifold_id(manifold_ind);
6242 break;
6243 default:
6245 }
6246}
6247
6248
6249
6250template <int structdim, int dim, int spacedim>
6251double
6253{
6255# ifndef _MSC_VER
6256 ReferenceCells::max_n_vertices<structdim>()
6257# else
6259# endif
6260 >
6261 vertices(this->n_vertices());
6262
6263 for (unsigned int v = 0; v < vertices.size(); ++v)
6264 vertices[v] = this->vertex(v);
6265
6266 return internal::TriaAccessorImplementation::diameter<structdim, spacedim>(
6267 vertices);
6268}
6269
6270
6271
6272template <int dim, int spacedim>
6273double
6275 const Mapping<dim, spacedim> &mapping) const
6276{
6277 return internal::TriaAccessorImplementation::diameter<dim, spacedim>(
6279 this->tria, this->level(), this->index())));
6280}
6281
6282
6283
6284template <int structdim, int dim, int spacedim>
6285std::pair<Point<spacedim>, double>
6287{
6288 // If the object is one dimensional, the enclosing ball is the initial iterate
6289 // i.e., the ball's center and diameter are the center and the diameter of the
6290 // object.
6291 if (structdim == 1)
6292 return std::make_pair((this->vertex(1) + this->vertex(0)) * 0.5,
6293 (this->vertex(1) - this->vertex(0)).norm() * 0.5);
6294
6295 // The list is_initial_guess_vertex contains bool values and has the same size
6296 // as the number of vertices per object. The entries of
6297 // is_initial_guess_vertex are set true only for those two vertices
6298 // corresponding to the largest diagonal which is being used to construct the
6299 // initial ball. We employ this mask to skip these two vertices while
6300 // enlarging the ball.
6301 std::vector<bool> is_initial_guess_vertex(this->n_vertices());
6302
6303 // First let all the vertices be outside
6304 std::fill(is_initial_guess_vertex.begin(),
6305 is_initial_guess_vertex.end(),
6306 false);
6307
6308 // Get an initial guess by looking at the largest diagonal
6309 Point<spacedim> center;
6310 double radius = 0;
6311
6312 switch (structdim)
6313 {
6314 case 2:
6315 {
6316 const Point<spacedim> p30(this->vertex(3) - this->vertex(0));
6317 const Point<spacedim> p21(this->vertex(2) - this->vertex(1));
6318 if (p30.norm() > p21.norm())
6319 {
6320 center = this->vertex(0) + 0.5 * p30;
6321 radius = p30.norm() / 2.;
6322 is_initial_guess_vertex[3] = true;
6323 is_initial_guess_vertex[0] = true;
6324 }
6325 else
6326 {
6327 center = this->vertex(1) + 0.5 * p21;
6328 radius = p21.norm() / 2.;
6329 is_initial_guess_vertex[2] = true;
6330 is_initial_guess_vertex[1] = true;
6331 }
6332 break;
6333 }
6334 case 3:
6335 {
6336 const Point<spacedim> p70(this->vertex(7) - this->vertex(0));
6337 const Point<spacedim> p61(this->vertex(6) - this->vertex(1));
6338 const Point<spacedim> p25(this->vertex(2) - this->vertex(5));
6339 const Point<spacedim> p34(this->vertex(3) - this->vertex(4));
6340 const std::vector<double> diagonals = {p70.norm(),
6341 p61.norm(),
6342 p25.norm(),
6343 p34.norm()};
6344 const std::vector<double>::const_iterator it =
6345 std::max_element(diagonals.begin(), diagonals.end());
6346 if (it == diagonals.begin())
6347 {
6348 center = this->vertex(0) + 0.5 * p70;
6349 is_initial_guess_vertex[7] = true;
6350 is_initial_guess_vertex[0] = true;
6351 }
6352 else if (it == diagonals.begin() + 1)
6353 {
6354 center = this->vertex(1) + 0.5 * p61;
6355 is_initial_guess_vertex[6] = true;
6356 is_initial_guess_vertex[1] = true;
6357 }
6358 else if (it == diagonals.begin() + 2)
6359 {
6360 center = this->vertex(5) + 0.5 * p25;
6361 is_initial_guess_vertex[2] = true;
6362 is_initial_guess_vertex[5] = true;
6363 }
6364 else
6365 {
6366 center = this->vertex(4) + 0.5 * p34;
6367 is_initial_guess_vertex[3] = true;
6368 is_initial_guess_vertex[4] = true;
6369 }
6370 radius = *it * 0.5;
6371 break;
6372 }
6373 default:
6375 return std::pair<Point<spacedim>, double>();
6376 }
6377
6378 // For each vertex that is found to be geometrically outside the ball
6379 // enlarge the ball so that the new ball contains both the previous ball
6380 // and the given vertex.
6381 for (const unsigned int v : this->vertex_indices())
6382 if (!is_initial_guess_vertex[v])
6383 {
6384 const double distance = center.distance(this->vertex(v));
6385 if (distance > radius)
6386 {
6387 // we found a vertex which is outside of the ball extend it (move
6388 // center and change radius)
6389 const Point<spacedim> pCV(center - this->vertex(v));
6390 radius = (distance + radius) * 0.5;
6391 center = this->vertex(v) + pCV * (radius / distance);
6392
6393 // Now the new ball constructed in this block encloses the vertex
6394 // (v) that was found to be geometrically outside the old ball.
6395 }
6396 }
6397 if constexpr (running_in_debug_mode())
6398 {
6399 bool all_vertices_within_ball = true;
6400
6401 // Set all_vertices_within_ball false if any of the vertices of the object
6402 // are geometrically outside the ball
6403 for (const unsigned int v : this->vertex_indices())
6404 if (center.distance(this->vertex(v)) >
6405 radius + 100. * std::numeric_limits<double>::epsilon())
6406 {
6407 all_vertices_within_ball = false;
6408 break;
6409 }
6410 // If all the vertices are not within the ball throw error
6411 Assert(all_vertices_within_ball, ExcInternalError());
6412 }
6413 return std::make_pair(center, radius);
6414}
6415
6416
6417template <int structdim, int dim, int spacedim>
6418double
6420{
6421 switch (structdim)
6422 {
6423 case 1:
6424 return (this->vertex(1) - this->vertex(0)).norm();
6425 case 2:
6426 case 3:
6427 {
6428 double min = std::numeric_limits<double>::max();
6429 for (const unsigned int i : this->vertex_indices())
6430 for (unsigned int j = i + 1; j < this->n_vertices(); ++j)
6431 min = std::min(min,
6432 (this->vertex(i) - this->vertex(j)) *
6433 (this->vertex(i) - this->vertex(j)));
6434 return std::sqrt(min);
6435 }
6436 default:
6438 return -1e10;
6439 }
6440}
6441
6442
6443template <int structdim, int dim, int spacedim>
6444bool
6447{
6448 // go through the vertices and check... The cell is a translation of the
6449 // previous one in case the distance between the individual vertices in the
6450 // two cell is the same for all the vertices. So do the check by first getting
6451 // the distance on the first vertex, and then checking whether all others have
6452 // the same down to rounding errors (we have to be careful here because the
6453 // calculation of the displacement between one cell and the next can already
6454 // result in the loss of one or two digits), so we choose 1e-12 times the
6455 // distance between the zeroth vertices here.
6456 bool is_translation = true;
6457 const Tensor<1, spacedim> dist = o->vertex(0) - this->vertex(0);
6458 const double tol_square = 1e-24 * dist.norm_square();
6459 for (unsigned int i = 1; i < this->n_vertices(); ++i)
6460 {
6461 const Tensor<1, spacedim> dist_new =
6462 (o->vertex(i) - this->vertex(i)) - dist;
6463 if (dist_new.norm_square() > tol_square)
6464 {
6465 is_translation = false;
6466 break;
6467 }
6468 }
6469 return is_translation;
6470}
6471
6472
6473
6474template <int structdim, int dim, int spacedim>
6475unsigned int
6477{
6478 return this->reference_cell().n_vertices();
6479}
6480
6481
6482
6483template <int structdim, int dim, int spacedim>
6484unsigned int
6486{
6487 return this->reference_cell().n_lines();
6488}
6489
6490
6491
6492template <int structdim, int dim, int spacedim>
6493unsigned int
6495{
6496 Assert(structdim == dim,
6497 ExcMessage("This function can only be used on objects "
6498 "that are cells, but not on faces or edges "
6499 "that bound cells."));
6500
6501 return this->reference_cell().n_faces();
6502}
6503
6504
6505
6506template <int structdim, int dim, int spacedim>
6509{
6511 n_vertices());
6512}
6513
6514
6515
6516template <int structdim, int dim, int spacedim>
6519{
6521 n_lines());
6522}
6523
6524
6525
6526template <int structdim, int dim, int spacedim>
6529{
6531 n_faces());
6532}
6533
6534
6535
6536/*----------------- Functions: TriaAccessor<0,dim,spacedim> -----------------*/
6537
6538template <int dim, int spacedim>
6540 const Triangulation<dim, spacedim> *tria,
6541 const unsigned int vertex_index)
6542 : tria(tria)
6543 , global_vertex_index(vertex_index)
6544{}
6545
6546
6547
6548template <int dim, int spacedim>
6550 const Triangulation<dim, spacedim> *tria,
6551 const int /*level*/,
6552 const int index,
6553 const AccessorData *)
6554 : tria(tria)
6556{}
6557
6558
6559
6560template <int dim, int spacedim>
6561template <int structdim2, int dim2, int spacedim2>
6564 : tria(nullptr)
6566{
6567 Assert(false, ExcImpossibleInDim(0));
6568}
6569
6570
6571
6572template <int dim, int spacedim>
6573template <int structdim2, int dim2, int spacedim2>
6576 : tria(nullptr)
6578{
6579 Assert(false, ExcImpossibleInDim(0));
6580}
6581
6582
6583
6584template <int dim, int spacedim>
6585inline void
6587{
6588 tria = t.tria;
6589 global_vertex_index = t.global_vertex_index;
6590}
6591
6592
6593
6594template <int dim, int spacedim>
6595inline bool
6597 const TriaAccessor<0, dim, spacedim> &other) const
6598{
6600
6601 return (global_vertex_index < other.global_vertex_index);
6602}
6603
6604
6605
6606template <int dim, int spacedim>
6609{
6610 if (global_vertex_index != numbers::invalid_unsigned_int)
6611 return IteratorState::valid;
6612 else
6614}
6615
6616
6617
6618template <int dim, int spacedim>
6619inline int
6621{
6622 return 0;
6623}
6624
6625
6626
6627template <int dim, int spacedim>
6628inline int
6630{
6631 return global_vertex_index;
6632}
6633
6634
6635
6636template <int dim, int spacedim>
6637inline const Triangulation<dim, spacedim> &
6639{
6640 return *tria;
6641}
6642
6643
6644
6645template <int dim, int spacedim>
6646inline void
6648{
6650 if (global_vertex_index >= tria->n_vertices())
6652}
6653
6654
6655
6656template <int dim, int spacedim>
6657inline void
6659{
6660 if (global_vertex_index != numbers::invalid_unsigned_int)
6661 {
6662 if (global_vertex_index != 0)
6664 else
6666 }
6667}
6668
6669
6670
6671template <int dim, int spacedim>
6672inline bool
6674{
6675 const bool result =
6676 ((tria == t.tria) && (global_vertex_index == t.global_vertex_index));
6677
6678 return result;
6679}
6680
6681
6682
6683template <int dim, int spacedim>
6684inline bool
6686{
6687 return !(*this == t);
6688}
6689
6690
6691
6692template <int dim, int spacedim>
6693inline unsigned int
6694TriaAccessor<0, dim, spacedim>::vertex_index(const unsigned int) const
6695{
6696 return global_vertex_index;
6697}
6698
6699
6700
6701template <int dim, int spacedim>
6702inline Point<spacedim> &
6703TriaAccessor<0, dim, spacedim>::vertex(const unsigned int) const
6704{
6705 return const_cast<Point<spacedim> &>(
6706 this->tria->vertices[global_vertex_index]);
6707}
6708
6709
6710
6711template <int dim, int spacedim>
6712inline typename ::internal::TriangulationImplementation::
6713 Iterators<dim, spacedim>::line_iterator
6714 TriaAccessor<0, dim, spacedim>::line(const unsigned int)
6715{
6716 return typename ::internal::TriangulationImplementation::
6717 Iterators<dim, spacedim>::line_iterator();
6718}
6719
6720
6721
6722template <int dim, int spacedim>
6723inline unsigned int
6725{
6726 Assert(false, ExcImpossibleInDim(0));
6728}
6729
6730
6731
6732template <int dim, int spacedim>
6733inline typename ::internal::TriangulationImplementation::
6734 Iterators<dim, spacedim>::quad_iterator
6735 TriaAccessor<0, dim, spacedim>::quad(const unsigned int)
6736{
6737 return typename ::internal::TriangulationImplementation::
6738 Iterators<dim, spacedim>::quad_iterator();
6739}
6740
6741
6742
6743template <int dim, int spacedim>
6744inline unsigned int
6746{
6747 Assert(false, ExcImpossibleInDim(0));
6749}
6750
6751
6752
6753template <int dim, int spacedim>
6754inline double
6756{
6757 return 0.;
6758}
6759
6760
6761
6762template <int dim, int spacedim>
6763inline double
6765{
6766 return 0.;
6767}
6768
6769
6770
6771template <int dim, int spacedim>
6772inline Point<spacedim>
6773TriaAccessor<0, dim, spacedim>::center(const bool, const bool) const
6774{
6775 return this->tria->vertices[global_vertex_index];
6776}
6777
6778
6779
6780template <int dim, int spacedim>
6781inline double
6783{
6784 return 1.0;
6785}
6786
6787
6788
6789template <int dim, int spacedim>
6792 const unsigned int /*face*/)
6793{
6795}
6796
6797
6798
6799template <int dim, int spacedim>
6800inline bool
6801TriaAccessor<0, dim, spacedim>::face_orientation(const unsigned int /*face*/)
6802{
6803 return false;
6804}
6805
6806
6807
6808template <int dim, int spacedim>
6809inline bool
6810TriaAccessor<0, dim, spacedim>::face_flip(const unsigned int /*face*/)
6811{
6812 return false;
6813}
6814
6815
6816
6817template <int dim, int spacedim>
6818inline bool
6819TriaAccessor<0, dim, spacedim>::face_rotation(const unsigned int /*face*/)
6820{
6821 return false;
6822}
6823
6824
6825
6826template <int dim, int spacedim>
6828TriaAccessor<0, dim, spacedim>::line_orientation(const unsigned int /*line*/)
6829{
6831}
6832
6833
6834
6835template <int dim, int spacedim>
6836inline bool
6838{
6839 return false;
6840}
6841
6842
6843
6844template <int dim, int spacedim>
6845inline unsigned int
6847{
6848 return 0;
6849}
6850
6851
6852
6853template <int dim, int spacedim>
6854inline unsigned int
6856{
6857 return 0;
6858}
6859
6860
6861
6862template <int dim, int spacedim>
6863inline unsigned int
6865{
6866 return 0;
6867}
6868
6869
6870
6871template <int dim, int spacedim>
6872inline unsigned int
6875{
6877}
6878
6879
6880
6881template <int dim, int spacedim>
6883TriaAccessor<0, dim, spacedim>::child(const unsigned int)
6884{
6886}
6887
6888
6889
6890template <int dim, int spacedim>
6893{
6895}
6896
6897
6898
6899template <int dim, int spacedim>
6900inline RefinementCase<0>
6902{
6904}
6905
6906
6907
6908template <int dim, int spacedim>
6909inline int
6911{
6912 return -1;
6913}
6914
6915
6916
6917template <int dim, int spacedim>
6918inline int
6920{
6921 return -1;
6922}
6923
6924
6925
6926template <int dim, int spacedim>
6927inline bool
6929{
6930 return tria->vertex_used(global_vertex_index);
6931}
6932
6933
6934
6935/*------------------- Functions: TriaAccessor<0,1,spacedim> -----------------*/
6936
6937template <int spacedim>
6939 const Triangulation<1, spacedim> *tria,
6940 const VertexKind vertex_kind,
6941 const unsigned int vertex_index)
6942 : tria(tria)
6943 , vertex_kind(vertex_kind)
6944 , global_vertex_index(vertex_index)
6945{}
6946
6947
6948
6949template <int spacedim>
6951 const Triangulation<1, spacedim> *tria,
6952 const int level,
6953 const int index,
6954 const AccessorData *)
6955 : tria(tria)
6956 , vertex_kind(interior_vertex)
6958{
6959 // in general, calling this constructor should yield an error -- users should
6960 // instead call the one immediately above. however, if you create something
6961 // like Triangulation<1>::face_iterator() then this calls the default
6962 // constructor of the iterator which calls the accessor with argument list
6963 // (0,-2,-2,0), so in this particular case accept this call and create an
6964 // object that corresponds to the default constructed (invalid) vertex
6965 // accessor
6966 (void)level;
6967 (void)index;
6968 Assert((level == -2) && (index == -2),
6969 ExcMessage(
6970 "This constructor can not be called for face iterators in 1d, "
6971 "except to default-construct iterator objects."));
6972}
6973
6974
6975
6976template <int spacedim>
6977template <int structdim2, int dim2, int spacedim2>
6980 : tria(nullptr)
6981 , vertex_kind(interior_vertex)
6983{
6984 Assert(false, ExcImpossibleInDim(0));
6985}
6986
6987
6988
6989template <int spacedim>
6990template <int structdim2, int dim2, int spacedim2>
6993 : tria(nullptr)
6994 , vertex_kind(interior_vertex)
6996{
6997 Assert(false, ExcImpossibleInDim(0));
6998}
6999
7000
7001
7002template <int spacedim>
7003inline void
7005{
7006 tria = t.tria;
7007 vertex_kind = t.vertex_kind;
7008 global_vertex_index = t.global_vertex_index;
7009}
7010
7011
7012
7013template <int spacedim>
7014inline void
7017{
7018 // We cannot convert from TriaAccessorBase to
7019 // TriaAccessor<0,1,spacedim> because the latter is not derived from
7020 // the former. We should never get here.
7022}
7023
7024
7025
7026template <int spacedim>
7027inline bool
7029 const TriaAccessor<0, 1, spacedim> &other) const
7030{
7032
7033 return (global_vertex_index < other.global_vertex_index);
7034}
7035
7036
7037
7038template <int spacedim>
7041{
7042 return IteratorState::valid;
7043}
7044
7045
7046template <int spacedim>
7047inline int
7049{
7050 return 0;
7051}
7052
7053
7054
7055template <int spacedim>
7056inline int
7058{
7059 return global_vertex_index;
7060}
7061
7062
7063
7064template <int spacedim>
7065inline const Triangulation<1, spacedim> &
7067{
7068 return *tria;
7069}
7070
7071
7072
7073template <int spacedim>
7074inline void
7076{
7078}
7079
7080
7081template <int spacedim>
7082inline void
7084{
7086}
7087
7088
7089
7090template <int spacedim>
7091inline bool
7093{
7094 const bool result =
7095 ((tria == t.tria) && (global_vertex_index == t.global_vertex_index));
7096 // if we point to the same vertex, make sure we know the same about it
7097 if (result == true)
7098 Assert(vertex_kind == t.vertex_kind, ExcInternalError());
7099
7100 return result;
7101}
7102
7103
7104
7105template <int spacedim>
7106inline bool
7108{
7109 return !(*this == t);
7110}
7111
7112
7113
7114template <int spacedim>
7115inline unsigned int
7116TriaAccessor<0, 1, spacedim>::vertex_index(const unsigned int i) const
7117{
7118 AssertIndexRange(i, 1);
7119 (void)i;
7120 return global_vertex_index;
7121}
7122
7123
7124
7125template <int spacedim>
7126inline Point<spacedim> &
7127TriaAccessor<0, 1, spacedim>::vertex(const unsigned int i) const
7128{
7129 AssertIndexRange(i, 1);
7130 (void)i;
7131 return const_cast<Point<spacedim> &>(
7132 this->tria->vertices[global_vertex_index]);
7133}
7134
7135
7136
7137template <int spacedim>
7138inline Point<spacedim>
7140{
7141 return this->tria->vertices[global_vertex_index];
7142}
7143
7144
7145
7146template <int spacedim>
7147inline typename ::internal::TriangulationImplementation::
7148 Iterators<1, spacedim>::line_iterator
7149 TriaAccessor<0, 1, spacedim>::line(const unsigned int)
7150{
7151 return {};
7152}
7153
7154
7155template <int spacedim>
7156inline unsigned int
7158{
7159 Assert(false, ExcImpossibleInDim(0));
7161}
7162
7163
7164template <int spacedim>
7165inline typename ::internal::TriangulationImplementation::
7166 Iterators<1, spacedim>::quad_iterator
7167 TriaAccessor<0, 1, spacedim>::quad(const unsigned int)
7168{
7169 return {};
7170}
7171
7172
7173
7174template <int spacedim>
7175inline unsigned int
7177{
7178 Assert(false, ExcImpossibleInDim(0));
7180}
7181
7182
7183
7184template <int spacedim>
7185inline double
7187{
7188 return 1.0;
7189}
7190
7191
7192
7193template <int spacedim>
7194inline bool
7196{
7197 return vertex_kind != interior_vertex;
7198}
7199
7200
7201template <int spacedim>
7202inline types::boundary_id
7204{
7205 switch (vertex_kind)
7206 {
7207 case left_vertex:
7208 case right_vertex:
7209 {
7211 this->vertex_index()) !=
7212 tria->vertex_to_boundary_id_map_1d->end(),
7214
7215 return (*tria->vertex_to_boundary_id_map_1d)[this->vertex_index()];
7216 }
7217
7218 default:
7220 }
7221}
7222
7223
7224
7225template <int spacedim>
7226inline const Manifold<1, spacedim> &
7228{
7229 return this->tria->get_manifold(this->manifold_id());
7230}
7231
7232
7233
7234template <int spacedim>
7235inline types::manifold_id
7237{
7238 if (tria->vertex_to_manifold_id_map_1d->find(this->vertex_index()) !=
7239 tria->vertex_to_manifold_id_map_1d->end())
7240 return (*tria->vertex_to_manifold_id_map_1d)[this->vertex_index()];
7241 else
7243}
7244
7245
7246template <int spacedim>
7249 const unsigned int /*face*/)
7250{
7252}
7253
7254
7255template <int spacedim>
7256inline bool
7257TriaAccessor<0, 1, spacedim>::face_orientation(const unsigned int /*face*/)
7258{
7259 return false;
7260}
7261
7262
7263
7264template <int spacedim>
7265inline bool
7266TriaAccessor<0, 1, spacedim>::face_flip(const unsigned int /*face*/)
7267{
7268 return false;
7269}
7270
7271
7272
7273template <int spacedim>
7274inline bool
7275TriaAccessor<0, 1, spacedim>::face_rotation(const unsigned int /*face*/)
7276{
7277 return false;
7278}
7279
7280
7281
7282template <int spacedim>
7284TriaAccessor<0, 1, spacedim>::line_orientation(const unsigned int /*line*/)
7285{
7287}
7288
7289
7290
7291template <int spacedim>
7292inline bool
7294{
7295 return false;
7296}
7297
7298
7299
7300template <int spacedim>
7301inline unsigned int
7303{
7304 return 0;
7305}
7306
7307
7308
7309template <int spacedim>
7310inline unsigned int
7312{
7313 return 0;
7314}
7315
7316
7317
7318template <int spacedim>
7319inline unsigned int
7321{
7322 return 0;
7323}
7324
7325
7326
7327template <int spacedim>
7328inline unsigned int
7331{
7333}
7334
7335
7336
7337template <int spacedim>
7339TriaAccessor<0, 1, spacedim>::child(const unsigned int)
7340{
7342}
7343
7344
7345template <int spacedim>
7348{
7350}
7351
7352
7353template <int spacedim>
7354inline RefinementCase<0>
7356{
7358}
7359
7360template <int spacedim>
7361inline int
7363{
7364 return -1;
7365}
7366
7367
7368template <int spacedim>
7369inline int
7371{
7372 return -1;
7373}
7374
7375
7376
7377template <int spacedim>
7378inline void
7380{
7381 Assert(tria->vertex_to_boundary_id_map_1d->find(this->vertex_index()) !=
7382 tria->vertex_to_boundary_id_map_1d->end(),
7383 ExcMessage("You can't set the boundary_id of a face of a cell that is "
7384 "not actually at the boundary."));
7385
7386 (*tria->vertex_to_boundary_id_map_1d)[this->vertex_index()] = b;
7387}
7388
7389
7390
7391template <int spacedim>
7392inline void
7394{
7395 (*tria->vertex_to_manifold_id_map_1d)[this->vertex_index()] = b;
7396}
7397
7398
7399
7400template <int spacedim>
7401inline void
7403 const types::boundary_id b) const
7404{
7405 set_boundary_id(b);
7406}
7407
7408
7409
7410template <int spacedim>
7411inline void
7413{
7414 set_manifold_id(b);
7415}
7416
7417
7418
7419template <int spacedim>
7420inline bool
7422{
7423 return tria->vertex_used(global_vertex_index);
7424}
7425
7426
7427
7428template <int spacedim>
7429inline ReferenceCell<0>
7431{
7433}
7434
7435
7436
7437template <int spacedim>
7438unsigned int
7440{
7441 return 1;
7442}
7443
7444
7445
7446template <int spacedim>
7447unsigned int
7449{
7450 return 0;
7451}
7452
7453
7454
7455template <int spacedim>
7458{
7460 n_vertices());
7461}
7462
7463
7464
7465template <int spacedim>
7468{
7470 n_lines());
7471}
7472
7473/*------------------ Functions: CellAccessor<dim,spacedim> ------------------*/
7474
7475
7476template <int dim, int spacedim>
7478 const Triangulation<dim, spacedim> *parent,
7479 const int level,
7480 const int index,
7481 const AccessorData *local_data)
7482 : TriaAccessor<dim, dim, spacedim>(parent, level, index, local_data)
7483{}
7484
7485
7486
7487template <int dim, int spacedim>
7489 const TriaAccessor<dim, dim, spacedim> &cell_accessor)
7490 : TriaAccessor<dim, dim, spacedim>(
7491 static_cast<const TriaAccessor<dim, dim, spacedim> &>(cell_accessor))
7492{}
7493
7494
7495
7496template <int dim, int spacedim>
7498CellAccessor<dim, spacedim>::child(const unsigned int i) const
7499{
7501 this->level() + 1,
7502 this->child_index(i));
7503
7504 Assert((q.state() == IteratorState::past_the_end) || q->used(),
7506
7507 return q;
7508}
7509
7510
7511
7512template <int dim, int spacedim>
7513inline boost::container::small_vector<TriaIterator<CellAccessor<dim, spacedim>>,
7514 ReferenceCells::max_n_children<dim>()>
7516{
7517 boost::container::small_vector<TriaIterator<CellAccessor<dim, spacedim>>,
7518 ReferenceCells::max_n_children<dim>()>
7519 child_iterators(this->n_children());
7520
7521 for (unsigned int i = 0; i < this->n_children(); ++i)
7522 child_iterators[i] = this->child(i);
7523
7524 return child_iterators;
7525}
7526
7527
7528
7529template <int dim, int spacedim>
7530inline TriaIterator<TriaAccessor<dim - 1, dim, spacedim>>
7531CellAccessor<dim, spacedim>::face(const unsigned int i) const
7532{
7533 AssertIndexRange(i, this->n_faces());
7534 if constexpr (dim == 1)
7535 {
7536 using VertexKind = typename TriaAccessor<0, 1, spacedim>::VertexKind;
7537 VertexKind vertex_kind = VertexKind::interior_vertex;
7538 if (i == 0 && at_boundary(0))
7539 vertex_kind = VertexKind::left_vertex;
7540 if (i == 1 && at_boundary(1))
7541 vertex_kind = VertexKind::right_vertex;
7542 TriaAccessor<0, 1, spacedim> a(&this->get_triangulation(),
7543 vertex_kind,
7544 this->vertex_index(i));
7546 }
7547 else if constexpr (dim == 2)
7548 return this->line(i);
7549 else if constexpr (dim == 3)
7550 return this->quad(i);
7551 else
7552 {
7553 Assert(false, ExcNotImplemented());
7554 return {};
7555 }
7556}
7557
7558
7559
7560template <int dim, int spacedim>
7561inline unsigned int
7564{
7565 for (const unsigned int face_n : this->face_indices())
7566 if (this->face(face_n) == face)
7567 return face_n;
7568
7569 Assert(false,
7570 ExcMessage("The given face is not a face of the current cell."));
7572}
7573
7574
7575
7576template <int dim, int spacedim>
7577inline boost::container::small_vector<
7578 TriaIterator<TriaAccessor<dim - 1, dim, spacedim>>,
7579# ifndef _MSC_VER
7580 ReferenceCells::max_n_faces<dim>()
7581# else
7583# endif
7584 >
7586{
7587 boost::container::small_vector<
7588 TriaIterator<TriaAccessor<dim - 1, dim, spacedim>>,
7589# ifndef _MSC_VER
7590 ReferenceCells::max_n_faces<dim>()
7591# else
7593# endif
7594 >
7595 face_iterators(this->n_faces());
7596
7597 for (const unsigned int i : this->face_indices())
7598 face_iterators[i] = this->face(i);
7599
7600 return face_iterators;
7601}
7602
7603
7604
7605template <int dim, int spacedim>
7606inline unsigned int
7607CellAccessor<dim, spacedim>::face_index(const unsigned int i) const
7608{
7609 switch (dim)
7610 {
7611 case 1:
7612 return this->vertex_index(i);
7613
7614 case 2:
7615 return this->line_index(i);
7616
7617 case 3:
7618 return this->quad_index(i);
7619
7620 default:
7622 }
7623}
7624
7625
7626
7627template <int dim, int spacedim>
7628inline int
7629CellAccessor<dim, spacedim>::neighbor_index(const unsigned int face_no) const
7630{
7631 AssertIndexRange(face_no, this->n_faces());
7632 return this->tria->levels[this->level()]->neighbor_index(this->present_index,
7633 face_no);
7634}
7635
7636
7637
7638template <int dim, int spacedim>
7639inline int
7640CellAccessor<dim, spacedim>::neighbor_level(const unsigned int face_no) const
7641{
7642 AssertIndexRange(face_no, this->n_faces());
7643 return this->tria->levels[this->level()]->neighbor_level(this->present_index,
7644 face_no);
7645}
7646
7647
7648
7649template <int dim, int spacedim>
7652{
7654 // cells flagged for refinement must be active (the @p set_refine_flag
7655 // function checks this, but activity may change when refinement is executed
7656 // and for some reason the refine flag is not cleared).
7657 Assert(
7658 this->is_active() ||
7659 !this->tria->levels[this->level()]->refine_flags[this->present_index],
7660 ExcRefineCellNotActive());
7661 return RefinementCase<dim>(
7662 this->tria->levels[this->level()]->refine_flags[this->present_index]);
7663}
7664
7665
7666
7667template <int dim, int spacedim>
7668inline void
7670 const RefinementCase<dim> refinement_case) const
7671{
7672 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
7673 Assert(!coarsen_flag_set(), ExcCellFlaggedForCoarsening());
7674
7675 this->tria->levels[this->level()]->refine_flags[this->present_index] =
7676 refinement_case;
7677}
7678
7679
7680
7681template <int dim, int spacedim>
7682inline void
7684{
7685 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
7686 this->tria->levels[this->level()]->refine_flags[this->present_index] =
7688}
7689
7690
7691template <int dim, int spacedim>
7692inline std::uint8_t
7694{
7696 if (this->tria->levels[this->level()]->refine_choice.size() == 0)
7697 return 0U;
7698 return this->tria->levels[this->level()]->refine_choice[this->present_index];
7699}
7700
7701
7702template <int dim, int spacedim>
7703inline void
7705 const std::uint8_t refinement_choice) const
7706{
7707 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
7708 if (this->tria->levels[this->level()]->refine_choice.size() != 0)
7709 this->tria->levels[this->level()]->refine_choice[this->present_index] =
7710 refinement_choice;
7711}
7712
7713
7714template <int dim, int spacedim>
7715inline void
7717{
7718 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
7719 if (this->tria->levels[this->level()]->refine_choice.size() != 0)
7720 this->tria->levels[this->level()]->refine_choice[this->present_index] =
7722}
7723
7724
7725template <int dim, int spacedim>
7726inline bool
7728 const unsigned int face_no,
7729 const RefinementCase<dim - 1> &face_refinement_case) const
7730{
7731 Assert(dim > 1, ExcImpossibleInDim(dim));
7732 AssertIndexRange(face_no, this->n_faces());
7733 AssertIndexRange(face_refinement_case,
7735
7736 // the new refinement case is a combination of the minimum required one for
7737 // the given face refinement and the already existing flagged refinement case
7738 RefinementCase<dim> old_ref_case = refine_flag_set();
7739 RefinementCase<dim> new_ref_case =
7740 (old_ref_case |
7742 face_refinement_case,
7743 face_no,
7744 this->face_orientation(face_no),
7745 this->face_flip(face_no),
7746 this->face_rotation(face_no)));
7747 set_refine_flag(new_ref_case);
7748 // return, whether we had to change the refinement flag
7749 return new_ref_case != old_ref_case;
7750}
7751
7752
7753
7754template <int dim, int spacedim>
7755inline bool
7757 const unsigned int line_no) const
7758{
7759 Assert(dim > 1, ExcImpossibleInDim(dim));
7760 AssertIndexRange(line_no, this->n_lines());
7761
7762 // the new refinement case is a combination of the minimum required one for
7763 // the given line refinement and the already existing flagged refinement case
7765 old_ref_case = refine_flag_set(),
7766 new_ref_case =
7767 old_ref_case |
7769 set_refine_flag(new_ref_case);
7770 // return, whether we had to change the refinement flag
7771 return new_ref_case != old_ref_case;
7772}
7773
7774
7775
7776template <int dim, int spacedim>
7778CellAccessor<dim, spacedim>::subface_case(const unsigned int face_no) const
7779{
7781 AssertIndexRange(face_no, this->n_faces());
7782
7783 if constexpr (dim == 1)
7785 else if constexpr (dim == 2)
7786 return ((face(face_no)->has_children()) ?
7788 internal::SubfaceCase<2>::case_none);
7789 else if constexpr (dim == 3)
7790 {
7791 switch (static_cast<std::uint8_t>(face(face_no)->refinement_case()))
7792 {
7796 if (face(face_no)->child(0)->has_children())
7797 {
7798 Assert(face(face_no)->child(0)->refinement_case() ==
7801 if (face(face_no)->child(1)->has_children())
7802 {
7803 Assert(face(face_no)->child(1)->refinement_case() ==
7807 }
7808 else
7810 }
7811 else
7812 {
7813 if (face(face_no)->child(1)->has_children())
7814 {
7815 Assert(face(face_no)->child(1)->refinement_case() ==
7819 }
7820 else
7822 }
7824 if (face(face_no)->child(0)->has_children())
7825 {
7826 Assert(face(face_no)->child(0)->refinement_case() ==
7829 if (face(face_no)->child(1)->has_children())
7830 {
7831 Assert(face(face_no)->child(1)->refinement_case() ==
7835 }
7836 else
7838 }
7839 else
7840 {
7841 if (face(face_no)->child(1)->has_children())
7842 {
7843 Assert(face(face_no)->child(1)->refinement_case() ==
7847 }
7848 else
7850 }
7853 default:
7855 }
7856 }
7857
7858 // we should never get here
7861}
7862
7863
7864
7865template <int dim, int spacedim>
7866inline bool
7868{
7870 // cells flagged for coarsening must be active (the @p set_refine_flag
7871 // function checks this, but activity may change when refinement is executed
7872 // and for some reason the refine flag is not cleared).
7873 Assert(
7874 this->is_active() ||
7875 !this->tria->levels[this->level()]->coarsen_flags[this->present_index],
7876 ExcRefineCellNotActive());
7877 return this->tria->levels[this->level()]->coarsen_flags[this->present_index];
7878}
7879
7880
7881
7882template <int dim, int spacedim>
7883inline void
7885{
7886 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
7887 Assert(!refine_flag_set(), ExcCellFlaggedForRefinement());
7888
7889 this->tria->levels[this->level()]->coarsen_flags[this->present_index] = true;
7890}
7891
7892
7893
7894template <int dim, int spacedim>
7895inline void
7897{
7898 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
7899 this->tria->levels[this->level()]->coarsen_flags[this->present_index] = false;
7900}
7901
7902
7903
7904template <int dim, int spacedim>
7906CellAccessor<dim, spacedim>::neighbor(const unsigned int face_no) const
7907{
7909 neighbor_level(face_no),
7910 neighbor_index(face_no));
7911
7912 Assert((q.state() == IteratorState::past_the_end) || q->used(),
7914
7915 return q;
7916}
7917
7918
7919
7920template <int dim, int spacedim>
7921inline bool
7923{
7924 return !this->has_children();
7925}
7926
7927
7928
7929template <int dim, int spacedim>
7930inline bool
7932{
7933 Assert(this->is_active(),
7934 ExcMessage("is_locally_owned() can only be called on active cells!"));
7935# ifndef DEAL_II_WITH_MPI
7936 return true;
7937# else
7938
7939 // Serial triangulations report invalid_subdomain_id as their locally owned
7940 // subdomain, so the first condition checks whether we have a serial
7941 // triangulation, in which case all cells are locally owned. The second
7942 // condition compares the subdomain id in the parallel case.
7943 const types::subdomain_id locally_owned_subdomain =
7944 this->tria->locally_owned_subdomain();
7945 return (locally_owned_subdomain == numbers::invalid_subdomain_id ||
7946 this->subdomain_id() == locally_owned_subdomain);
7947
7948# endif
7949}
7950
7951
7952template <int dim, int spacedim>
7953inline bool
7955{
7956# ifndef DEAL_II_WITH_MPI
7957 return true;
7958# else
7959
7960 // Serial triangulations report invalid_subdomain_id as their locally owned
7961 // subdomain, so the first condition checks whether we have a serial
7962 // triangulation, in which case all cells are locally owned. The second
7963 // condition compares the subdomain id in the parallel case.
7964 const types::subdomain_id locally_owned_subdomain =
7965 this->tria->locally_owned_subdomain();
7966 return (locally_owned_subdomain == numbers::invalid_subdomain_id ||
7967 this->level_subdomain_id() == locally_owned_subdomain);
7968
7969# endif
7970}
7971
7972
7973template <int dim, int spacedim>
7974inline bool
7976{
7977 Assert(this->is_active(),
7978 ExcMessage("is_ghost() can only be called on active cells!"));
7979 if (this->has_children())
7980 return false;
7981
7982# ifndef DEAL_II_WITH_MPI
7983 return false;
7984# else
7985
7986 // Serial triangulations report invalid_subdomain_id as their locally owned
7987 // subdomain, so the first condition rules out that case as all cells to a
7988 // serial triangulation are locally owned and none is ghosted. The second
7989 // and third conditions check whether the cell's subdomain is not the
7990 // locally owned one and not artificial.
7991 const types::subdomain_id locally_owned_subdomain =
7992 this->tria->locally_owned_subdomain();
7993 const types::subdomain_id subdomain_id = this->subdomain_id();
7994 return (locally_owned_subdomain != numbers::invalid_subdomain_id &&
7995 subdomain_id != locally_owned_subdomain &&
7996 subdomain_id != numbers::artificial_subdomain_id);
7997
7998# endif
7999}
8000
8001
8002template <int dim, int spacedim>
8003inline bool
8005{
8006# ifndef DEAL_II_WITH_MPI
8007 return false;
8008# else
8009
8010 // Serial triangulations report invalid_subdomain_id as their locally owned
8011 // subdomain, so the first condition checks whether we have a serial
8012 // triangulation, in which case all cells are locally owned. The second
8013 // condition compares the subdomain id in the parallel case.
8014 const types::subdomain_id locally_owned_subdomain =
8015 this->tria->locally_owned_subdomain();
8016 const types::subdomain_id subdomain_id = this->level_subdomain_id();
8017 return (locally_owned_subdomain != numbers::invalid_subdomain_id &&
8018 subdomain_id != locally_owned_subdomain &&
8019 subdomain_id != numbers::artificial_subdomain_id);
8020
8021# endif
8022}
8023
8024
8025
8026template <int dim, int spacedim>
8027inline bool
8029{
8030 Assert(this->is_active(),
8031 ExcMessage("is_artificial() can only be called on active cells!"));
8032# ifndef DEAL_II_WITH_MPI
8033 return false;
8034# else
8035
8036 // Serial triangulations report invalid_subdomain_id as their locally owned
8037 // subdomain, so the first condition rules out that case as all cells to a
8038 // serial triangulation are locally owned and none is artificial.
8039 return (this->tria->locally_owned_subdomain() !=
8041 this->subdomain_id() == numbers::artificial_subdomain_id);
8042
8043# endif
8044}
8045
8046
8047
8048template <int dim, int spacedim>
8049inline bool
8051{
8052# ifndef DEAL_II_WITH_MPI
8053 return false;
8054# else
8055 return (this->tria->locally_owned_subdomain() !=
8057 this->level_subdomain_id() == numbers::artificial_subdomain_id);
8058# endif
8059}
8060
8061
8062
8063template <int dim, int spacedim>
8064inline void
8066 const unsigned int face_no,
8067 const TriaIterator<CellAccessor<dim, spacedim>> &neighbor) const
8068{
8069 AssertIndexRange(face_no, this->n_faces());
8070
8071 Assert(neighbor.state() != IteratorState::invalid,
8072 ExcMessage("The provided neighbor must be either a valid iterator or "
8073 "an end iterator (to indicate a boundary face)"));
8074 auto &level = this->tria->levels[this->level()];
8075 level->set_neighbor(this->present_index,
8076 face_no,
8077 neighbor->level(),
8078 neighbor->index());
8079}
8080
8081
8082
8083template <int dim, int spacedim>
8084inline types::material_id
8086{
8088 return this->tria->levels[this->level()]
8089 ->cells.boundary_or_material_id[this->present_index]
8090 .material_id;
8091}
8092
8093
8094
8095template <int dim, int spacedim>
8098{
8100 Assert(this->is_active(),
8101 ExcMessage("subdomain_id() can only be called on active cells!"));
8102 return this->tria->levels[this->level()]->subdomain_ids[this->present_index];
8103}
8104
8105
8106
8107template <int dim, int spacedim>
8110{
8112 return this->tria->levels[this->level()]
8113 ->level_subdomain_ids[this->present_index];
8114}
8115
8116
8117
8118template <int dim, int spacedim>
8119inline unsigned int
8120CellAccessor<dim, spacedim>::neighbor_face_no(const unsigned int neighbor) const
8121{
8122 const unsigned int n2 = neighbor_of_neighbor_internal(neighbor);
8124 // return this value as the neighbor is not coarser
8125 return n2;
8126 else
8127 // the neighbor is coarser
8128 return neighbor_of_coarser_neighbor(neighbor).first;
8129}
8130
8131
8132
8133template <int dim, int spacedim>
8134inline bool
8136{
8137 return false;
8138}
8139
8140
8141
8142template <int dim, int spacedim>
8143inline unsigned int
8145{
8147 return this->tria->levels[this->level()]
8148 ->active_cell_indices[this->present_index];
8149}
8150
8151
8152
8153template <int dim, int spacedim>
8156{
8158 Assert(this->is_active(),
8159 ExcMessage(
8160 "global_active_cell_index() can only be called on active cells!"));
8161
8162 return this->tria->levels[this->level()]
8163 ->global_active_cell_indices[this->present_index];
8164}
8165
8166
8167
8168template <int dim, int spacedim>
8171{
8172 return this->tria->levels[this->level()]
8173 ->global_level_cell_indices[this->present_index];
8174}
8175
8176
8177
8178template <int dim, int spacedim>
8179inline bool
8181{
8183 if constexpr (dim == spacedim)
8184 return true;
8185 else if constexpr (dim == spacedim - 1)
8186 return this->tria->levels[this->level()]
8187 ->direction_flags[this->present_index];
8188 else
8189 {
8190 Assert(false,
8191 ExcMessage("This function cannot be called if dim<spacedim-1."));
8192 return true;
8193 }
8194}
8195
8196#endif // DOXYGEN
8197
8199
8200
8201#endif
*  *  for(const auto &cell :triangulation.active_cell_iterators())
*  const Number radius
void recursively_set_subdomain_id(const types::subdomain_id new_subdomain_id) const
CellAccessor(const Triangulation< dim, spacedim > *parent=nullptr, const int level=-1, const int index=-1, const AccessorData *local_data=nullptr)
TriaIterator< CellAccessor< dim, spacedim > > parent() const
unsigned int neighbor_face_no(const unsigned int neighbor) const
void set_active_cell_index(const unsigned int active_cell_index) const
unsigned int neighbor_of_neighbor_internal(const unsigned int neighbor) const
TriaIterator< CellAccessor< dim, spacedim > > periodic_neighbor(const unsigned int i) const
types::global_cell_index global_active_cell_index() const
TriaIterator< CellAccessor< dim, spacedim > > neighbor(const unsigned int face_no) const
internal::SubfaceCase< dim > subface_case(const unsigned int face_no) const
boost::container::small_vector< TriaIterator< TriaAccessor< dim - 1, dim, spacedim > >, ReferenceCells::max_n_faces< dim >() > face_iterators() const
bool is_artificial_on_level() const
void set_direction_flag(const bool new_direction_flag) const
void recursively_set_material_id(const types::material_id new_material_id) const
void set_level_subdomain_id(const types::subdomain_id new_level_subdomain_id) const
types::subdomain_id level_subdomain_id() const
std::uint8_t refine_choice() const
RefinementCase< dim > refine_flag_set() const
bool flag_for_face_refinement(const unsigned int face_no, const RefinementCase< dim - 1 > &face_refinement_case=RefinementCase< dim - 1 >::isotropic_refinement) const
unsigned int face_index(const unsigned int i) const
double diameter(const Mapping< dim, spacedim > &mapping) const
TriaActiveIterator< DoFCellAccessor< dim, spacedim, false > > as_dof_handler_iterator(const DoFHandler< dim, spacedim > &dof_handler) const
CellAccessor< dim, spacedim > & operator=(CellAccessor< dim, spacedim > &&)=default
bool is_active() const
bool is_ghost() const
TriaIterator< CellAccessor< dim, spacedim > > neighbor_child_on_subface(const unsigned int face_no, const unsigned int subface_no) const
void set_subdomain_id(const types::subdomain_id new_subdomain_id) const
bool neighbor_is_coarser(const unsigned int face_no) const
TriaIterator< CellAccessor< dim, spacedim > > child(const unsigned int i) const
void set_global_level_cell_index(const types::global_cell_index index) const
bool has_periodic_neighbor(const unsigned int i) const
void clear_refine_choice() const
int periodic_neighbor_level(const unsigned int i) const
std::pair< unsigned int, unsigned int > neighbor_of_coarser_neighbor(const unsigned int neighbor) const
~CellAccessor()=default
CellAccessor(const CellAccessor< dim, spacedim > &)=default
void set_coarsen_flag() const
TriaIterator< TriaAccessor< dim - 1, dim, spacedim > > face(const unsigned int i) const
CellAccessor< dim, spacedim > & operator=(const CellAccessor< dim, spacedim > &)=delete
unsigned int neighbor_of_neighbor(const unsigned int face_no) const
unsigned int face_iterator_to_index(const TriaIterator< TriaAccessor< dim - 1, dim, spacedim > > &face) const
void set_material_id(const types::material_id new_material_id) const
bool is_locally_owned() const
boost::container::small_vector< TriaIterator< CellAccessor< dim, spacedim > >, ReferenceCells::max_n_children< dim >()> child_iterators() const
void set_refine_flag(const RefinementCase< dim > ref_case=RefinementCase< dim >::isotropic_refinement) const
CellAccessor(CellAccessor< dim, spacedim > &&)=default
bool point_inside_codim(const Point< spacedim_ > &p) const
typename TriaAccessor< dim, dim, spacedim >::AccessorData AccessorData
bool is_locally_owned_on_level() const
bool has_boundary_lines() const
TriaIterator< CellAccessor< dim, spacedim > > periodic_neighbor_child_on_subface(const unsigned int face_no, const unsigned int subface_no) const
int neighbor_level(const unsigned int face_no) const
int periodic_neighbor_index(const unsigned int i) const
bool periodic_neighbor_is_coarser(const unsigned int i) const
void set_global_active_cell_index(const types::global_cell_index index) const
void clear_coarsen_flag() const
std::set< TriaActiveIterator< CellAccessor< dim, spacedim > > > get_cells_adjacent_to_line(const unsigned int i) const
void set_refine_choice(const std::uint8_t refinement_choice=static_cast< char >(IsotropicRefinementChoice::isotropic_refinement)) const
void set_parent(const unsigned int parent_index)
std::pair< unsigned int, unsigned int > periodic_neighbor_of_coarser_periodic_neighbor(const unsigned face_no) const
CellAccessor(const TriaAccessor< dim, dim, spacedim > &cell_accessor)
bool at_boundary() const
unsigned int active_cell_index() const
static bool is_level_cell()
void clear_refine_flag() const
int neighbor_index(const unsigned int face_no) const
bool point_inside(const Point< spacedim > &p) const
types::subdomain_id subdomain_id() const
void set_neighbor(const unsigned int face_no, const TriaIterator< CellAccessor< dim, spacedim > > &neighbor) const
bool direction_flag() const
types::material_id material_id() const
bool coarsen_flag_set() const
types::global_cell_index global_level_cell_index() const
bool flag_for_line_refinement(const unsigned int line_no) const
CellId id() const
bool is_artificial() const
TriaIterator< DoFCellAccessor< dim, spacedim, true > > as_dof_handler_level_iterator(const DoFHandler< dim, spacedim > &dof_handler) const
bool is_ghost_on_level() const
TriaIterator< CellAccessor< dim, spacedim > > neighbor_or_periodic_neighbor(const unsigned int i) const
int parent_index() const
unsigned int periodic_neighbor_of_periodic_neighbor(const unsigned int i) const
unsigned int periodic_neighbor_face_no(const unsigned int i) const
void set_manifold_id(const types::manifold_id) const
InvalidAccessor(const InvalidAccessor &)
static constexpr unsigned int space_dimension
static int level()
bool operator==(const InvalidAccessor &) const
Point< spacedim > & vertex(const unsigned int i) const
void * quad(const unsigned int i) const
void operator++() const
void * line(const unsigned int i) const
static IteratorState::IteratorStates state()
bool operator!=(const InvalidAccessor &) const
bool has_children() const
unsigned int user_index() const
static const unsigned int structure_dimension
void copy_from(const InvalidAccessor &)
void set_user_index(const unsigned int p) const
static int index()
types::manifold_id manifold_id() const
InvalidAccessor(const void *parent=nullptr, const int level=-1, const int index=-1, const AccessorData *local_data=nullptr)
static constexpr unsigned int dimension
void operator--() const
bool used() const
InvalidAccessor(const OtherAccessor &)
Abstract base class for mapping classes.
Definition mapping.h:318
virtual boost::container::small_vector< Point< spacedim >, ReferenceCells::max_n_vertices< dim >() > get_vertices(const typename Triangulation< dim, spacedim >::cell_iterator &cell) const
Definition point.h:111
numbers::NumberTraits< Number >::real_type distance(const Point< dim, Number > &p) const
constexpr unsigned int n_vertices() const
std::array< unsigned int, 2 > standard_vertex_to_face_and_vertex_index(const unsigned int vertex) const
constexpr unsigned int n_faces() const
unsigned int standard_to_real_face_line(const unsigned int line, const unsigned int face, const types::geometric_orientation face_orientation) const
constexpr unsigned int n_lines() const
unsigned int standard_to_real_face_vertex(const unsigned int vertex, const unsigned int face, const types::geometric_orientation face_orientation) const
std::array< unsigned int, 2 > standard_line_to_face_and_line_index(const unsigned int line) const
numbers::NumberTraits< Number >::real_type norm() const
constexpr numbers::NumberTraits< Number >::real_type norm_square() const
bool operator!=(const TriaAccessorBase &) const
static constexpr unsigned int space_dimension
static constexpr unsigned int dimension
TriaAccessorBase(const TriaAccessorBase &)
void operator=(const TriaAccessorBase *)=delete
void set_level(const int level)
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
std::conditional_t< structdim==dim, int, Empty > 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()
std_cxx20::ranges::iota_view< unsigned int, unsigned int > line_indices() const
unsigned int vertex_index(const unsigned int i=0) const
void copy_from(const TriaAccessor &)
void set_all_boundary_ids(const types::boundary_id) const
static IteratorState::IteratorStates state()
Point< spacedim > center() const
static int child_index(const unsigned int i)
Returns -1.
types::manifold_id manifold_id() const
static unsigned int n_children()
TriaAccessor(const TriaAccessor< structdim2, dim2, spacedim2 > &)
void set_boundary_id(const types::boundary_id) const
Point< spacedim > & vertex(const unsigned int i=0) const
unsigned int n_vertices() const
void set_manifold_id(const types::manifold_id)
void copy_from(const TriaAccessorBase< 0, 1, spacedim > &)
ReferenceCell< 0 > reference_cell() const
bool operator==(const TriaAccessor &) const
const Triangulation< 1, spacedim > * tria
double extent_in_direction(const unsigned int axis) const
TriaAccessor(const Triangulation< dim, spacedim > *tria, const unsigned int vertex_index)
Point< spacedim > & vertex(const unsigned int i=0) const
static typename::internal::TriangulationImplementation::Iterators< dim, spacedim >::line_iterator line(const unsigned int)
bool operator!=(const TriaAccessor &) const
static RefinementCase< 0 > refinement_case()
void copy_from(const TriaAccessor &)
static TriaIterator< TriaAccessor< 0, dim, spacedim > > child(const unsigned int)
Return an invalid object.
TriaAccessor(const InvalidAccessor< structdim2, dim2, spacedim2 > &)
static int child_index(const unsigned int i)
Returns -1.
bool operator==(const TriaAccessor &) const
static unsigned int line_index(const unsigned int i)
static TriaIterator< TriaAccessor< 0, dim, spacedim > > isotropic_child(const unsigned int)
Return an invalid object.
static typename::internal::TriangulationImplementation::Iterators< dim, spacedim >::quad_iterator quad(const unsigned int i)
unsigned int vertex_index(const unsigned int i=0) const
const Triangulation< dim, spacedim > * tria
static int isotropic_child_index(const unsigned int i)
Returns -1.
TriaAccessor(const Triangulation< dim, spacedim > *tria=nullptr, const int level=0, const int index=0, const AccessorData *=nullptr)
static unsigned int n_children()
const Triangulation< dim, spacedim > & get_triangulation() const
static unsigned int child_iterator_to_index(const TriaIterator< TriaAccessor< 0, dim, spacedim > > &)
Return an invalid unsigned integer.
static unsigned int max_refinement_depth()
static unsigned int quad_index(const unsigned int i)
static unsigned int n_active_descendants()
TriaAccessor(const TriaAccessor< structdim2, dim2, spacedim2 > &)
Point< spacedim > center(const bool respect_manifold=false, const bool interpolate_from_surrounding=false) const
IteratorState::IteratorStates state() const
std_cxx20::ranges::iota_view< unsigned int, unsigned int > vertex_indices() const
void clear_children() const
void set_boundary_id_internal(const types::boundary_id id) const
void set_user_index(const unsigned int p) const
TriaAccessor(TriaAccessor &&)=default
void clear_user_pointer() const
unsigned int n_active_descendants() const
void recursively_set_user_index(const unsigned int p) const
TriaIterator< TriaAccessor< 0, dim, spacedim > > vertex_iterator(const unsigned int i) const
void clear_user_data() const
TriaAccessor(const TriaAccessor< structdim2, dim2, spacedim2 > &)
Point< structdim > real_to_unit_cell_affine_approximation(const Point< spacedim > &point) const
void recursively_clear_user_index() const
unsigned int line_index(const unsigned int i) const
const Manifold< dim, spacedim > & get_manifold() const
void recursively_set_user_pointer(void *p) const
unsigned int n_lines() const
double extent_in_direction(const unsigned int axis) const
Point< spacedim > intermediate_point(const Point< structdim > &coordinates) const
unsigned int n_vertices() const
bool has_children() const
void recursively_clear_user_flag() const
std_cxx20::ranges::iota_view< unsigned int, unsigned int > line_indices() const
typename TriaAccessorBase< structdim, dim, spacedim >::AccessorData AccessorData
Point< spacedim > barycenter() const
BoundingBox< spacedim > bounding_box() const
void set_bounding_object_indices(const std::initializer_list< unsigned int > &new_indices) const
void clear_user_flag() const
TriaIterator< TriaAccessor< structdim, dim, spacedim > > child(const unsigned int i) const
unsigned int n_children() const
std_cxx20::ranges::iota_view< unsigned int, unsigned int > face_indices() const
void recursively_set_user_flag() const
void set_boundary_id(const types::boundary_id) const
bool is_translation_of(const TriaIterator< TriaAccessor< structdim, dim, spacedim > > &o) const
bool user_flag_set() const
void set_used_flag() const
types::manifold_id manifold_id() const
void set_user_flag() const
TriaAccessor(const TriaAccessor &)=default
void clear_used_flag() const
std::pair< Point< spacedim >, double > enclosing_ball() const
unsigned int vertex_index(const unsigned int i) const
void * user_pointer() const
int isotropic_child_index(const unsigned int i) const
Point< spacedim > center(const bool respect_manifold=false, const bool interpolate_from_surrounding=false) const
~TriaAccessor()=default
ReferenceCell< structdim > reference_cell() const
void set_refinement_case(const RefinementCase< structdim > &ref_case) const
void clear_user_index() const
double minimum_vertex_distance() const
double measure() const
void set_all_boundary_ids(const types::boundary_id) const
void set_bounding_object_indices(const std::initializer_list< int > &new_indices) const
unsigned int max_refinement_depth() const
Point< spacedim > & vertex(const unsigned int i) const
void set_line_orientation(const unsigned int line, const types::geometric_orientation orientation) const
unsigned int quad_index(const unsigned int i) const
TriaAccessor & operator=(const TriaAccessor &)=delete
unsigned int user_index() const
int child_index(const unsigned int i) const
void set_user_pointer(void *p) const
void recursively_clear_user_pointer() const
RefinementCase< structdim > refinement_case() const
typename::internal::TriangulationImplementation::Iterators< dim, spacedim >::line_iterator line(const unsigned int i) const
TriaAccessor(const Triangulation< dim, spacedim > *parent=nullptr, const int level=-1, const int index=-1, const AccessorData *local_data=nullptr)
unsigned int child_iterator_to_index(const TriaIterator< TriaAccessor< structdim, dim, spacedim > > &child) const
TriaAccessor(const InvalidAccessor< structdim2, dim2, spacedim2 > &)
bool used() const
void set_children(const unsigned int i, const int index) const
void clear_refinement_case() const
double diameter() const
bool at_boundary() const
types::boundary_id boundary_id() const
unsigned int n_faces() const
TriaAccessor & operator=(TriaAccessor &&)=default
TriaIterator< TriaAccessor< structdim, dim, spacedim > > isotropic_child(const unsigned int i) const
typename::internal::TriangulationImplementation::Iterators< dim, spacedim >::quad_iterator quad(const unsigned int i) const
IteratorState::IteratorStates state() const
std::unique_ptr< std::map< unsigned int, types::manifold_id > > vertex_to_manifold_id_map_1d
Definition tria.h:4691
std::unique_ptr<::internal::TriangulationImplementation::TriaFaces< dim > > faces
Definition tria.h:4603
std::vector< Point< spacedim > > vertices
Definition tria.h:4609
virtual types::subdomain_id locally_owned_subdomain() const
std::unique_ptr< std::map< unsigned int, types::boundary_id > > vertex_to_boundary_id_map_1d
Definition tria.h:4668
std::vector< std::unique_ptr< ::internal::TriangulationImplementation::TriaLevel< dim, spacedim > > > levels
Definition tria.h:4595
bool vertex_used(const unsigned int index) const
unsigned int n_vertices() const
#define DEAL_II_DEPRECATED
Definition config.h:294
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
constexpr bool running_in_debug_mode()
Definition config.h:76
#define DEAL_II_CXX20_REQUIRES(condition)
Definition config.h:249
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
#define DEAL_II_ASSERT_UNREACHABLE()
#define DEAL_II_NOT_IMPLEMENTED()
unsigned int level
Definition grid_out.cc:4642
unsigned int vertex_indices[2]
static ::ExceptionBase & ExcCantCompareIterators()
#define DeclException0(Exception0)
static ::ExceptionBase & ExcCellHasNoParent()
static ::ExceptionBase & ExcCellFlaggedForRefinement()
static ::ExceptionBase & ExcCellHasNoChildren()
static ::ExceptionBase & ExcNotImplemented()
static ::ExceptionBase & ExcCellNotUsed()
static ::ExceptionBase & ExcNoPeriodicNeighbor()
static ::ExceptionBase & ExcCantSetChildren(int arg1)
#define Assert(cond, exc)
static ::ExceptionBase & ExcImpossibleInDim(int arg1)
static ::ExceptionBase & ExcNeighborIsNotCoarser()
static ::ExceptionBase & ExcSetOnlyEvenChildren(int arg1)
static ::ExceptionBase & ExcNeighborIsCoarser()
#define AssertIndexRange(index, range)
#define DeclExceptionMsg(Exception, defaulttext)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcFacesHaveNoLevel()
static ::ExceptionBase & ExcDereferenceInvalidObject(AccessorType arg1)
static ::ExceptionBase & ExcCellFlaggedForCoarsening()
static ::ExceptionBase & ExcIndexRange(std::size_t arg1, std::size_t arg2, std::size_t arg3)
#define DeclException1(Exception1, type1, outsequence)
static ::ExceptionBase & ExcRefineCellNotActive()
static ::ExceptionBase & ExcMessage(std::string arg1)
static ::ExceptionBase & ExcCellNotActive()
void set_all_manifold_ids(const types::manifold_id) const
const Manifold< dim, spacedim > & get_manifold(const types::manifold_id number) const
void set_all_manifold_ids(const types::manifold_id)
void set_manifold_id(const types::manifold_id) const
static bool face_orientation(const unsigned int face)
Always return false.
static types::geometric_orientation line_orientation(const unsigned int line)
Always return numbers::reverse_line_orientation.
bool face_rotation(const unsigned int face) const
bool face_orientation(const unsigned int face) const
static bool face_flip(const unsigned int face)
Always return false.
types::geometric_orientation combined_face_orientation(const unsigned int face) const
static bool face_flip(const unsigned int face)
Always return false.
void set_combined_face_orientation(const unsigned int face_no, const types::geometric_orientation combined_orientation) const
static types::geometric_orientation combined_face_orientation(const unsigned int face)
Always return 0.
static bool face_rotation(const unsigned int face)
Always return false.
types::geometric_orientation line_orientation(const unsigned int line) const
static bool face_rotation(const unsigned int face)
Always return false.
static types::geometric_orientation line_orientation(const unsigned int line)
Always return numbers::reverse_line_orientation.
static bool face_orientation(const unsigned int face)
Always return false.
bool face_flip(const unsigned int face) const
static types::geometric_orientation combined_face_orientation(const unsigned int face)
Always return 0.
void reference_cell(Triangulation< dim, spacedim > &tria, const ReferenceCell< dim > &reference_cell)
@ past_the_end
Iterator reached end of container.
@ valid
Iterator points to a valid object.
@ invalid
Iterator is invalid, probably due to an error.
constexpr char U
double norm(const FEValuesBase< dim > &fe, const ArrayView< const std::vector< Tensor< 1, dim > > > &Du)
Definition divergence.h:469
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
Tensor< 2, dim, Number > l(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
SymmetricTensor< 2, dim, Number > b(const Tensor< 2, dim, Number > &F)
SymmetricTensor< 2, dim, Number > epsilon(const Tensor< 2, dim, Number > &Grad_u)
*  *  if(update_pressure &update_flags) *  compute_pressure(constitutive_request
*  *  *  *  std::vector< Number > ThermoPlasticMaterial< dim, ViscoplasticYieldLaw, Number >::get_state_parameters   const
constexpr ReferenceCell< 3 > Hexahedron
constexpr ReferenceCell< 2 > Quadrilateral
constexpr ReferenceCell< 1 > Line
constexpr ReferenceCell< 2 > Triangle
constexpr ReferenceCell< 3 > Tetrahedron
constexpr ReferenceCell< 3 > Pyramid
constexpr ReferenceCell< 3 > Wedge
constexpr ReferenceCell< 0 > Vertex
T sum(const T &t, const MPI_Comm mpi_communicator)
types::geometric_orientation combined_face_orientation(const bool face_orientation, const bool face_rotation, const bool face_flip)
constexpr types::geometric_orientation invalid_geometric_orientation
Definition types.h:369
constexpr unsigned int invalid_unsigned_int
Definition types.h:228
constexpr types::boundary_id internal_face_boundary_id
Definition types.h:319
constexpr types::manifold_id flat_manifold_id
Definition types.h:332
constexpr types::subdomain_id artificial_subdomain_id
Definition types.h:406
constexpr types::geometric_orientation reverse_line_orientation
Definition types.h:355
constexpr types::subdomain_id invalid_subdomain_id
Definition types.h:385
constexpr types::geometric_orientation default_geometric_orientation
Definition types.h:342
boost::integer_range< IncrementableType > iota_view
Definition iota_view.h:43
STL namespace.
::VectorizedArray< Number, width > min(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > max(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > sqrt(const ::VectorizedArray< Number, width > &)
unsigned int manifold_id
Definition types.h:171
std::uint64_t global_vertex_index
Definition types.h:55
unsigned int subdomain_id
Definition types.h:50
unsigned int boundary_id
Definition types.h:159
std::uint8_t geometric_orientation
Definition types.h:38
static RefinementCase< dim > min_cell_refinement_case_for_line_refinement(const unsigned int line_no)
static RefinementCase< dim > min_cell_refinement_case_for_face_refinement(const RefinementCase< dim - 1 > &face_refinement_case, const unsigned int face_no, const bool face_orientation=true, const bool face_flip=false, const bool face_rotation=false)