Skip to content

Instantly share code, notes, and snippets.

@hongyuanjia
Created May 8, 2019 17:51
Show Gist options
  • Save hongyuanjia/dad0945a53ff89f25673c0ba456fbd21 to your computer and use it in GitHub Desktop.
Save hongyuanjia/dad0945a53ff89f25673c0ba456fbd21 to your computer and use it in GitHub Desktop.
Test how EnergyPlus handle leap year with AMY data in different versions
library(eplusr)
library(purrr)
library(data.table)
library(lubridate)
example_idf <- function (ver) {
file.path(eplus_config(ver)$dir, "ExampleFiles", "5Zone_Transformer.idf")
}
example_epw <- function(ver) {
file.path(eplus_config(ver)$dir, "WeatherData", "USA_CA_San.Francisco.Intl.AP.724940_TMY3.epw")
}
del_runperiod <- function (idf) {
if (idf$is_valid_class("RunPeriod")) {
idf$del(idf$object_id("RunPeriod", simplify = TRUE))
}
idf
}
del_output <- function (idf) {
if (idf$is_valid_class("Output:Variable")) {
idf$del(idf$object_id("Output:Variable", simplify = TRUE))
}
idf
}
add_output <- function (idf) {
del_output(idf)
idf$add(Output_Variable = list("*", "Site Outdoor Air Drybulb Temperature", "Timestep"))
# make sure sql output is generated
idf$add(Output_SQLite = list("Simple"))
idf
}
add_runperiod <- function (idf, actual_year = FALSE) {
del_runperiod(idf)
if (idf$version() > 8.9) {
if (actual_year) {
idf$add(RunPeriod = list("actual_year", 1, 1, 2012, 12, 31))
} else {
idf$add(RunPeriod = list("actual_year", 1, 1, NULL, 12, 31))
}
} else {
if (actual_year) {
idf$add(RunPeriod = list("full_year", 1, 1, 12, 31, start_year = 2012))
} else {
idf$add(RunPeriod = list("full_year", 1, 1, 12, 31))
}
}
idf
}
create_leapyear_epw <- function (epw) {
# get epw data
epw_data <- epw$data(start_year = 2012, update = TRUE)
# create leap day data
feb29 <- epw_data[datetime >= ymd("2012-03-01") & datetime < ymd("2012-03-02")]
set(feb29, NULL, "datetime", feb29$datetime - days(1))
set(feb29, NULL, "day", 29L)
epw_data_with_leap <- rbindlist(list(epw_data, feb29))
setorder(epw_data_with_leap, datetime)
# replace weather data with leap year data
epw$set(data = epw_data_with_leap, realyear = TRUE, start_day_of_week = weekdays(epw_data_with_leap$datetime[[1]]), warning = FALSE)
epw
}
# ver
ver <- c(8.8, 9.0, 9.1)
# type of run period
type_runperiod <- c("tmy", "amy")
# type of epw file
type_epw <- c("nonleap", "leap")
# combine all cases into a data.frame
comb <- cross_df(list(version = ver, type_runperiod = type_runperiod, type_epw = type_epw))
# get paths of idf and epw of all cases
input <- pmap(comb, function (version, type_runperiod, type_epw) {
idf <- read_idf(example_idf(version))
# decrease timestep per hour to speed up
idf$Timestep$set(1)
# only output outdoor air to speed up
add_output(idf)
# add tmy run period
add_runperiod(idf, switch(type_runperiod, tmy = FALSE, amy = TRUE))
# save
path_idf <- idf$save(file.path(tempdir(), version, paste0(type_runperiod, "_", type_epw, ".idf")), overwrite = TRUE)
epw <- read_epw(example_epw(version))
if (type_epw == "leap") epw <- create_leapyear_epw(epw)
# save
path_epw <- epw$save(file.path(tempdir(), version, paste0(type_epw, ".epw")), overwrite = TRUE)
c(idf = path_idf, epw = path_epw)
})
setDT(comb)
set(comb, NULL, c("idf", "epw"), list(map_chr(input, "idf"), map_chr(input, "epw")))
set(comb, NULL, "output_dir", file.path(dirname(comb$idf), comb$type_epw))
# run all cases
run_multi(comb$idf, comb$epw, comb$output_dir)
# get sql path
set(comb, NULL, "sql", file.path(comb$output_dir, paste0(tools::file_path_sans_ext(basename(comb$idf)), ".sql")))
# read output
set(comb, NULL, "num_leap", comb$sql %>% map_int(~eplus_sql(.x)$report_data(key_value = "Environment", month = 2, day = c(28, 29), all = TRUE)[, .(datetime, month, day)][, .N]))
set(comb, NULL, "num_row", comb$sql %>% map_int(~eplus_sql(.x)$read_table("Time")[, .N]))
comb[, .(version, type_runperiod, type_epw, num_row, num_leap)]
# version type_runperiod type_epw num_row num_leap
# 1: 8.8 tmy nonleap 8760 24
# 2: 9.0 tmy nonleap 8760 24
# 3: 9.1 tmy nonleap 8760 24
# 4: 8.8 amy nonleap 8760 24
# 5: 9.0 amy nonleap 8760 24
# 6: 9.1 amy nonleap 8760 24
# 7: 8.8 tmy leap 8784 48
# 8: 9.0 tmy leap 8784 48
# 9: 9.1 tmy leap 8760 24
# 10: 8.8 amy leap 8784 48
# 11: 9.0 amy leap 8784 48
# 12: 9.1 amy leap 8784 48
@hongyuanjia
Copy link
Author

In summary:

  1. If your input weather has a leap year, even if no Start Year is given in RunPeriod in your IDF, you will still get 366 days in v8.9 and v9.0. It means that the weather file can overwrite RunPeriod settings. This issues has been fixed via #7199. In EnergyPlus v9.1, Feb 29 gets skipped during simulation.
  2. If your input weather does not have a leap year but a Start Year is given in RunPeriod in your IDF, simulation can complete successfully, without any warnings on the missing Feb 29 data in your weather. There is an open issue about this in EnergPlus GitHub Repo.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment