Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SP_Ph1_Transformer3W model #30

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions Examples/Cxx/CIM/Slack_Trafo3W_Gen_Load.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/* Copyright 2017-2020 Institute for Automation of Complex Power Systems,
* EONERC, RWTH Aachen University
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*********************************************************************************/

#include <cps/CIM/Reader.h>
#include <DPsim.h>

using namespace std;
using namespace DPsim;
using namespace CPS;
using namespace CPS::CIM;

/*
* This example runs the powerflow for the CIGRE MV benchmark system (neglecting the tap changers of the transformers)
*/
int main(int argc, char** argv) {

// Find CIM files
std::list<fs::path> filenames;
if (argc <= 1) {
filenames = DPsim::Utils::findFiles({
"Slack_Trafo3W_PowerFlow_EQ.xml",
"Slack_Trafo3W_PowerFlow_TP.xml",
"Slack_Trafo3W_PowerFlow_SV.xml",
"Slack_Trafo3W_PowerFlow_SSH.xml"
}, "build/_deps/cim-data-src/BasicGrids/PowerFactory/Slack_Trafo3W_PowerFlow", "CIMPATH");
}
else {
filenames = std::list<fs::path>(argv + 1, argv + argc);
}

String simName = "Trafo3W_PFSolver";
CPS::Real system_freq = 60;

CIM::Reader reader(simName, Logger::Level::debug, Logger::Level::off);
SystemTopology system = reader.loadCIM(
system_freq,
filenames,
CPS::Domain::SP,
CPS::PhaseType::Single,
CPS::GeneratorType::PVNode
);
system.renderToFile("build/_deps/cim-data-src/BasicGrids/PowerFactory/Slack_Trafo3W_PowerFlow/Trafo3W_PowerFlowTest.svg");

auto logger = DPsim::DataLogger::make(simName);
for (auto node : system.mNodes)
{
logger->addAttribute(node->name() + ".V", node->attribute("v"));
}

Simulation sim(simName, Logger::Level::debug);
sim.setSystem(system);
sim.setTimeStep(1);
sim.setFinalTime(1);
sim.setDomain(Domain::SP);
sim.setSolverType(Solver::Type::NRP);
sim.doInitFromNodesAndTerminals(true);
sim.addLogger(logger);

sim.run();

return 0;
}
1 change: 1 addition & 0 deletions Examples/Cxx/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ if(WITH_CIM)

