From 9756162430edde4dbb5396974b5f4f3632c9a034 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Mon, 19 Aug 2024 10:30:22 +0200 Subject: [PATCH 1/3] feat: implement build_order for core components --- src/IESopt.jl | 12 ++++-------- src/core.jl | 5 +++++ src/core/connection.jl | 7 +++++++ src/core/decision.jl | 9 +++++++++ src/core/node.jl | 7 +++++++ src/core/profile.jl | 7 +++++++ src/core/unit.jl | 7 +++++++ 7 files changed, 46 insertions(+), 8 deletions(-) diff --git a/src/IESopt.jl b/src/IESopt.jl index f5aa57f..90de3bf 100644 --- a/src/IESopt.jl +++ b/src/IESopt.jl @@ -102,14 +102,10 @@ function _build_model!(model::JuMP.Model; callbacks::Union{Nothing, Dict}) @info "Preparing components" - # Place Decisions first, since those need to be built before everything else. - corder = Vector{_CoreComponent}( - collect(component for component in values(_iesopt(model).model.components) if component isa Decision), - ) - append!( - corder, - collect(component for component in values(_iesopt(model).model.components) if !(component isa Decision)), - ) + # Sort components by their build priority. + # For instance, Decisions with a default build priority of 1000 are built before all other components + # with a default build priority of 0 + corder = sort(collect(values(_iesopt(model).model.components)); by=_build_priority, rev=true) @info "Start creating JuMP model" components_with_addons = [] diff --git a/src/core.jl b/src/core.jl index eaed7d7..5f4248a 100644 --- a/src/core.jl +++ b/src/core.jl @@ -178,6 +178,11 @@ _component_type(::Node) = :Node _component_type(::Profile) = :Profile _component_type(::Unit) = :Unit +_build_priority(cc::_CoreComponent) = _build_priority(cc.build_priority, 0.0) +_build_priority(::Nothing, default) = default +_build_priority(priority::Real, ::T) where {T} = convert(T, priority) +_build_priority(priority, ::Any) = @error "Unsupported build priority" priority + function Base.getproperty(cc::_CoreComponent, field::Symbol) try (field == :var) && (return getfield(cc, :_ccoc).variables) diff --git a/src/core/connection.jl b/src/core/connection.jl index 630cd2b..a4b4f60 100644 --- a/src/core/connection.jl +++ b/src/core/connection.jl @@ -79,6 +79,13 @@ A `Connection` is used to model arbitrary flows of energy between `Node`s. It al pf_R::_OptionalScalarInput = nothing pf_B::_OptionalScalarInput = nothing + raw"""```{"mandatory": "no", "values": "numeric", "unit": "-", "default": "`0`"}``` + Priority for the build order of components. Components with higher build_priority are built before. + This can be useful for addons, that connect multiple components and rely on specific components being initialized + before others. + """ + build_priority::_OptionalScalarInput = nothing + # [Internal] ======================================================================================================= # - diff --git a/src/core/decision.jl b/src/core/decision.jl index d4ef236..8d63fbd 100644 --- a/src/core/decision.jl +++ b/src/core/decision.jl @@ -65,6 +65,13 @@ component's settings, as well as have associated costs. """ sos::Vector{Dict{String, Float64}} = Vector() + raw"""```{"mandatory": "no", "values": "numeric", "unit": "-", "default": "`1000`"}``` + Priority for the build order of components. Components with higher build_priority are built before. + This can be useful for addons, that connect multiple components and rely on specific components being initialized + before others. + """ + build_priority::_OptionalScalarInput = nothing + # [Internal] ======================================================================================================= # - @@ -153,6 +160,8 @@ function _result(decision::Decision, mode::String, field::String; result::Int=1) return nothing end +_build_priority(decision::Decision) = _build_priority(decision.build_priority, 1000.0) + include("decision/con_fixed.jl") include("decision/con_sos_value.jl") include("decision/con_sos1.jl") diff --git a/src/core/node.jl b/src/core/node.jl index 065b4dc..262c980 100644 --- a/src/core/node.jl +++ b/src/core/node.jl @@ -102,6 +102,13 @@ balance equation. This allows using `Node`s for various storage tasks (like batt # Powerflow pf_slack::Bool = false + raw"""```{"mandatory": "no", "values": "numeric", "unit": "-", "default": "`0`"}``` + Priority for the build order of components. Components with higher build_priority are built before. + This can be useful for addons, that connect multiple components and rely on specific components being initialized + before others. + """ + build_priority::_OptionalScalarInput = nothing + # [Internal] ======================================================================================================= # - diff --git a/src/core/profile.jl b/src/core/profile.jl index b46b45d..37ae66e 100644 --- a/src/core/profile.jl +++ b/src/core/profile.jl @@ -107,6 +107,13 @@ Besides modelling fixed profiles, they also allow different ways to modify the v allow_deviation::Symbol = :off cost_deviation::_OptionalScalarInput = nothing + raw"""```{"mandatory": "no", "values": "numeric", "unit": "-", "default": "`0`"}``` + Priority for the build order of components. Components with higher build_priority are built before. + This can be useful for addons, that connect multiple components and rely on specific components being initialized + before others. + """ + build_priority::_OptionalScalarInput = nothing + # [Internal] ======================================================================================================= # - diff --git a/src/core/unit.jl b/src/core/unit.jl index 7ab38cc..721d8cb 100644 --- a/src/core/unit.jl +++ b/src/core/unit.jl @@ -211,6 +211,13 @@ A `Unit` allows transforming one (or many) forms of energy into another one (or """ startup_cost::_OptionalScalarInput = nothing + raw"""```{"mandatory": "no", "values": "numeric", "unit": "-", "default": "`0`"}``` + Priority for the build order of components. Components with higher build_priority are built before. + This can be useful for addons, that connect multiple components and rely on specific components being initialized + before others. + """ + build_priority::_OptionalScalarInput = nothing + # [Internal] ======================================================================================================= conversion_dict::Dict{Symbol, Dict{Carrier, _NumericalInput}} = Dict(:in => Dict(), :out => Dict()) conversion_at_min_dict::Dict{Symbol, Dict{Carrier, _NumericalInput}} = Dict(:in => Dict(), :out => Dict()) From 0e4d28026dc00c519ad2526703c7dcf1fbfb4ae8 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Mon, 19 Aug 2024 21:17:48 +0200 Subject: [PATCH 2/3] chore: bump IESoptLib compat to 0.3 --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index ed64c2b..1515f97 100644 --- a/Project.toml +++ b/Project.toml @@ -54,7 +54,7 @@ Dates = "<0.0.1,1" GLPK = "1.2.1" Gurobi = "1.3.0" HiGHS = "1.9" -IESoptLib = "0.1, 0.2, 0.3" +IESoptLib = "0.3" Ipopt = "1.6.2" JLD2 = "0.4" JSON = "0.21" From 72e9a8eb27c657f9c5517dfe39f68ab29166cec1 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Tue, 20 Aug 2024 09:54:08 +0200 Subject: [PATCH 3/3] ci: update Pkg dependencies in Documentation workflow --- .github/workflows/Documentation.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/Documentation.yml b/.github/workflows/Documentation.yml index ce966b6..32b7c0c 100644 --- a/.github/workflows/Documentation.yml +++ b/.github/workflows/Documentation.yml @@ -23,6 +23,7 @@ jobs: shell: julia --project=docs --color=yes {0} run: | using Pkg + Pkg.update() Pkg.develop(PackageSpec(path=pwd())) Pkg.instantiate() - uses: julia-actions/julia-buildpkg@v1