PyOpenMagnetics 1.3.12__tar.gz → 1.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/.github/workflows/publish.yml +16 -11
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/AGENTS.md +77 -16
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/CMakeLists.txt +20 -17
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/PKG-INFO +24 -1
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/README.md +23 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/llms.txt +35 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/pyproject.toml +1 -1
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/src/advisers.cpp +106 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/src/bobbin.cpp +81 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/src/bobbin.h +5 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/src/common.h +1 -0
- pyopenmagnetics-1.4.0/src/converter.cpp +4199 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/src/core.cpp +240 -7
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/src/core.h +10 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/src/database.cpp +80 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/src/database.h +5 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/src/losses.cpp +110 -3
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/src/losses.h +5 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/src/plotting.cpp +250 -12
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/src/plotting.h +5 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/src/settings.cpp +116 -2
- pyopenmagnetics-1.4.0/src/settings.h +25 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/src/simulation.cpp +404 -3
- pyopenmagnetics-1.4.0/src/simulation.h +57 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/src/utils.cpp +289 -3
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/src/utils.h +12 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/src/winding.cpp +98 -3
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/src/winding.h +5 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/src/wire.cpp +60 -1
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/src/wire.h +4 -0
- pyopenmagnetics-1.3.12/src/converter.cpp +0 -1383
- pyopenmagnetics-1.3.12/src/settings.h +0 -17
- pyopenmagnetics-1.3.12/src/simulation.h +0 -37
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/.github/workflows/ci.yml +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/.gitignore +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/LICENSE +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/PyOpenMagnetics.pyi +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/api/MAS.py +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/api/mas_db_reader.py +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/api/validation.py +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/clear_cibuildwheel_cache.sh +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/docs/compatibility.md +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/docs/errors.md +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/docs/performance.md +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/examples/README.md +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/examples/buck_inductor.py +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/examples/complete_simulation_example.py +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/examples/converter_design_example.py +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/examples/debug_bobbin.py +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/examples/debug_coil.py +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/examples/debug_core.py +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/examples/debug_plotting.py +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/examples/flyback_220v_12v_1a.py +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/examples/flyback_220v_12v_2a_complete.py +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/examples/flyback_bh_curve.png +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/examples/flyback_core.png +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/examples/flyback_design.py +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/examples/flyback_summary.png +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/examples/flyback_waveforms.png +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/examples/list_plot_funcs.py +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/examples/plot_flyback_design.py +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/examples/plot_flyback_pyom.py +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/examples/test_field_calc.py +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/examples/test_field_plot.py +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/force_fresh_build.sh +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/notebooks/01_getting_started.ipynb +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/notebooks/02_buck_inductor.ipynb +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/notebooks/03_core_losses.ipynb +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/notebooks/README.md +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/requirements.txt +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/src/advisers.h +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/src/converter.h +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/src/logging.cpp +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/src/logging.h +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/src/module.cpp +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/test.py +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/tests/__init__.py +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/tests/conftest.py +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/tests/test_converter_endpoints.py +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/tests/test_core.py +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/tests/test_core_adviser.py +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/tests/test_examples_integration.py +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/tests/test_inputs.py +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/tests/test_logging.py +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/tests/test_magnetic_adviser.py +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/tests/test_plotting.py +0 -0
- {pyopenmagnetics-1.3.12 → pyopenmagnetics-1.4.0}/tests/test_winding.py +0 -0
|
@@ -10,6 +10,11 @@ on:
|
|
|
10
10
|
required: false
|
|
11
11
|
default: false
|
|
12
12
|
type: boolean
|
|
13
|
+
publish_to_pypi:
|
|
14
|
+
description: 'Publish to real PyPI instead of TestPyPI (use to rebuild a failed release without recreating the GitHub release/tag)'
|
|
15
|
+
required: false
|
|
16
|
+
default: false
|
|
17
|
+
type: boolean
|
|
13
18
|
|
|
14
19
|
env:
|
|
15
20
|
GIT_LFS_SKIP_SMUDGE: 1 # Skip LFS to avoid bandwidth quota issues
|
|
@@ -109,18 +114,18 @@ jobs:
|
|
|
109
114
|
if [ $i -lt 3 ]; then sleep 60; fi
|
|
110
115
|
done
|
|
111
116
|
CIBW_ENVIRONMENT_LINUX: PATH=/opt/rh/gcc-toolset-13/root/usr/bin:$PATH LD_LIBRARY_PATH=/opt/rh/gcc-toolset-13/root/usr/lib64:$LD_LIBRARY_PATH
|
|
112
|
-
CIBW_BEFORE_BUILD: pip install --default-timeout=60 --retries 5 scikit-build-core cmake ninja pybind11
|
|
117
|
+
CIBW_BEFORE_BUILD: pip install --default-timeout=60 --retries 5 scikit-build-core "cmake<4" ninja pybind11
|
|
113
118
|
CIBW_TEST_COMMAND: python -c "import PyOpenMagnetics; print(f'PyOpenMagnetics loaded successfully with {len(dir(PyOpenMagnetics))} functions')"
|
|
114
119
|
|
|
115
120
|
- name: Publish Linux wheels to PyPI
|
|
116
|
-
if: github.event_name == 'release'
|
|
121
|
+
if: github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && inputs.publish_to_pypi)
|
|
117
122
|
uses: pypa/gh-action-pypi-publish@release/v1
|
|
118
123
|
with:
|
|
119
124
|
password: ${{ secrets.PYPI_API_TOKEN }}
|
|
120
125
|
packages-dir: wheelhouse/
|
|
121
126
|
|
|
122
127
|
- name: Publish Linux wheels to TestPyPI
|
|
123
|
-
if: github.event_name == 'workflow_dispatch'
|
|
128
|
+
if: github.event_name == 'workflow_dispatch' && !inputs.publish_to_pypi
|
|
124
129
|
uses: pypa/gh-action-pypi-publish@release/v1
|
|
125
130
|
with:
|
|
126
131
|
repository-url: https://test.pypi.org/legacy/
|
|
@@ -181,21 +186,21 @@ jobs:
|
|
|
181
186
|
CIBW_BUILD: cp310-* cp311-* cp312-* cp313-*
|
|
182
187
|
CIBW_SKIP: "*-win32 *-manylinux_i686 *musllinux* pp*"
|
|
183
188
|
CIBW_BEFORE_ALL_WINDOWS: npm install -g quicktype
|
|
184
|
-
CIBW_BEFORE_BUILD: pip install --default-timeout=60 --retries 5 scikit-build-core cmake ninja pybind11
|
|
189
|
+
CIBW_BEFORE_BUILD: pip install --default-timeout=60 --retries 5 scikit-build-core "cmake<4" ninja pybind11
|
|
185
190
|
CIBW_TEST_COMMAND: python -c "import PyOpenMagnetics; print(f'PyOpenMagnetics loaded successfully with {len(dir(PyOpenMagnetics))} functions')"
|
|
186
191
|
|
|
187
192
|
- name: Install twine
|
|
188
193
|
run: python -m pip install twine
|
|
189
194
|
|
|
190
195
|
- name: Publish Windows wheels to PyPI
|
|
191
|
-
if: github.event_name == 'release'
|
|
196
|
+
if: github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && inputs.publish_to_pypi)
|
|
192
197
|
run: python -m twine upload wheelhouse/*.whl
|
|
193
198
|
env:
|
|
194
199
|
TWINE_USERNAME: __token__
|
|
195
200
|
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
|
|
196
201
|
|
|
197
202
|
- name: Publish Windows wheels to TestPyPI
|
|
198
|
-
if: github.event_name == 'workflow_dispatch'
|
|
203
|
+
if: github.event_name == 'workflow_dispatch' && !inputs.publish_to_pypi
|
|
199
204
|
run: python -m twine upload --repository-url https://test.pypi.org/legacy/ wheelhouse/*.whl
|
|
200
205
|
env:
|
|
201
206
|
TWINE_USERNAME: __token__
|
|
@@ -266,21 +271,21 @@ jobs:
|
|
|
266
271
|
if [ $i -lt 5 ]; then sleep 60; fi
|
|
267
272
|
done
|
|
268
273
|
CIBW_ENVIRONMENT_MACOS: MACOSX_DEPLOYMENT_TARGET=15.0
|
|
269
|
-
CIBW_BEFORE_BUILD: pip install --default-timeout=60 --retries 5 scikit-build-core cmake ninja pybind11
|
|
274
|
+
CIBW_BEFORE_BUILD: pip install --default-timeout=60 --retries 5 scikit-build-core "cmake<4" ninja pybind11
|
|
270
275
|
CIBW_TEST_COMMAND: python -c "import PyOpenMagnetics; print(f'PyOpenMagnetics loaded successfully with {len(dir(PyOpenMagnetics))} functions')"
|
|
271
276
|
|
|
272
277
|
- name: Install twine
|
|
273
278
|
run: python -m pip install twine
|
|
274
279
|
|
|
275
280
|
- name: Publish macOS wheels to PyPI
|
|
276
|
-
if: github.event_name == 'release'
|
|
281
|
+
if: github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && inputs.publish_to_pypi)
|
|
277
282
|
run: python -m twine upload wheelhouse/*.whl
|
|
278
283
|
env:
|
|
279
284
|
TWINE_USERNAME: __token__
|
|
280
285
|
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
|
|
281
286
|
|
|
282
287
|
- name: Publish macOS wheels to TestPyPI
|
|
283
|
-
if: github.event_name == 'workflow_dispatch'
|
|
288
|
+
if: github.event_name == 'workflow_dispatch' && !inputs.publish_to_pypi
|
|
284
289
|
run: python -m twine upload --repository-url https://test.pypi.org/legacy/ wheelhouse/*.whl
|
|
285
290
|
env:
|
|
286
291
|
TWINE_USERNAME: __token__
|
|
@@ -338,14 +343,14 @@ jobs:
|
|
|
338
343
|
run: python -m build --sdist
|
|
339
344
|
|
|
340
345
|
- name: Publish sdist to PyPI
|
|
341
|
-
if: github.event_name == 'release'
|
|
346
|
+
if: github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && inputs.publish_to_pypi)
|
|
342
347
|
uses: pypa/gh-action-pypi-publish@release/v1
|
|
343
348
|
with:
|
|
344
349
|
password: ${{ secrets.PYPI_API_TOKEN }}
|
|
345
350
|
packages-dir: dist/
|
|
346
351
|
|
|
347
352
|
- name: Publish sdist to TestPyPI
|
|
348
|
-
if: github.event_name == 'workflow_dispatch'
|
|
353
|
+
if: github.event_name == 'workflow_dispatch' && !inputs.publish_to_pypi
|
|
349
354
|
uses: pypa/gh-action-pypi-publish@release/v1
|
|
350
355
|
with:
|
|
351
356
|
repository-url: https://test.pypi.org/legacy/
|
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# AGENTS.md — PyOpenMagnetics AI Assistant Guide
|
|
2
2
|
|
|
3
|
+
> **MKF is authoritative for all magnetics math.** Before implementing any
|
|
4
|
+
> magnetics calculation or assuming an API exists, consult
|
|
5
|
+
> [`../MKF/CAPABILITIES.md`](../MKF/CAPABILITIES.md). If a needed capability
|
|
6
|
+
> isn't listed there, ask — don't reinvent it here.
|
|
7
|
+
|
|
8
|
+
> **Two stub files in this repo:**
|
|
9
|
+
> - `PyOpenMagnetics.pyi` — **curated**. Authoritative on arg conventions
|
|
10
|
+
> and gotchas. Read this first.
|
|
11
|
+
> - `PyOpenMagnetics.generated.pyi` — **auto-generated** from the compiled
|
|
12
|
+
> `.so` via pybind11-stubgen. Wider coverage (every exported symbol) but
|
|
13
|
+
> raw — signatures are right, conventions may not be. Use as a discovery
|
|
14
|
+
> index; when it disagrees with the curated stub, trust the curated one.
|
|
15
|
+
|
|
3
16
|
> **This file is the SINGLE SOURCE OF TRUTH for any AI agent using PyOpenMagnetics.**
|
|
4
17
|
> Every instruction was derived from reading the C++ source code
|
|
5
18
|
> (`converter.cpp`, `magnetics.cpp`, `cores.cpp`, `wires.cpp`, `settings.cpp`,
|
|
@@ -615,26 +628,74 @@ subcircuit = PyOM.export_magnetic_as_subcircuit(magnetic)
|
|
|
615
628
|
|
|
616
629
|
## 11. Supported Topologies
|
|
617
630
|
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
631
|
+
`process_converter("<topology>", json, use_ngspice)` is the universal entry
|
|
632
|
+
point and accepts every string below, plus its `"advanced_<topology>"` form
|
|
633
|
+
(the internal builds the `Advanced*` MKF class either way — "advanced" is
|
|
634
|
+
selected by the JSON payload shape, e.g. presence of `desiredInductance` /
|
|
635
|
+
`desiredMagnetizingInductance` / `desiredBoostInductance`, not by the name).
|
|
636
|
+
|
|
637
|
+
### 11.1 Per-topology API parity matrix
|
|
638
|
+
|
|
639
|
+
Every topology exposes the **same four surfaces** (✓ = present). Columns:
|
|
640
|
+
- **inputs** — `calculate_<t>_inputs(json)` (basic) and
|
|
641
|
+
`calculate_advanced_<t>_inputs(json)` (advanced)
|
|
642
|
+
- **process** — dedicated `process_<t>(json)` thin wrapper (all are also
|
|
643
|
+
reachable via the generic `process_converter`)
|
|
644
|
+
- **simulate** — `simulate_<t>_ideal_waveforms(json)` (ngspice)
|
|
645
|
+
- **ngspice** — `generate_<t>_ngspice_circuit(json, input_voltage_index=0, operating_point_index=0)`
|
|
646
|
+
|
|
647
|
+
| Topology string | inputs (basic / advanced) | process_* | simulate | generate ngspice |
|
|
648
|
+
|---|---|---|---|---|
|
|
649
|
+
| `flyback` | ✓ / ✓ | ✓ | ✓ (+`simulate_flyback_with_magnetic`) | ✓ |
|
|
650
|
+
| `buck` | ✓ / ✓ | ✓ | ✓ | ✓ |
|
|
651
|
+
| `boost` | ✓ / ✓ | ✓ | ✓ | ✓ |
|
|
652
|
+
| `single_switch_forward` | ✓ / ✓ | ✓ | ✓ (`simulate_forward_*`) | ✓ (`generate_forward_*`) |
|
|
653
|
+
| `two_switch_forward` | ✓ / ✓ | ✓ | ✓ | ✓ |
|
|
654
|
+
| `active_clamp_forward` | ✓ / ✓ | ✓ | ✓ | ✓ |
|
|
655
|
+
| `push_pull` | ✓ / ✓ | ✓ | ✓ | ✓ |
|
|
656
|
+
| `isolated_buck` | ✓ / ✓ | ✓ | ✓ | ✓ |
|
|
657
|
+
| `isolated_buck_boost` | ✓ / ✓ | ✓ | ✓ | ✓ |
|
|
658
|
+
| `cuk` | ✓ / ✓ | ✓ | ✓ | ✓ |
|
|
659
|
+
| `sepic` | ✓ / ✓ | ✓ | ✓ | ✓ |
|
|
660
|
+
| `zeta` | ✓ / ✓ | ✓ | ✓ | ✓ |
|
|
661
|
+
| `four_switch_buck_boost` | ✓ / ✓ | ✓ | ✓ | ✓ |
|
|
662
|
+
| `weinberg` | ✓ / ✓ | ✓ | ✓ | ✓ |
|
|
663
|
+
| `llc` | ✓ / ✓ | via `process_converter` | ✓ | ✓ |
|
|
664
|
+
| `cllc` | ✓ / ✓ | via `process_converter` | ✓ | ✓ |
|
|
665
|
+
| `clllc` | ✓ / ✓ | ✓ | ✓ | ✓ |
|
|
666
|
+
| `src` | ✓ / ✓ | ✓ | ✓ | ✓ |
|
|
667
|
+
| `dab` | ✓ / ✓ | via `process_converter` | ✓ | ✓ |
|
|
668
|
+
| `phase_shifted_full_bridge` (`psfb`) | ✓ / ✓ | via `process_converter` | ✓ | ✓ |
|
|
669
|
+
| `phase_shifted_half_bridge` (`pshb`) | ✓ / ✓ | via `process_converter` | ✓ | ✓ |
|
|
670
|
+
| `asymmetric_half_bridge` (`ahb`) | ✓ / ✓ | ✓ | ✓ | ✓ |
|
|
671
|
+
| `vienna` | ✓ / ✓ | ✓ | ✓ | ✓ |
|
|
672
|
+
| `power_factor_correction` (`pfc`) | ✓ / — ¹ | via `process_converter` | ✓ (`simulate_pfc_waveforms`) | ✓ ² |
|
|
673
|
+
| `current_transformer` | — ³ | ✓ ³ | — | — |
|
|
674
|
+
| `common_mode_choke` (`cmc`) | `calculate_cmc_inputs` / `calculate_advanced_cmc_inputs` | — | `simulate_cmc_ideal_waveforms`, `simulate_cmc_lisn_waveforms` | `generate_cmc_ngspice_circuit` |
|
|
675
|
+
| `differential_mode_choke` (`dmc`) | `calculate_dmc_inputs` | `propose_dmc_design`, `verify_dmc_attenuation` | `simulate_dmc_waveforms` | `generate_dmc_ngspice_circuit` |
|
|
676
|
+
|
|
677
|
+
¹ PFC has no `AdvancedPowerFactorCorrection` class in MKF — basic-only by design;
|
|
678
|
+
there is intentionally no `calculate_advanced_pfc_inputs`.
|
|
679
|
+
² `generate_pfc_ngspice_circuit(json, dc_resistance=0.1, simulation_time=0.02,
|
|
680
|
+
time_step=1e-8)` — PFC is a line-frequency model, so it takes circuit-damping
|
|
681
|
+
parameters instead of the `input_voltage_index` / `operating_point_index`
|
|
682
|
+
sweep indices used by the DC-DC family. Inductance comes from an explicit
|
|
683
|
+
`"inductance"` field or is derived from `"mode"` (CCM/CrCM/DCM).
|
|
684
|
+
³ Current transformer is measurement-only: `process_current_transformer(json,
|
|
685
|
+
turns_ratio, secondary_resistance=0.0)`.
|
|
686
|
+
|
|
687
|
+
### 11.2 Dedicated `process_*` thin wrappers
|
|
688
|
+
|
|
633
689
|
`process_flyback()`, `process_buck()`, `process_boost()`,
|
|
634
690
|
`process_single_switch_forward()`, `process_two_switch_forward()`,
|
|
635
691
|
`process_active_clamp_forward()`, `process_push_pull()`,
|
|
636
692
|
`process_isolated_buck()`, `process_isolated_buck_boost()`,
|
|
637
|
-
`
|
|
693
|
+
`process_cuk()`, `process_sepic()`, `process_zeta()`,
|
|
694
|
+
`process_four_switch_buck_boost()`, `process_asymmetric_half_bridge()`,
|
|
695
|
+
`process_weinberg()`, `process_vienna()`, `process_clllc()`, `process_src()`,
|
|
696
|
+
`process_current_transformer(json, turns_ratio, secondary_resistance=0.0)`.
|
|
697
|
+
Topologies without a dedicated wrapper (`llc`, `cllc`, `dab`, `psfb`, `pshb`,
|
|
698
|
+
`pfc`) are reached through `process_converter("<topology>", json)`.
|
|
638
699
|
|
|
639
700
|
---
|
|
640
701
|
|
|
@@ -24,16 +24,15 @@ else ()
|
|
|
24
24
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wno-deprecated-declarations -Wno-unused-parameter -Wno-switch")
|
|
25
25
|
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
|
26
26
|
|
|
27
|
-
# set(CMAKE_BUILD_TYPE RelWithDebInfo)
|
|
28
27
|
# set(CMAKE_BUILD_TYPE MinSizeRel)
|
|
29
|
-
set(CMAKE_BUILD_TYPE Release)
|
|
30
|
-
|
|
28
|
+
# set(CMAKE_BUILD_TYPE Release)
|
|
29
|
+
set(CMAKE_BUILD_TYPE RelWithDebInfo)
|
|
30
|
+
|
|
31
31
|
# Enable Link Time Optimization to reduce binary size
|
|
32
32
|
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION FALSE) # TEMP: disable LTO (OOM)
|
|
33
|
-
|
|
34
|
-
#
|
|
35
|
-
set(
|
|
36
|
-
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} -Wl,--strip-all")
|
|
33
|
+
|
|
34
|
+
# Debug build: keep symbols and frame pointers for gdb backtraces.
|
|
35
|
+
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -O1 -g -fno-omit-frame-pointer")
|
|
37
36
|
endif()
|
|
38
37
|
|
|
39
38
|
SET(MAS_DIRECTORY "${CMAKE_BINARY_DIR}/MAS/")
|
|
@@ -123,12 +122,12 @@ if(NOT LOCAL_MKF_MAS)
|
|
|
123
122
|
set(MKF_FORCE_REFRESH "2026-04-29-extra-components")
|
|
124
123
|
# Tell MKF to disable matplotplusplus and use SVG-based Painter instead
|
|
125
124
|
set(INCLUDE_PYMKF ON CACHE BOOL "Build Python interface" FORCE)
|
|
126
|
-
# GIT_SUBMODULES_RECURSE pulls in CAS/
|
|
125
|
+
# GIT_SUBMODULES_RECURSE pulls in CAS/PEAS (added 2026-04 alongside the
|
|
127
126
|
# ExtraComponentsMode API). MAS is also a submodule of MKF but PyMKF
|
|
128
|
-
# fetches it independently below for fast-update reasons; CAS/
|
|
127
|
+
# fetches it independently below for fast-update reasons; CAS/PEAS only
|
|
129
128
|
# exist as MKF submodules, so we need them populated under MKF/.
|
|
130
129
|
# NOTE: we cannot use GIT_SHALLOW with GIT_SUBMODULES — shallow clone
|
|
131
|
-
# skips submodule init. Drop the shallow flag for MKF so CAS/
|
|
130
|
+
# skips submodule init. Drop the shallow flag for MKF so CAS/PEAS/
|
|
132
131
|
# cci_coords are actually checked out. cci_coords MUST stay in this
|
|
133
132
|
# list — the CCI generator reads from MKF/cci_coords/coordinates/.
|
|
134
133
|
# MAS is fetched separately below (not a sub-fetch of MKF here) so
|
|
@@ -137,7 +136,7 @@ if(NOT LOCAL_MKF_MAS)
|
|
|
137
136
|
GIT_REPOSITORY https://github.com/OpenMagnetics/MKF.git
|
|
138
137
|
GIT_TAG main
|
|
139
138
|
GIT_PROGRESS TRUE
|
|
140
|
-
GIT_SUBMODULES "CAS" "
|
|
139
|
+
GIT_SUBMODULES "CAS" "PEAS" "cci_coords"
|
|
141
140
|
GIT_SUBMODULES_RECURSE TRUE)
|
|
142
141
|
|
|
143
142
|
message(STATUS "Fetching mas")
|
|
@@ -262,14 +261,14 @@ add_custom_target(PyMASGeneration
|
|
|
262
261
|
|
|
263
262
|
# ──────────────────────────────────────────────────────────────────
|
|
264
263
|
# CAS.hpp generation (mirrors MKF/CMakeLists.txt:419-451)
|
|
265
|
-
# CAS = Capacitor Adviser Schema.
|
|
264
|
+
# CAS = Capacitor Adviser Schema. PEAS = Power Element Adviser Schema.
|
|
266
265
|
# Both are submodules of MKF (added 2026-04). MKF/Topology.h #includes
|
|
267
266
|
# <CAS.hpp> for the get_extra_components_inputs API; we must generate
|
|
268
267
|
# the header here so PyOpenMagnetics's TU sees it.
|
|
269
268
|
# ──────────────────────────────────────────────────────────────────
|
|
270
269
|
set(CAS_DIRECTORY "${CMAKE_BINARY_DIR}/CAS/")
|
|
271
270
|
set(CAS_DIR "${MKF_DIR}/CAS")
|
|
272
|
-
set(
|
|
271
|
+
set(PEAS_DIR "${MKF_DIR}/PEAS")
|
|
273
272
|
file(MAKE_DIRECTORY "${CAS_DIRECTORY}")
|
|
274
273
|
|
|
275
274
|
add_custom_command(
|
|
@@ -277,8 +276,10 @@ add_custom_command(
|
|
|
277
276
|
COMMAND ${CMAKE_COMMAND} -E remove -f "${CAS_DIRECTORY}/CAS.hpp"
|
|
278
277
|
COMMAND quicktype -l c++ -s schema ${CAS_DIR}/schemas/inputs.json
|
|
279
278
|
-S ${CAS_DIR}/schemas/inputs/designRequirements.json
|
|
280
|
-
-S ${
|
|
281
|
-
-S ${
|
|
279
|
+
-S ${PEAS_DIR}/schemas/utils.json
|
|
280
|
+
-S ${PEAS_DIR}/schemas/inputs/twoTerminalOperatingPoint.json
|
|
281
|
+
-S ${PEAS_DIR}/schemas/inputs/operatingConditions.json
|
|
282
|
+
-S ${PEAS_DIR}/schemas/inputs/operatingPointExcitation.json
|
|
282
283
|
-o ${CAS_DIRECTORY}/CAS.hpp --namespace CAS --source-style single-source
|
|
283
284
|
--type-style pascal-case --member-style underscore-case
|
|
284
285
|
--enumerator-style upper-underscore-case --no-boost
|
|
@@ -286,8 +287,10 @@ add_custom_command(
|
|
|
286
287
|
DEPENDS
|
|
287
288
|
"${CAS_DIR}/schemas/inputs.json"
|
|
288
289
|
"${CAS_DIR}/schemas/inputs/designRequirements.json"
|
|
289
|
-
"${
|
|
290
|
-
"${
|
|
290
|
+
"${PEAS_DIR}/schemas/utils.json"
|
|
291
|
+
"${PEAS_DIR}/schemas/inputs/twoTerminalOperatingPoint.json"
|
|
292
|
+
"${PEAS_DIR}/schemas/inputs/operatingConditions.json"
|
|
293
|
+
"${PEAS_DIR}/schemas/inputs/operatingPointExcitation.json"
|
|
291
294
|
USES_TERMINAL)
|
|
292
295
|
|
|
293
296
|
add_custom_target(PyCASGeneration
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: PyOpenMagnetics
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.4.0
|
|
4
4
|
Summary: Python wrapper for OpenMagnetics
|
|
5
5
|
Author-Email: Alfonso Martinez <Alfonso_VII@hotmail.com>
|
|
6
6
|
Classifier: Development Status :: 4 - Beta
|
|
@@ -314,6 +314,29 @@ magnetics = get_advised_magnetics(inputs, max_results=5)
|
|
|
314
314
|
|----------|-------------|
|
|
315
315
|
| `export_magnetic_as_subcircuit(magnetic, ...)` | Export as SPICE model |
|
|
316
316
|
|
|
317
|
+
### Converter Topologies
|
|
318
|
+
|
|
319
|
+
All 24 power topologies are exposed with a uniform API. Use the generic
|
|
320
|
+
`process_converter("<topology>", converter, use_ngspice)` (also accepts
|
|
321
|
+
`"advanced_<topology>"`), or the per-topology functions below.
|
|
322
|
+
|
|
323
|
+
| Function family | Description |
|
|
324
|
+
|----------|-------------|
|
|
325
|
+
| `process_converter(name, json, use_ngspice=True)` | Universal dispatch for every topology |
|
|
326
|
+
| `design_magnetics_from_converter(name, json, max_results, core_mode, ...)` | Converter → advised magnetic designs (single call) |
|
|
327
|
+
| `calculate_<t>_inputs(json)` | Build MAS inputs (basic mode) for topology `<t>` |
|
|
328
|
+
| `calculate_advanced_<t>_inputs(json)` | Build MAS inputs (advanced mode) |
|
|
329
|
+
| `simulate_<t>_ideal_waveforms(json)` | ngspice ideal-waveform simulation |
|
|
330
|
+
| `generate_<t>_ngspice_circuit(json, input_voltage_index=0, operating_point_index=0)` | Generate ngspice netlist |
|
|
331
|
+
|
|
332
|
+
`<t>` ∈ `flyback, buck, boost, single_switch_forward, two_switch_forward,
|
|
333
|
+
active_clamp_forward, push_pull, isolated_buck, isolated_buck_boost, cuk,
|
|
334
|
+
sepic, zeta, four_switch_buck_boost, weinberg, llc, cllc, clllc, src, dab,
|
|
335
|
+
psfb, pshb, ahb, vienna`. PFC is basic-only (`calculate_pfc_inputs`,
|
|
336
|
+
`generate_pfc_ngspice_circuit(json, dc_resistance=0.1, simulation_time=0.02,
|
|
337
|
+
time_step=1e-8)`); common-/differential-mode chokes use the `cmc` / `dmc`
|
|
338
|
+
families. See `AGENTS.md` §11 for the full per-topology parity matrix.
|
|
339
|
+
|
|
317
340
|
## Core Materials
|
|
318
341
|
|
|
319
342
|
PyOpenMagnetics includes materials from major manufacturers:
|
|
@@ -297,6 +297,29 @@ magnetics = get_advised_magnetics(inputs, max_results=5)
|
|
|
297
297
|
|----------|-------------|
|
|
298
298
|
| `export_magnetic_as_subcircuit(magnetic, ...)` | Export as SPICE model |
|
|
299
299
|
|
|
300
|
+
### Converter Topologies
|
|
301
|
+
|
|
302
|
+
All 24 power topologies are exposed with a uniform API. Use the generic
|
|
303
|
+
`process_converter("<topology>", converter, use_ngspice)` (also accepts
|
|
304
|
+
`"advanced_<topology>"`), or the per-topology functions below.
|
|
305
|
+
|
|
306
|
+
| Function family | Description |
|
|
307
|
+
|----------|-------------|
|
|
308
|
+
| `process_converter(name, json, use_ngspice=True)` | Universal dispatch for every topology |
|
|
309
|
+
| `design_magnetics_from_converter(name, json, max_results, core_mode, ...)` | Converter → advised magnetic designs (single call) |
|
|
310
|
+
| `calculate_<t>_inputs(json)` | Build MAS inputs (basic mode) for topology `<t>` |
|
|
311
|
+
| `calculate_advanced_<t>_inputs(json)` | Build MAS inputs (advanced mode) |
|
|
312
|
+
| `simulate_<t>_ideal_waveforms(json)` | ngspice ideal-waveform simulation |
|
|
313
|
+
| `generate_<t>_ngspice_circuit(json, input_voltage_index=0, operating_point_index=0)` | Generate ngspice netlist |
|
|
314
|
+
|
|
315
|
+
`<t>` ∈ `flyback, buck, boost, single_switch_forward, two_switch_forward,
|
|
316
|
+
active_clamp_forward, push_pull, isolated_buck, isolated_buck_boost, cuk,
|
|
317
|
+
sepic, zeta, four_switch_buck_boost, weinberg, llc, cllc, clllc, src, dab,
|
|
318
|
+
psfb, pshb, ahb, vienna`. PFC is basic-only (`calculate_pfc_inputs`,
|
|
319
|
+
`generate_pfc_ngspice_circuit(json, dc_resistance=0.1, simulation_time=0.02,
|
|
320
|
+
time_step=1e-8)`); common-/differential-mode chokes use the `cmc` / `dmc`
|
|
321
|
+
families. See `AGENTS.md` §11 for the full per-topology parity matrix.
|
|
322
|
+
|
|
300
323
|
## Core Materials
|
|
301
324
|
|
|
302
325
|
PyOpenMagnetics includes materials from major manufacturers:
|
|
@@ -763,6 +763,41 @@ inputs = {
|
|
|
763
763
|
processed = PyOpenMagnetics.process_inputs(inputs)
|
|
764
764
|
```
|
|
765
765
|
|
|
766
|
+
### Low-Level Per-Topology API (uniform across all topologies)
|
|
767
|
+
|
|
768
|
+
Beyond the high-level `process_converter` / `design_magnetics_from_converter`
|
|
769
|
+
entry points, every topology exposes the **same four function families**, so
|
|
770
|
+
any topology can be driven the same way:
|
|
771
|
+
|
|
772
|
+
```python
|
|
773
|
+
# 1. Input builders — basic and advanced modes (advanced = JSON carries a
|
|
774
|
+
# desired* inductance/turns-ratio field; both reach the same MKF engine):
|
|
775
|
+
inputs = PyOpenMagnetics.calculate_dab_inputs(converter)
|
|
776
|
+
inputs_adv = PyOpenMagnetics.calculate_advanced_dab_inputs(converter)
|
|
777
|
+
|
|
778
|
+
# 2. Generic dispatch (accepts "<topology>" and "advanced_<topology>"):
|
|
779
|
+
inputs = PyOpenMagnetics.process_converter("vienna", converter, True)
|
|
780
|
+
|
|
781
|
+
# 3. Ideal-waveform SPICE simulation:
|
|
782
|
+
waveforms = PyOpenMagnetics.simulate_vienna_ideal_waveforms(converter)
|
|
783
|
+
|
|
784
|
+
# 4. ngspice netlist generation:
|
|
785
|
+
netlist = PyOpenMagnetics.generate_vienna_ngspice_circuit(converter, 0, 0)
|
|
786
|
+
```
|
|
787
|
+
|
|
788
|
+
Coverage is uniform for: `flyback, buck, boost, single_switch_forward,
|
|
789
|
+
two_switch_forward, active_clamp_forward, push_pull, isolated_buck,
|
|
790
|
+
isolated_buck_boost, cuk, sepic, zeta, four_switch_buck_boost, weinberg, llc,
|
|
791
|
+
cllc, clllc, src, dab, psfb, pshb, asymmetric_half_bridge (ahb), vienna`.
|
|
792
|
+
Both `calculate_<t>_inputs` and `calculate_advanced_<t>_inputs` exist for each
|
|
793
|
+
of these. Exceptions: **PFC** has no advanced variant
|
|
794
|
+
(`calculate_pfc_inputs` only; `generate_pfc_ngspice_circuit(json,
|
|
795
|
+
dc_resistance=0.1, simulation_time=0.02, time_step=1e-8)` uses a
|
|
796
|
+
line-frequency model with no sweep indices), and **current_transformer** is
|
|
797
|
+
measurement-only (`process_current_transformer`). Common- and
|
|
798
|
+
differential-mode chokes have their own `calculate_cmc_inputs` /
|
|
799
|
+
`calculate_advanced_cmc_inputs` / `calculate_dmc_inputs` families.
|
|
800
|
+
|
|
766
801
|
## Related Projects
|
|
767
802
|
- **MKF**: C++ magnetics engine - github.com/OpenMagnetics/MKF
|
|
768
803
|
- **MAS**: Magnetic Agnostic Structure JSON schema - github.com/OpenMagnetics/MAS
|
|
@@ -236,6 +236,98 @@ json calculate_advised_magnetics_from_cache(json inputsJson, json filterFlowJson
|
|
|
236
236
|
}
|
|
237
237
|
}
|
|
238
238
|
|
|
239
|
+
json calculate_advised_sections(json masJson, json patternJson, int repetitions) {
|
|
240
|
+
try {
|
|
241
|
+
OpenMagnetics::Mas mas(masJson);
|
|
242
|
+
std::vector<size_t> pattern;
|
|
243
|
+
for (auto& elem : patternJson) {
|
|
244
|
+
pattern.push_back(elem);
|
|
245
|
+
}
|
|
246
|
+
auto bobbin = mas.get_magnetic().get_coil().get_bobbin();
|
|
247
|
+
if (std::holds_alternative<std::string>(bobbin)) {
|
|
248
|
+
auto bobbinString = std::get<std::string>(bobbin);
|
|
249
|
+
if (bobbinString == "Dummy") {
|
|
250
|
+
mas.get_mutable_magnetic().get_mutable_coil().set_bobbin(
|
|
251
|
+
OpenMagnetics::Bobbin::create_quick_bobbin(mas.get_mutable_magnetic().get_mutable_core()));
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
for (size_t windingIndex = 0; windingIndex < mas.get_magnetic().get_coil().get_functional_description().size(); ++windingIndex) {
|
|
255
|
+
mas.get_mutable_magnetic().get_mutable_coil().get_mutable_functional_description()[windingIndex].set_wire("Dummy");
|
|
256
|
+
}
|
|
257
|
+
auto sections = OpenMagnetics::CoilAdviser().get_advised_sections(mas, pattern, repetitions);
|
|
258
|
+
json result = json::array();
|
|
259
|
+
for (auto& section : sections) {
|
|
260
|
+
json aux;
|
|
261
|
+
to_json(aux, section);
|
|
262
|
+
result.push_back(aux);
|
|
263
|
+
}
|
|
264
|
+
return result;
|
|
265
|
+
}
|
|
266
|
+
catch (const std::exception& exc) {
|
|
267
|
+
return json{{"error", std::string("calculate_advised_sections: ") + exc.what()}};
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
json calculate_advised_coil(json masJson) {
|
|
272
|
+
try {
|
|
273
|
+
OpenMagnetics::Settings::GetInstance().set_coil_delimit_and_compact(true);
|
|
274
|
+
OpenMagnetics::Mas mas(masJson);
|
|
275
|
+
for (size_t windingIndex = 0; windingIndex < mas.get_magnetic().get_coil().get_functional_description().size(); ++windingIndex) {
|
|
276
|
+
mas.get_mutable_magnetic().get_mutable_coil().get_mutable_functional_description()[windingIndex].set_wire("Dummy");
|
|
277
|
+
}
|
|
278
|
+
mas.get_mutable_magnetic().get_mutable_coil().set_turns_description(std::nullopt);
|
|
279
|
+
mas.get_mutable_magnetic().get_mutable_coil().set_layers_description(std::nullopt);
|
|
280
|
+
mas.get_mutable_magnetic().get_mutable_coil().set_sections_description(std::nullopt);
|
|
281
|
+
mas.get_mutable_magnetic().get_mutable_coil().set_groups_description(std::nullopt);
|
|
282
|
+
OpenMagnetics::CoilAdviser coilAdviser;
|
|
283
|
+
auto masMagneticsWithCoil = coilAdviser.get_advised_coil(mas, 1);
|
|
284
|
+
if (masMagneticsWithCoil.size() > 0) {
|
|
285
|
+
json result;
|
|
286
|
+
to_json(result, masMagneticsWithCoil[0]);
|
|
287
|
+
return result;
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
return json{{"error", "No coil found"}};
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
catch (const std::exception& exc) {
|
|
294
|
+
return json{{"error", std::string("calculate_advised_coil: ") + exc.what()}};
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
json calculate_advised_wires(json windingJson, json sectionJson, json currentJson, json solidInsulationRequirementsJson, double temperature, uint8_t numberSections, size_t maximumNumberResults, bool usePlanarWires) {
|
|
299
|
+
try {
|
|
300
|
+
OpenMagnetics::Settings::GetInstance().set_coil_delimit_and_compact(true);
|
|
301
|
+
OpenMagnetics::Winding winding(windingJson);
|
|
302
|
+
OpenMagnetics::WireSolidInsulationRequirements wireSolidInsulationRequirements(solidInsulationRequirementsJson);
|
|
303
|
+
Section section(sectionJson);
|
|
304
|
+
SignalDescriptor current(currentJson);
|
|
305
|
+
OpenMagnetics::WireAdviser wireAdviser;
|
|
306
|
+
wireAdviser.set_wire_solid_insulation_requirements(wireSolidInsulationRequirements);
|
|
307
|
+
std::vector<std::pair<OpenMagnetics::Winding, double>> windingsWithScoring;
|
|
308
|
+
if (usePlanarWires) {
|
|
309
|
+
windingsWithScoring = wireAdviser.get_advised_planar_wire(winding, section, current, temperature, numberSections, maximumNumberResults);
|
|
310
|
+
}
|
|
311
|
+
else {
|
|
312
|
+
windingsWithScoring = wireAdviser.get_advised_wire(winding, section, current, temperature, numberSections, maximumNumberResults);
|
|
313
|
+
}
|
|
314
|
+
json results;
|
|
315
|
+
results["data"] = json::array();
|
|
316
|
+
for (auto& [w, scoring] : windingsWithScoring) {
|
|
317
|
+
json result;
|
|
318
|
+
json windingJson;
|
|
319
|
+
to_json(windingJson, w);
|
|
320
|
+
result["winding"] = windingJson;
|
|
321
|
+
result["scoring"] = scoring;
|
|
322
|
+
results["data"].push_back(result);
|
|
323
|
+
}
|
|
324
|
+
return results;
|
|
325
|
+
}
|
|
326
|
+
catch (const std::exception& exc) {
|
|
327
|
+
return json{{"error", std::string("calculate_advised_wires: ") + exc.what()}};
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
239
331
|
void register_adviser_bindings(py::module& m) {
|
|
240
332
|
m.def("calculate_advised_cores", &calculate_advised_cores,
|
|
241
333
|
R"pbdoc(
|
|
@@ -386,6 +478,20 @@ void register_adviser_bindings(py::module& m) {
|
|
|
386
478
|
Returns "Exception: No magnetics found in cache" if cache is empty.
|
|
387
479
|
)pbdoc",
|
|
388
480
|
py::arg("inputs_json"), py::arg("filter_flow_json"), py::arg("max_results"));
|
|
481
|
+
|
|
482
|
+
m.def("calculate_advised_sections", &calculate_advised_sections,
|
|
483
|
+
"Get advised coil sections.",
|
|
484
|
+
py::arg("mas"), py::arg("pattern"), py::arg("repetitions"));
|
|
485
|
+
|
|
486
|
+
m.def("calculate_advised_coil", &calculate_advised_coil,
|
|
487
|
+
"Get full coil design advice.",
|
|
488
|
+
py::arg("mas"));
|
|
489
|
+
|
|
490
|
+
m.def("calculate_advised_wires", &calculate_advised_wires,
|
|
491
|
+
"Get wire selection advice.",
|
|
492
|
+
py::arg("winding"), py::arg("section"), py::arg("current"),
|
|
493
|
+
py::arg("solid_insulation_requirements"), py::arg("temperature"), py::arg("number_sections"),
|
|
494
|
+
py::arg("max_results"), py::arg("use_planar_wires") = false);
|
|
389
495
|
}
|
|
390
496
|
|
|
391
497
|
} // namespace PyMKF
|
|
@@ -99,6 +99,48 @@ bool check_if_fits(json bobbinJson, double dimension, bool isHorizontalOrRadial)
|
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
+
json create_simple_bobbin_from_core(json coreJson) {
|
|
103
|
+
try {
|
|
104
|
+
OpenMagnetics::Core core(coreJson, false, false, false);
|
|
105
|
+
auto bobbin = OpenMagnetics::Bobbin::create_quick_bobbin(core);
|
|
106
|
+
|
|
107
|
+
json result;
|
|
108
|
+
to_json(result, bobbin);
|
|
109
|
+
return result;
|
|
110
|
+
}
|
|
111
|
+
catch (const std::exception &exc) {
|
|
112
|
+
return "Exception: " + std::string{exc.what()};
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
json create_simple_bobbin_from_core_with_custom_thickness(json coreJson, double thickness) {
|
|
117
|
+
try {
|
|
118
|
+
OpenMagnetics::Core core(coreJson, false, false, false);
|
|
119
|
+
auto bobbin = OpenMagnetics::Bobbin::create_quick_bobbin(core, thickness);
|
|
120
|
+
|
|
121
|
+
json result;
|
|
122
|
+
to_json(result, bobbin);
|
|
123
|
+
return result;
|
|
124
|
+
}
|
|
125
|
+
catch (const std::exception &exc) {
|
|
126
|
+
return "Exception: " + std::string{exc.what()};
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
json create_simple_bobbin_from_core_with_custom_thicknesses(json coreJson, double wallThickness, double columnThickness) {
|
|
131
|
+
try {
|
|
132
|
+
OpenMagnetics::Core core(coreJson, false, false, false);
|
|
133
|
+
auto bobbin = OpenMagnetics::Bobbin::create_quick_bobbin(core, wallThickness, columnThickness);
|
|
134
|
+
|
|
135
|
+
json result;
|
|
136
|
+
to_json(result, bobbin);
|
|
137
|
+
return result;
|
|
138
|
+
}
|
|
139
|
+
catch (const std::exception &exc) {
|
|
140
|
+
return "Exception: " + std::string{exc.what()};
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
102
144
|
void register_bobbin_bindings(py::module& m) {
|
|
103
145
|
m.def("get_bobbins", &get_bobbins, "Retrieve all available bobbins as JSON objects");
|
|
104
146
|
m.def("get_bobbin_names", &get_bobbin_names, "Retrieve list of all bobbin names");
|
|
@@ -108,6 +150,45 @@ void register_bobbin_bindings(py::module& m) {
|
|
|
108
150
|
m.def("calculate_bobbin_data", &calculate_bobbin_data, "Calculate bobbin specifications");
|
|
109
151
|
m.def("process_bobbin", &process_bobbin, "Process bobbin geometry");
|
|
110
152
|
m.def("check_if_fits", &check_if_fits, "Check if winding fits in available space");
|
|
153
|
+
|
|
154
|
+
m.def("create_simple_bobbin_from_core", &create_simple_bobbin_from_core,
|
|
155
|
+
R"pbdoc(
|
|
156
|
+
Create a simple bobbin from core data.
|
|
157
|
+
|
|
158
|
+
Args:
|
|
159
|
+
core_json: JSON Core object.
|
|
160
|
+
|
|
161
|
+
Returns:
|
|
162
|
+
JSON Bobbin object.
|
|
163
|
+
)pbdoc",
|
|
164
|
+
py::arg("core_json"));
|
|
165
|
+
|
|
166
|
+
m.def("create_simple_bobbin_from_core_with_custom_thickness", &create_simple_bobbin_from_core_with_custom_thickness,
|
|
167
|
+
R"pbdoc(
|
|
168
|
+
Create a simple bobbin from core data with custom wall thickness.
|
|
169
|
+
|
|
170
|
+
Args:
|
|
171
|
+
core_json: JSON Core object.
|
|
172
|
+
thickness: Wall thickness in meters.
|
|
173
|
+
|
|
174
|
+
Returns:
|
|
175
|
+
JSON Bobbin object.
|
|
176
|
+
)pbdoc",
|
|
177
|
+
py::arg("core_json"), py::arg("thickness"));
|
|
178
|
+
|
|
179
|
+
m.def("create_simple_bobbin_from_core_with_custom_thicknesses", &create_simple_bobbin_from_core_with_custom_thicknesses,
|
|
180
|
+
R"pbdoc(
|
|
181
|
+
Create a simple bobbin from core data with custom wall and column thicknesses.
|
|
182
|
+
|
|
183
|
+
Args:
|
|
184
|
+
core_json: JSON Core object.
|
|
185
|
+
wall_thickness: Wall thickness in meters.
|
|
186
|
+
column_thickness: Column thickness in meters.
|
|
187
|
+
|
|
188
|
+
Returns:
|
|
189
|
+
JSON Bobbin object.
|
|
190
|
+
)pbdoc",
|
|
191
|
+
py::arg("core_json"), py::arg("wall_thickness"), py::arg("column_thickness"));
|
|
111
192
|
}
|
|
112
193
|
|
|
113
194
|
} // namespace PyMKF
|
|
@@ -13,6 +13,11 @@ json calculate_bobbin_data(json magneticJson);
|
|
|
13
13
|
json process_bobbin(json bobbinJson);
|
|
14
14
|
bool check_if_fits(json bobbinJson, double dimension, bool isHorizontalOrRadial);
|
|
15
15
|
|
|
16
|
+
// Simple bobbin creation
|
|
17
|
+
json create_simple_bobbin_from_core(json coreJson);
|
|
18
|
+
json create_simple_bobbin_from_core_with_custom_thickness(json coreJson, double thickness);
|
|
19
|
+
json create_simple_bobbin_from_core_with_custom_thicknesses(json coreJson, double wallThickness, double columnThickness);
|
|
20
|
+
|
|
16
21
|
void register_bobbin_bindings(py::module& m);
|
|
17
22
|
|
|
18
23
|
} // namespace PyMKF
|