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

📄 pf30.cpp

📁 电力系统潮流计算程序
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	int ix;							//因子表上三角元素地址(序号)计数
	double Y_Work[NODEMAX];			//工作数组
	double Temp1,Temp2;				//临时工作单元
	int kgpv;

	for(i=0;i<Num_Node-Num_Swing;i++)
	{
		if(IterFlag==1&&Node_Flag[i]==2)		//无功迭代对应的PV节点
		{
			Num_Fact_UpTri[i][IterFlag]=0;
			Fact_Diag[i][IterFlag]=0.0;
		}
		else
		{
			for(k=i+1;k<Num_Node-Num_Swing;k++)
				Y_Work[k]=0.0;
			Y_Work[i]=Y_Diag[i][1];

			for(k=No_First_Y_UpTri[i];k<No_First_Y_UpTri[i+1];k++)
			{
				j=Foot_Y_UpTri[k];
				Y_Work[j]=Y_UpTri[k][1];
			}
			if(IterFlag==1)
			{
				for(kgpv=0;kgpv<Num_GPV;kgpv++)
				{
					j=Gen_PVNode[kgpv][0];			//PV节点号
					Y_Work[j]=0.0;
				}
			}

			ix=0;
			for(im=0;im<i;im++)
			{
				for(k=0;k<Num_Fact_UpTri[im][IterFlag];k++)
				{
					if(Foot_Fact_UpTri[ix][IterFlag]!=i)
						ix++;
					else
					{
						Temp1=Fact_UpTri[ix][IterFlag]\
							/Fact_Diag[im][IterFlag];
						for(k=k;k<Num_Fact_UpTri[im][IterFlag];k++)
						{
							j=Foot_Fact_UpTri[ix][IterFlag];
							Temp2=Temp1*Fact_UpTri[ix][IterFlag];
							Y_Work[j]=Y_Work[j]-Temp2;
							ix++;
						}
					}
				}
			}
			Fact_Diag[i][IterFlag]=1.0/Y_Work[i];
			Temp1=Fact_Diag[i][IterFlag];
			k=0;
			for(j=i+1;j<Num_Node-Num_Swing;j++)
			{
				if(fabs(Y_Work[j])!=0.0)
				{
					Fact_UpTri[ix][IterFlag]=Y_Work[j]*Temp1;
					Foot_Fact_UpTri[ix][IterFlag]=j;
					k++;
					ix++;
				}
			}
			Num_Fact_UpTri[i][IterFlag]=k;
		}
	}
//因子表结果输出
/*	cout<<endl<<"因子表对角元素:序号(与节点号同)和元素值"<<endl;
	for(i=0;i<Num_Node-Num_Swing;i++)
		cout<<setw(5)<<i<<setw(15)<<Fact_Diag[i][IterFlag]<<endl;

	cout<<endl<<"因子表上三角非零元素:序号、列足码和元素值"<<endl;
	for(i=0;i<ix;i++)
		cout<<setw(5)<<i<<setw(5)<<Foot_Fact_UpTri[i][IterFlag]\
		<<setw(15)<<Fact_UpTri[i][IterFlag]<<endl;
*/
}

//方程AX=t求解
void Equ_Calculation(int Num_Node,int Num_Swing,
					 double Power_Dis_Correct[NODEMAX],int IterFlag)
{
	int i,j,k,ix;							//参见Factor_Table子程说明
	double Temp1,Temp2;						//临时工作单元

	ix=0;
	for(i=0;i<Num_Node-Num_Swing;i++)		//前代运算开始
	{
		Temp1=Power_Dis_Correct[i];			//将右端量送入临时工作单元
		for(k=0;k<Num_Fact_UpTri[i][IterFlag];k++)
		{
			j=Foot_Fact_UpTri[ix][IterFlag];
			Temp2=Temp1*Fact_UpTri[ix][IterFlag];
			Power_Dis_Correct[j]=Power_Dis_Correct[j]-Temp2;
			ix++;
		}
		Power_Dis_Correct[i]=Temp1*Fact_Diag[i][IterFlag];
	}
	for(i=Num_Node-Num_Swing-1;i>=0;i--)	//回代运算开始
	{
		Temp1=Power_Dis_Correct[i];
		for(k=0;k<Num_Fact_UpTri[i][IterFlag];k++)
		{
			ix--;
			j=Foot_Fact_UpTri[ix][IterFlag];
			Temp2=Power_Dis_Correct[j]*Fact_UpTri[ix][IterFlag];
			Temp1=Temp1-Temp2;
		}
		Power_Dis_Correct[i]=Temp1;				//最终得未知数的解
	}
}


