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 = PowerSystemsPowerSystems
julia> using PowerFlows
julia> using Logging
julia> using Sundials
julia> using Plots
Note

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))", ); endERROR: UndefVarError: `sys` not defined

plot

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)) - ω", ); endERROR: UndefVarError: `sys` not defined

plot

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.eigenvaluesERROR: 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 systemERROR: 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> sysERROR: 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.eigenvaluesERROR: 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))", ); endERROR: UndefVarError: `sys` not defined

plot

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)) - ω", ); endERROR: 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

plot