牛顿拉夫逊法和PQ分解法的区别与联系是什么?求高人指点

牛顿拉夫逊法和PQ分解法的区别与联系是什么?求高人指点,第1张

1、60年代中期,基于导纳矩阵的牛顿—拉夫逊法。牛顿一拉夫逊法(简称牛顿法)是数学中解决非线性方程式的典型方法,有较好的收敛性。在解决电力系统潮流计算问题时,是以导纳矩阵为基础的,因此,只要我们能在迭代过程中尽可能保持方程式系数矩阵的稀疏性,就可以大大提高牛顿法潮流程序的效率。自从60年代中后期,在牛顿法中利用了最佳顺序消去法以后,牛顿法在收敛性、内存要求、速度方面都超过了阻抗法,成为60年代末期以后广泛采用的优秀方法。牛拉法的要点是把非线性方程式的求解过程变成反复地求解线性的修正方程式过程,即通常所称的逐次线性化过程。

2、70年代中期,PQ分解法。由于交流高压电网中输电线路等元件的R<<X,因此有功功率的变化主要决定于电压相位角的变化,而无功功率的变化则主要决定于电压模值的变化。这个特性反映在极坐标形式的牛顿法修正方程式的元素上,是N及J二个子块元素的数值相对于H、L二个子块的元素要小得多。

这个方法,根据电力系统的特点,抓住主要矛盾,对纯数学的牛顿法进行了改进,从而在内存容量及计算速度方面都大大向前迈进了一步。使一个32K内存容量的数字计算机可以计算1000个节点系统的潮流问题,此方法计算速度已能用于在线计算,作系统静态安全监视。目前,我国很多电力系统都采用了PQ分解法潮流程序。

3、在有些应用场合,对计算精度的要求不高,而对计算速度要求较高。如输电网规划初期,只需要考虑有功功率平衡的问题,而不需要考虑无功功率平衡和电压的问题,这时可以对潮流方程进行简化处理,用直流潮流进行计算。直流潮流方程是一个线性方程组,求解不需迭代,不存在收敛的问题;导纳矩阵是稀疏的,可利用稀疏技术进一步提高计算速度;当高压电网满足R<<X时时,计算误差通常在3%-10%之内,可满足对精度要求不高的场合。直流潮流不能计算节点的电压和无功功率潮流。

4、为满足不同的需求开发了各种潮流算法:动态潮流、保留非线性的潮流、最小化潮流计算法、自动调整潮流、最优潮流、交直流系统潮流、直流潮流、随机潮流、三相潮流,含有柔性元件的潮流,并行算法等。

在潮流计算程序中设这迭代次数上限是为了应对潮流发散的情况。

比如一个正确的潮流计算 一般用牛拉法是 迭代6次,PQ分解法是 迭代12次。若潮流出现发散情况,迭代到20次,dP和dQ仍然不能收敛到你要的精度(比如0.0001),此时我们判定潮流发散,若不设一个迭代上限,可想而知,程序会一直迭代下去,此时数值已完全失去意义。

潮流发散意味着计算失败,这可能由两个原因导致:1数据存在问题,初值不在收敛域以内;2程序本身问题,考虑不全面,有bug。

同时也可能产生两个现象,一种是 潮流直接发散,若干次迭代后,数值已经很离谱,此时数值肯定没有意义。还有一种是,雅克比矩阵接近病态,收敛极其缓慢(也可能是初值选取不当),此时适当的放大收敛次数限制,有一定可能得到收敛后的结果。

多编程序,多思考,希望对你有帮助!

//PQ 分解法源程序

#include "math.h"

#include "stdio.h"

#include "stdlib.h"

#define M 14 //预计支路数

#define N 14 //预计节点数

//

struct linestr //支路信息

{

int i,j //和该支路相连的两个节点

float r,x,g,b //该支路的参数,kb为非标准变比

float pij,qij,pji,qji //支路潮流—计算数据

}line[M]

struct pointstr //节点信息

{

int sign //节点类型,0—平衡节点,1—PQ节点,2—PV节点

float voltage,cta,p,q //节点电压幅值和相位角,节点注入有功、无功

}pointpri[N],pointaft[N] //pointpri用于存放节点的初始数据,pointaft用于存放计算后的节点数据

float G[N][N]={0},B[N][N]={0} //节点导纳阵

//

float B1[N][N]={0},B2[N][N]={0}//修正方程系数矩阵

float detp[N]={0},detct[N]={0},detq[N]={0},detv[N]={0}//依次放修正方程的修正量

