cimforreduceloss/testHasttable/cimexporter.cpp

454 lines
15 KiB
C++
Raw Normal View History

#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;
// writer<<"type"<<"\t";
// writer<<ite->id<<"\t";
// writer<<0<<"\r\n";
}
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;
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();
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->toNum, ite->tf->g1,ite->tf->b1));//都只用g1,b1的数据
//保存节点注入功率
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->capacity,-ite->dg->capacity) );
// 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);
*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;
}
}