16#ifndef dealii_symmetric_tensor_h
17#define dealii_symmetric_tensor_h
35template <
int rank,
int dim,
typename Number =
double>
39template <
int dim,
typename Number>
43template <
int dim,
typename Number>
47template <
int dim,
typename Number>
51template <
int dim,
typename Number>
55template <
int dim,
typename Number>
59template <
int dim2,
typename Number>
63template <
int dim,
typename Number>
67template <
int dim,
typename Number>
79 template <
int rank,
int dim,
typename T,
typename U>
85 std::complex<typename ProductType<T, U>::type>>;
88 template <
int rank,
int dim,
typename T,
typename U>
95 std::complex<typename ProductType<T, U>::type>>;
98 template <
typename T,
int rank,
int dim,
typename U>
104 std::complex<typename ProductType<T, U>::type>>;
107 template <
int rank,
int dim,
typename T,
typename U>
114 std::complex<typename ProductType<T, U>::type>>;
122 namespace SymmetricTensorImplementation
128 template <
int rank,
int dim,
typename Number>
136 namespace SymmetricTensorAccessors
146 const unsigned int new_index,
147 const unsigned int position)
154 return {previous_indices[0], new_index};
167 const unsigned int new_index,
168 const unsigned int position)
180 return {previous_indices[0],
185 return {previous_indices[0],
190 return {previous_indices[0],
211 typename OtherNumber = Number>
226 template <
int dim,
typename Number,
typename OtherNumber>
246 template <
int rank,
int dim,
typename Number>
252 template <
int dim,
typename Number>
259 static const unsigned int n_independent_components =
260 (dim * dim + dim) / 2;
273 template <
int dim,
typename Number>
281 static const unsigned int n_rank2_components = (dim * dim + dim) / 2;
286 static const unsigned int n_independent_components =
287 (n_rank2_components *
305 template <
int rank,
int dim,
bool constness,
typename Number>
314 template <
int rank,
int dim,
typename Number>
328 template <
int rank,
int dim,
typename Number>
369 template <
int rank,
int dim,
bool constness,
int P,
typename Number>
413 constexpr Accessor<rank, dim, constness, P - 1, Number>
419 constexpr Accessor<rank, dim, constness, P - 1, Number>
431 template <
int,
int,
typename>
432 friend class ::SymmetricTensor;
433 template <
int,
int,
bool,
int,
typename>
435 friend class ::SymmetricTensor<rank, dim, Number>;
436 friend class Accessor<rank, dim, constness, P + 1, Number>;
448 template <
int rank,
int dim,
bool constness,
typename Number>
511 template <
int,
int,
typename>
512 friend class ::SymmetricTensor;
513 template <
int,
int,
bool,
int,
typename>
515 friend class ::SymmetricTensor<rank, dim, Number>;
516 friend class SymmetricTensorAccessors::
517 Accessor<rank, dim, constness, 2, Number>;
596template <int rank_, int dim, typename Number>
600 static_assert(rank_ % 2 == 0,
"A SymmetricTensor must have even rank!");
610 static const unsigned int dimension = dim;
615 static const unsigned int rank = rank_;
622 static constexpr unsigned int n_independent_components =
624 n_independent_components;
645 template <
typename OtherNumber>
670 template <
typename OtherNumber>
705 template <
typename OtherNumber>
739 template <
typename OtherNumber>
746 template <
typename OtherNumber>
754 template <
typename OtherNumber>
761 template <
typename OtherNumber>
797 template <
typename OtherNumber>
806 template <
typename OtherNumber>
820 constexpr const Number &
827 constexpr internal::SymmetricTensorAccessors::
828 Accessor<rank_, dim,
true, rank_ - 1, Number>
835 constexpr internal::SymmetricTensorAccessors::
836 Accessor<rank_, dim,
false, rank_ - 1, Number>
859 constexpr const Number &
890 static constexpr unsigned int
920 static constexpr std::size_t
928 template <
class Archive>
950 template <
int,
int,
typename>
954 template <
int dim2,
typename Number2>
955 friend constexpr Number2
958 template <
int dim2,
typename Number2>
959 friend constexpr Number2
962 template <
int dim2,
typename Number2>
966 template <
int dim2,
typename Number2>
970 template <
int dim2,
typename Number2>
974 template <
int dim2,
typename Number2>
981 Inverse<2, dim, Number>;
984 Inverse<4, dim, Number>;
994template <int rank, int dim, typename Number>
997template <int rank_, int dim, typename Number>
998constexpr unsigned
int
1003 namespace SymmetricTensorAccessors
1005 template <
int rank_,
int dim,
bool constness,
int P,
typename Number>
1016 template <
int rank_,
int dim,
bool constness,
int P,
typename Number>
1018 Accessor<rank_, dim, constness, P - 1, Number>
1019 Accessor<rank_, dim, constness, P, Number>::
1020 operator[](
const unsigned int i)
1022 return Accessor<rank_, dim, constness, P - 1, Number>(
1023 tensor,
merge(previous_indices, i, rank_ - P));
1028 template <
int rank_,
int dim,
bool constness,
int P,
typename Number>
1030 Accessor<rank_, dim, constness, P - 1, Number>
1031 Accessor<rank_, dim, constness, P, Number>::
1032 operator[](
const unsigned int i)
const
1034 return Accessor<rank_, dim, constness, P - 1, Number>(
1035 tensor,
merge(previous_indices, i, rank_ - P));
1040 template <
int rank_,
int dim,
bool constness,
typename Number>
1042 Accessor<rank_, dim, constness, 1, Number>::Accessor(
1043 tensor_type & tensor,
1046 , previous_indices(previous_indices)
1051 template <
int rank_,
int dim,
bool constness,
typename Number>
1053 typename Accessor<rank_, dim, constness, 1, Number>::reference
1054 Accessor<rank_, dim, constness, 1, Number>::
1055 operator[](
const unsigned int i)
1057 return tensor(
merge(previous_indices, i, rank_ - 1));
1061 template <
int rank_,
int dim,
bool constness,
typename Number>
1063 typename Accessor<rank_, dim, constness, 1, Number>::reference
1064 Accessor<rank_, dim, constness, 1, Number>::
1065 operator[](
const unsigned int i)
const
1067 return tensor(
merge(previous_indices, i, rank_ - 1));
1074template <
int rank_,
int dim,
typename Number>
1075template <
typename OtherNumber>
1080 static_assert(rank == 2,
"This function is only implemented for rank==2");
1081 for (
unsigned int d = 0;
d < dim; ++
d)
1082 for (
unsigned int e = 0;
e <
d; ++
e)
1084 ExcMessage(
"The incoming Tensor must be exactly symmetric."));
1086 for (
unsigned int d = 0;
d < dim; ++
d)
1089 for (
unsigned int d = 0, c = 0;
d < dim; ++
d)
1090 for (
unsigned int e =
d + 1;
e < dim; ++
e, ++c)
1091 data[dim + c] = t[
d][
e];
1096template <
int rank_,
int dim,
typename Number>
1097template <
typename OtherNumber>
1101 : data(initializer.data)
1106template <
int rank_,
int dim,
typename Number>
1109 const Number (&array)[n_independent_components])
1111 *reinterpret_cast<const typename base_tensor_type::array_type *>(array))
1114 Assert(
sizeof(
typename base_tensor_type::array_type) ==
sizeof(array),
1120template <
int rank_,
int dim,
typename Number>
1121template <
typename OtherNumber>
1132template <
int rank_,
int dim,
typename Number>
1137 ExcMessage(
"Only assignment with zero is allowed"));
1148 namespace SymmetricTensorImplementation
1150 template <
int dim,
typename Number>
1151 constexpr inline DEAL_II_ALWAYS_INLINE ::Tensor<2, dim, Number>
1152 convert_to_tensor(const ::SymmetricTensor<2, dim, Number> &s)
1157 for (
unsigned int d = 0;
d < dim; ++
d)
1158 t[
d][
d] = s.access_raw_entry(
d);
1161 for (
unsigned int d = 0, c = 0;
d < dim; ++
d)
1162 for (
unsigned int e =
d + 1;
e < dim; ++
e, ++c)
1164 t[
d][
e] = s.access_raw_entry(dim + c);
1165 t[
e][
d] = s.access_raw_entry(dim + c);
1171 template <
int dim,
typename Number>
1172 constexpr ::Tensor<4, dim, Number>
1173 convert_to_tensor(const ::SymmetricTensor<4, dim, Number> &st)
1180 for (
unsigned int i = 0; i < dim; ++i)
1181 for (
unsigned int j = i; j < dim; ++j)
1182 for (
unsigned int k = 0; k < dim; ++k)
1183 for (
unsigned int l = k;
l < dim; ++
l)
1193 template <
typename Number>
1194 struct Inverse<2, 1, Number>
1196 constexpr static inline DEAL_II_ALWAYS_INLINE
1197 ::SymmetricTensor<2, 1, Number>
1198 value(const ::SymmetricTensor<2, 1, Number> &t)
1202 tmp[0][0] = 1.0 / t[0][0];
1209 template <
typename Number>
1210 struct Inverse<2, 2, Number>
1212 constexpr static inline DEAL_II_ALWAYS_INLINE
1213 ::SymmetricTensor<2, 2, Number>
1214 value(const ::SymmetricTensor<2, 2, Number> &t)
1224 const Number inv_det_t =
1225 1.0 / (t[idx_00] * t[idx_11] - t[idx_01] * t[idx_01]);
1226 tmp[idx_00] = t[idx_11];
1227 tmp[idx_01] = -t[idx_01];
1228 tmp[idx_11] = t[idx_00];
1236 template <
typename Number>
1237 struct Inverse<2, 3, Number>
1239 constexpr static ::SymmetricTensor<2, 3, Number>
1240 value(const ::SymmetricTensor<2, 3, Number> &t)
1284 const Number inv_det_t =
1285 1.0 / (t[idx_00] * t[idx_11] * t[idx_22] -
1286 t[idx_00] * t[idx_12] * t[idx_12] -
1287 t[idx_01] * t[idx_01] * t[idx_22] +
1288 2.0 * t[idx_01] * t[idx_02] * t[idx_12] -
1289 t[idx_02] * t[idx_02] * t[idx_11]);
1290 tmp[idx_00] = t[idx_11] * t[idx_22] - t[idx_12] * t[idx_12];
1291 tmp[idx_01] = -t[idx_01] * t[idx_22] + t[idx_02] * t[idx_12];
1292 tmp[idx_02] = t[idx_01] * t[idx_12] - t[idx_02] * t[idx_11];
1293 tmp[idx_11] = t[idx_00] * t[idx_22] - t[idx_02] * t[idx_02];
1294 tmp[idx_12] = -t[idx_00] * t[idx_12] + t[idx_01] * t[idx_02];
1295 tmp[idx_22] = t[idx_00] * t[idx_11] - t[idx_01] * t[idx_01];
1303 template <
typename Number>
1304 struct Inverse<4, 1, Number>
1306 constexpr static inline ::SymmetricTensor<4, 1, Number>
1307 value(const ::SymmetricTensor<4, 1, Number> &t)
1310 tmp.
data[0][0] = 1.0 / t.data[0][0];
1316 template <
typename Number>
1317 struct Inverse<4, 2, Number>
1319 constexpr static inline ::SymmetricTensor<4, 2, Number>
1320 value(const ::SymmetricTensor<4, 2, Number> &t)
1346 const Number t4 = t.
data[0][0] * t.data[1][1],
1347 t6 = t.data[0][0] * t.data[1][2],
1348 t8 = t.data[0][1] * t.data[1][0],
1349 t00 = t.data[0][2] * t.data[1][0],
1350 t01 = t.data[0][1] * t.data[2][0],
1351 t04 = t.data[0][2] * t.data[2][0],
1352 t07 = 1.0 / (t4 * t.data[2][2] - t6 * t.data[2][1] -
1353 t8 * t.data[2][2] + t00 * t.data[2][1] +
1354 t01 * t.data[1][2] - t04 * t.data[1][1]);
1356 (t.data[1][1] * t.data[2][2] - t.data[1][2] * t.data[2][1]) * t07;
1358 -(t.data[0][1] * t.data[2][2] - t.data[0][2] * t.data[2][1]) * t07;
1360 -(-t.data[0][1] * t.data[1][2] + t.data[0][2] * t.data[1][1]) * t07;
1362 -(t.data[1][0] * t.data[2][2] - t.data[1][2] * t.data[2][0]) * t07;
1363 tmp.
data[1][1] = (t.data[0][0] * t.data[2][2] - t04) * t07;
1364 tmp.
data[1][2] = -(t6 - t00) * t07;
1366 -(-t.data[1][0] * t.data[2][1] + t.data[1][1] * t.data[2][0]) * t07;
1367 tmp.
data[2][1] = -(t.data[0][0] * t.data[2][1] - t01) * t07;
1368 tmp.
data[2][2] = (t4 - t8) * t07;
1372 tmp.
data[2][0] /= 2;
1373 tmp.
data[2][1] /= 2;
1374 tmp.
data[0][2] /= 2;
1375 tmp.
data[1][2] /= 2;
1376 tmp.
data[2][2] /= 4;
1383 template <
typename Number>
1384 struct Inverse<4, 3, Number>
1386 static ::SymmetricTensor<4, 3, Number>
1387 value(const ::SymmetricTensor<4, 3, Number> &t)
1397 const unsigned int N = 6;
1403 for (
unsigned int i = 0; i <
N; ++i)
1405 const Number typical_diagonal_element =
1406 diagonal_sum /
static_cast<double>(
N);
1407 (void)typical_diagonal_element;
1410 for (
unsigned int i = 0; i <
N; ++i)
1413 for (
unsigned int j = 0; j <
N; ++j)
1419 for (
unsigned int i = j + 1; i <
N; ++i)
1427 Assert(
max > 1.e-16 * typical_diagonal_element,
1428 ExcMessage(
"This tensor seems to be noninvertible"));
1433 for (
unsigned int k = 0; k <
N; ++k)
1440 const Number hr = 1. / tmp.
data[j][j];
1441 tmp.
data[j][j] = hr;
1442 for (
unsigned int k = 0; k <
N; ++k)
1446 for (
unsigned int i = 0; i <
N; ++i)
1450 tmp.
data[i][k] -= tmp.
data[i][j] * tmp.
data[j][k] * hr;
1453 for (
unsigned int i = 0; i <
N; ++i)
1455 tmp.
data[i][j] *= hr;
1456 tmp.
data[j][i] *= -hr;
1458 tmp.
data[j][j] = hr;
1463 for (
unsigned int i = 0; i <
N; ++i)
1465 for (
unsigned int k = 0; k <
N; ++k)
1466 hv[p[k]] = tmp.
data[i][k];
1467 for (
unsigned int k = 0; k <
N; ++k)
1468 tmp.
data[i][k] = hv[k];
1473 for (
unsigned int i = 3; i < 6; ++i)
1474 for (
unsigned int j = 0; j < 3; ++j)
1475 tmp.
data[i][j] /= 2;
1477 for (
unsigned int i = 0; i < 3; ++i)
1478 for (
unsigned int j = 3; j < 6; ++j)
1479 tmp.
data[i][j] /= 2;
1481 for (
unsigned int i = 3; i < 6; ++i)
1482 for (
unsigned int j = 3; j < 6; ++j)
1483 tmp.
data[i][j] /= 4;
1494template <
int rank_,
int dim,
typename Number>
1498 return internal::SymmetricTensorImplementation::convert_to_tensor(*
this);
1503template <
int rank_,
int dim,
typename Number>
1508 return data == t.
data;
1513template <
int rank_,
int dim,
typename Number>
1518 return data != t.
data;
1523template <
int rank_,
int dim,
typename Number>
1524template <
typename OtherNumber>
1535template <
int rank_,
int dim,
typename Number>
1536template <
typename OtherNumber>
1547template <
int rank_,
int dim,
typename Number>
1548template <
typename OtherNumber>
1558template <
int rank_,
int dim,
typename Number>
1559template <
typename OtherNumber>
1569template <
int rank_,
int dim,
typename Number>
1580template <
int rank_,
int dim,
typename Number>
1589template <
int rank_,
int dim,
typename Number>
1590constexpr std::size_t
1602 template <
int dim,
typename Number,
typename OtherNumber = Number>
1606 perform_double_contraction(
1607 const typename SymmetricTensorAccessors::StorageType<2, dim, Number>::
1608 base_tensor_type &data,
1609 const typename SymmetricTensorAccessors::
1610 StorageType<2, dim, OtherNumber>::base_tensor_type &sdata)
1618 return data[0] * sdata[0];
1623 result_type
sum = data[dim] * sdata[dim];
1624 for (
unsigned int d = dim + 1;
d < (dim * (dim + 1) / 2); ++
d)
1625 sum += data[
d] * sdata[
d];
1629 for (
unsigned int d = 0;
d < dim; ++
d)
1630 sum += data[
d] * sdata[
d];
1637 template <
int dim,
typename Number,
typename OtherNumber = Number>
1641 perform_double_contraction(
1642 const typename SymmetricTensorAccessors::StorageType<4, dim, Number>::
1643 base_tensor_type &data,
1644 const typename SymmetricTensorAccessors::
1645 StorageType<2, dim, OtherNumber>::base_tensor_type &sdata)
1652 const unsigned int data_dim = SymmetricTensorAccessors::
1653 StorageType<2, dim, value_type>::n_independent_components;
1654 value_type tmp[data_dim]{};
1655 for (
unsigned int i = 0; i < data_dim; ++i)
1657 perform_double_contraction<dim, Number, OtherNumber>(data[i], sdata);
1658 return result_type(tmp);
1663 template <
int dim,
typename Number,
typename OtherNumber = Number>
1665 typename SymmetricTensorAccessors::StorageType<
1671 perform_double_contraction(
1672 const typename SymmetricTensorAccessors::StorageType<2, dim, Number>::
1673 base_tensor_type &data,
1674 const typename SymmetricTensorAccessors::
1675 StorageType<4, dim, OtherNumber>::base_tensor_type &sdata)
1679 using base_tensor_type =
typename SymmetricTensorAccessors::
1680 StorageType<2, dim, value_type>::base_tensor_type;
1682 base_tensor_type tmp;
1683 for (
unsigned int i = 0; i < tmp.dimension; ++i)
1686 value_type
sum = data[dim] * sdata[dim][i];
1687 for (
unsigned int d = dim + 1;
d < (dim * (dim + 1) / 2); ++
d)
1688 sum += data[
d] * sdata[
d][i];
1692 for (
unsigned int d = 0;
d < dim; ++
d)
1693 sum += data[
d] * sdata[
d][i];
1701 template <
int dim,
typename Number,
typename OtherNumber = Number>
1703 typename SymmetricTensorAccessors::StorageType<
1709 perform_double_contraction(
1710 const typename SymmetricTensorAccessors::StorageType<4, dim, Number>::
1711 base_tensor_type &data,
1712 const typename SymmetricTensorAccessors::
1713 StorageType<4, dim, OtherNumber>::base_tensor_type &sdata)
1717 using base_tensor_type =
typename SymmetricTensorAccessors::
1718 StorageType<4, dim, value_type>::base_tensor_type;
1720 const unsigned int data_dim = SymmetricTensorAccessors::
1721 StorageType<2, dim, value_type>::n_independent_components;
1722 base_tensor_type tmp;
1723 for (
unsigned int i = 0; i < data_dim; ++i)
1724 for (
unsigned int j = 0; j < data_dim; ++j)
1727 for (
unsigned int d = dim;
d < (dim * (dim + 1) / 2); ++
d)
1728 tmp[i][j] += data[i][
d] * sdata[
d][j];
1729 tmp[i][j] += tmp[i][j];
1732 for (
unsigned int d = 0;
d < dim; ++
d)
1733 tmp[i][j] += data[i][
d] * sdata[
d][j];
1742template <
int rank_,
int dim,
typename Number>
1743template <
typename OtherNumber>
1754 return internal::perform_double_contraction<dim, Number, OtherNumber>(data,
1760template <
int rank_,
int dim,
typename Number>
1761template <
typename OtherNumber>
1770 internal::perform_double_contraction<dim, Number, OtherNumber>(data,
1793 template <
typename Type>
1794 struct Uninitialized
1799 template <
typename Type>
1800 Type Uninitialized<Type>::value;
1802 template <
int dim,
typename Number>
1805 typename SymmetricTensorAccessors::
1806 StorageType<2, dim, Number>::base_tensor_type &data)
1814 if (indices[0] == indices[1])
1815 return data[indices[0]];
1822 Assert(((indices[0] == 1) && (indices[1] == 0)) ||
1823 ((indices[0] == 0) && (indices[1] == 1)),
1832 for (
unsigned int d = 0, c = 0;
d < dim; ++
d)
1833 for (
unsigned int e =
d + 1;
e < dim; ++
e, ++c)
1834 if ((sorted_indices[0] ==
d) && (sorted_indices[1] ==
e))
1835 return data[dim + c];
1843 return Uninitialized<Number>::value;
1848 template <
int dim,
typename Number>
1851 const typename SymmetricTensorAccessors::
1852 StorageType<2, dim, Number>::base_tensor_type &data)
1860 if (indices[0] == indices[1])
1861 return data[indices[0]];
1868 Assert(((indices[0] == 1) && (indices[1] == 0)) ||
1869 ((indices[0] == 0) && (indices[1] == 1)),
1878 for (
unsigned int d = 0, c = 0;
d < dim; ++
d)
1879 for (
unsigned int e =
d + 1;
e < dim; ++
e, ++c)
1880 if ((sorted_indices[0] ==
d) && (sorted_indices[1] ==
e))
1881 return data[dim + c];
1889 return Uninitialized<Number>::value;
1894 template <
int dim,
typename Number>
1895 constexpr inline Number &
1897 typename SymmetricTensorAccessors::
1898 StorageType<4, dim, Number>::base_tensor_type &data)
1912 constexpr std::size_t base_index[2][2] = {{0, 2}, {2, 1}};
1913 return data[base_index[indices[0]][indices[1]]]
1914 [base_index[indices[2]][indices[3]]];
1923 constexpr std::size_t base_index[3][3] = {{0, 3, 4},
1926 return data[base_index[indices[0]][indices[1]]]
1927 [base_index[indices[2]][indices[3]]];
1937 return Uninitialized<Number>::value;
1941 template <
int dim,
typename Number>
1944 const typename SymmetricTensorAccessors::
1945 StorageType<4, dim, Number>::base_tensor_type &data)
1959 constexpr std::size_t base_index[2][2] = {{0, 2}, {2, 1}};
1960 return data[base_index[indices[0]][indices[1]]]
1961 [base_index[indices[2]][indices[3]]];
1970 constexpr std::size_t base_index[3][3] = {{0, 3, 4},
1973 return data[base_index[indices[0]][indices[1]]]
1974 [base_index[indices[2]][indices[3]]];
1984 return Uninitialized<Number>::value;
1991template <
int rank_,
int dim,
typename Number>
1996 for (
unsigned int r = 0; r < rank; ++r)
1998 return internal::symmetric_tensor_access<dim, Number>(indices, data);
2003template <
int rank_,
int dim,
typename Number>
2008 for (
unsigned int r = 0; r < rank; ++r)
2010 return internal::symmetric_tensor_access<dim, Number>(indices, data);
2017 namespace SymmetricTensorImplementation
2019 template <
int rank_>
2021 get_partially_filled_indices(
const unsigned int row,
2022 const std::integral_constant<int, 2> &)
2028 template <
int rank_>
2030 get_partially_filled_indices(
const unsigned int row,
2031 const std::integral_constant<int, 4> &)
2042template <
int rank_,
int dim,
typename Number>
2044 Accessor<rank_, dim,
true, rank_ - 1, Number>
2048 return internal::SymmetricTensorAccessors::
2049 Accessor<rank_, dim,
true, rank_ - 1, Number>(
2051 internal::SymmetricTensorImplementation::get_partially_filled_indices<
2052 rank_>(row, std::integral_constant<int, rank_>()));
2057template <
int rank_,
int dim,
typename Number>
2059 Accessor<rank_, dim,
false, rank_ - 1, Number>
2062 return internal::SymmetricTensorAccessors::
2063 Accessor<rank_, dim,
false, rank_ - 1, Number>(
2065 internal::SymmetricTensorImplementation::get_partially_filled_indices<
2066 rank_>(row, std::integral_constant<int, rank_>()));
2071template <
int rank_,
int dim,
typename Number>
2076 return operator()(indices);
2081template <
int rank_,
int dim,
typename Number>
2086 return operator()(indices);
2091template <
int rank_,
int dim,
typename Number>
2095 return std::addressof(this->access_raw_entry(0));
2100template <
int rank_,
int dim,
typename Number>
2101inline const Number *
2104 return std::addressof(this->access_raw_entry(0));
2109template <
int rank_,
int dim,
typename Number>
2113 return begin_raw() + n_independent_components;
2118template <
int rank_,
int dim,
typename Number>
2119inline const Number *
2122 return begin_raw() + n_independent_components;
2129 namespace SymmetricTensorImplementation
2131 template <
int dim,
typename Number>
2132 constexpr unsigned int
2133 entry_to_indices(const ::SymmetricTensor<2, dim, Number> &,
2134 const unsigned int index)
2140 template <
int dim,
typename Number>
2141 constexpr ::TableIndices<2>
2142 entry_to_indices(const ::SymmetricTensor<4, dim, Number> &,
2143 const unsigned int index)
2154template <
int rank_,
int dim,
typename Number>
2155constexpr inline const Number &
2157 const unsigned int index)
const
2160 return data[internal::SymmetricTensorImplementation::entry_to_indices(*
this,
2166template <
int rank_,
int dim,
typename Number>
2167constexpr inline Number &
2171 return data[internal::SymmetricTensorImplementation::entry_to_indices(*
this,
2179 template <
int dim,
typename Number>
2181 compute_norm(
const typename SymmetricTensorAccessors::
2182 StorageType<2, dim, Number>::base_tensor_type &data)
2209 for (
unsigned int d = 0;
d < dim; ++
d)
2212 for (
unsigned int d = dim;
d < (dim * dim + dim) / 2; ++
d)
2223 template <
int dim,
typename Number>
2225 compute_norm(
const typename SymmetricTensorAccessors::
2226 StorageType<4, dim, Number>::base_tensor_type &data)
2238 const unsigned int n_independent_components = data.dimension;
2240 for (
unsigned int i = 0; i < dim; ++i)
2241 for (
unsigned int j = 0; j < dim; ++j)
2244 for (
unsigned int i = 0; i < dim; ++i)
2245 for (
unsigned int j = dim; j < n_independent_components; ++j)
2248 for (
unsigned int i = dim; i < n_independent_components; ++i)
2249 for (
unsigned int j = 0; j < dim; ++j)
2252 for (
unsigned int i = dim; i < n_independent_components; ++i)
2253 for (
unsigned int j = dim; j < n_independent_components; ++j)
2266template <
int rank_,
int dim,
typename Number>
2270 return internal::compute_norm<dim, Number>(data);
2277 namespace SymmetricTensorImplementation
2300 constexpr unsigned int table[2][2] = {{0, 2}, {2, 1}};
2301 return table[indices[0]][indices[1]];
2306 constexpr unsigned int table[3][3] = {{0, 3, 4},
2309 return table[indices[0]][indices[1]];
2314 constexpr unsigned int table[4][4] = {{0, 4, 5, 6},
2318 return table[indices[0]][indices[1]];
2324 if (indices[0] == indices[1])
2328 sorted_indices.sort();
2330 for (
unsigned int d = 0, c = 0;
d < dim; ++
d)
2331 for (
unsigned int e =
d + 1;
e < dim; ++
e, ++c)
2332 if ((sorted_indices[0] ==
d) && (sorted_indices[1] ==
e))
2348 template <
int dim,
int rank_>
2349 constexpr inline unsigned int
2360template <
int rank_,
int dim,
typename Number>
2361constexpr unsigned int
2365 return internal::SymmetricTensorImplementation::component_to_unrolled_index<
2373 namespace SymmetricTensorImplementation
2385 const std::integral_constant<int, 2> &)
2423 for (
unsigned int d = 0, c = dim;
d < dim; ++
d)
2424 for (
unsigned int e =
d + 1;
e < dim; ++
e, ++c)
2442 template <
int dim,
int rank_>
2444 typename std::enable_if<rank_ != 2, TableIndices<rank_>>::type
2446 const std::integral_constant<int, rank_> &)
2455 n_independent_components));
2463template <
int rank_,
int dim,
typename Number>
2466 const unsigned int i)
2468 return internal::SymmetricTensorImplementation::unrolled_to_component_indices<
2469 dim>(i, std::integral_constant<int, rank_>());
2474template <
int rank_,
int dim,
typename Number>
2475template <
class Archive>
2500template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2525template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2545template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2562template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2579template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2596template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2620template <
int dim,
typename Number>
2636 return (tmp + tmp + t.
data[0] * t.
data[1] * t.
data[2] -
2660template <
int dim,
typename Number>
2678template <
int dim,
typename Number>
2682 Number t =
d.data[0];
2683 for (
unsigned int i = 1; i < dim; ++i)
2700template <
int dim,
typename Number>
2719template <
typename Number>
2746template <
typename Number>
2750 return t[0][0] * t[1][1] - t[0][1] * t[0][1];
2763template <
typename Number>
2767 return (t[0][0] * t[1][1] + t[1][1] * t[2][2] + t[2][2] * t[0][0] -
2768 t[0][1] * t[0][1] - t[0][2] * t[0][2] - t[1][2] * t[1][2]);
2780template <
typename Number>
2781std::array<Number, 1>
2808template <
typename Number>
2809std::array<Number, 2>
2836template <
typename Number>
2837std::array<Number, 3>
2844 namespace SymmetricTensorImplementation
2883 template <
int dim,
typename Number>
2887 std::array<Number, dim> &
d,
2888 std::array<Number, dim - 1> &
e);
2931 template <
int dim,
typename Number>
2932 std::array<std::pair<Number, Tensor<1, dim, Number>>, dim>
2976 template <
int dim,
typename Number>
2977 std::array<std::pair<Number, Tensor<1, dim, Number>>, dim>
2995 template <
typename Number>
2996 std::array<std::pair<Number, Tensor<1, 2, Number>>, 2>
3033 template <
typename Number>
3034 std::array<std::pair<Number, Tensor<1, 3, Number>>, 3>
3041 template <
int dim,
typename Number>
3048 return lhs.first > rhs.first;
3151template <
int dim,
typename Number>
3152std::array<std::pair<Number, Tensor<1, dim, Number>>,
3153 std::integral_constant<int, dim>::value>
3168template <
int rank_,
int dim,
typename Number>
3187template <
int dim,
typename Number>
3194 const Number tr =
trace(t) / dim;
3195 for (
unsigned int i = 0; i < dim; ++i)
3209template <
int dim,
typename Number>
3229 for (
unsigned int d = 0;
d < dim; ++
d)
3248 return unit_symmetric_tensor<dim, double>();
3281template <
int dim,
typename Number>
3288 for (
unsigned int i = 0; i < dim; ++i)
3289 for (
unsigned int j = 0; j < dim; ++j)
3298 for (
unsigned int i = dim;
3299 i < internal::SymmetricTensorAccessors::StorageType<4, dim, Number>::
3320 return deviator_tensor<dim, double>();
3362template <
int dim,
typename Number>
3369 for (
unsigned int i = 0; i < dim; ++i)
3377 for (
unsigned int i = dim;
3378 i < internal::SymmetricTensorAccessors::StorageType<4, dim, Number>::
3399 return identity_tensor<dim, double>();
3413template <
int dim,
typename Number>
3433template <
int dim,
typename Number>
3464template <
int dim,
typename Number>
3472 for (
unsigned int i = 0; i < dim; ++i)
3473 for (
unsigned int j = i; j < dim; ++j)
3474 for (
unsigned int k = 0; k < dim; ++k)
3475 for (
unsigned int l = k;
l < dim; ++
l)
3476 tmp[i][j][k][
l] = t1[i][j] * t2[k][
l];
3490template <
int dim,
typename Number>
3495 for (
unsigned int d = 0;
d < dim; ++
d)
3496 result[
d][
d] = t[
d][
d];
3499 for (
unsigned int d = 0;
d < dim; ++
d)
3500 for (
unsigned int e =
d + 1;
e < dim; ++
e)
3501 result[
d][
e] = (t[
d][
e] + t[
e][
d]) * half;
3514template <
int rank_,
int dim,
typename Number>
3532template <
int rank_,
int dim,
typename Number>
3567template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
3574 const OtherNumber & factor)
3597template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
3607 return (t * factor);
3617template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
3624 const OtherNumber & factor)
3640template <
int rank_,
int dim>
3657template <
int rank_,
int dim>
3673template <
int rank_,
int dim>
3691template <
int dim,
typename Number,
typename OtherNumber>
3713template <
int dim,
typename Number,
typename OtherNumber>
3721 for (
unsigned int i = 0; i < dim; ++i)
3722 for (
unsigned int j = 0; j < dim; ++j)
3723 s += t1[i][j] * t2[i][j];
3741template <
int dim,
typename Number,
typename OtherNumber>
3764template <
typename Number,
typename OtherNumber>
3770 tmp[0][0] = t[0][0][0][0] * s[0][0];
3789template <
typename Number,
typename OtherNumber>
3795 tmp[0][0] = t[0][0][0][0] * s[0][0];
3814template <
typename Number,
typename OtherNumber>
3820 const unsigned int dim = 2;
3822 for (
unsigned int i = 0; i < dim; ++i)
3823 for (
unsigned int j = i; j < dim; ++j)
3824 tmp[i][j] = t[i][j][0][0] * s[0][0] + t[i][j][1][1] * s[1][1] +
3825 2 * t[i][j][0][1] * s[0][1];
3844template <
typename Number,
typename OtherNumber>
3850 const unsigned int dim = 2;
3852 for (
unsigned int i = 0; i < dim; ++i)
3853 for (
unsigned int j = i; j < dim; ++j)
3854 tmp[i][j] = s[0][0] * t[0][0][i][j] * +s[1][1] * t[1][1][i][j] +
3855 2 * s[0][1] * t[0][1][i][j];
3874template <
typename Number,
typename OtherNumber>
3880 const unsigned int dim = 3;
3882 for (
unsigned int i = 0; i < dim; ++i)
3883 for (
unsigned int j = i; j < dim; ++j)
3884 tmp[i][j] = t[i][j][0][0] * s[0][0] + t[i][j][1][1] * s[1][1] +
3885 t[i][j][2][2] * s[2][2] + 2 * t[i][j][0][1] * s[0][1] +
3886 2 * t[i][j][0][2] * s[0][2] + 2 * t[i][j][1][2] * s[1][2];
3905template <
typename Number,
typename OtherNumber>
3911 const unsigned int dim = 3;
3913 for (
unsigned int i = 0; i < dim; ++i)
3914 for (
unsigned int j = i; j < dim; ++j)
3915 tmp[i][j] = s[0][0] * t[0][0][i][j] + s[1][1] * t[1][1][i][j] +
3916 s[2][2] * t[2][2][i][j] + 2 * s[0][1] * t[0][1][i][j] +
3917 2 * s[0][2] * t[0][2][i][j] + 2 * s[1][2] * t[1][2][i][j];
3928template <
int dim,
typename Number,
typename OtherNumber>
3934 for (
unsigned int i = 0; i < dim; ++i)
3935 for (
unsigned int j = 0; j < dim; ++j)
3936 dest[i] += src1[i][j] * src2[j];
3947template <
int dim,
typename Number,
typename OtherNumber>
3977template <
int rank_1,
3981 typename OtherNumber>
3983 typename Tensor<rank_1 + rank_2 - 2,
4013template <
int rank_1,
4017 typename OtherNumber>
4019 typename Tensor<rank_1 + rank_2 - 2,
4039template <
int dim,
typename Number>
4040inline std::ostream &
4048 for (
unsigned int i = 0; i < dim; ++i)
4049 for (
unsigned int j = 0; j < dim; ++j)
4066template <
int dim,
typename Number>
4067inline std::ostream &
4075 for (
unsigned int i = 0; i < dim; ++i)
4076 for (
unsigned int j = 0; j < dim; ++j)
4077 for (
unsigned int k = 0; k < dim; ++k)
4078 for (
unsigned int l = 0;
l < dim; ++
l)
4079 tt[i][j][k][
l] = t[i][j][k][
l];
OutputOperator< VectorType > & operator<<(OutputOperator< VectorType > &out, unsigned int step)
constexpr bool operator==(const SymmetricTensor &) const
constexpr Number first_invariant(const SymmetricTensor< 2, dim, Number > &t)
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)
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)
constexpr ProductType< Number, OtherNumber >::type scalar_product(const Tensor< 2, dim, Number > &t1, const SymmetricTensor< 2, dim, OtherNumber > &t2)
constexpr SymmetricTensor< 4, dim, Number > invert(const SymmetricTensor< 4, dim, Number > &t)
constexpr SymmetricTensor< rank_, dim > operator*(const SymmetricTensor< rank_, dim > &t, const double factor)
constexpr Tensor< 1, dim, typename ProductType< Number, OtherNumber >::type > operator*(const SymmetricTensor< 2, dim, Number > &src1, const Tensor< 1, dim, OtherNumber > &src2)
constexpr SymmetricTensor< 2, dim, Number > symmetrize(const Tensor< 2, dim, Number > &t)
constexpr SymmetricTensor(const Number(&array)[n_independent_components])
friend constexpr SymmetricTensor< 2, dim2, Number2 > unit_symmetric_tensor()
constexpr Tensor< rank_, dim, typename ProductType< Number, OtherNumber >::type > operator-(const SymmetricTensor< rank_, dim, Number > &left, const Tensor< rank_, dim, OtherNumber > &right)
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 constexpr unsigned int component_to_unrolled_index(const TableIndices< rank_ > &indices)
constexpr SymmetricTensor< 2, dim, Number > invert(const SymmetricTensor< 2, dim, Number > &t)
constexpr Tensor< 1, dim, typename ProductType< Number, OtherNumber >::type > operator*(const Tensor< 1, dim, Number > &src1, const SymmetricTensor< 2, dim, OtherNumber > &src2)
std::array< Number, 2 > eigenvalues(const SymmetricTensor< 2, 2, Number > &T)
friend class SymmetricTensor
void serialize(Archive &ar, const unsigned int version)
constexpr Tensor< rank_, dim, typename ProductType< Number, OtherNumber >::type > operator-(const Tensor< rank_, dim, Number > &left, const SymmetricTensor< rank_, dim, OtherNumber > &right)
friend constexpr Number2 determinant(const SymmetricTensor< 2, dim2, Number2 > &t)
const Number * begin_raw() const
const Number * end_raw() const
std::array< Number, 1 > eigenvalues(const SymmetricTensor< 2, 1, Number > &T)
constexpr internal::SymmetricTensorAccessors::Accessor< rank_, dim, false, rank_ - 1, Number > operator[](const unsigned int row)
typename base_tensor_descriptor::base_tensor_type base_tensor_type
constexpr const Number & operator()(const TableIndices< rank_ > &indices) const
constexpr bool operator!=(const SymmetricTensor &) const
constexpr Number & operator[](const TableIndices< rank_ > &indices)
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)
constexpr SymmetricTensor< rank_, dim, typename ProductType< Number, typename EnableIfScalar< OtherNumber >::type >::type > operator/(const SymmetricTensor< rank_, dim, Number > &t, const OtherNumber &factor)
static constexpr std::size_t memory_consumption()
constexpr ProductType< Number, OtherNumber >::type scalar_product(const SymmetricTensor< 2, dim, Number > &t1, const Tensor< 2, dim, OtherNumber > &t2)
friend constexpr SymmetricTensor< 2, dim2, Number2 > deviator(const SymmetricTensor< 2, dim2, Number2 > &t)
friend constexpr Number2 trace(const SymmetricTensor< 2, dim2, Number2 > &d)
constexpr SymmetricTensor< 2, dim, Number > deviator(const SymmetricTensor< 2, dim, Number > &t)
constexpr Tensor< rank_, dim, typename ProductType< Number, OtherNumber >::type > operator+(const SymmetricTensor< rank_, dim, Number > &left, const Tensor< rank_, dim, OtherNumber > &right)
constexpr Number determinant(const SymmetricTensor< 2, dim, Number > &t)
constexpr const Number & operator[](const TableIndices< rank_ > &indices) const
constexpr SymmetricTensor & operator=(const Number &d)
SymmetricTensor(const Tensor< 2, dim, OtherNumber > &t)
static constexpr TableIndices< rank_ > unrolled_to_component_indices(const unsigned int i)
constexpr SymmetricTensor< 4, dim, Number > outer_product(const SymmetricTensor< 2, dim, Number > &t1, const SymmetricTensor< 2, dim, Number > &t2)
friend constexpr SymmetricTensor< 4, dim2, Number2 > identity_tensor()
constexpr Number & access_raw_entry(const unsigned int unrolled_index)
constexpr Number trace(const SymmetricTensor< 2, dim, Number > &d)
constexpr numbers::NumberTraits< Number >::real_type norm() const
constexpr SymmetricTensor operator-() const
constexpr internal::SymmetricTensorAccessors::double_contraction_result< rank_, 2, dim, Number, OtherNumber >::type operator*(const SymmetricTensor< 2, dim, OtherNumber > &s) const
constexpr SymmetricTensor()=default
std::array< std::pair< Number, Tensor< 1, dim, Number > >, std::integral_constant< int, dim >::value > eigenvectors(const SymmetricTensor< 2, dim, Number > &T, const SymmetricTensorEigenvectorMethod method=SymmetricTensorEigenvectorMethod::ql_implicit_shifts)
constexpr Number second_invariant(const SymmetricTensor< 2, 1, Number > &)
constexpr Number third_invariant(const SymmetricTensor< 2, dim, Number > &t)
constexpr SymmetricTensor(const SymmetricTensor< rank_, dim, OtherNumber > &initializer)
constexpr SymmetricTensor & operator-=(const SymmetricTensor< rank_, dim, OtherNumber > &)
constexpr SymmetricTensor< rank_, dim, Number > operator*(const Number &factor, const SymmetricTensor< rank_, dim, Number > &t)
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)
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)
constexpr ProductType< Number, OtherNumber >::type scalar_product(const SymmetricTensor< 2, dim, Number > &t1, const SymmetricTensor< 2, dim, OtherNumber > &t2)
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)
friend constexpr SymmetricTensor< 4, dim2, Number2 > deviator_tensor()
constexpr SymmetricTensor< rank_, dim, typename ProductType< Number, OtherNumber >::type > operator-(const SymmetricTensor< rank_, dim, Number > &left, const SymmetricTensor< rank_, dim, OtherNumber > &right)
constexpr SymmetricTensor< rank_, dim, typename ProductType< Number, OtherNumber >::type > operator+(const SymmetricTensor< rank_, dim, Number > &left, const SymmetricTensor< rank_, dim, OtherNumber > &right)
constexpr Number second_invariant(const SymmetricTensor< 2, 3, Number > &t)
constexpr SymmetricTensor< rank_, dim, Number > operator*(const SymmetricTensor< rank_, dim, Number > &t, const Number &factor)
constexpr const Number & access_raw_entry(const unsigned int unrolled_index) const
constexpr SymmetricTensor & operator=(const SymmetricTensor< rank_, dim, OtherNumber > &rhs)
constexpr SymmetricTensor< rank_, dim, Number > transpose(const SymmetricTensor< rank_, dim, Number > &t)
constexpr SymmetricTensor< rank_, dim > operator*(const double factor, const SymmetricTensor< rank_, dim > &t)
constexpr SymmetricTensor & operator/=(const OtherNumber &factor)
constexpr Tensor< rank_, dim, typename ProductType< Number, OtherNumber >::type > operator+(const Tensor< rank_, dim, Number > &left, const SymmetricTensor< rank_, dim, OtherNumber > &right)
constexpr Number second_invariant(const SymmetricTensor< 2, 2, Number > &t)
constexpr SymmetricTensor & operator+=(const SymmetricTensor< rank_, dim, OtherNumber > &)
constexpr internal::SymmetricTensorAccessors::double_contraction_result< rank_, 4, dim, Number, OtherNumber >::type operator*(const SymmetricTensor< 4, dim, OtherNumber > &s) const
constexpr SymmetricTensor< rank_, dim > operator/(const SymmetricTensor< rank_, dim > &t, const double factor)
std::array< Number, 3 > eigenvalues(const SymmetricTensor< 2, 3, Number > &T)
constexpr internal::SymmetricTensorAccessors::Accessor< rank_, dim, true, rank_ - 1, Number > operator[](const unsigned int row) const
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)
constexpr SymmetricTensor & operator*=(const OtherNumber &factor)
constexpr Number & operator()(const TableIndices< rank_ > &indices)
typename AccessorTypes< rank, dim, constness, Number >::reference reference
constexpr reference operator[](const unsigned int) const
const TableIndices< rank > previous_indices
constexpr Accessor(const Accessor &)=default
constexpr Accessor(tensor_type &tensor, const TableIndices< rank > &previous_indices)
constexpr reference operator[](const unsigned int)
typename AccessorTypes< rank, dim, constness, Number >::tensor_type tensor_type
const TableIndices< rank > previous_indices
typename AccessorTypes< rank, dim, constness, Number >::tensor_type tensor_type
constexpr Accessor< rank, dim, constness, P - 1, Number > operator[](const unsigned int i)
constexpr Accessor(tensor_type &tensor, const TableIndices< rank > &previous_indices)
constexpr Accessor(const Accessor &)=default
typename AccessorTypes< rank, dim, constness, Number >::reference reference
constexpr Accessor< rank, dim, constness, P - 1, Number > operator[](const unsigned int i) const
#define DEAL_II_ALWAYS_INLINE
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_CONSTEXPR
#define DEAL_II_NAMESPACE_CLOSE
static ::ExceptionBase & ExcNotImplemented()
static ::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
#define Assert(cond, exc)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcMessage(std::string arg1)
Expression fabs(const Expression &x)
void swap(MemorySpaceData< Number, MemorySpace > &, MemorySpaceData< Number, MemorySpace > &)
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)
constexpr TableIndices< 2 > merge(const TableIndices< 2 > &previous_indices, const unsigned int new_index, const unsigned int position)
constexpr TableIndices< 4 > merge(const TableIndices< 4 > &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 > &)
constexpr SymmetricTensor< rank_, dim, typename ProductType< OtherNumber, typename EnableIfScalar< Number >::type >::type > operator*(const Number &factor, const SymmetricTensor< rank_, dim, OtherNumber > &t)
constexpr SymmetricTensor< rank_, dim, typename ProductType< Number, typename EnableIfScalar< OtherNumber >::type >::type > operator*(const SymmetricTensor< rank_, dim, Number > &t, const OtherNumber &factor)
typename internal::ProductTypeImpl< typename std::decay< T >::type, typename std::decay< U >::type >::type type
static constexpr const T & value(const T &t)
typename ProductType< Number, OtherNumber >::type type
typename ProductType< Number, OtherNumber >::type value_type
::SymmetricTensor< rank1+rank2 - 4, dim, value_type > type
std::pair< Number, Tensor< 1, dim, Number > > EigValsVecs
bool operator()(const EigValsVecs &lhs, const EigValsVecs &rhs)
static real_type abs(const number &x)
constexpr SymmetricTensor< 4, dim, Number > deviator_tensor()
constexpr SymmetricTensor< 4, dim, Number > identity_tensor()
SymmetricTensorEigenvectorMethod
constexpr SymmetricTensor< 2, dim, Number > unit_symmetric_tensor()