EMT_Ph3_AvVoltageSourceInverterDQ.cpp 19.4 KB
Newer Older
1
2
/* Copyright 2017-2020 Institute for Automation of Complex Power Systems,
 *                     EONERC, RWTH Aachen University
Markus Mirz's avatar
Markus Mirz committed
3
 *
4
5
6
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
Markus Mirz's avatar
Markus Mirz committed
7
8
9
10
11
12
 *********************************************************************************/

#include <cps/EMT/EMT_Ph3_AvVoltageSourceInverterDQ.h>

using namespace CPS;

13

14
EMT::Ph3::AvVoltageSourceInverterDQ::AvVoltageSourceInverterDQ(String uid, String name, Logger::Level logLevel, Bool withTrafo) :
15
	SimPowerComp<Real>(uid, name, logLevel) {
Markus Mirz's avatar
Markus Mirz committed
16
	mPhaseType = PhaseType::ABC;
17
	if (withTrafo) {
18
		setVirtualNodeNumber(4);
19
20
21
		mConnectionTransformer = EMT::Ph3::Transformer::make(mName + "_trans", Logger::Level::debug);
		mSubComponents.push_back(mConnectionTransformer);
	} else {
22
		setVirtualNodeNumber(3);
23
	}
24
	mWithConnectionTransformer = withTrafo;
Markus Mirz's avatar
Markus Mirz committed
25
	setTerminalNumber(1);
26

27
	mSLog->info("Create {} {}", type(), name);
Markus Mirz's avatar
Markus Mirz committed
28
29
30
	mIntfVoltage = Matrix::Zero(3, 1);
	mIntfCurrent = Matrix::Zero(3, 1);

31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
	// Create electrical sub components
	mSubResistorF = EMT::Ph3::Resistor::make(mName + "_resF", mLogLevel);
	mSubResistorC = EMT::Ph3::Resistor::make(mName + "_resC", mLogLevel);
	mSubCapacitorF = EMT::Ph3::Capacitor::make(mName + "_capF", mLogLevel);
	mSubInductorF = EMT::Ph3::Inductor::make(mName + "_indF", mLogLevel);
	mSubCtrledVoltageSource = EMT::Ph3::VoltageSource::make(mName + "_src", mLogLevel);
	mSubComponents.push_back(mSubResistorF);
	mSubComponents.push_back(mSubResistorC);
	mSubComponents.push_back(mSubCapacitorF);
	mSubComponents.push_back(mSubInductorF);
	mSubComponents.push_back(mSubCtrledVoltageSource);

	mSLog->info("Electrical subcomponents: ");
	for (auto subcomp: mSubComponents)
		mSLog->info("- {}", subcomp->name());

	// Create control sub components
	mPLL = Signal::PLL::make(mName + "_PLL", mLogLevel);
	mPowerControllerVSI = Signal::PowerControllerVSI::make(mName + "_PowerControllerVSI", mLogLevel);

	// general variables of inverter
52
53
54
	addAttribute<Real>("Omega_nom", &mOmegaN, Flags::read | Flags::write);
	addAttribute<Real>("P_ref", &mPref, Flags::read | Flags::write);
	addAttribute<Real>("Q_ref", &mQref, Flags::read | Flags::write);
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76

	// interfacing variables
	addAttribute<Real>("Vc_d", &mVcd, Flags::read | Flags::write);
	addAttribute<Real>("Vc_q", &mVcq, Flags::read | Flags::write);
	addAttribute<Real>("Irc_d", &mIrcd, Flags::read | Flags::write);
	addAttribute<Real>("Irc_q", &mIrcq, Flags::read | Flags::write);
	addAttribute<MatrixComp>("Vsref", &mVsref, Flags::read | Flags::write);

	// PLL
	mPLL->setAttributeRef("input_ref", attribute<Real>("Vc_q"));
	addAttributeRef<Matrix>("pll_output", mPLL->attribute<Matrix>("output_curr"), Flags::read);

	// Power controller
	// input references
	mPowerControllerVSI->setAttributeRef("Vc_d", attribute<Real>("Vc_d"));
	mPowerControllerVSI->setAttributeRef("Vc_q", attribute<Real>("Vc_q"));
	mPowerControllerVSI->setAttributeRef("Irc_d", attribute<Real>("Irc_d"));
	mPowerControllerVSI->setAttributeRef("Irc_q", attribute<Real>("Irc_q"));
	// input, state and output vector for logging
	addAttributeRef<Matrix>("powerctrl_inputs", mPowerControllerVSI->attribute<Matrix>("input_curr"), Flags::read);
	addAttributeRef<Matrix>("powerctrl_states", mPowerControllerVSI->attribute<Matrix>("state_curr"), Flags::read);
	addAttributeRef<Matrix>("powerctrl_outputs", mPowerControllerVSI->attribute<Matrix>("output_curr"), Flags::read);
77
78
79
}

