16 #ifndef dealii_symmetric_tensor_h 17 #define dealii_symmetric_tensor_h 20 #include <deal.II/base/numbers.h> 21 #include <deal.II/base/table_indices.h> 22 #include <deal.II/base/template_constraints.h> 23 #include <deal.II/base/tensor.h> 29 DEAL_II_NAMESPACE_OPEN
31 template <
int rank,
int dim,
typename Number =
double>
34 template <
int dim,
typename Number>
38 template <
int dim,
typename Number>
42 template <
int dim,
typename Number>
46 template <
int dim,
typename Number>
50 template <
int dim,
typename Number>
54 template <
int dim2,
typename Number>
58 template <
int dim,
typename Number>
62 template <
int dim,
typename Number>
74 namespace SymmetricTensorImplementation
80 template <
int rank,
int dim,
typename Number>
88 namespace SymmetricTensorAccessors
98 const unsigned int new_index,
99 const unsigned int position)
106 return {previous_indices[0], new_index};
119 const unsigned int new_index,
120 const unsigned int position)
132 return {previous_indices[0],
137 return {previous_indices[0],
142 return {previous_indices[0],
164 typename OtherNumber = Number>
167 using value_type =
typename ProductType<Number, OtherNumber>::type;
181 template <
int dim,
typename Number,
typename OtherNumber>
184 using type =
typename ProductType<Number, OtherNumber>::type;
201 template <
int rank,
int dim,
typename Number>
207 template <
int dim,
typename Number>
214 static const unsigned int n_independent_components =
215 (dim * dim + dim) / 2;
228 template <
int dim,
typename Number>
236 static const unsigned int n_rank2_components = (dim * dim + dim) / 2;
241 static const unsigned int n_independent_components =
242 (n_rank2_components *
260 template <
int rank,
int dim,
bool constness,
typename Number>
269 template <
int rank,
int dim,
typename Number>
272 using tensor_type = const ::SymmetricTensor<rank, dim, Number>;
274 using reference = Number;
283 template <
int rank,
int dim,
typename Number>
288 using reference = Number &;
326 template <
int rank,
int dim,
bool constness,
int P,
typename Number>
362 Accessor(
const Accessor &) =
default;
368 Accessor<rank, dim, constness, P - 1, Number>
369 operator[](
const unsigned int i);
374 Accessor<rank, dim, constness, P - 1, Number>
375 operator[](
const unsigned int i)
const;
381 tensor_type & tensor;
388 template <
int,
int,
typename>
389 friend class ::SymmetricTensor;
390 template <
int,
int,
bool,
int,
typename>
391 friend class Accessor;
392 #ifndef DEAL_II_TEMPL_SPEC_FRIEND_BUG 393 friend class ::SymmetricTensor<rank, dim, Number>;
394 friend class Accessor<rank, dim, constness, P + 1, Number>;
409 template <
int rank,
int dim,
bool constness,
typename Number>
410 class Accessor<rank, dim, constness, 1, Number>
417 typename AccessorTypes<rank, dim, constness, Number>::reference;
419 typename AccessorTypes<rank, dim, constness, Number>::tensor_type;
448 Accessor(
const Accessor &) =
default;
454 reference operator[](
const unsigned int);
459 reference operator[](
const unsigned int)
const;
465 tensor_type & tensor;
472 template <
int,
int,
typename>
473 friend class ::SymmetricTensor;
474 template <
int,
int,
bool,
int,
typename>
475 friend class SymmetricTensorAccessors::Accessor;
476 #ifndef DEAL_II_TEMPL_SPEC_FRIEND_BUG 477 friend class ::SymmetricTensor<rank, dim, Number>;
478 friend class SymmetricTensorAccessors::
479 Accessor<rank, dim, constness, 2, Number>;
550 template <int rank_, int dim, typename Number>
554 static_assert(rank_ % 2 == 0,
"A SymmetricTensor must have even rank!");
564 static const unsigned int dimension = dim;
569 static const unsigned int rank = rank_;
576 static constexpr
unsigned int n_independent_components =
578 n_independent_components;
595 template <
typename OtherNumber>
620 template <
typename OtherNumber>
655 template <
typename OtherNumber>
666 operator=(
const Number &d);
689 template <
typename OtherNumber>
696 template <
typename OtherNumber>
704 template <
typename OtherNumber>
706 operator*=(
const OtherNumber &factor);
711 template <
typename OtherNumber>
713 operator/=(
const OtherNumber &factor);
745 template <
typename OtherNumber>
746 typename internal::SymmetricTensorAccessors::
747 double_contraction_result<rank_, 2, dim, Number, OtherNumber>::type
754 template <
typename OtherNumber>
755 typename internal::SymmetricTensorAccessors::
756 double_contraction_result<rank_, 4, dim, Number, OtherNumber>::type
775 internal::SymmetricTensorAccessors::
776 Accessor<rank_, dim,
true, rank_ - 1, Number>
777 operator[](
const unsigned int row)
const;
783 internal::SymmetricTensorAccessors::
784 Accessor<rank_, dim,
false, rank_ - 1, Number>
785 operator[](
const unsigned int row);
807 access_raw_entry(
const unsigned int unrolled_index)
const;
815 access_raw_entry(
const unsigned int unrolled_index);
845 unrolled_to_component_indices(
const unsigned int i);
867 memory_consumption();
873 template <
class Archive>
875 serialize(Archive &ar,
const unsigned int version);
897 template <
int,
int,
typename>
903 template <
int dim2,
typename Number2>
907 template <
int dim2,
typename Number2>
911 template <
int dim2,
typename Number2>
915 template <
int dim2,
typename Number2>
919 template <
int dim2,
typename Number2>
923 template <
int dim2,
typename Number2>
932 Inverse<2, dim, Number>;
935 Inverse<4, dim, Number>;
945 template <int rank, int dim, typename Number>
948 template <int rank_, int dim, typename Number>
949 constexpr unsigned int
954 namespace SymmetricTensorAccessors
956 template <
int rank_,
int dim,
bool constness,
int P,
typename Number>
957 Accessor<rank_, dim, constness, P, Number>::Accessor(
958 tensor_type & tensor,
961 , previous_indices(previous_indices)
966 template <
int rank_,
int dim,
bool constness,
int P,
typename Number>
967 Accessor<rank_, dim, constness, P - 1, Number>
968 Accessor<rank_, dim, constness, P, Number>::
969 operator[](
const unsigned int i)
971 return Accessor<rank_, dim, constness, P - 1, Number>(
972 tensor,
merge(previous_indices, i, rank_ - P));
977 template <
int rank_,
int dim,
bool constness,
int P,
typename Number>
978 Accessor<rank_, dim, constness, P - 1, Number>
979 Accessor<rank_, dim, constness, P, Number>::
980 operator[](
const unsigned int i)
const 982 return Accessor<rank_, dim, constness, P - 1, Number>(
983 tensor,
merge(previous_indices, i, rank_ - P));
988 template <
int rank_,
int dim,
bool constness,
typename Number>
989 Accessor<rank_, dim, constness, 1, Number>::Accessor(
990 tensor_type & tensor,
993 , previous_indices(previous_indices)
998 template <
int rank_,
int dim,
bool constness,
typename Number>
999 typename Accessor<rank_, dim, constness, 1, Number>::reference
1000 Accessor<rank_, dim, constness, 1, Number>::
1001 operator[](
const unsigned int i)
1003 return tensor(
merge(previous_indices, i, rank_ - 1));
1007 template <
int rank_,
int dim,
bool constness,
typename Number>
1008 typename Accessor<rank_, dim, constness, 1, Number>::reference
1009 Accessor<rank_, dim, constness, 1, Number>::
1010 operator[](
const unsigned int i)
const 1012 return tensor(
merge(previous_indices, i, rank_ - 1));
1019 template <
int rank_,
int dim,
typename Number>
1024 for (
unsigned int i = 0; i < base_tensor_type::dimension; ++i)
1029 template <
int rank_,
int dim,
typename Number>
1030 template <
typename OtherNumber>
1059 for (
unsigned int d = 0;
d < dim; ++
d)
1060 for (
unsigned int e = 0;
e <
d; ++
e)
1063 for (
unsigned int d = 0;
d < dim; ++
d)
1066 for (
unsigned int d = 0, c = 0;
d < dim; ++
d)
1067 for (
unsigned int e = d + 1;
e < dim; ++
e, ++c)
1068 data[dim + c] = t[d][e];
1074 template <
int rank_,
int dim,
typename Number>
1075 template <
typename OtherNumber>
1079 for (
unsigned int i = 0; i < base_tensor_type::dimension; ++i)
1082 initializer.
data[i]);
1087 template <
int rank_,
int dim,
typename Number>
1089 const Number (&array)[n_independent_components])
1091 *reinterpret_cast<const typename base_tensor_type::array_type *>(array))
1094 Assert(
sizeof(
typename base_tensor_type::array_type) ==
sizeof(array),
1100 template <
int rank_,
int dim,
typename Number>
1101 template <
typename OtherNumber>
1106 for (
unsigned int i = 0; i < base_tensor_type::dimension; ++i)
1107 data[i] = t.
data[i];
1113 template <
int rank_,
int dim,
typename Number>
1118 ExcMessage(
"Only assignment with zero is allowed"));
1129 namespace SymmetricTensorImplementation
1131 template <
int dim,
typename Number>
1132 inline DEAL_II_ALWAYS_INLINE ::Tensor<2, dim, Number>
1133 convert_to_tensor(const ::SymmetricTensor<2, dim, Number> &s)
1138 for (
unsigned int d = 0;
d < dim; ++
d)
1142 for (
unsigned int d = 0, c = 0;
d < dim; ++
d)
1143 for (
unsigned int e = d + 1;
e < dim; ++
e, ++c)
1145 t[
d][
e] = s.access_raw_entry(dim + c);
1146 t[
e][
d] = s.access_raw_entry(dim + c);
1152 template <
int dim,
typename Number>
1154 convert_to_tensor(const ::SymmetricTensor<4, dim, Number> &st)
1161 for (
unsigned int i = 0; i < dim; ++i)
1162 for (
unsigned int j = i; j < dim; ++j)
1163 for (
unsigned int k = 0; k < dim; ++k)
1164 for (
unsigned int l = k;
l < dim; ++
l)
1174 template <
typename Number>
1175 struct Inverse<2, 1, Number>
1177 static inline ::SymmetricTensor<2, 1, Number>
1178 value(const ::SymmetricTensor<2, 1, Number> &t)
1182 tmp[0][0] = 1.0 / t[0][0];
1189 template <
typename Number>
1190 struct Inverse<2, 2, Number>
1192 static inline ::SymmetricTensor<2, 2, Number>
1193 value(const ::SymmetricTensor<2, 2, Number> &t)
1203 const Number inv_det_t =
1204 1.0 / (t[idx_00] * t[idx_11] - t[idx_01] * t[idx_01]);
1205 tmp[idx_00] = t[idx_11];
1206 tmp[idx_01] = -t[idx_01];
1207 tmp[idx_11] = t[idx_00];
1215 template <
typename Number>
1216 struct Inverse<2, 3, Number>
1218 static ::SymmetricTensor<2, 3, Number>
1219 value(const ::SymmetricTensor<2, 3, Number> &t)
1263 const Number inv_det_t =
1264 1.0 / (t[idx_00] * t[idx_11] * t[idx_22] -
1265 t[idx_00] * t[idx_12] * t[idx_12] -
1266 t[idx_01] * t[idx_01] * t[idx_22] +
1267 2.0 * t[idx_01] * t[idx_02] * t[idx_12] -
1268 t[idx_02] * t[idx_02] * t[idx_11]);
1269 tmp[idx_00] = t[idx_11] * t[idx_22] - t[idx_12] * t[idx_12];
1270 tmp[idx_01] = -t[idx_01] * t[idx_22] + t[idx_02] * t[idx_12];
1271 tmp[idx_02] = t[idx_01] * t[idx_12] - t[idx_02] * t[idx_11];
1272 tmp[idx_11] = t[idx_00] * t[idx_22] - t[idx_02] * t[idx_02];
1273 tmp[idx_12] = -t[idx_00] * t[idx_12] + t[idx_01] * t[idx_02];
1274 tmp[idx_22] = t[idx_00] * t[idx_11] - t[idx_01] * t[idx_01];
1282 template <
typename Number>
1283 struct Inverse<4, 1, Number>
1285 static inline ::SymmetricTensor<4, 1, Number>
1286 value(const ::SymmetricTensor<4, 1, Number> &t)
1289 tmp.
data[0][0] = 1.0 / t.data[0][0];
1295 template <
typename Number>
1296 struct Inverse<4, 2, Number>
1298 static inline ::SymmetricTensor<4, 2, Number>
1299 value(const ::SymmetricTensor<4, 2, Number> &t)
1325 const Number t4 = t.
data[0][0] * t.data[1][1],
1326 t6 = t.data[0][0] * t.data[1][2],
1327 t8 = t.data[0][1] * t.data[1][0],
1328 t00 = t.data[0][2] * t.data[1][0],
1329 t01 = t.data[0][1] * t.data[2][0],
1330 t04 = t.data[0][2] * t.data[2][0],
1331 t07 = 1.0 / (t4 * t.data[2][2] - t6 * t.data[2][1] -
1332 t8 * t.data[2][2] + t00 * t.data[2][1] +
1333 t01 * t.data[1][2] - t04 * t.data[1][1]);
1335 (t.data[1][1] * t.data[2][2] - t.data[1][2] * t.data[2][1]) * t07;
1337 -(t.data[0][1] * t.data[2][2] - t.data[0][2] * t.data[2][1]) * t07;
1339 -(-t.data[0][1] * t.data[1][2] + t.data[0][2] * t.data[1][1]) * t07;
1341 -(t.data[1][0] * t.data[2][2] - t.data[1][2] * t.data[2][0]) * t07;
1342 tmp.
data[1][1] = (t.data[0][0] * t.data[2][2] - t04) * t07;
1343 tmp.
data[1][2] = -(t6 - t00) * t07;
1345 -(-t.data[1][0] * t.data[2][1] + t.data[1][1] * t.data[2][0]) * t07;
1346 tmp.
data[2][1] = -(t.data[0][0] * t.data[2][1] - t01) * t07;
1347 tmp.
data[2][2] = (t4 - t8) * t07;
1351 tmp.
data[2][0] /= 2;
1352 tmp.
data[2][1] /= 2;
1353 tmp.
data[0][2] /= 2;
1354 tmp.
data[1][2] /= 2;
1355 tmp.
data[2][2] /= 4;
1362 template <
typename Number>
1363 struct Inverse<4, 3, Number>
1365 static ::SymmetricTensor<4, 3, Number>
1366 value(const ::SymmetricTensor<4, 3, Number> &t)
1376 const unsigned int N = 6;
1382 for (
unsigned int i = 0; i < N; ++i)
1383 diagonal_sum += std::fabs(tmp.
data[i][i]);
1384 const Number typical_diagonal_element =
1385 diagonal_sum /
static_cast<double>(N);
1386 (void)typical_diagonal_element;
1389 for (
unsigned int i = 0; i < N; ++i)
1392 for (
unsigned int j = 0; j < N; ++j)
1396 Number
max = std::fabs(tmp.
data[j][j]);
1398 for (
unsigned int i = j + 1; i < N; ++i)
1399 if (std::fabs(tmp.
data[i][j]) > max)
1401 max = std::fabs(tmp.
data[i][j]);
1406 Assert(max > 1.e-16 * typical_diagonal_element,
1407 ExcMessage(
"This tensor seems to be noninvertible"));
1412 for (
unsigned int k = 0; k < N; ++k)
1419 const Number hr = 1. / tmp.
data[j][j];
1420 tmp.
data[j][j] = hr;
1421 for (
unsigned int k = 0; k < N; ++k)
1425 for (
unsigned int i = 0; i < N; ++i)
1429 tmp.
data[i][k] -= tmp.
data[i][j] * tmp.
data[j][k] * hr;
1432 for (
unsigned int i = 0; i < N; ++i)
1434 tmp.
data[i][j] *= hr;
1435 tmp.
data[j][i] *= -hr;
1437 tmp.
data[j][j] = hr;
1442 for (
unsigned int i = 0; i < N; ++i)
1444 for (
unsigned int k = 0; k < N; ++k)
1445 hv[p[k]] = tmp.
data[i][k];
1446 for (
unsigned int k = 0; k < N; ++k)
1447 tmp.
data[i][k] = hv[k];
1452 for (
unsigned int i = 3; i < 6; ++i)
1453 for (
unsigned int j = 0; j < 3; ++j)
1454 tmp.
data[i][j] /= 2;
1456 for (
unsigned int i = 0; i < 3; ++i)
1457 for (
unsigned int j = 3; j < 6; ++j)
1458 tmp.
data[i][j] /= 2;
1460 for (
unsigned int i = 3; i < 6; ++i)
1461 for (
unsigned int j = 3; j < 6; ++j)
1462 tmp.
data[i][j] /= 4;
1473 template <
int rank_,
int dim,
typename Number>
1477 return internal::SymmetricTensorImplementation::convert_to_tensor(*
this);
1482 template <
int rank_,
int dim,
typename Number>
1487 return data == t.
data;
1492 template <
int rank_,
int dim,
typename Number>
1497 return data != t.
data;
1502 template <
int rank_,
int dim,
typename Number>
1503 template <
typename OtherNumber>
1514 template <
int rank_,
int dim,
typename Number>
1515 template <
typename OtherNumber>
1526 template <
int rank_,
int dim,
typename Number>
1527 template <
typename OtherNumber>
1537 template <
int rank_,
int dim,
typename Number>
1538 template <
typename OtherNumber>
1548 template <
int rank_,
int dim,
typename Number>
1559 template <
int rank_,
int dim,
typename Number>
1560 inline DEAL_II_ALWAYS_INLINE
void 1568 template <
int rank_,
int dim,
typename Number>
1581 template <
int dim,
typename Number,
typename OtherNumber = Number>
1582 inline DEAL_II_ALWAYS_INLINE
typename SymmetricTensorAccessors::
1583 double_contraction_result<2, 2, dim, Number, OtherNumber>::type
1584 perform_double_contraction(
1585 const typename SymmetricTensorAccessors::StorageType<2, dim, Number>::
1586 base_tensor_type &data,
1587 const typename SymmetricTensorAccessors::
1588 StorageType<2, dim, OtherNumber>::base_tensor_type &sdata)
1590 using result_type =
typename SymmetricTensorAccessors::
1591 double_contraction_result<2, 2, dim, Number, OtherNumber>::type;
1596 return data[0] * sdata[0];
1601 result_type
sum = data[dim] * sdata[dim];
1602 for (
unsigned int d = dim + 1;
d < (dim * (dim + 1) / 2); ++
d)
1603 sum += data[d] * sdata[d];
1607 for (
unsigned int d = 0;
d < dim; ++
d)
1608 sum += data[d] * sdata[d];
1615 template <
int dim,
typename Number,
typename OtherNumber = Number>
1616 inline typename SymmetricTensorAccessors::
1617 double_contraction_result<4, 2, dim, Number, OtherNumber>::type
1618 perform_double_contraction(
1619 const typename SymmetricTensorAccessors::StorageType<4, dim, Number>::
1620 base_tensor_type &data,
1621 const typename SymmetricTensorAccessors::
1622 StorageType<2, dim, OtherNumber>::base_tensor_type &sdata)
1624 using result_type =
typename SymmetricTensorAccessors::
1625 double_contraction_result<4, 2, dim, Number, OtherNumber>::type;
1626 using value_type =
typename SymmetricTensorAccessors::
1627 double_contraction_result<4, 2, dim, Number, OtherNumber>::value_type;
1629 const unsigned int data_dim = SymmetricTensorAccessors::
1630 StorageType<2, dim, value_type>::n_independent_components;
1631 value_type tmp[data_dim];
1632 for (
unsigned int i = 0; i < data_dim; ++i)
1634 perform_double_contraction<dim, Number, OtherNumber>(data[i], sdata);
1635 return result_type(tmp);
1640 template <
int dim,
typename Number,
typename OtherNumber = Number>
1641 inline typename SymmetricTensorAccessors::StorageType<
1644 typename SymmetricTensorAccessors::
1645 double_contraction_result<2, 4, dim, Number, OtherNumber>::value_type>::
1647 perform_double_contraction(
1648 const typename SymmetricTensorAccessors::StorageType<2, dim, Number>::
1649 base_tensor_type &data,
1650 const typename SymmetricTensorAccessors::
1651 StorageType<4, dim, OtherNumber>::base_tensor_type &sdata)
1653 using value_type =
typename SymmetricTensorAccessors::
1654 double_contraction_result<2, 4, dim, Number, OtherNumber>::value_type;
1655 using base_tensor_type =
typename SymmetricTensorAccessors::
1656 StorageType<2, dim, value_type>::base_tensor_type;
1658 base_tensor_type tmp;
1659 for (
unsigned int i = 0; i < tmp.dimension; ++i)
1662 value_type
sum = data[dim] * sdata[dim][i];
1663 for (
unsigned int d = dim + 1;
d < (dim * (dim + 1) / 2); ++
d)
1664 sum += data[d] * sdata[d][i];
1668 for (
unsigned int d = 0;
d < dim; ++
d)
1669 sum += data[d] * sdata[d][i];
1677 template <
int dim,
typename Number,
typename OtherNumber = Number>
1678 inline typename SymmetricTensorAccessors::StorageType<
1681 typename SymmetricTensorAccessors::
1682 double_contraction_result<4, 4, dim, Number, OtherNumber>::value_type>::
1684 perform_double_contraction(
1685 const typename SymmetricTensorAccessors::StorageType<4, dim, Number>::
1686 base_tensor_type &data,
1687 const typename SymmetricTensorAccessors::
1688 StorageType<4, dim, OtherNumber>::base_tensor_type &sdata)
1690 using value_type =
typename SymmetricTensorAccessors::
1691 double_contraction_result<4, 4, dim, Number, OtherNumber>::value_type;
1692 using base_tensor_type =
typename SymmetricTensorAccessors::
1693 StorageType<4, dim, value_type>::base_tensor_type;
1695 const unsigned int data_dim = SymmetricTensorAccessors::
1696 StorageType<2, dim, value_type>::n_independent_components;
1697 base_tensor_type tmp;
1698 for (
unsigned int i = 0; i < data_dim; ++i)
1699 for (
unsigned int j = 0; j < data_dim; ++j)
1702 for (
unsigned int d = dim;
d < (dim * (dim + 1) / 2); ++
d)
1703 tmp[i][j] += data[i][d] * sdata[d][j];
1704 tmp[i][j] += tmp[i][j];
1707 for (
unsigned int d = 0;
d < dim; ++
d)
1708 tmp[i][j] += data[i][d] * sdata[d][j];
1717 template <
int rank_,
int dim,
typename Number>
1718 template <
typename OtherNumber>
1719 inline DEAL_II_ALWAYS_INLINE
typename internal::SymmetricTensorAccessors::
1720 double_contraction_result<rank_, 2, dim, Number, OtherNumber>::type
1728 return internal::perform_double_contraction<dim, Number, OtherNumber>(data,
1734 template <
int rank_,
int dim,
typename Number>
1735 template <
typename OtherNumber>
1736 inline typename internal::SymmetricTensorAccessors::
1737 double_contraction_result<rank_, 4, dim, Number, OtherNumber>::type
1741 typename internal::SymmetricTensorAccessors::
1742 double_contraction_result<rank_, 4, dim, Number, OtherNumber>::type tmp;
1744 internal::perform_double_contraction<dim, Number, OtherNumber>(data,
1761 template <
int dim,
typename Number>
1764 typename SymmetricTensorAccessors::
1765 StorageType<2, dim, Number>::base_tensor_type &data)
1773 if (indices[0] == indices[1])
1774 return data[indices[0]];
1781 Assert(((indices[0] == 1) && (indices[1] == 0)) ||
1782 ((indices[0] == 0) && (indices[1] == 1)),
1790 sorted_indices.sort();
1792 for (
unsigned int d = 0, c = 0;
d < dim; ++
d)
1793 for (
unsigned int e = d + 1;
e < dim; ++
e, ++c)
1794 if ((sorted_indices[0] == d) && (sorted_indices[1] == e))
1795 return data[dim + c];
1800 static Number dummy_but_referenceable = Number();
1801 return dummy_but_referenceable;
1806 template <
int dim,
typename Number>
1807 inline const Number &
1809 const typename SymmetricTensorAccessors::
1810 StorageType<2, dim, Number>::base_tensor_type &data)
1818 if (indices[0] == indices[1])
1819 return data[indices[0]];
1826 Assert(((indices[0] == 1) && (indices[1] == 0)) ||
1827 ((indices[0] == 0) && (indices[1] == 1)),
1835 sorted_indices.sort();
1837 for (
unsigned int d = 0, c = 0;
d < dim; ++
d)
1838 for (
unsigned int e = d + 1;
e < dim; ++
e, ++c)
1839 if ((sorted_indices[0] == d) && (sorted_indices[1] == e))
1840 return data[dim + c];
1845 static Number dummy_but_referenceable = Number();
1846 return dummy_but_referenceable;
1851 template <
int dim,
typename Number>
1854 typename SymmetricTensorAccessors::
1855 StorageType<4, dim, Number>::base_tensor_type &data)
1873 unsigned int base_index[2];
1874 if ((indices[0] == 0) && (indices[1] == 0))
1876 else if ((indices[0] == 1) && (indices[1] == 1))
1881 if ((indices[2] == 0) && (indices[3] == 0))
1883 else if ((indices[2] == 1) && (indices[3] == 1))
1888 return data[base_index[0]][base_index[1]];
1902 unsigned int base_index[2];
1903 if ((indices[0] == 0) && (indices[1] == 0))
1905 else if ((indices[0] == 1) && (indices[1] == 1))
1907 else if ((indices[0] == 2) && (indices[1] == 2))
1909 else if (((indices[0] == 0) && (indices[1] == 1)) ||
1910 ((indices[0] == 1) && (indices[1] == 0)))
1912 else if (((indices[0] == 0) && (indices[1] == 2)) ||
1913 ((indices[0] == 2) && (indices[1] == 0)))
1917 Assert(((indices[0] == 1) && (indices[1] == 2)) ||
1918 ((indices[0] == 2) && (indices[1] == 1)),
1923 if ((indices[2] == 0) && (indices[3] == 0))
1925 else if ((indices[2] == 1) && (indices[3] == 1))
1927 else if ((indices[2] == 2) && (indices[3] == 2))
1929 else if (((indices[2] == 0) && (indices[3] == 1)) ||
1930 ((indices[2] == 1) && (indices[3] == 0)))
1932 else if (((indices[2] == 0) && (indices[3] == 2)) ||
1933 ((indices[2] == 2) && (indices[3] == 0)))
1937 Assert(((indices[2] == 1) && (indices[3] == 2)) ||
1938 ((indices[2] == 2) && (indices[3] == 1)),
1943 return data[base_index[0]][base_index[1]];
1950 static Number dummy;
1955 template <
int dim,
typename Number>
1956 inline const Number &
1958 const typename SymmetricTensorAccessors::
1959 StorageType<4, dim, Number>::base_tensor_type &data)
1977 unsigned int base_index[2];
1978 if ((indices[0] == 0) && (indices[1] == 0))
1980 else if ((indices[0] == 1) && (indices[1] == 1))
1985 if ((indices[2] == 0) && (indices[3] == 0))
1987 else if ((indices[2] == 1) && (indices[3] == 1))
1992 return data[base_index[0]][base_index[1]];
2006 unsigned int base_index[2];
2007 if ((indices[0] == 0) && (indices[1] == 0))
2009 else if ((indices[0] == 1) && (indices[1] == 1))
2011 else if ((indices[0] == 2) && (indices[1] == 2))
2013 else if (((indices[0] == 0) && (indices[1] == 1)) ||
2014 ((indices[0] == 1) && (indices[1] == 0)))
2016 else if (((indices[0] == 0) && (indices[1] == 2)) ||
2017 ((indices[0] == 2) && (indices[1] == 0)))
2021 Assert(((indices[0] == 1) && (indices[1] == 2)) ||
2022 ((indices[0] == 2) && (indices[1] == 1)),
2027 if ((indices[2] == 0) && (indices[3] == 0))
2029 else if ((indices[2] == 1) && (indices[3] == 1))
2031 else if ((indices[2] == 2) && (indices[3] == 2))
2033 else if (((indices[2] == 0) && (indices[3] == 1)) ||
2034 ((indices[2] == 1) && (indices[3] == 0)))
2036 else if (((indices[2] == 0) && (indices[3] == 2)) ||
2037 ((indices[2] == 2) && (indices[3] == 0)))
2041 Assert(((indices[2] == 1) && (indices[3] == 2)) ||
2042 ((indices[2] == 2) && (indices[3] == 1)),
2047 return data[base_index[0]][base_index[1]];
2054 static Number dummy;
2062 template <
int rank_,
int dim,
typename Number>
2067 for (
unsigned int r = 0; r < rank; ++r)
2069 return internal::symmetric_tensor_access<dim, Number>(indices, data);
2074 template <
int rank_,
int dim,
typename Number>
2075 inline const Number &
2079 for (
unsigned int r = 0; r < rank; ++r)
2081 return internal::symmetric_tensor_access<dim, Number>(indices, data);
2088 namespace SymmetricTensorImplementation
2090 template <
int rank_>
2092 get_partially_filled_indices(
const unsigned int row,
2093 const std::integral_constant<int, 2> &)
2099 template <
int rank_>
2101 get_partially_filled_indices(
const unsigned int row,
2102 const std::integral_constant<int, 4> &)
2113 template <
int rank_,
int dim,
typename Number>
2114 internal::SymmetricTensorAccessors::
2115 Accessor<rank_, dim,
true, rank_ - 1, Number>
2119 return internal::SymmetricTensorAccessors::
2120 Accessor<rank_, dim,
true, rank_ - 1, Number>(
2122 internal::SymmetricTensorImplementation::get_partially_filled_indices<
2123 rank_>(row, std::integral_constant<int, rank_>()));
2128 template <
int rank_,
int dim,
typename Number>
2129 internal::SymmetricTensorAccessors::
2130 Accessor<rank_, dim,
false, rank_ - 1, Number>
2133 return internal::SymmetricTensorAccessors::
2134 Accessor<rank_, dim,
false, rank_ - 1, Number>(
2136 internal::SymmetricTensorImplementation::get_partially_filled_indices<
2137 rank_>(row, std::integral_constant<int, rank_>()));
2142 template <
int rank_,
int dim,
typename Number>
2146 return operator()(indices);
2151 template <
int rank_,
int dim,
typename Number>
2155 return operator()(indices);
2160 template <
int rank_,
int dim,
typename Number>
2164 return std::addressof(this->access_raw_entry(0));
2169 template <
int rank_,
int dim,
typename Number>
2170 inline const Number *
2173 return std::addressof(this->access_raw_entry(0));
2178 template <
int rank_,
int dim,
typename Number>
2182 return begin_raw() + n_independent_components;
2187 template <
int rank_,
int dim,
typename Number>
2188 inline const Number *
2191 return begin_raw() + n_independent_components;
2198 namespace SymmetricTensorImplementation
2200 template <
int dim,
typename Number>
2202 entry_to_indices(const ::SymmetricTensor<2, dim, Number> &,
2203 const unsigned int index)
2209 template <
int dim,
typename Number>
2211 entry_to_indices(const ::SymmetricTensor<4, dim, Number> &,
2212 const unsigned int index)
2223 template <
int rank_,
int dim,
typename Number>
2224 inline const Number &
2226 const unsigned int index)
const 2229 return data[internal::SymmetricTensorImplementation::entry_to_indices(*
this,
2235 template <
int rank_,
int dim,
typename Number>
2240 return data[internal::SymmetricTensorImplementation::entry_to_indices(*
this,
2248 template <
int dim,
typename Number>
2250 compute_norm(
const typename SymmetricTensorAccessors::
2251 StorageType<2, dim, Number>::base_tensor_type &data)
2278 for (
unsigned int d = 0;
d < dim; ++
d)
2281 for (
unsigned int d = dim;
d < (dim * dim + dim) / 2; ++
d)
2285 return std::sqrt(return_value);
2292 template <
int dim,
typename Number>
2294 compute_norm(
const typename SymmetricTensorAccessors::
2295 StorageType<4, dim, Number>::base_tensor_type &data)
2307 const unsigned int n_independent_components = data.dimension;
2309 for (
unsigned int i = 0; i < dim; ++i)
2310 for (
unsigned int j = 0; j < dim; ++j)
2313 for (
unsigned int i = 0; i < dim; ++i)
2314 for (
unsigned int j = dim; j < n_independent_components; ++j)
2317 for (
unsigned int i = dim; i < n_independent_components; ++i)
2318 for (
unsigned int j = 0; j < dim; ++j)
2321 for (
unsigned int i = dim; i < n_independent_components; ++i)
2322 for (
unsigned int j = dim; j < n_independent_components; ++j)
2326 return std::sqrt(return_value);
2335 template <
int rank_,
int dim,
typename Number>
2339 return internal::compute_norm<dim, Number>(data);
2346 namespace SymmetricTensorImplementation
2369 static const unsigned int table[2][2] = {{0, 2}, {2, 1}};
2370 return table[indices[0]][indices[1]];
2375 static const unsigned int table[3][3] = {{0, 3, 4},
2378 return table[indices[0]][indices[1]];
2383 static const unsigned int table[4][4] = {{0, 4, 5, 6},
2387 return table[indices[0]][indices[1]];
2393 if (indices[0] == indices[1])
2397 sorted_indices.sort();
2399 for (
unsigned int d = 0, c = 0;
d < dim; ++
d)
2400 for (
unsigned int e = d + 1;
e < dim; ++
e, ++c)
2401 if ((sorted_indices[0] == d) && (sorted_indices[1] == e))
2417 template <
int dim,
int rank_>
2429 template <
int rank_,
int dim,
typename Number>
2434 return internal::SymmetricTensorImplementation::component_to_unrolled_index<
2442 namespace SymmetricTensorImplementation
2454 const std::integral_constant<int, 2> &)
2492 for (
unsigned int d = 0, c = 0;
d < dim; ++
d)
2493 for (
unsigned int e = d + 1;
e < dim; ++
e, ++c)
2511 template <
int dim,
int rank_>
2514 const std::integral_constant<int, rank_> &)
2523 n_independent_components));
2531 template <
int rank_,
int dim,
typename Number>
2534 const unsigned int i)
2536 return internal::SymmetricTensorImplementation::unrolled_to_component_indices<
2537 dim>(i, std::integral_constant<int, rank_>());
2542 template <
int rank_,
int dim,
typename Number>
2543 template <
class Archive>
2568 template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2571 typename ProductType<Number, OtherNumber>::type>
2594 template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2597 typename ProductType<Number, OtherNumber>::type>
2615 template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2631 template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2647 template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2663 template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
2686 template <
int dim,
typename Number>
2702 return (tmp + tmp + t.
data[0] * t.
data[1] * t.
data[2] -
2724 template <
int dim,
typename Number>
2740 template <
int dim,
typename Number>
2744 Number t = d.data[0];
2745 for (
unsigned int i = 1; i < dim; ++i)
2760 template <
int dim,
typename Number>
2780 template <
typename Number>
2808 template <
typename Number>
2812 return t[0][0] * t[1][1] - t[0][1] * t[0][1];
2826 template <
typename Number>
2830 return (t[0][0] * t[1][1] + t[1][1] * t[2][2] + t[2][2] * t[0][0] -
2831 t[0][1] * t[0][1] - t[0][2] * t[0][2] - t[1][2] * t[1][2]);
2844 template <
typename Number>
2845 std::array<Number, 1>
2873 template <
typename Number>
2874 std::array<Number, 2>
2901 template <
typename Number>
2902 std::array<Number, 3>
2909 namespace SymmetricTensorImplementation
2950 template <
int dim,
typename Number>
2954 std::array<Number, dim> & d,
2955 std::array<Number, dim - 1> & e);
3000 template <
int dim,
typename Number>
3001 std::array<std::pair<Number, Tensor<1, dim, Number>>, dim>
3047 template <
int dim,
typename Number>
3048 std::array<std::pair<Number, Tensor<1, dim, Number>>, dim>
3068 template <
typename Number>
3069 std::array<std::pair<Number, Tensor<1, 2, Number>>, 2>
3070 hybrid(const ::SymmetricTensor<2, 2, Number> &A);
3108 template <
typename Number>
3109 std::array<std::pair<Number, Tensor<1, 3, Number>>, 3>
3110 hybrid(const ::SymmetricTensor<2, 3, Number> &A);
3116 template <
int dim,
typename Number>
3119 using EigValsVecs = std::pair<Number, Tensor<1, dim, Number>>;
3121 operator()(
const EigValsVecs &lhs,
const EigValsVecs &rhs)
3123 return lhs.first > rhs.first;
3227 template <
int dim,
typename Number>
3228 std::array<std::pair<Number, Tensor<1, dim, Number>>,
3229 std::integral_constant<int, dim>::value>
3245 template <
int rank_,
int dim,
typename Number>
3263 template <
int dim,
typename Number>
3270 const Number tr =
trace(t) / dim;
3271 for (
unsigned int i = 0; i < dim; ++i)
3286 template <
int dim,
typename Number>
3305 for (
unsigned int d = 0; d < dim; ++d)
3325 return unit_symmetric_tensor<dim, double>();
3344 template <
int dim,
typename Number>
3351 for (
unsigned int i = 0; i < dim; ++i)
3352 for (
unsigned int j = 0; j < dim; ++j)
3353 tmp.
data[i][j] = (i == j ? 1 : 0) - 1. / dim;
3360 for (
unsigned int i = dim;
3361 i < internal::SymmetricTensorAccessors::StorageType<4, dim, Number>::
3364 tmp.
data[i][i] = 0.5;
3389 return deviator_tensor<dim, double>();
3416 template <
int dim,
typename Number>
3423 for (
unsigned int i = 0; i < dim; ++i)
3431 for (
unsigned int i = dim;
3432 i < internal::SymmetricTensorAccessors::StorageType<4, dim, Number>::
3435 tmp.
data[i][i] = 0.5;
3467 return identity_tensor<dim, double>();
3482 template <
int dim,
typename Number>
3503 template <
int dim,
typename Number>
3527 template <
int dim,
typename Number>
3535 for (
unsigned int i = 0; i < dim; ++i)
3536 for (
unsigned int j = i; j < dim; ++j)
3537 for (
unsigned int k = 0; k < dim; ++k)
3538 for (
unsigned int l = k; l < dim; ++l)
3539 tmp[i][j][k][l] = t1[i][j] * t2[k][l];
3554 template <
int dim,
typename Number>
3558 Number array[(dim * dim + dim) / 2];
3559 for (
unsigned int d = 0; d < dim; ++d)
3561 for (
unsigned int d = 0, c = 0; d < dim; ++d)
3562 for (
unsigned int e = d + 1; e < dim; ++e, ++c)
3563 array[dim + c] = (t[d][e] + t[e][d]) * 0.5;
3576 template <
int rank_,
int dim,
typename Number>
3594 template <
int rank_,
int dim,
typename Number>
3629 template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
3636 const OtherNumber & factor)
3643 using product_type =
typename ProductType<Number, OtherNumber>::type;
3652 product_type new_factor;
3653 new_factor = factor;
3668 template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
3678 return (t * factor);
3688 template <
int rank_,
int dim,
typename Number,
typename OtherNumber>
3695 const OtherNumber & factor)
3711 template <
int rank_,
int dim>
3728 template <
int rank_,
int dim>
3744 template <
int rank_,
int dim>
3762 template <
int dim,
typename Number,
typename OtherNumber>
3763 inline typename ProductType<Number, OtherNumber>::type
3780 template <
int dim,
typename Number,
typename OtherNumber>
3781 inline typename ProductType<Number, OtherNumber>::type
3786 typename ProductType<Number, OtherNumber>::type>::value(0.0);
3787 for (
unsigned int i = 0; i < dim; ++i)
3788 for (
unsigned int j = 0; j < dim; ++j)
3789 s += t1[i][j] * t2[i][j];
3803 template <
int dim,
typename Number,
typename OtherNumber>
3804 inline typename ProductType<Number, OtherNumber>::type
3827 template <
typename Number,
typename OtherNumber>
3829 SymmetricTensor<2, 1,
typename ProductType<Number, OtherNumber>::type> &tmp,
3833 tmp[0][0] = t[0][0][0][0] * s[0][0];
3853 template <
typename Number,
typename OtherNumber>
3855 SymmetricTensor<2, 1,
typename ProductType<Number, OtherNumber>::type> &tmp,
3859 tmp[0][0] = t[0][0][0][0] * s[0][0];
3878 template <
typename Number,
typename OtherNumber>
3880 SymmetricTensor<2, 2,
typename ProductType<Number, OtherNumber>::type> &tmp,
3884 const unsigned int dim = 2;
3886 for (
unsigned int i = 0; i < dim; ++i)
3887 for (
unsigned int j = i; j < dim; ++j)
3888 tmp[i][j] = t[i][j][0][0] * s[0][0] + t[i][j][1][1] * s[1][1] +
3889 2 * t[i][j][0][1] * s[0][1];
3909 template <
typename Number,
typename OtherNumber>
3911 SymmetricTensor<2, 2,
typename ProductType<Number, OtherNumber>::type> &tmp,
3915 const unsigned int dim = 2;
3917 for (
unsigned int i = 0; i < dim; ++i)
3918 for (
unsigned int j = i; j < dim; ++j)
3919 tmp[i][j] = s[0][0] * t[0][0][i][j] * +s[1][1] * t[1][1][i][j] +
3920 2 * s[0][1] * t[0][1][i][j];
3940 template <
typename Number,
typename OtherNumber>
3942 SymmetricTensor<2, 3,
typename ProductType<Number, OtherNumber>::type> &tmp,
3946 const unsigned int dim = 3;
3948 for (
unsigned int i = 0; i < dim; ++i)
3949 for (
unsigned int j = i; j < dim; ++j)
3950 tmp[i][j] = t[i][j][0][0] * s[0][0] + t[i][j][1][1] * s[1][1] +
3951 t[i][j][2][2] * s[2][2] + 2 * t[i][j][0][1] * s[0][1] +
3952 2 * t[i][j][0][2] * s[0][2] + 2 * t[i][j][1][2] * s[1][2];
3972 template <
typename Number,
typename OtherNumber>
3974 SymmetricTensor<2, 3,
typename ProductType<Number, OtherNumber>::type> &tmp,
3978 const unsigned int dim = 3;
3980 for (
unsigned int i = 0; i < dim; ++i)
3981 for (
unsigned int j = i; j < dim; ++j)
3982 tmp[i][j] = s[0][0] * t[0][0][i][j] + s[1][1] * t[1][1][i][j] +
3983 s[2][2] * t[2][2][i][j] + 2 * s[0][1] * t[0][1][i][j] +
3984 2 * s[0][2] * t[0][2][i][j] + 2 * s[1][2] * t[1][2][i][j];
3996 template <
int dim,
typename Number,
typename OtherNumber>
4002 for (
unsigned int i = 0; i < dim; ++i)
4003 for (
unsigned int j = 0; j < dim; ++j)
4004 dest[i] += src1[i][j] * src2[j];
4016 template <
int dim,
typename Number,
typename OtherNumber>
4047 template <
int rank_1,
4051 typename OtherNumber>
4052 inline DEAL_II_ALWAYS_INLINE
4053 typename Tensor<rank_1 + rank_2 - 2,
4055 typename ProductType<Number, OtherNumber>::type>::tensor_type
4059 typename Tensor<rank_1 + rank_2 - 2,
4061 typename ProductType<Number, OtherNumber>::type>::tensor_type
4089 template <
int rank_1,
4093 typename OtherNumber>
4094 inline DEAL_II_ALWAYS_INLINE
4095 typename Tensor<rank_1 + rank_2 - 2,
4097 typename ProductType<Number, OtherNumber>::type>::tensor_type
4101 typename Tensor<rank_1 + rank_2 - 2,
4103 typename ProductType<Number, OtherNumber>::type>::tensor_type
4120 template <
int dim,
typename Number>
4121 inline std::ostream &
4122 operator<<(std::ostream &out, const SymmetricTensor<2, dim, Number> &t)
4129 for (
unsigned int i = 0; i < dim; ++i)
4130 for (
unsigned int j = 0; j < dim; ++j)
4147 template <
int dim,
typename Number>
4148 inline std::ostream &
4149 operator<<(std::ostream &out, const SymmetricTensor<4, dim, Number> &t)
4156 for (
unsigned int i = 0; i < dim; ++i)
4157 for (
unsigned int j = 0; j < dim; ++j)
4158 for (
unsigned int k = 0; k < dim; ++k)
4159 for (
unsigned int l = 0; l < dim; ++l)
4160 tt[i][j][k][l] = t[i][j][k][l];
4166 DEAL_II_NAMESPACE_CLOSE
SymmetricTensor< rank_, dim, typename ProductType< Number, typename EnableIfScalar< OtherNumber >::type >::type > operator/(const SymmetricTensor< rank_, dim, Number > &t, const OtherNumber &factor)
static const unsigned int invalid_unsigned_int
internal::SymmetricTensorAccessors::Accessor< rank_, dim, true, rank_ - 1, Number > operator[](const unsigned int row) const
Number determinant(const SymmetricTensor< 2, dim, Number > &)
static unsigned int component_to_unrolled_index(const TableIndices< rank_ > &indices)
SymmetricTensor< 2, dim, Number > invert(const SymmetricTensor< 2, dim, Number > &t)
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
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)
SymmetricTensor< 2, dim, Number > symmetrize(const Tensor< 2, dim, Number > &t)
Number trace(const SymmetricTensor< 2, dim, Number > &d)
bool value_is_zero(const Number &value)
void double_contract(SymmetricTensor< 2, 1, typename ProductType< Number, OtherNumber >::type > &tmp, const SymmetricTensor< 4, 1, Number > &t, const SymmetricTensor< 2, 1, OtherNumber > &s)
#define AssertIndexRange(index, range)
SymmetricTensor< 4, dim, Number > deviator_tensor()
TableIndices< 2 > merge(const TableIndices< 2 > &previous_indices, const unsigned int new_index, const unsigned int position)
SymmetricTensor & operator=(const SymmetricTensor< rank_, dim, OtherNumber > &rhs)
static std::size_t memory_consumption()
static real_type abs(const number &x)
SymmetricTensorEigenvectorMethod
SymmetricTensor< rank_, dim, typename ProductType< Number, OtherNumber >::type > operator+(const SymmetricTensor< rank_, dim, Number > &left, const SymmetricTensor< rank_, dim, OtherNumber > &right)
static ::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
SymmetricTensor & operator/=(const OtherNumber &factor)
SymmetricTensor< rank_, dim, Number > operator*(const SymmetricTensor< rank_, dim, Number > &t, const Number &factor)
static TableIndices< rank_ > unrolled_to_component_indices(const unsigned int i)
SymmetricTensor< rank_, dim, typename ProductType< Number, OtherNumber >::type > operator-(const SymmetricTensor< rank_, dim, Number > &left, const SymmetricTensor< rank_, dim, OtherNumber > &right)
static ::ExceptionBase & ExcMessage(std::string arg1)
Number first_invariant(const SymmetricTensor< 2, dim, Number > &t)
const Number & access_raw_entry(const unsigned int unrolled_index) const
typename base_tensor_descriptor::base_tensor_type base_tensor_type
bool operator!=(const SymmetricTensor &) const
T sum(const T &t, const MPI_Comm &mpi_communicator)
#define Assert(cond, exc)
SymmetricTensor< 2, dim, Number > deviator(const SymmetricTensor< 2, dim, Number > &t)
Number trace(const SymmetricTensor< 2, dim, Number > &d)
void serialize(Archive &ar, const unsigned int version)
void tridiagonalize(const ::SymmetricTensor< 2, dim, Number > &A, ::Tensor< 2, dim, Number > &Q, std::array< Number, dim > &d, std::array< Number, dim - 1 > &e)
SymmetricTensor< 4, dim, Number > outer_product(const SymmetricTensor< 2, dim, Number > &t1, const SymmetricTensor< 2, dim, Number > &t2)
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
ProductType< Number, OtherNumber >::type scalar_product(const SymmetricTensor< 2, dim, Number > &t1, const SymmetricTensor< 2, dim, OtherNumber > &t2)
Number & operator()(const TableIndices< rank_ > &indices)
void swap(Vector< Number > &u, Vector< Number > &v)
Number determinant(const SymmetricTensor< 2, dim, Number > &t)
SymmetricTensor< 2, dim, Number > deviator(const SymmetricTensor< 2, dim, Number > &)
SymmetricTensor operator-() const
SymmetricTensor & operator*=(const OtherNumber &factor)
internal::SymmetricTensorAccessors::double_contraction_result< rank_, 2, dim, Number, OtherNumber >::type operator*(const SymmetricTensor< 2, dim, OtherNumber > &s) const
SymmetricTensor & operator+=(const SymmetricTensor< rank_, dim, OtherNumber > &)
Number third_invariant(const SymmetricTensor< 2, dim, Number > &t)
static ::ExceptionBase & ExcNotImplemented()
bool operator==(const SymmetricTensor &) const
std::array< Number, 1 > eigenvalues(const SymmetricTensor< 2, 1, Number > &T)
SymmetricTensor< 2, dim, Number > unit_symmetric_tensor()
SymmetricTensor< rank_, dim, typename ProductType< Number, OtherNumber >::type > operator-(const SymmetricTensor< rank_, dim, Number > &left, const SymmetricTensor< rank_, dim, OtherNumber > &right)
T max(const T &t, const MPI_Comm &mpi_communicator)
SymmetricTensor< 4, dim, Number > identity_tensor()
Number second_invariant(const SymmetricTensor< 2, 1, Number > &)
SymmetricTensor & operator-=(const SymmetricTensor< rank_, dim, OtherNumber > &)
numbers::NumberTraits< Number >::real_type norm() const
Tensor< 2, dim, Number > l(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
static ::ExceptionBase & ExcInternalError()
Point< dim, typename ProductType< Number, typename EnableIfScalar< OtherNumber >::type >::type > operator*(const OtherNumber) const