https://mooseframework.inl.gov
Loading...
Searching...
No Matches
Classes | Public Types | Public Member Functions | Static Public Member Functions | Protected Member Functions | Protected Attributes | Friends | List of all members
RankFourTensorTempl< T > Class Template Reference

RankFourTensorTempl is designed to handle any N-dimensional fourth order tensor, C. More...

#include <RankFourTensor.h>

Classes

struct  TwoTensorMultTraits
 
struct  TwoTensorMultTraits< RankTwoTensorTempl, Scalar >
 
struct  TwoTensorMultTraits< TensorValue, Scalar >
 
struct  TwoTensorMultTraits< TypeTensor, Scalar >
 

Public Types

enum  InitMethod {
  initNone , initIdentity , initIdentityFour , initIdentitySymmetricFour ,
  initIdentityDeviatoric
}
 Initialization method. More...
 
enum  FillMethod {
  antisymmetric , symmetric9 , symmetric21 , general_isotropic ,
  symmetric_isotropic , symmetric_isotropic_E_nu , antisymmetric_isotropic , axisymmetric_rz ,
  general , principal , orthotropic
}
 To fill up the 81 entries in the 4th-order tensor, fillFromInputVector is called with one of the following fill_methods. More...
 
typedef tuple_of< 4, unsigned intindex_type
 
typedef T value_type
 

Public Member Functions

 RankFourTensorTempl ()
 Default constructor; fills to zero.
 
 RankFourTensorTempl (const InitMethod)
 Select specific initialization pattern.
 
 RankFourTensorTempl (const std::vector< T > &, FillMethod)
 Fill from vector.
 
 RankFourTensorTempl (const RankFourTensorTempl< T > &a)=default
 Copy assignment operator must be defined if used.
 
template<typename T2 >
 RankFourTensorTempl (const RankFourTensorTempl< T2 > &copy)
 Copy constructor.
 
template<typename T2 >
 RankFourTensorTempl (const SymmetricRankFourTensorTempl< T2 > &t)
 The conversion operator from a SymmetricRankFourTensorTempl
 
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.
 
const T & operator() (unsigned int i, unsigned int j, unsigned int k, unsigned int l) const
 Gets the value for the indices specified.
 
void zero ()
 Zeros out the tensor.
 
void print (std::ostream &stm=Moose::out) const
 Print the rank four tensor.
 
void printReal (std::ostream &stm=Moose::out) const
 Print the values of the rank four tensor.
 
RankFourTensorTempl< T > & operator= (const RankFourTensorTempl< T > &a)=default
 copies values from a into this tensor
 
template<typename Scalar >
std::enable_if< libMesh::ScalarTraits< Scalar >::value, RankFourTensorTempl & >::type operator= (const Scalar &libmesh_dbg_var(p))
 Assignment-from-scalar operator.
 
template<template< typename > class Tensor, typename T2 >
auto operator* (const Tensor< T2 > &a) const -> typename std::enable_if< TwoTensorMultTraits< Tensor, T2 >::value, RankTwoTensorTempl< decltype(T() *T2())> >::type
 C_ijkl*a_kl.
 
template<typename T2 >
auto operator* (const T2 &a) const -> typename std::enable_if< libMesh::ScalarTraits< T2 >::value, RankFourTensorTempl< decltype(T() *T2())> >::type
 C_ijkl*a.
 
RankFourTensorTempl< T > & operator*= (const T &a)
 C_ijkl *= a.
 
template<typename T2 >
auto operator/ (const T2 &a) const -> typename std::enable_if< libMesh::ScalarTraits< T2 >::value, RankFourTensorTempl< decltype(T()/T2())> >::type
 C_ijkl/a.
 
RankFourTensorTempl< T > & operator/= (const T &a)
 C_ijkl /= a for all i, j, k, l.
 
RankFourTensorTempl< T > & operator+= (const RankFourTensorTempl< T > &a)
 C_ijkl += a_ijkl for all i, j, k, l.
 
template<typename T2 >
auto operator+ (const RankFourTensorTempl< T2 > &a) const -> RankFourTensorTempl< decltype(T()+T2())>
 C_ijkl + a_ijkl.
 
RankFourTensorTempl< T > & operator-= (const RankFourTensorTempl< T > &a)
 C_ijkl -= a_ijkl.
 
template<typename T2 >
auto operator- (const RankFourTensorTempl< T2 > &a) const -> RankFourTensorTempl< decltype(T() - T2())>
 C_ijkl - a_ijkl.
 
RankFourTensorTempl< T > operator- () const
 -C_ijkl
 
template<typename T2 >
auto operator* (const RankFourTensorTempl< T2 > &a) const -> RankFourTensorTempl< decltype(T() *T2())>
 C_ijpq*a_pqkl.
 
L2norm () const
 sqrt(C_ijkl*C_ijkl)
 
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 that C_ijkl = C_jikl = C_ijlk.
 
RankFourTensorTempl< T > inverse () const
 This returns A_ijkl such that C_ijkl*A_klmn = de_im de_jn i.e.
 
void rotate (const TypeTensor< T > &R)
 Rotate the tensor using C_ijkl = R_im R_jn R_ko R_lp C_mnop.
 
RankFourTensorTempl< T > transposeMajor () const
 Transpose the tensor by swapping the first pair with the second pair of indices.
 
RankFourTensorTempl< T > transposeIj () const
 Transpose the tensor by swapping the first two indeces.
 
RankFourTensorTempl< T > transposeKl () const
 Transpose the tensor by swapping the last two indeces.
 
template<int m>
RankThreeTensorTempl< T > contraction (const libMesh::VectorValue< T > &b) const
 single contraction of a RankFourTensor with a vector over index m
 
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).
 
void fillFromInputVector (const std::vector< T > &input, FillMethod fill_method)
 fillFromInputVector takes some number of inputs to fill the Rank-4 tensor.
 
template<typename T2 >
void fillSymmetric9FromInputVector (const T2 &input)
 fillSymmetric9FromInputVector takes 9 inputs to fill in the Rank-4 tensor with the appropriate crystal symmetries maintained.
 
template<typename T2 >
void fillSymmetric21FromInputVector (const T2 &input)
 fillSymmetric21FromInputVector takes either 21 inputs to fill in the Rank-4 tensor with the appropriate crystal symmetries maintained.
 
RankTwoTensorTempl< T > innerProductTranspose (const RankTwoTensorTempl< T > &) const
 Inner product of the major transposed tensor with a rank two tensor.
 
contractionIj (unsigned int, unsigned int, const RankTwoTensorTempl< T > &) const
 Sum C_ijkl M_kl for a given i,j.
 
contractionKl (unsigned int, unsigned int, const RankTwoTensorTempl< T > &) const
 Sum M_ij C_ijkl for a given k,l.
 
sum3x3 () const
 Calculates the sum of Ciijj for i and j varying from 0 to 2.
 
libMesh::VectorValue< T > sum3x1 () const
 Calculates the vector a[i] = sum over j Ciijj for i and j varying from 0 to 2.
 
RankFourTensorTempl< T > tripleProductJkl (const RankTwoTensorTempl< T > &, const RankTwoTensorTempl< T > &, const RankTwoTensorTempl< T > &) const
 Calculates C_imnt A_jm B_kn C_lt.
 
RankFourTensorTempl< T > tripleProductIkl (const RankTwoTensorTempl< T > &, const RankTwoTensorTempl< T > &, const RankTwoTensorTempl< T > &) const
 Calculates C_mjnt A_im B_kn C_lt.
 
RankFourTensorTempl< T > tripleProductIjl (const RankTwoTensorTempl< T > &, const RankTwoTensorTempl< T > &, const RankTwoTensorTempl< T > &) const
 Calculates C_mnkt A_im B_jn C_lt.
 
RankFourTensorTempl< T > tripleProductIjk (const RankTwoTensorTempl< T > &, const RankTwoTensorTempl< T > &, const RankTwoTensorTempl< T > &) const
 Calculates C_mntl A_im B_jn C_kt.
 
RankFourTensorTempl< T > singleProductI (const RankTwoTensorTempl< T > &) const
 Calculates C_mjkl A_im.
 
RankFourTensorTempl< T > singleProductJ (const RankTwoTensorTempl< T > &) const
 Calculates C_imkl A_jm.
 
RankFourTensorTempl< T > singleProductK (const RankTwoTensorTempl< T > &) const
 Calculates C_ijml A_km.
 
RankFourTensorTempl< T > singleProductL (const RankTwoTensorTempl< T > &) const
 Calculates C_ijkm A_lm.
 
bool isSymmetric () const
 checks if the tensor is symmetric
 
bool isIsotropic () const
 checks if the tensor is isotropic
 
RankFourTensorTempl< Real > invSymm () const
 
void fillGeneralIsotropic (const T &i0, const T &i1, const T &i2)
 Vector-less fill API functions. See docs of the corresponding ...FromInputVector methods.
 
void fillAntisymmetricIsotropic (const T &i0)
 
void fillSymmetricIsotropic (const T &i0, const T &i1)
 
void fillSymmetricIsotropicEandNu (const T &E, const T &nu)
 

Static Public Member Functions

static RankFourTensorTempl< T > Identity ()
 
static RankFourTensorTempl< T > IdentityFour ()
 
static RankFourTensorTempl< T > IdentityDeviatoric ()
 Identity of type \delta_{ik} \delta_{jl} - \delta_{ij} \delta_{kl} / 3.
 
static MooseEnum fillMethodEnum ()
 Static method for use in validParams for getting the "fill_method".
 

Static Public Attributes

static constexpr unsigned int N = Moose::dim
 tensor dimension and powers of the dimension
 
static constexpr unsigned int N2 = N * N
 
static constexpr unsigned int N3 = N * N * N
 
static constexpr unsigned int N4 = N * N * N * N
 

Protected Member Functions

void fillAntisymmetricFromInputVector (const std::vector< T > &input)
 fillAntisymmetricFromInputVector takes 6 inputs to fill the the antisymmetric Rank-4 tensor with the appropriate symmetries maintained.
 
