DPsim
Loading...
Searching...
No Matches
ExciterDC1Simp.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/ExciterDC1Simp.h>
5
6using namespace CPS;
7using namespace CPS::Signal;
8
9ExciterDC1Simp::ExciterDC1Simp(const String &name, CPS::Logger::Level logLevel)
10 : SimSignalComp(name, name, logLevel),
11 mVh(mAttributes->create<Real>("Vh", 0)),
12 mVr(mAttributes->create<Real>("Vr", 0)),
13 mEf(mAttributes->create<Real>("Ef", 0.0)) {}
14
16 std::shared_ptr<Base::ExciterParameters> parameters) {
17
18 if (auto params = std::dynamic_pointer_cast<Signal::ExciterDC1SimpParameters>(
19 parameters)) {
20 mParameters = params;
21
22 if (mParameters->Tr == 0) {
23 SPDLOG_LOGGER_ERROR(mSLog, "ExciterDC1Simp: Tr must be non-zero (used as "
24 "divisor in voltage transducer)");
26 }
27 if (mParameters->Ta == 0) {
28 SPDLOG_LOGGER_ERROR(
29 mSLog,
30 "ExciterDC1Simp: Ta must be non-zero (used as divisor in amplifier)");
32 }
33 if (mParameters->Tf == 0) {
34 SPDLOG_LOGGER_ERROR(
35 mSLog, "ExciterDC1Simp: Tf must be non-zero (used as divisor "
36 "in stabilizing feedback)");
38 }
39 if (mParameters->Tef == 0) {
40 SPDLOG_LOGGER_ERROR(
41 mSLog, "ExciterDC1Simp: Tef must be non-zero (used as divisor "
42 "in exciter output)");
44 }
45 if (mParameters->Ka == 0) {
46 SPDLOG_LOGGER_ERROR(
47 mSLog, "ExciterDC1Simp: Ka must be non-zero (used as divisor "
48 "when computing initial amplifier input)");
50 }
51
52 SPDLOG_LOGGER_INFO(mSLog,
53 "\nExciterDC1Simp parameters:"
54 "\nTa: {:e}"
55 "\nKa: {:e}"
56 "\nTef: {:e}"
57 "\nKef: {:e}"
58 "\nTf: {:e}"
59 "\nKf: {:e}"
60 "\nTr: {:e}"
61 "\nAef: {:e}"
62 "\nBef: {:e}"
63 "\nMaximum amplifier Voltage: {:e}"
64 "\nMinimum amplifier Voltage: {:e}\n",
65 mParameters->Ta, mParameters->Ka, mParameters->Tef,
66 mParameters->Kef, mParameters->Tf, mParameters->Kf,
67 mParameters->Tr, mParameters->Aef, mParameters->Bef,
68 mParameters->MaxVa, mParameters->MinVa);
69 } else {
70 SPDLOG_LOGGER_ERROR(
71 mSLog, "Type of parameters class of {} has to be ExciterDC1Simp!",
72 this->name());
73 throw CPS::TypeException();
74 }
75}
76
77void ExciterDC1Simp::initializeStates(Real Vh_init, Real Ef_init) {
78 //
79 **mVh = Vh_init;
80 **mEf = Ef_init;
81 SPDLOG_LOGGER_INFO(mSLog,
82 "Initially set excitation system initial values:"
83 "\ninit Vh: {:e}"
84 "\ninit Ef: {:e}",
85 **mVh, **mEf);
86
88 **mVr = **mVh;
89
91 mVf = 0.0;
92
94 mVsat = mParameters->Aef * exp(mParameters->Bef * abs(**mEf));
95
97 mVa = mParameters->Kef * **mEf + mVsat * **mEf;
98 if (mVa > mParameters->MaxVa)
99 mVa = mParameters->MaxVa;
100 if (mVa < mParameters->MinVa)
101 mVa = mParameters->MinVa;
102
104 mVin = mVa / mParameters->Ka;
105
107 mVref = **mVr + mVin;
108
110 if (std::abs(**mEf - mVa / (mVsat + mParameters->Kef)) > DOUBLE_EPSILON)
111 SPDLOG_LOGGER_WARN(mSLog, "\nInitial conditions are not consistent!!!");
112
113 SPDLOG_LOGGER_INFO(mSLog,
114 "\nActually applied excitation system initial values:"
115 "\nVref : {:e}"
116 "\ninit_Vr: {:e}"
117 "\ninit_Ef: {:e}"
118 "\ninit_Va: {:e}",
119 mVref, **mVr, **mEf, mVa);
120 mSLog->flush();
121}
122
123Real ExciterDC1Simp::step(Real mVd, Real mVq, Real dt, Real Vpss) {
124 // Voltage magnitude calculation
125 **mVh = sqrt(pow(mVd, 2.) + pow(mVq, 2.));
126
127 // update state variables at time k-1
128 mVr_prev = **mVr;
129 mVa_prev = mVa;
130 mVf_prev = mVf;
131 mEf_prev = **mEf;
132
133 // compute state variables at time k using euler forward
134
135 // saturation function
136 mVsat = mParameters->Aef * exp(mParameters->Bef * abs(mEf_prev));
137
138 // Voltage Transducer equation
139 **mVr = **mVr + dt / mParameters->Tr * (**mVh - **mVr);
140
141 // Voltage amplifier equation
142 mVin = mVref + Vpss - **mVr - mVf;
143 mVa = mVa_prev + dt / mParameters->Ta * (mVin * mParameters->Ka - mVa_prev);
144 if (mVa > mParameters->MaxVa)
145 mVa = mParameters->MaxVa;
146 else if (mVa < mParameters->MinVa)
147 mVa = mParameters->MinVa;
148
149 // Stabilizing feedback
150 mVf = (1. - dt / mParameters->Tf) * mVf_prev +
151 dt * mParameters->Kf / (mParameters->Tf * mParameters->Tef) *
152 (mVa_prev - (mVsat + mParameters->Kef) * mEf_prev);
153
154 // Exciter output
155 **mEf = mEf_prev + dt / mParameters->Tef *
156 (mVa_prev - (mVsat + mParameters->Kef) * mEf_prev);
157
158 return **mEf;
159}
AttributeList::Ptr mAttributes
Attribute List.
void initializeStates(Real Vh_init, Real Vf_init) final
Initializes exciter variables.
ExciterDC1Simp(const String &name, CPS::Logger::Level logLevel=Logger::Level::info)
Constructor.
void setParameters(std::shared_ptr< Base::ExciterParameters > parameters) final
Initializes exciter parameters.
Real step(Real mVd, Real mVq, Real dt, Real Vpss=0) final
Performs an step to update field voltage value.
Logger::Log mSLog
Component logger.