Reference documentation for deal.II version GIT relicensing-214-g6e74dec06b 2024-03-27 18:10: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
notation.h
Go to the documentation of this file.
1// ------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: LGPL-2.1-or-later
4// Copyright (C) 2017 - 2023 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Part of the source code is dual licensed under Apache-2.0 WITH
9// LLVM-exception OR LGPL-2.1-or-later. Detailed license information
10// governing the source code and code contributions can be found in
11// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II.
12//
13// ------------------------------------------------------------------------
14
15#ifndef dealii_physics_notation_h
16#define dealii_physics_notation_h
17
18#include <deal.II/base/config.h>
19
23#include <deal.II/base/tensor.h>
24
26#include <deal.II/lac/vector.h>
27
28#include <type_traits>
29
31
32
33namespace Physics
34{
35 namespace Notation
36 {
284 namespace Kelvin
285 {
290 int,
291 int,
292 int,
293 << "The number of rows in the input matrix is " << arg1
294 << ", but needs to be either " << arg2 << " or " << arg3
295 << '.');
296
297
302 int,
303 int,
304 int,
305 int,
306 << "The number of rows in the input matrix is " << arg1
307 << ", but needs to be either " << arg2 << ',' << arg3
308 << ", or " << arg4 << '.');
309
310
315 int,
316 int,
317 int,
318 << "The number of columns in the input matrix is " << arg1
319 << ", but needs to be either " << arg2 << " or " << arg3
320 << '.');
321
322
327 int,
328 int,
329 int,
330 int,
331 << "The number of columns in the input matrix is " << arg1
332 << ", but needs to be either " << arg2 << ',' << arg3
333 << ", or " << arg4 << '.');
334
335
346 template <typename Number>
348 to_vector(const Number &s);
349
350
356 template <int dim, typename Number>
359
360
366 template <int dim, typename Number>
369
370
376 template <int dim, typename Number>
379
380
387 template <int dim, typename Number>
390
391
397 template <typename Number>
399 to_matrix(const Number &s);
400
401
407 template <int dim, typename Number>
410
411
417 template <int dim, typename Number>
420
421
427 template <int dim, typename Number>
430
431
441 template <int dim, typename Number>
444
477 template <int dim,
478 typename SubTensor1 = Tensor<2, dim>,
479 typename SubTensor2 = Tensor<1, dim>,
480 typename Number>
483
484
491 template <int dim, typename Number>
494
495
503 template <int dim, typename Number>
506
517 template <typename Number>
518 void
519 to_tensor(const Vector<Number> &vec, Number &s);
520
521
525 template <int dim, typename Number>
526 void
528
529
533 template <int dim, typename Number>
534 void
536
537
541 template <int dim, typename Number>
542 void
544
545
549 template <int dim, typename Number>
550 void
552
553
557 template <typename Number>
558 void
559 to_tensor(const FullMatrix<Number> &mtrx, Number &s);
560
561
565 template <int dim, typename Number>
566 void
568
569
573 template <int dim, typename Number>
574 void
576
577
581 template <int dim, typename Number>
582 void
584
585
589 template <int dim, typename Number>
590 void
593
594
604 template <int dim, typename Number>
605 void
607
608
612 template <int dim, typename Number>
613 void
615
616
620 template <int dim, typename Number>
621 void
624
625
630 template <typename TensorType, typename Number>
631 TensorType
633
634
639 template <typename TensorType, typename Number>
640 TensorType
644 } // namespace Kelvin
645
646 } // namespace Notation
647} // namespace Physics
648
649
650#ifndef DOXYGEN
651
652
653// ------------------------- inline functions ------------------------
654
655
656namespace Physics
657{
658 namespace Notation
659 {
660 namespace Kelvin
661 {
662 namespace internal
663 {
671 template <int dim>
672 std::pair<unsigned int, unsigned int>
673 indices_from_component(const unsigned int component_n,
674 const bool symmetric);
675
676
677 template <int dim>
678 std::pair<unsigned int, unsigned int>
679 indices_from_component(const unsigned int /*component_n*/, const bool)
680 {
682 return std::make_pair(0u, 0u);
683 }
684
685
686 template <>
687 inline std::pair<unsigned int, unsigned int>
688 indices_from_component<1>(const unsigned int component_n, const bool)
689 {
690 AssertIndexRange(component_n, 1);
691
692 return std::make_pair(0u, 0u);
693 }
694
695
696 template <>
697 inline std::pair<unsigned int, unsigned int>
698 indices_from_component<2>(const unsigned int component_n,
699 const bool symmetric)
700 {
701 if (symmetric == true)
702 {
703 Assert(
705 ExcIndexRange(component_n,
706 0,
708 }
709 else
710 {
712 ExcIndexRange(component_n,
713 0,
715 }
716
717 static const unsigned int indices[4][2] = {{0, 0},
718 {1, 1},
719 {0, 1},
720 {1, 0}};
721 return std::make_pair(indices[component_n][0],
722 indices[component_n][1]);
723 }
724
725
726 template <>
727 inline std::pair<unsigned int, unsigned int>
728 indices_from_component<3>(const unsigned int component_n,
729 const bool symmetric)
730 {
731 if (symmetric == true)
732 {
733 Assert(
735 ExcIndexRange(component_n,
736 0,
738 }
739 else
740 {
742 ExcIndexRange(component_n,
743 0,
745 }
746
747 static const unsigned int indices[9][2] = {{0, 0},
748 {1, 1},
749 {2, 2},
750 {1, 2},
751 {0, 2},
752 {0, 1},
753 {1, 0},
754 {2, 0},
755 {2, 1}};
756 return std::make_pair(indices[component_n][0],
757 indices[component_n][1]);
758 }
759
760
765 template <int dim>
766 double
767 vector_component_factor(const unsigned int component_i,
768 const bool symmetric)
769 {
770 if (symmetric == false)
771 return 1.0;
772
773 if (component_i < dim)
774 return 1.0;
775 else
776 return numbers::SQRT2;
777 }
778
779
784 template <int dim>
785 double
786 matrix_component_factor(const unsigned int component_i,
787 const unsigned int component_j,
788 const bool symmetric)
789 {
790 if (symmetric == false)
791 return 1.0;
792
793 // This case check returns equivalent of this result:
794 // internal::vector_component_factor<dim>(component_i,symmetric)*internal::vector_component_factor<dim>(component_j,symmetric);
795 if (component_i < dim && component_j < dim)
796 return 1.0;
797 else if (component_i >= dim && component_j >= dim)
798 return 2.0;
799 else // ((component_i >= dim && component_j < dim) || (component_i <
800 // dim && component_j >= dim))
801 return numbers::SQRT2;
802 }
803
804 } // namespace internal
805
806
807 template <typename Number>
809 to_vector(const Number &s)
810 {
812 const unsigned int n_rows = out.size();
813 for (unsigned int r = 0; r < n_rows; ++r)
814 out(r) = s;
815 return out;
816 }
817
818
819 template <int dim, typename Number>
822 {
823 return to_vector(s.operator const Number &());
824 }
825
826
827 template <int dim, typename Number>
830 {
832 const unsigned int n_rows = out.size();
833 for (unsigned int r = 0; r < n_rows; ++r)
834 {
835 const std::pair<unsigned int, unsigned int> indices =
836 internal::indices_from_component<dim>(r, false);
837 Assert(indices.first < dim, ExcInternalError());
838 const unsigned int i = indices.first;
839 out(r) = v[i];
840 }
841 return out;
842 }
843
844
845 template <int dim, typename Number>
848 {
850 const unsigned int n_rows = out.size();
851 for (unsigned int r = 0; r < n_rows; ++r)
852 {
853 const std::pair<unsigned int, unsigned int> indices =
854 internal::indices_from_component<dim>(r, false);
855 Assert(indices.first < dim, ExcInternalError());
856 Assert(indices.second < dim, ExcInternalError());
857 const unsigned int i = indices.first;
858 const unsigned int j = indices.second;
859 out(r) = t[i][j];
860 }
861 return out;
862 }
863
864
865 template <int dim, typename Number>
868 {
870 const unsigned int n_rows = out.size();
871 for (unsigned int r = 0; r < n_rows; ++r)
872 {
873 const std::pair<unsigned int, unsigned int> indices =
874 internal::indices_from_component<dim>(r, true);
875 Assert(indices.first < dim, ExcInternalError());
876 Assert(indices.second < dim, ExcInternalError());
877 Assert(indices.second >= indices.first, ExcInternalError());
878 const unsigned int i = indices.first;
879 const unsigned int j = indices.second;
880
881 const double factor =
882 internal::vector_component_factor<dim>(r, true);
883
884 out(r) = factor * st[i][j];
885 }
886 return out;
887 }
888
889
890 template <typename Number>
892 to_matrix(const Number &s)
893 {
895 out(0, 0) = s;
896 return out;
897 }
898
899
900 template <int dim, typename Number>
903 {
904 return to_matrix(s.operator const Number &());
905 }
906
907
908 template <int dim, typename Number>
911 {
913 const unsigned int n_rows = out.m();
914 const unsigned int n_cols = out.n();
915 for (unsigned int r = 0; r < n_rows; ++r)
916 {
917 const std::pair<unsigned int, unsigned int> indices =
918 internal::indices_from_component<dim>(r, false);
919 Assert(indices.first < dim, ExcInternalError());
920 const unsigned int i = indices.first;
921
922 for (unsigned int c = 0; c < n_cols; ++c)
923 {
924 Assert(c < 1, ExcInternalError());
925 out(r, c) = v[i];
926 }
927 }
928 return out;
929 }
930
931
932 template <int dim, typename Number>
935 {
936 FullMatrix<Number> out(dim, dim);
937 const unsigned int n_rows = out.m();
938 const unsigned int n_cols = out.n();
939 for (unsigned int r = 0; r < n_rows; ++r)
940 {
941 const std::pair<unsigned int, unsigned int> indices_i =
942 internal::indices_from_component<dim>(r, false);
943 Assert(indices_i.first < dim, ExcInternalError());
944 Assert(indices_i.second < dim, ExcInternalError());
945 const unsigned int i = indices_i.first;
946
947 for (unsigned int c = 0; c < n_cols; ++c)
948 {
949 const std::pair<unsigned int, unsigned int> indices_j =
950 internal::indices_from_component<dim>(c, false);
951 Assert(indices_j.first < dim, ExcInternalError());
952 Assert(indices_j.second < dim, ExcInternalError());
953 const unsigned int j = indices_j.second;
954
955 out(r, c) = t[i][j];
956 }
957 }
958 return out;
959 }
960
961
962 template <int dim, typename Number>
965 {
967 }
968
969
970 namespace internal
971 {
972 template <typename TensorType>
973 struct is_rank_2_symmetric_tensor : std::false_type
974 {};
975
976 template <int dim, typename Number>
977 struct is_rank_2_symmetric_tensor<SymmetricTensor<2, dim, Number>>
978 : std::true_type
979 {};
980 } // namespace internal
981
982
983 template <int dim,
984 typename SubTensor1,
985 typename SubTensor2,
986 typename Number>
989 {
990 static_assert(
991 (SubTensor1::dimension == dim && SubTensor2::dimension == dim),
992 "Sub-tensor spatial dimension is different from those of the input tensor.");
993
994 static_assert(
995 (SubTensor1::rank == 2 && SubTensor2::rank == 1) ||
996 (SubTensor1::rank == 1 && SubTensor2::rank == 2),
997 "Cannot build a rank 3 tensor from the given combination of sub-tensors.");
998
999 FullMatrix<Number> out(SubTensor1::n_independent_components,
1000 SubTensor2::n_independent_components);
1001 const unsigned int n_rows = out.m();
1002 const unsigned int n_cols = out.n();
1003
1004 if (SubTensor1::rank == 2 && SubTensor2::rank == 1)
1005 {
1006 const bool subtensor_is_rank_2_symmetric_tensor =
1007 internal::is_rank_2_symmetric_tensor<SubTensor1>::value;
1008
1009 for (unsigned int r = 0; r < n_rows; ++r)
1010 {
1011 const std::pair<unsigned int, unsigned int> indices_ij =
1012 internal::indices_from_component<dim>(
1013 r, subtensor_is_rank_2_symmetric_tensor);
1014 Assert(indices_ij.first < dim, ExcInternalError());
1015 Assert(indices_ij.second < dim, ExcInternalError());
1016 if (subtensor_is_rank_2_symmetric_tensor)
1017 {
1018 Assert(indices_ij.second >= indices_ij.first,
1020 }
1021 const unsigned int i = indices_ij.first;
1022 const unsigned int j = indices_ij.second;
1023
1024 const double factor = internal::vector_component_factor<dim>(
1025 r, subtensor_is_rank_2_symmetric_tensor);
1026
1027 for (unsigned int c = 0; c < n_cols; ++c)
1028 {
1029 const std::pair<unsigned int, unsigned int> indices_k =
1030 internal::indices_from_component<dim>(c, false);
1031 Assert(indices_k.first < dim, ExcInternalError());
1032 const unsigned int k = indices_k.first;
1033
1034 if (subtensor_is_rank_2_symmetric_tensor)
1035 out(r, c) = factor * t[i][j][k];
1036 else
1037 out(r, c) = t[i][j][k];
1038 }
1039 }
1040 }
1041 else if (SubTensor1::rank == 1 && SubTensor2::rank == 2)
1042 {
1043 const bool subtensor_is_rank_2_symmetric_tensor =
1044 internal::is_rank_2_symmetric_tensor<SubTensor2>::value;
1045
1046 for (unsigned int r = 0; r < n_rows; ++r)
1047 {
1048 const std::pair<unsigned int, unsigned int> indices_k =
1049 internal::indices_from_component<dim>(r, false);
1050 Assert(indices_k.first < dim, ExcInternalError());
1051 const unsigned int k = indices_k.first;
1052
1053 for (unsigned int c = 0; c < n_cols; ++c)
1054 {
1055 const std::pair<unsigned int, unsigned int> indices_ij =
1056 internal::indices_from_component<dim>(
1057 c, subtensor_is_rank_2_symmetric_tensor);
1058 Assert(indices_ij.first < dim, ExcInternalError());
1059 Assert(indices_ij.second < dim, ExcInternalError());
1060 if (subtensor_is_rank_2_symmetric_tensor)
1061 {
1062 Assert(indices_ij.second >= indices_ij.first,
1064 }
1065 const unsigned int i = indices_ij.first;
1066 const unsigned int j = indices_ij.second;
1067
1068 if (subtensor_is_rank_2_symmetric_tensor)
1069 {
1070 const double factor =
1071 internal::vector_component_factor<dim>(
1072 c, subtensor_is_rank_2_symmetric_tensor);
1073 out(r, c) = factor * t[k][i][j];
1074 }
1075 else
1076 out(r, c) = t[k][i][j];
1077 }
1078 }
1079 }
1080 else
1081 {
1083 }
1084
1085 return out;
1086 }
1087
1088
1089 template <int dim, typename Number>
1092 {
1096 const unsigned int n_rows = out.m();
1097 const unsigned int n_cols = out.n();
1098 for (unsigned int r = 0; r < n_rows; ++r)
1099 {
1100 const std::pair<unsigned int, unsigned int> indices_ij =
1101 internal::indices_from_component<dim>(r, false);
1102 Assert(indices_ij.first < dim, ExcInternalError());
1103 Assert(indices_ij.second < dim, ExcInternalError());
1104 const unsigned int i = indices_ij.first;
1105 const unsigned int j = indices_ij.second;
1106
1107 for (unsigned int c = 0; c < n_cols; ++c)
1108 {
1109 const std::pair<unsigned int, unsigned int> indices_kl =
1110 internal::indices_from_component<dim>(c, false);
1111 Assert(indices_kl.first < dim, ExcInternalError());
1112 Assert(indices_kl.second < dim, ExcInternalError());
1113 const unsigned int k = indices_kl.first;
1114 const unsigned int l = indices_kl.second;
1115
1116 out(r, c) = t[i][j][k][l];
1117 }
1118 }
1119 return out;
1120 }
1121
1122
1123 template <int dim, typename Number>
1126 {
1130 const unsigned int n_rows = out.m();
1131 const unsigned int n_cols = out.n();
1132 for (unsigned int r = 0; r < n_rows; ++r)
1133 {
1134 const std::pair<unsigned int, unsigned int> indices_ij =
1135 internal::indices_from_component<dim>(r, true);
1136 Assert(indices_ij.first < dim, ExcInternalError());
1137 Assert(indices_ij.second < dim, ExcInternalError());
1138 Assert(indices_ij.second >= indices_ij.first, ExcInternalError());
1139 const unsigned int i = indices_ij.first;
1140 const unsigned int j = indices_ij.second;
1141
1142 for (unsigned int c = 0; c < n_cols; ++c)
1143 {
1144 const std::pair<unsigned int, unsigned int> indices_kl =
1145 internal::indices_from_component<dim>(c, true);
1146 Assert(indices_kl.first < dim, ExcInternalError());
1147 Assert(indices_kl.second < dim, ExcInternalError());
1148 Assert(indices_kl.second >= indices_kl.first,
1150 const unsigned int k = indices_kl.first;
1151 const unsigned int l = indices_kl.second;
1152
1153 const double factor =
1154 internal::matrix_component_factor<dim>(r, c, true);
1155
1156 out(r, c) = factor * st[i][j][k][l];
1157 }
1158 }
1159 return out;
1160 }
1161
1162
1163 template <typename Number>
1164 void
1165 to_tensor(const Vector<Number> &vec, Number &s)
1166 {
1167 Assert(vec.size() == 1, ExcDimensionMismatch(vec.size(), 1));
1168 s = vec(0);
1169 }
1170
1171
1172 template <int dim, typename Number>
1173 void
1175 {
1176 return to_tensor(vec, s.operator Number &());
1177 }
1178
1179
1180 template <int dim, typename Number>
1181 void
1183 {
1186 const unsigned int n_rows = vec.size();
1187 for (unsigned int r = 0; r < n_rows; ++r)
1188 {
1189 const std::pair<unsigned int, unsigned int> indices =
1190 internal::indices_from_component<dim>(r, false);
1191 Assert(indices.first < dim, ExcInternalError());
1192 const unsigned int i = indices.first;
1193 v[i] = vec(r);
1194 }
1195 }
1196
1197
1198 template <int dim, typename Number>
1199 void
1201 {
1204 const unsigned int n_rows = vec.size();
1205 for (unsigned int r = 0; r < n_rows; ++r)
1206 {
1207 const std::pair<unsigned int, unsigned int> indices =
1208 internal::indices_from_component<dim>(r, false);
1209 Assert(indices.first < dim, ExcInternalError());
1210 Assert(indices.second < dim, ExcInternalError());
1211 const unsigned int i = indices.first;
1212 const unsigned int j = indices.second;
1213 t[i][j] = vec(r);
1214 }
1215 }
1216
1217
1218 template <int dim, typename Number>
1219 void
1221 {
1224 const unsigned int n_rows = vec.size();
1225 for (unsigned int r = 0; r < n_rows; ++r)
1226 {
1227 const std::pair<unsigned int, unsigned int> indices =
1228 internal::indices_from_component<dim>(r, true);
1229 Assert(indices.first < dim, ExcInternalError());
1230 Assert(indices.second < dim, ExcInternalError());
1231 Assert(indices.second >= indices.first, ExcInternalError());
1232 const unsigned int i = indices.first;
1233 const unsigned int j = indices.second;
1234
1235 const double inv_factor =
1236 1.0 / internal::vector_component_factor<dim>(r, true);
1237
1238 st[i][j] = inv_factor * vec(r);
1239 }
1240 }
1241
1242
1243 template <typename Number>
1244 void
1245 to_tensor(const FullMatrix<Number> &mtrx, Number &s)
1246 {
1247 Assert(mtrx.m() == 1, ExcDimensionMismatch(mtrx.m(), 1));
1248 Assert(mtrx.n() == 1, ExcDimensionMismatch(mtrx.n(), 1));
1249 Assert(mtrx.n_elements() == 1,
1250 ExcDimensionMismatch(mtrx.n_elements(), 1));
1251 s = mtrx(0, 0);
1252 }
1253
1254
1255 template <int dim, typename Number>
1256 void
1258 {
1259 return to_tensor(mtrx, s.operator Number &());
1260 }
1261
1262
1263 template <int dim, typename Number>
1264 void
1266 {
1267 Assert(mtrx.m() == dim, ExcDimensionMismatch(mtrx.m(), dim));
1268 Assert(mtrx.n() == 1, ExcDimensionMismatch(mtrx.n(), 1));
1269 Assert(mtrx.n_elements() == v.n_independent_components,
1270 ExcDimensionMismatch(mtrx.n_elements(),
1272
1273 const unsigned int n_rows = mtrx.m();
1274 const unsigned int n_cols = mtrx.n();
1275 for (unsigned int r = 0; r < n_rows; ++r)
1276 {
1277 const std::pair<unsigned int, unsigned int> indices =
1278 internal::indices_from_component<dim>(r, false);
1279 Assert(indices.first < dim, ExcInternalError());
1280 Assert(indices.second == 0, ExcInternalError());
1281 const unsigned int i = indices.first;
1282
1283 for (unsigned int c = 0; c < n_cols; ++c)
1284 {
1285 Assert(c < 1, ExcInternalError());
1286 v[i] = mtrx(r, c);
1287 }
1288 }
1289 }
1290
1291
1292 template <int dim, typename Number>
1293 void
1295 {
1296 Assert(mtrx.m() == dim, ExcDimensionMismatch(mtrx.m(), dim));
1297 Assert(mtrx.n() == dim, ExcDimensionMismatch(mtrx.n(), dim));
1298 Assert(mtrx.n_elements() == t.n_independent_components,
1299 ExcDimensionMismatch(mtrx.n_elements(),
1301
1302 const unsigned int n_rows = mtrx.m();
1303 const unsigned int n_cols = mtrx.n();
1304 for (unsigned int r = 0; r < n_rows; ++r)
1305 {
1306 const std::pair<unsigned int, unsigned int> indices_i =
1307 internal::indices_from_component<dim>(r, false);
1308 Assert(indices_i.first < dim, ExcInternalError());
1309 Assert(indices_i.second < dim, ExcInternalError());
1310 const unsigned int i = indices_i.first;
1311
1312 for (unsigned int c = 0; c < n_cols; ++c)
1313 {
1314 const std::pair<unsigned int, unsigned int> indices_j =
1315 internal::indices_from_component<dim>(c, false);
1316 Assert(indices_j.first < dim, ExcInternalError());
1317 Assert(indices_j.second < dim, ExcInternalError());
1318 const unsigned int j = indices_j.second;
1319
1320 t[i][j] = mtrx(r, c);
1321 }
1322 }
1323 }
1324
1325
1326 template <int dim, typename Number>
1327 void
1328 to_tensor(const FullMatrix<Number> &mtrx,
1330 {
1331 // Its impossible to fit the (dim^2 + dim)/2 entries into a square
1332 // matrix We therefore assume that its been converted to a standard
1333 // tensor format using to_matrix (SymmetricTensor<2,dim,Number>) at some
1334 // point...
1335 Assert(mtrx.m() == dim, ExcDimensionMismatch(mtrx.m(), dim));
1336 Assert(mtrx.n() == dim, ExcDimensionMismatch(mtrx.n(), dim));
1337 Assert((mtrx.n_elements() ==
1340 mtrx.n_elements(),
1342
1344 to_tensor(mtrx, tmp);
1345 st = symmetrize(tmp);
1346 Assert((Tensor<2, dim, Number>(st) - tmp).norm() < 1e-12,
1347 ExcMessage(
1348 "The entries stored inside the matrix were not symmetric"));
1349 }
1350
1351
1352 template <int dim, typename Number>
1353 void
1355 {
1357 (mtrx.m() ==
1359 (mtrx.m() ==
1362 mtrx.m(),
1367 (mtrx.n() ==
1369 (mtrx.n() ==
1372 mtrx.n(),
1376
1377 const unsigned int n_rows = mtrx.m();
1378 const unsigned int n_cols = mtrx.n();
1380 {
1381 Assert(
1383 (mtrx.m() ==
1386 mtrx.m(),
1389
1390 const bool subtensor_is_rank_2_symmetric_tensor =
1391 (mtrx.m() ==
1393
1394 for (unsigned int r = 0; r < n_rows; ++r)
1395 {
1396 const std::pair<unsigned int, unsigned int> indices_ij =
1397 internal::indices_from_component<dim>(
1398 r, subtensor_is_rank_2_symmetric_tensor);
1399 Assert(indices_ij.first < dim, ExcInternalError());
1400 Assert(indices_ij.second < dim, ExcInternalError());
1401 if (subtensor_is_rank_2_symmetric_tensor)
1402 {
1403 Assert(indices_ij.second >= indices_ij.first,
1405 }
1406 const unsigned int i = indices_ij.first;
1407 const unsigned int j = indices_ij.second;
1408
1409 const double inv_factor =
1410 1.0 / internal::vector_component_factor<dim>(
1411 r, subtensor_is_rank_2_symmetric_tensor);
1412
1413 for (unsigned int c = 0; c < n_cols; ++c)
1414 {
1415 const std::pair<unsigned int, unsigned int> indices_k =
1416 internal::indices_from_component<dim>(c, false);
1417 Assert(indices_k.first < dim, ExcInternalError());
1418 const unsigned int k = indices_k.first;
1419
1420 if (subtensor_is_rank_2_symmetric_tensor)
1421 {
1422 t[i][j][k] = inv_factor * mtrx(r, c);
1423 t[j][i][k] = t[i][j][k];
1424 }
1425 else
1426 t[i][j][k] = mtrx(r, c);
1427 }
1428 }
1429 }
1430 else
1431 {
1432 Assert(
1436 Assert(
1438 (mtrx.n() ==
1441 mtrx.n(),
1444
1445 const bool subtensor_is_rank_2_symmetric_tensor =
1446 (mtrx.n() ==
1448
1449 for (unsigned int r = 0; r < n_rows; ++r)
1450 {
1451 const std::pair<unsigned int, unsigned int> indices_k =
1452 internal::indices_from_component<dim>(r, false);
1453 Assert(indices_k.first < dim, ExcInternalError());
1454 const unsigned int k = indices_k.first;
1455
1456 for (unsigned int c = 0; c < n_cols; ++c)
1457 {
1458 const std::pair<unsigned int, unsigned int> indices_ij =
1459 internal::indices_from_component<dim>(
1460 c, subtensor_is_rank_2_symmetric_tensor);
1461 Assert(indices_ij.first < dim, ExcInternalError());
1462 Assert(indices_ij.second < dim, ExcInternalError());
1463 if (subtensor_is_rank_2_symmetric_tensor)
1464 {
1465 Assert(indices_ij.second >= indices_ij.first,
1467 }
1468 const unsigned int i = indices_ij.first;
1469 const unsigned int j = indices_ij.second;
1470
1471 if (subtensor_is_rank_2_symmetric_tensor)
1472 {
1473 const double inv_factor =
1474 1.0 / internal::vector_component_factor<dim>(
1475 c, subtensor_is_rank_2_symmetric_tensor);
1476 t[k][i][j] = inv_factor * mtrx(r, c);
1477 t[k][j][i] = t[k][i][j];
1478 }
1479 else
1480 t[k][i][j] = mtrx(r, c);
1481 }
1482 }
1483 }
1484 }
1485
1486
1487 template <int dim, typename Number>
1488 void
1490 {
1497 Assert(mtrx.n_elements() == t.n_independent_components,
1498 ExcDimensionMismatch(mtrx.n_elements(),
1500
1501 const unsigned int n_rows = mtrx.m();
1502 const unsigned int n_cols = mtrx.n();
1503 for (unsigned int r = 0; r < n_rows; ++r)
1504 {
1505 const std::pair<unsigned int, unsigned int> indices_ij =
1506 internal::indices_from_component<dim>(r, false);
1507 Assert(indices_ij.first < dim, ExcInternalError());
1508 Assert(indices_ij.second < dim, ExcInternalError());
1509 const unsigned int i = indices_ij.first;
1510 const unsigned int j = indices_ij.second;
1511
1512 for (unsigned int c = 0; c < n_cols; ++c)
1513 {
1514 const std::pair<unsigned int, unsigned int> indices_kl =
1515 internal::indices_from_component<dim>(c, false);
1516 Assert(indices_kl.first < dim, ExcInternalError());
1517 Assert(indices_kl.second < dim, ExcInternalError());
1518 const unsigned int k = indices_kl.first;
1519 const unsigned int l = indices_kl.second;
1520
1521 t[i][j][k][l] = mtrx(r, c);
1522 }
1523 }
1524 }
1525
1526
1527 template <int dim, typename Number>
1528 void
1529 to_tensor(const FullMatrix<Number> &mtrx,
1531 {
1532 Assert((mtrx.m() ==
1535 mtrx.m(),
1537 Assert((mtrx.n() ==
1540 mtrx.n(),
1542 Assert(mtrx.n_elements() == st.n_independent_components,
1543 ExcDimensionMismatch(mtrx.n_elements(),
1545
1546 const unsigned int n_rows = mtrx.m();
1547 const unsigned int n_cols = mtrx.n();
1548 for (unsigned int r = 0; r < n_rows; ++r)
1549 {
1550 const std::pair<unsigned int, unsigned int> indices_ij =
1551 internal::indices_from_component<dim>(r, false);
1552 Assert(indices_ij.first < dim, ExcInternalError());
1553 Assert(indices_ij.second < dim, ExcInternalError());
1554 const unsigned int i = indices_ij.first;
1555 const unsigned int j = indices_ij.second;
1556
1557 for (unsigned int c = 0; c < n_cols; ++c)
1558 {
1559 const std::pair<unsigned int, unsigned int> indices_kl =
1560 internal::indices_from_component<dim>(c, false);
1561 Assert(indices_kl.first < dim, ExcInternalError());
1562 Assert(indices_kl.second < dim, ExcInternalError());
1563 const unsigned int k = indices_kl.first;
1564 const unsigned int l = indices_kl.second;
1565
1566 const double inv_factor =
1567 1.0 / internal::matrix_component_factor<dim>(r, c, true);
1568
1569 st[i][j][k][l] = inv_factor * mtrx(r, c);
1570 }
1571 }
1572 }
1573
1574
1575 template <typename TensorType, typename Number>
1576 inline TensorType
1577 to_tensor(const Vector<Number> &vec)
1578 {
1579 TensorType out;
1580 to_tensor(vec, out);
1581 return out;
1582 }
1583
1584
1585 template <typename TensorType, typename Number>
1586 inline TensorType
1587 to_tensor(const FullMatrix<Number> &mtrx)
1588 {
1589 TensorType out;
1590 to_tensor(mtrx, out);
1591 return out;
1592 }
1593
1594 } // namespace Kelvin
1595 } // namespace Notation
1596} // namespace Physics
1597
1598
1599#endif // DOXYGEN
1600
1601
1603
1604#endif
size_type n() const
size_type m() const
static constexpr unsigned int n_independent_components
static constexpr unsigned int n_independent_components
Definition tensor.h:546
virtual size_type size() const override
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:502
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:503
static ::ExceptionBase & ExcNotationExcFullMatrixToTensorRowSize2(int arg1, int arg2, int arg3)
#define DeclException4(Exception4, type1, type2, type3, type4, outsequence)
Definition exceptions.h:585
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
static ::ExceptionBase & ExcNotationExcFullMatrixToTensorRowSize3(int arg1, int arg2, int arg3, int arg4)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
#define DeclException3(Exception3, type1, type2, type3, outsequence)
Definition exceptions.h:562
static ::ExceptionBase & ExcIndexRange(std::size_t arg1, std::size_t arg2, std::size_t arg3)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
static ::ExceptionBase & ExcMessage(std::string arg1)
static ::ExceptionBase & ExcNotationExcFullMatrixToTensorColSize3(int arg1, int arg2, int arg3, int arg4)
static ::ExceptionBase & ExcNotationExcFullMatrixToTensorColSize2(int arg1, int arg2, int arg3)
#define AssertThrow(cond, exc)
double norm(const FEValuesBase< dim > &fe, const ArrayView< const std::vector< Tensor< 1, dim > > > &Du)
Definition divergence.h:471
Tensor< 2, dim, Number > l(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
void to_tensor(const Vector< Number > &vec, Number &s)
FullMatrix< Number > to_matrix(const Number &s)
Vector< Number > to_vector(const Number &s)
static constexpr double SQRT2
Definition numbers.h:274
const InputIterator OutputIterator out
Definition parallel.h:167
DEAL_II_HOST constexpr SymmetricTensor< 2, dim, Number > symmetrize(const Tensor< 2, dim, Number > &t)