PyOpenMagnetics 1.6.0__tar.gz → 1.6.2__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 (87) hide show
  1. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/.github/workflows/publish.yml +11 -5
  2. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/CMakeLists.txt +67 -4
  3. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/PKG-INFO +1 -1
  4. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/pyproject.toml +2 -2
  5. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/src/common.h +0 -1
  6. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/src/simulation.cpp +24 -0
  7. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/.github/workflows/ci.yml +0 -0
  8. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/.gitignore +0 -0
  9. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/AGENTS.md +0 -0
  10. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/LICENSE +0 -0
  11. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/PyOpenMagnetics.pyi +0 -0
  12. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/README.md +0 -0
  13. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/__init__.py +0 -0
  14. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/api/MAS.py +0 -0
  15. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/api/mas_db_reader.py +0 -0
  16. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/api/validation.py +0 -0
  17. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/clear_cibuildwheel_cache.sh +0 -0
  18. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/docs/compatibility.md +0 -0
  19. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/docs/errors.md +0 -0
  20. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/docs/performance.md +0 -0
  21. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/examples/README.md +0 -0
  22. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/examples/buck_inductor.py +0 -0
  23. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/examples/complete_simulation_example.py +0 -0
  24. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/examples/converter_design_example.py +0 -0
  25. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/examples/debug_bobbin.py +0 -0
  26. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/examples/debug_coil.py +0 -0
  27. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/examples/debug_core.py +0 -0
  28. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/examples/debug_plotting.py +0 -0
  29. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/examples/flyback_220v_12v_1a.py +0 -0
  30. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/examples/flyback_220v_12v_2a_complete.py +0 -0
  31. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/examples/flyback_bh_curve.png +0 -0
  32. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/examples/flyback_core.png +0 -0
  33. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/examples/flyback_design.py +0 -0
  34. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/examples/flyback_summary.png +0 -0
  35. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/examples/flyback_waveforms.png +0 -0
  36. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/examples/list_plot_funcs.py +0 -0
  37. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/examples/plot_flyback_design.py +0 -0
  38. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/examples/plot_flyback_pyom.py +0 -0
  39. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/examples/test_field_calc.py +0 -0
  40. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/examples/test_field_plot.py +0 -0
  41. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/force_fresh_build.sh +0 -0
  42. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/llms.txt +0 -0
  43. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/notebooks/01_getting_started.ipynb +0 -0
  44. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/notebooks/02_buck_inductor.ipynb +0 -0
  45. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/notebooks/03_core_losses.ipynb +0 -0
  46. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/notebooks/README.md +0 -0
  47. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/requirements.txt +0 -0
  48. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/src/advisers.cpp +0 -0
  49. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/src/advisers.h +0 -0
  50. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/src/bobbin.cpp +0 -0
  51. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/src/bobbin.h +0 -0
  52. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/src/cmc.cpp +0 -0
  53. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/src/cmc.h +0 -0
  54. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/src/converter.cpp +0 -0
  55. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/src/converter.h +0 -0
  56. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/src/core.cpp +0 -0
  57. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/src/core.h +0 -0
  58. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/src/database.cpp +0 -0
  59. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/src/database.h +0 -0
  60. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/src/logging.cpp +0 -0
  61. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/src/logging.h +0 -0
  62. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/src/losses.cpp +0 -0
  63. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/src/losses.h +0 -0
  64. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/src/module.cpp +0 -0
  65. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/src/plotting.cpp +0 -0
  66. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/src/plotting.h +0 -0
  67. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/src/settings.cpp +0 -0
  68. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/src/settings.h +0 -0
  69. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/src/simulation.h +0 -0
  70. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/src/utils.cpp +0 -0
  71. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/src/utils.h +0 -0
  72. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/src/winding.cpp +0 -0
  73. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/src/winding.h +0 -0
  74. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/src/wire.cpp +0 -0
  75. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/src/wire.h +0 -0
  76. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/test.py +0 -0
  77. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/tests/__init__.py +0 -0
  78. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/tests/conftest.py +0 -0
  79. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/tests/test_converter_endpoints.py +0 -0
  80. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/tests/test_core.py +0 -0
  81. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/tests/test_core_adviser.py +0 -0
  82. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/tests/test_examples_integration.py +0 -0
  83. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/tests/test_inputs.py +0 -0
  84. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/tests/test_logging.py +0 -0
  85. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/tests/test_magnetic_adviser.py +0 -0
  86. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/tests/test_plotting.py +0 -0
  87. {pyopenmagnetics-1.6.0 → pyopenmagnetics-1.6.2}/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/
