Quick Start Guide
The data for these tutorials is provided in PowerSystemCaseBuilder. If you want to build your own case, take a look at the tutorial Creating and Handling Data for Dynamic Simulations
For more details about loading data and adding more dynamic components check the Creating a System with Dynamic devices section of the documentation in PowerSystems.jl
.
For a detailed tutorial about this case visit One Machine against Infinite Bus (OMIB) Simulation
Loading data
Data can be loaded from a pss/e raw file and a pss/e dyr file.
julia> using PowerSystems
julia> using PowerSimulationsDynamics
julia> using PowerSystemCaseBuilder
julia> using Sundials
julia> using Plots
julia> omib_sys = build_system(PSIDSystems, "OMIB System")
┌ Info: Building new system OMIB System from raw data └ sys_descriptor.raw_data = "" ┌ Warning: System is saved in the data format version 2.0.0 will be automatically upgraded to 3.0.0 upon saving └ @ PowerSystems ~/.julia/packages/PowerSystems/xh3fM/src/data_format_conversions.jl:82 ┌ Warning: struct ACBus does not exist in validation configuration file, validation skipped └ @ InfrastructureSystems ~/.julia/packages/InfrastructureSystems/9btGb/src/validation.jl:51 ┌ Warning: struct ACBus does not exist in validation configuration file, validation skipped └ @ InfrastructureSystems ~/.julia/packages/InfrastructureSystems/9btGb/src/validation.jl:51 ┌ Warning: struct DynamicGenerator does not exist in validation configuration file, validation skipped └ @ InfrastructureSystems ~/.julia/packages/InfrastructureSystems/9btGb/src/validation.jl:51 ┌ Warning: field prime_mover_type does not exist in ThermalStandard validation config └ @ InfrastructureSystems ~/.julia/packages/InfrastructureSystems/9btGb/src/validation.jl:65 ┌ Warning: struct DynamicGenerator does not exist in validation configuration file, validation skipped └ @ InfrastructureSystems ~/.julia/packages/InfrastructureSystems/9btGb/src/validation.jl:51 ┌ Warning: System is saved in the data format version 2.0.0 will be automatically upgraded to 3.0.0 upon saving └ @ PowerSystems ~/.julia/packages/PowerSystems/xh3fM/src/data_format_conversions.jl:110 ┌ Warning: There are no ElectricLoad Components in the System └ @ PowerSystems ~/.julia/packages/PowerSystems/xh3fM/src/utils/IO/system_checks.jl:59 [ Info: Serialized System to /home/runner/.julia/packages/PowerSystemCaseBuilder/vlTjU/data/serialized_system/NoArgs/OMIB System.json [ Info: Serialized System metadata to /home/runner/.julia/packages/PowerSystemCaseBuilder/vlTjU/data/serialized_system/NoArgs/OMIB System_metadata.json System ┌───────────────────┬─────────────┐ │ Property │ Value │ ├───────────────────┼─────────────┤ │ Name │ │ │ Description │ │ │ System Units Base │ SYSTEM_BASE │ │ Base Power │ 100.0 │ │ Base Frequency │ 60.0 │ │ Num Components │ 10 │ └───────────────────┴─────────────┘ Static Components ┌─────────────────┬───────┬────────────────────────┬───────────────┐ │ Type │ Count │ Has Static Time Series │ Has Forecasts │ ├─────────────────┼───────┼────────────────────────┼───────────────┤ │ ACBus │ 2 │ false │ false │ │ Arc │ 1 │ false │ false │ │ Area │ 1 │ false │ false │ │ Line │ 2 │ false │ false │ │ LoadZone │ 1 │ false │ false │ │ Source │ 1 │ false │ false │ │ ThermalStandard │ 1 │ false │ false │ └─────────────────┴───────┴────────────────────────┴───────────────┘ Dynamic Components ┌──────────────────┬───────┐ │ Type │ Count │ ├──────────────────┼───────┤ │ DynamicGenerator │ 1 │ └──────────────────┴───────┘
Define the Simulation
julia> time_span = (0.0, 30.0)
(0.0, 30.0)
julia> perturbation_trip = BranchTrip(1.0, Line, "BUS 1-BUS 2-i_1")
BranchTrip(1.0, Line, "BUS 1-BUS 2-i_1")
julia> sim = Simulation!(ResidualModel, omib_sys, pwd(), time_span, perturbation_trip)
[ Info: Unit System changed to UnitSystem.DEVICE_BASE = 1 Simulation Summary ┌─────────────────────────┬────────────────┐ │ Property │ Value │ ├─────────────────────────┼────────────────┤ │ Status │ BUILT │ │ Simulation Type │ Residual Model │ │ Initialized? │ Yes │ │ Multimachine system? │ No │ │ Time Span │ (0.0, 30.0) │ │ Number of States │ 6 │ │ Number of Perturbations │ 1 │ └─────────────────────────┴────────────────┘
Explore initial conditions for the simulation
julia> x0_init = read_initial_conditions(sim)
Dict{String, Any} with 5 entries: "generator-102-1" => Dict(:ω=>1.0, :δ=>0.168525) "V_R" => Dict(102=>1.03973, 101=>1.05) "Vm" => Dict(102=>1.04, 101=>1.05) "θ" => Dict(102=>0.0228958, 101=>0.0) "V_I" => Dict(102=>0.0238095, 101=>0.0)
julia> show_states_initial_value(sim)
Voltage Variables ==================== BUS 1 ==================== Vm 1.05 θ 0.0 ==================== BUS 2 ==================== Vm 1.04 θ 0.0229 ==================== ==================== Differential States generator-102-1 ==================== δ 0.1685 ω 1.0 ====================
Obtain small signal results for initial conditions
Show eigenvalues for operating point
julia> small_sig = small_signal_analysis(sim)
The system is small signal stable
julia> summary_eigenvalues(small_sig)
2×6 DataFrame Row │ Most Associated Part. Factor Real Part Imag. Part Damping [%] Fr ⋯ │ Any Any Any Any Any An ⋯ ─────┼────────────────────────────────────────────────────────────────────────── 1 │ generator-102-1 δ 0.5 -0.158831 -13.2643 1.19735 2. ⋯ 2 │ generator-102-1 δ 0.5 -0.158831 13.2643 1.19735 2. 1 column omitted
Execute the simulation
julia> execute!(sim, IDA(), dtmax = 0.02, saveat = 0.02, enable_progress_bar = false)
SIMULATION_FINALIZED::BUILD_STATUS = 6
Make a plot of the results
julia> results = read_results(sim)
Simulation Results Summary ┌────────────────────────────┬─────────────┐ │ Property │ Value │ ├────────────────────────────┼─────────────┤ │ System Base Power [MVA] │ 100.0 │ │ System Base Frequency [Hz] │ 60.0 │ │ Time Span │ (0.0, 30.0) │ │ Total Time Steps │ 1502 │ │ Number of States │ 6 │ │ Total solve time │ 2.051573684 │ └────────────────────────────┴─────────────┘
julia> angle = get_state_series(results, ("generator-102-1", :δ));
julia> plot(angle, xlabel = "time", ylabel = "rotor angle [rad]", label = "gen-102-1")
Plot{Plots.GRBackend() n=1}
If you miss PSS/e's plotting aesthetics and want something that resembles that, you can use UnicodePlots
.
julia> using UnicodePlots
julia> unicodeplots()
Plots.UnicodePlotsBackend()
julia> plot(angle, xlabel = "time", ylabel = "rotor angle [rad]", label = "gen-102-1");