DPsim
Loading...
Searching...
No Matches
EMT_Ph3_HalfDecouplingLine.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2026 Institute for Automation of Complex Power Systems, EONERC, RWTH Aachen University
2// SPDX-License-Identifier: MPL-2.0
3
6
7using namespace CPS;
8
10 Logger::Level logLevel)
11 : CompositePowerComp<Real>(uid, name, true, true, logLevel),
13 mAttributes->create<Matrix>("i_src_ctrl", Matrix::Zero(3, 1))),
14 mSrcRes(mAttributes->create<Matrix>("src_res", Matrix::Zero(3, 3))),
15 mReceivingVolt(mAttributes->createDynamic<Matrix>("receiving_volt")),
16 mReceivingCur(mAttributes->createDynamic<Matrix>("receiving_cur")),
18 mAttributes->create<Matrix>("sending_volt", Matrix::Zero(3, 1))),
20 mAttributes->create<Matrix>("sending_cur", Matrix::Zero(3, 1))) {
21
25 **mIntfVoltage = Matrix::Zero(3, 1);
26 **mIntfCurrent = Matrix::Zero(3, 1);
27}
28
30 Matrix inductance,
31 Matrix capacitance) {
32
33 mResistance = resistance;
34 mInductance = inductance;
35 mCapacitance = capacitance;
36
37 mSurgeImpedance = (inductance * capacitance.inverse()).array().sqrt();
38 mDelay = (inductance.array() * capacitance.array()).sqrt().maxCoeff();
39
41
42 SPDLOG_LOGGER_INFO(mSLog, "surge impedance: {}", mSurgeImpedance);
43 SPDLOG_LOGGER_INFO(mSLog, "delay: {}", mDelay);
44
45 mParametersSet = true;
46}
47
49 Attribute<Matrix>::Ptr receivingVolt, Attribute<Matrix>::Ptr receivingCur) {
50 mReceivingVolt->setReference(receivingVolt);
51 mReceivingCur->setReference(receivingCur);
52}
53
72
74 Real frequency) {
75
76 **mIntfVoltage = initialVoltage(0).real();
77 **mIntfCurrent = Matrix::Zero(3, 1);
78
79 **mSendingVolt = -(**mIntfVoltage);
80 **mSendingCur = Matrix::Zero(3, 1);
81}
82
84 Real omega, Real timeStep, Attribute<Matrix>::Ptr leftVector) {
85 if (mDelay < timeStep)
86 throw SystemError("Timestep too large for decoupling");
87
88 mBufSize = static_cast<UInt>(ceil(mDelay / timeStep));
89 mAlpha = 1 - (mBufSize - mDelay / timeStep);
90 SPDLOG_LOGGER_INFO(mSLog, "bufsize {} alpha {}", mBufSize, mAlpha);
91
92 MatrixComp voltNear = -initialVoltage(0);
93 MatrixComp voltFar = (**mReceivingVolt).cast<Complex>();
94
95 MatrixComp seriesAdmittance =
96 (mResistance + Complex(0, omega) * mInductance).inverse();
97 MatrixComp initAdmittance =
98 seriesAdmittance + Complex(0, omega) * mCapacitance / 2;
99 MatrixComp curNear = initAdmittance * voltNear - seriesAdmittance * voltFar;
100
101 SPDLOG_LOGGER_INFO(mSLog, "initial voltage: v_k {}", voltNear);
102 SPDLOG_LOGGER_INFO(mSLog, "initial current: i_k {}", curNear);
103
104 mVoltBuf = voltNear.real().transpose().replicate(mBufSize, 1);
105 mCurBuf = curNear.real().transpose().replicate(mBufSize, 1);
106
107 **mSendingVolt = voltNear.real();
108 **mSendingCur = curNear.real();
109}
110
112 Matrix c1 = data.row(mBufIdx);
113 Matrix c2 = mBufIdx == mBufSize - 1 ? data.row(0) : data.row(mBufIdx + 1);
114 return (mAlpha * c1 + (1 - mAlpha) * c2).transpose();
115}
116
117void EMT::Ph3::HalfDecouplingLine::step(Real time, Int timeStepCount) {
118 Matrix voltNear = **mSendingVolt;
119 Matrix curNear = **mSendingCur;
120 Matrix voltFar = **mReceivingVolt;
121 Matrix curFar = **mReceivingCur;
122
123 Matrix denom =
125
126 if (timeStepCount == 0) {
128 curNear - (mSurgeImpedance + mResistance / 4).inverse() * voltNear;
129 } else {
131 -mSurgeImpedance * denom.inverse() *
132 (voltFar + (mSurgeImpedance - mResistance / 4) * curFar) -
133 mResistance / 4 * denom.inverse() *
134 (voltNear + (mSurgeImpedance - mResistance / 4) * curNear);
135 }
136
137 mSubCtrledCurrentSource->mCurrentRef->set(**mSrcCtrledCurrent);
138}
139
141 mVoltBuf.row(mBufIdx) = -mSubRes->intfVoltage().transpose();
142 mCurBuf.row(mBufIdx) =
143 -mSubRes->intfCurrent().transpose() + (**mSrcCtrledCurrent).transpose();
144
145 mBufIdx++;
146 if (mBufIdx == mBufSize)
147 mBufIdx = 0;
148
151}
152
154 Int timeStepCount) {
155 step(time, timeStepCount);
156 mSubCtrledCurrentSource->mnaPreStep(time, timeStepCount);
158}
159
161 Real time, Int timeStepCount, Attribute<Matrix>::Ptr &leftVector) {
162 mnaCompUpdateVoltage(**leftVector);
163 mnaCompUpdateCurrent(**leftVector);
164 postStep();
165}
166
168 const Matrix &leftVector) {
169 (**mIntfVoltage)(0, 0) =
171 (**mIntfVoltage)(1, 0) =
173 (**mIntfVoltage)(2, 0) =
175}
176
178 const Matrix &leftVector) {
179 **mIntfCurrent = -mSubRes->intfCurrent() + **mSrcCtrledCurrent;
180}
181
183 AttributeBase::List &prevStepDependencies,
184 AttributeBase::List &attributeDependencies,
185 AttributeBase::List &modifiedAttributes) {
186 prevStepDependencies.push_back(mIntfCurrent);
187 prevStepDependencies.push_back(mIntfVoltage);
188 prevStepDependencies.push_back(mReceivingVolt);
189 prevStepDependencies.push_back(mReceivingCur);
190 modifiedAttributes.push_back(mRightVector);
191}
192
194 AttributeBase::List &prevStepDependencies,
195 AttributeBase::List &attributeDependencies,
196 AttributeBase::List &modifiedAttributes,
197 Attribute<Matrix>::Ptr &leftVector) {
198 attributeDependencies.push_back(leftVector);
199 modifiedAttributes.push_back(mIntfVoltage);
200 modifiedAttributes.push_back(mIntfCurrent);
201 modifiedAttributes.push_back(mSendingVolt);
202 modifiedAttributes.push_back(mSendingCur);
203}
std::vector< Ptr > List
Definition Attribute.h:123
AttributePointer< Attribute< T > > Ptr
Definition Attribute.h:249
void addMNASubComponent(typename SimPowerComp< Real >::Ptr subc, MNA_SUBCOMP_TASK_ORDER preStepOrder, MNA_SUBCOMP_TASK_ORDER postStepOrder, Bool contributeToRightVector)
void mnaCompApplyRightSideVectorStamp(Matrix &rightVector) override
CompositePowerComp(String uid, String name, Bool hasPreStep, Bool hasPostStep, Logger::Level logLevel)
const Attribute< Matrix >::Ptr mSrcCtrledCurrent
History current fed into the controlled current source.
Real mDelay
Travel time of the whole line.
std::shared_ptr< EMT::Ph3::ControlledCurrentSource > mSubCtrledCurrentSource
Controlled current source carrying the history term.
Matrix mSurgeImpedance
Surge impedance, sqrt(L/C)
const Attribute< Matrix >::Ptr mReceivingCur
Far-end current one travel time ago, supplied by the other half.
void mnaParentAddPostStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes, Attribute< Matrix >::Ptr &leftVector) override
Add MNA post step dependencies.
void mnaCompUpdateCurrent(const Matrix &leftVector) override
Updates internal current variable of the component.
void createSubComponents() override
Creates the terminating resistor and the history current source.
void mnaParentInitialize(Real omega, Real timeStep, Attribute< Matrix >::Ptr leftVector) override
Sizes the ring buffers and seeds them from the steady state.
void mnaParentPreStep(Real time, Int timeStepCount) override
MNA pre step operations.
const Attribute< Matrix >::Ptr mReceivingVolt
Far-end voltage one travel time ago, supplied by the other half.
void mnaParentPostStep(Real time, Int timeStepCount, Attribute< Matrix >::Ptr &leftVector) override
MNA post step operations.
const Attribute< Matrix >::Ptr mSendingVolt
This end's voltage one travel time ago, for the other half to read.
void setParameters(Matrix resistance, Matrix inductance, Matrix capacitance)
Line data. Give the parameters of the whole line, not of this half.
std::shared_ptr< EMT::Ph3::Resistor > mSubRes
Terminating impedance calculated from line parameters.
void mnaCompUpdateVoltage(const Matrix &leftVector) override
Updates internal voltage variable of the component.
HalfDecouplingLine(String name, Logger::Level logLevel=Logger::Level::off)
Defines name and logging level.
void initializeParentFromNodesAndTerminals(Real frequency) override
Seeds the interface quantities and the sending attributes.
const Attribute< Matrix >::Ptr mSrcRes
Terminating resistance.
Matrix mVoltBuf
Ring buffers for the values of previous timesteps, one row per stored step.
Matrix interpolate(Matrix &data)
Reads a ring buffer one travel time back.
const Attribute< Matrix >::Ptr mSendingCur
This end's current one travel time ago, for the other half to read.
void step(Real time, Int timeStepCount)
Updates the history current from the exchanged quantities.
void mnaParentAddPreStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes) override
Add MNA pre step dependencies.
void setCouplingSource(Attribute< Matrix >::Ptr receivingVolt, Attribute< Matrix >::Ptr receivingCur)
void postStep()
Records this end's quantities and publishes them one travel time delayed.
const Attribute< String >::Ptr mName
Human readable name.
String uid()
Returns unique id.
AttributeList::Ptr mAttributes
Attribute List.
spdlog::level::level_enum Level
Definition Logger.h:33
Attribute< Matrix >::Ptr mRightVector
static Real realFromVectorElement(const Matrix &mat, Matrix::Index row)
static Ptr GND
Definition SimNode.h:35
UInt matrixNodeIndex(UInt nodeIndex)
const Attribute< MatrixVar< Real > >::Ptr mIntfCurrent
SimTerminal< Real >::List mTerminals
void setVirtualNodeNumber(UInt num)
const Attribute< MatrixVar< Real > >::Ptr mIntfVoltage
MatrixComp initialVoltage(UInt index)
void setTerminalNumber(UInt num)
Logger::Level mLogLevel
Component logger control for internal variables.
bool mParametersSet
Flag indicating that parameters are set via setParameters() function.
Logger::Log mSLog
Component logger.
static std::shared_ptr< Resistor > make(Args &&...args)
Definition PtrFactory.h:19
struct dps_magma_data data
Eigen::Matrix< Real, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor > Matrix
Dense matrix for real numbers.
Definition Definitions.h:81
std::string String
Definition Definitions.h:65
double Real
Definition Definitions.h:62
int Int
Definition Definitions.h:61
std::complex< Real > Complex
Definition Definitions.h:63
Eigen::Matrix< Complex, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor > MatrixComp
Dense matrix for complex numbers.
Definition Definitions.h:84
unsigned int UInt
Definition Definitions.h:60