phase-sweep

mcp
Security Audit
Warn
Health Warn
  • License — License: Apache-2.0
  • Description — Repository has a description
  • Active repo — Last push 0 days ago
  • Low visibility — Only 5 GitHub stars
Code Pass
  • Code scan — Scanned 12 files during light audit, no dangerous patterns found
Permissions Pass
  • Permissions — No dangerous permissions requested

No AI report is available for this listing yet.

SUMMARY

Electromagnetic design sweeps: analytical, FEM and drive models, checked against measured data. Use them from a Python API, web dashboard or MCP server.

README.md

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.

phasesweep dashboard - CREATOR Case PMSM results

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 against
phasesweep.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 in data/.

Verification and validation: FEM air-gap field against the Zhu, Howe & Chan closed form, and CREATOR back-EMF against the measured waveform

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 in
scripts/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.

CREATOR back-EMF - measured waveform and circuit-model fundamental

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. See
data/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. See
data/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 with
fem 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 redistributes
phasesweep 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.

Reviews (0)

No results found