Skip to content

Commit

Permalink
Reuse stamp code for EMT synchron. generators (#315)
Browse files Browse the repository at this point in the history
### Summary
This PR fixes and extends functionality of `MNAStampUtils` and reuses
the stamping logic for EMT synchronous generators.

### Details

- **MNAStampUtils: Fix stamping of full matrices (i.e., matrices with
non-zero off-diagonal elements)**
The incorrect logic for full matrices in `MNAStampUtils` was not
previously recognized because 3-phase components that already used
`MNAStampUtils` (i.e. 3-phase R, L, C components) do not have coupling
between the phases (their conductance matrix is diagonal). The incorrect
logic became apparent when the code was reused for stamping synchronous
generator's conductance matrix.
- **MNAStampUtils: add matrix stamp functions with optimized logic**
Added functions `stamp3x3ConductanceMatrixBetween2Nodes` and
`stamp3x3ConductanceMatrixNodeToGround,` that do not check if a terminal
is grounded. This check is usually skipped in components, implementing
`MNAVariableCompInterface`.
- **Reuse conductance stamping logic for EMT synchronous generators**
The commit does not include `EMT_Ph3_SynchronGeneratorDQ`. Conductance
stamping is never called in `EMT_Ph3_SynchronGeneratorDQ,` due to
hard-coded `mCompensationOn` data member. Therefore, it is not covered
by tests and examples.

### Related work
- **Issue Reference**: These changes were discussed in an issue:
#288
- **Previous PR**: This PR continues the work of:
#306
- **Future Plans**: There are plans for future PRs to reuse stamp code
for other components deriving from the `MNASimPowerComp` class.
  • Loading branch information
m-mirz authored Jul 21, 2024
2 parents 204eb27 + c06b0e9 commit ce74d8e
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 230 deletions.
42 changes: 25 additions & 17 deletions dpsim-models/include/dpsim-models/MNAStampUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,15 @@ class MNAStampUtils {
Bool isTerminal2NotGrounded,
const Logger::Log &mSLog);

static void stamp3x3ConductanceMatrixBetween2Nodes(
const Matrix &conductanceMat, SparseMatrixRow &mat, UInt node1Index,
UInt node2Index, const Logger::Log &mSLog);

static void stamp3x3ConductanceMatrixNodeToGround(const Matrix &conductanceMat,
SparseMatrixRow &mat,
UInt nodeIndex,
const Logger::Log &mSLog);

static void stampAdmittanceMatrix(
const MatrixComp &admittanceMat, SparseMatrixRow &mat, UInt node1Index,
UInt node2Index, Bool isTerminal1NotGrounded, Bool isTerminal2NotGrounded,
Expand Down Expand Up @@ -57,6 +66,19 @@ class MNAStampUtils {
Bool isTerminal2NotGrounded, Int maxFreq, Int freqIdx,
const Logger::Log &mSLog);

template <typename T>
static void stampMatrixBetween2Nodes(const MatrixVar<T> &matrix,
UInt sizeOfMatrix, SparseMatrixRow &mat,
UInt node1Index, UInt node2Index,
Int maxFreq, Int freqIdx,
const Logger::Log &mSLog);

template <typename T>
static void stampMatrixNodeToGround(const MatrixVar<T> &matrix,
UInt sizeOfMatrix, SparseMatrixRow &mat,
UInt nodeIndex, Int maxFreq, Int freqIdx,
const Logger::Log &mSLog);

template <typename T>
static void stampValueAsScalarMatrix(T value, UInt sizeOfScalarMatrix,
SparseMatrixRow &mat, UInt node1Index,
Expand All @@ -66,23 +88,9 @@ class MNAStampUtils {
Int freqIdx, const Logger::Log &mSLog);

template <typename T>
static void stampValueNoConditions(T value, SparseMatrixRow &mat,
UInt node1Index, UInt node2Index,
Int maxFreq, Int freqIdx,
const Logger::Log &mSLog);

template <typename T>
static void stampValueOnDiagonalNoConditions(T value, SparseMatrixRow &mat,
UInt nodeIndex, Int maxFreq,
Int freqIdx,
const Logger::Log &mSLog);

template <typename T>
static void stampValueOffDiagonalNoConditions(T value, SparseMatrixRow &mat,
UInt node1Index,
UInt node2Index, Int maxFreq,
Int freqIdx,
const Logger::Log &mSLog);
static void stampToMatrix(T value, SparseMatrixRow &mat, UInt row1,
UInt column1, UInt row2, UInt column2, Int maxFreq,
Int freqIdx, const Logger::Log &mSLog);

static void addToMatrixElement(SparseMatrixRow &mat, Matrix::Index row,
Matrix::Index column, Real value, Int maxFreq,
Expand Down
140 changes: 6 additions & 134 deletions dpsim-models/src/EMT/EMT_Ph3_ReducedOrderSynchronGeneratorVBR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,25 +184,8 @@ void EMT::Ph3::ReducedOrderSynchronGeneratorVBR::mnaCompApplySystemMatrixStamp(
SparseMatrixRow &systemMatrix) {

if (mModelAsNortonSource) {
// Stamp conductance matrix
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 0),
matrixNodeIndex(0, 0), mConductanceMatrix(0, 0));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 0),
matrixNodeIndex(0, 1), mConductanceMatrix(0, 1));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 0),
matrixNodeIndex(0, 2), mConductanceMatrix(0, 2));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 1),
matrixNodeIndex(0, 0), mConductanceMatrix(1, 0));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 1),
matrixNodeIndex(0, 1), mConductanceMatrix(1, 1));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 1),
matrixNodeIndex(0, 2), mConductanceMatrix(1, 2));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 2),
matrixNodeIndex(0, 0), mConductanceMatrix(2, 0));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 2),
matrixNodeIndex(0, 1), mConductanceMatrix(2, 1));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 2),
matrixNodeIndex(0, 2), mConductanceMatrix(2, 2));
MNAStampUtils::stamp3x3ConductanceMatrixNodeToGround(
mConductanceMatrix, systemMatrix, matrixNodeIndex(0), mSLog);
} else {
// Stamp voltage source
Math::addToMatrixElement(
Expand All @@ -225,121 +208,10 @@ void EMT::Ph3::ReducedOrderSynchronGeneratorVBR::mnaCompApplySystemMatrixStamp(
mVirtualNodes[0]->matrixNodeIndex(PhaseType::C), 1);

// Stamp conductance matrix

// set upper left block, 3x3 entries
Math::addToMatrixElement(systemMatrix,
mVirtualNodes[0]->matrixNodeIndex(PhaseType::A),
mVirtualNodes[0]->matrixNodeIndex(PhaseType::A),
mConductanceMatrix(0, 0));
Math::addToMatrixElement(systemMatrix,
mVirtualNodes[0]->matrixNodeIndex(PhaseType::A),
mVirtualNodes[0]->matrixNodeIndex(PhaseType::B),
mConductanceMatrix(0, 1));
Math::addToMatrixElement(systemMatrix,
mVirtualNodes[0]->matrixNodeIndex(PhaseType::A),
mVirtualNodes[0]->matrixNodeIndex(PhaseType::C),
mConductanceMatrix(0, 2));
Math::addToMatrixElement(systemMatrix,
mVirtualNodes[0]->matrixNodeIndex(PhaseType::B),
mVirtualNodes[0]->matrixNodeIndex(PhaseType::A),
mConductanceMatrix(1, 0));
Math::addToMatrixElement(systemMatrix,
mVirtualNodes[0]->matrixNodeIndex(PhaseType::B),
mVirtualNodes[0]->matrixNodeIndex(PhaseType::B),
mConductanceMatrix(1, 1));
Math::addToMatrixElement(systemMatrix,
mVirtualNodes[0]->matrixNodeIndex(PhaseType::B),
mVirtualNodes[0]->matrixNodeIndex(PhaseType::C),
mConductanceMatrix(1, 2));
Math::addToMatrixElement(systemMatrix,
mVirtualNodes[0]->matrixNodeIndex(PhaseType::C),
mVirtualNodes[0]->matrixNodeIndex(PhaseType::A),
mConductanceMatrix(2, 0));
Math::addToMatrixElement(systemMatrix,
mVirtualNodes[0]->matrixNodeIndex(PhaseType::C),
mVirtualNodes[0]->matrixNodeIndex(PhaseType::B),
mConductanceMatrix(2, 1));
Math::addToMatrixElement(systemMatrix,
mVirtualNodes[0]->matrixNodeIndex(PhaseType::C),
mVirtualNodes[0]->matrixNodeIndex(PhaseType::C),
mConductanceMatrix(2, 2));

// set buttom right block, 3x3 entries
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 0),
matrixNodeIndex(0, 0), mConductanceMatrix(0, 0));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 0),
matrixNodeIndex(0, 1), mConductanceMatrix(0, 1));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 0),
matrixNodeIndex(0, 2), mConductanceMatrix(0, 2));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 1),
matrixNodeIndex(0, 0), mConductanceMatrix(1, 0));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 1),
matrixNodeIndex(0, 1), mConductanceMatrix(1, 1));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 1),
matrixNodeIndex(0, 2), mConductanceMatrix(1, 2));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 2),
matrixNodeIndex(0, 0), mConductanceMatrix(2, 0));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 2),
matrixNodeIndex(0, 1), mConductanceMatrix(2, 1));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 2),
matrixNodeIndex(0, 2), mConductanceMatrix(2, 2));

