5.1 Tensor Fundamentals
Definition: Tensor
Tensors are generalizations of multidimensional arrays:
Tensors are generalizations of multidimensional arrays:
- 0th-order tensor = scalar
- 1st-order tensor = vector
- 2nd-order tensor = matrix
- nth-order tensor = n-dimensional array
Code Example 1: Tensor Operations with NumPy
Python Implementation: Creating and Manipulating Tensors
# Requirements:
# - Python 3.9+
# - numpy>=1.24.0, <2.0.0
"""
Example: Code Example 1: Tensor Operations with NumPy
Purpose: Demonstrate core concepts and implementation patterns
Target: Beginner to Intermediate
Execution time: ~5 seconds
Dependencies: None
"""
import numpy as np
# Tensors of various orders
scalar = 5.0 # 0th-order
vector = np.array([1, 2, 3]) # 1st-order
matrix = np.array([[1, 2], [3, 4]]) # 2nd-order
tensor_3d = np.random.rand(2, 3, 4) # 3rd-order
print("Tensor Examples:")
print(f"Scalar (0th-order): {scalar}")
print(f" Shape: {np.array(scalar).shape}\n")
print(f"Vector (1st-order): {vector}")
print(f" Shape: {vector.shape}\n")
print(f"Matrix (2nd-order):\n{matrix}")
print(f" Shape: {matrix.shape}\n")
print(f"3rd-order Tensor shape: {tensor_3d.shape}")
print(f" Number of elements: {tensor_3d.size}\n")
# Tensor transpose (axis permutation)
tensor_transposed = np.transpose(tensor_3d, (2, 0, 1)) # (2,3,4) -> (4,2,3)
print(f"Transposed shape: {tensor_transposed.shape}")5.2 Tensor Product and Contraction
Definition: Tensor Operations
- Tensor Product (outer product): (m-th order) ⊗ (n-th order) → (m+n-th order)
- Contraction: operation summing over indices, reduces order by 2
- Inner product: special case of contraction
Code Example 2: Tensor Product and Contraction
Python Implementation: Basic Tensor Operations
# Vector tensor product
a = np.array([1, 2, 3])
b = np.array([4, 5])
# Outer product (tensor product)
tensor_product = np.outer(a, b) # or np.tensordot(a, b, 0)
print("Tensor Product:")
print(f"a = {a} (shape: {a.shape})")
print(f"b = {b} (shape: {b.shape})")
print(f"a ⊗ b =\n{tensor_product}")
print(f"Shape: {tensor_product.shape}\n")
# Contraction (trace)
A = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
trace = np.trace(A) # Sum of diagonal elements (contraction example)
print(f"Matrix A Contraction (Trace):")
print(f"A =\n{A}")
print(f"tr(A) = {trace}\n")
# Einstein summation notation (np.einsum)
# 'ij,jk->ik' is matrix product A @ B
A_test = np.array([[1, 2], [3, 4]])
B_test = np.array([[5, 6], [7, 8]])
result_matmul = np.einsum('ij,jk->ik', A_test, B_test)
result_direct = A_test @ B_test
print("Einstein Summation Notation:")
print(f"A @ B =\n{result_matmul}")
print(f"Match? {np.allclose(result_matmul, result_direct)}")5.3 Symmetric and Antisymmetric Tensors
Theorem: Tensor Symmetry
For 2nd-order tensor T:
For 2nd-order tensor T:
- Symmetric: T_{ij} = T_{ji} (stress tensor, inertia tensor)
- Antisymmetric: T_{ij} = -T_{ji} (rotation tensor, angular velocity tensor)
- Any tensor can be decomposed into symmetric and antisymmetric parts
Code Example 3: Symmetric and Antisymmetric Decomposition
Python Implementation: Symmetric Decomposition of Tensors
# Arbitrary tensor
T = np.array([[3, 7, 2],
[5, 1, 9],
[4, 6, 8]])
# Symmetric part
T_sym = (T + T.T) / 2
# Antisymmetric part
T_antisym = (T - T.T) / 2
print("Symmetric and Antisymmetric Decomposition:")
print(f"Original Tensor T:\n{T}\n")
print(f"Symmetric Part T_sym = (T + T^T)/2:\n{T_sym}\n")
print(f"Antisymmetric Part T_antisym = (T - T^T)/2:\n{T_antisym}\n")
# Verification: T = T_sym + T_antisym
reconstructed = T_sym + T_antisym
print(f"Reconstruction T_sym + T_antisym:\n{reconstructed}")
print(f"Matches original? {np.allclose(T, reconstructed)}\n")
# Confirm symmetry
print(f"T_sym is symmetric? {np.allclose(T_sym, T_sym.T)}")
print(f"T_antisym is antisymmetric? {np.allclose(T_antisym, -T_antisym.T)}")5.4 Stress Tensor
Application Example: Stress Tensor
Stress state in materials is represented by a 2nd-order symmetric tensor: \[\sigma = \begin{pmatrix} \sigma_{xx} & \sigma_{xy} & \sigma_{xz} \\ \sigma_{yx} & \sigma_{yy} & \sigma_{yz} \\ \sigma_{zx} & \sigma_{zy} & \sigma_{zz} \end{pmatrix}\] Diagonal components: normal stress, off-diagonal components: shear stress
Stress state in materials is represented by a 2nd-order symmetric tensor: \[\sigma = \begin{pmatrix} \sigma_{xx} & \sigma_{xy} & \sigma_{xz} \\ \sigma_{yx} & \sigma_{yy} & \sigma_{yz} \\ \sigma_{zx} & \sigma_{zy} & \sigma_{zz} \end{pmatrix}\] Diagonal components: normal stress, off-diagonal components: shear stress
Code Example 4: Principal Stress of Stress Tensor
Python Implementation: Principal Stress Analysis
# Stress tensor (units: MPa)
stress_tensor = np.array([[100, 30, 0],
[30, 60, 0],
[0, 0, 20]])
print("Stress Tensor Analysis:")
print(f"Stress Tensor σ (MPa):\n{stress_tensor}\n")
# Confirm symmetry
print(f"Symmetric tensor? {np.allclose(stress_tensor, stress_tensor.T)}\n")
# Principal stresses (eigenvalues) and principal axes (eigenvectors)
principal_stresses, principal_axes = np.linalg.eigh(stress_tensor)
# Sort in descending order
idx = principal_stresses.argsort()[::-1]
principal_stresses = principal_stresses[idx]
principal_axes = principal_axes[:, idx]
print("Principal Stress Analysis:")
for i in range(3):
print(f"Principal Stress σ{i+1} = {principal_stresses[i]:.2f} MPa")
print(f"Principal Axis Direction: {principal_axes[:, i]}\n")
# Von Mises equivalent stress
sigma_vm = np.sqrt(((principal_stresses[0] - principal_stresses[1])**2 +
(principal_stresses[1] - principal_stresses[2])**2 +
(principal_stresses[2] - principal_stresses[0])**2) / 2)
print(f"Von Mises Equivalent Stress: {sigma_vm:.2f} MPa")5.5 Strain Tensor
Definition: Strain Tensor
From displacement vector u, strain tensor ε is defined as: \[\epsilon_{ij} = \frac{1}{2}\left(\frac{\partial u_i}{\partial x_j} + \frac{\partial u_j}{\partial x_i}\right)\] Diagonal components: linear strain, off-diagonal components: shear strain
From displacement vector u, strain tensor ε is defined as: \[\epsilon_{ij} = \frac{1}{2}\left(\frac{\partial u_i}{\partial x_j} + \frac{\partial u_j}{\partial x_i}\right)\] Diagonal components: linear strain, off-diagonal components: shear strain
Code Example 5: Calculating Strain Tensor
Python Implementation: Strain Tensor Calculation
# Define displacement field (simplified: uniform strain)
# u_x = ε_xx * x + ε_xy * y
# u_y = ε_yx * x + ε_yy * y
# Displacement gradient tensor (du_i/dx_j)
displacement_gradient = np.array([[0.002, 0.001], # [du_x/dx, du_x/dy]
[0.001, 0.003]]) # [du_y/dx, du_y/dy]
# Strain tensor (symmetric part)
strain_tensor = (displacement_gradient + displacement_gradient.T) / 2
# Rotation tensor (antisymmetric part)
rotation_tensor = (displacement_gradient - displacement_gradient.T) / 2
print("Strain Tensor:")
print(f"Displacement Gradient Tensor ∇u:\n{displacement_gradient}\n")
print(f"Strain Tensor ε = (∇u + ∇u^T)/2:\n{strain_tensor}\n")
print(f"Rotation Tensor ω = (∇u - ∇u^T)/2:\n{rotation_tensor}\n")
# Volumetric strain (trace)
volumetric_strain = np.trace(strain_tensor)
print(f"Volumetric Strain (tr ε): {volumetric_strain:.5f}")
# Deviatoric strain tensor
deviatoric_strain = strain_tensor - volumetric_strain/2 * np.eye(2)
print(f"Deviatoric Strain Tensor:\n{deviatoric_strain}")5.6 Elastic Tensor (4th-order Tensor)
Definition: Generalized Hooke's Law
The stress-strain relationship is expressed by elastic tensor C (4th-order): \[\sigma_{ij} = C_{ijkl} \epsilon_{kl}\] For isotropic materials, simplified to two Lame constants λ, μ.
The stress-strain relationship is expressed by elastic tensor C (4th-order): \[\sigma_{ij} = C_{ijkl} \epsilon_{kl}\] For isotropic materials, simplified to two Lame constants λ, μ.
Code Example 6: Stress-Strain Relationship for Isotropic Materials
Python Implementation: Elastic Tensor (Voigt Notation)
# Elastic constants for isotropic material
E = 200e9 # Young's modulus (Pa)
nu = 0.3 # Poisson's ratio
# Lame constants
lambda_lame = (E * nu) / ((1 + nu) * (1 - 2*nu))
mu = E / (2 * (1 + nu)) # Shear modulus
print("Elastic Constants for Isotropic Material:")
print(f"Young's Modulus E = {E/1e9:.0f} GPa")
print(f"Poisson's Ratio ν = {nu}")
print(f"Lame Constant λ = {lambda_lame/1e9:.2f} GPa")
print(f"Shear Modulus μ = {mu/1e9:.2f} GPa\n")
# Elastic tensor in Voigt notation (6×6 matrix)
# [σ_xx, σ_yy, σ_zz, σ_yz, σ_zx, σ_xy]^T = C [ε_xx, ε_yy, ε_zz, 2ε_yz, 2ε_zx, 2ε_xy]^T
C_voigt = np.zeros((6, 6))
# Diagonal components
C_voigt[0:3, 0:3] = lambda_lame
C_voigt += np.diag([2*mu, 2*mu, 2*mu, mu, mu, mu])
print(f"Elastic Tensor (Voigt Notation, GPa):")
print(np.round(C_voigt/1e9, 2))Code Example 7: Stress Calculation from Strain
Python Implementation: Stress-Strain Transformation
# Strain vector (Voigt notation)
strain_voigt = np.array([0.001, 0.0005, 0.0003, 0, 0, 0.0002])
# Calculate stress
stress_voigt = C_voigt @ strain_voigt
print("\nStress-Strain Calculation:")
print(f"Strain ε: {strain_voigt}")
print(f"Stress σ (MPa): {stress_voigt/1e6}")
# Convert to tensor form
stress_tensor_calc = np.array([[stress_voigt[0], stress_voigt[5], stress_voigt[4]],
[stress_voigt[5], stress_voigt[1], stress_voigt[3]],
[stress_voigt[4], stress_voigt[3], stress_voigt[2]]])
print(f"\nStress Tensor σ (MPa):\n{stress_tensor_calc/1e6}")5.7 Application to Crystallography: Crystal Symmetry and Tensors
Note: Due to crystal symmetry, the number of independent components of the elastic tensor decreases.
- Triclinic system: 21 components
- Cubic system: 3 components (close to isotropic)
- Hexagonal system: 5 components
- Triclinic system: 21 components
- Cubic system: 3 components (close to isotropic)
- Hexagonal system: 5 components
Code Example 8: Elastic Tensor for Cubic Crystal
Python Implementation: Elastic Analysis for Cubic Crystal
# Elastic constants for cubic crystal (e.g., Si)
C11 = 165.7e9 # Pa
C12 = 63.9e9
C44 = 79.6e9
# Elastic tensor in Voigt notation
C_cubic = np.array([[C11, C12, C12, 0, 0, 0],
[C12, C11, C12, 0, 0, 0],
[C12, C12, C11, 0, 0, 0],
[0, 0, 0, C44, 0, 0],
[0, 0, 0, 0, C44, 0],
[0, 0, 0, 0, 0, C44]])
print("Elastic Tensor for Cubic Crystal (Si, GPa):")
print(np.round(C_cubic/1e9, 1))
print(f"\nIndependent Elastic Constants: 3 (C11, C12, C44)")
# Deviation from isotropy (Zener anisotropy ratio)
A = 2*C44 / (C11 - C12)
print(f"\nZener Anisotropy Ratio A = 2C44/(C11-C12) = {A:.3f}")
print(f"(A=1 means perfectly isotropic)")
# Bulk modulus and rigidity modulus
K_bulk = (C11 + 2*C12) / 3
G_shear = (C11 - C12 + 3*C44) / 5
print(f"\nAverage Properties:")
print(f"Bulk Modulus K = {K_bulk/1e9:.1f} GPa")
print(f"Shear Modulus G = {G_shear/1e9:.1f} GPa")
# Equivalent Young's modulus and Poisson's ratio (equivalent isotropy)
E_equivalent = 9*K_bulk*G_shear / (3*K_bulk + G_shear)
nu_equivalent = (3*K_bulk - 2*G_shear) / (2*(3*K_bulk + G_shear))
print(f"Equivalent Young's Modulus E = {E_equivalent/1e9:.1f} GPa")
print(f"Equivalent Poisson's Ratio ν = {nu_equivalent:.3f}")Summary
- Tensors are generalizations of multidimensional arrays, unifying scalars, vectors, and matrices
- Tensor product and contraction are fundamental operations, concisely expressed with Einstein summation notation
- Stress and strain tensors are fundamental quantities in solid mechanics (2nd-order symmetric tensors)
- Elastic tensor (4th-order) describes stress-strain relationships, simplified by crystal symmetry
- Principal stress analysis (eigenvalue problem) enables material failure assessment
- Complex tensor operations can be efficiently implemented with NumPy and einsum