cimforreduceloss/testHasttable/cimexporter.cpp

473 lines
16 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "cimexporter.h"
#include <iostream>
CIMExporter::CIMExporter(const QHash<QString, BasicElementInfo *> &eleHT, const QString &loadDir):loadDir(loadDir),eleHT(eleHT)
{
}
void CIMExporter::add(const QPair<QString,QString>& fromTo,Line* line)
{
LineStru lineStru;
lineStru.line=line;
lineStru.fromID=fromTo.first;
lineStru.toID=fromTo.second;
lineStru.id=line->ac->getID();
lineStru.isZeroBranch=std::fabs(line->length)<1e-5;
lineStru.dispose=false;
lineStru.type="AC";
lineStru.length=line->length;
this->line.push_back(lineStru);
}
void CIMExporter::add(const QPair<QString,QString>& fromTo,Switch* sw)
{
SwitchStru switchStru;
switchStru.sw=sw;
switchStru.fromID=fromTo.first;
switchStru.toID=fromTo.second;
switchStru.id=sw->id;
switchStru.isZeroBranch=true;
switchStru.dispose=false;
switchStru.type="SW";
this->sw.push_back(switchStru);
}
void CIMExporter::add(const QPair<QString,QString>& fromTo,Transformer* tf)
{
TransformerStru tfStru;
tfStru.tf=tf;
tfStru.fromID=fromTo.first;
tfStru.toID=fromTo.second;
tfStru.isZeroBranch=false;
tfStru.dispose=false;
tfStru.id=tf->getTF()->getID();
tfStru.type="TF";
this->tf.push_back(tfStru);
}
void CIMExporter::add(const QPair<QString,QString>& fromTo,DG* dg)
{
DGStru dgStru;
dgStru.dg=dg;
dgStru.fromID=fromTo.first;
dgStru.toID=fromTo.second;
dgStru.isZeroBranch=false;
dgStru.dispose=false;
dgStru.id=dg->id;
dgStru.type="DG";
this->dg.push_back(dgStru);
}
void CIMExporter::exportTo(const QString& path,const QString &rootID)
{
char seperator='\t';
QString endLine="\r\n";
//输出到文件
QFile fd(path);
if(fd.open(QFile::WriteOnly))
{
//消减元件
QList<BranchStruc*> elements;
for(int i=0;i<this->line.length();i++)
{
// std::cout<<this->line[i].fromID.toStdString()<<" "<<this->line[i].id.toStdString()<<" "<<this->line[i].toID.toStdString()<<std::endl;
elements.push_back( &(this->line[i]) );
}
for(int i=0;i<this->sw.length();i++)
{
// std::cout<<this->sw[i].fromID.toStdString()<<" "<<this->sw[i].id.toStdString()<<" "<<this->sw[i].toID.toStdString()<<std::endl;
elements.push_back( &(this->sw[i]) );
}
for(int i=0;i<this->tf.length();i++)
{
// std::cout<<this->tf[i].fromID.toStdString()<<" "<<this->tf[i].id.toStdString()<<" "<<this->tf[i].toID.toStdString()<<std::endl;
elements.push_back( &(this->tf[i]) );
}
for(int i=0;i<this->dg.length();i++)
{
// std::cout<<this->dg[i].fromID.toStdString()<<" "<<this->dg[i].id.toStdString()<<" "<<this->dg[i].toID.toStdString()<<std::endl;
elements.push_back( &(this->dg[i]) );
}
ElementReduction elementReduction(elements);
elementReduction.doIt(rootID);//消除0阻抗支路把几段线路连成一段
//先给所有节点都编号
this->idToNumber(this->line);
this->idToNumber(this->sw);
this->idToNumber(this->tf);
this->idToNumber(this->dg);
//开始按iPso格式要求输出
QTextStream writer(&fd);
//iPso 第一行
writer<<this->number.keys().length()<<seperator;//节点数
//TODO: 支路数要单独计算
writer<<0<<seperator;//支路数,由于有些支路被删掉了,所以要计算一下。这里暂时不计算。
writer<<1<<seperator;//计算目标
writer<<1e-5<<seperator;//收敛精度
writer<<-1<<endLine;//忘记是什么了
writer<<0<<endLine;//数据间隔
int balanceNum;//平衡节点号
foreach(LineStru l,this->line )
{
if(l.id==rootID)
{
balanceNum=l.fromNum;
break;
}
}
// std::cout<<"line number "<<this->line.first().fromNum<<" "<<this->line.first().toNum<<" "<<this->line.first().isZeroBranch<<this->line.first().dispose <<std::endl;
writer<<1<<seperator<<balanceNum<<seperator;
writer<<"1.05"<<endLine;//平衡节点电压
writer<<0<<endLine;//数据间隔
int seqN=1;//序号
//先输出线路
// writer<<QStringLiteral("线路")<<QStringLiteral("\r\n");
// writer<<QStringLiteral("节点号")<<QStringLiteral("\t")<<QStringLiteral("节点号")<<QStringLiteral("\t")<<QStringLiteral("型号")<<QStringLiteral("\t")<<QStringLiteral("长度(m)")<<QStringLiteral("\r\n");
for(QList<LineStru>::iterator ite=this->line.begin();
ite!=this->line.end();
ite++)
{
LineStru l=*ite;
if(l.dispose)
{
continue;
}
writer<<seqN++<<seperator;
writer<<l.fromNum<<seperator;
writer<<l.toNum<<seperator;
writer<<l.line->r<<seperator;
writer<<l.line->x<<seperator;
writer<<l.line->b1<<seperator;
writer<<l.line->b2<<seperator;
writer<<endLine;
}
//输出刀闸
for(QList<SwitchStru>::iterator ite=this->sw.begin();
ite!=this->sw.end();
ite++)
{
if(ite->dispose)
{
continue;
}
writer<<seqN++<<seperator;
writer<<ite->fromNum<<seperator;
writer<<ite->toNum<<seperator;
writer<<ite->sw->r<<seperator;
writer<<ite->sw->x<<seperator;
writer<<ite->sw->b1<<seperator;
writer<<ite->sw->b2<<seperator;
writer<<endLine;
}
//输出DG算作短支路
for(QList<DGStru>::iterator ite=this->dg.begin();
ite!=this->dg.end();
ite++)
{
if(ite->dispose)
{
continue;
}
writer<<seqN++<<seperator;
writer<<ite->fromNum<<seperator;
writer<<ite->toNum<<seperator;
writer<<ite->dg->r<<seperator;
writer<<ite->dg->x<<seperator;
writer<<ite->dg->b1<<seperator;
writer<<ite->dg->b2<<seperator;
writer<<endLine;
}
writer<<0<<endLine;//数据间隔
//输出变压器
RecurseDir recurseDir;
recurseDir.setDir(this->loadDir);
QStringList files;
files=recurseDir.getFiles();
//只取文件名
QStringList baseNames;
foreach(QString file,files)
{
QFileInfo fileInfo(file);
if(fileInfo.suffix().toLower()!="csv")
{
continue;
}
baseNames<<fileInfo.baseName();
// std::cout<<"has "<<fileInfo.baseName().toLocal8Bit().data()<<std::endl;
}
seqN=1;
// writer<<QStringLiteral("变压器")<<"\r\n";
// writer<<QStringLiteral("节点号")<<"\t"<<QStringLiteral("节点号")<<"\t"<<QStringLiteral("型号")<<"\t"<<QStringLiteral("容量(MVA)")<<"\r\n";
//把接地支路准备一下
QList<CIMExporter::GroundBranch > groudBranch;//first is g, second is b.
QList<CIMExporter::NodePQ> nodePQ;//节点注入功率,也就是负荷或者发电机
QStringList usedLoad;
for(QList<TransformerStru>::iterator ite=this->tf.begin();
ite!=this->tf.end();
ite++)
{
if(ite->dispose)
{
continue;
}
PowerTransformer *tf=ite->tf->getTF();
QString subID=tf->getEquipmentMemberOf_EquipmentContainer();//所属Substation的ID
Substation *sub=static_cast<Substation *>(this->eleHT[subID]);
if(!sub)
{
std::cout<<"CIMExporter:: can not substation of "<<subID.toStdString()<<std::endl;
continue;
}
// std::cout<<"sub id"<< subID.toStdString()<<" "<<sub->getID().toStdString()<<std::endl;
writer<<seqN++<<seperator;
writer<<0<<seperator;//变压器区域
writer<<ite->fromNum<<seperator;
writer<<ite->toNum<<seperator;
writer<<ite->tf->r<<seperator;
writer<<ite->tf->x<<seperator;
writer<<ite->tf->ratio<<seperator;
writer<<1<<seperator;
writer<<1<<seperator;
writer<<1<<seperator;
writer<<endLine;
//保存接地支路
groudBranch.push_back(CIMExporter::GroundBranch(ite->fromNum, ite->tf->g1,ite->tf->b1));//都只用g1,b1的数据
LoadMapping loadMapping;
QVector<QSharedPointer<LoadInfo> > vecLoadInfo=loadMapping.getSubstationLoad(sub->getID());
foreach(QSharedPointer<LoadInfo> p,vecLoadInfo)
{
QFileInfo targetBasename(p->getLoadPath());
// std::cout<<"search for "<<targetBasename.baseName().toLocal8Bit().data()<<std::endl;
if( baseNames.contains( targetBasename.baseName()) and !usedLoad.contains(targetBasename.baseName()))
{
// std::cout<<targetBasename.baseName().toLocal8Bit().data()<<" used "<<std::endl;
usedLoad<<targetBasename.baseName();
//保存节点注入功率
nodePQ.push_back(CIMExporter::NodePQ(ite->toNum,p->get3PhP(),p->get3PhQ()));
// writer<<"type"<<"\t";
// writer<<ite->id<<"\t";
// writer<<tf->getMVA()<<"\r\n";
//加到LoadExport中
LoadExporter loadExporter;
loadExporter.add(targetBasename.baseName(),p);
break;
}
}
}
writer<<0<<endLine;//数据间隔
writer<<0<<endLine;//数据间隔
seqN=1;
foreach(CIMExporter::GroundBranch gb,groudBranch)
{
writer<<seqN++<<seperator;
writer<<gb.nodeNum<<seperator;
writer<<gb.g<<seperator;
writer<<gb.b<<seperator;
writer<<endLine;
}
writer<<0<<endLine;//数据间隔
writer<<0<<endLine;//数据间隔
writer<<0<<endLine;//数据间隔
//列出DG
// writer<<QStringLiteral("分布式电源")<<"\r\n";
for(QList<DGStru>::iterator ite=this->dg.begin();
ite!=this->dg.end();
ite++)
{
//保存到节点注入功率中
nodePQ.push_back(CIMExporter::NodePQ(ite->toNum,-ite->dg->getPG(0.95)/1000,-ite->dg->getQG(0.95)/1000) );//capapcity的单位是kVA
// writer<<ite->fromNum<<"\t";
// writer<<ite->toNum<<"\t";
// writer<<ite->dg->capacity<<"\r\n";
}
//iPso 开始输出注入功率
CIMExporter::NodePQ *nodePQPointer=new CIMExporter::NodePQ[this->number.keys().length()];
foreach(CIMExporter::NodePQ n,nodePQ)
{
int nodeNum=n.nodeNum;
if(nodeNum>this->number.keys().length())
{
std::cout<<"number of nodePQ is beyond node number."<<std::endl;
break;
}
nodePQPointer[nodeNum-1]=n;
}
seqN=1;
for(int i=0;i<this->number.keys().length();i++)
{
writer<<seqN<<seperator;
writer<<-1<<seperator;
writer<<seqN++<<seperator;
writer<<10<<seperator;
writer<<0<<seperator;
writer<<0<<seperator;
writer<<nodePQPointer[i].P<<seperator;
writer<<nodePQPointer[i].Q<<seperator;
writer<<1<<seperator;
writer<<0<<seperator;
writer<<endLine;
}
writer<<0<<endLine;//数据间隔
writer<<1<< seperator<<1<< seperator<<balanceNum<< seperator<<1<< seperator<< -100<< seperator<<100<< seperator<<0<< seperator<<0<< seperator<<0<< seperator<<0<< seperator;
writer<<endLine;
writer<<0<<endLine;//数据间隔
writer<<0<<endLine;//数据间隔
writer<<1<< seperator<<1<< seperator<<balanceNum<<seperator<<1<< seperator<<1.05<< seperator<< -100<< seperator<<100<< seperator<<0<< seperator<<0<< seperator<<0<< seperator<<0<< seperator;
writer<<endLine;
writer<<0<<endLine;//数据间隔
writer<<0<<endLine;//数据间隔
writer<<1<< seperator<<balanceNum<< seperator<<0.999<< seperator<<1.001<<seperator;
writer<<endLine;
//接着13个0
writer<<0<<endLine;//数据间隔
writer<<0<<endLine;//数据间隔
writer<<0<<endLine;//数据间隔
writer<<0<<endLine;//数据间隔
writer<<0<<endLine;//数据间隔
writer<<0<<endLine;//数据间隔
writer<<0<<endLine;//数据间隔
writer<<0<<endLine;//数据间隔
writer<<0<<endLine;//数据间隔
writer<<0<<endLine;//数据间隔
writer<<0<<endLine;//数据间隔
writer<<0<<endLine;//数据间隔
writer<<0<<endLine;//数据间隔
//列出没有用的负荷文件
foreach(QString name, baseNames)
{
if(!usedLoad.contains(name))
{
LoadMatchException except;
if(!except.contains(name))
{
std::cout<<name.toLocal8Bit().data()<<"not used"<<std::endl;
}
else
{
std::cout<<name.toLocal8Bit().data()<<"not used but excepted."<<std::endl;
}
}
}
this->topologyTest();
fd.close();
}
}
template<typename T>
void CIMExporter::idToNumber(QList<T> &s)//把所有元件的标识进行编号
{
for(typename QList<T>::iterator ite=s.begin();
ite!=s.end();
ite++
)
{
if(ite->dispose)
{
// std::cout<<ite->id.toStdString()<<" dispose"<<std::endl;
continue;
}
T _t=*ite;
_t.fromNum=this->numberIt(_t.fromID);
_t.toNum=this->numberIt(_t.toID);
// std::cout<<"id "<<_t.id.toStdString()<<" "<<_t.fromNum<<" "<<_t.toNum<<std::endl;
*ite=_t;
}
}
int CIMExporter::numberIt(const QString& id)
{
if(this->number.contains(id))
{
return this->number.value(id);
}
else
{
int n=this->number.keys().length()+1;
this->number[id]=n;
// std::cout<<id.toStdString()<<" "<<n<<std::endl;
return n;
}
}
bool CIMExporter::topologyTest()
{
//检查一下拓扑关系
QList<QPair<int,int> > linkage;
for(QList<LineStru>::iterator ite=this->line.begin();
ite!=this->line.end();
ite++)
{
if(ite->dispose)
{
continue;
}
linkage.push_back(QPair<int,int>(ite->fromNum,ite->toNum));
}
for(QList<SwitchStru>::iterator ite=this->sw.begin();
ite!=this->sw.end();
ite++)
{
if(ite->dispose)
{
continue;
}
linkage.push_back(QPair<int,int>(ite->fromNum,ite->toNum));
}
for(QList<TransformerStru>::iterator ite=this->tf.begin();
ite!=this->tf.end();
ite++)
{
if(ite->dispose)
{
continue;
}
linkage.push_back(QPair<int,int>(ite->fromNum,ite->toNum));
}
for(QList<DGStru>::iterator ite=this->dg.begin();
ite!=this->dg.end();
ite++)
{
if(ite->dispose)
{
continue;
}
linkage.push_back(QPair<int,int>(ite->fromNum,ite->toNum));
}
TopologyTest tpTest(this->number.keys().length());
if(tpTest.start(linkage))
{
std::cout<<"topoloty ok!"<<std::endl;
return true;
}else
{
std::cout<<"not ok topology"<<std::endl;
return false;
}
}