void EMT::Ph3::AvVoltageSourceInverterDQ::setParameters(Real sysOmega, Real sysVoltNom, Real Pref, Real Qref) {
80
	mParametersSet = true;
81
82

	mSLog->info("General Parameters:");
83
84
85
86
87
88
89
90
91
	mSLog->info("Nominal Voltage={} [V] Nominal Omega={} [1/s]", sysVoltNom, sysOmega);
	mSLog->info("Active Power={} [W] Reactive Power={} [VAr]", Pref, Qref);

	mPowerControllerVSI->setParameters(Pref, Qref);

	mOmegaN = sysOmega;
	mVnom = sysVoltNom;
	mPref = Pref;
	mQref = Qref;
Markus Mirz's avatar
Markus Mirz committed
92
93
}

94
95
96
void EMT::Ph3::AvVoltageSourceInverterDQ::setTransformerParameters(Real nomVoltageEnd1, Real nomVoltageEnd2,
	Real ratedPower, Real ratioAbs,	Real ratioPhase, Real resistance, Real inductance, Real omega) {

97
	Base::AvVoltageSourceInverterDQ::setTransformerParameters(nomVoltageEnd1, nomVoltageEnd2,
98
99
100
101
102
		ratedPower, ratioAbs, ratioPhase, resistance, inductance, omega);

	mSLog->info("Connection Transformer Parameters:");
	mSLog->info("Resistance={} [Ohm] Inductance={} [H]", mTransformerResistance, mTransformerInductance);
    mSLog->info("Tap Ratio={} [ ] Phase Shift={} [deg]", mTransformerRatioAbs, mTransformerRatioPhase);
103
104
105

	if (mWithConnectionTransformer)
		mConnectionTransformer->setParameters(mTransformerRatioAbs, mTransformerRatioPhase, CPS::CIM::Reader::singlePhaseParameterToThreePhase(mTransformerResistance), CPS::CIM::Reader::singlePhaseParameterToThreePhase(mTransformerInductance));
106
107
108
109
110
111
}

void EMT::Ph3::AvVoltageSourceInverterDQ::setControllerParameters(Real Kp_pll, Real Ki_pll,
	Real Kp_powerCtrl, Real Ki_powerCtrl, Real Kp_currCtrl, Real Ki_currCtrl, Real Omega_cutoff) {

	mSLog->info("Control Parameters:");
112
113
114
115
116
117
118
119
120
	mSLog->info("PLL: K_i = {}, K_p = {}, Omega_Nom = {}", Kp_pll, Ki_pll, Omega_cutoff);
	mSLog->info("Power Loop: K_i = {}, K_p = {}", Kp_powerCtrl, Ki_powerCtrl);
	mSLog->info("Current Loop: K_i = {}, K_p = {}", Kp_currCtrl, Ki_currCtrl);
	mSLog->info("Cut-Off Frequency = {}", Omega_cutoff);

	// TODO: add and use Omega_nominal instead of Omega_cutoff
	mPLL->setParameters(Kp_pll, Ki_pll, Omega_cutoff);
	mPLL->composeStateSpaceMatrices();
	mPowerControllerVSI->setControllerParameters(Kp_powerCtrl, Ki_powerCtrl, Kp_currCtrl, Ki_currCtrl, Omega_cutoff);
121
122
123
}

