FEM2D
An open-source Python library for structural finite element analysis of 2D structures.
FEM2D is a Python package for performing 2D finite element analysis (FEA) of structural frames, including truss, beam, and spring elements with support for linear static analysis, geometrically non-linear analysis, and global mass matrix assembly for dynamic analysis.
Features
- Element Library:
- Beam Element: Elastic 2D Euler-Bernoulli beam elements including axial and bending stiffness (shear deformation is neglected). Supports uniform and varying member loads, moment releases (hinges), and rotational/translational mass.
- Truss Element: Pin-jointed bar elements with axial stiffness only. The same
TrussElementclass is used for linear and corotational geometrically-nonlinear analyses. - Spring Element: 2D elastic spring elements with customizable axial stiffness.
- Analysis Types:
- Linear Static Analysis: Standard matrix analysis under nodal loads, distributed loads, and concentrated member loads.
- Geometrically Non-Linear Analysis: Iterative solver using the Newton-Raphson scheme combined with corotational formulations for large displacement/rotation problems. Enabled by passing
geometric_nonlinear=TruetoStructure.solve(...). - Mass Matrix Assembly: Assembles global mass matrices (including rotational inertia and extra non-structural mass) to support modal and eigenvalue analysis.
- Post-Processing & Visualization:
- Pandas Integration: Convert displacements, reactions, and element forces directly into pandas DataFrames for easy analysis and post-processing.
- Graphical Plots: Plot the undeformed/deformed configurations, support conditions, and applied loads using Matplotlib.
Installation
From Source (Developer Install)
-
Clone the repository:
git clone https://github.com/learnstructure/fem-2d.git cd fem-2d
-
Install in editable mode along with development dependencies:
pip install -e .[dev]
Quick Start Examples
1. Linear Static Frame Analysis (High-Level API)
The SimpleFrame class provides a simplified API for building and solving structures.
from fem2d import SimpleFrame
from fem2d.results import Results
# Initialize simple frame
frame = SimpleFrame()
# Define nodes (id, x, y)
frame.add_node(1, 0.0, 0.0)
frame.add_node(2, 0.0, 120.0)
frame.add_node(3, 120.0, 120.0)
frame.add_node(4, 120.0, 0.0)
# Properties
E = 30000.0 # ksi
A = 10.0 # sq. in.
I = 200.0 # in^4
# Add frame elements (id, node_i, node_j, E, A, I)
frame.add_frame(1, 1, 2, E, A, I)
frame.add_frame(2, 2, 3, E, A, I / 2)
frame.add_frame(3, 3, 4, E, A, I)
# Apply fixed supports at base nodes (node_id, [ux, uy, rz])
frame.add_support(1, [True, True, True])
frame.add_support(4, [True, True, True])
# Apply nodal loads (node_id, [Fx, Fy, Mz])
frame.add_node_load(2, [10.0, 0.0, 0.0])
frame.add_node_load(3, [0.0, 0.0, 5.0])
# Solve the structure
frame.solve()
# Retrieve results
results = Results(frame)
print("Node Displacements:\n", results.node_displacements())
print("Reactions:\n", results.reactions())
print("Element End Forces:\n", results.element_forces())
2. Geometrically Non-Linear Truss Analysis
For advanced analyses, use the core Structure class. The same
TrussElement is used for both linear and corotational geometrically
non-linear analyses — pass geometric_nonlinear=True to
Structure.solve(...) to switch on the corotational formulation.
from fem2d import Structure, Node, ElasticMaterial, TrussElement
from fem2d.results import Results
from fem2d.sections import Section
# Create structure and nodes
structure = Structure()
node1 = Node(1, 0.0, 0.0)
node2 = Node(2, 4.0, 3.0)
node3 = Node(3, 8.0, 0.0)
structure.add_node(node1)
structure.add_node(node2)
structure.add_node(node3)
# Material and section
E = 200e6 # Material modulus (kN/m^2)
EA = 45155.0 # axial stiffness (kN)
A = EA / E # cross-sectional area (m^2)
material = ElasticMaterial(E)
section = Section(A)
# Add linear truss elements (corotational path is enabled via solve below)
structure.add_element(TrussElement(1, node1, node2, material, section))
structure.add_element(TrussElement(2, node2, node3, material, section))
structure.add_element(TrussElement(3, node3, node1, material, section))
# Support boundaries — compact (ux, uy) form
node1.set_support(1, 1) # pinned
node3.set_support(0, 1) # roller
# External vertical point force at Node 2
node2.set_load(fx=0.0, fy=-2000.0, mz=0.0)
# Run Newton-Raphson analysis with corotational formulation
structure.solve(geometric_nonlinear=True, tolerance=1e-8, max_iter=30)
# Print displacements and forces
results = Results(structure)
print(results.node_displacements())
print(results.element_forces())
3. Visualizing Structures
You can easily generate visualization plots of undeformed and deformed structural shapes:
from fem2d import DrawStructure
# Initialize plotter with analyzed structure
plotter = DrawStructure(structure, scale=0.05)
# Render structure in Matplotlib window
plotter.draw()
Running Tests
Verify that your installation is working correctly by running the tests:
pytest
Citing FEM2D
If you use fem2d in your academic research or professional work, please cite it as follows:
Mandal, A. (2026). FEM2D: An open-source Python library for structural analysis of 2D structures (v0.4.0). Zenodo. https://doi.org/10.5281/zenodo.20990850
Refer to CITATION.cff for the BibTeX format details.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Release files for fem2d 0.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| fem2d-0.4.0.tar.gz | 44.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| fem2d-0.4.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 91.8 kB
Release files / fem2d-0.4.0.tar.gz
| Download URL | fem2d-0.4.0.tar.gz |
|---|---|
| Size | 44.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c545fe71f9fbbb63a5b80f70e58daab4b70f5e6402403fcc94a376a41d6cc28c
|
|
BLAKE2b-256 checksum How to use checksums |
d1cdc1b7ab926b351f6a157d4d6112f17ab51402393e01c0f4ae154be03e1dce
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.2
|
Release files / fem2d-0.4.0-py3-none-any.whl
| Download URL | fem2d-0.4.0-py3-none-any.whl |
|---|---|
| Size | 47.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f74cf60fd522589e7850ebe1e641d16b21f3806541de3e13e48cd0676d273d14
|
|
BLAKE2b-256 checksum How to use checksums |
cf221a19a46e0f9a2bba27a6de244d7d9188fd484162b1753cb6d5d2def15db1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.2
|