Commit 833df060 authored by Jan Dinkelbach's avatar Jan Dinkelbach Committed by Markus Mirz
Browse files

refactor vsi in sp1ph and add tests for slack line vsi example

parent 05ab0722
......@@ -41,6 +41,7 @@ set(CIRCUIT_SOURCES
# SP examples
Circuits/SP_Circuits.cpp
Circuits/SP_PiLine.cpp
Circuits/SP_Slack_PiLine_VSI_with_PF_Init.cpp
# Combined EMT/DP/SP examples
Circuits/EMT_DP_SP_Slack.cpp
......
......@@ -115,7 +115,7 @@ int main(int argc, char* argv[]) {
pv->setParameters(scenario.systemOmega, scenario.pvNominalVoltage, scenario.pvNominalActivePower, scenario.pvNominalReactivePower);
pv->setControllerParameters(cmdScaleP*scenario.KpPLL, cmdScaleI*scenario.KiPLL, cmdScaleP*scenario.KpPowerCtrl, cmdScaleI*scenario.KiPowerCtrl, cmdScaleP*scenario.KpCurrCtrl, cmdScaleI*scenario.KiCurrCtrl, scenario.OmegaCutoff);
pv->setFilterParameters(scenario.Lf, scenario.Cf, scenario.Rf, scenario.Rc);
pv->setTransformerParameters(scenario.systemNominalVoltage, scenario.pvNominalVoltage, scenario.transformerNominalPower, scenario.systemNominalVoltage/scenario.pvNominalVoltage, 0, 0, scenario.transformerInductance, scenario.systemOmega);
pv->setTransformerParameters(scenario.systemNominalVoltage, scenario.pvNominalVoltage, scenario.systemNominalVoltage/scenario.pvNominalVoltage, 0, 0, scenario.transformerInductance);
pv->setInitialStateValues(scenario.pvNominalActivePower, scenario.pvNominalReactivePower, scenario.phi_dInit, scenario.phi_qInit, scenario.gamma_dInit, scenario.gamma_qInit);
pv->withControl(pvWithControl);
......
......@@ -110,7 +110,7 @@ void simTrafoSP1ph() {
// Parameters
vs->setParameters(CPS::Math::polar(voltageHVSide, 0));
trafo->setParameters(voltageHVSide, voltageMVSide, 50e6, ratio, 0, trafoResistance, trafoInductance, 2.0*PI*50.0);
trafo->setParameters(voltageHVSide, voltageMVSide, ratio, 0, trafoResistance, trafoInductance);
loadRes->setParameters(loadResistanceMVSide);
// Define system topology
......
/* Copyright 2017-2020 Institute for Automation of Complex Power Systems,
* EONERC, RWTH Aachen University
* DPsim
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************************/
#include <DPsim.h>
#include "../Examples.h"
using namespace DPsim;
using namespace CPS;
using namespace CPS::CIM;
int main(int argc, char* argv[]) {
Examples::SGIB::ScenarioConfig scenario;
Real finalTime = 2;
Real timeStep = 0.0001;
String simName = "SP_Slack_PiLine_VSI_with_PF_Init";
Bool pvWithControl = true;
Real cmdScaleP = 1.0;
Real cmdScaleI = 1.0;
CommandLineArgs args(argc, argv);
if (argc > 1) {
timeStep = args.timeStep;
finalTime = args.duration;
if (args.name != "dpsim")
simName = args.name;
if (args.options_bool.find("control") != args.options_bool.end())
pvWithControl = args.options_bool["control"];
if (args.options.find("scale_kp") != args.options.end())
cmdScaleI = args.options["scale_kp"];
if (args.options.find("scale_ki") != args.options.end())
cmdScaleI = args.options["scale_ki"];
}
// ----- POWERFLOW FOR INITIALIZATION -----
Real timeStepPF = finalTime;
Real finalTimePF = finalTime+timeStepPF;
String simNamePF = simName+"_PF";
Logger::setLogDir("logs/" + simNamePF);
// Components
auto n1PF = SimNode<Complex>::make("n1", PhaseType::Single);
auto n2PF = SimNode<Complex>::make("n2", PhaseType::Single);
auto extnetPF = SP::Ph1::NetworkInjection::make("Slack", Logger::Level::debug);
extnetPF->setParameters(scenario.systemNominalVoltage);
extnetPF->setBaseVoltage(scenario.systemNominalVoltage);
extnetPF->modifyPowerFlowBusType(PowerflowBusType::VD);
auto linePF = SP::Ph1::PiLine::make("PiLine", Logger::Level::debug);
linePF->setParameters(scenario.lineResistance, scenario.lineInductance, scenario.lineCapacitance);
linePF->setBaseVoltage(scenario.systemNominalVoltage);
auto loadPF = SP::Ph1::Load::make("Load", Logger::Level::debug);
loadPF->setParameters(-scenario.pvNominalActivePower, -scenario.pvNominalReactivePower, scenario.systemNominalVoltage);
loadPF->modifyPowerFlowBusType(PowerflowBusType::PQ);
// Topology
extnetPF->connect({ n1PF });
linePF->connect({ n1PF, n2PF });
loadPF->connect({ n2PF });
auto systemPF = SystemTopology(50,
SystemNodeList{n1PF, n2PF},
SystemComponentList{extnetPF, linePF, loadPF});
// Logging
auto loggerPF = DataLogger::make(simNamePF);
loggerPF->addAttribute("v1", n1PF->attribute("v"));
loggerPF->addAttribute("v2", n2PF->attribute("v"));
// Simulation
Simulation simPF(simNamePF, Logger::Level::debug);
simPF.setSystem(systemPF);
simPF.setTimeStep(timeStepPF);
simPF.setFinalTime(finalTimePF);
simPF.setDomain(Domain::SP);
simPF.setSolverType(Solver::Type::NRP);
simPF.doPowerFlowInit(false);
simPF.addLogger(loggerPF);
simPF.run();
// ----- DYNAMIC SIMULATION -----
Real timeStepSP = timeStep;
Real finalTimeSP = finalTime+timeStepSP;
String simNameSP = simName+"_SP";
Logger::setLogDir("logs/" + simNameSP);
// Components
auto n1SP = SimNode<Complex>::make("n1", PhaseType::Single);
auto n2SP = SimNode<Complex>::make("n2", PhaseType::Single);
auto extnetSP = SP::Ph1::NetworkInjection::make("Slack", Logger::Level::debug);
extnetSP->setParameters(Complex(scenario.systemNominalVoltage,0));
auto lineSP = SP::Ph1::PiLine::make("PiLine", Logger::Level::debug);
lineSP->setParameters(scenario.lineResistance, scenario.lineInductance, scenario.lineCapacitance);
auto pv = SP::Ph1::AvVoltageSourceInverterDQ::make("pv", "pv", Logger::Level::debug, true);
pv->setParameters(scenario.systemOmega, scenario.pvNominalVoltage, scenario.pvNominalActivePower, scenario.pvNominalReactivePower);
pv->setControllerParameters(cmdScaleP*scenario.KpPLL, cmdScaleI*scenario.KiPLL, cmdScaleP*scenario.KpPowerCtrl, cmdScaleI*scenario.KiPowerCtrl, cmdScaleP*scenario.KpCurrCtrl, cmdScaleI*scenario.KiCurrCtrl, scenario.OmegaCutoff);
pv->setFilterParameters(scenario.Lf, scenario.Cf, scenario.Rf, scenario.Rc);
pv->setTransformerParameters(scenario.systemNominalVoltage, scenario.pvNominalVoltage, scenario.systemNominalVoltage/scenario.pvNominalVoltage, 0, 0, scenario.transformerInductance);
pv->setInitialStateValues(scenario.pvNominalActivePower, scenario.pvNominalReactivePower, scenario.phi_dInit, scenario.phi_qInit, scenario.gamma_dInit, scenario.gamma_qInit);
pv->withControl(pvWithControl);
// Topology
extnetSP->connect({ n1SP });
lineSP->connect({ n1SP, n2SP });
pv->connect({ n2SP });
auto systemSP = SystemTopology(50,
SystemNodeList{n1SP, n2SP},
SystemComponentList{extnetSP, lineSP, pv});
// Initialization of dynamic topology with values from powerflow
CIM::Reader reader(simNameSP, Logger::Level::debug);
reader.initDynamicSystemTopologyWithPowerflow(systemPF, systemSP);
// Logging
auto loggerSP = DataLogger::make(simNameSP);
loggerSP->addAttribute("v1", n1SP->attribute("v"));
loggerSP->addAttribute("v2", n2SP->attribute("v"));
loggerSP->addAttribute("i12", lineSP->attribute("i_intf"));
Examples::CIGREMV::logPVAttributes(loggerSP, pv);
// load step sized in absolute terms
std::shared_ptr<SwitchEvent> loadStepEvent = Examples::createEventAddPowerConsumption("n2", std::round(5.0/timeStep)*timeStep, 10e6, systemSP, Domain::SP, loggerSP);
// Simulation
Simulation sim(simNameSP, Logger::Level::debug);
sim.setSystem(systemSP);
sim.setTimeStep(timeStepSP);
sim.setFinalTime(finalTimeSP);
sim.setDomain(Domain::SP);
sim.addEvent(loadStepEvent);
sim.addLogger(loggerSP);
sim.run();
}
......@@ -132,8 +132,11 @@ namespace CIGREMV {
if (domain == Domain::SP) {
SimNode<Complex>::Ptr connectionNode = system.node<CPS::SimNode<Complex>>("N" + std::to_string(n));
auto pv = SP::Ph1::AvVoltageSourceInverterDQ::make("pv_" + connectionNode->name(), "pv_" + connectionNode->name(), Logger::Level::debug, true);
pv->setParameters(scenario.systemOmega, Complex(scenario.pvUnitNominalVoltage, 0), pvActivePower, pvReactivePower);
pv->setTransformerParameters(scenario.systemNominalVoltage, scenario.pvUnitNominalVoltage, scenario.transformerNominalPower, scenario.systemNominalVoltage/scenario.pvUnitNominalVoltage, 0, 0, scenario.transformerInductance, scenario.systemOmega);
pv->setParameters(scenario.systemOmega, scenario.pvUnitNominalVoltage, pvActivePower, pvReactivePower);
pv->setControllerParameters(scenario.KpPLL, scenario.KiPLL, scenario.KpPowerCtrl, scenario.KiPowerCtrl, scenario.KpCurrCtrl, scenario.KiCurrCtrl, scenario.OmegaCutoff);
pv->setFilterParameters(scenario.Lf, scenario.Cf, scenario.Rf, scenario.Rc);
pv->setTransformerParameters(scenario.systemNominalVoltage, scenario.pvUnitNominalVoltage, scenario.systemNominalVoltage/scenario.pvUnitNominalVoltage, 0, 0, scenario.transformerInductance);
pv->setInitialStateValues(scenario.pInit, scenario.qInit, scenario.phi_dInit, scenario.phi_qInit, scenario.gamma_dInit, scenario.gamma_qInit);
system.addComponent(pv);
system.connectComponentToNodes<Complex>(pv, { connectionNode });
} else if (domain == Domain::DP) {
......@@ -142,7 +145,7 @@ namespace CIGREMV {
pv->setParameters(scenario.systemOmega, scenario.pvUnitNominalVoltage, pvActivePower, pvReactivePower);
pv->setControllerParameters(scenario.KpPLL, scenario.KiPLL, scenario.KpPowerCtrl, scenario.KiPowerCtrl, scenario.KpCurrCtrl, scenario.KiCurrCtrl, scenario.OmegaCutoff);
pv->setFilterParameters(scenario.Lf, scenario.Cf, scenario.Rf, scenario.Rc);
pv->setTransformerParameters(scenario.systemNominalVoltage, scenario.pvUnitNominalVoltage, scenario.transformerNominalPower, scenario.systemNominalVoltage/scenario.pvUnitNominalVoltage, 0, 0, scenario.transformerInductance, scenario.systemOmega);
pv->setTransformerParameters(scenario.systemNominalVoltage, scenario.pvUnitNominalVoltage, scenario.systemNominalVoltage/scenario.pvUnitNominalVoltage, 0, 0, scenario.transformerInductance);
pv->setInitialStateValues(scenario.pInit, scenario.qInit, scenario.phi_dInit, scenario.phi_qInit, scenario.gamma_dInit, scenario.gamma_qInit);
system.addComponent(pv);
system.connectComponentToNodes<Complex>(pv, { connectionNode });
......@@ -198,6 +201,16 @@ namespace CIGREMV {
system.connectComponentToNodes<Complex>(loadSwitch, { CPS::SimNode<Complex>::GND, connectionNode});
logger->addAttribute("switchedload_i", loadSwitch->attribute("i_intf"));
return DPsim::SwitchEvent::make(eventTime, loadSwitch, true);
} else if (domain == CPS::Domain::SP) {
auto loadSwitch = SP::Ph1::Switch::make("Load_Add_Switch_" + nodeName, Logger::Level::debug);
auto connectionNode = system.node<CPS::SimNode<Complex>>(nodeName);
Real resistance = std::abs(connectionNode->initialSingleVoltage())*std::abs(connectionNode->initialSingleVoltage())/additionalActivePower;
loadSwitch->setParameters(1e9, resistance);
loadSwitch->open();
system.addComponent(loadSwitch);
system.connectComponentToNodes<Complex>(loadSwitch, { CPS::SimNode<Complex>::GND, connectionNode});
logger->addAttribute("switchedload_i", loadSwitch->attribute("i_intf"));
return DPsim::SwitchEvent::make(eventTime, loadSwitch, true);
} else {
return nullptr;
}
......
......@@ -10,11 +10,12 @@
"TOP=${TOP:-$(git rev-parse --show-toplevel)}\n",
"PATH=${TOP}/build/Examples/Cxx\n",
"\n",
"TIMESTEP=1e-3\n",
"TIMESTEP=0.1e-3\n",
"DURATION=10.0\n",
"\n",
"EMT_Slack_PiLine_VSI_with_PF_Init --timestep=${TIMESTEP} --duration=${DURATION}\n",
"DP_Slack_PiLine_VSI_with_PF_Init --timestep=${TIMESTEP} --duration=${DURATION}"
"DP_Slack_PiLine_VSI_with_PF_Init --timestep=${TIMESTEP} --duration=${DURATION}\n",
"SP_Slack_PiLine_VSI_with_PF_Init --timestep=${TIMESTEP} --duration=${DURATION}"
]
},
{
......@@ -29,6 +30,10 @@
"\n",
"model_name = 'Slack_PiLine_VSI_with_PF_Init'\n",
"\n",
"path_SP = 'logs/' + 'SP_' + model_name + '_SP/'\n",
"dpsim_result_file_SP = path_SP + 'SP_' + model_name + '_SP.csv'\n",
"ts_dpsim_SP = read_timeseries_csv(dpsim_result_file_SP)\n",
"\n",
"path_DP = 'logs/' + 'DP_' + model_name + '_DP/'\n",
"dpsim_result_file_DP = path_DP + 'DP_' + model_name + '_DP.csv'\n",
"ts_dpsim_DP = read_timeseries_csv(dpsim_result_file_DP)\n",
......@@ -65,8 +70,9 @@
"var_name = 'v2'\n",
"plt.figure(figsize=(12,8))\n",
"plt.plot(ts_dpsim_EMT[var_name+'_0'].interpolate(50e-6).time, np.sqrt(3/2)*ts_dpsim_EMT[var_name+'_0'].interpolate(50e-6).values, label='EMT')\n",
"plt.plot(ts_dpsim_DP[var_name].interpolate(50e-6).time, ts_dpsim_DP[var_name].interpolate(50e-6).frequency_shift(50).values, label='DP backshift', linestyle='--')\n",
"#plt.xlim([2.9, 4.4])\n",
"plt.plot(ts_dpsim_DP[var_name].interpolate(50e-6).time, ts_dpsim_DP[var_name].interpolate(50e-6).frequency_shift(50).values, label='DP backshift', linestyle='-.')\n",
"plt.plot(ts_dpsim_SP[var_name].interpolate(50e-6).time, ts_dpsim_SP[var_name].interpolate(50e-6).frequency_shift(50).values, label='SP backshift', linestyle='--')\n",
"plt.xlim([4.9, 6.4])\n",
"plt.legend()\n",
"plt.show()"
]
......@@ -80,7 +86,8 @@
"var_name = 'i12'\n",
"plt.figure(figsize=(12,8))\n",
"plt.plot(ts_dpsim_EMT[var_name+'_0'].interpolate(50e-6).time, np.sqrt(3/2)*ts_dpsim_EMT[var_name+'_0'].interpolate(50e-6).values, label='EMT')\n",
"plt.plot(ts_dpsim_DP[var_name].interpolate(50e-6).time, ts_dpsim_DP[var_name].interpolate(50e-6).frequency_shift(50).values, label='DP backshift', linestyle='--')\n",
"plt.plot(ts_dpsim_DP[var_name].interpolate(50e-6).time, ts_dpsim_DP[var_name].interpolate(50e-6).frequency_shift(50).values, label='DP backshift', linestyle='-.')\n",
"plt.plot(ts_dpsim_SP[var_name].interpolate(50e-6).time, ts_dpsim_SP[var_name].interpolate(50e-6).frequency_shift(50).values, label='SP backshift', linestyle='--')\n",
"#plt.xlim([2.9, 4.4])\n",
"plt.legend()\n",
"plt.show()"
......@@ -95,7 +102,8 @@
"var_name = 'pv_v_intf'\n",
"plt.figure(figsize=(12,8))\n",
"plt.plot(ts_dpsim_EMT[var_name+'_0'].interpolate(50e-6).time, np.sqrt(3/2)*ts_dpsim_EMT[var_name+'_0'].interpolate(50e-6).values, label='EMT')\n",
"plt.plot(ts_dpsim_DP[var_name].interpolate(50e-6).time, ts_dpsim_DP[var_name].interpolate(50e-6).frequency_shift(50).values, label='DP backshift', linestyle='--')#\n",
"plt.plot(ts_dpsim_DP[var_name].interpolate(50e-6).time, ts_dpsim_DP[var_name].interpolate(50e-6).frequency_shift(50).values, label='DP backshift', linestyle='-.')\n",
"plt.plot(ts_dpsim_SP[var_name].interpolate(50e-6).time, ts_dpsim_SP[var_name].interpolate(50e-6).frequency_shift(50).values, label='SP backshift', linestyle='--')\n",
"#plt.xlim([2.9, 4.4])\n",
"plt.legend()\n",
"plt.show()\n"
......@@ -110,7 +118,8 @@
"var_name = 'pv_i_intf'\n",
"plt.figure(figsize=(12,8))\n",
"plt.plot(ts_dpsim_EMT[var_name+'_0'].interpolate(50e-6).time, np.sqrt(3/2)*ts_dpsim_EMT[var_name+'_0'].interpolate(50e-6).values, label='EMT')\n",
"plt.plot(ts_dpsim_DP[var_name].interpolate(50e-6).time, ts_dpsim_DP[var_name].interpolate(50e-6).frequency_shift(50).values, label='DP backshift', linestyle='--')#\n",
"plt.plot(ts_dpsim_DP[var_name].interpolate(50e-6).time, ts_dpsim_DP[var_name].interpolate(50e-6).frequency_shift(50).values, label='DP backshift', linestyle='-.')\n",
"plt.plot(ts_dpsim_SP[var_name].interpolate(50e-6).time, ts_dpsim_SP[var_name].interpolate(50e-6).frequency_shift(50).values, label='SP backshift', linestyle='--')\n",
"#plt.xlim([2.9, 4.4])\n",
"plt.legend()\n",
"plt.show()\n"
......@@ -125,7 +134,8 @@
"var_name = 'pv_pll_output_0'\n",
"plt.figure(figsize=(12,8))\n",
"plt.plot(ts_dpsim_EMT[var_name].interpolate(50e-6).time, ts_dpsim_EMT[var_name].interpolate(50e-6).values, label='EMT')\n",
"plt.plot(ts_dpsim_DP[var_name].interpolate(50e-6).time, ts_dpsim_DP[var_name].interpolate(50e-6).values, label='DP', linestyle='--')\n",
"plt.plot(ts_dpsim_DP[var_name].interpolate(50e-6).time, ts_dpsim_DP[var_name].interpolate(50e-6).values, label='DP', linestyle='-.')\n",
"plt.plot(ts_dpsim_SP[var_name].interpolate(50e-6).time, ts_dpsim_SP[var_name].interpolate(50e-6).values, label='SP', linestyle='--')\n",
"plt.legend()\n",
"plt.show()"
]
......@@ -139,7 +149,8 @@
"var_name = 'pv_pll_output_1'\n",
"plt.figure(figsize=(12,8))\n",
"plt.plot(ts_dpsim_EMT[var_name].interpolate(50e-6).time, ts_dpsim_EMT[var_name].interpolate(50e-6).values, label='EMT')\n",
"plt.plot(ts_dpsim_DP[var_name].interpolate(50e-6).time, ts_dpsim_DP[var_name].interpolate(50e-6).values, label='DP', linestyle='--')\n",
"plt.plot(ts_dpsim_DP[var_name].interpolate(50e-6).time, ts_dpsim_DP[var_name].interpolate(50e-6).values, label='DP', linestyle='-.')\n",
"plt.plot(ts_dpsim_SP[var_name].interpolate(50e-6).time, ts_dpsim_SP[var_name].interpolate(50e-6).values, label='SP', linestyle='--')\n",
"plt.legend()\n",
"plt.show()"
]
......@@ -153,7 +164,8 @@
"var_name = 'pv_powerctrl_state_p'\n",
"plt.figure(figsize=(12,8))\n",
"plt.plot(ts_dpsim_EMT[var_name].interpolate(50e-6).time, ts_dpsim_EMT[var_name].interpolate(50e-6).values, label='EMT')\n",
"plt.plot(ts_dpsim_DP[var_name].interpolate(50e-6).time, ts_dpsim_DP[var_name].interpolate(50e-6).values, label='DP', linestyle='--')\n",
"plt.plot(ts_dpsim_DP[var_name].interpolate(50e-6).time, ts_dpsim_DP[var_name].interpolate(50e-6).values, label='DP', linestyle='-.')\n",
"plt.plot(ts_dpsim_SP[var_name].interpolate(50e-6).time, ts_dpsim_SP[var_name].interpolate(50e-6).values, label='SP', linestyle='--')\n",
"plt.legend()\n",
"plt.show()"
]
......@@ -167,7 +179,8 @@
"var_name = 'pv_powerctrl_state_q'\n",
"plt.figure(figsize=(12,8))\n",
"plt.plot(ts_dpsim_EMT[var_name].interpolate(50e-6).time, ts_dpsim_EMT[var_name].interpolate(50e-6).values, label='EMT')\n",
"plt.plot(ts_dpsim_DP[var_name].interpolate(50e-6).time, ts_dpsim_DP[var_name].interpolate(50e-6).values, label='DP', linestyle='--')\n",
"plt.plot(ts_dpsim_DP[var_name].interpolate(50e-6).time, ts_dpsim_DP[var_name].interpolate(50e-6).values, label='DP', linestyle='-.')\n",
"plt.plot(ts_dpsim_SP[var_name].interpolate(50e-6).time, ts_dpsim_SP[var_name].interpolate(50e-6).values, label='SP', linestyle='--')\n",
"plt.legend()\n",
"plt.show()"
]
......@@ -181,7 +194,8 @@
"var_name = 'pv_powerctrl_input_ircd'\n",
"plt.figure(figsize=(12,8))\n",
"plt.plot(ts_dpsim_EMT[var_name].interpolate(50e-6).time, ts_dpsim_EMT[var_name].interpolate(50e-6).values, label='EMT')\n",
"plt.plot(ts_dpsim_DP[var_name].interpolate(50e-6).time, ts_dpsim_DP[var_name].interpolate(50e-6).values, label='DP', linestyle='--')\n",
"plt.plot(ts_dpsim_DP[var_name].interpolate(50e-6).time, ts_dpsim_DP[var_name].interpolate(50e-6).values, label='DP', linestyle='-.')\n",
"plt.plot(ts_dpsim_SP[var_name].interpolate(50e-6).time, ts_dpsim_SP[var_name].interpolate(50e-6).values, label='SP', linestyle='--')\n",
"plt.legend()\n",
"plt.show()"
]
......@@ -195,7 +209,8 @@
"var_name = 'pv_powerctrl_input_vcd'\n",
"plt.figure(figsize=(12,8))\n",
"plt.plot(ts_dpsim_EMT[var_name].interpolate(50e-6).time, ts_dpsim_EMT[var_name].interpolate(50e-6).values, label='EMT')\n",
"plt.plot(ts_dpsim_DP[var_name].interpolate(50e-6).time, ts_dpsim_DP[var_name].interpolate(50e-6).values, label='DP', linestyle='--')\n",
"plt.plot(ts_dpsim_DP[var_name].interpolate(50e-6).time, ts_dpsim_DP[var_name].interpolate(50e-6).values, label='DP', linestyle='-.')\n",
"plt.plot(ts_dpsim_SP[var_name].interpolate(50e-6).time, ts_dpsim_SP[var_name].interpolate(50e-6).values, label='SP', linestyle='--')\n",
"plt.legend()\n",
"plt.show()"
]
......@@ -209,7 +224,8 @@
"var_name = 'pv_powerctrl_input_vcq'\n",
"plt.figure(figsize=(12,8))\n",
"plt.plot(ts_dpsim_EMT[var_name].interpolate(50e-6).time, ts_dpsim_EMT[var_name].interpolate(50e-6).values, label='EMT')\n",
"plt.plot(ts_dpsim_DP[var_name].interpolate(50e-6).time, ts_dpsim_DP[var_name].interpolate(50e-6).values, label='DP', linestyle='--')\n",
"plt.plot(ts_dpsim_DP[var_name].interpolate(50e-6).time, ts_dpsim_DP[var_name].interpolate(50e-6).values, label='DP', linestyle='-.')\n",
"plt.plot(ts_dpsim_SP[var_name].interpolate(50e-6).time, ts_dpsim_SP[var_name].interpolate(50e-6).values, label='SP', linestyle='--')\n",
"plt.legend()\n",
"plt.show()"
]
......
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# DP Simulation of topology with slack, line and VSI"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
" %%bash\n",
"TOP=${TOP:-$(git rev-parse --show-toplevel)}\n",
"PATH=${TOP}/build/Examples/Cxx\n",
"\n",
"TIMESTEP=1e-3\n",
"DURATION=4.0\n",
"\n",
"SP_Slack_PiLine_VSI_with_PF_Init --timestep=${TIMESTEP} --duration=${DURATION}"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from villas.dataprocessing.readtools import *\n",
"from villas.dataprocessing.timeseries import *\n",
"import matplotlib.pyplot as plt\n",
"import re\n",
"\n",
"# %matplotlib widget"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## PF results"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"modelName = 'SP_Slack_PiLine_VSI_with_PF_Init_PF'\n",
"path = 'logs/' + modelName + '/'\n",
"dpsim_result_file = path + modelName + '.csv'\n",
"\n",
"ts_dpsim_pf = read_timeseries_csv(dpsim_result_file)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## SP results"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"modelName = 'SP_Slack_PiLine_VSI_with_PF_Init_SP'\n",
"path = 'logs/' + modelName + '/'\n",
"dpsim_result_file = path + modelName + '.csv'\n",
"\n",
"ts_dpsim = read_timeseries_csv(dpsim_result_file)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"plt.figure(figsize=(12,6))\n",
"for ts_name, ts_obj in ts_dpsim.items():\n",
" if ts_name == 'v1' or ts_name == 'v2':\n",
" plt.plot(ts_obj.time, ts_obj.abs().values, label=ts_name)\n",
"for ts_name, ts_obj in ts_dpsim_pf.items():\n",
" if ts_name == 'v1' or ts_name == 'v2':\n",
" plt.plot(ts_obj.time, ts_obj.abs().values, label=ts_name+'_pf', linestyle=':')\n",
"plt.legend()\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.6"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
......@@ -163,11 +163,6 @@ void PFSolver::determinePFBusType() {
connectedPV = true;
}
}
else if (std::shared_ptr<CPS::SP::Ph1::AvVoltageSourceInverterDQ> vsi = std::dynamic_pointer_cast<CPS::SP::Ph1::AvVoltageSourceInverterDQ>(comp)){
if (vsi->mPowerflowBusType == CPS::PowerflowBusType::PQ) {
connectedPQ = true;
}
}
}
// determine powerflow bus types according connected type of connected components
......
......@@ -27,10 +27,6 @@ void PFSolverPowerPolar::generateInitialSolution(Real time, bool keep_last_solut
load->calculatePerUnitParameters(mBaseApparentPower, mSystem.mSystemOmega);
}
}
else if (std::shared_ptr<CPS::SP::Ph1::AvVoltageSourceInverterDQ> vsi =
std::dynamic_pointer_cast<CPS::SP::Ph1::AvVoltageSourceInverterDQ>(comp)) {
vsi->updatePQ(time);
}
}
// set initial solution for the new time
......
......@@ -33,8 +33,8 @@ namespace Base {
/// Setter for filter parameters
void setFilterParameters(Real Lf, Real Cf, Real Rf, Real Rc);
/// Setter for optional connection transformer
void setTransformerParameters(Real nomVoltageEnd1, Real nomVoltageEnd2, Real ratedPower, Real ratioAbs,
Real ratioPhase, Real resistance, Real inductance, Real omega);
void setTransformerParameters(Real nomVoltageEnd1, Real nomVoltageEnd2, Real ratioAbs,
Real ratioPhase, Real resistance, Real inductance);
};
}
}
......@@ -75,10 +75,10 @@ namespace CPS {
// CSVReader::Mode mode = CSVReader::Mode::AUTO,
// CSVReader::DataFormat format = CSVReader::DataFormat::SECONDS);
void assignLoadProfileSP(std::vector<std::shared_ptr<CPS::SP::Ph1::AvVoltageSourceInverterDQ>>& loads,
Real start_time = -1, Real time_step = 1, Real end_time = -1, Real scale_factor= 1,
CSVReader::Mode mode = CSVReader::Mode::AUTO,
CSVReader::DataFormat format = CSVReader::DataFormat::SECONDS);
// void assignLoadProfileSP(std::vector<std::shared_ptr<CPS::SP::Ph1::AvVoltageSourceInverterDQ>>& loads,
// Real start_time = -1, Real time_step = 1, Real end_time = -1, Real scale_factor= 1,
// CSVReader::Mode mode = CSVReader::Mode::AUTO,
// CSVReader::DataFormat format = CSVReader::DataFormat::SECONDS);
void assignLoadProfileDP(std::vector<std::shared_ptr<CPS::DP::Ph1::AvVoltageSourceInverterDQ>>& loads,
Real start_time = -1, Real time_step = 1, Real end_time = -1, Real scale_factor= 1,
......
......@@ -19,6 +19,7 @@
#include <cps/SP/SP_Ph1_Transformer.h>
#include <cps/SP/SP_Ph1_SolidStateTransformer.h>
#include <cps/SP/SP_Ph1_Load.h>
#include <cps/SP/SP_Ph1_Switch.h>
#include <cps/SP/SP_Ph1_SynchronGenerator.h>
#include <cps/SP/SP_Ph1_PQNode.h>
#include <cps/SP/SP_Ph1_PVNode.h>
......
......@@ -102,8 +102,7 @@ namespace Ph1 {
/// Setter for parameters of control loops
void setControllerParameters(Real Kp_pll, Real Ki_pll, Real Kp_powerCtrl, Real Ki_powerCtrl, Real Kp_currCtrl, Real Ki_currCtrl, Real Omega_cutoff);
/// Setter for parameters of transformer
void setTransformerParameters(Real nomVoltageEnd1, Real nomVoltageEnd2,
Real ratedPower, Real ratioAbs, Real ratioPhase, Real resistance, Real inductance, Real omega);
void setTransformerParameters(Real nomVoltageEnd1, Real nomVoltageEnd2, Real ratioAbs, Real ratioPhase, Real resistance, Real inductance);
/// Setter for parameters of filter
void setFilterParameters(Real Lf, Real Cf, Real Rf, Real Rc);
/// Setter for initial values applied in controllers
......
......@@ -14,260 +14,163 @@
#include <cps/SP/SP_Ph1_Resistor.h>
#include <cps/SP/SP_Ph1_Inductor.h>
#include <cps/SP/SP_Ph1_Capacitor.h>
#include <cps/SP/SP_Ph1_ControlledVoltageSource.h>
#include <cps/SP/SP_Ph1_Load.h>
#include <cps/SP/SP_Ph1_VoltageSource.h>
#include <cps/SP/SP_Ph1_Transformer.h>
#include <cps/Base/Base_AvVoltageSourceInverterDQ.h>
#include <cps/Signal/PLL.h>
#include <cps/Signal/PowerControllerVSI.h>
namespace CPS {
namespace SP {
namespace Ph1 {
/*
Average voltage source inverter
- modelled in dq
- with interface to SP grid
*/
class AvVoltageSourceInverterDQ :
public Base::AvVoltageSourceInverterDQ,
public SimPowerComp<Complex>,
public MNAInterface,
public PFSolverInterfaceBus,
public SharedFactory<AvVoltageSourceInverterDQ> {
protected:
Complex mVoltNom;