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>
110template <
int dim,
typename Number =
double>
152template <
int dim,
typename Number =
double>
157template <
int dim,
typename Number>
161template <
int dim,
typename Number>
174template <
int dim2,
typename Number>
216template <
int dim,
typename Number>
234template <
int dim,
typename Number>
246 template <
int rank,
int dim,
typename T,
typename U>
252 std::complex<typename ProductType<T, U>::type>>;
255 template <
int rank,
int dim,
typename T,
typename U>
262 std::complex<typename ProductType<T, U>::type>>;
265 template <
typename T,
int rank,
int dim,
typename U>
271 std::complex<typename ProductType<T, U>::type>>;
274 template <
int rank,
int dim,
typename T,
typename U>
281 std::complex<typename ProductType<T, U>::type>>;
295 template <
int rank,
int dim,
typename Number>
314 const unsigned int new_index,
315 const unsigned int position)
322 return {previous_indices[0], new_index};
336 const unsigned int new_index,
337 const unsigned int position)
349 return {previous_indices[0],
354 return {previous_indices[0],
359 return {previous_indices[0],
380 typename OtherNumber = Number>
395 template <
int dim,
typename Number,
typename OtherNumber>
415 template <
int rank,
int dim,
typename Number>
421 template <
int dim,
typename Number>
429 (dim * dim + dim) / 2;
442 template <
int dim,
typename Number>
474 template <
int rank,
int dim,
bool constness,
typename Number>
483 template <
int rank,
int dim,
typename Number>
497 template <
int rank,
int dim,
typename Number>
538 template <
int rank,
int dim,
bool constness,
int P,
typename Number>
585 constexpr Accessor<rank, dim, constness, P - 1, Number>
592 constexpr Accessor<rank, dim, constness, P - 1, Number>
604 template <
int,
int,
typename>
605 friend class ::SymmetricTensor;
606 template <
int,
int,
bool,
int,
typename>
608 friend class ::SymmetricTensor<rank, dim, Number>;
609 friend class Accessor<rank, dim, constness, P + 1, Number>;
621 template <
int rank,
int dim,
bool constness,
typename Number>
690 template <
int,
int,
typename>
691 friend class ::SymmetricTensor;
692 template <
int,
int,
bool,
int,
typename>
694 friend class ::SymmetricTensor<rank, dim, Number>;
696 Accessor<rank, dim, constness, 2, Number>;
775template <int rank_, int dim, typename Number>
779 static_assert(rank_ % 2 == 0,
"A SymmetricTensor must have even rank!");
794 static const unsigned int rank = rank_;
803 n_independent_components;
825 template <
typename OtherNumber>
851 template <
typename OtherNumber>
861 template <
typename OtherNumber>
899 template <
typename OtherNumber>
906 template <
typename OtherNumber>
914 template <
typename OtherNumber>
921 template <
typename OtherNumber>
984 template <
typename OtherNumber>
986 double_contraction_result<rank_, 2, dim, Number, OtherNumber>::type
993 template <
typename OtherNumber>
995 double_contraction_result<rank_, 4, dim, Number, OtherNumber>::type
1009 constexpr const Number &
1017 constexpr internal::SymmetricTensorAccessors::
1018 Accessor<rank_, dim,
true, rank_ - 1, Number>
1026 constexpr internal::SymmetricTensorAccessors::
1027 Accessor<rank_, dim,
false, rank_ - 1, Number>
1036 constexpr const Number &
1055 constexpr const Number &
1127 template <
class Archive>
1151 template <
int,
int,
typename>
1155 template <
int dim2,
typename Number2>
1159 template <
int dim2,
typename Number2>
1163 template <
int dim2,
typename Number2>
1167 template <
int dim2,
typename Number2>
1171 template <
int dim2,
typename Number2>
1175 template <
int dim2,
typename Number2>
1182 Inverse<2, dim, Number>;
1185 Inverse<4, dim, Number>;
1196template <int rank, int dim, typename Number>
1199template <int rank_, int dim, typename Number>
1200constexpr unsigned
int
1205 namespace SymmetricTensorAccessors
1207 template <
int rank_,
int dim,
bool constness,
int P,
typename Number>
1209 Accessor<rank_, dim, constness, P, Number>::Accessor(
1210 tensor_type &tensor,
1213 , previous_indices(previous_indices)
1218 template <
int rank_,
int dim,
bool constness,
int P,
typename Number>
1220 Accessor<rank_, dim, constness, P - 1, Number>
1221 Accessor<rank_, dim, constness, P, Number>::operator[](
1222 const unsigned int i)
1224 return Accessor<rank_, dim, constness, P - 1, Number>(
1225 tensor, merge(previous_indices, i, rank_ - P));
1230 template <
int rank_,
int dim,
bool constness,
int P,
typename Number>
1232 Accessor<rank_, dim, constness, P - 1, Number>
1233 Accessor<rank_, dim, constness, P, Number>::operator[](
1234 const unsigned int i)
const
1236 return Accessor<rank_, dim, constness, P - 1, Number>(
1237 tensor,
merge(previous_indices, i, rank_ - P));
1242 template <
int rank_,
int dim,
bool constness,
typename Number>
1244 Accessor<rank_, dim, constness, 1, Number>::Accessor(
1245 tensor_type &tensor,
1248 , previous_indices(previous_indices)
1253 template <
int rank_,
int dim,
bool constness,
typename Number>
1255 typename Accessor<rank_, dim, constness, 1, Number>::reference
1256 Accessor<rank_, dim, constness, 1, Number>::operator[](
1257 const unsigned int i)
1259 return tensor(
merge(previous_indices, i, rank_ - 1));
1263 template <
int rank_,
int dim,
bool constness,
typename Number>
1265 typename Accessor<rank_, dim, constness, 1, Number>::reference
1266 Accessor<rank_, dim, constness, 1, Number>::operator[](
1267 const unsigned int i)
const
1269 return tensor(
merge(previous_indices, i, rank_ - 1));
1276template <
int rank_,
int dim,
typename Number>
1277template <
typename OtherNumber>
1282 static_assert(rank == 2,
"This function is only implemented for rank==2");
1283 for (
unsigned int d = 0;
d < dim; ++
d)
1284 for (
unsigned int e = 0;
e <
d; ++
e)
1285 Assert(t[d][e] == t[e][d],
1286 ExcMessage(
"The incoming Tensor must be exactly symmetric."));
1288 for (
unsigned int d = 0;
d < dim; ++
d)
1291 for (
unsigned int d = 0, c = 0;
d < dim; ++
d)
1292 for (
unsigned int e = d + 1;
e < dim; ++
e, ++c)
1293 data[dim + c] = t[d][e];
1298template <
int rank_,
int dim,
typename Number>
1299template <
typename OtherNumber>
1303 : data(initializer.data)
1308template <
int rank_,
int dim,
typename Number>
1311 const Number (&array)[n_independent_components])
1313 *reinterpret_cast<const typename base_tensor_type::array_type *>(array))
1316 Assert(
sizeof(
typename base_tensor_type::array_type) ==
sizeof(array),
1322template <
int rank_,
int dim,
typename Number>
1323template <
typename OtherNumber>
1335template <
int rank_,
int dim,
typename Number>
1341 ExcMessage(
"Only assignment with zero is allowed"));
1354 template <
int dim,
typename Number>
1355 constexpr inline DEAL_II_ALWAYS_INLINE ::Tensor<2, dim, Number>
1356 convert_to_tensor(const ::SymmetricTensor<2, dim, Number> &s)
1358 ::Tensor<2, dim, Number> t;
1361 for (
unsigned int d = 0;
d < dim; ++
d)
1362 t[d][d] = s.access_raw_entry(d);
1365 for (
unsigned int d = 0, c = 0;
d < dim; ++
d)
1366 for (
unsigned int e = d + 1;
e < dim; ++
e, ++c)
1368 t[
d][
e] = s.access_raw_entry(dim + c);
1369 t[
e][
d] = s.access_raw_entry(dim + c);
1375 template <
int dim,
typename Number>
1376 constexpr ::Tensor<4, dim, Number>
1377 convert_to_tensor(const ::SymmetricTensor<4, dim, Number> &st)
1382 ::Tensor<4, dim, Number> t;
1384 for (
unsigned int i = 0; i < dim; ++i)
1385 for (
unsigned int j = i; j < dim; ++j)
1386 for (
unsigned int k = 0; k < dim; ++k)
1387 for (
unsigned int l = k;
l < dim; ++
l)
1388 t[TableIndices<4>(i, j, k, l)] = t[TableIndices<4>(i, j, l, k)] =
1389 t[TableIndices<4>(j, i, k, l)] =
1390 t[TableIndices<4>(j, i, l, k)] =
1391 st[TableIndices<4>(i, j, k, l)];
1397 template <
typename Number>
1400 constexpr static inline DEAL_II_ALWAYS_INLINE
1401 ::SymmetricTensor<2, 1, Number>
1402 value(const ::SymmetricTensor<2, 1, Number> &t)
1404 ::SymmetricTensor<2, 1, Number> tmp;
1406 tmp[0][0] = 1.0 / t[0][0];
1413 template <
typename Number>
1416 constexpr static inline DEAL_II_ALWAYS_INLINE
1417 ::SymmetricTensor<2, 2, Number>
1418 value(const ::SymmetricTensor<2, 2, Number> &t)
1420 ::SymmetricTensor<2, 2, Number> tmp;
1425 const TableIndices<2> idx_00(0, 0);
1426 const TableIndices<2> idx_01(0, 1);
1427 const TableIndices<2> idx_11(1, 1);
1428 const Number inv_det_t =
1429 1.0 / (t[idx_00] * t[idx_11] - t[idx_01] * t[idx_01]);
1430 tmp[idx_00] = t[idx_11];
1431 tmp[idx_01] = -t[idx_01];
1432 tmp[idx_11] = t[idx_00];
1440 template <
typename Number>
1443 constexpr static ::SymmetricTensor<2, 3, Number>
1444 value(const ::SymmetricTensor<2, 3, Number> &t)
1446 ::SymmetricTensor<2, 3, Number> tmp;
1482 const TableIndices<2> idx_00(0, 0);
1483 const TableIndices<2> idx_01(0, 1);
1484 const TableIndices<2> idx_02(0, 2);
1485 const TableIndices<2> idx_11(1, 1);
1486 const TableIndices<2> idx_12(1, 2);
1487 const TableIndices<2> idx_22(2, 2);
1488 const Number inv_det_t =
1489 1.0 / (t[idx_00] * t[idx_11] * t[idx_22] -
1490 t[idx_00] * t[idx_12] * t[idx_12] -
1491 t[idx_01] * t[idx_01] * t[idx_22] +
1492 2.0 * t[idx_01] * t[idx_02] * t[idx_12] -
1493 t[idx_02] * t[idx_02] * t[idx_11]);
1494 tmp[idx_00] = t[idx_11] * t[idx_22] - t[idx_12] * t[idx_12];
1495 tmp[idx_01] = -t[idx_01] * t[idx_22] + t[idx_02] * t[idx_12];
1496 tmp[idx_02] = t[idx_01] * t[idx_12] - t[idx_02] * t[idx_11];
1497 tmp[idx_11] = t[idx_00] * t[idx_22] - t[idx_02] * t[idx_02];
1498 tmp[idx_12] = -t[idx_00] * t[idx_12] + t[idx_01] * t[idx_02];
1499 tmp[idx_22] = t[idx_00] * t[idx_11] - t[idx_01] * t[idx_01];
1507 template <
typename Number>
1510 constexpr static inline ::SymmetricTensor<4, 1, Number>
1511 value(const ::SymmetricTensor<4, 1, Number> &t)
1513 ::SymmetricTensor<4, 1, Number> tmp;
1514 tmp.
data[0][0] = 1.0 / t.data[0][0];
1520 template <
typename Number>
1523 constexpr static inline ::SymmetricTensor<4, 2, Number>
1524 value(const ::SymmetricTensor<4, 2, Number> &t)
1526 ::SymmetricTensor<4, 2, Number> tmp;
1550 const Number t4 = t.data[0][0] * t.data[1][1],
1551 t6 = t.data[0][0] * t.data[1][2],
1552 t8 = t.data[0][1] * t.data[1][0],
1553 t00 = t.data[0][2] * t.data[1][0],
1554 t01 = t.data[0][1] * t.data[2][0],
1555 t04 = t.data[0][2] * t.data[2][0],
1556 t07 = 1.0 / (t4 * t.data[2][2] - t6 * t.data[2][1] -
1557 t8 * t.data[2][2] + t00 * t.data[2][1] +
1558 t01 * t.data[1][2] - t04 * t.data[1][1]);
1560 (t.data[1][1] * t.data[2][2] - t.data[1][2] * t.data[2][1]) * t07;
1562 -(t.data[0][1] * t.data[2][2] - t.data[0][2] * t.data[2][1]) * t07;
1564 -(-t.data[0][1] * t.data[1][2] + t.data[0][2] * t.data[1][1]) * t07;
1566 -(t.data[1][0] * t.data[2][2] - t.data[1][2] * t.data[2][0]) * t07;
1567 tmp.
data[1][1] = (t.data[0][0] * t.data[2][2] - t04) * t07;
1568 tmp.
data[1][2] = -(t6 - t00) * t07;
1570 -(-t.data[1][0] * t.data[2][1] + t.data[1][1] * t.data[2][0]) * t07;
1571 tmp.
data[2][1] = -(t.data[0][0] * t.data[2][1] - t01) * t07;
1572 tmp.
data[2][2] = (t4 - t8) * t07;
1576 tmp.
data[2][0] /= 2;
1577 tmp.
data[2][1] /= 2;
1578 tmp.
data[0][2] /= 2;
1579 tmp.
data[1][2] /= 2;
1580 tmp.
data[2][2] /= 4;
1587 template <
typename Number>
1590 static ::SymmetricTensor<4, 3, Number>
1591 value(const ::SymmetricTensor<4, 3, Number> &t)
1593 ::SymmetricTensor<4, 3, Number> tmp = t;
1601 const unsigned int N = 6;
1607 for (
unsigned int i = 0; i <
N; ++i)
1609 const Number typical_diagonal_element =
1610 diagonal_sum /
static_cast<double>(
N);
1611 (void)typical_diagonal_element;
1614 for (
unsigned int i = 0; i <
N; ++i)
1617 for (
unsigned int j = 0; j <
N; ++j)
1623 for (
unsigned int i = j + 1; i <
N; ++i)
1631 Assert(max > 1.e-16 * typical_diagonal_element,
1632 ExcMessage(
"This tensor seems to be noninvertible"));
1637 for (
unsigned int k = 0; k <
N; ++k)
1638 std::swap(tmp.
data[j][k], tmp.
data[r][k]);
1640 std::swap(p[j], p[r]);
1644 const Number hr = 1. / tmp.
data[j][j];
1645 tmp.
data[j][j] = hr;
1646 for (
unsigned int k = 0; k <
N; ++k)
1650 for (
unsigned int i = 0; i <
N; ++i)
1654 tmp.
data[i][k] -= tmp.
data[i][j] * tmp.
data[j][k] * hr;
1657 for (
unsigned int i = 0; i <
N; ++i)
1659 tmp.
data[i][j] *= hr;
1660 tmp.
data[j][i] *= -hr;
1662 tmp.
data[j][j] = hr;
1667 for (
unsigned int i = 0; i <
N; ++i)
1669 for (
unsigned int k = 0; k <
N; ++k)
1670 hv[p[k]] = tmp.
data[i][k];
1671 for (
unsigned int k = 0; k <
N; ++k)
1672 tmp.
data[i][k] = hv[k];
1677 for (
unsigned int i = 3; i < 6; ++i)
1678 for (
unsigned int j = 0; j < 3; ++j)
1679 tmp.
data[i][j] /= 2;
1681 for (
unsigned int i = 0; i < 3; ++i)
1682 for (
unsigned int j = 3; j < 6; ++j)
1683 tmp.
data[i][j] /= 2;
1685 for (
unsigned int i = 3; i < 6; ++i)
1686 for (
unsigned int j = 3; j < 6; ++j)
1687 tmp.
data[i][j] /= 4;
1698template <
int rank_,
int dim,
typename Number>
1703 return internal::SymmetricTensorImplementation::convert_to_tensor(*
this);
1708template <
int rank_,
int dim,
typename Number>
1713 return data == t.
data;
1718template <
int rank_,
int dim,
typename Number>
1723 return data != t.
data;
1728template <
int rank_,
int dim,
typename Number>
1729template <
typename OtherNumber>
1741template <
int rank_,
int dim,
typename Number>
1742template <
typename OtherNumber>
1754template <
int rank_,
int dim,
typename Number>
1755template <
typename OtherNumber>
1766template <
int rank_,
int dim,
typename Number>
1767template <
typename OtherNumber>
1778template <
int rank_,
int dim,
typename Number>
1790template <
int rank_,
int dim,
typename Number>
1799template <
int rank_,
int dim,
typename Number>
1815 template <
int dim,
typename Number,
typename OtherNumber = Number>
1817 typename SymmetricTensorAccessors::
1818 double_contraction_result<2, 2, dim, Number, OtherNumber>::type
1819 perform_double_contraction(
1821 base_tensor_type &data,
1823 StorageType<2, dim, OtherNumber>::base_tensor_type &sdata)
1825 using result_type =
typename SymmetricTensorAccessors::
1826 double_contraction_result<2, 2, dim, Number, OtherNumber>::type;
1831 return data[0] * sdata[0];
1839 result_type
sum = data[dim] * sdata[dim];
1840 for (
unsigned int d = dim + 1;
d < (dim * (dim + 1) / 2); ++
d)
1841 sum += data[d] * sdata[d];
1845 for (
unsigned int d = 0;
d < dim; ++
d)
1846 sum += data[d] * sdata[d];
1857 template <
int dim,
typename Number,
typename OtherNumber = Number>
1859 typename SymmetricTensorAccessors::
1860 double_contraction_result<4, 2, dim, Number, OtherNumber>::type
1861 perform_double_contraction(
1863 base_tensor_type &data,
1865 StorageType<2, dim, OtherNumber>::base_tensor_type &sdata)
1867 using result_type =
typename SymmetricTensorAccessors::
1868 double_contraction_result<4, 2, dim, Number, OtherNumber>::type;
1869 using value_type =
typename SymmetricTensorAccessors::
1870 double_contraction_result<4, 2, dim, Number, OtherNumber>::value_type;
1872 const unsigned int data_dim = SymmetricTensorAccessors::
1873 StorageType<2, dim, value_type>::n_independent_components;
1874 value_type tmp[data_dim]{};
1875 for (
unsigned int i = 0; i < data_dim; ++i)
1877 perform_double_contraction<dim, Number, OtherNumber>(data[i], sdata);
1878 return result_type(tmp);
1887 template <
int dim,
typename Number,
typename OtherNumber = Number>
1892 typename SymmetricTensorAccessors::
1893 double_contraction_result<2, 4, dim, Number, OtherNumber>::value_type>::
1895 perform_double_contraction(
1897 base_tensor_type &data,
1899 StorageType<4, dim, OtherNumber>::base_tensor_type &sdata)
1901 using value_type =
typename SymmetricTensorAccessors::
1902 double_contraction_result<2, 4, dim, Number, OtherNumber>::value_type;
1903 using base_tensor_type =
typename SymmetricTensorAccessors::
1904 StorageType<2, dim, value_type>::base_tensor_type;
1906 base_tensor_type tmp;
1907 for (
unsigned int i = 0; i < tmp.dimension; ++i)
1914 value_type
sum = data[dim] * sdata[dim][i];
1915 for (
unsigned int d = dim + 1;
d < (dim * (dim + 1) / 2); ++
d)
1916 sum += data[d] * sdata[d][i];
1920 for (
unsigned int d = 0;
d < dim; ++
d)
1921 sum += data[d] * sdata[d][i];
1932 template <
int dim,
typename Number,
typename OtherNumber = Number>
1937 typename SymmetricTensorAccessors::
1938 double_contraction_result<4, 4, dim, Number, OtherNumber>::value_type>::
1940 perform_double_contraction(
1942 base_tensor_type &data,
1944 StorageType<4, dim, OtherNumber>::base_tensor_type &sdata)
1946 using value_type =
typename SymmetricTensorAccessors::
1947 double_contraction_result<4, 4, dim, Number, OtherNumber>::value_type;
1948 using base_tensor_type =
typename SymmetricTensorAccessors::
1949 StorageType<4, dim, value_type>::base_tensor_type;
1951 const unsigned int data_dim = SymmetricTensorAccessors::
1952 StorageType<2, dim, value_type>::n_independent_components;
1953 base_tensor_type tmp;
1954 for (
unsigned int i = 0; i < data_dim; ++i)
1955 for (
unsigned int j = 0; j < data_dim; ++j)
1958 for (
unsigned int d = dim;
d < (dim * (dim + 1) / 2); ++
d)
1959 tmp[i][j] += data[i][d] * sdata[d][j];
1960 tmp[i][j] += tmp[i][j];
1963 for (
unsigned int d = 0;
d < dim; ++
d)
1964 tmp[i][j] += data[i][d] * sdata[d][j];
1973template <
int rank_,
int dim,
typename Number>
1974template <
typename OtherNumber>
1976 typename internal::SymmetricTensorAccessors::
1977 double_contraction_result<rank_, 2, dim, Number, OtherNumber>::type
1983 return internal::perform_double_contraction<dim, Number, OtherNumber>(data,
1989template <
int rank_,
int dim,
typename Number>
1990template <
typename OtherNumber>
1992 typename internal::SymmetricTensorAccessors::
1993 double_contraction_result<rank_, 4, dim, Number, OtherNumber>::type
1997 typename internal::SymmetricTensorAccessors::
1998 double_contraction_result<rank_, 4, dim, Number, OtherNumber>::type tmp;
2000 internal::perform_double_contraction<dim, Number, OtherNumber>(data,
2039 constexpr ::ndarray<unsigned int, 2, 2> table = {
2040 {{{0, 2}}, {{2, 1}}}};
2041 return table[indices[0]][indices[1]];
2045 constexpr ::ndarray<unsigned int, 3, 3> table = {
2046 {{{0, 3, 4}}, {{3, 1, 5}}, {{4, 5, 2}}}};
2047 return table[indices[0]][indices[1]];
2051 constexpr ::ndarray<unsigned int, 4, 4> table = {
2056 return table[indices[0]][indices[1]];
2061 if (indices[0] == indices[1])
2064 const TableIndices<2> sorted_indices(
2072 for (
unsigned int d = 0;
d < dim; ++
d)
2073 for (
unsigned int e = d + 1;
e < dim; ++
e, ++c)
2074 if ((sorted_indices[0] == d) && (sorted_indices[1] == e))
2090 template <
int dim,
int rank_>
2091 constexpr inline unsigned int
2100 template <
int dim,
typename Number>
2102 symmetric_tensor_access(
const TableIndices<2> &indices,
2104 StorageType<2, dim, Number>::base_tensor_type &data)
2112 template <
int dim,
typename Number>
2114 symmetric_tensor_access(
const TableIndices<2> &indices,
2116 StorageType<2, dim, Number>::base_tensor_type &data)
2124 template <
int dim,
typename Number>
2125 constexpr inline Number &
2126 symmetric_tensor_access(
const TableIndices<4> &indices,
2128 StorageType<4, dim, Number>::base_tensor_type &data)
2142 constexpr std::size_t base_index[2][2] = {{0, 2}, {2, 1}};
2143 return data[base_index[indices[0]][indices[1]]]
2144 [base_index[indices[2]][indices[3]]];
2153 constexpr std::size_t base_index[3][3] = {{0, 3, 4},
2156 return data[base_index[indices[0]][indices[1]]]
2157 [base_index[indices[2]][indices[3]]];
2172 template <
int dim,
typename Number>
2174 symmetric_tensor_access(
const TableIndices<4> &indices,
2176 StorageType<4, dim, Number>::base_tensor_type &data)
2190 constexpr std::size_t base_index[2][2] = {{0, 2}, {2, 1}};
2191 return data[base_index[indices[0]][indices[1]]]
2192 [base_index[indices[2]][indices[3]]];
2201 constexpr std::size_t base_index[3][3] = {{0, 3, 4},
2204 return data[base_index[indices[0]][indices[1]]]
2205 [base_index[indices[2]][indices[3]]];
2223template <
int rank_,
int dim,
typename Number>
2228 for (
unsigned int r = 0; r < rank; ++r)
2230 return internal::symmetric_tensor_access<dim, Number>(indices, data);
2235template <
int rank_,
int dim,
typename Number>
2240 for (
unsigned int r = 0; r < rank; ++r)
2242 return internal::symmetric_tensor_access<dim, Number>(indices, data);
2251 template <
int rank_>
2252 constexpr TableIndices<rank_>
2253 get_partially_filled_indices(
const unsigned int row,
2254 const std::integral_constant<int, 2> &)
2260 template <
int rank_>
2261 constexpr TableIndices<rank_>
2262 get_partially_filled_indices(
const unsigned int row,
2263 const std::integral_constant<int, 4> &)
2265 return TableIndices<rank_>(row,
2274template <
int rank_,
int dim,
typename Number>
2276 SymmetricTensorAccessors::Accessor<rank_, dim,
true, rank_ - 1, Number>
2279 return internal::SymmetricTensorAccessors::
2280 Accessor<rank_, dim,
true, rank_ - 1, Number>(
2282 internal::SymmetricTensorImplementation::get_partially_filled_indices<
2283 rank_>(row, std::integral_constant<int, rank_>()));
2288template <
int rank_,
int dim,
typename Number>
2290 SymmetricTensorAccessors::Accessor<rank_, dim,
false, rank_ - 1, Number>
2293 return internal::SymmetricTensorAccessors::
2294 Accessor<rank_, dim,
false, rank_ - 1, Number>(
2296 internal::SymmetricTensorImplementation::get_partially_filled_indices<
2297 rank_>(row, std::integral_constant<int, rank_>()));
2302template <
int rank_,
int dim,
typename Number>
2307 return operator()(indices);
2312template <
int rank_,
int dim,
typename Number>
2317 return operator()(indices);
2322template <
int rank_,
int dim,
typename Number>
2325 const unsigned int index)
const
2328 if constexpr (rank == 2)
2331 return data[
decltype(data)::unrolled_to_component_indices(index)];
2336template <
int rank_,
int dim,
typename Number>
2341 if constexpr (rank == 2)
2344 return data[
decltype(data)::unrolled_to_component_indices(index)];
2351 template <
int dim,
typename Number>
2354 StorageType<2, dim, Number>::base_tensor_type &data)
2381 for (
unsigned int d = 0;
d < dim; ++
d)
2384 for (
unsigned int d = dim;
d < (dim * dim + dim) / 2; ++
d)
2388 return sqrt(return_value);
2395 template <
int dim,
typename Number>
2398 StorageType<4, dim, Number>::base_tensor_type &data)
2412 const unsigned int n_independent_components = data.dimension;
2414 for (
unsigned int i = 0; i < dim; ++i)
2415 for (
unsigned int j = 0; j < dim; ++j)
2418 for (
unsigned int i = 0; i < dim; ++i)
2419 for (
unsigned int j = dim; j < n_independent_components; ++j)
2422 for (
unsigned int i = dim; i < n_independent_components; ++i)
2423 for (
unsigned int j = 0; j < dim; ++j)
2426 for (
unsigned int i = dim; i < n_independent_components; ++i)
2427 for (
unsigned int j = dim; j < n_independent_components; ++j)
2431 return sqrt(return_value);
2440template <
int rank_,
int dim,
typename Number>
2444 return internal::compute_norm<dim, Number>(data);
2449template <
int rank_,
int dim,
typename Number>
2454 return internal::SymmetricTensorImplementation::component_to_unrolled_index<
2474 const std::integral_constant<int, 2> &)
2491 const TableIndices<2> table[3] = {TableIndices<2>(0, 0),
2492 TableIndices<2>(1, 1),
2493 TableIndices<2>(0, 1)};
2499 const TableIndices<2> table[6] = {TableIndices<2>(0, 0),
2500 TableIndices<2>(1, 1),
2501 TableIndices<2>(2, 2),
2502 TableIndices<2>(0, 1),
2503 TableIndices<2>(0, 2),
2504 TableIndices<2>(1, 2)};
2512 for (
unsigned int d = 0, c = dim;
d < dim; ++
d)
2513 for (
unsigned int e = d + 1;
e < dim; ++
e, ++c)
2531 template <
int dim,
int rank_>
2532 constexpr inline std::enable_if_t<rank_ != 2, TableIndices<rank_>>
2534 const std::integral_constant<int, rank_> &)
2542 ::SymmetricTensor<rank_, dim, double>::
2543 n_independent_components));
2545 return TableIndices<rank_>();
2551template <
int rank_,
int dim,
typename Number>
2554 const unsigned int i)
2556 return internal::SymmetricTensorImplementation::unrolled_to_component_indices<
2557 dim>(i, std::integral_constant<int, rank_>());
2562template <
int rank_,
int dim,
typename Number>
2563template <
class Archive>
2588template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2613template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2633template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2650template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2667template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2684template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2695template <
int dim,
typename Number>
2711 return (tmp + tmp + t.
data[0] * t.
data[1] * t.
data[2] -
2735template <
int dim,
typename Number>
2744template <
int dim,
typename Number>
2748 Number t = d.data[0];
2749 for (
unsigned int i = 1; i < dim; ++i)
2766template <
int dim,
typename Number>
2785template <
typename Number>
2812template <
typename Number>
2816 return t[0][0] * t[1][1] - t[0][1] * t[0][1];
2829template <
typename Number>
2833 return (t[0][0] * t[1][1] + t[1][1] * t[2][2] + t[2][2] * t[0][0] -
2834 t[0][1] * t[0][1] - t[0][2] * t[0][2] - t[1][2] * t[1][2]);
2846template <
typename Number>
2847std::array<Number, 1>
2874template <
typename Number>
2875std::array<Number, 2>
2902template <
typename Number>
2903std::array<Number, 3>
2910 namespace SymmetricTensorImplementation
2923 template <
int dim,
typename Number>
2927 std::array<Number, dim> &d,
2928 std::array<Number, dim - 1> &e);
2945 template <
int dim,
typename Number>
2946 std::array<std::pair<Number, Tensor<1, dim, Number>>, dim>
2964 template <
int dim,
typename Number>
2965 std::array<std::pair<Number, Tensor<1, dim, Number>>, dim>
2983 template <
typename Number>
2984 std::array<std::pair<Number, Tensor<1, 2, Number>>, 2>
2985 hybrid(const ::SymmetricTensor<2, 2, Number> &A);
3003 template <
typename Number>
3004 std::array<std::pair<Number, Tensor<1, 3, Number>>, 3>
3005 hybrid(const ::SymmetricTensor<2, 3, Number> &A);
3011 template <
int dim,
typename Number>
3018 return lhs.first > rhs.first;
3085template <
int dim,
typename Number>
3086std::array<std::pair<Number, Tensor<1, dim, Number>>, dim>
3101template <
int rank_,
int dim,
typename Number>
3110template <
int dim,
typename Number>
3119 for (
unsigned int i = 0; i < dim; ++i)
3127template <
int dim,
typename Number>
3148 for (
unsigned int d = 0; d < dim; ++d)
3156template <
int dim,
typename Number>
3163 for (
unsigned int i = 0; i < dim; ++i)
3164 for (
unsigned int j = 0; j < dim; ++j)
3173 for (
unsigned int i = dim;
3174 i < internal::SymmetricTensorAccessors::StorageType<4, dim, Number>::
3184template <
int dim,
typename Number>
3192 for (
unsigned int i = 0; i < dim; ++i)
3200 for (
unsigned int i = dim;
3201 i < internal::SymmetricTensorAccessors::StorageType<4, dim, Number>::
3220template <
int dim,
typename Number>
3240template <
int dim,
typename Number>
3271template <
int dim,
typename Number>
3279 for (
unsigned int i = 0; i < dim; ++i)
3280 for (
unsigned int j = i; j < dim; ++j)
3281 for (
unsigned int k = 0; k < dim; ++k)
3282 for (
unsigned int l = k; l < dim; ++l)
3283 tmp[i][j][k][l] = t1[i][j] * t2[k][l];
3313template <
int dim,
typename Number>
3319 const std::array<std::pair<Number, Tensor<1, dim, Number>>, dim>
3323 positive_negative_tensors;
3325 auto &[positive_part_tensor, negative_part_tensor] =
3326 positive_negative_tensors;
3328 positive_part_tensor = 0;
3329 for (
unsigned int i = 0; i < dim; ++i)
3330 if (eigen_system[i].first > 0)
3331 positive_part_tensor += eigen_system[i].first *
3333 eigen_system[i].second));
3335 negative_part_tensor = 0;
3336 for (
unsigned int i = 0; i < dim; ++i)
3337 if (eigen_system[i].first < 0)
3338 negative_part_tensor += eigen_system[i].first *
3340 eigen_system[i].second));
3342 return positive_negative_tensors;
3377template <
int dim,
typename Number>
3378std::tuple<SymmetricTensor<2, dim, Number>,
3387 auto heaviside_function{[](
const double x) {
3388 if (std::fabs(x) < 1.0e-16)
3396 std::tuple<SymmetricTensor<2, dim, Number>,
3400 positive_negative_tensors_projectors;
3402 auto &[positive_part_tensor,
3403 negative_part_tensor,
3405 negative_projector] = positive_negative_tensors_projectors;
3407 const std::array<std::pair<Number, Tensor<1, dim, Number>>, dim>
3410 positive_part_tensor = 0;
3411 for (
unsigned int i = 0; i < dim; ++i)
3412 if (eigen_system[i].first > 0)
3413 positive_part_tensor += eigen_system[i].first *
3415 eigen_system[i].second));
3417 negative_part_tensor = 0;
3418 for (
unsigned int i = 0; i < dim; ++i)
3419 if (eigen_system[i].first < 0)
3420 negative_part_tensor += eigen_system[i].first *
3422 eigen_system[i].second));
3424 std::array<SymmetricTensor<2, dim, Number>, dim> M;
3425 for (
unsigned int a = 0; a < dim; ++a)
3429 std::array<SymmetricTensor<4, dim, Number>, dim> Q;
3430 for (
unsigned int a = 0; a < dim; ++a)
3433 std::array<std::array<SymmetricTensor<4, dim, Number>, dim>, dim> G;
3434 for (
unsigned int a = 0; a < dim; ++a)
3435 for (
unsigned int b = 0; b < dim; ++b)
3436 for (
unsigned int i = 0; i < dim; ++i)
3437 for (
unsigned int j = 0; j < dim; ++j)
3438 for (
unsigned int k = 0; k < dim; ++k)
3439 for (
unsigned int l = 0; l < dim; ++l)
3440 G[a][b][i][j][k][l] =
3441 M[a][i][k] * M[b][j][l] + M[a][i][l] * M[b][j][k];
3444 positive_projector = 0;
3445 for (
unsigned int a = 0; a < dim; ++a)
3447 double lambda_a = eigen_system[a].first;
3448 positive_projector += heaviside_function(lambda_a) * Q[a];
3449 for (
unsigned int b = 0; b < dim; ++b)
3453 double lambda_b = eigen_system[b].first;
3456 if (std::fabs(lambda_a - lambda_b) > 1.0e-12)
3457 v_ab = (std::fmax(lambda_a, 0.0) - std::fmax(lambda_b, 0.0)) /
3458 (lambda_a - lambda_b);
3460 v_ab = 0.5 * (heaviside_function(lambda_a) +
3461 heaviside_function(lambda_b));
3463 positive_projector += 0.5 * v_ab * 0.5 * (G[a][b] + G[b][a]);
3469 negative_projector = 0;
3470 for (
unsigned int a = 0; a < dim; ++a)
3472 double lambda_a = eigen_system[a].first;
3473 negative_projector += heaviside_function(-lambda_a) * Q[a];
3474 for (
unsigned int b = 0; b < dim; ++b)
3478 double lambda_b = eigen_system[b].first;
3481 if (std::fabs(lambda_a - lambda_b) > 1.0e-12)
3482 v_ab = (std::fmin(lambda_a, 0.0) - std::fmin(lambda_b, 0.0)) /
3483 (lambda_a - lambda_b);
3485 v_ab = 0.5 * (heaviside_function(-lambda_a) +
3486 heaviside_function(-lambda_b));
3488 negative_projector += 0.5 * v_ab * 0.5 * (G[a][b] + G[b][a]);
3493 return positive_negative_tensors_projectors;
3503template <
int dim,
typename Number>
3509 for (
unsigned int d = 0; d < dim; ++d)
3510 result[d][d] = t[d][d];
3513 for (
unsigned int d = 0; d < dim; ++d)
3514 for (
unsigned int e = d + 1; e < dim; ++e)
3515 result[d][e] = (t[d][e] + t[e][d]) * half;
3532template <
int dim,
typename Number>
3542 for (
unsigned int i = 0; i < dim; ++i)
3543 for (
unsigned int j = 0; j < dim; ++j)
3544 for (
unsigned int k = 0; k < dim; ++k)
3545 for (
unsigned int l = 0; l < dim; ++l)
3547 if (i != j && k == l)
3550 result[i][j][k][k] = (t[i][j][k][k] + t[j][i][k][k]) * half;
3552 else if (i == j && k != l)
3555 result[i][i][k][l] = (t[i][i][k][l] + t[i][i][l][k]) * half;
3557 else if (i != j && k != l)
3560 result[i][j][k][l] = (t[i][j][k][l] + t[j][i][k][l] +
3561 t[i][j][l][k] + t[j][i][l][k]) *
3567 result[i][j][k][l] = t[i][j][k][l];
3575 for (
unsigned int i = 0; i < dim; ++i)
3576 for (
unsigned int j = i; j < dim; ++j)
3577 for (
unsigned int k = 0; k < dim; ++k)
3578 for (
unsigned int l = k; l < dim; ++l)
3579 result[i][j][k][l] = (t[i][j][k][l] + t[k][l][i][j]) * half;
3593template <
int rank_,
int dim,
typename Number>
3612template <
int rank_,
int dim,
typename Number>
3646template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
3653 const OtherNumber &factor)
3675template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
3685 return (t * factor);
3695template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
3702 const OtherNumber &factor)
3718template <
int rank_,
int dim>
3735template <
int rank_,
int dim>
3751template <
int rank_,
int dim>
3769template <
int dim,
typename Number,
typename OtherNumber>
3791template <
int dim,
typename Number,
typename OtherNumber>
3799 for (
unsigned int i = 0; i < dim; ++i)
3800 for (
unsigned int j = 0; j < dim; ++j)
3801 s += t1[i][j] * t2[i][j];
3818template <
int dim,
typename Number,
typename OtherNumber>
3842template <
typename Number,
typename OtherNumber>
3849 tmp[0][0] = t[0][0][0][0] * s[0][0];
3868template <
typename Number,
typename OtherNumber>
3875 tmp[0][0] = t[0][0][0][0] * s[0][0];
3894template <
typename Number,
typename OtherNumber>
3901 const unsigned int dim = 2;
3903 for (
unsigned int i = 0; i < dim; ++i)
3904 for (
unsigned int j = i; j < dim; ++j)
3905 tmp[i][j] = t[i][j][0][0] * s[0][0] + t[i][j][1][1] * s[1][1] +
3906 2 * t[i][j][0][1] * s[0][1];
3925template <
typename Number,
typename OtherNumber>
3932 const unsigned int dim = 2;
3934 for (
unsigned int i = 0; i < dim; ++i)
3935 for (
unsigned int j = i; j < dim; ++j)
3936 tmp[i][j] = s[0][0] * t[0][0][i][j] * +s[1][1] * t[1][1][i][j] +
3937 2 * s[0][1] * t[0][1][i][j];
3956template <
typename Number,
typename OtherNumber>
3963 const unsigned int dim = 3;
3965 for (
unsigned int i = 0; i < dim; ++i)
3966 for (
unsigned int j = i; j < dim; ++j)
3967 tmp[i][j] = t[i][j][0][0] * s[0][0] + t[i][j][1][1] * s[1][1] +
3968 t[i][j][2][2] * s[2][2] + 2 * t[i][j][0][1] * s[0][1] +
3969 2 * t[i][j][0][2] * s[0][2] + 2 * t[i][j][1][2] * s[1][2];
3988template <
typename Number,
typename OtherNumber>
3995 const unsigned int dim = 3;
3997 for (
unsigned int i = 0; i < dim; ++i)
3998 for (
unsigned int j = i; j < dim; ++j)
3999 tmp[i][j] = s[0][0] * t[0][0][i][j] + s[1][1] * t[1][1][i][j] +
4000 s[2][2] * t[2][2][i][j] + 2 * s[0][1] * t[0][1][i][j] +
4001 2 * s[0][2] * t[0][2][i][j] + 2 * s[1][2] * t[1][2][i][j];
4012template <
int dim,
typename Number,
typename OtherNumber>
4020 for (
unsigned int i = 0; i < dim; ++i)
4022 dest[i] = src1[i][0] * src2[0];
4023 for (
unsigned int j = 1; j < dim; ++j)
4024 dest[i] += src1[i][j] * src2[j];
4036template <
int dim,
typename Number,
typename OtherNumber>
4068template <
int rank_1,
4072 typename OtherNumber>
4074 typename Tensor<rank_1 + rank_2 - 2,
4104template <
int rank_1,
4108 typename OtherNumber>
4110 typename Tensor<rank_1 + rank_2 - 2,
4130template <
int dim,
typename Number>
4131inline std::ostream &
4139 for (
unsigned int i = 0; i < dim; ++i)
4140 for (
unsigned int j = 0; j < dim; ++j)
4157template <
int dim,
typename Number>
4158inline std::ostream &
4166 for (
unsigned int i = 0; i < dim; ++i)
4167 for (
unsigned int j = 0; j < dim; ++j)
4168 for (
unsigned int k = 0; k < dim; ++k)
4169 for (
unsigned int l = 0; l < dim; ++l)
4170 tt[i][j][k][l] = t[i][j][k][l];
DEAL_II_HOST constexpr SymmetricTensor< rank_, dim, Number > operator*(const SymmetricTensor< rank_, dim, Number > &t, const Number &factor)
DEAL_II_HOST constexpr Number determinant(const SymmetricTensor< 2, dim, Number > &)
DEAL_II_HOST constexpr SymmetricTensor< rank_, dim, Number > transpose(const SymmetricTensor< rank_, dim, Number > &t)
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)
internal::SymmetricTensorAccessors::StorageType< rank_, dim, std::complex< typename ProductType< T, U >::type > > base_tensor_descriptor
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)
static const unsigned int rank
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 internal::SymmetricTensorAccessors::Accessor< rank_, dim, true, rank_ - 1, Number > operator[](const unsigned int row) const
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)
static constexpr unsigned int dimension
DEAL_II_HOST constexpr SymmetricTensor()=default
DEAL_II_HOST constexpr Number second_invariant(const SymmetricTensor< 2, 3, Number > &t)
DEAL_II_HOST constexpr internal::SymmetricTensorAccessors::Accessor< rank_, dim, false, rank_ - 1, Number > operator[](const unsigned int row)
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)
static constexpr unsigned int n_independent_components
std::array< Number, 3 > eigenvalues(const SymmetricTensor< 2, 3, Number > &T)
typename AccessorTypes< rank, dim, constness, Number >::tensor_type tensor_type
typename AccessorTypes< rank, dim, constness, Number >::reference reference
const TableIndices< rank > previous_indices
friend class SymmetricTensorAccessors::Accessor
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
const unsigned int DoFAccessor< structdim, dim, spacedim, level_dof_access >::dimension
#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)
const bool IsBlockVector< VectorType >::value
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)
SymmetricTensor< rank, dim, std::complex< typename ProductType< T, U >::type > > type
SymmetricTensor< rank, dim, std::complex< typename ProductType< T, U >::type > > type
SymmetricTensor< rank, dim, std::complex< typename ProductType< T, U >::type > > type
SymmetricTensor< rank, dim, std::complex< typename ProductType< T, U >::type > > type
::SymmetricTensor< rank, dim, Number > tensor_type
const ::SymmetricTensor< rank, dim, Number > tensor_type
Tensor< 1, n_independent_components, Number > base_tensor_type
static const unsigned int n_independent_components
Tensor< 2, n_rank2_components, Number > base_tensor_type
static const unsigned int n_independent_components
static const unsigned int n_rank2_components
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)
static constexpr real_type abs_square(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()
constexpr ProductType< Number, OtherNumber >::type scalar_product(const Tensor< rank, dim, Number > &left, const Tensor< rank, dim, OtherNumber > &right)