The accompanying Jupyter notebook can be obtained here 1_thermoelasticity
Linear thermoelasticity
The temperature field is uncoupled from the mechanical fields whereas the latter depend on the temperature due to presence of thermal strains in the thermoelastic constitutive relation. This situation can be described as weak thermomechanical coupling.
Problem position
We consider the case of a rectangular 2D domain of dimensions
from dolfin import *
from mshr import *
import matplotlib.pyplot as plt
%matplotlib inline
L, H = 5, 3
mesh = RectangleMesh(Point(0., 0.), Point(L, H), 100, 10, "crossed")
def lateral_sides(x, on_boundary):
return (near(x[0], 0) or near(x[0], L)) and on_boundary
def bottom(x, on_boundary):
return near(x[1], 0) and on_boundary
def top(x, on_boundary):
return near(x[1], H) and on_boundary
Because of the weak coupling discussed before, the thermal and mechanical problem can be solved separately. As a result, we don't need to resort to Mixed FunctionSpaces but can just define separately both problems.
The temperature is solution to the following equation
where
VT = FunctionSpace(mesh, "CG", 1)
T_, dT = TestFunction(VT), TrialFunction(VT)
Delta_T = Function(VT, name="Temperature increase")
aT = dot(grad(dT), grad(T_))*dx
LT = Constant(0)*T_*dx
bcT = [DirichletBC(VT, Constant(50.), bottom),
DirichletBC(VT, Constant(0.), top),
DirichletBC(VT, Constant(0.), lateral_sides)]
solve(aT == LT, Delta_T, bcT)
plt.figure(figsize=(18, 8))
p = plot(Delta_T)
plt.colorbar(p)
plt.show()
Mechanical problem
The linearized thermoelastic constitutive equation is given by:
where
E = Constant(50e3)
nu = Constant(0.2)
mu = E/2/(1+nu)
lmbda = E*nu/(1+nu)/(1-2*nu)
alpha = Constant(1e-5)
f = Constant((0, 0))
def eps(v):
return sym(grad(v))
def sigma(v, dT):
return (lmbda*tr(eps(v))- alpha*(3*lmbda+2*mu)*dT)*Identity(2) + 2.0*mu*eps(v)
Vu = VectorFunctionSpace(mesh, 'CG', 2)
du = TrialFunction(Vu)
u_ = TestFunction(Vu)
Wint = inner(sigma(du, Delta_T), eps(u_))*dx
aM = lhs(Wint)
LM = rhs(Wint) + inner(f, u_)*dx
bcu = DirichletBC(Vu, Constant((0., 0.)), lateral_sides)
u = Function(Vu, name="Displacement")
First, the self-weight loading is deactivated, only thermal stresses are computed.
solve(aM == LM, u, bcu)
plt.figure(figsize=(18, 8))
p = plot(1e3*u[1],title="Vertical displacement [mm]")
plt.colorbar(p)
plt.show()
plt.figure(figsize=(18, 8))
p = plot(sigma(u, Delta_T)[0, 0],title="Horizontal stress [MPa]")
plt.colorbar(p)
plt.show()