phase-sweep
Health Uyari
- License — License: Apache-2.0
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 5 GitHub stars
Code Gecti
- Code scan — Scanned 12 files during light audit, no dangerous patterns found
Permissions Gecti
- Permissions — No dangerous permissions requested
Bu listing icin henuz AI raporu yok.
Electromagnetic design sweeps: analytical, FEM and drive models, checked against measured data. Use them from a Python API, web dashboard or MCP server.
phase-sweep
Electromagnetic design sweeps: analytical, FEM, and drive models, checked
against measured data. Use them from a Python API, web dashboard, or MCP
server. Covers PMSM and induction machines, and integrates with
motulator and
NGSolve through optional dependencies.

What it does
phase-sweep reads a motor definition from TOML and runs the models that its
inputs support. A motor with geometry can use the analytical and FEM field
solvers; one with only circuit parameters can still produce torque-speed
envelopes, thermal estimates, and motulator drive simulations. The bundled
motors (motors/ plus the validation anchors under data/) cover radial
and axial-flux machines, including SPM, IPM, outrunner, SynRM, Halbach,
and inset-magnet examples. Published and measured data are
included where licensing permits.
Sweeps can run in parallel and store their results in an append-only JSONL
file. A local browser dashboard runs jobs, plots stored results, and compares
them with imported measurements. An AI agent can submit jobs and read results
over MCP, including model caveats about assumptions and
omissions.
Features
Field solvers
- Closed-form air-gap field (Zhu, Howe & Chan 2002), inrunner and outrunner
- NGSolve 2D FEM: slotted or smooth-bore stators, linear or nonlinear iron,
Maxwell-stress torque - Cogging torque and demagnetization screening
- Axial flux: quasi-3D layer model and multi-plane 2D FEM
- Harmonic decomposition, with an optional CuPy GPU path
Circuit models
- MTPA, stall torque, torque-speed envelope with field weakening
- S1 thermal-duty screening and Bertotti iron loss
- Induction machines: equivalent circuit, torque-slip with deep-bar and
saturation tables, IEEE 112 parameter identification, time-harmonic cage FEM
Drive simulation
- motulator current-control transients, single- or two-mass load
Sweeps and validation
- Parallel parameter sweeps into a crash-safe JSONL result store
- Sensitivity analysis and bounded calibration against measurements
- Measured-data import and cross-validation; FEM checked against Zhu, Howe &
Chan and ElmerFEM
(validation report)
Dashboard
- Local browser dashboard: queue jobs, watch progress, plot results, edit
motor configs
Agent access (MCP)
- MCP endpoint on the same server: per-motor model applicability, dry-run
cost estimates, sweep tables, and results with headline metrics and model
caveats; the dashboard's Agent tab shows tool calls and jobs
Documentation:
motor TOML format |
agent use (MCP) |
architecture |
validation report |
result-store contract |
glossary |
references
Scope and limitations
The field solvers are two-dimensional. The axial models combine several 2D
planes, while separate offline studies estimate 3D effects.
Saturation enters the PMSM circuit models only through a user-supplied[flux_map] (consumed by rated_torque, stall_torque, torque_speed,operating_point, motor_thermal, and drive_sim), and the induction
circuit models only through a user-supplied magnetizing table
([induction] L_m_vs_i); no model predicts a saturated inductance from
geometry. AC winding losses and magnet eddy-current
losses are not implemented.
Install
Requires Python 3.12+.
git clone https://github.com/jonelay/phase-sweep.git
cd phase-sweep
# Full install (all solvers + server + plotting + pytest)
pip install -e ".[all,test]"
# Or core only (circuit-parameter models and result store, no FEM/sim/plots)
pip install -e .
Optional extras:
| Extra | What it adds |
|---|---|
[fem] |
NGSolve FEM field solver |
[sim] |
motulator drive simulation |
[viz] |
matplotlib plotting |
[server] |
FastAPI local server + dashboard |
[all] |
All of the above |
[gpu] |
GPU harmonics (requires CUDA 12.x) |
[mkl] |
Intel MKL BLAS backend for NGSolve |
[test] |
pytest + plugins |
NGSolve provides Python packages for supported Linux, macOS, and Windows
environments. See the NGSolve installation guide
for current platform details.
The circuit-parameter models and non-FEM CLI paths do not require NGSolve.
Or with uv:
uv venv .venv --python 3.12
uv sync --extra all --extra test
Run the tests:
uv run pytest -m "not fem and not slow" # core CI lane
uv run pytest # all tests available in this environment
Quick start
Compute the torque-speed envelope of the Prius 2004 IPM:
from phasesweep import MODEL_REGISTRY, RunConfig, load_motor
motor = load_motor("motors/prius_2004.toml")
cfg = RunConfig(motor=motor, model="torque_speed")
envelope = MODEL_REGISTRY["torque_speed"].fn(cfg)
print(f"Peak torque: {envelope['tau_curve_peak'][0]:.0f} Nm")
print(f"Peak power: {envelope['p_max_peak']/1000:.0f} kW")
Both numbers are constant-inductance over-predictions - see the
saturation caveat below.
Compute the air-gap field of a motor with full geometry - analytically,
then with the 2D FEM solver, and compare:
motor = load_motor("motors/belkhadir_outrunner.toml")
cfg = RunConfig(motor=motor, model="analytical", n_theta=720)
metrics = MODEL_REGISTRY["analytical"].fn(cfg)
print(f"Analytical B1: {metrics['fundamental']:.3f} T")
print(f"Back-EMF: {metrics['backemf_fundamental']:.1f} V")
cfg = RunConfig(motor=motor, model="fem", n_theta=720)
metrics = MODEL_REGISTRY["fem"].fn(cfg)
print(f"FEM B1: {metrics['fundamental']:.3f} T")
The analytical solver supports surface-mounted magnets with air between the
arcs. Inset rotors, including the bundled CREATOR motor, require the FEM model.
Launch the dashboard (needs the [server] extra):
phasesweep-server # serves http://127.0.0.1:8000
It reads motors/*.toml and the result store in output/ relative to
the working directory (the shipped motor definitions live in the source
repository, not in the wheel; --motors-dir points elsewhere), queues
solver jobs across worker processes, streams progress over WebSocket,
and plots stored waveforms, harmonics, and envelopes in the browser.
Downstream consumers of the store read rows againstphasesweep.record_schema and the
result-store contract.
The same server exposes an MCP endpoint
at /mcp, so an AI agent can check which models run on a motor, submit
jobs and sweeps, and read results. Each result comes with the model's
headline metrics and units, plus caveats drawn from its own provenance (for
example, a torque envelope computed with constant inductances). Jobs share
the dashboard's worker pool, and the dashboard's Agent tab plots the
designs the agent has explored and shows each tool call live. For Claude
Code:
claude mcp add --transport http phase-sweep http://127.0.0.1:8000/mcp
The server has no authentication; keep it on loopback unless something in
front of it authenticates. Tools, result caveats, cost planning, and limits
are in docs/mcp.md.
CLI tools
| Command | Purpose |
|---|---|
phasesweep-check-motor |
Check a motor definition file for structural validity, input consistency, and model execution |
phasesweep-import |
Import measured data (JSON) into the result store |
phasesweep-crossval |
Compare computed vs measured results across motors |
phasesweep-calibrate |
Fit motor parameters to measured quantities |
phasesweep-server |
Local FastAPI server + browser dashboard |
Each command supports --help.
Available models
RunConfig(motor=..., model=<key>) dispatches through MODEL_REGISTRY.
Each entry declares what it produces and which motor fields it needs;
a motor missing a required field fails validation before any solve.
| Key | Cost | Computes | Requires |
|---|---|---|---|
analytical |
fast | Air-gap B_r waveform, fundamental, THD, back-EMF, flux linkage | geometry, magnet |
fem |
slow | No-load B_r waveform, |B| field grid, fundamental, peak iron flux density; Maxwell-stress torque when j_s is supplied |
geometry, magnet, mu_r_fe |
analytical_axial |
fast | Air-gap B_z waveform, fundamental, THD, flux linkage (quasi-3D layer model) | axial geometry, magnet |
fem_axial |
slow | B_z waveform and fundamental from multi-plane Cartesian FEM | axial geometry, magnet, mu_r_fe |
cogging_torque |
slow | Peak-to-peak cogging torque, dominant harmonic order | geometry, magnet, mu_r_fe |
demag_screen |
slow | Minimum magnet flux density vs knee at fault current, demag margin | geometry, magnet, winding, B_knee; i_fault per run |
drive_sim |
medium | Speed/torque/current transients, settling time, droop | R_s, L_d, L_q, psi_f, J |
drive_sim_two_mass |
medium | drive_sim with a two-mass load; adds shaft torque |
same, plus load params |
rated_torque |
fast | MTPA torque and angle at rated current, torque constant | psi_f, I_rated |
stall_torque |
fast | Voltage/current-limited stall torque | psi_f, R_s, drive limits |
torque_speed |
fast | Continuous + peak envelope, base speed, field-weakening range | R_s, L_d, L_q, psi_f, drive limits |
operating_point |
fast | Minimum-current dq point, voltages, modulation index, power factor, powers for a speed + torque demand | circuit, drive limits; w_mech, tau_ref per run |
thermal_duty |
fast | S1 verdict, copper loss, winding temperature over a duty profile | psi_f, R_s, duty profile |
motor_thermal |
fast | Steady winding / iron / magnet temperatures of a three-node network coupled to operating_point |
[thermal_network], [iron], alpha_Br, circuit, drive limits; w_mech, tau_ref, T_coolant per run |
iron_loss |
fast | Hysteresis + eddy core loss at a given speed | [iron] |
im_equivalent_circuit |
fast | Induction-machine circuit at one slip: torque, currents, power factor, losses | [induction], R_s; slip per run |
im_torque_slip |
fast | Torque-slip sweep: breakdown, starting and rated points | [induction], R_s |
im_bar_impedance |
medium | Predicted deep-bar R_2(f) / L_sigma_r(f) tables from a single-slot-pitch harmonic FEM solve |
cage [geometry], sigma_bar, winding |
im_fem_harmonic |
slow | Full-machine time-harmonic FEM at one slip: current, power factor, torque, loss split, field grid; linear or saturating iron | cage [geometry] with stator slots, [induction] ratings, R_s, winding; slip per run |
im_fem_locked_rotor |
slow | Virtual blocked-rotor tests identified into R_2(f) / leakage tables; no-load sweep into L_m(I_m) when saturating |
same as im_fem_harmonic |
Each model's full input and output contract is in MODEL_REGISTRY; the
TOML fields are documented in docs/motor-toml.md.
The fem quick-start call above is a no-load field solve and does not
return loaded torque. See
docs/add-a-radial-pmsm.md for the staged
new-motor workflow.
The registry keys backemf_capture, inductance_test,resistance_test, torque_test, iron_loss_test, and airgap_flux_test
are imported measurement record types used by phasesweep-import and the
cross-validation comparisons.
Motor definition
Motors are TOML files. Only a pole-pair count is required (name
defaults to the filename stem);
each model declares which further fields it needs, so a circuit-only
motor (no geometry) runs the torque and envelope models, and the field
solvers require geometry. Minimal example:
[motor]
name = "example"
type = "SPMSM"
[circuit]
n_p = 4
R_s = 0.05 # Ohm per phase
L_d = 0.0002 # H
L_q = 0.0002 # H
psi_f = 0.012 # Wb per-phase peak
[drive]
U_DC = 48.0 # V
MAX_I_S = 30.0 # A peak
Sections, fields, units, and defaults are documented in
docs/motor-toml.md. The bundled motors/
files are worked examples with provenance comments. To add a new motor and
evaluate it, follow docs/add-a-radial-pmsm.md
and phasesweep-check-motor.
Verification and validation
Each model builds on a published formulation (references)
and is tested two ways:
- Verification: the solver computes its equations correctly. FEM is
compared with closed-form solutions and an independent FEM code. - Validation: the model describes a real machine. Results are compared
with measured and published data for the reference machines indata/.

Every comparison runs in the test suite. Three examples follow, one of each
kind of result; the validation report covers more
machines, their sources, and what each comparison tests.
Verification: FEM against TEAM 30a, Zhu, Howe & Chan, and ElmerFEM
The time-harmonic FEM solver is verified against
TEAM Problem 30a, the Compumag benchmark
for induction-machine field codes. Torque, phase voltage, and rotor and steel
losses agree with the problem's exact solution within 0.5 %, and the
three-phase results also match the published tables at every tabulated speed.
The magnetostatic FEM solver is verified against the Zhu, Howe & Chan (2002)
closed-form air-gap field across reference inrunner and outrunner
configurations. Acceptance bounds and current results are documented in the
validation report.
Radial and axial FEM results are also cross-checked against
ElmerFEM. Pinned comparison records inscripts/elmer_radial/ and scripts/elmer_axial/ are exercised by the core
test suite; regenerating them requires a local ElmerSolver.
Validation: back-EMF against the CREATOR benchmark
The CREATOR open-benchmark PMSM
(sintered-ferrite inrunner; Muetze et al., COMPEL 2025) supplies measured
back-EMF data and published circuit parameters. Computed values, references,
tolerances, and errors are reported in the
validation report.

The benchmark supplies ψ_f. The calculated back-EMF fundamental checks the
electrical-speed conversion and E = ω_e·ψ_f, not the field solver's prediction
of ψ_f. The validation report covers the separate MTPA angle, rated torque,
and nonlinear FEM field comparisons.
The measured waveform is trapezoidal, consistent with the nearly rectangular
ferrite magnets and the square-wave magnetization used by both field solvers.
The current comparison covers only the fundamental because the model does not
yet produce a back-EMF waveform.
Known limit: Prius 2004 stall torque
The Prius 2004 case exercises stall torque, MTPA angle, and the
torque-speed envelope for a 50 kW, 8-pole, V-shape NdFeB traction motor.
Circuit parameters come from ORNL teardown and dynamometer reports
(OSTI 885676,
OSTI 890029). It is not a validation
at high current: the constant-inductance model predicts about 905 N·m stall
torque against about 340 N·m measured in ORNL's locked-rotor test at 250 A
(OSTI 921782; +166 %), because L_q
saturates. The test suite pins that prediction as a regression value and
checks the one-sided bound against the measurement;
the MTPA angle is checked against a plausible band, not a measured value.
See docs/validation-report.md for details.
Reference data
The data/prius_2004/ directory contains the
Pyleecan machine-readable IPM
geometry and ORNL dynamometer reference values for the Toyota
Prius 2004 traction motor. Seedata/prius_2004/README.md for sources and
declared assumptions.
The data/creator_case_pmsm/ directory documents the reference data from
the CREATOR open-benchmark PMSM (Muetze et al., 2025); the data files
themselves are not redistributed. Seedata/creator_case_pmsm/README.md for
attribution and citation information, and License for terms.
Dependencies
| Package | Purpose | License |
|---|---|---|
| NumPy / SciPy | Numerical computation | BSD-3-Clause |
| motulator (optional) | Synchronous machine drive simulation | MIT |
| NGSolve (optional) | 2D finite element field solver | LGPL-2.1 |
| Matplotlib (optional) | Plotting | PSF (BSD-compatible) |
| FastAPI + uvicorn (optional) | Local server + dashboard | MIT / BSD-3-Clause |
| structlog + tomli-w (optional) | Server logging, TOML export | MIT or Apache-2.0 / MIT |
| CuPy (optional) | GPU-accelerated harmonic decomposition | MIT |
Package layout
The package layout and data-flow spine are described in
docs/architecture.md. Alongside the package:scripts/ (validation and maintenance tools), tests/ (pytest suite withfem and slow markers), data/ (published, measured, and derived
validation data), and motors/ (motor parameter files).
Contributing
Bug reports, documentation fixes, validation datasets, and motor references
are welcome.
See CONTRIBUTING.md for setup and process.
Questions and discrepancy reports:
GitHub Issues.
Citing
If you use phasesweep in a report or publication:
J. Lay, phasesweep: Electromagnetic design sweeps — analytical, FEM, and
drive models, 2026. https://github.com/jonelay/phase-sweep
License
Code and data are licensed under Apache-2.0, except for the
third-party data files listed below. The data consists of parameter values
transcribed from cited publications or measured by the project authors.
NOTICE credits the sources, and anyone who redistributesphasesweep must include it (Apache-2.0 §4(d)).
| Files | License | Source |
|---|---|---|
data/prius_2004/pyleecan_geometry.json |
Apache-2.0 | Pyleecan |
data/creator_case_pmsm/: files derived from the CREATOR dataset (not shipped) |
CC BY-NC-ND 4.0 | Muetze et al., 2025 (README) |
data/creator_case_im/: files fetched by scripts/fetch_creator_im_dataset.py (not shipped) |
CC BY-NC 4.0 | CREATOR IM dataset (README) |
data/bmw_i3/: BMWi3_GeometryAutoCAD.dxf, FEMResults_1000rpm.xlsx, and flux_maps_7x7.json (derived from the xlsx) |
CC BY 4.0 | Gierczynski & Grzesiak, 2021 (NOTICE) |
data/creator_case_im/creator_case_im.toml is transcribed and therefore
Apache-2.0.
Yorumlar (0)
Yorum birakmak icin giris yap.
Yorum birakSonuc bulunamadi