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

Eigenvalues #262

Draft
wants to merge 13 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ if(MSVC)

# Silence Visual Studio error C2220
add_definitions(-D_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING)

add_compile_options(/bigobj) # Fixes error C1128 for compiling MNAEigenvalueExtractor with MSVC compiler.

# Set exception handling for portability
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc")
Expand Down
43 changes: 43 additions & 0 deletions docs/hugo/content/en/docs/Overview/eigenvalues.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
title: "Eigenvalues"
linkTitle: "Eigenvalues"
date: 2024-03-20
---

In parallel to simulating a power system, DPsim allows to extract eigenvalues of the power system state-space model's state matrix for each simulation time step. Eigenvalue extraction can be enabled for a ``Simulation``.



## Equations
``discreteEigenvalues`` $\mathbf{z}$ are computed from discretized state matrix $A_{d}$, that in EMT domain is calculated from:

$$
\mathbf{A}_{d}=\mathbf{S}-\mathbf{G}_{b}\mathbf{A}_{bn}\mathbf{G}^{-1} \mathbf{A}_{nb}
$$

where $\mathbf{S}$ is a sign matrix, $\mathbf{G}_{b}$ is a discretization matrix, $\mathbf{G}$ is a Modified Nodal Analysis (MNA) power system conductance matrix, $\mathbf{A}_{bn}$ and $\mathbf{A}_{nb}$ are <i>branch x node</i> and <i>node x branch</i> incidence matrices respectively.

The MNA power system conductance matrix $\mathbf{G}$ is available from power system MNA model. To prepare the rest of the matrices, each power system component needs to be stamped into $\mathbf{A}_{bn}$ and $\mathbf{A}_{nb}$, while dynamic components also need to be stamped into $\mathbf{S}$ and $\mathbf{G}_{b}$ matrices.


``eigenvalues`` $\mathbf{\lambda}$ of the time-continuous state-space model matrix $A$ can then be calculated from ``discreteEigenvalues`` $\mathbf{z}$. Assuming the Trapezoidal rule of discretization in EMT domain, the equation is:

$$
\mathbf{\lambda}=\frac{2}{\Delta t} \frac{\mathbf{z} - 1}{\mathbf{z} + 1}
$$


## Implementation

The ``MNAEigenvalueExtractor`` class is a template class responsible for extracting eigenvalues.
The ``EigenvalueCompInterface`` is interface to be implemented by all components participating in eigenvalue extraction. The ``EigenvalueDynamicCompInterface`` is interface to be implemented by all _dynamic_ components participating in eigenvalue extraction. These interfaces provide the signatures of the functions that are used to stamp a component into the matrices $\mathbf{A}_{bn}$, $\mathbf{A}_{nb}$, $\mathbf{S}$ and $\mathbf{G}_{b}$.

The table below provides an overview of the components, that support eigenvalue extraction in EMT and in DP domains:

| Component |Is dynamic?| EMT domain, Ph1 | DP domain, Ph1 |
| -------- |-------- | -------- | -------- |
| ``Resistor`` |&mdash;| &#x2714; | &#x2714; |
| ``Inductor`` |&#x2714;| &#x2714; | &#x2714; |
| ``Capacitor`` |&#x2714;| &#x2714; | &#x2714; |
| ``Switch`` |&mdash;| &mdash; | &#x2714; |
| ``VoltageSource`` |&mdash;| &#x2714; | &#x2714; |
13 changes: 12 additions & 1 deletion dpsim-models/include/dpsim-models/DP/DP_Ph1_Capacitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include <dpsim-models/Base/Base_Ph1_Capacitor.h>
#include <dpsim-models/MNASimPowerComp.h>
#include <dpsim-models/Solver/EigenvalueDynamicCompInterface.h>

