|
| 1 | +""" |
| 2 | +Default function to compute output current. |
| 3 | +Returns an error |
| 4 | +
|
| 5 | +""" |
| 6 | +function compute_output_current( |
| 7 | + ::SimulationResults, |
| 8 | + dynamic_device::I, |
| 9 | + ::Vector{Float64}, |
| 10 | + ::Vector{Float64}, |
| 11 | + ::Union{Nothing, Float64}, |
| 12 | +) where {I <: PSY.DynamicInjection} |
| 13 | + |
| 14 | + #Return error |
| 15 | + error( |
| 16 | + "Output current for device type $(typeof(dynamic_device)) is not implemented yet.", |
| 17 | + ) |
| 18 | +end |
| 19 | + |
1 | 20 | """ |
2 | 21 | Function to obtain the output current time series of a Dynamic Generator model out of the DAE Solution. It receives the simulation inputs, |
3 | 22 | the dynamic device and bus voltage. It is dispatched for device type to compute the specific current. |
@@ -30,6 +49,99 @@ function compute_output_current( |
30 | 49 | ) |
31 | 50 | end |
32 | 51 |
|
| 52 | +""" |
| 53 | +Function to obtain the output current time series of a AggregateDistributedGenerationA (DERA) model out of the DAE Solution. |
| 54 | +It receives the simulation inputs, the dynamic device and bus voltage. |
| 55 | +
|
| 56 | +""" |
| 57 | +function compute_output_current( |
| 58 | + res::SimulationResults, |
| 59 | + dynamic_device::PSY.AggregateDistributedGenerationA, |
| 60 | + V_R::Vector{Float64}, |
| 61 | + V_I::Vector{Float64}, |
| 62 | + dt::Union{Nothing, Float64}, |
| 63 | +) |
| 64 | + |
| 65 | + #Obtain Data |
| 66 | + sys = get_system(res) |
| 67 | + Sbase = PSY.get_base_power(sys) |
| 68 | + basepower = PSY.get_base_power(dynamic_device) |
| 69 | + base_power_ratio = basepower / Sbase |
| 70 | + Freq_Flag = PSY.get_Freq_Flag(dynamic_device) |
| 71 | + name = PSY.get_name(dynamic_device) |
| 72 | + if Freq_Flag == 1 |
| 73 | + _, Pord = post_proc_state_series(res, (name, :Pord), dt) |
| 74 | + _, dPord = post_proc_state_series(res, (name, :dPord), dt) |
| 75 | + Tpord = PSY.get_Tpord(dynamic_device) |
| 76 | + P_lim = PSY.get_P_lim(dynamic_device) |
| 77 | + end |
| 78 | + |
| 79 | + # Get states |
| 80 | + θ = atan.(V_I ./ V_R) |
| 81 | + ts, Ip = post_proc_state_series(res, (name, :Ip), dt) |
| 82 | + ts, Iq = post_proc_state_series(res, (name, :Iq), dt) |
| 83 | + _, Mult = post_proc_state_series(res, (name, :Mult), dt) |
| 84 | + _, Vmeas = post_proc_state_series(res, (name, :Vmeas), dt) |
| 85 | + Iq_neg = -Iq |
| 86 | + Ip_cmd = Ip |
| 87 | + Iq_cmd = Iq |
| 88 | + |
| 89 | + # Get Params |
| 90 | + Tg = PSY.get_Tg(dynamic_device) |
| 91 | + rrpwr = PSY.get_rrpwr(dynamic_device) |
| 92 | + P_ref = PSY.get_P_ref(dynamic_device) |
| 93 | + |
| 94 | + I_R = similar(Ip) |
| 95 | + I_I = similar(Iq) |
| 96 | + for (ix, Ip_cmd_val) in enumerate(Ip_cmd) |
| 97 | + Ip_min, Ip_max, _, _ = current_limit_logic(dynamic_device, Ip_cmd_val, Iq_cmd[ix]) |
| 98 | + if Ip[ix] >= 0 |
| 99 | + Rup = abs(rrpwr) |
| 100 | + Rdown = -Inf |
| 101 | + else |
| 102 | + Rdown = -abs(rrpwr) |
| 103 | + Rup = Inf |
| 104 | + end |
| 105 | + if Freq_Flag == 0 |
| 106 | + Ip_input = clamp(P_ref / max(Vmeas[ix], 0.01), Ip_min, Ip_max) * Mult[ix] |
| 107 | + Ip_limited, _ = low_pass_nonwindup_ramp_limits( |
| 108 | + Ip_input, |
| 109 | + Ip[ix], |
| 110 | + 1.0, |
| 111 | + Tg, |
| 112 | + -Inf, |
| 113 | + Inf, |
| 114 | + Rdown, |
| 115 | + Rup, |
| 116 | + ) |
| 117 | + else |
| 118 | + Pord_limited, _ = low_pass_nonwindup_mass_matrix( |
| 119 | + dPord[ix], |
| 120 | + Pord[ix], |
| 121 | + 1.0, |
| 122 | + Tpord, |
| 123 | + P_lim[:min], |
| 124 | + P_lim[:max], |
| 125 | + ) |
| 126 | + Ip_input = clamp(Pord_limited / max(Vmeas[ix], 0.01), Ip_min, Ip_max) * Mult[ix] |
| 127 | + Ip_limited, _ = low_pass_nonwindup_ramp_limits( |
| 128 | + Ip_input, |
| 129 | + Ip[ix], |
| 130 | + 1.0, |
| 131 | + Tg, |
| 132 | + -Inf, |
| 133 | + Inf, |
| 134 | + Rdown, |
| 135 | + Rup, |
| 136 | + ) |
| 137 | + end |
| 138 | + I_R[ix] = real(complex(Ip_limited, Iq_neg[ix]) * exp(im * θ[ix])) * base_power_ratio |
| 139 | + I_I[ix] = imag(complex(Ip_limited, Iq_neg[ix]) * exp(im * θ[ix])) * base_power_ratio |
| 140 | + end |
| 141 | + |
| 142 | + return ts, I_R, I_I |
| 143 | +end |
| 144 | + |
33 | 145 | """ |
34 | 146 | Function to obtain the field current time series of a Dynamic Generator model out of the DAE Solution. It receives the simulation inputs, |
35 | 147 | the dynamic device and bus voltage. It is dispatched for device type to compute the specific current. |
|
0 commit comments