www.mooseframework.org
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...
 
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)
 copies values from a into this tensor More...
 
template<typename Scalar >
boostcopy::enable_if_c< 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< 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< 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 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...
 
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
 
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/5]

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

Default constructor; fills to zero.

Definition at line 50 of file RankFourTensorImplementation.h.

51 {
52  mooseAssert(N == 3, "RankFourTensorTempl<T> is currently only tested for 3 dimensions.");
53 
54  for (auto i : make_range(N4))
55  _vals[i] = 0.0;
56 }
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/5]

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

Select specific initialization pattern.

Definition at line 59 of file RankFourTensorImplementation.h.

60 {
61  unsigned int index = 0;
62  switch (init)
63  {
64  case initNone:
65  break;
66 
67  case initIdentity:
68  zero();
69  for (auto i : make_range(N))
70  (*this)(i, i, i, i) = 1.0;
71  break;
72 
73  case initIdentityFour:
74  for (auto i : make_range(N))
75  for (auto j : make_range(N))
76  for (auto k : make_range(N))
77  for (auto l : make_range(N))
78  _vals[index++] = Real(i == k && j == l);
79  break;
80 
82  for (auto i : make_range(N))
83  for (auto j : make_range(N))
84  for (auto k : make_range(N))
85  for (auto l : make_range(N))
86  _vals[index++] = 0.5 * Real(i == k && j == l) + 0.5 * Real(i == l && j == k);
87  break;
88 
90  for (unsigned int i = 0; i < N; ++i)
91  for (unsigned int j = 0; j < N; ++j)
92  for (unsigned int k = 0; k < N; ++k)
93  for (unsigned int l = 0; l < N; ++l)
94  {
95  _vals[index] = Real(i == k && j == l);
96  if ((i == j) && (k == l))
97  _vals[index] -= 1.0 / 3.0;
98  index++;
99  }
100  break;
101 
102  default:
103  mooseError("Unknown RankFourTensorTempl<T> initialization pattern.");
104  }
105 }
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:299
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/5]

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

Fill from vector.

Definition at line 108 of file RankFourTensorImplementation.h.

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

◆ RankFourTensorTempl() [4/5]

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

Copy assignment operator must be defined if used.

◆ RankFourTensorTempl() [5/5]

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

Copy constructor.

Definition at line 541 of file RankFourTensor.h.

542 {
543  for (auto i : make_range(N4))
544  _vals[i] = copy._vals[i];
545 }
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)

Member Function Documentation

◆ contraction()