void EMT::Ph3::AvVoltageSourceInverterDQ::setFilterParameters(Real Lf, Real Cf, Real Rf, Real Rc) {
124
	Base::AvVoltageSourceInverterDQ::setFilterParameters(Lf, Cf, Rf, Rc);
125
126
127
128

	mSLog->info("Filter Parameters:");
	mSLog->info("Inductance Lf={} [H] Capacitance Cf={} [F]", mLf, mCf);
	mSLog->info("Resistance Rf={} [H] Resistance Rc={} [F]", mRf, mRc);
129
130
131
132
133

	mSubResistorC->setParameters(CPS::CIM::Reader::singlePhaseParameterToThreePhase(mRc));
	mSubResistorF->setParameters(CPS::CIM::Reader::singlePhaseParameterToThreePhase(mRf));
	mSubInductorF->setParameters(CPS::CIM::Reader::singlePhaseParameterToThreePhase(mLf));
	mSubCapacitorF->setParameters(CPS::CIM::Reader::singlePhaseParameterToThreePhase(mCf));
134
135
}

136
void EMT::Ph3::AvVoltageSourceInverterDQ::setInitialStateValues(Real pInit, Real qInit,
137
138
139
	Real phi_dInit, Real phi_qInit, Real gamma_dInit, Real gamma_qInit) {

	mSLog->info("Initial State Value Parameters:");
140
141
142
	mSLog->info("PInit = {}, QInit = {}", pInit, qInit);
	mSLog->info("Phi_dInit = {}, Phi_qInit = {}", phi_dInit, phi_qInit);
	mSLog->info("Gamma_dInit = {}, Gamma_qInit = {}", gamma_dInit, gamma_qInit);
Markus Mirz's avatar
Markus Mirz committed
143

144
	mPowerControllerVSI->setInitialStateValues(pInit, qInit, phi_dInit, phi_qInit, gamma_dInit, gamma_qInit);
Markus Mirz's avatar
Markus Mirz committed
145
146
}