float pn[N]={0},ctn[N]={0},qn[N]={0},vn[N]={0} //依次放修正量对应的节点号,即变量对应的节点号

int nline,npoint //准确的支路数和节点数

int npq,npv,nbal //PQ节点数、PV节点数、平衡节点数

void creat()

{

int i

npq=0npv=0nbal=0

printf("\n请输入总支路数:")scanf("%d",&nline)

for(i=1i<=nlinei++)

{

printf("请输入%d号支路数据:\n",i)

printf("和该支路相连的节点号i,j(请用逗号隔开):")scanf("%d,%d",&(line[i].i),&(line[i].j))

printf("该支路的电阻和电抗R,X(请用逗号隔开):")scanf("%f,%f",&(line[i].r),&(line[i].x))

printf("该支路的对地电导和电纳G,B(请用逗号隔开):")scanf("%f,%f",&(line[i].g),&(line[i].b))

line[i].pij=0line[i].qij=0line[i].pji=0line[i].qji=0

//形成节点导纳阵

G[line[i].i][line[i].j]=-line[i].r/((line[i].r*line[i].r+line[i].x*line[i].x))

G[line[i].j][line[i].i]=G[line[i].i][line[i].j]

B[line[i].i][line[i].j]=line[i].x/((line[i].r*line[i].r+line[i].x*line[i].x))

B[line[i].j][line[i].i]=B[line[i].i][line[i].j]

G[line[i].i][line[i].i]+=line[i].r/((line[i].r*line[i].r+line[i].x*line[i].x))

G[line[i].i][line[i].i]+=line[i].g

B[line[i].i][line[i].i]+=(-line[i].x)/((line[i].r*line[i].r+line[i].x*line[i].x))

B[line[i].i][line[i].i]+=line[i].b

G[line[i].j][line[i].j]+=line[i].r/(line[i].r*line[i].r+line[i].x*line[i].x)

G[line[i].j][line[i].j]+=line[i].g

B[line[i].j][line[i].j]+=(-line[i].x)/(line[i].r*line[i].r+line[i].x*line[i].x)

B[line[i].j][line[i].j]+=line[i].b

}

printf("\n请输入总节点数:")scanf("%d",&npoint)

for(i=1i<=npointi++)

{

printf("请输入节点%d的数据\n",i)

printf("选择节点类型(1-平衡节点,2-PQ节点,3-PV节点):")

scanf("%d",&(pointpri[i].sign))

if(pointpri[i].sign==1)

{

printf("请输入该节点的电压幅值和相位角(用逗号隔开):")

scanf("%f,%f",&(pointpri[i].voltage),&(pointpri[i].cta))

pointpri[i].p=0pointpri[i].q=0

nbal++

}

else if(pointpri[i].sign==2)

{

printf("请输入该节点的注入有功和无功(用逗号隔开):")

scanf("%f,%f",&(pointpri[i].p),&(pointpri[i].q))

pointpri[i].voltage=1pointpri[i].cta=0

npq++

}

else if(pointpri[i].sign==3)

{

printf("请输入该节点的有功注入和电压幅值(用逗号隔开):")

scanf("%f,%f",&(pointpri[i].p),&(pointpri[i].voltage))

pointpri[i].q=0pointpri[i].cta=0

npv++

}

else

{

printf("选择无效,请重新输入\n")

i--

}

if(nbal>1)

{

printf("出现多个平衡节点,请重新输入\n")

i--nbal--

}

}

}

void view()

{

int i,j

for(i=1i<=npointi++)

{

for(j=1j<=npointj++)

printf("%f+j%f ,",G[i][j],B[i][j])

printf("\n")

}

for(i=1i<=npointi++)

{

printf("节点%d参数:",i)

if(pointpri[i].sign==1)printf("平衡节点 v=%f,theta=%f\n",pointpri[i].voltage,pointpri[i].cta)

else if(pointpri[i].sign==2)printf("PQ节点 P=%f,Q=%f\n",pointpri[i].p,pointpri[i].q)

else printf("PV节点 P=%f,v=%f\n",pointpri[i].p,pointpri[i].voltage)

}

}

void modify()

{

}

void run()

