From c21acf3c6212e370318ee73ff5f6570e5645f4ef Mon Sep 17 00:00:00 2001 From: Jose Daniel Lara Date: Thu, 4 Apr 2024 11:30:03 -0600 Subject: [PATCH] changes to support simulation --- src/algorithms/sequential_algorithm.jl | 5 ++- src/multi_optimization_container.jl | 1 + src/multiproblem_template.jl | 30 +++++++++++++--- src/problems/multi_region_problem.jl | 47 ++++++++++++++++++++++++-- 4 files changed, 73 insertions(+), 10 deletions(-) diff --git a/src/algorithms/sequential_algorithm.jl b/src/algorithms/sequential_algorithm.jl index ffdb173..fe473a3 100644 --- a/src/algorithms/sequential_algorithm.jl +++ b/src/algorithms/sequential_algorithm.jl @@ -35,7 +35,7 @@ function write_results_to_main_container(container::MultiOptimizationContainer) main_container_data_field = getproperty(container, field) for (key, src) in subproblem_data_field if src isa JuMP.Containers.SparseAxisArray - @warn "Skip SparseAxisArray" field key + # @warn "Skip SparseAxisArray" field key continue end num_dims = ndims(src) @@ -45,7 +45,7 @@ function write_results_to_main_container(container::MultiOptimizationContainer) data = PSI.jump_value.(src) catch e if e isa UndefRefError - @warn "Skip UndefRefError for" field key + #@warn "Skip UndefRefError for" field key continue end rethrow() @@ -68,7 +68,6 @@ function write_results_to_main_container(container::MultiOptimizationContainer) end _write_parameter_results_to_main_container(container, subproblem) end - # Parameters need a separate approach due to the way the containers work return end diff --git a/src/multi_optimization_container.jl b/src/multi_optimization_container.jl index befcebe..8331eef 100644 --- a/src/multi_optimization_container.jl +++ b/src/multi_optimization_container.jl @@ -163,6 +163,7 @@ function init_optimization_container!( PSI.LOG_GROUP_OPTIMIZATION_CONTAINER subproblem.settings = deepcopy(settings) PSI.init_optimization_container!(subproblem, network_model, sys) + subproblem.built_for_recurrent_solves = true end _finalize_jump_model!(container, settings) return diff --git a/src/multiproblem_template.jl b/src/multiproblem_template.jl index 57d48de..06e8603 100644 --- a/src/multiproblem_template.jl +++ b/src/multiproblem_template.jl @@ -47,6 +47,26 @@ function get_sub_problem_keys(template::MultiProblemTemplate) return sort!(collect(keys(get_sub_templates(template)))) end +function PSI.get_component_types(template::MultiProblemTemplate)::Vector{DataType} + base_template = template.base_template + return vcat( + get_component_type.(values(get_device_models(base_template))), + get_component_type.(values(get_branch_models(base_template))), + get_component_type.(values(get_service_models(base_template))), + ) +end + +function PSI.get_model(template::MultiProblemTemplate, ::Type{T}) where {T <: PSY.Device} + base_template = template.base_template + if T <: PSY.Branch + return get(base_template.branches, Symbol(T), nothing) + elseif T <: PSY.Device + return get(base_template.devices, Symbol(T), nothing) + else + error("Component $T not present in the template") + end +end + """ Sets the network model in a template. """ @@ -92,8 +112,9 @@ function PSI.set_device_model!( ) PSI.set_device_model!(template.base_template, model) for (id, sub_template) in get_sub_templates(template) - PSI.set_subsystem!(model, id) - PSI.set_device_model!(sub_template, model) + new_model = deepcopy(model) + PSI.set_subsystem!(new_model, id) + PSI.set_device_model!(sub_template, new_model) end return end @@ -104,8 +125,9 @@ function PSI.set_device_model!( ) PSI.set_device_model!(template.base_template, model) for (id, sub_template) in get_sub_templates(template) - PSI.set_subsystem!(model, id) - PSI.set_device_model!(sub_template, PSI.DeviceModel(component_type, formulation)) + new_model = deepcopy(model) + PSI.set_subsystem!(new_model, id) + PSI.set_device_model!(sub_template, new_model) end return end diff --git a/src/problems/multi_region_problem.jl b/src/problems/multi_region_problem.jl index 6af01ac..9502afc 100644 --- a/src/problems/multi_region_problem.jl +++ b/src/problems/multi_region_problem.jl @@ -184,9 +184,9 @@ function _make_parameter_arrays(subproblem_parameters, field_name) end function _make_array_joined_by_axes( - a1::JuMP.Containers.DenseAxisArray{Float64, 2}, - a2::JuMP.Containers.DenseAxisArray{Float64, 2}, -) + a1::JuMP.Containers.DenseAxisArray{T, 2}, + a2::JuMP.Containers.DenseAxisArray{U, 2}, +) where {T <: Union{Float64, JuMP.VariableRef}, U <: Union{Float64, JuMP.VariableRef}} ax1 = axes(a1) ax2 = axes(a2) if ax1[2] != ax2[2] @@ -208,6 +208,8 @@ function PSI.build_impl!(model::PSI.DecisionModel{MultiRegionProblem}) handle_initial_conditions!(model) PSI.build_model!(model) _map_containers(model) + container = PSI.get_optimization_container(model) + container.built_for_recurrent_solves = true # Might need custom implementation for this container type # serialize_metadata!(get_optimization_container(model), get_output_dir(model)) PSI.log_values(PSI.get_settings(model)) @@ -323,3 +325,42 @@ function PSI._add_feedforward_to_model( end return end + +function PSI.update_parameters!( + model::PSI.DecisionModel{MultiRegionProblem}, + decision_states::PSI.DatasetContainer{PSI.InMemoryDataset}, +) + container = PSI.get_optimization_container(model) + for (ix, subproblem) in container.subproblems + @info "Updating subproblem $ix" + PSI.cost_function_unsynch(subproblem) + for key in keys(PSI.get_parameters(subproblem)) + PSI.update_container_parameter_values!(subproblem, model, key, decision_states) + end + end + + + if !PSI.is_synchronized(model) + for subproblem in values(container.subproblems) + PSI.update_objective_function!(subproblem) + obj_func = PSI.get_objective_expression(subproblem) + PSI.set_synchronized_status(obj_func, true) + end + end + return +end + +""" +Default problem update function for most problems with no customization +""" +function PSI.update_model!(model::PSI.DecisionModel{MultiRegionProblem}, sim::PSI.Simulation) + PSI.update_model!(model, PSI.get_simulation_state(sim), PSI.get_ini_cond_chronology(sim)) + #= + if get_rebuild_model(model) + container = get_optimization_container(model) + reset_optimization_model!(container) + build_impl!(container, get_template(model), get_system(model)) + end + =# + return +end