📄 pf30.cpp
字号:
//多平衡节点+普通PQ分解
#include "fstream.h"
#include "math.h"
#include "stdlib.h"
#include "iomanip.h"
#include "time.h"
#define LINEMAX 5000 //最大线路数
#define GENERATORMAX 500 //最大发电机数
#define LOADMAX 2000 //最大负荷数
#define NODEMAX 2000 //最大节点数
#define SWINGMAX 20 //最大平衡节点数
#define PVMAX 500 //最大PV节点数
#define NODEFACTOR 10 //导纳矩阵中非零非对角元素的个数相对于
//最大节点数(NODEMAX)的倍数.
#define Deg_to_Rad 0.017453292 //度到弧度的转换系数
#define Rad_to_Deg 57.29577951 //弧度到度的转换系数
#define SinglePai 3.14159265 //圆周率
#define DoublePai 6.2831853 //两倍的圆周率
struct Line //线路参数结构定义
{
int Node_No[2]; //线路两端节点名(号):0-左节点;1-右节点
int Flag; //线路类型标志:0-普通支路;1、2-变压器支路。其中,
//1-非标准变比在左侧节点,2-非标准变比在右侧节点。
//对接地支路,左右节点名(号)相同。
double RXBK[3]; //0-R;1-X;2-Bc/2 或 K
}LLine[LINEMAX];
struct Generator //发电机参数结构定义
{
int Node_No; //发电机节点名(号)
int Flag; //发电机节点类型标志:0-平衡节点;1-PQ节点;2-PV节点
double PQV[2]; //对平衡节点,0-V,1-Angle;对PQ节点,0-P,1-Q;对PV节
//点,0-P,1-V。
}GGen[GENERATORMAX];
struct Load //负荷参数结构定义
{
int Node_No; //负荷节点名(号)
int Flag; //负荷节点静特性标志:0-不计静特性;1-计静特性。
double ABC[6]; //PL=a1*V**V+b1*V+c1,QL=a2*V*V+b2*V+c2。
//0-a1;1-a2;2-b1;3-b2;4-c1;5-c2。
}LLoad[LOADMAX];
int Node_Name_NewtoOld[NODEMAX];//新节点名(号)-->旧节点名(号)
int Node_Flag[NODEMAX]; //节点类型标志:0-平衡,1-PQ,2-PV
int Line_NodeName[LINEMAX][2]; //线路的左、右节点新名(号)
int Line_No_NewtoOld[LINEMAX]; //新线路号-->旧线路号
int Line_Flag[LINEMAX]; //新线路的类型标志:0,1,2说明同Line结构
int Gen_NodeName[GENERATORMAX]; //发电机节点的新节点名(号)
int Gen_No_NewtoOld[GENERATORMAX]; //新发电机顺序号-->旧发电机顺序号
int Gen_SWNode[SWINGMAX][2]; //平衡节点数据:0-新节点名(号);
//1-对应的旧发电机顺序号
int Gen_PVNode[PVMAX][2]; //发电机PV节点数据:0-新节点名(号);
//1-对应的旧发电机顺序号
int Gen_PQNode[GENERATORMAX][2];//发电机PQ节点数据:0-新节点名(号);
//1-对应的旧发电机顺序号
int Load_NodeName[LOADMAX]; //负荷节点的新节点名(号)
int Load_No_NewtoOld[LOADMAX]; //新负荷顺序号-->旧负荷顺序号
//读数据子程
void Data_Input(int &Num_Line,int &Num_Gen,int &Num_Load,double &Eps,
int &Iter_Max,int &VolIni_Flag,int &VolRes_Flag)
{
int i,j;
// 从键盘读数据文件名
char argv[20];
cout<<"Please input diskette data-file name:"<<endl;
cin.getline(argv,sizeof(argv));
// 打开数据文件
ifstream infile(argv);
if(infile.fail())
{
cerr<<"Error opening the diskette data-file:"<<argv<<endl;
exit(0);
}
else
{
//读记数器变量值
infile>>Num_Line>>Num_Gen>>Num_Load>>Eps>>Iter_Max\
>>VolIni_Flag>>VolRes_Flag;
/* cout<<setw(5)<<Num_Line<<setw(5)<<Num_Gen\
<<setw(5)<<Num_Load<<setw(10)<<Eps\
<<Iter_Max<<VolIni_Flag<<VolRes_Flag<<endl; */
if(Num_Line>LINEMAX)
{
cout<<"Lines Number > LINEMAX!"<<endl; exit(0);
}
if(Num_Gen>GENERATORMAX)
{
cout<<"Generators Number > GENERATORMAX!"<<endl;
exit(1);
}
if(Num_Load>LOADMAX)
{
cout<<"Loads Number > LOADMAX!"<<endl; exit(2);
}
//读线路参数
for(i=0;i<Num_Line;i++)
{
infile>>LLine[i].Node_No[0]>>LLine[i].Node_No[1]\
>>LLine[i].Flag;
for(j=0;j<3;j++)infile>>LLine[i].RXBK[j];
/* cout<<setw(5)<<LLine[i].Node_No[0]\
<<setw(5)<<LLine[i].Node_No[1]\
<<setw(5)<<LLine[i].Flag;
cout<<setw(10)<<LLine[i].RXBK[0]\
<<setw(10)<<LLine[i].RXBK[1]\
<<setw(10)<<LLine[i].RXBK[2]<<endl; */
}
//读发电机参数
for(i=0;i<Num_Gen;i++)
{
infile>>GGen[i].Node_No>>GGen[i].Flag>>GGen[i].PQV[0]\
>>GGen[i].PQV[1];
/* cout<<setw(5)<<GGen[i].Node_No\
<<setw(5)<<GGen[i].Flag\
<<setw(10)<<GGen[i].PQV[0]\
<<setw(10)<<GGen[i].PQV[1]<<endl; */
}
//读负荷参数
for(i=0;i<Num_Load;i++)
{
infile>>LLoad[i].Node_No>>LLoad[i].Flag;
for(j=0;j<6;j++)infile>>LLoad[i].ABC[j];
/* cout<<setw(5)<<LLoad[i].Node_No<<setw(5)<<LLoad[i].Flag;
for(j=0;j<6;j++)cout<<setw(10)<<LLoad[i].ABC[j];
cout<<endl; */
}
}
infile.close();
}
//序号处理子程
void Node_Sequen(int &Num_Node,int Num_Line,int Num_Gen,int Num_Load,
int &Num_Swing,int &Num_GPV,int &Num_GPQ)
{
int i,j,Flag,temp,np;
int Node_Name[NODEMAX][2]; //0-节点名(号);1-节点出线数
//统计各节点的出线数
for (i=0;i<NODEMAX;i++)Node_Name[i][1]=0; //节点出线数初始化为0
for(i=0;i<Num_Line;i++)
{
if(LLine[i].Node_No[0]==LLine[i].Node_No[1])
continue; //接地支路(左右节点相同)不在出线统计之内
Flag=0; //左节点出线数分析开始
for(j=0;j<Num_Node;j++)
{
if(LLine[i].Node_No[0]==Node_Name[j][0])//该节点已经在节点
{ //数组中出现,只需
Node_Name[j][1]++; //出线数加1。
Flag=1;
};
if(Flag==1)break;
}
if(Flag==0) //该节点还没在
{ //节点数组中出
Node_Name[Num_Node][0]=LLine[i].Node_No[0]; //现,需将该节
Node_Name[Num_Node][1]++; //点名(号)添加
Num_Node++; //到节点数组中,
if(Num_Node>NODEMAX) //然后该节点的
{ //出线数加1,并
cout<<"Nodes Number > NODEMAX!"<<endl; //将节点数也加
exit(4); //1。
}
}
Flag=0; //右节点出线数分析开始
for(j=0;j<Num_Node;j++)
{
if(LLine[i].Node_No[1]==Node_Name[j][0])//该节点已经在节点
{ //数组中出现,只需
Node_Name[j][1]++; //出线数加1
Flag=1;
};
if(Flag==1)break;
}
if(Flag==0) //该节点还没在
{ //节点数组中出
Node_Name[Num_Node][0]=LLine[i].Node_No[1]; //现,需将该节
Node_Name[Num_Node][1]++; //点名(号)添加
Num_Node++; //到节点数组中,
if(Num_Node>NODEMAX) //然后该节点的
{ //出线数加1,并
cout<<"Nodes Number > NODEMAX!"<<endl; //将节点数也加
exit(5); //1。
}
}
}
//节点出线数统计完毕,屏幕输出。其中,Num_Node为总节点数。
/* cout<<endl<<"Node: Number, Name and out-line number"<<endl;
for(i=0;i<Num_Node;i++)cout<<setw(5)<<i<<setw(5)<<Node_Name[i][0]\
<<setw(5)<<Node_Name[i][1]<<endl;*/
//根据出线数由小到大的顺序对节点进行排序(冒泡算法)
for(i=0;i<Num_Node-1;i++)
{
np=i;
for(int j=i+1;j<Num_Node;j++)
if(Node_Name[np][1]>Node_Name[j][1])np=j;
temp=Node_Name[i][0];
Node_Name[i][0]=Node_Name[np][0];
Node_Name[np][0]=temp;
temp=Node_Name[i][1];
Node_Name[i][1]=Node_Name[np][1];
Node_Name[np][1]=temp;
}
/* cout<<endl<<"Node Sequence: Number, Name and out-line number"<<endl;
for(i=0;i<Num_Node;i++)cout<<setw(5)<<i<<setw(5)<<Node_Name[i][0]\
<<setw(5)<<Node_Name[i][1]<<endl;*/
//平衡节点统计:总数及各节点的名(号)
int Node_Name_Swing[SWINGMAX];
for(i=0;i<Num_Gen;i++)
{
if(GGen[i].Flag==0)
{
Node_Name_Swing[Num_Swing]=GGen[i].Node_No;
Num_Swing++;
if(Num_Swing>SWINGMAX)
{
cout<<"Swinging Generators Number > SWINGMAX!"<<endl;
exit(6);
}
}
}
/* cout<<endl<<"Swing: Number and Name "<<Num_Swing<<endl;
for(i=0;i<Num_Swing;i++)cout<<setw(5)<<i<<setw(5)<<\
Node_Name_Swing[i]<<endl;*/
//根据出线数由小到大的顺序对节点排序,并将平衡节点排在最后(序号最大)
int Nswing=0,Nnode=0;
for(i=0;i<Num_Node;i++)
{
Flag=0;
for(j=0;j<Num_Swing;j++)
{
if(Node_Name[i][0]==Node_Name_Swing[j])Flag=1;
if(Flag==1)break; //Flag=1时,表示该节点为平衡节点,
} //需排在靠后的位置上。
if(Flag==0)
{
Node_Name_NewtoOld[Nnode]=Node_Name[i][0];
Nnode++;
}
else //最后的各平衡节点间也仍然按出线数由小到大的顺序排列
{
Node_Name_NewtoOld[Num_Node-Num_Swing+Nswing]=\
Node_Name[i][0];
Nswing++;
}
}
/* cout<<endl<<"Node Sequence with swing nodes being in the end: "\
<<"Number, Name"<<endl;
for(i=0;i<Num_Node;i++)cout<<setw(5)<<i<<setw(5)\
<<Node_Name_NewtoOld[i]<<endl; */
//新线路类型标志赋初值
for(i=0;i<Num_Line;i++)Line_Flag[i]=LLine[i].Flag;
//线路名(号)处理:变成新的节点名(号)且左节点的绝对值小于右节点的绝对值
for(i=0;i<Num_Line;i++)
{
Flag=0;
for(j=0;j<Num_Node;j++)
{
if(LLine[i].Node_No[0]==Node_Name_NewtoOld[j])//左节点处理
{
Line_NodeName[i][0]=j; //赋新名(号)
Flag=1;
}
if(Flag==1)break;
}
Flag=0;
for(j=0;j<Num_Node;j++)
{
if(LLine[i].Node_No[1]==Node_Name_NewtoOld[j])//右节点处理
{
Line_NodeName[i][1]=j; //赋新名(号)
Flag=1;
}
if(Flag==1)break;
}
if(Line_NodeName[i][0]>Line_NodeName[i][1])//左节点的绝对值小于
{ //右节点的绝对值处理
if(LLine[i].Flag==1)Line_Flag[i]=2; //变压器的非标准
if(LLine[i].Flag==2)Line_Flag[i]=1; //变比侧发生变化
temp=Line_NodeName[i][0];
Line_NodeName[i][0]=Line_NodeName[i][1];
Line_NodeName[i][1]=temp;
}
}
/* cout<<endl<<"Line:line number,type,left node,right node"<<endl;
for(i=0;i<Num_Line;i++)
cout<<setw(5)<<i<<setw(5)<<Line_Flag[i]\
<<setw(5)<<Line_NodeName[i][0]\
<<setw(5)<<Line_NodeName[i][1]<<endl;
*/
//线路排序:按照左节点的绝对值由小到大、若左节点的绝对值相等则按照右节
//点的绝对值由小到大顺序排序(双排序冒泡算法)
for(i=0;i<Num_Line;i++)Line_No_NewtoOld[i]=i;
for(i=0;i<Num_Line-1;i++)
{
np=i;
for(j=i+1;j<Num_Line;j++)
{
if(Line_NodeName[j][0]<Line_NodeName[np][0] \
||(Line_NodeName[j][0]==Line_NodeName[np][0] \
&&Line_NodeName[j][1]<Line_NodeName[np][1]))
{
np=j;
}
}
temp=Line_NodeName[np][0];
Line_NodeName[np][0]=Line_NodeName[i][0];
Line_NodeName[i][0]=temp;
temp=Line_NodeName[np][1];
Line_NodeName[np][1]=Line_NodeName[i][1];
Line_NodeName[i][1]=temp;
temp=Line_No_NewtoOld[np];
Line_No_NewtoOld[np]=Line_No_NewtoOld[i];
Line_No_NewtoOld[i]=temp;
temp=Line_Flag[np];
Line_Flag[np]=Line_Flag[i];
Line_Flag[i]=temp;
}
/* cout<<endl<<"Line sequencing: new line number,new type, new left"\
<<" node, new right node, old line number"<<endl;
for(i=0;i<Num_Line;i++)
cout<<setw(5)<<i<<setw(5)<<Line_Flag[i]\
<<setw(5)<<Line_NodeName[i][0]\
<<setw(5)<<Line_NodeName[i][1]\
<<setw(5)<<Line_No_NewtoOld[i]<<endl;
*/
//发电机节点名(号)处理:变成新的节点名(号)
for(i=0;i<Num_Gen;i++)
{
Flag=0;
for(j=0;j<Num_Node;j++)
{
if(GGen[i].Node_No==Node_Name_NewtoOld[j])
{
Gen_NodeName[i]=j; //赋新名(号)
Flag=1;
}
if(Flag==1)break;
}
}
/* cout<<endl<<"Generator node new name:number, new node name"<<endl;
for(i=0;i<Num_Gen;i++)
cout<<setw(5)<<i<<setw(5)<<Gen_NodeName[i]<<endl;*/
//发电机排序:按照新节点名(号)由小到大的顺序排序,并找出新发电机序号
//对应的旧发电机序号
for(i=0;i<Num_Gen;i++)Gen_No_NewtoOld[i]=i;
for(i=0;i<Num_Gen-1;i++)
{
np=i;
for(j=i+1;j<Num_Gen;j++)
{
if(Gen_NodeName[j]<Gen_NodeName[np])
{
np=j;
}
}
temp=Gen_NodeName[np];
Gen_NodeName[np]=Gen_NodeName[i];
Gen_NodeName[i]=temp;
temp=Gen_No_NewtoOld[np];
Gen_No_NewtoOld[np]=Gen_No_NewtoOld[i];
Gen_No_NewtoOld[i]=temp;
}
/* cout<<endl<<"Generator sequencing: new gen number, new node, old"\
<<" gen number"<<endl;
for(i=0;i<Num_Gen;i++)
cout<<setw(5)<<i<<setw(5)<<Gen_NodeName[i]\
<<setw(5)<<Gen_No_NewtoOld[i]<<endl;*/
//负荷节点名(号)处理:变成新的节点名(号)
for(i=0;i<Num_Load;i++)
{
Flag=0;
for(j=0;j<Num_Node;j++)
{
if(LLoad[i].Node_No==Node_Name_NewtoOld[j])
{
Load_NodeName[i]=j; //赋新名(号)
Flag=1;
}
if(Flag==1)break;
}
}
/* cout<<endl<<"Load node new name: number, new node name"<<endl;
for(i=0;i<Num_Load;i++)
cout<<setw(5)<<i<<setw(5)<<Load_NodeName[i]<<endl;*/
//负荷排序:按照新节点名(号)由小到大的顺序排序,并找出新负荷序号
//对应的旧负荷序号
for(i=0;i<Num_Load;i++)Load_No_NewtoOld[i]=i;
for(i=0;i<Num_Load-1;i++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -