Loading [MathJax]/extensions/TeX/newcommand.js
 deal.II version GIT relicensing-2981-gc9b2d476df 2025-04-01 01:00: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\}}
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
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,
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, accessor.n_faces());
4906
4907 if (dim == 1)
4908 Assert(combined_orientation == numbers::default_geometric_orientation,
4909 ExcMessage("In 1d, faces do not have an orientation, so the "
4910 "only valid value is the default."));
4911 else if (dim == 2)
4912 Assert(combined_orientation ==
4914 combined_orientation == numbers::reverse_line_orientation,
4915 ExcMessage(
4916 "In 2d, the only valid values of the combined orientation "
4917 "are the standard orientation or the reversed line "
4918 "orientation."));
4919
4920 // face_orientations is not set up in 1d
4921 if (dim != 1)
4922 accessor.tria->levels[accessor.present_level]
4923 ->face_orientations.set_combined_orientation(
4924 accessor.present_index * ReferenceCells::max_n_faces<dim>() +
4925 face,
4926 combined_orientation);
4927 }
4928
4929
4930
4931 template <int dim, int spacedim>
4932 static std::array<unsigned int, 1>
4933 get_line_indices_of_cell(const TriaAccessor<1, dim, spacedim> &)
4934 {
4936 return {};
4937 }
4938
4939
4940
4941 template <int structdim, int dim, int spacedim>
4942 static std::array<unsigned int, 4>
4943 get_line_indices_of_cell(const TriaAccessor<2, dim, spacedim> &cell)
4944 {
4945 // For 2d cells the access cell->line_orientation() is already
4946 // efficient
4947 std::array<unsigned int, 4> line_indices = {};
4948 for (const unsigned int line : cell.line_indices())
4949 line_indices[line] = cell.line_index(line);
4950 return line_indices;
4951 }
4952
4957 template <int structdim, int dim, int spacedim>
4958 static std::array<unsigned int, 12>
4959 get_line_indices_of_cell(
4961 {
4962 std::array<unsigned int, 12> line_indices = {};
4963
4964 // For hexahedra, the classical access via quads -> lines is too
4965 // inefficient. Unroll this code here to allow the compiler to inline
4966 // the necessary functions.
4967 const auto ref_cell = cell.reference_cell();
4968 if (ref_cell == ReferenceCells::Hexahedron)
4969 {
4970 for (unsigned int f = 4; f < 6; ++f)
4971 {
4972 const auto orientation =
4973 cell.get_triangulation()
4974 .levels[cell.level()]
4975 ->face_orientations.get_combined_orientation(
4976 cell.index() * ReferenceCells::max_n_faces<dim>() + f);
4977
4978 // It might seem superfluous to spell out the four indices
4979 // that get later consumed by a for loop over these four
4980 // elements; however, for the compiler it is easier to inline
4981 // the statement of standard_to_real_face_line() when next to
4982 // each other, as opposed to be interleaved with a
4983 // line_index() call.
4984 const std::array<unsigned int, 4> my_indices{
4985 {ref_cell.standard_to_real_face_line(0, f, orientation),
4986 ref_cell.standard_to_real_face_line(1, f, orientation),
4987 ref_cell.standard_to_real_face_line(2, f, orientation),
4988 ref_cell.standard_to_real_face_line(3, f, orientation)}};
4989 const auto quad = cell.quad(f);
4990 for (unsigned int l = 0; l < 4; ++l)
4991 line_indices[4 * (f - 4) + l] =
4992 quad->line_index(my_indices[l]);
4993 }
4994 for (unsigned int f = 0; f < 2; ++f)
4995 {
4996 const auto orientation =
4997 cell.get_triangulation()
4998 .levels[cell.level()]
4999 ->face_orientations.get_combined_orientation(
5000 cell.index() * ReferenceCells::max_n_faces<dim>() + f);
5001 const std::array<unsigned int, 2> my_indices{
5002 {ref_cell.standard_to_real_face_line(0, f, orientation),
5003 ref_cell.standard_to_real_face_line(1, f, orientation)}};
5004 const auto quad = cell.quad(f);
5005 line_indices[8 + f] = quad->line_index(my_indices[0]);
5006 line_indices[10 + f] = quad->line_index(my_indices[1]);
5007 }
5008 }
5009 else if (ref_cell == ReferenceCells::Tetrahedron)
5010 {
5011 std::array<unsigned int, 3> orientations{
5014 cell.combined_face_orientation(2)}};
5015 const std::array<unsigned int, 6> my_indices{
5016 {ref_cell.standard_to_real_face_line(0, 0, orientations[0]),
5017 ref_cell.standard_to_real_face_line(1, 0, orientations[0]),
5018 ref_cell.standard_to_real_face_line(2, 0, orientations[0]),
5019 ref_cell.standard_to_real_face_line(1, 1, orientations[1]),
5020 ref_cell.standard_to_real_face_line(2, 1, orientations[1]),
5021 ref_cell.standard_to_real_face_line(1, 2, orientations[2])}};
5022 line_indices[0] = cell.quad(0)->line_index(my_indices[0]);
5023 line_indices[1] = cell.quad(0)->line_index(my_indices[1]);
5024 line_indices[2] = cell.quad(0)->line_index(my_indices[2]);
5025 line_indices[3] = cell.quad(1)->line_index(my_indices[3]);
5026 line_indices[4] = cell.quad(1)->line_index(my_indices[4]);
5027 line_indices[5] = cell.quad(2)->line_index(my_indices[5]);
5028 }
5029 else
5030 // For other shapes (wedges, pyramids), we do not currently
5031 // implement an optimized function.
5032 for (unsigned int l = 0; l < std::min(12U, cell.n_lines()); ++l)
5033 line_indices[l] = cell.line_index(l);
5034
5035 return line_indices;
5036 }
5037
5038
5039
5044 template <int dim, int spacedim>
5045 static std::array<types::geometric_orientation, 1>
5046 get_line_orientations_of_cell(const TriaAccessor<1, dim, spacedim> &)
5047 {
5049 return {};
5050 }
5051
5052
5053
5058 template <int dim, int spacedim>
5059 static std::array<types::geometric_orientation, 4>
5060 get_line_orientations_of_cell(const TriaAccessor<2, dim, spacedim> &cell)
5061 {
5062 // For 2d cells the access cell->line_orientation() is already
5063 // efficient
5064 std::array<types::geometric_orientation, 4> line_orientations = {};
5065 for (const unsigned int line : cell.line_indices())
5066 line_orientations[line] = cell.line_orientation(line);
5067 return line_orientations;
5068 }
5069
5070
5071
5076 template <int dim, int spacedim>
5077 static std::array<types::geometric_orientation, 12>
5078 get_line_orientations_of_cell(const TriaAccessor<3, dim, spacedim> &cell)
5079 {
5080 std::array<types::geometric_orientation, 12> line_orientations = {};
5081
5082 // For hexahedra, the classical access via quads -> lines is too
5083 // inefficient. Unroll this code here to allow the compiler to inline
5084 // the necessary functions.
5085 const auto ref_cell = cell.reference_cell();
5086 if (ref_cell == ReferenceCells::Hexahedron)
5087 {
5088 for (unsigned int f = 4; f < 6; ++f)
5089 {
5090 const auto orientation =
5091 cell.get_triangulation()
5092 .levels[cell.level()]
5093 ->face_orientations.get_combined_orientation(
5094 cell.index() * ReferenceCells::max_n_faces<dim>() + f);
5095
5096 // It might seem superfluous to spell out the four indices and
5097 // orientations that get later consumed by a for loop over
5098 // these four elements; however, for the compiler it is easier
5099 // to inline the statement of standard_to_real_face_line()
5100 // when next to each other, as opposed to be interleaved with
5101 // a line_index() call.
5102 const std::array<unsigned int, 4> my_indices{
5103 {ref_cell.standard_to_real_face_line(0, f, orientation),
5104 ref_cell.standard_to_real_face_line(1, f, orientation),
5105 ref_cell.standard_to_real_face_line(2, f, orientation),
5106 ref_cell.standard_to_real_face_line(3, f, orientation)}};
5107 const auto quad = cell.quad(f);
5108 const std::array<types::geometric_orientation, 4>
5109 my_orientations{{ref_cell.face_to_cell_line_orientation(
5110 0,
5111 f,
5112 orientation,
5113 quad->line_orientation(my_indices[0])),
5114 ref_cell.face_to_cell_line_orientation(
5115 1,
5116 f,
5117 orientation,
5118 quad->line_orientation(my_indices[1])),
5119 ref_cell.face_to_cell_line_orientation(
5120 2,
5121 f,
5122 orientation,
5123 quad->line_orientation(my_indices[2])),
5124 ref_cell.face_to_cell_line_orientation(
5125 3,
5126 f,
5127 orientation,
5128 quad->line_orientation(my_indices[3]))}};
5129 for (unsigned int l = 0; l < 4; ++l)
5130 line_orientations[4 * (f - 4) + l] = my_orientations[l];
5131 }
5132 for (unsigned int f = 0; f < 2; ++f)
5133 {
5134 const auto orientation =
5135 cell.get_triangulation()
5136 .levels[cell.level()]
5137 ->face_orientations.get_combined_orientation(
5138 cell.index() * ReferenceCells::max_n_faces<3>() + f);
5139 const std::array<unsigned int, 2> my_indices{
5140 {ref_cell.standard_to_real_face_line(0, f, orientation),
5141 ref_cell.standard_to_real_face_line(1, f, orientation)}};
5142 const auto quad = cell.quad(f);
5143 const std::array<types::geometric_orientation, 2>
5144 my_orientations{{ref_cell.face_to_cell_line_orientation(
5145 0,
5146 f,
5147 orientation,
5148 quad->line_orientation(my_indices[0])),
5149 ref_cell.face_to_cell_line_orientation(
5150 1,
5151 f,
5152 orientation,
5153 quad->line_orientation(my_indices[1]))}};
5154 line_orientations[8 + f] = my_orientations[0];
5155 line_orientations[10 + f] = my_orientations[1];
5156 }
5157 }
5158 else if (ref_cell == ReferenceCells::Tetrahedron)
5159 {
5160 std::array<unsigned int, 3> orientations{
5163 cell.combined_face_orientation(2)}};
5164 const std::array<unsigned int, 6> my_indices{
5165 {ref_cell.standard_to_real_face_line(0, 0, orientations[0]),
5166 ref_cell.standard_to_real_face_line(1, 0, orientations[0]),
5167 ref_cell.standard_to_real_face_line(2, 0, orientations[0]),
5168 ref_cell.standard_to_real_face_line(1, 1, orientations[1]),
5169 ref_cell.standard_to_real_face_line(2, 1, orientations[1]),
5170 ref_cell.standard_to_real_face_line(1, 2, orientations[2])}};
5171 line_orientations[0] = ref_cell.face_to_cell_line_orientation(
5172 0,
5173 0,
5174 orientations[0],
5175 cell.quad(0)->line_orientation(my_indices[0]));
5176 line_orientations[1] = ref_cell.face_to_cell_line_orientation(
5177 1,
5178 0,
5179 orientations[0],
5180 cell.quad(0)->line_orientation(my_indices[1]));
5181 line_orientations[2] = ref_cell.face_to_cell_line_orientation(
5182 2,
5183 0,
5184 orientations[0],
5185 cell.quad(0)->line_orientation(my_indices[2]));
5186 line_orientations[3] = ref_cell.face_to_cell_line_orientation(
5187 1,
5188 1,
5189 orientations[1],
5190 cell.quad(1)->line_orientation(my_indices[3]));
5191 line_orientations[4] = ref_cell.face_to_cell_line_orientation(
5192 2,
5193 1,
5194 orientations[1],
5195 cell.quad(1)->line_orientation(my_indices[4]));
5196 line_orientations[5] = ref_cell.face_to_cell_line_orientation(
5197 1,
5198 2,
5199 orientations[2],
5200 cell.quad(2)->line_orientation(my_indices[5]));
5201 }
5202 else
5203 // For other shapes (wedges, pyramids), we do not currently
5204 // implement an optimized function
5205 for (unsigned int l = 0; l < std::min(12U, cell.n_lines()); ++l)
5206 line_orientations[l] = cell.line_orientation(l);
5207
5208 return line_orientations;
5209 }
5210 };
5211 } // namespace TriaAccessorImplementation
5212} // namespace internal
5213
5214
5215
5216template <int structdim, int dim, int spacedim>
5218 const Triangulation<dim, spacedim> *parent,
5219 const int level,
5220 const int index,
5221 const AccessorData *local_data)
5222 : TriaAccessorBase<structdim, dim, spacedim>(parent, level, index, local_data)
5223{}
5224
5225
5226
5227template <int structdim, int dim, int spacedim>
5228inline bool
5230{
5231 Assert(this->state() == IteratorState::valid,
5232 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5233 *this));
5234 return this->objects().used[this->present_index];
5235}
5236
5237
5238
5239template <int structdim, int dim, int spacedim>
5242 const unsigned int i) const
5243{
5245 0,
5246 vertex_index(i));
5247}
5248
5249
5250
5251template <int structdim, int dim, int spacedim>
5252inline ReferenceCell
5254{
5255 if (structdim == 0)
5257 else if (structdim == 1)
5258 return ReferenceCells::Line;
5259 else if (structdim == dim)
5260 return this->tria->levels[this->present_level]
5261 ->reference_cell[this->present_index];
5262 else
5263 return this->tria->faces->get_quad_type(this->present_index);
5264}
5265
5266
5267
5268template <int structdim, int dim, int spacedim>
5269inline unsigned int
5271 const unsigned int corner) const
5272{
5273 AssertIndexRange(corner, this->n_vertices());
5274
5275 if constexpr (structdim == 1)
5276 {
5277 // This branch needs to be first (and not combined with the structdim ==
5278 // dim branch) so that we can get line vertex indices when setting up the
5279 // cell vertex index cache
5280 return this->objects()
5281 .cells[this->present_index * ReferenceCells::max_n_faces<1>() + corner];
5282 }
5283 else if constexpr (structdim == dim)
5284 {
5285 // This branch should only be used after the cell vertex index cache is
5286 // set up
5287 const auto my_index = static_cast<std::size_t>(this->present_index) *
5288 ReferenceCells::max_n_vertices<dim>();
5289 AssertIndexRange(my_index + corner,
5290 this->tria->levels[this->present_level]
5291 ->cell_vertex_indices_cache.size());
5292 const unsigned int vertex_index =
5293 this->tria->levels[this->present_level]
5294 ->cell_vertex_indices_cache[my_index + corner];
5296 return vertex_index;
5297 }
5298 else if constexpr (structdim == 2)
5299 {
5300 const auto [line_index, vertex_index] =
5301 this->reference_cell().standard_vertex_to_face_and_vertex_index(corner);
5302 const auto vertex_within_line_index =
5303 this->reference_cell().standard_to_real_face_vertex(
5304 vertex_index, line_index, this->line_orientation(line_index));
5305
5306 return this->line(line_index)->vertex_index(vertex_within_line_index);
5307 }
5308 else
5309 {
5312 }
5313}
5314
5315
5316
5317template <int structdim, int dim, int spacedim>
5318inline Point<spacedim> &
5319TriaAccessor<structdim, dim, spacedim>::vertex(const unsigned int i) const
5320{
5321 return const_cast<Point<spacedim> &>(this->tria->vertices[vertex_index(i)]);
5322}
5323
5324
5325
5326template <int structdim, int dim, int spacedim>
5327inline typename ::internal::TriangulationImplementation::
5328 Iterators<dim, spacedim>::line_iterator
5329 TriaAccessor<structdim, dim, spacedim>::line(const unsigned int i) const
5330{
5331 // checks happen in line_index
5332 return typename ::internal::TriangulationImplementation::
5333 Iterators<dim, spacedim>::line_iterator(this->tria, 0, line_index(i));
5334}
5335
5336
5337
5338template <int structdim, int dim, int spacedim>
5339inline unsigned int
5341{
5342 (void)i;
5343 AssertIndexRange(i, this->n_lines());
5344 Assert(structdim != 1,
5345 ExcMessage("You can't ask for the index of a line bounding a "
5346 "one-dimensional cell because it is not bounded by "
5347 "lines."));
5348
5349 if constexpr (structdim == 2)
5350 {
5351 return this->objects()
5352 .cells[this->present_index * ReferenceCells::max_n_faces<2>() + i];
5353 }
5354 else if constexpr (structdim == 3)
5355 {
5356 const auto [face_index, line_index] =
5357 this->reference_cell().standard_line_to_face_and_line_index(i);
5358 const auto line_within_face_index =
5359 this->reference_cell().standard_to_real_face_line(
5360 line_index, face_index, this->combined_face_orientation(face_index));
5361
5362 return this->quad(face_index)->line_index(line_within_face_index);
5363 }
5364
5367}
5368
5369
5370
5371template <int structdim, int dim, int spacedim>
5372inline typename ::internal::TriangulationImplementation::
5373 Iterators<dim, spacedim>::quad_iterator
5374 TriaAccessor<structdim, dim, spacedim>::quad(const unsigned int i) const
5375{
5376 // checks happen in quad_index
5377 return typename ::internal::TriangulationImplementation::
5378 Iterators<dim, spacedim>::quad_iterator(this->tria, 0, quad_index(i));
5379}
5380
5381
5382
5383template <int structdim, int dim, int spacedim>
5384inline unsigned int
5386{
5387 Assert(structdim == 3,
5388 ExcMessage("You can't ask for the index of a quad bounding "
5389 "a one- or two-dimensional cell because it is not "
5390 "bounded by quads."));
5391 // work around a bogus GCC-9 warning which considers i unused except in 3d
5392 (void)i;
5393 if constexpr (structdim == 3)
5394 {
5395 AssertIndexRange(i, n_faces());
5396 return this->tria->levels[this->present_level]
5397 ->cells
5398 .cells[this->present_index * ReferenceCells::max_n_faces<3>() + i];
5399 }
5400 else
5402}
5403
5404
5405
5406template <int structdim, int dim, int spacedim>
5409 const unsigned int face) const
5410{
5412 AssertIndexRange(face, n_faces());
5413 Assert(structdim == dim,
5414 ExcMessage("This function can only be used on objects "
5415 "that are cells, but not on faces or edges "
5416 "that bound cells."));
5417 // work around a bogus GCC-9 warning which considers face unused except in 3d
5418 (void)face;
5419
5420 if constexpr (structdim == 1)
5422 else if constexpr (structdim == 2)
5423 {
5424 // if all elements are quads (or if we have a very special consistently
5425 // oriented triangular mesh) then we do not store this array
5426 if (this->tria->levels[this->present_level]
5427 ->face_orientations.n_objects() == 0)
5429 else
5430 return this->tria->levels[this->present_level]
5431 ->face_orientations.get_orientation(
5432 this->present_index * ReferenceCells::max_n_faces<dim>() + face);
5433 }
5434 else
5435 return this->tria->levels[this->present_level]
5436 ->face_orientations.get_combined_orientation(
5437 this->present_index * ReferenceCells::max_n_faces<dim>() + face);
5438}
5439
5440
5441
5442template <int structdim, int dim, int spacedim>
5443inline bool
5445 const unsigned int face) const
5446{
5448 AssertIndexRange(face, n_faces());
5449 Assert(structdim == dim,
5450 ExcMessage("This function can only be used on objects "
5451 "that are cells, but not on faces or edges "
5452 "that bound cells."));
5453 // work around a bogus GCC-9 warning which considers face unused in 1d
5454 (void)face;
5455
5456 if constexpr (structdim == 1)
5457 // in 1d 'faces' are vertices and those are always consistently oriented
5458 return true;
5459 else if constexpr (structdim == 2)
5460 return this->line_orientation(face) ==
5462 else
5463 return this->tria->levels[this->present_level]
5464 ->face_orientations.get_orientation(
5465 this->present_index * ReferenceCells::max_n_faces<structdim>() + face);
5466}
5467
5468
5469
5470template <int structdim, int dim, int spacedim>
5471inline bool
5472TriaAccessor<structdim, dim, spacedim>::face_flip(const unsigned int face) const
5473{
5475 Assert(structdim == dim,
5476 ExcMessage("This function can only be used on objects "
5477 "that are cells, but not on faces or edges "
5478 "that bound cells."));
5479 AssertIndexRange(face, n_faces());
5480 // work around a bogus GCC-9 warning which considers face unused except in 3d
5481 (void)face;
5482
5483 if constexpr (structdim == 3)
5484 return this->tria->levels[this->present_level]->face_orientations.get_flip(
5485 this->present_index * ReferenceCells::max_n_faces<structdim>() + face);
5486 else
5487 // In 1d and 2d, face_flip is always false as faces can only be
5488 // 'flipped' in 3d.
5489 return false;
5490}
5491
5492
5493template <int structdim, int dim, int spacedim>
5494inline bool
5496 const unsigned int face) const
5497{
5499 Assert(structdim == dim,
5500 ExcMessage("This function can only be used on objects "
5501 "that are cells, but not on faces or edges "
5502 "that bound cells."));
5503 AssertIndexRange(face, n_faces());
5504 // work around a bogus GCC-9 warning which considers face unused except in 3d
5505 (void)face;
5506
5507 if constexpr (structdim == 3)
5508 return this->tria->levels[this->present_level]
5509 ->face_orientations.get_rotation(
5510 this->present_index * ReferenceCells::max_n_faces<structdim>() + face);
5511 else
5512 // In 1d and 2d, face_rotation is always false as faces can only be
5513 // 'rotated' in 3d.
5514 return false;
5515}
5516
5517
5518
5519template <int structdim, int dim, int spacedim>
5522 const unsigned int line) const
5523{
5525 AssertIndexRange(line, this->n_lines());
5526 // work around a bogus GCC-9 warning which considers line unused in 1d
5527 (void)line;
5528
5529 if constexpr (structdim == 1)
5531 else if constexpr (structdim == 2 && dim == 2)
5532 // lines in 2d are faces
5533 {
5534 const auto combined_orientation = combined_face_orientation(line);
5535 Assert(combined_orientation == numbers::default_geometric_orientation ||
5536 combined_orientation == numbers::reverse_line_orientation,
5538 return combined_orientation;
5539 }
5540 else if constexpr (structdim == 2 && dim == 3)
5541 {
5542 // line orientations in 3d are stored in their own array as bools: here
5543 // 'true' is the default orientation and 'false' is the reversed one
5544 // (which matches set_line_orientation())
5545 const auto index =
5546 this->present_index * ReferenceCells::max_n_lines<2>() + line;
5547 Assert(index < this->tria->faces->quads_line_orientations.size(),
5549 return this->tria->faces->quads_line_orientations[index] ?
5552 }
5553 else if constexpr (structdim == 3 && dim == 3)
5554 {
5555 const auto reference_cell = this->reference_cell();
5556 // First pick a face on which this line is a part of, and the
5557 // index of the line within.
5558 const auto [face_index, line_index] =
5559 reference_cell.standard_line_to_face_and_line_index(line);
5560 const auto line_within_face_index =
5561 reference_cell.standard_to_real_face_line(
5562 line_index, face_index, this->combined_face_orientation(face_index));
5563
5564 // Then query how that line is oriented within that face:
5565 return reference_cell.face_to_cell_line_orientation(
5566 line_index,
5567 face_index,
5568 this->combined_face_orientation(face_index),
5569 this->quad(face_index)->line_orientation(line_within_face_index));
5570 }
5571 else
5572 {
5574 return false;
5575 }
5576}
5577
5578
5579
5580template <int structdim, int dim, int spacedim>
5581inline void
5583 const unsigned int line,
5584 const types::geometric_orientation value) const
5585{
5587 AssertIndexRange(line, this->n_lines());
5588 Assert(dim != 1,
5589 ExcMessage("In 1d lines are cells and thus do not need to have their "
5590 "orientations set."));
5591 Assert(dim != 2,
5592 ExcMessage("In 2d lines are faces, and, for compatibility with other "
5593 "dimensions, their orientations should be set via "
5594 "set_combined_orientation()."));
5595 // work around a bogus GCC-9 warning which considers line and value unused
5596 // except in 3d
5597 (void)line;
5598 (void)value;
5599
5600 if constexpr (dim == 3)
5601 {
5602 // We set line orientations per face, not per cell, so this only works for
5603 // faces in 3d.
5604 Assert(structdim == 2, ExcNotImplemented());
5605 const auto index =
5606 this->present_index * ReferenceCells::max_n_lines<2>() + line;
5607 Assert(index < this->tria->faces->quads_line_orientations.size(),
5609 this->tria->faces->quads_line_orientations[index] =
5611 }
5612}
5613
5614
5615
5616template <int structdim, int dim, int spacedim>
5617inline void
5619 const unsigned int face,
5620 const types::geometric_orientation combined_orientation) const
5621{
5623 AssertIndexRange(face, this->n_faces());
5624
5625 ::internal::TriaAccessorImplementation::Implementation::
5626 set_combined_face_orientation(*this, face, combined_orientation);
5627}
5628
5629
5630
5631template <int structdim, int dim, int spacedim>
5632void
5634{
5635 Assert(this->state() == IteratorState::valid,
5636 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5637 *this));
5638 this->objects().used[this->present_index] = true;
5639}
5640
5641
5642
5643template <int structdim, int dim, int spacedim>
5644void
5646{
5647 Assert(this->state() == IteratorState::valid,
5648 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5649 *this));
5650 this->objects().used[this->present_index] = false;
5651}
5652
5653
5654template <int structdim, int dim, int spacedim>
5655int
5657{
5659 AssertIndexRange(i, n_children());
5660
5661 // each set of two children are stored
5662 // consecutively, so we only have to find
5663 // the location of the set of children
5664 const unsigned int n_sets_of_two =
5666 return this->objects().children[n_sets_of_two * this->present_index + i / 2] +
5667 i % 2;
5668}
5669
5670
5671
5672template <int structdim, int dim, int spacedim>
5673int
5675 const unsigned int i) const
5676{
5678
5679 switch (structdim)
5680 {
5681 case 1:
5682 return child_index(i);
5683 case 2:
5684 {
5685 const RefinementCase<2> this_refinement_case(
5686 static_cast<std::uint8_t>(refinement_case()));
5687
5688 Assert(this_refinement_case != RefinementCase<2>::no_refinement,
5690
5691 if (this_refinement_case == RefinementCase<2>::cut_xy)
5692 return child_index(i);
5693 else if ((this_refinement_case == RefinementCase<2>::cut_x) &&
5694 (child(i % 2)->refinement_case() ==
5696 return child(i % 2)->child_index(i / 2);
5697 else if ((this_refinement_case == RefinementCase<2>::cut_y) &&
5698 (child(i / 2)->refinement_case() ==
5700 return child(i / 2)->child_index(i % 2);
5701 else
5702 Assert(
5703 false,
5704 ExcMessage(
5705 "This cell has no grandchildren equivalent to isotropic refinement"));
5706 break;
5707 }
5708
5709 case 3:
5711 }
5712 return -1;
5713}
5714
5715
5716
5717template <int structdim, int dim, int spacedim>
5720{
5721 Assert(this->state() == IteratorState::valid,
5722 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5723 *this));
5724
5725 switch (structdim)
5726 {
5727 case 1:
5729 this->objects().children[this->present_index] != -1 ?
5730 // cast the branches
5731 // here first to uchar
5732 // and then (above) to
5733 // RefinementCase<structdim>
5734 // so that the
5735 // conversion is valid
5736 // even for the case
5737 // structdim>1 (for
5738 // which this part of
5739 // the code is dead
5740 // anyway)
5741 static_cast<std::uint8_t>(RefinementCase<1>::cut_x) :
5742 static_cast<std::uint8_t>(RefinementCase<1>::no_refinement)));
5743
5744 default:
5745 Assert(static_cast<unsigned int>(this->present_index) <
5746 this->objects().refinement_cases.size(),
5747 ExcIndexRange(this->present_index,
5748 0,
5749 this->objects().refinement_cases.size()));
5750
5751 return (static_cast<RefinementCase<structdim>>(
5752 this->objects().refinement_cases[this->present_index]));
5753 }
5754}
5755
5756
5757
5758template <int structdim, int dim, int spacedim>
5760TriaAccessor<structdim, dim, spacedim>::child(const unsigned int i) const
5761
5762{
5763 // checking of 'i' happens in child_index
5765 this->tria, (dim == structdim ? this->level() + 1 : 0), child_index(i));
5766
5767 Assert((q.state() == IteratorState::past_the_end) || q->used(),
5769
5770 return q;
5771}
5772
5773
5774
5775template <int structdim, int dim, int spacedim>
5776inline unsigned int
5779{
5780 const auto n_children = this->n_children();
5781 for (unsigned int child_n = 0; child_n < n_children; ++child_n)
5782 if (this->child(child_n) == child)
5783 return child_n;
5784
5785 Assert(false,
5786 ExcMessage("The given child is not a child of the current object."));
5788}
5789
5790
5791
5792template <int structdim, int dim, int spacedim>
5795 const unsigned int i) const
5796{
5797 // checking of 'i' happens in child() or
5798 // child_index() called below
5799 switch (structdim)
5800 {
5801 case 1:
5802 // no anisotropic refinement in 1d
5803 return child(i);
5804
5805 case 2:
5806 {
5807 const RefinementCase<2> this_refinement_case(
5808 static_cast<std::uint8_t>(refinement_case()));
5809
5810 Assert(this_refinement_case != RefinementCase<2>::no_refinement,
5812
5813 if (this_refinement_case == RefinementCase<2>::cut_xy)
5814 return child(i);
5815 else if ((this_refinement_case == RefinementCase<2>::cut_x) &&
5816 (child(i % 2)->refinement_case() ==
5818 return child(i % 2)->child(i / 2);
5819 else if ((this_refinement_case == RefinementCase<2>::cut_y) &&
5820 (child(i / 2)->refinement_case() ==
5822 return child(i / 2)->child(i % 2);
5823 else
5824 Assert(
5825 false,
5826 ExcMessage(
5827 "This cell has no grandchildren equivalent to isotropic refinement"));
5828 break;
5829 }
5830
5831 default:
5833 }
5834 // we don't get here but have to return
5835 // something...
5836 return child(0);
5837}
5838
5839
5840
5841template <int structdim, int dim, int spacedim>
5842inline bool
5844{
5845 Assert(this->state() == IteratorState::valid,
5846 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5847 *this));
5848
5849 // each set of two children are stored
5850 // consecutively, so we only have to find
5851 // the location of the set of children
5852 const unsigned int n_sets_of_two =
5854 return (this->objects().children[n_sets_of_two * this->present_index] != -1);
5855}
5856
5857
5858
5859template <int structdim, int dim, int spacedim>
5860inline unsigned int
5862{
5863 Assert(this->state() == IteratorState::valid,
5864 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5865 *this));
5869 else
5870 return GeometryInfo<structdim>::n_children(refinement_case());
5871}
5872
5873
5874
5875template <int structdim, int dim, int spacedim>
5876inline void
5878 const RefinementCase<structdim> &refinement_case) const
5879{
5880 Assert(this->state() == IteratorState::valid,
5881 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5882 *this));
5883 Assert(static_cast<unsigned int>(this->present_index) <
5884 this->objects().refinement_cases.size(),
5885 ExcIndexRange(this->present_index,
5886 0,
5887 this->objects().refinement_cases.size()));
5888
5889 this->objects().refinement_cases[this->present_index] = refinement_case;
5890}
5891
5892
5893template <int structdim, int dim, int spacedim>
5894inline void
5896{
5897 Assert(this->state() == IteratorState::valid,
5898 TriaAccessorExceptions::ExcDereferenceInvalidObject<TriaAccessor>(
5899 *this));
5900 Assert(static_cast<unsigned int>(this->present_index) <
5901 this->objects().refinement_cases.size(),
5902 ExcIndexRange(this->present_index,
5903 0,
5904 this->objects().refinement_cases.size()));
5905
5906 this->objects().refinement_cases[this->present_index] =
5908}
5909
5910
5911
5912template <int structdim, int dim, int spacedim>
5913void
5915 const int index) const
5916{
5919
5920 // each set of two children are stored
5921 // consecutively, so we only have to find
5922 // the location of the set of children
5923 const unsigned int n_sets_of_two =
5925
5926 Assert(
5927 // clearing the child index for a cell
5928 (index == -1) ||
5929 // if setting the child index for the i'th child (with i==0),
5930 // then the index must be a non-negative number
5931 (i == 0 && !this->has_children() && (index >= 0)) ||
5932 // if setting the child index for the i'th child (with i>0),
5933 // then the previously stored index must be the invalid
5934 // index
5935 (i > 0 && this->has_children() && (index >= 0) &&
5936 this->objects().children[n_sets_of_two * this->present_index + i / 2] ==
5937 -1),
5939
5940 this->objects().children[n_sets_of_two * this->present_index + i / 2] = index;
5941}
5942
5943
5944
5945template <int structdim, int dim, int spacedim>
5946void
5948{
5949 // each set of two children are stored
5950 // consecutively, so we only have to find
5951 // the location of the set of children
5952 const unsigned int n_sets_of_two =
5954
5955 for (unsigned int i = 0; i < n_sets_of_two; ++i)
5956 set_children(2 * i, -1);
5957}
5958
5959
5960
5961template <int structdim, int dim, int spacedim>
5962inline bool
5964{
5966 return this->objects().user_flags[this->present_index];
5967}
5968
5969
5970
5971template <int structdim, int dim, int spacedim>
5972inline void
5974{
5976 this->objects().user_flags[this->present_index] = true;
5977}
5978
5979
5980
5981template <int structdim, int dim, int spacedim>
5982inline void
5984{
5986 this->objects().user_flags[this->present_index] = false;
5987}
5988
5989
5990
5991template <int structdim, int dim, int spacedim>
5992void
5994{
5995 set_user_flag();
5996
5997 if (this->has_children())
5998 for (unsigned int c = 0; c < this->n_children(); ++c)
5999 this->child(c)->recursively_set_user_flag();
6000}
6001
6002
6003
6004template <int structdim, int dim, int spacedim>
6005void
6007{
6008 clear_user_flag();
6009
6010 if (this->has_children())
6011 for (unsigned int c = 0; c < this->n_children(); ++c)
6012 this->child(c)->recursively_clear_user_flag();
6013}
6014
6015
6016
6017template <int structdim, int dim, int spacedim>
6018void
6020{
6022 this->objects().clear_user_data(this->present_index);
6023}
6024
6025
6026
6027template <int structdim, int dim, int spacedim>
6028void
6030{
6032 this->objects().user_pointer(this->present_index) = p;
6033}
6034
6035
6036
6037template <int structdim, int dim, int spacedim>
6038void
6040{
6042 this->objects().user_pointer(this->present_index) = nullptr;
6043}
6044
6045
6046
6047template <int structdim, int dim, int spacedim>
6048void *
6050{
6052 return this->objects().user_pointer(this->present_index);
6053}
6054
6055
6056
6057template <int structdim, int dim, int spacedim>
6058void
6060 void *p) const
6061{
6062 set_user_pointer(p);
6063
6064 if (this->has_children())
6065 for (unsigned int c = 0; c < this->n_children(); ++c)
6066 this->child(c)->recursively_set_user_pointer(p);
6067}
6068
6069
6070
6071template <int structdim, int dim, int spacedim>
6072void
6074{
6075 clear_user_pointer();
6076
6077 if (this->has_children())
6078 for (unsigned int c = 0; c < this->n_children(); ++c)
6079 this->child(c)->recursively_clear_user_pointer();
6080}
6081
6082
6083
6084template <int structdim, int dim, int spacedim>
6085void
6087 const unsigned int p) const
6088{
6090 this->objects().user_index(this->present_index) = p;
6091}
6092
6093
6094
6095template <int structdim, int dim, int spacedim>
6096void
6098{
6100 this->objects().user_index(this->present_index) = 0;
6101}
6102
6103
6104
6105template <int structdim, int dim, int spacedim>
6106unsigned int
6108{
6110 return this->objects().user_index(this->present_index);
6111}
6112
6113
6114
6115template <int structdim, int dim, int spacedim>
6116void
6118 const unsigned int p) const
6119{
6120 set_user_index(p);
6121
6122 if (this->has_children())
6123 for (unsigned int c = 0; c < this->n_children(); ++c)
6124 this->child(c)->recursively_set_user_index(p);
6125}
6126
6127
6128
6129template <int structdim, int dim, int spacedim>
6130void
6132{
6133 clear_user_index();
6134
6135 if (this->has_children())
6136 for (unsigned int c = 0; c < this->n_children(); ++c)
6137 this->child(c)->recursively_clear_user_index();
6138}
6139
6140
6141
6142template <int structdim, int dim, int spacedim>
6143inline unsigned int
6145{
6146 if (!this->has_children())
6147 return 0;
6148
6149 unsigned int max_depth = 1;
6150 for (unsigned int c = 0; c < n_children(); ++c)
6151 max_depth = std::max(max_depth, child(c)->max_refinement_depth() + 1);
6152 return max_depth;
6153}
6154
6155
6156
6157template <int structdim, int dim, int spacedim>
6158unsigned int
6160{
6161 if (!this->has_children())
6162 return 1;
6163 else
6164 {
6165 unsigned int sum = 0;
6166 for (unsigned int c = 0; c < n_children(); ++c)
6167 sum += this->child(c)->n_active_descendants();
6168 return sum;
6169 }
6170}
6171
6172
6173
6174template <int structdim, int dim, int spacedim>
6177{
6178 Assert(structdim < dim, ExcImpossibleInDim(dim));
6180
6181 return this->objects()
6182 .boundary_or_material_id[this->present_index]
6183 .boundary_id;
6184}
6185
6186
6187
6188template <int structdim, int dim, int spacedim>
6189void
6191 const types::boundary_id boundary_ind) const
6192{
6193 Assert(structdim < dim, ExcImpossibleInDim(dim));
6196 ExcMessage("You are trying to set the boundary_id to an invalid "
6197 "value (numbers::internal_face_boundary_id is reserved)."));
6198 Assert(this->at_boundary(),
6199 ExcMessage("You are trying to set the boundary_id of an "
6200 "internal object, which is not allowed!"));
6201
6202 this->objects().boundary_or_material_id[this->present_index].boundary_id =
6203 boundary_ind;
6204}
6205
6206
6207
6208template <int structdim, int dim, int spacedim>
6209void
6211 const types::boundary_id boundary_ind) const
6212{
6213 Assert(structdim < dim, ExcImpossibleInDim(dim));
6215
6216 this->objects().boundary_or_material_id[this->present_index].boundary_id =
6217 boundary_ind;
6218}
6219
6220
6221
6222template <int structdim, int dim, int spacedim>
6223void
6225 const types::boundary_id boundary_ind) const
6226{
6227 set_boundary_id(boundary_ind);
6228
6229 switch (structdim)
6230 {
6231 case 1:
6232 // 1d objects have no sub-objects
6233 // where we have to do anything
6234 break;
6235
6236 case 2:
6237 // for boundary quads also set
6238 // boundary_id of bounding lines
6239 for (unsigned int i = 0; i < this->n_lines(); ++i)
6240 this->line(i)->set_boundary_id(boundary_ind);
6241 break;
6242
6243 default:
6245 }
6246}
6247
6248
6249
6250template <int structdim, int dim, int spacedim>
6251bool
6253{
6254 // error checking is done
6255 // in boundary_id()
6257}
6258
6259
6260
6261template <int structdim, int dim, int spacedim>
6264{
6266 return this->tria->get_manifold(this->manifold_id());
6267}
6268
6269
6270template <int structdim, int dim, int spacedim>
6273{
6275
6276 return this->objects().manifold_id[this->present_index];
6277}
6278
6279
6280
6281template <int structdim, int dim, int spacedim>
6282void
6284 const types::manifold_id manifold_ind) const
6285{
6287
6288 this->objects().manifold_id[this->present_index] = manifold_ind;
6289}
6290
6291
6292template <int structdim, int dim, int spacedim>
6293void
6295 const types::manifold_id manifold_ind) const
6296{
6297 set_manifold_id(manifold_ind);
6298
6299 if (this->has_children())
6300 for (unsigned int c = 0; c < this->n_children(); ++c)
6301 this->child(c)->set_all_manifold_ids(manifold_ind);
6302
6303 switch (structdim)
6304 {
6305 case 1:
6306 if (dim == 1)
6307 {
6308 (*this->tria->vertex_to_manifold_id_map_1d)[vertex_index(0)] =
6309 manifold_ind;
6310 (*this->tria->vertex_to_manifold_id_map_1d)[vertex_index(1)] =
6311 manifold_ind;
6312 }
6313 break;
6314
6315 case 2:
6316 // for quads/simplices also set manifold_id of bounding lines
6317 for (unsigned int i = 0; i < this->n_lines(); ++i)
6318 this->line(i)->set_manifold_id(manifold_ind);
6319 break;
6320 default:
6322 }
6323}
6324
6325
6326
6327template <int structdim, int dim, int spacedim>
6328double
6330{
6331 boost::container::small_vector<Point<spacedim>,
6332# ifndef _MSC_VER
6333 ReferenceCells::max_n_vertices<structdim>()
6334# else
6336# endif
6337 >
6338 vertices(this->n_vertices());
6339
6340 for (unsigned int v = 0; v < vertices.size(); ++v)
6341 vertices[v] = this->vertex(v);
6342
6343 return internal::TriaAccessorImplementation::diameter<structdim, spacedim>(
6344 vertices);
6345}
6346
6347
6348
6349template <int dim, int spacedim>
6350double
6352 const Mapping<dim, spacedim> &mapping) const
6353{
6354 return internal::TriaAccessorImplementation::diameter<dim, spacedim>(
6356 this->tria, this->level(), this->index())));
6357}
6358
6359
6360
6361template <int structdim, int dim, int spacedim>
6362std::pair<Point<spacedim>, double>
6364{
6365 // If the object is one dimensional,
6366 // the enclosing ball is the initial iterate
6367 // i.e., the ball's center and diameter are
6368 // the center and the diameter of the object.
6369 if (structdim == 1)
6370 return std::make_pair((this->vertex(1) + this->vertex(0)) * 0.5,
6371 (this->vertex(1) - this->vertex(0)).norm() * 0.5);
6372
6373 // The list is_initial_guess_vertex contains bool values and has
6374 // the same size as the number of vertices per object.
6375 // The entries of is_initial_guess_vertex are set true only for those
6376 // two vertices corresponding to the largest diagonal which is being used
6377 // to construct the initial ball.
6378 // We employ this mask to skip these two vertices while enlarging the ball.
6379 std::vector<bool> is_initial_guess_vertex(this->n_vertices());
6380
6381 // First let all the vertices be outside
6382 std::fill(is_initial_guess_vertex.begin(),
6383 is_initial_guess_vertex.end(),
6384 false);
6385
6386 // Get an initial guess by looking at the largest diagonal
6387 Point<spacedim> center;
6388 double radius = 0;
6389
6390 switch (structdim)
6391 {
6392 case 2:
6393 {
6394 const Point<spacedim> p30(this->vertex(3) - this->vertex(0));
6395 const Point<spacedim> p21(this->vertex(2) - this->vertex(1));
6396 if (p30.norm() > p21.norm())
6397 {
6398 center = this->vertex(0) + 0.5 * p30;
6399 radius = p30.norm() / 2.;
6400 is_initial_guess_vertex[3] = true;
6401 is_initial_guess_vertex[0] = true;
6402 }
6403 else
6404 {
6405 center = this->vertex(1) + 0.5 * p21;
6406 radius = p21.norm() / 2.;
6407 is_initial_guess_vertex[2] = true;
6408 is_initial_guess_vertex[1] = true;
6409 }
6410 break;
6411 }
6412 case 3:
6413 {
6414 const Point<spacedim> p70(this->vertex(7) - this->vertex(0));
6415 const Point<spacedim> p61(this->vertex(6) - this->vertex(1));
6416 const Point<spacedim> p25(this->vertex(2) - this->vertex(5));
6417 const Point<spacedim> p34(this->vertex(3) - this->vertex(4));
6418 const std::vector<double> diagonals = {p70.norm(),
6419 p61.norm(),
6420 p25.norm(),
6421 p34.norm()};
6422 const std::vector<double>::const_iterator it =
6423 std::max_element(diagonals.begin(), diagonals.end());
6424 if (it == diagonals.begin())
6425 {
6426 center = this->vertex(0) + 0.5 * p70;
6427 is_initial_guess_vertex[7] = true;
6428 is_initial_guess_vertex[0] = true;
6429 }
6430 else if (it == diagonals.begin() + 1)
6431 {
6432 center = this->vertex(1) + 0.5 * p61;
6433 is_initial_guess_vertex[6] = true;
6434 is_initial_guess_vertex[1] = true;
6435 }
6436 else if (it == diagonals.begin() + 2)
6437 {
6438 center = this->vertex(5) + 0.5 * p25;
6439 is_initial_guess_vertex[2] = true;
6440 is_initial_guess_vertex[5] = true;
6441 }
6442 else
6443 {
6444 center = this->vertex(4) + 0.5 * p34;
6445 is_initial_guess_vertex[3] = true;
6446 is_initial_guess_vertex[4] = true;
6447 }
6448 radius = *it * 0.5;
6449 break;
6450 }
6451 default:
6453 return std::pair<Point<spacedim>, double>();
6454 }
6455
6456 // For each vertex that is found to be geometrically outside the ball
6457 // enlarge the ball so that the new ball contains both the previous ball
6458 // and the given vertex.
6459 for (const unsigned int v : this->vertex_indices())
6460 if (!is_initial_guess_vertex[v])
6461 {
6462 const double distance = center.distance(this->vertex(v));
6463 if (distance > radius)
6464 {
6465 // we found a vertex which is outside of the ball
6466 // extend it (move center and change radius)
6467 const Point<spacedim> pCV(center - this->vertex(v));
6468 radius = (distance + radius) * 0.5;
6469 center = this->vertex(v) + pCV * (radius / distance);
6470
6471 // Now the new ball constructed in this block
6472 // encloses the vertex (v) that was found to be geometrically
6473 // outside the old ball.
6474 }
6475 }
6476 if constexpr (running_in_debug_mode())
6477 {
6478 bool all_vertices_within_ball = true;
6479
6480 // Set all_vertices_within_ball false if any of the vertices of the object
6481 // are geometrically outside the ball
6482 for (const unsigned int v : this->vertex_indices())
6483 if (center.distance(this->vertex(v)) >
6484 radius + 100. * std::numeric_limits<double>::epsilon())
6485 {
6486 all_vertices_within_ball = false;
6487 break;
6488 }
6489 // If all the vertices are not within the ball throw error
6490 Assert(all_vertices_within_ball, ExcInternalError());
6491 }
6492 return std::make_pair(center, radius);
6493}
6494
6495
6496template <int structdim, int dim, int spacedim>
6497double
6499{
6500 switch (structdim)
6501 {
6502 case 1:
6503 return (this->vertex(1) - this->vertex(0)).norm();
6504 case 2:
6505 case 3:
6506 {
6507 double min = std::numeric_limits<double>::max();
6508 for (const unsigned int i : this->vertex_indices())
6509 for (unsigned int j = i + 1; j < this->n_vertices(); ++j)
6510 min = std::min(min,
6511 (this->vertex(i) - this->vertex(j)) *
6512 (this->vertex(i) - this->vertex(j)));
6513 return std::sqrt(min);
6514 }
6515 default:
6517 return -1e10;
6518 }
6519}
6520
6521
6522template <int structdim, int dim, int spacedim>
6523bool
6526{
6527 // go through the vertices and check... The
6528 // cell is a translation of the previous
6529 // one in case the distance between the
6530 // individual vertices in the two cell is
6531 // the same for all the vertices. So do the
6532 // check by first getting the distance on
6533 // the first vertex, and then checking
6534 // whether all others have the same down to
6535 // rounding errors (we have to be careful
6536 // here because the calculation of the
6537 // displacement between one cell and the
6538 // next can already result in the loss of
6539 // one or two digits), so we choose 1e-12
6540 // times the distance between the zeroth
6541 // vertices here.
6542 bool is_translation = true;
6543 const Tensor<1, spacedim> dist = o->vertex(0) - this->vertex(0);
6544 const double tol_square = 1e-24 * dist.norm_square();
6545 for (unsigned int i = 1; i < this->n_vertices(); ++i)
6546 {
6547 const Tensor<1, spacedim> dist_new =
6548 (o->vertex(i) - this->vertex(i)) - dist;
6549 if (dist_new.norm_square() > tol_square)
6550 {
6551 is_translation = false;
6552 break;
6553 }
6554 }
6555 return is_translation;
6556}
6557
6558
6559
6560template <int structdim, int dim, int spacedim>
6561unsigned int
6563{
6564 return this->reference_cell().n_vertices();
6565}
6566
6567
6568
6569template <int structdim, int dim, int spacedim>
6570unsigned int
6572{
6573 return this->reference_cell().n_lines();
6574}
6575
6576
6577
6578template <int structdim, int dim, int spacedim>
6579unsigned int
6581{
6582 Assert(structdim == dim,
6583 ExcMessage("This function can only be used on objects "
6584 "that are cells, but not on faces or edges "
6585 "that bound cells."));
6586
6587 return this->reference_cell().n_faces();
6588}
6589
6590
6591
6592template <int structdim, int dim, int spacedim>
6595{
6597 n_vertices());
6598}
6599
6600
6601
6602template <int structdim, int dim, int spacedim>
6605{
6607 n_lines());
6608}
6609
6610
6611
6612template <int structdim, int dim, int spacedim>
6615{
6617 n_faces());
6618}
6619
6620
6621
6622/*----------------- Functions: TriaAccessor<0,dim,spacedim> -----------------*/
6623
6624template <int dim, int spacedim>
6626 const Triangulation<dim, spacedim> *tria,
6627 const unsigned int vertex_index)
6628 : tria(tria)
6629 , global_vertex_index(vertex_index)
6630{}
6631
6632
6633
6634template <int dim, int spacedim>
6636 const Triangulation<dim, spacedim> *tria,
6637 const int /*level*/,
6638 const int index,
6639 const AccessorData *)
6640 : tria(tria)
6642{}
6643
6644
6645
6646template <int dim, int spacedim>
6647template <int structdim2, int dim2, int spacedim2>
6650 : tria(nullptr)
6652{
6653 Assert(false, ExcImpossibleInDim(0));
6654}
6655
6656
6657
6658template <int dim, int spacedim>
6659template <int structdim2, int dim2, int spacedim2>
6662 : tria(nullptr)
6664{
6665 Assert(false, ExcImpossibleInDim(0));
6666}
6667
6668
6669
6670template <int dim, int spacedim>
6671inline void
6673{
6674 tria = t.tria;
6675 global_vertex_index = t.global_vertex_index;
6676}
6677
6678
6679
6680template <int dim, int spacedim>
6681inline bool
6683 const TriaAccessor<0, dim, spacedim> &other) const
6684{
6686
6687 return (global_vertex_index < other.global_vertex_index);
6688}
6689
6690
6691
6692template <int dim, int spacedim>
6695{
6696 if (global_vertex_index != numbers::invalid_unsigned_int)
6697 return IteratorState::valid;
6698 else
6700}
6701
6702
6703
6704template <int dim, int spacedim>
6705inline int
6707{
6708 return 0;
6709}
6710
6711
6712
6713template <int dim, int spacedim>
6714inline int
6716{
6717 return global_vertex_index;
6718}
6719
6720
6721
6722template <int dim, int spacedim>
6723inline const Triangulation<dim, spacedim> &
6725{
6726 return *tria;
6727}
6728
6729
6730
6731template <int dim, int spacedim>
6732inline void
6734{
6736 if (global_vertex_index >= tria->n_vertices())
6738}
6739
6740
6741
6742template <int dim, int spacedim>
6743inline void
6745{
6746 if (global_vertex_index != numbers::invalid_unsigned_int)
6747 {
6748 if (global_vertex_index != 0)
6750 else
6752 }
6753}
6754
6755
6756
6757template <int dim, int spacedim>
6758inline bool
6760{
6761 const bool result =
6762 ((tria == t.tria) && (global_vertex_index == t.global_vertex_index));
6763
6764 return result;
6765}
6766
6767
6768
6769template <int dim, int spacedim>
6770inline bool
6772{
6773 return !(*this == t);
6774}
6775
6776
6777
6778template <int dim, int spacedim>
6779inline unsigned int
6780TriaAccessor<0, dim, spacedim>::vertex_index(const unsigned int) const
6781{
6782 return global_vertex_index;
6783}
6784
6785
6786
6787template <int dim, int spacedim>
6788inline Point<spacedim> &
6789TriaAccessor<0, dim, spacedim>::vertex(const unsigned int) const
6790{
6791 return const_cast<Point<spacedim> &>(
6792 this->tria->vertices[global_vertex_index]);
6793}
6794
6795
6796
6797template <int dim, int spacedim>
6798inline typename ::internal::TriangulationImplementation::
6799 Iterators<dim, spacedim>::line_iterator
6800 TriaAccessor<0, dim, spacedim>::line(const unsigned int)
6801{
6802 return typename ::internal::TriangulationImplementation::
6803 Iterators<dim, spacedim>::line_iterator();
6804}
6805
6806
6807
6808template <int dim, int spacedim>
6809inline unsigned int
6811{
6812 Assert(false, ExcImpossibleInDim(0));
6814}
6815
6816
6817
6818template <int dim, int spacedim>
6819inline typename ::internal::TriangulationImplementation::
6820 Iterators<dim, spacedim>::quad_iterator
6821 TriaAccessor<0, dim, spacedim>::quad(const unsigned int)
6822{
6823 return typename ::internal::TriangulationImplementation::
6824 Iterators<dim, spacedim>::quad_iterator();
6825}
6826
6827
6828
6829template <int dim, int spacedim>
6830inline unsigned int
6832{
6833 Assert(false, ExcImpossibleInDim(0));
6835}
6836
6837
6838
6839template <int dim, int spacedim>
6840inline double
6842{
6843 return 0.;
6844}
6845
6846
6847
6848template <int dim, int spacedim>
6849inline double
6851{
6852 return 0.;
6853}
6854
6855
6856
6857template <int dim, int spacedim>
6858inline Point<spacedim>
6859TriaAccessor<0, dim, spacedim>::center(const bool, const bool) const
6860{
6861 return this->tria->vertices[global_vertex_index];
6862}
6863
6864
6865
6866template <int dim, int spacedim>
6867inline double
6869{
6870 return 0.;
6871}
6872
6873
6874
6875template <int dim, int spacedim>
6878 const unsigned int /*face*/)
6879{
6881}
6882
6883
6884
6885template <int dim, int spacedim>
6886inline bool
6887TriaAccessor<0, dim, spacedim>::face_orientation(const unsigned int /*face*/)
6888{
6889 return false;
6890}
6891
6892
6893
6894template <int dim, int spacedim>
6895inline bool
6896TriaAccessor<0, dim, spacedim>::face_flip(const unsigned int /*face*/)
6897{
6898 return false;
6899}
6900
6901
6902
6903template <int dim, int spacedim>
6904inline bool
6905TriaAccessor<0, dim, spacedim>::face_rotation(const unsigned int /*face*/)
6906{
6907 return false;
6908}
6909
6910
6911
6912template <int dim, int spacedim>
6914TriaAccessor<0, dim, spacedim>::line_orientation(const unsigned int /*line*/)
6915{
6917}
6918
6919
6920
6921template <int dim, int spacedim>
6922inline bool
6924{
6925 return false;
6926}
6927
6928
6929
6930template <int dim, int spacedim>
6931inline unsigned int
6933{
6934 return 0;
6935}
6936
6937
6938
6939template <int dim, int spacedim>
6940inline unsigned int
6942{
6943 return 0;
6944}
6945
6946
6947
6948template <int dim, int spacedim>
6949inline unsigned int
6951{
6952 return 0;
6953}
6954
6955
6956
6957template <int dim, int spacedim>
6958inline unsigned int
6961{
6963}
6964
6965
6966
6967template <int dim, int spacedim>
6969TriaAccessor<0, dim, spacedim>::child(const unsigned int)
6970{
6972}
6973
6974
6975
6976template <int dim, int spacedim>
6979{
6981}
6982
6983
6984
6985template <int dim, int spacedim>
6986inline RefinementCase<0>
6988{
6990}
6991
6992
6993
6994template <int dim, int spacedim>
6995inline int
6997{
6998 return -1;
6999}
7000
7001
7002
7003template <int dim, int spacedim>
7004inline int
7006{
7007 return -1;
7008}
7009
7010
7011
7012template <int dim, int spacedim>
7013inline bool
7015{
7016 return tria->vertex_used(global_vertex_index);
7017}
7018
7019
7020
7021/*------------------- Functions: TriaAccessor<0,1,spacedim> -----------------*/
7022
7023template <int spacedim>
7025 const Triangulation<1, spacedim> *tria,
7026 const VertexKind vertex_kind,
7027 const unsigned int vertex_index)
7028 : tria(tria)
7029 , vertex_kind(vertex_kind)
7030 , global_vertex_index(vertex_index)
7031{}
7032
7033
7034
7035template <int spacedim>
7037 const Triangulation<1, spacedim> *tria,
7038 const int level,
7039 const int index,
7040 const AccessorData *)
7041 : tria(tria)
7042 , vertex_kind(interior_vertex)
7044{
7045 // in general, calling this constructor should yield an error -- users should
7046 // instead call the one immediately above. however, if you create something
7047 // like Triangulation<1>::face_iterator() then this calls the default
7048 // constructor of the iterator which calls the accessor with argument list
7049 // (0,-2,-2,0), so in this particular case accept this call and create an
7050 // object that corresponds to the default constructed (invalid) vertex
7051 // accessor
7052 (void)level;
7053 (void)index;
7054 Assert((level == -2) && (index == -2),
7055 ExcMessage(
7056 "This constructor can not be called for face iterators in 1d, "
7057 "except to default-construct iterator objects."));
7058}
7059
7060
7061
7062template <int spacedim>
7063template <int structdim2, int dim2, int spacedim2>
7066 : tria(nullptr)
7067 , vertex_kind(interior_vertex)
7069{
7070 Assert(false, ExcImpossibleInDim(0));
7071}
7072
7073
7074
7075template <int spacedim>
7076template <int structdim2, int dim2, int spacedim2>
7079 : tria(nullptr)
7080 , vertex_kind(interior_vertex)
7082{
7083 Assert(false, ExcImpossibleInDim(0));
7084}
7085
7086
7087
7088template <int spacedim>
7089inline void
7091{
7092 tria = t.tria;
7093 vertex_kind = t.vertex_kind;
7094 global_vertex_index = t.global_vertex_index;
7095}
7096
7097
7098
7099template <int spacedim>
7100inline void
7103{
7104 // We cannot convert from TriaAccessorBase to
7105 // TriaAccessor<0,1,spacedim> because the latter is not derived from
7106 // the former. We should never get here.
7108}
7109
7110
7111
7112template <int spacedim>
7113inline bool
7115 const TriaAccessor<0, 1, spacedim> &other) const
7116{
7118
7119 return (global_vertex_index < other.global_vertex_index);
7120}
7121
7122
7123
7124template <int spacedim>
7127{
7128 return IteratorState::valid;
7129}
7130
7131
7132template <int spacedim>
7133inline int
7135{
7136 return 0;
7137}
7138
7139
7140
7141template <int spacedim>
7142inline int
7144{
7145 return global_vertex_index;
7146}
7147
7148
7149
7150template <int spacedim>
7151inline const Triangulation<1, spacedim> &
7153{
7154 return *tria;
7155}
7156
7157
7158
7159template <int spacedim>
7160inline void
7162{
7164}
7165
7166
7167template <int spacedim>
7168inline void
7170{
7172}
7173
7174
7175
7176template <int spacedim>
7177inline bool
7179{
7180 const bool result =
7181 ((tria == t.tria) && (global_vertex_index == t.global_vertex_index));
7182 // if we point to the same vertex,
7183 // make sure we know the same about
7184 // it
7185 if (result == true)
7186 Assert(vertex_kind == t.vertex_kind, ExcInternalError());
7187
7188 return result;
7189}
7190
7191
7192
7193template <int spacedim>
7194inline bool
7196{
7197 return !(*this == t);
7198}
7199
7200
7201
7202template <int spacedim>
7203inline unsigned int
7204TriaAccessor<0, 1, spacedim>::vertex_index(const unsigned int i) const
7205{
7206 AssertIndexRange(i, 1);
7207 (void)i;
7208 return global_vertex_index;
7209}
7210
7211
7212
7213template <int spacedim>
7214inline Point<spacedim> &
7215TriaAccessor<0, 1, spacedim>::vertex(const unsigned int i) const
7216{
7217 AssertIndexRange(i, 1);
7218 (void)i;
7219 return const_cast<Point<spacedim> &>(
7220 this->tria->vertices[global_vertex_index]);
7221}
7222
7223
7224
7225template <int spacedim>
7226inline Point<spacedim>
7228{
7229 return this->tria->vertices[global_vertex_index];
7230}
7231
7232
7233
7234template <int spacedim>
7235inline typename ::internal::TriangulationImplementation::
7236 Iterators<1, spacedim>::line_iterator
7237 TriaAccessor<0, 1, spacedim>::line(const unsigned int)
7238{
7239 return {};
7240}
7241
7242
7243template <int spacedim>
7244inline unsigned int
7246{
7247 Assert(false, ExcImpossibleInDim(0));
7249}
7250
7251
7252template <int spacedim>
7253inline typename ::internal::TriangulationImplementation::
7254 Iterators<1, spacedim>::quad_iterator
7255 TriaAccessor<0, 1, spacedim>::quad(const unsigned int)
7256{
7257 return {};
7258}
7259
7260
7261
7262template <int spacedim>
7263inline unsigned int
7265{
7266 Assert(false, ExcImpossibleInDim(0));
7268}
7269
7270
7271template <int spacedim>
7272inline bool
7274{
7275 return vertex_kind != interior_vertex;
7276}
7277
7278
7279template <int spacedim>
7280inline types::boundary_id
7282{
7283 switch (vertex_kind)
7284 {
7285 case left_vertex:
7286 case right_vertex:
7287 {
7289 this->vertex_index()) !=
7290 tria->vertex_to_boundary_id_map_1d->end(),
7292
7293 return (*tria->vertex_to_boundary_id_map_1d)[this->vertex_index()];
7294 }
7295
7296 default:
7298 }
7299}
7300
7301
7302
7303template <int spacedim>
7304inline const Manifold<1, spacedim> &
7306{
7307 return this->tria->get_manifold(this->manifold_id());
7308}
7309
7310
7311
7312template <int spacedim>
7313inline types::manifold_id
7315{
7316 if (tria->vertex_to_manifold_id_map_1d->find(this->vertex_index()) !=
7317 tria->vertex_to_manifold_id_map_1d->end())
7318 return (*tria->vertex_to_manifold_id_map_1d)[this->vertex_index()];
7319 else
7321}
7322
7323
7324template <int spacedim>
7327 const unsigned int /*face*/)
7328{
7330}
7331
7332
7333template <int spacedim>
7334inline bool
7335TriaAccessor<0, 1, spacedim>::face_orientation(const unsigned int /*face*/)
7336{
7337 return false;
7338}
7339
7340
7341
7342template <int spacedim>
7343inline bool
7344TriaAccessor<0, 1, spacedim>::face_flip(const unsigned int /*face*/)
7345{
7346 return false;
7347}
7348
7349
7350
7351template <int spacedim>
7352inline bool
7353TriaAccessor<0, 1, spacedim>::face_rotation(const unsigned int /*face*/)
7354{
7355 return false;
7356}
7357
7358
7359
7360template <int spacedim>
7362TriaAccessor<0, 1, spacedim>::line_orientation(const unsigned int /*line*/)
7363{
7365}
7366
7367
7368
7369template <int spacedim>
7370inline bool
7372{
7373 return false;
7374}
7375
7376
7377
7378template <int spacedim>
7379inline unsigned int
7381{
7382 return 0;
7383}
7384
7385
7386
7387template <int spacedim>
7388inline unsigned int
7390{
7391 return 0;
7392}
7393
7394
7395
7396template <int spacedim>
7397inline unsigned int
7399{
7400 return 0;
7401}
7402
7403
7404
7405template <int spacedim>
7406inline unsigned int
7409{
7411}
7412
7413
7414
7415template <int spacedim>
7417TriaAccessor<0, 1, spacedim>::child(const unsigned int)
7418{
7420}
7421
7422
7423template <int spacedim>
7426{
7428}
7429
7430
7431template <int spacedim>
7432inline RefinementCase<0>
7434{
7436}
7437
7438template <int spacedim>
7439inline int
7441{
7442 return -1;
7443}
7444
7445
7446template <int spacedim>
7447inline int
7449{
7450 return -1;
7451}
7452
7453
7454
7455template <int spacedim>
7456inline void
7458{
7459 Assert(tria->vertex_to_boundary_id_map_1d->find(this->vertex_index()) !=
7460 tria->vertex_to_boundary_id_map_1d->end(),
7461 ExcMessage("You can't set the boundary_id of a face of a cell that is "
7462 "not actually at the boundary."));
7463
7464 (*tria->vertex_to_boundary_id_map_1d)[this->vertex_index()] = b;
7465}
7466
7467
7468
7469template <int spacedim>
7470inline void
7472{
7473 (*tria->vertex_to_manifold_id_map_1d)[this->vertex_index()] = b;
7474}
7475
7476
7477
7478template <int spacedim>
7479inline void
7481 const types::boundary_id b) const
7482{
7483 set_boundary_id(b);
7484}
7485
7486
7487
7488template <int spacedim>
7489inline void
7491{
7492 set_manifold_id(b);
7493}
7494
7495
7496
7497template <int spacedim>
7498inline bool
7500{
7501 return tria->vertex_used(global_vertex_index);
7502}
7503
7504
7505
7506template <int spacedim>
7507inline ReferenceCell
7509{
7511}
7512
7513
7514
7515template <int spacedim>
7516unsigned int
7518{
7519 return 1;
7520}
7521
7522
7523
7524template <int spacedim>
7525unsigned int
7527{
7528 return 0;
7529}
7530
7531
7532
7533template <int spacedim>
7536{
7538 n_vertices());
7539}
7540
7541
7542
7543template <int spacedim>
7546{
7548 n_lines());
7549}
7550
7551/*------------------ Functions: CellAccessor<dim,spacedim> ------------------*/
7552
7553
7554template <int dim, int spacedim>
7556 const Triangulation<dim, spacedim> *parent,
7557 const int level,
7558 const int index,
7559 const AccessorData *local_data)
7560 : TriaAccessor<dim, dim, spacedim>(parent, level, index, local_data)
7561{}
7562
7563
7564
7565template <int dim, int spacedim>
7567 const TriaAccessor<dim, dim, spacedim> &cell_accessor)
7568 : TriaAccessor<dim, dim, spacedim>(
7569 static_cast<const TriaAccessor<dim, dim, spacedim> &>(cell_accessor))
7570{}
7571
7572
7573
7574template <int dim, int spacedim>
7576CellAccessor<dim, spacedim>::child(const unsigned int i) const
7577{
7579 this->present_level + 1,
7580 this->child_index(i));
7581
7582 Assert((q.state() == IteratorState::past_the_end) || q->used(),
7584
7585 return q;
7586}
7587
7588
7589
7590template <int dim, int spacedim>
7591inline boost::container::small_vector<TriaIterator<CellAccessor<dim, spacedim>>,
7594{
7595 boost::container::small_vector<TriaIterator<CellAccessor<dim, spacedim>>,
7597 child_iterators(this->n_children());
7598
7599 for (unsigned int i = 0; i < this->n_children(); ++i)
7600 child_iterators[i] = this->child(i);
7601
7602 return child_iterators;
7603}
7604
7605
7606
7607template <int dim, int spacedim>
7608inline TriaIterator<TriaAccessor<dim - 1, dim, spacedim>>
7609CellAccessor<dim, spacedim>::face(const unsigned int i) const
7610{
7611 AssertIndexRange(i, this->n_faces());
7612 if constexpr (dim == 1)
7613 {
7614 using VertexKind = typename TriaAccessor<0, 1, spacedim>::VertexKind;
7615 VertexKind vertex_kind = VertexKind::interior_vertex;
7616 if (i == 0 && at_boundary(0))
7617 vertex_kind = VertexKind::left_vertex;
7618 if (i == 1 && at_boundary(1))
7619 vertex_kind = VertexKind::right_vertex;
7620 TriaAccessor<0, 1, spacedim> a(&this->get_triangulation(),
7621 vertex_kind,
7622 this->vertex_index(i));
7624 }
7625 else if constexpr (dim == 2)
7626 return this->line(i);
7627 else if constexpr (dim == 3)
7628 return this->quad(i);
7629 else
7630 {
7631 Assert(false, ExcNotImplemented());
7632 return {};
7633 }
7634}
7635
7636
7637
7638template <int dim, int spacedim>
7639inline unsigned int
7642{
7643 for (const unsigned int face_n : this->face_indices())
7644 if (this->face(face_n) == face)
7645 return face_n;
7646
7647 Assert(false,
7648 ExcMessage("The given face is not a face of the current cell."));
7650}
7651
7652
7653
7654template <int dim, int spacedim>
7655inline 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 >
7664{
7665 boost::container::small_vector<
7666 TriaIterator<TriaAccessor<dim - 1, dim, spacedim>>,
7667# ifndef _MSC_VER
7668 ReferenceCells::max_n_faces<dim>()
7669# else
7671# endif
7672 >
7673 face_iterators(this->n_faces());
7674
7675 for (const unsigned int i : this->face_indices())
7676 face_iterators[i] = this->face(i);
7677
7678 return face_iterators;
7679}
7680
7681
7682
7683template <int dim, int spacedim>
7684inline unsigned int
7685CellAccessor<dim, spacedim>::face_index(const unsigned int i) const
7686{
7687 switch (dim)
7688 {
7689 case 1:
7690 return this->vertex_index(i);
7691
7692 case 2:
7693 return this->line_index(i);
7694
7695 case 3:
7696 return this->quad_index(i);
7697
7698 default:
7700 }
7701}
7702
7703
7704
7705template <int dim, int spacedim>
7706inline int
7707CellAccessor<dim, spacedim>::neighbor_index(const unsigned int face_no) const
7708{
7709 AssertIndexRange(face_no, this->n_faces());
7710 return this->tria->levels[this->present_level]
7711 ->neighbors[this->present_index * ReferenceCells::max_n_faces<dim>() +
7712 face_no]
7713 .second;
7714}
7715
7716
7717
7718template <int dim, int spacedim>
7719inline int
7720CellAccessor<dim, spacedim>::neighbor_level(const unsigned int face_no) const
7721{
7722 AssertIndexRange(face_no, this->n_faces());
7723 return this->tria->levels[this->present_level]
7724 ->neighbors[this->present_index * ReferenceCells::max_n_faces<dim>() +
7725 face_no]
7726 .first;
7727}
7728
7729
7730
7731template <int dim, int spacedim>
7734{
7736 // cells flagged for refinement must be active
7737 // (the @p set_refine_flag function checks this,
7738 // but activity may change when refinement is
7739 // executed and for some reason the refine
7740 // flag is not cleared).
7741 Assert(this->is_active() || !this->tria->levels[this->present_level]
7742 ->refine_flags[this->present_index],
7743 ExcRefineCellNotActive());
7744 return RefinementCase<dim>(
7745 this->tria->levels[this->present_level]->refine_flags[this->present_index]);
7746}
7747
7748
7749
7750template <int dim, int spacedim>
7751inline void
7753 const RefinementCase<dim> refinement_case) const
7754{
7755 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
7756 Assert(!coarsen_flag_set(), ExcCellFlaggedForCoarsening());
7757
7758 this->tria->levels[this->present_level]->refine_flags[this->present_index] =
7759 refinement_case;
7760}
7761
7762
7763
7764template <int dim, int spacedim>
7765inline void
7767{
7768 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
7769 this->tria->levels[this->present_level]->refine_flags[this->present_index] =
7771}
7772
7773
7774template <int dim, int spacedim>
7775inline std::uint8_t
7777{
7779 if (this->tria->levels[this->present_level]->refine_choice.size() == 0)
7780 return 0U;
7781 return this->tria->levels[this->present_level]
7782 ->refine_choice[this->present_index];
7783}
7784
7785
7786template <int dim, int spacedim>
7787inline void
7789 const std::uint8_t refinement_choice) const
7790{
7791 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
7792 if (this->tria->levels[this->present_level]->refine_choice.size() != 0)
7793 this->tria->levels[this->present_level]
7794 ->refine_choice[this->present_index] = refinement_choice;
7795}
7796
7797
7798template <int dim, int spacedim>
7799inline void
7801{
7802 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
7803 if (this->tria->levels[this->present_level]->refine_choice.size() != 0)
7804 this->tria->levels[this->present_level]
7805 ->refine_choice[this->present_index] =
7807}
7808
7809
7810template <int dim, int spacedim>
7811inline bool
7813 const unsigned int face_no,
7814 const RefinementCase<dim - 1> &face_refinement_case) const
7815{
7816 Assert(dim > 1, ExcImpossibleInDim(dim));
7817 AssertIndexRange(face_no, this->n_faces());
7818 AssertIndexRange(face_refinement_case,
7820
7821 // the new refinement case is a combination
7822 // of the minimum required one for the given
7823 // face refinement and the already existing
7824 // flagged refinement case
7825 RefinementCase<dim> old_ref_case = refine_flag_set();
7826 RefinementCase<dim> new_ref_case =
7827 (old_ref_case |
7829 face_refinement_case,
7830 face_no,
7831 this->face_orientation(face_no),
7832 this->face_flip(face_no),
7833 this->face_rotation(face_no)));
7834 set_refine_flag(new_ref_case);
7835 // return, whether we had to change the
7836 // refinement flag
7837 return new_ref_case != old_ref_case;
7838}
7839
7840
7841
7842template <int dim, int spacedim>
7843inline bool
7845 const unsigned int line_no) const
7846{
7847 Assert(dim > 1, ExcImpossibleInDim(dim));
7848 AssertIndexRange(line_no, this->n_lines());
7849
7850 // the new refinement case is a combination
7851 // of the minimum required one for the given
7852 // line refinement and the already existing
7853 // flagged refinement case
7855 old_ref_case = refine_flag_set(),
7856 new_ref_case =
7857 old_ref_case |
7859 set_refine_flag(new_ref_case);
7860 // return, whether we had to change the
7861 // refinement flag
7862 return new_ref_case != old_ref_case;
7863}
7864
7865
7866
7867template <int dim, int spacedim>
7868inline ::internal::SubfaceCase<dim>
7869CellAccessor<dim, spacedim>::subface_case(const unsigned int face_no) const
7870{
7872 AssertIndexRange(face_no, this->n_faces());
7873
7874 if constexpr (dim == 1)
7875 return ::internal::SubfaceCase<1>::case_none;
7876 else if constexpr (dim == 2)
7877 return ((face(face_no)->has_children()) ?
7879 ::internal::SubfaceCase<2>::case_none);
7880 else if constexpr (dim == 3)
7881 {
7882 switch (static_cast<std::uint8_t>(face(face_no)->refinement_case()))
7883 {
7885 return ::internal::SubfaceCase<3>::case_none;
7887 if (face(face_no)->child(0)->has_children())
7888 {
7889 Assert(face(face_no)->child(0)->refinement_case() ==
7892 if (face(face_no)->child(1)->has_children())
7893 {
7894 Assert(face(face_no)->child(1)->refinement_case() ==
7897 return ::internal::SubfaceCase<3>::case_x1y2y;
7898 }
7899 else
7900 return ::internal::SubfaceCase<3>::case_x1y;
7901 }
7902 else
7903 {
7904 if (face(face_no)->child(1)->has_children())
7905 {
7906 Assert(face(face_no)->child(1)->refinement_case() ==
7909 return ::internal::SubfaceCase<3>::case_x2y;
7910 }
7911 else
7912 return ::internal::SubfaceCase<3>::case_x;
7913 }
7915 if (face(face_no)->child(0)->has_children())
7916 {
7917 Assert(face(face_no)->child(0)->refinement_case() ==
7920 if (face(face_no)->child(1)->has_children())
7921 {
7922 Assert(face(face_no)->child(1)->refinement_case() ==
7925 return ::internal::SubfaceCase<3>::case_y1x2x;
7926 }
7927 else
7928 return ::internal::SubfaceCase<3>::case_y1x;
7929 }
7930 else
7931 {
7932 if (face(face_no)->child(1)->has_children())
7933 {
7934 Assert(face(face_no)->child(1)->refinement_case() ==
7937 return ::internal::SubfaceCase<3>::case_y2x;
7938 }
7939 else
7940 return ::internal::SubfaceCase<3>::case_y;
7941 }
7943 return ::internal::SubfaceCase<3>::case_xy;
7944 default:
7946 }
7947 }
7948
7949 // we should never get here
7951 return ::internal::SubfaceCase<dim>::case_none;
7952}
7953
7954
7955
7956template <int dim, int spacedim>
7957inline bool
7959{
7961 // cells flagged for coarsening must be active
7962 // (the @p set_refine_flag function checks this,
7963 // but activity may change when refinement is
7964 // executed and for some reason the refine
7965 // flag is not cleared).
7966 Assert(this->is_active() || !this->tria->levels[this->present_level]
7967 ->coarsen_flags[this->present_index],
7968 ExcRefineCellNotActive());
7969 return this->tria->levels[this->present_level]
7970 ->coarsen_flags[this->present_index];
7971}
7972
7973
7974
7975template <int dim, int spacedim>
7976inline void
7978{
7979 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
7980 Assert(!refine_flag_set(), ExcCellFlaggedForRefinement());
7981
7982 this->tria->levels[this->present_level]->coarsen_flags[this->present_index] =
7983 true;
7984}
7985
7986
7987
7988template <int dim, int spacedim>
7989inline void
7991{
7992 Assert(this->used() && this->is_active(), ExcRefineCellNotActive());
7993 this->tria->levels[this->present_level]->coarsen_flags[this->present_index] =
7994 false;
7995}
7996
7997
7998
7999template <int dim, int spacedim>
8001CellAccessor<dim, spacedim>::neighbor(const unsigned int face_no) const
8002{
8004 neighbor_level(face_no),
8005 neighbor_index(face_no));
8006
8007 Assert((q.state() == IteratorState::past_the_end) || q->used(),
8009
8010 return q;
8011}
8012
8013
8014
8015template <int dim, int spacedim>
8016inline bool
8018{
8019 return !this->has_children();
8020}
8021
8022
8023
8024template <int dim, int spacedim>
8025inline bool
8027{
8028 Assert(this->is_active(),
8029 ExcMessage("is_locally_owned() can only be called on active cells!"));
8030# ifndef DEAL_II_WITH_MPI
8031 return true;
8032# else
8033
8034 // Serial triangulations report invalid_subdomain_id as their locally owned
8035 // subdomain, so the first condition checks whether we have a serial
8036 // triangulation, in which case all cells are locally owned. The second
8037 // condition compares the subdomain id in the parallel case.
8038 const types::subdomain_id locally_owned_subdomain =
8039 this->tria->locally_owned_subdomain();
8040 return (locally_owned_subdomain == numbers::invalid_subdomain_id ||
8041 this->subdomain_id() == locally_owned_subdomain);
8042
8043# endif
8044}
8045
8046
8047template <int dim, int spacedim>
8048inline bool
8050{
8051# ifndef DEAL_II_WITH_MPI
8052 return true;
8053# else
8054
8055 // Serial triangulations report invalid_subdomain_id as their locally owned
8056 // subdomain, so the first condition checks whether we have a serial
8057 // triangulation, in which case all cells are locally owned. The second
8058 // condition compares the subdomain id in the parallel case.
8059 const types::subdomain_id locally_owned_subdomain =
8060 this->tria->locally_owned_subdomain();
8061 return (locally_owned_subdomain == numbers::invalid_subdomain_id ||
8062 this->level_subdomain_id() == locally_owned_subdomain);
8063
8064# endif
8065}
8066
8067
8068template <int dim, int spacedim>
8069inline bool
8071{
8072 Assert(this->is_active(),
8073 ExcMessage("is_ghost() can only be called on active cells!"));
8074 if (this->has_children())
8075 return false;
8076
8077# ifndef DEAL_II_WITH_MPI
8078 return false;
8079# else
8080
8081 // Serial triangulations report invalid_subdomain_id as their locally owned
8082 // subdomain, so the first condition rules out that case as all cells to a
8083 // serial triangulation are locally owned and none is ghosted. The second
8084 // and third conditions check whether the cell's subdomain is not the
8085 // locally owned one and not artificial.
8086 const types::subdomain_id locally_owned_subdomain =
8087 this->tria->locally_owned_subdomain();
8088 const types::subdomain_id subdomain_id = this->subdomain_id();
8089 return (locally_owned_subdomain != numbers::invalid_subdomain_id &&
8090 subdomain_id != locally_owned_subdomain &&
8091 subdomain_id != numbers::artificial_subdomain_id);
8092
8093# endif
8094}
8095
8096
8097template <int dim, int spacedim>
8098inline bool
8100{
8101# ifndef DEAL_II_WITH_MPI
8102 return false;
8103# else
8104
8105 // Serial triangulations report invalid_subdomain_id as their locally owned
8106 // subdomain, so the first condition checks whether we have a serial
8107 // triangulation, in which case all cells are locally owned. The second
8108 // condition compares the subdomain id in the parallel case.
8109 const types::subdomain_id locally_owned_subdomain =
8110 this->tria->locally_owned_subdomain();
8111 const types::subdomain_id subdomain_id = this->level_subdomain_id();
8112 return (locally_owned_subdomain != numbers::invalid_subdomain_id &&
8113 subdomain_id != locally_owned_subdomain &&
8114 subdomain_id != numbers::artificial_subdomain_id);
8115
8116# endif
8117}
8118
8119
8120
8121template <int dim, int spacedim>
8122inline bool
8124{
8125 Assert(this->is_active(),
8126 ExcMessage("is_artificial() can only be called on active cells!"));
8127# ifndef DEAL_II_WITH_MPI
8128 return false;
8129# else
8130
8131 // Serial triangulations report invalid_subdomain_id as their locally owned
8132 // subdomain, so the first condition rules out that case as all cells to a
8133 // serial triangulation are locally owned and none is artificial.
8134 return (this->tria->locally_owned_subdomain() !=
8136 this->subdomain_id() == numbers::artificial_subdomain_id);
8137
8138# endif
8139}
8140
8141
8142
8143template <int dim, int spacedim>
8144inline bool
8146{
8147# ifndef DEAL_II_WITH_MPI
8148 return false;
8149# else
8150 return (this->tria->locally_owned_subdomain() !=
8152 this->level_subdomain_id() == numbers::artificial_subdomain_id);
8153# endif
8154}
8155
8156
8157
8158template <int dim, int spacedim>
8161{
8163 Assert(this->is_active(),
8164 ExcMessage("subdomain_id() can only be called on active cells!"));
8165 return this->tria->levels[this->present_level]
8166 ->subdomain_ids[this->present_index];
8167}
8168
8169
8170
8171template <int dim, int spacedim>
8174{
8176 return this->tria->levels[this->present_level]
8177 ->level_subdomain_ids[this->present_index];
8178}
8179
8180
8181
8182template <int dim, int spacedim>
8183inline unsigned int
8184CellAccessor<dim, spacedim>::neighbor_face_no(const unsigned int neighbor) const
8185{
8186 const unsigned int n2 = neighbor_of_neighbor_internal(neighbor);
8188 // return this value as the
8189 // neighbor is not coarser
8190 return n2;
8191 else
8192 // the neighbor is coarser
8193 return neighbor_of_coarser_neighbor(neighbor).first;
8194}
8195
8196
8197
8198template <int dim, int spacedim>
8199inline bool
8201{
8202 return false;
8203}
8204
8205
8206
8207template <int dim, int spacedim>
8208inline unsigned int
8210{
8212 return this->tria->levels[this->present_level]
8213 ->active_cell_indices[this->present_index];
8214}
8215
8216
8217
8218template <int dim, int spacedim>
8221{
8223 Assert(this->is_active(),
8224 ExcMessage(
8225 "global_active_cell_index() can only be called on active cells!"));
8226
8227 return this->tria->levels[this->present_level]
8228 ->global_active_cell_indices[this->present_index];
8229}
8230
8231
8232
8233template <int dim, int spacedim>
8236{
8237 return this->tria->levels[this->present_level]
8238 ->global_level_cell_indices[this->present_index];
8239}
8240
8241#endif // DOXYGEN
8242
8244
8245
8246#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_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:40
constexpr bool running_in_debug_mode()
Definition config.h:78
#define DEAL_II_CXX20_REQUIRES(condition)
Definition config.h:246
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:41
#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:232
constexpr types::boundary_id internal_face_boundary_id
Definition types.h:323
constexpr types::manifold_id flat_manifold_id
Definition types.h:336
constexpr types::subdomain_id artificial_subdomain_id
Definition types.h:396
constexpr types::geometric_orientation reverse_line_orientation
Definition types.h:359
constexpr types::subdomain_id invalid_subdomain_id
Definition types.h:375
constexpr types::geometric_orientation default_geometric_orientation
Definition types.h:346
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:165
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:153
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)