# PF(Power Flow) example
CIM/Slack_Trafo_Load.cpp
CIM/Slack_Trafo3W_Gen_Load.cpp
CIM/Slack_TrafoTapChanger_Load.cpp
CIM/CIGRE_MV_PowerFlowTest.cpp
CIM/CIGRE_MV_PowerFlowTest_LoadProfiles.cpp
Expand Down
2 changes: 2 additions & 0 deletions Include/dpsim/PFSolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ namespace DPsim {
CPS::SystemTopology mSystem;
/// Vector of transformer components
std::vector<std::shared_ptr<CPS::SP::Ph1::Transformer>> mTransformers;
/// Vector of transformer components
std::vector<std::shared_ptr<CPS::SP::Ph1::Transformer3W>> mTransformers3W;
/// Vector of solid state transformer components
std::vector<std::shared_ptr<CPS::SP::Ph1::SolidStateTransformer>> mSolidStateTransformers;
/// Vector of synchronous generator components
Expand Down
34 changes: 33 additions & 1 deletion Source/PFSolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ void PFSolver::initialize(){
mLoads.push_back(load);
else if (std::shared_ptr<CPS::SP::Ph1::Transformer> trafo = std::dynamic_pointer_cast<CPS::SP::Ph1::Transformer>(comp))
mTransformers.push_back(trafo);
else if (std::shared_ptr<CPS::SP::Ph1::Transformer3W> trafo3W = std::dynamic_pointer_cast<CPS::SP::Ph1::Transformer3W>(comp))
mTransformers3W.push_back(trafo3W);
else if (std::shared_ptr<CPS::SP::Ph1::PiLine> line = std::dynamic_pointer_cast<CPS::SP::Ph1::PiLine>(comp))
mLines.push_back(line);
else if (std::shared_ptr<CPS::SP::Ph1::NetworkInjection> extnet = std::dynamic_pointer_cast<CPS::SP::Ph1::NetworkInjection>(comp))
Expand Down Expand Up @@ -86,6 +88,9 @@ void PFSolver::initializeComponents(){
for(auto trans : mTransformers) {
trans->calculatePerUnitParameters(mBaseApparentPower, mSystem.mSystemOmega);
}
for(auto trans3w : mTransformers3W) {
trans3w->calculatePerUnitParameters(mBaseApparentPower, mSystem.mSystemOmega);
}
for(auto shunt : mShunts) {
shunt->calculatePerUnitParameters(mBaseApparentPower, mSystem.mSystemOmega);
}
Expand Down Expand Up @@ -113,6 +118,16 @@ void PFSolver::setBaseApparentPower() {
if (trafo->attribute<Real>("S")->get() > maxPower)
maxPower = trafo->attribute<Real>("S")->get();
}
else if (!mTransformers3W.empty()) {
for (auto trafo3w : mTransformers3W){
if (trafo3w->attribute<Real>("S1")->get() > maxPower)
maxPower = trafo3w->attribute<Real>("S1")->get();
if (trafo3w->attribute<Real>("S2")->get() > maxPower)
maxPower = trafo3w->attribute<Real>("S2")->get();
if (trafo3w->attribute<Real>("S3")->get() > maxPower)
maxPower = trafo3w->attribute<Real>("S3")->get();
}
}
if (maxPower != 0.)
mBaseApparentPower = pow(10, 1 + floor(log10(maxPower)));
else
Expand Down Expand Up @@ -196,6 +211,11 @@ void PFSolver::determinePFBusType() {
mSLog->debug("{}: VD, PV and PQ type component connect -> set as VD bus", node->name());
mVDBusIndices.push_back(node->matrixNodeIndex());
mVDBuses.push_back(node);
} // VD and PQ type component connect -> set as VD bus
else if (!connectedPV && connectedPQ && connectedVD) {
mSLog->debug("{}: VD and PQ type component connect -> set as VD bus", node->name());
mVDBusIndices.push_back(node->matrixNodeIndex());
mVDBuses.push_back(node);
}
else {
std::stringstream ss;
Expand Down Expand Up @@ -263,13 +283,25 @@ void PFSolver::composeAdmittanceMatrix() {
}
trans->pfApplyAdmittanceMatrixStamp(mY);
}
for(auto trans3W : mTransformers3W) {
//to check if this transformer could be ignored
if (trans3W->attribute("R1") == 0 && trans3W->attribute("L1") == 0 &&
trans3W->attribute("R2") == 0 && trans3W->attribute("L2") == 0 &&
trans3W->attribute("R3") == 0 && trans3W->attribute("L3") == 0) {
mSLog->info("{} {} ignored for R = 0 and L = 0 in all windings", trans3W->type(), trans3W->name());
continue;
}
trans3W->pfApplyAdmittanceMatrixStamp(mY);
}
for(auto shunt : mShunts) {
shunt->pfApplyAdmittanceMatrixStamp(mY);
}
}
if(mLines.empty() && mTransformers.empty()) {
if(mLines.empty() && mTransformers.empty() && mTransformers3W.empty()) {
throw std::invalid_argument("There are no bus");
}

mSLog->info("#### System matrix:\n{}", mY);
}

CPS::Real PFSolver::G(int i, int j) {
Expand Down
48 changes: 45 additions & 3 deletions Source/PFSolverPowerPolar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,11 +305,38 @@ void PFSolverPowerPolar::setSolution() {
baseVoltage_ = trans->attribute<CPS::Real>("nominal_voltage_end2")->get();
break;
}
else if (std::shared_ptr<CPS::SP::Ph1::SynchronGenerator> gen = std::dynamic_pointer_cast<CPS::SP::Ph1::SynchronGenerator>(comp)) {
baseVoltage_ =gen->attribute<CPS::Real>("base_Voltage")->get();
}
else if (std::shared_ptr<CPS::SP::Ph1::Transformer3W> trans3W = std::dynamic_pointer_cast<CPS::SP::Ph1::Transformer3W>(comp)) {
if (trans3W->terminal(0)->node()->name() == node->name()){
baseVoltage_ = trans3W->attribute<CPS::Real>("nominal_voltage_end1")->get();
break;
}
else if (trans3W->terminal(1)->node()->name() == node->name()){
baseVoltage_ = trans3W->attribute<CPS::Real>("nominal_voltage_end2")->get();
break;
}
else if (trans3W->terminal(2)->node()->name() == node->name()){
baseVoltage_ = trans3W->attribute<CPS::Real>("nominal_voltage_end3")->get();
break;
}
else
}
else if (std::shared_ptr<CPS::SP::Ph1::SynchronGenerator> gen = std::dynamic_pointer_cast<CPS::SP::Ph1::SynchronGenerator>(comp)) {
baseVoltage_ = gen->attribute<CPS::Real>("base_Voltage")->get();
break;
}
else if (std::shared_ptr<CPS::SP::Ph1::NetworkInjection> extnet = std::dynamic_pointer_cast<CPS::SP::Ph1::NetworkInjection>(comp)) {
baseVoltage_ = extnet->attribute<CPS::Real>("base_Voltage")->get();
break;
}
else if (std::shared_ptr<CPS::SP::Ph1::Shunt> shunt = std::dynamic_pointer_cast<CPS::SP::Ph1::Shunt>(comp)) {
baseVoltage_ = shunt->attribute<CPS::Real>("base_Voltage")->get();
break;
}
else if (std::shared_ptr<CPS::SP::Ph1::Load> load = std::dynamic_pointer_cast<CPS::SP::Ph1::Load>(comp)) {
baseVoltage_ = load->attribute<CPS::Real>("V_nom")->get();
break;
}
else {
mSLog->warn("Unable to get base voltage at {}", node->name());
}
}
Expand Down Expand Up @@ -340,6 +367,17 @@ void PFSolverPowerPolar::calculateBranchFlow() {
VectorComp flow_on_branch = v.array()*current.conjugate().array();
trafo->updateBranchFlow(current, flow_on_branch);
}
for (auto trafo3W : mTransformers3W) {
VectorComp v(3);
v(0) = sol_V_complex.coeff(trafo3W->node(0)->matrixNodeIndex());
v(1) = sol_V_complex.coeff(trafo3W->node(1)->matrixNodeIndex());
v(2) = sol_V_complex.coeff(trafo3W->node(2)->matrixNodeIndex());
/// I = Y * V
VectorComp current = trafo3W->Y_element() * v;
/// pf on branch [S_01; S_10] = [V_0 * conj(I_0); V_1 * conj(I_1)]
VectorComp flow_on_branch = v.array()*current.conjugate().array();
trafo3W->updateBranchFlow(current, flow_on_branch);
}
}

void PFSolverPowerPolar::calculateNodalInjection() {
Expand All @@ -358,6 +396,10 @@ void PFSolverPowerPolar::calculateNodalInjection() {
trafo->storeNodalInjection(sol_S_complex.coeff(node->matrixNodeIndex()));
break;
}
else if (std::shared_ptr<CPS::SP::Ph1::Transformer3W> trafo3W = std::dynamic_pointer_cast<CPS::SP::Ph1::Transformer3W>(comp)) {
trafo3W->storeNodalInjection(sol_S_complex.coeff(node->matrixNodeIndex()));
break;
}
}
}
}
Expand Down
53 changes: 53 additions & 0 deletions models/Include/cps/Base/Base_Ph1_Transformer.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,59 @@ namespace Ph1 {
mInductance = inductance;
}
};

