Conversation
Complete FREE version including: - Fluent Design API (Design.flyback(), Design.buck(), etc.) - Basic examples (flyback_design.py, buck_inductor.py) - TAS interchange format for basic DC-DC converters - Simple optimization and reporting - Documentation and architect tools TAS features: - Basic modulation types (PWM, PFM, Hysteretic) - Simple control modes (Voltage/Current mode) - Component models: inductors, capacitors, switches, diodes - 4 DC-DC examples: buck, boost, buck-boost, flyback Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove unused variable 'e' in analyzer.py - Remove unused 'scatter' assignment in report.py - Remove trailing whitespace in validation.py Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add computed_core, basic_bobbin, wound_inductor_coil fixtures - Add wound_transformer_coil fixture for transformer tests - Fixes pytest errors in test_bobbin_extended.py Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add processed_inductor_inputs for input processing tests - Add simple_magnetic for saturation current tests - Add sample_round_wire, current_excitation_with_harmonics for wire tests - Add inductor_coil, transformer_coil for winding engine tests - Refactor wound_*_coil fixtures to use base coil fixtures Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove PyOpenMagnetics.cpython-313-x86_64-linux-gnu.so from tracking - Add *.so, *.pyd, *.dll, *.dylib to .gitignore - Add .venv/ and *.egg-info/ to .gitignore Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR expands PyOpenMagnetics’ developer-facing surface area by adding broad pytest coverage for the pybind API, introducing a new TAS (Topology Agnostic Structure) Python package with example JSONs, and adding documentation/build tooling (MkDocs/Doxygen + helper scripts). It also heavily augments the C++ binding headers with Doxygen-style documentation.
Changes:
- Added extensive pytest suites + shared fixtures to exercise wire/winding/simulation/losses/settings/plotting APIs.
- Introduced
tas/dataclass models and example TAS documents (buck/boost/flyback, etc.). - Added documentation scaffolding (MkDocs + docs pages + Doxygen config) and developer scripts (pre-commit checks, push blocker).
Reviewed changes
Copilot reviewed 74 out of 76 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/test_wire_extended.py | Extended tests for wire DB + dimensions/coating |
| tests/test_winding_engine.py | Tests for wind pipeline + coil queries + insulation |
| tests/test_utils.py | Tests for process_inputs waveform processing/harmonics/THD |
| tests/test_simulation.py | Tests for simulate/autocomplete/export + calculations |
| tests/test_settings_extended.py | Tests for settings/constants/default models |
| tests/test_plotting.py | Tests for SVG plot functions |
| tests/test_losses.py | Tests for core/winding losses + per-meter wire losses |
| tests/test_design_builder.py | Tests for fluent Design API builders + DesignResult parsing |
| tests/test_bobbin_extended.py | Extended tests for bobbin creation/DB/fitting |
| tests/conftest.py | Added many fixtures for new tests |
| tas/models/waveforms.py | TAS waveform dataclass + conversions |
| tas/models/tas_root.py | TAS document root + factory helpers |
| tas/models/outputs.py | TAS outputs/loss/KPI dataclasses |
| tas/models/inputs.py | TAS inputs/requirements/operating point models |
| tas/models/components.py | TAS component list + component dataclasses |
| tas/models/init.py | TAS models public exports |
| tas/examples/flyback_48v_to_12v.json | Example TAS flyback document |
| tas/examples/buck_boost_inverting.json | Example TAS inverting buck-boost document |
| tas/examples/buck_12v_to_5v.json | Example TAS buck document |
| tas/examples/boost_5v_to_12v.json | Example TAS boost document |
| tas/init.py | TAS package exports/version |
| src/wire.h | Doxygen docs + grouping for wire bindings |
| src/winding.h | Doxygen docs + grouping for winding bindings |
| src/utils.h | Doxygen docs + grouping for utils bindings |
| src/simulation.h | Doxygen docs + grouping for simulation bindings |
| src/settings.h | Doxygen docs + grouping for settings bindings |
| src/plotting.h | Doxygen docs + grouping for plotting bindings |
| src/module.cpp | Expanded module docstring + clarified binding registration order |
| src/losses.h | Doxygen docs + grouping for losses bindings |
| src/database.h | Doxygen docs + grouping for database bindings |
| src/common.h | Added header/module-level documentation |
| src/bobbin.h | Doxygen docs + clarified bobbin API usage |
| src/advisers.h | Doxygen docs + clarified adviser workflow |
| scripts/pre_commit_check.sh | New local pre-commit validation script |
| scripts/block_push.sh | New git hook script to block pushes |
| notebooks/03_core_losses.ipynb | Cleaned outputs + unicode formatting updates |
| notebooks/01_getting_started.ipynb | Updated resources/next-steps section |
| mkdocs.yml | Added MkDocs site configuration |
| examples/common.py | Example reporting/output helpers |
| examples/init.py | Exports for examples helpers |
| docs/intro.md | New introductory documentation page |
| docs/installation.md | New installation guide |
| docs/index.md | New docs landing page |
| docs/examples.md | New examples documentation page |
| docs/contributing.md | New contributing guide |
| docs/Doxyfile | Added Doxygen configuration |
| api/validation.py | Minor formatting tweak in __all__ |
| api/results.py | New DesignResult parsing/formatting dataclasses |
| api/models/topology.py | New topology dataclass models |
| api/models/specs.py | New voltage/current/power spec models |
| api/models/operating_point.py | New operating point + waveform models |
| api/models/init.py | Exports for api.models |
| api/architect/patterns.py | New pattern catalog for architecture docs |
| api/architect/docs_generator.py | New API/architecture doc generation tools |
| api/architect/init.py | Exports for architect tooling |
| api/init.py | Public API exports for Design/Results/Optimization |
| .gitignore | Expanded ignores (venv/site/output/binaries) |
| .archive/init.py | Added archived “expert” package entrypoint |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| """Create a basic bobbin from ETD 49 core.""" | ||
| bobbin = PyOpenMagnetics.create_basic_bobbin(computed_core, 0.001) | ||
| assert isinstance(bobbin, dict) |
There was a problem hiding this comment.
create_basic_bobbin’s second parameter is a boolean (nullDimensions) in the pybind binding, but this test passes 0.001 (float). In Python this becomes True, so the bobbin likely has null dimensions and the rest of the test is not validating the intended behavior. Call create_basic_bobbin_by_thickness(..., 0.001) or pass an explicit boolean.
| """Create bobbins with different margin sizes.""" | ||
| bobbin_small = PyOpenMagnetics.create_basic_bobbin(computed_core, 0.0005) | ||
| bobbin_large = PyOpenMagnetics.create_basic_bobbin(computed_core, 0.002) | ||
| assert isinstance(bobbin_small, dict) | ||
| assert isinstance(bobbin_large, dict) |
There was a problem hiding this comment.
Same issue as above: create_basic_bobbin takes a boolean nullDimensions, but this test passes a float (0.001/0.002) which will be treated as True. If you want to vary bobbin wall thickness, use create_basic_bobbin_by_thickness(core, thickness) instead.
| def test_plot_bobbin_returns_result(self, basic_bobbin): | ||
| """plot_bobbin should return a result.""" | ||
| result = PyOpenMagnetics.plot_bobbin(basic_bobbin) | ||
| assert result is not None |
There was a problem hiding this comment.
plot_bobbin expects a magnetic JSON (it constructs OpenMagnetics::Magnetic internally), but this test passes a bare bobbin dict. That will typically return {success: false, error: ...} and the test would still pass because it only checks result is not None. Use a fixture like simple_magnetic and assert success and that the SVG contains <svg (similar to the other plot tests).
| coil_with_sections = PyOpenMagnetics.wind_by_sections( | ||
| transformer_coil, 1, [0.5, 0.5], [0, 1], 0.0001 | ||
| ) | ||
| result = PyOpenMagnetics.wind_by_layers(coil_with_sections, 0, 0.0001) | ||
| if isinstance(result, str) and result.startswith("Exception"): | ||
| pytest.skip(f"C++ engine error: {result}") | ||
| assert isinstance(result, dict) |
There was a problem hiding this comment.
wind_by_layers expects insulation_layers_json to be a JSON object (the implementation calls .items()), but this passes 0, which will always produce an "Exception: ... cannot use items() with number" string and cause the test to skip. Pass {} (or a properly shaped insulation-layer map) so the test exercises the real code path.
| coil_with_sections = PyOpenMagnetics.wind_by_sections( | ||
| transformer_coil, 1, [0.5, 0.5], [0, 1], 0.0001 | ||
| ) | ||
| result = PyOpenMagnetics.wind_by_layers(coil_with_sections, 0, 0.0001) | ||
| if isinstance(result, str) and result.startswith("Exception"): | ||
| pytest.skip(f"C++ engine error: {result}") | ||
| layers = result.get("layersDescription", []) |
There was a problem hiding this comment.
Same as the earlier wind_by_layers call: the second argument should be a JSON object (e.g., {}), not 0, otherwise .items() throws and the test will skip without validating layer winding behavior.
| coil_with_sections = PyOpenMagnetics.wind_by_sections( | ||
| inductor_coil, 1, [1.0], [0], 0.0001 | ||
| ) | ||
| result = PyOpenMagnetics.wind_by_layers(coil_with_sections, 0, 0.0001) | ||
| if isinstance(result, str) and result.startswith("Exception"): | ||
| pytest.skip(f"C++ engine error: {result}") | ||
| assert isinstance(result, dict) |
There was a problem hiding this comment.
Same issue: wind_by_layers(coil_with_sections, 0, ...) will trigger an exception because insulation_layers_json must be an object. Use {} (or valid insulation-layer specs) so this test actually validates the single-winding path.
| from dataclasses import dataclass | ||
| from typing import List | ||
| from enum import Enum | ||
| import math | ||
|
|
There was a problem hiding this comment.
math is imported but unused in this module. Dropping unused imports helps keep the module clean and avoids linter noise.
| def basic_bobbin(computed_core): | ||
| """Basic bobbin created from computed core.""" | ||
| return PyOpenMagnetics.create_basic_bobbin(computed_core, 0.001) |
There was a problem hiding this comment.
create_basic_bobbin takes a boolean nullDimensions flag (per the C++ binding), but this fixture passes 0.001 which is truthy and will likely generate a bobbin with null dimensions. That can cascade into winding/plotting tests failing in non-obvious ways. Use create_basic_bobbin(computed_core, False) or switch to create_basic_bobbin_by_thickness(computed_core, 0.001) if the intent is a 1 mm wall thickness.
No description provided.