template<typename T >
template<int m>
RankThreeTensorTempl< T > RankFourTensorTempl< T >::contraction ( const 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 760 of file RankFourTensor.h.

761 {
763  static constexpr std::size_t z[4][3] = {{1, 2, 3}, {0, 2, 3}, {0, 1, 3}, {0, 1, 2}};
764  std::size_t x[4];
765  for (x[0] = 0; x[0] < N; ++x[0])
766  for (x[1] = 0; x[1] < N; ++x[1])
767  for (x[2] = 0; x[2] < N; ++x[2])
768  for (x[3] = 0; x[3] < N; ++x[3])
769  result(x[z[m][0]], x[z[m][1]], x[z[m][2]]) += (*this)(x[0], x[1], x[2], x[3]) * b(x[m]);
770 
771  return result;
772 }
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 892 of file RankFourTensorImplementation.h.

895 {
896  T val = 0;
897  for (unsigned int k = 0; k < N; k++)
898  for (unsigned int l = 0; l < N; l++)
899  val += (*this)(i, j, k, l) * M(k, l);
900 
901  return val;
902 }
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 906 of file RankFourTensorImplementation.h.

909 {
910  T val = 0;
911  for (unsigned int i = 0; i < N; i++)
912  for (unsigned int j = 0; j < N; j++)
913  val += (*this)(i, j, k, l) * M(i, j);
914 
915  return val;
916 }
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 596 of file RankFourTensorImplementation.h.

597 {
598  if (input.size() != 6)
599  mooseError(
600  "To use fillAntisymmetricFromInputVector, your input must have size 6. Yours has size ",
601  input.size());
602 
603  zero();
604 
605  (*this)(0, 1, 0, 1) = input[0]; // B1212
606  (*this)(0, 1, 0, 2) = input[1]; // B1213
607  (*this)(0, 1, 1, 2) = input[2]; // B1223
608 
609  (*this)(0, 2, 0, 2) = input[3]; // B1313
610  (*this)(0, 2, 1, 2) = input[4]; // B1323
611 
612  (*this)(1, 2, 1, 2) = input[5]; // B2323
613 
614  // symmetry on the two pairs
615  (*this)(0, 2, 0, 1) = (*this)(0, 1, 0, 2);
616  (*this)(1, 2, 0, 1) = (*this)(0, 1, 1, 2);
617  (*this)(1, 2, 0, 2) = (*this)(0, 2, 1, 2);
618  // have now got the upper parts of vals[0][1], vals[0][2] and vals[1][2]
619 
620  // fill in from antisymmetry relations
621  for (auto i : make_range(N))
622  for (auto j : make_range(N))
623  {
624  (*this)(0, 1, j, i) = -(*this)(0, 1, i, j);
625  (*this)(0, 2, j, i) = -(*this)(0, 2, i, j);
626  (*this)(1, 2, j, i) = -(*this)(1, 2, i, j);
627  }
628  // have now got all of vals[0][1], vals[0][2] and vals[1][2]
629 
630  // fill in from antisymmetry relations
631  for (auto i : make_range(N))
632  for (auto j : make_range(N))
633  {
634  (*this)(1, 0, i, j) = -(*this)(0, 1, i, j);
635  (*this)(2, 0, i, j) = -(*this)(0, 2, i, j);
636  (*this)(2, 1, i, j) = -(*this)(1, 2, i, j);
637  }
638 }
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:299
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 683 of file RankFourTensorImplementation.h.

684 {
685  fillGeneralIsotropic(0.0, 0.0, i0);
686 }
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 671 of file RankFourTensorImplementation.h.

672 {
673  if (input.size() != 1)
674  mooseError("To use fillAntisymmetricIsotropicFromInputVector, your input must have size 1. "
675  "Yours has size ",
676  input.size());
677 
678  fillGeneralIsotropic(0.0, 0.0, input[0]);
679 }
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:299
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 738 of file RankFourTensorImplementation.h.

739 {
740  mooseAssert(input.size() == 5,
741  "To use fillAxisymmetricRZFromInputVector, your input must have size 5.");
742 
743  // C1111 C1122 C1133 0 0 0
744  // C2222 C2233=C1133 0 0 0
745  // C3333 0 0 0
746  // C2323 0 0
747  // C3131=C2323 0
748  // C1212
749  // clang-format off
750  fillSymmetric21FromInputVector(std::array<T,21>
751  {{input[0],input[1],input[2], 0.0, 0.0, 0.0,
752  input[0],input[2], 0.0, 0.0, 0.0,
753  input[3], 0.0, 0.0, 0.0,
754  input[4], 0.0, 0.0,
755  input[4], 0.0,
756  (input[0] - input[1]) * 0.5}});
757  // clang-format on
758 }
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 551 of file RankFourTensorImplementation.h.

552 {
553 
554  switch (fill_method)
555  {
556  case antisymmetric:
558  break;
559  case symmetric9:
561  break;
562  case symmetric21:
564  break;
565  case general_isotropic:
567  break;
568  case symmetric_isotropic:
570  break;
573  break;
576  break;
577  case axisymmetric_rz:
579  break;
580  case general:
582  break;
583  case principal:
585  break;
586  case orthotropic:
588  break;
589  default:
590  mooseError("fillFromInputVector called with unknown fill_method of ", fill_method);
591  }
592 }
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:299
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 762 of file RankFourTensorImplementation.h.

763 {
764  if (input.size() != 81)
765  mooseError("To use fillGeneralFromInputVector, your input must have size 81. Yours has size ",
766  input.size());
767 
768  for (auto i : make_range(N4))
769  _vals[i] = input[i];
770 }
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:299
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 654 of file RankFourTensorImplementation.h.

655 {
656  for (auto i : make_range(N))
657  for (auto j : make_range(N))
658  for (auto k : make_range(N))
659  for (auto l : make_range(N))
660  {
661  (*this)(i, j, k, l) = i0 * Real(i == j) * Real(k == l) +
662  i1 * Real(i == k) * Real(j == l) + i1 * Real(i == l) * Real(j == k);
663  for (auto m : make_range(N))
664  (*this)(i, j, k, l) +=
665  i2 * Real(PermutationTensor::eps(i, j, m)) * Real(PermutationTensor::eps(k, l, m));
666  }
667 }
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 642 of file RankFourTensorImplementation.h.

643 {
644  if (input.size() != 3)
645  mooseError("To use fillGeneralIsotropicFromInputVector, your input must have size 3. Yours "
646  "has size ",
647  input.size());
648 
649  fillGeneralIsotropic(input[0], input[1], input[2]);
650 }
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:299
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 795 of file RankFourTensorImplementation.h.

796 {
797  if (input.size() != 12)
798  mooseError("To use fillGeneralOrhotropicFromInputVector, your input must have size 12. Yours "
799  "has size ",
800  input.size());
801 
802  const T & Ea = input[0];
803  const T & Eb = input[1];
804  const T & Ec = input[2];
805  const T & Gab = input[3];
806  const T & Gbc = input[4];
807  const T & Gca = input[5];
808  const T & nuba = input[6];
809  const T & nuca = input[7];
810  const T & nucb = input[8];
811  const T & nuab = input[9];
812  const T & nuac = input[10];
813  const T & nubc = input[11];
814 
815  // Input must satisfy constraints.
816  bool preserve_symmetry = MooseUtils::absoluteFuzzyEqual(nuab * Eb, nuba * Ea) &&
817  MooseUtils::absoluteFuzzyEqual(nuca * Ea, nuac * Ec) &&
818  MooseUtils::absoluteFuzzyEqual(nubc * Ec, nucb * Eb);
819 
820  if (!preserve_symmetry)
821  mooseError("Orthotropic elasticity tensor input is not consistent with symmetry requirements. "
822  "Check input for accuracy");
823 
824  unsigned int ntens = N * (N + 1) / 2;
825 
826  std::vector<T> mat;
827  mat.assign(ntens * ntens, 0);
828 
829  T k = 1 - nuab * nuba - nubc * nucb - nuca * nuac - nuab * nubc * nuca - nuba * nucb * nuac;
830 
831  bool is_positive_definite =
832  (k > 0) && (1 - nubc * nucb) > 0 && (1 - nuac * nuca) > 0 && (1 - nuab * nuba) > 0;
833  if (!is_positive_definite)
834  mooseError("Orthotropic elasticity tensor input is not positive definite. Check input for "
835  "accuracy");
836 
837  mat[0] = Ea * (1 - nubc * nucb) / k;
838  mat[1] = Ea * (nubc * nuca + nuba) / k;
839  mat[2] = Ea * (nuba * nucb + nuca) / k;
840 
841  mat[6] = Eb * (nuac * nucb + nuab) / k;
842  mat[7] = Eb * (1 - nuac * nuca) / k;
843  mat[8] = Eb * (nuab * nuca + nucb) / k;
844 
845  mat[12] = Ec * (nuab * nubc + nuac) / k;
846  mat[13] = Ec * (nuac * nuba + nubc) / k;
847  mat[14] = Ec * (1 - nuab * nuba) / k;
848 
849  mat[21] = 2 * Gab;
850  mat[28] = 2 * Gca;
851  mat[35] = 2 * Gbc;
852 
853  // Switching from Voigt to fourth order tensor
854  // Copied from existing code (invSymm)
855  int nskip = N - 1;
856 
857  unsigned int index = 0;
858  for (auto i : make_range(N))
859  for (auto j : make_range(N))
860  for (auto k : make_range(N))
861  for (auto l : make_range(N))
862  {
863  if (i == j)
864  (*this)._vals[index] =
865  k == l ? mat[i * ntens + k] : mat[i * ntens + k + nskip + l] / 2.0;
866  else
867  (*this)._vals[index] = k == l ? mat[(nskip + i + j) * ntens + k]
868  : mat[(nskip + i + j) * ntens + k + nskip + l] / 2.0;
869  index++;
870  }
871 }
bool absoluteFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
Function to check whether two variables are equal within an absolute tolerance.
Definition: MooseUtils.h:346
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:299
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 42 of file RankFourTensorImplementation.h.

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

◆ 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 774 of file RankFourTensorImplementation.h.

775 {
776  if (input.size() != 9)
777  mooseError("To use fillPrincipalFromInputVector, your input must have size 9. Yours has size ",
778  input.size());
779 
780  zero();
781 
782  (*this)(0, 0, 0, 0) = input[0];
783  (*this)(0, 0, 1, 1) = input[1];
784  (*this)(0, 0, 2, 2) = input[2];
785  (*this)(1, 1, 0, 0) = input[3];
786  (*this)(1, 1, 1, 1) = input[4];
787  (*this)(1, 1, 2, 2) = input[5];
788  (*this)(2, 2, 0, 0) = input[6];
789  (*this)(2, 2, 1, 1) = input[7];
790  (*this)(2, 2, 2, 2) = input[8];
791 }
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:299
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 616 of file RankFourTensor.h.

617 {
618  mooseAssert(input.size() == 21,
619  "To use fillSymmetric21FromInputVector, your input must have size 21.");
620 
621  (*this)(0, 0, 0, 0) = input[0]; // C1111
622  (*this)(1, 1, 1, 1) = input[6]; // C2222
623  (*this)(2, 2, 2, 2) = input[11]; // C3333
624 
625  (*this)(0, 0, 1, 1) = input[1]; // C1122
626  (*this)(1, 1, 0, 0) = input[1];
627 
628  (*this)(0, 0, 2, 2) = input[2]; // C1133
629  (*this)(2, 2, 0, 0) = input[2];
630 
631  (*this)(1, 1, 2, 2) = input[7]; // C2233
632  (*this)(2, 2, 1, 1) = input[7];
633 
634  (*this)(0, 0, 0, 2) = input[4]; // C1113
635  (*this)(0, 0, 2, 0) = input[4];
636  (*this)(0, 2, 0, 0) = input[4];
637  (*this)(2, 0, 0, 0) = input[4];
638 
639  (*this)(0, 0, 0, 1) = input[5]; // C1112
640  (*this)(0, 0, 1, 0) = input[5];
641  (*this)(0, 1, 0, 0) = input[5];
642  (*this)(1, 0, 0, 0) = input[5];
643 
644  (*this)(1, 1, 1, 2) = input[8]; // C2223
645  (*this)(1, 1, 2, 1) = input[8];
646  (*this)(1, 2, 1, 1) = input[8];
647  (*this)(2, 1, 1, 1) = input[8];
648 
649  (*this)(1, 1, 1, 0) = input[10];
650  (*this)(1, 1, 0, 1) = input[10];
651  (*this)(1, 0, 1, 1) = input[10];
652  (*this)(0, 1, 1, 1) = input[10]; // C2212 //flipped for filling purposes
653 
654  (*this)(2, 2, 2, 1) = input[12];
655  (*this)(2, 2, 1, 2) = input[12];
656  (*this)(2, 1, 2, 2) = input[12];
657  (*this)(1, 2, 2, 2) = input[12]; // C3323 //flipped for filling purposes
658 
659  (*this)(2, 2, 2, 0) = input[13];
660  (*this)(2, 2, 0, 2) = input[13];
661  (*this)(2, 0, 2, 2) = input[13];
662  (*this)(0, 2, 2, 2) = input[13]; // C3313 //flipped for filling purposes
663 
664  (*this)(0, 0, 1, 2) = input[3]; // C1123
665  (*this)(0, 0, 2, 1) = input[3];
666  (*this)(1, 2, 0, 0) = input[3];
667  (*this)(2, 1, 0, 0) = input[3];
668 
669  (*this)(1, 1, 0, 2) = input[9];
670  (*this)(1, 1, 2, 0) = input[9];
671  (*this)(0, 2, 1, 1) = input[9]; // C2213 //flipped for filling purposes
672  (*this)(2, 0, 1, 1) = input[9];
673 
674  (*this)(2, 2, 0, 1) = input[14];
675  (*this)(2, 2, 1, 0) = input[14];
676  (*this)(0, 1, 2, 2) = input[14]; // C3312 //flipped for filling purposes
677  (*this)(1, 0, 2, 2) = input[14];
678 
679  (*this)(1, 2, 1, 2) = input[15]; // C2323
680  (*this)(2, 1, 2, 1) = input[15];
681  (*this)(2, 1, 1, 2) = input[15];
682  (*this)(1, 2, 2, 1) = input[15];
683 
684  (*this)(0, 2, 0, 2) = input[18]; // C1313
685  (*this)(2, 0, 2, 0) = input[18];
686  (*this)(2, 0, 0, 2) = input[18];
687  (*this)(0, 2, 2, 0) = input[18];
688 
689  (*this)(0, 1, 0, 1) = input[20]; // C1212
690  (*this)(1, 0, 1, 0) = input[20];
691  (*this)(1, 0, 0, 1) = input[20];
692  (*this)(0, 1, 1, 0) = input[20];
693 
694  (*this)(1, 2, 0, 2) = input[16];
695  (*this)(0, 2, 1, 2) = input[16]; // C2313 //flipped for filling purposes
696  (*this)(2, 1, 0, 2) = input[16];
697  (*this)(1, 2, 2, 0) = input[16];
698  (*this)(2, 0, 1, 2) = input[16];
699  (*this)(0, 2, 2, 1) = input[16];
700  (*this)(2, 1, 2, 0) = input[16];
701  (*this)(2, 0, 2, 1) = input[16];
702 
703  (*this)(1, 2, 0, 1) = input[17];
704  (*this)(0, 1, 1, 2) = input[17]; // C2312 //flipped for filling purposes
705  (*this)(2, 1, 0, 1) = input[17];
706  (*this)(1, 2, 1, 0) = input[17];
707  (*this)(1, 0, 1, 2) = input[17];
708  (*this)(0, 1, 2, 1) = input[17];
709  (*this)(2, 1, 1, 0) = input[17];
710  (*this)(1, 0, 2, 1) = input[17];
711 
712  (*this)(0, 2, 0, 1) = input[19];
713  (*this)(0, 1, 0, 2) = input[19]; // C1312 //flipped for filling purposes
714  (*this)(2, 0, 0, 1) = input[19];
715  (*this)(0, 2, 1, 0) = input[19];
716  (*this)(1, 0, 0, 2) = input[19];
717  (*this)(0, 1, 2, 0) = input[19];
718  (*this)(2, 0, 1, 0) = input[19];
719  (*this)(1, 0, 2, 0) = input[19];
720 }

◆ 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 579 of file RankFourTensor.h.

580 {
581  mooseAssert(input.size() == 9,
582  "To use fillSymmetric9FromInputVector, your input must have size 9.");
583  zero();
584 
585  (*this)(0, 0, 0, 0) = input[0]; // C1111
586  (*this)(1, 1, 1, 1) = input[3]; // C2222
587  (*this)(2, 2, 2, 2) = input[5]; // C3333
588 
589  (*this)(0, 0, 1, 1) = input[1]; // C1122
590  (*this)(1, 1, 0, 0) = input[1];
591 
592  (*this)(0, 0, 2, 2) = input[2]; // C1133
593  (*this)(2, 2, 0, 0) = input[2];
594 
595  (*this)(1, 1, 2, 2) = input[4]; // C2233
596  (*this)(2, 2, 1, 1) = input[4];
597 
598  (*this)(1, 2, 1, 2) = input[6]; // C2323
599  (*this)(2, 1, 2, 1) = input[6];
600  (*this)(2, 1, 1, 2) = input[6];
601  (*this)(1, 2, 2, 1) = input[6];
602 
603  (*this)(0, 2, 0, 2) = input[7]; // C1313
604  (*this)(2, 0, 2, 0) = input[7];
605  (*this)(2, 0, 0, 2) = input[7];
606  (*this)(0, 2, 2, 0) = input[7];
607 
608  (*this)(0, 1, 0, 1) = input[8]; // C1212
609  (*this)(1, 0, 1, 0) = input[8];
610  (*this)(1, 0, 0, 1) = input[8];
611  (*this)(0, 1, 1, 0) = input[8];
612 }
void zero()
Zeros out the tensor.

◆ fillSymmetricIsotropic()

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

Definition at line 699 of file RankFourTensorImplementation.h.

700 {
701  // clang-format off
702  fillSymmetric21FromInputVector(std::array<T,21>
703  {{lambda + 2.0 * G, lambda, lambda, 0.0, 0.0, 0.0,
704  lambda + 2.0 * G, lambda, 0.0, 0.0, 0.0,
705  lambda + 2.0 * G, 0.0, 0.0, 0.0,
706  G, 0.0, 0.0,
707  G, 0.0,
708  G}});
709  // clang-format on
710 }
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 727 of file RankFourTensorImplementation.h.

728 {
729  // Calculate lambda and the shear modulus from the given young's modulus and poisson's ratio
730  const T & lambda = E * nu / ((1.0 + nu) * (1.0 - 2.0 * nu));
731  const T & G = E / (2.0 * (1.0 + nu));
732 
733  fillSymmetricIsotropic(lambda, G);
734 }
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 714 of file RankFourTensorImplementation.h.

715 {
716  if (input.size() != 2)
717  mooseError(
718  "To use fillSymmetricIsotropicEandNuFromInputVector, your input must have size 2. Yours "
719  "has size ",
720  input.size());
721 
722  fillSymmetricIsotropicEandNu(input[0], input[1]);
723 }
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:299
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 690 of file RankFourTensorImplementation.h.

691 {
692  mooseAssert(input.size() == 2,
693  "To use fillSymmetricIsotropicFromInputVector, your input must have size 2.");
694  fillSymmetricIsotropic(input[0], input[1]);
695 }
void fillSymmetricIsotropic(const T &i0, const T &i1)

◆ Identity()

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

Definition at line 148 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 151 of file RankFourTensor.h.

152  {
154  };
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 149 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 875 of file RankFourTensorImplementation.h.

876 {
877  RankTwoTensorTempl<T> result;
878 
879  unsigned int index = 0;
880  for (unsigned int ij = 0; ij < N2; ++ij)
881  {
882  T bb = b._coords[ij];
883  for (unsigned int kl = 0; kl < N2; ++kl)
884  result._coords[kl] += _vals[index++] * bb;
885  }
886 
887  return result;
888 }
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:79

◆ 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 724 of file RankFourTensor.h.

725 {
726 
727  // The inverse of a 3x3x3x3 in the C_ijkl*A_klmn = de_im de_jn sense is
728  // simply the inverse of the 9x9 matrix of the tensor entries.
729  // So all we need to do is inverse _vals (with the appropriate row-major
730  // storage)
731 
732  RankFourTensorTempl<T> result;
733 
734  if constexpr (RankFourTensorTempl<T>::N4 * sizeof(T) > EIGEN_STACK_ALLOCATION_LIMIT)
735  {
736  // Allocate on the heap if you're going to exceed the stack size limit
737  Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> mat(9, 9);
738  for (auto i : make_range(9 * 9))
739  mat(i) = _vals[i];
740 
741  mat = mat.inverse();
742 
743  for (auto i : make_range(9 * 9))
744  result._vals[i] = mat(i);
745  }
746  else
747  {
748  // Allocate on the stack if small enough
749  const Eigen::Map<const Eigen::Matrix<T, 9, 9, Eigen::RowMajor>> mat(&_vals[0]);
750  Eigen::Map<Eigen::Matrix<T, 9, 9, Eigen::RowMajor>> res(&result._vals[0]);
751  res = mat.inverse();
752  }
753 
754  return result;
755 }
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 256 of file RankFourTensorImplementation.h.

257 {
258  mooseError("The invSymm operation calls to LAPACK and only supports plain Real type tensors.");
259 }
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:299

◆ invSymm() [2/2]

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

Definition at line 263 of file RankFourTensorImplementation.h.

264 {
265  unsigned int ntens = N * (N + 1) / 2;
266  int nskip = N - 1;
267 
269  std::vector<PetscScalar> mat;
270  mat.assign(ntens * ntens, 0);
271 
272  // We use the LAPACK matrix inversion routine here. Form the matrix
273  //
274  // mat[0] mat[1] mat[2] mat[3] mat[4] mat[5]
275  // mat[6] mat[7] mat[8] mat[9] mat[10] mat[11]
276  // mat[12] mat[13] mat[14] mat[15] mat[16] mat[17]
277  // mat[18] mat[19] mat[20] mat[21] mat[22] mat[23]
278  // mat[24] mat[25] mat[26] mat[27] mat[28] mat[29]
279  // mat[30] mat[31] mat[32] mat[33] mat[34] mat[35]
280  //
281  // This is filled from the indpendent components of C assuming
282  // the symmetry C_ijkl = C_ijlk = C_jikl.
283  //
284  // If there are two rank-four tensors X and Y then the reason for
285  // this filling becomes apparent if we want to calculate
286  // X_ijkl*Y_klmn = Z_ijmn
287  // For denote the "mat" versions of X, Y and Z by x, y and z.
288  // Then
289  // z_ab = x_ac*y_cb
290  // Eg
291  // z_00 = Z_0000 = X_0000*Y_0000 + X_0011*Y_1111 + X_0022*Y_2200 + 2*X_0001*Y_0100 +
292  // 2*X_0002*Y_0200 + 2*X_0012*Y_1200 (the factors of 2 come from the assumed symmetries)
293  // 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 +
294  // 2*X_0002*2*Y_0201 + 2*X_0012*2*Y_1201
295  // 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 +
296  // 2*X_0102*2*Y_0202 + 2*X_0112*2*Y_1202
297  // Finally, we use LAPACK to find x^-1, and put it back into rank-4 tensor form
298  //
299  // mat[0] = C(0,0,0,0)
300  // mat[1] = C(0,0,1,1)
301  // mat[2] = C(0,0,2,2)
302  // mat[3] = C(0,0,0,1)*2
303  // mat[4] = C(0,0,0,2)*2
304  // mat[5] = C(0,0,1,2)*2
305 
306  // mat[6] = C(1,1,0,0)
307  // mat[7] = C(1,1,1,1)
308  // mat[8] = C(1,1,2,2)
309  // mat[9] = C(1,1,0,1)*2
310  // mat[10] = C(1,1,0,2)*2
311  // mat[11] = C(1,1,1,2)*2
312 
313  // mat[12] = C(2,2,0,0)
314  // mat[13] = C(2,2,1,1)
315  // mat[14] = C(2,2,2,2)
316  // mat[15] = C(2,2,0,1)*2
317  // mat[16] = C(2,2,0,2)*2
318  // mat[17] = C(2,2,1,2)*2
319 
320  // mat[18] = C(0,1,0,0)
321  // mat[19] = C(0,1,1,1)
322  // mat[20] = C(0,1,2,2)
323  // mat[21] = C(0,1,0,1)*2
324  // mat[22] = C(0,1,0,2)*2
325  // mat[23] = C(0,1,1,2)*2
326 
327  // mat[24] = C(0,2,0,0)
328  // mat[25] = C(0,2,1,1)
329  // mat[26] = C(0,2,2,2)
330  // mat[27] = C(0,2,0,1)*2
331  // mat[28] = C(0,2,0,2)*2
332  // mat[29] = C(0,2,1,2)*2
333 
334  // mat[30] = C(1,2,0,0)
335  // mat[31] = C(1,2,1,1)
336  // mat[32] = C(1,2,2,2)
337  // mat[33] = C(1,2,0,1)*2
338  // mat[34] = C(1,2,0,2)*2
339  // mat[35] = C(1,2,1,2)*2
340 
341  unsigned int index = 0;
342  for (auto i : make_range(N))
343  for (auto j : make_range(N))
344  for (auto k : make_range(N))
345  for (auto l : make_range(N))
346  {
347  if (i == j)
348  mat[k == l ? i * ntens + k : i * ntens + k + nskip + l] += _vals[index];
349  else
350  // i!=j
351  mat[k == l ? (nskip + i + j) * ntens + k : (nskip + i + j) * ntens + k + nskip + l] +=
352  _vals[index]; // note the +=, which results in double-counting and is rectified
353  // below
354  index++;
355  }
356 
357  for (unsigned int i = 3; i < ntens; ++i)
358  for (auto j : make_range(ntens))
359  mat[i * ntens + j] /= 2.0; // because of double-counting above
360 
361  // use LAPACK to find the inverse
362  MatrixTools::inverse(mat, ntens);
363 
364  // build the resulting rank-four tensor
365  // using the inverse of the above algorithm
366  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  result._vals[index] =
374  k == l ? mat[i * ntens + k] : mat[i * ntens + k + nskip + l] / 2.0;
375  else
376  // i!=j
377  result._vals[index] = k == l ? mat[(nskip + i + j) * ntens + k]
378  : mat[(nskip + i + j) * ntens + k + nskip + l] / 2.0;
379  index++;
380  }
381 
382  return result;
383 }
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 1105 of file RankFourTensorImplementation.h.

