23 #include "libmesh/utility.h" 24 #include "libmesh/tensor_value.h" 25 #include "libmesh/vector_value.h" 46 return MooseEnum(
"antisymmetric symmetric9 symmetric21 general_isotropic symmetric_isotropic " 47 "symmetric_isotropic_E_nu antisymmetric_isotropic axisymmetric_rz general " 48 "principal orthotropic");
54 mooseAssert(
N == 3,
"RankFourTensorTempl<T> is currently only tested for 3 dimensions.");
63 unsigned int index = 0;
72 (*this)(i, i, i, i) = 1.0;
75 case initIdentityFour:
80 _vals[index++] =
Real(i == k && j == l);
83 case initIdentitySymmetricFour:
88 _vals[index++] = 0.5 *
Real(i == k && j == l) + 0.5 *
Real(i == l && j == k);
91 case initIdentityDeviatoric:
92 for (
unsigned int i = 0; i <
N; ++i)
93 for (
unsigned int j = 0; j <
N; ++j)
94 for (
unsigned int k = 0; k <
N; ++k)
95 for (
unsigned int l = 0; l <
N; ++l)
97 _vals[index] =
Real(i == k && j == l);
98 if ((i == j) && (k == l))
99 _vals[index] -= 1.0 / 3.0;
105 mooseError(
"Unknown RankFourTensorTempl<T> initialization pattern.");
109 template <
typename T>
112 fillFromInputVector(input, fill_method);
115 template <
typename T>
123 template <
typename T>
124 template <
template <
typename>
class Tensor,
typename T2>
127 typename std::enable_if<TwoTensorMultTraits<Tensor, T2>::value,
130 typedef decltype(T() * T2()) ValueType;
133 if constexpr (std::is_same_v<T, Real> && std::is_same_v<T2, Real>)
138 Eigen::Matrix<Real, N2, 1> bvec;
139 for (
unsigned int kl = 0; kl < N2; ++kl)
140 bvec(kl) = b(kl /
N, kl %
N);
141 const Eigen::Map<const Eigen::Matrix<Real, N2, N2, Eigen::RowMajor>> a(_vals);
142 Eigen::Map<Eigen::Matrix<Real, N2, 1>> r(result.
_coords);
143 r.noalias() = a * bvec;
148 unsigned int index = 0;
149 for (
unsigned int ij = 0; ij < N2; ++ij)
152 for (
unsigned int kl = 0; kl < N2; ++kl)
153 tmp += _vals[index++] * b(kl / LIBMESH_DIM, kl % LIBMESH_DIM);
161 template <
typename T>
170 template <
typename T>
179 template <
typename T>
184 _vals[i] += a.
_vals[i];
188 template <
typename T>
189 template <
typename T2>
196 result.
_vals[i] = _vals[i] + b._vals[i];
200 template <
typename T>
205 _vals[i] -= a.
_vals[i];
209 template <
typename T>
210 template <
typename T2>
217 result.
_vals[i] = _vals[i] - b._vals[i];
221 template <
typename T>
227 result.
_vals[i] = -_vals[i];
231 template <
typename T>
232 template <
typename T2>
237 typedef decltype(T() * T2()) ValueType;
240 if constexpr (std::is_same_v<T, Real> && std::is_same_v<T2, Real>)
246 const Eigen::Map<const Eigen::Matrix<Real, N2, N2, Eigen::RowMajor>> a(_vals);
247 const Eigen::Map<const Eigen::Matrix<Real, N2, N2, Eigen::RowMajor>> bmat(b._vals);
248 Eigen::Map<Eigen::Matrix<Real, N2, N2, Eigen::RowMajor>> r(result.
_vals);
249 r.noalias() = a * bmat;
260 result(i, j, k, l) += (*this)(i, j, p, q) * b(p, q, k, l);
266 template <
typename T>
279 template <
typename T>
283 mooseError(
"The invSymm operation calls to LAPACK and only supports plain Real type tensors.");
290 unsigned int ntens =
N * (
N + 1) / 2;
294 std::vector<PetscScalar> mat;
295 mat.assign(ntens * ntens, 0);
366 unsigned int index = 0;
373 mat[k == l ? i * ntens + k : i * ntens + k + nskip + l] += _vals[index];
376 mat[k == l ? (nskip + i + j) * ntens + k : (nskip + i + j) * ntens + k + nskip + l] +=
382 for (
unsigned int i = 3; i < ntens; ++i)
384 mat[i * ntens + j] /= 2.0;
398 result.
_vals[index] =
399 k == l ? mat[i * ntens + k] : mat[i * ntens + k + nskip + l] / 2.0;
402 result.
_vals[index] = k == l ? mat[(nskip + i + j) * ntens + k]
403 : mat[(nskip + i + j) * ntens + k + nskip + l] / 2.0;
410 template <
typename T>
416 unsigned int index = 0;
422 unsigned int index2 = 0;
426 const T & a = R(i, m);
429 const T & ab = a * R(j, n);
432 const T & abc = ab * R(k, o);
434 sum += abc * R(l, p) * old.
_vals[index2++];
438 _vals[index++] = sum;
442 template <
typename T>
449 stm <<
"i = " << i <<
" j = " << j <<
'\n';
453 stm << std::setw(15) << (*this)(i, j, k, l) <<
" ";
462 template <
typename T>
466 for (
unsigned int i = 0; i <
N; ++i)
467 for (
unsigned int j = 0; j <
N; ++j)
469 stm <<
"i = " << i <<
" j = " << j <<
'\n';
470 for (
unsigned int k = 0; k <
N; ++k)
472 for (
unsigned int l = 0; l <
N; ++l)
482 template <
typename T>
488 unsigned int index = 0;
493 result.
_vals[index++] = _vals[k * N3 + i *
N + j + l * N2];
498 template <
typename T>
508 result(i, j, k, l) = (*this)(j, i, k, l);
513 template <
typename T>
523 result(i, j, k, l) = (*this)(i, j, l, k);
528 template <
typename T>
534 if (input.size() == 9)
537 (*this)(0, 0, 0, 0) = input[0];
538 (*this)(0, 0, 0, 1) = input[1];
539 (*this)(0, 0, 1, 1) = input[2];
540 (*this)(0, 1, 0, 1) = input[3];
541 (*this)(0, 1, 1, 1) = input[4];
542 (*this)(0, 1, 0, 0) = input[5];
543 (*this)(1, 1, 0, 0) = input[6];
544 (*this)(1, 1, 0, 1) = input[7];
545 (*this)(1, 1, 1, 1) = input[8];
548 (*this)(0, 0, 1, 0) = (*
this)(0, 0, 0, 1);
549 (*this)(0, 1, 1, 0) = (*
this)(0, 1, 0, 1);
550 (*this)(1, 0, 0, 0) = (*
this)(0, 1, 0, 0);
551 (*this)(1, 0, 0, 1) = (*
this)(0, 1, 0, 1);
552 (*this)(1, 0, 1, 1) = (*
this)(0, 1, 1, 1);
553 (*this)(1, 0, 0, 0) = (*
this)(0, 1, 0, 0);
554 (*this)(1, 1, 1, 0) = (*
this)(1, 1, 0, 1);
556 else if (input.size() == 2)
559 (*this)(0, 0, 0, 0) = input[0];
560 (*this)(0, 0, 1, 1) = input[1];
562 (*this)(1, 1, 1, 1) = (*
this)(0, 0, 0, 0);
563 (*this)(1, 1, 0, 0) = (*
this)(0, 0, 1, 1);
564 (*this)(0, 1, 0, 1) = 0.5 * ((*
this)(0, 0, 0, 0) - (*
this)(0, 0, 1, 1));
565 (*this)(1, 0, 0, 1) = (*
this)(0, 1, 0, 1);
566 (*this)(0, 1, 1, 0) = (*
this)(0, 1, 0, 1);
567 (*this)(1, 0, 1, 0) = (*
this)(0, 1, 0, 1);
570 mooseError(
"Please provide correct number of inputs for surface RankFourTensorTempl<T> " 574 template <
typename T>
582 fillAntisymmetricFromInputVector(input);
585 fillSymmetric9FromInputVector(input);
588 fillSymmetric21FromInputVector(input);
590 case general_isotropic:
591 fillGeneralIsotropicFromInputVector(input);
593 case symmetric_isotropic:
594 fillSymmetricIsotropicFromInputVector(input);
596 case symmetric_isotropic_E_nu:
597 fillSymmetricIsotropicEandNuFromInputVector(input);
599 case antisymmetric_isotropic:
600 fillAntisymmetricIsotropicFromInputVector(input);
602 case axisymmetric_rz:
603 fillAxisymmetricRZFromInputVector(input);
606 fillGeneralFromInputVector(input);
609 fillPrincipalFromInputVector(input);
612 fillGeneralOrthotropicFromInputVector(input);
615 mooseError(
"fillFromInputVector called with unknown fill_method of ", fill_method);
619 template <
typename T>
623 if (input.size() != 6)
625 "To use fillAntisymmetricFromInputVector, your input must have size 6. Yours has size ",
630 (*this)(0, 1, 0, 1) = input[0];
631 (*this)(0, 1, 0, 2) = input[1];
632 (*this)(0, 1, 1, 2) = input[2];
634 (*this)(0, 2, 0, 2) = input[3];
635 (*this)(0, 2, 1, 2) = input[4];
637 (*this)(1, 2, 1, 2) = input[5];
640 (*this)(0, 2, 0, 1) = (*
this)(0, 1, 0, 2);
641 (*this)(1, 2, 0, 1) = (*
this)(0, 1, 1, 2);
642 (*this)(1, 2, 0, 2) = (*
this)(0, 2, 1, 2);
649 (*this)(0, 1, j, i) = -(*
this)(0, 1, i, j);
650 (*this)(0, 2, j, i) = -(*
this)(0, 2, i, j);
651 (*this)(1, 2, j, i) = -(*
this)(1, 2, i, j);
659 (*this)(1, 0, i, j) = -(*
this)(0, 1, i, j);
660 (*this)(2, 0, i, j) = -(*
this)(0, 2, i, j);
661 (*this)(2, 1, i, j) = -(*
this)(1, 2, i, j);
665 template <
typename T>
669 if (input.size() != 3)
670 mooseError(
"To use fillGeneralIsotropicFromInputVector, your input must have size 3. Yours " 674 fillGeneralIsotropic(input[0], input[1], input[2]);
677 template <
typename T>
686 (*this)(i, j, k, l) = i0 *
Real(i == j) *
Real(k == l) +
689 (*this)(i, j, k, l) +=
694 template <
typename T>
698 if (input.size() != 1)
699 mooseError(
"To use fillAntisymmetricIsotropicFromInputVector, your input must have size 1. " 703 fillGeneralIsotropic(0.0, 0.0, input[0]);
706 template <
typename T>
710 fillGeneralIsotropic(0.0, 0.0, i0);
713 template <
typename T>
717 mooseAssert(input.size() == 2,
718 "To use fillSymmetricIsotropicFromInputVector, your input must have size 2.");
719 fillSymmetricIsotropic(input[0], input[1]);
722 template <
typename T>
727 fillSymmetric21FromInputVector(std::array<T,21>
728 {{lambda + 2.0 * G, lambda, lambda, 0.0, 0.0, 0.0,
729 lambda + 2.0 * G, lambda, 0.0, 0.0, 0.0,
730 lambda + 2.0 * G, 0.0, 0.0, 0.0,
737 template <
typename T>
741 if (input.size() != 2)
743 "To use fillSymmetricIsotropicEandNuFromInputVector, your input must have size 2. Yours " 747 fillSymmetricIsotropicEandNu(input[0], input[1]);
750 template <
typename T>
755 const T & lambda = E * nu / ((1.0 + nu) * (1.0 - 2.0 * nu));
756 const T & G = E / (2.0 * (1.0 + nu));
758 fillSymmetricIsotropic(lambda, G);
761 template <
typename T>
765 mooseAssert(input.size() == 5,
766 "To use fillAxisymmetricRZFromInputVector, your input must have size 5.");
775 fillSymmetric21FromInputVector(std::array<T,21>
776 {{input[0],input[1],input[2], 0.0, 0.0, 0.0,
777 input[0],input[2], 0.0, 0.0, 0.0,
778 input[3], 0.0, 0.0, 0.0,
781 (input[0] - input[1]) * 0.5}});
785 template <
typename T>
789 if (input.size() != 81)
790 mooseError(
"To use fillGeneralFromInputVector, your input must have size 81. Yours has size ",
797 template <
typename T>
801 if (input.size() != 9)
802 mooseError(
"To use fillPrincipalFromInputVector, your input must have size 9. Yours has size ",
807 (*this)(0, 0, 0, 0) = input[0];
808 (*this)(0, 0, 1, 1) = input[1];
809 (*this)(0, 0, 2, 2) = input[2];
810 (*this)(1, 1, 0, 0) = input[3];
811 (*this)(1, 1, 1, 1) = input[4];
812 (*this)(1, 1, 2, 2) = input[5];
813 (*this)(2, 2, 0, 0) = input[6];
814 (*this)(2, 2, 1, 1) = input[7];
815 (*this)(2, 2, 2, 2) = input[8];
818 template <
typename T>
822 if (input.size() != 12)
823 mooseError(
"To use fillGeneralOrhotropicFromInputVector, your input must have size 12. Yours " 827 const T & Ea = input[0];
828 const T & Eb = input[1];
829 const T & Ec = input[2];
830 const T & Gab = input[3];
831 const T & Gbc = input[4];
832 const T & Gca = input[5];
833 const T & nuba = input[6];
834 const T & nuca = input[7];
835 const T & nucb = input[8];
836 const T & nuab = input[9];
837 const T & nuac = input[10];
838 const T & nubc = input[11];
841 bool preserve_symmetry = MooseUtils::relativeFuzzyEqual(nuab * Eb, nuba * Ea) &&
842 MooseUtils::relativeFuzzyEqual(nuca * Ea, nuac * Ec) &&
843 MooseUtils::relativeFuzzyEqual(nubc * Ec, nucb * Eb);
845 if (!preserve_symmetry)
846 mooseError(
"Orthotropic elasticity tensor input is not consistent with symmetry requirements. " 847 "Check input for accuracy");
849 unsigned int ntens =
N * (
N + 1) / 2;
852 mat.assign(ntens * ntens, 0);
854 T k = 1 - nuab * nuba - nubc * nucb - nuca * nuac - nuab * nubc * nuca - nuba * nucb * nuac;
856 bool is_positive_definite =
857 (k > 0) && (1 - nubc * nucb) > 0 && (1 - nuac * nuca) > 0 && (1 - nuab * nuba) > 0;
858 if (!is_positive_definite)
859 mooseError(
"Orthotropic elasticity tensor input is not positive definite. Check input for " 862 mat[0] = Ea * (1 - nubc * nucb) / k;
863 mat[1] = Ea * (nubc * nuca + nuba) / k;
864 mat[2] = Ea * (nuba * nucb + nuca) / k;
866 mat[6] = Eb * (nuac * nucb + nuab) / k;
867 mat[7] = Eb * (1 - nuac * nuca) / k;
868 mat[8] = Eb * (nuab * nuca + nucb) / k;
870 mat[12] = Ec * (nuab * nubc + nuac) / k;
871 mat[13] = Ec * (nuac * nuba + nubc) / k;
872 mat[14] = Ec * (1 - nuab * nuba) / k;
882 unsigned int index = 0;
889 (*this)._vals[index] =
890 k == l ? mat[i * ntens + k] : mat[i * ntens + k + nskip + l] / 2.0;
892 (*this)._vals[index] = k == l ? mat[(nskip + i + j) * ntens + k]
893 : mat[(nskip + i + j) * ntens + k + nskip + l] / 2.0;
898 template <
typename T>
904 unsigned int index = 0;
905 for (
unsigned int ij = 0; ij < N2; ++ij)
908 for (
unsigned int kl = 0; kl < N2; ++kl)
909 result.
_coords[kl] += _vals[index++] * bb;
915 template <
typename T>
922 for (
unsigned int k = 0; k <
N; k++)
923 for (
unsigned int l = 0; l <
N; l++)
924 val += (*
this)(i, j, k, l) * M(k, l);
929 template <
typename T>
936 for (
unsigned int i = 0; i <
N; i++)
937 for (
unsigned int j = 0; j <
N; j++)
938 val += (*
this)(i, j, k, l) * M(i, j);
943 template <
typename T>
951 sum += (*this)(i, i, j, j);
955 template <
typename T>
961 a(0) = (*this)(0, 0, 0, 0) + (*
this)(0, 0, 1, 1) + (*
this)(0, 0, 2, 2);
962 a(1) = (*this)(1, 1, 0, 0) + (*
this)(1, 1, 1, 1) + (*
this)(1, 1, 2, 2);
963 a(2) = (*this)(2, 2, 0, 0) + (*
this)(2, 2, 1, 1) + (*
this)(2, 2, 2, 2);
967 template <
typename T>
974 for (
unsigned int i = 0; i <
N; i++)
975 for (
unsigned int j = 0; j <
N; j++)
976 for (
unsigned int k = 0; k <
N; k++)
977 for (
unsigned int l = 0; l <
N; l++)
978 for (
unsigned int m = 0; m <
N; m++)
979 for (
unsigned int n = 0; n <
N; n++)
980 for (
unsigned int t = 0; t <
N; t++)
981 R(i, j, k, l) += (*this)(i, m, n, t) * A(j, m) *
B(k, n) * C(l, t);
986 template <
typename T>
993 for (
unsigned int i = 0; i <
N; i++)
994 for (
unsigned int j = 0; j <
N; j++)
995 for (
unsigned int k = 0; k <
N; k++)
996 for (
unsigned int l = 0; l <
N; l++)
997 for (
unsigned int m = 0; m <
N; m++)
998 for (
unsigned int n = 0; n <
N; n++)
999 for (
unsigned int t = 0; t <
N; t++)
1000 R(i, j, k, l) += (*this)(m, j, n, t) * A(i, m) *
B(k, n) * C(l, t);
1005 template <
typename T>
1012 for (
unsigned int i = 0; i <
N; i++)
1013 for (
unsigned int j = 0; j <
N; j++)
1014 for (
unsigned int k = 0; k <
N; k++)
1015 for (
unsigned int l = 0; l <
N; l++)
1016 for (
unsigned int m = 0; m <
N; m++)
1017 for (
unsigned int n = 0; n <
N; n++)
1018 for (
unsigned int t = 0; t <
N; t++)
1019 R(i, j, k, l) += (*this)(m, n, k, t) * A(i, m) *
B(j, n) * C(l, t);
1024 template <
typename T>
1031 for (
unsigned int i = 0; i <
N; i++)
1032 for (
unsigned int j = 0; j <
N; j++)
1033 for (
unsigned int k = 0; k <
N; k++)
1034 for (
unsigned int l = 0; l <
N; l++)
1035 for (
unsigned int m = 0; m <
N; m++)
1036 for (
unsigned int n = 0; n <
N; n++)
1037 for (
unsigned int t = 0; t <
N; t++)
1038 R(i, j, k, l) += (*this)(m, n, t, l) * A(i, m) *
B(j, n) * C(k, t);
1043 template <
typename T>
1049 for (
unsigned int i = 0; i <
N; i++)
1050 for (
unsigned int j = 0; j <
N; j++)
1051 for (
unsigned int k = 0; k <
N; k++)
1052 for (
unsigned int l = 0; l <
N; l++)
1053 for (
unsigned int m = 0; m <
N; m++)
1054 R(i, j, k, l) += (*this)(m, j, k, l) * A(i, m);
1059 template <
typename T>
1065 for (
unsigned int i = 0; i <
N; i++)
1066 for (
unsigned int j = 0; j <
N; j++)
1067 for (
unsigned int k = 0; k <
N; k++)
1068 for (
unsigned int l = 0; l <
N; l++)
1069 for (
unsigned int m = 0; m <
N; m++)
1070 R(i, j, k, l) += (*this)(i, m, k, l) * A(j, m);
1075 template <
typename T>
1081 for (
unsigned int i = 0; i <
N; i++)
1082 for (
unsigned int j = 0; j <
N; j++)
1083 for (
unsigned int k = 0; k <
N; k++)
1084 for (
unsigned int l = 0; l <
N; l++)
1085 for (
unsigned int m = 0; m <
N; m++)
1086 R(i, j, k, l) += (*this)(i, j, m, l) * A(k, m);
1091 template <
typename T>
1097 for (
unsigned int i = 0; i <
N; i++)
1098 for (
unsigned int j = 0; j <
N; j++)
1099 for (
unsigned int k = 0; k <
N; k++)
1100 for (
unsigned int l = 0; l <
N; l++)
1101 for (
unsigned int m = 0; m <
N; m++)
1102 R(i, j, k, l) += (*this)(i, j, k, m) * A(l, m);
1107 template <
typename T>
1117 if ((*
this)(i, j, k, l) != (*
this)(j, i, k, l) ||
1118 (*
this)(i, j, k, l) != (*
this)(i, j, l, k))
1122 if ((*
this)(i, j, k, l) != (*
this)(k, l, i, j))
1128 template <
typename T>
1137 const T & mu = (*this)(0, 1, 0, 1);
1139 if ((*
this)(1, 2, 1, 2) != mu || (*
this)(2, 0, 2, 0) != mu)
1142 if ((*
this)(2, 0, 1, 2) != 0.0 || (*
this)(0, 1, 1, 2) != 0.0 || (*
this)(0, 1, 2, 0) != 0.0)
1148 if (_vals[i * (N3 + N2) + ((j + 1) %
N) *
N + (j + 2) %
N] != 0.0)
1152 const T & K1 = (*this)(0, 0, 0, 0);
1153 const T & K2 = (*this)(0, 0, 1, 1);
1154 if (!MooseUtils::relativeFuzzyEqual(K1 - 4.0 * mu / 3.0, K2 + 2.0 * mu / 3.0))
1156 if ((*
this)(1, 1, 1, 1) != K1 || (*
this)(2, 2, 2, 2) != K1)
1160 if ((*
this)(i, i, j, j) != K2)
RankFourTensorTempl is designed to handle any N-dimensional fourth order tensor, C.
RankFourTensorTempl< T > singleProductJ(const RankTwoTensorTempl< T > &) const
Calculates C_imkl A_jm.
int eps(unsigned int i, unsigned int j)
2D version
void fillGeneralFromInputVector(const std::vector< T > &input)
fillGeneralFromInputVector takes 81 inputs to fill the Rank-4 tensor No symmetries are explicitly mai...
void fillGeneralOrthotropicFromInputVector(const std::vector< T > &input)
fillGeneralOrhotropicFromInputVector takes 10 inputs to fill the Rank-4 tensor It defines a general o...
void fillAntisymmetricFromInputVector(const std::vector< T > &input)
fillAntisymmetricFromInputVector takes 6 inputs to fill the the antisymmetric Rank-4 tensor with the ...
RankFourTensorTempl< T > singleProductL(const RankTwoTensorTempl< T > &) const
Calculates C_ijkm A_lm.
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
RankFourTensorTempl< T > tripleProductIjl(const RankTwoTensorTempl< T > &, const RankTwoTensorTempl< T > &, const RankTwoTensorTempl< T > &) const
Calculates C_mnkt A_im B_jn C_lt.
RankFourTensorTempl< T > & operator*=(const T &a)
C_ijkl *= a.
RankTwoTensorTempl< T > innerProductTranspose(const RankTwoTensorTempl< T > &) const
Inner product of the major transposed tensor with a rank two tensor.
void fillPrincipalFromInputVector(const std::vector< T > &input)
fillPrincipalFromInputVector takes 9 inputs to fill a Rank-4 tensor C1111 = input0 C1122 = input1 C11...
void fillFromInputVector(const std::vector< T > &input, FillMethod fill_method)
fillFromInputVector takes some number of inputs to fill the Rank-4 tensor.
T _coords[LIBMESH_DIM *LIBMESH_DIM]
void surfaceFillFromInputVector(const std::vector< T > &input)
Fills the tensor entries ignoring the last dimension (ie, C_ijkl=0 if any of i, j, k, or l = 3).
T contractionIj(unsigned int, unsigned int, const RankTwoTensorTempl< T > &) const
Sum C_ijkl M_kl for a given i,j.
void print(std::ostream &stm=Moose::out) const
Print the rank four tensor.
RankFourTensorTempl< T > & operator/=(const T &a)
C_ijkl /= a for all i, j, k, l.
auto operator*(const Tensor< T2 > &a) const -> typename std::enable_if< TwoTensorMultTraits< Tensor, T2 >::value, RankTwoTensorTempl< decltype(T() *T2())>>::type
C_ijkl*a_kl.
RankFourTensorTempl< T > tripleProductJkl(const RankTwoTensorTempl< T > &, const RankTwoTensorTempl< T > &, const RankTwoTensorTempl< T > &) const
Calculates C_imnt A_jm B_kn C_lt.
RankFourTensorTempl< T > tripleProductIjk(const RankTwoTensorTempl< T > &, const RankTwoTensorTempl< T > &, const RankTwoTensorTempl< T > &) const
Calculates C_mntl A_im B_jn C_kt.
void fillSymmetricIsotropic(const T &i0, const T &i1)
auto operator+(const RankFourTensorTempl< T2 > &a) const -> RankFourTensorTempl< decltype(T()+T2())>
C_ijkl + a_ijkl.
void fillGeneralIsotropicFromInputVector(const std::vector< T > &input)
fillGeneralIsotropicFromInputVector takes 3 inputs to fill the Rank-4 tensor with symmetries C_ijkl =...
void zero()
Zeros out the tensor.
FillMethod
To fill up the 81 entries in the 4th-order tensor, fillFromInputVector is called with one of the foll...
T L2norm() const
sqrt(C_ijkl*C_ijkl)
void fillSymmetricIsotropicEandNu(const T &E, const T &nu)
bool isSymmetric() const
checks if the tensor is symmetric
void fillGeneralIsotropic(const T &i0, const T &i1, const T &i2)
Vector-less fill API functions. See docs of the corresponding ...FromInputVector methods.
RankFourTensorTempl()
Default constructor; fills to zero.
void init(triangulateio &t)
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
void printReal(std::ostream &stm=Moose::out) const
Print the values of the rank four tensor.
T sum3x3() const
Calculates the sum of Ciijj for i and j varying from 0 to 2.
RankFourTensorTempl< T > transposeMajor() const
Transpose the tensor by swapping the first pair with the second pair of indices.
bool isIsotropic() const
checks if the tensor is isotropic
T _vals[N4]
The values of the rank-four tensor stored by index=(((i * LIBMESH_DIM + j) * LIBMESH_DIM + k) * LIBME...
void fillAxisymmetricRZFromInputVector(const std::vector< T > &input)
fillAxisymmetricRZFromInputVector takes 5 inputs to fill the axisymmetric Rank-4 tensor with the appr...
void rotate(const TypeTensor< T > &R)
Rotate the tensor using C_ijkl = R_im R_jn R_ko R_lp C_mnop.
void fillSymmetricIsotropicEandNuFromInputVector(const std::vector< T > &input)
fillSymmetricIsotropicEandNuFromInputVector is a variation of the fillSymmetricIsotropicFromInputVect...
libMesh::VectorValue< T > sum3x1() const
Calculates the vector a[i] = sum over j Ciijj for i and j varying from 0 to 2.
T contractionKl(unsigned int, unsigned int, const RankTwoTensorTempl< T > &) const
Sum M_ij C_ijkl for a given k,l.
RankFourTensorTempl< T > transposeIj() const
Transpose the tensor by swapping the first two indeces.
void fillSymmetricIsotropicFromInputVector(const std::vector< T > &input)
fillSymmetricIsotropicFromInputVector takes 2 inputs to fill the the symmetric Rank-4 tensor with the...
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template * sqrt(_arg)) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(tanh
RankFourTensorTempl< T > singleProductI(const RankTwoTensorTempl< T > &) const
Calculates C_mjkl A_im.
RankTwoTensorTempl is designed to handle the Stress or Strain Tensor for a fully anisotropic material...
InitMethod
Initialization method.
RankFourTensorTempl< T > operator-() const
-C_ijkl
IntRange< T > make_range(T beg, T end)
void fillAntisymmetricIsotropicFromInputVector(const std::vector< T > &input)
fillAntisymmetricIsotropicFromInputVector takes 1 input to fill the the antisymmetric Rank-4 tensor w...
static MooseEnum fillMethodEnum()
Static method for use in validParams for getting the "fill_method".
RankFourTensorTempl< T > singleProductK(const RankTwoTensorTempl< T > &) const
Calculates C_ijml A_km.
RankFourTensorTempl< T > & operator+=(const RankFourTensorTempl< T > &a)
C_ijkl += a_ijkl for all i, j, k, l.
void fillAntisymmetricIsotropic(const T &i0)
RankFourTensorTempl< T > tripleProductIkl(const RankTwoTensorTempl< T > &, const RankTwoTensorTempl< T > &, const RankTwoTensorTempl< T > &) const
Calculates C_mjnt A_im B_kn C_lt.
RankFourTensorTempl< T > transposeKl() const
Transpose the tensor by swapping the last two indeces.
RankFourTensorTempl< T > invSymm() const
This returns A_ijkl such that C_ijkl*A_klmn = 0.5*(de_im de_jn + de_in de_jm) This routine assumes th...
RankFourTensorTempl< T > & operator-=(const RankFourTensorTempl< T > &a)
C_ijkl -= a_ijkl.
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template pow< 2 >(tan(_arg))+1.0) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(sqrt