Section 11 Management (SWATfarmR)

WIP: Every field in the OPTAIN SWAT setup needs its own management. We will use the SWATFarmR package to define it.

run_this_chapter = FALSE

Pre-requirements

The creation of management schedules with SWATfarmR requires a SWAT+ model setup created by the SWATbuildR package.

We also require the following package and functions:

require(DT)
require(ggplot2)
require(readr)
require(stringr)
require(magrittr)
require(SWATfarmR)
require(sf)
require(tidyverse)
require(lubridate)
require(reshape2)
require(remotes)
require(dplyr)
require(data.table)
require(DT)

source('model_data/code/functions_write_SWATfarmR_input.R')

11.1 Pre-processing crop rotation

This OPTAIN-provided workflow pre-processes our crop rotation data into a SWATfarmR compatible format. Authored by Michael Strauch, modified by Moritz Shore

11.1.1 Input files

11.1.1.1 Land use map with crop information

This map has the following requirements:

  1. The map must contain the land use of each hru. In case of cropland, the names must be unique for each field (e.g., ‘field_1’, ‘field_2’, etc.)

  2. The map must also contain crop infos for the period 1988 to 2020 (or 2021 if crop info available). This requires an extrapolation of the available crop sequences (the sequences derived from remote-sensing based crop classification or local data).

  3. The extrapolated crop sequence for 33 years will be also used for running climate scenarios and must not contain any gaps. That means, gaps have to be closed manually!

  4. The year columns must be named y_1988, y_1989, etc.

  5. The crop infos for each year must match the crop_mgt names in the management operation schedules (provided in a .csv file, see below)

see also section 4.1 of the modelling protocol (Schürz et al. 2022)

lu_shp <- 'model_data/input/crop/land_with_cr.shp'

lu <- st_drop_geometry(read_sf(lu_shp))

datatable(
  lu %>% head(50),
  extensions = "Scroller",
  options = list(scrollY = 200, scroller = TRUE)
)

11.1.1.2 Management operation schedules for each crop

..or, if available, crop-management type.

  1. All schedules must be compiled in one csv file (see example in demo data and study also section 4.2 of the modelling protocol)

  2. ‘crop_mgt’ must start with the 4-character SWAT crop names (any further management specification is optional).

  3. Each schedule must contain a ‘skip’ line to indicate the change of years.

  4. The ‘skip’ line should never be the last line of a schedule.

mgt_csv <- 'model_data/input/management/mgt_crops_CS10.csv'

mgt_crop <- read.csv(mgt_csv)

datatable(mgt_crop,
          extensions = "Scroller",
          options = list(scrollY = 200, scroller = TRUE))

11.1.1.3 Management operation schedules for generic land-use classes

Usually all non-cropland classes with vegetation cover

  1. here, all schedules must be provided already in the SWATfarmR input format.
lu_generic_csv <- 'model_data/input/management/farmR_generic_CS10.csv' # generic land use management .csv table

mgt_generic <- read.csv(lu_generic_csv)

datatable(mgt_generic)

11.1.2 Settings

11.1.2.1 Simulation Period

start_y <- 2010 # starting year (consider at least 3 years for warm-up!)
end_y <- 2020 # ending year

11.1.2.2 Prefix of cropland hrus

all names of hrus with a crop rotation must begin with this prefix in column ‘lu’ of your land use

hru_crops <- 'a_'

11.1.2.3 Multi-year farmland grass

Did you define any multi-year farmland grass schedules? ‘y’ (yes), ‘n’ (no)

m_yr_sch_existing <- 'n'

If yes, define also the following variables. If not, skip next four lines

crop_myr <- 'past' # name of your farmland grass

Maximum number of years farmland grass can grow before it is killed (should be <8)

max_yr <- 5

Do your multi-year farmland grass schedules consider the type of the following crop (summer or winter crop)?

(e.g., a ’_1.5yr’ schedule with a kill op in spring allows for planting a summer crop immediately afterwards)

If yes, you must define your summer crops

crop_s <- c('sgbt','csil','barl')

Do your summer crop schedules usually start with an operation in autumn (e.g. tillage)? To combine them with farmland grass, it is necessary that you provide ‘half-year-schedules’ (‘half-year-schedules’ are additional summer crop schedules without operations in autumn) The adapted schedules should be added to the crop management table with suffix ’_0.5yr’ (e.g. ‘csil_0.5yr’)

If additional ‘half-year-schedules’ are not needed, because your normal summer crop schedules do not start in autumn, type ‘n’

additional_h_yr_sch_existing <- 'n' # 'y' (yes), 'n' (no)

11.1.3 Checks

Check for correct positioning of ‘skip’ line

check_skip <- check_skip_position()

Check for date conflicts in single crop schedules

check_date_conflicts1()

Build schedules for crop sequences (Messages disabled)

rota_schedules <- build_rotation_schedules()

Check for date conflicts in the full rotation schedule. (Messages disabled)

check_date_conflicts2()

Solve minor date conflicts (where only a few days/weeks are overlapping)

(Messages disabled)

rota_schedules <- solve_date_conflicts()

Check again for date conflicts (Messages disabled)

check_date_conflicts2()

11.1.4 Writing input data

Write the SWAT farmR input table

write_farmR_input()

The output of this pre-processing stage is loaded in from this file:

farmR_input <- readr::read_csv("model_data/input/management/farmR_input.csv",
                               show_col_types = F)

datatable(
  head(farmR_input, 50),
  extensions = "Scroller",
  options = list(scrollY = 200, scroller = TRUE)
)

Micha’s preperation script prints out land use names which will not work for us, we need to fix them.

This is how our land-use names look:

