Skip to main content

PySimHub

RapidFEM

Electromagnetic FEM solver written in Rust, distributed as a Python package on PyPI. Two backends sit behind one geometry / material / physics API: a frequency-domain solver (Nédélec first-kind curl-conforming elements, complex-symmetric sparse linear algebra) and a time-domain DGTD solver (nodal discontinuous Galerkin, Krylov/ETD exponential time integration, model-order reduction). The geometry is non-dimensionalised before assembly, so sub-micron RFIC passives and metre-scale structures use the same numerical path. An optional Flask-based local UI provides a code editor and a live viewer.

Install

pip install rapidfem            # solver only
pip install rapidfem[ui]        # solver + local UI

Wheels for Windows, Linux, and macOS are built in CI; the Rust core is compiled ahead of time, so no Rust toolchain is needed on the user's machine. Gmsh (the gmsh Python wheel) is pulled in automatically and provides the OpenCASCADE geometry kernel and mesher used by rapidfem.Geometry.

Quick start (Python API)

import numpy as np
import rapidfem as rf

# Build geometry; attach materials + physics directly to entities
g = rf.Geometry(maxh=rf.lambda_maxh(f_max=12e9))
air = g.box(22.86e-3, 10.16e-3, 30e-3, position=(-11.43e-3, -5.08e-3, 0),
            material=rf.Air())

rf.RectWaveguidePort(air.faces.min(axis="z"))
rf.RectWaveguidePort(air.faces.max(axis="z"))
rf.PEC(*air.faces.unassigned)

g.mesh()

# Define the problem once, run any number of analyses on it
prob = rf.Problem(g)                      # Problem is the frequency-domain ProblemFD
result = prob.sweep(np.linspace(8e9, 12e9, 21))
print(result.frequencies.shape, result.sparams.shape)

# The same Problem can also drive an eigenmode solve or a far-field pattern:
# modes   = prob.eigenmode(target_frequency=10e9, n_modes=6)
# pattern = prob.farfield(result, freq_idx=10, port_idx=0)

python_src/rapidfem/examples/ has end-to-end runs: microstrip and coupled lines, iris and stepped-impedance filters, patch / Vivaldi / inverted-F antennas (PML + far-field), pyramidal horns, dielectric resonators, and the fd_rfic_* on-chip passives. RFIC geometry comes from a process stack and layout via rapidfem.rfic (rfic.Stack, Geometry.from_gds).

Importing external CAD and meshes

g.load(path) brings external geometry into the scene; the action is chosen from the file extension.

g = rf.Geometry(maxh=rf.lambda_maxh(f_max=20e9))

# STEP / IGES / BREP land in the same OpenCASCADE kernel as the primitives,
# so the result is a normal GeoObject: boolean it, transform it, select its
# faces, attach materials and physics, exactly like a g.box(...).
part = g.load("horn.step", material=rf.Air())   # mm STEP -> metres by default
post = g.cylinder(radius=0.5e-3, height=5e-3)
g.cut(part, post)                                # compose CAD with primitives
g.rotate(part, math.pi / 2, axis=(0, 1, 0))      # full transform API applies
rf.RectWaveguidePort(part.faces.max(axis="z"))
rf.PEC(*part.faces.unassigned)
g.mesh()

# Place/orient any import at load time, like a primitive's position= kwarg:
part = g.load("horn.step", position=(0, 0, 5e-3), rotation=(math.pi, (0, 0, 1)))

# STL is a surface triangulation, healed into a meshable solid. It is a discrete
# body (its geometry is the mesh), so it stays standalone: it takes a material,
# physics, placement and meshing, but it cannot be combined with OCC primitives
# or boolean ops (export STEP/IGES/BREP for that). STL is unit-less; pass scale=
# (metres per file unit) for a model authored in mm.
g = rf.Geometry(maxh=0.5e-3)
blob = g.load("antenna.stl", material=rf.Air(), scale=1e-3, position=(0, 0, 1e-3))

# A pre-built .msh volume mesh is already tessellated, so loading one switches
# the geometry into mesh mode: its named physical groups become selectable
# handles for materials and physics. g.mesh() bakes the bindings (no remeshing)
# and the usual Problem/sweep pipeline runs unchanged.
g = rf.Geometry()
scene = g.load("waveguide.msh")
scene.group("air").material = rf.Air()
rf.RectWaveguidePort(scene.group("port_in"))
rf.RectWaveguidePort(scene.group("port_out"))
rf.PEC(scene.group("walls"))
g.mesh()
result = rf.Problem(g).sweep(np.linspace(8e9, 12e9, 21))

