verify_enable_thermal.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. """Verify the executor enable_thermal plumbing end-to-end on real Motor-CAD.
  2. Runs RobustMotorCADSolver with enable_thermal=True for a single point and
  3. checks that:
  4. 1. The EM and thermal solves both complete.
  5. 2. Thermal metrics are merged into the point result.
  6. 3. Thermal metric columns are written to scan_results.csv.
  7. Ambient temperature is overridden to 25 C in-memory (the MARS model ships an
  8. abnormal 125 C) so the temperature-rise / thermal-resistance metrics come out
  9. physically positive.
  10. Run with the venv python that has ansys-motorcad-core installed, e.g.:
  11. <venv>/Scripts/python.exe scripts/verify_enable_thermal.py
  12. All source is ASCII only.
  13. """
  14. from __future__ import annotations
  15. import os
  16. import sys
  17. import time
  18. from pathlib import Path
  19. _ROOT = Path(__file__).resolve().parent.parent
  20. sys.path.insert(0, str(_ROOT / "src"))
  21. sys.path.insert(0, str(_ROOT / "scripts"))
  22. from robust_motorcad import RobustMotorCADSolver # noqa: E402
  23. MODEL = str(_ROOT / "models" / "MARS-12S10P_SSSR_D76-C150_V5.0-0819.mot")
  24. THERMAL_KEYS = [
  25. "winding_temp_c", "winding_hotspot_temp_c", "magnet_temp_c",
  26. "stator_temp_c", "bearing_temp_c", "temp_rise_c",
  27. "thermal_resistance_k_w",
  28. ]
  29. def main(thermal_mode: str = "coupled") -> int:
  30. output_dir = str(_ROOT / "output" / (
  31. "verify_thermal_" + time.strftime("%Y%m%d_%H%M%S")
  32. ))
  33. solver = RobustMotorCADSolver(
  34. model_path=MODEL, output_dir=output_dir, ambient_temperature=25.0,
  35. thermal_mode=thermal_mode,
  36. )
  37. solver.connect()
  38. try:
  39. result = solver.run_single_point(
  40. {"RMSCurrent": 21.0, "Shaft_Speed": 5000.0},
  41. point_index=0, point_label="verify",
  42. )
  43. print("status: %s" % result["status"], flush=True)
  44. print("=== thermal metrics in point result ===", flush=True)
  45. for key in THERMAL_KEYS:
  46. print(" %s = %s" % (key, result.get("metrics", {}).get(key)),
  47. flush=True)
  48. csv_path = os.path.join(output_dir, "scan_results.csv")
  49. csv_ok = os.path.exists(csv_path)
  50. print("scan_results.csv exists: %s" % csv_ok, flush=True)
  51. thermal_in_csv = False
  52. if csv_ok:
  53. header = open(csv_path, encoding="utf-8").readline().rstrip()
  54. thermal_in_csv = all(k in header for k in THERMAL_KEYS)
  55. print("thermal columns present in CSV header: %s" % thermal_in_csv,
  56. flush=True)
  57. merged = all(
  58. key in result.get("metrics", {}) for key in THERMAL_KEYS
  59. )
  60. ok = (
  61. result["status"] == "OK" and merged and csv_ok and thermal_in_csv
  62. )
  63. print("")
  64. print("ENABLE_THERMAL END-TO-END: %s" % ("PASS" if ok else "FAIL"),
  65. flush=True)
  66. return 0 if ok else 1
  67. finally:
  68. solver.disconnect()
  69. if __name__ == "__main__":
  70. import argparse
  71. parser = argparse.ArgumentParser()
  72. parser.add_argument("--thermal-mode", choices=["off", "steady", "coupled"],
  73. default="coupled")
  74. args = parser.parse_args()
  75. sys.exit(main(thermal_mode=args.thermal_mode))