Skip to content

Commit 7f1a1eb

Browse files
authored
Introduce stage__output (#1094)
2 parents 914304f + 2575de6 commit 7f1a1eb

File tree

5 files changed

+32
-18
lines changed

5 files changed

+32
-18
lines changed

src/data_structure/preprocess_data_structure.jl

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -914,13 +914,12 @@ function generate_unit_commitment_parameters()
914914
indices(shut_down_cost),
915915
(x.unit for x in indices(start_up_limit)),
916916
(x.unit for x in indices(shut_down_limit)),
917-
# ramp_up constraint needs units_started_up variable to avoid being infeasible
918917
(x.unit for x in indices(ramp_up_limit)),
919-
# ramp_down constraint needs units_shut_down variable to avoid being infeasible
920918
(x.unit for x in indices(ramp_down_limit)),
921919
(x.unit for x in indices(unit_start_flow) if unit_start_flow(; x...) != 0),
922920
(x.unit for x in indices(units_started_up_coefficient) if units_started_up_coefficient(; x...) != 0),
923-
(u for (st, out, u) in stage__output__unit() if out.name in (:units_started_up, :units_shut_down)),
921+
(u for (st, u) in stage__output__unit(output=output.((:units_started_up, :units_shut_down)))),
922+
!isempty(stage__output(output=output.((:units_started_up, :units_shut_down)))) ? unit() : (),
924923
)
925924
)
926925
)
@@ -929,7 +928,8 @@ function generate_unit_commitment_parameters()
929928
(
930929
indices(scheduled_outage_duration),
931930
indices(fix_units_out_of_service),
932-
(u for (st, out, u) in stage__output__unit() if out.name == :units_out_of_service),
931+
(u for (st, u) in stage__output__unit(output=output(:units_out_of_service))),
932+
!isempty(stage__output(output=output(:units_out_of_service))) ? unit() : (),
933933
)
934934
)
935935
)
@@ -946,7 +946,8 @@ function generate_unit_commitment_parameters()
946946
(x.unit for x in indices(minimum_operating_point) if minimum_operating_point(; x...) != 0),
947947
(x.unit for x in indices(ramp_up_limit)),
948948
(x.unit for x in indices(ramp_down_limit)),
949-
(u for (st, out, u) in stage__output__unit() if out.name == :units_on),
949+
(u for (st, u) in stage__output__unit(output=output(:units_on))),
950+
!isempty(stage__output(output=output(:units_on))) ? unit() : (),
950951
(
951952
u
952953
for u in indices(online_variable_type)

src/run_spineopt.jl

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -482,11 +482,14 @@ struct SpineOptExt
482482
end
483483
else
484484
intermediate_results_folder = ""
485-
reports_by_output = Dict(
486-
(out.name, true) => []
485+
outputs = (
486+
out
487487
for stage__output__entity in (stage__output__unit, stage__output__node, stage__output__connection)
488488
for (out, _ent) in stage__output__entity(stage=stage)
489489
)
490+
reports_by_output = Dict(
491+
(out.name, true) => [] for out in Iterators.flatten((outputs, stage__output(stage=stage)))
492+
)
490493
end
491494
event_handlers = Dict(
492495
:model_built => Set(),

src/run_spineopt_basic.jl

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -282,11 +282,15 @@ function _init_downstream_outputs!(st, stage_m, child_models)
282282
out = output(out_name)
283283
out_indices = stage_m.ext[:spineopt].variables_definition[out_name][:indices](stage_m)
284284
isempty(out_indices) && continue
285-
objs_by_class_name = Dict(
286-
:unit => stage__output__unit(stage=st, output=out),
287-
:node => stage__output__node(stage=st, output=out),
288-
:connection => stage__output__connection(stage=st, output=out),
289-
)
285+
objs_by_class_name = if out in stage__output(stage=st)
286+
Dict(:unit => anything, :node => anything, :connection => anything)
287+
else
288+
Dict(
289+
:unit => stage__output__unit(stage=st, output=out),
290+
:node => stage__output__node(stage=st, output=out),
291+
:connection => stage__output__connection(stage=st, output=out),
292+
)
293+
end
290294
unique_entities = unique(_drop_key(ind, :t) for ind in out_indices)
291295
filter!(unique_entities) do ent
292296
_stage_output_includes_entity(ent, objs_by_class_name)
@@ -301,6 +305,11 @@ function _init_downstream_outputs!(st, stage_m, child_models)
301305
)
302306
objs_by_class_name_by_res = Dict()
303307
for (class_name, objs) in objs_by_class_name
308+
if objs === anything
309+
res = output_resolution(; stage=st, output=out, _strict=false)
310+
get!(objs_by_class_name_by_res, res, Dict())[class_name] = anything
311+
continue
312+
end
304313
for obj in objs
305314
res = output_resolution(; stage=st, output=out, ((class_name => obj),)..., _strict=false)
306315
push!(get!(get!(objs_by_class_name_by_res, res, Dict()), class_name, []), obj)
@@ -331,7 +340,8 @@ end
331340

332341
function _stage_output_includes_entity(ent, objs_by_class_name)
333342
any(objs_by_class_name) do (class_name, objs)
334-
get(ent, class_name, nothing) in objs
343+
obj = get(ent, class_name, nothing)
344+
obj !== nothing && obj in objs
335345
end
336346
end
337347

templates/spineopt_template.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
["parent_stochastic_scenario__child_stochastic_scenario", ["stochastic_scenario", "stochastic_scenario"], "A parent-child relationship between two `stochastic_scenario`s defining the master stochastic direct acyclic graph."],
4444
["report__output", ["report", "output"], "An `output` that should be included in a `report`."],
4545
["stage__child_stage", ["stage", "stage"], "A parent-child relationship between two `stage`s (EXPERIMENTAL)."],
46+
["stage__output", ["stage", "output"], "An `output` that should be fixed by a `stage` for all entities in all its children (EXPERIMENTAL)."],
4647
["stage__output__connection", ["stage", "output", "connection"], "An `output` that should be fixed by a `stage` for a `connection` in all its children (EXPERIMENTAL)."],
4748
["stage__output__node", ["stage", "output", "node"], "An `output` that should be fixed by a `stage` for a `node` in all its children (EXPERIMENTAL)."],
4849
["stage__output__unit", ["stage", "output", "unit"], "An `output` that should be fixed by a `stage` for a `unit` in all its children (EXPERIMENTAL)."],
@@ -349,6 +350,7 @@
349350
["node__user_constraint", "storages_invested_available_coefficient", 0.0, null, "Coefficient of the specified node's storages invested available variable in the specified user constraint."],
350351
["node__user_constraint", "storages_invested_coefficient", 0.0 , null, "Coefficient of the specified node's storage investment variable in the specified user constraint."],
351352
["report__output", "overwrite_results_on_rolling", true, null, "Whether or not results from further windows should overwrite results from previous ones."],
353+
["stage__output", "output_resolution", null, null, "A duration or array of durations indicating the points in time where the output of this stage should be fixed in the children. If not specified, then the output is fixed at the end of each child's roling window (EXPERIMENTAL)."],
352354
["stage__output__connection", "output_resolution", null, null, "A duration or array of durations indicating the points in time where the output of this stage should be fixed in the children. If not specified, then the output is fixed at the end of each child's roling window (EXPERIMENTAL)."],
353355
["stage__output__node", "output_resolution", null, null, "A duration or array of durations indicating the points in time where the output of this stage should be fixed in the children. If not specified, then the output is fixed at the end of each child's roling window (EXPERIMENTAL)."],
354356
["stage__output__unit", "output_resolution", null, null, "A duration or array of durations indicating the points in time where the output of this stage should be fixed in the children. If not specified, then the output is fixed at the end of each child's roling window (EXPERIMENTAL)."],

test/run_spineopt_multi_stage.jl

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -168,17 +168,15 @@ function _lt_storage_investments_setup(storage_count)
168168
lt_storage_data = _lt_storage_data(storage_count)
169169
lt_storage_investments_data = Dict(
170170
:relationships => Any[
171-
("stage__output__node", ("lt_storage", "storages_invested_available", "storage_node$k"))
172-
for k in 1:storage_count
171+
("stage__output", ("lt_storage", "storages_invested_available"))
173172
],
174173
:relationship_parameter_values => Any[
175174
(
176-
"stage__output__node",
177-
("lt_storage", "storages_invested_available", "storage_node$k"),
175+
"stage__output",
176+
("lt_storage", "storages_invested_available"),
178177
"output_resolution",
179178
unparse_db_value(Hour(1)),
180179
)
181-
for k in 1:storage_count
182180
],
183181
)
184182
merge!(append!, lt_storage_data, lt_storage_investments_data)

0 commit comments

Comments
 (0)