void fillGeneralIsotropicFromInputVector (const std::vector< T > &input)
 fillGeneralIsotropicFromInputVector takes 3 inputs to fill the Rank-4 tensor with symmetries C_ijkl = C_klij, and isotropy, ie C_ijkl = la*de_ij*de_kl + mu*(de_ik*de_jl + de_il*de_jk) + a*ep_ijm*ep_klm where la is the first Lame modulus, mu is the second (shear) Lame modulus, and a is the antisymmetric shear modulus, and ep is the permutation tensor
 
void fillAntisymmetricIsotropicFromInputVector (const std::vector< T > &input)
 fillAntisymmetricIsotropicFromInputVector takes 1 input to fill the the antisymmetric Rank-4 tensor with the appropriate symmetries maintained.
 
void fillSymmetricIsotropicFromInputVector (const std::vector< T > &input)
 fillSymmetricIsotropicFromInputVector takes 2 inputs to fill the the symmetric Rank-4 tensor with the appropriate symmetries maintained.
 
void fillSymmetricIsotropicEandNuFromInputVector (const std::vector< T > &input)
 fillSymmetricIsotropicEandNuFromInputVector is a variation of the fillSymmetricIsotropicFromInputVector which takes as inputs the more commonly used Young's modulus (E) and Poisson's ratio (nu) constants to fill the isotropic elasticity tensor.
 
void fillAxisymmetricRZFromInputVector (const std::vector< T > &input)
 fillAxisymmetricRZFromInputVector takes 5 inputs to fill the axisymmetric Rank-4 tensor with the appropriate symmetries maintatined for use with axisymmetric problems using coord_type = RZ.
 
void fillGeneralFromInputVector (const std::vector< T > &input)
 fillGeneralFromInputVector takes 81 inputs to fill the Rank-4 tensor No symmetries are explicitly maintained
 
void fillPrincipalFromInputVector (const std::vector< T > &input)
 fillPrincipalFromInputVector takes 9 inputs to fill a Rank-4 tensor C1111 = input0 C1122 = input1 C1133 = input2 C2211 = input3 C2222 = input4 C2233 = input5 C3311 = input6 C3322 = input7 C3333 = input8 with all other components being zero
 
void fillGeneralOrthotropicFromInputVector (const std::vector< T > &input)
 fillGeneralOrhotropicFromInputVector takes 10 inputs to fill the Rank-4 tensor It defines a general orthotropic tensor for which some constraints among elastic parameters exist
 

Protected Attributes

_vals [N4]
 The values of the rank-four tensor stored by index=(((i * LIBMESH_DIM + j) * LIBMESH_DIM + k) * LIBMESH_DIM + l)
 

Friends

template<typename T2 >
class RankTwoTensorTempl
 
template<typename T2 >
class RankFourTensorTempl
 
template<typename T2 >
class RankThreeTensorTempl
 
std::ostream & operator<< (std::ostream &os, const RankFourTensorTempl< T > &t)
 
template<class T2 >
void dataStore (std::ostream &, RankFourTensorTempl< T2 > &, void *)
 
template<class T2 >
void dataLoad (std::istream &, RankFourTensorTempl< T2 > &, void *)
 

Detailed Description

template<typename T>
class RankFourTensorTempl< T >

RankFourTensorTempl is designed to handle any N-dimensional fourth order tensor, C.

Since N is hard-coded to 3, RankFourTensorTempl holds 81 separate C_ijkl entries, with i,j,k,l = 0, 1, 2.

Definition at line 65 of file RankFourTensor.h.

Member Typedef Documentation

◆ index_type

template<typename T >
typedef tuple_of<4, unsigned int> RankFourTensorTempl< T >::index_type

Definition at line 75 of file RankFourTensor.h.

◆ value_type

template<typename T >
typedef T RankFourTensorTempl< T >::value_type

Definition at line 76 of file RankFourTensor.h.

Member Enumeration Documentation

◆ FillMethod

template<typename T >
enum RankFourTensorTempl::FillMethod

To fill up the 81 entries in the 4th-order tensor, fillFromInputVector is called with one of the following fill_methods.

See the fill*FromInputVector functions for more details

Enumerator
antisymmetric 
symmetric9 
symmetric21 
general_isotropic 
symmetric_isotropic 
symmetric_isotropic_E_nu 
antisymmetric_isotropic 
axisymmetric_rz 
general 
principal 
orthotropic 

Definition at line 93 of file RankFourTensor.h.

◆ InitMethod

template<typename T >
enum RankFourTensorTempl::InitMethod

Initialization method.

Enumerator
initNone 
initIdentity 
initIdentityFour 
initIdentitySymmetricFour 
initIdentityDeviatoric 

Definition at line 79 of file RankFourTensor.h.

Constructor & Destructor Documentation

◆ RankFourTensorTempl() [1/6]

template<typename T >
RankFourTensorTempl< T >::RankFourTensorTempl ( )

Default constructor; fills to zero.

Definition at line 52 of file RankFourTensorImplementation.h.

53{
54 mooseAssert(N == 3, "RankFourTensorTempl<T> is currently only tested for 3 dimensions.");
55
56 for (auto i : make_range(N4))
57 _vals[i] = 0.0;
58}
static constexpr unsigned int N4
T _vals[N4]
The values of the rank-four tensor stored by index=(((i * LIBMESH_DIM + j) * LIBMESH_DIM + k) * LIBME...
static constexpr unsigned int N
tensor dimension and powers of the dimension
IntRange< T > make_range(T beg, T end)

◆ RankFourTensorTempl() [2/6]

template<typename T >
RankFourTensorTempl< T >::RankFourTensorTempl ( const InitMethod  init)

Select specific initialization pattern.

Definition at line 61 of file RankFourTensorImplementation.h.

62{
63 unsigned int index = 0;
64 switch (init)
65 {
66 case initNone:
67 break;
68
69 case initIdentity:
70 zero();
71 for (auto i : make_range(N))
72 (*this)(i, i, i, i) = 1.0;
73 break;
74
76 for (auto i : make_range(N))
77 for (auto j : make_range(N))
78 for (auto k : make_range(N))
79 for (auto l : make_range(N))
80 _vals[index++] = Real(i == k && j == l);
81 break;
82
84 for (auto i : make_range(N))
85 for (auto j : make_range(N))
86 for (auto k : make_range(N))
87 for (auto l : make_range(N))
88 _vals[index++] = 0.5 * Real(i == k && j == l) + 0.5 * Real(i == l && j == k);
89 break;
90
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)
96 {
97 _vals[index] = Real(i == k && j == l);
98 if ((i == j) && (k == l))
99 _vals[index] -= 1.0 / 3.0;
100 index++;
101 }
102 break;
103
104 default:
105 mooseError("Unknown RankFourTensorTempl<T> initialization pattern.");
106 }
107}
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
for(PetscInt i=0;i< nvars;++i)
void zero()
Zeros out the tensor.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real

◆ RankFourTensorTempl() [3/6]

template<typename T >
RankFourTensorTempl< T >::RankFourTensorTempl ( const std::vector< T > &  input,
FillMethod  fill_method 
)

Fill from vector.

Definition at line 110 of file RankFourTensorImplementation.h.

111{
112 fillFromInputVector(input, fill_method);
113}
void fillFromInputVector(const std::vector< T > &input, FillMethod fill_method)
fillFromInputVector takes some number of inputs to fill the Rank-4 tensor.

◆ RankFourTensorTempl() [4/6]

template<typename T >
RankFourTensorTempl< T >::RankFourTensorTempl ( const RankFourTensorTempl< T > &  a)
default

Copy assignment operator must be defined if used.

◆ RankFourTensorTempl() [5/6]

template<typename T >
template<typename T2 >
RankFourTensorTempl< T >::RankFourTensorTempl ( const RankFourTensorTempl< T2 > &  copy)

Copy constructor.

Definition at line 570 of file RankFourTensor.h.

571{
572 for (auto i : libMesh::make_range(N4))
573 _vals[i] = copy._vals[i];
574}
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...

◆ RankFourTensorTempl() [6/6]

template<typename T >
template<typename T2 >
RankFourTensorTempl< T >::RankFourTensorTempl ( const SymmetricRankFourTensorTempl< T2 > &  t)
inline

The conversion operator from a SymmetricRankFourTensorTempl

Definition at line 151 of file RankFourTensor.h.

152 {
153 for (const auto a : make_range(SymmetricRankFourTensorTempl<T2>::N))
154 for (const auto b : make_range(SymmetricRankFourTensorTempl<T2>::N))
155 {
157 const auto i = idx[0];
158 const auto j = idx[1];
159 const auto k = idx[2];
160 const auto l = idx[3];
161
162 // Rijkl = Rjikl = Rijlk = Rjilk
163 (*this)(i, j, k, l) = t(a, b) / SymmetricRankFourTensorTempl<T2>::mandelFactor(a, b);
164 (*this)(j, i, k, l) = t(a, b) / SymmetricRankFourTensorTempl<T2>::mandelFactor(a, b);
165 (*this)(i, j, l, k) = t(a, b) / SymmetricRankFourTensorTempl<T2>::mandelFactor(a, b);
166 (*this)(j, i, l, k) = t(a, b) / SymmetricRankFourTensorTempl<T2>::mandelFactor(a, b);
167 }
168 }
SymmetricRankFourTensorTempl is designed to handle an N-dimensional fourth order tensor with minor sy...
static constexpr Real mandelFactor(unsigned int i, unsigned int j)
returns the 1, sqrt(2), or 2 prefactor in the Mandel notation for the indices i,j ranging from 0-5.
unsigned int idx(const ElemType type, const unsigned int nx, const unsigned int i, const unsigned int j)

Member Function Documentation

◆ contraction()

template<typename T >
template<int m>
RankThreeTensorTempl< T > RankFourTensorTempl< T >::contraction ( const libMesh::VectorValue< T > &  b) const

single contraction of a RankFourTensor with a vector over index m

Returns
C_xxx = a_ijkl*b_m where m={i,j,k,l} and xxx the remaining indices

Definition at line 789 of file RankFourTensor.h.