class Transformer3W {
protected:
/// Nominal voltage of primary side
Real mNominalVoltageEnd1;
/// Nominal voltage of secondary side
Real mNominalVoltageEnd2;
/// Nominal voltage of secondary side
Real mNominalVoltageEnd3;
/// Transformer ratio primary side
Complex mRatio1;
/// Transformer ratio secondary side
Complex mRatio2;
/// Transformer ratio tetrary side
Complex mRatio3;
/// Resistance [Ohm] primary side
Real mResistance1;
/// Resistance [Ohm] secondary side
Real mResistance2;
/// Resistance [Ohm] tetrary side
Real mResistance3;
/// Inductance [H] primary side
Real mInductance1;
/// Inductance [H] secondary side
Real mInductance2;
/// Inductance [H] tetrary side
Real mInductance3;

public:
///
void setParameters(
Real nomVoltageEnd1, Real nomVoltageEnd2, Real nomVoltageEnd3,
Real ratioAbs1, Real ratioAbs2, Real ratioAbs3,
Real ratioPhase1, Real ratioPhase2, Real ratioPhase3,
Real resistance1, Real resistance2, Real resistance3,
Real inductance1, Real inductance2, Real inductance3
) {

mNominalVoltageEnd1 = nomVoltageEnd1;
mNominalVoltageEnd2 = nomVoltageEnd2;
mNominalVoltageEnd3 = nomVoltageEnd3;
mRatio1 = std::polar<Real>(ratioAbs1, ratioPhase1);
mRatio2 = std::polar<Real>(ratioAbs2, ratioPhase2);
mRatio3 = std::polar<Real>(ratioAbs3, ratioPhase3);
mResistance1 = resistance1;
mResistance2 = resistance2;
mResistance3 = resistance3;
mInductance1 = inductance1;
mInductance2 = inductance2;
mInductance3 = inductance3;
}
};

}
}
}
3 changes: 3 additions & 0 deletions models/Include/cps/CIM/Reader.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ namespace CIMPP {
class ExternalNetworkInjection;
class EnergyConsumer;
class PowerTransformer;
class PowerTransformer3W;
class EquivalentShunt;
class LinearShuntCompensator;
class TopologicalNode;
class ConductingEquipment;
};
Expand Down Expand Up @@ -147,6 +149,7 @@ namespace CIM {
TopologicalPowerComp::Ptr mapExternalNetworkInjection(CIMPP::ExternalNetworkInjection* extnet);
/// Returns a shunt
TopologicalPowerComp::Ptr mapEquivalentShunt(CIMPP::EquivalentShunt *shunt);
TopologicalPowerComp::Ptr mapEquivalentShunt(CIMPP::LinearShuntCompensator *shunt);

// #### Helper Functions ####
/// Determine base voltage associated with object
Expand Down
1 change: 1 addition & 0 deletions models/Include/cps/Components.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <cps/SP/SP_Ph1_PiLine.h>
#include <cps/SP/SP_Ph1_Shunt.h>
#include <cps/SP/SP_Ph1_Transformer.h>
#include <cps/SP/SP_Ph1_Transformer3W.h>
#include <cps/SP/SP_Ph1_SolidStateTransformer.h>
#include <cps/SP/SP_Ph1_Load.h>
#include <cps/SP/SP_Ph1_Switch.h>
Expand Down
Loading