Skip to content

Commit

Permalink
Use expressions to replace represented variables too
Browse files Browse the repository at this point in the history
  • Loading branch information
manuelma committed Nov 25, 2024
1 parent 43d0067 commit 8ceb632
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 27 deletions.
32 changes: 16 additions & 16 deletions src/variables/variable_common.jl
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,9 @@ Add a variable to `m`, with given `name` and indices given by interating over `i
or nothing
- `required_history_period::Union{Period,Nothing}=nothing`: given an index, return the required history period
or nothing
- `replacement_expressions::Dict=Dict()`: mapping some of the indices of the variable - as returned by the given
`indices` function - to another Dict that defines an expression to use instead of the variable for that index.
- `replacement_expressions::OrderedDict=OrderedDict()`: mapping some of the indices of the variable -
as returned by the given `indices` function - to another Dict that defines an expression to use
instead of the variable for that index.
The expression Dict simply maps variable names to a tuple of reference index and coefficient.
The expression is then built as the sum of the coefficient and the variable for the reference index,
over the entire Dict.
Expand All @@ -53,7 +54,7 @@ function add_variable!(
non_anticipativity_time::Union{Parameter,Nothing}=nothing,
non_anticipativity_margin::Union{Parameter,Nothing}=nothing,
required_history_period::Union{Period,Nothing}=nothing,
replacement_expressions=Dict(),
replacement_expressions=OrderedDict(),
)
lb = _nothing_if_empty(lb)
ub = _nothing_if_empty(ub)
Expand All @@ -65,6 +66,9 @@ function add_variable!(
t_start = start(first(time_slice(m)))
t_history = TimeSlice(t_start - required_history_period, t_start)
history_time_slices = [t for t in history_time_slice(m) if overlaps(t_history, t)]
isempty(SpineInterface.indices(representative_periods_mapping)) || merge!(
replacement_expressions, _representative_period_expresions(m, name, indices, replacement_expressions)
)
first_ind = iterate(indices(m))
K = first_ind === nothing ? Any : typeof(first_ind[1])
V = Union{VariableRef,GenericAffExpr{T,VariableRef} where T<:Union{Number,Call}}
Expand Down Expand Up @@ -112,9 +116,6 @@ function add_variable!(
fix(var, Call(initial_value_ts, (t=ind.t,), (Symbol(:initial_, name), ind)))
end
end
isempty(SpineInterface.indices(representative_periods_mapping)) || merge!(
vars, _representative_periods_mapping(m, vars, indices, replacement_expressions)
)
vars
end

Expand All @@ -136,7 +137,7 @@ function _variable_definition(;
non_anticipativity_margin=nothing,
history_time_slices=[],
history_vars_by_ind=Dict(),
replacement_expressions=Dict(),
replacement_expressions=OrderedDict(),
)
Dict(
:indices => indices,
Expand All @@ -161,7 +162,9 @@ function _expand_replacement_expressions!(m)
exprs = Dict()
for (ind, formula) in replacement_expressions
vars[ind] = exprs[ind] = sum(
coeff * _get_var_with_replacement(m, ref_name, ref_ind) for (ref_name, (ref_ind, coeff)) in formula
coeff * _get_var_with_replacement(m, ref_name, ref_ind)
for (ref_name, reference_index_to_coef) in formula
for (ref_ind, coeff) in reference_index_to_coef
)
end
_finalize_expressions!(m, exprs, name, def)
Expand Down Expand Up @@ -284,10 +287,10 @@ function _representative_index_to_coefficient(m, ind, indices)
end

"""
A `Dict` mapping non representative indices to the variable or expression for the representative index.
A `Dict` mapping non representative indices to the expression Dict for the representative index.
"""
function _representative_periods_mapping(
m::Model, vars::Dict, indices::Function, replacement_expressions::Union{Dict, OrderedDict}
function _representative_period_expresions(
m::Model, name::Symbol, indices::Function, replacement_expressions::Union{Dict, OrderedDict}
)
# By default, `indices` skips represented time slices for operational variables other than node_state,
# as well as for investment variables. This is done by setting the default value of the `temporal_block` argument
Expand All @@ -297,11 +300,8 @@ function _representative_periods_mapping(
representative_indices = indices(m)
all_indices = indices(m; temporal_block=anything)
represented_indices = setdiff(all_indices, representative_indices)
Dict(
ind => sum(
coef * vars[representative_ind]
for (representative_ind, coef) in _representative_index_to_coefficient(m, ind, indices)
)
OrderedDict(
ind => Dict(name => _representative_index_to_coefficient(m, ind, indices))
for ind in represented_indices
if !haskey(replacement_expressions, ind)
)
Expand Down
11 changes: 8 additions & 3 deletions src/variables/variable_connection_flow.jl
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,14 @@ function add_variable_connection_flow!(m::Model)
fix_ratio_d1_d2 = ((fix_ratio_out_in_connection_flow, direction(:to_node), direction(:from_node)),)
replacement_expressions = OrderedDict(
(connection=conn, node=n, direction=d, stochastic_scenario=s, t=t) => Dict(
:connection_flow => (
(connection=conn, node=n_ref, direction=d_ref, stochastic_scenario=s, t=t),
_fix_ratio_connection_flow(m, conn, n, n_ref, s, t, fix_ratio, direct),
:connection_flow => Dict(
(
connection=conn,
node=n_ref,
direction=d_ref,
stochastic_scenario=s,
t=t,
) => _fix_ratio_connection_flow(m, conn, n, n_ref, s, t, fix_ratio, direct)
)
)
for (conn, n_ref, d_ref, n, d, fix_ratio, direct) in _related_flows(fix_ratio_d1_d2)
Expand Down
20 changes: 12 additions & 8 deletions src/variables/variable_unit_flow.jl
Original file line number Diff line number Diff line change
Expand Up @@ -126,16 +126,20 @@ function add_variable_unit_flow!(m::Model)
fix_ratio_d1_d2 = ((r, _ratio_to_d1_d2(r)...) for r in _fix_unit_flow_ratios())
replacement_expressions = OrderedDict(
(unit=u, node=n, direction=d, stochastic_scenario=s, t=t) => Dict(
:unit_flow => (
(unit=u, node=n_ref, direction=d_ref, stochastic_scenario=s, t=t),
_fix_ratio_unit_flow(m, u, n, n_ref, s, t, fix_ratio, direct),
:unit_flow => Dict(
(
unit=u,
node=n_ref,
direction=d_ref,
stochastic_scenario=s,
t=t,
) => _fix_ratio_unit_flow(m, u, n, n_ref, s, t, fix_ratio, direct)
),
:units_on => (
(unit=u, stochastic_scenario=s, t=t), _fix_units_on_coeff(m, u, n, n_ref, s, t, fix_ratio, direct)
:units_on => Dict(
(unit=u, stochastic_scenario=s, t=t) => _fix_units_on_coeff(m, u, n, n_ref, s, t, fix_ratio, direct)
),
:units_started_up => (
(unit=u, stochastic_scenario=s, t=t),
_signed_unit_start_flow(m, u, n, n_ref, s, t, fix_ratio, direct),
:units_started_up => Dict(
(unit=u, stochastic_scenario=s, t=t) => _signed_unit_start_flow(m, u, n, n_ref, s, t, fix_ratio, direct)
),
)
for (u, n_ref, d_ref, n, d, fix_ratio, direct) in _related_flows(fix_ratio_d1_d2)
Expand Down

0 comments on commit 8ceb632

Please sign in to comment.