@@ -142,7 +142,7 @@ if(NOT LOCAL_MKF_MAS)
142
142
  set(MKF_GIT_TAG "main"
143
143
  CACHE STRING "MKF git ref for the vendored PyOM build")
144
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")
145
+ set(MKF_FORCE_REFRESH "2026-07-09-cm-sweep-permeability-poco")
146
146
  # Tell MKF to disable matplotplusplus and use SVG-based Painter instead
147
147
  set(INCLUDE_PYMKF ON CACHE BOOL "Build Python interface" FORCE)
148
148
  # GIT_SUBMODULES_RECURSE pulls in CAS/PEAS (added 2026-04 alongside the
@@ -344,6 +344,9 @@ add_custom_command(
344
344
  COMMAND ${CMAKE_COMMAND} -E remove -f "${CAS_DIRECTORY}/CAS.hpp"
345
345
  COMMAND quicktype -l c++ -s schema ${CAS_DIR}/schemas/inputs.json
346
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
347
350
  -S ${PEAS_DIR}/schemas/utils.json
348
351
  -S ${PEAS_DIR}/schemas/inputs/twoTerminalOperatingPoint.json
349
352
  -S ${PEAS_DIR}/schemas/inputs/operatingConditions.json
@@ -458,15 +461,55 @@ include(ExternalProject)
458
461
  set(KIRCHHOFF_GIT_TAG "main" CACHE STRING "Kirchhoff git tag/branch to build (when fetching from GitHub)")
459
462
  set(KIRCHHOFF_SOURCE_DIR "" CACHE PATH "Local Kirchhoff working tree (leave empty to fetch from GitHub)")
460
463
  set(KIRCHHOFF_BUILD_DIR "${CMAKE_BINARY_DIR}/kirchhoff-build")
461
- set(KIRCHHOFF_API_LIB "${KIRCHHOFF_BUILD_DIR}/libKirchhoffApi.so")
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
+ # The Visual Studio generator is multi-config: it emits build artifacts into a per-config
469
+ # subdirectory (Release/), so the KirchhoffApi DLL + import lib land in kirchhoff-build/Release/,
470
+ # NOT kirchhoff-build/ directly. The wheel build is always Release (CMAKE_BUILD_TYPE=Release and
471
+ # the ExternalProject BUILD_COMMAND uses --config Release), so point at that subdir; otherwise the
472
+ # extension link fails with LNK1181: cannot open input file 'KirchhoffApi.lib'.
473
+ set(KIRCHHOFF_API_LIB "${KIRCHHOFF_BUILD_DIR}/Release/KirchhoffApi.dll")
474
+ set(KIRCHHOFF_API_IMPLIB "${KIRCHHOFF_BUILD_DIR}/Release/KirchhoffApi.lib")
475
+ elseif(APPLE)
476
+ set(KIRCHHOFF_API_LIB "${KIRCHHOFF_BUILD_DIR}/libKirchhoffApi.dylib")
477
+ else()
478
+ set(KIRCHHOFF_API_LIB "${KIRCHHOFF_BUILD_DIR}/libKirchhoffApi.so")
479
+ endif()
462
480
  if(KIRCHHOFF_SOURCE_DIR)
463
481
  set(_kirchhoff_src SOURCE_DIR "${KIRCHHOFF_SOURCE_DIR}")
464
482
  set(_kirchhoff_hdr_dir "${KIRCHHOFF_SOURCE_DIR}/src")
465
483
  else()
466
- set(_kirchhoff_src GIT_REPOSITORY "git@github.com:OpenConverters/Kirchhoff.git"
484
+ # HTTPS (not SSH): the manylinux wheel containers have no ssh binary. Kirchhoff and its PSMA
485
+ # submodules are public, so anonymous HTTPS clones them fine. The submodule URLs in Kirchhoff's
486
+ # own .gitmodules are SSH, so CI additionally sets url."https://github.com/".insteadOf in
487
+ # CIBW_BEFORE_ALL (publish.yml) to rewrite those during the recursive clone.
488
+ set(_kirchhoff_src GIT_REPOSITORY "https://github.com/OpenConverters/Kirchhoff.git"
467
489
  GIT_TAG "${KIRCHHOFF_GIT_TAG}")
468
490
  set(_kirchhoff_hdr_dir "${CMAKE_BINARY_DIR}/kirchhoff-ext-prefix/src/kirchhoff_ext/src")
469
491
  endif()
492
+ # Kelvin — KH's shared TAS component selector. Since ~mid-2026 KH requires it
493
+ # (add_subdirectory(KELVIN_DIR)) but it is NOT a KH submodule, so the source must be
494
+ # supplied or KH fails to configure ("../Kelvin is not an existing directory"). KH
495
+ # builds it in-tree reusing its own PEAS, so only the checkout is needed. Mirrors
496
+ # MKF/CMakeLists.txt's KIRCHHOFF_KELVIN_DIR wiring. HTTPS for the same manylinux
497
+ # reason as the Kirchhoff clone above.
498
+ set(KIRCHHOFF_KELVIN_DIR "" CACHE PATH "Local Kelvin checkout for the Kirchhoff build (empty = fetch)")
499
+ if(NOT KIRCHHOFF_KELVIN_DIR)
500
+ set(KIRCHHOFF_KELVIN_GIT_TAG "main" CACHE STRING "Kelvin git tag/branch (when fetched for Kirchhoff)")
501
+ FetchContent_Declare(kirchhoff_kelvin
502
+ GIT_REPOSITORY "https://github.com/OpenConverters/Kelvin.git"
503
+ GIT_TAG "${KIRCHHOFF_KELVIN_GIT_TAG}"
504
+ GIT_SUBMODULES "" # KH overrides KELVIN_PEAS_DIR to its own PEAS; Kelvin's own submodules are unused
505
+ SOURCE_DIR "${CMAKE_BINARY_DIR}/kirchhoff-kelvin-src")
506
+ # Download only — KH does the add_subdirectory(KELVIN_DIR) in its own context.
507
+ FetchContent_GetProperties(kirchhoff_kelvin)
508
+ if(NOT kirchhoff_kelvin_POPULATED)
509
+ FetchContent_Populate(kirchhoff_kelvin)
510
+ endif()
511
+ set(KIRCHHOFF_KELVIN_DIR "${kirchhoff_kelvin_SOURCE_DIR}")
512
+ endif()
470
513
  ExternalProject_Add(kirchhoff_ext
471
514
  ${_kirchhoff_src}
472
515
  PREFIX "${CMAKE_BINARY_DIR}/kirchhoff-ext-prefix"
@@ -476,16 +519,36 @@ ExternalProject_Add(kirchhoff_ext
476
519
  -DKIRCHHOFF_BUILD_SHARED_API=ON # emit libKirchhoffApi.so (string facade, hidden internals)
477
520
  -DKIRCHHOFF_BUILD_PYBIND=OFF
478
521
  -DENABLE_NGSPICE=ON # KH carries the simulator MKF stopped building
522
+ -DKELVIN_DIR=${KIRCHHOFF_KELVIN_DIR} # Kelvin source (fetched above or a local checkout)
523
+ # Build ONLY the KirchhoffApi shared lib (+ its dependency chain), not Kirchhoff's standalone
524
+ # test/example executables. The wheel needs only the facade lib, and those demos/tests use POSIX
525
+ # popen/pclose (MSVC-only _popen/_pclose) that break the Windows build — and compiling 25+ binaries
526
+ # per Python version is pure waste. src/ (the library) is clean of popen.
527
+ BUILD_COMMAND "${CMAKE_COMMAND}" --build <BINARY_DIR> --config Release --target KirchhoffApi
479
528
  BUILD_ALWAYS OFF
480
529
  INSTALL_COMMAND ""
481
- BUILD_BYPRODUCTS "${KIRCHHOFF_API_LIB}")
530
+ BUILD_BYPRODUCTS "${KIRCHHOFF_API_LIB}" "${KIRCHHOFF_API_IMPLIB}")
482
531
  include_directories("${_kirchhoff_hdr_dir}")
483
532
  add_library(KirchhoffApi SHARED IMPORTED)
484
533
  set_target_properties(KirchhoffApi PROPERTIES IMPORTED_LOCATION "${KIRCHHOFF_API_LIB}")
534
+ if(WIN32)
535
+ set_target_properties(KirchhoffApi PROPERTIES IMPORTED_IMPLIB "${KIRCHHOFF_API_IMPLIB}")
536
+ endif()
485
537
  add_dependencies(KirchhoffApi kirchhoff_ext)
486
538
  target_link_libraries(PyOpenMagnetics PRIVATE KirchhoffApi)
487
539
  add_dependencies(PyOpenMagnetics kirchhoff_ext)
488
540
 
541
+ # Ship libKirchhoffApi next to the extension in the wheel and point the extension's RPATH at
542
+ # itself, so (1) the co-built shared lib resolves at runtime and (2) the wheel-repair tools
543
+ # (auditwheel / delocate / delvewheel) can LOCATE and vendor it — otherwise auditwheel fails with
544
+ # "required library libKirchhoffApi.so could not be located" even though the build linked fine.
545
+ if(APPLE)
546
+ set_target_properties(PyOpenMagnetics PROPERTIES INSTALL_RPATH "@loader_path" BUILD_WITH_INSTALL_RPATH TRUE)
547
+ elseif(NOT WIN32)
548
+ set_target_properties(PyOpenMagnetics PROPERTIES INSTALL_RPATH "$ORIGIN" BUILD_WITH_INSTALL_RPATH TRUE)
549
+ endif()
550
+ install(FILES "${KIRCHHOFF_API_LIB}" DESTINATION .)
551
+
489
552
  # target_link_libraries(PyOpenMagnetics PUBLIC MKF)
490
553
 
491
554
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: PyOpenMagnetics
3
- Version: 1.6.0
3
+ Version: 1.6.2
4
4
  Summary: Python wrapper for OpenMagnetics
5
5
  Author-Email: Alfonso Martinez <Alfonso_VII@hotmail.com>
6
6
  Classifier: Development Status :: 4 - Beta
@@ -4,7 +4,7 @@ build-backend = "scikit_build_core.build"
4
4
 
5
5
  [project]
6
6
  name = "PyOpenMagnetics"
7
- version = "1.6.0"
7
+ version = "1.6.2"
8
8
  requires-python = ">=3.8"
9
9
  authors = [
10
10
  { name="Alfonso Martinez", email="Alfonso_VII@hotmail.com" },
@@ -27,7 +27,7 @@ Contact = "https://www.linkedin.com/in/alfonso-martinez-de-la-torre/"
27
27
 
28
28
  [tool.scikit-build]
29
29
  build-dir = "build/{wheel_tag}"
30
- cmake.verbose = true
30
+ build.verbose = true
31
31
  sdist.exclude = [".venv*", ".venv*/**", "build", "build/**", "dist", "dist/**", "*.egg-info", "__pycache__", "*.pyc"]
32
32
  # Include additional files in the wheel
33
33
  wheel.packages = ["."]
@@ -34,7 +34,6 @@
34
34
  #include "processors/Inputs.h"
35
35
  #include "processors/MagneticSimulator.h"
36
36
  #include "processors/CircuitSimulatorInterface.h"
37
- #include "processors/NgspiceRunner.h"
38
37
  #include "processors/Sweeper.h"
39
38
  #include "support/Painter.h"
40
39
  #include "support/Utils.h"
@@ -325,6 +325,21 @@ json sweep_impedance_over_frequency(json magneticJson, double start, double stop
325
325
  }
326
326
  }
327
327
 
328
+ json sweep_common_mode_impedance_over_frequency(json magneticJson, double start, double stop, size_t numberElements, std::string mode, std::string title) {
329
+ try {
330
+ OpenMagnetics::Magnetic magnetic(magneticJson);
331
+ auto result = OpenMagnetics::Sweeper::sweep_common_mode_impedance_over_frequency(magnetic, start, stop, numberElements, mode, title);
332
+ json resultJson;
333
+ to_json(resultJson, result);
334
+ return resultJson;
335
+ }
336
+ catch (const std::exception &exc) {
337
+ json exception;
338
+ exception["data"] = "Exception: " + std::string{exc.what()};
339
+ return exception;
340
+ }
341
+ }
342
+
328
343
  json sweep_differential_mode_impedance_over_frequency(json magneticJson, double start, double stop, size_t numberElements, std::string mode, std::string title) {
329
344
  try {
330
345
  OpenMagnetics::Magnetic magnetic(magneticJson);
@@ -809,6 +824,15 @@ void register_simulation_bindings(py::module& m) {
809
824
  py::arg("title"),
810
825
  "Sweep impedance over a frequency range.");
811
826
 
827
+ m.def("sweep_common_mode_impedance_over_frequency", &sweep_common_mode_impedance_over_frequency,
828
+ py::arg("magnetic_json"),
829
+ py::arg("start"),
830
+ py::arg("stop"),
831
+ py::arg("number_elements"),
832
+ py::arg("mode"),
833
+ py::arg("title"),
834
+ "Sweep common-mode impedance (all windings driven in parallel — the CMC datasheet CM measurement; magnetizing tank only, no leakage resonance) over a frequency range.");
835
+
812
836
  m.def("sweep_differential_mode_impedance_over_frequency", &sweep_differential_mode_impedance_over_frequency,
813
837
  py::arg("magnetic_json"),
814
838
  py::arg("start"),
File without changes
File without changes