Skip to contents

Install R package

# Enable repository from kwb-r
options(repos = c(
  kwbr = 'https://kwb-r.r-universe.dev',
  CRAN = 'https://cloud.r-project.org'))

# Download and install kwb.swmm in R
install.packages('kwb.swmm')

Download SWMM Executable

library(kwb.swmm)
#> SWMM executable not found.

swmm_exe <- kwb.swmm::download_swmm_executable(tdir = getwd(),
                                               swmm_version = "5.2.0")
#> Downloading and extracting SWMM folder to 'D:/a/kwb.swmm/kwb.swmm/vignettes' ... ok. (0.57 secs)

Define Paths


paths_list <- list(
  model_dir =  kwb.swmm::extdata_file("models/lid"),
  model_name = "zone-1_bioretention-cell_lidshare-1.00",
  model_inp = "<model_dir>/<model_name>.inp",
  model_out = "<model_dir>/<model_name>.out",
  model_rpt = "<model_dir>/<model_name>.rpt",
  swmm_exe = swmm_exe
)

paths <- kwb.utils::resolve(paths_list)

Read Input

inp <- swmmr::read_inp(paths$model_inp)

## print some inputs
inp$options
#> # A tibble: 34 × 2
#>    Option            Value     
#>    <chr>             <chr>     
#>  1 FLOW_UNITS        LPS       
#>  2 INFILTRATION      HORTON    
#>  3 FLOW_ROUTING      KINWAVE   
#>  4 LINK_OFFSETS      DEPTH     
#>  5 MIN_SLOPE         0         
#>  6 ALLOW_PONDING     NO        
#>  7 SKIP_STEADY_STATE NO        
#>  8 IGNORE_SNOWMELT   YES       
#>  9 START_DATE        04/30/2008
#> 10 START_TIME        00:00:00  
#> # ℹ 24 more rows

inp$lid_controls
#> # A tibble: 3 × 9
#>   Name                `Type/Layer`  Par1   Par2   Par3   Par4  Par5  Par6   Par7
#>   <chr>               <chr>        <int>  <dbl>  <dbl>  <dbl> <dbl> <dbl>  <dbl>
#> 1 bioretention_cell.… BC              NA NA     NA     NA      NA    NA   NA    
#> 2 bioretention_cell.… SURFACE        300  0.05   0.3    4       5    NA   NA    
#> 3 bioretention_cell.… SOIL           500  0.437  0.105  0.047   3.6   0.5  0.047

inp$lid_usage
#> # A tibble: 1 × 10
#>   Subcatchment `LID Process`   Number  Area Width InitSat FromImp ToPerv RptFile
#>   <chr>        <chr>            <int> <int> <int>   <int>   <int>  <int> <chr>  
#> 1 S1           bioretention_c…      1  1000     6       0       0      0 *      
#> # ℹ 1 more variable: DrainTo <chr>

Run SWMM

kwb.swmm::run_swmm(model_dir = paths$model_dir,
                   model_inp = paths$model_inp,
                   exe = paths$swmm_exe)

Read Output