790{
792 static constexpr std::size_t z[4][3] = {{1, 2, 3}, {0, 2, 3}, {0, 1, 3}, {0, 1, 2}};
793 std::size_t x[4];
794 for (x[0] = 0; x[0] < N; ++x[0])
795 for (x[1] = 0; x[1] < N; ++x[1])
796 for (x[2] = 0; x[2] < N; ++x[2])
797 for (x[3] = 0; x[3] < N; ++x[3])
798 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]);
799
800 return result;
801}
RankThreeTensor is designed to handle any N-dimensional third order tensor, r.

◆ contractionIj()

template<typename T >
T RankFourTensorTempl< T >::contractionIj ( unsigned int  i,
unsigned int  j,
const RankTwoTensorTempl< T > &  M 
) const

Sum C_ijkl M_kl for a given i,j.

Definition at line 917 of file RankFourTensorImplementation.h.

920{
921 T val = 0;
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);
925
926 return val;
927}

◆ contractionKl()

template<typename T >
T RankFourTensorTempl< T >::contractionKl ( unsigned int  k,
unsigned int  l,
const RankTwoTensorTempl< T > &  M 
) const

Sum M_ij C_ijkl for a given k,l.

Definition at line 931 of file RankFourTensorImplementation.h.

934{
935 T val = 0;
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);
939
940 return val;
941}

◆ fillAntisymmetricFromInputVector()

template<typename T >
void RankFourTensorTempl< T >::fillAntisymmetricFromInputVector ( const std::vector< T > &  input)
protected

fillAntisymmetricFromInputVector takes 6 inputs to fill the the antisymmetric Rank-4 tensor with the appropriate symmetries maintained.

I.e., B_ijkl = -B_jikl = -B_ijlk = B_klij

Parameters
inputthis is B1212, B1213, B1223, B1313, B1323, B2323.

Definition at line 621 of file RankFourTensorImplementation.h.

622{
623 if (input.size() != 6)
625 "To use fillAntisymmetricFromInputVector, your input must have size 6. Yours has size ",
626 input.size());
627
628 zero();
629
630 (*this)(0, 1, 0, 1) = input[0]; // B1212
631 (*this)(0, 1, 0, 2) = input[1]; // B1213
632 (*this)(0, 1, 1, 2) = input[2]; // B1223
633
634 (*this)(0, 2, 0, 2) = input[3]; // B1313
635 (*this)(0, 2, 1, 2) = input[4]; // B1323
636
637 (*this)(1, 2, 1, 2) = input[5]; // B2323
638
639 // symmetry on the two pairs
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);
643 // have now got the upper parts of vals[0][1], vals[0][2] and vals[1][2]
644
645 // fill in from antisymmetry relations
646 for (auto i : make_range(N))
647 for (auto j : make_range(N))
648 {
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);
652 }
653 // have now got all of vals[0][1], vals[0][2] and vals[1][2]
654
655 // fill in from antisymmetry relations
656 for (auto i : make_range(N))
657 for (auto j : make_range(N))
658 {
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);
662 }
663}

◆ fillAntisymmetricIsotropic()

template<typename T >
void RankFourTensorTempl< T >::fillAntisymmetricIsotropic ( const T &  i0)

Definition at line 708 of file RankFourTensorImplementation.h.

709{
710 fillGeneralIsotropic(0.0, 0.0, i0);
711}
void fillGeneralIsotropic(const T &i0, const T &i1, const T &i2)
Vector-less fill API functions. See docs of the corresponding ...FromInputVector methods.

◆ fillAntisymmetricIsotropicFromInputVector()

template<typename T >
void RankFourTensorTempl< T >::fillAntisymmetricIsotropicFromInputVector ( const std::vector< T > &  input)
protected

fillAntisymmetricIsotropicFromInputVector takes 1 input to fill the the antisymmetric Rank-4 tensor with the appropriate symmetries maintained.

I.e., C_ijkl = a * ep_ijm * ep_klm, where epsilon is the permutation tensor (and sum on m)

Parameters
inputthis is a in the above formula

Definition at line 696 of file RankFourTensorImplementation.h.

697{
698 if (input.size() != 1)
699 mooseError("To use fillAntisymmetricIsotropicFromInputVector, your input must have size 1. "
700 "Yours has size ",
701 input.size());
702
703 fillGeneralIsotropic(0.0, 0.0, input[0]);
704}

◆ fillAxisymmetricRZFromInputVector()

template<typename T >
void RankFourTensorTempl< T >::fillAxisymmetricRZFromInputVector ( const std::vector< T > &  input)
protected

fillAxisymmetricRZFromInputVector takes 5 inputs to fill the axisymmetric Rank-4 tensor with the appropriate symmetries maintatined for use with axisymmetric problems using coord_type = RZ.

I.e. C1111 = C2222, C1133 = C2233, C2323 = C3131 and C1212 = 0.5*(C1111-C1122)

Parameters
inputthis is C1111, C1122, C1133, C3333, C2323.

Definition at line 763 of file RankFourTensorImplementation.h.

764{
765 mooseAssert(input.size() == 5,
766 "To use fillAxisymmetricRZFromInputVector, your input must have size 5.");
767
768 // C1111 C1122 C1133 0 0 0
769 // C2222 C2233=C1133 0 0 0
770 // C3333 0 0 0
771 // C2323 0 0
772 // C3131=C2323 0
773 // C1212
774 // clang-format off
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,
779 input[4], 0.0, 0.0,
780 input[4], 0.0,
781 (input[0] - input[1]) * 0.5}});
782 // clang-format on
783}
void fillSymmetric21FromInputVector(const T2 &input)
fillSymmetric21FromInputVector takes either 21 inputs to fill in the Rank-4 tensor with the appropria...

◆ fillFromInputVector()

template<typename T >
void RankFourTensorTempl< T >::fillFromInputVector ( const std::vector< T > &  input,
FillMethod  fill_method 
)

fillFromInputVector takes some number of inputs to fill the Rank-4 tensor.

Parameters
inputthe numbers that will be placed in the tensor
fill_methodthis can be: antisymmetric (use fillAntisymmetricFromInputVector) symmetric9 (use fillSymmetric9FromInputVector) symmetric21 (use fillSymmetric21FromInputVector) general_isotropic (use fillGeneralIsotropicFrominputVector) symmetric_isotropic (use fillSymmetricIsotropicFromInputVector) antisymmetric_isotropic (use fillAntisymmetricIsotropicFromInputVector) axisymmetric_rz (use fillAxisymmetricRZFromInputVector) general (use fillGeneralFromInputVector) principal (use fillPrincipalFromInputVector)

Definition at line 576 of file RankFourTensorImplementation.h.

577{
578
579 switch (fill_method)
580 {
581 case antisymmetric:
583 break;
584 case symmetric9:
586 break;
587 case symmetric21:
589 break;
592 break;
595 break;
598 break;
601 break;
602 case axisymmetric_rz:
604 break;
605 case general:
607 break;
608 case principal:
610 break;
611 case orthotropic:
613 break;
614 default:
615 mooseError("fillFromInputVector called with unknown fill_method of ", fill_method);
616 }
617}
void fillGeneralOrthotropicFromInputVector(const std::vector< T > &input)
fillGeneralOrhotropicFromInputVector takes 10 inputs to fill the Rank-4 tensor It defines a general o...
void fillSymmetric9FromInputVector(const T2 &input)
fillSymmetric9FromInputVector takes 9 inputs to fill in the Rank-4 tensor with the appropriate crysta...
void fillGeneralIsotropicFromInputVector(const std::vector< T > &input)
fillGeneralIsotropicFromInputVector takes 3 inputs to fill the Rank-4 tensor with symmetries C_ijkl =...
void fillAntisymmetricIsotropicFromInputVector(const std::vector< T > &input)
fillAntisymmetricIsotropicFromInputVector takes 1 input to fill the the antisymmetric Rank-4 tensor w...
void fillPrincipalFromInputVector(const std::vector< T > &input)
fillPrincipalFromInputVector takes 9 inputs to fill a Rank-4 tensor C1111 = input0 C1122 = input1 C11...
void fillSymmetricIsotropicEandNuFromInputVector(const std::vector< T > &input)
fillSymmetricIsotropicEandNuFromInputVector is a variation of the fillSymmetricIsotropicFromInputVect...
void fillSymmetricIsotropicFromInputVector(const std::vector< T > &input)
fillSymmetricIsotropicFromInputVector takes 2 inputs to fill the the symmetric Rank-4 tensor with the...
void fillGeneralFromInputVector(const std::vector< T > &input)
fillGeneralFromInputVector takes 81 inputs to fill the Rank-4 tensor No symmetries are explicitly mai...
void fillAxisymmetricRZFromInputVector(const std::vector< T > &input)
fillAxisymmetricRZFromInputVector takes 5 inputs to fill the axisymmetric Rank-4 tensor with the appr...
void fillAntisymmetricFromInputVector(const std::vector< T > &input)
fillAntisymmetricFromInputVector takes 6 inputs to fill the the antisymmetric Rank-4 tensor with the ...

◆ fillGeneralFromInputVector()

template<typename T >
void RankFourTensorTempl< T >::fillGeneralFromInputVector ( const std::vector< T > &  input)
protected

fillGeneralFromInputVector takes 81 inputs to fill the Rank-4 tensor No symmetries are explicitly maintained

Parameters
inputC(i,j,k,l) = input[i*N*N*N + j*N*N + k*N + l]

Definition at line 787 of file RankFourTensorImplementation.h.

788{
789 if (input.size() != 81)
790 mooseError("To use fillGeneralFromInputVector, your input must have size 81. Yours has size ",
791 input.size());
792
793 for (auto i : make_range(N4))
794 _vals[i] = input[i];
795}

◆ fillGeneralIsotropic()

template<typename T >
void RankFourTensorTempl< T >::fillGeneralIsotropic ( const T &  i0,
const T &  i1,
const T &  i2 
)

Vector-less fill API functions. See docs of the corresponding ...FromInputVector methods.

Definition at line 679 of file RankFourTensorImplementation.h.

