15#ifndef dealii_tensor_h
16#define dealii_tensor_h
27#ifdef DEAL_II_WITH_ADOLC
28# include <adolc/adouble.h>
33#include <boost/version.hpp>
34#if BOOST_VERSION >= 106400
35# include <boost/serialization/array_wrapper.hpp>
37# include <boost/serialization/array.hpp>
50template <
typename ElementType,
typename MemorySpace>
53template <
int dim,
typename Number>
57template <
int rank_,
int dim, typename Number =
double>
59template <typename Number>
61template <typename number>
102template <
int dim,
typename Number>
106 static_assert(dim >= 0,
107 "Tensors must have a dimension greater than or equal to one.");
122 static constexpr unsigned int rank = 0;
167 template <
typename OtherNumber>
176 template <
typename OtherNumber>
180#ifdef DEAL_II_DELETED_MOVE_CONSTRUCTOR_BUG
223 template <
typename OtherNumber>
227#if defined(__INTEL_COMPILER) || defined(DEAL_II_DELETED_MOVE_CONSTRUCTOR_BUG)
240#ifdef DEAL_II_DELETED_MOVE_CONSTRUCTOR_BUG
254 template <
typename OtherNumber>
263 template <
typename OtherNumber>
270 template <
typename OtherNumber>
277 template <
typename OtherNumber>
286 template <
typename OtherNumber>
295 template <
typename OtherNumber>
304 template <
typename OtherNumber>
313 template <
typename OtherNumber>
364 template <
class Iterator>
366 unroll(
const Iterator begin,
const Iterator end)
const;
373 template <
class Archive>
390 template <
int,
int,
typename>
469template <
int rank_,
int dim,
typename Number>
473 static_assert(rank_ >= 1,
474 "Tensors must have a rank greater than or equal to one.");
475 static_assert(dim >= 0,
476 "Tensors must have a dimension greater than or equal to zero.");
490 static constexpr unsigned int rank = rank_;
515 std::conditional_t<rank_ == 1, Number,
Tensor<rank_ - 1, dim, Number>>;
530 Number[(dim != 0) ? dim : 1],
560 template <
typename ElementType,
typename MemorySpace>
571 template <
typename OtherNumber>
578 template <
typename OtherNumber>
585 template <
typename OtherNumber>
589#ifdef DEAL_II_DELETED_MOVE_CONSTRUCTOR_BUG
620 constexpr const Number &
632 DEAL_II_DEPRECATED_EARLY
639 DEAL_II_DEPRECATED_EARLY
646 DEAL_II_DEPRECATED_EARLY
653 DEAL_II_DEPRECATED_EARLY
664 template <
typename OtherNumber>
685#ifdef DEAL_II_DELETED_MOVE_CONSTRUCTOR_BUG
702 template <
typename OtherNumber>
709 template <
typename OtherNumber>
718 template <
typename OtherNumber>
727 template <
typename OtherNumber>
737 template <
typename OtherNumber>
746 template <
typename OtherNumber>
804 template <
typename OtherNumber>
818 template <
class Iterator>
820 unroll(
const Iterator begin,
const Iterator end)
const;
841 static constexpr std::size_t
849 template <
class Archive>
865 std::conditional_t<rank_ == 1,
866 std::array<Number, dim>,
867 std::array<
Tensor<rank_ - 1, dim, Number>, dim>>
876 template <
typename ArrayLike, std::size_t... Indices>
878 Tensor(
const ArrayLike &initializer, std::index_sequence<Indices...>);
881 template <
int,
int,
typename>
886 friend class Point<dim, Number>;
897 template <
int rank,
int dim,
typename T,
typename U>
898 struct ProductTypeImpl<
Tensor<rank, dim, T>,
std::complex<U>>
904 template <
int rank,
int dim,
typename T,
typename U>
905 struct ProductTypeImpl<
Tensor<rank, dim,
std::complex<T>>, std::complex<U>>
911 template <
typename T,
int rank,
int dim,
typename U>
912 struct ProductTypeImpl<
std::complex<T>,
Tensor<rank, dim, U>>
918 template <
int rank,
int dim,
typename T,
typename U>
919 struct ProductTypeImpl<
std::complex<T>,
Tensor<rank, dim, std::complex<U>>>
930 template <
int rank,
int dim,
typename T>
931 struct NumberType<
Tensor<rank, dim, T>>
954template <
int dim,
typename Number>
964template <
int dim,
typename Number>
965template <
typename OtherNumber>
973template <
int dim,
typename Number>
974template <
typename OtherNumber>
981# ifdef DEAL_II_DELETED_MOVE_CONSTRUCTOR_BUG
982template <
int dim,
typename Number>
990template <
int dim,
typename Number>
993 :
value{std::move(other.value)}
999template <
int dim,
typename Number>
1004 ExcMessage(
"Cannot access an object of type Tensor<0,0,Number>"));
1009template <
int dim,
typename Number>
1014 ExcMessage(
"Cannot access an object of type Tensor<0,0,Number>"));
1020template <
int dim,
typename Number>
1021template <
typename OtherNumber>
1030# if defined(__INTEL_COMPILER) || defined(DEAL_II_DELETED_MOVE_CONSTRUCTOR_BUG)
1031template <
int dim,
typename Number>
1040# ifdef DEAL_II_DELETED_MOVE_CONSTRUCTOR_BUG
1041template <
int dim,
typename Number>
1045 value = std::move(other.value);
1052template <
int dim,
typename Number>
1053template <
typename OtherNumber>
1062template <
int dim,
typename Number>
1063template <
typename OtherNumber>
1064constexpr inline bool
1067# ifdef DEAL_II_ADOLC_WITH_ADVANCED_BRANCHING
1068 Assert(!(std::is_same_v<Number, adouble> ||
1069 std::is_same_v<OtherNumber, adouble>),
1071 "The Tensor equality operator for ADOL-C taped numbers has not yet "
1072 "been extended to support advanced branching."));
1079template <
int dim,
typename Number>
1080template <
typename OtherNumber>
1084 return !((*this) == p);
1088template <
int dim,
typename Number>
1089template <
typename OtherNumber>
1098template <
int dim,
typename Number>
1099template <
typename OtherNumber>
1111 namespace ComplexWorkaround
1113 template <
typename Number,
typename OtherNumber>
1115 multiply_assign_scalar(Number &val,
const OtherNumber &s)
1120 template <
typename Number,
typename OtherNumber>
1122 multiply_assign_scalar(std::complex<Number> &val,
const OtherNumber &s)
1124# if KOKKOS_VERSION >= 30600
1125 KOKKOS_IF_ON_HOST((val *= s;))
1126 KOKKOS_IF_ON_DEVICE(({
1130 "This function is not implemented for std::complex<Number>!\n");
1133# ifdef KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST
1139 "This function is not implemented for std::complex<Number>!\n");
1147template <
int dim,
typename Number>
1148template <
typename OtherNumber>
1152 internal::ComplexWorkaround::multiply_assign_scalar(value, s);
1158template <
int dim,
typename Number>
1159template <
typename OtherNumber>
1168template <
int dim,
typename Number>
1176template <
int dim,
typename Number>
1181 ExcMessage(
"Cannot access an object of type Tensor<0,0,Number>"));
1186template <
int dim,
typename Number>
1192 ExcMessage(
"Cannot access an object of type Tensor<0,0,Number>"));
1198template <
int dim,
typename Number>
1199constexpr inline void
1209template <
int dim,
typename Number>
1210template <
class Iterator>
1217 ExcMessage(
"Cannot unroll an object of type Tensor<0,0,Number>"));
1218 Assert(std::distance(begin, end) >= 1,
1219 ExcMessage(
"The provided iterator range must contain at least one "
1226template <
int dim,
typename Number>
1227template <
class Archive>
1235template <
int dim,
typename Number>
1241template <
int rank_,
int dim,
typename Number>
1242template <
typename ArrayLike, std::size_t... indices>
1245 std::index_sequence<indices...>)
1261 : values{{([&initializer]() -> value_type {
1262 if constexpr (rank_ == 1)
1268 static_assert(
sizeof...(indices) == dim,
1269 "dim should match the number of indices");
1273# ifdef DEAL_II_HAVE_CXX20
1275template <
int rank_,
int dim,
typename Number>
1310 []<
std::size_t... I>(
1311 const
std::index_sequence<I...> &) constexpr -> decltype(values) {
1312 if constexpr (rank_ == 1)
1314 auto get_zero_and_ignore_argument = [](
int) {
1317 return {{(get_zero_and_ignore_argument(I))...}};
1321 auto get_zero_and_ignore_argument = [](
int) {
1322 return Tensor<rank_ - 1, dim, Number>();
1324 return {{(get_zero_and_ignore_argument(I))...}};
1326 }(std::make_index_sequence<dim>()))
1342 namespace TensorInitialization
1344 template <
int rank,
int dim,
typename Number, std::size_t... I>
1345 constexpr std::array<typename Tensor<rank, dim, Number>::value_type, dim>
1346 make_zero_array(
const std::index_sequence<I...> &)
1348 static_assert(
sizeof...(I) == dim,
"This is bad.");
1354 if constexpr (dim == 0)
1358 else if constexpr (rank == 1)
1360 auto get_zero_and_ignore_argument = [](
int) {
1363 return {{(get_zero_and_ignore_argument(I))...}};
1367 auto get_zero_and_ignore_argument = [](
int) {
1368 return Tensor<rank - 1, dim, Number>();
1370 return {{(get_zero_and_ignore_argument(I))...}};
1377template <
int rank_,
int dim,
typename Number>
1380 : values(
internal::TensorInitialization::make_zero_array<rank_, dim, Number>(
1381 std::make_index_sequence<dim>()))
1388template <
int rank_,
int dim,
typename Number>
1391 :
Tensor(initializer,
std::make_index_sequence<dim>{})
1396template <
int rank_,
int dim,
typename Number>
1397template <
typename ElementType,
typename MemorySpace>
1403 const int my_n_independent_components = n_independent_components;
1406 for (
unsigned int i = 0; i < my_n_independent_components; ++i)
1407 (*
this)[unrolled_to_component_indices(i)] = initializer[i];
1412template <
int rank_,
int dim,
typename Number>
1413template <
typename OtherNumber>
1417 :
Tensor(initializer,
std::make_index_sequence<dim>{})
1422template <
int rank_,
int dim,
typename Number>
1423template <
typename OtherNumber>
1427 :
Tensor(initializer,
std::make_index_sequence<dim>{})
1432template <
int rank_,
int dim,
typename Number>
1433template <
typename OtherNumber>
1435operator
Tensor<1, dim,
Tensor<rank_ - 1, dim, OtherNumber>>()
const
1438 std::copy(values.begin(), values.end(), x.values.begin());
1443# ifdef DEAL_II_DELETED_MOVE_CONSTRUCTOR_BUG
1444template <
int rank_,
int dim,
typename Number>
1447 : values(other.values)
1452template <
int rank_,
int dim,
typename Number>
1455 : values(std::move(other.values))
1461template <
int rank_,
int dim,
typename Number>
1467 ExcMessage(
"Cannot access an object of type Tensor<rank_,0,Number>"));
1475template <
int rank_,
int dim,
typename Number>
1481 ExcMessage(
"Cannot access an object of type Tensor<rank_,0,Number>"));
1489template <
int rank_,
int dim,
typename Number>
1494 ExcMessage(
"Cannot access an object of type Tensor<rank_,0,Number>"));
1501template <
int rank_,
int dim,
typename Number>
1506 ExcMessage(
"Cannot access an object of type Tensor<rank_,0,Number>"));
1513template <
int rank_,
int dim,
typename Number>
1517 static_assert(rank_ == 1,
1518 "This function is only available for rank-1 tensors "
1519 "because higher-rank tensors may not store their elements "
1520 "in a contiguous array.");
1522 return std::addressof(
1523 this->
operator[](this->unrolled_to_component_indices(0)));
1528template <
int rank_,
int dim,
typename Number>
1529inline const Number *
1532 static_assert(rank_ == 1,
1533 "This function is only available for rank-1 tensors "
1534 "because higher-rank tensors may not store their elements "
1535 "in a contiguous array.");
1537 return std::addressof(
1538 this->
operator[](this->unrolled_to_component_indices(0)));
1543template <
int rank_,
int dim,
typename Number>
1547 static_assert(rank_ == 1,
1548 "This function is only available for rank-1 tensors "
1549 "because higher-rank tensors may not store their elements "
1550 "in a contiguous array.");
1552 return begin_raw() + n_independent_components;
1557template <
int rank_,
int dim,
typename Number>
1558inline const Number *
1561 static_assert(rank_ == 1,
1562 "This function is only available for rank-1 tensors "
1563 "because higher-rank tensors may not store their elements "
1564 "in a contiguous array.");
1566 return begin_raw() + n_independent_components;
1571template <
int rank_,
int dim,
typename Number>
1572template <
typename OtherNumber>
1578 for (
unsigned int i = 0; i < dim; ++i)
1585template <
int rank_,
int dim,
typename Number>
1593 for (
unsigned int i = 0; i < dim; ++i)
1599# ifdef DEAL_II_DELETED_MOVE_CONSTRUCTOR_BUG
1600template <
int rank_,
int dim,
typename Number>
1604 for (
unsigned int i = 0; i < dim; ++i)
1605 values[i] = other.
values[i];
1611template <
int rank_,
int dim,
typename Number>
1616 for (
unsigned int i = 0; i < dim; ++i)
1617 values[i] = other.
values[i];
1623template <
int rank_,
int dim,
typename Number>
1624template <
typename OtherNumber>
1625constexpr inline bool
1629# ifdef DEAL_II_ADOLC_WITH_ADVANCED_BRANCHING
1630 Assert(!(std::is_same_v<Number, adouble> ||
1631 std::is_same_v<OtherNumber, adouble>),
1633 "The Tensor equality operator for ADOL-C taped numbers has not yet "
1634 "been extended to support advanced branching."));
1637 for (
unsigned int i = 0; i < dim; ++i)
1651constexpr inline bool
1658template <
int rank_,
int dim,
typename Number>
1659template <
typename OtherNumber>
1664 return !((*this) == p);
1668template <
int rank_,
int dim,
typename Number>
1669template <
typename OtherNumber>
1675 for (
unsigned int i = 0; i < dim; ++i)
1676 values[i] += p.
values[i];
1681template <
int rank_,
int dim,
typename Number>
1682template <
typename OtherNumber>
1688 for (
unsigned int i = 0; i < dim; ++i)
1689 values[i] -= p.
values[i];
1694template <
int rank_,
int dim,
typename Number>
1695template <
typename OtherNumber>
1700 for (
unsigned int i = 0; i < dim; ++i)
1707template <
int rank_,
int dim,
typename Number>
1708template <
typename OtherNumber>
1713 if constexpr (std::is_integral<
1715 std::is_same_v<Number, Differentiation::SD::Expression>)
1718 for (
unsigned int d = 0;
d < dim; ++
d)
1725 const Number inverse_factor = Number(1.) / s;
1726 for (
unsigned int d = 0;
d < dim; ++
d)
1727 values[d] *= inverse_factor;
1734template <
int rank_,
int dim,
typename Number>
1741 for (
unsigned int i = 0; i < dim; ++i)
1742 tmp.
values[i] = -values[i];
1748template <
int rank_,
int dim,
typename Number>
1754 if constexpr ((rank_ == 1) && (dim == 1) && std::is_arithmetic_v<Number>)
1758 else if constexpr ((rank_ == 2) && (dim == 1) && std::is_arithmetic_v<Number>)
1771 return sqrt(norm_square());
1776template <
int rank_,
int dim,
typename Number>
1781 if constexpr (dim == 0)
1784 else if constexpr (rank_ == 1)
1790 for (
unsigned int i = 1; i < dim; ++i)
1800 values[0].norm_square();
1801 for (
unsigned int i = 1; i < dim; ++i)
1802 s += values[i].norm_square();
1810template <
int rank_,
int dim,
typename Number>
1811template <
typename OtherNumber>
1815 unroll(result.
begin(), result.
end());
1820template <
int rank_,
int dim,
typename Number>
1821template <
class Iterator>
1824 const Iterator end)
const
1826 if constexpr (rank_ > 1)
1829 Iterator next =
begin;
1830 for (
unsigned int i = 0; i < dim; ++i)
1832 values[i].unroll(next, end);
1842 Assert(std::distance(begin, end) >= dim,
1844 "The provided iterator range must contain at least 'dim' "
1846 std::copy(std::begin(values), std::end(values), begin);
1852template <
int rank_,
int dim,
typename Number>
1853constexpr inline unsigned int
1857 unsigned int index = 0;
1858 for (
int r = 0; r < rank_; ++r)
1859 index = index * dim + indices[r];
1866template <
int rank_,
int dim,
typename Number>
1871 unsigned int dummy = n_independent_components;
1875 if constexpr (dim == 0)
1879 "A tensor with dimension 0 does not store any elements. "
1880 "There is no indexing that can address its elements."));
1887 unsigned int remainder = i;
1888 for (
int r = rank_ - 1; r >= 0; --r)
1890 indices[r] = remainder % dim;
1891 remainder = remainder / dim;
1900template <
int rank_,
int dim,
typename Number>
1901constexpr inline void
1904 for (
unsigned int i = 0; i < dim; ++i)
1909template <
int rank_,
int dim,
typename Number>
1910constexpr std::size_t
1917template <
int rank_,
int dim,
typename Number>
1918template <
class Archive>
1922 if constexpr (rank_ > 1)
1925 ar &boost::serialization::make_array(&values[0], dim);
1929template <
int rank_,
int dim,
typename Number>
1948template <
int rank_,
int dim,
typename Number>
1949inline std::ostream &
1952 for (
unsigned int i = 0; i < dim; ++i)
1956 for (
unsigned int j = 0; j < rank_; ++j)
1970template <
int dim,
typename Number>
1971inline std::ostream &
1974 out << static_cast<const Number &>(p);
1997template <
int dim,
typename Number,
typename Other>
2002 return object *
static_cast<const Number &
>(t);
2017template <
int dim,
typename Number,
typename Other>
2022 return static_cast<const Number &
>(t) *
object;
2037template <
int dim,
typename Number,
typename OtherNumber>
2043 return static_cast<const Number &
>(src1) *
2044 static_cast<const OtherNumber &
>(src2);
2055template <
int dim,
typename Number,
typename OtherNumber>
2063 return static_cast<const Number &
>(t) / factor;
2074template <
int dim,
typename Number,
typename OtherNumber>
2080 return static_cast<const Number &
>(p) +
static_cast<const OtherNumber &
>(q);
2091template <
int dim,
typename Number,
typename OtherNumber>
2097 return static_cast<const Number &
>(p) -
static_cast<const OtherNumber &
>(q);
2113template <
int rank,
int dim,
typename Number,
typename OtherNumber>
2139template <
int rank,
int dim,
typename Number,
typename OtherNumber>
2162template <
int rank,
int dim,
typename Number,
typename OtherNumber>
2185template <
int rank,
int dim,
typename Number,
typename OtherNumber>
2206template <
int rank,
int dim,
typename Number,
typename OtherNumber>
2223template <
int dim,
typename Number,
typename OtherNumber>
2252template <
int rank,
int dim,
typename Number,
typename OtherNumber>
2260 for (
unsigned int i = 0; i < dim; ++i)
2311template <
int rank_1,
2315 typename OtherNumber,
2316 typename = std::enable_if_t<rank_1 >= 1 && rank_2 >= 1>>
2318 typename Tensor<rank_1 + rank_2 - 2,
2330 if constexpr ((rank_1 == 1) && (rank_2 == 1))
2334 static_assert(dim > 0,
"Tensors cannot have dimension zero.");
2336 for (
unsigned int i = 1; i < dim; ++i)
2337 sum += src1[i] * src2[i];
2341 else if constexpr ((rank_1 == 2) && (rank_2 == 1))
2347 rank_1 + rank_2 - 2,
2350 for (
unsigned int i = 0; i < dim; ++i)
2351 result[i] += src1[i] * src2;
2360 rank_1 + rank_2 - 2,
2364 TensorAccessors::internal::
2365 ReorderedIndexView<0, rank_2, const Tensor<rank_2, dim, OtherNumber>>
2404template <
int index_1,
2410 typename OtherNumber>
2412 typename Tensor<rank_1 + rank_2 - 2,
2418 Assert(0 <= index_1 && index_1 < rank_1,
2420 "The specified index_1 must lie within the range [0,rank_1)"));
2421 Assert(0 <= index_2 && index_2 < rank_2,
2423 "The specified index_2 must lie within the range [0,rank_2)"));
2430 reord_01 = reordered_index_view<index_1, rank_1>(src1);
2436 reord_02 = reordered_index_view<index_2, rank_2>(src2);
2438 typename Tensor<rank_1 + rank_2 - 2,
2477template <
int index_1,
2485 typename OtherNumber>
2487 typename Tensor<rank_1 + rank_2 - 4,
2493 Assert(0 <= index_1 && index_1 < rank_1,
2495 "The specified index_1 must lie within the range [0,rank_1)"));
2496 Assert(0 <= index_3 && index_3 < rank_1,
2498 "The specified index_3 must lie within the range [0,rank_1)"));
2499 Assert(index_1 != index_3,
2500 ExcMessage(
"index_1 and index_3 must not be the same"));
2501 Assert(0 <= index_2 && index_2 < rank_2,
2503 "The specified index_2 must lie within the range [0,rank_2)"));
2504 Assert(0 <= index_4 && index_4 < rank_2,
2506 "The specified index_4 must lie within the range [0,rank_2)"));
2507 Assert(index_2 != index_4,
2508 ExcMessage(
"index_2 and index_4 must not be the same"));
2525 (index_3 < index_1 ? index_3 : index_3 - 1),
2537 (index_4 < index_2 ? index_4 : index_4 - 1),
2545 typename Tensor<rank_1 + rank_2 - 4,
2566template <
int rank,
int dim,
typename Number,
typename OtherNumber>
2595template <
template <
int,
int,
typename>
class TensorT1,
2596 template <
int,
int,
typename>
2598 template <
int,
int,
typename>
2608 contract3(
const TensorT1<rank_1, dim, T1> &left,
2609 const TensorT2<rank_1 + rank_2, dim, T2> &middle,
2610 const TensorT3<rank_2, dim, T3> &right)
2630template <
int rank_1,
2634 typename OtherNumber>
2640 typename Tensor<rank_1 + rank_2,
2667template <
int dim,
typename Number>
2676 result[1] = -src[0];
2691template <
int dim,
typename Number1,
typename Number2>
2702 constexpr int s0 = 0 % dim;
2703 constexpr int s1 = 1 % dim;
2704 constexpr int s2 = 2 % dim;
2706 result[s0] = src1[s1] * src2[s2] - src1[s2] * src2[s1];
2707 result[s1] = src1[s2] * src2[s0] - src1[s0] * src2[s2];
2708 result[s2] = src1[s0] * src2[s1] - src1[s1] * src2[s0];
2727template <
int dim,
typename Number>
2735 for (
unsigned int k = 0; k < dim; ++k)
2737 Tensor<2, dim - 1, Number> minor;
2738 for (
unsigned int i = 0; i < dim - 1; ++i)
2739 for (
unsigned int j = 0; j < dim - 1; ++j)
2740 minor[i][j] = t[i][j < k ? j : j + 1];
2742 const Number cofactor = ((k % 2 == 0) ? -1. : 1.) *
determinant(minor);
2744 det += t[dim - 1][k] * cofactor;
2747 return ((dim % 2 == 0) ? 1. : -1.) * det;
2755template <
typename Number>
2767template <
typename Number>
2772 return t[0][0] * t[1][1] - t[1][0] * t[0][1];
2780template <
typename Number>
2791 return t[0][0] * C0 + t[0][1] * C1 + t[0][2] * C2;
2801template <
int dim,
typename Number>
2806 for (
unsigned int i = 1; i < dim; ++i)
2820template <
int dim,
typename Number>
2824 Number return_tensor[dim][dim];
2837template <
typename Number>
2845 return return_tensor;
2849template <
typename Number>
2856 1.0 / (t[0][0] * t[1][1] - t[1][0] * t[0][1]));
2857 return_tensor[0][0] = t[1][1];
2858 return_tensor[0][1] = -t[0][1];
2859 return_tensor[1][0] = -t[1][0];
2860 return_tensor[1][1] = t[0][0];
2861 return_tensor *= inv_det_t;
2863 return return_tensor;
2866template <
typename Number>
2872 const auto value = [](
const auto &t) {
2876 return_tensor[0][0] =
value(t[1][1] * t[2][2]) -
value(t[1][2] * t[2][1]);
2877 return_tensor[0][1] =
value(t[0][2] * t[2][1]) -
value(t[0][1] * t[2][2]);
2878 return_tensor[0][2] =
value(t[0][1] * t[1][2]) -
value(t[0][2] * t[1][1]);
2879 return_tensor[1][0] =
value(t[1][2] * t[2][0]) -
value(t[1][0] * t[2][2]);
2880 return_tensor[1][1] =
value(t[0][0] * t[2][2]) -
value(t[0][2] * t[2][0]);
2881 return_tensor[1][2] =
value(t[0][2] * t[1][0]) -
value(t[0][0] * t[1][2]);
2882 return_tensor[2][0] =
value(t[1][0] * t[2][1]) -
value(t[1][1] * t[2][0]);
2883 return_tensor[2][1] =
value(t[0][1] * t[2][0]) -
value(t[0][0] * t[2][1]);
2884 return_tensor[2][2] =
value(t[0][0] * t[1][1]) -
value(t[0][1] * t[1][0]);
2886 const Number inv_det_t =
2887 value(1.0 / (t[0][0] * return_tensor[0][0] + t[0][1] * return_tensor[1][0] +
2888 t[0][2] * return_tensor[2][0]));
2889 return_tensor *= inv_det_t;
2891 return return_tensor;
2902template <
int dim,
typename Number>
2907 for (
unsigned int i = 0; i < dim; ++i)
2910 for (
unsigned int j = i + 1; j < dim; ++j)
2933template <
int dim,
typename Number>
2954template <
int dim,
typename Number>
3025template <
int dim,
typename Number>
3037template <
int dim,
typename Number>
3042 for (
unsigned int j = 0; j < dim; ++j)
3045 for (
unsigned int i = 0; i < dim; ++i)
3063template <
int dim,
typename Number>
3068 for (
unsigned int i = 0; i < dim; ++i)
3071 for (
unsigned int j = 0; j < dim; ++j)
3089# ifdef DEAL_II_ADOLC_WITH_ADVANCED_BRANCHING
3098 for (
unsigned int j = 0; j < dim; ++j)
3101 for (
unsigned int i = 0; i < dim; ++i)
3102 sum += fabs(t[i][j]);
3104 condassign(max, (sum > max), sum, max);
3116 for (
unsigned int i = 0; i < dim; ++i)
3119 for (
unsigned int j = 0; j < dim; ++j)
3120 sum +=
fabs(t[i][j]);
3122 condassign(max, (sum > max), sum, max);
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
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 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
std::conditional_t< rank_==1, Number, Tensor< rank_ - 1, dim, Number > > value_type
constexpr Tensor(const Tensor< rank_, dim, OtherNumber > &initializer)
numbers::NumberTraits< Number >::real_type norm() const
constexpr Tensor & operator-=(const Tensor< rank_, dim, OtherNumber > &)
void unroll(const Iterator begin, const Iterator end) const
void unroll(Vector< OtherNumber > &result) 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
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 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Tensor< 0, dim, typename ProductType< Number, OtherNumber >::type > operator-(const Tensor< 0, dim, Number > &p, const Tensor< 0, dim, OtherNumber > &q)
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)
constexpr DEAL_II_HOST_DEVICE_ALWAYS_INLINE Tensor()
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 & operator+=(const Tensor< rank_, dim, OtherNumber > &)
constexpr DEAL_II_HOST_DEVICE_ALWAYS_INLINE Tensor< 0, dim, typename ProductType< Number, OtherNumber >::type > operator+(const Tensor< 0, dim, Number > &p, const Tensor< 0, dim, OtherNumber > &q)
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_NAMESPACE_CLOSE
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)
constexpr ReturnType< rank, T >::value_type & extract(T &t, const ArrayType &indices)
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)
VectorType::value_type * begin(VectorType &V)
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 > &)
#define DEAL_II_HOST_DEVICE
#define DEAL_II_HOST_DEVICE_ALWAYS_INLINE
typename internal::ProductTypeImpl< std::decay_t< T >, std::decay_t< U > >::type type
static constexpr DEAL_II_HOST_DEVICE_ALWAYS_INLINE const T & value(const T &t)
static real_type abs(const number &x)
static constexpr real_type abs_square(const number &x)
DEAL_II_HOST constexpr Number determinant(const SymmetricTensor< 2, dim, Number > &)
DEAL_II_HOST constexpr SymmetricTensor< 2, dim, Number > invert(const SymmetricTensor< 2, dim, Number > &)
DEAL_II_HOST constexpr SymmetricTensor< 4, dim, Number > outer_product(const SymmetricTensor< 2, dim, Number > &t1, const SymmetricTensor< 2, dim, Number > &t2)
DEAL_II_HOST constexpr Number trace(const SymmetricTensor< 2, dim2, Number > &)
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)
constexpr ProductType< Other, Number >::type operator*(const Other &object, const Tensor< 0, dim, Number > &t)
Number l1_norm(const Tensor< 2, dim, Number > &t)