马上加入,结交更多好友,共享更多资料,让你轻松玩转电力研学社区!
您需要 登录 才可以下载或查看,没有账号?立即加入
×
实验目的根据所给的电力系统,编制潮流计算程序,通过计算机进行调试,最后完成一个切实可行的电力系统计算应用程序。通过自己设计电力系统计算程序使同学对电力系统分析有进一步理解,同时加强计算机实际应用能力的训练。 程序计算原理1、概述应用计算机进行电力系统计算,首先要掌握电力系统相应计算的数学模型;其次是运用合理的计算方法;第三则是选择合适的计算机语言编制计算程序。 建立电力系统计算的相关数学模型,就是建立用于描述电力系统相应计算的有关参数间的相互关系的数学方程式。该数学模型的建立往往要突出问题的主要方面,即考虑影响问题的主要因素,而忽略一些次要因素,使数学模型既能正确地反映实际问题,又使计算不过于复杂。 运用合理的计算方法,就是要求所选用的计算方法能快速准确地得出正确结果,同时还应要求在解算过程中占用内存少,以利提高计算机的解题规模。 选择合适的语言编写程序,就是首先确定用什么计算机语言来编制程序;其次是作出计算的流程图;第三根据流程图用选择的语言编写计算程序。然后上机调试,直到语法上无错误。本程序采用C语言进行编程。 所编制的程序难免存在逻辑错误,因此先用一个已知结果的系统作为例题进行计算。用程序计算的结果和已知结果相比较,如果结果相差甚远就要逐步分析程序的计算步骤,查出问题的出处;如果结果比较接近,则逐步分析误差来源;直到结果正确为止。 2、电力系统潮流计算的程序算法潮流计算是电力系统分析中的一种最基本的计算,它的任务是对给定的运行条件确定系统的运行状态,如母线上的电压(幅值及相角)、网络中的功率分布及功率损耗等。 目前计算机潮流计算的方法主要有牛顿-拉夫逊算法和PQ分解法。牛顿-拉夫逊算法是数学上求解非线形方程组的有效方法,具有较好的收敛性,曾经是潮流计算中应用比较普遍的方法。PQ快速分解法是从牛顿-拉夫逊算法演变而来的,是将纯数学的牛顿-拉夫逊算法与电力系统具体特点相结合并进行简化与改进而得出的。PQ快速分解法比牛顿-拉夫逊算法大大提高了计算速度和节省了内存,故而本程序以PQ快速分解法进行潮流计算。 1)形成节点导纳矩阵(1)自导纳的形成对节点i其自导纳Yii是节点i以外的所有节点都接地时节点i对地的总导纳。显然,Yii应等于与节点i相接的各支路导纳之和,即file:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps5678.tmp.png 式中,yi0为节点i与零电位节点之间的支路导纳;yij为节点i与节点j之间的支路导纳。 (2)互导纳的形成对节点i与节点k之间的互导纳是节点i、k之间的支路导纳的负值,即file:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps5679.tmp.png 不难理解file:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps567A.tmp.png。若节点i和k没有支路直接相连时,便有Yik=0 (3)含变压器支路的处理若节点p、q间接有变压器,如下图所示,则可作出其∏型等值电路为: file:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps568A.tmp.png 图1 变压器∏型等值电路 则p、q的自导纳和节点间的互导纳分别为 file:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps568B.tmp.png 2)计算不平衡功率△P、△Q并形成修正方程式对每一个PQ节点或每一个PV节点都可以根据下列公式计算出有功功率增量△P file:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps568C.tmp.png 而对于每一个PQ节点还可以根据下面的公式计算出无功功率增量△Q file:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps568D.tmp.png 在有功功率增量和无功功率增量不满足如下约束条件时 file:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps568E.tmp.png 利用PQ分解法则可以形成如下修正方程 file:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps568F.tmp.png file:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps56A0.tmp.png 3)利用因子表法求解修正方程在电网计算中经常遇到这样的问题,对方程组需要反复多次求解,而每次求解仅改变常数项F,系数矩阵保持不变。按照一般的高斯消去法,对每一改变的常数项,形成包括常数项及系数矩阵在内的增广矩阵,然后消去回代求出其解。可以看出,每次对增广矩阵中A矩阵元素的消元都是重复的,为了避免这种重复,我们把对相同的系数矩阵重复进行的消去与对不同的常数项进行的消去分开进行,因此对系数矩阵的消去只需进行一次,并在消去的过程中将对常数项进行消去运算的运算因子保存下来,形成所谓因子表,这就是因子表法。因为因子表记录了高斯消去法对常数项进行消去的全部信息,利用它便可对不同常数项进行消去,形成上三角矩阵,最后求出全部未知数。 在使用PQ分解法时,其系数矩阵是在迭代过程中保持不变的,所以为了节省内存和缩短运算时间我们采取了因子表法。同时由于电网的节点导纳矩阵矩阵是稀疏阵和对称阵,于是我们可以采取只保存系数矩阵的上三角阵来使运算更为简化。 若线性方程组一般形式如下: file:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps56A1.tmp.png 其中file:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps56A2.tmp.png称为系数矩阵,file:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps56A3.tmp.png称为未知数向量, file:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps56A4.tmp.png称为常数项向量。将矩阵A的元素进行如下处理: file:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps56A5.tmp.png file:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps56B6.tmp.png 得到因子表 file:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps56B7.tmp.png 其中 file:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps56B8.tmp.png; 再利用因子表进行前代过程,求出每次迭代后的常数项。其前代公式是: file:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps56B9.tmp.png 求得向量file:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps56BA.tmp.png; 再由因子表与前代得到的向量F,得到方程组 file:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps56BB.tmp.png 求解出此方程即可得到线性方程组的解向量file:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps56BC.tmp.png。 4)多次迭代最终求得V和file:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps56CC.tmp.png以及全线路功率利用上面所介绍的方法求解修正方程组 file:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps56CD.tmp.png file:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps56CE.tmp.png 可以求得file:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps56CF.tmp.png和file:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps56D0.tmp.png。 再利用file:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps56D1.tmp.png求得每次迭代后的结果。多次迭代当其满足约束条件file:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps56D2.tmp.png和file:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps56E3.tmp.png时,迭代结束。迭代结束后即可得到各节点的V和file:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps56E4.tmp.png,再根据V、file:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps56E5.tmp.png来计算PV节点的无功功率Q和平衡节点的功率以及网络中的功率分布。 PV节点及平衡节点无功功率计算公式为: file:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps56E6.tmp.png 平衡节点有功功率计算公式为: file:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps56E7.tmp.png 以下图所标示的正方向,输电线路功率的计算公式如下: file:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps56E8.tmp.pngfile:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps56F8.tmp.png 图2 支路功率计算 对其进行实部虚部进行分解可得P、Q计算公式为: file:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps56F9.tmp.png 程序及说明1、主要变量说明1)结构体类型说明(1)节点功率结构体struct Nodetype { float P,Q; }; 其中,P为节点的有功功率,Q为无功功率。节点功率不区分负荷功率和发电机功率,其值为本节点连接的各支路输入功率及节点所接负荷、发电机功率之和,且规定功率流入节点为正,流出为负。详细说明参见下一章“算例及结果”的第二节“源数据格式说明”。 (2)线路参数结构体struct Linetype { float G,B,B0,k; }; 其中,G、B为线路的导纳和容纳;B0为线路的考虑变压器Π型等值电路后的对地充电容纳的一半Bc/2;k为折算到标准变压器支路后的变压器变比。详细说明参见下一章“算例及结果”的第二节“源数据格式说明”。 2)变量说明表2 程序主要变量说明 3、程序流程图file:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps56FA.tmp.png 图3 程序主流程图 file:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps56FB.tmp.png 图4 迭代部分流程图 4、程序代码/* FUNCTION : POWER FLOW */ /* WRITTEN BY : HUANG&YANG&TONG */ /* LAST EDITED : 2008-11-24 */ #include <stdio.h> #include <math.h> /*** 宏定义 ***/ #define eP 0.00001 #define eQ 0.00001 #define Y_(i,j) (*(*(Y+i)-i+j)) #define Yij (*(Yi+j)) #define Yji (*(*(Y+j)-j+i)) #define Pji Yji.G*cos(tmp)+Yji.B*sin(tmp) #define Pij Yij.G*cos(tmp)+Yij.B*sin(tmp) #define Qji Yji.G*sin(tmp)-Yji.B*cos(tmp) #define Qij Yij.G*sin(tmp)-Yij.B*cos(tmp) /*** 结构体变量定义 ***/ struct Nodetype /* 节点功率 */ { float P,Q; }; struct Linetype /* 线路类型 */ { float G,B,B0,k; }; /*** 子函数声明 ***/ void in_node(); /* 读节点功率 */ void in_line(); /* 读线路参数 */ void B_Form(); /* 生成BP、BQ矩阵 */ void factor(); /* 求因子表 */ void solve(float **B,float *X,int N); /* 解方程组 */ void PrtNode(); /*打印节点参数*/ void ErrorMsg(int Flag); /* 错误提示信息 */ /*** 全局变量声明 ***/ int Node; /*节点数*/ int *Num; /*保存原始节点序号*/ int NP,NQ=0; /*PV+PQ、PQ节点数*/ struct Nodetype *No; /*节点数据*/ struct Linetype **Y; /*线路参数*/ float **BP,**BQ; /*有功、无功简化雅克比矩阵B*/ float *V; /*节点电压有效值*/ float *Dlta; /*节点电压相角值*/ unsigned int count=0; /*迭代计数*/ int i,j,k,m; /*通用下标值*/ float tmp; /*临时数据暂存*/ char *Type; /*节点类型*/ FILE *in,*out; /*输入、输出文件指针*/ /****************** 主函数 ******************/ /**↓****↓****↓** 主函数 **↓****↓****↓**/ int main(void) { int kp=1,kq=1; /*P、Q精度判断:1-不满足,0-满足精度要求*/ float *dP,*dPi,*dQ,*dQi; /*ΔP、ΔQ*/ float Dltai; struct Linetype *Yi; struct Nodetype *Noi; float tP,tQ; if((in=fopen("Data.txt","r"))==NULL) ErrorMsg(1); if((out=fopen("out.txt","w"))==NULL) ErrorMsg(2); in_node(); /*读取节点参数并统计PQ、PV节点数*/ in_line(); /*读取线路参数并形成Y矩阵*/ B_Form(); /*形成B(BP&BQ)矩阵*/ factor(); /*求B因子式(仍保存于BP&BQ)*/ for(i=0;i<NQ;i++) *(V+i)=1; /*对PQ节点电压V赋初值*/ dP=(float *)malloc(sizeof(float)*NP); /*ΔP*/ dQ=dP; /*ΔQ*//*ΔP、ΔQ不同时存在,故而可共用空间*/ loop: /****开始迭代****/ if(kp==0&&kq==0) goto loopEnd; count++; /*迭代次数加一*/ if(count==65535) ErrorMsg(99); /*不收敛,退出*/ kp=0; for(i=0;i<NP;i++) { dPi=dP+i; Yi=*(Y+i)-i; Dltai=*(Dlta+i); *dPi=0; for(j=0;j<Node;j++) { tmp=Dltai-*(Dlta+j); /*tmp即δij*/ if(i>j) *dPi+=*(V+j)*(Pji); else *dPi+=*(V+j)*(Pij); } /*注意到Y矩阵为上三角矩阵,i>j时要交换下标*/ *dPi*=*(V+i); *dPi=(*(No+i)).P-*dPi; /*求得ΔPi*/ if(fabs(*dPi)>0x8fffffff) ErrorMsg(99); /*不收敛,退出*/ if(fabs(*dPi)>eP) kp=1; /*有不满足精度的ΔP即令kp=1*/ *dPi/=*(V+i); /*求得常数项ΔPi/Vi*/ } if(kp==0) goto loopQ; solve(BP,dP,NP); for(i=0;i<NP;i++) *(Dlta+i)+=(*(dP+i)/(*(V+i))); /*修正相角δ+=Δδ*/ loopQ: if(kp==0&&kq==0) goto loopEnd; kq=0; for(i=0;i<NQ;i++) { dQi=dQ+i; Yi=*(Y+i)-i; Dltai=*(Dlta+i); *dQi=0; for(j=0;j<Node;j++) { tmp=Dltai-*(Dlta+j); /*tmp即δij*/ if(i>j) *dQi+=*(V+j)*(Qji); else *dQi+=*(V+j)*(Qij); } /*注意到Y矩阵为上三角矩阵,i>j时要交换下标*/ *dQi*=*(V+i); *dQi=(*(No+i)).Q-*dQi; /*求得ΔQi*/ if(fabs(*dQi)>0x8fffffff) ErrorMsg(99); /*不收敛,退出*/ if(fabs(*dQi)>eQ) kq=1; /*有不满足精度的ΔQ即令kq=1*/ *dQi/=*(V+i); /*求得常数项ΔQi/Vi*/ } if(kq==0) goto loop; solve(BQ,dQ,NQ); for(i=0;i<NQ;i++) *(V+i)+=*(dQ+i); /*修正PQ节点电压V+=ΔV*/ goto loop; /*无功迭代,则必定需要下一轮回迭代判断*/ loopEnd: /****迭代结束****/ free(dP); /*释放内存空间*/ /****计算PV节点和平衡节点的无功功率Q****/ for(i=NQ;i<Node;i++) { Noi=No+i; Yi=*(Y+i)-i; Dltai=*(Dlta+i); for(j=0;j<Node;j++) { tmp=Dltai-*(Dlta+j); /*tmp即δij*/ if(i>j) (*Noi).Q+=*(V+j)*(Qji); else (*Noi).Q+=*(V+j)*(Qij); } /*注意到Y矩阵为上三角矩阵,i>j时要交换下标*/ (*Noi).Q*=*(V+i); } /****计算平衡节点的有功功率P****/ i=NP; Noi=No+i; Dltai=*(Dlta+i); for(j=0;j<Node;j++) { tmp=Dltai-*(Dlta+j); /*tmp即δij*/ (*Noi).P+=*(V+j)*(Pji); } /*注意到Y矩阵为上三角矩阵,i>j时要交换下标*/ (*Noi).P*=*(V+i); /****输出最终结果****/ fprintf(out,"\n\n【 潮流计算结果(节点) 】 ( 迭代次数k=%3d )\n",count-1); PrtNode(); /****计算全部线路功率****/ fprintf(out,"\n\n【 潮流计算结果(线路) 】\n"); fprintf(out," 线路 P Q\n"); for(k=0;k<Node;k++) { i=*(Num+k); Yi=*(Y+i)-i; Dltai=*(Dlta+i); Noi=No+i; for(m=0;m<Node;m++) { j=*(Num+m); if(j==i) continue; tmp=Dltai-*(Dlta+j); /*tmp即δij*/ if(j<i) { if(Yji.B==0) continue; /*若Bij=0,则节点i、j无直接联系*/ tP=*(V+j)*(Pji); tP=*(V+i)*Yji.G-tP; tP*=*(V+i); tQ=-*(V+j)*(Qji); tQ-=*(V+i)*(Yji.B-Yji.B0/Yji.k); tQ*=*(V+i); } else { if(Yij.B==0) continue; /*若Bij=0,则节点i、j无直接联系*/ tP=*(V+j)*(Pij); tP=*(V+i)*Yij.G-tP; tP*=*(V+i); tQ=-*(V+j)*(Qij); tQ-=*(V+i)*(Yij.B-Yij.B0); tQ*=*(V+i); } fprintf(out,"S[%d,%d]= (%10.6f,%10.6f)\n",k+1,m+1,-tP,-tQ); } } fclose(out); system("cmd /c start out.txt"); return(0); } /**↑****↑****↑** 主函数 **↑****↑****↑**/ /****************** 主函数 ******************/ /**************** 子函数:读节点数据 ****************/ void in_node() { struct Nodetype *Noi; /*临时变量*/ fscanf(in,"%d %d",&Node,&k);/*读取节点数Node*/ NP=Node-1; /*PV+PQ节点数,即非平衡节点数目*/ Num=(int *)malloc(sizeof(int)*Node); /*开Node个空间,每节点一个*/ V=(float *)malloc(sizeof(float)*Node); /*电压*/ Dlta=(float *)malloc(sizeof(float)*Node); /*电压相角*/ No=(struct Nodetype *)malloc(sizeof(struct Nodetype)*Node);/*节点功率*/ j=1; while(k!=0) /*若k=0,表明节点数据读取完毕*/ { switch(k) { case 1:k=NQ;NQ++;break; /*NQ统计PQ节点个数*/ case 2:k=NP-j;j++;break; /*从NP-1个空间倒着保存PV节点*/ case 3:k=NP;break; /*平衡节点*/ default:ErrorMsg(3); } Noi=No+k; fscanf(in,"%d %f %f %f %f",&i,&(*Noi).P,&(*Noi).Q,V+k,Dlta+k); i--; /*节点编号减一,以和程序表达方式兼容*/ *(Num+i)=k; /*第i个Num元素中存放i节点在No中的下标*/ fscanf(in,"%d",&k); /*读取节点类型*/ } if(NQ+j!=Node) ErrorMsg(4); /*检验节点数据个数是否够Node个*/ fprintf(out,"【 节点参数表 】\n"); PrtNode(); fprintf(out," 总节点:%d\n PQ节点:%d\n PV节点:%d\n",Node,NQ,NP-NQ); } /************ 子函数:读线路数据,并形成节点导纳矩阵Y ************/ void in_line() { struct Linetype *Yi; float R,X,k,B; m=sizeof(struct Linetype); Y=(struct Linetype **)malloc(m*Node); /*先开Node行,每一个节点一行*/ for(i=0;i<Node;i++) /*再在第i行上面开辟Node-i列*/ { /*即以上三角存储 Y 矩阵*/ *(Y+i)=(struct Linetype *)malloc(m*(Node-i)); Yi=*(Y+i)-i; for(j=i;j<Node;j++) {Yij.G=Yij.B=Yij.B0=Yij.k=0;} /*初始化*/ } while(feof(in)==0) /*文件指针到文件末*/ { fscanf(in,"%d %d %f %f %f %f",&i,&j,&R,&X,&k,&B); i--;j--; i=*(Num+i); /*转换节点号为该节点在程序中的储存编号*/ j=*(Num+j); (*(*(Y+i))).B+=B; /* 将对地充电导纳累加到自导纳 */ (*(*(Y+j))).B+=B; if(k!=1.0) { X*=k;R=0; tmp=(1-k)/X; (*(*(Y+i))).B+=tmp; /*将变压器的对地充电容纳累加到自导纳*/ (*(*(Y+j))).B+=-(tmp/k); B=tmp; k=-k; } if(i>j) {tmp=i;i=j;j=tmp;k=1/k;B*=k;} Yi=*(Y+i)-i; /* 以Yi代替*(Y+i)-i,简化表达式并避免重复计算 */ Yij.B0=B; /*保存ij0、ji0对地充电电容到Bij0*/ Yij.k=k; /*且有B0ji=B0ij/k*/ tmp=R*R+X*X; R/=tmp; X/=tmp; Yij.G=-R; /* 生成互导纳 */ Yij.B=X; (*(*(Y+i))).G+=R; /* 将线路互导纳累加到自导纳 */ (*(*(Y+i))).B+=-X; (*(*(Y+j))).G+=R; (*(*(Y+j))).B+=-X; } fclose(in); fprintf(out,"\n【 节点导纳矩阵 Y 】\n"); for(k=0;k<Node;k++) { i=k; i=*(Num+i); /*查取第i节点在程序中存储序号*/ for(j=0;j<k;j++) fprintf(out,"\t\t\t"); for(m=k;m<Node;m++) { j=*(Num+m); /*查取第j节点在程序中存储序号*/ if(i<j) fprintf(out,"(%10.6f,%10.6f) ",Y_(i,j).G,Y_(i,j).B); else fprintf(out,"(%10.6f,%10.6f) ",Y_(j,i).G,Y_(j,i).B); } fprintf(out,"\n"); } } /**************** 子函数:生成BP、BQ矩阵 ****************/ void B_Form() { float *BPi,*BQi; struct Linetype *Yi; int size=sizeof(float); BP=(float **)malloc(size*NP); /*以上三角存储*/ for(i=0;i<NP;i++) *(BP+i)=(float *)malloc(size*(NP-i)); for(i=0;i<NP;i++) { BPi=*(BP+i)-i; /* 以BPi代替*(BP+i)-i,避免重复计算 */ Yi=*(Y+i)-i; for(j=i;j<NP;j++) *(BPi+j)=Yij.B; /*(BPi+j)即相当于BP[j]*/ } BQ=BP; /* BP包含BQ,BP左上角的NQ*NQ子阵即BQ */ } /**************** 子函数:求因子表 ****************/ void factor() { float *BPi,*BPk,*BQi; for(i=0;i<NP;i++) { BPi=*(BP+i)-i; for(k=0;k<i;k++) { BPk=*(BP+k)-k; tmp=(*(BPk+i))/(*(BPk+k)); for(j=i;j<NP;j++) (*(BPi+j))-=tmp*(*(BPk+j)); } *(BPi+i)=1/(*(BPi+i)); for(j=i+1;j<NP;j++) *(BPi+j)*=*(BPi+i); } } /**************** 子函数:解方程组 ****************/ void solve(float **B,float *X,int N) { float *Bi,*Xi; for(i=0;i<N;i++) *(X+i)=-*(X+i);/*对常数项取负*/ /****对常数列进行前代****/ for(i=0;i<N;i++) { Bi=*(B+i)-i; Xi=X+i; for(j=i+1;j<N;j++) *(X+j)-=*(Bi+j)**Xi; *Xi*=*(Bi+i); } /****回代以求解方程组****/ for(i=N-1;i>=0;i--) { Bi=*(B+i)-i; Xi=X+i; for(j=N-1;j>i;j--) *Xi-=*(Bi+j)**(X+j); } } /****打印节点参数****/ void PrtNode() { struct Nodetype *Noi; fprintf(out,"节点 类型 P Q V δ\n"); for(i=0;i<Node;) { j=*(Num+i); /*查取第i节点在程序中存储序号*/ Noi=No+j; if(j<NQ) Type="PQ"; else Type="PV"; if(j==NP) Type="BS"; fprintf(out,"%3d %s %10.6f %10.6f %10.6f %10.6f\n", ++i,Type,(*Noi).P,(*Noi).Q,*(V+j),*(Dlta+j)/0.017453); } } /**************** 子函数:错误信息 ****************/ void ErrorMsg(int Flag) { switch(Flag) { case 1:printf("\n\tError(1): Failed to Open File \"Data.txt\"!");break; case 2:printf("\n\tError(2): Failed to Creat File \"out.txt\"!");break; case 3:printf("\n\tError(3): Node Data Error, Please Check!");break; case 4:printf("\n\tError(4): Lack Node Data, Please Check!");break; case 99:printf("k=%d\n\tError(99): It's Emanative!",count);break; } getch(); fclose(out); exit(Flag); } 算例及结果1、原始数据程序编写过程中,采用了《电力系统分析》教材的4节点、IEEE9节点参数进行了验证。本说明书中仅列出4节点验算过程。 4节点测试数据来源于参考文献中的《电力系统分析》(下册)第61页例11-5,用于检验程序正确性的参考计算结果见67页。对其基本情况总结如下。 1)网络连接图file:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps570C.tmp.jpg 图6 算例电力系统网络图 2)节点参数表4 算例节点参数表 3)线路参数表5 算例线路参数表 4)数据文件data.txtfile:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps571D.tmp.png 图7 数据文件格式 2、源数据格式说明源数据有功功率、无功功率、电压、阻抗、感抗、对地充电容纳均以标幺值表示。 数据文件必须命名为data.txt且与潮流计算程序放置于同一个文件中。数据文件data.txt包含两类参数:节点参数和线路参数。节点数据块与线路数据块之间用数字0作为间隔,即在节点数据块结束后,另起一行输入0,然后再在后面按格式要求录入线路参数 1)节点参数节点参数包括:系统节点数Node、节点功率(有功P、无功Q),节点电压(有效值V、相角Delta) 参数组织格式: (1)节点数Node节点数Node写在参数文件的开头,如:4表明为四节点系统。 (2)功率和电压P/Q/V/Delta首先给出节点参数示例: 2 3 0.5 0 1.10 0 第一列数字2表明该节点的类型为2-PV节点;第二列数字3表明该行数据为节点3的参数;后面三列依次为P、Q、V的给定值,给定值为0,表明该项参数未知;第六列为相角δ,非平衡节点的δ即为PQ迭代的初始相角值,平衡节点的即为给定的相角值。 节点功率为各支路输入功率之和,且规定功率流入节点为正,流出为负。故而负荷功率为负值,发电机功率为正值。 (3)节点类型的判断根据节点的给定参数可以将节点分为三种类型: 1)PQ节点:给定P、Q初始值的节点,用数字代码1表示; 2)PV节点:给定P、V初始值的节点,用数字代码2表示; 3)平衡节点:没有给定P、Q初始值,仅给定V的初始值,用数字代码3表示; 节点本身不分先后,不必刻意按编号大小来列写各节点,只需将每一个节点的参数按格式列写即可。 2)线路参数线路参数包括:线路阻抗(R,X)、变压器变比k和对地充电(接地支路)容纳b。每一条线路包括节点号在内共有6个参数,6个参数缺一不可。 (1)线路阻抗Z首先给出线路参数示例: 1 4 0.12 0.5 1 0.01920 前两列代表线路两端的节点编号,亦即线路编号14(即41);第三四列代表线路阻抗Z=0.12+j0.5;第五列为变压器变比k;最后一列为线路的对地充电电容的一半,即B/2。 k不为0。当k=1则表明该支路为普通支路;否则该支路为变压器支路。普通支路没有任何特殊要求,但对于变压器支路,有以下注意事项。 (2)变压器支路首先给出变压器线路示例: 3 1 0 0.3 0.909091 0 1)变比k为转换为变压器支路的标准等值电路(如下图)后的变比。 file:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps571E.tmp.png 图8 变压器∏型等值电路 2)变压器线路的编号31有特定含义:3对应节点p,1对应节点q。即变压器支路的编号对节点顺序有要求,p节点编号在前,q节点在后。 3)q节点为全系统参考电压侧。 程序智能化读取线路数据,用户无需刻意对线路参数进行归类、排序,可随意输入,只要每行数据都各自符合格式要求即可。 3、计算结果file:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps571F.tmp.jpg file:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps572F.tmp.jpg file:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps5730.tmp.jpg file:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps5731.tmp.jpg file:///C:\Users\LUNWEN~1\AppData\Local\Temp\ksohtml\wps5742.tmp.jpg 4、输出数据说明(1)节点参数表节点参数表实际上只是对源数据的重现,用于对源数据的整理以及检验程序是否成功读取原始数据。 其中,节点类型列中,BS代表平衡节点、PQ代表PQ节点、PV代表PV节点。 参数表后紧随的是对各类节点数目的统计结果。 该表属于对原始数据的基本统计处理。 (2)节点导纳矩阵节点导纳矩阵以上三角方式按照节点编号顺序输出,括号内部逗号前为导纳Gij、逗号后为容纳Bij。下三角部分可由上三角部分对称得到。 (3)潮流计算结果(节点)该部分计算结果包含PQ迭代次数k和节点参数计算结果。 迭代次数k在65535次以内均可正常显示。一般PQ迭代不会达到这个数值,否则可以认为PQ迭代是发散的。 节点参数计算结果表,展示了PQ迭代收敛时的计算结果,包括非平衡节点的电压相角δ、PQ节点的电压V、PV节点的无功功率Q和平衡节点的功率。 (4)潮流计算结果(线路)线路功率计算结果表,展示了PQ迭代收敛时的线路功率计算结果S,包括线路有功功率P和无功功率Q。程序按节点编号顺序仅输出了实际存在的线路或变压器支路上的功率。 课设心得参考文献1、何仰赞,温增银. 电力系统分析(上、下册)(第三版). 武汉:华中科技大学出版社,2002 2、周全仁,张清益. 电网计算与程序设计. 长沙:湖南科学技术出版社,1983 3、杨健霑. C语言程序设计. 武汉:武汉大学出版社,2006 0 `" R1 I: M- D( J! p
|