PyOpenMagnetics 1.7.18__tar.gz → 1.7.19__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 (92) hide show
  1. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/PKG-INFO +1 -1
  2. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/pyproject.toml +1 -1
  3. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/src/advisers.cpp +13 -3
  4. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/src/advisers.h +1 -1
  5. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/src/core.cpp +28 -0
  6. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/src/core.h +1 -0
  7. pyopenmagnetics-1.7.19/tests/test_datasheet_only_catalogue.py +112 -0
  8. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/.github/workflows/ci.yml +0 -0
  9. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/.github/workflows/publish.yml +0 -0
  10. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/.gitignore +0 -0
  11. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/AGENTS.md +0 -0
  12. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/CMakeLists.txt +0 -0
  13. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/LICENSE +0 -0
  14. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/PyOpenMagnetics.pyi +0 -0
  15. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/README.md +0 -0
  16. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/_packaging/__init__.py +0 -0
  17. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/_packaging/_build_info.py.in +0 -0
  18. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/api/MAS.py +0 -0
  19. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/api/mas_db_reader.py +0 -0
  20. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/api/validation.py +0 -0
  21. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/clear_cibuildwheel_cache.sh +0 -0
  22. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/docs/compatibility.md +0 -0
  23. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/docs/errors.md +0 -0
  24. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/docs/performance.md +0 -0
  25. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/examples/README.md +0 -0
  26. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/examples/buck_inductor.py +0 -0
  27. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/examples/complete_simulation_example.py +0 -0
  28. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/examples/converter_design_example.py +0 -0
  29. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/examples/debug_bobbin.py +0 -0
  30. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/examples/debug_coil.py +0 -0
  31. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/examples/debug_core.py +0 -0
  32. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/examples/debug_plotting.py +0 -0
  33. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/examples/flyback_220v_12v_1a.py +0 -0
  34. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/examples/flyback_220v_12v_2a_complete.py +0 -0
  35. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/examples/flyback_bh_curve.png +0 -0
  36. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/examples/flyback_core.png +0 -0
  37. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/examples/flyback_design.py +0 -0
  38. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/examples/flyback_summary.png +0 -0
  39. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/examples/flyback_waveforms.png +0 -0
  40. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/examples/list_plot_funcs.py +0 -0
  41. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/examples/plot_flyback_design.py +0 -0
  42. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/examples/plot_flyback_pyom.py +0 -0
  43. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/examples/test_field_calc.py +0 -0
  44. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/examples/test_field_plot.py +0 -0
  45. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/force_fresh_build.sh +0 -0
  46. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/llms.txt +0 -0
  47. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/notebooks/01_getting_started.ipynb +0 -0
  48. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/notebooks/02_buck_inductor.ipynb +0 -0
  49. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/notebooks/03_core_losses.ipynb +0 -0
  50. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/notebooks/README.md +0 -0
  51. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/requirements.txt +0 -0
  52. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/src/bobbin.cpp +0 -0
  53. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/src/bobbin.h +0 -0
  54. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/src/cmc.cpp +0 -0
  55. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/src/cmc.h +0 -0
  56. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/src/common.h +0 -0
  57. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/src/converter.cpp +0 -0
  58. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/src/converter.h +0 -0
  59. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/src/crossref.cpp +0 -0
  60. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/src/crossref.h +0 -0
  61. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/src/database.cpp +0 -0
  62. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/src/database.h +0 -0
  63. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/src/logging.cpp +0 -0
  64. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/src/logging.h +0 -0
  65. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/src/losses.cpp +0 -0
  66. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/src/losses.h +0 -0
  67. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/src/module.cpp +0 -0
  68. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/src/plotting.cpp +0 -0
  69. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/src/plotting.h +0 -0
  70. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/src/settings.cpp +0 -0
  71. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/src/settings.h +0 -0
  72. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/src/simulation.cpp +0 -0
  73. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/src/simulation.h +0 -0
  74. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/src/utils.cpp +0 -0
  75. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/src/utils.h +0 -0
  76. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/src/winding.cpp +0 -0
  77. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/src/winding.h +0 -0
  78. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/src/wire.cpp +0 -0
  79. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/src/wire.h +0 -0
  80. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/test.py +0 -0
  81. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/tests/__init__.py +0 -0
  82. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/tests/conftest.py +0 -0
  83. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/tests/test_converter_endpoints.py +0 -0
  84. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/tests/test_core.py +0 -0
  85. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/tests/test_core_adviser.py +0 -0
  86. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/tests/test_examples_integration.py +0 -0
  87. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/tests/test_inputs.py +0 -0
  88. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/tests/test_logging.py +0 -0
  89. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/tests/test_magnetic_adviser.py +0 -0
  90. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/tests/test_magnetics_catalogue_load.py +0 -0
  91. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/tests/test_plotting.py +0 -0
  92. {pyopenmagnetics-1.7.18 → pyopenmagnetics-1.7.19}/tests/test_winding.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: PyOpenMagnetics
