15#ifndef dealii_symmetric_tensor_h
16#define dealii_symmetric_tensor_h
35template <
int rank,
int dim,
typename Number =
double>
49template <
int dim,
typename Number =
double>
82template <
int dim,
typename Number =
double>
124template <
int dim,
typename Number =
double>
129template <
int dim,
typename Number>
133template <
int dim,
typename Number>
146template <
int dim2,
typename Number>
160template <
int dim,
typename Number>
178template <
int dim,
typename Number>
190 template <
int rank,
int dim,
typename T,
typename U>
196 std::complex<typename ProductType<T, U>::type>>;
199 template <
int rank,
int dim,
typename T,
typename U>
206 std::complex<typename ProductType<T, U>::type>>;
209 template <
typename T,
int rank,
int dim,
typename U>
215 std::complex<typename ProductType<T, U>::type>>;
218 template <
int rank,
int dim,
typename T,
typename U>
225 std::complex<typename ProductType<T, U>::type>>;
233 namespace SymmetricTensorImplementation
239 template <
int rank,
int dim,
typename Number>
233 namespace SymmetricTensorImplementation {
…}
247 namespace SymmetricTensorAccessors
258 const unsigned int new_index,
259 const unsigned int position)
266 return {previous_indices[0], new_index};
280 const unsigned int new_index,
281 const unsigned int position)
293 return {previous_indices[0],
298 return {previous_indices[0],
303 return {previous_indices[0],
324 typename OtherNumber = Number>
339 template <
int dim,
typename Number,
typename OtherNumber>
359 template <
int rank,
int dim,
typename Number>
365 template <
int dim,
typename Number>
372 static const unsigned int n_independent_components =
373 (dim * dim + dim) / 2;
386 template <
int dim,
typename Number>
394 static const unsigned int n_rank2_components = (dim * dim + dim) / 2;
399 static const unsigned int n_independent_components =
400 (n_rank2_components *
418 template <
int rank,
int dim,
bool constness,
typename Number>
427 template <
int rank,
int dim,
typename Number>
441 template <
int rank,
int dim,
typename Number>
482 template <
int rank,
int dim,
bool constness,
int P,
typename Number>
529 constexpr Accessor<rank, dim, constness, P - 1, Number>
536 constexpr Accessor<rank, dim, constness, P - 1, Number>
548 template <
int,
int,
typename>
549 friend class ::SymmetricTensor;
550 template <
int,
int,
bool,
int,
typename>
552 friend class ::SymmetricTensor<rank, dim, Number>;
553 friend class Accessor<rank, dim, constness, P + 1, Number>;
565 template <
int rank,
int dim,
bool constness,
typename Number>
634 template <
int,
int,
typename>
635 friend class ::SymmetricTensor;
636 template <
int,
int,
bool,
int,
typename>
638 friend class ::SymmetricTensor<rank, dim, Number>;
639 friend class SymmetricTensorAccessors::
640 Accessor<rank, dim, constness, 2, Number>;
247 namespace SymmetricTensorAccessors {
…}
719template <int rank_, int dim, typename Number>
723 static_assert(rank_ % 2 == 0,
"A SymmetricTensor must have even rank!");
733 static constexpr unsigned int dimension = dim;
738 static const unsigned int rank = rank_;
745 static constexpr unsigned int n_independent_components =
747 n_independent_components;
769 template <
typename OtherNumber>
795 template <
typename OtherNumber>
805 template <
typename OtherNumber>
843 template <
typename OtherNumber>
850 template <
typename OtherNumber>
858 template <
typename OtherNumber>
865 template <
typename OtherNumber>
928 template <
typename OtherNumber>
930 double_contraction_result<rank_, 2, dim, Number, OtherNumber>::type
937 template <
typename OtherNumber>
939 double_contraction_result<rank_, 4, dim, Number, OtherNumber>::type
953 constexpr const Number &
961 constexpr internal::SymmetricTensorAccessors::
962 Accessor<rank_, dim,
true, rank_ - 1, Number>
970 constexpr internal::SymmetricTensorAccessors::
971 Accessor<rank_, dim,
false, rank_ - 1, Number>
980 constexpr const Number &
999 constexpr const Number &
1071 template <
class Archive>
1095 template <
int,
int,
typename>
1099 template <
int dim2,
typename Number2>
1103 template <
int dim2,
typename Number2>
1107 template <
int dim2,
typename Number2>
1111 template <
int dim2,
typename Number2>
1115 template <
int dim2,
typename Number2>
1119 template <
int dim2,
typename Number2>
1126 Inverse<2, dim, Number>;
1129 Inverse<4, dim, Number>;
1140template <int rank, int dim, typename Number>
1143template <int rank_, int dim, typename Number>
1144constexpr unsigned
int
1149 namespace SymmetricTensorAccessors
1151 template <
int rank_,
int dim,
bool constness,
int P,
typename Number>
1153 Accessor<rank_, dim, constness, P, Number>::Accessor(
1154 tensor_type &tensor,
1157 , previous_indices(previous_indices)
1162 template <
int rank_,
int dim,
bool constness,
int P,
typename Number>
1164 Accessor<rank_, dim, constness, P - 1, Number>
1165 Accessor<rank_, dim, constness, P, Number>::operator[](
1166 const unsigned int i)
1168 return Accessor<rank_, dim, constness, P - 1, Number>(
1169 tensor, merge(previous_indices, i, rank_ - P));
1174 template <
int rank_,
int dim,
bool constness,
int P,
typename Number>
1176 Accessor<rank_, dim, constness, P - 1, Number>
1177 Accessor<rank_, dim, constness, P, Number>::operator[](
1178 const unsigned int i)
const
1180 return Accessor<rank_, dim, constness, P - 1, Number>(
1181 tensor,
merge(previous_indices, i, rank_ - P));
1186 template <
int rank_,
int dim,
bool constness,
typename Number>
1188 Accessor<rank_, dim, constness, 1, Number>::Accessor(
1189 tensor_type &tensor,
1192 , previous_indices(previous_indices)
1197 template <
int rank_,
int dim,
bool constness,
typename Number>
1199 typename Accessor<rank_, dim, constness, 1, Number>::reference
1200 Accessor<rank_, dim, constness, 1, Number>::operator[](
1201 const unsigned int i)
1203 return tensor(
merge(previous_indices, i, rank_ - 1));
1207 template <
int rank_,
int dim,
bool constness,
typename Number>
1209 typename Accessor<rank_, dim, constness, 1, Number>::reference
1210 Accessor<rank_, dim, constness, 1, Number>::operator[](
1211 const unsigned int i)
const
1213 return tensor(
merge(previous_indices, i, rank_ - 1));
1220template <
int rank_,
int dim,
typename Number>
1221template <
typename OtherNumber>
1226 static_assert(rank == 2,
"This function is only implemented for rank==2");
1227 for (
unsigned int d = 0;
d < dim; ++
d)
1228 for (
unsigned int e = 0;
e <
d; ++
e)
1229 Assert(t[d][e] == t[e][d],
1230 ExcMessage(
"The incoming Tensor must be exactly symmetric."));
1232 for (
unsigned int d = 0;
d < dim; ++
d)
1235 for (
unsigned int d = 0, c = 0;
d < dim; ++
d)
1236 for (
unsigned int e = d + 1;
e < dim; ++
e, ++c)
1237 data[dim + c] = t[d][e];
1242template <
int rank_,
int dim,
typename Number>
1243template <
typename OtherNumber>
1252template <
int rank_,
int dim,
typename Number>
1255 const Number (&array)[n_independent_components])
1257 *reinterpret_cast<const typename base_tensor_type::array_type *>(array))
1260 Assert(
sizeof(
typename base_tensor_type::array_type) ==
sizeof(array),
1266template <
int rank_,
int dim,
typename Number>
1267template <
typename OtherNumber>
1279template <
int rank_,
int dim,
typename Number>
1285 ExcMessage(
"Only assignment with zero is allowed"));
1296 namespace SymmetricTensorImplementation
1298 template <
int dim,
typename Number>
1299 constexpr inline DEAL_II_ALWAYS_INLINE ::Tensor<2, dim, Number>
1300 convert_to_tensor(const ::SymmetricTensor<2, dim, Number> &s)
1305 for (
unsigned int d = 0;
d < dim; ++
d)
1306 t[d][d] = s.access_raw_entry(d);
1309 for (
unsigned int d = 0, c = 0;
d < dim; ++
d)
1310 for (
unsigned int e = d + 1;
e < dim; ++
e, ++c)
1312 t[
d][
e] = s.access_raw_entry(dim + c);
1313 t[
e][
d] = s.access_raw_entry(dim + c);
1319 template <
int dim,
typename Number>
1320 constexpr ::Tensor<4, dim, Number>
1321 convert_to_tensor(const ::SymmetricTensor<4, dim, Number> &st)
1328 for (
unsigned int i = 0; i < dim; ++i)
1329 for (
unsigned int j = i; j < dim; ++j)
1330 for (
unsigned int k = 0; k < dim; ++k)
1331 for (
unsigned int l = k;
l < dim; ++
l)
1341 template <
typename Number>
1342 struct Inverse<2, 1, Number>
1344 constexpr static inline DEAL_II_ALWAYS_INLINE
1345 ::SymmetricTensor<2, 1, Number>
1346 value(const ::SymmetricTensor<2, 1, Number> &t)
1350 tmp[0][0] = 1.0 / t[0][0];
1357 template <
typename Number>
1358 struct Inverse<2, 2, Number>
1360 constexpr static inline DEAL_II_ALWAYS_INLINE
1361 ::SymmetricTensor<2, 2, Number>
1362 value(const ::SymmetricTensor<2, 2, Number> &t)
1372 const Number inv_det_t =
1373 1.0 / (t[idx_00] * t[idx_11] - t[idx_01] * t[idx_01]);
1374 tmp[idx_00] = t[idx_11];
1375 tmp[idx_01] = -t[idx_01];
1376 tmp[idx_11] = t[idx_00];
1384 template <
typename Number>
1385 struct Inverse<2, 3, Number>
1387 constexpr static ::SymmetricTensor<2, 3, Number>
1388 value(const ::SymmetricTensor<2, 3, Number> &t)
1432 const Number inv_det_t =
1433 1.0 / (t[idx_00] * t[idx_11] * t[idx_22] -
1434 t[idx_00] * t[idx_12] * t[idx_12] -
1435 t[idx_01] * t[idx_01] * t[idx_22] +
1436 2.0 * t[idx_01] * t[idx_02] * t[idx_12] -
1437 t[idx_02] * t[idx_02] * t[idx_11]);
1438 tmp[idx_00] = t[idx_11] * t[idx_22] - t[idx_12] * t[idx_12];
1439 tmp[idx_01] = -t[idx_01] * t[idx_22] + t[idx_02] * t[idx_12];
1440 tmp[idx_02] = t[idx_01] * t[idx_12] - t[idx_02] * t[idx_11];
1441 tmp[idx_11] = t[idx_00] * t[idx_22] - t[idx_02] * t[idx_02];
1442 tmp[idx_12] = -t[idx_00] * t[idx_12] + t[idx_01] * t[idx_02];
1443 tmp[idx_22] = t[idx_00] * t[idx_11] - t[idx_01] * t[idx_01];
1451 template <
typename Number>
1452 struct Inverse<4, 1, Number>
1454 constexpr static inline ::SymmetricTensor<4, 1, Number>
1455 value(const ::SymmetricTensor<4, 1, Number> &t)
1458 tmp.
data[0][0] = 1.0 / t.data[0][0];
1464 template <
typename Number>
1465 struct Inverse<4, 2, Number>
1467 constexpr static inline ::SymmetricTensor<4, 2, Number>
1468 value(const ::SymmetricTensor<4, 2, Number> &t)
1494 const Number t4 = t.
data[0][0] * t.data[1][1],
1495 t6 = t.data[0][0] * t.data[1][2],
1496 t8 = t.data[0][1] * t.data[1][0],
1497 t00 = t.data[0][2] * t.data[1][0],
1498 t01 = t.data[0][1] * t.data[2][0],
1499 t04 = t.data[0][2] * t.data[2][0],
1500 t07 = 1.0 / (t4 * t.data[2][2] - t6 * t.data[2][1] -
1501 t8 * t.data[2][2] + t00 * t.data[2][1] +
1502 t01 * t.data[1][2] - t04 * t.data[1][1]);
1504 (t.data[1][1] * t.data[2][2] - t.data[1][2] * t.data[2][1]) * t07;
1506 -(t.data[0][1] * t.data[2][2] - t.data[0][2] * t.data[2][1]) * t07;
1508 -(-t.data[0][1] * t.data[1][2] + t.data[0][2] * t.data[1][1]) * t07;
1510 -(t.data[1][0] * t.data[2][2] - t.data[1][2] * t.data[2][0]) * t07;
1511 tmp.
data[1][1] = (t.data[0][0] * t.data[2][2] - t04) * t07;
1512 tmp.
data[1][2] = -(t6 - t00) * t07;
1514 -(-t.data[1][0] * t.data[2][1] + t.data[1][1] * t.data[2][0]) * t07;
1515 tmp.
data[2][1] = -(t.data[0][0] * t.data[2][1] - t01) * t07;
1516 tmp.
data[2][2] = (t4 - t8) * t07;
1520 tmp.
data[2][0] /= 2;
1521 tmp.
data[2][1] /= 2;
1522 tmp.
data[0][2] /= 2;
1523 tmp.
data[1][2] /= 2;
1524 tmp.
data[2][2] /= 4;
1531 template <
typename Number>
1532 struct Inverse<4, 3, Number>
1534 static ::SymmetricTensor<4, 3, Number>
1535 value(const ::SymmetricTensor<4, 3, Number> &t)
1545 const unsigned int N = 6;
1551 for (
unsigned int i = 0; i <
N; ++i)
1553 const Number typical_diagonal_element =
1554 diagonal_sum /
static_cast<double>(
N);
1555 (void)typical_diagonal_element;
1558 for (
unsigned int i = 0; i <
N; ++i)
1561 for (
unsigned int j = 0; j <
N; ++j)
1567 for (
unsigned int i = j + 1; i <
N; ++i)
1575 Assert(max > 1.e-16 * typical_diagonal_element,
1576 ExcMessage(
"This tensor seems to be noninvertible"));
1581 for (
unsigned int k = 0; k <
N; ++k)
1582 std::swap(tmp.
data[j][k], tmp.
data[r][k]);
1584 std::swap(p[j], p[r]);
1588 const Number hr = 1. / tmp.
data[j][j];
1589 tmp.
data[j][j] = hr;
1590 for (
unsigned int k = 0; k <
N; ++k)
1594 for (
unsigned int i = 0; i <
N; ++i)
1598 tmp.
data[i][k] -= tmp.
data[i][j] * tmp.
data[j][k] * hr;
1601 for (
unsigned int i = 0; i <
N; ++i)
1603 tmp.
data[i][j] *= hr;
1604 tmp.
data[j][i] *= -hr;
1606 tmp.
data[j][j] = hr;
1611 for (
unsigned int i = 0; i <
N; ++i)
1613 for (
unsigned int k = 0; k <
N; ++k)
1614 hv[p[k]] = tmp.
data[i][k];
1615 for (
unsigned int k = 0; k <
N; ++k)
1616 tmp.
data[i][k] = hv[k];
1621 for (
unsigned int i = 3; i < 6; ++i)
1622 for (
unsigned int j = 0; j < 3; ++j)
1623 tmp.
data[i][j] /= 2;
1625 for (
unsigned int i = 0; i < 3; ++i)
1626 for (
unsigned int j = 3; j < 6; ++j)
1627 tmp.
data[i][j] /= 2;
1629 for (
unsigned int i = 3; i < 6; ++i)
1630 for (
unsigned int j = 3; j < 6; ++j)
1631 tmp.
data[i][j] /= 4;
1642template <
int rank_,
int dim,
typename Number>
1647 return internal::SymmetricTensorImplementation::convert_to_tensor(*
this);
1652template <
int rank_,
int dim,
typename Number>
1662template <
int rank_,
int dim,
typename Number>
1672template <
int rank_,
int dim,
typename Number>
1673template <
typename OtherNumber>
1685template <
int rank_,
int dim,
typename Number>
1686template <
typename OtherNumber>
1698template <
int rank_,
int dim,
typename Number>
1699template <
typename OtherNumber>
1710template <
int rank_,
int dim,
typename Number>
1711template <
typename OtherNumber>
1722template <
int rank_,
int dim,
typename Number>
1734template <
int rank_,
int dim,
typename Number>
1743template <
int rank_,
int dim,
typename Number>
1759 template <
int dim,
typename Number,
typename OtherNumber = Number>
1761 typename SymmetricTensorAccessors::
1762 double_contraction_result<2, 2, dim, Number, OtherNumber>::type
1763 perform_double_contraction(
1764 const typename SymmetricTensorAccessors::StorageType<2, dim, Number>::
1765 base_tensor_type &
data,
1766 const typename SymmetricTensorAccessors::
1767 StorageType<2, dim, OtherNumber>::base_tensor_type &sdata)
1769 using result_type =
typename SymmetricTensorAccessors::
1770 double_contraction_result<2, 2, dim, Number, OtherNumber>::type;
1775 return data[0] * sdata[0];
1783 result_type
sum =
data[dim] * sdata[dim];
1784 for (
unsigned int d = dim + 1;
d < (dim * (dim + 1) / 2); ++
d)
1785 sum +=
data[d] * sdata[d];
1789 for (
unsigned int d = 0;
d < dim; ++
d)
1790 sum +=
data[d] * sdata[d];
1801 template <
int dim,
typename Number,
typename OtherNumber = Number>
1803 typename SymmetricTensorAccessors::
1804 double_contraction_result<4, 2, dim, Number, OtherNumber>::type
1805 perform_double_contraction(
1806 const typename SymmetricTensorAccessors::StorageType<4, dim, Number>::
1807 base_tensor_type &
data,
1808 const typename SymmetricTensorAccessors::
1809 StorageType<2, dim, OtherNumber>::base_tensor_type &sdata)
1811 using result_type =
typename SymmetricTensorAccessors::
1812 double_contraction_result<4, 2, dim, Number, OtherNumber>::type;
1813 using value_type =
typename SymmetricTensorAccessors::
1814 double_contraction_result<4, 2, dim, Number, OtherNumber>::value_type;
1816 const unsigned int data_dim = SymmetricTensorAccessors::
1817 StorageType<2, dim, value_type>::n_independent_components;
1818 value_type tmp[data_dim]{};
1819 for (
unsigned int i = 0; i < data_dim; ++i)
1821 perform_double_contraction<dim, Number, OtherNumber>(
data[i], sdata);
1822 return result_type(tmp);
1831 template <
int dim,
typename Number,
typename OtherNumber = Number>
1833 typename SymmetricTensorAccessors::StorageType<
1836 typename SymmetricTensorAccessors::
1837 double_contraction_result<2, 4, dim, Number, OtherNumber>::value_type>::
1839 perform_double_contraction(
1840 const typename SymmetricTensorAccessors::StorageType<2, dim, Number>::
1841 base_tensor_type &
data,
1842 const typename SymmetricTensorAccessors::
1843 StorageType<4, dim, OtherNumber>::base_tensor_type &sdata)
1845 using value_type =
typename SymmetricTensorAccessors::
1846 double_contraction_result<2, 4, dim, Number, OtherNumber>::value_type;
1847 using base_tensor_type =
typename SymmetricTensorAccessors::
1848 StorageType<2, dim, value_type>::base_tensor_type;
1850 base_tensor_type tmp;
1851 for (
unsigned int i = 0; i < tmp.dimension; ++i)
1858 value_type
sum =
data[dim] * sdata[dim][i];
1859 for (
unsigned int d = dim + 1;
d < (dim * (dim + 1) / 2); ++
d)
1860 sum +=
data[d] * sdata[d][i];
1864 for (
unsigned int d = 0;
d < dim; ++
d)
1865 sum +=
data[d] * sdata[d][i];
1876 template <
int dim,
typename Number,
typename OtherNumber = Number>
1878 typename SymmetricTensorAccessors::StorageType<
1881 typename SymmetricTensorAccessors::
1882 double_contraction_result<4, 4, dim, Number, OtherNumber>::value_type>::
1884 perform_double_contraction(
1885 const typename SymmetricTensorAccessors::StorageType<4, dim, Number>::
1886 base_tensor_type &
data,
1887 const typename SymmetricTensorAccessors::
1888 StorageType<4, dim, OtherNumber>::base_tensor_type &sdata)
1890 using value_type =
typename SymmetricTensorAccessors::
1891 double_contraction_result<4, 4, dim, Number, OtherNumber>::value_type;
1892 using base_tensor_type =
typename SymmetricTensorAccessors::
1893 StorageType<4, dim, value_type>::base_tensor_type;
1895 const unsigned int data_dim = SymmetricTensorAccessors::
1896 StorageType<2, dim, value_type>::n_independent_components;
1897 base_tensor_type tmp;
1898 for (
unsigned int i = 0; i < data_dim; ++i)
1899 for (
unsigned int j = 0; j < data_dim; ++j)
1902 for (
unsigned int d = dim;
d < (dim * (dim + 1) / 2); ++
d)
1903 tmp[i][j] +=
data[i][d] * sdata[d][j];
1904 tmp[i][j] += tmp[i][j];
1907 for (
unsigned int d = 0;
d < dim; ++
d)
1908 tmp[i][j] +=
data[i][d] * sdata[d][j];
1917template <
int rank_,
int dim,
typename Number>
1918template <
typename OtherNumber>
1920 typename internal::SymmetricTensorAccessors::
1921 double_contraction_result<rank_, 2, dim, Number, OtherNumber>::type
1927 return internal::perform_double_contraction<dim, Number, OtherNumber>(
data,
1933template <
int rank_,
int dim,
typename Number>
1934template <
typename OtherNumber>
1936 typename internal::SymmetricTensorAccessors::
1937 double_contraction_result<rank_, 4, dim, Number, OtherNumber>::type
1941 typename internal::SymmetricTensorAccessors::
1942 double_contraction_result<rank_, 4, dim, Number, OtherNumber>::type tmp;
1944 internal::perform_double_contraction<dim, Number, OtherNumber>(
data,
1961 namespace SymmetricTensorImplementation
1983 constexpr ::ndarray<unsigned int, 2, 2> table = {
1984 {{{0, 2}}, {{2, 1}}}};
1985 return table[indices[0]][indices[1]];
1989 constexpr ::ndarray<unsigned int, 3, 3> table = {
1990 {{{0, 3, 4}}, {{3, 1, 5}}, {{4, 5, 2}}}};
1991 return table[indices[0]][indices[1]];
1995 constexpr ::ndarray<unsigned int, 4, 4> table = {
2000 return table[indices[0]][indices[1]];
2005 if (indices[0] == indices[1])
2016 for (
unsigned int d = 0;
d < dim; ++
d)
2017 for (
unsigned int e = d + 1;
e < dim; ++
e, ++c)
2018 if ((sorted_indices[0] == d) && (sorted_indices[1] == e))
2034 template <
int dim,
int rank_>
2035 constexpr inline unsigned int
2044 template <
int dim,
typename Number>
2047 typename SymmetricTensorAccessors::
2048 StorageType<2, dim, Number>::base_tensor_type &
data)
2050 return data[SymmetricTensorImplementation::component_to_unrolled_index<dim>(
2056 template <
int dim,
typename Number>
2059 const typename SymmetricTensorAccessors::
2060 StorageType<2, dim, Number>::base_tensor_type &
data)
2062 return data[SymmetricTensorImplementation::component_to_unrolled_index<dim>(
2068 template <
int dim,
typename Number>
2069 constexpr inline Number &
2071 typename SymmetricTensorAccessors::
2072 StorageType<4, dim, Number>::base_tensor_type &
data)
2086 constexpr std::size_t base_index[2][2] = {{0, 2}, {2, 1}};
2087 return data[base_index[indices[0]][indices[1]]]
2088 [base_index[indices[2]][indices[3]]];
2097 constexpr std::size_t base_index[3][3] = {{0, 3, 4},
2100 return data[base_index[indices[0]][indices[1]]]
2101 [base_index[indices[2]][indices[3]]];
2116 template <
int dim,
typename Number>
2119 const typename SymmetricTensorAccessors::
2120 StorageType<4, dim, Number>::base_tensor_type &
data)
2134 constexpr std::size_t base_index[2][2] = {{0, 2}, {2, 1}};
2135 return data[base_index[indices[0]][indices[1]]]
2136 [base_index[indices[2]][indices[3]]];
2145 constexpr std::size_t base_index[3][3] = {{0, 3, 4},
2148 return data[base_index[indices[0]][indices[1]]]
2149 [base_index[indices[2]][indices[3]]];
2167template <
int rank_,
int dim,
typename Number>
2172 for (
unsigned int r = 0; r < rank; ++r)
2174 return internal::symmetric_tensor_access<dim, Number>(indices,
data);
2179template <
int rank_,
int dim,
typename Number>
2184 for (
unsigned int r = 0; r < rank; ++r)
2186 return internal::symmetric_tensor_access<dim, Number>(indices,
data);
2193 namespace SymmetricTensorImplementation
2195 template <
int rank_>
2197 get_partially_filled_indices(
const unsigned int row,
2198 const std::integral_constant<int, 2> &)
2204 template <
int rank_>
2206 get_partially_filled_indices(
const unsigned int row,
2207 const std::integral_constant<int, 4> &)
2218template <
int rank_,
int dim,
typename Number>
2220 SymmetricTensorAccessors::Accessor<rank_, dim,
true, rank_ - 1, Number>
2223 return internal::SymmetricTensorAccessors::
2224 Accessor<rank_, dim,
true, rank_ - 1, Number>(
2226 internal::SymmetricTensorImplementation::get_partially_filled_indices<
2227 rank_>(row, std::integral_constant<int, rank_>()));
2232template <
int rank_,
int dim,
typename Number>
2234 SymmetricTensorAccessors::Accessor<rank_, dim,
false, rank_ - 1, Number>
2237 return internal::SymmetricTensorAccessors::
2238 Accessor<rank_, dim,
false, rank_ - 1, Number>(
2240 internal::SymmetricTensorImplementation::get_partially_filled_indices<
2241 rank_>(row, std::integral_constant<int, rank_>()));
2246template <
int rank_,
int dim,
typename Number>
2251 return operator()(indices);
2256template <
int rank_,
int dim,
typename Number>
2261 return operator()(indices);
2266template <
int rank_,
int dim,
typename Number>
2269 const unsigned int index)
const
2272 if constexpr (rank == 2)
2275 return data[
decltype(
data)::unrolled_to_component_indices(index)];
2280template <
int rank_,
int dim,
typename Number>
2285 if constexpr (rank == 2)
2288 return data[
decltype(
data)::unrolled_to_component_indices(index)];
2295 template <
int dim,
typename Number>
2297 compute_norm(
const typename SymmetricTensorAccessors::
2298 StorageType<2, dim, Number>::base_tensor_type &
data)
2325 for (
unsigned int d = 0;
d < dim; ++
d)
2328 for (
unsigned int d = dim;
d < (dim * dim + dim) / 2; ++
d)
2332 return sqrt(return_value);
2339 template <
int dim,
typename Number>
2341 compute_norm(
const typename SymmetricTensorAccessors::
2342 StorageType<4, dim, Number>::base_tensor_type &
data)
2356 const unsigned int n_independent_components =
data.dimension;
2358 for (
unsigned int i = 0; i < dim; ++i)
2359 for (
unsigned int j = 0; j < dim; ++j)
2362 for (
unsigned int i = 0; i < dim; ++i)
2363 for (
unsigned int j = dim; j < n_independent_components; ++j)
2366 for (
unsigned int i = dim; i < n_independent_components; ++i)
2367 for (
unsigned int j = 0; j < dim; ++j)
2370 for (
unsigned int i = dim; i < n_independent_components; ++i)
2371 for (
unsigned int j = dim; j < n_independent_components; ++j)
2375 return sqrt(return_value);
2384template <
int rank_,
int dim,
typename Number>
2388 return internal::compute_norm<dim, Number>(
data);
2393template <
int rank_,
int dim,
typename Number>
2398 return internal::SymmetricTensorImplementation::component_to_unrolled_index<
2406 namespace SymmetricTensorImplementation
2418 const std::integral_constant<int, 2> &)
2456 for (
unsigned int d = 0, c = dim;
d < dim; ++
d)
2457 for (
unsigned int e = d + 1;
e < dim; ++
e, ++c)
2475 template <
int dim,
int rank_>
2476 constexpr inline std::enable_if_t<rank_ != 2, TableIndices<rank_>>
2478 const std::integral_constant<int, rank_> &)
2487 n_independent_components));
2495template <
int rank_,
int dim,
typename Number>
2498 const unsigned int i)
2500 return internal::SymmetricTensorImplementation::unrolled_to_component_indices<
2501 dim>(i, std::integral_constant<int, rank_>());
2506template <
int rank_,
int dim,
typename Number>
2507template <
class Archive>
2532template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2557template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2577template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2594template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2611template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2628template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2639template <
int dim,
typename Number>
2655 return (tmp + tmp + t.
data[0] * t.
data[1] * t.
data[2] -
2679template <
int dim,
typename Number>
2688template <
int dim,
typename Number>
2692 Number t = d.data[0];
2693 for (
unsigned int i = 1; i < dim; ++i)
2710template <
int dim,
typename Number>
2729template <
typename Number>
2756template <
typename Number>
2760 return t[0][0] * t[1][1] - t[0][1] * t[0][1];
2773template <
typename Number>
2777 return (t[0][0] * t[1][1] + t[1][1] * t[2][2] + t[2][2] * t[0][0] -
2778 t[0][1] * t[0][1] - t[0][2] * t[0][2] - t[1][2] * t[1][2]);
2790template <
typename Number>
2791std::array<Number, 1>
2818template <
typename Number>
2819std::array<Number, 2>
2846template <
typename Number>
2847std::array<Number, 3>
2854 namespace SymmetricTensorImplementation
2867 template <
int dim,
typename Number>
2871 std::array<Number, dim> &d,
2872 std::array<Number, dim - 1> &e);
2889 template <
int dim,
typename Number>
2890 std::array<std::pair<Number, Tensor<1, dim, Number>>, dim>
2908 template <
int dim,
typename Number>
2909 std::array<std::pair<Number, Tensor<1, dim, Number>>, dim>
2927 template <
typename Number>
2928 std::array<std::pair<Number, Tensor<1, 2, Number>>, 2>
2929 hybrid(const ::SymmetricTensor<2, 2, Number> &A);
2947 template <
typename Number>
2948 std::array<std::pair<Number, Tensor<1, 3, Number>>, 3>
2949 hybrid(const ::SymmetricTensor<2, 3, Number> &A);
2955 template <
int dim,
typename Number>
2962 return lhs.first > rhs.first;
3029template <
int dim,
typename Number>
3030std::array<std::pair<Number, Tensor<1, dim, Number>>, dim>
3045template <
int rank_,
int dim,
typename Number>
3054template <
int dim,
typename Number>
3063 for (
unsigned int i = 0; i < dim; ++i)
3071template <
int dim,
typename Number>
3092 for (
unsigned int d = 0; d < dim; ++d)
3100template <
int dim,
typename Number>
3107 for (
unsigned int i = 0; i < dim; ++i)
3108 for (
unsigned int j = 0; j < dim; ++j)
3117 for (
unsigned int i = dim;
3118 i < internal::SymmetricTensorAccessors::StorageType<4, dim, Number>::
3128template <
int dim,
typename Number>
3136 for (
unsigned int i = 0; i < dim; ++i)
3144 for (
unsigned int i = dim;
3145 i < internal::SymmetricTensorAccessors::StorageType<4, dim, Number>::
3164template <
int dim,
typename Number>
3184template <
int dim,
typename Number>
3215template <
int dim,
typename Number>
3223 for (
unsigned int i = 0; i < dim; ++i)
3224 for (
unsigned int j = i; j < dim; ++j)
3225 for (
unsigned int k = 0; k < dim; ++k)
3226 for (
unsigned int l = k; l < dim; ++l)
3227 tmp[i][j][k][l] = t1[i][j] * t2[k][l];
3257template <
int dim,
typename Number>
3263 const std::array<std::pair<Number, Tensor<1, dim, Number>>, dim>
3267 positive_negative_tensors;
3269 auto &[positive_part_tensor, negative_part_tensor] =
3270 positive_negative_tensors;
3272 positive_part_tensor = 0;
3273 for (
unsigned int i = 0; i < dim; ++i)
3274 if (eigen_system[i].
first > 0)
3275 positive_part_tensor += eigen_system[i].first *
3277 eigen_system[i].
second));
3279 negative_part_tensor = 0;
3280 for (
unsigned int i = 0; i < dim; ++i)
3281 if (eigen_system[i].
first < 0)
3282 negative_part_tensor += eigen_system[i].first *
3284 eigen_system[i].
second));
3286 return positive_negative_tensors;
3321template <
int dim,
typename Number>
3322std::tuple<SymmetricTensor<2, dim, Number>,
3331 auto heaviside_function{[](
const double x) {
3332 if (std::fabs(x) < 1.0e-16)
3340 std::tuple<SymmetricTensor<2, dim, Number>,
3344 positive_negative_tensors_projectors;
3346 auto &[positive_part_tensor,
3347 negative_part_tensor,
3349 negative_projector] = positive_negative_tensors_projectors;
3351 const std::array<std::pair<Number, Tensor<1, dim, Number>>, dim>
3354 positive_part_tensor = 0;
3355 for (
unsigned int i = 0; i < dim; ++i)
3356 if (eigen_system[i].
first > 0)
3357 positive_part_tensor += eigen_system[i].first *
3359 eigen_system[i].
second));
3361 negative_part_tensor = 0;
3362 for (
unsigned int i = 0; i < dim; ++i)
3363 if (eigen_system[i].
first < 0)
3364 negative_part_tensor += eigen_system[i].first *
3366 eigen_system[i].
second));
3368 std::array<SymmetricTensor<2, dim, Number>, dim> M;
3369 for (
unsigned int a = 0; a < dim; ++a)
3373 std::array<SymmetricTensor<4, dim, Number>, dim> Q;
3374 for (
unsigned int a = 0; a < dim; ++a)
3377 std::array<std::array<SymmetricTensor<4, dim, Number>, dim>, dim> G;
3378 for (
unsigned int a = 0; a < dim; ++a)
3379 for (
unsigned int b = 0; b < dim; ++b)
3380 for (
unsigned int i = 0; i < dim; ++i)
3381 for (
unsigned int j = 0; j < dim; ++j)
3382 for (
unsigned int k = 0; k < dim; ++k)
3383 for (
unsigned int l = 0; l < dim; ++l)
3384 G[a][b][i][j][k][l] =
3385 M[a][i][k] * M[b][j][l] + M[a][i][l] * M[b][j][k];
3388 positive_projector = 0;
3389 for (
unsigned int a = 0; a < dim; ++a)
3391 double lambda_a = eigen_system[a].first;
3392 positive_projector += heaviside_function(lambda_a) * Q[a];
3393 for (
unsigned int b = 0; b < dim; ++b)
3397 double lambda_b = eigen_system[b].first;
3400 if (std::fabs(lambda_a - lambda_b) > 1.0e-12)
3401 v_ab = (std::fmax(lambda_a, 0.0) - std::fmax(lambda_b, 0.0)) /
3402 (lambda_a - lambda_b);
3404 v_ab = 0.5 * (heaviside_function(lambda_a) +
3405 heaviside_function(lambda_b));
3407 positive_projector += 0.5 * v_ab * 0.5 * (G[a][b] + G[b][a]);
3413 negative_projector = 0;
3414 for (
unsigned int a = 0; a < dim; ++a)
3416 double lambda_a = eigen_system[a].first;
3417 negative_projector += heaviside_function(-lambda_a) * Q[a];
3418 for (
unsigned int b = 0; b < dim; ++b)
3422 double lambda_b = eigen_system[b].first;
3425 if (std::fabs(lambda_a - lambda_b) > 1.0e-12)
3426 v_ab = (std::fmin(lambda_a, 0.0) - std::fmin(lambda_b, 0.0)) /
3427 (lambda_a - lambda_b);
3429 v_ab = 0.5 * (heaviside_function(-lambda_a) +
3430 heaviside_function(-lambda_b));
3432 negative_projector += 0.5 * v_ab * 0.5 * (G[a][b] + G[b][a]);
3437 return positive_negative_tensors_projectors;
3447template <
int dim,
typename Number>
3453 for (
unsigned int d = 0; d < dim; ++d)
3454 result[d][d] = t[d][d];
3457 for (
unsigned int d = 0; d < dim; ++d)
3458 for (
unsigned int e = d + 1; e < dim; ++e)
3459 result[d][e] = (t[d][e] + t[e][d]) * half;
3476template <
int dim,
typename Number>
3486 for (
unsigned int i = 0; i < dim; ++i)
3487 for (
unsigned int j = 0; j < dim; ++j)
3488 for (
unsigned int k = 0; k < dim; ++k)
3489 for (
unsigned int l = 0; l < dim; ++l)
3491 if (i != j && k == l)
3494 result[i][j][k][k] = (t[i][j][k][k] + t[j][i][k][k]) * half;
3496 else if (i == j && k != l)
3499 result[i][i][k][l] = (t[i][i][k][l] + t[i][i][l][k]) * half;
3501 else if (i != j && k != l)
3504 result[i][j][k][l] = (t[i][j][k][l] + t[j][i][k][l] +
3505 t[i][j][l][k] + t[j][i][l][k]) *
3511 result[i][j][k][l] = t[i][j][k][l];
3519 for (
unsigned int i = 0; i < dim; ++i)
3520 for (
unsigned int j = i; j < dim; ++j)
3521 for (
unsigned int k = 0; k < dim; ++k)
3522 for (
unsigned int l = k; l < dim; ++l)
3523 result[i][j][k][l] = (t[i][j][k][l] + t[k][l][i][j]) * half;
3537template <
int rank_,
int dim,
typename Number>
3556template <
int rank_,
int dim,
typename Number>
3590template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
3597 const OtherNumber &factor)
3619template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
3629 return (t * factor);
3639template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
3646 const OtherNumber &factor)
3662template <
int rank_,
int dim>
3679template <
int rank_,
int dim>
3695template <
int rank_,
int dim>
3713template <
int dim,
typename Number,
typename OtherNumber>
3735template <
int dim,
typename Number,
typename OtherNumber>
3743 for (
unsigned int i = 0; i < dim; ++i)
3744 for (
unsigned int j = 0; j < dim; ++j)
3745 s += t1[i][j] * t2[i][j];
3762template <
int dim,
typename Number,
typename OtherNumber>
3768 return scalar_product(t2, t1);
3786template <
typename Number,
typename OtherNumber>
3793 tmp[0][0] = t[0][0][0][0] * s[0][0];
3812template <
typename Number,
typename OtherNumber>
3819 tmp[0][0] = t[0][0][0][0] * s[0][0];
3838template <
typename Number,
typename OtherNumber>
3845 const unsigned int dim = 2;
3847 for (
unsigned int i = 0; i < dim; ++i)
3848 for (
unsigned int j = i; j < dim; ++j)
3849 tmp[i][j] = t[i][j][0][0] * s[0][0] + t[i][j][1][1] * s[1][1] +
3850 2 * t[i][j][0][1] * s[0][1];
3869template <
typename Number,
typename OtherNumber>
3876 const unsigned int dim = 2;
3878 for (
unsigned int i = 0; i < dim; ++i)
3879 for (
unsigned int j = i; j < dim; ++j)
3880 tmp[i][j] = s[0][0] * t[0][0][i][j] * +s[1][1] * t[1][1][i][j] +
3881 2 * s[0][1] * t[0][1][i][j];
3900template <
typename Number,
typename OtherNumber>
3907 const unsigned int dim = 3;
3909 for (
unsigned int i = 0; i < dim; ++i)
3910 for (
unsigned int j = i; j < dim; ++j)
3911 tmp[i][j] = t[i][j][0][0] * s[0][0] + t[i][j][1][1] * s[1][1] +
3912 t[i][j][2][2] * s[2][2] + 2 * t[i][j][0][1] * s[0][1] +
3913 2 * t[i][j][0][2] * s[0][2] + 2 * t[i][j][1][2] * s[1][2];
3932template <
typename Number,
typename OtherNumber>
3939 const unsigned int dim = 3;
3941 for (
unsigned int i = 0; i < dim; ++i)
3942 for (
unsigned int j = i; j < dim; ++j)
3943 tmp[i][j] = s[0][0] * t[0][0][i][j] + s[1][1] * t[1][1][i][j] +
3944 s[2][2] * t[2][2][i][j] + 2 * s[0][1] * t[0][1][i][j] +
3945 2 * s[0][2] * t[0][2][i][j] + 2 * s[1][2] * t[1][2][i][j];
3956template <
int dim,
typename Number,
typename OtherNumber>
3964 for (
unsigned int i = 0; i < dim; ++i)
3966 dest[i] = src1[i][0] * src2[0];
3967 for (
unsigned int j = 1; j < dim; ++j)
3968 dest[i] += src1[i][j] * src2[j];
3980template <
int dim,
typename Number,
typename OtherNumber>
4012template <
int rank_1,
4016 typename OtherNumber>
4018 typename Tensor<rank_1 + rank_2 - 2,
4048template <
int rank_1,
4052 typename OtherNumber>
4054 typename Tensor<rank_1 + rank_2 - 2,
4074template <
int dim,
typename Number>
4075inline std::ostream &
4083 for (
unsigned int i = 0; i < dim; ++i)
4084 for (
unsigned int j = 0; j < dim; ++j)
4075inline std::ostream & {
…}
4101template <
int dim,
typename Number>
4102inline std::ostream &
4110 for (
unsigned int i = 0; i < dim; ++i)
4111 for (
unsigned int j = 0; j < dim; ++j)
4112 for (
unsigned int k = 0; k < dim; ++k)
4113 for (
unsigned int l = 0; l < dim; ++l)
4114 tt[i][j][k][l] = t[i][j][k][l];
4102inline std::ostream & {
…}
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
#define DEAL_II_ASSERT_UNREACHABLE()
#define DEAL_II_NOT_IMPLEMENTED()
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)
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 unsigned int invalid_unsigned_int
constexpr bool value_is_zero(const Number &value)
::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 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()