{

int i,j,k,m,n

float E,e//E为题目所要求的迭代精度,由键盘输入,e为每一步迭代的实际计算精度,用以和E比较

int numPQ[N]//PQ节点号

int numPV[N]//PV节点号

int numBAL //平衡节点号

int np_th[N],nq_v[N]//迭代方程中的有功-电压相位角方程、无功-电压幅值方程分别对应的节点号

float B1_fac[N][N]={0},B2_fac[N][N]={0},a

j=1k=1m=1n=1

for(i=1i<=npointi++){B1_fac[i][i]=1B2_fac[i][i]=1}

for(i=1i<=npointi++)

{//将数据存入一个新的结构体数组,保证在迭代过程中即使数据有改变,仍能保留住原始数据

pointaft[i].sign=pointpri[i].sign

pointaft[i].voltage=pointpri[i].voltage

pointaft[i].cta=pointpri[i].cta

pointaft[i].p=pointpri[i].p

pointaft[i].q=pointpri[i].q

//统计PV节点和PQ节点序号,并存入临时数组

if(pointpri[i].sign==1)numBAL=i

else if(pointpri[i].sign==2){numPQ[j++]=inp_th[m++]=inq_v[n++]=i}

else {numPV[k++]=inp_th[m++]=i}

}

//形成有功-相位角的迭代方程系数矩阵B1

for(i=1i<=npoint-1i++)

for(j=1j<=npoint-1j++)

B1[i][j]=B[np_th[i]][np_th[j]]

//形成因子表

for(k=1k<=npoint-1k++)

for(i=k+1i<=npoint-1i++)

{ a=B1[i][k]

for(j=1j<=npoint-1j++)

{

B1[i][j]-=a*B1[k][j]/B1[k][k]

B1_fac[i][j]-=a*B1_fac[k][j]/B1[k][k]

}

}

//形成无功-电压幅值的迭代方程的系数矩阵B2

for(i=1i<=npqi++)

for(j=1j<=npqj++)

B2[i][j]=B[nq_v[i]][nq_v[j]]

//形成因子表

for(k=1k<=npqk++)

for(i=k+1i<=npqi++)

{ a=B2[i][k]

for(j=1j<=npqj++)

{

B2[i][j]-=a*B2[k][j]/B2[k][k]

B2_fac[i][j]-=a*B2_fac[k][j]/B2[k][k]

}

}

printf("请输入迭代精度:")scanf("%f",&E)

k=-1

do

{

e=0

k++

//有功迭代

//首先计算有功不平衡量

for(i=1i<=npoint-1i++)

{

detp[i]=pointaft[np_th[i]].p/pointaft[np_th[i]].voltage

for(j=1j<=npointj++)

detp[i]-=pointaft[j].voltage*(G[np_th[i]][j]*cos(pointaft[np_th[i]].cta-pointaft[j].cta)+B[np_th[i]][j]*sin(pointaft[np_th[i]].cta-pointaft[j].cta))

printf("%f,",detp[i])

}

for(i=1i<=npoint-1i++)

{

detct[i]=0

for(j=1j<=npoint-1j++)

detct[i]+=B1_fac[i][j]*detp[j]

}

for(i=npoint-1i>=1i--)

{

for(j=npoint-1j>ij--)

detct[i]-=B1[i][j]*detct[j]

detct[i]/=B1[i][i]

}

for(i=1i<=npoint-1i++)detct[i]/=(-pointaft[np_th[i]].voltage)//求出相位角的修正量

for(i=1i<=npoint-1i++){pointaft[np_th[i]].cta+=detct[i]e+=detct[i]*detct[i]}//修正角度,并计算精度

printf("第%d次迭代后的相位角:",k)

for(i=1i<=npointi++)printf("%f,",pointaft[i].cta)

printf("\n")

//无功迭代

//首先计算无功不平衡量

for(i=1i<=npqi++)

{

detq[i]=pointaft[nq_v[i]].q/pointaft[nq_v[i]].voltage

for(j=1j<=npointj++)

detq[i]-=pointaft[j].voltage*(G[nq_v[i]][j]*sin(pointaft[nq_v[i]].cta-pointaft[j].cta)-B[nq_v[i]][j]*cos(pointaft[nq_v[i]].cta-pointaft[j].cta))

printf("%f,",detq[i])

}

for(i=1i<=npqi++)

{

detv[i]=0

for(j=1j<=npqj++)

detv[i]+=B2_fac[i][j]*detq[j]

}

for(i=npqi>=1i--)

{

for(j=npqj>ij--)

detv[i]-=B2[i][j]*detv[j]

detv[i]/=B2[i][i]

}

for(i=1i<=npqi++)detv[i]/=(-1)//求出电压的修正量

for(i=1i<=npqi++){pointaft[nq_v[i]].voltage+=detv[i]e+=detv[i]*detv[i]}//修正电压

printf("第%d次迭代后的电压幅值为:",k)

for(i=1i<=npointi++)printf("%f,",pointaft[i].voltage)

printf("\n")

}while(e>E&&k<100)

//输出结果

printf("在满足精度E=%f的情况下,计算结果为:",E)

for(i=1i<=npointi++)

printf("v%d=%f,cta%d=%f\n",i,pointaft[i].voltage,i,pointaft[i].cta)

//计算平衡节点注入功率

pointaft[numBAL].p=0pointaft[numBAL].q=0

for(i=1i<=npointi++)

{

pointaft[numBAL].p+=pointaft[i].voltage*(G[numBAL][i]*cos(pointaft[numBAL].cta-pointaft[i].cta)+B[numBAL][i]*sin(pointaft[numBAL].cta-pointaft[i].cta))

pointaft[numBAL].q+=pointaft[i].voltage*(G[numBAL][i]*sin(pointaft[numBAL].cta-pointaft[i].cta)-B[numBAL][i]*cos(pointaft[numBAL].cta-pointaft[i].cta))

}

pointaft[numBAL].p*=pointaft[numBAL].voltage

pointaft[numBAL].q*=pointaft[numBAL].voltage

printf("平衡节点注入功率为:%f+j%f\n",pointaft[numBAL].p,pointaft[numBAL].q)

//计算各支路潮流

for(k=1k<=nlinek++)

{

float aa,bb,cc

i=line[k].ij=line[k].j

aa=pointaft[i].voltage*cos(pointaft[i].cta)-pointaft[j].voltage*cos(pointaft[j].cta)

bb=pointaft[i].voltage*sin(pointaft[i].cta)-pointaft[j].voltage*sin(pointaft[j].cta)

cc=line[k].r*line[k].r+line[k].x*line[k].x

line[k].pij=(line[k].r*(pointaft[i].voltage*cos(pointaft[i].cta)*aa+pointaft[i].voltage*sin(pointaft[i].cta*bb))-line[k].x*(pointaft[i].voltage*sin(pointaft[i].cta*aa-pointaft[i].voltage*cos(pointaft[i].cta)*bb)))/cc

line[k].qij=(line[k].x*(pointaft[i].voltage*cos(pointaft[i].cta)*aa+pointaft[i].voltage*sin(pointaft[i].cta*bb))+line[k].r*(pointaft[i].voltage*sin(pointaft[i].cta*aa-pointaft[i].voltage*cos(pointaft[i].cta)*bb)))/cc

line[k].pji=(line[k].r*(pointaft[j].voltage*cos(pointaft[j].cta)*(-aa)+pointaft[j].voltage*sin(pointaft[j].cta*(-bb)))-line[k].x*(pointaft[j].voltage*sin(pointaft[j].cta*(-aa)-pointaft[j].voltage*cos(pointaft[j].cta)*(-bb))))/cc

line[k].qji=(line[k].x*(pointaft[j].voltage*cos(pointaft[j].cta)*(-aa)+pointaft[j].voltage*sin(pointaft[j].cta*(-bb)))+line[k].r*(pointaft[j].voltage*sin(pointaft[j].cta*(-aa)-pointaft[j].voltage*cos(pointaft[j].cta)*(-bb))))/cc

printf("由节点%d流向节点%d的功率为:%f+j%f\n",i,j,line[k].pij,line[k].qij)

printf("由节点%d流向节点%d的功率为:%f+j%f\n",j,i,line[k].pji,line[k].qji)

}

}

main ()

{

int a

printf("\n")

printf("***************电力系统潮流计算**************\n")

printf("\n")

printf(" 设计者: 李 冰 设计:2014 年 5 月\n")

printf("\n")

printf("\n")

printf(" 注:各参数用标么值表示,角度均以弧度制表示\n")

printf("\n")

printf("\n")

do

{

printf("请选择:1-建立电网2-查看数据3-修改数据4-运行计算0-退出程序:")//由键盘输入选项

scanf("%d",&a)

if (a==0) //如果选中0,就表示退出程序

{

exit(0)

}

else if (a==1) //如果选中1,就跳去执行建立电网,即creat处

{

creat()

}

else if (a==2) //如果选中2,就跳去执行查看数据,即view处

{

view()

}

else if (a==3) //如果选中1,就跳去执行修改数据,即modify处

{

modify()

}

else if (a==4) //如果选中1,就跳去执行运行计算,即run处

{

run()

}

else //如果以上都不是,则表示无效输入,重新要求输入选择

{

printf("\n无效输入,请重新选择\n")

}

}while(1)

}

不知道能不能帮到你


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/11918426.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-19
下一篇 2023-05-19

发表评论

登录后才能评论

评论列表(0条)

保存