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

Static Public Attributes

static constexpr unsigned int N = Moose::dim
 tensor dimension and powers of the dimension More...
 
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. More...
 
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 More...
 
void fillAntisymmetricIsotropicFromInputVector (const std::vector< T > &input)
 fillAntisymmetricIsotropicFromInputVector takes 1 input to fill the the antisymmetric Rank-4 tensor with the appropriate symmetries maintained. More...
 
void fillSymmetricIsotropicFromInputVector (const std::vector< T > &input)
 fillSymmetricIsotropicFromInputVector takes 2 inputs to fill the the symmetric Rank-4 tensor with the appropriate symmetries maintained. More...
 
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. More...
 
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. More...
 
void fillGeneralFromInputVector (const std::vector< T > &input)
 fillGeneralFromInputVector takes 81 inputs to fill the Rank-4 tensor No symmetries are explicitly maintained More...
 
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 More...
 
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 More...
 

Protected Attributes

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

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...
IntRange< T > make_range(T beg, T end)
static constexpr unsigned int N
tensor dimension and powers of the dimension

◆ 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 
75  case initIdentityFour:
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
void zero()
Zeros out the tensor.
T _vals[N4]
The values of the rank-four tensor stored by index=(((i * LIBMESH_DIM + j) * LIBMESH_DIM + k) * LIBME...
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
IntRange< T > make_range(T beg, T end)
static constexpr unsigned int N
tensor dimension and powers of the dimension

◆ 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 }
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...
IntRange< T > make_range(T beg, T end)

◆ 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  }
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...
SymmetricRankFourTensorTempl is designed to handle an N-dimensional fourth order tensor with minor sy...
IntRange< T > make_range(T beg, T end)
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.
static constexpr unsigned int N
tensor dimension and powers of the dimension

◆ 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 }
static constexpr unsigned int N
tensor dimension and powers of the dimension

◆ 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 }
static constexpr unsigned int N
tensor dimension and powers of the dimension

◆ 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)
624  mooseError(
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 }
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:311
void zero()
Zeros out the tensor.
IntRange< T > make_range(T beg, T end)
static constexpr unsigned int N
tensor dimension and powers of the dimension

◆ 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 }
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:311
void fillGeneralIsotropic(const T &i0, const T &i1, const T &i2)
Vector-less fill API functions. See docs of the corresponding ...FromInputVector methods.

◆ 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;
590  case general_isotropic:
592  break;
593  case symmetric_isotropic:
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 fillSymmetric9FromInputVector(const T2 &input)
fillSymmetric9FromInputVector takes 9 inputs to fill in the Rank-4 tensor with the appropriate crysta...
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 ...
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:311
void fillSymmetric21FromInputVector(const T2 &input)
fillSymmetric21FromInputVector takes either 21 inputs to fill in the Rank-4 tensor with the appropria...
void fillPrincipalFromInputVector(const std::vector< T > &input)
fillPrincipalFromInputVector takes 9 inputs to fill a Rank-4 tensor C1111 = input0 C1122 = input1 C11...
void fillGeneralIsotropicFromInputVector(const std::vector< T > &input)
fillGeneralIsotropicFromInputVector takes 3 inputs to fill the Rank-4 tensor with symmetries C_ijkl =...
void fillAxisymmetricRZFromInputVector(const std::vector< T > &input)
fillAxisymmetricRZFromInputVector takes 5 inputs to fill the axisymmetric Rank-4 tensor with the appr...
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 fillAntisymmetricIsotropicFromInputVector(const std::vector< T > &input)
fillAntisymmetricIsotropicFromInputVector takes 1 input to fill the the antisymmetric Rank-4 tensor w...

◆ 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 }
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:311
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...
IntRange< T > make_range(T beg, T end)

◆ 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 }
int eps(unsigned int i, unsigned int j)
2D version
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
IntRange< T > make_range(T beg, T end)
static constexpr unsigned int N
tensor dimension and powers of the dimension

◆ 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 }
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:311
void fillGeneralIsotropic(const T &i0, const T &i1, const T &i2)
Vector-less fill API functions. See docs of the corresponding ...FromInputVector methods.

◆ 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 }
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:311
IntRange< T > make_range(T beg, T end)
static constexpr unsigned int N
tensor dimension and powers of the dimension

◆ 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:54

◆ 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 }
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:311
void zero()
Zeros out the tensor.

◆ 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 }
void zero()
Zeros out the tensor.

◆ 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 }
void fillSymmetric21FromInputVector(const T2 &input)
fillSymmetric21FromInputVector takes either 21 inputs to fill in the Rank-4 tensor with the appropria...

◆ 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)
742  mooseError(
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 mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:311
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 }
void fillSymmetricIsotropic(const T &i0, const T &i1)

