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

use lower volt side param for snubber res sizing in dp1ph and sp1ph trafo

parent b802ab05
......@@ -41,13 +41,13 @@ set(CIRCUIT_SOURCES
# SP examples
Circuits/SP_Circuits.cpp
Circuits/SP_PiLine.cpp
Circuits/SP_Trafo.cpp
# Combined EMT/DP/SP examples
Circuits/EMT_DP_SP_Slack.cpp
Circuits/EMT_DP_VS_Init.cpp
Circuits/EMT_DP_SP_VS_RLC.cpp
Circuits/DP_EMT_RL_SourceStep.cpp
Circuits/DP_SP_Trafo.cpp
)
set(SYNCGEN_SOURCES
......
......@@ -66,6 +66,7 @@ void simTrafoElementsSP1ph() {
// 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);
......@@ -98,7 +99,7 @@ void simTrafoSP1ph() {
// Components
auto vs = SP::Ph1::VoltageSource::make("v_1", Logger::Level::debug);
auto trafo = std::make_shared<SP::Ph1::Transformer>("trafo", "trafo", Logger::Level::debug, true);
auto trafo = SP::Ph1::Transformer::make("trafo", "trafo", Logger::Level::debug, true);
auto loadRes = SP::Ph1::Resistor::make("r_1", Logger::Level::debug);
// Topology
......@@ -117,6 +118,7 @@ void simTrafoSP1ph() {
// 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);
......@@ -129,10 +131,124 @@ void simTrafoSP1ph() {
sim.run();
}
void simTrafoElementsDP1ph() {
Real timeStep = 0.00005;
Real finalTime = 1;
String simName = "DP_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<Complex>::make("n1");
auto n2 = SimNode<Complex>::make("n2");
auto vn1 = SimNode<Complex>::make("vn1");
// Components
auto vs = DP::Ph1::VoltageSource::make("v_1");
auto trafoRes = DP::Ph1::Resistor::make("trafo_res");
auto trafoSnubberRes = DP::Ph1::Resistor::make("trafo_snub_res");
auto trafoInd = DP::Ph1::Inductor::make("trafo_ind");
auto loadRes = DP::Ph1::Resistor::make("r_1");
// Topology
vs->connect({ SimNode<Complex>::GND, n1 });
trafoRes->connect({ n1, vn1 });
trafoInd->connect({ vn1, n2 });
trafoSnubberRes->connect({ n2, SimNode<Complex>::GND });
loadRes->connect({ n2, SimNode<Complex>::GND });
// Parameters
vs->setParameters(CPS::Math::polar(voltageHVSide, 0));
trafoRes->setParameters(trafoResistance);
trafoInd->setParameters(trafoInductance);
trafoSnubberRes->setParameters(snubberResistanceHVSide);
loadRes->setParameters(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::DP);
sim.addLogger(logger);
sim.run();
}
void simTrafoDP1ph() {
Real timeStep = 0.00005;
Real finalTime = 1;
String simName = "DP_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<Complex>::make("n1");
auto n2 = SimNode<Complex>::make("n2");
// Components
auto vs = DP::Ph1::VoltageSource::make("v_1", Logger::Level::debug);
auto trafo = DP::Ph1::Transformer::make("trafo", "trafo", Logger::Level::debug, true);
auto loadRes = DP::Ph1::Resistor::make("r_1", Logger::Level::debug);
// Topology
vs->connect({ SimNode<Complex>::GND, n1 });
trafo->connect({ n1, n2 });
loadRes->connect({ n2, SimNode<Complex>::GND });
// Parameters
vs->setParameters(CPS::Math::polar(voltageHVSide, 0));
trafo->setParameters(voltageHVSide, voltageMVSide, ratio, 0, trafoResistance, trafoInductance);
loadRes->setParameters(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::DP);
sim.addLogger(logger);
sim.run();
}
int main(int argc, char* argv[]) {
simTrafoElementsSP1ph();
simTrafoSP1ph();
simTrafoElementsDP1ph();
simTrafoDP1ph();
return 0;
}
......@@ -13,24 +13,24 @@
# %matplotlib widget
epsilon = 1e-12
```
%% Cell type:markdown id: tags:
## SP Trafo with elements
%% Cell type:code id: tags:
``` python
%%bash
TOP=${TOP:-$(git rev-parse --show-toplevel)}
PATH=${TOP}/build/Examples/Cxx
SP_Trafo
DP_SP_Trafo
```
%% Cell type:markdown id: tags:
## SP Trafo with elements
%% Cell type:code id: tags:
``` python
work_dir = 'logs/SP_Trafo_Elements/'
log_name = 'SP_Trafo_Elements'
......@@ -110,10 +110,137 @@
errors_sp_shifted.append(np.absolute(trafo_elements_sp_shifted[name].values - trafo_component_sp_shifted[name].values).max())
print(name + ': ' + str(errors_sp_shifted[-1]))
assert np.max(errors_sp_shifted) < epsilon
```
%% Cell type:markdown id: tags:
## DP Trafo with elements
%% Cell type:code id: tags:
``` python
work_dir = 'logs/DP_Trafo_Elements/'
log_name = 'DP_Trafo_Elements'
print(work_dir + log_name + '.csv')
trafo_elements = rt.read_timeseries_dpsim(work_dir + log_name + '.csv')
trafo_elements_dp_shifted = ts.frequency_shift_list(trafo_elements, 50)
```
%% Cell type:code id: tags:
``` python
plt.figure()
plt.plot(trafo_elements_dp_shifted['v1_shift'].time, trafo_elements_dp_shifted['v1_shift'].values, label='v1_shift')
plt.legend()
```
%% Cell type:code id: tags:
``` python
plt.figure()
plt.plot(trafo_elements_dp_shifted['itrafo_shift'].time, trafo_elements_dp_shifted['itrafo_shift'].values, label='itrafo_shift')
plt.legend()
```
%% Cell type:markdown id: tags:
## DP Trafo composite model
%% Cell type:code id: tags:
``` python
work_dir = 'logs/DP_Trafo_Component/'
log_name = 'DP_Trafo_Component'
print(work_dir + log_name + '.csv')
trafo_component = rt.read_timeseries_dpsim(work_dir + log_name + '.csv')
trafo_component_dp_shifted = ts.frequency_shift_list(trafo_component, 50)
```
%% Cell type:code id: tags:
``` python
plt.figure()
plt.plot(trafo_component_dp_shifted['v1_shift'].time, trafo_component_dp_shifted['v1_shift'].values, label='v1_shift')
plt.legend()
```
%% Cell type:code id: tags:
``` python
plt.figure()
plt.plot(trafo_component_dp_shifted['itrafo_shift'].time, trafo_component_dp_shifted['itrafo_shift'].values, label='itrafo_shift')
plt.legend()
```
%% Cell type:markdown id: tags:
## Error for DP Trafo
%% Cell type:code id: tags:
``` python
plt.figure()
for name in ['v1_shift', 'itrafo_shift']:
plt.plot(trafo_elements_dp_shifted[name].time, trafo_elements_dp_shifted[name].values - trafo_component_dp_shifted[name].values, label=name+'_error')
plt.legend()
```
%% Cell type:markdown id: tags:
## Assertion for DP Trafo
%% Cell type:code id: tags:
``` python
errors_sp_shifted = []
for name in ['v1_shift', 'itrafo_shift']:
errors_sp_shifted.append(np.absolute(trafo_elements_sp_shifted[name].values - trafo_component_sp_shifted[name].values).max())
print(name + ': ' + str(errors_sp_shifted[-1]))
assert np.max(errors_sp_shifted) < epsilon
```
%% Cell type:markdown id: tags:
### Comparison SP vs. DP
%% Cell type:code id: tags:
``` python
plt.figure()
for name in [('v1_shift', 'v1_shift')]:
plt.plot(trafo_component_sp_shifted[name[0]].time, trafo_component_sp_shifted[name[0]].values - trafo_component_dp_shifted[name[1]].values, label=name[0]+' (SP) vs. '+name[1]+' (DP)')
plt.legend()
```
%% Cell type:code id: tags:
``` python
plt.figure()
for name in [('itrafo_shift', 'itrafo_shift')]:
plt.plot(trafo_component_sp_shifted[name[0]].time, trafo_component_sp_shifted[name[0]].values - trafo_component_dp_shifted[name[1]].values, label=name[0]+' (SP) vs. '+name[1]+' (DP)')
plt.legend()
```
%% Cell type:markdown id: tags:
### Assertion SP vs. DP
%% Cell type:code id: tags:
``` python
compare_errors_abs = []
compare_errors_rel = []
for name in [('v1_shift', 'v1_shift'), ('itrafo_shift', 'itrafo_shift')]:
compare_errors_abs.append(np.absolute(trafo_component_sp_shifted[name[0]].values - trafo_component_dp_shifted[name[1]].values).max())
compare_errors_rel.append(np.absolute(trafo_component_sp_shifted[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) < 3e-1
```
%% Cell type:code id: tags:
``` python
```
......
......@@ -23,6 +23,8 @@ namespace Base {
Real mRc;
/// transformer
Real mTransformerNominalVoltageEnd1;
Real mTransformerNominalVoltageEnd2;
Real mTransformerResistance;
Real mTransformerInductance;
Real mTransformerRatioAbs;
......
......@@ -15,6 +15,10 @@ namespace Base {
namespace Ph1 {
class Transformer {
protected:
/// Nominal voltage of primary side
Real mNominalVoltageEnd1;
/// Nominal voltage of secondary side
Real mNominalVoltageEnd2;
/// Complex transformer ratio
Complex mRatio;
/// Resistance [Ohm]
......@@ -24,7 +28,9 @@ namespace Ph1 {
public:
///
void setParameters(Real ratioAbs, Real ratioPhase, Real resistance, Real inductance) {
void setParameters(Real nomVoltageEnd1, Real nomVoltageEnd2, Real ratioAbs, Real ratioPhase, Real resistance, Real inductance) {
mNominalVoltageEnd1 = nomVoltageEnd1;
mNominalVoltageEnd2 = nomVoltageEnd2;
mRatio = std::polar<Real>(ratioAbs, ratioPhase);
mResistance = resistance;
mInductance = inductance;
......
......@@ -47,7 +47,7 @@ namespace Ph1 {
// #### General ####
/// Defines component parameters
void setParameters(Real ratioAbs, Real ratioPhase, Real resistance, Real inductance);
void setParameters(Real nomVoltageEnd1, Real nomVoltageEnd2, Real ratioAbs, Real ratioPhase, Real resistance, Real inductance);
/// Initializes component from power flow data
void initializeFromNodesAndTerminals(Real frequency);
......
......@@ -44,10 +44,6 @@ namespace Ph1 {
Real mRatioAbs = 1;
/// Transformer ratio pase [deg]
Real mRatioPhase = 0;
/// Nominal voltage of primary side
Real mNominalVoltageEnd1;
/// Nominal voltage of secondary side
Real mNominalVoltageEnd2;
/// Nominal omega
Real mNominalOmega;
......
......@@ -13,6 +13,8 @@ using namespace CPS;
void Base::AvVoltageSourceInverterDQ::setTransformerParameters(Real nomVoltageEnd1, Real nomVoltageEnd2, Real ratedPower, Real ratioAbs,
Real ratioPhase, Real resistance, Real inductance, Real omega) {
mTransformerNominalVoltageEnd1 = nomVoltageEnd1;
mTransformerNominalVoltageEnd2 = nomVoltageEnd2;
mTransformerResistance = resistance;
mTransformerInductance = inductance;
mTransformerRatioAbs = ratioAbs;
......
......@@ -512,7 +512,7 @@ TopologicalPowerComp::Ptr Reader::mapPowerTransformer(CIMPP::PowerTransformer* t
else {
Bool withResistiveLosses = resistance > 0;
auto transformer = std::make_shared<DP::Ph1::Transformer>(trans->mRID, trans->name, mComponentLogLevel, withResistiveLosses);
transformer->setParameters(ratioAbs, ratioPhase, resistance, inductance);
transformer->setParameters(voltageNode1, voltageNode2, ratioAbs, ratioPhase, resistance, inductance);
return transformer;
}
}
......
......@@ -100,11 +100,12 @@ void DP::Ph1::AvVoltageSourceInverterDQ::setTransformerParameters(Real nomVoltag
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, mTransformerResistance, mTransformerInductance);
mConnectionTransformer->setParameters(mTransformerNominalVoltageEnd1, mTransformerNominalVoltageEnd2, mTransformerRatioAbs, mTransformerRatioPhase, mTransformerResistance, mTransformerInductance);
}
void DP::Ph1::AvVoltageSourceInverterDQ::setControllerParameters(Real Kp_pll, Real Ki_pll,
......
......@@ -32,17 +32,18 @@ DP::Ph1::Transformer::Transformer(String uid, String name,
SimPowerComp<Complex>::Ptr DP::Ph1::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 DP::Ph1::Transformer::setParameters(Real ratioAbs, Real ratioPhase,
void DP::Ph1::Transformer::setParameters(Real nomVoltageEnd1, Real nomVoltageEnd2, Real ratioAbs, Real ratioPhase,
Real resistance, Real inductance) {
Base::Ph1::Transformer::setParameters(ratioAbs, ratioPhase, resistance, inductance);
mSLog->info("Resistance={} [Ohm] Inductance={} [Ohm] (referred to primary side)", resistance, inductance);
mSLog->info("Tap Ratio={} [ ] Phase Shift={} [deg]", ratioAbs, ratioPhase);
Base::Ph1::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));
mParametersSet = true;
}
......@@ -87,8 +88,8 @@ void DP::Ph1::Transformer::initializeFromNodesAndTerminals(Real frequency) {
mSubInductor->initializeFromNodesAndTerminals(frequency);
// Create parallel sub components
// A snubber conductance is added on the low voltage side (resistance approximately scaled with LV side voltage)
mSnubberResistance = std::abs(node(1)->initialSingleVoltage())*1e6;
// A snubber conductance is added on the low voltage side (resistance scaled with lower voltage side)
mSnubberResistance = mNominalVoltageEnd1 > mNominalVoltageEnd2 ? std::abs(mNominalVoltageEnd2)*1e6 : std::abs(mNominalVoltageEnd1)*1e6;
mSubSnubResistor = std::make_shared<DP::Ph1::Resistor>(mName + "_snub_res", mLogLevel);
mSubSnubResistor->setParameters(mSnubberResistance);
mSubSnubResistor->connect({ node(1), DP::SimNode::GND });
......
......@@ -45,22 +45,21 @@ SP::Ph1::Transformer::Transformer(String uid, String name, Logger::Level logLeve
void SP::Ph1::Transformer::setParameters(Real nomVoltageEnd1, Real nomVoltageEnd2, Real ratedPower, Real ratioAbs,
Real ratioPhase, Real resistance, Real inductance, Real omega) {
// Note: to be consistent impedance values must be referred to high voltage side (and base voltage set to higher voltage)
mNominalVoltageEnd1 = nomVoltageEnd1;
mNominalVoltageEnd2 = nomVoltageEnd2;
Base::Ph1::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));
mRatedPower = ratedPower;
mRatio = Complex(ratioAbs*cos(ratioPhase), ratioAbs*sin(ratioPhase));
mRatioAbs = ratioAbs;
mRatioPhase = ratioPhase;
mResistance = resistance;
mInductance = inductance;
mRatioAbs = std::abs(mRatio);
mRatioPhase = std::arg(mRatio);
mConductance = 1 / mResistance;
mNominalOmega = omega;
mReactance = mNominalOmega * mInductance;
mSLog->info("Resistance={} [Ohm] Reactance={} [Ohm] (referred to primary side)", mResistance, mReactance);
mSLog->info("Tap Ratio={} [ ] Phase Shift={} [deg]", mRatioAbs, mRatioPhase);
mParametersSet = true;
}
......@@ -111,11 +110,8 @@ void SP::Ph1::Transformer::initializeFromNodesAndTerminals(Real frequency) {
mSubInductor->initializeFromNodesAndTerminals(frequency);
// Create parallel sub components
// A snubber conductance is added on the low voltage side (resistance approximately scaled with LV side voltage)
if (Math::abs(mRatio) < 1.)
mSnubberResistance = std::abs(mNominalVoltageEnd1)*1e6;
else
mSnubberResistance = std::abs(mNominalVoltageEnd2)*1e6;
// A snubber conductance is added on the low voltage side (resistance scaled with lower voltage side)
mSnubberResistance = mNominalVoltageEnd1 > mNominalVoltageEnd2 ? std::abs(mNominalVoltageEnd2)*1e6 : std::abs(mNominalVoltageEnd1)*1e6;
mSubSnubResistor = std::make_shared<SP::Ph1::Resistor>(mUID + "_snub_res", mName + "_snub_res", Logger::Level::off);
mSubSnubResistor->setParameters(mSnubberResistance);
mSubSnubResistor->connect({ node(1), SP::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