📄 flow.cpp
字号:
for(i=0;i<NodeNum;i++)
{
if(fabs(pNodeData[i].ShuntB)>SMALLEST)
{
int n=pNodeData[i].Num;
ni=OptimisedNode(n);
tii=B.GetElement(ni,ni);
tii=tii+pNodeData[i].ShuntB;
B.SetElement(ni,ni,tii);
}
}
//-------------2004.10.27,处理小阻抗和R/X比值较大的支路而增加的类
if(bUseParallelCompenTech && nAbnormalBranchNum>0)
{
ParallelCompensBranch * pcb;
double Bij;
for(i=0;i<nAbnormalBranchNum;i++)
{
pcb=ParalCompensBranches+i;
ni=OptimisedNode(pcb->NodeI-1);
nj=OptimisedNode(pcb->NodeJ-1);
tii=B.GetElement(ni,ni); //获得导纳矩阵原来元素的值
tij=B.GetElement(ni,nj);
tji=B.GetElement(nj,ni);
tjj=B.GetElement(nj,nj);
Bij=pcb->Bn;
if(pcb->BranchType==LN)
{
tii=tii+Bij;
tjj=tjj+Bij;
tij=tij-Bij;
tji=tji-Bij;
}
else //变压器支路
{
double y12=Bij/pb->K;
tii=tii+y12;
tjj=tjj+y12;
tij=tij-y12;
tji=tji-y12;
}
B.SetElement(ni,ni,tii); //设置导纳矩阵的值
B.SetElement(ni,nj,tij);
B.SetElement(nj,ni,tji);
B.SetElement(nj,nj,tjj);
}
}
*/
/*
#ifndef NDEBUG
printf("\n\nB Matrix");
for(i=0;i<NodeNum;i++)
{
printf("\n");
for(int j=0;j<NodeNum;j++)
{
printf("%lf ",B.GetElement(i,j));
}
}
#endif
*/
}
//--------------------------------------------------------------------------------
inline double Flow::GetX(int Row, int Col)
{
return X.GetElement(Row,Col);
}
//--------------------------------------------------------------------------------
inline void Flow::SetX(int Row, int Col, double Value)
{
X.SetElement(Row,Col,Value);
}
//--------------------------------------------------------------------------------
bool Flow::PQ_XB1()
{
std::cout<<'\n'<<"迭代次数"<<" "<<"最大有功偏差"<<" "<<"所在节点"<<" "<<"最大无功偏差"<<" "<<"所在节点"<<'\n';
int i;
int ITER=0; //迭代次数
bPFconverge=false;
int * PQNode=new int[SumOfPQ]; //PQ节点编号表
SparseMatrix<double> PMatrix(NodeNum-1,NodeNum-1); //P 对应修正方程系数矩阵
SparseMatrix<double> QMatrix(NodeNum-1,NodeNum-1); //Q 对应修正方程系数矩阵
// CsparMatrix<double> QMatrix(SumOfPQ,SumOfPQ); //Q 对应修正方程系数矩阵
int nsl=OptimisedNode(SlackNodeOrder-1);
for(i=0;i<NodeNum;i++) //设置节点电压和相位初值
{
int ti;
ti=OriginalNode(i);
if(pNodeData[ti].NodeType==PQ)
U[i]=1.0; //设置PQ电压幅值为1
else
U[i]=pNodeData[ti].DesireVolt; //设置PV节点和平衡节点电压幅值
Phase[i]=Phase[nsl]; //设置节点电压相位
}
for(i=0;i<NodeNum;i++) //设置P系数矩阵
{
if(i==SlackNodeOrder-1) continue;
int tii=OptimisedNode(i); //优化后的编号
for(int j=0;j<NodeNum;j++)
{
if(j==SlackNodeOrder-1) continue;
int tjj=OptimisedNode(j); //优化后的编号
PMatrix.SetElement(tii,tjj,X.GetElement(tii,tjj));
if(i==j && pNodeData[i].NodeType ==PV)
QMatrix.SetElement(tii,tjj,1.0);
else if(pNodeData[i].NodeType !=PV && pNodeData[j].NodeType !=PV)
QMatrix.SetElement(tii,tjj,B.GetElement(tii,tjj));
}
}
QMatrix.BuildFactorTable(); //建立因子表
PMatrix.BuildFactorTable();
//功率误差方程式
double * PError=new double[NodeNum-1];
double * QError=new double[NodeNum-1];
int oldOrder;
int MaxErrNodeP,MaxErrNodeQ;
double MaxErrorP,MaxErrorQ;
MaxErrorP=2*eps;MaxErrorQ=2*eps;
do{
/*
#ifndef NDEBUG
printf("\nIterate...");
for(i=0;i<NodeNum;i++)
{
printf("\nNode %d: %lf <%lf",i,U[OptimisedNode(i)],Phase[OptimisedNode(i)]);
}
#endif
*/
//-----------------------
//-------------2008.10.27,处理小阻抗和R/X比值较大的支路而增加
if(bParallelCompenTechSwitched) CalcParalCompensBranchesPQ();
MaxErrorQ=0.0;
CalcNodalPowerQ();
for(i=0;i<NodeNum-1;i++)
{
oldOrder=OriginalNode(i);
if(pNodeData[oldOrder].NodeType==PV)
QError[i]=0.0;
else
QError[i]=(pNodeData[oldOrder].Q-NodalPowerQ[i])/U[i];
if(fabs(QError[i]) > MaxErrorQ)
{
MaxErrorQ=fabs(QError[i]);
MaxErrNodeQ=oldOrder;
}
}
/*
#ifndef NDEBUG
printf("\nThe ERROR of Q\n");
for(i=0;i<NodeNum-1;i++)
printf("%lf ",QError[i]);
#endif
*/
QMatrix.ResolveEquation(QError); //解Q的修正方程
/*
#ifndef NDEBUG
printf("\nThe Result of Q\n");
for(i=0;i<NodeNum-1;i++)
{
printf("%lf ",QError[i]);
}
#endif
*/
for(i=0;i<NodeNum-1;i++) //修正电压幅值
{
U[i]-=QError[i];
}
//-------------2008.10.27,处理小阻抗和R/X比值较大的支路而增加
if(bParallelCompenTechSwitched) CalcParalCompensBranchesPQ();
if(MaxErrorP>eps)
{
MaxErrorP=0.0;
CalcNodalPowerP();
for(i=0;i<NodeNum-1;i++)
{
oldOrder=OriginalNode(i);
PError[i]=(pNodeData[oldOrder].P-NodalPowerP[i])/U[i];
if(fabs(PError[i])>MaxErrorP)
{
MaxErrorP=fabs(PError[i]);
MaxErrNodeP=oldOrder;
}
}
/*
#ifndef NDEBUG
printf("\nThe Error of P\n");
for(i=0;i<NodeNum-1;i++)
printf("%lf ",PError[i]);
#endif
*/
PMatrix.ResolveEquation(PError); //解P修正方程
/*
#ifndef NDEBUG
printf("\nThe Result of P\n");
for(i=0;i<NodeNum-1;i++)
printf("%lf ",PError[i]);
#endif
*/
for(i=0;i<NodeNum-1;i++) //修正相位
{
Phase[i]-=PError[i]; ///U[i];
}
}
ITER++;
//#ifndef NDEBUG
std::cout<<setw(4)<<ITER<<setw(16)<<MaxErrorP<<setw(10)<<pNodeData[MaxErrNodeP].Num<<setw(16)<<MaxErrorQ<<setw(11)<<pNodeData[MaxErrNodeQ].Num<<std::endl;
// getch();
//#endif
// fprintf(outfile,"\nITERATION TIME: %d ",ITER);
// fprintf(outfile,"MaxErrorP:%lf MaxErrorQ:%lf",MaxErrorP,MaxErrorQ);
if(ITER>MaxIterNum)
{
//#ifndef NDEBUG
std::cout<<"PQ Method Failed! "<<std::endl;
//#endif
return false;
}
}while(fabs(MaxErrorP)>eps || fabs(MaxErrorQ)>eps);
std::cout<<std::endl<<"总迭代次数: "<<ITER<<" 精度为:"<<eps<<std::endl;
outfile<<std::endl<<"总迭代次数: "<<ITER<<" 精度为:"<<eps<<std::endl;
bPFconverge=true;
delete [] PError;
delete [] QError;
delete [] PQNode;
return true;
}
//-----------------------------------------------------------------------
//--------2008.12.11----------
//应用符号分解技术
bool Flow::PQ_XB2()
{
std::cout<<'\n'<<"迭代次数"<<" "<<"最大有功偏差"<<" "<<"所在节点"<<" "<<"最大无功偏差"<<" "<<"所在节点"<<'\n';
int i;
int ITER=0; //迭代次数
bPFconverge=false;
JacPQ PMatrix; //P 对应修正方程系数矩阵
JacPQ QMatrix; //Q 对应修正方程系数矩阵
PMatrix.Initialize(NodeNum-1);
QMatrix.Initialize(NodeNum-1);
int nsl=OptimisedNode(SlackNodeOrder-1);
for(i=0;i<NodeNum;i++) //设置节点电压和相位初值
{
int ti;
ti=OriginalNode(i);
if(pNodeData[ti].NodeType==PQ)
U[i]=1.0; //设置PQ电压幅值为1
else
U[i]=pNodeData[ti].DesireVolt; //设置PV节点和平衡节点电压幅值
Phase[i]=Phase[nsl]; //设置节点电压相位
}
for(i=0;i<NodeNum;i++) //设置P系数矩阵
{
if(i==SlackNodeOrder-1) continue;
int tii=OptimisedNode(i); //优化后的编号
for(int j=0;j<NodeNum;j++)
{
if(j==SlackNodeOrder-1) continue;
int tjj=OptimisedNode(j); //优化后的编号
PMatrix.SetBElement(tii,tjj,X.GetElement(tii,tjj));
if(i==j && pNodeData[i].NodeType ==PV)
QMatrix.SetBElement(tii,tjj,1.0);
else if(pNodeData[i].NodeType !=PV && pNodeData[j].NodeType !=PV)
QMatrix.SetBElement(tii,tjj,B.GetElement(tii,tjj));
}
}
//解雅可比矩阵
PMatrix.SetBStatus(true);
QMatrix.SetBStatus(true);
PMatrix.CountElement();
QMatrix.CountElement();
QMatrix.BuildFactorTable(); //建立因子表
PMatrix.BuildFactorTable();
//功率误差方程式
double * PError=new double[NodeNum-1];
double * QError=new double[NodeNum-1];
int oldOrder;
int MaxErrNodeP,MaxErrNodeQ;
double MaxErrorP,MaxErrorQ;
MaxErrorP=2*eps;MaxErrorQ=2*eps;
do{
/*
#ifndef NDEBUG
printf("\nIterate...");
for(i=0;i<NodeNum;i++)
{
printf("\nNode %d: %lf <%lf",i,U[OptimisedNode(i)],Phase[OptimisedNode(i)]);
}
#endif
*/
MaxErrorP=0.0;
CalcNodalPowerP();
for(i=0;i<NodeNum-1;i++)
{
oldOrder=OriginalNode(i);
PError[i]=(pNodeData[oldOrder].P-NodalPowerP[i])/U[i];
if(fabs(PError[i])>MaxErrorP)
{
MaxErrorP=fabs(PError[i]);
MaxErrNodeP=oldOrder;
}
}
/*
#ifndef NDEBUG
printf("\nThe Error of P\n");
for(i=0;i<NodeNum-1;i++)
printf("%lf ",PError[i]);
#endif
*/
PMatrix.ResolveEquation(PError); //解P修正方程
/*
#ifndef NDEBUG
printf("\nThe Result of P\n");
for(i=0;i<NodeNum-1;i++)
printf("%lf ",PError[i]);
#endif
*/
for(i=0;i<NodeNum-1;i++) //修正相位
{
Phase[i]-=PError[i];
}
MaxErrorQ=0.0;
CalcNodalPowerQ();
for(i=0;i<NodeNum-1;i++)
{
oldOrder=OriginalNode(i);
if(pNodeData[oldOrder].NodeType==PV)
QError[i]=0.0;
else
QError[i]=(pNodeData[oldOrder].Q-NodalPowerQ[i])/U[i];
if(fabs(QError[i]) > MaxErrorQ)
{
MaxErrorQ=fabs(QError[i]);
MaxErrNodeQ=oldOrder;
}
}
/*
#ifndef NDEBUG
printf("\nThe ERROR of Q\n");
for(i=0;i<NodeNum-1;i++)
printf("%lf ",QError[i]);
#endif
*/
QMatrix.ResolveEquation(QError); //解Q的修正方程
/*
#ifndef NDEBUG
printf("\nThe Result of Q\n");
for(i=0;i<NodeNum-1;i++)
{
printf("%lf ",QError[i]);
}
#endif
*/
for(i=0;i<NodeNum-1;i++) //修正电压幅值
{
U[i]-=QError[i]/U[i];
}
ITER++;
#ifndef NDEBUG
std::cout<<setw(4)<<ITER
<<setw(16)<<MaxErrorP<<setw(10)<<pNodeData[MaxErrNodeP].Num
<<setw(16)<<MaxErrorQ<<setw(11)<<pNodeData[MaxErrNodeQ].Num
<<'\n';
#endif
//fprintf(outfile,"\nITERATION TIME: %d ",ITER);
//fprintf(outfile,"MaxErrorP:%lf MaxErrorQ:%lf",MaxErrorP,MaxErrorQ);
if(ITER>MaxIterNum)
{
std::cout<<std::endl<<"PQ Method Failed! "<<std::endl;
return false;
}
}while(fabs(MaxErrorP)>eps || fabs(MaxErrorQ)>eps);
std::cout<<std::endl<<"总迭代次数: "<<ITER<<" 精度为:"<<eps<<std::endl;
//outfile<<std::endl<<"总迭代次数: "<<ITER<<" 精度为:"<<eps<<std::endl;
bPFconverge=true;
delete [] PError;
delete [] QError;
return true;
}
//--------------------------------------------------------------------------------
bool Flow::PQ_BX2()
{
std::cout<<'\n'<<"迭代次数"<<" "<<"最大有功偏差"<<" "<<"所在节点"<<" "<<"最大无功偏差"<<" "<<"所在节点"<<'\n';
int i;
int ITER=0; //迭代次数
bPFconverge=false;
int * PQNode=new int[SumOfPQ]; //PQ节点编号表
SparseMatrix<double> PMatrix(NodeNum-1,NodeNum-1); //P 对应修正方程系数矩阵
SparseMatrix<double> QMatrix(SumOfPQ,SumOfPQ); //Q 对应修正方程系数矩阵
int nsl=OptimisedNode(SlackNodeOrder-1);
int count=0; //用于统计PQ节点个数
for(i=0;i<NodeNum;i++) //获得PQ节点优化后的编号列表
{
int fi;
fi=OriginalNode(i); //获得未优化的节点编号
if(pNodeData[fi].NodeType==PQ)
{
PQNode[count]=i;
count++;
}
}
for(i=0;i<NodeNum;i++) //设置节点电压和相位初值
{
int ti;
ti=OriginalNode(i);
if(pNodeData[ti].NodeType==PQ)
U[i]=1.0; //设置PQ电压幅值为1
else
U[i]=pNodeData[ti].DesireVolt; //设置PV节点和平衡节点电压幅值
Phase[i]=Phase[nsl]; //设置节点电压相位
}
for(i=0;i<NodeNum;i++) //设置P系数矩阵
{
if(i==SlackNodeOrder-1) continue;
int tii=OptimisedNode(i); //优化后的编号
for(int j=0;j<NodeNum;j++)
{
if(j==SlackNodeOrder-1) continue;
int tjj=OptimisedNode(j); //优化后的编号
PMatrix.SetElement(tii,tjj,B.GetElement(tii,tjj));
}
}
//建立Q的系数矩阵
for(i=0;i<SumOfPQ;i++)
{
int ti=PQNode[i];
for(int j=0;j<SumOfPQ;j++)
{
int tj=PQNode[j];
QMatrix.SetElement(i,j,GetX(ti,tj));
}
}
QMatrix.BuildFactorTable(); //建立因子表
PMatrix.BuildFactorTable();
//功率误差方程式
double * PError=new double[NodeNum-1];
double * QError=new double[SumOfPQ];
int oldOrder;
int MaxErrNodeP,MaxErrNodeQ;
double MaxErrorP,MaxErrorQ;
MaxErrorP=2*eps;MaxErrorQ=2*eps;
do{
/*
#ifndef NDEBUG
printf("\nIterate...");
for(i=0;i
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -