Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Emt syngen trstab #185

Open
wants to merge 32 commits into
base: master
Choose a base branch
from
Open

Emt syngen trstab #185

wants to merge 32 commits into from

Conversation

gnakti
Copy link
Contributor

@gnakti gnakti commented Feb 6, 2023

This branch implements:

  • The synchronous generator second-order model in EMT domain
  • A variable resistance switch in EMT domain
  • SMIB and 3-Bus c++ examples in EMT domain with two scenarios (steady state & fault)
  • SMIB and 3-Bus Jupyter Notebooks extended with EMT domain

@sonarqubecloud
Copy link

sonarqubecloud bot commented Feb 6, 2023

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 58 Code Smells

0.0% 0.0% Coverage
16.1% 16.1% Duplication

@gnakti gnakti added the enhancement New feature or request label Feb 6, 2023
gnakti added 27 commits July 16, 2023 14:22
Signed-off-by: Ghassen Nakti <[email protected]>
Signed-off-by: Ghassen Nakti <[email protected]>
Signed-off-by: Ghassen Nakti <[email protected]>
Signed-off-by: Ghassen Nakti <[email protected]>
Signed-off-by: Ghassen Nakti <[email protected]>
Signed-off-by: Ghassen Nakti <[email protected]>
Signed-off-by: Ghassen Nakti <[email protected]>
Signed-off-by: Ghassen Nakti <[email protected]>
Signed-off-by: Ghassen Nakti <[email protected]>
Signed-off-by: Ghassen Nakti <[email protected]>
Signed-off-by: Ghassen Nakti <[email protected]>
Signed-off-by: Ghassen Nakti <[email protected]>
Signed-off-by: Ghassen Nakti <[email protected]>
@gnakti gnakti force-pushed the emt-syngen-trstab branch from 608f0e1 to 02b4287 Compare July 16, 2023 12:29
@sonarqubecloud
Copy link

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 54 Code Smells

0.0% 0.0% Coverage
12.9% 12.9% Duplication

@gnakti gnakti requested a review from dinkelbachjan July 17, 2023 07:17
Comment on lines +13 to +14
// !!! TODO: Adaptions to use in EMT_Ph3 models phase-to-ground peak variables
// !!! with initialization from phase-to-phase RMS variables
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume this is here due to copy & paste and can be removed

Comment on lines +32 to +33
public MNAVariableCompInterface,
public MNASwitchInterface,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need inheritance from both classes? I would assume that we require always system recomputation with varResSwitch and consequently use MNAVariableCompInterface. So can't we drop MNASwitchInterface?

Comment on lines +115 to +171
void EMT::Ph3::varResSwitch::mnaCompApplySwitchSystemMatrixStamp(Bool closed, SparseMatrixRow& systemMatrix, Int freqIdx) {
MatrixFixedSize<3, 3> conductance = (closed) ?
(**mClosedResistance).inverse() : (**mOpenResistance).inverse();

// Set diagonal entries
if (terminalNotGrounded(0)) {
// set upper left block, 3x3 entries
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 0), matrixNodeIndex(0, 0), conductance(0, 0));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 0), matrixNodeIndex(0, 1), conductance(0, 1));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 0), matrixNodeIndex(0, 2), conductance(0, 2));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 1), matrixNodeIndex(0, 0), conductance(1, 0));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 1), matrixNodeIndex(0, 1), conductance(1, 1));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 1), matrixNodeIndex(0, 2), conductance(1, 2));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 2), matrixNodeIndex(0, 0), conductance(2, 0));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 2), matrixNodeIndex(0, 1), conductance(2, 1));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 2), matrixNodeIndex(0, 2), conductance(2, 2));
}
if (terminalNotGrounded(1)) {
// set buttom right block, 3x3 entries
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(1, 0), matrixNodeIndex(1, 0), conductance(0, 0));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(1, 0), matrixNodeIndex(1, 1), conductance(0, 1));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(1, 0), matrixNodeIndex(1, 2), conductance(0, 2));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(1, 1), matrixNodeIndex(1, 0), conductance(1, 0));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(1, 1), matrixNodeIndex(1, 1), conductance(1, 1));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(1, 1), matrixNodeIndex(1, 2), conductance(1, 2));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(1, 2), matrixNodeIndex(1, 0), conductance(2, 0));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(1, 2), matrixNodeIndex(1, 1), conductance(2, 1));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(1, 2), matrixNodeIndex(1, 2), conductance(2, 2));
}
// Set off diagonal blocks, 2x3x3 entries
if (terminalNotGrounded(0) && terminalNotGrounded(1)) {
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 0), matrixNodeIndex(1, 0), -conductance(0, 0));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 0), matrixNodeIndex(1, 1), -conductance(0, 1));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 0), matrixNodeIndex(1, 2), -conductance(0, 2));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 1), matrixNodeIndex(1, 0), -conductance(1, 0));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 1), matrixNodeIndex(1, 1), -conductance(1, 1));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 1), matrixNodeIndex(1, 2), -conductance(1, 2));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 2), matrixNodeIndex(1, 0), -conductance(2, 0));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 2), matrixNodeIndex(1, 1), -conductance(2, 1));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 2), matrixNodeIndex(1, 2), -conductance(2, 2));


