Commit 3c11e0c0 authored by Markus Mirz's avatar Markus Mirz
Browse files

updated components and CIM reader

parent 167d6cf0
......@@ -23,8 +23,6 @@
#include <iostream>
#include "SynchronGenUnitTest.h"
#include "ReferenceCircuits.h"
#include "ShmemTest.h"
#include "CIMTest.h"
......
......@@ -99,7 +99,7 @@ ElementPtr CIMReader::mapACLineSegment(ACLineSegment* line) {
mLogger->Log(LogLevel::INFO) << "Create RxLine " << line->name << " node1=" << nodes[0] << " node2=" << nodes[1]
<< " R=" << r << " X=" << x << std::endl;
return make_shared<RxLine>(line->name, nodes[0], nodes[1], r, x/mFrequency);
return make_shared<RxLineDP>(line->name, nodes[0], nodes[1], r, x/mFrequency);
}
void CIMReader::mapAsynchronousMachine(AsynchronousMachine* machine) {
......@@ -126,9 +126,13 @@ ElementPtr CIMReader::mapExternalNetworkInjection(ExternalNetworkInjection* inj)
mLogger->Log(LogLevel::ERROR) << "ExternalNetworkInjection " << inj->mRID << " has no associated SvVoltage, ignoring" << std::endl;
return nullptr;
}
Real voltAbs = volt->v.value;
Real voltPhase = volt->angle.value;
Complex initVoltage = std::polar(voltAbs, voltPhase * PI / 180);
mLogger->Log(LogLevel::INFO) << "IdealVoltageSource " << inj->name << " rid=" << inj->mRID << " node1=" << node
<< " V=" << volt->v.value << "<" << volt->angle.value << std::endl;
return make_shared<IdealVoltageSource>(inj->name, node, 0, Complex(volt->v.value, volt->angle.value*PI/180));
<< " V=" << voltAbs << "<" << voltPhase << std::endl;
return make_shared<IdealVoltageSource>(inj->name, node, 0, initVoltage);
}
ElementPtr CIMReader::mapPowerTransformer(PowerTransformer* trans) {
......@@ -189,16 +193,18 @@ ElementPtr CIMReader::mapSynchronousMachine(SynchronousMachine* machine) {
mLogger->Log(LogLevel::WARN) << "SynchronousMachine " << machine->mRID << " has no associated SvVoltage, ignoring" << std::endl;
return nullptr;
}
mLogger->Log(LogLevel::INFO) << "VoltSourceRes " << machine->name << " rid=" << machine->mRID << " node=" << node
<< " V=" << volt->v.value << "<" << volt->angle.value << std::endl;
Real voltAbs = volt->v.value;
Real voltPhase = volt->angle.value;
Complex initVoltage = std::polar(voltAbs, voltPhase * PI / 180);
// Apply unit multipliers according to CGMES convetions.
volt->v.value = CIMReader::unitValue(volt->v.value, UnitMultiplier::k);
// TODO is it appropiate to use this resistance here
mLogger->Log(LogLevel::INFO) << "Create IdealVoltageSource " << machine->name << " node=" << node
<< " V=" << volt->v.value << "<" << volt->angle.value << std::endl;
return make_shared<IdealVoltageSource>(machine->name, node, 0, Complex(volt->v.value, volt->angle.value*PI/180));
<< " V=" << voltAbs << "<" << voltPhase << std::endl;
return make_shared<IdealVoltageSource>(machine->name, node, 0, initVoltage);
}
ElementPtr CIMReader::mapComponent(BaseClass* obj) {
......
......@@ -42,37 +42,51 @@ using namespace IEC61970::Base::Wires;
namespace DPsim {
class CIMReader {
private:
// CIM logger
/// CIM logger
Logger* mLogger;
// Model from CIM++
/// Model from CIM++
CIMModel mModel;
// All components after mapping
/// All components after mapping
ElementList mComponents;
// System frequency (has to be given to convert between reactances
// in CIM and inductances used inside the simulation)
/// System frequency (has to be given to convert between reactances
/// in CIM and inductances used inside the simulation)
Real mFrequency;
// Maps the RID of a topological node to its simulation matrix index
// as given in the component constructors (1 for the first node).
/// Maps the RID of a topological node to its simulation matrix index
/// as given in the component constructors (1 for the first node).
std::map<String, Int> mTopNodes;
// Maps the RID of a ConductingEquipment to a list of nodes as given in
// the component constructors.
/// Maps the RID of a ConductingEquipment to a list of nodes as given in
/// the component constructors.
std::map<String, std::vector<Int>> mEqNodeMap;
// SvVoltage, if present, for each node (indexed starting with 0!)
/// SvVoltage, if present, for each node (indexed starting with 0!)
SvVoltage **mVoltages;
// Maps the RID of a Terminal to its associated power flow
/// Maps the RID of a Terminal to its associated power flow
std::map<String, SvPowerFlow*> mPowerFlows;
// Number of ideal voltage sources
/// Number of ideal voltage sources
Int mNumVoltageSources;
ElementPtr mapComponent(BaseClass* obj);
/// Returns an RX-Line.
/// The voltage should be given in kV and the angle in degree.
/// TODO: Introduce different models such as PI and wave model.
ElementPtr mapACLineSegment(ACLineSegment* line);
void mapAsynchronousMachine(AsynchronousMachine* machine);
/// Returns an PQload with voltage setting according to load flow data.
/// Currently the only option is to create an RL-load.
/// The voltage should be given in kV and the angle in degree.
/// TODO: Introduce different load models here.
void mapEnergyConsumer(EnergyConsumer* con);
void mapEquivalentInjection(EquivalentInjection* inj);
ElementPtr mapExternalNetworkInjection(ExternalNetworkInjection* inj);
ElementPtr mapPowerTransformer(PowerTransformer *trans);
/// Returns an IdealVoltageSource with voltage setting according to load flow data
/// at machine terminals. The voltage should be given in kV and the angle in degree.
/// TODO: Introduce real synchronous generator models here.
ElementPtr mapSynchronousMachine(SynchronousMachine* machine);
/// Returns an PQload with voltage setting according to load flow data.
/// Currently the only option is to create an RL-load.
/// The voltage should be given in kV and the angle in degree.
/// TODO: Introduce real PQload model here.
ElementPtr newPQLoad(String rid, String name);
public:
CIMReader(Real om, Logger& logger);
......
......@@ -38,17 +38,13 @@ namespace DPsim {
protected:
/// Capacitance [F]
Real capacitance;
/// Real part of the voltage across the capacitor [V]
Real deltavr;
/// Imaginary part of the voltage across the capacitor [V]
Real deltavi;
/// Real and imaginary part of the current trough the capacitor [A]
/// Real and imaginary part of the current through the capacitor [A]
Real currr;
Real curri;
///Real and imaginary part of the DC equivalent current source [A]
Real cureqr;
Real cureqi;
......
......@@ -27,8 +27,7 @@ using namespace DPsim;
IdealTransformerDP::IdealTransformerDP(String name, Int node1, Int node2, Real ratioAbs, Real ratioPhase) : BaseComponent(name, node1, node2) {
mNumVirtualNodes = 1;
mVirtualNodes = { 0 };
mRatioRe = ratioAbs*cos(ratioPhase);
mRatioIm = ratioAbs*sin(ratioPhase);
mRatio = std::polar(ratioAbs, ratioPhase);
}
void IdealTransformerDP::applySystemMatrixStamp(SystemModel& system) {
......@@ -37,7 +36,7 @@ void IdealTransformerDP::applySystemMatrixStamp(SystemModel& system) {
system.setCompSystemMatrixElement(mVirtualNodes[0], mNode1, 1.0, 0);
}
if (mNode2 >= 0) {
system.setCompSystemMatrixElement(mNode2, mVirtualNodes[0], mRatioRe, mRatioIm);
system.setCompSystemMatrixElement(mVirtualNodes[0], mNode2, -mRatioRe, -mRatioIm);
system.setCompSystemMatrixElement(mNode2, mVirtualNodes[0], mRatio.real, mRatio.imag);
system.setCompSystemMatrixElement(mVirtualNodes[0], mNode2, -mRatio.real, -mRatio.imag);
}
}
......@@ -30,8 +30,8 @@ namespace DPsim {
/// Ideal transformer that is connected to ground
class IdealTransformerDP : public BaseComponent {
private:
Real mRatioRe;
Real mRatioIm;
/// Transformer ratio
Complex mRatio;
public:
IdealTransformerDP() { };
IdealTransformerDP(String name, Int node1, Int node2, Real ratioRe, Real ratioIm);
......
......@@ -40,26 +40,20 @@ void PQLoadDP::init(Real om, Real dt) {
mResistance = mSvVoltage*mSvVoltage*mActivePower/abs;
mConductance = 1.0 / mResistance;
mReactance = mSvVoltage*mSvVoltage*mReactivePower/abs;
mInductance = mReactance /om;
mInductance = mReactance / om;
inductor = std::make_shared<InductorDP>(mName + "_ind", mNode1, mNode2, mInductance);
resistor = std::make_shared<ResistorDP>(mName + "_res", mNode1, mNode2, mResistance);
inductor->init(om, dt);
resistor->init(om, dt);
}
void PQLoadDP::applySystemMatrixStamp(SystemModel& system) {
// powers / svvoltage might have changed, so update them
Real abs = mActivePower*mActivePower + mReactivePower*mReactivePower;
mResistance = mSvVoltage*mSvVoltage*mActivePower/abs;
mConductance = 1.0 / mResistance;
mReactance = mSvVoltage*mSvVoltage*mReactivePower/abs;
mInductance = mReactance /system.getOmega();
// Add resistive part to system matrix
resistor->applySystemMatrixStamp(system);
// Add inductive part to system matrix
inductor->applySystemMatrixStamp(system);
}
void PQLoadDP::step(SystemModel& system, Real time) {
......
......@@ -31,13 +31,18 @@ namespace DPsim {
// TODO currently modeled as an impedance, which obviously doesn't have a constant power characteristic
class PQLoadDP : public BaseComponent {
protected:
/// Active power [Watt]
Real mActivePower;
/// Reactive power [VAr]
Real mReactivePower;
/// Voltage [V]
Real mSvVoltage;
/// Resistance [Ohm]
Real mResistance;
/// Conductance [S]
Real mConductance;
/// Reactance [Ohm]
Real mReactance;
/// Inductance [H]
Real mInductance;
......
......@@ -24,7 +24,7 @@
using namespace DPsim;
RxLine::RxLine(String name, Int node1, Int node2, Real resistance, Real inductance, LineTypes type) : BaseComponent(name, node1, node2) {
RxLineDP::RxLineDP(String name, Int node1, Int node2, Real resistance, Real inductance, LineTypes type) : BaseComponent(name, node1, node2) {
mNumVirtualNodes = 1;
mVirtualNodes = { 0 };
mResistance = resistance;
......@@ -35,7 +35,7 @@ RxLine::RxLine(String name, Int node1, Int node2, Real resistance, Real inductan
attrMap["inductance"] = { AttrReal, &mInductance };
}
void RxLine::applySystemMatrixStamp(SystemModel& system) {
void RxLineDP::applySystemMatrixStamp(SystemModel& system) {
if (mType == LineTypes::RxLine2Node) {
Real a = system.getTimeStep() / (2 * mInductance);
Real b = system.getTimeStep()*system.getOmega() / 2;
......@@ -105,7 +105,7 @@ void RxLine::applySystemMatrixStamp(SystemModel& system) {
}
}
void RxLine::init(Real om, Real dt) {
void RxLineDP::init(Real om, Real dt) {
// Initialize internal state
mCurrRe = 0;
mCurrIm = 0;
......@@ -122,7 +122,7 @@ void RxLine::init(Real om, Real dt) {
cureqi_ind = 0;
}
void RxLine::step(SystemModel& system, Real time) {
void RxLineDP::step(SystemModel& system, Real time) {
if (mType == LineTypes::RxLine2Node) {
......@@ -160,7 +160,7 @@ void RxLine::step(SystemModel& system, Real time) {
}
}
void RxLine::postStep(SystemModel& system) {
void RxLineDP::postStep(SystemModel& system) {
if (mType == LineTypes::RxLine2Node) {
......@@ -229,6 +229,6 @@ void RxLine::postStep(SystemModel& system) {
}
}
Complex RxLine::getCurrent(SystemModel& system) {
Complex RxLineDP::getCurrent(SystemModel& system) {
return Complex(mCurrRe, mCurrIm);
}
......@@ -27,7 +27,7 @@
namespace DPsim {
class RxLine : public BaseComponent {
class RxLineDP : public BaseComponent {
protected:
Real mResistance;
Real mConductance;
......@@ -59,8 +59,8 @@ namespace DPsim {
Real curri_ind;
public:
RxLine() { };
RxLine(String name, Int node1, Int node2, Real resistance, Real inductance, LineTypes type = LineTypes::RxLine3Node);
RxLineDP() { };
RxLineDP(String name, Int node1, Int node2, Real resistance, Real inductance, LineTypes type = LineTypes::RxLine3Node);
void init(Real om, Real dt);
void applySystemMatrixStamp(SystemModel& system);
......
......@@ -25,22 +25,21 @@
using namespace DPsim;
TransformerDP::TransformerDP(String name, Int node1, Int node2, Real ratioAbs, Real ratioPhase, Real resistance, Real reactance) : BaseComponent(name, node1, node2) {
mRatioRe = ratioAbs*cos(ratioPhase);
mRatioIm = ratioAbs*sin(ratioPhase);
mRatioAbs = ratioAbs;
mRatioPhase = ratioPhase;
mRatio = std::polar(ratioAbs, ratioPhase);
mResistance = resistance;
mReactance = reactance;
if (resistance == 0) {
mNumVirtualNodes = 2;
}
else {
if (resistance > 0.000001) {
mNumVirtualNodes = 3;
mVirtualNodes = { 0, 0, 0 };
}
mVirtualNodes = { 0 };
}
void TransformerDP::init(Real om, Real dt) {
/*
Real abs = mActivePower*mActivePower + mReactivePower*mReactivePower;
mResistance = mSvVoltage*mSvVoltage*mActivePower / abs;
mConductance = 1.0 / mResistance;
mReactance = mSvVoltage*mSvVoltage*mReactivePower / abs;
......@@ -48,7 +47,8 @@ void TransformerDP::init(Real om, Real dt) {
inductor = std::make_shared<InductorDP>(mName + "_ind", mNode1, mNode2, mInductance);
resistor = std::make_shared<ResistorDP>(mName + "_res", mNode1, mNode2, mResistance);
*/
inductor->init(om, dt);
resistor->init(om, dt);
}
void TransformerDP::applySystemMatrixStamp(SystemModel& system) {
......
......@@ -24,6 +24,8 @@
#pragma once
#include "BaseComponent.h"
#include "RxLineDP.h"
#include "IdealTransformerDP.h"
#include "InductorDP.h"
namespace DPsim {
......@@ -31,16 +33,27 @@ namespace DPsim {
/// Transformer that includes an inductance and resistance
class TransformerDP : public BaseComponent {
private:
Real mRatioRe;
Real mRatioIm;
/// Transformer ratio
Complex mRatio;
Real mRatioAbs;
Real mRatioPhase;
/// Voltage [V]
Real mSvVoltage;
/// Resistance [Ohm]
Real mResistance;
/// Conductance [S]
Real mConductance;
/// Reactance [Ohm]
Real mReactance;
/// Inductance [H]
Real mInductance;
/// Internal ideal transformer
shared_ptr<IdealTransformerDP> mIdealTransformer;
/// Internal RX-line to model losses
shared_ptr<RxLineDP> mLine;
/// Internal inductor to model losses
shared_ptr<InductorDP> mInductor;
shared_ptr<InductorDP> inductor;
public:
TransformerDP() { };
TransformerDP(String name, Int node1, Int node2, Real ratioAbs, Real ratioPhase, Real resistance, Real inductance);
......
......@@ -143,7 +143,6 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\..\Examples\C++\CIMTest.h" />
<ClInclude Include="..\..\Examples\C++\ReferenceCircuits.h" />
<ClInclude Include="..\..\Examples\C++\ShmemTest.h" />
<ClInclude Include="..\..\Examples\C++\SynchronGenUnitTest.h" />
<ClInclude Include="..\..\Source\CIMReader.h" />
......
......@@ -69,9 +69,6 @@
<ClInclude Include="..\..\Source\CIMReader.h">
<Filter>Headerdateien</Filter>
</ClInclude>
<ClInclude Include="..\..\Examples\C++\ReferenceCircuits.h">
<Filter>Headerdateien\Examples</Filter>
</ClInclude>
<ClInclude Include="..\..\Examples\C++\ShmemTest.h">
<Filter>Headerdateien\Examples</Filter>
</ClInclude>
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment