DPsim
Loading...
Searching...
No Matches
DecouplingIdealTransformer_SP_Ph1.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
7#include <cstdlib>
9
10using namespace CPS;
11using namespace CPS::SP::Ph1;
12using namespace CPS::Signal;
13
15 String name, Logger::Level logLevel)
16 : SimSignalComp(name, name, logLevel),
17 mStates(mAttributes->create<Matrix>("states")),
20 mSrcVoltageRef(mAttributes->create<Complex>("v_ref")),
21 mSrcCurrentRef(mAttributes->create<Complex>("i_ref")) {
22
23 mRes1 = Resistor::make(name + "_r1", logLevel);
24 mRes2 = Resistor::make(name + "_r2", logLevel);
27
28 mSrcVoltage = mVoltageSrc->mVoltageRef;
29 mSrcCurrent = mCurrentSrc->mCurrentRef;
30}
31
34 Matrix voltageSrcIntfCurr, Complex current1Extrap0, CouplingMethod method) {
35
36 mNode1 = node1;
37 mNode2 = node2;
39
40 mDelay = delay;
41 mCouplingMethod = method;
42
45 }
46
47 mRes1->setParameters(mInternalSeriesResistance);
48 mRes1->connect({node1, mVirtualNode});
49 mRes2->setParameters(mInternalParallelResistance);
50 mRes2->connect({node2, SimNode<Complex>::GND});
51 mVoltageSrc->setParameters(Complex(0, 0));
52 mVoltageSrcIntfCurr = voltageSrcIntfCurr;
53 mCurrent1Extrap0 = current1Extrap0;
55 mCurrentSrc->setParameters(Complex(0, 0));
56 mCurrentSrc->connect({SimNode<Complex>::GND, node2});
57}
58
60 if (mDelay <= 0) {
61 mDelay = 0;
62 mBufSize = 1;
63 mAlpha = 1;
64 } else {
65 mBufSize = static_cast<UInt>(ceil(mDelay / timeStep));
66 mAlpha = 1 - (mBufSize - mDelay / timeStep);
67 }
68 SPDLOG_LOGGER_INFO(mSLog, "bufsize {} alpha {}", mBufSize, mAlpha);
69
70 mVoltageSrc->setIntfCurrent(mVoltageSrcIntfCurr);
71 Complex cur1 = mVoltageSrc->mIntfCurrent->get()(0);
72 Complex volt2 = mNode2->initialSingleVoltage() * RMS3PH_TO_PEAK1PH;
73
74 mVirtualNode->setInitialVoltage(mNode1->initialSingleVoltage() *
77
78 SPDLOG_LOGGER_INFO(mSLog, "initial current: i_1 {}", cur1);
79 SPDLOG_LOGGER_INFO(mSLog, "initial voltage: v_2 {}", volt2);
80
81 **mSrcVoltageRef = volt2;
82 **mSrcCurrentRef = cur1;
83 mVoltageSrc->setParameters(**mSrcVoltageRef);
84 mCurrentSrc->setParameters(**mSrcCurrentRef);
85
86 Matrix mSourceCurrentIntfVoltage(1, 1);
87 mSourceCurrentIntfVoltage(0, 0) = std::abs(volt2);
88 mCurrentSrc->setIntfVoltage(mSourceCurrentIntfVoltage);
89
90 mVoltageSrc->setIntfVoltage(mSourceCurrentIntfVoltage);
91 mVoltageSrc->setIntfCurrent(mVoltageSrcIntfCurr);
92
94 **mSourceVoltageIntfCurrent = mVoltageSrc->intfCurrent()(0, 0);
95
96 // Resize ring buffers and initialize
97 mCur1.resize(mBufSize, cur1);
98 mVol2.resize(mBufSize, volt2);
99
100 SPDLOG_LOGGER_INFO(mSLog, "Verify initial current: i_1 {}",
101 mCurrentSrc->intfCurrent()(0, 0));
102 SPDLOG_LOGGER_INFO(mSLog, "Verify initial voltage: v_2 {}",
103 mVoltageSrc->intfVoltage()(0, 0));
104
105 mCur1Extrap = std::vector<Complex>(mExtrapolationDegree + 1, Complex(0, 0));
107 if (mExtrapolationDegree > 0) {
109 }
110 mVol2Extrap = std::vector<Complex>(mExtrapolationDegree + 1, volt2);
111}
112
115 Complex c1 = data[mBufIdx];
116 Complex c2 = mBufIdx == mBufSize - 1 ? data[0] : data[mBufIdx + 1];
117 return mAlpha * c1 + (1 - mAlpha) * c2;
118}
119
124 Complex c2 =
126 Real delayFraction =
127 (mDelay * (mBufIdx + 1)) / static_cast<float>(mBufSize);
128 Real tEval = mDelay + delayFraction;
129 return ((c2 - c1) / mDelay) * tEval + c1;
130 } else {
131 return data[mMacroBufIdx];
132 }
133}
134
136 Complex volt1, cur2;
138 volt1 = interpolate(mVol2);
139 cur2 = interpolate(mCur1);
140 } else {
141 volt1 = extrapolate(mVol2Extrap);
142 cur2 = extrapolate(mCur1Extrap);
143 }
144
145 // Update voltage and current
146 **mSrcVoltageRef = volt1;
147 **mSrcCurrentRef = cur2;
148 **mSourceVoltageIntfVoltage = mVoltageSrc->intfVoltage()(0, 0);
149 **mSourceVoltageIntfCurrent = mVoltageSrc->intfCurrent()(0, 0);
150
153}
154
156 Int timeStepCount) {
157 mITM.step(time, timeStepCount);
158}
159
161 // Update ringbuffers with new values
162 mCur1[mBufIdx] = mVoltageSrc->intfCurrent()(0, 0);
163 mVol2[mBufIdx] = -mCurrentSrc->intfVoltage()(0, 0);
164
165 mBufIdx++;
166 if (mBufIdx == mBufSize) {
169 mMacroBufIdx++;
171 mMacroBufIdx = 0;
172 }
173 mBufIdx = 0;
174 }
175}
176
178 Int timeStepCount) {
179 mITM.postStep();
180}
181
183 return Task::List(
184 {std::make_shared<PreStep>(*this), std::make_shared<PostStep>(*this)});
185}
186
190
std::vector< Ptr > List
AttributeList::Ptr mAttributes
Attribute List.
spdlog::level::level_enum Level
Definition Logger.h:33
void execute(Real time, Int timeStepCount)
std::shared_ptr< SP::Ph1::ControlledCurrentSource > mCurrentSrc
void setParameters(SimNode< Complex >::Ptr node1, SimNode< Complex >::Ptr node2, Real delay, Matrix voltageSrcIntfCurr, Complex current1Extrap0, CouplingMethod method=CouplingMethod::DELAY)
DecouplingIdealTransformer_SP_Ph1(String name, Logger::Level logLevel=Logger::Level::info)
const Attribute< Matrix >::Ptr mStates
FIXME: workaround for dependency analysis as long as the states aren't attributes.
std::shared_ptr< SP::Ph1::ControlledVoltageSource > mVoltageSrc
std::shared_ptr< SimNode< VarType > > Ptr
Definition SimNode.h:32
static Ptr GND
Definition SimNode.h:35
SimSignalComp(String uid, String name, Logger::Level logLevel=Logger::Level::off)
std::vector< Ptr > List
Definition Task.h:28
std::shared_ptr< TopologicalNode > Ptr
Logger::Log mSLog
Component logger.
static std::shared_ptr< Resistor > make(Args &&...args)
Definition PtrFactory.h:19
#define RMS3PH_TO_PEAK1PH
Definition Definitions.h:50
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
CouplingMethod
int Int
Definition Definitions.h:61
std::complex< Real > Complex
Definition Definitions.h:63
unsigned int UInt
Definition Definitions.h:60