Math::addToMatrixElement(systemMatrix, matrixNodeIndex(1, 0), matrixNodeIndex(0, 0), -conductance(0, 0));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(1, 0), matrixNodeIndex(0, 1), -conductance(0, 1));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(1, 0), matrixNodeIndex(0, 2), -conductance(0, 2));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(1, 1), matrixNodeIndex(0, 0), -conductance(1, 0));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(1, 1), matrixNodeIndex(0, 1), -conductance(1, 1));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(1, 1), matrixNodeIndex(0, 2), -conductance(1, 2));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(1, 2), matrixNodeIndex(0, 0), -conductance(2, 0));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(1, 2), matrixNodeIndex(0, 1), -conductance(2, 1));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(1, 2), matrixNodeIndex(0, 2), -conductance(2, 2));
}

SPDLOG_LOGGER_TRACE(mSLog,
"\nConductance matrix: {:s}",
Logger::matrixToString(conductance));
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really require this method? I assume that, when employing the varResSwitch, we do not follow the approach of precalculating the matrices before the simulation, but instead use the approach of system recomputation during the simulation. mnaCompApplySwitchSystemMatrixStamp is used when precalculating the matrices. So I would assume that the method can be removed in this model and instead only mnaCompApplySystemMatrixStamp and hasParameterChanged will be used to build the component's matrix stamp.

Comment on lines +38 to +45
Bool mPrevState=false;
Real mDeltaResClosed = 0;
Real mDeltaResOpen = 1.5;
Matrix mPrevRes; // previous resistance value to multiply with rate of change
// because we change the base value mClosedResistance & mOpenResistance to recompute the system Matrix
// we need to save the initialisation values to use them as target values in the transition
Matrix mInitClosedRes;
Matrix mInitOpenRes;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Improve code style, explanatory \\\ comments are missing


// #### MNA section for switches ####
/// Check if switch is closed
Bool mnaIsClosed() { return isClosed(); }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Required? Why not use of isClosed from Base::Ph3::Switch?

/// Add MNA post step dependencies
void mnaCompAddPostStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes, Attribute<Matrix>::Ptr &leftVector) override;

Bool hasParameterChanged();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add override flag

//Define variables for the transition
mDeltaResClosed= 0;
// mDeltaResOpen = 1.5; // assumption for 1ms step size
mDeltaResOpen= 0.5*timestep/0.001 + 1;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add an explanatory comment for this formula and where the fixed values e.g. 0.001 come from?

simDP.setDirectLinearSolverImplementation(DPsim::DirectLinearSolverImpl::SparseLU);

if (useVarResSwitch == true) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of useVarResSwitch seems inconstistent. Sometimes you use it for case distinctions, sometimes you just comment out the respective varResSwitch code lines, e.g. in 147-151

Comment on lines +1134 to +1139
"for name in ['delta_gen']:\n",
" plt.plot(ts_sp1ph_TrStab_dl[name+'1'].interpolate(timestep).time[begin_idx:end_idx], ts_sp1ph_TrStab_dl[name+'2'].interpolate(timestep).values[begin_idx:end_idx]*180/3.14 - ts_sp1ph_TrStab_dl[name+'1'].interpolate(timestep).values[begin_idx:end_idx]*180/3.14, label=name + ' SP backshift')\n",
" plt.plot(ts_dp1ph_TrStab_dl[name+'1'].interpolate(timestep).time[begin_idx:end_idx], ts_dp1ph_TrStab_dl[name+'2'].interpolate(timestep).values[begin_idx:end_idx]*180/3.14 - ts_dp1ph_TrStab_dl[name+'1'].interpolate(timestep).values[begin_idx:end_idx]*180/3.14, label=name + ' DP backshift', linestyle='--')\n",
" plt.plot(ts_emt3ph_TrStab_dl[name+'1'].interpolate(timestep).time[begin_idx:end_idx], ts_emt3ph_TrStab_dl[name+'2'].interpolate(timestep).values[begin_idx:end_idx]*180/3.14 - ts_emt3ph_TrStab_dl[name+'1'].interpolate(timestep).values[begin_idx:end_idx]*180/3.14, label=name + ' EMT')\n",
"plt.legend()"
]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently, the SynGenTrStab notebooks do no include any assert statements for validation. Can't this be changed? E.g. by performing cross-domain validations

Comment on lines +262 to +265
if (mConvertWithOmegaMech)
dOmMech = mNomOmega*mNomOmega / (2.* (**mInertia) * mNomPower * (**mOmMech)) * (**mMechPower - **mElecActivePower - mKd*(**mOmMech - mNomOmega));
else
dOmMech = mNomOmega / (2. * **mInertia * mNomPower) * (**mMechPower - **mElecActivePower - mKd*(**mOmMech - mNomOmega));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As follow-up of this PR, the swing equation could be aggregated instead to make this feature also available to other synchronous generator models. Issue #235 is opened up for that

@gnakti gnakti assigned gnakti and unassigned dinkelbachjan May 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
Status: Ready for Review
Development

Successfully merging this pull request may close these issues.

2 participants