Solid Mechanics#

The mechanics submodule contains classes for the generation of solid bodies. Solid body objects are supported as items of the Newton-Rhapson procedure.

Solid Body#

The generation of internal force vectors or stiffness matrices of solid bodies are provided as assembly-methods of a felupe.SolidBody. The correct integral form is chosen based on the felupe.Field inside the felupe.FieldContainer.

import felupe as fe

neohooke = fe.NeoHooke(mu=1.0, bulk=5000.0)
mesh = fe.Cube(n=6)
region = fe.RegionHexahedron(mesh)
displacement = fe.Field(region, dim=3)
field = fe.FieldContainer([displacement])

body = fe.SolidBody(umat=neohooke, field=field)
internal_force = body.assemble.vector(field, parallel=False, jit=False)
stiffness_matrix = body.assemble.matrix(field, parallel=False, jit=False)

During assembly, several results are stored, e.g. the gradient of the strain energy density function per unit undeformed volume (first Piola-Kirchhoff stress tensor). Other results are the deformation gradient or the fourth-order elasticity tensor associated to the first Piola-Kirchhoff stress tensor.

F = body.results.kinematics
P = body.results.stress
A = body.results.elasticity

The Cauchy stress tensor, as well as the gradient and the hessian of the strain energy density function per unit undeformed volume are obtained by evaluate-methods of the solid body.

P = body.evaluate.gradient(field)
A = body.evaluate.hessian(field)
s = body.evaluate.cauchy_stress(field)

Body Force (Gravity) on a Solid Body#

The generation of internal force vectors or stiffness matrices of body forces acting on solid bodies are provided as assembly-methods of a felupe.SolidBodyGravity. The correct integral form is chosen based on the felupe.Field inside the felupe.FieldContainer. If the internal field is a mixed field, the assembled vectors from the gravity contribution have to be resized to the dimensions of the internal force vector.

body = fe.SolidBodyGravity(field=field, gravity=[9810, 0, 0], density=7.85e-9)

internal_force_gravity = body.assemble.vector(
    field, parallel=False, jit=False, resize=internal_force
)

Pressure Boundary on a Solid Body#

The generation of internal force vectors or stiffness matrices of pressure boundaries on solid bodies are provided as assembly-methods of a felupe.SolidBodyPressure. The correct integral form is chosen based on the felupe.Field inside the felupe.FieldContainer. If the internal field is a mixed field, the assembled vectors and matrices from the pressure contribution have to be resized to the dimensions of the internal force vector and the stiffness matrix.

region_pressure = fe.RegionHexahedronBoundary(
    mesh=mesh,
    only_surface=True, # select only faces on the outline
    mask=mesh.points[:, 0] == 0, # select a subset of faces on the surface
)

displacement_boundary = fe.Field(region_pressure, dim=3)
field_boundary = fe.FieldContainer([displacement_boundary])
displacement_boundary.values = displacement.values # link field values

body_pressure = fe.SolidBodyPressure(field=field_boundary)

internal_force_pressure = body_pressure.assemble.vector(
    field=field_boundary, parallel=False, jit=False, resize=internal_force
)

stiffness_matrix_pressure = body_pressure.assemble.matrix(
    field=field_boundary, parallel=False, jit=False, resize=stiffness_matrix
)

For axisymmetric problems the boundary region has to be created with the attribute ensure_3d=True.

mesh = fe.Rectangle(a=(0, 30), b=(20, 40), n=(21, 11))
region = fe.RegionQuad(mesh)

region_pressure = fe.RegionQuadBoundary(
    mesh=mesh,
    only_surface=True, # select only faces on the outline
    mask=mesh.points[:, 0] == 0, # select a subset of faces on the surface
    ensure_3d=True, # flag for axisymmetric boundary region
)

displacement = fe.FieldAxisymmetric(region)
displacement_boundary = fe.FieldAxisymmetric(region_pressure)
displacement_boundary.values = displacement.values # link field values