Elastic 3D truss with linear bar elements¶

Open In Colab Binder

A small 3D bridge-like space truss with bottom chords, a top chord, and diagonal bracing.

In [1]:
import torch

from torchfem import Truss
from torchfem.materials import IsotropicElasticity1D

torch.set_default_dtype(torch.float64)

Model setup¶

In [2]:
# Create material
material = IsotropicElasticity1D(210000.0)

# Node layout: two bottom chords (y = +/- 0.6) and one top chord (y = 0, z = 1)
x = torch.tensor([0.0, 2.0, 4.0, 6.0, 8.0])
bottom_left = torch.stack([x, -0.6 * torch.ones_like(x), torch.zeros_like(x)], dim=1)
bottom_right = torch.stack([x, 0.6 * torch.ones_like(x), torch.zeros_like(x)], dim=1)
top = torch.stack([x, torch.zeros_like(x), torch.ones_like(x)], dim=1)
nodes = torch.cat([bottom_left, bottom_right, top], dim=0)

elements = []

# Longitudinal chords
for i in range(4):
    elements.append([i, i + 1])  # bottom left
    elements.append([5 + i, 5 + i + 1])  # bottom right
    elements.append([10 + i, 10 + i + 1])  # top

# Floor beams between both bottom chords
for i in range(5):
    elements.append([i, 5 + i])

# Vertical posts from top chord to deck
for i in range(5):
    elements.append([10 + i, i])
    elements.append([10 + i, 5 + i])

# Side diagonals (Warren-like)
for i in range(4):
    elements.append([i, 10 + i + 1])
    elements.append([i + 1, 10 + i])
    elements.append([5 + i, 10 + i + 1])
    elements.append([5 + i + 1, 10 + i])

# Deck X-bracing
for i in range(4):
    elements.append([i, 5 + i + 1])
    elements.append([5 + i, i + 1])

elements = torch.tensor(elements)

# Create truss
truss = Truss(nodes, elements, material)

# Boundary conditions
truss.constraints[[4, 9], :] = True
truss.constraints[[0, 5], 2] = True
truss.forces[2, 2] = -2.0
truss.forces[7, 2] = -2.0

# Geometrical properties
truss.areas[:] = 0.015
truss.areas[:12] = 0.030  # Chords
truss.areas[12:17] = 0.020  # Floor beams

# Visualize
truss.plot()

Solve¶

In [3]:
u, f, σ, F, α = truss.solve()

Plot stress and deformation¶

In [4]:
# Deformed truss with stress coloring
truss.plot(u=50 * u, element_property={"Stress": σ}, cmap="inferno")