16 #ifndef dealii__tensor_h 17 #define dealii__tensor_h 19 #include <deal.II/base/config.h> 20 #include <deal.II/base/exceptions.h> 21 #include <deal.II/base/table_indices.h> 22 #include <deal.II/base/tensor_accessors.h> 23 #include <deal.II/base/template_constraints.h> 24 #include <deal.II/base/utilities.h> 30 DEAL_II_NAMESPACE_OPEN
34 template <
int dim,
typename Number>
class Point;
35 template <
int rank_,
int dim,
typename Number =
double>
class Tensor;
40 template <
int dim,
typename Number>
41 class Tensor<-2, dim, Number>
45 template <
int dim,
typename Number>
46 class Tensor<-1, dim, Number>
82 template <
int dim,
typename Number>
99 static const unsigned int rank = 0;
144 template <
typename OtherNumber>
150 template <
typename OtherNumber>
151 Tensor (
const OtherNumber initializer);
168 operator const Number &()
const;
180 template <
typename OtherNumber>
186 template<
typename OtherNumber>
192 template<
typename OtherNumber>
198 template<
typename OtherNumber>
204 template<
typename OtherNumber>
210 template<
typename OtherNumber>
216 template<
typename OtherNumber>
243 real_type
norm ()
const;
255 template <
class Archive>
256 void serialize(Archive &ar,
const unsigned int version);
273 template <
typename OtherNumber>
275 unsigned int &start_index)
const;
280 template <
int,
int,
typename>
friend class Tensor;
326 template <
int rank_,
int dim,
typename Number>
343 static const unsigned int rank = rank_;
349 static const unsigned int 388 template <
typename OtherNumber>
394 template <
typename OtherNumber>
400 template <
typename OtherNumber>
401 operator Tensor<1,dim,
Tensor<rank_-1,dim,OtherNumber> > ()
const;
411 const value_type &
operator[](
const unsigned int i)
const;
433 template <
typename OtherNumber>
447 template <
typename OtherNumber>
453 template <
typename OtherNumber>
459 template <
typename OtherNumber>
465 template <
typename OtherNumber>
472 template <
typename OtherNumber>
478 template <
typename OtherNumber>
521 template <
typename OtherNumber>
549 template <
class Archive>
550 void serialize(Archive &ar,
const unsigned int version);
569 template <
typename OtherNumber>
571 unsigned int &start_index)
const;
576 template <
int,
int,
typename>
friend class Tensor;
589 template <
int dim,
typename Number>
597 template <
int dim,
typename Number>
605 template <
int dim,
typename Number>
606 template <
typename OtherNumber>
614 template <
int dim,
typename Number>
615 template <
typename OtherNumber>
623 template <
int dim,
typename Number>
627 Assert(dim != 0,
ExcMessage(
"Cannot access an object of type Tensor<0,0,Number>"));
632 template <
int dim,
typename Number>
636 Assert(dim != 0,
ExcMessage(
"Cannot access an object of type Tensor<0,0,Number>"));
641 template <
int dim,
typename Number>
650 template <
int dim,
typename Number>
651 template <
typename OtherNumber>
660 template <
int dim,
typename Number>
661 template <
typename OtherNumber>
665 return (value == p.value);
669 template <
int dim,
typename Number>
670 template <
typename OtherNumber>
674 return !((*this) == p);
678 template <
int dim,
typename Number>
679 template <
typename OtherNumber>
688 template <
int dim,
typename Number>
689 template <
typename OtherNumber>
698 template <
int dim,
typename Number>
699 template <
typename OtherNumber>
708 template <
int dim,
typename Number>
709 template <
typename OtherNumber>
718 template <
int dim,
typename Number>
726 template <
int dim,
typename Number>
731 Assert(dim != 0,
ExcMessage(
"Cannot access an object of type Tensor<0,0,Number>"));
736 template <
int dim,
typename Number>
741 Assert(dim != 0,
ExcMessage(
"Cannot access an object of type Tensor<0,0,Number>"));
746 template <
int dim,
typename Number>
747 template <
typename OtherNumber>
751 unsigned int &index)
const 753 Assert(dim != 0,
ExcMessage(
"Cannot unroll an object of type Tensor<0,0,Number>"));
754 result[index] = value;
759 template <
int dim,
typename Number>
767 template <
int dim,
typename Number>
768 template <
class Archive>
779 template <
int rank_,
int dim,
typename Number>
788 template <
int rank_,
int dim,
typename Number>
793 std::copy (&initializer[0], &initializer[0]+dim, &
values[0]);
797 template <
int rank_,
int dim,
typename Number>
801 for (
unsigned int i=0; i<dim; ++i)
802 values[i] = initializer[i];
806 template <
int rank_,
int dim,
typename Number>
807 template <
typename OtherNumber>
811 for (
unsigned int i=0; i!=dim; ++i)
812 values[i] = initializer[i];
816 template <
int rank_,
int dim,
typename Number>
817 template <
typename OtherNumber>
822 for (
unsigned int i=0; i<dim; ++i)
823 values[i] = initializer[i];
827 template <
int rank_,
int dim,
typename Number>
828 template <
typename OtherNumber>
831 operator
Tensor<1,dim,Tensor<rank_-1,dim,OtherNumber> > ()
const 833 return Tensor<1,dim,Tensor<rank_-1,dim,Number> > (
values);
840 namespace TensorSubscriptor
842 template <
typename ArrayElementType,
int dim>
843 inline DEAL_II_ALWAYS_INLINE
845 subscript (ArrayElementType *
values,
846 const unsigned int i,
849 Assert (i<dim, ExcIndexRange(i, 0, dim));
854 template <
typename ArrayElementType>
856 subscript (ArrayElementType *,
860 Assert(
false,
ExcMessage(
"Cannot access elements of an object of type Tensor<rank,0,Number>."));
861 static ArrayElementType t;
868 template <
int rank_,
int dim,
typename Number>
869 inline DEAL_II_ALWAYS_INLINE
877 template <
int rank_,
int dim,
typename Number>
878 inline DEAL_II_ALWAYS_INLINE
886 template <
int rank_,
int dim,
typename Number>
891 Assert(dim != 0,
ExcMessage(
"Cannot access an object of type Tensor<rank_,0,Number>"));
893 return TensorAccessors::extract<rank_>(*
this, indices);
897 template <
int rank_,
int dim,
typename Number>
902 Assert(dim != 0,
ExcMessage(
"Cannot access an object of type Tensor<rank_,0,Number>"));
904 return TensorAccessors::extract<rank_>(*
this, indices);
908 template <
int rank_,
int dim,
typename Number>
919 template <
int rank_,
int dim,
typename Number>
920 template <
typename OtherNumber>
931 template <
int rank_,
int dim,
typename Number>
936 Assert (d == Number(),
ExcMessage (
"Only assignment with zero is allowed"));
939 for (
unsigned int i=0; i<dim; ++i)
945 template <
int rank_,
int dim,
typename Number>
946 template <
typename OtherNumber>
951 for (
unsigned int i=0; i<dim; ++i)
972 template <
int rank_,
int dim,
typename Number>
973 template <
typename OtherNumber>
978 return !((*this) == p);
982 template <
int rank_,
int dim,
typename Number>
983 template <
typename OtherNumber>
988 for (
unsigned int i=0; i<dim; ++i)
994 template <
int rank_,
int dim,
typename Number>
995 template <
typename OtherNumber>
1000 for (
unsigned int i=0; i<dim; ++i)
1006 template <
int rank_,
int dim,
typename Number>
1007 template <
typename OtherNumber>
1012 for (
unsigned int i=0; i<dim; ++i)
1018 template <
int rank_,
int dim,
typename Number>
1019 template <
typename OtherNumber>
1024 for (
unsigned int i=0; i<dim; ++i)
1030 template <
int rank_,
int dim,
typename Number>
1037 for (
unsigned int i=0; i<dim; ++i)
1044 template <
int rank_,
int dim,
typename Number>
1053 template <
int rank_,
int dim,
typename Number>
1059 for (
unsigned int i=0; i<dim; ++i)
1066 template <
int rank_,
int dim,
typename Number>
1067 template <
typename OtherNumber>
1074 unsigned int index = 0;
1079 template <
int rank_,
int dim,
typename Number>
1080 template <
typename OtherNumber>
1084 unsigned int &index)
const 1086 for (
unsigned int i=0; i<dim; ++i)
1091 template <
int rank_,
int dim,
typename Number>
1096 unsigned int index = 0;
1097 for (
int r = 0; r < rank_; ++r)
1098 index = index * dim + indices[r];
1104 template <
int rank_,
int dim,
typename Number>
1114 unsigned int remainder = i;
1115 for (
int r=rank_-1; r>=0; --r)
1117 indices[r] = (remainder % dim);
1120 Assert (remainder == 0, ExcInternalError());
1126 template <
int rank_,
int dim,
typename Number>
1130 for (
unsigned int i=0; i<dim; ++i)
1135 template <
int rank_,
int dim,
typename Number>
1144 template <
int rank_,
int dim,
typename Number>
1145 template <
class Archive>
1168 template <
int rank_,
int dim,
typename Number>
1170 std::ostream &operator << (std::ostream &out, const Tensor<rank_,dim,Number> &p)
1172 for (
unsigned int i = 0; i < dim; ++i)
1189 template <
int dim,
typename Number>
1191 std::ostream &operator << (std::ostream &out, const Tensor<0,dim,Number> &p)
1193 out << static_cast<const Number &>(p);
1205 #ifndef DEAL_II_WITH_CXX11 1206 template <
typename T,
typename U,
int rank,
int dim>
1212 template <
typename T,
typename U,
int rank,
int dim>
1229 template <
int dim,
typename Number,
typename Other>
1235 return object *
static_cast<const Number &
>(t);
1247 template <
int dim,
typename Number,
typename Other>
1253 return static_cast<const Number &
>(t) *
object;
1266 template <
int dim,
typename Number,
typename OtherNumber>
1272 return static_cast<const Number &
>(src1) *
1273 static_cast<const OtherNumber &>(src2);
1282 template <
int dim,
typename Number,
typename OtherNumber>
1286 const OtherNumber factor)
1288 return static_cast<Number
>(t) / factor;
1297 template <
int dim,
typename Number,
typename OtherNumber>
1302 return static_cast<const Number &
>(p) + static_cast<const OtherNumber &>(q);
1311 template <
int dim,
typename Number,
typename OtherNumber>
1316 return static_cast<const Number &
>(p) - static_cast<const OtherNumber &>(q);
1330 template <
int rank,
int dim,
1332 typename OtherNumber>
1336 const OtherNumber factor)
1340 for (
unsigned int d=0; d<dim; ++d)
1341 tt[d] = t[d] * factor;
1356 template <
int rank,
int dim,
1358 typename OtherNumber>
1376 template <
int rank,
int dim,
1378 typename OtherNumber>
1382 const OtherNumber factor)
1386 for (
unsigned int d=0; d<dim; ++d)
1387 tt[d] = t[d] / factor;
1399 template <
int rank,
int dim,
typename Number,
typename OtherNumber>
1406 for (
unsigned int i=0; i<dim; ++i)
1420 template <
int rank,
int dim,
typename Number,
typename OtherNumber>
1427 for (
unsigned int i=0; i<dim; ++i)
1464 template <
int rank_1,
int rank_2,
int dim,
1465 typename Number,
typename OtherNumber>
1466 inline DEAL_II_ALWAYS_INLINE
1473 TensorAccessors::internal::ReorderedIndexView<0, rank_2, const Tensor<rank_2, dim, OtherNumber> >
1474 reordered = TensorAccessors::reordered_index_view<0, rank_2>(src2);
1475 TensorAccessors::contract<1, rank_1, rank_2, dim>(result, src1, reordered);
1510 template <
int index_1,
int index_2,
1511 int rank_1,
int rank_2,
int dim,
1512 typename Number,
typename OtherNumber>
1518 Assert(0 <= index_1 && index_1 < rank_1,
1519 ExcMessage(
"The specified index_1 must lie within the range [0,rank_1)"));
1520 Assert(0 <= index_2 && index_2 < rank_2,
1521 ExcMessage(
"The specified index_2 must lie within the range [0,rank_2)"));
1527 ReorderedIndexView<index_1, rank_1, const Tensor<rank_1, dim, Number> >
1528 reord_01 = reordered_index_view<index_1, rank_1>(src1);
1531 ReorderedIndexView<index_2, rank_2, const Tensor<rank_2, dim, OtherNumber> >
1532 reord_02 = reordered_index_view<index_2, rank_2>(src2);
1536 TensorAccessors::contract<1, rank_1, rank_2, dim>(result, reord_01, reord_02);
1572 template <
int index_1,
int index_2,
int index_3,
int index_4,
1573 int rank_1,
int rank_2,
int dim,
1574 typename Number,
typename OtherNumber>
1580 Assert(0 <= index_1 && index_1 < rank_1,
1581 ExcMessage(
"The specified index_1 must lie within the range [0,rank_1)"));
1582 Assert(0 <= index_3 && index_3 < rank_1,
1583 ExcMessage(
"The specified index_3 must lie within the range [0,rank_1)"));
1584 Assert(index_1 != index_3,
1585 ExcMessage(
"index_1 and index_3 must not be the same"));
1586 Assert(0 <= index_2 && index_2 < rank_2,
1587 ExcMessage(
"The specified index_2 must lie within the range [0,rank_2)"));
1588 Assert(0 <= index_4 && index_4 < rank_2,
1589 ExcMessage(
"The specified index_4 must lie within the range [0,rank_2)"));
1590 Assert(index_2 != index_4,
1591 ExcMessage(
"index_2 and index_4 must not be the same"));
1597 ReorderedIndexView<index_1, rank_1, const Tensor<rank_1, dim, Number> >
1598 reord_1 = TensorAccessors::reordered_index_view<index_1, rank_1>(src1);
1601 ReorderedIndexView<index_2, rank_2, const Tensor<rank_2, dim, OtherNumber> >
1602 reord_2 = TensorAccessors::reordered_index_view<index_2, rank_2>(src2);
1607 ReorderedIndexView<(index_3 < index_1 ? index_3 : index_3 - 1), rank_1, ReorderedIndexView<index_1, rank_1,
const Tensor<rank_1, dim, Number> > >
1618 TensorAccessors::contract<2, rank_1, rank_2, dim>(result, reord_3, reord_4);
1636 template <
int rank,
int dim,
typename Number,
typename OtherNumber>
1643 TensorAccessors::contract<rank, rank, rank, dim>(result, left, right);
1663 template <
int rank_1,
int rank_2,
int dim,
1664 typename T1,
typename T2,
typename T3>
1672 return TensorAccessors::contract3<rank_1, rank_2, dim, return_type>(
1673 left, middle, right);
1688 template <
int rank_1,
int rank_2,
int dim,
1689 typename Number,
typename OtherNumber>
1696 TensorAccessors::contract<0, rank_1, rank_2, dim>(result, src1, src2);
1719 template <
int dim,
typename Number>
1724 Assert (dim==2, ExcInternalError());
1729 result[1] = -src[0];
1745 template <
int dim,
typename Number>
1751 Assert (dim==3, ExcInternalError());
1755 result[0] = src1[1]*src2[2] - src1[2]*src2[1];
1756 result[1] = src1[2]*src2[0] - src1[0]*src2[2];
1757 result[2] = src1[0]*src2[1] - src1[1]*src2[0];
1776 template <
int dim,
typename Number>
1782 Number det = Number();
1784 for (
unsigned int k=0; k<dim; ++k)
1786 Tensor<2,dim-1,Number> minor;
1787 for (
unsigned int i=0; i<dim-1; ++i)
1788 for (
unsigned int j=0; j<dim-1; ++j)
1789 minor[i][j] = t[i][j<k ? j : j+1];
1791 const Number cofactor = ((k % 2 == 0) ? -1. : 1.) *
determinant(minor);
1793 det += t[dim-1][k] * cofactor;
1796 return ((dim % 2 == 0) ? 1. : -1.) * det;
1804 template <
typename Number>
1819 template <
int dim,
typename Number>
1823 for (
unsigned int i=1; i<dim; ++i)
1838 template <
int dim,
typename Number>
1843 Number return_tensor [dim][dim];
1847 return_tensor[0][0] = 1.0/t[0][0];
1854 const Number det = t[0][0]*t[1][1]-t[1][0]*t[0][1];
1855 const Number t4 = 1.0/det;
1856 return_tensor[0][0] = t[1][1]*t4;
1857 return_tensor[0][1] = -t[0][1]*t4;
1858 return_tensor[1][0] = -t[1][0]*t4;
1859 return_tensor[1][1] = t[0][0]*t4;
1865 const Number t4 = t[0][0]*t[1][1],
1866 t6 = t[0][0]*t[1][2],
1867 t8 = t[0][1]*t[1][0],
1868 t00 = t[0][2]*t[1][0],
1869 t01 = t[0][1]*t[2][0],
1870 t04 = t[0][2]*t[2][0],
1871 det = (t4*t[2][2]-t6*t[2][1]-t8*t[2][2]+
1872 t00*t[2][1]+t01*t[1][2]-t04*t[1][1]),
1874 return_tensor[0][0] = (t[1][1]*t[2][2]-t[1][2]*t[2][1])*t07;
1875 return_tensor[0][1] = (t[0][2]*t[2][1]-t[0][1]*t[2][2])*t07;
1876 return_tensor[0][2] = (t[0][1]*t[1][2]-t[0][2]*t[1][1])*t07;
1877 return_tensor[1][0] = (t[1][2]*t[2][0]-t[1][0]*t[2][2])*t07;
1878 return_tensor[1][1] = (t[0][0]*t[2][2]-t04)*t07;
1879 return_tensor[1][2] = (t00-t6)*t07;
1880 return_tensor[2][0] = (t[1][0]*t[2][1]-t[1][1]*t[2][0])*t07;
1881 return_tensor[2][1] = (t01-t[0][0]*t[2][1])*t07;
1882 return_tensor[2][2] = (t4-t8)*t07;
1903 template <
int dim,
typename Number>
1909 for (
unsigned int i=0; i<dim; ++i)
1912 for (
unsigned int j=i+1; j<dim; ++j)
1929 template <
int dim,
typename Number>
1935 for (
unsigned int j=0; j<dim; ++j)
1938 for (
unsigned int i=0; i<dim; ++i)
1939 sum += std::fabs(t[i][j]);
1956 template <
int dim,
typename Number>
1962 for (
unsigned int i=0; i<dim; ++i)
1965 for (
unsigned int j=0; j<dim; ++j)
1966 sum += std::fabs(t[i][j]);
1977 DEAL_II_NAMESPACE_CLOSE
1980 #include <deal.II/base/tensor_deprecated.h> Tensor< rank, dim, Number > sum(const Tensor< rank, dim, Number > &local, const MPI_Comm &mpi_communicator)
numbers::NumberTraits< Number >::real_type real_type
Number trace(const Tensor< 2, dim, Number > &d)
#define AssertDimension(dim1, dim2)
static unsigned int component_to_unrolled_index(const TableIndices< rank_ > &indices)
static const unsigned int n_independent_components
bool operator==(const Tensor< rank_, dim, OtherNumber > &) const
::ExceptionBase & ExcMessage(std::string arg1)
static std::size_t memory_consumption()
bool operator!=(const Tensor< rank_, dim, OtherNumber > &) const
Tensor< rank_1+rank_2 - 4, dim, typename ProductType< Number, OtherNumber >::type >::tensor_type double_contract(const Tensor< rank_1, dim, Number > &src1, const Tensor< rank_2, dim, OtherNumber > &src2)
Tensor< rank_, dim, Number > & operator-=(const Tensor< rank_, dim, OtherNumber > &)
static const unsigned int rank
#define AssertThrow(cond, exc)
static real_type abs(const number &x)
numbers::NumberTraits< Number >::real_type norm() const
void unroll_recursion(Vector< OtherNumber > &result, unsigned int &start_index) const
ProductType< Other, Number >::type operator*(const Other object, const Tensor< 0, dim, Number > &t)
Tensor< 2, dim, Number > transpose(const Tensor< 2, dim, Number > &t)
Tensor< rank_, dim, Number > & operator+=(const Tensor< rank_, dim, OtherNumber > &)
static real_type abs_square(const number &x)
Tensor< 1, dim, Number > cross_product_2d(const Tensor< 1, dim, Number > &src)
#define Assert(cond, exc)
ProductType< Number, OtherNumber >::type scalar_product(const Tensor< rank, dim, Number > &left, const Tensor< rank, dim, OtherNumber > &right)
Tensor< rank_, dim, Number > tensor_type
DEAL_II_ALWAYS_INLINE internal::ReorderedIndexView< index, rank, T > reordered_index_view(T &t)
Tensor< 0, dim, typename ProductType< Number, OtherNumber >::type > operator+(const Tensor< 0, dim, Number > &p, const Tensor< 0, dim, OtherNumber > &q)
void serialize(Archive &ar, const unsigned int version)
double linfty_norm(const Tensor< 2, dim, Number > &t)
numbers::NumberTraits< Number >::real_type norm_square() const
double l1_norm(const Tensor< 2, dim, Number > &t)
Tensor< rank_, dim, Number > & operator/=(const OtherNumber factor)
Tensor< rank_-1, dim, Number >::array_type array_type[(dim !=0) ? dim :1]
static TableIndices< rank_ > unrolled_to_component_indices(const unsigned int i)
value_type & operator[](const unsigned int i)
Tensor< rank_-1, dim, Number > values[(dim !=0) ? dim :1]
Tensor< 1, dim, Number > cross_product_3d(const Tensor< 1, dim, Number > &src1, const Tensor< 1, dim, Number > &src2)
ProductType< T1, typename ProductType< T2, T3 >::type >::type contract3(const Tensor< rank_1, dim, T1 > &left, const Tensor< rank_1+rank_2, dim, T2 > &middle, const Tensor< rank_2, dim, T3 > &right)
Number determinant(const Tensor< 2, dim, Number > &t)
static const unsigned int dimension
Tensor< 0, dim, typename ProductType< Number, typename EnableIfScalar< OtherNumber >::type >::type > operator/(const Tensor< 0, dim, Number > &t, const OtherNumber factor)
Tensor< rank_-1, dim, Number >::tensor_type value_type
void unroll(Vector< OtherNumber > &result) const
Tensor< rank_, dim, Number > operator-() const
Tensor & operator=(const Tensor< rank_, dim, Number > &rhs)
Tensor< rank_, dim, Number > & operator*=(const OtherNumber factor)
Tensor< rank_1+rank_2 - 2, dim, typename ProductType< Number, OtherNumber >::type >::tensor_type contract(const Tensor< rank_1, dim, Number > &src1, const Tensor< rank_2, dim, OtherNumber > &src2)
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)
Tensor< 2, dim, Number > invert(const Tensor< 2, dim, Number > &t)
Number determinant(const Tensor< 2, 1, Number > &t)