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

📄 pf33.cpp

📁 含有移相器的配电网潮流计算程序
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//多平衡节点+大R/X比处理+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 3.14159265/180.0		//度到弧度的转换系数
#define Rad_to_Deg 180.0/3.14159265		//弧度到度的转换系数
//#define Resist_to_React  1.0/4.0		//需特殊处理的线路R/X阈值
#define Resist_to_React  4.0/1.0		//需特殊处理的线路R/X阈值
#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<<"Number of lines is greater than LINEMAX!"<<endl;
			exit(0);
		}
		if(Num_Gen>GENERATORMAX)
		{
			cout<<"Number of generators is greater than GENERATORMAX!"<<endl;
			exit(1);
		}
		if(Num_Load>LOADMAX)
		{
			cout<<"Number of loads is greater than 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])
			{					//该节点已经在节点数组中出现,只需出线数加1
				Node_Name[j][1]++;
				Flag=1;
			};
			if(Flag==1)break;
		}
		if(Flag==0)	//该节点还没在节点数组中出现,需将该节点名(号)添加到
		{			//节点数组中,然后该节点的出线数加1,并将节点数也加1
			Node_Name[Num_Node][0]=LLine[i].Node_No[0];
			Node_Name[Num_Node][1]++;
			(Num_Node)++;
			if(Num_Node>NODEMAX)
			{
				cout<<"Number of nodes is greater than NODEMAX!"<<endl;
				exit(4);
			}
		}

		Flag=0;					//右节点出线数分析开始
		for(j=0;j<Num_Node;j++)
		{
			if(LLine[i].Node_No[1]==Node_Name[j][0])	
			{					//该节点已经在节点数组中出现,只需出线数加1
				Node_Name[j][1]++;
				Flag=1;
			};
			if(Flag==1)break;
		}
		if(Flag==0)	//该节点还没在节点数组中出现,需将该节点名(号)添加到
		{			//节点数组中,然后该节点的出线数加1,并将节点数也加1。
			Node_Name[Num_Node][0]=LLine[i].Node_No[1];
			Node_Name[Num_Node][1]++;
			(Num_Node)++;
			if(Num_Node>NODEMAX)
			{
				cout<<"Number of nodes is greater than NODEMAX!"<<endl;
				exit(5);
			}
		}
	}						
//节点出线数统计完毕,屏幕输出。其中,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<<"Number of swinging generators is greater than 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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -