10 #include <dpsim-models/DP/DP_Ph1_Inverter.h>
11 #include <dpsim-models/MathUtils.h>
19 setVirtualNodeNumber(1);
24 void DP::Ph1::Inverter::setParameters(
const std::vector<Int> &carrierHarms,
25 const std::vector<Int> &modulHarms,
26 Real inputVoltage, Real ratio,
28 mCarHarms = carrierHarms;
29 mModHarms = modulHarms;
34 mParametersSet =
true;
39 void DP::Ph1::Inverter::generateFrequencies() {
40 for (Int m = 2; m <= mMaxCarrierHarm; m = m + 2) {
41 mCarHarms.push_back(m);
42 SPDLOG_LOGGER_INFO(mSLog,
"Add carrier harmonic {0}", m);
44 for (Int n = -mMaxModulHarm; n <= mMaxModulHarm; n = n + 2) {
45 mModHarms.push_back(n);
46 SPDLOG_LOGGER_INFO(mSLog,
"Add modulation harmonic {0}", n);
53 SPDLOG_LOGGER_INFO(mSLog,
"\n--- Initialization ---");
56 mCarHarNum =
static_cast<UInt
>(mCarHarms.size());
57 mModHarNum =
static_cast<UInt
>(mModHarms.size());
58 if (mCarHarNum != mModHarNum) {
59 throw std::invalid_argument(
60 "Number of carrier and modulation harmonics must be equal.");
64 mPhasorMags = Matrix::Zero(mHarNum, 1);
65 mPhasorPhases = Matrix::Zero(mHarNum, 1);
66 mPhasorFreqs = Matrix::Zero(mHarNum, 1);
68 for (UInt h = 0; h < mHarNum; h++) {
69 mPhasorFreqs(h, 0) = mCarHarms[h] * mFreqCar + mModHarms[h] * mFreqMod;
70 mPhasorPhases(h, 0) = mCarHarms[h] * mPhaseCar + mModHarms[h] * mPhaseMod;
74 for (Int f = 0; f <= mMaxBesselSumIdx; f++) {
75 mFactorials.push_back(factorial(f));
78 for (UInt h = 0; h < mHarNum; h++) {
79 for (Int f = 0; f <= mMaxBesselSumIdx; f++)
80 mMultInvFactorials[f + mModHarms[h]] = multInvFactorial(f + mModHarms[h]);
83 SPDLOG_LOGGER_INFO(mSLog,
86 "\n--- End of initialization ---",
87 mPhasorFreqs, mPhasorPhases);
90 void DP::Ph1::Inverter::calculatePhasors() {
92 mVfund = mModIdx * mVin;
93 (**mIntfVoltage)(0, 0) = Complex(0, mVfund * -1);
97 for (UInt h = 0; h < mHarNum; h++) {
98 Real Jn = besselFirstKind_n_opt(mModHarms[h], mMaxBesselSumIdx,
99 mCarHarms[h] * mModIdx * PI / 2.);
102 (**mIntfVoltage)(0, h + 1) =
103 Complex(0, -1 * (4. * mVin / PI) * (Jn / mCarHarms[h]) *
104 cos(mCarHarms[h] * PI / 2.));
107 SPDLOG_LOGGER_DEBUG(mSLog,
108 "\n--- Phasor calculation ---"
111 "\n--- Phasor calculation end ---",
112 mPhasorMags, **mIntfVoltage);
119 updateMatrixNodeIndices();
123 void DP::Ph1::Inverter::mnaCompInitializeHarm(
124 Real omega, Real timeStep,
126 updateMatrixNodeIndices();
128 mMnaTasks.push_back(std::make_shared<MnaPreStepHarm>(*
this));
129 mMnaTasks.push_back(std::make_shared<MnaPostStepHarm>(*
this, leftVectors));
130 **mRightVector = Matrix::Zero(leftVectors[0]->get().rows(), mNumFreqs);
136 SparseMatrixRow &systemMatrix) {
137 SPDLOG_LOGGER_INFO(mSLog,
"--- Stamping into system matrix ---");
139 for (UInt freq = 0; freq < mNumFreqs; freq++) {
140 SPDLOG_LOGGER_INFO(mSLog,
"Stamp frequency {:d}", freq);
141 if (terminalNotGrounded(0)) {
142 Math::setMatrixElement(systemMatrix, mVirtualNodes[0]->matrixNodeIndex(),
143 matrixNodeIndex(0), Complex(1, 0), mNumFreqs,
145 Math::setMatrixElement(systemMatrix, matrixNodeIndex(0),
146 mVirtualNodes[0]->matrixNodeIndex(), Complex(1, 0),
150 if (terminalNotGrounded(0)) {
151 SPDLOG_LOGGER_INFO(mSLog,
"Add {:f} to system at ({:d},{:d})", 1.,
152 mVirtualNodes[0]->matrixNodeIndex(),
154 SPDLOG_LOGGER_INFO(mSLog,
"Add {:f} to system at ({:d},{:d})", 1.,
156 mVirtualNodes[0]->matrixNodeIndex());
159 SPDLOG_LOGGER_INFO(mSLog,
"--- Stamping into system matrix end ---");
162 void DP::Ph1::Inverter::mnaCompApplySystemMatrixStampHarm(
163 SparseMatrixRow &systemMatrix, Int freqIdx) {
164 SPDLOG_LOGGER_INFO(mSLog,
"Stamp frequency {:d}", freqIdx);
165 if (terminalNotGrounded(0)) {
166 Math::setMatrixElement(systemMatrix, mVirtualNodes[0]->matrixNodeIndex(),
167 matrixNodeIndex(0), Complex(1, 0));
168 Math::setMatrixElement(systemMatrix, matrixNodeIndex(0),
169 mVirtualNodes[0]->matrixNodeIndex(), Complex(1, 0));
172 if (terminalNotGrounded(0)) {
173 SPDLOG_LOGGER_INFO(mSLog,
"Add {:f} to system at ({:d},{:d})", 1.,
174 mVirtualNodes[0]->matrixNodeIndex(), matrixNodeIndex(0));
175 SPDLOG_LOGGER_INFO(mSLog,
"Add {:f} to system at ({:d},{:d})", 1.,
176 matrixNodeIndex(0), mVirtualNodes[0]->matrixNodeIndex());
181 SPDLOG_LOGGER_DEBUG(mSLog,
"Stamp harmonics into source vector");
182 for (UInt freq = 0; freq < mNumFreqs; freq++) {
183 if (terminalNotGrounded(0)) {
184 Math::setVectorElement(rightVector, mVirtualNodes[0]->matrixNodeIndex(),
185 (**mIntfVoltage)(0, freq), mNumFreqs, freq);
187 SPDLOG_LOGGER_DEBUG(mSLog,
188 "Add {:s} to source vector at {:d}, harmonic {:d}",
189 Logger::complexToString((**mIntfVoltage)(0, freq)),
190 mVirtualNodes[0]->matrixNodeIndex(), freq);
195 void DP::Ph1::Inverter::mnaCompApplyRightSideVectorStampHarm(
196 Matrix &rightVector) {
197 SPDLOG_LOGGER_DEBUG(mSLog,
"Stamp harmonics into source vector");
198 for (UInt freq = 0; freq < mNumFreqs; freq++) {
199 if (terminalNotGrounded(0)) {
200 Math::setVectorElement(rightVector, mVirtualNodes[0]->matrixNodeIndex(),
201 (**mIntfVoltage)(0, freq), 1, 0, freq);
206 void DP::Ph1::Inverter::mnaCompApplyRightSideVectorStampHarm(
207 Matrix &rightVector, Int freq) {
208 Math::setVectorElement(rightVector, mVirtualNodes[0]->matrixNodeIndex(),
209 (**mIntfVoltage)(0, freq));
213 AttributeBase::List &prevStepDependencies,
214 AttributeBase::List &attributeDependencies,
215 AttributeBase::List &modifiedAttributes) {
216 modifiedAttributes.push_back(mRightVector);
217 modifiedAttributes.push_back(mIntfVoltage);
220 void DP::Ph1::Inverter::mnaCompPreStep(Real time, Int timeStepCount) {
222 mnaCompApplyRightSideVectorStamp(**mRightVector);
225 void DP::Ph1::Inverter::MnaPreStepHarm::execute(Real time, Int timeStepCount) {
226 mInverter.calculatePhasors();
227 mInverter.mnaCompApplyRightSideVectorStampHarm(**mInverter.mRightVector);
231 AttributeBase::List &prevStepDependencies,
232 AttributeBase::List &attributeDependencies,
233 AttributeBase::List &modifiedAttributes,
235 attributeDependencies.push_back(leftVector);
236 modifiedAttributes.push_back(mIntfCurrent);
239 void DP::Ph1::Inverter::mnaCompPostStep(Real time, Int timeStepCount,
242 void DP::Ph1::Inverter::MnaPostStepHarm::execute(Real time, Int timeStepCount) {
251 for (Int k = 0; k <= k_max; ++k) {
252 Real Jn_k = pow(-1, k) / (double)factorial(k) * multInvFactorial(k + n) *
253 pow(x / 2., 2. * k + n);
262 for (Int k = 0; k <= k_max; ++k) {
263 Real Jn_k = pow(-1, k) / mFactorials[k] * mMultInvFactorials[k + n] *
264 pow(x / 2., 2. * k + n);
270 long long DP::Ph1::Inverter::factorial(Int n)
const {
271 return (n == 1 || n == 0) ? 1 : factorial(n - 1) * n;
274 Real DP::Ph1::Inverter::multInvFactorial(Int n)
const {
278 return 1. / (double)factorial(n);
281 Real DP::Ph1::Inverter::multInvIntGamma(Real n)
const {
285 return 1. / std::tgamma(n);
void mnaCompAddPreStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes) override
Add MNA pre step dependencies.
void mnaCompApplySystemMatrixStamp(SparseMatrixRow &systemMatrix) override
Stamps system matrix.
void initialize(Matrix frequencies) override
Initialize components with correct network frequencies.
Real besselFirstKind_n(Int n, Int k_max, Real x) const
Bessel function.
Real besselFirstKind_n_opt(Int n, Int k_max, Real x)
Bessel function using look up tables for factorials.
Inverter(String name, String uid, Logger::Level logLevel=Logger::Level::off)
Defines UID, name and logging level.
void mnaCompApplyRightSideVectorStamp(Matrix &rightVector) override
Stamps right side (source) vector.
void initializeFromNodesAndTerminals(Real frequency) override
Initializes Component variables according to power flow data stored in Nodes.
void mnaCompInitialize(Real omega, Real timeStep, Attribute< Matrix >::Ptr leftVector) override
Initializes internal variables of the component.
void mnaCompAddPostStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes, Attribute< Matrix >::Ptr &leftVector) override
Add MNA post step dependencies.
Base class for all MNA 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.