deal.II version GIT relicensing-3145-g5a760040ed 2025-04-25 14:40:00+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Loading...
Searching...
No Matches
tria_accessor.h
Go to the documentation of this file.
1// ------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: LGPL-2.1-or-later
4// Copyright (C) 1998 - 2024 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Part of the source code is dual licensed under Apache-2.0 WITH
9// LLVM-exception OR LGPL-2.1-or-later. Detailed license information
10// governing the source code and code contributions can be found in
11// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II.
12//
13// ------------------------------------------------------------------------
14
15#ifndef dealii_tria_accessor_h
16#define dealii_tria_accessor_h
17
18
19#include <deal.II/base/config.h>
20
24#include <deal.II/base/point.h>
26
34
35#include <boost/container/small_vector.hpp>
36
37#include <cmath>
38#include <limits>
39#include <utility>
40
41
43
44// Forward declarations
45#ifndef DOXYGEN
46template <int dim, int spacedim>
48class Triangulation;
49template <typename Accessor>
50class TriaRawIterator;
51template <typename Accessor>
52class TriaIterator;
53template <typename Accessor>
55
56namespace parallel
57{
58 template <int dim, int spacedim>
60 class TriangulationBase;
61}
62
63template <int dim, int spacedim>
65class DoFHandler;
66template <int dim, int spacedim, bool lda>
67class DoFCellAccessor;
68
69
70template <int dim, int spacedim>
71class Manifold;
72
73template <int dim, int spacedim>
74class Mapping;
75#endif
76
77namespace internal
78{
79 namespace TriangulationImplementation
80 {
81 class TriaObjects;
82 struct Implementation;
83 struct ImplementationMixedMesh;
84 } // namespace TriangulationImplementation
85
86 namespace TriaAccessorImplementation
87 {
88 struct Implementation;
89
95 template <int structdim, int dim>
97 {
98 struct type
99 {
103 type() = default;
104
108 type(const int level)
109 {
111 (void)level; // removes -Wunused-parameter warning in optimized mode
112 }
113
117 operator int() const
118 {
119 return 0;
120 }
121
122 void
124 {
126 }
127
128 void
130 {
132 }
133 };
134 };
135
136
142 template <int dim>
143 struct PresentLevelType<dim, dim>
144 {
145 using type = int;
146 };
147 } // namespace TriaAccessorImplementation
148} // namespace internal
149template <int structdim, int dim, int spacedim>
150class TriaAccessor;
151template <int dim, int spacedim>
152class TriaAccessor<0, dim, spacedim>;
153template <int spacedim>
154class TriaAccessor<0, 1, spacedim>;
155
160{
165 "The operation you are attempting can only be performed for "
166 "(cell, face, or edge) iterators that point to valid "
167 "objects. These objects need not necessarily be active, "
168 "i.e., have no children, but they need to be part of a "
169 "triangulation. (The objects pointed to by an iterator "
170 "may -- after coarsening -- also be objects that used "
171 "to be part of a triangulation, but are now no longer "
172 "used. Their memory location may have been retained "
173 "for re-use upon the next mesh refinement, but is "
174 "currently unused.)");
185 "The operation you are attempting can only be performed for "
186 "(cell, face, or edge) iterators that point to 'active' "
187 "objects. 'Active' objects are those that do not have "
188 "children (in the case of cells), or that are part of "
189 "an active cell (in the case of faces or edges). However, "
190 "the object on which you are trying the current "
191 "operation is not 'active' in this sense.");
198 "The operation you are attempting can only be performed for "
199 "(cell, face, or edge) iterators that have children, "
200 "but the object on which you are trying the current "
201 "operation does not have any.");
209 "The operation you are attempting can only be performed for "
210 "(cell, face, or edge) iterators that have a parent object, "
211 "but the object on which you are trying the current "
212 "operation does not have one -- i.e., it is on the "
213 "coarsest level of the triangulation.");
218 int,
219 << "You can only set the child index if the cell does not "
220 << "currently have children registered; or you can clear it. "
221 << "The given index was " << arg1
222 << " (-1 means: clear children).");
226 template <typename AccessorType>
228 AccessorType,
229 << "You tried to dereference an iterator for which this "
230 << "is not possible. More information on this iterator: "
231 << "index=" << arg1.index() << ", state="
232 << (arg1.state() == IteratorState::valid ?
233 "valid" :
234 (arg1.state() == IteratorState::past_the_end ?
235 "past_the_end" :
236 "invalid")));
241 "Iterators can only be compared if they point to the same "
242 "triangulation, or if neither of them are associated "
243 "with a triangulation.");
244 // TODO: Write documentation!
249 // TODO: Write documentation!
269 // TODO: Write documentation!
275 int,
276 << "You can only set the child index of an even numbered child."
277 << "The number of the child given was " << arg1 << '.');
278} // namespace TriaAccessorExceptions
279
280
306template <int structdim, int dim, int spacedim = dim>
308{
309public:
316 static constexpr unsigned int space_dimension = spacedim;
317
323 static constexpr unsigned int dimension = dim;
324
330 static const unsigned int structure_dimension = structdim;
331
341 void
342 operator=(const TriaAccessorBase *) = delete;
343
344protected:
350 using AccessorData = void;
351
356 const int level = -1,
357 const int index = -1,
358 const AccessorData * = nullptr);
359
364
372 void
374
380
391 bool
392 operator<(const TriaAccessorBase &other) const;
393
394protected:
398 bool
400
404 bool
406
420 void
422
430 void
440 objects() const;
441
442public:
448 using LocalData = void *;
449
473 int
474 level() const;
475
502 int
503 index() const;
504
510 state() const;
511
518
522protected:
527 typename ::internal::TriaAccessorImplementation::
528 PresentLevelType<structdim, dim>::type present_level;
529
535
540
541private:
542 template <typename Accessor>
543 friend class TriaRawIterator;
544 template <typename Accessor>
545 friend class TriaIterator;
546 template <typename Accessor>
547 friend class TriaActiveIterator;
548};
549
550
551
572template <int structdim, int dim, int spacedim = dim>
574{
575public:
582 static constexpr unsigned int space_dimension = spacedim;
583
589 static constexpr unsigned int dimension = dim;
590
596 static const unsigned int structure_dimension = structdim;
597
603 using AccessorData = void;
604
612 InvalidAccessor(const void *parent = nullptr,
613 const int level = -1,
614 const int index = -1,
615 const AccessorData *local_data = nullptr);
616
625
630 template <typename OtherAccessor>
631 InvalidAccessor(const OtherAccessor &);
632
636 void
638
642 bool
644 bool
646
650 void
651 operator++() const;
652 void
653 operator--() const;
654
660 state();
661
662
667 static int
668 level();
669
674 static int
675 index();
676
681 bool
682 used() const;
683
688 bool
690
695 manifold_id() const;
696
700 unsigned int
701 user_index() const;
702
706 void
707 set_user_index(const unsigned int p) const;
708
712 void
714
719 vertex(const unsigned int i) const;
720
725 void *
726 line(const unsigned int i) const;
727
732 void *
733 quad(const unsigned int i) const;
734};
735
736
737
755template <int structdim, int dim, int spacedim>
756class TriaAccessor : public TriaAccessorBase<structdim, dim, spacedim>
757{
758public:
764
769 const int level = -1,
770 const int index = -1,
771 const AccessorData *local_data = nullptr);
772
777 TriaAccessor(const TriaAccessor &) = default;
778
782 TriaAccessor(TriaAccessor &&) = default; // NOLINT
783
796 template <int structdim2, int dim2, int spacedim2>
798
803 template <int structdim2, int dim2, int spacedim2>
805
816 operator=(const TriaAccessor &) = delete;
817
822 operator=(TriaAccessor &&) = default; // NOLINT
823
827 ~TriaAccessor() = default;
828
835 bool
836 used() const;
837
850 vertex_iterator(const unsigned int i) const;
851
867 unsigned int
868 vertex_index(const unsigned int i) const;
869
908 vertex(const unsigned int i) const;
909
913 typename ::internal::TriangulationImplementation::
914 Iterators<dim, spacedim>::line_iterator
915 line(const unsigned int i) const;
916
923 unsigned int
924 line_index(const unsigned int i) const;
925
929 typename ::internal::TriangulationImplementation::
930 Iterators<dim, spacedim>::quad_iterator
931 quad(const unsigned int i) const;
932
939 unsigned int
940 quad_index(const unsigned int i) const;
959 combined_face_orientation(const unsigned int face) const;
960
972 bool
973 face_orientation(const unsigned int face) const;
974
984 bool
985 face_flip(const unsigned int face) const;
986
996 bool
997 face_rotation(const unsigned int face) const;
998
1009 line_orientation(const unsigned int line) const;
1024 bool
1026
1031 unsigned int
1032 n_children() const;
1033
1047 unsigned int
1049
1063 unsigned int
1065
1070 child(const unsigned int i) const;
1071
1076 unsigned int
1079
1089 isotropic_child(const unsigned int i) const;
1090
1096
1102 int
1103 child_index(const unsigned int i) const;
1104
1110 int
1111 isotropic_child_index(const unsigned int i) const;
1135
1163 void
1165
1194 void
1196
1204 bool
1206
1218
1241
1259 void
1261
1275 void
1277
1294 bool
1296
1302 void
1304
1310 void
1312
1318 void
1320
1326 void
1328
1334 void
1336
1348 void
1349 set_user_pointer(void *p) const;
1350
1356 void
1358
1376 void *
1378
1400 void
1402
1409 void
1411
1421 void
1422 set_user_index(const unsigned int p) const;
1423
1429 void
1431
1443 unsigned int
1444 user_index() const;
1445
1463 void
1464 recursively_set_user_index(const unsigned int p) const;
1465
1474 void
1510 double
1511 diameter() const;
1512
1539 std::pair<Point<spacedim>, double>
1541
1552
1562 double
1563 extent_in_direction(const unsigned int axis) const;
1564
1568 double
1570
1585 intermediate_point(const Point<structdim> &coordinates) const;
1586
1611
1647 center(const bool respect_manifold = false,
1648 const bool interpolate_from_surrounding = false) const;
1649
1668 barycenter() const;
1669
1700 double
1701 measure() const;
1702
1717 bool
1720
1726
1730 unsigned int
1731 n_vertices() const;
1732
1736 unsigned int
1737 n_lines() const;
1738
1748 unsigned int
1749 n_faces() const;
1750
1757
1764
1773
1778private:
1783 void
1785
1793 void
1795 const std::initializer_list<int> &new_indices) const;
1796
1800 void
1802 const std::initializer_list<unsigned int> &new_indices) const;
1803
1811 void
1812 set_line_orientation(const unsigned int line,
1813 const types::geometric_orientation orientation) const;
1814
1822 void
1824 const unsigned int face,
1825 const types::geometric_orientation combined_orientation) const;
1826
1830 void
1832
1836 void
1838
1847 void
1849
1857 void
1859
1866 void
1867 set_children(const unsigned int i, const int index) const;
1868
1873 void
1875
1876private:
1877 friend class Triangulation<dim, spacedim>;
1878
1879 friend struct ::internal::TriangulationImplementation::Implementation;
1880 friend struct ::internal::TriangulationImplementation::
1881 ImplementationMixedMesh;
1882 friend struct ::internal::TriaAccessorImplementation::Implementation;
1883};
1884
1885
1886
1905template <int dim, int spacedim>
1906class TriaAccessor<0, dim, spacedim>
1907{
1908public:
1914 static constexpr unsigned int space_dimension = spacedim;
1915
1921 static constexpr unsigned int dimension = dim;
1922
1928 static const unsigned int structure_dimension = 0;
1929
1933 using AccessorData = void;
1934
1940 const unsigned int vertex_index);
1941
1948 const int level = 0,
1949 const int index = 0,
1950 const AccessorData * = nullptr);
1951
1955 template <int structdim2, int dim2, int spacedim2>
1957
1961 template <int structdim2, int dim2, int spacedim2>
1963
1968 state() const;
1969
1974 static int
1976
1981 int
1982 index() const;
1983
1990
2000 void
2002
2006 void
2011 bool
2012 operator==(const TriaAccessor &) const;
2013
2017 bool
2018 operator!=(const TriaAccessor &) const;
2019
2047 unsigned int
2048 vertex_index(const unsigned int i = 0) const;
2049
2056 vertex(const unsigned int i = 0) const;
2057
2062 typename ::internal::TriangulationImplementation::
2063 Iterators<dim, spacedim>::line_iterator static line(const unsigned int);
2064
2068 static unsigned int
2069 line_index(const unsigned int i);
2070
2074 static typename ::internal::TriangulationImplementation::
2075 Iterators<dim, spacedim>::quad_iterator
2076 quad(const unsigned int i);
2077
2081 static unsigned int
2082 quad_index(const unsigned int i);
2083
2099 double
2100 diameter() const;
2101
2109 double
2110 extent_in_direction(const unsigned int axis) const;
2111
2120 center(const bool respect_manifold = false,
2121 const bool interpolate_from_surrounding = false) const;
2122
2131 double
2132 measure() const;
2150 combined_face_orientation(const unsigned int face);
2151
2155 static bool
2156 face_orientation(const unsigned int face);
2157
2161 static bool
2162 face_flip(const unsigned int face);
2163
2167 static bool
2168 face_rotation(const unsigned int face);
2169
2174 line_orientation(const unsigned int line);
2175
2190 static bool
2192
2197 static unsigned int
2199
2204 static unsigned int
2206
2210 static unsigned int
2212
2216 static unsigned int
2218
2223 child(const unsigned int);
2224
2229 isotropic_child(const unsigned int);
2230
2234 static RefinementCase<0>
2236
2240 static int
2241 child_index(const unsigned int i);
2242
2246 static int
2247 isotropic_child_index(const unsigned int i);
2255 bool
2256 used() const;
2257
2258protected:
2266 void
2268
2277 bool
2278 operator<(const TriaAccessor &other) const;
2279
2284
2289
2290private:
2291 template <typename Accessor>
2292 friend class TriaRawIterator;
2293 template <typename Accessor>
2294 friend class TriaIterator;
2295 template <typename Accessor>
2297};
2298
2299
2300
2317template <int spacedim>
2318class TriaAccessor<0, 1, spacedim>
2319{
2320public:
2326 static constexpr unsigned int space_dimension = spacedim;
2327
2333 static constexpr unsigned int dimension = 1;
2334
2340 static const unsigned int structure_dimension = 0;
2341
2345 using AccessorData = void;
2346
2352 {
2364 right_vertex
2366
2379 const VertexKind vertex_kind,
2380 const unsigned int vertex_index);
2381
2388 const int = 0,
2389 const int = 0,
2390 const AccessorData * = nullptr);
2391
2395 template <int structdim2, int dim2, int spacedim2>
2397
2401 template <int structdim2, int dim2, int spacedim2>
2403
2408 void
2410
2416 void
2418
2426
2431 static int
2433
2438 int
2439 index() const;
2440
2447
2458 void
2459 operator++() const;
2460
2465 void
2466 operator--() const;
2470 bool
2471 operator==(const TriaAccessor &) const;
2472
2476 bool
2477 operator!=(const TriaAccessor &) const;
2478
2487 bool
2488 operator<(const TriaAccessor &other) const;
2489
2516 unsigned int
2517 vertex_index(const unsigned int i = 0) const;
2518
2525 vertex(const unsigned int i = 0) const;
2526
2532 center() const;
2533
2538 typename ::internal::TriangulationImplementation::
2539 Iterators<1, spacedim>::line_iterator static line(const unsigned int);
2540
2547 static unsigned int
2548 line_index(const unsigned int i);
2549
2553 static typename ::internal::TriangulationImplementation::
2554 Iterators<1, spacedim>::quad_iterator
2555 quad(const unsigned int i);
2556
2563 static unsigned int
2564 quad_index(const unsigned int i);
2565
2575 bool
2577
2594
2598 const Manifold<1, spacedim> &
2600
2609
2610
2622 bool
2623 user_flag_set() const;
2624
2630 void
2631 set_user_flag() const;
2632
2638 void
2639 clear_user_flag() const;
2640
2646 void
2648
2654 void
2656
2662 void
2663 clear_user_data() const;
2664
2676 void
2677 set_user_pointer(void *p) const;
2678
2684 void
2685 clear_user_pointer() const;
2686
2702 void *
2703 user_pointer() const;
2704
2726 void
2727 recursively_set_user_pointer(void *p) const;
2728
2735 void
2737
2747 void
2748 set_user_index(const unsigned int p) const;
2749
2755 void
2756 clear_user_index() const;
2757
2769 unsigned int
2770 user_index() const;
2771
2789 void
2790 recursively_set_user_index(const unsigned int p) const;
2791
2800 void
2819 combined_face_orientation(const unsigned int face);
2820
2824 static bool
2825 face_orientation(const unsigned int face);
2826
2830 static bool
2831 face_flip(const unsigned int face);
2832
2836 static bool
2837 face_rotation(const unsigned int face);
2838
2843 line_orientation(const unsigned int line);
2844
2859 static bool
2861
2866 static unsigned int
2868
2873 static unsigned int
2875
2879 static unsigned int
2881
2885 static unsigned int
2887
2892 child(const unsigned int);
2893
2898 isotropic_child(const unsigned int);
2899
2903 static RefinementCase<0>
2905
2909 static int
2910 child_index(const unsigned int i);
2911
2915 static int
2916 isotropic_child_index(const unsigned int i);
2947 void
2949
2956 void
2958
2968 void
2970
2982 void
2991 bool
2992 used() const;
2993
2999
3003 unsigned int
3004 n_vertices() const;
3005
3009 unsigned int
3010 n_lines() const;
3011
3018
3025
3026protected:
3031
3037
3042};
3043
3044
3045
3061template <int dim, int spacedim = dim>
3062class CellAccessor : public TriaAccessor<dim, dim, spacedim>
3063{
3064public:
3069
3074
3086 const int level = -1,
3087 const int index = -1,
3088 const AccessorData *local_data = nullptr);
3089
3094
3107 template <int structdim2, int dim2, int spacedim2>
3109
3114 template <int structdim2, int dim2, int spacedim2>
3116
3121
3125 // NOLINTNEXTLINE OSX does not compile with noexcept
3127
3131 ~CellAccessor() = default;
3132
3144
3148 // NOLINTNEXTLINE OSX does not compile with noexcept
3151
3175 as_dof_handler_iterator(const DoFHandler<dim, spacedim> &dof_handler) const;
3176
3187 const DoFHandler<dim, spacedim> &dof_handler) const;
3188
3189
3206 child(const unsigned int i) const;
3207
3211 boost::container::small_vector<TriaIterator<CellAccessor<dim, spacedim>>,
3214
3218 TriaIterator<TriaAccessor<dim - 1, dim, spacedim>>
3219 face(const unsigned int i) const;
3220
3225 unsigned int
3228
3232 boost::container::small_vector<
3233 TriaIterator<TriaAccessor<dim - 1, dim, spacedim>>,
3234#ifndef _MSC_VER // MSVC prior to 2022 cannot use a constexpr function this way
3235 ReferenceCells::max_n_faces<dim>()
3236#else
3238#endif
3239 >
3241
3251 unsigned int
3252 face_index(const unsigned int i) const;
3253
3302 neighbor_child_on_subface(const unsigned int face_no,
3303 const unsigned int subface_no) const;
3304
3353 neighbor(const unsigned int face_no) const;
3354
3362 int
3363 neighbor_index(const unsigned int face_no) const;
3364
3372 int
3373 neighbor_level(const unsigned int face_no) const;
3374
3386 unsigned int
3387 neighbor_of_neighbor(const unsigned int face_no) const;
3388
3399 bool
3400 neighbor_is_coarser(const unsigned int face_no) const;
3401
3416 std::pair<unsigned int, unsigned int>
3417 neighbor_of_coarser_neighbor(const unsigned int neighbor) const;
3418
3425 unsigned int
3426 neighbor_face_no(const unsigned int neighbor) const;
3427
3431 static bool
3433
3447 bool
3448 has_periodic_neighbor(const unsigned int i) const;
3449
3467 periodic_neighbor(const unsigned int i) const;
3468
3477 neighbor_or_periodic_neighbor(const unsigned int i) const;
3478
3494 periodic_neighbor_child_on_subface(const unsigned int face_no,
3495 const unsigned int subface_no) const;
3496
3507 std::pair<unsigned int, unsigned int>
3508 periodic_neighbor_of_coarser_periodic_neighbor(const unsigned face_no) const;
3509
3515 int
3516 periodic_neighbor_index(const unsigned int i) const;
3517
3523 int
3524 periodic_neighbor_level(const unsigned int i) const;
3525
3540 unsigned int
3541 periodic_neighbor_of_periodic_neighbor(const unsigned int i) const;
3542
3548 unsigned int
3549 periodic_neighbor_face_no(const unsigned int i) const;
3550
3557 bool
3558 periodic_neighbor_is_coarser(const unsigned int i) const;
3559
3576 bool
3577 at_boundary(const unsigned int i) const;
3578
3587 bool
3588 at_boundary() const;
3589
3597 bool
3598 has_boundary_lines() const;
3626
3644 void
3647
3651 void
3653
3658 std::uint8_t
3660
3665 void
3666 set_refine_choice(const std::uint8_t refinement_choice = static_cast<char>(
3668
3672 void
3674
3682 bool
3684 const unsigned int face_no,
3685 const RefinementCase<dim - 1> &face_refinement_case =
3687
3693 bool
3694 flag_for_line_refinement(const unsigned int line_no) const;
3695
3705 subface_case(const unsigned int face_no) const;
3706
3710 bool
3712
3717 void
3719
3723 void
3748 material_id() const;
3749
3761 void
3762 set_material_id(const types::material_id new_material_id) const;
3763
3772 void
3773 recursively_set_material_id(const types::material_id new_material_id) const;
3801
3817 void
3818 set_subdomain_id(const types::subdomain_id new_subdomain_id) const;
3819
3830
3835 void
3837 const types::subdomain_id new_level_subdomain_id) const;
3838
3839
3855 void
3857 const types::subdomain_id new_subdomain_id) const;
3881
3891
3908 bool
3909 direction_flag() const;
3910
3936 unsigned int
3938
3946 int
3947 parent_index() const;
3948
3955 parent() const;
3956
3976 bool
3977 is_active() const;
3978
3998 bool
4000
4005 bool
4007
4041 bool
4042 is_ghost() const;
4043
4049 bool
4051
4078 bool
4080
4087 bool
4089
4103 bool
4105
4114 void
4115 set_neighbor(const unsigned int i,
4116 const TriaIterator<CellAccessor<dim, spacedim>> &pointer) const;
4117
4131 CellId
4132 id() const;
4133
4134 using TriaAccessor<dim, dim, spacedim>::diameter;
4135
4139 double
4140 diameter(const Mapping<dim, spacedim> &mapping) const;
4141
4159
4160protected:
4176 unsigned int
4177 neighbor_of_neighbor_internal(const unsigned int neighbor) const;
4178
4184 template <int dim_, int spacedim_>
4185 bool
4186 point_inside_codim(const Point<spacedim_> &p) const;
4187
4188
4189
4190private:
4195 void
4196 set_active_cell_index(const unsigned int active_cell_index) const;
4197
4201 void
4203
4207 void
4209
4213 void
4214 set_parent(const unsigned int parent_index);
4215
4226 void
4227 set_direction_flag(const bool new_direction_flag) const;
4228
4229 friend class Triangulation<dim, spacedim>;
4230
4231 friend class parallel::TriangulationBase<dim, spacedim>;
4232
4233 friend struct ::internal::TriangulationImplementation::Implementation;
4234 friend struct ::internal::TriangulationImplementation::
4235 ImplementationMixedMesh;
4236};
4237
4238
4239
4240/* ----- declaration of explicit specializations and general templates ----- */
4241
4242
4243template <int structdim, int dim, int spacedim>
4244template <typename OtherAccessor>
4246 const OtherAccessor &)
4247{
4248 Assert(false,
4249 ExcMessage("You are attempting an illegal conversion between "
4250 "iterator/accessor types. The constructor you call "
4251 "only exists to make certain template constructs "
4252 "easier to write as dimension independent code but "
4253 "the conversion is not valid in the current context."));
4254}
4255
4256
4257
4258template <int structdim, int dim, int spacedim>
4259template <int structdim2, int dim2, int spacedim2>
4262{
4263 Assert(false,
4264 ExcMessage("You are attempting an illegal conversion between "
4265 "iterator/accessor types. The constructor you call "
4266 "only exists to make certain template constructs "
4267 "easier to write as dimension independent code but "
4268 "the conversion is not valid in the current context."));
4269}
4270
4271
4272
4273template <int dim, int spacedim>
4274template <int structdim2, int dim2, int spacedim2>
4277{
4278 Assert(false,
4279 ExcMessage("You are attempting an illegal conversion between "
4280 "iterator/accessor types. The constructor you call "
4281 "only exists to make certain template constructs "
4282 "easier to write as dimension independent code but "
4283 "the conversion is not valid in the current context."));
4284}
4285
4286
4287
4288template <int structdim, int dim, int spacedim>
4289template <int structdim2, int dim2, int spacedim2>
4292{
4293 Assert(false,
4294 ExcMessage("You are attempting an illegal conversion between "
4295 "iterator/accessor types. The constructor you call "
4296 "only exists to make certain template constructs "
4297 "easier to write as dimension independent code but "
4298 "the conversion is not valid in the current context."));
4299}
4300
4301
4302
4303template <int dim, int spacedim>
4304template <int structdim2, int dim2, int spacedim2>
4307{
4308 Assert(false,
4309 ExcMessage("You are attempting an illegal conversion between "
4310 "iterator/accessor types. The constructor you call "
4311 "only exists to make certain template constructs "
4312 "easier to write as dimension independent code but "
4313 "the conversion is not valid in the current context."));
4314}
4315
4316
4317#ifndef DOXYGEN
4318
4319template <>
4320bool
4322template <>
4323bool
4325template <>
4326bool
4328template <>
4329bool
4331template <>
4332bool
4334template <>
4335bool
4337// -------------------------------------------------------------------
4338
4339template <>
4340void
4342
4343
4344
4345namespace internal
4346{
4347 namespace TriaAccessorImplementation
4348 {
4354 template <int dim, int spacedim>
4355 inline double
4356 diameter(
4357 const boost::container::small_vector<Point<spacedim>,
4359 vertices)
4360 {
4361 const ReferenceCell reference_cell =
4362 ReferenceCell::n_vertices_to_type(dim, vertices.size());
4363
4364 if (reference_cell == ReferenceCells::Line)
4365 // Return the distance between the two vertices
4366 return (vertices[1] - vertices[0]).norm();
4367 else if (reference_cell == ReferenceCells::Triangle)
4368 // Return the longest of the three edges
4369 return std::max({(vertices[1] - vertices[0]).norm(),
4370 (vertices[2] - vertices[1]).norm(),
4371 (vertices[2] - vertices[0]).norm()});
4372 else if (reference_cell == ReferenceCells::Quadrilateral)
4373 // Return the longer one of the two diagonals of the quadrilateral
4374 return std::max({(vertices[3] - vertices[0]).norm(),
4375 (vertices[2] - vertices[1]).norm()});
4376 else if (reference_cell == ReferenceCells::Tetrahedron)
4377 // Return the longest of the six edges of the tetrahedron
4378 return std::max({(vertices[1] - vertices[0]).norm(),
4379 (vertices[2] - vertices[0]).norm(),
4380 (vertices[2] - vertices[1]).norm(),
4381 (vertices[3] - vertices[0]).norm(),
4382 (vertices[3] - vertices[1]).norm(),
4383 (vertices[3] - vertices[2]).norm()});
4384 else if (reference_cell == ReferenceCells::Pyramid)
4385 // Return ...
4386 return std::max({// the longest diagonal of the quadrilateral base
4387 // of the pyramid or ...
4388 (vertices[3] - vertices[0]).norm(),
4389 (vertices[2] - vertices[1]).norm(),
4390 // the longest edge connected with the apex of the
4391 // pyramid
4392 (vertices[4] - vertices[0]).norm(),
4393 (vertices[4] - vertices[1]).norm(),
4394 (vertices[4] - vertices[2]).norm(),
4395 (vertices[4] - vertices[3]).norm()});
4396 else if (reference_cell == ReferenceCells::Wedge)
4397 // Return ...
4398 return std::max({// the longest of the 2*3=6 diagonals of the three
4399 // quadrilateral sides of the wedge or ...
4400 (vertices[4] - vertices[0]).norm(),
4401 (vertices[3] - vertices[1]).norm(),
4402 (vertices[5] - vertices[1]).norm(),
4403 (vertices[4] - vertices[2]).norm(),
4404 (vertices[5] - vertices[0]).norm(),
4405 (vertices[3] - vertices[2]).norm(),
4406 // the longest of the 3*2=6 edges of the two
4407 // triangular faces of the wedge
4408 (vertices[1] - vertices[0]).norm(),
4409 (vertices[2] - vertices[1]).norm(),
4410 (vertices[2] - vertices[0]).norm(),
4411 (vertices[4] - vertices[3]).norm(),
4412 (vertices[5] - vertices[4]).norm(),
4413 (vertices[5] - vertices[3]).norm()});
4414 else if (reference_cell == ReferenceCells::Hexahedron)
4415 // Return the longest of the four diagonals of the hexahedron
4416 return std::max({(vertices[7] - vertices[0]).norm(),
4417 (vertices[6] - vertices[1]).norm(),
4418 (vertices[2] - vertices[5]).norm(),
4419 (vertices[3] - vertices[4]).norm()});
4420
4422 return -1e10;
4423 }
4424 } // namespace TriaAccessorImplementation
4425} // namespace internal
4426
4427
4428/*--------------------- Functions: TriaAccessorBase -------------------------*/
4429
4430template <int structdim, int dim, int spacedim>
4432 const Triangulation<dim, spacedim> *tria,
4433 const int level,
4434 const int index,
4435 const AccessorData *)
4436 : present_level((structdim == dim) ? level : 0)
4437 , present_index(index)
4438 , tria(tria)
4439{
4440 // non-cells have no level, so a 0
4441 // should have been passed, or a -1
4442 // for an end-iterator, or -2 for
4443 // an invalid (default constructed)
4444 // iterator
4445 if (structdim != dim)
4446 {
4447 Assert((level == 0) || (level == -1) || (level == -2),
4449 }
4450}
4451
4452
4453template <int structdim, int dim, int spacedim>
4456 : present_level(a.present_level)
4457 , present_index(a.present_index)
4458 , tria(a.tria)
4459{}
4460
4461
4462template <int structdim, int dim, int spacedim>
4463inline void
4466{
4467 present_level = a.present_level;
4468 present_index = a.present_index;
4469 tria = a.tria;
4470
4471 if (structdim != dim)
4472 {
4473 Assert((present_level == 0) || (present_level == -1) ||
4474 (present_level == -2),
4476 }
4477}
4478
4479
4480
4481template <int structdim, int dim, int spacedim>
4485{
4486 present_level = a.present_level;
4487 present_index = a.present_index;
4488 tria = a.tria;
4489
4490 if (structdim != dim)
4491 {
4492 Assert((present_level == 0) || (present_level == -1) ||
4493 (present_level == -2),
4495 }
4496 return *this;
4497}
4498
4499
4500
4501template <int structdim, int dim, int spacedim>
4502inline bool
4505{
4506 Assert(tria == a.tria || tria == nullptr || a.tria == nullptr,
4508 return ((tria == a.tria) && (present_level == a.present_level) &&
4509 (present_index == a.present_index));
4510}
4511
4512
4513
4514template <int structdim, int dim, int spacedim>
4515inline bool
4518{
4519 Assert(tria == a.tria || tria == nullptr || a.tria == nullptr,
4521 return ((tria != a.tria) || (present_level != a.present_level) ||
4522 (present_index != a.present_index));
4523}
4524
4525
4526
4527template <int structdim, int dim, int spacedim>
4528inline bool
4531{
4533
4534 if (present_level != other.present_level)
4535 return (present_level < other.present_level);
4536
4537 return (present_index < other.present_index);
4538}
4539
4540
4541
4542template <int structdim, int dim, int spacedim>
4543inline int
4545{
4546 // This is always zero or invalid
4547 // if the object is not a cell
4548 return present_level;
4549}
4550
4551
4552
4553template <int structdim, int dim, int spacedim>
4554inline int
4556{
4557 return present_index;
4558}
4559
4560
4561
4562template <int structdim, int dim, int spacedim>
4565{
4566 if ((present_level >= 0) && (present_index >= 0))
4567 return IteratorState::valid;
4568 else if (present_index == -1)
4570 else
4572}
4573
4574
4575
4576template <int structdim, int dim, int spacedim>
4577inline const Triangulation<dim, spacedim> &
4579{
4580 return *tria;
4581}
4582
4583
4584
4585template <int structdim, int dim, int spacedim>
4586inline void
4588{
4589 // this iterator is used for
4590 // objects without level
4591 ++this->present_index;
4592
4593 if (structdim != dim)
4594 {
4595 // is index still in the range of
4596 // the vector? (note that we don't
4597 // have to set the level, since
4598 // dim!=1 and the object therefore
4599 // has no level)
4600 if (this->present_index >= static_cast<int>(objects().n_objects()))
4601 this->present_index = -1;
4602 }
4603 else
4604 {
4605 while (this->present_index >=
4606 static_cast<int>(
4607 this->tria->levels[this->present_level]->cells.n_objects()))
4608 {
4609 // no -> go one level up until we find
4610 // one with more than zero cells
4611 ++this->present_level;
4612 this->present_index = 0;
4613 // highest level reached?
4614 if (this->present_level >=
4615 static_cast<int>(this->tria->levels.size()))
4616 {
4617 // return with past the end pointer
4618 this->present_level = this->present_index = -1;
4619 return;
4620 }
4621 }
4622 }
4623}
4624
4625
4626template <int structdim, int dim, int spacedim>
4627inline void
4629{
4630 // same as operator++
4631 --this->present_index;
4632
4633 if (structdim != dim)
4634 {
4635 if (this->present_index < 0)
4636 this->present_index = -1;
4637 }
4638 else
4639 {
4640 while (this->present_index < 0)
4641 {
4642 // no -> go one level down
4643 --this->present_level;
4644 // lowest level reached?
4645 if (this->present_level == -1)
4646 {
4647 // return with past the end pointer
4648 this->present_level = this->present_index = -1;
4649 return;
4650 }
4651 // else
4652 this->present_index =
4653 this->tria->levels[this->present_level]->cells.n_objects() - 1;
4654 }
4655 }
4656}
4657
4658
4659
4660template <int structdim, int dim, int spacedim>
4661inline ::internal::TriangulationImplementation::TriaObjects &
4663{
4664 if (structdim == dim)
4665 return this->tria->levels[this->present_level]->cells;
4666
4667 if (structdim == 1 && dim > 1)
4668 return this->tria->faces->lines;
4669
4670 if (structdim == 2 && dim > 2)
4671 return this->tria->faces->quads;
4672
4674
4675 return this->tria->levels[this->present_level]->cells;
4676}
4677
4678
4679
4680/*---------------------- Functions: InvalidAccessor -------------------------*/
4681
4682template <int structdim, int dim, int spacedim>
4684 const int,
4685 const int,
4686 const AccessorData *)
4687{
4688 Assert(false,
4689 ExcMessage("You are attempting an invalid conversion between "
4690 "iterator/accessor types. The constructor you call "
4691 "only exists to make certain template constructs "
4692 "easier to write as dimension independent code but "
4693 "the conversion is not valid in the current context."));
4694}
4695
4696
4697
4698template <int structdim, int dim, int spacedim>
4700 const InvalidAccessor &)
4701{
4702 Assert(false,
4703 ExcMessage("You are attempting an invalid conversion between "
4704 "iterator/accessor types. The constructor you call "
4705 "only exists to make certain template constructs "
4706 "easier to write as dimension independent code but "
4707 "the conversion is not valid in the current context."));
4708}
4709
4710
4711
4712template <int structdim, int dim, int spacedim>
4713void
4715{
4716 // nothing to do here. we could
4717 // throw an exception but we can't
4718 // get here without first creating
4719 // an object which would have
4720 // already thrown
4721}
4722
4723
4724
4725template <int structdim, int dim, int spacedim>
4726bool
4728 const InvalidAccessor &) const
4729{
4730 // nothing to do here. we could
4731 // throw an exception but we can't
4732 // get here without first creating
4733 // an object which would have
4734 // already thrown
4735 return false;
4736}
4737
4738
4739
4740template <int structdim, int dim, int spacedim>
4741bool
4743 const InvalidAccessor &) const
4744{
4745 // nothing to do here. we could
4746 // throw an exception but we can't
4747 // get here without first creating
4748 // an object which would have
4749 // already thrown
4750 return true;
4751}
4752
4753
4754
4755template <int structdim, int dim, int spacedim>
4756bool
4758{
4759 // nothing to do here. we could
4760 // throw an exception but we can't
4761 // get here without first creating
4762 // an object which would have
4763 // already thrown
4764 return false;
4765}
4766
4767
4768
4769template <int structdim, int dim, int spacedim>
4770bool
4772{
4773 // nothing to do here. we could
4774 // throw an exception but we can't
4775 // get here without first creating
4776 // an object which would have
4777 // already thrown
4778 return false;
4779}
4780
4781
4782
4783template <int structdim, int dim, int spacedim>
4784void
4786{}
4787
4788
4789
4790template <int structdim, int dim, int spacedim>
4791void
4793{}
4794
4795
4796
4797template <int structdim, int dim, int spacedim>
4800{
4802}
4803
4804
4805
4806template <int structdim, int dim, int spacedim>
4807unsigned int
4809{
4811}
4812
4813
4814
4815template <int structdim, int dim, int spacedim>
4816void
4818 const unsigned int) const
4819{
4820 Assert(false,
4821 ExcMessage("You are trying to set the user index of an "
4822 "invalid object."));
4823}
4824
4825
4826
4827template <int structdim, int dim, int spacedim>
4828void
4830 const types::manifold_id) const
4831{
4832 Assert(false,
4833 ExcMessage("You are trying to set the manifold id of an "
4834 "invalid object."));
4835}
4836
4837
4838
4839template <int structdim, int dim, int spacedim>
4840inline Point<spacedim> &
4842{
4843 // nothing to do here. we could throw an exception but we can't get here
4844 // without first creating an object which would have already thrown
4845 static Point<spacedim> invalid_vertex;
4846 return invalid_vertex;
4847}
4848
4849
4850template <int structdim, int dim, int spacedim>
4851inline void *
4853{
4854 // nothing to do here. we could throw an exception but we can't get here
4855 // without first creating an object which would have already thrown
4856 return nullptr;
4857}
4858
4859
4860
4861template <int structdim, int dim, int spacedim>
4862inline void *
4864{
4865 // nothing to do here. we could throw an exception but we can't get here
4866 // without first creating an object which would have already thrown
4867 return nullptr;
4868}
4869
4870
4871/*------------------------ Functions: TriaAccessor ---------------------------*/
4872
4873
4874namespace internal
4875{
4876 namespace TriaAccessorImplementation
4877 {
4878 // make sure that if in the following we
4879 // write TriaAccessor
4880 // we mean the *class*
4881 // ::TriaAccessor, not the
4882 // enclosing namespace
4883 // ::internal::TriaAccessor
4884 using ::TriaAccessor;
4885
4890 struct Implementation
4891 {
4895 template <int structdim, int dim, int spacedim>
4896 inline static void
4897 set_combined_face_orientation(
4899 const unsigned int face_no,
4900 const types::geometric_orientation combined_orientation)
4901 {
4902 Assert(structdim == dim,
4903 ExcMessage("This function can only be used on objects that are "
4904 "cells and not on objects which bound cells."));
4905 AssertIndexRange(face_no, accessor.n_faces());
4906 AssertIndexRange(combined_orientation,
4908 face_no));
4909
4910 // face_orientations is not set up in 1d
4911 if (dim != 1)
4912 accessor.tria->levels[accessor.present_level]
4913 ->face_orientations.set_combined_orientation(
4914 accessor.present_index * ReferenceCells::max_n_faces<dim>() +
4915 face_no,
4916 combined_orientation);
4917 }
4918
4919
4920
4921 template <int dim, int spacedim>
4922 static std::array<unsigned int, 1>
4923 get_line_indices_of_cell(const TriaAccessor<1, dim, spacedim> &)
4924 {
4926 return {};
4927 }
4928
4929
4930
4931 template <int structdim, int dim, int spacedim>
4932 static std::array<unsigned int, 4>
4933 get_line_indices_of_cell(const TriaAccessor<2, dim, spacedim> &cell)
4934 {
4935 // For 2d cells the access cell->line_orientation() is already
4936 // efficient
4937 std::array<unsigned int, 4> line_indices = {};
4938 for (const unsigned int line : cell.line_indices())
4939 line_indices[line] = cell.line_index(line);
4940 return line_indices;
4941 }
4942
4947 template <int structdim, int dim, int spacedim>
4948 static std::array<unsigned int, 12>
4949 get_line_indices_of_cell(
4951 {
4952 std::array<unsigned int, 12> line_indices = {};
4953
4954 // For hexahedra, the classical access via quads -> lines is too
4955 // inefficient. Unroll this code here to allow the compiler to inline
4956 // the necessary functions.
4957 const auto ref_cell = cell.reference_cell();
4958 if (ref_cell == ReferenceCells::Hexahedron)
4959 {
4960 for (unsigned int f = 4; f < 6; ++f)
4961 {
4962 const auto orientation =
4963 cell.get_triangulation()
4964 .levels[cell.level()]
4965 ->face_orientations.get_combined_orientation(
4966 cell.index() * ReferenceCells::max_n_faces<dim>() + f);
4967
4968 // It might seem superfluous to spell out the four indices
4969 // that get later consumed by a for loop over these four
4970 // elements; however, for the compiler it is easier to inline
4971 // the statement of standard_to_real_face_line() when next to
4972 // each other, as opposed to be interleaved with a
4973 // line_index() call.
4974 const std::array<unsigned int, 4> my_indices{
4975 {ref_cell.standard_to_real_face_line(0, f, orientation),
4976 ref_cell.standard_to_real_face_line(1, f, orientation),
4977 ref_cell.standard_to_real_face_line(2, f, orientation),
4978 ref_cell.standard_to_real_face_line(3, f, orientation)}};
4979 const auto quad = cell.quad(f);
4980 for (unsigned int l = 0; l < 4; ++l)
4981 line_indices[4 * (f - 4) + l] =
4982 quad->line_index(my_indices[l]);
4983 }
4984 for (unsigned int f = 0; f < 2; ++f)
4985 {
4986 const auto orientation =
4987 cell.get_triangulation()
4988 .levels[cell.level()]
4989 ->face_orientations.get_combined_orientation(
4990 cell.index() * ReferenceCells::max_n_faces<dim>() + f);
4991 const std::array<unsigned int, 2> my_indices{
4992 {ref_cell.standard_to_real_face_line(0, f, orientation),
4993 ref_cell.standard_to_real_face_line(1, f, orientation)}};
4994 const auto quad = cell.quad(f);
4995 line_indices[8 + f] = quad->line_index(my_indices[0]);
4996 line_indices[10 + f] = quad->line_index(my_indices[1]);
4997 }
4998 }
4999 else if (ref_cell == ReferenceCells::Tetrahedron)
5000 {
5001 std::array<unsigned int, 3> orientations{
5004 cell.combined_face_orientation(2)}};
5005 const std::array<unsigned int, 6> my_indices{
5006 {ref_cell.standard_to_real_face_line(0, 0, orientations[0]),
5007 ref_cell.standard_to_real_face_line(1, 0, orientations[0]),
5008 ref_cell.standard_to_real_face_line(2, 0, orientations[0]),
5009 ref_cell.standard_to_real_face_line(1, 1, orientations[1]),
5010 ref_cell.standard_to_real_face_line(2, 1, orientations[1]),
5011 ref_cell.standard_to_real_face_line(1, 2, orientations[2])}};
5012 line_indices[0] = cell.quad(0)->line_index(my_indices[0]);
5013 line_indices[1] = cell.quad(0)->line_index(my_indices[1]);
5014 line_indices[2] = cell.quad(0)->line_index(my_indices[2]);
5015 line_indices[3] = cell.quad(1)->line_index(my_indices[3]);
5016 line_indices[4] = cell.quad(1)->line_index(my_indices[4]);
5017 line_indices[5] = cell.quad(2)->line_index(my_indices[5]);
5018 }
5019 else
5020 // For other shapes (wedges, pyramids), we do not currently
5021 // implement an optimized function.
5022 for (unsigned int l = 0; l < std::min(12U, cell.n_lines()); ++l)
5023 line_indices[l] = cell.line_index(l);
5024
5025 return line_indices;
5026 }
5027
5028
5029
5034 template <int dim, int spacedim>
5035 static std::array<types::geometric_orientation, 1>
5036 get_line_orientations_of_cell(const TriaAccessor<1, dim, spacedim> &)
5037 {
5039 return {};
5040 }
5041
5042
5043
5048 template <int dim, int spacedim>
5049 static std::array<types::geometric_orientation, 4>
5050 get_line_orientations_of_cell(const TriaAccessor<2, dim, spacedim> &cell)
5051 {
5052 // For 2d cells the access cell->line_orientation() is already
5053 // efficient
5054 std::array<types::geometric_orientation, 4> line_orientations = {};
5055 for (const unsigned int line : cell.line_indices())
5056 line_orientations[line] = cell.line_orientation(line);
5057 return line_orientations;
5058 }
5059
5060
5061
5066 template <int dim, int spacedim>
5067 static std::array<types::geometric_orientation, 12>
5068 get_line_orientations_of_cell(const TriaAccessor<3, dim, spacedim> &cell)
5069 {
5070 std::array<types::geometric_orientation, 12> line_orientations = {};
5071
5072 // For hexahedra, the classical access via quads -> lines is too
5073 // inefficient. Unroll this code here to allow the compiler to inline
5074 // the necessary functions.
5075 const auto ref_cell = cell.reference_cell();
5076 if (ref_cell == ReferenceCells::Hexahedron)
5077 {
5078 for (unsigned int f = 4; f < 6; ++f)
5079 {
5080 const auto orientation =
5081 cell.get_triangulation()
5082 .levels[cell.level()]
5083 ->face_orientations.get_combined_orientation(
5084 cell.index() * ReferenceCells::max_n_faces<dim>() + f);
5085
5086 // It might seem superfluous to spell out the four indices and
5087 // orientations that get later consumed by a for loop over
5088 // these four elements; however, for the compiler it is easier
5089 // to inline the statement of standard_to_real_face_line()
5090 // when next to each other, as opposed to be interleaved with
5091 // a line_index() call.
5092 const std::array<unsigned int, 4> my_indices{
5093 {ref_cell.standard_to_real_face_line(0, f, orientation),
5094 ref_cell.standard_to_real_face_line(1, f, orientation),
5095 ref_cell.standard_to_real_face_line(2, f, orientation),
5096 ref_cell.standard_to_real_face_line(3, f, orientation)}};
5097 const auto quad = cell.quad(f);
5098 const std::array<types::geometric_orientation, 4>
5099 my_orientations{{ref_cell.face_to_cell_line_orientation(
5100 0,
5101 f,
5102 orientation,
5103 quad->line_orientation(my_indices[0])),
5104 ref_cell.face_to_cell_line_orientation(
5105 1,
5106 f,
5107 orientation,
5108 quad->line_orientation(my_indices[1])),
5109 ref_cell.face_to_cell_line_orientation(
5110 2,
5111 f,
5112 orientation,
5113 quad->line_orientation(my_indices[2])),
5114 ref_cell.face_to_cell_line_orientation(
5115 3,
5116 f,
5117 orientation,
5118 quad->line_orientation(my_indices[3]))}};
5119 for (unsigned int l = 0; l < 4; ++l)
5120 line_orientations[4 * (f - 4) + l] = my_orientations[l];
5121 }
5122 for (unsigned int f = 0; f < 2; ++f)
5123 {
5124 const auto orientation =
5125 cell.get_triangulation()
5126 .levels[cell.level()]
5127 ->face_orientations.get_combined_orientation(
5128 cell.index() * ReferenceCells::max_n_faces<3>() + f);
5129 const std::array<unsigned int, 2> my_indices{
5130 {ref_cell.standard_to_real_face_line(0, f, orientation),
5131 ref_cell.standard_to_real_face_line(1, f, orientation)}};
5132 const auto quad = cell.quad(f);
5133 const std::array<types::geometric_orientation, 2>
5134 my_orientations{{ref_cell.face_to_cell_line_orientation(
5135 0,
5136 f,
5137 orientation,
5138 quad->line_orientation(my_indices[0])),
5139 ref_cell.face_to_cell_line_orientation(
5140 1,
5141 f,
5142 orientation,
5143 quad->line_orientation(my_indices[1]))}};
5144 line_orientations[8 + f] = my_orientations[0];
5145 line_orientations[10 + f] = my_orientations[1];
5146 }
5147 }
5148 else if (ref_cell == ReferenceCells::Tetrahedron)
5149 {
5150 std::array<unsigned int, 3> orientations{
5153 cell.combined_face_orientation(2)}};
5154 const std::array<unsigned int, 6> my_indices{
5155 {ref_cell.standard_to_real_face_line(0, 0, orientations[0]),
5156 ref_cell.standard_to_real_face_line(1, 0, orientations[0]),
5157 ref_cell.standard_to_real_face_line(2, 0, orientations[0]),
5158 ref_cell.standard_to_real_face_line(1, 1, orientations[1]),
5159 ref_cell.standard_to_real_face_line(2, 1, orientations[1]),
5160 ref_cell.standard_to_real_face_line(1, 2, orientations[2])}};
5161 line_orientations[0] = ref_cell.face_to_cell_line_orientation(
5162 0,
5163 0,
5164 orientations[0],
5165 cell.quad(0)->line_orientation(my_indices[0]));
5166 line_orientations[1] = ref_cell.face_to_cell_line_orientation(
5167 1,
5168 0,
5169 orientations[0],
5170 cell.quad(0)->line_orientation(my_indices[1]));
5171 line_orientations[2] = ref_cell.face_to_cell_line_orientation(
5172 2,
5173 0,
5174 orientations[0],
5175 cell.quad(0)->line_orientation(my_indices[2]));
5176 line_orientations[3] = ref_cell.face_to_cell_line_orientation(
5177 1,
5178 1,
5179 orientations[1],
5180 cell.quad(1)->line_orientation(my_indices[3]));
5181 line_orientations[4] = ref_cell.face_to_cell_line_orientation(
5182 2,
5183 1,
5184 orientations[1],
5185 cell.quad(1)->line_orientation(my_indices[4]));
5186 line_orientations[5] = ref_cell.face_to_cell_line_orientation(
5187 1,
5188 2,
5189 orientations[2],
5190 cell.quad(2)->line_orientation(my_indices[5]));
5191 }
5192 else
5193 // For other shapes (wedges, pyramids), we do not currently
5194 // implement an optimized function
5195 for (unsigned int l = 0; l < std::min(12U, cell.n_lines()); ++l)
5196 line_orientations[l] = cell.line_orientation(l);
5197
5198 return line_orientations;
5199 }
5200 };
5201 } // namespace TriaAccessorImplementation
5202} // namespace internal
5203
5204
5205
5206template <int structdim, int dim, int spacedim>
5208 const Triangulation<dim, spacedim> *parent,
5209 const int level,
5210 const int index,
5211 const AccessorData *local_data)
5212 : TriaAccessorBase<structdim, dim, spacedim>(parent, level, index, local_data)
5213{}
5214
5215
5216
5217template <int structdim, int dim, int spacedim>
5218inline bool
5220{
5221 Assert(this->state() == IteratorState::valid,
5222 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5223 *this));
5224 return this->objects().used[this->present_index];
5225}
5226
5227
5228
5229template <int structdim, int dim, int spacedim>
5232 const unsigned int i) const
5233{
5235 0,
5236 vertex_index(i));
5237}
5238
5239
5240
5241template <int structdim, int dim, int spacedim>
5242inline ReferenceCell
5244{
5245 if (structdim == 0)
5247 else if (structdim == 1)
5248 return ReferenceCells::Line;
5249 else if (structdim == dim)
5250 return this->tria->levels[this->present_level]
5251 ->reference_cell[this->present_index];
5252 else
5253 return this->tria->faces->get_quad_type(this->present_index);
5254}
5255
5256
5257
5258template <int structdim, int dim, int spacedim>
5259inline unsigned int
5261 const unsigned int corner) const
5262{
5263 AssertIndexRange(corner, this->n_vertices());
5264
5265 if constexpr (structdim == 1)
5266 {
5267 // This branch needs to be first (and not combined with the structdim ==
5268 // dim branch) so that we can get line vertex indices when setting up the
5269 // cell vertex index cache
5270 return this->objects()
5271 .cells[this->present_index * ReferenceCells::max_n_faces<1>() + corner];
5272 }
5273 else if constexpr (structdim == dim)
5274 {
5275 // This branch should only be used after the cell vertex index cache is
5276 // set up
5277 const auto my_index = static_cast<std::size_t>(this->present_index) *
5278 ReferenceCells::max_n_vertices<dim>();
5279 AssertIndexRange(my_index + corner,
5280 this->tria->levels[this->present_level]
5281 ->cell_vertex_indices_cache.size());
5282 const unsigned int vertex_index =
5283 this->tria->levels[this->present_level]
5284 ->cell_vertex_indices_cache[my_index + corner];
5286 return vertex_index;
5287 }
5288 else if constexpr (structdim == 2)
5289 {
5290 const auto [line_index, vertex_index] =
5291 this->reference_cell().standard_vertex_to_face_and_vertex_index(corner);
5292 const auto vertex_within_line_index =
5293 this->reference_cell().standard_to_real_face_vertex(
5294 vertex_index, line_index, this->line_orientation(line_index));
5295
5296 return this->line(line_index)->vertex_index(vertex_within_line_index);
5297 }
5298 else
5299 {
5302 }
5303}
5304
5305
5306
5307template <int structdim, int dim, int spacedim>
5308inline Point<spacedim> &
5309TriaAccessor<structdim, dim, spacedim>::vertex(const unsigned int i) const
5310{
5311 return const_cast<Point<spacedim> &>(this->tria->vertices[vertex_index(i)]);
5312}
5313
5314
5315
5316template <int structdim, int dim, int spacedim>
5317inline typename ::internal::TriangulationImplementation::
5318 Iterators<dim, spacedim>::line_iterator
5319 TriaAccessor<structdim, dim, spacedim>::line(const unsigned int i) const
5320{
5321 // checks happen in line_index
5322 return typename ::internal::TriangulationImplementation::
5323 Iterators<dim, spacedim>::line_iterator(this->tria, 0, line_index(i));
5324}
5325
5326
5327
5328template <int structdim, int dim, int spacedim>
5329inline unsigned int
5331{
5332 (void)i;
5333 AssertIndexRange(i, this->n_lines());
5334 Assert(structdim != 1,
5335 ExcMessage("You can't ask for the index of a line bounding a "
5336 "one-dimensional cell because it is not bounded by "
5337 "lines."));
5338
5339 if constexpr (structdim == 2)
5340 {
5341 return this->objects()
5342 .cells[this->present_index * ReferenceCells::max_n_faces<2>() + i];
5343 }
5344 else if constexpr (structdim == 3)
5345 {
5346 const auto [face_index, line_index] =
5347 this->reference_cell().standard_line_to_face_and_line_index(i);
5348 const auto line_within_face_index =
5349 this->reference_cell().standard_to_real_face_line(
5350 line_index, face_index, this->combined_face_orientation(face_index));
5351
5352 return this->quad(face_index)->line_index(line_within_face_index);
5353 }
5354
5357}
5358
5359
5360
5361template <int structdim, int dim, int spacedim>
5362inline typename ::internal::TriangulationImplementation::
5363 Iterators<dim, spacedim>::quad_iterator
5364 TriaAccessor<structdim, dim, spacedim>::quad(const unsigned int i) const
5365{
5366 // checks happen in quad_index
5367 return typename ::internal::TriangulationImplementation::
5368 Iterators<dim, spacedim>::quad_iterator(this->tria, 0, quad_index(i));
5369}
5370
5371
5372
5373template <int structdim, int dim, int spacedim>
5374inline unsigned int
5376{
5377 Assert(structdim == 3,
5378 ExcMessage("You can't ask for the index of a quad bounding "
5379 "a one- or two-dimensional cell because it is not "
5380 "bounded by quads."));
5381 // work around a bogus GCC-9 warning which considers i unused except in 3d
5382 (void)i;
5383 if constexpr (structdim == 3)
5384 {
5385 AssertIndexRange(i, n_faces());
5386 return this->tria->levels[this->present_level]
5387 ->cells
5388 .cells[this->present_index * ReferenceCells::max_n_faces<3>() + i];
5389 }
5390 else
5392}
5393
5394
5395
5396template <int structdim, int dim, int spacedim>
5399 const unsigned int face) const
5400{
5402 AssertIndexRange(face, n_faces());
5403 Assert(structdim == dim,
5404 ExcMessage("This function can only be used on objects "
5405 "that are cells, but not on faces or edges "
5406 "that bound cells."));
5407 // work around a bogus GCC-9 warning which considers face unused except in 3d
5408 (void)face;
5409
5410 if constexpr (structdim == 1)
5412 else if constexpr (structdim == 2)
5413 {
5414 // if all elements are quads (or if we have a very special consistently
5415 // oriented triangular mesh) then we do not store this array
5416 if (this->tria->levels[this->present_level]
5417 ->face_orientations.n_objects() == 0)
5419 else
5420 return this->tria->levels[this->present_level]
5421 ->face_orientations.get_combined_orientation(
5422 this->present_index * ReferenceCells::max_n_faces<dim>() + face);
5423 }
5424 else
5425 return this->tria->levels[this->present_level]
5426 ->face_orientations.get_combined_orientation(
5427 this->present_index * ReferenceCells::max_n_faces<dim>() + face);
5428}
5429
5430
5431
5432template <int structdim, int dim, int spacedim>
5433inline bool
5435 const unsigned int face) const
5436{
5438 AssertIndexRange(face, n_faces());
5439 Assert(structdim == dim,
5440 ExcMessage("This function can only be used on objects "
5441 "that are cells, but not on faces or edges "
5442 "that bound cells."));
5443 // work around a bogus GCC-9 warning which considers face unused in 1d
5444 (void)face;
5445
5446 if constexpr (structdim == 1)
5447 // in 1d 'faces' are vertices and those are always consistently oriented
5448 return true;
5449 else if constexpr (structdim == 2)
5450 return this->line_orientation(face) ==
5452 else
5453 return this->tria->levels[this->present_level]
5454 ->face_orientations.get_orientation(
5455 this->present_index * ReferenceCells::max_n_faces<structdim>() + face);
5456}
5457
5458
5459
5460template <int structdim, int dim, int spacedim>
5461inline bool
5462TriaAccessor<structdim, dim, spacedim>::face_flip(const unsigned int face) const
5463{
5465 Assert(structdim == dim,
5466 ExcMessage("This function can only be used on objects "
5467 "that are cells, but not on faces or edges "
5468 "that bound cells."));
5469 AssertIndexRange(face, n_faces());
5470 // work around a bogus GCC-9 warning which considers face unused except in 3d
5471 (void)face;
5472
5473 if constexpr (structdim == 3)
5474 return this->tria->levels[this->present_level]->face_orientations.get_flip(
5475 this->present_index * ReferenceCells::max_n_faces<structdim>() + face);
5476 else
5477 // In 1d and 2d, face_flip is always false as faces can only be
5478 // 'flipped' in 3d.
5479 return false;
5480}
5481
5482
5483template <int structdim, int dim, int spacedim>
5484inline bool
5486 const unsigned int face) const
5487{
5489 Assert(structdim == dim,
5490 ExcMessage("This function can only be used on objects "
5491 "that are cells, but not on faces or edges "
5492 "that bound cells."));
5493 AssertIndexRange(face, n_faces());
5494 // work around a bogus GCC-9 warning which considers face unused except in 3d
5495 (void)face;
5496
5497 if constexpr (structdim == 3)
5498 return this->tria->levels[this->present_level]
5499 ->face_orientations.get_rotation(
5500 this->present_index * ReferenceCells::max_n_faces<structdim>() + face);
5501 else
5502 // In 1d and 2d, face_rotation is always false as faces can only be
5503 // 'rotated' in 3d.
5504 return false;
5505}
5506
5507
5508
5509template <int structdim, int dim, int spacedim>
5512 const unsigned int line) const
5513{
5515 AssertIndexRange(line, this->n_lines());
5516 // work around a bogus GCC-9 warning which considers line unused in 1d
5517 (void)line;
5518
5519 if constexpr (structdim == 1)
5521 else if constexpr (structdim == 2 && dim == 2)
5522 // lines in 2d are faces
5523 {
5524 const auto combined_orientation = combined_face_orientation(line);
5525 Assert(combined_orientation == numbers::default_geometric_orientation ||
5526 combined_orientation == numbers::reverse_line_orientation,
5528 return combined_orientation;
5529 }
5530 else if constexpr (structdim == 2 && dim == 3)
5531 {
5532 // line orientations in 3d are stored in their own array as bools: here
5533 // 'true' is the default orientation and 'false' is the reversed one
5534 // (which matches set_line_orientation())
5535 const auto index =
5536 this->present_index * ReferenceCells::max_n_lines<2>() + line;
5537 Assert(index < this->tria->faces->quads_line_orientations.size(),
5539 return this->tria->faces->quads_line_orientations[index] ?
5542 }
5543 else if constexpr (structdim == 3 && dim == 3)
5544 {
5545 const auto reference_cell = this->reference_cell();
5546 // First pick a face on which this line is a part of, and the
5547 // index of the line within.
5548 const auto [face_index, line_index] =
5549 reference_cell.standard_line_to_face_and_line_index(line);
5550 const auto line_within_face_index =
5551 reference_cell.standard_to_real_face_line(
5552 line_index, face_index, this->combined_face_orientation(face_index));
5553
5554 // Then query how that line is oriented within that face:
5555 return reference_cell.face_to_cell_line_orientation(
5556 line_index,
5557 face_index,
5558 this->combined_face_orientation(face_index),
5559 this->quad(face_index)->line_orientation(line_within_face_index));
5560 }
5561 else
5562 {
5564 return false;
5565 }
5566}
5567
5568
5569
5570template <int structdim, int dim, int spacedim>
5571inline void
5573 const unsigned int line,
5574 const types::geometric_orientation value) const
5575{
5577 AssertIndexRange(line, this->n_lines());
5578 Assert(dim != 1,
5579 ExcMessage("In 1d lines are cells and thus do not need to have their "
5580 "orientations set."));
5581 Assert(dim != 2,
5582 ExcMessage("In 2d lines are faces, and, for compatibility with other "
5583 "dimensions, their orientations should be set via "
5584 "set_combined_face_orientation()."));
5585 // work around a bogus GCC-9 warning which considers line and value unused
5586 // except in 3d
5587 (void)line;
5588 (void)value;
5589
5590 if constexpr (dim == 3)
5591 {
5592 // We set line orientations per face, not per cell, so this only works for
5593 // faces in 3d.
5594 Assert(structdim == 2, ExcNotImplemented());
5595 const auto index =
5596 this->present_index * ReferenceCells::max_n_lines<2>() + line;
5597 Assert(index < this->tria->faces->quads_line_orientations.size(),
5599 this->tria->faces->quads_line_orientations[index] =
5601 }
5602}
5603
5604
5605
5606template <int structdim, int dim, int spacedim>
5607inline void
5609 const unsigned int face,
5610 const types::geometric_orientation combined_orientation) const
5611{
5613 AssertIndexRange(face, this->n_faces());
5614
5615 ::internal::TriaAccessorImplementation::Implementation::
5616 set_combined_face_orientation(*this, face, combined_orientation);
5617}
5618
5619
5620
5621template <int structdim, int dim, int spacedim>
5622void
5624{
5625 Assert(this->state() == IteratorState::valid,
5626 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5627 *this));
5628 this->objects().used[this->present_index] = true;
5629}
5630
5631
5632
5633template <int structdim, int dim, int spacedim>
5634void
5636{
5637 Assert(this->state() == IteratorState::valid,
5638 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5639 *this));
5640 this->objects().used[this->present_index] = false;
5641}
5642
5643
5644template <int structdim, int dim, int spacedim>
5645int
5647{
5649 AssertIndexRange(i, n_children());
5650
5651 // each set of two children are stored
5652 // consecutively, so we only have to find
5653 // the location of the set of children
5654 const unsigned int n_sets_of_two =
5656 return this->objects().children[n_sets_of_two * this->present_index + i / 2] +
5657 i % 2;
5658}
5659
5660
5661
5662template <int structdim, int dim, int spacedim>
5663int
5665 const unsigned int i) const
5666{
5668
5669 switch (structdim)
5670 {
5671 case 1:
5672 return child_index(i);
5673 case 2:
5674 {
5675 const RefinementCase<2> this_refinement_case(
5676 static_cast<std::uint8_t>(refinement_case()));
5677
5678 Assert(this_refinement_case != RefinementCase<2>::no_refinement,
5680
5681 if (this_refinement_case == RefinementCase<2>::cut_xy)
5682 return child_index(i);
5683 else if ((this_refinement_case == RefinementCase<2>::cut_x) &&
5684 (child(i % 2)->refinement_case() ==
5686 return child(i % 2)->child_index(i / 2);
5687 else if ((this_refinement_case == RefinementCase<2>::cut_y) &&
5688 (child(i / 2)->refinement_case() ==
5690 return child(i / 2)->child_index(i % 2);
5691 else
5692 Assert(
5693 false,
5694 ExcMessage(
5695 "This cell has no grandchildren equivalent to isotropic refinement"));
5696 break;
5697 }
5698
5699 case 3:
5701 }
5702 return -1;
5703}
5704
5705
5706
5707template <int structdim, int dim, int spacedim>
5710{
5711 Assert(this->state() == IteratorState::valid,
5712 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5713 *this));
5714
5715 switch (structdim)
5716 {
5717 case 1:
5719 this->objects().children[this->present_index] != -1 ?
5720 // cast the branches
5721 // here first to uchar
5722 // and then (above) to
5723 // RefinementCase<structdim>
5724 // so that the
5725 // conversion is valid
5726 // even for the case
5727 // structdim>1 (for
5728 // which this part of
5729 // the code is dead
5730 // anyway)
5731 static_cast<std::uint8_t>(RefinementCase<1>::cut_x) :
5732 static_cast<std::uint8_t>(RefinementCase<1>::no_refinement)));
5733
5734 default:
5735 Assert(static_cast<unsigned int>(this->present_index) <
5736 this->objects().refinement_cases.size(),
5737 ExcIndexRange(this->present_index,
5738 0,
5739 this->objects().refinement_cases.size()));
5740
5741 return (static_cast<RefinementCase<structdim>>(
5742 this->objects().refinement_cases[this->present_index]));
5743 }
5744}
5745
5746
5747
5748template <int structdim, int dim, int spacedim>
5750TriaAccessor<structdim, dim, spacedim>::child(const unsigned int i) const
5751
5752{
5753 // checking of 'i' happens in child_index
5755 this->tria, (dim == structdim ? this->level() + 1 : 0), child_index(i));
5756
5757 Assert((q.state() == IteratorState::past_the_end) || q->used(),
5759
5760 return q;
5761}
5762
5763
5764
5765template <int structdim, int dim, int spacedim>
5766inline unsigned int
5769{
5770 const auto n_children = this->n_children();
5771 for (unsigned int child_n = 0; child_n < n_children; ++child_n)
5772 if (this->child(child_n) == child)
5773 return child_n;
5774
5775 Assert(false,
5776 ExcMessage("The given child is not a child of the current object."));
5778}
5779
5780
5781
5782template <int structdim, int dim, int spacedim>
5785 const unsigned int i) const
5786{
5787 // checking of 'i' happens in child() or
5788 // child_index() called below
5789 switch (structdim)
5790 {
5791 case 1:
5792 // no anisotropic refinement in 1d
5793 return child(i);
5794
5795 case 2:
5796 {
5797 const RefinementCase<2> this_refinement_case(
5798 static_cast<std::uint8_t>(refinement_case()));
5799
5800 Assert(this_refinement_case != RefinementCase<2>::no_refinement,
5802
5803 if (this_refinement_case == RefinementCase<2>::cut_xy)
5804 return child(i);
5805 else if ((this_refinement_case == RefinementCase<2>::cut_x) &&
5806 (child(i % 2)->refinement_case() ==
5808 return child(i % 2)->child(i / 2);
5809 else if ((this_refinement_case == RefinementCase<2>::cut_y) &&
5810 (child(i / 2)->refinement_case() ==
5812 return child(i / 2)->child(i % 2);
5813 else
5814 Assert(
5815 false,
5816 ExcMessage(
5817 "This cell has no grandchildren equivalent to isotropic refinement"));
5818 break;
5819 }
5820
5821 default:
5823 }
5824 // we don't get here but have to return
5825 // something...
5826 return child(0);
5827}
5828
5829
5830
5831template <int structdim, int dim, int spacedim>
5832inline bool
5834{
5835 Assert(this->state() == IteratorState::valid,
5836 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5837 *this));
5838
5839 // each set of two children are stored
5840 // consecutively, so we only have to find
5841 // the location of the set of children
5842 const unsigned int n_sets_of_two =
5844 return (this->objects().children[n_sets_of_two * this->present_index] != -1);
5845}
5846
5847
5848
5849template <int structdim, int dim, int spacedim>
5850inline unsigned int
5852{
5853 Assert(this->state() == IteratorState::valid,
5854 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5855 *this));
5859 else
5860 return GeometryInfo<structdim>::n_children(refinement_case());
5861}
5862
5863
5864
5865template <int structdim, int dim, int spacedim>
5866inline void
5868 const RefinementCase<structdim> &refinement_case) const
5869{
5870 Assert(this->state() == IteratorState::valid,
5871 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5872 *this));
5873 Assert(static_cast<unsigned int>(this->present_index) <
5874 this->objects().refinement_cases.size(),
5875 ExcIndexRange(this->present_index,
5876 0,
5877 this->objects().refinement_cases.size()));
5878
5879 this->objects().refinement_cases[this->present_index] = refinement_case;
5880}
5881
5882
5883template <int structdim, int dim, int spacedim>
5884inline void
5886{
5887 Assert(this->state() == IteratorState::valid,
5888 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5889 *this));
5890 Assert(static_cast<unsigned int>(this->present_index) <
5891 this->objects().refinement_cases.size(),
5892 ExcIndexRange(this->present_index,
5893 0,
5894 this->objects().refinement_cases.size()));
5895
5896 this->objects().refinement_cases[this->present_index] =
5898}
5899
5900
5901
5902template <int structdim, int dim, int spacedim>
5903void
5905 const int index) const
5906{
5909
5910 // each set of two children are stored
5911 // consecutively, so we only have to find
5912 // the location of the set of children
5913 const unsigned int n_sets_of_two =
5915
5916 Assert(
5917 // clearing the child index for a cell
5918 (index == -1) ||
5919 // if setting the child index for the i'th child (with i==0),
5920 // then the index must be a non-negative number
5921 (i == 0 && !this->has_children() && (index >= 0)) ||
5922 // if setting the child index for the i'th child (with i>0),
5923 // then the previously stored index must be the invalid
5924 // index
5925 (i > 0 && this->has_children() && (index >= 0) &&
5926 this->objects().children[n_sets_of_two * this->present_index + i / 2] ==
5927 -1),
5929
5930 this->objects().children[n_sets_of_two * this->present_index + i / 2] = index;
5931}
5932
5933
5934
5935template <int structdim, int dim, int spacedim>
5936void
5938{
5939 // each set of two children are stored
5940 // consecutively, so we only have to find
5941 // the location of the set of children
5942 const unsigned int n_sets_of_two =
5944
5945 for (unsigned int i = 0; i < n_sets_of_two; ++i)
5946 set_children(2 * i, -1);
5947}
5948
5949
5950
5951template <int structdim, int dim, int spacedim>
5952inline bool
5954{
5956 return this->objects().user_flags[this->present_index];
5957}
5958
5959
5960
5961template <int structdim, int dim, int spacedim>
5962inline void
5964{
5966 this->objects().user_flags[this->present_index] = true;
5967}
5968
5969
5970
5971template <int structdim, int dim, int spacedim>
5972inline void
5974{
5976 this->objects().user_flags[this->present_index] = false;
5977}
5978
5979
5980
5981template <int structdim, int dim, int spacedim>
5982void
5984{
5985 set_user_flag();
5986
5987 if (this->has_children())
5988 for (unsigned int c = 0; c < this->n_children(); ++c)
5989 this->child(c)->recursively_set_user_flag();
5990}
5991
5992
5993
5994template <int structdim, int dim, int spacedim>
5995void
5997{
5998 clear_user_flag();
5999
6000 if (this->has_children())
6001 for (unsigned int c = 0; c < this->n_children(); ++c)
6002 this->child(c)->recursively_clear_user_flag();
6003}
6004
6005
6006
6007template <int structdim, int dim, int spacedim>
6008void
6010{
6012 this->objects().clear_user_data(this->present_index);
6013}
6014
6015
6016
6017template <int structdim, int dim, int spacedim>
6018void
6020{
6022 this->objects().user_pointer(this->present_index) = p;
6023}
6024
6025
6026
6027template <int structdim, int dim, int spacedim>
6028void
6030{
6032 this->objects().user_pointer(this->present_index) = nullptr;
6033}
6034
6035
6036
6037template <int structdim, int dim, int spacedim>
6038void *
6040{
6042 return this->objects().user_pointer(this->present_index);
6043}
6044
6045
6046
6047template <int structdim, int dim, int spacedim>
6048void
6050 void *p) const
6051{
6052 set_user_pointer(p);
6053
6054 if (this->has_children())
6055 for (unsigned int c = 0; c < this->n_children(); ++c)
6056 this->child(c)->recursively_set_user_pointer(p);
6057}
6058
6059
6060
6061template <int structdim, int dim, int spacedim>
6062void
6064{
6065 clear_user_pointer();
6066
6067 if (this->has_children())
6068 for (unsigned int c = 0; c < this->n_children(); ++c)
6069 this->child(c)->recursively_clear_user_pointer();
6070}
6071
6072
6073
6074template <int structdim, int dim, int spacedim>
6075void
6077 const unsigned int p) const
6078{
6080 this->objects().user_index(this->present_index) = p;
6081}
6082
6083
6084
6085template <int structdim, int dim, int spacedim>
6086void
6088{
6090 this->objects().user_index(this->present_index) = 0;
6091}
6092
6093
6094
6095template <int structdim, int dim, int spacedim>
6096unsigned int
6098{
6100 return this->objects().user_index(this->present_index);
6101}
6102
6103
6104
6105template <int structdim, int dim, int spacedim>
6106void
6108 const unsigned int p) const
6109{
6110 set_user_index(p);
6111
6112 if (this->has_children())
6113 for (unsigned int c = 0; c < this->n_children(); ++c)
6114 this->child(c)->recursively_set_user_index(p);
6115}
6116
6117
6118
6119template <int structdim, int dim, int spacedim>
6120void
6122{
6123 clear_user_index();
6124
6125 if (this->has_children())
6126 for (unsigned int c = 0; c < this->n_children(); ++c)
6127 this->child(c)->recursively_clear_user_index();
6128}
6129
6130
6131
6132template <int structdim, int dim, int spacedim>
6133inline unsigned int
6135{
6136 if (!this->has_children())
6137 return 0;
6138
6139 unsigned int max_depth = 1;
6140 for (unsigned int c = 0; c < n_children(); ++c)
6141 max_depth = std::max(max_depth, child(c)->max_refinement_depth() + 1);
6142 return max_depth;
6143}
6144
6145
6146
6147template <int structdim, int dim, int spacedim>
6148unsigned int
6150{
6151 if (!this->has_children())
6152 return 1;
6153 else
6154 {
6155 unsigned int sum = 0;
6156 for (unsigned int c = 0; c < n_children(); ++c)
6157 sum += this->child(c)->n_active_descendants();
6158 return sum;
6159 }
6160}
6161
6162
6163
6164template <int structdim, int dim, int spacedim>
6167{
6168 Assert(structdim < dim, ExcImpossibleInDim(dim));
6170
6171 return this->objects()
6172 .boundary_or_material_id[this->present_index]
6173 .boundary_id;
6174}
6175
6176
6177
6178template <int structdim, int dim, int spacedim>
6179void
6181 const types::boundary_id boundary_ind) const
6182{
6183 Assert(structdim < dim, ExcImpossibleInDim(dim));
6186 ExcMessage("You are trying to set the boundary_id to an invalid "
6187 "value (numbers::internal_face_boundary_id is reserved)."));
6188 Assert(this->at_boundary(),
6189 ExcMessage("You are trying to set the boundary_id of an "
6190 "internal object, which is not allowed!"));
6191
6192 this->objects().boundary_or_material_id[this->present_index].boundary_id =
6193 boundary_ind;
6194}
6195
6196
6197
6198template <int structdim, int dim, int spacedim>
6199void
6201 const types::boundary_id boundary_ind) const
6202{
6203 Assert(structdim < dim, ExcImpossibleInDim(dim));
6205
6206 this->objects().boundary_or_material_id[this->present_index].boundary_id =
6207 boundary_ind;
6208}
6209
6210
6211
6212template <int structdim, int dim, int spacedim>
6213void
6215 const types::boundary_id boundary_ind) const
6216{
6217 set_boundary_id(boundary_ind);
6218
6219 switch (structdim)
6220 {
6221 case 1:
6222 // 1d objects have no sub-objects
6223 // where we have to do anything
6224 break;
6225
6226 case 2:
6227 // for boundary quads also set
6228 // boundary_id of bounding lines
6229 for (unsigned int i = 0; i < this->n_lines(); ++i)
6230 this->line(i)->set_boundary_id(boundary_ind);
6231 break;
6232
6233 default:
6235 }
6236}
6237
6238
6239
6240template <int structdim, int dim, int spacedim>
6241bool
6243{
6244 // error checking is done
6245 // in boundary_id()
6247}
6248
6249
6250
6251template <int structdim, int dim, int spacedim>
6254{
6256 return this->tria->get_manifold(this->manifold_id());
6257}
6258
6259
6260template <int structdim, int dim, int spacedim>
6263{
6265
6266 return this->objects().manifold_id[this->present_index];
6267}
6268
6269
6270
6271template <int structdim, int dim, int spacedim>
6272void
6274 const types::manifold_id manifold_ind) const
6275{
6277
6278 this->objects().manifold_id[this->present_index] = manifold_ind;
6279}
6280
6281
6282template <int structdim, int dim, int spacedim>
6283void
6285 const types::manifold_id manifold_ind) const
6286{
6287 set_manifold_id(manifold_ind);
6288
6289 if (this->has_children())
6290 for (unsigned int c = 0; c < this->n_children(); ++c)
6291 this->child(c)->set_all_manifold_ids(manifold_ind);
6292
6293 switch (structdim)
6294 {
6295 case 1:
6296 if (dim == 1)
6297 {
6298 (*this->tria->vertex_to_manifold_id_map_1d)[vertex_index(0)] =
6299 manifold_ind;
6300 (*this->tria->vertex_to_manifold_id_map_1d)[vertex_index(1)] =
6301 manifold_ind;
6302 }
6303 break;
6304
6305 case 2:
6306 // for quads/simplices also set manifold_id of bounding lines
6307 for (unsigned int i = 0; i < this->n_lines(); ++i)
6308 this->line(i)->set_manifold_id(manifold_ind);
6309 break;
6310 default:
6312 }
6313}
6314
6315
6316
6317template <int structdim, int dim, int spacedim>
6318double
6320{
6321 boost::container::small_vector<Point<spacedim>,
6322# ifndef _MSC_VER
6323 ReferenceCells::max_n_vertices<structdim>()
6324# else
6326# endif
6327 >
6328 vertices(this->n_vertices());
6329
6330 for (unsigned int v = 0; v < vertices.size(); ++v)
6331 vertices[v] = this->vertex(v);
6332
6333 return internal::TriaAccessorImplementation::diameter<structdim, spacedim>(
6334 vertices);
6335}
6336
6337
6338
6339template <int dim, int spacedim>
6340double
6342 const Mapping<dim, spacedim> &mapping) const
6343{
6344 return internal::TriaAccessorImplementation::diameter<dim, spacedim>(
6346 this->tria, this->level(), this->index())));
6347}
6348
6349
6350
6351template <int structdim, int dim, int spacedim>
6352std::pair<Point<spacedim>, double>
6354{
6355 // If the object is one dimensional,
6356 // the enclosing ball is the initial iterate
6357 // i.e., the ball's center and diameter are
6358 // the center and the diameter of the object.
6359 if (structdim == 1)
6360 return std::make_pair((this->vertex(1) + this->vertex(0)) * 0.5,
6361 (this->vertex(1) - this->vertex(0)).norm() * 0.5);
6362
6363 // The list is_initial_guess_vertex contains bool values and has
6364 // the same size as the number of vertices per object.
6365 // The entries of is_initial_guess_vertex are set true only for those
6366 // two vertices corresponding to the largest diagonal which is being used
6367 // to construct the initial ball.
6368 // We employ this mask to skip these two vertices while enlarging the ball.
6369 std::vector<bool> is_initial_guess_vertex(this->n_vertices());
6370
6371 // First let all the vertices be outside
6372 std::fill(is_initial_guess_vertex.begin(),
6373 is_initial_guess_vertex.end(),
6374 false);
6375
6376 // Get an initial guess by looking at the largest diagonal
6377 Point<spacedim> center;
6378 double radius = 0;
6379
6380 switch (structdim)
6381 {
6382 case 2:
6383 {
6384 const Point<spacedim> p30(this->vertex(3) - this->vertex(0));
6385 const Point<spacedim> p21(this->vertex(2) - this->vertex(1));
6386 if (p30.norm() > p21.norm())
6387 {
6388 center = this->vertex(0) + 0.5 * p30;
6389 radius = p30.norm() / 2.;
6390 is_initial_guess_vertex[3] = true;
6391 is_initial_guess_vertex[0] = true;
6392 }
6393 else
6394 {
6395 center = this->vertex(1) + 0.5 * p21;
6396 radius = p21.norm() / 2.;
6397 is_initial_guess_vertex[2] = true;
6398 is_initial_guess_vertex[1] = true;
6399 }
6400 break;
6401 }
6402 case 3:
6403 {
6404 const Point<spacedim> p70(this->vertex(7) - this->vertex(0));
6405 const Point<spacedim> p61(this->vertex(6) - this->vertex(1));
6406 const Point<spacedim> p25(this->vertex(2) - this->vertex(5));
6407 const Point<spacedim> p34(this->vertex(3) - this->vertex(4));
6408 const std::vector<double> diagonals = {p70.norm(),
6409 p61.norm(),
6410 p25.norm(),
6411 p34.norm()};
6412 const std::vector<double>::const_iterator it =
6413 std::max_element(diagonals.begin(), diagonals.end());
6414 if (it == diagonals.begin())
6415 {
6416 center = this->vertex(0) + 0.5 * p70;
6417 is_initial_guess_vertex[7] = true;
6418 is_initial_guess_vertex[0] = true;
6419 }
6420 else if (it == diagonals.begin() + 1)
6421 {
6422 center = this->vertex(1) + 0.5 * p61;
6423 is_initial_guess_vertex[6] = true;
6424 is_initial_guess_vertex[1] = true;
6425 }
6426 else if (it == diagonals.begin() + 2)
6427 {
6428 center = this->vertex(5) + 0.5 * p25;
6429 is_initial_guess_vertex[2] = true;
6430 is_initial_guess_vertex[5] = true;
6431 }
6432 else
6433 {
6434 center = this->vertex(4) + 0.5 * p34;
6435 is_initial_guess_vertex[3] = true;
6436 is_initial_guess_vertex[4] = true;
6437 }
6438 radius = *it * 0.5;
6439 break;
6440 }
6441 default:
6443 return std::pair<Point<spacedim>, double>();
6444 }
6445
6446 // For each vertex that is found to be geometrically outside the ball
6447 // enlarge the ball so that the new ball contains both the previous ball
6448 // and the given vertex.
6449 for (const unsigned int v : this->vertex_indices())
6450 if (!is_initial_guess_vertex[v])
6451 {
6452 const double distance = center.distance(this->vertex(v));
6453 if (distance > radius)
6454 {
6455 // we found a vertex which is outside of the ball
6456 // extend it (move center and change radius)
6457 const Point<spacedim> pCV(center - this->vertex(v));
6458 radius = (distance + radius) * 0.5;
6459 center = this->vertex(v) + pCV * (radius / distance);
6460
6461 // Now the new ball constructed in this block
6462 // encloses the vertex (v) that was found to be geometrically
6463 // outside the old ball.
6464 }
6465 }
6466 if constexpr (running_in_debug_mode())
6467 {
6468 bool all_vertices_within_ball = true;
6469
6470 // Set all_vertices_within_ball false if any of the vertices of the object
6471 // are geometrically outside the ball
6472 for (const unsigned int v : this->vertex_indices())
6473 if (center.distance(this->vertex(v)) >
6474 radius + 100. * std::numeric_limits<double>::epsilon())
6475 {
6476 all_vertices_within_ball = false;
6477 break;
6478 }
6479 // If all the vertices are not within the ball throw error
6480 Assert(all_vertices_within_ball, ExcInternalError());
6481 }
6482 return std::make_pair(center, radius);
6483}
6484
6485
6486template <int structdim, int dim, int spacedim>
6487double
6489{
6490 switch (structdim)
6491 {
6492 case 1:
6493 return (this->vertex(1) - this->vertex(0)).norm();
6494 case 2:
6495 case 3:
6496 {
6497 double min = std::numeric_limits<double>::max();
6498 for (const unsigned int i : this->vertex_indices())
6499 for (unsigned int j = i + 1; j < this->n_vertices(); ++j)
6500 min = std::min(min,
6501 (this->vertex(i) - this->vertex(j)) *
6502 (this->vertex(i) - this->vertex(j)));
6503 return std::sqrt(min);
6504 }
6505 default:
6507 return -1e10;
6508 }
6509}
6510
6511
6512template <int structdim, int dim, int spacedim>
6513bool
6516{
6517 // go through the vertices and check... The
6518 // cell is a translation of the previous
6519 // one in case the distance between the
6520 // individual vertices in the two cell is
6521 // the same for all the vertices. So do the
6522 // check by first getting the distance on
6523 // the first vertex, and then checking
6524 // whether all others have the same down to
6525 // rounding errors (we have to be careful
6526 // here because the calculation of the
6527 // displacement between one cell and the
6528 // next can already result in the loss of
6529 // one or two digits), so we choose 1e-12
6530 // times the distance between the zeroth
6531 // vertices here.
6532 bool is_translation = true;
6533 const Tensor<1, spacedim> dist = o->vertex(0) - this->vertex(0);
6534 const double tol_square = 1e-24 * dist.norm_square();
6535 for (unsigned int i = 1; i < this->n_vertices(); ++i)
6536 {
6537 const Tensor<1, spacedim> dist_new =
6538 (o->vertex(i) - this->vertex(i)) - dist;
6539 if (dist_new.norm_square() > tol_square)
6540 {
6541 is_translation = false;
6542 break;
6543 }
6544 }
6545 return is_translation;
6546}
6547
6548
6549
6550template <int structdim, int dim, int spacedim>
6551unsigned int
6553{
6554 return this->reference_cell().n_vertices();
6555}
6556
6557
6558
6559template <int structdim, int dim, int spacedim>
6560unsigned int
6562{
6563 return this->reference_cell().n_lines();
6564}
6565
6566
6567
6568template <int structdim, int dim, int spacedim>
6569unsigned int
6571{
6572 Assert(structdim == dim,
6573 ExcMessage("This function can only be used on objects "
6574 "that are cells, but not on faces or edges "
6575 "that bound cells."));
6576
6577 return this->reference_cell().n_faces();
6578}
6579
6580
6581
6582template <int structdim, int dim, int spacedim>
6585{
6587 n_vertices());
6588}
6589
6590
6591
6592template <int structdim, int dim, int spacedim>
6595{
6597 n_lines());
6598}
6599
6600
6601
6602template <int structdim, int dim, int spacedim>
6605{
6607 n_faces());
6608}
6609
6610
6611
6612/*----------------- Functions: TriaAccessor<0,dim,spacedim> -----------------*/
6613
6614template <int dim, int spacedim>
6616 const Triangulation<dim, spacedim> *tria,
6617 const unsigned int vertex_index)
6618 : tria(tria)
6619 , global_vertex_index(vertex_index)
6620{}
6621
6622
6623
6624template <int dim, int spacedim>
6626 const Triangulation<dim, spacedim> *tria,
6627 const int /*level*/,
6628 const int index,
6629 const AccessorData *)
6630 : tria(tria)
6632{}
6633
6634
6635
6636template <int dim, int spacedim>
6637template <int structdim2, int dim2, int spacedim2>
6640 : tria(nullptr)
6642{
6643 Assert(false, ExcImpossibleInDim(0));
6644}
6645
6646
6647
6648template <int dim, int spacedim>
6649template <int structdim2, int dim2, int spacedim2>
6652 : tria(nullptr)
6654{
6655 Assert(false, ExcImpossibleInDim(0));
6656}
6657
6658
6659
6660template <int dim, int spacedim>
6661inline void
6663{
6664 tria = t.tria;
6665 global_vertex_index = t.global_vertex_index;
6666}
6667
6668
6669
6670template <int dim, int spacedim>
6671inline bool
6673 const TriaAccessor<0, dim, spacedim> &other) const
6674{
6676
6677 return (global_vertex_index < other.global_vertex_index);
6678}
6679
6680
6681
6682template <int dim, int spacedim>
6685{
6686 if (global_vertex_index != numbers::invalid_unsigned_int)
6687 return IteratorState::valid;
6688 else
6690}
6691
6692
6693
6694template <int dim, int spacedim>
6695inline int
6697{
6698 return 0;
6699}
6700
6701
6702
6703template <int dim, int spacedim>
6704inline int
6706{
6707 return global_vertex_index;
6708}
6709
6710
6711
6712template <int dim, int spacedim>
6713inline const Triangulation<dim, spacedim> &
6715{
6716 return *tria;
6717}
6718
6719
6720
6721template <int dim, int spacedim>
6722inline void
6724{
6726 if (global_vertex_index >= tria->n_vertices())
6728}
6729
6730
6731
6732template <int dim, int spacedim>
6733inline void
6735{
6736 if (global_vertex_index != numbers::invalid_unsigned_int)
6737 {
6738 if (global_vertex_index != 0)
6740 else
6742 }
6743}
6744
6745
6746
6747template <int dim, int spacedim>
6748inline bool
6750{
6751 const bool result =
6752 ((tria == t.tria) && (global_vertex_index == t.global_vertex_index));
6753
6754 return result;
6755}
6756
6757
6758
6759template <int dim, int spacedim>
6760inline bool
6762{
6763 return !(*this == t);
6764}
6765
6766
6767
6768template <int dim, int spacedim>
6769inline unsigned int
6770TriaAccessor<0, dim, spacedim>::vertex_index(const unsigned int) const
6771{
6772 return global_vertex_index;
6773}
6774
6775
6776
6777template <int dim, int spacedim>
6778inline Point<spacedim> &
6779TriaAccessor<0, dim, spacedim>::vertex(const unsigned int) const
6780{
6781 return const_cast<Point<spacedim> &>(
6782 this->tria->vertices[global_vertex_index]);
6783}
6784
6785
6786
6787template <int dim, int spacedim>
6788inline typename ::internal::TriangulationImplementation::
6789 Iterators<dim, spacedim>::line_iterator
6790 TriaAccessor<0, dim, spacedim>::line(const unsigned int)
6791{
6792 return typename ::internal::TriangulationImplementation::
6793 Iterators<dim, spacedim>::line_iterator();
6794}
6795
6796
6797
6798template <int dim, int spacedim>
6799inline unsigned int
6801{
6802 Assert(false, ExcImpossibleInDim(0));
6804}
6805
6806
6807
6808template <int dim, int spacedim>
6809inline typename ::internal::TriangulationImplementation::
6810 Iterators<dim, spacedim>::quad_iterator
6811 TriaAccessor<0, dim, spacedim>::quad(const unsigned int)
6812{
6813 return typename ::internal::TriangulationImplementation::
6814 Iterators<dim, spacedim>::quad_iterator();
6815}
6816
6817
6818
6819template <int dim, int spacedim>
6820inline unsigned int
6822{
6823 Assert(false, ExcImpossibleInDim(0));
6825}
6826
6827
6828
6829template <int dim, int spacedim>
6830inline double
6832{
6833 return 0.;
6834}
6835
6836
6837
6838template <int dim, int spacedim>
6839inline double
6841{
6842 return 0.;
6843}
6844
6845
6846
6847template <int dim, int spacedim>
6848inline Point<spacedim>
6849TriaAccessor<0, dim, spacedim>::center(const bool, const bool) const
6850{
6851 return this->tria->vertices[global_vertex_index];
6852}
6853
6854
6855
6856template <int dim, int spacedim>
6857inline double
6859{
6860 return 0.;
6861}
6862
6863
6864
6865template <int dim, int spacedim>
6868 const unsigned int /*face*/)
6869{
6871}
6872
6873
6874
6875template <int dim, int spacedim>
6876inline bool
6877TriaAccessor<0, dim, spacedim>::face_orientation(const unsigned int /*face*/)
6878{
6879 return false;
6880}
6881
6882
6883
6884template <int dim, int spacedim>
6885inline bool
6886TriaAccessor<0, dim, spacedim>::face_flip(const unsigned int /*face*/)
6887{
6888 return false;
6889}
6890
6891
6892
6893template <int dim, int spacedim>
6894inline bool
6895TriaAccessor<0, dim, spacedim>::face_rotation(const unsigned int /*face*/)
6896{
6897 return false;
6898}
6899
6900
6901
6902template <int dim, int spacedim>
6904TriaAccessor<0, dim, spacedim>::line_orientation(const unsigned int /*line*/)
6905{
6907}
6908
6909
6910
6911template <int dim, int spacedim>
6912inline bool
6914{
6915 return false;
6916}
6917
6918
6919
6920template <int dim, int spacedim>
6921inline unsigned int
6923{
6924 return 0;
6925}
6926
6927
6928
6929template <int dim, int spacedim>
6930inline unsigned int
6932{
6933 return 0;
6934}
6935
6936
6937
6938template <int dim, int spacedim>
6939inline unsigned int
6941{
6942 return 0;
6943}
6944
6945
6946
6947template <int dim, int spacedim>
6948inline unsigned int
6951{
6953}
6954
6955
6956
6957template <int dim, int spacedim>
6959TriaAccessor<0, dim, spacedim>::child(const unsigned int)
6960{
6962}
6963
6964
6965
6966template <int dim, int spacedim>
6969{
6971}
6972
6973
6974
6975template <int dim, int spacedim>
6976inline RefinementCase<0>
6978{
6980}
6981
6982
6983
6984template <int dim, int spacedim>
6985inline int
6987{
6988 return -1;
6989}
6990
6991
6992
6993template <int dim, int spacedim>
6994inline int
6996{
6997 return -1;
6998}
6999
7000
7001
7002template <int dim, int spacedim>
7003inline bool
7005{
7006 return tria->vertex_used(global_vertex_index);
7007}
7008
7009
7010
7011/*------------------- Functions: TriaAccessor<0,1,spacedim> -----------------*/
7012
7013template <int spacedim>
7015 const Triangulation<1, spacedim> *tria,
7016 const VertexKind vertex_kind,
7017 const unsigned int vertex_index)
7018 : tria(tria)
7019 , vertex_kind(vertex_kind)
7020 , global_vertex_index(vertex_index)
7021{}
7022
7023
7024
7025template <int spacedim>
7027 const Triangulation<1, spacedim> *tria,
7028 const int level,
7029 const int index,
7030 const AccessorData *)
7031 : tria(tria)
7032 , vertex_kind(interior_vertex)
7034{
7035 // in general, calling this constructor should yield an error -- users should
7036 // instead call the one immediately above. however, if you create something
7037 // like Triangulation<1>::face_iterator() then this calls the default
7038 // constructor of the iterator which calls the accessor with argument list
7039 // (0,-2,-2,0), so in this particular case accept this call and create an
7040 // object that corresponds to the default constructed (invalid) vertex
7041 // accessor
7042 (void)level;
7043 (void)index;
7044 Assert((level == -2) && (index == -2),
7045 ExcMessage(
7046 "This constructor can not be called for face iterators in 1d, "
7047 "except to default-construct iterator objects."));
7048}
7049
7050
7051
7052template <int spacedim>
7053template <int structdim2, int dim2, int spacedim2>
7056 : tria(nullptr)
7057 , vertex_kind(interior_vertex)
7059{
7060 Assert(false, ExcImpossibleInDim(0));
7061}
7062
7063
7064
7065template <int spacedim>
7066template <int structdim2, int dim2, int spacedim2>
7069 : tria(nullptr)
7070 , vertex_kind(interior_vertex)
7072{
7073 Assert(false, ExcImpossibleInDim(0));
7074}
7075
7076
7077
7078template <int spacedim>
7079inline void
7081{
7082 tria = t.tria;
7083 vertex_kind = t.vertex_kind;
7084 global_vertex_index = t.global_vertex_index;
7085}
7086
7087
7088
7089template <int spacedim>
7090inline void
7093{
7094 // We cannot convert from TriaAccessorBase to
7095 // TriaAccessor<0,1,spacedim> because the latter is not derived from
7096 // the former. We should never get here.
7098}
7099
7100
7101
7102template <int spacedim>
7103inline bool
7105 const TriaAccessor<0, 1, spacedim> &other) const
7106{
7108
7109 return (global_vertex_index < other.global_vertex_index);
7110}
7111
7112
7113
7114template <int spacedim>
7117{
7118 return IteratorState::valid;
7119}
7120
7121
7122template <int spacedim>
7123inline int
7125{
7126 return 0;
7127}
7128
7129
7130
7131template <int spacedim>
7132inline int
7134{
7135 return global_vertex_index;
7136}
7137
7138
7139
7140template <int spacedim>
7141inline const Triangulation<1, spacedim> &
7143{
7144 return *tria;
7145}
7146
7147
7148
7149template <int spacedim>
7150inline void
7152{
7154}
7155
7156
7157template <int spacedim>
7158inline void
7160{
7162}
7163
7164
7165
7166template <int spacedim>
7167inline bool
7169{
7170 const bool result =
7171 ((tria == t.tria) && (global_vertex_index == t.global_vertex_index));
7172 // if we point to the same vertex,
7173 // make sure we know the same about
7174 // it
7175 if (result == true)
7176 Assert(vertex_kind == t.vertex_kind, ExcInternalError());
7177
7178 return result;
7179}
7180
7181
7182
7183template <int spacedim>
7184inline bool
7186{
7187 return !(*this == t);
7188}
7189
7190
7191
7192template <int spacedim>
7193inline unsigned int
7194TriaAccessor<0, 1, spacedim>::vertex_index(const unsigned int i) const
7195{
7196 AssertIndexRange(i, 1);
7197 (void)i;
7198 return global_vertex_index;
7199}
7200
7201
7202
7203template <int spacedim>
7204inline Point<spacedim> &
7205TriaAccessor<0, 1, spacedim>::vertex(const unsigned int i) const
7206{
7207 AssertIndexRange(i, 1);
7208 (void)i;
7209 return const_cast<Point<spacedim> &>(
7210 this->tria->vertices[global_vertex_index]);
7211}
7212
7213
7214
7215template <int spacedim>
7216inline Point<spacedim>
7218{
7219 return this->tria->vertices[global_vertex_index];
7220}
7221
7222
7223
7224template <int spacedim>
7225inline typename ::internal::TriangulationImplementation::
7226 Iterators<1, spacedim>::line_iterator
7227 TriaAccessor<0, 1, spacedim>::line(const unsigned int)
7228{
7229 return {};
7230}
7231
7232
7233template <int spacedim>
7234inline unsigned int
7236{
7237 Assert(false, ExcImpossibleInDim(0));
7239}
7240
7241
7242template <int spacedim>
7243inline typename ::internal::TriangulationImplementation::
7244 Iterators<1, spacedim>::quad_iterator
7245 TriaAccessor<0, 1, spacedim>::quad(const unsigned int)
7246{
7247 return {};
7248}
7249
7250
7251
7252template <int spacedim>
7253inline unsigned int
7255{
7256 Assert(false, ExcImpossibleInDim(0));
7258}
7259
7260
7261template <int spacedim>
7262inline bool
7264{
7265 return vertex_kind != interior_vertex;
7266}
7267
7268
7269template <int spacedim>
7270inline types::boundary_id
7272{
7273 switch (vertex_kind)
7274 {
7275 case left_vertex:
7276 case right_vertex:
7277 {
7279 this->vertex_index()) !=
7280 tria->vertex_to_boundary_id_map_1d->end(),
7282
7283 return (*tria->vertex_to_boundary_id_map_1d)[this->vertex_index()];
7284 }
7285
7286 default:
7288 }
7289}
7290
7291
7292
7293template <int spacedim>
7294inline const Manifold<1, spacedim> &
7296{
7297 return this->tria->get_manifold(this->manifold_id());
7298}
7299
7300
7301
7302template <int spacedim>
7303inline types::manifold_id
7305{
7306 if (tria->vertex_to_manifold_id_map_1d->find(this->vertex_index()) !=
7307 tria->vertex_to_manifold_id_map_1d->end())
7308 return (*tria->vertex_to_manifold_id_map_1d)[this->vertex_index()];
7309 else
7311}
7312
7313
7314template <int spacedim>
7317 const unsigned int /*face*/)
7318{
7320}
7321
7322
7323template <int spacedim>
7324inline bool
7325TriaAccessor<0, 1, spacedim>::face_orientation(const unsigned int /*face*/)
7326{
7327 return false;
7328}
7329
7330
7331
7332template <int spacedim>
7333inline bool
7334TriaAccessor<0, 1, spacedim>::face_flip(const unsigned int /*face*/)
7335{
7336 return false;
7337}
7338
7339
7340
7341template <int spacedim>
7342inline bool
7343TriaAccessor<0, 1, spacedim>::face_rotation(const unsigned int /*face*/)
7344{
7345 return false;
7346}
7347
7348
7349
7350template <int spacedim>
7352TriaAccessor<0, 1, spacedim>::line_orientation(const unsigned int /*line*/)
7353{
7355}
7356
7357
7358
7359template <int spacedim>
7360inline bool
7362{
7363 return false;
7364}
7365
7366
7367
7368template <int spacedim>
7369inline unsigned int
7371{
7372 return 0;
7373}
7374
7375
7376
7377template <int spacedim>
7378inline unsigned int
7380{
7381 return 0;
7382}
7383
7384
7385
7386template <int spacedim>
7387inline unsigned int
7389{
7390 return 0;
7391}
7392
7393
7394
7395template <int spacedim>
7396inline unsigned int
7399{
7401}
7402
7403
7404
7405template <int spacedim>
7407TriaAccessor<0, 1, spacedim>::child(const unsigned int)
7408{
7410}
7411
7412
7413template <int spacedim>
7416{
7418}
7419
7420
7421template <int spacedim>
7422inline RefinementCase<0>
7424{
7426}
7427
7428template <int spacedim>
7429inline int
7431{
7432 return -1;
7433}
7434
7435
7436template <int spacedim>
7437inline int
7439{
7440 return -1;
7441}
7442
7443
7444
7445template <int spacedim>
7446inline void
7448{
7449 Assert(tria->vertex_to_boundary_id_map_1d->find(this->vertex_index()) !=
7450 tria->vertex_to_boundary_id_map_1d->end(),
7451 ExcMessage("You can't set the boundary_id of a face of a cell that is "
7452 "not actually at the boundary."));
7453
7454 (*tria->vertex_to_boundary_id_map_1d)[this->vertex_index()] = b;
7455}
7456
7457
7458
7459template <int spacedim>
7460inline void
7462{
7463 (*tria->vertex_to_manifold_id_map_1d)[this->vertex_index()] = b;
7464}
7465
7466
7467
7468template <int spacedim>
7469inline void
7471 const types::boundary_id b) const
7472{
7473 set_boundary_id(b);
7474}
7475
7476
7477
7478template <int spacedim>
7479inline void
7481{
7482 set_manifold_id(b);
7483}
7484
7485
7486
7487template <int spacedim>
7488inline bool
7490{
7491 return tria->vertex_used(global_vertex_index);
7492}
7493
7494
7495
7496template <int spacedim>
7497inline ReferenceCell
7499{
7501}
7502
7503
7504
7505template <int spacedim>
7506unsigned int
7508{
7509 return 1;
7510}
7511
7512
7513
7514template <int spacedim>
7515unsigned int
7517{
7518 return 0;
7519}
7520
7521
7522
7523template <int spacedim>
7526{
7528 n_vertices());
7529}
7530
7531
7532
7533template <int spacedim>
7536{
7538 n_lines());
7539}
7540
7541/*------------------ Functions: CellAccessor<dim,spacedim> ------------------*/
7542
7543
7544template <int dim, int spacedim>
7546 const Triangulation<dim, spacedim> *parent,
7547 const int level,
7548 const int index,
7549 const AccessorData *local_data)
7550 : TriaAccessor<dim, dim, spacedim>(parent, level, index, local_data)
7551{}
7552
7553
7554
7555template <int dim, int spacedim>
7557 const TriaAccessor<dim, dim, spacedim> &cell_accessor)
7558 : TriaAccessor<dim, dim, spacedim>(
7559 static_cast<const TriaAccessor<dim, dim, spacedim> &>(cell_accessor))
7560{}
7561
7562
7563
7564template <int dim, int spacedim>
7566CellAccessor<dim, spacedim>::child(const unsigned int i) const
7567{
7569 this->present_level + 1,
7570 this->child_index(i));
7571
7572 Assert((q.state() == IteratorState::past_the_end) || q->used(),
7574
7575 return q;
7576}
7577
7578
7579
7580template <int dim, int spacedim>
7581inline boost::container::small_vector<TriaIterator<CellAccessor<dim, spacedim>>,
7584{
7585 boost::container::small_vector<TriaIterator<CellAccessor<dim, spacedim>>,
7587 child_iterators(this->n_children());
7588
7589 for (unsigned int i = 0; i < this->n_children(); ++i)
7590 child_iterators[i] = this->child(i);
7591
7592 return child_iterators;
7593}
7594
7595
7596
7597template <int dim, int spacedim>
7598inline TriaIterator<TriaAccessor<dim - 1, dim, spacedim>>
7599CellAccessor<dim, spacedim>::face(const unsigned int i) const
7600{
7601 AssertIndexRange(i, this->n_faces());
7602 if constexpr (dim == 1)
7603 {
7604 using VertexKind = typename TriaAccessor<0, 1, spacedim>::VertexKind;
7605 VertexKind vertex_kind = VertexKind::interior_vertex;
7606 if (i == 0 && at_boundary(0))
7607 vertex_kind = VertexKind::left_vertex;
7608 if (i == 1 && at_boundary(1))
7609 vertex_kind = VertexKind::right_vertex;
7610 TriaAccessor<0, 1, spacedim> a(&this->get_triangulation(),
7611 vertex_kind,
7612 this->vertex_index(i));
7614 }
7615 else if constexpr (dim == 2)
7616 return this->line(i);
7617 else if constexpr (dim == 3)
7618 return this->quad(i);
7619 else
7620 {
7621 Assert(false, ExcNotImplemented());
7622 return {};
7623 }
7624}
7625
7626
7627
7628template <int dim, int spacedim>
7629inline unsigned int
7632{
7633 for (const unsigned int face_n : this->face_indices())
7634 if (this->face(face_n) == face)
7635 return face_n;
7636
7637 Assert(false,
7638 ExcMessage("The given face is not a face of the current cell."));
7640}
7641
7642
7643
7644template <int dim, int spacedim>
7645inline boost::container::small_vector<
7646 TriaIterator<TriaAccessor<dim - 1, dim, spacedim>>,
7647# ifndef _MSC_VER
7648 ReferenceCells::max_n_faces<dim>()
7649# else
7651# endif
7652 >
7654{
7655 boost::container::small_vector<
7656 TriaIterator<TriaAccessor<dim - 1, dim, spacedim>>,
7657# ifndef _MSC_VER
7658 ReferenceCells::max_n_faces<dim>()
7659# else
7661# endif
7662 >
7663 face_iterators(this->n_faces());
7664
7665 for (const unsigned int i : this->face_indices())
7666 face_iterators[i] = this->face(i);
7667
7668 return face_iterators;
7669}
7670
7671
7672
7673template <int dim, int spacedim>
7674inline unsigned int
7675CellAccessor<dim, spacedim>::face_index(const unsigned int i) const
7676{
7677 switch (dim)
7678 {
7679 case 1:
7680 return this->vertex_index(i);
7681
7682 case 2:
7683 return this->line_index(i);
7684
7685 case 3:
7686 return this->quad_index(i);
7687
7688 default:
7690 }
7691}
7692
7693
7694
7695template <int dim, int spacedim>
7696inline int
7697CellAccessor<dim, spacedim>::neighbor_index(const unsigned int face_no) const
7698{
7699 AssertIndexRange(face_no, this->n_faces());
7700 return this->tria->levels[this->present_level]
7701 ->neighbors[this->present_index * ReferenceCells::max_n_faces<dim>() +
7702 face_no]
7703 .second;
7704}
7705
7706
7707
7708template <int dim, int spacedim>
7709inline int
7710CellAccessor<dim, spacedim>::neighbor_level(const unsigned int face_no) const
7711{
7712 AssertIndexRange(face_no, this->n_faces());
7713 return this->tria->levels[this->present_level]
7714 ->neighbors[this->present_index * ReferenceCells::max_n_faces<dim>() +
7715 face_no]
7716 .first;
7717}
7718
7719
7720
7721template <int dim, int spacedim>
7724{
7726 // cells flagged for refinement must be active
7727 // (the @p set_refine_flag function checks this,
7728 // but activity may change when refinement is
7729 // executed and for some reason the refine
7730 // flag is not cleared).
7731 Assert(this->is_active() || !this->tria->levels[this->present_level]
7732 ->refine_flags[this->present_index],
7733 ExcRefineCellNotActive());
7734 return RefinementCase<dim>(
7735 this->tria->levels[this->present_level]->refine_flags[this->present_index]);
7736}
7737
7738
7739
7740template <int dim, int spacedim>
7741inline void
7743 const RefinementCase<dim> refinement_case) const
7744{
7745 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
7746 Assert(!coarsen_flag_set(), ExcCellFlaggedForCoarsening());
7747
7748 this->tria->levels[this->present_level]->refine_flags[this->present_index] =
7749 refinement_case;
7750}
7751
7752
7753
7754template <int dim, int spacedim>
7755inline void
7757{
7758 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
7759 this->tria->levels[this->present_level]->refine_flags[this->present_index] =
7761}
7762
7763
7764template <int dim, int spacedim>
7765inline std::uint8_t
7767{
7769 if (this->tria->levels[this->present_level]->refine_choice.size() == 0)
7770 return 0U;
7771 return this->tria->levels[this->present_level]
7772 ->refine_choice[this->present_index];
7773}
7774
7775
7776template <int dim, int spacedim>
7777inline void
7779 const std::uint8_t refinement_choice) const
7780{
7781 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
7782 if (this->tria->levels[this->present_level]->refine_choice.size() != 0)
7783 this->tria->levels[this->present_level]
7784 ->refine_choice[this->present_index] = refinement_choice;
7785}
7786
7787
7788template <int dim, int spacedim>
7789inline void
7791{
7792 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
7793 if (this->tria->levels[this->present_level]->refine_choice.size() != 0)
7794 this->tria->levels[this->present_level]
7795 ->refine_choice[this->present_index] =
7797}
7798
7799
7800template <int dim, int spacedim>
7801inline bool
7803 const unsigned int face_no,
7804 const RefinementCase<dim - 1> &face_refinement_case) const
7805{
7806 Assert(dim > 1, ExcImpossibleInDim(dim));
7807 AssertIndexRange(face_no, this->n_faces());
7808 AssertIndexRange(face_refinement_case,
7810
7811 // the new refinement case is a combination
7812 // of the minimum required one for the given
7813 // face refinement and the already existing
7814 // flagged refinement case
7815 RefinementCase<dim> old_ref_case = refine_flag_set();
7816 RefinementCase<dim> new_ref_case =
7817 (old_ref_case |
7819 face_refinement_case,
7820 face_no,
7821 this->face_orientation(face_no),
7822 this->face_flip(face_no),
7823 this->face_rotation(face_no)));
7824 set_refine_flag(new_ref_case);
7825 // return, whether we had to change the
7826 // refinement flag
7827 return new_ref_case != old_ref_case;
7828}
7829
7830
7831
7832template <int dim, int spacedim>
7833inline bool
7835 const unsigned int line_no) const
7836{
7837 Assert(dim > 1, ExcImpossibleInDim(dim));
7838 AssertIndexRange(line_no, this->n_lines());
7839
7840 // the new refinement case is a combination
7841 // of the minimum required one for the given
7842 // line refinement and the already existing
7843 // flagged refinement case
7845 old_ref_case = refine_flag_set(),
7846 new_ref_case =
7847 old_ref_case |
7849 set_refine_flag(new_ref_case);
7850 // return, whether we had to change the
7851 // refinement flag
7852 return new_ref_case != old_ref_case;
7853}
7854
7855
7856
7857template <int dim, int spacedim>
7858inline ::internal::SubfaceCase<dim>
7859CellAccessor<dim, spacedim>::subface_case(const unsigned int face_no) const
7860{
7862 AssertIndexRange(face_no, this->n_faces());
7863
7864 if constexpr (dim == 1)
7865 return ::internal::SubfaceCase<1>::case_none;
7866 else if constexpr (dim == 2)
7867 return ((face(face_no)->has_children()) ?
7869 ::internal::SubfaceCase<2>::case_none);
7870 else if constexpr (dim == 3)
7871 {
7872 switch (static_cast<std::uint8_t>(face(face_no)->refinement_case()))
7873 {
7875 return ::internal::SubfaceCase<3>::case_none;
7877 if (face(face_no)->child(0)->has_children())
7878 {
7879 Assert(face(face_no)->child(0)->refinement_case() ==
7882 if (face(face_no)->child(1)->has_children())
7883 {
7884 Assert(face(face_no)->child(1)->refinement_case() ==
7887 return ::internal::SubfaceCase<3>::case_x1y2y;
7888 }
7889 else
7890 return ::internal::SubfaceCase<3>::case_x1y;
7891 }
7892 else
7893 {
7894 if (face(face_no)->child(1)->has_children())
7895 {
7896 Assert(face(face_no)->child(1)->refinement_case() ==
7899 return ::internal::SubfaceCase<3>::case_x2y;
7900 }
7901 else
7902 return ::internal::SubfaceCase<3>::case_x;
7903 }
7905 if (face(face_no)->child(0)->has_children())
7906 {
7907 Assert(face(face_no)->child(0)->refinement_case() ==
7910 if (face(face_no)->child(1)->has_children())
7911 {
7912 Assert(face(face_no)->child(1)->refinement_case() ==
7915 return ::internal::SubfaceCase<3>::case_y1x2x;
7916 }
7917 else
7918 return ::internal::SubfaceCase<3>::case_y1x;
7919 }
7920 else
7921 {
7922 if (face(face_no)->child(1)->has_children())
7923 {
7924 Assert(face(face_no)->child(1)->refinement_case() ==
7927 return ::internal::SubfaceCase<3>::case_y2x;
7928 }
7929 else
7930 return ::internal::SubfaceCase<3>::case_y;
7931 }
7933 return ::internal::SubfaceCase<3>::case_xy;
7934 default:
7936 }
7937 }
7938
7939 // we should never get here
7941 return ::internal::SubfaceCase<dim>::case_none;
7942}
7943
7944
7945
7946template <int dim, int spacedim>
7947inline bool
7949{
7951 // cells flagged for coarsening must be active
7952 // (the @p set_refine_flag function checks this,
7953 // but activity may change when refinement is
7954 // executed and for some reason the refine
7955 // flag is not cleared).
7956 Assert(this->is_active() || !this->tria->levels[this->present_level]
7957 ->coarsen_flags[this->present_index],
7958 ExcRefineCellNotActive());
7959 return this->tria->levels[this->present_level]
7960 ->coarsen_flags[this->present_index];
7961}
7962
7963
7964
7965template <int dim, int spacedim>
7966inline void
7968{
7969 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
7970 Assert(!refine_flag_set(), ExcCellFlaggedForRefinement());
7971
7972 this->tria->levels[this->present_level]->coarsen_flags[this->present_index] =
7973 true;
7974}
7975
7976
7977
7978template <int dim, int spacedim>
7979inline void
7981{
7982 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
7983 this->tria->levels[this->present_level]->coarsen_flags[this->present_index] =
7984 false;
7985}
7986
7987
7988
7989template <int dim, int spacedim>
7991CellAccessor<dim, spacedim>::neighbor(const unsigned int face_no) const
7992{
7994 neighbor_level(face_no),
7995 neighbor_index(face_no));
7996
7997 Assert((q.state() == IteratorState::past_the_end) || q->used(),
7999
8000 return q;
8001}
8002
8003
8004
8005template <int dim, int spacedim>
8006inline bool
8008{
8009 return !this->has_children();
8010}
8011
8012
8013
8014template <int dim, int spacedim>
8015inline bool
8017{
8018 Assert(this->is_active(),
8019 ExcMessage("is_locally_owned() can only be called on active cells!"));
8020# ifndef DEAL_II_WITH_MPI
8021 return true;
8022# else
8023
8024 // Serial triangulations report invalid_subdomain_id as their locally owned
8025 // subdomain, so the first condition checks whether we have a serial
8026 // triangulation, in which case all cells are locally owned. The second
8027 // condition compares the subdomain id in the parallel case.
8028 const types::subdomain_id locally_owned_subdomain =
8029 this->tria->locally_owned_subdomain();
8030 return (locally_owned_subdomain == numbers::invalid_subdomain_id ||
8031 this->subdomain_id() == locally_owned_subdomain);
8032
8033# endif
8034}
8035
8036
8037template <int dim, int spacedim>
8038inline bool
8040{
8041# ifndef DEAL_II_WITH_MPI
8042 return true;
8043# else
8044
8045 // Serial triangulations report invalid_subdomain_id as their locally owned
8046 // subdomain, so the first condition checks whether we have a serial
8047 // triangulation, in which case all cells are locally owned. The second
8048 // condition compares the subdomain id in the parallel case.
8049 const types::subdomain_id locally_owned_subdomain =
8050 this->tria->locally_owned_subdomain();
8051 return (locally_owned_subdomain == numbers::invalid_subdomain_id ||
8052 this->level_subdomain_id() == locally_owned_subdomain);
8053
8054# endif
8055}
8056
8057
8058template <int dim, int spacedim>
8059inline bool
8061{
8062 Assert(this->is_active(),
8063 ExcMessage("is_ghost() can only be called on active cells!"));
8064 if (this->has_children())
8065 return false;
8066
8067# ifndef DEAL_II_WITH_MPI
8068 return false;
8069# else
8070
8071 // Serial triangulations report invalid_subdomain_id as their locally owned
8072 // subdomain, so the first condition rules out that case as all cells to a
8073 // serial triangulation are locally owned and none is ghosted. The second
8074 // and third conditions check whether the cell's subdomain is not the
8075 // locally owned one and not artificial.
8076 const types::subdomain_id locally_owned_subdomain =
8077 this->tria->locally_owned_subdomain();
8078 const types::subdomain_id subdomain_id = this->subdomain_id();
8079 return (locally_owned_subdomain != numbers::invalid_subdomain_id &&
8080 subdomain_id != locally_owned_subdomain &&
8081 subdomain_id != numbers::artificial_subdomain_id);
8082
8083# endif
8084}
8085
8086
8087template <int dim, int spacedim>
8088inline bool
8090{
8091# ifndef DEAL_II_WITH_MPI
8092 return false;
8093# else
8094
8095 // Serial triangulations report invalid_subdomain_id as their locally owned
8096 // subdomain, so the first condition checks whether we have a serial
8097 // triangulation, in which case all cells are locally owned. The second
8098 // condition compares the subdomain id in the parallel case.
8099 const types::subdomain_id locally_owned_subdomain =
8100 this->tria->locally_owned_subdomain();
8101 const types::subdomain_id subdomain_id = this->level_subdomain_id();
8102 return (locally_owned_subdomain != numbers::invalid_subdomain_id &&
8103 subdomain_id != locally_owned_subdomain &&
8104 subdomain_id != numbers::artificial_subdomain_id);
8105
8106# endif
8107}
8108
8109
8110
8111template <int dim, int spacedim>
8112inline bool
8114{
8115 Assert(this->is_active(),
8116 ExcMessage("is_artificial() can only be called on active cells!"));
8117# ifndef DEAL_II_WITH_MPI
8118 return false;
8119# else
8120
8121 // Serial triangulations report invalid_subdomain_id as their locally owned
8122 // subdomain, so the first condition rules out that case as all cells to a
8123 // serial triangulation are locally owned and none is artificial.
8124 return (this->tria->locally_owned_subdomain() !=
8126 this->subdomain_id() == numbers::artificial_subdomain_id);
8127
8128# endif
8129}
8130
8131
8132
8133template <int dim, int spacedim>
8134inline bool
8136{
8137# ifndef DEAL_II_WITH_MPI
8138 return false;
8139# else
8140 return (this->tria->locally_owned_subdomain() !=
8142 this->level_subdomain_id() == numbers::artificial_subdomain_id);
8143# endif
8144}
8145
8146
8147
8148template <int dim, int spacedim>
8151{
8153 Assert(this->is_active(),
8154 ExcMessage("subdomain_id() can only be called on active cells!"));
8155 return this->tria->levels[this->present_level]
8156 ->subdomain_ids[this->present_index];
8157}
8158
8159
8160
8161template <int dim, int spacedim>
8164{
8166 return this->tria->levels[this->present_level]
8167 ->level_subdomain_ids[this->present_index];
8168}
8169
8170
8171
8172template <int dim, int spacedim>
8173inline unsigned int
8174CellAccessor<dim, spacedim>::neighbor_face_no(const unsigned int neighbor) const
8175{
8176 const unsigned int n2 = neighbor_of_neighbor_internal(neighbor);
8178 // return this value as the
8179 // neighbor is not coarser
8180 return n2;
8181 else
8182 // the neighbor is coarser
8183 return neighbor_of_coarser_neighbor(neighbor).first;
8184}
8185
8186
8187
8188template <int dim, int spacedim>
8189inline bool
8191{
8192 return false;
8193}
8194
8195
8196
8197template <int dim, int spacedim>
8198inline unsigned int
8200{
8202 return this->tria->levels[this->present_level]
8203 ->active_cell_indices[this->present_index];
8204}
8205
8206
8207
8208template <int dim, int spacedim>
8211{
8213 Assert(this->is_active(),
8214 ExcMessage(
8215 "global_active_cell_index() can only be called on active cells!"));
8216
8217 return this->tria->levels[this->present_level]
8218 ->global_active_cell_indices[this->present_index];
8219}
8220
8221
8222
8223template <int dim, int spacedim>
8226{
8227 return this->tria->levels[this->present_level]
8228 ->global_level_cell_indices[this->present_index];
8229}
8230
8231#endif // DOXYGEN
8232
8234
8235
8236#endif
void recursively_set_subdomain_id(const types::subdomain_id new_subdomain_id) const
CellAccessor(const Triangulation< dim, spacedim > *parent=nullptr, const int level=-1, const int index=-1, const AccessorData *local_data=nullptr)
TriaIterator< CellAccessor< dim, spacedim > > parent() const
unsigned int neighbor_face_no(const unsigned int neighbor) const
void set_active_cell_index(const unsigned int active_cell_index) const
unsigned int neighbor_of_neighbor_internal(const unsigned int neighbor) const
TriaIterator< CellAccessor< dim, spacedim > > periodic_neighbor(const unsigned int i) const
types::global_cell_index global_active_cell_index() const
void set_neighbor(const unsigned int i, const TriaIterator< CellAccessor< dim, spacedim > > &pointer) const
TriaIterator< CellAccessor< dim, spacedim > > neighbor(const unsigned int face_no) const
boost::container::small_vector< TriaIterator< TriaAccessor< dim - 1, dim, spacedim > >, ReferenceCells::max_n_faces< dim >() > face_iterators() const
bool is_artificial_on_level() const
void set_direction_flag(const bool new_direction_flag) const
void recursively_set_material_id(const types::material_id new_material_id) const
void set_level_subdomain_id(const types::subdomain_id new_level_subdomain_id) const
types::subdomain_id level_subdomain_id() const
std::uint8_t refine_choice() const
RefinementCase< dim > refine_flag_set() const
bool flag_for_face_refinement(const unsigned int face_no, const RefinementCase< dim - 1 > &face_refinement_case=RefinementCase< dim - 1 >::isotropic_refinement) const
unsigned int face_index(const unsigned int i) const
double diameter(const Mapping< dim, spacedim > &mapping) const
TriaActiveIterator< DoFCellAccessor< dim, spacedim, false > > as_dof_handler_iterator(const DoFHandler< dim, spacedim > &dof_handler) const
CellAccessor< dim, spacedim > & operator=(CellAccessor< dim, spacedim > &&)=default
bool is_active() const
bool is_ghost() const
TriaIterator< CellAccessor< dim, spacedim > > neighbor_child_on_subface(const unsigned int face_no, const unsigned int subface_no) const
void set_subdomain_id(const types::subdomain_id new_subdomain_id) const
bool neighbor_is_coarser(const unsigned int face_no) const
TriaIterator< CellAccessor< dim, spacedim > > child(const unsigned int i) const
void set_global_level_cell_index(const types::global_cell_index index) const
bool has_periodic_neighbor(const unsigned int i) const
void clear_refine_choice() const
int periodic_neighbor_level(const unsigned int i) const
std::pair< unsigned int, unsigned int > neighbor_of_coarser_neighbor(const unsigned int neighbor) const
~CellAccessor()=default
CellAccessor(const CellAccessor< dim, spacedim > &)=default
void set_coarsen_flag() const
TriaIterator< TriaAccessor< dim - 1, dim, spacedim > > face(const unsigned int i) const
CellAccessor< dim, spacedim > & operator=(const CellAccessor< dim, spacedim > &)=delete
unsigned int neighbor_of_neighbor(const unsigned int face_no) const
unsigned int face_iterator_to_index(const TriaIterator< TriaAccessor< dim - 1, dim, spacedim > > &face) const
void set_material_id(const types::material_id new_material_id) const
bool is_locally_owned() const
void set_refine_flag(const RefinementCase< dim > ref_case=RefinementCase< dim >::isotropic_refinement) const
CellAccessor(CellAccessor< dim, spacedim > &&)=default
bool point_inside_codim(const Point< spacedim_ > &p) const
typename TriaAccessor< dim, dim, spacedim >::AccessorData AccessorData
bool is_locally_owned_on_level() const
bool has_boundary_lines() const
TriaIterator< CellAccessor< dim, spacedim > > periodic_neighbor_child_on_subface(const unsigned int face_no, const unsigned int subface_no) const
int neighbor_level(const unsigned int face_no) const
int periodic_neighbor_index(const unsigned int i) const
bool periodic_neighbor_is_coarser(const unsigned int i) const
void set_global_active_cell_index(const types::global_cell_index index) const
void clear_coarsen_flag() const
void set_refine_choice(const std::uint8_t refinement_choice=static_cast< char >(IsotropicRefinementChoice::isotropic_refinement)) const
boost::container::small_vector< TriaIterator< CellAccessor< dim, spacedim > >, GeometryInfo< dim >::max_children_per_cell > child_iterators() const
void set_parent(const unsigned int parent_index)
std::pair< unsigned int, unsigned int > periodic_neighbor_of_coarser_periodic_neighbor(const unsigned face_no) const
CellAccessor(const TriaAccessor< dim, dim, spacedim > &cell_accessor)
bool at_boundary() const
unsigned int active_cell_index() const
static bool is_level_cell()
void clear_refine_flag() const
int neighbor_index(const unsigned int face_no) const
bool point_inside(const Point< spacedim > &p) const
types::subdomain_id subdomain_id() const
bool direction_flag() const
types::material_id material_id() const
bool coarsen_flag_set() const
types::global_cell_index global_level_cell_index() const
bool flag_for_line_refinement(const unsigned int line_no) const
CellId id() const
::internal::SubfaceCase< dim > subface_case(const unsigned int face_no) const
bool is_artificial() const
TriaIterator< DoFCellAccessor< dim, spacedim, true > > as_dof_handler_level_iterator(const DoFHandler< dim, spacedim > &dof_handler) const
bool is_ghost_on_level() const
TriaIterator< CellAccessor< dim, spacedim > > neighbor_or_periodic_neighbor(const unsigned int i) const
int parent_index() const
unsigned int periodic_neighbor_of_periodic_neighbor(const unsigned int i) const
unsigned int periodic_neighbor_face_no(const unsigned int i) const
void set_manifold_id(const types::manifold_id) const
InvalidAccessor(const InvalidAccessor &)
static constexpr unsigned int space_dimension
static int level()
bool operator==(const InvalidAccessor &) const
Point< spacedim > & vertex(const unsigned int i) const
void * quad(const unsigned int i) const
void operator++() const
void * line(const unsigned int i) const
static IteratorState::IteratorStates state()
bool operator!=(const InvalidAccessor &) const
bool has_children() const
unsigned int user_index() const
static const unsigned int structure_dimension
void copy_from(const InvalidAccessor &)
void set_user_index(const unsigned int p) const
static int index()
types::manifold_id manifold_id() const
InvalidAccessor(const void *parent=nullptr, const int level=-1, const int index=-1, const AccessorData *local_data=nullptr)
static constexpr unsigned int dimension
void operator--() const
bool used() const
InvalidAccessor(const OtherAccessor &)
Abstract base class for mapping classes.
Definition mapping.h:320
virtual boost::container::small_vector< Point< spacedim >, ReferenceCells::max_n_vertices< dim >() > get_vertices(const typename Triangulation< dim, spacedim >::cell_iterator &cell) const
Definition point.h:113
numbers::NumberTraits< Number >::real_type distance(const Point< dim, Number > &p) const
unsigned int n_vertices() const
unsigned int standard_to_real_face_vertex(const unsigned int vertex, const unsigned int face, const types::geometric_orientation face_orientation) const
std::array< unsigned int, 2 > standard_vertex_to_face_and_vertex_index(const unsigned int vertex) const
std::array< unsigned int, 2 > standard_line_to_face_and_line_index(const unsigned int line) const
unsigned int n_face_orientations(const unsigned int face_no) const
unsigned int n_faces() const
unsigned int n_lines() const
static ReferenceCell n_vertices_to_type(const int dim, const unsigned int n_vertices)
unsigned int standard_to_real_face_line(const unsigned int line, const unsigned int face, const types::geometric_orientation face_orientation) const
numbers::NumberTraits< Number >::real_type norm() const
constexpr numbers::NumberTraits< Number >::real_type norm_square() const
bool operator!=(const TriaAccessorBase &) const
static constexpr unsigned int space_dimension
static constexpr unsigned int dimension
TriaAccessorBase(const TriaAccessorBase &)
void operator=(const TriaAccessorBase *)=delete
static const unsigned int structure_dimension
TriaAccessorBase(const Triangulation< dim, spacedim > *parent=nullptr, const int level=-1, const int index=-1, const AccessorData *=nullptr)
void copy_from(const TriaAccessorBase &)
const Triangulation< dim, spacedim > & get_triangulation() const
IteratorState::IteratorStates state() const
int index() const
bool operator<(const TriaAccessorBase &other) const
typename::internal::TriaAccessorImplementation::PresentLevelType< structdim, dim >::type present_level
::internal::TriangulationImplementation::TriaObjects & objects() const
TriaAccessorBase & operator=(const TriaAccessorBase &)
int level() const
const Triangulation< dim, spacedim > * tria
bool operator==(const TriaAccessorBase &) const
static TriaIterator< TriaAccessor< 0, 1, spacedim > > isotropic_child(const unsigned int)
Return an invalid object.
static unsigned int line_index(const unsigned int i)
std_cxx20::ranges::iota_view< unsigned int, unsigned int > vertex_indices() const
static unsigned int child_iterator_to_index(const TriaIterator< TriaAccessor< 0, 1, spacedim > > &)
Return an invalid unsigned integer.
static unsigned int max_refinement_depth()
static unsigned int quad_index(const unsigned int i)
static typename::internal::TriangulationImplementation::Iterators< 1, spacedim >::quad_iterator quad(const unsigned int i)
const Manifold< 1, spacedim > & get_manifold() const
TriaAccessor(const InvalidAccessor< structdim2, dim2, spacedim2 > &)
TriaAccessor(const Triangulation< 1, spacedim > *tria, const VertexKind vertex_kind, const unsigned int vertex_index)
static TriaIterator< TriaAccessor< 0, 1, spacedim > > child(const unsigned int)
Return an invalid object.
unsigned int n_lines() const
const Triangulation< 1, spacedim > & get_triangulation() const
bool operator!=(const TriaAccessor &) const
TriaAccessor(const Triangulation< 1, spacedim > *tria=nullptr, const int=0, const int=0, const AccessorData *=nullptr)
static unsigned int n_active_descendants()
static int isotropic_child_index(const unsigned int i)
Returns -1.
types::boundary_id boundary_id() const
static typename::internal::TriangulationImplementation::Iterators< 1, spacedim >::line_iterator line(const unsigned int)
static RefinementCase< 0 > refinement_case()
ReferenceCell reference_cell() const
std_cxx20::ranges::iota_view< unsigned int, unsigned int > line_indices() const
unsigned int vertex_index(const unsigned int i=0) const
void copy_from(const TriaAccessor &)
void set_all_boundary_ids(const types::boundary_id) const
static IteratorState::IteratorStates state()
Point< spacedim > center() const
static int child_index(const unsigned int i)
Returns -1.
types::manifold_id manifold_id() const
static unsigned int n_children()
TriaAccessor(const TriaAccessor< structdim2, dim2, spacedim2 > &)
void set_boundary_id(const types::boundary_id) const
Point< spacedim > & vertex(const unsigned int i=0) const
unsigned int n_vertices() const
void set_manifold_id(const types::manifold_id)
void copy_from(const TriaAccessorBase< 0, 1, spacedim > &)
bool operator==(const TriaAccessor &) const
const Triangulation< 1, spacedim > * tria
double extent_in_direction(const unsigned int axis) const
TriaAccessor(const Triangulation< dim, spacedim > *tria, const unsigned int vertex_index)
Point< spacedim > & vertex(const unsigned int i=0) const
static typename::internal::TriangulationImplementation::Iterators< dim, spacedim >::line_iterator line(const unsigned int)
bool operator!=(const TriaAccessor &) const
static RefinementCase< 0 > refinement_case()
void copy_from(const TriaAccessor &)
static TriaIterator< TriaAccessor< 0, dim, spacedim > > child(const unsigned int)
Return an invalid object.
TriaAccessor(const InvalidAccessor< structdim2, dim2, spacedim2 > &)
static int child_index(const unsigned int i)
Returns -1.
bool operator==(const TriaAccessor &) const
static unsigned int line_index(const unsigned int i)
static TriaIterator< TriaAccessor< 0, dim, spacedim > > isotropic_child(const unsigned int)
Return an invalid object.
static typename::internal::TriangulationImplementation::Iterators< dim, spacedim >::quad_iterator quad(const unsigned int i)
unsigned int vertex_index(const unsigned int i=0) const
const Triangulation< dim, spacedim > * tria
static int isotropic_child_index(const unsigned int i)
Returns -1.
TriaAccessor(const Triangulation< dim, spacedim > *tria=nullptr, const int level=0, const int index=0, const AccessorData *=nullptr)
static unsigned int n_children()
const Triangulation< dim, spacedim > & get_triangulation() const
static unsigned int child_iterator_to_index(const TriaIterator< TriaAccessor< 0, dim, spacedim > > &)
Return an invalid unsigned integer.
static unsigned int max_refinement_depth()
static unsigned int quad_index(const unsigned int i)
static unsigned int n_active_descendants()
TriaAccessor(const TriaAccessor< structdim2, dim2, spacedim2 > &)
Point< spacedim > center(const bool respect_manifold=false, const bool interpolate_from_surrounding=false) const
IteratorState::IteratorStates state() const
std_cxx20::ranges::iota_view< unsigned int, unsigned int > vertex_indices() const
void clear_children() const
void set_boundary_id_internal(const types::boundary_id id) const
void set_user_index(const unsigned int p) const
TriaAccessor(TriaAccessor &&)=default
void clear_user_pointer() const
unsigned int n_active_descendants() const
void recursively_set_user_index(const unsigned int p) const
TriaIterator< TriaAccessor< 0, dim, spacedim > > vertex_iterator(const unsigned int i) const
void clear_user_data() const
TriaAccessor(const TriaAccessor< structdim2, dim2, spacedim2 > &)
Point< structdim > real_to_unit_cell_affine_approximation(const Point< spacedim > &point) const
void recursively_clear_user_index() const
unsigned int line_index(const unsigned int i) const
const Manifold< dim, spacedim > & get_manifold() const
void recursively_set_user_pointer(void *p) const
unsigned int n_lines() const
double extent_in_direction(const unsigned int axis) const
Point< spacedim > intermediate_point(const Point< structdim > &coordinates) const
unsigned int n_vertices() const
bool has_children() const
void recursively_clear_user_flag() const
std_cxx20::ranges::iota_view< unsigned int, unsigned int > line_indices() const
typename TriaAccessorBase< structdim, dim, spacedim >::AccessorData AccessorData
Point< spacedim > barycenter() const
BoundingBox< spacedim > bounding_box() const
void set_bounding_object_indices(const std::initializer_list< unsigned int > &new_indices) const
void clear_user_flag() const
TriaIterator< TriaAccessor< structdim, dim, spacedim > > child(const unsigned int i) const
unsigned int n_children() const
std_cxx20::ranges::iota_view< unsigned int, unsigned int > face_indices() const
void recursively_set_user_flag() const
void set_boundary_id(const types::boundary_id) const
bool is_translation_of(const TriaIterator< TriaAccessor< structdim, dim, spacedim > > &o) const
bool user_flag_set() const
void set_used_flag() const
types::manifold_id manifold_id() const
void set_user_flag() const
TriaAccessor(const TriaAccessor &)=default
void clear_used_flag() const
std::pair< Point< spacedim >, double > enclosing_ball() const
unsigned int vertex_index(const unsigned int i) const
void * user_pointer() const
int isotropic_child_index(const unsigned int i) const
Point< spacedim > center(const bool respect_manifold=false, const bool interpolate_from_surrounding=false) const
~TriaAccessor()=default
void set_refinement_case(const RefinementCase< structdim > &ref_case) const
void clear_user_index() const
double minimum_vertex_distance() const
double measure() const
void set_all_boundary_ids(const types::boundary_id) const
void set_bounding_object_indices(const std::initializer_list< int > &new_indices) const
unsigned int max_refinement_depth() const
Point< spacedim > & vertex(const unsigned int i) const
void set_line_orientation(const unsigned int line, const types::geometric_orientation orientation) const
unsigned int quad_index(const unsigned int i) const
TriaAccessor & operator=(const TriaAccessor &)=delete
unsigned int user_index() const
int child_index(const unsigned int i) const
void set_user_pointer(void *p) const
void recursively_clear_user_pointer() const
ReferenceCell reference_cell() const
RefinementCase< structdim > refinement_case() const
typename::internal::TriangulationImplementation::Iterators< dim, spacedim >::line_iterator line(const unsigned int i) const
TriaAccessor(const Triangulation< dim, spacedim > *parent=nullptr, const int level=-1, const int index=-1, const AccessorData *local_data=nullptr)
unsigned int child_iterator_to_index(const TriaIterator< TriaAccessor< structdim, dim, spacedim > > &child) const
TriaAccessor(const InvalidAccessor< structdim2, dim2, spacedim2 > &)
bool used() const
void set_children(const unsigned int i, const int index) const
void clear_refinement_case() const
double diameter() const
bool at_boundary() const
types::boundary_id boundary_id() const
unsigned int n_faces() const
TriaAccessor & operator=(TriaAccessor &&)=default
TriaIterator< TriaAccessor< structdim, dim, spacedim > > isotropic_child(const unsigned int i) const
typename::internal::TriangulationImplementation::Iterators< dim, spacedim >::quad_iterator quad(const unsigned int i) const
IteratorState::IteratorStates state() const
std::unique_ptr< std::map< unsigned int, types::manifold_id > > vertex_to_manifold_id_map_1d
Definition tria.h:4572
std::vector< Point< spacedim > > vertices
Definition tria.h:4498
virtual types::subdomain_id locally_owned_subdomain() const
std::unique_ptr< std::map< unsigned int, types::boundary_id > > vertex_to_boundary_id_map_1d
Definition tria.h:4549
std::unique_ptr<::internal::TriangulationImplementation::TriaFaces > faces
Definition tria.h:4492
bool vertex_used(const unsigned int index) const
unsigned int n_vertices() const
std::vector< std::unique_ptr<::internal::TriangulationImplementation::TriaLevel > > levels
Definition tria.h:4484
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:35
constexpr bool running_in_debug_mode()
Definition config.h:73
#define DEAL_II_CXX20_REQUIRES(condition)
Definition config.h:243
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:36
#define DEAL_II_ASSERT_UNREACHABLE()
#define DEAL_II_NOT_IMPLEMENTED()
unsigned int level
Definition grid_out.cc:4635
unsigned int vertex_indices[2]
static ::ExceptionBase & ExcCantCompareIterators()
#define DeclException0(Exception0)
static ::ExceptionBase & ExcCellHasNoParent()
static ::ExceptionBase & ExcCellFlaggedForRefinement()
static ::ExceptionBase & ExcCellHasNoChildren()
static ::ExceptionBase & ExcNotImplemented()
static ::ExceptionBase & ExcCellNotUsed()
static ::ExceptionBase & ExcNoPeriodicNeighbor()
static ::ExceptionBase & ExcCantSetChildren(int arg1)
#define Assert(cond, exc)
static ::ExceptionBase & ExcImpossibleInDim(int arg1)
static ::ExceptionBase & ExcNeighborIsNotCoarser()
static ::ExceptionBase & ExcSetOnlyEvenChildren(int arg1)
static ::ExceptionBase & ExcNeighborIsCoarser()
#define AssertIndexRange(index, range)
#define DeclExceptionMsg(Exception, defaulttext)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcFacesHaveNoLevel()
static ::ExceptionBase & ExcDereferenceInvalidObject(AccessorType arg1)
static ::ExceptionBase & ExcCellFlaggedForCoarsening()
static ::ExceptionBase & ExcIndexRange(std::size_t arg1, std::size_t arg2, std::size_t arg3)
#define DeclException1(Exception1, type1, outsequence)
static ::ExceptionBase & ExcRefineCellNotActive()
static ::ExceptionBase & ExcMessage(std::string arg1)
static ::ExceptionBase & ExcCellNotActive()
void set_all_manifold_ids(const types::manifold_id) const
const Manifold< dim, spacedim > & get_manifold(const types::manifold_id number) const
void set_all_manifold_ids(const types::manifold_id)
void set_manifold_id(const types::manifold_id) const
static bool face_orientation(const unsigned int face)
Always return false.
static types::geometric_orientation line_orientation(const unsigned int line)
Always return numbers::reverse_line_orientation.
bool face_rotation(const unsigned int face) const
bool face_orientation(const unsigned int face) const
static bool face_flip(const unsigned int face)
Always return false.
types::geometric_orientation combined_face_orientation(const unsigned int face) const
static bool face_flip(const unsigned int face)
Always return false.
static types::geometric_orientation combined_face_orientation(const unsigned int face)
Always return 0.
static bool face_rotation(const unsigned int face)
Always return false.
types::geometric_orientation line_orientation(const unsigned int line) const
static bool face_rotation(const unsigned int face)
Always return false.
void set_combined_face_orientation(const unsigned int face, const types::geometric_orientation combined_orientation) const
static types::geometric_orientation line_orientation(const unsigned int line)
Always return numbers::reverse_line_orientation.
static bool face_orientation(const unsigned int face)
Always return false.
bool face_flip(const unsigned int face) const
static types::geometric_orientation combined_face_orientation(const unsigned int face)
Always return 0.
void reference_cell(Triangulation< dim, spacedim > &tria, const ReferenceCell &reference_cell)
@ past_the_end
Iterator reached end of container.
@ valid
Iterator points to a valid object.
@ invalid
Iterator is invalid, probably due to an error.
constexpr char U
double norm(const FEValuesBase< dim > &fe, const ArrayView< const std::vector< Tensor< 1, dim > > > &Du)
Definition divergence.h:471
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
Tensor< 2, dim, Number > l(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
SymmetricTensor< 2, dim, Number > b(const Tensor< 2, dim, Number > &F)
SymmetricTensor< 2, dim, Number > epsilon(const Tensor< 2, dim, Number > &Grad_u)
constexpr ReferenceCell Triangle
constexpr ReferenceCell Hexahedron
constexpr ReferenceCell Pyramid
constexpr ReferenceCell Wedge
constexpr ReferenceCell Vertex
constexpr ReferenceCell Quadrilateral
constexpr ReferenceCell Tetrahedron
constexpr ReferenceCell Line
T sum(const T &t, const MPI_Comm mpi_communicator)
types::geometric_orientation combined_face_orientation(const bool face_orientation, const bool face_rotation, const bool face_flip)
constexpr unsigned int invalid_unsigned_int
Definition types.h:238
constexpr types::boundary_id internal_face_boundary_id
Definition types.h:329
constexpr types::manifold_id flat_manifold_id
Definition types.h:342
constexpr types::subdomain_id artificial_subdomain_id
Definition types.h:402
constexpr types::geometric_orientation reverse_line_orientation
Definition types.h:365
constexpr types::subdomain_id invalid_subdomain_id
Definition types.h:381
constexpr types::geometric_orientation default_geometric_orientation
Definition types.h:352
boost::integer_range< IncrementableType > iota_view
Definition iota_view.h:45
STL namespace.
::VectorizedArray< Number, width > min(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > max(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > sqrt(const ::VectorizedArray< Number, width > &)
unsigned int manifold_id
Definition types.h:173
std::uint64_t global_vertex_index
Definition types.h:57
unsigned int subdomain_id
Definition types.h:52
unsigned char geometric_orientation
Definition types.h:40
unsigned int boundary_id
Definition types.h:161
static RefinementCase< dim > min_cell_refinement_case_for_line_refinement(const unsigned int line_no)
static RefinementCase< dim > min_cell_refinement_case_for_face_refinement(const RefinementCase< dim - 1 > &face_refinement_case, const unsigned int face_no, const bool face_orientation=true, const bool face_flip=false, const bool face_rotation=false)
static unsigned int n_children(const RefinementCase< dim > &refinement_case)