1106 {
1107  // prerequisite is symmetry
1108  if (!isSymmetric())
1109  return false;
1110 
1111  // inspect shear components
1112  const T & mu = (*this)(0, 1, 0, 1);
1113  // ...diagonal
1114  if ((*this)(1, 2, 1, 2) != mu || (*this)(2, 0, 2, 0) != mu)
1115  return false;
1116  // ...off-diagonal
1117  if ((*this)(2, 0, 1, 2) != 0.0 || (*this)(0, 1, 1, 2) != 0.0 || (*this)(0, 1, 2, 0) != 0.0)
1118  return false;
1119 
1120  // off diagonal blocks in Voigt
1121  for (auto i : make_range(N))
1122  for (auto j : make_range(N))
1123  if (_vals[i * (N3 + N2) + ((j + 1) % N) * N + (j + 2) % N] != 0.0)
1124  return false;
1125 
1126  // top left block
1127  const T & K1 = (*this)(0, 0, 0, 0);
1128  const T & K2 = (*this)(0, 0, 1, 1);
1129  if (!MooseUtils::relativeFuzzyEqual(K1 - 4.0 * mu / 3.0, K2 + 2.0 * mu / 3.0))
1130  return false;
1131  if ((*this)(1, 1, 1, 1) != K1 || (*this)(2, 2, 2, 2) != K1)
1132  return false;
1133  for (auto i : make_range(1u, N))
1134  for (auto j : make_range(i))
1135  if ((*this)(i, i, j, j) != K2)
1136  return false;
1137 
1138  return true;
1139 }
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...
bool relativeFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
Function to check whether two variables are equal within a relative tolerance.
Definition: MooseUtils.h:454
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 1084 of file RankFourTensorImplementation.h.