unit= sets the target unit OpenCASCADE converts a STEP/IGES file into (default "M", so a millimetre file arrives at metre coordinates); scale= is an extra metres-per-file-unit factor for unit-less STL or a mis-declared CAD unit. examples/fd_step_import.py is a full STEP-driven sweep.

Local UI

rapidfem serve ./my_project/

Opens a browser window with a CodeMirror Python editor, a 3D geometry / mesh / field viewer (raw WebGL2), and S-parameter plots. The geometry view updates on save (Ctrl+S); mesh and solver runs are explicit. Results stream in as the solve runs; fields are fetched on demand as you scrub frequency and port. rapidfem.show(g) sends a geometry to the viewer.

Features

  • Geometry builder: OpenCASCADE primitives with boolean ops, transforms, and fillet/chamfer. Ready-made RF structures in rf.structures (coax, microstrip, CPW, stripline, waveguides, helix) build geometry and ports in one call.
  • External CAD / mesh import: g.load(path) pulls in STEP / IGES / BREP solids as composable primitives, heals STL surfaces into meshable solids, or loads a pre-built .msh and exposes its named physical groups for material / physics binding.
  • RFIC / GDS: rapidfem.rfic process stacks and Geometry.from_gds build on-chip passives, solved after non-dimensionalisation down to sub-micron features.
  • Element: Nédélec first-kind curl-conforming tetrahedral elements, order 2 (20 DOFs per cell), in a hierarchical basis. Opt-in per-cell mixed order (1-2) via [element] order_policy = "adaptive"; the default is uniform order 2.
  • Excitations: rectangular waveguide ports (arbitrary TE modes), lumped ports (TEM, multi-line voltage integral), coax and wave ports, Floquet plane-wave port (normal incidence), first-order absorbing boundary.
  • PML: anisotropic stretched-coordinate perfectly matched layer.
  • Lossy materials: complex permittivity with loss tangent and conductivity, surface impedance for metals, Debye dispersion; cached across sweeps.
  • Sparse solvers: pure-Rust rslab complex-symmetric LDLᵀ (Bunch-Kaufman) with a-priori memory estimates; optional MKL PARDISO where mkl_rt is installed.
  • Frequency sweep: assembles E/B once, refactors only the frequency-dependent K per point, reuses the symbolic factorisation pattern.
  • Eigenmode solver: shift-invert Lanczos in the B inner product, with a per-mode residual check.
  • Adaptive refinement: residual error estimator with Dörfler marking, exports a size field for gmsh re-meshing.
  • Output: Touchstone (.s1p/.s2p/.snp), VTK field export, far-field NFFT.
  • Parallel assembly: rayon-based element matrix evaluation.

Time-domain backend (DGTD)

ProblemTD, behind the same API, compiles a structure into an explicit linear ODE dy/dt = A·y and exposes it as a model at every level:

  • DGTD: nodal discontinuous Galerkin on tetrahedra, upwind or energy-conserving central flux.
  • Exponential time integration: matrix-free Krylov/ETD propagator, exact for the linear system at any step size (no CFL limit).
  • Model export / reduction: the RHS, the verbatim sparse operator A, an exponential stepper, or Krylov-projected reduced models.
  • Materials: heterogeneous, lossy, anisotropic, and Debye-dispersive media; matched absorbing layers; periodic boundaries.
  • Output: field probes, RFT transfer function, VTK field-animation export.
import rapidfem as rf

ptd  = rf.ProblemTD.box(size=(1, 1, 1), cells=(2, 2, 2), order=2)
traj = ptd.transient(y0, dt=0.02, steps=200)   # turnkey transient
rom  = ptd.reduce(y0, dim=60)                   # model-order reduction
A    = ptd.state_space()                        # the verbatim operator

Method notes and the ProblemTD API are in docs/td-backend.md.

Solver backends

Solver Type Notes
rslab Complex-symmetric LDLᵀ (Bunch-Kaufman) Pure Rust, no native dependencies, always available. Numeric-only refactorisation across sweeps, a-priori RAM gate.
MKL PARDISO Complex-symmetric LDLᵀ Opt-in, needs mkl_rt on PATH.

Select with RAPIDFEM_SOLVER ("auto", "pardiso", "rslab"), set before import rapidfem. The default "auto" tries PARDISO, then rslab. For MKL: conda install mkl or pip install mkl (ensure mkl_rt is on PATH).

Verification

cargo test --release pins the element and solver kernels against independent symbolic derivations to machine precision: the Nédélec element matrices, the barycentric integration coefficients, the surface-element trace, the hierarchical-basis and exact-sequence properties, the global assembly, and the eigensolver against a densely computed cavity spectrum. The derivations, completeness proofs, and entrywise cross-checks live in derivations/.

