Inverter Modeling simulation
Originally Contributed by: José Daniel Lara
Introduction
This tutorial will introduce the modeling of an inverter with Virtual Inertia in a multi-machine model of the system. We will load the data directly from PSS/e dynamic files.
The tutorial uses a modified 14-bus system on which all the synchronous machines have been substituted by generators with ESAC1A AVR's and no Turbine Governors.
In the first portion of the tutorial we will simulate the system with the original data and cause a line trip between Buses 2 and 4. In the second part of the simulation, we will switch generator 6 with a battery using an inverter and perform the same fault.
Load the packages
julia> using PowerSimulationsDynamics
julia> using PowerSystemCaseBuilder
julia> using PowerSystems
julia> const PSY = PowerSystems
PowerSystems
julia> using PowerFlows
julia> using Logging
julia> using Sundials
julia> using Plots
PowerSystemCaseBuilder.jl
is a helper library that makes it easier to reproduce examples in the documentation and tutorials. Normally you would pass your local files to create the system data instead of calling the function build_system
. For more details visit PowerSystemCaseBuilder Documentation
Create the system using PowerSystemCaseBuilder.jl
:
julia> sys = build_system(PSIDSystems, "14 Bus Base Case")
ERROR: UndefVarError: `build_system` not defined
PowerSystemCaseBuilder.jl
is a helper library that makes it easier to reproduce examples in the documentation and tutorials. Normally you would pass your local files to create the system data.
Define Simulation Problem with a 20 second simulation period and the branch trip at t = 1.0:
julia> sim = Simulation( ResidualModel, #Type of model used sys, #system mktempdir(), #path for the simulation output (0.0, 20.0), #time span BranchTrip(1.0, Line, "BUS 02-BUS 04-i_1"); console_level = Logging.Info, )
ERROR: UndefVarError: `sys` not defined
Now that the system is initialized, we can verify the system states for potential issues.
julia> show_states_initial_value(sim)
ERROR: UndefVarError: `sim` not defined
We execute the simulation with an additional tolerance for the solver set at 1e-8:
julia> execute!(sim, IDA(); abstol = 1e-8)
ERROR: UndefVarError: `sim` not defined
Using PowerSimulationsDynamics
tools for exploring the results, we can plot all the voltage results for the buses:
julia> result = read_results(sim)
ERROR: UndefVarError: `sim` not defined
julia> p = plot();
julia> for b in get_components(ACBus, sys) voltage_series = get_voltage_magnitude_series(result, get_number(b)) plot!( p, voltage_series; xlabel = "Time", ylabel = "Voltage Magnitude [pu]", label = "Bus - $(get_name(b))", ); end
ERROR: UndefVarError: `sys` not defined
We can also explore the frequency of the different generators
julia> p2 = plot();
julia> for g in get_components(ThermalStandard, sys) state_series = get_state_series(result, (get_name(g), :ω)) plot!( p2, state_series; xlabel = "Time", ylabel = "Speed [pu]", label = "$(get_name(g)) - ω", ); end
ERROR: UndefVarError: `sys` not defined
It is also possible to explore the small signal stability of this system we created.
julia> res = small_signal_analysis(sim)
ERROR: UndefVarError: `sim` not defined
The eigenvalues can be explored
julia> res.eigenvalues
ERROR: UndefVarError: `res` not defined
Modifying the system and adding storage
Reload the system for this example:
julia> sys = build_system(PSIDSystems, "14 Bus Base Case") # We want to remove the generator 6 and the dynamic component attached to it.
ERROR: UndefVarError: `build_system` not defined
julia> thermal_gen = get_component(ThermalStandard, sys, "generator-6-1")
ERROR: UndefVarError: `sys` not defined
julia> remove_component!(sys, get_dynamic_injector(thermal_gen))
ERROR: UndefVarError: `sys` not defined
julia> remove_component!(sys, thermal_gen) # We can now define our storage device and add it to the system
ERROR: UndefVarError: `sys` not defined
julia> storage = GenericBattery( name = "Battery", bus = get_component(Bus, sys, "BUS 06"), available = true, prime_mover = PrimeMovers.BA, active_power = 0.6, reactive_power = 0.16, rating = 1.1, base_power = 25.0, initial_energy = 50.0, state_of_charge_limits = (min = 5.0, max = 100.0), input_active_power_limits = (min = 0.0, max = 1.0), output_active_power_limits = (min = 0.0, max = 1.0), reactive_power_limits = (min = -1.0, max = 1.0), efficiency = (in = 0.80, out = 0.90), )
ERROR: UndefVarError: `sys` not defined
julia> add_component!(sys, storage)
ERROR: UndefVarError: `sys` not defined
A good sanity check it running a power flow on the system to make sure all the components are properly scaled and that the system is properly balanced. We can use PowerSystems
to perform this check. We can get the results back and perform a sanity check.
julia> res = solve_powerflow(ACPowerFlow(), sys)
ERROR: UndefVarError: `sys` not defined
julia> res["bus_results"]
ERROR: UndefVarError: `res` not defined
After verifying that the system works, we can define our inverter dynamics and add it to the battery that has already been stored in the system.
julia> inverter = DynamicInverter( name = get_name(storage), ω_ref = 1.0, # ω_ref, converter = AverageConverter(rated_voltage = 138.0, rated_current = 100.0), outer_control = OuterControl( VirtualInertia(Ta = 2.0, kd = 400.0, kω = 20.0), ReactivePowerDroop(kq = 0.2, ωf = 1000.0), ), inner_control = VoltageModeControl( kpv = 0.59, #Voltage controller proportional gain kiv = 736.0, #Voltage controller integral gain kffv = 0.0, #Binary variable enabling the voltage feed-forward in output of current controllers rv = 0.0, #Virtual resistance in pu lv = 0.2, #Virtual inductance in pu kpc = 1.27, #Current controller proportional gain kic = 14.3, #Current controller integral gain kffi = 0.0, #Binary variable enabling the current feed-forward in output of current controllers ωad = 50.0, #Active damping low pass filter cut-off frequency kad = 0.2, ), dc_source = FixedDCSource(voltage = 600.0), freq_estimator = KauraPLL( ω_lp = 500.0, #Cut-off frequency for LowPass filter of PLL filter. kp_pll = 0.084, #PLL proportional gain ki_pll = 4.69, #PLL integral gain ), filter = LCLFilter(lf = 0.08, rf = 0.003, cf = 0.074, lg = 0.2, rg = 0.01), )
ERROR: UndefVarError: `storage` not defined
julia> add_component!(sys, inverter, storage)
ERROR: UndefVarError: `sys` not defined
These are the current system components:
julia> sys
ERROR: UndefVarError: `sys` not defined
Define Simulation problem using the same parameters:
julia> sim = Simulation( ResidualModel, #Type of model used sys, #system mktempdir(), #path for the simulation output (0.0, 20.0), #time span BranchTrip(1.0, Line, "BUS 02-BUS 04-i_1"); console_level = Logging.Info, )
ERROR: UndefVarError: `sys` not defined
We can verify the small signal stability of the system before running the simulation:
julia> res = small_signal_analysis(sim)
ERROR: UndefVarError: `sim` not defined
Exploring the eigenvalues:
julia> res.eigenvalues
ERROR: UndefVarError: `res` not defined
We execute the simulation
julia> execute!(sim, IDA(); abstol = 1e-8)
ERROR: UndefVarError: `sim` not defined
Using PowerSimulationsDynamics
tools for exploring the results, we can plot all the voltage results for the buses
julia> result = read_results(sim)
ERROR: UndefVarError: `sim` not defined
julia> p = plot();
julia> for b in get_components(ACBus, sys) voltage_series = get_voltage_magnitude_series(result, get_number(b)) plot!( p, voltage_series; xlabel = "Time", ylabel = "Voltage Magnitude [pu]", label = "Bus - $(get_name(b))", ); end
ERROR: UndefVarError: `sys` not defined
We can also explore the frequency of the different static generators and storage
julia> p2 = plot();
julia> for g in get_components(ThermalStandard, sys) state_series = get_state_series(result, (get_name(g), :ω)) plot!( p2, state_series; xlabel = "Time", ylabel = "Speed [pu]", label = "$(get_name(g)) - ω", ); end
ERROR: UndefVarError: `sys` not defined
julia> state_series = get_state_series(result, ("Battery", :ω_oc))
ERROR: UndefVarError: `result` not defined
julia> plot!(p2, state_series; xlabel = "Time", ylabel = "Speed [pu]", label = "Battery - ω");
ERROR: UndefVarError: `state_series` not defined