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.
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/.github/workflows/ci.yml +106 -90
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/.github/workflows/publish.yml +7 -7
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/CMakeLists.txt +14 -1
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/PKG-INFO +1 -1
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/pyproject.toml +4 -4
- pyopenmagnetics-1.6.4/src/crossref.cpp +164 -0
- pyopenmagnetics-1.6.4/src/crossref.h +20 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/losses.cpp +11 -5
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/module.cpp +2 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/.gitignore +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/AGENTS.md +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/LICENSE +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/PyOpenMagnetics.pyi +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/README.md +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/__init__.py +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/api/MAS.py +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/api/mas_db_reader.py +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/api/validation.py +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/clear_cibuildwheel_cache.sh +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/docs/compatibility.md +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/docs/errors.md +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/docs/performance.md +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/examples/README.md +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/examples/buck_inductor.py +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/examples/complete_simulation_example.py +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/examples/converter_design_example.py +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/examples/debug_bobbin.py +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/examples/debug_coil.py +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/examples/debug_core.py +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/examples/debug_plotting.py +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/examples/flyback_220v_12v_1a.py +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/examples/flyback_220v_12v_2a_complete.py +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/examples/flyback_bh_curve.png +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/examples/flyback_core.png +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/examples/flyback_design.py +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/examples/flyback_summary.png +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/examples/flyback_waveforms.png +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/examples/list_plot_funcs.py +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/examples/plot_flyback_design.py +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/examples/plot_flyback_pyom.py +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/examples/test_field_calc.py +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/examples/test_field_plot.py +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/force_fresh_build.sh +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/llms.txt +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/notebooks/01_getting_started.ipynb +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/notebooks/02_buck_inductor.ipynb +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/notebooks/03_core_losses.ipynb +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/notebooks/README.md +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/requirements.txt +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/advisers.cpp +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/advisers.h +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/bobbin.cpp +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/bobbin.h +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/cmc.cpp +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/cmc.h +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/common.h +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/converter.cpp +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/converter.h +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/core.cpp +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/core.h +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/database.cpp +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/database.h +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/logging.cpp +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/logging.h +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/losses.h +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/plotting.cpp +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/plotting.h +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/settings.cpp +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/settings.h +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/simulation.cpp +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/simulation.h +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/utils.cpp +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/utils.h +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/winding.cpp +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/winding.h +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/wire.cpp +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/src/wire.h +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/test.py +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/tests/__init__.py +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/tests/conftest.py +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/tests/test_converter_endpoints.py +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/tests/test_core.py +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/tests/test_core_adviser.py +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/tests/test_examples_integration.py +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/tests/test_inputs.py +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/tests/test_logging.py +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/tests/test_magnetic_adviser.py +0 -0
- {pyopenmagnetics-1.6.2 → pyopenmagnetics-1.6.4}/tests/test_plotting.py +0 -0
- {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:
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
- name:
|
|
46
|
-
run:
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
- name:
|
|
54
|
-
run: |
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
- name:
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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-
|
|
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
|
|
@@ -4,7 +4,7 @@ build-backend = "scikit_build_core.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "PyOpenMagnetics"
|
|
7
|
-
version = "1.6.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
313
|
-
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|