double Voltage[NODEMAX][2];						//节点电压:0-相位角;
												//1-幅值。
double Current_Const[SWINGMAX*NODEFACTOR][2];	//常数电流:0-实部;
												//1-虚部。
int Node_Name_Curr_Const[SWINGMAX*NODEFACTOR];	//常数电流的节点名(号)
double Power_Const[NODEMAX][2];					//各节点注入功率不变部
												//分:0-实部;1-虚部。

void Voltage_Initial(int Num_Node,int Num_Swing);


//初始化子程
void Initial(int Num_Node,int Num_Line,int Num_Load,int Num_Swing,
			 int Num_GPV,int Num_GPQ,int &Num_Cur_Const,
			 double DVolt[NODEMAX][2],ofstream &of_PQDisOut,
			 int VolIni_Flag)				
{
	int i,j,jl,jr,k,kk;
	int Flag;
	int kg_old,kl_old;					//发电机、负荷旧顺序号工作单元
	int kl;								//负荷计数临时工作单元
	int kgpv;							//发电机PV节点计数临时工作单元
	int kgpq;							//发电机PQ节点计数临时工作单元
	double R,X,Z,Ang;					//线路参数及平衡节点电压相角临
										//时单元。
	double yij[2],V_Temp[2],I_Temp[2];	//临时工作单元

	for(i=0;i<Num_Node-Num_Swing;i++)
	{
		Voltage[i][0]=0.0;				//电压相位的初值:0.0(弧度)
		Voltage[i][1]=1.0;				//电压幅值的初值:1.0
		DVolt[i][0]=0.0;				//电压相量变化量赋初值0.0
		DVolt[i][1]=0.0;
		Power_Const[i][0]=0.0;			//各节点注入功率赋初值
		Power_Const[i][1]=0.0;

	}
	if(VolIni_Flag==1)Voltage_Initial(Num_Node,Num_Swing);
	for(kgpv=0;kgpv<Num_GPV;kgpv++)		//发电机PV节点的电压幅值=VG
	{
		i=Gen_PVNode[kgpv][0];
		kg_old=Gen_PVNode[kgpv][1];
		Voltage[i][1]=GGen[kg_old].PQV[1];
	}

	for(i=0;i<Num_Line;i++)				//常数电流信息求解
	{
		jl=Line_NodeName[i][0];			//线路左节点
		jr=Line_NodeName[i][1];			//线路右节点
		if(jl<Num_Node-Num_Swing\
			&&jr>=Num_Node-Num_Swing)	//jl为普通节点,jr为平衡节点。
		{									
			k=Line_No_NewtoOld[i];		//对应的旧线路号
			R=LLine[k].RXBK[0];
			X=LLine[k].RXBK[1];
			Z=R*R+X*X;
			if(Line_Flag[i]==0)
			{
				R=R/Z;
				X=-X/Z;
			}
			else
			{
				R=R/Z/LLine[k].RXBK[2];
				X=-X/Z/LLine[k].RXBK[2];
			}
			yij[0]=R;
			yij[1]=X;				//至此求得支路导纳除以非标准变比

			Flag=0;
			for(k=0;k<Num_Swing;k++)
			{
				if(Gen_SWNode[k][0]==jr)
				{
					kk=Gen_SWNode[k][1];
					Ang=GGen[kk].PQV[1]*Deg_to_Rad;
					V_Temp[0]=GGen[kk].PQV[0]*cos(Ang);
					V_Temp[1]=GGen[kk].PQV[0]*sin(Ang);
					Flag=1;
				}
				if(Flag==1)break;
			}						//至此求得相应平衡节点电压的实虚部

			Flag=0;
			for(j=0;j<Num_Cur_Const;j++)
			{
				if(Node_Name_Curr_Const[j]==jl)Flag=1;
				if(Flag==1)break;
			}
			if(Flag==0)					//新增常数电流节点
			{
				Node_Name_Curr_Const[Num_Cur_Const]=jl;
				Comp_Mul(Current_Const[Num_Cur_Const],yij,V_Temp);
				Num_Cur_Const++;
				if(Num_Cur_Const>SWINGMAX*NODEFACTOR)
				{
					cout<<"Number of constant-current nodes "\
						"> SWINGMAX*NODEFACTOR!"<<endl;
					exit(10);
				}
			}
			else						//该常数电流节点已经出现过
			{
				Comp_Mul(I_Temp,yij,V_Temp);
				Current_Const[j][0]=Current_Const[j][0]+I_Temp[0];
				Current_Const[j][1]=Current_Const[j][1]+I_Temp[1];
			}
		}
	}
//输出常数电流节点数据
/*	cout<<endl<<"Constant current:Number, new node name, "\
		<<"current value"<<endl;
	for(i=0;i<Num_Cur_Const;i++)
		cout<<setw(5)<<i<<setw(5)<<Node_Name_Curr_Const[i]\
		<<setw(10)<<Current_Const[i][0]\
		<<setw(10)<<Current_Const[i][1]<<endl;*/

//各节点注入功率不变部分求值处理
	kgpv=0;
	kgpq=0;
	kl=0;
	for(i=0;i<Num_Node-Num_Swing;i++)
	{
		if(kgpv<Num_GPV&&i==Gen_PVNode[kgpv][0])	//发电机PV节点
		{
			kg_old=Gen_PVNode[kgpv][1];				//发电机旧顺序号
			if(kl<Num_Load&&i==Load_NodeName[kl])	//负荷节点
			{
				kl_old=Load_No_NewtoOld[kl];		//负荷旧顺序号
				Power_Const[i][0]=Power_Const[i][0]\
					+GGen[kg_old].PQV[0]\
					-LLoad[kl_old].ABC[4];			//有功部分加PG和C1
				kl++;
			}
			else									//非负荷节点
			{
				Power_Const[i][0]=Power_Const[i][0]\
					+GGen[kg_old].PQV[0];			//有功部分加入PG
			}
			kgpv++;
		}
		else if(kgpq<Num_GPQ&&i==Gen_PQNode[kgpq][0])	//发电机PQ节点
		{
			kg_old=Gen_PQNode[kgpq][1];				//发电机旧顺序号
			if(kl<Num_Load&&i==Load_NodeName[kl])	//负荷节点
			{
				kl_old=Load_No_NewtoOld[kl];		//负荷旧顺序号
				Power_Const[i][0]=Power_Const[i][0]\
					+GGen[kg_old].PQV[0]\
					-LLoad[kl_old].ABC[4];			//有功部分加PG和C1
				Power_Const[i][1]=Power_Const[i][1]\
					+GGen[kg_old].PQV[1]\
					-LLoad[kl_old].ABC[5];			//无功部分加QG和C2
				kl++;
			}
			else									//非负荷节点
			{
				Power_Const[i][0]=Power_Const[i][0]\
					+GGen[kg_old].PQV[0];			//有功部分加入PG
				Power_Const[i][1]=Power_Const[i][1]\
					+GGen[kg_old].PQV[1];			//无功部分加入QG
			}
			kgpq++;
		}
		else					//既非发电机PV节点,又非发电机PQ节点
		{
			if(kl<Num_Load&&i==Load_NodeName[kl])	//负荷节点
			{
				kl_old=Load_No_NewtoOld[kl];		//负荷旧顺序号
				Power_Const[i][0]=Power_Const[i][0]\
					-LLoad[kl_old].ABC[4];			//有功部分加入C1
				Power_Const[i][1]=Power_Const[i][1]\
					-LLoad[kl_old].ABC[5];			//无功部分加入C2
				kl++;
			}
		}
	}
//各节点注入功率不变部分处理结果输出:新节点名(号),有功功率,无功功率
/*	cout<<endl<<"Node input constant power:new node name, real and "\
		<<"reactive power"<<endl;
	for(i=0;i<Num_Node-Num_Swing;i++)
		cout<<setw(5)<<i<<setw(10)<<Power_Const[i][0]\
		<<setw(10)<<Power_Const[i][1]<<endl;*/

//功率失配量输出部分的标题输出
//打开失配量输出磁盘文件
	of_PQDisOut.open("pqdis.dat",ios::out,filebuf::openprot);
	if(of_PQDisOut.fail())	//判断打开是否有错
	{
		cerr<<"Error opening the diskette data-file:"<<"pqdis.dat"\
			<<endl;		exit(10);
	}
	of_PQDisOut<<setiosflags( ios::fixed);	
	of_PQDisOut<<setw(15)<<"Iterating No"<<setw(15)<<"P_Dis_Max"\
		<<setw(6)<<"Node"<<setw(15)<<"Q_Dis_Max"\
		<<setw(6)<<"Node"<<endl;
	of_PQDisOut<<setw(15)<<"=============="\
		<<setw(15)<<"=============="\
		<<setw(6)<<"====="\
		<<setw(15)<<"=============="\
		<<setw(6)<<"====="<<endl;
	cout<<setiosflags( ios::fixed);
	cout<<setw(15)<<"Iterating No"<<setw(15)<<"P_Dis_Max"\
		<<setw(6)<<"Node"<<setw(15)<<"Q_Dis_Max"\
		<<setw(6)<<"Node"<<endl;
	cout<<setw(15)<<"=============="\
		<<setw(15)<<"=============="\
		<<setw(6)<<"====="\
		<<setw(15)<<"=============="<<setw(6)<<"====="<<endl;
}

