15#ifndef dealii_symmetric_tensor_h
16#define dealii_symmetric_tensor_h
33template <
int rank,
int dim,
typename Number =
double>
47template <
int dim,
typename Number =
double>
80template <
int dim,
typename Number =
double>
122template <
int dim,
typename Number =
double>
127template <
int dim,
typename Number>
131template <
int dim,
typename Number>
144template <
int dim2,
typename Number>
158template <
int dim,
typename Number>
176template <
int dim,
typename Number>
188 template <
int rank,
int dim,
typename T,
typename U>
194 std::complex<typename ProductType<T, U>::type>>;
197 template <
int rank,
int dim,
typename T,
typename U>
204 std::complex<typename ProductType<T, U>::type>>;
207 template <
typename T,
int rank,
int dim,
typename U>
213 std::complex<typename ProductType<T, U>::type>>;
216 template <
int rank,
int dim,
typename T,
typename U>
223 std::complex<typename ProductType<T, U>::type>>;
231 namespace SymmetricTensorImplementation
237 template <
int rank,
int dim,
typename Number>
245 namespace SymmetricTensorAccessors
256 const unsigned int new_index,
257 const unsigned int position)
264 return {previous_indices[0], new_index};
278 const unsigned int new_index,
279 const unsigned int position)
291 return {previous_indices[0],
296 return {previous_indices[0],
301 return {previous_indices[0],
322 typename OtherNumber = Number>
337 template <
int dim,
typename Number,
typename OtherNumber>
357 template <
int rank,
int dim,
typename Number>
363 template <
int dim,
typename Number>
370 static const unsigned int n_independent_components =
371 (dim * dim + dim) / 2;
384 template <
int dim,
typename Number>
392 static const unsigned int n_rank2_components = (dim * dim + dim) / 2;
397 static const unsigned int n_independent_components =
398 (n_rank2_components *
416 template <
int rank,
int dim,
bool constness,
typename Number>
425 template <
int rank,
int dim,
typename Number>
439 template <
int rank,
int dim,
typename Number>
480 template <
int rank,
int dim,
bool constness,
int P,
typename Number>
527 constexpr Accessor<rank, dim, constness, P - 1, Number>
534 constexpr Accessor<rank, dim, constness, P - 1, Number>
546 template <
int,
int,
typename>
547 friend class ::SymmetricTensor;
548 template <
int,
int,
bool,
int,
typename>
550 friend class ::SymmetricTensor<rank, dim, Number>;
551 friend class Accessor<rank, dim, constness, P + 1, Number>;
563 template <
int rank,
int dim,
bool constness,
typename Number>
632 template <
int,
int,
typename>
633 friend class ::SymmetricTensor;
634 template <
int,
int,
bool,
int,
typename>
636 friend class ::SymmetricTensor<rank, dim, Number>;
637 friend class SymmetricTensorAccessors::
638 Accessor<rank, dim, constness, 2, Number>;
717template <int rank_, int dim, typename Number>
721 static_assert(rank_ % 2 == 0,
"A SymmetricTensor must have even rank!");
731 static constexpr unsigned int dimension = dim;
736 static const unsigned int rank = rank_;
743 static constexpr unsigned int n_independent_components =
745 n_independent_components;
767 template <
typename OtherNumber>
793 template <
typename OtherNumber>
852 template <
typename OtherNumber>
890 template <
typename OtherNumber>
897 template <
typename OtherNumber>
905 template <
typename OtherNumber>
912 template <
typename OtherNumber>
975 template <
typename OtherNumber>
977 double_contraction_result<rank_, 2, dim, Number, OtherNumber>::type
984 template <
typename OtherNumber>
986 double_contraction_result<rank_, 4, dim, Number, OtherNumber>::type
1000 constexpr const Number &
1008 constexpr internal::SymmetricTensorAccessors::
1009 Accessor<rank_, dim,
true, rank_ - 1, Number>
1017 constexpr internal::SymmetricTensorAccessors::
1018 Accessor<rank_, dim,
false, rank_ - 1, Number>
1027 constexpr const Number &
1046 constexpr const Number &
1118 template <
class Archive>
1142 template <
int,
int,
typename>
1146 template <
int dim2,
typename Number2>
1150 template <
int dim2,
typename Number2>
1154 template <
int dim2,
typename Number2>
1158 template <
int dim2,
typename Number2>
1162 template <
int dim2,
typename Number2>
1166 template <
int dim2,
typename Number2>
1173 Inverse<2, dim, Number>;
1176 Inverse<4, dim, Number>;
1187template <int rank, int dim, typename Number>
1190template <int rank_, int dim, typename Number>
1191constexpr unsigned
int
1196 namespace SymmetricTensorAccessors
1198 template <
int rank_,
int dim,
bool constness,
int P,
typename Number>
1200 Accessor<rank_, dim, constness, P, Number>::Accessor(
1201 tensor_type &tensor,
1204 , previous_indices(previous_indices)
1209 template <
int rank_,
int dim,
bool constness,
int P,
typename Number>
1211 Accessor<rank_, dim, constness, P - 1, Number>
1212 Accessor<rank_, dim, constness, P, Number>::operator[](
1213 const unsigned int i)
1215 return Accessor<rank_, dim, constness, P - 1, Number>(
1216 tensor, merge(previous_indices, i, rank_ - P));
1221 template <
int rank_,
int dim,
bool constness,
int P,
typename Number>
1223 Accessor<rank_, dim, constness, P - 1, Number>
1224 Accessor<rank_, dim, constness, P, Number>::operator[](
1225 const unsigned int i)
const
1227 return Accessor<rank_, dim, constness, P - 1, Number>(
1228 tensor,
merge(previous_indices, i, rank_ - P));
1233 template <
int rank_,
int dim,
bool constness,
typename Number>
1235 Accessor<rank_, dim, constness, 1, Number>::Accessor(
1236 tensor_type &tensor,
1239 , previous_indices(previous_indices)
1244 template <
int rank_,
int dim,
bool constness,
typename Number>
1246 typename Accessor<rank_, dim, constness, 1, Number>::reference
1247 Accessor<rank_, dim, constness, 1, Number>::operator[](
1248 const unsigned int i)
1250 return tensor(
merge(previous_indices, i, rank_ - 1));
1254 template <
int rank_,
int dim,
bool constness,
typename Number>
1256 typename Accessor<rank_, dim, constness, 1, Number>::reference
1257 Accessor<rank_, dim, constness, 1, Number>::operator[](
1258 const unsigned int i)
const
1260 return tensor(
merge(previous_indices, i, rank_ - 1));
1267template <
int rank_,
int dim,
typename Number>
1268template <
typename OtherNumber>
1273 static_assert(rank == 2,
"This function is only implemented for rank==2");
1274 for (
unsigned int d = 0;
d < dim; ++
d)
1275 for (
unsigned int e = 0;
e <
d; ++
e)
1276 Assert(t[d][e] == t[e][d],
1277 ExcMessage(
"The incoming Tensor must be exactly symmetric."));
1279 for (
unsigned int d = 0;
d < dim; ++
d)
1282 for (
unsigned int d = 0, c = 0;
d < dim; ++
d)
1283 for (
unsigned int e = d + 1;
e < dim; ++
e, ++c)
1284 data[dim + c] = t[d][e];
1289template <
int rank_,
int dim,
typename Number>
1290template <
typename OtherNumber>
1294 : data(initializer.data)
1299template <
int rank_,
int dim,
typename Number>
1302 const Number (&array)[n_independent_components])
1304 *reinterpret_cast<const typename base_tensor_type::array_type *>(array))
1307 Assert(
sizeof(
typename base_tensor_type::array_type) ==
sizeof(array),
1313template <
int rank_,
int dim,
typename Number>
1314template <
typename OtherNumber>
1326template <
int rank_,
int dim,
typename Number>
1332 ExcMessage(
"Only assignment with zero is allowed"));
1343 namespace SymmetricTensorImplementation
1345 template <
int dim,
typename Number>
1346 constexpr inline DEAL_II_ALWAYS_INLINE ::Tensor<2, dim, Number>
1347 convert_to_tensor(const ::SymmetricTensor<2, dim, Number> &s)
1352 for (
unsigned int d = 0;
d < dim; ++
d)
1353 t[d][d] = s.access_raw_entry(d);
1356 for (
unsigned int d = 0, c = 0;
d < dim; ++
d)
1357 for (
unsigned int e = d + 1;
e < dim; ++
e, ++c)
1359 t[
d][
e] = s.access_raw_entry(dim + c);
1360 t[
e][
d] = s.access_raw_entry(dim + c);
1366 template <
int dim,
typename Number>
1367 constexpr ::Tensor<4, dim, Number>
1368 convert_to_tensor(const ::SymmetricTensor<4, dim, Number> &st)
1375 for (
unsigned int i = 0; i < dim; ++i)
1376 for (
unsigned int j = i; j < dim; ++j)
1377 for (
unsigned int k = 0; k < dim; ++k)
1378 for (
unsigned int l = k;
l < dim; ++
l)
1388 template <
typename Number>
1389 struct Inverse<2, 1, Number>
1391 constexpr static inline DEAL_II_ALWAYS_INLINE
1392 ::SymmetricTensor<2, 1, Number>
1393 value(const ::SymmetricTensor<2, 1, Number> &t)
1397 tmp[0][0] = 1.0 / t[0][0];
1404 template <
typename Number>
1405 struct Inverse<2, 2, Number>
1407 constexpr static inline DEAL_II_ALWAYS_INLINE
1408 ::SymmetricTensor<2, 2, Number>
1409 value(const ::SymmetricTensor<2, 2, Number> &t)
1419 const Number inv_det_t =
1420 1.0 / (t[idx_00] * t[idx_11] - t[idx_01] * t[idx_01]);
1421 tmp[idx_00] = t[idx_11];
1422 tmp[idx_01] = -t[idx_01];
1423 tmp[idx_11] = t[idx_00];
1431 template <
typename Number>
1432 struct Inverse<2, 3, Number>
1434 constexpr static ::SymmetricTensor<2, 3, Number>
1435 value(const ::SymmetricTensor<2, 3, Number> &t)
1479 const Number inv_det_t =
1480 1.0 / (t[idx_00] * t[idx_11] * t[idx_22] -
1481 t[idx_00] * t[idx_12] * t[idx_12] -
1482 t[idx_01] * t[idx_01] * t[idx_22] +
1483 2.0 * t[idx_01] * t[idx_02] * t[idx_12] -
1484 t[idx_02] * t[idx_02] * t[idx_11]);
1485 tmp[idx_00] = t[idx_11] * t[idx_22] - t[idx_12] * t[idx_12];
1486 tmp[idx_01] = -t[idx_01] * t[idx_22] + t[idx_02] * t[idx_12];
1487 tmp[idx_02] = t[idx_01] * t[idx_12] - t[idx_02] * t[idx_11];
1488 tmp[idx_11] = t[idx_00] * t[idx_22] - t[idx_02] * t[idx_02];
1489 tmp[idx_12] = -t[idx_00] * t[idx_12] + t[idx_01] * t[idx_02];
1490 tmp[idx_22] = t[idx_00] * t[idx_11] - t[idx_01] * t[idx_01];
1498 template <
typename Number>
1499 struct Inverse<4, 1, Number>
1501 constexpr static inline ::SymmetricTensor<4, 1, Number>
1502 value(const ::SymmetricTensor<4, 1, Number> &t)
1505 tmp.
data[0][0] = 1.0 / t.data[0][0];
1511 template <
typename Number>
1512 struct Inverse<4, 2, Number>
1514 constexpr static inline ::SymmetricTensor<4, 2, Number>
1515 value(const ::SymmetricTensor<4, 2, Number> &t)
1541 const Number t4 = t.
data[0][0] * t.data[1][1],
1542 t6 = t.data[0][0] * t.data[1][2],
1543 t8 = t.data[0][1] * t.data[1][0],
1544 t00 = t.data[0][2] * t.data[1][0],
1545 t01 = t.data[0][1] * t.data[2][0],
1546 t04 = t.data[0][2] * t.data[2][0],
1547 t07 = 1.0 / (t4 * t.data[2][2] - t6 * t.data[2][1] -
1548 t8 * t.data[2][2] + t00 * t.data[2][1] +
1549 t01 * t.data[1][2] - t04 * t.data[1][1]);
1551 (t.data[1][1] * t.data[2][2] - t.data[1][2] * t.data[2][1]) * t07;
1553 -(t.data[0][1] * t.data[2][2] - t.data[0][2] * t.data[2][1]) * t07;
1555 -(-t.data[0][1] * t.data[1][2] + t.data[0][2] * t.data[1][1]) * t07;
1557 -(t.data[1][0] * t.data[2][2] - t.data[1][2] * t.data[2][0]) * t07;
1558 tmp.
data[1][1] = (t.data[0][0] * t.data[2][2] - t04) * t07;
1559 tmp.
data[1][2] = -(t6 - t00) * t07;
1561 -(-t.data[1][0] * t.data[2][1] + t.data[1][1] * t.data[2][0]) * t07;
1562 tmp.
data[2][1] = -(t.data[0][0] * t.data[2][1] - t01) * t07;
1563 tmp.
data[2][2] = (t4 - t8) * t07;
1567 tmp.
data[2][0] /= 2;
1568 tmp.
data[2][1] /= 2;
1569 tmp.
data[0][2] /= 2;
1570 tmp.
data[1][2] /= 2;
1571 tmp.
data[2][2] /= 4;
1578 template <
typename Number>
1579 struct Inverse<4, 3, Number>
1581 static ::SymmetricTensor<4, 3, Number>
1582 value(const ::SymmetricTensor<4, 3, Number> &t)
1592 const unsigned int N = 6;
1598 for (
unsigned int i = 0; i < N; ++i)
1600 const Number typical_diagonal_element =
1601 diagonal_sum /
static_cast<double>(N);
1602 (void)typical_diagonal_element;
1605 for (
unsigned int i = 0; i < N; ++i)
1608 for (
unsigned int j = 0; j < N; ++j)
1614 for (
unsigned int i = j + 1; i < N; ++i)
1622 Assert(max > 1.e-16 * typical_diagonal_element,
1623 ExcMessage(
"This tensor seems to be noninvertible"));
1628 for (
unsigned int k = 0; k < N; ++k)
1629 std::swap(tmp.
data[j][k], tmp.
data[r][k]);
1631 std::swap(p[j], p[r]);
1635 const Number hr = 1. / tmp.
data[j][j];
1636 tmp.
data[j][j] = hr;
1637 for (
unsigned int k = 0; k < N; ++k)
1641 for (
unsigned int i = 0; i < N; ++i)
1645 tmp.
data[i][k] -= tmp.
data[i][j] * tmp.
data[j][k] * hr;
1648 for (
unsigned int i = 0; i < N; ++i)
1650 tmp.
data[i][j] *= hr;
1651 tmp.
data[j][i] *= -hr;
1653 tmp.
data[j][j] = hr;
1658 for (
unsigned int i = 0; i < N; ++i)
1660 for (
unsigned int k = 0; k < N; ++k)
1661 hv[p[k]] = tmp.
data[i][k];
1662 for (
unsigned int k = 0; k < N; ++k)
1663 tmp.
data[i][k] = hv[k];
1668 for (
unsigned int i = 3; i < 6; ++i)
1669 for (
unsigned int j = 0; j < 3; ++j)
1670 tmp.
data[i][j] /= 2;
1672 for (
unsigned int i = 0; i < 3; ++i)
1673 for (
unsigned int j = 3; j < 6; ++j)
1674 tmp.
data[i][j] /= 2;
1676 for (
unsigned int i = 3; i < 6; ++i)
1677 for (
unsigned int j = 3; j < 6; ++j)
1678 tmp.
data[i][j] /= 4;
1689template <
int rank_,
int dim,
typename Number>
1694 return internal::SymmetricTensorImplementation::convert_to_tensor(*
this);
1699template <
int rank_,
int dim,
typename Number>
1704 return data == t.
data;
1709template <
int rank_,
int dim,
typename Number>
1714 return data != t.
data;
1719template <
int rank_,
int dim,
typename Number>
1720template <
typename OtherNumber>
1732template <
int rank_,
int dim,
typename Number>
1733template <
typename OtherNumber>
1745template <
int rank_,
int dim,
typename Number>
1746template <
typename OtherNumber>
1757template <
int rank_,
int dim,
typename Number>
1758template <
typename OtherNumber>
1769template <
int rank_,
int dim,
typename Number>
1781template <
int rank_,
int dim,
typename Number>
1790template <
int rank_,
int dim,
typename Number>
1806 template <
int dim,
typename Number,
typename OtherNumber = Number>
1808 typename SymmetricTensorAccessors::
1809 double_contraction_result<2, 2, dim, Number, OtherNumber>::type
1810 perform_double_contraction(
1811 const typename SymmetricTensorAccessors::StorageType<2, dim, Number>::
1812 base_tensor_type &data,
1813 const typename SymmetricTensorAccessors::
1814 StorageType<2, dim, OtherNumber>::base_tensor_type &sdata)
1816 using result_type =
typename SymmetricTensorAccessors::
1817 double_contraction_result<2, 2, dim, Number, OtherNumber>::type;
1822 return data[0] * sdata[0];
1830 result_type
sum = data[dim] * sdata[dim];
1831 for (
unsigned int d = dim + 1;
d < (dim * (dim + 1) / 2); ++
d)
1832 sum += data[d] * sdata[d];
1836 for (
unsigned int d = 0;
d < dim; ++
d)
1837 sum += data[d] * sdata[d];
1848 template <
int dim,
typename Number,
typename OtherNumber = Number>
1850 typename SymmetricTensorAccessors::
1851 double_contraction_result<4, 2, dim, Number, OtherNumber>::type
1852 perform_double_contraction(
1853 const typename SymmetricTensorAccessors::StorageType<4, dim, Number>::
1854 base_tensor_type &data,
1855 const typename SymmetricTensorAccessors::
1856 StorageType<2, dim, OtherNumber>::base_tensor_type &sdata)
1858 using result_type =
typename SymmetricTensorAccessors::
1859 double_contraction_result<4, 2, dim, Number, OtherNumber>::type;
1860 using value_type =
typename SymmetricTensorAccessors::
1861 double_contraction_result<4, 2, dim, Number, OtherNumber>::value_type;
1863 const unsigned int data_dim = SymmetricTensorAccessors::
1864 StorageType<2, dim, value_type>::n_independent_components;
1865 value_type tmp[data_dim]{};
1866 for (
unsigned int i = 0; i < data_dim; ++i)
1868 perform_double_contraction<dim, Number, OtherNumber>(data[i], sdata);
1869 return result_type(tmp);
1878 template <
int dim,
typename Number,
typename OtherNumber = Number>
1880 typename SymmetricTensorAccessors::StorageType<
1883 typename SymmetricTensorAccessors::
1884 double_contraction_result<2, 4, dim, Number, OtherNumber>::value_type>::
1886 perform_double_contraction(
1887 const typename SymmetricTensorAccessors::StorageType<2, dim, Number>::
1888 base_tensor_type &data,
1889 const typename SymmetricTensorAccessors::
1890 StorageType<4, dim, OtherNumber>::base_tensor_type &sdata)
1892 using value_type =
typename SymmetricTensorAccessors::
1893 double_contraction_result<2, 4, dim, Number, OtherNumber>::value_type;
1894 using base_tensor_type =
typename SymmetricTensorAccessors::
1895 StorageType<2, dim, value_type>::base_tensor_type;
1897 base_tensor_type tmp;
1898 for (
unsigned int i = 0; i < tmp.dimension; ++i)
1905 value_type
sum = data[dim] * sdata[dim][i];
1906 for (
unsigned int d = dim + 1;
d < (dim * (dim + 1) / 2); ++
d)
1907 sum += data[d] * sdata[d][i];
1911 for (
unsigned int d = 0;
d < dim; ++
d)
1912 sum += data[d] * sdata[d][i];
1923 template <
int dim,
typename Number,
typename OtherNumber = Number>
1925 typename SymmetricTensorAccessors::StorageType<
1928 typename SymmetricTensorAccessors::
1929 double_contraction_result<4, 4, dim, Number, OtherNumber>::value_type>::
1931 perform_double_contraction(
1932 const typename SymmetricTensorAccessors::StorageType<4, dim, Number>::
1933 base_tensor_type &data,
1934 const typename SymmetricTensorAccessors::
1935 StorageType<4, dim, OtherNumber>::base_tensor_type &sdata)
1937 using value_type =
typename SymmetricTensorAccessors::
1938 double_contraction_result<4, 4, dim, Number, OtherNumber>::value_type;
1939 using base_tensor_type =
typename SymmetricTensorAccessors::
1940 StorageType<4, dim, value_type>::base_tensor_type;
1942 const unsigned int data_dim = SymmetricTensorAccessors::
1943 StorageType<2, dim, value_type>::n_independent_components;
1944 base_tensor_type tmp;
1945 for (
unsigned int i = 0; i < data_dim; ++i)
1946 for (
unsigned int j = 0; j < data_dim; ++j)
1949 for (
unsigned int d = dim;
d < (dim * (dim + 1) / 2); ++
d)
1950 tmp[i][j] += data[i][d] * sdata[d][j];
1951 tmp[i][j] += tmp[i][j];
1954 for (
unsigned int d = 0;
d < dim; ++
d)
1955 tmp[i][j] += data[i][d] * sdata[d][j];
1964template <
int rank_,
int dim,
typename Number>
1965template <
typename OtherNumber>
1967 typename internal::SymmetricTensorAccessors::
1968 double_contraction_result<rank_, 2, dim, Number, OtherNumber>::type
1974 return internal::perform_double_contraction<dim, Number, OtherNumber>(data,
1980template <
int rank_,
int dim,
typename Number>
1981template <
typename OtherNumber>
1983 typename internal::SymmetricTensorAccessors::
1984 double_contraction_result<rank_, 4, dim, Number, OtherNumber>::type
1988 typename internal::SymmetricTensorAccessors::
1989 double_contraction_result<rank_, 4, dim, Number, OtherNumber>::type tmp;
1991 internal::perform_double_contraction<dim, Number, OtherNumber>(data,
2008 namespace SymmetricTensorImplementation
2030 constexpr ::ndarray<unsigned int, 2, 2> table = {
2031 {{{0, 2}}, {{2, 1}}}};
2032 return table[indices[0]][indices[1]];
2036 constexpr ::ndarray<unsigned int, 3, 3> table = {
2037 {{{0, 3, 4}}, {{3, 1, 5}}, {{4, 5, 2}}}};
2038 return table[indices[0]][indices[1]];
2042 constexpr ::ndarray<unsigned int, 4, 4> table = {
2047 return table[indices[0]][indices[1]];
2052 if (indices[0] == indices[1])
2063 for (
unsigned int d = 0;
d < dim; ++
d)
2064 for (
unsigned int e = d + 1;
e < dim; ++
e, ++c)
2065 if ((sorted_indices[0] == d) && (sorted_indices[1] == e))
2081 template <
int dim,
int rank_>
2082 constexpr inline unsigned int
2091 template <
int dim,
typename Number>
2094 typename SymmetricTensorAccessors::
2095 StorageType<2, dim, Number>::base_tensor_type &data)
2103 template <
int dim,
typename Number>
2106 const typename SymmetricTensorAccessors::
2107 StorageType<2, dim, Number>::base_tensor_type &data)
2115 template <
int dim,
typename Number>
2116 constexpr inline Number &
2118 typename SymmetricTensorAccessors::
2119 StorageType<4, dim, Number>::base_tensor_type &data)
2133 constexpr std::size_t base_index[2][2] = {{0, 2}, {2, 1}};
2134 return data[base_index[indices[0]][indices[1]]]
2135 [base_index[indices[2]][indices[3]]];
2144 constexpr std::size_t base_index[3][3] = {{0, 3, 4},
2147 return data[base_index[indices[0]][indices[1]]]
2148 [base_index[indices[2]][indices[3]]];
2163 template <
int dim,
typename Number>
2166 const typename SymmetricTensorAccessors::
2167 StorageType<4, dim, Number>::base_tensor_type &data)
2181 constexpr std::size_t base_index[2][2] = {{0, 2}, {2, 1}};
2182 return data[base_index[indices[0]][indices[1]]]
2183 [base_index[indices[2]][indices[3]]];
2192 constexpr std::size_t base_index[3][3] = {{0, 3, 4},
2195 return data[base_index[indices[0]][indices[1]]]
2196 [base_index[indices[2]][indices[3]]];
2214template <
int rank_,
int dim,
typename Number>
2219 for (
unsigned int r = 0; r < rank; ++r)
2221 return internal::symmetric_tensor_access<dim, Number>(indices, data);
2226template <
int rank_,
int dim,
typename Number>
2231 for (
unsigned int r = 0; r < rank; ++r)
2233 return internal::symmetric_tensor_access<dim, Number>(indices, data);
2240 namespace SymmetricTensorImplementation
2242 template <
int rank_>
2244 get_partially_filled_indices(
const unsigned int row,
2245 const std::integral_constant<int, 2> &)
2251 template <
int rank_>
2253 get_partially_filled_indices(
const unsigned int row,
2254 const std::integral_constant<int, 4> &)
2265template <
int rank_,
int dim,
typename Number>
2267 SymmetricTensorAccessors::Accessor<rank_, dim,
true, rank_ - 1, Number>
2270 return internal::SymmetricTensorAccessors::
2271 Accessor<rank_, dim,
true, rank_ - 1, Number>(
2273 internal::SymmetricTensorImplementation::get_partially_filled_indices<
2274 rank_>(row, std::integral_constant<int, rank_>()));
2279template <
int rank_,
int dim,
typename Number>
2281 SymmetricTensorAccessors::Accessor<rank_, dim,
false, rank_ - 1, Number>
2284 return internal::SymmetricTensorAccessors::
2285 Accessor<rank_, dim,
false, rank_ - 1, Number>(
2287 internal::SymmetricTensorImplementation::get_partially_filled_indices<
2288 rank_>(row, std::integral_constant<int, rank_>()));
2293template <
int rank_,
int dim,
typename Number>
2298 return operator()(indices);
2303template <
int rank_,
int dim,
typename Number>
2308 return operator()(indices);
2313template <
int rank_,
int dim,
typename Number>
2317 return std::addressof(this->access_raw_entry(0));
2322template <
int rank_,
int dim,
typename Number>
2323inline const Number *
2326 return std::addressof(this->access_raw_entry(0));
2331template <
int rank_,
int dim,
typename Number>
2335 return begin_raw() + n_independent_components;
2340template <
int rank_,
int dim,
typename Number>
2341inline const Number *
2344 return begin_raw() + n_independent_components;
2349template <
int rank_,
int dim,
typename Number>
2352 const unsigned int index)
const
2355 if constexpr (rank == 2)
2358 return data[
decltype(data)::unrolled_to_component_indices(index)];
2363template <
int rank_,
int dim,
typename Number>
2368 if constexpr (rank == 2)
2371 return data[
decltype(data)::unrolled_to_component_indices(index)];
2378 template <
int dim,
typename Number>
2380 compute_norm(
const typename SymmetricTensorAccessors::
2381 StorageType<2, dim, Number>::base_tensor_type &data)
2408 for (
unsigned int d = 0;
d < dim; ++
d)
2411 for (
unsigned int d = dim;
d < (dim * dim + dim) / 2; ++
d)
2415 return sqrt(return_value);
2422 template <
int dim,
typename Number>
2424 compute_norm(
const typename SymmetricTensorAccessors::
2425 StorageType<4, dim, Number>::base_tensor_type &data)
2439 const unsigned int n_independent_components = data.dimension;
2441 for (
unsigned int i = 0; i < dim; ++i)
2442 for (
unsigned int j = 0; j < dim; ++j)
2445 for (
unsigned int i = 0; i < dim; ++i)
2446 for (
unsigned int j = dim; j < n_independent_components; ++j)
2449 for (
unsigned int i = dim; i < n_independent_components; ++i)
2450 for (
unsigned int j = 0; j < dim; ++j)
2453 for (
unsigned int i = dim; i < n_independent_components; ++i)
2454 for (
unsigned int j = dim; j < n_independent_components; ++j)
2458 return sqrt(return_value);
2467template <
int rank_,
int dim,
typename Number>
2471 return internal::compute_norm<dim, Number>(data);
2476template <
int rank_,
int dim,
typename Number>
2481 return internal::SymmetricTensorImplementation::component_to_unrolled_index<
2489 namespace SymmetricTensorImplementation
2501 const std::integral_constant<int, 2> &)
2539 for (
unsigned int d = 0, c = dim;
d < dim; ++
d)
2540 for (
unsigned int e = d + 1;
e < dim; ++
e, ++c)
2558 template <
int dim,
int rank_>
2559 constexpr inline std::enable_if_t<rank_ != 2, TableIndices<rank_>>
2561 const std::integral_constant<int, rank_> &)
2570 n_independent_components));
2578template <
int rank_,
int dim,
typename Number>
2581 const unsigned int i)
2583 return internal::SymmetricTensorImplementation::unrolled_to_component_indices<
2584 dim>(i, std::integral_constant<int, rank_>());
2589template <
int rank_,
int dim,
typename Number>
2590template <
class Archive>
2615template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2640template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2660template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2677template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2694template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2711template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2722template <
int dim,
typename Number>
2738 return (tmp + tmp + t.
data[0] * t.
data[1] * t.
data[2] -
2762template <
int dim,
typename Number>
2771template <
int dim,
typename Number>
2775 Number t = d.data[0];
2776 for (
unsigned int i = 1; i < dim; ++i)
2793template <
int dim,
typename Number>
2812template <
typename Number>
2839template <
typename Number>
2843 return t[0][0] * t[1][1] - t[0][1] * t[0][1];
2856template <
typename Number>
2860 return (t[0][0] * t[1][1] + t[1][1] * t[2][2] + t[2][2] * t[0][0] -
2861 t[0][1] * t[0][1] - t[0][2] * t[0][2] - t[1][2] * t[1][2]);
2873template <
typename Number>
2874std::array<Number, 1>
2901template <
typename Number>
2902std::array<Number, 2>
2929template <
typename Number>
2930std::array<Number, 3>
2937 namespace SymmetricTensorImplementation
2950 template <
int dim,
typename Number>
2954 std::array<Number, dim> &d,
2955 std::array<Number, dim - 1> &e);
2972 template <
int dim,
typename Number>
2973 std::array<std::pair<Number, Tensor<1, dim, Number>>, dim>
2991 template <
int dim,
typename Number>
2992 std::array<std::pair<Number, Tensor<1, dim, Number>>, dim>
3010 template <
typename Number>
3011 std::array<std::pair<Number, Tensor<1, 2, Number>>, 2>
3012 hybrid(const ::SymmetricTensor<2, 2, Number> &A);
3030 template <
typename Number>
3031 std::array<std::pair<Number, Tensor<1, 3, Number>>, 3>
3032 hybrid(const ::SymmetricTensor<2, 3, Number> &A);
3038 template <
int dim,
typename Number>
3045 return lhs.first > rhs.first;
3112template <
int dim,
typename Number>
3113std::array<std::pair<Number, Tensor<1, dim, Number>>,
3114 std::integral_constant<int, dim>::value>
3129template <
int rank_,
int dim,
typename Number>
3138template <
int dim,
typename Number>
3147 for (
unsigned int i = 0; i < dim; ++i)
3155template <
int dim,
typename Number>
3176 for (
unsigned int d = 0; d < dim; ++d)
3184template <
int dim,
typename Number>
3191 for (
unsigned int i = 0; i < dim; ++i)
3192 for (
unsigned int j = 0; j < dim; ++j)
3201 for (
unsigned int i = dim;
3202 i < internal::SymmetricTensorAccessors::StorageType<4, dim, Number>::
3212template <
int dim,
typename Number>
3220 for (
unsigned int i = 0; i < dim; ++i)
3228 for (
unsigned int i = dim;
3229 i < internal::SymmetricTensorAccessors::StorageType<4, dim, Number>::
3248template <
int dim,
typename Number>
3268template <
int dim,
typename Number>
3299template <
int dim,
typename Number>
3307 for (
unsigned int i = 0; i < dim; ++i)
3308 for (
unsigned int j = i; j < dim; ++j)
3309 for (
unsigned int k = 0; k < dim; ++k)
3310 for (
unsigned int l = k; l < dim; ++l)
3311 tmp[i][j][k][l] = t1[i][j] * t2[k][l];
3341template <
int dim,
typename Number>
3347 const std::array<std::pair<Number, Tensor<1, dim, Number>>, dim>
3351 positive_negative_tensors;
3353 auto &[positive_part_tensor, negative_part_tensor] =
3354 positive_negative_tensors;
3356 positive_part_tensor = 0;
3357 for (
unsigned int i = 0; i < dim; ++i)
3358 if (eigen_system[i].
first > 0)
3359 positive_part_tensor += eigen_system[i].first *
3361 eigen_system[i].
second));
3363 negative_part_tensor = 0;
3364 for (
unsigned int i = 0; i < dim; ++i)
3365 if (eigen_system[i].
first < 0)
3366 negative_part_tensor += eigen_system[i].first *
3368 eigen_system[i].
second));
3370 return positive_negative_tensors;
3405template <
int dim,
typename Number>
3406std::tuple<SymmetricTensor<2, dim, Number>,
3415 auto heaviside_function{[](
const double x) {
3416 if (std::fabs(x) < 1.0e-16)
3424 std::tuple<SymmetricTensor<2, dim, Number>,
3428 positive_negative_tensors_projectors;
3430 auto &[positive_part_tensor,
3431 negative_part_tensor,
3433 negative_projector] = positive_negative_tensors_projectors;
3435 const std::array<std::pair<Number, Tensor<1, dim, Number>>, dim>
3438 positive_part_tensor = 0;
3439 for (
unsigned int i = 0; i < dim; ++i)
3440 if (eigen_system[i].
first > 0)
3441 positive_part_tensor += eigen_system[i].first *
3443 eigen_system[i].
second));
3445 negative_part_tensor = 0;
3446 for (
unsigned int i = 0; i < dim; ++i)
3447 if (eigen_system[i].
first < 0)
3448 negative_part_tensor += eigen_system[i].first *
3450 eigen_system[i].
second));
3452 std::array<SymmetricTensor<2, dim, Number>, dim> M;
3453 for (
unsigned int a = 0; a < dim; ++a)
3457 std::array<SymmetricTensor<4, dim, Number>, dim> Q;
3458 for (
unsigned int a = 0; a < dim; ++a)
3461 std::array<std::array<SymmetricTensor<4, dim, Number>, dim>, dim> G;
3462 for (
unsigned int a = 0; a < dim; ++a)
3463 for (
unsigned int b = 0; b < dim; ++b)
3464 for (
unsigned int i = 0; i < dim; ++i)
3465 for (
unsigned int j = 0; j < dim; ++j)
3466 for (
unsigned int k = 0; k < dim; ++k)
3467 for (
unsigned int l = 0; l < dim; ++l)
3468 G[a][b][i][j][k][l] =
3469 M[a][i][k] * M[b][j][l] + M[a][i][l] * M[b][j][k];
3472 positive_projector = 0;
3473 for (
unsigned int a = 0; a < dim; ++a)
3475 double lambda_a = eigen_system[a].first;
3476 positive_projector += heaviside_function(lambda_a) * Q[a];
3477 for (
unsigned int b = 0; b < dim; ++b)
3481 double lambda_b = eigen_system[b].first;
3484 if (std::fabs(lambda_a - lambda_b) > 1.0e-12)
3485 v_ab = (std::fmax(lambda_a, 0.0) - std::fmax(lambda_b, 0.0)) /
3486 (lambda_a - lambda_b);
3488 v_ab = 0.5 * (heaviside_function(lambda_a) +
3489 heaviside_function(lambda_b));
3491 positive_projector += 0.5 * v_ab * 0.5 * (G[a][b] + G[b][a]);
3497 negative_projector = 0;
3498 for (
unsigned int a = 0; a < dim; ++a)
3500 double lambda_a = eigen_system[a].first;
3501 negative_projector += heaviside_function(-lambda_a) * Q[a];
3502 for (
unsigned int b = 0; b < dim; ++b)
3506 double lambda_b = eigen_system[b].first;
3509 if (std::fabs(lambda_a - lambda_b) > 1.0e-12)
3510 v_ab = (std::fmin(lambda_a, 0.0) - std::fmin(lambda_b, 0.0)) /
3511 (lambda_a - lambda_b);
3513 v_ab = 0.5 * (heaviside_function(-lambda_a) +
3514 heaviside_function(-lambda_b));
3516 negative_projector += 0.5 * v_ab * 0.5 * (G[a][b] + G[b][a]);
3521 return positive_negative_tensors_projectors;
3531template <
int dim,
typename Number>
3537 for (
unsigned int d = 0; d < dim; ++d)
3538 result[d][d] = t[d][d];
3541 for (
unsigned int d = 0; d < dim; ++d)
3542 for (
unsigned int e = d + 1; e < dim; ++e)
3543 result[d][e] = (t[d][e] + t[e][d]) * half;
3556template <
int rank_,
int dim,
typename Number>
3575template <
int rank_,
int dim,
typename Number>
3609template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
3616 const OtherNumber &factor)
3638template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
3648 return (t * factor);
3658template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
3665 const OtherNumber &factor)
3681template <
int rank_,
int dim>
3698template <
int rank_,
int dim>
3714template <
int rank_,
int dim>
3732template <
int dim,
typename Number,
typename OtherNumber>
3754template <
int dim,
typename Number,
typename OtherNumber>
3762 for (
unsigned int i = 0; i < dim; ++i)
3763 for (
unsigned int j = 0; j < dim; ++j)
3764 s += t1[i][j] * t2[i][j];
3781template <
int dim,
typename Number,
typename OtherNumber>
3787 return scalar_product(t2, t1);
3805template <
typename Number,
typename OtherNumber>
3812 tmp[0][0] = t[0][0][0][0] * s[0][0];
3831template <
typename Number,
typename OtherNumber>
3838 tmp[0][0] = t[0][0][0][0] * s[0][0];
3857template <
typename Number,
typename OtherNumber>
3864 const unsigned int dim = 2;
3866 for (
unsigned int i = 0; i < dim; ++i)
3867 for (
unsigned int j = i; j < dim; ++j)
3868 tmp[i][j] = t[i][j][0][0] * s[0][0] + t[i][j][1][1] * s[1][1] +
3869 2 * t[i][j][0][1] * s[0][1];
3888template <
typename Number,
typename OtherNumber>
3895 const unsigned int dim = 2;
3897 for (
unsigned int i = 0; i < dim; ++i)
3898 for (
unsigned int j = i; j < dim; ++j)
3899 tmp[i][j] = s[0][0] * t[0][0][i][j] * +s[1][1] * t[1][1][i][j] +
3900 2 * s[0][1] * t[0][1][i][j];
3919template <
typename Number,
typename OtherNumber>
3926 const unsigned int dim = 3;
3928 for (
unsigned int i = 0; i < dim; ++i)
3929 for (
unsigned int j = i; j < dim; ++j)
3930 tmp[i][j] = t[i][j][0][0] * s[0][0] + t[i][j][1][1] * s[1][1] +
3931 t[i][j][2][2] * s[2][2] + 2 * t[i][j][0][1] * s[0][1] +
3932 2 * t[i][j][0][2] * s[0][2] + 2 * t[i][j][1][2] * s[1][2];
3951template <
typename Number,
typename OtherNumber>
3958 const unsigned int dim = 3;
3960 for (
unsigned int i = 0; i < dim; ++i)
3961 for (
unsigned int j = i; j < dim; ++j)
3962 tmp[i][j] = s[0][0] * t[0][0][i][j] + s[1][1] * t[1][1][i][j] +
3963 s[2][2] * t[2][2][i][j] + 2 * s[0][1] * t[0][1][i][j] +
3964 2 * s[0][2] * t[0][2][i][j] + 2 * s[1][2] * t[1][2][i][j];
3975template <
int dim,
typename Number,
typename OtherNumber>
3983 for (
unsigned int i = 0; i < dim; ++i)
3985 dest[i] = src1[i][0] * src2[0];
3986 for (
unsigned int j = 1; j < dim; ++j)
3987 dest[i] += src1[i][j] * src2[j];
3999template <
int dim,
typename Number,
typename OtherNumber>
4031template <
int rank_1,
4035 typename OtherNumber>
4037 typename Tensor<rank_1 + rank_2 - 2,
4067template <
int rank_1,
4071 typename OtherNumber>
4073 typename Tensor<rank_1 + rank_2 - 2,
4093template <
int dim,
typename Number>
4094inline std::ostream &
4102 for (
unsigned int i = 0; i < dim; ++i)
4103 for (
unsigned int j = 0; j < dim; ++j)
4120template <
int dim,
typename Number>
4121inline std::ostream &
4129 for (
unsigned int i = 0; i < dim; ++i)
4130 for (
unsigned int j = 0; j < dim; ++j)
4131 for (
unsigned int k = 0; k < dim; ++k)
4132 for (
unsigned int l = 0; l < dim; ++l)
4133 tt[i][j][k][l] = t[i][j][k][l];
DEAL_II_HOST constexpr SymmetricTensor< rank_, dim, Number > operator*(const SymmetricTensor< rank_, dim, Number > &t, const Number &factor)
DEAL_II_HOST constexpr Number determinant(const SymmetricTensor< 2, dim, Number > &)
DEAL_II_HOST constexpr SymmetricTensor< rank_, dim, Number > transpose(const SymmetricTensor< rank_, dim, Number > &t)
DEAL_II_HOST constexpr internal::SymmetricTensorAccessors::Accessor< rank_, dim, false, rank_ - 1, Number > operator[](const unsigned int row)
std::pair< SymmetricTensor< 2, dim, Number >, SymmetricTensor< 2, dim, Number > > positive_negative_split(const SymmetricTensor< 2, dim, Number > &original_tensor)
DEAL_II_HOST constexpr SymmetricTensor< rank_, dim, typename ProductType< Number, typename EnableIfScalar< OtherNumber >::type >::type > operator/(const SymmetricTensor< rank_, dim, Number > &t, const OtherNumber &factor)
DEAL_II_HOST constexpr SymmetricTensor< 2, dim, Number > symmetrize(const Tensor< 2, dim, Number > &t)
DEAL_II_HOST constexpr void double_contract(SymmetricTensor< 2, 2, typename ProductType< Number, OtherNumber >::type > &tmp, const SymmetricTensor< 4, 2, Number > &t, const SymmetricTensor< 2, 2, OtherNumber > &s)
static DEAL_II_HOST constexpr std::size_t memory_consumption()
DEAL_II_HOST constexpr SymmetricTensor & operator/=(const OtherNumber &factor)
DEAL_II_HOST constexpr Tensor< rank_1+rank_2-2, dim, typenameProductType< Number, OtherNumber >::type >::tensor_type operator*(const Tensor< rank_1, dim, Number > &src1, const SymmetricTensor< rank_2, dim, OtherNumber > &src2)
DEAL_II_HOST constexpr Number third_invariant(const SymmetricTensor< 2, dim, Number > &t)
DEAL_II_HOST constexpr Tensor< 1, dim, typename ProductType< Number, OtherNumber >::type > operator*(const SymmetricTensor< 2, dim, Number > &src1, const Tensor< 1, dim, OtherNumber > &src2)
DEAL_II_HOST constexpr SymmetricTensor< rank_, dim, typename ProductType< OtherNumber, typename EnableIfScalar< Number >::type >::type > operator*(const Number &factor, const SymmetricTensor< rank_, dim, OtherNumber > &t)
DEAL_II_HOST constexpr Number & operator[](const TableIndices< rank_ > &indices)
std::array< Number, 2 > eigenvalues(const SymmetricTensor< 2, 2, Number > &T)
DEAL_II_HOST constexpr SymmetricTensor< rank_, dim, typename ProductType< Number, OtherNumber >::type > operator-(const SymmetricTensor< rank_, dim, Number > &left, const SymmetricTensor< rank_, dim, OtherNumber > &right)
void serialize(Archive &ar, const unsigned int version)
const Number * begin_raw() const
const Number * end_raw() const
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
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)
std::array< std::pair< Number, Tensor< 1, dim, Number > >, std::integral_constant< int, dim >::value > eigenvectors(const SymmetricTensor< 2, dim, Number > &T, const SymmetricTensorEigenvectorMethod method=SymmetricTensorEigenvectorMethod::ql_implicit_shifts)
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< 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 >::tensor_type tensor_type
typename AccessorTypes< rank, dim, constness, Number >::reference reference
const TableIndices< rank > previous_indices
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_DEPRECATED
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_CONSTEXPR
#define DEAL_II_NAMESPACE_CLOSE
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcIndexRange(std::size_t arg1, std::size_t arg2, std::size_t arg3)
static ::ExceptionBase & ExcMessage(std::string arg1)
#define DEAL_II_ASSERT_UNREACHABLE()
#define DEAL_II_NOT_IMPLEMENTED()
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
Tensor< 2, dim, Number > l(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
T sum(const T &t, const MPI_Comm mpi_communicator)
DEAL_II_HOST constexpr TableIndices< 2 > merge(const TableIndices< 2 > &previous_indices, const unsigned int new_index, const unsigned int position)
void tridiagonalize(const ::SymmetricTensor< 2, dim, Number > &A, ::Tensor< 2, dim, Number > &Q, std::array< Number, dim > &d, std::array< Number, dim - 1 > &e)
constexpr bool value_is_zero(const Number &value)
static const unsigned int invalid_unsigned_int
::VectorizedArray< Number, width > min(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > max(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > sqrt(const ::VectorizedArray< Number, width > &)
typename internal::ProductTypeImpl< std::decay_t< T >, std::decay_t< U > >::type type
static constexpr DEAL_II_HOST_DEVICE_ALWAYS_INLINE const T & value(const T &t)
typename ProductType< Number, OtherNumber >::type type
typename ProductType< Number, OtherNumber >::type value_type
std::pair< Number, Tensor< 1, dim, Number > > EigValsVecs
bool operator()(const EigValsVecs &lhs, const EigValsVecs &rhs)
static real_type abs(const number &x)
DEAL_II_HOST constexpr Number determinant(const SymmetricTensor< 2, dim, Number > &)
DEAL_II_HOST constexpr SymmetricTensor< 2, dim, Number > symmetrize(const Tensor< 2, dim, Number > &t)
DEAL_II_HOST constexpr SymmetricTensor< 2, dim, Number > invert(const SymmetricTensor< 2, dim, Number > &)
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()
std::array< std::pair< Number, Tensor< 1, dim, Number > >, std::integral_constant< int, dim >::value > eigenvectors(const SymmetricTensor< 2, dim, Number > &T, const SymmetricTensorEigenvectorMethod method=SymmetricTensorEigenvectorMethod::ql_implicit_shifts)
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()