680{
681 for (auto i : make_range(N))
682 for (auto j : make_range(N))
683 for (auto k : make_range(N))
684 for (auto l : make_range(N))
685 {
686 (*this)(i, j, k, l) = i0 * Real(i == j) * Real(k == l) +
687 i1 * Real(i == k) * Real(j == l) + i1 * Real(i == l) * Real(j == k);
688 for (auto m : make_range(N))
689 (*this)(i, j, k, l) +=
690 i2 * Real(PermutationTensor::eps(i, j, m)) * Real(PermutationTensor::eps(k, l, m));
691 }
692}
Utility functions to return the permutation pseudo tensor in 2D, 3D or 4D.
int eps(unsigned int i, unsigned int j)
2D version

◆ fillGeneralIsotropicFromInputVector()

template<typename T >
void RankFourTensorTempl< T >::fillGeneralIsotropicFromInputVector ( const std::vector< T > &  input)
protected

fillGeneralIsotropicFromInputVector takes 3 inputs to fill the Rank-4 tensor with symmetries C_ijkl = C_klij, and isotropy, ie C_ijkl = la*de_ij*de_kl + mu*(de_ik*de_jl + de_il*de_jk) + a*ep_ijm*ep_klm where la is the first Lame modulus, mu is the second (shear) Lame modulus, and a is the antisymmetric shear modulus, and ep is the permutation tensor

Parameters
inputthis is la, mu, a in the above formula

Definition at line 667 of file RankFourTensorImplementation.h.

668{
669 if (input.size() != 3)
670 mooseError("To use fillGeneralIsotropicFromInputVector, your input must have size 3. Yours "
671 "has size ",
672 input.size());
673
674 fillGeneralIsotropic(input[0], input[1], input[2]);
675}

◆ fillGeneralOrthotropicFromInputVector()

template<typename T >
void RankFourTensorTempl< T >::fillGeneralOrthotropicFromInputVector ( const std::vector< T > &  input)
protected

fillGeneralOrhotropicFromInputVector takes 10 inputs to fill the Rank-4 tensor It defines a general orthotropic tensor for which some constraints among elastic parameters exist

Parameters
inputEa, Eb, Ec, Gab, Gbc, Gca, nuba, nuca, nucb, nuab, nuac, nubc

Definition at line 820 of file RankFourTensorImplementation.h.

821{
822 if (input.size() != 12)
823 mooseError("To use fillGeneralOrhotropicFromInputVector, your input must have size 12. Yours "
824 "has size ",
825 input.size());
826
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];
839
840 // Input must satisfy constraints.
841 bool preserve_symmetry = MooseUtils::relativeFuzzyEqual(nuab * Eb, nuba * Ea) &&
842 MooseUtils::relativeFuzzyEqual(nuca * Ea, nuac * Ec) &&
843 MooseUtils::relativeFuzzyEqual(nubc * Ec, nucb * Eb);
844
845 if (!preserve_symmetry)
846 mooseError("Orthotropic elasticity tensor input is not consistent with symmetry requirements. "
847 "Check input for accuracy");
848
849 unsigned int ntens = N * (N + 1) / 2;
850
851 std::vector<T> mat;
852 mat.assign(ntens * ntens, 0);
853
854 T k = 1 - nuab * nuba - nubc * nucb - nuca * nuac - nuab * nubc * nuca - nuba * nucb * nuac;
855
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 "
860 "accuracy");
861
862 mat[0] = Ea * (1 - nubc * nucb) / k;
863 mat[1] = Ea * (nubc * nuca + nuba) / k;
864 mat[2] = Ea * (nuba * nucb + nuca) / k;
865
866 mat[6] = Eb * (nuac * nucb + nuab) / k;
867 mat[7] = Eb * (1 - nuac * nuca) / k;
868 mat[8] = Eb * (nuab * nuca + nucb) / k;
869
870 mat[12] = Ec * (nuab * nubc + nuac) / k;
871 mat[13] = Ec * (nuac * nuba + nubc) / k;
872 mat[14] = Ec * (1 - nuab * nuba) / k;
873
874 mat[21] = 2 * Gab;
875 mat[28] = 2 * Gca;
876 mat[35] = 2 * Gbc;
877
878 // Switching from Voigt to fourth order tensor
879 // Copied from existing code (invSymm)
880 int nskip = N - 1;
881
882 unsigned int index = 0;
883 for (auto i : make_range(N))
884 for (auto j : make_range(N))
885 for (auto k : make_range(N))
886 for (auto l : make_range(N))
887 {
888 if (i == j)
889 (*this)._vals[index] =
890 k == l ? mat[i * ntens + k] : mat[i * ntens + k + nskip + l] / 2.0;
891 else
892 (*this)._vals[index] = k == l ? mat[(nskip + i + j) * ntens + k]
893 : mat[(nskip + i + j) * ntens + k + nskip + l] / 2.0;
894 index++;
895 }
896}

◆ fillMethodEnum()

template<typename T >
MooseEnum RankFourTensorTempl< T >::fillMethodEnum ( )
static

Static method for use in validParams for getting the "fill_method".

Definition at line 44 of file RankFourTensorImplementation.h.

45{
46 return MooseEnum("antisymmetric symmetric9 symmetric21 general_isotropic symmetric_isotropic "
47 "symmetric_isotropic_E_nu antisymmetric_isotropic axisymmetric_rz general "
48 "principal orthotropic");
49}
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition MooseEnum.h:55

◆ fillPrincipalFromInputVector()

template<typename T >
void RankFourTensorTempl< T >::fillPrincipalFromInputVector ( const std::vector< T > &  input)
protected

fillPrincipalFromInputVector takes 9 inputs to fill a Rank-4 tensor C1111 = input0 C1122 = input1 C1133 = input2 C2211 = input3 C2222 = input4 C2233 = input5 C3311 = input6 C3322 = input7 C3333 = input8 with all other components being zero

Definition at line 799 of file RankFourTensorImplementation.h.

800{
801 if (input.size() != 9)
802 mooseError("To use fillPrincipalFromInputVector, your input must have size 9. Yours has size ",
803 input.size());
804
805 zero();
806
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];
816}

◆ fillSymmetric21FromInputVector()

template<typename T >
template<typename T2 >
void RankFourTensorTempl< T >::fillSymmetric21FromInputVector ( const T2 &  input)

fillSymmetric21FromInputVector takes either 21 inputs to fill in the Rank-4 tensor with the appropriate crystal symmetries maintained.

I.e., C_ijkl = C_klij, C_ijkl = C_ijlk, C_ijkl = C_jikl

Parameters
inputis C1111 C1122 C1133 C1123 C1113 C1112 C2222 C2233 C2223 C2213 C2212 C3333 C3323 C3313 C3312 C2323 C2313 C2312 C1313 C1312 C1212

Definition at line 645 of file RankFourTensor.h.

646{
647 mooseAssert(input.size() == 21,
648 "To use fillSymmetric21FromInputVector, your input must have size 21.");
649
650 (*this)(0, 0, 0, 0) = input[0]; // C1111
651 (*this)(1, 1, 1, 1) = input[6]; // C2222
652 (*this)(2, 2, 2, 2) = input[11]; // C3333
653
654 (*this)(0, 0, 1, 1) = input[1]; // C1122
655 (*this)(1, 1, 0, 0) = input[1];
656
657 (*this)(0, 0, 2, 2) = input[2]; // C1133
658 (*this)(2, 2, 0, 0) = input[2];
659
660 (*this)(1, 1, 2, 2) = input[7]; // C2233
661 (*this)(2, 2, 1, 1) = input[7];
662
663 (*this)(0, 0, 0, 2) = input[4]; // C1113
664 (*this)(0, 0, 2, 0) = input[4];
665 (*this)(0, 2, 0, 0) = input[4];
666 (*this)(2, 0, 0, 0) = input[4];
667
668 (*this)(0, 0, 0, 1) = input[5]; // C1112
669 (*this)(0, 0, 1, 0) = input[5];
670 (*this)(0, 1, 0, 0) = input[5];
671 (*this)(1, 0, 0, 0) = input[5];
672
673 (*this)(1, 1, 1, 2) = input[8]; // C2223
674 (*this)(1, 1, 2, 1) = input[8];
675 (*this)(1, 2, 1, 1) = input[8];
676 (*this)(2, 1, 1, 1) = input[8];
677
678 (*this)(1, 1, 1, 0) = input[10];
679 (*this)(1, 1, 0, 1) = input[10];
680 (*this)(1, 0, 1, 1) = input[10];
681 (*this)(0, 1, 1, 1) = input[10]; // C2212 //flipped for filling purposes
682
683 (*this)(2, 2, 2, 1) = input[12];
684 (*this)(2, 2, 1, 2) = input[12];
685 (*this)(2, 1, 2, 2) = input[12];
686 (*this)(1, 2, 2, 2) = input[12]; // C3323 //flipped for filling purposes
687
688 (*this)(2, 2, 2, 0) = input[13];
689 (*this)(2, 2, 0, 2) = input[13];
690 (*this)(2, 0, 2, 2) = input[13];
691 (*this)(0, 2, 2, 2) = input[13]; // C3313 //flipped for filling purposes
692
693 (*this)(0, 0, 1, 2) = input[3]; // C1123
694 (*this)(0, 0, 2, 1) = input[3];
695 (*this)(1, 2, 0, 0) = input[3];
696 (*this)(2, 1, 0, 0) = input[3];
697
698 (*this)(1, 1, 0, 2) = input[9];
699 (*this)(1, 1, 2, 0) = input[9];
700 (*this)(0, 2, 1, 1) = input[9]; // C2213 //flipped for filling purposes
701 (*this)(2, 0, 1, 1) = input[9];
702
703 (*this)(2, 2, 0, 1) = input[14];
704 (*this)(2, 2, 1, 0) = input[14];
705 (*this)(0, 1, 2, 2) = input[14]; // C3312 //flipped for filling purposes
706 (*this)(1, 0, 2, 2) = input[14];
707
708 (*this)(1, 2, 1, 2) = input[15]; // C2323
709 (*this)(2, 1, 2, 1) = input[15];
710 (*this)(2, 1, 1, 2) = input[15];
711 (*this)(1, 2, 2, 1) = input[15];
712
713 (*this)(0, 2, 0, 2) = input[18]; // C1313
714 (*this)(2, 0, 2, 0) = input[18];
715 (*this)(2, 0, 0, 2) = input[18];
716 (*this)(0, 2, 2, 0) = input[18];
717
718 (*this)(0, 1, 0, 1) = input[20]; // C1212
719 (*this)(1, 0, 1, 0) = input[20];
720 (*this)(1, 0, 0, 1) = input[20];
721 (*this)(0, 1, 1, 0) = input[20];
722
723 (*this)(1, 2, 0, 2) = input[16];
724 (*this)(0, 2, 1, 2) = input[16]; // C2313 //flipped for filling purposes
725 (*this)(2, 1, 0, 2) = input[16];
726 (*this)(1, 2, 2, 0) = input[16];
727 (*this)(2, 0, 1, 2) = input[16];
728 (*this)(0, 2, 2, 1) = input[16];
729 (*this)(2, 1, 2, 0) = input[16];
730 (*this)(2, 0, 2, 1) = input[16];
731
732 (*this)(1, 2, 0, 1) = input[17];
733 (*this)(0, 1, 1, 2) = input[17]; // C2312 //flipped for filling purposes
734 (*this)(2, 1, 0, 1) = input[17];
735 (*this)(1, 2, 1, 0) = input[17];
736 (*this)(1, 0, 1, 2) = input[17];
737 (*this)(0, 1, 2, 1) = input[17];
738 (*this)(2, 1, 1, 0) = input[17];
739 (*this)(1, 0, 2, 1) = input[17];
740
741 (*this)(0, 2, 0, 1) = input[19];
742 (*this)(0, 1, 0, 2) = input[19]; // C1312 //flipped for filling purposes
743 (*this)(2, 0, 0, 1) = input[19];
744 (*this)(0, 2, 1, 0) = input[19];
745 (*this)(1, 0, 0, 2) = input[19];
746 (*this)(0, 1, 2, 0) = input[19];
747 (*this)(2, 0, 1, 0) = input[19];
748 (*this)(1, 0, 2, 0) = input[19];
749}

