PyOpenMagnetics 1.2.0__tar.gz → 1.2.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 (65) hide show
  1. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/.github/workflows/publish.yml +103 -12
  2. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/CMakeLists.txt +10 -0
  3. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/PKG-INFO +1 -1
  4. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/PyOpenMagnetics.pyi +54 -5
  5. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/pyproject.toml +10 -10
  6. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/src/common.h +2 -0
  7. pyopenmagnetics-1.2.2/src/converter.cpp +656 -0
  8. pyopenmagnetics-1.2.2/src/converter.h +33 -0
  9. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/src/core.cpp +11 -1
  10. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/src/module.cpp +2 -0
  11. pyopenmagnetics-1.2.2/tests/test_converter_endpoints.py +235 -0
  12. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/.github/workflows/ci.yml +0 -0
  13. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/.gitignore +0 -0
  14. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/LICENSE +0 -0
  15. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/README.md +0 -0
  16. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/api/MAS.py +0 -0
  17. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/api/mas_db_reader.py +0 -0
  18. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/api/validation.py +0 -0
  19. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/clear_cibuildwheel_cache.sh +0 -0
  20. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/docs/compatibility.md +0 -0
  21. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/docs/errors.md +0 -0
  22. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/docs/performance.md +0 -0
  23. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/examples/README.md +0 -0
  24. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/examples/buck_inductor.py +0 -0
  25. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/examples/flyback_design.py +0 -0
  26. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/force_fresh_build.sh +0 -0
  27. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/llms.txt +0 -0
  28. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/notebooks/01_getting_started.ipynb +0 -0
  29. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/notebooks/02_buck_inductor.ipynb +0 -0
  30. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/notebooks/03_core_losses.ipynb +0 -0
  31. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/notebooks/README.md +0 -0
  32. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/requirements.txt +0 -0
  33. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/src/advisers.cpp +0 -0
  34. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/src/advisers.h +0 -0
  35. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/src/bobbin.cpp +0 -0
  36. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/src/bobbin.h +0 -0
  37. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/src/core.h +0 -0
  38. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/src/database.cpp +0 -0
  39. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/src/database.h +0 -0
  40. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/src/logging.cpp +0 -0
  41. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/src/logging.h +0 -0
  42. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/src/losses.cpp +0 -0
  43. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/src/losses.h +0 -0
  44. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/src/plotting.cpp +0 -0
  45. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/src/plotting.h +0 -0
  46. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/src/settings.cpp +0 -0
  47. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/src/settings.h +0 -0
  48. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/src/simulation.cpp +0 -0
  49. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/src/simulation.h +0 -0
  50. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/src/utils.cpp +0 -0
  51. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/src/utils.h +0 -0
  52. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/src/winding.cpp +0 -0
  53. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/src/winding.h +0 -0
  54. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/src/wire.cpp +0 -0
  55. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/src/wire.h +0 -0
  56. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/test.py +0 -0
  57. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/tests/__init__.py +0 -0
  58. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/tests/conftest.py +0 -0
  59. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/tests/test_core.py +0 -0
  60. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/tests/test_core_adviser.py +0 -0
  61. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/tests/test_examples_integration.py +0 -0
  62. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/tests/test_inputs.py +0 -0
  63. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/tests/test_logging.py +0 -0
  64. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/tests/test_magnetic_adviser.py +0 -0
  65. {pyopenmagnetics-1.2.0 → pyopenmagnetics-1.2.2}/tests/test_winding.py +0 -0
@@ -4,6 +4,12 @@ on:
4
4
  release:
5
5
  types: [published]
6
6
  workflow_dispatch: # Allow manual trigger for testing
7
+ inputs:
8
+ skip_macos:
9
+ description: 'Skip macOS builds (useful when macOS builds are failing due to infrastructure issues)'
10
+ required: false
11
+ default: false
12
+ type: boolean
7
13
 
8
14
  env:
9
15
  GIT_LFS_SKIP_SMUDGE: 1 # Skip LFS to avoid bandwidth quota issues
@@ -12,16 +18,36 @@ jobs:
12
18
  build_wheels:
13
19
  name: Build wheels on ${{ matrix.os }}
14
20
  runs-on: ${{ matrix.os }}
21
+ continue-on-error: ${{ matrix.os == 'macos-15' }}
15
22
  strategy:
16
23
  fail-fast: false
17
24
  matrix:
18
- os: [ubuntu-22.04, windows-2022, macos-15]
25
+ os: ${{ github.event_name == 'workflow_dispatch' && inputs.skip_macos && fromJson('["ubuntu-22.04", "windows-2022"]') || fromJson('["ubuntu-22.04", "windows-2022", "macos-15"]') }}
19
26
 
20
27
  steps:
21
28
  - uses: actions/checkout@v4
22
29
  with:
