2D truss finite element solver in Python. Assembles the stiffness matrix, solves for displacements, computes stress, strain, axial forces and reactions, and visualizes the deformed structure.
- Sparse stiffness matrix assembly (
scipy.sparse) - Stability check via minimum eigenvalue before solving
- Residual check after solving for numerical quality assurance
- Stress, strain, and axial force per bar
- Deformed shape visualization with coolwarm stress colormap
- Automatic force arrow scaling
- Support symbols (pin, roller-x, roller-y) inferred from boundary conditions
PlotSettingsdataclass for full visualization control
- numpy>=1.24
- scipy>=1.10
- matplotlib>=3.7
- Python 3.9+ recommended.
from truss2d import Nodes, Bars, PlotSettings, solve_truss, plot_truss
import numpy as np
nodes = Nodes(
coordinates=np.array([
[0, 4], [3, 4], [0, 0], [3, 0], [6, 0]
], dtype=float),
forces=np.array([
[0, 0],
[10000, 0],
[0, 0],
[10000, 270],
[0, 0]
], dtype=float),
boundary_conditions=np.array([0, 1, 4, 8, 9]) # 0-based DOF indices
)
bars = Bars(
connectivity=np.array([
[0,1],[0,2],[2,1],[1,3],[1,4],[2,3],[3,4]
]),
E=np.full(7, 2e11), # Pa
A=np.full(7, 1e-5) # m²
)
result = solve_truss(nodes, bars)
result.print_summary(nodes.boundary_conditions)
result.print_summary(nodes.boundary_conditions)
# Default settings
plot_truss(nodes, bars, result)
# Custom settings
plot_truss(nodes, bars, result, PlotSettings(
scale=10, # deformation amplification
force_scale=None, # None = auto-scale arrows
cmap="coolwarm", # stress colormap
figsize=(10, 7),
bar_linewidth=2.5,
undeformed_alpha=0.3,
node_color="black",
node_fontsize=10,
force_color="green",
arrow_width=0.009,
support_symbol_size=0.2, # tune to match truss scale
))Forces are defined as [magnitude, angle_deg] where 0° points in the +X direction and angles increase counter-clockwise.
| Angle | Direction |
|---|---|
| 0° | → +X |
| 90° | ↑ +Y |
| 180° | ← -X |
| 270° | ↓ -Y |
boundary_conditions is a list of 0-based DOF indices to constrain:
- Node
ihas DOFs2i(x) and2i+1(y) - Constrain both to fix a pin support
- Constrain one to model a roller
truss2d/
├── truss2d.py # solver and visualization
├── example_01.py # example 01
└── README.md
TrussResult contains:
| Field | Description |
|---|---|
displacements |
Nodal displacement vector (2n,) |
stress |
Axial stress per bar (m,) |
strain |
Axial strain per bar (m,) |
axial_force |
Axial force per bar (m,) |
reactions |
Full reaction force vector (2n,) |