Skip to content

Commit 11238c0

Browse files
Decoupling ITM (#423)
This PR implements new decoupling elements based on the Ideal Transformer Model (ITM) for exemplifying co-simulation scenarios. This PR renames the Python API (dpsimpy) function `add` to `add_component`.
2 parents 2732152 + 154dd85 commit 11238c0

63 files changed

Lines changed: 6795 additions & 52 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/hugo/content/en/docs/Models/Ideal Transformer Model/images/ITM.svg

Lines changed: 632 additions & 0 deletions
Loading
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
title: "Ideal Transformer Model"
3+
linkTitle: "Ideal Transformer Model"
4+
date: 2026-06-26
5+
author: Andres Acosta <andres.acosta@eonerc.rwth-aachen.de>
6+
---
7+
8+
The Ideal Transformer Model (ITM) is a signal component that splits a circuit into two subcircuits, using a common node as a Point of Common Coupling (PCC), in such a way that a copy of this node is found in the two subcircuits, as shown in Fig. 1, where the copies of the node are denoted as $n$ and $m$. Moreover, the circuits are coupled using a controlled voltage source and a controlled current source, which exchange their interface currents and voltages, respectively, namely the interface signals. This exchange takes place using a ring buffer, on top of which a second ring buffer has been implemented to emulate a co-simualtion using a macro-step, which means that the exchange of interface signals can be made at an interval larger than the simulation's step size. This second ring buffer is used to implement Zero- and First-Order hold extrapolation methods, while the first ring buffer allows to linearly interpolate the value of the signal at the current time step, in case the delay between both subcircuits is not an integer multiple of the step size.
9+
10+
<center>
11+
<figure margin=30%>
12+
<img src="./images/ITM.svg" width=100% alt="ITM">
13+
<figcaption>Fig. 1: Ideal Transformer Model Circuit diagram.
14+
</figcaption>
15+
</figure>
16+
</center>
17+
18+
To add an ITM, users must split the cirtuit and create the copies of the PCC node. An example of this process can be found in the Notebook `ITM.ipynb`.
19+
20+
To avoid connections of the controlled voltage source with a capacitor, or the controlled current source with an inductor, the resistors $R_{\mathrm{series}}$ and $R_{\mathrm{parallel}}$ are included.

dpsim-models/include/dpsim-models/Components.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
#include <dpsim-models/Config.h>
1212

1313
#include <dpsim-models/SP/SP_Ph1_AvVoltageSourceInverterDQ.h>
14+
#include <dpsim-models/SP/SP_Ph1_ControlledCurrentSource.h>
15+
#include <dpsim-models/SP/SP_Ph1_ControlledVoltageSource.h>
1416
#include <dpsim-models/SP/SP_Ph1_Load.h>
1517
#include <dpsim-models/SP/SP_Ph1_NetworkInjection.h>
1618
#include <dpsim-models/SP/SP_Ph1_PQNode.h>
@@ -54,6 +56,8 @@
5456
#ifdef WITH_VILLAS
5557
#include <dpsim-models/DP/DP_Ph1_ProfileVoltageSource.h>
5658
#endif
59+
#include <dpsim-models/DP/DP_Ph1_ControlledCurrentSource.h>
60+
#include <dpsim-models/DP/DP_Ph1_ControlledVoltageSource.h>
5761
#include <dpsim-models/DP/DP_Ph1_RxLine.h>
5862
#include <dpsim-models/DP/DP_Ph1_SVC.h>
5963
#include <dpsim-models/DP/DP_Ph1_Switch.h>
@@ -149,6 +153,10 @@
149153
#include <dpsim-models/EMT/EMT_Ph3_TwoTerminalVTypeVariableSSNComp.h>
150154

151155
#include <dpsim-models/Signal/CosineFMGenerator.h>
156+
#include <dpsim-models/Signal/DecouplingIdealTransformer_DP_Ph1.h>
157+
#include <dpsim-models/Signal/DecouplingIdealTransformer_EMT_Ph1.h>
158+
#include <dpsim-models/Signal/DecouplingIdealTransformer_EMT_Ph3.h>
159+
#include <dpsim-models/Signal/DecouplingIdealTransformer_SP_Ph1.h>
152160
#include <dpsim-models/Signal/DecouplingLine.h>
153161
#include <dpsim-models/Signal/DecouplingLineEMT.h>
154162
#include <dpsim-models/Signal/DecouplingLineEMT_Ph3.h>
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// SPDX-FileCopyrightText: 2026 Institute for Automation of Complex Power Systems, EONERC, RWTH Aachen University
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
#pragma once
5+
6+
#include <dpsim-models/Base/Base_Ph1_CurrentSource.h>
7+
#include <dpsim-models/MNASimPowerComp.h>
8+
#include <dpsim-models/Solver/MNAInterface.h>
9+
#include <dpsim-models/Task.h>
10+
11+
namespace CPS {
12+
namespace DP {
13+
namespace Ph1 {
14+
/// \brief Dynamic phasor ideal current source
15+
///
16+
/// A positive current is flowing out of node1 and into node2.
17+
/// In case of a dynamic phasor simulation, a frequency different
18+
/// from zero is added on top of the system frequency.
19+
class ControlledCurrentSource : public MNASimPowerComp<Complex>,
20+
public SharedFactory<ControlledCurrentSource> {
21+
protected:
22+
// Updates current according to reference phasor and frequency
23+
void updateCurrent(Real time);
24+
25+
public:
26+
const Attribute<Complex>::Ptr mCurrentRef;
27+
/// Defines UID, name and logging level
28+
ControlledCurrentSource(String uid, String name,
29+
Logger::Level loglevel = Logger::Level::off);
30+
/// Defines name and logging level
31+
ControlledCurrentSource(String name,
32+
Logger::Level logLevel = Logger::Level::off)
33+
: ControlledCurrentSource(name, name, logLevel) {}
34+
35+
void setParameters(Complex currentRef);
36+
37+
SimPowerComp<Complex>::Ptr clone(String name) override;
38+
39+
// #### General ####
40+
/// Initializes component from power flow data
41+
void initializeFromNodesAndTerminals(Real frequency) override;
42+
43+
// #### MNA section ####
44+
///
45+
void mnaCompInitialize(Real omega, Real timeStep,
46+
Attribute<Matrix>::Ptr leftVector) override;
47+
/// Stamps system matrix
48+
void mnaCompApplySystemMatrixStamp(SparseMatrixRow &systemMatrix) override {}
49+
/// Stamps right side (source) vector
50+
void mnaCompApplyRightSideVectorStamp(Matrix &rightVector) override;
51+
///
52+
void mnaCompUpdateVoltage(const Matrix &leftVector) override;
53+
54+
/// Add MNA pre step dependencies
55+
void mnaCompAddPreStepDependencies(
56+
AttributeBase::List &prevStepDependencies,
57+
AttributeBase::List &attributeDependencies,
58+
AttributeBase::List &modifiedAttributes) override;
59+
/// Add MNA post step dependencies
60+
void
61+
mnaCompAddPostStepDependencies(AttributeBase::List &prevStepDependencies,
62+
AttributeBase::List &attributeDependencies,
63+
AttributeBase::List &modifiedAttributes,
64+
Attribute<Matrix>::Ptr &leftVector) override;
65+
void mnaCompPreStep(Real time, Int timeStepCount) override;
66+
void mnaCompPostStep(Real time, Int timeStepCount,
67+
Attribute<Matrix>::Ptr &leftVector) override;
68+
};
69+
} // namespace Ph1
70+
} // namespace DP
71+
} // namespace CPS
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// SPDX-FileCopyrightText: 2026 Institute for Automation of Complex Power Systems, EONERC, RWTH Aachen University
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
#pragma once
5+
6+
#include <dpsim-models/MNASimPowerComp.h>
7+
#include <dpsim-models/Signal/CosineFMGenerator.h>
8+
#include <dpsim-models/Signal/FrequencyRampGenerator.h>
9+
#include <dpsim-models/Signal/SignalGenerator.h>
10+
#include <dpsim-models/Signal/SineWaveGenerator.h>
11+
#include <dpsim-models/Solver/MNAInterface.h>
12+
13+
namespace CPS {
14+
namespace DP {
15+
namespace Ph1 {
16+
/// \brief Controlled Ideal Voltage source model
17+
///
18+
/// This model uses modified nodal analysis to represent an ideal voltage source.
19+
/// This voltage source derives it's output purely from attributes rather than an internal signal generator.
20+
class ControlledVoltageSource : public MNASimPowerComp<Complex>,
21+
public SharedFactory<ControlledVoltageSource> {
22+
protected:
23+
// Updates voltage according to reference phasor and frequency
24+
void updateVoltage(Real time);
25+
26+
public:
27+
const CPS::Attribute<Complex>::Ptr mVoltageRef;
28+
29+
/// Defines UID, name and logging level
30+
ControlledVoltageSource(String uid, String name,
31+
Logger::Level logLevel = Logger::Level::off);
32+
///
33+
ControlledVoltageSource(String name,
34+
Logger::Level logLevel = Logger::Level::off)
35+
: ControlledVoltageSource(name, name, logLevel) {}
36+
37+
SimPowerComp<Complex>::Ptr clone(String name) override;
38+
// #### General ####
39+
/// Initializes component from power flow data
40+
void initializeFromNodesAndTerminals(Real frequency) override;
41+
/// Setter for reference voltage with a real valued generator
42+
/// This will initialize the values of mVoltageRef to match the given parameters
43+
/// However, the attributes can be modified during the simulation to dynamically change the value of the output voltage.
44+
void setParameters(Complex voltageRef);
45+
46+
// #### MNA section ####
47+
/// Initializes internal variables of the component
48+
void mnaCompInitialize(Real omega, Real timeStep,
49+
Attribute<Matrix>::Ptr leftVector) override;
50+
/// Stamps system matrix
51+
void mnaCompApplySystemMatrixStamp(SparseMatrixRow &systemMatrix) override;
52+
/// Stamps right side (source) vector
53+
void mnaCompApplyRightSideVectorStamp(Matrix &rightVector) override;
54+
/// Returns current through the component
55+
void mnaCompUpdateCurrent(const Matrix &leftVector) override;
56+
/// MNA pre step operations
57+
void mnaCompPreStep(Real time, Int timeStepCount) override;
58+
/// MNA post step operations
59+
void mnaCompPostStep(Real time, Int timeStepCount,
60+
Attribute<Matrix>::Ptr &leftVector) override;
61+
/// Add MNA pre step dependencies
62+
void mnaCompAddPreStepDependencies(
63+
AttributeBase::List &prevStepDependencies,
64+
AttributeBase::List &attributeDependencies,
65+
AttributeBase::List &modifiedAttributes) override;
66+
/// Add MNA post step dependencies
67+
void
68+
mnaCompAddPostStepDependencies(AttributeBase::List &prevStepDependencies,
69+
AttributeBase::List &attributeDependencies,
70+
AttributeBase::List &modifiedAttributes,
71+
Attribute<Matrix>::Ptr &leftVector) override;
72+
};
73+
} // namespace Ph1
74+
} // namespace DP
75+
} // namespace CPS

dpsim-models/include/dpsim-models/Definitions.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ enum class GeneratorType {
132132
};
133133
enum class SGOrder { SG3Order, SG4Order, SG5Order, SG6aOrder, SG6bOrder };
134134

135+
enum class CouplingMethod { DELAY, EXTRAPOLATION_ZOH, EXTRAPOLATION_LINEAR };
136+
135137
// ### Exceptions ###
136138
class Exception : public std::exception {};
137139
class AccessException : public Exception {};

dpsim-models/include/dpsim-models/EMT/EMT_Ph3_RXLoad.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ class RXLoad : public CompositePowerComp<Real>, public SharedFactory<RXLoad> {
5959
RXLoad(String name, Matrix activePower, Matrix reactivePower, Real volt,
6060
Logger::Level logLevel = Logger::Level::off);
6161

62+
SimPowerComp<Real>::Ptr clone(String name) override;
63+
6264
// #### General ####
6365
virtual String description() override {
6466
return fmt::format("Active: {}MW, Reactive: {}MVAr, Voltage: {}kV",
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// SPDX-FileCopyrightText: 2026 Institute for Automation of Complex Power Systems, EONERC, RWTH Aachen University
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
#pragma once
5+
6+
#include <dpsim-models/Base/Base_Ph1_CurrentSource.h>
7+
#include <dpsim-models/MNASimPowerComp.h>
8+
#include <dpsim-models/Signal/SineWaveGenerator.h>
9+
#include <dpsim-models/Solver/MNAInterface.h>
10+
#include <dpsim-models/Task.h>
11+
12+
namespace CPS {
13+
namespace SP {
14+
namespace Ph1 {
15+
/// \brief Ideal Current source model
16+
///
17+
/// A positive current is flowing out of node1 and into node2.
18+
class ControlledCurrentSource : public MNASimPowerComp<Complex>,
19+
public SharedFactory<ControlledCurrentSource> {
20+
21+
protected:
22+
// Updates current according to reference phasor and frequency
23+
void updateCurrent(Real time);
24+
25+
public:
26+
const Attribute<Complex>::Ptr mCurrentRef;
27+
/// Defines UID, name and logging level
28+
ControlledCurrentSource(String uid, String name,
29+
Logger::Level loglevel = Logger::Level::off);
30+
/// Defines name and logging level
31+
ControlledCurrentSource(String name,
32+
Logger::Level logLevel = Logger::Level::off)
33+
: ControlledCurrentSource(name, name, logLevel) {}
34+
/// Defines name, component parameters and logging level
35+
ControlledCurrentSource(String name, Complex current,
36+
Logger::Level logLevel = Logger::Level::off);
37+
38+
SimPowerComp<Complex>::Ptr clone(String copySuffix) override;
39+
40+
// #### General ####
41+
/// Initializes component from power flow data
42+
void initializeFromNodesAndTerminals(Real frequency) override;
43+
///
44+
// void setSourceValue(Complex current);
45+
46+
void setParameters(Complex currentRef);
47+
48+
// #### MNA section ####
49+
///
50+
void mnaCompInitialize(Real omega, Real timeStep,
51+
Attribute<Matrix>::Ptr leftVector) override;
52+
/// Stamps system matrix
53+
void mnaCompApplySystemMatrixStamp(SparseMatrixRow &systemMatrix) override {}
54+
/// Stamps right side (source) vector
55+
void mnaCompApplyRightSideVectorStamp(Matrix &rightVector) override;
56+
///
57+
void mnaCompUpdateVoltage(const Matrix &leftVector) override;
58+
59+
/// Add MNA pre step dependencies
60+
void mnaCompAddPreStepDependencies(
61+
AttributeBase::List &prevStepDependencies,
62+
AttributeBase::List &attributeDependencies,
63+
AttributeBase::List &modifiedAttributes) override;
64+
/// Add MNA post step dependencies
65+
void
66+
mnaCompAddPostStepDependencies(AttributeBase::List &prevStepDependencies,
67+
AttributeBase::List &attributeDependencies,
68+
AttributeBase::List &modifiedAttributes,
69+
Attribute<Matrix>::Ptr &leftVector) override;
70+
void mnaCompPreStep(Real time, Int timeStepCount) override;
71+
void mnaCompPostStep(Real time, Int timeStepCount,
72+
Attribute<Matrix>::Ptr &leftVector) override;
73+
};
74+
} // namespace Ph1
75+
} // namespace SP
76+
} // namespace CPS
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
// SPDX-FileCopyrightText: 2026 Institute for Automation of Complex Power Systems, EONERC, RWTH Aachen University
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
#pragma once
5+
6+
#include <dpsim-models/MNASimPowerComp.h>
7+
#include <dpsim-models/Signal/CosineFMGenerator.h>
8+
#include <dpsim-models/Signal/FrequencyRampGenerator.h>
9+
#include <dpsim-models/Signal/SignalGenerator.h>
10+
#include <dpsim-models/Signal/SineWaveGenerator.h>
11+
#include <dpsim-models/Solver/DAEInterface.h>
12+
#include <dpsim-models/Solver/MNAInterface.h>
13+
14+
namespace CPS {
15+
namespace SP {
16+
namespace Ph1 {
17+
/// \brief Ideal Voltage source model
18+
///
19+
/// This model uses modified nodal analysis to represent an ideal voltage source.
20+
/// For a voltage source between nodes j and k, a new variable
21+
/// (current across the voltage source) is added to the left side vector
22+
/// as unkown and it is taken into account for the equation of node j as
23+
/// positve and for the equation of node k as negative. Moreover
24+
/// a new equation ej - ek = V is added to the problem.
25+
class ControlledVoltageSource : public MNASimPowerComp<Complex>,
26+
public SharedFactory<ControlledVoltageSource> {
27+
private:
28+
///
29+
void updateVoltage(Real time);
30+
31+
public:
32+
const Attribute<Complex>::Ptr mVoltageRef;
33+
const Attribute<Real>::Ptr mSrcFreq;
34+
35+
/// Defines UID, name, component parameters and logging level
36+
ControlledVoltageSource(String uid, String name,
37+
Logger::Level loglevel = Logger::Level::off);
38+
/// Defines UID, name, component parameters and logging level
39+
ControlledVoltageSource(String name,
40+
Logger::Level logLevel = Logger::Level::off)
41+
: ControlledVoltageSource(name, name, logLevel) {}
42+
/// Defines name, component parameters and logging level
43+
ControlledVoltageSource(String name, Complex voltage,
44+
Logger::Level logLevel = Logger::Level::off);
45+
///
46+
SimPowerComp<Complex>::Ptr clone(String name) override;
47+
48+
// #### General ####
49+
/// Initializes component from power flow data
50+
void initializeFromNodesAndTerminals(Real frequency) override;
51+
/// Setter for reference voltage and frequency with a sine wave generator
52+
/// This will initialize the values of mVoltageRef and mSrcFreq to match the given parameters
53+
/// However, the attributes can be modified during the simulation to dynamically change the magnitude, frequency, and phase of the sine wave.
54+
void setParameters(Complex voltageRef);
55+
56+
// #### MNA Section ####
57+
/// Initializes internal variables of the component
58+
void mnaCompInitialize(Real omega, Real timeStep,
59+
Attribute<Matrix>::Ptr leftVector) override;
60+
/// Stamps system matrix
61+
void mnaCompApplySystemMatrixStamp(SparseMatrixRow &systemMatrix) override;
62+
/// Stamps right side (source) vector
63+
void mnaCompApplyRightSideVectorStamp(Matrix &rightVector) override;
64+
/// Returns current through the component
65+
void mnaCompUpdateCurrent(const Matrix &leftVector) override;
66+
/// MNA pre step operations
67+
void mnaCompPreStep(Real time, Int timeStepCount) override;
68+
/// MNA post step operations
69+
void mnaCompPostStep(Real time, Int timeStepCount,
70+
Attribute<Matrix>::Ptr &leftVector) override;
71+
/// Add MNA pre step dependencies
72+
void mnaCompAddPreStepDependencies(
73+
AttributeBase::List &prevStepDependencies,
74+
AttributeBase::List &attributeDependencies,
75+
AttributeBase::List &modifiedAttributes) override;
76+
/// Add MNA post step dependencies
77+
void
78+
mnaCompAddPostStepDependencies(AttributeBase::List &prevStepDependencies,
79+
AttributeBase::List &attributeDependencies,
80+
AttributeBase::List &modifiedAttributes,
81+
Attribute<Matrix>::Ptr &leftVector) override;
82+
};
83+
} // namespace Ph1
84+
} // namespace SP
85+
} // namespace CPS

0 commit comments

Comments
 (0)