246 template <
int rank,
int dim,
typename T,
typename U>
252 std::complex<typename ProductType<T, U>::type>>;
255 template <
int rank,
int dim,
typename T,
typename U>
262 std::complex<typename ProductType<T, U>::type>>;
265 template <
typename T,
int rank,
int dim,
typename U>
271 std::complex<typename ProductType<T, U>::type>>;
274 template <
int rank,
int dim,
typename T,
typename U>
281 std::complex<typename ProductType<T, U>::type>>;
295 template <
int rank,
int dim,
typename Number>
314 const unsigned int new_index,
315 const unsigned int position)
322 return {previous_indices[0], new_index};
336 const unsigned int new_index,
337 const unsigned int position)
349 return {previous_indices[0],
354 return {previous_indices[0],
359 return {previous_indices[0],
380 typename OtherNumber = Number>
395 template <
int dim,
typename Number,
typename OtherNumber>
415 template <
int rank,
int dim,
typename Number>
421 template <
int dim,
typename Number>
429 (dim * dim + dim) / 2;
442 template <
int dim,
typename Number>
474 template <
int rank,
int dim,
bool constness,
typename Number>
483 template <
int rank,
int dim,
typename Number>
497 template <
int rank,
int dim,
typename Number>
538 template <
int rank,
int dim,
bool constness,
int P,
typename Number>
585 constexpr Accessor<rank, dim, constness, P - 1, Number>
592 constexpr Accessor<rank, dim, constness, P - 1, Number>
604 template <
int,
int,
typename>
605 friend class ::SymmetricTensor;
606 template <
int,
int,
bool,
int,
typename>
608 friend class ::SymmetricTensor<rank, dim, Number>;
609 friend class Accessor<rank, dim, constness, P + 1, Number>;
621 template <
int rank,
int dim,
bool constness,
typename Number>
690 template <
int,
int,
typename>
691 friend class ::SymmetricTensor;
692 template <
int,
int,
bool,
int,
typename>
694 friend class ::SymmetricTensor<rank, dim, Number>;
696 Accessor<rank, dim, constness, 2, Number>;
775template <int rank_, int dim, typename Number>
779 static_assert(rank_ % 2 == 0,
"A SymmetricTensor must have even rank!");
794 static const unsigned int rank = rank_;
803 n_independent_components;
825 template <
typename OtherNumber>
851 template <
typename OtherNumber>
861 template <
typename OtherNumber>
899 template <
typename OtherNumber>
906 template <
typename OtherNumber>
914 template <
typename OtherNumber>
921 template <
typename OtherNumber>
984 template <
typename OtherNumber>
986 double_contraction_result<rank_, 2, dim, Number, OtherNumber>::type
993 template <
typename OtherNumber>
995 double_contraction_result<rank_, 4, dim, Number, OtherNumber>::type
1009 constexpr const Number &
1017 constexpr internal::SymmetricTensorAccessors::
1018 Accessor<rank_, dim,
true, rank_ - 1, Number>
1026 constexpr internal::SymmetricTensorAccessors::
1027 Accessor<rank_, dim,
false, rank_ - 1, Number>
1036 constexpr const Number &
1055 constexpr const Number &
1127 template <
class Archive>
1151 template <
int,
int,
typename>
1155 template <
int dim2,
typename Number2>
1159 template <
int dim2,
typename Number2>
1163 template <
int dim2,
typename Number2>
1167 template <
int dim2,
typename Number2>
1171 template <
int dim2,
typename Number2>
1175 template <
int dim2,
typename Number2>
1182 Inverse<2, dim, Number>;
1185 Inverse<4, dim, Number>;
1196template <int rank, int dim, typename Number>
1199template <int rank_, int dim, typename Number>
1200constexpr unsigned
int
1205 namespace SymmetricTensorAccessors
1207 template <
int rank_,
int dim,
bool constness,
int P,
typename Number>
1209 Accessor<rank_, dim, constness, P, Number>::Accessor(
1210 tensor_type &tensor,
1213 , previous_indices(previous_indices)
1218 template <
int rank_,
int dim,
bool constness,
int P,
typename Number>
1220 Accessor<rank_, dim, constness, P - 1, Number>
1221 Accessor<rank_, dim, constness, P, Number>::operator[](
1222 const unsigned int i)
1224 return Accessor<rank_, dim, constness, P - 1, Number>(
1225 tensor, merge(previous_indices, i, rank_ - P));
1230 template <
int rank_,
int dim,
bool constness,
int P,
typename Number>
1232 Accessor<rank_, dim, constness, P - 1, Number>
1233 Accessor<rank_, dim, constness, P, Number>::operator[](
1234 const unsigned int i)
const
1236 return Accessor<rank_, dim, constness, P - 1, Number>(
1237 tensor,
merge(previous_indices, i, rank_ - P));
1242 template <
int rank_,
int dim,
bool constness,
typename Number>
1244 Accessor<rank_, dim, constness, 1, Number>::Accessor(
1245 tensor_type &tensor,
1248 , previous_indices(previous_indices)
1253 template <
int rank_,
int dim,
bool constness,
typename Number>
1255 typename Accessor<rank_, dim, constness, 1, Number>::reference
1256 Accessor<rank_, dim, constness, 1, Number>::operator[](
1257 const unsigned int i)
1259 return tensor(
merge(previous_indices, i, rank_ - 1));
1263 template <
int rank_,
int dim,
bool constness,
typename Number>
1265 typename Accessor<rank_, dim, constness, 1, Number>::reference
1266 Accessor<rank_, dim, constness, 1, Number>::operator[](
1267 const unsigned int i)
const
1269 return tensor(
merge(previous_indices, i, rank_ - 1));
1276template <
int rank_,
int dim,
typename Number>
1277template <
typename OtherNumber>
1282 static_assert(rank == 2,
"This function is only implemented for rank==2");
1283 for (
unsigned int d = 0;
d < dim; ++
d)
1284 for (
unsigned int e = 0;
e <
d; ++
e)
1285 Assert(t[d][e] == t[e][d],
1286 ExcMessage(
"The incoming Tensor must be exactly symmetric."));
1288 for (
unsigned int d = 0;
d < dim; ++
d)
1291 for (
unsigned int d = 0, c = 0;
d < dim; ++
d)
1292 for (
unsigned int e = d + 1;
e < dim; ++
e, ++c)
1293 data[dim + c] = t[d][e];
1298template <
int rank_,
int dim,
typename Number>
1299template <
typename OtherNumber>
1303 : data(initializer.data)
1308template <
int rank_,
int dim,
typename Number>
1311 const Number (&array)[n_independent_components])
1313 *reinterpret_cast<const typename base_tensor_type::array_type *>(array))
1316 Assert(
sizeof(
typename base_tensor_type::array_type) ==
sizeof(array),
1317 ExcInternalError());
1322template <
int rank_,
int dim,
typename Number>
1323template <
typename OtherNumber>
1335template <
int rank_,
int dim,
typename Number>
1341 ExcMessage(
"Only assignment with zero is allowed"));
1354 template <
int dim,
typename Number>
1355 constexpr inline DEAL_II_ALWAYS_INLINE ::Tensor<2, dim, Number>
1356 convert_to_tensor(const ::SymmetricTensor<2, dim, Number> &s)
1358 ::Tensor<2, dim, Number> t;
1361 for (
unsigned int d = 0;
d < dim; ++
d)
1362 t[d][d] = s.access_raw_entry(d);
1365 for (
unsigned int d = 0, c = 0;
d < dim; ++
d)
1366 for (
unsigned int e = d + 1;
e < dim; ++
e, ++c)
1368 t[
d][
e] = s.access_raw_entry(dim + c);
1369 t[
e][
d] = s.access_raw_entry(dim + c);
1375 template <
int dim,
typename Number>
1376 constexpr ::Tensor<4, dim, Number>
1377 convert_to_tensor(const ::SymmetricTensor<4, dim, Number> &st)
1382 ::Tensor<4, dim, Number> t;
1384 for (
unsigned int i = 0; i < dim; ++i)
1385 for (
unsigned int j = i; j < dim; ++j)
1386 for (
unsigned int k = 0; k < dim; ++k)
1387 for (
unsigned int l = k;
l < dim; ++
l)
1397 template <
typename Number>
1400 constexpr static inline DEAL_II_ALWAYS_INLINE
1401 ::SymmetricTensor<2, 1, Number>
1402 value(const ::SymmetricTensor<2, 1, Number> &t)
1404 ::SymmetricTensor<2, 1, Number> tmp;
1406 tmp[0][0] = 1.0 / t[0][0];
1413 template <
typename Number>
1416 constexpr static inline DEAL_II_ALWAYS_INLINE
1417 ::SymmetricTensor<2, 2, Number>
1418 value(const ::SymmetricTensor<2, 2, Number> &t)
1420 ::SymmetricTensor<2, 2, Number> tmp;
1425 const TableIndices<2> idx_00(0, 0);
1426 const TableIndices<2> idx_01(0, 1);
1427 const TableIndices<2> idx_11(1, 1);
1428 const Number inv_det_t =
1429 1.0 / (t[idx_00] * t[idx_11] - t[idx_01] * t[idx_01]);
1430 tmp[idx_00] = t[idx_11];
1431 tmp[idx_01] = -t[idx_01];
1432 tmp[idx_11] = t[idx_00];
1440 template <
typename Number>
1443 constexpr static ::SymmetricTensor<2, 3, Number>
1444 value(const ::SymmetricTensor<2, 3, Number> &t)
1446 ::SymmetricTensor<2, 3, Number> tmp;
1482 const TableIndices<2> idx_00(0, 0);
1483 const TableIndices<2> idx_01(0, 1);
1484 const TableIndices<2> idx_02(0, 2);
1485 const TableIndices<2> idx_11(1, 1);
1486 const TableIndices<2> idx_12(1, 2);
1487 const TableIndices<2> idx_22(2, 2);
1488 const Number inv_det_t =
1489 1.0 / (t[idx_00] * t[idx_11] * t[idx_22] -
1490 t[idx_00] * t[idx_12] * t[idx_12] -
1491 t[idx_01] * t[idx_01] * t[idx_22] +
1492 2.0 * t[idx_01] * t[idx_02] * t[idx_12] -
1493 t[idx_02] * t[idx_02] * t[idx_11]);
1494 tmp[idx_00] = t[idx_11] * t[idx_22] - t[idx_12] * t[idx_12];
1495 tmp[idx_01] = -t[idx_01] * t[idx_22] + t[idx_02] * t[idx_12];
1496 tmp[idx_02] = t[idx_01] * t[idx_12] - t[idx_02] * t[idx_11];
1497 tmp[idx_11] = t[idx_00] * t[idx_22] - t[idx_02] * t[idx_02];
1498 tmp[idx_12] = -t[idx_00] * t[idx_12] + t[idx_01] * t[idx_02];
1499 tmp[idx_22] = t[idx_00] * t[idx_11] - t[idx_01] * t[idx_01];
1507 template <
typename Number>
1510 constexpr static inline ::SymmetricTensor<4, 1, Number>
1511 value(const ::SymmetricTensor<4, 1, Number> &t)
1513 ::SymmetricTensor<4, 1, Number> tmp;
1514 tmp.
data[0][0] = 1.0 / t.data[0][0];
1520 template <
typename Number>
1523 constexpr static inline ::SymmetricTensor<4, 2, Number>
1524 value(const ::SymmetricTensor<4, 2, Number> &t)
1526 ::SymmetricTensor<4, 2, Number> tmp;
1550 const Number t4 = t.data[0][0] * t.data[1][1],
1551 t6 = t.data[0][0] * t.data[1][2],
1552 t8 = t.data[0][1] * t.data[1][0],
1553 t00 = t.data[0][2] * t.data[1][0],
1554 t01 = t.data[0][1] * t.data[2][0],
1555 t04 = t.data[0][2] * t.data[2][0],
1556 t07 = 1.0 / (t4 * t.data[2][2] - t6 * t.data[2][1] -
1557 t8 * t.data[2][2] + t00 * t.data[2][1] +
1558 t01 * t.data[1][2] - t04 * t.data[1][1]);
1560 (t.data[1][1] * t.data[2][2] - t.data[1][2] * t.data[2][1]) * t07;
1562 -(t.data[0][1] * t.data[2][2] - t.data[0][2] * t.data[2][1]) * t07;
1564 -(-t.data[0][1] * t.data[1][2] + t.data[0][2] * t.data[1][1]) * t07;
1566 -(t.data[1][0] * t.data[2][2] - t.data[1][2] * t.data[2][0]) * t07;
1567 tmp.
data[1][1] = (t.data[0][0] * t.data[2][2] - t04) * t07;
1568 tmp.
data[1][2] = -(t6 - t00) * t07;
1570 -(-t.data[1][0] * t.data[2][1] + t.data[1][1] * t.data[2][0]) * t07;
1571 tmp.
data[2][1] = -(t.data[0][0] * t.data[2][1] - t01) * t07;
1572 tmp.
data[2][2] = (t4 - t8) * t07;
1576 tmp.
data[2][0] /= 2;
1577 tmp.
data[2][1] /= 2;
1578 tmp.
data[0][2] /= 2;
1579 tmp.
data[1][2] /= 2;
1580 tmp.
data[2][2] /= 4;
1587 template <
typename Number>
1590 static ::SymmetricTensor<4, 3, Number>
1591 value(const ::SymmetricTensor<4, 3, Number> &t)
1593 ::SymmetricTensor<4, 3, Number> tmp = t;
1601 const unsigned int N = 6;
1607 for (
unsigned int i = 0; i <
N; ++i)
1609 const Number typical_diagonal_element =
1610 diagonal_sum /
static_cast<double>(
N);
1611 (void)typical_diagonal_element;
1614 for (
unsigned int i = 0; i <
N; ++i)
1617 for (
unsigned int j = 0; j <
N; ++j)
1623 for (
unsigned int i = j + 1; i <
N; ++i)
1631 Assert(max > 1.e-16 * typical_diagonal_element,
1632 ExcMessage(
"This tensor seems to be noninvertible"));
1637 for (
unsigned int k = 0; k <
N; ++k)
1638 std::swap(tmp.
data[j][k], tmp.
data[r][k]);
1640 std::swap(p[j], p[r]);
1644 const Number hr = 1. / tmp.
data[j][j];
1645 tmp.
data[j][j] = hr;
1646 for (
unsigned int k = 0; k <
N; ++k)
1650 for (
unsigned int i = 0; i <
N; ++i)
1654 tmp.
data[i][k] -= tmp.
data[i][j] * tmp.
data[j][k] * hr;
1657 for (
unsigned int i = 0; i <
N; ++i)
1659 tmp.
data[i][j] *= hr;
1660 tmp.
data[j][i] *= -hr;
1662 tmp.
data[j][j] = hr;
1667 for (
unsigned int i = 0; i <
N; ++i)
1669 for (
unsigned int k = 0; k <
N; ++k)
1670 hv[p[k]] = tmp.
data[i][k];
1671 for (
unsigned int k = 0; k <
N; ++k)
1672 tmp.
data[i][k] = hv[k];
1677 for (
unsigned int i = 3; i < 6; ++i)
1678 for (
unsigned int j = 0; j < 3; ++j)
1679 tmp.
data[i][j] /= 2;
1681 for (
unsigned int i = 0; i < 3; ++i)
1682 for (
unsigned int j = 3; j < 6; ++j)
1683 tmp.
data[i][j] /= 2;
1685 for (
unsigned int i = 3; i < 6; ++i)
1686 for (
unsigned int j = 3; j < 6; ++j)
1687 tmp.
data[i][j] /= 4;
1698template <
int rank_,
int dim,
typename Number>
1703 return internal::SymmetricTensorImplementation::convert_to_tensor(*
this);
1708template <
int rank_,
int dim,
typename Number>
1713 return data == t.
data;
1718template <
int rank_,
int dim,
typename Number>
1723 return data != t.
data;
1728template <
int rank_,
int dim,
typename Number>
1729template <
typename OtherNumber>
1741template <
int rank_,
int dim,
typename Number>
1742template <
typename OtherNumber>
1754template <
int rank_,
int dim,
typename Number>
1755template <
typename OtherNumber>
1766template <
int rank_,
int dim,
typename Number>
1767template <
typename OtherNumber>
1778template <
int rank_,
int dim,
typename Number>
1790template <
int rank_,
int dim,
typename Number>
1799template <
int rank_,
int dim,
typename Number>
1815 template <
int dim,
typename Number,
typename OtherNumber = Number>
1817 typename SymmetricTensorAccessors::
1818 double_contraction_result<2, 2, dim, Number, OtherNumber>::type
1819 perform_double_contraction(
1821 base_tensor_type &data,
1823 StorageType<2, dim, OtherNumber>::base_tensor_type &sdata)
1825 using result_type =
typename SymmetricTensorAccessors::
1826 double_contraction_result<2, 2, dim, Number, OtherNumber>::type;
1831 return data[0] * sdata[0];
1839 result_type
sum = data[dim] * sdata[dim];
1840 for (
unsigned int d = dim + 1;
d < (dim * (dim + 1) / 2); ++
d)
1841 sum += data[d] * sdata[d];
1845 for (
unsigned int d = 0;
d < dim; ++
d)
1846 sum += data[d] * sdata[d];
1857 template <
int dim,
typename Number,
typename OtherNumber = Number>
1859 typename SymmetricTensorAccessors::
1860 double_contraction_result<4, 2, dim, Number, OtherNumber>::type
1861 perform_double_contraction(
1863 base_tensor_type &data,
1865 StorageType<2, dim, OtherNumber>::base_tensor_type &sdata)
1867 using result_type =
typename SymmetricTensorAccessors::
1868 double_contraction_result<4, 2, dim, Number, OtherNumber>::type;
1869 using value_type =
typename SymmetricTensorAccessors::
1870 double_contraction_result<4, 2, dim, Number, OtherNumber>::value_type;
1872 const unsigned int data_dim = SymmetricTensorAccessors::
1873 StorageType<2, dim, value_type>::n_independent_components;
1874 value_type tmp[data_dim]{};
1875 for (
unsigned int i = 0; i < data_dim; ++i)
1877 perform_double_contraction<dim, Number, OtherNumber>(data[i], sdata);
1878 return result_type(tmp);
1887 template <
int dim,
typename Number,
typename OtherNumber = Number>
1892 typename SymmetricTensorAccessors::
1893 double_contraction_result<2, 4, dim, Number, OtherNumber>::value_type>::
1895 perform_double_contraction(
1897 base_tensor_type &data,
1899 StorageType<4, dim, OtherNumber>::base_tensor_type &sdata)
1901 using value_type =
typename SymmetricTensorAccessors::
1902 double_contraction_result<2, 4, dim, Number, OtherNumber>::value_type;
1903 using base_tensor_type =
typename SymmetricTensorAccessors::
1904 StorageType<2, dim, value_type>::base_tensor_type;
1906 base_tensor_type tmp;
1907 for (
unsigned int i = 0; i < tmp.dimension; ++i)
1914 value_type
sum = data[dim] * sdata[dim][i];
1915 for (
unsigned int d = dim + 1;
d < (dim * (dim + 1) / 2); ++
d)
1916 sum += data[d] * sdata[d][i];
1920 for (
unsigned int d = 0;
d < dim; ++
d)
1921 sum += data[d] * sdata[d][i];
1932 template <
int dim,
typename Number,
typename OtherNumber = Number>
1937 typename SymmetricTensorAccessors::
1938 double_contraction_result<4, 4, dim, Number, OtherNumber>::value_type>::
1940 perform_double_contraction(
1942 base_tensor_type &data,
1944 StorageType<4, dim, OtherNumber>::base_tensor_type &sdata)
1946 using value_type =
typename SymmetricTensorAccessors::
1947 double_contraction_result<4, 4, dim, Number, OtherNumber>::value_type;
1948 using base_tensor_type =
typename SymmetricTensorAccessors::
1949 StorageType<4, dim, value_type>::base_tensor_type;
1951 const unsigned int data_dim = SymmetricTensorAccessors::
1952 StorageType<2, dim, value_type>::n_independent_components;
1953 base_tensor_type tmp;
1954 for (
unsigned int i = 0; i < data_dim; ++i)
1955 for (
unsigned int j = 0; j < data_dim; ++j)
1958 for (
unsigned int d = dim;
d < (dim * (dim + 1) / 2); ++
d)
1959 tmp[i][j] += data[i][d] * sdata[d][j];
1960 tmp[i][j] += tmp[i][j];
1963 for (
unsigned int d = 0;
d < dim; ++
d)
1964 tmp[i][j] += data[i][d] * sdata[d][j];
1973template <
int rank_,
int dim,
typename Number>
1974template <
typename OtherNumber>
1976 typename internal::SymmetricTensorAccessors::
1977 double_contraction_result<rank_, 2, dim, Number, OtherNumber>::type
1983 return internal::perform_double_contraction<dim, Number, OtherNumber>(data,
1989template <
int rank_,
int dim,
typename Number>
1990template <
typename OtherNumber>
1992 typename internal::SymmetricTensorAccessors::
1993 double_contraction_result<rank_, 4, dim, Number, OtherNumber>::type
1997 typename internal::SymmetricTensorAccessors::
1998 double_contraction_result<rank_, 4, dim, Number, OtherNumber>::type tmp;
2000 internal::perform_double_contraction<dim, Number, OtherNumber>(data,
2026 component_to_unrolled_index(
const TableIndices<2> &indices)
2039 constexpr ::ndarray<unsigned int, 2, 2> table = {
2040 {{{0, 2}}, {{2, 1}}}};
2041 return table[indices[0]][indices[1]];
2045 constexpr ::ndarray<unsigned int, 3, 3> table = {
2046 {{{0, 3, 4}}, {{3, 1, 5}}, {{4, 5, 2}}}};
2047 return table[indices[0]][indices[1]];
2051 constexpr ::ndarray<unsigned int, 4, 4> table = {
2056 return table[indices[0]][indices[1]];
2061 if (indices[0] == indices[1])
2064 const TableIndices<2> sorted_indices(
2072 for (
unsigned int d = 0;
d < dim; ++
d)
2073 for (
unsigned int e = d + 1;
e < dim; ++
e, ++c)
2074 if ((sorted_indices[0] == d) && (sorted_indices[1] == e))
2090 template <
int dim,
int rank_>
2091 constexpr inline unsigned int
2092 component_to_unrolled_index(
const TableIndices<rank_> &indices)
2100 template <
int dim,
typename Number>
2102 symmetric_tensor_access(
const TableIndices<2> &indices,
2104 StorageType<2, dim, Number>::base_tensor_type &data)
2112 template <
int dim,
typename Number>
2114 symmetric_tensor_access(
const TableIndices<2> &indices,
2116 StorageType<2, dim, Number>::base_tensor_type &data)
2124 template <
int dim,
typename Number>
2125 constexpr inline Number &
2126 symmetric_tensor_access(
const TableIndices<4> &indices,
2128 StorageType<4, dim, Number>::base_tensor_type &data)
2142 constexpr std::size_t base_index[2][2] = {{0, 2}, {2, 1}};
2143 return data[base_index[indices[0]][indices[1]]]
2144 [base_index[indices[2]][indices[3]]];
2153 constexpr std::size_t base_index[3][3] = {{0, 3, 4},
2156 return data[base_index[indices[0]][indices[1]]]
2157 [base_index[indices[2]][indices[3]]];
2172 template <
int dim,
typename Number>
2174 symmetric_tensor_access(
const TableIndices<4> &indices,
2176 StorageType<4, dim, Number>::base_tensor_type &data)
2190 constexpr std::size_t base_index[2][2] = {{0, 2}, {2, 1}};
2191 return data[base_index[indices[0]][indices[1]]]
2192 [base_index[indices[2]][indices[3]]];
2201 constexpr std::size_t base_index[3][3] = {{0, 3, 4},
2204 return data[base_index[indices[0]][indices[1]]]
2205 [base_index[indices[2]][indices[3]]];
2223template <
int rank_,
int dim,
typename Number>
2228 for (
unsigned int r = 0; r < rank; ++r)
2230 return internal::symmetric_tensor_access<dim, Number>(indices, data);
2235template <
int rank_,
int dim,
typename Number>
2240 for (
unsigned int r = 0; r < rank; ++r)
2242 return internal::symmetric_tensor_access<dim, Number>(indices, data);
2251 template <
int rank_>
2252 constexpr TableIndices<rank_>
2253 get_partially_filled_indices(
const unsigned int row,
2254 const std::integral_constant<int, 2> &)
2260 template <
int rank_>
2261 constexpr TableIndices<rank_>
2262 get_partially_filled_indices(
const unsigned int row,
2263 const std::integral_constant<int, 4> &)
2274template <
int rank_,
int dim,
typename Number>
2276 SymmetricTensorAccessors::Accessor<rank_, dim,
true, rank_ - 1, Number>
2279 return internal::SymmetricTensorAccessors::
2280 Accessor<rank_, dim,
true, rank_ - 1, Number>(
2282 internal::SymmetricTensorImplementation::get_partially_filled_indices<
2283 rank_>(row, std::integral_constant<int, rank_>()));
2288template <
int rank_,
int dim,
typename Number>
2290 SymmetricTensorAccessors::Accessor<rank_, dim,
false, rank_ - 1, Number>
2293 return internal::SymmetricTensorAccessors::
2294 Accessor<rank_, dim,
false, rank_ - 1, Number>(
2296 internal::SymmetricTensorImplementation::get_partially_filled_indices<
2297 rank_>(row, std::integral_constant<int, rank_>()));
2302template <
int rank_,
int dim,
typename Number>
2307 return operator()(indices);
2312template <
int rank_,
int dim,
typename Number>
2317 return operator()(indices);
2322template <
int rank_,
int dim,
typename Number>
2325 const unsigned int index)
const
2328 if constexpr (rank == 2)
2331 return data[
decltype(data)::unrolled_to_component_indices(index)];
2336template <
int rank_,
int dim,
typename Number>
2341 if constexpr (rank == 2)
2344 return data[
decltype(data)::unrolled_to_component_indices(index)];
2351 template <
int dim,
typename Number>
2354 StorageType<2, dim, Number>::base_tensor_type &data)
2381 for (
unsigned int d = 0;
d < dim; ++
d)
2384 for (
unsigned int d = dim;
d < (dim * dim + dim) / 2; ++
d)
2388 return sqrt(return_value);
2395 template <
int dim,
typename Number>
2398 StorageType<4, dim, Number>::base_tensor_type &data)
2412 const unsigned int n_independent_components = data.dimension;
2414 for (
unsigned int i = 0; i < dim; ++i)
2415 for (
unsigned int j = 0; j < dim; ++j)
2418 for (
unsigned int i = 0; i < dim; ++i)
2419 for (
unsigned int j = dim; j < n_independent_components; ++j)
2422 for (
unsigned int i = dim; i < n_independent_components; ++i)
2423 for (
unsigned int j = 0; j < dim; ++j)
2426 for (
unsigned int i = dim; i < n_independent_components; ++i)
2427 for (
unsigned int j = dim; j < n_independent_components; ++j)
2431 return sqrt(return_value);
2440template <
int rank_,
int dim,
typename Number>
2444 return internal::compute_norm<dim, Number>(data);
2449template <
int rank_,
int dim,
typename Number>
2454 return internal::SymmetricTensorImplementation::component_to_unrolled_index<
2473 unrolled_to_component_indices(
const unsigned int i,
2474 const std::integral_constant<int, 2> &)
2512 for (
unsigned int d = 0, c = dim;
d < dim; ++
d)
2513 for (
unsigned int e = d + 1;
e < dim; ++
e, ++c)
2531 template <
int dim,
int rank_>
2532 constexpr inline std::enable_if_t<rank_ != 2, TableIndices<rank_>>
2533 unrolled_to_component_indices(
const unsigned int i,
2534 const std::integral_constant<int, rank_> &)
2542 ::SymmetricTensor<rank_, dim, double>::
2543 n_independent_components));
2551template <
int rank_,
int dim,
typename Number>
2554 const unsigned int i)
2556 return internal::SymmetricTensorImplementation::unrolled_to_component_indices<
2557 dim>(i, std::integral_constant<int, rank_>());
2562template <
int rank_,
int dim,
typename Number>
2563template <
class Archive>
2588template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2613template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2633template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2650template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2667template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2684template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2695template <
int dim,
typename Number>
2711 return (tmp + tmp + t.
data[0] * t.
data[1] * t.
data[2] -