1085 {
1086  for (auto i : make_range(1u, N))
1087  for (auto j : make_range(i))
1088  for (auto k : make_range(1u, N))
1089  for (auto l : make_range(k))
1090  {
1091  // minor symmetries
1092  if ((*this)(i, j, k, l) != (*this)(j, i, k, l) ||
1093  (*this)(i, j, k, l) != (*this)(i, j, l, k))
1094  return false;
1095 
1096  // major symmetry
1097  if ((*this)(i, j, k, l) != (*this)(k, l, i, j))
1098  return false;
1099  }
1100  return true;
1101 }
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 244 of file RankFourTensorImplementation.h.

245 {
246  T l2 = 0;
247 
248  for (auto i : make_range(N4))
249  l2 += Utility::pow<2>(_vals[i]);
250 
251  return std::sqrt(l2);
252 }
ADRealEigenVector< T, D, asd > sqrt(const ADRealEigenVector< T, D, asd > &)
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)
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 157 of file RankFourTensor.h.

158  {
159  return _vals[i * N3 + j * N2 + k * N + l];
160  }
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 166 of file RankFourTensor.h.

167  {
168  return _vals[i * N3 + j * N2 + k * N + l];
169  }
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 133 of file RankFourTensorImplementation.h.

136 {
137  typedef decltype(T() * T2()) ValueType;
138  RankTwoTensorTempl<ValueType> result;
139 
140  unsigned int index = 0;
141  for (unsigned int ij = 0; ij < N2; ++ij)
142  {
143  ValueType tmp = 0;
144  for (unsigned int kl = 0; kl < N2; ++kl)
145  tmp += _vals[index++] * b(kl / LIBMESH_DIM, kl % LIBMESH_DIM);
146  result._coords[ij] = tmp;
147  }
148 
149  return result;
150 }
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:79

