Skip to contents

Time resolution

Sub-annual time resolution is set via the calendar object, that specifies levels of nested time-frames (such as ‘ANNUAL’, ‘MONTH’, ‘DAY’, ‘HOUR’, etc. depending on the modeling goals and decided level of details). This structure of modeled sub-annual time resolution is assigned by a timetable data.frame with columns named as used time-frames, as well as ‘slice’ (refers to the lowest level of ‘time-slices’ with unique names, e.g. ‘d001_h15’ indicating the 1st day of the year and the 15th hour of the day), the ‘share’ column (for the share of the time-frame in the year), and ‘weight’ (for the weight of the time-frame in the year, used in sampled calendars).

# create timetable with 3 levels of timeframes: ANNUAL, YDAY, HOUR
timetable_d365_h24 <- energyRt::make_timetable(energyRt::tsl_levels$d365_h24)
# full year timetable has 8760 time-slices (24 hours * 365 days)
timetable_d365_h24
#>       ANNUAL   YDAY   HOUR    slice        share weight
#>       <char> <char> <char>   <char>        <num>  <num>
#>    1: ANNUAL   d001    h00 d001_h00 0.0001141553      1
#>    2: ANNUAL   d001    h01 d001_h01 0.0001141553      1
#>    3: ANNUAL   d001    h02 d001_h02 0.0001141553      1
#>    4: ANNUAL   d001    h03 d001_h03 0.0001141553      1
#>    5: ANNUAL   d001    h04 d001_h04 0.0001141553      1
#>   ---                                                  
#> 8756: ANNUAL   d365    h19 d365_h19 0.0001141553      1
#> 8757: ANNUAL   d365    h20 d365_h20 0.0001141553      1
#> 8758: ANNUAL   d365    h21 d365_h21 0.0001141553      1
#> 8759: ANNUAL   d365    h22 d365_h22 0.0001141553      1
#> 8760: ANNUAL   d365    h23 d365_h23 0.0001141553      1

This time-table is to define a calendar object, that also describes the hierarchy of time-frames and sets the sequence of the time-slices.

# create calendar object from a time-table
calendar_d365_h24 <- newCalendar(
  name = "d365_h24",
  timetable = timetable_d365_h24
  )

The model object (described below) must have the calendar object with all time-frames and time-slices used in the model. However, scenarios can be solved for a subset of the time-slices, defined by another calendar object with sub-set of time-slices. Here we define a calendar with a subset of 1 day per month and 24 hours per each day. Therefore, the total number of time-slices in the subset is 12 days * 24 hours = 288 time-slices (vs. 8760 time-slices in the full calendar).

# pick days
yday_sample <- 15 + c(0, as.integer(cumsum(days_in_month(1:11)))) # one day per month
# pick hours
hour_sample <- 0:23 # all 24 hours

timetable_subset <- timetable_d365_h24 |>
  filter(YDAY %in% yday2YDAY(yday_sample)) |>
  filter(HOUR %in% hour2HOUR(hour_sample))
timetable_subset
#>      ANNUAL   YDAY   HOUR    slice        share weight
#>      <char> <char> <char>   <char>        <num>  <num>
#>   1: ANNUAL   d015    h00 d015_h00 0.0001141553      1
#>   2: ANNUAL   d015    h01 d015_h01 0.0001141553      1
#>   3: ANNUAL   d015    h02 d015_h02 0.0001141553      1
#>   4: ANNUAL   d015    h03 d015_h03 0.0001141553      1
#>   5: ANNUAL   d015    h04 d015_h04 0.0001141553      1
#>  ---                                                  
#> 284: ANNUAL   d349    h19 d349_h19 0.0001141553      1
#> 285: ANNUAL   d349    h20 d349_h20 0.0001141553      1
#> 286: ANNUAL   d349    h21 d349_h21 0.0001141553      1
#> 287: ANNUAL   d349    h22 d349_h22 0.0001141553      1
#> 288: ANNUAL   d349    h23 d349_h23 0.0001141553      1
unique(timetable_subset$HOUR)
#>  [1] "h00" "h01" "h02" "h03" "h04" "h05" "h06" "h07" "h08" "h09" "h10" "h11"
#> [13] "h12" "h13" "h14" "h15" "h16" "h17" "h18" "h19" "h20" "h21" "h22" "h23"
unique(timetable_subset$YDAY)
#>  [1] "d015" "d046" "d074" "d105" "d135" "d166" "d196" "d227" "d258" "d288"
#> [11] "d319" "d349"
unique(timetable_subset$YDAY) |> tsl2dtm(year = 2019, tmz = "Asia/Kolkata")
#>  [1] "2019-01-15 IST" "2019-02-15 IST" "2019-03-15 IST" "2019-04-15 IST"
#>  [5] "2019-05-15 IST" "2019-06-15 IST" "2019-07-15 IST" "2019-08-15 IST"
#>  [9] "2019-09-15 IST" "2019-10-15 IST" "2019-11-15 IST" "2019-12-15 IST"

