103 copy->setFilterParameters(
mLf,
mCf,
mRf);
121 throw std::invalid_argument(
"GFL parameters must be finite.");
124 throw std::invalid_argument(
125 "GFL nominal angular frequency must be positive.");
127 if (sysVoltNom <= 0.0)
128 throw std::invalid_argument(
"GFL nominal voltage must be positive.");
139 SPDLOG_LOGGER_INFO(
mSLog,
140 "GFL general parameters:"
142 "\n omega_nom = {} rad/s"
154 throw std::logic_error(
"GFL::setParameters() must be called before "
155 "setControllerParameters().");
161 throw std::invalid_argument(
"GFL controller parameters must be finite.");
164 throw std::invalid_argument(
"GFL PLL integral gain must be non-zero.");
166 if (kiPowerCtrl == 0.0)
167 throw std::invalid_argument(
168 "GFL power-controller integral gain must be non-zero.");
170 if (kiCurrCtrl == 0.0)
171 throw std::invalid_argument(
172 "GFL current-controller integral gain must be non-zero.");
174 if (omegaCutoff <= 0.0)
175 throw std::invalid_argument(
176 "GFL power-filter cutoff frequency must be positive.");
192 mPLL->composeStateSpaceMatrices();
203 throw std::invalid_argument(
"GFL filter parameters must be finite.");
206 throw std::invalid_argument(
"GFL filter inductance Lf must be positive.");
209 throw std::invalid_argument(
"GFL filter capacitance Cf must be positive.");
212 throw std::invalid_argument(
213 "GFL filter resistance Rf must be non-negative.");
227 SPDLOG_LOGGER_INFO(
mSLog,
228 "GFL filter parameters:"
243 throw std::invalid_argument(
"GFL initial state values must be finite.");
255 gammaDInit, gammaQInit);
260 Matrix transform = Matrix::Zero(2, 3);
262 const Real k = std::sqrt(2.0 / 3.0);
264 transform << k * std::cos(theta), k * std::cos(theta - 2.0 *
PI / 3.0),
265 k * std::cos(theta + 2.0 *
PI / 3.0),
267 -k * std::sin(theta), -k * std::sin(theta - 2.0 *
PI / 3.0),
268 -k * std::sin(theta + 2.0 *
PI / 3.0);
276 Matrix transform = Matrix::Zero(3, 2);
278 const Real k = std::sqrt(2.0 / 3.0);
280 transform << k * std::cos(theta), -k * std::sin(theta),
282 k * std::cos(theta - 2.0 *
PI / 3.0),
283 -k * std::sin(theta - 2.0 *
PI / 3.0),
285 k * std::cos(theta + 2.0 *
PI / 3.0),
286 -k * std::sin(theta + 2.0 *
PI / 3.0);
292 const Matrix &fabc)
const {
299 const Matrix &fdq)
const {
334 const Real phiPLL = (**mPllOutput)(1, 0);
342 throw std::logic_error(
343 "GFL::setParameters() must be called before initialization.");
346 throw std::logic_error(
347 "GFL::setFilterParameters() must be called before initialization.");
350 throw std::logic_error(
351 "GFL::setControllerParameters() must be called before initialization.");
353 const Real omega = 2.0 *
PI * frequency;
368 if (std::abs(vPcc(0, 0)) < 1e-12)
369 throw std::runtime_error(
"GFL cannot initialize from zero PCC voltage.");
376 const Complex iGridA = std::conj((2.0 / 3.0) * sRef / vPcc(0, 0));
380 iGrid(0, 0) = iGridA;
389 const MatrixComp vInductorInput = vPcc + j * omega *
mLf * iF;
423 const Real theta0 = std::arg(vPcc(0, 0));
425 const Matrix vPccAbc0 = vPcc.real();
427 const Matrix iGridAbc0 = iGrid.real();
429 const Matrix vSourceAbc0 = vSource.real();
450 Matrix pllStateInit = Matrix::Zero(2, 1);
452 Matrix pllOutputInit = Matrix::Zero(2, 1);
454 pllStateInit(0, 0) = theta0;
458 pllOutputInit = pllStateInit;
460 mPLL->setInitialValues(**
mVcq, pllStateInit, pllOutputInit);
466 const Real phiDInit =
469 const Real phiQInit =
476 const Real gammaDInit =
479 const Real gammaQInit =
483 gammaDInit, gammaQInit);
493 "\n--- EMT_Ph3_GFL initialization ---"
494 "\nPCC voltage abc: {:s}"
495 "\nGrid injection abc: {:s}"
496 "\nFilter current abc: {:s}"
497 "\nSource voltage abc: {:s}"
498 "\nP/Q init: [{:.6e}, {:.6e}]"
499 "\nVc dq: [{:.6e}, {:.6e}]"
500 "\nIgrid dq: [{:.6e}, {:.6e}]"
501 "\n--- Initialization finished ---",
523 mPLL->setSimulationParameters(timeStep);
528 mMnaTasks.push_back(std::make_shared<ControlPreStep>(*
this));
530 mMnaTasks.push_back(std::make_shared<ControlStep>(*
this));
538 mPLL->signalAddPreStepDependencies(prevStepDependencies,
539 attributeDependencies, modifiedAttributes);
542 prevStepDependencies, attributeDependencies, modifiedAttributes);
547 mPLL->signalPreStep(time, timeStepCount);
558 mPLL->signalAddStepDependencies(prevStepDependencies, attributeDependencies,
562 prevStepDependencies, attributeDependencies, modifiedAttributes);
571 modifiedAttributes.push_back(
mVsref);
577 Real thetaMeasurement =
mPLL->mOutputPrev->get()(0, 0);
579 if (timeStepCount > 0) {
580 const Real phiPLLPrev =
mPLL->mOutputPrev->get()(1, 0);
584 thetaMeasurement +=
mTimeStep * omegaPLLPrev;
590 mPLL->signalStep(time, timeStepCount);
595 const Real thetaPLL = (**mPllOutput)(0, 0);
597 const Real phiPLL = (**mPllOutput)(1, 0);
614 prevStepDependencies.push_back(
mVsref);
622 attributeDependencies.push_back(
mPLL->mOutputPrev);
636 ->mnaPreStep(time, timeStepCount);
647 attributeDependencies.push_back(leftVector);
679 (**mIntfVoltage)(0, 0) =
682 (**mIntfVoltage)(1, 0) =
685 (**mIntfVoltage)(2, 0) =
AttributePointer< Attribute< T > > Ptr
void addMNASubComponent(typename SimPowerComp< Real >::Ptr subc, MNA_SUBCOMP_TASK_ORDER preStepOrder, MNA_SUBCOMP_TASK_ORDER postStepOrder, Bool contributeToRightVector)
void mnaCompApplyRightSideVectorStamp(Matrix &rightVector) override
CompositePowerComp(String uid, String name, Bool hasPreStep, Bool hasPostStep, Logger::Level logLevel)
Bool mManualInitialStatesSet
Matrix parkTransformPowerInvariant(Real theta, const Matrix &fabc) const
void setInitialStateValues(Real pInit, Real qInit, Real phiDInit, Real phiQInit, Real gammaDInit, Real gammaQInit)
const Attribute< Real >::Ptr mIgridQ
const Attribute< Matrix >::Ptr mPowerctrlStates
const Attribute< Matrix >::Ptr mPowerctrlInputs
Power-controller logging vectors.
void controlPreStep(Real time, Int timeStepCount)
void mnaParentPreStep(Real time, Int timeStepCount) override
void updateMeasurementAttributes(Real theta)
void addControlStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes)
SimPowerComp< Real >::Ptr clone(String name) override
Returns a modified copy of the component with the given suffix added to the name and without.
Matrix inverseParkTransformPowerInvariant(Real theta, const Matrix &fdq) const
void mnaCompUpdateCurrent(const Matrix &leftVector) override
Matrix getInverseParkTransformMatrixPowerInvariant(Real theta) const
void mnaCompUpdateVoltage(const Matrix &leftVector) override
std::shared_ptr< EMT::Ph3::Capacitor > mSubCapacitorF
void addControlPreStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes)
const Attribute< Matrix >::Ptr mPowerctrlOutputs
void setFilterParameters(Real lf, Real cf, Real rf)
Filter parameters. No Rc exists in this model.
const Attribute< Real >::Ptr mVcd
PCC voltage in controller dq frame.
const Attribute< Real >::Ptr mVcq
void setControllerParameters(Real kpPLL, Real kiPLL, Real kpPowerCtrl, Real kiPowerCtrl, Real kpCurrCtrl, Real kiCurrCtrl, Real omegaCutoff)
Controller parameters.
const Attribute< Real >::Ptr mPInst
Instantaneous controller-frame active/reactive power.
Bool mControllerParametersSet
void setParameters(Real sysOmega, Real sysVoltNom, Real pRef, Real qRef)
General operating parameters.
const Attribute< Matrix >::Ptr mPllOutput
PLL output [theta, phi_pll].
void mnaParentPostStep(Real time, Int timeStepCount, Attribute< Matrix >::Ptr &leftVector) override
std::shared_ptr< Signal::PLL > mPLL
std::shared_ptr< EMT::Ph3::Inductor > mSubInductorF
const Attribute< Real >::Ptr mOmegaPLL
Estimated PLL angular frequency [rad/s].
void initializeParentFromNodesAndTerminals(Real frequency) override
const Attribute< Matrix >::Ptr mVs
Actual controlled source voltage.
std::shared_ptr< Signal::PowerControllerVSI > mPowerControllerVSI
const Attribute< Matrix >::Ptr mVsref
Controlled source voltage reference in abc instantaneous peak values.
std::shared_ptr< EMT::Ph3::VoltageSource > mSubControlledVoltageSource
const Attribute< Real >::Ptr mIgridD
Positive converter-to-grid current in controller dq frame.
void mnaParentAddPostStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes, Attribute< Matrix >::Ptr &leftVector) override
void controlStep(Real time, Int timeStepCount)
std::shared_ptr< EMT::Ph3::Resistor > mSubResistorF
Matrix getParkTransformMatrixPowerInvariant(Real theta) const
void updatePowerAndFrequencyAttributes()
void mnaParentInitialize(Real omega, Real timeStep, Attribute< Matrix >::Ptr leftVector) override
void mnaParentAddPreStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes) override
const Attribute< Real >::Ptr mQInst
Bool mFilterParametersSet
GFL(String uid, String name, Logger::Level logLevel=Logger::Level::off)
const Attribute< String >::Ptr mName
Human readable name.
String uid()
Returns unique id.
String type()
Get component type (cross-platform)
AttributeList::Ptr mAttributes
Attribute List.
spdlog::level::level_enum Level
static String matrixToString(const Matrix &mat)
Attribute< Matrix >::Ptr mRightVector
static Real realFromVectorElement(const Matrix &mat, Matrix::Index row)
static Matrix singlePhaseParameterToThreePhase(Real parameter)
To convert single phase parameters to symmetrical three phase ones.
static bool isFinite(Real value)
UInt matrixNodeIndex(UInt nodeIndex)
const Attribute< MatrixVar< Real > >::Ptr mIntfCurrent
SimTerminal< Real >::List mTerminals
void setVirtualNodeNumber(UInt num)
const Attribute< MatrixVar< Real > >::Ptr mIntfVoltage
MatrixComp initialVoltage(UInt index)
SimNode< Real >::Ptr virtualNode(UInt index)
std::shared_ptr< SimPowerComp< VarType > > Ptr
SimNode< Real >::List mVirtualNodes
Bool terminalNotGrounded(UInt index)
Complex initialSingleVoltage(UInt index)
void setTerminalNumber(UInt num)
Logger::Level mLogLevel
Component logger control for internal variables.
bool mParametersSet
Flag indicating that parameters are set via setParameters() function.
Logger::Log mSLog
Component logger.
static std::shared_ptr< VoltageSource > make(Args &&...args)
#define RMS3PH_TO_PEAK1PH
#define PEAK1PH_TO_RMS3PH
Eigen::Matrix< Real, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor > Matrix
Dense matrix for real numbers.
std::complex< Real > Complex
Eigen::Matrix< Complex, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor > MatrixComp
Dense matrix for complex numbers.