Project #2: Review: Tensor vs. Vector Notation
Project #2: Review: Tensor vs. Vector Notation
Project #2: Review: Tensor vs. Vector Notation
Project #2
Since there is no straight-forward way to deal with higher-order tensors in code, we use vector notation. That
is, here and in the following, our code will work with a displacement gradient vector and stress vector. For
example, in 2D we convert tensors into vectors according to
u1,1 σ11
u1,1 u1,2 u1,2 σ 1,1 σ 1,2
σ12
β = ∇u = → β̃ = , σ= → σ̃ = .
u2,1 u2,2 u2,1 σ2,1 σ2,2 σ21
u2,2 σ22
The finite-deformation version is analogous with F̃ and P̃ . The fourth-order incremental tangent tensor now
becomes a simple matrix defined via
∂ σ̃
C̃ = and, e.g., C̃11 = C1111 , C̃12 = C1112 , C̃13 = C1113 , etc.
∂ β̃
That is, according to the stress and strain vectors where indices are ordered as {(11), (12), (21), (22)}, the
indices of C̃ij (with i, j = 1, . . . , 4 in 2D) stand for a pair of indices according to the above order.
For convenience, utility functions are available for the simple conversion between vector and standard notation.
This way we can first define Cijkl in the classical way and then convert to the above vector form. Of course,
you are welcome to use those utility tools in your code.
Finally, recall that we had shown in class that (the finite-deformation version is analogous)
∂W ∂W ∂σij ∂ σ̃i
σij = ⇔ σ̃i = and Cijkl = ⇔ C̃ij = .
∂(∇u)ij ∂ β̃i ∂(∇u)kl ∂ β̃j
Let us implement the 3D isotropic linear elastic material model from Project #1, defined by the energy density
λ 1h i
W (∇u) = (tr ε)2 + µ ε · ε with ε= ∇u + (∇u)T , β = ∇u.
2 2
Let us implement the linear elastic material model as a C++ class that has the following components:
• Use typedef to define the vectors/matrices DisplacementGradient, Stress, Strain, and TangentMatrix
as Eigen::Matrix<double,?,?> with their correct dimensions in 3D.
1
Computational Solid Mechanics (151-0519-00L) October 11, 2017
Fall 2017 Prof. Dennis M. Kochmann, ETH Zürich
• The class constructor should receive two doubles as input (E and ν) and store those within the class
as private members. (Recall the conversion between λ, µ and E, ν derived in Project #1.)
• The class should have a method computeEnergy, which receives the DisplacementGradient vector
β̃ and returns the energy density W as a double.
• The class should have a method computeStress, which receives a DisplacementGradient vector β̃
and returns a Stress vector σ̃.
• The class should have a method computeStrain, which receives a DisplacementGradient vector β̃
and returns the strain vector ε̃ as Strain.
Let us repeat the above implementation for the compressible Neo-Hookean material model from Project #1,
which had the energy density
µ λ
W (F ) = (tr C − 3) + (ln J)2 − µ ln J.
2 2
Now working with β̃, P̃ and C̃, let us implement this material model as a new class having the same methods
as the linear elastic one implemented above.
Let us verify the correct implementation of the above material models by checking if the stresses are indeed
the correct derivatives of the energy, and analogously the tangent matrix the derivative of the stresses. To
this end, we use the forward-Euler finite-difference approximation
f (x + h) − f (x)
f 0 (x) ≈ ,
h
where |h| 1 is a small perturbation. Let us implement a function that verifies if P̃ = ∂W/∂ β̃ and
C̃ = ∂ P̃ /∂ β̃ are implemented correctly, as follows.
Let your new function pick a random (reasonable) β̃ and numerically compute each component of P̃ and
C̃ using the above finite difference approximation (by perturbing each component of β̃ by a small h, one
component at a time). Compare those numerical values to the stress and stiffness values returned by the
material model. The material model passes the test if the relative error between numerical and analytical
derivatives (e.g., ||P̃analytical − P̃numerical ||/||P̃analytical ||) is below a specified tolerance tol.
Use the test function to verify the correct implementation of your own linear elastic and Neo-Hookean models.
For testing, use h = 10−6 and tol = 10−4 and pick some positive material constants.
2
Computational Solid Mechanics (151-0519-00L) October 11, 2017
Fall 2017 Prof. Dennis M. Kochmann, ETH Zürich
• Pick a random β̃ 6= 0.
Compute a perturbed β̃ 0 such that β̃ 0 = β̃ except for one perturbed component β̃i0 = β̃i + h.
• Repeat the above procedure for all components i of β̃ to compute all components of σ̃.
The calculation of C̃ follows analogously: compute σ̃0 , then perturb each component j of β̃ 0 and compute σ̃ 0
for each j. Then Cij,numerical = (σ̃0,i − σ̃i0 )/h.