PyOpenMagnetics 1.7.6__tar.gz → 1.7.8__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.7.6 → pyopenmagnetics-1.7.8}/PKG-INFO +1 -1
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/pyproject.toml +1 -1
- pyopenmagnetics-1.7.8/src/common.h +114 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/src/core.cpp +48 -18
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/src/core.h +1 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/src/losses.cpp +2 -4
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/src/simulation.cpp +4 -12
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/src/winding.cpp +14 -2
- pyopenmagnetics-1.7.6/src/common.h +0 -58
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/.github/workflows/ci.yml +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/.github/workflows/publish.yml +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/.gitignore +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/AGENTS.md +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/CMakeLists.txt +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/LICENSE +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/PyOpenMagnetics.pyi +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/README.md +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/_packaging/__init__.py +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/_packaging/_build_info.py.in +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/api/MAS.py +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/api/mas_db_reader.py +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/api/validation.py +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/clear_cibuildwheel_cache.sh +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/docs/compatibility.md +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/docs/errors.md +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/docs/performance.md +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/examples/README.md +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/examples/buck_inductor.py +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/examples/complete_simulation_example.py +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/examples/converter_design_example.py +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/examples/debug_bobbin.py +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/examples/debug_coil.py +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/examples/debug_core.py +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/examples/debug_plotting.py +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/examples/flyback_220v_12v_1a.py +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/examples/flyback_220v_12v_2a_complete.py +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/examples/flyback_bh_curve.png +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/examples/flyback_core.png +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/examples/flyback_design.py +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/examples/flyback_summary.png +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/examples/flyback_waveforms.png +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/examples/list_plot_funcs.py +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/examples/plot_flyback_design.py +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/examples/plot_flyback_pyom.py +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/examples/test_field_calc.py +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/examples/test_field_plot.py +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/force_fresh_build.sh +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/llms.txt +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/notebooks/01_getting_started.ipynb +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/notebooks/02_buck_inductor.ipynb +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/notebooks/03_core_losses.ipynb +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/notebooks/README.md +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/requirements.txt +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/src/advisers.cpp +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/src/advisers.h +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/src/bobbin.cpp +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/src/bobbin.h +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/src/cmc.cpp +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/src/cmc.h +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/src/converter.cpp +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/src/converter.h +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/src/crossref.cpp +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/src/crossref.h +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/src/database.cpp +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/src/database.h +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/src/logging.cpp +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/src/logging.h +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/src/losses.h +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/src/module.cpp +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/src/plotting.cpp +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/src/plotting.h +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/src/settings.cpp +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/src/settings.h +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/src/simulation.h +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/src/utils.cpp +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/src/utils.h +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/src/winding.h +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/src/wire.cpp +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/src/wire.h +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/test.py +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/tests/__init__.py +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/tests/conftest.py +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/tests/test_converter_endpoints.py +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/tests/test_core.py +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/tests/test_core_adviser.py +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/tests/test_examples_integration.py +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/tests/test_inputs.py +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/tests/test_logging.py +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/tests/test_magnetic_adviser.py +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/tests/test_magnetics_catalogue_load.py +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/tests/test_plotting.py +0 -0
- {pyopenmagnetics-1.7.6 → pyopenmagnetics-1.7.8}/tests/test_winding.py +0 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <pybind11/pybind11.h>
|
|
4
|
+
#include <pybind11/stl.h>
|
|
5
|
+
#include "pybind11_json/pybind11_json.hpp"
|
|
6
|
+
#include <magic_enum.hpp>
|
|
7
|
+
#include <algorithm>
|
|
8
|
+
#include <stdexcept>
|
|
9
|
+
#include "json.hpp"
|
|
10
|
+
|
|
11
|
+
#include <MAS.hpp>
|
|
12
|
+
#include "advisers/MagneticAdviser.h"
|
|
13
|
+
#include "constructive_models/Bobbin.h"
|
|
14
|
+
#include "constructive_models/Coil.h"
|
|
15
|
+
#include "constructive_models/Core.h"
|
|
16
|
+
#include "constructive_models/Insulation.h"
|
|
17
|
+
#include "constructive_models/Magnetic.h"
|
|
18
|
+
#include "constructive_models/Mas.h"
|
|
19
|
+
#include "constructive_models/NumberTurns.h"
|
|
20
|
+
#include "constructive_models/Wire.h"
|
|
21
|
+
#include "physical_models/InitialPermeability.h"
|
|
22
|
+
#include "physical_models/MagneticEnergy.h"
|
|
23
|
+
#include "physical_models/Reluctance.h"
|
|
24
|
+
#include "physical_models/Temperature.h"
|
|
25
|
+
#include "physical_models/ThermalResistance.h"
|
|
26
|
+
#include "physical_models/MagnetizingInductance.h"
|
|
27
|
+
#include "physical_models/CoreLosses.h"
|
|
28
|
+
#include "physical_models/Resistivity.h"
|
|
29
|
+
#include "physical_models/CoreTemperature.h"
|
|
30
|
+
#include "physical_models/LeakageInductance.h"
|
|
31
|
+
#include "physical_models/Inductance.h"
|
|
32
|
+
#include "physical_models/StrayCapacitance.h"
|
|
33
|
+
#include "physical_models/WindingOhmicLosses.h"
|
|
34
|
+
#include "physical_models/WindingSkinEffectLosses.h"
|
|
35
|
+
#include "physical_models/WindingLosses.h"
|
|
36
|
+
#include "processors/Inputs.h"
|
|
37
|
+
#include "processors/MagneticSimulator.h"
|
|
38
|
+
#include "processors/CircuitSimulatorInterface.h"
|
|
39
|
+
#include "processors/Sweeper.h"
|
|
40
|
+
#include "support/Painter.h"
|
|
41
|
+
#include "support/Utils.h"
|
|
42
|
+
|
|
43
|
+
using namespace MAS;
|
|
44
|
+
using json = nlohmann::json;
|
|
45
|
+
using ordered_json = nlohmann::ordered_json;
|
|
46
|
+
|
|
47
|
+
namespace py = pybind11;
|
|
48
|
+
|
|
49
|
+
#define STRINGIFY(x) #x
|
|
50
|
+
#define MACRO_STRINGIFY(x) STRINGIFY(x)
|
|
51
|
+
|
|
52
|
+
namespace PyMKF {
|
|
53
|
+
|
|
54
|
+
// THE MODELS DICT NAMES THE GAP-RELUCTANCE MODEL UNDER TWO SPELLINGS, AND BOTH ARE REAL.
|
|
55
|
+
// Every Python entry point here has always read "reluctance", settings.cpp publishes that key as
|
|
56
|
+
// the default, and it stays the documented name. MKF's own C++ spells the same choice
|
|
57
|
+
// "gapReluctance" -- CoreCrossReferencer, MagneticAdviser, MagneticFilter, MagneticFilterLosses
|
|
58
|
+
// and CoreAdviserPipeline all use that -- so anyone moving between the two layers reaches for it
|
|
59
|
+
// naturally. It used to be accepted and silently dropped: the key was never looked at, the call
|
|
60
|
+
// fell back to defaults.reluctanceModelDefault, and a sweep over all nine models returned nine
|
|
61
|
+
// identical numbers, which reads as "the model does not matter for this core" rather than "the
|
|
62
|
+
// argument was ignored" (heimdall ABT #952 -- it cost a full pass of a real investigation).
|
|
63
|
+
//
|
|
64
|
+
// Accept both, "reluctance" first so the documented key wins if a caller somehow sets both.
|
|
65
|
+
// Unknown KEYS are still ignored on purpose: one dict legitimately carries several subsystems'
|
|
66
|
+
// choices ("coreLosses" alongside this one), so a strict reader would break valid callers.
|
|
67
|
+
// An unknown model NAME does throw, and now says so -- magic_enum's .value() on an empty
|
|
68
|
+
// optional threw a bare "bad optional access" that named neither the key nor the offending value.
|
|
69
|
+
inline bool find_reluctance_model(const std::map<std::string, std::string>& models,
|
|
70
|
+
OpenMagnetics::ReluctanceModels& reluctanceModelName) {
|
|
71
|
+
for (const char* key : {"reluctance", "gapReluctance"}) {
|
|
72
|
+
auto entry = models.find(key);
|
|
73
|
+
if (entry == models.end()) {
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
std::string modelNameJsonUpper = entry->second;
|
|
77
|
+
std::transform(modelNameJsonUpper.begin(), modelNameJsonUpper.end(),
|
|
78
|
+
modelNameJsonUpper.begin(), ::toupper);
|
|
79
|
+
auto parsed = magic_enum::enum_cast<OpenMagnetics::ReluctanceModels>(modelNameJsonUpper);
|
|
80
|
+
if (!parsed.has_value()) {
|
|
81
|
+
std::string known;
|
|
82
|
+
for (auto name : magic_enum::enum_names<OpenMagnetics::ReluctanceModels>()) {
|
|
83
|
+
known += (known.empty() ? "" : ", ") + std::string(name);
|
|
84
|
+
}
|
|
85
|
+
throw std::runtime_error("Unknown reluctance model '" + entry->second + "' given as '"
|
|
86
|
+
+ std::string(key) + "'. Known models: " + known);
|
|
87
|
+
}
|
|
88
|
+
reluctanceModelName = parsed.value();
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
inline bool find_reluctance_model(const json& modelsData,
|
|
95
|
+
OpenMagnetics::ReluctanceModels& reluctanceModelName) {
|
|
96
|
+
if (modelsData.is_null() || !modelsData.is_object()) {
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
std::map<std::string, std::string> models;
|
|
100
|
+
for (auto& [key, value] : modelsData.items()) {
|
|
101
|
+
if (value.is_string()) {
|
|
102
|
+
models[key] = value.get<std::string>();
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return find_reluctance_model(models, reluctanceModelName);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Global database declaration - defined in module.cpp
|
|
109
|
+
extern std::map<std::string, OpenMagnetics::Mas> masDatabase;
|
|
110
|
+
|
|
111
|
+
// Get the directory containing the PyOpenMagnetics module
|
|
112
|
+
std::string get_module_path();
|
|
113
|
+
|
|
114
|
+
} // namespace PyMKF
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#include "core.h"
|
|
2
|
+
#include "constructive_models/CorePiece.h"
|
|
2
3
|
#include "physical_models/ComplexPermeability.h"
|
|
3
4
|
#include <filesystem>
|
|
4
5
|
|
|
@@ -123,6 +124,22 @@ json calculate_core_geometrical_description(json coreDataJson) {
|
|
|
123
124
|
return result;
|
|
124
125
|
}
|
|
125
126
|
|
|
127
|
+
// ABT #1002: the IEC shape constants of a moulded body split per region (post, cover, base),
|
|
128
|
+
// so a material fit can attribute each region's reluctance to the powder pressed there.
|
|
129
|
+
json calculate_core_region_shape_constants(json coreDataJson) {
|
|
130
|
+
OpenMagnetics::Core core(coreDataJson, false, false, false);
|
|
131
|
+
auto corePiece = OpenMagnetics::CorePiece::factory(core.resolve_shape());
|
|
132
|
+
auto regions = corePiece->get_region_shape_constants();
|
|
133
|
+
if (!regions) {
|
|
134
|
+
throw std::invalid_argument("this shape family does not expose per-region shape constants");
|
|
135
|
+
}
|
|
136
|
+
json result = json::array();
|
|
137
|
+
for (auto& region : *regions) {
|
|
138
|
+
result.push_back({{"name", region.name}, {"c1", region.c1}, {"c2", region.c2}, {"minimumArea", region.minimumArea}});
|
|
139
|
+
}
|
|
140
|
+
return result;
|
|
141
|
+
}
|
|
142
|
+
|
|
126
143
|
json calculate_core_gapping(json coreDataJson) {
|
|
127
144
|
OpenMagnetics::Core core(coreDataJson, false, false, false);
|
|
128
145
|
core.process_gap_or_throw();
|
|
@@ -290,11 +307,7 @@ double calculate_inductance_from_number_turns_and_gapping(json coreData, json co
|
|
|
290
307
|
std::map<std::string, std::string> models = modelsData.get<std::map<std::string, std::string>>();
|
|
291
308
|
|
|
292
309
|
auto reluctanceModelName = OpenMagnetics::defaults.reluctanceModelDefault;
|
|
293
|
-
|
|
294
|
-
std::string modelNameJsonUpper = models["reluctance"];
|
|
295
|
-
std::transform(modelNameJsonUpper.begin(), modelNameJsonUpper.end(), modelNameJsonUpper.begin(), ::toupper);
|
|
296
|
-
reluctanceModelName = magic_enum::enum_cast<OpenMagnetics::ReluctanceModels>(modelNameJsonUpper).value();
|
|
297
|
-
}
|
|
310
|
+
find_reluctance_model(models, reluctanceModelName);
|
|
298
311
|
|
|
299
312
|
OpenMagnetics::MagnetizingInductance magnetizingInductanceObj(reluctanceModelName);
|
|
300
313
|
double magnetizingInductance = magnetizingInductanceObj.calculate_inductance_from_number_turns_and_gapping(core, coil, &operatingPoint).get_magnetizing_inductance().get_nominal().value();
|
|
@@ -310,9 +323,7 @@ double calculate_number_turns_from_gapping_and_inductance(json coreData, json co
|
|
|
310
323
|
std::map<std::string, std::string> models = modelsData.get<std::map<std::string, std::string>>();
|
|
311
324
|
|
|
312
325
|
auto reluctanceModelName = OpenMagnetics::defaults.reluctanceModelDefault;
|
|
313
|
-
|
|
314
|
-
OpenMagnetics::from_json(models["reluctance"], reluctanceModelName);
|
|
315
|
-
}
|
|
326
|
+
find_reluctance_model(models, reluctanceModelName);
|
|
316
327
|
|
|
317
328
|
OpenMagnetics::MagnetizingInductance magnetizingInductanceObj(reluctanceModelName);
|
|
318
329
|
double numberTurns = magnetizingInductanceObj.calculate_number_turns_from_gapping_and_inductance(core, coil, &inputs);
|
|
@@ -331,9 +342,7 @@ double calculate_number_turns_from_gapping_and_inductance_legacy(json coreData,
|
|
|
331
342
|
std::map<std::string, std::string> models = modelsData.get<std::map<std::string, std::string>>();
|
|
332
343
|
|
|
333
344
|
auto reluctanceModelName = OpenMagnetics::defaults.reluctanceModelDefault;
|
|
334
|
-
|
|
335
|
-
OpenMagnetics::from_json(models["reluctance"], reluctanceModelName);
|
|
336
|
-
}
|
|
345
|
+
find_reluctance_model(models, reluctanceModelName);
|
|
337
346
|
|
|
338
347
|
OpenMagnetics::MagnetizingInductance magnetizingInductanceObj(reluctanceModelName);
|
|
339
348
|
double numberTurns = magnetizingInductanceObj.calculate_number_turns_from_gapping_and_inductance(core, &inputs);
|
|
@@ -351,9 +360,7 @@ json calculate_gapping_from_number_turns_and_inductance(json coreData, json coil
|
|
|
351
360
|
OpenMagnetics::GappingType gappingType = magic_enum::enum_cast<OpenMagnetics::GappingType>(gappingTypeJson).value();
|
|
352
361
|
|
|
353
362
|
auto reluctanceModelName = OpenMagnetics::defaults.reluctanceModelDefault;
|
|
354
|
-
|
|
355
|
-
OpenMagnetics::from_json(models["reluctance"], reluctanceModelName);
|
|
356
|
-
}
|
|
363
|
+
find_reluctance_model(models, reluctanceModelName);
|
|
357
364
|
|
|
358
365
|
OpenMagnetics::MagnetizingInductance magnetizingInductanceObj(reluctanceModelName);
|
|
359
366
|
std::vector<CoreGap> gapping = magnetizingInductanceObj.calculate_gapping_from_number_turns_and_inductance(core, coil, &inputs, gappingType, decimals);
|
|
@@ -785,6 +792,25 @@ void register_core_bindings(py::module& m) {
|
|
|
785
792
|
py::arg("core_data_json"),
|
|
786
793
|
py::call_guard<py::gil_scoped_release>());
|
|
787
794
|
|
|
795
|
+
m.def("calculate_core_region_shape_constants", &calculate_core_region_shape_constants,
|
|
796
|
+
R"pbdoc(
|
|
797
|
+
Per-region IEC shape constants of a moulded body (ABT #1002).
|
|
798
|
+
|
|
799
|
+
A compression-moulded body can be pressed from up to three powders: the post the coil
|
|
800
|
+
sits on, the cover over the coil and the base plate under it. This returns the IEC 60205
|
|
801
|
+
section sums of each region, in the order functionalDescription.material lists the grades
|
|
802
|
+
([post, cover, base]), so a material fit can attribute each region's reluctance to the
|
|
803
|
+
powder pressed there: R_region = c1 / (mu0 * mu_region), Ae_region = c1 / c2.
|
|
804
|
+
|
|
805
|
+
Args:
|
|
806
|
+
core_data_json: JSON object with functionalDescription (shape family 'molded').
|
|
807
|
+
|
|
808
|
+
Returns:
|
|
809
|
+
JSON array of {name, c1, c2, minimumArea}. Raises for families without regions.
|
|
810
|
+
)pbdoc",
|
|
811
|
+
py::arg("core_data_json"),
|
|
812
|
+
py::call_guard<py::gil_scoped_release>());
|
|
813
|
+
|
|
788
814
|
m.def("calculate_core_geometrical_description", &calculate_core_geometrical_description,
|
|
789
815
|
R"pbdoc(
|
|
790
816
|
Calculate geometrical description for core visualization.
|
|
@@ -1003,7 +1029,8 @@ void register_core_bindings(py::module& m) {
|
|
|
1003
1029
|
core_data: JSON object with core specification.
|
|
1004
1030
|
coil_data: JSON object with coil specification (for turns).
|
|
1005
1031
|
operating_point_data: JSON operating point for DC bias consideration.
|
|
1006
|
-
models_data: JSON dict with "reluctance"
|
|
1032
|
+
models_data: JSON dict with "reluctance" (or MKF's own spelling,
|
|
1033
|
+
"gapReluctance" -- both accepted) model selection.
|
|
1007
1034
|
|
|
1008
1035
|
Returns:
|
|
1009
1036
|
Magnetizing inductance in Henries.
|
|
@@ -1021,7 +1048,8 @@ void register_core_bindings(py::module& m) {
|
|
|
1021
1048
|
core_data: JSON object with core specification.
|
|
1022
1049
|
coil_data: JSON object with coil/winding specification.
|
|
1023
1050
|
inputs_data: JSON Inputs with magnetizingInductance requirement.
|
|
1024
|
-
models_data: JSON dict with "reluctance"
|
|
1051
|
+
models_data: JSON dict with "reluctance" (or MKF's own spelling,
|
|
1052
|
+
"gapReluctance" -- both accepted) model selection.
|
|
1025
1053
|
|
|
1026
1054
|
Returns:
|
|
1027
1055
|
Required number of turns (may be non-integer).
|
|
@@ -1043,7 +1071,8 @@ void register_core_bindings(py::module& m) {
|
|
|
1043
1071
|
Args:
|
|
1044
1072
|
core_data: JSON object with core specification.
|
|
1045
1073
|
inputs_data: JSON Inputs with magnetizingInductance requirement.
|
|
1046
|
-
models_data: JSON dict with "reluctance"
|
|
1074
|
+
models_data: JSON dict with "reluctance" (or MKF's own spelling,
|
|
1075
|
+
"gapReluctance" -- both accepted) model selection.
|
|
1047
1076
|
|
|
1048
1077
|
Returns:
|
|
1049
1078
|
Required number of turns (may be non-integer).
|
|
@@ -1063,7 +1092,8 @@ void register_core_bindings(py::module& m) {
|
|
|
1063
1092
|
inputs_data: JSON Inputs with magnetizingInductance requirement.
|
|
1064
1093
|
gapping_type_json: Gap type ("SUBTRACTIVE", "ADDITIVE", "DISTRIBUTED").
|
|
1065
1094
|
decimals: Precision in decimal places for gap length.
|
|
1066
|
-
models_data: JSON dict with "reluctance"
|
|
1095
|
+
models_data: JSON dict with "reluctance" (or MKF's own spelling,
|
|
1096
|
+
"gapReluctance" -- both accepted) model selection.
|
|
1067
1097
|
|
|
1068
1098
|
Returns:
|
|
1069
1099
|
JSON Core object with updated gapping configuration.
|
|
@@ -32,6 +32,7 @@ json get_available_cores();
|
|
|
32
32
|
json calculate_core_data(json coreDataJson, bool includeMaterialData);
|
|
33
33
|
json calculate_core_processed_description(json coreDataJson);
|
|
34
34
|
json calculate_core_geometrical_description(json coreDataJson);
|
|
35
|
+
json calculate_core_region_shape_constants(json coreDataJson);
|
|
35
36
|
json calculate_core_gapping(json coreDataJson);
|
|
36
37
|
json load_core_data(json coresJson);
|
|
37
38
|
json get_core_temperature_dependant_parameters(json coreData, double temperature);
|
|
@@ -18,9 +18,7 @@ json calculate_core_losses(json coreData, json coilData, json inputsData, json m
|
|
|
18
18
|
std::map<std::string, std::string> models = modelsData.get<std::map<std::string, std::string>>();
|
|
19
19
|
|
|
20
20
|
auto reluctanceModelName = OpenMagnetics::defaults.reluctanceModelDefault;
|
|
21
|
-
|
|
22
|
-
OpenMagnetics::from_json(models["reluctance"], reluctanceModelName);
|
|
23
|
-
}
|
|
21
|
+
find_reluctance_model(models, reluctanceModelName);
|
|
24
22
|
auto coreLossesModelName = OpenMagnetics::defaults.coreLossesModelDefault;
|
|
25
23
|
if (models.find("coreLosses") != models.end()) {
|
|
26
24
|
OpenMagnetics::from_json(models["coreLosses"], coreLossesModelName);
|
|
@@ -315,7 +313,7 @@ void register_losses_bindings(py::module& m) {
|
|
|
315
313
|
inputs_data: JSON object with operating points (frequency, flux density).
|
|
316
314
|
models_data: JSON dict specifying models to use:
|
|
317
315
|
- "coreLosses": "STEINMETZ", "IGSE", "MSE", "BARG", "ROSHEN", "PROPRIETARY"
|
|
318
|
-
- "reluctance": "ZHANG", "MUEHLETHALER", "PARTRIDGE", "STENGLEIN"
|
|
316
|
+
- "reluctance" (alias "gapReluctance"): "ZHANG", "MUEHLETHALER", "PARTRIDGE", "STENGLEIN"
|
|
319
317
|
|
|
320
318
|
Returns:
|
|
321
319
|
JSON object containing:
|
|
@@ -7,9 +7,7 @@ json simulate(json inputsJson, json magneticJson, json modelsData) {
|
|
|
7
7
|
OpenMagnetics::Magnetic magnetic(magneticJson);
|
|
8
8
|
|
|
9
9
|
auto reluctanceModelName = OpenMagnetics::defaults.reluctanceModelDefault;
|
|
10
|
-
|
|
11
|
-
OpenMagnetics::from_json(modelsData["reluctance"], reluctanceModelName);
|
|
12
|
-
}
|
|
10
|
+
find_reluctance_model(modelsData, reluctanceModelName);
|
|
13
11
|
auto coreLossesModelName = OpenMagnetics::defaults.coreLossesModelDefault;
|
|
14
12
|
if (!modelsData.is_null() && modelsData.find("coreLosses") != modelsData.end()) {
|
|
15
13
|
OpenMagnetics::from_json(modelsData["coreLosses"], coreLossesModelName);
|
|
@@ -145,9 +143,7 @@ json calculate_inductance_matrix(json magneticJson, double frequency, json model
|
|
|
145
143
|
OpenMagnetics::Magnetic magnetic(magneticJson);
|
|
146
144
|
|
|
147
145
|
auto reluctanceModelName = OpenMagnetics::defaults.reluctanceModelDefault;
|
|
148
|
-
|
|
149
|
-
OpenMagnetics::from_json(modelsData["reluctance"], reluctanceModelName);
|
|
150
|
-
}
|
|
146
|
+
find_reluctance_model(modelsData, reluctanceModelName);
|
|
151
147
|
|
|
152
148
|
OpenMagnetics::Inductance inductance(reluctanceModelName);
|
|
153
149
|
auto inductanceMatrix = inductance.calculate_inductance_matrix(magnetic, frequency);
|
|
@@ -313,9 +309,7 @@ json calculate_coupling_coefficient_matrix(json magneticJson, double frequency,
|
|
|
313
309
|
OpenMagnetics::Magnetic magnetic(magneticJson);
|
|
314
310
|
|
|
315
311
|
auto reluctanceModelName = OpenMagnetics::defaults.reluctanceModelDefault;
|
|
316
|
-
|
|
317
|
-
OpenMagnetics::from_json(modelsData["reluctance"], reluctanceModelName);
|
|
318
|
-
}
|
|
312
|
+
find_reluctance_model(modelsData, reluctanceModelName);
|
|
319
313
|
|
|
320
314
|
OpenMagnetics::Inductance inductance(reluctanceModelName);
|
|
321
315
|
|
|
@@ -352,9 +346,7 @@ json calculate_leakage_inductance_matrix(json magneticJson, double frequency, js
|
|
|
352
346
|
OpenMagnetics::Magnetic magnetic(magneticJson);
|
|
353
347
|
|
|
354
348
|
auto reluctanceModelName = OpenMagnetics::defaults.reluctanceModelDefault;
|
|
355
|
-
|
|
356
|
-
OpenMagnetics::from_json(modelsData["reluctance"], reluctanceModelName);
|
|
357
|
-
}
|
|
349
|
+
find_reluctance_model(modelsData, reluctanceModelName);
|
|
358
350
|
|
|
359
351
|
OpenMagnetics::Inductance inductance(reluctanceModelName);
|
|
360
352
|
auto leakageInductanceMatrix = inductance.calculate_leakage_inductance_matrix(magnetic, frequency);
|
|
@@ -117,7 +117,14 @@ json wind(json coilJson, size_t repetitions, json proportionPerWindingJson, json
|
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
if (!coil.get_turns_description()) {
|
|
120
|
-
|
|
120
|
+
// ABT #930: "Turns not created" on its own cannot be acted on — it reads as a broken
|
|
121
|
+
// winder even when MKF is correctly refusing an impossible geometry (a 0.36 mm conductor
|
|
122
|
+
// asked into a 0.10 mm annulus). MKF now records why; pass it on.
|
|
123
|
+
const auto& reason = coil.get_last_fit_failure();
|
|
124
|
+
throw std::runtime_error(reason.empty()
|
|
125
|
+
? std::string("Turns not created: the winding does not fit its window, and the reason "
|
|
126
|
+
"could not be narrowed further.")
|
|
127
|
+
: "Turns not created. " + reason);
|
|
121
128
|
}
|
|
122
129
|
|
|
123
130
|
json result;
|
|
@@ -136,7 +143,12 @@ json wind_planar(json coilJson, json stackUpJson, double borderToWireDistance, j
|
|
|
136
143
|
coil.wind_planar(stackUp, borderToWireDistance, wireToWireDistance, insulationThickness, coreToLayerDistance);
|
|
137
144
|
|
|
138
145
|
if (!coil.get_turns_description()) {
|
|
139
|
-
|
|
146
|
+
// ABT #930: same as wind() above — say why, not just that.
|
|
147
|
+
const auto& reason = coil.get_last_fit_failure();
|
|
148
|
+
throw std::runtime_error(reason.empty()
|
|
149
|
+
? std::string("Turns not created: the planar winding does not fit its window, and the "
|
|
150
|
+
"reason could not be narrowed further.")
|
|
151
|
+
: "Turns not created. " + reason);
|
|
140
152
|
}
|
|
141
153
|
|
|
142
154
|
return coil;
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
#pragma once
|
|
2
|
-
|
|
3
|
-
#include <pybind11/pybind11.h>
|
|
4
|
-
#include <pybind11/stl.h>
|
|
5
|
-
#include "pybind11_json/pybind11_json.hpp"
|
|
6
|
-
#include <magic_enum.hpp>
|
|
7
|
-
#include "json.hpp"
|
|
8
|
-
|
|
9
|
-
#include <MAS.hpp>
|
|
10
|
-
#include "advisers/MagneticAdviser.h"
|
|
11
|
-
#include "constructive_models/Bobbin.h"
|
|
12
|
-
#include "constructive_models/Coil.h"
|
|
13
|
-
#include "constructive_models/Core.h"
|
|
14
|
-
#include "constructive_models/Insulation.h"
|
|
15
|
-
#include "constructive_models/Magnetic.h"
|
|
16
|
-
#include "constructive_models/Mas.h"
|
|
17
|
-
#include "constructive_models/NumberTurns.h"
|
|
18
|
-
#include "constructive_models/Wire.h"
|
|
19
|
-
#include "physical_models/InitialPermeability.h"
|
|
20
|
-
#include "physical_models/MagneticEnergy.h"
|
|
21
|
-
#include "physical_models/Reluctance.h"
|
|
22
|
-
#include "physical_models/Temperature.h"
|
|
23
|
-
#include "physical_models/ThermalResistance.h"
|
|
24
|
-
#include "physical_models/MagnetizingInductance.h"
|
|
25
|
-
#include "physical_models/CoreLosses.h"
|
|
26
|
-
#include "physical_models/Resistivity.h"
|
|
27
|
-
#include "physical_models/CoreTemperature.h"
|
|
28
|
-
#include "physical_models/LeakageInductance.h"
|
|
29
|
-
#include "physical_models/Inductance.h"
|
|
30
|
-
#include "physical_models/StrayCapacitance.h"
|
|
31
|
-
#include "physical_models/WindingOhmicLosses.h"
|
|
32
|
-
#include "physical_models/WindingSkinEffectLosses.h"
|
|
33
|
-
#include "physical_models/WindingLosses.h"
|
|
34
|
-
#include "processors/Inputs.h"
|
|
35
|
-
#include "processors/MagneticSimulator.h"
|
|
36
|
-
#include "processors/CircuitSimulatorInterface.h"
|
|
37
|
-
#include "processors/Sweeper.h"
|
|
38
|
-
#include "support/Painter.h"
|
|
39
|
-
#include "support/Utils.h"
|
|
40
|
-
|
|
41
|
-
using namespace MAS;
|
|
42
|
-
using json = nlohmann::json;
|
|
43
|
-
using ordered_json = nlohmann::ordered_json;
|
|
44
|
-
|
|
45
|
-
namespace py = pybind11;
|
|
46
|
-
|
|
47
|
-
#define STRINGIFY(x) #x
|
|
48
|
-
#define MACRO_STRINGIFY(x) STRINGIFY(x)
|
|
49
|
-
|
|
50
|
-
namespace PyMKF {
|
|
51
|
-
|
|
52
|
-
// Global database declaration - defined in module.cpp
|
|
53
|
-
extern std::map<std::string, OpenMagnetics::Mas> masDatabase;
|
|
54
|
-
|
|
55
|
-
// Get the directory containing the PyOpenMagnetics module
|
|
56
|
-
std::string get_module_path();
|
|
57
|
-
|
|
58
|
-
} // namespace PyMKF
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|