Reference documentation for deal.II version 9.2.0
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
transformations.h
Go to the documentation of this file.
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2016 - 2019 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef dealii_transformations_h
17 #define dealii_transformations_h
18 
19 #include <deal.II/base/config.h>
20 
21 #include <deal.II/base/point.h>
23 #include <deal.II/base/tensor.h>
24 
26 
27 
28 namespace Physics
29 {
30  namespace Transformations
31  {
38  namespace Rotations
39  {
44 
60  template <typename Number>
62  rotation_matrix_2d(const Number &angle);
63 
64 
93  template <typename Number>
95  rotation_matrix_3d(const Point<3, Number> &axis, const Number &angle);
96 
98 
99  } // namespace Rotations
100 
119  namespace Contravariant
120  {
125 
139  template <int dim, typename Number>
142  const Tensor<2, dim, Number> &F);
143 
158  template <int dim, typename Number>
161  const Tensor<2, dim, Number> &F);
162 
178  template <int dim, typename Number>
181  const Tensor<2, dim, Number> & F);
182 
197  template <int dim, typename Number>
200  const Tensor<2, dim, Number> &F);
201 
217  template <int dim, typename Number>
220  const Tensor<2, dim, Number> & F);
221 
223 
228 
242  template <int dim, typename Number>
245  const Tensor<2, dim, Number> &F);
246 
261  template <int dim, typename Number>
264  const Tensor<2, dim, Number> &F);
265 
280  template <int dim, typename Number>
283  const Tensor<2, dim, Number> & F);
284 
299  template <int dim, typename Number>
302  const Tensor<2, dim, Number> &F);
303 
318  template <int dim, typename Number>
321  const Tensor<2, dim, Number> & F);
322 
324  } // namespace Contravariant
325 
346  namespace Covariant
347  {
352 
366  template <int dim, typename Number>
369  const Tensor<2, dim, Number> &F);
370 
385  template <int dim, typename Number>
388  const Tensor<2, dim, Number> &F);
389 
405  template <int dim, typename Number>
408  const Tensor<2, dim, Number> & F);
409 
424  template <int dim, typename Number>
427  const Tensor<2, dim, Number> &F);
428 
444  template <int dim, typename Number>
447  const Tensor<2, dim, Number> & F);
448 
450 
455 
469  template <int dim, typename Number>
472  const Tensor<2, dim, Number> &F);
473 
488  template <int dim, typename Number>
491  const Tensor<2, dim, Number> &F);
492 
507  template <int dim, typename Number>
510  const Tensor<2, dim, Number> & F);
511 
526  template <int dim, typename Number>
529  const Tensor<2, dim, Number> &F);
530 
545  template <int dim, typename Number>
548  const Tensor<2, dim, Number> & F);
549 
551  } // namespace Covariant
552 
560  namespace Piola
561  {
566 
582  template <int dim, typename Number>
585  const Tensor<2, dim, Number> &F);
586 
602  template <int dim, typename Number>
605  const Tensor<2, dim, Number> &F);
606 
623  template <int dim, typename Number>
626  const Tensor<2, dim, Number> & F);
627 
644  template <int dim, typename Number>
647  const Tensor<2, dim, Number> &F);
648 
666  template <int dim, typename Number>
669  const Tensor<2, dim, Number> & F);
670 
672 
677 
693  template <int dim, typename Number>
696  const Tensor<2, dim, Number> &F);
697 
713  template <int dim, typename Number>
716  const Tensor<2, dim, Number> &F);
717 
733  template <int dim, typename Number>
736  const Tensor<2, dim, Number> & F);
737 
754  template <int dim, typename Number>
757  const Tensor<2, dim, Number> &F);
758 
775  template <int dim, typename Number>
778  const Tensor<2, dim, Number> & F);
779 
781  } // namespace Piola
782 
787 
810  template <int dim, typename Number>
813  const Tensor<2, dim, Number> &F);
814 
816  } // namespace Transformations
817 } // namespace Physics
818 
819 
820 
821 #ifndef DOXYGEN
822 
823 // ------------------------- inline functions ------------------------
824 
825 namespace internal
826 {
827  namespace Physics
828  {
829  template <int dim, typename Number>
831  transformation_contraction(const Tensor<1, dim, Number> &V,
832  const Tensor<2, dim, Number> &F)
833  {
834  return contract<1, 0>(F, V);
835  }
836 
837 
838 
839  template <int dim, typename Number>
841  transformation_contraction(const Tensor<2, dim, Number> &T,
842  const Tensor<2, dim, Number> &F)
843  {
844  return contract<1, 0>(F, contract<1, 1>(T, F));
845  }
846 
847 
848 
849  template <int dim, typename Number>
850  inline ::SymmetricTensor<2, dim, Number>
851  transformation_contraction(const ::SymmetricTensor<2, dim, Number> &T,
852  const Tensor<2, dim, Number> & F)
853  {
855  for (unsigned int i = 0; i < dim; ++i)
856  for (unsigned int J = 0; J < dim; ++J)
857  // Loop over I but complex.h defines a macro I, so use I_ instead
858  for (unsigned int I_ = 0; I_ < dim; ++I_)
859  tmp_1[i][J] += F[i][I_] * T[I_][J];
860 
862  for (unsigned int i = 0; i < dim; ++i)
863  for (unsigned int j = i; j < dim; ++j)
864  for (unsigned int J = 0; J < dim; ++J)
865  out[i][j] += F[j][J] * tmp_1[i][J];
866 
867  return out;
868  }
869 
870 
871 
872  template <int dim, typename Number>
874  transformation_contraction(const Tensor<4, dim, Number> &H,
875  const Tensor<2, dim, Number> &F)
876  {
877  // This contraction order and indexing might look a bit dubious, so a
878  // quick explanation as to what's going on is probably in order:
879  //
880  // When the contract() function operates on the inner indices, the
881  // result has the inner index and outer index transposed, i.e.
882  // contract<2,1>(H,F) implies
883  // T_{IJLk} = (H_{IJMN} F_{mM}) \delta_{mL} \delta_{Nk}
884  // rather than T_{IJkL} (the desired result).
885  // So, in effect, contraction of the 3rd (inner) index with F as the
886  // second argument results in its transposition with respect to its
887  // adjacent neighbor. This is due to the position of the argument F,
888  // leading to the free index being on the right hand side of the result.
889  // However, given that we can do two transformations from the LHS of H
890  // and two from the right we can undo the otherwise erroneous
891  // swapping of the outer indices upon application of the second
892  // sets of contractions.
893  //
894  // Note: Its significantly quicker (in 3d) to push forward
895  // each index individually
896  return contract<1, 1>(
897  F, contract<1, 1>(F, contract<2, 1>(contract<2, 1>(H, F), F)));
898  }
899 
900 
901 
902  template <int dim, typename Number>
903  inline ::SymmetricTensor<4, dim, Number>
904  transformation_contraction(const ::SymmetricTensor<4, dim, Number> &H,
905  const Tensor<2, dim, Number> & F)
906  {
907  // The first and last transformation operations respectively
908  // break and recover the symmetry properties of the tensors.
909  // We also want to perform a minimal number of operations here
910  // and avoid some complications related to the transposition of
911  // tensor indices when contracting inner indices using the contract()
912  // function. (For an explanation of the contraction operations,
913  // please see the note in the equivalent function for standard
914  // Tensors.) So what we'll do here is manually perform the first
915  // and last contractions that break/recover the tensor symmetries
916  // on the inner indices, and use the contract() function only on
917  // the outer indices.
918  //
919  // Note: Its significantly quicker (in 3d) to push forward
920  // each index individually
921 
922  // Push forward (inner) index 1
924  // Loop over I but complex.h defines a macro I, so use I_ instead
925  for (unsigned int I_ = 0; I_ < dim; ++I_)
926  for (unsigned int j = 0; j < dim; ++j)
927  for (unsigned int K = 0; K < dim; ++K)
928  for (unsigned int L = 0; L < dim; ++L)
929  for (unsigned int J = 0; J < dim; ++J)
930  tmp[I_][j][K][L] += F[j][J] * H[I_][J][K][L];
931 
932  // Push forward (outer) indices 0 and 3
933  tmp = contract<1, 0>(F, contract<3, 1>(tmp, F));
934 
935  // Push forward (inner) index 2
937  for (unsigned int i = 0; i < dim; ++i)
938  for (unsigned int j = i; j < dim; ++j)
939  for (unsigned int k = 0; k < dim; ++k)
940  for (unsigned int l = k; l < dim; ++l)
941  for (unsigned int K = 0; K < dim; ++K)
942  out[i][j][k][l] += F[k][K] * tmp[i][j][K][l];
943 
944  return out;
945  }
946  } // namespace Physics
947 } // namespace internal
948 
949 
950 
951 template <typename Number>
954 {
955  const double rotation[2][2] = {{std::cos(angle), -std::sin(angle)},
957  return Tensor<2, 2>(rotation);
958 }
959 
960 
961 
962 template <typename Number>
965  const Point<3, Number> &axis,
966  const Number & angle)
967 {
968  Assert(std::abs(axis.norm() - 1.0) < 1e-9,
969  ExcMessage("The supplied axial vector is not a unit vector."));
970  const Number c = std::cos(angle);
971  const Number s = std::sin(angle);
972  const Number t = 1. - c;
973  const double rotation[3][3] = {{t * axis[0] * axis[0] + c,
974  t * axis[0] * axis[1] - s * axis[2],
975  t * axis[0] * axis[2] + s * axis[1]},
976  {t * axis[0] * axis[1] + s * axis[2],
977  t * axis[1] * axis[1] + c,
978  t * axis[1] * axis[2] - s * axis[0]},
979  {t * axis[0] * axis[2] - s * axis[1],
980  t * axis[1] * axis[2] + s * axis[0],
981  t * axis[2] * axis[2] + c}};
982  return Tensor<2, 3, Number>(rotation);
983 }
984 
985 
986 
987 template <int dim, typename Number>
990  const Tensor<1, dim, Number> &V,
991  const Tensor<2, dim, Number> &F)
992 {
993  return internal::Physics::transformation_contraction(V, F);
994 }
995 
996 
997 
998 template <int dim, typename Number>
1001  const Tensor<2, dim, Number> &T,
1002  const Tensor<2, dim, Number> &F)
1003 {
1004  return internal::Physics::transformation_contraction(T, F);
1005 }
1006 
1007 
1008 
1009 template <int dim, typename Number>
1013  const Tensor<2, dim, Number> & F)
1014 {
1015  return internal::Physics::transformation_contraction(T, F);
1016 }
1017 
1018 
1019 
1020 template <int dim, typename Number>
1023  const Tensor<4, dim, Number> &H,
1024  const Tensor<2, dim, Number> &F)
1025 {
1026  return internal::Physics::transformation_contraction(H, F);
1027 }
1028 
1029 
1030 
1031 template <int dim, typename Number>
1035  const Tensor<2, dim, Number> & F)
1036 {
1037  return internal::Physics::transformation_contraction(H, F);
1038 }
1039 
1040 
1041 
1042 template <int dim, typename Number>
1045  const Tensor<1, dim, Number> &v,
1046  const Tensor<2, dim, Number> &F)
1047 {
1048  return internal::Physics::transformation_contraction(v, invert(F));
1049 }
1050 
1051 
1052 
1053 template <int dim, typename Number>
1056  const Tensor<2, dim, Number> &t,
1057  const Tensor<2, dim, Number> &F)
1058 {
1059  return internal::Physics::transformation_contraction(t, invert(F));
1060 }
1061 
1062 
1063 
1064 template <int dim, typename Number>
1068  const Tensor<2, dim, Number> & F)
1069 {
1070  return internal::Physics::transformation_contraction(t, invert(F));
1071 }
1072 
1073 
1074 
1075 template <int dim, typename Number>
1078  const Tensor<4, dim, Number> &h,
1079  const Tensor<2, dim, Number> &F)
1080 {
1081  return internal::Physics::transformation_contraction(h, invert(F));
1082 }
1083 
1084 
1085 
1086 template <int dim, typename Number>
1090  const Tensor<2, dim, Number> & F)
1091 {
1092  return internal::Physics::transformation_contraction(h, invert(F));
1093 }
1094 
1095 
1096 
1097 template <int dim, typename Number>
1100  const Tensor<1, dim, Number> &V,
1101  const Tensor<2, dim, Number> &F)
1102 {
1103  return internal::Physics::transformation_contraction(V, transpose(invert(F)));
1104 }
1105 
1106 
1107 
1108 template <int dim, typename Number>
1111  const Tensor<2, dim, Number> &T,
1112  const Tensor<2, dim, Number> &F)
1113 {
1114  return internal::Physics::transformation_contraction(T, transpose(invert(F)));
1115 }
1116 
1117 
1118 
1119 template <int dim, typename Number>
1123  const Tensor<2, dim, Number> & F)
1124 {
1125  return internal::Physics::transformation_contraction(T, transpose(invert(F)));
1126 }
1127 
1128 
1129 
1130 template <int dim, typename Number>
1133  const Tensor<4, dim, Number> &H,
1134  const Tensor<2, dim, Number> &F)
1135 {
1136  return internal::Physics::transformation_contraction(H, transpose(invert(F)));
1137 }
1138 
1139 
1140 
1141 template <int dim, typename Number>
1145  const Tensor<2, dim, Number> & F)
1146 {
1147  return internal::Physics::transformation_contraction(H, transpose(invert(F)));
1148 }
1149 
1150 
1151 
1152 template <int dim, typename Number>
1155  const Tensor<2, dim, Number> &F)
1156 {
1157  return internal::Physics::transformation_contraction(v, transpose(F));
1158 }
1159 
1160 
1161 
1162 template <int dim, typename Number>
1165  const Tensor<2, dim, Number> &F)
1166 {
1167  return internal::Physics::transformation_contraction(t, transpose(F));
1168 }
1169 
1170 
1171 
1172 template <int dim, typename Number>
1176  const Tensor<2, dim, Number> & F)
1177 {
1178  return internal::Physics::transformation_contraction(t, transpose(F));
1179 }
1180 
1181 
1182 
1183 template <int dim, typename Number>
1186  const Tensor<2, dim, Number> &F)
1187 {
1188  return internal::Physics::transformation_contraction(h, transpose(F));
1189 }
1190 
1191 
1192 
1193 template <int dim, typename Number>
1197  const Tensor<2, dim, Number> & F)
1198 {
1199  return internal::Physics::transformation_contraction(h, transpose(F));
1200 }
1201 
1202 
1203 
1204 template <int dim, typename Number>
1207  const Tensor<2, dim, Number> &F)
1208 {
1209  return Number(1.0 / determinant(F)) * Contravariant::push_forward(V, F);
1210 }
1211 
1212 
1213 
1214 template <int dim, typename Number>
1217  const Tensor<2, dim, Number> &F)
1218 {
1219  return Number(1.0 / determinant(F)) * Contravariant::push_forward(T, F);
1220 }
1221 
1222 
1223 
1224 template <int dim, typename Number>
1228  const Tensor<2, dim, Number> & F)
1229 {
1230  return Number(1.0 / determinant(F)) * Contravariant::push_forward(T, F);
1231 }
1232 
1233 
1234 
1235 template <int dim, typename Number>
1238  const Tensor<2, dim, Number> &F)
1239 {
1240  return Number(1.0 / determinant(F)) * Contravariant::push_forward(H, F);
1241 }
1242 
1243 
1244 
1245 template <int dim, typename Number>
1249  const Tensor<2, dim, Number> & F)
1250 {
1251  return Number(1.0 / determinant(F)) * Contravariant::push_forward(H, F);
1252 }
1253 
1254 
1255 
1256 template <int dim, typename Number>
1259  const Tensor<2, dim, Number> &F)
1260 {
1261  return Number(determinant(F)) * Contravariant::pull_back(v, F);
1262 }
1263 
1264 
1265 
1266 template <int dim, typename Number>
1269  const Tensor<2, dim, Number> &F)
1270 {
1271  return Number(determinant(F)) * Contravariant::pull_back(t, F);
1272 }
1273 
1274 
1275 
1276 template <int dim, typename Number>
1280  const Tensor<2, dim, Number> & F)
1281 {
1282  return Number(determinant(F)) * Contravariant::pull_back(t, F);
1283 }
1284 
1285 
1286 
1287 template <int dim, typename Number>
1290  const Tensor<2, dim, Number> &F)
1291 {
1292  return Number(determinant(F)) * Contravariant::pull_back(h, F);
1293 }
1294 
1295 
1296 
1297 template <int dim, typename Number>
1301  const Tensor<2, dim, Number> & F)
1302 {
1303  return Number(determinant(F)) * Contravariant::pull_back(h, F);
1304 }
1305 
1306 
1307 
1308 template <int dim, typename Number>
1311  const Tensor<2, dim, Number> &F)
1312 {
1313  return cofactor(F) * N;
1314 }
1315 
1316 #endif // DOXYGEN
1317 
1319 
1320 #endif
Physics
Definition: physics.h:28
Physics::Elasticity::Kinematics::F
Tensor< 2, dim, Number > F(const Tensor< 2, dim, Number > &Grad_u)
Physics::Transformations::Rotations::rotation_matrix_3d
Tensor< 2, 3, Number > rotation_matrix_3d(const Point< 3, Number > &axis, const Number &angle)
Tensor::cofactor
constexpr Tensor< 2, dim, Number > cofactor(const Tensor< 2, dim, Number > &t)
Definition: tensor.h:2653
Physics::Transformations::Piola::pull_back
Tensor< 1, dim, Number > pull_back(const Tensor< 1, dim, Number > &v, const Tensor< 2, dim, Number > &F)
SymmetricTensor
Definition: symmetric_tensor.h:611
Physics::Transformations::Covariant::pull_back
Tensor< 1, dim, Number > pull_back(const Tensor< 1, dim, Number > &v, const Tensor< 2, dim, Number > &F)
LAPACKSupport::V
static const char V
Definition: lapack_support.h:175
SymmetricTensor::invert
constexpr SymmetricTensor< 2, dim, Number > invert(const SymmetricTensor< 2, dim, Number > &t)
Definition: symmetric_tensor.h:3467
LAPACKSupport::L
static const char L
Definition: lapack_support.h:171
Physics::Transformations::Rotations::rotation_matrix_2d
Tensor< 2, 2, Number > rotation_matrix_2d(const Number &angle)
Physics::Elasticity::Kinematics::e
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
Physics::Transformations::Piola::push_forward
SymmetricTensor< 4, dim, Number > push_forward(const SymmetricTensor< 4, dim, Number > &H, const Tensor< 2, dim, Number > &F)
std::cos
inline ::VectorizedArray< Number, width > cos(const ::VectorizedArray< Number, width > &x)
Definition: vectorization.h:5324
Physics::Transformations::Contravariant::pull_back
Tensor< 1, dim, Number > pull_back(const Tensor< 1, dim, Number > &v, const Tensor< 2, dim, Number > &F)
Physics::Transformations::Piola::pull_back
SymmetricTensor< 4, dim, Number > pull_back(const SymmetricTensor< 4, dim, Number > &h, const Tensor< 2, dim, Number > &F)
LAPACKSupport::T
static const char T
Definition: lapack_support.h:163
tensor.h
Tensor< 1, dim, double >::norm
numbers::NumberTraits< double >::real_type norm() const
StandardExceptions::ExcMessage
static ::ExceptionBase & ExcMessage(std::string arg1)
angle
const double angle
Definition: grid_tools_nontemplates.cc:277
Tensor
Definition: tensor.h:450
DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:358
Physics::Elasticity::Kinematics::l
Tensor< 2, dim, Number > l(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
Physics::Transformations::Contravariant::push_forward
Tensor< 1, dim, Number > push_forward(const Tensor< 1, dim, Number > &V, const Tensor< 2, dim, Number > &F)
Physics::Transformations::nansons_formula
Tensor< 1, dim, Number > nansons_formula(const Tensor< 1, dim, Number > &N, const Tensor< 2, dim, Number > &F)
Assert
#define Assert(cond, exc)
Definition: exceptions.h:1419
symmetric_tensor.h
SymmetricTensor::determinant
constexpr Number determinant(const SymmetricTensor< 2, dim, Number > &t)
Definition: symmetric_tensor.h:2645
Physics::Transformations::Piola::push_forward
Tensor< 1, dim, Number > push_forward(const Tensor< 1, dim, Number > &V, const Tensor< 2, dim, Number > &F)
Point
Definition: point.h:111
config.h
internal
Definition: aligned_vector.h:369
LAPACKSupport::N
static const char N
Definition: lapack_support.h:159
DEAL_II_NAMESPACE_CLOSE
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:359
DerivativeForm::transpose
DerivativeForm< 1, spacedim, dim, Number > transpose(const DerivativeForm< 1, dim, spacedim, Number > &DF)
Definition: derivative_form.h:470
std::sin
inline ::VectorizedArray< Number, width > sin(const ::VectorizedArray< Number, width > &x)
Definition: vectorization.h:5297
point.h
Physics::Transformations::Covariant::push_forward
Tensor< 1, dim, Number > push_forward(const Tensor< 1, dim, Number > &V, const Tensor< 2, dim, Number > &F)