9 #include <dpsim-models/Signal/DecouplingLineEMT.h>
12 using namespace CPS::EMT::Ph1;
13 using namespace CPS::Signal;
15 DecouplingLineEMT::DecouplingLineEMT(String name, Logger::Level logLevel)
17 mStates(mAttributes->create<Matrix>(
"states")),
18 mSrcCur1Ref(mAttributes->create<Real>(
"i_src1")),
19 mSrcCur2Ref(mAttributes->create<Real>(
"i_src2")) {
21 mRes1 = Resistor::make(name +
"_r1", logLevel);
22 mRes2 = Resistor::make(name +
"_r2", logLevel);
23 mSrc1 = CurrentSource::make(name +
"_i1", logLevel);
24 mSrc2 = CurrentSource::make(name +
"_i2", logLevel);
26 mSrcCur1 = mSrc1->mCurrentRef;
27 mSrcCur2 = mSrc2->mCurrentRef;
30 void DecouplingLineEMT::setParameters(SimNode<Real>::Ptr node1,
31 SimNode<Real>::Ptr node2, Real resistance,
32 Real inductance, Real capacitance) {
34 mResistance = resistance;
35 mInductance = inductance;
36 mCapacitance = capacitance;
40 mSurgeImpedance = sqrt(inductance / capacitance);
41 mDelay = sqrt(inductance * capacitance);
42 SPDLOG_LOGGER_INFO(
mSLog,
"surge impedance: {}", mSurgeImpedance);
43 SPDLOG_LOGGER_INFO(
mSLog,
"delay: {}", mDelay);
45 mRes1->setParameters(mSurgeImpedance + mResistance / 4);
47 mRes2->setParameters(mSurgeImpedance + mResistance / 4);
49 mSrc1->setParameters(0);
51 mSrc2->setParameters(0);
55 void DecouplingLineEMT::initialize(Real omega, Real timeStep) {
56 if (mDelay < timeStep)
57 throw SystemError(
"Timestep too large for decoupling");
59 mBufSize =
static_cast<UInt
>(ceil(mDelay / timeStep));
60 mAlpha = 1 - (mBufSize - mDelay / timeStep);
61 SPDLOG_LOGGER_INFO(
mSLog,
"bufsize {} alpha {}", mBufSize, mAlpha);
64 Complex volt1 = mNode1->initialSingleVoltage();
65 Complex volt2 = mNode2->initialSingleVoltage();
66 Complex initAdmittance = 1. / Complex(mResistance, omega * mInductance) +
67 Complex(0, omega * mCapacitance / 2);
68 Complex cur1 = volt1 * initAdmittance -
69 volt2 / Complex(mResistance, omega * mInductance);
70 Complex cur2 = volt2 * initAdmittance -
71 volt1 / Complex(mResistance, omega * mInductance);
72 SPDLOG_LOGGER_INFO(
mSLog,
"initial voltages: v_k {} v_m {}", volt1, volt2);
73 SPDLOG_LOGGER_INFO(
mSLog,
"initial currents: i_km {} i_mk {}", cur1, cur2);
76 mVolt1.resize(mBufSize, volt1.real());
77 mVolt2.resize(mBufSize, volt2.real());
78 mCur1.resize(mBufSize, cur1.real());
79 mCur2.resize(mBufSize, cur2.real());
82 Real DecouplingLineEMT::interpolate(std::vector<Real> &data) {
84 Real c1 = data[mBufIdx];
85 Real c2 = mBufIdx == mBufSize - 1 ? data[0] : data[mBufIdx + 1];
86 return mAlpha * c1 + (1 - mAlpha) * c2;
89 void DecouplingLineEMT::step(Real time, Int timeStepCount) {
90 Real volt1 = interpolate(mVolt1);
91 Real volt2 = interpolate(mVolt2);
92 Real cur1 = interpolate(mCur1);
93 Real cur2 = interpolate(mCur2);
95 (mSurgeImpedance + mResistance / 4) * (mSurgeImpedance + mResistance / 4);
97 if (timeStepCount == 0) {
99 **mSrcCur1Ref = cur1 - volt1 / (mSurgeImpedance + mResistance / 4);
100 **mSrcCur2Ref = cur2 - volt2 / (mSurgeImpedance + mResistance / 4);
103 **mSrcCur1Ref = -mSurgeImpedance / denom *
104 (volt2 + (mSurgeImpedance - mResistance / 4) * cur2) -
105 mResistance / 4 / denom *
106 (volt1 + (mSurgeImpedance - mResistance / 4) * cur1);
107 **mSrcCur2Ref = -mSurgeImpedance / denom *
108 (volt1 + (mSurgeImpedance - mResistance / 4) * cur1) -
109 mResistance / 4 / denom *
110 (volt2 + (mSurgeImpedance - mResistance / 4) * cur2);
112 mSrcCur1->
set(**mSrcCur1Ref);
113 mSrcCur2->
set(**mSrcCur2Ref);
116 void DecouplingLineEMT::PreStep::execute(Real time, Int timeStepCount) {
117 mLine.step(time, timeStepCount);
120 void DecouplingLineEMT::postStep() {
122 mVolt1[mBufIdx] = -mRes1->intfVoltage()(0, 0);
123 mVolt2[mBufIdx] = -mRes2->intfVoltage()(0, 0);
124 mCur1[mBufIdx] = -mRes1->intfCurrent()(0, 0) + mSrcCur1->
get().real();
125 mCur2[mBufIdx] = -mRes2->intfCurrent()(0, 0) + mSrcCur2->
get().real();
128 if (mBufIdx == mBufSize)
132 void DecouplingLineEMT::PostStep::execute(Real time, Int timeStepCount) {
136 Task::List DecouplingLineEMT::getTasks() {
138 {std::make_shared<PreStep>(*
this), std::make_shared<PostStep>(*
this)});
141 IdentifiedObject::List DecouplingLineEMT::getLineComponents() {
142 return IdentifiedObject::List({mRes1, mRes2, mSrc1, mSrc2});
virtual void set(T value)=0
Logger::Log mSLog
Component logger.