◆ operator*() [2/3]

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

C_ijkl*a.

Definition at line 550 of file RankFourTensor.h.

553 {
554  typedef decltype(T() * T2()) ValueType;
555  RankFourTensorTempl<ValueType> result;
556 
557  for (auto i : make_range(N4))
558  result._vals[i] = _vals[i] * b;
559 
560  return result;
561 }
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...

◆ 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 225 of file RankFourTensorImplementation.h.

227 {
228  typedef decltype(T() * T2()) ValueType;
229  RankFourTensorTempl<ValueType> result;
230 
231  for (auto i : make_range(N))
232  for (auto j : make_range(N))
233  for (auto k : make_range(N))
234  for (auto l : make_range(N))
235  for (auto p : make_range(N))
236  for (auto q : make_range(N))
237  result(i, j, k, l) += (*this)(i, j, p, q) * b(p, q, k, l);
238 
239  return result;
240 }
RankFourTensorTempl is designed to handle any N-dimensional fourth order tensor, C.
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 154 of file RankFourTensorImplementation.h.

155 {
156  for (auto i : make_range(N4))
157  _vals[i] *= a;
158  return *this;
159 }
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 182 of file RankFourTensorImplementation.h.

184 {
186  for (auto i : make_range(N4))
187  result._vals[i] = _vals[i] + b._vals[i];
188  return result;
189 }
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 172 of file RankFourTensorImplementation.h.

