# Overview

The tensor mechanics module provides a powerful system for solving solid mechanics problems using a simple to use syntax based on tensor forms. Rather then converting the tensors to matrices that take advantage of the inherent symmetries, tensor objects have been created for Rank 2 and Rank 4 tensors. This approach allows the tensor equations to be implemented directly, which especially simplifies the development of polycrystalline models that require frequent tensor rotations.

# Mathematical introduction

A material varies from its rest shape due to stress. This departure from the rest shape is called deformation or displacement, and the proportion of deformation to original size is called strain. To determine the deformed shape and the stress, a governing equation is solved to determine the displacement vector $$\mathbf{u}$$$. The strong form of the governing equation on the domain $$\Omega$$$ and boundary $$\Gamma=\Gamma_{\mathit{\iota _i}}\cup\Gamma_{\mathit{g_i}}$$$can be stated as follows: \begin{eqnarray} \nabla \cdot\boldsymbol{\sigma} + \mathbf{b} &=& \mathbf{0} \;\mathrm{in}\;\Omega \\ \mathbf{u} &=& \mathbf{g}\;\mathrm{in}\;\Gamma_{ \mathbf{g}} \\ \boldsymbol{\sigma} \cdot \mathbf{n}&=&\boldsymbol{\iota}\;\mathrm{in}\;\Gamma_{ \boldsymbol{\iota}} \end{eqnarray} where $$\boldsymbol{\sigma}$$$ is the Cauchy stress tensor, $$\mathbf{u}$$$is the displacement vector, $$\mathbf{b}$$$ is the body force, $$\mathbf{n}$$$is the unit normal to the boundary, $$\mathbf{g}$$$ is the prescribed displacement on the boundary and $$\boldsymbol{\iota}$$$is the prescribed traction on the boundary. The weak form of the residual equation is expressed as: \begin{eqnarray} \mathbb{R} = \left( \boldsymbol{\sigma}, \nabla \phi_m \right) - \left< \boldsymbol{\iota}, \phi_m \right> - \left( \mathbf{b}, \phi_m \right) = \mathbf{0}, \end{eqnarray} where $$(\cdot)$$$ and $$\left< \cdot \right>$$$represent volume and boundary integrals, respectively. The solution of the residual equation with Newton's method requires the Jacobian of the residual equation, which can be expressed as (ignoring boundary terms) \begin{eqnarray} \mathbb{J} = \left( \frac{\partial \boldsymbol{\sigma}}{\partial \nabla \mathbf{u}} , \nabla \phi_m \right). \end{eqnarray} The material stress response is described by the constitutive model, where the stress is determined as a function of the strain. Assuming linear elasticity (only valid for small strains), the material response is linear, i.e. $$\boldsymbol{\sigma} = \boldsymbol{\mathcal{C}}(\boldsymbol{\epsilon})$$$. The tensor mechanics system can handle linear elasticity and finite strain mechanics, including both elasticity and plasticity.

Porepressure ("PoroMechanics") may also be used in TensorMechanics. Further information can be found on the PoroMechanics page.

# Using TensorMechanics

## Code

### Materials

The materials classes in Tensor Mechanics are where stresses, strains, and other relevant materials information are calculated. There is one base class, TensorMechanicsMaterial, and multiple derived classes for linear elasticity, crystal plasticity, and large-deformation plasticity.

#### TensorMechanicsMaterial

TensorMechanicsMaterial handles a fully anisotropic, single-crystal materials elastic constants. Depending on the specified crystallography (filling type), it can take up to 21 independent stiffness tensor inputs.

There are several virtual methods, which can be overridden in derived classes:

virtual void computeProperties()
// all other method calls must start from within here; calls computeStrain(), vomputeQpElasticityTensor(), computeQpStress()

virtual void computeQpElasticityTensor()
// computes the local elasticity tensor

virtual void computeStrain()
//computes the strain by calling computeQpStrain()

virtual void computeQpStrain()=0
//Calculates the strain, MUST be overridden in derived classes

virtual void computeQpStress()=0
//calculates the stress, MUST be overridden in derived classes


In addition, internal class variables include the gradients of the displacements from the current and previous timesteps, Euler angles, the temperature (if it exists in the simulation), and materials properties of the stress, the elastic strain, the elasticity tensor, and the Jacobian multiplier for the elastostatic equilibrium equations.

### Tensor classes

The basis for Tensor Mechanics is the tensor representation classes. The two base classes are RankTwoTensor and RankFourTensor, which as expected hold 3x3 values and 3x3x3x3 values, respectively. A suite of operators and get/set methods are available.

#### Specifying values from an input file

Both RankTwoTensor and RankFourTensor allow a user to specify how to the tensor from an input file.

void RankTwoTensor::fillFromInputVector(const std::vector<Real> input)