3
- Version: 1.7.18
3
+ Version: 1.7.19
4
4
  Summary: Python wrapper for OpenMagnetics
5
5
  Author-Email: Alfonso Martinez <Alfonso_VII@hotmail.com>
6
6
  Classifier: Development Status :: 4 - Beta
@@ -4,7 +4,7 @@ build-backend = "scikit_build_core.build"
4
4
 
5
5
  [project]
6
6
  name = "PyOpenMagnetics"
7
- version = "1.7.18"
7
+ version = "1.7.19"
8
8
  requires-python = ">=3.8"
9
9
  authors = [
10
10
  { name="Alfonso Martinez", email="Alfonso_VII@hotmail.com" },
@@ -222,7 +222,7 @@ json calculate_advised_magnetics_from_catalog(json inputsJson, json catalogJson,
222
222
  return results;
223
223
  }
224
224
 
225
- json calculate_advised_magnetics_from_cache(json inputsJson, json filterFlowJson, int maximumNumberResults) {
225
+ json calculate_advised_magnetics_from_cache(json inputsJson, json filterFlowJson, int maximumNumberResults, std::optional<std::vector<std::string>> references) {
226
226
  OpenMagnetics::settings.set_coil_delimit_and_compact(true);
227
227
  OpenMagnetics::Inputs inputs(inputsJson);
228
228
 
@@ -237,7 +237,12 @@ json calculate_advised_magnetics_from_cache(json inputsJson, json filterFlowJson
237
237
  }
238
238
 
239
239
  OpenMagnetics::MagneticAdviser magneticAdviser;
240
- auto masMagnetics = magneticAdviser.get_advised_magnetic(inputs, OpenMagnetics::magneticsCache.get(), filterFlow, maximumNumberResults);
240
+ // `references` restricts the search to those cached parts -- one tool's family, or an
241
+ // admin-chosen pool, out of a cache several callers share. A reference the cache does not
242
+ // hold raises rather than silently searching fewer parts.
243
+ auto masMagnetics = references
244
+ ? magneticAdviser.get_advised_magnetic(inputs, OpenMagnetics::magneticsCache.subset(references.value()), filterFlow, maximumNumberResults)
245
+ : magneticAdviser.get_advised_magnetic(inputs, OpenMagnetics::magneticsCache.get(), filterFlow, maximumNumberResults);
241
246
 
242
247
  auto scoringsPerFilter = magneticAdviser.get_scorings();
243
248
 
@@ -507,6 +512,11 @@ void register_adviser_bindings(py::module& m) {
507
512
  filter_flow_json: JSON array of MagneticFilterOperation objects defining
508
513
  the filtering pipeline.
509
514
  max_results: Maximum number of recommendations to return.
515
+ references: Optional list of cached references (manufacturerInfo.reference) to
516
+ search instead of the whole cache. Raises
517
+ PyOpenMagnetics.EngineError naming any reference the cache does not
518
+ hold. The cache may hold datasheet-only parts (no core, no coil):
519
+ they are ranked on the filters that apply to them.
510
520
 
511
521
  Returns:
512
522
  JSON object with "data" array containing ranked results.
@@ -520,7 +530,7 @@ void register_adviser_bindings(py::module& m) {
520
530
  Cache must be populated before calling this function.
521
531
  Raises PyOpenMagnetics.EngineError if the cache is empty.
522
532
  )pbdoc",
523
- py::arg("inputs_json"), py::arg("filter_flow_json"), py::arg("max_results"),
533
+ py::arg("inputs_json"), py::arg("filter_flow_json"), py::arg("max_results"), py::arg("references") = py::none(),
524
534
  py::call_guard<py::gil_scoped_release>());
525
535
 
526
536
  m.def("calculate_manufacturability_report", &calculate_manufacturability_report,
@@ -12,7 +12,7 @@ json calculate_advised_magnetics(json inputsJson, int maximumNumberResults, json
12
12
  json calculate_advised_magnetics_with_filters(json inputsJson, json filterFlowJson, int maximumNumberResults, json coreModeJson);
13
13
  json calculate_advised_magnetics_fast(json inputsJson, int maximumNumberResults, json coreModeJson);
14
14
  json calculate_advised_magnetics_from_catalog(json inputsJson, json catalogJson, int maximumNumberResults);
15
- json calculate_advised_magnetics_from_cache(json inputsJson, json filterFlowJson, int maximumNumberResults);
15
+ json calculate_advised_magnetics_from_cache(json inputsJson, json filterFlowJson, int maximumNumberResults, std::optional<std::vector<std::string>> references = std::nullopt);
16
16
 
17
17
  // Design-for-manufacturing rule pack (ABT #1177, WP8)
18
18
  json calculate_manufacturability_report(json masJson);
@@ -403,6 +403,11 @@ double calculate_saturation_current(json magneticJson, double temperature) {
403
403
  return magnetic.calculate_saturation_current(temperature);
404
404
  }
405
405
 
406
+ std::optional<double> calculate_datasheet_inductance(json magneticJson, double dcBiasCurrent, double temperature) {
407
+ OpenMagnetics::Magnetic magnetic(magneticJson);
408
+ return magnetic.calculate_datasheet_inductance(dcBiasCurrent, temperature);
409
+ }
410
+
406
411
  double calculate_saturation_current_at_operating_point(
407
412
  json magneticJson, json operatingPointJson, double temperature) {
408
413
  OpenMagnetics::Magnetic magnetic(magneticJson);
@@ -1196,6 +1201,29 @@ void register_core_bindings(py::module& m) {
1196
1201
  py::arg("magnetic_json"), py::arg("temperature"),
1197
1202
  py::call_guard<py::gil_scoped_release>());
1198
1203
 
1204
+ m.def("calculate_datasheet_inductance", &calculate_datasheet_inductance,
1205
+ R"pbdoc(
1206
+ Inductance a catalogue part's DATASHEET gives at a DC bias and temperature.
1207
+
1208
+ Reads the measured L(I) points of the part's single-winding inductor entry
1209
+ (manufacturerInfo.datasheetInfo.electrical): linear in current along each measured
1210
+ temperature, linear between the two measured temperatures bracketing `temperature`,
1211
+ and the nearest measured temperature outside that range. Without L(I) points, the
1212
+ stated inductance. Works for datasheet-only parts (no core, no coil).
1213
+
1214
+ Args:
1215
+ magnetic_json: JSON Magnetic object carrying a datasheet.
1216
+ dc_bias_current: DC bias current in Amperes.
1217
+ temperature: Temperature in Celsius.
1218
+
1219
+ Returns:
1220
+ Inductance in Henries, or None when the bias lies beyond the measured curve.
1221
+ Raises PyOpenMagnetics.EngineError when the datasheet gives neither an inductance
1222
+ nor L(I) points.
1223
+ )pbdoc",
1224
+ py::arg("magnetic_json"), py::arg("dc_bias_current"), py::arg("temperature"),
1225
+ py::call_guard<py::gil_scoped_release>());
1226
+
1199
1227
  m.def("calculate_temperature_from_core_thermal_resistance", &calculate_temperature_from_core_thermal_resistance,
1200
1228
  R"pbdoc(
1201
1229
  Calculate core temperature from thermal resistance and losses.
@@ -38,6 +38,7 @@ json load_core_data(json coresJson);
38
38
  json get_core_temperature_dependant_parameters(json coreData, double temperature);
39
39
  double calculate_core_maximum_magnetic_energy(json coreDataJson, json operatingPointJson);
40
40
  double calculate_saturation_current(json magneticJson, double temperature);
41
+ std::optional<double> calculate_datasheet_inductance(json magneticJson, double dcBiasCurrent, double temperature);
41
42
  double calculate_peak_winding_current(json magneticJson, json operatingPointJson, int windingIndex);
42
43
  double calculate_temperature_from_core_thermal_resistance(json coreJson, double totalLosses);
43
44
 
@@ -0,0 +1,112 @@
1
+ """
2
+ A catalogue may hold parts known only by their datasheet: no core, no coil, just
3
+ manufacturerInfo.datasheetInfo, which MAS allows. They must load with expansion on, be ranked
4
+ by the cache adviser on the filters that apply to them (datasheet limits, the measured L(I),
5
+ the published body size), and come back in the results rather than be dropped.
6
+
7
+ `references` restricts a search to part of a cache several callers share.
8
+ """
9
+ import json
10
+
11
+ import pytest
12
+
13
+ import PyOpenMagnetics
14
+
15
+
16
+ def datasheet_part(reference, rated_current=3.0):
17
+ """A 10 uH single-winding inductor known only by its datasheet."""
18
+ return {
19
+ "manufacturerInfo": {
20
+ "name": "Test Maker",
21
+ "reference": reference,
22
+ "datasheetInfo": {
23
+ "electrical": [
24
+ {
25
+ "subtype": "inductor",
26
+ "inductance": {"nominal": 10e-6},
27
+ "inductancePoints": [
28
+ {"current": 0, "inductance": 10e-6, "temperature": 20},
29
+ {"current": 2, "inductance": 9e-6, "temperature": 20},
30
+ {"current": 4, "inductance": 6e-6, "temperature": 20},
31
+ ],
32
+ "ratedCurrents": [rated_current],
33
+ "saturationCurrents": [{"percentInductanceDrop": 30, "current": 4.0}],
34
+ }
35
+ ],
36
+ "mechanical": {"length": {"nominal": 5e-3}, "width": {"nominal": 5e-3}, "height": {"nominal": 3e-3}},
37
+ },
38
+ }
39
+ }
40
+
41
+
42
+ def buck_inputs():
43
+ """9 uH at 1 A DC with 0.4 A ripple, 1 MHz."""
44
+ inputs = {
45
+ "designRequirements": {"magnetizingInductance": {"minimum": 8e-6}, "turnsRatios": []},
46
+ "operatingPoints": [
47
+ {
48
+ "name": "op",
49
+ "conditions": {"ambientTemperature": 25},
50
+ "excitationsPerWinding": [
51
+ {"name": "w", "frequency": 1e6, "current": {"waveform": {"data": [0.8, 1.2, 0.8], "time": [0, 0.5e-6, 1e-6]}}}
52
+ ],
53
+ }
54
+ ],
55
+ }
56
+ return PyOpenMagnetics.process_inputs(inputs)
57
+
58
+
59
+ FLOW = [
60
+ {"filter": "Datasheet Limits", "invert": True, "log": False, "strictlyRequired": True, "weight": 1.0},
61
+ {"filter": "Magnetizing Inductance", "invert": True, "log": False, "strictlyRequired": False, "weight": 1.0},
62
+ {"filter": "Volume", "invert": True, "log": False, "strictlyRequired": False, "weight": 1.0},
63
+ {"filter": "Losses", "invert": True, "log": False, "strictlyRequired": False, "weight": 1.0},
64
+ ]
65
+
66
+
67
+ @pytest.fixture
68
+ def catalogue(tmp_path):
69
+ PyOpenMagnetics.clear_magnetic_cache()
70
+ path = tmp_path / "catalogue.ndjson"
71
+ parts = [datasheet_part("ROOMY", rated_current=5.0), datasheet_part("TIGHT", rated_current=1.3), datasheet_part("OTHER")]
72
+ path.write_text("\n".join(json.dumps(part) for part in parts) + "\n", encoding="utf-8")
73
+ PyOpenMagnetics.load_magnetics_from_file(str(path), True)
74
+ yield
75
+ PyOpenMagnetics.clear_magnetic_cache()
76
+
77
+
78
+ def references_of(result):
79
+ return [item["mas"]["magnetic"]["manufacturerInfo"]["reference"] for item in result["data"]]
80
+
81
+
82
+ def test_datasheet_only_parts_are_ranked_on_the_filters_that_apply(catalogue):
83
+ result = PyOpenMagnetics.calculate_advised_magnetics_from_cache(buck_inputs(), FLOW, 10)
84
+
85
+ assert set(references_of(result)) == {"ROOMY", "TIGHT", "OTHER"}
86
+ scores = result["data"][0]["scoringPerFilter"]
87
+ assert "MAGNETIZING_INDUCTANCE" in scores and "VOLUME" in scores
88
+ # Losses cannot judge a part with no construction: no score, never a stand-in.
89
+ assert "LOSSES" not in scores
90
+
91
+
92
+ def test_the_part_with_more_margin_to_its_ratings_ranks_first(catalogue):
93
+ flow = [dict(FLOW[0], strictlyRequired=False)]
94
+ result = PyOpenMagnetics.calculate_advised_magnetics_from_cache(buck_inputs(), flow, 10)
95
+ order = references_of(result)
96
+ assert order.index("ROOMY") < order.index("TIGHT")
97
+
98
+
99
+ def test_references_restrict_the_search(catalogue):
100
+ result = PyOpenMagnetics.calculate_advised_magnetics_from_cache(buck_inputs(), FLOW, 10, ["ROOMY", "TIGHT"])
101
+ assert set(references_of(result)) == {"ROOMY", "TIGHT"}
102
+
103
+
104
+ def test_an_unknown_reference_raises_instead_of_searching_less(catalogue):
105
+ with pytest.raises(Exception, match="not in the cache"):
106
+ PyOpenMagnetics.calculate_advised_magnetics_from_cache(buck_inputs(), FLOW, 10, ["ROOMY", "MISSING"])
107
+
108
+
109
+ def test_datasheet_inductance_at_a_bias():
110
+ part = datasheet_part("P")
111
+ assert PyOpenMagnetics.calculate_datasheet_inductance(part, 1.0, 20) == pytest.approx(9.5e-6)
112
+ assert PyOpenMagnetics.calculate_datasheet_inductance(part, 5.0, 20) is None