简介:这份资料面向电力系统仿真方向的学习者与工程技术人员,聚焦PSS/E(Power System Simulation Engine)中用户自定义模型的开发方法,帮助读者理解如何用Fortran编写模型子程序并接入PSS/E完成特定仿真需求。内容围绕动态仿真计算的实现机制展开,涵盖MODE、KPAUSE、MSTATE、MIDTRM等标志位的含义,以及STRT等行为通过TBLCNC、CONEC、CONET等连接子程序调用模型子程序对应语句的过程;同时说明与机组相关模型的子程序书写格式SUBROUTINE modelname(MC,ISLOT),以及STRTIN数组位置表入口、CALL调用语句和地址自动分配规则,并给出模型库调用顺序与自定义模型逻辑书写步骤。资源包为1个doc文档,压缩后约27KB,篇幅精炼,适合作为查阅手册。目前已有677人学习,可帮助读者快速建立自定义模型的整体框架认识,理清标志位与调用流程,为后续编写和调试模型子程序提供参考。
1. PSSE自定义模型到底在解决什么问题
如果你在电力系统仿真岗待过一阵,大概率遇到过这种场景:调度侧给来一个新型储能电站的机电暂态模型,结构跟 PSSE 自带库里的任何一台机都对不上,控制框图里又是前馈又是死区又是变流器限幅,翻遍 POM 手册也找不到现成模块能拼出来。这时候只有两条路——要么用自带模块硬凑,精度对不上;要么写自定义模型,把微分方程和控制逻辑直接塞进 PSSE 的求解器里。PSSE 自定义模型学习资料要解决的,就是第二条路怎么走通的问题。
它面向的是做机电暂态仿真的工程师、做新能源并网建模的研究生,以及需要把厂家黑匣子模型落到 PSSE 里的系统分析人员。核心工具链是 PSSE 的 CONEC/CONET 子程序、FLAT 文件、以及 DYRE/DYR 动态数据记录。学它的价值在于:一旦掌握,你能把任意结构的控制系统写成 PSSE 能识别的模型,不再受自带库限制。代价是调试周期长,一个符号写错就可能让整个潮流不收敛,所以下面按“先立概念、再动手、最后排坑”的顺序讲。
2. 从 CONEC 到 CONET:自定义模型的骨架怎么搭
PSSE 自定义模型的本质,是让用户用 Fortran 写两个子程序,挂到 PSSE 的求解循环里。CONEC 负责在仿真初始化阶段读参数、算初值、分配状态变量;CONET 负责在每个积分步计算状态变量的导数和代数输出。两者通过一个公共的 IC 数组和状态变量数组通信。理解这个骨架,比背任何语法都重要。
2.1 CONEC 和 CONET 的分工与调用时机
CONEC 在动态仿真开始前被调用一次,主要做四件事:从 DYRE 记录里读入模型参数、根据潮流结果计算状态变量初值、检查参数合法性、把需要跨步传递的量存进公共块。CONET 则在每个时步被调用,输入是当前状态变量和母线电压,输出是状态变量导数和注入电流。
常见做法是先在纸上把控制框图拆成“状态方程 + 代数方程”两组。比如一个带一阶惯性的有功控制环,状态变量取积分器输出,CONET 里写DX(1) = (Kp*(PREF - P) - X(1))/T,输出PORD = X(1) + Kp*(PREF - P)。这里 X 是状态变量数组,DX 是导数数组,索引从 1 开始,不能越界。
参数传递靠 IC 数组。IC 的前几个位置被 PSSE 保留,用户参数一般从 IC(11) 往后放。在 DYRE 记录里按顺序填,CONEC 里按同样顺序读。顺序错一位,整个模型行为就变了,这是最常见的翻车点。
2.2 用 FLAT 文件定义模型参数和状态变量
FLAT 文件是 PSSE 自定义模型的“声明文件”,告诉 PSSE 这个模型有几个状态变量、几个参数、每个参数的默认值和上下限。没有 FLAT 文件,PSSE 不知道给 CONEC 传多少个数。
一个最小 FLAT 文件结构如下:
! FLAT file for a simple governor model ! IC array layout: ! IC(1-10) reserved by PSSE ! IC(11) = Kp proportional gain ! IC(12) = T time constant ! IC(13) = PMAX upper limit ! IC(14) = PMIN lower limit ! State variables: 1 (integrator output)对应在 CONEC 里读参数:
SUBROUTINE CONEC INCLUDE 'COMON4.INS' COMMON /MYMOD/ KP, T, PMAX, PMIN KP = IC(11) T = IC(12) PMAX = IC(13) PMIN = IC(14) ! 初值:假设初始有功为 P0,积分器输出初值取 P0 X(1) = P0 RETURN END逻辑说明:COMON4.INS是 PSSE 提供的公共块声明文件,必须包含。IC数组在 CONEC 入口时已经由 PSSE 从 DYRE 记录填好。X(1)是第一个状态变量的初值,这里直接取潮流算出的有功,保证仿真从稳态起步。参数说明:Kp 典型值 20~50,T 典型值 0.1~0.5 秒,PMAX/PMIN 按机组容量填,单位与 PSSE 内部一致(通常为 MW 或 pu,取决于母线基准)。
2.3 在 CONET 里写状态方程和输出方程
CONET 是真正干活的地方。每个时步,PSSE 把当前状态变量 X 和母线电压 V 传进来,你算出 DX 和注入电流。
SUBROUTINE CONET INCLUDE 'COMON4.INS' COMMON /MYMOD/ KP, T, PMAX, PMIN ! P 为当前有功,从 PSSE 公共块取 P = PELEC(1) ! 状态方程:一阶惯性 DX(1) = (KP*(PREF - P) - X(1))/T ! 输出方程:有功指令 PORD = X(1) + KP*(PREF - P) ! 限幅 IF (PORD .GT. PMAX) PORD = PMAX IF (PORD .LT. PMIN) PORD = PMIN ! 注入电流:这里简化处理,实际需按母线电压和功率计算 CURNT(1) = PORD/V(1) RETURN END逻辑说明:PELEC(1)是 PSSE 提供的当前有功输出,PREF是参考值,通常从 IC 数组或公共块取。DX(1)是状态变量导数,PSSE 用积分器推进。CURNT(1)是注入电流实部,虚部类似处理。参数说明:V(1)是母线电压实部,注意除零保护;PORD限幅后要同步更新注入电流,否则限幅不起作用。
注意:CONET 里不要做任何文件读写或屏幕输出,每个时步调用一次,I/O 会拖慢仿真几个数量级。
3. 把自定义模型挂进 PSSE 仿真的完整流程
写完 CONEC/CONET 只是第一步,真正让模型跑起来还需要编译、链接、配置 DYRE 记录、设置动态仿真参数。这一章按实际操作顺序走一遍。
3.1 编译链接:生成 PSSE 能加载的动态库
PSSE 在 Windows 下通常用 Intel Fortran 或 gfortran 编译。关键是把 PSSE 提供的库文件链接进去,否则找不到COMON4.INS里的符号。
# 以 gfortran 为例,假设 PSSE 安装目录为 C:\PSSE gfortran -c conec.f -I"C:\PSSE\PSSLIB" -o conec.o gfortran -c conet.f -I"C:\PSSE\PSSLIB" -o conet.o gfortran -shared -o mymodel.dll conec.o conet.o -L"C:\PSSE\PSSLIB" -lpsse逻辑说明:-I指定头文件路径,-L指定库路径,-lpsse链接 PSSE 主库。生成的mymodel.dll放到 PSSE 的PSSLIB目录或当前工作目录。参数说明:不同 PSSE 版本库名可能不同,常见有psse、psslib,以实际安装目录下的.lib文件为准。如果链接报 undefined symbol,多半是库名或路径不对。
3.2 DYRE 记录怎么写:参数顺序和单位
DYRE 记录是 PSSE 动态数据文件里的一行,格式为:母线名、机组 ID、模型名、参数 1、参数 2……参数顺序必须和 CONEC 里 IC 读取顺序完全一致。
! DYRE record example ! Bus ID Model Kp T PMAX PMIN 101 1 MYMOD 30.0 0.2 100.0 0.0逻辑说明:PSSE 读到MYMOD后,会去加载mymodel.dll,然后按顺序把 30.0、0.2、100.0、0.0 填入 IC(11) 到 IC(14)。参数说明:Kp 无量纲,T 单位秒,PMAX/PMIN 单位 MW。如果模型有多个状态变量,FLAT 文件里要声明清楚,否则 PSSE 分配的状态数组不够用,仿真会直接崩。
3.3 动态仿真设置:步长、积分方法和初值检查
PSSE 动态仿真常用步长 0.01 秒或 0.005 秒。步长太大,一阶惯性环节可能数值振荡;步长太小,仿真时间成倍增加。积分方法一般选隐式梯形法,对刚性系统更稳。
! 在 PSSE 动态仿真设置里 ! 步长:0.01 s ! 积分方法:Trapezoidal ! 仿真时长:10 s ! 故障:母线 101 在 1 s 时三相短路,1.1 s 清除逻辑说明:故障设置用来激发动态响应,观察自定义模型输出是否合理。参数说明:如果仿真在第一个步长就不收敛,先检查 CONEC 里初值是否和潮流一致;如果中途发散,检查 CONET 里是否有除零或限幅逻辑错误。
提示:每次改完 CONEC/CONET 重新编译后,PSSE 里要重新加载动态库,否则用的还是旧版本。这个坑我踩过不止一次。
4. 避坑与排查:自定义模型最常见的五类翻车
自定义模型调试周期长,大部分时间花在找错上。下面五条是按出现频率排的,每条按“现象 → 原因 → 解决”写。
4.1 仿真第一步就不收敛
现象:点开始仿真,立刻报“初始化失败”或“状态变量初值非法”。原因:CONEC 里算的初值和潮流结果对不上,或者状态变量初值超出物理范围。解决:在 CONEC 里把关键初值打印到日志文件(调试阶段临时加),和潮流结果逐项对比。常见是 P0 取错,或者积分器初值没按稳态条件算。
4.2 仿真中途发散,状态变量飙到无穷大
现象:前几秒正常,某个扰动后状态变量指数增长。原因:CONET 里状态方程符号写反,或者反馈极性搞错,形成正反馈。解决:把 CONET 里每个 DX 表达式单独拿出来,在纸上推一遍稳态条件,确认扰动消失后能回到平衡点。另一个常见原因是限幅逻辑没加,输出无限增大。
4.3 参数改了但仿真结果没变化
现象:改了 DYRE 里的 Kp,重新仿真,曲线一模一样。原因:PSSE 缓存了旧的动态库或旧的 DYRE 记录,没有重新加载。解决:确认编译后的 dll 时间戳是新的,PSSE 里重新读取动态数据文件,必要时重启 PSSE。另一个可能是参数顺序填错,改的那个位置根本没被 CONEC 读取。
4.4 多机系统中自定义模型之间互相干扰
现象:单机测试正常,多机系统里几台自定义模型机组行为异常。原因:公共块变量没有按机组区分,多个实例共用同一组变量。解决:PSSE 为每个机组实例分配独立的 IC 和 X 数组,但如果你在公共块里定义了全局变量,就会串。所有参数和状态变量必须通过 IC 和 X 传递,不要用自定义 COMMON 存跨步数据。
4.5 编译通过但 PSSE 加载时报“找不到入口点”
现象:dll 编译成功,PSSE 加载时报“无法定位程序输入点”。原因:函数名修饰问题。Fortran 编译后函数名可能变成conec_或CONEC@0,而 PSSE 期望的是CONEC。解决:在编译选项里加-fno-underscoring或使用!DEC$ ATTRIBUTES指令指定导出名。具体写法查所用编译器的文档,不同版本差异较大。
5. 进阶技巧:用验证用例反推模型正确性
自定义模型写完后,怎么证明它是对的?最可靠的办法是构造一个解析解已知的简单用例,把自定义模型和解析解对比。比如一阶惯性环节,给阶跃输入,输出应该是指数上升曲线,时间常数 T 处达到 63.2%。如果仿真曲线和解析解对不上,说明 CONET 里的积分逻辑有问题。
另一个技巧是“降阶验证”:把自定义模型参数设成极端值,让它退化成 PSSE 自带模型。比如把二阶环节的第二个时间常数设成 0.001 秒,行为应该接近一阶环节。如果退化后行为和自带模型一致,说明主体逻辑没问题,差异出在附加环节上。
我一般会在项目里建一个test_cases目录,每个自定义模型配一个最小测试系统,包含潮流文件、DYRE 文件、故障设置和预期曲线。每次改完代码,先跑测试用例,通过了再上实际系统。这个习惯帮我省了大量返工时间。
注意:验证用例的潮流文件要尽量简单,一台机、一条线、一个负荷就够。系统越简单,出问题时越容易定位。
最后一个具体技巧:在 CONET 里加一个计数器,每调用 1000 次往日志写一次当前状态变量值。这样仿真发散时,你能看到是哪个变量先失控,比看最终报错信息有用得多。日志文件在调试完成后记得关掉,否则长时间仿真会写满磁盘。
希望帮到你。
本文还有配套的精品资源,点击获取