Última actualización: 03 junio 2020



1 Definición

Las zonas de amortiguación son áreas de vegetación ribereña que se dispone en forma de franja a lo largo de la red hidrográfica y que por sus funciones naturales son usadas para reducir contaminación difusa desde zonas agrícolas.

2 Reglamentación de Zonas Buffer para el Santa Lucía

Según el Plan de Acción Santa Lucía - Medidas de segunda generación, se establece la zona buffer de 40 metros a lo largo de los cauces principales y de 25 metros en los tributarios menores.

La distribución espacial de las zonas buffer se puede consultar a continuación.En dónde para una mejor visualización se muestra el buffer de 160 metros para los cauces principales y de 20 metros para los tributarios.

3 Modelación de Zonas buffer con SWAT

SWAT modela las zonas buffer (Filter Strip) a través del VFSMOD (Muñoz-Carpena, Parsons, and Gilliam 1999), el cual es un modelo empírico que ha sido parametrizado con información de muchos experimentos de campo.

SWAT modela la zona buffer a nivel de HRU a través de 3 parámetros.

  • FILTER_RATIO: Relación area del HRU / area zona buffer. Rango 0-300. Valor mas común 30-60. Valor por defecto 40.
  • FILTER_CON: Fracción del HRU que drena hacia el 10% de la zona buffer con mayor flujo. Se estima que el 10% del filtro recibe entre 0.25-0.75 de la escorrentía. El valor por defecto es 0.5.
  • FILTER_CH: Fracción del flujo que está canalizada (esta fracción no se le aplica el filtro). Valor por defecto 0.

A efectos de simplificar el análisis solamente nos concentraremos en el parámetro FILTER_RATIO. Ya que es el parámetro que relaciona el area del HRU y el area del filtro. En otras palabras, este parámetro define el area del HRU que será utilizada para zona buffer.

Los parámetros FILTER_CON y FILTER_CH pueden afectar la efectividad de la zona buffer, son parámetros que dependen en gran medida del relieve y del drenaje. No serán abordados en este trabajo.

4 Definición de escenarios

Se consideran 6 anchos de zona buffer tanto para los cauces principales como para los tributarios. Los anchos considerados son 5, 10, 20, 40, 80 y 160 metros.

Estos anchos se pueden aplicar por ejemplo:

  • A nivel de cuenca la cuenca (6x6=36 escenarios)
  • A nivel de subcuencas (6x6x41=1476 escenarios)
  • Por uso de la tierra LECH, AGRP, AGRC, GRAS (6*4=24)
  • Por uso de la tierra y subcuenca (6x6x41x4= 5904)

5 Parametrización de los escenarios

Se desarrolló un código en R el cual permite calcular el parámetro FILTER_RATIO y el área de la zona buffer en función de los anchos definidos anteriormente. El código se muestra en el Anexo1: Filter_Ratio y requiere un pre-procesamiento en QGIS.

Los valores de FILTER_RATIO para los distintos escenarios se pueden consultar en la siguiente tabla:

6 Implementación de las Zonas Buffer en SWAT

La implenetación de las Zonas buffer en SWAT debe hacerse modificando y/o creando los archivos .ops y .sub. Estos archivos no pueden modificarse utilizando la versión actual de SWATplusR. La modificación se puede hacer siguiendo el código que se presenta en Anexo2: Modelación de zona buffer.

A efectos de mostrar un ejemplo de la implementación de las zonas buffer se ejecutó el modelo con:

  • Escenario base (sin Zona buffer ¿? a verificar)
  • Buffer de 40 metros en los cauces principales y 20 metros en los tributarios
  • Buffer de 160 metros en cauces principales y tributarios

La siguiente imagen muestra la probabilidad de tener una concentración de fósforo menor a el valor dado en el eje “x”. La linea vertical gris indica el valor de concentración máximo permitido en la norma (0.025 mg/l). Se tiene una probabilidad de ~0.65 de estar en la norma para Paso de los Troncos y en el orden de ~0.05 para Paso Pache. Estos resultados confirman lo que se conoce. Muchos ríos de Uruguay no cumplen con la norma. Igualmente se observa que el buffer de 160 metros no es una solución para que el río cumpla con la norma.

base <- readRDS("~/R_projects/SWAT_calibration_ETmodis/resultados/ZonaBuffer_optim22/test01_base.RDS")
P160T160 <- readRDS("~/R_projects/SWAT_calibration_ETmodis/resultados/ZonaBuffer_optim22/test01_P160T160.RDS")
P40T20 <- readRDS("~/R_projects/SWAT_calibration_ETmodis/resultados/ZonaBuffer_optim22/test01_P40T20.RDS")

