Skip to content

Commit

Permalink
Changed the default number of units based on is_candidate. (#1036)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mastomaki authored Nov 26, 2024
2 parents e14159d + 1f88fb2 commit 6801a27
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 4 deletions.
2 changes: 1 addition & 1 deletion docs/src/concept_reference/number_of_units.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
Defines how many members a certain [unit](@ref) object represents. Typically this parameter takes a binary (UC) or integer (clustered UC) value. Together with the [unit\_availability\_factor](@ref) and [units\_unavailable](@ref), this will determine the maximum number of members that can be online at any given time. (Thus restricting the [units\_on](@ref) variable). It is possible to allow the model to increase the `number_of_units` itself, through [Investment Optimization](@ref). It is also possible to schedule maintenance outages using [outage\_variable\_type](@ref) and [scheduled\_outage\_duration](@ref).

The default value for this parameter is 1.
The default value for this parameter is 1. The default value is 0 when [candidate\_units](@ref) has been defined for the unit in question.
5 changes: 4 additions & 1 deletion src/constraints/constraint_units_available.jl
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,10 @@ function _build_constraint_units_available(m, u, s, t)
init=0,
)
<=
+ number_of_units(m; unit=u, stochastic_scenario=s, t=t)
# Change the default number of units so that it is zero when candidate units are present
# and otherwise 1.
+ ifelse(is_candidate(unit=u), number_of_units(m; unit=u, stochastic_scenario=s, t=t, _default=0),
number_of_units(m; unit=u, stochastic_scenario=s, t=t) )
- units_unavailable(m; unit=u, stochastic_scenario=s, t=t)
)
end
Expand Down
2 changes: 1 addition & 1 deletion templates/spineopt_template.json
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@
["unit", "is_renewable", false, "boolean_value_list", "Whether the unit is renewable - used in the minimum renewable generation constraint within the Benders master problem"],
["unit", "min_down_time", null, null, "Minimum downtime of a `unit` after it shuts down."],
["unit", "min_up_time", null, null, "Minimum uptime of a `unit` after it starts up."],
["unit", "number_of_units", 1.0, null, "Denotes the number of 'sub units' aggregated to form the modelled `unit`."],
["unit", "number_of_units", 1.0, null, "Denotes the number of 'sub units' aggregated to form the modelled `unit`. The default value becomes zero if `candidate_units` has been defined."],
["unit", "online_variable_type", "unit_online_variable_type_linear", "unit_online_variable_type_list", "A selector for how the `units_on` variable is represented within the model."],
["unit", "outage_variable_type", "unit_online_variable_type_none", "unit_online_variable_type_list", "Determines whether the outage variable is integer or continuous or none(no optimisation of maintenance outages)."],
["unit", "scheduled_outage_duration", null, null, "Specifies the amount of time a unit must be out of service for maintenance as a single block over the course of the optimisation window"],
Expand Down
37 changes: 36 additions & 1 deletion test/constraints/constraint_unit.jl
Original file line number Diff line number Diff line change
Expand Up @@ -155,11 +155,12 @@ function test_constraint_units_available()
end
end
end

function test_constraint_units_available_units_unavailable()
@testset "constraint_units_available_units_unavailable" begin
url_in = _test_constraint_unit_setup()
number_of_units = 4
candidate_units = 3
candidate_units = 3
units_unavailable = 1
unit_availability_factor = 0.5
object_parameter_values = [
Expand Down Expand Up @@ -191,6 +192,40 @@ function test_constraint_units_available_units_unavailable()
@test _is_constraint_equal(observed_con, expected_con)
end
end
@testset "constraint_units_available_units_unavailable_default" begin
url_in = _test_constraint_unit_setup()
candidate_units = 3
number_of_units_when_candidates_units = 0
units_unavailable = 1
unit_availability_factor = 0.5
object_parameter_values = [
["unit", "unit_ab", "candidate_units", candidate_units],
["unit", "unit_ab", "units_unavailable", units_unavailable],
["unit", "unit_ab", "unit_availability_factor", unit_availability_factor],
]
relationships = [
["unit__investment_temporal_block", ["unit_ab", "hourly"]],
["unit__investment_stochastic_structure", ["unit_ab", "stochastic"]],
]
SpineInterface.import_data(url_in; relationships=relationships, object_parameter_values=object_parameter_values)
m = run_spineopt(url_in; log_level=0, optimize=false)
var_units_on = m.ext[:spineopt].variables[:units_on]
var_units_invested_available = m.ext[:spineopt].variables[:units_invested_available]
constraint = m.ext[:spineopt].constraints[:units_available]
@test length(constraint) == 2
scenarios = (stochastic_scenario(:parent), stochastic_scenario(:child))
time_slices = time_slice(m; temporal_block=temporal_block(:hourly))
@testset for (s, t) in zip(scenarios, time_slices)
key = (unit(:unit_ab), s, t)
var_u_on = var_units_on[key...]
var_u_inv_av = var_units_invested_available[key...]
expected_con = @build_constraint(var_u_on <= number_of_units_when_candidates_units + var_u_inv_av - units_unavailable)
con_key = (unit(:unit_ab), s, t)
con = constraint[con_key...]
observed_con = constraint_object(con)
@test _is_constraint_equal(observed_con, expected_con)
end
end
end

function test_constraint_unit_state_transition()
Expand Down

0 comments on commit 6801a27

Please sign in to comment.