173 {
174  for (auto i : make_range(N4))
175  _vals[i] += a._vals[i];
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 >
template<typename T2 >
auto RankFourTensorTempl< T >::operator- ( const RankFourTensorTempl< T2 > &  a) const -> RankFourTensorTempl<decltype(T() - T2())>

C_ijkl - a_ijkl.

Definition at line 203 of file RankFourTensorImplementation.h.

205 {
206  RankFourTensorTempl<decltype(T() - T2())> result;
207  for (auto i : make_range(N4))
208  result._vals[i] = _vals[i] - b._vals[i];
209  return result;
210 }
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 214 of file RankFourTensorImplementation.h.

215 {
216  RankFourTensorTempl<T> result;
217  for (auto i : make_range(N4))
218  result._vals[i] = -_vals[i];
219  return result;
220 }
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 193 of file RankFourTensorImplementation.h.

194 {
195  for (auto i : make_range(N4))
196  _vals[i] -= a._vals[i];
197  return *this;
198 }
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<ScalarTraits<T2>::value, RankFourTensorTempl<decltype(T() / T2())>>::type

C_ijkl/a.

Definition at line 566 of file RankFourTensor.h.

569 {
570  RankFourTensorTempl<decltype(T() / T2())> result;
571  for (auto i : make_range(N4))
572  result._vals[i] = _vals[i] / b;
573  return result;
574 }
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 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=() [1/2]

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

copies values from a into this tensor

Definition at line 123 of file RankFourTensorImplementation.h.

124 {
125  for (auto i : make_range(N4))
126  _vals[i] = a._vals[i];
127  return *this;
128 }
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>
template<typename Scalar >
boostcopy::enable_if_c<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 190 of file RankFourTensor.h.

191  {
192  libmesh_assert_equal_to(p, Scalar(0));
193  this->zero();
194  return *this;
195  }
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 419 of file RankFourTensorImplementation.h.

420 {
421  for (auto i : make_range(N))
422  for (auto j : make_range(N))
423  {
424  stm << "i = " << i << " j = " << j << '\n';
425  for (auto k : make_range(N))
426  {
427  for (auto l : make_range(N))
428  stm << std::setw(15) << (*this)(i, j, k, l) << " ";
429 
430  stm << '\n';
431  }
432  }
433 
434  stm << std::flush;
435 }
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 439 of file RankFourTensorImplementation.h.

440 {
441  for (unsigned int i = 0; i < N; ++i)
442  for (unsigned int j = 0; j < N; ++j)
443  {
444  stm << "i = " << i << " j = " << j << '\n';
445  for (unsigned int k = 0; k < N; ++k)
446  {
447  for (unsigned int l = 0; l < N; ++l)
448  stm << std::setw(15) << MetaPhysicL::raw_value((*this)(i, j, k, l)) << " ";
449 
450  stm << '\n';
451  }
452  }
453 
454  stm << std::flush;
455 }
auto raw_value(const Eigen::Map< T > &in)
Definition: ADReal.h:73
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 387 of file RankFourTensorImplementation.h.

388 {
389  RankFourTensorTempl<T> old = *this;
390 
391  unsigned int 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  unsigned int index2 = 0;
398  T sum = 0.0;
399  for (auto m : make_range(N))
400  {
401  const T & a = R(i, m);
402  for (auto n : make_range(N))
403  {
404  const T & ab = a * R(j, n);
405  for (auto o : make_range(N))
406  {
407  const T & abc = ab * R(k, o);
408  for (auto p : make_range(N))
409  sum += abc * R(l, p) * old._vals[index2++];
410  }
411  }
412  }
413  _vals[index++] = sum;
414  }
415 }
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 1020 of file RankFourTensorImplementation.h.