# se eliminan los días donde el caudal simulado es cero
base = base[base$FLOW_41!=0 & base$FLOW_23!=0,]
P40T20 = P40T20[P40T20$FLOW_41!=0 & P40T20$FLOW_23!=0,]
P160T160 = P160T160[P160T160$FLOW_41!=0 & P160T160$FLOW_23!=0,]

# Concentración de Fósforo
base$conPT_41 = (1000*base$PT_41)/(base$FLOW_41*60*60*24)
base$conPT_23 = (1000*base$PT_23)/(base$FLOW_23*60*60*24)
P40T20$conPT_41 = (1000*P40T20$PT_41)/(P40T20$FLOW_41*60*60*24)
P40T20$conPT_23 = (1000*P40T20$PT_23)/(P40T20$FLOW_23*60*60*24)
P160T160$conPT_41 = (1000*P160T160$PT_41)/(P160T160$FLOW_41*60*60*24)
P160T160$conPT_23 = (1000*P160T160$PT_23)/(P160T160$FLOW_23*60*60*24)

# funciones de probabilidad acumulada
base_PT41 = ecdf(base$conPT_41)
base_PT23 = ecdf(base$conPT_23)
P40T20_PT41 = ecdf(P40T20$conPT_41)
P40T20_PT23 = ecdf(P40T20$conPT_23)
P160T160_PT41 = ecdf(P160T160$conPT_41)
P160T160_PT23 = ecdf(P160T160$conPT_23)

x = seq(0,2, length.out = 10000)

par(mfrow=c(1,2), mar=c(4,4,1,1))

plot(c(0.01,2), c(0.01,1), type="n", xlab = "Concentración (mg/l)", ylab = "Probabilidad", 
     log="x", las=1, main = "Paso Pache (41)")
lines(x, base_PT41(x))
lines(x, P40T20_PT41(x), col=2)
lines(x, P160T160_PT41(x), col=4)
abline(v=0.025, col=8, lty=2)

plot(c(0.01,2), c(0.01,1), type="n", xlab = "Concentración (mg/l)", ylab = "Probabilidad", 
     log="x", las=1, main = "Paso de los Troncos (23)")
lines(x, base_PT23(x))
lines(x, P40T20_PT23(x), col=2)
lines(x, P160T160_PT23(x), col=4)
abline(v=0.025, col=8, lty=2)

legend("bottomright", c("Base", "P40T20", "P160T160"), col=c(1,2,4),lty=1)

Anexo1: Filter_Ratio

rm(list = ls())

library(maptools)
library(raster)
library(rgeos)

utm = CRS("+proj=utm +zone=21 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs")

shp_dir = "C:/Users/Rafael Navas/Documents/R_projects/SWAT_calibration_ETmodis/SL_level5_mensual_backup/shapefiles/"

sub = readShapePoly(paste0(shp_dir,"subs1.shp"),
                    proj4string = CRS("+proj=utm +zone=21 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs"))

MontNat = readShapePoly("C:/Users/Rafael Navas/Google Drive/SWAT-SubSantaLucia/2-Input data/2-Uso del suelo/LCCS_shapes/LCCS2015/LCCS2015_MultipartToSinglepa_clip_dissolve.shp",
                          proj4string = CRS("+proj=utm +zone=21 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs"))
MontNat = MontNat[MontNat$LABE_15=="Monte Nativo",]

gIntersection(sub, MontNat, byid = F)


plot(MontNat,col=2,border=2)
plot(gIntersection(sub, MontNat, byid = FALSE), col=4, border=4, add=T)

FR = data.frame(subassin = c(), ZB_principal_km2 = c(), ZB_tributarios_km2 = c(), 
                area_ZB_km2 = c(), FILTER_RATIO=c())
