PyOpenMagnetics 1.5.1__tar.gz → 1.6.1__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.
Files changed (88) hide show
  1. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/.github/workflows/publish.yml +11 -5
  2. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/CMakeLists.txt +123 -14
  3. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/PKG-INFO +24 -1
  4. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/README.md +23 -0
  5. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/pyproject.toml +78 -78
  6. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/src/advisers.cpp +69 -1
  7. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/src/advisers.h +1 -0
  8. pyopenmagnetics-1.6.1/src/cmc.cpp +67 -0
  9. pyopenmagnetics-1.6.1/src/cmc.h +13 -0
  10. pyopenmagnetics-1.6.1/src/converter.cpp +569 -0
  11. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/src/losses.cpp +1 -1
  12. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/src/module.cpp +4 -2
  13. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/src/simulation.cpp +23 -36
  14. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/src/simulation.h +1 -1
  15. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/src/utils.cpp +3 -3
  16. pyopenmagnetics-1.5.1/src/converter.cpp +0 -4385
  17. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/.github/workflows/ci.yml +0 -0
  18. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/.gitignore +0 -0
  19. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/AGENTS.md +0 -0
  20. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/LICENSE +0 -0
  21. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/PyOpenMagnetics.pyi +0 -0
  22. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/__init__.py +0 -0
  23. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/api/MAS.py +0 -0
  24. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/api/mas_db_reader.py +0 -0
  25. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/api/validation.py +0 -0
  26. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/clear_cibuildwheel_cache.sh +0 -0
  27. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/docs/compatibility.md +0 -0
  28. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/docs/errors.md +0 -0
  29. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/docs/performance.md +0 -0
  30. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/examples/README.md +0 -0
  31. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/examples/buck_inductor.py +0 -0
  32. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/examples/complete_simulation_example.py +0 -0
  33. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/examples/converter_design_example.py +0 -0
  34. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/examples/debug_bobbin.py +0 -0
  35. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/examples/debug_coil.py +0 -0
  36. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/examples/debug_core.py +0 -0
  37. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/examples/debug_plotting.py +0 -0
  38. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/examples/flyback_220v_12v_1a.py +0 -0
  39. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/examples/flyback_220v_12v_2a_complete.py +0 -0
  40. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/examples/flyback_bh_curve.png +0 -0
  41. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/examples/flyback_core.png +0 -0
  42. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/examples/flyback_design.py +0 -0
  43. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/examples/flyback_summary.png +0 -0
  44. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/examples/flyback_waveforms.png +0 -0
  45. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/examples/list_plot_funcs.py +0 -0
  46. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/examples/plot_flyback_design.py +0 -0
  47. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/examples/plot_flyback_pyom.py +0 -0
  48. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/examples/test_field_calc.py +0 -0
  49. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/examples/test_field_plot.py +0 -0
  50. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/force_fresh_build.sh +0 -0
  51. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/llms.txt +0 -0
  52. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/notebooks/01_getting_started.ipynb +0 -0
  53. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/notebooks/02_buck_inductor.ipynb +0 -0
  54. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/notebooks/03_core_losses.ipynb +0 -0
  55. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/notebooks/README.md +0 -0
  56. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/requirements.txt +0 -0
  57. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/src/bobbin.cpp +0 -0
  58. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/src/bobbin.h +0 -0
  59. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/src/common.h +0 -0
  60. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/src/converter.h +0 -0
  61. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/src/core.cpp +0 -0
  62. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/src/core.h +0 -0
  63. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/src/database.cpp +0 -0
  64. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/src/database.h +0 -0
  65. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/src/logging.cpp +0 -0
  66. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/src/logging.h +0 -0
  67. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/src/losses.h +0 -0
  68. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/src/plotting.cpp +0 -0
  69. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/src/plotting.h +0 -0
  70. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/src/settings.cpp +0 -0
  71. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/src/settings.h +0 -0
  72. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/src/utils.h +0 -0
  73. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/src/winding.cpp +0 -0
  74. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/src/winding.h +0 -0
  75. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/src/wire.cpp +0 -0
  76. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/src/wire.h +0 -0
  77. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/test.py +0 -0
  78. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/tests/__init__.py +0 -0
  79. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/tests/conftest.py +0 -0
  80. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/tests/test_converter_endpoints.py +0 -0
  81. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/tests/test_core.py +0 -0
  82. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/tests/test_core_adviser.py +0 -0
  83. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/tests/test_examples_integration.py +0 -0
  84. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/tests/test_inputs.py +0 -0
  85. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/tests/test_logging.py +0 -0
  86. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/tests/test_magnetic_adviser.py +0 -0
  87. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/tests/test_plotting.py +0 -0
  88. {pyopenmagnetics-1.5.1 → pyopenmagnetics-1.6.1}/tests/test_winding.py +0 -0
@@ -114,6 +114,7 @@ jobs:
114
114
  CIBW_SKIP: "*-win32 *-manylinux_i686 *musllinux* pp*"
115
115
  CIBW_MANYLINUX_X86_64_IMAGE: manylinux_2_28
116
116
  CIBW_BEFORE_ALL_LINUX: |
117
+ git config --global url."https://github.com/".insteadOf "git@github.com:"
117
118
  for i in {1..3}; do