◆ fillSymmetric9FromInputVector()

template<typename T >
template<typename T2 >
void RankFourTensorTempl< T >::fillSymmetric9FromInputVector ( const T2 &  input)

fillSymmetric9FromInputVector takes 9 inputs to fill in the Rank-4 tensor with the appropriate crystal symmetries maintained.

I.e., C_ijkl = C_klij, C_ijkl = C_ijlk, C_ijkl = C_jikl

Parameters
inputis: C1111 C1122 C1133 C2222 C2233 C3333 C2323 C1313 C1212 In the isotropic case this is (la is first Lame constant, mu is second (shear) Lame constant) la+2mu la la la+2mu la la+2mu mu mu mu

Definition at line 608 of file RankFourTensor.h.

609{
610 mooseAssert(input.size() == 9,
611 "To use fillSymmetric9FromInputVector, your input must have size 9.");
612 zero();
613
614 (*this)(0, 0, 0, 0) = input[0]; // C1111
615 (*this)(1, 1, 1, 1) = input[3]; // C2222
616 (*this)(2, 2, 2, 2) = input[5]; // C3333
617
618 (*this)(0, 0, 1, 1) = input[1]; // C1122
619 (*this)(1, 1, 0, 0) = input[1];
620
621 (*this)(0, 0, 2, 2) = input[2]; // C1133
622 (*this)(2, 2, 0, 0) = input[2];
623
624 (*this)(1, 1, 2, 2) = input[4]; // C2233
625 (*this)(2, 2, 1, 1) = input[4];
626
627 (*this)(1, 2, 1, 2) = input[6]; // C2323
628 (*this)(2, 1, 2, 1) = input[6];
629 (*this)(2, 1, 1, 2) = input[6];
630 (*this)(1, 2, 2, 1) = input[6];
631
632 (*this)(0, 2, 0, 2) = input[7]; // C1313
633 (*this)(2, 0, 2, 0) = input[7];
634 (*this)(2, 0, 0, 2) = input[7];
635 (*this)(0, 2, 2, 0) = input[7];
636
637 (*this)(0, 1, 0, 1) = input[8]; // C1212
638 (*this)(1, 0, 1, 0) = input[8];
639 (*this)(1, 0, 0, 1) = input[8];
640 (*this)(0, 1, 1, 0) = input[8];
641}

◆ fillSymmetricIsotropic()

template<typename T >
void RankFourTensorTempl< T >::fillSymmetricIsotropic ( const T &  i0,
const T &  i1 
)

Definition at line 724 of file RankFourTensorImplementation.h.

725{
726 // clang-format off
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,
731 G, 0.0, 0.0,
732 G, 0.0,
733 G}});
734 // clang-format on
735}

◆ fillSymmetricIsotropicEandNu()

template<typename T >
void RankFourTensorTempl< T >::fillSymmetricIsotropicEandNu ( const T &  E,
const T &  nu 
)

Definition at line 752 of file RankFourTensorImplementation.h.

753{
754 // Calculate lambda and the shear modulus from the given young's modulus and poisson's ratio
755 const T & lambda = E * nu / ((1.0 + nu) * (1.0 - 2.0 * nu));
756 const T & G = E / (2.0 * (1.0 + nu));
757
758 fillSymmetricIsotropic(lambda, G);
759}
void fillSymmetricIsotropic(const T &i0, const T &i1)

◆ fillSymmetricIsotropicEandNuFromInputVector()

template<typename T >
void RankFourTensorTempl< T >::fillSymmetricIsotropicEandNuFromInputVector ( const std::vector< T > &  input)
protected

fillSymmetricIsotropicEandNuFromInputVector is a variation of the fillSymmetricIsotropicFromInputVector which takes as inputs the more commonly used Young's modulus (E) and Poisson's ratio (nu) constants to fill the isotropic elasticity tensor.

Using well-known formulas, E and nu are used to calculate lambda and mu and then the vector is passed to fillSymmetricIsotropicFromInputVector.

Parameters
inputYoung's modulus (E) and Poisson's ratio (nu)

Definition at line 739 of file RankFourTensorImplementation.h.

740{
741 if (input.size() != 2)
743 "To use fillSymmetricIsotropicEandNuFromInputVector, your input must have size 2. Yours "
744 "has size ",
745 input.size());
746
747 fillSymmetricIsotropicEandNu(input[0], input[1]);
748}
void fillSymmetricIsotropicEandNu(const T &E, const T &nu)

◆ fillSymmetricIsotropicFromInputVector()

template<typename T >
void RankFourTensorTempl< T >::fillSymmetricIsotropicFromInputVector ( const std::vector< T > &  input)
protected

fillSymmetricIsotropicFromInputVector takes 2 inputs to fill the the symmetric Rank-4 tensor with the appropriate symmetries maintained.

C_ijkl = lambda*de_ij*de_kl + mu*(de_ik*de_jl + de_il*de_jk) where lambda is the first Lame modulus, mu is the second (shear) Lame modulus,

Parameters
inputthis is lambda and mu in the above formula

Definition at line 715 of file RankFourTensorImplementation.h.

716{
717 mooseAssert(input.size() == 2,
718 "To use fillSymmetricIsotropicFromInputVector, your input must have size 2.");
719 fillSymmetricIsotropic(input[0], input[1]);
720}

◆ Identity()

template<typename T >
static RankFourTensorTempl< T > RankFourTensorTempl< T >::Identity ( )
inlinestatic

Definition at line 171 of file RankFourTensor.h.

RankFourTensorTempl is designed to handle any N-dimensional fourth order tensor, C.

◆ IdentityDeviatoric()

template<typename T >
static RankFourTensorTempl< T > RankFourTensorTempl< T >::IdentityDeviatoric ( )
inlinestatic

Identity of type \delta_{ik} \delta_{jl} - \delta_{ij} \delta_{kl} / 3.

Definition at line 174 of file RankFourTensor.h.

◆ IdentityFour()

template<typename T >
static RankFourTensorTempl< T > RankFourTensorTempl< T >::IdentityFour ( )
inlinestatic

Definition at line 172 of file RankFourTensor.h.

◆ innerProductTranspose()

template<typename T >
RankTwoTensorTempl< T > RankFourTensorTempl< T >::innerProductTranspose ( const RankTwoTensorTempl< T > &  b) const

Inner product of the major transposed tensor with a rank two tensor.

Definition at line 900 of file RankFourTensorImplementation.h.

901{
903
904 unsigned int index = 0;
905 for (unsigned int ij = 0; ij < N2; ++ij)
906 {
907 T bb = b._coords[ij];
908 for (unsigned int kl = 0; kl < N2; ++kl)
909 result._coords[kl] += _vals[index++] * bb;
910 }
911
912 return result;
913}
static constexpr unsigned int N2
RankTwoTensorTempl is designed to handle the Stress or Strain Tensor for a fully anisotropic material...
T _coords[LIBMESH_DIM *LIBMESH_DIM]

◆ inverse()

template<typename T >
RankFourTensorTempl< T > RankFourTensorTempl< T >::inverse ( ) const

This returns A_ijkl such that C_ijkl*A_klmn = de_im de_jn i.e.

the general rank four inverse

Definition at line 753 of file RankFourTensor.h.

754{
755
756 // The inverse of a 3x3x3x3 in the C_ijkl*A_klmn = de_im de_jn sense is
757 // simply the inverse of the 9x9 matrix of the tensor entries.
758 // So all we need to do is inverse _vals (with the appropriate row-major
759 // storage)
760
762
763 if constexpr (RankFourTensorTempl<T>::N4 * sizeof(T) > EIGEN_STACK_ALLOCATION_LIMIT)
764 {
765 // Allocate on the heap if you're going to exceed the stack size limit
766 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> mat(9, 9);
767 for (auto i : libMesh::make_range(9 * 9))
768 mat(i) = _vals[i];
769
770 mat = mat.inverse();
771
772 for (auto i : libMesh::make_range(9 * 9))
773 result._vals[i] = mat(i);
774 }
775 else
776 {
777 // Allocate on the stack if small enough
778 const Eigen::Map<const Eigen::Matrix<T, 9, 9, Eigen::RowMajor>> mat(&_vals[0]);
779 Eigen::Map<Eigen::Matrix<T, 9, 9, Eigen::RowMajor>> res(&result._vals[0]);
780 res = mat.inverse();
781 }
782
783 return result;
784}

