Skip to main content

Analytical electromechanical machine design library

Project description

emachines

Analytical electromechanical machine design library.

emachines is the core physics and mathematics engine behind emdesignlabs.com. It provides well-documented, tested, and citable implementations of the analytical models used in electric motor design.

Scope

  • Winding analysis — winding factors (kp, kd, kw), star-of-slots phasor method, slot/pole geometry, coil matrix
  • Magnetics — BH curve models (Fröhlich), iron loss (Steinmetz, Modified Steinmetz, Bertotti), electrical steel database
  • Motor models — PMSM dq-frame, surface-PM analytical design

Every function documents the equation it implements and its bibliographic source.

Installation

pip install emachines

For development (editable install alongside emdesignlabs):

pip install -e path/to/emachines

Quick Start

from emachines.winding.factors import winding_factor
from emachines.winding.sos import (
    get_basic_params, build_coil_matrix, winding_factor_sos,
    check_symmetry, get_valid_coil_spans
)
from emachines.magnetics.iron_loss import bertotti, fit_loss_model
from emachines.magnetics.electrical_steel import SteelDatabase, SAMPLE_LOSS
from emachines.motors.pmsm import PMSMParams, torque

# ── Winding factors ───────────────────────────────────────────────────────────

# Integer-slot: 24s/4p, 5/6 chording (closed-form kp × kd)
kw1 = winding_factor(nu=1, Q=24, p=2, coil_span=5)
print(f"kw1 (24s/4p chorded) = {kw1:.4f}")   # → 0.9330

# FSCW: 12s/10p, tooth-coil (star-of-slots phasor, auto-dispatched)
kw1 = winding_factor(nu=1, Q=12, p=5, coil_span=1)
print(f"kw1 (12s/10p FSCW)   = {kw1:.4f}")   # → 0.9330

# FSCW: 9s/8p
kw1 = winding_factor(nu=1, Q=9, p=4, coil_span=1)
print(f"kw1 (9s/8p FSCW)     = {kw1:.4f}")   # → 0.9452

# Winding geometry: classify a slot/pole combination
params = get_basic_params(Q=12, P=10)
print(params['winding_type'])    # → 'concentrated'
print(params['q'])               # → Fraction(2, 5)
print(check_symmetry(12, 10))   # → True

# Slot-conductor occupancy matrix (2 layers, tooth-coil span)
matrix = build_coil_matrix(Q=12, P=10, m=3, layers=2, w=1)
# matrix[layer, slot] = ±phase_index (1-indexed), shape (2, 12)

# Full harmonic spectrum via phasor method
from emachines.winding.sos import winding_factor_sos
for nu in [1, 3, 5, 7]:
    kw = winding_factor_sos(nu, Q=12, P=10, layers=2, w=1)
    print(f"  kw(ν={nu}) = {kw:.4f}")

# ── Iron loss ─────────────────────────────────────────────────────────────────

# Bertotti forward model at 400 Hz, 1.5 T
loss = bertotti(f=400, B_peak=1.5, k_h=0.02, k_e=1e-4, k_a=1e-3)
print(f"Total loss = {loss['total']:.2f} W/kg")
print(f"  Hysteresis: {loss['hysteresis']:.2f}  Eddy: {loss['eddy']:.2f}  Anomalous: {loss['anomalous']:.2f}")

# Fit Bertotti coefficients from measured data
import numpy as np
f_arr    = np.array([50, 100, 200, 400])
B_arr    = np.array([1.0, 1.0, 1.0, 1.0])
loss_arr = np.array([1.2, 2.8, 6.5, 15.1])
result = fit_loss_model(f_arr, B_arr, loss_arr, model="Bertotti")
print(f"k_h={result['k_h']:.4f}, k_e={result['k_e']:.2e}, R²={result['r2']:.4f}")

# ── Electrical steel database ─────────────────────────────────────────────────

# Load from manufacturer datasheets (data_dir is your local folder)
db = SteelDatabase("path/to/datasheets")
grade = db.load("M270-50A")
print(grade.loss_at(freq=200, B=1.5))   # W/kg interpolated from datasheet

# Built-in reference data — no files required
print(SAMPLE_LOSS["M-19"])   # DataFrame: loss vs frequency and flux density

# ── PMSM motor model ──────────────────────────────────────────────────────────

