deal.II version GIT relicensing-6834-g5b78e6bcdf 2026-10-01 11:20:01+00:00
\(\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\}}\)
Loading...
Searching...
No Matches
transformations.h
Go to the documentation of this file.
1// -----------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception OR LGPL-2.1-or-later
4// Copyright (C) 2016 - 2024 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Detailed license information governing the source code and contributions
9// can be found in LICENSE.md and CONTRIBUTING.md at the top level directory.
10//
11// -----------------------------------------------------------------------------
12
13#ifndef dealii_transformations_h
14#define dealii_transformations_h
15
16#include <deal.II/base/config.h>
17
19#include <deal.II/base/tensor.h>
20
22
23
24namespace Physics
25{
26 namespace Transformations
27 {
32 namespace Rotations
33 {
54 template <typename Number>
56 rotation_matrix_2d(const Number &angle);
57
58
87 template <typename Number>
89 rotation_matrix_3d(const Tensor<1, 3, Number> &axis, const Number &angle);
90
93 } // namespace Rotations
94
111 namespace Contravariant
112 {
131 template <int dim, typename Number>
134 const Tensor<2, dim, Number> &F);
135
150 template <int dim, typename Number>
153 const Tensor<2, dim, Number> &F);
154
170 template <int dim, typename Number>
173 const Tensor<2, dim, Number> &F);
174
189 template <int dim, typename Number>
192 const Tensor<2, dim, Number> &F);
193
209 template <int dim, typename Number>
212 const Tensor<2, dim, Number> &F);
213
234 template <int dim, typename Number>
237 const Tensor<2, dim, Number> &F);
238
253 template <int dim, typename Number>
256 const Tensor<2, dim, Number> &F);
257
272 template <int dim, typename Number>
275 const Tensor<2, dim, Number> &F);
276
291 template <int dim, typename Number>
294 const Tensor<2, dim, Number> &F);
295
310 template <int dim, typename Number>
313 const Tensor<2, dim, Number> &F);
314
316 } // namespace Contravariant
317
336 namespace Covariant
337 {
356 template <int dim, typename Number>
359 const Tensor<2, dim, Number> &F);
360
375 template <int dim, typename Number>
378 const Tensor<2, dim, Number> &F);
379
395 template <int dim, typename Number>
398 const Tensor<2, dim, Number> &F);
399
414 template <int dim, typename Number>
417 const Tensor<2, dim, Number> &F);
418
434 template <int dim, typename Number>
437 const Tensor<2, dim, Number> &F);
438
459 template <int dim, typename Number>
462 const Tensor<2, dim, Number> &F);
463
478 template <int dim, typename Number>
481 const Tensor<2, dim, Number> &F);
482
497 template <int dim, typename Number>
500 const Tensor<2, dim, Number> &F);
501
516 template <int dim, typename Number>
519 const Tensor<2, dim, Number> &F);
520
535 template <int dim, typename Number>
538 const Tensor<2, dim, Number> &F);
539
541 } // namespace Covariant
542
548 namespace Piola
549 {
570 template <int dim, typename Number>
573 const Tensor<2, dim, Number> &F);
574
590 template <int dim, typename Number>
593 const Tensor<2, dim, Number> &F);
594
611 template <int dim, typename Number>
614 const Tensor<2, dim, Number> &F);
615
632 template <int dim, typename Number>
635 const Tensor<2, dim, Number> &F);
636
654 template <int dim, typename Number>
657 const Tensor<2, dim, Number> &F);
658
681 template <int dim, typename Number>
684 const Tensor<2, dim, Number> &F);
685
701 template <int dim, typename Number>
704 const Tensor<2, dim, Number> &F);
705
721 template <int dim, typename Number>
724 const Tensor<2, dim, Number> &F);
725
742 template <int dim, typename Number>
745 const Tensor<2, dim, Number> &F);
746
763 template <int dim, typename Number>
766 const Tensor<2, dim, Number> &F);
767
769 } // namespace Piola
770
798 template <int dim, typename Number>
801 const Tensor<2, dim, Number> &F);
802
820 template <int dim, typename Number>
823 const Tensor<2, dim, Number> &B);
824
836 template <int dim, typename Number>
839 const Tensor<2, dim, Number> &B);
840
852 template <int dim, typename Number>
855 const Tensor<2, dim, Number> &B);
856
867 template <int dim, typename Number>
870 const Tensor<2, dim, Number> &B);
871
883 template <int dim, typename Number>
886 const Tensor<2, dim, Number> &B);
887
890 } // namespace Transformations
891} // namespace Physics
892
893
894
895#ifndef DOXYGEN
896
897
898
899template <typename Number>
902{
903 // Make things work with AD types
904 using std::cos;
905 using std::sin;
906
907 const Number rotation[2][2] = {{cos(angle), -sin(angle)},
908 {sin(angle), cos(angle)}};
909 return Tensor<2, 2>(rotation);
910}
911
912
913
914template <typename Number>
917 const Tensor<1, 3, Number> &axis,
918 const Number &angle)
919{
920 // Make things work with AD types
921 using std::abs;
922 using std::cos;
923 using std::sin;
924
925 Assert(abs(axis.norm() - 1.0) < 1e-9,
926 ExcMessage("The supplied axial vector is not a unit vector."));
927 const Number c = cos(angle);
928 const Number s = sin(angle);
929 const Number t = 1. - c;
930 const Number rotation[3][3] = {{t * axis[0] * axis[0] + c,
931 t * axis[0] * axis[1] - s * axis[2],
932 t * axis[0] * axis[2] + s * axis[1]},
933 {t * axis[0] * axis[1] + s * axis[2],
934 t * axis[1] * axis[1] + c,
935 t * axis[1] * axis[2] - s * axis[0]},
936 {t * axis[0] * axis[2] - s * axis[1],
937 t * axis[1] * axis[2] + s * axis[0],
938 t * axis[2] * axis[2] + c}};
939 return Tensor<2, 3, Number>(rotation);
940}
941
942
943
944template <int dim, typename Number>
947 const Tensor<1, dim, Number> &V,
948 const Tensor<2, dim, Number> &F)
949{
951}
952
953
954
955template <int dim, typename Number>
958 const Tensor<2, dim, Number> &T,
959 const Tensor<2, dim, Number> &F)
960{
962}
963
964
965
966template <int dim, typename Number>
970 const Tensor<2, dim, Number> &F)
971{
973}
974
975
976
977template <int dim, typename Number>
980 const Tensor<4, dim, Number> &H,
981 const Tensor<2, dim, Number> &F)
982{
984}
985
986
987
988template <int dim, typename Number>
992 const Tensor<2, dim, Number> &F)
993{
995}
996
997
998
999template <int dim, typename Number>
1002 const Tensor<1, dim, Number> &v,
1003 const Tensor<2, dim, Number> &F)
1004{
1006}
1007
1008
1009
1010template <int dim, typename Number>
1013 const Tensor<2, dim, Number> &t,
1014 const Tensor<2, dim, Number> &F)
1015{
1017}
1018
1019
1020
1021template <int dim, typename Number>
1025 const Tensor<2, dim, Number> &F)
1026{
1028}
1029
1030
1031
1032template <int dim, typename Number>
1035 const Tensor<4, dim, Number> &h,
1036 const Tensor<2, dim, Number> &F)
1037{
1039}
1040
1041
1042
1043template <int dim, typename Number>
1047 const Tensor<2, dim, Number> &F)
1048{
1050}
1051
1052
1053
1054template <int dim, typename Number>
1057 const Tensor<1, dim, Number> &V,
1058 const Tensor<2, dim, Number> &F)
1059{
1061 transpose(invert(F)));
1062}
1063
1064
1065
1066template <int dim, typename Number>
1069 const Tensor<2, dim, Number> &T,
1070 const Tensor<2, dim, Number> &F)
1071{
1073 transpose(invert(F)));
1074}
1075
1076
1077
1078template <int dim, typename Number>
1082 const Tensor<2, dim, Number> &F)
1083{
1085 transpose(invert(F)));
1086}
1087
1088
1089
1090template <int dim, typename Number>
1093 const Tensor<4, dim, Number> &H,
1094 const Tensor<2, dim, Number> &F)
1095{
1097 transpose(invert(F)));
1098}
1099
1100
1101
1102template <int dim, typename Number>
1106 const Tensor<2, dim, Number> &F)
1107{
1109 transpose(invert(F)));
1110}
1111
1112
1113
1114template <int dim, typename Number>
1117 const Tensor<2, dim, Number> &F)
1118{
1120}
1121
1122
1123
1124template <int dim, typename Number>
1127 const Tensor<2, dim, Number> &F)
1128{
1130}
1131
1132
1133
1134template <int dim, typename Number>
1138 const Tensor<2, dim, Number> &F)
1139{
1141}
1142
1143
1144
1145template <int dim, typename Number>
1148 const Tensor<2, dim, Number> &F)
1149{
1151}
1152
1153
1154
1155template <int dim, typename Number>
1159 const Tensor<2, dim, Number> &F)
1160{
1162}
1163
1164
1165
1166template <int dim, typename Number>
1169 const Tensor<2, dim, Number> &F)
1170{
1171 return Number(1.0 / determinant(F)) * Contravariant::push_forward(V, F);
1172}
1173
1174
1175
1176template <int dim, typename Number>
1179 const Tensor<2, dim, Number> &F)
1180{
1181 return Number(1.0 / determinant(F)) * Contravariant::push_forward(T, F);
1182}
1183
1184
1185
1186template <int dim, typename Number>
1190 const Tensor<2, dim, Number> &F)
1191{
1192 return Number(1.0 / determinant(F)) * Contravariant::push_forward(T, F);
1193}
1194
1195
1196
1197template <int dim, typename Number>
1200 const Tensor<2, dim, Number> &F)
1201{
1202 return Number(1.0 / determinant(F)) * Contravariant::push_forward(H, F);
1203}
1204
1205
1206
1207template <int dim, typename Number>
1211 const Tensor<2, dim, Number> &F)
1212{
1213 return Number(1.0 / determinant(F)) * Contravariant::push_forward(H, F);
1214}
1215
1216
1217
1218template <int dim, typename Number>
1221 const Tensor<2, dim, Number> &F)
1222{
1223 return Number(determinant(F)) * Contravariant::pull_back(v, F);
1224}
1225
1226
1227
1228template <int dim, typename Number>
1231 const Tensor<2, dim, Number> &F)
1232{
1233 return Number(determinant(F)) * Contravariant::pull_back(t, F);
1234}
1235
1236
1237
1238template <int dim, typename Number>
1242 const Tensor<2, dim, Number> &F)
1243{
1244 return Number(determinant(F)) * Contravariant::pull_back(t, F);
1245}
1246
1247
1248
1249template <int dim, typename Number>
1252 const Tensor<2, dim, Number> &F)
1253{
1254 return Number(determinant(F)) * Contravariant::pull_back(h, F);
1255}
1256
1257
1258
1259template <int dim, typename Number>
1263 const Tensor<2, dim, Number> &F)
1264{
1265 return Number(determinant(F)) * Contravariant::pull_back(h, F);
1266}
1267
1268
1269
1270template <int dim, typename Number>
1273 const Tensor<2, dim, Number> &F)
1274{
1275 return cofactor(F) * N;
1276}
1277
1278
1279template <int dim, typename Number>
1282 const Tensor<2, dim, Number> &B)
1283{
1284 return contract<1, 0>(B, V);
1285}
1286
1287
1288
1289template <int dim, typename Number>
1292 const Tensor<2, dim, Number> &B)
1293{
1294 return contract<1, 0>(B, contract<1, 1>(T, B));
1295}
1296
1297
1298
1299template <int dim, typename Number>
1303 const Tensor<2, dim, Number> &B)
1304{
1306 for (unsigned int i = 0; i < dim; ++i)
1307 for (unsigned int J = 0; J < dim; ++J)
1308 // Loop over I but complex.h defines a macro I, so use I_ instead
1309 for (unsigned int I_ = 0; I_ < dim; ++I_)
1310 tmp_1[i][J] += B[i][I_] * T[I_][J];
1311
1313 for (unsigned int i = 0; i < dim; ++i)
1314 for (unsigned int j = i; j < dim; ++j)
1315 for (unsigned int J = 0; J < dim; ++J)
1316 out[i][j] += B[j][J] * tmp_1[i][J];
1317
1318 return out;
1319}
1320
1321
1322
1323template <int dim, typename Number>
1326 const Tensor<2, dim, Number> &B)
1327{
1328 // This contraction order and indexing might look a bit dubious, so a
1329 // quick explanation as to what's going on is probably in order:
1330 //
1331 // When the contract() function operates on the inner indices, the
1332 // result has the inner index and outer index transposed, i.e.
1333 // contract<2,1>(H,F) implies
1334 // T_{IJLk} = (H_{IJMN} F_{mM}) \delta_{mL} \delta_{Nk}
1335 // rather than T_{IJkL} (the desired result).
1336 // So, in effect, contraction of the 3rd (inner) index with F as the
1337 // second argument results in its transposition with respect to its
1338 // adjacent neighbor. This is due to the position of the argument F,
1339 // leading to the free index being on the right hand side of the result.
1340 // However, given that we can do two transformations from the LHS of H
1341 // and two from the right we can undo the otherwise erroneous
1342 // swapping of the outer indices upon application of the second
1343 // sets of contractions.
1344 //
1345 // Note: Its significantly quicker (in 3d) to push forward
1346 // each index individually
1347 return contract<1, 1>(
1348 B, contract<1, 1>(B, contract<2, 1>(contract<2, 1>(H, B), B)));
1349}
1350
1351
1352
1353template <int dim, typename Number>
1357 const Tensor<2, dim, Number> &B)
1358{
1359 // The first and last transformation operations respectively
1360 // break and recover the symmetry properties of the tensors.
1361 // We also want to perform a minimal number of operations here
1362 // and avoid some complications related to the transposition of
1363 // tensor indices when contracting inner indices using the contract()
1364 // function. (For an explanation of the contraction operations,
1365 // please see the note in the equivalent function for standard
1366 // Tensors.) So what we'll do here is manually perform the first
1367 // and last contractions that break/recover the tensor symmetries
1368 // on the inner indices, and use the contract() function only on
1369 // the outer indices.
1370 //
1371 // Note: Its significantly quicker (in 3d) to push forward
1372 // each index individually
1373
1374 // Push forward (inner) index 1
1376 // Loop over I but complex.h defines a macro I, so use I_ instead
1377 for (unsigned int I_ = 0; I_ < dim; ++I_)
1378 for (unsigned int j = 0; j < dim; ++j)
1379 for (unsigned int K = 0; K < dim; ++K)
1380 for (unsigned int L = 0; L < dim; ++L)
1381 for (unsigned int J = 0; J < dim; ++J)
1382 tmp[I_][j][K][L] += B[j][J] * H[I_][J][K][L];
1383
1384 // Push forward (outer) indices 0 and 3
1385 tmp = contract<1, 0>(B, contract<3, 1>(tmp, B));
1386
1387 // Push forward (inner) index 2
1389 for (unsigned int i = 0; i < dim; ++i)
1390 for (unsigned int j = i; j < dim; ++j)
1391 for (unsigned int k = 0; k < dim; ++k)
1392 for (unsigned int l = k; l < dim; ++l)
1393 for (unsigned int K = 0; K < dim; ++K)
1394 out[i][j][k][l] += B[k][K] * tmp[i][j][K][l];
1395
1396 return out;
1397}
1398
1399#endif // DOXYGEN
1400
1402
1403#endif
numbers::NumberTraits< Number >::real_type norm() const
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
DerivativeForm< 1, spacedim, dim, Number > transpose(const DerivativeForm< 1, dim, spacedim, Number > &DF)
#define Assert(cond, exc)
static ::ExceptionBase & ExcMessage(std::string arg1)
CGAL::Exact_predicates_exact_constructions_kernel_with_sqrt K
constexpr char L
constexpr char N
Tensor< 2, dim, Number > l(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
Tensor< 1, dim, Number > pull_back(const Tensor< 1, dim, Number > &v, const Tensor< 2, dim, Number > &F)
Tensor< 1, dim, Number > push_forward(const Tensor< 1, dim, Number > &V, const Tensor< 2, dim, Number > &F)
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)
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)
Tensor< 2, 3, Number > rotation_matrix_3d(const Tensor< 1, 3, Number > &axis, const Number &angle)
Tensor< 2, 2, Number > rotation_matrix_2d(const Number &angle)
Tensor< 1, dim, Number > nansons_formula(const Tensor< 1, dim, Number > &N, const Tensor< 2, dim, Number > &F)
Tensor< 1, dim, Number > basis_transformation(const Tensor< 1, dim, Number > &V, const Tensor< 2, dim, Number > &B)
*  *  *  RotationFunction< dim, Number >::RotationFunction Number(dim)
::VectorizedArray< Number, width > cos(const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > sin(const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > abs(const ::VectorizedArray< Number, width > &)
constexpr Number determinant(const SymmetricTensor< 2, dim, Number > &)
constexpr SymmetricTensor< 2, dim, Number > invert(const SymmetricTensor< 2, dim, Number > &)