takes a vector of six or nine inputs. If six inputs are used, the appropriate symmetries are maintained ($$\sigma_{ij} = \sigma_{ji}$$$). void RankFourTensor::fillFromInputVector(const std::vector<Real> input, FillMethod fill_method)  takes a vector of inputs of the appropriate length to fill in the tensor, with the appropriate symmetries maintained ($$C_{ijkl} = C_{klij}, C_{ijkl} = C_{ijlk}, C_{ijkl} = C_{jikl}$$$). Several fill methods are available to specify additional symmetries:

antisymmetric
symmetric9
symmetric21
general_isotropic
symmetric_isotropic
antisymmetric_isotropic
general


There is error checking on the input vector length and the enumerator type.

#### Getting and setting values

Both RankTwoTensor and RankFourTensor allow a user to get and set values from the tensor using the bracket () notation.

RankTwoTensor a;
a(i,j) = val;


sets the i,j component of the tensor to val. We use zero based indexing for the dimensions (0, 1, and 2).

RankFourTensor b;
b(i,j,k,l) = val;


sets the i,j,k,l component of the tensor to val. We use zero based indexing for the dimensions (0, 1, and 2).

Use the same notation to read tensor components.

RankTwoTensor a;
RankFourTensor b;
Real c;
c = a(0,0);
c = b(0,0,0,0);


#### Operators

A wide array of mathematical operators exist for the tensors in TensorMechanics.

##### RankTwoTensor

The following operators are available for RankTwoTensor, with the values in parentheses indicating what the type of the other object to be subject to the operation.

=
+= (RankTwoTensor)
-= (RankTwoTensor)
*= (Real, RankTwoTensor)
/= (Real)
+ (RankTwoTensor)
- (RankTwoTensor)
* (Real, RankTwoTensor, TypeTensor<Real>)
/ (Real)


zero()
transpose()
L2norm()
row(int) (returns a TypeVector<Real>)
rotate(RealTensorValue)
rotate(RankTwoTensor)
rotateXyPlane(Real)
doubleContraction()
deviatoric (traceless part)
trace()
dtrace() (derivatives of trace() wrt tensor entries)
secondInvariant() (second invariant of the symmetric part of deviatoric)
dsecondInvariant()  (derivatives of secondInvariant() wrt tensor entries)
d2secondInvariant()  (second derivatives of secondInvariant() wrt tensor entries)
thirdInvariant() (third invariant of the symmetric part of deviatoric, ie det(deviatoric + deviatoric.transpose())/2)
dthirdInvariant()  (derivatives of thirdInvariant() wrt tensor entries)
d2thirdInvariant()  (second derivatives of thirdInvariant() wrt tensor entries)
sin3Lode()  (sin of three times the Lode angle)
dsin3Lode()  (derivatives of sin3Lode() wrt tensor entries)
d2sin3Lode()  (second derivatives of sin3Lode() wrt tensor entries)
det() (determinant)
ddet()  (derivatives of det() wrt tensor entries)
inverse()
symmetricEigenvalues  (eigenvalues of symmetric part of tensor)
dsymmetricEigenvalues  (derivatives of symmetricEigenvalues wrt the tensor entries)
d2symmetricEigenvalues (second derivatives of symmetricEigenvalues wrt the tensor entries)


These methods a thoroughly tested using CPPUNIT.

##### RankFourTensor

The following operators are available for RankFourTensor, with the values in parentheses indicating what the type of the other object to be subject to the operation.

=
+= (RankFourTensor)
-= (RankFourTensor)
*= (Real)
/= (Real)
+ (RankFourTensor)
- (RankFourTensor)
* (RankTwoTensor, RealTensorValue, Real)
/ (Real)


## Visualization of stresses and strains and other tensor components

To visualize stresses, strains, and elasticity tensor components, there are several auxiliary kernels available. This necessitates also using auxiliary variables. RankTwoAux is used to output a RankTwoTensor component, and RankFourAux is used to output a RankFourTensor component. For example, $$\sigma_{11}, \epsilon_{22}$$$, and $$C_{1122}$$$ can be visualized by first declaring auxiliary variables for them in the input file:

[AuxVariables]
[./s11_aux]
order = CONSTANT
family = MONOMIAL
[../]

[./e22_aux]
order = CONSTANT
family = MONOMIAL
[../]

[./C1122_aux]
order = CONSTANT
family = MONOMIAL
[../]
[]


Next, the appropriate auxiliary kernels are used. They require the name of the material property that you wish to see the field value for, and the indices of the tensor value (either 0, 1, or 2). For example,

[AuxKernels]
[./report_s11]
type = RankTwoAux
rank_two_tensor = stress      # this is the name of the material property
index_i = 0                   # this is the first index, i, from 0 to 2
index_j = 0                   # this is the 2nd index, j, from 0 to 2
variable = s11_aux            # auxilliary variable declared previously
[../]

[./report_e22]
type = RankTwoAux
rank_two_tensor = elastic_strain
index_i = 1
index_j = 1
variable = e22_aux
[../]

[./report_C1122]
type = RankFourAux
rank_four_tensor = elasticity_tensor
index_i = 0
index_j = 0
index_k = 1
index_l = 1
variable = C1122_aux
[../]
[]