Markus Mirz's avatar
Markus Mirz committed
147
void EMT::Ph3::AvVoltageSourceInverterDQ::initializeFromNodesAndTerminals(Real frequency) {
Markus Mirz's avatar
Markus Mirz committed
148

149
150
151
152
153
	// use complex interface quantities for initialization calculations
	MatrixComp intfVoltageComplex = Matrix::Zero(3, 1);
	MatrixComp intfCurrentComplex = Matrix::Zero(3, 1);

	// derive complex threephase initialization from single phase initial values (only valid for balanced systems)
154
	intfVoltageComplex(0, 0) = RMS3PH_TO_PEAK1PH * initialSingleVoltage(0);
155
156
	intfVoltageComplex(1, 0) = intfVoltageComplex(0, 0) * SHIFT_TO_PHASE_B;
	intfVoltageComplex(2, 0) = intfVoltageComplex(0, 0) * SHIFT_TO_PHASE_C;
157
	intfCurrentComplex(0, 0) = -std::conj(2./3.*Complex(mPref, mQref) / intfVoltageComplex(0, 0));
158
159
160
161
162
	intfCurrentComplex(1, 0) = intfCurrentComplex(0, 0) * SHIFT_TO_PHASE_B;
	intfCurrentComplex(2, 0) = intfCurrentComplex(0, 0) * SHIFT_TO_PHASE_C;

	MatrixComp filterInterfaceInitialVoltage = MatrixComp::Zero(3, 1);
	MatrixComp filterInterfaceInitialCurrent = MatrixComp::Zero(3, 1);
163
	if (mWithConnectionTransformer) {
164
		// calculate quantities of low voltage side of transformer (being the interface quantities of the filter, calculations only valid for symmetrical systems)
165
		filterInterfaceInitialVoltage = (intfVoltageComplex - Complex(mTransformerResistance, mTransformerInductance*mOmegaN)*intfCurrentComplex) / Complex(mTransformerRatioAbs, mTransformerRatioPhase);
166
167
168
		filterInterfaceInitialCurrent = intfCurrentComplex * Complex(mTransformerRatioAbs, mTransformerRatioPhase);

		// connect and init transformer
169
170
		mVirtualNodes[3]->setInitialVoltage(PEAK1PH_TO_RMS3PH * filterInterfaceInitialVoltage);
		mConnectionTransformer->connect({ mTerminals[0]->node(), mVirtualNodes[3] });
171
172
173
174
175
	} else {
		// if no transformer used, filter interface equal to inverter interface
		filterInterfaceInitialVoltage = intfVoltageComplex;
		filterInterfaceInitialCurrent = intfCurrentComplex;
	}
Markus Mirz's avatar
Markus Mirz committed
176

177
	// derive initialization quantities of filter (calculations only valid for symmetrical systems)
178
179
180
181
	MatrixComp vcInit = filterInterfaceInitialVoltage - filterInterfaceInitialCurrent * Complex(mRc, 0);
	MatrixComp icfInit = vcInit * Complex(0., 2. * PI * frequency * mCf);
	MatrixComp vfInit = vcInit - (filterInterfaceInitialCurrent - icfInit) * Complex(0., 2. * PI * frequency * mLf);
	MatrixComp vsInit = vfInit - (filterInterfaceInitialCurrent - icfInit) * Complex(mRf, 0);
182
183
184
	mVirtualNodes[0]->setInitialVoltage(PEAK1PH_TO_RMS3PH * vsInit);
	mVirtualNodes[1]->setInitialVoltage(PEAK1PH_TO_RMS3PH * vfInit);
	mVirtualNodes[2]->setInitialVoltage(PEAK1PH_TO_RMS3PH * vcInit);
Markus Mirz's avatar
Markus Mirz committed
185

186
	// save real interface quantities calculated from complex ones
187
188
	mIntfVoltage = intfVoltageComplex.real();
	mIntfCurrent = intfCurrentComplex.real();
189

190
191
192
193
194
195
196
197
198
	// Set parameters electrical subcomponents
	mVsref(0,0) = mVirtualNodes[0]->initialSingleVoltage();
	mSubCtrledVoltageSource->setParameters(mVsref(0,0));

	// Connect electrical subcomponents
	mSubCtrledVoltageSource->connect({ SimNode::GND, mVirtualNodes[0] });
	mSubResistorF->connect({ mVirtualNodes[0], mVirtualNodes[1] });
	mSubInductorF->connect({ mVirtualNodes[1], mVirtualNodes[2] });
	mSubCapacitorF->connect({ mVirtualNodes[2], SimNode::GND });
199
	if (mWithConnectionTransformer)
200
		mSubResistorC->connect({ mVirtualNodes[2],  mVirtualNodes[3]});
201
	else
202
		mSubResistorC->connect({ mVirtualNodes[2],  mTerminals[0]->node()});
Markus Mirz's avatar
Markus Mirz committed
203

204
205
206
207
208
	// Initialize electrical subcomponents
	for (auto subcomp: mSubComponents) {
		subcomp->initialize(mFrequencies);
		subcomp->initializeFromNodesAndTerminals(frequency);
	}
Markus Mirz's avatar
Markus Mirz committed
209

210
211
212
213
214
215
216
217
218
219
220
221
222
	// Initialize control subcomponents
	// current and voltage inputs to PLL and power controller
	Complex vcdq, ircdq;
	vcdq = Math::rotatingFrame2to1(mVirtualNodes[3]->initialSingleVoltage(), std::arg(mVirtualNodes[3]->initialSingleVoltage()), 0);
	ircdq = Math::rotatingFrame2to1(-1. * filterInterfaceInitialCurrent(0, 0), std::arg(mVirtualNodes[3]->initialSingleVoltage()), 0);
	mVcd = vcdq.real();
	mVcq = vcdq.imag();
	mIrcd = ircdq.real();
	mIrcq = ircdq.imag();
	// angle input
	Matrix matrixStateInit = Matrix::Zero(2,1);
	matrixStateInit(0,0) = std::arg(mVirtualNodes[3]->initialSingleVoltage());
	mPLL->setInitialValues(mVcq, matrixStateInit, Matrix::Zero(2,1));
223

Markus Mirz's avatar
Markus Mirz committed
224
225
226
227
228
229
230
	mSLog->info(
		"\n--- Initialization from powerflow ---"
		"\nVoltage across: {:s}"
		"\nCurrent: {:s}"
		"\nTerminal 0 voltage: {:s}"
		"\nTerminal 0 connected to {:s} = sim node {:d}"
		"\n--- Initialization from powerflow finished ---",
231
232
		Logger::phasorToString(intfVoltageComplex(0, 0)),
		Logger::phasorToString(intfCurrentComplex(0, 0)),
233
		Logger::phasorToString(RMS3PH_TO_PEAK1PH * initialSingleVoltage(0)),
Markus Mirz's avatar
Markus Mirz committed
234
		mTerminals[0]->node()->name(), mTerminals[0]->node()->matrixNodeIndex());
Markus Mirz's avatar
Markus Mirz committed
235
236
237
238
}

