Skip to main content

NuSA

A Python library for structural analysis using the finite element method, designed for academic purposes.

PyPI Python License

Releases

  • 0.1.0 (16/11/2016)
  • 0.2.0 (14/07/2019)
  • 0.3.0a1 First alpha release (20/09/2026)
  • 0.3.0b1 Beta release (21/09/2026)
  • 0.3.0rc1 Release candidate (22/09/2026)
  • 0.3.0rc2 Release candidate (22/09/2026)
  • 0.3.0 Stable release (23/09/2026)
  • 0.4.0 Stable release (06/10/2026)

Requirements

NuSA requires Python 3.10 or newer and installs NumPy, Matplotlib, tabulate, and meshio as Python dependencies.

The nusa.mesh helpers can read triangular meshes immediately after installing NuSA. Generating new meshes from geometry additionally requires the external Gmsh executable to be installed and available on PATH.

Installation

Install the current PyPI release:

pip install nusa

Mesh-file support through meshio is included in the default installation. The historical nusa[mesh] extra remains accepted as a compatibility alias, but is no longer required.

To generate meshes, install Gmsh separately and verify that NuSA can discover it:

gmsh --version

Install the current development branch directly from GitHub:

pip install "nusa @ git+https://github.com/JorgeDeLosSantos/nusa.git@develop"

For local development:

git clone https://github.com/JorgeDeLosSantos/nusa.git
cd nusa
git checkout develop
python -m pip install -e ".[test]"
python -m pytest

Analysis workflow

NuSA 0.4 separates finite-element problem definition from solved state:

from nusa import LinearStaticAnalysis, solve

result = solve(model)

# Equivalent explicit form:
result = LinearStaticAnalysis().solve(model)

Model contains topology, loads, and prescribed displacements. A solve returns an independent StaticResult snapshot containing displacements, reactions, nodal forces, and canonical element results.

Supported element types

  • Spring
  • Bar
  • Truss
  • Beam
  • Linear triangle (plane stress formulation)

Mini-Demos

Linear Triangle Element

import numpy as np

from nusa import LinearTriangle, LinearTriangleModel, Node, plot_model
import nusa.mesh as nmsh

md = nmsh.Modeler()
a = md.add_rectangle((0,0),(1,1), esize=0.1)
b = md.add_circle((0.5,0.5), 0.1, esize=0.05)
md.subtract_surfaces(a,b)
nc, ec = md.generate_mesh()
x,y = nc[:,0], nc[:,1]

nodes = []
elements = []

for k,nd in enumerate(nc):
    cn = Node((x[k],y[k]))
    nodes.append(cn)
    
for elm in ec:
    i, j, k = int(elm[0]), int(elm[1]), int(elm[2])
    ni, nj, nk = nodes[i], nodes[j], nodes[k]
    ce = LinearTriangle((ni, nj, nk), 200e9, 0.3, 0.1)
    elements.append(ce)

model = LinearTriangleModel()
for node in nodes: model.add_node(node)
for elm in elements: model.add_element(elm)
    
# Boundary conditions and loads
minx, maxx = min(x), max(x)
miny, maxy = min(y), max(y)

for node in nodes:
    if np.isclose(node.x, minx):
        model.add_constraint(node, ux=0, uy=0)
    if np.isclose(node.x, maxx):
        model.add_force(node, (10e3,0))

plot_model(model)
result = model.solve()
result.plot_nodal_field("von_mises_stress")

Spring element

Example 01. For the spring assemblage with arbitrarily numbered nodes shown in the figure, obtain (a) the displacements of nodes 3 and 4, (b) the reaction forces at nodes 1 and 2, and (c) the forces in each spring. A force of 5000 lb is applied at node 4 in the x direction. The spring constants are given in the figure. Nodes 1 and 2 are fixed.

# NuSA Demo
from nusa import Node, Spring, SpringModel
    
def test1():
    """
    Logan, D. (2007). A first course in the finite element analysis.
    Example 2.1, pp. 42.
    """
    P = 5000.0

    # Model
    m1 = SpringModel("2D Model")

    # Nodes
    n1 = Node((0,0))
    n2 = Node((0,0))
    n3 = Node((0,0))
    n4 = Node((0,0))

    # Elements
    e1 = Spring((n1,n3),1000.0)
    e2 = Spring((n3,n4),2000.0)
    e3 = Spring((n4,n2),3000.0)

    # Adding elements and nodes to the model
    for nd in (n1,n2,n3,n4):
        m1.add_node(nd)
    for el in (e1,e2,e3):
        m1.add_element(el)

    m1.add_force(n4, (P,))
    m1.add_constraint(n1, ux=0)
    m1.add_constraint(n2, ux=0)
    result = m1.solve()
    return result

if __name__ == '__main__':
    test1()

Beam element

Example 02. For the beam and loading shown, determine the deflection at point C. Use E = 29 x 106 psi.

"""
Beer & Johnston. (2012) Mechanics of materials. 
Problem 9.13 , pp. 568.
"""
from nusa import Beam, BeamModel, Node

# Input data 
E = 29e6
I = 291 # W14x30 
P = 35e3
L1 = 5*12 # in
L2 = 10*12 #in
# Model
m1 = BeamModel("Beam Model")
# Nodes
n1 = Node((0,0))
n2 = Node((L1,0))
n3 = Node((L1+L2,0))
# Elements
e1 = Beam((n1,n2),E,I)
e2 = Beam((n2,n3),E,I)

# Add elements and nodes
for nd in (n1,n2,n3): m1.add_node(nd)
for el in (e1,e2): m1.add_element(el)
    
m1.add_force(n2, (-P,))
m1.add_constraint(n1, uy=0) # pin
m1.add_constraint(n3, uy=0) # roller
result = m1.solve()

# Displacement at C point
print(result.displacement(n2)["uy"])

GUIs based on NuSA

Documentation and Examples

You can view the online documentation at the following link: https://jorgedelossantos.github.io/nusa/.

The repository also contains historical Jupyter notebooks under docs/nusa-info/. Some of those notebooks predate the 0.3.0 API and are retained as archival material; the executable scripts under examples/ and the current Sphinx documentation are the recommended references for the current API.

About...

Developer: Pedro Jorge De Los Santos E-mail: delossantosmfq@gmail.com

Metadata

Release files for nusa 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for nusa 0.4.0
File Size Uploaded
nusa-0.4.0.tar.gz 56.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for nusa 0.4.0
File Interpreter ABI Platform
nusa-0.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 88.4 kB

Release files / nusa-0.4.0.tar.gz

Download URL nusa-0.4.0.tar.gz
Size 56.2 kB
Tags Source
SHA-256 checksum
How to use checksums
6eb856989a1e38772c4af462fcf012812950f5a573b932aad6c8af2579116bfb
BLAKE2b-256 checksum
How to use checksums
27239a15064474900a4ef5e75497172e866440cf37d52874b82e69b3191742f4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release files / nusa-0.4.0-py3-none-any.whl

Download URL nusa-0.4.0-py3-none-any.whl
Size 32.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
501cb7b42eae6cf828e4e68a78b4452f0fcac54254eb8ee0b5ac2bc522c4dcc7
BLAKE2b-256 checksum
How to use checksums
f67ebf40f9b780b59e7a77d94b93c1116d8f9958d35b51bafcf978d3cf6ad85d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.4.0 This release

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page