# -*- coding: utf-8 -*- """生成「涡激振荡仿真台」交互单页。 上半 = 可交互正演 (涡脱频率/锁频带/Scruton, 工程经验模型, 非 CFD); 下半 = 真实实测 (9 台秒级: 抗涡激动作标志 + 塔筒双向加速度), 已脱敏。""" import json, pathlib SRC = "/Users/yuanying/wind-analytics/outputs/_combined/safety_assessment.json" rows = json.load(open(SRC, encoding="utf-8"))["per_turbine"] # 脱敏: 场名 -> 甲/乙, 台号重编 fmap, out, n = {}, [], 0 for r in rows: f = r["farm"] if f not in fmap: fmap[f] = "甲场" if not fmap else "乙场" n += 1 out.append({"t": f"{fmap[f]} #{n}", "viv": r["抗涡激触发pct"], "stop": r["塔停机max"], "gen": r["塔发电p95"], "all": r["塔全窗max"], "chain": r["振动安全链跌pct"], "blade": r["三叶极差p99"], "sec": r["n_sec"]}) DATA = json.dumps(out, ensure_ascii=False) HTML = f''' 涡激实测核验
涡激实测核验VORTEX-INDUCED VIBRATION
离线运行 · 无需网络
配套:机理见「涡激共振模拟器」

零触发,怎么证明不是监测盲区

涡激振荡的机理与机型对比,看配套的涡激共振模拟器(十二款机型预设、三种机理可切换)。 本页只回答一个问题:某批机组的抗涡激动作一次都没触发,这到底是「真没事」还是「监测面根本没在工作」? 这是所有阴性结论都要过的一关。

② 实测 · 九台机组秒级回放 · 真实数据

这九台机组,抗涡激动作一次都没触发

数据来自两个风场共九台机组的秒级长窗,每台 43200 秒。机组本身带一个 「变桨执行抗涡激动作」的状态标志,加上塔筒驱动侧与非驱动侧的加速度通道。已脱敏:场名与台号均已重编。

抗涡激动作触发
—
九台全部为零
振动安全链跌落
—
九台全部为零
三叶桨距极差 p99
—
集距同步,无 1P 不平衡
零触发不等于没问题 —— 除非你能证明监测面是活的。 这正是本例最值得学的地方:塔筒加速度有量值、有分布,停机与发电两个工况分得开(见上图),说明通道是活的, 所以「零触发」是真的阴性结果。而同一份交付里,机组自带的在线模态特征通道(塔筒一阶、叶片不平衡、传动链扭振) 全部是 0 或占位值 —— 那才是死通道,不能拿来下任何结论。一活一死并排放在同一批数据里,这就是最好的教材。
③ 判据

要下「无共振」这个结论,得几条独立证据

证据本例实测它单独够不够
抗涡激动作标志0 % 触发不够 —— 得先证明这个标志位是活的
塔筒加速度(停机工况)0.11 – 0.43 m/s²关键 —— 有量值有分布,证明通道活
塔筒加速度(发电 p95)0.16 – 0.21 m/s²关键 —— 两工况可分,非死值
振动安全链0 % 跌落不够 —— 同上,需活性证据
变桨速度 p95(查 hunting)< 0.5 – 0.75 °/s旁证
三叶桨距极差(查 1P)0 °旁证 —— 集距机型本就同步
六条独立证据全部指向同一结论,且其中两条能证明监测面本身是活的,所以「无共振」这个阴性结论站得住。 少了活性证据那两条,剩下四个零就只是四个零。
观澜 · 涡激实测核验 · 实测数据已脱敏 · 离线单文件 · 机理见「涡激共振模拟器」
''' p = pathlib.Path("/Users/yuanying/guanlan-rudong-v2/outputs/rudong/windscada/_demo/sim/涡激实测核验.html") p.write_text(HTML, encoding="utf-8") print(f"written {p.name} {len(HTML)//1024} KB 台数={len(out)}") leaks={k:HTML.count(k) for k in ["庄源","新风","ZY0","XF0","中车","庄河"] if HTML.count(k)} print("标识残留:", leaks or "0 ✓")