lus <- read.table("model_data/cs10_setup/swat_input_mod/landuse.lum",
                  skip = 1, header = T)

datatable(lus)

As we can see, we have land uses with either the suffix _drn_lum or just _lum. However, our farmR input only has _lum. We need to fix that:

fix <- farmR_input

fix$land_use <- farmR_input$land_use %>% str_remove_all("_lum")

# remove duplicates
#fix2 <- distinct(fix) # does this work? or are they read sequentially?

drained_fields <- lus$name[which(grepl(x = lus$name, "_drn_"))] %>% str_remove("_drn") %>% str_remove("_lum")

non_drained_fields <- lus$name[which(!(grepl(x = lus$name, "_drn_lum")))] %>% str_remove("_drn") %>% str_remove("_lum")

fixed_drained <- fix[which(fix$land_use %in% drained_fields),]
fixed_non_drained <- fix[which(fix$land_use %in% non_drained_fields),]

fixed_non_drained$land_use <- paste0(fixed_non_drained$land_use, "_lum")
fixed_drained$land_use <- paste0(fixed_drained$land_use, "_drn_lum")

full_fix <- rbind(fixed_non_drained, fixed_drained)
datatable(full_fix)
write_csv(full_fix, file ="model_data/input/management/farmR_input2.csv", na = "")

11.2 Initializing FarmR

We will create a dedicated directory for our SWATfarmR and copy in our latest text input files.

dir.create("model_data/cs10_setup/swat_farmR/", showWarnings = F)

sta_files <- list.files("model_data/cs10_setup/optain-cs10/",
                        pattern = "sta_",
                        full.names = T)

cli_files <- list.files("model_data/cs10_setup/optain-cs10/",
                        pattern = ".cli",
                        full.names = T)

input_files_base <- list.files("model_data/cs10_setup/swat_input/",
                               full.names = T)

source_files <- c(sta_files, cli_files, input_files_base)

status <- file.copy(from = source_files,
                    to = "model_data/cs10_setup/swat_farmR/",
                    overwrite = T)

# overwriting the base files with our modifications
input_files_mod <- list.files("model_data/cs10_setup/swat_input_mod/",
                              full.names = T)

status_mod <- file.copy(from = input_files_mod, 
                        to = "model_data/cs10_setup/swat_farmR/",
                        overwrite = T)

If the FarmR has never been initialized, then use new_farmr() and read_management(), otherwise load_farmr().

project_path <- "model_data/cs10_setup/swat_farmr/"

file.remove("model_data/cs10_setup/swat_farmR/cs10.farm")

new_farmr(project_name = "cs10", project_path = project_path )

#load_farmr(...)

cs10$read_management(file = "model_data/input/management/farmR_input2.csv")

11.3 Calculating API

TODO loading API from section REF

# using temp API
# TODO add real API

# Load dplyr. We will use functions such as 'mutate' and 'select'.
library(dplyr)
# Extract the precipitation from the farmr project
pcp <- cs10$.data$variables$pcp

# Extract the hydrologic soil group values for all HRUs
hsg <- select(cs10$.data$meta$hru_attributes, hru, hyd_grp)

# Calculate api values for the hsg classes A to D
api_A <- variable_decay(variable = pcp, n_steps = -5, decay_rate = 1)
api_B <- variable_decay(variable = pcp, n_steps = -5, decay_rate = 0.8)
api_C <- variable_decay(variable = pcp, n_steps = -5, decay_rate = 0.7)
api_D <- variable_decay(variable = pcp, n_steps = -5, decay_rate = 0.5)

# Bind the data together into one api table and name them with the hsgs
api <- bind_cols(api_A, api_B, api_C, api_D)
names(api) <- c('api_A', 'api_B', 'api_C', 'api_D')

# To add the variable to the farmR you have to tell it which variables are
# assigned to which HRUs
hru_asgn <- mutate(hsg, api = paste0('api_', hyd_grp)) %>% select(hru, api)
  
# Add the variable api to the farmR project
cs10$add_variable(data = api, name = 'api', assign_unit = hru_asgn, overwrite = T)

TODO

11.4 Scheduling Operations

cs10$schedule_operations(start_year = 2011,
                         end_year = 2020,
                         n_schedule = 2,
                         replace = "all")

11.4.1 Write Operations

We cannot write from 1988 as it is limited to our climate data, which currently only spans back to 2010 (2011?)

cs10$write_operations(start_year = 2011, end_year = 2020)

“Writing management files: - Loading scheduled operations: 100%
- Preparing ‘hru-data.hru’ - Preparing ‘landuse.lum’ - Preparing ‘schedule.mgt’ - Preparing ‘plant.ini’ - Writing files - Updating ‘time.sim’ - Updating ‘file.cio’ Finished writing management files in 5M 40S”

Make sure to use the files in the SWATfarmR directory going forward.

Test to see if the setup still works:

# No it does not 
# TODO

Temp fix:

### Change tiledrain to 0

Related Issues

FarmR 3.1 Issues UFZ #28

FarmR 3.1 Fix UFZ #27 on the UFZ gitlab FarmR 3.0 issues – #64

Update FarmR to 3.0 - #56

No Plant ET - #48

Schedule Ops 1988-2020 - #51

Re-extrapolate the crop rotation - #47

References

Schürz, Christoph, Natalja Čerkasova, Csilla Farkas, Attila Nemes, Plunge, Michael Strauch, Brigitta Szabó, and Mikołaj Piniewski. 2022. “SWAT+ Modeling Protocol for the Assessment of Water and Nutrient Retention Measures in Small Agricultural Catchments,” December. https://doi.org/10.5281/ZENODO.7463395.