DPsim
Loading...
Searching...
No Matches
PSS1A.cpp
1// SPDX-FileCopyrightText: 2026 Institute for Automation of Complex Power Systems, EONERC, RWTH Aachen University
2// SPDX-License-Identifier: MPL-2.0
3
4#include <dpsim-models/MathUtils.h>
5#include <dpsim-models/Signal/PSS1A.h>
6
7using namespace CPS;
8
9Signal::PSS1A::PSS1A(const String &name, CPS::Logger::Level logLevel)
10 : SimSignalComp(name, name, logLevel) {}
11
12void Signal::PSS1A::setParameters(
13 std::shared_ptr<Base::PSSParameters> parameters) {
14
15 if (auto params =
16 std::dynamic_pointer_cast<Signal::PSS1AParameters>(parameters)) {
17 mParameters = params;
18
19 if (mParameters->Tw == 0) {
20 SPDLOG_LOGGER_ERROR(mSLog, "PSS1A: Tw must be non-zero (used as "
21 "divisor in washout filter)");
22 throw CPS::InvalidArgumentException();
23 }
24 if (mParameters->T2 == 0) {
25 SPDLOG_LOGGER_ERROR(mSLog, "PSS1A: T2 must be non-zero (used as "
26 "divisor in first lead-lag block)");
27 throw CPS::InvalidArgumentException();
28 }
29 if (mParameters->T4 == 0) {
30 SPDLOG_LOGGER_ERROR(mSLog, "PSS1A: T4 must be non-zero (used as "
31 "divisor in second lead-lag block)");
32 throw CPS::InvalidArgumentException();
33 }
34
35 SPDLOG_LOGGER_INFO(mSLog,
36 "\nPSS1A parameters:"
37 "\nKp: {:e}"
38 "\nKv: {:e}"
39 "\nKw: {:e}"
40 "\nT1: {:e}"
41 "\nT2: {:e}"
42 "\nT3: {:e}"
43 "\nT4: {:e}"
44 "\nMaximum stabilizer output signal: {:e}"
45 "\nMinimum stabilizer output signal: {:e}"
46 "\nTw: {:e}",
47 mParameters->Kp, mParameters->Kv, mParameters->Kw,
48 mParameters->T1, mParameters->T2, mParameters->T3,
49 mParameters->T4, mParameters->Vs_max,
50 mParameters->Vs_min, mParameters->Tw);
51 mSLog->flush();
52
53 mA = 1. - mParameters->T1 / mParameters->T2;
54 mB = 1. - mParameters->T3 / mParameters->T4;
55 } else {
56 SPDLOG_LOGGER_ERROR(
57 mSLog, "Type of parameters class of {} has to be PSS1AParameters!",
58 this->name());
59 throw CPS::TypeException();
60 }
61}
62
63void Signal::PSS1A::initializeStates(Real omega, Real activePower, Real Vd,
64 Real Vq) {
65 Real Vh = sqrt(pow(Vd, 2.) + pow(Vq, 2.));
66
67 mV1 = -(mParameters->Kw * omega + mParameters->Kp * activePower +
68 mParameters->Kv * Vh);
69 mV2 = mA * (mParameters->Kw * omega + mParameters->Kp * activePower +
70 mParameters->Kv * Vh + mV1);
71 mV3 =
72 mB * (mV2 + (mParameters->T1 / mParameters->T2) *
73 (mParameters->Kw * omega + mParameters->Kp * activePower +
74 mParameters->Kv * Vh + mV1));
75 mVs = mV3 + (mParameters->T3 / mParameters->T4) *
76 (mV2 + (mParameters->T1 / mParameters->T2) *
77 (mParameters->Kw * omega +
78 mParameters->Kp * activePower +
79 mParameters->Kv * Vh + mV1));
80
81 mOmega_prev = omega;
82 mActivePower_prev = activePower;
83 mVh_prev = Vh;
84
85 SPDLOG_LOGGER_INFO(mSLog,
86 "\nInitial values:"
87 "\nmV1(t=0): {:e}"
88 "\nmV2(t=0): {:e}"
89 "\nmV3(t=0): {:e}"
90 "\nmVs(t=0): {:e}",
91 mV1, mV2, mV3, mVs);
92 mSLog->flush();
93}
94
95Real Signal::PSS1A::step(Real omega, Real activePower, Real Vd, Real Vq,
96 Real dt) {
97 Real Vh = sqrt(pow(Vd, 2.) + pow(Vq, 2.));
98
99 mV1_prev = mV1;
100 mV2_prev = mV2;
101 mV3_prev = mV3;
102 mVs_prev = mVs;
103
104 mV1 = mV1_prev - dt / mParameters->Tw *
105 (mParameters->Kw * mOmega_prev +
106 mParameters->Kp * mActivePower_prev +
107 mParameters->Kv * mVh_prev + mV1_prev);
108 mV2 = mV2_prev + dt / mParameters->T2 *
109 (mA * (mParameters->Kw * mOmega_prev +
110 mParameters->Kp * mActivePower_prev +
111 mParameters->Kv * mVh_prev + mV1_prev) -
112 mV2_prev);
113 mV3 = mV3_prev +
114 dt / mParameters->T4 *
115 (mB * (mV2_prev + (mParameters->T1 / mParameters->T2) *
116 (mParameters->Kw * mOmega_prev +
117 mParameters->Kp * mActivePower_prev +
118 mParameters->Kv * mVh_prev + mV1_prev)) -
119 mV3_prev);
120
121 mVs = mV3 + (mParameters->T3 / mParameters->T4) *
122 (mV2 + (mParameters->T1 / mParameters->T2) *
123 (mParameters->Kw * omega +
124 mParameters->Kp * activePower +
125 mParameters->Kv * Vh + mV1));
126
127 mOmega_prev = omega;
128 mActivePower_prev = activePower;
129 mVh_prev = Vh;
130
131 if (mVs > mParameters->Vs_max)
132 mVs = mParameters->Vs_max;
133 else if (mVs < mParameters->Vs_min)
134 mVs = mParameters->Vs_min;
135
136 return mVs;
137}
void initializeStates(Real omega, Real activePower, Real Vd, Real Vq) final
Initializes PSS state variables from power-flow solution.
Definition PSS1A.cpp:63
Real step(Real omega, Real activePower, Real Vd, Real Vq, Real dt) final
Definition PSS1A.cpp:95
Logger::Log mSLog
Component logger.