results <- kwb.swmm::get_results(path_out = paths$model_out)
#> File D:/a/_temp/Library/kwb.swmm/extdata/models/lid/zone-1_bioretention-cell_lidshare-1.00.out opened.
#> InputStartPos: 42
#> OutputStartPos: 270
#> SWMM_Nperiods: 100463
#> errCode: 0
#> magic2: 516114522
#> 1 subcatchments read.
#> 1 nodes read.
#> 0 links read.
#> 0 pollutants read.
#> n_variables[SUBCATCH]: 8
#> n_variables[NODE]: 6
#> n_variables[LINK]: 5
#> n_variables[SYS]: 15
#> SWMM_StartDate: 39568.000000
#> SWMM_ReportStep: 3600
#> File D:/a/_temp/Library/kwb.swmm/extdata/models/lid/zone-1_bioretention-cell_lidshare-1.00.out opened.
#> InputStartPos: 42
#> OutputStartPos: 270
#> SWMM_Nperiods: 100463
#> errCode: 0
#> magic2: 516114522
#> 1 subcatchments read.
#> 1 nodes read.
#> 0 links read.
#> 0 pollutants read.
#> n_variables[SUBCATCH]: 8
#> n_variables[NODE]: 6
#> n_variables[LINK]: 5
#> n_variables[SYS]: 15
#> SWMM_StartDate: 39568.000000
#> SWMM_ReportStep: 3600
#> File D:/a/_temp/Library/kwb.swmm/extdata/models/lid/zone-1_bioretention-cell_lidshare-1.00.out opened.
#> InputStartPos: 42
#> OutputStartPos: 270
#> SWMM_Nperiods: 100463
#> errCode: 0
#> magic2: 516114522
#> 1 subcatchments read.
#> 1 nodes read.
#> 0 links read.
#> 0 pollutants read.
#> n_variables[SUBCATCH]: 8
#> n_variables[NODE]: 6
#> n_variables[LINK]: 5
#> n_variables[SYS]: 15
#> SWMM_StartDate: 39568.000000
#> SWMM_ReportStep: 3600
#> Reading time series 1/14 ... ok.
#> Reading time series 2/14 ... ok.
#> Reading time series 3/14 ... ok.
#> Reading time series 4/14 ... ok.
#> Reading time series 5/14 ... ok.
#> Reading time series 6/14 ... ok.
#> Reading time series 7/14 ... ok.
#> Reading time series 8/14 ... ok.
#> Reading time series 9/14 ... ok.
#> Reading time series 10/14 ... ok.
#> Reading time series 11/14 ... ok.
#> Reading time series 12/14 ... ok.
#> Reading time series 13/14 ... ok.
#> Reading time series 14/14 ... ok.
results
#> # A tibble: 100,463 × 15
#>    datetime            total_rainfall total_snow_depth average_losses
#>    <dttm>                       <dbl>            <dbl>          <dbl>
#>  1 2008-04-30 01:00:00          0                    0              0
#>  2 2008-04-30 02:00:00          0                    0              0
#>  3 2008-04-30 03:00:00          0                    0              0
#>  4 2008-04-30 04:00:00          0                    0              0
#>  5 2008-04-30 05:00:00          0                    0              0
#>  6 2008-04-30 06:00:00          0                    0              0
#>  7 2008-04-30 07:00:00          0.789                0              0
#>  8 2008-04-30 08:00:00          0                    0              0
#>  9 2008-04-30 09:00:00          0                    0              0
#> 10 2008-04-30 10:00:00          0                    0              0
#> # ℹ 100,453 more rows
#> # ℹ 11 more variables: total_runoff <dbl>, total_dry_weather_inflow <dbl>,
#> #   total_groundwater_inflow <dbl>, total_RDII_inflow <dbl>,
#> #   total_external_inflow <dbl>, total_direct_inflow <dbl>,
#> #   total_external_flooding <dbl>, total_outflow_from_outfalls <dbl>,
#> #   total_nodal_storage_volume <dbl>, potential_evaporation <dbl>,
#> #   actual_evaporation <dbl>

Calculate Rainstats

results_system <- kwb.swmm::get_results(path_out = paths$model_out,
                                        vIndex = c(1, 4)) %>%
  dplyr::rename(
    total_rainfall_mmPerHour = .data$total_rainfall,
    total_runoff_litrePerSecond = .data$total_runoff
  ) %>%
  dplyr::mutate(total_runoff_mmPerHour = kwb.swmm::lps_to_mmPerHour(.data$total_runoff_litrePerSecond)) %>%
  dplyr::select(-.data$total_runoff_litrePerSecond)
