16 #ifndef dealii__symmetric_tensor_h 17 #define dealii__symmetric_tensor_h 20 #include <deal.II/base/tensor.h> 21 #include <deal.II/base/numbers.h> 22 #include <deal.II/base/table_indices.h> 23 #include <deal.II/base/template_constraints.h> 24 #include <deal.II/base/vectorization.h> 26 DEAL_II_NAMESPACE_OPEN
28 template <
int rank,
int dim,
typename Number=
double>
class SymmetricTensor;
40 template <
int dim2,
typename Number> Number
45 template <
int dim,
typename Number> Number
56 namespace SymmetricTensorAccessors
66 const unsigned int new_index,
67 const unsigned int position)
87 const unsigned int new_index,
88 const unsigned int position)
122 template <
int rank1,
int rank2,
int dim,
typename Number>
125 typedef ::SymmetricTensor<rank1+rank2-4,dim,Number>
type;
137 template <
int dim,
typename Number>
157 template <
int rank,
int dim,
typename Number>
163 template <
int dim,
typename Number>
170 static const unsigned int 171 n_independent_components = (dim*dim + dim)/2;
184 template <
int dim,
typename Number>
192 static const unsigned int 193 n_rank2_components = (dim*dim + dim)/2;
198 static const unsigned int 199 n_independent_components = (n_rank2_components *
217 template <
int rank,
int dim,
bool constness,
typename Number>
226 template <
int rank,
int dim,
typename Number>
229 typedef const ::SymmetricTensor<rank,dim,Number>
tensor_type;
231 typedef Number reference;
240 template <
int rank,
int dim,
typename Number>
243 typedef ::SymmetricTensor<rank,dim,Number>
tensor_type;
245 typedef Number &reference;
283 template <
int rank,
int dim,
bool constness,
int P,
typename Number>
312 Accessor (tensor_type &tensor,
318 Accessor (
const Accessor &a);
325 Accessor<rank,dim,constness,P-1,Number> operator [] (
const unsigned int i);
330 Accessor<rank,dim,constness,P-1,Number> operator [] (
const unsigned int i)
const;
343 template <
int,
int,
typename>
friend class ::SymmetricTensor;
344 template <
int,
int,
bool,
int,
typename>
345 friend class Accessor;
346 # ifndef DEAL_II_TEMPL_SPEC_FRIEND_BUG 347 friend class ::SymmetricTensor<rank,dim,Number>;
348 friend class Accessor<rank,dim,constness,P+1,Number>;
363 template <
int rank,
int dim,
bool constness,
typename Number>
364 class Accessor<rank,dim,constness,1,Number>
370 typedef typename AccessorTypes<rank,dim,constness,Number>::reference reference;
371 typedef typename AccessorTypes<rank,dim,constness,Number>::tensor_type tensor_type;
395 Accessor (tensor_type &tensor,
406 Accessor (
const Accessor &a);
413 reference operator [] (
const unsigned int);
418 reference operator [] (
const unsigned int)
const;
431 template <
int,
int,
typename>
friend class ::SymmetricTensor;
432 template <
int,
int,
bool,
int,
typename>
433 friend class SymmetricTensorAccessors::Accessor;
434 # ifndef DEAL_II_TEMPL_SPEC_FRIEND_BUG 435 friend class ::SymmetricTensor<rank,dim,Number>;
436 friend class SymmetricTensorAccessors::Accessor<rank,dim,constness,2,Number>;
507 template <
int rank,
int dim,
typename Number>
569 template <
typename OtherNumber>
683 internal::SymmetricTensorAccessors::Accessor<rank,dim,
true,rank-1,Number>
690 internal::SymmetricTensorAccessors::Accessor<rank,dim,
false,rank-1,Number>
781 template <
class Archive>
782 void serialize(Archive &ar,
const unsigned int version);
810 template <
int dim2,
typename Number2>
813 template <
int dim2,
typename Number2>
816 template <
int dim2,
typename Number2>
820 template <
int dim2,
typename Number2>
823 template <
int dim2,
typename Number2>
826 template <
int dim2,
typename Number2>
829 template <
int dim2,
typename Number2>
832 template <
int dim2,
typename Number2>
844 namespace SymmetricTensorAccessors
846 template <
int rank,
int dim,
bool constness,
int P,
typename Number>
847 Accessor<rank,dim,constness,P,Number>::
848 Accessor (tensor_type &tensor,
852 previous_indices (previous_indices)
856 template <
int rank,
int dim,
bool constness,
int P,
typename Number>
857 Accessor<rank,dim,constness,P,Number>::
858 Accessor (
const Accessor &a)
861 previous_indices (a.previous_indices)
866 template <
int rank,
int dim,
bool constness,
int P,
typename Number>
867 Accessor<rank,dim,constness,P-1,Number>
868 Accessor<rank,dim,constness,P,Number>::operator[] (
const unsigned int i)
870 return Accessor<rank,dim,constness,P-1,Number> (tensor,
871 merge (previous_indices, i, rank-P));
876 template <
int rank,
int dim,
bool constness,
int P,
typename Number>
877 Accessor<rank,dim,constness,P-1,Number>
878 Accessor<rank,dim,constness,P,Number>::operator[] (
const unsigned int i)
const 880 return Accessor<rank,dim,constness,P-1,Number> (tensor,
881 merge (previous_indices, i, rank-P));
886 template <
int rank,
int dim,
bool constness,
typename Number>
887 Accessor<rank,dim,constness,1,Number>::
888 Accessor (tensor_type &tensor,
892 previous_indices (previous_indices)
897 template <
int rank,
int dim,
bool constness,
typename Number>
898 Accessor<rank,dim,constness,1,Number>::
899 Accessor (
const Accessor &a)
902 previous_indices (a.previous_indices)
907 template <
int rank,
int dim,
bool constness,
typename Number>
908 typename Accessor<rank,dim,constness,1,Number>::reference
909 Accessor<rank,dim,constness,1,Number>::operator[] (
const unsigned int i)
911 return tensor(merge (previous_indices, i, rank-1));
915 template <
int rank,
int dim,
bool constness,
typename Number>
916 typename Accessor<rank,dim,constness,1,Number>::reference
917 Accessor<rank,dim,constness,1,Number>::operator[] (
const unsigned int i)
const 919 return tensor(merge (previous_indices, i, rank-1));
926 template <
int rank,
int dim,
typename Number>
933 template <
int rank,
int dim,
typename Number>
962 for (
unsigned int d=0;
d<dim; ++
d)
963 for (
unsigned int e=0;
e<
d; ++
e)
966 for (
unsigned int d=0;
d<dim; ++
d)
969 for (
unsigned int d=0, c=0;
d<dim; ++
d)
970 for (
unsigned int e=d+1;
e<dim; ++
e, ++c)
971 data[dim+c] = t[d][e];
977 template <
int rank,
int dim,
typename Number>
978 template <
typename OtherNumber>
983 for (
unsigned int i=0; i<base_tensor_type::dimension; ++i)
984 data[i] = initializer.
data[i];
990 template <
int rank,
int dim,
typename Number>
994 data (*reinterpret_cast<const typename base_tensor_type::array_type *>(array))
997 Assert (
sizeof(
typename base_tensor_type::array_type)
1004 template <
int rank,
int dim,
typename Number>
1022 template <
int dim,
typename Number>
1024 convert_to_tensor (const ::SymmetricTensor<2,dim,Number> &s)
1029 for (
unsigned int d=0;
d<dim; ++
d)
1030 t[d][d] = s.access_raw_entry(d);
1033 for (
unsigned int d=0, c=0;
d<dim; ++
d)
1034 for (
unsigned int e=d+1;
e<dim; ++
e, ++c)
1036 t[
d][
e] = s.access_raw_entry(dim+c);
1037 t[
e][
d] = s.access_raw_entry(dim+c);
1039 return ::Tensor<2,dim,Number>(t);
1043 template <
int dim,
typename Number>
1045 convert_to_tensor (const ::SymmetricTensor<4,dim,Number> &st)
1052 for (
unsigned int i=0; i<dim; ++i)
1053 for (
unsigned int j=i; j<dim; ++j)
1054 for (
unsigned int k=0; k<dim; ++k)
1055 for (
unsigned int l=k;
l<dim; ++
l)
1069 template <
int rank,
int dim,
typename Number>
1074 return internal::SymmetricTensor::convert_to_tensor (*
this);
1079 template <
int rank,
int dim,
typename Number>
1085 return data == t.data;
1090 template <
int rank,
int dim,
typename Number>
1096 return data != t.data;
1101 template <
int rank,
int dim,
typename Number>
1113 template <
int rank,
int dim,
typename Number>
1125 template <
int rank,
int dim,
typename Number>
1136 template <
int rank,
int dim,
typename Number>
1147 template <
int rank,
int dim,
typename Number>
1159 template <
int rank,
int dim,
typename Number>
1171 template <
int rank,
int dim,
typename Number>
1183 template <
int rank,
int dim,
typename Number>
1193 template <
int rank,
int dim,
typename Number>
1208 template <
int dim,
typename Number>
1210 typename SymmetricTensorAccessors::double_contraction_result<2,2,dim,Number>::type
1217 return data[0] * sdata[0];
1221 Number
sum = data[dim] * sdata[dim];
1222 for (
unsigned int d=dim+1;
d<(dim*(dim+1)/2); ++
d)
1223 sum += data[d] * sdata[d];
1227 for (
unsigned int d=0;
d<dim; ++
d)
1228 sum += data[d] * sdata[d];
1235 template <
int dim,
typename Number>
1237 typename SymmetricTensorAccessors::double_contraction_result<4,2,dim,Number>::type
1241 const unsigned int data_dim =
1243 Number tmp [data_dim];
1244 for (
unsigned int i=0; i<data_dim; ++i)
1245 tmp[i] = perform_double_contraction<dim,Number>(data[i], sdata);
1246 return ::SymmetricTensor<2,dim,Number>(tmp);
1251 template <
int dim,
typename Number>
1258 for (
unsigned int i=0; i<tmp.dimension; ++i)
1261 Number
sum = data[dim] * sdata[dim][i];
1262 for (
unsigned int d=dim+1;
d<(dim*(dim+1)/2); ++
d)
1263 sum += data[d] * sdata[d][i];
1267 for (
unsigned int d=0;
d<dim; ++
d)
1268 sum += data[d] * sdata[d][i];
1276 template <
int dim,
typename Number>
1282 const unsigned int data_dim =
1285 for (
unsigned int i=0; i<data_dim; ++i)
1286 for (
unsigned int j=0; j<data_dim; ++j)
1289 for (
unsigned int d=dim;
d<(dim*(dim+1)/2); ++
d)
1290 tmp[i][j] += data[i][d] * sdata[d][j];
1291 tmp[i][j] += tmp[i][j];
1294 for (
unsigned int d=0;
d<dim; ++
d)
1295 tmp[i][j] += data[i][d] * sdata[d][j];
1304 template <
int rank,
int dim,
typename Number>
1313 return internal::perform_double_contraction<dim,Number> (data, s.
data);
1318 template <
int rank,
int dim,
typename Number>
1323 typename internal::SymmetricTensorAccessors::
1324 double_contraction_result<rank,4,dim,Number>::type tmp;
1325 tmp.
data = internal::perform_double_contraction<dim,Number> (data,s.
data);
1341 template <
int dim,
typename Number>
1353 if (indices[0] == indices[1])
1354 return data[indices[0]];
1361 Assert (((indices[0]==1) && (indices[1]==0)) ||
1362 ((indices[0]==0) && (indices[1]==1)),
1370 sorted_indices.sort ();
1372 for (
unsigned int d=0, c=0;
d<dim; ++
d)
1373 for (
unsigned int e=d+1;
e<dim; ++
e, ++c)
1374 if ((sorted_indices[0]==d) && (sorted_indices[1]==e))
1380 static Number dummy_but_referenceable = Number();
1381 return dummy_but_referenceable;
1386 template <
int dim,
typename Number>
1398 if (indices[0] == indices[1])
1399 return data[indices[0]];
1406 Assert (((indices[0]==1) && (indices[1]==0)) ||
1407 ((indices[0]==0) && (indices[1]==1)),
1415 sorted_indices.sort ();
1417 for (
unsigned int d=0, c=0;
d<dim; ++
d)
1418 for (
unsigned int e=d+1;
e<dim; ++
e, ++c)
1419 if ((sorted_indices[0]==d) && (sorted_indices[1]==e))
1425 static Number dummy_but_referenceable = Number();
1426 return dummy_but_referenceable;
1431 template <
int dim,
typename Number>
1453 unsigned int base_index[2] ;
1454 if ((indices[0] == 0) && (indices[1] == 0))
1456 else if ((indices[0] == 1) && (indices[1] == 1))
1461 if ((indices[2] == 0) && (indices[3] == 0))
1463 else if ((indices[2] == 1) && (indices[3] == 1))
1468 return data[base_index[0]][base_index[1]];
1482 unsigned int base_index[2] ;
1483 if ((indices[0] == 0) && (indices[1] == 0))
1485 else if ((indices[0] == 1) && (indices[1] == 1))
1487 else if ((indices[0] == 2) && (indices[1] == 2))
1489 else if (((indices[0] == 0) && (indices[1] == 1)) ||
1490 ((indices[0] == 1) && (indices[1] == 0)))
1492 else if (((indices[0] == 0) && (indices[1] == 2)) ||
1493 ((indices[0] == 2) && (indices[1] == 0)))
1497 Assert (((indices[0] == 1) && (indices[1] == 2)) ||
1498 ((indices[0] == 2) && (indices[1] == 1)),
1503 if ((indices[2] == 0) && (indices[3] == 0))
1505 else if ((indices[2] == 1) && (indices[3] == 1))
1507 else if ((indices[2] == 2) && (indices[3] == 2))
1509 else if (((indices[2] == 0) && (indices[3] == 1)) ||
1510 ((indices[2] == 1) && (indices[3] == 0)))
1512 else if (((indices[2] == 0) && (indices[3] == 2)) ||
1513 ((indices[2] == 2) && (indices[3] == 0)))
1517 Assert (((indices[2] == 1) && (indices[3] == 2)) ||
1518 ((indices[2] == 2) && (indices[3] == 1)),
1523 return data[base_index[0]][base_index[1]];
1530 static Number dummy;
1535 template <
int dim,
typename Number>
1557 unsigned int base_index[2] ;
1558 if ((indices[0] == 0) && (indices[1] == 0))
1560 else if ((indices[0] == 1) && (indices[1] == 1))
1565 if ((indices[2] == 0) && (indices[3] == 0))
1567 else if ((indices[2] == 1) && (indices[3] == 1))
1572 return data[base_index[0]][base_index[1]];
1586 unsigned int base_index[2] ;
1587 if ((indices[0] == 0) && (indices[1] == 0))
1589 else if ((indices[0] == 1) && (indices[1] == 1))
1591 else if ((indices[0] == 2) && (indices[1] == 2))
1593 else if (((indices[0] == 0) && (indices[1] == 1)) ||
1594 ((indices[0] == 1) && (indices[1] == 0)))
1596 else if (((indices[0] == 0) && (indices[1] == 2)) ||
1597 ((indices[0] == 2) && (indices[1] == 0)))
1601 Assert (((indices[0] == 1) && (indices[1] == 2)) ||
1602 ((indices[0] == 2) && (indices[1] == 1)),
1607 if ((indices[2] == 0) && (indices[3] == 0))
1609 else if ((indices[2] == 1) && (indices[3] == 1))
1611 else if ((indices[2] == 2) && (indices[3] == 2))
1613 else if (((indices[2] == 0) && (indices[3] == 1)) ||
1614 ((indices[2] == 1) && (indices[3] == 0)))
1616 else if (((indices[2] == 0) && (indices[3] == 2)) ||
1617 ((indices[2] == 2) && (indices[3] == 0)))
1621 Assert (((indices[2] == 1) && (indices[3] == 2)) ||
1622 ((indices[2] == 2) && (indices[3] == 1)),
1627 return data[base_index[0]][base_index[1]];
1634 static Number dummy;
1642 template <
int rank,
int dim,
typename Number>
1647 for (
unsigned int r=0; r<rank; ++r)
1649 return internal::symmetric_tensor_access<dim,Number> (indices, data);
1654 template <
int rank,
int dim,
typename Number>
1660 for (
unsigned int r=0; r<rank; ++r)
1662 return internal::symmetric_tensor_access<dim,Number> (indices, data);
1667 template <
int rank,
int dim,
typename Number>
1668 internal::SymmetricTensorAccessors::Accessor<rank,dim,
true,rank-1,Number>
1672 internal::SymmetricTensorAccessors::
1678 template <
int rank,
int dim,
typename Number>
1679 internal::SymmetricTensorAccessors::Accessor<rank,dim,
false,rank-1,Number>
1683 internal::SymmetricTensorAccessors::
1689 template <
int rank,
int dim,
typename Number>
1694 return operator()(indices);
1699 template <
int rank,
int dim,
typename Number>
1704 return operator()(indices);
1714 template <
int dim,
typename Number>
1716 entry_to_indices (const ::SymmetricTensor<2,dim,Number> &,
1717 const unsigned int index)
1723 template <
int dim,
typename Number>
1725 entry_to_indices (const ::SymmetricTensor<4,dim,Number> &,
1726 const unsigned int index)
1738 template <
int rank,
int dim,
typename Number>
1744 return data[internal::SymmetricTensor::entry_to_indices(*
this, index)];
1749 template <
int rank,
int dim,
typename Number>
1755 return data[internal::SymmetricTensor::entry_to_indices(*
this, index)];
1762 template <
int dim,
typename Number>
1790 for (
unsigned int d=0;
d<dim; ++
d)
1792 for (
unsigned int d=dim;
d<(dim*dim+dim)/2; ++
d)
1795 return std::sqrt(return_value);
1802 template <
int dim,
typename Number>
1817 const unsigned int n_independent_components = data.dimension;
1819 for (
unsigned int i=0; i<dim; ++i)
1820 for (
unsigned int j=0; j<dim; ++j)
1822 for (
unsigned int i=0; i<dim; ++i)
1823 for (
unsigned int j=dim; j<n_independent_components; ++j)
1825 for (
unsigned int i=dim; i<n_independent_components; ++i)
1826 for (
unsigned int j=0; j<dim; ++j)
1828 for (
unsigned int i=dim; i<n_independent_components; ++i)
1829 for (
unsigned int j=dim; j<n_independent_components; ++j)
1832 return std::sqrt(return_value);
1841 template <
int rank,
int dim,
typename Number>
1846 return internal::compute_norm<dim,Number> (data);
1865 component_to_unrolled_index
1880 static const unsigned int table[2][2] = {{0, 2},
1883 return table[indices[0]][indices[1]];
1888 static const unsigned int table[3][3] = {{0, 3, 4},
1892 return table[indices[0]][indices[1]];
1897 static const unsigned int table[4][4] = {{0, 4, 5, 6},
1902 return table[indices[0]][indices[1]];
1908 if (indices[0] == indices[1])
1912 sorted_indices.sort ();
1914 for (
unsigned int d=0, c=0;
d<dim; ++
d)
1915 for (
unsigned int e=d+1;
e<dim; ++
e, ++c)
1916 if ((sorted_indices[0]==d) && (sorted_indices[1]==e))
1932 template <
int dim,
int rank>
1935 component_to_unrolled_index
1947 template <
int rank,
int dim,
typename Number>
1953 return internal::SymmetricTensor::component_to_unrolled_index<dim> (indices);
1974 unrolled_to_component_indices
1975 (
const unsigned int i,
1976 const int2type<2> &)
2016 for (
unsigned int d=0, c=0;
d<dim; ++
d)
2017 for (
unsigned int e=d+1;
e<dim; ++
e, ++c)
2035 template <
int dim,
int rank>
2038 unrolled_to_component_indices
2039 (
const unsigned int i,
2040 const int2type<rank> &)
2053 template <
int rank,
int dim,
typename Number>
2057 (
const unsigned int i)
2060 internal::SymmetricTensor::unrolled_to_component_indices<dim> (i,
2066 template <
int rank,
int dim,
typename Number>
2067 template <
class Archive>
2087 template <
int rank,
int dim,
typename Number,
typename OtherNumber>
2103 template <
int rank,
int dim,
typename Number,
typename OtherNumber>
2119 template <
int rank,
int dim,
typename Number,
typename OtherNumber>
2135 template <
int rank,
int dim,
typename Number,
typename OtherNumber>
2159 template <
int dim,
typename Number>
2198 template <
int dim,
typename Number>
2214 template <
int dim,
typename Number>
2217 Number t = d.data[0];
2218 for (
unsigned int i=1; i<dim; ++i)
2233 template <
int dim,
typename Number>
2253 template <
typename Number>
2282 template <
typename Number>
2286 return t[0][0]*t[1][1] - t[0][1]*t[0][1];
2300 template <
typename Number>
2304 return (t[0][0]*t[1][1] + t[1][1]*t[2][2] + t[2][2]*t[0][0]
2305 - t[0][1]*t[0][1] - t[0][2]*t[0][2] - t[1][2]*t[1][2]);
2320 template <
int rank,
int dim,
typename Number>
2339 template <
int dim,
typename Number>
2347 const Number tr =
trace(t) / dim;
2348 for (
unsigned int i=0; i<dim; ++i)
2363 template <
int dim,
typename Number>
2366 unit_symmetric_tensor ()
2383 for (
unsigned int d=0; d<dim; ++d)
2402 unit_symmetric_tensor ()
2404 return unit_symmetric_tensor<dim,double>();
2423 template <
int dim,
typename Number>
2431 for (
unsigned int i=0; i<dim; ++i)
2432 for (
unsigned int j=0; j<dim; ++j)
2433 tmp.
data[i][j] = (i==j ? 1 : 0) - 1./dim;
2440 for (
unsigned int i=dim;
2441 i<internal::SymmetricTensorAccessors::StorageType<4,dim,Number>::n_rank2_components;
2443 tmp.
data[i][i] = 0.5;
2469 return deviator_tensor<dim,double>();
2496 template <
int dim,
typename Number>
2504 for (
unsigned int i=0; i<dim; ++i)
2512 for (
unsigned int i=dim;
2513 i<internal::SymmetricTensorAccessors::StorageType<4,dim,Number>::n_rank2_components;
2515 tmp.
data[i][i] = 0.5;
2548 return identity_tensor<dim,double>();
2563 template <
int dim,
typename Number>
2580 template <
typename Number>
2587 tmp[0][0] = 1.0/t[0][0];
2594 template <
typename Number>
2607 const Number inv_det_t
2608 = 1.0/(t[idx_00]*t[idx_11]
2609 - t[idx_01]*t[idx_01]);
2610 tmp[idx_00] = t[idx_11];
2611 tmp[idx_01] = -t[idx_01];
2612 tmp[idx_11] = t[idx_00];
2620 template <
typename Number>
2643 const Number inv_det_t
2644 = 1.0/(t[idx_00]*t[idx_11]*t[idx_22]
2645 - t[idx_00]*t[idx_12]*t[idx_12]
2646 - t[idx_01]*t[idx_01]*t[idx_22]
2647 + 2.0*t[idx_01]*t[idx_02]*t[idx_12]
2648 - t[idx_02]*t[idx_02]*t[idx_11]);
2649 tmp[idx_00] = t[idx_11]*t[idx_22] - t[idx_12]*t[idx_12];
2650 tmp[idx_01] = -t[idx_01]*t[idx_22] + t[idx_02]*t[idx_12];
2651 tmp[idx_02] = t[idx_01]*t[idx_12] - t[idx_02]*t[idx_11];
2652 tmp[idx_11] = t[idx_00]*t[idx_22] - t[idx_02]*t[idx_02];
2653 tmp[idx_12] = -t[idx_00]*t[idx_12] + t[idx_01]*t[idx_02];
2654 tmp[idx_22] = t[idx_00]*t[idx_11] - t[idx_01]*t[idx_01];
2677 template <
int dim,
typename Number>
2723 const Number t4 = t.
data[0][0]*t.
data[1][1],
2729 t07 = 1.0/(t4*t.
data[2][2]-t6*t.
data[2][1]-
2731 t01*t.
data[1][2]-t04*t.
data[1][1]);
2737 tmp.
data[1][2] = -(t6-t00)*t07;
2740 tmp.
data[2][2] = (t4-t8)*t07;
2744 tmp.
data[2][0] /= 2;
2745 tmp.
data[2][1] /= 2;
2746 tmp.
data[0][2] /= 2;
2747 tmp.
data[1][2] /= 2;
2748 tmp.
data[2][2] /= 4;
2793 template <
int dim,
typename Number>
2802 for (
unsigned int i=0; i<dim; ++i)
2803 for (
unsigned int j=i; j<dim; ++j)
2804 for (
unsigned int k=0; k<dim; ++k)
2805 for (
unsigned int l=k; l<dim; ++l)
2806 tmp[i][j][k][l] = t1[i][j] * t2[k][l];
2821 template <
int dim,
typename Number>
2826 Number array[(dim*dim+dim)/2];
2827 for (
unsigned int d=0; d<dim; ++d)
2829 for (
unsigned int d=0, c=0; d<dim; ++d)
2830 for (
unsigned int e=d+1; e<dim; ++e, ++c)
2831 array[dim+c] = (t[d][e]+t[e][d])*0.5;
2844 template <
int rank,
int dim,
typename Number>
2848 const Number factor)
2864 template <
int rank,
int dim,
typename Number>
2875 #ifndef DEAL_II_WITH_CXX11 2877 template <
typename T,
typename U,
int rank,
int dim>
2883 template <
typename T,
typename U,
int rank,
int dim>
2918 template <
int rank,
int dim,
typename Number,
typename OtherNumber>
2922 const OtherNumber factor)
2938 product_type new_factor;
2939 new_factor = factor;
2954 template <
int rank,
int dim,
typename Number,
typename OtherNumber>
2971 template <
int rank,
int dim,
typename Number>
2975 const Number factor)
2990 template <
int rank,
int dim>
2994 const double factor)
3009 template <
int rank,
int dim>
3027 template <
int rank,
int dim>
3031 const double factor)
3047 template <
int dim,
typename Number>
3066 template <
int dim,
typename Number>
3073 for (
unsigned int i=0; i<dim; ++i)
3074 for (
unsigned int j=0; j<dim; ++j)
3075 s += t1[i][j] * t2[i][j];
3089 template <
int dim,
typename Number>
3114 template <
typename Number>
3121 tmp[0][0] = t[0][0][0][0] * s[0][0];
3141 template <
typename Number>
3148 tmp[0][0] = t[0][0][0][0] * s[0][0];
3167 template <
typename Number>
3174 const unsigned int dim = 2;
3176 for (
unsigned int i=0; i<dim; ++i)
3177 for (
unsigned int j=i; j<dim; ++j)
3178 tmp[i][j] = t[i][j][0][0] * s[0][0] +
3179 t[i][j][1][1] * s[1][1] +
3180 2 * t[i][j][0][1] * s[0][1];
3200 template <
typename Number>
3207 const unsigned int dim = 2;
3209 for (
unsigned int i=0; i<dim; ++i)
3210 for (
unsigned int j=i; j<dim; ++j)
3211 tmp[i][j] = s[0][0] * t[0][0][i][j] * +
3212 s[1][1] * t[1][1][i][j] +
3213 2 * s[0][1] * t[0][1][i][j];
3233 template <
typename Number>
3240 const unsigned int dim = 3;
3242 for (
unsigned int i=0; i<dim; ++i)
3243 for (
unsigned int j=i; j<dim; ++j)
3244 tmp[i][j] = t[i][j][0][0] * s[0][0] +
3245 t[i][j][1][1] * s[1][1] +
3246 t[i][j][2][2] * s[2][2] +
3247 2 * t[i][j][0][1] * s[0][1] +
3248 2 * t[i][j][0][2] * s[0][2] +
3249 2 * t[i][j][1][2] * s[1][2];
3269 template <
typename Number>
3276 const unsigned int dim = 3;
3278 for (
unsigned int i=0; i<dim; ++i)
3279 for (
unsigned int j=i; j<dim; ++j)
3280 tmp[i][j] = s[0][0] * t[0][0][i][j] +
3281 s[1][1] * t[1][1][i][j] +
3282 s[2][2] * t[2][2][i][j] +
3283 2 * s[0][1] * t[0][1][i][j] +
3284 2 * s[0][2] * t[0][2][i][j] +
3285 2 * s[1][2] * t[1][2][i][j];
3297 template <
int dim,
typename Number>
3303 for (
unsigned int i=0; i<dim; ++i)
3304 for (
unsigned int j=0; j<dim; ++j)
3305 dest[i] += src1[i][j] * src2[j];
3317 template <
int dim,
typename Number>
3336 template <
int dim,
typename Number>
3346 for (
unsigned int i=0; i<dim; ++i)
3347 for (
unsigned int j=0; j<dim; ++j)
3364 template <
int dim,
typename Number>
3374 for (
unsigned int i=0; i<dim; ++i)
3375 for (
unsigned int j=0; j<dim; ++j)
3376 for (
unsigned int k=0; k<dim; ++k)
3377 for (
unsigned int l=0; l<dim; ++l)
3378 tt[i][j][k][l] = t[i][j][k][l];
3384 DEAL_II_NAMESPACE_CLOSE
friend SymmetricTensor< 4, dim2, Number2 > identity_tensor()
Tensor< 2, n_rank2_components, Number > base_tensor_type
static const unsigned int invalid_unsigned_int
Tensor< rank, dim, typename ProductType< Number, OtherNumber >::type > operator+(const SymmetricTensor< rank, dim, Number > &left, const Tensor< rank, dim, OtherNumber > &right)
void double_contract(SymmetricTensor< 2, 2, Number > &tmp, const SymmetricTensor< 4, 2, Number > &t, const SymmetricTensor< 2, 2, Number > &s)
SymmetricTensor operator-() const
Tensor< rank, dim, typename ProductType< Number, OtherNumber >::type > operator+(const Tensor< rank, dim, Number > &left, const SymmetricTensor< rank, dim, OtherNumber > &right)
SymmetricTensor< rank, dim, Number > operator/(const SymmetricTensor< rank, dim, Number > &t, const Number factor)
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
static const unsigned int n_independent_components
SymmetricTensor< 2, dim, Number > symmetrize(const Tensor< 2, dim, Number > &t)
void double_contract(SymmetricTensor< 2, 3, Number > &tmp, const SymmetricTensor< 2, 3, Number > &s, const SymmetricTensor< 4, 3, Number > &t)
void double_contract(SymmetricTensor< 2, 1, Number > &tmp, const SymmetricTensor< 4, 1, Number > &t, const SymmetricTensor< 2, 1, Number > &s)
#define AssertIndexRange(index, range)
static TableIndices< rank > unrolled_to_component_indices(const unsigned int i)
void double_contract(SymmetricTensor< 2, 1, Number > &tmp, const SymmetricTensor< 2, 1, Number > &s, const SymmetricTensor< 4, 1, Number > &t)
TableIndices< 2 > merge(const TableIndices< 2 > &previous_indices, const unsigned int new_index, const unsigned int position)
#define AssertThrow(cond, exc)
static real_type abs(const number &x)
bool operator!=(const SymmetricTensor &) const
static ::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
void serialize(Archive &ar, const unsigned int version)
static const unsigned int dimension
static const unsigned int n_independent_components
static unsigned int component_to_unrolled_index(const TableIndices< rank > &indices)
internal::SymmetricTensorAccessors::double_contraction_result< rank, 2, dim, Number >::type operator*(const SymmetricTensor< 2, dim, Number > &s) const
bool operator==(const SymmetricTensor &) const
void double_contract(SymmetricTensor< 2, 2, Number > &tmp, const SymmetricTensor< 2, 2, Number > &s, const SymmetricTensor< 4, 2, Number > &t)
static ::ExceptionBase & ExcMessage(std::string arg1)
static std::size_t memory_consumption()
numbers::NumberTraits< Number >::real_type norm() const
Number second_invariant(const SymmetricTensor< 2, 2, Number > &t)
Number first_invariant(const SymmetricTensor< 2, dim, Number > &t)
SymmetricTensor & operator-=(const SymmetricTensor &)
friend Number2 trace(const SymmetricTensor< 2, dim2, Number2 > &d)
T sum(const T &t, const MPI_Comm &mpi_communicator)
#define Assert(cond, exc)
base_tensor_descriptor::base_tensor_type base_tensor_type
SymmetricTensor< rank, dim, Number > transpose(const SymmetricTensor< rank, dim, Number > &t)
Tensor< rank, dim, typename ProductType< Number, OtherNumber >::type > operator-(const SymmetricTensor< rank, dim, Number > &left, const Tensor< rank, dim, OtherNumber > &right)
SymmetricTensor< 2, dim, Number > deviator(const SymmetricTensor< 2, dim, Number > &t)
Number trace(const SymmetricTensor< 2, dim, Number > &d)
Sacado::Fad::DFad< T > scalar_product(const SymmetricTensor< 2, dim, Sacado::Fad::DFad< T > > &t1, const Tensor< 2, dim, Number > &t2)
internal::SymmetricTensorAccessors::StorageType< rank, dim, Number > base_tensor_descriptor
friend SymmetricTensor< 2, dim2, Number2 > unit_symmetric_tensor()
Tensor< rank, dim, typename ProductType< Number, OtherNumber >::type > operator-(const Tensor< rank, dim, Number > &left, const SymmetricTensor< rank, dim, OtherNumber > &right)
SymmetricTensor< 4, dim, Number > outer_product(const SymmetricTensor< 2, dim, Number > &t1, const SymmetricTensor< 2, dim, Number > &t2)
Number scalar_product(const SymmetricTensor< 2, dim, Number > &t1, const SymmetricTensor< 2, dim, Number > &t2)
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
Number access_raw_entry(const unsigned int unrolled_index) const
void double_contract(SymmetricTensor< 2, 3, Number > &tmp, const SymmetricTensor< 4, 3, Number > &t, const SymmetricTensor< 2, 3, Number > &s)
Number scalar_product(const SymmetricTensor< 2, dim, Number > &t1, const Tensor< 2, dim, Number > &t2)
OutputOperator< VectorType > & operator<<(OutputOperator< VectorType > &out, unsigned int step)
Number determinant(const SymmetricTensor< 2, dim, Number > &t)
internal::SymmetricTensorAccessors::Accessor< rank, dim, true, rank-1, Number > operator[](const unsigned int row) const
SymmetricTensor & operator/=(const Number factor)
SymmetricTensor operator+(const SymmetricTensor &s) const
Number third_invariant(const SymmetricTensor< 2, dim, Number > &t)
Number & operator()(const TableIndices< rank > &indices)
Tensor< 1, n_independent_components, Number > base_tensor_type
static ::ExceptionBase & ExcNotImplemented()
SymmetricTensor< 4, dim, Number > invert(const SymmetricTensor< 4, dim, Number > &t)
SymmetricTensor & operator+=(const SymmetricTensor &)
SymmetricTensor & operator*=(const Number factor)
SymmetricTensor< 2, dim, Number > invert(const SymmetricTensor< 2, dim, Number > &)
Number second_invariant(const SymmetricTensor< 2, 3, Number > &t)
friend SymmetricTensor< 4, dim2, Number2 > deviator_tensor()
Point< dim, typename ProductType< Number, typename EnableIfScalar< OtherNumber >::type >::type > operator*(const OtherNumber) const
Number scalar_product(const Tensor< 2, dim, Number > &t1, const SymmetricTensor< 2, dim, Number > &t2)
SymmetricTensor & operator=(const Number d)
Number second_invariant(const SymmetricTensor< 2, 1, Number > &)
Tensor< 2, dim, Number > l(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
static ::ExceptionBase & ExcInternalError()