axial_probe2.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. # -*- coding: utf-8 -*-
  2. """
  3. 第3轮: 无求解快速图名筛查
  4. ==========================
  5. 原理: get_magnetic_graph_point 对"图名不存在"与"图存在但无结果/点号越界"
  6. 应返回不同报错文案。先用已知图名(TorqueVsAngle/FluxDensityAirgap)与伪名
  7. (Bogus_XYZ)标定两类文案, 再穷举前缀x后缀组合, 秒级筛出真实存在的轴向力图名。
  8. 命中后单次求解并读取全波形。
  9. 用法: python axial_probe2.py [--quit] [--no-solve]
  10. """
  11. import json
  12. import os
  13. import sys
  14. import time
  15. BASE = os.path.dirname(os.path.abspath(__file__))
  16. MOT_SRC = os.path.join(BASE, "MARS-12S10P_SSSR_D76-C150_V5.0-0819.mot")
  17. OUT_DIR = os.path.join(BASE, "output_motorcad")
  18. PREFIXES = ["", "OC", "OC_", "OC ", "OL", "OL_", "OL ", "Load", "Load_",
  19. "Load ", "OnLoad_", "OnLoad", "On Load ", "OpenCircuit_",
  20. "OpenCircuit", "Open Circuit ", "NoLoad_", "No Load ", "Th1_",
  21. "Th1", "1_", "Transient_", "Static_", "Rotor_", "Stator_"]
  22. SUFFIXES = ["Axial_Force_Rotor", "Axial_Force_Stator",
  23. "Axial Force Rotor", "Axial Force Stator"]
  24. EXTRA = ["Axial_Force", "Axial Force", "Axial Force (Rotor)",
  25. "Axial Force (Stator)", "AxialForceRotor", "AxialForceStator",
  26. "Axial_Force_Rotor_OL", "Axial_Force_Rotor_OC",
  27. "Axial_Force_Stator_OL", "Axial_Force_Stator_OC",
  28. "Fz_Rotor_OL_Lumped", "Fz_Stator_OL_Lumped",
  29. "Ft_Rotor_OL_Lumped", "Fr_Stator_OL_Lumped"]
  30. CONTROLS_GOOD = ["TorqueVsAngle", "FluxDensityAirgap"]
  31. CONTROLS_BAD = ["Bogus_XYZ_NotAGraph"]
  32. def err_of(mc, name):
  33. try:
  34. x, y = mc.get_magnetic_graph_point(name, 0)
  35. return ("OK", (x, y))
  36. except Exception as e:
  37. return ("ERR", str(e))
  38. def stats(ys):
  39. if not ys:
  40. return None
  41. return {"mean": sum(ys) / len(ys), "min": min(ys), "max": max(ys),
  42. "pk2pk": max(ys) - min(ys), "n": len(ys)}
  43. def read_graph(mc, name, maxpts=200):
  44. xs, ys = [], []
  45. for i in range(maxpts):
  46. try:
  47. x, y = mc.get_magnetic_graph_point(name, i)
  48. except Exception:
  49. break
  50. xs.append(x)
  51. ys.append(y)
  52. return xs, ys
  53. def main(argv):
  54. quit_after = "--quit" in argv
  55. no_solve = "--no-solve" in argv
  56. os.makedirs(OUT_DIR, exist_ok=True)
  57. ts = time.strftime("%m%d_%H%M%S")
  58. from ansys.motorcad.core import MotorCAD
  59. print("启动 Motor-CAD (前台) ...")
  60. mc = MotorCAD()
  61. results = {"when": ts, "probe_round": 3}
  62. try:
  63. mc.load_from_file(MOT_SRC)
  64. # ---- 标定两类报错文案 ----
  65. calib = {}
  66. for n in CONTROLS_GOOD + CONTROLS_BAD:
  67. calib[n] = err_of(mc, n)
  68. print(" 标定 %s -> %s" % (n, calib[n]))
  69. results["calibration"] = {k: list(v) for k, v in calib.items()}
  70. bad_msg = calib[CONTROLS_BAD[0]][1]
  71. # ---- 穷举筛查 (无求解, 快) ----
  72. cands = [p + s for p in PREFIXES for s in SUFFIXES] + EXTRA
  73. exists, not_exists, odd = [], [], {}
  74. for n in cands:
  75. kind, payload = err_of(mc, n)
  76. if kind == "OK":
  77. exists.append(n)
  78. elif payload == bad_msg:
  79. not_exists.append(n)
  80. else:
  81. odd[n] = payload # 报错文案不同于"不存在" => 图可能存在
  82. results["screen"] = {"exists_ok": exists, "odd_errors": odd,
  83. "n_not_exists": len(not_exists)}
  84. print("筛查: 直接OK %s; 异样报错 %s; 不存在 %d 个"
  85. % (exists, json.dumps(odd, ensure_ascii=False), len(not_exists)))
  86. promising = exists + list(odd.keys())
  87. if promising and not no_solve:
  88. for var in ["ElectromagneticForcesCalc_Load",
  89. "ElectromagneticForcesCalc_OC"]:
  90. mc.set_variable(var, True)
  91. print("有候选, 单次求解后读全波形 ...")
  92. t0 = time.time()
  93. mc.do_magnetic_calculation()
  94. print(" 耗时 %.1f s" % (time.time() - t0))
  95. waves = {}
  96. for n in promising + CONTROLS_GOOD:
  97. xs, ys = read_graph(mc, n)
  98. if ys:
  99. waves[n] = {"stats": stats(ys), "x": xs, "y": ys}
  100. print(" [波形] %s: %s" % (n, stats(ys)))
  101. results["waveforms"] = waves
  102. elif not promising:
  103. print("[如实] 全部候选均为'不存在', 需换思路 (数值ID枚举或GUI人工查图名)")
  104. res_path = os.path.join(OUT_DIR, "probe2_results_%s.json" % ts)
  105. with open(res_path, "w", encoding="utf-8") as f:
  106. json.dump(results, f, ensure_ascii=False, indent=2)
  107. print("RESULTS: %s" % res_path)
  108. return 0
  109. finally:
  110. if quit_after:
  111. try:
  112. mc.quit()
  113. except Exception:
  114. pass
  115. else:
  116. print("[提示] Motor-CAD 保持前台打开供检查。")
  117. if __name__ == "__main__":
  118. sys.exit(main(sys.argv[1:]))