// Set off diagonal blocks
Math::addToMatrixElement(systemMatrix,
mVirtualNodes[0]->matrixNodeIndex(PhaseType::A),
matrixNodeIndex(0, 0), -mConductanceMatrix(0, 0));
Math::addToMatrixElement(systemMatrix,
mVirtualNodes[0]->matrixNodeIndex(PhaseType::A),
matrixNodeIndex(0, 1), -mConductanceMatrix(0, 1));
Math::addToMatrixElement(systemMatrix,
mVirtualNodes[0]->matrixNodeIndex(PhaseType::A),
matrixNodeIndex(0, 2), -mConductanceMatrix(0, 2));
Math::addToMatrixElement(systemMatrix,
mVirtualNodes[0]->matrixNodeIndex(PhaseType::B),
matrixNodeIndex(0, 0), -mConductanceMatrix(1, 0));
Math::addToMatrixElement(systemMatrix,
mVirtualNodes[0]->matrixNodeIndex(PhaseType::B),
matrixNodeIndex(0, 1), -mConductanceMatrix(1, 1));
Math::addToMatrixElement(systemMatrix,
mVirtualNodes[0]->matrixNodeIndex(PhaseType::B),
matrixNodeIndex(0, 2), -mConductanceMatrix(1, 2));
Math::addToMatrixElement(systemMatrix,
mVirtualNodes[0]->matrixNodeIndex(PhaseType::C),
matrixNodeIndex(0, 0), -mConductanceMatrix(2, 0));
Math::addToMatrixElement(systemMatrix,
mVirtualNodes[0]->matrixNodeIndex(PhaseType::C),
matrixNodeIndex(0, 1), -mConductanceMatrix(2, 1));
Math::addToMatrixElement(systemMatrix,
mVirtualNodes[0]->matrixNodeIndex(PhaseType::C),
matrixNodeIndex(0, 2), -mConductanceMatrix(2, 2));

Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 0),
mVirtualNodes[0]->matrixNodeIndex(PhaseType::A),
-mConductanceMatrix(0, 0));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 0),
mVirtualNodes[0]->matrixNodeIndex(PhaseType::B),
-mConductanceMatrix(0, 1));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 0),
mVirtualNodes[0]->matrixNodeIndex(PhaseType::C),
-mConductanceMatrix(0, 2));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 1),
mVirtualNodes[0]->matrixNodeIndex(PhaseType::A),
-mConductanceMatrix(1, 0));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 1),
mVirtualNodes[0]->matrixNodeIndex(PhaseType::B),
-mConductanceMatrix(1, 1));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 1),
mVirtualNodes[0]->matrixNodeIndex(PhaseType::C),
-mConductanceMatrix(1, 2));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 2),
mVirtualNodes[0]->matrixNodeIndex(PhaseType::A),
-mConductanceMatrix(2, 0));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 2),
mVirtualNodes[0]->matrixNodeIndex(PhaseType::B),
-mConductanceMatrix(2, 1));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 2),
mVirtualNodes[0]->matrixNodeIndex(PhaseType::C),
-mConductanceMatrix(2, 2));
MNAStampUtils::stamp3x3ConductanceMatrixBetween2Nodes(
mConductanceMatrix, systemMatrix,
mVirtualNodes[0]->matrixNodeIndex(PhaseType::A), matrixNodeIndex(0),
mSLog);
}
}