#> File D:/a/_temp/Library/kwb.swmm/extdata/models/lid/zone-1_bioretention-cell_lidshare-1.00.out opened.
#> InputStartPos: 42
#> OutputStartPos: 270
#> SWMM_Nperiods: 100463
#> errCode: 0
#> magic2: 516114522
#> 1 subcatchments read.
#> 1 nodes read.
#> 0 links read.
#> 0 pollutants read.
#> n_variables[SUBCATCH]: 8
#> n_variables[NODE]: 6
#> n_variables[LINK]: 5
#> n_variables[SYS]: 15
#> SWMM_StartDate: 39568.000000
#> SWMM_ReportStep: 3600
#> File D:/a/_temp/Library/kwb.swmm/extdata/models/lid/zone-1_bioretention-cell_lidshare-1.00.out opened.
#> InputStartPos: 42
#> OutputStartPos: 270
#> SWMM_Nperiods: 100463
#> errCode: 0
#> magic2: 516114522
#> 1 subcatchments read.
#> 1 nodes read.
#> 0 links read.
#> 0 pollutants read.
#> n_variables[SUBCATCH]: 8
#> n_variables[NODE]: 6
#> n_variables[LINK]: 5
#> n_variables[SYS]: 15
#> SWMM_StartDate: 39568.000000
#> SWMM_ReportStep: 3600
#> File D:/a/_temp/Library/kwb.swmm/extdata/models/lid/zone-1_bioretention-cell_lidshare-1.00.out opened.
#> InputStartPos: 42
#> OutputStartPos: 270
#> SWMM_Nperiods: 100463
#> errCode: 0
#> magic2: 516114522
#> 1 subcatchments read.
#> 1 nodes read.
#> 0 links read.
#> 0 pollutants read.
#> n_variables[SUBCATCH]: 8
#> n_variables[NODE]: 6
#> n_variables[LINK]: 5
#> n_variables[SYS]: 15
#> SWMM_StartDate: 39568.000000
#> SWMM_ReportStep: 3600
#> Reading time series 1/2 ... ok.
#> Reading time series 2/2 ... ok.
#> Warning: Use of .data in tidyselect expressions was deprecated in tidyselect 1.2.0.
#>  Please use `"total_rainfall"` instead of `.data$total_rainfall`
#> This warning is displayed once every 8 hours.
#> Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
#> generated.
#> Warning: Use of .data in tidyselect expressions was deprecated in tidyselect 1.2.0.
#>  Please use `"total_runoff"` instead of `.data$total_runoff`
#> This warning is displayed once every 8 hours.
#> Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
#> generated.
#> Warning: Use of .data in tidyselect expressions was deprecated in tidyselect 1.2.0.
#>  Please use `"total_runoff_litrePerSecond"` instead of
#>   `.data$total_runoff_litrePerSecond`
#> This warning is displayed once every 8 hours.
#> Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
#> generated.

results_system
#> # A tibble: 100,463 × 3
#>    datetime            total_rainfall_mmPerHour total_runoff_mmPerHour
#>    <dttm>                                 <dbl>                  <dbl>
#>  1 2008-04-30 01:00:00                    0                          0
#>  2 2008-04-30 02:00:00                    0                          0
#>  3 2008-04-30 03:00:00                    0                          0
#>  4 2008-04-30 04:00:00                    0                          0
#>  5 2008-04-30 05:00:00                    0                          0
#>  6 2008-04-30 06:00:00                    0                          0
#>  7 2008-04-30 07:00:00                    0.789                      0
#>  8 2008-04-30 08:00:00                    0                          0
#>  9 2008-04-30 09:00:00                    0                          0
#> 10 2008-04-30 10:00:00                    0                          0
#> # ℹ 100,453 more rows

results_vrr <-  results_system %>%
  dplyr::mutate(year = lubridate::year(.data$datetime)) %>%
  dplyr::group_by(.data$year) %>%
  dplyr::summarise(vrr = 1 - (
    sum(.data$total_runoff_mmPerHour) / sum(.data$total_rainfall_mmPerHour)
  ))
results_vrr
#> # A tibble: 12 × 2
#>     year   vrr
#>    <dbl> <dbl>
#>  1  2008     1
#>  2  2009     1
#>  3  2010     1
#>  4  2011     1
#>  5  2012     1
#>  6  2013     1
#>  7  2014     1
#>  8  2015     1
#>  9  2016     1
#> 10  2017     1
#> 11  2018     1
#> 12  2019     1

