Plane elasticityΒΆ
The solid mechanics module provides a LinearElasticStress material and one
StressDivergence kernel per displacement component, in plane stress, plane
strain, axisymmetric, or three-dimensional form. The helper
dualmesh.physics.add_plane_elasticity() adds all of them at once.
# SPDX-License-Identifier: LGPL-2.1-or-later
"""A large plate with a circular hole under uniaxial tension.
One quarter of the plate is modelled with an annular mesh graded towards the
hole. The classical stress concentration factor of three is recovered at the
top of the hole. The result is written as a VTK file with the stress
components as cell data.
"""
import math
import dualmesh as dm
import numpy as np
HOLE_RADIUS, OUTER_RADIUS, APPLIED_STRESS = 1.0, 20.0, 1.0
def solve(num_radial_elements=30, num_angular_elements=30):
mesh = dm.generate_annulus_mesh(
inner_radius=HOLE_RADIUS,
outer_radius=OUTER_RADIUS,
num_radial_elements=num_radial_elements,
num_angular_elements=num_angular_elements,
radial_bias=1.15,
)
problem = dm.Problem(mesh)
dm.physics.add_plane_elasticity(
problem, displacements=["u", "v"], youngs_modulus=1.0, poissons_ratio=0.3
)
# symmetry on the two straight edges
problem.add_boundary_condition(
"DirichletBC", "sym_v", variable="v", boundary="start", value=0.0
)
problem.add_boundary_condition("DirichletBC", "sym_u", variable="u", boundary="end", value=0.0)
# remote uniaxial tension applied on the outer arc: t = (sigma n_x, 0)
problem.add_boundary_condition(
"TractionBC",
"remote_x",
variable="u",
boundary="outer",
traction=lambda x, y, z, t: APPLIED_STRESS * x / math.hypot(x, y),
)
problem.add_boundary_condition(
"TractionBC", "remote_y", variable="v", boundary="outer", traction=0.0
)
problem.solve()
return problem
if __name__ == "__main__":
problem = solve()
stress = problem.property_at_centroids("stress")
centroids = np.array(
[problem.mesh.element_centroid(e) for e in range(problem.mesh.num_elements)]
)
radius = np.hypot(centroids[:, 0], centroids[:, 1])
at_hole = radius < HOLE_RADIUS * 1.05
print(
f"maximum sigma_xx near the hole: {np.max(stress[at_hole, 0]):.3f}"
f" (exact stress concentration factor: 3)"
)
problem.write_vtu("plate_with_hole.vtu", cell_properties=["stress"])
print("wrote plate_with_hole.vtu")
Points to note:
Tractions are prescribed with
TractionBC(a component of the traction vector) orPressureBC(a normal pressure), both of which are natural conditions on the equations of the corresponding components.Stresses are material properties, evaluated wherever they are asked for:
problem.property_at_centroids("stress")returns them at element centres, in the Voigt order \((\sigma_{xx}, \sigma_{yy}, \sigma_{zz}, \sigma_{yz}, \sigma_{xz}, \sigma_{xy})\), andwrite_vtuwrites them as cell data.For a thick cylinder under internal pressure the same set-up reproduces Table 9.9.1 of the book; for an axisymmetric model use
coordinates="axisymmetric"andformulation="axisymmetric", which adds the hoop stress to the radial equation automatically.