for(sb in 12:41){
  print(sb)
  sub_sub = sub[sub$Subbasin==sb,]
  if(sb!=12){
    MontNat_sub = gIntersection(MontNat,sub_sub,  byid = FALSE, unaryUnion_if_byid_false=F)
  }else{
    MontNat_sub = 0
  }
  
  for(Psize in c("05","10","20","40","80","160")){
  for(Ssize in c("05","10","20","40","80","160")){
    ZB_P = readShapePoly(paste0(shp_dir, "ZB_P",Psize,".shp"),
                      proj4string = utm)    
    ZB_S = readShapePoly(paste0(shp_dir, "ZB_S",Ssize,".shp"),
                       proj4string = utm)
    ZB = gUnion(ZB_P, ZB_S,byid = F)
    ZB_sub = gIntersection(sub_sub, ZB, byid = FALSE)
    if(sb!=12){
      MontNat_ZB = gIntersection(MontNat_sub, ZB_sub, byid = FALSE)
      area_MontNat = ifelse(is.null(MontNat_ZB), 0, area(MontNat_ZB))
    }else{
      area_MontNat = 0
    }
    area_ZB = (area(ZB_sub) - area_MontNat)/1000000
    area_sub = area(sub_sub)/1000000
    FILTER_RATIO = area_sub/area_ZB
    FR_in = data.frame(subassin = sb, ZB_principal_km2 = Psize, ZB_tributarios_km2 = Ssize, 
                       area_ZB_km2 = area_ZB, FILTER_RATIO=FILTER_RATIO)
    FR = rbind(FR,FR_in)
    print(FR_in)
  }  
  }
  
}

saveRDS(FR, "C:/Users/Rafael Navas/Documents/R_projects/SWAT_calibration_ETmodis/02_codes_scenarios/03_filter_ratio.RDS")

Anexo2: Modelación de zona buffer

Este código modifica y crea los archivos .ops y .sub para modelar la zona buffer. Se cambian únicamente los usos de suelo GRAS, AGRP, AGRC y LECH (711 HRU cambiados de un total de 865).

rm(list=ls())

library(tibble)
library(SWATplusR)
library(stringi)
library(stringr)

# lectura de parámetros optimizados
par_set = readRDS("./resultados/optim20200401_22/best_par_tibble.RDS")

# Creacion de escenarios
FR = readRDS("./02_codes_scenarios/03_filter_ratio.RDS")

model_path = "./SWAT_SL_20200401/"
runrun_path = "./ModelRun_FilterStrip"

# Cuidado aqui se elimina la carpeta runrun_path!!!!!!!!!!!!!!!!
unlink(runrun_path, recursive = TRUE)
dir.create(runrun_path)

# creacion de un nuevo directorio
R.utils::copyDirectory(from=model_path, to=runrun_path)

#Lectura metadata HRU
hru_info <- readRDS("~/R_projects/SWAT_calibration_ETmodis/shapefiles_RDS/hru_info.RDS")

# Seleccion de HRU a aplicar cambios (FILTER_RATIO) 
hru2change = hru_info[hru_info$LANDUSE %in% c("GRAS", "AGRC", "AGRP", "LECH"),]


# Alteracion de parametros del Filter Strip
BufferPrin = "40"
BufferTrib = "20"
FilterRatio2sub = FR[FR$ZB_principal_km2==BufferPrin & FR$ZB_tributarios_km2==BufferTrib,]

hru2change$FilterRatio = FilterRatio2sub$FILTER_RATIO[match(hru2change$Subbasin, FilterRatio2sub$subassin)]

# creacion de archivos .ops

for(i in 1:nrow(hru2change)){
  MONTH = 1
  DAY = 1
  IYEAR = 2009
  MGT_OP = 4
  FILTER_I = 1
  FILTER_RATIO = hru2change$FilterRatio[i]
  FILTER_CON = 0.5
  FILTER_CH = 0
  
  fs_line =  paste0(str_pad(MONTH, 3, pad=" "),
                    str_pad(DAY, 6-3, pad=" "),
                    str_pad(IYEAR, 15-6, pad=" "),
                    str_pad(MGT_OP,18-15, pad = " "),
                    str_pad(FILTER_I,23-18, pad = " "),
                    str_pad(round(FILTER_RATIO,2),34-23, pad = " "),
                    str_pad(round(FILTER_CON,5),47-34, pad = " "),
                    str_pad(round(FILTER_CH,2),54-47, pad = " "))
  
  ops_file = paste0(hru2change$HRUGIS[i],".ops")
  ops_out = rbind(".ops generado en R", fs_line)
  write.table(ops_out, file=paste0(runrun_path,"/", ops_file), quote = F, col.names = F,
              row.names = F)
  
}

#Modificacion de archivos .sub
sub_files = list.files(runrun_path, pattern = ".sub", full.names = T)
for(i in 1:length(sub_files)){
  sub_file = readLines(sub_files[i])
  cc = substr(sub_file,1,9) %in% paste(hru2change$HRUGIS)    
  substr(sub_file[cc], 66, 78) <-  paste0(substr(sub_file[cc],1,10),"ops")
  write.table(sub_file, file=sub_files[i], quote = F, col.names = F,
              row.names = F)
}



