电力系统潮流计算课程设计Word格式.docx
《电力系统潮流计算课程设计Word格式.docx》由会员分享,可在线阅读,更多相关《电力系统潮流计算课程设计Word格式.docx(32页珍藏版)》请在冰豆网上搜索。
1.高斯-赛德尔迭代法
以导纳矩阵为基础,并应用高斯--塞德尔迭代的算法是在电力系统中最早得到应用的潮流计算方法,目前高斯一塞德尔法已很少使用。
将所求方程f(x)=0改写为x=ψ(x),不能直接得出方程的根,给一个猜测值x0得:
x1=ψ(x0),又可取x1为猜测值,进一步得:
优点:
(1)原理简单,程序设计十分容易。
(2)导纳矩阵是一个对称且高度稀疏的矩阵,因此占用内存非常节省。
(3)就每次迭代所需的计算量而言,是各种潮流算法中最小的,并且和网络所包含的节点数成正比关系。
缺点:
(1)收敛速度很慢。
(2)对病态条件系统,计算往往会发生收敛困难:
如节点间相位角差很大的重负荷系统、包含有负电抗支路(如某些三绕组变压器或线路串联电容等)的系统、具有较长的辐射形线路的系统、长线路与短线路接在同一节点上,而且长短线路的长度比值又很大的系统。
(3)平衡节点所在位置的不同选择,也会影响到收敛性能。
2.牛顿-拉夫逊法
牛顿法是数学中求解非线性方程式的典型方法,有较好的收敛性。
自从20世纪60年代中期采用了最佳顺序消去法以后,牛顿法在收敛性、内存要求、计算速度方面都超过了其他方法,成为直到目前仍被广泛采用的方法。
(1)收敛速度快,若选择到一个较好的初值,算法将具有平方收敛特性,一般迭代4—5次便可以收敛到一个非常精确的解。
而且其迭代次数与所计算网络的规模基本无关。
(2)具有良好的收敛可靠性,对于前面提到的对以节点导纳矩阵为基础的高斯一塞德尔法呈病态的系统,牛顿法均能可靠地收敛。
(3)牛顿法所需的内存量及每次迭代所需时间均较前述的高斯一塞德尔法为多,并与程序设计技巧有密切关系。
牛顿法的可靠收敛取决于有一个良好的启动初值。
如果初值选择不当,算法有可能根本不收敛或收敛到一个无法运行的解点上。
解决方法:
对于正常运行的系统,各节点电压一般均在额定值附近,偏移不会太大,并且各节点间的相位角差也不大,所以对各节点可以采用统一的电压初值(也称为“平直电压”),“平直电压”法假定:
这样一般能得到满意的结果。
但若系统因无功紧张或其它原因导致电压质量很差或有重载线路而节点间角差很大时,仍用上述初始电压就有可能出现问题。
可以先用高斯一塞德尔法迭代1-2次;
以此迭代结果作为牛顿法的初值,也可以先用直流法潮流求解一次以求得一个较好的角度初值,然后转入牛顿法迭代。
3.P-Q分解法
电力系统中常用的P-Q分解法派生于以极坐标表示的牛顿-拉夫逊法,其基本思想是把节点功率表示为电压向量的极坐标形式,以有功功率误差作为修正电压向量角度的依据,以无功功率误差作为修正电压幅值的依据,把有功和无功分开进行迭代其主要特点是以一个(n-1)阶和一个m阶不变的、对称的系数矩阵B,B代替原来的(n+m-1)阶变化的、不对称的系数矩阵M,以此提高计算速度,降低对计算机贮存容量的要求。
P-Q分解法在计算速度方面有显著的提高,迅速得到了推广。
本课程设计中不采用此方法,因此不再过多赘述。
三、程序设计
1.程序设计环境
(1)采用方法:
牛顿-拉夫逊法
(2)设计工具:
VC++6.0程序
(3)运行环境:
win864位操作系统
2.主程序清单
#include<
iostream.h>
conio.h>
math.h>
fstream.h>
string.h>
stdlib.h>
iomanip.h>
time.h>
constdoubleCalculateError=0.00001;
//定义计算收敛条件
staticintAllNodeNumber;
//节点总数
staticintBranchNumber;
//支路总数
staticintGroundNumber;
//接地支路总数
classBUS
{
public:
intOldNumber;
//旧的节点编号
intNodeType;
//节点类型(0-pq节点,2-pv节点,3-平衡节点)
doubleLoadP;
//负荷有功
doubleLoadQ;
//负荷无功
doubleGenP;
//发电机有功
doubleGenQ;
//发电机无功
doubleVoltageVal;
//电压幅值
doubleVoltageAngle;
//电压相角
doubleNodeP;
//节点净有功
doubleNodeQ;
//节点净无功
doubleNodeE;
//电压e分量
doubleNodeF;
//电压f分量
BUS():
OldNumber(0),NodeType(0),LoadP(0),LoadQ(0),GenP(0),GenQ(0),VoltageVal(1.0),VoltageAngle(0.0),NodeP(0.0),NodeQ(0.0),NodeE(1.0),NodeF(0.0){
}
};
classBRANCH
intNodeI;
//节点i侧
intNodeJ;
//节点j侧
intCircuit;
//判断是否是双回路(0单回路,1双回路)
doubleR;
//支路电阻
doubleX;
//支路电抗
doubleY;
//线路变压器变比或接地导纳B
BRANCH():
NodeI(0),NodeJ(0),Circuit
(1),R(0.0),X(0.0),Y(0.0){
classYii//存导纳矩阵对角元素
doubleG,B;
Yii():
G(0.0),B(0.0){}
classYij//存导纳矩阵非对角元素和列号
intj;
Yij():
G(0),B(0),j(0){
classGROUND//存接地支路数据
intNode;
doubleG;
doubleB;
classCURRENT//存支路电流
doubleE,F;
classPOWER//存支路功率
doubleP1,Q1;
doubleP2,Q2;
classPOWERFLOW
doublemaxerror;
char*FileName,*ResultName;
voidInputData();
//读入系统数据
voidTinny2();
//半动态节点优化编号
voidFormY();
//形成节点导纳矩阵
voidFormJ();
//形成雅克比矩阵(边形成边消去)
voidbranchpower();
//计算支路功率
voidoutputdata();
//输出潮流计算结果
ifstreaminput;
ofstreamoutput;
POWERFLOW();
~POWERFLOW();
private:
int*NewNumber;
//按新号顺序存旧号
int*OldNewNumber;
//按旧号顺序存新号
BUS*bus;
BRANCH*branch;
GROUND*ground;
CURRENT*I;
//迭代后计算的各支路的电流
POWER*power;
//各支路功率
doubleBaseS;
Yii*yii;
Yij*yij;
int*seq;
//导纳矩阵各行非对角元素首地址
int*sum;
//导纳矩阵各行非对角元素个数
double*a;
//电流分量
double*b;
double*groundpower;
//接地支路功率
intcount;
//记录迭代次数
POWERFLOW:
:
POWERFLOW()
FileName=NULL;
ResultName=NULL;
NewNumber=NULL;
bus=NULL;
branch=NULL;
ground=NULL;
BaseS=0;
count=0;
}
~POWERFLOW()
delete[]NewNumber;
delete[]OldNewNumber;
delete[]bus;
delete[]branch;
delete[]I;
delete[]power;
delete[]yii;
delete[]yij;
delete[]seq;
delete[]sum;
delete[]a;
delete[]b;
voidPOWERFLOW:
InputData()//读入数据
input.open(FileName,ios:
nocreate);
input>
>
BaseS;
if(!
input)
{
cout<
<
"
数据文件有问题!
请检查!
endl;
return;
AllNodeNumber;
bus=newBUS[AllNodeNumber];
for(inti=0;
i<
i++)
{
input>
bus[i].OldNumber>
bus[i].NodeType>
bus[i].LoadP>
bus[i].LoadQ
>
bus[i].GenP>
bus[i].GenQ>
bus[i].VoltageAngle>
bus[i].VoltageVal;
bus[i].NodeE=bus[i].VoltageVal*cos(bus[i].VoltageAngle*3.14159265/180);
bus[i].NodeF=bus[i].VoltageVal*sin(bus[i].VoltageAngle*3.14159265/180);
bus[i].NodeP=(bus[i].GenP-bus[i].LoadP)/BaseS;
bus[i].NodeQ=(bus[i].GenQ-bus[i].LoadQ)/BaseS;
BranchNumber;
branch=newBRANCH[BranchNumber];
for(i=0;
branch[i].NodeI>
branch[i].NodeJ>
branch[i].R>
branch[i].X>
branch[i].Y;
if(i==1)
branch[i].Circuit=0;
else
if((branch[i].NodeI==branch[i-1].NodeI)&
&
(branch[i].NodeJ==branch[i-1].NodeJ))
{
branch[i].Circuit=1;
branch[i-1].Circuit=1;
}
elsebranch[i].Circuit=0;
GroundNumber;
ground=newGROUND[GroundNumber];
for(i=0;
input>
ground[i].Node>
ground[i].G>
ground[i].B;
}
input.close();
Tinny2()//半动态节点优化编号
NewNumber=newint[AllNodeNumber+1];
int*ConnectNum=newint[AllNodeNumber+1];
int**NodeConnect=newint*[AllNodeNumber+1];
(AllNodeNumber+1);
NodeConnect[i]=newint[15];
for(i=1;
ConnectNum[i]=0;
ConnectNum[abs(branch[i].NodeI)]++;
ConnectNum[abs(branch[i].NodeJ)]++;
NodeConnect[abs(branch[i].NodeI)][ConnectNum[abs(branch[i].NodeI)]]=abs(branch[i].NodeJ);
NodeConnect[abs(branch[i].NodeJ)][ConnectNum[abs(branch[i].NodeJ)]]=abs(branch[i].NodeI);
if(branch[i].Circuit==1)
++i;
for(intz=1;
z<
z++)
NewNumber[z]=1;
for(i=1;
if(ConnectNum[NewNumber[z]]>
ConnectNum[i])
NewNumber[z]=i;
if(ConnectNum[NewNumber[z]]==1)
for(intj=1;
j<
(ConnectNum[NodeConnect[NewNumber[z]][1]]+1);
j++)
if(NodeConnect[NodeConnect[NewNumber[z]][1]][j]==NewNumber[z])
{
NodeConnect[NodeConnect[NewNumber[z]][1]][j]=NodeConnect[NodeConnect[NewNumber[z]][1]][ConnectNum[NodeConnect[NewNumber[z]][1]]];
}
ConnectNum[NodeConnect[NewNumber[z]][1]]--;
for(i=1;
(ConnectNum[NewNumber[z]]+1);
for(intj=1;
(ConnectNum[NodeConnect[NewNumber[z]][i]]+1);
if(NodeConnect[NodeConnect[NewNumber[z]][i]][j]==NewNumber[z])
NodeConnect[NodeConnect[NewNumber[z]][i]][j]=NodeConnect[NodeConnect[NewNumber[z]][i]][ConnectNum[NodeConnect[NewNumber[z]][i]]];
ConnectNum[NodeConnect[NewNumber[z]][i]]--;
}
(ConnectNum[NewNumber[z]]);
for(intk=i+1;
k<
k++)
for(intj=1;
{
if(NodeConnect[NewNumber[z]][k]!
=NodeConnect[NodeConnect[NewNumber[z]][i]][j])
continue;
elsebreak;
}
if(j==(ConnectNum[NodeConnect[NewNumber[z]][i]]+1))
ConnectNum[NodeConnect[NewNumber[z]][i]]++;
ConnectNum[NodeConnect[NewNumber[z]][k]]++;
NodeConnect[NodeConnect[NewNumber[z]][i]][ConnectNum[NodeConnect[NewNumber[z]][i]]]=NodeConnect[NewNumber[z]][k];
NodeConnect[NodeConnect[NewNumber[z]][k]][ConnectNum[NodeConnect[NewNumber[z]][k]]]=NodeConnect[NewNumber[z]][i];
ConnectNum[NewNumber[z]]=AllNodeNumber;
i++)//新号数组中对应的老号
cout<
NewNumber[i]<
"
;
OldNewNumber=newint[AllNodeNumber+1];
for(intj=1;
if(NewNumber[j]==i)
OldNewNumber[i]=j;
i++)//老号数组中对应的新号
OldNewNumber[i]<
delete[]ConnectNum;
for(i=0;
i<
i++)
delete[15]NodeConnect[i];
FormY()//形成导纳矩阵
intz=1;
yii=newYii[AllNodeNumber+1];
yij=newYij[BranchNumber+1];
seq=newint[AllNodeNumber+1];
sum=newint[AllNodeNumber];
for(intf=0;
f<
f++)
seq[f]=0;
sum[f]=0;
seq[AllNodeNumber]=0;
for(inti=1;
for(intj=0;
if((NewNumber[i]==abs(branch[j].NodeI))||(NewNumber[i]==abs(branch[j].NodeJ)))
if(OldNewNumber[abs(branch[j].NodeI)]<
i||OldNewNumber[abs(branch[j].NodeJ)]<
i)
continue;
doubleZ=branch[j].R*branch[j].R+branch[j].X*branch[j].X;
if(branch[j].NodeI<
0)
if(branch[j].Circuit==1)
doubleZ1=branch[j+1].R*branch[j+1].R+branch[j+1].X*branch[j+1].X;
yij[z].G=-branch[j].R/(Z*branch[j].Y)-branch[j+1].R/(Z1*branch[j+1].Y);
yij[z].B=branch[j].X/(Z*branch[j].Y)+branch[j+1].