//读取电压初始化值(按内部节点号)子程
void Voltage_Initial(int Num_Node,int Num_Swing)
{
	ifstream if_VIn("vol30.ini",ios::in,filebuf::openprot);
	if(if_VIn.fail())
	{
		cerr<<"Error opening the voltage initial diskette data-file:"\
			<<"Vol30.ini"<<endl;	exit(0);
	}
	for(int i=0;i<Num_Node-Num_Swing;i++)
		if_VIn>>Voltage[i][0]>>Voltage[i][1];
	if_VIn.close();										//关闭磁盘文件
}


//求节点功率失配量子程(PV节点的dQi=0)
void PowerDis_Comp(int Num_Node,int Num_Load,int Num_Swing,int Num_GPV,
				   int Num_Cur_Const,double Power_Dis[NODEMAX][2],
				   double Pij_Sum[NODEMAX][2],double DVolt[NODEMAX][2],
				   ofstream of_PQDisOut,int Num_Iteration,
				   double &Power_Dis_Max)
{
	int i,j,k,li,kl_old,kl,kgpv,ki,k1;
	double V,Ang;					//节点i电压幅值和相位
	double VV[2];					//节点i电压实部和虚部
	double V_Temp[2];				//节点电压临时工作单元(实、虚部)
	double Cur_Count[2];			//注入电流统计单元(实、虚部)
	double Cur_Temp[2];				//注入电流临时工作单元(实、虚部)
	double Ix,Iy;					//电流(实、虚部)
	double PP,QQ;					//有功、无功
	int ipmax,iqmax;				//最大有功、无功失配量对应的节点号
	double P_Dis_Max,Q_Dis_Max;		//最大有功、无功失配量

	kl=0;
	kgpv=0;
	ki=0;
	for(i=0;i<Num_Node-Num_Swing;i++)
	{
		Power_Dis[i][0]=Power_Const[i][0];	//将节点i注入功率不变部分
		Power_Dis[i][1]=Power_Const[i][1];	//送入失配量单元。
		Ang=Voltage[i][0];	 				//上次迭代后节点i电压相位
		V=Voltage[i][1];					//和幅值。
		VV[0]=V*cos(Ang);					//上次迭代后节点i电压实部
		VV[1]=V*sin(Ang);					//和虚部。
//下面求Pij和Qij及从节点i发出的所有Pij和Qij之和
		Cur_Count[0]=0.0;
		Cur_Count[1]=0.0;
		for(k=No_First_Y_DownTri[i];\
			k<No_First_Y_DownTri[i+1];k++)	//下三角第i行非零元循环
		{
			j=Foot_Y_DownTri[k];	//下三角第i行当前非零元的列足码
			V_Temp[0]=Voltage[j][1]*cos(Voltage[j][0]);
			V_Temp[1]=Voltage[j][1]*sin(Voltage[j][0]);
			li=No_Y_DownTri_RowtoCol[k];	//对应的按列压缩存储序列
											//中同一非零元的序号。
			Comp_Mul(Cur_Temp,Y_UpTri[li],V_Temp);
			Cur_Count[0]=Cur_Count[0]+Cur_Temp[0];
			Cur_Count[1]=Cur_Count[1]+Cur_Temp[1];
		}
		Comp_Mul(Cur_Temp,Y_Diag[i],VV);
		Cur_Count[0]=Cur_Count[0]+Cur_Temp[0];
		Cur_Count[1]=Cur_Count[1]+Cur_Temp[1];
		for(k=No_First_Y_UpTri[i];k<No_First_Y_UpTri[i+1];k++)
		{
			j=Foot_Y_UpTri[k];
			V_Temp[0]=Voltage[j][1]*cos(Voltage[j][0]);
			V_Temp[1]=Voltage[j][1]*sin(Voltage[j][0]);
			Comp_Mul(Cur_Temp,Y_UpTri[k],V_Temp);

⌨️ 快捷键说明

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