⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pf30.cpp

📁 电力系统潮流计算程序 电力专业的学生用的最多的一个小程序。
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//多平衡节点+普通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 + -