◆ 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 {ik} {jl} - {ij} {kl} / 3.

Definition at line 174 of file RankFourTensor.h.

175  {
177  };
RankFourTensorTempl is designed to handle any N-dimensional fourth order tensor, C.

◆ IdentityFour()

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

Definition at line 172 of file RankFourTensor.h.

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

◆ 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 {
902  RankTwoTensorTempl<T> result;
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 }
T _coords[LIBMESH_DIM *LIBMESH_DIM]
static constexpr unsigned int N2
T _vals[N4]
The values of the rank-four tensor stored by index=(((i * LIBMESH_DIM + j) * LIBMESH_DIM + k) * LIBME...
RankTwoTensorTempl is designed to handle the Stress or Strain Tensor for a fully anisotropic material...
Definition: RankTwoTensor.h:87

◆ 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 
761  RankFourTensorTempl<T> result;
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 }
RankFourTensorTempl is designed to handle any N-dimensional fourth order tensor, C.
T _vals[N4]
The values of the rank-four tensor stored by index=(((i * LIBMESH_DIM + j) * LIBMESH_DIM + k) * LIBME...
IntRange< T > make_range(T beg, T end)

◆ 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 }
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:311

◆ invSymm() [2/2]

template<>
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 }
RankFourTensorTempl is designed to handle any N-dimensional fourth order tensor, C.
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
T _vals[N4]
The values of the rank-four tensor stored by index=(((i * LIBMESH_DIM + j) * LIBMESH_DIM + k) * LIBME...
IntRange< T > make_range(T beg, T end)
static constexpr unsigned int N
tensor dimension and powers of the dimension

◆ 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 }
static constexpr unsigned int N3
static constexpr unsigned int N2
bool isSymmetric() const
checks if the tensor is symmetric
T _vals[N4]
The values of the rank-four tensor stored by index=(((i * LIBMESH_DIM + j) * LIBMESH_DIM + k) * LIBME...
IntRange< T > make_range(T beg, T end)
static constexpr unsigned int N
tensor dimension and powers of the dimension

◆ 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 }
IntRange< T > make_range(T beg, T end)
static constexpr unsigned int N
tensor dimension and powers of the dimension

◆ 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 }
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...
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template * sqrt(_arg)) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(tanh
IntRange< T > make_range(T beg, T end)
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

◆ 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  }
static constexpr unsigned int N3
static constexpr unsigned int N2
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

◆ 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  }
static constexpr unsigned int N3
static constexpr unsigned int N2
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

◆ operator*() [1/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;
131  RankTwoTensorTempl<ValueType> result;
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 }
static constexpr unsigned int N2
T _vals[N4]
The values of the rank-four tensor stored by index=(((i * LIBMESH_DIM + j) * LIBMESH_DIM + k) * LIBME...
RankTwoTensorTempl is designed to handle the Stress or Strain Tensor for a fully anisotropic material...
Definition: RankTwoTensor.h:87
if(!dmm->_nl) SETERRQ(PETSC_COMM_WORLD
static constexpr unsigned int N
tensor dimension and powers of the dimension

◆ 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;
584  RankFourTensorTempl<ValueType> result;
585 
586  for (auto i : libMesh::make_range(N4))
587  result._vals[i] = _vals[i] * b;
588 
589  return result;
590 }
RankFourTensorTempl is designed to handle any N-dimensional fourth order tensor, C.
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
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...
for(PetscInt i=0;i< nvars;++i)

◆ operator*() [3/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;
238  RankFourTensorTempl<ValueType> result;
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 }
RankFourTensorTempl is designed to handle any N-dimensional fourth order tensor, C.
T _vals[N4]
The values of the rank-four tensor stored by index=(((i * LIBMESH_DIM + j) * LIBMESH_DIM + k) * LIBME...
if(!dmm->_nl) SETERRQ(PETSC_COMM_WORLD
IntRange< T > make_range(T beg, T end)
static constexpr unsigned int N
tensor dimension and powers of the dimension

◆ 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 }
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...
IntRange< T > make_range(T beg, T end)

◆ 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 {
195  for (auto i : make_range(N4))
196  result._vals[i] = _vals[i] + b._vals[i];
197  return result;
198 }
RankFourTensorTempl is designed to handle any N-dimensional fourth order tensor, C.
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...
IntRange< T > make_range(T beg, T end)

◆ 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 }
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...
IntRange< T > make_range(T beg, T end)

◆ operator-() [1/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 }
RankFourTensorTempl is designed to handle any N-dimensional fourth order tensor, C.
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...
IntRange< T > make_range(T beg, T end)

◆ operator-() [2/2]

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

-C_ijkl

Definition at line 223 of file RankFourTensorImplementation.h.

224 {
225  RankFourTensorTempl<T> result;
226  for (auto i : make_range(N4))
227  result._vals[i] = -_vals[i];
228  return result;
229 }
RankFourTensorTempl is designed to handle any N-dimensional fourth order tensor, C.
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...
IntRange< T > make_range(T beg, T end)

◆ 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 }
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...
IntRange< T > make_range(T beg, T end)

