PyOpenMagnetics 1.6.2__tar.gz → 1.6.4__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 (89) hide show
  1. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/.github/workflows/ci.yml +106 -90
  2. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/.github/workflows/publish.yml +7 -7
  3. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/CMakeLists.txt +14 -1
  4. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/PKG-INFO +1 -1
  5. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/pyproject.toml +4 -4
  6. pyopenmagnetics-1.6.4/src/crossref.cpp +164 -0
  7. pyopenmagnetics-1.6.4/src/crossref.h +20 -0
  8. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/losses.cpp +11 -5
  9. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/module.cpp +2 -0
  10. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/.gitignore +0 -0
  11. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/AGENTS.md +0 -0
  12. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/LICENSE +0 -0
  13. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/PyOpenMagnetics.pyi +0 -0
  14. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/README.md +0 -0
  15. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/__init__.py +0 -0
  16. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/api/MAS.py +0 -0
  17. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/api/mas_db_reader.py +0 -0
  18. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/api/validation.py +0 -0
  19. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/clear_cibuildwheel_cache.sh +0 -0
  20. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/docs/compatibility.md +0 -0
  21. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/docs/errors.md +0 -0
  22. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/docs/performance.md +0 -0
  23. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/examples/README.md +0 -0
  24. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/examples/buck_inductor.py +0 -0
  25. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/examples/complete_simulation_example.py +0 -0
  26. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/examples/converter_design_example.py +0 -0
  27. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/examples/debug_bobbin.py +0 -0
  28. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/examples/debug_coil.py +0 -0
  29. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/examples/debug_core.py +0 -0
  30. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/examples/debug_plotting.py +0 -0
  31. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/examples/flyback_220v_12v_1a.py +0 -0
  32. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/examples/flyback_220v_12v_2a_complete.py +0 -0
  33. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/examples/flyback_bh_curve.png +0 -0
  34. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/examples/flyback_core.png +0 -0
  35. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/examples/flyback_design.py +0 -0
  36. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/examples/flyback_summary.png +0 -0
  37. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/examples/flyback_waveforms.png +0 -0
  38. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/examples/list_plot_funcs.py +0 -0
  39. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/examples/plot_flyback_design.py +0 -0
  40. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/examples/plot_flyback_pyom.py +0 -0
  41. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/examples/test_field_calc.py +0 -0
  42. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/examples/test_field_plot.py +0 -0
  43. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/force_fresh_build.sh +0 -0
  44. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/llms.txt +0 -0
  45. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/notebooks/01_getting_started.ipynb +0 -0
  46. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/notebooks/02_buck_inductor.ipynb +0 -0
  47. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/notebooks/03_core_losses.ipynb +0 -0
  48. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/notebooks/README.md +0 -0
  49. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/requirements.txt +0 -0
  50. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/advisers.cpp +0 -0
  51. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/advisers.h +0 -0
  52. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/bobbin.cpp +0 -0
  53. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/bobbin.h +0 -0
  54. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/cmc.cpp +0 -0
  55. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/cmc.h +0 -0
  56. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/common.h +0 -0
  57. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/converter.cpp +0 -0
  58. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/converter.h +0 -0
  59. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/core.cpp +0 -0
  60. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/core.h +0 -0
  61. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/database.cpp +0 -0
  62. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/database.h +0 -0
  63. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/logging.cpp +0 -0
  64. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/logging.h +0 -0
  65. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/losses.h +0 -0
  66. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/plotting.cpp +0 -0
  67. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/plotting.h +0 -0
  68. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/settings.cpp +0 -0
  69. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/settings.h +0 -0
  70. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/simulation.cpp +0 -0
  71. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/simulation.h +0 -0
  72. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/utils.cpp +0 -0
  73. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/utils.h +0 -0
  74. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/winding.cpp +0 -0
  75. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/winding.h +0 -0
  76. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/wire.cpp +0 -0
  77. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/wire.h +0 -0
  78. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/test.py +0 -0
  79. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/tests/__init__.py +0 -0
  80. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/tests/conftest.py +0 -0
  81. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/tests/test_converter_endpoints.py +0 -0
  82. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/tests/test_core.py +0 -0
  83. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/tests/test_core_adviser.py +0 -0
  84. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/tests/test_examples_integration.py +0 -0
  85. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/tests/test_inputs.py +0 -0
  86. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/tests/test_logging.py +0 -0
  87. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/tests/test_magnetic_adviser.py +0 -0
  88. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/tests/test_plotting.py +0 -0
  89. {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/tests/test_winding.py +0 -0
@@ -1,90 +1,106 @@
1
- name: CI
2
-
3
- on:
4
- push:
5
- branches: [main, master, develop]
6
- pull_request:
7
- branches: [main, master, develop]
8
-
9
- env:
10
- GIT_LFS_SKIP_SMUDGE: 1 # Skip LFS to avoid bandwidth quota issues
11
-
12
- jobs:
13
- test:
14
- name: Test on ${{ matrix.os }} / Python ${{ matrix.python-version }}
15
- runs-on: ${{ matrix.os }}
16
- strategy:
17
- fail-fast: false
18
- matrix:
19
- os: [ubuntu-22.04, windows-2022, macos-14]
20
- python-version: ["3.10", "3.11", "3.12"]
21
-
22
- steps:
23
- - uses: actions/checkout@v4
24
- with:
25
- submodules: recursive
26
-
27
- - name: Set up Python ${{ matrix.python-version }}
28
- uses: actions/setup-python@v5
29
- with:
30
- python-version: ${{ matrix.python-version }}
31
-
32
- - name: Set up Node.js
33
- uses: actions/setup-node@v4
34
- with:
35
- node-version: "18"
36
-
37
- - name: Install quicktype
38
- run: npm install -g quicktype
39
-
40
- - name: Install build dependencies
41
- run: |
42
- python -m pip install --upgrade pip
43
- pip install build pytest
44
-
45
- - name: Build and install package
46
- run: |
47
- pip install .
48
-
49
- - name: Verify installation
50
- run: |
51
- python -c "import PyOpenMagnetics; print('PyOpenMagnetics loaded with', len(dir(PyOpenMagnetics)), 'functions')"
52
-
53
- - name: Run tests
54
- run: |
55
- pytest tests/ -v --tb=short
56
- continue-on-error: true # Some tests may require specific data files
57
-
58
- build_check:
59
- name: Build check
60
- runs-on: ubuntu-22.04
61
- steps:
62
- - uses: actions/checkout@v4
63
- with:
64
- submodules: recursive
65
-
66
- - name: Set up Python
67
- uses: actions/setup-python@v5
68
- with:
69
- python-version: "3.11"
70
-
71
- - name: Set up Node.js
72
- uses: actions/setup-node@v4
73
- with:
74
- node-version: "18"
75
-
76
- - name: Install quicktype
77
- run: npm install -g quicktype
78
-
79
- - name: Install build
80
- run: python -m pip install build
81
-
82
- - name: Build package
83
- run: python -m build
84
-
85
- - name: Check built files
86
- run: |
87
- ls -la dist/
88
- echo "--- Wheel contents ---"
89
- python -m zipfile -l dist/*.whl | head -50
90
-
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main, master, develop]
6
+ pull_request:
7
+ branches: [main, master, develop]
8
+
9
+ env:
10
+ GIT_LFS_SKIP_SMUDGE: 1 # Skip LFS to avoid bandwidth quota issues
11
+
12
+ jobs:
13
+ test:
14
+ name: Test on ${{ matrix.os }} / Python ${{ matrix.python-version }}
15
+ runs-on: ${{ matrix.os }}
16
+ strategy:
17
+ fail-fast: false
18
+ matrix:
19
+ os: [ubuntu-22.04, windows-2022, macos-14]
20
+ python-version: ["3.10", "3.11", "3.12"]
21
+
22
+ steps:
23
+ - uses: actions/checkout@v4
24
+ with:
25
+ submodules: recursive
26
+
27
+ - name: Set up Python ${{ matrix.python-version }}
28
+ uses: actions/setup-python@v5
29
+ with:
30
+ python-version: ${{ matrix.python-version }}
31
+
32
+ - name: Set up Node.js
33
+ uses: actions/setup-node@v4
34
+ with:
35
+ node-version: "18"
36
+
37
+ - name: Rewrite SSH submodule URLs to HTTPS
38
+ # Kirchhoff (fetched at build time by CMake ExternalProject) declares its
39
+ # PSMA schema submodules with git@github.com: URLs, which a runner cannot
40
+ # authenticate -> "Permission denied (publickey)" and a failed wheel build.
41
+ # publish.yml already does this inside CIBW_BEFORE_ALL_*; CI never did,
42
+ # which is why every CI job was red on every OS while publish stayed green.
43
+ run: git config --global url."https://github.com/".insteadOf "git@github.com:"
44
+
45
+ - name: Install quicktype
46
+ run: npm install -g quicktype@23.2.6
47
+
48
+ - name: Install build dependencies
49
+ run: |
50
+ python -m pip install --upgrade pip
51
+ pip install build pytest
52
+
53
+ - name: Build and install package
54
+ run: |
55
+ pip install .
56
+
57
+ - name: Verify installation
58
+ run: |
59
+ python -c "import PyOpenMagnetics; print('PyOpenMagnetics loaded with', len(dir(PyOpenMagnetics)), 'functions')"
60
+
61
+ - name: Run tests
62
+ run: |
63
+ pytest tests/ -v --tb=short
64
+ continue-on-error: true # Some tests may require specific data files
65
+
66
+ build_check:
67
+ name: Build check
68
+ runs-on: ubuntu-22.04
69
+ steps:
70
+ - uses: actions/checkout@v4
71
+ with:
72
+ submodules: recursive
73
+
74
+ - name: Set up Python
75
+ uses: actions/setup-python@v5
76
+ with:
77
+ python-version: "3.11"
78
+
79
+ - name: Set up Node.js
80
+ uses: actions/setup-node@v4
81
+ with:
82
+ node-version: "18"
83
+
84
+ - name: Rewrite SSH submodule URLs to HTTPS
85
+ # Kirchhoff (fetched at build time by CMake ExternalProject) declares its
86
+ # PSMA schema submodules with git@github.com: URLs, which a runner cannot
87
+ # authenticate -> "Permission denied (publickey)" and a failed wheel build.
88
+ # publish.yml already does this inside CIBW_BEFORE_ALL_*; CI never did,
89
+ # which is why every CI job was red on every OS while publish stayed green.
90
+ run: git config --global url."https://github.com/".insteadOf "git@github.com:"
91
+
92
+ - name: Install quicktype
93
+ run: npm install -g quicktype@23.2.6
94
+
95
+ - name: Install build
96
+ run: python -m pip install build
97
+
98
+ - name: Build package
99
+ run: python -m build
100
+
101
+ - name: Check built files
102
+ run: |
103
+ ls -la dist/
104
+ echo "--- Wheel contents ---"
105
+ python -m zipfile -l dist/*.whl | head -50
106
+
@@ -75,7 +75,7 @@ jobs:
75
75
  shell: bash
76
76
  run: |
77
77
  for i in {1..5}; do
78
- npm install -g quicktype && break
78
+ npm install -g quicktype@23.2.6 && break
79
79
  if [ $i -lt 5 ]; then
80
80
  echo "Retry $i failed, waiting 60s..."
81
81
  sleep 60
@@ -120,7 +120,7 @@ jobs:
120
120
  source /opt/rh/gcc-toolset-13/enable && \
121
121
  curl -fsSL --max-time 10 https://rpm.nodesource.com/setup_18.x | bash - && \
122
122
  dnf install -y nodejs && \
123
- npm install -g quicktype) && break
123
+ npm install -g quicktype@23.2.6) && break
124
124
  if [ $i -lt 3 ]; then sleep 60; fi
125
125
  done
126
126
  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
@@ -192,7 +192,7 @@ jobs:
192
192
  node-version: "18"
193
193
 
194
194
  - name: Install quicktype
195
- run: npm install -g quicktype
195
+ run: npm install -g quicktype@23.2.6
196
196
 
197
197
  - name: Install cibuildwheel
198
198
  run: python -m pip install cibuildwheel==2.21.3
@@ -202,7 +202,7 @@ jobs:
202
202
  env:
203
203
  CIBW_BUILD: ${{ matrix.python }}-*
204
204
  CIBW_SKIP: "*-win32 *-manylinux_i686 *musllinux* pp*"
205
- CIBW_BEFORE_ALL_WINDOWS: git config --global url."https://github.com/".insteadOf "git@github.com:" && npm install -g quicktype
205
+ CIBW_BEFORE_ALL_WINDOWS: git config --global url."https://github.com/".insteadOf "git@github.com:" && npm install -g quicktype@23.2.6
206
206
  CIBW_BEFORE_BUILD: pip install --default-timeout=60 --retries 5 scikit-build-core "cmake<4" ninja pybind11
207
207
  CIBW_TEST_COMMAND: python -c "import PyOpenMagnetics; print(f'PyOpenMagnetics loaded successfully with {len(dir(PyOpenMagnetics))} functions')"
208
208
 
@@ -275,7 +275,7 @@ jobs:
275
275
  shell: bash
276
276
  run: |
277
277
  for i in {1..5}; do
278
- npm install -g quicktype && break
278
+ npm install -g quicktype@23.2.6 && break
279
279
  if [ $i -lt 5 ]; then sleep 60; fi
280
280
  done
281
281
 
@@ -290,7 +290,7 @@ jobs:
290
290
  CIBW_BEFORE_ALL_MACOS: |
291
291
  git config --global url."https://github.com/".insteadOf "git@github.com:"
292
292
  for i in {1..5}; do
293
- npm install -g quicktype && break
293
+ npm install -g quicktype@23.2.6 && break
294
294
  if [ $i -lt 5 ]; then sleep 60; fi
295
295
  done
296
296
  CIBW_ENVIRONMENT_MACOS: MACOSX_DEPLOYMENT_TARGET=15.0
@@ -352,7 +352,7 @@ jobs:
352
352
  shell: bash
353
353
  run: |
354
354
  for i in {1..5}; do
355
- npm install -g quicktype && break
355
+ npm install -g quicktype@23.2.6 && break
356
356
  if [ $i -lt 5 ]; then
357
357
  echo "Retry $i failed, waiting 60s..."
358
358
  sleep 60
@@ -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-09-cm-sweep-permeability-poco")
145
+ set(MKF_FORCE_REFRESH "2026-08-05-v1.6.4-mkf-dragback-adviser-thermal")
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
@@ -243,6 +243,10 @@ endif()
243
243
  message(STATUS "Compiling MAS")
244
244
 
245
245
 
246
+ # Every schema the generated header is built from — the DEPENDS list below.
247
+ file(GLOB_RECURSE MAS_SCHEMA_FILES CONFIGURE_DEPENDS "${MAS_DIR}/schemas/*.json")
248
+ file(GLOB_RECURSE PEAS_SCHEMA_FILES CONFIGURE_DEPENDS "${MKF_DIR}/PEAS/schemas/*.json")
249
+
246
250
  add_custom_command(
247
251
  OUTPUT "${MAS_DIRECTORY}/MAS.hpp"
248
252
  # Force regeneration by removing output first
@@ -321,6 +325,15 @@ add_custom_command(
321
325
  -S ${MAS_DIR}/schemas/inputs/topologies/seriesResonant.json
322
326
  -S ${MAS_DIR}/schemas/inputs/topologies/vienna.json
323
327
  -o ${MAS_DIRECTORY}/MAS.hpp --namespace MAS --source-style single-source --type-style pascal-case --member-style underscore-case --enumerator-style upper-underscore-case --no-boost
328
+ # WITHOUT THIS, CMake treats MAS.hpp as up to date forever once the file
329
+ # exists: no dependency is declared, so the schemas can change and the header
330
+ # silently keeps stale members. That is how a 6 July MAS.hpp survived a 28 July
331
+ # schema and broke MKF's Coil.h on Winding::set_winding_window — the schema had
332
+ # `windingWindow`, the generated class did not. (The `remove -f` above does NOT
333
+ # help: it runs only once CMake has already decided to regenerate.)
334
+ # Globbed rather than repeating the ~80-entry -S list, which would drift out of
335
+ # sync with it; CONFIGURE_DEPENDS also re-globs when a schema file is added.
336
+ DEPENDS ${MAS_SCHEMA_FILES} ${PEAS_SCHEMA_FILES}
324
337
  USES_TERMINAL)
325
338
 
326
339
  add_custom_target(PyMASGeneration
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: PyOpenMagnetics
3
- Version: 1.6.2
3
+ Version: 1.6.4
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.2"
7
+ version = "1.6.4"
8
8
  requires-python = ">=3.8"
9
9
  authors = [
10
10
  { name="Alfonso Martinez", email="Alfonso_VII@hotmail.com" },
@@ -60,7 +60,7 @@ before-all = [
60
60
  "dnf -y module enable nodejs:20",
61
61
  "dnf -y install nodejs npm",
62
62
  "npm --version",
63
- "npm install -g quicktype@23.0.170"
63
+ "npm install -g quicktype@23.2.6"
64
64
  ]
65
65
  # Parallel level 2 (not 3): two large pybind11 TUs compiling at once stays
66
66
  # within the runner's RAM. Combined with dropping -g (see CMakeLists.txt),
@@ -68,11 +68,11 @@ before-all = [
68
68
  environment = { GIT_LFS_SKIP_SMUDGE=1, CMAKE_BUILD_PARALLEL_LEVEL="2" }
69
69
 
70
70
  [tool.cibuildwheel.macos]
71
- before-all = "npm --version && npm install -g quicktype@23.0.170"
71
+ before-all = "npm --version && npm install -g quicktype@23.2.6"
72
72
  environment = { MACOSX_DEPLOYMENT_TARGET="14.0", GIT_LFS_SKIP_SMUDGE=1, CMAKE_BUILD_PARALLEL_LEVEL="3" }
73
73
 
74
74
  [tool.cibuildwheel.windows]
75
- before-all = "rmdir /S /Q build && npm --version && npm install -g quicktype@23.0.170"
75
+ before-all = "rmdir /S /Q build && npm --version && npm install -g quicktype@23.2.6"
76
76
  archs = ["AMD64"]
77
77
 
78
78
  environment = { GIT_LFS_SKIP_SMUDGE=1, CMAKE_BUILD_PARALLEL_LEVEL="2" }
@@ -0,0 +1,164 @@
1
+ #include "crossref.h"
2
+
3
+ #include "advisers/CoreCrossReferencer.h"
4
+ #include "advisers/CoreMaterialCrossReferencer.h"
5
+
6
+ namespace PyMKF {
7
+
8
+ // The cross-referencers were reachable only from the WASM build (the web app's
9
+ // `crossReferencers` module), so a Python consumer could not offer the
10
+ // CoreCrossReferencer / CoreMaterialCrossReferencer tools the app has. These
11
+ // mirror that surface, following the same {"data": ...} envelope and
12
+ // "Exception: ..." error convention as the advisers.
13
+
14
+ json calculate_cross_referenced_core(json referenceCoreJson, json inputsJson,
15
+ int64_t referenceNumberTurns, json weightsJson,
16
+ int maximumNumberResults) {
17
+ try {
18
+ OpenMagnetics::Core referenceCore(referenceCoreJson);
19
+ OpenMagnetics::Inputs inputs(inputsJson);
20
+
21
+ std::map<std::string, double> weightsKeysJson = weightsJson;
22
+ std::map<OpenMagnetics::CoreCrossReferencerFilters, double> weights;
23
+ for (auto const& [filterName, weight] : weightsKeysJson) {
24
+ OpenMagnetics::CoreCrossReferencerFilters filter;
25
+ OpenMagnetics::from_json(filterName, filter);
26
+ weights[filter] = weight;
27
+ }
28
+
29
+ OpenMagnetics::CoreCrossReferencer coreCrossReferencer;
30
+ auto scoredCores = weights.empty()
31
+ ? coreCrossReferencer.get_cross_referenced_core(referenceCore, referenceNumberTurns,
32
+ inputs, maximumNumberResults)
33
+ : coreCrossReferencer.get_cross_referenced_core(referenceCore, referenceNumberTurns,
34
+ inputs, weights, maximumNumberResults);
35
+
36
+ auto scoringsPerFilter = coreCrossReferencer.get_scorings();
37
+
38
+ json results = json();
39
+ results["data"] = json::array();
40
+ for (auto& [core, scoring] : scoredCores) {
41
+ json result;
42
+ json coreJson;
43
+ to_json(coreJson, core);
44
+ result["core"] = coreJson;
45
+ result["scoring"] = scoring;
46
+
47
+ std::string name = core.get_name().value_or("");
48
+ if (scoringsPerFilter.count(name)) {
49
+ json filterScorings;
50
+ for (auto& [filter, filterScore] : scoringsPerFilter[name]) {
51
+ filterScorings[std::string(magic_enum::enum_name(filter))] = filterScore;
52
+ }
53
+ result["scoringPerFilter"] = filterScorings;
54
+ }
55
+ results["data"].push_back(result);
56
+ }
57
+
58
+ OpenMagnetics::settings.reset();
59
+ return results;
60
+ }
61
+ catch (const std::exception &exc) {
62
+ json exception;
63
+ exception["data"] = "Exception: " + std::string{exc.what()};
64
+ return exception;
65
+ }
66
+ }
67
+
68
+ json calculate_cross_referenced_core_material(json referenceCoreMaterialJson, double temperature,
69
+ json weightsJson, int maximumNumberResults) {
70
+ try {
71
+ CoreMaterial referenceCoreMaterial(referenceCoreMaterialJson);
72
+
73
+ std::map<std::string, double> weightsKeysJson = weightsJson;
74
+ std::map<OpenMagnetics::CoreMaterialCrossReferencerFilters,
75
+ double> weights;
76
+ for (auto const& [filterName, weight] : weightsKeysJson) {
77
+ OpenMagnetics::CoreMaterialCrossReferencerFilters filter;
78
+ OpenMagnetics::from_json(filterName, filter);
79
+ weights[filter] = weight;
80
+ }
81
+
82
+ OpenMagnetics::CoreMaterialCrossReferencer coreMaterialCrossReferencer;
83
+ auto scoredMaterials = weights.empty()
84
+ ? coreMaterialCrossReferencer.get_cross_referenced_core_material(
85
+ referenceCoreMaterial, temperature, maximumNumberResults)
86
+ : coreMaterialCrossReferencer.get_cross_referenced_core_material(
87
+ referenceCoreMaterial, temperature, weights, maximumNumberResults);
88
+
89
+ auto scoringsPerFilter = coreMaterialCrossReferencer.get_scorings();
90
+
91
+ json results = json();
92
+ results["data"] = json::array();
93
+ for (auto& [material, scoring] : scoredMaterials) {
94
+ json result;
95
+ json materialJson;
96
+ to_json(materialJson, material);
97
+ result["material"] = materialJson;
98
+ result["scoring"] = scoring;
99
+
100
+ std::string name = material.get_name();
101
+ if (scoringsPerFilter.count(name)) {
102
+ json filterScorings;
103
+ for (auto& [filter, filterScore] : scoringsPerFilter[name]) {
104
+ filterScorings[std::string(magic_enum::enum_name(filter))] = filterScore;
105
+ }
106
+ result["scoringPerFilter"] = filterScorings;
107
+ }
108
+ results["data"].push_back(result);
109
+ }
110
+
111
+ OpenMagnetics::settings.reset();
112
+ return results;
113
+ }
114
+ catch (const std::exception &exc) {
115
+ json exception;
116
+ exception["data"] = "Exception: " + std::string{exc.what()};
117
+ return exception;
118
+ }
119
+ }
120
+
121
+ void register_crossref_bindings(py::module& m) {
122
+ m.def("calculate_cross_referenced_core", &calculate_cross_referenced_core,
123
+ R"pbdoc(
124
+ Rank cores that could replace a reference core.
125
+
126
+ Args:
127
+ reference_core_json: the core being replaced (shape, material, gapping).
128
+ inputs_json: design requirements and operating points the replacement must meet.
129
+ reference_number_turns: turns on the reference design.
130
+ weights_json: optional filter weights. Keys: "PERMEANCE", "CORE_LOSSES",
131
+ "SATURATION", "WINDING_WINDOW_AREA", "EFFECTIVE_AREA",
132
+ "ENVELOPING_VOLUME". Empty uses the adviser's defaults.
133
+ max_results: how many alternatives to return.
134
+
135
+ Returns:
136
+ {"data": [{"core", "scoring", "scoringPerFilter"}]} best first, or
137
+ {"data": "Exception: ..."} on failure.
138
+ )pbdoc",
139
+ py::arg("reference_core_json"), py::arg("inputs_json"),
140
+ py::arg("reference_number_turns"), py::arg("weights_json") = json::object(),
141
+ py::arg("max_results") = 10);
142
+
143
+ m.def("calculate_cross_referenced_core_material", &calculate_cross_referenced_core_material,
144
+ R"pbdoc(
145
+ Rank core materials that could replace a reference material.
146
+
147
+ Args:
148
+ reference_core_material_json: the material being replaced.
149
+ temperature: operating temperature in Celsius (material properties are
150
+ strongly temperature dependent, so this is not optional).
151
+ weights_json: optional filter weights. Keys: "INITIAL_PERMEABILITY",
152
+ "REMANENCE", "COERCIVE_FORCE", "SATURATION",
153
+ "CURIE_TEMPERATURE", "VOLUMETRIC_LOSSES".
154
+ max_results: how many alternatives to return.
155
+
156
+ Returns:
157
+ {"data": [{"material", "scoring", "scoringPerFilter"}]} best first, or
158
+ {"data": "Exception: ..."} on failure.
159
+ )pbdoc",
160
+ py::arg("reference_core_material_json"), py::arg("temperature"),
161
+ py::arg("weights_json") = json::object(), py::arg("max_results") = 10);
162
+ }
163
+
164
+ } // namespace PyMKF
@@ -0,0 +1,20 @@
1
+ #pragma once
2
+
3
+ #include "common.h"
4
+
5
+ namespace PyMKF {
6
+
7
+ // Core cross-referencer: given a reference core (shape + material + gapping) and
8
+ // the operating conditions, rank alternatives that could replace it.
9
+ json calculate_cross_referenced_core(json referenceCoreJson, json inputsJson,
10
+ int64_t referenceNumberTurns, json weightsJson,
11
+ int maximumNumberResults);
12
+
13
+ // Core-material cross-referencer: rank materials that could replace a reference
14
+ // material at a given temperature.
15
+ json calculate_cross_referenced_core_material(json referenceCoreMaterialJson, double temperature,
16
+ json weightsJson, int maximumNumberResults);
17
+
18
+ void register_crossref_bindings(py::module& m);
19
+
20
+ } // namespace PyMKF
@@ -309,13 +309,19 @@ json get_available_core_losses_methods(json magneticJson) {
309
309
  json calculate_filling_factor(json coilJson) {
310
310
  try {
311
311
  OpenMagnetics::Coil coil(coilJson, false);
312
- auto [areaFillingFactor, otherFactors] = coil.calculate_filling_factor();
313
- auto [overlappingFillingFactor, contiguousFillingFactor] = otherFactors;
312
+ // MKF main changed Coil::calculate_filling_factor() from
313
+ // std::pair<double, std::pair<double,double>> to a named
314
+ // FillingFactorsOutput struct (area / maxLayer / overlapping /
315
+ // contiguous / windingFits). Read the members directly; keep the
316
+ // original three keys and add the two new members.
317
+ auto fillingFactors = coil.calculate_filling_factor();
314
318
 
315
319
  json result;
316
- result["areaFillingFactor"] = areaFillingFactor;
317
- result["overlappingFillingFactor"] = overlappingFillingFactor;
318
- result["contiguousFillingFactor"] = contiguousFillingFactor;
320
+ result["areaFillingFactor"] = fillingFactors.areaFillingFactor;
321
+ result["overlappingFillingFactor"] = fillingFactors.overlappingFillingFactor;
322
+ result["contiguousFillingFactor"] = fillingFactors.contiguousFillingFactor;
323
+ result["maxLayerFillingFactor"] = fillingFactors.maxLayerFillingFactor;
324
+ result["windingFits"] = fillingFactors.windingFits;
319
325
  return result;
320
326
  }
321
327
  catch (const std::exception &exc) {
@@ -5,6 +5,7 @@
5
5
  #include "bobbin.h"
6
6
  #include "winding.h"
7
7
  #include "advisers.h"
8
+ #include "crossref.h"
8
9
  #include "converter.h" // converter surface re-pointed at Kirchhoff api (converter.cpp shims)
9
10
  #include "cmc.h" // CMC bindings re-pointed at Kirchhoff api::design_cmc (el-choker's path)
10
11
  #include "losses.h"
@@ -34,6 +35,7 @@ PYBIND11_MODULE(PyOpenMagnetics, m) {
34
35
  PyMKF::register_bobbin_bindings(m);
35
36
  PyMKF::register_winding_bindings(m);
36
37
  PyMKF::register_adviser_bindings(m);
38
+ PyMKF::register_crossref_bindings(m); // core / core-material cross-referencers
37
39
  PyMKF::register_converter_bindings(m); // converter surface via Kirchhoff
38
40
  PyMKF::register_cmc_bindings(m); // CMC via Kirchhoff (calculate_cmc_inputs + advanced)
39
41
  PyMKF::register_losses_bindings(m);
File without changes
File without changes