Reference documentation for deal.II version GIT 204c5e6f02 2022-07-06 01:00:01+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
fe_interface_values.h
Go to the documentation of this file.
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2018 - 2022 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef dealii_fe_interface_values_h
17 #define dealii_fe_interface_values_h
18 
19 #include <deal.II/base/config.h>
20 
22 
23 #include <deal.II/fe/fe_values.h>
24 #include <deal.II/fe/mapping_q1.h>
25 
27 
29 
30 #ifndef DOXYGEN
31 template <int dim, int spacedim>
32 class FEInterfaceValues;
33 #endif
34 
40 {
44  template <int dim, int spacedim = dim>
45  class Base
46  {
47  public:
52 
53  protected:
58 
63  template <class InputVector, class OutputVector>
64  void
65  get_local_dof_values(const InputVector &dof_values,
66  OutputVector & local_dof_values) const;
67  };
68 
69 
70 
74  template <int dim, int spacedim = dim>
75  class Scalar : public Base<dim, spacedim>
76  {
77  public:
81  using value_type = double;
82 
87  using gradient_type =
89 
94  using hessian_type =
96 
103 
110  template <typename Number>
112 
119  template <typename Number>
122 
129  template <typename Number>
132 
139  template <typename Number>
142 
147  const unsigned int component);
148 
153 
173  value_type
174  value(const bool here_or_there,
175  const unsigned int interface_dof_index,
176  const unsigned int q_point) const;
177 
179 
184 
195  value_type
196  jump_in_values(const unsigned int interface_dof_index,
197  const unsigned int q_point) const;
198 
205  value_type
206  jump(const unsigned int interface_dof_index,
207  const unsigned int q_point) const;
208 
220  jump_in_gradients(const unsigned int interface_dof_index,
221  const unsigned int q_point) const;
222 
230  jump_gradient(const unsigned int interface_dof_index,
231  const unsigned int q_point) const;
232 
244  jump_in_hessians(const unsigned int interface_dof_index,
245  const unsigned int q_point) const;
246 
254  jump_hessian(const unsigned int interface_dof_index,
255  const unsigned int q_point) const;
256 
268  jump_in_third_derivatives(const unsigned int interface_dof_index,
269  const unsigned int q_point) const;
270 
278  jump_3rd_derivative(const unsigned int interface_dof_index,
279  const unsigned int q_point) const;
280 
282 
287 
298  value_type
299  average_of_values(const unsigned int interface_dof_index,
300  const unsigned int q_point) const;
301 
308  value_type
309  average_value(const unsigned int interface_dof_index,
310  const unsigned int q_point) const;
311 
318  value_type
319  average(const unsigned int interface_dof_index,
320  const unsigned int q_point) const;
321 
333  average_of_gradients(const unsigned int interface_dof_index,
334  const unsigned int q_point) const;
335 
343  average_gradient(const unsigned int interface_dof_index,
344  const unsigned int q_point) const;
345 
358  average_of_hessians(const unsigned int interface_dof_index,
359  const unsigned int q_point) const;
360 
368  average_hessian(const unsigned int interface_dof_index,
369  const unsigned int q_point) const;
370 
372 
377 
397  template <class InputVector>
398  void
400  const bool here_or_there,
401  const InputVector &fe_function,
403  &values) const;
404 
427  template <class InputVector>
428  void
430  const bool here_or_there,
431  const InputVector &local_dof_values,
433  &values) const;
434 
436 
441 
455  template <class InputVector>
456  void
458  const InputVector &fe_function,
460  &values) const;
461 
469  template <class InputVector>
470  void
472  const InputVector &local_dof_values,
474  &values) const;
475 
489  template <class InputVector>
490  void
492  const InputVector &fe_function,
494  &gradients) const;
495 
503  template <class InputVector>
504  void
506  const InputVector &local_dof_values,
508  &gradients) const;
509 
523  template <class InputVector>
524  void
526  const InputVector &fe_function,
528  &hessians) const;
529 
537  template <class InputVector>
538  void
540  const InputVector &local_dof_values,
542  &hessians) const;
543 
558  template <class InputVector>
559  void
561  const InputVector &fe_function,
562  std::vector<
564  &third_derivatives) const;
565 
573  template <class InputVector>
574  void
576  const InputVector &local_dof_values,
577  std::vector<
579  &third_derivatives) const;
580 
582 
587 
601  template <class InputVector>
602  void
604  const InputVector &fe_function,
606  &values) const;
607 
615  template <class InputVector>
616  void
618  const InputVector &local_dof_values,
620  &values) const;
621 
635  template <class InputVector>
636  void
638  const InputVector &fe_function,
640  &gradients) const;
641 
649  template <class InputVector>
650  void
652  const InputVector &local_dof_values,
654  &gradients) const;
655 
669  template <class InputVector>
670  void
672  const InputVector &fe_function,
674  &hessians) const;
675 
683  template <class InputVector>
684  void
686  const InputVector &local_dof_values,
688  &hessians) const;
689 
691 
692  private:
697  };
698 
699 
700 
704  template <int dim, int spacedim = dim>
705  class Vector : public Base<dim, spacedim>
706  {
707  public:
711  using value_type =
713 
720 
726  using hessian_type =
728 
736 
743  template <typename Number>
745 
752  template <typename Number>
755 
762  template <typename Number>
765 
772  template <typename Number>
775 
780  const unsigned int first_vector_component);
781 
786 
806  value_type
807  value(const bool here_or_there,
808  const unsigned int interface_dof_index,
809  const unsigned int q_point) const;
810 
812 
817 
827  value_type
828  jump_in_values(const unsigned int interface_dof_index,
829  const unsigned int q_point) const;
830 
837  value_type
838  jump(const unsigned int interface_dof_index,
839  const unsigned int q_point) const;
840 
851  jump_in_gradients(const unsigned int interface_dof_index,
852  const unsigned int q_point) const;
853 
860  jump_gradient(const unsigned int interface_dof_index,
861  const unsigned int q_point) const;
862 
874  jump_in_hessians(const unsigned int interface_dof_index,
875  const unsigned int q_point) const;
876 
883  jump_hessian(const unsigned int interface_dof_index,
884  const unsigned int q_point) const;
885 
897  jump_in_third_derivatives(const unsigned int interface_dof_index,
898  const unsigned int q_point) const;
899 
907  jump_3rd_derivative(const unsigned int interface_dof_index,
908  const unsigned int q_point) const;
909 
911 
916 
926  value_type
927  average_of_values(const unsigned int interface_dof_index,
928  const unsigned int q_point) const;
929 
936  value_type
937  average(const unsigned int interface_dof_index,
938  const unsigned int q_point) const;
939 
950  average_of_gradients(const unsigned int interface_dof_index,
951  const unsigned int q_point) const;
952 
960  average_gradient(const unsigned int interface_dof_index,
961  const unsigned int q_point) const;
962 
975  average_of_hessians(const unsigned int interface_dof_index,
976  const unsigned int q_point) const;
977 
984  average_hessian(const unsigned int interface_dof_index,
985  const unsigned int q_point) const;
986 
988 
993 
1013  template <class InputVector>
1014  void
1016  const bool here_or_there,
1017  const InputVector &fe_function,
1019  &values) const;
1020 
1043  template <class InputVector>
1044  void
1046  const bool here_or_there,
1047  const InputVector &local_dof_values,
1049  &values) const;
1050 
1052 
1057 
1071  template <class InputVector>
1072  void
1074  const InputVector &fe_function,
1076  &values) const;
1077 
1085  template <class InputVector>
1086  void
1088  const InputVector &local_dof_values,
1090  &values) const;
1091 
1105  template <class InputVector>
1106  void
1108  const InputVector &fe_function,
1110  &gradients) const;
1111 
1119  template <class InputVector>
1120  void
1122  const InputVector &local_dof_values,
1124  &gradients) const;
1125 
1139  template <class InputVector>
1140  void
1142  const InputVector &fe_function,
1144  &hessians) const;
1145 
1153  template <class InputVector>
1154  void
1156  const InputVector &local_dof_values,
1158  &hessians) const;
1159 
1174  template <class InputVector>
1175  void
1177  const InputVector &fe_function,
1178  std::vector<
1180  &third_derivatives) const;
1181 
1189  template <class InputVector>
1190  void
1192  const InputVector &local_dof_values,
1193  std::vector<
1195  &third_derivatives) const;
1196 
1198 
1203 
1217  template <class InputVector>
1218  void
1220  const InputVector &fe_function,
1222  &values) const;
1223 
1231  template <class InputVector>
1232  void
1234  const InputVector &local_dof_values,
1236  &values) const;
1237 
1251  template <class InputVector>
1252  void
1254  const InputVector &fe_function,
1256  &gradients) const;
1257 
1265  template <class InputVector>
1266  void
1268  const InputVector &local_dof_values,
1270  &gradients) const;
1271 
1285  template <class InputVector>
1286  void
1288  const InputVector &fe_function,
1290  &hessians) const;
1291 
1299  template <class InputVector>
1300  void
1302  const InputVector &local_dof_values,
1304  &hessians) const;
1305 
1307 
1308  private:
1313  };
1314 } // namespace FEInterfaceViews
1315 
1316 
1317 namespace internal
1318 {
1320  {
1325  template <int dim, int spacedim, typename Extractor>
1326  struct ViewType
1327  {};
1328 
1336  template <int dim, int spacedim>
1337  struct ViewType<dim, spacedim, FEValuesExtractors::Scalar>
1338  {
1339  using type = typename ::FEInterfaceViews::Scalar<dim, spacedim>;
1340  };
1341 
1349  template <int dim, int spacedim>
1350  struct ViewType<dim, spacedim, FEValuesExtractors::Vector>
1351  {
1352  using type = typename ::FEInterfaceViews::Vector<dim, spacedim>;
1353  };
1354  } // namespace FEInterfaceViews
1355 } // namespace internal
1356 
1357 namespace FEInterfaceViews
1358 {
1363  template <int dim, int spacedim, typename Extractor>
1364  using View = typename ::internal::FEInterfaceViews::
1365  ViewType<dim, spacedim, Extractor>::type;
1366 } // namespace FEInterfaceViews
1367 
1368 
1369 
1394 template <int dim, int spacedim = dim>
1396 {
1397 public:
1401  const unsigned int n_quadrature_points;
1402 
1409  const FiniteElement<dim, spacedim> &fe,
1410  const Quadrature<dim - 1> & quadrature,
1411  const UpdateFlags update_flags);
1412 
1419  const FiniteElement<dim, spacedim> &fe,
1420  const hp::QCollection<dim - 1> & quadrature,
1421  const UpdateFlags update_flags);
1422 
1430  const Quadrature<dim - 1> & quadrature,
1431  const UpdateFlags update_flags);
1432 
1464  template <class CellIteratorType, class CellNeighborIteratorType>
1465  void
1466  reinit(const CellIteratorType & cell,
1467  const unsigned int face_no,
1468  const unsigned int sub_face_no,
1469  const CellNeighborIteratorType &cell_neighbor,
1470  const unsigned int face_no_neighbor,
1471  const unsigned int sub_face_no_neighbor);
1472 
1484  template <class CellIteratorType>
1485  void
1486  reinit(const CellIteratorType &cell, const unsigned int face_no);
1487 
1496  get_fe_face_values(const unsigned int cell_index) const;
1497 
1501  const Mapping<dim, spacedim> &
1502  get_mapping() const;
1503 
1508  get_fe() const;
1509 
1513  const Quadrature<dim - 1> &
1515 
1519  UpdateFlags
1521 
1529  get_cell(const unsigned int cell_index) const;
1530 
1538  unsigned int
1539  get_face_number(const unsigned int cell_index) const;
1540 
1552  bool
1553  at_boundary() const;
1554 
1566  double
1567  JxW(const unsigned int quadrature_point) const;
1568 
1574  const std::vector<double> &
1576 
1586  const std::vector<Tensor<1, spacedim>> &
1588 
1598 
1604  const std::vector<Point<spacedim>> &
1606 
1617  unsigned
1619 
1648  dof_indices() const;
1649 
1660  std::vector<types::global_dof_index>
1662 
1675  std::array<unsigned int, 2>
1676  interface_dof_to_dof_indices(const unsigned int interface_dof_index) const;
1677 
1687  normal(const unsigned int q_point_index) const;
1688 
1719  double
1720  shape_value(const bool here_or_there,
1721  const unsigned int interface_dof_index,
1722  const unsigned int q_point,
1723  const unsigned int component = 0) const;
1724 
1752  double
1753  jump_in_shape_values(const unsigned int interface_dof_index,
1754  const unsigned int q_point,
1755  const unsigned int component = 0) const;
1756 
1763  double
1764  jump(const unsigned int interface_dof_index,
1765  const unsigned int q_point,
1766  const unsigned int component = 0) const;
1767 
1782  jump_in_shape_gradients(const unsigned int interface_dof_index,
1783  const unsigned int q_point,
1784  const unsigned int component = 0) const;
1785 
1793  jump_gradient(const unsigned int interface_dof_index,
1794  const unsigned int q_point,
1795  const unsigned int component = 0) const;
1796 
1812  jump_in_shape_hessians(const unsigned int interface_dof_index,
1813  const unsigned int q_point,
1814  const unsigned int component = 0) const;
1815 
1823  jump_hessian(const unsigned int interface_dof_index,
1824  const unsigned int q_point,
1825  const unsigned int component = 0) const;
1826 
1841  jump_in_shape_3rd_derivatives(const unsigned int interface_dof_index,
1842  const unsigned int q_point,
1843  const unsigned int component = 0) const;
1844 
1852  jump_3rd_derivative(const unsigned int interface_dof_index,
1853  const unsigned int q_point,
1854  const unsigned int component = 0) const;
1855 
1878  double
1879  average_of_shape_values(const unsigned int interface_dof_index,
1880  const unsigned int q_point,
1881  const unsigned int component = 0) const;
1882 
1889  double
1890  average(const unsigned int interface_dof_index,
1891  const unsigned int q_point,
1892  const unsigned int component = 0) const;
1893 
1908  average_of_shape_gradients(const unsigned int interface_dof_index,
1909  const unsigned int q_point,
1910  const unsigned int component = 0) const;
1911 
1919  average_gradient(const unsigned int interface_dof_index,
1920  const unsigned int q_point,
1921  const unsigned int component = 0) const;
1922 
1938  average_of_shape_hessians(const unsigned int interface_dof_index,
1939  const unsigned int q_point,
1940  const unsigned int component = 0) const;
1941 
1949  average_hessian(const unsigned int interface_dof_index,
1950  const unsigned int q_point,
1951  const unsigned int component = 0) const;
1952 
1972  template <class InputVector>
1973  void
1975  const InputVector & fe_function,
1976  std::vector<typename InputVector::value_type> &values) const;
1977 
1986  template <class InputVector>
1987  void
1989  const InputVector &fe_function,
1991  &gradients) const;
1992 
2000  template <class InputVector>
2001  void
2003  const InputVector &fe_function,
2005  &hessians) const;
2006 
2015  template <class InputVector>
2016  void
2018  const InputVector &fe_function,
2020  &third_derivatives) const;
2021 
2023 
2028 
2037  template <class InputVector>
2038  void
2040  const InputVector & fe_function,
2041  std::vector<typename InputVector::value_type> &values) const;
2042 
2050  template <class InputVector>
2051  void
2053  const InputVector &fe_function,
2055  &gradients) const;
2056 
2064  template <class InputVector>
2065  void
2067  const InputVector &fe_function,
2069  &hessians) const;
2070 
2090 
2099 
2104 private:
2108  std::vector<types::global_dof_index> interface_dof_indices;
2109 
2115  std::vector<std::array<unsigned int, 2>> dofmap;
2116 
2121 
2126 
2131 
2136 
2142 
2149 
2150  /* Make the view classes friends of this class, since they access internal
2151  * data.
2152  */
2153  template <int, int>
2155  template <int, int>
2157 };
2158 
2159 
2160 
2161 #ifndef DOXYGEN
2162 
2163 /*---------------------- Inline functions ---------------------*/
2164 
2165 template <int dim, int spacedim>
2167  const Mapping<dim, spacedim> & mapping,
2168  const FiniteElement<dim, spacedim> &fe,
2169  const Quadrature<dim - 1> & quadrature,
2170  const UpdateFlags update_flags)
2171  : n_quadrature_points(quadrature.size())
2172  , internal_fe_face_values(mapping, fe, quadrature, update_flags)
2173  , internal_fe_subface_values(mapping, fe, quadrature, update_flags)
2174  , internal_fe_face_values_neighbor(mapping, fe, quadrature, update_flags)
2175  , internal_fe_subface_values_neighbor(mapping, fe, quadrature, update_flags)
2176  , fe_face_values(nullptr)
2177  , fe_face_values_neighbor(nullptr)
2178 {}
2179 
2180 
2181 
2182 template <int dim, int spacedim>
2184  const Mapping<dim, spacedim> & mapping,
2185  const FiniteElement<dim, spacedim> &fe,
2186  const hp::QCollection<dim - 1> & quadrature,
2187  const UpdateFlags update_flags)
2188  : n_quadrature_points(quadrature.max_n_quadrature_points())
2189  , internal_fe_face_values(mapping, fe, quadrature, update_flags)
2190  , internal_fe_subface_values(mapping, fe, quadrature, update_flags)
2191  , internal_fe_face_values_neighbor(mapping, fe, quadrature[0], update_flags)
2192  , internal_fe_subface_values_neighbor(mapping,
2193  fe,
2194  quadrature[0],
2195  update_flags)
2196  , fe_face_values(nullptr)
2197  , fe_face_values_neighbor(nullptr)
2198 {}
2199 
2200 
2201 
2202 template <int dim, int spacedim>
2204  const FiniteElement<dim, spacedim> &fe,
2205  const Quadrature<dim - 1> & quadrature,
2206  const UpdateFlags update_flags)
2207  : n_quadrature_points(quadrature.size())
2208  , internal_fe_face_values(
2209  fe.reference_cell().template get_default_linear_mapping<dim, spacedim>(),
2210  fe,
2211  quadrature,
2212  update_flags)
2213  , internal_fe_subface_values(
2214  fe.reference_cell().template get_default_linear_mapping<dim, spacedim>(),
2215  fe,
2216  quadrature,
2217  update_flags)
2218  , internal_fe_face_values_neighbor(
2219  fe.reference_cell().template get_default_linear_mapping<dim, spacedim>(),
2220  fe,
2221  quadrature,
2222  update_flags)
2223  , internal_fe_subface_values_neighbor(
2224  fe.reference_cell().template get_default_linear_mapping<dim, spacedim>(),
2225  fe,
2226  quadrature,
2227  update_flags)
2228  , fe_face_values(nullptr)
2229  , fe_face_values_neighbor(nullptr)
2230 {}
2231 
2232 
2233 
2234 template <int dim, int spacedim>
2235 template <class CellIteratorType, class CellNeighborIteratorType>
2236 void
2238  const CellIteratorType & cell,
2239  const unsigned int face_no,
2240  const unsigned int sub_face_no,
2241  const CellNeighborIteratorType &cell_neighbor,
2242  const unsigned int face_no_neighbor,
2243  const unsigned int sub_face_no_neighbor)
2244 {
2245  if (sub_face_no == numbers::invalid_unsigned_int)
2246  {
2247  internal_fe_face_values.reinit(cell, face_no);
2248  fe_face_values = &internal_fe_face_values;
2249  }
2250  else
2251  {
2252  internal_fe_subface_values.reinit(cell, face_no, sub_face_no);
2253  fe_face_values = &internal_fe_subface_values;
2254  }
2255  if (sub_face_no_neighbor == numbers::invalid_unsigned_int)
2256  {
2257  internal_fe_face_values_neighbor.reinit(cell_neighbor, face_no_neighbor);
2258  fe_face_values_neighbor = &internal_fe_face_values_neighbor;
2259  }
2260  else
2261  {
2262  internal_fe_subface_values_neighbor.reinit(cell_neighbor,
2263  face_no_neighbor,
2264  sub_face_no_neighbor);
2265  fe_face_values_neighbor = &internal_fe_subface_values_neighbor;
2266  }
2267 
2268  AssertDimension(fe_face_values->n_quadrature_points,
2269  fe_face_values_neighbor->n_quadrature_points);
2270 
2271  const_cast<unsigned int &>(this->n_quadrature_points) =
2272  fe_face_values->n_quadrature_points;
2273 
2274  // Set up dof mapping and remove duplicates (for continuous elements).
2275  {
2276  // Get dof indices first:
2277  std::vector<types::global_dof_index> v(
2278  fe_face_values->get_fe().n_dofs_per_cell());
2279  cell->get_active_or_mg_dof_indices(v);
2280  std::vector<types::global_dof_index> v2(
2281  fe_face_values_neighbor->get_fe().n_dofs_per_cell());
2282  cell_neighbor->get_active_or_mg_dof_indices(v2);
2283 
2284  // Fill a map from the global dof index to the left and right
2285  // local index.
2286  std::map<types::global_dof_index, std::pair<unsigned int, unsigned int>>
2287  tempmap;
2288  std::pair<unsigned int, unsigned int> invalid_entry(
2290 
2291  for (unsigned int i = 0; i < v.size(); ++i)
2292  {
2293  // If not already existing, add an invalid entry:
2294  auto result = tempmap.insert(std::make_pair(v[i], invalid_entry));
2295  result.first->second.first = i;
2296  }
2297 
2298  for (unsigned int i = 0; i < v2.size(); ++i)
2299  {
2300  // If not already existing, add an invalid entry:
2301  auto result = tempmap.insert(std::make_pair(v2[i], invalid_entry));
2302  result.first->second.second = i;
2303  }
2304 
2305  // Transfer from the map to the sorted std::vectors.
2306  dofmap.resize(tempmap.size());
2307  interface_dof_indices.resize(tempmap.size());
2308  unsigned int idx = 0;
2309  for (auto &x : tempmap)
2310  {
2311  interface_dof_indices[idx] = x.first;
2312  dofmap[idx] = {{x.second.first, x.second.second}};
2313  ++idx;
2314  }
2315  }
2316 }
2317 
2318 
2319 
2320 template <int dim, int spacedim>
2321 template <class CellIteratorType>
2322 void
2323 FEInterfaceValues<dim, spacedim>::reinit(const CellIteratorType &cell,
2324  const unsigned int face_no)
2325 {
2326  internal_fe_face_values.reinit(cell, face_no);
2327  fe_face_values = &internal_fe_face_values;
2328  fe_face_values_neighbor = nullptr;
2329 
2330  interface_dof_indices.resize(fe_face_values->get_fe().n_dofs_per_cell());
2331  cell->get_active_or_mg_dof_indices(interface_dof_indices);
2332 
2333  dofmap.resize(interface_dof_indices.size());
2334 
2335  for (unsigned int i = 0; i < interface_dof_indices.size(); ++i)
2336  {
2337  dofmap[i] = {{i, numbers::invalid_unsigned_int}};
2338  }
2339 }
2340 
2341 
2342 
2343 template <int dim, int spacedim>
2344 inline double
2345 FEInterfaceValues<dim, spacedim>::JxW(const unsigned int q) const
2346 {
2347  Assert(fe_face_values != nullptr,
2348  ExcMessage("This call requires a call to reinit() first."));
2349  return fe_face_values->JxW(q);
2350 }
2351 
2352 
2353 
2354 template <int dim, int spacedim>
2355 const std::vector<double> &
2357 {
2358  Assert(fe_face_values != nullptr,
2359  ExcMessage("This call requires a call to reinit() first."));
2360  return fe_face_values->get_JxW_values();
2361 }
2362 
2363 
2364 
2365 template <int dim, int spacedim>
2366 const std::vector<Tensor<1, spacedim>> &
2368 {
2369  Assert(fe_face_values != nullptr,
2370  ExcMessage("This call requires a call to reinit() first."));
2371  return fe_face_values->get_normal_vectors();
2372 }
2373 
2374 
2375 
2376 template <int dim, int spacedim>
2377 const Mapping<dim, spacedim> &
2379 {
2380  return internal_fe_face_values.get_mapping();
2381 }
2382 
2383 
2384 
2385 template <int dim, int spacedim>
2388 {
2389  return internal_fe_face_values.get_fe();
2390 }
2391 
2392 
2393 
2394 template <int dim, int spacedim>
2395 const Quadrature<dim - 1> &
2397 {
2398  return internal_fe_face_values.get_quadrature();
2399 }
2400 
2401 
2402 
2403 template <int dim, int spacedim>
2406 {
2407  return {0U, n_quadrature_points};
2408 }
2409 
2410 
2411 
2412 template <int dim, int spacedim>
2413 const std::vector<Point<spacedim>> &
2415 {
2416  Assert(fe_face_values != nullptr,
2417  ExcMessage("This call requires a call to reinit() first."));
2418  return fe_face_values->get_quadrature_points();
2419 }
2420 
2421 
2422 
2423 template <int dim, int spacedim>
2426 {
2427  return internal_fe_face_values.get_update_flags();
2428 }
2429 
2430 
2431 
2432 template <int dim, int spacedim>
2435 {
2436  return get_fe_face_values(cell_index).get_cell();
2437 }
2438 
2439 
2440 
2441 template <int dim, int spacedim>
2442 inline unsigned int
2444  const unsigned int cell_index) const
2445 {
2446  return get_fe_face_values(cell_index).get_face_number();
2447 }
2448 
2449 
2450 
2451 template <int dim, int spacedim>
2452 unsigned
2454 {
2455  Assert(
2456  interface_dof_indices.size() > 0,
2457  ExcMessage(
2458  "n_current_interface_dofs() is only available after a call to reinit()."));
2459  return interface_dof_indices.size();
2460 }
2461 
2462 
2463 
2464 template <int dim, int spacedim>
2467 {
2468  return {0U, n_current_interface_dofs()};
2469 }
2470 
2471 
2472 
2473 template <int dim, int spacedim>
2474 bool
2476 {
2477  return fe_face_values_neighbor == nullptr;
2478 }
2479 
2480 
2481 
2482 template <int dim, int spacedim>
2483 std::vector<types::global_dof_index>
2485 {
2486  return interface_dof_indices;
2487 }
2488 
2489 
2490 
2491 template <int dim, int spacedim>
2492 std::array<unsigned int, 2>
2494  const unsigned int interface_dof_index) const
2495 {
2496  AssertIndexRange(interface_dof_index, n_current_interface_dofs());
2497  return dofmap[interface_dof_index];
2498 }
2499 
2500 
2501 
2502 template <int dim, int spacedim>
2505  const unsigned int cell_index) const
2506 {
2508  Assert(
2509  cell_index == 0 || !at_boundary(),
2510  ExcMessage(
2511  "You are on a boundary, so you can only ask for the first FEFaceValues object."));
2512 
2513  return (cell_index == 0) ? *fe_face_values : *fe_face_values_neighbor;
2514 }
2515 
2516 
2517 
2518 template <int dim, int spacedim>
2520 FEInterfaceValues<dim, spacedim>::normal(const unsigned int q_point_index) const
2521 {
2522  return fe_face_values->normal_vector(q_point_index);
2523 }
2524 
2525 
2526 
2527 template <int dim, int spacedim>
2528 double
2530  const bool here_or_there,
2531  const unsigned int interface_dof_index,
2532  const unsigned int q_point,
2533  const unsigned int component) const
2534 {
2535  const auto dof_pair = dofmap[interface_dof_index];
2536 
2537  if (here_or_there && dof_pair[0] != numbers::invalid_unsigned_int)
2538  return get_fe_face_values(0).shape_value_component(dof_pair[0],
2539  q_point,
2540  component);
2541  if (!here_or_there && dof_pair[1] != numbers::invalid_unsigned_int)
2542  return get_fe_face_values(1).shape_value_component(dof_pair[1],
2543  q_point,
2544  component);
2545 
2546  return 0.0;
2547 }
2548 
2549 
2550 
2551 template <int dim, int spacedim>
2552 double
2554  const unsigned int interface_dof_index,
2555  const unsigned int q_point,
2556  const unsigned int component) const
2557 {
2558  const auto dof_pair = dofmap[interface_dof_index];
2559 
2560  double value = 0.0;
2561 
2562  if (dof_pair[0] != numbers::invalid_unsigned_int)
2563  value += get_fe_face_values(0).shape_value_component(dof_pair[0],
2564  q_point,
2565  component);
2566  if (dof_pair[1] != numbers::invalid_unsigned_int)
2567  value -= get_fe_face_values(1).shape_value_component(dof_pair[1],
2568  q_point,
2569  component);
2570  return value;
2571 }
2572 
2573 
2574 
2575 template <int dim, int spacedim>
2576 double
2577 FEInterfaceValues<dim, spacedim>::jump(const unsigned int interface_dof_index,
2578  const unsigned int q_point,
2579  const unsigned int component) const
2580 {
2581  return jump_in_shape_values(interface_dof_index, q_point, component);
2582 }
2583 
2584 
2585 
2586 template <int dim, int spacedim>
2587 double
2589  const unsigned int interface_dof_index,
2590  const unsigned int q_point,
2591  const unsigned int component) const
2592 {
2593  const auto dof_pair = dofmap[interface_dof_index];
2594 
2595  if (at_boundary())
2596  return get_fe_face_values(0).shape_value_component(dof_pair[0],
2597  q_point,
2598  component);
2599 
2600  double value = 0.0;
2601 
2602  if (dof_pair[0] != numbers::invalid_unsigned_int)
2603  value += 0.5 * get_fe_face_values(0).shape_value_component(dof_pair[0],
2604  q_point,
2605  component);
2606  if (dof_pair[1] != numbers::invalid_unsigned_int)
2607  value += 0.5 * get_fe_face_values(1).shape_value_component(dof_pair[1],
2608  q_point,
2609  component);
2610 
2611  return value;
2612 }
2613 
2614 
2615 
2616 template <int dim, int spacedim>
2617 double
2619  const unsigned int interface_dof_index,
2620  const unsigned int q_point,
2621  const unsigned int component) const
2622 {
2623  return average_of_shape_values(interface_dof_index, q_point, component);
2624 }
2625 
2626 
2627 
2628 template <int dim, int spacedim>
2631  const unsigned int interface_dof_index,
2632  const unsigned int q_point,
2633  const unsigned int component) const
2634 {
2635  const auto dof_pair = dofmap[interface_dof_index];
2636 
2637  if (at_boundary())
2638  return get_fe_face_values(0).shape_grad_component(dof_pair[0],
2639  q_point,
2640  component);
2641 
2643 
2644  if (dof_pair[0] != numbers::invalid_unsigned_int)
2645  value += 0.5 * get_fe_face_values(0).shape_grad_component(dof_pair[0],
2646  q_point,
2647  component);
2648  if (dof_pair[1] != numbers::invalid_unsigned_int)
2649  value += 0.5 * get_fe_face_values(1).shape_grad_component(dof_pair[1],
2650  q_point,
2651  component);
2652 
2653  return value;
2654 }
2655 
2656 
2657 
2658 template <int dim, int spacedim>
2661  const unsigned int interface_dof_index,
2662  const unsigned int q_point,
2663  const unsigned int component) const
2664 {
2665  return average_of_shape_gradients(interface_dof_index, q_point, component);
2666 }
2667 
2668 
2669 
2670 template <int dim, int spacedim>
2673  const unsigned int interface_dof_index,
2674  const unsigned int q_point,
2675  const unsigned int component) const
2676 {
2677  const auto dof_pair = dofmap[interface_dof_index];
2678 
2679  if (at_boundary())
2680  return get_fe_face_values(0).shape_hessian_component(dof_pair[0],
2681  q_point,
2682  component);
2683 
2685 
2686  if (dof_pair[0] != numbers::invalid_unsigned_int)
2687  value += 0.5 * get_fe_face_values(0).shape_hessian_component(dof_pair[0],
2688  q_point,
2689  component);
2690  if (dof_pair[1] != numbers::invalid_unsigned_int)
2691  value += 0.5 * get_fe_face_values(1).shape_hessian_component(dof_pair[1],
2692  q_point,
2693  component);
2694 
2695  return value;
2696 }
2697 
2698 
2699 
2700 template <int dim, int spacedim>
2703  const unsigned int interface_dof_index,
2704  const unsigned int q_point,
2705  const unsigned int component) const
2706 {
2707  return average_of_shape_hessians(interface_dof_index, q_point, component);
2708 }
2709 
2710 
2711 
2712 template <int dim, int spacedim>
2715  const unsigned int interface_dof_index,
2716  const unsigned int q_point,
2717  const unsigned int component) const
2718 {
2719  const auto dof_pair = dofmap[interface_dof_index];
2720 
2721  if (at_boundary())
2722  return get_fe_face_values(0).shape_grad_component(dof_pair[0],
2723  q_point,
2724  component);
2725 
2727 
2728  if (dof_pair[0] != numbers::invalid_unsigned_int)
2729  value += get_fe_face_values(0).shape_grad_component(dof_pair[0],
2730  q_point,
2731  component);
2732  if (dof_pair[1] != numbers::invalid_unsigned_int)
2733  value -= get_fe_face_values(1).shape_grad_component(dof_pair[1],
2734  q_point,
2735  component);
2736 
2737  return value;
2738 }
2739 
2740 
2741 
2742 template <int dim, int spacedim>
2745  const unsigned int interface_dof_index,
2746  const unsigned int q_point,
2747  const unsigned int component) const
2748 {
2749  return jump_in_shape_gradients(interface_dof_index, q_point, component);
2750 }
2751 
2752 
2753 
2754 template <int dim, int spacedim>
2757  const unsigned int interface_dof_index,
2758  const unsigned int q_point,
2759  const unsigned int component) const
2760 {
2761  const auto dof_pair = dofmap[interface_dof_index];
2762 
2763  if (at_boundary())
2764  return get_fe_face_values(0).shape_hessian_component(dof_pair[0],
2765  q_point,
2766  component);
2767 
2769 
2770  if (dof_pair[0] != numbers::invalid_unsigned_int)
2771  value += get_fe_face_values(0).shape_hessian_component(dof_pair[0],
2772  q_point,
2773  component);
2774  if (dof_pair[1] != numbers::invalid_unsigned_int)
2775  value -= get_fe_face_values(1).shape_hessian_component(dof_pair[1],
2776  q_point,
2777  component);
2778 
2779  return value;
2780 }
2781 
2782 
2783 
2784 template <int dim, int spacedim>
2787  const unsigned int interface_dof_index,
2788  const unsigned int q_point,
2789  const unsigned int component) const
2790 {
2791  return jump_in_shape_hessians(interface_dof_index, q_point, component);
2792 }
2793 
2794 
2795 
2796 template <int dim, int spacedim>
2799  const unsigned int interface_dof_index,
2800  const unsigned int q_point,
2801  const unsigned int component) const
2802 {
2803  const auto dof_pair = dofmap[interface_dof_index];
2804 
2805  if (at_boundary())
2806  return get_fe_face_values(0).shape_3rd_derivative_component(dof_pair[0],
2807  q_point,
2808  component);
2809 
2811 
2812  if (dof_pair[0] != numbers::invalid_unsigned_int)
2813  value += get_fe_face_values(0).shape_3rd_derivative_component(dof_pair[0],
2814  q_point,
2815  component);
2816  if (dof_pair[1] != numbers::invalid_unsigned_int)
2817  value -= get_fe_face_values(1).shape_3rd_derivative_component(dof_pair[1],
2818  q_point,
2819  component);
2820 
2821  return value;
2822 }
2823 
2824 
2825 
2826 template <int dim, int spacedim>
2829  const unsigned int interface_dof_index,
2830  const unsigned int q_point,
2831  const unsigned int component) const
2832 {
2833  return jump_in_shape_3rd_derivatives(interface_dof_index, q_point, component);
2834 }
2835 
2836 
2837 
2838 template <int dim, int spacedim>
2839 template <class InputVector>
2840 void
2842  const InputVector & fe_function,
2843  std::vector<typename InputVector::value_type> &values) const
2844 {
2845  AssertDimension(values.size(), n_quadrature_points);
2846 
2848  this->operator[](scalar).get_jump_in_function_values(fe_function, values);
2849 }
2850 
2851 
2852 
2853 template <int dim, int spacedim>
2854 template <class InputVector>
2855 void
2857  const InputVector &fe_function,
2859  const
2860 {
2861  AssertDimension(gradients.size(), n_quadrature_points);
2862 
2864  this->operator[](scalar).get_jump_in_function_gradients(fe_function,
2865  gradients);
2866 }
2867 
2868 
2869 
2870 template <int dim, int spacedim>
2871 template <class InputVector>
2872 void
2874  const InputVector &fe_function,
2876  const
2877 {
2878  AssertDimension(hessians.size(), n_quadrature_points);
2879 
2881  this->operator[](scalar).get_jump_in_function_hessians(fe_function, hessians);
2882 }
2883 
2884 
2885 
2886 template <int dim, int spacedim>
2887 template <class InputVector>
2888 void
2890  const InputVector &fe_function,
2892  &third_derivatives) const
2893 {
2894  AssertDimension(third_derivatives.size(), n_quadrature_points);
2895 
2897  this->operator[](scalar).get_jump_in_function_third_derivatives(
2898  fe_function, third_derivatives);
2899 }
2900 
2901 
2902 
2903 template <int dim, int spacedim>
2904 template <class InputVector>
2905 void
2907  const InputVector & fe_function,
2908  std::vector<typename InputVector::value_type> &values) const
2909 {
2910  AssertDimension(values.size(), n_quadrature_points);
2911 
2913  this->operator[](scalar).get_average_of_function_values(fe_function, values);
2914 }
2915 
2916 
2917 
2918 template <int dim, int spacedim>
2919 template <class InputVector>
2920 void
2922  const InputVector &fe_function,
2924  const
2925 {
2926  AssertDimension(gradients.size(), n_quadrature_points);
2927 
2929  this->operator[](scalar).get_average_of_function_gradients(fe_function,
2930  gradients);
2931 }
2932 
2933 
2934 
2935 template <int dim, int spacedim>
2936 template <class InputVector>
2937 void
2939  const InputVector &fe_function,
2941  const
2942 {
2943  AssertDimension(hessians.size(), n_quadrature_points);
2944 
2946  this->operator[](scalar).get_average_of_function_hessians(fe_function,
2947  hessians);
2948 }
2949 
2950 
2951 
2952 /*------------ Inline functions: FEInterfaceValues------------*/
2953 template <int dim, int spacedim>
2956  const FEValuesExtractors::Scalar &scalar) const
2957 {
2958  AssertIndexRange(scalar.component, this->get_fe().n_components());
2959  return FEInterfaceViews::Scalar<dim, spacedim>(*this, scalar.component);
2960 }
2961 
2962 
2963 
2964 template <int dim, int spacedim>
2967  const FEValuesExtractors::Vector &vector) const
2968 {
2969  const FiniteElement<dim, spacedim> &fe = this->get_fe();
2970  const unsigned int n_vectors =
2973  0);
2974  (void)n_vectors;
2975  AssertIndexRange(vector.first_vector_component, n_vectors);
2977  vector.first_vector_component);
2978 }
2979 
2980 
2981 
2982 namespace FEInterfaceViews
2983 {
2984  template <int dim, int spacedim>
2986  const FEInterfaceValues<dim, spacedim> &fe_interface)
2987  : fe_interface(&fe_interface)
2988  {}
2989 
2990 
2991 
2992  template <int dim, int spacedim>
2994  const FEInterfaceValues<dim, spacedim> &fe_interface,
2995  const unsigned int component)
2996  : Base<dim, spacedim>(fe_interface)
2997  , extractor(component)
2998  {}
2999 
3000 
3001 
3002  template <int dim, int spacedim>
3003  template <class InputVector, class OutputVector>
3004  void
3005  Base<dim, spacedim>::get_local_dof_values(
3006  const InputVector &dof_values,
3007  OutputVector & local_dof_values) const
3008  {
3009  const auto &interface_dof_indices =
3010  this->fe_interface->get_interface_dof_indices();
3011 
3012  AssertDimension(interface_dof_indices.size(), local_dof_values.size());
3013 
3014  for (unsigned int i : this->fe_interface->dof_indices())
3015  local_dof_values[i] = dof_values(interface_dof_indices[i]);
3016  }
3017 
3018 
3019 
3020  template <int dim, int spacedim>
3022  Scalar<dim, spacedim>::value(const bool here_or_there,
3023  const unsigned int interface_dof_index,
3024  const unsigned int q_point) const
3025  {
3026  const auto dof_pair = this->fe_interface->dofmap[interface_dof_index];
3027 
3028  if (here_or_there && dof_pair[0] != numbers::invalid_unsigned_int)
3029  return (*(this->fe_interface->fe_face_values))[extractor].value(
3030  dof_pair[0], q_point);
3031 
3032  if (!here_or_there && dof_pair[1] != numbers::invalid_unsigned_int)
3033  return (*(this->fe_interface->fe_face_values_neighbor))[extractor].value(
3034  dof_pair[1], q_point);
3035 
3036  return 0.0;
3037  }
3038 
3039 
3040 
3041  template <int dim, int spacedim>
3043  Scalar<dim, spacedim>::jump_in_values(const unsigned int interface_dof_index,
3044  const unsigned int q_point) const
3045  {
3046  const auto dof_pair = this->fe_interface->dofmap[interface_dof_index];
3047 
3048  value_type value = 0.0;
3049 
3050  if (dof_pair[0] != numbers::invalid_unsigned_int)
3051  value +=
3052  (*(this->fe_interface->fe_face_values))[extractor].value(dof_pair[0],
3053  q_point);
3054 
3055  if (dof_pair[1] != numbers::invalid_unsigned_int)
3056  value -=
3057  (*(this->fe_interface->fe_face_values_neighbor))[extractor].value(
3058  dof_pair[1], q_point);
3059 
3060  return value;
3061  }
3062 
3063 
3064 
3065  template <int dim, int spacedim>
3067  Scalar<dim, spacedim>::jump(const unsigned int interface_dof_index,
3068  const unsigned int q_point) const
3069  {
3070  return jump_in_values(interface_dof_index, q_point);
3071  }
3072 
3073 
3074 
3075  template <int dim, int spacedim>
3077  Scalar<dim, spacedim>::average_of_values(
3078  const unsigned int interface_dof_index,
3079  const unsigned int q_point) const
3080  {
3081  const auto dof_pair = this->fe_interface->dofmap[interface_dof_index];
3082 
3083  if (this->fe_interface->at_boundary())
3084  return (*(this->fe_interface->fe_face_values))[extractor].value(
3085  dof_pair[0], q_point);
3086 
3087  value_type value = 0.0;
3088 
3089  if (dof_pair[0] != numbers::invalid_unsigned_int)
3090  value +=
3091  0.5 *
3092  (*(this->fe_interface->fe_face_values))[extractor].value(dof_pair[0],
3093  q_point);
3094 
3095  if (dof_pair[1] != numbers::invalid_unsigned_int)
3096  value +=
3097  0.5 * (*(this->fe_interface->fe_face_values_neighbor))[extractor].value(
3098  dof_pair[1], q_point);
3099 
3100  return value;
3101  }
3102 
3103 
3104 
3105  template <int dim, int spacedim>
3107  Scalar<dim, spacedim>::average(const unsigned int interface_dof_index,
3108  const unsigned int q_point) const
3109  {
3110  return average_of_values(interface_dof_index, q_point);
3111  }
3112 
3113 
3114 
3115  template <int dim, int spacedim>
3117  Scalar<dim, spacedim>::average_of_gradients(
3118  const unsigned int interface_dof_index,
3119  const unsigned int q_point) const
3120  {
3121  const auto dof_pair = this->fe_interface->dofmap[interface_dof_index];
3122 
3123  if (this->fe_interface->at_boundary())
3124  return (*(this->fe_interface->fe_face_values))[extractor].gradient(
3125  dof_pair[0], q_point);
3126 
3127  gradient_type value;
3128 
3129  if (dof_pair[0] != numbers::invalid_unsigned_int)
3130  value +=
3131  0.5 *
3132  (*(this->fe_interface->fe_face_values))[extractor].gradient(dof_pair[0],
3133  q_point);
3134 
3135  if (dof_pair[1] != numbers::invalid_unsigned_int)
3136  value += 0.5 * (*(this->fe_interface->fe_face_values_neighbor))[extractor]
3137  .gradient(dof_pair[1], q_point);
3138 
3139  return value;
3140  }
3141 
3142 
3143  template <int dim, int spacedim>
3145  Scalar<dim, spacedim>::average_gradient(
3146  const unsigned int interface_dof_index,
3147  const unsigned int q_point) const
3148  {
3149  return average_of_gradients(interface_dof_index, q_point);
3150  }
3151 
3152 
3153 
3154  template <int dim, int spacedim>
3156  Scalar<dim, spacedim>::jump_in_gradients(
3157  const unsigned int interface_dof_index,
3158  const unsigned int q_point) const
3159  {
3160  const auto dof_pair = this->fe_interface->dofmap[interface_dof_index];
3161 
3162  if (this->fe_interface->at_boundary())
3163  return (*(this->fe_interface->fe_face_values))[extractor].gradient(
3164  dof_pair[0], q_point);
3165 
3166  gradient_type value;
3167 
3168  if (dof_pair[0] != numbers::invalid_unsigned_int)
3169  value +=
3170  (*(this->fe_interface->fe_face_values))[extractor].gradient(dof_pair[0],
3171  q_point);
3172 
3173  if (dof_pair[1] != numbers::invalid_unsigned_int)
3174  value -=
3175  (*(this->fe_interface->fe_face_values_neighbor))[extractor].gradient(
3176  dof_pair[1], q_point);
3177 
3178  return value;
3179  }
3180 
3181 
3182 
3183  template <int dim, int spacedim>
3185  Scalar<dim, spacedim>::jump_gradient(const unsigned int interface_dof_index,
3186  const unsigned int q_point) const
3187  {
3188  return jump_in_gradients(interface_dof_index, q_point);
3189  }
3190 
3191 
3192 
3193  template <int dim, int spacedim>
3195  Scalar<dim, spacedim>::average_of_hessians(
3196  const unsigned int interface_dof_index,
3197  const unsigned int q_point) const
3198  {
3199  const auto dof_pair = this->fe_interface->dofmap[interface_dof_index];
3200 
3201  if (this->fe_interface->at_boundary())
3202  return (*(this->fe_interface->fe_face_values))[extractor].hessian(
3203  dof_pair[0], q_point);
3204 
3205  hessian_type value;
3206 
3207  if (dof_pair[0] != numbers::invalid_unsigned_int)
3208  value +=
3209  0.5 *
3210  (*(this->fe_interface->fe_face_values))[extractor].hessian(dof_pair[0],
3211  q_point);
3212 
3213  if (dof_pair[1] != numbers::invalid_unsigned_int)
3214  value += 0.5 * (*(this->fe_interface->fe_face_values_neighbor))[extractor]
3215  .hessian(dof_pair[1], q_point);
3216 
3217  return value;
3218  }
3219 
3220 
3221 
3222  template <int dim, int spacedim>
3224  Scalar<dim, spacedim>::average_hessian(const unsigned int interface_dof_index,
3225  const unsigned int q_point) const
3226  {
3227  return average_of_hessians(interface_dof_index, q_point);
3228  }
3229 
3230 
3231 
3232  template <int dim, int spacedim>
3234  Scalar<dim, spacedim>::jump_in_third_derivatives(
3235  const unsigned int interface_dof_index,
3236  const unsigned int q_point) const
3237  {
3238  const auto dof_pair = this->fe_interface->dofmap[interface_dof_index];
3239 
3240  if (this->fe_interface->at_boundary())
3241  return (*(this->fe_interface->fe_face_values))[extractor]
3242  .third_derivative(dof_pair[0], q_point);
3243 
3244  third_derivative_type value;
3245 
3246  if (dof_pair[0] != numbers::invalid_unsigned_int)
3247  value +=
3248  (*(this->fe_interface->fe_face_values))[extractor].third_derivative(
3249  dof_pair[0], q_point);
3250 
3251  if (dof_pair[1] != numbers::invalid_unsigned_int)
3252  value -= (*(this->fe_interface->fe_face_values_neighbor))[extractor]
3253  .third_derivative(dof_pair[1], q_point);
3254 
3255  return value;
3256  }
3257 
3258 
3259 
3260  template <int dim, int spacedim>
3262  Scalar<dim, spacedim>::jump_3rd_derivative(
3263  const unsigned int interface_dof_index,
3264  const unsigned int q_point) const
3265  {
3266  return jump_in_third_derivatives(interface_dof_index, q_point);
3267  }
3268 
3269 
3270 
3271  template <int dim, int spacedim>
3273  Scalar<dim, spacedim>::jump_in_hessians(
3274  const unsigned int interface_dof_index,
3275  const unsigned int q_point) const
3276  {
3277  const auto dof_pair = this->fe_interface->dofmap[interface_dof_index];
3278 
3279  if (this->fe_interface->at_boundary())
3280  return (*(this->fe_interface->fe_face_values))[extractor].hessian(
3281  dof_pair[0], q_point);
3282 
3283  hessian_type value;
3284 
3285  if (dof_pair[0] != numbers::invalid_unsigned_int)
3286  value +=
3287  (*(this->fe_interface->fe_face_values))[extractor].hessian(dof_pair[0],
3288  q_point);
3289 
3290  if (dof_pair[1] != numbers::invalid_unsigned_int)
3291  value -=
3292  (*(this->fe_interface->fe_face_values_neighbor))[extractor].hessian(
3293  dof_pair[1], q_point);
3294 
3295  return value;
3296  }
3297 
3298 
3299 
3300  template <int dim, int spacedim>
3302  Scalar<dim, spacedim>::jump_hessian(const unsigned int interface_dof_index,
3303  const unsigned int q_point) const
3304  {
3305  return jump_in_hessians(interface_dof_index, q_point);
3306  }
3307 
3308 
3309 
3310  template <int dim, int spacedim>
3311  template <class InputVector>
3312  void
3314  const bool here_or_there,
3315  const InputVector &local_dof_values,
3316  std::vector<solution_value_type<typename InputVector::value_type>> &values)
3317  const
3318  {
3319  AssertDimension(values.size(), this->fe_interface->n_quadrature_points);
3320 
3321  for (const auto dof_index : this->fe_interface->dof_indices())
3322  for (const auto q_index : this->fe_interface->quadrature_point_indices())
3323  {
3324  if (dof_index == 0)
3325  values[q_index] = 0.;
3326 
3327  values[q_index] += local_dof_values[dof_index] *
3328  value(here_or_there, dof_index, q_index);
3329  }
3330  }
3331 
3332 
3333 
3334  template <int dim, int spacedim>
3335  template <class InputVector>
3336  void
3338  const bool here_or_there,
3339  const InputVector &fe_function,
3340  std::vector<solution_value_type<typename InputVector::value_type>> &values)
3341  const
3342  {
3343  std::vector<typename InputVector::value_type> local_dof_values(
3344  this->fe_interface->n_current_interface_dofs());
3345  this->get_local_dof_values(fe_function, local_dof_values);
3346 
3347  get_function_values_from_local_dof_values(here_or_there,
3348  local_dof_values,
3349  values);
3350  }
3351 
3352 
3353 
3354  template <int dim, int spacedim>
3355  template <class InputVector>
3356  void
3357  Scalar<dim, spacedim>::get_jump_in_function_values_from_local_dof_values(
3358  const InputVector &local_dof_values,
3359  std::vector<solution_value_type<typename InputVector::value_type>> &values)
3360  const
3361  {
3362  AssertDimension(values.size(), this->fe_interface->n_quadrature_points);
3363 
3364  for (const auto dof_index : this->fe_interface->dof_indices())
3365  for (const auto q_index : this->fe_interface->quadrature_point_indices())
3366  {
3367  if (dof_index == 0)
3368  values[q_index] = 0.;
3369 
3370  values[q_index] +=
3371  local_dof_values[dof_index] * jump_in_values(dof_index, q_index);
3372  }
3373  }
3374 
3375 
3376 
3377  template <int dim, int spacedim>
3378  template <class InputVector>
3379  void
3380  Scalar<dim, spacedim>::get_jump_in_function_values(
3381  const InputVector &fe_function,
3382  std::vector<solution_value_type<typename InputVector::value_type>> &values)
3383  const
3384  {
3385  std::vector<typename InputVector::value_type> local_dof_values(
3386  this->fe_interface->n_current_interface_dofs());
3387  this->get_local_dof_values(fe_function, local_dof_values);
3388 
3389  get_jump_in_function_values_from_local_dof_values(local_dof_values, values);
3390  }
3391 
3392 
3393 
3394  template <int dim, int spacedim>
3395  template <class InputVector>
3396  void
3397  Scalar<dim, spacedim>::get_jump_in_function_gradients_from_local_dof_values(
3398  const InputVector &local_dof_values,
3399  std::vector<solution_gradient_type<typename InputVector::value_type>>
3400  &gradients) const
3401  {
3402  AssertDimension(gradients.size(), this->fe_interface->n_quadrature_points);
3403 
3404  for (const auto dof_index : this->fe_interface->dof_indices())
3405  for (const auto q_index : this->fe_interface->quadrature_point_indices())
3406  {
3407  if (dof_index == 0)
3408  gradients[q_index] = 0.;
3409 
3410  gradients[q_index] +=
3411  local_dof_values[dof_index] * jump_in_gradients(dof_index, q_index);
3412  }
3413  }
3414 
3415 
3416 
3417  template <int dim, int spacedim>
3418  template <class InputVector>
3419  void
3420  Scalar<dim, spacedim>::get_jump_in_function_gradients(
3421  const InputVector &fe_function,
3422  std::vector<solution_gradient_type<typename InputVector::value_type>>
3423  &gradients) const
3424  {
3425  std::vector<typename InputVector::value_type> local_dof_values(
3426  this->fe_interface->n_current_interface_dofs());
3427  this->get_local_dof_values(fe_function, local_dof_values);
3428 
3429  get_jump_in_function_gradients_from_local_dof_values(local_dof_values,
3430  gradients);
3431  }
3432 
3433 
3434 
3435  template <int dim, int spacedim>
3436  template <class InputVector>
3437  void
3438  Scalar<dim, spacedim>::get_average_of_function_values_from_local_dof_values(
3439  const InputVector &local_dof_values,
3440  std::vector<solution_value_type<typename InputVector::value_type>> &values)
3441  const
3442  {
3443  AssertDimension(values.size(), this->fe_interface->n_quadrature_points);
3444 
3445  for (const auto dof_index : this->fe_interface->dof_indices())
3446  for (const auto q_index : this->fe_interface->quadrature_point_indices())
3447  {
3448  if (dof_index == 0)
3449  values[q_index] = 0.;
3450 
3451  values[q_index] +=
3452  local_dof_values[dof_index] * average_of_values(dof_index, q_index);
3453  }
3454  }
3455 
3456 
3457 
3458  template <int dim, int spacedim>
3459  template <class InputVector>
3460  void
3461  Scalar<dim, spacedim>::get_average_of_function_values(
3462  const InputVector &fe_function,
3463  std::vector<solution_value_type<typename InputVector::value_type>> &values)
3464  const
3465  {
3466  std::vector<typename InputVector::value_type> local_dof_values(
3467  this->fe_interface->n_current_interface_dofs());
3468  this->get_local_dof_values(fe_function, local_dof_values);
3469 
3470  get_average_of_function_values_from_local_dof_values(local_dof_values,
3471  values);
3472  }
3473 
3474 
3475 
3476  template <int dim, int spacedim>
3477  template <class InputVector>
3478  void
3479  Scalar<dim, spacedim>::
3480  get_average_of_function_gradients_from_local_dof_values(
3481  const InputVector &local_dof_values,
3482  std::vector<solution_gradient_type<typename InputVector::value_type>>
3483  &gradients) const
3484  {
3485  AssertDimension(gradients.size(), this->fe_interface->n_quadrature_points);
3486 
3487  for (const auto dof_index : this->fe_interface->dof_indices())
3488  for (const auto q_index : this->fe_interface->quadrature_point_indices())
3489  {
3490  if (dof_index == 0)
3491  gradients[q_index] = 0.;
3492 
3493  gradients[q_index] += local_dof_values[dof_index] *
3494  average_of_gradients(dof_index, q_index);
3495  }
3496  }
3497 
3498 
3499 
3500  template <int dim, int spacedim>
3501  template <class InputVector>
3502  void
3503  Scalar<dim, spacedim>::get_average_of_function_gradients(
3504  const InputVector &fe_function,
3505  std::vector<solution_gradient_type<typename InputVector::value_type>>
3506  &gradients) const
3507  {
3508  std::vector<typename InputVector::value_type> local_dof_values(
3509  this->fe_interface->n_current_interface_dofs());
3510  this->get_local_dof_values(fe_function, local_dof_values);
3511 
3512  get_average_of_function_gradients_from_local_dof_values(local_dof_values,
3513  gradients);
3514  }
3515 
3516 
3517 
3518  template <int dim, int spacedim>
3519  template <class InputVector>
3520  void
3521  Scalar<dim, spacedim>::get_jump_in_function_hessians_from_local_dof_values(
3522  const InputVector &local_dof_values,
3523  std::vector<solution_hessian_type<typename InputVector::value_type>>
3524  &hessians) const
3525  {
3526  AssertDimension(hessians.size(), this->fe_interface->n_quadrature_points);
3527 
3528  for (const auto dof_index : this->fe_interface->dof_indices())
3529  for (const auto q_index : this->fe_interface->quadrature_point_indices())
3530  {
3531  if (dof_index == 0)
3532  hessians[q_index] = 0.;
3533 
3534  hessians[q_index] +=
3535  local_dof_values[dof_index] * jump_in_hessians(dof_index, q_index);
3536  }
3537  }
3538 
3539 
3540 
3541  template <int dim, int spacedim>
3542  template <class InputVector>
3543  void
3544  Scalar<dim, spacedim>::get_jump_in_function_hessians(
3545  const InputVector &fe_function,
3546  std::vector<solution_hessian_type<typename InputVector::value_type>>
3547  &hessians) const
3548  {
3549  std::vector<typename InputVector::value_type> local_dof_values(
3550  this->fe_interface->n_current_interface_dofs());
3551  this->get_local_dof_values(fe_function, local_dof_values);
3552 
3553  get_jump_in_function_hessians_from_local_dof_values(local_dof_values,
3554  hessians);
3555  }
3556 
3557 
3558 
3559  template <int dim, int spacedim>
3560  template <class InputVector>
3561  void
3562  Scalar<dim, spacedim>::get_average_of_function_hessians_from_local_dof_values(
3563  const InputVector &local_dof_values,
3564  std::vector<solution_hessian_type<typename InputVector::value_type>>
3565  &hessians) const
3566  {
3567  AssertDimension(hessians.size(), this->fe_interface->n_quadrature_points);
3568 
3569  for (unsigned int dof_index : this->fe_interface->dof_indices())
3570  for (const auto q_index : this->fe_interface->quadrature_point_indices())
3571  {
3572  if (dof_index == 0)
3573  hessians[q_index] = 0.;
3574 
3575  hessians[q_index] += local_dof_values[dof_index] *
3576  average_of_hessians(dof_index, q_index);
3577  }
3578  }
3579 
3580 
3581 
3582  template <int dim, int spacedim>
3583  template <class InputVector>
3584  void
3585  Scalar<dim, spacedim>::get_average_of_function_hessians(
3586  const InputVector &fe_function,
3587  std::vector<solution_hessian_type<typename InputVector::value_type>>
3588  &hessians) const
3589  {
3590  std::vector<typename InputVector::value_type> local_dof_values(
3591  this->fe_interface->n_current_interface_dofs());
3592  this->get_local_dof_values(fe_function, local_dof_values);
3593 
3594  get_average_of_function_hessians_from_local_dof_values(local_dof_values,
3595  hessians);
3596  }
3597 
3598 
3599 
3600  template <int dim, int spacedim>
3601  template <class InputVector>
3602  void
3603  Scalar<dim, spacedim>::
3604  get_jump_in_function_third_derivatives_from_local_dof_values(
3605  const InputVector &local_dof_values,
3606  std::vector<
3607  solution_third_derivative_type<typename InputVector::value_type>>
3608  &third_derivatives) const
3609  {
3610  AssertDimension(third_derivatives.size(),
3611  this->fe_interface->n_quadrature_points);
3612 
3613  for (unsigned int dof_index : this->fe_interface->dof_indices())
3614  for (const auto q_index : this->fe_interface->quadrature_point_indices())
3615  {
3616  if (dof_index == 0)
3617  third_derivatives[q_index] = 0.;
3618 
3619  third_derivatives[q_index] +=
3620  local_dof_values[dof_index] *
3621  jump_in_third_derivatives(dof_index, q_index);
3622  }
3623  }
3624 
3625 
3626 
3627  template <int dim, int spacedim>
3628  template <class InputVector>
3629  void
3630  Scalar<dim, spacedim>::get_jump_in_function_third_derivatives(
3631  const InputVector &fe_function,
3632  std::vector<
3633  solution_third_derivative_type<typename InputVector::value_type>>
3634  &third_derivatives) const
3635  {
3636  std::vector<typename InputVector::value_type> local_dof_values(
3637  this->fe_interface->n_current_interface_dofs());
3638  this->get_local_dof_values(fe_function, local_dof_values);
3639 
3640  get_jump_in_function_third_derivatives_from_local_dof_values(
3641  local_dof_values, third_derivatives);
3642  }
3643 
3644 
3645 
3646  template <int dim, int spacedim>
3648  const FEInterfaceValues<dim, spacedim> &fe_interface,
3649  const unsigned int first_vector_component)
3650  : Base<dim, spacedim>(fe_interface)
3651  , extractor(first_vector_component)
3652  {}
3653 
3654 
3655 
3656  template <int dim, int spacedim>
3658  Vector<dim, spacedim>::value(const bool here_or_there,
3659  const unsigned int interface_dof_index,
3660  const unsigned int q_point) const
3661  {
3662  const auto dof_pair = this->fe_interface->dofmap[interface_dof_index];
3663 
3664  if (here_or_there && dof_pair[0] != numbers::invalid_unsigned_int)
3665  return (*(this->fe_interface->fe_face_values))[extractor].value(
3666  dof_pair[0], q_point);
3667 
3668  if (!here_or_there && dof_pair[1] != numbers::invalid_unsigned_int)
3669  return (*(this->fe_interface->fe_face_values_neighbor))[extractor].value(
3670  dof_pair[1], q_point);
3671 
3672  return value_type();
3673  }
3674 
3675 
3676 
3677  template <int dim, int spacedim>
3679  Vector<dim, spacedim>::jump_in_values(const unsigned int interface_dof_index,
3680  const unsigned int q_point) const
3681  {
3682  const auto dof_pair = this->fe_interface->dofmap[interface_dof_index];
3683 
3684  value_type value;
3685 
3686  if (dof_pair[0] != numbers::invalid_unsigned_int)
3687  value +=
3688  (*(this->fe_interface->fe_face_values))[extractor].value(dof_pair[0],
3689  q_point);
3690 
3691  if (dof_pair[1] != numbers::invalid_unsigned_int)
3692  value -=
3693  (*(this->fe_interface->fe_face_values_neighbor))[extractor].value(
3694  dof_pair[1], q_point);
3695 
3696  return value;
3697  }
3698 
3699 
3700 
3701  template <int dim, int spacedim>
3703  Vector<dim, spacedim>::jump(const unsigned int interface_dof_index,
3704  const unsigned int q_point) const
3705  {
3706  return jump_in_values(interface_dof_index, q_point);
3707  }
3708 
3709 
3710 
3711  template <int dim, int spacedim>
3714  const unsigned int interface_dof_index,
3715  const unsigned int q_point) const
3716  {
3717  const auto dof_pair = this->fe_interface->dofmap[interface_dof_index];
3718 
3719  if (this->fe_interface->at_boundary())
3720  return (*(this->fe_interface->fe_face_values))[extractor].value(
3721  dof_pair[0], q_point);
3722 
3723  value_type value;
3724 
3725  if (dof_pair[0] != numbers::invalid_unsigned_int)
3726  value +=
3727  0.5 *
3728  (*(this->fe_interface->fe_face_values))[extractor].value(dof_pair[0],
3729  q_point);
3730 
3731  if (dof_pair[1] != numbers::invalid_unsigned_int)
3732  value +=
3733  0.5 * (*(this->fe_interface->fe_face_values_neighbor))[extractor].value(
3734  dof_pair[1], q_point);
3735 
3736  return value;
3737  }
3738 
3739 
3740 
3741  template <int dim, int spacedim>
3743  Vector<dim, spacedim>::average(const unsigned int interface_dof_index,
3744  const unsigned int q_point) const
3745  {
3746  return average_of_values(interface_dof_index, q_point);
3747  }
3748 
3749 
3750 
3751  template <int dim, int spacedim>
3754  const unsigned int interface_dof_index,
3755  const unsigned int q_point) const
3756  {
3757  const auto dof_pair = this->fe_interface->dofmap[interface_dof_index];
3758 
3759  if (this->fe_interface->at_boundary())
3760  return (*(this->fe_interface->fe_face_values))[extractor].gradient(
3761  dof_pair[0], q_point);
3762 
3763  gradient_type value;
3764 
3765  if (dof_pair[0] != numbers::invalid_unsigned_int)
3766  value +=
3767  0.5 *
3768  (*(this->fe_interface->fe_face_values))[extractor].gradient(dof_pair[0],
3769  q_point);
3770 
3771  if (dof_pair[1] != numbers::invalid_unsigned_int)
3772  value += 0.5 * (*(this->fe_interface->fe_face_values_neighbor))[extractor]
3773  .gradient(dof_pair[1], q_point);
3774 
3775  return value;
3776  }
3777 
3778 
3779 
3780  template <int dim, int spacedim>
3783  const unsigned int interface_dof_index,
3784  const unsigned int q_point) const
3785  {
3786  return average_of_gradients(interface_dof_index, q_point);
3787  }
3788 
3789 
3790 
3791  template <int dim, int spacedim>
3794  const unsigned int interface_dof_index,
3795  const unsigned int q_point) const
3796  {
3797  const auto dof_pair = this->fe_interface->dofmap[interface_dof_index];
3798 
3799  if (this->fe_interface->at_boundary())
3800  return (*(this->fe_interface->fe_face_values))[extractor].gradient(
3801  dof_pair[0], q_point);
3802 
3803  gradient_type value;
3804 
3805  if (dof_pair[0] != numbers::invalid_unsigned_int)
3806  value +=
3807  (*(this->fe_interface->fe_face_values))[extractor].gradient(dof_pair[0],
3808  q_point);
3809 
3810  if (dof_pair[1] != numbers::invalid_unsigned_int)
3811  value -=
3812  (*(this->fe_interface->fe_face_values_neighbor))[extractor].gradient(
3813  dof_pair[1], q_point);
3814 
3815  return value;
3816  }
3817 
3818 
3819 
3820  template <int dim, int spacedim>
3822  Vector<dim, spacedim>::jump_gradient(const unsigned int interface_dof_index,
3823  const unsigned int q_point) const
3824  {
3825  return jump_in_gradients(interface_dof_index, q_point);
3826  }
3827 
3828 
3829 
3830  template <int dim, int spacedim>
3833  const unsigned int interface_dof_index,
3834  const unsigned int q_point) const
3835  {
3836  const auto dof_pair = this->fe_interface->dofmap[interface_dof_index];
3837 
3838  if (this->fe_interface->at_boundary())
3839  return (*(this->fe_interface->fe_face_values))[extractor].hessian(
3840  dof_pair[0], q_point);
3841 
3842  hessian_type value;
3843 
3844  if (dof_pair[0] != numbers::invalid_unsigned_int)
3845  value +=
3846  0.5 *
3847  (*(this->fe_interface->fe_face_values))[extractor].hessian(dof_pair[0],
3848  q_point);
3849 
3850  if (dof_pair[1] != numbers::invalid_unsigned_int)
3851  value += 0.5 * (*(this->fe_interface->fe_face_values_neighbor))[extractor]
3852  .hessian(dof_pair[1], q_point);
3853 
3854  return value;
3855  }
3856 
3857 
3858 
3859  template <int dim, int spacedim>
3861  Vector<dim, spacedim>::average_hessian(const unsigned int interface_dof_index,
3862  const unsigned int q_point) const
3863  {
3864  return average_of_hessians(interface_dof_index, q_point);
3865  }
3866 
3867 
3868 
3869  template <int dim, int spacedim>
3872  const unsigned int interface_dof_index,
3873  const unsigned int q_point) const
3874  {
3875  const auto dof_pair = this->fe_interface->dofmap[interface_dof_index];
3876 
3877  if (this->fe_interface->at_boundary())
3878  return (*(this->fe_interface->fe_face_values))[extractor].hessian(
3879  dof_pair[0], q_point);
3880 
3881  hessian_type value;
3882 
3883  if (dof_pair[0] != numbers::invalid_unsigned_int)
3884  value +=
3885  (*(this->fe_interface->fe_face_values))[extractor].hessian(dof_pair[0],
3886  q_point);
3887 
3888  if (dof_pair[1] != numbers::invalid_unsigned_int)
3889  value -=
3890  (*(this->fe_interface->fe_face_values_neighbor))[extractor].hessian(
3891  dof_pair[1], q_point);
3892 
3893  return value;
3894  }
3895 
3896 
3897 
3898  template <int dim, int spacedim>
3900  Vector<dim, spacedim>::jump_hessian(const unsigned int interface_dof_index,
3901  const unsigned int q_point) const
3902  {
3903  return jump_in_hessians(interface_dof_index, q_point);
3904  }
3905 
3906 
3907 
3908  template <int dim, int spacedim>
3911  const unsigned int interface_dof_index,
3912  const unsigned int q_point) const
3913  {
3914  const auto dof_pair = this->fe_interface->dofmap[interface_dof_index];
3915 
3916  if (this->fe_interface->at_boundary())
3917  return (*(this->fe_interface->fe_face_values))[extractor]
3918  .third_derivative(dof_pair[0], q_point);
3919 
3920  third_derivative_type value;
3921 
3922  if (dof_pair[0] != numbers::invalid_unsigned_int)
3923  value +=
3924  (*(this->fe_interface->fe_face_values))[extractor].third_derivative(
3925  dof_pair[0], q_point);
3926 
3927  if (dof_pair[1] != numbers::invalid_unsigned_int)
3928  value -= (*(this->fe_interface->fe_face_values_neighbor))[extractor]
3929  .third_derivative(dof_pair[1], q_point);
3930 
3931  return value;
3932  }
3933 
3934 
3935 
3936  template <int dim, int spacedim>
3939  const unsigned int interface_dof_index,
3940  const unsigned int q_point) const
3941  {
3942  return jump_in_third_derivatives(interface_dof_index, q_point);
3943  }
3944 
3945 
3946 
3947  template <int dim, int spacedim>
3948  template <class InputVector>
3949  void
3951  const bool here_or_there,
3952  const InputVector &local_dof_values,
3953  std::vector<solution_value_type<typename InputVector::value_type>> &values)
3954  const
3955  {
3956  AssertDimension(values.size(), this->fe_interface->n_quadrature_points);
3957 
3958  for (const auto dof_index : this->fe_interface->dof_indices())
3959  for (const auto q_index : this->fe_interface->quadrature_point_indices())
3960  {
3961  if (dof_index == 0)
3962  values[q_index] = 0.;
3963 
3964  values[q_index] += local_dof_values[dof_index] *
3965  value(here_or_there, dof_index, q_index);
3966  }
3967  }
3968 
3969 
3970 
3971  template <int dim, int spacedim>
3972  template <class InputVector>
3973  void
3975  const bool here_or_there,
3976  const InputVector &fe_function,
3977  std::vector<solution_value_type<typename InputVector::value_type>> &values)
3978  const
3979  {
3980  std::vector<typename InputVector::value_type> local_dof_values(
3981  this->fe_interface->n_current_interface_dofs());
3982  this->get_local_dof_values(fe_function, local_dof_values);
3983 
3984  get_function_values_from_local_dof_values(here_or_there,
3985  local_dof_values,
3986  values);
3987  }
3988 
3989 
3990 
3991  template <int dim, int spacedim>
3992  template <class InputVector>
3993  void
3995  const InputVector &local_dof_values,
3996  std::vector<solution_value_type<typename InputVector::value_type>> &values)
3997  const
3998  {
3999  AssertDimension(values.size(), this->fe_interface->n_quadrature_points);
4000 
4001  for (const auto dof_index : this->fe_interface->dof_indices())
4002  for (const auto q_index : this->fe_interface->quadrature_point_indices())
4003  {
4004  if (dof_index == 0)
4005  values[q_index] = 0.;
4006 
4007  values[q_index] +=
4008  local_dof_values[dof_index] * jump_in_values(dof_index, q_index);
4009  }
4010  }
4011 
4012 
4013 
4014  template <int dim, int spacedim>
4015  template <class InputVector>
4016  void
4018  const InputVector &fe_function,
4019  std::vector<solution_value_type<typename InputVector::value_type>> &values)
4020  const
4021  {
4022  std::vector<typename InputVector::value_type> local_dof_values(
4023  this->fe_interface->n_current_interface_dofs());
4024  this->get_local_dof_values(fe_function, local_dof_values);
4025 
4026  get_jump_in_function_values_from_local_dof_values(local_dof_values, values);
4027  }
4028 
4029 
4030 
4031  template <int dim, int spacedim>
4032  template <class InputVector>
4033  void
4035  const InputVector &local_dof_values,
4036  std::vector<solution_gradient_type<typename InputVector::value_type>>
4037  &gradients) const
4038  {
4039  AssertDimension(gradients.size(), this->fe_interface->n_quadrature_points);
4040 
4041  for (const auto dof_index : this->fe_interface->dof_indices())
4042  for (const auto q_index : this->fe_interface->quadrature_point_indices())
4043  {
4044  if (dof_index == 0)
4045  gradients[q_index] = 0.;
4046 
4047  gradients[q_index] +=
4048  local_dof_values[dof_index] * jump_in_gradients(dof_index, q_index);
4049  }
4050  }
4051 
4052 
4053 
4054  template <int dim, int spacedim>
4055  template <class InputVector>
4056  void
4058  const InputVector &fe_function,
4059  std::vector<solution_gradient_type<typename InputVector::value_type>>
4060  &gradients) const
4061  {
4062  std::vector<typename InputVector::value_type> local_dof_values(
4063  this->fe_interface->n_current_interface_dofs());
4064  this->get_local_dof_values(fe_function, local_dof_values);
4065 
4066  get_jump_in_function_gradients_from_local_dof_values(local_dof_values,
4067  gradients);
4068  }
4069 
4070 
4071 
4072  template <int dim, int spacedim>
4073  template <class InputVector>
4074  void
4076  const InputVector &local_dof_values,
4077  std::vector<solution_value_type<typename InputVector::value_type>> &values)
4078  const
4079  {
4080  AssertDimension(values.size(), this->fe_interface->n_quadrature_points);
4081 
4082  for (const auto dof_index : this->fe_interface->dof_indices())
4083  for (const auto q_index : this->fe_interface->quadrature_point_indices())
4084  {
4085  if (dof_index == 0)
4086  values[q_index] = 0.;
4087 
4088  values[q_index] +=
4089  local_dof_values[dof_index] * average_of_values(dof_index, q_index);
4090  }
4091  }
4092 
4093 
4094 
4095  template <int dim, int spacedim>
4096  template <class InputVector>
4097  void
4099  const InputVector &fe_function,
4100  std::vector<solution_value_type<typename InputVector::value_type>> &values)
4101  const
4102  {
4103  std::vector<typename InputVector::value_type> local_dof_values(
4104  this->fe_interface->n_current_interface_dofs());
4105  this->get_local_dof_values(fe_function, local_dof_values);
4106 
4107  get_average_of_function_values_from_local_dof_values(local_dof_values,
4108  values);
4109  }
4110 
4111 
4112 
4113  template <int dim, int spacedim>
4114  template <class InputVector>
4115  void
4118  const InputVector &local_dof_values,
4119  std::vector<solution_gradient_type<typename InputVector::value_type>>
4120  &gradients) const
4121  {
4122  AssertDimension(gradients.size(), this->fe_interface->n_quadrature_points);
4123 
4124  for (const auto dof_index : this->fe_interface->dof_indices())
4125  for (const auto q_index : this->fe_interface->quadrature_point_indices())
4126  {
4127  if (dof_index == 0)
4128  gradients[q_index] = 0.;
4129 
4130  gradients[q_index] += local_dof_values[dof_index] *
4131  average_of_gradients(dof_index, q_index);
4132  }
4133  }
4134 
4135 
4136 
4137  template <int dim, int spacedim>
4138  template <class InputVector>
4139  void
4141  const InputVector &fe_function,
4142  std::vector<solution_gradient_type<typename InputVector::value_type>>
4143  &gradients) const
4144  {
4145  std::vector<typename InputVector::value_type> local_dof_values(
4146  this->fe_interface->n_current_interface_dofs());
4147  this->get_local_dof_values(fe_function, local_dof_values);
4148 
4149  get_average_of_function_gradients_from_local_dof_values(local_dof_values,
4150  gradients);
4151  }
4152 
4153 
4154 
4155  template <int dim, int spacedim>
4156  template <class InputVector>
4157  void
4159  const InputVector &local_dof_values,
4160  std::vector<solution_hessian_type<typename InputVector::value_type>>
4161  &hessians) const
4162  {
4163  AssertDimension(hessians.size(), this->fe_interface->n_quadrature_points);
4164 
4165  for (const auto dof_index : this->fe_interface->dof_indices())
4166  for (const auto q_index : this->fe_interface->quadrature_point_indices())
4167  {
4168  if (dof_index == 0)
4169  hessians[q_index] = 0.;
4170 
4171  hessians[q_index] +=
4172  local_dof_values[dof_index] * jump_in_hessians(dof_index, q_index);
4173  }
4174  }
4175 
4176 
4177 
4178  template <int dim, int spacedim>
4179  template <class InputVector>
4180  void
4182  const InputVector &fe_function,
4183  std::vector<solution_hessian_type<typename InputVector::value_type>>
4184  &hessians) const
4185  {
4186  std::vector<typename InputVector::value_type> local_dof_values(
4187  this->fe_interface->n_current_interface_dofs());
4188  this->get_local_dof_values(fe_function, local_dof_values);
4189 
4190  get_jump_in_function_hessians_from_local_dof_values(local_dof_values,
4191  hessians);
4192  }
4193 
4194 
4195 
4196  template <int dim, int spacedim>
4197  template <class InputVector>
4198  void
4200  const InputVector &local_dof_values,
4201  std::vector<solution_hessian_type<typename InputVector::value_type>>
4202  &hessians) const
4203  {
4204  AssertDimension(hessians.size(), this->fe_interface->n_quadrature_points);
4205 
4206  for (unsigned int dof_index : this->fe_interface->dof_indices())
4207  for (const auto q_index : this->fe_interface->quadrature_point_indices())
4208  {
4209  if (dof_index == 0)
4210  hessians[q_index] = 0.;
4211 
4212  hessians[q_index] += local_dof_values[dof_index] *
4213  average_of_hessians(dof_index, q_index);
4214  }
4215  }
4216 
4217 
4218 
4219  template <int dim, int spacedim>
4220  template <class InputVector>
4221  void
4223  const InputVector &fe_function,
4224  std::vector<solution_hessian_type<typename InputVector::value_type>>
4225  &hessians) const
4226  {
4227  std::vector<typename InputVector::value_type> local_dof_values(
4228  this->fe_interface->n_current_interface_dofs());
4229  this->get_local_dof_values(fe_function, local_dof_values);
4230 
4231  get_average_of_function_hessians_from_local_dof_values(local_dof_values,
4232  hessians);
4233  }
4234 
4235 
4236 
4237  template <int dim, int spacedim>
4238  template <class InputVector>
4239  void
4242  const InputVector &local_dof_values,
4243  std::vector<
4244  solution_third_derivative_type<typename InputVector::value_type>>
4245  &third_derivatives) const
4246  {
4247  AssertDimension(third_derivatives.size(),
4248  this->fe_interface->n_quadrature_points);
4249 
4250  for (unsigned int dof_index : this->fe_interface->dof_indices())
4251  for (const auto q_index : this->fe_interface->quadrature_point_indices())
4252  {
4253  if (dof_index == 0)
4254  third_derivatives[q_index] = 0.;
4255 
4256  third_derivatives[q_index] +=
4257  local_dof_values[dof_index] *
4258  jump_in_third_derivatives(dof_index, q_index);
4259  }
4260  }
4261 
4262 
4263 
4264  template <int dim, int spacedim>
4265  template <class InputVector>
4266  void
4268  const InputVector &fe_function,
4269  std::vector<
4270  solution_third_derivative_type<typename InputVector::value_type>>
4271  &third_derivatives) const
4272  {
4273  std::vector<typename InputVector::value_type> local_dof_values(
4274  this->fe_interface->n_current_interface_dofs());
4275  this->get_local_dof_values(fe_function, local_dof_values);
4276 
4277  get_jump_in_function_third_derivatives_from_local_dof_values(
4278  local_dof_values, third_derivatives);
4279  }
4280 } // namespace FEInterfaceViews
4281 
4282 #endif // DOXYGEN
4283 
4285 
4286 #endif
const std::vector< Tensor< 1, spacedim > > & get_normal_vectors() const
std::vector< types::global_dof_index > get_interface_dof_indices() const
UpdateFlags get_update_flags() 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< 1, spacedim > normal(const unsigned int q_point_index) const
FEFaceValuesBase< dim, spacedim > * fe_face_values_neighbor
Tensor< 2, spacedim > average_hessian(const unsigned int interface_dof_index, const unsigned int q_point, const unsigned int component=0) const
void get_jump_in_function_third_derivatives(const InputVector &fe_function, std::vector< Tensor< 3, spacedim, typename InputVector::value_type >> &third_derivatives) const
const FEInterfaceViews::Scalar< dim, spacedim > operator[](const FEValuesExtractors::Scalar &scalar) const
bool at_boundary() 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
FESubfaceValues< dim, spacedim > internal_fe_subface_values_neighbor
FEInterfaceValues(const Mapping< dim, spacedim > &mapping, const FiniteElement< dim, spacedim > &fe, const Quadrature< dim - 1 > &quadrature, const UpdateFlags update_flags)
const unsigned int n_quadrature_points
const Mapping< dim, spacedim > & get_mapping() const
Tensor< 1, spacedim > jump_gradient(const unsigned int interface_dof_index, const unsigned int q_point, const unsigned int component=0) const
std::array< unsigned int, 2 > interface_dof_to_dof_indices(const unsigned int interface_dof_index) const
unsigned n_current_interface_dofs() const
Tensor< 1, spacedim > average_gradient(const unsigned int interface_dof_index, const unsigned int q_point, const unsigned int component=0) const
double average_of_shape_values(const unsigned int interface_dof_index, const unsigned int q_point, const unsigned int component=0) const
double average(const unsigned int interface_dof_index, const unsigned int q_point, const unsigned int component=0) const
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
void get_jump_in_function_gradients(const InputVector &fe_function, std::vector< Tensor< 1, spacedim, typename InputVector::value_type >> &gradients) const
std_cxx20::ranges::iota_view< unsigned int, unsigned int > quadrature_point_indices() const
void get_average_of_function_hessians(const InputVector &fe_function, std::vector< Tensor< 2, spacedim, typename InputVector::value_type >> &hessians) const
const std::vector< Point< spacedim > > & get_quadrature_points() const
double jump(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
const Triangulation< dim, spacedim >::cell_iterator get_cell(const unsigned int cell_index) 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
std::vector< types::global_dof_index > interface_dof_indices
const std::vector< double > & get_JxW_values() const
const FEInterfaceViews::Vector< dim, spacedim > operator[](const FEValuesExtractors::Vector &vector) const
std::vector< std::array< unsigned int, 2 > > dofmap
double JxW(const unsigned int quadrature_point) const
FESubfaceValues< dim, spacedim > internal_fe_subface_values
void get_average_of_function_values(const InputVector &fe_function, std::vector< typename InputVector::value_type > &values) const
const Quadrature< dim - 1 > & get_quadrature() const
void reinit(const CellIteratorType &cell, const unsigned int face_no)
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)
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
void get_jump_in_function_hessians(const InputVector &fe_function, std::vector< Tensor< 2, spacedim, typename InputVector::value_type >> &hessians) const
FEInterfaceValues(const FiniteElement< dim, spacedim > &fe, const Quadrature< dim - 1 > &quadrature, const UpdateFlags update_flags)
Tensor< 3, spacedim > jump_3rd_derivative(const unsigned int interface_dof_index, const unsigned int q_point, const unsigned int component=0) const
Tensor< 2, spacedim > jump_hessian(const unsigned int interface_dof_index, const unsigned int q_point, const unsigned int component=0) const
const FiniteElement< dim, spacedim > & get_fe() 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
FEFaceValues< dim, spacedim > internal_fe_face_values
std_cxx20::ranges::iota_view< unsigned int, unsigned int > dof_indices() const
void get_jump_in_function_values(const InputVector &fe_function, std::vector< typename InputVector::value_type > &values) const
FEFaceValues< dim, spacedim > internal_fe_face_values_neighbor
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
void get_average_of_function_gradients(const InputVector &fe_function, std::vector< Tensor< 1, spacedim, typename InputVector::value_type >> &gradients) 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_average_of_function_hessians(const InputVector &fe_function, std::vector< solution_hessian_type< typename InputVector::value_type >> &hessians) const
gradient_type average_gradient(const unsigned int interface_dof_index, const unsigned int q_point) const
gradient_type jump_in_gradients(const unsigned int interface_dof_index, const unsigned int q_point) const
hessian_type jump_hessian(const unsigned int interface_dof_index, const unsigned int q_point) const
gradient_type jump_gradient(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(const InputVector &fe_function, std::vector< solution_value_type< typename InputVector::value_type >> &values) const
void get_average_of_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(const bool here_or_there, const InputVector &fe_function, std::vector< solution_value_type< typename InputVector::value_type >> &values) const
const FEValuesExtractors::Scalar extractor
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
value_type jump(const unsigned int interface_dof_index, const unsigned int q_point) const
typename FEValuesViews::Scalar< dim, spacedim >::gradient_type gradient_type
hessian_type average_of_hessians(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
value_type value(const bool here_or_there, const unsigned int interface_dof_index, const unsigned int q_point) const
value_type average(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
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
value_type average_value(const unsigned int interface_dof_index, const unsigned int q_point) const
hessian_type average_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, third_derivative_type >::type solution_third_derivative_type
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_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_gradients(const InputVector &fe_function, std::vector< solution_gradient_type< typename InputVector::value_type >> &gradients) const
Scalar(const FEInterfaceValues< dim, spacedim > &fe_interface, const unsigned int component)
void get_jump_in_function_hessians(const InputVector &fe_function, std::vector< solution_hessian_type< typename InputVector::value_type >> &hessians) const
typename FEValuesViews::Scalar< dim, spacedim >::hessian_type hessian_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
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
third_derivative_type jump_3rd_derivative(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_average_of_function_hessians_from_local_dof_values(const InputVector &local_dof_values, std::vector< solution_hessian_type< typename InputVector::value_type >> &hessians) const
value_type average_of_values(const unsigned int interface_dof_index, const unsigned int q_point) const
value_type jump_in_values(const unsigned int interface_dof_index, const unsigned int q_point) const
typename FEValuesViews::Scalar< dim, spacedim >::third_derivative_type third_derivative_type
typename ProductType< Number, hessian_type >::type solution_hessian_type
typename ProductType< Number, gradient_type >::type solution_gradient_type
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
const FEValuesExtractors::Vector extractor
void get_jump_in_function_hessians(const InputVector &fe_function, std::vector< solution_hessian_type< typename InputVector::value_type >> &hessians) const
void get_average_of_function_hessians(const InputVector &fe_function, std::vector< solution_hessian_type< typename InputVector::value_type >> &hessians) const
void get_jump_in_function_gradients(const InputVector &fe_function, 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
hessian_type average_hessian(const unsigned int interface_dof_index, const unsigned int q_point) const
value_type average(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_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_third_derivatives(const InputVector &fe_function, std::vector< solution_third_derivative_type< typename InputVector::value_type >> &third_derivatives) const
void get_average_of_function_values(const InputVector &fe_function, std::vector< solution_value_type< typename InputVector::value_type >> &values) const
typename ProductType< Number, gradient_type >::type solution_gradient_type
hessian_type jump_hessian(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
typename ProductType< Number, value_type >::type solution_value_type
typename FEValuesViews::Vector< dim, spacedim >::value_type value_type
value_type value(const bool here_or_there, const unsigned int interface_dof_index, const unsigned int q_point) const
third_derivative_type jump_in_third_derivatives(const unsigned int interface_dof_index, const unsigned int q_point) const
third_derivative_type jump_3rd_derivative(const unsigned int interface_dof_index, const unsigned int q_point) const
value_type jump_in_values(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
void get_average_of_function_gradients(const InputVector &fe_function, std::vector< solution_gradient_type< typename InputVector::value_type >> &gradients) const
value_type jump(const unsigned int interface_dof_index, const unsigned int q_point) const
typename ProductType< Number, hessian_type >::type solution_hessian_type
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
gradient_type jump_gradient(const unsigned int interface_dof_index, const unsigned int q_point) const
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_function_values(const bool here_or_there, const InputVector &fe_function, 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 ProductType< Number, third_derivative_type >::type solution_third_derivative_type
void get_jump_in_function_values(const InputVector &fe_function, std::vector< solution_value_type< typename InputVector::value_type >> &values) 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 FEValuesViews::Vector< dim, spacedim >::third_derivative_type third_derivative_type
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_average_of_function_gradients_from_local_dof_values(const InputVector &local_dof_values, std::vector< solution_gradient_type< typename InputVector::value_type >> &gradients) const
gradient_type average_gradient(const unsigned int interface_dof_index, const unsigned int q_point) const
hessian_type average_of_hessians(const unsigned int interface_dof_index, const unsigned int q_point) const
typename FEValuesViews::Vector< dim, spacedim >::hessian_type hessian_type
value_type value(const unsigned int shape_function, const unsigned int q_point) const
void get_function_values_from_local_dof_values(const InputVector &dof_values, std::vector< solution_value_type< typename InputVector::value_type >> &values) const
Definition: fe_values.cc:1578
void get_function_values(const InputVector &fe_function, std::vector< solution_value_type< typename InputVector::value_type >> &values) const
Definition: fe_values.cc:1547
::Tensor< 1, spacedim > gradient_type
Definition: fe_values.h:161
::Tensor< 2, spacedim > hessian_type
Definition: fe_values.h:168
::Tensor< 3, spacedim > third_derivative_type
Definition: fe_values.h:175
unsigned int n_components() const
Definition: vector.h:109
#define DEAL_II_DEPRECATED
Definition: config.h:164
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:442
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:443
UpdateFlags
unsigned int cell_index
Definition: grid_tools.cc:1132
#define Assert(cond, exc)
Definition: exceptions.h:1473
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1667
#define AssertIndexRange(index, range)
Definition: exceptions.h:1732
static ::ExceptionBase & ExcMessage(std::string arg1)
friend class Vector
Definition: vector.h:1035
const Mapping< dim, spacedim > & get_default_linear_mapping(const Triangulation< dim, spacedim > &triangulation)
Definition: mapping.cc:260
typename ::internal::FEInterfaceViews::ViewType< dim, spacedim, Extractor >::type View
void reference_cell(Triangulation< dim, spacedim > &tria, const ReferenceCell &reference_cell)
static const char U
static const unsigned int invalid_unsigned_int
Definition: types.h:201
boost::integer_range< IncrementableType > iota_view
Definition: iota_view.h:46
typename internal::ProductTypeImpl< typename std::decay< T >::type, typename std::decay< U >::type >::type type