[FElupe v0.1.1] - Axisymmetric Analysis with (u,p,J) Mixed-Formulation and Isotropic Hyperelasticity #86
Replies: 4 comments
-
The problem in the above is example is that FElupe v0.1.1 does not understand the hessian shape of madati (u,p,J) materials. This is the reason for the following lines of the above code in the newton-scheme: A[1] = A[1][:, :, 0, 0]
A[2] = A[2][:, :, 0, 0]
A[3] = A[3][0, 0, 0, 0]
A[4] = A[4][0, 0, 0, 0]
A[5] = A[5][0, 0, 0, 0] FElupe is expecting a shape of |
Beta Was this translation helpful? Give feedback.
-
By going through this old example it is really nice how FElupe has evolved since the last two years. I'll update this example and eventually add it to the docs. |
Beta Was this translation helpful? Give feedback.
-
This is a first idea for a new example with a dynamic mesh. import felupe as fem
import numpy as np
layers = [2, 11, 2, 11, 2]
lines = [
fem.mesh.Line(a=0, b=13, n=21).expand(n=1).translate(2, axis=1),
fem.mesh.Line(a=0, b=13, n=21).expand(n=1).translate(2.5, axis=1),
fem.mesh.Line(a=-0.2, b=10, n=21).expand(n=1).translate(4.5, axis=1),
fem.mesh.Line(a=-0.2, b=10, n=21).expand(n=1).translate(5, axis=1),
fem.mesh.Line(a=-0.4, b=7, n=21).expand(n=1).translate(6.5, axis=1),
fem.mesh.Line(a=-0.4, b=7, n=21).expand(n=1).translate(7, axis=1),
]
faces = fem.MeshContainer(
[
first.fill_between(second, n=n)
for first, second, n in zip(lines[:-1], lines[1:], layers)
]
)
point = lambda m: m.points[np.unique(m.cells)].mean(axis=0) - np.array([2, 0])
mask = lambda m: np.unique(m.cells)
kwargs = dict(axis=1, exponent=2.5, normalize=True)
faces.points[:] = (
faces[1]
.add_runouts([3], centerpoint=point(faces[1]), mask=mask(faces[1]), **kwargs)
.points
)
faces.points[:] = (
faces[3]
.add_runouts([7], centerpoint=point(faces[3]), mask=mask(faces[3]), **kwargs)
.points
)
faces.points[:21] = faces.points[21 : 2 * 21]
faces.points[-21:] = faces.points[-2 * 21 : -21]
faces.points[:] = faces[0].rotate(15, axis=2).points
faces[0].y[:21] = 2
faces[-1].y[-21:] = 8.5
mesh = fem.MeshContainer([faces.stack([1, 3]), faces.stack([0, 2, 4])])
mesh.imshow(colors=[None, "white"], show_edges=True, opacity=1)
mesh = fem.MeshContainer(
[m.revolve(n=73, phi=270).rotate(-90, axis=1).rotate(-90, axis=2) for m in mesh]
)
mesh.imshow(colors=[None, "white"], show_edges=True, opacity=1) |
Beta Was this translation helpful? Give feedback.
-
Unfortunately, Read-the-docs can't handle such examples. The only way would be to share them tested with Github Actions in a separate repo? Locally, it takes less than a minute to complete. codeimport felupe as fem
import numpy as np
import pypardiso
layers = [2, 11, 2, 11, 2]
lines = [
fem.mesh.Line(a=0, b=13, n=21).expand(n=1).translate(2, axis=1),
fem.mesh.Line(a=0, b=13, n=21).expand(n=1).translate(2.5, axis=1),
fem.mesh.Line(a=-0.2, b=10, n=21).expand(n=1).translate(4.5, axis=1),
fem.mesh.Line(a=-0.2, b=10, n=21).expand(n=1).translate(5, axis=1),
fem.mesh.Line(a=-0.4, b=7, n=21).expand(n=1).translate(6.5, axis=1),
fem.mesh.Line(a=-0.4, b=7, n=21).expand(n=1).translate(7, axis=1),
]
faces = fem.MeshContainer(
[
first.fill_between(second, n=n)
for first, second, n in zip(lines[:-1], lines[1:], layers)
]
)
point = lambda m: m.points[np.unique(m.cells)].mean(axis=0) - np.array([2, 0])
mask = lambda m: np.unique(m.cells)
kwargs = dict(axis=1, exponent=2.5, normalize=True)
faces.points[:] = (
faces[1]
.add_runouts([3], centerpoint=point(faces[1]), mask=mask(faces[1]), **kwargs)
.points
)
faces.points[:] = (
faces[3]
.add_runouts([7], centerpoint=point(faces[3]), mask=mask(faces[3]), **kwargs)
.points
)
faces.points[:21] = faces.points[21 : 2 * 21]
faces.points[-21:] = faces.points[-2 * 21 : -21]
faces.points[:] = faces[0].rotate(15, axis=2).points
faces[0].y[:21] = 2
faces[-1].y[-21:] = 8.5
container = fem.MeshContainer([faces.stack([1, 3]), faces.stack([0, 2, 4])])
container.imshow(colors=[None, "white"], show_edges=True, opacity=1)
container = fem.MeshContainer(
[
m.revolve(n=37, phi=180).rotate(-90, axis=1).rotate(-90, axis=2)
for m in container
],
merge=True,
decimals=4,
)
container.imshow(colors=[None, "white"], show_edges=True, opacity=1)
mesh = container.stack()
region = fem.RegionHexahedron(mesh)
field = fem.FieldContainer([fem.Field(region, dim=3)])
regions = [fem.RegionHexahedron(m) for m in container]
fields = [fem.FieldsMixed(r, n=1) for r in regions]
boundaries, loadcase = fem.dof.uniaxial(field, clamped=True, axis=2, sym=(0, 1, 0))
solids = [
fem.SolidBodyNearlyIncompressible(fem.NeoHooke(mu=1), fields[0], bulk=200),
fem.SolidBody(fem.LinearElasticLargeStrain(E=2.1e5, nu=0.3), fields[1]),
]
move = fem.math.linsteps([0, -1.5], num=3)
ramp = {boundaries["move"]: move}
step = fem.Step(
items=[
*solids,
],
ramp=ramp,
boundaries=boundaries,
)
job = fem.Job(steps=[step])
job.evaluate(x0=field, tol=1e-1, solver=pypardiso.spsolve, parallel=True)
boundaries, loadcase = fem.dof.shear(
field,
axes=(0, 2),
moves=(0, 0, -1.5),
sym=True,
)
move = fem.math.linsteps([0, 0.5], num=5)
ramp = {boundaries["move"]: move}
step = fem.Step(
items=[
*solids,
],
ramp=ramp,
boundaries=boundaries,
)
job = fem.Job(steps=[step])
job.evaluate(x0=field, tol=1e-2, solver=pypardiso.spsolve, parallel=True)
plotter = fields[1].plot(show_undeformed=False, color="white", show_edges=False)
fields[0].plot(
"Principal Values of Logarithmic Strain",
show_undeformed=False,
project=fem.topoints,
plotter=plotter,
).show() |
Beta Was this translation helpful? Give feedback.
-
This is an axisymmetric example of a mixed field formulation for the treatment of nearly-incompressibility. Matadi is used for the definition of the material behavior. The (Nastran) mesh file is located here - download and save it as
conical-spring.bdf
.In the first step, the mesh is read with the help of
meshio
. A FElupe mesh is created with the imported points and cells.Next, we set up our problem.
The original mesh is now rotated. In order to update the regions and fields, we re-define them once again.
The constitutive (hyperelastic) material behavior is defined by matadi:
Finally, a newton-rhapson - procedure obtains equilibrium on all active dof's:
Results are exported via meshio. Steel stress results are set to zero before export in order to visualize the stress state in the rubber. Note that the stress on the steel-rubber boundary is not true because it is divided by the number of cells per point.
Output of residuals:
Beta Was this translation helpful? Give feedback.
All reactions