python/tests/ runs end-to-end S-parameter checks on microstrip, stripline, CPW, waveguide, filter, and antenna geometries against closed-form values. Those run real solves, so they are run locally (cd python && pytest -m slow), not in CI.

Acknowledgments

rapidfem began as a Rust port of EMerge (PyPI), Robert Fennis' open-source Python electromagnetic FEM solver. Its script-first design shaped the geometry / material / physics API, and the early releases ported its Python implementation to Rust. Thanks to Robert Fennis for building and sharing it.

The solver kernels have since been independently re-derived from primary sources: Nédélec's edge-element construction, standard microwave theory, and the barycentric integration identities. The derivations and cross-checks are in derivations/.

License

GPL-3.0-or-later with the Gmsh additional permission; see LICENSE. Copyright (C) Milan Rother and rapidfem contributors; commercial terms available.

Metadata

Release files for rapidfem 0.22.1

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

Source distribution (sdist)

Source distribution for rapidfem 0.22.1
File Size Uploaded
rapidfem-0.22.1.tar.gz 84.3 MB Details

Built distributions (wheels)

Table of built distributions (wheels) for rapidfem 0.22.1
File Interpreter ABI Platform
rapidfem-0.22.1-cp310-abi3-win_amd64.whl CPython 3.10 abi3 Windows x86-64 Details
rapidfem-0.22.1-cp310-abi3-manylinux_2_39_x86_64.whl CPython 3.10 abi3 Linux glibc 2.39+ x86-64 Details
rapidfem-0.22.1-cp310-abi3-macosx_11_0_arm64.whl CPython 3.10 abi3 macOS 11.0+ ARM64 Details

Total release size: 340.4 MB

Release files / rapidfem-0.22.1.tar.gz

Download URL rapidfem-0.22.1.tar.gz
Size 84.3 MB
Tags Source
SHA-256 checksum
How to use checksums
53890a58e957f08ee5b8fec387276b16715a0027a86d8afc3a55e92a3f902a21
BLAKE2b-256 checksum
How to use checksums
e564922d74e6fb36dc05d678d457c04a28c15dc1a3f9202677206394d8d6a60d
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 Aug 13, 2026.

Transparency log

Release files / rapidfem-0.22.1-cp310-abi3-win_amd64.whl

Download URL rapidfem-0.22.1-cp310-abi3-win_amd64.whl
Size 85.5 MB
Tags CPython 3.10 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
0d8140f9da2a3dede4e340f0be3356438425f9e791004439f7eceeb0406ca720
BLAKE2b-256 checksum
How to use checksums
137bec5f7639ac542e265cdbbb729574d188ad7dfe316a17c273800df079558f
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 Aug 13, 2026.

Transparency log

Release files / rapidfem-0.22.1-cp310-abi3-manylinux_2_39_x86_64.whl

Download URL rapidfem-0.22.1-cp310-abi3-manylinux_2_39_x86_64.whl
Size 85.6 MB
Tags CPython 3.10 Linux glibc 2.39+ x86-64 abi3
SHA-256 checksum
How to use checksums
dcf6682e2095488c5053ff5d63fc36a13b58cf8fbb460871720dcc40cb7aad59
BLAKE2b-256 checksum
How to use checksums
3ba486c2736387583089d4d81903ede454a9f5fac8d3494ad5c9d451a5817502
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 Aug 13, 2026.

Transparency log

Release files / rapidfem-0.22.1-cp310-abi3-macosx_11_0_arm64.whl

Download URL rapidfem-0.22.1-cp310-abi3-macosx_11_0_arm64.whl
Size 85.0 MB
Tags CPython 3.10 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
93abb92412fa37c24ee86cd056e868506f52f00844652c13eb241936faedd9ab
BLAKE2b-256 checksum
How to use checksums
5e5eacc19655b2dacee6c60d958e9540500efd197f70623bf2c81438df346736
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 Aug 13, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.22.1 This release

4 release files

0.22.0

4 release files

0.20.0

4 release files

0.19.0

4 release files

0.18.1

4 release files

0.18.0

4 release files

0.17.0

4 release files

0.16.0

4 release files

0.15.0

4 release files

0.13.1

4 release files

0.13.0

4 release files

0.10.2

4 release files

0.10.1

4 release files

0.10.0

4 release files

0.9.0

4 release files

0.8.0

4 release files

0.7.1

4 release files

0.6.0

4 release files

0.5.0

4 release files

0.4.0

4 release files

0.3.0

4 release files

0.2.1

4 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