◆ invSymm() [1/2]

template<typename T >
RankFourTensorTempl< T > 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 that C_ijkl = C_jikl = C_ijlk.

Definition at line 281 of file RankFourTensorImplementation.h.

282{
283 mooseError("The invSymm operation calls to LAPACK and only supports plain Real type tensors.");
284}

◆ invSymm() [2/2]

RankFourTensorTempl< Real > RankFourTensorTempl< Real >::invSymm ( ) const

Definition at line 288 of file RankFourTensorImplementation.h.

289{
290 unsigned int ntens = N * (N + 1) / 2;
291 int nskip = N - 1;
292
294 std::vector<PetscScalar> mat;
295 mat.assign(ntens * ntens, 0);
296
297 // We use the LAPACK matrix inversion routine here. Form the matrix
298 //
299 // mat[0] mat[1] mat[2] mat[3] mat[4] mat[5]
300 // mat[6] mat[7] mat[8] mat[9] mat[10] mat[11]
301 // mat[12] mat[13] mat[14] mat[15] mat[16] mat[17]
302 // mat[18] mat[19] mat[20] mat[21] mat[22] mat[23]
303 // mat[24] mat[25] mat[26] mat[27] mat[28] mat[29]
304 // mat[30] mat[31] mat[32] mat[33] mat[34] mat[35]
305 //
306 // This is filled from the indpendent components of C assuming
307 // the symmetry C_ijkl = C_ijlk = C_jikl.
308 //
309 // If there are two rank-four tensors X and Y then the reason for
310 // this filling becomes apparent if we want to calculate
311 // X_ijkl*Y_klmn = Z_ijmn
312 // For denote the "mat" versions of X, Y and Z by x, y and z.
313 // Then
314 // z_ab = x_ac*y_cb
315 // Eg
316 // z_00 = Z_0000 = X_0000*Y_0000 + X_0011*Y_1111 + X_0022*Y_2200 + 2*X_0001*Y_0100 +
317 // 2*X_0002*Y_0200 + 2*X_0012*Y_1200 (the factors of 2 come from the assumed symmetries)
318 // z_03 = 2*Z_0001 = X_0000*2*Y_0001 + X_0011*2*Y_1101 + X_0022*2*Y_2201 + 2*X_0001*2*Y_0101 +
319 // 2*X_0002*2*Y_0201 + 2*X_0012*2*Y_1201
320 // z_22 = 2*Z_0102 = X_0100*2*Y_0002 + X_0111*2*X_1102 + X_0122*2*Y_2202 + 2*X_0101*2*Y_0102 +
321 // 2*X_0102*2*Y_0202 + 2*X_0112*2*Y_1202
322 // Finally, we use LAPACK to find x^-1, and put it back into rank-4 tensor form
323 //
324 // mat[0] = C(0,0,0,0)
325 // mat[1] = C(0,0,1,1)
326 // mat[2] = C(0,0,2,2)
327 // mat[3] = C(0,0,0,1)*2
328 // mat[4] = C(0,0,0,2)*2
329 // mat[5] = C(0,0,1,2)*2
330
331 // mat[6] = C(1,1,0,0)
332 // mat[7] = C(1,1,1,1)
333 // mat[8] = C(1,1,2,2)
334 // mat[9] = C(1,1,0,1)*2
335 // mat[10] = C(1,1,0,2)*2
336 // mat[11] = C(1,1,1,2)*2
337
338 // mat[12] = C(2,2,0,0)
339 // mat[13] = C(2,2,1,1)
340 // mat[14] = C(2,2,2,2)
341 // mat[15] = C(2,2,0,1)*2
342 // mat[16] = C(2,2,0,2)*2
343 // mat[17] = C(2,2,1,2)*2
344
345 // mat[18] = C(0,1,0,0)
346 // mat[19] = C(0,1,1,1)
347 // mat[20] = C(0,1,2,2)
348 // mat[21] = C(0,1,0,1)*2
349 // mat[22] = C(0,1,0,2)*2
350 // mat[23] = C(0,1,1,2)*2
351
352 // mat[24] = C(0,2,0,0)
353 // mat[25] = C(0,2,1,1)
354 // mat[26] = C(0,2,2,2)
355 // mat[27] = C(0,2,0,1)*2
356 // mat[28] = C(0,2,0,2)*2
357 // mat[29] = C(0,2,1,2)*2
358
359 // mat[30] = C(1,2,0,0)
360 // mat[31] = C(1,2,1,1)
361 // mat[32] = C(1,2,2,2)
362 // mat[33] = C(1,2,0,1)*2
363 // mat[34] = C(1,2,0,2)*2
364 // mat[35] = C(1,2,1,2)*2
365
366 unsigned int index = 0;
367 for (auto i : make_range(N))
368 for (auto j : make_range(N))
369 for (auto k : make_range(N))
370 for (auto l : make_range(N))
371 {
372 if (i == j)
373 mat[k == l ? i * ntens + k : i * ntens + k + nskip + l] += _vals[index];
374 else
375 // i!=j
376 mat[k == l ? (nskip + i + j) * ntens + k : (nskip + i + j) * ntens + k + nskip + l] +=
377 _vals[index]; // note the +=, which results in double-counting and is rectified
378 // below
379 index++;
380 }
381
382 for (unsigned int i = 3; i < ntens; ++i)
383 for (auto j : make_range(ntens))
384 mat[i * ntens + j] /= 2.0; // because of double-counting above
385
386 // use LAPACK to find the inverse
387 MatrixTools::inverse(mat, ntens);
388
389 // build the resulting rank-four tensor
390 // using the inverse of the above algorithm
391 index = 0;
392 for (auto i : make_range(N))
393 for (auto j : make_range(N))
394 for (auto k : make_range(N))
395 for (auto l : make_range(N))
396 {
397 if (i == j)
398 result._vals[index] =
399 k == l ? mat[i * ntens + k] : mat[i * ntens + k + nskip + l] / 2.0;
400 else
401 // i!=j
402 result._vals[index] = k == l ? mat[(nskip + i + j) * ntens + k]
403 : mat[(nskip + i + j) * ntens + k + nskip + l] / 2.0;
404 index++;
405 }
406
407 return result;
408}
void inverse(const std::vector< std::vector< Real > > &m, std::vector< std::vector< Real > > &m_inv)
Inverse the dense square matrix m using LAPACK routines.
Definition MatrixTools.C:23

◆ isIsotropic()

template<typename T >
bool RankFourTensorTempl< T >::isIsotropic ( ) const

checks if the tensor is isotropic

Definition at line 1130 of file RankFourTensorImplementation.h.

