deal.II version 9.8.0
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Loading...
Searching...
No Matches
dof_accessor.h
Go to the documentation of this file.
1// -----------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception OR LGPL-2.1-or-later
4// Copyright (C) 1998 - 2026 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Detailed license information governing the source code and contributions
9// can be found in LICENSE.md and CONTRIBUTING.md at the top level directory.
10//
11// -----------------------------------------------------------------------------
12
13#ifndef dealii_dof_accessor_h
14#define dealii_dof_accessor_h
15
16
17#include <deal.II/base/config.h>
18
19#include <deal.II/base/types.h>
20
24
26
30
31#include <boost/container/small_vector.hpp>
32
33#include <set>
34#include <type_traits>
35#include <vector>
36
37
39
40// Forward declarations
41#ifndef DOXYGEN
42template <typename number>
43class FullMatrix;
44template <typename number>
45class Vector;
46template <typename number>
48
49template <typename Accessor>
50class TriaRawIterator;
51
52template <int, int>
53class FiniteElement;
54
55namespace internal
56{
58 {
59 struct Implementation;
60 }
61
63 {
64 struct Implementation;
65 namespace Policy
66 {
67 struct Implementation;
68 }
69 } // namespace DoFHandlerImplementation
70
71 namespace hp
72 {
74 {
75 struct Implementation;
76 }
77 } // namespace hp
78} // namespace internal
79#endif
80
81
82namespace internal
83{
85 {
102 template <int structdim, int dim, int spacedim>
111
112
118 template <int dim, int spacedim>
119 struct Inheritance<dim, dim, spacedim>
120 {
126 };
127
128 struct Implementation;
129 } // namespace DoFAccessorImplementation
130} // namespace internal
131
132
133/* -------------------------------------------------------------------------- */
134
135
136
209template <int structdim, int dim, int spacedim, bool level_dof_access>
211 Inheritance<structdim, dim, spacedim>::BaseClass
212{
213public:
218 static constexpr unsigned int dimension = dim;
219
224 static constexpr unsigned int space_dimension = spacedim;
225
230 using BaseClass = typename ::internal::DoFAccessorImplementation::
231 Inheritance<structdim, dimension, space_dimension>::BaseClass;
232
237
244
249
266 const int level,
267 const int index,
269
274 default;
275
279 DoFAccessor( // NOLINT
281 default; // NOLINT
282
286 ~DoFAccessor() = default;
287
300 template <int structdim2, int dim2, int spacedim2>
302
307 template <int structdim2, int dim2, int spacedim2, bool level_dof_access2>
310
314 template <bool level_dof_access2>
316
328 delete;
329
334 operator=( // NOLINT
336 default; // NOLINT
337
341
347
351 template <bool level_dof_access2>
352 void
354
359 void
361
366 static bool
368
375
380 child(const unsigned int c) const;
381
387 typename ::internal::DoFHandlerImplementation::
388 Iterators<dim, spacedim, level_dof_access>::line_iterator
389 line(const unsigned int i) const;
390
396 typename ::internal::DoFHandlerImplementation::
397 Iterators<dim, spacedim, level_dof_access>::quad_iterator
398 quad(const unsigned int i) const;
399
403
410
445 void
447 std::vector<types::global_dof_index> &dof_indices,
448 const types::fe_index fe_index = numbers::invalid_fe_index) const;
449
456 void
458 const int level,
459 std::vector<types::global_dof_index> &dof_indices,
460 const types::fe_index fe_index = numbers::invalid_fe_index) const;
461
465 void
467 const int level,
468 const std::vector<types::global_dof_index> &dof_indices,
470
494 const unsigned int vertex,
495 const unsigned int i,
496 const types::fe_index fe_index = numbers::invalid_fe_index) const;
497
505 const int level,
506 const unsigned int vertex,
507 const unsigned int i,
508 const types::fe_index fe_index = numbers::invalid_fe_index) const;
509
538 dof_index(const unsigned int i,
539 const types::fe_index fe_index = numbers::invalid_fe_index) const;
540
545 mg_dof_index(const int level, const unsigned int i) const;
546
550
557
568 unsigned int
570
579 nth_active_fe_index(const unsigned int n) const;
580
587 std::set<types::fe_index>
589
599 bool
600 fe_index_is_active(const types::fe_index fe_index) const;
601
608 get_fe(const types::fe_index fe_index) const;
609
613
620 "This accessor object has not been "
621 "associated with any DoFHandler object.");
654
655protected:
660
661public:
675 template <int structdim2, int dim2, int spacedim2, bool level_dof_access2>
676 bool
679
683 template <int structdim2, int dim2, int spacedim2, bool level_dof_access2>
684 bool
687
688protected:
692 void
694
713 void
715 const unsigned int i,
716 const types::global_dof_index index,
717 const types::fe_index fe_index = numbers::invalid_fe_index) const;
718
719 void
720 set_mg_dof_index(const int level,
721 const unsigned int i,
722 const types::global_dof_index index) const;
723
724 void
726 const int level,
727 const unsigned int vertex,
728 const unsigned int i,
729 const types::global_dof_index index,
730 const types::fe_index fe_index = numbers::invalid_fe_index) const;
731
732 // Iterator classes need to be friends because they need to access
733 // operator== and operator!=.
734 template <typename>
735 friend class TriaRawIterator;
736 template <int, int, int, bool>
737 friend class DoFAccessor;
738
739private:
740 // Make the DoFHandler class a friend so that it can call the set_xxx()
741 // functions.
742 friend class DoFHandler<dim, spacedim>;
743
744 friend struct ::internal::DoFHandlerImplementation::Policy::
745 Implementation;
746 friend struct ::internal::DoFHandlerImplementation::Implementation;
747 friend struct ::internal::hp::DoFHandlerImplementation::Implementation;
748 friend struct ::internal::DoFCellAccessorImplementation::Implementation;
749 friend struct ::internal::DoFAccessorImplementation::Implementation;
750};
751
752
753
761template <int spacedim, bool level_dof_access>
762class DoFAccessor<0, 1, spacedim, level_dof_access>
763 : public TriaAccessor<0, 1, spacedim>
764{
765public:
770 static constexpr unsigned int dimension = 1;
771
776 static constexpr unsigned int space_dimension = spacedim;
777
783
788
795
799 DoFAccessor();
800
820 const unsigned int vertex_index,
822
830 const int = 0,
831 const int = 0,
833
846 template <int structdim2, int dim2, int spacedim2>
848
853 template <int structdim2, int dim2, int spacedim2, bool level_dof_access2>
856
861
865 // NOLINTNEXTLINE OSX does not compile with noexcept
867
871 ~DoFAccessor() = default;
872
884
890 default;
891
895
899 const DoFHandler<1, spacedim> &
900 get_dof_handler() const;
901
905 template <bool level_dof_access2>
906 void
907 copy_from(const DoFAccessor<0, 1, spacedim, level_dof_access2> &a);
908
913 void
914 copy_from(const TriaAccessorBase<0, 1, spacedim> &da);
915
922
928 TriaIterator<DoFAccessor<0, 1, spacedim, level_dof_access>>
929 child(const unsigned int c) const;
930
937 typename ::internal::DoFHandlerImplementation::
938 Iterators<1, spacedim, level_dof_access>::line_iterator
939 line(const unsigned int i) const;
940
947 typename ::internal::DoFHandlerImplementation::
948 Iterators<1, spacedim, level_dof_access>::quad_iterator
949 quad(const unsigned int i) const;
950
954
961
994 void
996 std::vector<types::global_dof_index> &dof_indices,
997 const types::fe_index fe_index = numbers::invalid_fe_index) const;
998
1005 void
1007 const int level,
1008 std::vector<types::global_dof_index> &dof_indices,
1009 const types::fe_index fe_index = numbers::invalid_fe_index) const;
1010
1029 types::global_dof_index
1031 const unsigned int vertex,
1032 const unsigned int i,
1033 const types::fe_index fe_index = numbers::invalid_fe_index) const;
1034
1052 types::global_dof_index
1053 dof_index(const unsigned int i,
1054 const types::fe_index fe_index = numbers::invalid_fe_index) const;
1055
1059
1066
1074 unsigned int
1075 n_active_fe_indices() const;
1076
1084 types::fe_index
1085 nth_active_fe_index(const unsigned int n) const;
1086
1095 bool
1096 fe_index_is_active(const types::fe_index fe_index) const;
1097
1103 const FiniteElement<1, spacedim> &
1104 get_fe(const types::fe_index fe_index) const;
1105
1109
1116 "This accessor object has not been "
1117 "associated with any DoFHandler object.");
1150
1151protected:
1156
1160 template <int structdim2, int dim2, int spacedim2, bool level_dof_access2>
1161 bool
1162 operator==(
1163 const DoFAccessor<structdim2, dim2, spacedim2, level_dof_access2> &) const;
1164
1168 template <int structdim2, int dim2, int spacedim2, bool level_dof_access2>
1169 bool
1170 operator!=(
1171 const DoFAccessor<structdim2, dim2, spacedim2, level_dof_access2> &) const;
1172
1176 void
1177 set_dof_handler(DoFHandler<1, spacedim> *dh);
1178
1197 void
1199 const unsigned int i,
1200 const types::global_dof_index index,
1201 const types::fe_index fe_index = numbers::invalid_fe_index) const;
1202
1203 // Iterator classes need to be friends because they need to access
1204 // operator== and operator!=.
1205 template <typename>
1206 friend class TriaRawIterator;
1207
1208
1209 // Make the DoFHandler class a friend so that it can call the set_xxx()
1210 // functions.
1211 friend class DoFHandler<1, spacedim>;
1212
1213 friend struct ::internal::DoFHandlerImplementation::Policy::
1215 friend struct ::internal::DoFHandlerImplementation::Implementation;
1216 friend struct ::internal::hp::DoFHandlerImplementation::Implementation;
1217 friend struct ::internal::DoFCellAccessorImplementation::Implementation;
1218};
1219
1220
1221
1222/* -------------------------------------------------------------------------- */
1223
1224
1245template <int structdim, int dim, int spacedim = dim>
1246class DoFInvalidAccessor : public InvalidAccessor<structdim, dim, spacedim>
1247{
1248public:
1254
1262 DoFInvalidAccessor(const void *parent = nullptr,
1263 const int level = -1,
1264 const int index = -1,
1265 const AccessorData *local_data = nullptr);
1266
1275
1280 template <typename OtherAccessor>
1281 DoFInvalidAccessor(const OtherAccessor &);
1282
1289 dof_index(const unsigned int i,
1290 const types::fe_index fe_index =
1292
1298 void
1300 const unsigned int i,
1302 const types::fe_index fe_index = numbers::invalid_fe_index) const;
1303};
1304
1305
1306
1307/* -------------------------------------------------------------------------- */
1308
1309
1321template <int dimension_, int space_dimension_, bool level_dof_access>
1322class DoFCellAccessor : public DoFAccessor<dimension_,
1323 dimension_,
1324 space_dimension_,
1325 level_dof_access>
1326{
1327public:
1331 static const unsigned int dim = dimension_;
1332
1336 static const unsigned int spacedim = space_dimension_;
1337
1338
1343
1350
1355
1361 dimension_,
1362 space_dimension_,
1363 level_dof_access>>;
1364
1371
1376 const int level,
1377 const int index,
1378 const AccessorData *local_data);
1379
1392 template <int structdim2, int dim2, int spacedim2>
1394
1399 template <int structdim2, int dim2, int spacedim2, bool level_dof_access2>
1402
1408 default;
1409
1415 &&) = default; // NOLINT
1416
1420 ~DoFCellAccessor() = default;
1421
1434 delete;
1435
1440 operator=( // NOLINT
1442 &&) = default; // NOLINT
1443
1447
1458 parent() const;
1459
1466
1473 neighbor(const unsigned int i) const;
1474
1481 periodic_neighbor(const unsigned int i) const;
1482
1489 neighbor_or_periodic_neighbor(const unsigned int i) const;
1490
1497 child(const unsigned int i) const;
1498
1502 boost::container::small_vector<
1507
1515 face(const unsigned int i) const;
1516
1520 boost::container::small_vector<face_iterator,
1523
1531 neighbor_child_on_subface(const unsigned int face_no,
1532 const unsigned int subface_no) const;
1533
1541 periodic_neighbor_child_on_subface(const unsigned int face_no,
1542 const unsigned int subface_no) const;
1543
1547
1554
1572 template <class InputVector, typename number>
1573 void
1574 get_dof_values(const InputVector &values, Vector<number> &local_values) const;
1575
1593 template <typename Number, typename ForwardIterator>
1594 void
1596 ForwardIterator local_values_begin,
1597 ForwardIterator local_values_end) const;
1598
1619 template <class InputVector, typename ForwardIterator>
1620 void
1623 const InputVector &values,
1624 ForwardIterator local_values_begin,
1625 ForwardIterator local_values_end) const;
1626
1651 template <class OutputVector, typename number>
1652 void
1653 set_dof_values(const Vector<number> &local_values,
1654 OutputVector &values) const;
1655
1687 template <typename Number>
1688 void
1690 const ReadVector<Number> &values,
1691 ArrayView<Number> interpolated_values,
1692 const types::fe_index fe_index = numbers::invalid_fe_index) const;
1693
1698 template <typename Number>
1699 void
1701 const ReadVector<Number> &values,
1702 Vector<Number> &interpolated_values,
1703 const types::fe_index fe_index = numbers::invalid_fe_index) const;
1704
1766 template <class OutputVector, typename number>
1767 void
1769 const Vector<number> &local_values,
1770 OutputVector &values,
1772 const bool perform_check = false) const;
1773
1783 template <class OutputVector, typename number>
1784 void
1786 const Vector<number> &local_values,
1787 OutputVector &values,
1788 const types::fe_index fe_index = numbers::invalid_fe_index) const;
1789
1804 template <typename number, typename OutputVector>
1805 void
1807 OutputVector &global_destination) const;
1808
1823 template <typename ForwardIterator, typename OutputVector>
1824 void
1825 distribute_local_to_global(ForwardIterator local_source_begin,
1826 ForwardIterator local_source_end,
1827 OutputVector &global_destination) const;
1828
1842 template <typename ForwardIterator, typename OutputVector>
1843 void
1846 ForwardIterator local_source_begin,
1847 ForwardIterator local_source_end,
1848 OutputVector &global_destination) const;
1849
1856 template <typename number, typename OutputMatrix>
1857 void
1859 OutputMatrix &global_destination) const;
1860
1865 template <typename number, typename OutputMatrix, typename OutputVector>
1866 void
1868 const Vector<number> &local_vector,
1869 OutputMatrix &global_matrix,
1870 OutputVector &global_vector) const;
1871
1875
1879
1883
1896 void
1898 std::vector<types::global_dof_index> &dof_indices) const;
1899
1931 void
1932 get_dof_indices(std::vector<types::global_dof_index> &dof_indices) const;
1933
1938 void
1939 get_mg_dof_indices(std::vector<types::global_dof_index> &dof_indices) const;
1940
1944
1951
1966 get_fe() const;
1967
1995
2022 void
2027
2032 void
2033 set_dof_indices(const std::vector<types::global_dof_index> &dof_indices);
2034
2038 void
2039 set_mg_dof_indices(const std::vector<types::global_dof_index> &dof_indices);
2040
2047
2068
2089
2098 void
2100
2107 bool
2109
2118 void
2123
2124private:
2125 friend struct ::internal::DoFCellAccessorImplementation::Implementation;
2126};
2127
2128
2129template <int structdim, int dim, int spacedim, bool level_dof_access>
2130inline bool
2135
2136
2137
2138template <int structdim, int dim, int spacedim>
2139template <typename OtherAccessor>
2141 const OtherAccessor &)
2142{
2143 Assert(false,
2144 ExcMessage("You are attempting an illegal conversion between "
2145 "iterator/accessor types. The constructor you call "
2146 "only exists to make certain template constructs "
2147 "easier to write as dimension independent code but "
2148 "the conversion is not valid in the current context."));
2149}
2150
2151
2152
2153/*------------------------- Functions: DoFAccessor ---------------------------*/
2154
2155
2156template <int structdim, int dim, int spacedim, bool level_dof_access>
2161
2162
2163
2164template <int structdim, int dim, int spacedim, bool level_dof_access>
2166 const Triangulation<dim, spacedim> *tria,
2167 const int level,
2168 const int index,
2170 : ::internal::DoFAccessorImplementation::
2171 Inheritance<structdim, dim, spacedim>::BaseClass(tria, level, index)
2172 , dof_handler(const_cast<DoFHandler<dim, spacedim> *>(dof_handler))
2173{
2174 Assert(
2175 tria == nullptr || &dof_handler->get_triangulation() == tria,
2176 ExcMessage(
2177 "You can't create a DoF accessor in which the DoFHandler object "
2178 "uses a different triangulation than the one you pass as argument."));
2179}
2180
2181
2182
2183template <int structdim, int dim, int spacedim, bool level_dof_access>
2184template <int structdim2, int dim2, int spacedim2>
2190
2191
2192
2193template <int structdim, int dim, int spacedim, bool level_dof_access>
2194template <int structdim2, int dim2, int spacedim2, bool level_dof_access2>
2197 : BaseClass(other)
2198 , dof_handler(nullptr)
2199{
2200 Assert(false,
2201 ExcMessage(
2202 "You are trying to assign iterators that are incompatible. "
2203 "The reason for incompatibility is that they refer to objects of "
2204 "different dimensionality (e.g., assigning a line iterator "
2205 "to a quad iterator)."));
2206}
2207
2208
2209
2210template <int structdim, int dim, int spacedim, bool level_dof_access>
2211template <bool level_dof_access2>
2217
2218
2219
2220template <int structdim, int dim, int spacedim, bool level_dof_access>
2221inline void
2228
2229
2230
2231template <int structdim, int dim, int spacedim, bool level_dof_access>
2232inline const DoFHandler<dim, spacedim> &
2238
2239
2240
2241template <int structdim, int dim, int spacedim, bool level_dof_access>
2242inline void
2249
2250
2251
2252template <int structdim, int dim, int spacedim, bool level_dof_access>
2253template <bool level_dof_access2>
2254inline void
2261
2262
2263
2264template <int structdim, int dim, int spacedim, bool level_dof_access>
2265template <int structdim2, int dim2, int spacedim2, bool level_dof_access2>
2266inline bool
2274
2275
2276
2277template <int structdim, int dim, int spacedim, bool level_dof_access>
2278template <int structdim2, int dim2, int spacedim2, bool level_dof_access2>
2279inline bool
2287
2288
2289
2290template <int structdim, int dim, int spacedim, bool level_dof_access>
2293 const unsigned int i) const
2294{
2295 Assert(static_cast<unsigned int>(this->level()) <
2296 this->dof_handler->object_dof_indices.size(),
2297 ExcMessage("DoFHandler not initialized"));
2298
2301
2303 *t, this->dof_handler);
2304 return q;
2305}
2306
2307
2308namespace internal
2309{
2310 namespace DoFAccessorImplementation
2311 {
2316 template <int structdim, int dim, int spacedim, bool level_dof_access>
2320 const types::fe_index fe_index)
2321 {
2322 if (cell.get_dof_handler().has_hp_capabilities() == false)
2323 {
2324 // No hp enabled, and the argument is at its default value -> we
2325 // can translate to the default active fe index
2326 Assert(
2327 (fe_index == numbers::invalid_fe_index) ||
2329 ExcMessage(
2330 "It is not possible to specify a FE index if no hp support is used!"));
2331
2333 }
2334 else
2335 {
2336 // Otherwise: If anything other than the default is provided by
2337 // the caller, then we should take just that. As an exception, if
2338 // we are on a cell (rather than a face/edge/vertex), then we know
2339 // that there is only one active fe index on this cell and we can
2340 // use that:
2341 if ((dim == structdim) && (fe_index == numbers::invalid_fe_index))
2342 {
2344
2345 return cell.nth_active_fe_index(0);
2346 }
2347
2348 Assert((fe_index != numbers::invalid_fe_index),
2349 ExcMessage(
2350 "You need to specify a FE index if hp support is used!"));
2351
2352 return fe_index;
2353 }
2354 }
2355
2361 {
2371 boost::container::small_vector<::types::global_dof_index, 100>;
2372
2383 template <int dim,
2384 int spacedim,
2385 int structdim,
2386 typename GlobalIndexType,
2387 typename DoFPProcessor>
2388 static void
2390 const unsigned int obj_level,
2391 const unsigned int obj_index,
2392 const types::fe_index fe_index,
2393 const unsigned int local_index,
2394 const std::integral_constant<int, structdim> &,
2395 GlobalIndexType &global_index,
2396 const DoFPProcessor &process)
2397 {
2398 Assert(structdim == dim || obj_level == 0, ExcNotImplemented());
2399
2400 // 1) no hp used -> fe_index == 0
2401 if (dof_handler.hp_capability_enabled == false)
2402 {
2403 AssertDimension(fe_index,
2405
2406 process(
2407 dof_handler.object_dof_indices
2408 [obj_level][structdim]
2409 [dof_handler.object_dof_ptr[obj_level][structdim][obj_index] +
2410 local_index],
2411 global_index);
2412
2413 return;
2414 }
2415
2416 // 2) cell and hp is used -> there is only one fe_index
2417 if (structdim == dim)
2418 {
2419 process(
2420 dof_handler.object_dof_indices
2421 [obj_level][structdim]
2422 [dof_handler.object_dof_ptr[obj_level][structdim][obj_index] +
2423 local_index],
2424 global_index);
2425 return;
2426 }
2427
2428 // 3) general entity and hp is used
2429 AssertIndexRange(obj_level, dof_handler.object_dof_indices.size());
2430 AssertIndexRange(structdim,
2431 dof_handler.object_dof_indices[obj_level].size());
2432
2434
2435 AssertIndexRange(structdim, dof_handler.hp_object_fe_ptr.size());
2436 AssertIndexRange(obj_index,
2437 dof_handler.hp_object_fe_ptr[structdim].size());
2438
2439 const auto ptr =
2440 std::find(dof_handler.hp_object_fe_indices[structdim].begin() +
2441 dof_handler.hp_object_fe_ptr[structdim][obj_index],
2442 dof_handler.hp_object_fe_indices[structdim].begin() +
2443 dof_handler.hp_object_fe_ptr[structdim][obj_index + 1],
2444 fe_index);
2445
2446 Assert(ptr != dof_handler.hp_object_fe_indices[structdim].begin() +
2447 dof_handler.hp_object_fe_ptr[structdim][obj_index + 1],
2448 ExcMessage(
2449 "You are requesting an active FE index that is not assigned "
2450 "to any of the cells connected to this entity."));
2451
2452 const types::fe_index fe_index_ =
2453 std::distance(dof_handler.hp_object_fe_indices[structdim].begin() +
2454 dof_handler.hp_object_fe_ptr[structdim][obj_index],
2455 ptr);
2456
2458 dof_handler.hp_capability_enabled ?
2459 (dof_handler.hp_object_fe_ptr[structdim][obj_index] + fe_index_) :
2460 obj_index,
2461 dof_handler.object_dof_ptr[obj_level][structdim].size());
2462
2464 dof_handler.object_dof_ptr
2465 [obj_level][structdim]
2466 [dof_handler.hp_capability_enabled ?
2467 (dof_handler.hp_object_fe_ptr[structdim][obj_index] +
2468 fe_index_) :
2469 obj_index] +
2470 local_index,
2471 dof_handler.object_dof_indices[obj_level][structdim].size());
2472
2473 process(dof_handler.object_dof_indices
2474 [obj_level][structdim]
2475 [dof_handler.object_dof_ptr
2476 [obj_level][structdim]
2477 [dof_handler.hp_capability_enabled ?
2478 (dof_handler.hp_object_fe_ptr[structdim][obj_index] +
2479 fe_index_) :
2480 obj_index] +
2481 local_index],
2482 global_index);
2483 }
2484
2494 template <int dim, int spacedim, int structdim>
2495 static std::pair<unsigned int, unsigned int>
2497 const unsigned int obj_level,
2498 const unsigned int obj_index,
2499 const types::fe_index fe_index,
2500 const std::integral_constant<int, structdim> &)
2501 {
2502 Assert(structdim == dim || obj_level == 0, ExcNotImplemented());
2503
2504 // determine range of dofs in global data structure
2505 // 1) cell
2506 if (structdim == dim)
2507 {
2508 const unsigned int ptr_0 =
2509 dof_handler.object_dof_ptr[obj_level][structdim][obj_index];
2510 const unsigned int length =
2511 dof_handler.get_fe(fe_index).template n_dofs_per_object<dim>(0);
2512
2513 return {ptr_0, length};
2514 }
2515
2516 // 2) hp is not used -> fe_index == 0
2517 if (dof_handler.hp_capability_enabled == false)
2518 {
2519 AssertDimension(fe_index,
2521
2522 const unsigned int ptr_0 =
2523 dof_handler.object_dof_ptr[obj_level][structdim][obj_index];
2524 const unsigned int length =
2525 dof_handler.object_dof_ptr[obj_level][structdim][obj_index + 1] -
2526 ptr_0;
2527
2528 return {ptr_0, length};
2529 }
2530
2531 // 3) hp is used
2532 AssertIndexRange(obj_level, dof_handler.object_dof_indices.size());
2533 AssertIndexRange(structdim,
2534 dof_handler.object_dof_indices[obj_level].size());
2535
2536 AssertIndexRange(structdim, dof_handler.hp_object_fe_ptr.size());
2537 AssertIndexRange(obj_index,
2538 dof_handler.hp_object_fe_ptr[structdim].size());
2539
2540 const auto fe_index_local_ptr =
2541 std::find(dof_handler.hp_object_fe_indices[structdim].begin() +
2542 dof_handler.hp_object_fe_ptr[structdim][obj_index],
2543 dof_handler.hp_object_fe_indices[structdim].begin() +
2544 dof_handler.hp_object_fe_ptr[structdim][obj_index + 1],
2545 fe_index);
2546
2547 Assert(fe_index_local_ptr !=
2548 dof_handler.hp_object_fe_indices[structdim].begin() +
2549 dof_handler.hp_object_fe_ptr[structdim][obj_index + 1],
2550 ExcMessage(
2551 "You tried to call a function accessing DoF indices, but "
2552 "they appear not be available (yet) or inconsistent. "
2553 "Did you call distribute_dofs() first? Alternatively, if "
2554 "you are using different elements on different cells (i.e., "
2555 "you are using the hp capabilities of deal.II), did you "
2556 "change the active_fe_index of a cell since you last "
2557 "called distribute_dofs()?"));
2558
2559 const types::fe_index fe_index_local =
2560 std::distance(dof_handler.hp_object_fe_indices[structdim].begin() +
2561 dof_handler.hp_object_fe_ptr[structdim][obj_index],
2562 fe_index_local_ptr);
2563
2565 dof_handler.hp_object_fe_ptr[structdim][obj_index] + fe_index_local,
2566 dof_handler.object_dof_ptr[obj_level][structdim].size());
2567
2568 const unsigned int ptr_0 =
2569 dof_handler
2570 .object_dof_ptr[obj_level][structdim]
2571 [dof_handler.hp_object_fe_ptr[structdim][obj_index] +
2572 fe_index_local];
2573 const unsigned int ptr_1 =
2574 dof_handler
2575 .object_dof_ptr[obj_level][structdim]
2576 [dof_handler.hp_object_fe_ptr[structdim][obj_index] +
2577 fe_index_local + 1];
2578
2579 return {ptr_0, ptr_1 - ptr_0};
2580 }
2581
2582 template <int dim, int spacedim, int structdim, bool level_dof_access>
2583 static std::pair<unsigned int, unsigned int>
2585 const ::DoFAccessor<structdim, dim, spacedim, level_dof_access>
2586 accessor,
2587 const types::fe_index fe_index)
2588 {
2589 return process_object_range(accessor.get_dof_handler(),
2590 accessor.level(),
2591 accessor.index(),
2592 fe_index,
2593 std::integral_constant<int, structdim>());
2594 }
2595
2596 template <int dim, int spacedim, int structdim>
2597 static std::pair<unsigned int, unsigned int>
2599 const unsigned int)
2600 {
2602
2603 return {0, 0};
2604 }
2605
2606
2607
2616 template <int dim,
2617 int spacedim,
2618 int structdim,
2619 typename DoFProcessor,
2620 typename DoFMapping>
2621 static DEAL_II_ALWAYS_INLINE void
2623 const unsigned int obj_level,
2624 const unsigned int obj_index,
2625 const types::fe_index fe_index,
2626 const DoFMapping &mapping,
2627 const std::integral_constant<int, structdim> &dd,
2628 types::global_dof_index *&dof_indices_ptr,
2629 const DoFProcessor &process)
2630 {
2631 Assert(structdim == dim || obj_level == 0, ExcNotImplemented());
2632
2633 // determine range of dofs in global data structure
2634 const auto range =
2635 process_object_range(dof_handler, obj_level, obj_index, fe_index, dd);
2636 if (range.second == 0)
2637 return;
2638
2639 std::vector<types::global_dof_index> &object_dof_indices =
2640 dof_handler
2641 .object_dof_indices[structdim < dim ? 0 : obj_level][structdim];
2642 AssertIndexRange(range.first, object_dof_indices.size());
2644 object_dof_indices.data() + range.first;
2645
2646 // process dofs
2647 for (unsigned int i = 0; i < range.second; ++i)
2648 {
2649 process(
2650 stored_indices[(structdim == 0 || structdim == dim) ? i :
2651 mapping(i)],
2652 dof_indices_ptr);
2653 if (dof_indices_ptr != nullptr)
2654 ++dof_indices_ptr;
2655 }
2656 }
2657
2658
2659
2670 template <int dim, int spacedim, int structdim>
2671 static void
2673 const unsigned int obj_level,
2674 const unsigned int obj_index,
2675 const types::fe_index fe_index,
2676 const unsigned int local_index,
2677 const std::integral_constant<int, structdim> &dd,
2678 const types::global_dof_index global_index)
2679 {
2680 process_dof_index(dof_handler,
2681 obj_level,
2682 obj_index,
2683 fe_index,
2684 local_index,
2685 dd,
2686 global_index,
2687 [](auto &ptr, const auto &value) { ptr = value; });
2688 }
2689
2690
2701 template <int dim, int spacedim, int structdim>
2704 const unsigned int obj_level,
2705 const unsigned int obj_index,
2706 const types::fe_index fe_index,
2707 const unsigned int local_index,
2708 const std::integral_constant<int, structdim> &dd)
2709 {
2710 types::global_dof_index global_index;
2711 process_dof_index(dof_handler,
2712 obj_level,
2713 obj_index,
2714 fe_index,
2715 local_index,
2716 dd,
2717 global_index,
2718 [](const auto &ptr, auto &value) { value = ptr; });
2719 return global_index;
2720 }
2721
2722
2723 template <int dim, int spacedim>
2726 const int level,
2727 const unsigned int vertex_index,
2728 const unsigned int i)
2729 {
2730 Assert(dof_handler.hp_capability_enabled == false,
2731 ExcMessage(
2732 "DoFHandler in hp-mode does not implement multilevel DoFs."));
2733
2734 return dof_handler.mg_vertex_dofs[vertex_index].access_index(
2735 level, i, dof_handler.get_fe().n_dofs_per_vertex());
2736 }
2737
2738
2739
2749 template <int dim, int spacedim, int structdim>
2750 static unsigned int
2752 const unsigned int obj_level,
2753 const unsigned int obj_index,
2754 const std::integral_constant<int, structdim> &)
2755 {
2756 (void)obj_level;
2757
2758 Assert(structdim == dim || obj_level == 0, ExcNotImplemented());
2759
2760 // 1) no hp used -> fe_index == 0
2761 if (dof_handler.hp_capability_enabled == false)
2762 return 1;
2763
2764 // 2) cell and hp is used -> there is only one fe_index
2765 if (structdim == dim)
2766 return 1;
2767
2768 // 3) general entity and hp is used
2769 AssertIndexRange(structdim, dof_handler.hp_object_fe_ptr.size());
2770 AssertIndexRange(obj_index + 1,
2771 dof_handler.hp_object_fe_ptr[structdim].size());
2772
2773 return dof_handler.hp_object_fe_ptr[structdim][obj_index + 1] -
2774 dof_handler.hp_object_fe_ptr[structdim][obj_index];
2775 }
2776
2777
2778
2788 template <int dim, int spacedim, int structdim>
2789 static types::fe_index
2791 const unsigned int obj_level,
2792 const unsigned int obj_index,
2793 const unsigned int local_index,
2794 const std::integral_constant<int, structdim> &)
2795 {
2796 Assert(structdim == dim || obj_level == 0, ExcNotImplemented());
2797
2798 // for cells only one active FE index available
2799 Assert(((structdim == dim) &&
2801 false,
2803
2804 // 1) no hp used -> fe_index == 0
2805 if (dof_handler.hp_capability_enabled == false)
2807
2808 // 2) cell and hp is used -> there is only one fe_index
2809 if (structdim == dim)
2810 return dof_handler.hp_cell_active_fe_indices[obj_level][obj_index];
2811
2812 // 3) general entity and hp is used
2813 AssertIndexRange(structdim, dof_handler.hp_object_fe_indices.size());
2814 AssertIndexRange(structdim, dof_handler.hp_object_fe_ptr.size());
2815 AssertIndexRange(obj_index,
2816 dof_handler.hp_object_fe_ptr[structdim].size());
2817 AssertIndexRange(dof_handler.hp_object_fe_ptr[structdim][obj_index] +
2818 local_index,
2819 dof_handler.hp_object_fe_indices[structdim].size());
2820
2821 return dof_handler.hp_object_fe_indices
2822 [structdim]
2823 [dof_handler.hp_object_fe_ptr[structdim][obj_index] + local_index];
2824 }
2825
2826
2827
2840 template <int dim, int spacedim, int structdim>
2841 static std::set<types::fe_index>
2843 const unsigned int obj_level,
2844 const unsigned int obj_index,
2845 const std::integral_constant<int, structdim> &t)
2846 {
2847 Assert(structdim == dim || obj_level == 0, ExcNotImplemented());
2848
2849 // 1) no hp used -> fe_index == 0
2850 if (dof_handler.hp_capability_enabled == false)
2852
2853 // 2) cell and hp is used -> there is only one fe_index
2854 if (structdim == dim)
2855 return {dof_handler.hp_cell_active_fe_indices[obj_level][obj_index]};
2856
2857 // 3) general entity and hp is used
2858 std::set<types::fe_index> active_fe_indices;
2859 for (unsigned int i = 0;
2860 i < n_active_fe_indices(dof_handler, obj_level, obj_index, t);
2861 ++i)
2862 active_fe_indices.insert(
2863 nth_active_fe_index(dof_handler, obj_level, obj_index, i, t));
2864 return active_fe_indices;
2865 }
2866
2867
2868
2869 template <int dim, int spacedim, int structdim>
2870 static bool
2872 const unsigned int obj_level,
2873 const unsigned int obj_index,
2874 const types::fe_index fe_index,
2875 const std::integral_constant<int, structdim> &)
2876 {
2877 Assert(structdim == dim || obj_level == 0, ExcNotImplemented());
2878
2879 // 1) no hp used -> fe_index == 0
2880 if (dof_handler.hp_capability_enabled == false)
2882
2883 // 2) cell and hp is used -> there is only one fe_index
2884 if (structdim == dim)
2885 return dof_handler.hp_cell_active_fe_indices[obj_level][obj_index] ==
2886 fe_index;
2887
2888 // 3) general entity and hp is used
2889 return std::find(
2890 dof_handler.hp_object_fe_indices[structdim].begin() +
2891 dof_handler.hp_object_fe_ptr[structdim][obj_index],
2892 dof_handler.hp_object_fe_indices[structdim].begin() +
2893 dof_handler.hp_object_fe_ptr[structdim][obj_index + 1],
2894 fe_index) !=
2895 (dof_handler.hp_object_fe_indices[structdim].begin() +
2896 dof_handler.hp_object_fe_ptr[structdim][obj_index + 1]);
2897 }
2898
2899
2900
2901 template <typename InputVector, typename ForwardIterator>
2902 static void
2903 extract_subvector_to(const InputVector &values,
2904 const types::global_dof_index *cache,
2905 const types::global_dof_index *cache_end,
2906 ForwardIterator local_values_begin)
2907 {
2908 values.extract_subvector_to(cache, cache_end, local_values_begin);
2909 }
2910
2911
2912
2913#ifdef DEAL_II_WITH_TRILINOS
2914 static std::vector<unsigned int>
2916 const types::global_dof_index *v_end)
2917 {
2918 // initialize original index locations
2919 std::vector<unsigned int> idx(v_end - v_begin);
2920 std::iota(idx.begin(), idx.end(), 0u);
2921
2922 // sort indices based on comparing values in v
2923 std::sort(idx.begin(),
2924 idx.end(),
2925 [&v_begin](unsigned int i1, unsigned int i2) {
2926 return *(v_begin + i1) < *(v_begin + i2);
2927 });
2928
2929 return idx;
2930 }
2931
2932
2933
2934# ifdef DEAL_II_TRILINOS_WITH_TPETRA
2935 template <typename ForwardIterator, typename Number, typename MemorySpace>
2936 static void
2939 &values,
2940 const types::global_dof_index *cache_begin,
2941 const types::global_dof_index *cache_end,
2942 ForwardIterator local_values_begin)
2943 {
2944 std::vector<unsigned int> sorted_indices_pos =
2945 sort_indices(cache_begin, cache_end);
2946 const unsigned int cache_size = cache_end - cache_begin;
2947 std::vector<types::global_dof_index> cache_indices(cache_size);
2948 for (unsigned int i = 0; i < cache_size; ++i)
2949 cache_indices[i] = *(cache_begin + sorted_indices_pos[i]);
2950
2951 IndexSet index_set(cache_indices.back() + 1);
2952 index_set.add_indices(cache_indices.begin(), cache_indices.end());
2953 index_set.compress();
2954 LinearAlgebra::ReadWriteVector<Number> read_write_vector(index_set);
2955 read_write_vector.import_elements(values, VectorOperation::insert);
2956
2957 // Copy the elements from read_write_vector and reorder them.
2958 for (unsigned int i = 0; i < cache_size; ++i, ++local_values_begin)
2959 *local_values_begin = read_write_vector[sorted_indices_pos[i]];
2960 }
2961# endif
2962
2963
2964# ifdef DEAL_II_TRILINOS_WITH_EPETRA
2965 template <typename ForwardIterator>
2966 static void
2968 const types::global_dof_index *cache_begin,
2969 const types::global_dof_index *cache_end,
2970 ForwardIterator local_values_begin)
2971 {
2972 std::vector<unsigned int> sorted_indices_pos =
2973 sort_indices(cache_begin, cache_end);
2974 const unsigned int cache_size = cache_end - cache_begin;
2975 std::vector<types::global_dof_index> cache_indices(cache_size);
2976 for (unsigned int i = 0; i < cache_size; ++i)
2977 cache_indices[i] = *(cache_begin + sorted_indices_pos[i]);
2978
2979 IndexSet index_set(cache_indices.back() + 1);
2980 index_set.add_indices(cache_indices.begin(), cache_indices.end());
2981 index_set.compress();
2982 LinearAlgebra::ReadWriteVector<double> read_write_vector(index_set);
2983 read_write_vector.import_elements(values, VectorOperation::insert);
2984
2985 // Copy the elements from read_write_vector and reorder them.
2986 for (unsigned int i = 0; i < cache_size; ++i, ++local_values_begin)
2987 *local_values_begin = read_write_vector[sorted_indices_pos[i]];
2988 }
2989# endif
2990#endif
2991
2996 template <int dim, int spacedim, bool level_dof_access, int structdim>
2997 static unsigned int
2999 const ::DoFAccessor<structdim, dim, spacedim, level_dof_access>
3000 &accessor,
3001 const types::fe_index fe_index_,
3002 const bool count_level_dofs)
3003 {
3004 // note: we cannot rely on the template parameter level_dof_access here,
3005 // since the function get_mg_dof_indices()/set_mg_dof_indices() can be
3006 // called even if level_dof_access==false.
3007 if (count_level_dofs)
3008 {
3009 const auto &fe = accessor.get_fe(fe_index_);
3010
3011 const unsigned int //
3012 dofs_per_vertex = fe.n_dofs_per_vertex(), //
3013 dofs_per_line = fe.n_dofs_per_line(), //
3014 dofs_per_quad = fe.n_dofs_per_quad(0 /*dummy*/), //
3015 dofs_per_hex = fe.n_dofs_per_hex(); //
3016
3017 unsigned int index = 0;
3018
3019 // 1) VERTEX dofs
3020 index += dofs_per_vertex * accessor.n_vertices();
3021
3022 // 2) LINE dofs
3023 if (structdim == 2 || structdim == 3)
3024 index += dofs_per_line * accessor.n_lines();
3025
3026 // 3) FACE dofs
3027 if (structdim == 3)
3028 index += dofs_per_quad * accessor.n_faces();
3029
3030 // 4) INNER dofs
3031 const unsigned int interior_dofs =
3032 structdim == 1 ? dofs_per_line :
3033 (structdim == 2 ? dofs_per_quad : dofs_per_hex);
3034
3035 index += interior_dofs;
3036
3037 return index;
3038 }
3039 else
3040 {
3041 const auto fe_index =
3043 accessor, fe_index_);
3044
3045 unsigned int index = 0;
3046
3047 // 1) VERTEX dofs
3048 for (const auto vertex : accessor.vertex_indices())
3049 index += process_object_range(accessor.get_dof_handler(),
3050 0,
3051 accessor.vertex_index(vertex),
3052 fe_index,
3053 std::integral_constant<int, 0>())
3054 .second;
3055
3056 // 2) LINE dofs
3057 if (structdim == 2 || structdim == 3)
3058 for (const auto line : accessor.line_indices())
3059 index +=
3060 process_object_range(*accessor.line(line), fe_index).second;
3061
3062 // 3) FACE dofs
3063 if (structdim == 3)
3064 for (const auto face : accessor.face_indices())
3065 index +=
3066 process_object_range(*accessor.quad(face), fe_index).second;
3067
3068 // 4) INNER dofs
3069 index += process_object_range(accessor, fe_index).second;
3070
3071 return index;
3072 }
3073 }
3074
3075
3076
3077 // The next few internal helper functions are needed to support various
3078 // DoFIndicesType kinds, e.g. actual vectors of DoFIndices or empty
3079 // types that we use when we only want to work on the internally stored
3080 // DoFs and never extract any number.
3081 template <typename ArrayType>
3082 static unsigned int
3083 get_array_length(const ArrayType &array)
3084 {
3085 return array.size();
3086 }
3087
3088 static unsigned int
3089 get_array_length(const std::tuple<> &)
3090 {
3091 return 0;
3092 }
3093
3094 template <typename ArrayType>
3096 get_array_ptr(const ArrayType &array)
3097 {
3098 return const_cast<types::global_dof_index *>(array.data());
3099 }
3100
3102 get_array_ptr(const std::tuple<> &)
3103 {
3104 return nullptr;
3105 }
3106
3107
3108
3114 template <int dim,
3115 int spacedim,
3116 bool level_dof_access,
3117 int structdim,
3118 typename DoFIndicesType,
3119 typename DoFOperation,
3120 typename DoFProcessor>
3121 static void
3123 const ::DoFAccessor<structdim, dim, spacedim, level_dof_access>
3124 &accessor,
3125 const DoFIndicesType &const_dof_indices,
3126 const types::fe_index fe_index_,
3127 const DoFOperation &dof_operation,
3128 const DoFProcessor &dof_processor,
3129 const bool count_level_dofs)
3130 {
3131 const types::fe_index fe_index =
3133 accessor, fe_index_);
3134
3135 // we cannot rely on the template parameter level_dof_access here, since
3136 // the function get_mg_dof_indices()/set_mg_dof_indices() can be called
3137 // even if level_dof_access==false.
3138 (void)count_level_dofs;
3139
3140 const auto &fe = accessor.get_fe(fe_index);
3141
3142 // we want to pass in rvalue 'std::tuple<>' types as `DoFIndicesType`,
3143 // but we need non-const references for std::vector<> types, so get in
3144 // a const reference here and immediately cast the constness away -
3145 // note that any use of the dereferenced invalid type will result in a
3146 // segfault
3147 types::global_dof_index *dof_indices_ptr =
3148 get_array_ptr(const_dof_indices);
3149 types::global_dof_index *end_dof_indices =
3150 dof_indices_ptr + get_array_length(const_dof_indices);
3151
3152 // 1) VERTEX dofs, only step into the functions if we actually have
3153 // DoFs on them
3154 if (fe.n_dofs_per_vertex() > 0)
3155 for (const auto vertex : accessor.vertex_indices())
3156 dof_operation.process_vertex_dofs(*accessor.dof_handler,
3157 accessor.vertex_index(vertex),
3158 fe_index,
3159 dof_indices_ptr,
3160 dof_processor);
3161
3162 // 2) copy dof numbers from the LINE, accounting for the possibility of
3163 // reversed line orientations.
3164 if (structdim > 1 && fe.n_dofs_per_line() > 0)
3165 {
3166 const auto line_indices = internal::TriaAccessorImplementation::
3167 Implementation::get_line_indices_of_cell(accessor);
3168 const auto line_orientations =
3169 internal::TriaAccessorImplementation::Implementation::
3170 get_line_orientations_of_cell(accessor);
3171
3172 for (const auto line : accessor.line_indices())
3173 {
3174 const auto line_orientation = line_orientations[line];
3175 if (line_orientation == numbers::default_geometric_orientation)
3176 dof_operation.process_dofs(
3177 accessor.get_dof_handler(),
3178 0,
3179 line_indices[line],
3180 fe_index,
3181 [](const auto d) { return d; },
3182 std::integral_constant<int, 1>(),
3183 dof_indices_ptr,
3184 dof_processor);
3185 else
3186 {
3187 Assert(line_orientation ==
3190 dof_operation.process_dofs(
3191 accessor.get_dof_handler(),
3192 0,
3193 line_indices[line],
3194 fe_index,
3195 [&fe, line_orientation](const auto d) {
3196 return fe.adjust_line_dof_index_for_line_orientation(
3197 d, line_orientation);
3198 },
3199 std::integral_constant<int, 1>(),
3200 dof_indices_ptr,
3201 dof_processor);
3202 }
3203 }
3204 }
3205
3206 // 3) copy dof numbers from the QUAD (i.e., 3d faces). Like lines we
3207 // only adjust dof indices (which has some cost) if we are not in the
3208 // default orientation.
3209 if (structdim == 3 && fe.max_dofs_per_quad() > 0)
3210 for (const auto face_no : accessor.face_indices())
3211 {
3212 const auto combined_orientation =
3213 accessor.combined_face_orientation(face_no);
3214 const unsigned int quad_index = accessor.quad_index(face_no);
3215 if (combined_orientation ==
3217 dof_operation.process_dofs(
3218 accessor.get_dof_handler(),
3219 0,
3220 quad_index,
3221 fe_index,
3222 [](const auto d) { return d; },
3223 std::integral_constant<int, 2>(),
3224 dof_indices_ptr,
3225 dof_processor);
3226 else
3227 dof_operation.process_dofs(
3228 accessor.get_dof_handler(),
3229 0,
3230 quad_index,
3231 fe_index,
3232 [&](const auto d) {
3233 return fe.adjust_quad_dof_index_for_face_orientation(
3234 d, face_no, combined_orientation);
3235 },
3236 std::integral_constant<int, 2>(),
3237 dof_indices_ptr,
3238 dof_processor);
3239 }
3240
3241 // 4) INNER dofs (i.e., line dofs in 1d, quad dofs in 2d, or hex dofs in
3242 // 3d) - here we need to make sure that the shortcut to not run the
3243 // function does not miss the faces of wedge and pyramid elements where
3244 // n_dofs_per_object might not return the largest possible value
3245 if (((dim == 3 && structdim == 2) ?
3246 fe.max_dofs_per_quad() :
3247 fe.template n_dofs_per_object<structdim>()) > 0)
3248 dof_operation.process_dofs(
3249 accessor.get_dof_handler(),
3250 accessor.level(),
3251 accessor.index(),
3252 fe_index,
3253 [&](const auto d) { return d; },
3254 std::integral_constant<int, structdim>(),
3255 dof_indices_ptr,
3256 dof_processor);
3257
3258 if (dof_indices_ptr != nullptr)
3259 {
3260 AssertDimension(n_dof_indices(accessor, fe_index, count_level_dofs),
3261 dof_indices_ptr - get_array_ptr(const_dof_indices));
3262 }
3263
3264 // PM: This is a part that should not be reached since it indicates that
3265 // an object (and/or its subobjects) is not active. However,
3266 // unfortunately this function is called by
3267 // DoFTools::set_periodicity_constraints() indirectly by
3268 // get_dof_indices() also for artificial faces to determine if a face
3269 // is artificial.
3271 for (; dof_indices_ptr < end_dof_indices; ++dof_indices_ptr)
3272 dof_processor(invalid_index, dof_indices_ptr);
3273 }
3274
3275
3276
3281 template <int dim, int spacedim>
3283 {
3287 template <typename DoFProcessor>
3290 const unsigned int vertex_index,
3291 const types::fe_index fe_index,
3292 types::global_dof_index *&dof_indices_ptr,
3293 const DoFProcessor &dof_processor) const
3294 {
3296 dof_handler,
3297 0,
3298 vertex_index,
3299 fe_index,
3300 [](const auto d) {
3302 return d;
3303 },
3304 std::integral_constant<int, 0>(),
3305 dof_indices_ptr,
3306 dof_processor);
3307 }
3308
3312 template <int structdim, typename DoFMapping, typename DoFProcessor>
3315 const unsigned int obj_level,
3316 const unsigned int obj_index,
3317 const types::fe_index fe_index,
3318 const DoFMapping &mapping,
3319 const std::integral_constant<int, structdim>,
3320 types::global_dof_index *&dof_indices_ptr,
3321 const DoFProcessor &dof_processor) const
3322 {
3324 dof_handler,
3325 obj_level,
3326 obj_index,
3327 fe_index,
3328 mapping,
3329 std::integral_constant<int, std::min(structdim, dim)>(),
3330 dof_indices_ptr,
3331 dof_processor);
3332 }
3333 };
3334
3335
3336
3341 template <int dim, int spacedim>
3343 {
3347 MGDoFIndexProcessor(const unsigned int level)
3348 : level(level)
3349 {}
3350
3354 template <typename DoFProcessor>
3357 const unsigned int vertex_index,
3358 const types::fe_index,
3359 types::global_dof_index *&dof_indices_ptr,
3360 const DoFProcessor &dof_processor) const
3361 {
3362 const unsigned int n_indices =
3363 dof_handler.get_fe(0).template n_dofs_per_object<0>();
3364 types::global_dof_index *stored_indices =
3365 &dof_handler.mg_vertex_dofs[vertex_index].access_index(level,
3366 0,
3367 n_indices);
3368 for (unsigned int d = 0; d < n_indices; ++d, ++dof_indices_ptr)
3369 dof_processor(stored_indices[d], dof_indices_ptr);
3370 }
3371
3375 template <int structdim, typename DoFMapping, typename DoFProcessor>
3378 const unsigned int,
3379 const unsigned int obj_index,
3380 const types::fe_index fe_index,
3381 const DoFMapping &mapping,
3382 const std::integral_constant<int, structdim>,
3383 types::global_dof_index *&dof_indices_ptr,
3384 const DoFProcessor &dof_processor) const
3385 {
3386 const unsigned int n_indices =
3387 dof_handler.get_fe(0).template n_dofs_per_object<structdim>();
3388 types::global_dof_index *stored_indices = &get_mg_dof_index(
3389 dof_handler,
3390 dof_handler.mg_levels[level],
3391 dof_handler.mg_faces,
3392 obj_index,
3393 fe_index,
3394 0,
3395 std::integral_constant<int, std::min(structdim, dim)>());
3396 for (unsigned int d = 0; d < n_indices; ++d, ++dof_indices_ptr)
3397 dof_processor(stored_indices[structdim < dim ? mapping(d) : d],
3398 dof_indices_ptr);
3399 }
3400
3401 private:
3402 const unsigned int level;
3403 };
3404
3405
3406
3407 template <int dim, int spacedim, bool level_dof_access, int structdim>
3408 static void
3410 const ::DoFAccessor<structdim, dim, spacedim, level_dof_access>
3411 &accessor,
3412 std::vector<types::global_dof_index> &dof_indices,
3413 const types::fe_index fe_index)
3414 {
3416 accessor,
3417 dof_indices,
3418 fe_index,
3420 [](auto stored_index, auto dof_ptr) { *dof_ptr = stored_index; },
3421 false);
3422 }
3423
3424
3425
3426 template <int dim, int spacedim, bool level_dof_access, int structdim>
3427 static void
3429 const ::DoFAccessor<structdim, dim, spacedim, level_dof_access>
3430 &accessor,
3431 const std::vector<types::global_dof_index> &dof_indices,
3432 const types::fe_index fe_index)
3433 {
3434 // Note: this function is as general as `get_dof_indices()`. This
3435 // assert is placed here since it is currently only used by the
3436 // function DoFCellAccessor::set_dof_indices(), which is called by
3437 // internal::DoFHandlerImplementation::Policy::Implementation::distribute_dofs().
3438 // In the case of new use cases, this assert can be removed.
3439 Assert(
3440 dim == structdim,
3441 ExcMessage(
3442 "This function is intended to be used for DoFCellAccessor, i.e., "
3443 "dimension == structdim."));
3444
3446 accessor,
3447 dof_indices,
3448 fe_index,
3450 [](auto &stored_index, auto dof_ptr) { stored_index = *dof_ptr; },
3451 false);
3452 }
3453
3454
3455
3456 template <int dim, int spacedim, bool level_dof_access, int structdim>
3457 static void
3459 const ::DoFAccessor<structdim, dim, spacedim, level_dof_access>
3460 &accessor,
3461 const int level,
3462 std::vector<types::global_dof_index> &dof_indices,
3463 const types::fe_index fe_index)
3464 {
3466 ExcMessage("MG DoF indices cannot be queried in hp case"));
3468 accessor,
3469 dof_indices,
3470 fe_index,
3472 [](auto stored_index, auto dof_ptr) { *dof_ptr = stored_index; },
3473 true);
3474 }
3475
3476
3477
3478 template <int dim, int spacedim, bool level_dof_access, int structdim>
3479 static void
3481 const ::DoFAccessor<structdim, dim, spacedim, level_dof_access>
3482 &accessor,
3483 const int level,
3484 const std::vector<types::global_dof_index> &dof_indices,
3485 const types::fe_index fe_index)
3486 {
3488 ExcMessage("MG DoF indices cannot be queried in hp case"));
3489
3490 // Note: this function is as general as `get_mg_dof_indices()`. This
3491 // assert is placed here since it is currently only used by the
3492 // function DoFCellAccessor::set_mg_dof_indices(), which is called by
3493 // internal::DoFHandlerImplementation::Policy::Implementation::distribute_mg_dofs().
3494 // In the case of new use cases, this assert can be removed.
3495 Assert(dim == structdim,
3496 ExcMessage("This function is intended to be used for "
3497 "DoFCellAccessor, i.e., dimension == structdim."));
3498
3500 accessor,
3501 dof_indices,
3502 fe_index,
3504 [](auto &stored_index, auto dof_ptr) { stored_index = *dof_ptr; },
3505 true);
3506 }
3507
3508
3509
3510 template <int dim, int spacedim>
3513 const DoFHandler<dim, spacedim> &dof_handler,
3515 &mg_level,
3517 &,
3518 const unsigned int obj_index,
3519 const types::fe_index fe_index,
3520 const unsigned int local_index,
3521 const std::integral_constant<int, dim>)
3522 {
3523 Assert(dof_handler.hp_capability_enabled == false,
3525
3526 return mg_level->dof_object.access_dof_index(
3527 static_cast<const DoFHandler<dim, spacedim> &>(dof_handler),
3528 obj_index,
3529 fe_index,
3530 local_index);
3531 }
3532
3533
3534
3535 template <int dim, int spacedim, std::enable_if_t<(dim > 1), int> = 0>
3538 const DoFHandler<dim, spacedim> &dof_handler,
3540 &,
3542 &mg_faces,
3543 const unsigned int obj_index,
3544 const types::fe_index fe_index,
3545 const unsigned int local_index,
3546 const std::integral_constant<int, 1>)
3547 {
3548 return mg_faces->lines.access_dof_index(
3549 static_cast<const DoFHandler<dim, spacedim> &>(dof_handler),
3550 obj_index,
3551 fe_index,
3552 local_index);
3553 }
3554
3555
3556
3557 template <int spacedim>
3560 const DoFHandler<3, spacedim> &dof_handler,
3562 &,
3564 &mg_faces,
3565 const unsigned int obj_index,
3566 const types::fe_index fe_index,
3567 const unsigned int local_index,
3568 const std::integral_constant<int, 2>)
3569 {
3570 Assert(dof_handler.hp_capability_enabled == false,
3572 return mg_faces->quads.access_dof_index(
3573 static_cast<const DoFHandler<3, spacedim> &>(dof_handler),
3574 obj_index,
3575 fe_index,
3576 local_index);
3577 }
3578 };
3579
3580
3581
3582 template <int dim, int spacedim, bool level_dof_access>
3583 void
3585 const ::DoFCellAccessor<dim, spacedim, level_dof_access> &accessor,
3587 const unsigned int fe_index);
3588 } // namespace DoFAccessorImplementation
3589} // namespace internal
3590
3591
3592
3593template <int structdim, int dim, int spacedim, bool level_dof_access>
3596 const unsigned int i,
3597 const types::fe_index fe_index_) const
3598{
3599 const auto fe_index =
3601 fe_index_);
3602
3603 // access the respective DoF
3604 return ::internal::DoFAccessorImplementation::Implementation::
3605 get_dof_index(*this->dof_handler,
3606 this->level(),
3607 this->index(),
3608 fe_index,
3609 i,
3610 std::integral_constant<int, structdim>());
3611}
3612
3613
3614template <int structdim, int dim, int spacedim, bool level_dof_access>
3617 const int level,
3618 const unsigned int i) const
3619{
3621 *this->dof_handler,
3622 this->dof_handler->mg_levels[level],
3623 this->dof_handler->mg_faces,
3624 this->index(),
3625 0,
3626 i,
3627 std::integral_constant<int, structdim>());
3628}
3629
3630
3631template <int structdim, int dim, int spacedim, bool level_dof_access>
3632inline void
3634 const unsigned int i,
3635 const types::global_dof_index index,
3636 const types::fe_index fe_index_) const
3637{
3638 const auto fe_index =
3640 fe_index_);
3641
3642 // access the respective DoF
3644 *this->dof_handler,
3645 this->level(),
3646 this->index(),
3647 fe_index,
3648 i,
3649 std::integral_constant<int, structdim>(),
3650 index);
3651}
3652
3653
3654
3655template <int structdim, int dim, int spacedim, bool level_dof_access>
3656inline void
3658 const int level,
3659 const unsigned int i,
3660 const types::global_dof_index index) const
3661{
3663 *this->dof_handler,
3664 this->dof_handler->mg_levels[level],
3665 this->dof_handler->mg_faces,
3666 this->index(),
3667 0,
3668 i,
3669 std::integral_constant<int, structdim>()) = index;
3670}
3671
3672
3673
3674template <int structdim, int dim, int spacedim, bool level_dof_access>
3675inline unsigned int
3677 const
3678{
3679 // access the respective DoF
3680 return ::internal::DoFAccessorImplementation::Implementation::
3681 n_active_fe_indices(*this->dof_handler,
3682 this->level(),
3683 this->index(),
3684 std::integral_constant<int, structdim>());
3685}
3686
3687
3688
3689template <int structdim, int dim, int spacedim, bool level_dof_access>
3690inline types::fe_index
3692 const unsigned int n) const
3693{
3694 // access the respective DoF
3695 return ::internal::DoFAccessorImplementation::Implementation::
3696 nth_active_fe_index(*this->dof_handler,
3697 this->level(),
3698 this->index(),
3699 n,
3700 std::integral_constant<int, structdim>());
3701}
3702
3703
3704
3705template <int structdim, int dim, int spacedim, bool level_dof_access>
3706inline std::set<types::fe_index>
3708 const
3709{
3710 std::set<types::fe_index> active_fe_indices;
3711 for (unsigned int i = 0; i < n_active_fe_indices(); ++i)
3712 active_fe_indices.insert(nth_active_fe_index(i));
3713 return active_fe_indices;
3714}
3715
3716
3717
3718template <int structdim, int dim, int spacedim, bool level_dof_access>
3719inline bool
3721 const types::fe_index fe_index) const
3722{
3723 // access the respective DoF
3724 return ::internal::DoFAccessorImplementation::Implementation::
3725 fe_index_is_active(*this->dof_handler,
3726 this->level(),
3727 this->index(),
3728 fe_index,
3729 std::integral_constant<int, structdim>());
3730}
3731
3732
3733
3734template <int structdim, int dim, int spacedim, bool level_dof_access>
3737 const unsigned int vertex,
3738 const unsigned int i,
3739 const types::fe_index fe_index_) const
3740{
3741 const types::fe_index fe_index =
3742 (((this->dof_handler->hp_capability_enabled == false) &&
3743 (fe_index_ == numbers::invalid_fe_index)) ?
3744 // No hp enabled, and the argument is at its default value -> we
3745 // can translate to the default active fe index
3747 // Otherwise: If anything other than the default is provided by
3748 // the caller, then we should take just that. As an exception, if
3749 // we are on a cell (rather than a face/edge/vertex), then we know
3750 // that there is only one active fe index on this cell and we can
3751 // use that:
3752 ((dim == structdim) && (fe_index_ == numbers::invalid_fe_index) ?
3753 this->nth_active_fe_index(0) :
3754 fe_index_));
3755
3756 return ::internal::DoFAccessorImplementation::Implementation::
3757 get_dof_index(*this->dof_handler,
3758 0,
3759 this->vertex_index(vertex),
3760 fe_index,
3761 i,
3762 std::integral_constant<int, 0>());
3763}
3764
3765
3766template <int structdim, int dim, int spacedim, bool level_dof_access>
3769 const int level,
3770 const unsigned int vertex,
3771 const unsigned int i,
3772 const types::fe_index fe_index_) const
3773{
3774 const auto fe_index =
3776 fe_index_);
3777 (void)fe_index;
3778 Assert(this->dof_handler != nullptr, ExcInvalidObject());
3779 Assert(this->dof_handler->mg_vertex_dofs.size() > 0,
3780 ExcMessage("Multigrid DoF indices can only be accessed after "
3781 "DoFHandler::distribute_mg_dofs() has been called!"));
3782 AssertIndexRange(vertex, this->n_vertices());
3783 AssertIndexRange(i, this->dof_handler->get_fe(fe_index).n_dofs_per_vertex());
3784
3785 Assert(dof_handler->hp_capability_enabled == false,
3786 ExcMessage(
3787 "DoFHandler in hp-mode does not implement multilevel DoFs."));
3788
3789 return this->dof_handler->mg_vertex_dofs[this->vertex_index(vertex)]
3790 .access_index(level, i, this->dof_handler->get_fe().n_dofs_per_vertex());
3791}
3792
3793
3794
3795template <int structdim, int dim, int spacedim, bool level_dof_access>
3796inline void
3798 set_mg_vertex_dof_index(const int level,
3799 const unsigned int vertex,
3800 const unsigned int i,
3801 const types::global_dof_index index,
3802 const types::fe_index fe_index_) const
3803{
3804 const auto fe_index =
3806 fe_index_);
3807 (void)fe_index;
3808 Assert(this->dof_handler != nullptr, ExcInvalidObject());
3809 AssertIndexRange(vertex, this->n_vertices());
3810 AssertIndexRange(i, this->dof_handler->get_fe(fe_index).n_dofs_per_vertex());
3811
3812 Assert(dof_handler->hp_capability_enabled == false,
3813 ExcMessage(
3814 "DoFHandler in hp-mode does not implement multilevel DoFs."));
3815
3816 this->dof_handler->mg_vertex_dofs[this->vertex_index(vertex)].access_index(
3817 level, i, this->dof_handler->get_fe().n_dofs_per_vertex()) = index;
3818}
3819
3820
3821
3822template <int structdim, int dim, int spacedim, bool level_dof_access>
3823inline const FiniteElement<dim, spacedim> &
3825 const types::fe_index fe_index) const
3826{
3827 Assert(fe_index_is_active(fe_index) == true,
3828 ExcMessage("This function can only be called for active FE indices"));
3829
3830 return this->dof_handler->get_fe(fe_index);
3831}
3832
3833
3834
3835template <int structdim, int dim, int spacedim, bool level_dof_access>
3836inline typename ::internal::DoFHandlerImplementation::
3837 Iterators<dim, spacedim, level_dof_access>::line_iterator
3839 const unsigned int i) const
3840{
3841 // if we are asking for a particular line and this object refers to
3842 // a line, then the only valid index is i==0 and we should return
3843 // *this
3844 if (structdim == 1)
3845 {
3846 Assert(i == 0,
3847 ExcMessage("You can only ask for line zero if the "
3848 "current object is a line itself."));
3849 return typename ::internal::DoFHandlerImplementation::
3850 Iterators<dim, spacedim, level_dof_access>::cell_iterator(
3851 &this->get_triangulation(),
3852 this->level(),
3853 this->index(),
3854 &this->get_dof_handler());
3855 }
3856
3857 // otherwise we need to be in structdim>=2
3858 Assert(structdim > 1, ExcImpossibleInDim(structdim));
3859 Assert(dim > 1, ExcImpossibleInDim(dim));
3860
3861 // checking of 'i' happens in line_index(i)
3862 return typename ::internal::DoFHandlerImplementation::
3863 Iterators<dim, spacedim, level_dof_access>::line_iterator(
3864 this->tria,
3865 0, // only sub-objects are allowed, which have no level
3866 this->line_index(i),
3867 this->dof_handler);
3868}
3869
3870
3871template <int structdim, int dim, int spacedim, bool level_dof_access>
3872inline typename ::internal::DoFHandlerImplementation::
3873 Iterators<dim, spacedim, level_dof_access>::quad_iterator
3875 const unsigned int i) const
3876{
3877 // if we are asking for a
3878 // particular quad and this object
3879 // refers to a quad, then the only
3880 // valid index is i==0 and we
3881 // should return *this
3882 if (structdim == 2)
3883 {
3884 Assert(i == 0,
3885 ExcMessage("You can only ask for quad zero if the "
3886 "current object is a quad itself."));
3887 return typename ::internal::DoFHandlerImplementation::
3888 Iterators<dim, spacedim>::cell_iterator(&this->get_triangulation(),
3889 this->level(),
3890 this->index(),
3891 &this->get_dof_handler());
3892 }
3893
3894 // otherwise we need to be in structdim>=3
3895 Assert(structdim > 2, ExcImpossibleInDim(structdim));
3896 Assert(dim > 2, ExcImpossibleInDim(dim));
3897
3898 // checking of 'i' happens in quad_index(i)
3899 return typename ::internal::DoFHandlerImplementation::
3900 Iterators<dim, spacedim, level_dof_access>::quad_iterator(
3901 this->tria,
3902 0, // only sub-objects are allowed, which have no level
3903 this->quad_index(i),
3904 this->dof_handler);
3905}
3906
3907
3908/*----------------- Functions: DoFAccessor<0,1,spacedim> --------------------*/
3909
3910
3911template <int spacedim, bool level_dof_access>
3916
3917
3918
3919template <int spacedim, bool level_dof_access>
3928
3929
3930
3931template <int spacedim, bool level_dof_access>
3934 const int level,
3935 const int index,
3937 // This is the constructor signature for "ordinary" (non-vertex)
3938 // accessors and we shouldn't be calling it altogether. But it is also
3939 // the constructor that the default-constructor of TriaRawIterator
3940 // calls when default-constructing an iterator object. If so, this
3941 // happens with level==-2 and index==-2, and this is the only case we
3942 // would like to support. We do this by just forwarding to the
3943 // other constructor of this class, and then asserting the condition
3944 // on level and index.
3945 : DoFAccessor<0, 1, spacedim, level_dof_access>(
3946 tria,
3947 TriaAccessor<0, 1, spacedim>::interior_vertex,
3948 0U,
3950{
3951 (void)level;
3952 (void)index;
3953 Assert((tria == nullptr) && (level == -2) && (index == -2) &&
3954 (dof_handler == nullptr),
3955 ExcMessage(
3956 "This constructor can not be called for face iterators in 1d, "
3957 "except to default-construct iterator objects."));
3958}
3959
3960
3961
3962template <int spacedim, bool level_dof_access>
3963template <int structdim2, int dim2, int spacedim2>
3969
3970
3971
3972template <int spacedim, bool level_dof_access>
3973template <int structdim2, int dim2, int spacedim2, bool level_dof_access2>
3979
3980
3981
3982template <int spacedim, bool level_dof_access>
3983inline void
3990
3991
3992
3993template <int spacedim, bool level_dof_access>
3994inline void
3996 const unsigned int /*i*/,
3997 const types::global_dof_index /*index*/,
3998 const types::fe_index /*fe_index*/) const
3999{
4001}
4002
4003
4004
4005template <int spacedim, bool level_dof_access>
4006inline const DoFHandler<1, spacedim> &
4011
4012
4013
4014template <int spacedim, bool level_dof_access>
4015inline void
4017 std::vector<types::global_dof_index> &dof_indices,
4018 const types::fe_index fe_index_) const
4019{
4020 const auto fe_index =
4022 fe_index_);
4023
4024 for (unsigned int i = 0; i < dof_indices.size(); ++i)
4025 dof_indices[i] = ::internal::DoFAccessorImplementation::
4026 Implementation::get_dof_index(*dof_handler,
4027 0,
4028 this->global_vertex_index,
4029 fe_index,
4030 i,
4031 std::integral_constant<int, 0>());
4032}
4033
4034
4035
4036template <int spacedim, bool level_dof_access>
4037inline void
4039 const int level,
4040 std::vector<types::global_dof_index> &dof_indices,
4041 const types::fe_index fe_index_) const
4042{
4043 const auto fe_index =
4045 fe_index_);
4046 (void)fe_index;
4048
4049 for (unsigned int i = 0; i < dof_indices.size(); ++i)
4050 dof_indices[i] =
4053}
4054
4055
4056
4057template <int spacedim, bool level_dof_access>
4060 const unsigned int vertex,
4061 const unsigned int i,
4062 const types::fe_index fe_index_) const
4063{
4064 const auto fe_index =
4066 fe_index_);
4067
4068 (void)vertex;
4070 return ::internal::DoFAccessorImplementation::Implementation::
4071 get_dof_index(*dof_handler,
4072 0,
4073 this->global_vertex_index,
4074 fe_index,
4075 i,
4076 std::integral_constant<int, 0>());
4077}
4078
4079
4080
4081template <int spacedim, bool level_dof_access>
4084 const unsigned int i,
4085 const types::fe_index fe_index_) const
4086{
4087 const auto fe_index =
4089 fe_index_);
4090
4091 return ::internal::DoFAccessorImplementation::Implementation::
4092 get_dof_index(*this->dof_handler,
4093 0,
4094 this->vertex_index(0),
4095 fe_index,
4096 i,
4097 std::integral_constant<int, 0>());
4098}
4099
4100
4101
4102template <int spacedim, bool level_dof_access>
4103inline unsigned int
4108
4109
4110
4111template <int spacedim, bool level_dof_access>
4112inline types::fe_index
4114 const unsigned int /*n*/) const
4115{
4116 return 0;
4117}
4118
4119
4120
4121template <int spacedim, bool level_dof_access>
4122inline bool
4124 const types::fe_index /*fe_index*/) const
4125{
4127 return false;
4128}
4129
4130
4131
4132template <int spacedim, bool level_dof_access>
4133inline const FiniteElement<1, spacedim> &
4135 const types::fe_index fe_index) const
4136{
4137 Assert(this->dof_handler != nullptr, ExcInvalidObject());
4138 return dof_handler->get_fe(fe_index);
4139}
4140
4141
4142
4143template <int spacedim, bool level_dof_access>
4144inline void
4151
4152
4153
4154template <int spacedim, bool level_dof_access>
4155template <bool level_dof_access2>
4156inline void
4163
4164
4165
4166template <int spacedim, bool level_dof_access>
4173
4174
4175
4176template <int spacedim, bool level_dof_access>
4177inline typename ::internal::DoFHandlerImplementation::
4178 Iterators<1, spacedim, level_dof_access>::line_iterator
4180 const unsigned int /*c*/) const
4181{
4183 return typename ::internal::DoFHandlerImplementation::
4184 Iterators<1, spacedim, level_dof_access>::line_iterator();
4185}
4186
4187
4188
4189template <int spacedim, bool level_dof_access>
4190inline typename ::internal::DoFHandlerImplementation::
4191 Iterators<1, spacedim, level_dof_access>::quad_iterator
4193 const unsigned int /*c*/) const
4194{
4196 return typename ::internal::DoFHandlerImplementation::
4197 Iterators<1, spacedim, level_dof_access>::quad_iterator();
4198}
4199
4200
4201
4202template <int spacedim, bool level_dof_access>
4203template <int structdim2, int dim2, int spacedim2, bool level_dof_access2>
4204inline bool
4212
4213
4214
4215template <int spacedim, bool level_dof_access>
4216template <int structdim2, int dim2, int spacedim2, bool level_dof_access2>
4217inline bool
4225
4226
4227
4228/*------------------------- Functions: DoFCellAccessor -----------------------*/
4229
4230
4231namespace internal
4232{
4234 {
4240 {
4245 template <int dim, int spacedim, bool level_dof_access>
4246 static types::fe_index
4249 {
4250 if (accessor.dof_handler->hp_capability_enabled == false)
4252
4253 Assert(accessor.dof_handler != nullptr,
4254 (typename std::decay_t<decltype(accessor)>::ExcInvalidObject()));
4255 Assert(static_cast<unsigned int>(accessor.level()) <
4256 accessor.dof_handler->hp_cell_future_fe_indices.size(),
4257 ExcMessage("DoFHandler not initialized"));
4258
4259 return accessor.dof_handler
4260 ->hp_cell_active_fe_indices[accessor.level()][accessor.present_index];
4261 }
4262
4263
4264
4269 template <int dim, int spacedim, bool level_dof_access>
4270 static void
4273 const types::fe_index i)
4274 {
4275 if (accessor.dof_handler->hp_capability_enabled == false)
4276 {
4278 return;
4279 }
4280
4281 Assert(accessor.dof_handler != nullptr,
4282 (typename std::decay_t<decltype(accessor)>::ExcInvalidObject()));
4283 Assert(static_cast<unsigned int>(accessor.level()) <
4284 accessor.dof_handler->hp_cell_future_fe_indices.size(),
4285 ExcMessage("DoFHandler not initialized"));
4287 ExcMessage("Invalid finite element index."));
4288
4289 accessor.dof_handler
4290 ->hp_cell_active_fe_indices[accessor.level()]
4291 [accessor.present_index] = i;
4292 }
4293
4294
4295
4300 template <int dim, int spacedim, bool level_dof_access>
4301 static types::fe_index
4304 {
4305 if (accessor.dof_handler->hp_capability_enabled == false)
4307
4308 Assert(accessor.dof_handler != nullptr,
4309 (typename std::decay_t<decltype(accessor)>::ExcInvalidObject()));
4310 Assert(static_cast<unsigned int>(accessor.level()) <
4311 accessor.dof_handler->hp_cell_future_fe_indices.size(),
4312 ExcMessage("DoFHandler not initialized"));
4313
4314 if (future_fe_index_set(accessor))
4315 return accessor.dof_handler
4316 ->hp_cell_future_fe_indices[accessor.level()]
4317 [accessor.present_index];
4318 else
4319 return accessor.dof_handler
4320 ->hp_cell_active_fe_indices[accessor.level()]
4321 [accessor.present_index];
4322 }
4323
4324
4329 template <int dim, int spacedim, bool level_dof_access>
4330 static void
4333 const types::fe_index i)
4334 {
4335 if (accessor.dof_handler->hp_capability_enabled == false)
4336 {
4338 return;
4339 }
4340
4341 Assert(accessor.dof_handler != nullptr,
4342 (typename std::decay_t<decltype(accessor)>::ExcInvalidObject()));
4343 Assert(static_cast<unsigned int>(accessor.level()) <
4344 accessor.dof_handler->hp_cell_future_fe_indices.size(),
4345 ExcMessage("DoFHandler not initialized"));
4347 ExcMessage("Invalid finite element index."));
4348
4349 accessor.dof_handler
4350 ->hp_cell_future_fe_indices[accessor.level()]
4351 [accessor.present_index] = i;
4352 }
4353
4354
4355
4360 template <int dim, int spacedim, bool level_dof_access>
4361 static bool
4364 {
4365 if (accessor.dof_handler->hp_capability_enabled == false)
4366 return false;
4367
4368 Assert(accessor.dof_handler != nullptr,
4369 (typename std::decay_t<decltype(accessor)>::ExcInvalidObject()));
4370 Assert(static_cast<unsigned int>(accessor.level()) <
4371 accessor.dof_handler->hp_cell_future_fe_indices.size(),
4372 ExcMessage("DoFHandler not initialized"));
4373
4374 return accessor.dof_handler
4375 ->hp_cell_future_fe_indices[accessor.level()]
4376 [accessor.present_index] !=
4378 }
4379
4380
4381
4386 template <int dim, int spacedim, bool level_dof_access>
4387 static void
4390 {
4391 if (accessor.dof_handler->hp_capability_enabled == false)
4392 return;
4393
4394 Assert(accessor.dof_handler != nullptr,
4395 (typename std::decay_t<decltype(accessor)>::ExcInvalidObject()));
4396 Assert(static_cast<unsigned int>(accessor.level()) <
4397 accessor.dof_handler->hp_cell_future_fe_indices.size(),
4398 ExcMessage("DoFHandler not initialized"));
4399
4400 accessor.dof_handler
4401 ->hp_cell_future_fe_indices[accessor.level()]
4402 [accessor.present_index] =
4404 }
4405 };
4406 } // namespace DoFCellAccessorImplementation
4407} // namespace internal
4408
4409
4410
4411template <int dimension_, int space_dimension_, bool level_dof_access>
4414 const int level,
4415 const int index,
4416 const AccessorData *local_data)
4417 : DoFAccessor<dimension_, dimension_, space_dimension_, level_dof_access>(
4418 tria,
4419 level,
4420 index,
4421 local_data)
4422{}
4423
4424
4425
4426template <int dimension_, int space_dimension_, bool level_dof_access>
4427template <int structdim2, int dim2, int spacedim2>
4433
4434
4435
4436template <int dimension_, int space_dimension_, bool level_dof_access>
4437template <int structdim2, int dim2, int spacedim2, bool level_dof_access2>
4443
4444
4445
4446template <int dimension_, int space_dimension_, bool level_dof_access>
4447inline TriaIterator<
4450 const unsigned int i) const
4451{
4453 q(this->tria,
4454 this->neighbor_level(i),
4455 this->neighbor_index(i),
4456 this->dof_handler);
4457
4458 if constexpr (running_in_debug_mode())
4459 {
4461 Assert(q->used(), ExcInternalError());
4462 }
4463 return q;
4464}
4465
4466
4467
4468template <int dimension_, int space_dimension_, bool level_dof_access>
4469inline TriaIterator<
4472 const unsigned int i) const
4473{
4475 q(this->tria, this->level() + 1, this->child_index(i), this->dof_handler);
4476
4477 if constexpr (running_in_debug_mode())
4478 {
4480 Assert(q->used(), ExcInternalError());
4481 }
4482 return q;
4483}
4484
4485
4486
4487template <int dimension_, int space_dimension_, bool level_dof_access>
4488inline boost::container::small_vector<
4492 child_iterators() const
4493{
4494 boost::container::small_vector<
4498 child_iterators(this->n_children());
4499
4500 for (unsigned int i = 0; i < this->n_children(); ++i)
4501 child_iterators[i] = this->child(i);
4502
4503 return child_iterators;
4504}
4505
4506
4507
4508template <int dimension_, int space_dimension_, bool level_dof_access>
4509inline TriaIterator<
4512{
4514 q(this->tria, this->level() - 1, this->parent_index(), this->dof_handler);
4515
4516 return q;
4517}
4518
4519
4520
4521namespace internal
4522{
4523 namespace DoFCellAccessorImplementation
4524 {
4525 template <int dim, int spacedim, bool level_dof_access>
4526 inline TriaIterator<
4527 ::DoFAccessor<dim - 1, dim, spacedim, level_dof_access>>
4529 const ::DoFCellAccessor<dim, spacedim, level_dof_access> &cell,
4530 const unsigned int i,
4531 const std::integral_constant<int, 1>)
4532 {
4534 &cell.get_triangulation(),
4535 ((i == 0) && cell.at_boundary(0) ?
4537 ((i == 1) && cell.at_boundary(1) ?
4540 cell.vertex_index(i),
4541 &cell.get_dof_handler());
4542 return ::TriaIterator<
4544 }
4545
4546
4547 template <int dim, int spacedim, bool level_dof_access>
4548 inline TriaIterator<
4549 ::DoFAccessor<dim - 1, dim, spacedim, level_dof_access>>
4551 const ::DoFCellAccessor<dim, spacedim, level_dof_access> &cell,
4552 const unsigned int i,
4553 const std::integral_constant<int, 2>)
4554 {
4555 return cell.line(i);
4556 }
4557
4558
4559 template <int dim, int spacedim, bool level_dof_access>
4560 inline TriaIterator<
4561 ::DoFAccessor<dim - 1, dim, spacedim, level_dof_access>>
4563 const ::DoFCellAccessor<dim, spacedim, level_dof_access> &cell,
4564 const unsigned int i,
4565 const std::integral_constant<int, 3>)
4566 {
4567 return cell.quad(i);
4568 }
4569 } // namespace DoFCellAccessorImplementation
4570} // namespace internal
4571
4572
4573
4574template <int dimension_, int space_dimension_, bool level_dof_access>
4575inline typename DoFCellAccessor<dimension_,
4576 space_dimension_,
4577 level_dof_access>::face_iterator
4579 const unsigned int i) const
4580{
4581 AssertIndexRange(i, this->n_faces());
4582
4583 return ::internal::DoFCellAccessorImplementation::get_face(
4584 *this, i, std::integral_constant<int, dimension_>());
4585}
4586
4587
4588
4589template <int dimension_, int space_dimension_, bool level_dof_access>
4590inline boost::container::small_vector<
4592 face_iterator,
4595 face_iterators() const
4596{
4597 boost::container::small_vector<
4599 face_iterator,
4601 face_iterators(this->n_faces());
4602
4603 for (const unsigned int i : this->face_indices())
4604 face_iterators[i] =
4606 *this, i, std::integral_constant<int, dimension_>());
4607
4608 return face_iterators;
4609}
4610
4611
4612
4613template <int dimension_, int space_dimension_, bool level_dof_access>
4614inline void
4617 std::vector<types::global_dof_index> &dof_indices) const
4618{
4619 if (level_dof_access)
4620 get_mg_dof_indices(dof_indices);
4621 else
4622 get_dof_indices(dof_indices);
4623}
4624
4625
4626
4627template <int dimension_, int space_dimension_, bool level_dof_access>
4628template <class InputVector, typename number>
4629inline void
4631 const InputVector &values,
4632 Vector<number> &local_values) const
4633{
4634 get_dof_values(values, local_values.begin(), local_values.end());
4635}
4636
4637
4638
4639template <int dimension_, int space_dimension_, bool level_dof_access>
4640template <typename Number, typename ForwardIterator>
4641inline void
4643 const ReadVector<Number> &values,
4644 ForwardIterator local_values_begin,
4645 ForwardIterator local_values_end) const
4646{
4647 (void)local_values_end;
4648 Assert(this->is_artificial() == false,
4649 ExcMessage("Can't ask for DoF indices on artificial cells."));
4650 Assert(this->is_active(), ExcMessage("Cell must be active."));
4651 Assert(this->dof_handler != nullptr, typename BaseClass::ExcInvalidObject());
4652
4653 Assert(static_cast<unsigned int>(local_values_end - local_values_begin) ==
4654 this->get_fe().n_dofs_per_cell(),
4656 Assert(values.size() == this->get_dof_handler().n_dofs(),
4658
4660 dof_indices(this->get_fe().n_dofs_per_cell());
4662 *this, dof_indices, this->active_fe_index());
4663
4664 boost::container::small_vector<Number, 100> values_temp(local_values_end -
4665 local_values_begin);
4666 auto view = make_array_view(values_temp.begin(), values_temp.end());
4667 values.extract_subvector_to(make_array_view(dof_indices.begin(),
4668 dof_indices.end()),
4669 view);
4670 using view_type = std::remove_reference_t<decltype(*local_values_begin)>;
4671 ArrayView<view_type> values_view2(&*local_values_begin,
4672 local_values_end - local_values_begin);
4673 std::copy(values_temp.begin(), values_temp.end(), values_view2.begin());
4674}
4675
4676
4677
4678template <int dimension_, int space_dimension_, bool level_dof_access>
4679template <class InputVector, typename ForwardIterator>
4680inline void
4683 const InputVector &values,
4684 ForwardIterator local_values_begin,
4685 ForwardIterator local_values_end) const
4686{
4687 Assert(this->is_artificial() == false,
4688 ExcMessage("Can't ask for DoF indices on artificial cells."));
4689 Assert(this->is_active(), ExcMessage("Cell must be active."));
4690
4691 Assert(static_cast<unsigned int>(local_values_end - local_values_begin) ==
4692 this->get_fe().n_dofs_per_cell(),
4694 Assert(values.size() == this->get_dof_handler().n_dofs(),
4696
4697
4699 dof_indices(this->get_fe().n_dofs_per_cell());
4701 *this, dof_indices, this->active_fe_index());
4702
4703 constraints.get_dof_values(values,
4704 dof_indices.data(),
4705 local_values_begin,
4706 local_values_end);
4707}
4708
4709
4710
4711template <int dimension_, int space_dimension_, bool level_dof_access>
4712template <class OutputVector, typename number>
4713inline void
4715 const Vector<number> &local_values,
4716 OutputVector &values) const
4717{
4718 Assert(this->is_artificial() == false,
4719 ExcMessage("Can't ask for DoF indices on artificial cells."));
4720 Assert(this->is_active(), ExcMessage("Cell must be active."));
4721
4722 Assert(static_cast<unsigned int>(local_values.size()) ==
4723 this->get_fe().n_dofs_per_cell(),
4725 Assert(values.size() == this->get_dof_handler().n_dofs(),
4727
4728
4729 Assert(this->dof_handler != nullptr, typename BaseClass::ExcInvalidObject());
4731 dof_indices(this->get_fe().n_dofs_per_cell());
4733 *this, dof_indices, this->active_fe_index());
4734
4735 for (unsigned int i = 0; i < this->get_fe().n_dofs_per_cell(); ++i)
4737 dof_indices[i],
4738 values);
4739}
4740
4741
4742
4743template <int dimension_, int space_dimension_, bool level_dof_access>
4746{
4747 Assert(this->dof_handler != nullptr, typename BaseClass::ExcInvalidObject());
4748 Assert((this->dof_handler->hp_capability_enabled == false) ||
4749 this->is_active(),
4750 ExcMessage(
4751 "For DoFHandler objects in hp-mode, finite elements are only "
4752 "associated with active cells. Consequently, you can not ask "
4753 "for the active finite element on cells with children."));
4754
4755 const auto &fe = this->dof_handler->get_fe(active_fe_index());
4756
4757 Assert(this->reference_cell() == fe.reference_cell(),
4758 ExcMessage(
4759 "The reference-cell type used on this cell (" +
4760 this->reference_cell().to_string() +
4761 ") does not match the reference-cell type of the finite element "
4762 "associated with this cell (" +
4763 fe.reference_cell().to_string() +
4764 "). "
4765 "Did you accidentally use simplex elements on hypercube meshes "
4766 "(or the other way around), or are you using a mixed mesh and "
4767 "assigned a simplex element to a hypercube cell (or the other "
4768 "way around) via the active_fe_index?"));
4769
4770 return fe;
4771}
4772
4773
4774
4775template <int dimension_, int space_dimension_, bool level_dof_access>
4776inline types::fe_index
4778 active_fe_index() const
4779{
4780 Assert((this->dof_handler->hp_capability_enabled == false) ||
4781 this->is_active(),
4782 ExcMessage(
4783 "You can not ask for the active FE index on a cell that has "
4784 "children because no degrees of freedom are assigned "
4785 "to this cell and, consequently, no finite element "
4786 "is associated with it."));
4787 Assert((this->dof_handler->hp_capability_enabled == false) ||
4788 (this->is_locally_owned() || this->is_ghost()),
4789 ExcMessage("You can only query active FE index information on cells "
4790 "that are either locally owned or (after distributing "
4791 "degrees of freedom) are ghost cells."));
4792
4793 return ::internal::DoFCellAccessorImplementation::Implementation::
4794 active_fe_index(*this);
4795}
4796
4797
4798
4799template <int dimension_, int space_dimension_, bool level_dof_access>
4800inline void
4803{
4804 Assert((this->dof_handler->hp_capability_enabled == false) ||
4805 this->is_active(),
4806 ExcMessage("You can not set the active FE index on a cell that has "
4807 "children because no degrees of freedom will be assigned "
4808 "to this cell."));
4809
4810 Assert((this->dof_handler->hp_capability_enabled == false) ||
4811 this->is_locally_owned(),
4812 ExcMessage("You can only set active FE index information on cells "
4813 "that are locally owned. On ghost cells, this information "
4814 "will automatically be propagated from the owning process "
4815 "of that cell, and there is no information at all on "
4816 "artificial cells."));
4817
4819 set_active_fe_index(*this, i);
4820}
4821
4822
4823
4824template <int dimension_, int space_dimension_, bool level_dof_access>
4827 const
4828{
4829 Assert(this->dof_handler != nullptr, typename BaseClass::ExcInvalidObject());
4830 Assert((this->dof_handler->hp_capability_enabled == false) ||
4831 this->is_active(),
4832 ExcMessage(
4833 "For DoFHandler objects in hp-mode, finite elements are only "
4834 "associated with active cells. Consequently, you can not ask "
4835 "for the future finite element on cells with children."));
4836
4837 return this->dof_handler->get_fe(future_fe_index());
4838}
4839
4840
4841
4842template <int dimension_, int space_dimension_, bool level_dof_access>
4843inline types::fe_index
4845 future_fe_index() const
4846{
4847 Assert((this->dof_handler->hp_capability_enabled == false) ||
4848 (this->has_children() == false),
4849 ExcMessage(
4850 "You can not ask for the future FE index on a cell that has "
4851 "children because no degrees of freedom are assigned "
4852 "to this cell and, consequently, no finite element "
4853 "is associated with it."));
4854 Assert((this->dof_handler->hp_capability_enabled == false) ||
4855 (this->is_locally_owned()),
4856 ExcMessage("You can only query future FE index information on cells "
4857 "that are locally owned."));
4858
4859 return ::internal::DoFCellAccessorImplementation::Implementation::
4860 future_fe_index(*this);
4861}
4862
4863
4864
4865template <int dimension_, int space_dimension_, bool level_dof_access>
4866inline void
4869{
4870 Assert((this->dof_handler->hp_capability_enabled == false) ||
4871 (this->has_children() == false),
4872 ExcMessage("You can not set the future FE index on a cell that has "
4873 "children because no degrees of freedom will be assigned "
4874 "to this cell."));
4875
4876 Assert((this->dof_handler->hp_capability_enabled == false) ||
4877 this->is_locally_owned(),
4878 ExcMessage("You can only set future FE index information on cells "
4879 "that are locally owned."));
4880
4882 set_future_fe_index(*this, i);
4883}
4884
4885
4886
4887template <int dimension_, int space_dimension_, bool level_dof_access>
4888inline bool
4891{
4892 Assert((this->dof_handler->hp_capability_enabled == false) ||
4893 (this->has_children() == false),
4894 ExcMessage(
4895 "You can not ask for the future FE index on a cell that has "
4896 "children because no degrees of freedom are assigned "
4897 "to this cell and, consequently, no finite element "
4898 "is associated with it."));
4899 Assert((this->dof_handler->hp_capability_enabled == false) ||
4900 (this->is_locally_owned()),
4901 ExcMessage("You can only query future FE index information on cells "
4902 "that are locally owned."));
4903
4904 return ::internal::DoFCellAccessorImplementation::Implementation::
4905 future_fe_index_set(*this);
4906}
4907
4908
4909
4910template <int dimension_, int space_dimension_, bool level_dof_access>
4911inline void
4914{
4915 Assert((this->dof_handler->hp_capability_enabled == false) ||
4916 (this->has_children() == false),
4917 ExcMessage(
4918 "You can not ask for the future FE index on a cell that has "
4919 "children because no degrees of freedom are assigned "
4920 "to this cell and, consequently, no finite element "
4921 "is associated with it."));
4922 Assert((this->dof_handler->hp_capability_enabled == false) ||
4923 (this->is_locally_owned()),
4924 ExcMessage("You can only query future FE index information on cells "
4925 "that are locally owned."));
4926
4929}
4930
4931
4932
4933template <int dimension_, int space_dimension_, bool level_dof_access>
4934template <typename number, typename OutputVector>
4935inline void
4938 OutputVector &global_destination) const
4939{
4940 this->distribute_local_to_global(local_source.begin(),
4941 local_source.end(),
4942 global_destination);
4943}
4944
4945
4946
4947template <int dimension_, int space_dimension_, bool level_dof_access>
4948template <typename ForwardIterator, typename OutputVector>
4949inline void
4951 distribute_local_to_global(ForwardIterator local_source_begin,
4952 ForwardIterator local_source_end,
4953 OutputVector &global_destination) const
4954{
4955 Assert(this->dof_handler != nullptr,
4956 (typename std::decay_t<decltype(*this)>::ExcInvalidObject()));
4957 Assert(static_cast<unsigned int>(local_source_end - local_source_begin) ==
4958 this->get_fe().n_dofs_per_cell(),
4959 (typename std::decay_t<decltype(*this)>::ExcVectorDoesNotMatch()));
4960 Assert(this->dof_handler->n_dofs() == global_destination.size(),
4961 (typename std::decay_t<decltype(*this)>::ExcVectorDoesNotMatch()));
4962
4963 Assert(!this->has_children(), ExcMessage("Cell must be active"));
4964
4965 Assert(
4966 internal::ArrayViewHelper::is_contiguous(local_source_begin,
4967 local_source_end),
4968 ExcMessage(
4969 "This function can not be called with iterator types that do not point to contiguous memory."));
4970
4971 const unsigned int n_dofs = local_source_end - local_source_begin;
4972
4974 dof_indices(n_dofs);
4976 *this, dof_indices, this->active_fe_index());
4977
4978 // distribute cell vector
4979 global_destination.add(n_dofs, dof_indices.data(), &(*local_source_begin));
4980}
4981
4982
4983
4984template <int dimension_, int space_dimension_, bool level_dof_access>
4985template <typename ForwardIterator, typename OutputVector>
4986inline void
4990 ForwardIterator local_source_begin,
4991 ForwardIterator local_source_end,
4992 OutputVector &global_destination) const
4993{
4994 Assert(this->dof_handler != nullptr,
4995 (typename std::decay_t<decltype(*this)>::ExcInvalidObject()));
4996 Assert(local_source_end - local_source_begin ==
4997 this->get_fe().n_dofs_per_cell(),
4998 (typename std::decay_t<decltype(*this)>::ExcVectorDoesNotMatch()));
4999 Assert(this->dof_handler->n_dofs() == global_destination.size(),
5000 (typename std::decay_t<decltype(*this)>::ExcVectorDoesNotMatch()));
5001
5002 Assert(!this->has_children(), ExcMessage("Cell must be active."));
5003
5005 dof_indices(this->get_fe().n_dofs_per_cell());
5007 *this, dof_indices, this->active_fe_index());
5008
5009 // distribute cell vector
5010 constraints.distribute_local_to_global(local_source_begin,
5011 local_source_end,
5012 dof_indices.data(),
5013 global_destination);
5014}
5015
5016
5017
5018template <int dimension_, int space_dimension_, bool level_dof_access>
5019template <typename number, typename OutputMatrix>
5020inline void
5023 OutputMatrix &global_destination) const
5024{
5025 Assert(this->dof_handler != nullptr,
5026 (typename std::decay_t<decltype(*this)>::ExcInvalidObject()));
5027 Assert(local_source.m() == this->get_fe().n_dofs_per_cell(),
5028 (typename std::decay_t<decltype(*this)>::ExcMatrixDoesNotMatch()));
5029 Assert(local_source.n() == this->get_fe().n_dofs_per_cell(),
5030 (typename std::decay_t<decltype(*this)>::ExcMatrixDoesNotMatch()));
5031 Assert(this->dof_handler->n_dofs() == global_destination.m(),
5032 (typename std::decay_t<decltype(*this)>::ExcMatrixDoesNotMatch()));
5033 Assert(this->dof_handler->n_dofs() == global_destination.n(),
5034 (typename std::decay_t<decltype(*this)>::ExcMatrixDoesNotMatch()));
5035
5036 Assert(!this->has_children(), ExcMessage("Cell must be active."));
5037
5038 const unsigned int n_dofs = local_source.m();
5039
5041 dof_indices(n_dofs);
5043 *this, dof_indices, this->active_fe_index());
5044
5045 // distribute cell matrix
5046 for (unsigned int i = 0; i < n_dofs; ++i)
5047 global_destination.add(dof_indices[i],
5048 n_dofs,
5049 dof_indices.data(),
5050 &local_source(i, 0));
5051}
5052
5053
5054
5055template <int dimension_, int space_dimension_, bool level_dof_access>
5056template <typename number, typename OutputMatrix, typename OutputVector>
5057inline void
5060 const Vector<number> &local_vector,
5061 OutputMatrix &global_matrix,
5062 OutputVector &global_vector) const
5063{
5064 Assert(this->dof_handler != nullptr,
5065 (typename std::decay_t<decltype(*this)>::ExcInvalidObject()));
5066 Assert(local_matrix.m() == this->get_fe().n_dofs_per_cell(),
5067 (typename std::decay_t<decltype(*this)>::ExcMatrixDoesNotMatch()));
5068 Assert(local_matrix.n() == this->get_fe().n_dofs_per_cell(),
5069 (typename std::decay_t<decltype(*this)>::ExcVectorDoesNotMatch()));
5070 Assert(this->dof_handler->n_dofs() == global_matrix.m(),
5071 (typename std::decay_t<decltype(*this)>::ExcMatrixDoesNotMatch()));
5072 Assert(this->dof_handler->n_dofs() == global_matrix.n(),
5073 (typename std::decay_t<decltype(*this)>::ExcMatrixDoesNotMatch()));
5074 Assert(local_vector.size() == this->get_fe().n_dofs_per_cell(),
5075 (typename std::decay_t<decltype(*this)>::ExcVectorDoesNotMatch()));
5076 Assert(this->dof_handler->n_dofs() == global_vector.size(),
5077 (typename std::decay_t<decltype(*this)>::ExcVectorDoesNotMatch()));
5078
5079 Assert(!this->has_children(), ExcMessage("Cell must be active."));
5080
5081 const unsigned int n_dofs = this->get_fe().n_dofs_per_cell();
5083 dof_indices(n_dofs);
5085 *this, dof_indices, this->active_fe_index());
5086
5087 // distribute cell matrices
5088 for (unsigned int i = 0; i < n_dofs; ++i)
5089 {
5090 global_matrix.add(dof_indices[i],
5091 n_dofs,
5092 dof_indices.data(),
5093 &local_matrix(i, 0));
5094 global_vector(dof_indices[i]) += local_vector(i);
5095 }
5096}
5097
5098
5099
5101
5102
5103#endif
ArrayView< std::remove_reference_t< typename std::iterator_traits< Iterator >::reference >, MemorySpaceType > make_array_view(const Iterator begin, const Iterator end)
void get_dof_values(const VectorType &global_vector, ForwardIteratorInd local_indices_begin, ForwardIteratorVec local_vector_begin, ForwardIteratorVec local_vector_end) const
void distribute_local_to_global(const InVector &local_vector, const std::vector< size_type > &local_dof_indices, OutVector &global_vector) const
iterator begin() const
Definition array_view.h:755
friend struct ::internal::DoFHandlerImplementation::Policy::Implementation
void get_mg_dof_indices(const int level, std::vector< types::global_dof_index > &dof_indices, const types::fe_index fe_index=numbers::invalid_fe_index) const
DoFAccessor< 0, 1, spacedim, level_dof_access > & operator=(const DoFAccessor< 0, 1, spacedim, level_dof_access > &da)=delete
void get_dof_indices(std::vector< types::global_dof_index > &dof_indices, const types::fe_index fe_index=numbers::invalid_fe_index) const
typename::internal::DoFHandlerImplementation::Iterators< 1, spacedim, level_dof_access >::line_iterator line(const unsigned int i) const
DoFAccessor< 0, 1, spacedim, level_dof_access > & operator=(DoFAccessor< 0, 1, spacedim, level_dof_access > &&) noexcept=default
types::global_dof_index vertex_dof_index(const unsigned int vertex, const unsigned int i, const types::fe_index fe_index=numbers::invalid_fe_index) const
TriaAccessor< 0, 1, spacedim > BaseClass
DoFAccessor(DoFAccessor< 0, 1, spacedim, level_dof_access > &&)=default
const DoFHandler< 1, spacedim > & get_dof_handler() const
types::global_dof_index dof_index(const unsigned int i, const types::fe_index fe_index=numbers::invalid_fe_index) const
typename::internal::DoFHandlerImplementation::Iterators< 1, spacedim, level_dof_access >::quad_iterator quad(const unsigned int i) const
DoFAccessor(const DoFAccessor< 0, 1, spacedim, level_dof_access > &)=default
types::fe_index nth_active_fe_index(const unsigned int n) const
const FiniteElement< 1, spacedim > & get_fe(const types::fe_index fe_index) const
void set_dof_index(const unsigned int i, const types::global_dof_index index, const types::fe_index fe_index=numbers::invalid_fe_index) const
static constexpr unsigned int space_dimension
void set_dof_handler(DoFHandler< 1, spacedim > *dh)
TriaIterator< DoFAccessor< 0, 1, spacedim, level_dof_access > > child(const unsigned int c) const
bool fe_index_is_active(const types::fe_index fe_index) const
void copy_from(const DoFAccessor< 0, 1, spacedim, level_dof_access2 > &a)
typename::internal::DoFHandlerImplementation::Iterators< dim, spacedim, level_dof_access >::line_iterator line(const unsigned int i) const
const DoFHandler< dim, spacedim > & get_dof_handler() const
void set_mg_dof_index(const int level, const unsigned int i, const types::global_dof_index index) const
friend class DoFAccessor
DoFAccessor< structdim, dim, spacedim, level_dof_access > & operator=(const DoFAccessor< structdim, dim, spacedim, level_dof_access > &da)=delete
types::fe_index nth_active_fe_index(const unsigned int n) const
DoFAccessor(DoFAccessor< structdim, dim, spacedim, level_dof_access > &&)
DoFAccessor(const DoFAccessor< structdim, dim, spacedim, level_dof_access2 > &)
TriaIterator< DoFAccessor< structdim, dim, spacedim, level_dof_access > > child(const unsigned int c) const
void set_mg_vertex_dof_index(const int level, const unsigned int vertex, const unsigned int i, const types::global_dof_index index, const types::fe_index fe_index=numbers::invalid_fe_index) const
~DoFAccessor()=default
void set_dof_handler(DoFHandler< dim, spacedim > *dh)
DoFAccessor(const DoFAccessor< structdim2, dim2, spacedim2, level_dof_access2 > &)
DoFAccessor< structdim, dim, spacedim, level_dof_access > & operator=(DoFAccessor< structdim, dim, spacedim, level_dof_access > &&)
std::set< types::fe_index > get_active_fe_indices() const
DoFAccessor(const DoFAccessor< structdim, dim, spacedim, level_dof_access > &)=default
void set_mg_dof_indices(const int level, const std::vector< types::global_dof_index > &dof_indices, const types::fe_index fe_index=numbers::invalid_fe_index)
void get_mg_dof_indices(const int level, std::vector< types::global_dof_index > &dof_indices, const types::fe_index fe_index=numbers::invalid_fe_index) const
types::global_dof_index mg_vertex_dof_index(const int level, const unsigned int vertex, const unsigned int i, const types::fe_index fe_index=numbers::invalid_fe_index) const
DoFAccessor(const Triangulation< dim, spacedim > *tria, const int level, const int index, const DoFHandler< dim, spacedim > *dof_handler)
bool operator!=(const DoFAccessor< structdim2, dim2, spacedim2, level_dof_access2 > &) const
void copy_from(const TriaAccessorBase< structdim, dim, spacedim > &da)
types::global_dof_index dof_index(const unsigned int i, const types::fe_index fe_index=numbers::invalid_fe_index) const
typename::internal::DoFHandlerImplementation::Iterators< dim, spacedim, level_dof_access >::quad_iterator quad(const unsigned int i) const
DoFHandler< dimension, space_dimension > AccessorData
void copy_from(const DoFAccessor< structdim, dim, spacedim, level_dof_access2 > &a)
const FiniteElement< dim, spacedim > & get_fe(const types::fe_index fe_index) const
typename ::internal::DoFAccessorImplementation:: Inheritance< structdim, dimension, space_dimension >::BaseClass BaseClass
void get_dof_indices(std::vector< types::global_dof_index > &dof_indices, const types::fe_index fe_index=numbers::invalid_fe_index) const
bool operator==(const DoFAccessor< structdim2, dim2, spacedim2, level_dof_access2 > &) const
types::global_dof_index mg_dof_index(const int level, const unsigned int i) const
void set_dof_index(const unsigned int i, const types::global_dof_index index, const types::fe_index fe_index=numbers::invalid_fe_index) const
unsigned int n_active_fe_indices() const
static bool is_level_cell()
types::global_dof_index vertex_dof_index(const unsigned int vertex, const unsigned int i, const types::fe_index fe_index=numbers::invalid_fe_index) const
DoFAccessor(const InvalidAccessor< structdim2, dim2, spacedim2 > &)
bool fe_index_is_active(const types::fe_index fe_index) const
TriaIterator< DoFCellAccessor< dimension_, space_dimension_, level_dof_access > > periodic_neighbor_child_on_subface(const unsigned int face_no, const unsigned int subface_no) const
boost::container::small_vector< TriaIterator< DoFCellAccessor< dimension_, space_dimension_, level_dof_access > >, GeometryInfo< dimension_ >::max_children_per_cell > child_iterators() const
DoFCellAccessor(DoFCellAccessor< dimension_, space_dimension_, level_dof_access > &&)=default
DoFHandler< dimension_, space_dimension_ > AccessorData
void get_active_or_mg_dof_indices(std::vector< types::global_dof_index > &dof_indices) const
void get_dof_values(const InputVector &values, Vector< number > &local_values) const
boost::container::small_vector< face_iterator, GeometryInfo< dimension_ >::faces_per_cell > face_iterators() const
types::fe_index future_fe_index() const
DoFCellAccessor< dimension_, space_dimension_, level_dof_access > & operator=(const DoFCellAccessor< dimension_, space_dimension_, level_dof_access > &da)=delete
const FiniteElement< dimension_, space_dimension_ > & get_fe() const
TriaIterator< DoFCellAccessor< dimension_, space_dimension_, level_dof_access > > child(const unsigned int i) const
DoFCellAccessor(const Triangulation< dimension_, space_dimension_ > *tria, const int level, const int index, const AccessorData *local_data)
void set_future_fe_index(const types::fe_index i) const
void distribute_local_to_global(const Vector< number > &local_source, OutputVector &global_destination) const
TriaIterator< DoFCellAccessor< dimension_, space_dimension_, level_dof_access > > neighbor_or_periodic_neighbor(const unsigned int i) const
const FiniteElement< dimension_, space_dimension_ > & get_future_fe() const
void get_dof_values(const AffineConstraints< typename InputVector::value_type > &constraints, const InputVector &values, ForwardIterator local_values_begin, ForwardIterator local_values_end) const
void distribute_local_to_global(const FullMatrix< number > &local_source, OutputMatrix &global_destination) const
TriaIterator< DoFCellAccessor< dimension_, space_dimension_, level_dof_access > > neighbor(const unsigned int i) const
static const unsigned int dim
void set_active_fe_index(const types::fe_index i) const
void distribute_local_to_global_by_interpolation(const Vector< number > &local_values, OutputVector &values, const types::fe_index fe_index=numbers::invalid_fe_index) const
DoFCellAccessor(const DoFAccessor< structdim2, dim2, spacedim2, level_dof_access2 > &)
TriaIterator< DoFCellAccessor< dimension_, space_dimension_, level_dof_access > > periodic_neighbor(const unsigned int i) const
DoFCellAccessor(const InvalidAccessor< structdim2, dim2, spacedim2 > &)
static const unsigned int spacedim
void get_interpolated_dof_values(const ReadVector< Number > &values, Vector< Number > &interpolated_values, const types::fe_index fe_index=numbers::invalid_fe_index) const
face_iterator face(const unsigned int i) const
void clear_future_fe_index() const
void distribute_local_to_global(const FullMatrix< number > &local_matrix, const Vector< number > &local_vector, OutputMatrix &global_matrix, OutputVector &global_vector) const
void set_dof_indices(const std::vector< types::global_dof_index > &dof_indices)
void distribute_local_to_global(const AffineConstraints< typename OutputVector::value_type > &constraints, ForwardIterator local_source_begin, ForwardIterator local_source_end, OutputVector &global_destination) const
void set_dof_values(const Vector< number > &local_values, OutputVector &values) const
TriaIterator< DoFCellAccessor< dimension_, space_dimension_, level_dof_access > > neighbor_child_on_subface(const unsigned int face_no, const unsigned int subface_no) const
void set_dof_values_by_interpolation(const Vector< number > &local_values, OutputVector &values, const types::fe_index fe_index=numbers::invalid_fe_index, const bool perform_check=false) const
void set_mg_dof_indices(const std::vector< types::global_dof_index > &dof_indices)
DoFCellAccessor(const DoFCellAccessor< dimension_, space_dimension_, level_dof_access > &)=default
void get_mg_dof_indices(std::vector< types::global_dof_index > &dof_indices) const
void distribute_local_to_global(ForwardIterator local_source_begin, ForwardIterator local_source_end, OutputVector &global_destination) const
void get_dof_values(const ReadVector< Number > &values, ForwardIterator local_values_begin, ForwardIterator local_values_end) const
~DoFCellAccessor()=default
DoFHandler< dimension_, space_dimension_ > Container
bool future_fe_index_set() const
DoFCellAccessor< dimension_, space_dimension_, level_dof_access > & operator=(DoFCellAccessor< dimension_, space_dimension_, level_dof_access > &&)=default
TriaIterator< DoFAccessor< dimension_ - 1, dimension_, space_dimension_, level_dof_access > > face_iterator
void get_dof_indices(std::vector< types::global_dof_index > &dof_indices) const
types::fe_index active_fe_index() const
void get_interpolated_dof_values(const ReadVector< Number > &values, ArrayView< Number > interpolated_values, const types::fe_index fe_index=numbers::invalid_fe_index) const
DoFAccessor< dimension_, dimension_, space_dimension_, level_dof_access > BaseClass
TriaIterator< DoFCellAccessor< dimension_, space_dimension_, level_dof_access > > parent() const
std::vector< std::unique_ptr<::internal::DoFHandlerImplementation::DoFLevel< dim > > > mg_levels
static const types::fe_index default_fe_index
std::vector< std::vector< types::fe_index > > hp_cell_future_fe_indices
const FiniteElement< dim, spacedim > & get_fe(const types::fe_index index=0) const
std::vector< std::vector< types::fe_index > > hp_cell_active_fe_indices
std::vector< MGVertexDoFs > mg_vertex_dofs
std::vector< std::array< std::vector< types::global_dof_index >, dim+1 > > object_dof_indices
std::vector< std::array< std::vector< offset_type >, dim+1 > > object_dof_ptr
std::unique_ptr<::internal::DoFHandlerImplementation::DoFFaces< dim > > mg_faces
bool hp_capability_enabled
bool has_hp_capabilities() const
std::array< std::vector< offset_type >, dim+1 > hp_object_fe_ptr
std::array< std::vector< types::fe_index >, dim+1 > hp_object_fe_indices
typename InvalidAccessor< structdim, dim, spacedim >::AccessorData AccessorData
DoFInvalidAccessor(const void *parent=nullptr, const int level=-1, const int index=-1, const AccessorData *local_data=nullptr)
unsigned int n_dofs_per_vertex() const
size_type n() const
size_type m() const
void compress() const
Definition index_set.h:1791
void add_indices(const ForwardIterator &begin, const ForwardIterator &end)
Definition index_set.h:1838
InvalidAccessor(const void *parent=nullptr, const int level=-1, const int index=-1, const AccessorData *local_data=nullptr)
void import_elements(const ::Vector< Number > &vec, VectorOperation::values operation, const std::shared_ptr< const Utilities::MPI::CommunicationPatternBase > &communication_pattern={})
TriaAccessorBase(const Triangulation< dim, spacedim > *parent=nullptr, const int level=-1, const int index=-1, const AccessorData *=nullptr)
TriaAccessor(const Triangulation< 1, spacedim > *tria, const VertexKind vertex_kind, const unsigned int vertex_index)
unsigned int vertex_index(const unsigned int i=0) const
void copy_from(const TriaAccessor &)
Point< spacedim > & vertex(const unsigned int i=0) const
const Triangulation< 1, spacedim > * tria
TriaIterator< TriaAccessor< structdim, dim, spacedim > > child(const unsigned int i) const
IteratorState::IteratorStates state() const
virtual size_type size() const override
iterator end()
iterator begin()
#define DEAL_II_ALWAYS_INLINE
Definition config.h:165
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_RESTRICT
Definition config.h:166
constexpr bool running_in_debug_mode()
Definition config.h:76
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
#define DEAL_II_ASSERT_UNREACHABLE()
#define DEAL_II_NOT_IMPLEMENTED()
#define DeclException0(Exception0)
static ::ExceptionBase & ExcVectorDoesNotMatch()
static ::ExceptionBase & ExcVectorNotEmpty()
static ::ExceptionBase & ExcMatrixDoesNotMatch()
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
static ::ExceptionBase & ExcImpossibleInDim(int arg1)
static ::ExceptionBase & ExcNotImplementedWithHP()
static ::ExceptionBase & ExcCantCompareIterators()
#define AssertDimension(dim1, dim2)
#define AssertIndexRange(index, range)
#define DeclExceptionMsg(Exception, defaulttext)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcMessage(std::string arg1)
const bool IsBlockVector< VectorType >::value
MappingQ< dim, spacedim > StaticMappingQ1< dim, spacedim >::mapping
Definition mapping_q1.h:101
@ past_the_end
Iterator reached end of container.
Definition hp.h:115
types::fe_index get_fe_index_or_default(const DoFAccessor< structdim, dim, spacedim, level_dof_access > &cell, const types::fe_index fe_index)
void get_cell_dof_indices(const ::DoFCellAccessor< dim, spacedim, level_dof_access > &accessor, Implementation::dof_index_vector_type &dof_indices, const unsigned int fe_index)
TriaIterator< ::DoFAccessor< dim - 1, dim, spacedim, level_dof_access > > get_face(const ::DoFCellAccessor< dim, spacedim, level_dof_access > &cell, const unsigned int i, const std::integral_constant< int, 1 >)
constexpr types::global_dof_index invalid_dof_index
Definition types.h:267
constexpr types::geometric_orientation reverse_line_orientation
Definition types.h:363
constexpr types::geometric_orientation default_geometric_orientation
Definition types.h:350
constexpr types::fe_index invalid_fe_index
Definition types.h:258
STL namespace.
::VectorizedArray< Number, width > min(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
Definition types.h:30
unsigned short int fe_index
Definition types.h:70
unsigned int global_dof_index
Definition types.h:92
static constexpr unsigned int faces_per_cell
static constexpr unsigned int max_children_per_cell
void process_vertex_dofs(DoFHandler< dim, spacedim > &dof_handler, const unsigned int vertex_index, const types::fe_index fe_index, types::global_dof_index *&dof_indices_ptr, const DoFProcessor &dof_processor) const
void process_dofs(const DoFHandler< dim, spacedim > &dof_handler, const unsigned int obj_level, const unsigned int obj_index, const types::fe_index fe_index, const DoFMapping &mapping, const std::integral_constant< int, structdim >, types::global_dof_index *&dof_indices_ptr, const DoFProcessor &dof_processor) const
void process_dofs(const DoFHandler< dim, spacedim > &dof_handler, const unsigned int, const unsigned int obj_index, const types::fe_index fe_index, const DoFMapping &mapping, const std::integral_constant< int, structdim >, types::global_dof_index *&dof_indices_ptr, const DoFProcessor &dof_processor) const
void process_vertex_dofs(DoFHandler< dim, spacedim > &dof_handler, const unsigned int vertex_index, const types::fe_index, types::global_dof_index *&dof_indices_ptr, const DoFProcessor &dof_processor) const
static types::global_dof_index * get_array_ptr(const std::tuple<> &)
static void process_dof_indices(const ::DoFAccessor< structdim, dim, spacedim, level_dof_access > &accessor, const DoFIndicesType &const_dof_indices, const types::fe_index fe_index_, const DoFOperation &dof_operation, const DoFProcessor &dof_processor, const bool count_level_dofs)
static void get_dof_indices(const ::DoFAccessor< structdim, dim, spacedim, level_dof_access > &accessor, std::vector< types::global_dof_index > &dof_indices, const types::fe_index fe_index)
static void extract_subvector_to(const LinearAlgebra::TpetraWrappers::Vector< Number, MemorySpace > &values, const types::global_dof_index *cache_begin, const types::global_dof_index *cache_end, ForwardIterator local_values_begin)
static std::set< types::fe_index > get_active_fe_indices(const DoFHandler< dim, spacedim > &dof_handler, const unsigned int obj_level, const unsigned int obj_index, const std::integral_constant< int, structdim > &t)
static types::global_dof_index * get_array_ptr(const ArrayType &array)
static unsigned int get_array_length(const std::tuple<> &)
boost::container::small_vector<::types::global_dof_index, 100 > dof_index_vector_type
static unsigned int n_active_fe_indices(const DoFHandler< dim, spacedim > &dof_handler, const unsigned int obj_level, const unsigned int obj_index, const std::integral_constant< int, structdim > &)
static void set_dof_index(const DoFHandler< dim, spacedim > &dof_handler, const unsigned int obj_level, const unsigned int obj_index, const types::fe_index fe_index, const unsigned int local_index, const std::integral_constant< int, structdim > &dd, const types::global_dof_index global_index)
static void extract_subvector_to(const LinearAlgebra::EpetraWrappers::Vector &values, const types::global_dof_index *cache_begin, const types::global_dof_index *cache_end, ForwardIterator local_values_begin)
static void get_mg_dof_indices(const ::DoFAccessor< structdim, dim, spacedim, level_dof_access > &accessor, const int level, std::vector< types::global_dof_index > &dof_indices, const types::fe_index fe_index)
static bool fe_index_is_active(const DoFHandler< dim, spacedim > &dof_handler, const unsigned int obj_level, const unsigned int obj_index, const types::fe_index fe_index, const std::integral_constant< int, structdim > &)
static types::global_dof_index & get_mg_dof_index(const DoFHandler< dim, spacedim > &dof_handler, const std::unique_ptr< internal::DoFHandlerImplementation::DoFLevel< dim > > &, const std::unique_ptr< internal::DoFHandlerImplementation::DoFFaces< dim > > &mg_faces, const unsigned int obj_index, const types::fe_index fe_index, const unsigned int local_index, const std::integral_constant< int, 1 >)
static types::global_dof_index & get_mg_dof_index(const DoFHandler< dim, spacedim > &dof_handler, const std::unique_ptr< internal::DoFHandlerImplementation::DoFLevel< dim > > &mg_level, const std::unique_ptr< internal::DoFHandlerImplementation::DoFFaces< dim > > &, const unsigned int obj_index, const types::fe_index fe_index, const unsigned int local_index, const std::integral_constant< int, dim >)
static std::pair< unsigned int, unsigned int > process_object_range(const ::DoFAccessor< structdim, dim, spacedim, level_dof_access > accessor, const types::fe_index fe_index)
static types::global_dof_index & mg_vertex_dof_index(DoFHandler< dim, spacedim > &dof_handler, const int level, const unsigned int vertex_index, const unsigned int i)
static void set_mg_dof_indices(const ::DoFAccessor< structdim, dim, spacedim, level_dof_access > &accessor, const int level, const std::vector< types::global_dof_index > &dof_indices, const types::fe_index fe_index)
static void set_dof_indices(const ::DoFAccessor< structdim, dim, spacedim, level_dof_access > &accessor, const std::vector< types::global_dof_index > &dof_indices, const types::fe_index fe_index)
static void process_dof_index(const DoFHandler< dim, spacedim > &dof_handler, const unsigned int obj_level, const unsigned int obj_index, const types::fe_index fe_index, const unsigned int local_index, const std::integral_constant< int, structdim > &, GlobalIndexType &global_index, const DoFPProcessor &process)
static types::global_dof_index & get_mg_dof_index(const DoFHandler< 3, spacedim > &dof_handler, const std::unique_ptr< internal::DoFHandlerImplementation::DoFLevel< 3 > > &, const std::unique_ptr< internal::DoFHandlerImplementation::DoFFaces< 3 > > &mg_faces, const unsigned int obj_index, const types::fe_index fe_index, const unsigned int local_index, const std::integral_constant< int, 2 >)
static std::pair< unsigned int, unsigned int > process_object_range(const DoFHandler< dim, spacedim > &dof_handler, const unsigned int obj_level, const unsigned int obj_index, const types::fe_index fe_index, const std::integral_constant< int, structdim > &)
static void extract_subvector_to(const InputVector &values, const types::global_dof_index *cache, const types::global_dof_index *cache_end, ForwardIterator local_values_begin)
static std::vector< unsigned int > sort_indices(const types::global_dof_index *v_begin, const types::global_dof_index *v_end)
static types::fe_index nth_active_fe_index(const DoFHandler< dim, spacedim > &dof_handler, const unsigned int obj_level, const unsigned int obj_index, const unsigned int local_index, const std::integral_constant< int, structdim > &)
static void process_object(const DoFHandler< dim, spacedim > &dof_handler, const unsigned int obj_level, const unsigned int obj_index, const types::fe_index fe_index, const DoFMapping &mapping, const std::integral_constant< int, structdim > &dd, types::global_dof_index *&dof_indices_ptr, const DoFProcessor &process)
static types::global_dof_index get_dof_index(const DoFHandler< dim, spacedim > &dof_handler, const unsigned int obj_level, const unsigned int obj_index, const types::fe_index fe_index, const unsigned int local_index, const std::integral_constant< int, structdim > &dd)
static unsigned int n_dof_indices(const ::DoFAccessor< structdim, dim, spacedim, level_dof_access > &accessor, const types::fe_index fe_index_, const bool count_level_dofs)
static std::pair< unsigned int, unsigned int > process_object_range(::DoFInvalidAccessor< structdim, dim, spacedim >, const unsigned int)
static unsigned int get_array_length(const ArrayType &array)
::TriaAccessor< structdim, dim, spacedim > BaseClass
static types::fe_index future_fe_index(const DoFCellAccessor< dim, spacedim, level_dof_access > &accessor)
static void clear_future_fe_index(const DoFCellAccessor< dim, spacedim, level_dof_access > &accessor)
static bool future_fe_index_set(const DoFCellAccessor< dim, spacedim, level_dof_access > &accessor)
static void set_active_fe_index(const DoFCellAccessor< dim, spacedim, level_dof_access > &accessor, const types::fe_index i)
static void set_future_fe_index(const DoFCellAccessor< dim, spacedim, level_dof_access > &accessor, const types::fe_index i)
static types::fe_index active_fe_index(const DoFCellAccessor< dim, spacedim, level_dof_access > &accessor)
static void set(typename VectorType::value_type value, const types::global_dof_index i, VectorType &V)