🤖 For AI Assistants: If you're an AI assistant helping with this library, please read AGENTS.md FIRST before continuing with this README. It contains essential information about:
- Correct import procedures (this package requires special handling)
⚠️ Using API methods instead of manual calculations (CRITICAL)- Required field specifications for converter topologies
- Troubleshooting common API errors
- Complete working examples
⚠️ AVOID MANUAL MODE: Always useprocess_flyback(),calculate_advised_magnetics(), and other API methods rather than doing manual calculations. The MKF engine handles complex magnetic effects that manual calculations cannot.
PyOpenMagnetics is a Python wrapper for MKF (Magnetics Knowledge Foundation), the simulation engine of OpenMagnetics, providing a comprehensive toolkit for designing and analyzing magnetic components such as transformers and inductors.
- 🧲 Core Database: Access to extensive database of core shapes, materials, and manufacturers
- 🔌 Winding Design: Automatic winding calculations with support for various wire types (round, litz, rectangular, planar)
- 📊 Loss Calculations: Core losses (Steinmetz), winding losses (DC, skin effect, proximity effect)
- 🎯 Design Adviser: Automated recommendations for optimal magnetic designs
- 📈 Signal Processing: Harmonic analysis, waveform processing
- 🖼️ Visualization: SVG plotting of cores, windings, magnetic fields
- 🔧 SPICE Export: Export magnetic components as SPICE subcircuits
pip install PyOpenMagneticsgit clone https://github.com/OpenMagnetics/PyOpenMagnetics.git
cd PyOpenMagnetics
pip install .This build compiles MKF by globbing its .cpp files directly into the
extension (it does not drive MKF's own CMake). MKF main has since moved to
"delete converter_models + link the Kirchhoff converter-model library
(libKirchhoffApi.so)"; because Kirchhoff and its AAS sibling are not yet
published, a from-scratch build of newer main cannot obtain that library
and fails to link.
CMakeLists.txt therefore pins the MKF FetchContent to the last self-contained
commit — MKF_GIT_TAG=2ae859dcae6c3b2e5a128893247b7714360e863f, the exact SHA
the shipping .so was built from — and a configure-time guard fails loudly if
the checkout drifts. A clean rebuild is reproducible as-is:
rm -rf build && pip install . --no-deps -v # or: cmake -S . -B build && ninja -C buildTo advance the pin you must first wire the Kirchhoff library build into
CMakeLists.txt (publish AAS/Kirchhoff, then add_subdirectory +
target_link_libraries(... libKirchhoffApi.so)). Overriding
-DMKF_GIT_TAG=main before that lands will break the link.
Important: The compiled extension module may require special import handling:
import importlib.util
# Option 1: Direct loading (recommended)
so_path = '/path/to/PyOpenMagnetics.cpython-311-x86_64-linux-gnu.so'
spec = importlib.util.spec_from_file_location('PyOpenMagnetics', so_path)
PyOpenMagnetics = importlib.util.module_from_spec(spec)
spec.loader.exec_module(PyOpenMagnetics)
# Option 2: Create __init__.py (see AGENTS.md for details)
# Verify installation
PyOpenMagnetics.load_databases({})
print(f"✓ Loaded {len(PyOpenMagnetics.get_core_materials())} materials")
print(f"✓ Loaded {len(PyOpenMagnetics.get_core_shapes())} shapes")See AGENTS.md for complete import instructions and troubleshooting.
import PyOpenMagnetics
# Find a core shape by name
shape = PyOpenMagnetics.find_core_shape_by_name("E 42/21/15")
# Find a core material by name
material = PyOpenMagnetics.find_core_material_by_name("3C95")
# Create a core with gapping
core_data = {
"functionalDescription": {
"shape": shape,
"material": material,
"gapping": [{"type": "subtractive", "length": 0.001}], # 1mm gap
"numberStacks": 1
}
}
# Calculate complete core data
core = PyOpenMagnetics.calculate_core_data(core_data, False)
print(f"Effective area: {core['processedDescription']['effectiveParameters']['effectiveArea']} m²")import PyOpenMagnetics
# Define design requirements
inputs = {
"designRequirements": {
"magnetizingInductance": {
"minimum": 100e-6, # 100 µH minimum
"nominal": 110e-6 # 110 µH nominal
},
"turnsRatios": [{"nominal": 5.0}] # 5:1 turns ratio
},
"operatingPoints": [
{
"name": "Nominal",
"conditions": {"ambientTemperature": 25},
"excitationsPerWinding": [
{
"name": "Primary",
"frequency": 100000, # 100 kHz
"current": {
"waveform": {
"data": [0, 1.0, 0],
"time": [0, 5e-6, 10e-6]
}
},
"voltage": {
"waveform": {
"data": [50, 50, -50, -50],
"time": [0, 5e-6, 5e-6, 10e-6]
}
}
}
]
}
]
}
# Process inputs (adds harmonics and validation)
processed_inputs = PyOpenMagnetics.process_inputs(inputs)
# Get magnetic recommendations
# core_mode: "available cores" (stock cores) or "standard cores" (all standard shapes)
result = PyOpenMagnetics.calculate_advised_magnetics(processed_inputs, 5, "standard cores")
# Result format: {"data": [{"mas": {...}, "scoring": float, "scoringPerFilter": {...}}, ...]}
for i, item in enumerate(result["data"]):
mag = item["mas"]["magnetic"]
core = mag["core"]["functionalDescription"]
print(f"{i+1}. {core['shape']['name']} - {core['material']['name']} (score: {item['scoring']:.3f})")import PyOpenMagnetics
# Define core and operating point
core_data = {...} # Your core definition
operating_point = {
"name": "Nominal",
"conditions": {"ambientTemperature": 25},
"excitationsPerWinding": [
{
"frequency": 100000,
"magneticFluxDensity": {
"processed": {
"peakToPeak": 0.2, # 200 mT peak-to-peak
"offset": 0
}
}
}
]
}
losses = PyOpenMagnetics.calculate_core_losses(core_data, operating_point, "IGSE")
print(f"Core losses: {losses['coreLosses']} W")import PyOpenMagnetics
# Define coil requirements
coil_functional_description = [
{
"name": "Primary",
"numberTurns": 50,
"numberParallels": 1,
"wire": "Round 0.5 - Grade 1"
},
{
"name": "Secondary",
"numberTurns": 10,
"numberParallels": 3,
"wire": "Round 1.0 - Grade 1"
}
]
# Wind the coil on the core
result = PyOpenMagnetics.wind(core_data, coil_functional_description, bobbin_data, [1, 1], [])
print(f"Winding successful: {result.get('windingResult', 'unknown')}")PyOpenMagnetics includes a complete flyback converter design wizard. See flyback.py for a full example:
from flyback import design_flyback, create_mas_inputs, get_advised_magnetics
# Define flyback specifications
specs = {
"input_voltage_min": 90,
"input_voltage_max": 375,
"outputs": [{"voltage": 12, "current": 2, "diode_drop": 0.5}],
"switching_frequency": 100000,
"max_duty_cycle": 0.45,
"efficiency": 0.85,
"current_ripple_ratio": 0.4,
"force_dcm": False,
"safety_margin": 0.85,
"ambient_temperature": 40,
"max_drain_source_voltage": None,
}
# Calculate magnetic requirements
design = design_flyback(specs)
print(f"Required inductance: {design['min_inductance']*1e6:.1f} µH")
print(f"Turns ratio: {design['turns_ratios'][0]:.2f}")
# Create inputs for PyOpenMagnetics
inputs = create_mas_inputs(specs, design)
# Get recommended magnetics
magnetics = get_advised_magnetics(inputs, max_results=5)| Function | Description |
|---|---|
get_core_materials() |
Get all available core materials |
get_core_shapes() |
Get all available core shapes |
get_wires() |
Get all available wires |
get_bobbins() |
Get all available bobbins |
find_core_material_by_name(name) |
Find core material by name |
find_core_shape_by_name(name) |
Find core shape by name |
find_wire_by_name(name) |
Find wire by name |
| Function | Description |
|---|---|
calculate_core_data(core, process) |
Calculate complete core data |
calculate_core_gapping(core, gapping) |
Calculate gapping configuration |
calculate_inductance_from_number_turns_and_gapping(...) |
Calculate inductance |
calculate_core_losses(core, operating_point, model) |
Calculate core losses |
| Function | Description |
|---|---|
wind(core, coil, bobbin, pattern, layers) |
Wind coils on a core |
calculate_winding_losses(...) |
Calculate total winding losses |
calculate_ohmic_losses(...) |
Calculate DC losses |
calculate_skin_effect_losses(...) |
Calculate skin effect losses |
calculate_proximity_effect_losses(...) |
Calculate proximity effect losses |
| Function | Description |
|---|---|
calculate_advised_cores(inputs, max_results) |
Get recommended cores |
calculate_advised_magnetics(inputs, max, mode) |
Get complete designs |
process_inputs(inputs) |
Process and validate inputs |
| Function | Description |
|---|---|
plot_core(core, ...) |
Generate SVG of core |
plot_sections(magnetic, ...) |
Plot winding sections |
plot_layers(magnetic, ...) |
Plot winding layers |
plot_turns(magnetic, ...) |
Plot individual turns |
plot_field(magnetic, ...) |
Plot magnetic field |
| Function | Description |
|---|---|
get_settings() |
Get current settings |
set_settings(settings) |
Configure settings |
reset_settings() |
Reset to defaults |
| Function | Description |
|---|---|
export_magnetic_as_subcircuit(magnetic, ...) |
Export as SPICE model |
All 24 power topologies are exposed with a uniform API. Use the generic
process_converter("<topology>", converter, use_ngspice) (also accepts
"advanced_<topology>"), or the per-topology functions below.
| Function family | Description |
|---|---|
process_converter(name, json, use_ngspice=True) |
Universal dispatch for every topology |
design_magnetics_from_converter(name, json, max_results, core_mode, ...) |
Converter → advised magnetic designs (single call) |
calculate_<t>_inputs(json) |
Build MAS inputs (basic mode) for topology <t> |
calculate_advanced_<t>_inputs(json) |
Build MAS inputs (advanced mode) |
simulate_<t>_ideal_waveforms(json) |
ngspice ideal-waveform simulation |
generate_<t>_ngspice_circuit(json, input_voltage_index=0, operating_point_index=0) |
Generate ngspice netlist |
<t> ∈ flyback, buck, boost, single_switch_forward, two_switch_forward, active_clamp_forward, push_pull, isolated_buck, isolated_buck_boost, cuk, sepic, zeta, four_switch_buck_boost, weinberg, llc, cllc, clllc, src, dab, psfb, pshb, ahb, vienna. PFC is basic-only (calculate_pfc_inputs,
generate_pfc_ngspice_circuit(json, dc_resistance=0.1, simulation_time=0.02, time_step=1e-8)); common-/differential-mode chokes use the cmc / dmc
families. See AGENTS.md §11 for the full per-topology parity matrix.
PyOpenMagnetics includes materials from major manufacturers:
- TDK/EPCOS: N27, N49, N87, N95, N97, etc.
- Ferroxcube: 3C90, 3C94, 3C95, 3F3, 3F4, etc.
- Fair-Rite: Various ferrite materials
- Magnetics Inc.: Powder cores (MPP, High Flux, Kool Mu)
- Micrometals: Iron powder cores
Supported shape families include:
- E cores: E, EI, EFD, EQ, ER
- ETD/EC cores: ETD, EC
- PQ/PM cores: PQ, PM
- RM cores: RM, RM/ILP
- Toroidal: Various sizes
- Pot cores: P, PT
- U/UI cores: U, UI, UR
- Planar: E-LP, EQ-LP, etc.
- Round enamelled wire: Various AWG and IEC sizes
- Litz wire: Multiple strand configurations
- Rectangular wire: For high-current applications
- Foil: For planar magnetics
- Planar PCB: For integrated designs
Use set_settings() to configure:
settings = PyOpenMagnetics.get_settings()
settings["coilAllowMarginTape"] = True
settings["coilWindEvenIfNotFit"] = False
settings["painterNumberPointsX"] = 50
PyOpenMagnetics.set_settings(settings)Contributions are welcome! Please see the OpenMagnetics organization for contribution guidelines.
- llms.txt - Comprehensive API reference optimized for AI assistants and quick lookup
- examples/ - Practical example scripts for common design workflows
- PyOpenMagnetics.pyi - Type stubs for IDE autocompletion
- notebooks/ - Interactive Jupyter notebook tutorials with visualizations
- Getting Started - Introduction to PyOpenMagnetics
- Buck Inductor - Complete inductor design workflow
- Core Losses - In-depth core loss analysis
- docs/errors.md - Common errors and solutions
- docs/performance.md - Performance optimization guide
- docs/compatibility.md - Python/platform version compatibility
- api/validation.py - Runtime JSON schema validation for inputs
This project is licensed under the MIT License - see the LICENSE file for details.
- MKF - C++ magnetics library
- MAS - Magnetic Agnostic Structure schema
- OpenMagnetics Web - Online design tool
- Maniktala, S. "Switching Power Supplies A-Z", 2nd Edition
- Basso, C. "Switch-Mode Power Supplies", 2nd Edition
- McLyman, C. "Transformer and Inductor Design Handbook"
For questions and support:
- 🐛 GitHub Issues
- 💬 Discussions
- 📧 Contact the maintainers