Skip to content

Commit

Permalink
Add functions to compute time resolution periods and matrices
Browse files Browse the repository at this point in the history
  • Loading branch information
abelsiqueira committed Oct 17, 2023
1 parent ad1c3cc commit e4aa78a
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 1 deletion.
3 changes: 2 additions & 1 deletion src/TulipaEnergyModel.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ using Graphs
using HiGHS
using JuMP

include("input_tables.jl")
include("io.jl")
include("model.jl")
include("input_tables.jl")
include("time-resolution.jl")

end
86 changes: 86 additions & 0 deletions src/time-resolution.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
export resolution_matrix, compute_rp_periods

"""
M = resolution_matrix(rp_periods, time_steps)
Computes the resolution balance matrix using the array of `rp_periods` and the array of `time_steps`.
The elements in these arrays must be ranges.
## Examples
The following two examples are for two flows/assets with resolutions of 3h and 4h, so that the representative period has 4h periods.
```jldoctest
rp_periods = [1:4, 5:8, 9:12]
time_steps = [1:4, 5:8, 9:12]
resolution_matrix(rp_periods, time_steps)
# output
3×3 Matrix{Float64}:
1.0 0.0 0.0
0.0 1.0 0.0
0.0 0.0 1.0
```
```jldoctest
rp_periods = [1:4, 5:8, 9:12]
time_steps = [1:3, 4:6, 7:9, 10:12]
resolution_matrix(rp_periods, time_steps)
# output
3×4 Matrix{Float64}:
1.0 0.333333 0.0 0.0
0.0 0.666667 0.666667 0.0
0.0 0.0 0.333333 1.0
```
"""
function resolution_matrix(
rp_periods::AbstractVector{<:UnitRange{<:Integer}},
time_steps::AbstractVector{<:UnitRange{<:Integer}},
)
M = [
length(period time_step) / length(time_step) for period in rp_periods,
time_step in time_steps
]

return M
end

"""
rp_periods = compute_rp_periods(array_time_steps)
Given the time steps of various flows/assets in the `array_time_steps` input, compute the representative period splits.
Each element of `array_time_steps` is a an array of ranges.
## Examples
```jldoctest
time_steps1 = [1:4, 5:8, 9:12]
time_steps2 = [1:3, 4:6, 7:9, 10:12]
compute_rp_periods([time_steps1, time_steps2])
# output
3-element Vector{UnitRange{Int64}}:
1:4
5:8
9:12
```
"""
function compute_rp_periods(
array_time_steps::AbstractVector{<:AbstractVector{<:UnitRange{<:Integer}}},
)
rp_periods = UnitRange{Int}[]
period_start = 1
representative_period_end = maximum(last.(last.(array_time_steps)))
while period_start < representative_period_end
period_end =
maximum(last(T[findfirst(last.(T) .≥ period_start)]) for T in array_time_steps)
@assert period_end period_start
push!(rp_periods, period_start:period_end)
period_start = period_end + 1
end
return rp_periods
end
47 changes: 47 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,50 @@ end
[(:investable, Bool, String7), (:peak_demand, Float64, String7)]
end
end

@testset "Time resolution" begin
@testset "resolution_matrix" begin
rp_periods = [1:4, 5:8, 9:12]
time_steps = [1:4, 5:8, 9:12]
expected = [
1.0 0.0 0.0
0.0 1.0 0.0
0.0 0.0 1.0
]
@test resolution_matrix(rp_periods, time_steps) == expected

time_steps = [1:3, 4:6, 7:9, 10:12]
expected = [
1.0 1/3 0.0 0.0
0.0 2/3 2/3 0.0
0.0 0.0 1/3 1.0
]
@test resolution_matrix(rp_periods, time_steps) == expected

time_steps = [1:6, 7:9, 10:10, 11:11, 12:12]
expected = [
2/3 0.0 0.0 0.0 0.0
1/3 2/3 0.0 0.0 0.0
0.0 1/3 1.0 1.0 1.0
]
@test resolution_matrix(rp_periods, time_steps) == expected
end

@testset "compute_rp_periods" begin
# regular
time_steps1 = [1:4, 5:8, 9:12] # every 4 hours
time_steps2 = [1:3, 4:6, 7:9, 10:12] # every 3 hours
time_steps3 = [i:i for i = 1:12] # hourly

@test compute_rp_periods([time_steps1, time_steps2]) == time_steps1
@test compute_rp_periods([time_steps1, time_steps2, time_steps3]) == time_steps1
@test compute_rp_periods([time_steps2, time_steps3]) == time_steps2

# Irregular
time_steps4 = [1:6, 7:9, 10:11, 12:12]
time_steps5 = [1:2, 3:4, 5:12]
@test compute_rp_periods([time_steps1, time_steps4]) == [1:6, 7:9, 10:12]
@test compute_rp_periods([time_steps1, time_steps5]) == [1:4, 5:12]
@test compute_rp_periods([time_steps4, time_steps5]) == [1:6, 7:12]
end
end

0 comments on commit e4aa78a

Please sign in to comment.