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
fe_interface_values.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) 2019 - 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_fe_interface_values_h
14#define dealii_fe_interface_values_h
15
16#include <deal.II/base/config.h>
17
19
21#include <deal.II/fe/mapping.h>
22
26
28
29#ifndef DOXYGEN
30template <int dim, int spacedim>
32#endif
33
39{
43 template <int dim, int spacedim = dim>
44 class Base
45 {
46 public:
51
52 protected:
57
62 template <class InputVector, class OutputVector>
63 void
64 get_local_dof_values(const InputVector &dof_values,
65 OutputVector &local_dof_values) const;
66 };
67
68
69
73 template <int dim, int spacedim = dim>
74 class Scalar : public Base<dim, spacedim>
75 {
76 public:
80 using value_type = double;
81
88
95
102
109 template <typename Number>
111
118 template <typename Number>
121
128 template <typename Number>
131
138 template <typename Number>
141
146 const unsigned int component);
147
152
173 value(const bool here_or_there,
174 const unsigned int interface_dof_index,
175 const unsigned int q_point) const;
176
192 gradient(const bool here_or_there,
193 const unsigned int interface_dof_index,
194 const unsigned int q_point) const;
195
197
202
214 jump_in_values(const unsigned int interface_dof_index,
215 const unsigned int q_point) const;
216
228 jump_in_gradients(const unsigned int interface_dof_index,
229 const unsigned int q_point) const;
230
242 jump_in_hessians(const unsigned int interface_dof_index,
243 const unsigned int q_point) const;
244
256 jump_in_third_derivatives(const unsigned int interface_dof_index,
257 const unsigned int q_point) const;
258
260
265
277 average_of_values(const unsigned int interface_dof_index,
278 const unsigned int q_point) const;
279
291 average_of_gradients(const unsigned int interface_dof_index,
292 const unsigned int q_point) const;
293
306 average_of_hessians(const unsigned int interface_dof_index,
307 const unsigned int q_point) const;
308
310
315
335 template <class InputVector>
336 void
338 const bool here_or_there,
339 const InputVector &fe_function,
341 &values) const;
342
365 template <class InputVector>
366 void
368 const bool here_or_there,
369 const InputVector &local_dof_values,
371 &values) const;
372
374
379
393 template <class InputVector>
394 void
396 const InputVector &fe_function,
398 &values) const;
399
407 template <class InputVector>
408 void
410 const InputVector &local_dof_values,
412 &values) const;
413
427 template <class InputVector>
428 void
430 const InputVector &fe_function,
432 &gradients) const;
433
441 template <class InputVector>
442 void
444 const InputVector &local_dof_values,
446 &gradients) const;
447
461 template <class InputVector>
462 void
464 const InputVector &fe_function,
466 &hessians) const;
467
475 template <class InputVector>
476 void
478 const InputVector &local_dof_values,
480 &hessians) const;
481
496 template <class InputVector>
497 void
499 const InputVector &fe_function,
500 std::vector<
502 &third_derivatives) const;
503
511 template <class InputVector>
512 void
514 const InputVector &local_dof_values,
515 std::vector<
517 &third_derivatives) const;
518
520
525
539 template <class InputVector>
540 void
542 const InputVector &fe_function,
544 &values) const;
545
553 template <class InputVector>
554 void
556 const InputVector &local_dof_values,
558 &values) const;
559
573 template <class InputVector>
574 void
576 const InputVector &fe_function,
578 &gradients) const;
579
587 template <class InputVector>
588 void
590 const InputVector &local_dof_values,
592 &gradients) const;
593
607 template <class InputVector>
608 void
610 const InputVector &fe_function,
612 &hessians) const;
613
621 template <class InputVector>
622 void
624 const InputVector &local_dof_values,
626 &hessians) const;
627
629
630 private:
635 };
636
637
638
642 template <int dim, int spacedim = dim>
643 class Vector : public Base<dim, spacedim>
644 {
645 public:
651
658
666
674
681 template <typename Number>
683
690 template <typename Number>
693
700 template <typename Number>
703
710 template <typename Number>
713
718 const unsigned int first_vector_component);
719
724
745 value(const bool here_or_there,
746 const unsigned int interface_dof_index,
747 const unsigned int q_point) const;
748
764 gradient(const bool here_or_there,
765 const unsigned int interface_dof_index,
766 const unsigned int q_point) const;
767
768
770
775
786 jump_in_values(const unsigned int interface_dof_index,
787 const unsigned int q_point) const;
788
799 jump_in_gradients(const unsigned int interface_dof_index,
800 const unsigned int q_point) const;
801
808 jump_gradient(const unsigned int interface_dof_index,
809 const unsigned int q_point) const;
810
822 jump_in_hessians(const unsigned int interface_dof_index,
823 const unsigned int q_point) const;
824
831 jump_hessian(const unsigned int interface_dof_index,
832 const unsigned int q_point) const;
833
845 jump_in_third_derivatives(const unsigned int interface_dof_index,
846 const unsigned int q_point) const;
847
849
854
865 average_of_values(const unsigned int interface_dof_index,
866 const unsigned int q_point) const;
867
878 average_of_gradients(const unsigned int interface_dof_index,
879 const unsigned int q_point) const;
880
893 average_of_hessians(const unsigned int interface_dof_index,
894 const unsigned int q_point) const;
895
902 average_hessian(const unsigned int interface_dof_index,
903 const unsigned int q_point) const;
904
906
911
931 template <class InputVector>
932 void
934 const bool here_or_there,
935 const InputVector &fe_function,
937 &values) const;
938
961 template <class InputVector>
962 void
964 const bool here_or_there,
965 const InputVector &local_dof_values,
967 &values) const;
968
970
975
989 template <class InputVector>
990 void
992 const InputVector &fe_function,
994 &values) const;
995
1003 template <class InputVector>
1004 void
1006 const InputVector &local_dof_values,
1008 &values) const;
1009
1023 template <class InputVector>
1024 void
1026 const InputVector &fe_function,
1028 &gradients) const;
1029
1037 template <class InputVector>
1038 void
1040 const InputVector &local_dof_values,
1042 &gradients) const;
1043
1057 template <class InputVector>
1058 void
1060 const InputVector &fe_function,
1062 &hessians) const;
1063
1071 template <class InputVector>
1072 void
1074 const InputVector &local_dof_values,
1076 &hessians) const;
1077
1092 template <class InputVector>
1093 void
1095 const InputVector &fe_function,
1096 std::vector<
1098 &third_derivatives) const;
1099
1107 template <class InputVector>
1108 void
1110 const InputVector &local_dof_values,
1111 std::vector<
1113 &third_derivatives) const;
1114
1116
1121
1135 template <class InputVector>
1136 void
1138 const InputVector &fe_function,
1140 &values) const;
1141
1149 template <class InputVector>
1150 void
1152 const InputVector &local_dof_values,
1154 &values) const;
1155
1169 template <class InputVector>
1170 void
1172 const InputVector &fe_function,
1174 &gradients) const;
1175
1183 template <class InputVector>
1184 void
1186 const InputVector &local_dof_values,
1188 &gradients) const;
1189
1203 template <class InputVector>
1204 void
1206 const InputVector &fe_function,
1208 &hessians) const;
1209
1217 template <class InputVector>
1218 void
1220 const InputVector &local_dof_values,
1222 &hessians) const;
1223
1225
1226 private:
1231 };
1232} // namespace FEInterfaceViews
1233
1234
1235namespace internal
1236{
1238 {
1243 template <int dim, int spacedim, typename Extractor>
1245 {};
1246
1254 template <int dim, int spacedim>
1255 struct ViewType<dim, spacedim, FEValuesExtractors::Scalar>
1256 {
1257 using type = typename ::FEInterfaceViews::Scalar<dim, spacedim>;
1258 };
1259
1267 template <int dim, int spacedim>
1268 struct ViewType<dim, spacedim, FEValuesExtractors::Vector>
1269 {
1270 using type = typename ::FEInterfaceViews::Vector<dim, spacedim>;
1271 };
1272 } // namespace FEInterfaceViews
1273} // namespace internal
1274
1275namespace FEInterfaceViews
1276{
1281 template <int dim, int spacedim, typename Extractor>
1282 using View = typename ::internal::FEInterfaceViews::
1283 ViewType<dim, spacedim, Extractor>::type;
1284} // namespace FEInterfaceViews
1285
1286
1287
1312template <int dim, int spacedim = dim>
1314{
1315public:
1329 {
1330 InterfaceData(const unsigned int face_no,
1331 const unsigned int sub_face_no,
1332 const unsigned int face_no_neighbor,
1333 const unsigned int sub_face_no_neighbor)
1334 : face_no(face_no)
1338 {}
1339
1340 // mandatory
1341 unsigned int face_no;
1342 unsigned int sub_face_no;
1343 unsigned int face_no_neighbor;
1345
1346 // optional
1353 };
1354
1357 const unsigned int n_quadrature_points;
1358
1366 const Quadrature<dim - 1> &quadrature,
1367 const UpdateFlags update_flags);
1368
1376 const hp::QCollection<dim - 1> &quadrature,
1377 const UpdateFlags update_flags);
1378
1386 const Quadrature<dim - 1> &quadrature,
1387 const UpdateFlags update_flags);
1388
1394 const hp::MappingCollection<dim, spacedim> &mapping_collection,
1395 const hp::FECollection<dim, spacedim> &fe_collection,
1396 const hp::QCollection<dim - 1> &quadrature_collection,
1397 const UpdateFlags update_flags);
1398
1403 const hp::QCollection<dim - 1> &quadrature_collection,
1404 const UpdateFlags update_flags);
1405
1522 template <typename CellIteratorType, typename CellNeighborIteratorType>
1523 void
1524 reinit(const CellIteratorType &cell,
1525 const unsigned int face_no,
1526 const unsigned int sub_face_no,
1527 const CellNeighborIteratorType &cell_neighbor,
1528 const unsigned int face_no_neighbor,
1529 const unsigned int sub_face_no_neighbor,
1530 const unsigned int q_index = numbers::invalid_unsigned_int,
1531 const unsigned int mapping_index = numbers::invalid_unsigned_int,
1532 const unsigned int fe_index = numbers::invalid_unsigned_int,
1533 const unsigned int fe_index_neighbor = numbers::invalid_unsigned_int);
1534
1549 template <typename CellIteratorType, typename CellNeighborIteratorType>
1550 void
1551 reinit(const CellIteratorType &cell,
1552 const CellNeighborIteratorType &cell_neighbor,
1553 const InterfaceData &interface_data);
1554
1581 template <typename CellIteratorType>
1582 void
1583 reinit(const CellIteratorType &cell,
1584 const unsigned int face_no,
1585 const unsigned int q_index = numbers::invalid_unsigned_int,
1586 const unsigned int mapping_index = numbers::invalid_unsigned_int,
1587 const unsigned int fe_index = numbers::invalid_unsigned_int);
1588
1597 get_fe_face_values(const unsigned int cell_index) const;
1598
1604
1609 get_fe() const;
1610
1614 const Quadrature<dim - 1> &
1616
1622
1628
1632 const hp::QCollection<dim - 1> &
1634
1639 bool
1641
1645 UpdateFlags
1647
1655 get_cell(const unsigned int cell_index) const;
1656
1664 unsigned int
1665 get_face_number(const unsigned int cell_index) const;
1666
1671
1678 bool
1680
1692 double
1693 JxW(const unsigned int quadrature_point) const;
1694
1700 const std::vector<double> &
1702
1713 DEAL_II_DEPRECATED_WITH_COMMENT("Use the function normal_vector().")
1714 Tensor<1, spacedim>
1715 normal(const unsigned int q_point_index) const;
1716
1725 Tensor<1, spacedim>
1726 normal_vector(const unsigned int q_point_index) const;
1727
1737 const std::vector<Tensor<1, spacedim>> &
1739
1747 std_cxx20::ranges::iota_view<unsigned int, unsigned int>
1749
1756 const Point<spacedim> &
1757 quadrature_point(const unsigned int q_point) const;
1758
1764 const std::vector<Point<spacedim>> &
1766
1777 unsigned
1779
1807 std_cxx20::ranges::iota_view<unsigned int, unsigned int>
1809
1820 std::vector<types::global_dof_index>
1822
1835 std::array<unsigned int, 2>
1836 interface_dof_to_dof_indices(const unsigned int interface_dof_index) const;
1837
1841
1846
1868 double
1869 shape_value(const bool here_or_there,
1870 const unsigned int interface_dof_index,
1871 const unsigned int q_point,
1872 const unsigned int component = 0) const;
1873
1883 Tensor<1, spacedim>
1884 shape_grad(const bool here_or_there,
1885 const unsigned int interface_dof_index,
1886 const unsigned int q_point,
1887 const unsigned int component = 0) const;
1888
1892
1897
1916 double
1917 jump_in_shape_values(const unsigned int interface_dof_index,
1918 const unsigned int q_point,
1919 const unsigned int component = 0) const;
1920
1934 Tensor<1, spacedim>
1935 jump_in_shape_gradients(const unsigned int interface_dof_index,
1936 const unsigned int q_point,
1937 const unsigned int component = 0) const;
1938
1953 Tensor<2, spacedim>
1954 jump_in_shape_hessians(const unsigned int interface_dof_index,
1955 const unsigned int q_point,
1956 const unsigned int component = 0) const;
1957
1971 Tensor<3, spacedim>
1972 jump_in_shape_3rd_derivatives(const unsigned int interface_dof_index,
1973 const unsigned int q_point,
1974 const unsigned int component = 0) const;
1975
1979
1984
1998 double
1999 average_of_shape_values(const unsigned int interface_dof_index,
2000 const unsigned int q_point,
2001 const unsigned int component = 0) const;
2002
2016 Tensor<1, spacedim>
2017 average_of_shape_gradients(const unsigned int interface_dof_index,
2018 const unsigned int q_point,
2019 const unsigned int component = 0) const;
2020
2035 Tensor<2, spacedim>
2036 average_of_shape_hessians(const unsigned int interface_dof_index,
2037 const unsigned int q_point,
2038 const unsigned int component = 0) const;
2039
2043
2044
2045
2050
2059 template <class InputVector>
2060 void
2062 const InputVector &fe_function,
2063 std::vector<typename InputVector::value_type> &values) const;
2064
2073 template <class InputVector>
2074 void
2076 const InputVector &fe_function,
2077 std::vector<Tensor<1, spacedim, typename InputVector::value_type>>
2078 &gradients) const;
2079
2087 template <class InputVector>
2088 void
2090 const InputVector &fe_function,
2091 std::vector<Tensor<2, spacedim, typename InputVector::value_type>>
2092 &hessians) const;
2093
2102 template <class InputVector>
2103 void
2105 const InputVector &fe_function,
2106 std::vector<Tensor<3, spacedim, typename InputVector::value_type>>
2107 &third_derivatives) const;
2108
2110
2115
2124 template <class InputVector>
2125 void
2127 const InputVector &fe_function,
2128 std::vector<typename InputVector::value_type> &values) const;
2129
2137 template <class InputVector>
2138 void
2140 const InputVector &fe_function,
2141 std::vector<Tensor<1, spacedim, typename InputVector::value_type>>
2142 &gradients) const;
2143
2151 template <class InputVector>
2152 void
2154 const InputVector &fe_function,
2155 std::vector<Tensor<2, spacedim, typename InputVector::value_type>>
2156 &hessians) const;
2157
2161
2162
2163
2168
2175 FEInterfaceViews::Scalar<dim, spacedim>
2176 operator[](const FEValuesExtractors::Scalar &scalar) const;
2177
2184 FEInterfaceViews::Vector<dim, spacedim>
2185 operator[](const FEValuesExtractors::Vector &vector) const;
2186
2190
2191private:
2199 std::vector<std::pair<types::global_dof_index, std::array<unsigned int, 2>>>
2201
2207
2214 // non-hp data
2219
2223 std::unique_ptr<FEFaceValues<dim, spacedim>> internal_fe_face_values;
2224
2229
2234
2238 std::unique_ptr<FESubfaceValues<dim, spacedim>>
2240 // non-hp data
2242 // hp data
2247
2252 std::unique_ptr<hp::FEFaceValues<dim, spacedim>> internal_hp_fe_face_values;
2253
2258 std::unique_ptr<hp::FESubfaceValues<dim, spacedim>>
2260
2265 std::unique_ptr<hp::FEFaceValues<dim, spacedim>>
2267
2272 std::unique_ptr<hp::FESubfaceValues<dim, spacedim>>
2274
2282 "The current function doesn't make sense when used with a "
2283 "FEInterfaceValues object with hp-capabilities.");
2284
2292 "The current function doesn't make sense when used with a "
2293 "FEInterfaceValues object without hp-capabilities.");
2294 // hp data
2296
2297 /*
2298 * Make the view classes friends of this class, since they
2299 * access internal data.
2300 */
2301 template <int, int>
2303 template <int, int>
2305};
2306
2307
2308
2309#ifndef DOXYGEN
2310
2311/*---------------------- Inline functions ---------------------*/
2312
2313template <int dim, int spacedim>
2317 const Quadrature<dim - 1> &quadrature,
2318 const UpdateFlags update_flags)
2319 : n_quadrature_points(quadrature.size())
2320 , fe_face_values(nullptr)
2321 , fe_face_values_neighbor(nullptr)
2323 std::make_unique<FEFaceValues<dim, spacedim>>(mapping,
2324 fe,
2325 quadrature,
2326 update_flags))
2328 std::make_unique<FESubfaceValues<dim, spacedim>>(mapping,
2329 fe,
2330 quadrature,
2331 update_flags))
2333 std::make_unique<FEFaceValues<dim, spacedim>>(mapping,
2334 fe,
2335 quadrature,
2336 update_flags))
2338 std::make_unique<FESubfaceValues<dim, spacedim>>(mapping,
2339 fe,
2340 quadrature,
2341 update_flags))
2342{}
2343
2344
2345
2346template <int dim, int spacedim>
2349 const Quadrature<dim - 1> &quadrature,
2350 const UpdateFlags update_flags)
2352 fe.reference_cell().template get_default_linear_mapping<spacedim>(),
2353 fe,
2354 quadrature,
2355 update_flags)
2356{}
2357
2358
2359
2360template <int dim, int spacedim>
2364 const hp::QCollection<dim - 1> &quadrature,
2365 const UpdateFlags update_flags)
2366 : n_quadrature_points(quadrature.max_n_quadrature_points())
2367 , fe_face_values(nullptr)
2368 , fe_face_values_neighbor(nullptr)
2369 , internal_fe_face_values(
2370 std::make_unique<FEFaceValues<dim, spacedim>>(mapping,
2371 fe,
2372 quadrature,
2373 update_flags))
2374 , internal_fe_subface_values(
2375 std::make_unique<FESubfaceValues<dim, spacedim>>(mapping,
2376 fe,
2377 quadrature,
2378 update_flags))
2379 , internal_fe_face_values_neighbor(
2380 std::make_unique<FEFaceValues<dim, spacedim>>(mapping,
2381 fe,
2382 quadrature[0],
2383 update_flags))
2384 , internal_fe_subface_values_neighbor(
2385 std::make_unique<FESubfaceValues<dim, spacedim>>(mapping,
2386 fe,
2387 quadrature[0],
2388 update_flags))
2389{}
2390
2391
2392
2393template <int dim, int spacedim>
2395 const hp::MappingCollection<dim, spacedim> &mapping_collection,
2396 const hp::FECollection<dim, spacedim> &fe_collection,
2397 const hp::QCollection<dim - 1> &quadrature_collection,
2398 const UpdateFlags update_flags)
2399 : n_quadrature_points(quadrature_collection.max_n_quadrature_points())
2400 , fe_face_values(nullptr)
2401 , fe_face_values_neighbor(nullptr)
2402 , internal_hp_fe_face_values(
2403 std::make_unique<hp::FEFaceValues<dim, spacedim>>(mapping_collection,
2404 fe_collection,
2405 quadrature_collection,
2406 update_flags))
2407 , internal_hp_fe_subface_values(
2408 std::make_unique<hp::FESubfaceValues<dim, spacedim>>(
2409 mapping_collection,
2410 fe_collection,
2411 quadrature_collection,
2412 update_flags))
2413 , internal_hp_fe_face_values_neighbor(
2414 std::make_unique<hp::FEFaceValues<dim, spacedim>>(mapping_collection,
2415 fe_collection,
2416 quadrature_collection,
2417 update_flags))
2418 , internal_hp_fe_subface_values_neighbor(
2419 std::make_unique<hp::FESubfaceValues<dim, spacedim>>(
2420 mapping_collection,
2421 fe_collection,
2422 quadrature_collection,
2423 update_flags))
2424{
2425 AssertDimension(dim, spacedim);
2426}
2427
2428
2429
2430template <int dim, int spacedim>
2432 const hp::FECollection<dim, spacedim> &fe_collection,
2433 const hp::QCollection<dim - 1> &quadrature_collection,
2434 const UpdateFlags update_flags)
2435 : FEInterfaceValues(fe_collection.get_reference_cell_default_linear_mapping(),
2436 fe_collection,
2437 quadrature_collection,
2438 update_flags)
2439{}
2440
2441
2442
2443template <int dim, int spacedim>
2444template <typename CellIteratorType, typename CellNeighborIteratorType>
2445void
2447 const CellIteratorType &cell,
2448 const unsigned int face_no,
2449 const unsigned int sub_face_no,
2450 const CellNeighborIteratorType &cell_neighbor,
2451 const unsigned int face_no_neighbor,
2452 const unsigned int sub_face_no_neighbor,
2453 const unsigned int q_index,
2454 const unsigned int mapping_index,
2455 const unsigned int fe_index_in,
2456 const unsigned int fe_index_neighbor_in)
2457{
2458 InterfaceData data(face_no,
2459 sub_face_no,
2460 face_no_neighbor,
2461 sub_face_no_neighbor);
2462 data.q_index = q_index;
2463 data.mapping_index = mapping_index;
2464 data.fe_index = fe_index_in;
2465 data.fe_index_neighbor = fe_index_neighbor_in;
2466
2467 reinit(cell, cell_neighbor, data);
2468}
2469
2470
2471
2472template <int dim, int spacedim>
2473template <typename CellIteratorType, typename CellNeighborIteratorType>
2474void
2476 const CellIteratorType &cell,
2477 const CellNeighborIteratorType &cell_neighbor,
2478 const InterfaceData &interface_data)
2479{
2480 Assert(internal_fe_face_values || internal_hp_fe_face_values,
2482
2483 constexpr bool is_dof_cell_accessor =
2484 std::is_same_v<DoFCellAccessor<dim, spacedim, true>,
2485 typename CellIteratorType::AccessorType> ||
2486 std::is_same_v<DoFCellAccessor<dim, spacedim, false>,
2487 typename CellIteratorType::AccessorType>;
2488
2489 constexpr bool is_dof_cell_accessor_neighbor =
2490 std::is_same_v<DoFCellAccessor<dim, spacedim, true>,
2491 typename CellNeighborIteratorType::AccessorType> ||
2492 std::is_same_v<DoFCellAccessor<dim, spacedim, false>,
2493 typename CellNeighborIteratorType::AccessorType>;
2494
2495 const unsigned int face_no = interface_data.face_no;
2496 const unsigned int sub_face_no = interface_data.sub_face_no;
2497 const unsigned int face_no_neighbor = interface_data.face_no_neighbor;
2498 const unsigned int sub_face_no_neighbor = interface_data.sub_face_no_neighbor;
2499
2500 unsigned int active_fe_index = 0;
2501 unsigned int active_fe_index_neighbor = 0;
2502
2503 if (internal_fe_face_values)
2504 {
2505 if (sub_face_no == numbers::invalid_unsigned_int)
2506 {
2507 internal_fe_face_values->reinit(cell, face_no);
2508 fe_face_values = internal_fe_face_values.get();
2509 }
2510 else
2511 {
2512 internal_fe_subface_values->reinit(cell, face_no, sub_face_no);
2513 fe_face_values = internal_fe_subface_values.get();
2514 }
2515 if (sub_face_no_neighbor == numbers::invalid_unsigned_int)
2516 {
2517 internal_fe_face_values_neighbor->reinit(cell_neighbor,
2518 face_no_neighbor);
2519 fe_face_values_neighbor = internal_fe_face_values_neighbor.get();
2520 }
2521 else
2522 {
2523 internal_fe_subface_values_neighbor->reinit(cell_neighbor,
2524 face_no_neighbor,
2525 sub_face_no_neighbor);
2526 fe_face_values_neighbor = internal_fe_subface_values_neighbor.get();
2527 }
2528
2529 AssertDimension(fe_face_values->n_quadrature_points,
2530 fe_face_values_neighbor->n_quadrature_points);
2531
2532 const_cast<unsigned int &>(this->n_quadrature_points) =
2533 fe_face_values->n_quadrature_points;
2534 }
2535 else if (internal_hp_fe_face_values)
2536 {
2537 active_fe_index = interface_data.fe_index;
2538 active_fe_index_neighbor =
2539 (interface_data.fe_index_neighbor == numbers::invalid_unsigned_int) ?
2540 interface_data.fe_index :
2541 interface_data.fe_index_neighbor;
2542
2543 if (active_fe_index == numbers::invalid_unsigned_int)
2544 {
2545 if constexpr (is_dof_cell_accessor)
2546 active_fe_index = cell->active_fe_index();
2547 else
2548 active_fe_index = 0;
2549 }
2550
2551 if (active_fe_index_neighbor == numbers::invalid_unsigned_int)
2552 {
2553 if constexpr (is_dof_cell_accessor_neighbor)
2554 active_fe_index_neighbor = cell_neighbor->active_fe_index();
2555 else
2556 active_fe_index_neighbor = 0;
2557 }
2558
2559 unsigned int used_q_index = interface_data.q_index;
2560 unsigned int used_mapping_index = interface_data.mapping_index;
2561
2562 // First check. If there is only one element in a collection, and if none
2563 // had been specified explicitly, then that's clearly the one to take:
2564 if (used_q_index == numbers::invalid_unsigned_int)
2565 if (internal_hp_fe_face_values->get_quadrature_collection().size() == 1)
2566 used_q_index = 0;
2567
2568 if (used_mapping_index == numbers::invalid_unsigned_int)
2569 if (internal_hp_fe_face_values->get_mapping_collection().size() == 1)
2570 used_mapping_index = 0;
2571
2572 // Second check: See if the two quadrature objects are the same, because
2573 // in that case it does not matter which one we use. Unfortunately, we
2574 // currently have no way of testing that two mapping objects are the
2575 // same :-(
2576 if (used_q_index == numbers::invalid_unsigned_int)
2577 if (internal_hp_fe_face_values
2578 ->get_quadrature_collection()[active_fe_index] ==
2579 internal_hp_fe_face_values
2580 ->get_quadrature_collection()[active_fe_index_neighbor])
2581 used_q_index = active_fe_index;
2582
2583 // Third check, if the above did not already suffice. We see if we
2584 // can get somewhere via the dominated's finite element index.
2585 if ((used_q_index == numbers::invalid_unsigned_int) ||
2586 (used_mapping_index == numbers::invalid_unsigned_int))
2587 {
2588 const unsigned int dominated_fe_index =
2589 ((used_q_index == numbers::invalid_unsigned_int) ||
2590 (used_mapping_index == numbers::invalid_unsigned_int) ?
2591 internal_hp_fe_face_values->get_fe_collection()
2592 .find_dominated_fe(
2593 {active_fe_index, active_fe_index_neighbor}) :
2595
2596 if (used_q_index == numbers::invalid_unsigned_int)
2597 {
2598 Assert(dominated_fe_index != numbers::invalid_fe_index,
2599 ExcMessage(
2600 "You called this function with 'q_index' left at its "
2601 "default value, but this can only work if one of "
2602 "the two finite elements adjacent to this face "
2603 "dominates the other. See the documentation "
2604 "of this function for more information of how "
2605 "to deal with this situation."));
2606 used_q_index = dominated_fe_index;
2607 }
2608
2609 if (used_mapping_index == numbers::invalid_unsigned_int)
2610 {
2611 Assert(dominated_fe_index != numbers::invalid_fe_index,
2612 ExcMessage(
2613 "You called this function with 'mapping_index' left "
2614 "at its default value, but this can only work if one "
2615 "of the two finite elements adjacent to this face "
2616 "dominates the other. See the documentation "
2617 "of this function for more information of how "
2618 "to deal with this situation."));
2619 used_mapping_index = dominated_fe_index;
2620 }
2621 }
2622
2623 // If q_index_neighbor is given use it, if not use the values determined
2624 // before
2625 const unsigned int used_q_index_neighbor =
2626 (interface_data.q_index_neighbor == numbers::invalid_unsigned_int) ?
2627 used_q_index :
2628 interface_data.q_index_neighbor;
2629 // Same as for q_index_neighbor
2630 const unsigned int used_mapping_index_neighbor =
2631 (interface_data.mapping_index_neighbor ==
2633 used_mapping_index :
2634 interface_data.mapping_index_neighbor;
2635
2636 // Same as if above, but when hp is enabled.
2637 if (sub_face_no == numbers::invalid_unsigned_int)
2638 {
2639 internal_hp_fe_face_values->reinit(
2640 cell, face_no, used_q_index, used_mapping_index, active_fe_index);
2642 internal_hp_fe_face_values->get_present_fe_values());
2643 }
2644 else
2645 {
2646 internal_hp_fe_subface_values->reinit(cell,
2647 face_no,
2648 sub_face_no,
2649 used_q_index,
2650 used_mapping_index,
2651 active_fe_index);
2652
2654 internal_hp_fe_subface_values->get_present_fe_values());
2655 }
2656 if (sub_face_no_neighbor == numbers::invalid_unsigned_int)
2657 {
2658 internal_hp_fe_face_values_neighbor->reinit(
2659 cell_neighbor,
2660 face_no_neighbor,
2661 used_q_index_neighbor,
2662 used_mapping_index_neighbor,
2663 active_fe_index_neighbor);
2664
2665 fe_face_values_neighbor = &const_cast<FEFaceValues<dim, spacedim> &>(
2666 internal_hp_fe_face_values_neighbor->get_present_fe_values());
2667 }
2668 else
2669 {
2670 internal_hp_fe_subface_values_neighbor->reinit(
2671 cell_neighbor,
2672 face_no_neighbor,
2673 sub_face_no_neighbor,
2674 used_q_index_neighbor,
2675 used_mapping_index_neighbor,
2676 active_fe_index_neighbor);
2677
2678 fe_face_values_neighbor =
2679 &const_cast<FESubfaceValues<dim, spacedim> &>(
2680 internal_hp_fe_subface_values_neighbor->get_present_fe_values());
2681 }
2682
2683 AssertDimension(fe_face_values->n_quadrature_points,
2684 fe_face_values_neighbor->n_quadrature_points);
2685
2686 const_cast<unsigned int &>(this->n_quadrature_points) =
2687 fe_face_values->n_quadrature_points;
2688 }
2689
2690 // Set up dof mapping and remove duplicates (for continuous elements).
2691 if constexpr (is_dof_cell_accessor_neighbor && is_dof_cell_accessor)
2692 {
2693 // Get dof indices first:
2694 std::vector<types::global_dof_index> v_1(
2695 fe_face_values->get_fe().n_dofs_per_cell());
2696 cell->get_active_or_mg_dof_indices(v_1);
2697 std::vector<types::global_dof_index> v_2(
2698 fe_face_values_neighbor->get_fe().n_dofs_per_cell());
2699 cell_neighbor->get_active_or_mg_dof_indices(v_2);
2700
2701 interface_dof_data.resize(v_1.size() + v_2.size());
2702
2703 // First create a mapping for the DoFs on the first side
2704 // of the interface:
2705 for (unsigned int i = 0; i < v_1.size(); ++i)
2706 interface_dof_data[i] = {v_1[i], {{i, numbers::invalid_unsigned_int}}};
2707
2708 // Then we need to add the DoFs on the second side. We need
2709 // to merge this information with the mapping on the first
2710 // side, which if we left things as is, would result in an O(N^2)
2711 // complexity: For each DoF on the second side, we'd have to search
2712 // all of the ones on the first side. But we can reduce this to
2713 // O(N*log(N)) by sorting the DoFs on the first side, in which
2714 // case finding whether a second-side DoF already exists on the
2715 // first side only requires log(N) steps. So sort the information
2716 // we added above.
2717 //
2718 // In practice, DoF indices on many cells are already sorted
2719 // (because we number them in the first place in the same order
2720 // as we encounter them here). So guard the sorting step by a cheap
2721 // check for whether the data is already sorted:
2722 const auto compare_interface_dofs = [](const auto &interface_dof_1,
2723 const auto &interface_dof_2) {
2724 return (interface_dof_1.first < interface_dof_2.first);
2725 };
2726 const auto interface_dof_data_end_after_v_1 =
2727 interface_dof_data.begin() + v_1.size();
2728 if (std::is_sorted(interface_dof_data.begin(),
2729 interface_dof_data_end_after_v_1,
2730 compare_interface_dofs) == false)
2731 std::sort(interface_dof_data.begin(),
2732 interface_dof_data_end_after_v_1,
2733 compare_interface_dofs);
2734
2735 // Now add the second set of DoFs:
2736 unsigned int idx = v_1.size();
2737 for (unsigned int i = 0; i < v_2.size(); ++i)
2738 {
2739 // Find out whether v2[i] is a DoF that also exists on the first side
2740 // of the interface. If it does, we need to record 'i' in the second
2741 // slot of the map. If it doesn't, record an {invalid,i} entry.
2742 //
2743 // Because we sorted the first set of interface DoFs, finding whether
2744 // a given v_2[i] already exists can be done via std::lower_bound(),
2745 // rather than requiring the much more expensive std::find().
2746 const auto it =
2747 std::lower_bound(interface_dof_data.begin(),
2748 interface_dof_data_end_after_v_1,
2749 v_2[i],
2750 [](const auto &interface_dof_1,
2751 const auto &index) {
2752 return (interface_dof_1.first < index);
2753 });
2754 if ((it != interface_dof_data_end_after_v_1) && (it->first == v_2[i]))
2755 {
2756 it->second[1] = i;
2757 }
2758 else
2759 {
2760 interface_dof_data[idx] = {v_2[i],
2762 ++idx;
2763 }
2764 }
2765 interface_dof_data.resize(idx);
2766 }
2767 else
2768 // We don't have DoF indices associated with at least one of the two
2769 // cells. In that case, only build the mapping from the local numbering
2770 // on the interface to the local numbering on either side, without
2771 // reference to global DoF indices.
2772 {
2773 const unsigned int n_dofs_per_cell_1 = fe_face_values->dofs_per_cell;
2774 const unsigned int n_dofs_per_cell_2 =
2775 fe_face_values_neighbor->dofs_per_cell;
2776
2777 interface_dof_data.resize(n_dofs_per_cell_1 + n_dofs_per_cell_2);
2778
2779 for (unsigned int i = 0; i < n_dofs_per_cell_1; ++i)
2780 {
2781 interface_dof_data[i] = {numbers::invalid_dof_index,
2783 }
2784
2785 for (unsigned int i = 0; i < n_dofs_per_cell_2; ++i)
2786 {
2787 interface_dof_data[i + n_dofs_per_cell_1] = {
2789 }
2790 }
2791}
2792
2793
2794
2795template <int dim, int spacedim>
2796template <typename CellIteratorType>
2797void
2798FEInterfaceValues<dim, spacedim>::reinit(const CellIteratorType &cell,
2799 const unsigned int face_no,
2800 const unsigned int q_index,
2801 const unsigned int mapping_index,
2802 const unsigned int fe_index)
2803{
2804 Assert(internal_fe_face_values || internal_hp_fe_face_values,
2806
2807 if (internal_fe_face_values)
2808 {
2809 Assert((q_index == 0 || q_index == numbers::invalid_unsigned_int),
2811 Assert((mapping_index == 0 ||
2812 mapping_index == numbers::invalid_unsigned_int),
2814 Assert((fe_index == 0 || fe_index == numbers::invalid_unsigned_int),
2816
2817 internal_fe_face_values->reinit(cell, face_no);
2818 fe_face_values = internal_fe_face_values.get();
2819 fe_face_values_neighbor = nullptr;
2820 }
2821 else if (internal_hp_fe_face_values)
2822 {
2823 internal_hp_fe_face_values->reinit(
2824 cell, face_no, q_index, mapping_index, fe_index);
2826 internal_hp_fe_face_values->get_present_fe_values());
2827 fe_face_values_neighbor = nullptr;
2828 }
2829
2830 std::vector<types::global_dof_index> interface_dof_indices(
2831 fe_face_values->get_fe().n_dofs_per_cell());
2832
2833 if constexpr (std::is_same_v<typename CellIteratorType::AccessorType,
2835 std::is_same_v<typename CellIteratorType::AccessorType,
2837 {
2838 cell->get_active_or_mg_dof_indices(interface_dof_indices);
2839 }
2840 else
2841 {
2842 for (auto &i : interface_dof_indices)
2844 }
2845
2846 interface_dof_data.resize(interface_dof_indices.size());
2847 for (unsigned int i = 0; i < interface_dof_indices.size(); ++i)
2848 interface_dof_data[i] = {interface_dof_indices[i],
2850}
2851
2852
2853
2854template <int dim, int spacedim>
2855inline double
2856FEInterfaceValues<dim, spacedim>::JxW(const unsigned int q) const
2857{
2858 Assert(fe_face_values != nullptr,
2859 ExcMessage("This call requires a call to reinit() first."));
2860 return fe_face_values->JxW(q);
2861}
2862
2863
2864
2865template <int dim, int spacedim>
2866const std::vector<double> &
2868{
2869 Assert(fe_face_values != nullptr,
2870 ExcMessage("This call requires a call to reinit() first."));
2871 return fe_face_values->get_JxW_values();
2872}
2873
2874
2875
2876template <int dim, int spacedim>
2877const std::vector<Tensor<1, spacedim>> &
2879{
2880 Assert(fe_face_values != nullptr,
2881 ExcMessage("This call requires a call to reinit() first."));
2882 return fe_face_values->get_normal_vectors();
2883}
2884
2885
2886
2887template <int dim, int spacedim>
2890{
2891 Assert(!has_hp_capabilities(), ExcOnlyAvailableWithoutHP());
2892 return internal_fe_face_values->get_mapping();
2893}
2894
2895
2896
2897template <int dim, int spacedim>
2900{
2901 Assert(!has_hp_capabilities(), ExcOnlyAvailableWithoutHP());
2902 return internal_fe_face_values->get_fe();
2903}
2904
2905
2906
2907template <int dim, int spacedim>
2908const Quadrature<dim - 1> &
2910{
2911 Assert(!has_hp_capabilities(), ExcOnlyAvailableWithoutHP());
2912 return internal_fe_face_values->get_quadrature();
2913}
2914
2915
2916
2917template <int dim, int spacedim>
2920{
2921 Assert(has_hp_capabilities(), ExcOnlyAvailableWithHP());
2922 return internal_hp_fe_face_values->get_mapping_collection();
2923}
2924
2925
2926
2927template <int dim, int spacedim>
2930{
2931 Assert(has_hp_capabilities(), ExcOnlyAvailableWithHP());
2932 return internal_hp_fe_face_values->get_fe_collection();
2933}
2934
2935
2936
2937template <int dim, int spacedim>
2938const hp::QCollection<dim - 1> &
2940{
2941 Assert(has_hp_capabilities(), ExcOnlyAvailableWithHP());
2942 return internal_hp_fe_face_values->get_quadrature_collection();
2943}
2944
2945
2946
2947template <int dim, int spacedim>
2948bool
2950{
2951 if (internal_hp_fe_face_values || internal_hp_fe_subface_values ||
2952 internal_hp_fe_face_values_neighbor ||
2953 internal_hp_fe_subface_values_neighbor)
2954 {
2955 Assert(!internal_fe_face_values, ExcInternalError());
2956 Assert(!internal_fe_subface_values, ExcInternalError());
2957 Assert(!internal_fe_face_values_neighbor, ExcInternalError());
2958 Assert(!internal_fe_subface_values_neighbor, ExcInternalError());
2959
2960 return true;
2961 }
2962
2963 Assert(internal_fe_face_values || internal_fe_subface_values ||
2964 internal_fe_face_values_neighbor ||
2965 internal_fe_subface_values_neighbor,
2967 Assert(!internal_hp_fe_face_values, ExcInternalError());
2968 Assert(!internal_hp_fe_subface_values, ExcInternalError());
2969 Assert(!internal_hp_fe_face_values_neighbor, ExcInternalError());
2970 Assert(!internal_hp_fe_subface_values_neighbor, ExcInternalError());
2971
2972 return false;
2973}
2974
2975
2976
2977template <int dim, int spacedim>
2978inline std_cxx20::ranges::iota_view<unsigned int, unsigned int>
2980{
2981 return std_cxx20::ranges::iota_view<unsigned int, unsigned int>(
2982 0U, n_quadrature_points);
2983}
2984
2985
2986
2987template <int dim, int spacedim>
2988const Point<spacedim> &
2990 const unsigned int q_point) const
2991{
2992 Assert(fe_face_values != nullptr,
2993 ExcMessage("This call requires a call to reinit() first."));
2994 return fe_face_values->quadrature_point(q_point);
2995}
2996
2997
2998
2999template <int dim, int spacedim>
3000const std::vector<Point<spacedim>> &
3002{
3003 Assert(fe_face_values != nullptr,
3004 ExcMessage("This call requires a call to reinit() first."));
3005 return fe_face_values->get_quadrature_points();
3006}
3007
3008
3009
3010template <int dim, int spacedim>
3013{
3014 if (has_hp_capabilities())
3015 return internal_hp_fe_face_values->get_update_flags();
3016 else
3017 return internal_fe_face_values->get_update_flags();
3018}
3019
3020
3021
3022template <int dim, int spacedim>
3024FEInterfaceValues<dim, spacedim>::get_cell(const unsigned int cell_index) const
3025{
3026 return get_fe_face_values(cell_index).get_cell();
3027}
3028
3029
3030
3031template <int dim, int spacedim>
3032inline unsigned int
3034 const unsigned int cell_index) const
3035{
3036 return get_fe_face_values(cell_index).get_face_number();
3037}
3038
3039
3040
3041template <int dim, int spacedim>
3042unsigned
3044{
3045 Assert(
3046 interface_dof_data.size() > 0,
3047 ExcMessage(
3048 "n_current_interface_dofs() is only available after a call to reinit()."));
3049 return interface_dof_data.size();
3050}
3051
3052
3053
3054template <int dim, int spacedim>
3055inline std_cxx20::ranges::iota_view<unsigned int, unsigned int>
3057{
3058 return std_cxx20::ranges::iota_view<unsigned int, unsigned int>(
3059 0U, n_current_interface_dofs());
3060}
3061
3062
3063
3064template <int dim, int spacedim>
3065bool
3067{
3068 return fe_face_values_neighbor == nullptr;
3069}
3070
3071
3072
3073template <int dim, int spacedim>
3074std::vector<types::global_dof_index>
3076{
3077 std::vector<types::global_dof_index> interface_dof_indices(
3078 interface_dof_data.size());
3079
3080 for (const unsigned int i : dof_indices())
3081 interface_dof_indices[i] = interface_dof_data[i].first;
3082
3083 return interface_dof_indices;
3084}
3085
3086
3087
3088template <int dim, int spacedim>
3089std::array<unsigned int, 2>
3091 const unsigned int interface_dof_index) const
3092{
3093 AssertIndexRange(interface_dof_index, n_current_interface_dofs());
3094 return interface_dof_data[interface_dof_index].second;
3095}
3096
3097
3098
3099template <int dim, int spacedim>
3102 const unsigned int cell_index) const
3103{
3104 AssertIndexRange(cell_index, 2);
3105 Assert(
3106 cell_index == 0 || !at_boundary(),
3107 ExcMessage(
3108 "You are on a boundary, so you can only ask for the first FEFaceValues object."));
3109
3110 return (cell_index == 0) ? *fe_face_values : *fe_face_values_neighbor;
3111}
3112
3113
3114
3115template <int dim, int spacedim>
3117FEInterfaceValues<dim, spacedim>::normal(const unsigned int q_point_index) const
3118{
3119 return normal_vector(q_point_index);
3120}
3121
3122
3123
3124template <int dim, int spacedim>
3127 const unsigned int q_point_index) const
3128{
3129 return fe_face_values->normal_vector(q_point_index);
3130}
3131
3132
3133
3134template <int dim, int spacedim>
3135double
3137 const bool here_or_there,
3138 const unsigned int interface_dof_index,
3139 const unsigned int q_point,
3140 const unsigned int component) const
3141{
3142 const auto dof_pair = interface_dof_to_dof_indices(interface_dof_index);
3143
3144 if (here_or_there && dof_pair[0] != numbers::invalid_unsigned_int)
3145 return get_fe_face_values(0).shape_value_component(dof_pair[0],
3146 q_point,
3147 component);
3148 if (!here_or_there && dof_pair[1] != numbers::invalid_unsigned_int)
3149 return get_fe_face_values(1).shape_value_component(dof_pair[1],
3150 q_point,
3151 component);
3152
3153 return 0.0;
3154}
3155
3156
3157template <int dim, int spacedim>
3160 const bool here_or_there,
3161 const unsigned int interface_dof_index,
3162 const unsigned int q_point,
3163 const unsigned int component) const
3164{
3165 const auto dof_pair = interface_dof_to_dof_indices(interface_dof_index);
3166
3168
3169 if (here_or_there && dof_pair[0] != numbers::invalid_unsigned_int)
3170 value = get_fe_face_values(0).shape_grad_component(dof_pair[0],
3171 q_point,
3172 component);
3173 if (!here_or_there && dof_pair[1] != numbers::invalid_unsigned_int)
3174 value = get_fe_face_values(1).shape_grad_component(dof_pair[1],
3175 q_point,
3176 component);
3177
3178 return value;
3179}
3180
3181template <int dim, int spacedim>
3182double
3184 const unsigned int interface_dof_index,
3185 const unsigned int q_point,
3186 const unsigned int component) const
3187{
3188 const auto dof_pair = interface_dof_to_dof_indices(interface_dof_index);
3189
3190 double value = 0.0;
3191
3192 if (dof_pair[0] != numbers::invalid_unsigned_int)
3193 value += get_fe_face_values(0).shape_value_component(dof_pair[0],
3194 q_point,
3195 component);
3196 if (dof_pair[1] != numbers::invalid_unsigned_int)
3197 value -= get_fe_face_values(1).shape_value_component(dof_pair[1],
3198 q_point,
3199 component);
3200 return value;
3201}
3202
3203
3204
3205template <int dim, int spacedim>
3206double
3208 const unsigned int interface_dof_index,
3209 const unsigned int q_point,
3210 const unsigned int component) const
3211{
3212 const auto dof_pair = interface_dof_to_dof_indices(interface_dof_index);
3213
3214 if (at_boundary())
3215 return get_fe_face_values(0).shape_value_component(dof_pair[0],
3216 q_point,
3217 component);
3218
3219 double value = 0.0;
3220
3221 if (dof_pair[0] != numbers::invalid_unsigned_int)
3222 value += 0.5 * get_fe_face_values(0).shape_value_component(dof_pair[0],
3223 q_point,
3224 component);
3225 if (dof_pair[1] != numbers::invalid_unsigned_int)
3226 value += 0.5 * get_fe_face_values(1).shape_value_component(dof_pair[1],
3227 q_point,
3228 component);
3229
3230 return value;
3231}
3232
3233
3234
3235template <int dim, int spacedim>
3238 const unsigned int interface_dof_index,
3239 const unsigned int q_point,
3240 const unsigned int component) const
3241{
3242 const auto dof_pair = interface_dof_to_dof_indices(interface_dof_index);
3243
3244 if (at_boundary())
3245 return get_fe_face_values(0).shape_grad_component(dof_pair[0],
3246 q_point,
3247 component);
3248
3250
3251 if (dof_pair[0] != numbers::invalid_unsigned_int)
3252 value += 0.5 * get_fe_face_values(0).shape_grad_component(dof_pair[0],
3253 q_point,
3254 component);
3255 if (dof_pair[1] != numbers::invalid_unsigned_int)
3256 value += 0.5 * get_fe_face_values(1).shape_grad_component(dof_pair[1],
3257 q_point,
3258 component);
3259
3260 return value;
3261}
3262
3263
3264
3265template <int dim, int spacedim>
3268 const unsigned int interface_dof_index,
3269 const unsigned int q_point,
3270 const unsigned int component) const
3271{
3272 const auto dof_pair = interface_dof_to_dof_indices(interface_dof_index);
3273
3274 if (at_boundary())
3275 return get_fe_face_values(0).shape_hessian_component(dof_pair[0],
3276 q_point,
3277 component);
3278
3280
3281 if (dof_pair[0] != numbers::invalid_unsigned_int)
3282 value += 0.5 * get_fe_face_values(0).shape_hessian_component(dof_pair[0],
3283 q_point,
3284 component);
3285 if (dof_pair[1] != numbers::invalid_unsigned_int)
3286 value += 0.5 * get_fe_face_values(1).shape_hessian_component(dof_pair[1],
3287 q_point,
3288 component);
3289
3290 return value;
3291}
3292
3293
3294
3295template <int dim, int spacedim>
3298 const unsigned int interface_dof_index,
3299 const unsigned int q_point,
3300 const unsigned int component) const
3301{
3302 const auto dof_pair = interface_dof_to_dof_indices(interface_dof_index);
3303
3304 if (at_boundary())
3305 return get_fe_face_values(0).shape_grad_component(dof_pair[0],
3306 q_point,
3307 component);
3308
3310
3311 if (dof_pair[0] != numbers::invalid_unsigned_int)
3312 value += get_fe_face_values(0).shape_grad_component(dof_pair[0],
3313 q_point,
3314 component);
3315 if (dof_pair[1] != numbers::invalid_unsigned_int)
3316 value -= get_fe_face_values(1).shape_grad_component(dof_pair[1],
3317 q_point,
3318 component);
3319
3320 return value;
3321}
3322
3323
3324
3325template <int dim, int spacedim>
3328 const unsigned int interface_dof_index,
3329 const unsigned int q_point,
3330 const unsigned int component) const
3331{
3332 const auto dof_pair = interface_dof_to_dof_indices(interface_dof_index);
3333
3334 if (at_boundary())
3335 return get_fe_face_values(0).shape_hessian_component(dof_pair[0],
3336 q_point,
3337 component);
3338
3340
3341 if (dof_pair[0] != numbers::invalid_unsigned_int)
3342 value += get_fe_face_values(0).shape_hessian_component(dof_pair[0],
3343 q_point,
3344 component);
3345 if (dof_pair[1] != numbers::invalid_unsigned_int)
3346 value -= get_fe_face_values(1).shape_hessian_component(dof_pair[1],
3347 q_point,
3348 component);
3349
3350 return value;
3351}
3352
3353
3354
3355template <int dim, int spacedim>
3358 const unsigned int interface_dof_index,
3359 const unsigned int q_point,
3360 const unsigned int component) const
3361{
3362 const auto dof_pair = interface_dof_to_dof_indices(interface_dof_index);
3363
3364 if (at_boundary())
3365 return get_fe_face_values(0).shape_3rd_derivative_component(dof_pair[0],
3366 q_point,
3367 component);
3368
3370
3371 if (dof_pair[0] != numbers::invalid_unsigned_int)
3372 value += get_fe_face_values(0).shape_3rd_derivative_component(dof_pair[0],
3373 q_point,
3374 component);
3375 if (dof_pair[1] != numbers::invalid_unsigned_int)
3376 value -= get_fe_face_values(1).shape_3rd_derivative_component(dof_pair[1],
3377 q_point,
3378 component);
3379
3380 return value;
3381}
3382
3383
3384
3385template <int dim, int spacedim>
3386template <class InputVector>
3387void
3389 const InputVector &fe_function,
3390 std::vector<typename InputVector::value_type> &values) const
3391{
3392 AssertDimension(values.size(), n_quadrature_points);
3393
3395 this->operator[](scalar).get_jump_in_function_values(fe_function, values);
3396}
3397
3398
3399
3400template <int dim, int spacedim>
3401template <class InputVector>
3402void
3404 const InputVector &fe_function,
3406 const
3407{
3408 AssertDimension(gradients.size(), n_quadrature_points);
3409
3411 this->operator[](scalar).get_jump_in_function_gradients(fe_function,
3412 gradients);
3413}
3414
3415
3416
3417template <int dim, int spacedim>
3418template <class InputVector>
3419void
3421 const InputVector &fe_function,
3423 const
3424{
3425 AssertDimension(hessians.size(), n_quadrature_points);
3426
3428 this->operator[](scalar).get_jump_in_function_hessians(fe_function, hessians);
3429}
3430
3431
3432
3433template <int dim, int spacedim>
3434template <class InputVector>
3435void
3437 const InputVector &fe_function,
3439 &third_derivatives) const
3440{
3441 AssertDimension(third_derivatives.size(), n_quadrature_points);
3442
3444 this->operator[](scalar).get_jump_in_function_third_derivatives(
3445 fe_function, third_derivatives);
3446}
3447
3448
3449
3450template <int dim, int spacedim>
3451template <class InputVector>
3452void
3454 const InputVector &fe_function,
3455 std::vector<typename InputVector::value_type> &values) const
3456{
3457 AssertDimension(values.size(), n_quadrature_points);
3458
3460 this->operator[](scalar).get_average_of_function_values(fe_function, values);
3461}
3462
3463
3464
3465template <int dim, int spacedim>
3466template <class InputVector>
3467void
3469 const InputVector &fe_function,
3471 const
3472{
3473 AssertDimension(gradients.size(), n_quadrature_points);
3474
3476 this->operator[](scalar).get_average_of_function_gradients(fe_function,
3477 gradients);
3478}
3479
3480
3481
3482template <int dim, int spacedim>
3483template <class InputVector>
3484void
3486 const InputVector &fe_function,
3488 const
3489{
3490 AssertDimension(hessians.size(), n_quadrature_points);
3491
3493 this->operator[](scalar).get_average_of_function_hessians(fe_function,
3494 hessians);
3495}
3496
3497
3498
3499/*------------ Inline functions: FEInterfaceValues------------*/
3500template <int dim, int spacedim>
3503 const FEValuesExtractors::Scalar &scalar) const
3504{
3505 const unsigned int n_components =
3506 (this->has_hp_capabilities() ? this->get_fe_collection().n_components() :
3507 this->get_fe().n_components());
3508 (void)n_components;
3509 AssertIndexRange(scalar.component, n_components);
3510 return FEInterfaceViews::Scalar<dim, spacedim>(*this, scalar.component);
3511}
3512
3513
3514
3515template <int dim, int spacedim>
3518 const FEValuesExtractors::Vector &vector) const
3519{
3520 const unsigned int n_components =
3521 (this->has_hp_capabilities() ? this->get_fe_collection().n_components() :
3522 this->get_fe().n_components());
3523 const unsigned int n_vectors =
3526 0);
3527 (void)n_components;
3528 (void)n_vectors;
3529 AssertIndexRange(vector.first_vector_component, n_vectors);
3531 vector.first_vector_component);
3532}
3533
3534
3535
3536namespace FEInterfaceViews
3537{
3538 template <int dim, int spacedim>
3540 const FEInterfaceValues<dim, spacedim> &fe_interface)
3541 : fe_interface(&fe_interface)
3542 {}
3543
3544
3545
3546 template <int dim, int spacedim>
3547 Scalar<dim, spacedim>::Scalar(
3548 const FEInterfaceValues<dim, spacedim> &fe_interface,
3549 const unsigned int component)
3550 : Base<dim, spacedim>(fe_interface)
3551 , extractor(component)
3552 {}
3553
3554
3555
3556 template <int dim, int spacedim>
3557 template <class InputVector, class OutputVector>
3558 void
3559 Base<dim, spacedim>::get_local_dof_values(
3560 const InputVector &dof_values,
3561 OutputVector &local_dof_values) const
3562 {
3563 const auto &interface_dof_indices =
3564 this->fe_interface->get_interface_dof_indices();
3565
3566 AssertDimension(interface_dof_indices.size(), local_dof_values.size());
3567
3568 for (const unsigned int i : this->fe_interface->dof_indices())
3569 local_dof_values[i] = dof_values(interface_dof_indices[i]);
3570 }
3571
3572
3573
3574 template <int dim, int spacedim>
3575 typename Scalar<dim, spacedim>::value_type
3576 Scalar<dim, spacedim>::value(const bool here_or_there,
3577 const unsigned int interface_dof_index,
3578 const unsigned int q_point) const
3579 {
3580 const auto dof_pair =
3581 this->fe_interface->interface_dof_to_dof_indices(interface_dof_index);
3582
3583 if (here_or_there && dof_pair[0] != numbers::invalid_unsigned_int)
3584 return (*(this->fe_interface->fe_face_values))[extractor].value(
3585 dof_pair[0], q_point);
3586
3587 if (!here_or_there && dof_pair[1] != numbers::invalid_unsigned_int)
3588 return (*(this->fe_interface->fe_face_values_neighbor))[extractor].value(
3589 dof_pair[1], q_point);
3590
3591 return 0.0;
3592 }
3593
3594
3595
3596 template <int dim, int spacedim>
3597 typename Scalar<dim, spacedim>::gradient_type
3598 Scalar<dim, spacedim>::gradient(const bool here_or_there,
3599 const unsigned int interface_dof_index,
3600 const unsigned int q_point) const
3601 {
3602 const auto dof_pair =
3603 this->fe_interface->interface_dof_to_dof_indices(interface_dof_index);
3604
3605 gradient_type value;
3606
3607 if (here_or_there && dof_pair[0] != numbers::invalid_unsigned_int)
3608 return (*(this->fe_interface->fe_face_values))[extractor].gradient(
3609 dof_pair[0], q_point);
3610
3611 if (!here_or_there && dof_pair[1] != numbers::invalid_unsigned_int)
3612 return (*(this->fe_interface->fe_face_values_neighbor))[extractor]
3613 .gradient(dof_pair[1], q_point);
3614
3615 return value;
3616 }
3617
3618
3619
3620 template <int dim, int spacedim>
3621 typename Scalar<dim, spacedim>::value_type
3622 Scalar<dim, spacedim>::jump_in_values(const unsigned int interface_dof_index,
3623 const unsigned int q_point) const
3624 {
3625 const auto dof_pair =
3626 this->fe_interface->interface_dof_to_dof_indices(interface_dof_index);
3627
3628 value_type value = 0.0;
3629
3630 if (dof_pair[0] != numbers::invalid_unsigned_int)
3631 value +=
3632 (*(this->fe_interface->fe_face_values))[extractor].value(dof_pair[0],
3633 q_point);
3634
3635 if (dof_pair[1] != numbers::invalid_unsigned_int)
3636 value -=
3637 (*(this->fe_interface->fe_face_values_neighbor))[extractor].value(
3638 dof_pair[1], q_point);
3639
3640 return value;
3641 }
3642
3643
3644
3645 template <int dim, int spacedim>
3646 typename Scalar<dim, spacedim>::value_type
3647 Scalar<dim, spacedim>::average_of_values(
3648 const unsigned int interface_dof_index,
3649 const unsigned int q_point) const
3650 {
3651 const auto dof_pair =
3652 this->fe_interface->interface_dof_to_dof_indices(interface_dof_index);
3653
3654 if (this->fe_interface->at_boundary())
3655 return (*(this->fe_interface->fe_face_values))[extractor].value(
3656 dof_pair[0], q_point);
3657
3658 value_type value = 0.0;
3659
3660 if (dof_pair[0] != numbers::invalid_unsigned_int)
3661 value +=
3662 0.5 *
3663 (*(this->fe_interface->fe_face_values))[extractor].value(dof_pair[0],
3664 q_point);
3665
3666 if (dof_pair[1] != numbers::invalid_unsigned_int)
3667 value +=
3668 0.5 * (*(this->fe_interface->fe_face_values_neighbor))[extractor].value(
3669 dof_pair[1], q_point);
3670
3671 return value;
3672 }
3673
3674
3675
3676 template <int dim, int spacedim>
3677 typename Scalar<dim, spacedim>::gradient_type
3678 Scalar<dim, spacedim>::average_of_gradients(
3679 const unsigned int interface_dof_index,
3680 const unsigned int q_point) const
3681 {
3682 const auto dof_pair =
3683 this->fe_interface->interface_dof_to_dof_indices(interface_dof_index);
3684
3685 if (this->fe_interface->at_boundary())
3686 return (*(this->fe_interface->fe_face_values))[extractor].gradient(
3687 dof_pair[0], q_point);
3688
3689 gradient_type value;
3690
3691 if (dof_pair[0] != numbers::invalid_unsigned_int)
3692 value +=
3693 0.5 *
3694 (*(this->fe_interface->fe_face_values))[extractor].gradient(dof_pair[0],
3695 q_point);
3696
3697 if (dof_pair[1] != numbers::invalid_unsigned_int)
3698 value += 0.5 * (*(this->fe_interface->fe_face_values_neighbor))[extractor]
3699 .gradient(dof_pair[1], q_point);
3700
3701 return value;
3702 }
3703
3704
3705
3706 template <int dim, int spacedim>
3707 typename Scalar<dim, spacedim>::gradient_type
3708 Scalar<dim, spacedim>::jump_in_gradients(
3709 const unsigned int interface_dof_index,
3710 const unsigned int q_point) const
3711 {
3712 const auto dof_pair =
3713 this->fe_interface->interface_dof_to_dof_indices(interface_dof_index);
3714
3715 if (this->fe_interface->at_boundary())
3716 return (*(this->fe_interface->fe_face_values))[extractor].gradient(
3717 dof_pair[0], q_point);
3718
3719 gradient_type value;
3720
3721 if (dof_pair[0] != numbers::invalid_unsigned_int)
3722 value +=
3723 (*(this->fe_interface->fe_face_values))[extractor].gradient(dof_pair[0],
3724 q_point);
3725
3726 if (dof_pair[1] != numbers::invalid_unsigned_int)
3727 value -=
3728 (*(this->fe_interface->fe_face_values_neighbor))[extractor].gradient(
3729 dof_pair[1], q_point);
3730
3731 return value;
3732 }
3733
3734
3735
3736 template <int dim, int spacedim>
3737 typename Scalar<dim, spacedim>::hessian_type
3738 Scalar<dim, spacedim>::average_of_hessians(
3739 const unsigned int interface_dof_index,
3740 const unsigned int q_point) const
3741 {
3742 const auto dof_pair =
3743 this->fe_interface->interface_dof_to_dof_indices(interface_dof_index);
3744
3745 if (this->fe_interface->at_boundary())
3746 return (*(this->fe_interface->fe_face_values))[extractor].hessian(
3747 dof_pair[0], q_point);
3748
3749 hessian_type value;
3750
3751 if (dof_pair[0] != numbers::invalid_unsigned_int)
3752 value +=
3753 0.5 *
3754 (*(this->fe_interface->fe_face_values))[extractor].hessian(dof_pair[0],
3755 q_point);
3756
3757 if (dof_pair[1] != numbers::invalid_unsigned_int)
3758 value += 0.5 * (*(this->fe_interface->fe_face_values_neighbor))[extractor]
3759 .hessian(dof_pair[1], q_point);
3760
3761 return value;
3762 }
3763
3764
3765
3766 template <int dim, int spacedim>
3767 typename Scalar<dim, spacedim>::third_derivative_type
3768 Scalar<dim, spacedim>::jump_in_third_derivatives(
3769 const unsigned int interface_dof_index,
3770 const unsigned int q_point) const
3771 {
3772 const auto dof_pair =
3773 this->fe_interface->interface_dof_to_dof_indices(interface_dof_index);
3774
3775 if (this->fe_interface->at_boundary())
3776 return (*(this->fe_interface->fe_face_values))[extractor]
3777 .third_derivative(dof_pair[0], q_point);
3778
3779 third_derivative_type value;
3780
3781 if (dof_pair[0] != numbers::invalid_unsigned_int)
3782 value +=
3783 (*(this->fe_interface->fe_face_values))[extractor].third_derivative(
3784 dof_pair[0], q_point);
3785
3786 if (dof_pair[1] != numbers::invalid_unsigned_int)
3787 value -= (*(this->fe_interface->fe_face_values_neighbor))[extractor]
3788 .third_derivative(dof_pair[1], q_point);
3789
3790 return value;
3791 }
3792
3793
3794
3795 template <int dim, int spacedim>
3796 typename Scalar<dim, spacedim>::hessian_type
3797 Scalar<dim, spacedim>::jump_in_hessians(
3798 const unsigned int interface_dof_index,
3799 const unsigned int q_point) const
3800 {
3801 const auto dof_pair =
3802 this->fe_interface->interface_dof_to_dof_indices(interface_dof_index);
3803
3804 if (this->fe_interface->at_boundary())
3805 return (*(this->fe_interface->fe_face_values))[extractor].hessian(
3806 dof_pair[0], q_point);
3807
3808 hessian_type value;
3809
3810 if (dof_pair[0] != numbers::invalid_unsigned_int)
3811 value +=
3812 (*(this->fe_interface->fe_face_values))[extractor].hessian(dof_pair[0],
3813 q_point);
3814
3815 if (dof_pair[1] != numbers::invalid_unsigned_int)
3816 value -=
3817 (*(this->fe_interface->fe_face_values_neighbor))[extractor].hessian(
3818 dof_pair[1], q_point);
3819
3820 return value;
3821 }
3822
3823
3824
3825 template <int dim, int spacedim>
3826 template <class InputVector>
3827 void
3828 Scalar<dim, spacedim>::get_function_values_from_local_dof_values(
3829 const bool here_or_there,
3830 const InputVector &local_dof_values,
3831 std::vector<solution_value_type<typename InputVector::value_type>> &values)
3832 const
3833 {
3834 AssertDimension(values.size(), this->fe_interface->n_quadrature_points);
3835
3836 for (const auto dof_index : this->fe_interface->dof_indices())
3837 for (const auto q_index : this->fe_interface->quadrature_point_indices())
3838 {
3839 if (dof_index == 0)
3840 values[q_index] = 0.;
3841
3842 values[q_index] += local_dof_values[dof_index] *
3843 value(here_or_there, dof_index, q_index);
3844 }
3845 }
3846
3847
3848
3849 template <int dim, int spacedim>
3850 template <class InputVector>
3851 void
3852 Scalar<dim, spacedim>::get_function_values(
3853 const bool here_or_there,
3854 const InputVector &fe_function,
3855 std::vector<solution_value_type<typename InputVector::value_type>> &values)
3856 const
3857 {
3858 std::vector<typename InputVector::value_type> local_dof_values(
3859 this->fe_interface->n_current_interface_dofs());
3860 this->get_local_dof_values(fe_function, local_dof_values);
3861
3862 get_function_values_from_local_dof_values(here_or_there,
3863 local_dof_values,
3864 values);
3865 }
3866
3867
3868
3869 template <int dim, int spacedim>
3870 template <class InputVector>
3871 void
3872 Scalar<dim, spacedim>::get_jump_in_function_values_from_local_dof_values(
3873 const InputVector &local_dof_values,
3874 std::vector<solution_value_type<typename InputVector::value_type>> &values)
3875 const
3876 {
3877 AssertDimension(values.size(), this->fe_interface->n_quadrature_points);
3878
3879 for (const auto dof_index : this->fe_interface->dof_indices())
3880 for (const auto q_index : this->fe_interface->quadrature_point_indices())
3881 {
3882 if (dof_index == 0)
3883 values[q_index] = 0.;
3884
3885 values[q_index] +=
3886 local_dof_values[dof_index] * jump_in_values(dof_index, q_index);
3887 }
3888 }
3889
3890
3891
3892 template <int dim, int spacedim>
3893 template <class InputVector>
3894 void
3895 Scalar<dim, spacedim>::get_jump_in_function_values(
3896 const InputVector &fe_function,
3897 std::vector<solution_value_type<typename InputVector::value_type>> &values)
3898 const
3899 {
3900 std::vector<typename InputVector::value_type> local_dof_values(
3901 this->fe_interface->n_current_interface_dofs());
3902 this->get_local_dof_values(fe_function, local_dof_values);
3903
3904 get_jump_in_function_values_from_local_dof_values(local_dof_values, values);
3905 }
3906
3907
3908
3909 template <int dim, int spacedim>
3910 template <class InputVector>
3911 void
3912 Scalar<dim, spacedim>::get_jump_in_function_gradients_from_local_dof_values(
3913 const InputVector &local_dof_values,
3914 std::vector<solution_gradient_type<typename InputVector::value_type>>
3915 &gradients) const
3916 {
3917 AssertDimension(gradients.size(), this->fe_interface->n_quadrature_points);
3918
3919 for (const auto dof_index : this->fe_interface->dof_indices())
3920 for (const auto q_index : this->fe_interface->quadrature_point_indices())
3921 {
3922 if (dof_index == 0)
3923 gradients[q_index] = 0.;
3924
3925 gradients[q_index] +=
3926 local_dof_values[dof_index] * jump_in_gradients(dof_index, q_index);
3927 }
3928 }
3929
3930
3931
3932 template <int dim, int spacedim>
3933 template <class InputVector>
3934 void
3935 Scalar<dim, spacedim>::get_jump_in_function_gradients(
3936 const InputVector &fe_function,
3937 std::vector<solution_gradient_type<typename InputVector::value_type>>
3938 &gradients) const
3939 {
3940 std::vector<typename InputVector::value_type> local_dof_values(
3941 this->fe_interface->n_current_interface_dofs());
3942 this->get_local_dof_values(fe_function, local_dof_values);
3943
3944 get_jump_in_function_gradients_from_local_dof_values(local_dof_values,
3945 gradients);
3946 }
3947
3948
3949
3950 template <int dim, int spacedim>
3951 template <class InputVector>
3952 void
3953 Scalar<dim, spacedim>::get_average_of_function_values_from_local_dof_values(
3954 const InputVector &local_dof_values,
3955 std::vector<solution_value_type<typename InputVector::value_type>> &values)
3956 const
3957 {
3958 AssertDimension(values.size(), this->fe_interface->n_quadrature_points);
3959
3960 for (const auto dof_index : this->fe_interface->dof_indices())
3961 for (const auto q_index : this->fe_interface->quadrature_point_indices())
3962 {
3963 if (dof_index == 0)
3964 values[q_index] = 0.;
3965
3966 values[q_index] +=
3967 local_dof_values[dof_index] * average_of_values(dof_index, q_index);
3968 }
3969 }
3970
3971
3972
3973 template <int dim, int spacedim>
3974 template <class InputVector>
3975 void
3976 Scalar<dim, spacedim>::get_average_of_function_values(
3977 const InputVector &fe_function,
3978 std::vector<solution_value_type<typename InputVector::value_type>> &values)
3979 const
3980 {
3981 std::vector<typename InputVector::value_type> local_dof_values(
3982 this->fe_interface->n_current_interface_dofs());
3983 this->get_local_dof_values(fe_function, local_dof_values);
3984
3985 get_average_of_function_values_from_local_dof_values(local_dof_values,
3986 values);
3987 }
3988
3989
3990
3991 template <int dim, int spacedim>
3992 template <class InputVector>
3993 void
3994 Scalar<dim, spacedim>::
3995 get_average_of_function_gradients_from_local_dof_values(
3996 const InputVector &local_dof_values,
3997 std::vector<solution_gradient_type<typename InputVector::value_type>>
3998 &gradients) const
3999 {
4000 AssertDimension(gradients.size(), this->fe_interface->n_quadrature_points);
4001
4002 for (const auto dof_index : this->fe_interface->dof_indices())
4003 for (const auto q_index : this->fe_interface->quadrature_point_indices())
4004 {
4005 if (dof_index == 0)
4006 gradients[q_index] = 0.;
4007
4008 gradients[q_index] += local_dof_values[dof_index] *
4009 average_of_gradients(dof_index, q_index);
4010 }
4011 }
4012
4013
4014
4015 template <int dim, int spacedim>
4016 template <class InputVector>
4017 void
4018 Scalar<dim, spacedim>::get_average_of_function_gradients(
4019 const InputVector &fe_function,
4020 std::vector<solution_gradient_type<typename InputVector::value_type>>
4021 &gradients) const
4022 {
4023 std::vector<typename InputVector::value_type> local_dof_values(
4024 this->fe_interface->n_current_interface_dofs());
4025 this->get_local_dof_values(fe_function, local_dof_values);
4026
4027 get_average_of_function_gradients_from_local_dof_values(local_dof_values,
4028 gradients);
4029 }
4030
4031
4032
4033 template <int dim, int spacedim>
4034 template <class InputVector>
4035 void
4036 Scalar<dim, spacedim>::get_jump_in_function_hessians_from_local_dof_values(
4037 const InputVector &local_dof_values,
4038 std::vector<solution_hessian_type<typename InputVector::value_type>>
4039 &hessians) const
4040 {
4041 AssertDimension(hessians.size(), this->fe_interface->n_quadrature_points);
4042
4043 for (const auto dof_index : this->fe_interface->dof_indices())
4044 for (const auto q_index : this->fe_interface->quadrature_point_indices())
4045 {
4046 if (dof_index == 0)
4047 hessians[q_index] = 0.;
4048
4049 hessians[q_index] +=
4050 local_dof_values[dof_index] * jump_in_hessians(dof_index, q_index);
4051 }
4052 }
4053
4054
4055
4056 template <int dim, int spacedim>
4057 template <class InputVector>
4058 void
4059 Scalar<dim, spacedim>::get_jump_in_function_hessians(
4060 const InputVector &fe_function,
4061 std::vector<solution_hessian_type<typename InputVector::value_type>>
4062 &hessians) const
4063 {
4064 std::vector<typename InputVector::value_type> local_dof_values(
4065 this->fe_interface->n_current_interface_dofs());
4066 this->get_local_dof_values(fe_function, local_dof_values);
4067
4068 get_jump_in_function_hessians_from_local_dof_values(local_dof_values,
4069 hessians);
4070 }
4071
4072
4073
4074 template <int dim, int spacedim>
4075 template <class InputVector>
4076 void
4077 Scalar<dim, spacedim>::get_average_of_function_hessians_from_local_dof_values(
4078 const InputVector &local_dof_values,
4079 std::vector<solution_hessian_type<typename InputVector::value_type>>
4080 &hessians) const
4081 {
4082 AssertDimension(hessians.size(), this->fe_interface->n_quadrature_points);
4083
4084 for (const unsigned int dof_index : this->fe_interface->dof_indices())
4085 for (const auto q_index : this->fe_interface->quadrature_point_indices())
4086 {
4087 if (dof_index == 0)
4088 hessians[q_index] = 0.;
4089
4090 hessians[q_index] += local_dof_values[dof_index] *
4091 average_of_hessians(dof_index, q_index);
4092 }
4093 }
4094
4095
4096
4097 template <int dim, int spacedim>
4098 template <class InputVector>
4099 void
4100 Scalar<dim, spacedim>::get_average_of_function_hessians(
4101 const InputVector &fe_function,
4102 std::vector<solution_hessian_type<typename InputVector::value_type>>
4103 &hessians) const
4104 {
4105 std::vector<typename InputVector::value_type> local_dof_values(
4106 this->fe_interface->n_current_interface_dofs());
4107 this->get_local_dof_values(fe_function, local_dof_values);
4108
4109 get_average_of_function_hessians_from_local_dof_values(local_dof_values,
4110 hessians);
4111 }
4112
4113
4114
4115 template <int dim, int spacedim>
4116 template <class InputVector>
4117 void
4118 Scalar<dim, spacedim>::
4119 get_jump_in_function_third_derivatives_from_local_dof_values(
4120 const InputVector &local_dof_values,
4121 std::vector<
4122 solution_third_derivative_type<typename InputVector::value_type>>
4123 &third_derivatives) const
4124 {
4125 AssertDimension(third_derivatives.size(),
4126 this->fe_interface->n_quadrature_points);
4127
4128 for (const unsigned int dof_index : this->fe_interface->dof_indices())
4129 for (const auto q_index : this->fe_interface->quadrature_point_indices())
4130 {
4131 if (dof_index == 0)
4132 third_derivatives[q_index] = 0.;
4133
4134 third_derivatives[q_index] +=
4135 local_dof_values[dof_index] *
4136 jump_in_third_derivatives(dof_index, q_index);
4137 }
4138 }
4139
4140
4141
4142 template <int dim, int spacedim>
4143 template <class InputVector>
4144 void
4145 Scalar<dim, spacedim>::get_jump_in_function_third_derivatives(
4146 const InputVector &fe_function,
4147 std::vector<
4148 solution_third_derivative_type<typename InputVector::value_type>>
4149 &third_derivatives) const
4150 {
4151 std::vector<typename InputVector::value_type> local_dof_values(
4152 this->fe_interface->n_current_interface_dofs());
4153 this->get_local_dof_values(fe_function, local_dof_values);
4154
4155 get_jump_in_function_third_derivatives_from_local_dof_values(
4156 local_dof_values, third_derivatives);
4157 }
4158
4159
4160
4161 template <int dim, int spacedim>
4163 const FEInterfaceValues<dim, spacedim> &fe_interface,
4164 const unsigned int first_vector_component)
4165 : Base<dim, spacedim>(fe_interface)
4166 , extractor(first_vector_component)
4167 {}
4168
4169
4170
4171 template <int dim, int spacedim>
4173 Vector<dim, spacedim>::value(const bool here_or_there,
4174 const unsigned int interface_dof_index,
4175 const unsigned int q_point) const
4176 {
4177 const auto dof_pair =
4178 this->fe_interface->interface_dof_to_dof_indices(interface_dof_index);
4179
4180 if (here_or_there && dof_pair[0] != numbers::invalid_unsigned_int)
4181 return (*(this->fe_interface->fe_face_values))[extractor].value(
4182 dof_pair[0], q_point);
4183
4184 if (!here_or_there && dof_pair[1] != numbers::invalid_unsigned_int)
4185 return (*(this->fe_interface->fe_face_values_neighbor))[extractor].value(
4186 dof_pair[1], q_point);
4187
4188 return value_type();
4189 }
4190
4191
4192
4193 template <int dim, int spacedim>
4195 Vector<dim, spacedim>::gradient(const bool here_or_there,
4196 const unsigned int interface_dof_index,
4197 const unsigned int q_point) const
4198 {
4199 const auto dof_pair =
4200 this->fe_interface->interface_dof_to_dof_indices(interface_dof_index);
4201
4202 gradient_type value;
4203
4204 if (here_or_there && dof_pair[0] != numbers::invalid_unsigned_int)
4205 return (*(this->fe_interface->fe_face_values))[extractor].gradient(
4206 dof_pair[0], q_point);
4207
4208 if (!here_or_there && dof_pair[1] != numbers::invalid_unsigned_int)
4209 return (*(this->fe_interface->fe_face_values_neighbor))[extractor]
4210 .gradient(dof_pair[1], q_point);
4211
4212 return value;
4213 }
4214
4215
4216
4217 template <int dim, int spacedim>
4219 Vector<dim, spacedim>::jump_in_values(const unsigned int interface_dof_index,
4220 const unsigned int q_point) const
4221 {
4222 const auto dof_pair =
4223 this->fe_interface->interface_dof_to_dof_indices(interface_dof_index);
4224
4226
4227 if (dof_pair[0] != numbers::invalid_unsigned_int)
4228 value +=
4229 (*(this->fe_interface->fe_face_values))[extractor].value(dof_pair[0],
4230 q_point);
4231
4232 if (dof_pair[1] != numbers::invalid_unsigned_int)
4233 value -=
4234 (*(this->fe_interface->fe_face_values_neighbor))[extractor].value(
4235 dof_pair[1], q_point);
4236
4237 return value;
4238 }
4239
4240
4241
4242 template <int dim, int spacedim>
4245 const unsigned int interface_dof_index,
4246 const unsigned int q_point) const
4247 {
4248 const auto dof_pair =
4249 this->fe_interface->interface_dof_to_dof_indices(interface_dof_index);
4250
4251 if (this->fe_interface->at_boundary())
4252 return (*(this->fe_interface->fe_face_values))[extractor].value(
4253 dof_pair[0], q_point);
4254
4256
4257 if (dof_pair[0] != numbers::invalid_unsigned_int)
4258 value +=
4259 0.5 *
4260 (*(this->fe_interface->fe_face_values))[extractor].value(dof_pair[0],
4261 q_point);
4262
4263 if (dof_pair[1] != numbers::invalid_unsigned_int)
4264 value +=
4265 0.5 * (*(this->fe_interface->fe_face_values_neighbor))[extractor].value(
4266 dof_pair[1], q_point);
4267
4268 return value;
4269 }
4270
4271
4272
4273 template <int dim, int spacedim>
4276 const unsigned int interface_dof_index,
4277 const unsigned int q_point) const
4278 {
4279 const auto dof_pair =
4280 this->fe_interface->interface_dof_to_dof_indices(interface_dof_index);
4281
4282 if (this->fe_interface->at_boundary())
4283 return (*(this->fe_interface->fe_face_values))[extractor].gradient(
4284 dof_pair[0], q_point);
4285
4286 gradient_type value;
4287
4288 if (dof_pair[0] != numbers::invalid_unsigned_int)
4289 value +=
4290 0.5 *
4291 (*(this->fe_interface->fe_face_values))[extractor].gradient(dof_pair[0],
4292 q_point);
4293
4294 if (dof_pair[1] != numbers::invalid_unsigned_int)
4295 value += 0.5 * (*(this->fe_interface->fe_face_values_neighbor))[extractor]
4296 .gradient(dof_pair[1], q_point);
4297
4298 return value;
4299 }
4300
4301
4302
4303 template <int dim, int spacedim>
4306 const unsigned int interface_dof_index,
4307 const unsigned int q_point) const
4308 {
4309 const auto dof_pair =
4310 this->fe_interface->interface_dof_to_dof_indices(interface_dof_index);
4311
4312 if (this->fe_interface->at_boundary())
4313 return (*(this->fe_interface->fe_face_values))[extractor].gradient(
4314 dof_pair[0], q_point);
4315
4316 gradient_type value;
4317
4318 if (dof_pair[0] != numbers::invalid_unsigned_int)
4319 value +=
4320 (*(this->fe_interface->fe_face_values))[extractor].gradient(dof_pair[0],
4321 q_point);
4322
4323 if (dof_pair[1] != numbers::invalid_unsigned_int)
4324 value -=
4325 (*(this->fe_interface->fe_face_values_neighbor))[extractor].gradient(
4326 dof_pair[1], q_point);
4327
4328 return value;
4329 }
4330
4331
4332
4333 template <int dim, int spacedim>
4335 Vector<dim, spacedim>::jump_gradient(const unsigned int interface_dof_index,
4336 const unsigned int q_point) const
4337 {
4338 return jump_in_gradients(interface_dof_index, q_point);
4339 }
4340
4341
4342
4343 template <int dim, int spacedim>
4346 const unsigned int interface_dof_index,
4347 const unsigned int q_point) const
4348 {
4349 const auto dof_pair =
4350 this->fe_interface->interface_dof_to_dof_indices(interface_dof_index);
4351
4352 if (this->fe_interface->at_boundary())
4353 return (*(this->fe_interface->fe_face_values))[extractor].hessian(
4354 dof_pair[0], q_point);
4355
4356 hessian_type value;
4357
4358 if (dof_pair[0] != numbers::invalid_unsigned_int)
4359 value +=
4360 0.5 *
4361 (*(this->fe_interface->fe_face_values))[extractor].hessian(dof_pair[0],
4362 q_point);
4363
4364 if (dof_pair[1] != numbers::invalid_unsigned_int)
4365 value += 0.5 * (*(this->fe_interface->fe_face_values_neighbor))[extractor]
4366 .hessian(dof_pair[1], q_point);
4367
4368 return value;
4369 }
4370
4371
4372
4373 template <int dim, int spacedim>
4375 Vector<dim, spacedim>::average_hessian(const unsigned int interface_dof_index,
4376 const unsigned int q_point) const
4377 {
4378 return average_of_hessians(interface_dof_index, q_point);
4379 }
4380
4381
4382
4383 template <int dim, int spacedim>
4386 const unsigned int interface_dof_index,
4387 const unsigned int q_point) const
4388 {
4389 const auto dof_pair =
4390 this->fe_interface->interface_dof_to_dof_indices(interface_dof_index);
4391
4392 if (this->fe_interface->at_boundary())
4393 return (*(this->fe_interface->fe_face_values))[extractor].hessian(
4394 dof_pair[0], q_point);
4395
4396 hessian_type value;
4397
4398 if (dof_pair[0] != numbers::invalid_unsigned_int)
4399 value +=
4400 (*(this->fe_interface->fe_face_values))[extractor].hessian(dof_pair[0],
4401 q_point);
4402
4403 if (dof_pair[1] != numbers::invalid_unsigned_int)
4404 value -=
4405 (*(this->fe_interface->fe_face_values_neighbor))[extractor].hessian(
4406 dof_pair[1], q_point);
4407
4408 return value;
4409 }
4410
4411
4412
4413 template <int dim, int spacedim>
4415 Vector<dim, spacedim>::jump_hessian(const unsigned int interface_dof_index,
4416 const unsigned int q_point) const
4417 {
4418 return jump_in_hessians(interface_dof_index, q_point);
4419 }
4420
4421
4422
4423 template <int dim, int spacedim>
4426 const unsigned int interface_dof_index,
4427 const unsigned int q_point) const
4428 {
4429 const auto dof_pair =
4430 this->fe_interface->interface_dof_to_dof_indices(interface_dof_index);
4431
4432 if (this->fe_interface->at_boundary())
4433 return (*(this->fe_interface->fe_face_values))[extractor]
4434 .third_derivative(dof_pair[0], q_point);
4435
4436 third_derivative_type value;
4437
4438 if (dof_pair[0] != numbers::invalid_unsigned_int)
4439 value +=
4440 (*(this->fe_interface->fe_face_values))[extractor].third_derivative(
4441 dof_pair[0], q_point);
4442
4443 if (dof_pair[1] != numbers::invalid_unsigned_int)
4444 value -= (*(this->fe_interface->fe_face_values_neighbor))[extractor]
4445 .third_derivative(dof_pair[1], q_point);
4446
4447 return value;
4448 }
4449
4450
4451
4452 template <int dim, int spacedim>
4453 template <class InputVector>
4454 void
4456 const bool here_or_there,
4457 const InputVector &local_dof_values,
4458 std::vector<solution_value_type<typename InputVector::value_type>> &values)
4459 const
4460 {
4461 AssertDimension(values.size(), this->fe_interface->n_quadrature_points);
4462
4463 for (const auto dof_index : this->fe_interface->dof_indices())
4464 for (const auto q_index : this->fe_interface->quadrature_point_indices())
4465 {
4466 if (dof_index == 0)
4467 values[q_index] = 0.;
4468
4469 values[q_index] += local_dof_values[dof_index] *
4470 value(here_or_there, dof_index, q_index);
4471 }
4472 }
4473
4474
4475
4476 template <int dim, int spacedim>
4477 template <class InputVector>
4478 void
4480 const bool here_or_there,
4481 const InputVector &fe_function,
4482 std::vector<solution_value_type<typename InputVector::value_type>> &values)
4483 const
4484 {
4485 std::vector<typename InputVector::value_type> local_dof_values(
4486 this->fe_interface->n_current_interface_dofs());
4487 this->get_local_dof_values(fe_function, local_dof_values);
4488
4489 get_function_values_from_local_dof_values(here_or_there,
4490 local_dof_values,
4491 values);
4492 }
4493
4494
4495
4496 template <int dim, int spacedim>
4497 template <class InputVector>
4498 void
4500 const InputVector &local_dof_values,
4501 std::vector<solution_value_type<typename InputVector::value_type>> &values)
4502 const
4503 {
4504 AssertDimension(values.size(), this->fe_interface->n_quadrature_points);
4505
4506 for (const auto dof_index : this->fe_interface->dof_indices())
4507 for (const auto q_index : this->fe_interface->quadrature_point_indices())
4508 {
4509 if (dof_index == 0)
4510 values[q_index] = 0.;
4511
4512 values[q_index] +=
4513 local_dof_values[dof_index] * jump_in_values(dof_index, q_index);
4514 }
4515 }
4516
4517
4518
4519 template <int dim, int spacedim>
4520 template <class InputVector>
4521 void
4523 const InputVector &fe_function,
4524 std::vector<solution_value_type<typename InputVector::value_type>> &values)
4525 const
4526 {
4527 std::vector<typename InputVector::value_type> local_dof_values(
4528 this->fe_interface->n_current_interface_dofs());
4529 this->get_local_dof_values(fe_function, local_dof_values);
4530
4531 get_jump_in_function_values_from_local_dof_values(local_dof_values, values);
4532 }
4533
4534
4535
4536 template <int dim, int spacedim>
4537 template <class InputVector>
4538 void
4540 const InputVector &local_dof_values,
4541 std::vector<solution_gradient_type<typename InputVector::value_type>>
4542 &gradients) const
4543 {
4544 AssertDimension(gradients.size(), this->fe_interface->n_quadrature_points);
4545
4546 for (const auto dof_index : this->fe_interface->dof_indices())
4547 for (const auto q_index : this->fe_interface->quadrature_point_indices())
4548 {
4549 if (dof_index == 0)
4550 gradients[q_index] = 0.;
4551
4552 gradients[q_index] +=
4553 local_dof_values[dof_index] * jump_in_gradients(dof_index, q_index);
4554 }
4555 }
4556
4557
4558
4559 template <int dim, int spacedim>
4560 template <class InputVector>
4561 void
4563 const InputVector &fe_function,
4564 std::vector<solution_gradient_type<typename InputVector::value_type>>
4565 &gradients) const
4566 {
4567 std::vector<typename InputVector::value_type> local_dof_values(
4568 this->fe_interface->n_current_interface_dofs());
4569 this->get_local_dof_values(fe_function, local_dof_values);
4570
4571 get_jump_in_function_gradients_from_local_dof_values(local_dof_values,
4572 gradients);
4573 }
4574
4575
4576
4577 template <int dim, int spacedim>
4578 template <class InputVector>
4579 void
4581 const InputVector &local_dof_values,
4582 std::vector<solution_value_type<typename InputVector::value_type>> &values)
4583 const
4584 {
4585 AssertDimension(values.size(), this->fe_interface->n_quadrature_points);
4586
4587 for (const auto dof_index : this->fe_interface->dof_indices())
4588 for (const auto q_index : this->fe_interface->quadrature_point_indices())
4589 {
4590 if (dof_index == 0)
4591 values[q_index] = 0.;
4592
4593 values[q_index] +=
4594 local_dof_values[dof_index] * average_of_values(dof_index, q_index);
4595 }
4596 }
4597
4598
4599
4600 template <int dim, int spacedim>
4601 template <class InputVector>
4602 void
4604 const InputVector &fe_function,
4605 std::vector<solution_value_type<typename InputVector::value_type>> &values)
4606 const
4607 {
4608 std::vector<typename InputVector::value_type> local_dof_values(
4609 this->fe_interface->n_current_interface_dofs());
4610 this->get_local_dof_values(fe_function, local_dof_values);
4611
4612 get_average_of_function_values_from_local_dof_values(local_dof_values,
4613 values);
4614 }
4615
4616
4617
4618 template <int dim, int spacedim>
4619 template <class InputVector>
4620 void
4623 const InputVector &local_dof_values,
4624 std::vector<solution_gradient_type<typename InputVector::value_type>>
4625 &gradients) const
4626 {
4627 AssertDimension(gradients.size(), this->fe_interface->n_quadrature_points);
4628
4629 for (const auto dof_index : this->fe_interface->dof_indices())
4630 for (const auto q_index : this->fe_interface->quadrature_point_indices())
4631 {
4632 if (dof_index == 0)
4633 gradients[q_index] = 0.;
4634
4635 gradients[q_index] += local_dof_values[dof_index] *
4636 average_of_gradients(dof_index, q_index);
4637 }
4638 }
4639
4640
4641
4642 template <int dim, int spacedim>
4643 template <class InputVector>
4644 void
4646 const InputVector &fe_function,
4647 std::vector<solution_gradient_type<typename InputVector::value_type>>
4648 &gradients) const
4649 {
4650 std::vector<typename InputVector::value_type> local_dof_values(
4651 this->fe_interface->n_current_interface_dofs());
4652 this->get_local_dof_values(fe_function, local_dof_values);
4653
4654 get_average_of_function_gradients_from_local_dof_values(local_dof_values,
4655 gradients);
4656 }
4657
4658
4659
4660 template <int dim, int spacedim>
4661 template <class InputVector>
4662 void
4664 const InputVector &local_dof_values,
4665 std::vector<solution_hessian_type<typename InputVector::value_type>>
4666 &hessians) const
4667 {
4668 AssertDimension(hessians.size(), this->fe_interface->n_quadrature_points);
4669
4670 for (const auto dof_index : this->fe_interface->dof_indices())
4671 for (const auto q_index : this->fe_interface->quadrature_point_indices())
4672 {
4673 if (dof_index == 0)
4674 hessians[q_index] = 0.;
4675
4676 hessians[q_index] +=
4677 local_dof_values[dof_index] * jump_in_hessians(dof_index, q_index);
4678 }
4679 }
4680
4681
4682
4683 template <int dim, int spacedim>
4684 template <class InputVector>
4685 void
4687 const InputVector &fe_function,
4688 std::vector<solution_hessian_type<typename InputVector::value_type>>
4689 &hessians) const
4690 {
4691 std::vector<typename InputVector::value_type> local_dof_values(
4692 this->fe_interface->n_current_interface_dofs());
4693 this->get_local_dof_values(fe_function, local_dof_values);
4694
4695 get_jump_in_function_hessians_from_local_dof_values(local_dof_values,
4696 hessians);
4697 }
4698
4699
4700
4701 template <int dim, int spacedim>
4702 template <class InputVector>
4703 void
4705 const InputVector &local_dof_values,
4706 std::vector<solution_hessian_type<typename InputVector::value_type>>
4707 &hessians) const
4708 {
4709 AssertDimension(hessians.size(), this->fe_interface->n_quadrature_points);
4710
4711 for (const unsigned int dof_index : this->fe_interface->dof_indices())
4712 for (const auto q_index : this->fe_interface->quadrature_point_indices())
4713 {
4714 if (dof_index == 0)
4715 hessians[q_index] = 0.;
4716
4717 hessians[q_index] += local_dof_values[dof_index] *
4718 average_of_hessians(dof_index, q_index);
4719 }
4720 }
4721
4722
4723
4724 template <int dim, int spacedim>
4725 template <class InputVector>
4726 void
4728 const InputVector &fe_function,
4729 std::vector<solution_hessian_type<typename InputVector::value_type>>
4730 &hessians) const
4731 {
4732 std::vector<typename InputVector::value_type> local_dof_values(
4733 this->fe_interface->n_current_interface_dofs());
4734 this->get_local_dof_values(fe_function, local_dof_values);
4735
4736 get_average_of_function_hessians_from_local_dof_values(local_dof_values,
4737 hessians);
4738 }
4739
4740
4741
4742 template <int dim, int spacedim>
4743 template <class InputVector>
4744 void
4747 const InputVector &local_dof_values,
4748 std::vector<
4749 solution_third_derivative_type<typename InputVector::value_type>>
4750 &third_derivatives) const
4751 {
4752 AssertDimension(third_derivatives.size(),
4753 this->fe_interface->n_quadrature_points);
4754
4755 for (const unsigned int dof_index : this->fe_interface->dof_indices())
4756 for (const auto q_index : this->fe_interface->quadrature_point_indices())
4757 {
4758 if (dof_index == 0)
4759 third_derivatives[q_index] = 0.;
4760
4761 third_derivatives[q_index] +=
4762 local_dof_values[dof_index] *
4763 jump_in_third_derivatives(dof_index, q_index);
4764 }
4765 }
4766
4767
4768
4769 template <int dim, int spacedim>
4770 template <class InputVector>
4771 void
4773 const InputVector &fe_function,
4774 std::vector<
4775 solution_third_derivative_type<typename InputVector::value_type>>
4776 &third_derivatives) const
4777 {
4778 std::vector<typename InputVector::value_type> local_dof_values(
4779 this->fe_interface->n_current_interface_dofs());
4780 this->get_local_dof_values(fe_function, local_dof_values);
4781
4782 get_jump_in_function_third_derivatives_from_local_dof_values(
4783 local_dof_values, third_derivatives);
4784 }
4785} // namespace FEInterfaceViews
4786
4787#endif // DOXYGEN
4788
4790
4791#endif
friend class FEInterfaceViews::Scalar
std::unique_ptr< FEFaceValues< dim, spacedim > > internal_fe_face_values
UpdateFlags get_update_flags() const
const hp::MappingCollection< dim, spacedim > & get_mapping_collection() const
Tensor< 1, spacedim > average_of_shape_gradients(const unsigned int interface_dof_index, const unsigned int q_point, const unsigned int component=0) const
void get_average_of_function_gradients(const InputVector &fe_function, std::vector< Tensor< 1, spacedim, typename InputVector::value_type > > &gradients) const
void get_jump_in_function_third_derivatives(const InputVector &fe_function, std::vector< Tensor< 3, spacedim, typename InputVector::value_type > > &third_derivatives) const
std_cxx20::ranges::iota_view< unsigned int, unsigned int > dof_indices() const
FEFaceValuesBase< dim, spacedim > * fe_face_values_neighbor
friend class FEInterfaceViews::Vector
bool at_boundary() const
const std::vector< double > & get_JxW_values() const
void get_average_of_function_hessians(const InputVector &fe_function, std::vector< Tensor< 2, spacedim, typename InputVector::value_type > > &hessians) const
FEInterfaceValues(const Mapping< dim, spacedim > &mapping, const FiniteElement< dim, spacedim > &fe, const Quadrature< dim - 1 > &quadrature, const UpdateFlags update_flags)
void reinit(const CellIteratorType &cell, const unsigned int face_no, const unsigned int q_index=numbers::invalid_unsigned_int, const unsigned int mapping_index=numbers::invalid_unsigned_int, const unsigned int fe_index=numbers::invalid_unsigned_int)
const hp::FECollection< dim, spacedim > & get_fe_collection() const
Tensor< 3, spacedim > jump_in_shape_3rd_derivatives(const unsigned int interface_dof_index, const unsigned int q_point, const unsigned int component=0) const
std::vector< std::pair< types::global_dof_index, std::array< unsigned int, 2 > > > interface_dof_data
FEInterfaceValues(const hp::MappingCollection< dim, spacedim > &mapping_collection, const hp::FECollection< dim, spacedim > &fe_collection, const hp::QCollection< dim - 1 > &quadrature_collection, const UpdateFlags update_flags)
std::unique_ptr< hp::FESubfaceValues< dim, spacedim > > internal_hp_fe_subface_values
const unsigned int n_quadrature_points
bool has_hp_capabilities() const
void reinit(const CellIteratorType &cell, const unsigned int face_no, const unsigned int sub_face_no, const CellNeighborIteratorType &cell_neighbor, const unsigned int face_no_neighbor, const unsigned int sub_face_no_neighbor, const unsigned int q_index=numbers::invalid_unsigned_int, const unsigned int mapping_index=numbers::invalid_unsigned_int, const unsigned int fe_index=numbers::invalid_unsigned_int, const unsigned int fe_index_neighbor=numbers::invalid_unsigned_int)
FEInterfaceViews::Scalar< dim, spacedim > operator[](const FEValuesExtractors::Scalar &scalar) const
unsigned n_current_interface_dofs() const
const std::vector< Tensor< 1, spacedim > > & get_normal_vectors() const
const FiniteElement< dim, spacedim > & get_fe() const
double average_of_shape_values(const unsigned int interface_dof_index, const unsigned int q_point, const unsigned int component=0) const
const std::vector< Point< spacedim > > & get_quadrature_points() const
std::unique_ptr< FESubfaceValues< dim, spacedim > > internal_fe_subface_values
double shape_value(const bool here_or_there, const unsigned int interface_dof_index, const unsigned int q_point, const unsigned int component=0) const
const FEFaceValuesBase< dim, spacedim > & get_fe_face_values(const unsigned int cell_index) const
Tensor< 2, spacedim > average_of_shape_hessians(const unsigned int interface_dof_index, const unsigned int q_point, const unsigned int component=0) const
std::unique_ptr< hp::FESubfaceValues< dim, spacedim > > internal_hp_fe_subface_values_neighbor
FEInterfaceValues(const hp::FECollection< dim, spacedim > &fe_collection, const hp::QCollection< dim - 1 > &quadrature_collection, const UpdateFlags update_flags)
const hp::QCollection< dim - 1 > & get_quadrature_collection() const
FEInterfaceValues(const Mapping< dim, spacedim > &mapping, const FiniteElement< dim, spacedim > &fe, const hp::QCollection< dim - 1 > &quadrature, const UpdateFlags update_flags)
FEFaceValuesBase< dim, spacedim > * fe_face_values
Tensor< 1, spacedim > normal_vector(const unsigned int q_point_index) const
std::unique_ptr< FESubfaceValues< dim, spacedim > > internal_fe_subface_values_neighbor
Tensor< 1, spacedim > shape_grad(const bool here_or_there, const unsigned int interface_dof_index, const unsigned int q_point, const unsigned int component=0) const
Triangulation< dim, spacedim >::cell_iterator get_cell(const unsigned int cell_index) const
void get_jump_in_function_hessians(const InputVector &fe_function, std::vector< Tensor< 2, spacedim, typename InputVector::value_type > > &hessians) const
double JxW(const unsigned int quadrature_point) const
Tensor< 1, spacedim > normal(const unsigned int q_point_index) const
void get_average_of_function_values(const InputVector &fe_function, std::vector< typename InputVector::value_type > &values) const
Tensor< 1, spacedim > jump_in_shape_gradients(const unsigned int interface_dof_index, const unsigned int q_point, const unsigned int component=0) const
Tensor< 2, spacedim > jump_in_shape_hessians(const unsigned int interface_dof_index, const unsigned int q_point, const unsigned int component=0) const
std::unique_ptr< hp::FEFaceValues< dim, spacedim > > internal_hp_fe_face_values_neighbor
std_cxx20::ranges::iota_view< unsigned int, unsigned int > quadrature_point_indices() const
double jump_in_shape_values(const unsigned int interface_dof_index, const unsigned int q_point, const unsigned int component=0) const
unsigned int get_face_number(const unsigned int cell_index) const
std::vector< types::global_dof_index > get_interface_dof_indices() const
FEInterfaceValues(const FiniteElement< dim, spacedim > &fe, const Quadrature< dim - 1 > &quadrature, const UpdateFlags update_flags)
void reinit(const CellIteratorType &cell, const CellNeighborIteratorType &cell_neighbor, const InterfaceData &interface_data)
std::array< unsigned int, 2 > interface_dof_to_dof_indices(const unsigned int interface_dof_index) const
std::unique_ptr< hp::FEFaceValues< dim, spacedim > > internal_hp_fe_face_values
std::unique_ptr< FEFaceValues< dim, spacedim > > internal_fe_face_values_neighbor
void get_jump_in_function_values(const InputVector &fe_function, std::vector< typename InputVector::value_type > &values) const
void get_jump_in_function_gradients(const InputVector &fe_function, std::vector< Tensor< 1, spacedim, typename InputVector::value_type > > &gradients) const
const Mapping< dim, spacedim > & get_mapping() const
const Point< spacedim > & quadrature_point(const unsigned int q_point) const
const Quadrature< dim - 1 > & get_quadrature() const
void get_local_dof_values(const InputVector &dof_values, OutputVector &local_dof_values) const
Base(const FEInterfaceValues< dim, spacedim > &fe_interface)
const FEInterfaceValues< dim, spacedim > * fe_interface
void get_jump_in_function_third_derivatives(const InputVector &fe_function, std::vector< solution_third_derivative_type< typename InputVector::value_type > > &third_derivatives) const
void get_jump_in_function_gradients_from_local_dof_values(const InputVector &local_dof_values, std::vector< solution_gradient_type< typename InputVector::value_type > > &gradients) const
gradient_type jump_in_gradients(const unsigned int interface_dof_index, const unsigned int q_point) const
void get_jump_in_function_hessians(const InputVector &fe_function, std::vector< solution_hessian_type< typename InputVector::value_type > > &hessians) const
hessian_type jump_in_hessians(const unsigned int interface_dof_index, const unsigned int q_point) const
typename FEValuesViews::Scalar< dim, spacedim >::gradient_type gradient_type
gradient_type gradient(const bool here_or_there, const unsigned int interface_dof_index, const unsigned int q_point) const
typename FEValuesViews::Scalar< dim, spacedim >::hessian_type hessian_type
const FEValuesExtractors::Scalar extractor
void get_jump_in_function_third_derivatives_from_local_dof_values(const InputVector &local_dof_values, std::vector< solution_third_derivative_type< typename InputVector::value_type > > &third_derivatives) const
typename ProductType< Number, gradient_type >::type solution_gradient_type
hessian_type average_of_hessians(const unsigned int interface_dof_index, const unsigned int q_point) const
void get_jump_in_function_gradients(const InputVector &fe_function, std::vector< solution_gradient_type< typename InputVector::value_type > > &gradients) const
value_type value(const bool here_or_there, const unsigned int interface_dof_index, const unsigned int q_point) const
void get_average_of_function_hessians_from_local_dof_values(const InputVector &local_dof_values, std::vector< solution_hessian_type< typename InputVector::value_type > > &hessians) const
void get_average_of_function_values_from_local_dof_values(const InputVector &local_dof_values, std::vector< solution_value_type< typename InputVector::value_type > > &values) const
typename ProductType< Number, third_derivative_type >::type solution_third_derivative_type
void get_average_of_function_values(const InputVector &fe_function, std::vector< solution_value_type< typename InputVector::value_type > > &values) const
typename ProductType< Number, value_type >::type solution_value_type
void get_average_of_function_gradients(const InputVector &fe_function, std::vector< solution_gradient_type< typename InputVector::value_type > > &gradients) const
void get_jump_in_function_values_from_local_dof_values(const InputVector &local_dof_values, std::vector< solution_value_type< typename InputVector::value_type > > &values) const
void get_jump_in_function_values(const InputVector &fe_function, std::vector< solution_value_type< typename InputVector::value_type > > &values) const
Scalar(const FEInterfaceValues< dim, spacedim > &fe_interface, const unsigned int component)
typename FEValuesViews::Scalar< dim, spacedim >::third_derivative_type third_derivative_type
third_derivative_type jump_in_third_derivatives(const unsigned int interface_dof_index, const unsigned int q_point) const
gradient_type average_of_gradients(const unsigned int interface_dof_index, const unsigned int q_point) const
void get_average_of_function_hessians(const InputVector &fe_function, std::vector< solution_hessian_type< typename InputVector::value_type > > &hessians) const
void get_average_of_function_gradients_from_local_dof_values(const InputVector &local_dof_values, std::vector< solution_gradient_type< typename InputVector::value_type > > &gradients) const
value_type average_of_values(const unsigned int interface_dof_index, const unsigned int q_point) const
void get_jump_in_function_hessians_from_local_dof_values(const InputVector &local_dof_values, std::vector< solution_hessian_type< typename InputVector::value_type > > &hessians) const
value_type jump_in_values(const unsigned int interface_dof_index, const unsigned int q_point) const
void get_function_values_from_local_dof_values(const bool here_or_there, const InputVector &local_dof_values, std::vector< solution_value_type< typename InputVector::value_type > > &values) const
void get_function_values(const bool here_or_there, const InputVector &fe_function, std::vector< solution_value_type< typename InputVector::value_type > > &values) const
typename ProductType< Number, hessian_type >::type solution_hessian_type
typename ProductType< Number, gradient_type >::type solution_gradient_type
typename FEValuesViews::Vector< dim, spacedim >::hessian_type hessian_type
const FEValuesExtractors::Vector extractor
void get_average_of_function_gradients_from_local_dof_values(const InputVector &local_dof_values, std::vector< solution_gradient_type< typename InputVector::value_type > > &gradients) const
void get_average_of_function_hessians(const InputVector &fe_function, std::vector< solution_hessian_type< typename InputVector::value_type > > &hessians) const
gradient_type gradient(const bool here_or_there, const unsigned int interface_dof_index, const unsigned int q_point) const
void get_jump_in_function_values(const InputVector &fe_function, std::vector< solution_value_type< typename InputVector::value_type > > &values) const
void get_average_of_function_values_from_local_dof_values(const InputVector &local_dof_values, std::vector< solution_value_type< typename InputVector::value_type > > &values) const
void get_function_values_from_local_dof_values(const bool here_or_there, const InputVector &local_dof_values, std::vector< solution_value_type< typename InputVector::value_type > > &values) const
void get_average_of_function_hessians_from_local_dof_values(const InputVector &local_dof_values, std::vector< solution_hessian_type< typename InputVector::value_type > > &hessians) const
hessian_type average_hessian(const unsigned int interface_dof_index, const unsigned int q_point) const
Vector(const FEInterfaceValues< dim, spacedim > &fe_interface, const unsigned int first_vector_component)
void get_average_of_function_gradients(const InputVector &fe_function, std::vector< solution_gradient_type< typename InputVector::value_type > > &gradients) const
void get_function_values(const bool here_or_there, const InputVector &fe_function, std::vector< solution_value_type< typename InputVector::value_type > > &values) const
hessian_type jump_hessian(const unsigned int interface_dof_index, const unsigned int q_point) const
typename ProductType< Number, value_type >::type solution_value_type
typename ProductType< Number, hessian_type >::type solution_hessian_type
void get_average_of_function_values(const InputVector &fe_function, std::vector< solution_value_type< typename InputVector::value_type > > &values) const
value_type value(const bool here_or_there, const unsigned int interface_dof_index, const unsigned int q_point) const
void get_jump_in_function_third_derivatives_from_local_dof_values(const InputVector &local_dof_values, std::vector< solution_third_derivative_type< typename InputVector::value_type > > &third_derivatives) const
void get_jump_in_function_gradients(const InputVector &fe_function, std::vector< solution_gradient_type< typename InputVector::value_type > > &gradients) const
third_derivative_type jump_in_third_derivatives(const unsigned int interface_dof_index, const unsigned int q_point) const
void get_jump_in_function_gradients_from_local_dof_values(const InputVector &local_dof_values, std::vector< solution_gradient_type< typename InputVector::value_type > > &gradients) const
void get_jump_in_function_hessians_from_local_dof_values(const InputVector &local_dof_values, std::vector< solution_hessian_type< typename InputVector::value_type > > &hessians) const
void get_jump_in_function_hessians(const InputVector &fe_function, std::vector< solution_hessian_type< typename InputVector::value_type > > &hessians) const
value_type jump_in_values(const unsigned int interface_dof_index, const unsigned int q_point) const
typename FEValuesViews::Vector< dim, spacedim >::value_type value_type
void get_jump_in_function_third_derivatives(const InputVector &fe_function, std::vector< solution_third_derivative_type< typename InputVector::value_type > > &third_derivatives) const
gradient_type jump_gradient(const unsigned int interface_dof_index, const unsigned int q_point) const
typename FEValuesViews::Vector< dim, spacedim >::third_derivative_type third_derivative_type
value_type average_of_values(const unsigned int interface_dof_index, const unsigned int q_point) const
hessian_type jump_in_hessians(const unsigned int interface_dof_index, const unsigned int q_point) const
void get_jump_in_function_values_from_local_dof_values(const InputVector &local_dof_values, std::vector< solution_value_type< typename InputVector::value_type > > &values) const
gradient_type average_of_gradients(const unsigned int interface_dof_index, const unsigned int q_point) const
typename FEValuesViews::Vector< dim, spacedim >::gradient_type gradient_type
gradient_type jump_in_gradients(const unsigned int interface_dof_index, const unsigned int q_point) const
typename ProductType< Number, third_derivative_type >::type solution_third_derivative_type
hessian_type average_of_hessians(const unsigned int interface_dof_index, const unsigned int q_point) const
::Tensor< 1, spacedim > gradient_type
::Tensor< 2, spacedim > hessian_type
::Tensor< 3, spacedim > third_derivative_type
::Tensor< 4, spacedim > third_derivative_type
::Tensor< 2, spacedim > gradient_type
::Tensor< 3, spacedim > hessian_type
::Tensor< 1, spacedim > value_type
Abstract base class for mapping classes.
Definition mapping.h:318
Definition point.h:111
static constexpr unsigned int n_independent_components
Definition tensor.h:496
friend class Vector
Definition vector.h:1102
Number value_type
Definition vector.h:115
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_DEPRECATED_WITH_COMMENT(comment)
Definition config.h:287
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
static ::ExceptionBase & ExcOnlyAvailableWithHP()
#define AssertDimension(dim1, dim2)
#define AssertIndexRange(index, range)
#define DeclExceptionMsg(Exception, defaulttext)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcNotInitialized()
static ::ExceptionBase & ExcOnlyAvailableWithoutHP()
static ::ExceptionBase & ExcMessage(std::string arg1)
TriaIterator< CellAccessor< dim, spacedim > > cell_iterator
Definition tria.h:1624
const bool IsBlockVector< VectorType >::value
UpdateFlags
const Mapping< dim, spacedim > & get_default_linear_mapping(const Triangulation< dim, spacedim > &triangulation)
Definition mapping.cc:314
MappingQ< dim, spacedim > StaticMappingQ1< dim, spacedim >::mapping
Definition mapping_q1.h:101
typename ::internal::FEInterfaceViews:: ViewType< dim, spacedim, Extractor >::type View
*  *  *  ScaleZFunction< dim, Number, components >::ScaleZFunction *  component(component)
Definition hp.h:115
void reinit(MatrixBlock< MatrixType > &v, const BlockSparsityPattern &p)
constexpr types::global_dof_index invalid_dof_index
Definition types.h:267
constexpr unsigned int invalid_unsigned_int
Definition types.h:236
constexpr types::fe_index invalid_fe_index
Definition types.h:258
STL namespace.
Definition types.h:30
*  *  FEFaceValues< 2 > fe_face_values(fe, face_quadrature_formula, update_values|update_quadrature_points| *  update_normal_vectors|update_JxW_values)
InterfaceData(const unsigned int face_no, const unsigned int sub_face_no, const unsigned int face_no_neighbor, const unsigned int sub_face_no_neighbor)
typename internal::ProductTypeImpl< std::decay_t< T >, std::decay_t< U > >::type type