16#ifndef dealii_symmetric_tensor_h
17#define dealii_symmetric_tensor_h
33template <
int rank,
int dim,
typename Number =
double>
43template <
int dim,
typename Number =
double>
75template <
int dim,
typename Number =
double>
116template <
int dim,
typename Number =
double>
120template <
int dim,
typename Number>
124template <
int dim,
typename Number>
128template <
int dim2,
typename Number>
132template <
int dim,
typename Number>
136template <
int dim,
typename Number>
148 template <
int rank,
int dim,
typename T,
typename U>
154 std::complex<typename ProductType<T, U>::type>>;
157 template <
int rank,
int dim,
typename T,
typename U>
164 std::complex<typename ProductType<T, U>::type>>;
167 template <
typename T,
int rank,
int dim,
typename U>
173 std::complex<typename ProductType<T, U>::type>>;
176 template <
int rank,
int dim,
typename T,
typename U>
183 std::complex<typename ProductType<T, U>::type>>;
191 namespace SymmetricTensorImplementation
197 template <
int rank,
int dim,
typename Number>
205 namespace SymmetricTensorAccessors
215 const unsigned int new_index,
216 const unsigned int position)
223 return {previous_indices[0], new_index};
236 const unsigned int new_index,
237 const unsigned int position)
249 return {previous_indices[0],
254 return {previous_indices[0],
259 return {previous_indices[0],
280 typename OtherNumber = Number>
295 template <
int dim,
typename Number,
typename OtherNumber>
315 template <
int rank,
int dim,
typename Number>
321 template <
int dim,
typename Number>
328 static const unsigned int n_independent_components =
329 (dim * dim + dim) / 2;
342 template <
int dim,
typename Number>
350 static const unsigned int n_rank2_components = (dim * dim + dim) / 2;
355 static const unsigned int n_independent_components =
356 (n_rank2_components *
374 template <
int rank,
int dim,
bool constness,
typename Number>
383 template <
int rank,
int dim,
typename Number>
397 template <
int rank,
int dim,
typename Number>
438 template <
int rank,
int dim,
bool constness,
int P,
typename Number>
482 constexpr Accessor<rank, dim, constness, P - 1, Number>
488 constexpr Accessor<rank, dim, constness, P - 1, Number>
500 template <
int,
int,
typename>
501 friend class ::SymmetricTensor;
502 template <
int,
int,
bool,
int,
typename>
504 friend class ::SymmetricTensor<rank, dim, Number>;
505 friend class Accessor<rank, dim, constness, P + 1, Number>;
517 template <
int rank,
int dim,
bool constness,
typename Number>
582 template <
int,
int,
typename>
583 friend class ::SymmetricTensor;
584 template <
int,
int,
bool,
int,
typename>
586 friend class ::SymmetricTensor<rank, dim, Number>;
587 friend class SymmetricTensorAccessors::
588 Accessor<rank, dim, constness, 2, Number>;
667template <int rank_, int dim, typename Number>
671 static_assert(rank_ % 2 == 0,
"A SymmetricTensor must have even rank!");
681 static constexpr unsigned int dimension = dim;
686 static const unsigned int rank = rank_;
693 static constexpr unsigned int n_independent_components =
695 n_independent_components;
716 template <
typename OtherNumber>
741 template <
typename OtherNumber>
753 DEAL_II_DEPRECATED_EARLY
765 DEAL_II_DEPRECATED_EARLY
777 DEAL_II_DEPRECATED_EARLY
790 DEAL_II_DEPRECATED_EARLY
800 template <
typename OtherNumber>
834 template <
typename OtherNumber>
841 template <
typename OtherNumber>
849 template <
typename OtherNumber>
856 template <
typename OtherNumber>
918 template <
typename OtherNumber>
927 template <
typename OtherNumber>
941 constexpr const Number &
948 constexpr internal::SymmetricTensorAccessors::
949 Accessor<rank_, dim,
true, rank_ - 1, Number>
956 constexpr internal::SymmetricTensorAccessors::
957 Accessor<rank_, dim,
false, rank_ - 1, Number>
965 constexpr const Number &
982 constexpr const Number &
1013 static constexpr unsigned int
1043 static constexpr std::size_t
1051 template <
class Archive>
1073 template <
int,
int,
typename>
1077 template <
int dim2,
typename Number2>
1078 friend constexpr Number2
1081 template <
int dim2,
typename Number2>
1085 template <
int dim2,
typename Number2>
1089 template <
int dim2,
typename Number2>
1093 template <
int dim2,
typename Number2>
1097 template <
int dim2,
typename Number2>
1104 Inverse<2, dim, Number>;
1107 Inverse<4, dim, Number>;
1117template <int rank, int dim, typename Number>
1120template <int rank_, int dim, typename Number>
1121constexpr unsigned
int
1126 namespace SymmetricTensorAccessors
1128 template <
int rank_,
int dim,
bool constness,
int P,
typename Number>
1139 template <
int rank_,
int dim,
bool constness,
int P,
typename Number>
1141 Accessor<rank_, dim, constness, P - 1, Number>
1142 Accessor<rank_, dim, constness, P, Number>::operator[](
1143 const unsigned int i)
1145 return Accessor<rank_, dim, constness, P - 1, Number>(
1146 tensor,
merge(previous_indices, i, rank_ - P));
1151 template <
int rank_,
int dim,
bool constness,
int P,
typename Number>
1153 Accessor<rank_, dim, constness, P - 1, Number>
1154 Accessor<rank_, dim, constness, P, Number>::operator[](
1155 const unsigned int i)
const
1157 return Accessor<rank_, dim, constness, P - 1, Number>(
1158 tensor,
merge(previous_indices, i, rank_ - P));
1163 template <
int rank_,
int dim,
bool constness,
typename Number>
1165 Accessor<rank_, dim, constness, 1, Number>::Accessor(
1166 tensor_type & tensor,
1169 , previous_indices(previous_indices)
1174 template <
int rank_,
int dim,
bool constness,
typename Number>
1176 typename Accessor<rank_, dim, constness, 1, Number>::reference
1177 Accessor<rank_, dim, constness, 1, Number>::operator[](
1178 const unsigned int i)
1180 return tensor(
merge(previous_indices, i, rank_ - 1));
1184 template <
int rank_,
int dim,
bool constness,
typename Number>
1186 typename Accessor<rank_, dim, constness, 1, Number>::reference
1187 Accessor<rank_, dim, constness, 1, Number>::operator[](
1188 const unsigned int i)
const
1190 return tensor(
merge(previous_indices, i, rank_ - 1));
1197template <
int rank_,
int dim,
typename Number>
1198template <
typename OtherNumber>
1203 static_assert(rank == 2,
"This function is only implemented for rank==2");
1204 for (
unsigned int d = 0;
d < dim; ++
d)
1205 for (
unsigned int e = 0;
e <
d; ++
e)
1207 ExcMessage(
"The incoming Tensor must be exactly symmetric."));
1209 for (
unsigned int d = 0;
d < dim; ++
d)
1212 for (
unsigned int d = 0, c = 0;
d < dim; ++
d)
1213 for (
unsigned int e =
d + 1;
e < dim; ++
e, ++c)
1214 data[dim + c] = t[
d][
e];
1219template <
int rank_,
int dim,
typename Number>
1220template <
typename OtherNumber>
1224 : data(initializer.data)
1229template <
int rank_,
int dim,
typename Number>
1232 const Number (&array)[n_independent_components])
1234 *reinterpret_cast<const typename base_tensor_type::array_type *>(array))
1237 Assert(
sizeof(
typename base_tensor_type::array_type) ==
sizeof(array),
1243template <
int rank_,
int dim,
typename Number>
1244template <
typename OtherNumber>
1255template <
int rank_,
int dim,
typename Number>
1260 ExcMessage(
"Only assignment with zero is allowed"));
1271 namespace SymmetricTensorImplementation
1273 template <
int dim,
typename Number>
1274 constexpr inline DEAL_II_ALWAYS_INLINE ::Tensor<2, dim, Number>
1275 convert_to_tensor(const ::SymmetricTensor<2, dim, Number> &s)
1280 for (
unsigned int d = 0;
d < dim; ++
d)
1281 t[
d][
d] = s.access_raw_entry(
d);
1284 for (
unsigned int d = 0, c = 0;
d < dim; ++
d)
1285 for (
unsigned int e =
d + 1;
e < dim; ++
e, ++c)
1287 t[
d][
e] = s.access_raw_entry(dim + c);
1288 t[
e][
d] = s.access_raw_entry(dim + c);
1294 template <
int dim,
typename Number>
1295 constexpr ::Tensor<4, dim, Number>
1296 convert_to_tensor(const ::SymmetricTensor<4, dim, Number> &st)
1303 for (
unsigned int i = 0; i < dim; ++i)
1304 for (
unsigned int j = i; j < dim; ++j)
1305 for (
unsigned int k = 0; k < dim; ++k)
1306 for (
unsigned int l = k;
l < dim; ++
l)
1316 template <
typename Number>
1317 struct Inverse<2, 1, Number>
1319 constexpr static inline DEAL_II_ALWAYS_INLINE
1320 ::SymmetricTensor<2, 1, Number>
1321 value(const ::SymmetricTensor<2, 1, Number> &t)
1325 tmp[0][0] = 1.0 / t[0][0];
1332 template <
typename Number>
1333 struct Inverse<2, 2, Number>
1335 constexpr static inline DEAL_II_ALWAYS_INLINE
1336 ::SymmetricTensor<2, 2, Number>
1337 value(const ::SymmetricTensor<2, 2, Number> &t)
1347 const Number inv_det_t =
1348 1.0 / (t[idx_00] * t[idx_11] - t[idx_01] * t[idx_01]);
1349 tmp[idx_00] = t[idx_11];
1350 tmp[idx_01] = -t[idx_01];
1351 tmp[idx_11] = t[idx_00];
1359 template <
typename Number>
1360 struct Inverse<2, 3, Number>
1362 constexpr static ::SymmetricTensor<2, 3, Number>
1363 value(const ::SymmetricTensor<2, 3, Number> &t)
1407 const Number inv_det_t =
1408 1.0 / (t[idx_00] * t[idx_11] * t[idx_22] -
1409 t[idx_00] * t[idx_12] * t[idx_12] -
1410 t[idx_01] * t[idx_01] * t[idx_22] +
1411 2.0 * t[idx_01] * t[idx_02] * t[idx_12] -
1412 t[idx_02] * t[idx_02] * t[idx_11]);
1413 tmp[idx_00] = t[idx_11] * t[idx_22] - t[idx_12] * t[idx_12];
1414 tmp[idx_01] = -t[idx_01] * t[idx_22] + t[idx_02] * t[idx_12];
1415 tmp[idx_02] = t[idx_01] * t[idx_12] - t[idx_02] * t[idx_11];
1416 tmp[idx_11] = t[idx_00] * t[idx_22] - t[idx_02] * t[idx_02];
1417 tmp[idx_12] = -t[idx_00] * t[idx_12] + t[idx_01] * t[idx_02];
1418 tmp[idx_22] = t[idx_00] * t[idx_11] - t[idx_01] * t[idx_01];
1426 template <
typename Number>
1427 struct Inverse<4, 1, Number>
1429 constexpr static inline ::SymmetricTensor<4, 1, Number>
1430 value(const ::SymmetricTensor<4, 1, Number> &t)
1433 tmp.
data[0][0] = 1.0 / t.data[0][0];
1439 template <
typename Number>
1440 struct Inverse<4, 2, Number>
1442 constexpr static inline ::SymmetricTensor<4, 2, Number>
1443 value(const ::SymmetricTensor<4, 2, Number> &t)
1469 const Number t4 = t.
data[0][0] * t.data[1][1],
1470 t6 = t.data[0][0] * t.data[1][2],
1471 t8 = t.data[0][1] * t.data[1][0],
1472 t00 = t.data[0][2] * t.data[1][0],
1473 t01 = t.data[0][1] * t.data[2][0],
1474 t04 = t.data[0][2] * t.data[2][0],
1475 t07 = 1.0 / (t4 * t.data[2][2] - t6 * t.data[2][1] -
1476 t8 * t.data[2][2] + t00 * t.data[2][1] +
1477 t01 * t.data[1][2] - t04 * t.data[1][1]);
1479 (t.data[1][1] * t.data[2][2] - t.data[1][2] * t.data[2][1]) * t07;
1481 -(t.data[0][1] * t.data[2][2] - t.data[0][2] * t.data[2][1]) * t07;
1483 -(-t.data[0][1] * t.data[1][2] + t.data[0][2] * t.data[1][1]) * t07;
1485 -(t.data[1][0] * t.data[2][2] - t.data[1][2] * t.data[2][0]) * t07;
1486 tmp.
data[1][1] = (t.data[0][0] * t.data[2][2] - t04) * t07;
1487 tmp.
data[1][2] = -(t6 - t00) * t07;
1489 -(-t.data[1][0] * t.data[2][1] + t.data[1][1] * t.data[2][0]) * t07;
1490 tmp.
data[2][1] = -(t.data[0][0] * t.data[2][1] - t01) * t07;
1491 tmp.
data[2][2] = (t4 - t8) * t07;
1495 tmp.
data[2][0] /= 2;
1496 tmp.
data[2][1] /= 2;
1497 tmp.
data[0][2] /= 2;
1498 tmp.
data[1][2] /= 2;
1499 tmp.
data[2][2] /= 4;
1506 template <
typename Number>
1507 struct Inverse<4, 3, Number>
1509 static ::SymmetricTensor<4, 3, Number>
1510 value(const ::SymmetricTensor<4, 3, Number> &t)
1520 const unsigned int N = 6;
1526 for (
unsigned int i = 0; i <
N; ++i)
1528 const Number typical_diagonal_element =
1529 diagonal_sum /
static_cast<double>(
N);
1530 (void)typical_diagonal_element;
1533 for (
unsigned int i = 0; i <
N; ++i)
1536 for (
unsigned int j = 0; j <
N; ++j)
1542 for (
unsigned int i = j + 1; i <
N; ++i)
1550 Assert(
max > 1.e-16 * typical_diagonal_element,
1551 ExcMessage(
"This tensor seems to be noninvertible"));
1556 for (
unsigned int k = 0; k <
N; ++k)
1563 const Number hr = 1. / tmp.
data[j][j];
1564 tmp.
data[j][j] = hr;
1565 for (
unsigned int k = 0; k <
N; ++k)
1569 for (
unsigned int i = 0; i <
N; ++i)
1573 tmp.
data[i][k] -= tmp.
data[i][j] * tmp.
data[j][k] * hr;
1576 for (
unsigned int i = 0; i <
N; ++i)
1578 tmp.
data[i][j] *= hr;
1579 tmp.
data[j][i] *= -hr;
1581 tmp.
data[j][j] = hr;
1586 for (
unsigned int i = 0; i <
N; ++i)
1588 for (
unsigned int k = 0; k <
N; ++k)
1589 hv[p[k]] = tmp.
data[i][k];
1590 for (
unsigned int k = 0; k <
N; ++k)
1591 tmp.
data[i][k] = hv[k];
1596 for (
unsigned int i = 3; i < 6; ++i)
1597 for (
unsigned int j = 0; j < 3; ++j)
1598 tmp.
data[i][j] /= 2;
1600 for (
unsigned int i = 0; i < 3; ++i)
1601 for (
unsigned int j = 3; j < 6; ++j)
1602 tmp.
data[i][j] /= 2;
1604 for (
unsigned int i = 3; i < 6; ++i)
1605 for (
unsigned int j = 3; j < 6; ++j)
1606 tmp.
data[i][j] /= 4;
1617template <
int rank_,
int dim,
typename Number>
1622 return internal::SymmetricTensorImplementation::convert_to_tensor(*
this);
1627template <
int rank_,
int dim,
typename Number>
1632 return data == t.
data;
1637template <
int rank_,
int dim,
typename Number>
1642 return data != t.
data;
1647template <
int rank_,
int dim,
typename Number>
1648template <
typename OtherNumber>
1659template <
int rank_,
int dim,
typename Number>
1660template <
typename OtherNumber>
1671template <
int rank_,
int dim,
typename Number>
1672template <
typename OtherNumber>
1682template <
int rank_,
int dim,
typename Number>
1683template <
typename OtherNumber>
1693template <
int rank_,
int dim,
typename Number>
1704template <
int rank_,
int dim,
typename Number>
1713template <
int rank_,
int dim,
typename Number>
1714constexpr std::size_t
1726 template <
int dim,
typename Number,
typename OtherNumber = Number>
1730 perform_double_contraction(
1731 const typename SymmetricTensorAccessors::StorageType<2, dim, Number>::
1732 base_tensor_type &data,
1733 const typename SymmetricTensorAccessors::
1734 StorageType<2, dim, OtherNumber>::base_tensor_type &sdata)
1742 return data[0] * sdata[0];
1747 result_type
sum = data[dim] * sdata[dim];
1748 for (
unsigned int d = dim + 1;
d < (dim * (dim + 1) / 2); ++
d)
1749 sum += data[
d] * sdata[
d];
1753 for (
unsigned int d = 0;
d < dim; ++
d)
1754 sum += data[
d] * sdata[
d];
1761 template <
int dim,
typename Number,
typename OtherNumber = Number>
1765 perform_double_contraction(
1766 const typename SymmetricTensorAccessors::StorageType<4, dim, Number>::
1767 base_tensor_type &data,
1768 const typename SymmetricTensorAccessors::
1769 StorageType<2, dim, OtherNumber>::base_tensor_type &sdata)
1776 const unsigned int data_dim = SymmetricTensorAccessors::
1777 StorageType<2, dim, value_type>::n_independent_components;
1778 value_type tmp[data_dim]{};
1779 for (
unsigned int i = 0; i < data_dim; ++i)
1781 perform_double_contraction<dim, Number, OtherNumber>(data[i], sdata);
1782 return result_type(tmp);
1787 template <
int dim,
typename Number,
typename OtherNumber = Number>
1789 typename SymmetricTensorAccessors::StorageType<
1795 perform_double_contraction(
1796 const typename SymmetricTensorAccessors::StorageType<2, dim, Number>::
1797 base_tensor_type &data,
1798 const typename SymmetricTensorAccessors::
1799 StorageType<4, dim, OtherNumber>::base_tensor_type &sdata)
1803 using base_tensor_type =
typename SymmetricTensorAccessors::
1804 StorageType<2, dim, value_type>::base_tensor_type;
1806 base_tensor_type tmp;
1807 for (
unsigned int i = 0; i < tmp.dimension; ++i)
1810 value_type
sum = data[dim] * sdata[dim][i];
1811 for (
unsigned int d = dim + 1;
d < (dim * (dim + 1) / 2); ++
d)
1812 sum += data[
d] * sdata[
d][i];
1816 for (
unsigned int d = 0;
d < dim; ++
d)
1817 sum += data[
d] * sdata[
d][i];
1825 template <
int dim,
typename Number,
typename OtherNumber = Number>
1827 typename SymmetricTensorAccessors::StorageType<
1833 perform_double_contraction(
1834 const typename SymmetricTensorAccessors::StorageType<4, dim, Number>::
1835 base_tensor_type &data,
1836 const typename SymmetricTensorAccessors::
1837 StorageType<4, dim, OtherNumber>::base_tensor_type &sdata)
1841 using base_tensor_type =
typename SymmetricTensorAccessors::
1842 StorageType<4, dim, value_type>::base_tensor_type;
1844 const unsigned int data_dim = SymmetricTensorAccessors::
1845 StorageType<2, dim, value_type>::n_independent_components;
1846 base_tensor_type tmp;
1847 for (
unsigned int i = 0; i < data_dim; ++i)
1848 for (
unsigned int j = 0; j < data_dim; ++j)
1851 for (
unsigned int d = dim;
d < (dim * (dim + 1) / 2); ++
d)
1852 tmp[i][j] += data[i][
d] * sdata[
d][j];
1853 tmp[i][j] += tmp[i][j];
1856 for (
unsigned int d = 0;
d < dim; ++
d)
1857 tmp[i][j] += data[i][
d] * sdata[
d][j];
1866template <
int rank_,
int dim,
typename Number>
1867template <
typename OtherNumber>
1878 return internal::perform_double_contraction<dim, Number, OtherNumber>(data,
1884template <
int rank_,
int dim,
typename Number>
1885template <
typename OtherNumber>
1894 internal::perform_double_contraction<dim, Number, OtherNumber>(data,
1917 template <
typename Type>
1918 struct Uninitialized
1923 template <
typename Type>
1924 Type Uninitialized<Type>::value;
1926 template <
int dim,
typename Number>
1929 typename SymmetricTensorAccessors::
1930 StorageType<2, dim, Number>::base_tensor_type &data)
1938 if (indices[0] == indices[1])
1939 return data[indices[0]];
1946 Assert(((indices[0] == 1) && (indices[1] == 0)) ||
1947 ((indices[0] == 0) && (indices[1] == 1)),
1956 for (
unsigned int d = 0, c = 0;
d < dim; ++
d)
1957 for (
unsigned int e =
d + 1;
e < dim; ++
e, ++c)
1958 if ((sorted_indices[0] ==
d) && (sorted_indices[1] ==
e))
1959 return data[dim + c];
1967 return Uninitialized<Number>::value;
1972 template <
int dim,
typename Number>
1975 const typename SymmetricTensorAccessors::
1976 StorageType<2, dim, Number>::base_tensor_type &data)
1984 if (indices[0] == indices[1])
1985 return data[indices[0]];
1992 Assert(((indices[0] == 1) && (indices[1] == 0)) ||
1993 ((indices[0] == 0) && (indices[1] == 1)),
2002 for (
unsigned int d = 0, c = 0;
d < dim; ++
d)
2003 for (
unsigned int e =
d + 1;
e < dim; ++
e, ++c)
2004 if ((sorted_indices[0] ==
d) && (sorted_indices[1] ==
e))
2005 return data[dim + c];
2013 return Uninitialized<Number>::value;
2018 template <
int dim,
typename Number>
2019 constexpr inline Number &
2021 typename SymmetricTensorAccessors::
2022 StorageType<4, dim, Number>::base_tensor_type &data)
2036 constexpr std::size_t base_index[2][2] = {{0, 2}, {2, 1}};
2037 return data[base_index[indices[0]][indices[1]]]
2038 [base_index[indices[2]][indices[3]]];
2047 constexpr std::size_t base_index[3][3] = {{0, 3, 4},
2050 return data[base_index[indices[0]][indices[1]]]
2051 [base_index[indices[2]][indices[3]]];
2061 return Uninitialized<Number>::value;
2065 template <
int dim,
typename Number>
2068 const typename SymmetricTensorAccessors::
2069 StorageType<4, dim, Number>::base_tensor_type &data)
2083 constexpr std::size_t base_index[2][2] = {{0, 2}, {2, 1}};
2084 return data[base_index[indices[0]][indices[1]]]
2085 [base_index[indices[2]][indices[3]]];
2094 constexpr std::size_t base_index[3][3] = {{0, 3, 4},
2097 return data[base_index[indices[0]][indices[1]]]
2098 [base_index[indices[2]][indices[3]]];
2108 return Uninitialized<Number>::value;
2115template <
int rank_,
int dim,
typename Number>
2120 for (
unsigned int r = 0; r < rank; ++r)
2122 return internal::symmetric_tensor_access<dim, Number>(indices, data);
2127template <
int rank_,
int dim,
typename Number>
2132 for (
unsigned int r = 0; r < rank; ++r)
2134 return internal::symmetric_tensor_access<dim, Number>(indices, data);
2141 namespace SymmetricTensorImplementation
2143 template <
int rank_>
2145 get_partially_filled_indices(
const unsigned int row,
2146 const std::integral_constant<int, 2> &)
2152 template <
int rank_>
2154 get_partially_filled_indices(
const unsigned int row,
2155 const std::integral_constant<int, 4> &)
2166template <
int rank_,
int dim,
typename Number>
2168 Accessor<rank_, dim,
true, rank_ - 1, Number>
2171 return internal::SymmetricTensorAccessors::
2172 Accessor<rank_, dim,
true, rank_ - 1, Number>(
2174 internal::SymmetricTensorImplementation::get_partially_filled_indices<
2175 rank_>(row, std::integral_constant<int, rank_>()));
2180template <
int rank_,
int dim,
typename Number>
2182 Accessor<rank_, dim,
false, rank_ - 1, Number>
2185 return internal::SymmetricTensorAccessors::
2186 Accessor<rank_, dim,
false, rank_ - 1, Number>(
2188 internal::SymmetricTensorImplementation::get_partially_filled_indices<
2189 rank_>(row, std::integral_constant<int, rank_>()));
2194template <
int rank_,
int dim,
typename Number>
2199 return operator()(indices);
2204template <
int rank_,
int dim,
typename Number>
2209 return operator()(indices);
2214template <
int rank_,
int dim,
typename Number>
2218 return std::addressof(this->access_raw_entry(0));
2223template <
int rank_,
int dim,
typename Number>
2224inline const Number *
2227 return std::addressof(this->access_raw_entry(0));
2232template <
int rank_,
int dim,
typename Number>
2236 return begin_raw() + n_independent_components;
2241template <
int rank_,
int dim,
typename Number>
2242inline const Number *
2245 return begin_raw() + n_independent_components;
2252 namespace SymmetricTensorImplementation
2254 template <
int dim,
typename Number>
2255 constexpr unsigned int
2256 entry_to_indices(const ::SymmetricTensor<2, dim, Number> &,
2257 const unsigned int index)
2263 template <
int dim,
typename Number>
2264 constexpr ::TableIndices<2>
2265 entry_to_indices(const ::SymmetricTensor<4, dim, Number> &,
2266 const unsigned int index)
2277template <
int rank_,
int dim,
typename Number>
2278constexpr inline const Number &
2280 const unsigned int index)
const
2283 return data[internal::SymmetricTensorImplementation::entry_to_indices(*
this,
2289template <
int rank_,
int dim,
typename Number>
2290constexpr inline Number &
2294 return data[internal::SymmetricTensorImplementation::entry_to_indices(*
this,
2302 template <
int dim,
typename Number>
2304 compute_norm(
const typename SymmetricTensorAccessors::
2305 StorageType<2, dim, Number>::base_tensor_type &data)
2332 for (
unsigned int d = 0;
d < dim; ++
d)
2335 for (
unsigned int d = dim;
d < (dim * dim + dim) / 2; ++
d)
2346 template <
int dim,
typename Number>
2348 compute_norm(
const typename SymmetricTensorAccessors::
2349 StorageType<4, dim, Number>::base_tensor_type &data)
2361 const unsigned int n_independent_components = data.dimension;
2363 for (
unsigned int i = 0; i < dim; ++i)
2364 for (
unsigned int j = 0; j < dim; ++j)
2367 for (
unsigned int i = 0; i < dim; ++i)
2368 for (
unsigned int j = dim; j < n_independent_components; ++j)
2371 for (
unsigned int i = dim; i < n_independent_components; ++i)
2372 for (
unsigned int j = 0; j < dim; ++j)
2375 for (
unsigned int i = dim; i < n_independent_components; ++i)
2376 for (
unsigned int j = dim; j < n_independent_components; ++j)
2389template <
int rank_,
int dim,
typename Number>
2393 return internal::compute_norm<dim, Number>(data);
2400 namespace SymmetricTensorImplementation
2423 constexpr unsigned int table[2][2] = {{0, 2}, {2, 1}};
2424 return table[indices[0]][indices[1]];
2429 constexpr unsigned int table[3][3] = {{0, 3, 4},
2432 return table[indices[0]][indices[1]];
2437 constexpr unsigned int table[4][4] = {{0, 4, 5, 6},
2441 return table[indices[0]][indices[1]];
2447 if (indices[0] == indices[1])
2451 sorted_indices.sort();
2453 for (
unsigned int d = 0, c = 0;
d < dim; ++
d)
2454 for (
unsigned int e =
d + 1;
e < dim; ++
e, ++c)
2455 if ((sorted_indices[0] ==
d) && (sorted_indices[1] ==
e))
2471 template <
int dim,
int rank_>
2472 constexpr inline unsigned int
2483template <
int rank_,
int dim,
typename Number>
2484constexpr unsigned int
2488 return internal::SymmetricTensorImplementation::component_to_unrolled_index<
2496 namespace SymmetricTensorImplementation
2508 const std::integral_constant<int, 2> &)
2546 for (
unsigned int d = 0, c = dim;
d < dim; ++
d)
2547 for (
unsigned int e =
d + 1;
e < dim; ++
e, ++c)
2565 template <
int dim,
int rank_>
2567 typename std::enable_if<rank_ != 2, TableIndices<rank_>>::type
2569 const std::integral_constant<int, rank_> &)
2578 n_independent_components));
2586template <
int rank_,
int dim,
typename Number>
2589 const unsigned int i)
2591 return internal::SymmetricTensorImplementation::unrolled_to_component_indices<
2592 dim>(i, std::integral_constant<int, rank_>());
2597template <
int rank_,
int dim,
typename Number>
2598template <
class Archive>
2623template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2648template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2668template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2685template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2702template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2719template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2743template <
int dim,
typename Number>
2759 return (tmp + tmp + t.
data[0] * t.
data[1] * t.
data[2] -
2783template <
int dim,
typename Number>
2801template <
int dim,
typename Number>
2805 Number t =
d.data[0];
2806 for (
unsigned int i = 1; i < dim; ++i)
2823template <
int dim,
typename Number>
2842template <
typename Number>
2869template <
typename Number>
2873 return t[0][0] * t[1][1] - t[0][1] * t[0][1];
2886template <
typename Number>
2890 return (t[0][0] * t[1][1] + t[1][1] * t[2][2] + t[2][2] * t[0][0] -
2891 t[0][1] * t[0][1] - t[0][2] * t[0][2] - t[1][2] * t[1][2]);
2903template <
typename Number>
2904std::array<Number, 1>
2931template <
typename Number>
2932std::array<Number, 2>
2959template <
typename Number>
2960std::array<Number, 3>
2967 namespace SymmetricTensorImplementation
3006 template <
int dim,
typename Number>
3010 std::array<Number, dim> &
d,
3011 std::array<Number, dim - 1> &
e);
3054 template <
int dim,
typename Number>
3055 std::array<std::pair<Number, Tensor<1, dim, Number>>, dim>
3099 template <
int dim,
typename Number>
3100 std::array<std::pair<Number, Tensor<1, dim, Number>>, dim>
3118 template <
typename Number>
3119 std::array<std::pair<Number, Tensor<1, 2, Number>>, 2>
3156 template <
typename Number>
3157 std::array<std::pair<Number, Tensor<1, 3, Number>>, 3>
3164 template <
int dim,
typename Number>
3171 return lhs.first > rhs.first;
3274template <
int dim,
typename Number>
3275std::array<std::pair<Number, Tensor<1, dim, Number>>,
3276 std::integral_constant<int, dim>::value>
3291template <
int rank_,
int dim,
typename Number>
3310template <
int dim,
typename Number>
3317 const Number tr =
trace(t) / dim;
3318 for (
unsigned int i = 0; i < dim; ++i)
3326template <
int dim,
typename Number>
3346 for (
unsigned int d = 0;
d < dim; ++
d)
3354template <
int dim,
typename Number>
3361 for (
unsigned int i = 0; i < dim; ++i)
3362 for (
unsigned int j = 0; j < dim; ++j)
3371 for (
unsigned int i = dim;
3372 i < internal::SymmetricTensorAccessors::StorageType<4, dim, Number>::
3382template <
int dim,
typename Number>
3389 for (
unsigned int i = 0; i < dim; ++i)
3397 for (
unsigned int i = dim;
3398 i < internal::SymmetricTensorAccessors::StorageType<4, dim, Number>::
3417template <
int dim,
typename Number>
3437template <
int dim,
typename Number>
3468template <
int dim,
typename Number>
3476 for (
unsigned int i = 0; i < dim; ++i)
3477 for (
unsigned int j = i; j < dim; ++j)
3478 for (
unsigned int k = 0; k < dim; ++k)
3479 for (
unsigned int l = k;
l < dim; ++
l)
3480 tmp[i][j][k][
l] = t1[i][j] * t2[k][
l];
3494template <
int dim,
typename Number>
3499 for (
unsigned int d = 0;
d < dim; ++
d)
3500 result[
d][
d] = t[
d][
d];
3503 for (
unsigned int d = 0;
d < dim; ++
d)
3504 for (
unsigned int e =
d + 1;
e < dim; ++
e)
3505 result[
d][
e] = (t[
d][
e] + t[
e][
d]) * half;
3518template <
int rank_,
int dim,
typename Number>
3536template <
int rank_,
int dim,
typename Number>
3571template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
3578 const OtherNumber & factor)
3601template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
3611 return (t * factor);
3621template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
3628 const OtherNumber & factor)
3644template <
int rank_,
int dim>
3661template <
int rank_,
int dim>
3677template <
int rank_,
int dim>
3695template <
int dim,
typename Number,
typename OtherNumber>
3717template <
int dim,
typename Number,
typename OtherNumber>
3725 for (
unsigned int i = 0; i < dim; ++i)
3726 for (
unsigned int j = 0; j < dim; ++j)
3727 s += t1[i][j] * t2[i][j];
3745template <
int dim,
typename Number,
typename OtherNumber>
3768template <
typename Number,
typename OtherNumber>
3775 tmp[0][0] = t[0][0][0][0] * s[0][0];
3794template <
typename Number,
typename OtherNumber>
3795constexpr inline void
3801 tmp[0][0] = t[0][0][0][0] * s[0][0];
3820template <
typename Number,
typename OtherNumber>
3821constexpr inline void
3827 const unsigned int dim = 2;
3829 for (
unsigned int i = 0; i < dim; ++i)
3830 for (
unsigned int j = i; j < dim; ++j)
3831 tmp[i][j] = t[i][j][0][0] * s[0][0] + t[i][j][1][1] * s[1][1] +
3832 2 * t[i][j][0][1] * s[0][1];
3851template <
typename Number,
typename OtherNumber>
3852constexpr inline void
3858 const unsigned int dim = 2;
3860 for (
unsigned int i = 0; i < dim; ++i)
3861 for (
unsigned int j = i; j < dim; ++j)
3862 tmp[i][j] = s[0][0] * t[0][0][i][j] * +s[1][1] * t[1][1][i][j] +
3863 2 * s[0][1] * t[0][1][i][j];
3882template <
typename Number,
typename OtherNumber>
3883constexpr inline void
3889 const unsigned int dim = 3;
3891 for (
unsigned int i = 0; i < dim; ++i)
3892 for (
unsigned int j = i; j < dim; ++j)
3893 tmp[i][j] = t[i][j][0][0] * s[0][0] + t[i][j][1][1] * s[1][1] +
3894 t[i][j][2][2] * s[2][2] + 2 * t[i][j][0][1] * s[0][1] +
3895 2 * t[i][j][0][2] * s[0][2] + 2 * t[i][j][1][2] * s[1][2];
3914template <
typename Number,
typename OtherNumber>
3915constexpr inline void
3921 const unsigned int dim = 3;
3923 for (
unsigned int i = 0; i < dim; ++i)
3924 for (
unsigned int j = i; j < dim; ++j)
3925 tmp[i][j] = s[0][0] * t[0][0][i][j] + s[1][1] * t[1][1][i][j] +
3926 s[2][2] * t[2][2][i][j] + 2 * s[0][1] * t[0][1][i][j] +
3927 2 * s[0][2] * t[0][2][i][j] + 2 * s[1][2] * t[1][2][i][j];
3938template <
int dim,
typename Number,
typename OtherNumber>
3944 for (
unsigned int i = 0; i < dim; ++i)
3945 for (
unsigned int j = 0; j < dim; ++j)
3946 dest[i] += src1[i][j] * src2[j];
3957template <
int dim,
typename Number,
typename OtherNumber>
3987template <
int rank_1,
3991 typename OtherNumber>
3993 typename Tensor<rank_1 + rank_2 - 2,
4023template <
int rank_1,
4027 typename OtherNumber>
4029 typename Tensor<rank_1 + rank_2 - 2,
4049template <
int dim,
typename Number>
4050inline std::ostream &
4058 for (
unsigned int i = 0; i < dim; ++i)
4059 for (
unsigned int j = 0; j < dim; ++j)
4076template <
int dim,
typename Number>
4077inline std::ostream &
4085 for (
unsigned int i = 0; i < dim; ++i)
4086 for (
unsigned int j = 0; j < dim; ++j)
4087 for (
unsigned int k = 0; k < dim; ++k)
4088 for (
unsigned int l = 0;
l < dim; ++
l)
4089 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])
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
friend constexpr SymmetricTensor< 4, dim2, Number2 > deviator_tensor()
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)
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)
friend constexpr SymmetricTensor< 4, dim2, Number2 > identity_tensor()
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)
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 > &)
friend constexpr SymmetricTensor< 2, dim2, Number2 > unit_symmetric_tensor()
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()
#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)
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()