23
30
  submodules: recursive
24
31
 
32
+ - name: Cache cibuildwheel
33
+ uses: actions/cache@v4
34
+ with:
35
+ path: |
36
+ ~/.cache/cibuildwheel
37
+ ~/Library/Caches/cibuildwheel
38
+ C:\Users\runneradmin\AppData\Local\pypa\cibuildwheel\Cache
39
+ key: cibuildwheel-${{ runner.os }}-${{ hashFiles('**/pyproject.toml') }}
40
+ restore-keys: |
41
+ cibuildwheel-${{ runner.os }}-
42
+
43
+ - name: Cache npm
44
+ uses: actions/cache@v4
45
+ with:
46
+ path: ~/.npm
47
+ key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }}
48
+ restore-keys: |
49
+ ${{ runner.os }}-npm-
50
+
25
51
  - name: Set up Python
26
52
  uses: actions/setup-python@v5
27
53
  with:
@@ -33,11 +59,51 @@ jobs:
33
59
  node-version: "18"
34
60
 
35
61
  - name: Install quicktype
36
- run: npm install -g quicktype
62
+ shell: bash
63
+ run: |
64
+ for i in {1..5}; do
65
+ npm install -g quicktype && break
66
+ if [ $i -lt 5 ]; then
67
+ echo "Retry $i failed, waiting 60s..."
68
+ sleep 60
69
+ fi
70
+ done
37
71
 
38
72
  - name: Install cibuildwheel
39
73
  run: python -m pip install cibuildwheel==2.21.3
40
74
 
75
+ - name: Pre-download virtualenv
76
+ shell: bash
77
+ run: |
78
+ # Create cache directory
79
+ if [[ "$RUNNER_OS" == "Windows" ]]; then
80
+ CACHE_DIR="$LOCALAPPDATA/pypa/cibuildwheel/Cache"
81
+ elif [[ "$RUNNER_OS" == "macOS" ]]; then
82
+ CACHE_DIR="$HOME/Library/Caches/cibuildwheel"
83
+ else
84
+ CACHE_DIR="$HOME/.cache/cibuildwheel"
85
+ fi
86
+ mkdir -p "$CACHE_DIR"
87
+
88
+ # Download virtualenv.pyz with retry
89
+ VENV_VERSION="20.26.6"
90
+ VENV_FILE="$CACHE_DIR/virtualenv-$VENV_VERSION.pyz"
91
+ VENV_URL="https://github.com/pypa/get-virtualenv/blob/$VENV_VERSION/public/virtualenv.pyz?raw=true"
92
+
93
+ if [[ ! -f "$VENV_FILE" ]]; then
94
+ echo "Downloading virtualenv.pyz..."
95
+ for i in {1..10}; do
96
+ if curl -fsSL --max-time 30 "$VENV_URL" -o "$VENV_FILE"; then
97
+ echo "Downloaded successfully"
98
+ break
99
+ fi
100
+ echo "Download attempt $i failed, waiting 60s..."
101
+ sleep 60
102
+ done
103
+ else
104
+ echo "virtualenv.pyz already cached"
105
+ fi
106
+
41
107
  - name: Build wheels
42
108
  run: python -m cibuildwheel --output-dir wheelhouse
43
109
  env:
@@ -50,19 +116,26 @@ jobs:
50
116
  # Install Node.js 18 and quicktype in the build container (Linux)
51
117
  # Also install gcc-toolset-13 for C++23 support
52
118
  CIBW_BEFORE_ALL_LINUX: |
53
- dnf install -y gcc-toolset-13 && \
54
- source /opt/rh/gcc-toolset-13/enable && \
55
- curl -fsSL https://rpm.nodesource.com/setup_18.x | bash - && \
56
- dnf install -y nodejs && \
57
- npm install -g quicktype
58
- CIBW_BEFORE_ALL_MACOS: npm install -g quicktype
119
+ for i in {1..3}; do
120
+ (dnf install -y gcc-toolset-13 eigen3-devel && \
121
+ source /opt/rh/gcc-toolset-13/enable && \
122
+ curl -fsSL --max-time 10 https://rpm.nodesource.com/setup_18.x | bash - && \
123
+ dnf install -y nodejs && \
124
+ npm install -g quicktype) && break
125
+ if [ $i -lt 3 ]; then sleep 60; fi
126
+ done
127
+ CIBW_BEFORE_ALL_MACOS: |
128
+ for i in {1..5}; do
129
+ npm install -g quicktype && break
130
+ if [ $i -lt 5 ]; then sleep 60; fi
131
+ done
59
132
  CIBW_BEFORE_ALL_WINDOWS: npm install -g quicktype
60
133
  # Set macOS deployment target to 15.0 for arm64 (Homebrew libraries require it)
61
134
  CIBW_ENVIRONMENT_MACOS: MACOSX_DEPLOYMENT_TARGET=15.0
