From a5bcfc92961beaa31d98df4209a4ac65f80709b4 Mon Sep 17 00:00:00 2001 From: Jose Daniel Lara Date: Tue, 27 Feb 2024 10:25:19 -0700 Subject: [PATCH 1/6] re-implement outages --- src/PowerSystems.jl | 6 ++- src/contingencies.jl | 1 + src/outages.jl | 98 +++++++++++++++++++++++++++++++++----------- 3 files changed, 80 insertions(+), 25 deletions(-) create mode 100644 src/contingencies.jl diff --git a/src/PowerSystems.jl b/src/PowerSystems.jl index 201ec612b7..c61f5e25f2 100644 --- a/src/PowerSystems.jl +++ b/src/PowerSystems.jl @@ -220,10 +220,13 @@ export PriorityCurrentLimiter export Source export PeriodicVariableSource +export Contingency + # Outages export Outage -export ForcedOutage +export GeometricDistributionForcedOutage export PlannedOutage +export TimeSeriesForcedOutage export Service export AbstractReserve @@ -620,6 +623,7 @@ include("models/supplemental_constructors.jl") include("models/supplemental_accessors.jl") # Supplemental attributes +include("contingencies.jl") include("outages.jl") # Definitions of PowerSystem diff --git a/src/contingencies.jl b/src/contingencies.jl new file mode 100644 index 0000000000..e66f59a391 --- /dev/null +++ b/src/contingencies.jl @@ -0,0 +1 @@ +abstract type Contingency <: SupplementalAttribute end diff --git a/src/outages.jl b/src/outages.jl index 302c98fcd4..dad3a97557 100644 --- a/src/outages.jl +++ b/src/outages.jl @@ -1,56 +1,74 @@ -abstract type Outage <: SupplementalAttribute end +abstract type Outage <: Contigency end -struct ForcedOutage <: Outage - forced_outage_rate::Float64 - mean_time_to_recovery::Int +"""Get `components_uuid`.""" +get_component_uuids(x::Outage) = x.component_uuids +"""Get `internal`.""" +get_internal(x::Outage) = x.internal +"""Get `time_series_container`.""" +get_time_series_container(x::Outage) = x.time_series_container + +""" +Attribute that contains information regarding forced outages modeled with a +geometric distribution. The outage probabilities and recovery times can be modeled as time +series. + +# Arguments +- `time_to_recovery::Int`: Time elapsed to recovery after a failure in Milliseconds. +- `outage_probability::Float64`: Characterizes the probability of failure (1 - p) in the geometric distribution. +- `time_series_container::InfrastructureSystems.TimeSeriesContainer`: internal time_series storage +- `internal::InfrastructureSystemsInternal`: power system internal reference, do not modify +""" +struct GeometricDistributionForcedOutage <: Outage + time_to_recovery::Int outage_probability::Float64 - recovery_probability::Float64 time_series_container::InfrastructureSystems.TimeSeriesContainer component_uuids::InfrastructureSystems.ComponentUUIDs internal::InfrastructureSystemsInternal end -function ForcedOutage(; - forced_outage_rate = 0.0, - mean_time_to_recovery = 0, +function GeometricDistributionForcedOutage(; + time_to_recovery = 0.0, outage_probability = 0.0, - recovery_probability = 0.0, time_series_container = InfrastructureSystems.TimeSeriesContainer(), component_uuids = InfrastructureSystems.ComponentUUIDs(), internal = InfrastructureSystemsInternal(), ) - return ForcedOutage( - forced_outage_rate, - mean_time_to_recovery, + return GeometricDistributionForcedOutage( + time_to_recovery, outage_probability, - recovery_probability, time_series_container, component_uuids, internal, ) end -get_component_uuids(x::ForcedOutage) = x.component_uuids -get_internal(x::ForcedOutage) = x.internal -get_time_series_container(x::ForcedOutage) = x.time_series_container +"""Get [`GeometricDistributionForcedOutage`](@ref) `time_to_recovery`.""" +get_time_to_recovery(value::GeometricDistributionForcedOutage) = value.time_to_recovery +"""Get [`GeometricDistributionForcedOutage`](@ref) `outage_probability`.""" +get_outage_probability(value::GeometricDistributionForcedOutage) = value.outage_probability + +""" +Attribute that contains information regarding planned outages. +# Arguments +- `outage_schedule::String`: String name of the time series used for the scheduled outages +- `time_series_container::InfrastructureSystems.TimeSeriesContainer`: internal time_series storage +- `internal::InfrastructureSystemsInternal`: power system internal reference, do not modify +""" struct PlannedOutage <: Outage - time_to_recovery::Int - outage_schedule::Int + outage_schedule::String time_series_container::InfrastructureSystems.TimeSeriesContainer component_uuids::InfrastructureSystems.ComponentUUIDs internal::InfrastructureSystemsInternal end function PlannedOutage(; - time_to_recovery = 0, - outage_schedule = 0.0, + outage_schedule, time_series_container = InfrastructureSystems.TimeSeriesContainer(), component_uuids = InfrastructureSystems.ComponentUUIDs(), internal = InfrastructureSystemsInternal(), ) return PlannedOutage( - time_to_recovery, outage_schedule, time_series_container, component_uuids, @@ -58,6 +76,38 @@ function PlannedOutage(; ) end -get_component_uuids(x::PlannedOutage) = x.component_uuids -get_internal(x::PlannedOutage) = x.internal -get_time_series_container(x::PlannedOutage) = x.time_series_container +"""Get [`PlannedOutage`](@ref) `outage_schedule`.""" +get_outage_schedule(value::PlannedOutage) = value.outage_schedule + +""" +Attribute that contains information for time series representation of forced outages. The +data can be obtained from a simulation or historical information. + +# Arguments +- `outage_scenario::String`: String name of the time series used for the forced outage in the model +- `time_series_container::InfrastructureSystems.TimeSeriesContainer`: internal time_series storage +- `internal::InfrastructureSystemsInternal`: power system internal reference, do not modify +""" +struct TimeSeriesForcedOutage <: Outage + outage_scenario::String + time_series_container::InfrastructureSystems.TimeSeriesContainer + component_uuids::InfrastructureSystems.ComponentUUIDs + internal::InfrastructureSystemsInternal +end + +function TimeSeriesForcedOutage(; + outage_scenario, + time_series_container = InfrastructureSystems.TimeSeriesContainer(), + component_uuids = InfrastructureSystems.ComponentUUIDs(), + internal = InfrastructureSystemsInternal(), +) + return TimeSeriesForcedOutage( + outage_scenario, + time_series_container, + component_uuids, + internal, + ) +end + +"""Get [`TimeSeriesForcedOutage`](@ref) `outage_scenario`.""" +get_outage_scenario(value::TimeSeriesForcedOutage) = value.outage_scenario From 3f9dae7cfe12acbe28b4ac3fa5dee3b58a11d6d7 Mon Sep 17 00:00:00 2001 From: Jose Daniel Lara Date: Tue, 27 Feb 2024 10:40:43 -0700 Subject: [PATCH 2/6] update test code --- test/common.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/common.jl b/test/common.jl index 88c3975dcd..f4d7512f5d 100644 --- a/test/common.jl +++ b/test/common.jl @@ -226,10 +226,10 @@ function create_system_with_outages() initial_time = Dates.DateTime("2020-01-01T00:00:00") end_time = Dates.DateTime("2020-01-01T23:00:00") dates = collect(initial_time:Dates.Hour(1):end_time) - fo1 = ForcedOutage(; forced_outage_rate = 1.0) - fo2 = ForcedOutage(; forced_outage_rate = 2.0) - po1 = PlannedOutage(; outage_schedule = 3.0) - po2 = PlannedOutage(; outage_schedule = 4.0) + fo1 = GeometricDistributionForcedOutage(; outage_probability = 0.5) + fo2 = GeometricDistributionForcedOutage(; outage_probability = 0.5) + po1 = PlannedOutage(; outage_schedule = "1") + po2 = PlannedOutage(; outage_schedule = "1") add_supplemental_attribute!(sys, gen1, fo1) add_supplemental_attribute!(sys, gen1, po1) add_supplemental_attribute!(sys, gen2, fo2) From 492969a6d28ff39998663e6dc9f3d93896b8a65c Mon Sep 17 00:00:00 2001 From: Jose Daniel Lara Date: Tue, 27 Feb 2024 10:40:53 -0700 Subject: [PATCH 3/6] add time to recovery for time series outages --- src/outages.jl | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/outages.jl b/src/outages.jl index dad3a97557..d2752e72ae 100644 --- a/src/outages.jl +++ b/src/outages.jl @@ -80,16 +80,18 @@ end get_outage_schedule(value::PlannedOutage) = value.outage_schedule """ -Attribute that contains information for time series representation of forced outages. The -data can be obtained from a simulation or historical information. +Attribute that contains information for time series representation for the start of forced outages. +The data can be obtained from a simulation or historical information. # Arguments +- `time_to_recovery::Int`: Time elapsed to recovery after a failure in Milliseconds. - `outage_scenario::String`: String name of the time series used for the forced outage in the model - `time_series_container::InfrastructureSystems.TimeSeriesContainer`: internal time_series storage - `internal::InfrastructureSystemsInternal`: power system internal reference, do not modify """ struct TimeSeriesForcedOutage <: Outage outage_scenario::String + time_to_recovery::Int time_series_container::InfrastructureSystems.TimeSeriesContainer component_uuids::InfrastructureSystems.ComponentUUIDs internal::InfrastructureSystemsInternal @@ -109,5 +111,7 @@ function TimeSeriesForcedOutage(; ) end +"""Get [`GeometricDistributionForcedOutage`](@ref) `time_to_recovery`.""" +get_time_to_recovery(value::GeometricDistributionForcedOutage) = value.time_to_recovery """Get [`TimeSeriesForcedOutage`](@ref) `outage_scenario`.""" get_outage_scenario(value::TimeSeriesForcedOutage) = value.outage_scenario From 42c2514c1ff6c4e2007fe96c12be4fdb0885ab02 Mon Sep 17 00:00:00 2001 From: Jose Daniel Lara Date: Tue, 27 Feb 2024 11:55:18 -0700 Subject: [PATCH 4/6] minor changes --- src/outages.jl | 44 +++++++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/src/outages.jl b/src/outages.jl index d2752e72ae..f6415e7215 100644 --- a/src/outages.jl +++ b/src/outages.jl @@ -8,34 +8,34 @@ get_internal(x::Outage) = x.internal get_time_series_container(x::Outage) = x.time_series_container """ -Attribute that contains information regarding forced outages modeled with a -geometric distribution. The outage probabilities and recovery times can be modeled as time +Attribute that contains information regarding forced outages where the transition probabilities +are modeled with geometric distributions. The outage probabilities and recovery probabilities can be modeled as time series. # Arguments - `time_to_recovery::Int`: Time elapsed to recovery after a failure in Milliseconds. -- `outage_probability::Float64`: Characterizes the probability of failure (1 - p) in the geometric distribution. +- `outage_transition_probability::Float64`: Characterizes the probability of failure (1 - p) in the geometric distribution. - `time_series_container::InfrastructureSystems.TimeSeriesContainer`: internal time_series storage - `internal::InfrastructureSystemsInternal`: power system internal reference, do not modify """ struct GeometricDistributionForcedOutage <: Outage - time_to_recovery::Int - outage_probability::Float64 + mean_time_to_recovery::Float64 + outage_transition_probability::Float64 time_series_container::InfrastructureSystems.TimeSeriesContainer component_uuids::InfrastructureSystems.ComponentUUIDs internal::InfrastructureSystemsInternal end function GeometricDistributionForcedOutage(; - time_to_recovery = 0.0, - outage_probability = 0.0, + mean_time_to_recovery = 0.0, + outage_transition_probability = 0.0, time_series_container = InfrastructureSystems.TimeSeriesContainer(), component_uuids = InfrastructureSystems.ComponentUUIDs(), internal = InfrastructureSystemsInternal(), ) return GeometricDistributionForcedOutage( - time_to_recovery, - outage_probability, + mean_time_to_recovery, + outage_transition_probability, time_series_container, component_uuids, internal, @@ -43,9 +43,11 @@ function GeometricDistributionForcedOutage(; end """Get [`GeometricDistributionForcedOutage`](@ref) `time_to_recovery`.""" -get_time_to_recovery(value::GeometricDistributionForcedOutage) = value.time_to_recovery +get_mean_time_to_recovery(value::GeometricDistributionForcedOutage) = + value.mean_time_to_recovery """Get [`GeometricDistributionForcedOutage`](@ref) `outage_probability`.""" -get_outage_probability(value::GeometricDistributionForcedOutage) = value.outage_probability +get_outage_transition_probability(value::GeometricDistributionForcedOutage) = + value.outage_transition_probability """ Attribute that contains information regarding planned outages. @@ -80,38 +82,34 @@ end get_outage_schedule(value::PlannedOutage) = value.outage_schedule """ -Attribute that contains information for time series representation for the start of forced outages. -The data can be obtained from a simulation or historical information. +Attribute that contains the representation of the status of the component forced outage. +The data can be obtained from the simulation of an stochastic process or historical information. # Arguments -- `time_to_recovery::Int`: Time elapsed to recovery after a failure in Milliseconds. -- `outage_scenario::String`: String name of the time series used for the forced outage in the model +- `outage_status_scenario::String`: String name of the time series used for the forced outage status in the model. 1 is used represent outaged and 0 for available. - `time_series_container::InfrastructureSystems.TimeSeriesContainer`: internal time_series storage - `internal::InfrastructureSystemsInternal`: power system internal reference, do not modify """ struct TimeSeriesForcedOutage <: Outage - outage_scenario::String - time_to_recovery::Int + outage_status_scenario::String time_series_container::InfrastructureSystems.TimeSeriesContainer component_uuids::InfrastructureSystems.ComponentUUIDs internal::InfrastructureSystemsInternal end function TimeSeriesForcedOutage(; - outage_scenario, + outage_status_scenario, time_series_container = InfrastructureSystems.TimeSeriesContainer(), component_uuids = InfrastructureSystems.ComponentUUIDs(), internal = InfrastructureSystemsInternal(), ) return TimeSeriesForcedOutage( - outage_scenario, + outage_status_scenario, time_series_container, component_uuids, internal, ) end -"""Get [`GeometricDistributionForcedOutage`](@ref) `time_to_recovery`.""" -get_time_to_recovery(value::GeometricDistributionForcedOutage) = value.time_to_recovery -"""Get [`TimeSeriesForcedOutage`](@ref) `outage_scenario`.""" -get_outage_scenario(value::TimeSeriesForcedOutage) = value.outage_scenario +"""Get [`TimeSeriesForcedOutage`](@ref) `outage_status_scenario`.""" +get_outage_status_scenario(value::TimeSeriesForcedOutage) = value.outage_status_scenario From 89d7571dc785890dbf70b1781bf19b8e8ea49621 Mon Sep 17 00:00:00 2001 From: Jose Daniel Lara Date: Tue, 27 Feb 2024 11:57:31 -0700 Subject: [PATCH 5/6] fix typo --- src/outages.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/outages.jl b/src/outages.jl index f6415e7215..1dd0ba7961 100644 --- a/src/outages.jl +++ b/src/outages.jl @@ -1,4 +1,4 @@ -abstract type Outage <: Contigency end +abstract type Outage <: Contingency end """Get `components_uuid`.""" get_component_uuids(x::Outage) = x.component_uuids From 2f728af86a974cfe41eaae9f09c3cdda727abdc4 Mon Sep 17 00:00:00 2001 From: Jose Daniel Lara Date: Tue, 27 Feb 2024 18:17:36 -0700 Subject: [PATCH 6/6] simplify get_available_components --- src/base.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/base.jl b/src/base.jl index 234c79a399..dd43cddbc7 100644 --- a/src/base.jl +++ b/src/base.jl @@ -972,7 +972,7 @@ Gets components availability. Requires type T to have the method get_available i """ function get_available_components(::Type{T}, sys::System) where {T <: Component} - return get_components(x -> get_available(x), T, sys) + return get_components(get_available, T, sys) end """