deal.II version GIT relicensing-6839-g338455934c 2026-10-02 12: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: Apache-2.0 WITH LLVM-exception OR LGPL-2.1-or-later
4// Copyright (C) 2017 - 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_physics_notation_h
14#define dealii_physics_notation_h
15
16#include <deal.II/base/config.h>
17
21#include <deal.II/base/tensor.h>
22
24#include <deal.II/lac/vector.h>
25
26#include <type_traits>
27
29
30
31namespace Physics
32{
33 namespace Notation
34 {
256 namespace Kelvin
257 {
262 int,
263 int,
264 int,
265 << "The number of rows in the input matrix is " << arg1
266 << ", but needs to be either " << arg2 << " or " << arg3
267 << '.');
268
269
274 int,
275 int,
276 int,
277 int,
278 << "The number of rows in the input matrix is " << arg1
279 << ", but needs to be either " << arg2 << ',' << arg3
280 << ", or " << arg4 << '.');
281
282
287 int,
288 int,
289 int,
290 << "The number of columns in the input matrix is " << arg1
291 << ", but needs to be either " << arg2 << " or " << arg3
292 << '.');
293
294
299 int,
300 int,
301 int,
302 int,
303 << "The number of columns in the input matrix is " << arg1
304 << ", but needs to be either " << arg2 << ',' << arg3
305 << ", or " << arg4 << '.');
306
307
318 template <typename Number>
320 to_vector(const Number &s);
321
322
328 template <int dim, typename Number>
331
332
338 template <int dim, typename Number>
341
342
348 template <int dim, typename Number>
351
352
359 template <int dim, typename Number>
362
363
369 template <typename Number>
371 to_matrix(const Number &s);
372
373
379 template <int dim, typename Number>
382
383
389 template <int dim, typename Number>
392
393
399 template <int dim, typename Number>
402
403
413 template <int dim, typename Number>
416
449 template <int dim,
450 typename SubTensor1 = Tensor<2, dim>,
451 typename SubTensor2 = Tensor<1, dim>,
452 typename Number>
455
456
463 template <int dim, typename Number>
466
467
475 template <int dim, typename Number>
478
489 template <typename Number>
490 void
491 to_tensor(const Vector<Number> &vec, Number &s);
492
493
497 template <int dim, typename Number>
498 void
500
501
505 template <int dim, typename Number>
506 void
508
509
513 template <int dim, typename Number>
514 void
516
517
521 template <int dim, typename Number>
522 void
524
525
529 template <typename Number>
530 void
531 to_tensor(const FullMatrix<Number> &mtrx, Number &s);
532
533
537 template <int dim, typename Number>
538 void
540
541
545 template <int dim, typename Number>
546 void
548
549
553 template <int dim, typename Number>
554 void
556
557
561 template <int dim, typename Number>
562 void
565
566
576 template <int dim, typename Number>
577 void
579
580
584 template <int dim, typename Number>
585 void
587
588
592 template <int dim, typename Number>
593 void
596
597
602 template <typename TensorType, typename Number>
603 TensorType
605
606
611 template <typename TensorType, typename Number>
612 TensorType
616 } // namespace Kelvin
617
618 } // namespace Notation
619} // namespace Physics
620
621
622#ifndef DOXYGEN
623
624
625// ------------------------- inline functions ------------------------
626
627
628namespace Physics
629{
630 namespace Notation
631 {
632 namespace Kelvin
633 {
634 namespace internal
635 {
643 template <int dim>
644 std::pair<unsigned int, unsigned int>
645 indices_from_component(const unsigned int component_n,
646 const bool symmetric);
647
648
649 template <int dim>
650 std::pair<unsigned int, unsigned int>
651 indices_from_component(const unsigned int /*component_n*/, const bool)
652 {
654 return std::make_pair(0u, 0u);
655 }
656
657
658 template <>
659 inline std::pair<unsigned int, unsigned int>
660 indices_from_component<1>(const unsigned int component_n, const bool)
661 {
662 AssertIndexRange(component_n, 1);
663
664 return std::make_pair(0u, 0u);
665 }
666
667
668 template <>
669 inline std::pair<unsigned int, unsigned int>
670 indices_from_component<2>(const unsigned int component_n,
671 const bool symmetric)
672 {
673 if (symmetric == true)
674 {
675 Assert(
677 ExcIndexRange(component_n,
678 0,
680 }
681 else
682 {
684 ExcIndexRange(component_n,
685 0,
687 }
688
689 static const unsigned int indices[4][2] = {{0, 0},
690 {1, 1},
691 {0, 1},
692 {1, 0}};
693 return std::make_pair(indices[component_n][0],
694 indices[component_n][1]);
695 }
696
697
698 template <>
699 inline std::pair<unsigned int, unsigned int>
700 indices_from_component<3>(const unsigned int component_n,
701 const bool symmetric)
702 {
703 if (symmetric == true)
704 {
705 Assert(
707 ExcIndexRange(component_n,
708 0,
710 }
711 else
712 {
714 ExcIndexRange(component_n,
715 0,
717 }
718
719 static const unsigned int indices[9][2] = {{0, 0},
720 {1, 1},
721 {2, 2},
722 {1, 2},
723 {0, 2},
724 {0, 1},
725 {1, 0},
726 {2, 0},
727 {2, 1}};
728 return std::make_pair(indices[component_n][0],
729 indices[component_n][1]);
730 }
731
732
737 template <int dim>
738 double
739 vector_component_factor(const unsigned int component_i,
740 const bool symmetric)
741 {
742 if (symmetric == false)
743 return 1.0;
744
745 if (component_i < dim)
746 return 1.0;
747 else
748 return numbers::SQRT2;
749 }
750
751
756 template <int dim>
757 double
758 matrix_component_factor(const unsigned int component_i,
759 const unsigned int component_j,
760 const bool symmetric)
761 {
762 if (symmetric == false)
763 return 1.0;
764
765 // This case check returns equivalent of this result:
766 // internal::vector_component_factor<dim>(component_i,symmetric)*internal::vector_component_factor<dim>(component_j,symmetric);
767 if (component_i < dim && component_j < dim)
768 return 1.0;
769 else if (component_i >= dim && component_j >= dim)
770 return 2.0;
771 else // ((component_i >= dim && component_j < dim) || (component_i <
772 // dim && component_j >= dim))
773 return numbers::SQRT2;
774 }
775
776 } // namespace internal
777
778
779 template <typename Number>
781 to_vector(const Number &s)
782 {
783 Vector<Number> out(1);
784 const unsigned int n_rows = out.size();
785 for (unsigned int r = 0; r < n_rows; ++r)
786 out(r) = s;
787 return out;
788 }
789
790
791 template <int dim, typename Number>
794 {
795 return to_vector(s.operator const Number &());
796 }
797
798
799 template <int dim, typename Number>
802 {
804 const unsigned int n_rows = out.size();
805 for (unsigned int r = 0; r < n_rows; ++r)
806 {
807 const std::pair<unsigned int, unsigned int> indices =
808 internal::indices_from_component<dim>(r, false);
809 Assert(indices.first < dim, ExcInternalError());
810 const unsigned int i = indices.first;
811 out(r) = v[i];
812 }
813 return out;
814 }
815
816
817 template <int dim, typename Number>
820 {
822 const unsigned int n_rows = out.size();
823 for (unsigned int r = 0; r < n_rows; ++r)
824 {
825 const std::pair<unsigned int, unsigned int> indices =
826 internal::indices_from_component<dim>(r, false);
827 Assert(indices.first < dim, ExcInternalError());
828 Assert(indices.second < dim, ExcInternalError());
829 const unsigned int i = indices.first;
830 const unsigned int j = indices.second;
831 out(r) = t[i][j];
832 }
833 return out;
834 }
835
836
837 template <int dim, typename Number>
840 {
842 const unsigned int n_rows = out.size();
843 for (unsigned int r = 0; r < n_rows; ++r)
844 {
845 const std::pair<unsigned int, unsigned int> indices =
846 internal::indices_from_component<dim>(r, true);
847 Assert(indices.first < dim, ExcInternalError());
848 Assert(indices.second < dim, ExcInternalError());
849 Assert(indices.second >= indices.first, ExcInternalError());
850 const unsigned int i = indices.first;
851 const unsigned int j = indices.second;
852
853 const double factor =
854 internal::vector_component_factor<dim>(r, true);
855
856 out(r) = factor * st[i][j];
857 }
858 return out;
859 }
860
861
862 template <typename Number>
864 to_matrix(const Number &s)
865 {
866 FullMatrix<Number> out(1, 1);
867 out(0, 0) = s;
868 return out;
869 }
870
871
872 template <int dim, typename Number>
875 {
876 return to_matrix(s.operator const Number &());
877 }
878
879
880 template <int dim, typename Number>
883 {
885 const unsigned int n_rows = out.m();
886 const unsigned int n_cols = out.n();
887 for (unsigned int r = 0; r < n_rows; ++r)
888 {
889 const std::pair<unsigned int, unsigned int> indices =
890 internal::indices_from_component<dim>(r, false);
891 Assert(indices.first < dim, ExcInternalError());
892 const unsigned int i = indices.first;
893
894 for (unsigned int c = 0; c < n_cols; ++c)
895 {
896 Assert(c < 1, ExcInternalError());
897 out(r, c) = v[i];
898 }
899 }
900 return out;
901 }
902
903
904 template <int dim, typename Number>
907 {
908 FullMatrix<Number> out(dim, dim);
909 const unsigned int n_rows = out.m();
910 const unsigned int n_cols = out.n();
911 for (unsigned int r = 0; r < n_rows; ++r)
912 {
913 const std::pair<unsigned int, unsigned int> indices_i =
914 internal::indices_from_component<dim>(r, false);
915 Assert(indices_i.first < dim, ExcInternalError());
916 Assert(indices_i.second < dim, ExcInternalError());
917 const unsigned int i = indices_i.first;
918
919 for (unsigned int c = 0; c < n_cols; ++c)
920 {
921 const std::pair<unsigned int, unsigned int> indices_j =
922 internal::indices_from_component<dim>(c, false);
923 Assert(indices_j.first < dim, ExcInternalError());
924 Assert(indices_j.second < dim, ExcInternalError());
925 const unsigned int j = indices_j.second;
926
927 out(r, c) = t[i][j];
928 }
929 }
930 return out;
931 }
932
933
934 template <int dim, typename Number>
937 {
939 }
940
941
942 namespace internal
943 {
944 template <typename TensorType>
945 struct is_rank_2_symmetric_tensor : std::false_type
946 {};
947
948 template <int dim, typename Number>
949 struct is_rank_2_symmetric_tensor<SymmetricTensor<2, dim, Number>>
950 : std::true_type
951 {};
952 } // namespace internal
953
954
955 template <int dim,
956 typename SubTensor1,
957 typename SubTensor2,
958 typename Number>
961 {
962 static_assert(
963 (SubTensor1::dimension == dim && SubTensor2::dimension == dim),
964 "Sub-tensor spatial dimension is different from those of the input tensor.");
965
966 static_assert(
967 (SubTensor1::rank == 2 && SubTensor2::rank == 1) ||
968 (SubTensor1::rank == 1 && SubTensor2::rank == 2),
969 "Cannot build a rank 3 tensor from the given combination of sub-tensors.");
970
971 FullMatrix<Number> out(SubTensor1::n_independent_components,
972 SubTensor2::n_independent_components);
973 const unsigned int n_rows = out.m();
974 const unsigned int n_cols = out.n();
975
976 if (SubTensor1::rank == 2 && SubTensor2::rank == 1)
977 {
978 const bool subtensor_is_rank_2_symmetric_tensor =
979 internal::is_rank_2_symmetric_tensor<SubTensor1>::value;
980
981 for (unsigned int r = 0; r < n_rows; ++r)
982 {
983 const std::pair<unsigned int, unsigned int> indices_ij =
984 internal::indices_from_component<dim>(
985 r, subtensor_is_rank_2_symmetric_tensor);
986 Assert(indices_ij.first < dim, ExcInternalError());
987 Assert(indices_ij.second < dim, ExcInternalError());
988 if (subtensor_is_rank_2_symmetric_tensor)
989 {
990 Assert(indices_ij.second >= indices_ij.first,
992 }
993 const unsigned int i = indices_ij.first;
994 const unsigned int j = indices_ij.second;
995
996 const double factor = internal::vector_component_factor<dim>(
997 r, subtensor_is_rank_2_symmetric_tensor);
998
999 for (unsigned int c = 0; c < n_cols; ++c)
1000 {
1001 const std::pair<unsigned int, unsigned int> indices_k =
1002 internal::indices_from_component<dim>(c, false);
1003 Assert(indices_k.first < dim, ExcInternalError());
1004 const unsigned int k = indices_k.first;
1005
1006 if (subtensor_is_rank_2_symmetric_tensor)
1007 out(r, c) = factor * t[i][j][k];
1008 else
1009 out(r, c) = t[i][j][k];
1010 }
1011 }
1012 }
1013 else if (SubTensor1::rank == 1 && SubTensor2::rank == 2)
1014 {
1015 const bool subtensor_is_rank_2_symmetric_tensor =
1016 internal::is_rank_2_symmetric_tensor<SubTensor2>::value;
1017
1018 for (unsigned int r = 0; r < n_rows; ++r)
1019 {
1020 const std::pair<unsigned int, unsigned int> indices_k =
1021 internal::indices_from_component<dim>(r, false);
1022 Assert(indices_k.first < dim, ExcInternalError());
1023 const unsigned int k = indices_k.first;
1024
1025 for (unsigned int c = 0; c < n_cols; ++c)
1026 {
1027 const std::pair<unsigned int, unsigned int> indices_ij =
1028 internal::indices_from_component<dim>(
1029 c, subtensor_is_rank_2_symmetric_tensor);
1030 Assert(indices_ij.first < dim, ExcInternalError());
1031 Assert(indices_ij.second < dim, ExcInternalError());
1032 if (subtensor_is_rank_2_symmetric_tensor)
1033 {
1034 Assert(indices_ij.second >= indices_ij.first,
1036 }
1037 const unsigned int i = indices_ij.first;
1038 const unsigned int j = indices_ij.second;
1039
1040 if (subtensor_is_rank_2_symmetric_tensor)
1041 {
1042 const double factor =
1043 internal::vector_component_factor<dim>(
1044 c, subtensor_is_rank_2_symmetric_tensor);
1045 out(r, c) = factor * t[k][i][j];
1046 }
1047 else
1048 out(r, c) = t[k][i][j];
1049 }
1050 }
1051 }
1052 else
1053 {
1055 }
1056
1057 return out;
1058 }
1059
1060
1061 template <int dim, typename Number>
1064 {
1068 const unsigned int n_rows = out.m();
1069 const unsigned int n_cols = out.n();
1070 for (unsigned int r = 0; r < n_rows; ++r)
1071 {
1072 const std::pair<unsigned int, unsigned int> indices_ij =
1073 internal::indices_from_component<dim>(r, false);
1074 Assert(indices_ij.first < dim, ExcInternalError());
1075 Assert(indices_ij.second < dim, ExcInternalError());
1076 const unsigned int i = indices_ij.first;
1077 const unsigned int j = indices_ij.second;
1078
1079 for (unsigned int c = 0; c < n_cols; ++c)
1080 {
1081 const std::pair<unsigned int, unsigned int> indices_kl =
1082 internal::indices_from_component<dim>(c, false);
1083 Assert(indices_kl.first < dim, ExcInternalError());
1084 Assert(indices_kl.second < dim, ExcInternalError());
1085 const unsigned int k = indices_kl.first;
1086 const unsigned int l = indices_kl.second;
1087
1088 out(r, c) = t[i][j][k][l];
1089 }
1090 }
1091 return out;
1092 }
1093
1094
1095 template <int dim, typename Number>
1098 {
1102 const unsigned int n_rows = out.m();
1103 const unsigned int n_cols = out.n();
1104 for (unsigned int r = 0; r < n_rows; ++r)
1105 {
1106 const std::pair<unsigned int, unsigned int> indices_ij =
1107 internal::indices_from_component<dim>(r, true);
1108 Assert(indices_ij.first < dim, ExcInternalError());
1109 Assert(indices_ij.second < dim, ExcInternalError());
1110 Assert(indices_ij.second >= indices_ij.first, ExcInternalError());
1111 const unsigned int i = indices_ij.first;
1112 const unsigned int j = indices_ij.second;
1113
1114 for (unsigned int c = 0; c < n_cols; ++c)
1115 {
1116 const std::pair<unsigned int, unsigned int> indices_kl =
1117 internal::indices_from_component<dim>(c, true);
1118 Assert(indices_kl.first < dim, ExcInternalError());
1119 Assert(indices_kl.second < dim, ExcInternalError());
1120 Assert(indices_kl.second >= indices_kl.first,
1122 const unsigned int k = indices_kl.first;
1123 const unsigned int l = indices_kl.second;
1124
1125 const double factor =
1126 internal::matrix_component_factor<dim>(r, c, true);
1127
1128 out(r, c) = factor * st[i][j][k][l];
1129 }
1130 }
1131 return out;
1132 }
1133
1134
1135 template <typename Number>
1136 void
1137 to_tensor(const Vector<Number> &vec, Number &s)
1138 {
1139 Assert(vec.size() == 1, ExcDimensionMismatch(vec.size(), 1));
1140 s = vec(0);
1141 }
1142
1143
1144 template <int dim, typename Number>
1145 void
1147 {
1148 return to_tensor(vec, s.operator Number &());
1149 }
1150
1151
1152 template <int dim, typename Number>
1153 void
1155 {
1158 const unsigned int n_rows = vec.size();
1159 for (unsigned int r = 0; r < n_rows; ++r)
1160 {
1161 const std::pair<unsigned int, unsigned int> indices =
1162 internal::indices_from_component<dim>(r, false);
1163 Assert(indices.first < dim, ExcInternalError());
1164 const unsigned int i = indices.first;
1165 v[i] = vec(r);
1166 }
1167 }
1168
1169
1170 template <int dim, typename Number>
1171 void
1173 {
1176 const unsigned int n_rows = vec.size();
1177 for (unsigned int r = 0; r < n_rows; ++r)
1178 {
1179 const std::pair<unsigned int, unsigned int> indices =
1180 internal::indices_from_component<dim>(r, false);
1181 Assert(indices.first < dim, ExcInternalError());
1182 Assert(indices.second < dim, ExcInternalError());
1183 const unsigned int i = indices.first;
1184 const unsigned int j = indices.second;
1185 t[i][j] = vec(r);
1186 }
1187 }
1188
1189
1190 template <int dim, typename Number>
1191 void
1193 {
1196 const unsigned int n_rows = vec.size();
1197 for (unsigned int r = 0; r < n_rows; ++r)
1198 {
1199 const std::pair<unsigned int, unsigned int> indices =
1200 internal::indices_from_component<dim>(r, true);
1201 Assert(indices.first < dim, ExcInternalError());
1202 Assert(indices.second < dim, ExcInternalError());
1203 Assert(indices.second >= indices.first, ExcInternalError());
1204 const unsigned int i = indices.first;
1205 const unsigned int j = indices.second;
1206
1207 const double inv_factor =
1208 1.0 / internal::vector_component_factor<dim>(r, true);
1209
1210 st[i][j] = inv_factor * vec(r);
1211 }
1212 }
1213
1214
1215 template <typename Number>
1216 void
1217 to_tensor(const FullMatrix<Number> &mtrx, Number &s)
1218 {
1219 Assert(mtrx.m() == 1, ExcDimensionMismatch(mtrx.m(), 1));
1220 Assert(mtrx.n() == 1, ExcDimensionMismatch(mtrx.n(), 1));
1221 Assert(mtrx.n_elements() == 1,
1222 ExcDimensionMismatch(mtrx.n_elements(), 1));
1223 s = mtrx(0, 0);
1224 }
1225
1226
1227 template <int dim, typename Number>
1228 void
1230 {
1231 return to_tensor(mtrx, s.operator Number &());
1232 }
1233
1234
1235 template <int dim, typename Number>
1236 void
1238 {
1239 Assert(mtrx.m() == dim, ExcDimensionMismatch(mtrx.m(), dim));
1240 Assert(mtrx.n() == 1, ExcDimensionMismatch(mtrx.n(), 1));
1241 Assert(mtrx.n_elements() == v.n_independent_components,
1242 ExcDimensionMismatch(mtrx.n_elements(),
1244
1245 const unsigned int n_rows = mtrx.m();
1246 const unsigned int n_cols = mtrx.n();
1247 for (unsigned int r = 0; r < n_rows; ++r)
1248 {
1249 const std::pair<unsigned int, unsigned int> indices =
1250 internal::indices_from_component<dim>(r, false);
1251 Assert(indices.first < dim, ExcInternalError());
1252 Assert(indices.second == 0, ExcInternalError());
1253 const unsigned int i = indices.first;
1254
1255 for (unsigned int c = 0; c < n_cols; ++c)
1256 {
1257 Assert(c < 1, ExcInternalError());
1258 v[i] = mtrx(r, c);
1259 }
1260 }
1261 }
1262
1263
1264 template <int dim, typename Number>
1265 void
1267 {
1268 Assert(mtrx.m() == dim, ExcDimensionMismatch(mtrx.m(), dim));
1269 Assert(mtrx.n() == dim, ExcDimensionMismatch(mtrx.n(), dim));
1270 Assert(mtrx.n_elements() == t.n_independent_components,
1271 ExcDimensionMismatch(mtrx.n_elements(),
1273
1274 const unsigned int n_rows = mtrx.m();
1275 const unsigned int n_cols = mtrx.n();
1276 for (unsigned int r = 0; r < n_rows; ++r)
1277 {
1278 const std::pair<unsigned int, unsigned int> indices_i =
1279 internal::indices_from_component<dim>(r, false);
1280 Assert(indices_i.first < dim, ExcInternalError());
1281 Assert(indices_i.second < dim, ExcInternalError());
1282 const unsigned int i = indices_i.first;
1283
1284 for (unsigned int c = 0; c < n_cols; ++c)
1285 {
1286 const std::pair<unsigned int, unsigned int> indices_j =
1287 internal::indices_from_component<dim>(c, false);
1288 Assert(indices_j.first < dim, ExcInternalError());
1289 Assert(indices_j.second < dim, ExcInternalError());
1290 const unsigned int j = indices_j.second;
1291
1292 t[i][j] = mtrx(r, c);
1293 }
1294 }
1295 }
1296
1297
1298 template <int dim, typename Number>
1299 void
1300 to_tensor(const FullMatrix<Number> &mtrx,
1302 {
1303 // Its impossible to fit the (dim^2 + dim)/2 entries into a square
1304 // matrix We therefore assume that its been converted to a standard
1305 // tensor format using to_matrix (SymmetricTensor<2,dim,Number>) at some
1306 // point...
1307 Assert(mtrx.m() == dim, ExcDimensionMismatch(mtrx.m(), dim));
1308 Assert(mtrx.n() == dim, ExcDimensionMismatch(mtrx.n(), dim));
1309 Assert((mtrx.n_elements() ==
1312 mtrx.n_elements(),
1314
1316 to_tensor(mtrx, tmp);
1317 st = symmetrize(tmp);
1318 Assert((Tensor<2, dim, Number>(st) - tmp).norm() < 1e-12,
1319 ExcMessage(
1320 "The entries stored inside the matrix were not symmetric"));
1321 }
1322
1323
1324 template <int dim, typename Number>
1325 void
1327 {
1329 (mtrx.m() ==
1331 (mtrx.m() ==
1334 mtrx.m(),
1339 (mtrx.n() ==
1341 (mtrx.n() ==
1344 mtrx.n(),
1348
1349 const unsigned int n_rows = mtrx.m();
1350 const unsigned int n_cols = mtrx.n();
1352 {
1353 Assert(
1355 (mtrx.m() ==
1358 mtrx.m(),
1361
1362 const bool subtensor_is_rank_2_symmetric_tensor =
1363 (mtrx.m() ==
1365
1366 for (unsigned int r = 0; r < n_rows; ++r)
1367 {
1368 const std::pair<unsigned int, unsigned int> indices_ij =
1369 internal::indices_from_component<dim>(
1370 r, subtensor_is_rank_2_symmetric_tensor);
1371 Assert(indices_ij.first < dim, ExcInternalError());
1372 Assert(indices_ij.second < dim, ExcInternalError());
1373 if (subtensor_is_rank_2_symmetric_tensor)
1374 {
1375 Assert(indices_ij.second >= indices_ij.first,
1377 }
1378 const unsigned int i = indices_ij.first;
1379 const unsigned int j = indices_ij.second;
1380
1381 const double inv_factor =
1382 1.0 / internal::vector_component_factor<dim>(
1383 r, subtensor_is_rank_2_symmetric_tensor);
1384
1385 for (unsigned int c = 0; c < n_cols; ++c)
1386 {
1387 const std::pair<unsigned int, unsigned int> indices_k =
1388 internal::indices_from_component<dim>(c, false);
1389 Assert(indices_k.first < dim, ExcInternalError());
1390 const unsigned int k = indices_k.first;
1391
1392 if (subtensor_is_rank_2_symmetric_tensor)
1393 {
1394 t[i][j][k] = inv_factor * mtrx(r, c);
1395 t[j][i][k] = t[i][j][k];
1396 }
1397 else
1398 t[i][j][k] = mtrx(r, c);
1399 }
1400 }
1401 }
1402 else
1403 {
1404 Assert(
1408 Assert(
1410 (mtrx.n() ==
1413 mtrx.n(),
1416
1417 const bool subtensor_is_rank_2_symmetric_tensor =
1418 (mtrx.n() ==
1420
1421 for (unsigned int r = 0; r < n_rows; ++r)
1422 {
1423 const std::pair<unsigned int, unsigned int> indices_k =
1424 internal::indices_from_component<dim>(r, false);
1425 Assert(indices_k.first < dim, ExcInternalError());
1426 const unsigned int k = indices_k.first;
1427
1428 for (unsigned int c = 0; c < n_cols; ++c)
1429 {
1430 const std::pair<unsigned int, unsigned int> indices_ij =
1431 internal::indices_from_component<dim>(
1432 c, subtensor_is_rank_2_symmetric_tensor);
1433 Assert(indices_ij.first < dim, ExcInternalError());
1434 Assert(indices_ij.second < dim, ExcInternalError());
1435 if (subtensor_is_rank_2_symmetric_tensor)
1436 {
1437 Assert(indices_ij.second >= indices_ij.first,
1439 }
1440 const unsigned int i = indices_ij.first;
1441 const unsigned int j = indices_ij.second;
1442
1443 if (subtensor_is_rank_2_symmetric_tensor)
1444 {
1445 const double inv_factor =
1446 1.0 / internal::vector_component_factor<dim>(
1447 c, subtensor_is_rank_2_symmetric_tensor);
1448 t[k][i][j] = inv_factor * mtrx(r, c);
1449 t[k][j][i] = t[k][i][j];
1450 }
1451 else
1452 t[k][i][j] = mtrx(r, c);
1453 }
1454 }
1455 }
1456 }
1457
1458
1459 template <int dim, typename Number>
1460 void
1462 {
1469 Assert(mtrx.n_elements() == t.n_independent_components,
1470 ExcDimensionMismatch(mtrx.n_elements(),
1472
1473 const unsigned int n_rows = mtrx.m();
1474 const unsigned int n_cols = mtrx.n();
1475 for (unsigned int r = 0; r < n_rows; ++r)
1476 {
1477 const std::pair<unsigned int, unsigned int> indices_ij =
1478 internal::indices_from_component<dim>(r, false);
1479 Assert(indices_ij.first < dim, ExcInternalError());
1480 Assert(indices_ij.second < dim, ExcInternalError());
1481 const unsigned int i = indices_ij.first;
1482 const unsigned int j = indices_ij.second;
1483
1484 for (unsigned int c = 0; c < n_cols; ++c)
1485 {
1486 const std::pair<unsigned int, unsigned int> indices_kl =
1487 internal::indices_from_component<dim>(c, false);
1488 Assert(indices_kl.first < dim, ExcInternalError());
1489 Assert(indices_kl.second < dim, ExcInternalError());
1490 const unsigned int k = indices_kl.first;
1491 const unsigned int l = indices_kl.second;
1492
1493 t[i][j][k][l] = mtrx(r, c);
1494 }
1495 }
1496 }
1497
1498
1499 template <int dim, typename Number>
1500 void
1501 to_tensor(const FullMatrix<Number> &mtrx,
1503 {
1504 Assert((mtrx.m() ==
1507 mtrx.m(),
1509 Assert((mtrx.n() ==
1512 mtrx.n(),
1514 Assert(mtrx.n_elements() == st.n_independent_components,
1515 ExcDimensionMismatch(mtrx.n_elements(),
1517
1518 const unsigned int n_rows = mtrx.m();
1519 const unsigned int n_cols = mtrx.n();
1520 for (unsigned int r = 0; r < n_rows; ++r)
1521 {
1522 const std::pair<unsigned int, unsigned int> indices_ij =
1523 internal::indices_from_component<dim>(r, false);
1524 Assert(indices_ij.first < dim, ExcInternalError());
1525 Assert(indices_ij.second < dim, ExcInternalError());
1526 const unsigned int i = indices_ij.first;
1527 const unsigned int j = indices_ij.second;
1528
1529 for (unsigned int c = 0; c < n_cols; ++c)
1530 {
1531 const std::pair<unsigned int, unsigned int> indices_kl =
1532 internal::indices_from_component<dim>(c, false);
1533 Assert(indices_kl.first < dim, ExcInternalError());
1534 Assert(indices_kl.second < dim, ExcInternalError());
1535 const unsigned int k = indices_kl.first;
1536 const unsigned int l = indices_kl.second;
1537
1538 const double inv_factor =
1539 1.0 / internal::matrix_component_factor<dim>(r, c, true);
1540
1541 st[i][j][k][l] = inv_factor * mtrx(r, c);
1542 }
1543 }
1544 }
1545
1546
1547 template <typename TensorType, typename Number>
1548 inline TensorType
1549 to_tensor(const Vector<Number> &vec)
1550 {
1551 TensorType out;
1552 to_tensor(vec, out);
1553 return out;
1554 }
1555
1556
1557 template <typename TensorType, typename Number>
1558 inline TensorType
1559 to_tensor(const FullMatrix<Number> &mtrx)
1560 {
1561 TensorType out;
1562 to_tensor(mtrx, out);
1563 return out;
1564 }
1565
1566 } // namespace Kelvin
1567 } // namespace Notation
1568} // namespace Physics
1569
1570
1571#endif // DOXYGEN
1572
1573
1575
1576#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:496
virtual size_type size() const override
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
static ::ExceptionBase & ExcNotationExcFullMatrixToTensorRowSize2(int arg1, int arg2, int arg3)
#define DeclException4(Exception4, type1, type2, type3, type4, outsequence)
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)
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:469
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)
*  *  *  RotationFunction< dim, Number >::RotationFunction Number(dim)
constexpr double SQRT2
Definition numbers.h:255
constexpr SymmetricTensor< 2, dim, Number > symmetrize(const Tensor< 2, dim, Number > &t)