SUBSET_HOURS <- nrow(timetable_subset) # total hours in the subset
FRACT_YEAR <- SUBSET_HOURS / 8760 # fraction in a year
print("Subannual time resolution:")
#> [1] "Subannual time resolution:"
print(paste("   Total number of days a year:", length(yday_sample)))
#> [1] "   Total number of days a year: 12"
print(paste("   Total number of hours per year:", SUBSET_HOURS))
#> [1] "   Total number of hours per year: 288"

# Partial calendar
partial_calendar <- newCalendar(
  name = "d365_h24_subset_1day_per_month",
  timetable = timetable_subset,
  year_fraction = sum(timetable_subset$share)
)

Model horizon

Calendars are (currently) set sub-annual time-structure for all years.

horizon_2020_2060_by_10 <- newHorizon(
  name = "Y2020_2060_by_10",
  desc = "2020 to 2060 by 10 years",
  period = 2020:2060,
  intervals = c(1, 5, rep(10, 15)),
  mid_is_end = T
)
horizon_2020_2060_by_10
#> An object of class "horizon"
#> Slot "name":
#> [1] "Y2020_2060_by_10"
#> 
#> Slot "desc":
#> [1] "2020 to 2060 by 10 years"
#> 
#> Slot "period":
#>  [1] 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034
#> [16] 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049
#> [31] 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060
#> 
#> Slot "intervals":
#>    start   mid   end
#>    <num> <num> <num>
#> 1:  2020  2020  2020
#> 2:  2021  2025  2025
#> 3:  2026  2035  2035
#> 4:  2036  2045  2045
#> 5:  2046  2055  2055
#> 6:  2056  2060  2060

horizon_2020_2060_by_5 <- newHorizon(
  name = "Y2020_2060_by_5",
  desc = "2020 to 2060 by 5 years",
  period = 2020:2060,
  intervals = c(1, rep(5, 25)),
  mid_is_end = T
)

horizon_2020 <- newHorizon(
  name = "Y2020",
  desc = "one year horizon: 2020",
  period = 2020,
  intervals = c(1),
  mid_is_end = T
)

horizon_2030 <- newHorizon(
  name = "Y2030",
  desc = "one year horizon: 2030",
  period = 2030,
  intervals = c(1),
  mid_is_end = T
)

horizon_2040 <- newHorizon(
  name = "Y2040",
  desc = "one year horizon: 2040",
  period = 2040,
  intervals = c(1),
  mid_is_end = T
)

horizon_2050 <- newHorizon(
  name = "Y2050",
  desc = "one year horizon: 2050",
  period = 2050,
  intervals = c(1),
  mid_is_end = T
)

horizon_2060 <- newHorizon(
  name = "Y2060",
  desc = "one year horizon: 2060",
  period = 2060,
  intervals = c(1),
  mid_is_end = T
)

horizon_2070 <- newHorizon(
  name = "Y2070",
  desc = "one year horizon: 2070",
  period = 2070,
  intervals = c(1),
  mid_is_end = T
)