Reference documentation for deal.II version GIT 35969cdc9b 2023-12-09 01:10:02+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_values_views.h
Go to the documentation of this file.
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1998 - 2023 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_values_views_h
17 #define dealii_fe_values_views_h
18 
19 #include <deal.II/base/config.h>
20 
22 #include <deal.II/base/lazy.h>
25 #include <deal.II/base/tensor.h>
26 
29 
31 
32 #include <type_traits>
33 #include <vector>
34 
36 
37 // Forward declaration
38 #ifndef DOXYGEN
39 template <int dim, int spacedim = dim>
40 class FEValuesBase;
41 #endif
42 
43 namespace internal
44 {
49  template <int dim, typename NumberType = double>
50  struct CurlType;
51 
58  template <typename NumberType>
59  struct CurlType<1, NumberType>
60  {
62  };
63 
70  template <typename NumberType>
71  struct CurlType<2, NumberType>
72  {
74  };
75 
82  template <typename NumberType>
83  struct CurlType<3, NumberType>
84  {
86  };
87 } // namespace internal
88 
89 
90 
112 namespace FEValuesViews
113 {
125  template <int dim, int spacedim = dim>
126  class Scalar
127  {
128  public:
135 
142 
149 
156 
163  template <typename Number>
165 
172  template <typename Number>
175 
182  template <typename Number>
185 
192  template <typename Number>
195 
202  template <typename Number>
205 
211  {
221 
230  unsigned int row_index;
231  };
232 
236  Scalar();
237 
243  Scalar(const FEValuesBase<dim, spacedim> &fe_values_base,
244  const unsigned int component);
245 
250  Scalar(const Scalar<dim, spacedim> &) = delete;
251 
255  // NOLINTNEXTLINE OSX does not compile with noexcept
257 
261  ~Scalar() = default;
262 
267  Scalar &
268  operator=(const Scalar<dim, spacedim> &) = delete;
269 
273  Scalar &
274  operator=(Scalar<dim, spacedim> &&) noexcept = default;
275 
289  value_type
290  value(const unsigned int shape_function, const unsigned int q_point) const;
291 
303  gradient(const unsigned int shape_function,
304  const unsigned int q_point) const;
305 
317  hessian(const unsigned int shape_function,
318  const unsigned int q_point) const;
319 
331  third_derivative(const unsigned int shape_function,
332  const unsigned int q_point) const;
333 
351  template <typename Number>
352  void
353  get_function_values(const ReadVector<Number> &fe_function,
354  std::vector<solution_value_type<Number>> &values) const;
355 
390  template <class InputVector>
391  void
393  const InputVector &dof_values,
394  std::vector<solution_value_type<typename InputVector::value_type>>
395  &values) const;
396 
414  template <typename Number>
415  void
417  const ReadVector<Number> &fe_function,
418  std::vector<solution_gradient_type<Number>> &gradients) const;
419 
426  template <class InputVector>
427  void
429  const InputVector &dof_values,
430  std::vector<solution_gradient_type<typename InputVector::value_type>>
431  &gradients) const;
432 
450  template <typename Number>
451  void
453  const ReadVector<Number> &fe_function,
454  std::vector<solution_hessian_type<Number>> &hessians) const;
455 
462  template <class InputVector>
463  void
465  const InputVector &dof_values,
466  std::vector<solution_hessian_type<typename InputVector::value_type>>
467  &hessians) const;
468 
469 
488  template <typename Number>
489  void
491  const ReadVector<Number> &fe_function,
492  std::vector<solution_laplacian_type<Number>> &laplacians) const;
493 
500  template <class InputVector>
501  void
503  const InputVector &dof_values,
504  std::vector<solution_laplacian_type<typename InputVector::value_type>>
505  &laplacians) const;
506 
507 
526  template <typename Number>
527  void
529  const ReadVector<Number> &fe_function,
530  std::vector<solution_third_derivative_type<Number>> &third_derivatives)
531  const;
532 
539  template <class InputVector>
540  void
542  const InputVector &dof_values,
543  std::vector<
544  solution_third_derivative_type<typename InputVector::value_type>>
545  &third_derivatives) const;
546 
547 
548  private:
552  SmartPointer<const FEValuesBase<dim, spacedim>> fe_values;
553 
558  unsigned int component;
559 
564  };
565 
566 
567 
597  template <int dim, int spacedim = dim>
598  class Vector
599  {
600  public:
607 
617 
629 
636 
643  using curl_type = typename ::internal::CurlType<spacedim>::type;
644 
651 
658 
665  template <typename Number>
667 
674  template <typename Number>
677 
684  template <typename Number>
687 
694  template <typename Number>
697 
704  template <typename Number>
707 
714  template <typename Number>
716 
723  template <typename Number>
726 
733  template <typename Number>
736 
742  {
752 
762  unsigned int row_index[spacedim];
763 
774  };
775 
779  Vector();
780 
789  Vector(const FEValuesBase<dim, spacedim> &fe_values_base,
790  const unsigned int first_vector_component);
791 
796  Vector(const Vector<dim, spacedim> &) = delete;
797 
801  // NOLINTNEXTLINE OSX does not compile with noexcept
803 
807  ~Vector() = default;
808 
813  Vector &
814  operator=(const Vector<dim, spacedim> &) = delete;
815 
819  // NOLINTNEXTLINE OSX does not compile with noexcept
820  Vector &
821  operator=(Vector<dim, spacedim> &&) = default; // NOLINT
822 
839  value_type
840  value(const unsigned int shape_function, const unsigned int q_point) const;
841 
856  gradient(const unsigned int shape_function,
857  const unsigned int q_point) const;
858 
875  symmetric_gradient(const unsigned int shape_function,
876  const unsigned int q_point) const;
877 
889  divergence(const unsigned int shape_function,
890  const unsigned int q_point) const;
891 
912  curl_type
913  curl(const unsigned int shape_function, const unsigned int q_point) const;
914 
926  hessian(const unsigned int shape_function,
927  const unsigned int q_point) const;
928 
940  third_derivative(const unsigned int shape_function,
941  const unsigned int q_point) const;
942 
960  template <typename Number>
961  void
962  get_function_values(const ReadVector<Number> &fe_function,
963  std::vector<solution_value_type<Number>> &values) const;
964 
999  template <class InputVector>
1000  void
1002  const InputVector &dof_values,
1004  &values) const;
1005 
1023  template <typename Number>
1024  void
1026  const ReadVector<Number> &fe_function,
1027  std::vector<solution_gradient_type<Number>> &gradients) const;
1028 
1035  template <class InputVector>
1036  void
1038  const InputVector &dof_values,
1040  &gradients) const;
1041 
1065  template <typename Number>
1066  void
1067  get_function_symmetric_gradients(
1068  const ReadVector<Number> &fe_function,
1070  &symmetric_gradients) const;
1071 
1078  template <class InputVector>
1079  void
1080  get_function_symmetric_gradients_from_local_dof_values(
1081  const InputVector &dof_values,
1082  std::vector<
1084  &symmetric_gradients) const;
1085 
1104  template <typename Number>
1105  void
1106  get_function_divergences(
1107  const ReadVector<Number> &fe_function,
1108  std::vector<solution_divergence_type<Number>> &divergences) const;
1109 
1116  template <class InputVector>
1117  void
1118  get_function_divergences_from_local_dof_values(
1119  const InputVector &dof_values,
1121  &divergences) const;
1122 
1141  template <typename Number>
1142  void
1143  get_function_curls(const ReadVector<Number> &fe_function,
1144  std::vector<solution_curl_type<Number>> &curls) const;
1145 
1152  template <class InputVector>
1153  void
1154  get_function_curls_from_local_dof_values(
1155  const InputVector &dof_values,
1157  const;
1158 
1176  template <typename Number>
1177  void
1179  const ReadVector<Number> &fe_function,
1180  std::vector<solution_hessian_type<Number>> &hessians) const;
1181 
1188  template <class InputVector>
1189  void
1191  const InputVector &dof_values,
1193  &hessians) const;
1194 
1213  template <typename Number>
1214  void
1216  const ReadVector<Number> &fe_function,
1217  std::vector<solution_laplacian_type<Number>> &laplacians) const;
1218 
1225  template <class InputVector>
1226  void
1228  const InputVector &dof_values,
1230  &laplacians) const;
1231 
1250  template <typename Number>
1251  void
1253  const ReadVector<Number> &fe_function,
1254  std::vector<solution_third_derivative_type<Number>> &third_derivatives)
1255  const;
1256 
1263  template <class InputVector>
1264  void
1266  const InputVector &dof_values,
1267  std::vector<
1269  &third_derivatives) const;
1270 
1271  private:
1276 
1282 
1286  std::vector<ShapeFunctionData> shape_function_data;
1287  };
1288 
1289 
1290  template <int rank, int dim, int spacedim = dim>
1292 
1315  template <int dim, int spacedim>
1316  class SymmetricTensor<2, dim, spacedim>
1317  {
1318  public:
1326 
1337 
1344  template <typename Number>
1346 
1353  template <typename Number>
1356 
1357 
1362  struct ShapeFunctionData
1363  {
1372  bool is_nonzero_shape_function_component
1373  [value_type::n_independent_components];
1374 
1384  unsigned int row_index[value_type::n_independent_components];
1385 
1395 
1400  };
1401 
1405  SymmetricTensor();
1406 
1416  SymmetricTensor(const FEValuesBase<dim, spacedim> &fe_values_base,
1417  const unsigned int first_tensor_component);
1418 
1424 
1428  // NOLINTNEXTLINE OSX does not compile with noexcept
1430 
1435  SymmetricTensor &
1437 
1441  SymmetricTensor &
1443 
1461  value_type
1462  value(const unsigned int shape_function, const unsigned int q_point) const;
1463 
1478  divergence(const unsigned int shape_function,
1479  const unsigned int q_point) const;
1480 
1498  template <typename Number>
1499  void
1500  get_function_values(const ReadVector<Number> &fe_function,
1501  std::vector<solution_value_type<Number>> &values) const;
1502 
1537  template <class InputVector>
1538  void
1540  const InputVector &dof_values,
1541  std::vector<solution_value_type<typename InputVector::value_type>>
1542  &values) const;
1543 
1565  template <typename Number>
1566  void
1567  get_function_divergences(
1568  const ReadVector<Number> &fe_function,
1569  std::vector<solution_divergence_type<Number>> &divergences) const;
1570 
1577  template <class InputVector>
1578  void
1579  get_function_divergences_from_local_dof_values(
1580  const InputVector &dof_values,
1581  std::vector<solution_divergence_type<typename InputVector::value_type>>
1582  &divergences) const;
1583 
1584  private:
1588  SmartPointer<const FEValuesBase<dim, spacedim>> fe_values;
1589 
1594  unsigned int first_tensor_component;
1595 
1599  std::vector<ShapeFunctionData> shape_function_data;
1600  };
1601 
1602 
1603  template <int rank, int dim, int spacedim = dim>
1604  class Tensor;
1605 
1624  template <int dim, int spacedim>
1625  class Tensor<2, dim, spacedim>
1626  {
1627  public:
1633 
1638 
1644 
1651  template <typename Number>
1653 
1660  template <typename Number>
1663 
1670  template <typename Number>
1673 
1674 
1679  struct ShapeFunctionData
1680  {
1689  bool is_nonzero_shape_function_component
1690  [value_type::n_independent_components];
1691 
1701  unsigned int row_index[value_type::n_independent_components];
1702 
1712 
1717  };
1718 
1722  Tensor();
1723 
1729 
1733  // NOLINTNEXTLINE OSX does not compile with noexcept
1735 
1739  ~Tensor() = default;
1740 
1750  Tensor(const FEValuesBase<dim, spacedim> &fe_values_base,
1751  const unsigned int first_tensor_component);
1752 
1753 
1758  Tensor &
1760 
1764  Tensor &
1765  operator=(Tensor<2, dim, spacedim> &&) = default; // NOLINT
1766 
1783  value_type
1784  value(const unsigned int shape_function, const unsigned int q_point) const;
1785 
1800  divergence(const unsigned int shape_function,
1801  const unsigned int q_point) const;
1802 
1817  gradient(const unsigned int shape_function,
1818  const unsigned int q_point) const;
1819 
1837  template <typename Number>
1838  void
1839  get_function_values(const ReadVector<Number> &fe_function,
1840  std::vector<solution_value_type<Number>> &values) const;
1841 
1876  template <class InputVector>
1877  void
1879  const InputVector &dof_values,
1881  &values) const;
1882 
1904  template <typename Number>
1905  void
1906  get_function_divergences(
1907  const ReadVector<Number> &fe_function,
1908  std::vector<solution_divergence_type<Number>> &divergences) const;
1909 
1916  template <class InputVector>
1917  void
1918  get_function_divergences_from_local_dof_values(
1919  const InputVector &dof_values,
1921  &divergences) const;
1922 
1939  template <typename Number>
1940  void
1942  const ReadVector<Number> &fe_function,
1943  std::vector<solution_gradient_type<Number>> &gradients) const;
1944 
1951  template <class InputVector>
1952  void
1954  const InputVector &dof_values,
1956  &gradients) const;
1957 
1958  private:
1963 
1969 
1973  std::vector<ShapeFunctionData> shape_function_data;
1974  };
1975 
1976 } // namespace FEValuesViews
1977 
1978 
1979 namespace internal
1980 {
1981  namespace FEValuesViews
1982  {
1987  template <int dim, int spacedim, typename Extractor>
1988  struct ViewType
1989  {};
1990 
1998  template <int dim, int spacedim>
1999  struct ViewType<dim, spacedim, FEValuesExtractors::Scalar>
2000  {
2001  using type = typename ::FEValuesViews::Scalar<dim, spacedim>;
2002  };
2003 
2011  template <int dim, int spacedim>
2012  struct ViewType<dim, spacedim, FEValuesExtractors::Vector>
2013  {
2014  using type = typename ::FEValuesViews::Vector<dim, spacedim>;
2015  };
2016 
2024  template <int dim, int spacedim, int rank>
2025  struct ViewType<dim, spacedim, FEValuesExtractors::Tensor<rank>>
2026  {
2027  using type = typename ::FEValuesViews::Tensor<rank, dim, spacedim>;
2028  };
2029 
2037  template <int dim, int spacedim, int rank>
2038  struct ViewType<dim, spacedim, FEValuesExtractors::SymmetricTensor<rank>>
2039  {
2040  using type =
2041  typename ::FEValuesViews::SymmetricTensor<rank, dim, spacedim>;
2042  };
2043 
2051  template <int dim, int spacedim>
2052  struct Cache
2053  {
2058  std::vector<Lazy<::FEValuesViews::Scalar<dim, spacedim>>> scalars;
2059  std::vector<Lazy<::FEValuesViews::Vector<dim, spacedim>>> vectors;
2060  std::vector<
2063  std::vector<Lazy<::FEValuesViews::Tensor<2, dim, spacedim>>>
2065 
2070  };
2071  } // namespace FEValuesViews
2072 } // namespace internal
2073 
2074 namespace FEValuesViews
2075 {
2080  template <int dim, int spacedim, typename Extractor>
2081  using View = typename ::internal::FEValuesViews::
2082  ViewType<dim, spacedim, Extractor>::type;
2083 } // namespace FEValuesViews
2084 
2085 #ifndef DOXYGEN
2086 
2087 /*---------------- Inline functions: namespace FEValuesViews -----------------*/
2088 
2089 namespace FEValuesViews
2090 {
2091  template <int dim, int spacedim>
2092  inline typename Scalar<dim, spacedim>::value_type
2093  Scalar<dim, spacedim>::value(const unsigned int shape_function,
2094  const unsigned int q_point) const
2095  {
2096  AssertIndexRange(shape_function, fe_values->fe->n_dofs_per_cell());
2097  Assert(
2098  fe_values->update_flags & update_values,
2100  "update_values"))));
2101 
2102  // an adaptation of the FEValuesBase::shape_value_component function
2103  // except that here we know the component as fixed and we have
2104  // pre-computed and cached a bunch of information. See the comments there.
2105  if (shape_function_data[shape_function].is_nonzero_shape_function_component)
2106  return fe_values->finite_element_output.shape_values(
2107  shape_function_data[shape_function].row_index, q_point);
2108  else
2109  return 0;
2110  }
2111 
2112 
2113 
2114  template <int dim, int spacedim>
2115  inline typename Scalar<dim, spacedim>::gradient_type
2116  Scalar<dim, spacedim>::gradient(const unsigned int shape_function,
2117  const unsigned int q_point) const
2118  {
2119  AssertIndexRange(shape_function, fe_values->fe->n_dofs_per_cell());
2120  Assert(fe_values->update_flags & update_gradients,
2122  "update_gradients")));
2123 
2124  // an adaptation of the FEValuesBase::shape_grad_component
2125  // function except that here we know the component as fixed and we have
2126  // pre-computed and cached a bunch of information. See the comments there.
2127  if (shape_function_data[shape_function].is_nonzero_shape_function_component)
2128  return fe_values->finite_element_output
2129  .shape_gradients[shape_function_data[shape_function].row_index]
2130  [q_point];
2131  else
2132  return gradient_type();
2133  }
2134 
2135 
2136 
2137  template <int dim, int spacedim>
2138  inline typename Scalar<dim, spacedim>::hessian_type
2139  Scalar<dim, spacedim>::hessian(const unsigned int shape_function,
2140  const unsigned int q_point) const
2141  {
2142  AssertIndexRange(shape_function, fe_values->fe->n_dofs_per_cell());
2143  Assert(fe_values->update_flags & update_hessians,
2145  "update_hessians")));
2146 
2147  // an adaptation of the FEValuesBase::shape_hessian_component
2148  // function except that here we know the component as fixed and we have
2149  // pre-computed and cached a bunch of information. See the comments there.
2150  if (shape_function_data[shape_function].is_nonzero_shape_function_component)
2151  return fe_values->finite_element_output
2152  .shape_hessians[shape_function_data[shape_function].row_index][q_point];
2153  else
2154  return hessian_type();
2155  }
2156 
2157 
2158 
2159  template <int dim, int spacedim>
2161  Scalar<dim, spacedim>::third_derivative(const unsigned int shape_function,
2162  const unsigned int q_point) const
2163  {
2164  AssertIndexRange(shape_function, fe_values->fe->n_dofs_per_cell());
2165  Assert(fe_values->update_flags & update_3rd_derivatives,
2167  "update_3rd_derivatives")));
2168 
2169  // an adaptation of the FEValuesBase::shape_3rdderivative_component
2170  // function except that here we know the component as fixed and we have
2171  // pre-computed and cached a bunch of information. See the comments there.
2172  if (shape_function_data[shape_function].is_nonzero_shape_function_component)
2173  return fe_values->finite_element_output
2174  .shape_3rd_derivatives[shape_function_data[shape_function].row_index]
2175  [q_point];
2176  else
2177  return third_derivative_type();
2178  }
2179 
2180 
2181 
2182  template <int dim, int spacedim>
2183  inline typename Vector<dim, spacedim>::value_type
2184  Vector<dim, spacedim>::value(const unsigned int shape_function,
2185  const unsigned int q_point) const
2186  {
2187  AssertIndexRange(shape_function, fe_values->fe->n_dofs_per_cell());
2188  Assert(fe_values->update_flags & update_values,
2190  "update_values")));
2191 
2192  // same as for the scalar case except that we have one more index
2193  const int snc =
2194  shape_function_data[shape_function].single_nonzero_component;
2195  if (snc == -2)
2196  return value_type();
2197  else if (snc != -1)
2198  {
2199  value_type return_value;
2200  return_value[shape_function_data[shape_function]
2201  .single_nonzero_component_index] =
2202  fe_values->finite_element_output.shape_values(snc, q_point);
2203  return return_value;
2204  }
2205  else
2206  {
2207  value_type return_value;
2208  for (unsigned int d = 0; d < dim; ++d)
2209  if (shape_function_data[shape_function]
2210  .is_nonzero_shape_function_component[d])
2211  return_value[d] = fe_values->finite_element_output.shape_values(
2212  shape_function_data[shape_function].row_index[d], q_point);
2213 
2214  return return_value;
2215  }
2216  }
2217 
2218 
2219 
2220  template <int dim, int spacedim>
2221  inline typename Vector<dim, spacedim>::gradient_type
2222  Vector<dim, spacedim>::gradient(const unsigned int shape_function,
2223  const unsigned int q_point) const
2224  {
2225  AssertIndexRange(shape_function, fe_values->fe->n_dofs_per_cell());
2226  Assert(fe_values->update_flags & update_gradients,
2228  "update_gradients")));
2229 
2230  // same as for the scalar case except that we have one more index
2231  const int snc =
2232  shape_function_data[shape_function].single_nonzero_component;
2233  if (snc == -2)
2234  return gradient_type();
2235  else if (snc != -1)
2236  {
2237  gradient_type return_value;
2238  return_value[shape_function_data[shape_function]
2239  .single_nonzero_component_index] =
2240  fe_values->finite_element_output.shape_gradients[snc][q_point];
2241  return return_value;
2242  }
2243  else
2244  {
2245  gradient_type return_value;
2246  for (unsigned int d = 0; d < dim; ++d)
2247  if (shape_function_data[shape_function]
2248  .is_nonzero_shape_function_component[d])
2249  return_value[d] =
2250  fe_values->finite_element_output.shape_gradients
2251  [shape_function_data[shape_function].row_index[d]][q_point];
2252 
2253  return return_value;
2254  }
2255  }
2256 
2257 
2258 
2259  template <int dim, int spacedim>
2261  Vector<dim, spacedim>::divergence(const unsigned int shape_function,
2262  const unsigned int q_point) const
2263  {
2264  // this function works like in the case above
2265  AssertIndexRange(shape_function, fe_values->fe->n_dofs_per_cell());
2266  Assert(fe_values->update_flags & update_gradients,
2268  "update_gradients")));
2269 
2270  // same as for the scalar case except that we have one more index
2271  const int snc =
2272  shape_function_data[shape_function].single_nonzero_component;
2273  if (snc == -2)
2274  return divergence_type();
2275  else if (snc != -1)
2276  return fe_values->finite_element_output
2277  .shape_gradients[snc][q_point][shape_function_data[shape_function]
2278  .single_nonzero_component_index];
2279  else
2280  {
2281  divergence_type return_value = 0;
2282  for (unsigned int d = 0; d < dim; ++d)
2283  if (shape_function_data[shape_function]
2284  .is_nonzero_shape_function_component[d])
2285  return_value +=
2286  fe_values->finite_element_output.shape_gradients
2287  [shape_function_data[shape_function].row_index[d]][q_point][d];
2288 
2289  return return_value;
2290  }
2291  }
2292 
2293 
2294 
2295  template <int dim, int spacedim>
2296  inline typename Vector<dim, spacedim>::curl_type
2297  Vector<dim, spacedim>::curl(const unsigned int shape_function,
2298  const unsigned int q_point) const
2299  {
2300  // this function works like in the case above
2301 
2302  AssertIndexRange(shape_function, fe_values->fe->n_dofs_per_cell());
2303  Assert(fe_values->update_flags & update_gradients,
2305  "update_gradients")));
2306  // same as for the scalar case except that we have one more index
2307  const int snc =
2308  shape_function_data[shape_function].single_nonzero_component;
2309 
2310  if (snc == -2)
2311  return curl_type();
2312 
2313  else
2314  switch (dim)
2315  {
2316  case 1:
2317  {
2318  Assert(false,
2319  ExcMessage(
2320  "Computing the curl in 1d is not a useful operation"));
2321  return curl_type();
2322  }
2323 
2324  case 2:
2325  {
2326  if (snc != -1)
2327  {
2328  curl_type return_value;
2329 
2330  // the single nonzero component can only be zero or one in 2d
2331  if (shape_function_data[shape_function]
2332  .single_nonzero_component_index == 0)
2333  return_value[0] =
2334  -1.0 * fe_values->finite_element_output
2335  .shape_gradients[snc][q_point][1];
2336  else
2337  return_value[0] = fe_values->finite_element_output
2338  .shape_gradients[snc][q_point][0];
2339 
2340  return return_value;
2341  }
2342 
2343  else
2344  {
2345  curl_type return_value;
2346 
2347  return_value[0] = 0.0;
2348 
2349  if (shape_function_data[shape_function]
2350  .is_nonzero_shape_function_component[0])
2351  return_value[0] -=
2352  fe_values->finite_element_output
2353  .shape_gradients[shape_function_data[shape_function]
2354  .row_index[0]][q_point][1];
2355 
2356  if (shape_function_data[shape_function]
2357  .is_nonzero_shape_function_component[1])
2358  return_value[0] +=
2359  fe_values->finite_element_output
2360  .shape_gradients[shape_function_data[shape_function]
2361  .row_index[1]][q_point][0];
2362 
2363  return return_value;
2364  }
2365  }
2366 
2367  case 3:
2368  {
2369  if (snc != -1)
2370  {
2371  curl_type return_value;
2372 
2373  switch (shape_function_data[shape_function]
2374  .single_nonzero_component_index)
2375  {
2376  case 0:
2377  {
2378  return_value[0] = 0;
2379  return_value[1] = fe_values->finite_element_output
2380  .shape_gradients[snc][q_point][2];
2381  return_value[2] =
2382  -1.0 * fe_values->finite_element_output
2383  .shape_gradients[snc][q_point][1];
2384  return return_value;
2385  }
2386 
2387  case 1:
2388  {
2389  return_value[0] =
2390  -1.0 * fe_values->finite_element_output
2391  .shape_gradients[snc][q_point][2];
2392  return_value[1] = 0;
2393  return_value[2] = fe_values->finite_element_output
2394  .shape_gradients[snc][q_point][0];
2395  return return_value;
2396  }
2397 
2398  default:
2399  {
2400  return_value[0] = fe_values->finite_element_output
2401  .shape_gradients[snc][q_point][1];
2402  return_value[1] =
2403  -1.0 * fe_values->finite_element_output
2404  .shape_gradients[snc][q_point][0];
2405  return_value[2] = 0;
2406  return return_value;
2407  }
2408  }
2409  }
2410 
2411  else
2412  {
2413  curl_type return_value;
2414 
2415  for (unsigned int i = 0; i < dim; ++i)
2416  return_value[i] = 0.0;
2417 
2418  if (shape_function_data[shape_function]
2419  .is_nonzero_shape_function_component[0])
2420  {
2421  return_value[1] +=
2422  fe_values->finite_element_output
2423  .shape_gradients[shape_function_data[shape_function]
2424  .row_index[0]][q_point][2];
2425  return_value[2] -=
2426  fe_values->finite_element_output
2427  .shape_gradients[shape_function_data[shape_function]
2428  .row_index[0]][q_point][1];
2429  }
2430 
2431  if (shape_function_data[shape_function]
2432  .is_nonzero_shape_function_component[1])
2433  {
2434  return_value[0] -=
2435  fe_values->finite_element_output
2436  .shape_gradients[shape_function_data[shape_function]
2437  .row_index[1]][q_point][2];
2438  return_value[2] +=
2439  fe_values->finite_element_output
2440  .shape_gradients[shape_function_data[shape_function]
2441  .row_index[1]][q_point][0];
2442  }
2443 
2444  if (shape_function_data[shape_function]
2445  .is_nonzero_shape_function_component[2])
2446  {
2447  return_value[0] +=
2448  fe_values->finite_element_output
2449  .shape_gradients[shape_function_data[shape_function]
2450  .row_index[2]][q_point][1];
2451  return_value[1] -=
2452  fe_values->finite_element_output
2453  .shape_gradients[shape_function_data[shape_function]
2454  .row_index[2]][q_point][0];
2455  }
2456 
2457  return return_value;
2458  }
2459  }
2460  }
2461  // should not end up here
2462  Assert(false, ExcInternalError());
2463  return curl_type();
2464  }
2465 
2466 
2467 
2468  template <int dim, int spacedim>
2469  inline typename Vector<dim, spacedim>::hessian_type
2470  Vector<dim, spacedim>::hessian(const unsigned int shape_function,
2471  const unsigned int q_point) const
2472  {
2473  // this function works like in the case above
2474  AssertIndexRange(shape_function, fe_values->fe->n_dofs_per_cell());
2475  Assert(fe_values->update_flags & update_hessians,
2477  "update_hessians")));
2478 
2479  // same as for the scalar case except that we have one more index
2480  const int snc =
2481  shape_function_data[shape_function].single_nonzero_component;
2482  if (snc == -2)
2483  return hessian_type();
2484  else if (snc != -1)
2485  {
2486  hessian_type return_value;
2487  return_value[shape_function_data[shape_function]
2488  .single_nonzero_component_index] =
2489  fe_values->finite_element_output.shape_hessians[snc][q_point];
2490  return return_value;
2491  }
2492  else
2493  {
2494  hessian_type return_value;
2495  for (unsigned int d = 0; d < dim; ++d)
2496  if (shape_function_data[shape_function]
2497  .is_nonzero_shape_function_component[d])
2498  return_value[d] =
2499  fe_values->finite_element_output.shape_hessians
2500  [shape_function_data[shape_function].row_index[d]][q_point];
2501 
2502  return return_value;
2503  }
2504  }
2505 
2506 
2507 
2508  template <int dim, int spacedim>
2510  Vector<dim, spacedim>::third_derivative(const unsigned int shape_function,
2511  const unsigned int q_point) const
2512  {
2513  // this function works like in the case above
2514  AssertIndexRange(shape_function, fe_values->fe->n_dofs_per_cell());
2515  Assert(fe_values->update_flags & update_3rd_derivatives,
2517  "update_3rd_derivatives")));
2518 
2519  // same as for the scalar case except that we have one more index
2520  const int snc =
2521  shape_function_data[shape_function].single_nonzero_component;
2522  if (snc == -2)
2523  return third_derivative_type();
2524  else if (snc != -1)
2525  {
2526  third_derivative_type return_value;
2527  return_value[shape_function_data[shape_function]
2528  .single_nonzero_component_index] =
2529  fe_values->finite_element_output.shape_3rd_derivatives[snc][q_point];
2530  return return_value;
2531  }
2532  else
2533  {
2534  third_derivative_type return_value;
2535  for (unsigned int d = 0; d < dim; ++d)
2536  if (shape_function_data[shape_function]
2537  .is_nonzero_shape_function_component[d])
2538  return_value[d] =
2539  fe_values->finite_element_output.shape_3rd_derivatives
2540  [shape_function_data[shape_function].row_index[d]][q_point];
2541 
2542  return return_value;
2543  }
2544  }
2545 
2546 
2547 
2548  namespace internal
2549  {
2554  inline ::SymmetricTensor<2, 1>
2555  symmetrize_single_row(const unsigned int n, const ::Tensor<1, 1> &t)
2556  {
2557  AssertIndexRange(n, 1);
2558  (void)n;
2559 
2560  return {{t[0]}};
2561  }
2562 
2563 
2564 
2565  inline ::SymmetricTensor<2, 2>
2566  symmetrize_single_row(const unsigned int n, const ::Tensor<1, 2> &t)
2567  {
2568  switch (n)
2569  {
2570  case 0:
2571  {
2572  return {{t[0], 0, t[1] / 2}};
2573  }
2574  case 1:
2575  {
2576  return {{0, t[1], t[0] / 2}};
2577  }
2578  default:
2579  {
2580  AssertIndexRange(n, 2);
2581  return {};
2582  }
2583  }
2584  }
2585 
2586 
2587 
2588  inline ::SymmetricTensor<2, 3>
2589  symmetrize_single_row(const unsigned int n, const ::Tensor<1, 3> &t)
2590  {
2591  switch (n)
2592  {
2593  case 0:
2594  {
2595  return {{t[0], 0, 0, t[1] / 2, t[2] / 2, 0}};
2596  }
2597  case 1:
2598  {
2599  return {{0, t[1], 0, t[0] / 2, 0, t[2] / 2}};
2600  }
2601  case 2:
2602  {
2603  return {{0, 0, t[2], 0, t[0] / 2, t[1] / 2}};
2604  }
2605  default:
2606  {
2607  AssertIndexRange(n, 3);
2608  return {};
2609  }
2610  }
2611  }
2612  } // namespace internal
2613 
2614 
2615 
2616  template <int dim, int spacedim>
2618  Vector<dim, spacedim>::symmetric_gradient(const unsigned int shape_function,
2619  const unsigned int q_point) const
2620  {
2621  AssertIndexRange(shape_function, fe_values->fe->n_dofs_per_cell());
2622  Assert(fe_values->update_flags & update_gradients,
2624  "update_gradients")));
2625 
2626  // same as for the scalar case except that we have one more index
2627  const int snc =
2628  shape_function_data[shape_function].single_nonzero_component;
2629  if (snc == -2)
2630  return symmetric_gradient_type();
2631  else if (snc != -1)
2632  return internal::symmetrize_single_row(
2633  shape_function_data[shape_function].single_nonzero_component_index,
2634  fe_values->finite_element_output.shape_gradients[snc][q_point]);
2635  else
2636  {
2637  gradient_type return_value;
2638  for (unsigned int d = 0; d < dim; ++d)
2639  if (shape_function_data[shape_function]
2640  .is_nonzero_shape_function_component[d])
2641  return_value[d] =
2642  fe_values->finite_element_output.shape_gradients
2643  [shape_function_data[shape_function].row_index[d]][q_point];
2644 
2645  return symmetrize(return_value);
2646  }
2647  }
2648 
2649 
2650 
2651  template <int dim, int spacedim>
2653  SymmetricTensor<2, dim, spacedim>::value(const unsigned int shape_function,
2654  const unsigned int q_point) const
2655  {
2656  AssertIndexRange(shape_function, fe_values->fe->n_dofs_per_cell());
2657  Assert(fe_values->update_flags & update_values,
2659  "update_values")));
2660 
2661  // similar to the vector case where we have more then one index and we need
2662  // to convert between unrolled and component indexing for tensors
2663  const int snc =
2664  shape_function_data[shape_function].single_nonzero_component;
2665 
2666  if (snc == -2)
2667  {
2668  // shape function is zero for the selected components
2669  return value_type();
2670  }
2671  else if (snc != -1)
2672  {
2673  value_type return_value;
2674  const unsigned int comp =
2675  shape_function_data[shape_function].single_nonzero_component_index;
2676  return_value[value_type::unrolled_to_component_indices(comp)] =
2677  fe_values->finite_element_output.shape_values(snc, q_point);
2678  return return_value;
2679  }
2680  else
2681  {
2682  value_type return_value;
2683  for (unsigned int d = 0; d < value_type::n_independent_components; ++d)
2684  if (shape_function_data[shape_function]
2685  .is_nonzero_shape_function_component[d])
2686  return_value[value_type::unrolled_to_component_indices(d)] =
2687  fe_values->finite_element_output.shape_values(
2688  shape_function_data[shape_function].row_index[d], q_point);
2689  return return_value;
2690  }
2691  }
2692 
2693 
2694 
2695  template <int dim, int spacedim>
2698  const unsigned int shape_function,
2699  const unsigned int q_point) const
2700  {
2701  AssertIndexRange(shape_function, fe_values->fe->n_dofs_per_cell());
2702  Assert(fe_values->update_flags & update_gradients,
2704  "update_gradients")));
2705 
2706  const int snc =
2707  shape_function_data[shape_function].single_nonzero_component;
2708 
2709  if (snc == -2)
2710  {
2711  // shape function is zero for the selected components
2712  return divergence_type();
2713  }
2714  else if (snc != -1)
2715  {
2716  // we have a single non-zero component when the symmetric tensor is
2717  // represented in unrolled form. this implies we potentially have
2718  // two non-zero components when represented in component form! we
2719  // will only have one non-zero entry if the non-zero component lies on
2720  // the diagonal of the tensor.
2721  //
2722  // the divergence of a second-order tensor is a first order tensor.
2723  //
2724  // assume the second-order tensor is A with components A_{ij}. then
2725  // A_{ij} = A_{ji} and there is only one (if diagonal) or two non-zero
2726  // entries in the tensorial representation. define the
2727  // divergence as:
2728  // b_i \dealcoloneq \dfrac{\partial phi_{ij}}{\partial x_j}.
2729  // (which is incidentally also
2730  // b_j \dealcoloneq \dfrac{\partial phi_{ij}}{\partial x_i}).
2731  // In both cases, a sum is implied.
2732  //
2733  // Now, we know the nonzero component in unrolled form: it is indicated
2734  // by 'snc'. we can figure out which tensor components belong to this:
2735  const unsigned int comp =
2736  shape_function_data[shape_function].single_nonzero_component_index;
2737  const unsigned int ii =
2738  value_type::unrolled_to_component_indices(comp)[0];
2739  const unsigned int jj =
2740  value_type::unrolled_to_component_indices(comp)[1];
2741 
2742  // given the form of the divergence above, if ii=jj there is only a
2743  // single nonzero component of the full tensor and the gradient
2744  // equals
2745  // b_ii \dealcoloneq \dfrac{\partial phi_{ii,ii}}{\partial x_ii}.
2746  // all other entries of 'b' are zero
2747  //
2748  // on the other hand, if ii!=jj, then there are two nonzero entries in
2749  // the full tensor and
2750  // b_ii \dealcoloneq \dfrac{\partial phi_{ii,jj}}{\partial x_ii}.
2751  // b_jj \dealcoloneq \dfrac{\partial phi_{ii,jj}}{\partial x_jj}.
2752  // again, all other entries of 'b' are zero
2753  const ::Tensor<1, spacedim> &phi_grad =
2754  fe_values->finite_element_output.shape_gradients[snc][q_point];
2755 
2756  divergence_type return_value;
2757  return_value[ii] = phi_grad[jj];
2758 
2759  if (ii != jj)
2760  return_value[jj] = phi_grad[ii];
2761 
2762  return return_value;
2763  }
2764  else
2765  {
2766  Assert(false, ExcNotImplemented());
2767  divergence_type return_value;
2768  return return_value;
2769  }
2770  }
2771 
2772 
2773 
2774  template <int dim, int spacedim>
2775  inline typename Tensor<2, dim, spacedim>::value_type
2776  Tensor<2, dim, spacedim>::value(const unsigned int shape_function,
2777  const unsigned int q_point) const
2778  {
2779  AssertIndexRange(shape_function, fe_values->fe->n_dofs_per_cell());
2780  Assert(fe_values->update_flags & update_values,
2782  "update_values")));
2783 
2784  // similar to the vector case where we have more then one index and we need
2785  // to convert between unrolled and component indexing for tensors
2786  const int snc =
2787  shape_function_data[shape_function].single_nonzero_component;
2788 
2789  if (snc == -2)
2790  {
2791  // shape function is zero for the selected components
2792  return value_type();
2793  }
2794  else if (snc != -1)
2795  {
2796  value_type return_value;
2797  const unsigned int comp =
2798  shape_function_data[shape_function].single_nonzero_component_index;
2799  const TableIndices<2> indices =
2801  return_value[indices] =
2802  fe_values->finite_element_output.shape_values(snc, q_point);
2803  return return_value;
2804  }
2805  else
2806  {
2807  value_type return_value;
2808  for (unsigned int d = 0; d < dim * dim; ++d)
2809  if (shape_function_data[shape_function]
2810  .is_nonzero_shape_function_component[d])
2811  {
2812  const TableIndices<2> indices =
2814  return_value[indices] =
2815  fe_values->finite_element_output.shape_values(
2816  shape_function_data[shape_function].row_index[d], q_point);
2817  }
2818  return return_value;
2819  }
2820  }
2821 
2822 
2823 
2824  template <int dim, int spacedim>
2826  Tensor<2, dim, spacedim>::divergence(const unsigned int shape_function,
2827  const unsigned int q_point) const
2828  {
2829  AssertIndexRange(shape_function, fe_values->fe->n_dofs_per_cell());
2830  Assert(fe_values->update_flags & update_gradients,
2832  "update_gradients")));
2833 
2834  const int snc =
2835  shape_function_data[shape_function].single_nonzero_component;
2836 
2837  if (snc == -2)
2838  {
2839  // shape function is zero for the selected components
2840  return divergence_type();
2841  }
2842  else if (snc != -1)
2843  {
2844  // we have a single non-zero component when the tensor is
2845  // represented in unrolled form.
2846  //
2847  // the divergence of a second-order tensor is a first order tensor.
2848  //
2849  // assume the second-order tensor is A with components A_{ij},
2850  // then divergence is d_i := \frac{\partial A_{ij}}{\partial x_j}
2851  //
2852  // Now, we know the nonzero component in unrolled form: it is indicated
2853  // by 'snc'. we can figure out which tensor components belong to this:
2854  const unsigned int comp =
2855  shape_function_data[shape_function].single_nonzero_component_index;
2856  const TableIndices<2> indices =
2858  const unsigned int ii = indices[0];
2859  const unsigned int jj = indices[1];
2860 
2861  const ::Tensor<1, spacedim> &phi_grad =
2862  fe_values->finite_element_output.shape_gradients[snc][q_point];
2863 
2864  divergence_type return_value;
2865  // note that we contract \nabla from the right
2866  return_value[ii] = phi_grad[jj];
2867 
2868  return return_value;
2869  }
2870  else
2871  {
2872  Assert(false, ExcNotImplemented());
2873  divergence_type return_value;
2874  return return_value;
2875  }
2876  }
2877 
2878 
2879 
2880  template <int dim, int spacedim>
2882  Tensor<2, dim, spacedim>::gradient(const unsigned int shape_function,
2883  const unsigned int q_point) const
2884  {
2885  AssertIndexRange(shape_function, fe_values->fe->n_dofs_per_cell());
2886  Assert(fe_values->update_flags & update_gradients,
2888  "update_gradients")));
2889 
2890  const int snc =
2891  shape_function_data[shape_function].single_nonzero_component;
2892 
2893  if (snc == -2)
2894  {
2895  // shape function is zero for the selected components
2896  return gradient_type();
2897  }
2898  else if (snc != -1)
2899  {
2900  // we have a single non-zero component when the tensor is
2901  // represented in unrolled form.
2902  //
2903  // the gradient of a second-order tensor is a third order tensor.
2904  //
2905  // assume the second-order tensor is A with components A_{ij},
2906  // then gradient is B_{ijk} := \frac{\partial A_{ij}}{\partial x_k}
2907  //
2908  // Now, we know the nonzero component in unrolled form: it is indicated
2909  // by 'snc'. we can figure out which tensor components belong to this:
2910  const unsigned int comp =
2911  shape_function_data[shape_function].single_nonzero_component_index;
2912  const TableIndices<2> indices =
2914  const unsigned int ii = indices[0];
2915  const unsigned int jj = indices[1];
2916 
2917  const ::Tensor<1, spacedim> &phi_grad =
2918  fe_values->finite_element_output.shape_gradients[snc][q_point];
2919 
2920  gradient_type return_value;
2921  return_value[ii][jj] = phi_grad;
2922 
2923  return return_value;
2924  }
2925  else
2926  {
2927  Assert(false, ExcNotImplemented());
2928  gradient_type return_value;
2929  return return_value;
2930  }
2931  }
2932 } // namespace FEValuesViews
2933 
2934 #endif
2935 
2937 
2938 #endif
typename ProductType< Number, hessian_type >::type solution_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
void get_function_gradients_from_local_dof_values(const InputVector &dof_values, std::vector< solution_gradient_type< typename InputVector::value_type >> &gradients) const
gradient_type gradient(const unsigned int shape_function, const unsigned int q_point) const
std::vector< ShapeFunctionData > shape_function_data
::Tensor< 1, spacedim > gradient_type
typename ProductType< Number, value_type >::type solution_laplacian_type
void get_function_third_derivatives(const ReadVector< Number > &fe_function, std::vector< solution_third_derivative_type< Number >> &third_derivatives) const
third_derivative_type third_derivative(const unsigned int shape_function, const unsigned int q_point) const
void get_function_gradients(const ReadVector< Number > &fe_function, std::vector< solution_gradient_type< Number >> &gradients) const
typename ProductType< Number, third_derivative_type >::type solution_third_derivative_type
typename ProductType< Number, value_type >::type solution_value_type
::Tensor< 2, spacedim > hessian_type
typename ProductType< Number, gradient_type >::type solution_gradient_type
void get_function_laplacians(const ReadVector< Number > &fe_function, std::vector< solution_laplacian_type< Number >> &laplacians) const
void get_function_hessians_from_local_dof_values(const InputVector &dof_values, std::vector< solution_hessian_type< typename InputVector::value_type >> &hessians) const
Scalar & operator=(const Scalar< dim, spacedim > &)=delete
SmartPointer< const FEValuesBase< dim, spacedim > > fe_values
void get_function_values(const ReadVector< Number > &fe_function, std::vector< solution_value_type< Number >> &values) const
Scalar(Scalar< dim, spacedim > &&)=default
void get_function_hessians(const ReadVector< Number > &fe_function, std::vector< solution_hessian_type< Number >> &hessians) const
void get_function_laplacians_from_local_dof_values(const InputVector &dof_values, std::vector< solution_laplacian_type< typename InputVector::value_type >> &laplacians) const
Scalar(const Scalar< dim, spacedim > &)=delete
hessian_type hessian(const unsigned int shape_function, const unsigned int q_point) const
Scalar & operator=(Scalar< dim, spacedim > &&) noexcept=default
void get_function_third_derivatives_from_local_dof_values(const InputVector &dof_values, std::vector< solution_third_derivative_type< typename InputVector::value_type >> &third_derivatives) const
::Tensor< 3, spacedim > third_derivative_type
SymmetricTensor(const SymmetricTensor< 2, dim, spacedim > &)=delete
SymmetricTensor(SymmetricTensor< 2, dim, spacedim > &&)=default
SymmetricTensor & operator=(const SymmetricTensor< 2, dim, spacedim > &)=delete
SymmetricTensor & operator=(SymmetricTensor< 2, dim, spacedim > &&) noexcept=default
typename ProductType< Number, value_type >::type solution_value_type
typename ProductType< Number, divergence_type >::type solution_divergence_type
typename ProductType< Number, value_type >::type solution_value_type
typename ProductType< Number, divergence_type >::type solution_divergence_type
typename ProductType< Number, gradient_type >::type solution_gradient_type
divergence_type divergence(const unsigned int shape_function, const unsigned int q_point) const
Tensor(const Tensor< 2, dim, spacedim > &)=delete
SmartPointer< const FEValuesBase< dim, spacedim > > fe_values
value_type value(const unsigned int shape_function, const unsigned int q_point) const
gradient_type gradient(const unsigned int shape_function, const unsigned int q_point) const
Tensor(Tensor< 2, dim, spacedim > &&)=default
std::vector< ShapeFunctionData > shape_function_data
Tensor & operator=(const Tensor< 2, dim, spacedim > &)=delete
Tensor & operator=(Tensor< 2, dim, spacedim > &&)=default
Vector & operator=(Vector< dim, spacedim > &&)=default
typename ProductType< Number, third_derivative_type >::type solution_third_derivative_type
typename ProductType< Number, divergence_type >::type solution_divergence_type
Vector(const Vector< dim, spacedim > &)=delete
unsigned int first_vector_component
hessian_type hessian(const unsigned int shape_function, const unsigned int q_point) const
typename ProductType< Number, hessian_type >::type solution_hessian_type
Vector & operator=(const Vector< dim, spacedim > &)=delete
typename ProductType< Number, symmetric_gradient_type >::type solution_symmetric_gradient_type
gradient_type gradient(const unsigned int shape_function, const unsigned int q_point) const
divergence_type divergence(const unsigned int shape_function, const unsigned int q_point) const
third_derivative_type third_derivative(const unsigned int shape_function, const unsigned int q_point) const
typename ProductType< Number, gradient_type >::type solution_gradient_type
typename ProductType< Number, value_type >::type solution_value_type
symmetric_gradient_type symmetric_gradient(const unsigned int shape_function, const unsigned int q_point) const
Vector(Vector< dim, spacedim > &&)=default
typename ::internal::CurlType< spacedim >::type curl_type
typename ProductType< Number, curl_type >::type solution_curl_type
std::vector< ShapeFunctionData > shape_function_data
value_type value(const unsigned int shape_function, const unsigned int q_point) const
curl_type curl(const unsigned int shape_function, const unsigned int q_point) const
typename ProductType< Number, value_type >::type solution_laplacian_type
SmartPointer< const FEValuesBase< dim, spacedim > > fe_values
Definition: lazy.h:87
Definition: tensor.h:516
static constexpr TableIndices< rank_ > unrolled_to_component_indices(const unsigned int i)
typename Tensor< rank_ - 1, dim, Number >::tensor_type value_type
Definition: tensor.h:549
Definition: vector.h:110
Number value_type
Definition: vector.h:129
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:477
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:478
static ::ExceptionBase & ExcInternalError()
#define Assert(cond, exc)
Definition: exceptions.h:1631
static ::ExceptionBase & ExcNotImplemented()
#define AssertIndexRange(index, range)
Definition: exceptions.h:1888
static ::ExceptionBase & ExcMessage(std::string arg1)
@ update_hessians
Second derivatives of shape functions.
@ update_values
Shape function values.
@ update_3rd_derivatives
Third derivatives of shape functions.
@ update_gradients
Shape function gradients.
typename ::internal::FEValuesViews::ViewType< dim, spacedim, Extractor >::type View
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
typename internal::ProductTypeImpl< std::decay_t< T >, std::decay_t< U > >::type type
std::vector< Lazy<::FEValuesViews::Vector< dim, spacedim > > > vectors
std::vector< Lazy<::FEValuesViews::SymmetricTensor< 2, dim, spacedim > > > symmetric_second_order_tensors
std::vector< Lazy<::FEValuesViews::Tensor< 2, dim, spacedim > > > second_order_tensors
std::vector< Lazy<::FEValuesViews::Scalar< dim, spacedim > > > scalars
constexpr DEAL_II_HOST SymmetricTensor< 2, dim, Number > symmetrize(const Tensor< 2, dim, Number > &t)