62
135
  # Enable gcc-toolset-13 before build for C++23
63
136
  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
64
- # Install build dependencies
65
- CIBW_BEFORE_BUILD: pip install scikit-build-core cmake ninja pybind11
137
+ # Install build dependencies with retry
138
+ CIBW_BEFORE_BUILD: pip install --default-timeout=60 --retries 5 scikit-build-core cmake ninja pybind11
66
139
  # Test the wheel
67
140
  CIBW_TEST_COMMAND: python -c "import PyOpenMagnetics; print(f'PyOpenMagnetics loaded successfully with {len(dir(PyOpenMagnetics))} functions')"
68
141
 
@@ -79,6 +152,14 @@ jobs:
79
152
  with:
80
153
  submodules: recursive
81
154
 
155
+ - name: Cache npm
156
+ uses: actions/cache@v4
157
+ with:
158
+ path: ~/.npm
159
+ key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }}
160
+ restore-keys: |
161
+ ${{ runner.os }}-npm-
162
+
82
163
  - name: Set up Python
83
164
  uses: actions/setup-python@v5
84
165
  with:
@@ -90,7 +171,15 @@ jobs:
90
171
  node-version: "18"
91
172
 
92
173
  - name: Install quicktype
93
- run: npm install -g quicktype
174
+ shell: bash
175
+ run: |
176
+ for i in {1..5}; do
177
+ npm install -g quicktype && break
178
+ if [ $i -lt 5 ]; then
179
+ echo "Retry $i failed, waiting 60s..."
180
+ sleep 60
181
+ fi
182
+ done
94
183
 
95
184
  - name: Install build
96
185
  run: python -m pip install build
@@ -121,9 +210,10 @@ jobs:
121
210
  with:
122
211
  path: dist
123
212
  merge-multiple: true
213
+ continue-on-error: true
124
214
 
125
215
  - name: List distribution files
126
- run: ls -la dist/
216
+ run: ls -la dist/ 2>/dev/null || echo "No distribution files found"
127
217
 
128
218
  - name: Publish to PyPI
129
219
  uses: pypa/gh-action-pypi-publish@release/v1
@@ -150,6 +240,7 @@ jobs:
150
240
  with:
151
241
  path: dist
152
242
  merge-multiple: true
243
+ continue-on-error: true
153
244
 
154
245
  - name: Publish to TestPyPI
155
246
  uses: pypa/gh-action-pypi-publish@release/v1
@@ -106,6 +106,15 @@ FetchContent_Declare(rapidfuzz
106
106
  GIT_TAG main)
107
107
  FetchContent_MakeAvailable(rapidfuzz)
108
108
 
109
+ message(STATUS "Fetching Eigen")
110
+ FetchContent_Declare(eigen
111
+ GIT_REPOSITORY https://gitlab.com/libeigen/eigen.git
112
+ GIT_TAG 3.4.0
113
+ GIT_PROGRESS TRUE
114
+ GIT_SHALLOW TRUE)
115
+ FetchContent_MakeAvailable(eigen)
116
+ include_directories("${CMAKE_BINARY_DIR}/_deps/eigen-src")
117
+
109
118
  message(STATUS "Fetching MKF")
110
119
  # Force fresh clone by using a unique timestamp - update this when MKF changes
111
120
  set(MKF_FORCE_REFRESH "2025-02-26-01")
@@ -266,6 +275,7 @@ include_directories("${CMAKE_BINARY_DIR}/_deps/mkf-src/src/converter_models/")
266
275
  include_directories("${CMAKE_BINARY_DIR}/_deps/mkf-src/src/physical_models/")
267
276
  include_directories("${CMAKE_BINARY_DIR}/_deps/mkf-src/src/processors/")
268
277
  include_directories("${CMAKE_BINARY_DIR}/_deps/mkf-src/src/support/")
278
+ include_directories("${CMAKE_BINARY_DIR}/_deps/eigen-src")
269
279
  include_directories("${CMAKE_BINARY_DIR}/_cmrc/include")
270
280
  include_directories("${MAS_DIRECTORY}")
271
281
  include_directories("src/")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: PyOpenMagnetics
3
- Version: 1.2.0
3
+ Version: 1.2.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
@@ -685,11 +685,60 @@ def get_default_models() -> JsonDict:
685
685
  """Get default model selections."""
686
686
  ...
687
687
 
