16#ifndef dealii_symmetric_tensor_h
17#define dealii_symmetric_tensor_h
33template <
int rank,
int dim,
typename Number =
double>
43template <
int dim,
typename Number =
double>
75template <
int dim,
typename Number =
double>
116template <
int dim,
typename Number =
double>
120template <
int dim,
typename Number>
124template <
int dim,
typename Number>
137template <
int dim2,
typename Number>
151template <
int dim,
typename Number>
168template <
int dim,
typename Number>
180 template <
int rank,
int dim,
typename T,
typename U>
186 std::complex<typename ProductType<T, U>::type>>;
189 template <
int rank,
int dim,
typename T,
typename U>
196 std::complex<typename ProductType<T, U>::type>>;
199 template <
typename T,
int rank,
int dim,
typename U>
205 std::complex<typename ProductType<T, U>::type>>;
208 template <
int rank,
int dim,
typename T,
typename U>
215 std::complex<typename ProductType<T, U>::type>>;
223 namespace SymmetricTensorImplementation
229 template <
int rank,
int dim,
typename Number>
237 namespace SymmetricTensorAccessors
247 const unsigned int new_index,
248 const unsigned int position)
255 return {previous_indices[0], new_index};
268 const unsigned int new_index,
269 const unsigned int position)
281 return {previous_indices[0],
286 return {previous_indices[0],
291 return {previous_indices[0],
312 typename OtherNumber = Number>
327 template <
int dim,
typename Number,
typename OtherNumber>
347 template <
int rank,
int dim,
typename Number>
353 template <
int dim,
typename Number>
360 static const unsigned int n_independent_components =
361 (dim * dim + dim) / 2;
374 template <
int dim,
typename Number>
382 static const unsigned int n_rank2_components = (dim * dim + dim) / 2;
387 static const unsigned int n_independent_components =
388 (n_rank2_components *
406 template <
int rank,
int dim,
bool constness,
typename Number>
415 template <
int rank,
int dim,
typename Number>
429 template <
int rank,
int dim,
typename Number>
470 template <
int rank,
int dim,
bool constness,
int P,
typename Number>
514 constexpr Accessor<rank, dim, constness, P - 1, Number>
520 constexpr Accessor<rank, dim, constness, P - 1, Number>
532 template <
int,
int,
typename>
533 friend class ::SymmetricTensor;
534 template <
int,
int,
bool,
int,
typename>
536 friend class ::SymmetricTensor<rank, dim, Number>;
537 friend class Accessor<rank, dim, constness, P + 1, Number>;
549 template <
int rank,
int dim,
bool constness,
typename Number>
614 template <
int,
int,
typename>
615 friend class ::SymmetricTensor;
616 template <
int,
int,
bool,
int,
typename>
618 friend class ::SymmetricTensor<rank, dim, Number>;
619 friend class SymmetricTensorAccessors::
620 Accessor<rank, dim, constness, 2, Number>;
699template <int rank_, int dim, typename Number>
703 static_assert(rank_ % 2 == 0,
"A SymmetricTensor must have even rank!");
713 static constexpr unsigned int dimension = dim;
718 static const unsigned int rank = rank_;
725 static constexpr unsigned int n_independent_components =
727 n_independent_components;
748 template <
typename OtherNumber>
773 template <
typename OtherNumber>
785 DEAL_II_DEPRECATED_EARLY
797 DEAL_II_DEPRECATED_EARLY
809 DEAL_II_DEPRECATED_EARLY
822 DEAL_II_DEPRECATED_EARLY
832 template <
typename OtherNumber>
866 template <
typename OtherNumber>
873 template <
typename OtherNumber>
881 template <
typename OtherNumber>
888 template <
typename OtherNumber>
950 template <
typename OtherNumber>
952 double_contraction_result<rank_, 2, dim, Number, OtherNumber>::type
959 template <
typename OtherNumber>
961 double_contraction_result<rank_, 4, dim, Number, OtherNumber>::type
973 constexpr const Number &
980 constexpr internal::SymmetricTensorAccessors::
981 Accessor<rank_, dim,
true, rank_ - 1, Number>
988 constexpr internal::SymmetricTensorAccessors::
989 Accessor<rank_, dim,
false, rank_ - 1, Number>
997 constexpr const Number &
1014 constexpr const Number &
1045 static constexpr unsigned int
1075 static constexpr std::size_t
1083 template <
class Archive>
1107 template <
int,
int,
typename>
1111 template <
int dim2,
typename Number2>
1112 friend constexpr Number2
1115 template <
int dim2,
typename Number2>
1119 template <
int dim2,
typename Number2>
1123 template <
int dim2,
typename Number2>
1127 template <
int dim2,
typename Number2>
1131 template <
int dim2,
typename Number2>
1138 Inverse<2, dim, Number>;
1141 Inverse<4, dim, Number>;
1152template <int rank, int dim, typename Number>
1155template <int rank_, int dim, typename Number>
1156constexpr unsigned
int
1161 namespace SymmetricTensorAccessors
1163 template <
int rank_,
int dim,
bool constness,
int P,
typename Number>
1165 Accessor<rank_, dim, constness, P, Number>::Accessor(
1166 tensor_type & tensor,
1169 , previous_indices(previous_indices)
1174 template <
int rank_,
int dim,
bool constness,
int P,
typename Number>
1176 Accessor<rank_, dim, constness, P - 1, Number>
1177 Accessor<rank_, dim, constness, P, Number>::operator[](
1178 const unsigned int i)
1180 return Accessor<rank_, dim, constness, P - 1, Number>(
1181 tensor, merge(previous_indices, i, rank_ - P));
1186 template <
int rank_,
int dim,
bool constness,
int P,
typename Number>
1188 Accessor<rank_, dim, constness, P - 1, Number>
1189 Accessor<rank_, dim, constness, P, Number>::operator[](
1190 const unsigned int i)
const
1192 return Accessor<rank_, dim, constness, P - 1, Number>(
1193 tensor,
merge(previous_indices, i, rank_ - P));
1198 template <
int rank_,
int dim,
bool constness,
typename Number>
1200 Accessor<rank_, dim, constness, 1, Number>::Accessor(
1201 tensor_type & tensor,
1204 , previous_indices(previous_indices)
1209 template <
int rank_,
int dim,
bool constness,
typename Number>
1211 typename Accessor<rank_, dim, constness, 1, Number>::reference
1212 Accessor<rank_, dim, constness, 1, Number>::operator[](
1213 const unsigned int i)
1215 return tensor(
merge(previous_indices, i, rank_ - 1));
1219 template <
int rank_,
int dim,
bool constness,
typename Number>
1221 typename Accessor<rank_, dim, constness, 1, Number>::reference
1222 Accessor<rank_, dim, constness, 1, Number>::operator[](
1223 const unsigned int i)
const
1225 return tensor(
merge(previous_indices, i, rank_ - 1));
1232template <
int rank_,
int dim,
typename Number>
1233template <
typename OtherNumber>
1238 static_assert(rank == 2,
"This function is only implemented for rank==2");
1239 for (
unsigned int d = 0;
d < dim; ++
d)
1240 for (
unsigned int e = 0;
e <
d; ++
e)
1241 Assert(t[d][e] == t[e][d],
1242 ExcMessage(
"The incoming Tensor must be exactly symmetric."));
1244 for (
unsigned int d = 0;
d < dim; ++
d)
1247 for (
unsigned int d = 0, c = 0;
d < dim; ++
d)
1248 for (
unsigned int e = d + 1;
e < dim; ++
e, ++c)
1249 data[dim + c] = t[d][e];
1254template <
int rank_,
int dim,
typename Number>
1255template <
typename OtherNumber>
1259 : data(initializer.data)
1264template <
int rank_,
int dim,
typename Number>
1267 const Number (&array)[n_independent_components])
1269 *reinterpret_cast<const typename base_tensor_type::array_type *>(array))
1272 Assert(
sizeof(
typename base_tensor_type::array_type) ==
sizeof(array),
1278template <
int rank_,
int dim,
typename Number>
1279template <
typename OtherNumber>
1290template <
int rank_,
int dim,
typename Number>
1295 ExcMessage(
"Only assignment with zero is allowed"));
1306 namespace SymmetricTensorImplementation
1308 template <
int dim,
typename Number>
1309 constexpr inline DEAL_II_ALWAYS_INLINE ::Tensor<2, dim, Number>
1310 convert_to_tensor(const ::SymmetricTensor<2, dim, Number> &s)
1315 for (
unsigned int d = 0;
d < dim; ++
d)
1316 t[d][d] = s.access_raw_entry(d);
1319 for (
unsigned int d = 0, c = 0;
d < dim; ++
d)
1320 for (
unsigned int e = d + 1;
e < dim; ++
e, ++c)
1322 t[
d][
e] = s.access_raw_entry(dim + c);
1323 t[
e][
d] = s.access_raw_entry(dim + c);
1329 template <
int dim,
typename Number>
1330 constexpr ::Tensor<4, dim, Number>
1331 convert_to_tensor(const ::SymmetricTensor<4, dim, Number> &st)
1338 for (
unsigned int i = 0; i < dim; ++i)
1339 for (
unsigned int j = i; j < dim; ++j)
1340 for (
unsigned int k = 0; k < dim; ++k)
1341 for (
unsigned int l = k;
l < dim; ++
l)
1351 template <
typename Number>
1352 struct Inverse<2, 1, Number>
1354 constexpr static inline DEAL_II_ALWAYS_INLINE
1355 ::SymmetricTensor<2, 1, Number>
1356 value(const ::SymmetricTensor<2, 1, Number> &t)
1360 tmp[0][0] = 1.0 / t[0][0];
1367 template <
typename Number>
1368 struct Inverse<2, 2, Number>
1370 constexpr static inline DEAL_II_ALWAYS_INLINE
1371 ::SymmetricTensor<2, 2, Number>
1372 value(const ::SymmetricTensor<2, 2, Number> &t)
1382 const Number inv_det_t =
1383 1.0 / (t[idx_00] * t[idx_11] - t[idx_01] * t[idx_01]);
1384 tmp[idx_00] = t[idx_11];
1385 tmp[idx_01] = -t[idx_01];
1386 tmp[idx_11] = t[idx_00];
1394 template <
typename Number>
1395 struct Inverse<2, 3, Number>
1397 constexpr static ::SymmetricTensor<2, 3, Number>
1398 value(const ::SymmetricTensor<2, 3, Number> &t)
1442 const Number inv_det_t =
1443 1.0 / (t[idx_00] * t[idx_11] * t[idx_22] -
1444 t[idx_00] * t[idx_12] * t[idx_12] -
1445 t[idx_01] * t[idx_01] * t[idx_22] +
1446 2.0 * t[idx_01] * t[idx_02] * t[idx_12] -
1447 t[idx_02] * t[idx_02] * t[idx_11]);
1448 tmp[idx_00] = t[idx_11] * t[idx_22] - t[idx_12] * t[idx_12];
1449 tmp[idx_01] = -t[idx_01] * t[idx_22] + t[idx_02] * t[idx_12];
1450 tmp[idx_02] = t[idx_01] * t[idx_12] - t[idx_02] * t[idx_11];
1451 tmp[idx_11] = t[idx_00] * t[idx_22] - t[idx_02] * t[idx_02];
1452 tmp[idx_12] = -t[idx_00] * t[idx_12] + t[idx_01] * t[idx_02];
1453 tmp[idx_22] = t[idx_00] * t[idx_11] - t[idx_01] * t[idx_01];
1461 template <
typename Number>
1462 struct Inverse<4, 1, Number>
1464 constexpr static inline ::SymmetricTensor<4, 1, Number>
1465 value(const ::SymmetricTensor<4, 1, Number> &t)
1468 tmp.
data[0][0] = 1.0 / t.data[0][0];
1474 template <
typename Number>
1475 struct Inverse<4, 2, Number>
1477 constexpr static inline ::SymmetricTensor<4, 2, Number>
1478 value(const ::SymmetricTensor<4, 2, Number> &t)
1504 const Number t4 = t.
data[0][0] * t.data[1][1],
1505 t6 = t.data[0][0] * t.data[1][2],
1506 t8 = t.data[0][1] * t.data[1][0],
1507 t00 = t.data[0][2] * t.data[1][0],
1508 t01 = t.data[0][1] * t.data[2][0],
1509 t04 = t.data[0][2] * t.data[2][0],
1510 t07 = 1.0 / (t4 * t.data[2][2] - t6 * t.data[2][1] -
1511 t8 * t.data[2][2] + t00 * t.data[2][1] +
1512 t01 * t.data[1][2] - t04 * t.data[1][1]);
1514 (t.data[1][1] * t.data[2][2] - t.data[1][2] * t.data[2][1]) * t07;
1516 -(t.data[0][1] * t.data[2][2] - t.data[0][2] * t.data[2][1]) * t07;
1518 -(-t.data[0][1] * t.data[1][2] + t.data[0][2] * t.data[1][1]) * t07;
1520 -(t.data[1][0] * t.data[2][2] - t.data[1][2] * t.data[2][0]) * t07;
1521 tmp.
data[1][1] = (t.data[0][0] * t.data[2][2] - t04) * t07;
1522 tmp.
data[1][2] = -(t6 - t00) * t07;
1524 -(-t.data[1][0] * t.data[2][1] + t.data[1][1] * t.data[2][0]) * t07;
1525 tmp.
data[2][1] = -(t.data[0][0] * t.data[2][1] - t01) * t07;
1526 tmp.
data[2][2] = (t4 - t8) * t07;
1530 tmp.
data[2][0] /= 2;
1531 tmp.
data[2][1] /= 2;
1532 tmp.
data[0][2] /= 2;
1533 tmp.
data[1][2] /= 2;
1534 tmp.
data[2][2] /= 4;
1541 template <
typename Number>
1542 struct Inverse<4, 3, Number>
1544 static ::SymmetricTensor<4, 3, Number>
1545 value(const ::SymmetricTensor<4, 3, Number> &t)
1555 const unsigned int N = 6;
1561 for (
unsigned int i = 0; i < N; ++i)
1562 diagonal_sum += std::fabs(tmp.
data[i][i]);
1563 const Number typical_diagonal_element =
1564 diagonal_sum /
static_cast<double>(N);
1565 (void)typical_diagonal_element;
1568 for (
unsigned int i = 0; i < N; ++i)
1571 for (
unsigned int j = 0; j < N; ++j)
1575 Number
max = std::fabs(tmp.
data[j][j]);
1577 for (
unsigned int i = j + 1; i < N; ++i)
1578 if (std::fabs(tmp.
data[i][j]) > max)
1580 max = std::fabs(tmp.
data[i][j]);
1585 Assert(max > 1.e-16 * typical_diagonal_element,
1586 ExcMessage(
"This tensor seems to be noninvertible"));
1591 for (
unsigned int k = 0; k < N; ++k)
1592 std::swap(tmp.
data[j][k], tmp.
data[r][k]);
1594 std::swap(p[j], p[r]);
1598 const Number hr = 1. / tmp.
data[j][j];
1599 tmp.
data[j][j] = hr;
1600 for (
unsigned int k = 0; k < N; ++k)
1604 for (
unsigned int i = 0; i < N; ++i)
1608 tmp.
data[i][k] -= tmp.
data[i][j] * tmp.
data[j][k] * hr;
1611 for (
unsigned int i = 0; i < N; ++i)
1613 tmp.
data[i][j] *= hr;
1614 tmp.
data[j][i] *= -hr;
1616 tmp.
data[j][j] = hr;
1621 for (
unsigned int i = 0; i < N; ++i)
1623 for (
unsigned int k = 0; k < N; ++k)
1624 hv[p[k]] = tmp.
data[i][k];
1625 for (
unsigned int k = 0; k < N; ++k)
1626 tmp.
data[i][k] = hv[k];
1631 for (
unsigned int i = 3; i < 6; ++i)
1632 for (
unsigned int j = 0; j < 3; ++j)
1633 tmp.
data[i][j] /= 2;
1635 for (
unsigned int i = 0; i < 3; ++i)
1636 for (
unsigned int j = 3; j < 6; ++j)
1637 tmp.
data[i][j] /= 2;
1639 for (
unsigned int i = 3; i < 6; ++i)
1640 for (
unsigned int j = 3; j < 6; ++j)
1641 tmp.
data[i][j] /= 4;
1652template <
int rank_,
int dim,
typename Number>
1657 return internal::SymmetricTensorImplementation::convert_to_tensor(*
this);
1662template <
int rank_,
int dim,
typename Number>
1667 return data == t.
data;
1672template <
int rank_,
int dim,
typename Number>
1677 return data != t.
data;
1682template <
int rank_,
int dim,
typename Number>
1683template <
typename OtherNumber>
1694template <
int rank_,
int dim,
typename Number>
1695template <
typename OtherNumber>
1706template <
int rank_,
int dim,
typename Number>
1707template <
typename OtherNumber>
1717template <
int rank_,
int dim,
typename Number>
1718template <
typename OtherNumber>
1728template <
int rank_,
int dim,
typename Number>
1739template <
int rank_,
int dim,
typename Number>
1748template <
int rank_,
int dim,
typename Number>
1749constexpr std::size_t
1761 template <
int dim,
typename Number,
typename OtherNumber = Number>
1763 typename SymmetricTensorAccessors::
1764 double_contraction_result<2, 2, dim, Number, OtherNumber>::type
1765 perform_double_contraction(
1766 const typename SymmetricTensorAccessors::StorageType<2, dim, Number>::
1767 base_tensor_type &data,
1768 const typename SymmetricTensorAccessors::
1769 StorageType<2, dim, OtherNumber>::base_tensor_type &sdata)
1771 using result_type =
typename SymmetricTensorAccessors::
1772 double_contraction_result<2, 2, dim, Number, OtherNumber>::type;
1777 return data[0] * sdata[0];
1782 result_type
sum = data[dim] * sdata[dim];
1783 for (
unsigned int d = dim + 1;
d < (dim * (dim + 1) / 2); ++
d)
1784 sum += data[d] * sdata[d];
1788 for (
unsigned int d = 0;
d < dim; ++
d)
1789 sum += data[d] * sdata[d];
1796 template <
int dim,
typename Number,
typename OtherNumber = Number>
1798 typename SymmetricTensorAccessors::
1799 double_contraction_result<4, 2, dim, Number, OtherNumber>::type
1800 perform_double_contraction(
1801 const typename SymmetricTensorAccessors::StorageType<4, dim, Number>::
1802 base_tensor_type &data,
1803 const typename SymmetricTensorAccessors::
1804 StorageType<2, dim, OtherNumber>::base_tensor_type &sdata)
1806 using result_type =
typename SymmetricTensorAccessors::
1807 double_contraction_result<4, 2, dim, Number, OtherNumber>::type;
1808 using value_type =
typename SymmetricTensorAccessors::
1809 double_contraction_result<4, 2, dim, Number, OtherNumber>::value_type;
1811 const unsigned int data_dim = SymmetricTensorAccessors::
1812 StorageType<2, dim, value_type>::n_independent_components;
1813 value_type tmp[data_dim]{};
1814 for (
unsigned int i = 0; i < data_dim; ++i)
1816 perform_double_contraction<dim, Number, OtherNumber>(data[i], sdata);
1817 return result_type(tmp);
1822 template <
int dim,
typename Number,
typename OtherNumber = Number>
1824 typename SymmetricTensorAccessors::StorageType<
1827 typename SymmetricTensorAccessors::
1828 double_contraction_result<2, 4, dim, Number, OtherNumber>::value_type>::
1830 perform_double_contraction(
1831 const typename SymmetricTensorAccessors::StorageType<2, dim, Number>::
1832 base_tensor_type &data,
1833 const typename SymmetricTensorAccessors::
1834 StorageType<4, dim, OtherNumber>::base_tensor_type &sdata)
1836 using value_type =
typename SymmetricTensorAccessors::
1837 double_contraction_result<2, 4, dim, Number, OtherNumber>::value_type;
1838 using base_tensor_type =
typename SymmetricTensorAccessors::
1839 StorageType<2, dim, value_type>::base_tensor_type;
1841 base_tensor_type tmp;
1842 for (
unsigned int i = 0; i < tmp.dimension; ++i)
1845 value_type
sum = data[dim] * sdata[dim][i];
1846 for (
unsigned int d = dim + 1;
d < (dim * (dim + 1) / 2); ++
d)
1847 sum += data[d] * sdata[d][i];
1851 for (
unsigned int d = 0;
d < dim; ++
d)
1852 sum += data[d] * sdata[d][i];
1860 template <
int dim,
typename Number,
typename OtherNumber = Number>
1862 typename SymmetricTensorAccessors::StorageType<
1865 typename SymmetricTensorAccessors::
1866 double_contraction_result<4, 4, dim, Number, OtherNumber>::value_type>::
1868 perform_double_contraction(
1869 const typename SymmetricTensorAccessors::StorageType<4, dim, Number>::
1870 base_tensor_type &data,
1871 const typename SymmetricTensorAccessors::
1872 StorageType<4, dim, OtherNumber>::base_tensor_type &sdata)
1874 using value_type =
typename SymmetricTensorAccessors::
1875 double_contraction_result<4, 4, dim, Number, OtherNumber>::value_type;
1876 using base_tensor_type =
typename SymmetricTensorAccessors::
1877 StorageType<4, dim, value_type>::base_tensor_type;
1879 const unsigned int data_dim = SymmetricTensorAccessors::
1880 StorageType<2, dim, value_type>::n_independent_components;
1881 base_tensor_type tmp;
1882 for (
unsigned int i = 0; i < data_dim; ++i)
1883 for (
unsigned int j = 0; j < data_dim; ++j)
1886 for (
unsigned int d = dim;
d < (dim * (dim + 1) / 2); ++
d)
1887 tmp[i][j] += data[i][d] * sdata[d][j];
1888 tmp[i][j] += tmp[i][j];
1891 for (
unsigned int d = 0;
d < dim; ++
d)
1892 tmp[i][j] += data[i][d] * sdata[d][j];
1901template <
int rank_,
int dim,
typename Number>
1902template <
typename OtherNumber>
1904 typename internal::SymmetricTensorAccessors::
1905 double_contraction_result<rank_, 2, dim, Number, OtherNumber>::type
1913 return internal::perform_double_contraction<dim, Number, OtherNumber>(data,
1919template <
int rank_,
int dim,
typename Number>
1920template <
typename OtherNumber>
1922 double_contraction_result<rank_, 4, dim, Number, OtherNumber>::type
1926 typename internal::SymmetricTensorAccessors::
1927 double_contraction_result<rank_, 4, dim, Number, OtherNumber>::type tmp;
1929 internal::perform_double_contraction<dim, Number, OtherNumber>(data,
1952 template <
typename Type>
1953 struct Uninitialized
1958 template <
typename Type>
1959 Type Uninitialized<Type>::value;
1961 template <
int dim,
typename Number>
1964 typename SymmetricTensorAccessors::
1965 StorageType<2, dim, Number>::base_tensor_type &data)
1973 if (indices[0] == indices[1])
1974 return data[indices[0]];
1981 Assert(((indices[0] == 1) && (indices[1] == 0)) ||
1982 ((indices[0] == 0) && (indices[1] == 1)),
1991 for (
unsigned int d = 0, c = 0;
d < dim; ++
d)
1992 for (
unsigned int e = d + 1;
e < dim; ++
e, ++c)
1993 if ((sorted_indices[0] == d) && (sorted_indices[1] == e))
1994 return data[dim + c];
2002 return Uninitialized<Number>::value;
2007 template <
int dim,
typename Number>
2010 const typename SymmetricTensorAccessors::
2011 StorageType<2, dim, Number>::base_tensor_type &data)
2019 if (indices[0] == indices[1])
2020 return data[indices[0]];
2027 Assert(((indices[0] == 1) && (indices[1] == 0)) ||
2028 ((indices[0] == 0) && (indices[1] == 1)),
2037 for (
unsigned int d = 0, c = 0;
d < dim; ++
d)
2038 for (
unsigned int e = d + 1;
e < dim; ++
e, ++c)
2039 if ((sorted_indices[0] == d) && (sorted_indices[1] == e))
2040 return data[dim + c];
2048 return Uninitialized<Number>::value;
2053 template <
int dim,
typename Number>
2054 constexpr inline Number &
2056 typename SymmetricTensorAccessors::
2057 StorageType<4, dim, Number>::base_tensor_type &data)
2071 constexpr std::size_t base_index[2][2] = {{0, 2}, {2, 1}};
2072 return data[base_index[indices[0]][indices[1]]]
2073 [base_index[indices[2]][indices[3]]];
2082 constexpr std::size_t base_index[3][3] = {{0, 3, 4},
2085 return data[base_index[indices[0]][indices[1]]]
2086 [base_index[indices[2]][indices[3]]];
2096 return Uninitialized<Number>::value;
2100 template <
int dim,
typename Number>
2103 const typename SymmetricTensorAccessors::
2104 StorageType<4, dim, Number>::base_tensor_type &data)
2118 constexpr std::size_t base_index[2][2] = {{0, 2}, {2, 1}};
2119 return data[base_index[indices[0]][indices[1]]]
2120 [base_index[indices[2]][indices[3]]];
2129 constexpr std::size_t base_index[3][3] = {{0, 3, 4},
2132 return data[base_index[indices[0]][indices[1]]]
2133 [base_index[indices[2]][indices[3]]];
2143 return Uninitialized<Number>::value;
2150template <
int rank_,
int dim,
typename Number>
2155 for (
unsigned int r = 0; r < rank; ++r)
2157 return internal::symmetric_tensor_access<dim, Number>(indices, data);
2162template <
int rank_,
int dim,
typename Number>
2167 for (
unsigned int r = 0; r < rank; ++r)
2169 return internal::symmetric_tensor_access<dim, Number>(indices, data);
2176 namespace SymmetricTensorImplementation
2178 template <
int rank_>
2180 get_partially_filled_indices(
const unsigned int row,
2181 const std::integral_constant<int, 2> &)
2187 template <
int rank_>
2189 get_partially_filled_indices(
const unsigned int row,
2190 const std::integral_constant<int, 4> &)
2201template <
int rank_,
int dim,
typename Number>
2203 Accessor<rank_, dim,
true, rank_ - 1, Number>
2206 return internal::SymmetricTensorAccessors::
2207 Accessor<rank_, dim,
true, rank_ - 1, Number>(
2209 internal::SymmetricTensorImplementation::get_partially_filled_indices<
2210 rank_>(row, std::integral_constant<int, rank_>()));
2215template <
int rank_,
int dim,
typename Number>
2217 Accessor<rank_, dim,
false, rank_ - 1, Number>
2220 return internal::SymmetricTensorAccessors::
2221 Accessor<rank_, dim,
false, rank_ - 1, Number>(
2223 internal::SymmetricTensorImplementation::get_partially_filled_indices<
2224 rank_>(row, std::integral_constant<int, rank_>()));
2229template <
int rank_,
int dim,
typename Number>
2234 return operator()(indices);
2239template <
int rank_,
int dim,
typename Number>
2244 return operator()(indices);
2249template <
int rank_,
int dim,
typename Number>
2253 return std::addressof(this->access_raw_entry(0));
2258template <
int rank_,
int dim,
typename Number>
2259inline const Number *
2262 return std::addressof(this->access_raw_entry(0));
2267template <
int rank_,
int dim,
typename Number>
2271 return begin_raw() + n_independent_components;
2276template <
int rank_,
int dim,
typename Number>
2277inline const Number *
2280 return begin_raw() + n_independent_components;
2287 namespace SymmetricTensorImplementation
2289 template <
int dim,
typename Number>
2290 constexpr unsigned int
2291 entry_to_indices(const ::SymmetricTensor<2, dim, Number> &,
2292 const unsigned int index)
2298 template <
int dim,
typename Number>
2299 constexpr ::TableIndices<2>
2300 entry_to_indices(const ::SymmetricTensor<4, dim, Number> &,
2301 const unsigned int index)
2312template <
int rank_,
int dim,
typename Number>
2313constexpr inline const Number &
2315 const unsigned int index)
const
2318 return data[internal::SymmetricTensorImplementation::entry_to_indices(*
this,
2324template <
int rank_,
int dim,
typename Number>
2325constexpr inline Number &
2329 return data[internal::SymmetricTensorImplementation::entry_to_indices(*
this,
2337 template <
int dim,
typename Number>
2339 compute_norm(
const typename SymmetricTensorAccessors::
2340 StorageType<2, dim, Number>::base_tensor_type &data)
2367 for (
unsigned int d = 0;
d < dim; ++
d)
2370 for (
unsigned int d = dim;
d < (dim * dim + dim) / 2; ++
d)
2381 template <
int dim,
typename Number>
2383 compute_norm(
const typename SymmetricTensorAccessors::
2384 StorageType<4, dim, Number>::base_tensor_type &data)
2396 const unsigned int n_independent_components = data.dimension;
2398 for (
unsigned int i = 0; i < dim; ++i)
2399 for (
unsigned int j = 0; j < dim; ++j)
2402 for (
unsigned int i = 0; i < dim; ++i)
2403 for (
unsigned int j = dim; j < n_independent_components; ++j)
2406 for (
unsigned int i = dim; i < n_independent_components; ++i)
2407 for (
unsigned int j = 0; j < dim; ++j)
2410 for (
unsigned int i = dim; i < n_independent_components; ++i)
2411 for (
unsigned int j = dim; j < n_independent_components; ++j)
2424template <
int rank_,
int dim,
typename Number>
2428 return internal::compute_norm<dim, Number>(data);
2435 namespace SymmetricTensorImplementation
2458 constexpr unsigned int table[2][2] = {{0, 2}, {2, 1}};
2459 return table[indices[0]][indices[1]];
2464 constexpr unsigned int table[3][3] = {{0, 3, 4},
2467 return table[indices[0]][indices[1]];
2472 constexpr unsigned int table[4][4] = {{0, 4, 5, 6},
2476 return table[indices[0]][indices[1]];
2482 if (indices[0] == indices[1])
2486 sorted_indices.sort();
2488 for (
unsigned int d = 0, c = 0;
d < dim; ++
d)
2489 for (
unsigned int e = d + 1;
e < dim; ++
e, ++c)
2490 if ((sorted_indices[0] == d) && (sorted_indices[1] == e))
2506 template <
int dim,
int rank_>
2507 constexpr inline unsigned int
2518template <
int rank_,
int dim,
typename Number>
2519constexpr unsigned int
2523 return internal::SymmetricTensorImplementation::component_to_unrolled_index<
2531 namespace SymmetricTensorImplementation
2543 const std::integral_constant<int, 2> &)
2581 for (
unsigned int d = 0, c = dim;
d < dim; ++
d)
2582 for (
unsigned int e = d + 1;
e < dim; ++
e, ++c)
2600 template <
int dim,
int rank_>
2602 typename std::enable_if<rank_ != 2, TableIndices<rank_>>::type
2604 const std::integral_constant<int, rank_> &)
2613 n_independent_components));
2621template <
int rank_,
int dim,
typename Number>
2624 const unsigned int i)
2626 return internal::SymmetricTensorImplementation::unrolled_to_component_indices<
2627 dim>(i, std::integral_constant<int, rank_>());
2632template <
int rank_,
int dim,
typename Number>
2633template <
class Archive>
2658template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2683template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2703template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2720template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2737template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2754template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2765template <
int dim,
typename Number>
2781 return (tmp + tmp + t.
data[0] * t.
data[1] * t.
data[2] -
2805template <
int dim,
typename Number>
2814template <
int dim,
typename Number>
2818 Number t = d.data[0];
2819 for (
unsigned int i = 1; i < dim; ++i)
2836template <
int dim,
typename Number>
2855template <
typename Number>
2882template <
typename Number>
2886 return t[0][0] * t[1][1] - t[0][1] * t[0][1];
2899template <
typename Number>
2903 return (t[0][0] * t[1][1] + t[1][1] * t[2][2] + t[2][2] * t[0][0] -
2904 t[0][1] * t[0][1] - t[0][2] * t[0][2] - t[1][2] * t[1][2]);
2916template <
typename Number>
2917std::array<Number, 1>
2944template <
typename Number>
2945std::array<Number, 2>
2972template <
typename Number>
2973std::array<Number, 3>
2980 namespace SymmetricTensorImplementation
3019 template <
int dim,
typename Number>
3023 std::array<Number, dim> & d,
3024 std::array<Number, dim - 1> & e);
3067 template <
int dim,
typename Number>
3068 std::array<std::pair<Number, Tensor<1, dim, Number>>, dim>
3112 template <
int dim,
typename Number>
3113 std::array<std::pair<Number, Tensor<1, dim, Number>>, dim>
3131 template <
typename Number>
3132 std::array<std::pair<Number, Tensor<1, 2, Number>>, 2>
3133 hybrid(const ::SymmetricTensor<2, 2, Number> &A);
3169 template <
typename Number>
3170 std::array<std::pair<Number, Tensor<1, 3, Number>>, 3>
3171 hybrid(const ::SymmetricTensor<2, 3, Number> &A);
3177 template <
int dim,
typename Number>
3184 return lhs.first > rhs.first;
3287template <
int dim,
typename Number>
3288std::array<std::pair<Number, Tensor<1, dim, Number>>,
3289 std::integral_constant<int, dim>::value>
3304template <
int rank_,
int dim,
typename Number>
3313template <
int dim,
typename Number>
3320 const Number tr =
trace(t) / dim;
3321 for (
unsigned int i = 0; i < dim; ++i)
3329template <
int dim,
typename Number>
3349 for (
unsigned int d = 0; d < dim; ++d)
3357template <
int dim,
typename Number>
3364 for (
unsigned int i = 0; i < dim; ++i)
3365 for (
unsigned int j = 0; j < dim; ++j)
3374 for (
unsigned int i = dim;
3375 i < internal::SymmetricTensorAccessors::StorageType<4, dim, Number>::
3385template <
int dim,
typename Number>
3392 for (
unsigned int i = 0; i < dim; ++i)
3400 for (
unsigned int i = dim;
3401 i < internal::SymmetricTensorAccessors::StorageType<4, dim, Number>::
3420template <
int dim,
typename Number>
3440template <
int dim,
typename Number>
3471template <
int dim,
typename Number>
3479 for (
unsigned int i = 0; i < dim; ++i)
3480 for (
unsigned int j = i; j < dim; ++j)
3481 for (
unsigned int k = 0; k < dim; ++k)
3482 for (
unsigned int l = k; l < dim; ++l)
3483 tmp[i][j][k][l] = t1[i][j] * t2[k][l];
3497template <
int dim,
typename Number>
3502 for (
unsigned int d = 0; d < dim; ++d)
3503 result[d][d] = t[d][d];
3506 for (
unsigned int d = 0; d < dim; ++d)
3507 for (
unsigned int e = d + 1; e < dim; ++e)
3508 result[d][e] = (t[d][e] + t[e][d]) * half;
3521template <
int rank_,
int dim,
typename Number>
3539template <
int rank_,
int dim,
typename Number>
3574template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
3581 const OtherNumber & factor)
3604template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
3614 return (t * factor);
3624template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
3631 const OtherNumber & factor)
3647template <
int rank_,
int dim>
3664template <
int rank_,
int dim>
3680template <
int rank_,
int dim>
3698template <
int dim,
typename Number,
typename OtherNumber>
3720template <
int dim,
typename Number,
typename OtherNumber>
3728 for (
unsigned int i = 0; i < dim; ++i)
3729 for (
unsigned int j = 0; j < dim; ++j)
3730 s += t1[i][j] * t2[i][j];
3748template <
int dim,
typename Number,
typename OtherNumber>
3771template <
typename Number,
typename OtherNumber>
3778 tmp[0][0] = t[0][0][0][0] * s[0][0];
3797template <
typename Number,
typename OtherNumber>
3798constexpr inline void
3804 tmp[0][0] = t[0][0][0][0] * s[0][0];
3823template <
typename Number,
typename OtherNumber>
3824constexpr inline void
3830 const unsigned int dim = 2;
3832 for (
unsigned int i = 0; i < dim; ++i)
3833 for (
unsigned int j = i; j < dim; ++j)
3834 tmp[i][j] = t[i][j][0][0] * s[0][0] + t[i][j][1][1] * s[1][1] +
3835 2 * t[i][j][0][1] * s[0][1];
3854template <
typename Number,
typename OtherNumber>
3855constexpr inline void
3861 const unsigned int dim = 2;
3863 for (
unsigned int i = 0; i < dim; ++i)
3864 for (
unsigned int j = i; j < dim; ++j)
3865 tmp[i][j] = s[0][0] * t[0][0][i][j] * +s[1][1] * t[1][1][i][j] +
3866 2 * s[0][1] * t[0][1][i][j];
3885template <
typename Number,
typename OtherNumber>
3886constexpr inline void
3892 const unsigned int dim = 3;
3894 for (
unsigned int i = 0; i < dim; ++i)
3895 for (
unsigned int j = i; j < dim; ++j)
3896 tmp[i][j] = t[i][j][0][0] * s[0][0] + t[i][j][1][1] * s[1][1] +
3897 t[i][j][2][2] * s[2][2] + 2 * t[i][j][0][1] * s[0][1] +
3898 2 * t[i][j][0][2] * s[0][2] + 2 * t[i][j][1][2] * s[1][2];
3917template <
typename Number,
typename OtherNumber>
3918constexpr inline void
3924 const unsigned int dim = 3;
3926 for (
unsigned int i = 0; i < dim; ++i)
3927 for (
unsigned int j = i; j < dim; ++j)
3928 tmp[i][j] = s[0][0] * t[0][0][i][j] + s[1][1] * t[1][1][i][j] +
3929 s[2][2] * t[2][2][i][j] + 2 * s[0][1] * t[0][1][i][j] +
3930 2 * s[0][2] * t[0][2][i][j] + 2 * s[1][2] * t[1][2][i][j];
3941template <
int dim,
typename Number,
typename OtherNumber>
3947 for (
unsigned int i = 0; i < dim; ++i)
3948 for (
unsigned int j = 0; j < dim; ++j)
3949 dest[i] += src1[i][j] * src2[j];
3960template <
int dim,
typename Number,
typename OtherNumber>
3990template <
int rank_1,
3994 typename OtherNumber>
3996 typename Tensor<rank_1 + rank_2 - 2,
4026template <
int rank_1,
4030 typename OtherNumber>
4032 typename Tensor<rank_1 + rank_2 - 2,
4052template <
int dim,
typename Number>
4053inline std::ostream &
4061 for (
unsigned int i = 0; i < dim; ++i)
4062 for (
unsigned int j = 0; j < dim; ++j)
4079template <
int dim,
typename Number>
4080inline std::ostream &
4088 for (
unsigned int i = 0; i < dim; ++i)
4089 for (
unsigned int j = 0; j < dim; ++j)
4090 for (
unsigned int k = 0; k < dim; ++k)
4091 for (
unsigned int l = 0; l < dim; ++l)
4092 tt[i][j][k][l] = t[i][j][k][l];
constexpr SymmetricTensor< 2, dim, Number > deviator(const SymmetricTensor< 2, dim, Number > &)
constexpr bool operator==(const SymmetricTensor &) const
constexpr Number first_invariant(const SymmetricTensor< 2, dim, Number > &t)
constexpr void double_contract(SymmetricTensor< 2, 2, typename ProductType< Number, OtherNumber >::type > &tmp, const SymmetricTensor< 2, 2, Number > &s, const SymmetricTensor< 4, 2, OtherNumber > &t)
constexpr void double_contract(SymmetricTensor< 2, 1, typename ProductType< Number, OtherNumber >::type > &tmp, const SymmetricTensor< 4, 1, Number > &t, const SymmetricTensor< 2, 1, OtherNumber > &s)
constexpr ProductType< Number, OtherNumber >::type scalar_product(const Tensor< 2, dim, Number > &t1, const SymmetricTensor< 2, dim, OtherNumber > &t2)
constexpr SymmetricTensor< 4, dim, Number > invert(const SymmetricTensor< 4, dim, Number > &t)
constexpr SymmetricTensor< rank_, dim > operator*(const SymmetricTensor< rank_, dim > &t, const double factor)
constexpr Tensor< 1, dim, typename ProductType< Number, OtherNumber >::type > operator*(const SymmetricTensor< 2, dim, Number > &src1, const Tensor< 1, dim, OtherNumber > &src2)
constexpr SymmetricTensor< 2, dim, Number > symmetrize(const Tensor< 2, dim, Number > &t)
constexpr SymmetricTensor(const Number(&array)[n_independent_components])
constexpr Tensor< rank_, dim, typename ProductType< Number, OtherNumber >::type > operator-(const SymmetricTensor< rank_, dim, Number > &left, const Tensor< rank_, dim, OtherNumber > &right)
constexpr void double_contract(SymmetricTensor< 2, 2, typename ProductType< Number, OtherNumber >::type > &tmp, const SymmetricTensor< 4, 2, Number > &t, const SymmetricTensor< 2, 2, OtherNumber > &s)
static constexpr unsigned int component_to_unrolled_index(const TableIndices< rank_ > &indices)
constexpr Number determinant(const SymmetricTensor< 2, dim, Number > &)
constexpr SymmetricTensor< 2, dim, Number > invert(const SymmetricTensor< 2, dim, Number > &t)
constexpr Tensor< 1, dim, typename ProductType< Number, OtherNumber >::type > operator*(const Tensor< 1, dim, Number > &src1, const SymmetricTensor< 2, dim, OtherNumber > &src2)
std::array< Number, 2 > eigenvalues(const SymmetricTensor< 2, 2, Number > &T)
void serialize(Archive &ar, const unsigned int version)
constexpr Tensor< rank_, dim, typename ProductType< Number, OtherNumber >::type > operator-(const Tensor< rank_, dim, Number > &left, const SymmetricTensor< rank_, dim, OtherNumber > &right)
const Number * begin_raw() const
const Number * end_raw() const
constexpr Number trace(const SymmetricTensor< 2, dim2, Number > &)
std::array< Number, 1 > eigenvalues(const SymmetricTensor< 2, 1, Number > &T)
constexpr internal::SymmetricTensorAccessors::Accessor< rank_, dim, false, rank_ - 1, Number > operator[](const unsigned int row)
typename base_tensor_descriptor::base_tensor_type base_tensor_type
constexpr const Number & operator()(const TableIndices< rank_ > &indices) const
constexpr SymmetricTensor< 4, dim, Number > deviator_tensor()
constexpr bool operator!=(const SymmetricTensor &) const
constexpr Number & operator[](const TableIndices< rank_ > &indices)
constexpr void double_contract(SymmetricTensor< 2, 1, typename ProductType< Number, OtherNumber >::type > &tmp, const SymmetricTensor< 2, 1, Number > &s, const SymmetricTensor< 4, 1, OtherNumber > &t)
constexpr SymmetricTensor< rank_, dim, typename ProductType< Number, typename EnableIfScalar< OtherNumber >::type >::type > operator/(const SymmetricTensor< rank_, dim, Number > &t, const OtherNumber &factor)
static constexpr std::size_t memory_consumption()
constexpr ProductType< Number, OtherNumber >::type scalar_product(const SymmetricTensor< 2, dim, Number > &t1, const Tensor< 2, dim, OtherNumber > &t2)
constexpr Tensor< rank_, dim, typename ProductType< Number, OtherNumber >::type > operator+(const SymmetricTensor< rank_, dim, Number > &left, const Tensor< rank_, dim, OtherNumber > &right)
constexpr const Number & operator[](const TableIndices< rank_ > &indices) const
constexpr SymmetricTensor & operator=(const Number &d)
SymmetricTensor(const Tensor< 2, dim, OtherNumber > &t)
static constexpr TableIndices< rank_ > unrolled_to_component_indices(const unsigned int i)
constexpr SymmetricTensor< 4, dim, Number > outer_product(const SymmetricTensor< 2, dim, Number > &t1, const SymmetricTensor< 2, dim, Number > &t2)
constexpr Number & access_raw_entry(const unsigned int unrolled_index)
constexpr numbers::NumberTraits< Number >::real_type norm() const
constexpr SymmetricTensor operator-() const
constexpr internal::SymmetricTensorAccessors::double_contraction_result< rank_, 2, dim, Number, OtherNumber >::type operator*(const SymmetricTensor< 2, dim, OtherNumber > &s) const
constexpr SymmetricTensor()=default
std::array< std::pair< Number, Tensor< 1, dim, Number > >, std::integral_constant< int, dim >::value > eigenvectors(const SymmetricTensor< 2, dim, Number > &T, const SymmetricTensorEigenvectorMethod method=SymmetricTensorEigenvectorMethod::ql_implicit_shifts)
constexpr Number second_invariant(const SymmetricTensor< 2, 1, Number > &)
constexpr Number third_invariant(const SymmetricTensor< 2, dim, Number > &t)
constexpr SymmetricTensor(const SymmetricTensor< rank_, dim, OtherNumber > &initializer)
constexpr SymmetricTensor & operator-=(const SymmetricTensor< rank_, dim, OtherNumber > &)
constexpr SymmetricTensor< rank_, dim, Number > operator*(const Number &factor, const SymmetricTensor< rank_, dim, Number > &t)
constexpr Tensor< rank_1+rank_2-2, dim, typenameProductType< Number, OtherNumber >::type >::tensor_type operator*(const Tensor< rank_1, dim, Number > &src1, const SymmetricTensor< rank_2, dim, OtherNumber > &src2)
constexpr Tensor< rank_1+rank_2-2, dim, typenameProductType< Number, OtherNumber >::type >::tensor_type operator*(const SymmetricTensor< rank_1, dim, Number > &src1, const Tensor< rank_2, dim, OtherNumber > &src2)
constexpr ProductType< Number, OtherNumber >::type scalar_product(const SymmetricTensor< 2, dim, Number > &t1, const SymmetricTensor< 2, dim, OtherNumber > &t2)
constexpr SymmetricTensor< 4, dim, Number > identity_tensor()
constexpr void double_contract(SymmetricTensor< 2, 3, typename ProductType< Number, OtherNumber >::type > &tmp, const SymmetricTensor< 4, 3, Number > &t, const SymmetricTensor< 2, 3, OtherNumber > &s)
constexpr SymmetricTensor< rank_, dim, typename ProductType< Number, OtherNumber >::type > operator-(const SymmetricTensor< rank_, dim, Number > &left, const SymmetricTensor< rank_, dim, OtherNumber > &right)
constexpr SymmetricTensor< rank_, dim, typename ProductType< Number, OtherNumber >::type > operator+(const SymmetricTensor< rank_, dim, Number > &left, const SymmetricTensor< rank_, dim, OtherNumber > &right)
constexpr Number second_invariant(const SymmetricTensor< 2, 3, Number > &t)
constexpr SymmetricTensor< rank_, dim, Number > operator*(const SymmetricTensor< rank_, dim, Number > &t, const Number &factor)
constexpr const Number & access_raw_entry(const unsigned int unrolled_index) const
constexpr SymmetricTensor & operator=(const SymmetricTensor< rank_, dim, OtherNumber > &rhs)
constexpr SymmetricTensor< rank_, dim, Number > transpose(const SymmetricTensor< rank_, dim, Number > &t)
constexpr SymmetricTensor< rank_, dim > operator*(const double factor, const SymmetricTensor< rank_, dim > &t)
constexpr SymmetricTensor & operator/=(const OtherNumber &factor)
constexpr Tensor< rank_, dim, typename ProductType< Number, OtherNumber >::type > operator+(const Tensor< rank_, dim, Number > &left, const SymmetricTensor< rank_, dim, OtherNumber > &right)
constexpr Number second_invariant(const SymmetricTensor< 2, 2, Number > &t)
constexpr SymmetricTensor & operator+=(const SymmetricTensor< rank_, dim, OtherNumber > &)
constexpr SymmetricTensor< 2, dim, Number > unit_symmetric_tensor()
constexpr internal::SymmetricTensorAccessors::double_contraction_result< rank_, 4, dim, Number, OtherNumber >::type operator*(const SymmetricTensor< 4, dim, OtherNumber > &s) const
constexpr SymmetricTensor< rank_, dim > operator/(const SymmetricTensor< rank_, dim > &t, const double factor)
std::array< Number, 3 > eigenvalues(const SymmetricTensor< 2, 3, Number > &T)
constexpr internal::SymmetricTensorAccessors::Accessor< rank_, dim, true, rank_ - 1, Number > operator[](const unsigned int row) const
constexpr void double_contract(SymmetricTensor< 2, 3, typename ProductType< Number, OtherNumber >::type > &tmp, const SymmetricTensor< 2, 3, Number > &s, const SymmetricTensor< 4, 3, OtherNumber > &t)
constexpr SymmetricTensor & operator*=(const OtherNumber &factor)
constexpr Number & operator()(const TableIndices< rank_ > &indices)
typename AccessorTypes< rank, dim, constness, Number >::reference reference
constexpr reference operator[](const unsigned int) const
const TableIndices< rank > previous_indices
constexpr Accessor(const Accessor &)=default
constexpr Accessor(tensor_type &tensor, const TableIndices< rank > &previous_indices)
constexpr reference operator[](const unsigned int)
typename AccessorTypes< rank, dim, constness, Number >::tensor_type tensor_type
const TableIndices< rank > previous_indices
typename AccessorTypes< rank, dim, constness, Number >::tensor_type tensor_type
constexpr Accessor< rank, dim, constness, P - 1, Number > operator[](const unsigned int i)
constexpr Accessor(tensor_type &tensor, const TableIndices< rank > &previous_indices)
constexpr Accessor(const Accessor &)=default
typename AccessorTypes< rank, dim, constness, Number >::reference reference
constexpr Accessor< rank, dim, constness, P - 1, Number > operator[](const unsigned int i) const
#define DEAL_II_ALWAYS_INLINE
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_CONSTEXPR
#define DEAL_II_NAMESPACE_CLOSE
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcIndexRange(std::size_t arg1, std::size_t arg2, std::size_t arg3)
static ::ExceptionBase & ExcMessage(std::string arg1)
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
Tensor< 2, dim, Number > l(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
T sum(const T &t, const MPI_Comm &mpi_communicator)
constexpr TableIndices< 2 > merge(const TableIndices< 2 > &previous_indices, const unsigned int new_index, const unsigned int position)
void tridiagonalize(const ::SymmetricTensor< 2, dim, Number > &A, ::Tensor< 2, dim, Number > &Q, std::array< Number, dim > &d, std::array< Number, dim - 1 > &e)
constexpr bool value_is_zero(const Number &value)
static const unsigned int invalid_unsigned_int
::VectorizedArray< Number, width > min(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > max(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > sqrt(const ::VectorizedArray< Number, width > &)
constexpr SymmetricTensor< rank_, dim, typename ProductType< OtherNumber, typename EnableIfScalar< Number >::type >::type > operator*(const Number &factor, const SymmetricTensor< rank_, dim, OtherNumber > &t)
constexpr SymmetricTensor< rank_, dim, typename ProductType< Number, typename EnableIfScalar< OtherNumber >::type >::type > operator*(const SymmetricTensor< rank_, dim, Number > &t, const OtherNumber &factor)
typename internal::ProductTypeImpl< typename std::decay< T >::type, typename std::decay< U >::type >::type type
static constexpr const T & value(const T &t)
typename ProductType< Number, OtherNumber >::type type
typename ProductType< Number, OtherNumber >::type value_type
std::pair< Number, Tensor< 1, dim, Number > > EigValsVecs
bool operator()(const EigValsVecs &lhs, const EigValsVecs &rhs)
static real_type abs(const number &x)
constexpr SymmetricTensor< 2, dim, Number > deviator(const SymmetricTensor< 2, dim, Number > &)
constexpr Number determinant(const SymmetricTensor< 2, dim, Number > &)
constexpr SymmetricTensor< 2, dim, Number > invert(const SymmetricTensor< 2, dim, Number > &)
constexpr Number trace(const SymmetricTensor< 2, dim2, Number > &)
constexpr SymmetricTensor< 4, dim, Number > deviator_tensor()
std::ostream & operator<<(std::ostream &out, const SymmetricTensor< 2, dim, Number > &t)
constexpr ProductType< Number, OtherNumber >::type scalar_product(const SymmetricTensor< 2, dim, Number > &t1, const SymmetricTensor< 2, dim, OtherNumber > &t2)
constexpr SymmetricTensor< 4, dim, Number > identity_tensor()
SymmetricTensorEigenvectorMethod
constexpr SymmetricTensor< 2, dim, Number > unit_symmetric_tensor()