namespace CPS {
namespace DP {
Expand All @@ -23,7 +24,8 @@ namespace Ph1 {
/// frequency and the current source changes for each iteration.
class Capacitor : public MNASimPowerComp<Complex>,
public Base::Ph1::Capacitor,
public SharedFactory<Capacitor> {
public SharedFactory<Capacitor>,
public EigenvalueDynamicCompInterface<Complex> {
protected:
/// DC equivalent current source for harmonics [A]
MatrixComp mEquivCurrent;
Expand Down Expand Up @@ -119,6 +121,15 @@ class Capacitor : public MNASimPowerComp<Complex>,
Capacitor &mCapacitor;
std::vector<Attribute<Matrix>::Ptr> mLeftVectors;
};

// #### Implementation of eigenvalue dynamic component interface ####
void stampSignMatrix(UInt branchIdx, MatrixVar<Complex> &signMatrix,
Complex coeffDP) final;
void stampDiscretizationMatrix(UInt branchIdx,
MatrixVar<Complex> &discretizationMatrix,
Complex coeffDP) final;
void stampBranchNodeIncidenceMatrix(UInt branchIdx,
Matrix &branchNodeIncidenceMatrix) final;
};
} // namespace Ph1
} // namespace DP
Expand Down
13 changes: 12 additions & 1 deletion dpsim-models/include/dpsim-models/DP/DP_Ph1_Inductor.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include <dpsim-models/Base/Base_Ph1_Inductor.h>
#include <dpsim-models/MNASimPowerComp.h>
#include <dpsim-models/Solver/EigenvalueDynamicCompInterface.h>
#include <dpsim-models/Solver/MNATearInterface.h>

namespace CPS {
Expand All @@ -25,7 +26,8 @@ namespace Ph1 {
class Inductor : public MNASimPowerComp<Complex>,
public Base::Ph1::Inductor,
public MNATearInterface,
public SharedFactory<Inductor> {
public SharedFactory<Inductor>,
public EigenvalueDynamicCompInterface<Complex> {
protected:
/// DC equivalent current source for harmonics [A]
MatrixComp mEquivCurrent;
Expand Down Expand Up @@ -127,6 +129,15 @@ class Inductor : public MNASimPowerComp<Complex>,
Inductor &mInductor;
std::vector<Attribute<Matrix>::Ptr> mLeftVectors;
};

// #### Implementation of eigenvalue dynamic component interface ####
void stampSignMatrix(UInt branchIdx, MatrixVar<Complex> &signMatrix,
Complex coeffDP) final;
void stampDiscretizationMatrix(UInt branchIdx,
MatrixVar<Complex> &discretizationMatrix,
Complex coeffDP) final;
void stampBranchNodeIncidenceMatrix(UInt branchIdx,
Matrix &branchNodeIncidenceMatrix) final;
};
} // namespace Ph1
} // namespace DP
Expand Down
35 changes: 21 additions & 14 deletions dpsim-models/include/dpsim-models/DP/DP_Ph1_Resistor.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <dpsim-models/Base/Base_Ph1_Resistor.h>
#include <dpsim-models/MNASimPowerComp.h>
#include <dpsim-models/Solver/DAEInterface.h>
#include <dpsim-models/Solver/EigenvalueCompInterface.h>
#include <dpsim-models/Solver/MNATearInterface.h>

namespace CPS {
Expand All @@ -21,7 +22,8 @@ class Resistor : public MNASimPowerComp<Complex>,
public Base::Ph1::Resistor,
public MNATearInterface,
public DAEInterface,
public SharedFactory<Resistor> {
public SharedFactory<Resistor>,
public EigenvalueCompInterface {
public:
/// Defines UID, name and logging level
Resistor(String uid, String name,
Expand All @@ -30,37 +32,38 @@ class Resistor : public MNASimPowerComp<Complex>,
Resistor(String name, Logger::Level logLevel = Logger::Level::off)
: Resistor(name, name, logLevel) {}

SimPowerComp<Complex>::Ptr clone(String name);
SimPowerComp<Complex>::Ptr clone(String name) override;

// #### General ####
/// Initializes component from power flow data
void initializeFromNodesAndTerminals(Real frequency);
void initializeFromNodesAndTerminals(Real frequency) override;

// #### MNA section ####
void mnaCompInitialize(Real omega, Real timeStep,
Attribute<Matrix>::Ptr leftVector);
void mnaCompInitializeHarm(Real omega, Real timeStep,
std::vector<Attribute<Matrix>::Ptr> leftVector);
Attribute<Matrix>::Ptr leftVector) override;
void mnaCompInitializeHarm(
Real omega, Real timeStep,
std::vector<Attribute<Matrix>::Ptr> leftVector) override;
/// Stamps system matrix
void mnaCompApplySystemMatrixStamp(SparseMatrixRow &systemMatrix);
void mnaCompApplySystemMatrixStamp(SparseMatrixRow &systemMatrix) override;
/// Stamps system matrix considering the frequency index
void mnaCompApplySystemMatrixStampHarm(SparseMatrixRow &systemMatrix,
Int freqIdx);
Int freqIdx) override;
/// Update interface voltage from MNA system result
void mnaCompUpdateVoltage(const Matrix &leftVector);
void mnaCompUpdateVoltage(const Matrix &leftVector) override;
void mnaCompUpdateVoltageHarm(const Matrix &leftVector, Int freqIdx);
/// Update interface current from MNA system result
void mnaCompUpdateCurrent(const Matrix &leftVector);
void mnaCompUpdateCurrent(const Matrix &leftVector) override;
void mnaCompUpdateCurrentHarm();
/// MNA pre and post step operations
void mnaCompPostStep(Real time, Int timeStepCount,
Attribute<Matrix>::Ptr &leftVector);
Attribute<Matrix>::Ptr &leftVector) override;
/// add MNA pre and post step dependencies
void
mnaCompAddPostStepDependencies(AttributeBase::List &prevStepDependencies,
AttributeBase::List &attributeDependencies,
AttributeBase::List &modifiedAttributes,
Attribute<Matrix>::Ptr &leftVector);
Attribute<Matrix>::Ptr &leftVector) override;

class MnaPostStepHarm : public Task {
public:
Expand All @@ -86,9 +89,13 @@ class Resistor : public MNASimPowerComp<Complex>,
// #### DAE Section ####
///Residual Function for DAE Solver
void daeResidual(double ttime, const double state[], const double dstate_dt[],
double resid[], std::vector<int> &off);
double resid[], std::vector<int> &off) override;
///Voltage Getter
Complex daeInitialize();
Complex daeInitialize() override;

// #### Implementation of eigenvalue component interface ####
void stampBranchNodeIncidenceMatrix(UInt branchIdx,
Matrix &branchNodeIncidenceMatrix) final;
};
} // namespace Ph1
} // namespace DP
Expand Down
30 changes: 18 additions & 12 deletions dpsim-models/include/dpsim-models/DP/DP_Ph1_Switch.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <dpsim-models/Definitions.h>
#include <dpsim-models/Logger.h>
#include <dpsim-models/MNASimPowerComp.h>
#include <dpsim-models/Solver/EigenvalueCompInterface.h>
#include <dpsim-models/Solver/MNAInterface.h>
#include <dpsim-models/Solver/MNASwitchInterface.h>

Expand All @@ -25,7 +26,8 @@ namespace Ph1 {
class Switch : public MNASimPowerComp<Complex>,
public Base::Ph1::Switch,
public SharedFactory<Switch>,
public MNASwitchInterface {
public MNASwitchInterface,
public EigenvalueCompInterface {
protected:
public:
/// Defines UID, name, component parameters and logging level
Expand All @@ -34,40 +36,44 @@ class Switch : public MNASimPowerComp<Complex>,
Switch(String name, Logger::Level logLevel = Logger::Level::off)
: Switch(name, name, logLevel) {}

SimPowerComp<Complex>::Ptr clone(String name);
SimPowerComp<Complex>::Ptr clone(String name) override;

// #### General ####
/// Initializes component from power flow data
void initializeFromNodesAndTerminals(Real frequency);
void initializeFromNodesAndTerminals(Real frequency) override;

// #### General MNA section ####
void mnaCompInitialize(Real omega, Real timeStep,
Attribute<Matrix>::Ptr leftVector);
Attribute<Matrix>::Ptr leftVector) override;
/// Stamps system matrix
void mnaCompApplySystemMatrixStamp(SparseMatrixRow &systemMatrix);
void mnaCompApplySystemMatrixStamp(SparseMatrixRow &systemMatrix) override;
/// Stamps right side (source) vector
void mnaCompApplyRightSideVectorStamp(Matrix &rightVector);
void mnaCompApplyRightSideVectorStamp(Matrix &rightVector) override;
/// Update interface voltage from MNA system result
void mnaCompUpdateVoltage(const Matrix &leftVector);
void mnaCompUpdateVoltage(const Matrix &leftVector) override;
/// Update interface current from MNA system result
void mnaCompUpdateCurrent(const Matrix &leftVector);
void mnaCompUpdateCurrent(const Matrix &leftVector) override;
/// MNA post step operations
void mnaCompPostStep(Real time, Int timeStepCount,
Attribute<Matrix>::Ptr &leftVector);
Attribute<Matrix>::Ptr &leftVector) override;
/// Add MNA post step dependencies
void
mnaCompAddPostStepDependencies(AttributeBase::List &prevStepDependencies,
AttributeBase::List &attributeDependencies,
AttributeBase::List &modifiedAttributes,
Attribute<Matrix>::Ptr &leftVector);
Attribute<Matrix>::Ptr &leftVector) override;

// #### MNA section for switch ####
/// Check if switch is closed
Bool mnaIsClosed();
Bool mnaIsClosed() override;
/// Stamps system matrix considering the defined switch position
void mnaCompApplySwitchSystemMatrixStamp(Bool closed,
SparseMatrixRow &systemMatrix,
Int freqIdx);
Int freqIdx) override;

// #### Implementation of eigenvalue component interface ####
void stampBranchNodeIncidenceMatrix(UInt branchIdx,
Matrix &branchNodeIncidenceMatrix) final;
};
} // namespace Ph1
} // namespace DP
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <dpsim-models/Signal/SignalGenerator.h>
#include <dpsim-models/Signal/SineWaveGenerator.h>
#include <dpsim-models/Solver/DAEInterface.h>
#include <dpsim-models/Solver/EigenvalueCompInterface.h>
#include <dpsim-models/Solver/MNAInterface.h>

namespace CPS {
Expand All @@ -38,7 +39,8 @@ namespace Ph1 {
/// a new equation ej - ek = V is added to the problem.
class VoltageSource : public MNASimPowerComp<Complex>,
public DAEInterface,
public SharedFactory<VoltageSource> {
public SharedFactory<VoltageSource>,
public EigenvalueCompInterface {
private:
///
void updateVoltage(Real time);
Expand Down Expand Up @@ -151,6 +153,10 @@ class VoltageSource : public MNASimPowerComp<Complex>,
double resid[], std::vector<int> &off) override;
///Voltage Getter
Complex daeInitialize() override;

// #### Implementation of eigenvalue component interface ####
void stampBranchNodeIncidenceMatrix(UInt branchIdx,
Matrix &branchNodeIncidenceMatrix) final;
};
} // namespace Ph1
} // namespace DP
Expand Down
13 changes: 12 additions & 1 deletion dpsim-models/include/dpsim-models/EMT/EMT_Ph1_Capacitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include <dpsim-models/Base/Base_Ph1_Capacitor.h>
#include <dpsim-models/MNASimPowerComp.h>
#include <dpsim-models/Solver/EigenvalueDynamicCompInterface.h>
#include <dpsim-models/Solver/MNAInterface.h>

namespace CPS {
Expand All @@ -24,7 +25,8 @@ namespace Ph1 {
///frequency and the current source changes for each iteration.
class Capacitor : public MNASimPowerComp<Real>,
public Base::Ph1::Capacitor,
public SharedFactory<Capacitor> {
public SharedFactory<Capacitor>,
public EigenvalueDynamicCompInterface<Real> {
protected:
/// DC equivalent current source [A]
Real mEquivCurrent;
Expand Down Expand Up @@ -73,6 +75,15 @@ class Capacitor : public MNASimPowerComp<Real>,
AttributeBase::List &attributeDependencies,
AttributeBase::List &modifiedAttributes,
Attribute<Matrix>::Ptr &leftVector) override;

// #### Implementation of eigenvalue dynamic component interface ####
void stampSignMatrix(UInt branchIdx, MatrixVar<Real> &signMatrix,
Complex coeffDP) final;
void stampDiscretizationMatrix(UInt branchIdx,
MatrixVar<Real> &discretizationMatrix,
Complex coeffDP) final;
void stampBranchNodeIncidenceMatrix(UInt branchIdx,
Matrix &branchNodeIncidenceMatrix) final;
};
} // namespace Ph1
} // namespace EMT
Expand Down
13 changes: 12 additions & 1 deletion dpsim-models/include/dpsim-models/EMT/EMT_Ph1_Inductor.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include <dpsim-models/Base/Base_Ph1_Inductor.h>
#include <dpsim-models/MNASimPowerComp.h>
#include <dpsim-models/Solver/EigenvalueDynamicCompInterface.h>
#include <dpsim-models/Solver/MNAInterface.h>

namespace CPS {
Expand All @@ -24,7 +25,8 @@ namespace Ph1 {
/// frequency and the current source changes for each iteration.
class Inductor : public MNASimPowerComp<Real>,
public Base::Ph1::Inductor,
public SharedFactory<Inductor> {
public SharedFactory<Inductor>,
public EigenvalueDynamicCompInterface<Real> {
protected:
/// DC equivalent current source [A]
Real mEquivCurrent;
Expand Down Expand Up @@ -74,6 +76,15 @@ class Inductor : public MNASimPowerComp<Real>,
AttributeBase::List &attributeDependencies,
AttributeBase::List &modifiedAttributes,
Attribute<Matrix>::Ptr &leftVector) override;

// #### Implementation of eigenvalue dynamic component interface ####
void stampSignMatrix(UInt branchIdx, MatrixVar<Real> &signMatrix,
Complex coeffDP) final;
void stampDiscretizationMatrix(UInt branchIdx,
MatrixVar<Real> &discretizationMatrix,
Complex coeffDP) final;
void stampBranchNodeIncidenceMatrix(UInt branchIdx,
Matrix &branchNodeIncidenceMatrix) final;
};
} // namespace Ph1
} // namespace EMT
Expand Down
Loading
Loading