16 #ifndef dealii__symmetric_tensor_h 17 #define dealii__symmetric_tensor_h 20 #include <deal.II/base/tensor.h> 21 #include <deal.II/base/table_indices.h> 22 #include <deal.II/base/template_constraints.h> 24 DEAL_II_NAMESPACE_OPEN
26 template <
int rank,
int dim,
typename Number=
double>
class SymmetricTensor;
36 template <
int dim2,
typename Number> Number
41 template <
int dim,
typename Number> Number
52 namespace SymmetricTensorAccessors
62 const unsigned int new_index,
63 const unsigned int position)
65 Assert (position < 2, ExcIndexRange (position, 0, 2));
83 const unsigned int new_index,
84 const unsigned int position)
86 Assert (position < 4, ExcIndexRange (position, 0, 4));
105 Assert (
false, ExcInternalError());
118 template <
int rank1,
int rank2,
int dim,
typename Number>
121 typedef ::SymmetricTensor<rank1+rank2-4,dim,Number>
type;
133 template <
int dim,
typename Number>
153 template <
int rank,
int dim,
typename Number>
159 template <
int dim,
typename Number>
166 static const unsigned int 167 n_independent_components = (dim*dim + dim)/2;
180 template <
int dim,
typename Number>
188 static const unsigned int 189 n_rank2_components = (dim*dim + dim)/2;
194 static const unsigned int 195 n_independent_components = (n_rank2_components *
213 template <
int rank,
int dim,
bool constness,
typename Number>
222 template <
int rank,
int dim,
typename Number>
225 typedef const ::SymmetricTensor<rank,dim,Number>
tensor_type;
227 typedef Number reference;
236 template <
int rank,
int dim,
typename Number>
239 typedef ::SymmetricTensor<rank,dim,Number>
tensor_type;
241 typedef Number &reference;
279 template <
int rank,
int dim,
bool constness,
int P,
typename Number>
308 Accessor (tensor_type &tensor,
319 Accessor (
const Accessor &a);
326 Accessor<rank,dim,constness,P-1,Number> operator [] (
const unsigned int i);
339 template <
int,
int,
typename>
friend class ::SymmetricTensor;
340 template <
int,
int,
bool,
int,
typename>
341 friend class Accessor;
342 # ifndef DEAL_II_TEMPL_SPEC_FRIEND_BUG 343 friend class ::SymmetricTensor<rank,dim,Number>;
344 friend class Accessor<rank,dim,constness,P+1,Number>;
359 template <
int rank,
int dim,
bool constness,
typename Number>
360 class Accessor<rank,dim,constness,1,Number>
391 Accessor (tensor_type &tensor,
402 Accessor (
const Accessor &a);
409 reference operator [] (
const unsigned int);
422 template <
int,
int,
typename>
friend class ::SymmetricTensor;
423 template <
int,
int,
bool,
int,
typename>
424 friend class SymmetricTensorAccessors::Accessor;
425 # ifndef DEAL_II_TEMPL_SPEC_FRIEND_BUG 426 friend class ::SymmetricTensor<rank,dim,Number>;
427 friend class SymmetricTensorAccessors::Accessor<rank,dim,constness,2,Number>;
497 template <
int rank,
int dim,
typename Number>
509 static const unsigned int dimension = dim;
516 static const unsigned int n_independent_components
518 n_independent_components;
559 template <
typename OtherNumber>
682 internal::SymmetricTensorAccessors::Accessor<rank,dim,
true,rank-1,Number>
683 operator [] (
const unsigned int row)
const;
689 internal::SymmetricTensorAccessors::Accessor<rank,dim,
false,rank-1,Number>
690 operator [] (
const unsigned int row);
710 access_raw_entry (
const unsigned int unrolled_index)
const;
718 access_raw_entry (
const unsigned int unrolled_index);
729 Number norm ()
const;
749 unrolled_to_component_indices (
const unsigned int i);
769 static std::size_t memory_consumption ();
775 template <
class Archive>
776 void serialize(Archive &ar,
const unsigned int version);
804 template <
int dim2,
typename Number2>
807 template <
int dim2,
typename Number2>
810 template <
int dim2,
typename Number2>
814 template <
int dim2,
typename Number2>
817 template <
int dim2,
typename Number2>
820 template <
int dim2,
typename Number2>
823 template <
int dim2,
typename Number2>
835 namespace SymmetricTensorAccessors
837 template <
int rank,
int dim,
bool constness,
int P,
typename Number>
838 Accessor<rank,dim,constness,P,Number>::
841 tensor (*static_cast<tensor_type *>(0)),
844 Assert (
false,
ExcMessage (
"You can't call the default constructor of this class."));
848 template <
int rank,
int dim,
bool constness,
int P,
typename Number>
849 Accessor<rank,dim,constness,P,Number>::
850 Accessor (tensor_type &tensor,
854 previous_indices (previous_indices)
858 template <
int rank,
int dim,
bool constness,
int P,
typename Number>
859 Accessor<rank,dim,constness,P,Number>::
860 Accessor (
const Accessor &a)
863 previous_indices (a.previous_indices)
868 template <
int rank,
int dim,
bool constness,
int P,
typename Number>
869 Accessor<rank,dim,constness,P-1,Number>
870 Accessor<rank,dim,constness,P,Number>::operator[] (
const unsigned int i)
872 return Accessor<rank,dim,constness,P-1,Number> (tensor,
873 merge (previous_indices, i, rank-P));
878 template <
int rank,
int dim,
bool constness,
typename Number>
879 Accessor<rank,dim,constness,1,Number>::
882 tensor (*static_cast<tensor_type *>(0)),
885 Assert (
false,
ExcMessage (
"You can't call the default constructor of this class."));
890 template <
int rank,
int dim,
bool constness,
typename Number>
891 Accessor<rank,dim,constness,1,Number>::
892 Accessor (tensor_type &tensor,
896 previous_indices (previous_indices)
901 template <
int rank,
int dim,
bool constness,
typename Number>
902 Accessor<rank,dim,constness,1,Number>::
903 Accessor (
const Accessor &a)
906 previous_indices (a.previous_indices)
911 template <
int rank,
int dim,
bool constness,
typename Number>
912 typename Accessor<rank,dim,constness,1,Number>::reference
913 Accessor<rank,dim,constness,1,Number>::operator[] (
const unsigned int i)
915 return tensor(merge (previous_indices, i, rank-1));
924 template <
int rank,
int dim,
typename Number>
931 template <
int rank,
int dim,
typename Number>
935 Assert (rank == 2, ExcNotImplemented());
939 Assert (t[0][1] == t[1][0], ExcInternalError());
947 Assert (t[0][1] == t[1][0], ExcInternalError());
948 Assert (t[0][2] == t[2][0], ExcInternalError());
949 Assert (t[1][2] == t[2][1], ExcInternalError());
960 for (
unsigned int d=0; d<dim; ++d)
961 for (
unsigned int e=0; e<d; ++e)
962 Assert(t[d][e] == t[e][d], ExcInternalError());
964 for (
unsigned int d=0; d<dim; ++d)
967 for (
unsigned int d=0, c=0; d<dim; ++d)
968 for (
unsigned int e=d+1; e<dim; ++e, ++c)
969 data[dim+c] = t[d][e];
975 template <
int rank,
int dim,
typename Number>
976 template <
typename OtherNumber>
988 template <
int rank,
int dim,
typename Number>
995 Assert (
sizeof(
typename base_tensor_type::array_type)
1002 template <
int rank,
int dim,
typename Number>
1013 template <
int rank,
int dim,
typename Number>
1028 template <
int rank,
int dim,
typename Number>
1033 Assert (rank == 2, ExcNotImplemented());
1035 for (
unsigned int d=0; d<dim; ++d)
1037 for (
unsigned int d=0, c=0; d<dim; ++d)
1038 for (
unsigned int e=d+1; e<dim; ++e, ++c)
1040 t[d][e] =
data[dim+c];
1041 t[e][d] =
data[dim+c];
1048 template <
int rank,
int dim,
typename Number>
1054 return data == t.data;
1059 template <
int rank,
int dim,
typename Number>
1062 SymmetricTensor<rank,dim,Number>::operator !=
1065 return data != t.data;
1070 template <
int rank,
int dim,
typename Number>
1073 SymmetricTensor<rank,dim,Number>::operator +=
1082 template <
int rank,
int dim,
typename Number>
1085 SymmetricTensor<rank,dim,Number>::operator -=
1094 template <
int rank,
int dim,
typename Number>
1105 template <
int rank,
int dim,
typename Number>
1116 template <
int rank,
int dim,
typename Number>
1128 template <
int rank,
int dim,
typename Number>
1140 template <
int rank,
int dim,
typename Number>
1152 template <
int rank,
int dim,
typename Number>
1162 template <
int rank,
int dim,
typename Number>
1176 template <
int dim,
typename Number>
1178 typename SymmetricTensorAccessors::double_contraction_result<2,2,dim,Number>::type
1179 perform_double_contraction (
const typename SymmetricTensorAccessors::StorageType<2,dim,Number>::base_tensor_type &
data,
1180 const typename SymmetricTensorAccessors::StorageType<2,dim,Number>::base_tensor_type &sdata)
1185 return data[0] * sdata[0];
1187 return (data[0] * sdata[0] +
1188 data[1] * sdata[1] +
1189 2*data[2] * sdata[2]);
1193 Number
sum = data[dim] * sdata[dim];
1194 for (
unsigned int d=dim+1; d<(dim*(dim+1)/2); ++d)
1195 sum += data[d] * sdata[d];
1197 for (
unsigned int d=0; d<dim; ++d)
1198 sum += data[d] * sdata[d];
1205 template <
int dim,
typename Number>
1207 typename SymmetricTensorAccessors::double_contraction_result<4,2,dim,Number>::type
1208 perform_double_contraction (
const typename SymmetricTensorAccessors::StorageType<4,dim,Number>::base_tensor_type &data,
1209 const typename SymmetricTensorAccessors::StorageType<2,dim,Number>::base_tensor_type &sdata)
1211 const unsigned int data_dim =
1212 SymmetricTensorAccessors::StorageType<2,dim,Number>::n_independent_components;
1213 Number tmp [data_dim];
1214 for (
unsigned int i=0; i<data_dim; ++i)
1215 tmp[i] = perform_double_contraction<dim,Number>(data[i], sdata);
1216 return ::SymmetricTensor<2,dim,Number>(tmp);
1221 template <
int dim,
typename Number>
1223 typename SymmetricTensorAccessors::StorageType<2,dim,Number>::base_tensor_type
1224 perform_double_contraction (
const typename SymmetricTensorAccessors::StorageType<2,dim,Number>::base_tensor_type &data,
1225 const typename SymmetricTensorAccessors::StorageType<4,dim,Number>::base_tensor_type &sdata)
1227 typename SymmetricTensorAccessors::StorageType<2,dim,Number>::base_tensor_type tmp;
1228 for (
unsigned int i=0; i<tmp.dimension; ++i)
1230 for (
unsigned int d=0; d<dim; ++d)
1231 tmp[i] += data[d] * sdata[d][i];
1232 for (
unsigned int d=dim; d<(dim*(dim+1)/2); ++d)
1233 tmp[i] += 2 * data[d] * sdata[d][i];
1240 template <
int dim,
typename Number>
1242 typename SymmetricTensorAccessors::StorageType<4,dim,Number>::base_tensor_type
1243 perform_double_contraction (
const typename SymmetricTensorAccessors::StorageType<4,dim,Number>::base_tensor_type &data,
1244 const typename SymmetricTensorAccessors::StorageType<4,dim,Number>::base_tensor_type &sdata)
1246 const unsigned int data_dim =
1247 SymmetricTensorAccessors::StorageType<2,dim,Number>::n_independent_components;
1248 typename SymmetricTensorAccessors::StorageType<4,dim,Number>::base_tensor_type tmp;
1249 for (
unsigned int i=0; i<data_dim; ++i)
1250 for (
unsigned int j=0; j<data_dim; ++j)
1252 for (
unsigned int d=0; d<dim; ++d)
1253 tmp[i][j] += data[i][d] * sdata[d][j];
1254 for (
unsigned int d=dim; d<(dim*(dim+1)/2); ++d)
1255 tmp[i][j] += 2 * data[i][d] * sdata[d][j];
1264 template <
int rank,
int dim,
typename Number>
1273 return internal::perform_double_contraction<dim,Number> (
data, s.
data);
1278 template <
int rank,
int dim,
typename Number>
1283 typename internal::SymmetricTensorAccessors::
1284 double_contraction_result<rank,4,dim,Number>::type tmp;
1285 tmp.
data = internal::perform_double_contraction<dim,Number> (
data,s.
data);
1301 template <
int dim,
typename Number>
1305 typename SymmetricTensorAccessors::StorageType<2,dim,Number>::base_tensor_type &data)
1313 if (indices[0] == indices[1])
1314 return data[indices[0]];
1321 Assert (((indices[0]==1) && (indices[1]==0)) ||
1322 ((indices[0]==0) && (indices[1]==1)),
1323 ExcInternalError());
1330 sorted_indices.sort ();
1332 for (
unsigned int d=0, c=0; d<dim; ++d)
1333 for (
unsigned int e=d+1; e<dim; ++e, ++c)
1334 if ((sorted_indices[0]==d) && (sorted_indices[1]==e))
1336 Assert (
false, ExcInternalError());
1340 static Number dummy_but_referenceable = Number();
1341 return dummy_but_referenceable;
1346 template <
int dim,
typename Number>
1350 const typename SymmetricTensorAccessors::StorageType<2,dim,Number>::base_tensor_type &data)
1358 if (indices[0] == indices[1])
1359 return data[indices[0]];
1366 Assert (((indices[0]==1) && (indices[1]==0)) ||
1367 ((indices[0]==0) && (indices[1]==1)),
1368 ExcInternalError());
1375 sorted_indices.sort ();
1377 for (
unsigned int d=0, c=0; d<dim; ++d)
1378 for (
unsigned int e=d+1; e<dim; ++e, ++c)
1379 if ((sorted_indices[0]==d) && (sorted_indices[1]==e))
1381 Assert (
false, ExcInternalError());
1385 static Number dummy_but_referenceable = Number();
1386 return dummy_but_referenceable;
1391 template <
int dim,
typename Number>
1395 typename SymmetricTensorAccessors::StorageType<4,dim,Number>::base_tensor_type &data)
1413 unsigned int base_index[2] ;
1414 if ((indices[0] == 0) && (indices[1] == 0))
1416 else if ((indices[0] == 1) && (indices[1] == 1))
1421 if ((indices[2] == 0) && (indices[3] == 0))
1423 else if ((indices[2] == 1) && (indices[3] == 1))
1428 return data[base_index[0]][base_index[1]];
1442 unsigned int base_index[2] ;
1443 if ((indices[0] == 0) && (indices[1] == 0))
1445 else if ((indices[0] == 1) && (indices[1] == 1))
1447 else if ((indices[0] == 2) && (indices[1] == 2))
1449 else if (((indices[0] == 0) && (indices[1] == 1)) ||
1450 ((indices[0] == 1) && (indices[1] == 0)))
1452 else if (((indices[0] == 0) && (indices[1] == 2)) ||
1453 ((indices[0] == 2) && (indices[1] == 0)))
1457 Assert (((indices[0] == 1) && (indices[1] == 2)) ||
1458 ((indices[0] == 2) && (indices[1] == 1)),
1459 ExcInternalError());
1463 if ((indices[2] == 0) && (indices[3] == 0))
1465 else if ((indices[2] == 1) && (indices[3] == 1))
1467 else if ((indices[2] == 2) && (indices[3] == 2))
1469 else if (((indices[2] == 0) && (indices[3] == 1)) ||
1470 ((indices[2] == 1) && (indices[3] == 0)))
1472 else if (((indices[2] == 0) && (indices[3] == 2)) ||
1473 ((indices[2] == 2) && (indices[3] == 0)))
1477 Assert (((indices[2] == 1) && (indices[3] == 2)) ||
1478 ((indices[2] == 2) && (indices[3] == 1)),
1479 ExcInternalError());
1483 return data[base_index[0]][base_index[1]];
1487 Assert (
false, ExcNotImplemented());
1490 static Number dummy;
1495 template <
int dim,
typename Number>
1499 const typename SymmetricTensorAccessors::StorageType<4,dim,Number>::base_tensor_type &data)
1517 unsigned int base_index[2] ;
1518 if ((indices[0] == 0) && (indices[1] == 0))
1520 else if ((indices[0] == 1) && (indices[1] == 1))
1525 if ((indices[2] == 0) && (indices[3] == 0))
1527 else if ((indices[2] == 1) && (indices[3] == 1))
1532 return data[base_index[0]][base_index[1]];
1546 unsigned int base_index[2] ;
1547 if ((indices[0] == 0) && (indices[1] == 0))
1549 else if ((indices[0] == 1) && (indices[1] == 1))
1551 else if ((indices[0] == 2) && (indices[1] == 2))
1553 else if (((indices[0] == 0) && (indices[1] == 1)) ||
1554 ((indices[0] == 1) && (indices[1] == 0)))
1556 else if (((indices[0] == 0) && (indices[1] == 2)) ||
1557 ((indices[0] == 2) && (indices[1] == 0)))
1561 Assert (((indices[0] == 1) && (indices[1] == 2)) ||
1562 ((indices[0] == 2) && (indices[1] == 1)),
1563 ExcInternalError());
1567 if ((indices[2] == 0) && (indices[3] == 0))
1569 else if ((indices[2] == 1) && (indices[3] == 1))
1571 else if ((indices[2] == 2) && (indices[3] == 2))
1573 else if (((indices[2] == 0) && (indices[3] == 1)) ||
1574 ((indices[2] == 1) && (indices[3] == 0)))
1576 else if (((indices[2] == 0) && (indices[3] == 2)) ||
1577 ((indices[2] == 2) && (indices[3] == 0)))
1581 Assert (((indices[2] == 1) && (indices[3] == 2)) ||
1582 ((indices[2] == 2) && (indices[3] == 1)),
1583 ExcInternalError());
1587 return data[base_index[0]][base_index[1]];
1591 Assert (
false, ExcNotImplemented());
1594 static Number dummy;
1602 template <
int rank,
int dim,
typename Number>
1607 for (
unsigned int r=0; r<rank; ++r)
1608 Assert (indices[r] < dimension, ExcIndexRange (indices[r], 0, dimension));
1609 return internal::symmetric_tensor_access<dim,Number> (indices,
data);
1614 template <
int rank,
int dim,
typename Number>
1620 for (
unsigned int r=0; r<rank; ++r)
1621 Assert (indices[r] < dimension, ExcIndexRange (indices[r], 0, dimension));
1622 return internal::symmetric_tensor_access<dim,Number> (indices,
data);
1627 template <
int rank,
int dim,
typename Number>
1628 internal::SymmetricTensorAccessors::Accessor<rank,dim,
true,rank-1,Number>
1632 internal::SymmetricTensorAccessors::
1638 template <
int rank,
int dim,
typename Number>
1639 internal::SymmetricTensorAccessors::Accessor<rank,dim,
false,rank-1,Number>
1643 internal::SymmetricTensorAccessors::
1649 template <
int rank,
int dim,
typename Number>
1659 template <
int rank,
int dim,
typename Number>
1669 template <
int rank,
int dim,
typename Number>
1680 template <
int rank,
int dim,
typename Number>
1693 template <
int dim,
typename Number>
1696 compute_norm (
const typename SymmetricTensorAccessors::StorageType<2,dim,Number>::base_tensor_type &data)
1698 Number return_value;
1702 return_value = std::fabs(data[0]);
1705 return_value = std::sqrt(data[0]*data[0] + data[1]*data[1] +
1709 return_value = std::sqrt(data[0]*data[0] + data[1]*data[1] +
1710 data[2]*data[2] + 2*data[3]*data[3] +
1711 2*data[4]*data[4] + 2*data[5]*data[5]);
1714 return_value = Number();
1715 for (
unsigned int d=0; d<dim; ++d)
1716 return_value += data[d] * data[d];
1717 for (
unsigned int d=dim; d<(dim*dim+dim)/2; ++d)
1718 return_value += 2 * data[d] * data[d];
1719 return_value = std::sqrt(return_value);
1721 return return_value;
1726 template <
int dim,
typename Number>
1729 compute_norm (
const typename SymmetricTensorAccessors::StorageType<4,dim,Number>::base_tensor_type &data)
1731 Number return_value;
1732 const unsigned int n_independent_components = data.dimension;
1737 return_value = std::fabs (data[0][0]);
1740 return_value = Number();
1741 for (
unsigned int i=0; i<dim; ++i)
1742 for (
unsigned int j=0; j<dim; ++j)
1743 return_value += data[i][j] * data[i][j];
1744 for (
unsigned int i=0; i<dim; ++i)
1746 return_value += 2 * data[i][j] * data[i][j];
1748 for (
unsigned int j=0; j<dim; ++j)
1749 return_value += 2 * data[i][j] * data[i][j];
1752 return_value += 4 * data[i][j] * data[i][j];
1753 return_value = std::sqrt(return_value);
1756 return return_value;
1763 template <
int rank,
int dim,
typename Number>
1768 return internal::compute_norm<dim,Number> (
data);
1790 Assert (indices[0] < dim, ExcIndexRange(indices[0], 0, dim));
1791 Assert (indices[1] < dim, ExcIndexRange(indices[1], 0, dim));
1802 static const unsigned int table[2][2] = {{0, 2},
1805 return table[indices[0]][indices[1]];
1810 static const unsigned int table[3][3] = {{0, 3, 4},
1814 return table[indices[0]][indices[1]];
1819 static const unsigned int table[4][4] = {{0, 4, 5, 6},
1824 return table[indices[0]][indices[1]];
1830 if (indices[0] == indices[1])
1834 sorted_indices.sort ();
1836 for (
unsigned int d=0, c=0; d<dim; ++d)
1837 for (
unsigned int e=d+1; e<dim; ++e, ++c)
1838 if ((sorted_indices[0]==d) && (sorted_indices[1]==e))
1854 template <
int dim,
int rank>
1861 Assert (
false, ExcNotImplemented());
1869 template <
int rank,
int dim,
typename Number>
1875 return internal::SymmetricTensor::component_to_unrolled_index<dim> (indices);
1897 (
const unsigned int i,
1898 const int2type<2> &)
1938 for (
unsigned int d=0, c=0; d<dim; ++d)
1939 for (
unsigned int e=d+1; e<dim; ++e, ++c)
1957 template <
int dim,
int rank>
1961 (
const unsigned int i,
1962 const int2type<rank> &)
1967 Assert (
false, ExcNotImplemented());
1975 template <
int rank,
int dim,
typename Number>
1979 (
const unsigned int i)
1982 internal::SymmetricTensor::unrolled_to_component_indices<dim> (i,
1988 template <
int rank,
int dim,
typename Number>
1989 template <
class Archive>
2009 template <
int rank,
int dim,
typename Number,
typename OtherNumber>
2025 template <
int rank,
int dim,
typename Number,
typename OtherNumber>
2041 template <
int rank,
int dim,
typename Number,
typename OtherNumber>
2057 template <
int rank,
int dim,
typename Number,
typename OtherNumber>
2081 template <
int dim,
typename Number>
2101 Assert (
false, ExcNotImplemented());
2117 template <
int dim,
typename Number>
2121 return determinant (t);
2133 template <
int dim,
typename Number>
2136 Number t = d.
data[0];
2137 for (
unsigned int i=1; i<dim; ++i)
2152 template <
int dim,
typename Number>
2167 template <
typename Number>
2183 template <
typename Number>
2187 return t[0][0]*t[1][1] - t[0][1]*t[0][1];
2199 template <
typename Number>
2203 return (t[0][0]*t[1][1] + t[1][1]*t[2][2] + t[2][2]*t[0][0]
2204 - t[0][1]*t[0][1] - t[0][2]*t[0][2] - t[1][2]*t[1][2]);
2219 template <
int rank,
int dim,
typename Number>
2238 template <
int dim,
typename Number>
2246 const Number tr =
trace(t) / dim;
2247 for (
unsigned int i=0; i<dim; ++i)
2262 template <
int dim,
typename Number>
2282 for (
unsigned int d=0; d<dim; ++d)
2303 return unit_symmetric_tensor<dim,double>();
2322 template <
int dim,
typename Number>
2330 for (
unsigned int i=0; i<dim; ++i)
2331 for (
unsigned int j=0; j<dim; ++j)
2332 tmp.
data[i][j] = (i==j ? 1 : 0) - 1./dim;
2339 for (
unsigned int i=dim;
2340 i<internal::SymmetricTensorAccessors::StorageType<4,dim,Number>::n_rank2_components;
2342 tmp.
data[i][i] = 0.5;
2368 return deviator_tensor<dim,double>();
2395 template <
int dim,
typename Number>
2403 for (
unsigned int i=0; i<dim; ++i)
2411 for (
unsigned int i=dim;
2412 i<internal::SymmetricTensorAccessors::StorageType<4,dim,Number>::n_rank2_components;
2414 tmp.
data[i][i] = 0.5;
2447 return identity_tensor<dim,double>();
2465 template <
int dim,
typename Number>
2511 const Number t4 = t.
data[0][0]*t.
data[1][1],
2517 t07 = 1.0/(t4*t.
data[2][2]-t6*t.
data[2][1]-
2519 t01*t.
data[1][2]-t04*t.
data[1][1]);
2525 tmp.
data[1][2] = -(t6-t00)*t07;
2528 tmp.
data[2][2] = (t4-t8)*t07;
2532 tmp.
data[2][0] /= 2;
2533 tmp.
data[2][1] /= 2;
2534 tmp.
data[0][2] /= 2;
2535 tmp.
data[1][2] /= 2;
2536 tmp.
data[2][2] /= 4;
2540 Assert (
false, ExcNotImplemented());
2581 template <
int dim,
typename Number>
2590 for (
unsigned int i=0; i<dim; ++i)
2591 for (
unsigned int j=i; j<dim; ++j)
2592 for (
unsigned int k=0; k<dim; ++k)
2593 for (
unsigned int l=k; l<dim; ++l)
2594 tmp[i][j][k][l] = t1[i][j] * t2[k][l];
2609 template <
int dim,
typename Number>
2614 Number array[(dim*dim+dim)/2];
2615 for (
unsigned int d=0; d<dim; ++d)
2617 for (
unsigned int d=0, c=0; d<dim; ++d)
2618 for (
unsigned int e=d+1; e<dim; ++e, ++c)
2619 array[dim+c] = (t[d][e]+t[e][d])*0.5;
2632 template <
int rank,
int dim,
typename Number>
2636 const Number factor)
2652 template <
int rank,
int dim,
typename Number>
2663 #ifndef DEAL_II_WITH_CXX11 2665 template <
typename T,
typename U,
int rank,
int dim>
2666 struct ProductType<T,SymmetricTensor<rank,dim,U> >
2671 template <
typename T,
typename U,
int rank,
int dim>
2706 template <
int rank,
int dim,
typename Number,
typename OtherNumber>
2710 const OtherNumber factor)
2719 tt *= product_type(factor);
2733 template <
int rank,
int dim,
typename Number,
typename OtherNumber>
2750 template <
int rank,
int dim,
typename Number>
2754 const Number factor)
2769 template <
int rank,
int dim>
2773 const double factor)
2788 template <
int rank,
int dim>
2806 template <
int rank,
int dim>
2810 const double factor)
2826 template <
int dim,
typename Number>
2845 template <
int dim,
typename Number>
2852 for (
unsigned int i=0; i<dim; ++i)
2853 for (
unsigned int j=0; j<dim; ++j)
2854 s += t1[i][j] * t2[i][j];
2868 template <
int dim,
typename Number>
2893 template <
typename Number>
2900 tmp[0][0] = t[0][0][0][0] * s[0][0];
2920 template <
typename Number>
2927 tmp[0][0] = t[0][0][0][0] * s[0][0];
2946 template <
typename Number>
2953 const unsigned int dim = 2;
2955 for (
unsigned int i=0; i<dim; ++i)
2956 for (
unsigned int j=i; j<dim; ++j)
2957 tmp[i][j] = t[i][j][0][0] * s[0][0] +
2958 t[i][j][1][1] * s[1][1] +
2959 2 * t[i][j][0][1] * s[0][1];
2979 template <
typename Number>
2986 const unsigned int dim = 2;
2988 for (
unsigned int i=0; i<dim; ++i)
2989 for (
unsigned int j=i; j<dim; ++j)
2990 tmp[i][j] = s[0][0] * t[0][0][i][j] * +
2991 s[1][1] * t[1][1][i][j] +
2992 2 * s[0][1] * t[0][1][i][j];
3012 template <
typename Number>
3019 const unsigned int dim = 3;
3021 for (
unsigned int i=0; i<dim; ++i)
3022 for (
unsigned int j=i; j<dim; ++j)
3023 tmp[i][j] = t[i][j][0][0] * s[0][0] +
3024 t[i][j][1][1] * s[1][1] +
3025 t[i][j][2][2] * s[2][2] +
3026 2 * t[i][j][0][1] * s[0][1] +
3027 2 * t[i][j][0][2] * s[0][2] +
3028 2 * t[i][j][1][2] * s[1][2];
3048 template <
typename Number>
3055 const unsigned int dim = 3;
3057 for (
unsigned int i=0; i<dim; ++i)
3058 for (
unsigned int j=i; j<dim; ++j)
3059 tmp[i][j] = s[0][0] * t[0][0][i][j] +
3060 s[1][1] * t[1][1][i][j] +
3061 s[2][2] * t[2][2][i][j] +
3062 2 * s[0][1] * t[0][1][i][j] +
3063 2 * s[0][2] * t[0][2][i][j] +
3064 2 * s[1][2] * t[1][2][i][j];
3084 template <
int dim,
typename Number>
3090 for (
unsigned int i=0; i<dim; ++i)
3091 for (
unsigned int j=0; j<dim; ++j)
3092 dest[i] += src1[i][j] * src2[j];
3106 template <
int dim,
typename Number>
3116 for (
unsigned int i=0; i<dim; ++i)
3117 for (
unsigned int j=0; j<dim; ++j)
3134 template <
int dim,
typename Number>
3144 for (
unsigned int i=0; i<dim; ++i)
3145 for (
unsigned int j=0; j<dim; ++j)
3146 for (
unsigned int k=0; k<dim; ++k)
3147 for (
unsigned int l=0; l<dim; ++l)
3148 tt[i][j][k][l] = t[i][j][k][l];
3154 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)
static const unsigned int n_independent_components
SymmetricTensor< 2, dim, Number > symmetrize(const Tensor< 2, dim, Number > &t)
::ExceptionBase & ExcMessage(std::string arg1)
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)
void serialize(Archive &ar, const unsigned int version)
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
void double_contract(SymmetricTensor< 2, 2, Number > &tmp, const SymmetricTensor< 2, 2, Number > &s, const SymmetricTensor< 4, 2, Number > &t)
static std::size_t memory_consumption()
Number second_invariant(const SymmetricTensor< 2, 2, Number > &t)
Number first_invariant(const SymmetricTensor< 2, dim, Number > &t)
friend Number2 trace(const SymmetricTensor< 2, dim2, Number2 > &d)
#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)
std::ostream & operator<<(std::ostream &out, const SymmetricTensor< 2, dim, Number > &t)
Number access_raw_entry(const unsigned int unrolled_index) const
SymmetricTensor< rank, dim, Number > sum(const SymmetricTensor< rank, dim, Number > &local, const MPI_Comm &mpi_communicator)
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)
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 & operator()(const TableIndices< rank > &indices)
Tensor< 1, n_independent_components, Number > base_tensor_type
SymmetricTensor< 4, dim, Number > invert(const SymmetricTensor< 4, dim, Number > &t)
SymmetricTensor & operator*=(const Number factor)
Number second_invariant(const SymmetricTensor< 2, 3, Number > &t)
friend SymmetricTensor< 4, dim2, Number2 > deviator_tensor()
Number scalar_product(const Tensor< 2, dim, Number > &t1, const SymmetricTensor< 2, dim, Number > &t2)
double third_invariant(const SymmetricTensor< 2, dim, Number > &t)
Number second_invariant(const SymmetricTensor< 2, 1, Number > &)
SymmetricTensor & operator=(const SymmetricTensor &)