From 7de5f870952689ddf5d94864d2d3eeb0c3893857 Mon Sep 17 00:00:00 2001 From: "martin.moraga" Date: Fri, 22 Mar 2024 09:21:59 +0100 Subject: [PATCH] added new DroopController signal class Signed-off-by: martin.moraga --- .../dpsim-models/Base/Base_VSIControlDQ.h | 41 ++-- .../Base/Base_VSIVoltageSourceInverterDQ.h | 219 +++++++++-------- .../include/dpsim-models/Components.h | 8 +- .../DP/DP_Ph1_VSIVoltageControlDQ.h | 5 +- .../EMT/EMT_Ph3_VSIVoltageControlDQ.h | 133 ++++++----- .../dpsim-models/Signal/DroopController.h | 58 +++++ .../dpsim-models/Signal/VSIControlType1.h | 24 +- .../Base/Base_VSIVoltageSourceInverterDQ.cpp | 109 +++++---- dpsim-models/src/CMakeLists.txt | 6 +- ...P_Ph1_ReducedOrderSynchronGeneratorVBR.cpp | 117 +++++---- dpsim-models/src/Signal/DroopController.cpp | 33 +++ dpsim-models/src/Signal/VSIControlType1.cpp | 225 +++++++++++++----- dpsim/src/pybind/DPComponents.cpp | 133 ++++++----- dpsim/src/pybind/EMTComponents.cpp | 150 ++++++------ dpsim/src/pybind/SPComponents.cpp | 120 +++++----- dpsim/src/pybind/SignalComponents.cpp | 24 +- python/src/dpsim/matpower.py | 2 +- 17 files changed, 858 insertions(+), 549 deletions(-) create mode 100644 dpsim-models/include/dpsim-models/Signal/DroopController.h create mode 100644 dpsim-models/src/Signal/DroopController.cpp diff --git a/dpsim-models/include/dpsim-models/Base/Base_VSIControlDQ.h b/dpsim-models/include/dpsim-models/Base/Base_VSIControlDQ.h index e5a14a92c7..f9cd09fc13 100644 --- a/dpsim-models/include/dpsim-models/Base/Base_VSIControlDQ.h +++ b/dpsim-models/include/dpsim-models/Base/Base_VSIControlDQ.h @@ -8,17 +8,23 @@ #pragma once -namespace CPS { -namespace Base { +#include - class VSIControlParameters { +namespace CPS +{ + namespace Base + { + + class VSIControlParameters + { public: - VSIControlParameters() { }; + VSIControlParameters(){}; virtual ~VSIControlParameters() = default; - }; + }; - /// @brief Base model for VSI controllers in dq reference frame - class VSIControlDQ { + /// @brief Base model for VSI controllers in dq reference frame + class VSIControlDQ + { protected: /// @@ -27,20 +33,23 @@ namespace Base { Bool mModelAsCurrentSource; public: - /// virtual void setParameters(std::shared_ptr parameters) = 0; + /// + virtual void calculateVBRconstants(){}; + /// Initializes - virtual void initialize(const Complex& Vsref_dq, const Complex& Vcap_dq, - const Complex& Ifilter_dq, Real time_step, Bool modelAsCurrentSource) = 0; + virtual void initialize(const Complex &Vsref_dq, const Complex &Vcap_dq, + const Complex &Ifilter_dq, Real time_step, Bool modelAsCurrentSource) = 0; /// Returns voltage of the voltage source if mModelAsCurrentSource=false, /// and current of equivalent current source if mModelAsCurrentSource=true - virtual Complex step(const Complex& Vcap_dq, const Complex& Ifilter_dq) = 0; - - }; -} + virtual Complex step(const Complex &Vcap_dq, const Complex &Ifilter_dq) = 0; + virtual Complex stepVBR(const Complex &Vcap_dq, const Complex &Ifilter_dq) + { + return Complex(0, 0); + }; + }; + } } - - diff --git a/dpsim-models/include/dpsim-models/Base/Base_VSIVoltageSourceInverterDQ.h b/dpsim-models/include/dpsim-models/Base/Base_VSIVoltageSourceInverterDQ.h index 907490aa5a..3aa5b70c1d 100644 --- a/dpsim-models/include/dpsim-models/Base/Base_VSIVoltageSourceInverterDQ.h +++ b/dpsim-models/include/dpsim-models/Base/Base_VSIVoltageSourceInverterDQ.h @@ -12,111 +12,120 @@ #include #include #include +#include #include -namespace CPS { -namespace Base { - - /// @brief Base model of average grid forming inverter - template - class VSIVoltageSourceInverterDQ { - private: - /// Component logger - Logger::Log mLogger; - - protected: - // ### General Parameters ### - /// mModelAsCurrentSource=true --> Inverter is modeled as current source, otherwise as voltage source - Bool mModelAsCurrentSource; - /// Simulation step - Real mTimeStep; - /// Nominal Omega - Real mOmegaN; - - // ### Inverter Parameters ### - /// Nominal frequency - Real mOmegaNom; - /// Nominal voltage - Real mVnom; - /// Voltage d reference - Real mVdRef; - /// Voltage q reference - Real mVqRef; - /// Active power reference - Real mPref; - - // ### Inverter Flags ### - /// Flag for usage of interface resistor Rc - Bool mWithInterfaceResistor = false; - /// Flag for control droop usage - Bool mWithDroop = false; - - // Filter parameters - Real mLf; - Real mCf; - Real mRf; - Real mRc; - - // ### Inverter Variables ### - /// Omega - const Attribute::Ptr mOmega; - /// System angle (rotating at nominal omega) - const Attribute::Ptr mThetaSys; - /// Inverter angle (rotating at inverter omega) - const Attribute::Ptr mThetaInv; - /// Voltage/Current as control output after transformation interface - const Attribute::Ptr mSourceValue; - /// Voltage/Current as control output after transformation interface - const Attribute::Ptr mSourceValue_dq; - /// Measured voltage in dq reference frame - const Attribute::Ptr mVcap_dq; - /// Measured current in dq reference frame - const Attribute::Ptr mIfilter_dq; - /// inverter terminal active power - const Attribute::Ptr mPower; - - // ### Voltage Controller Variables ### - - // #### Controllers #### - /// Determines if VSI control is activated - Bool mWithControl = true; - - /// Signal component modelling voltage regulator and exciter - std::shared_ptr mVSIController; - - public: - explicit VSIVoltageSourceInverterDQ(Logger::Log Log, CPS::AttributeList::Ptr attributeList, - Bool modelAsCurrentSource, Bool withInterfaceResistor) : - mLogger(Log), - mModelAsCurrentSource(modelAsCurrentSource), - mWithInterfaceResistor(withInterfaceResistor), - mOmega(attributeList->create("Omega", 0)), - mThetaSys(attributeList->create("ThetaSys", 0)), - mThetaInv(attributeList->create("ThetaInv", 0)), - mSourceValue(attributeList->create("SourceValue", MatrixComp::Zero(1,1))), - mSourceValue_dq(attributeList->create("SourceValue_dq", Complex(0,0))), - mVcap_dq(attributeList->create("Vcap_dq", 0)), - mIfilter_dq(attributeList->create("Ifilter_dq", 0)), - mPower(attributeList->create("Power", 0)){ }; - - /// Setter for general parameters of inverter - void setParameters(Real sysOmega, Real VdRef, Real VqRef); - /// Setter for filter parameters - void setFilterParameters(Real Lf, Real Cf, Real Rf, Real Rc); - - // ### Controllers ### - /// Add VSI Controller - void addVSIController(std::shared_ptr VSIController); - - protected: - /// - virtual void createSubComponents() = 0; - /// - int determineNumberOfVirtualNodes(); - /// - void initializeFilterVariables(const Complex & interfaceVoltage, - const Complex & interfaceCurrent, - typename SimNode::List virtualNodesList); - }; -} +namespace CPS +{ + namespace Base + { + + /// @brief Base model of average grid forming inverter + template + class VSIVoltageSourceInverterDQ + { + private: + /// Component logger + Logger::Log mLogger; + + protected: + // ### General Parameters ### + /// mModelAsCurrentSource=true --> Inverter is modeled as current source, otherwise as voltage source + Bool mModelAsCurrentSource; + /// Simulation step + Real mTimeStep; + /// Nominal Omega + Real mOmegaN; + + // ### Inverter Parameters ### + /// Nominal frequency + Real mOmegaNom; + /// Nominal voltage + Real mVnom; + /// Voltage d reference + Real mVdRef; + /// Voltage q reference + Real mVqRef; + /// Active power reference + Real mPref; + + // ### Inverter Flags ### + /// Flag for usage of interface resistor Rc + Bool mWithInterfaceResistor = false; + /// Flag for control droop usage + Bool mWithDroop = false; + + // Filter parameters + Real mLf; + Real mCf; + Real mRf; + Real mRc; + + // ### Inverter Variables ### + /// Omega + const Attribute::Ptr mOmega; + /// System angle (rotating at nominal omega) + const Attribute::Ptr mThetaSys; + /// Inverter angle (rotating at inverter omega) + const Attribute::Ptr mThetaInv; + /// Voltage/Current as control output after transformation interface + const Attribute::Ptr mSourceValue; + /// Voltage/Current as control output after transformation interface + const Attribute::Ptr mSourceValue_dq; + /// Measured voltage in dq reference frame + const Attribute::Ptr mVcap_dq; + /// Measured current in dq reference frame + const Attribute::Ptr mIfilter_dq; + /// inverter terminal active power + const Attribute::Ptr mPower; + + // ### Voltage Controller Variables ### + + // #### Controllers #### + /// Determines if VSI control is activated + Bool mWithControl = true; + /// Determines if Droop Control is activated + Bool mWithDroopControl = false; + + /// Signal component modelling vsi controller (grid forming or grid following mode) + std::shared_ptr mVSIController; + /// Signal component modelling the droop controller + std::shared_ptr mDroopController; + + public: + explicit VSIVoltageSourceInverterDQ(Logger::Log Log, CPS::AttributeList::Ptr attributeList, + Bool modelAsCurrentSource, Bool withInterfaceResistor) : mLogger(Log), + mModelAsCurrentSource(modelAsCurrentSource), + mWithInterfaceResistor(withInterfaceResistor), + mOmega(attributeList->create("Omega", 0)), + mThetaSys(attributeList->create("ThetaSys", 0)), + mThetaInv(attributeList->create("ThetaInv", 0)), + mSourceValue(attributeList->create("SourceValue", MatrixComp::Zero(1, 1))), + mSourceValue_dq(attributeList->create("SourceValue_dq", Complex(0, 0))), + mVcap_dq(attributeList->create("Vcap_dq", 0)), + mIfilter_dq(attributeList->create("Ifilter_dq", 0)), + mPower(attributeList->create("Power", 0)){}; + + /// Setter for general parameters of inverter + void setParameters(Real sysOmega, Real VdRef, Real VqRef); + /// Setter for filter parameters + void setFilterParameters(Real Lf, Real Cf, Real Rf, Real Rc); + + // ### Controllers ### + /// VSI Controller + void addVSIController(std::shared_ptr VSIController); + /// Droop Controller + void addDroopController(std::shared_ptr DroopController); + + protected: + /// + virtual void createSubComponents() = 0; + /// + int determineNumberOfVirtualNodes(); + /// + void initializeFilterVariables(const Complex &interfaceVoltage, + const Complex &interfaceCurrent, + typename SimNode::List virtualNodesList); + }; + } } diff --git a/dpsim-models/include/dpsim-models/Components.h b/dpsim-models/include/dpsim-models/Components.h index 7cc59b04ff..8c8324a2d2 100644 --- a/dpsim-models/include/dpsim-models/Components.h +++ b/dpsim-models/include/dpsim-models/Components.h @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -74,6 +75,7 @@ #include #include #include +#include #include #include #include @@ -82,7 +84,7 @@ #include #include #ifdef WITH_SUNDIALS - #include +#include #endif #include #include @@ -97,6 +99,7 @@ #include #include #include +#include #include #include #include @@ -115,7 +118,7 @@ #include #include #ifdef WITH_SUNDIALS - #include +#include #endif #include #include @@ -152,3 +155,4 @@ #include #include #include +#include \ No newline at end of file diff --git a/dpsim-models/include/dpsim-models/DP/DP_Ph1_VSIVoltageControlDQ.h b/dpsim-models/include/dpsim-models/DP/DP_Ph1_VSIVoltageControlDQ.h index ae29a31fb9..b01e54f893 100644 --- a/dpsim-models/include/dpsim-models/DP/DP_Ph1_VSIVoltageControlDQ.h +++ b/dpsim-models/include/dpsim-models/DP/DP_Ph1_VSIVoltageControlDQ.h @@ -9,12 +9,11 @@ #include #include +#include #include #include #include -#include #include -#include namespace CPS { namespace DP { @@ -23,8 +22,8 @@ namespace Ph1 { public CompositePowerComp, public Base::VSIVoltageSourceInverterDQ, public SharedFactory { - protected: + protected: // ### Electrical Subcomponents ### /// Controlled voltage source std::shared_ptr mSubCtrledVoltageSource; diff --git a/dpsim-models/include/dpsim-models/EMT/EMT_Ph3_VSIVoltageControlDQ.h b/dpsim-models/include/dpsim-models/EMT/EMT_Ph3_VSIVoltageControlDQ.h index 638d6259df..f43f5e410b 100644 --- a/dpsim-models/include/dpsim-models/EMT/EMT_Ph3_VSIVoltageControlDQ.h +++ b/dpsim-models/include/dpsim-models/EMT/EMT_Ph3_VSIVoltageControlDQ.h @@ -16,76 +16,77 @@ #include #include -namespace CPS { -namespace EMT { -namespace Ph3 { - class VSIVoltageControlDQ : - public CompositePowerComp, - public Base::VSIVoltageSourceInverterDQ, - public SharedFactory { - protected: +namespace CPS +{ + namespace EMT + { + namespace Ph3 + { + class VSIVoltageControlDQ : public CompositePowerComp, + public Base::VSIVoltageSourceInverterDQ, + public SharedFactory + { + protected: + // ### Electrical Subcomponents ### + /// Controlled voltage source + std::shared_ptr mSubCtrledVoltageSource; + /// RL Element as part of LC filter + std::shared_ptr mSubFilterRL; + /// Capacitor Cf as part of LC filter + std::shared_ptr mSubCapacitorF; + /// Optional interface Resistor Rc (connected between grid and filter capacitor) + std::shared_ptr mSubResistorC; - // ### Electrical Subcomponents ### - /// Controlled voltage source - std::shared_ptr mSubCtrledVoltageSource; - /// RL Element as part of LC filter - std::shared_ptr mSubFilterRL; - /// Capacitor Cf as part of LC filter - std::shared_ptr mSubCapacitorF; - /// Optional interface Resistor Rc (connected between grid and filter capacitor) - std::shared_ptr mSubResistorC; + public: + // ### General Parameters ### - public: - // ### General Parameters ### + /// Defines name amd logging level + VSIVoltageControlDQ(String name, Logger::Level logLevel = Logger::Level::off) + : VSIVoltageControlDQ(name, name, logLevel) {} + /// Defines UID, name, logging level and connection trafo existence + VSIVoltageControlDQ(String uid, String name, Logger::Level logLevel = Logger::Level::off, + Bool modelAsCurrentSource = false, Bool withInterfaceResistor = false); - /// Defines name amd logging level - VSIVoltageControlDQ(String name, Logger::Level logLevel = Logger::Level::off) - : VSIVoltageControlDQ(name, name, logLevel) {} - /// Defines UID, name, logging level and connection trafo existence - VSIVoltageControlDQ(String uid, String name, Logger::Level logLevel = Logger::Level::off, - Bool modelAsCurrentSource = false, Bool withInterfaceResistor = false); + // #### General #### + /// Initializes component from power flow data + void initializeFromNodesAndTerminals(Real frequency) final; - // #### General #### - /// Initializes component from power flow data - void initializeFromNodesAndTerminals(Real frequency) final; + // #### MNA section #### + /// Initializes internal variables of the component + void mnaParentInitialize(Real omega, Real timeStep, Attribute::Ptr leftVector) final; + /// Updates current through the component + void mnaCompUpdateCurrent(const Matrix &leftVector) final; + /// Updates voltage across component + void mnaCompUpdateVoltage(const Matrix &leftVector) final; + /// MNA pre step operations + void mnaParentPreStep(Real time, Int timeStepCount) final; + /// + void mnaParentApplyRightSideVectorStamp(Matrix &rightVector) final; + /// MNA post step operations + void mnaParentPostStep(Real time, Int timeStepCount, Attribute::Ptr &leftVector) final; + /// Add MNA pre step dependencies + void mnaParentAddPreStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes) final; + /// Add MNA post step dependencies + void mnaParentAddPostStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes, Attribute::Ptr &leftVector) final; - // #### MNA section #### - /// Initializes internal variables of the component - void mnaParentInitialize(Real omega, Real timeStep, Attribute::Ptr leftVector) final; - /// Updates current through the component - void mnaCompUpdateCurrent(const Matrix& leftVector) final; - /// Updates voltage across component - void mnaCompUpdateVoltage(const Matrix& leftVector) final; - /// MNA pre step operations - void mnaParentPreStep(Real time, Int timeStepCount) final; - /// - void mnaParentApplyRightSideVectorStamp(Matrix& rightVector) final; - /// MNA post step operations - void mnaParentPostStep(Real time, Int timeStepCount, Attribute::Ptr &leftVector) final; - /// Add MNA pre step dependencies - void mnaParentAddPreStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes) final; - /// Add MNA post step dependencies - void mnaParentAddPostStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes, Attribute::Ptr &leftVector) final; + private: + /// + void createSubComponents() final; + /// + void connectSubComponents(); + /// + void updatePower(); - private: - /// - void createSubComponents() final; - /// - void connectSubComponents(); - /// - void updatePower(); - - // #### Mathematical Matrix Transforms #### - /// - Matrix getParkTransformMatrixPowerInvariant(Real theta); - /// - Complex parkTransformPowerInvariant(Real theta, const Matrix &fabc); - /// - Matrix getInverseParkTransformMatrixPowerInvariant(Real theta); - /// - Matrix inverseParkTransformPowerInvariant(Real theta, const Complex &fdq); - - }; -} -} + // #### Mathematical Matrix Transforms #### + /// + Matrix getParkTransformMatrixPowerInvariant(Real theta); + /// + Complex parkTransformPowerInvariant(Real theta, const Matrix &fabc); + /// + Matrix getInverseParkTransformMatrixPowerInvariant(Real theta); + /// + Matrix inverseParkTransformPowerInvariant(Real theta, const Complex &fdq); + }; + } + } } diff --git a/dpsim-models/include/dpsim-models/Signal/DroopController.h b/dpsim-models/include/dpsim-models/Signal/DroopController.h new file mode 100644 index 0000000000..438188f7a2 --- /dev/null +++ b/dpsim-models/include/dpsim-models/Signal/DroopController.h @@ -0,0 +1,58 @@ +#pragma once + +#include +#include + +namespace CPS +{ + namespace Signal + { + + class DroopControllerParameters : public SharedFactory + { + + public: + /// Time constant lag unit + Real Tau_p; + /// Time constant lead-lag unit + Real Tau_l; + /// + Real Mp; + /// + Real Pref; + /// + Real OmegaNom; + }; + + /// DOC: + class DroopController : public SimSignalComp, + public SharedFactory + { + + private: + /// + Real mTimeStep; + /// Controller Parameters + std::shared_ptr mParameters; + + /// Controller variables + /// Omega + const Attribute::Ptr mOmega; + + public: + /// + explicit DroopController(const String &name, CPS::Logger::Level logLevel) : SimSignalComp(name, name, logLevel), + mOmega(mAttributes->create("Omega", 0)) {} + + /// Sets Parameters of the vsi controller + void setParameters(std::shared_ptr parameters); + + /// Initialises the initial state of the vsi controller + void initialize(Real time_step, Real initial_omega); + + /// Performs a step to update all state variables and the output + Real step(const Real mActivePower); + }; + + } +} \ No newline at end of file diff --git a/dpsim-models/include/dpsim-models/Signal/VSIControlType1.h b/dpsim-models/include/dpsim-models/Signal/VSIControlType1.h index 4fc23ce78e..46d23bdafd 100644 --- a/dpsim-models/include/dpsim-models/Signal/VSIControlType1.h +++ b/dpsim-models/include/dpsim-models/Signal/VSIControlType1.h @@ -45,6 +45,15 @@ namespace Signal { public SimSignalComp, public Base::VSIControlDQ, public SharedFactory { + + public: + /// @brief VBR auxiliar variables + Real mA_VBR; + Real mB_VBR; + Real mB2_VBR; + Real mC_VBR; + Real mD_VBR; + Real mE_VBR; private: /// Controller Parameters @@ -52,7 +61,7 @@ namespace Signal { /// Controller variables /// state variable of the outer loop (d-component) - Attribute::Ptr mPhi_d; + const Attribute::Ptr mPhi_d; /// state variable of the outer loop (q-component) const Attribute::Ptr mPhi_q; /// state variable of the inner loop (d-component) @@ -90,6 +99,12 @@ namespace Signal { /// Output const Attribute::Ptr mOutput; + /// ### VBR Auxiliar Variables ### + Complex mVcap_dq; + Complex mIfilter_dq; + Real mIref_d; + Real mIref_q; + public: /// explicit VSIControlType1(const String & name, CPS::Logger::Level logLevel) : @@ -110,12 +125,19 @@ namespace Signal { /// Sets Parameters of the vsi controller void setParameters(std::shared_ptr parameters) final; + /// + void calculateVBRconstants() final; + /// Initialises the initial state of the vsi controller void initialize(const Complex& Vsref_dq, const Complex& Vcap_dq, const Complex& Ifilter_dq, Real time_step, Bool modelAsCurrentSource) final; /// Performs a step to update all state variables and the output Complex step(const Complex& Vcap_dq, const Complex& Ifilter_dq) final; + + /// + Complex stepVBR(const Complex& Vcap_dq, const Complex& Ifilter_dq) final; + }; } diff --git a/dpsim-models/src/Base/Base_VSIVoltageSourceInverterDQ.cpp b/dpsim-models/src/Base/Base_VSIVoltageSourceInverterDQ.cpp index ec7d369ee9..0a3dc7ff68 100644 --- a/dpsim-models/src/Base/Base_VSIVoltageSourceInverterDQ.cpp +++ b/dpsim-models/src/Base/Base_VSIVoltageSourceInverterDQ.cpp @@ -12,23 +12,25 @@ using namespace CPS; template void Base::VSIVoltageSourceInverterDQ::setParameters( - Real sysOmega, Real VdRef, Real VqRef) { + Real sysOmega, Real VdRef, Real VqRef) +{ mOmegaNom = sysOmega; mVdRef = VdRef; mVqRef = VqRef; - SPDLOG_LOGGER_INFO(mLogger, - "\nGeneral Parameters:" - "\n\tNominal Omega = {} [1/s]" - "\n\tVdRef = {} [V] " - "\n\tVqRef = {} [V]", - mOmegaNom, mVdRef, mVqRef); + SPDLOG_LOGGER_INFO(mLogger, + "\nGeneral Parameters:" + "\n\tNominal Omega = {} [1/s]" + "\n\tVdRef = {} [V] " + "\n\tVqRef = {} [V]", + mOmegaNom, mVdRef, mVqRef); } template void Base::VSIVoltageSourceInverterDQ::setFilterParameters( - Real Lf, Real Cf, Real Rf, Real Rc) { + Real Lf, Real Cf, Real Rf, Real Rc) +{ mLf = Lf; mCf = Cf; @@ -37,37 +39,47 @@ void Base::VSIVoltageSourceInverterDQ::setFilterParameters( createSubComponents(); - SPDLOG_LOGGER_INFO(mLogger, - "\nFilter Parameters:" - "\n\tInductance Lf = {} [H]" - "\n\tCapacitance Cf = {} [F]" - "\n\tResistance Rf = {} [H]" - "\n\tResistance Rc = {} [F]", - mLf, mCf, mRf, mRc); + SPDLOG_LOGGER_INFO(mLogger, + "\nFilter Parameters:" + "\n\tInductance Lf = {} [H]" + "\n\tCapacitance Cf = {} [F]" + "\n\tResistance Rf = {} [H]" + "\n\tResistance Rc = {} [F]", + mLf, mCf, mRf, mRc); mLogger->flush(); } template -int Base::VSIVoltageSourceInverterDQ::determineNumberOfVirtualNodes() { +int Base::VSIVoltageSourceInverterDQ::determineNumberOfVirtualNodes() +{ // first virtual node is the second node of the rl element int numberOfVirtualNodes = 1; - - if (mWithInterfaceResistor) - numberOfVirtualNodes += 1; - + + if (mWithInterfaceResistor) + numberOfVirtualNodes += 1; + return numberOfVirtualNodes; } template -void Base::VSIVoltageSourceInverterDQ::addVSIController(std::shared_ptr VSIController) { +void Base::VSIVoltageSourceInverterDQ::addVSIController(std::shared_ptr VSIController) +{ mVSIController = VSIController; mWithControl = true; } +template +void Base::VSIVoltageSourceInverterDQ::addDroopController(std::shared_ptr DroopController) +{ + mDroopController = DroopController; + mWithDroop = true; +} + template void Base::VSIVoltageSourceInverterDQ::initializeFilterVariables( - const Complex & interfaceVoltage, const Complex & interfaceCurrent, - typename SimNode::List virtualNodesList) { + const Complex &interfaceVoltage, const Complex &interfaceCurrent, + typename SimNode::List virtualNodesList) +{ // derive initialization quantities of filter /// initial filter capacitor voltage @@ -77,7 +89,7 @@ void Base::VSIVoltageSourceInverterDQ::initializeFilterVariables( else vcInit = interfaceVoltage; - /// initial filter capacitor current + /// initial filter capacitor current Complex icfInit = vcInit * Complex(0., mOmegaNom * mCf); /// initial voltage/current equivalent source @@ -96,35 +108,36 @@ void Base::VSIVoltageSourceInverterDQ::initializeFilterVariables( **mVcap_dq = Math::rotatingFrame2to1(vcInit, **mThetaInv, **mThetaSys); **mIfilter_dq = Math::rotatingFrame2to1(filterCurrentInit, **mThetaInv, **mThetaSys); **mSourceValue_dq = Math::rotatingFrame2to1(sourceInitialValue, **mThetaInv, **mThetaSys); - - String inverter_type = mModelAsCurrentSource? "current source": "voltage source"; - String unit = mModelAsCurrentSource? "[A]": "[V]"; - SPDLOG_LOGGER_INFO(mLogger, - "\nInverter will be modelled as {}" - "\nInitialize Filter Variables:" - "\n\tInitial capacitor voltage: {}[V]" - "\n\tInitial capacitor voltage d-axis: {}[V]" - "\n\tInitial capacitor voltage q-axis: {}[V]" - "\n\tInitial filter current: {}[A]" - "\n\tInitial filter d-axis: {}[A]" - "\n\tInitial filter q-axis: {}[A]" - "\n\tInitial equivalent source: {}{}" - "\n\tInverter equivalent source d-axis value: {}{}" - "\n\tInverter equivalent source q-axis value: {}{}", - inverter_type, - Logger::phasorToString(vcInit), - (**mVcap_dq).real(), (**mVcap_dq).imag(), - Logger::phasorToString(filterCurrentInit), - (**mIfilter_dq).real(), (**mIfilter_dq).imag(), - sourceInitialValue, unit, - (**mSourceValue_dq).real(), unit, - (**mSourceValue_dq).imag(), unit); + + String inverter_type = mModelAsCurrentSource ? "current source" : "voltage source"; + String unit = mModelAsCurrentSource ? "[A]" : "[V]"; + SPDLOG_LOGGER_INFO(mLogger, + "\nInverter will be modelled as {}" + "\nInitialize Filter Variables:" + "\n\tInitial capacitor voltage: {}[V]" + "\n\tInitial capacitor voltage d-axis: {}[V]" + "\n\tInitial capacitor voltage q-axis: {}[V]" + "\n\tInitial filter current: {}[A]" + "\n\tInitial filter d-axis: {}[A]" + "\n\tInitial filter q-axis: {}[A]" + "\n\tInitial equivalent source: {}{}" + "\n\tInverter equivalent source d-axis value: {}{}" + "\n\tInverter equivalent source q-axis value: {}{}", + inverter_type, + Logger::phasorToString(vcInit), + (**mVcap_dq).real(), (**mVcap_dq).imag(), + Logger::phasorToString(filterCurrentInit), + (**mIfilter_dq).real(), (**mIfilter_dq).imag(), + sourceInitialValue, unit, + (**mSourceValue_dq).real(), unit, + (**mSourceValue_dq).imag(), unit); mLogger->flush(); // TODO: MOVE // initialize voltage of virtual nodes virtualNodesList[0]->setInitialVoltage(vcInit + filterCurrentInit * Complex(mRf, mOmegaNom * mLf)); - if (mWithInterfaceResistor) { + if (mWithInterfaceResistor) + { // filter capacitor is connected to mVirtualNodes[1], the second // node of the interface resistor is mTerminals[0] virtualNodesList[1]->setInitialVoltage(vcInit); diff --git a/dpsim-models/src/CMakeLists.txt b/dpsim-models/src/CMakeLists.txt index dd228d0d13..72919f1fd2 100644 --- a/dpsim-models/src/CMakeLists.txt +++ b/dpsim-models/src/CMakeLists.txt @@ -52,6 +52,7 @@ list(APPEND MODELS_SOURCES DP/DP_Ph1_varResSwitch.cpp DP/DP_Ph1_DPDQInterface.cpp DP/DP_Ph1_VSIVoltageControlDQ.cpp + DP/DP_Ph1_VSIVoltageControlVBR.cpp DP/DP_Ph3_VoltageSource.cpp DP/DP_Ph3_Capacitor.cpp @@ -107,6 +108,7 @@ list(APPEND MODELS_SOURCES # EMT/EMT_Ph3_SynchronGeneratorVBRStandalone.cpp EMT/EMT_Ph3_SynchronGeneratorTrStab.cpp EMT/EMT_Ph3_VSIVoltageControlDQ.cpp + EMT/EMT_Ph3_VSIVoltageControlVBR.cpp SP/SP_Ph1_VoltageSource.cpp SP/SP_Ph1_Capacitor.cpp @@ -135,12 +137,13 @@ list(APPEND MODELS_SOURCES SP/SP_Ph1_NetworkInjection.cpp SP/SP_Ph1_SynchronGeneratorTrStab.cpp SP/SP_Ph1_varResSwitch.cpp + SP/SP_Ph1_VSIVoltageControlDQ.cpp + SP/SP_Ph1_VSIVoltageControlVBR.cpp SP/SP_Ph3_Capacitor.cpp SP/SP_Ph3_Inductor.cpp SP/SP_Ph3_Resistor.cpp SP/SP_Ph3_VoltageSource.cpp - SP/SP_Ph1_VSIVoltageControlDQ.cpp Signal/DecouplingLine.cpp Signal/DecouplingLineEMT.cpp @@ -155,6 +158,7 @@ list(APPEND MODELS_SOURCES Signal/PLL.cpp Signal/VCO.cpp Signal/Droop.cpp + Signal/DroopController.cpp Signal/Integrator.cpp Signal/PowerControllerVSI.cpp Signal/VoltageControllerVSI.cpp diff --git a/dpsim-models/src/DP/DP_Ph1_ReducedOrderSynchronGeneratorVBR.cpp b/dpsim-models/src/DP/DP_Ph1_ReducedOrderSynchronGeneratorVBR.cpp index 52159e12e6..e79a7e5586 100644 --- a/dpsim-models/src/DP/DP_Ph1_ReducedOrderSynchronGeneratorVBR.cpp +++ b/dpsim-models/src/DP/DP_Ph1_ReducedOrderSynchronGeneratorVBR.cpp @@ -10,9 +10,9 @@ using namespace CPS; -DP::Ph1::ReducedOrderSynchronGeneratorVBR::ReducedOrderSynchronGeneratorVBR - (const String & uid, const String & name, Logger::Level logLevel) - : Base::ReducedOrderSynchronGenerator(uid, name, logLevel) { +DP::Ph1::ReducedOrderSynchronGeneratorVBR::ReducedOrderSynchronGeneratorVBR(const String &uid, const String &name, Logger::Level logLevel) + : Base::ReducedOrderSynchronGenerator(uid, name, logLevel) +{ mPhaseType = PhaseType::Single; setTerminalNumber(1); @@ -22,27 +22,29 @@ DP::Ph1::ReducedOrderSynchronGeneratorVBR::ReducedOrderSynchronGeneratorVBR **mIntfCurrent = MatrixComp::Zero(1, 1); // initialize conductance Matrix - mConductanceMatrix = Matrix::Zero(2,2); + mConductanceMatrix = Matrix::Zero(2, 2); } -DP::Ph1::ReducedOrderSynchronGeneratorVBR::ReducedOrderSynchronGeneratorVBR - (const String & name, Logger::Level logLevel) - : ReducedOrderSynchronGeneratorVBR(name, name, logLevel) { +DP::Ph1::ReducedOrderSynchronGeneratorVBR::ReducedOrderSynchronGeneratorVBR(const String &name, Logger::Level logLevel) + : ReducedOrderSynchronGeneratorVBR(name, name, logLevel) +{ } -void DP::Ph1::ReducedOrderSynchronGeneratorVBR::calculateConductanceMatrix() { - MatrixFixedSize<2, 2> resistanceMatrix = MatrixFixedSize<2, 2>::Zero(2,2); +void DP::Ph1::ReducedOrderSynchronGeneratorVBR::calculateConductanceMatrix() +{ + MatrixFixedSize<2, 2> resistanceMatrix = MatrixFixedSize<2, 2>::Zero(2, 2); Real DeltaTheta = **mThetaMech - mBase_OmMech * mSimTime; - resistanceMatrix(0,0) = - (mA + mB) / 2.0 * sin(2*DeltaTheta); - resistanceMatrix(0,1) = (mA - mB) / 2.0 + (mA + mB) / 2.0 * cos(2*DeltaTheta); - resistanceMatrix(1,0) = - (mA - mB) / 2.0 + (mA + mB) / 2.0 * cos(2*DeltaTheta); - resistanceMatrix(1,1) = (mA + mB) / 2.0 * sin(2*DeltaTheta); + resistanceMatrix(0, 0) = -(mA + mB) / 2.0 * sin(2 * DeltaTheta); + resistanceMatrix(0, 1) = (mA - mB) / 2.0 + (mA + mB) / 2.0 * cos(2 * DeltaTheta); + resistanceMatrix(1, 0) = -(mA - mB) / 2.0 + (mA + mB) / 2.0 * cos(2 * DeltaTheta); + resistanceMatrix(1, 1) = (mA + mB) / 2.0 * sin(2 * DeltaTheta); resistanceMatrix = resistanceMatrix * mBase_Z; mConductanceMatrix = resistanceMatrix.inverse(); } void DP::Ph1::ReducedOrderSynchronGeneratorVBR::mnaCompInitialize(Real omega, - Real timeStep, Attribute::Ptr leftVector) { + Real timeStep, Attribute::Ptr leftVector) +{ Base::ReducedOrderSynchronGenerator::mnaCompInitialize(omega, timeStep, leftVector); @@ -53,35 +55,38 @@ void DP::Ph1::ReducedOrderSynchronGeneratorVBR::mnaCompInitialize(Real omega, auto complexOffset = (UInt)(n / 2); // set variable matrix entries depending on equivalent representation - if (mModelAsNortonSource) { - mVariableSystemMatrixEntries.push_back(std::make_pair(matrixNodeIndex(0, 0), matrixNodeIndex(0, 0))); - mVariableSystemMatrixEntries.push_back(std::make_pair(matrixNodeIndex(0, 0) + complexOffset, matrixNodeIndex(0, 0))); - mVariableSystemMatrixEntries.push_back(std::make_pair(matrixNodeIndex(0, 0), matrixNodeIndex(0, 0) + complexOffset)); - mVariableSystemMatrixEntries.push_back(std::make_pair(matrixNodeIndex(0, 0) + complexOffset, matrixNodeIndex(0, 0) + complexOffset)); - } else { + if (mModelAsNortonSource) + { + mVariableSystemMatrixEntries.push_back(std::make_pair(matrixNodeIndex(0, 0), matrixNodeIndex(0, 0))); + mVariableSystemMatrixEntries.push_back(std::make_pair(matrixNodeIndex(0, 0) + complexOffset, matrixNodeIndex(0, 0))); + mVariableSystemMatrixEntries.push_back(std::make_pair(matrixNodeIndex(0, 0), matrixNodeIndex(0, 0) + complexOffset)); + mVariableSystemMatrixEntries.push_back(std::make_pair(matrixNodeIndex(0, 0) + complexOffset, matrixNodeIndex(0, 0) + complexOffset)); + } + else + { // upper left - mVariableSystemMatrixEntries.push_back(std::make_pair(mVirtualNodes[0]->matrixNodeIndex(), mVirtualNodes[0]->matrixNodeIndex())); - mVariableSystemMatrixEntries.push_back(std::make_pair(mVirtualNodes[0]->matrixNodeIndex() + complexOffset, mVirtualNodes[0]->matrixNodeIndex())); - mVariableSystemMatrixEntries.push_back(std::make_pair(mVirtualNodes[0]->matrixNodeIndex(), mVirtualNodes[0]->matrixNodeIndex() + complexOffset)); - mVariableSystemMatrixEntries.push_back(std::make_pair(mVirtualNodes[0]->matrixNodeIndex() + complexOffset, mVirtualNodes[0]->matrixNodeIndex() + complexOffset)); + mVariableSystemMatrixEntries.push_back(std::make_pair(mVirtualNodes[0]->matrixNodeIndex(), mVirtualNodes[0]->matrixNodeIndex())); + mVariableSystemMatrixEntries.push_back(std::make_pair(mVirtualNodes[0]->matrixNodeIndex() + complexOffset, mVirtualNodes[0]->matrixNodeIndex())); + mVariableSystemMatrixEntries.push_back(std::make_pair(mVirtualNodes[0]->matrixNodeIndex(), mVirtualNodes[0]->matrixNodeIndex() + complexOffset)); + mVariableSystemMatrixEntries.push_back(std::make_pair(mVirtualNodes[0]->matrixNodeIndex() + complexOffset, mVirtualNodes[0]->matrixNodeIndex() + complexOffset)); // bottom right - mVariableSystemMatrixEntries.push_back(std::make_pair(matrixNodeIndex(0, 0), matrixNodeIndex(0, 0))); - mVariableSystemMatrixEntries.push_back(std::make_pair(matrixNodeIndex(0, 0) + complexOffset, matrixNodeIndex(0, 0))); - mVariableSystemMatrixEntries.push_back(std::make_pair(matrixNodeIndex(0, 0), matrixNodeIndex(0, 0) + complexOffset)); - mVariableSystemMatrixEntries.push_back(std::make_pair(matrixNodeIndex(0, 0) + complexOffset, matrixNodeIndex(0, 0) + complexOffset)); + mVariableSystemMatrixEntries.push_back(std::make_pair(matrixNodeIndex(0, 0), matrixNodeIndex(0, 0))); + mVariableSystemMatrixEntries.push_back(std::make_pair(matrixNodeIndex(0, 0) + complexOffset, matrixNodeIndex(0, 0))); + mVariableSystemMatrixEntries.push_back(std::make_pair(matrixNodeIndex(0, 0), matrixNodeIndex(0, 0) + complexOffset)); + mVariableSystemMatrixEntries.push_back(std::make_pair(matrixNodeIndex(0, 0) + complexOffset, matrixNodeIndex(0, 0) + complexOffset)); // first off diagonal - mVariableSystemMatrixEntries.push_back(std::make_pair(mVirtualNodes[0]->matrixNodeIndex(), matrixNodeIndex(0, 0))); - mVariableSystemMatrixEntries.push_back(std::make_pair(mVirtualNodes[0]->matrixNodeIndex() + complexOffset, matrixNodeIndex(0, 0))); - mVariableSystemMatrixEntries.push_back(std::make_pair(mVirtualNodes[0]->matrixNodeIndex(), matrixNodeIndex(0, 0) + complexOffset)); - mVariableSystemMatrixEntries.push_back(std::make_pair(mVirtualNodes[0]->matrixNodeIndex() + complexOffset, matrixNodeIndex(0, 0) + complexOffset)); + mVariableSystemMatrixEntries.push_back(std::make_pair(mVirtualNodes[0]->matrixNodeIndex(), matrixNodeIndex(0, 0))); + mVariableSystemMatrixEntries.push_back(std::make_pair(mVirtualNodes[0]->matrixNodeIndex() + complexOffset, matrixNodeIndex(0, 0))); + mVariableSystemMatrixEntries.push_back(std::make_pair(mVirtualNodes[0]->matrixNodeIndex(), matrixNodeIndex(0, 0) + complexOffset)); + mVariableSystemMatrixEntries.push_back(std::make_pair(mVirtualNodes[0]->matrixNodeIndex() + complexOffset, matrixNodeIndex(0, 0) + complexOffset)); // second off diagonal - mVariableSystemMatrixEntries.push_back(std::make_pair(matrixNodeIndex(0, 0), mVirtualNodes[0]->matrixNodeIndex())); - mVariableSystemMatrixEntries.push_back(std::make_pair(matrixNodeIndex(0, 0) + complexOffset, mVirtualNodes[0]->matrixNodeIndex())); - mVariableSystemMatrixEntries.push_back(std::make_pair(matrixNodeIndex(0, 0), mVirtualNodes[0]->matrixNodeIndex() + complexOffset)); - mVariableSystemMatrixEntries.push_back(std::make_pair(matrixNodeIndex(0, 0) + complexOffset, mVirtualNodes[0]->matrixNodeIndex() + complexOffset)); + mVariableSystemMatrixEntries.push_back(std::make_pair(matrixNodeIndex(0, 0), mVirtualNodes[0]->matrixNodeIndex())); + mVariableSystemMatrixEntries.push_back(std::make_pair(matrixNodeIndex(0, 0) + complexOffset, mVirtualNodes[0]->matrixNodeIndex())); + mVariableSystemMatrixEntries.push_back(std::make_pair(matrixNodeIndex(0, 0), mVirtualNodes[0]->matrixNodeIndex() + complexOffset)); + mVariableSystemMatrixEntries.push_back(std::make_pair(matrixNodeIndex(0, 0) + complexOffset, mVirtualNodes[0]->matrixNodeIndex() + complexOffset)); } SPDLOG_LOGGER_INFO(mSLog, "List of index pairs of varying matrix entries: "); @@ -89,11 +94,15 @@ void DP::Ph1::ReducedOrderSynchronGeneratorVBR::mnaCompInitialize(Real omega, SPDLOG_LOGGER_INFO(mSLog, "({}, {})", indexPair.first, indexPair.second); } -void DP::Ph1::ReducedOrderSynchronGeneratorVBR::mnaCompApplySystemMatrixStamp(SparseMatrixRow& systemMatrix) { - if (mModelAsNortonSource) { +void DP::Ph1::ReducedOrderSynchronGeneratorVBR::mnaCompApplySystemMatrixStamp(SparseMatrixRow &systemMatrix) +{ + if (mModelAsNortonSource) + { // Stamp conductance matrix Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 0), matrixNodeIndex(0, 0), mConductanceMatrix); - } else { + } + else + { // Stamp voltage source Math::setMatrixElement(systemMatrix, mVirtualNodes[0]->matrixNodeIndex(), mVirtualNodes[1]->matrixNodeIndex(), Complex(-1, 0)); Math::setMatrixElement(systemMatrix, mVirtualNodes[1]->matrixNodeIndex(), mVirtualNodes[0]->matrixNodeIndex(), Complex(1, 0)); @@ -111,20 +120,25 @@ void DP::Ph1::ReducedOrderSynchronGeneratorVBR::mnaCompApplySystemMatrixStamp(Sp } } -void DP::Ph1::ReducedOrderSynchronGeneratorVBR::mnaCompApplyRightSideVectorStamp(Matrix& rightVector) { - if (mModelAsNortonSource) { +void DP::Ph1::ReducedOrderSynchronGeneratorVBR::mnaCompApplyRightSideVectorStamp(Matrix &rightVector) +{ + if (mModelAsNortonSource) + { // Determine equivalent Norton current - mIvbr = Complex(mConductanceMatrix(0,0) * mEvbr.real() + mConductanceMatrix(0,1) * mEvbr.imag(), - mConductanceMatrix(1,0) * mEvbr.real() + mConductanceMatrix(1,1) * mEvbr.imag()); + mIvbr = Complex(mConductanceMatrix(0, 0) * mEvbr.real() + mConductanceMatrix(0, 1) * mEvbr.imag(), + mConductanceMatrix(1, 0) * mEvbr.real() + mConductanceMatrix(1, 1) * mEvbr.imag()); // Stamp Norton current - Math::setVectorElement(rightVector, matrixNodeIndex(0,0), mIvbr); - } else { + Math::setVectorElement(rightVector, matrixNodeIndex(0, 0), mIvbr); + } + else + { // Stamp history voltage Math::setVectorElement(rightVector, mVirtualNodes[1]->matrixNodeIndex(), mEvbr); } } -void DP::Ph1::ReducedOrderSynchronGeneratorVBR::mnaCompPostStep(const Matrix& leftVector) { +void DP::Ph1::ReducedOrderSynchronGeneratorVBR::mnaCompPostStep(const Matrix &leftVector) +{ // update armature voltage (**mIntfVoltage)(0, 0) = Math::complexFromVectorElement(leftVector, matrixNodeIndex(0, 0)); @@ -132,10 +146,13 @@ void DP::Ph1::ReducedOrderSynchronGeneratorVBR::mnaCompPostStep(const Matrix& le **mVdq = mDomainInterface.applyDPToDQTransform((**mIntfVoltage)(0, 0)) / mBase_V_RMS; // update armature current - if (mModelAsNortonSource) { - (**mIntfCurrent)(0, 0) = mIvbr - Complex(mConductanceMatrix(0,0) * (**mIntfVoltage)(0, 0).real() + mConductanceMatrix(0,1) * (**mIntfVoltage)(0, 0).imag(), - mConductanceMatrix(1,0) * (**mIntfVoltage)(0, 0).real() + mConductanceMatrix(1,1) * (**mIntfVoltage)(0, 0).imag()); - } else { + if (mModelAsNortonSource) + { + (**mIntfCurrent)(0, 0) = mIvbr - Complex(mConductanceMatrix(0, 0) * (**mIntfVoltage)(0, 0).real() + mConductanceMatrix(0, 1) * (**mIntfVoltage)(0, 0).imag(), + mConductanceMatrix(1, 0) * (**mIntfVoltage)(0, 0).real() + mConductanceMatrix(1, 1) * (**mIntfVoltage)(0, 0).imag()); + } + else + { (**mIntfCurrent)(0, 0) = Math::complexFromVectorElement(leftVector, mVirtualNodes[1]->matrixNodeIndex()); } diff --git a/dpsim-models/src/Signal/DroopController.cpp b/dpsim-models/src/Signal/DroopController.cpp new file mode 100644 index 0000000000..fb6c6461e4 --- /dev/null +++ b/dpsim-models/src/Signal/DroopController.cpp @@ -0,0 +1,33 @@ +#include +#include + +using namespace CPS; +using namespace CPS::Signal; + +void DroopController::setParameters(std::shared_ptr parameters) +{ + mParameters = parameters; + SPDLOG_LOGGER_INFO(mSLog, + "\nDroopController Parameters:" + "\n\tM_p = {:e}" + "\n\tTau_p = {:e}" + "\n\tTau_l = {:e}", + mParameters->Mp, + mParameters->Tau_p, mParameters->Tau_l); + mSLog->flush(); +} + +void DroopController::initialize(Real time_step, Real initial_omega) +{ + mTimeStep = time_step; + **mOmega = initial_omega; +} + +Real DroopController::step(const Real mActivePower) +{ + // + **mOmega = **mOmega + mTimeStep / mParameters->Tau_p * + (-**mOmega + mParameters->OmegaNom - mParameters->Mp * (mParameters->Pref - mActivePower)); + + return **mOmega; +} \ No newline at end of file diff --git a/dpsim-models/src/Signal/VSIControlType1.cpp b/dpsim-models/src/Signal/VSIControlType1.cpp index 3db42f5ede..adb97e9b38 100644 --- a/dpsim-models/src/Signal/VSIControlType1.cpp +++ b/dpsim-models/src/Signal/VSIControlType1.cpp @@ -4,117 +4,224 @@ using namespace CPS; using namespace CPS::Signal; -void VSIControlType1::setParameters(std::shared_ptr parameters) { - if (auto params = std::dynamic_pointer_cast(parameters)){ - mParameters = params; - SPDLOG_LOGGER_INFO(mSLog, - "\nVSIController Type1 Parameters: " - "\nKpv: {:e}" - "\nKiv: {:e}" - "\nKpc: {:e}" - "\nKic: {:e}", - mParameters->Kpv, mParameters->Kiv, - mParameters->Kpc, mParameters->Kic); +void VSIControlType1::setParameters(std::shared_ptr parameters) +{ + if (auto params = std::dynamic_pointer_cast(parameters)) + { + mParameters = params; + SPDLOG_LOGGER_INFO(mSLog, + "\nVSIController Type1 Parameters: " + "\nKpv: {:e}" + "\nKiv: {:e}" + "\nKpc: {:e}" + "\nKic: {:e}", + mParameters->Kpv, mParameters->Kiv, + mParameters->Kpc, mParameters->Kic); mSLog->flush(); - } else { + } + else + { std::cout << "Type of parameters class of " << this->name() << " has to be VSIControlType1!" << std::endl; throw CPS::TypeException(); } } -void VSIControlType1::initialize(const Complex& Vsref_dq, const Complex& Vcap_dq, - const Complex& Ifilter_dq, Real time_step, Bool modelAsCurrentSource) { - +void VSIControlType1::initialize(const Complex &Vsref_dq, const Complex &Vcap_dq, + const Complex &Ifilter_dq, Real time_step, Bool modelAsCurrentSource) +{ mTimeStep = time_step; mModelAsCurrentSource = modelAsCurrentSource; + + mVcap_dq = Vcap_dq; + mIfilter_dq = Ifilter_dq; + **mPhi_d = Ifilter_dq.real() / mParameters->Kiv; - **mPhi_q = Ifilter_dq.imag() / mParameters->Kiv; + **mPhi_q = Ifilter_dq.imag() / mParameters->Kiv; **mGamma_d = (Vsref_dq.real() - Vcap_dq.real()) / mParameters->Kic; **mGamma_q = (Vsref_dq.imag() - Vcap_dq.imag()) / mParameters->Kic; SPDLOG_LOGGER_INFO(mSLog, - "\nInitialize controller states:" - "\n\tPhi_d = {}" - "\n\tPhi_q = {}" - "\n\tGamma_d = {}" - "\n\tGamma_q = {}", - **mPhi_d, **mPhi_q, **mGamma_d, **mGamma_q); + "\nInitialize controller states:" + "\n\tPhi_d = {}" + "\n\tPhi_q = {}" + "\n\tGamma_d = {}" + "\n\tGamma_q = {}", + **mPhi_d, **mPhi_q, **mGamma_d, **mGamma_q); mSLog->flush(); **mStateCurr << **mPhi_d, **mPhi_q, **mGamma_d, **mGamma_q; - // initialize state matrix - // [x] = [phid, phiq, gammad, gammaq] + // initialize state matrix + // [x] = [phid, phiq, gammad, gammaq] // [u] = [vdref, vqref, vdc, vqc, idc, idq] // [y] = [vdout, vqout] - mA << - 0, 0, 0, 0, + mA << 0, 0, 0, 0, 0, 0, 0, 0, mParameters->Kiv, 0, 0, 0, 0, mParameters->Kiv, 0, 0; - mB << - 1, 0, -1, 0, 0, 0, + mB << 1, 0, -1, 0, 0, 0, 0, 1, 0, -1, 0, 0, mParameters->Kpv, 0, -mParameters->Kpv, 0, -1, 0, 0, mParameters->Kpv, 0, -mParameters->Kpv, 0, -1; - mC << - mParameters->Kpc * mParameters->Kiv, 0, mParameters->Kic, 0, + mC << mParameters->Kpc * mParameters->Kiv, 0, mParameters->Kic, 0, 0, mParameters->Kpc * mParameters->Kiv, 0, mParameters->Kic; - mD << - mParameters->Kpc * mParameters->Kpv , 0, -mParameters->Kpc * mParameters->Kpv + 1, 0, -mParameters->Kpc, 0, + mD << mParameters->Kpc * mParameters->Kpv, 0, -mParameters->Kpc * mParameters->Kpv + 1, 0, -mParameters->Kpc, 0, 0, mParameters->Kpc * mParameters->Kpv, 0, -mParameters->Kpc * mParameters->Kpv + 1, 0, -mParameters->Kpc; - Math::calculateStateSpaceTrapezoidalMatrices(mA, mB, Matrix::Zero(4,1), mTimeStep, mATrapezoidal, mBTrapezoidal, mCTrapezoidal); + Math::calculateStateSpaceTrapezoidalMatrices(mA, mB, Matrix::Zero(4, 1), mTimeStep, mATrapezoidal, mBTrapezoidal, mCTrapezoidal); **mInputCurr << mParameters->VdRef, mParameters->VqRef, Vcap_dq.real(), Vcap_dq.imag(), Ifilter_dq.real(), Ifilter_dq.imag(); - // Log state-space matrices - SPDLOG_LOGGER_INFO(mSLog, - "\nState space matrices:" - "\nA = \n{}" - "\nB = \n{}" - "\nC = \n{}" - "\nD = \n{}", - mA, mB, mC, mD); - mSLog->flush(); + // Log state-space matrices + SPDLOG_LOGGER_INFO(mSLog, + "\nState space matrices:" + "\nA = \n{}" + "\nB = \n{}" + "\nC = \n{}" + "\nD = \n{}", + mA, mB, mC, mD); + mSLog->flush(); +} + +void VSIControlType1::calculateVBRconstants() +{ + mA_VBR = mParameters->Kpc + mParameters->Kic * mTimeStep / 2.; + mB_VBR = mParameters->Kpv + mParameters->Kiv * mTimeStep / 2.; + mB2_VBR = mParameters->Kpv + mParameters->Kiv * mTimeStep; + mC_VBR = mParameters->Kiv * mTimeStep / 2.; + mD_VBR = mParameters->Kic * mTimeStep / 2.; + mE_VBR = -mA_VBR * mB_VBR + 1.; + + // initialize Iref + mIref_d = mB2_VBR * mParameters->VdRef - mB_VBR * mVcap_dq.real() - mC_VBR * mVcap_dq.real() + **mPhi_d * mParameters->Kiv; + mIref_q = mB2_VBR * mParameters->VqRef - mB_VBR * mVcap_dq.imag() - mC_VBR * mVcap_dq.imag() + **mPhi_q * mParameters->Kiv; + + // calculate Vhist at t=k+1 + Real Vhist_d = -mA_VBR * mC_VBR * mVcap_dq.real() - mD_VBR * mIfilter_dq.real() + mD_VBR * mIref_d + mA_VBR * **mPhi_d * mParameters->Kiv + **mGamma_d * mParameters->Kic + mA_VBR * mB2_VBR * mParameters->VdRef; + Real Vhist_q = -mA_VBR * mC_VBR * mVcap_dq.imag() - mD_VBR * mIfilter_dq.imag() + mD_VBR * mIref_q + mA_VBR * **mPhi_q * mParameters->Kiv + **mGamma_q * mParameters->Kic + mA_VBR * mB2_VBR * mParameters->VqRef; + + // Test + Real Vsource_test_d = mVcap_dq.real() - mA_VBR * mB_VBR * mVcap_dq.real() - mA_VBR * mIfilter_dq.real() + Vhist_d; + Real Vsource_test_q = mVcap_dq.imag() - mA_VBR * mB_VBR * mVcap_dq.imag() - mA_VBR * mIfilter_dq.imag() + Vhist_q; + + // intial reference current + mIfilter_dq = Complex(mIref_d, mIref_q); + + SPDLOG_LOGGER_INFO(mSLog, + "\n--- VBR constants: ---" + "\nA_VBR = {}" + "\nB_VBR = {}" + "\nC_VBR = {}" + "\nD_VBR = {}" + "\nE_VBR = {}" + "\nIref_d = {}" + "\nIref_d = {}" + "\nInit Vhist_d = {}" + "\nInit Vhist_q = {}" + "\nInit Vsource_test_d = {}" + "\nInit Vsource_test_q = {}", + mA_VBR, mB_VBR, mC_VBR, mD_VBR, mE_VBR, + mIref_d, mIref_q, Vhist_d, Vhist_q, + Vsource_test_d, Vsource_test_q); + mSLog->flush(); } -Complex VSIControlType1::step(const Complex& Vcap_dq, const Complex& Ifilter_dq) { - +Complex VSIControlType1::step(const Complex &Vcap_dq, const Complex &Ifilter_dq) +{ // **mStatePrev = **mStateCurr; - // get current inputs + // get current inputs **mInputPrev = **mInputCurr; **mInputCurr << mParameters->VdRef, mParameters->VqRef, Vcap_dq.real(), Vcap_dq.imag(), Ifilter_dq.real(), Ifilter_dq.imag(); - + // calculate new states //**mStateCurr = Math::StateSpaceTrapezoidal(**mStatePrev, mA, mB, mTimeStep, **mInputCurr, **mInputPrev); - **mStateCurr = Math::applyStateSpaceTrapezoidalMatrices(mATrapezoidal, mBTrapezoidal, mCTrapezoidal, **mStatePrev, **mInputCurr, **mInputPrev); + **mStateCurr = Math::applyStateSpaceTrapezoidalMatrices(mATrapezoidal, mBTrapezoidal, mCTrapezoidal, **mStatePrev, **mInputCurr, **mInputPrev); // calculate controller outputs - if (mModelAsCurrentSource) { + if (mModelAsCurrentSource) + { Real error_d = mParameters->VdRef - Vcap_dq.real(); Real error_q = mParameters->VqRef - Vcap_dq.imag(); - (**mOutput)(0,0) = ((**mStateCurr)(0, 0) * mParameters->Kiv + mParameters->Kpv * error_d) * (mTimeStep / mParameters->tau) + (1. - mTimeStep / mParameters->tau) * Ifilter_dq.real(); - (**mOutput)(1,0) = ((**mStateCurr)(1, 0) * mParameters->Kiv + mParameters->Kpv * error_q) * (mTimeStep / mParameters->tau) + (1. - mTimeStep / mParameters->tau) * Ifilter_dq.imag(); - } else { + (**mOutput)(0, 0) = ((**mStateCurr)(0, 0) * mParameters->Kiv + mParameters->Kpv * error_d) * (mTimeStep / mParameters->tau) + (1. - mTimeStep / mParameters->tau) * Ifilter_dq.real(); + (**mOutput)(1, 0) = ((**mStateCurr)(1, 0) * mParameters->Kiv + mParameters->Kpv * error_q) * (mTimeStep / mParameters->tau) + (1. - mTimeStep / mParameters->tau) * Ifilter_dq.imag(); + } + else + { **mOutput = mC * **mStateCurr + mD * **mInputCurr; } - SPDLOG_LOGGER_DEBUG(mSLog, - "\n - InputCurr = \n{}" - "\n - InputPrev = \n{}" - "\n - StatePrev = \n{}" - "\n - StateCurr = \n{}" - "\n - Output values: \n{}", - **mInputCurr, **mInputPrev, **mStatePrev, **mStateCurr, **mOutput); + SPDLOG_LOGGER_DEBUG(mSLog, + "\n - InputCurr = \n{}" + "\n - InputPrev = \n{}" + "\n - StatePrev = \n{}" + "\n - StateCurr = \n{}" + "\n - Output values: \n{}", + **mInputCurr, **mInputPrev, **mStatePrev, **mStateCurr, **mOutput); // - return Complex((**mOutput)(0,0), (**mOutput)(1,0)); + return Complex((**mOutput)(0, 0), (**mOutput)(1, 0)); } +Complex VSIControlType1::stepVBR(const Complex &Vcap_dq, const Complex &Ifilter_dq) +{ + // store previous values (t=k-1) + Complex Vcap_dq_prev = mVcap_dq; + Complex Ifilter_dq_prev = mIfilter_dq; + Real Iref_d_prev = mIref_d; + Real Iref_q_prev = mIref_q; + + // update variables at t=k + mVcap_dq = Vcap_dq; + mIfilter_dq = Ifilter_dq; + + // calculate reference current at time t=k + mIref_d = mB2_VBR * mParameters->VdRef - mB_VBR * mVcap_dq.real() - mC_VBR * Vcap_dq_prev.real() + **mPhi_d * mParameters->Kiv; + mIref_q = mB2_VBR * mParameters->VqRef - mB_VBR * mVcap_dq.imag() - mC_VBR * Vcap_dq_prev.imag() + **mPhi_q * mParameters->Kiv; + + // Update phi at time t=k + **mPhi_d = **mPhi_d + (mTimeStep / 2.) * (2 * mParameters->VdRef - mVcap_dq.real() - Vcap_dq_prev.real()); + **mPhi_q = **mPhi_q + (mTimeStep / 2.) * (2 * mParameters->VqRef - mVcap_dq.imag() - Vcap_dq_prev.imag()); + + // Update lambda at time t=k + **mGamma_d = **mGamma_d + (mTimeStep / 2.) * (mIref_d - mIfilter_dq.real() + Iref_d_prev - Ifilter_dq_prev.real()); + **mGamma_q = **mGamma_q + (mTimeStep / 2.) * (mIref_q - mIfilter_dq.imag() + Iref_q_prev - Ifilter_dq_prev.imag()); + + // calculate Vvbr at t=k+1 + Real Vhist_d = -mA_VBR * mC_VBR * mVcap_dq.real() - mD_VBR * mIfilter_dq.real() + mD_VBR * mIref_d + mA_VBR * **mPhi_d * mParameters->Kiv + **mGamma_d * mParameters->Kic + mA_VBR * mB2_VBR * mParameters->VdRef; + Real Vhist_q = -mA_VBR * mC_VBR * mVcap_dq.imag() - mD_VBR * mIfilter_dq.imag() + mD_VBR * mIref_q + mA_VBR * **mPhi_q * mParameters->Kiv + **mGamma_q * mParameters->Kic + mA_VBR * mB2_VBR * mParameters->VqRef; + + // Test + Real Vsource_test_d = mVcap_dq.real() - mA_VBR * mB_VBR * mVcap_dq.real() - mA_VBR * mIfilter_dq.real() + Vhist_d; + Real Vsource_test_q = mVcap_dq.imag() - mA_VBR * mB_VBR * mVcap_dq.imag() - mA_VBR * mIfilter_dq.imag() + Vhist_q; + // + + SPDLOG_LOGGER_DEBUG(mSLog, + "\n--- Test Step: ---" + "\nmVcap_dq_d = {}" + "\nmVcap_dq_q = {}" + "\nIfilter_dq_d = {}" + "\nIfilter_dq_q = {}" + "\nVsource_test_d = {}" + "\nVsource_test_q = {}" + "\nVhist_d = {}" + "\nVhist_q = {}" + "\nIref_d = {}" + "\nIref_d = {}" + "\nmPhi_d = {}" + "\nmPhi_q = {}" + "\nmGamma_d = {}" + "\nmGamma_q = {}", + mVcap_dq.real(), mVcap_dq.imag(), + Ifilter_dq.real(), Ifilter_dq.imag(), + Vsource_test_d, Vsource_test_q, + Vhist_d, Vhist_q, mIref_d, mIref_q, + **mPhi_d, **mPhi_q, **mGamma_d, **mGamma_q); + + return Complex(Vhist_d, Vhist_q); +} \ No newline at end of file diff --git a/dpsim/src/pybind/DPComponents.cpp b/dpsim/src/pybind/DPComponents.cpp index e51658bb79..2bede1dbb8 100644 --- a/dpsim/src/pybind/DPComponents.cpp +++ b/dpsim/src/pybind/DPComponents.cpp @@ -17,18 +17,18 @@ namespace py = pybind11; using namespace pybind11::literals; -void addDPComponents(py::module_ mDP) { +void addDPComponents(py::module_ mDP) +{ py::class_, CPS::TopologicalNode>(mDP, "SimNode", py::module_local()) - .def(py::init()) + .def(py::init()) .def(py::init()) .def(py::init>()) .def("set_initial_voltage", py::overload_cast(&CPS::DP::SimNode::setInitialVoltage, py::const_)) .def("set_initial_voltage", py::overload_cast(&CPS::DP::SimNode::setInitialVoltage, py::const_)) .def("set_initial_voltage", py::overload_cast(&CPS::DP::SimNode::setInitialVoltage, py::const_)) - .def("single_voltage", &CPS::DP::SimNode::singleVoltage, "phase_type"_a=CPS::PhaseType::Single) + .def("single_voltage", &CPS::DP::SimNode::singleVoltage, "phase_type"_a = CPS::PhaseType::Single) .def_readonly_static("gnd", &CPS::DP::SimNode::GND); - py::module mDPPh1 = mDP.def_submodule("ph1", "single phase dynamic phasor models"); addDPPh1Components(mDPPh1); @@ -36,106 +36,107 @@ void addDPComponents(py::module_ mDP) { addDPPh3Components(mDPPh3); } -void addDPPh1Components(py::module_ mDPPh1) { +void addDPPh1Components(py::module_ mDPPh1) +{ py::class_, CPS::SimPowerComp>(mDPPh1, "VoltageSource", py::multiple_inheritance()) - .def(py::init()) + .def(py::init()) .def(py::init()) - .def("set_parameters", py::overload_cast(&CPS::DP::Ph1::VoltageSource::setParameters), "V_ref"_a, "f_src"_a=0) + .def("set_parameters", py::overload_cast(&CPS::DP::Ph1::VoltageSource::setParameters), "V_ref"_a, "f_src"_a = 0) .def("connect", &CPS::DP::Ph1::VoltageSource::connect) .def_property("V_ref", createAttributeGetter("V_ref"), createAttributeSetter("V_ref")) .def_property("f_src", createAttributeGetter("f_src"), createAttributeSetter("f_src")); py::class_, CPS::SimPowerComp>(mDPPh1, "VoltageSourceNorton", py::multiple_inheritance()) - .def(py::init()) + .def(py::init()) .def(py::init()) - .def("set_parameters", py::overload_cast(&CPS::DP::Ph1::VoltageSourceNorton::setParameters), "V_ref"_a, "f_src"_a=-1) + .def("set_parameters", py::overload_cast(&CPS::DP::Ph1::VoltageSourceNorton::setParameters), "V_ref"_a, "f_src"_a = -1) .def("connect", &CPS::DP::Ph1::VoltageSourceNorton::connect); py::class_, CPS::SimPowerComp>(mDPPh1, "CurrentSource", py::multiple_inheritance()) - .def(py::init()) + .def(py::init()) .def(py::init()) - .def("set_parameters", &CPS::DP::Ph1::CurrentSource::setParameters, "I_ref"_a) + .def("set_parameters", &CPS::DP::Ph1::CurrentSource::setParameters, "I_ref"_a) .def("connect", &CPS::DP::Ph1::CurrentSource::connect) .def_property("I_ref", createAttributeGetter("I_ref"), createAttributeSetter("I_ref")); py::class_, CPS::SimPowerComp>(mDPPh1, "Resistor", py::multiple_inheritance()) - .def(py::init()) + .def(py::init()) .def(py::init()) - .def("set_parameters", &CPS::DP::Ph1::Resistor::setParameters, "R"_a) + .def("set_parameters", &CPS::DP::Ph1::Resistor::setParameters, "R"_a) .def("connect", &CPS::DP::Ph1::Resistor::connect) .def_property("R", createAttributeGetter("R"), createAttributeSetter("R")); py::class_, CPS::SimPowerComp>(mDPPh1, "Capacitor", py::multiple_inheritance()) - .def(py::init()) + .def(py::init()) .def(py::init()) - .def("set_parameters", &CPS::DP::Ph1::Capacitor::setParameters, "C"_a) + .def("set_parameters", &CPS::DP::Ph1::Capacitor::setParameters, "C"_a) .def("connect", &CPS::DP::Ph1::Capacitor::connect) .def_property("C", createAttributeGetter("C"), createAttributeSetter("C")); py::class_, CPS::SimPowerComp>(mDPPh1, "Inductor", py::multiple_inheritance()) - .def(py::init()) + .def(py::init()) .def(py::init()) - .def("set_parameters", &CPS::DP::Ph1::Inductor::setParameters, "L"_a) + .def("set_parameters", &CPS::DP::Ph1::Inductor::setParameters, "L"_a) .def("connect", &CPS::DP::Ph1::Inductor::connect) .def_property("L", createAttributeGetter("L"), createAttributeSetter("L")); py::class_, CPS::SimPowerComp>(mDPPh1, "ResInductor", py::multiple_inheritance()) - .def(py::init()) + .def(py::init()) .def(py::init()) - .def("set_parameters", &CPS::DP::Ph1::ResIndSeries::setParameters, "R"_a, "L"_a) + .def("set_parameters", &CPS::DP::Ph1::ResIndSeries::setParameters, "R"_a, "L"_a) .def("connect", &CPS::DP::Ph1::ResIndSeries::connect); py::class_, CPS::SimPowerComp>(mDPPh1, "NetworkInjection", py::multiple_inheritance()) - .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) + .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) .def("set_parameters", py::overload_cast(&CPS::DP::Ph1::NetworkInjection::setParameters), "V_ref"_a, "f_src"_a = 0) .def("connect", &CPS::DP::Ph1::NetworkInjection::connect); py::class_, CPS::SimPowerComp>(mDPPh1, "PiLine", py::multiple_inheritance()) - .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) - .def("set_parameters", &CPS::DP::Ph1::PiLine::setParameters, "series_resistance"_a, "series_inductance"_a, "parallel_capacitance"_a=0, "parallel_conductance"_a=0) + .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) + .def("set_parameters", &CPS::DP::Ph1::PiLine::setParameters, "series_resistance"_a, "series_inductance"_a, "parallel_capacitance"_a = 0, "parallel_conductance"_a = 0) .def("connect", &CPS::DP::Ph1::PiLine::connect); py::class_, CPS::SimPowerComp>(mDPPh1, "RXLoad", py::multiple_inheritance()) - .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) + .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) .def("set_parameters", py::overload_cast(&CPS::DP::Ph1::RXLoad::setParameters), "active_power"_a, "reactive_power"_a) - .def("set_parameters", py::overload_cast(&CPS::DP::Ph1::RXLoad::setParameters), "active_power"_a, "reactive_power"_a, "nominal_voltage"_a) + .def("set_parameters", py::overload_cast(&CPS::DP::Ph1::RXLoad::setParameters), "active_power"_a, "reactive_power"_a, "nominal_voltage"_a) .def("connect", &CPS::DP::Ph1::RXLoad::connect); py::class_, CPS::SimPowerComp, CPS::Base::Ph1::Switch>(mDPPh1, "Switch", py::multiple_inheritance()) - .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) - .def("set_parameters", &CPS::DP::Ph1::Switch::setParameters, "open_resistance"_a, "closed_resistance"_a, "closed"_a = false) // cppcheck-suppress assignBoolToPointer + .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) + .def("set_parameters", &CPS::DP::Ph1::Switch::setParameters, "open_resistance"_a, "closed_resistance"_a, "closed"_a = false) // cppcheck-suppress assignBoolToPointer .def("open", &CPS::DP::Ph1::Switch::open) .def("close", &CPS::DP::Ph1::Switch::close) .def("connect", &CPS::DP::Ph1::Switch::connect); py::class_, CPS::SimPowerComp, CPS::Base::Ph1::Switch>(mDPPh1, "varResSwitch", py::multiple_inheritance()) - .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) - .def("set_parameters", &CPS::DP::Ph1::varResSwitch::setParameters, "open_resistance"_a, "closed_resistance"_a, "closed"_a = false) // cppcheck-suppress assignBoolToPointer + .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) + .def("set_parameters", &CPS::DP::Ph1::varResSwitch::setParameters, "open_resistance"_a, "closed_resistance"_a, "closed"_a = false) // cppcheck-suppress assignBoolToPointer .def("open", &CPS::DP::Ph1::varResSwitch::open) .def("close", &CPS::DP::Ph1::varResSwitch::close) .def("set_init_parameters", &CPS::DP::Ph1::varResSwitch::setInitParameters, "time_step"_a) .def("connect", &CPS::DP::Ph1::varResSwitch::connect); py::class_, CPS::SimPowerComp>(mDPPh1, "SynchronGeneratorTrStab", py::multiple_inheritance()) - .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) + .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) .def("set_standard_parameters_PU", &CPS::DP::Ph1::SynchronGeneratorTrStab::setStandardParametersPU, - "nom_power"_a, "nom_volt"_a, "nom_freq"_a, "Xpd"_a, "inertia"_a, "Rs"_a=0, "D"_a=0) + "nom_power"_a, "nom_volt"_a, "nom_freq"_a, "Xpd"_a, "inertia"_a, "Rs"_a = 0, "D"_a = 0) .def("set_fundamental_parameters_PU", &CPS::DP::Ph1::SynchronGeneratorTrStab::setFundamentalParametersPU, - "nom_power"_a, "nom_volt"_a, "nom_freq"_a, "Ll"_a, "Lmd"_a, "Llfd"_a, "H"_a, "D"_a = 0) + "nom_power"_a, "nom_volt"_a, "nom_freq"_a, "Ll"_a, "Lmd"_a, "Llfd"_a, "H"_a, "D"_a = 0) .def("set_initial_values", &CPS::DP::Ph1::SynchronGeneratorTrStab::setInitialValues, "elec_power"_a, "mech_power"_a) .def("connect", &CPS::DP::Ph1::SynchronGeneratorTrStab::connect) .def("set_model_flags", &CPS::DP::Ph1::SynchronGeneratorTrStab::setModelFlags, "convert_with_omega_mech"_a) - .def("set_reference_omega", [](CPS::DP::Ph1::SynchronGeneratorTrStab &gen, std::string refOmegaName, CPS::IdentifiedObject::Ptr refOmegaComp, - std::string refDeltaName, CPS::IdentifiedObject::Ptr refDeltaComp) { - gen.setReferenceOmega(refOmegaComp->attributeTyped(refOmegaName), refDeltaComp->attributeTyped(refDeltaName)); - }, "ref_omega_name"_a="w_r", "ref_omage_comp"_a, "ref_delta_name"_a="delta_r", "ref_delta_comp"_a); + .def( + "set_reference_omega", [](CPS::DP::Ph1::SynchronGeneratorTrStab &gen, std::string refOmegaName, CPS::IdentifiedObject::Ptr refOmegaComp, std::string refDeltaName, CPS::IdentifiedObject::Ptr refDeltaComp) + { gen.setReferenceOmega(refOmegaComp->attributeTyped(refOmegaName), refDeltaComp->attributeTyped(refDeltaName)); }, + "ref_omega_name"_a = "w_r", "ref_omage_comp"_a, "ref_delta_name"_a = "delta_r", "ref_delta_comp"_a); py::class_, CPS::Base::ReducedOrderSynchronGenerator>(mDPPh1, "ReducedOrderSynchronGeneratorVBR", py::multiple_inheritance()); py::class_, CPS::DP::Ph1::ReducedOrderSynchronGeneratorVBR>(mDPPh1, "SynchronGenerator3OrderVBR", py::multiple_inheritance()) .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) .def("set_operational_parameters_per_unit", py::overload_cast(&CPS::DP::Ph1::SynchronGenerator3OrderVBR::setOperationalParametersPerUnit), "nom_power"_a, "nom_voltage"_a, "nom_frequency"_a, "H"_a, "Ld"_a, "Lq"_a, "L0"_a, "Ld_t"_a, "Td0_t"_a); - + py::class_, CPS::DP::Ph1::ReducedOrderSynchronGeneratorVBR>(mDPPh1, "SynchronGenerator4OrderVBR", py::multiple_inheritance()) .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) .def("set_operational_parameters_per_unit", py::overload_cast(&CPS::DP::Ph1::SynchronGenerator4OrderVBR::setOperationalParametersPerUnit), "nom_power"_a, "nom_voltage"_a, "nom_frequency"_a, "H"_a, "Ld"_a, "Lq"_a, "L0"_a, "Ld_t"_a, "Lq_t"_a, "Td0_t"_a, "Tq0_t"_a); @@ -150,7 +151,7 @@ void addDPPh1Components(py::module_ mDPPh1) { py::class_, CPS::DP::Ph1::ReducedOrderSynchronGeneratorVBR>(mDPPh1, "SynchronGenerator6bOrderVBR", py::multiple_inheritance()) .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) - .def("set_operational_parameters_per_unit", py::overload_cast(&CPS::DP::Ph1::SynchronGenerator6bOrderVBR::setOperationalParametersPerUnit), "nom_power"_a, "nom_voltage"_a, "nom_frequency"_a, "H"_a, "Ld"_a, "Lq"_a, "L0"_a, "Ld_t"_a, "Lq_t"_a, "Td0_t"_a, "Tq0_t"_a, "Ld_s"_a, "Lq_s"_a, "Td0_s"_a, "Tq0_s"_a, "Taa"_a=0); + .def("set_operational_parameters_per_unit", py::overload_cast(&CPS::DP::Ph1::SynchronGenerator6bOrderVBR::setOperationalParametersPerUnit), "nom_power"_a, "nom_voltage"_a, "nom_frequency"_a, "H"_a, "Ld"_a, "Lq"_a, "L0"_a, "Ld_t"_a, "Lq_t"_a, "Td0_t"_a, "Tq0_t"_a, "Ld_s"_a, "Lq_s"_a, "Td0_s"_a, "Tq0_s"_a, "Taa"_a = 0); py::class_, CPS::Base::ReducedOrderSynchronGenerator, CPS::MNASyncGenInterface>(mDPPh1, "SynchronGenerator4OrderTPM", py::multiple_inheritance()) .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) @@ -163,73 +164,79 @@ void addDPPh1Components(py::module_ mDPPh1) { py::class_, CPS::Base::ReducedOrderSynchronGenerator, CPS::MNASyncGenInterface>(mDPPh1, "SynchronGenerator6OrderPCM", py::multiple_inheritance()) .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) - .def("set_operational_parameters_per_unit", py::overload_cast(&CPS::DP::Ph1::SynchronGenerator6OrderPCM::setOperationalParametersPerUnit), "nom_power"_a, "nom_voltage"_a, "nom_frequency"_a, "H"_a, "Ld"_a, "Lq"_a, "L0"_a, "Ld_t"_a, "Lq_t"_a, "Td0_t"_a, "Tq0_t"_a, "Ld_s"_a, "Lq_s"_a, "Td0_s"_a, "Tq0_s"_a, "Taa"_a=0) + .def("set_operational_parameters_per_unit", py::overload_cast(&CPS::DP::Ph1::SynchronGenerator6OrderPCM::setOperationalParametersPerUnit), "nom_power"_a, "nom_voltage"_a, "nom_frequency"_a, "H"_a, "Ld"_a, "Lq"_a, "L0"_a, "Ld_t"_a, "Lq_t"_a, "Td0_t"_a, "Tq0_t"_a, "Ld_s"_a, "Lq_s"_a, "Td0_s"_a, "Tq0_s"_a, "Taa"_a = 0) .def("connect", &CPS::DP::Ph1::SynchronGenerator6OrderPCM::connect); py::class_, CPS::SimPowerComp>(mDPPh1, "AvVoltageSourceInverterDQ", py::multiple_inheritance()) - .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) + .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) .def(py::init(), "uid"_a, "name"_a, "loglevel"_a = CPS::Logger::Level::off, "with_trafo"_a = false) // cppcheck-suppress assignBoolToPointer .def("set_parameters", &CPS::DP::Ph1::AvVoltageSourceInverterDQ::setParameters, "sys_omega"_a, "sys_volt_nom"_a, "p_ref"_a, "q_ref"_a) .def("set_filter_parameters", &CPS::DP::Ph1::AvVoltageSourceInverterDQ::setFilterParameters, "Lf"_a, "Cf"_a, "Rf"_a, "Rc"_a) .def("set_controller_parameters", &CPS::DP::Ph1::AvVoltageSourceInverterDQ::setControllerParameters, - "Kp_pll"_a, "Ki_pll"_a, "Kp_power_ctrl"_a, "Ki_power_ctrl"_a, "Kp_curr_ctrl"_a, "Ki_curr_ctrl"_a, "omega_cutoff"_a) + "Kp_pll"_a, "Ki_pll"_a, "Kp_power_ctrl"_a, "Ki_power_ctrl"_a, "Kp_curr_ctrl"_a, "Ki_curr_ctrl"_a, "omega_cutoff"_a) .def("set_transformer_parameters", &CPS::DP::Ph1::AvVoltageSourceInverterDQ::setTransformerParameters, - "nom_voltage_end_1"_a, "nom_voltage_end_2"_a, "rated_power"_a, "ratio_abs"_a, "ratio_phase"_a, "resistance"_a, "inductance"_a) + "nom_voltage_end_1"_a, "nom_voltage_end_2"_a, "rated_power"_a, "ratio_abs"_a, "ratio_phase"_a, "resistance"_a, "inductance"_a) .def("set_initial_state_values", &CPS::DP::Ph1::AvVoltageSourceInverterDQ::setInitialStateValues, - "p_init"_a, "q_init"_a, "phi_d_init"_a, "phi_q_init"_a, "gamma_d_init"_a, "gamma_q_init"_a) + "p_init"_a, "q_init"_a, "phi_d_init"_a, "phi_q_init"_a, "gamma_d_init"_a, "gamma_q_init"_a) .def("with_control", &CPS::DP::Ph1::AvVoltageSourceInverterDQ::withControl) .def("connect", &CPS::DP::Ph1::AvVoltageSourceInverterDQ::connect); py::class_, CPS::SimPowerComp, CPS::Base::VSIVoltageSourceInverterDQ>(mDPPh1, "VSIVoltageControlDQ", py::multiple_inheritance()) - .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) - .def(py::init(), "uid"_a, "name"_a, "loglevel"_a = CPS::Logger::Level::off, "model_as_current_source"_a=false, "with_interface_resistor"_a=false) // cppcheck-suppress assignBoolToPointer + .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) + .def(py::init(), "uid"_a, "name"_a, "loglevel"_a = CPS::Logger::Level::off, "model_as_current_source"_a = false, "with_interface_resistor"_a = false) // cppcheck-suppress assignBoolToPointer .def("connect", &CPS::DP::Ph1::VSIVoltageControlDQ::connect); + py::class_, CPS::SimPowerComp, CPS::Base::VSIVoltageSourceInverterDQ>(mDPPh1, "VSIVoltageControlVBR", py::multiple_inheritance()) + .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) + .def(py::init(), "uid"_a, "name"_a, "loglevel"_a = CPS::Logger::Level::off, "model_as_current_source"_a = false) // cppcheck-suppress assignBoolToPointer + .def("connect", &CPS::DP::Ph1::VSIVoltageControlVBR::connect); + py::class_, CPS::SimPowerComp>(mDPPh1, "Inverter", py::multiple_inheritance()) - .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) + .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) .def("set_parameters", &CPS::DP::Ph1::Inverter::setParameters, "carrier_harms"_a, "modul_harms"_a, "input_voltage"_a, "ratio"_a, "phase"_a) .def("connect", &CPS::DP::Ph1::Inverter::connect); py::class_, CPS::SimPowerComp>(mDPPh1, "Transformer", py::multiple_inheritance()) - .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) + .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) .def(py::init(), "uid"_a, "name"_a, "loglevel"_a = CPS::Logger::Level::off) // cppcheck-suppress assignBoolToPointer .def("set_parameters", py::overload_cast(&CPS::DP::Ph1::Transformer::setParameters), "nom_voltage_end_1"_a, "nom_voltage_end_2"_a, "ratio_abs"_a, "ratio_phase"_a, "resistance"_a, "inductance"_a) .def("connect", &CPS::DP::Ph1::Transformer::connect); } -void addDPPh3Components(py::module_ mDPPh3) { +void addDPPh3Components(py::module_ mDPPh3) +{ - #ifdef WITH_SUNDIALS +#ifdef WITH_SUNDIALS py::class_, CPS::SimPowerComp>(mDPPh3, "SynchronGeneratorDQODE", py::multiple_inheritance()) - .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) + .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) .def("set_parameters_fundamental_per_unit", &CPS::DP::Ph3::SynchronGeneratorDQODE::setParametersFundamentalPerUnit, - "nom_power"_a, "nom_volt"_a, "nom_freq"_a, "pole_number"_a, "nom_field_cur"_a, - "Rs"_a, "Ll"_a, "Lmd"_a, "Lmq"_a, "Rfd"_a, "Llfd"_a, "Rkd"_a, "Llkd"_a, - "Rkq1"_a, "Llkq1"_a, "Rkq2"_a, "Llkq2"_a, "inertia"_a, "init_active_power"_a, - "init_reactive_power"_a, "init_terminal_volt"_a, "init_volt_angle"_a, "init_mech_power"_a) + "nom_power"_a, "nom_volt"_a, "nom_freq"_a, "pole_number"_a, "nom_field_cur"_a, + "Rs"_a, "Ll"_a, "Lmd"_a, "Lmq"_a, "Rfd"_a, "Llfd"_a, "Rkd"_a, "Llkd"_a, + "Rkq1"_a, "Llkq1"_a, "Rkq2"_a, "Llkq2"_a, "inertia"_a, "init_active_power"_a, + "init_reactive_power"_a, "init_terminal_volt"_a, "init_volt_angle"_a, "init_mech_power"_a) .def("connect", &CPS::DP::Ph3::SynchronGeneratorDQODE::connect); - #endif +#endif py::class_, CPS::SimPowerComp>(mDPPh3, "SynchronGeneratorDQTrapez", py::multiple_inheritance()) - .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) + .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) .def("set_parameters_fundamental_per_unit", &CPS::DP::Ph3::SynchronGeneratorDQTrapez::setParametersFundamentalPerUnit, - "nom_power"_a, "nom_volt"_a, "nom_freq"_a, "pole_number"_a, "nom_field_cur"_a, - "Rs"_a, "Ll"_a, "Lmd"_a, "Lmq"_a, "Rfd"_a, "Llfd"_a, "Rkd"_a, "Llkd"_a, - "Rkq1"_a, "Llkq1"_a, "Rkq2"_a, "Llkq2"_a, "inertia"_a, "init_active_power"_a, - "init_reactive_power"_a, "init_terminal_volt"_a, "init_volt_angle"_a, "init_mech_power"_a) + "nom_power"_a, "nom_volt"_a, "nom_freq"_a, "pole_number"_a, "nom_field_cur"_a, + "Rs"_a, "Ll"_a, "Lmd"_a, "Lmq"_a, "Rfd"_a, "Llfd"_a, "Rkd"_a, "Llkd"_a, + "Rkq1"_a, "Llkq1"_a, "Rkq2"_a, "Llkq2"_a, "inertia"_a, "init_active_power"_a, + "init_reactive_power"_a, "init_terminal_volt"_a, "init_volt_angle"_a, "init_mech_power"_a) .def("connect", &CPS::DP::Ph3::SynchronGeneratorDQTrapez::connect); py::class_, CPS::SimPowerComp>(mDPPh3, "SeriesResistor", py::multiple_inheritance()) - .def(py::init()) + .def(py::init()) .def(py::init()) - .def("set_parameters", &CPS::DP::Ph3::SeriesResistor::setParameters, "R"_a) + .def("set_parameters", &CPS::DP::Ph3::SeriesResistor::setParameters, "R"_a) .def("connect", &CPS::DP::Ph3::SeriesResistor::connect); py::class_, CPS::SimPowerComp, CPS::Base::Ph1::Switch>(mDPPh3, "SeriesSwitch", py::multiple_inheritance()) - .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) - .def("set_parameters", &CPS::DP::Ph3::SeriesSwitch::setParameters, "open_resistance"_a, "closed_resistance"_a, "closed"_a = false) // cppcheck-suppress assignBoolToPointer + .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) + .def("set_parameters", &CPS::DP::Ph3::SeriesSwitch::setParameters, "open_resistance"_a, "closed_resistance"_a, "closed"_a = false) // cppcheck-suppress assignBoolToPointer .def("open", &CPS::DP::Ph3::SeriesSwitch::open) .def("close", &CPS::DP::Ph3::SeriesSwitch::close) .def("connect", &CPS::DP::Ph3::SeriesSwitch::connect); diff --git a/dpsim/src/pybind/EMTComponents.cpp b/dpsim/src/pybind/EMTComponents.cpp index d5ed80f7f1..377ebfe365 100644 --- a/dpsim/src/pybind/EMTComponents.cpp +++ b/dpsim/src/pybind/EMTComponents.cpp @@ -17,9 +17,10 @@ namespace py = pybind11; using namespace pybind11::literals; -void addEMTComponents(py::module_ mEMT) { +void addEMTComponents(py::module_ mEMT) +{ py::class_, CPS::TopologicalNode>(mEMT, "SimNode", py::module_local()) - .def(py::init()) + .def(py::init()) .def(py::init()) .def(py::init>()) .def("set_initial_voltage", py::overload_cast(&CPS::EMT::SimNode::setInitialVoltage, py::const_)) @@ -33,120 +34,121 @@ void addEMTComponents(py::module_ mEMT) { addEMTPh3Components(mEMTPh3); } -void addEMTPh1Components(py::module_ mEMTPh1) { +void addEMTPh1Components(py::module_ mEMTPh1) +{ py::class_, CPS::SimPowerComp>(mEMTPh1, "CurrentSource", py::multiple_inheritance()) - .def(py::init()) + .def(py::init()) .def(py::init()) - .def("set_parameters", &CPS::EMT::Ph1::CurrentSource::setParameters, "I_ref"_a, "f_src"_a = -1) + .def("set_parameters", &CPS::EMT::Ph1::CurrentSource::setParameters, "I_ref"_a, "f_src"_a = -1) .def("connect", &CPS::EMT::Ph1::CurrentSource::connect) .def_property("I_ref", createAttributeGetter("I_ref"), createAttributeSetter("I_ref")) .def_property("f_src", createAttributeGetter("f_src"), createAttributeSetter("f_src")); py::class_, CPS::SimPowerComp>(mEMTPh1, "VoltageSource", py::multiple_inheritance()) - .def(py::init()) + .def(py::init()) .def(py::init()) - .def("set_parameters", &CPS::EMT::Ph1::VoltageSource::setParameters, "V_ref"_a, "f_src"_a = -1) + .def("set_parameters", &CPS::EMT::Ph1::VoltageSource::setParameters, "V_ref"_a, "f_src"_a = -1) .def("connect", &CPS::EMT::Ph1::VoltageSource::connect) .def_property("V_ref", createAttributeGetter("V_ref"), createAttributeSetter("V_ref")) .def_property("f_src", createAttributeGetter("f_src"), createAttributeSetter("f_src")); py::class_, CPS::SimPowerComp>(mEMTPh1, "Resistor", py::multiple_inheritance()) - .def(py::init()) + .def(py::init()) .def(py::init()) - .def("set_parameters", &CPS::EMT::Ph1::Resistor::setParameters, "R"_a) + .def("set_parameters", &CPS::EMT::Ph1::Resistor::setParameters, "R"_a) .def("connect", &CPS::EMT::Ph1::Resistor::connect) .def_property("R", createAttributeGetter("R"), createAttributeSetter("R")); py::class_, CPS::SimPowerComp>(mEMTPh1, "Capacitor", py::multiple_inheritance()) - .def(py::init()) + .def(py::init()) .def(py::init()) - .def("set_parameters", &CPS::EMT::Ph1::Capacitor::setParameters, "C"_a) + .def("set_parameters", &CPS::EMT::Ph1::Capacitor::setParameters, "C"_a) .def("connect", &CPS::EMT::Ph1::Capacitor::connect) .def_property("C", createAttributeGetter("C"), createAttributeSetter("C")); py::class_, CPS::SimPowerComp>(mEMTPh1, "Inductor", py::multiple_inheritance()) - .def(py::init()) + .def(py::init()) .def(py::init()) - .def("set_parameters", &CPS::EMT::Ph1::Inductor::setParameters, "L"_a) + .def("set_parameters", &CPS::EMT::Ph1::Inductor::setParameters, "L"_a) .def("connect", &CPS::EMT::Ph1::Inductor::connect) .def_property("L", createAttributeGetter("L"), createAttributeSetter("L")); - } -void addEMTPh3Components(py::module_ mEMTPh3) { +void addEMTPh3Components(py::module_ mEMTPh3) +{ py::class_, CPS::SimPowerComp>(mEMTPh3, "VoltageSource", py::multiple_inheritance()) - .def(py::init()) + .def(py::init()) .def(py::init()) - .def("set_parameters", py::overload_cast(&CPS::EMT::Ph3::VoltageSource::setParameters), "V_ref"_a, "f_src"_a = 50) + .def("set_parameters", py::overload_cast(&CPS::EMT::Ph3::VoltageSource::setParameters), "V_ref"_a, "f_src"_a = 50) .def("connect", &CPS::EMT::Ph3::VoltageSource::connect) .def_property("V_ref", createAttributeGetter("V_ref"), createAttributeSetter("V_ref")) .def_property("f_src", createAttributeGetter("f_src"), createAttributeSetter("f_src")); py::class_, CPS::SimPowerComp>(mEMTPh3, "Resistor", py::multiple_inheritance()) - .def(py::init()) + .def(py::init()) .def(py::init()) - .def("set_parameters", &CPS::EMT::Ph3::Resistor::setParameters, "R"_a) - .def("connect", &CPS::EMT::Ph3::Resistor::connect);; + .def("set_parameters", &CPS::EMT::Ph3::Resistor::setParameters, "R"_a) + .def("connect", &CPS::EMT::Ph3::Resistor::connect); + ; py::class_, CPS::SimPowerComp>(mEMTPh3, "Capacitor", py::multiple_inheritance()) - .def(py::init()) + .def(py::init()) .def(py::init()) - .def("set_parameters", &CPS::EMT::Ph3::Capacitor::setParameters, "C"_a) + .def("set_parameters", &CPS::EMT::Ph3::Capacitor::setParameters, "C"_a) .def("connect", &CPS::EMT::Ph3::Capacitor::connect); py::class_, CPS::SimPowerComp>(mEMTPh3, "Inductor", py::multiple_inheritance()) - .def(py::init()) + .def(py::init()) .def(py::init()) - .def("set_parameters", &CPS::EMT::Ph3::Inductor::setParameters, "L"_a) + .def("set_parameters", &CPS::EMT::Ph3::Inductor::setParameters, "L"_a) .def("connect", &CPS::EMT::Ph3::Inductor::connect); py::class_, CPS::SimPowerComp>(mEMTPh3, "ResInductor", py::multiple_inheritance()) - .def(py::init()) + .def(py::init()) .def(py::init()) - .def("set_parameters", &CPS::EMT::Ph3::ResIndSeries::setParameters, "R"_a, "L"_a) + .def("set_parameters", &CPS::EMT::Ph3::ResIndSeries::setParameters, "R"_a, "L"_a) .def("connect", &CPS::EMT::Ph3::ResIndSeries::connect); py::class_, CPS::SimPowerComp>(mEMTPh3, "NetworkInjection", py::multiple_inheritance()) - .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) - .def("set_parameters", py::overload_cast(&CPS::EMT::Ph3::NetworkInjection::setParameters), "V_ref"_a, "f_src"_a=50) + .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) + .def("set_parameters", py::overload_cast(&CPS::EMT::Ph3::NetworkInjection::setParameters), "V_ref"_a, "f_src"_a = 50) .def("connect", &CPS::EMT::Ph3::NetworkInjection::connect); py::class_, CPS::SimPowerComp>(mEMTPh3, "PiLine", py::multiple_inheritance()) - .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) - .def("set_symmetric_parameters", py::overload_cast(&CPS::EMT::Ph3::PiLine::setParameters), "series_resistance"_a, "series_inductance"_a, "parallel_capacitance"_a=0.0, "parallel_conductance"_a=0.0) - .def("set_parameters", py::overload_cast(&CPS::EMT::Ph3::PiLine::setParameters), "series_resistance"_a, "series_inductance"_a, "parallel_capacitance"_a=zeroMatrix(3), "parallel_conductance"_a=zeroMatrix(3)) + .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) + .def("set_symmetric_parameters", py::overload_cast(&CPS::EMT::Ph3::PiLine::setParameters), "series_resistance"_a, "series_inductance"_a, "parallel_capacitance"_a = 0.0, "parallel_conductance"_a = 0.0) + .def("set_parameters", py::overload_cast(&CPS::EMT::Ph3::PiLine::setParameters), "series_resistance"_a, "series_inductance"_a, "parallel_capacitance"_a = zeroMatrix(3), "parallel_conductance"_a = zeroMatrix(3)) .def("connect", &CPS::EMT::Ph3::PiLine::connect); py::class_, CPS::SimPowerComp>(mEMTPh3, "RXLoad", py::multiple_inheritance()) - .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) + .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) .def("set_parameters", py::overload_cast(&CPS::EMT::Ph3::RXLoad::setParameters), "active_power"_a, "reactive_power"_a) .def("set_parameters", py::overload_cast(&CPS::EMT::Ph3::RXLoad::setParameters), "active_power"_a, "reactive_power"_a) - .def("set_parameters", py::overload_cast(&CPS::EMT::Ph3::RXLoad::setParameters), "active_power"_a, "reactive_power"_a, "volt"_a) + .def("set_parameters", py::overload_cast(&CPS::EMT::Ph3::RXLoad::setParameters), "active_power"_a, "reactive_power"_a, "volt"_a) .def("set_parameters", py::overload_cast(&CPS::EMT::Ph3::RXLoad::setParameters), "active_power"_a, "reactive_power"_a, "volt"_a) .def("connect", &CPS::EMT::Ph3::RXLoad::connect); py::class_, CPS::SimPowerComp, CPS::Base::Ph3::Switch>(mEMTPh3, "Switch", py::multiple_inheritance()) - .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) - .def("set_parameters", &CPS::EMT::Ph3::Switch::setParameters, "open_resistance"_a, "closed_resistance"_a, "closed"_a = false) // cppcheck-suppress assignBoolToPointer + .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) + .def("set_parameters", &CPS::EMT::Ph3::Switch::setParameters, "open_resistance"_a, "closed_resistance"_a, "closed"_a = false) // cppcheck-suppress assignBoolToPointer .def("open", &CPS::EMT::Ph3::Switch::openSwitch) .def("close", &CPS::EMT::Ph3::Switch::closeSwitch) .def("connect", &CPS::EMT::Ph3::Switch::connect); py::class_, CPS::SimPowerComp>(mEMTPh3, "SynchronGeneratorDQTrapez", py::multiple_inheritance()) - .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) + .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) .def("set_parameters_operational_per_unit", &CPS::EMT::Ph3::SynchronGeneratorDQTrapez::setParametersOperationalPerUnit, - "nom_power"_a, "nom_volt"_a, "nom_freq"_a, "pole_number"_a, "nom_field_cur"_a, "Rs"_a, "Ld"_a, "Lq"_a, "Ld_t"_a, "Lq_t"_a, "Ld_s"_a, - "Lq_s"_a, "Ll"_a, "Td0_t"_a, "Tq0_t"_a, "Td0_s"_a, "Tq0_s"_a, "inertia"_a) + "nom_power"_a, "nom_volt"_a, "nom_freq"_a, "pole_number"_a, "nom_field_cur"_a, "Rs"_a, "Ld"_a, "Lq"_a, "Ld_t"_a, "Lq_t"_a, "Ld_s"_a, + "Lq_s"_a, "Ll"_a, "Td0_t"_a, "Tq0_t"_a, "Td0_s"_a, "Tq0_s"_a, "inertia"_a) .def("set_parameters_fundamental_per_unit", &CPS::EMT::Ph3::SynchronGeneratorDQTrapez::setParametersFundamentalPerUnit, - "nom_power"_a, "nom_volt"_a, "nom_freq"_a, "pole_number"_a, "nom_field_cur"_a, "Rs"_a, "Ll"_a, "Lmd"_a, "Lmq"_a, "Rfd"_a, "Llfd"_a, - "Rkd"_a, "Llkd"_a, "Rkq1"_a, "Llkq1"_a, "Rkq2"_a, "Llkq2"_a, "inertia"_a, "init_active_power"_a, "init_reactive_power"_a, - "init_terminal_volt"_a, "init_volt_angle"_a, "init_mech_power"_a) - .def("apply_parameters_from_json", [](std::shared_ptr syngen, const CPS::String json) { - DPsim::Utils::applySynchronousGeneratorParametersFromJson(json::parse(json), syngen); - }) + "nom_power"_a, "nom_volt"_a, "nom_freq"_a, "pole_number"_a, "nom_field_cur"_a, "Rs"_a, "Ll"_a, "Lmd"_a, "Lmq"_a, "Rfd"_a, "Llfd"_a, + "Rkd"_a, "Llkd"_a, "Rkq1"_a, "Llkq1"_a, "Rkq2"_a, "Llkq2"_a, "inertia"_a, "init_active_power"_a, "init_reactive_power"_a, + "init_terminal_volt"_a, "init_volt_angle"_a, "init_mech_power"_a) + .def("apply_parameters_from_json", [](std::shared_ptr syngen, const CPS::String json) + { DPsim::Utils::applySynchronousGeneratorParametersFromJson(json::parse(json), syngen); }) .def("set_initial_values", &CPS::EMT::Ph3::SynchronGeneratorDQTrapez::setInitialValues, - "init_active_power"_a, "init_reactive_power"_a, - "init_terminal_volt"_a, "init_volt_angle"_a, "init_mech_power"_a); + "init_active_power"_a, "init_reactive_power"_a, + "init_terminal_volt"_a, "init_volt_angle"_a, "init_mech_power"_a); py::class_, CPS::Base::ReducedOrderSynchronGenerator>(mEMTPh3, "ReducedOrderSynchronGeneratorVBR", py::multiple_inheritance()); @@ -160,7 +162,7 @@ void addEMTPh3Components(py::module_ mEMTPh3) { py::class_, CPS::EMT::Ph3::ReducedOrderSynchronGeneratorVBR>(mEMTPh3, "SynchronGenerator5OrderVBR", py::multiple_inheritance()) .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) - .def("set_operational_parameters_per_unit", py::overload_cast(&CPS::EMT::Ph3::SynchronGenerator5OrderVBR::setOperationalParametersPerUnit), "nom_power"_a, "nom_voltage"_a, "nom_frequency"_a, "H"_a, "Ld"_a, "Lq"_a, "L0"_a, "Ld_t"_a, "Lq_t"_a, "Td0_t"_a, "Tq0_t"_a, "Ld_s"_a, "Lq_s"_a, "Td0_s"_a, "Tq0_s"_a, "Taa"_a); + .def("set_operational_parameters_per_unit", py::overload_cast(&CPS::EMT::Ph3::SynchronGenerator5OrderVBR::setOperationalParametersPerUnit), "nom_power"_a, "nom_voltage"_a, "nom_frequency"_a, "H"_a, "Ld"_a, "Lq"_a, "L0"_a, "Ld_t"_a, "Lq_t"_a, "Td0_t"_a, "Tq0_t"_a, "Ld_s"_a, "Lq_s"_a, "Td0_s"_a, "Tq0_s"_a, "Taa"_a); py::class_, CPS::EMT::Ph3::ReducedOrderSynchronGeneratorVBR>(mEMTPh3, "SynchronGenerator6aOrderVBR", py::multiple_inheritance()) .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) @@ -168,62 +170,66 @@ void addEMTPh3Components(py::module_ mEMTPh3) { py::class_, CPS::EMT::Ph3::ReducedOrderSynchronGeneratorVBR>(mEMTPh3, "SynchronGenerator6bOrderVBR", py::multiple_inheritance()) .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) - .def("set_operational_parameters_per_unit", py::overload_cast(&CPS::EMT::Ph3::SynchronGenerator6bOrderVBR::setOperationalParametersPerUnit), "nom_power"_a, "nom_voltage"_a, "nom_frequency"_a, "H"_a, "Ld"_a, "Lq"_a, "L0"_a, "Ld_t"_a, "Lq_t"_a, "Td0_t"_a, "Tq0_t"_a, "Ld_s"_a, "Lq_s"_a, "Td0_s"_a, "Tq0_s"_a, "Taa"_a=0); + .def("set_operational_parameters_per_unit", py::overload_cast(&CPS::EMT::Ph3::SynchronGenerator6bOrderVBR::setOperationalParametersPerUnit), "nom_power"_a, "nom_voltage"_a, "nom_frequency"_a, "H"_a, "Ld"_a, "Lq"_a, "L0"_a, "Ld_t"_a, "Lq_t"_a, "Td0_t"_a, "Tq0_t"_a, "Ld_s"_a, "Lq_s"_a, "Td0_s"_a, "Tq0_s"_a, "Taa"_a = 0); - #ifdef WITH_SUNDIALS +#ifdef WITH_SUNDIALS py::class_, CPS::SimPowerComp>(mEMTPh3, "SynchronGeneratorDQODE", py::multiple_inheritance()) - .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) + .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) .def("set_parameters_operational_per_unit", &CPS::EMT::Ph3::SynchronGeneratorDQODE::setParametersOperationalPerUnit, - "nom_power"_a, "nom_volt"_a, "nom_freq"_a, "pole_number"_a, "nom_field_cur"_a, "Rs"_a, "Ld"_a, "Lq"_a, "Ld_t"_a, "Lq_t"_a, "Ld_s"_a, - "Lq_s"_a, "Ll"_a, "Td0_t"_a, "Tq0_t"_a, "Td0_s"_a, "Tq0_s"_a, "inertia"_a) + "nom_power"_a, "nom_volt"_a, "nom_freq"_a, "pole_number"_a, "nom_field_cur"_a, "Rs"_a, "Ld"_a, "Lq"_a, "Ld_t"_a, "Lq_t"_a, "Ld_s"_a, + "Lq_s"_a, "Ll"_a, "Td0_t"_a, "Tq0_t"_a, "Td0_s"_a, "Tq0_s"_a, "inertia"_a) .def("set_parameters_fundamental_per_unit", &CPS::EMT::Ph3::SynchronGeneratorDQODE::setParametersFundamentalPerUnit, - "nom_power"_a, "nom_volt"_a, "nom_freq"_a, "pole_number"_a, "nom_field_cur"_a, "Rs"_a, "Ll"_a, "Lmd"_a, "Lmq"_a, "Rfd"_a, "Llfd"_a, - "Rkd"_a, "Llkd"_a, "Rkq1"_a, "Llkq1"_a, "Rkq2"_a, "Llkq2"_a, "inertia"_a, "init_active_power"_a, "init_reactive_power"_a, - "init_terminal_volt"_a, "init_volt_angle"_a, "init_mech_power"_a) - .def("apply_parameters_from_json", [](std::shared_ptr syngen, const CPS::String json) { - DPsim::Utils::applySynchronousGeneratorParametersFromJson(json::parse(json), syngen); - }) + "nom_power"_a, "nom_volt"_a, "nom_freq"_a, "pole_number"_a, "nom_field_cur"_a, "Rs"_a, "Ll"_a, "Lmd"_a, "Lmq"_a, "Rfd"_a, "Llfd"_a, + "Rkd"_a, "Llkd"_a, "Rkq1"_a, "Llkq1"_a, "Rkq2"_a, "Llkq2"_a, "inertia"_a, "init_active_power"_a, "init_reactive_power"_a, + "init_terminal_volt"_a, "init_volt_angle"_a, "init_mech_power"_a) + .def("apply_parameters_from_json", [](std::shared_ptr syngen, const CPS::String json) + { DPsim::Utils::applySynchronousGeneratorParametersFromJson(json::parse(json), syngen); }) .def("set_initial_values", &CPS::EMT::Ph3::SynchronGeneratorDQODE::setInitialValues, - "init_active_power"_a, "init_reactive_power"_a, - "init_terminal_volt"_a, "init_volt_angle"_a, "init_mech_power"_a); + "init_active_power"_a, "init_reactive_power"_a, + "init_terminal_volt"_a, "init_volt_angle"_a, "init_mech_power"_a); - #endif +#endif py::class_, CPS::SimPowerComp>(mEMTPh3, "AvVoltageSourceInverterDQ", py::multiple_inheritance()) - .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) + .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) .def(py::init(), "uid"_a, "name"_a, "loglevel"_a = CPS::Logger::Level::off, "with_trafo"_a = false) // cppcheck-suppress assignBoolToPointer .def("set_parameters", &CPS::EMT::Ph3::AvVoltageSourceInverterDQ::setParameters, "sys_omega"_a, "sys_volt_nom"_a, "p_ref"_a, "q_ref"_a) .def("set_filter_parameters", &CPS::EMT::Ph3::AvVoltageSourceInverterDQ::setFilterParameters, "Lf"_a, "Cf"_a, "Rf"_a, "Rc"_a) .def("set_controller_parameters", &CPS::EMT::Ph3::AvVoltageSourceInverterDQ::setControllerParameters, - "Kp_pll"_a, "Ki_pll"_a, "Kp_power_ctrl"_a, "Ki_power_ctrl"_a, "Kp_curr_ctrl"_a, "Ki_curr_ctrl"_a, "omega_cutoff"_a) + "Kp_pll"_a, "Ki_pll"_a, "Kp_power_ctrl"_a, "Ki_power_ctrl"_a, "Kp_curr_ctrl"_a, "Ki_curr_ctrl"_a, "omega_cutoff"_a) .def("set_transformer_parameters", &CPS::EMT::Ph3::AvVoltageSourceInverterDQ::setTransformerParameters, - "nom_voltage_end_1"_a, "nom_voltage_end_2"_a, "rated_power"_a, "ratio_abs"_a, "ratio_phase"_a, "resistance"_a, "inductance"_a, "omega"_a) + "nom_voltage_end_1"_a, "nom_voltage_end_2"_a, "rated_power"_a, "ratio_abs"_a, "ratio_phase"_a, "resistance"_a, "inductance"_a, "omega"_a) .def("set_initial_state_values", &CPS::EMT::Ph3::AvVoltageSourceInverterDQ::setInitialStateValues, - "p_init"_a, "q_init"_a, "phi_d_init"_a, "phi_q_init"_a, "gamma_d_init"_a, "gamma_q_init"_a) + "p_init"_a, "q_init"_a, "phi_d_init"_a, "phi_q_init"_a, "gamma_d_init"_a, "gamma_q_init"_a) .def("with_control", &CPS::EMT::Ph3::AvVoltageSourceInverterDQ::withControl) .def("connect", &CPS::EMT::Ph3::AvVoltageSourceInverterDQ::connect); py::class_, CPS::SimPowerComp, CPS::Base::VSIVoltageSourceInverterDQ>(mEMTPh3, "VSIVoltageControlDQ", py::multiple_inheritance()) - .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) - .def(py::init(), "uid"_a, "name"_a, "loglevel"_a = CPS::Logger::Level::off, "model_as_current_source"_a=false, "with_interface_resistor"_a=false) // cppcheck-suppress assignBoolToPointer + .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) + .def(py::init(), "uid"_a, "name"_a, "loglevel"_a = CPS::Logger::Level::off, "model_as_current_source"_a = false, "with_interface_resistor"_a = false) // cppcheck-suppress assignBoolToPointer .def("connect", &CPS::EMT::Ph3::VSIVoltageControlDQ::connect); + py::class_, CPS::SimPowerComp, CPS::Base::VSIVoltageSourceInverterDQ>(mEMTPh3, "VSIVoltageControlVBR", py::multiple_inheritance()) + .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) + .def(py::init(), "uid"_a, "name"_a, "loglevel"_a = CPS::Logger::Level::off, "model_as_current_source"_a = false) // cppcheck-suppress assignBoolToPointer + .def("connect", &CPS::EMT::Ph3::VSIVoltageControlVBR::connect); + py::class_, CPS::SimPowerComp>(mEMTPh3, "Transformer", py::multiple_inheritance()) - .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) + .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) .def(py::init(), "uid"_a, "name"_a, "loglevel"_a = CPS::Logger::Level::off) // cppcheck-suppress assignBoolToPointer .def("set_parameters", &CPS::EMT::Ph3::Transformer::setParameters, "nom_voltage_end_1"_a, "nom_voltage_end_2"_a, "ratio_abs"_a, "ratio_phase"_a, "resistance"_a, "inductance"_a) .def("connect", &CPS::EMT::Ph3::Transformer::connect); py::class_, CPS::SimPowerComp>(mEMTPh3, "SeriesResistor", py::multiple_inheritance()) - .def(py::init()) + .def(py::init()) .def(py::init()) - .def("set_parameters", &CPS::EMT::Ph3::SeriesResistor::setParameters, "R"_a) + .def("set_parameters", &CPS::EMT::Ph3::SeriesResistor::setParameters, "R"_a) .def("connect", &CPS::EMT::Ph3::SeriesResistor::connect); py::class_, CPS::SimPowerComp, CPS::Base::Ph1::Switch>(mEMTPh3, "SeriesSwitch", py::multiple_inheritance()) - .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) - .def("set_parameters", &CPS::EMT::Ph3::SeriesSwitch::setParameters, "open_resistance"_a, "closed_resistance"_a, "closed"_a = false) // cppcheck-suppress assignBoolToPointer + .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) + .def("set_parameters", &CPS::EMT::Ph3::SeriesSwitch::setParameters, "open_resistance"_a, "closed_resistance"_a, "closed"_a = false) // cppcheck-suppress assignBoolToPointer .def("open", &CPS::EMT::Ph3::SeriesSwitch::open) .def("close", &CPS::EMT::Ph3::SeriesSwitch::close) .def("connect", &CPS::EMT::Ph3::SeriesSwitch::connect); diff --git a/dpsim/src/pybind/SPComponents.cpp b/dpsim/src/pybind/SPComponents.cpp index f9f8c3e852..3d4135d84b 100644 --- a/dpsim/src/pybind/SPComponents.cpp +++ b/dpsim/src/pybind/SPComponents.cpp @@ -17,126 +17,128 @@ namespace py = pybind11; using namespace pybind11::literals; -void addSPComponents(py::module_ mSP) { +void addSPComponents(py::module_ mSP) +{ py::module mSPPh1 = mSP.def_submodule("ph1", "single phase static phasor models"); addSPPh1Components(mSPPh1); py::module mSPPh3 = mSP.def_submodule("ph3", "three phase static phasor models"); addSPPh3Components(mSPPh3); } -void addSPPh1Components(py::module_ mSPPh1) { - //SP Ph1 Components +void addSPPh1Components(py::module_ mSPPh1) +{ + // SP Ph1 Components py::class_, CPS::SimPowerComp>(mSPPh1, "VoltageSource", py::multiple_inheritance()) - .def(py::init()) + .def(py::init()) .def(py::init()) - .def("set_parameters", py::overload_cast(&CPS::SP::Ph1::VoltageSource::setParameters), "V_ref"_a, "f_src"_a = 0) + .def("set_parameters", py::overload_cast(&CPS::SP::Ph1::VoltageSource::setParameters), "V_ref"_a, "f_src"_a = 0) .def("connect", &CPS::SP::Ph1::VoltageSource::connect) .def_property("V_ref", createAttributeGetter("V_ref"), createAttributeSetter("V_ref")) .def_property("f_src", createAttributeGetter("f_src"), createAttributeSetter("f_src")); py::class_, CPS::SimPowerComp>(mSPPh1, "Resistor", py::multiple_inheritance()) - .def(py::init()) + .def(py::init()) .def(py::init()) - .def("set_parameters", &CPS::SP::Ph1::Resistor::setParameters, "R"_a) + .def("set_parameters", &CPS::SP::Ph1::Resistor::setParameters, "R"_a) .def("connect", &CPS::SP::Ph1::Resistor::connect) .def_property("R", createAttributeGetter("R"), createAttributeSetter("R")); py::class_, CPS::SimPowerComp>(mSPPh1, "Capacitor", py::multiple_inheritance()) - .def(py::init()) + .def(py::init()) .def(py::init()) - .def("set_parameters", &CPS::SP::Ph1::Capacitor::setParameters, "C"_a) + .def("set_parameters", &CPS::SP::Ph1::Capacitor::setParameters, "C"_a) .def("connect", &CPS::SP::Ph1::Capacitor::connect) .def_property("C", createAttributeGetter("C"), createAttributeSetter("C")); py::class_, CPS::SimPowerComp>(mSPPh1, "Inductor", py::multiple_inheritance()) - .def(py::init()) + .def(py::init()) .def(py::init()) - .def("set_parameters", &CPS::SP::Ph1::Inductor::setParameters, "L"_a) + .def("set_parameters", &CPS::SP::Ph1::Inductor::setParameters, "L"_a) .def("connect", &CPS::SP::Ph1::Inductor::connect) .def_property("L", createAttributeGetter("L"), createAttributeSetter("L")); py::class_, CPS::SimPowerComp>(mSPPh1, "ResInductor", py::multiple_inheritance()) - .def(py::init()) + .def(py::init()) .def(py::init()) - .def("set_parameters", &CPS::SP::Ph1::ResIndSeries::setParameters, "R"_a, "L"_a) + .def("set_parameters", &CPS::SP::Ph1::ResIndSeries::setParameters, "R"_a, "L"_a) .def("connect", &CPS::SP::Ph1::ResIndSeries::connect); py::class_, CPS::SimPowerComp>(mSPPh1, "NetworkInjection", py::multiple_inheritance()) - .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) - .def("set_parameters", py::overload_cast(&CPS::SP::Ph1::NetworkInjection::setParameters), "voltage_set_point"_a) - .def("set_parameters", py::overload_cast(&CPS::SP::Ph1::NetworkInjection::setParameters), "V_ref"_a, "f_src"_a = 0) + .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) + .def("set_parameters", py::overload_cast(&CPS::SP::Ph1::NetworkInjection::setParameters), "voltage_set_point"_a) + .def("set_parameters", py::overload_cast(&CPS::SP::Ph1::NetworkInjection::setParameters), "V_ref"_a, "f_src"_a = 0) .def("set_base_voltage", &CPS::SP::Ph1::NetworkInjection::setBaseVoltage, "base_voltage"_a) .def("connect", &CPS::SP::Ph1::NetworkInjection::connect) .def("modify_power_flow_bus_type", &CPS::SP::Ph1::NetworkInjection::modifyPowerFlowBusType, "bus_type"_a); py::class_, CPS::SimPowerComp>(mSPPh1, "PiLine", py::multiple_inheritance()) - .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) - .def("set_parameters", &CPS::SP::Ph1::PiLine::setParameters, "R"_a, "L"_a, "C"_a=0, "G"_a=0) + .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) + .def("set_parameters", &CPS::SP::Ph1::PiLine::setParameters, "R"_a, "L"_a, "C"_a = 0, "G"_a = 0) .def("set_base_voltage", &CPS::SP::Ph1::PiLine::setBaseVoltage, "base_voltage"_a) .def("connect", &CPS::SP::Ph1::PiLine::connect); py::class_, CPS::SimPowerComp>(mSPPh1, "Shunt", py::multiple_inheritance()) - .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) - .def("set_parameters", &CPS::SP::Ph1::Shunt::setParameters, "G"_a, "B"_a) + .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) + .def("set_parameters", &CPS::SP::Ph1::Shunt::setParameters, "G"_a, "B"_a) .def("set_base_voltage", &CPS::SP::Ph1::Shunt::setBaseVoltage, "base_voltage"_a) .def("connect", &CPS::SP::Ph1::Shunt::connect); py::class_, CPS::SimPowerComp>(mSPPh1, "Load", py::multiple_inheritance()) - .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) + .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) .def("set_parameters", py::overload_cast(&CPS::SP::Ph1::Load::setParameters), "active_power"_a, "reactive_power"_a) - .def("set_parameters", py::overload_cast(&CPS::SP::Ph1::Load::setParameters), "active_power"_a, "reactive_power"_a, "nominal_voltage"_a) + .def("set_parameters", py::overload_cast(&CPS::SP::Ph1::Load::setParameters), "active_power"_a, "reactive_power"_a, "nominal_voltage"_a) .def("modify_power_flow_bus_type", &CPS::SP::Ph1::Load::modifyPowerFlowBusType, "bus_type"_a) .def("connect", &CPS::SP::Ph1::Load::connect); py::class_, CPS::SimPowerComp, CPS::Base::Ph1::Switch>(mSPPh1, "Switch", py::multiple_inheritance()) - .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) - .def("set_parameters", &CPS::SP::Ph1::Switch::setParameters, "open_resistance"_a, "closed_resistance"_a, "closed"_a = false) // cppcheck-suppress assignBoolToPointer + .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) + .def("set_parameters", &CPS::SP::Ph1::Switch::setParameters, "open_resistance"_a, "closed_resistance"_a, "closed"_a = false) // cppcheck-suppress assignBoolToPointer .def("open", &CPS::SP::Ph1::Switch::open) .def("close", &CPS::SP::Ph1::Switch::close) .def("connect", &CPS::SP::Ph1::Switch::connect); py::class_, CPS::SimPowerComp>(mSPPh1, "SynchronGenerator", py::multiple_inheritance()) - .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) - .def("set_parameters", (&CPS::SP::Ph1::SynchronGenerator::setParameters), "rated_apparent_power"_a, "rated_voltage"_a, "set_point_active_power"_a, - "set_point_voltage"_a, "powerflow_bus_type"_a, "set_point_reactive_power"_a=0) - .def("set_base_voltage", &CPS::SP::Ph1::SynchronGenerator::setBaseVoltage, "base_voltage"_a) + .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) + .def("set_parameters", (&CPS::SP::Ph1::SynchronGenerator::setParameters), "rated_apparent_power"_a, "rated_voltage"_a, "set_point_active_power"_a, + "set_point_voltage"_a, "powerflow_bus_type"_a, "set_point_reactive_power"_a = 0) + .def("set_base_voltage", &CPS::SP::Ph1::SynchronGenerator::setBaseVoltage, "base_voltage"_a) .def("connect", &CPS::SP::Ph1::SynchronGenerator::connect) .def("modify_power_flow_bus_type", &CPS::SP::Ph1::SynchronGenerator::modifyPowerFlowBusType, "bus_type"_a) .def("get_apparent_power", &CPS::SP::Ph1::SynchronGenerator::getApparentPower); py::class_, CPS::SimPowerComp, CPS::Base::Ph1::Switch>(mSPPh1, "varResSwitch", py::multiple_inheritance()) - .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) - .def("set_parameters", &CPS::SP::Ph1::varResSwitch::setParameters, "open_resistance"_a, "closed_resistance"_a, "closed"_a = false) // cppcheck-suppress assignBoolToPointer + .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) + .def("set_parameters", &CPS::SP::Ph1::varResSwitch::setParameters, "open_resistance"_a, "closed_resistance"_a, "closed"_a = false) // cppcheck-suppress assignBoolToPointer .def("open", &CPS::SP::Ph1::varResSwitch::open) .def("close", &CPS::SP::Ph1::varResSwitch::close) .def("set_init_parameters", &CPS::SP::Ph1::varResSwitch::setInitParameters, "time_step"_a) .def("connect", &CPS::SP::Ph1::varResSwitch::connect); py::class_, CPS::SimPowerComp>(mSPPh1, "SynchronGeneratorTrStab", py::multiple_inheritance()) - .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) + .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) .def("set_standard_parameters_PU", &CPS::SP::Ph1::SynchronGeneratorTrStab::setStandardParametersPU, - "nom_power"_a, "nom_volt"_a, "nom_freq"_a, "Xpd"_a, "inertia"_a, "Rs"_a=0, "D"_a=0) + "nom_power"_a, "nom_volt"_a, "nom_freq"_a, "Xpd"_a, "inertia"_a, "Rs"_a = 0, "D"_a = 0) .def("set_initial_values", &CPS::SP::Ph1::SynchronGeneratorTrStab::setInitialValues, "elec_power"_a, "mech_power"_a) .def("connect", &CPS::SP::Ph1::SynchronGeneratorTrStab::connect) .def("set_model_flags", &CPS::SP::Ph1::SynchronGeneratorTrStab::setModelFlags, "convert_with_omega_mech"_a) - .def("set_reference_omega", [](CPS::SP::Ph1::SynchronGeneratorTrStab &gen, std::string refOmegaName, CPS::IdentifiedObject::Ptr refOmegaComp, - std::string refDeltaName, CPS::IdentifiedObject::Ptr refDeltaComp) { - gen.setReferenceOmega(refOmegaComp->attributeTyped(refOmegaName), refDeltaComp->attributeTyped(refDeltaName)); - }, "ref_omega_name"_a="w_r", "ref_omage_comp"_a, "ref_delta_name"_a="delta_r", "ref_delta_comp"_a); + .def( + "set_reference_omega", [](CPS::SP::Ph1::SynchronGeneratorTrStab &gen, std::string refOmegaName, CPS::IdentifiedObject::Ptr refOmegaComp, std::string refDeltaName, CPS::IdentifiedObject::Ptr refDeltaComp) + { gen.setReferenceOmega(refOmegaComp->attributeTyped(refOmegaName), refDeltaComp->attributeTyped(refDeltaName)); }, + "ref_omega_name"_a = "w_r", "ref_omage_comp"_a, "ref_delta_name"_a = "delta_r", "ref_delta_comp"_a); py::class_, CPS::Base::ReducedOrderSynchronGenerator>(mSPPh1, "ReducedOrderSynchronGeneratorVBR", py::multiple_inheritance()); py::class_, CPS::SP::Ph1::ReducedOrderSynchronGeneratorVBR>(mSPPh1, "SynchronGenerator3OrderVBR", py::multiple_inheritance()) .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) .def("set_operational_parameters_per_unit", py::overload_cast(&CPS::SP::Ph1::SynchronGenerator3OrderVBR::setOperationalParametersPerUnit), "nom_power"_a, "nom_voltage"_a, "nom_frequency"_a, "H"_a, "Ld"_a, "Lq"_a, "L0"_a, "Ld_t"_a, "Td0_t"_a); - + py::class_, CPS::SP::Ph1::ReducedOrderSynchronGeneratorVBR>(mSPPh1, "SynchronGenerator4OrderVBR", py::multiple_inheritance()) .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) .def("set_operational_parameters_per_unit", py::overload_cast(&CPS::SP::Ph1::SynchronGenerator4OrderVBR::setOperationalParametersPerUnit), "nom_power"_a, "nom_voltage"_a, "nom_frequency"_a, "H"_a, "Ld"_a, "Lq"_a, "L0"_a, "Ld_t"_a, "Lq_t"_a, "Td0_t"_a, "Tq0_t"_a); py::class_, CPS::SP::Ph1::ReducedOrderSynchronGeneratorVBR>(mSPPh1, "SynchronGenerator5OrderVBR", py::multiple_inheritance()) .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) - .def("set_operational_parameters_per_unit", py::overload_cast(&CPS::SP::Ph1::SynchronGenerator5OrderVBR::setOperationalParametersPerUnit), "nom_power"_a, "nom_voltage"_a, "nom_frequency"_a, "H"_a, "Ld"_a, "Lq"_a, "L0"_a, "Ld_t"_a, "Lq_t"_a, "Td0_t"_a, "Tq0_t"_a, "Ld_s"_a, "Lq_s"_a, "Td0_s"_a, "Tq0_s"_a, "Taa"_a); + .def("set_operational_parameters_per_unit", py::overload_cast(&CPS::SP::Ph1::SynchronGenerator5OrderVBR::setOperationalParametersPerUnit), "nom_power"_a, "nom_voltage"_a, "nom_frequency"_a, "H"_a, "Ld"_a, "Lq"_a, "L0"_a, "Ld_t"_a, "Lq_t"_a, "Td0_t"_a, "Tq0_t"_a, "Ld_s"_a, "Lq_s"_a, "Td0_s"_a, "Tq0_s"_a, "Taa"_a); py::class_, CPS::SP::Ph1::ReducedOrderSynchronGeneratorVBR>(mSPPh1, "SynchronGenerator6aOrderVBR", py::multiple_inheritance()) .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) @@ -144,60 +146,66 @@ void addSPPh1Components(py::module_ mSPPh1) { py::class_, CPS::SP::Ph1::ReducedOrderSynchronGeneratorVBR>(mSPPh1, "SynchronGenerator6bOrderVBR", py::multiple_inheritance()) .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) - .def("set_operational_parameters_per_unit", py::overload_cast(&CPS::SP::Ph1::SynchronGenerator6bOrderVBR::setOperationalParametersPerUnit), "nom_power"_a, "nom_voltage"_a, "nom_frequency"_a, "H"_a, "Ld"_a, "Lq"_a, "L0"_a, "Ld_t"_a, "Lq_t"_a, "Td0_t"_a, "Tq0_t"_a, "Ld_s"_a, "Lq_s"_a, "Td0_s"_a, "Tq0_s"_a, "Taa"_a=0); + .def("set_operational_parameters_per_unit", py::overload_cast(&CPS::SP::Ph1::SynchronGenerator6bOrderVBR::setOperationalParametersPerUnit), "nom_power"_a, "nom_voltage"_a, "nom_frequency"_a, "H"_a, "Ld"_a, "Lq"_a, "L0"_a, "Ld_t"_a, "Lq_t"_a, "Td0_t"_a, "Tq0_t"_a, "Ld_s"_a, "Lq_s"_a, "Td0_s"_a, "Tq0_s"_a, "Taa"_a = 0); py::class_, CPS::SimPowerComp>(mSPPh1, "AvVoltageSourceInverterDQ", py::multiple_inheritance()) - .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) + .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) .def(py::init(), "uid"_a, "name"_a, "loglevel"_a = CPS::Logger::Level::off, "with_trafo"_a = false) // cppcheck-suppress assignBoolToPointer .def("set_parameters", &CPS::SP::Ph1::AvVoltageSourceInverterDQ::setParameters, "sys_omega"_a, "sys_volt_nom"_a, "p_ref"_a, "q_ref"_a) .def("set_filter_parameters", &CPS::SP::Ph1::AvVoltageSourceInverterDQ::setFilterParameters, "Lf"_a, "Cf"_a, "Rf"_a, "Rc"_a) .def("set_controller_parameters", &CPS::SP::Ph1::AvVoltageSourceInverterDQ::setControllerParameters, - "Kp_pll"_a, "Ki_pll"_a, "Kp_power_ctrl"_a, "Ki_power_ctrl"_a, "Kp_curr_ctrl"_a, "Ki_curr_ctrl"_a, "omega_cutoff"_a) + "Kp_pll"_a, "Ki_pll"_a, "Kp_power_ctrl"_a, "Ki_power_ctrl"_a, "Kp_curr_ctrl"_a, "Ki_curr_ctrl"_a, "omega_cutoff"_a) .def("set_transformer_parameters", &CPS::SP::Ph1::AvVoltageSourceInverterDQ::setTransformerParameters, - "nom_voltage_end_1"_a, "nom_voltage_end_2"_a, "rated_power"_a, "ratio_abs"_a, "ratio_phase"_a, "resistance"_a, "inductance"_a) + "nom_voltage_end_1"_a, "nom_voltage_end_2"_a, "rated_power"_a, "ratio_abs"_a, "ratio_phase"_a, "resistance"_a, "inductance"_a) .def("set_initial_state_values", &CPS::SP::Ph1::AvVoltageSourceInverterDQ::setInitialStateValues, - "p_init"_a, "q_init"_a, "phi_d_init"_a, "phi_q_init"_a, "gamma_d_init"_a, "gamma_q_init"_a) + "p_init"_a, "q_init"_a, "phi_d_init"_a, "phi_q_init"_a, "gamma_d_init"_a, "gamma_q_init"_a) .def("with_control", &CPS::SP::Ph1::AvVoltageSourceInverterDQ::withControl) .def("connect", &CPS::SP::Ph1::AvVoltageSourceInverterDQ::connect); py::class_, CPS::SimPowerComp>(mSPPh1, "Transformer", py::multiple_inheritance()) - .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) + .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) .def(py::init(), "uid"_a, "name"_a, "loglevel"_a = CPS::Logger::Level::off) // cppcheck-suppress assignBoolToPointer .def("set_parameters", py::overload_cast(&CPS::SP::Ph1::Transformer::setParameters), "nom_voltage_end_1"_a, "nom_voltage_end_2"_a, "ratio_abs"_a, "ratio_phase"_a, "resistance"_a, "inductance"_a) .def("set_parameters", py::overload_cast(&CPS::SP::Ph1::Transformer::setParameters), "nom_voltage_end_1"_a, "nom_voltage_end_2"_a, "rated_power"_a, "ratio_abs"_a, "ratio_phase"_a, "resistance"_a, "inductance"_a) .def("set_base_voltage", &CPS::SP::Ph1::Transformer::setBaseVoltage, "base_voltage"_a) .def("connect", &CPS::SP::Ph1::Transformer::connect); - + py::class_, CPS::SimPowerComp, CPS::Base::VSIVoltageSourceInverterDQ>(mSPPh1, "VSIVoltageControlDQ", py::multiple_inheritance()) - .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) - .def(py::init(), "uid"_a, "name"_a, "loglevel"_a = CPS::Logger::Level::off, "model_as_current_source"_a=true, "with_interface_resistor"_a=false) // cppcheck-suppress assignBoolToPointer + .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) + .def(py::init(), "uid"_a, "name"_a, "loglevel"_a = CPS::Logger::Level::off, "model_as_current_source"_a = true, "with_interface_resistor"_a = false) // cppcheck-suppress assignBoolToPointer .def("connect", &CPS::SP::Ph1::VSIVoltageControlDQ::connect); + + py::class_, CPS::SimPowerComp, CPS::Base::VSIVoltageSourceInverterDQ>(mSPPh1, "VSIVoltageControlVBR", py::multiple_inheritance()) + .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off) + .def(py::init(), "uid"_a, "name"_a, "loglevel"_a = CPS::Logger::Level::off, "model_as_current_source"_a = false) // cppcheck-suppress assignBoolToPointer + .def("connect", &CPS::SP::Ph1::VSIVoltageControlVBR::connect); } -void addSPPh3Components(py::module_ mSPPh3) { +void addSPPh3Components(py::module_ mSPPh3) +{ py::class_, CPS::SimPowerComp>(mSPPh3, "VoltageSource", py::multiple_inheritance()) - .def(py::init()) + .def(py::init()) .def(py::init()) - .def("set_parameters", &CPS::SP::Ph3::VoltageSource::setParameters, "V_ref"_a) + .def("set_parameters", &CPS::SP::Ph3::VoltageSource::setParameters, "V_ref"_a) .def("connect", &CPS::SP::Ph3::VoltageSource::connect) .def_property("V_ref", createAttributeGetter("V_ref"), createAttributeSetter("V_ref")) .def_property("f_src", createAttributeGetter("f_src"), createAttributeSetter("f_src")); py::class_, CPS::SimPowerComp>(mSPPh3, "Resistor", py::multiple_inheritance()) - .def(py::init()) + .def(py::init()) .def(py::init()) - .def("set_parameters", &CPS::SP::Ph3::Resistor::setParameters, "R"_a) + .def("set_parameters", &CPS::SP::Ph3::Resistor::setParameters, "R"_a) .def("connect", &CPS::SP::Ph3::Resistor::connect); py::class_, CPS::SimPowerComp>(mSPPh3, "Capacitor", py::multiple_inheritance()) - .def(py::init()) + .def(py::init()) .def(py::init()) - .def("set_parameters", &CPS::SP::Ph3::Capacitor::setParameters, "C"_a) + .def("set_parameters", &CPS::SP::Ph3::Capacitor::setParameters, "C"_a) .def("connect", &CPS::SP::Ph3::Capacitor::connect); py::class_, CPS::SimPowerComp>(mSPPh3, "Inductor", py::multiple_inheritance()) - .def(py::init()) + .def(py::init()) .def(py::init()) - .def("set_parameters", &CPS::SP::Ph3::Inductor::setParameters, "L"_a) + .def("set_parameters", &CPS::SP::Ph3::Inductor::setParameters, "L"_a) .def("connect", &CPS::SP::Ph3::Inductor::connect); } diff --git a/dpsim/src/pybind/SignalComponents.cpp b/dpsim/src/pybind/SignalComponents.cpp index f6b719153a..b27d719e1c 100644 --- a/dpsim/src/pybind/SignalComponents.cpp +++ b/dpsim/src/pybind/SignalComponents.cpp @@ -17,16 +17,17 @@ namespace py = pybind11; using namespace pybind11::literals; -void addSignalComponents(py::module_ mSignal) { +void addSignalComponents(py::module_ mSignal) +{ py::class_, CPS::IdentifiedObject>(mSignal, "TopologicalSignalComp"); - py::class_, CPS::TopologicalSignalComp>(mSignal, "SimSignalComp"); + py::class_, CPS::TopologicalSignalComp>(mSignal, "SimSignalComp"); py::class_, CPS::SimSignalComp>(mSignal, "DecouplingLine", py::multiple_inheritance()) .def(py::init()) - .def(py::init()) + .def(py::init()) .def("set_parameters", &CPS::Signal::DecouplingLine::setParameters, "node_1"_a, "node_2"_a, "resistance"_a, "inductance"_a, "capacitance"_a) - .def("get_line_components", &CPS::Signal::DecouplingLine::getLineComponents); + .def("get_line_components", &CPS::Signal::DecouplingLine::getLineComponents); py::class_, CPS::SimSignalComp>(mSignal, "DecouplingLineEMT", py::multiple_inheritance()) .def(py::init()) @@ -43,7 +44,7 @@ void addSignalComponents(py::module_ mSignal) { .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off); py::class_, CPS::Base::Exciter>(mSignal, "ExciterST1Simp", py::multiple_inheritance()) .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off); - + py::class_, CPS::Base::ExciterParameters>(mSignal, "ExciterStaticParameters", py::multiple_inheritance()) .def(py::init()) .def_readwrite("Ta", &CPS::Signal::ExciterStaticParameters::Ta) @@ -103,7 +104,7 @@ void addSignalComponents(py::module_ mSignal) { .def_readwrite("Tw", &CPS::Signal::PSS1AParameters::Tw) .def_readwrite("Vs_max", &CPS::Signal::PSS1AParameters::Vs_max) .def_readwrite("Vs_min", &CPS::Signal::PSS1AParameters::Vs_min); - + // Governos py::class_, CPS::Base::Governor>(mSignal, "TurbineGovernorType1", py::multiple_inheritance()) .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off); @@ -189,4 +190,15 @@ void addSignalComponents(py::module_ mSignal) { .def_readwrite("Cf", &CPS::Signal::VSIControlType2Parameters::Cf) .def_readwrite("Lf", &CPS::Signal::VSIControlType2Parameters::Lf) .def_readwrite("tau", &CPS::Signal::VSIControlType2Parameters::tau); + + // Droop Controller + py::class_>(mSignal, "DroopControllerParameters", py::multiple_inheritance()) + .def(py::init()) + .def_readwrite("Kpv", &CPS::Signal::DroopControllerParameters::Tau_p) + .def_readwrite("Kiv", &CPS::Signal::DroopControllerParameters::Tau_l) + .def_readwrite("Kpc", &CPS::Signal::DroopControllerParameters::Mp) + .def_readwrite("Kic", &CPS::Signal::DroopControllerParameters::Pref) + .def_readwrite("VdRef", &CPS::Signal::DroopControllerParameters::OmegaNom); + py::class_>(mSignal, "DroopController", py::multiple_inheritance()) + .def(py::init(), "name"_a, "loglevel"_a = CPS::Logger::Level::off); } diff --git a/python/src/dpsim/matpower.py b/python/src/dpsim/matpower.py index 2d936424d7..c1695d64a2 100644 --- a/python/src/dpsim/matpower.py +++ b/python/src/dpsim/matpower.py @@ -541,7 +541,7 @@ def map_energy_consumer(self, index, bus_index, load_name=None, bus_type = dpsim if self.domain in [Domain.PF, Domain.SP]: load = self.dpsimpy_components.Load(load_name, self.log_level) else: - load = dpsimpy_components.RXLoad(load_name, self.log_level) + load = self.dpsimpy_components.RXLoad(load_name, self.log_level) load.set_parameters(load_p, load_q) if (self.domain==Domain.PF and bus_type==dpsimpy.PowerflowBusType.PQ):