1131{
1132 // prerequisite is symmetry
1133 if (!isSymmetric())
1134 return false;
1135
1136 // inspect shear components
1137 const T & mu = (*this)(0, 1, 0, 1);
1138 // ...diagonal
1139 if ((*this)(1, 2, 1, 2) != mu || (*this)(2, 0, 2, 0) != mu)
1140 return false;
1141 // ...off-diagonal
1142 if ((*this)(2, 0, 1, 2) != 0.0 || (*this)(0, 1, 1, 2) != 0.0 || (*this)(0, 1, 2, 0) != 0.0)
1143 return false;
1144
1145 // off diagonal blocks in Voigt
1146 for (auto i : make_range(N))
1147 for (auto j : make_range(N))
1148 if (_vals[i * (N3 + N2) + ((j + 1) % N) * N + (j + 2) % N] != 0.0)
1149 return false;
1150
1151 // top left block
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))
1155 return false;
1156 if ((*this)(1, 1, 1, 1) != K1 || (*this)(2, 2, 2, 2) != K1)
1157 return false;
1158 for (auto i : make_range(1u, N))
1159 for (auto j : make_range(i))
1160 if ((*this)(i, i, j, j) != K2)
1161 return false;
1162
1163 return true;
1164}
if(!dmm->_nl) SETERRQ(PETSC_COMM_WORLD
static constexpr unsigned int N3
bool isSymmetric() const
checks if the tensor is symmetric

◆ isSymmetric()

template<typename T >
bool RankFourTensorTempl< T >::isSymmetric ( ) const

checks if the tensor is symmetric

Definition at line 1109 of file RankFourTensorImplementation.h.

1110{
1111 for (auto i : make_range(1u, N))
1112 for (auto j : make_range(i))
1113 for (auto k : make_range(1u, N))
1114 for (auto l : make_range(k))
1115 {
1116 // minor symmetries
1117 if ((*this)(i, j, k, l) != (*this)(j, i, k, l) ||
1118 (*this)(i, j, k, l) != (*this)(i, j, l, k))
1119 return false;
1120
1121 // major symmetry
1122 if ((*this)(i, j, k, l) != (*this)(k, l, i, j))
1123 return false;
1124 }
1125 return true;
1126}

◆ L2norm()

template<typename T >
T RankFourTensorTempl< T >::L2norm ( ) const

sqrt(C_ijkl*C_ijkl)

Definition at line 268 of file RankFourTensorImplementation.h.

269{
270 T l2 = 0;
271
272 for (auto i : make_range(N4))
273 l2 += Utility::pow<2>(_vals[i]);
274
275 using std::sqrt;
276 return sqrt(l2);
277}
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template * sqrt(_arg)) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(tanh
T pow(const T &x)

◆ operator()() [1/2]

template<typename T >
T & RankFourTensorTempl< T >::operator() ( unsigned int  i,
unsigned int  j,
unsigned int  k,
unsigned int  l 
)
inline

Gets the value for the indices specified. Takes indices ranging from 0-2 for i, j, k, and l.

Definition at line 180 of file RankFourTensor.h.

181 {
182 return _vals[i * N3 + j * N2 + k * N + l];
183 }

◆ operator()() [2/2]

template<typename T >
const T & RankFourTensorTempl< T >::operator() ( unsigned int  i,
unsigned int  j,
unsigned int  k,
unsigned int  l 
) const
inline

Gets the value for the indices specified.

Takes indices ranging from 0-2 for i, j, k, and l. used for const

Definition at line 189 of file RankFourTensor.h.

190 {
191 return _vals[i * N3 + j * N2 + k * N + l];
192 }

◆ operator*() [1/3]

template<typename T >
template<typename T2 >
auto RankFourTensorTempl< T >::operator* ( const RankFourTensorTempl< T2 > &  a) const -> RankFourTensorTempl<decltype(T() * T2())>

C_ijpq*a_pqkl.

Definition at line 234 of file RankFourTensorImplementation.h.

236{
237 typedef decltype(T() * T2()) ValueType;
239
240 if constexpr (std::is_same_v<T, Real> && std::is_same_v<T2, Real>)
241 {
242 // C_ijkl = A_ijpq B_pqkl. With the row-major flat storage (linear index ij*N2 + kl, where
243 // ij = i*N + j and kl = k*N + l) this is exactly an (N2 x N2) matrix product over the
244 // flattened tensors. Dispatch to Eigen's vectorized kernel instead of the six-deep loop,
245 // which recomputes the flat index via operator() ~3x per innermost iteration.
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;
250 return result;
251 }
252 else
253 {
254 for (auto i : make_range(N))
255 for (auto j : make_range(N))
256 for (auto k : make_range(N))
257 for (auto l : make_range(N))
258 for (auto p : make_range(N))
259 for (auto q : make_range(N))
260 result(i, j, k, l) += (*this)(i, j, p, q) * b(p, q, k, l);
261
262 return result;
263 }
264}

◆ operator*() [2/3]

template<typename T >
template<typename T2 >
auto RankFourTensorTempl< T >::operator* ( const T2 &  a) const -> typename std::enable_if<libMesh::ScalarTraits<T2>::value, RankFourTensorTempl<decltype(T() * T2())>>::type

C_ijkl*a.

Definition at line 579 of file RankFourTensor.h.

582{
583 typedef decltype(T() * T2()) ValueType;
585
586 for (auto i : libMesh::make_range(N4))
587 result._vals[i] = _vals[i] * b;
588
589 return result;
590}

◆ operator*() [3/3]

template<typename T >
template<template< typename > class Tensor, typename T2 >
auto RankFourTensorTempl< T >::operator* ( const Tensor< T2 > &  a) const -> typename std::enable_if<TwoTensorMultTraits<Tensor, T2>::value, RankTwoTensorTempl<decltype(T() * T2())>>::type

C_ijkl*a_kl.

Definition at line 126 of file RankFourTensorImplementation.h.

129{
130 typedef decltype(T() * T2()) ValueType;
132
133 if constexpr (std::is_same_v<T, Real> && std::is_same_v<T2, Real>)
134 {
135 // result_ij = A_ijkl b_kl: an (N2 x N2) . (N2) matvec over the flat storage. Gather b into a
136 // contiguous vector once (b's storage type is generic here), then use Eigen's kernel -- the
137 // scalar loop below re-derives b's index with a div/mod on every inner iteration.
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;
144 return result;
145 }
146 else
147 {
148 unsigned int index = 0;
149 for (unsigned int ij = 0; ij < N2; ++ij)
150 {
151 ValueType tmp = 0;
152 for (unsigned int kl = 0; kl < N2; ++kl)
153 tmp += _vals[index++] * b(kl / LIBMESH_DIM, kl % LIBMESH_DIM);
154 result._coords[ij] = tmp;
155 }
156
157 return result;
158 }
159}

◆ operator*=()

template<typename T >
RankFourTensorTempl< T > & RankFourTensorTempl< T >::operator*= ( const T &  a)

C_ijkl *= a.

Definition at line 163 of file RankFourTensorImplementation.h.

164{
165 for (auto i : make_range(N4))
166 _vals[i] *= a;
167 return *this;
168}

◆ operator+()

template<typename T >
template<typename T2 >
auto RankFourTensorTempl< T >::operator+ ( const RankFourTensorTempl< T2 > &  a) const -> RankFourTensorTempl<decltype(T() + T2())>

C_ijkl + a_ijkl.

Definition at line 191 of file RankFourTensorImplementation.h.

193{
194 RankFourTensorTempl<decltype(T() + T2())> result;
195 for (auto i : make_range(N4))
196 result._vals[i] = _vals[i] + b._vals[i];
197 return result;
198}

◆ operator+=()

template<typename T >
RankFourTensorTempl< T > & RankFourTensorTempl< T >::operator+= ( const RankFourTensorTempl< T > &  a)

C_ijkl += a_ijkl for all i, j, k, l.

Definition at line 181 of file RankFourTensorImplementation.h.

182{
183 for (auto i : make_range(N4))
184 _vals[i] += a._vals[i];
185 return *this;
186}

◆ operator-() [1/2]

template<typename T >
RankFourTensorTempl< T > RankFourTensorTempl< T >::operator- ( ) const

-C_ijkl

Definition at line 223 of file RankFourTensorImplementation.h.

224{
226 for (auto i : make_range(N4))
227 result._vals[i] = -_vals[i];
228 return result;
229}

◆ operator-() [2/2]

template<typename T >
template<typename T2 >
auto RankFourTensorTempl< T >::operator- ( const RankFourTensorTempl< T2 > &  a) const -> RankFourTensorTempl<decltype(T() - T2())>

C_ijkl - a_ijkl.

Definition at line 212 of file RankFourTensorImplementation.h.

214{
215 RankFourTensorTempl<decltype(T() - T2())> result;
216 for (auto i : make_range(N4))
217 result._vals[i] = _vals[i] - b._vals[i];
218 return result;
219}

◆ operator-=()

template<typename T >
RankFourTensorTempl< T > & RankFourTensorTempl< T >::operator-= ( const RankFourTensorTempl< T > &  a)

C_ijkl -= a_ijkl.

Definition at line 202 of file RankFourTensorImplementation.h.

203{
204 for (auto i : make_range(N4))
205 _vals[i] -= a._vals[i];
206 return *this;
207}

◆ operator/()

template<typename T >
template<typename T2 >
auto RankFourTensorTempl< T >::operator/ ( const T2 &  a) const -> typename std::enable_if<libMesh::ScalarTraits<T2>::value, RankFourTensorTempl<decltype(T() / T2())>>::type

C_ijkl/a.

Definition at line 595 of file RankFourTensor.h.

598{
599 RankFourTensorTempl<decltype(T() / T2())> result;
600 for (auto i : libMesh::make_range(N4))
601 result._vals[i] = _vals[i] / b;
602 return result;
603}

◆ operator/=()

template<typename T >
RankFourTensorTempl< T > & RankFourTensorTempl< T >::operator/= ( const T &  a)

C_ijkl /= a for all i, j, k, l.

Definition at line 172 of file RankFourTensorImplementation.h.

173{
174 for (auto i : make_range(N4))
175 _vals[i] /= a;
176 return *this;
177}

◆ operator=() [1/2]

template<typename T >
RankFourTensorTempl< T > & RankFourTensorTempl< T >::operator= ( const RankFourTensorTempl< T > &  a)
default

copies values from a into this tensor

◆ operator=() [2/2]

template<typename T >
template<typename Scalar >
std::enable_if< libMesh::ScalarTraits< Scalar >::value, RankFourTensorTempl & >::type RankFourTensorTempl< T >::operator= ( const Scalar &  libmesh_dbg_varp)
inline

Assignment-from-scalar operator.

Used only to zero out the tensor.

Returns
A reference to *this.

Definition at line 219 of file RankFourTensor.h.

220 {
221 libmesh_assert_equal_to(p, Scalar(0));
222 this->zero();
223 return *this;
224 }

◆ print()

template<typename T >
void RankFourTensorTempl< T >::print ( std::ostream &  stm = Moose::out) const

Print the rank four tensor.

Definition at line 444 of file RankFourTensorImplementation.h.

445{
446 for (auto i : make_range(N))
447 for (auto j : make_range(N))
448 {
449 stm << "i = " << i << " j = " << j << '\n';
450 for (auto k : make_range(N))
451 {
452 for (auto l : make_range(N))
453 stm << std::setw(15) << (*this)(i, j, k, l) << " ";
454
455 stm << '\n';
456 }
457 }
458
459 stm << std::flush;
460}

◆ printReal()

template<typename T >
void RankFourTensorTempl< T >::printReal ( std::ostream &  stm = Moose::out) const

Print the values of the rank four tensor.

Definition at line 464 of file RankFourTensorImplementation.h.

465{
466 for (unsigned int i = 0; i < N; ++i)
467 for (unsigned int j = 0; j < N; ++j)
468 {
469 stm << "i = " << i << " j = " << j << '\n';
470 for (unsigned int k = 0; k < N; ++k)
471 {
472 for (unsigned int l = 0; l < N; ++l)
473 stm << std::setw(15) << MetaPhysicL::raw_value((*this)(i, j, k, l)) << " ";
474
475 stm << '\n';
476 }
477 }
478
479 stm << std::flush;
480}
auto raw_value(const Eigen::Map< T > &in)

◆ rotate()

template<typename T >
void RankFourTensorTempl< T >::rotate ( const TypeTensor< T > &  R)

Rotate the tensor using C_ijkl = R_im R_jn R_ko R_lp C_mnop.

Definition at line 412 of file RankFourTensorImplementation.h.

413{
414 RankFourTensorTempl<T> old = *this;
415
416 unsigned int index = 0;
417 for (auto i : make_range(N))
418 for (auto j : make_range(N))
419 for (auto k : make_range(N))
420 for (auto l : make_range(N))
421 {
422 unsigned int index2 = 0;
423 T sum = 0.0;
424 for (auto m : make_range(N))
425 {
426 const T & a = R(i, m);
427 for (auto n : make_range(N))
428 {
429 const T & ab = a * R(j, n);
430 for (auto o : make_range(N))
431 {
432 const T & abc = ab * R(k, o);
433 for (auto p : make_range(N))
434 sum += abc * R(l, p) * old._vals[index2++];
435 }
436 }
437 }
438 _vals[index++] = sum;
439 }
440}

◆ singleProductI()

template<typename T >
RankFourTensorTempl< T > RankFourTensorTempl< T >::singleProductI ( const RankTwoTensorTempl< T > &  A) const

Calculates C_mjkl A_im.

Definition at line 1045 of file RankFourTensorImplementation.h.

1046{
1048
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);
1055
1056 return R;
1057}

