PyOpenMagnetics 1.7.15__tar.gz → 1.7.17__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.15 → pyopenmagnetics-1.7.17}/CMakeLists.txt +5 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/PKG-INFO +1 -1
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/pyproject.toml +1 -1
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/src/advisers.cpp +41 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/src/advisers.h +3 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/src/common.h +1 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/src/winding.cpp +52 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/src/winding.h +3 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/tests/test_winding.py +55 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/.github/workflows/ci.yml +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/.github/workflows/publish.yml +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/.gitignore +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/AGENTS.md +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/LICENSE +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/PyOpenMagnetics.pyi +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/README.md +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/_packaging/__init__.py +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/_packaging/_build_info.py.in +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/api/MAS.py +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/api/mas_db_reader.py +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/api/validation.py +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/clear_cibuildwheel_cache.sh +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/docs/compatibility.md +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/docs/errors.md +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/docs/performance.md +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/examples/README.md +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/examples/buck_inductor.py +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/examples/complete_simulation_example.py +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/examples/converter_design_example.py +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/examples/debug_bobbin.py +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/examples/debug_coil.py +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/examples/debug_core.py +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/examples/debug_plotting.py +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/examples/flyback_220v_12v_1a.py +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/examples/flyback_220v_12v_2a_complete.py +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/examples/flyback_bh_curve.png +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/examples/flyback_core.png +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/examples/flyback_design.py +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/examples/flyback_summary.png +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/examples/flyback_waveforms.png +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/examples/list_plot_funcs.py +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/examples/plot_flyback_design.py +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/examples/plot_flyback_pyom.py +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/examples/test_field_calc.py +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/examples/test_field_plot.py +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/force_fresh_build.sh +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/llms.txt +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/notebooks/01_getting_started.ipynb +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/notebooks/02_buck_inductor.ipynb +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/notebooks/03_core_losses.ipynb +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/notebooks/README.md +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/requirements.txt +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/src/bobbin.cpp +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/src/bobbin.h +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/src/cmc.cpp +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/src/cmc.h +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/src/converter.cpp +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/src/converter.h +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/src/core.cpp +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/src/core.h +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/src/crossref.cpp +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/src/crossref.h +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/src/database.cpp +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/src/database.h +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/src/logging.cpp +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/src/logging.h +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/src/losses.cpp +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/src/losses.h +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/src/module.cpp +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/src/plotting.cpp +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/src/plotting.h +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/src/settings.cpp +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/src/settings.h +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/src/simulation.cpp +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/src/simulation.h +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/src/utils.cpp +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/src/utils.h +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/src/wire.cpp +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/src/wire.h +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/test.py +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/tests/__init__.py +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/tests/conftest.py +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/tests/test_converter_endpoints.py +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/tests/test_core.py +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/tests/test_core_adviser.py +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/tests/test_examples_integration.py +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/tests/test_inputs.py +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/tests/test_logging.py +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/tests/test_magnetic_adviser.py +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/tests/test_magnetics_catalogue_load.py +0 -0
- {pyopenmagnetics-1.7.15 → pyopenmagnetics-1.7.17}/tests/test_plotting.py +0 -0
|
@@ -479,6 +479,11 @@ target_link_libraries(PyOpenMagnetics PUBLIC data::data)
|
|
|
479
479
|
cmrc_add_resource_library(core_losses_data ALIAS data::core_losses_data NAMESPACE coreLossesData ${MKF_DIR}/src/data/core_losses/ciGSE_coefficients.json)
|
|
480
480
|
target_link_libraries(PyOpenMagnetics PUBLIC data::core_losses_data)
|
|
481
481
|
|
|
482
|
+
# ABT #1177 (MKF WP8): the design-for-manufacturing rule numbers and their sources. MKF opens it
|
|
483
|
+
# as "src/data/dfm_rules.json", hence WHENCE the MKF root (as for the insulation standards).
|
|
484
|
+
cmrc_add_resource_library(dfm_rules ALIAS data::dfm_rules NAMESPACE dfmData WHENCE ${MKF_DIR}/ ${MKF_DIR}/src/data/dfm_rules.json)
|
|
485
|
+
target_link_libraries(PyOpenMagnetics PUBLIC data::dfm_rules)
|
|
486
|
+
|
|
482
487
|
include_directories("${CMAKE_BINARY_DIR}/_deps/json-src/include/nlohmann/")
|
|
483
488
|
include_directories("${CMAKE_BINARY_DIR}/_deps/pybind11-src/include/")
|
|
484
489
|
include_directories("${CMAKE_BINARY_DIR}/_deps/pybind11_json-src/include/pybind11_json/")
|
|
@@ -267,6 +267,15 @@ json calculate_advised_magnetics_from_cache(json inputsJson, json filterFlowJson
|
|
|
267
267
|
return results;
|
|
268
268
|
}
|
|
269
269
|
|
|
270
|
+
json calculate_manufacturability_report(json masJson) {
|
|
271
|
+
OpenMagnetics::Mas mas(masJson);
|
|
272
|
+
OpenMagnetics::Manufacturability manufacturability;
|
|
273
|
+
auto report = manufacturability.calculate_report(mas);
|
|
274
|
+
json result;
|
|
275
|
+
OpenMagnetics::to_json(result, report);
|
|
276
|
+
return result;
|
|
277
|
+
}
|
|
278
|
+
|
|
270
279
|
json calculate_advised_sections(json masJson, json patternJson, int repetitions) {
|
|
271
280
|
OpenMagnetics::Mas mas(masJson);
|
|
272
281
|
std::vector<size_t> pattern;
|
|
@@ -514,6 +523,38 @@ void register_adviser_bindings(py::module& m) {
|
|
|
514
523
|
py::arg("inputs_json"), py::arg("filter_flow_json"), py::arg("max_results"),
|
|
515
524
|
py::call_guard<py::gil_scoped_release>());
|
|
516
525
|
|
|
526
|
+
m.def("calculate_manufacturability_report", &calculate_manufacturability_report,
|
|
527
|
+
R"pbdoc(
|
|
528
|
+
Run the design-for-manufacturing rule pack over a MAS design.
|
|
529
|
+
|
|
530
|
+
Encodes as checks the public Wuerth Elektronik DFM guidance (ABT #1177, WP8). The rule
|
|
531
|
+
numbers and the source that states each of them live in MKF's src/data/dfm_rules.json.
|
|
532
|
+
Nothing in the design is changed; this is a report.
|
|
533
|
+
|
|
534
|
+
Args:
|
|
535
|
+
mas: A full MAS object (inputs + magnetic).
|
|
536
|
+
|
|
537
|
+
Returns:
|
|
538
|
+
JSON object with:
|
|
539
|
+
- "findings": one entry per rule R1..R17, each with "ruleId", "title", "status",
|
|
540
|
+
"message", "source", and where they exist "measuredValue", "thresholdValue",
|
|
541
|
+
"unit", "scope", "reason".
|
|
542
|
+
- "numberPass" / "numberWarnings" / "numberFails" / "numberNotEvaluated" /
|
|
543
|
+
"numberNotApplicable" / "numberInformational".
|
|
544
|
+
|
|
545
|
+
"status" is one of PASS, WARNING, FAIL, INFORMATIONAL, NOT_APPLICABLE,
|
|
546
|
+
NOT_EVALUATED. NOT_EVALUATED always carries a "reason": a rule that cannot be
|
|
547
|
+
evaluated says so rather than defaulting to a pass. Rules R2, R3, R4, R10, R11,
|
|
548
|
+
R14 and R16 are owned by other work packages and report NOT_EVALUATED with the
|
|
549
|
+
owning work package as the reason.
|
|
550
|
+
|
|
551
|
+
Example:
|
|
552
|
+
>>> report = PyMKF.calculate_manufacturability_report(mas)
|
|
553
|
+
>>> [f["ruleId"] for f in report["findings"] if f["status"] == "WARNING"]
|
|
554
|
+
)pbdoc",
|
|
555
|
+
py::arg("mas"),
|
|
556
|
+
py::call_guard<py::gil_scoped_release>());
|
|
557
|
+
|
|
517
558
|
m.def("calculate_advised_sections", &calculate_advised_sections,
|
|
518
559
|
"Get advised coil sections.",
|
|
519
560
|
py::arg("mas"), py::arg("pattern"), py::arg("repetitions"),
|
|
@@ -14,6 +14,9 @@ json calculate_advised_magnetics_fast(json inputsJson, int maximumNumberResults,
|
|
|
14
14
|
json calculate_advised_magnetics_from_catalog(json inputsJson, json catalogJson, int maximumNumberResults);
|
|
15
15
|
json calculate_advised_magnetics_from_cache(json inputsJson, json filterFlowJson, int maximumNumberResults);
|
|
16
16
|
|
|
17
|
+
// Design-for-manufacturing rule pack (ABT #1177, WP8)
|
|
18
|
+
json calculate_manufacturability_report(json masJson);
|
|
19
|
+
|
|
17
20
|
void register_adviser_bindings(py::module& m);
|
|
18
21
|
|
|
19
22
|
} // namespace PyMKF
|
|
@@ -500,6 +500,32 @@ json get_isolation_side_from_index(size_t index) {
|
|
|
500
500
|
return OpenMagnetics::get_isolation_side_from_index(index);
|
|
501
501
|
}
|
|
502
502
|
|
|
503
|
+
json guess_round_wire_from_dc_resistance(json coilJson, json dcResistancesJson, double maxError) {
|
|
504
|
+
if (!dcResistancesJson.is_array()) {
|
|
505
|
+
throw std::invalid_argument("guess_round_wire_from_dc_resistance: dc_resistances must be a list of DC resistances in Ohm, one per winding");
|
|
506
|
+
}
|
|
507
|
+
std::vector<double> dcResistances = dcResistancesJson.get<std::vector<double>>();
|
|
508
|
+
OpenMagnetics::Coil coil(coilJson);
|
|
509
|
+
if (dcResistances.size() != coil.get_functional_description().size()) {
|
|
510
|
+
throw std::invalid_argument("guess_round_wire_from_dc_resistance: got " + std::to_string(dcResistances.size()) +
|
|
511
|
+
" DC resistances for a coil with " + std::to_string(coil.get_functional_description().size()) + " windings");
|
|
512
|
+
}
|
|
513
|
+
for (size_t index = 0; index < dcResistances.size(); ++index) {
|
|
514
|
+
if (!(dcResistances[index] > 0)) {
|
|
515
|
+
throw std::invalid_argument("guess_round_wire_from_dc_resistance: DC resistance of winding " + std::to_string(index) +
|
|
516
|
+
" must be positive, got " + std::to_string(dcResistances[index]));
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
json result = json::array();
|
|
521
|
+
for (auto& wire : coil.guess_round_wire_from_dc_resistance(dcResistances, maxError)) {
|
|
522
|
+
json aux;
|
|
523
|
+
to_json(aux, wire);
|
|
524
|
+
result.push_back(aux);
|
|
525
|
+
}
|
|
526
|
+
return result;
|
|
527
|
+
}
|
|
528
|
+
|
|
503
529
|
json set_interlayer_insulation(json coilJson, double layerThickness) {
|
|
504
530
|
OpenMagnetics::Coil coil(coilJson, false);
|
|
505
531
|
coil.set_interlayer_insulation(layerThickness);
|
|
@@ -868,6 +894,32 @@ void register_winding_bindings(py::module& m) {
|
|
|
868
894
|
py::arg("index"),
|
|
869
895
|
py::call_guard<py::gil_scoped_release>());
|
|
870
896
|
|
|
897
|
+
m.def("guess_round_wire_from_dc_resistance", &guess_round_wire_from_dc_resistance,
|
|
898
|
+
R"pbdoc(
|
|
899
|
+
Guess the round wire of each winding from its measured DC resistance.
|
|
900
|
+
|
|
901
|
+
Winds the coil, then iteratively replaces each winding's wire with the
|
|
902
|
+
round wire whose DC resistance per meter matches the target over the
|
|
903
|
+
wound wire length, re-winding until every winding is within max_error
|
|
904
|
+
(or the chosen wires stop changing).
|
|
905
|
+
|
|
906
|
+
Args:
|
|
907
|
+
coil_json: JSON Coil with bobbin and functionalDescription (any
|
|
908
|
+
initial wire; it is replaced).
|
|
909
|
+
dc_resistances: DC resistance in Ohm per winding, same order as
|
|
910
|
+
functionalDescription.
|
|
911
|
+
max_error: Maximum relative DC-resistance error (default 0.05).
|
|
912
|
+
|
|
913
|
+
Returns:
|
|
914
|
+
JSON array of Wire objects, one per winding.
|
|
915
|
+
|
|
916
|
+
Raises:
|
|
917
|
+
EngineError if dc_resistances is not a list, its length differs from
|
|
918
|
+
the number of windings, or any value is not positive.
|
|
919
|
+
)pbdoc",
|
|
920
|
+
py::arg("coil_json"), py::arg("dc_resistances"), py::arg("max_error") = 0.05,
|
|
921
|
+
py::call_guard<py::gil_scoped_release>());
|
|
922
|
+
|
|
871
923
|
m.def("set_interlayer_insulation", &set_interlayer_insulation,
|
|
872
924
|
R"pbdoc(
|
|
873
925
|
Set interlayer insulation for a coil.
|
|
@@ -39,6 +39,9 @@ json set_interlayer_insulation(json coilJson, double layerThickness);
|
|
|
39
39
|
json set_intersection_insulation(json coilJson, double layerThickness, int numberInsulationLayers);
|
|
40
40
|
json get_solid_insulation_requirements_for_wires(json inputsJson, json patternJson, int repetitions);
|
|
41
41
|
|
|
42
|
+
// Wire estimation
|
|
43
|
+
json guess_round_wire_from_dc_resistance(json coilJson, json dcResistancesJson, double maxError);
|
|
44
|
+
|
|
42
45
|
void register_winding_bindings(py::module& m);
|
|
43
46
|
|
|
44
47
|
} // namespace PyMKF
|
|
@@ -99,3 +99,58 @@ class TestInsulationMaterials:
|
|
|
99
99
|
if len(names) > 0:
|
|
100
100
|
material = PyOpenMagnetics.find_insulation_material_by_name(names[0])
|
|
101
101
|
assert isinstance(material, dict)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
class TestGuessRoundWireFromDcResistance:
|
|
105
|
+
"""Round-wire estimation from measured per-winding DC resistance."""
|
|
106
|
+
|
|
107
|
+
@staticmethod
|
|
108
|
+
def _current_transformer_coil(sample_toroidal_core, primary_wire, secondary_wire):
|
|
109
|
+
core = PyOpenMagnetics.calculate_core_data(sample_toroidal_core, False)
|
|
110
|
+
bobbin = PyOpenMagnetics.create_basic_bobbin(core, True)
|
|
111
|
+
return {
|
|
112
|
+
"bobbin": bobbin,
|
|
113
|
+
"functionalDescription": [
|
|
114
|
+
{"name": "primary", "numberTurns": 1, "numberParallels": 1,
|
|
115
|
+
"isolationSide": PyOpenMagnetics.get_isolation_side_from_index(0), "wire": primary_wire},
|
|
116
|
+
{"name": "secondary", "numberTurns": 50, "numberParallels": 1,
|
|
117
|
+
"isolationSide": PyOpenMagnetics.get_isolation_side_from_index(1), "wire": secondary_wire},
|
|
118
|
+
],
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
def test_round_trip_recovers_dc_resistance(self, sample_toroidal_core):
|
|
122
|
+
"""Wires guessed from a known coil's DC resistances reproduce those resistances."""
|
|
123
|
+
reference = self._current_transformer_coil(sample_toroidal_core, "Round 0.90 - Grade 1", "Round 0.212 - Grade 1")
|
|
124
|
+
wound = PyOpenMagnetics.wind(reference, 1, [0.5, 0.5], [0, 1], [])
|
|
125
|
+
dc_resistances = PyOpenMagnetics.calculate_dc_resistance_per_winding(wound, 25)
|
|
126
|
+
|
|
127
|
+
# Start from the thinnest wire, as heimdall's current-transformer translator does.
|
|
128
|
+
guess = self._current_transformer_coil(sample_toroidal_core, "Round 0.01 - Grade 1", "Round 0.01 - Grade 1")
|
|
129
|
+
wires = PyOpenMagnetics.guess_round_wire_from_dc_resistance(guess, dc_resistances)
|
|
130
|
+
|
|
131
|
+
assert isinstance(wires, list)
|
|
132
|
+
assert len(wires) == 2
|
|
133
|
+
for wire in wires:
|
|
134
|
+
assert wire["type"] == "round"
|
|
135
|
+
|
|
136
|
+
# A 1-turn primary needs a far thicker conductor than a 50-turn secondary.
|
|
137
|
+
assert wires[0]["conductingDiameter"]["nominal"] > wires[1]["conductingDiameter"]["nominal"]
|
|
138
|
+
|
|
139
|
+
guess["functionalDescription"][0]["wire"] = wires[0]
|
|
140
|
+
guess["functionalDescription"][1]["wire"] = wires[1]
|
|
141
|
+
rewound = PyOpenMagnetics.wind(guess, 1, [0.5, 0.5], [0, 1], [])
|
|
142
|
+
recovered = PyOpenMagnetics.calculate_dc_resistance_per_winding(rewound, 25)
|
|
143
|
+
for target, value in zip(dc_resistances, recovered):
|
|
144
|
+
assert abs(value - target) / target < 0.05
|
|
145
|
+
|
|
146
|
+
def test_rejects_resistance_count_mismatch(self, sample_toroidal_core):
|
|
147
|
+
"""One DC resistance per winding is required."""
|
|
148
|
+
coil = self._current_transformer_coil(sample_toroidal_core, "Round 0.01 - Grade 1", "Round 0.01 - Grade 1")
|
|
149
|
+
with pytest.raises(PyOpenMagnetics.EngineError):
|
|
150
|
+
PyOpenMagnetics.guess_round_wire_from_dc_resistance(coil, [0.001])
|
|
151
|
+
|
|
152
|
+
def test_rejects_non_positive_resistance(self, sample_toroidal_core):
|
|
153
|
+
"""A zero DC resistance has no wire and must not be silently mapped to one."""
|
|
154
|
+
coil = self._current_transformer_coil(sample_toroidal_core, "Round 0.01 - Grade 1", "Round 0.01 - Grade 1")
|
|
155
|
+
with pytest.raises(PyOpenMagnetics.EngineError):
|
|
156
|
+
PyOpenMagnetics.guess_round_wire_from_dc_resistance(coil, [0.001, 0.0])
|
|
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
|