void EMT::Ph3::AvVoltageSourceInverterDQ::mnaInitialize(Real omega, Real timeStep, Attribute<Matrix>::Ptr leftVector) {
	MNAInterface::mnaInitialize(omega, timeStep);
Markus Mirz's avatar
Markus Mirz committed
239
	updateMatrixNodeIndices();
240
241
	mTimeStep = timeStep;

242
243
244
245
	// initialize electrical subcomponents with MNA interface
	for (auto subcomp: mSubComponents)
		if (auto mnasubcomp = std::dynamic_pointer_cast<MNAInterface>(subcomp))
			mnasubcomp->mnaInitialize(omega, timeStep, leftVector);
Markus Mirz's avatar
Markus Mirz committed
246

247
248
249
	// initialize state space controller
	mPowerControllerVSI->initializeStateSpaceModel(omega, timeStep, leftVector);
	mPLL->setSimulationParameters(timeStep);
Markus Mirz's avatar
Markus Mirz committed
250

251
	// collect right side vectors of subcomponents
Markus Mirz's avatar
Markus Mirz committed
252
253
254
	mRightVectorStamps.push_back(&mSubCapacitorF->attribute<Matrix>("right_vector")->get());
	mRightVectorStamps.push_back(&mSubInductorF->attribute<Matrix>("right_vector")->get());
	mRightVectorStamps.push_back(&mSubCtrledVoltageSource->attribute<Matrix>("right_vector")->get());
255
	if (mWithConnectionTransformer)
256
		mRightVectorStamps.push_back(&mConnectionTransformer->attribute<Matrix>("right_vector")->get());
257
258

	// collect tasks
Markus Mirz's avatar
Markus Mirz committed
259
260
	mMnaTasks.push_back(std::make_shared<MnaPreStep>(*this));
	mMnaTasks.push_back(std::make_shared<MnaPostStep>(*this, leftVector));
261
262
263
264
265

	// TODO: these are actually no MNA tasks
	mMnaTasks.push_back(std::make_shared<ControlPreStep>(*this));
	mMnaTasks.push_back(std::make_shared<ControlStep>(*this));

Markus Mirz's avatar
Markus Mirz committed
266
267
268
269
270
	mRightVector = Matrix::Zero(leftVector->get().rows(), 1);
}


void EMT::Ph3::AvVoltageSourceInverterDQ::mnaApplySystemMatrixStamp(Matrix& systemMatrix) {
271
272
273
	for (auto subcomp: mSubComponents)
		if (auto mnasubcomp = std::dynamic_pointer_cast<MNAInterface>(subcomp))
			mnasubcomp->mnaApplySystemMatrixStamp(systemMatrix);
Markus Mirz's avatar
Markus Mirz committed
274
275
276
277
278
279
280
281
}

void EMT::Ph3::AvVoltageSourceInverterDQ::mnaApplyRightSideVectorStamp(Matrix& rightVector) {
	rightVector.setZero();
	for (auto stamp : mRightVectorStamps)
		rightVector += *stamp;
}

