Skip to contents

To be able to simulate the hydraulic dynamics inside a building during a flood event comes with its perks. One of them is that it allows us to refine flood damage estimation in those case in which the floodwater depth outside and inside the building differ. Instead of assuming that the level of water observed outside is the same that we had inside (current standard practice), we can simulate the actual maximum flood water depth inside each room in the building and estimate the damage.

In this vignette we would like to show the procedure to use if you want to estimate a damage function that takes into account the hydraulic dynamics of your building for a set of specific flood events.

Libraries

We will need to run multiple simulations of flood events. To make this exercise less time-consuming we will use the parallel library to run these simulations.

The parallel library handles parallel computation with R. Please make sure it is installed in your system.

Estimating the damage function of reference.

We will use one of the models shipped with floodam.buildingcalled adu_t as an example. This model proposes a 4-room house where three of them are organized around a central living room.

The models are available in your library’s installation folder. To get the path to this folder just ask R to locate them using the system.file() function. Once the path is set you can call the analyse_model() function to create the object model, using the shipped adu_t model and specifying c("load", "extract", "hydraulic", "damaging") as stages of analysis.

The function analyse_model() estimates damage functions by room in the hydraulic stage. These functions are the reference that the function analyse_hydraulic() uses to estimate the damage with hydraulic dynamics. The damaging stage is also included in the function analyse_model() so the damage function without hydraulic dynamics for flood events up to 48 hours is also available for comparison.

It should be noted that the damage function without hydraulic dynamics for flood events up to 48 hours is the equivalent to a damage function estimated including hydraulic dynamics for those cases in which the floodwater depths inside and outside of the building are the same.

#> set up model path shipped with floodam.building
model_path = list(
  data = system.file("extdata", package = "floodam.building"),
  output = tempdir()
)

model = analyse_model(
  model = "adu_t",
  type = "adu",
  stage = c("load", "extract", "hydraulic", "damaging"),
  path = model_path
)

dam_less_48 = model[["damaging"]][["absolute"]][["total"]][,"12"]

Preparing the set of flood events

In this example we are going to focus in estimating the damage function include hydraulic dynamics for a 1-hour long event in which the water rises from 0 during the first half (30 minutes) and recedes to 0 during the second half. The floodwater depth will be a variable parameter. We will use a sequence from 0 to 2 meters, increasing the depth 10 centimeters at a time. The library floodam.building allows you to go up to 5 meters if you want to.

hpeaks = seq(0, 2.0, by = 0.1)

floods = lapply(
  hpeaks, 
  function(h) {
    generate_limnigraph(
      model = model,
      time = c(0, 5400, 10800),
      depth = cbind(facade_1 = c(0, h, 0)),
      exposition = list(
        facade_1 = list(
          external = c(
            "wall_A", "wall_B", "wall_C", "wall_D",
            "wall_G", "wall_H", "wall_E", "wall_F"
          )
        )
      )
    )
  }
)

names(floods) = paste0("sim_", hpeaks)

Each of the elements of this list is a limnigraph of a symmetric 3-hours long event. The floodwater depth increases throughout the list from 0 to 2 meters.

Simulating flood events and estimating flood damage

To reduce simulation time, we will use a parallel lapply() function included in the parallel library, the mclapply() function, setting the number of cores to use as the half of cores available in your computer. We recommend you to keep half your cores unsed so you can still use your computer without any hindrance.

We will use the mclapply() function to loop over the list floods that we created above. Each limnigraph in floods will be passed to the function analyse_hydraulic() that will be executed using c("hydraulic", "damaging") as stages. We recommend you to set the argument detail = FALSE so that the function only outputs the slots hmax and damage each simulation (minimum information needed for this exercise).

This step may take a few minutes depending on your computer.

hydraulic = parallel::mclapply(
  names(floods), 
  function(f) {
    analyse_hydraulic(
      model = model,
      limnigraph = floods[[f]],
      opening_scenario = "close",
      stage = c("hydraulic", "damaging"),
      detail = FALSE,
      sim_id = f
    )
  }, 
 mc.cores = detectCores()/2
)

Once the simulations are done, the object hydraulic is created. It is a list of 21 unnamed slots, each containing two slots: hmax and damage. The slot hmax contains a matrix with maximum flood water depth in each room plus outside the building (column facade_1). The slot damage contains a matrix with the estimated damage corresponding to the estimated floodwater depth by room, using as reference the room’s damage function for events up to 48 hours. The matrix also includes the sum of the rooms’ damage.

To extract the total damage from the slot damage for each simulation, you can proceed as follows:

damage = sapply(hydraulic, function(sim) sim[["damage"]][, "total"])

The damage object should be a numeric vector of 21 elements. Now that you have this vector we can plot it against the floodwater depth outside the building and compare it with the building’s damage function of reference that stored in the object dam_less_48 :

plot(
  hpeaks * 100, dam_less_48[as.numeric(names(dam_less_48)) <= max(hpeaks * 100)], 
  col = "black", 
  type = "l", 
  xlab = "water height (cm)",
  ylab = "damage (euro)", 
  main = "Damage functions for short flood durations"
)
lines(hpeaks * 100, damage, type = "l", col = "red")
legend(
  "bottomright", 
  legend = c("12h ref", "simulations"), 
  col = c("black", "red"), 
  lwd = 2.0, 
  title = "flood duration (h)"
)

Congrats you have made your first refined damage function taking in account a flood scenario!