diff --git a/src/PowerSimulations.jl b/src/PowerSimulations.jl index 099a5f50a..c319cf5f9 100644 --- a/src/PowerSimulations.jl +++ b/src/PowerSimulations.jl @@ -393,9 +393,15 @@ import InfrastructureSystems.Optimization: import InfrastructureSystems.Optimization: read_results_with_keys, deserialize_key, encode_key_as_string, encode_keys_as_strings, should_write_resulting_value, convert_result_to_natural_units, to_matrix, get_store_container_type +import InfrastructureSystems.Optimization: get_source_data # IS.Optimization imports that stay private, may or may not be additional methods in PowerSimulations +# PowerSystems imports +import PowerSystems: + get_components, get_component, get_available_components, get_available_component, + get_groups, get_available_groups + export get_name export get_model_base_power export get_optimizer_stats @@ -530,6 +536,7 @@ include("simulation/simulation_store_params.jl") include("simulation/hdf_simulation_store.jl") include("simulation/in_memory_simulation_store.jl") include("simulation/simulation_problem_results.jl") +include("simulation/get_components_interface.jl") include("simulation/decision_model_simulation_results.jl") include("simulation/emulation_model_simulation_results.jl") include("simulation/realized_meta.jl") diff --git a/src/simulation/get_components_interface.jl b/src/simulation/get_components_interface.jl new file mode 100644 index 000000000..4f91707f9 --- /dev/null +++ b/src/simulation/get_components_interface.jl @@ -0,0 +1,74 @@ +# Analogous to `src/get_components_interface.jl` in PowerSystems.jl, see comments there. + +# get_components +""" +Calling `get_components` on a `Results` is the same as calling +[`get_available_components`] on the system attached to the results. +""" +PSY.get_components( + ::Type{T}, + res::IS.Results; + subsystem_name = nothing, +) where {T <: IS.InfrastructureSystemsComponent} = + IS.get_components(T, res; subsystem_name = subsystem_name) + +PSY.get_components(res::IS.Results, attribute::IS.SupplementalAttribute) = + IS.get_components(res, attribute) + +PSY.get_components( + filter_func::Function, + ::Type{T}, + res::IS.Results; + subsystem_name = nothing, +) where {T <: IS.InfrastructureSystemsComponent} = + IS.get_components(filter_func, T, res; subsystem_name = subsystem_name) + +PSY.get_components( + scope_limiter::Union{Function, Nothing}, + selector::IS.ComponentSelector, + res::IS.Results, +) = + IS.get_components(scope_limiter, selector, res) + +PSY.get_components(selector::IS.ComponentSelector, res::IS.Results) = + IS.get_components(selector, res) + +# get_component +""" +Calling `get_component` on a `Results` is the same as calling +[`get_available_component`] on the system attached to the results. +""" +PSY.get_component(res::IS.Results, uuid::Base.UUID) = IS.get_component(res, uuid) +PSY.get_component(res::IS.Results, uuid::String) = IS.get_component(res, uuid) + +PSY.get_component( + ::Type{T}, + res::IS.Results, + name::AbstractString, +) where {T <: IS.InfrastructureSystemsComponent} = + IS.get_component(T, res, name) + +PSY.get_component( + scope_limiter::Union{Function, Nothing}, + selector::IS.SingularComponentSelector, + res::IS.Results, +) = + IS.get_component(scope_limiter, selector, res) + +PSY.get_component(selector::IS.SingularComponentSelector, res::IS.Results) = + IS.get_component(selector, res) + +# get_groups +""" +Calling `get_groups` on a `Results` is the same as calling [`get_available_groups`] on +the system attached to the results. +""" +PSY.get_groups( + scope_limiter::Union{Function, Nothing}, + selector::IS.ComponentSelector, + res::IS.Results, +) = + IS.get_groups(scope_limiter, selector, res) + +PSY.get_groups(selector::IS.ComponentSelector, res::IS.Results) = + IS.get_groups(selector, res) diff --git a/src/simulation/simulation_problem_results.jl b/src/simulation/simulation_problem_results.jl index faa327d54..6bff5e061 100644 --- a/src/simulation/simulation_problem_results.jl +++ b/src/simulation/simulation_problem_results.jl @@ -62,6 +62,7 @@ end get_model_name(res::SimulationProblemResults) = res.problem get_system(res::SimulationProblemResults) = res.system +get_source_data(res::SimulationProblemResults) = get_system(res) # Needed for compatibility with the IS.Results interface get_resolution(res::SimulationProblemResults) = res.resolution get_execution_path(res::SimulationProblemResults) = res.execution_path get_model_base_power(res::SimulationProblemResults) = res.base_power diff --git a/test/test_model_decision.jl b/test/test_model_decision.jl index 6b1d1abc9..3407c3d0d 100644 --- a/test/test_model_decision.jl +++ b/test/test_model_decision.jl @@ -236,6 +236,13 @@ end @test isa(get_realized_timestamps(res), StepRange{DateTime}) @test isa(IS.Optimization.get_source_data(res), PSY.System) @test length(get_timestamps(res)) == 24 + + PSY.set_available!(first(get_components(ThermalStandard, get_system(res))), false) + @test collect(get_components(ThermalStandard, res)) == + collect(get_available_components(ThermalStandard, get_system(res))) + sel = PSY.make_selector(ThermalStandard; groupby = :each) + @test collect(get_groups(sel, res)) == + collect(get_available_groups(sel, get_system(res))) end @testset "Solve DecisionModelModel with auto-build" begin diff --git a/test/test_simulation_results.jl b/test/test_simulation_results.jl index d3ec74477..4bca6f8ac 100644 --- a/test/test_simulation_results.jl +++ b/test/test_simulation_results.jl @@ -313,6 +313,23 @@ function test_decision_problem_results_values( @test IS.get_uuid(get_system(results_uc)) === IS.get_uuid(c_sys5_hy_uc) @test IS.get_uuid(get_system(results_ed)) === IS.get_uuid(c_sys5_hy_ed) + # Temporarily mark some stuff unavailable + unav_uc = first(PSY.get_available_components(ThermalStandard, get_system(results_uc))) + PSY.set_available!(unav_uc, false) + unav_ed = first(PSY.get_available_components(ThermalStandard, get_system(results_ed))) + PSY.set_available!(unav_ed, false) + sel = PSY.make_selector(ThermalStandard; groupby = :each) + @test collect(get_components(ThermalStandard, results_uc)) == + collect(get_available_components(ThermalStandard, get_system(results_uc))) + @test collect(get_components(ThermalStandard, results_ed)) == + collect(get_available_components(ThermalStandard, get_system(results_ed))) + @test collect(get_groups(sel, results_uc)) == + collect(get_available_groups(sel, get_system(results_uc))) + @test collect(get_groups(sel, results_ed)) == + collect(get_available_groups(sel, get_system(results_ed))) + PSY.set_available!(unav_uc, true) + PSY.set_available!(unav_ed, true) + @test isempty(setdiff(UC_EXPECTED_VARS, list_variable_names(results_uc))) @test isempty(setdiff(ED_EXPECTED_VARS, list_variable_names(results_ed)))