13#ifndef dealii_physics_notation_h
14#define dealii_physics_notation_h
265 <<
"The number of rows in the input matrix is " << arg1
266 <<
", but needs to be either " << arg2 <<
" or " << arg3
278 <<
"The number of rows in the input matrix is " << arg1
279 <<
", but needs to be either " << arg2 <<
',' << arg3
280 <<
", or " << arg4 <<
'.');
290 <<
"The number of columns in the input matrix is " << arg1
291 <<
", but needs to be either " << arg2 <<
" or " << arg3
303 <<
"The number of columns in the input matrix is " << arg1
304 <<
", but needs to be either " << arg2 <<
',' << arg3
305 <<
", or " << arg4 <<
'.');
318 template <
typename Number>
328 template <
int dim,
typename Number>
338 template <
int dim,
typename Number>
348 template <
int dim,
typename Number>
359 template <
int dim,
typename Number>
369 template <
typename Number>
379 template <
int dim,
typename Number>
389 template <
int dim,
typename Number>
399 template <
int dim,
typename Number>
413 template <
int dim,
typename Number>
463 template <
int dim,
typename Number>
475 template <
int dim,
typename Number>
489 template <
typename Number>
497 template <
int dim,
typename Number>
505 template <
int dim,
typename Number>
513 template <
int dim,
typename Number>
521 template <
int dim,
typename Number>
529 template <
typename Number>
537 template <
int dim,
typename Number>
545 template <
int dim,
typename Number>
553 template <
int dim,
typename Number>
561 template <
int dim,
typename Number>
576 template <
int dim,
typename Number>
584 template <
int dim,
typename Number>
592 template <
int dim,
typename Number>
602 template <
typename TensorType,
typename Number>
611 template <
typename TensorType,
typename Number>
644 std::pair<unsigned int, unsigned int>
645 indices_from_component(
const unsigned int component_n,
646 const bool symmetric);
650 std::pair<unsigned int, unsigned int>
651 indices_from_component(
const unsigned int ,
const bool)
654 return std::make_pair(0u, 0u);
659 inline std::pair<unsigned int, unsigned int>
660 indices_from_component<1>(
const unsigned int component_n,
const bool)
664 return std::make_pair(0u, 0u);
669 inline std::pair<unsigned int, unsigned int>
670 indices_from_component<2>(
const unsigned int component_n,
671 const bool symmetric)
673 if (symmetric ==
true)
689 static const unsigned int indices[4][2] = {{0, 0},
693 return std::make_pair(indices[component_n][0],
694 indices[component_n][1]);
699 inline std::pair<unsigned int, unsigned int>
700 indices_from_component<3>(
const unsigned int component_n,
701 const bool symmetric)
703 if (symmetric ==
true)
719 static const unsigned int indices[9][2] = {{0, 0},
728 return std::make_pair(indices[component_n][0],
729 indices[component_n][1]);
739 vector_component_factor(
const unsigned int component_i,
740 const bool symmetric)
742 if (symmetric ==
false)
745 if (component_i < dim)
758 matrix_component_factor(
const unsigned int component_i,
759 const unsigned int component_j,
760 const bool symmetric)
762 if (symmetric ==
false)
767 if (component_i < dim && component_j < dim)
769 else if (component_i >= dim && component_j >= dim)
779 template <
typename Number>
784 const unsigned int n_rows = out.size();
785 for (
unsigned int r = 0; r < n_rows; ++r)
791 template <
int dim,
typename Number>
795 return to_vector(s.operator
const Number &());
799 template <
int dim,
typename Number>
804 const unsigned int n_rows = out.size();
805 for (
unsigned int r = 0; r < n_rows; ++r)
807 const std::pair<unsigned int, unsigned int> indices =
808 internal::indices_from_component<dim>(r,
false);
810 const unsigned int i = indices.first;
817 template <
int dim,
typename Number>
822 const unsigned int n_rows = out.size();
823 for (
unsigned int r = 0; r < n_rows; ++r)
825 const std::pair<unsigned int, unsigned int> indices =
826 internal::indices_from_component<dim>(r,
false);
829 const unsigned int i = indices.first;
830 const unsigned int j = indices.second;
837 template <
int dim,
typename Number>
842 const unsigned int n_rows = out.size();
843 for (
unsigned int r = 0; r < n_rows; ++r)
845 const std::pair<unsigned int, unsigned int> indices =
846 internal::indices_from_component<dim>(r,
true);
850 const unsigned int i = indices.first;
851 const unsigned int j = indices.second;
853 const double factor =
854 internal::vector_component_factor<dim>(r,
true);
856 out(r) = factor * st[i][j];
862 template <
typename Number>
872 template <
int dim,
typename Number>
876 return to_matrix(s.operator
const Number &());
880 template <
int dim,
typename Number>
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)
889 const std::pair<unsigned int, unsigned int> indices =
890 internal::indices_from_component<dim>(r,
false);
892 const unsigned int i = indices.first;
894 for (
unsigned int c = 0; c < n_cols; ++c)
904 template <
int dim,
typename Number>
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)
913 const std::pair<unsigned int, unsigned int> indices_i =
914 internal::indices_from_component<dim>(r,
false);
917 const unsigned int i = indices_i.first;
919 for (
unsigned int c = 0; c < n_cols; ++c)
921 const std::pair<unsigned int, unsigned int> indices_j =
922 internal::indices_from_component<dim>(c,
false);
925 const unsigned int j = indices_j.second;
934 template <
int dim,
typename Number>
944 template <
typename TensorType>
945 struct is_rank_2_symmetric_tensor : std::false_type
948 template <
int dim,
typename Number>
963 (SubTensor1::dimension == dim && SubTensor2::dimension == dim),
964 "Sub-tensor spatial dimension is different from those of the input tensor.");
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.");
972 SubTensor2::n_independent_components);
973 const unsigned int n_rows = out.m();
974 const unsigned int n_cols = out.n();
976 if (SubTensor1::rank == 2 && SubTensor2::rank == 1)
978 const bool subtensor_is_rank_2_symmetric_tensor =
979 internal::is_rank_2_symmetric_tensor<SubTensor1>::value;
981 for (
unsigned int r = 0; r < n_rows; ++r)
983 const std::pair<unsigned int, unsigned int> indices_ij =
984 internal::indices_from_component<dim>(
985 r, subtensor_is_rank_2_symmetric_tensor);
988 if (subtensor_is_rank_2_symmetric_tensor)
990 Assert(indices_ij.second >= indices_ij.first,
993 const unsigned int i = indices_ij.first;
994 const unsigned int j = indices_ij.second;
996 const double factor = internal::vector_component_factor<dim>(
997 r, subtensor_is_rank_2_symmetric_tensor);
999 for (
unsigned int c = 0; c < n_cols; ++c)
1001 const std::pair<unsigned int, unsigned int> indices_k =
1002 internal::indices_from_component<dim>(c,
false);
1004 const unsigned int k = indices_k.first;
1006 if (subtensor_is_rank_2_symmetric_tensor)
1007 out(r, c) = factor * t[i][j][k];
1009 out(r, c) = t[i][j][k];
1013 else if (SubTensor1::rank == 1 && SubTensor2::rank == 2)
1015 const bool subtensor_is_rank_2_symmetric_tensor =
1016 internal::is_rank_2_symmetric_tensor<SubTensor2>::value;
1018 for (
unsigned int r = 0; r < n_rows; ++r)
1020 const std::pair<unsigned int, unsigned int> indices_k =
1021 internal::indices_from_component<dim>(r,
false);
1023 const unsigned int k = indices_k.first;
1025 for (
unsigned int c = 0; c < n_cols; ++c)
1027 const std::pair<unsigned int, unsigned int> indices_ij =
1028 internal::indices_from_component<dim>(
1029 c, subtensor_is_rank_2_symmetric_tensor);
1032 if (subtensor_is_rank_2_symmetric_tensor)
1034 Assert(indices_ij.second >= indices_ij.first,
1037 const unsigned int i = indices_ij.first;
1038 const unsigned int j = indices_ij.second;
1040 if (subtensor_is_rank_2_symmetric_tensor)
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];
1048 out(r, c) = t[k][i][j];
1061 template <
int dim,
typename Number>
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)
1072 const std::pair<unsigned int, unsigned int> indices_ij =
1073 internal::indices_from_component<dim>(r,
false);
1076 const unsigned int i = indices_ij.first;
1077 const unsigned int j = indices_ij.second;
1079 for (
unsigned int c = 0; c < n_cols; ++c)
1081 const std::pair<unsigned int, unsigned int> indices_kl =
1082 internal::indices_from_component<dim>(c,
false);
1085 const unsigned int k = indices_kl.first;
1086 const unsigned int l = indices_kl.second;
1088 out(r, c) = t[i][j][k][
l];
1095 template <
int dim,
typename Number>
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)
1106 const std::pair<unsigned int, unsigned int> indices_ij =
1107 internal::indices_from_component<dim>(r,
true);
1111 const unsigned int i = indices_ij.first;
1112 const unsigned int j = indices_ij.second;
1114 for (
unsigned int c = 0; c < n_cols; ++c)
1116 const std::pair<unsigned int, unsigned int> indices_kl =
1117 internal::indices_from_component<dim>(c,
true);
1120 Assert(indices_kl.second >= indices_kl.first,
1122 const unsigned int k = indices_kl.first;
1123 const unsigned int l = indices_kl.second;
1125 const double factor =
1126 internal::matrix_component_factor<dim>(r, c,
true);
1128 out(r, c) = factor * st[i][j][k][
l];
1135 template <
typename Number>
1144 template <
int dim,
typename Number>
1148 return to_tensor(vec, s.operator Number &());
1152 template <
int dim,
typename Number>
1158 const unsigned int n_rows = vec.
size();
1159 for (
unsigned int r = 0; r < n_rows; ++r)
1161 const std::pair<unsigned int, unsigned int> indices =
1162 internal::indices_from_component<dim>(r,
false);
1164 const unsigned int i = indices.first;
1170 template <
int dim,
typename Number>
1176 const unsigned int n_rows = vec.
size();
1177 for (
unsigned int r = 0; r < n_rows; ++r)
1179 const std::pair<unsigned int, unsigned int> indices =
1180 internal::indices_from_component<dim>(r,
false);
1183 const unsigned int i = indices.first;
1184 const unsigned int j = indices.second;
1190 template <
int dim,
typename Number>
1196 const unsigned int n_rows = vec.
size();
1197 for (
unsigned int r = 0; r < n_rows; ++r)
1199 const std::pair<unsigned int, unsigned int> indices =
1200 internal::indices_from_component<dim>(r,
true);
1204 const unsigned int i = indices.first;
1205 const unsigned int j = indices.second;
1207 const double inv_factor =
1208 1.0 / internal::vector_component_factor<dim>(r,
true);
1210 st[i][j] = inv_factor * vec(r);
1215 template <
typename Number>
1221 Assert(mtrx.n_elements() == 1,
1227 template <
int dim,
typename Number>
1231 return to_tensor(mtrx, s.operator Number &());
1235 template <
int dim,
typename Number>
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)
1249 const std::pair<unsigned int, unsigned int> indices =
1250 internal::indices_from_component<dim>(r,
false);
1253 const unsigned int i = indices.first;
1255 for (
unsigned int c = 0; c < n_cols; ++c)
1264 template <
int dim,
typename Number>
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)
1278 const std::pair<unsigned int, unsigned int> indices_i =
1279 internal::indices_from_component<dim>(r,
false);
1282 const unsigned int i = indices_i.first;
1284 for (
unsigned int c = 0; c < n_cols; ++c)
1286 const std::pair<unsigned int, unsigned int> indices_j =
1287 internal::indices_from_component<dim>(c,
false);
1290 const unsigned int j = indices_j.second;
1292 t[i][j] = mtrx(r, c);
1298 template <
int dim,
typename Number>
1309 Assert((mtrx.n_elements() ==
1320 "The entries stored inside the matrix were not symmetric"));
1324 template <
int dim,
typename Number>
1349 const unsigned int n_rows = mtrx.
m();
1350 const unsigned int n_cols = mtrx.
n();
1362 const bool subtensor_is_rank_2_symmetric_tensor =
1366 for (
unsigned int r = 0; r < n_rows; ++r)
1368 const std::pair<unsigned int, unsigned int> indices_ij =
1369 internal::indices_from_component<dim>(
1370 r, subtensor_is_rank_2_symmetric_tensor);
1373 if (subtensor_is_rank_2_symmetric_tensor)
1375 Assert(indices_ij.second >= indices_ij.first,
1378 const unsigned int i = indices_ij.first;
1379 const unsigned int j = indices_ij.second;
1381 const double inv_factor =
1382 1.0 / internal::vector_component_factor<dim>(
1383 r, subtensor_is_rank_2_symmetric_tensor);
1385 for (
unsigned int c = 0; c < n_cols; ++c)
1387 const std::pair<unsigned int, unsigned int> indices_k =
1388 internal::indices_from_component<dim>(c,
false);
1390 const unsigned int k = indices_k.first;
1392 if (subtensor_is_rank_2_symmetric_tensor)
1394 t[i][j][k] = inv_factor * mtrx(r, c);
1395 t[j][i][k] = t[i][j][k];
1398 t[i][j][k] = mtrx(r, c);
1417 const bool subtensor_is_rank_2_symmetric_tensor =
1421 for (
unsigned int r = 0; r < n_rows; ++r)
1423 const std::pair<unsigned int, unsigned int> indices_k =
1424 internal::indices_from_component<dim>(r,
false);
1426 const unsigned int k = indices_k.first;
1428 for (
unsigned int c = 0; c < n_cols; ++c)
1430 const std::pair<unsigned int, unsigned int> indices_ij =
1431 internal::indices_from_component<dim>(
1432 c, subtensor_is_rank_2_symmetric_tensor);
1435 if (subtensor_is_rank_2_symmetric_tensor)
1437 Assert(indices_ij.second >= indices_ij.first,
1440 const unsigned int i = indices_ij.first;
1441 const unsigned int j = indices_ij.second;
1443 if (subtensor_is_rank_2_symmetric_tensor)
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];
1452 t[k][i][j] = mtrx(r, c);
1459 template <
int dim,
typename Number>
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)
1477 const std::pair<unsigned int, unsigned int> indices_ij =
1478 internal::indices_from_component<dim>(r,
false);
1481 const unsigned int i = indices_ij.first;
1482 const unsigned int j = indices_ij.second;
1484 for (
unsigned int c = 0; c < n_cols; ++c)
1486 const std::pair<unsigned int, unsigned int> indices_kl =
1487 internal::indices_from_component<dim>(c,
false);
1490 const unsigned int k = indices_kl.first;
1491 const unsigned int l = indices_kl.second;
1493 t[i][j][k][
l] = mtrx(r, c);
1499 template <
int dim,
typename Number>
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)
1522 const std::pair<unsigned int, unsigned int> indices_ij =
1523 internal::indices_from_component<dim>(r,
false);
1526 const unsigned int i = indices_ij.first;
1527 const unsigned int j = indices_ij.second;
1529 for (
unsigned int c = 0; c < n_cols; ++c)
1531 const std::pair<unsigned int, unsigned int> indices_kl =
1532 internal::indices_from_component<dim>(c,
false);
1535 const unsigned int k = indices_kl.first;
1536 const unsigned int l = indices_kl.second;
1538 const double inv_factor =
1539 1.0 / internal::matrix_component_factor<dim>(r, c,
true);
1541 st[i][j][k][
l] = inv_factor * mtrx(r, c);
1547 template <
typename TensorType,
typename Number>
1557 template <
typename TensorType,
typename Number>
static constexpr unsigned int n_independent_components
static constexpr unsigned int n_independent_components
virtual size_type size() const override
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
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)
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 SymmetricTensor< 2, dim, Number > symmetrize(const Tensor< 2, dim, Number > &t)