118
119
  (dnf install -y gcc-toolset-13 eigen3-devel && \
119
120
  source /opt/rh/gcc-toolset-13/enable && \
@@ -131,6 +132,7 @@ jobs:
131
132
  uses: pypa/gh-action-pypi-publish@release/v1
132
133
  with:
133
134
  password: ${{ secrets.PYPI_API_TOKEN }}
135
+ skip-existing: true
134
136
  packages-dir: wheelhouse/
135
137
 
136
138
  - name: Publish Linux wheels to TestPyPI
@@ -139,6 +141,7 @@ jobs:
139
141
  with:
140
142
  repository-url: https://test.pypi.org/legacy/
141
143
  password: ${{ secrets.TEST_PYPI_API_TOKEN }}
144
+ skip-existing: true
142
145
  packages-dir: wheelhouse/
143
146
 
144
147
  # Build and publish Windows wheels independently
@@ -199,7 +202,7 @@ jobs:
199
202
  env:
200
203
  CIBW_BUILD: ${{ matrix.python }}-*
201
204
  CIBW_SKIP: "*-win32 *-manylinux_i686 *musllinux* pp*"
202
- CIBW_BEFORE_ALL_WINDOWS: npm install -g quicktype
205
+ CIBW_BEFORE_ALL_WINDOWS: git config --global url."https://github.com/".insteadOf "git@github.com:" && npm install -g quicktype
203
206
  CIBW_BEFORE_BUILD: pip install --default-timeout=60 --retries 5 scikit-build-core "cmake<4" ninja pybind11
204
207
  CIBW_TEST_COMMAND: python -c "import PyOpenMagnetics; print(f'PyOpenMagnetics loaded successfully with {len(dir(PyOpenMagnetics))} functions')"
205
208
 
@@ -208,14 +211,14 @@ jobs:
208
211
 
209
212
  - name: Publish Windows wheels to PyPI
210
213
  if: github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && inputs.publish_to_pypi)
