| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- # -*- coding: utf-8 -*-
- """
- 对标 V3.0 解析报告的 FEA 验证扫描
- ==================================
- 参照《轴向磁通电机轴向磁拉力计算与轴承选型校核报告V3.0-20260826.pdf》:
- - 其基准: 磁钢 20°C, 空载 Fz=483 N (中值口径 500 N)
- - 其表3-3: g=0.6/1.0/1.5 mm -> 601/483/378 N, kneg(1mm)=250 N/mm
- 本模型 .mot 磁钢温度默认 100°C (Br -0.12%/K), 首先归一到 20°C 再扫气隙。
- 工况: 磁钢 20°C x 气隙 {0.6, 1.0, 1.5} mm, 各求解一次, 读 OC/OL 净轴向力
- 及气隙磁密; 有限差分求磁负刚度 kneg。
- 用法: python axial_compare.py [--quit]
- """
- 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")
- GAPS = [0.6, 1.0, 1.5]
- MAGNET_TEMP_C = 20.0
- MAX_TSTEPS = 64
- MAX_NODES = 40
- 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_nodes(mc, graph, sec, tstep):
- xs, ys = [], []
- for i in range(MAX_NODES):
- try:
- x, y = mc.get_magnetic_3d_graph_point(graph, sec, i, tstep)
- except Exception:
- break
- xs.append(x)
- ys.append(y)
- return xs, ys
- def net_force_series(mc, graph):
- series = []
- for tstep in range(MAX_TSTEPS):
- total, got = 0.0, False
- for sec in (1, 2):
- xs, ys = read_nodes(mc, graph, sec, tstep)
- if not ys:
- continue
- got = True
- nu = len(ys) - 1 if (len(xs) > 1 and
- abs(xs[-1] - xs[0] - 360.0) < 1e-6) else len(ys)
- total += sum(ys[:nu])
- if not got:
- break
- series.append(total)
- return series
- def read_2d(mc, graph, maxpts=64):
- ys = []
- for i in range(maxpts):
- try:
- _, y = mc.get_magnetic_graph_point(graph, i)
- except Exception:
- break
- ys.append(y)
- return ys
- def main(argv):
- quit_after = "--quit" 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()
- try:
- mc.set_visible(True) # /SCRIPTING 模式部分机器窗口不显示, 强制可见
- except Exception:
- pass
- results = {"when": ts, "magnet_temp_C": MAGNET_TEMP_C,
- "reference": "V3.0 报告表3-1/3-3: 20°C, g=0.6/1.0/1.5 -> "
- "601/483/378 N, kneg(1mm)=250 N/mm",
- "cases": []}
- try:
- mc.load_from_file(MOT_SRC)
- out_mot = os.path.join(OUT_DIR, "MARS_SSSR_compare_%s.mot" % ts)
- mc.save_to_file(out_mot)
- results["work_mot"] = out_mot
- t_before = mc.get_variable("Magnet_Temperature")
- results["magnet_temp_before_C"] = t_before
- mc.set_variable("Magnet_Temperature", MAGNET_TEMP_C)
- print("磁钢温度: %s -> %s °C" % (t_before, MAGNET_TEMP_C))
- for var in ["ElectromagneticForcesCalc_Load",
- "ElectromagneticForcesCalc_OC"]:
- mc.set_variable(var, True)
- for g in GAPS:
- mc.set_variable("Airgap", g)
- back = mc.get_variable("Airgap")
- print("== 气隙 %.1f mm (回读 %s), 求解 ..." % (g, back))
- t0 = time.time()
- mc.do_magnetic_calculation()
- dt = time.time() - t0
- case = {"airgap_mm": back, "solve_seconds": dt}
- for graph, key in [("Fr_Rotor_OC_Lumped", "F_OC"),
- ("Fr_Rotor_OL_Lumped", "F_OL")]:
- s = net_force_series(mc, graph)
- case[key] = stats(s)
- bys = read_2d(mc, "FluxDensityAirgap")
- if bys:
- case["B2_mean_T2"] = sum(b * b for b in bys) / len(bys)
- print(" F_OC=%.1f N, F_OL=%.1f N, mean(B²)=%.3f (耗时 %.0fs)"
- % (case["F_OC"]["mean"], case["F_OL"]["mean"],
- case.get("B2_mean_T2", -1), dt))
- results["cases"].append(case)
- # ---- 磁负刚度 (有限差分, OC 口径) ----
- cs = results["cases"]
- if len(cs) == 3:
- f = [c["F_OC"]["mean"] for c in cs]
- g0, g1, g2 = [c["airgap_mm"] for c in cs]
- k_low = -(f[1] - f[0]) / (g1 - g0) # 0.6~1.0 段
- k_high = -(f[2] - f[1]) / (g2 - g1) # 1.0~1.5 段
- k_mid = -(f[2] - f[0]) / (g2 - g0) # 全段中心差分
- results["kneg_N_per_mm"] = {"seg_0.6_1.0": k_low,
- "seg_1.0_1.5": k_high,
- "central_at_1.0": k_mid}
- print("kneg: 0.6~1.0段 %.0f, 1.0~1.5段 %.0f, 中心差分 %.0f N/mm "
- "(报告解析值 250)" % (k_low, k_high, k_mid))
- res_path = os.path.join(OUT_DIR, "compare_results_%s.json" % ts)
- with open(res_path, "w", encoding="utf-8") as fjson:
- json.dump(results, fjson, 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:]))
|