9 #include <dpsim-models/DP/DP_Ph1_Inductor.h>
23 auto copy = Inductor::make(name, mLogLevel);
24 copy->setParameters(**mInductance);
31 mEquivCurrent = MatrixComp::Zero(mNumFreqs, 1);
32 mEquivCond = MatrixComp::Zero(mNumFreqs, 1);
33 mPrevCurrFac = MatrixComp::Zero(mNumFreqs, 1);
38 Real omega = 2. * PI * frequency;
39 Complex impedance = {0, omega * **mInductance};
40 (**mIntfVoltage)(0, 0) = initialSingleVoltage(1) - initialSingleVoltage(0);
41 (**mIntfCurrent)(0, 0) = (**mIntfVoltage)(0, 0) / impedance;
43 SPDLOG_LOGGER_INFO(mSLog,
44 "\nInductance [H]: {:s}"
45 "\nImpedance [Ohm]: {:s}",
46 Logger::realToString(**mInductance),
47 Logger::complexToString(impedance));
48 SPDLOG_LOGGER_INFO(mSLog,
49 "\n--- Initialization from powerflow ---"
50 "\nVoltage across: {:s}"
52 "\nTerminal 0 voltage: {:s}"
53 "\nTerminal 1 voltage: {:s}"
54 "\n--- Initialization from powerflow finished ---",
55 Logger::phasorToString((**mIntfVoltage)(0, 0)),
56 Logger::phasorToString((**mIntfCurrent)(0, 0)),
57 Logger::phasorToString(initialSingleVoltage(0)),
58 Logger::phasorToString(initialSingleVoltage(1)));
63 void DP::Ph1::Inductor::initVars(Real timeStep) {
64 for (UInt freq = 0; freq < mNumFreqs; freq++) {
65 Real a = timeStep / (2. * **mInductance);
66 Real b = timeStep * 2. * PI * mFrequencies(freq, 0) / 2.;
68 Real equivCondReal = a / (1. + b * b);
69 Real equivCondImag = -a * b / (1. + b * b);
70 mEquivCond(freq, 0) = {equivCondReal, equivCondImag};
71 Real preCurrFracReal = (1. - b * b) / (1. + b * b);
72 Real preCurrFracImag = (-2. * b) / (1. + b * b);
73 mPrevCurrFac(freq, 0) = {preCurrFracReal, preCurrFracImag};
76 mEquivCurrent(freq, 0) = mEquivCond(freq, 0) * (**mIntfVoltage)(0, freq) +
77 mPrevCurrFac(freq, 0) * (**mIntfCurrent)(0, freq);
78 (**mIntfCurrent)(0, freq) =
79 mEquivCond(freq, 0) * (**mIntfVoltage)(0, freq) +
80 mEquivCurrent(freq, 0);
86 updateMatrixNodeIndices();
89 SPDLOG_LOGGER_INFO(mSLog,
90 "\n--- MNA initialization ---"
91 "\nInitial voltage {:s}"
92 "\nInitial current {:s}"
93 "\nEquiv. current {:s}"
94 "\n--- MNA initialization finished ---",
95 Logger::phasorToString((**mIntfVoltage)(0, 0)),
96 Logger::phasorToString((**mIntfCurrent)(0, 0)),
97 Logger::complexToString(mEquivCurrent(0, 0)));
100 void DP::Ph1::Inductor::mnaCompInitializeHarm(
101 Real omega, Real timeStep,
103 updateMatrixNodeIndices();
107 mMnaTasks.push_back(std::make_shared<MnaPreStepHarm>(*
this));
108 mMnaTasks.push_back(std::make_shared<MnaPostStepHarm>(*
this, leftVectors));
109 **mRightVector = Matrix::Zero(leftVectors[0]->get().rows(), mNumFreqs);
113 SparseMatrixRow &systemMatrix) {
114 for (UInt freq = 0; freq < mNumFreqs; freq++) {
115 MNAStampUtils::stampAdmittance(
116 mEquivCond(freq, 0), systemMatrix, matrixNodeIndex(0),
117 matrixNodeIndex(1), terminalNotGrounded(0), terminalNotGrounded(1),
118 mSLog, mNumFreqs, freq);
122 void DP::Ph1::Inductor::mnaCompApplySystemMatrixStampHarm(
123 SparseMatrixRow &systemMatrix, Int freqIdx) {
124 MNAStampUtils::stampAdmittance(mEquivCond(freqIdx, 0), systemMatrix,
125 matrixNodeIndex(0), matrixNodeIndex(1),
126 terminalNotGrounded(0), terminalNotGrounded(1),
131 for (UInt freq = 0; freq < mNumFreqs; freq++) {
133 mEquivCurrent(freq, 0) = mEquivCond(freq, 0) * (**mIntfVoltage)(0, freq) +
134 mPrevCurrFac(freq, 0) * (**mIntfCurrent)(0, freq);
136 if (terminalNotGrounded(0))
137 Math::setVectorElement(rightVector, matrixNodeIndex(0),
138 mEquivCurrent(freq, 0), mNumFreqs, freq);
139 if (terminalNotGrounded(1))
140 Math::setVectorElement(rightVector, matrixNodeIndex(1),
141 -mEquivCurrent(freq, 0), mNumFreqs, freq);
143 SPDLOG_LOGGER_DEBUG(mSLog,
"MNA EquivCurrent {:s}",
144 Logger::complexToString(mEquivCurrent(freq, 0)));
145 if (terminalNotGrounded(0))
146 SPDLOG_LOGGER_DEBUG(mSLog,
"Add {:s} to source vector at {:d}",
147 Logger::complexToString(mEquivCurrent(freq, 0)),
149 if (terminalNotGrounded(1))
150 SPDLOG_LOGGER_DEBUG(mSLog,
"Add {:s} to source vector at {:d}",
151 Logger::complexToString(-mEquivCurrent(freq, 0)),
156 void DP::Ph1::Inductor::mnaCompApplyRightSideVectorStampHarm(
157 Matrix &rightVector) {
158 for (UInt freq = 0; freq < mNumFreqs; freq++) {
160 mEquivCurrent(freq, 0) = mEquivCond(freq, 0) * (**mIntfVoltage)(0, freq) +
161 mPrevCurrFac(freq, 0) * (**mIntfCurrent)(0, freq);
163 if (terminalNotGrounded(0))
164 Math::setVectorElement(rightVector, matrixNodeIndex(0),
165 mEquivCurrent(freq, 0), 1, 0, freq);
166 if (terminalNotGrounded(1))
167 Math::setVectorElement(rightVector, matrixNodeIndex(1),
168 -mEquivCurrent(freq, 0), 1, 0, freq);
173 AttributeBase::List &prevStepDependencies,
174 AttributeBase::List &attributeDependencies,
175 AttributeBase::List &modifiedAttributes) {
177 prevStepDependencies.push_back(mIntfVoltage);
178 prevStepDependencies.push_back(mIntfCurrent);
179 modifiedAttributes.push_back(mRightVector);
183 this->mnaApplyRightSideVectorStamp(**this->mRightVector);
187 AttributeBase::List &prevStepDependencies,
188 AttributeBase::List &attributeDependencies,
189 AttributeBase::List &modifiedAttributes,
191 attributeDependencies.push_back(leftVector);
192 modifiedAttributes.push_back(mIntfVoltage);
193 modifiedAttributes.push_back(mIntfCurrent);
198 this->mnaUpdateVoltage(**leftVector);
199 this->mnaUpdateCurrent(**leftVector);
202 void DP::Ph1::Inductor::MnaPreStepHarm::execute(Real time, Int timeStepCount) {
203 mInductor.mnaCompApplyRightSideVectorStampHarm(**mInductor.mRightVector);
206 void DP::Ph1::Inductor::MnaPostStepHarm::execute(Real time, Int timeStepCount) {
207 for (UInt freq = 0; freq < mInductor.mNumFreqs; freq++)
208 mInductor.mnaCompUpdateVoltageHarm(**mLeftVectors[freq], freq);
209 mInductor.mnaCompUpdateCurrentHarm();
214 for (UInt freq = 0; freq < mNumFreqs; freq++) {
215 (**mIntfVoltage)(0, freq) = 0;
216 if (terminalNotGrounded(1))
217 (**mIntfVoltage)(0, freq) = Math::complexFromVectorElement(
218 leftVector, matrixNodeIndex(1), mNumFreqs, freq);
219 if (terminalNotGrounded(0))
220 (**mIntfVoltage)(0, freq) =
221 (**mIntfVoltage)(0, freq) -
222 Math::complexFromVectorElement(leftVector, matrixNodeIndex(0),
225 SPDLOG_LOGGER_DEBUG(mSLog,
"Voltage {:s}",
226 Logger::phasorToString((**mIntfVoltage)(0, freq)));
230 void DP::Ph1::Inductor::mnaCompUpdateVoltageHarm(
const Matrix &leftVector,
233 (**mIntfVoltage)(0, freqIdx) = 0;
234 if (terminalNotGrounded(1))
235 (**mIntfVoltage)(0, freqIdx) =
236 Math::complexFromVectorElement(leftVector, matrixNodeIndex(1));
237 if (terminalNotGrounded(0))
238 (**mIntfVoltage)(0, freqIdx) =
239 (**mIntfVoltage)(0, freqIdx) -
240 Math::complexFromVectorElement(leftVector, matrixNodeIndex(0));
242 SPDLOG_LOGGER_DEBUG(mSLog,
"Voltage {:s}",
243 Logger::phasorToString((**mIntfVoltage)(0, freqIdx)));
247 for (UInt freq = 0; freq < mNumFreqs; freq++) {
248 (**mIntfCurrent)(0, freq) =
249 mEquivCond(freq, 0) * (**mIntfVoltage)(0, freq) +
250 mEquivCurrent(freq, 0);
251 SPDLOG_LOGGER_DEBUG(mSLog,
"Current {:s}",
252 Logger::phasorToString((**mIntfCurrent)(0, freq)));
256 void DP::Ph1::Inductor::mnaCompUpdateCurrentHarm() {
257 for (UInt freq = 0; freq < mNumFreqs; freq++) {
258 (**mIntfCurrent)(0, freq) =
259 mEquivCond(freq, 0) * (**mIntfVoltage)(0, freq) +
260 mEquivCurrent(freq, 0);
261 SPDLOG_LOGGER_DEBUG(mSLog,
"Current {:s}",
262 Logger::phasorToString((**mIntfCurrent)(0, freq)));
267 void DP::Ph1::Inductor::mnaTearInitialize(Real omega, Real timeStep) {
271 void DP::Ph1::Inductor::mnaTearApplyMatrixStamp(SparseMatrixRow &tearMatrix) {
272 Math::addToMatrixElement(tearMatrix, mTearIdx, mTearIdx,
273 1. / mEquivCond(0, 0));
276 void DP::Ph1::Inductor::mnaTearApplyVoltageStamp(Matrix &voltageVector) {
277 mEquivCurrent(0, 0) = mEquivCond(0, 0) * (**mIntfVoltage)(0, 0) +
278 mPrevCurrFac(0, 0) * (**mIntfCurrent)(0, 0);
279 Math::addToVectorElement(voltageVector, mTearIdx,
280 mEquivCurrent(0, 0) / mEquivCond(0, 0));
283 void DP::Ph1::Inductor::mnaTearPostStep(Complex voltage, Complex current) {
284 (**mIntfVoltage)(0, 0) = voltage;
285 (**mIntfCurrent)(0, 0) = mEquivCond(0, 0) * voltage + mEquivCurrent(0, 0);
void mnaCompUpdateCurrent(const Matrix &leftVector) override
Update interface current from MNA system results.
void mnaCompAddPostStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes, Attribute< Matrix >::Ptr &leftVector) override
Add MNA post step dependencies.
SimPowerComp< Complex >::Ptr clone(String name) override
Return new instance with the same parameters.
MatrixComp mEquivCurrent
DC equivalent current source for harmonics [A].
void mnaCompAddPreStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes) override
Add MNA pre step dependencies.
void mnaCompInitialize(Real omega, Real timeStep, Attribute< Matrix >::Ptr leftVector) override
Initializes MNA specific variables.
void mnaCompUpdateVoltage(const Matrix &leftVector) override
Update interface voltage from MNA system results.
void mnaCompPostStep(Real time, Int timeStepCount, Attribute< Matrix >::Ptr &leftVector) override
MNA post step operations.
void mnaCompApplyRightSideVectorStamp(Matrix &rightVector) override
Stamps right side (source) vector.
void initializeFromNodesAndTerminals(Real frequency) override
Initializes states from power flow data.
void initialize(Matrix frequencies) override
Initializes state variables considering the number of frequencies.
void mnaCompPreStep(Real time, Int timeStepCount) override
MNA pre step operations.
void mnaCompApplySystemMatrixStamp(SparseMatrixRow &systemMatrix) override
Stamps system matrix.
Inductor(String uid, String name, Logger::Level logLevel=Logger::Level::off)
Defines UID, name and log level.
Base class for all MNA components that are transmitting power.
Base class for all components that are transmitting power.
virtual void initialize(Matrix frequencies)
Initialize components with correct network frequencies.
const Attribute< MatrixVar< Complex > >::Ptr mIntfCurrent
Current through component.
const Attribute< MatrixVar< Complex > >::Ptr mIntfVoltage
Voltage between terminals.