Expand Down
23 changes: 2 additions & 21 deletions dpsim-models/src/EMT/EMT_Ph3_SynchronGeneratorVBR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,27 +258,8 @@ void EMT::Ph3::SynchronGeneratorVBR::mnaCompPreStep(Real time,
void EMT::Ph3::SynchronGeneratorVBR::mnaCompApplySystemMatrixStamp(
SparseMatrixRow &systemMatrix) {
if (terminalNotGrounded(0)) {
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 0),
matrixNodeIndex(0, 0), mConductanceMat(0, 0));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 0),
matrixNodeIndex(0, 1), mConductanceMat(0, 1));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 0),
matrixNodeIndex(0, 2), mConductanceMat(0, 2));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 1),
matrixNodeIndex(0, 0), mConductanceMat(1, 0));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 1),
matrixNodeIndex(0, 1), mConductanceMat(1, 1));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 1),
matrixNodeIndex(0, 2), mConductanceMat(1, 2));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 2),
matrixNodeIndex(0, 0), mConductanceMat(2, 0));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 2),
matrixNodeIndex(0, 1), mConductanceMat(2, 1));
Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 2),
matrixNodeIndex(0, 2), mConductanceMat(2, 2));
// SPDLOG_LOGGER_INFO(mSLog, "Add {} to {}, {}", conductance, matrixNodeIndex(0,0), matrixNodeIndex(0,0));
// SPDLOG_LOGGER_INFO(mSLog, "Add {} to {}, {}", conductance, matrixNodeIndex(0,1), matrixNodeIndex(0,1));
// SPDLOG_LOGGER_INFO(mSLog, "Add {} to {}, {}", conductance, matrixNodeIndex(0,2), matrixNodeIndex(0,2));
MNAStampUtils::stamp3x3ConductanceMatrixNodeToGround(
mConductanceMat, systemMatrix, matrixNodeIndex(0), mSLog);
}
}

Expand Down
Loading

0 comments on commit ce74d8e

Please sign in to comment.