Reference documentation for deal.II version 9.0.0
transformations.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2016 - 2017 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 at
12 // the top level of the deal.II distribution.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef dealii_transformations_h
17 #define dealii_transformations_h
18 
19 #include <deal.II/base/point.h>
20 #include <deal.II/base/tensor.h>
22 
23 DEAL_II_NAMESPACE_OPEN
24 
25 
26 namespace Physics
27 {
28 
29  namespace Transformations
30  {
31 
38  namespace Rotations
39  {
44 
60  template <typename Number>
62  rotation_matrix_2d (const Number &angle);
63 
64 
93  template <typename Number>
96  const Number &angle);
97 
99 
100  }
101 
120  namespace Contravariant
121  {
122 
127 
141  template <int dim, typename Number>
144  const Tensor<2,dim,Number> &F);
145 
159  template <int dim, typename Number>
162  const Tensor<2,dim,Number> &F);
163 
178  template <int dim, typename Number>
181  const Tensor<2,dim,Number> &F);
182 
196  template <int dim, typename Number>
199  const Tensor<2,dim,Number> &F);
200 
215  template <int dim, typename Number>
218  const Tensor<2,dim,Number> &F);
219 
221 
226 
240  template <int dim, typename Number>
243  const Tensor<2,dim,Number> &F);
244 
258  template <int dim, typename Number>
261  const Tensor<2,dim,Number> &F);
262 
276  template <int dim, typename Number>
279  const Tensor<2,dim,Number> &F);
280 
294  template <int dim, typename Number>
297  const Tensor<2,dim,Number> &F);
298 
312  template <int dim, typename Number>
315  const Tensor<2,dim,Number> &F);
316 
318  }
319 
339  namespace Covariant
340  {
341 
346 
360  template <int dim, typename Number>
363  const Tensor<2,dim,Number> &F);
364 
378  template <int dim, typename Number>
381  const Tensor<2,dim,Number> &F);
382 
397  template <int dim, typename Number>
400  const Tensor<2,dim,Number> &F);
401 
415  template <int dim, typename Number>
418  const Tensor<2,dim,Number> &F);
419 
434  template <int dim, typename Number>
437  const Tensor<2,dim,Number> &F);
438 
440 
445 
459  template <int dim, typename Number>
462  const Tensor<2,dim,Number> &F);
463 
477  template <int dim, typename Number>
480  const Tensor<2,dim,Number> &F);
481 
495  template <int dim, typename Number>
498  const Tensor<2,dim,Number> &F);
499 
513  template <int dim, typename Number>
516  const Tensor<2,dim,Number> &F);
517 
531  template <int dim, typename Number>
534  const Tensor<2,dim,Number> &F);
535 
537  }
538 
546  namespace Piola
547  {
548 
553 
568  template <int dim, typename Number>
571  const Tensor<2,dim,Number> &F);
572 
587  template <int dim, typename Number>
590  const Tensor<2,dim,Number> &F);
591 
607  template <int dim, typename Number>
610  const Tensor<2,dim,Number> &F);
611 
626  template <int dim, typename Number>
629  const Tensor<2,dim,Number> &F);
630 
646  template <int dim, typename Number>
649  const Tensor<2,dim,Number> &F);
650 
652 
657 
672  template <int dim, typename Number>
675  const Tensor<2,dim,Number> &F);
676 
691  template <int dim, typename Number>
694  const Tensor<2,dim,Number> &F);
695 
710  template <int dim, typename Number>
713  const Tensor<2,dim,Number> &F);
714 
729  template <int dim, typename Number>
732  const Tensor<2,dim,Number> &F);
733 
748  template <int dim, typename Number>
751  const Tensor<2,dim,Number> &F);
752 
754  }
755 
760 
783  template <int dim, typename Number>
786  const Tensor<2,dim,Number> &F);
787 
789  }
790 }
791 
792 
793 
794 #ifndef DOXYGEN
795 
796 // ------------------------- inline functions ------------------------
797 
798 namespace internal
799 {
800  namespace Physics
801  {
802  namespace
803  {
804  template <int dim, typename Number>
805  inline
807  transformation_contraction (const Tensor<1,dim,Number> &V,
808  const Tensor<2,dim,Number> &F)
809  {
810  return contract<1,0>(F, V);
811  }
812 
813 
814 
815  template <int dim, typename Number>
816  inline
818  transformation_contraction (const Tensor<2,dim,Number> &T,
819  const Tensor<2,dim,Number> &F)
820  {
821  return contract<1,0>(F,contract<1,1>(T, F));
822  }
823 
824 
825 
826  template <int dim, typename Number>
827  inline
828  ::SymmetricTensor<2,dim,Number>
829  transformation_contraction (const ::SymmetricTensor<2,dim,Number> &T,
830  const Tensor<2,dim,Number> &F)
831  {
832  Tensor<2,dim,Number> tmp_1;
833  for (unsigned int i=0; i<dim; ++i)
834  for (unsigned int J=0; J<dim; ++J)
835  for (unsigned int I=0; I<dim; ++I)
836  tmp_1[i][J] += F[i][I] * T[I][J];
837 
839  for (unsigned int i=0; i<dim; ++i)
840  for (unsigned int j=i; j<dim; ++j)
841  for (unsigned int J=0; J<dim; ++J)
842  out[i][j] += F[j][J] * tmp_1[i][J];
843 
844  return out;
845  }
846 
847 
848 
849  template <int dim, typename Number>
850  inline
852  transformation_contraction (const Tensor<4,dim,Number> &H,
853  const Tensor<2,dim,Number> &F)
854  {
855  // This contraction order and indexing might look a bit dubious, so a
856  // quick explanation as to what's going on is probably in order:
857  //
858  // When the contract() function operates on the inner indices, the
859  // result has the inner index and outer index transposed, i.e.
860  // contract<2,1>(H,F) implies
861  // T_{IJLk} = (H_{IJMN} F_{mM}) \delta_{mL} \delta_{Nk}
862  // rather than T_{IJkL} (the desired result).
863  // So, in effect, contraction of the 3rd (inner) index with F as the
864  // second argument results in its transposition with respect to its
865  // adjacent neighbor. This is due to the position of the argument F,
866  // leading to the free index being on the right hand side of the result.
867  // However, given that we can do two transformations from the LHS of H
868  // and two from the right we can undo the otherwise erroneous
869  // swapping of the outer indices upon application of the second
870  // sets of contractions.
871  //
872  // Note: Its significantly quicker (in 3d) to push forward
873  // each index individually
874  return contract<1,1>(F,contract<1,1>(F,contract<2,1>(contract<2,1>(H,F), F)));
875  }
876 
877 
878 
879  template <int dim, typename Number>
880  inline
881  ::SymmetricTensor<4,dim,Number>
882  transformation_contraction (const ::SymmetricTensor<4,dim,Number> &H,
883  const Tensor<2,dim,Number> &F)
884  {
885  // The first and last transformation operations respectively
886  // break and recover the symmetry properties of the tensors.
887  // We also want to perform a minimal number of operations here
888  // and avoid some complications related to the transposition of
889  // tensor indices when contracting inner indices using the contract()
890  // function. (For an explanation of the contraction operations,
891  // please see the note in the equivalent function for standard
892  // Tensors.) So what we'll do here is manually perform the first
893  // and last contractions that break/recover the tensor symmetries
894  // on the inner indices, and use the contract() function only on
895  // the outer indices.
896  //
897  // Note: Its significantly quicker (in 3d) to push forward
898  // each index individually
899 
900  // Push forward (inner) index 1
902  for (unsigned int I=0; I<dim; ++I)
903  for (unsigned int j=0; j<dim; ++j)
904  for (unsigned int K=0; K<dim; ++K)
905  for (unsigned int L=0; L<dim; ++L)
906  for (unsigned int J=0; J<dim; ++J)
907  tmp[I][j][K][L] += F[j][J] * H[I][J][K][L];
908 
909  // Push forward (outer) indices 0 and 3
910  tmp = contract<1,0>(F, contract<3,1>(tmp,F));
911 
912  // Push forward (inner) index 2
914  for (unsigned int i=0; i<dim; ++i)
915  for (unsigned int j=i; j<dim; ++j)
916  for (unsigned int k=0; k<dim; ++k)
917  for (unsigned int l=k; l<dim; ++l)
918  for (unsigned int K=0; K<dim; ++K)
919  out[i][j][k][l] += F[k][K] * tmp[i][j][K][l];
920 
921  return out;
922  }
923  }
924  }
925 }
926 
927 
928 
929 template <typename Number>
932 {
933  const double rotation[2][2]
934  = {{
935  std::cos(angle), -std::sin(angle)
936  },
937  {
938  std::sin(angle), std::cos(angle)
939  }
940  };
941  return Tensor<2,2> (rotation);
942 }
943 
944 
945 
946 template <typename Number>
949  const Number &angle)
950 {
951  Assert(std::abs(axis.norm() - 1.0) < 1e-9,
952  ExcMessage("The supplied axial vector is not a unit vector."));
953  const Number c = std::cos(angle);
954  const Number s = std::sin(angle);
955  const Number t = 1.-c;
956  const double rotation[3][3]
957  = {{
958  t *axis[0] *axis[0] + c,
959  t *axis[0] *axis[1] - s *axis[2],
960  t *axis[0] *axis[2] + s *axis[1]
961  },
962  {
963  t *axis[0] *axis[1] + s *axis[2],
964  t *axis[1] *axis[1] + c,
965  t *axis[1] *axis[2] - s *axis[0]
966  },
967  {
968  t *axis[0] *axis[2] - s *axis[1],
969  t *axis[1] *axis[2] + s *axis[0],
970  t *axis[2] *axis[2] + c
971  }
972  };
973  return Tensor<2,3,Number>(rotation);
974 }
975 
976 
977 
978 template <int dim, typename Number>
979 inline
982  const Tensor<2,dim,Number> &F)
983 {
984  return internal::Physics::transformation_contraction(V,F);
985 }
986 
987 
988 
989 template <int dim, typename Number>
990 inline
993  const Tensor<2,dim,Number> &F)
994 {
995  return internal::Physics::transformation_contraction(T,F);
996 }
997 
998 
999 
1000 template <int dim, typename Number>
1001 inline
1004  const Tensor<2,dim,Number> &F)
1005 {
1006  return internal::Physics::transformation_contraction(T,F);
1007 }
1008 
1009 
1010 
1011 template <int dim, typename Number>
1012 inline
1015  const Tensor<2,dim,Number> &F)
1016 {
1017  return internal::Physics::transformation_contraction(H,F);
1018 }
1019 
1020 
1021 
1022 template <int dim, typename Number>
1023 inline
1026  const Tensor<2,dim,Number> &F)
1027 {
1028  return internal::Physics::transformation_contraction(H,F);
1029 }
1030 
1031 
1032 
1033 template <int dim, typename Number>
1034 inline
1037  const Tensor<2,dim,Number> &F)
1038 {
1039  return internal::Physics::transformation_contraction(v,invert(F));
1040 }
1041 
1042 
1043 
1044 template <int dim, typename Number>
1045 inline
1048  const Tensor<2,dim,Number> &F)
1049 {
1050  return internal::Physics::transformation_contraction(t,invert(F));
1051 }
1052 
1053 
1054 
1055 template <int dim, typename Number>
1056 inline
1059  const Tensor<2,dim,Number> &F)
1060 {
1061  return internal::Physics::transformation_contraction(t,invert(F));
1062 }
1063 
1064 
1065 
1066 template <int dim, typename Number>
1067 inline
1070  const Tensor<2,dim,Number> &F)
1071 {
1072  return internal::Physics::transformation_contraction(h,invert(F));
1073 }
1074 
1075 
1076 
1077 template <int dim, typename Number>
1078 inline
1081  const Tensor<2,dim,Number> &F)
1082 {
1083  return internal::Physics::transformation_contraction(h,invert(F));
1084 }
1085 
1086 
1087 
1088 template <int dim, typename Number>
1089 inline
1092  const Tensor<2,dim,Number> &F)
1093 {
1094  return internal::Physics::transformation_contraction(V,transpose(invert(F)));
1095 }
1096 
1097 
1098 
1099 template <int dim, typename Number>
1100 inline
1103  const Tensor<2,dim,Number> &F)
1104 {
1105  return internal::Physics::transformation_contraction(T,transpose(invert(F)));
1106 }
1107 
1108 
1109 
1110 template <int dim, typename Number>
1111 inline
1114  const Tensor<2,dim,Number> &F)
1115 {
1116  return internal::Physics::transformation_contraction(T,transpose(invert(F)));
1117 }
1118 
1119 
1120 
1121 template <int dim, typename Number>
1122 inline
1125  const Tensor<2,dim,Number> &F)
1126 {
1127  return internal::Physics::transformation_contraction(H,transpose(invert(F)));
1128 }
1129 
1130 
1131 
1132 template <int dim, typename Number>
1133 inline
1136  const Tensor<2,dim,Number> &F)
1137 {
1138  return internal::Physics::transformation_contraction(H,transpose(invert(F)));
1139 }
1140 
1141 
1142 
1143 template <int dim, typename Number>
1144 inline
1147  const Tensor<2,dim,Number> &F)
1148 {
1149  return internal::Physics::transformation_contraction(v,transpose(F));
1150 }
1151 
1152 
1153 
1154 template <int dim, typename Number>
1155 inline
1158  const Tensor<2,dim,Number> &F)
1159 {
1160  return internal::Physics::transformation_contraction(t,transpose(F));
1161 }
1162 
1163 
1164 
1165 template <int dim, typename Number>
1166 inline
1169  const Tensor<2,dim,Number> &F)
1170 {
1171  return internal::Physics::transformation_contraction(t,transpose(F));
1172 }
1173 
1174 
1175 
1176 template <int dim, typename Number>
1177 inline
1180  const Tensor<2,dim,Number> &F)
1181 {
1182  return internal::Physics::transformation_contraction(h,transpose(F));
1183 }
1184 
1185 
1186 
1187 template <int dim, typename Number>
1188 inline
1191  const Tensor<2,dim,Number> &F)
1192 {
1193  return internal::Physics::transformation_contraction(h,transpose(F));
1194 }
1195 
1196 
1197 
1198 template <int dim, typename Number>
1199 inline
1202  const Tensor<2,dim,Number> &F)
1203 {
1204  return Number(1.0/determinant(F))*Contravariant::push_forward(V,F);
1205 }
1206 
1207 
1208 
1209 template <int dim, typename Number>
1210 inline
1213  const Tensor<2,dim,Number> &F)
1214 {
1215  return Number(1.0/determinant(F))*Contravariant::push_forward(T,F);
1216 }
1217 
1218 
1219 
1220 template <int dim, typename Number>
1221 inline
1224  const Tensor<2,dim,Number> &F)
1225 {
1226  return Number(1.0/determinant(F))*Contravariant::push_forward(T,F);
1227 }
1228 
1229 
1230 
1231 template <int dim, typename Number>
1232 inline
1235  const Tensor<2,dim,Number> &F)
1236 {
1237  return Number(1.0/determinant(F))*Contravariant::push_forward(H,F);
1238 }
1239 
1240 
1241 
1242 template <int dim, typename Number>
1243 inline
1246  const Tensor<2,dim,Number> &F)
1247 {
1248  return Number(1.0/determinant(F))*Contravariant::push_forward(H,F);
1249 }
1250 
1251 
1252 
1253 template <int dim, typename Number>
1254 inline
1257  const Tensor<2,dim,Number> &F)
1258 {
1259  return Number(determinant(F))*Contravariant::pull_back(v,F);
1260 }
1261 
1262 
1263 
1264 template <int dim, typename Number>
1265 inline
1268  const Tensor<2,dim,Number> &F)
1269 {
1270  return Number(determinant(F))*Contravariant::pull_back(t,F);
1271 }
1272 
1273 
1274 
1275 template <int dim, typename Number>
1276 inline
1279  const Tensor<2,dim,Number> &F)
1280 {
1281  return Number(determinant(F))*Contravariant::pull_back(t,F);
1282 }
1283 
1284 
1285 
1286 template <int dim, typename Number>
1287 inline
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>
1298 inline
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>
1309 inline Tensor<1,dim,Number>
1311  const Tensor<2,dim,Number> &F)
1312 {
1313  return cofactor(F)*N;
1314 }
1315 
1316 #endif // DOXYGEN
1317 
1318 DEAL_II_NAMESPACE_CLOSE
1319 
1320 #endif
SymmetricTensor< 2, dim, Number > invert(const SymmetricTensor< 2, dim, Number > &t)
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
Tensor< 1, dim, Number > nansons_formula(const Tensor< 1, dim, Number > &N, const Tensor< 2, dim, Number > &F)
Definition: point.h:104
Tensor< 2, dim, Number > F(const Tensor< 2, dim, Number > &Grad_u)
Tensor< 2, dim, Number > cofactor(const Tensor< 2, dim, Number > &t)
Definition: tensor.h:2210
Tensor< 1, dim, Number > push_forward(const Tensor< 1, dim, Number > &V, const Tensor< 2, dim, Number > &F)
Tensor< 1, dim, Number > pull_back(const Tensor< 1, dim, Number > &v, const Tensor< 2, dim, Number > &F)
static ::ExceptionBase & ExcMessage(std::string arg1)
#define Assert(cond, exc)
Definition: exceptions.h:1142
Tensor< 1, dim, Number > push_forward(const Tensor< 1, dim, Number > &V, const Tensor< 2, dim, Number > &F)
Tensor< 2, 2, Number > rotation_matrix_2d(const Number &angle)
Tensor< 1, dim, Number > pull_back(const Tensor< 1, dim, Number > &v, const Tensor< 2, dim, Number > &F)
Number determinant(const SymmetricTensor< 2, dim, Number > &t)
Definition: mpi.h:53
Tensor< 1, dim, Number > push_forward(const Tensor< 1, dim, Number > &V, const Tensor< 2, dim, Number > &F)
Tensor< 1, dim, Number > pull_back(const Tensor< 1, dim, Number > &v, const Tensor< 2, dim, Number > &F)
DerivativeForm< 1, spacedim, dim, Number > transpose(const DerivativeForm< 1, dim, spacedim, Number > &DF)
Tensor< 2, 3, Number > rotation_matrix_3d(const Point< 3, Number > &axis, const Number &angle)
Tensor< 2, dim, Number > l(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)