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;
36 template <
typename Number>
class Vector;
41 template <
int dim,
typename Number>
42 class Tensor<-2, dim, Number>
46 template <
int dim,
typename Number>
47 class Tensor<-1, dim, Number>
83 template <
int dim,
typename Number>
100 static const unsigned int rank = 0;
140 template <
typename OtherNumber>
146 template <
typename OtherNumber>
147 Tensor (
const OtherNumber initializer);
164 operator const Number &()
const;
171 template <
typename OtherNumber>
177 template<
typename OtherNumber>
183 template<
typename OtherNumber>
189 template<
typename OtherNumber>
195 template<
typename OtherNumber>
201 template<
typename OtherNumber>
207 template<
typename OtherNumber>
246 template <
class Archive>
247 void serialize(Archive &ar,
const unsigned int version);
264 template <
typename OtherNumber>
266 unsigned int &start_index)
const;
271 template <
int,
int,
typename>
friend class Tensor;
317 template <
int rank_,
int dim,
typename Number>
334 static const unsigned int rank = rank_;
340 static const unsigned int 374 template <
typename OtherNumber>
380 template <
typename OtherNumber>
386 template <
typename OtherNumber>
387 operator Tensor<1,dim,
Tensor<rank_-1,dim,OtherNumber> > ()
const;
414 template <
typename OtherNumber>
428 template <
typename OtherNumber>
434 template <
typename OtherNumber>
440 template <
typename OtherNumber>
446 template <
typename OtherNumber>
453 template <
typename OtherNumber>
459 template <
typename OtherNumber>
502 template <
typename OtherNumber>
530 template <
class Archive>
531 void serialize(Archive &ar,
const unsigned int version);
550 template <
typename OtherNumber>
552 unsigned int &start_index)
const;
557 template <
int,
int,
typename>
friend class Tensor;
570 template <
int dim,
typename Number>
578 template <
int dim,
typename Number>
579 template <
typename OtherNumber>
587 template <
int dim,
typename Number>
588 template <
typename OtherNumber>
596 template <
int dim,
typename Number>
600 Assert(dim != 0,
ExcMessage(
"Cannot access an object of type Tensor<0,0,Number>"));
605 template <
int dim,
typename Number>
609 Assert(dim != 0,
ExcMessage(
"Cannot access an object of type Tensor<0,0,Number>"));
614 template <
int dim,
typename Number>
615 template <
typename OtherNumber>
624 template <
int dim,
typename Number>
625 template <
typename OtherNumber>
629 return (value == p.value);
633 template <
int dim,
typename Number>
634 template <
typename OtherNumber>
638 return !((*this) == p);
642 template <
int dim,
typename Number>
643 template <
typename OtherNumber>
652 template <
int dim,
typename Number>
653 template <
typename OtherNumber>
662 template <
int dim,
typename Number>
663 template <
typename OtherNumber>
672 template <
int dim,
typename Number>
673 template <
typename OtherNumber>
682 template <
int dim,
typename Number>
690 template <
int dim,
typename Number>
695 Assert(dim != 0,
ExcMessage(
"Cannot access an object of type Tensor<0,0,Number>"));
700 template <
int dim,
typename Number>
705 Assert(dim != 0,
ExcMessage(
"Cannot access an object of type Tensor<0,0,Number>"));
710 template <
int dim,
typename Number>
711 template <
typename OtherNumber>
715 unsigned int &index)
const 717 Assert(dim != 0,
ExcMessage(
"Cannot unroll an object of type Tensor<0,0,Number>"));
718 result[index] = value;
723 template <
int dim,
typename Number>
731 template <
int dim,
typename Number>
732 template <
class Archive>
743 template <
int rank_,
int dim,
typename Number>
752 template <
int rank_,
int dim,
typename Number>
756 for (
unsigned int i=0; i<dim; ++i)
757 values[i] = initializer[i];
761 template <
int rank_,
int dim,
typename Number>
762 template <
typename OtherNumber>
766 for (
unsigned int i=0; i!=dim; ++i)
767 values[i] = initializer[i];
771 template <
int rank_,
int dim,
typename Number>
772 template <
typename OtherNumber>
777 for (
unsigned int i=0; i<dim; ++i)
778 values[i] = initializer[i];
782 template <
int rank_,
int dim,
typename Number>
783 template <
typename OtherNumber>
795 namespace TensorSubscriptor
797 template <
typename ArrayElementType,
int dim>
798 inline DEAL_II_ALWAYS_INLINE
800 subscript (ArrayElementType *values,
801 const unsigned int i,
809 template <
typename ArrayElementType>
811 subscript (ArrayElementType *,
815 Assert(
false,
ExcMessage(
"Cannot access elements of an object of type Tensor<rank,0,Number>."));
816 static ArrayElementType t;
823 template <
int rank_,
int dim,
typename Number>
824 inline DEAL_II_ALWAYS_INLINE
832 template <
int rank_,
int dim,
typename Number>
833 inline DEAL_II_ALWAYS_INLINE
841 template <
int rank_,
int dim,
typename Number>
846 Assert(dim != 0,
ExcMessage(
"Cannot access an object of type Tensor<rank_,0,Number>"));
848 return TensorAccessors::extract<rank_>(*
this, indices);
852 template <
int rank_,
int dim,
typename Number>
857 Assert(dim != 0,
ExcMessage(
"Cannot access an object of type Tensor<rank_,0,Number>"));
859 return TensorAccessors::extract<rank_>(*
this, indices);
863 template <
int rank_,
int dim,
typename Number>
864 template <
typename OtherNumber>
875 template <
int rank_,
int dim,
typename Number>
880 Assert (d == Number(),
ExcMessage (
"Only assignment with zero is allowed"));
883 for (
unsigned int i=0; i<dim; ++i)
884 values[i] = Number();
889 template <
int rank_,
int dim,
typename Number>
890 template <
typename OtherNumber>
895 for (
unsigned int i=0; i<dim; ++i)
896 if (values[i] != p.
values[i])
916 template <
int rank_,
int dim,
typename Number>
917 template <
typename OtherNumber>
922 return !((*this) == p);
926 template <
int rank_,
int dim,
typename Number>
927 template <
typename OtherNumber>
932 for (
unsigned int i=0; i<dim; ++i)
938 template <
int rank_,
int dim,
typename Number>
939 template <
typename OtherNumber>
944 for (
unsigned int i=0; i<dim; ++i)
950 template <
int rank_,
int dim,
typename Number>
951 template <
typename OtherNumber>
956 for (
unsigned int i=0; i<dim; ++i)
962 template <
int rank_,
int dim,
typename Number>
963 template <
typename OtherNumber>
968 for (
unsigned int i=0; i<dim; ++i)
974 template <
int rank_,
int dim,
typename Number>
981 for (
unsigned int i=0; i<dim; ++i)
982 tmp.
values[i] = -values[i];
988 template <
int rank_,
int dim,
typename Number>
993 return std::sqrt (norm_square());
997 template <
int rank_,
int dim,
typename Number>
1003 for (
unsigned int i=0; i<dim; ++i)
1004 s += values[i].norm_square();
1010 template <
int rank_,
int dim,
typename Number>
1011 template <
typename OtherNumber>
1018 unsigned int index = 0;
1019 unroll_recursion (result, index);
1023 template <
int rank_,
int dim,
typename Number>
1024 template <
typename OtherNumber>
1028 unsigned int &index)
const 1030 for (
unsigned int i=0; i<dim; ++i)
1031 values[i].unroll_recursion(result, index);
1035 template <
int rank_,
int dim,
typename Number>
1040 unsigned int index = 0;
1041 for (
int r = 0; r < rank_; ++r)
1042 index = index * dim + indices[r];
1048 template <
int rank_,
int dim,
typename Number>
1053 Assert (i < n_independent_components,
1058 unsigned int remainder = i;
1059 for (
int r=rank_-1; r>=0; --r)
1061 indices[r] = (remainder % dim);
1070 template <
int rank_,
int dim,
typename Number>
1074 for (
unsigned int i=0; i<dim; ++i)
1079 template <
int rank_,
int dim,
typename Number>
1088 template <
int rank_,
int dim,
typename Number>
1089 template <
class Archive>
1112 template <
int rank_,
int dim,
typename Number>
1114 std::ostream &operator << (std::ostream &out, const Tensor<rank_,dim,Number> &p)
1116 for (
unsigned int i = 0; i < dim; ++i)
1133 template <
int dim,
typename Number>
1135 std::ostream &operator << (std::ostream &out, const Tensor<0,dim,Number> &p)
1137 out << static_cast<const Number &>(p);
1149 #ifndef DEAL_II_WITH_CXX11 1150 template <
typename T,
typename U,
int rank,
int dim>
1156 template <
typename T,
typename U,
int rank,
int dim>
1173 template <
int dim,
typename Number,
typename Other>
1179 return object *
static_cast<const Number &
>(t);
1191 template <
int dim,
typename Number,
typename Other>
1197 return static_cast<const Number &
>(t) *
object;
1210 template <
int dim,
typename Number,
typename OtherNumber>
1216 return static_cast<const Number &
>(src1) *
1217 static_cast<const OtherNumber &>(src2);
1226 template <
int dim,
typename Number,
typename OtherNumber>
1230 const OtherNumber factor)
1232 return static_cast<Number
>(t) / factor;
1241 template <
int dim,
typename Number,
typename OtherNumber>
1246 return static_cast<const Number &
>(p) + static_cast<const OtherNumber &>(q);
1255 template <
int dim,
typename Number,
typename OtherNumber>
1260 return static_cast<const Number &
>(p) - static_cast<const OtherNumber &>(q);
1274 template <
int rank,
int dim,
1276 typename OtherNumber>
1280 const OtherNumber factor)
1284 for (
unsigned int d=0; d<dim; ++d)
1285 tt[d] = t[d] * factor;
1300 template <
int rank,
int dim,
1302 typename OtherNumber>
1320 template <
int rank,
int dim,
1322 typename OtherNumber>
1326 const OtherNumber factor)
1330 for (
unsigned int d=0; d<dim; ++d)
1331 tt[d] = t[d] / factor;
1343 template <
int rank,
int dim,
typename Number,
typename OtherNumber>
1350 for (
unsigned int i=0; i<dim; ++i)
1364 template <
int rank,
int dim,
typename Number,
typename OtherNumber>
1371 for (
unsigned int i=0; i<dim; ++i)
1408 template <
int rank_1,
int rank_2,
int dim,
1409 typename Number,
typename OtherNumber>
1410 inline DEAL_II_ALWAYS_INLINE
1417 TensorAccessors::internal::ReorderedIndexView<0, rank_2, const Tensor<rank_2, dim, OtherNumber> >
1418 reordered = TensorAccessors::reordered_index_view<0, rank_2>(src2);
1419 TensorAccessors::contract<1, rank_1, rank_2, dim>(result, src1, reordered);
1454 template <
int index_1,
int index_2,
1455 int rank_1,
int rank_2,
int dim,
1456 typename Number,
typename OtherNumber>
1462 Assert(0 <= index_1 && index_1 < rank_1,
1463 ExcMessage(
"The specified index_1 must lie within the range [0,rank_1)"));
1464 Assert(0 <= index_2 && index_2 < rank_2,
1465 ExcMessage(
"The specified index_2 must lie within the range [0,rank_2)"));
1471 ReorderedIndexView<index_1, rank_1, const Tensor<rank_1, dim, Number> >
1472 reord_01 = reordered_index_view<index_1, rank_1>(src1);
1475 ReorderedIndexView<index_2, rank_2, const Tensor<rank_2, dim, OtherNumber> >
1476 reord_02 = reordered_index_view<index_2, rank_2>(src2);
1480 TensorAccessors::contract<1, rank_1, rank_2, dim>(result, reord_01, reord_02);
1516 template <
int index_1,
int index_2,
int index_3,
int index_4,
1517 int rank_1,
int rank_2,
int dim,
1518 typename Number,
typename OtherNumber>
1524 Assert(0 <= index_1 && index_1 < rank_1,
1525 ExcMessage(
"The specified index_1 must lie within the range [0,rank_1)"));
1526 Assert(0 <= index_3 && index_3 < rank_1,
1527 ExcMessage(
"The specified index_3 must lie within the range [0,rank_1)"));
1528 Assert(index_1 != index_3,
1529 ExcMessage(
"index_1 and index_3 must not be the same"));
1530 Assert(0 <= index_2 && index_2 < rank_2,
1531 ExcMessage(
"The specified index_2 must lie within the range [0,rank_2)"));
1532 Assert(0 <= index_4 && index_4 < rank_2,
1533 ExcMessage(
"The specified index_4 must lie within the range [0,rank_2)"));
1534 Assert(index_2 != index_4,
1535 ExcMessage(
"index_2 and index_4 must not be the same"));
1541 ReorderedIndexView<index_1, rank_1, const Tensor<rank_1, dim, Number> >
1542 reord_1 = TensorAccessors::reordered_index_view<index_1, rank_1>(src1);
1545 ReorderedIndexView<index_2, rank_2, const Tensor<rank_2, dim, OtherNumber> >
1546 reord_2 = TensorAccessors::reordered_index_view<index_2, rank_2>(src2);
1551 ReorderedIndexView<(index_3 < index_1 ? index_3 : index_3 - 1), rank_1, ReorderedIndexView<index_1, rank_1,
const Tensor<rank_1, dim, Number> > >
1562 TensorAccessors::contract<2, rank_1, rank_2, dim>(result, reord_3, reord_4);
1580 template <
int rank,
int dim,
typename Number,
typename OtherNumber>
1587 TensorAccessors::contract<rank, rank, rank, dim>(result, left, right);
1610 template <
template<
int,
int,
typename>
class TensorT1,
1611 template<
int,
int,
typename>
class TensorT2,
1612 template<
int,
int,
typename>
class TensorT3,
1613 int rank_1,
int rank_2,
int dim,
1614 typename T1,
typename T2,
typename T3>
1617 const TensorT2<rank_1 + rank_2, dim, T2> &middle,
1618 const TensorT3<rank_2, dim, T3> &right)
1622 return TensorAccessors::contract3<rank_1, rank_2, dim, return_type>(
1623 left, middle, right);
1638 template <
int rank_1,
int rank_2,
int dim,
1639 typename Number,
typename OtherNumber>
1646 TensorAccessors::contract<0, rank_1, rank_2, dim>(result, src1, src2);
1669 template <
int dim,
typename Number>
1679 result[1] = -src[0];
1695 template <
int dim,
typename Number>
1705 result[0] = src1[1]*src2[2] - src1[2]*src2[1];
1706 result[1] = src1[2]*src2[0] - src1[0]*src2[2];
1707 result[2] = src1[0]*src2[1] - src1[1]*src2[0];
1726 template <
int dim,
typename Number>
1732 Number det = Number();
1734 for (
unsigned int k=0; k<dim; ++k)
1736 Tensor<2,dim-1,Number> minor;
1737 for (
unsigned int i=0; i<dim-1; ++i)
1738 for (
unsigned int j=0; j<dim-1; ++j)
1739 minor[i][j] = t[i][j<k ? j : j+1];
1741 const Number cofactor = ((k % 2 == 0) ? -1. : 1.) * determinant(minor);
1743 det += t[dim-1][k] * cofactor;
1746 return ((dim % 2 == 0) ? 1. : -1.) * det;
1754 template <
typename Number>
1769 template <
int dim,
typename Number>
1773 for (
unsigned int i=1; i<dim; ++i)
1788 template <
int dim,
typename Number>
1793 Number return_tensor [dim][dim];
1806 template <
typename Number>
1811 Number return_tensor [1][1];
1813 return_tensor[0][0] = 1.0/t[0][0];
1819 template <
typename Number>
1828 const Number inv_det_t = 1.0/(t[0][0]*t[1][1]-t[1][0]*t[0][1]);
1829 return_tensor[0][0] = t[1][1];
1830 return_tensor[0][1] = -t[0][1];
1831 return_tensor[1][0] = -t[1][0];
1832 return_tensor[1][1] = t[0][0];
1833 return_tensor *= inv_det_t;
1835 return return_tensor;
1839 template <
typename Number>
1846 const Number t4 = t[0][0]*t[1][1],
1847 t6 = t[0][0]*t[1][2],
1848 t8 = t[0][1]*t[1][0],
1849 t00 = t[0][2]*t[1][0],
1850 t01 = t[0][1]*t[2][0],
1851 t04 = t[0][2]*t[2][0],
1852 inv_det_t = 1.0/(t4*t[2][2]-t6*t[2][1]-t8*t[2][2]+
1853 t00*t[2][1]+t01*t[1][2]-t04*t[1][1]);
1854 return_tensor[0][0] = t[1][1]*t[2][2]-t[1][2]*t[2][1];
1855 return_tensor[0][1] = t[0][2]*t[2][1]-t[0][1]*t[2][2];
1856 return_tensor[0][2] = t[0][1]*t[1][2]-t[0][2]*t[1][1];
1857 return_tensor[1][0] = t[1][2]*t[2][0]-t[1][0]*t[2][2];
1858 return_tensor[1][1] = t[0][0]*t[2][2]-t04;
1859 return_tensor[1][2] = t00-t6;
1860 return_tensor[2][0] = t[1][0]*t[2][1]-t[1][1]*t[2][0];
1861 return_tensor[2][1] = t01-t[0][0]*t[2][1];
1862 return_tensor[2][2] = t4-t8;
1863 return_tensor *= inv_det_t;
1865 return return_tensor;
1877 template <
int dim,
typename Number>
1883 for (
unsigned int i=0; i<dim; ++i)
1886 for (
unsigned int j=i+1; j<dim; ++j)
1909 template <
int dim,
typename Number>
1914 return determinant(t)*invert(t);
1932 template <
int dim,
typename Number>
1937 return transpose(adjugate(t));
1948 template <
int dim,
typename Number>
1954 for (
unsigned int j=0; j<dim; ++j)
1957 for (
unsigned int i=0; i<dim; ++i)
1958 sum += std::fabs(t[i][j]);
1975 template <
int dim,
typename Number>
1981 for (
unsigned int i=0; i<dim; ++i)
1984 for (
unsigned int j=0; j<dim; ++j)
1985 sum += std::fabs(t[i][j]);
1996 DEAL_II_NAMESPACE_CLOSE
1999 #include <deal.II/base/tensor_deprecated.h> 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)
Tensor< rank, dim, typename ProductType< Number, OtherNumber >::type > operator+(const SymmetricTensor< rank, dim, Number > &left, const Tensor< rank, dim, OtherNumber > &right)
SymmetricTensor< rank, dim, Number > operator/(const SymmetricTensor< rank, dim, Number > &t, const Number factor)
static const unsigned int n_independent_components
bool operator==(const Tensor< rank_, dim, OtherNumber > &) const
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 > &)
Tensor< 2, dim, Number > adjugate(const Tensor< 2, dim, Number > &t)
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
static ::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
Tensor & operator=(const Tensor< rank_, dim, OtherNumber > &rhs)
Tensor< 2, dim, Number > cofactor(const Tensor< 2, dim, Number > &t)
Tensor< 2, dim, Number > transpose(const Tensor< 2, dim, Number > &t)
static ::ExceptionBase & ExcMessage(std::string arg1)
ProductType< T1, typename ProductType< 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)
Tensor< rank_, dim, Number > & operator+=(const Tensor< rank_, dim, OtherNumber > &)
Tensor< 2, dim, Number > invert(const Tensor< 2, dim, Number > &)
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< rank, dim, typename ProductType< Number, OtherNumber >::type > operator-(const SymmetricTensor< rank, dim, Number > &left, const Tensor< rank, dim, OtherNumber > &right)
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)
Number determinant(const Tensor< 2, dim, Number > &t)
static const unsigned int dimension
Tensor< rank_-1, dim, Number >::tensor_type value_type
static ::ExceptionBase & ExcNotImplemented()
void unroll(Vector< OtherNumber > &result) const
Tensor< rank_, dim, Number > operator-() const
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)
Point< dim, typename ProductType< Number, typename EnableIfScalar< OtherNumber >::type >::type > operator*(const OtherNumber) const
static ::ExceptionBase & ExcInternalError()
Number determinant(const Tensor< 2, 1, Number > &t)