1021 {
1023 
1024  for (unsigned int i = 0; i < N; i++)
1025  for (unsigned int j = 0; j < N; j++)
1026  for (unsigned int k = 0; k < N; k++)
1027  for (unsigned int l = 0; l < N; l++)
1028  for (unsigned int m = 0; m < N; m++)
1029  R(i, j, k, l) += (*this)(m, j, k, l) * A(i, m);
1030 
1031  return R;
1032 }
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 1036 of file RankFourTensorImplementation.h.

1037 {
1039 
1040  for (unsigned int i = 0; i < N; i++)
1041  for (unsigned int j = 0; j < N; j++)
1042  for (unsigned int k = 0; k < N; k++)
1043  for (unsigned int l = 0; l < N; l++)
1044  for (unsigned int m = 0; m < N; m++)
1045  R(i, j, k, l) += (*this)(i, m, k, l) * A(j, m);
1046 
1047  return R;
1048 }
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 1052 of file RankFourTensorImplementation.h.

1053 {
1055 
1056  for (unsigned int i = 0; i < N; i++)
1057  for (unsigned int j = 0; j < N; j++)
1058  for (unsigned int k = 0; k < N; k++)
1059  for (unsigned int l = 0; l < N; l++)
1060  for (unsigned int m = 0; m < N; m++)
1061  R(i, j, k, l) += (*this)(i, j, m, l) * A(k, m);
1062 
1063  return R;
1064 }
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 1068 of file RankFourTensorImplementation.h.

1069 {
1071 
1072  for (unsigned int i = 0; i < N; i++)
1073  for (unsigned int j = 0; j < N; j++)
1074  for (unsigned int k = 0; k < N; k++)
1075  for (unsigned int l = 0; l < N; l++)
1076  for (unsigned int m = 0; m < N; m++)
1077  R(i, j, k, l) += (*this)(i, j, k, m) * A(l, m);
1078 
1079  return R;
1080 }
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 >
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 932 of file RankFourTensorImplementation.h.

933 {
934  // used for volumetric locking correction
935  VectorValue<T> a(3);
936  a(0) = (*this)(0, 0, 0, 0) + (*this)(0, 0, 1, 1) + (*this)(0, 0, 2, 2); // C0000 + C0011 + C0022
937  a(1) = (*this)(1, 1, 0, 0) + (*this)(1, 1, 1, 1) + (*this)(1, 1, 2, 2); // C1100 + C1111 + C1122
938  a(2) = (*this)(2, 2, 0, 0) + (*this)(2, 2, 1, 1) + (*this)(2, 2, 2, 2); // C2200 + C2211 + C2222
939  return a;
940 }

◆ 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 920 of file RankFourTensorImplementation.h.

921 {
922  // used in the volumetric locking correction
923  T sum = 0;
924  for (auto i : make_range(N))
925  for (auto j : make_range(N))
926  sum += (*this)(i, i, j, j);
927  return sum;
928 }
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 505 of file RankFourTensorImplementation.h.