# escenario base
base = run_swat2012(project_path = model_path,
                    output = list(FLOW = define_output(file = "rch",
                                                       variable = "FLOW_OUT",
                                                       unit = c(23,41)),
                                  PT = define_output(file = "rch",
                                                     variable = "TOT_Pkg",
                                                     unit = c(23,41)),
                                  NO3 = define_output(file = "rch",
                                                      variable = "NO3_OUT",
                                                      unit = c(23,41))),
                                         parameter = par_set[1,],
                    start_date = as.Date("2009-01-01"),
                    end_date = as.Date("2015-12-31"),
                    years_skip = 1,
                    add_parameter = FALSE,
                    keep_folder = F)

saveRDS(base, "./resultados/ZonaBuffer_optim22/test01_base.RDS")

# ejecucion del modelo
P40T20 = run_swat2012(project_path = runrun_path,
                     output = list(FLOW = define_output(file = "rch",
                                                        variable = "FLOW_OUT",
                                                        unit = c(23,41)),
                                   PT = define_output(file = "rch",
                                                      variable = "TOT_Pkg",
                                                      unit = c(23,41)),
                                   NO3 = define_output(file = "rch",
                                                       variable = "NO3_OUT",
                                                       unit = c(23,41))),
                     parameter = par_set[1,],
                     start_date = as.Date("2009-01-01"),
                     end_date = as.Date("2015-12-31"),
                     years_skip = 1,
                     add_parameter = FALSE,
                     keep_folder = F)

saveRDS(P40T20, "./resultados/ZonaBuffer_optim22/test01_P40T20.RDS")



# segunda escenario zona buffer de 160 metros
# Alteracion de parametros del Filter Strip
BufferPrin = "160"
BufferTrib = "160"
FilterRatio2sub = FR[FR$ZB_principal_km2==BufferPrin & FR$ZB_tributarios_km2==BufferTrib,]

hru2change$FilterRatio = FilterRatio2sub$FILTER_RATIO[match(hru2change$Subbasin, FilterRatio2sub$subassin)]

# creacion de archivos .ops

for(i in 1:nrow(hru2change)){
  MONTH = 1
  DAY = 1
  IYEAR = 2009
  MGT_OP = 4
  FILTER_I = 1
  FILTER_RATIO = hru2change$FilterRatio[i]
  FILTER_CON = 0.5
  FILTER_CH = 0
  
  fs_line =  paste0(str_pad(MONTH, 3, pad=" "),
                    str_pad(DAY, 6-3, pad=" "),
                    str_pad(IYEAR, 15-6, pad=" "),
                    str_pad(MGT_OP,18-15, pad = " "),
                    str_pad(FILTER_I,23-18, pad = " "),
                    str_pad(round(FILTER_RATIO,2),34-23, pad = " "),
                    str_pad(round(FILTER_CON,5),47-34, pad = " "),
                    str_pad(round(FILTER_CH,2),54-47, pad = " "))
  
  ops_file = paste0(hru2change$HRUGIS[i],".ops")
  ops_out = rbind(".ops generado en R", fs_line)
  write.table(ops_out, file=paste0(runrun_path,"/", ops_file), quote = F, col.names = F,
              row.names = F)
  
}


# ejecucion del modelo
P160T160 = run_swat2012(project_path = runrun_path,
                      output = list(FLOW = define_output(file = "rch",
                                                         variable = "FLOW_OUT",
                                                         unit = c(23,41)),
                                    PT = define_output(file = "rch",
                                                       variable = "TOT_Pkg",
                                                       unit = c(23,41)),
                                    NO3 = define_output(file = "rch",
                                                        variable = "NO3_OUT",
                                                        unit = c(23,41))),
                      parameter = par_set[1,],
                      start_date = as.Date("2009-01-01"),
                      end_date = as.Date("2015-12-31"),
                      years_skip = 1,
                      add_parameter = FALSE,
                      keep_folder = F)

saveRDS(P160T160, "./resultados/ZonaBuffer_optim22/test01_P160T160.RDS")

Muñoz-Carpena, Rafael, John E. Parsons, and J.Wendell Gilliam. 1999. “Modeling Hydrology and Sediment Transport in Vegetative Filter Strips.” Journal of Hydrology 214 (1-4): 111–29. https://doi.org/10.1016/S0022-1694(98)00272-8.

 




A work by Rafael Navas