motor = PMSMParams(p=3, Ld=5e-3, Lq=8e-3, psi_m=0.15, Rs=0.1)
Te = torque(motor, id=-3.0, iq=10.0)
print(f"Torque = {Te:.2f} N·m")

Modules

emachines.winding

Module Contents
winding.factors pitch_factor, distribution_factor, winding_factor — integer-slot (closed-form) and FSCW (auto-dispatch to sos)
winding.sos build_star_of_slots, build_coil_matrix, assign_phases, winding_factor_sos — star-of-slots phasor method for all winding types; get_basic_params, check_symmetry, get_valid_coil_spans, is_valid_combination

Winding factor dispatch in winding_factor():

  • q ≥ 1 (integer-slot) → closed-form kp × kd
  • q < 1 (FSCW) → star-of-slots phasor sum, double-layer convention (matches emetor.com)

emachines.magnetics

Module Contents
magnetics.bh_models Fröhlich analytical BH model and curve fitting
magnetics.iron_loss steinmetz, modified_steinmetz, bertotti forward models; fit_steinmetz, fit_modified_steinmetz, fit_bertotti, fit_loss_model dispatcher
magnetics.electrical_steel SteelGrade dataclass, SteelDatabase (Voestalpine Excel + ThyssenKrupp/SURA pickle loaders, LRU-cached), SAMPLE_BH and SAMPLE_LOSS reference data

emachines.motors

Module Contents
motors.pmsm PMSMParams, back_emf, torque (excitation + reluctance), dq_currents

Design Philosophy

  • Equations first — every function documents the formula it implements with LaTeX notation
  • Cited — every formula traces back to a specific reference (textbook, paper, standard)
  • Tested — validated against published datasets and reference tools (emetor, SWAT-EM)
  • Dependency-light — only numpy, scipy, and pandas required

Test Coverage

Release Tests Status
0.3.0 92 ✅ All passing
0.2.0 36 ✅ All passing
0.1.0 18 ✅ All passing

Changelog

[0.3.0] — 2026-05-09

  • winding.sos: complete star-of-slots module — build_star_of_slots, build_coil_matrix, assign_phases, winding_factor_sos, get_basic_params, check_symmetry, get_valid_coil_spans, is_valid_combination
  • winding.factors: winding_factor() now dispatches to star-of-slots for FSCW (q < 1)
  • winding/__init__.py: all sos symbols exported at package level
  • 92 passing tests, 0 xfailed — FSCW winding factors fully supported
  • Validated against emetor.com: 12s/10p → 0.933, 9s/8p → 0.945, 12s/8p → 0.866

[0.2.0] — 2026-05-08

  • magnetics.electrical_steel: SteelGrade, SteelDatabase, SAMPLE_BH, SAMPLE_LOSS
  • magnetics.iron_loss: fit_bertotti, fit_steinmetz, fit_modified_steinmetz, fit_loss_model
  • pandas>=1.5 added as runtime dependency

[0.1.0] — 2026-05-07

  • winding.factors: pitch_factor, distribution_factor, winding_factor (integer-slot)
  • magnetics.bh_models: Fröhlich BH model and fitting
  • magnetics.iron_loss: steinmetz, modified_steinmetz, bertotti
  • motors.pmsm: PMSMParams, back_emf, torque, dq_currents

Status

0.3.x — Alpha. API may change between minor versions.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

emachines-0.3.0.tar.gz (25.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

emachines-0.3.0-py3-none-any.whl (22.0 kB view details)

Uploaded Python 3

File details

Details for the file emachines-0.3.0.tar.gz.

File metadata

  • Download URL: emachines-0.3.0.tar.gz
  • Upload date:
  • Size: 25.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for emachines-0.3.0.tar.gz
Algorithm Hash digest
SHA256 eda10fc90ac73a68604eab9a2c8a7546a785b91fd4c758067b206acc2ed84dcd
MD5 0de7e45f185200e9002a291c103955c7
BLAKE2b-256 20a584d6485af55e56afa85f55e68272a1224c9c38505a3bc819b6fc73b7f8f4

See more details on using hashes here.

File details

Details for the file emachines-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: emachines-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 22.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for emachines-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 fca9857107bb95410aad96b3631ebccd1431874c0c869ad00f9d5896838077ff
MD5 453dee3ad4faf39e5c2cfe9dd2fa0fc3
BLAKE2b-256 7461180b7a9a802fa896be99ff03010e96b189637a7b8688be863bc45fea0bef

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page