◆ 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 }
RankFourTensorTempl is designed to handle any N-dimensional fourth order tensor, C.
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...
IntRange< T > make_range(T beg, T end)

◆ 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 }
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...
IntRange< T > make_range(T beg, T end)

◆ 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  }
void zero()
Zeros out the tensor.

◆ 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 }
IntRange< T > make_range(T beg, T end)
static constexpr unsigned int N
tensor dimension and powers of the dimension

◆ 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)
Definition: EigenADReal.h:100
static constexpr unsigned int N
tensor dimension and powers of the dimension

◆ 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 }
RankFourTensorTempl is designed to handle any N-dimensional fourth order tensor, C.
T _vals[N4]
The values of the rank-four tensor stored by index=(((i * LIBMESH_DIM + j) * LIBMESH_DIM + k) * LIBME...
IntRange< T > make_range(T beg, T end)
static constexpr unsigned int N
tensor dimension and powers of the dimension

◆ 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 }
RankFourTensorTempl is designed to handle any N-dimensional fourth order tensor, C.
static constexpr unsigned int N
tensor dimension and powers of the dimension

◆ 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 }
RankFourTensorTempl is designed to handle any N-dimensional fourth order tensor, C.
static constexpr unsigned int N
tensor dimension and powers of the dimension

◆ 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 }
RankFourTensorTempl is designed to handle any N-dimensional fourth order tensor, C.
static constexpr unsigned int N
tensor dimension and powers of the dimension

◆ 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 }
RankFourTensorTempl is designed to handle any N-dimensional fourth order tensor, C.
static constexpr unsigned int N
tensor dimension and powers of the dimension

◆ 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 }
IntRange< T > make_range(T beg, T end)
static constexpr unsigned int N
tensor dimension and powers of the dimension

◆ 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 }
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:311
void zero()
Zeros out the tensor.

◆ 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 {
502  RankFourTensorTempl<T> result;
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 }
RankFourTensorTempl is designed to handle any N-dimensional fourth order tensor, C.
IntRange< T > make_range(T beg, T end)
static constexpr unsigned int N
tensor dimension and powers of the dimension

◆ 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 {
517  RankFourTensorTempl<T> result;
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 }
RankFourTensorTempl is designed to handle any N-dimensional fourth order tensor, C.
IntRange< T > make_range(T beg, T end)
static constexpr unsigned int N
tensor dimension and powers of the dimension

◆ 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 {
486  RankFourTensorTempl<T> result;
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 }
RankFourTensorTempl is designed to handle any N-dimensional fourth order tensor, C.
static constexpr unsigned int N3
static constexpr unsigned int N2
T _vals[N4]
The values of the rank-four tensor stored by index=(((i * LIBMESH_DIM + j) * LIBMESH_DIM + k) * LIBME...
IntRange< T > make_range(T beg, T end)
static constexpr unsigned int N
tensor dimension and powers of the dimension

◆ 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 }
RankFourTensorTempl is designed to handle any N-dimensional fourth order tensor, C.
static constexpr unsigned int N
tensor dimension and powers of the dimension

◆ 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 }
RankFourTensorTempl is designed to handle any N-dimensional fourth order tensor, C.
static constexpr unsigned int N
tensor dimension and powers of the dimension

◆ 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 }
RankFourTensorTempl is designed to handle any N-dimensional fourth order tensor, C.
static constexpr unsigned int N
tensor dimension and powers of the dimension

◆ 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 }
RankFourTensorTempl is designed to handle any N-dimensional fourth order tensor, C.
static constexpr unsigned int N
tensor dimension and powers of the dimension

◆ zero()

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

Zeros out the tensor.

Definition at line 117 of file RankFourTensorImplementation.h.

Referenced by RankFourTensorTempl< T >::operator=().

118 {
119  for (auto i : make_range(N4))
120  _vals[i] = 0.0;
121 }
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...
IntRange< T > make_range(T beg, T end)

Friends And Related Function 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  }
std::basic_ostream< charT, traits > * os
Definition: InfixIterator.h:34
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
static

tensor dimension and powers of the dimension

Definition at line 69 of file RankFourTensor.h.

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

◆ N2

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

Definition at line 70 of file RankFourTensor.h.

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

◆ N3

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

Definition at line 71 of file RankFourTensor.h.

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

◆ N4

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

Definition at line 72 of file RankFourTensor.h.


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