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\}}\)
notation.h
Go to the documentation of this file.
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2017 - 2020 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_physics_notation_h
17 #define dealii_physics_notation_h
18 
19 #include <deal.II/base/config.h>
20 
22 #include <deal.II/base/numbers.h>
24 #include <deal.II/base/tensor.h>
25 
27 #include <deal.II/lac/vector.h>
28 
29 #include <type_traits>
30 
32 
33 
34 namespace Physics
35 {
36  namespace Notation
37  {
287  namespace Kelvin
288  {
293  int,
294  int,
295  int,
296  << "The number of rows in the input matrix is " << arg1
297  << ", but needs to be either " << arg2 << " or " << arg3
298  << ".");
299 
300 
305  int,
306  int,
307  int,
308  int,
309  << "The number of rows in the input matrix is " << arg1
310  << ", but needs to be either " << arg2 << "," << arg3
311  << ", or " << arg4 << ".");
312 
313 
318  int,
319  int,
320  int,
321  << "The number of columns in the input matrix is " << arg1
322  << ", but needs to be either " << arg2 << " or " << arg3
323  << ".");
324 
325 
330  int,
331  int,
332  int,
333  int,
334  << "The number of columns in the input matrix is " << arg1
335  << ", but needs to be either " << arg2 << "," << arg3
336  << ", or " << arg4 << ".");
337 
338 
343 
349  template <typename Number>
350  Vector<Number>
351  to_vector(const Number &s);
352 
353 
359  template <int dim, typename Number>
360  Vector<Number>
362 
363 
369  template <int dim, typename Number>
370  Vector<Number>
372 
373 
379  template <int dim, typename Number>
380  Vector<Number>
382 
383 
390  template <int dim, typename Number>
391  Vector<Number>
393 
394 
400  template <typename Number>
402  to_matrix(const Number &s);
403 
404 
410  template <int dim, typename Number>
413 
414 
420  template <int dim, typename Number>
423 
424 
430  template <int dim, typename Number>
433 
434 
444  template <int dim, typename Number>
447 
480  template <int dim,
481  typename SubTensor1 = Tensor<2, dim>,
482  typename SubTensor2 = Tensor<1, dim>,
483  typename Number>
486 
487 
494  template <int dim, typename Number>
497 
498 
506  template <int dim, typename Number>
509 
511 
516 
520  template <typename Number>
521  void
522  to_tensor(const Vector<Number> &vec, Number &s);
523 
524 
528  template <int dim, typename Number>
529  void
530  to_tensor(const Vector<Number> &vec, Tensor<0, dim, Number> &s);
531 
532 
536  template <int dim, typename Number>
537  void
538  to_tensor(const Vector<Number> &vec, Tensor<1, dim, Number> &v);
539 
540 
544  template <int dim, typename Number>
545  void
546  to_tensor(const Vector<Number> &vec, Tensor<2, dim, Number> &t);
547 
548 
552  template <int dim, typename Number>
553  void
554  to_tensor(const Vector<Number> &vec, SymmetricTensor<2, dim, Number> &st);
555 
556 
560  template <typename Number>
561  void
562  to_tensor(const FullMatrix<Number> &mtrx, Number &s);
563 
564 
568  template <int dim, typename Number>
569  void
571 
572 
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
594  to_tensor(const FullMatrix<Number> & mtrx,
596 
597 
607  template <int dim, typename Number>
608  void
610 
611 
615  template <int dim, typename Number>
616  void
618 
619 
623  template <int dim, typename Number>
624  void
625  to_tensor(const FullMatrix<Number> & mtrx,
627 
628 
633  template <typename TensorType, typename Number>
634  TensorType
635  to_tensor(const Vector<Number> &vec);
636 
637 
642  template <typename TensorType, typename Number>
643  TensorType
644  to_tensor(const FullMatrix<Number> &vec);
646 
647  } // namespace Kelvin
648 
649  } // namespace Notation
650 } // namespace Physics
651 
652 
653 #ifndef DOXYGEN
654 
655 
656 // ------------------------- inline functions ------------------------
657 
658 
659 namespace Physics
660 {
661  namespace Notation
662  {
663  namespace Kelvin
664  {
665  namespace internal
666  {
674  template <int dim>
675  std::pair<unsigned int, unsigned int>
676  indices_from_component(const unsigned int component_n,
677  const bool symmetric);
678 
679 
680  template <int dim>
681  std::pair<unsigned int, unsigned int>
682  indices_from_component(const unsigned int component_n, const bool)
683  {
684  AssertThrow(false, ExcNotImplemented());
685  return std::pair<unsigned int, unsigned int>();
686  }
687 
688 
689  template <>
690  inline std::pair<unsigned int, unsigned int>
691  indices_from_component<1>(const unsigned int component_n, const bool)
692  {
693  AssertIndexRange(component_n, 1);
694 
695  return std::make_pair(0u, 0u);
696  }
697 
698 
699  template <>
700  inline std::pair<unsigned int, unsigned int>
701  indices_from_component<2>(const unsigned int component_n,
702  const bool symmetric)
703  {
704  if (symmetric == true)
705  {
706  Assert(
708  ExcIndexRange(component_n,
709  0,
711  }
712  else
713  {
715  ExcIndexRange(component_n,
716  0,
718  }
719 
720  static const unsigned int indices[4][2] = {{0, 0},
721  {1, 1},
722  {0, 1},
723  {1, 0}};
724  return std::make_pair(indices[component_n][0],
725  indices[component_n][1]);
726  }
727 
728 
729  template <>
730  inline std::pair<unsigned int, unsigned int>
731  indices_from_component<3>(const unsigned int component_n,
732  const bool symmetric)
733  {
734  if (symmetric == true)
735  {
736  Assert(
738  ExcIndexRange(component_n,
739  0,
741  }
742  else
743  {
745  ExcIndexRange(component_n,
746  0,
748  }
749 
750  static const unsigned int indices[9][2] = {{0, 0},
751  {1, 1},
752  {2, 2},
753  {1, 2},
754  {0, 2},
755  {0, 1},
756  {1, 0},
757  {2, 0},
758  {2, 1}};
759  return std::make_pair(indices[component_n][0],
760  indices[component_n][1]);
761  }
762 
763 
768  template <int dim>
769  double
770  vector_component_factor(const unsigned int component_i,
771  const bool symmetric)
772  {
773  if (symmetric == false)
774  return 1.0;
775 
776  if (component_i < dim)
777  return 1.0;
778  else
779  return numbers::SQRT2;
780  }
781 
782 
787  template <int dim>
788  double
789  matrix_component_factor(const unsigned int component_i,
790  const unsigned int component_j,
791  const bool symmetric)
792  {
793  if (symmetric == false)
794  return 1.0;
795 
796  // This case check returns equivalent of this result:
797  // internal::vector_component_factor<dim>(component_i,symmetric)*internal::vector_component_factor<dim>(component_j,symmetric);
798  if (component_i < dim && component_j < dim)
799  return 1.0;
800  else if (component_i >= dim && component_j >= dim)
801  return 2.0;
802  else // ((component_i >= dim && component_j < dim) || (component_i <
803  // dim && component_j >= dim))
804  return numbers::SQRT2;
805  }
806 
807  } // namespace internal
808 
809 
810  template <typename Number>
811  Vector<Number>
812  to_vector(const Number &s)
813  {
814  Vector<Number> out(1);
815  const unsigned int n_rows = out.size();
816  for (unsigned int r = 0; r < n_rows; ++r)
817  out(r) = s;
818  return out;
819  }
820 
821 
822  template <int dim, typename Number>
823  Vector<Number>
825  {
826  return to_vector(s.operator const Number &());
827  }
828 
829 
830  template <int dim, typename Number>
831  Vector<Number>
833  {
834  Vector<Number> out(v.n_independent_components);
835  const unsigned int n_rows = out.size();
836  for (unsigned int r = 0; r < n_rows; ++r)
837  {
838  const std::pair<unsigned int, unsigned int> indices =
839  internal::indices_from_component<dim>(r, false);
840  Assert(indices.first < dim, ExcInternalError());
841  const unsigned int i = indices.first;
842  out(r) = v[i];
843  }
844  return out;
845  }
846 
847 
848  template <int dim, typename Number>
849  Vector<Number>
851  {
852  Vector<Number> out(t.n_independent_components);
853  const unsigned int n_rows = out.size();
854  for (unsigned int r = 0; r < n_rows; ++r)
855  {
856  const std::pair<unsigned int, unsigned int> indices =
857  internal::indices_from_component<dim>(r, false);
858  Assert(indices.first < dim, ExcInternalError());
859  Assert(indices.second < dim, ExcInternalError());
860  const unsigned int i = indices.first;
861  const unsigned int j = indices.second;
862  out(r) = t[i][j];
863  }
864  return out;
865  }
866 
867 
868  template <int dim, typename Number>
869  Vector<Number>
871  {
872  Vector<Number> out(st.n_independent_components);
873  const unsigned int n_rows = out.size();
874  for (unsigned int r = 0; r < n_rows; ++r)
875  {
876  const std::pair<unsigned int, unsigned int> indices =
877  internal::indices_from_component<dim>(r, true);
878  Assert(indices.first < dim, ExcInternalError());
879  Assert(indices.second < dim, ExcInternalError());
880  Assert(indices.second >= indices.first, ExcInternalError());
881  const unsigned int i = indices.first;
882  const unsigned int j = indices.second;
883 
884  const double factor =
885  internal::vector_component_factor<dim>(r, true);
886 
887  out(r) = factor * st[i][j];
888  }
889  return out;
890  }
891 
892 
893  template <typename Number>
895  to_matrix(const Number &s)
896  {
897  FullMatrix<Number> out(1, 1);
898  out(0, 0) = s;
899  return out;
900  }
901 
902 
903  template <int dim, typename Number>
906  {
907  return to_matrix(s.operator const Number &());
908  }
909 
910 
911  template <int dim, typename Number>
914  {
916  const unsigned int n_rows = out.m();
917  const unsigned int n_cols = out.n();
918  for (unsigned int r = 0; r < n_rows; ++r)
919  {
920  const std::pair<unsigned int, unsigned int> indices =
921  internal::indices_from_component<dim>(r, false);
922  Assert(indices.first < dim, ExcInternalError());
923  const unsigned int i = indices.first;
924 
925  for (unsigned int c = 0; c < n_cols; ++c)
926  {
927  Assert(c < 1, ExcInternalError());
928  out(r, c) = v[i];
929  }
930  }
931  return out;
932  }
933 
934 
935  template <int dim, typename Number>
938  {
939  FullMatrix<Number> out(dim, dim);
940  const unsigned int n_rows = out.m();
941  const unsigned int n_cols = out.n();
942  for (unsigned int r = 0; r < n_rows; ++r)
943  {
944  const std::pair<unsigned int, unsigned int> indices_i =
945  internal::indices_from_component<dim>(r, false);
946  Assert(indices_i.first < dim, ExcInternalError());
947  Assert(indices_i.second < dim, ExcInternalError());
948  const unsigned int i = indices_i.first;
949 
950  for (unsigned int c = 0; c < n_cols; ++c)
951  {
952  const std::pair<unsigned int, unsigned int> indices_j =
953  internal::indices_from_component<dim>(c, false);
954  Assert(indices_j.first < dim, ExcInternalError());
955  Assert(indices_j.second < dim, ExcInternalError());
956  const unsigned int j = indices_j.second;
957 
958  out(r, c) = t[i][j];
959  }
960  }
961  return out;
962  }
963 
964 
965  template <int dim, typename Number>
968  {
969  return to_matrix(Tensor<2, dim, Number>(st));
970  }
971 
972 
973  namespace internal
974  {
975  template <typename TensorType>
976  struct is_rank_2_symmetric_tensor : std::false_type
977  {};
978 
979  template <int dim, typename Number>
980  struct is_rank_2_symmetric_tensor<SymmetricTensor<2, dim, Number>>
981  : std::true_type
982  {};
983  } // namespace internal
984 
985 
986  template <int dim,
987  typename SubTensor1,
988  typename SubTensor2,
989  typename Number>
992  {
993  static_assert(
994  (SubTensor1::dimension == dim && SubTensor2::dimension == dim),
995  "Sub-tensor spatial dimension is different from those of the input tensor.");
996 
997  static_assert(
998  (SubTensor1::rank == 2 && SubTensor2::rank == 1) ||
999  (SubTensor1::rank == 1 && SubTensor2::rank == 2),
1000  "Cannot build a rank 3 tensor from the given combination of sub-tensors.");
1001 
1002  FullMatrix<Number> out(SubTensor1::n_independent_components,
1003  SubTensor2::n_independent_components);
1004  const unsigned int n_rows = out.m();
1005  const unsigned int n_cols = out.n();
1006 
1007  if (SubTensor1::rank == 2 && SubTensor2::rank == 1)
1008  {
1009  const bool subtensor_is_rank_2_symmetric_tensor =
1011 
1012  for (unsigned int r = 0; r < n_rows; ++r)
1013  {
1014  const std::pair<unsigned int, unsigned int> indices_ij =
1015  internal::indices_from_component<dim>(
1016  r, subtensor_is_rank_2_symmetric_tensor);
1017  Assert(indices_ij.first < dim, ExcInternalError());
1018  Assert(indices_ij.second < dim, ExcInternalError());
1019  if (subtensor_is_rank_2_symmetric_tensor)
1020  {
1021  Assert(indices_ij.second >= indices_ij.first,
1022  ExcInternalError());
1023  }
1024  const unsigned int i = indices_ij.first;
1025  const unsigned int j = indices_ij.second;
1026 
1027  const double factor = internal::vector_component_factor<dim>(
1028  r, subtensor_is_rank_2_symmetric_tensor);
1029 
1030  for (unsigned int c = 0; c < n_cols; ++c)
1031  {
1032  const std::pair<unsigned int, unsigned int> indices_k =
1033  internal::indices_from_component<dim>(c, false);
1034  Assert(indices_k.first < dim, ExcInternalError());
1035  const unsigned int k = indices_k.first;
1036 
1037  if (subtensor_is_rank_2_symmetric_tensor)
1038  out(r, c) = factor * t[i][j][k];
1039  else
1040  out(r, c) = t[i][j][k];
1041  }
1042  }
1043  }
1044  else if (SubTensor1::rank == 1 && SubTensor2::rank == 2)
1045  {
1046  const bool subtensor_is_rank_2_symmetric_tensor =
1048 
1049  for (unsigned int r = 0; r < n_rows; ++r)
1050  {
1051  const std::pair<unsigned int, unsigned int> indices_k =
1052  internal::indices_from_component<dim>(r, false);
1053  Assert(indices_k.first < dim, ExcInternalError());
1054  const unsigned int k = indices_k.first;
1055 
1056  for (unsigned int c = 0; c < n_cols; ++c)
1057  {
1058  const std::pair<unsigned int, unsigned int> indices_ij =
1059  internal::indices_from_component<dim>(
1060  c, subtensor_is_rank_2_symmetric_tensor);
1061  Assert(indices_ij.first < dim, ExcInternalError());
1062  Assert(indices_ij.second < dim, ExcInternalError());
1063  if (subtensor_is_rank_2_symmetric_tensor)
1064  {
1065  Assert(indices_ij.second >= indices_ij.first,
1066  ExcInternalError());
1067  }
1068  const unsigned int i = indices_ij.first;
1069  const unsigned int j = indices_ij.second;
1070 
1071  if (subtensor_is_rank_2_symmetric_tensor)
1072  {
1073  const double factor =
1074  internal::vector_component_factor<dim>(
1075  c, subtensor_is_rank_2_symmetric_tensor);
1076  out(r, c) = factor * t[k][i][j];
1077  }
1078  else
1079  out(r, c) = t[k][i][j];
1080  }
1081  }
1082  }
1083  else
1084  {
1085  AssertThrow(false, ExcNotImplemented());
1086  }
1087 
1088  return out;
1089  }
1090 
1091 
1092  template <int dim, typename Number>
1095  {
1096  FullMatrix<Number> out(
1099  const unsigned int n_rows = out.m();
1100  const unsigned int n_cols = out.n();
1101  for (unsigned int r = 0; r < n_rows; ++r)
1102  {
1103  const std::pair<unsigned int, unsigned int> indices_ij =
1104  internal::indices_from_component<dim>(r, false);
1105  Assert(indices_ij.first < dim, ExcInternalError());
1106  Assert(indices_ij.second < dim, ExcInternalError());
1107  const unsigned int i = indices_ij.first;
1108  const unsigned int j = indices_ij.second;
1109 
1110  for (unsigned int c = 0; c < n_cols; ++c)
1111  {
1112  const std::pair<unsigned int, unsigned int> indices_kl =
1113  internal::indices_from_component<dim>(c, false);
1114  Assert(indices_kl.first < dim, ExcInternalError());
1115  Assert(indices_kl.second < dim, ExcInternalError());
1116  const unsigned int k = indices_kl.first;
1117  const unsigned int l = indices_kl.second;
1118 
1119  out(r, c) = t[i][j][k][l];
1120  }
1121  }
1122  return out;
1123  }
1124 
1125 
1126  template <int dim, typename Number>
1129  {
1130  FullMatrix<Number> out(
1133  const unsigned int n_rows = out.m();
1134  const unsigned int n_cols = out.n();
1135  for (unsigned int r = 0; r < n_rows; ++r)
1136  {
1137  const std::pair<unsigned int, unsigned int> indices_ij =
1138  internal::indices_from_component<dim>(r, true);
1139  Assert(indices_ij.first < dim, ExcInternalError());
1140  Assert(indices_ij.second < dim, ExcInternalError());
1141  Assert(indices_ij.second >= indices_ij.first, ExcInternalError());
1142  const unsigned int i = indices_ij.first;
1143  const unsigned int j = indices_ij.second;
1144 
1145  for (unsigned int c = 0; c < n_cols; ++c)
1146  {
1147  const std::pair<unsigned int, unsigned int> indices_kl =
1148  internal::indices_from_component<dim>(c, true);
1149  Assert(indices_kl.first < dim, ExcInternalError());
1150  Assert(indices_kl.second < dim, ExcInternalError());
1151  Assert(indices_kl.second >= indices_kl.first,
1152  ExcInternalError());
1153  const unsigned int k = indices_kl.first;
1154  const unsigned int l = indices_kl.second;
1155 
1156  const double factor =
1157  internal::matrix_component_factor<dim>(r, c, true);
1158 
1159  out(r, c) = factor * st[i][j][k][l];
1160  }
1161  }
1162  return out;
1163  }
1164 
1165 
1166  template <typename Number>
1167  void
1168  to_tensor(const Vector<Number> &vec, Number &s)
1169  {
1170  Assert(vec.size() == 1, ExcDimensionMismatch(vec.size(), 1));
1171  s = vec(0);
1172  }
1173 
1174 
1175  template <int dim, typename Number>
1176  void
1177  to_tensor(const Vector<Number> &vec, Tensor<0, dim, Number> &s)
1178  {
1179  return to_tensor(vec, s.operator Number &());
1180  }
1181 
1182 
1183  template <int dim, typename Number>
1184  void
1185  to_tensor(const Vector<Number> &vec, Tensor<1, dim, Number> &v)
1186  {
1187  Assert(vec.size() == v.n_independent_components,
1189  const unsigned int n_rows = vec.size();
1190  for (unsigned int r = 0; r < n_rows; ++r)
1191  {
1192  const std::pair<unsigned int, unsigned int> indices =
1193  internal::indices_from_component<dim>(r, false);
1194  Assert(indices.first < dim, ExcInternalError());
1195  const unsigned int i = indices.first;
1196  v[i] = vec(r);
1197  }
1198  }
1199 
1200 
1201  template <int dim, typename Number>
1202  void
1203  to_tensor(const Vector<Number> &vec, Tensor<2, dim, Number> &t)
1204  {
1205  Assert(vec.size() == t.n_independent_components,
1207  const unsigned int n_rows = vec.size();
1208  for (unsigned int r = 0; r < n_rows; ++r)
1209  {
1210  const std::pair<unsigned int, unsigned int> indices =
1211  internal::indices_from_component<dim>(r, false);
1212  Assert(indices.first < dim, ExcInternalError());
1213  Assert(indices.second < dim, ExcInternalError());
1214  const unsigned int i = indices.first;
1215  const unsigned int j = indices.second;
1216  t[i][j] = vec(r);
1217  }
1218  }
1219 
1220 
1221  template <int dim, typename Number>
1222  void
1223  to_tensor(const Vector<Number> &vec, SymmetricTensor<2, dim, Number> &st)
1224  {
1225  Assert(vec.size() == st.n_independent_components,
1227  const unsigned int n_rows = vec.size();
1228  for (unsigned int r = 0; r < n_rows; ++r)
1229  {
1230  const std::pair<unsigned int, unsigned int> indices =
1231  internal::indices_from_component<dim>(r, true);
1232  Assert(indices.first < dim, ExcInternalError());
1233  Assert(indices.second < dim, ExcInternalError());
1234  Assert(indices.second >= indices.first, ExcInternalError());
1235  const unsigned int i = indices.first;
1236  const unsigned int j = indices.second;
1237 
1238  const double inv_factor =
1239  1.0 / internal::vector_component_factor<dim>(r, true);
1240 
1241  st[i][j] = inv_factor * vec(r);
1242  }
1243  }
1244 
1245 
1246  template <typename Number>
1247  void
1248  to_tensor(const FullMatrix<Number> &mtrx, Number &s)
1249  {
1250  Assert(mtrx.m() == 1, ExcDimensionMismatch(mtrx.m(), 1));
1251  Assert(mtrx.n() == 1, ExcDimensionMismatch(mtrx.n(), 1));
1252  Assert(mtrx.n_elements() == 1,
1253  ExcDimensionMismatch(mtrx.n_elements(), 1));
1254  s = mtrx(0, 0);
1255  }
1256 
1257 
1258  template <int dim, typename Number>
1259  void
1261  {
1262  return to_tensor(mtrx, s.operator Number &());
1263  }
1264 
1265 
1266  template <int dim, typename Number>
1267  void
1269  {
1270  Assert(mtrx.m() == dim, ExcDimensionMismatch(mtrx.m(), dim));
1271  Assert(mtrx.n() == 1, ExcDimensionMismatch(mtrx.n(), 1));
1275 
1276  const unsigned int n_rows = mtrx.m();
1277  const unsigned int n_cols = mtrx.n();
1278  for (unsigned int r = 0; r < n_rows; ++r)
1279  {
1280  const std::pair<unsigned int, unsigned int> indices =
1281  internal::indices_from_component<dim>(r, false);
1282  Assert(indices.first < dim, ExcInternalError());
1283  Assert(indices.second == 0, ExcInternalError());
1284  const unsigned int i = indices.first;
1285 
1286  for (unsigned int c = 0; c < n_cols; ++c)
1287  {
1288  Assert(c < 1, ExcInternalError());
1289  v[i] = mtrx(r, c);
1290  }
1291  }
1292  }
1293 
1294 
1295  template <int dim, typename Number>
1296  void
1298  {
1299  Assert(mtrx.m() == dim, ExcDimensionMismatch(mtrx.m(), dim));
1300  Assert(mtrx.n() == dim, ExcDimensionMismatch(mtrx.n(), dim));
1304 
1305  const unsigned int n_rows = mtrx.m();
1306  const unsigned int n_cols = mtrx.n();
1307  for (unsigned int r = 0; r < n_rows; ++r)
1308  {
1309  const std::pair<unsigned int, unsigned int> indices_i =
1310  internal::indices_from_component<dim>(r, false);
1311  Assert(indices_i.first < dim, ExcInternalError());
1312  Assert(indices_i.second < dim, ExcInternalError());
1313  const unsigned int i = indices_i.first;
1314 
1315  for (unsigned int c = 0; c < n_cols; ++c)
1316  {
1317  const std::pair<unsigned int, unsigned int> indices_j =
1318  internal::indices_from_component<dim>(c, false);
1319  Assert(indices_j.first < dim, ExcInternalError());
1320  Assert(indices_j.second < dim, ExcInternalError());
1321  const unsigned int j = indices_j.second;
1322 
1323  t[i][j] = mtrx(r, c);
1324  }
1325  }
1326  }
1327 
1328 
1329  template <int dim, typename Number>
1330  void
1331  to_tensor(const FullMatrix<Number> & mtrx,
1333  {
1334  // Its impossible to fit the (dim^2 + dim)/2 entries into a square
1335  // matrix We therefore assume that its been converted to a standard
1336  // tensor format using to_matrix (SymmetricTensor<2,dim,Number>) at some
1337  // point...
1338  Assert(mtrx.m() == dim, ExcDimensionMismatch(mtrx.m(), dim));
1339  Assert(mtrx.n() == dim, ExcDimensionMismatch(mtrx.n(), dim));
1340  Assert((mtrx.n_elements() ==
1343  mtrx.n_elements(),
1345 
1347  to_tensor(mtrx, tmp);
1348  st = symmetrize(tmp);
1349  Assert((Tensor<2, dim, Number>(st) - tmp).norm() < 1e-12,
1350  ExcMessage(
1351  "The entries stored inside the matrix were not symmetric"));
1352  }
1353 
1354 
1355  template <int dim, typename Number>
1356  void
1358  {
1360  (mtrx.m() ==
1362  (mtrx.m() ==
1365  mtrx.m(),
1370  (mtrx.n() ==
1372  (mtrx.n() ==
1375  mtrx.n(),
1379 
1380  const unsigned int n_rows = mtrx.m();
1381  const unsigned int n_cols = mtrx.n();
1383  {
1384  Assert(
1386  (mtrx.m() ==
1389  mtrx.m(),
1392 
1393  const bool subtensor_is_rank_2_symmetric_tensor =
1394  (mtrx.m() ==
1396 
1397  for (unsigned int r = 0; r < n_rows; ++r)
1398  {
1399  const std::pair<unsigned int, unsigned int> indices_ij =
1400  internal::indices_from_component<dim>(
1401  r, subtensor_is_rank_2_symmetric_tensor);
1402  Assert(indices_ij.first < dim, ExcInternalError());
1403  Assert(indices_ij.second < dim, ExcInternalError());
1404  if (subtensor_is_rank_2_symmetric_tensor)
1405  {
1406  Assert(indices_ij.second >= indices_ij.first,
1407  ExcInternalError());
1408  }
1409  const unsigned int i = indices_ij.first;
1410  const unsigned int j = indices_ij.second;
1411 
1412  const double inv_factor =
1413  1.0 / internal::vector_component_factor<dim>(
1414  r, subtensor_is_rank_2_symmetric_tensor);
1415 
1416  for (unsigned int c = 0; c < n_cols; ++c)
1417  {
1418  const std::pair<unsigned int, unsigned int> indices_k =
1419  internal::indices_from_component<dim>(c, false);
1420  Assert(indices_k.first < dim, ExcInternalError());
1421  const unsigned int k = indices_k.first;
1422 
1423  if (subtensor_is_rank_2_symmetric_tensor)
1424  {
1425  t[i][j][k] = inv_factor * mtrx(r, c);
1426  t[j][i][k] = t[i][j][k];
1427  }
1428  else
1429  t[i][j][k] = mtrx(r, c);
1430  }
1431  }
1432  }
1433  else
1434  {
1435  Assert(
1439  Assert(
1441  (mtrx.n() ==
1444  mtrx.n(),
1447 
1448  const bool subtensor_is_rank_2_symmetric_tensor =
1449  (mtrx.n() ==
1451 
1452  for (unsigned int r = 0; r < n_rows; ++r)
1453  {
1454  const std::pair<unsigned int, unsigned int> indices_k =
1455  internal::indices_from_component<dim>(r, false);
1456  Assert(indices_k.first < dim, ExcInternalError());
1457  const unsigned int k = indices_k.first;
1458 
1459  for (unsigned int c = 0; c < n_cols; ++c)
1460  {
1461  const std::pair<unsigned int, unsigned int> indices_ij =
1462  internal::indices_from_component<dim>(
1463  c, subtensor_is_rank_2_symmetric_tensor);
1464  Assert(indices_ij.first < dim, ExcInternalError());
1465  Assert(indices_ij.second < dim, ExcInternalError());
1466  if (subtensor_is_rank_2_symmetric_tensor)
1467  {
1468  Assert(indices_ij.second >= indices_ij.first,
1469  ExcInternalError());
1470  }
1471  const unsigned int i = indices_ij.first;
1472  const unsigned int j = indices_ij.second;
1473 
1474  if (subtensor_is_rank_2_symmetric_tensor)
1475  {
1476  const double inv_factor =
1477  1.0 / internal::vector_component_factor<dim>(
1478  c, subtensor_is_rank_2_symmetric_tensor);
1479  t[k][i][j] = inv_factor * mtrx(r, c);
1480  t[k][j][i] = t[k][i][j];
1481  }
1482  else
1483  t[k][i][j] = mtrx(r, c);
1484  }
1485  }
1486  }
1487  }
1488 
1489 
1490  template <int dim, typename Number>
1491  void
1493  {
1503 
1504  const unsigned int n_rows = mtrx.m();
1505  const unsigned int n_cols = mtrx.n();
1506  for (unsigned int r = 0; r < n_rows; ++r)
1507  {
1508  const std::pair<unsigned int, unsigned int> indices_ij =
1509  internal::indices_from_component<dim>(r, false);
1510  Assert(indices_ij.first < dim, ExcInternalError());
1511  Assert(indices_ij.second < dim, ExcInternalError());
1512  const unsigned int i = indices_ij.first;
1513  const unsigned int j = indices_ij.second;
1514 
1515  for (unsigned int c = 0; c < n_cols; ++c)
1516  {
1517  const std::pair<unsigned int, unsigned int> indices_kl =
1518  internal::indices_from_component<dim>(c, false);
1519  Assert(indices_kl.first < dim, ExcInternalError());
1520  Assert(indices_kl.second < dim, ExcInternalError());
1521  const unsigned int k = indices_kl.first;
1522  const unsigned int l = indices_kl.second;
1523 
1524  t[i][j][k][l] = mtrx(r, c);
1525  }
1526  }
1527  }
1528 
1529 
1530  template <int dim, typename Number>
1531  void
1532  to_tensor(const FullMatrix<Number> & mtrx,
1534  {
1535  Assert((mtrx.m() ==
1538  mtrx.m(),
1540  Assert((mtrx.n() ==
1543  mtrx.n(),
1548 
1549  const unsigned int n_rows = mtrx.m();
1550  const unsigned int n_cols = mtrx.n();
1551  for (unsigned int r = 0; r < n_rows; ++r)
1552  {
1553  const std::pair<unsigned int, unsigned int> indices_ij =
1554  internal::indices_from_component<dim>(r, false);
1555  Assert(indices_ij.first < dim, ExcInternalError());
1556  Assert(indices_ij.second < dim, ExcInternalError());
1557  const unsigned int i = indices_ij.first;
1558  const unsigned int j = indices_ij.second;
1559 
1560  for (unsigned int c = 0; c < n_cols; ++c)
1561  {
1562  const std::pair<unsigned int, unsigned int> indices_kl =
1563  internal::indices_from_component<dim>(c, false);
1564  Assert(indices_kl.first < dim, ExcInternalError());
1565  Assert(indices_kl.second < dim, ExcInternalError());
1566  const unsigned int k = indices_kl.first;
1567  const unsigned int l = indices_kl.second;
1568 
1569  const double inv_factor =
1570  1.0 / internal::matrix_component_factor<dim>(r, c, true);
1571 
1572  st[i][j][k][l] = inv_factor * mtrx(r, c);
1573  }
1574  }
1575  }
1576 
1577 
1578  template <typename TensorType, typename Number>
1579  inline TensorType
1580  to_tensor(const Vector<Number> &vec)
1581  {
1582  TensorType out;
1583  to_tensor(vec, out);
1584  return out;
1585  }
1586 
1587 
1588  template <typename TensorType, typename Number>
1589  inline TensorType
1590  to_tensor(const FullMatrix<Number> &mtrx)
1591  {
1592  TensorType out;
1593  to_tensor(mtrx, out);
1594  return out;
1595  }
1596 
1597  } // namespace Kelvin
1598  } // namespace Notation
1599 } // namespace Physics
1600 
1601 
1602 #endif // DOXYGEN
1603 
1604 
1606 
1607 #endif
Physics
Definition: physics.h:28
Physics::Notation::Kelvin::to_matrix
FullMatrix< Number > to_matrix(const Number &s)
Physics::Notation::Kelvin::ExcNotationExcFullMatrixToTensorColSize3
static ::ExceptionBase & ExcNotationExcFullMatrixToTensorColSize3(int arg1, int arg2, int arg3, int arg4)
Tensor::n_independent_components
static constexpr unsigned int n_independent_components
Definition: tensor.h:476
SymmetricTensor
Definition: symmetric_tensor.h:611
StandardExceptions::ExcNotImplemented
static ::ExceptionBase & ExcNotImplemented()
Physics::Notation::Kelvin::ExcNotationExcFullMatrixToTensorRowSize3
static ::ExceptionBase & ExcNotationExcFullMatrixToTensorRowSize3(int arg1, int arg2, int arg3, int arg4)
FullMatrix::m
size_type m() const
AssertIndexRange
#define AssertIndexRange(index, range)
Definition: exceptions.h:1649
Physics::Elasticity::Kinematics::e
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
FullMatrix::n
size_type n() const
Physics::Notation::Kelvin::to_tensor
void to_tensor(const Vector< Number > &vec, Number &s)
tensor.h
LAPACKSupport::symmetric
@ symmetric
Matrix is symmetric.
Definition: lapack_support.h:115
StandardExceptions::ExcIndexRange
static ::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
StandardExceptions::ExcMessage
static ::ExceptionBase & ExcMessage(std::string arg1)
Tensor
Definition: tensor.h:450
LocalIntegrators::Divergence::norm
double norm(const FEValuesBase< dim > &fe, const ArrayView< const std::vector< Tensor< 1, dim >>> &Du)
Definition: divergence.h:548
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)
DeclException3
#define DeclException3(Exception3, type1, type2, type3, outsequence)
Definition: exceptions.h:564
Tensor< 0, dim, Number >
Definition: tensor.h:93
TableBase< N, number >::n_elements
size_type n_elements() const
exceptions.h
DeclException4
#define DeclException4(Exception4, type1, type2, type3, type4, outsequence)
Definition: exceptions.h:587
value
static const bool value
Definition: dof_tools_constraints.cc:433
StandardExceptions::ExcInternalError
static ::ExceptionBase & ExcInternalError()
numbers::SQRT2
static constexpr double SQRT2
Definition: numbers.h:252
Assert
#define Assert(cond, exc)
Definition: exceptions.h:1419
symmetric_tensor.h
vector.h
Physics::Notation::Kelvin::to_vector
Vector< Number > to_vector(const Number &s)
StandardExceptions::ExcDimensionMismatch
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
config.h
FullMatrix
Definition: full_matrix.h:71
Physics::Notation::Kelvin::ExcNotationExcFullMatrixToTensorColSize2
static ::ExceptionBase & ExcNotationExcFullMatrixToTensorColSize2(int arg1, int arg2, int arg3)
Physics::Notation::Kelvin::ExcNotationExcFullMatrixToTensorRowSize2
static ::ExceptionBase & ExcNotationExcFullMatrixToTensorRowSize2(int arg1, int arg2, int arg3)
internal
Definition: aligned_vector.h:369
DEAL_II_NAMESPACE_CLOSE
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:359
AssertThrow
#define AssertThrow(cond, exc)
Definition: exceptions.h:1531
numbers.h
SymmetricTensor::n_independent_components
static constexpr unsigned int n_independent_components
Definition: symmetric_tensor.h:636
full_matrix.h
symmetrize
constexpr SymmetricTensor< 2, dim, Number > symmetrize(const Tensor< 2, dim, Number > &t)
Definition: symmetric_tensor.h:3547