211
- run: python -m twine upload wheelhouse/*.whl
214
+ run: python -m twine upload --skip-existing wheelhouse/*.whl
212
215
  env:
213
216
  TWINE_USERNAME: __token__
214
217
  TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
215
218
 
216
219
  - name: Publish Windows wheels to TestPyPI
217
220
  if: github.event_name == 'workflow_dispatch' && !inputs.publish_to_pypi
218
- run: python -m twine upload --repository-url https://test.pypi.org/legacy/ wheelhouse/*.whl
221
+ run: python -m twine upload --skip-existing --repository-url https://test.pypi.org/legacy/ wheelhouse/*.whl
219
222
  env:
220
223
  TWINE_USERNAME: __token__
221
224
  TWINE_PASSWORD: ${{ secrets.TEST_PYPI_API_TOKEN }}
@@ -285,6 +288,7 @@ jobs:
285
288
  CIBW_BUILD: ${{ matrix.python }}-*
286
289
  CIBW_SKIP: "*-win32 *-manylinux_i686 *musllinux* pp*"
287
290
  CIBW_BEFORE_ALL_MACOS: |
291
+ git config --global url."https://github.com/".insteadOf "git@github.com:"
288
292
  for i in {1..5}; do
289
293
  npm install -g quicktype && break
290
294
  if [ $i -lt 5 ]; then sleep 60; fi
@@ -298,14 +302,14 @@ jobs:
298
302
 
299
303
  - name: Publish macOS wheels to PyPI
300
304
  if: github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && inputs.publish_to_pypi)
301
- run: python -m twine upload wheelhouse/*.whl
305
+ run: python -m twine upload --skip-existing wheelhouse/*.whl
302
306
  env:
303
307
  TWINE_USERNAME: __token__
304
308
  TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
305
309
 
306
310
  - name: Publish macOS wheels to TestPyPI
307
311
  if: github.event_name == 'workflow_dispatch' && !inputs.publish_to_pypi
308
- run: python -m twine upload --repository-url https://test.pypi.org/legacy/ wheelhouse/*.whl
312
+ run: python -m twine upload --skip-existing --repository-url https://test.pypi.org/legacy/ wheelhouse/*.whl
309
313
  env:
310
314
  TWINE_USERNAME: __token__
311
315
  TWINE_PASSWORD: ${{ secrets.TEST_PYPI_API_TOKEN }}
@@ -366,6 +370,7 @@ jobs:
366
370
  uses: pypa/gh-action-pypi-publish@release/v1
367
371
  with:
368
372
  password: ${{ secrets.PYPI_API_TOKEN }}
373
+ skip-existing: true
369
374
  packages-dir: dist/
370
375
 
371
376
  - name: Publish sdist to TestPyPI
@@ -374,4 +379,5 @@ jobs:
374
379
  with:
375
380
  repository-url: https://test.pypi.org/legacy/
376
381
  password: ${{ secrets.TEST_PYPI_API_TOKEN }}
382
+ skip-existing: true
377
383
  packages-dir: dist/
@@ -42,6 +42,9 @@ else ()
42
42
  endif()
43
43
 
44
44
  SET(MAS_DIRECTORY "${CMAKE_BINARY_DIR}/MAS/")
45
+ # quicktype does not create the output directory; a FRESH build dir has no MAS/ yet
46
+ # (mirrors the CAS_DIRECTORY MAKE_DIRECTORY below).
47
+ file(MAKE_DIRECTORY "${MAS_DIRECTORY}")
45
48
  if(DEFINED ENV{LOCAL_MKF_DIR})
46
49
  SET(LOCAL_MKF_MAS TRUE)
47
50
  SET(MAS_DIR "${PROJECT_SOURCE_DIR}/_mas_local")
@@ -124,8 +127,22 @@ include_directories("${CMAKE_BINARY_DIR}/_deps/eigen-src")
124
127
 
125
128
  if(NOT LOCAL_MKF_MAS)
126
129
  message(STATUS "Fetching MKF")
127
- # Force fresh clone by using a unique timestamp - update this when MKF changes
128
- set(MKF_FORCE_REFRESH "2026-04-29-extra-components")
130
+ # --------------------------------------------------------------------
131
+ # MKF tracks main (ABT #73 resolved).
132
+ #
133
+ # MKF main deleted converter_models and links the Kirchhoff converter-model
134
+ # library (libKirchhoffApi.so) via KirchhoffBridge.cpp. The vendored build
135
+ # globs MKF's .cpp into the PyOpenMagnetics module, so it needs that .so at
136
+ # link time — which the Kirchhoff ExternalProject wired below (mirroring
137
+ # MKF's own MKF_USE_KIRCHHOFF) now provides. Kirchhoff and its AAS/PSMA
138
+ # siblings are published, so a clean checkout resolves the whole tree. The
139
+ # earlier 2ae859dc SHA pin (pre-converter_models-deletion) is no longer
140
+ # needed now that the Kirchhoff lib build is wired in — the prerequisite the
141
+ # old pin comment named. Tracks main so MKF fixes reach the wheel.
142
+ set(MKF_GIT_TAG "main"
143
+ CACHE STRING "MKF git ref for the vendored PyOM build")
144
+ # Force fresh clone by using a unique timestamp - update this when the pin changes
145
+ set(MKF_FORCE_REFRESH "2026-07-03-track-main-kirchhoff")
129
146
  # Tell MKF to disable matplotplusplus and use SVG-based Painter instead
130
147
  set(INCLUDE_PYMKF ON CACHE BOOL "Build Python interface" FORCE)
131
148
  # GIT_SUBMODULES_RECURSE pulls in CAS/PEAS (added 2026-04 alongside the
@@ -140,7 +157,7 @@ if(NOT LOCAL_MKF_MAS)
140
157
  # leave it out, otherwise FetchContent doubles the clone.
141
158
  FetchContent_Declare(MKF
142
159
  GIT_REPOSITORY https://github.com/OpenMagnetics/MKF.git
143
- GIT_TAG main
160
+ GIT_TAG ${MKF_GIT_TAG}
144
161
  GIT_PROGRESS TRUE
145
162
  GIT_SUBMODULES "CAS" "PEAS" "cci_coords"
146
163
  GIT_SUBMODULES_RECURSE TRUE)
@@ -182,28 +199,40 @@ if(NOT LOCAL_MKF_MAS)
182
199
  message(STATUS "MAS git error: ${MAS_GIT_ERROR}")
183
200
  endif()
184
201
 
185
- # Always delete and repopulate MKF to ensure we get the latest main,
186
- # mirroring the MAS refresh above. FetchContent will NOT re-fetch an
187
- # already-cloned source dir even with GIT_TAG main, so a persisted build
188
- # dir (incremental CI cache, local rebuilds) otherwise keeps a STALE MKF
189
- # checkout fixes merged to MKF main would silently never reach the wheel.
202
+ # Always delete and repopulate MKF so the checkout matches ${MKF_GIT_TAG}
203
+ # exactly, mirroring the MAS refresh above. FetchContent will NOT re-checkout
204
+ # an already-cloned source dir when the pin changes, so a persisted build dir
205
+ # (incremental CI cache, or a local build that previously tracked main) would
206
+ # otherwise keep a STALE MKF checkout at the wrong SHA e.g. a main tip that
207
+ # needs the unpublished libKirchhoffApi.so and fails to link (ABT #73).
190
208
  if(EXISTS ${CMAKE_BINARY_DIR}/_deps/mkf-src)
191
- message(STATUS "Removing old MKF source to force fresh clone")
209
+ message(STATUS "Removing old MKF source to force fresh checkout at ${MKF_GIT_TAG}")
192
210
  file(REMOVE_RECURSE ${CMAKE_BINARY_DIR}/_deps/mkf-src)
193
211
  endif()
194
212
  message(STATUS "Populating MKF")
195
213
  FetchContent_Populate(MKF)
196
- # Show git log to verify we built against MKF main HEAD
214
+ # Show git log AND assert the checkout is exactly the pinned SHA. A silent
215
+ # drift here would resurface the libKirchhoffApi.so link failure ABT #73
216
+ # guards against, so fail LOUDLY at configure time instead.
197
217
  execute_process(
198
- COMMAND git -C ${mkf_SOURCE_DIR} log --oneline -1
199
- OUTPUT_VARIABLE MKF_GIT_LOG
218
+ COMMAND git -C ${mkf_SOURCE_DIR} rev-parse HEAD
219
+ OUTPUT_VARIABLE MKF_GIT_HEAD
200
220
  OUTPUT_STRIP_TRAILING_WHITESPACE
201
221
  ERROR_VARIABLE MKF_GIT_ERROR
202
222
  )
203
- message(STATUS "MKF version: ${MKF_GIT_LOG}")
223
+ message(STATUS "MKF version: ${MKF_GIT_HEAD}")
204
224
  if(MKF_GIT_ERROR)
205
225
  message(STATUS "MKF git error: ${MKF_GIT_ERROR}")
206
226
  endif()
227
+ # Only assert when the pin is a full 40-char SHA (a branch/tag ref can't be
228
+ # compared to a resolved HEAD; that path is opt-in and the builder owns it).
229
+ string(LENGTH "${MKF_GIT_TAG}" _mkf_pin_len)
230
+ if(_mkf_pin_len EQUAL 40 AND NOT "${MKF_GIT_HEAD}" STREQUAL "${MKF_GIT_TAG}")
231
+ message(FATAL_ERROR
232
+ "Vendored PyOM built MKF at ${MKF_GIT_HEAD} but the pin is "
233
+ "${MKF_GIT_TAG} (ABT #73). Delete ${CMAKE_BINARY_DIR}/_deps/mkf-src "
234
+ "and reconfigure, or fetch the pinned commit.")
235
+ endif()
207
236
 
208
237
  message(STATUS ${MAS_SOURCE_DIR})
209
238
  else()
@@ -226,6 +255,13 @@ add_custom_command(
226
255
  -S ${MKF_DIR}/PEAS/schemas/utils.json
227
256
  -S ${MKF_DIR}/PEAS/schemas/inputs/operatingPointExcitation.json
228
257
  -S ${MKF_DIR}/PEAS/schemas/outputs/insulationCoordination.json
258
+ # outputBase.json must precede/accompany lossElementPerHarmonic.json: the
259
+ # latter's allOf[0] is {"$ref": "./outputBase.json"}. On Linux quicktype
260
+ # resolves that relative ref off the file path, but on Windows the file-URI
261
+ # resolution yields an empty URI ("Could not fetch schema") and the build
262
+ # fails. Feeding outputBase.json as a source lets quicktype resolve it by
263
+ # $id (https://psma.com/peas/outputs/outputBase.json) on every platform.
264
+ -S ${MKF_DIR}/PEAS/schemas/outputs/outputBase.json
229
265
  -S ${MKF_DIR}/PEAS/schemas/outputs/lossElementPerHarmonic.json
230
266
  -S ${MAS_DIR}/schemas/magnetic.json
231
267
  -S ${MAS_DIR}/schemas/magnetic/core.json
@@ -257,7 +293,8 @@ add_custom_command(
257
293
  -S ${MAS_DIR}/schemas/inputs/designRequirements.json
258
294
  -S ${MAS_DIR}/schemas/inputs/operatingConditions.json
259
295
  -S ${MAS_DIR}/schemas/inputs/operatingPoint.json
260
- -S ${MAS_DIR}/schemas/inputs/operatingPointExcitation.json
296
+ # operatingPointExcitation moved from MAS to PEAS (MAS 76d5e9e "consolidate on PEAS");
297
+ # the PEAS copy is already fed above (${MKF_DIR}/PEAS/schemas/inputs/operatingPointExcitation.json).
261
298
  -S ${MAS_DIR}/schemas/inputs/topologies/flyback.json
262
299
  -S ${MAS_DIR}/schemas/inputs/topologies/currentTransformer.json
263
300
  -S ${MAS_DIR}/schemas/inputs/topologies/boost.json
@@ -307,6 +344,9 @@ add_custom_command(
307
344
  COMMAND ${CMAKE_COMMAND} -E remove -f "${CAS_DIRECTORY}/CAS.hpp"
308
345
  COMMAND quicktype -l c++ -s schema ${CAS_DIR}/schemas/inputs.json
309
346
  -S ${CAS_DIR}/schemas/inputs/designRequirements.json
347
+ # designRequirements.allowedTechnologies $refs ../capacitor.json#/$defs/technology; feed it as a
348
+ # source so Windows quicktype resolves it by $id (relative file-URI resolution fails on Windows).
349
+ -S ${CAS_DIR}/schemas/capacitor.json
310
350
  -S ${PEAS_DIR}/schemas/utils.json
311
351
  -S ${PEAS_DIR}/schemas/inputs/twoTerminalOperatingPoint.json
312
352
  -S ${PEAS_DIR}/schemas/inputs/operatingConditions.json
@@ -341,6 +381,8 @@ file(GLOB SOURCES src/*.cpp
341
381
  ${MKF_DIR}/src/support/*.cpp
342
382
  )
343
383
 
384
+ # converter.cpp is now a thin shim over the Kirchhoff string API (libKirchhoffApi) — re-enabled.
385
+
344
386
  set(CCI_GENERATED_CPP "${CMAKE_BINARY_DIR}/generated/CciCoordinatesData.cpp")
345
387
  find_package(Python3 REQUIRED COMPONENTS Interpreter)
346
388
  add_custom_command(
@@ -408,6 +450,73 @@ include_directories("${CMAKE_BINARY_DIR}/_cmrc/include")
408
450
  include_directories("${MAS_DIRECTORY}")
409
451
  include_directories("src/")
410
452
 
453
+ # Kirchhoff: the externalised converter-model library that replaced MKF's converter_models. converter.cpp
454
+ # and cmc.cpp are thin shims over its Kirchhoff::api string/JSON facade (libKirchhoffApi.so), and MKF's
455
+ # converter_models/KirchhoffBridge.cpp links it too. Built ISOLATED via ExternalProject so Kirchhoff's own
456
+ # `namespace MAS` types stay hidden inside the .so and never collide with MKF's identically-named ones —
457
+ # only JSON strings cross the boundary. Mirrors MKF/CMakeLists.txt's MKF_USE_KIRCHHOFF wiring.
458
+ # * Default: clone from GitHub at KIRCHHOFF_GIT_TAG (recursive submodules).
459
+ # * Local dev: -DKIRCHHOFF_SOURCE_DIR=/path/to/Kirchhoff to build a working tree instead.
460
+ include(ExternalProject)
461
+ set(KIRCHHOFF_GIT_TAG "main" CACHE STRING "Kirchhoff git tag/branch to build (when fetching from GitHub)")
462
+ set(KIRCHHOFF_SOURCE_DIR "" CACHE PATH "Local Kirchhoff working tree (leave empty to fetch from GitHub)")
463
+ set(KIRCHHOFF_BUILD_DIR "${CMAKE_BINARY_DIR}/kirchhoff-build")
464
+ # Platform-specific shared-lib artifact names. On Windows a shared library links against an
465
+ # import library (.lib, IMPORTED_IMPLIB) with the .dll as the runtime (IMPORTED_LOCATION);
466
+ # Linux/macOS link the .so/.dylib directly.
467
+ if(WIN32)
468
+ set(KIRCHHOFF_API_LIB "${KIRCHHOFF_BUILD_DIR}/KirchhoffApi.dll")
469
+ set(KIRCHHOFF_API_IMPLIB "${KIRCHHOFF_BUILD_DIR}/KirchhoffApi.lib")
470
+ elseif(APPLE)
471
+ set(KIRCHHOFF_API_LIB "${KIRCHHOFF_BUILD_DIR}/libKirchhoffApi.dylib")
472
+ else()
473
+ set(KIRCHHOFF_API_LIB "${KIRCHHOFF_BUILD_DIR}/libKirchhoffApi.so")
474
+ endif()
475
+ if(KIRCHHOFF_SOURCE_DIR)
476
+ set(_kirchhoff_src SOURCE_DIR "${KIRCHHOFF_SOURCE_DIR}")
477
+ set(_kirchhoff_hdr_dir "${KIRCHHOFF_SOURCE_DIR}/src")
478
+ else()
479
+ # HTTPS (not SSH): the manylinux wheel containers have no ssh binary. Kirchhoff and its PSMA
480
+ # submodules are public, so anonymous HTTPS clones them fine. The submodule URLs in Kirchhoff's
481
+ # own .gitmodules are SSH, so CI additionally sets url."https://github.com/".insteadOf in
482
+ # CIBW_BEFORE_ALL (publish.yml) to rewrite those during the recursive clone.
483
+ set(_kirchhoff_src GIT_REPOSITORY "https://github.com/OpenConverters/Kirchhoff.git"
484
+ GIT_TAG "${KIRCHHOFF_GIT_TAG}")
485
+ set(_kirchhoff_hdr_dir "${CMAKE_BINARY_DIR}/kirchhoff-ext-prefix/src/kirchhoff_ext/src")
486
+ endif()
487
+ ExternalProject_Add(kirchhoff_ext
488
+ ${_kirchhoff_src}
489
+ PREFIX "${CMAKE_BINARY_DIR}/kirchhoff-ext-prefix"
490
+ BINARY_DIR "${KIRCHHOFF_BUILD_DIR}"
491
+ CMAKE_ARGS
492
+ -DCMAKE_BUILD_TYPE=Release
493
+ -DKIRCHHOFF_BUILD_SHARED_API=ON # emit libKirchhoffApi.so (string facade, hidden internals)
494
+ -DKIRCHHOFF_BUILD_PYBIND=OFF
495
+ -DENABLE_NGSPICE=ON # KH carries the simulator MKF stopped building
496
+ BUILD_ALWAYS OFF
497
+ INSTALL_COMMAND ""
498
+ BUILD_BYPRODUCTS "${KIRCHHOFF_API_LIB}" "${KIRCHHOFF_API_IMPLIB}")
499
+ include_directories("${_kirchhoff_hdr_dir}")
500
+ add_library(KirchhoffApi SHARED IMPORTED)
501
+ set_target_properties(KirchhoffApi PROPERTIES IMPORTED_LOCATION "${KIRCHHOFF_API_LIB}")
502
+ if(WIN32)
503
+ set_target_properties(KirchhoffApi PROPERTIES IMPORTED_IMPLIB "${KIRCHHOFF_API_IMPLIB}")
504
+ endif()
505
+ add_dependencies(KirchhoffApi kirchhoff_ext)
506
+ target_link_libraries(PyOpenMagnetics PRIVATE KirchhoffApi)
507
+ add_dependencies(PyOpenMagnetics kirchhoff_ext)
508
+
509
+ # Ship libKirchhoffApi next to the extension in the wheel and point the extension's RPATH at
510
+ # itself, so (1) the co-built shared lib resolves at runtime and (2) the wheel-repair tools
511
+ # (auditwheel / delocate / delvewheel) can LOCATE and vendor it — otherwise auditwheel fails with
512
+ # "required library libKirchhoffApi.so could not be located" even though the build linked fine.
513
+ if(APPLE)
514
+ set_target_properties(PyOpenMagnetics PROPERTIES INSTALL_RPATH "@loader_path" BUILD_WITH_INSTALL_RPATH TRUE)
515
+ elseif(NOT WIN32)
516
+ set_target_properties(PyOpenMagnetics PROPERTIES INSTALL_RPATH "$ORIGIN" BUILD_WITH_INSTALL_RPATH TRUE)
517
+ endif()
518
+ install(FILES "${KIRCHHOFF_API_LIB}" DESTINATION .)
519
+
411
520
  # target_link_libraries(PyOpenMagnetics PUBLIC MKF)
412
521
 
413
522
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: PyOpenMagnetics
3
- Version: 1.5.1
3
+ Version: 1.6.1
4
4
  Summary: Python wrapper for OpenMagnetics
5
5
  Author-Email: Alfonso Martinez <Alfonso_VII@hotmail.com>
6
6
  Classifier: Development Status :: 4 - Beta
@@ -57,6 +57,29 @@ cd PyOpenMagnetics
57
57
  pip install .
58
58
  ```
59
59
 
60
+ #### MKF is pinned to a SHA (build reproducibility — ABT #73)
61
+
62
+ This build compiles MKF by **globbing its `.cpp` files directly** into the
63
+ extension (it does not drive MKF's own CMake). MKF `main` has since moved to
64
+ "delete `converter_models` + link the Kirchhoff converter-model library
65
+ (`libKirchhoffApi.so`)"; because Kirchhoff and its AAS sibling are **not yet
66
+ published**, a from-scratch build of newer `main` cannot obtain that library
67
+ and **fails to link**.
68
+
69
+ `CMakeLists.txt` therefore pins the MKF FetchContent to the last self-contained
70
+ commit — `MKF_GIT_TAG=2ae859dcae6c3b2e5a128893247b7714360e863f`, the exact SHA
71
+ the shipping `.so` was built from — and a configure-time guard fails loudly if
72
+ the checkout drifts. A clean rebuild is reproducible as-is:
73
+
74
+ ```bash
75
+ rm -rf build && pip install . --no-deps -v # or: cmake -S . -B build && ninja -C build
76
+ ```
77
+
78
+ To **advance** the pin you must first wire the Kirchhoff library build into
79
+ `CMakeLists.txt` (publish AAS/Kirchhoff, then `add_subdirectory` +
80
+ `target_link_libraries(... libKirchhoffApi.so)`). Overriding
81
+ `-DMKF_GIT_TAG=main` before that lands will break the link.
82
+
60
83
  ### ⚠️ Import Instructions
61
84
 
62
85
  **Important:** The compiled extension module may require special import handling:
@@ -40,6 +40,29 @@ cd PyOpenMagnetics
40
40
  pip install .
41
41
  ```
42
42
 
43
+ #### MKF is pinned to a SHA (build reproducibility — ABT #73)
44
+
45
+ This build compiles MKF by **globbing its `.cpp` files directly** into the
46
+ extension (it does not drive MKF's own CMake). MKF `main` has since moved to
47
+ "delete `converter_models` + link the Kirchhoff converter-model library
48
+ (`libKirchhoffApi.so`)"; because Kirchhoff and its AAS sibling are **not yet
49
+ published**, a from-scratch build of newer `main` cannot obtain that library
50
+ and **fails to link**.
51
+
52
+ `CMakeLists.txt` therefore pins the MKF FetchContent to the last self-contained
53
+ commit — `MKF_GIT_TAG=2ae859dcae6c3b2e5a128893247b7714360e863f`, the exact SHA
54
+ the shipping `.so` was built from — and a configure-time guard fails loudly if
55
+ the checkout drifts. A clean rebuild is reproducible as-is:
56
+
57
+ ```bash
58
+ rm -rf build && pip install . --no-deps -v # or: cmake -S . -B build && ninja -C build
59
+ ```
60
+
61
+ To **advance** the pin you must first wire the Kirchhoff library build into
62
+ `CMakeLists.txt` (publish AAS/Kirchhoff, then `add_subdirectory` +
63
+ `target_link_libraries(... libKirchhoffApi.so)`). Overriding
64
+ `-DMKF_GIT_TAG=main` before that lands will break the link.
65
+
43
66
  ### ⚠️ Import Instructions
44
67
 
45
68
  **Important:** The compiled extension module may require special import handling:
@@ -1,78 +1,78 @@
1
- [build-system]
2
- requires = ["scikit-build-core", "pybind11"]
3
- build-backend = "scikit_build_core.build"
4
-
5
- [project]
6
- name = "PyOpenMagnetics"
7
- version = "1.5.1"
8
- requires-python = ">=3.8"
9
- authors = [
10
- { name="Alfonso Martinez", email="Alfonso_VII@hotmail.com" },
11
- ]
12
- description = "Python wrapper for OpenMagnetics"
13
- readme = "README.md"
14
- classifiers = [
15
- "Development Status :: 4 - Beta",
16
- "Programming Language :: Python :: 3",
17
- "Operating System :: Microsoft :: Windows :: Windows 11",
18
- "Operating System :: POSIX :: Linux",
19
- "Programming Language :: C++",
20
- "License :: OSI Approved :: MIT License",
21
- ]
22
-
23
- [project.urls]
24
- Homepage = "https://openmagnetics.com"
25
- Repository = "https://github.com/OpenMagnetics/PyOpenMagnetics"
26
- Contact = "https://www.linkedin.com/in/alfonso-martinez-de-la-torre/"
27
-
28
- [tool.scikit-build]
29
- build-dir = "build/{wheel_tag}"
30
- cmake.verbose = true
31
- sdist.exclude = [".venv*", ".venv*/**", "build", "build/**", "dist", "dist/**", "*.egg-info", "__pycache__", "*.pyc"]
32
- # Include additional files in the wheel
33
- wheel.packages = ["."]
34
- wheel.install-dir = "PyOpenMagnetics"
35
- # Ensure AGENTS.md and llms.txt are included in sdist and wheel
36
- sdist.include = ["__init__.py", "AGENTS.md", "llms.txt", "PyOpenMagnetics.pyi"]
37
-
38
- [[tool.scikit-build.overrides]]
39
- if.platform-system = "^linux"
40
- # build.tool-args = ["-j8"]
41
- [[tool.scikit-build.overrides]]
42
- if.platform-system = "^win32"
43
- # build.tool-args = ["-maxcpucount:8"]
44
-
45
- [tool.cibuildwheel]
46
- skip=["pp*", "*-win32", "*mul*"]
47
- manylinux-x86_64-image = "manylinux_2_28"
48
- manylinux-aarch64-image = "manylinux_2_28"
49
- manylinux-ppc64le-image = "manylinux_2_28"
50
- manylinux-s390x-image = "manylinux_2_28"
51
- manylinux-pypy_x86_64-image = "manylinux_2_28"
52
- manylinux-pypy_aarch64-image = "manylinux_2_28"
53
- environment = { GIT_LFS_SKIP_SMUDGE=1 }
54
- build-verbosity = 1
55
-
56
- [tool.cibuildwheel.linux]
57
- before-all = [
58
- "rm -rf /project/build /root/.cmake",
59
- "dnf -y module reset nodejs",
60
- "dnf -y module enable nodejs:20",
61
- "dnf -y install nodejs npm",
62
- "npm --version",
63
- "npm install -g quicktype@23.0.170"
64
- ]
65
- # Parallel level 2 (not 3): two large pybind11 TUs compiling at once stays
66
- # within the runner's RAM. Combined with dropping -g (see CMakeLists.txt),
67
- # this avoids the OOM that recycled the runner mid-compile (exit 143).
68
- environment = { GIT_LFS_SKIP_SMUDGE=1, CMAKE_BUILD_PARALLEL_LEVEL="2" }
69
-
70
- [tool.cibuildwheel.macos]
71
- before-all = "npm --version && npm install -g quicktype@23.0.170"
72
- environment = { MACOSX_DEPLOYMENT_TARGET="14.0", GIT_LFS_SKIP_SMUDGE=1, CMAKE_BUILD_PARALLEL_LEVEL="3" }
73
-
74
- [tool.cibuildwheel.windows]
75
- before-all = "rmdir /S /Q build && npm --version && npm install -g quicktype@23.0.170"
76
- archs = ["AMD64"]
77
-
78
- environment = { GIT_LFS_SKIP_SMUDGE=1, CMAKE_BUILD_PARALLEL_LEVEL="2" }
1
+ [build-system]
2
+ requires = ["scikit-build-core", "pybind11"]
3
+ build-backend = "scikit_build_core.build"
4
+
5
+ [project]
6
+ name = "PyOpenMagnetics"
7
+ version = "1.6.1"
8
+ requires-python = ">=3.8"
9
+ authors = [
10
+ { name="Alfonso Martinez", email="Alfonso_VII@hotmail.com" },
11
+ ]
12
+ description = "Python wrapper for OpenMagnetics"
13
+ readme = "README.md"
14
+ classifiers = [
15
+ "Development Status :: 4 - Beta",
16
+ "Programming Language :: Python :: 3",
17
+ "Operating System :: Microsoft :: Windows :: Windows 11",
18
+ "Operating System :: POSIX :: Linux",
19
+ "Programming Language :: C++",
20
+ "License :: OSI Approved :: MIT License",
21
+ ]
22
+
23
+ [project.urls]
24
+ Homepage = "https://openmagnetics.com"
25
+ Repository = "https://github.com/OpenMagnetics/PyOpenMagnetics"
26
+ Contact = "https://www.linkedin.com/in/alfonso-martinez-de-la-torre/"
27
+
28
+ [tool.scikit-build]
29
+ build-dir = "build/{wheel_tag}"
30
+ cmake.verbose = true
31
+ sdist.exclude = [".venv*", ".venv*/**", "build", "build/**", "dist", "dist/**", "*.egg-info", "__pycache__", "*.pyc"]
32
+ # Include additional files in the wheel
33
+ wheel.packages = ["."]
34
+ wheel.install-dir = "PyOpenMagnetics"
35
+ # Ensure AGENTS.md and llms.txt are included in sdist and wheel
36
+ sdist.include = ["__init__.py", "AGENTS.md", "llms.txt", "PyOpenMagnetics.pyi"]
37
+
38
+ [[tool.scikit-build.overrides]]
39
+ if.platform-system = "^linux"
40
+ # build.tool-args = ["-j8"]
41
+ [[tool.scikit-build.overrides]]
42
+ if.platform-system = "^win32"
43
+ # build.tool-args = ["-maxcpucount:8"]
44
+
45
+ [tool.cibuildwheel]
46
+ skip=["pp*", "*-win32", "*mul*"]
47
+ manylinux-x86_64-image = "manylinux_2_28"
48
+ manylinux-aarch64-image = "manylinux_2_28"
49
+ manylinux-ppc64le-image = "manylinux_2_28"
50
+ manylinux-s390x-image = "manylinux_2_28"
51
+ manylinux-pypy_x86_64-image = "manylinux_2_28"
52
+ manylinux-pypy_aarch64-image = "manylinux_2_28"
53
+ environment = { GIT_LFS_SKIP_SMUDGE=1 }
54
+ build-verbosity = 1
55
+
56
+ [tool.cibuildwheel.linux]
57
+ before-all = [
58
+ "rm -rf /project/build /root/.cmake",
59
+ "dnf -y module reset nodejs",
60
+ "dnf -y module enable nodejs:20",
61
+ "dnf -y install nodejs npm",
62
+ "npm --version",
63
+ "npm install -g quicktype@23.0.170"
64
+ ]
65
+ # Parallel level 2 (not 3): two large pybind11 TUs compiling at once stays
66
+ # within the runner's RAM. Combined with dropping -g (see CMakeLists.txt),
67
+ # this avoids the OOM that recycled the runner mid-compile (exit 143).
68
+ environment = { GIT_LFS_SKIP_SMUDGE=1, CMAKE_BUILD_PARALLEL_LEVEL="2" }
69
+
70
+ [tool.cibuildwheel.macos]
71
+ before-all = "npm --version && npm install -g quicktype@23.0.170"
72
+ environment = { MACOSX_DEPLOYMENT_TARGET="14.0", GIT_LFS_SKIP_SMUDGE=1, CMAKE_BUILD_PARALLEL_LEVEL="3" }
73
+
74
+ [tool.cibuildwheel.windows]
75
+ before-all = "rmdir /S /Q build && npm --version && npm install -g quicktype@23.0.170"
76
+ archs = ["AMD64"]
77
+
78
+ environment = { GIT_LFS_SKIP_SMUDGE=1, CMAKE_BUILD_PARALLEL_LEVEL="2" }
@@ -104,6 +104,61 @@ json calculate_advised_magnetics(json inputsJson, int maximumNumberResults, json
104
104
  }
105
105
  }
106
106
 
107
+ json calculate_advised_magnetics_with_filters(json inputsJson, json filterFlowJson, int maximumNumberResults, json coreModeJson) {
108
+ // FAST custom design driven by a CALLER-SUPPLIED filter flow: strictlyRequired
109
+ // filters (e.g. DC/EFFECTIVE_CURRENT_DENSITY, which the default custom flow
110
+ // omits) DROP any wound candidate that fails them, so designed windings are
111
+ // current-density gated while the fast path's loss ranking + core search are
112
+ // preserved. Exposes MagneticAdviser::get_advised_magnetic_fast(inputs, flow, n).
113
+ try {
114
+ OpenMagnetics::Inputs inputs(inputsJson);
115
+ OpenMagnetics::CoreAdviser::CoreAdviserModes coreMode;
116
+ from_json(coreModeJson, coreMode);
117
+
118
+ std::vector<OpenMagnetics::MagneticFilterOperation> filterFlow;
119
+ for (auto filterJson : filterFlowJson) {
120
+ OpenMagnetics::MagneticFilterOperation filter(filterJson);
121
+ filterFlow.push_back(filter);
122
+ }
123
+
124
+ OpenMagnetics::MagneticAdviser magneticAdviser;
125
+ magneticAdviser.set_core_mode(coreMode);
126
+ auto masMagnetics = magneticAdviser.get_advised_magnetic_fast(inputs, filterFlow, maximumNumberResults);
127
+
128
+ auto scoringsPerFilter = magneticAdviser.get_scorings();
129
+
130
+ json results = json();
131
+ results["data"] = json::array();
132
+ for (auto& [masMagnetic, scoring] : masMagnetics) {
133
+ std::string name = masMagnetic.get_magnetic().get_manufacturer_info().value().get_reference().value();
134
+ json result;
135
+ json masJson;
136
+ to_json(masJson, masMagnetic);
137
+ result["mas"] = masJson;
138
+ result["scoring"] = scoring;
139
+ if (scoringsPerFilter.count(name)) {
140
+ json filterScorings;
141
+ for (auto& [filter, filterScore] : scoringsPerFilter[name]) {
142
+ filterScorings[std::string(magic_enum::enum_name(filter))] = filterScore;
143
+ }
144
+ result["scoringPerFilter"] = filterScorings;
145
+ }
146
+ results["data"].push_back(result);
147
+ }
148
+
149
+ sort(results["data"].begin(), results["data"].end(), [](json& b1, json& b2) {
150
+ return b1["scoring"] > b2["scoring"];
151
+ });
152
+
153
+ return results;
154
+ }
155
+ catch (const std::exception &exc) {
156
+ json exception;
157
+ exception["data"] = "Exception: " + std::string{exc.what()};
158
+ return exception;
159
+ }
160
+ }
161
+
107
162
  json calculate_advised_magnetics_fast(json inputsJson, int maximumNumberResults, json coreModeJson) {
108
163
  try {
109
164
  OpenMagnetics::Inputs inputs(inputsJson);
@@ -391,7 +446,20 @@ void register_adviser_bindings(py::module& m) {
391
446
  ... print(f"Score: {item['scoring']}, Per filter: {item['scoringPerFilter']}")
392
447
  )pbdoc",
393
448
  py::arg("inputs_json"), py::arg("max_results"), py::arg("core_mode_json"));
394
-
449
+
450
+ m.def("calculate_advised_magnetics_with_filters", &calculate_advised_magnetics_with_filters,
451
+ R"pbdoc(
452
+ Fast custom magnetic design with a CALLER-SUPPLIED filter flow.
453
+
454
+ Like calculate_advised_magnetics_fast(), but strictlyRequired filters in
455
+ filter_flow_json DROP any wound candidate that fails them — e.g. add
456
+ DC_CURRENT_DENSITY / EFFECTIVE_CURRENT_DENSITY so designed windings are
457
+ current-density gated. Each filter op is
458
+ {"filter": <TitleCaseName>, "invert": bool, "log": bool,
459
+ "strictlyRequired": bool, "weight": float}.
460
+ )pbdoc",
461
+ py::arg("inputs_json"), py::arg("filter_flow_json"), py::arg("max_results"), py::arg("core_mode_json"));
462
+
395
463
  m.def("calculate_advised_magnetics_fast", &calculate_advised_magnetics_fast,
396
464
  R"pbdoc(
397
465
  Get recommended complete magnetic designs using fast analytical mode.
@@ -9,6 +9,7 @@ json calculate_advised_cores(json inputsJson, json weightsJson, int maximumNumbe
9
9
 
10
10
  // Magnetic adviser
11
11
  json calculate_advised_magnetics(json inputsJson, int maximumNumberResults, json coreModeJson);
12
+ json calculate_advised_magnetics_with_filters(json inputsJson, json filterFlowJson, int maximumNumberResults, json coreModeJson);
12
13
  json calculate_advised_magnetics_fast(json inputsJson, int maximumNumberResults, json coreModeJson);
13
14
  json calculate_advised_magnetics_from_catalog(json inputsJson, json catalogJson, int maximumNumberResults);
14
15
  json calculate_advised_magnetics_from_cache(json inputsJson, json filterFlowJson, int maximumNumberResults);