From ba277d72ad2323dbc62b2b1fb23faa3e4cef0986 Mon Sep 17 00:00:00 2001 From: rodrigomha Date: Fri, 5 Apr 2024 13:19:30 -0700 Subject: [PATCH] update removal of components --- src/portfolio.jl | 196 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 138 insertions(+), 58 deletions(-) diff --git a/src/portfolio.jl b/src/portfolio.jl index 121b6d3..1e9e43d 100644 --- a/src/portfolio.jl +++ b/src/portfolio.jl @@ -77,7 +77,7 @@ function add_technology!( skip_validation=false, kwargs..., ) where {T <: Technology} - IS.add_technology!( + IS.add_component!( portfolio.data, technology; allow_existing_time_series=deserialization_in_progress, @@ -168,66 +168,71 @@ function get_technologies( ) end -""" -Add time series data to a component. +# These are helper functions for debugging problems. +# Searches components linearly, and so is slow compared to the other get_component functions +get_technology(portfolio::Portfolio, uuid::Base.UUID) = + IS.get_component(portfolio.data, uuid) +get_technology(portfolio::Portfolio, uuid::String) = + IS.get_component(portfolio.data, Base.UUID(uuid)) -Throws ArgumentError if the component is not stored in the system. -""" -function add_time_series!( - portfolio::Portfolio, - component::Technology, - time_series::TimeSeriesData, +function _get_technologies_by_name( + abstract_types, + data::IS.SystemData, + name::AbstractString, ) - return IS.add_time_series!(portfolio.data, component, time_series) + _components = [] + for subtype in abstract_types + component = IS.get_component(subtype, data, name) + if !isnothing(component) + push!(_components, component) + end + end + + return _components end """ -Add the same time series data to multiple components. +Get the technologies of abstract type T with name. Note that PowerSystems enforces unique +names on each concrete type but not across concrete types. -This is significantly more efficent than calling `add_time_series!` for each component -individually with the same data because in this case, only one time series array is stored. +See [`get_technology`](@ref) if the concrete type is known. -Throws ArgumentError if a component is not stored in the system. +Throws ArgumentError if T is not an abstract type. """ -function add_time_series!(portfolio::Portfolio, technologies, time_series::TimeSeriesData) - return IS.add_time_series!(portfolio.data, technologies, time_series) +function get_components_by_name( + ::Type{T}, + portfolio::Portfolio, + name::AbstractString, +) where {T <: Component} + return IS.get_components_by_name(T, portfolio.data, name) end """ -Return the compression settings used for system data such as time series arrays. +Gets components availability. Requires type T to have the method get_available implemented. """ -get_compression_settings(portfolio::Portfolio) = IS.get_compression_settings(portfolio.data) -""" -Return the resolution for all time series. -""" -get_time_series_resolution(portfolio::Portfolio) = - IS.get_time_series_resolution(portfolio.data) +function get_available_technologies(::Type{T}, portfolio::Portfolio) where {T <: Technology} + return get_technologies(x -> get_available(x), T, portfolio) +end """ -Remove all time series data from the system. +Return true if the component is attached to the system. """ -function clear_time_series!(portfolio::Portfolio) - return IS.clear_time_series!(portfolio.data) +function is_attached(technology::T, portfolio::Porftolio) where {T <: Technology} + return is_attached(T, get_name(technology), portfolio) end -""" -Remove the time series data for a component and time series type. -""" -function remove_time_series!( - portfolio::Portfolio, - ::Type{T}, - component::Component, - name::String, -) where {T <: TimeSeriesData} - return IS.remove_time_series!(portfolio.data, T, component, name) +function is_attached(::Type{T}, name, portfolio::Portfolio) where {T <: Technology} + return !isnothing(get_technology(T, portfolio, name)) end """ -Remove all the time series data for a time series type. +Throws ArgumentError if the component is not attached to the system. """ -function remove_time_series!(portfolio::Portfolio, ::Type{T}) where {T <: TimeSeriesData} - return IS.remove_time_series!(portfolio.data, T) +function throw_if_not_attached(component::Component, sys::System) + if !is_attached(component, sys) + throw(ArgumentError("$(summary(component)) is not attached to the system")) + end end """ @@ -279,6 +284,87 @@ function remove_technologies!( return components end +handle_technology_removal!(::Portfolio, component::Component) = nothing + +function handle_component_removal!(portfolio::Portfolio, technology::Technology) + _handle_technology_removal_common!(technology) + # This may have to be refactored if handle_component_removal! needs to be implemented + # for a subtype. + # TODO: Check if clear_services makes sense for technologies + # clear_services!(technology) + return +end + +function _handle_technology_removal_common!(technology) + clear_units!(technology) +end + +################################### +########### Time Series ########### +################################### + +""" +Add time series data to a component. + +Throws ArgumentError if the component is not stored in the system. +""" +function add_time_series!( + portfolio::Portfolio, + component::Technology, + time_series::TimeSeriesData, +) + return IS.add_time_series!(portfolio.data, component, time_series) +end + +""" +Add the same time series data to multiple components. + +This is significantly more efficent than calling `add_time_series!` for each component +individually with the same data because in this case, only one time series array is stored. + +Throws ArgumentError if a component is not stored in the system. +""" +function add_time_series!(portfolio::Portfolio, technologies, time_series::TimeSeriesData) + return IS.add_time_series!(portfolio.data, technologies, time_series) +end + +""" +Return the compression settings used for system data such as time series arrays. +""" +get_compression_settings(portfolio::Portfolio) = IS.get_compression_settings(portfolio.data) + +""" +Return the resolution for all time series. +""" +get_time_series_resolution(portfolio::Portfolio) = + IS.get_time_series_resolution(portfolio.data) + +""" +Remove all time series data from the system. +""" +function clear_time_series!(portfolio::Portfolio) + return IS.clear_time_series!(portfolio.data) +end + +""" +Remove the time series data for a component and time series type. +""" +function remove_time_series!( + portfolio::Portfolio, + ::Type{T}, + component::Component, + name::String, +) where {T <: TimeSeriesData} + return IS.remove_time_series!(portfolio.data, T, component, name) +end + +""" +Remove all the time series data for a time series type. +""" +function remove_time_series!(portfolio::Portfolio, ::Type{T}) where {T <: TimeSeriesData} + return IS.remove_time_series!(portfolio.data, T) +end + #= ### Not sure if these methods make sense for technologies """ @@ -306,6 +392,19 @@ function set_name!(technology::Technology, name::AbstractString) technology.name = name end + +""" +Check system consistency and validity. +""" +function check(sys::System) + buses = get_components(ACBus, sys) + slack_bus_check(buses) + buscheck(buses) + critical_components_check(sys) + adequacy_check(sys) + return +end + =# function clear_units!(technology::Technology) @@ -369,25 +468,6 @@ function has_technology( return IS.has_component(T, portfolio.data.components, name) end -""" -Get the technology of type T with name. Returns nothing if no technology matches. If T is an abstract -type then the names of technologies across all subtypes of T must be unique. - -See [`get_technologies_by_name`](@ref) for abstract types with non-unique names across subtypes. - -Throws ArgumentError if T is not a concrete type and there is more than one component with -requested name -""" -function get_component( - ::Type{T}, - portfolio::Portfolio, - name::AbstractString, -) where {T <: Technology} - return IS.get_component(T, portfolio.data, name) -end - -## To continue: base.jl in PSY line 887. - function IS.serialize(portfolio::Portfolio) return end