Commit 05ab0722 authored by Jan Dinkelbach's avatar Jan Dinkelbach Committed by Markus Mirz
Browse files

use lower volt side param for snubber res sizing in emt3ph trafo and add...

use lower volt side param for snubber res sizing in emt3ph trafo and add validation to test notebook
parent 4cf169c3
......@@ -47,7 +47,7 @@ set(CIRCUIT_SOURCES
Circuits/EMT_DP_VS_Init.cpp
Circuits/EMT_DP_SP_VS_RLC.cpp
Circuits/DP_EMT_RL_SourceStep.cpp
Circuits/DP_SP_Trafo.cpp
Circuits/EMT_DP_SP_Trafo.cpp
)
set(SYNCGEN_SOURCES
......
......@@ -19,6 +19,7 @@
using namespace DPsim;
using namespace CPS;
using namespace CPS::CIM;
void simTrafoElementsSP1ph() {
Real timeStep = 0.00005;
......@@ -242,6 +243,117 @@ void simTrafoDP1ph() {
sim.run();
}
void simTrafoElementsEMT3ph() {
Real timeStep = 0.00005;
Real finalTime = 1;
String simName = "EMT_Trafo_Elements";
Logger::setLogDir("logs/"+simName);
Real voltageHVSide = 100000;
Real voltageMVSide = 10000;
Real trafoResistance = 1;
Real trafoInductance = 0.1;
Real loadResistanceHVSide = 10000;
Real ratio = voltageHVSide/voltageMVSide;
Real snubberResistanceHVSide = ratio*ratio*voltageMVSide*1e6;
// Nodes
auto n1 = SimNode<Real>::make("n1", PhaseType::ABC);
auto n2 = SimNode<Real>::make("n2", PhaseType::ABC);
auto vn1 = SimNode<Real>::make("vn1", PhaseType::ABC);
// Components
auto vs = EMT::Ph3::VoltageSource::make("v_1");
auto trafoRes = EMT::Ph3::Resistor::make("trafo_res");
auto trafoSnubberRes = EMT::Ph3::Resistor::make("trafo_snub_res");
auto trafoInd = EMT::Ph3::Inductor::make("trafo_ind");
auto loadRes = EMT::Ph3::Resistor::make("r_1");
// Topology
vs->connect({ SimNode<Real>::GND, n1 });
trafoRes->connect({ n1, vn1 });
trafoInd->connect({ vn1, n2 });
trafoSnubberRes->connect({ n2, SimNode<Real>::GND });
loadRes->connect({ n2, SimNode<Real>::GND });
// Parameters
vs->setParameters(Reader::singlePhaseVariableToThreePhase(CPS::Math::polar(100000, 0)), 50);
trafoRes->setParameters(Reader::singlePhaseParameterToThreePhase(trafoResistance));
trafoInd->setParameters(Reader::singlePhaseParameterToThreePhase(trafoInductance));
trafoSnubberRes->setParameters(Reader::singlePhaseParameterToThreePhase(snubberResistanceHVSide));
loadRes->setParameters(Reader::singlePhaseParameterToThreePhase(loadResistanceHVSide));
// Define system topology
SystemTopology sys(50, SystemNodeList{n1, n2, vn1 }, SystemComponentList{vs, trafoRes, trafoInd, trafoSnubberRes, loadRes});
// Logging
auto logger = DataLogger::make(simName);
logger->addAttribute("v1", n1->attribute("v"));
logger->addAttribute("v2", n2->attribute("v"));
logger->addAttribute("itrafo", trafoInd->attribute("i_intf"));
Simulation sim(simName);
sim.setSystem(sys);
sim.setTimeStep(timeStep);
sim.setFinalTime(finalTime);
sim.setDomain(Domain::EMT);
sim.addLogger(logger);
sim.run();
}
void simTrafoEMT3ph() {
Real timeStep = 0.00005;
Real finalTime = 1;
String simName = "EMT_Trafo_Component";
Logger::setLogDir("logs/"+simName);
Real voltageHVSide = 100000;
Real voltageMVSide = 10000;
Real trafoResistance = 1;
Real trafoInductance = 0.1;
Real loadResistanceHVSide = 10000;
Real ratio = voltageHVSide/voltageMVSide;
Real loadResistanceMVSide = loadResistanceHVSide/(ratio*ratio);
// Nodes
auto n1 = SimNode<Real>::make("n1", PhaseType::ABC);
auto n2 = SimNode<Real>::make("n2", PhaseType::ABC);
// Components
auto vs = EMT::Ph3::VoltageSource::make("v_1", Logger::Level::debug);
auto trafo = EMT::Ph3::Transformer::make("trafo", "trafo", Logger::Level::debug, true);
auto loadRes = EMT::Ph3::Resistor::make("r_1", Logger::Level::debug);
// Topology
vs->connect({ SimNode<Real>::GND, n1 });
trafo->connect({ n1, n2 });
loadRes->connect({ n2, SimNode<Real>::GND });
// Parameters
vs->setParameters(Reader::singlePhaseVariableToThreePhase(CPS::Math::polar(100000, 0)), 50);
trafo->setParameters(voltageHVSide, voltageMVSide, ratio, 0, Reader::singlePhaseParameterToThreePhase(trafoResistance), Reader::singlePhaseParameterToThreePhase(trafoInductance));
loadRes->setParameters(Reader::singlePhaseParameterToThreePhase(loadResistanceMVSide));
// Define system topology
SystemTopology sys(50, SystemNodeList{n1, n2 }, SystemComponentList{vs, trafo, loadRes});
// Logging
auto logger = DataLogger::make(simName);
logger->addAttribute("v1", n1->attribute("v"));
logger->addAttribute("v2", n2->attribute("v"));
logger->addAttribute("itrafo", trafo->attribute("i_intf"));
Simulation sim(simName);
sim.setSystem(sys);
sim.setTimeStep(timeStep);
sim.setFinalTime(finalTime);
sim.setDomain(Domain::EMT);
sim.addLogger(logger);
sim.run();
}
int main(int argc, char* argv[]) {
simTrafoElementsSP1ph();
......@@ -250,5 +362,8 @@ int main(int argc, char* argv[]) {
simTrafoElementsDP1ph();
simTrafoDP1ph();
simTrafoElementsEMT3ph();
simTrafoEMT3ph();
return 0;
}
......@@ -61,8 +61,8 @@ void EMT_Ph3_VSI2_4bus_SampleGrid() {
Real cf_param = 789.3e-6;
Real rc_param = 0.5;
trans_DG1->setParameters(Vnom_pv / Vnom, 0., Matrix::Identity(3,3)*rc_param, Matrix::Identity(3,3)*lf_param*0.01);
trans_DG2->setParameters(Vnom_pv / Vnom, 0., Matrix::Identity(3,3)*rc_param, Matrix::Identity(3,3)*lf_param * 0.01);
trans_DG1->setParameters(Vnom_pv, Vnom, Vnom_pv / Vnom, 0., Matrix::Identity(3,3)*rc_param, Matrix::Identity(3,3)*lf_param*0.01);
trans_DG2->setParameters(Vnom_pv, Vnom, Vnom_pv / Vnom, 0., Matrix::Identity(3,3)*rc_param, Matrix::Identity(3,3)*lf_param * 0.01);
//trans_inductor->setParameters(lf_param*0.01);
auto piline = PiLine::make("piline", Logger::Level::debug);
......
......@@ -11,20 +11,22 @@
import numpy as np
# %matplotlib widget
epsilon = 1e-12
PEAK1PH_TO_RMS3PH = np.sqrt(3/2)
```
%% Cell type:code id: tags:
``` python
%%bash
TOP=${TOP:-$(git rev-parse --show-toplevel)}
PATH=${TOP}/build/Examples/Cxx
DP_SP_Trafo
EMT_DP_SP_Trafo
```
%% Cell type:markdown id: tags:
## SP Trafo with elements
......@@ -199,10 +201,99 @@
assert np.max(errors_sp_shifted) < epsilon
```
%% Cell type:markdown id: tags:
## EMT Trafo with elements
%% Cell type:code id: tags:
``` python
work_dir = 'logs/EMT_Trafo_Elements/'
log_name = 'EMT_Trafo_Elements'
print(work_dir + log_name + '.csv')
trafo_elements_emt = rt.read_timeseries_dpsim(work_dir + log_name + '.csv')
```
%% Cell type:code id: tags:
``` python
plt.figure()
plt.plot(trafo_elements_emt['v1_0'].time, PEAK1PH_TO_RMS3PH*trafo_elements_emt['v1_0'].values, label='v1_0')
plt.legend()
```
%% Cell type:code id: tags:
``` python
plt.figure()
plt.plot(trafo_elements_emt['itrafo_0'].time, PEAK1PH_TO_RMS3PH*trafo_elements_emt['itrafo_0'].values, label='itrafo_0')
plt.legend()
```
%% Cell type:markdown id: tags:
## EMT Trafo composite model
%% Cell type:code id: tags:
``` python
work_dir = 'logs/EMT_Trafo_Component/'
log_name = 'EMT_Trafo_Component'
print(work_dir + log_name + '.csv')
trafo_component_emt = rt.read_timeseries_dpsim(work_dir + log_name + '.csv')
```
%% Cell type:code id: tags:
``` python
plt.figure()
plt.plot(trafo_component_emt['v1_0'].time, PEAK1PH_TO_RMS3PH*trafo_component_emt['v1_0'].values, label='v1_0')
plt.plot(trafo_component_emt['v1_1'].time, PEAK1PH_TO_RMS3PH*trafo_component_emt['v1_1'].values, label='v1_1')
plt.plot(trafo_component_emt['v1_2'].time, PEAK1PH_TO_RMS3PH*trafo_component_emt['v1_2'].values, label='v1_2')
plt.legend()
```
%% Cell type:code id: tags:
``` python
plt.figure()
plt.plot(trafo_component_emt['itrafo_0'].time, PEAK1PH_TO_RMS3PH*trafo_component_emt['itrafo_0'].values, label='itrafo_0')
plt.plot(trafo_component_emt['itrafo_1'].time, PEAK1PH_TO_RMS3PH*trafo_component_emt['itrafo_1'].values, label='itrafo_1')
plt.plot(trafo_component_emt['itrafo_2'].time, PEAK1PH_TO_RMS3PH*trafo_component_emt['itrafo_2'].values, label='itrafo_2')
plt.legend()
```
%% Cell type:markdown id: tags:
## Error for EMT Trafo
%% Cell type:code id: tags:
``` python
plt.figure()
for name in ['v1_0', 'v1_1', 'v1_1', 'itrafo_0', 'itrafo_1', 'itrafo_2']:
plt.plot(trafo_elements_emt[name].time, trafo_elements_emt[name].values - trafo_component_emt[name].values, label=name+'_error')
plt.legend()
```
%% Cell type:markdown id: tags:
## Assertion for EMT Trafo
%% Cell type:code id: tags:
``` python
errors_emt = []
for name in ['v1_0', 'v1_1', 'v1_1', 'itrafo_0', 'itrafo_1', 'itrafo_2']:
errors_emt.append(np.absolute(trafo_elements_emt[name].values - trafo_component_emt[name].values).max())
print(name + ': ' + str(errors_emt[-1]))
assert np.max(errors_emt) < epsilon
```
%% Cell type:markdown id: tags:
### Comparison SP vs. DP
%% Cell type:code id: tags:
``` python
......@@ -237,10 +328,50 @@
print(name[0]+' vs. '+name[1] + ' (rel): ' + str(compare_errors_rel[-1]))
print('Max rel error: '+ '{:.2}'.format(np.max(compare_errors_rel)*100) +'%')
assert np.max(compare_errors_rel) < 3e-1
```
%% Cell type:markdown id: tags:
### Comparison EMT vs. DP
%% Cell type:code id: tags:
``` python
plt.figure()
for name in [('v1_0', 'v1_shift')]:
plt.plot(trafo_component_emt[name[0]].time, PEAK1PH_TO_RMS3PH*trafo_component_emt[name[0]].values - trafo_component_dp_shifted[name[1]].values, label=name[0]+' vs. '+name[1])
plt.legend()
```
%% Cell type:code id: tags:
``` python
plt.figure()
for name in [('itrafo_0', 'itrafo_shift')]:
plt.plot(trafo_component_emt[name[0]].time, PEAK1PH_TO_RMS3PH*trafo_component_emt[name[0]].values - trafo_component_dp_shifted[name[1]].values, label=name[0]+' vs. '+name[1])
plt.legend()
```
%% Cell type:markdown id: tags:
### Assertion EMT vs. DP
%% Cell type:code id: tags:
``` python
compare_errors_abs = []
compare_errors_rel = []
for name in [('v1_0', 'v1_shift'), ('itrafo_0', 'itrafo_shift')]:
compare_errors_abs.append(np.absolute(PEAK1PH_TO_RMS3PH*trafo_component_emt[name[0]].values - trafo_component_dp_shifted[name[1]].values).max())
compare_errors_rel.append(np.absolute(PEAK1PH_TO_RMS3PH*trafo_component_emt[name[0]].values - trafo_component_dp_shifted[name[1]].values).max()/trafo_component_dp_shifted[name[1]].values.max())
print(name[0]+' vs. '+name[1] + ' (abs): ' + str(compare_errors_abs[-1]))
print(name[0]+' vs. '+name[1] + ' (rel): ' + str(compare_errors_rel[-1]))
print('Max rel error: '+ '{:.2}'.format(np.max(compare_errors_rel)*100) +'%')
assert np.max(compare_errors_rel) < 1e-4
```
%% Cell type:code id: tags:
``` python
```
......
......@@ -15,6 +15,10 @@ namespace Base {
namespace Ph3 {
class Transformer {
protected:
/// Nominal voltage of primary side
Real mNominalVoltageEnd1;
/// Nominal voltage of secondary side
Real mNominalVoltageEnd2;
/// Transformer ratio
Complex mRatio;
/// Resistance [Ohm]
......@@ -24,7 +28,9 @@ namespace Ph3 {
public:
///
void setParameters(Real ratioAbs, Real ratioPhase, Matrix resistance, Matrix inductance) {
void setParameters(Real nomVoltageEnd1, Real nomVoltageEnd2, Real ratioAbs, Real ratioPhase, Matrix resistance, Matrix inductance) {
mNominalVoltageEnd1 = nomVoltageEnd1;
mNominalVoltageEnd2 = nomVoltageEnd2;
mRatio = std::polar<Real>(ratioAbs, ratioPhase);
mResistance = resistance;
mInductance = inductance;
......
......@@ -47,7 +47,7 @@ namespace CPS {
// #### General ####
/// Defines component parameters
void setParameters(Real ratioAbs, Real ratioPhase, Matrix resistance, Matrix inductance);
void setParameters(Real nomVoltageEnd1, Real nomVoltageEnd2, Real ratioAbs, Real ratioPhase, Matrix resistance, Matrix inductance);
/// Initializes component from power flow data
void initializeFromNodesAndTerminals(Real frequency);
......
......@@ -493,7 +493,7 @@ TopologicalPowerComp::Ptr Reader::mapPowerTransformer(CIMPP::PowerTransformer* t
Matrix inductance_3ph = singlePhaseParameterToThreePhase(inductance);
Bool withResistiveLosses = resistance > 0;
auto transformer = std::make_shared<EMT::Ph3::Transformer>(trans->mRID, trans->name, mComponentLogLevel, withResistiveLosses);
transformer->setParameters(ratioAbs, ratioPhase, resistance_3ph, inductance_3ph);
transformer->setParameters(voltageNode1, voltageNode2, ratioAbs, ratioPhase, resistance_3ph, inductance_3ph);
return transformer;
}
else
......
......@@ -15,7 +15,7 @@ DP::Ph1::AvVoltageSourceInverterDQ::AvVoltageSourceInverterDQ(String uid, String
SimPowerComp<Complex>(uid, name, logLevel) {
if (withTrafo) {
setVirtualNodeNumber(4);
mConnectionTransformer = DP::Ph1::Transformer::make(mName + "_trans", Logger::Level::debug);
mConnectionTransformer = DP::Ph1::Transformer::make(mName + "_trans", mName + "_trans", mLogLevel, false);
mSubComponents.push_back(mConnectionTransformer);
} else {
setVirtualNodeNumber(3);
......@@ -105,6 +105,7 @@ void DP::Ph1::AvVoltageSourceInverterDQ::setTransformerParameters(Real nomVoltag
mSLog->info("Tap Ratio={} [ ] Phase Shift={} [deg]", mTransformerRatioAbs, mTransformerRatioPhase);
if (mWithConnectionTransformer)
// TODO: resistive losses neglected so far (mWithResistiveLosses=false)
mConnectionTransformer->setParameters(mTransformerNominalVoltageEnd1, mTransformerNominalVoltageEnd2, mTransformerRatioAbs, mTransformerRatioPhase, mTransformerResistance, mTransformerInductance);
}
......
......@@ -16,7 +16,7 @@ EMT::Ph3::AvVoltageSourceInverterDQ::AvVoltageSourceInverterDQ(String uid, Strin
mPhaseType = PhaseType::ABC;
if (withTrafo) {
setVirtualNodeNumber(4);
mConnectionTransformer = EMT::Ph3::Transformer::make(mName + "_trans", Logger::Level::debug);
mConnectionTransformer = EMT::Ph3::Transformer::make(mName + "_trans", mName + "_trans", mLogLevel, false);
mSubComponents.push_back(mConnectionTransformer);
} else {
setVirtualNodeNumber(3);
......@@ -96,16 +96,18 @@ void EMT::Ph3::AvVoltageSourceInverterDQ::setParameters(Real sysOmega, Real sysV
void EMT::Ph3::AvVoltageSourceInverterDQ::setTransformerParameters(Real nomVoltageEnd1, Real nomVoltageEnd2,
Real ratedPower, Real ratioAbs, Real ratioPhase, Real resistance, Real inductance, Real omega) {
Base::AvVoltageSourceInverterDQ::setTransformerParameters(nomVoltageEnd1, nomVoltageEnd2,
ratedPower, ratioAbs, ratioPhase, resistance, inductance, omega);
ratedPower, ratioAbs, ratioPhase, resistance, inductance, omega);
mSLog->info("Connection Transformer Parameters:");
mSLog->info("Nominal Voltage End 1={} [V] Nominal Voltage End 2={} [V]", mTransformerNominalVoltageEnd1, mTransformerNominalVoltageEnd2);
mSLog->info("Resistance={} [Ohm] Inductance={} [H]", mTransformerResistance, mTransformerInductance);
mSLog->info("Tap Ratio={} [ ] Phase Shift={} [deg]", mTransformerRatioAbs, mTransformerRatioPhase);
if (mWithConnectionTransformer)
mConnectionTransformer->setParameters(mTransformerRatioAbs, mTransformerRatioPhase, CPS::CIM::Reader::singlePhaseParameterToThreePhase(mTransformerResistance), CPS::CIM::Reader::singlePhaseParameterToThreePhase(mTransformerInductance));
// TODO: resistive losses neglected so far (mWithResistiveLosses=false)
mConnectionTransformer->setParameters(mTransformerNominalVoltageEnd1, mTransformerNominalVoltageEnd2, mTransformerRatioAbs, mTransformerRatioPhase, CPS::CIM::Reader::singlePhaseParameterToThreePhase(mTransformerResistance), CPS::CIM::Reader::singlePhaseParameterToThreePhase(mTransformerInductance));
}
void EMT::Ph3::AvVoltageSourceInverterDQ::setControllerParameters(Real Kp_pll, Real Ki_pll,
......
......@@ -33,16 +33,19 @@ EMT::Ph3::Transformer::Transformer(String uid, String name,
SimPowerComp<Real>::Ptr EMT::Ph3::Transformer::clone(String name) {
auto copy = Transformer::make(name, mLogLevel);
copy->setParameters(std::abs(mRatio), std::arg(mRatio), mResistance, mInductance);
copy->setParameters(mNominalVoltageEnd1, mNominalVoltageEnd2, std::abs(mRatio), std::arg(mRatio), mResistance, mInductance);
return copy;
}
void EMT::Ph3::Transformer::setParameters(Real ratioAbs, Real ratioPhase,
void EMT::Ph3::Transformer::setParameters(Real nomVoltageEnd1, Real nomVoltageEnd2, Real ratioAbs, Real ratioPhase,
Matrix resistance, Matrix inductance) {
Base::Ph3::Transformer::setParameters(ratioAbs, ratioPhase, resistance, inductance);
Base::Ph3::Transformer::setParameters(nomVoltageEnd1, nomVoltageEnd2, ratioAbs, ratioPhase, resistance, inductance);
mSLog->info("Nominal Voltage End 1={} [V] Nominal Voltage End 2={} [V]", mNominalVoltageEnd1, mNominalVoltageEnd2);
mSLog->info("Resistance={} [Ohm] Inductance={} [Ohm] (referred to primary side)", mResistance, mInductance);
mSLog->info("Tap Ratio={} [ ] Phase Shift={} [deg]", std::abs(mRatio), std::arg(mRatio));
mSLog->info("Resistance={} [Ohm] Inductance={} [Ohm] (referred to primary side)", resistance, inductance);
mSLog->info("Tap Ratio={} [ ] Phase Shift={} [deg]", ratioAbs, ratioPhase);
mParametersSet = true;
}
......@@ -99,7 +102,8 @@ void EMT::Ph3::Transformer::initializeFromNodesAndTerminals(Real frequency) {
// Create parallel sub components
// A snubber conductance is added on the low voltage side (resistance approximately scaled with LV side voltage)
mSnubberResistance = Matrix::Identity(3,3)*std::abs(node(1)->initialSingleVoltage())*1e6;
Real snubberResistance = mNominalVoltageEnd1 > mNominalVoltageEnd2 ? std::abs(mNominalVoltageEnd2)*1e6 : std::abs(mNominalVoltageEnd1)*1e6;
mSnubberResistance = Matrix::Identity(3,3)*(snubberResistance);
mSubSnubResistor = std::make_shared<EMT::Ph3::Resistor>(mName + "_snub_res", mLogLevel);
mSubSnubResistor->setParameters(mSnubberResistance);
mSubSnubResistor->connect({ node(1), EMT::SimNode::GND });
......
Markdown is supported
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