13#ifndef dealii_tensor_h
14#define dealii_tensor_h
25#include <Kokkos_Array.hpp>
27#ifdef DEAL_II_WITH_ADOLC
28# include <adolc/adouble.h>
40template <
typename ElementType,
typename MemorySpace>
43template <
int dim,
typename Number>
47template <
int rank_,
int dim, typename Number =
double>
49template <typename Number>
51template <typename number>
92template <
int dim,
typename Number>
96 static_assert(dim >= 0,
97 "Tensors must have a dimension greater than or equal to one.");
112 static constexpr unsigned int rank = 0;
157 template <
typename OtherNumber>
166 template <
typename OtherNumber>
170#ifdef DEAL_II_DELETED_MOVE_CONSTRUCTOR_BUG
213 template <
typename OtherNumber>
217#if defined(__INTEL_COMPILER) || defined(DEAL_II_DELETED_MOVE_CONSTRUCTOR_BUG)
230#ifdef DEAL_II_DELETED_MOVE_CONSTRUCTOR_BUG
244 template <
typename OtherNumber>
253 template <
typename OtherNumber>
260 template <
typename OtherNumber>
267 template <
typename OtherNumber>
276 template <
typename OtherNumber>
285 template <
typename OtherNumber>
294 template <
typename OtherNumber>
303 template <
typename OtherNumber>
354 template <
class Iterator>
363 template <
class Archive>
380 template <
int,
int,
typename>
459template <
int rank_,
int dim,
typename Number>
463 static_assert(rank_ >= 1,
464 "Tensors must have a rank greater than or equal to one.");
465 static_assert(dim >= 0,
466 "Tensors must have a dimension greater than or equal to zero.");
480 static constexpr unsigned int rank = rank_;
505 std::conditional_t<rank_ == 1, Number,
Tensor<rank_ - 1, dim, Number>>;
520 Number[(dim != 0) ? dim : 1],
550 template <
typename ElementType,
typename MemorySpace>
561 template <
typename OtherNumber>
568 template <
typename OtherNumber>
575 template <
typename OtherNumber>
579#ifdef DEAL_II_DELETED_MOVE_CONSTRUCTOR_BUG
610 constexpr const Number &
654 template <
typename OtherNumber>
675#ifdef DEAL_II_DELETED_MOVE_CONSTRUCTOR_BUG
692 template <
typename OtherNumber>
699 template <
typename OtherNumber>
708 template <
typename OtherNumber>
717 template <
typename OtherNumber>
727 template <
typename OtherNumber>
736 template <
typename OtherNumber>
794 template <
class Iterator>
817 static constexpr std::size_t
825 template <
class Archive>
841#if DEAL_II_KOKKOS_VERSION_GTE(3, 7, 0)
842 std::conditional_t<rank_ == 1,
843 Kokkos::Array<Number, dim>,
844 Kokkos::Array<
Tensor<rank_ - 1, dim, Number>, dim>>
846 std::conditional_t<rank_ == 1,
847 std::array<Number, dim>,
848 std::array<
Tensor<rank_ - 1, dim, Number>, dim>>
858 template <
typename ArrayLike, std::size_t... Indices>
860 Tensor(
const ArrayLike &initializer, std::index_sequence<Indices...>);
863 template <
int,
int,
typename>
868 friend class Point<dim, Number>;
879 template <
int rank,
int dim,
typename T,
typename U>
880 struct ProductTypeImpl<
Tensor<rank, dim, T>,
std::complex<U>>
886 template <
int rank,
int dim,
typename T,
typename U>
887 struct ProductTypeImpl<
Tensor<rank, dim,
std::complex<T>>, std::complex<U>>
893 template <
typename T,
int rank,
int dim,
typename U>
894 struct ProductTypeImpl<
std::complex<T>,
Tensor<rank, dim, U>>
900 template <
int rank,
int dim,
typename T,
typename U>
901 struct ProductTypeImpl<
std::complex<T>,
Tensor<rank, dim, std::complex<U>>>
912 template <
int rank,
int dim,
typename T>
913 struct NumberType<
Tensor<rank, dim,
T>>
936template <
int dim,
typename Number>
946template <
int dim,
typename Number>
947template <
typename OtherNumber>
955template <
int dim,
typename Number>
956template <
typename OtherNumber>
963# ifdef DEAL_II_DELETED_MOVE_CONSTRUCTOR_BUG
964template <
int dim,
typename Number>
972template <
int dim,
typename Number>
975 :
value{std::move(other.value)}
981template <
int dim,
typename Number>
986 ExcMessage(
"Cannot access an object of type Tensor<0,0,Number>"));
991template <
int dim,
typename Number>
996 ExcMessage(
"Cannot access an object of type Tensor<0,0,Number>"));
1002template <
int dim,
typename Number>
1003template <
typename OtherNumber>
1012# if defined(__INTEL_COMPILER) || defined(DEAL_II_DELETED_MOVE_CONSTRUCTOR_BUG)
1013template <
int dim,
typename Number>
1022# ifdef DEAL_II_DELETED_MOVE_CONSTRUCTOR_BUG
1023template <
int dim,
typename Number>
1027 value = std::move(other.value);
1034template <
int dim,
typename Number>
1035template <
typename OtherNumber>
1044template <
int dim,
typename Number>
1045template <
typename OtherNumber>
1046constexpr inline bool
1049# ifdef DEAL_II_ADOLC_WITH_ADVANCED_BRANCHING
1050 Assert(!(std::is_same_v<Number, adouble> ||
1051 std::is_same_v<OtherNumber, adouble>),
1053 "The Tensor equality operator for ADOL-C taped numbers has not yet "
1054 "been extended to support advanced branching."));
1061template <
int dim,
typename Number>
1062template <
typename OtherNumber>
1066 return !((*this) == p);
1070template <
int dim,
typename Number>
1071template <
typename OtherNumber>
1080template <
int dim,
typename Number>
1081template <
typename OtherNumber>
1093 namespace ComplexWorkaround
1095 template <
typename Number,
typename OtherNumber>
1097 multiply_assign_scalar(Number &val,
const OtherNumber &s)
1102 template <
typename Number,
typename OtherNumber>
1104 multiply_assign_scalar(std::complex<Number> &val,
const OtherNumber &s)
1106# if DEAL_II_KOKKOS_VERSION_GTE(3, 6, 0)
1107 KOKKOS_IF_ON_HOST((val *= s;))
1108 KOKKOS_IF_ON_DEVICE(({
1112 "This function is not implemented for std::complex<Number>!\n");
1123template <
int dim,
typename Number>
1124template <
typename OtherNumber>
1128 internal::ComplexWorkaround::multiply_assign_scalar(value, s);
1134template <
int dim,
typename Number>
1135template <
typename OtherNumber>
1144template <
int dim,
typename Number>
1152template <
int dim,
typename Number>
1157 ExcMessage(
"Cannot access an object of type Tensor<0,0,Number>"));
1162template <
int dim,
typename Number>
1168 ExcMessage(
"Cannot access an object of type Tensor<0,0,Number>"));
1174template <
int dim,
typename Number>
1175constexpr inline void
1185template <
int dim,
typename Number>
1186template <
class Iterator>
1192 ExcMessage(
"Cannot unroll an object of type Tensor<0,0,Number>"));
1194 ExcMessage(
"The provided iterator range must contain at least one "
1201template <
int dim,
typename Number>
1202template <
class Archive>
1210template <
int dim,
typename Number>
1216template <
int rank_,
int dim,
typename Number>
1217template <
typename ArrayLike, std::size_t... indices>
1220 std::index_sequence<indices...>)
1237 if constexpr (rank_ == 1)
1243 static_assert(
sizeof...(indices) == dim,
1244 "dim should match the number of indices");
1248# if defined(DEAL_II_HAVE_CXX20) && !defined(__NVCC__)
1250template <
int rank_,
int dim,
typename Number>
1285 []<
std::size_t... I>(
1286 const std::index_sequence<I...> &) constexpr -> decltype(
values) {
1287 if constexpr (dim == 0)
1291 else if constexpr (rank_ == 1)
1293 auto get_zero_and_ignore_argument = [](
int) {
1296 return {{(get_zero_and_ignore_argument(I))...}};
1300 auto get_zero_and_ignore_argument = [](
int) {
1303 return {{(get_zero_and_ignore_argument(I))...}};
1305 }(std::make_index_sequence<dim>()))
1321 namespace TensorInitialization
1323 template <
int rank,
int dim,
typename Number, std::size_t... I>
1324# if DEAL_II_KOKKOS_VERSION_GTE(3, 7, 0)
1325 constexpr Kokkos::Array<typename Tensor<rank, dim, Number>::value_type, dim>
1327 constexpr std::array<typename Tensor<rank, dim, Number>::value_type, dim>
1329 make_zero_array(
const std::index_sequence<I...> &)
1331 static_assert(
sizeof...(I) == dim,
"This is bad.");
1337 if constexpr (dim == 0)
1341 else if constexpr (rank == 1)
1343 auto get_zero_and_ignore_argument = [](
int) {
1346 return {{(get_zero_and_ignore_argument(I))...}};
1350 auto get_zero_and_ignore_argument = [](
int) {
1353 return {{(get_zero_and_ignore_argument(I))...}};
1360template <
int rank_,
int dim,
typename Number>
1364 std::make_index_sequence<dim>()))
1371template <
int rank_,
int dim,
typename Number>
1374 :
Tensor(initializer,
std::make_index_sequence<dim>{})
1379template <
int rank_,
int dim,
typename Number>
1380template <
typename ElementType,
typename MemorySpace>
1386 const int my_n_independent_components = n_independent_components;
1389 for (
unsigned int i = 0; i < my_n_independent_components; ++i)
1390 (*
this)[unrolled_to_component_indices(i)] = initializer[i];
1395template <
int rank_,
int dim,
typename Number>
1396template <
typename OtherNumber>
1400 :
Tensor(initializer,
std::make_index_sequence<dim>{})
1405template <
int rank_,
int dim,
typename Number>
1406template <
typename OtherNumber>
1410 :
Tensor(initializer,
std::make_index_sequence<dim>{})
1415template <
int rank_,
int dim,
typename Number>
1416template <
typename OtherNumber>
1418operator
Tensor<1, dim,
Tensor<rank_ - 1, dim, OtherNumber>>()
const
1426# ifdef DEAL_II_DELETED_MOVE_CONSTRUCTOR_BUG
1427template <
int rank_,
int dim,
typename Number>
1435template <
int rank_,
int dim,
typename Number>
1438 :
values(std::move(other.values))
1444template <
int rank_,
int dim,
typename Number>
1450 ExcMessage(
"Cannot access an object of type Tensor<rank_,0,Number>"));
1458template <
int rank_,
int dim,
typename Number>
1464 ExcMessage(
"Cannot access an object of type Tensor<rank_,0,Number>"));
1472template <
int rank_,
int dim,
typename Number>
1477 ExcMessage(
"Cannot access an object of type Tensor<rank_,0,Number>"));
1479 return TensorAccessors::extract<rank_>(*
this, indices);
1484template <
int rank_,
int dim,
typename Number>
1489 ExcMessage(
"Cannot access an object of type Tensor<rank_,0,Number>"));
1491 return TensorAccessors::extract<rank_>(*
this, indices);
1496template <
int rank_,
int dim,
typename Number>
1500 static_assert(rank_ == 1,
1501 "This function is only available for rank-1 tensors "
1502 "because higher-rank tensors may not store their elements "
1503 "in a contiguous array.");
1505 return std::addressof(
1506 this->
operator[](this->unrolled_to_component_indices(0)));
1511template <
int rank_,
int dim,
typename Number>
1515 static_assert(rank_ == 1,
1516 "This function is only available for rank-1 tensors "
1517 "because higher-rank tensors may not store their elements "
1518 "in a contiguous array.");
1520 return std::addressof(
1521 this->
operator[](this->unrolled_to_component_indices(0)));
1526template <
int rank_,
int dim,
typename Number>
1530 static_assert(rank_ == 1,
1531 "This function is only available for rank-1 tensors "
1532 "because higher-rank tensors may not store their elements "
1533 "in a contiguous array.");
1535 return begin_raw() + n_independent_components;
1540template <
int rank_,
int dim,
typename Number>
1544 static_assert(rank_ == 1,
1545 "This function is only available for rank-1 tensors "
1546 "because higher-rank tensors may not store their elements "
1547 "in a contiguous array.");
1549 return begin_raw() + n_independent_components;
1554template <
int rank_,
int dim,
typename Number>
1555template <
typename OtherNumber>
1561 for (
unsigned int i = 0; i < dim; ++i)
1568template <
int rank_,
int dim,
typename Number>
1575 for (
unsigned int i = 0; i < dim; ++i)
1581# ifdef DEAL_II_DELETED_MOVE_CONSTRUCTOR_BUG
1582template <
int rank_,
int dim,
typename Number>
1586 for (
unsigned int i = 0; i < dim; ++i)
1587 values[i] = other.
values[i];
1593template <
int rank_,
int dim,
typename Number>
1598 for (
unsigned int i = 0; i < dim; ++i)
1599 values[i] = other.
values[i];
1605template <
int rank_,
int dim,
typename Number>
1606template <
typename OtherNumber>
1607constexpr inline bool
1611# ifdef DEAL_II_ADOLC_WITH_ADVANCED_BRANCHING
1612 Assert(!(std::is_same_v<Number, adouble> ||
1613 std::is_same_v<OtherNumber, adouble>),
1615 "The Tensor equality operator for ADOL-C taped numbers has not yet "
1616 "been extended to support advanced branching."));
1619 for (
unsigned int i = 0; i < dim; ++i)
1633constexpr inline bool
1640template <
int rank_,
int dim,
typename Number>
1641template <
typename OtherNumber>
1646 return !((*this) == p);
1650template <
int rank_,
int dim,
typename Number>
1651template <
typename OtherNumber>
1657 for (
unsigned int i = 0; i < dim; ++i)
1658 values[i] += p.
values[i];
1663template <
int rank_,
int dim,
typename Number>
1664template <
typename OtherNumber>
1670 for (
unsigned int i = 0; i < dim; ++i)
1671 values[i] -= p.
values[i];
1676template <
int rank_,
int dim,
typename Number>
1677template <
typename OtherNumber>
1682 for (
unsigned int i = 0; i < dim; ++i)
1689template <
int rank_,
int dim,
typename Number>
1690template <
typename OtherNumber>
1695 if constexpr (std::is_integral_v<
1697 std::is_same_v<Number, Differentiation::SD::Expression>)
1700 for (
unsigned int d = 0;
d < dim; ++
d)
1708 for (
unsigned int d = 0;
d < dim; ++
d)
1709 values[d] *= inverse_factor;
1716template <
int rank_,
int dim,
typename Number>
1723 for (
unsigned int i = 0; i < dim; ++i)
1724 tmp.
values[i] = -values[i];
1730template <
int rank_,
int dim,
typename Number>
1736 if constexpr ((rank_ == 1) && (dim == 1) && std::is_arithmetic_v<Number>)
1740 else if constexpr ((rank_ == 2) && (dim == 1) && std::is_arithmetic_v<Number>)
1753 return sqrt(norm_square());
1758template <
int rank_,
int dim,
typename Number>
1763 if constexpr (dim == 0)
1766 else if constexpr (rank_ == 1)
1772 for (
unsigned int i = 1; i < dim; ++i)
1783 for (
unsigned int i = 1; i < dim; ++i)
1784 s += values[i].norm_square();
1792template <
int rank_,
int dim,
typename Number>
1793template <
class Iterator>
1796 const Iterator
end)
const
1798 if constexpr (rank_ > 1)
1801 Iterator next =
begin;
1802 for (
unsigned int i = 0; i < dim; ++i)
1815 "The provided iterator range must contain at least 'dim' "
1823template <
int rank_,
int dim,
typename Number>
1824constexpr inline unsigned int
1828 unsigned int index = 0;
1829 for (
int r = 0; r < rank_; ++r)
1830 index = index * dim + indices[r];
1837template <
int rank_,
int dim,
typename Number>
1842 unsigned int dummy = n_independent_components;
1845 if constexpr (dim == 0)
1849 "A tensor with dimension 0 does not store any elements. "
1850 "There is no indexing that can address its elements."));
1857 unsigned int remainder = i;
1858 for (
int r = rank_ - 1; r >= 0; --r)
1860 indices[r] = remainder % dim;
1861 remainder = remainder / dim;
1870template <
int rank_,
int dim,
typename Number>
1871constexpr inline void
1874 for (
unsigned int i = 0; i < dim; ++i)
1879template <
int rank_,
int dim,
typename Number>
1880constexpr std::size_t
1887template <
int rank_,
int dim,
typename Number>
1888template <
class Archive>
1892 for (
int i = 0; i < dim; ++i)
1899template <
int rank_,
int dim,
typename Number>
1918template <
int rank_,
int dim,
typename Number>
1919inline std::ostream &
1922 for (
unsigned int i = 0; i < dim; ++i)
1926 for (
unsigned int j = 0; j < rank_; ++j)
1940template <
int dim,
typename Number>
1941inline std::ostream &
1944 out << static_cast<const Number &>(p);
1967template <
int dim,
typename Number,
typename Other>
1972 return object *
static_cast<const Number &
>(t);
1987template <
int dim,
typename Number,
typename Other>
1992 return static_cast<const Number &
>(t) *
object;
2007template <
int dim,
typename Number,
typename OtherNumber>
2013 return static_cast<const Number &
>(src1) *
2014 static_cast<const OtherNumber &
>(src2);
2025template <
int dim,
typename Number,
typename OtherNumber>
2033 return static_cast<const Number &
>(t) / factor;
2044template <
int dim,
typename Number,
typename OtherNumber>
2050 return static_cast<const Number &
>(p) +
static_cast<const OtherNumber &
>(q);
2061template <
int dim,
typename Number,
typename OtherNumber>
2067 return static_cast<const Number &
>(p) -
static_cast<const OtherNumber &
>(q);
2083template <
int rank,
int dim,
typename Number,
typename OtherNumber>
2109template <
int rank,
int dim,
typename Number,
typename OtherNumber>
2132template <
int rank,
int dim,
typename Number,
typename OtherNumber>
2155template <
int rank,
int dim,
typename Number,
typename OtherNumber>
2176template <
int rank,
int dim,
typename Number,
typename OtherNumber>
2193template <
int dim,
typename Number,
typename OtherNumber>
2222template <
int rank,
int dim,
typename Number,
typename OtherNumber>
2230 for (
unsigned int i = 0; i < dim; ++i)
2281template <
int rank_1,
2285 typename OtherNumber,
2286 typename = std::enable_if_t<rank_1 >= 1 && rank_2 >= 1>>
2288 typename Tensor<rank_1 + rank_2 - 2,
2300 if constexpr ((rank_1 == 1) && (rank_2 == 1))
2304 static_assert(dim > 0,
"Tensors cannot have dimension zero.");
2306 for (
unsigned int i = 1; i < dim; ++i)
2307 sum += src1[i] * src2[i];
2311 else if constexpr ((rank_1 == 2) && (rank_2 == 1))
2317 rank_1 + rank_2 - 2,
2320 for (
unsigned int i = 0; i < dim; ++i)
2321 result[i] += src1[i] * src2;
2330 rank_1 + rank_2 - 2,
2334 TensorAccessors::internal::
2335 ReorderedIndexView<0, rank_2, const Tensor<rank_2, dim, OtherNumber>>
2336 reordered = TensorAccessors::reordered_index_view<0, rank_2>(src2);
2337 TensorAccessors::contract<1, rank_1, rank_2, dim>(result,
2374template <
int index_1,
2380 typename OtherNumber>
2382 typename Tensor<rank_1 + rank_2 - 2,
2388 Assert(0 <= index_1 && index_1 < rank_1,
2390 "The specified index_1 must lie within the range [0,rank_1)"));
2391 Assert(0 <= index_2 && index_2 < rank_2,
2393 "The specified index_2 must lie within the range [0,rank_2)"));
2400 reord_01 = reordered_index_view<index_1, rank_1>(src1);
2406 reord_02 = reordered_index_view<index_2, rank_2>(src2);
2408 typename Tensor<rank_1 + rank_2 - 2,
2412 TensorAccessors::contract<1, rank_1, rank_2, dim>(result, reord_01, reord_02);
2447template <
int index_1,
2455 typename OtherNumber>
2457 typename Tensor<rank_1 + rank_2 - 4,
2463 Assert(0 <= index_1 && index_1 < rank_1,
2465 "The specified index_1 must lie within the range [0,rank_1)"));
2466 Assert(0 <= index_3 && index_3 < rank_1,
2468 "The specified index_3 must lie within the range [0,rank_1)"));
2469 Assert(index_1 != index_3,
2470 ExcMessage(
"index_1 and index_3 must not be the same"));
2471 Assert(0 <= index_2 && index_2 < rank_2,
2473 "The specified index_2 must lie within the range [0,rank_2)"));
2474 Assert(0 <= index_4 && index_4 < rank_2,
2476 "The specified index_4 must lie within the range [0,rank_2)"));
2477 Assert(index_2 != index_4,
2478 ExcMessage(
"index_2 and index_4 must not be the same"));
2485 reord_1 = TensorAccessors::reordered_index_view<index_1, rank_1>(src1);
2489 reord_2 = TensorAccessors::reordered_index_view<index_2, rank_2>(src2);
2495 (index_3 < index_1 ? index_3 : index_3 - 1),
2507 (index_4 < index_2 ? index_4 : index_4 - 1),
2515 typename Tensor<rank_1 + rank_2 - 4,
2519 TensorAccessors::contract<2, rank_1, rank_2, dim>(result, reord_3, reord_4);
2536template <
int rank,
int dim,
typename Number,
typename OtherNumber>
2543 TensorAccessors::contract<rank, rank, rank, dim>(result, left, right);
2565template <
template <
int,
int,
typename>
class TensorT1,
2566 template <
int,
int,
typename>
2568 template <
int,
int,
typename>
2578 contract3(
const TensorT1<rank_1, dim, T1> &left,
2579 const TensorT2<rank_1 + rank_2, dim, T2> &middle,
2580 const TensorT3<rank_2, dim, T3> &right)
2584 return TensorAccessors::contract3<rank_1, rank_2, dim, return_type>(left,
2600template <
int rank_1,
2604 typename OtherNumber>
2610 typename Tensor<rank_1 + rank_2,
2614 TensorAccessors::contract<0, rank_1, rank_2, dim>(result, src1, src2);
2637template <
int dim,
typename Number>
2646 result[1] = -src[0];
2661template <
int dim,
typename Number1,
typename Number2>
2671 if constexpr (dim == 3)
2673 result[0] = src1[1] * src2[2] - src1[2] * src2[1];
2674 result[1] = src1[2] * src2[0] - src1[0] * src2[2];
2675 result[2] = src1[0] * src2[1] - src1[1] * src2[0];
2695template <
int dim,
typename Number>
2703 for (
unsigned int k = 0; k < dim; ++k)
2706 for (
unsigned int i = 0; i < dim - 1; ++i)
2707 for (
unsigned int j = 0; j < dim - 1; ++j)
2708 minor[i][j] = t[i][j < k ? j : j + 1];
2712 det += t[dim - 1][k] * cofactor;
2715 return ((dim % 2 == 0) ? 1. : -1.) * det;
2723template <
typename Number>
2735template <
typename Number>
2740 return t[0][0] * t[1][1] - t[1][0] * t[0][1];
2748template <
typename Number>
2759 return t[0][0] * C0 + t[0][1] * C1 + t[0][2] * C2;
2769template <
int dim,
typename Number>
2774 for (
unsigned int i = 1; i < dim; ++i)
2788template <
int dim,
typename Number>
2792 Number return_tensor[dim][dim];
2805template <
typename Number>
2813 return return_tensor;
2817template <
typename Number>
2824 1.0 / (t[0][0] * t[1][1] - t[1][0] * t[0][1]));
2825 return_tensor[0][0] = t[1][1];
2826 return_tensor[0][1] = -t[0][1];
2827 return_tensor[1][0] = -t[1][0];
2828 return_tensor[1][1] = t[0][0];
2829 return_tensor *= inv_det_t;
2831 return return_tensor;
2834template <
typename Number>
2840 const auto value = [](
const auto &t) {
2844 return_tensor[0][0] =
value(t[1][1] * t[2][2]) -
value(t[1][2] * t[2][1]);
2845 return_tensor[0][1] =
value(t[0][2] * t[2][1]) -
value(t[0][1] * t[2][2]);
2846 return_tensor[0][2] =
value(t[0][1] * t[1][2]) -
value(t[0][2] * t[1][1]);
2847 return_tensor[1][0] =
value(t[1][2] * t[2][0]) -
value(t[1][0] * t[2][2]);
2848 return_tensor[1][1] =
value(t[0][0] * t[2][2]) -
value(t[0][2] * t[2][0]);
2849 return_tensor[1][2] =
value(t[0][2] * t[1][0]) -
value(t[0][0] * t[1][2]);
2850 return_tensor[2][0] =
value(t[1][0] * t[2][1]) -
value(t[1][1] * t[2][0]);
2851 return_tensor[2][1] =
value(t[0][1] * t[2][0]) -
value(t[0][0] * t[2][1]);
2852 return_tensor[2][2] =
value(t[0][0] * t[1][1]) -
value(t[0][1] * t[1][0]);
2855 value(1.0 / (t[0][0] * return_tensor[0][0] + t[0][1] * return_tensor[1][0] +
2856 t[0][2] * return_tensor[2][0]));
2857 return_tensor *= inv_det_t;
2859 return return_tensor;
2870template <
int dim,
typename Number>
2875 for (
unsigned int i = 0; i < dim; ++i)
2878 for (
unsigned int j = i + 1; j < dim; ++j)
2901template <
int dim,
typename Number>
2922template <
int dim,
typename Number>
2993template <
int dim,
typename Number>
3005template <
int dim,
typename Number>
3010 for (
unsigned int j = 0; j < dim; ++j)
3013 for (
unsigned int i = 0; i < dim; ++i)
3031template <
int dim,
typename Number>
3036 for (
unsigned int i = 0; i < dim; ++i)
3039 for (
unsigned int j = 0; j < dim; ++j)
3057# ifdef DEAL_II_ADOLC_WITH_ADVANCED_BRANCHING
3066 for (
unsigned int j = 0; j < dim; ++j)
3069 for (
unsigned int i = 0; i < dim; ++i)
3070 sum += fabs(t[i][j]);
3072 condassign(max, (sum > max), sum, max);
3084 for (
unsigned int i = 0; i < dim; ++i)
3087 for (
unsigned int j = 0; j < dim; ++j)
3088 sum +=
fabs(t[i][j]);
3090 condassign(max, (sum > max), sum, max);
* * reference operator*() const
constexpr Tensor & operator*=(const OtherNumber &factor)
constexpr Tensor & operator=(const OtherNumber &d) &&=delete
void serialize(Archive &ar, const unsigned int version)
constexpr Tensor & operator/=(const OtherNumber &factor)
constexpr Tensor & operator-=(const Tensor< 0, dim, OtherNumber > &rhs)
constexpr Tensor(const Tensor< 0, dim, OtherNumber > &initializer)
constexpr Tensor(const OtherNumber &initializer)
constexpr real_type norm_square() const
constexpr bool operator!=(const Tensor< 0, dim, OtherNumber > &rhs) const
constexpr Tensor & operator=(const Tensor< 0, dim, OtherNumber > &rhs)
constexpr Tensor & operator+=(const Tensor< 0, dim, OtherNumber > &rhs)
void unroll(const Iterator begin, const Iterator end) const
constexpr bool operator==(const Tensor< 0, dim, OtherNumber > &rhs) const
typename numbers::NumberTraits< Number >::real_type real_type
constexpr Tensor & operator=(const OtherNumber &d) &
constexpr Tensor operator-() const
constexpr Tensor & operator/=(const OtherNumber &factor)
constexpr Tensor(const ArrayView< ElementType, MemorySpace > &initializer)
constexpr bool operator==(const Tensor< rank_, dim, OtherNumber > &) const
constexpr Tensor< rank, dim, typename ProductType< Number, typename EnableIfScalar< OtherNumber >::type >::type > operator/(const Tensor< rank, dim, Number > &t, const OtherNumber &factor)
constexpr Tensor(const Tensor< 1, dim, Tensor< rank_ - 1, dim, OtherNumber > > &initializer)
constexpr const Number & operator[](const TableIndices< rank_ > &indices) const
constexpr Tensor< 0, dim, typename ProductType< Number, OtherNumber >::type > operator-(const Tensor< 0, dim, Number > &p, const Tensor< 0, dim, OtherNumber > &q)
constexpr Tensor< 0, dim, typename ProductType< Number, typename EnableIfScalar< OtherNumber >::type >::type > operator/(const Tensor< 0, dim, Number > &t, const OtherNumber &factor)
static constexpr unsigned int rank
constexpr Tensor(const Tensor< rank_, dim, OtherNumber > &initializer)
std::conditional_t< rank_==1, Number, Tensor< rank_ - 1, dim, Number > > value_type
numbers::NumberTraits< Number >::real_type norm() const
constexpr Tensor & operator-=(const Tensor< rank_, dim, OtherNumber > &)
void unroll(const Iterator begin, const Iterator end) const
static constexpr unsigned int component_to_unrolled_index(const TableIndices< rank_ > &indices)
constexpr ProductType< Number, OtherNumber >::type operator*(const Tensor< 0, dim, Number > &src1, const Tensor< 0, dim, OtherNumber > &src2)
const Number * begin_raw() const
std::conditional_t< rank_==1, Number[(dim !=0) ? dim :1], typename Tensor< rank_ - 1, dim, Number >::array_type[(dim !=0) ? dim :1]> array_type
constexpr bool operator!=(const Tensor< rank_, dim, OtherNumber > &) const
constexpr Tensor< 0, dim, typename ProductType< Number, OtherNumber >::type > schur_product(const Tensor< 0, dim, Number > &src1, const Tensor< 0, dim, OtherNumber > &src2)
constexpr value_type & operator[](const unsigned int i)
constexpr Tensor< rank, dim, typename ProductType< Number, OtherNumber >::type > operator+(const Tensor< rank, dim, Number > &p, const Tensor< rank, dim, OtherNumber > &q)
Number linfty_norm(const Tensor< 2, dim, Number > &t)
constexpr ProductType< Other, Number >::type operator*(const Other &object, const Tensor< 0, dim, Number > &t)
Number l1_norm(const Tensor< 2, dim, Number > &t)
static constexpr unsigned int dimension
static constexpr TableIndices< rank_ > unrolled_to_component_indices(const unsigned int i)
constexpr Tensor & operator=(const Number &d) &&=delete
constexpr Tensor< rank, dim, typename ProductType< typename EnableIfScalar< Number >::type, OtherNumber >::type > operator*(const Number &factor, const Tensor< rank, dim, OtherNumber > &t)
static constexpr std::size_t memory_consumption()
constexpr Tensor & operator=(const Number &d) &
std::conditional_t< rank_==1, std::array< Number, dim >, std::array< Tensor< rank_ - 1, dim, Number >, dim > > values
constexpr Tensor< 0, dim, typename ProductType< Number, OtherNumber >::type > operator+(const Tensor< 0, dim, Number > &p, const Tensor< 0, dim, OtherNumber > &q)
constexpr Tensor & operator+=(const Tensor< rank_, dim, OtherNumber > &)
const Number * end_raw() const
constexpr Number & operator[](const TableIndices< rank_ > &indices)
constexpr Tensor< rank, dim, typename ProductType< Number, OtherNumber >::type > schur_product(const Tensor< rank, dim, Number > &src1, const Tensor< rank, dim, OtherNumber > &src2)
constexpr numbers::NumberTraits< Number >::real_type norm_square() const
constexpr Tensor< rank, dim, typename ProductType< Number, OtherNumber >::type > operator-(const Tensor< rank, dim, Number > &p, const Tensor< rank, dim, OtherNumber > &q)
constexpr ProductType< Number, Other >::type operator*(const Tensor< 0, dim, Number > &t, const Other &object)
constexpr Tensor(const ArrayLike &initializer, std::index_sequence< Indices... >)
constexpr Tensor< rank, dim, typename ProductType< Number, typename EnableIfScalar< OtherNumber >::type >::type > operator*(const Tensor< rank, dim, Number > &t, const OtherNumber &factor)
void serialize(Archive &ar, const unsigned int version)
constexpr Tensor & operator*=(const OtherNumber &factor)
constexpr const value_type & operator[](const unsigned int i) const
constexpr Tensor(const array_type &initializer)
static constexpr unsigned int n_independent_components
constexpr Tensor operator-() const
constexpr Tensor & operator=(const Tensor< rank_, dim, OtherNumber > &rhs)
#define DEAL_II_ALWAYS_INLINE
#define DEAL_II_DEPRECATED
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_CXX20_REQUIRES(condition)
#define DEAL_II_CXX23_ASSUME(expr)
#define DEAL_II_HOST_DEVICE
#define DEAL_II_NAMESPACE_CLOSE
#define DEAL_II_HOST_DEVICE_ALWAYS_INLINE
static ::ExceptionBase & ExcNotImplemented()
static ::ExceptionBase & ExcScalarAssignmentOnlyForZeroValue()
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
Expression fabs(const Expression &x)
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
* * * RotationFunction< dim, Number >::RotationFunction Number(dim)
* * * * std::vector< Number > ThermoPlasticMaterial< dim, ViscoplasticYieldLaw, Number >::get_state_parameters const
constexpr internal::ReorderedIndexView< index, rank, T > reordered_index_view(T &t)
constexpr void contract(T1 &result, const T2 &left, const T3 &right)
constexpr T1 contract3(const T2 &left, const T3 &middle, const T4 &right)
T sum(const T &t, const MPI_Comm mpi_communicator)
constexpr bool values_are_not_equal(const Number1 &value_1, const Number2 &value_2)
constexpr bool value_is_zero(const Number &value)
constexpr bool values_are_equal(const Number1 &value_1, const Number2 &value_2)
::VectorizedArray< Number, width > sqrt(const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > abs(const ::VectorizedArray< Number, width > &)
typename internal::ProductTypeImpl< std::decay_t< T >, std::decay_t< U > >::type type
static constexpr const T & value(const T &t)
decltype(std::declval< T >() *std::declval< U >()) type
static real_type abs(const number &x)
static constexpr real_type abs_square(const number &x)
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 > outer_product(const SymmetricTensor< 2, dim, Number > &t1, const SymmetricTensor< 2, dim, Number > &t2)
Tensor< 2, dim, Number > project_onto_orthogonal_tensors(const Tensor< 2, dim, Number > &A)
std::ostream & operator<<(std::ostream &out, const Tensor< rank_, dim, Number > &p)
constexpr Tensor< 0, dim, typename ProductType< Number, OtherNumber >::type > schur_product(const Tensor< 0, dim, Number > &src1, const Tensor< 0, dim, OtherNumber > &src2)
Number linfty_norm(const Tensor< 2, dim, Number > &t)
Number l1_norm(const Tensor< 2, dim, Number > &t)