Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
ACS
Public
Power System Simulation and Optimization
DPsim
DPsim
Commits
f95daada
Commit
f95daada
authored
Oct 12, 2020
by
Jan Dinkelbach
Committed by
Markus Mirz
Nov 21, 2020
Browse files
initial refactoring of emt3ph averaged inverter
parent
41ecaa79
Changes
4
Show whitespace changes
Inline
Side-by-side
Examples/Cxx/Circuits/EMT_Slack_PiLine_VSI_with_PF_Init.cpp
View file @
f95daada
...
...
@@ -101,7 +101,7 @@ int main(int argc, char* argv[]) {
pv
->
setControllerParameters
(
scenario
.
KpPLL
,
scenario
.
KiPLL
,
scenario
.
KpPowerCtrl
,
scenario
.
KiPowerCtrl
,
scenario
.
KpCurrCtrl
,
scenario
.
KiCurrCtrl
,
scenario
.
OmegaCutoff
);
pv
->
setFilterParameters
(
scenario
.
Lf
,
scenario
.
Cf
,
scenario
.
Rf
,
scenario
.
Rc
);
pv
->
setTransformerParameters
(
scenario
.
systemNominalVoltage
,
scenario
.
pvNominalVoltage
,
scenario
.
transformerNominalPower
,
scenario
.
systemNominalVoltage
/
scenario
.
pvNominalVoltage
,
0
,
0
,
scenario
.
transformerInductance
,
scenario
.
systemOmega
);
pv
->
setInitialStateValues
(
scenario
.
thetaPLLInit
,
scenario
.
phiPLLInit
,
scenario
.
pvNominalActivePower
,
scenario
.
pvNominalReactivePower
,
scenario
.
phi_dInit
,
scenario
.
phi_qInit
,
scenario
.
gamma_dInit
,
scenario
.
gamma_qInit
);
pv
->
setInitialStateValues
(
scenario
.
pvNominalActivePower
,
scenario
.
pvNominalReactivePower
,
scenario
.
phi_dInit
,
scenario
.
phi_qInit
,
scenario
.
gamma_dInit
,
scenario
.
gamma_qInit
);
// Topology
extnetEMT
->
connect
({
n1EMT
});
...
...
@@ -111,7 +111,7 @@ int main(int argc, char* argv[]) {
SystemNodeList
{
n1EMT
,
n2EMT
},
SystemComponentList
{
extnetEMT
,
lineEMT
,
pv
});
// Initialization of dynamic topology
(actually necessary here? node objects the same)
// Initialization of dynamic topology
CIM
::
Reader
reader
(
simNameEMT
,
Logger
::
Level
::
debug
);
reader
.
initDynamicSystemTopologyWithPowerflow
(
systemPF
,
systemEMT
);
...
...
Examples/Cxx/Examples.h
View file @
f95daada
...
...
@@ -151,7 +151,7 @@ namespace CIGREMV {
pv
->
setControllerParameters
(
scenario
.
KpPLL
,
scenario
.
KiPLL
,
scenario
.
KpPowerCtrl
,
scenario
.
KiPowerCtrl
,
scenario
.
KpCurrCtrl
,
scenario
.
KiCurrCtrl
,
scenario
.
OmegaCutoff
);
pv
->
setFilterParameters
(
scenario
.
Lf
,
scenario
.
Cf
,
scenario
.
Rf
,
scenario
.
Rc
);
pv
->
setTransformerParameters
(
scenario
.
systemNominalVoltage
,
scenario
.
pvUnitNominalVoltage
,
scenario
.
transformerNominalPower
,
scenario
.
systemNominalVoltage
/
scenario
.
pvUnitNominalVoltage
,
0
,
0
,
scenario
.
transformerInductance
,
scenario
.
systemOmega
);
pv
->
setInitialStateValues
(
scenario
.
thetaPLLInit
,
scenario
.
phiPLLInit
,
scenario
.
pInit
,
scenario
.
qInit
,
scenario
.
phi_dInit
,
scenario
.
phi_qInit
,
scenario
.
gamma_dInit
,
scenario
.
gamma_qInit
);
pv
->
setInitialStateValues
(
scenario
.
pInit
,
scenario
.
qInit
,
scenario
.
phi_dInit
,
scenario
.
phi_qInit
,
scenario
.
gamma_dInit
,
scenario
.
gamma_qInit
);
system
.
addComponent
(
pv
);
system
.
connectComponentToNodes
<
Real
>
(
pv
,
{
connectionNode
});
}
...
...
models/Include/cps/EMT/EMT_Ph3_AvVoltageSourceInverterDQ.h
View file @
f95daada
...
...
@@ -5,32 +5,54 @@
* 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/.
*********************************************************************************/
#pragma once
#include <cps/CIM/Reader.h>
#include <cps/SimPowerComp.h>
#include <cps/Solver/MNAInterface.h>
#include <cps/Definitions.h>
#include <cps/EMT/EMT_Ph3_Resistor.h>
#include <cps/EMT/EMT_Ph3_Inductor.h>
#include <cps/EMT/EMT_Ph3_Capacitor.h>
#include <cps/EMT/EMT_Ph3_
Controlled
VoltageSource.h>
#include <cps/EMT/EMT_Ph3_VoltageSource.h>
#include <cps/EMT/EMT_Ph3_Transformer.h>
#include <cps/Base/Base_AvVoltageSourceInverterDQWithStateSpace.h>
#include <cps/Base/Base_AvVoltageSourceInverterDQ.h>
#include <cps/Signal/PLL.h>
#include <cps/Signal/PowerControllerVSI.h>
namespace
CPS
{
namespace
EMT
{
namespace
Ph3
{
class
AvVoltageSourceInverterDQ
:
public
Base
::
AvVoltageSourceInverterDQ
WithStateSpace
,
public
Base
::
AvVoltageSourceInverterDQ
,
public
SimPowerComp
<
Real
>
,
public
MNAInterface
,
public
SharedFactory
<
AvVoltageSourceInverterDQ
>
{
protected:
// ### Subcomponents ###
// ### General Parameters ###
/// Nominal system angle
Real
mThetaN
=
0
;
/// Nominal frequency
Real
mOmegaN
;
/// Nominal voltage
Real
mVnom
;
/// Simulation step
Real
mTimeStep
;
/// Active power reference
Real
mPref
;
/// Reactive power reference
Real
mQref
;
// ### Control Subcomponents ###
/// PLL
std
::
shared_ptr
<
Signal
::
PLL
>
mPLL
;
/// Power Controller
std
::
shared_ptr
<
Signal
::
PowerControllerVSI
>
mPowerControllerVSI
;
// ### Electrical Subcomponents ###
/// Controlled voltage source
std
::
shared_ptr
<
EMT
::
Ph3
::
Controlled
VoltageSource
>
mSubCtrledVoltageSource
;
std
::
shared_ptr
<
EMT
::
Ph3
::
VoltageSource
>
mSubCtrledVoltageSource
;
/// Resistor Rf as part of LCL filter
std
::
shared_ptr
<
EMT
::
Ph3
::
Resistor
>
mSubResistorF
;
/// Capacitor Cf as part of LCL filter
...
...
@@ -42,101 +64,55 @@ namespace Ph3 {
/// Optional connection transformer
std
::
shared_ptr
<
EMT
::
Ph3
::
Transformer
>
mConnectionTransformer
;
// ### inputs ###
///
Matrix
mVcdq
=
Matrix
::
Zero
(
2
,
1
);
///
Matrix
mVcabc
=
Matrix
::
Zero
(
3
,
1
);
///
Matrix
mIrcdq
=
Matrix
::
Zero
(
2
,
1
);
///
Matrix
mIrcabc
=
Matrix
::
Zero
(
3
,
1
);
// ### outputs ###
///
Matrix
mVsdq
=
Matrix
::
Zero
(
2
,
1
);
///
Matrix
mVsabc
=
Matrix
::
Zero
(
3
,
1
);
/// in case variable time step simulation should be developed in the future
Real
mTimeStep
;
///
Bool
mCtrlOn
=
true
;
///
// ### Inverter Interfacing Variables ###
// Control inputs
/// Measured voltage d-axis in local reference frame
Real
mVcd
=
0
;
/// Measured voltage q-axis in local reference frame
Real
mVcq
=
0
;
/// Measured current d-axis in local reference frame
Real
mIrcd
=
0
;
/// Measured current q-axis in local reference frame
Real
mIrcq
=
0
;
// Control outputs
/// Voltage as control output after transformation interface
MatrixComp
mVsref
=
MatrixComp
::
Zero
(
1
,
1
);
/// Boolean for connection transformer usage
Bool
mWithConnectionTransformer
=
false
;
/// instantaneous omega
Real
mOmegaInst
=
0
;
/// instantaneous frequency
Real
mFreqInst
=
0
;
///
std
::
vector
<
Real
>*
mGenProfile
=
nullptr
;
///
std
::
vector
<
Real
>::
iterator
mCurrentPower
;
///
Attribute
<
Real
>::
Ptr
mQRefInput
;
// #### solver ####
///
std
::
vector
<
const
Matrix
*>
mRightVectorStamps
;
public:
///
///
Defines name amd logging level
AvVoltageSourceInverterDQ
(
String
name
,
Logger
::
Level
logLevel
=
Logger
::
Level
::
off
)
:
AvVoltageSourceInverterDQ
(
name
,
name
,
logLevel
)
{}
///
///
Defines UID, name, logging level and connection trafo existence
AvVoltageSourceInverterDQ
(
String
uid
,
String
name
,
Logger
::
Level
logLevel
=
Logger
::
Level
::
off
,
Bool
withTrafo
=
false
);
///
// #### General ####
/// Initializes component from power flow data
void
initializeFromNodesAndTerminals
(
Real
frequency
);
/// Setter for gengit eral parameters of inverter
void
setParameters
(
Real
sysOmega
,
Real
sysVoltNom
,
Real
Pref
,
Real
Qref
);
///
/// Setter for parameters of control loops
void
setControllerParameters
(
Real
Kp_pll
,
Real
Ki_pll
,
Real
Kp_powerCtrl
,
Real
Ki_powerCtrl
,
Real
Kp_currCtrl
,
Real
Ki_currCtrl
,
Real
Omega_cutoff
);
/// Setter for parameters of transformer
void
setTransformerParameters
(
Real
nomVoltageEnd1
,
Real
nomVoltageEnd2
,
Real
ratedPower
,
Real
ratioAbs
,
Real
ratioPhase
,
Real
resistance
,
Real
inductance
,
Real
omega
);
///
void
setControllerParameters
(
Real
Kp_pll
,
Real
Ki_pll
,
Real
Kp_powerCtrl
,
Real
Ki_powerCtrl
,
Real
Kp_currCtrl
,
Real
Ki_currCtrl
,
Real
Omega_cutoff
);
///
/// Setter for parameters of filter
void
setFilterParameters
(
Real
Lf
,
Real
Cf
,
Real
Rf
,
Real
Rc
);
///
void
setInitialStateValues
(
Real
thetaPLLInit
,
Real
phiPLLInit
,
Real
pInit
,
Real
qInit
,
///
Setter for initial values applied in controllers
void
setInitialStateValues
(
Real
pInit
,
Real
qInit
,
Real
phi_dInit
,
Real
phi_qInit
,
Real
gamma_dInit
,
Real
gamma_qInit
);
///
SimPowerComp
<
Real
>::
Ptr
clone
(
String
copySuffix
);
///
void
initializeStateSpaceModel
(
Real
omega
,
Real
timeStep
,
Attribute
<
Matrix
>::
Ptr
leftVector
);
///
void
updateInputStateSpaceModel
(
const
Matrix
&
leftVector
,
Real
time
);
///
void
updateStates
();
///
void
updateBMatrixStateSpaceModel
();
///
Matrix
getParkTransformMatrixPowerInvariant
(
Real
theta
);
///
Matrix
getInverseParkTransformMatrixPowerInvariant
(
Real
theta
);
///
Matrix
parkTransformPowerInvariant
(
Real
theta
,
Real
fa
,
Real
fb
,
Real
fc
);
///
Matrix
inverseParkTransformPowerInvariant
(
Real
theta
,
Real
fd
,
Real
fq
);
Matrix
parkTransformPowerInvariant
(
Real
theta
,
const
Matrix
&
fabc
);
///
void
step
(
Real
time
,
Int
timeStepCount
);
///
void
updatePowerGeneration
();
// #### General ####
///
//void addGenProfile(std::vector<Real>* genProfile);
///
void
addAggregatedGenProfile
(
std
::
vector
<
Real
>*
genProfile
,
Real
customerNumber
);
///
void
updateSetPoint
(
Real
time
);
///
void
initializeFromNodesAndTerminals
(
Real
frequency
);
// #### interface with villas node ####
void
ctrlReceiver
(
Attribute
<
Real
>::
Ptr
qref
);
// #### MNA section ####
/// Initializes internal variables of the component
void
mnaInitialize
(
Real
omega
,
Real
timeStep
,
Attribute
<
Matrix
>::
Ptr
leftVector
);
...
...
@@ -144,61 +120,72 @@ namespace Ph3 {
void
mnaApplySystemMatrixStamp
(
Matrix
&
systemMatrix
);
/// Stamps right side (source) vector
void
mnaApplyRightSideVectorStamp
(
Matrix
&
rightVector
);
///
Return
s current through the component
///
Update
s current through the component
void
mnaUpdateCurrent
(
const
Matrix
&
leftVector
);
class
MnaPreStep
:
public
CPS
::
Task
{
/// Updates voltage across component
void
mnaUpdateVoltage
(
const
Matrix
&
leftVector
);
/// MNA pre step operations
void
mnaPreStep
(
Real
time
,
Int
timeStepCount
);
/// MNA post step operations
void
mnaPostStep
(
Real
time
,
Int
timeStepCount
,
Attribute
<
Matrix
>::
Ptr
&
leftVector
);
/// Add MNA pre step dependencies
void
mnaAddPreStepDependencies
(
AttributeBase
::
List
&
prevStepDependencies
,
AttributeBase
::
List
&
attributeDependencies
,
AttributeBase
::
List
&
modifiedAttributes
);
/// Add MNA post step dependencies
void
mnaAddPostStepDependencies
(
AttributeBase
::
List
&
prevStepDependencies
,
AttributeBase
::
List
&
attributeDependencies
,
AttributeBase
::
List
&
modifiedAttributes
,
Attribute
<
Matrix
>::
Ptr
&
leftVector
);
// #### Control section ####
/// Control pre step operations
void
controlPreStep
(
Real
time
,
Int
timeStepCount
);
/// Perform step of controller
void
controlStep
(
Real
time
,
Int
timeStepCount
);
/// Add control step dependencies
void
addControlPreStepDependencies
(
AttributeBase
::
List
&
prevStepDependencies
,
AttributeBase
::
List
&
attributeDependencies
,
AttributeBase
::
List
&
modifiedAttributes
);
/// Add control step dependencies
void
addControlStepDependencies
(
AttributeBase
::
List
&
prevStepDependencies
,
AttributeBase
::
List
&
attributeDependencies
,
AttributeBase
::
List
&
modifiedAttributes
);
class
ControlPreStep
:
public
CPS
::
Task
{
public:
MnaPreStep
(
AvVoltageSourceInverterDQ
&
AvVoltageSourceInverterDQ
)
:
Task
(
AvVoltageSourceInverterDQ
.
mName
+
".MnaPreStep"
),
mAvVoltageSourceInverterDQ
(
AvVoltageSourceInverterDQ
)
{
//mAttributeDependencies.push_back(AvVoltageSourceInverterDQ.attribute("P_ref"));
mPrevStepDependencies
.
push_back
(
AvVoltageSourceInverterDQ
.
attribute
(
"i_intf"
));
mPrevStepDependencies
.
push_back
(
AvVoltageSourceInverterDQ
.
attribute
(
"v_intf"
));
mModifiedAttributes
.
push_back
(
AvVoltageSourceInverterDQ
.
mSubCtrledVoltageSource
->
attribute
(
"v_intf"
));
ControlPreStep
(
AvVoltageSourceInverterDQ
&
AvVoltageSourceInverterDQ
)
:
Task
(
AvVoltageSourceInverterDQ
.
mName
+
".ControlPreStep"
),
mAvVoltageSourceInverterDQ
(
AvVoltageSourceInverterDQ
)
{
mAvVoltageSourceInverterDQ
.
addControlPreStepDependencies
(
mPrevStepDependencies
,
mAttributeDependencies
,
mModifiedAttributes
);
}
void
execute
(
Real
time
,
Int
timeStepCount
);
void
execute
(
Real
time
,
Int
timeStepCount
)
{
mAvVoltageSourceInverterDQ
.
controlPreStep
(
time
,
timeStepCount
);
};
private:
AvVoltageSourceInverterDQ
&
mAvVoltageSourceInverterDQ
;
};
class
AddB
Step
:
public
Task
{
class
Control
Step
:
public
CPS
::
Task
{
public:
AddBStep
(
AvVoltageSourceInverterDQ
&
AvVoltageSourceInverterDQ
)
:
Task
(
AvVoltageSourceInverterDQ
.
mName
+
".AddBStep"
),
mAvVoltageSourceInverterDQ
(
AvVoltageSourceInverterDQ
)
{
mAttributeDependencies
.
push_back
(
AvVoltageSourceInverterDQ
.
mSubInductorF
->
attribute
(
"right_vector"
));
mAttributeDependencies
.
push_back
(
AvVoltageSourceInverterDQ
.
mConnectionTransformer
->
attribute
(
"right_vector"
));
mAttributeDependencies
.
push_back
(
AvVoltageSourceInverterDQ
.
mSubCapacitorF
->
attribute
(
"right_vector"
));
mAttributeDependencies
.
push_back
(
AvVoltageSourceInverterDQ
.
mSubCtrledVoltageSource
->
attribute
(
"right_vector"
));
mModifiedAttributes
.
push_back
(
AvVoltageSourceInverterDQ
.
attribute
(
"right_vector"
));
ControlStep
(
AvVoltageSourceInverterDQ
&
AvVoltageSourceInverterDQ
)
:
Task
(
AvVoltageSourceInverterDQ
.
mName
+
".ControlStep"
),
mAvVoltageSourceInverterDQ
(
AvVoltageSourceInverterDQ
)
{
mAvVoltageSourceInverterDQ
.
addControlStepDependencies
(
mPrevStepDependencies
,
mAttributeDependencies
,
mModifiedAttributes
);
}
void
execute
(
Real
time
,
Int
timeStepCount
);
void
execute
(
Real
time
,
Int
timeStepCount
)
{
mAvVoltageSourceInverterDQ
.
controlStep
(
time
,
timeStepCount
);
};
private:
AvVoltageSourceInverterDQ
&
mAvVoltageSourceInverterDQ
;
};
class
MnaPreStep
:
public
CPS
::
Task
{
public:
MnaPreStep
(
AvVoltageSourceInverterDQ
&
AvVoltageSourceInverterDQ
)
:
Task
(
AvVoltageSourceInverterDQ
.
mName
+
".MnaPreStep"
),
mAvVoltageSourceInverterDQ
(
AvVoltageSourceInverterDQ
)
{
mAvVoltageSourceInverterDQ
.
mnaAddPreStepDependencies
(
mPrevStepDependencies
,
mAttributeDependencies
,
mModifiedAttributes
);
}
void
execute
(
Real
time
,
Int
timeStepCount
)
{
mAvVoltageSourceInverterDQ
.
mnaPreStep
(
time
,
timeStepCount
);
};
private:
AvVoltageSourceInverterDQ
&
mAvVoltageSourceInverterDQ
;
};
class
MnaPostStep
:
public
CPS
::
Task
{
public:
MnaPostStep
(
AvVoltageSourceInverterDQ
&
AvVoltageSourceInverterDQ
,
Attribute
<
Matrix
>::
Ptr
leftVector
)
:
Task
(
AvVoltageSourceInverterDQ
.
mName
+
".MnaPostStep"
),
mAvVoltageSourceInverterDQ
(
AvVoltageSourceInverterDQ
),
mLeftVector
(
leftVector
)
{
mAttributeDependencies
.
push_back
(
leftVector
);
//mAttributeDependencies.push_back(AvVoltageSourceInverterDQ.attribute("Q_ref"));
//mAttributeDependencies.push_back(AvVoltageSourceInverterDQ.mQRefInput);
mAttributeDependencies
.
push_back
(
AvVoltageSourceInverterDQ
.
mSubCtrledVoltageSource
->
attribute
(
"i_intf"
));
mAttributeDependencies
.
push_back
(
AvVoltageSourceInverterDQ
.
mSubResistorF
->
attribute
(
"i_intf"
));
mAttributeDependencies
.
push_back
(
AvVoltageSourceInverterDQ
.
mSubInductorF
->
attribute
(
"i_intf"
));
mAttributeDependencies
.
push_back
(
AvVoltageSourceInverterDQ
.
mConnectionTransformer
->
attribute
(
"i_intf"
));
mAttributeDependencies
.
push_back
(
AvVoltageSourceInverterDQ
.
mSubResistorC
->
attribute
(
"i_intf"
));
mModifiedAttributes
.
push_back
(
AvVoltageSourceInverterDQ
.
attribute
(
"i_intf"
));
mModifiedAttributes
.
push_back
(
AvVoltageSourceInverterDQ
.
attribute
(
"v_intf"
));
Task
(
AvVoltageSourceInverterDQ
.
mName
+
".MnaPostStep"
),
mAvVoltageSourceInverterDQ
(
AvVoltageSourceInverterDQ
),
mLeftVector
(
leftVector
)
{
mAvVoltageSourceInverterDQ
.
mnaAddPostStepDependencies
(
mPrevStepDependencies
,
mAttributeDependencies
,
mModifiedAttributes
,
mLeftVector
);
}
void
execute
(
Real
time
,
Int
timeStepCount
);
void
execute
(
Real
time
,
Int
timeStepCount
)
{
mAvVoltageSourceInverterDQ
.
mnaPostStep
(
time
,
timeStepCount
,
mLeftVector
);
};
private:
AvVoltageSourceInverterDQ
&
mAvVoltageSourceInverterDQ
;
...
...
models/Source/EMT/EMT_Ph3_AvVoltageSourceInverterDQ.cpp
View file @
f95daada
...
...
@@ -10,295 +10,138 @@
using
namespace
CPS
;
EMT
::
Ph3
::
AvVoltageSourceInverterDQ
::
AvVoltageSourceInverterDQ
(
String
uid
,
String
name
,
Logger
::
Level
logLevel
,
Bool
withTrafo
)
:
SimPowerComp
<
Real
>
(
uid
,
name
,
logLevel
)
{
SimPowerComp
<
Real
>
(
uid
,
name
,
logLevel
)
{
mPhaseType
=
PhaseType
::
ABC
;
if
(
withTrafo
)
{
setVirtualNodeNumber
(
5
);
setVirtualNodeNumber
(
4
);
mConnectionTransformer
=
EMT
::
Ph3
::
Transformer
::
make
(
mName
+
"_trans"
,
Logger
::
Level
::
debug
);
mSubComponents
.
push_back
(
mConnectionTransformer
);
}
else
{
setVirtualNodeNumber
(
4
);
setVirtualNodeNumber
(
3
);
}
mWithConnectionTransformer
=
withTrafo
;
setTerminalNumber
(
1
);
mSLog
->
info
(
"Create {} {}"
,
this
->
type
(),
name
);
mSLog
->
info
(
"Create {} {}"
,
type
(),
name
);
mIntfVoltage
=
Matrix
::
Zero
(
3
,
1
);
mIntfCurrent
=
Matrix
::
Zero
(
3
,
1
);
// additional input variables
addAttribute
<
Matrix
>
(
"Vcdq"
,
&
mVcdq
,
Flags
::
read
|
Flags
::
write
);
addAttribute
<
Matrix
>
(
"Ircdq"
,
&
mIrcdq
,
Flags
::
read
|
Flags
::
write
);
// additional output variables
addAttribute
<
Matrix
>
(
"Vsdq"
,
&
mVsdq
,
Flags
::
read
|
Flags
::
write
);
// additional variables for logging
addAttribute
<
Real
>
(
"omega"
,
&
mOmegaInst
,
Flags
::
read
|
Flags
::
write
);
addAttribute
<
Real
>
(
"freq"
,
&
mFreqInst
,
Flags
::
read
|
Flags
::
write
);
addAttribute
<
Bool
>
(
"ctrl_on"
,
&
mCtrlOn
,
Flags
::
read
|
Flags
::
write
);
// state variables
addAttribute
<
Real
>
(
"theta"
,
&
mThetaPLL
,
Flags
::
read
|
Flags
::
write
);
addAttribute
<
Real
>
(
"phipll"
,
&
mPhiPLL
,
Flags
::
read
|
Flags
::
write
);
addAttribute
<
Real
>
(
"p"
,
&
mP
,
Flags
::
read
|
Flags
::
write
);
addAttribute
<
Real
>
(
"q"
,
&
mQ
,
Flags
::
read
|
Flags
::
write
);
addAttribute
<
Real
>
(
"phid"
,
&
mPhi_d
,
Flags
::
read
|
Flags
::
write
);
addAttribute
<
Real
>
(
"phiq"
,
&
mPhi_q
,
Flags
::
read
|
Flags
::
write
);
addAttribute
<
Real
>
(
"gammad"
,
&
mGamma_d
,
Flags
::
read
|
Flags
::
write
);
addAttribute
<
Real
>
(
"gammaq"
,
&
mGamma_q
,
Flags
::
read
|
Flags
::
write
);
// input variables
// 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
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
);
// 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
);
}
void
EMT
::
Ph3
::
AvVoltageSourceInverterDQ
::
setParameters
(
Real
sysOmega
,
Real
sysVoltNom
,
Real
Pref
,
Real
Qref
)
{
Base
::
AvVoltageSourceInverterDQWithStateSpace
::
setParameters
(
sysOmega
,
sysVoltNom
,
Pref
,
Qref
);
mParametersSet
=
true
;
mSLog
->
info
(
"General Parameters:"
);
mSLog
->
info
(
"Nominal Voltage={} [V] Nominal Omega={} [1/s]"
,
mVnom
,
mOmegaN
);
mSLog
->
info
(
"Active Power={} [W] Reactive Power={} [VAr]"
,
mPref
,
mQref
);
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
;
}
void
EMT
::
Ph3
::
AvVoltageSourceInverterDQ
::
setTransformerParameters
(
Real
nomVoltageEnd1
,
Real
nomVoltageEnd2
,
Real
ratedPower
,
Real
ratioAbs
,
Real
ratioPhase
,
Real
resistance
,
Real
inductance
,
Real
omega
)
{
Base
::
AvVoltageSourceInverterDQ
WithStateSpace
::
setTransformerParameters
(
nomVoltageEnd1
,
nomVoltageEnd2
,
Base
::
AvVoltageSourceInverterDQ
::
setTransformerParameters
(
nomVoltageEnd1
,
nomVoltageEnd2
,
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
);
if
(
mWithConnectionTransformer
)
mConnectionTransformer
->
setParameters
(
mTransformerRatioAbs
,
mTransformerRatioPhase
,
CPS
::
CIM
::
Reader
::
singlePhaseParameterToThreePhase
(
mTransformerResistance
),
CPS
::
CIM
::
Reader
::
singlePhaseParameterToThreePhase
(
mTransformerInductance
));
}
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
)
{
Base
::
AvVoltageSourceInverterDQWithStateSpace
::
setControllerParameters
(
Kp_pll
,
Ki_pll
,
Kp_powerCtrl
,
Ki_powerCtrl
,
Kp_currCtrl
,
Ki_currCtrl
,
Omega_cutoff
);
mSLog
->
info
(
"Control Parameters:"
);
mSLog
->
info
(
"PLL: K_i = {}, K_p = {}"
,
mKpPLL
,
mKiPLL
);
mSLog
->
info
(
"Power Loop: K_i = {}, K_p = {}"
,
mKpPowerCtrld
,
mKiPowerCtrld
);
mSLog
->
info
(
"Current Loop: K_i = {}, K_p = {}"
,
mKpCurrCtrld
,
mKiCurrCtrld
);
mSLog
->
info
(
"Cut-Off Frequency = {}"
,
mOmegaCutoff
);
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
);
}
void
EMT
::
Ph3
::
AvVoltageSourceInverterDQ
::
setFilterParameters
(
Real
Lf
,
Real
Cf
,
Real
Rf
,
Real
Rc
)
{
Base
::
AvVoltageSourceInverterDQWithStateSpace
::
setFilterParameters
(
Lf
,
Cf
,
Rf
,
Rc
);
Base
::
AvVoltageSourceInverterDQ
::
setFilterParameters
(
Lf
,
Cf
,
Rf
,
Rc
);
mSLog
->
info
(
"Filter Parameters:"
);
mSLog
->
info
(
"Inductance Lf={} [H] Capacitance Cf={} [F]"
,
mLf
,
mCf
);
mSLog
->
info
(
"Resistance Rf={} [H] Resistance Rc={} [F]"
,
mRf
,
mRc
);
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
));
}
void
EMT
::
Ph3
::
AvVoltageSourceInverterDQ
::
setInitialStateValues
(
Real
thetaPLLInit
,
Real
phiPLLInit
,
Real
pInit
,
Real
qInit
,
void
EMT
::
Ph3
::
AvVoltageSourceInverterDQ
::
setInitialStateValues
(
Real
pInit
,
Real
qInit
,
Real
phi_dInit
,
Real
phi_qInit
,
Real
gamma_dInit
,
Real
gamma_qInit
)
{
Base
::
AvVoltageSourceInverterDQWithStateSpace
::
setInitialStateValues
(
thetaPLLInit
,
phiPLLInit
,
pInit
,
qInit
,
phi_dInit
,
phi_qInit
,
gamma_dInit
,
gamma_qInit
);
mSLog
->
info
(
"Initial State Value Parameters:"
);
mSLog
->
info
(
"ThetaPLLInit = {}, PhiPLLInit = {}"
,
mThetaPLLInit
,
mPhiPLLInit
);
mSLog
->
info
(
"PInit = {}, QInit = {}"
,
mPInit
,
mQInit
);
mSLog
->
info
(
"Phi_dInit = {}, Phi_qInit = {}"
,
mPhi_dInit
,
mPhi_qInit
);
mSLog
->
info
(
"Gamma_dInit = {}, Gamma_qInit = {}"
,
mGamma_dInit
,
mGamma_qInit
);
}
SimPowerComp
<
Real
>::
Ptr
EMT
::
Ph3
::
AvVoltageSourceInverterDQ
::
clone
(
String
name
)
{
auto
copy
=
EMT
::
Ph3
::
AvVoltageSourceInverterDQ
::
make
(
name
,
mLogLevel
);
copy
->
setParameters
(
mOmegaN
,
mVnom
,
mPref
,
mQref
);
return
copy
;
}
void
EMT
::
Ph3
::
AvVoltageSourceInverterDQ
::
updateInputStateSpaceModel
(
const
Matrix
&
leftVector
,
Real
time
)
{
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
);
mVcabc
(
0
,
0
)
=
Math
::
realFromVectorElement
(
leftVector
,
mSubCapacitorF
->
matrixNodeIndex
(
0
,
0
));
mVcabc
(
1
,
0
)
=
Math
::
realFromVectorElement
(
leftVector
,
mSubCapacitorF
->
matrixNodeIndex
(
0
,
1
));
mVcabc
(
2
,
0
)
=
Math
::
realFromVectorElement
(
leftVector
,
mSubCapacitorF
->
matrixNodeIndex
(
0
,
2
));
mVcdq
=
parkTransformPowerInvariant
(
mThetaPLL
,
mVcabc
(
0
,
0
),
mVcabc
(
1
,
0
),
mVcabc
(
2
,
0
));
mIrcabc
=
-
1
*
mSubResistorC
->
attribute
<
Matrix
>
(
"i_intf"
)
->
get
();
mIrcdq
=
parkTransformPowerInvariant
(
mThetaPLL
,
mIrcabc
(
0
,
0
),
mIrcabc
(
1
,
0
),
mIrcabc
(
2
,
0
));
mIntfVoltage
(
0
,
0
)
=
Math
::
realFromVectorElement
(
leftVector
,
mTerminals
[
0
]
->
matrixNodeIndices
()[
0
]);
mIntfVoltage
(
1
,
0
)
=
Math
::
realFromVectorElement
(
leftVector
,
mTerminals
[
0
]
->
matrixNodeIndices
()[
1
]);
mIntfVoltage
(
2
,
0
)
=
Math
::
realFromVectorElement
(
leftVector
,
mTerminals
[
0
]
->
matrixNodeIndices
()[
2
]);
updateBMatrixStateSpaceModel
();
}
void
EMT
::
Ph3
::
AvVoltageSourceInverterDQ
::
addAggregatedGenProfile
(
std
::
vector
<
Real
>*
genProfile
,
Real
customerNumber
)
{
std
::
transform
(
genProfile
->
begin
(),
genProfile
->
end
(),
genProfile
->
begin
(),
std
::
bind1st
(
std
::
multiplies
<
Real
>
(),
customerNumber
));
mGenProfile
=
genProfile
;
}
void
EMT
::
Ph3
::
AvVoltageSourceInverterDQ
::
initializeStateSpaceModel
(
Real
omega
,
Real
timeStep
,
Attribute
<
Matrix
>::
Ptr
leftVector
)
{
mTimeStep
=
timeStep
;
mOmegaN
=
omega
;
mOmegaCutoff
=
omega
;
// get current and voltage inputs to state space model
// done here to ensure quantites are already initialized by initializeFromNodesAndTerminals
mIrcabc
=
-
1
*
mSubResistorC
->
attribute
<
Matrix
>
(
"i_intf"
)
->
get
();
mIrcdq
=
parkTransformPowerInvariant
(
mThetaPLL
,
mIrcabc
(
0
,
0
),
mIrcabc
(
1
,
0
),
mIrcabc
(
2
,
0
));
MatrixComp
initVcComplex
=
MatrixComp
::
Zero
(
3
,
1
);
initVcComplex
(
0
,
0
)
=
RMS3PH_TO_PEAK1PH
*
mVirtualNodes
[
4
]
->
initialSingleVoltage
();
initVcComplex
(
1
,
0
)
=
initVcComplex
(
0
,
0
)
*
SHIFT_TO_PHASE_B
;
initVcComplex
(
2
,
0
)
=
initVcComplex
(
0
,
0
)
*
SHIFT_TO_PHASE_C
;
mVcabc
=
initVcComplex
.
real
();
mVcdq
=
parkTransformPowerInvariant
(
mThetaPLL
,
mVcabc
(
0
,
0
),
mVcabc
(
1
,
0
),
mVcabc
(
2
,
0
));
updateBMatrixStateSpaceModel
();
// initialization of input
mU
<<
mOmegaN