col_eventsep <- "total_rainfall_mmPerHour"

rainevent_stats_mean <-
  kwb.swmm::calculate_rainevent_stats(results_system,
                                      col_eventsep = col_eventsep,
                                      aggregation_function = "mean") %>%
  dplyr::mutate(
    rainfall_cbm = .data$dur * .data$mean_total_rainfall_mmPerHour / 3600 /
      1000,
    runoff_cbm = .data$dur * .data$mean_total_runoff_mmPerHour /
      3600 / 1000,
    vrr = 1 - runoff_cbm / rainfall_cbm
  ) %>%
  dplyr::arrange(dplyr::desc(.data$mean_total_rainfall_mmPerHour))
#> Calculating `mean` event stats for parameter `total_rainfall_mmPerHour` ... ok. (3.18 secs) 
#> Calculating `mean` event stats for parameter `total_runoff_mmPerHour` ... ok. (2.98 secs)

head(rainevent_stats_mean)
#>   iBeg iEnd                tBeg                tEnd   dur pBefore pAfter event
#> 1 5034 5034 2016-08-21 13:00:00 2016-08-21 13:00:00  3600   86400 162000   995
#> 2 3024 3035 2013-06-23 15:00:00 2013-06-24 04:00:00 50400   36000  25200   599
#> 3 5230 5238 2017-06-21 15:00:00 2017-06-21 23:00:00 32400   43200 259200  1046
#> 4 3224 3233 2013-08-06 14:00:00 2013-08-06 23:00:00 36000  280800  32400   642
#> 5 6062 6068 2019-08-07 15:00:00 2019-08-07 21:00:00 25200   68400  72000  1201
#> 6 5445 5447 2018-06-28 12:00:00 2018-06-28 14:00:00 10800   86400  72000  1092
#>   mean_total_rainfall_mmPerHour mean_total_runoff_mmPerHour rainfall_cbm
#> 1                      8.605081                           0  0.008605081
#> 2                      6.654423                           0  0.093161928
#> 3                      5.424497                           0  0.048820477
#> 4                      5.153533                           0  0.051535330
#> 5                      4.868611                           0  0.034080276
#> 6                      4.771171                           0  0.014313512
#>   runoff_cbm vrr
#> 1          0   1
#> 2          0   1
#> 3          0   1
#> 4          0   1
#> 5          0   1
#> 6          0   1

rainevent_stats_max <-
  kwb.swmm::calculate_rainevent_stats(results_system,
                                      col_eventsep = col_eventsep,
                                      aggregation_function = "max") %>%
  dplyr::arrange(dplyr::desc(.data$max_total_rainfall_mmPerHour))
#> Calculating `max` event stats for parameter `total_rainfall_mmPerHour` ... ok. (3.01 secs) 
#> Calculating `max` event stats for parameter `total_runoff_mmPerHour` ... ok. (2.45 secs)

head(rainevent_stats_max)
#>   iBeg iEnd                tBeg                tEnd    dur pBefore pAfter event
#> 1  911  953 2009-07-26 12:00:00 2009-07-28 20:00:00 205200   61200  36000   193
#> 2 5230 5238 2017-06-21 15:00:00 2017-06-21 23:00:00  32400   43200 259200  1046
#> 3 3224 3233 2013-08-06 14:00:00 2013-08-06 23:00:00  36000  280800  32400   642
#> 4 3024 3035 2013-06-23 15:00:00 2013-06-24 04:00:00  50400   36000  25200   599
#> 5 2554 2559 2012-07-17 16:00:00 2012-07-17 21:00:00  21600   72000  21600   502
#> 6 5994 6002 2019-07-29 16:00:00 2019-07-30 03:00:00  43200  212400  43200  1192
#>   max_total_rainfall_mmPerHour max_total_runoff_mmPerHour
#> 1                     21.09241                          0
#> 2                     17.84431                          0
#> 3                     16.58891                          0
#> 4                     15.38480                          0
#> 5                     15.36419                          0
#> 6                     15.04827                          0