18 #include "libmesh/libmesh.h" 19 #include "libmesh/tuple_of.h" 20 #include "libmesh/int_range.h" 22 #include "metaphysicl/raw_type.h" 27 #include <Eigen/Dense> 70 static constexpr
unsigned int N2 =
N *
N;
71 static constexpr
unsigned int N3 =
N *
N *
N;
72 static constexpr
unsigned int N4 =
N *
N *
N *
N;
108 template <
template <
typename>
class Tensor,
typename Scalar>
113 template <
typename Scalar>
116 static const bool value = ScalarTraits<Scalar>::value;
118 template <
typename Scalar>
121 static const bool value = ScalarTraits<Scalar>::value;
123 template <
typename Scalar>
126 static const bool value = ScalarTraits<Scalar>::value;
144 template <
typename T2>
157 inline T &
operator()(
unsigned int i,
unsigned int j,
unsigned int k,
unsigned int l)
166 inline const T &
operator()(
unsigned int i,
unsigned int j,
unsigned int k,
unsigned int l)
const 175 void print(std::ostream & stm = Moose::out)
const;
178 void printReal(std::ostream & stm = Moose::out)
const;
188 template <
typename Scalar>
192 libmesh_assert_equal_to(p, Scalar(0));
198 template <
template <
typename>
class Tensor,
typename T2>
200 typename std::enable_if<TwoTensorMultTraits<Tensor, T2>::value,
204 template <
typename T2>
206 typename std::enable_if<ScalarTraits<T2>::value,
213 template <
typename T2>
215 typename std::enable_if<ScalarTraits<T2>::value,
225 template <
typename T2>
233 template <
typename T2>
241 template <
typename T2>
264 void rotate(
const TypeTensor<T> & R);
342 template <
typename T2>
353 template <
typename T2>
369 VectorValue<T>
sum3x1()
const;
500 template <
typename T2>
502 template <
typename T2>
504 template <
typename T2>
510 template <
typename T>
523 ret(i, j, k, l) =
raw_value(in(i, j, k, l));
530 template <
typename T1,
typename T2>
533 typename std::enable_if<ScalarTraits<T1>::value,
539 template <
typename T>
540 template <
typename T2>
544 _vals[i] = copy.
_vals[i];
547 template <
typename T>
548 template <
typename T2>
551 typename std::enable_if<ScalarTraits<T2>::value,
554 typedef decltype(T() * T2()) ValueType;
558 result.
_vals[i] = _vals[i] * b;
563 template <
typename T>
564 template <
typename T2>
567 typename std::enable_if<ScalarTraits<T2>::value,
572 result.
_vals[i] = _vals[i] / b;
576 template <
typename T>
577 template <
typename T2>
581 mooseAssert(input.size() == 9,
582 "To use fillSymmetric9FromInputVector, your input must have size 9.");
585 (*this)(0, 0, 0, 0) = input[0];
586 (*this)(1, 1, 1, 1) = input[3];
587 (*this)(2, 2, 2, 2) = input[5];
589 (*this)(0, 0, 1, 1) = input[1];
590 (*this)(1, 1, 0, 0) = input[1];
592 (*this)(0, 0, 2, 2) = input[2];
593 (*this)(2, 2, 0, 0) = input[2];
595 (*this)(1, 1, 2, 2) = input[4];
596 (*this)(2, 2, 1, 1) = input[4];
598 (*this)(1, 2, 1, 2) = input[6];
599 (*this)(2, 1, 2, 1) = input[6];
600 (*this)(2, 1, 1, 2) = input[6];
601 (*this)(1, 2, 2, 1) = input[6];
603 (*this)(0, 2, 0, 2) = input[7];
604 (*this)(2, 0, 2, 0) = input[7];
605 (*this)(2, 0, 0, 2) = input[7];
606 (*this)(0, 2, 2, 0) = input[7];
608 (*this)(0, 1, 0, 1) = input[8];
609 (*this)(1, 0, 1, 0) = input[8];
610 (*this)(1, 0, 0, 1) = input[8];
611 (*this)(0, 1, 1, 0) = input[8];
613 template <
typename T>
614 template <
typename T2>
618 mooseAssert(input.size() == 21,
619 "To use fillSymmetric21FromInputVector, your input must have size 21.");
621 (*this)(0, 0, 0, 0) = input[0];
622 (*this)(1, 1, 1, 1) = input[6];
623 (*this)(2, 2, 2, 2) = input[11];
625 (*this)(0, 0, 1, 1) = input[1];
626 (*this)(1, 1, 0, 0) = input[1];
628 (*this)(0, 0, 2, 2) = input[2];
629 (*this)(2, 2, 0, 0) = input[2];
631 (*this)(1, 1, 2, 2) = input[7];
632 (*this)(2, 2, 1, 1) = input[7];
634 (*this)(0, 0, 0, 2) = input[4];
635 (*this)(0, 0, 2, 0) = input[4];
636 (*this)(0, 2, 0, 0) = input[4];
637 (*this)(2, 0, 0, 0) = input[4];
639 (*this)(0, 0, 0, 1) = input[5];
640 (*this)(0, 0, 1, 0) = input[5];
641 (*this)(0, 1, 0, 0) = input[5];
642 (*this)(1, 0, 0, 0) = input[5];
644 (*this)(1, 1, 1, 2) = input[8];
645 (*this)(1, 1, 2, 1) = input[8];
646 (*this)(1, 2, 1, 1) = input[8];
647 (*this)(2, 1, 1, 1) = input[8];
649 (*this)(1, 1, 1, 0) = input[10];
650 (*this)(1, 1, 0, 1) = input[10];
651 (*this)(1, 0, 1, 1) = input[10];
652 (*this)(0, 1, 1, 1) = input[10];
654 (*this)(2, 2, 2, 1) = input[12];
655 (*this)(2, 2, 1, 2) = input[12];
656 (*this)(2, 1, 2, 2) = input[12];
657 (*this)(1, 2, 2, 2) = input[12];
659 (*this)(2, 2, 2, 0) = input[13];
660 (*this)(2, 2, 0, 2) = input[13];
661 (*this)(2, 0, 2, 2) = input[13];
662 (*this)(0, 2, 2, 2) = input[13];
664 (*this)(0, 0, 1, 2) = input[3];
665 (*this)(0, 0, 2, 1) = input[3];
666 (*this)(1, 2, 0, 0) = input[3];
667 (*this)(2, 1, 0, 0) = input[3];
669 (*this)(1, 1, 0, 2) = input[9];
670 (*this)(1, 1, 2, 0) = input[9];
671 (*this)(0, 2, 1, 1) = input[9];
672 (*this)(2, 0, 1, 1) = input[9];
674 (*this)(2, 2, 0, 1) = input[14];
675 (*this)(2, 2, 1, 0) = input[14];
676 (*this)(0, 1, 2, 2) = input[14];
677 (*this)(1, 0, 2, 2) = input[14];
679 (*this)(1, 2, 1, 2) = input[15];
680 (*this)(2, 1, 2, 1) = input[15];
681 (*this)(2, 1, 1, 2) = input[15];
682 (*this)(1, 2, 2, 1) = input[15];
684 (*this)(0, 2, 0, 2) = input[18];
685 (*this)(2, 0, 2, 0) = input[18];
686 (*this)(2, 0, 0, 2) = input[18];
687 (*this)(0, 2, 2, 0) = input[18];
689 (*this)(0, 1, 0, 1) = input[20];
690 (*this)(1, 0, 1, 0) = input[20];
691 (*this)(1, 0, 0, 1) = input[20];
692 (*this)(0, 1, 1, 0) = input[20];
694 (*this)(1, 2, 0, 2) = input[16];
695 (*this)(0, 2, 1, 2) = input[16];
696 (*this)(2, 1, 0, 2) = input[16];
697 (*this)(1, 2, 2, 0) = input[16];
698 (*this)(2, 0, 1, 2) = input[16];
699 (*this)(0, 2, 2, 1) = input[16];
700 (*this)(2, 1, 2, 0) = input[16];
701 (*this)(2, 0, 2, 1) = input[16];
703 (*this)(1, 2, 0, 1) = input[17];
704 (*this)(0, 1, 1, 2) = input[17];
705 (*this)(2, 1, 0, 1) = input[17];
706 (*this)(1, 2, 1, 0) = input[17];
707 (*this)(1, 0, 1, 2) = input[17];
708 (*this)(0, 1, 2, 1) = input[17];
709 (*this)(2, 1, 1, 0) = input[17];
710 (*this)(1, 0, 2, 1) = input[17];
712 (*this)(0, 2, 0, 1) = input[19];
713 (*this)(0, 1, 0, 2) = input[19];
714 (*this)(2, 0, 0, 1) = input[19];
715 (*this)(0, 2, 1, 0) = input[19];
716 (*this)(1, 0, 0, 2) = input[19];
717 (*this)(0, 1, 2, 0) = input[19];
718 (*this)(2, 0, 1, 0) = input[19];
719 (*this)(1, 0, 2, 0) = input[19];
722 template <
typename T>
737 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> mat(9, 9);
744 result.
_vals[i] = mat(i);
749 const Eigen::Map<const Eigen::Matrix<T, 9, 9, Eigen::RowMajor>> mat(&_vals[0]);
750 Eigen::Map<Eigen::Matrix<T, 9, 9, Eigen::RowMajor>> res(&result.
_vals[0]);
757 template <
typename T>
763 static constexpr std::size_t z[4][3] = {{1, 2, 3}, {0, 2, 3}, {0, 1, 3}, {0, 1, 2}};
765 for (x[0] = 0; x[0] <
N; ++x[0])
766 for (x[1] = 0; x[1] <
N; ++x[1])
767 for (x[2] = 0; x[2] <
N; ++x[2])
768 for (x[3] = 0; x[3] <
N; ++x[3])
769 result(x[z[m][0]], x[z[m][1]], x[z[m][2]]) += (*this)(x[0], x[1], x[2], x[3]) * b(x[m]);
RankFourTensorTempl is designed to handle any N-dimensional fourth order tensor, C.
RankFourTensorTempl< T > inverse() const
This returns A_ijkl such that C_ijkl*A_klmn = de_im de_jn i.e.
RankFourTensorTempl< T > singleProductJ(const RankTwoTensorTempl< T > &) const
Calculates C_imkl A_jm.
void mooseSetToZero(T &v)
Helper function templates to set a variable to zero.
RankFourTensorTempl< T > & operator=(const RankFourTensorTempl< T > &a)
copies values from a into this tensor
void fillSymmetric9FromInputVector(const T2 &input)
fillSymmetric9FromInputVector takes 9 inputs to fill in the Rank-4 tensor with the appropriate crysta...
VectorValue< T > sum3x1() const
Calculates the vector a[i] = sum over j Ciijj for i and j varying from 0 to 2.
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.
friend void dataStore(std::ostream &, RankFourTensorTempl< T2 > &, void *)
static RankFourTensorTempl< T > IdentityFour()
RankFourTensorTempl< T > tripleProductIjl(const RankTwoTensorTempl< T > &, const RankTwoTensorTempl< T > &, const RankTwoTensorTempl< T > &) const
Calculates C_mnkt A_im B_jn C_lt.
RankThreeTensorTempl< T > contraction(const VectorValue< T > &b) const
single contraction of a RankFourTensor with a vector over index m
RankFourTensorTempl< T > & operator*=(const T &a)
C_ijkl *= a.
void fillSymmetric21FromInputVector(const T2 &input)
fillSymmetric21FromInputVector takes either 21 inputs to fill in the Rank-4 tensor with the appropria...
RankTwoTensorTempl< T > innerProductTranspose(const RankTwoTensorTempl< T > &) const
Inner product of the major transposed tensor with a rank two tensor.
static constexpr unsigned int N3
tuple_of< 4, unsigned int > index_type
static RankFourTensorTempl< T > Identity()
friend void dataLoad(std::istream &, RankFourTensorTempl< T2 > &, void *)
static constexpr std::size_t dim
This is the dimension of all vector and tensor datastructures used in MOOSE.
void fillPrincipalFromInputVector(const std::vector< T > &input)
fillPrincipalFromInputVector takes 9 inputs to fill a Rank-4 tensor C1111 = input0 C1122 = input1 C11...
void mooseSetToZero< ADRankFourTensor >(ADRankFourTensor &v)
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
void fillFromInputVector(const std::vector< T > &input, FillMethod fill_method)
fillFromInputVector takes some number of inputs to fill the Rank-4 tensor.
static constexpr unsigned int N2
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).
static constexpr unsigned int N4
T contractionIj(unsigned int, unsigned int, const RankTwoTensorTempl< T > &) const
Sum C_ijkl M_kl for a given i,j.
auto operator*(const T1 &a, const RankFourTensorTempl< T2 > &b) -> typename std::enable_if< ScalarTraits< T1 >::value, RankFourTensorTempl< decltype(T1() *T2())>>::type
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.
RankThreeTensor is designed to handle any N-dimensional third order tensor, r.
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.
typename tuple_n< Index, T >::template type<> tuple_of
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 mooseSetToZero< RankFourTensor >(RankFourTensor &v)
Helper function template specialization to set an object to zero.
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.
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...
T contractionKl(unsigned int, unsigned int, const RankTwoTensorTempl< T > &) const
Sum M_ij C_ijkl for a given k,l.
T & operator()(unsigned int i, unsigned int j, unsigned int k, unsigned int l)
Gets the value for the indices specified. Takes indices ranging from 0-2 for i, j, k, and 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
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...
auto operator/(const T2 &a) const -> typename std::enable_if< ScalarTraits< T2 >::value, RankFourTensorTempl< decltype(T()/T2())>>::type
C_ijkl/a.
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.
static constexpr unsigned int N
tensor dimension and powers of the dimension
RankFourTensorTempl< T > & operator+=(const RankFourTensorTempl< T > &a)
C_ijkl += a_ijkl for all i, j, k, l.
const T & operator()(unsigned int i, unsigned int j, unsigned int k, unsigned int l) const
Gets the value for the indices specified.
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.
static RankFourTensorTempl< T > IdentityDeviatoric()
Identity of type {ik} {jl} - {ij} {kl} / 3.
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.
boostcopy::enable_if_c< ScalarTraits< Scalar >::value, RankFourTensorTempl & >::type operator=(const Scalar &libmesh_dbg_var(p))
Assignment-from-scalar operator.