Compaction rubber roller analysis issue (with linear isotropic material assumption) #808
Replies: 1 comment 2 replies
-
Hi @yvanblanchard, I won't give support and won't have a look on notebooks - sorry. Please use text-based code-blocks for your questions.
Nearly-incompressible materialsFor nearly incompressible materials like the silicone rubber of the provided paper, you have to use # rubber
E = 1.4 # MPa
nu = 0.4995
# ...
rubber = fem.SolidBodyNearlyIncompressible(
umat=fem.NeoHooke(mu=E / (2 * (1 + nu))),
field=field,
bulk=E / (3 * (1 - 2 * nu)), # MPa
)
# ... Here's the complete script.import numpy as np
import matplotlib.pyplot as plt
import felupe as fem
# geometry
r = 20 # mm
R = 40 # mm
length = 1 # mm
# load
initial_compression = (R - r) / 4 # mm
F = 5 # N
# rubber
E = 1.4 # MPa
nu = 0.4995
# meshing
nradial = 11 # number of radial points
ntheta = 181 # number of circ. points
# revolve two line-meshes, one for the rubber, one for the coating with equal `ntheta`
mesh = fem.mesh.Line(a=r, b=R, n=nradial).revolve(ntheta, phi=360)
# add control points to the mesh
mesh.update(points=np.vstack([mesh.points, [0, -R * 1.1], [0, 0]]))
# remove them from "points-without-cells"
# (otherwise the degrees-of-freedoms of these points would be ignored)
mesh.points_without_cells = mesh.points_without_cells[:-2]
# create a region & field (for boundary conditions)
region = fem.RegionQuad(mesh)
field = fem.FieldContainer([fem.FieldPlaneStrain(region, dim=2)])
# masks
x, y = mesh.points.T
inner = np.isclose(np.sqrt(x**2 + y**2), r)
outer = np.isclose(np.sqrt(x**2 + y**2), R)
# hyperelastic solid body
rubber = fem.SolidBodyNearlyIncompressible(
umat=fem.NeoHooke(mu=E / (2 * (1 + nu))),
field=field,
bulk=E / (3 * (1 - 2 * nu)), # MPa
)
# constraints (rigid bottom-plate and multi-point-c. from inner-radius to center-point)
bottom = fem.MultiPointContact(
field,
points=np.arange(mesh.npoints)[outer],
centerpoint=-2,
skip=(1, 0),
)
mpc = fem.MultiPointConstraint(
field,
points=np.arange(mesh.npoints)[inner],
centerpoint=-1,
skip=(0, 0),
)
# initial boundary conditions
boundaries_pre = {
"center": fem.Boundary(field[0], fx=0, fy=0, mode="and", skip=(0, 1)),
"move": fem.Boundary(
field[0],
fx=0,
fy=0,
mode="and",
skip=(1, 0),
value=-R * 0.1 - initial_compression,
),
"bottom": fem.dof.Boundary(field[0], fy=mesh.y.min()),
}
# initial compression load case
step_pre = fem.Step(
items=[rubber, bottom, mpc],
boundaries=boundaries_pre,
)
job_pre = fem.CharacteristicCurve(steps=[step_pre], boundary=boundaries_pre["center"])
job_pre.evaluate()
# boundary conditions
boundaries = {
"center": fem.Boundary(field[0], fx=0, fy=0, mode="and", skip=(0, 1)),
"bottom": fem.dof.Boundary(field[0], fy=mesh.y.min()),
}
# point load
load = fem.PointLoad(field, points=[-1], values=[0, -F / length])
# load case
step = fem.Step(
items=[rubber, bottom, mpc, load],
boundaries=boundaries,
)
job = fem.Job(steps=[step], boundary=boundaries["center"])
job.evaluate()
ax = field.imshow("Principal Values of Logarithmic Strain", project=fem.topoints)
# Create a region on the boundary and shift the Cauchy Stress, located at the
# quadrature points, to the mesh-points
# (instead of `fem.topoints(values, region)`,
# one could also use `fem.project(values, region)`).
boundary = fem.RegionQuadBoundary(mesh, mask=outer, ensure_3d=True)
stress = fem.topoints(rubber.evaluate.cauchy_stress(field), region).reshape(-1, 9)
# Create a new displacement field only on the boundary and link it to the existing
# displacement field.
displacement = fem.FieldContainer([fem.FieldPlaneStrain(boundary, dim=2)])
displacement.link(field)
# Obtain the deformation gradient on the surface-quadrature points and evaluate the
# surface normals on the deformed configuration at the quadrature points.
F = displacement.extract()[0]
N = boundary.normals
n = fem.math.dot(F, N, mode=(2, 1))
n /= fem.math.norm(n, axis=0)
# Interpolate the Cauchy-stress to the surface-quadrature points and evaluate the
# Cauchy stress-normal component (=contact pressure).
σ = fem.Field(boundary, values=stress).interpolate().reshape(F.shape)
p = -fem.math.ddot(σ, fem.math.dya(n, n, mode=1))
# Project the contact pressure from the surface-quadrature points to the mesh points
# for points which are in contact.
points_in_contact = bottom.results.force.reshape(-1, 2).nonzero()[0]
contact_pressure = np.zeros(mesh.npoints)
contact_pressure[points_in_contact] = fem.project(p, boundary)[points_in_contact]
# View the contact pressure
view = field.view(point_data={"Contact Pressure": contact_pressure})
view.plot(
"Contact Pressure",
show_undeformed=False,
style="points",
plotter=field.plot(color="white", plotter=bottom.plot(line_width=3, opacity=0.1)),
).show()
# Evaluate and plot the contact pressure (length)
mesh_deformed = mesh.copy(points=mesh.points + field[0].values)
points_in_contact = [
points_in_contact[0] - nradial,
*points_in_contact[:-1],
points_in_contact[-2] + nradial,
]
contact_coords = mesh_deformed.x[points_in_contact]
contact_length = contact_coords.max() - contact_coords.min()
# Ensure that the mesh-points are already sorted
assert np.allclose(np.argsort(contact_coords), np.arange(len(contact_coords)))
# Print displacements of the center of the roller
# a) the displacement field is the first field of the field container
# b) the center point is the last point of the mesh (manually added to the mesh points)
# c) the initial gap is subtracted from the displacement field
u = field[0].values - np.array([[0, -0.1 * R]])
print(f"Δd(center) = {u[-1, 1]:.2f} mm")
# Print deformed coordinates on the outer radius
# a) the displacement values are added to the mesh point coordinates
# b) the outer-mask is applied
X = mesh.points
x = X + u
# print(f"x(outer radius) = {x[outer]} mm")
fig, ax = plt.subplots()
ax.plot(
mesh_deformed.x[points_in_contact],
contact_pressure[points_in_contact],
marker="o",
label=f"Contact Length $\Delta x$ = {np.round(contact_length, 2)} mm",
)
ax.set_xlabel(r"Position $x$ in mm")
ax.set_ylabel(r"Contact Pressure in MPa")
ax.legend()
This time, the results from the paper
are very similar to the ones from this script. I slightly modified the contact pressure plot to include the zero values at the start and the end for a more precise contact length value.P.S.: This simulation model is still stable if you refine the mesh. nradial = 21 # number of radial points
ntheta = 721 # number of circ. points |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Hello,
I tried to model the compaction of a rubber roller but I face a convergence issue (max number of iterations reached).
Material: rubber , assumed as isotropic linear material (without any coating/cover material), considering that deformation is small enough (less than 20%).
Here is the python notebook file:
RollerCompaction-FEA_Felupe-Jiang.zip
Paper/article (input values and ref results):
jiang2021.pdf
Thank you for your help!
Beta Was this translation helpful? Give feedback.
All reactions