15#ifndef dealii_tensor_h
16#define dealii_tensor_h
27#include <Kokkos_Array.hpp>
29#ifdef DEAL_II_WITH_ADOLC
30# include <adolc/adouble.h>
42template <
typename ElementType,
typename MemorySpace>
45template <
int dim,
typename Number>
49template <
int rank_,
int dim, typename Number =
double>
51template <typename Number>
53template <typename number>
94template <
int dim,
typename Number>
98 static_assert(dim >= 0,
99 "Tensors must have a dimension greater than or equal to one.");
114 static constexpr unsigned int rank = 0;
159 template <
typename OtherNumber>
168 template <
typename OtherNumber>
172#ifdef DEAL_II_DELETED_MOVE_CONSTRUCTOR_BUG
215 template <
typename OtherNumber>
219#if defined(__INTEL_COMPILER) || defined(DEAL_II_DELETED_MOVE_CONSTRUCTOR_BUG)
232#ifdef DEAL_II_DELETED_MOVE_CONSTRUCTOR_BUG
246 template <
typename OtherNumber>
255 template <
typename OtherNumber>
262 template <
typename OtherNumber>
269 template <
typename OtherNumber>
278 template <
typename OtherNumber>
287 template <
typename OtherNumber>
296 template <
typename OtherNumber>
305 template <
typename OtherNumber>
356 template <
class Iterator>
358 unroll(
const Iterator begin,
const Iterator end)
const;
365 template <
class Archive>
382 template <
int,
int,
typename>
461template <
int rank_,
int dim,
typename Number>
465 static_assert(rank_ >= 1,
466 "Tensors must have a rank greater than or equal to one.");
467 static_assert(dim >= 0,
468 "Tensors must have a dimension greater than or equal to zero.");
482 static constexpr unsigned int rank = rank_;
507 std::conditional_t<rank_ == 1, Number,
Tensor<rank_ - 1, dim, Number>>;
522 Number[(dim != 0) ? dim : 1],
552 template <
typename ElementType,
typename MemorySpace>
563 template <
typename OtherNumber>
570 template <
typename OtherNumber>
577 template <
typename OtherNumber>
581#ifdef DEAL_II_DELETED_MOVE_CONSTRUCTOR_BUG
612 constexpr const Number &
656 template <
typename OtherNumber>
677#ifdef DEAL_II_DELETED_MOVE_CONSTRUCTOR_BUG
694 template <
typename OtherNumber>
701 template <
typename OtherNumber>
710 template <
typename OtherNumber>
719 template <
typename OtherNumber>
729 template <
typename OtherNumber>
738 template <
typename OtherNumber>
796 template <
class Iterator>
798 unroll(
const Iterator begin,
const Iterator end)
const;
819 static constexpr std::size_t
827 template <
class Archive>
843#if DEAL_II_KOKKOS_VERSION_GTE(3, 7, 0)
844 std::conditional_t<rank_ == 1,
845 Kokkos::Array<Number, dim>,
846 Kokkos::Array<
Tensor<rank_ - 1, dim, Number>, dim>>
848 std::conditional_t<rank_ == 1,
849 std::array<Number, dim>,
850 std::array<
Tensor<rank_ - 1, dim, Number>, dim>>
860 template <
typename ArrayLike, std::size_t... Indices>
862 Tensor(
const ArrayLike &initializer, std::index_sequence<Indices...>);
865 template <
int,
int,
typename>
870 friend class Point<dim, Number>;
881 template <
int rank,
int dim,
typename T,
typename U>
882 struct ProductTypeImpl<
Tensor<rank, dim, T>,
std::complex<U>>
888 template <
int rank,
int dim,
typename T,
typename U>
889 struct ProductTypeImpl<Tensor<rank, dim, std::complex<T>>, std::complex<U>>
892 Tensor<rank, dim, std::complex<typename ProductType<T, U>::type>>;
895 template <
typename T,
int rank,
int dim,
typename U>
899 Tensor<rank, dim, std::complex<typename ProductType<T, U>::type>>;
902 template <
int rank,
int dim,
typename T,
typename U>
903 struct ProductTypeImpl<std::complex<T>, Tensor<rank, dim, std::complex<U>>>
906 Tensor<rank, dim, std::complex<typename ProductType<T, U>::type>>;
914 template <
int rank,
int dim,
typename T>
918 Tensor<rank, dim, T> &
919 value(
const Tensor<rank, dim, T> &t)
927 Tensor<rank, dim, T> tmp;
938template <
int dim,
typename Number>
948template <
int dim,
typename Number>
949template <
typename OtherNumber>
957template <
int dim,
typename Number>
958template <
typename OtherNumber>
965# ifdef DEAL_II_DELETED_MOVE_CONSTRUCTOR_BUG
966template <
int dim,
typename Number>
974template <
int dim,
typename Number>
977 :
value{std::move(other.value)}
983template <
int dim,
typename Number>
988 ExcMessage(
"Cannot access an object of type Tensor<0,0,Number>"));
993template <
int dim,
typename Number>
998 ExcMessage(
"Cannot access an object of type Tensor<0,0,Number>"));
1004template <
int dim,
typename Number>
1005template <
typename OtherNumber>
1014# if defined(__INTEL_COMPILER) || defined(DEAL_II_DELETED_MOVE_CONSTRUCTOR_BUG)
1015template <
int dim,
typename Number>
1024# ifdef DEAL_II_DELETED_MOVE_CONSTRUCTOR_BUG
1025template <
int dim,
typename Number>
1029 value = std::move(other.value);
1036template <
int dim,
typename Number>
1037template <
typename OtherNumber>
1046template <
int dim,
typename Number>
1047template <
typename OtherNumber>
1048constexpr inline bool
1051# ifdef DEAL_II_ADOLC_WITH_ADVANCED_BRANCHING
1052 Assert(!(std::is_same_v<Number, adouble> ||
1053 std::is_same_v<OtherNumber, adouble>),
1055 "The Tensor equality operator for ADOL-C taped numbers has not yet "
1056 "been extended to support advanced branching."));
1063template <
int dim,
typename Number>
1064template <
typename OtherNumber>
1068 return !((*this) == p);
1072template <
int dim,
typename Number>
1073template <
typename OtherNumber>
1082template <
int dim,
typename Number>
1083template <
typename OtherNumber>
1095 namespace ComplexWorkaround
1097 template <
typename Number,
typename OtherNumber>
1099 multiply_assign_scalar(Number &val,
const OtherNumber &s)
1104 template <
typename Number,
typename OtherNumber>
1106 multiply_assign_scalar(std::complex<Number> &val,
const OtherNumber &s)
1108# if DEAL_II_KOKKOS_VERSION_GTE(3, 6, 0)
1109 KOKKOS_IF_ON_HOST((val *= s;))
1110 KOKKOS_IF_ON_DEVICE(({
1114 "This function is not implemented for std::complex<Number>!\n");
1117# ifdef KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST
1123 "This function is not implemented for std::complex<Number>!\n");
1131template <
int dim,
typename Number>
1132template <
typename OtherNumber>
1136 internal::ComplexWorkaround::multiply_assign_scalar(
value, s);
1142template <
int dim,
typename Number>
1143template <
typename OtherNumber>
1152template <
int dim,
typename Number>
1160template <
int dim,
typename Number>
1165 ExcMessage(
"Cannot access an object of type Tensor<0,0,Number>"));
1170template <
int dim,
typename Number>
1176 ExcMessage(
"Cannot access an object of type Tensor<0,0,Number>"));
1182template <
int dim,
typename Number>
1183constexpr inline void
1193template <
int dim,
typename Number>
1194template <
class Iterator>
1200 ExcMessage(
"Cannot unroll an object of type Tensor<0,0,Number>"));
1201 Assert(std::distance(begin, end) >= 1,
1202 ExcMessage(
"The provided iterator range must contain at least one "
1209template <
int dim,
typename Number>
1210template <
class Archive>
1218template <
int dim,
typename Number>
1224template <
int rank_,
int dim,
typename Number>
1225template <
typename ArrayLike, std::size_t... indices>
1228 std::index_sequence<indices...>)
1245 if constexpr (rank_ == 1)
1251 static_assert(
sizeof...(indices) == dim,
1252 "dim should match the number of indices");
1256# if defined(DEAL_II_HAVE_CXX20) && !defined(__NVCC__)
1258template <
int rank_,
int dim,
typename Number>
1293 []<
std::size_t... I>(
1294 const
std::index_sequence<I...> &) constexpr -> decltype(values) {
1295 if constexpr (dim == 0)
1299 else if constexpr (rank_ == 1)
1301 auto get_zero_and_ignore_argument = [](int) {
1304 return {{(get_zero_and_ignore_argument(I))...}};
1308 auto get_zero_and_ignore_argument = [](int) {
1309 return Tensor<rank_ - 1, dim, Number>();
1311 return {{(get_zero_and_ignore_argument(I))...}};
1313 }(std::make_index_sequence<dim>()))
1329 namespace TensorInitialization
1331 template <
int rank,
int dim,
typename Number, std::size_t... I>
1332# if DEAL_II_KOKKOS_VERSION_GTE(3, 7, 0)
1333 constexpr Kokkos::Array<typename Tensor<rank, dim, Number>::value_type, dim>
1335 constexpr std::array<typename Tensor<rank, dim, Number>::value_type, dim>
1337 make_zero_array(
const std::index_sequence<I...> &)
1339 static_assert(
sizeof...(I) == dim,
"This is bad.");
1345 if constexpr (dim == 0)
1349 else if constexpr (rank == 1)
1351 auto get_zero_and_ignore_argument = [](int) {
1354 return {{(get_zero_and_ignore_argument(I))...}};
1358 auto get_zero_and_ignore_argument = [](int) {
1359 return Tensor<rank - 1, dim, Number>();
1361 return {{(get_zero_and_ignore_argument(I))...}};
1368template <
int rank_,
int dim,
typename Number>
1371 : values(
internal::TensorInitialization::make_zero_array<rank_, dim, Number>(
1372 std::make_index_sequence<dim>()))
1379template <
int rank_,
int dim,
typename Number>
1382 :
Tensor(initializer,
std::make_index_sequence<dim>{})
1387template <
int rank_,
int dim,
typename Number>
1388template <
typename ElementType,
typename MemorySpace>
1394 const int my_n_independent_components = n_independent_components;
1397 for (
unsigned int i = 0; i < my_n_independent_components; ++i)
1398 (*
this)[unrolled_to_component_indices(i)] = initializer[i];
1403template <
int rank_,
int dim,
typename Number>
1404template <
typename OtherNumber>
1408 :
Tensor(initializer,
std::make_index_sequence<dim>{})
1413template <
int rank_,
int dim,
typename Number>
1414template <
typename OtherNumber>
1418 :
Tensor(initializer,
std::make_index_sequence<dim>{})
1423template <
int rank_,
int dim,
typename Number>
1424template <
typename OtherNumber>
1426operator
Tensor<1, dim,
Tensor<rank_ - 1, dim, OtherNumber>>()
const
1429 std::copy(values.data(), values.data() + values.size(), x.values.data());
1434# ifdef DEAL_II_DELETED_MOVE_CONSTRUCTOR_BUG
1435template <
int rank_,
int dim,
typename Number>
1438 : values(other.values)
1443template <
int rank_,
int dim,
typename Number>
1446 : values(std::move(other.values))
1452template <
int rank_,
int dim,
typename Number>
1458 ExcMessage(
"Cannot access an object of type Tensor<rank_,0,Number>"));
1466template <
int rank_,
int dim,
typename Number>
1472 ExcMessage(
"Cannot access an object of type Tensor<rank_,0,Number>"));
1480template <
int rank_,
int dim,
typename Number>
1485 ExcMessage(
"Cannot access an object of type Tensor<rank_,0,Number>"));
1492template <
int rank_,
int dim,
typename Number>
1497 ExcMessage(
"Cannot access an object of type Tensor<rank_,0,Number>"));
1504template <
int rank_,
int dim,
typename Number>
1508 static_assert(rank_ == 1,
1509 "This function is only available for rank-1 tensors "
1510 "because higher-rank tensors may not store their elements "
1511 "in a contiguous array.");
1513 return std::addressof(
1514 this->
operator[](this->unrolled_to_component_indices(0)));
1519template <
int rank_,
int dim,
typename Number>
1520inline const Number *
1523 static_assert(rank_ == 1,
1524 "This function is only available for rank-1 tensors "
1525 "because higher-rank tensors may not store their elements "
1526 "in a contiguous array.");
1528 return std::addressof(
1529 this->
operator[](this->unrolled_to_component_indices(0)));
1534template <
int rank_,
int dim,
typename Number>
1538 static_assert(rank_ == 1,
1539 "This function is only available for rank-1 tensors "
1540 "because higher-rank tensors may not store their elements "
1541 "in a contiguous array.");
1543 return begin_raw() + n_independent_components;
1548template <
int rank_,
int dim,
typename Number>
1549inline const Number *
1552 static_assert(rank_ == 1,
1553 "This function is only available for rank-1 tensors "
1554 "because higher-rank tensors may not store their elements "
1555 "in a contiguous array.");
1557 return begin_raw() + n_independent_components;
1562template <
int rank_,
int dim,
typename Number>
1563template <
typename OtherNumber>
1569 for (
unsigned int i = 0; i < dim; ++i)
1576template <
int rank_,
int dim,
typename Number>
1583 for (
unsigned int i = 0; i < dim; ++i)
1589# ifdef DEAL_II_DELETED_MOVE_CONSTRUCTOR_BUG
1590template <
int rank_,
int dim,
typename Number>
1594 for (
unsigned int i = 0; i < dim; ++i)
1595 values[i] = other.
values[i];
1601template <
int rank_,
int dim,
typename Number>
1606 for (
unsigned int i = 0; i < dim; ++i)
1607 values[i] = other.values[i];
1613template <
int rank_,
int dim,
typename Number>
1614template <
typename OtherNumber>
1615constexpr inline bool
1619# ifdef DEAL_II_ADOLC_WITH_ADVANCED_BRANCHING
1620 Assert(!(std::is_same_v<Number, adouble> ||
1621 std::is_same_v<OtherNumber, adouble>),
1623 "The Tensor equality operator for ADOL-C taped numbers has not yet "
1624 "been extended to support advanced branching."));
1627 for (
unsigned int i = 0; i < dim; ++i)
1641constexpr inline bool
1648template <
int rank_,
int dim,
typename Number>
1649template <
typename OtherNumber>
1654 return !((*this) == p);
1658template <
int rank_,
int dim,
typename Number>
1659template <
typename OtherNumber>
1665 for (
unsigned int i = 0; i < dim; ++i)
1666 values[i] += p.
values[i];
1671template <
int rank_,
int dim,
typename Number>
1672template <
typename OtherNumber>
1678 for (
unsigned int i = 0; i < dim; ++i)
1679 values[i] -= p.
values[i];
1684template <
int rank_,
int dim,
typename Number>
1685template <
typename OtherNumber>
1690 for (
unsigned int i = 0; i < dim; ++i)
1697template <
int rank_,
int dim,
typename Number>
1698template <
typename OtherNumber>
1703 if constexpr (std::is_integral_v<
1705 std::is_same_v<Number, Differentiation::SD::Expression>)
1708 for (
unsigned int d = 0;
d < dim; ++
d)
1715 const Number inverse_factor = Number(1.) / s;
1716 for (
unsigned int d = 0;
d < dim; ++
d)
1717 values[d] *= inverse_factor;
1724template <
int rank_,
int dim,
typename Number>
1731 for (
unsigned int i = 0; i < dim; ++i)
1732 tmp.
values[i] = -values[i];
1738template <
int rank_,
int dim,
typename Number>
1744 if constexpr ((rank_ == 1) && (dim == 1) && std::is_arithmetic_v<Number>)
1748 else if constexpr ((rank_ == 2) && (dim == 1) && std::is_arithmetic_v<Number>)
1761 return sqrt(norm_square());
1766template <
int rank_,
int dim,
typename Number>
1771 if constexpr (dim == 0)
1774 else if constexpr (rank_ == 1)
1780 for (
unsigned int i = 1; i < dim; ++i)
1790 values[0].norm_square();
1791 for (
unsigned int i = 1; i < dim; ++i)
1792 s += values[i].norm_square();
1800template <
int rank_,
int dim,
typename Number>
1801template <
class Iterator>
1804 const Iterator end)
const
1806 if constexpr (rank_ > 1)
1809 Iterator next =
begin;
1810 for (
unsigned int i = 0; i < dim; ++i)
1812 values[i].unroll(next, end);
1821 Assert(std::distance(begin, end) >= dim,
1823 "The provided iterator range must contain at least 'dim' "
1825 std::copy(values.data(), values.data() + values.size(), begin);
1831template <
int rank_,
int dim,
typename Number>
1832constexpr inline unsigned int
1836 unsigned int index = 0;
1837 for (
int r = 0; r < rank_; ++r)
1838 index = index * dim + indices[r];
1845template <
int rank_,
int dim,
typename Number>
1850 unsigned int dummy = n_independent_components;
1853 if constexpr (dim == 0)
1857 "A tensor with dimension 0 does not store any elements. "
1858 "There is no indexing that can address its elements."));
1865 unsigned int remainder = i;
1866 for (
int r = rank_ - 1; r >= 0; --r)
1868 indices[r] = remainder % dim;
1869 remainder = remainder / dim;
1878template <
int rank_,
int dim,
typename Number>
1879constexpr inline void
1882 for (
unsigned int i = 0; i < dim; ++i)
1887template <
int rank_,
int dim,
typename Number>
1888constexpr std::size_t
1895template <
int rank_,
int dim,
typename Number>
1896template <
class Archive>
1900 for (
int i = 0; i < dim; ++i)
1907template <
int rank_,
int dim,
typename Number>
1926template <
int rank_,
int dim,
typename Number>
1927inline std::ostream &
1930 for (
unsigned int i = 0; i < dim; ++i)
1934 for (
unsigned int j = 0; j < rank_; ++j)
1948template <
int dim,
typename Number>
1949inline std::ostream &
1952 out << static_cast<const Number &>(p);
1975template <
int dim,
typename Number,
typename Other>
1980 return object *
static_cast<const Number &
>(t);
1995template <
int dim,
typename Number,
typename Other>
2000 return static_cast<const Number &
>(t) *
object;
2015template <
int dim,
typename Number,
typename OtherNumber>
2021 return static_cast<const Number &
>(src1) *
2022 static_cast<const OtherNumber &
>(src2);
2033template <
int dim,
typename Number,
typename OtherNumber>
2041 return static_cast<const Number &
>(t) / factor;
2052template <
int dim,
typename Number,
typename OtherNumber>
2058 return static_cast<const Number &
>(p) +
static_cast<const OtherNumber &
>(q);
2069template <
int dim,
typename Number,
typename OtherNumber>
2075 return static_cast<const Number &
>(p) -
static_cast<const OtherNumber &
>(q);
2091template <
int rank,
int dim,
typename Number,
typename OtherNumber>
2117template <
int rank,
int dim,
typename Number,
typename OtherNumber>
2140template <
int rank,
int dim,
typename Number,
typename OtherNumber>
2163template <
int rank,
int dim,
typename Number,
typename OtherNumber>
2184template <
int rank,
int dim,
typename Number,
typename OtherNumber>
2201template <
int dim,
typename Number,
typename OtherNumber>
2230template <
int rank,
int dim,
typename Number,
typename OtherNumber>
2238 for (
unsigned int i = 0; i < dim; ++i)
2289template <
int rank_1,
2293 typename OtherNumber,
2294 typename = std::enable_if_t<rank_1 >= 1 && rank_2 >= 1>>
2296 typename Tensor<rank_1 + rank_2 - 2,
2308 if constexpr ((rank_1 == 1) && (rank_2 == 1))
2312 static_assert(dim > 0,
"Tensors cannot have dimension zero.");
2314 for (
unsigned int i = 1; i < dim; ++i)
2315 sum += src1[i] * src2[i];
2319 else if constexpr ((rank_1 == 2) && (rank_2 == 1))
2325 rank_1 + rank_2 - 2,
2328 for (
unsigned int i = 0; i < dim; ++i)
2329 result[i] += src1[i] * src2;
2338 rank_1 + rank_2 - 2,
2342 TensorAccessors::internal::
2343 ReorderedIndexView<0, rank_2, const Tensor<rank_2, dim, OtherNumber>>
2382template <
int index_1,
2388 typename OtherNumber>
2390 typename Tensor<rank_1 + rank_2 - 2,
2396 Assert(0 <= index_1 && index_1 < rank_1,
2398 "The specified index_1 must lie within the range [0,rank_1)"));
2399 Assert(0 <= index_2 && index_2 < rank_2,
2401 "The specified index_2 must lie within the range [0,rank_2)"));
2416 typename Tensor<rank_1 + rank_2 - 2,
2455template <
int index_1,
2463 typename OtherNumber>
2465 typename Tensor<rank_1 + rank_2 - 4,
2471 Assert(0 <= index_1 && index_1 < rank_1,
2473 "The specified index_1 must lie within the range [0,rank_1)"));
2474 Assert(0 <= index_3 && index_3 < rank_1,
2476 "The specified index_3 must lie within the range [0,rank_1)"));
2477 Assert(index_1 != index_3,
2478 ExcMessage(
"index_1 and index_3 must not be the same"));
2479 Assert(0 <= index_2 && index_2 < rank_2,
2481 "The specified index_2 must lie within the range [0,rank_2)"));
2482 Assert(0 <= index_4 && index_4 < rank_2,
2484 "The specified index_4 must lie within the range [0,rank_2)"));
2485 Assert(index_2 != index_4,
2486 ExcMessage(
"index_2 and index_4 must not be the same"));
2503 (index_3 < index_1 ? index_3 : index_3 - 1),
2515 (index_4 < index_2 ? index_4 : index_4 - 1),
2523 typename Tensor<rank_1 + rank_2 - 4,
2544template <
int rank,
int dim,
typename Number,
typename OtherNumber>
2573template <
template <
int,
int,
typename>
class TensorT1,
2574 template <
int,
int,
typename>
2576 template <
int,
int,
typename>
2587 const TensorT2<rank_1 + rank_2, dim, T2> &middle,
2588 const TensorT3<rank_2, dim, T3> &right)
2608template <
int rank_1,
2612 typename OtherNumber>
2618 typename Tensor<rank_1 + rank_2,
2645template <
int dim,
typename Number>
2654 result[1] = -src[0];
2669template <
int dim,
typename Number1,
typename Number2>
2679 if constexpr (dim == 3)
2681 result[0] = src1[1] * src2[2] - src1[2] * src2[1];
2682 result[1] = src1[2] * src2[0] - src1[0] * src2[2];
2683 result[2] = src1[0] * src2[1] - src1[1] * src2[0];
2703template <
int dim,
typename Number>
2711 for (
unsigned int k = 0; k < dim; ++k)
2713 Tensor<2, dim - 1, Number> minor;
2714 for (
unsigned int i = 0; i < dim - 1; ++i)
2715 for (
unsigned int j = 0; j < dim - 1; ++j)
2716 minor[i][j] = t[i][j < k ? j : j + 1];
2723 return ((dim % 2 == 0) ? 1. : -1.) * det;
2731template <
typename Number>
2743template <
typename Number>
2748 return t[0][0] * t[1][1] - t[1][0] * t[0][1];
2756template <
typename Number>
2767 return t[0][0] * C0 + t[0][1] * C1 + t[0][2] * C2;
2777template <
int dim,
typename Number>
2782 for (
unsigned int i = 1; i < dim; ++i)
2796template <
int dim,
typename Number>
2800 Number return_tensor[dim][dim];
2813template <
typename Number>
2821 return return_tensor;
2825template <
typename Number>
2832 1.0 / (t[0][0] * t[1][1] - t[1][0] * t[0][1]));
2833 return_tensor[0][0] = t[1][1];
2834 return_tensor[0][1] = -t[0][1];
2835 return_tensor[1][0] = -t[1][0];
2836 return_tensor[1][1] = t[0][0];
2837 return_tensor *= inv_det_t;
2839 return return_tensor;
2842template <
typename Number>
2848 const auto value = [](
const auto &t) {
2852 return_tensor[0][0] =
value(t[1][1] * t[2][2]) -
value(t[1][2] * t[2][1]);
2853 return_tensor[0][1] =
value(t[0][2] * t[2][1]) -
value(t[0][1] * t[2][2]);
2854 return_tensor[0][2] =
value(t[0][1] * t[1][2]) -
value(t[0][2] * t[1][1]);
2855 return_tensor[1][0] =
value(t[1][2] * t[2][0]) -
value(t[1][0] * t[2][2]);
2856 return_tensor[1][1] =
value(t[0][0] * t[2][2]) -
value(t[0][2] * t[2][0]);
2857 return_tensor[1][2] =
value(t[0][2] * t[1][0]) -
value(t[0][0] * t[1][2]);
2858 return_tensor[2][0] =
value(t[1][0] * t[2][1]) -
value(t[1][1] * t[2][0]);
2859 return_tensor[2][1] =
value(t[0][1] * t[2][0]) -
value(t[0][0] * t[2][1]);
2860 return_tensor[2][2] =
value(t[0][0] * t[1][1]) -
value(t[0][1] * t[1][0]);
2862 const Number inv_det_t =
2863 value(1.0 / (t[0][0] * return_tensor[0][0] + t[0][1] * return_tensor[1][0] +
2864 t[0][2] * return_tensor[2][0]));
2865 return_tensor *= inv_det_t;
2867 return return_tensor;
2878template <
int dim,
typename Number>
2883 for (
unsigned int i = 0; i < dim; ++i)
2886 for (
unsigned int j = i + 1; j < dim; ++j)
2909template <
int dim,
typename Number>
2930template <
int dim,
typename Number>
3001template <
int dim,
typename Number>
3013template <
int dim,
typename Number>
3018 for (
unsigned int j = 0; j < dim; ++j)
3021 for (
unsigned int i = 0; i < dim; ++i)
3039template <
int dim,
typename Number>
3044 for (
unsigned int i = 0; i < dim; ++i)
3047 for (
unsigned int j = 0; j < dim; ++j)
3065# ifdef DEAL_II_ADOLC_WITH_ADVANCED_BRANCHING
3074 for (
unsigned int j = 0; j < dim; ++j)
3077 for (
unsigned int i = 0; i < dim; ++i)
3078 sum += fabs(t[i][j]);
3080 condassign(max, (sum > max), sum, max);
3092 for (
unsigned int i = 0; i < dim; ++i)
3095 for (
unsigned int j = 0; j < dim; ++j)
3096 sum +=
fabs(t[i][j]);
3098 condassign(max, (sum > max), sum, max);
constexpr Tensor & operator*=(const OtherNumber &factor)
constexpr Tensor & operator=(const OtherNumber &d) &&=delete
static constexpr unsigned int n_independent_components
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
static constexpr unsigned int rank
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) &
static constexpr unsigned int dimension
constexpr Tensor operator-() const
constexpr Tensor & operator/=(const OtherNumber &factor)
constexpr Tensor(const ArrayView< ElementType, MemorySpace > &initializer)
constexpr Tensor< 2, dim, Number > cofactor(const Tensor< 2, dim, Number > &t)
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 Tensor< rank_1+rank_2, dim, typename ProductType< Number, OtherNumber >::type > outer_product(const Tensor< rank_1, dim, Number > &src1, const Tensor< rank_2, dim, OtherNumber > &src2)
constexpr Tensor< 2, dim, Number > adjugate(const Tensor< 2, dim, Number > &t)
constexpr const Number & operator[](const TableIndices< rank_ > &indices) const
constexpr ProductType< T1, typenameProductType< T2, T3 >::type >::type contract3(const TensorT1< rank_1, dim, T1 > &left, const TensorT2< rank_1+rank_2, dim, T2 > &middle, const TensorT3< rank_2, dim, T3 > &right)
constexpr Tensor< 2, dim, Number > transpose(const Tensor< 2, dim, Number > &t)
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, 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 Number determinant(const Tensor< 2, dim, Number > &t)
std::conditional_t< rank_==1, Number, Tensor< rank_ - 1, dim, Number > > value_type
constexpr Tensor(const Tensor< rank_, dim, OtherNumber > &initializer)
Tensor< rank, dim, Number > sum(const Tensor< rank, dim, Number > &local, const MPI_Comm mpi_communicator)
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
constexpr bool operator!=(const Tensor< rank_, dim, OtherNumber > &) const
constexpr ProductType< Number, OtherNumber >::type scalar_product(const Tensor< rank, dim, Number > &left, const Tensor< rank, dim, OtherNumber > &right)
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)
constexpr Tensor< rank_1+rank_2-4, dim, typenameProductType< Number, OtherNumber >::type >::tensor_type double_contract(const Tensor< rank_1, dim, Number > &src1, const Tensor< rank_2, dim, OtherNumber > &src2)
Tensor< 2, dim, Number > project_onto_orthogonal_tensors(const Tensor< 2, dim, Number > &A)
Number l1_norm(const Tensor< 2, dim, Number > &t)
constexpr Number trace(const Tensor< 2, dim, Number > &d)
static constexpr unsigned int dimension
static constexpr TableIndices< rank_ > unrolled_to_component_indices(const unsigned int i)
constexpr Tensor< 1, dim, Number > cross_product_2d(const Tensor< 1, dim, Number > &src)
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 Number determinant(const Tensor< 2, 1, Number > &t)
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)
Tensor< rank_, dim, Number > tensor_type
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 Number determinant(const Tensor< 2, 2, Number > &t)
constexpr Tensor< rank_1+rank_2-2, dim, typenameProductType< Number, OtherNumber >::type >::tensor_type contract(const Tensor< rank_1, dim, Number > &src1, const Tensor< rank_2, dim, OtherNumber > &src2)
constexpr Tensor< rank, dim, typename ProductType< Number, typename EnableIfScalar< OtherNumber >::type >::type > operator*(const Tensor< rank, dim, Number > &t, const OtherNumber &factor)
constexpr Tensor< 2, dim, Number > invert(const Tensor< 2, dim, Number > &)
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 Number determinant(const Tensor< 2, 3, Number > &t)
constexpr Tensor< rank_1+rank_2-2, dim, typenameProductType< Number, OtherNumber >::type >::tensor_type operator*(const Tensor< rank_1, dim, Number > &src1, const Tensor< rank_2, dim, OtherNumber > &src2)
constexpr Tensor(const array_type &initializer)
static constexpr unsigned int n_independent_components
constexpr Tensor operator-() const
constexpr Tensor< 1, dim, typename ProductType< Number1, Number2 >::type > cross_product_3d(const Tensor< 1, dim, Number1 > &src1, const Tensor< 1, dim, Number2 > &src2)
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)
const bool IsBlockVector< VectorType >::value
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 > &)
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 Tensor< 2, dim, Number > adjugate(const Tensor< 2, dim, Number > &t)
std::ostream & operator<<(std::ostream &out, const Tensor< rank_, dim, Number > &p)
constexpr Tensor< 2, dim, Number > transpose(const Tensor< 2, dim, Number > &t)
constexpr Number determinant(const Tensor< 2, dim, Number > &t)
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)
constexpr Tensor< 2, dim, Number > invert(const Tensor< 2, dim, Number > &)