◆ singleProductJ()

template<typename T >
RankFourTensorTempl< T > RankFourTensorTempl< T >::singleProductJ ( const RankTwoTensorTempl< T > &  A) const

Calculates C_imkl A_jm.

Definition at line 1061 of file RankFourTensorImplementation.h.

1062{
1064
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);
1071
1072 return R;
1073}

◆ singleProductK()

template<typename T >
RankFourTensorTempl< T > RankFourTensorTempl< T >::singleProductK ( const RankTwoTensorTempl< T > &  A) const

Calculates C_ijml A_km.

Definition at line 1077 of file RankFourTensorImplementation.h.

1078{
1080
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);
1087
1088 return R;
1089}

◆ singleProductL()

template<typename T >
RankFourTensorTempl< T > RankFourTensorTempl< T >::singleProductL ( const RankTwoTensorTempl< T > &  A) const

Calculates C_ijkm A_lm.

Definition at line 1093 of file RankFourTensorImplementation.h.

1094{
1096
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);
1103
1104 return R;
1105}

◆ sum3x1()

template<typename T >
libMesh::VectorValue< T > RankFourTensorTempl< T >::sum3x1 ( ) const

Calculates the vector a[i] = sum over j Ciijj for i and j varying from 0 to 2.

Definition at line 957 of file RankFourTensorImplementation.h.

958{
959 // used for volumetric locking correction
961 a(0) = (*this)(0, 0, 0, 0) + (*this)(0, 0, 1, 1) + (*this)(0, 0, 2, 2); // C0000 + C0011 + C0022
962 a(1) = (*this)(1, 1, 0, 0) + (*this)(1, 1, 1, 1) + (*this)(1, 1, 2, 2); // C1100 + C1111 + C1122
963 a(2) = (*this)(2, 2, 0, 0) + (*this)(2, 2, 1, 1) + (*this)(2, 2, 2, 2); // C2200 + C2211 + C2222
964 return a;
965}

◆ sum3x3()

template<typename T >
T RankFourTensorTempl< T >::sum3x3 ( ) const

Calculates the sum of Ciijj for i and j varying from 0 to 2.

Definition at line 945 of file RankFourTensorImplementation.h.

946{
947 // used in the volumetric locking correction
948 T sum = 0;
949 for (auto i : make_range(N))
950 for (auto j : make_range(N))
951 sum += (*this)(i, i, j, j);
952 return sum;
953}

◆ surfaceFillFromInputVector()

template<typename T >
void RankFourTensorTempl< T >::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).

Fill method depends on size of input Input size = 2. Then C_1111 = C_2222 = input[0], and C_1122 = input[1], and C_1212 = (input[0]

  • input[1])/2, and C_ijkl = C_jikl = C_ijlk = C_klij, and C_1211 = C_1222 = 0. Input size = 9. Then C_1111 = input[0], C_1112 = input[1], C_1122 = input[3], C_1212 = input[4], C_1222 = input[5], C_1211 = input[6] C_2211 = input[7], C_2212 = input[8], C_2222 = input[9] and C_ijkl = C_jikl = C_ijlk

Definition at line 530 of file RankFourTensorImplementation.h.

531{
532 zero();
533
534 if (input.size() == 9)
535 {
536 // then fill from vector C_1111, C_1112, C_1122, C_1212, C_1222, C_1211, C_2211, C_2212, C_2222
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];
546
547 // fill in remainders from C_ijkl = C_ijlk = C_jikl
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);
555 }
556 else if (input.size() == 2)
557 {
558 // only two independent constants, C_1111 and C_1122
559 (*this)(0, 0, 0, 0) = input[0];
560 (*this)(0, 0, 1, 1) = input[1];
561 // use symmetries
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);
568 }
569 else
570 mooseError("Please provide correct number of inputs for surface RankFourTensorTempl<T> "
571 "initialization.");
572}

◆ transposeIj()

template<typename T >
RankFourTensorTempl< T > RankFourTensorTempl< T >::transposeIj ( ) const

Transpose the tensor by swapping the first two indeces.

Returns
C_jikl

Definition at line 500 of file RankFourTensorImplementation.h.

501{
503
504 for (auto i : make_range(N))
505 for (auto j : make_range(N))
506 for (auto k : make_range(N))
507 for (auto l : make_range(N))
508 result(i, j, k, l) = (*this)(j, i, k, l);
509
510 return result;
511}

◆ transposeKl()

template<typename T >
RankFourTensorTempl< T > RankFourTensorTempl< T >::transposeKl ( ) const

Transpose the tensor by swapping the last two indeces.

Returns
C_ijlk

Definition at line 515 of file RankFourTensorImplementation.h.

516{
518
519 for (auto i : make_range(N))
520 for (auto j : make_range(N))
521 for (auto k : make_range(N))
522 for (auto l : make_range(N))
523 result(i, j, k, l) = (*this)(i, j, l, k);
524
525 return result;
526}

◆ transposeMajor()

template<typename T >
RankFourTensorTempl< T > RankFourTensorTempl< T >::transposeMajor ( ) const

Transpose the tensor by swapping the first pair with the second pair of indices.

Returns
C_klji

Definition at line 484 of file RankFourTensorImplementation.h.

485{
487
488 unsigned int index = 0;
489 for (auto i : make_range(N))
490 for (auto j : make_range(N))
491 for (auto k : make_range(N))
492 for (auto l : make_range(N))
493 result._vals[index++] = _vals[k * N3 + i * N + j + l * N2];
494
495 return result;
496}

◆ tripleProductIjk()

template<typename T >
RankFourTensorTempl< T > RankFourTensorTempl< T >::tripleProductIjk ( const RankTwoTensorTempl< T > &  A,
const RankTwoTensorTempl< T > &  B,
const RankTwoTensorTempl< T > &  C 
) const

Calculates C_mntl A_im B_jn C_kt.

Definition at line 1026 of file RankFourTensorImplementation.h.

1029{
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);
1039
1040 return R;
1041}

◆ tripleProductIjl()

template<typename T >
RankFourTensorTempl< T > RankFourTensorTempl< T >::tripleProductIjl ( const RankTwoTensorTempl< T > &  A,
const RankTwoTensorTempl< T > &  B,
const RankTwoTensorTempl< T > &  C 
) const

Calculates C_mnkt A_im B_jn C_lt.

Definition at line 1007 of file RankFourTensorImplementation.h.

1010{
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);
1020
1021 return R;
1022}

◆ tripleProductIkl()

template<typename T >
RankFourTensorTempl< T > RankFourTensorTempl< T >::tripleProductIkl ( const RankTwoTensorTempl< T > &  A,
const RankTwoTensorTempl< T > &  B,
const RankTwoTensorTempl< T > &  C 
) const

Calculates C_mjnt A_im B_kn C_lt.

Definition at line 988 of file RankFourTensorImplementation.h.

991{
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);
1001
1002 return R;
1003}

◆ tripleProductJkl()

template<typename T >
RankFourTensorTempl< T > RankFourTensorTempl< T >::tripleProductJkl ( const RankTwoTensorTempl< T > &  A,
const RankTwoTensorTempl< T > &  B,
const RankTwoTensorTempl< T > &  C 
) const

Calculates C_imnt A_jm B_kn C_lt.

Definition at line 969 of file RankFourTensorImplementation.h.

972{
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);
982
983 return R;
984}

◆ zero()

template<typename T >
void RankFourTensorTempl< T >::zero ( )

Zeros out the tensor.

Definition at line 117 of file RankFourTensorImplementation.h.

118{
119 for (auto i : make_range(N4))
120 _vals[i] = 0.0;
121}

Referenced by MathUtils::mooseSetToZero< ADRankFourTensor >(), MathUtils::mooseSetToZero< RankFourTensor >(), and RankFourTensorTempl< T >::operator=().

Friends And Related Symbol Documentation

◆ dataLoad

template<typename T >
template<class T2 >
void dataLoad ( std::istream &  ,
RankFourTensorTempl< T2 > &  ,
void *   
)
friend

◆ dataStore

template<typename T >
template<class T2 >
void dataStore ( std::ostream &  ,
RankFourTensorTempl< T2 > &  ,
void *   
)
friend

◆ operator<<

template<typename T >
std::ostream & operator<< ( std::ostream &  os,
const RankFourTensorTempl< T > &  t 
)
friend

Definition at line 200 of file RankFourTensor.h.

201 {
202 t.print(os);
203 return os;
204 }
void print(std::ostream &stm=Moose::out) const
Print the rank four tensor.

◆ RankFourTensorTempl

template<typename T >
template<typename T2 >
friend class RankFourTensorTempl
friend

Definition at line 532 of file RankFourTensor.h.

◆ RankThreeTensorTempl

template<typename T >
template<typename T2 >
friend class RankThreeTensorTempl
friend

Definition at line 534 of file RankFourTensor.h.

◆ RankTwoTensorTempl

template<typename T >
template<typename T2 >
friend class RankTwoTensorTempl
friend

Definition at line 530 of file RankFourTensor.h.

Member Data Documentation

◆ _vals

template<typename T >
T RankFourTensorTempl< T >::_vals[N4]
protected

◆ N

template<typename T >
constexpr unsigned int RankFourTensorTempl< T >::N = Moose::dim
staticconstexpr

tensor dimension and powers of the dimension

Definition at line 69 of file RankFourTensor.h.

Referenced by RankFourTensorTempl< T >::operator()(), and RankFourTensorTempl< T >::operator()().

◆ N2

template<typename T >
constexpr unsigned int RankFourTensorTempl< T >::N2 = N * N
staticconstexpr

◆ N3

template<typename T >
constexpr unsigned int RankFourTensorTempl< T >::N3 = N * N * N
staticconstexpr

◆ N4

template<typename T >
constexpr unsigned int RankFourTensorTempl< T >::N4 = N * N * N * N
staticconstexpr

Definition at line 72 of file RankFourTensor.h.


The documentation for this class was generated from the following files: