4#include <dpsim/MNAStateSpaceContributor.h>
6#include <dpsim-models/EMT/EMT_Ph3_Capacitor.h>
7#include <dpsim-models/EMT/EMT_Ph3_Inductor.h>
8#include <dpsim-models/EMT/EMT_Ph3_Resistor.h>
9#include <dpsim-models/EMT/EMT_Ph3_TwoTerminalVTypeSSNComp.h>
10#include <dpsim-models/EMT/EMT_Ph3_VoltageSource.h>
11#include <dpsim-models/SimPowerComp.h>
12#include <dpsim-models/Solver/MNAVariableCompInterface.h>
22using SimPowerCompReal = CPS::SimPowerComp<CPS::Real>;
26Matrix buildTwoTerminalInterfaceVoltageMapping(SimPowerCompReal &component,
28 Matrix K = Matrix::Zero(3, mnaVectorSize);
30 if (component.terminalNotGrounded(1)) {
31 for (UInt phase = 0; phase < 3; ++phase)
32 K(phase, component.matrixNodeIndex(1, phase)) = 1.0;
35 if (component.terminalNotGrounded(0)) {
36 for (UInt phase = 0; phase < 3; ++phase)
37 K(phase, component.matrixNodeIndex(0, phase)) = -1.0;
47void stampTwoTerminalCurrentInjectionMapping(
const Matrix &K, Matrix &CdMna,
49 const Matrix &outputMatrix) {
50 CdMna.block(0, stateOffset, CdMna.rows(), outputMatrix.cols()) +=
51 -K.transpose() * outputMatrix;
54Bool isVariableMNAComponent(
const MNAInterface::Ptr &component) {
55 return std::dynamic_pointer_cast<MNAVariableCompInterface>(component) !=
59class EMTPh3InductorStateSpaceContributor final
62 explicit EMTPh3InductorStateSpaceContributor(
63 std::shared_ptr<EMT::Ph3::Inductor> component)
64 : mComponent(std::move(component)) {}
66 UInt getStateCount()
const override {
return 3; }
68 void stamp(Matrix &AdLocal, Matrix &BdMna, Matrix &CdMna, UInt stateOffset,
69 UInt mnaVectorSize)
const override {
70 const Matrix &conductance = mComponent->getMNAConductance();
73 buildTwoTerminalInterfaceVoltageMapping(*mComponent, mnaVectorSize);
79 AdLocal.block(stateOffset, stateOffset, 3, 3) += Matrix::Identity(3, 3);
81 BdMna.block(stateOffset, 0, 3, mnaVectorSize) += 2.0 * conductance * K;
83 stampTwoTerminalCurrentInjectionMapping(K, CdMna, stateOffset,
84 Matrix::Identity(3, 3));
88 std::shared_ptr<EMT::Ph3::Inductor> mComponent;
91class EMTPh3CapacitorStateSpaceContributor final
94 explicit EMTPh3CapacitorStateSpaceContributor(
95 std::shared_ptr<EMT::Ph3::Capacitor> component)
96 : mComponent(std::move(component)) {}
98 UInt getStateCount()
const override {
return 3; }
100 void stamp(Matrix &AdLocal, Matrix &BdMna, Matrix &CdMna, UInt stateOffset,
101 UInt mnaVectorSize)
const override {
102 const Matrix &conductance = mComponent->getMNAConductance();
105 buildTwoTerminalInterfaceVoltageMapping(*mComponent, mnaVectorSize);
111 AdLocal.block(stateOffset, stateOffset, 3, 3) -= Matrix::Identity(3, 3);
113 BdMna.block(stateOffset, 0, 3, mnaVectorSize) -= 2.0 * conductance * K;
115 stampTwoTerminalCurrentInjectionMapping(K, CdMna, stateOffset,
116 Matrix::Identity(3, 3));
120 std::shared_ptr<EMT::Ph3::Capacitor> mComponent;
123class EMTPh3TwoTerminalVTypeSSNStateSpaceContributor final
126 EMTPh3TwoTerminalVTypeSSNStateSpaceContributor(
127 std::shared_ptr<EMT::Ph3::TwoTerminalVTypeSSNComp> component,
129 : mComponent(std::move(component)), mIsVariable(isVariable) {}
131 UInt getStateCount()
const override {
return mComponent->getStateCount(); }
133 Bool isVariable()
const override {
return mIsVariable; }
135 void stamp(Matrix &AdLocal, Matrix &BdMna, Matrix &CdMna, UInt stateOffset,
136 UInt mnaVectorSize)
const override {
137 const UInt localStateCount = getStateCount();
139 const Matrix &discreteA = mComponent->getDiscreteA();
140 const Matrix &discreteB = mComponent->getDiscreteB();
141 const Matrix &outputC = mComponent->getC();
144 buildTwoTerminalInterfaceVoltageMapping(*mComponent, mnaVectorSize);
151 AdLocal.block(stateOffset, stateOffset, localStateCount, localStateCount) +=
154 const Matrix inputUpdate =
155 (discreteA + Matrix::Identity(localStateCount, localStateCount)) *
158 BdMna.block(stateOffset, 0, localStateCount, mnaVectorSize) +=
161 stampTwoTerminalCurrentInjectionMapping(K, CdMna, stateOffset, outputC);
165 std::shared_ptr<EMT::Ph3::TwoTerminalVTypeSSNComp> mComponent;
166 Bool mIsVariable =
false;
171MNAStateSpaceContributor::Ptr
172MNAStateSpaceContributorFactory::create(
const MNAInterface::Ptr &component) {
177 std::dynamic_pointer_cast<EMT::Ph3::Inductor>(component)) {
178 return std::make_shared<EMTPh3InductorStateSpaceContributor>(inductor);
182 std::dynamic_pointer_cast<EMT::Ph3::Capacitor>(component)) {
183 return std::make_shared<EMTPh3CapacitorStateSpaceContributor>(capacitor);
186 if (
auto ssn = std::dynamic_pointer_cast<EMT::Ph3::TwoTerminalVTypeSSNComp>(
188 return std::make_shared<EMTPh3TwoTerminalVTypeSSNStateSpaceContributor>(
189 ssn, isVariableMNAComponent(component));
192 if (std::dynamic_pointer_cast<EMT::Ph3::Resistor>(component))
195 if (std::dynamic_pointer_cast<EMT::Ph3::VoltageSource>(component))
198 throw std::invalid_argument(
199 "Unsupported component in MNA state-space extraction.");
202MNAStateSpaceContributor::List MNAStateSpaceContributorFactory::createList(
203 const MNAInterface::List &components) {
204 MNAStateSpaceContributor::List contributors;
206 for (
const auto &component : components) {
207 auto contributor = create(component);
209 contributors.push_back(contributor);