688
- # =============================================================================
689
- # CONVERTER TOPOLOGY PROCESSORS
690
- # =============================================================================
691
-
692
- def process_flyback(flyback: JsonDict) -> Inputs:
688
+ # =============================================================================
689
+ # CONVERTER TOPOLOGY PROCESSORS
690
+ # =============================================================================
691
+
692
+ def process_converter(topology: str, converter: JsonDict, use_ngspice: bool = True) -> JsonDict:
693
+ """Process a converter topology specification to Inputs.
694
+
695
+ Generic endpoint that dispatches to the appropriate topology processor.
696
+
697
+ Args:
698
+ topology: Topology name ("flyback", "buck", "boost", "single_switch_forward",
699
+ "two_switch_forward", "active_clamp_forward", "push_pull", "llc",
700
+ "cllc", "dab", "phase_shifted_full_bridge", "phase_shifted_half_bridge",
701
+ "isolated_buck", "isolated_buck_boost", "current_transformer")
702
+ converter: JSON object with converter specification per MAS schema
703
+ use_ngspice: If True, uses ngspice simulation for waveform extraction
704
+
705
+ Returns:
706
+ JSON object with "designRequirements" and "operatingPoints"
707
+ On error, returns {"error": "..."}
708
+ """
709
+ ...
710
+
711
+ def design_magnetics_from_converter(
712
+ topology: str,
713
+ converter: JsonDict,
714
+ max_results: int = 1,
715
+ core_mode: str = "AVAILABLE_CORES",
716
+ use_ngspice: bool = True,
717
+ weights: Optional[Dict[str, float]] = None
718
+ ) -> JsonDict:
719
+ """Design magnetic components from a converter specification.
720
+
721
+ High-level endpoint that combines converter processing with magnetic adviser
722
+ to go from converter specification directly to ranked magnetic designs.
723
+
724
+ Args:
725
+ topology: Topology name (see process_converter for list)
726
+ converter: JSON object with converter specification per MAS schema
727
+ max_results: Maximum number of magnetic designs to return
728
+ core_mode: Core selection mode - "AVAILABLE_CORES" or "STANDARD_CORES"
729
+ use_ngspice: If True, uses ngspice simulation for waveform extraction
730
+ weights: Optional filter weights (e.g., {"COST": 1.0, "LOSSES": 2.0})
731
+
732
+ Returns:
733
+ JSON object with "data" array containing ranked results.
734
+ Each result has:
735
+ - "mas": Mas object with magnetic design
736
+ - "scoring": Overall float score
737
+ - "scoringPerFilter": Object with individual filter scores
738
+ """
739
+ ...
740
+
741
+ def process_flyback(flyback: JsonDict) -> Inputs:
693
742
  """Process Flyback converter specification to Inputs."""
694
743
  ...
695
744
 
@@ -4,7 +4,7 @@ build-backend = "scikit_build_core.build"
4
4
 
5
5
  [project]
6
6
  name = "PyOpenMagnetics"
7
- version = "1.2.0"
7
+ version = "1.2.2"
8
8
  requires-python = ">=3.8"
9
9
  authors = [
10
10
  { name="Alfonso Martinez", email="Alfonso_VII@hotmail.com" },
@@ -48,15 +48,15 @@ manylinux-pypy_aarch64-image = "manylinux_2_28"
48
48
  environment = { GIT_LFS_SKIP_SMUDGE=1 }
49
49
  build-verbosity = 1
50
50
 
51
- [tool.cibuildwheel.linux]
52
- before-all = [
53
- "rm -rf /project/build /root/.cmake",
54
- "dnf -y module reset nodejs",
55
- "dnf -y module enable nodejs:20",
56
- "dnf -y install nodejs npm",
57
- "npm --version",
58
- "npm install -g quicktype@23.0.170"
59
- ]
51
+ [tool.cibuildwheel.linux]
52
+ before-all = [
53
+ "rm -rf /project/build /root/.cmake",
54
+ "dnf -y module reset nodejs",
55
+ "dnf -y module enable nodejs:20",
56
+ "dnf -y install nodejs npm",
57
+ "npm --version",
58
+ "npm install -g quicktype@23.0.170"
59
+ ]
60
60
  environment = { GIT_LFS_SKIP_SMUDGE=1, CMAKE_BUILD_PARALLEL_LEVEL="3" }
61
61
 
62
62
  [tool.cibuildwheel.macos]
@@ -20,6 +20,7 @@
20
20
  #include "physical_models/MagneticEnergy.h"
21
21
  #include "physical_models/Reluctance.h"
22
22
  #include "physical_models/Temperature.h"
23
+ #include "physical_models/ThermalResistance.h"
23
24
  #include "physical_models/MagnetizingInductance.h"
24
25
  #include "physical_models/CoreLosses.h"
25
26
  #include "physical_models/Resistivity.h"
@@ -33,6 +34,7 @@
33
34
  #include "processors/Inputs.h"
34
35
  #include "processors/MagneticSimulator.h"
35
36
  #include "processors/CircuitSimulatorInterface.h"
37
+ #include "processors/NgspiceRunner.h"
36
38
  #include "support/Painter.h"
37
39
  #include "support/Utils.h"
38
40