DPsim
Loading...
Searching...
No Matches
ExciterDC1.cpp
1// SPDX-FileCopyrightText: 2025 Institute for Automation of Complex Power Systems, EONERC, RWTH Aachen University
2// SPDX-License-Identifier: MPL-2.0
3
4#include <dpsim-models/Signal/ExciterDC1.h>
5
6using namespace CPS;
7
8Signal::ExciterDC1::ExciterDC1(const String &name, CPS::Logger::Level logLevel)
9 : SimSignalComp(name, name, logLevel) {}
10
12 std::shared_ptr<Base::ExciterParameters> parameters) {
13
14 if (auto params =
15 std::dynamic_pointer_cast<Signal::ExciterDC1Parameters>(parameters)) {
16 mParameters = params;
17
18 if (mParameters->Tr == 0) {
19 SPDLOG_LOGGER_ERROR(mSLog, "ExciterDC1: Tr must be non-zero (used as "
20 "divisor in voltage transducer)");
22 }
23 if (mParameters->Tb == 0) {
24 SPDLOG_LOGGER_ERROR(mSLog, "ExciterDC1: Tb must be non-zero (used as "
25 "divisor in regulator lead-lag block)");
27 }
28 if (mParameters->Ta == 0) {
29 SPDLOG_LOGGER_ERROR(
30 mSLog,
31 "ExciterDC1: Ta must be non-zero (used as divisor in amplifier)");
33 }
34 if (mParameters->Tf == 0) {
35 SPDLOG_LOGGER_ERROR(mSLog,
36 "ExciterDC1: Tf must be non-zero (used as divisor in "
37 "stabilizing feedback)");
39 }
40 if (mParameters->Tef == 0) {
41 SPDLOG_LOGGER_ERROR(mSLog, "ExciterDC1: Tef must be non-zero (used as "
42 "divisor in exciter output)");
44 }
45 if (mParameters->Ka == 0) {
46 SPDLOG_LOGGER_ERROR(
47 mSLog, "ExciterDC1: Ka must be non-zero (used as divisor when "
48 "computing initial amplifier input)");
50 }
51
52 SPDLOG_LOGGER_INFO(mSLog,
53 "\nExciterDC1 parameters:"
54 "\nType: DC1"
55 "\nTr: {:e}"
56 "\nTa: {:e}"
57 "\nKa: {:e}"
58 "\nTb: {:e}"
59 "\nTc: {:e}"
60 "\nTef: {:e}"
61 "\nKef: {:e}"
62 "\nTf: {:e}"
63 "\nKf: {:e}"
64 "\nAef: {:e}"
65 "\nBef: {:e}"
66 "\nMaximum amplifier Voltage: {:e}"
67 "\nMinimum amplifier Voltage: {:e}\n",
68 mParameters->Tr, mParameters->Ta, mParameters->Ka,
69 mParameters->Tb, mParameters->Tc, mParameters->Tef,
70 mParameters->Kef, mParameters->Tf, mParameters->Kf,
71 mParameters->Aef, mParameters->Bef, mParameters->MaxVa,
72 mParameters->MinVa);
73 } else {
74 SPDLOG_LOGGER_ERROR(
75 mSLog, "Type of parameters class of {} has to be ExciterDC1Parameters!",
76 this->name());
77 throw CPS::TypeException();
78 }
79}
80
81void Signal::ExciterDC1::initializeStates(Real Vh_init, Real Ef_init) {
82
83 mVh = Vh_init;
84 mEf = Ef_init;
85
86 SPDLOG_LOGGER_INFO(mSLog,
87 "Initially set excitation system initial values:"
88 "\ninit Vh: {:e}"
89 "\ninit Ef: {:e}",
90 mVh, mEf);
91
93 mVr = mVh;
94
96 mVf = 0.0;
97
98 // ceiling function
99 mVsat = mParameters->Aef * exp(mParameters->Bef * abs(mEf));
100
102 mVa = mParameters->Kef * mEf + mVsat * mEf;
103 if (mVa > mParameters->MaxVa)
104 mVa = mParameters->MaxVa;
105 if (mVa < mParameters->MinVa)
106 mVa = mParameters->MinVa;
107
109 mVin = mVa / mParameters->Ka;
110
112 mVb = mVin;
113
115 mVref = mVr + mVin;
116
118 if (std::abs(mEf - mVa / (mVsat + mParameters->Kef)) > DOUBLE_EPSILON)
119 SPDLOG_LOGGER_WARN(mSLog, "\nInitial conditions are not consistent!!!");
120
121 SPDLOG_LOGGER_INFO(mSLog,
122 "Actually applied excitation system initial values:"
123 "\nVref : {:e}"
124 "\ninit Vr: {:e}"
125 "\ninit Vf: {:e}"
126 "\ninit Vb: {:e}"
127 "\ninit Vin: {:e}"
128 "\ninit Va: {:e}",
129 mVref, mVr, mVf, mVb, mVin, mVa);
130 mSLog->flush();
131}
132
133Real Signal::ExciterDC1::step(Real Vd, Real Vq, Real dt, Real Vpss) {
134 // Voltage magnitude calculation
135 mVh = sqrt(pow(Vd, 2.) + pow(Vq, 2.));
136
137 // update state variables at time k-1
138 mVr_prev = mVr;
139 mVf_prev = mVf;
140 mVb_prev = mVb;
141 mVin_prev = mVin;
142 mVa_prev = mVa;
143 mEf_prev = mEf;
144
145 // compute state variables at time k using euler forward
146
147 // saturation function
148 mVsat = mParameters->Aef * exp(mParameters->Bef * abs(mEf_prev));
149
150 // Voltage Transducer
151 mVr = mVr_prev + dt / mParameters->Tr * (mVh - mVr_prev);
152
153 // Regulator output
154 mVb = mVb_prev * (1 - dt / mParameters->Tb) +
155 dt / mParameters->Tb * (mVref + Vpss - mVr_prev - mVf_prev);
156 mVin = dt * (mParameters->Tc / mParameters->Tb) *
157 (mVref + Vpss - mVr_prev - mVf_prev - mVb_prev) +
158 mVb;
159
160 // Amplifier
161 mVa = mVa_prev +
162 dt / mParameters->Ta * (mVin_prev * mParameters->Ka - mVa_prev);
163 if (mVa > mParameters->MaxVa)
164 mVa = mParameters->MaxVa;
165 if (mVa < mParameters->MinVa)
166 mVa = mParameters->MinVa;
167
168 // Stabilizing feedback
169 mVf = (1. - dt / mParameters->Tf) * mVf_prev +
170 dt * mParameters->Kf / (mParameters->Tf * mParameters->Tef) *
171 (mVa_prev - (mVsat + mParameters->Kef) * mEf_prev);
172
173 // Exciter output
174 mEf = mEf_prev + dt / mParameters->Tef *
175 (mVa_prev - (mVsat + mParameters->Kef) * mEf_prev);
176
177 return mEf;
178}
ExciterDC1(const String &name, Logger::Level logLevel=Logger::Level::info)
Constructor.
Definition ExciterDC1.cpp:8
Real step(Real Vd, Real Vq, Real dt, Real Vpss=0) final
Performs an step to update field voltage value.
void initializeStates(Real Vh_init, Real Vf_init) final
Initializes exciter variables.
void setParameters(std::shared_ptr< Base::ExciterParameters > parameters) final
Initializes exciter parameters.
Logger::Log mSLog
Component logger.