282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
void EMT::Ph3::AvVoltageSourceInverterDQ::addControlPreStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes) {
	// add pre-step dependencies of subcomponents
	mPLL->signalAddPreStepDependencies(prevStepDependencies, attributeDependencies, modifiedAttributes);
	mPowerControllerVSI->signalAddPreStepDependencies(prevStepDependencies, attributeDependencies, modifiedAttributes);
}

void EMT::Ph3::AvVoltageSourceInverterDQ::controlPreStep(Real time, Int timeStepCount) {
	// add pre-step of subcomponents
	mPLL->signalPreStep(time, timeStepCount);
	mPowerControllerVSI->signalPreStep(time, timeStepCount);
}

void EMT::Ph3::AvVoltageSourceInverterDQ::addControlStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes) {
	// add step dependencies of subcomponents
	mPLL->signalAddStepDependencies(prevStepDependencies, attributeDependencies, modifiedAttributes);
	mPowerControllerVSI->signalAddStepDependencies(prevStepDependencies, attributeDependencies, modifiedAttributes);
	// add step dependencies of component itself
	attributeDependencies.push_back(attribute("i_intf"));
	attributeDependencies.push_back(attribute("v_intf"));
	modifiedAttributes.push_back(attribute("Vsref"));
}

Matrix EMT::Ph3::AvVoltageSourceInverterDQ::parkTransformPowerInvariant(Real theta, const Matrix &fabc) {
	// Calculates fdq = Tdq * fabc
	// Assumes that d-axis starts aligned with phase a
	Matrix Tdq = getParkTransformMatrixPowerInvariant(theta);
	Matrix dqvector = Tdq * fabc;
	return dqvector;
}

Matrix EMT::Ph3::AvVoltageSourceInverterDQ::getParkTransformMatrixPowerInvariant(Real theta) {
	// Return park matrix for theta
	// Assumes that d-axis starts aligned with phase a
	Matrix Tdq = Matrix::Zero(2, 3);
	Real k = sqrt(2. / 3.);
	Tdq <<
		k * cos(theta), k * cos(theta - 2. * M_PI / 3.), k * cos(theta + 2. * M_PI / 3.),
		-k * sin(theta), -k * sin(theta - 2. * M_PI / 3.), -k * sin(theta + 2. * M_PI / 3.);
	return Tdq;
}

void EMT::Ph3::AvVoltageSourceInverterDQ::controlStep(Real time, Int timeStepCount) {
	// Transformation interface forward
	Matrix vcdq, ircdq;
	ircdq = parkTransformPowerInvariant(mPLL->attribute<Matrix>("output_prev")->get()(0, 0), -1 * mSubResistorC->attribute<Matrix>("i_intf")->get());
	vcdq = parkTransformPowerInvariant(mPLL->attribute<Matrix>("output_prev")->get()(0, 0), mVirtualNodes[3]->attribute<Matrix>("v")->get());
	mVcd = vcdq(0, 0);
	mVcq = vcdq(1, 0);
	mIrcd = ircdq(0, 0);
	mIrcq = ircdq(1, 0);

	// add step of subcomponents
	mPLL->signalStep(time, timeStepCount);
	mPowerControllerVSI->signalStep(time, timeStepCount);

	// Transformation interface backward
	mVsref(0,0) = Math::rotatingFrame2to1(Complex(mPowerControllerVSI->attribute<Matrix>("output_curr")->get()(0, 0), mPowerControllerVSI->attribute<Matrix>("output_curr")->get()(1, 0)), mThetaN, mPLL->attribute<Matrix>("output_prev")->get()(0, 0));

	// Update nominal system angle
	mThetaN = mThetaN + mTimeStep * mOmegaN;
Markus Mirz's avatar
Markus Mirz committed
342
343
}