506 {
507  zero();
508 
509  if (input.size() == 9)
510  {
511  // then fill from vector C_1111, C_1112, C_1122, C_1212, C_1222, C_1211, C_2211, C_2212, C_2222
512  (*this)(0, 0, 0, 0) = input[0];
513  (*this)(0, 0, 0, 1) = input[1];
514  (*this)(0, 0, 1, 1) = input[2];
515  (*this)(0, 1, 0, 1) = input[3];
516  (*this)(0, 1, 1, 1) = input[4];
517  (*this)(0, 1, 0, 0) = input[5];
518  (*this)(1, 1, 0, 0) = input[6];
519  (*this)(1, 1, 0, 1) = input[7];
520  (*this)(1, 1, 1, 1) = input[8];
521 
522  // fill in remainders from C_ijkl = C_ijlk = C_jikl
523  (*this)(0, 0, 1, 0) = (*this)(0, 0, 0, 1);
524  (*this)(0, 1, 1, 0) = (*this)(0, 1, 0, 1);
525  (*this)(1, 0, 0, 0) = (*this)(0, 1, 0, 0);
526  (*this)(1, 0, 0, 1) = (*this)(0, 1, 0, 1);
527  (*this)(1, 0, 1, 1) = (*this)(0, 1, 1, 1);
528  (*this)(1, 0, 0, 0) = (*this)(0, 1, 0, 0);
529  (*this)(1, 1, 1, 0) = (*this)(1, 1, 0, 1);
530  }
531  else if (input.size() == 2)
532  {
533  // only two independent constants, C_1111 and C_1122
534  (*this)(0, 0, 0, 0) = input[0];
535  (*this)(0, 0, 1, 1) = input[1];
536  // use symmetries
537  (*this)(1, 1, 1, 1) = (*this)(0, 0, 0, 0);
538  (*this)(1, 1, 0, 0) = (*this)(0, 0, 1, 1);
539  (*this)(0, 1, 0, 1) = 0.5 * ((*this)(0, 0, 0, 0) - (*this)(0, 0, 1, 1));
540  (*this)(1, 0, 0, 1) = (*this)(0, 1, 0, 1);
541  (*this)(0, 1, 1, 0) = (*this)(0, 1, 0, 1);
542  (*this)(1, 0, 1, 0) = (*this)(0, 1, 0, 1);
543  }
544  else
545  mooseError("Please provide correct number of inputs for surface RankFourTensorTempl<T> "
546  "initialization.");
547 }
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:299
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 475 of file RankFourTensorImplementation.h.

476 {
477  RankFourTensorTempl<T> result;
478 
479  for (auto i : make_range(N))
480  for (auto j : make_range(N))
481  for (auto k : make_range(N))
482  for (auto l : make_range(N))
483  result(i, j, k, l) = (*this)(j, i, k, l);
484 
485  return result;
486 }
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 490 of file RankFourTensorImplementation.h.

491 {
492  RankFourTensorTempl<T> result;
493 
494  for (auto i : make_range(N))
495  for (auto j : make_range(N))
496  for (auto k : make_range(N))
497  for (auto l : make_range(N))
498  result(i, j, k, l) = (*this)(i, j, l, k);
499 
500  return result;
501 }
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 459 of file RankFourTensorImplementation.h.

460 {
461  RankFourTensorTempl<T> result;
462 
463  unsigned int index = 0;
464  for (auto i : make_range(N))
465  for (auto j : make_range(N))
466  for (auto k : make_range(N))
467  for (auto l : make_range(N))
468  result._vals[index++] = _vals[k * N3 + i * N + j + l * N2];
469 
470  return result;
471 }
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 1001 of file RankFourTensorImplementation.h.

1004 {
1006  for (unsigned int i = 0; i < N; i++)
1007  for (unsigned int j = 0; j < N; j++)
1008  for (unsigned int k = 0; k < N; k++)
1009  for (unsigned int l = 0; l < N; l++)
1010  for (unsigned int m = 0; m < N; m++)
1011  for (unsigned int n = 0; n < N; n++)
1012  for (unsigned int t = 0; t < N; t++)
1013  R(i, j, k, l) += (*this)(m, n, t, l) * A(i, m) * B(j, n) * C(k, t);
1014 
1015  return R;
1016 }
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 982 of file RankFourTensorImplementation.h.

985 {
987  for (unsigned int i = 0; i < N; i++)
988  for (unsigned int j = 0; j < N; j++)
989  for (unsigned int k = 0; k < N; k++)
990  for (unsigned int l = 0; l < N; l++)
991  for (unsigned int m = 0; m < N; m++)
992  for (unsigned int n = 0; n < N; n++)
993  for (unsigned int t = 0; t < N; t++)
994  R(i, j, k, l) += (*this)(m, n, k, t) * A(i, m) * B(j, n) * C(l, t);
995 
996  return R;
997 }
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 963 of file RankFourTensorImplementation.h.

966 {
968  for (unsigned int i = 0; i < N; i++)
969  for (unsigned int j = 0; j < N; j++)
970  for (unsigned int k = 0; k < N; k++)
971  for (unsigned int l = 0; l < N; l++)
972  for (unsigned int m = 0; m < N; m++)
973  for (unsigned int n = 0; n < N; n++)
974  for (unsigned int t = 0; t < N; t++)
975  R(i, j, k, l) += (*this)(m, j, n, t) * A(i, m) * B(k, n) * C(l, t);
976 
977  return R;
978 }
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 944 of file RankFourTensorImplementation.h.

947 {
949  for (unsigned int i = 0; i < N; i++)
950  for (unsigned int j = 0; j < N; j++)
951  for (unsigned int k = 0; k < N; k++)
952  for (unsigned int l = 0; l < N; l++)
953  for (unsigned int m = 0; m < N; m++)
954  for (unsigned int n = 0; n < N; n++)
955  for (unsigned int t = 0; t < N; t++)
956  R(i, j, k, l) += (*this)(i, m, n, t) * A(j, m) * B(k, n) * C(l, t);
957 
958  return R;
959 }
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 115 of file RankFourTensorImplementation.h.

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

116 {
117  for (auto i : make_range(N4))
118  _vals[i] = 0.0;
119 }
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

◆ RankFourTensorTempl

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

Definition at line 503 of file RankFourTensor.h.

◆ RankThreeTensorTempl

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

Definition at line 505 of file RankFourTensor.h.

◆ RankTwoTensorTempl

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

Definition at line 501 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: