# -*- coding: utf-8 -*- """ 第3轮: 无求解快速图名筛查 ========================== 原理: get_magnetic_graph_point 对"图名不存在"与"图存在但无结果/点号越界" 应返回不同报错文案。先用已知图名(TorqueVsAngle/FluxDensityAirgap)与伪名 (Bogus_XYZ)标定两类文案, 再穷举前缀x后缀组合, 秒级筛出真实存在的轴向力图名。 命中后单次求解并读取全波形。 用法: python axial_probe2.py [--quit] [--no-solve] """ import json import os import sys import time BASE = os.path.dirname(os.path.abspath(__file__)) MOT_SRC = os.path.join(BASE, "MARS-12S10P_SSSR_D76-C150_V5.0-0819.mot") OUT_DIR = os.path.join(BASE, "output_motorcad") PREFIXES = ["", "OC", "OC_", "OC ", "OL", "OL_", "OL ", "Load", "Load_", "Load ", "OnLoad_", "OnLoad", "On Load ", "OpenCircuit_", "OpenCircuit", "Open Circuit ", "NoLoad_", "No Load ", "Th1_", "Th1", "1_", "Transient_", "Static_", "Rotor_", "Stator_"] SUFFIXES = ["Axial_Force_Rotor", "Axial_Force_Stator", "Axial Force Rotor", "Axial Force Stator"] EXTRA = ["Axial_Force", "Axial Force", "Axial Force (Rotor)", "Axial Force (Stator)", "AxialForceRotor", "AxialForceStator", "Axial_Force_Rotor_OL", "Axial_Force_Rotor_OC", "Axial_Force_Stator_OL", "Axial_Force_Stator_OC", "Fz_Rotor_OL_Lumped", "Fz_Stator_OL_Lumped", "Ft_Rotor_OL_Lumped", "Fr_Stator_OL_Lumped"] CONTROLS_GOOD = ["TorqueVsAngle", "FluxDensityAirgap"] CONTROLS_BAD = ["Bogus_XYZ_NotAGraph"] def err_of(mc, name): try: x, y = mc.get_magnetic_graph_point(name, 0) return ("OK", (x, y)) except Exception as e: return ("ERR", str(e)) def stats(ys): if not ys: return None return {"mean": sum(ys) / len(ys), "min": min(ys), "max": max(ys), "pk2pk": max(ys) - min(ys), "n": len(ys)} def read_graph(mc, name, maxpts=200): xs, ys = [], [] for i in range(maxpts): try: x, y = mc.get_magnetic_graph_point(name, i) except Exception: break xs.append(x) ys.append(y) return xs, ys def main(argv): quit_after = "--quit" in argv no_solve = "--no-solve" in argv os.makedirs(OUT_DIR, exist_ok=True) ts = time.strftime("%m%d_%H%M%S") from ansys.motorcad.core import MotorCAD print("启动 Motor-CAD (前台) ...") mc = MotorCAD() results = {"when": ts, "probe_round": 3} try: mc.load_from_file(MOT_SRC) # ---- 标定两类报错文案 ---- calib = {} for n in CONTROLS_GOOD + CONTROLS_BAD: calib[n] = err_of(mc, n) print(" 标定 %s -> %s" % (n, calib[n])) results["calibration"] = {k: list(v) for k, v in calib.items()} bad_msg = calib[CONTROLS_BAD[0]][1] # ---- 穷举筛查 (无求解, 快) ---- cands = [p + s for p in PREFIXES for s in SUFFIXES] + EXTRA exists, not_exists, odd = [], [], {} for n in cands: kind, payload = err_of(mc, n) if kind == "OK": exists.append(n) elif payload == bad_msg: not_exists.append(n) else: odd[n] = payload # 报错文案不同于"不存在" => 图可能存在 results["screen"] = {"exists_ok": exists, "odd_errors": odd, "n_not_exists": len(not_exists)} print("筛查: 直接OK %s; 异样报错 %s; 不存在 %d 个" % (exists, json.dumps(odd, ensure_ascii=False), len(not_exists))) promising = exists + list(odd.keys()) if promising and not no_solve: for var in ["ElectromagneticForcesCalc_Load", "ElectromagneticForcesCalc_OC"]: mc.set_variable(var, True) print("有候选, 单次求解后读全波形 ...") t0 = time.time() mc.do_magnetic_calculation() print(" 耗时 %.1f s" % (time.time() - t0)) waves = {} for n in promising + CONTROLS_GOOD: xs, ys = read_graph(mc, n) if ys: waves[n] = {"stats": stats(ys), "x": xs, "y": ys} print(" [波形] %s: %s" % (n, stats(ys))) results["waveforms"] = waves elif not promising: print("[如实] 全部候选均为'不存在', 需换思路 (数值ID枚举或GUI人工查图名)") res_path = os.path.join(OUT_DIR, "probe2_results_%s.json" % ts) with open(res_path, "w", encoding="utf-8") as f: json.dump(results, f, ensure_ascii=False, indent=2) print("RESULTS: %s" % res_path) return 0 finally: if quit_after: try: mc.quit() except Exception: pass else: print("[提示] Motor-CAD 保持前台打开供检查。") if __name__ == "__main__": sys.exit(main(sys.argv[1:]))