简介:「风电场动态等值建模研究」面向电力系统分析、风电并网方向的科研人员与研究生,聚焦如何借助聚类分析把大规模风电场简化为少数代表性机组模型,从而降低仿真计算量、提升稳定性分析与优化调度效率。文档围绕K-means聚类展开,依次梳理数据收集、特征选择、聚类分组、等值模型建立、等值参数确定与模型验证的完整流程,并详解初始化、分配、更新、迭代与轮廓系数评估等算法环节,同时讨论非线性动力学、场站规模大、实时性要求高等难点,以及并网稳定性分析、功率预测与故障响应模拟等应用场景。压缩包内为1个docx文档,约11KB,轻量便于快速通读与二次整理,可用于课题入门、建模仿真参考或汇报提纲。目前已有100人学习,适合需要厘清等值建模思路、补齐聚类建模步骤的读者查阅。
1. 风电场动态等值建模在仿真链路里的真实位置
拿一个 200MW 的陆上风电场做例子:66 台 3MW 双馈机组,机端各挂一台箱变,35kV 集电线路走四回汇入升压站,再经主变接到 220kV 电网。要在 PSCAD 或 MATLAB/Simulink 里跑一次三相短路下的低电压穿越过程,若每台机组都按开关级详细模型搭,光机侧变流器桥臂就上百个,步长压到 20µs、仿真 10s,单次跑几个小时,工况扫描根本排不下。风电场动态等值建模要回答的就是:能不能把电气距离近、动态行为相似的机组合并成一台等值机,把集电网络折成一条等值阻抗,让并网点(PCC)的电压、有功、无功轨迹尽量贴着详细模型走。做并网特性校核、低电压穿越评估、场级调频调压策略验证的人,绕不开这一步。
2. 风电机组分群:特征向量怎么选才不丢动态
2.1 全场一台等值机什么时候会失真
尾流是第一个绕不过去的因素。一台 3MW 机组在 8m/s 来流下大概出力 1.6MW,上风向首排机组可能已经跑到 9m/s、接近 2.1MW,而第三排尾流区里的机组只有 6.5m/s、出力不足 1MW。这两种机组的转子转速、桨距角、机侧变流器占空比都不在一个工作点上,硬捏成一台等值机,聚合出来的风速约 7.5m/s,转子动能既不像首排也不像末排,故障期间转子转速的跌落轨迹就会明显偏。
第二个因素是集电距离。35kV 集电线路末端机端电压可能比首端低 2%~3%,稳态差别不大,但故障期间差别被放大:末端机端残压更低,撬棒(Crowbar)投入更早、持续时间更长。把不同残压水平的机组放在同一个群里,等值模型的撬棒动作时刻只能取一个折中值,PCC 的无功支撑曲线就对不上。
还有一种常见误判是把“同一型号”当成分群依据。同型号只说明本体参数相同,不说明运行状态相同。分群的依据应该是状态相似,不是铭牌一致。型号相同最多能让等值参数聚合的公式简单一点。
2.2 分群特征向量的优先级和取舍
实际工程里常用的特征量就那么几个,优先级和适用场景差别很大。
| 特征量 | 物理含义 | 适用场景 | 局限 |
|---|---|---|---|
| 风速 v | 决定运行点与出力水平 | 稳态分群首选,最直观 | 尾流区空间相关强,单点测风代表性差 |
| 桨距角 β | 区分部分负荷与限功率区 | 大风限功率工况必备 | 小风速段区分度低 |
| 转子转速 ω | 反映转子动能与变流器状态 | 故障暂态分群关键 | 需同步采样,实测数据难拿 |
| 机端电压 u | 反映电气距离与故障期降压深度 | 低电压穿越场景 | 稳态下几乎无区分度 |
一个实用的取舍是:做稳态并网校核,用风速 + 桨距角两维就够;做故障穿越校核,必须把转子转速和机端电压加进去。四维特征做 K-means 之前一定要标准化,否则风速的量纲(m/s,量级 10)会把电压(p.u.,量级 1)压死。
提示:风速数据最好取机舱风速仪 10 分钟均值再插值到仿真时刻,直接用瞬时风速做聚类,分群结果会在相邻时段来回跳。
2.3 用肘部法和轮廓系数确定分群数
分群数 K 靠拍脑袋定,是误差的第一大来源。常见做法是先用肘部法定上界,再用轮廓系数挑最终值。
import numpy as np import pandas as pd from sklearn.cluster import KMeans from sklearn.preprocessing import StandardScaler from sklearn.metrics import silhouette_score raw = pd.read_csv("wt_states.csv") # 字段:wt_id, v_wind, pitch_deg, rotor_rpm, u_pu, p_mw, s_mva # 四维特征:风速、桨距角、转速、机端电压 feat = raw[["v_wind", "pitch_deg", "rotor_rpm", "u_pu"]].values Xs = StandardScaler().fit_transform(feat) # 标准化,消除量纲差异 sse, sil = {}, {} for k in range(1, 9): km = KMeans(n_clusters=k, n_init=10, random_state=0) labels = km.fit_predict(Xs) sse[k] = km.inertia_ # 簇内平方和,画肘部曲线 if k >= 2: # 轮廓系数在 k=1 时无定义 sil[k] = silhouette_score(Xs, labels) print("SSE:", sse) print("Silhouette:", sil)n_init=10表示换 10 组初始质心各跑一次取最优,能躲开初值敏感导致的局部最优;random_state固定后结果可复现,做对比实验时别省这一项。看输出的方法很直接:SSE 曲线拐点之后每增加一个簇,下降幅度明显变缓的位置,就是候选 K;轮廓系数在 0.5 以上算结构清晰,0.3~0.5 属于可以接受。
2.4 分群结果除了指标还要看什么
轮廓系数好看不代表分群可用。拿到标签之后至少再核三件事:每个簇的容量占比,别出现一个簇只有两台机、另一个簇塞了五十台;每个簇内机端电压的极差,超过 0.03p.u. 就该拆;每个簇对应的集电馈线编号,跨三回以上馈线的簇,后面的网络化简误差会放大。
我一般会先把分群结果按容量排个序,容量占比低于 3% 的小簇要么并入最近的簇,要么单独保留为详细模型。这两台机在 PCC 上贡献的功率很小,但把它们塞进大簇会污染整个等值机的转速轨迹。
3. 集电网络化简与等值参数聚合的可执行流程
3.1 集电网络等值阻抗的折算口径
集电网给等值带来的误差常被低估。四回 35kV 馈线、每回十几台机组,树状结构要折成一个从 PCC 看出去的等值阻抗,工程上常用的口径是“功率损耗不变”,即让等值阻抗上的有功损耗等于原网络各支路损耗之和:
Z_eq = Σ(S_i² · Z_i) / (Σ S_i)²
其中 S_i 是流过第 i 段支路的功率,Z_i 是这段支路的复阻抗。这个式子成立的前提是先把树状馈线近似成从 PCC 出发的多条独立辐射支路;遇到环网或双回并列馈线,得先做星三角变换或者把环打开成辐射状再套公式。
import numpy as np def equiv_line_z(z_branch, s_branch): """按支路功率损耗不变折算集电网络等值阻抗。 z_branch: 各段支路复阻抗,单位 ohm s_branch: 各段支路流过的复功率,单位 MVA """ s_branch = np.asarray(s_branch, dtype=complex) z_branch = np.asarray(z_branch, dtype=complex) s_total = np.sum(np.abs(s_branch)) return np.sum(np.abs(s_branch) ** 2 * z_branch) / s_total ** 2 # 例:三段支路,阻抗递增,末段功率最小 z_seg = [0.12 + 0.35j, 0.09 + 0.27j, 0.05 + 0.15j] s_seg = [60, 40, 20] # MVA print(equiv_line_z(z_seg, s_seg))注意功率取模值再平方:复功率直接平方会得到复数平方,物理意义变了。折算出来的 Z_eq 通常明显小于首段阻抗,因为它按功率加权,功率最大的首段权重最高,这正是我们希望等值阻抗“等效于主要损耗路径”的原因。箱变阻抗别漏掉,型号相同时取 Z_T/n 与机组阻抗串起来一起折算。
3.2 机组本体参数的聚合口径
| 聚合对象 | 聚合公式 | 依据 |
|---|---|---|
| 等值容量 | S_eq = ΣS_i | 功率守恒 |
| 定子/转子阻抗 | Z_eq = 1/Σ(1/Z_i) | 并联,须先归算到同一容量基准 |
| 惯性时间常数 | H_eq = Σ(H_i·S_i)/ΣS_i | 转子动能守恒 |
| 轴系刚度与阻尼 | 按容量加权 | 归算到等值机容量 |
| 机侧/网侧变流器 PI 参数 | 容量加权近似 | 小信号一致,暂态需再校 |
最容易出错的是第二行。不同容量机组的标幺阻抗基准不同,直接套并联公式,得到的是纯数学上的并联值,物理上不成立。正确做法是先把每台机组的阻抗归算到各自的额定容量基准,再按容量加权求等效,最后再折算回等值机容量。
变流器 PI 参数用容量加权是近似,不是定理。多台机组的控制器并联之后,等值控制器的带宽会变化,如果原控制器带宽差异大,这个近似在暂态过程里会带来几十毫秒量级的相位误差。
3.3 分群与聚合的最小可跑流程
import numpy as np import pandas as pd from sklearn.cluster import KMeans from sklearn.preprocessing import StandardScaler raw = pd.read_csv("wt_states.csv") # 字段:wt_id, v_wind, pitch_deg, rotor_rpm, u_pu, s_mva, h_s, z_pu feat = raw[["v_wind", "pitch_deg", "rotor_rpm", "u_pu"]].values Xs = StandardScaler().fit_transform(feat) raw["grp"] = KMeans(n_clusters=3, n_init=10, random_state=0).fit_predict(Xs) def aggregate(g): s_sum = g["s_mva"].sum() # 等值容量 h_eq = (g["h_s"] * g["s_mva"]).sum() / s_sum # 容量加权惯性 z_base = g["z_pu"].values * g["s_mva"].values / s_sum # 先归算到等值机基准 z_eq = 1.0 / np.sum(1.0 / z_base) # 再按并联求等效 return pd.Series({"n": len(g), "s_eq": s_sum, "h_eq": h_eq, "z_eq": z_eq}) eq_params = raw.groupby("grp").apply(aggregate) print(eq_params)z_base这一行是关键:先做容量归算,再做并联。顺序颠倒会得到偏小的等值阻抗,故障期间等值机的短路电流偏大,PCC 电压跌落偏浅,误差会反着走。跑完打印的n列要顺手看一眼,出现过大的簇说明 K 偏小。
4. PCC 点轨迹校验:等值模型精度怎么量化
4.1 校验工况该怎么设计
只在稳态潮流的电压和功率上对得上,不能说明等值模型可用。常见的校核工况集至少包含三类:三相短路(含不同残压水平,比如 0.2、0.5、0.8p.u.)、阵风扰动(风速从 6m/s 阶跃到 12m/s)、以及频率支撑测试(系统频率阶跃 0.2Hz)。
每一类工况都要记录 PCC 的有功 P、无功 Q、电压幅值 U,必要时加上场站频率。采样时刻必须对齐,详细模型和等值模型用同一组输出时间点,别用各自的变步长输出直接相减。
注意:详细模型和等值模型的电气量测点要落在同一个节点上。等值模型里 PCC 就是并网点,但详细模型里 PCC 可能是升压站高压侧母线,中间差一台主变。测点错位会让所有误差指标都失真。
4.2 归一化均方根误差的算法实现
import numpy as np def nmrse(y_detail, y_equiv, base): """归一化均方根误差,返回百分数。 base 取详细模型稳态值,避免功率接近零时除零发散 """ y_detail = np.asarray(y_detail, dtype=float) y_equiv = np.asarray(y_equiv, dtype=float) if y_detail.shape != y_equiv.shape: raise ValueError("两条轨迹采样点必须对齐") err = y_equiv - y_detail return np.sqrt(np.mean((err / base) ** 2)) * 100.0 # 同一扰动下的两条曲线 e_p = nmrse(p_detail, p_equiv, base=p_detail.mean()) e_q = nmrse(q_detail, q_equiv, base=abs(q_detail).mean() + 1e-6) e_u = nmrse(u_detail, u_equiv, base=1.0) # 电压用 p.u.,基准取 1.0 print(f"P误差 {e_p:.2f}% Q误差 {e_q:.2f}% U误差 {e_u:.2f}%")有功基准取详细模型的稳态均值而不是额定容量,是为了让误差指标反映“相对这一工况的相对偏差”。无功稳态值可能接近零,所以加了 1e-6 的保护项。场级并网校核里,比较常见的判据是 PCC 有功和无功轨迹的归一化均方根误差控制在 5% 以内、电压控制在 0.01p.u. 以内,具体阈值要看接入系统的要求。
4.3 误差超标时先查什么
误差偏大先别急着加机群。按这个顺序排查命中率最高:先查网络等值,把集电网络的等值阻抗换成两段或三段等值,看误差是否明显下降;再查分群数,K 从 3 加到 5,看误差曲线的拐点;最后才动控制器参数,因为控制器聚合误差通常在暂态后半段才显现,如果误差在故障发生瞬间就超了,问题基本不在控制器上。
把误差按时间段拆开看也很有用。故障发生到切除这段时间的误差,主要由集电网络和分群决定;切除后恢复段的误差,更多来自转子动能(也就是 H_eq)和控制器带宽。两段分别定位,比只看一个总数快得多。
5. 多工况自适应等值:等值参数随运行点漂移时的补偿做法
一套等值参数只在标定工况附近可信。风速从 6m/s 涨到 12m/s,桨距角从 0° 走到 15°,变流器的等效带宽和转子等效惯性都会变,等值参数跟着漂。要覆盖全工况,常见做法是按风速区间标定多套等值参数,运行时按当前风速插值。
def blend(low, high, v, v_low, v_high): """在相邻两套标定参数之间做线性插值。 low/high: 两个风速区间的等值参数元组 (s_eq, h_eq, z_eq) """ if not (v_low <= v <= v_high): raise ValueError("运行点超出插值区间") w = (v - v_low) / (v_high - v_low) return tuple((1 - w) * a + w * b for a, b in zip(low, high)) # 6m/s 与 12m/s 两个标定点 p6 = (200.0, 5.1, 0.018) p12 = (200.0, 4.6, 0.021) print(blend(p6, p12, 9.0, 6.0, 12.0))插值区间不要拉太长。风速区间跨度超过 6m/s 时,等值阻抗的非线性会吃掉插值精度,这时候把区间切成三段更划算。
另一个方向是轨迹灵敏度校正。把误差较大的参数挑出来,逐个施加 ±5% 的扰动,看 PCC 有功轨迹的灵敏度大小,优先修正灵敏度高的参数。灵敏度低的参数怎么改都影响不大,不值得花时间。
| 场景 | 推荐做法 | 参数维护成本 |
|---|---|---|
| 稳态并网校核 | 单一等值参数,仅在额定附近标定 | 低 |
| 全风速段扫描 | 按 4m/s 一档切区间,各档独立标定 | 中 |
| 故障穿越评估 | 区间标定 + 轨迹灵敏度校正 | 高 |
| 实时仿真(RTDS 等) | 固定区间数,用查找表避免在线插值开销 | 中 |
最后说一个容易忽略的验证技巧:把详细模型在某工况下的 PCC 轨迹留出来不参与标定,用标定好的等值参数去跑,看误差是否落在标定工况的误差范围附近。如果验证工况的误差比标定工况高出两倍以上,说明区间边界切错了位置,把边界往误差峰值那边挪一档,插值残差从 3.1% 降到 1.4% 的那个位置,就是这套自适应参数该停下来的地方。
本文还有配套的精品资源,点击获取