15#ifndef dealii_symmetric_tensor_h
16#define dealii_symmetric_tensor_h
33template <
int rank,
int dim,
typename Number =
double>
47template <
int dim,
typename Number =
double>
80template <
int dim,
typename Number =
double>
122template <
int dim,
typename Number =
double>
127template <
int dim,
typename Number>
131template <
int dim,
typename Number>
144template <
int dim2,
typename Number>
158template <
int dim,
typename Number>
176template <
int dim,
typename Number>
188 template <
int rank,
int dim,
typename T,
typename U>
194 std::complex<typename ProductType<T, U>::type>>;
197 template <
int rank,
int dim,
typename T,
typename U>
204 std::complex<typename ProductType<T, U>::type>>;
207 template <
typename T,
int rank,
int dim,
typename U>
213 std::complex<typename ProductType<T, U>::type>>;
216 template <
int rank,
int dim,
typename T,
typename U>
223 std::complex<typename ProductType<T, U>::type>>;
231 namespace SymmetricTensorImplementation
237 template <
int rank,
int dim,
typename Number>
245 namespace SymmetricTensorAccessors
256 const unsigned int new_index,
257 const unsigned int position)
264 return {previous_indices[0], new_index};
278 const unsigned int new_index,
279 const unsigned int position)
291 return {previous_indices[0],
296 return {previous_indices[0],
301 return {previous_indices[0],
322 typename OtherNumber = Number>
337 template <
int dim,
typename Number,
typename OtherNumber>
357 template <
int rank,
int dim,
typename Number>
363 template <
int dim,
typename Number>
370 static const unsigned int n_independent_components =
371 (dim * dim + dim) / 2;
384 template <
int dim,
typename Number>
392 static const unsigned int n_rank2_components = (dim * dim + dim) / 2;
397 static const unsigned int n_independent_components =
398 (n_rank2_components *
416 template <
int rank,
int dim,
bool constness,
typename Number>
425 template <
int rank,
int dim,
typename Number>
439 template <
int rank,
int dim,
typename Number>
480 template <
int rank,
int dim,
bool constness,
int P,
typename Number>
527 constexpr Accessor<rank, dim, constness, P - 1, Number>
534 constexpr Accessor<rank, dim, constness, P - 1, Number>
546 template <
int,
int,
typename>
547 friend class ::SymmetricTensor;
548 template <
int,
int,
bool,
int,
typename>
550 friend class ::SymmetricTensor<rank, dim, Number>;
551 friend class Accessor<rank, dim, constness, P + 1, Number>;
563 template <
int rank,
int dim,
bool constness,
typename Number>
632 template <
int,
int,
typename>
633 friend class ::SymmetricTensor;
634 template <
int,
int,
bool,
int,
typename>
636 friend class ::SymmetricTensor<rank, dim, Number>;
637 friend class SymmetricTensorAccessors::
638 Accessor<rank, dim, constness, 2, Number>;
717template <int rank_, int dim, typename Number>
721 static_assert(rank_ % 2 == 0,
"A SymmetricTensor must have even rank!");
731 static constexpr unsigned int dimension = dim;
736 static const unsigned int rank = rank_;
743 static constexpr unsigned int n_independent_components =
745 n_independent_components;
767 template <
typename OtherNumber>
793 template <
typename OtherNumber>
803 template <
typename OtherNumber>
841 template <
typename OtherNumber>
848 template <
typename OtherNumber>
856 template <
typename OtherNumber>
863 template <
typename OtherNumber>
926 template <
typename OtherNumber>
928 double_contraction_result<rank_, 2, dim, Number, OtherNumber>::type
935 template <
typename OtherNumber>
937 double_contraction_result<rank_, 4, dim, Number, OtherNumber>::type
951 constexpr const Number &
959 constexpr internal::SymmetricTensorAccessors::
960 Accessor<rank_, dim,
true, rank_ - 1, Number>
968 constexpr internal::SymmetricTensorAccessors::
969 Accessor<rank_, dim,
false, rank_ - 1, Number>
978 constexpr const Number &
997 constexpr const Number &
1069 template <
class Archive>
1093 template <
int,
int,
typename>
1097 template <
int dim2,
typename Number2>
1101 template <
int dim2,
typename Number2>
1105 template <
int dim2,
typename Number2>
1109 template <
int dim2,
typename Number2>
1113 template <
int dim2,
typename Number2>
1117 template <
int dim2,
typename Number2>
1124 Inverse<2, dim, Number>;
1127 Inverse<4, dim, Number>;
1138template <int rank, int dim, typename Number>
1141template <int rank_, int dim, typename Number>
1142constexpr unsigned
int
1147 namespace SymmetricTensorAccessors
1149 template <
int rank_,
int dim,
bool constness,
int P,
typename Number>
1151 Accessor<rank_, dim, constness, P, Number>::Accessor(
1152 tensor_type &tensor,
1155 , previous_indices(previous_indices)
1160 template <
int rank_,
int dim,
bool constness,
int P,
typename Number>
1162 Accessor<rank_, dim, constness, P - 1, Number>
1163 Accessor<rank_, dim, constness, P, Number>::operator[](
1164 const unsigned int i)
1166 return Accessor<rank_, dim, constness, P - 1, Number>(
1167 tensor, merge(previous_indices, i, rank_ - P));
1172 template <
int rank_,
int dim,
bool constness,
int P,
typename Number>
1174 Accessor<rank_, dim, constness, P - 1, Number>
1175 Accessor<rank_, dim, constness, P, Number>::operator[](
1176 const unsigned int i)
const
1178 return Accessor<rank_, dim, constness, P - 1, Number>(
1179 tensor,
merge(previous_indices, i, rank_ - P));
1184 template <
int rank_,
int dim,
bool constness,
typename Number>
1186 Accessor<rank_, dim, constness, 1, Number>::Accessor(
1187 tensor_type &tensor,
1190 , previous_indices(previous_indices)
1195 template <
int rank_,
int dim,
bool constness,
typename Number>
1197 typename Accessor<rank_, dim, constness, 1, Number>::reference
1198 Accessor<rank_, dim, constness, 1, Number>::operator[](
1199 const unsigned int i)
1201 return tensor(
merge(previous_indices, i, rank_ - 1));
1205 template <
int rank_,
int dim,
bool constness,
typename Number>
1207 typename Accessor<rank_, dim, constness, 1, Number>::reference
1208 Accessor<rank_, dim, constness, 1, Number>::operator[](
1209 const unsigned int i)
const
1211 return tensor(
merge(previous_indices, i, rank_ - 1));
1218template <
int rank_,
int dim,
typename Number>
1219template <
typename OtherNumber>
1224 static_assert(rank == 2,
"This function is only implemented for rank==2");
1225 for (
unsigned int d = 0;
d < dim; ++
d)
1226 for (
unsigned int e = 0;
e <
d; ++
e)
1227 Assert(t[d][e] == t[e][d],
1228 ExcMessage(
"The incoming Tensor must be exactly symmetric."));
1230 for (
unsigned int d = 0;
d < dim; ++
d)
1233 for (
unsigned int d = 0, c = 0;
d < dim; ++
d)
1234 for (
unsigned int e = d + 1;
e < dim; ++
e, ++c)
1235 data[dim + c] = t[d][e];
1240template <
int rank_,
int dim,
typename Number>
1241template <
typename OtherNumber>
1250template <
int rank_,
int dim,
typename Number>
1253 const Number (&array)[n_independent_components])
1255 *reinterpret_cast<const typename base_tensor_type::array_type *>(array))
1258 Assert(
sizeof(
typename base_tensor_type::array_type) ==
sizeof(array),
1264template <
int rank_,
int dim,
typename Number>
1265template <
typename OtherNumber>
1277template <
int rank_,
int dim,
typename Number>
1283 ExcMessage(
"Only assignment with zero is allowed"));
1294 namespace SymmetricTensorImplementation
1296 template <
int dim,
typename Number>
1297 constexpr inline DEAL_II_ALWAYS_INLINE ::Tensor<2, dim, Number>
1298 convert_to_tensor(const ::SymmetricTensor<2, dim, Number> &s)
1303 for (
unsigned int d = 0;
d < dim; ++
d)
1304 t[d][d] = s.access_raw_entry(d);
1307 for (
unsigned int d = 0, c = 0;
d < dim; ++
d)
1308 for (
unsigned int e = d + 1;
e < dim; ++
e, ++c)
1310 t[
d][
e] = s.access_raw_entry(dim + c);
1311 t[
e][
d] = s.access_raw_entry(dim + c);
1317 template <
int dim,
typename Number>
1318 constexpr ::Tensor<4, dim, Number>
1319 convert_to_tensor(const ::SymmetricTensor<4, dim, Number> &st)
1326 for (
unsigned int i = 0; i < dim; ++i)
1327 for (
unsigned int j = i; j < dim; ++j)
1328 for (
unsigned int k = 0; k < dim; ++k)
1329 for (
unsigned int l = k;
l < dim; ++
l)
1339 template <
typename Number>
1340 struct Inverse<2, 1, Number>
1342 constexpr static inline DEAL_II_ALWAYS_INLINE
1343 ::SymmetricTensor<2, 1, Number>
1344 value(const ::SymmetricTensor<2, 1, Number> &t)
1348 tmp[0][0] = 1.0 / t[0][0];
1355 template <
typename Number>
1356 struct Inverse<2, 2, Number>
1358 constexpr static inline DEAL_II_ALWAYS_INLINE
1359 ::SymmetricTensor<2, 2, Number>
1360 value(const ::SymmetricTensor<2, 2, Number> &t)
1370 const Number inv_det_t =
1371 1.0 / (t[idx_00] * t[idx_11] - t[idx_01] * t[idx_01]);
1372 tmp[idx_00] = t[idx_11];
1373 tmp[idx_01] = -t[idx_01];
1374 tmp[idx_11] = t[idx_00];
1382 template <
typename Number>
1383 struct Inverse<2, 3, Number>
1385 constexpr static ::SymmetricTensor<2, 3, Number>
1386 value(const ::SymmetricTensor<2, 3, Number> &t)
1430 const Number inv_det_t =
1431 1.0 / (t[idx_00] * t[idx_11] * t[idx_22] -
1432 t[idx_00] * t[idx_12] * t[idx_12] -
1433 t[idx_01] * t[idx_01] * t[idx_22] +
1434 2.0 * t[idx_01] * t[idx_02] * t[idx_12] -
1435 t[idx_02] * t[idx_02] * t[idx_11]);
1436 tmp[idx_00] = t[idx_11] * t[idx_22] - t[idx_12] * t[idx_12];
1437 tmp[idx_01] = -t[idx_01] * t[idx_22] + t[idx_02] * t[idx_12];
1438 tmp[idx_02] = t[idx_01] * t[idx_12] - t[idx_02] * t[idx_11];
1439 tmp[idx_11] = t[idx_00] * t[idx_22] - t[idx_02] * t[idx_02];
1440 tmp[idx_12] = -t[idx_00] * t[idx_12] + t[idx_01] * t[idx_02];
1441 tmp[idx_22] = t[idx_00] * t[idx_11] - t[idx_01] * t[idx_01];
1449 template <
typename Number>
1450 struct Inverse<4, 1, Number>
1452 constexpr static inline ::SymmetricTensor<4, 1, Number>
1453 value(const ::SymmetricTensor<4, 1, Number> &t)
1456 tmp.
data[0][0] = 1.0 / t.data[0][0];
1462 template <
typename Number>
1463 struct Inverse<4, 2, Number>
1465 constexpr static inline ::SymmetricTensor<4, 2, Number>
1466 value(const ::SymmetricTensor<4, 2, Number> &t)
1492 const Number t4 = t.
data[0][0] * t.data[1][1],
1493 t6 = t.data[0][0] * t.data[1][2],
1494 t8 = t.data[0][1] * t.data[1][0],
1495 t00 = t.data[0][2] * t.data[1][0],
1496 t01 = t.data[0][1] * t.data[2][0],
1497 t04 = t.data[0][2] * t.data[2][0],
1498 t07 = 1.0 / (t4 * t.data[2][2] - t6 * t.data[2][1] -
1499 t8 * t.data[2][2] + t00 * t.data[2][1] +
1500 t01 * t.data[1][2] - t04 * t.data[1][1]);
1502 (t.data[1][1] * t.data[2][2] - t.data[1][2] * t.data[2][1]) * t07;
1504 -(t.data[0][1] * t.data[2][2] - t.data[0][2] * t.data[2][1]) * t07;
1506 -(-t.data[0][1] * t.data[1][2] + t.data[0][2] * t.data[1][1]) * t07;
1508 -(t.data[1][0] * t.data[2][2] - t.data[1][2] * t.data[2][0]) * t07;
1509 tmp.
data[1][1] = (t.data[0][0] * t.data[2][2] - t04) * t07;
1510 tmp.
data[1][2] = -(t6 - t00) * t07;
1512 -(-t.data[1][0] * t.data[2][1] + t.data[1][1] * t.data[2][0]) * t07;
1513 tmp.
data[2][1] = -(t.data[0][0] * t.data[2][1] - t01) * t07;
1514 tmp.
data[2][2] = (t4 - t8) * t07;
1518 tmp.
data[2][0] /= 2;
1519 tmp.
data[2][1] /= 2;
1520 tmp.
data[0][2] /= 2;
1521 tmp.
data[1][2] /= 2;
1522 tmp.
data[2][2] /= 4;
1529 template <
typename Number>
1530 struct Inverse<4, 3, Number>
1532 static ::SymmetricTensor<4, 3, Number>
1533 value(const ::SymmetricTensor<4, 3, Number> &t)
1543 const unsigned int N = 6;
1549 for (
unsigned int i = 0; i < N; ++i)
1551 const Number typical_diagonal_element =
1552 diagonal_sum /
static_cast<double>(N);
1553 (void)typical_diagonal_element;
1556 for (
unsigned int i = 0; i < N; ++i)
1559 for (
unsigned int j = 0; j < N; ++j)
1565 for (
unsigned int i = j + 1; i < N; ++i)
1573 Assert(max > 1.e-16 * typical_diagonal_element,
1574 ExcMessage(
"This tensor seems to be noninvertible"));
1579 for (
unsigned int k = 0; k < N; ++k)
1580 std::swap(tmp.
data[j][k], tmp.
data[r][k]);
1582 std::swap(p[j], p[r]);
1586 const Number hr = 1. / tmp.
data[j][j];
1587 tmp.
data[j][j] = hr;
1588 for (
unsigned int k = 0; k < N; ++k)
1592 for (
unsigned int i = 0; i < N; ++i)
1596 tmp.
data[i][k] -= tmp.
data[i][j] * tmp.
data[j][k] * hr;
1599 for (
unsigned int i = 0; i < N; ++i)
1601 tmp.
data[i][j] *= hr;
1602 tmp.
data[j][i] *= -hr;
1604 tmp.
data[j][j] = hr;
1609 for (
unsigned int i = 0; i < N; ++i)
1611 for (
unsigned int k = 0; k < N; ++k)
1612 hv[p[k]] = tmp.
data[i][k];
1613 for (
unsigned int k = 0; k < N; ++k)
1614 tmp.
data[i][k] = hv[k];
1619 for (
unsigned int i = 3; i < 6; ++i)
1620 for (
unsigned int j = 0; j < 3; ++j)
1621 tmp.
data[i][j] /= 2;
1623 for (
unsigned int i = 0; i < 3; ++i)
1624 for (
unsigned int j = 3; j < 6; ++j)
1625 tmp.
data[i][j] /= 2;
1627 for (
unsigned int i = 3; i < 6; ++i)
1628 for (
unsigned int j = 3; j < 6; ++j)
1629 tmp.
data[i][j] /= 4;
1640template <
int rank_,
int dim,
typename Number>
1645 return internal::SymmetricTensorImplementation::convert_to_tensor(*
this);
1650template <
int rank_,
int dim,
typename Number>
1660template <
int rank_,
int dim,
typename Number>
1670template <
int rank_,
int dim,
typename Number>
1671template <
typename OtherNumber>
1683template <
int rank_,
int dim,
typename Number>
1684template <
typename OtherNumber>
1696template <
int rank_,
int dim,
typename Number>
1697template <
typename OtherNumber>
1708template <
int rank_,
int dim,
typename Number>
1709template <
typename OtherNumber>
1720template <
int rank_,
int dim,
typename Number>
1732template <
int rank_,
int dim,
typename Number>
1741template <
int rank_,
int dim,
typename Number>
1757 template <
int dim,
typename Number,
typename OtherNumber = Number>
1759 typename SymmetricTensorAccessors::
1760 double_contraction_result<2, 2, dim, Number, OtherNumber>::type
1761 perform_double_contraction(
1762 const typename SymmetricTensorAccessors::StorageType<2, dim, Number>::
1763 base_tensor_type &
data,
1764 const typename SymmetricTensorAccessors::
1765 StorageType<2, dim, OtherNumber>::base_tensor_type &sdata)
1767 using result_type =
typename SymmetricTensorAccessors::
1768 double_contraction_result<2, 2, dim, Number, OtherNumber>::type;
1773 return data[0] * sdata[0];
1781 result_type
sum =
data[dim] * sdata[dim];
1782 for (
unsigned int d = dim + 1;
d < (dim * (dim + 1) / 2); ++
d)
1783 sum +=
data[d] * sdata[d];
1787 for (
unsigned int d = 0;
d < dim; ++
d)
1788 sum +=
data[d] * sdata[d];
1799 template <
int dim,
typename Number,
typename OtherNumber = Number>
1801 typename SymmetricTensorAccessors::
1802 double_contraction_result<4, 2, dim, Number, OtherNumber>::type
1803 perform_double_contraction(
1804 const typename SymmetricTensorAccessors::StorageType<4, dim, Number>::
1805 base_tensor_type &
data,
1806 const typename SymmetricTensorAccessors::
1807 StorageType<2, dim, OtherNumber>::base_tensor_type &sdata)
1809 using result_type =
typename SymmetricTensorAccessors::
1810 double_contraction_result<4, 2, dim, Number, OtherNumber>::type;
1811 using value_type =
typename SymmetricTensorAccessors::
1812 double_contraction_result<4, 2, dim, Number, OtherNumber>::value_type;
1814 const unsigned int data_dim = SymmetricTensorAccessors::
1815 StorageType<2, dim, value_type>::n_independent_components;
1816 value_type tmp[data_dim]{};
1817 for (
unsigned int i = 0; i < data_dim; ++i)
1819 perform_double_contraction<dim, Number, OtherNumber>(
data[i], sdata);
1820 return result_type(tmp);
1829 template <
int dim,
typename Number,
typename OtherNumber = Number>
1831 typename SymmetricTensorAccessors::StorageType<
1834 typename SymmetricTensorAccessors::
1835 double_contraction_result<2, 4, dim, Number, OtherNumber>::value_type>::
1837 perform_double_contraction(
1838 const typename SymmetricTensorAccessors::StorageType<2, dim, Number>::
1839 base_tensor_type &
data,
1840 const typename SymmetricTensorAccessors::
1841 StorageType<4, dim, OtherNumber>::base_tensor_type &sdata)
1843 using value_type =
typename SymmetricTensorAccessors::
1844 double_contraction_result<2, 4, dim, Number, OtherNumber>::value_type;
1845 using base_tensor_type =
typename SymmetricTensorAccessors::
1846 StorageType<2, dim, value_type>::base_tensor_type;
1848 base_tensor_type tmp;
1849 for (
unsigned int i = 0; i < tmp.dimension; ++i)
1856 value_type
sum =
data[dim] * sdata[dim][i];
1857 for (
unsigned int d = dim + 1;
d < (dim * (dim + 1) / 2); ++
d)
1858 sum +=
data[d] * sdata[d][i];
1862 for (
unsigned int d = 0;
d < dim; ++
d)
1863 sum +=
data[d] * sdata[d][i];
1874 template <
int dim,
typename Number,
typename OtherNumber = Number>
1876 typename SymmetricTensorAccessors::StorageType<
1879 typename SymmetricTensorAccessors::
1880 double_contraction_result<4, 4, dim, Number, OtherNumber>::value_type>::
1882 perform_double_contraction(
1883 const typename SymmetricTensorAccessors::StorageType<4, dim, Number>::
1884 base_tensor_type &
data,
1885 const typename SymmetricTensorAccessors::
1886 StorageType<4, dim, OtherNumber>::base_tensor_type &sdata)
1888 using value_type =
typename SymmetricTensorAccessors::
1889 double_contraction_result<4, 4, dim, Number, OtherNumber>::value_type;
1890 using base_tensor_type =
typename SymmetricTensorAccessors::
1891 StorageType<4, dim, value_type>::base_tensor_type;
1893 const unsigned int data_dim = SymmetricTensorAccessors::
1894 StorageType<2, dim, value_type>::n_independent_components;
1895 base_tensor_type tmp;
1896 for (
unsigned int i = 0; i < data_dim; ++i)
1897 for (
unsigned int j = 0; j < data_dim; ++j)
1900 for (
unsigned int d = dim;
d < (dim * (dim + 1) / 2); ++
d)
1901 tmp[i][j] +=
data[i][d] * sdata[d][j];
1902 tmp[i][j] += tmp[i][j];
1905 for (
unsigned int d = 0;
d < dim; ++
d)
1906 tmp[i][j] +=
data[i][d] * sdata[d][j];
1915template <
int rank_,
int dim,
typename Number>
1916template <
typename OtherNumber>
1918 typename internal::SymmetricTensorAccessors::
1919 double_contraction_result<rank_, 2, dim, Number, OtherNumber>::type
1925 return internal::perform_double_contraction<dim, Number, OtherNumber>(
data,
1931template <
int rank_,
int dim,
typename Number>
1932template <
typename OtherNumber>
1934 typename internal::SymmetricTensorAccessors::
1935 double_contraction_result<rank_, 4, dim, Number, OtherNumber>::type
1939 typename internal::SymmetricTensorAccessors::
1940 double_contraction_result<rank_, 4, dim, Number, OtherNumber>::type tmp;
1942 internal::perform_double_contraction<dim, Number, OtherNumber>(
data,
1959 namespace SymmetricTensorImplementation
1981 constexpr ::ndarray<unsigned int, 2, 2> table = {
1982 {{{0, 2}}, {{2, 1}}}};
1983 return table[indices[0]][indices[1]];
1987 constexpr ::ndarray<unsigned int, 3, 3> table = {
1988 {{{0, 3, 4}}, {{3, 1, 5}}, {{4, 5, 2}}}};
1989 return table[indices[0]][indices[1]];
1993 constexpr ::ndarray<unsigned int, 4, 4> table = {
1998 return table[indices[0]][indices[1]];
2003 if (indices[0] == indices[1])
2014 for (
unsigned int d = 0;
d < dim; ++
d)
2015 for (
unsigned int e = d + 1;
e < dim; ++
e, ++c)
2016 if ((sorted_indices[0] == d) && (sorted_indices[1] == e))
2032 template <
int dim,
int rank_>
2033 constexpr inline unsigned int
2042 template <
int dim,
typename Number>
2045 typename SymmetricTensorAccessors::
2046 StorageType<2, dim, Number>::base_tensor_type &
data)
2048 return data[SymmetricTensorImplementation::component_to_unrolled_index<dim>(
2054 template <
int dim,
typename Number>
2057 const typename SymmetricTensorAccessors::
2058 StorageType<2, dim, Number>::base_tensor_type &
data)
2060 return data[SymmetricTensorImplementation::component_to_unrolled_index<dim>(
2066 template <
int dim,
typename Number>
2067 constexpr inline Number &
2069 typename SymmetricTensorAccessors::
2070 StorageType<4, dim, Number>::base_tensor_type &
data)
2084 constexpr std::size_t base_index[2][2] = {{0, 2}, {2, 1}};
2085 return data[base_index[indices[0]][indices[1]]]
2086 [base_index[indices[2]][indices[3]]];
2095 constexpr std::size_t base_index[3][3] = {{0, 3, 4},
2098 return data[base_index[indices[0]][indices[1]]]
2099 [base_index[indices[2]][indices[3]]];
2114 template <
int dim,
typename Number>
2117 const typename SymmetricTensorAccessors::
2118 StorageType<4, dim, Number>::base_tensor_type &
data)
2132 constexpr std::size_t base_index[2][2] = {{0, 2}, {2, 1}};
2133 return data[base_index[indices[0]][indices[1]]]
2134 [base_index[indices[2]][indices[3]]];
2143 constexpr std::size_t base_index[3][3] = {{0, 3, 4},
2146 return data[base_index[indices[0]][indices[1]]]
2147 [base_index[indices[2]][indices[3]]];
2165template <
int rank_,
int dim,
typename Number>
2170 for (
unsigned int r = 0; r < rank; ++r)
2172 return internal::symmetric_tensor_access<dim, Number>(indices,
data);
2177template <
int rank_,
int dim,
typename Number>
2182 for (
unsigned int r = 0; r < rank; ++r)
2184 return internal::symmetric_tensor_access<dim, Number>(indices,
data);
2191 namespace SymmetricTensorImplementation
2193 template <
int rank_>
2195 get_partially_filled_indices(
const unsigned int row,
2196 const std::integral_constant<int, 2> &)
2202 template <
int rank_>
2204 get_partially_filled_indices(
const unsigned int row,
2205 const std::integral_constant<int, 4> &)
2216template <
int rank_,
int dim,
typename Number>
2218 SymmetricTensorAccessors::Accessor<rank_, dim,
true, rank_ - 1, Number>
2221 return internal::SymmetricTensorAccessors::
2222 Accessor<rank_, dim,
true, rank_ - 1, Number>(
2224 internal::SymmetricTensorImplementation::get_partially_filled_indices<
2225 rank_>(row, std::integral_constant<int, rank_>()));
2230template <
int rank_,
int dim,
typename Number>
2232 SymmetricTensorAccessors::Accessor<rank_, dim,
false, rank_ - 1, Number>
2235 return internal::SymmetricTensorAccessors::
2236 Accessor<rank_, dim,
false, rank_ - 1, Number>(
2238 internal::SymmetricTensorImplementation::get_partially_filled_indices<
2239 rank_>(row, std::integral_constant<int, rank_>()));
2244template <
int rank_,
int dim,
typename Number>
2249 return operator()(indices);
2254template <
int rank_,
int dim,
typename Number>
2259 return operator()(indices);
2264template <
int rank_,
int dim,
typename Number>
2267 const unsigned int index)
const
2270 if constexpr (rank == 2)
2273 return data[
decltype(
data)::unrolled_to_component_indices(index)];
2278template <
int rank_,
int dim,
typename Number>
2283 if constexpr (rank == 2)
2286 return data[
decltype(
data)::unrolled_to_component_indices(index)];
2293 template <
int dim,
typename Number>
2295 compute_norm(
const typename SymmetricTensorAccessors::
2296 StorageType<2, dim, Number>::base_tensor_type &
data)
2323 for (
unsigned int d = 0;
d < dim; ++
d)
2326 for (
unsigned int d = dim;
d < (dim * dim + dim) / 2; ++
d)
2330 return sqrt(return_value);
2337 template <
int dim,
typename Number>
2339 compute_norm(
const typename SymmetricTensorAccessors::
2340 StorageType<4, dim, Number>::base_tensor_type &
data)
2354 const unsigned int n_independent_components =
data.dimension;
2356 for (
unsigned int i = 0; i < dim; ++i)
2357 for (
unsigned int j = 0; j < dim; ++j)
2360 for (
unsigned int i = 0; i < dim; ++i)
2361 for (
unsigned int j = dim; j < n_independent_components; ++j)
2364 for (
unsigned int i = dim; i < n_independent_components; ++i)
2365 for (
unsigned int j = 0; j < dim; ++j)
2368 for (
unsigned int i = dim; i < n_independent_components; ++i)
2369 for (
unsigned int j = dim; j < n_independent_components; ++j)
2373 return sqrt(return_value);
2382template <
int rank_,
int dim,
typename Number>
2386 return internal::compute_norm<dim, Number>(
data);
2391template <
int rank_,
int dim,
typename Number>
2396 return internal::SymmetricTensorImplementation::component_to_unrolled_index<
2404 namespace SymmetricTensorImplementation
2416 const std::integral_constant<int, 2> &)
2454 for (
unsigned int d = 0, c = dim;
d < dim; ++
d)
2455 for (
unsigned int e = d + 1;
e < dim; ++
e, ++c)
2473 template <
int dim,
int rank_>
2474 constexpr inline std::enable_if_t<rank_ != 2, TableIndices<rank_>>
2476 const std::integral_constant<int, rank_> &)
2485 n_independent_components));
2493template <
int rank_,
int dim,
typename Number>
2496 const unsigned int i)
2498 return internal::SymmetricTensorImplementation::unrolled_to_component_indices<
2499 dim>(i, std::integral_constant<int, rank_>());
2504template <
int rank_,
int dim,
typename Number>
2505template <
class Archive>
2530template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2555template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2575template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2592template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2609template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2626template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2637template <
int dim,
typename Number>
2653 return (tmp + tmp + t.
data[0] * t.
data[1] * t.
data[2] -
2677template <
int dim,
typename Number>
2686template <
int dim,
typename Number>
2690 Number t = d.data[0];
2691 for (
unsigned int i = 1; i < dim; ++i)
2708template <
int dim,
typename Number>
2727template <
typename Number>
2754template <
typename Number>
2758 return t[0][0] * t[1][1] - t[0][1] * t[0][1];
2771template <
typename Number>
2775 return (t[0][0] * t[1][1] + t[1][1] * t[2][2] + t[2][2] * t[0][0] -
2776 t[0][1] * t[0][1] - t[0][2] * t[0][2] - t[1][2] * t[1][2]);
2788template <
typename Number>
2789std::array<Number, 1>
2816template <
typename Number>
2817std::array<Number, 2>
2844template <
typename Number>
2845std::array<Number, 3>
2852 namespace SymmetricTensorImplementation
2865 template <
int dim,
typename Number>
2869 std::array<Number, dim> &d,
2870 std::array<Number, dim - 1> &e);
2887 template <
int dim,
typename Number>
2888 std::array<std::pair<Number, Tensor<1, dim, Number>>, dim>
2906 template <
int dim,
typename Number>
2907 std::array<std::pair<Number, Tensor<1, dim, Number>>, dim>
2925 template <
typename Number>
2926 std::array<std::pair<Number, Tensor<1, 2, Number>>, 2>
2927 hybrid(const ::SymmetricTensor<2, 2, Number> &A);
2945 template <
typename Number>
2946 std::array<std::pair<Number, Tensor<1, 3, Number>>, 3>
2947 hybrid(const ::SymmetricTensor<2, 3, Number> &A);
2953 template <
int dim,
typename Number>
2960 return lhs.first > rhs.first;
3027template <
int dim,
typename Number>
3028std::array<std::pair<Number, Tensor<1, dim, Number>>, dim>
3043template <
int rank_,
int dim,
typename Number>
3052template <
int dim,
typename Number>
3061 for (
unsigned int i = 0; i < dim; ++i)
3069template <
int dim,
typename Number>
3090 for (
unsigned int d = 0; d < dim; ++d)
3098template <
int dim,
typename Number>
3105 for (
unsigned int i = 0; i < dim; ++i)
3106 for (
unsigned int j = 0; j < dim; ++j)
3115 for (
unsigned int i = dim;
3116 i < internal::SymmetricTensorAccessors::StorageType<4, dim, Number>::
3126template <
int dim,
typename Number>
3134 for (
unsigned int i = 0; i < dim; ++i)
3142 for (
unsigned int i = dim;
3143 i < internal::SymmetricTensorAccessors::StorageType<4, dim, Number>::
3162template <
int dim,
typename Number>
3182template <
int dim,
typename Number>
3213template <
int dim,
typename Number>
3221 for (
unsigned int i = 0; i < dim; ++i)
3222 for (
unsigned int j = i; j < dim; ++j)
3223 for (
unsigned int k = 0; k < dim; ++k)
3224 for (
unsigned int l = k; l < dim; ++l)
3225 tmp[i][j][k][l] = t1[i][j] * t2[k][l];
3255template <
int dim,
typename Number>
3261 const std::array<std::pair<Number, Tensor<1, dim, Number>>, dim>
3265 positive_negative_tensors;
3267 auto &[positive_part_tensor, negative_part_tensor] =
3268 positive_negative_tensors;
3270 positive_part_tensor = 0;
3271 for (
unsigned int i = 0; i < dim; ++i)
3272 if (eigen_system[i].
first > 0)
3273 positive_part_tensor += eigen_system[i].first *
3275 eigen_system[i].
second));
3277 negative_part_tensor = 0;
3278 for (
unsigned int i = 0; i < dim; ++i)
3279 if (eigen_system[i].
first < 0)
3280 negative_part_tensor += eigen_system[i].first *
3282 eigen_system[i].
second));
3284 return positive_negative_tensors;
3319template <
int dim,
typename Number>
3320std::tuple<SymmetricTensor<2, dim, Number>,
3329 auto heaviside_function{[](
const double x) {
3330 if (std::fabs(x) < 1.0e-16)
3338 std::tuple<SymmetricTensor<2, dim, Number>,
3342 positive_negative_tensors_projectors;
3344 auto &[positive_part_tensor,
3345 negative_part_tensor,
3347 negative_projector] = positive_negative_tensors_projectors;
3349 const std::array<std::pair<Number, Tensor<1, dim, Number>>, dim>
3352 positive_part_tensor = 0;
3353 for (
unsigned int i = 0; i < dim; ++i)
3354 if (eigen_system[i].
first > 0)
3355 positive_part_tensor += eigen_system[i].first *
3357 eigen_system[i].
second));
3359 negative_part_tensor = 0;
3360 for (
unsigned int i = 0; i < dim; ++i)
3361 if (eigen_system[i].
first < 0)
3362 negative_part_tensor += eigen_system[i].first *
3364 eigen_system[i].
second));
3366 std::array<SymmetricTensor<2, dim, Number>, dim> M;
3367 for (
unsigned int a = 0; a < dim; ++a)
3371 std::array<SymmetricTensor<4, dim, Number>, dim> Q;
3372 for (
unsigned int a = 0; a < dim; ++a)
3375 std::array<std::array<SymmetricTensor<4, dim, Number>, dim>, dim> G;
3376 for (
unsigned int a = 0; a < dim; ++a)
3377 for (
unsigned int b = 0; b < dim; ++b)
3378 for (
unsigned int i = 0; i < dim; ++i)
3379 for (
unsigned int j = 0; j < dim; ++j)
3380 for (
unsigned int k = 0; k < dim; ++k)
3381 for (
unsigned int l = 0; l < dim; ++l)
3382 G[a][b][i][j][k][l] =
3383 M[a][i][k] * M[b][j][l] + M[a][i][l] * M[b][j][k];
3386 positive_projector = 0;
3387 for (
unsigned int a = 0; a < dim; ++a)
3389 double lambda_a = eigen_system[a].first;
3390 positive_projector += heaviside_function(lambda_a) * Q[a];
3391 for (
unsigned int b = 0; b < dim; ++b)
3395 double lambda_b = eigen_system[b].first;
3398 if (std::fabs(lambda_a - lambda_b) > 1.0e-12)
3399 v_ab = (std::fmax(lambda_a, 0.0) - std::fmax(lambda_b, 0.0)) /
3400 (lambda_a - lambda_b);
3402 v_ab = 0.5 * (heaviside_function(lambda_a) +
3403 heaviside_function(lambda_b));
3405 positive_projector += 0.5 * v_ab * 0.5 * (G[a][b] + G[b][a]);
3411 negative_projector = 0;
3412 for (
unsigned int a = 0; a < dim; ++a)
3414 double lambda_a = eigen_system[a].first;
3415 negative_projector += heaviside_function(-lambda_a) * Q[a];
3416 for (
unsigned int b = 0; b < dim; ++b)
3420 double lambda_b = eigen_system[b].first;
3423 if (std::fabs(lambda_a - lambda_b) > 1.0e-12)
3424 v_ab = (std::fmin(lambda_a, 0.0) - std::fmin(lambda_b, 0.0)) /
3425 (lambda_a - lambda_b);
3427 v_ab = 0.5 * (heaviside_function(-lambda_a) +
3428 heaviside_function(-lambda_b));
3430 negative_projector += 0.5 * v_ab * 0.5 * (G[a][b] + G[b][a]);
3435 return positive_negative_tensors_projectors;
3445template <
int dim,
typename Number>
3451 for (
unsigned int d = 0; d < dim; ++d)
3452 result[d][d] = t[d][d];
3455 for (
unsigned int d = 0; d < dim; ++d)
3456 for (
unsigned int e = d + 1; e < dim; ++e)
3457 result[d][e] = (t[d][e] + t[e][d]) * half;
3474template <
int dim,
typename Number>
3484 for (
unsigned int i = 0; i < dim; ++i)
3485 for (
unsigned int j = 0; j < dim; ++j)
3486 for (
unsigned int k = 0; k < dim; ++k)
3487 for (
unsigned int l = 0; l < dim; ++l)
3489 if (i != j && k == l)
3492 result[i][j][k][k] = (t[i][j][k][k] + t[j][i][k][k]) * half;
3494 else if (i == j && k != l)
3497 result[i][i][k][l] = (t[i][i][k][l] + t[i][i][l][k]) * half;
3499 else if (i != j && k != l)
3502 result[i][j][k][l] = (t[i][j][k][l] + t[j][i][k][l] +
3503 t[i][j][l][k] + t[j][i][l][k]) *
3509 result[i][j][k][l] = t[i][j][k][l];
3517 for (
unsigned int i = 0; i < dim; ++i)
3518 for (
unsigned int j = i; j < dim; ++j)
3519 for (
unsigned int k = 0; k < dim; ++k)
3520 for (
unsigned int l = k; l < dim; ++l)
3521 result[i][j][k][l] = (t[i][j][k][l] + t[k][l][i][j]) * half;
3535template <
int rank_,
int dim,
typename Number>
3554template <
int rank_,
int dim,
typename Number>
3588template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
3595 const OtherNumber &factor)
3617template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
3627 return (t * factor);
3637template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
3644 const OtherNumber &factor)
3660template <
int rank_,
int dim>
3677template <
int rank_,
int dim>
3693template <
int rank_,
int dim>
3711template <
int dim,
typename Number,
typename OtherNumber>
3733template <
int dim,
typename Number,
typename OtherNumber>
3741 for (
unsigned int i = 0; i < dim; ++i)
3742 for (
unsigned int j = 0; j < dim; ++j)
3743 s += t1[i][j] * t2[i][j];
3760template <
int dim,
typename Number,
typename OtherNumber>
3766 return scalar_product(t2, t1);
3784template <
typename Number,
typename OtherNumber>
3791 tmp[0][0] = t[0][0][0][0] * s[0][0];
3810template <
typename Number,
typename OtherNumber>
3817 tmp[0][0] = t[0][0][0][0] * s[0][0];
3836template <
typename Number,
typename OtherNumber>
3843 const unsigned int dim = 2;
3845 for (
unsigned int i = 0; i < dim; ++i)
3846 for (
unsigned int j = i; j < dim; ++j)
3847 tmp[i][j] = t[i][j][0][0] * s[0][0] + t[i][j][1][1] * s[1][1] +
3848 2 * t[i][j][0][1] * s[0][1];
3867template <
typename Number,
typename OtherNumber>
3874 const unsigned int dim = 2;
3876 for (
unsigned int i = 0; i < dim; ++i)
3877 for (
unsigned int j = i; j < dim; ++j)
3878 tmp[i][j] = s[0][0] * t[0][0][i][j] * +s[1][1] * t[1][1][i][j] +
3879 2 * s[0][1] * t[0][1][i][j];
3898template <
typename Number,
typename OtherNumber>
3905 const unsigned int dim = 3;
3907 for (
unsigned int i = 0; i < dim; ++i)
3908 for (
unsigned int j = i; j < dim; ++j)
3909 tmp[i][j] = t[i][j][0][0] * s[0][0] + t[i][j][1][1] * s[1][1] +
3910 t[i][j][2][2] * s[2][2] + 2 * t[i][j][0][1] * s[0][1] +
3911 2 * t[i][j][0][2] * s[0][2] + 2 * t[i][j][1][2] * s[1][2];
3930template <
typename Number,
typename OtherNumber>
3937 const unsigned int dim = 3;
3939 for (
unsigned int i = 0; i < dim; ++i)
3940 for (
unsigned int j = i; j < dim; ++j)
3941 tmp[i][j] = s[0][0] * t[0][0][i][j] + s[1][1] * t[1][1][i][j] +
3942 s[2][2] * t[2][2][i][j] + 2 * s[0][1] * t[0][1][i][j] +
3943 2 * s[0][2] * t[0][2][i][j] + 2 * s[1][2] * t[1][2][i][j];
3954template <
int dim,
typename Number,
typename OtherNumber>
3962 for (
unsigned int i = 0; i < dim; ++i)
3964 dest[i] = src1[i][0] * src2[0];
3965 for (
unsigned int j = 1; j < dim; ++j)
3966 dest[i] += src1[i][j] * src2[j];
3978template <
int dim,
typename Number,
typename OtherNumber>
4010template <
int rank_1,
4014 typename OtherNumber>
4016 typename Tensor<rank_1 + rank_2 - 2,
4046template <
int rank_1,
4050 typename OtherNumber>
4052 typename Tensor<rank_1 + rank_2 - 2,
4072template <
int dim,
typename Number>
4073inline std::ostream &
4081 for (
unsigned int i = 0; i < dim; ++i)
4082 for (
unsigned int j = 0; j < dim; ++j)
4099template <
int dim,
typename Number>
4100inline std::ostream &
4108 for (
unsigned int i = 0; i < dim; ++i)
4109 for (
unsigned int j = 0; j < dim; ++j)
4110 for (
unsigned int k = 0; k < dim; ++k)
4111 for (
unsigned int l = 0; l < dim; ++l)
4112 tt[i][j][k][l] = t[i][j][k][l];
DEAL_II_HOST constexpr SymmetricTensor< rank_, dim, Number > operator*(const SymmetricTensor< rank_, dim, Number > &t, const Number &factor)
DEAL_II_HOST constexpr Number determinant(const SymmetricTensor< 2, dim, Number > &)
DEAL_II_HOST constexpr SymmetricTensor< rank_, dim, Number > transpose(const SymmetricTensor< rank_, dim, Number > &t)
DEAL_II_HOST constexpr internal::SymmetricTensorAccessors::Accessor< rank_, dim, false, rank_ - 1, Number > operator[](const unsigned int row)
std::pair< SymmetricTensor< 2, dim, Number >, SymmetricTensor< 2, dim, Number > > positive_negative_split(const SymmetricTensor< 2, dim, Number > &original_tensor)
DEAL_II_HOST constexpr SymmetricTensor< rank_, dim, typename ProductType< Number, typename EnableIfScalar< OtherNumber >::type >::type > operator/(const SymmetricTensor< rank_, dim, Number > &t, const OtherNumber &factor)
DEAL_II_HOST constexpr SymmetricTensor< 2, dim, Number > symmetrize(const Tensor< 2, dim, Number > &t)
DEAL_II_HOST constexpr void double_contract(SymmetricTensor< 2, 2, typename ProductType< Number, OtherNumber >::type > &tmp, const SymmetricTensor< 4, 2, Number > &t, const SymmetricTensor< 2, 2, OtherNumber > &s)
static DEAL_II_HOST constexpr std::size_t memory_consumption()
DEAL_II_HOST constexpr SymmetricTensor & operator/=(const OtherNumber &factor)
DEAL_II_HOST constexpr Tensor< rank_1+rank_2-2, dim, typenameProductType< Number, OtherNumber >::type >::tensor_type operator*(const Tensor< rank_1, dim, Number > &src1, const SymmetricTensor< rank_2, dim, OtherNumber > &src2)
DEAL_II_HOST constexpr Number third_invariant(const SymmetricTensor< 2, dim, Number > &t)
DEAL_II_HOST constexpr Tensor< 1, dim, typename ProductType< Number, OtherNumber >::type > operator*(const SymmetricTensor< 2, dim, Number > &src1, const Tensor< 1, dim, OtherNumber > &src2)
DEAL_II_HOST constexpr SymmetricTensor< rank_, dim, typename ProductType< OtherNumber, typename EnableIfScalar< Number >::type >::type > operator*(const Number &factor, const SymmetricTensor< rank_, dim, OtherNumber > &t)
DEAL_II_HOST constexpr Number & operator[](const TableIndices< rank_ > &indices)
std::array< Number, 2 > eigenvalues(const SymmetricTensor< 2, 2, Number > &T)
DEAL_II_HOST constexpr SymmetricTensor< rank_, dim, typename ProductType< Number, OtherNumber >::type > operator-(const SymmetricTensor< rank_, dim, Number > &left, const SymmetricTensor< rank_, dim, OtherNumber > &right)
void serialize(Archive &ar, const unsigned int version)
DEAL_II_HOST constexpr Number first_invariant(const SymmetricTensor< 2, dim, Number > &t)
std::array< Number, 1 > eigenvalues(const SymmetricTensor< 2, 1, Number > &T)
std::tuple< SymmetricTensor< 2, dim, Number >, SymmetricTensor< 2, dim, Number >, SymmetricTensor< 4, dim, Number >, SymmetricTensor< 4, dim, Number > > positive_negative_projectors(const SymmetricTensor< 2, dim, Number > &original_tensor)
DEAL_II_HOST constexpr SymmetricTensor< rank_, dim, typename ProductType< Number, typename EnableIfScalar< OtherNumber >::type >::type > operator*(const SymmetricTensor< rank_, dim, Number > &t, const OtherNumber &factor)
DEAL_II_HOST constexpr const Number & operator()(const TableIndices< rank_ > &indices) const
std::array< std::pair< Number, Tensor< 1, dim, Number > >, dim > eigenvectors(const SymmetricTensor< 2, dim, Number > &T, const SymmetricTensorEigenvectorMethod method=SymmetricTensorEigenvectorMethod::ql_implicit_shifts)
typename base_tensor_descriptor::base_tensor_type base_tensor_type
DEAL_II_HOST constexpr SymmetricTensor(const SymmetricTensor< rank_, dim, OtherNumber > &initializer)
DEAL_II_HOST constexpr ProductType< Number, OtherNumber >::type scalar_product(const Tensor< 2, dim, Number > &t1, const SymmetricTensor< 2, dim, OtherNumber > &t2)
DEAL_II_HOST constexpr SymmetricTensor< 4, dim, Number > outer_product(const SymmetricTensor< 2, dim, Number > &t1, const SymmetricTensor< 2, dim, Number > &t2)
DEAL_II_HOST constexpr SymmetricTensor< rank_, dim > operator/(const SymmetricTensor< rank_, dim > &t, const double factor)
DEAL_II_HOST constexpr bool operator==(const SymmetricTensor &) const
DEAL_II_HOST constexpr SymmetricTensor< 2, dim, Number > invert(const SymmetricTensor< 2, dim, Number > &t)
DEAL_II_HOST constexpr const Number & access_raw_entry(const unsigned int unrolled_index) const
DEAL_II_HOST constexpr Number & operator()(const TableIndices< rank_ > &indices)
DEAL_II_HOST constexpr SymmetricTensor & operator*=(const OtherNumber &factor)
DEAL_II_HOST constexpr ProductType< Number, OtherNumber >::type scalar_product(const SymmetricTensor< 2, dim, Number > &t1, const SymmetricTensor< 2, dim, OtherNumber > &t2)
DEAL_II_HOST constexpr SymmetricTensor(const Number(&array)[n_independent_components])
DEAL_II_HOST constexpr bool operator!=(const SymmetricTensor &) const
DEAL_II_HOST constexpr SymmetricTensor & operator=(const Number &d)
DEAL_II_HOST constexpr Tensor< rank_, dim, typename ProductType< Number, OtherNumber >::type > operator+(const SymmetricTensor< rank_, dim, Number > &left, const Tensor< rank_, dim, OtherNumber > &right)
DEAL_II_HOST constexpr SymmetricTensor operator-() const
DEAL_II_HOST constexpr ProductType< Number, OtherNumber >::type scalar_product(const SymmetricTensor< 2, dim, Number > &t1, const Tensor< 2, dim, OtherNumber > &t2)
DEAL_II_HOST constexpr SymmetricTensor< rank_, dim, typename ProductType< Number, OtherNumber >::type > operator+(const SymmetricTensor< rank_, dim, Number > &left, const SymmetricTensor< rank_, dim, OtherNumber > &right)
DEAL_II_HOST constexpr Number & access_raw_entry(const unsigned int unrolled_index)
DEAL_II_HOST constexpr Tensor< 1, dim, typename ProductType< Number, OtherNumber >::type > operator*(const Tensor< 1, dim, Number > &src1, const SymmetricTensor< 2, dim, OtherNumber > &src2)
DEAL_II_HOST constexpr Number trace(const SymmetricTensor< 2, dim2, Number > &)
DEAL_II_HOST constexpr SymmetricTensor< rank_, dim > operator*(const SymmetricTensor< rank_, dim > &t, const double factor)
SymmetricTensor(const Tensor< 2, dim, OtherNumber > &t)
DEAL_II_HOST constexpr void double_contract(SymmetricTensor< 2, 1, typename ProductType< Number, OtherNumber >::type > &tmp, const SymmetricTensor< 2, 1, Number > &s, const SymmetricTensor< 4, 1, OtherNumber > &t)
DEAL_II_HOST constexpr Tensor< rank_1+rank_2-2, dim, typenameProductType< Number, OtherNumber >::type >::tensor_type operator*(const SymmetricTensor< rank_1, dim, Number > &src1, const Tensor< rank_2, dim, OtherNumber > &src2)
DEAL_II_HOST constexpr internal::SymmetricTensorAccessors::double_contraction_result< rank_, 2, dim, Number, OtherNumber >::type operator*(const SymmetricTensor< 2, dim, OtherNumber > &s) const
static DEAL_II_HOST constexpr unsigned int component_to_unrolled_index(const TableIndices< rank_ > &indices)
DEAL_II_HOST constexpr void double_contract(SymmetricTensor< 2, 3, typename ProductType< Number, OtherNumber >::type > &tmp, const SymmetricTensor< 4, 3, Number > &t, const SymmetricTensor< 2, 3, OtherNumber > &s)
DEAL_II_HOST constexpr Tensor< rank_, dim, typename ProductType< Number, OtherNumber >::type > operator+(const Tensor< rank_, dim, Number > &left, const SymmetricTensor< rank_, dim, OtherNumber > &right)
DEAL_II_HOST constexpr void double_contract(SymmetricTensor< 2, 1, typename ProductType< Number, OtherNumber >::type > &tmp, const SymmetricTensor< 4, 1, Number > &t, const SymmetricTensor< 2, 1, OtherNumber > &s)
static DEAL_II_HOST constexpr TableIndices< rank_ > unrolled_to_component_indices(const unsigned int i)
DEAL_II_HOST constexpr SymmetricTensor< 4, dim, Number > deviator_tensor()
DEAL_II_HOST constexpr SymmetricTensor & operator-=(const SymmetricTensor< rank_, dim, OtherNumber > &)
DEAL_II_HOST constexpr void double_contract(SymmetricTensor< 2, 3, typename ProductType< Number, OtherNumber >::type > &tmp, const SymmetricTensor< 2, 3, Number > &s, const SymmetricTensor< 4, 3, OtherNumber > &t)
DEAL_II_HOST constexpr void clear()
DEAL_II_HOST constexpr SymmetricTensor< 4, dim, Number > identity_tensor()
DEAL_II_HOST constexpr SymmetricTensor< 4, dim, Number > invert(const SymmetricTensor< 4, dim, Number > &t)
DEAL_II_HOST constexpr void double_contract(SymmetricTensor< 2, 2, typename ProductType< Number, OtherNumber >::type > &tmp, const SymmetricTensor< 2, 2, Number > &s, const SymmetricTensor< 4, 2, OtherNumber > &t)
DEAL_II_HOST constexpr Number second_invariant(const SymmetricTensor< 2, 2, Number > &t)
DEAL_II_HOST constexpr SymmetricTensor< rank_, dim, Number > operator*(const Number &factor, const SymmetricTensor< rank_, dim, Number > &t)
DEAL_II_HOST constexpr numbers::NumberTraits< Number >::real_type norm() const
DEAL_II_HOST constexpr internal::SymmetricTensorAccessors::double_contraction_result< rank_, 4, dim, Number, OtherNumber >::type operator*(const SymmetricTensor< 4, dim, OtherNumber > &s) const
DEAL_II_HOST constexpr SymmetricTensor & operator=(const SymmetricTensor< rank_, dim, OtherNumber > &rhs)
DEAL_II_HOST constexpr SymmetricTensor()=default
DEAL_II_HOST constexpr Number second_invariant(const SymmetricTensor< 2, 3, Number > &t)
DEAL_II_HOST constexpr Number second_invariant(const SymmetricTensor< 2, 1, Number > &)
DEAL_II_HOST constexpr SymmetricTensor< 4, dim, Number > symmetrize(const Tensor< 4, dim, Number > &t, const bool major_symmetry)
DEAL_II_HOST constexpr SymmetricTensor< 2, dim, Number > deviator(const SymmetricTensor< 2, dim, Number > &)
DEAL_II_HOST constexpr Tensor< rank_, dim, typename ProductType< Number, OtherNumber >::type > operator-(const SymmetricTensor< rank_, dim, Number > &left, const Tensor< rank_, dim, OtherNumber > &right)
DEAL_II_HOST constexpr SymmetricTensor & operator+=(const SymmetricTensor< rank_, dim, OtherNumber > &)
DEAL_II_HOST constexpr const Number & operator[](const TableIndices< rank_ > &indices) const
DEAL_II_HOST constexpr Tensor< rank_, dim, typename ProductType< Number, OtherNumber >::type > operator-(const Tensor< rank_, dim, Number > &left, const SymmetricTensor< rank_, dim, OtherNumber > &right)
DEAL_II_HOST constexpr SymmetricTensor< 2, dim, Number > unit_symmetric_tensor()
DEAL_II_HOST constexpr SymmetricTensor< rank_, dim > operator*(const double factor, const SymmetricTensor< rank_, dim > &t)
std::array< Number, 3 > eigenvalues(const SymmetricTensor< 2, 3, Number > &T)
DEAL_II_HOST constexpr internal::SymmetricTensorAccessors::Accessor< rank_, dim, true, rank_ - 1, Number > operator[](const unsigned int row) const
typename AccessorTypes< rank, dim, constness, Number >::reference reference
const TableIndices< rank > previous_indices
typename AccessorTypes< rank, dim, constness, Number >::tensor_type tensor_type
DEAL_II_HOST constexpr Accessor(tensor_type &tensor, const TableIndices< rank > &previous_indices)
DEAL_II_HOST constexpr reference operator[](const unsigned int)
DEAL_II_HOST constexpr reference operator[](const unsigned int) const
DEAL_II_HOST constexpr Accessor(const Accessor &)=default
DEAL_II_HOST constexpr Accessor< rank, dim, constness, P - 1, Number > operator[](const unsigned int i) const
const TableIndices< rank > previous_indices
typename AccessorTypes< rank, dim, constness, Number >::tensor_type tensor_type
DEAL_II_HOST constexpr Accessor(tensor_type &tensor, const TableIndices< rank > &previous_indices)
DEAL_II_HOST constexpr Accessor< rank, dim, constness, P - 1, Number > operator[](const unsigned int i)
typename AccessorTypes< rank, dim, constness, Number >::reference reference
DEAL_II_HOST constexpr Accessor(const Accessor &)=default
#define DEAL_II_ALWAYS_INLINE
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_CONSTEXPR
#define DEAL_II_NAMESPACE_CLOSE
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcIndexRange(std::size_t arg1, std::size_t arg2, std::size_t arg3)
static ::ExceptionBase & ExcMessage(std::string arg1)
#define DEAL_II_ASSERT_UNREACHABLE()
#define DEAL_II_NOT_IMPLEMENTED()
std::vector< index_type > data
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
Tensor< 2, dim, Number > l(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
T sum(const T &t, const MPI_Comm mpi_communicator)
DEAL_II_HOST constexpr TableIndices< 2 > merge(const TableIndices< 2 > &previous_indices, const unsigned int new_index, const unsigned int position)
void tridiagonalize(const ::SymmetricTensor< 2, dim, Number > &A, ::Tensor< 2, dim, Number > &Q, std::array< Number, dim > &d, std::array< Number, dim - 1 > &e)
constexpr bool value_is_zero(const Number &value)
static const unsigned int invalid_unsigned_int
::VectorizedArray< Number, width > min(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > max(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > sqrt(const ::VectorizedArray< Number, width > &)
typename internal::ProductTypeImpl< std::decay_t< T >, std::decay_t< U > >::type type
static constexpr DEAL_II_HOST_DEVICE_ALWAYS_INLINE const T & value(const T &t)
typename ProductType< Number, OtherNumber >::type type
typename ProductType< Number, OtherNumber >::type value_type
std::pair< Number, Tensor< 1, dim, Number > > EigValsVecs
bool operator()(const EigValsVecs &lhs, const EigValsVecs &rhs)
static real_type abs(const number &x)
DEAL_II_HOST constexpr Number determinant(const SymmetricTensor< 2, dim, Number > &)
DEAL_II_HOST constexpr SymmetricTensor< 2, dim, Number > symmetrize(const Tensor< 2, dim, Number > &t)
DEAL_II_HOST constexpr SymmetricTensor< 2, dim, Number > invert(const SymmetricTensor< 2, dim, Number > &)
std::array< std::pair< Number, Tensor< 1, dim, Number > >, dim > eigenvectors(const SymmetricTensor< 2, dim, Number > &T, const SymmetricTensorEigenvectorMethod method=SymmetricTensorEigenvectorMethod::ql_implicit_shifts)
DEAL_II_HOST constexpr SymmetricTensor< 4, dim, Number > outer_product(const SymmetricTensor< 2, dim, Number > &t1, const SymmetricTensor< 2, dim, Number > &t2)
DEAL_II_HOST constexpr Number trace(const SymmetricTensor< 2, dim2, Number > &)
DEAL_II_HOST constexpr SymmetricTensor< 4, dim, Number > deviator_tensor()
DEAL_II_HOST constexpr SymmetricTensor< 4, dim, Number > identity_tensor()
SymmetricTensorEigenvectorMethod
DEAL_II_HOST constexpr SymmetricTensor< 2, dim, Number > deviator(const SymmetricTensor< 2, dim, Number > &)
DEAL_II_HOST constexpr SymmetricTensor< 2, dim, Number > unit_symmetric_tensor()