The accompanying Jupyter notebook can be obtained here 2_load_and_boundary_conditions
Loads and boundary conditions
The preceding tutorial focused on body forces. However, in situations where you need to apply traction force or a Dirichlet Boundary Condition (DBC) to specific parts of the mesh, this tutorial will address those scenarios.
Mesh entities
Conceptually, a mesh (modeled by the class Mesh), consists of a collection of mesh entities. A mesh entity is a pair (d, i), where d is the topological dimension of the mesh entity and i is a unique index of the mesh entity. Mesh entities are numbered within each topological dimension from 0 to nd − 1, where nd is the number of mesh entities of topological dimension d.
Entity | Dimension |
---|---|
Vertex | 0 |
Edge | 1 |
Face | 2 |
Facet | D-1 |
Cell | D |
length, depth = .6, .200
num_ele_along_depth = 10
ele_size = depth/num_ele_along_depth
mesh = RectangleMesh(Point(0, 0), Point(length, depth),
int(length/ele_size), int(depth/ele_size))
V = FunctionSpace(mesh, 'CG', 1)
U = VectorFunctionSpace(mesh, 'CG', 1)
T0 = TensorFunctionSpace(mesh, 'DG', 0)
Define the boundaries (Subdomains)
clamped_boundary = CompiledSubDomain("near(x[0],0)")
load_boundary = CompiledSubDomain("near(x[1],0.2) && x[0]>0.5")
Mark the boundaries on mesh
support_tag, load_tag = 1, 2
mf = MeshFunction("size_t", mesh, 1)
mf.set_all(0)
clamped_boundary.mark(mf,support_tag)
load_boundary.mark(mf,load_tag)
Visualize the boundaries
\[
\begin{align}
\sigma &= \lambda\,\hbox{tr}\,(\varepsilon) I + 2\mu\varepsilon,\\
\varepsilon &= \frac{1}{2}\left(\nabla u + (\nabla u)^{\top}\right),
\end{align}
\]
lmbda = (E * nu) / ((1 + nu) * (1 - 2 * nu))
mu = E / (2 * (1 + nu))
def epsilon(u):
return 0.5*(grad(u) + grad(u).T)
def sigma(u):
return lmbda*tr(epsilon(u))*Identity(dim) + 2*mu*epsilon(u)
a = inner(sigma(u), epsilon(v))*dx
t = Constant((0,100))
L = dot(f, v)*dx + dot(t,v)*ds(load_tag)
# Compute solution
u = Function(U)
solve(a == L, u, bc)
plt.figure(figsize=(18, 16))
# Plot solution
scale_factor = 1e5
plot(u*scale_factor, title='Displacement', mode='displacement')
<matplotlib.collections.PolyCollection at 0x7f38d4d042b0>
-1.8010419648112784e-06
plt.figure(figsize=(18, 16))
# Plot stress
s = sigma(u) - (1./3)*tr(sigma(u))*Identity(dim) # deviatoric stress
von_Mises = sqrt(3./2*inner(s, s))
von_Mises = project(von_Mises, V)
plot(von_Mises, title='Von Mises stress')
<matplotlib.tri.tricontour.TriContourSet at 0x7f38d4c3d1d0>
plt.figure(figsize=(18, 16))
# Compute magnitude of displacement
u_magnitude = sqrt(dot(u, u))
u_magnitude = project(u_magnitude, V)
plot(u_magnitude, 'Displacement magnitude')
print('min/max u:',
u_magnitude.vector().vec().array.min(),
u_magnitude.vector().vec().array.max())
min/max u: -5.71041349380966e-13 1.8360022678476485e-06
<matplotlib.tri.tricontour.TriContourSet at 0x7f38d4af0b38>
<matplotlib.tri.tricontour.TriContourSet at 0x7f38d4a8ad68>
<matplotlib.tri.tricontour.TriContourSet at 0x7f38d4a100f0>