344
345
346
347
348
349
350
351
352
353
354
355
void EMT::Ph3::AvVoltageSourceInverterDQ::mnaAddPreStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes) {
	// add pre-step dependencies of subcomponents
	for (auto subcomp: mSubComponents)
		if (auto mnasubcomp = std::dynamic_pointer_cast<MNAInterface>(subcomp))
			mnasubcomp->mnaAddPreStepDependencies(prevStepDependencies, attributeDependencies, modifiedAttributes);
	// add pre-step dependencies of component itself
	prevStepDependencies.push_back(attribute("Vsref"));
	prevStepDependencies.push_back(attribute("i_intf"));
	prevStepDependencies.push_back(attribute("v_intf"));
	attributeDependencies.push_back(mPowerControllerVSI->attribute<Matrix>("output_prev"));
	attributeDependencies.push_back(mPLL->attribute<Matrix>("output_prev"));
	modifiedAttributes.push_back(attribute("right_vector"));
Markus Mirz's avatar
Markus Mirz committed
356
357
}

358
359
360
361
362
363
364
365
366
void EMT::Ph3::AvVoltageSourceInverterDQ::mnaPreStep(Real time, Int timeStepCount) {
	// pre-step of subcomponents - controlled source
	mSubCtrledVoltageSource->setParameters(mVsref(0,0));
	// pre-step of subcomponents - others
	for (auto subcomp: mSubComponents)
		if (auto mnasubcomp = std::dynamic_pointer_cast<MNAInterface>(subcomp))
			mnasubcomp->mnaPreStep(time, timeStepCount);
	// pre-step of component itself
	mnaApplyRightSideVectorStamp(mRightVector);
Markus Mirz's avatar
Markus Mirz committed
367
368
}

369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
void EMT::Ph3::AvVoltageSourceInverterDQ::mnaAddPostStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes, Attribute<Matrix>::Ptr &leftVector) {
	// add post-step dependencies of subcomponents
	for (auto subcomp: mSubComponents)
		if (auto mnasubcomp = std::dynamic_pointer_cast<MNAInterface>(subcomp))
			mnasubcomp->mnaAddPostStepDependencies(prevStepDependencies, attributeDependencies, modifiedAttributes, leftVector);
	// add post-step dependencies of component itself
	attributeDependencies.push_back(leftVector);
	modifiedAttributes.push_back(attribute("v_intf"));
	modifiedAttributes.push_back(attribute("i_intf"));
}

void EMT::Ph3::AvVoltageSourceInverterDQ::mnaPostStep(Real time, Int timeStepCount, Attribute<Matrix>::Ptr &leftVector) {
	// post-step of subcomponents
	for (auto subcomp: mSubComponents)
		if (auto mnasubcomp = std::dynamic_pointer_cast<MNAInterface>(subcomp))
			mnasubcomp->mnaPostStep(time, timeStepCount, leftVector);
	// post-step of component itself
	mnaUpdateCurrent(*leftVector);
	mnaUpdateVoltage(*leftVector);
Markus Mirz's avatar
Markus Mirz committed
388
389
}

390
391
392
393
394
395
396
void EMT::Ph3::AvVoltageSourceInverterDQ::mnaUpdateCurrent(const Matrix& leftvector) {
	if (mWithConnectionTransformer)
		mIntfCurrent = mConnectionTransformer->attribute<Matrix>("i_intf")->get();
	else
		mIntfCurrent = mSubResistorC->attribute<Matrix>("i_intf")->get();
}

397
398
399
400
401
402
void EMT::Ph3::AvVoltageSourceInverterDQ::mnaUpdateVoltage(const Matrix& leftVector) {
	mVirtualNodes[3]->mnaUpdateVoltage(leftVector);
	// mIntfVoltage(0, 0) = Math::realFromVectorElement(leftVector, mVirtualNodes[3]->matrixNodeIndex(0, 0));
	// mIntfVoltage(1, 0) = Math::realFromVectorElement(leftVector, mVirtualNodes[3]->matrixNodeIndex(0, 1));
	// mIntfVoltage(2, 0) = Math::realFromVectorElement(leftVector, mVirtualNodes[3]->matrixNodeIndex(0, 2));
}