Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 102 additions & 0 deletions SCENARIO_TABLES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# Scenario decision tables

This document summarizes how SWAT+ handles scenario-based land use
changes through the `scen_lu.dtl` and `scen_dtl.upd` files.

## `scen_lu.dtl`

Decision tables that drive scenario land use changes are stored in
`scen_lu.dtl`. The file is read during initialization by
`dtbl_scen_read`:

```
28 inquire (file=in_cond%dtbl_scen, exist=i_exist)
29 if (.not. i_exist .or. in_cond%dtbl_scen == "null") then
30 allocate (dtbl_scen(0:0))
...
43 do i = 1, mdtbl
44 read (107,*,iostat=eof) header
45 if (eof < 0) exit
46 read (107,*,iostat=eof) dtbl_scen(i)%name, dtbl_scen(i)%conds, dtbl_scen(i)%alts, dtbl_scen(i)%acts
...
58 !read conditions and condition alternatives
59 read (107,*,iostat=eof) header
60 if (eof < 0) exit
61 do ic = 1, dtbl_scen(i)%conds
62 read (107,*,iostat=eof) dtbl_scen(i)%cond(ic), (dtbl_scen(i)%alt(ic,ial), ial = 1, dtbl_scen(i)%alts)
```

The routine allocates arrays for each table, then reads its list of
conditions, alternatives and actions. When an action type is
`"lu_change"` the code cross references the land use name to the
internal database:

```
76 do iac = 1, dtbl_scen(i)%acts
77 select case (dtbl_scen(i)%act(iac)%typ)
78 case ("lu_change")
79 do ilum = 1, db_mx%landuse
80 if (dtbl_scen(i)%act(iac)%file_pointer == lum(ilum)%name) then
81 dtbl_scen(i)%act_typ(iac) = ilum
```

These tables specify exactly which HRUs to change and what new land use
management file to apply when the listed conditions are satisfied.

## `scen_dtl.upd`

The file `scen_dtl.upd` lists which scenario tables are active. It is
read by `cal_cond_read`:

```
38 inquire (file="scen_dtl.upd", exist=i_exist)
39 if (.not. i_exist .or. "scen_dtl.upd" == "null") then
40 allocate (upd_cond(0:0))
...
55 do i = 1, num_dtls
56 read (107,*,iostat=eof) upd_cond(i)%max_hits, upd_cond(i)%typ, upd_cond(i)%dtbl
...
60 do icond = 1, db_mx%dtbl_scen
61 if (upd_cond(i)%dtbl == dtbl_scen(icond)%name) then
62 upd_cond(i)%cond_num = icond
```

Each row references a table from `scen_lu.dtl`; the array index is saved
as `upd_cond(i)%cond_num`. The total number of rows becomes
`db_mx%cond_up`, which controls the daily loop over scenario updates.

## Daily processing

During the simulation loop in `time_control.f90` the model evaluates all
scenario tables for every HRU each day:

```
223 !! conditional reset of land use and management
224 do iupd = 1, db_mx%cond_up
225 id = upd_cond(iupd)%cond_num
226 d_tbl => dtbl_scen(id)
227 do j = 1, sp_ob%hru
228 call conditions (j, id)
229 call actions (j, iob, id)
230 end do
231 end do
```

Each entry in `scen_dtl.upd` triggers one pass through its corresponding
decision table. When the table conditions are met, actions such as
`lu_change` adjust the HRU’s land use. The data structures for decision
Tables are defined in `conditional_module.f90`:

```
28 type decision_table
29 character(len=25) :: name
30 integer :: conds
31 integer :: alts
32 integer :: acts
...
36 integer, dimension(:), allocatable :: lu_chg_mx
37 character(len=1), dimension(:,:), allocatable :: act_outcomes
```

Understanding these files allows users to configure when and where
scenario-specific management changes take effect.
3 changes: 3 additions & 0 deletions curno.f90
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ subroutine curno(cnn,h)
real :: amin1 ! |

cn2(h) = cnn
if (cn2(h) > 100.) then
write (9005,*) "CN2 exceeds 100", h, cn2(h)
end if

!! calculate moisture condition I and III curve numbers
c2 = 100. - cnn
Expand Down
3 changes: 2 additions & 1 deletion pl_burnop.f90
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ subroutine pl_burnop (jj, iburn)
soil1(j)%hsta(1)%p = soil1(j)%hsta(1)%p + pl_burn%p
else
!! dynamic carbon (bsn_cc%cswat == 2)
pl_burn = fire_db(iburn)%fr_burn * (soil1(j)%hs(1) + soil1(j)%hp(1) + soil1(j)%rsd(ipl))
!! rsd is indexed by soil layer; burn only surface residue
pl_burn = fire_db(iburn)%fr_burn * (soil1(j)%hs(1) + soil1(j)%hp(1) + soil1(j)%rsd(1))
soil1(j)%rsd(1) = (1. - fire_db(iburn)%fr_burn) * soil1(j)%rsd(1)
soil1(j)%hs(1) = (1. - fire_db(iburn)%fr_burn) * soil1(j)%hs(1)
soil1(j)%hp(1) = (1. - fire_db(iburn)%fr_burn) * soil1(j)%hp(1)
Expand Down
6 changes: 5 additions & 1 deletion proc_bsn.f90
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ subroutine proc_bsn
open (9001,file="diagnostics.out", recl=8000) !!ext to 8000 recl per email 8/2/21 - Kai-Uwe
write (9001,*) "DIAGNOSTICS.OUT FILE"
!!! open drainage areas output file
open (9004,file="area_calc.out", recl=8000)
open (9004,file="area_calc.out", recl=8000)

!!! open file to log CN2 values exceeding 100
open (9005,file="cn2_warnings.out")
write (9005,*) "HRU curve numbers exceeding 100"

call basin_read_cc
call basin_read_objs
Expand Down
4 changes: 2 additions & 2 deletions soil_nutcarb_init.f90
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ subroutine soil_nutcarb_init (isol)

do ly = 1, nly
if (ly == 1) then
soil1(ihru)%cbn(ly) = max(0.001, soil(isol)%phys(ly)%cbn) !! assume 0.001% carbon if zero
soil1(ihru)%cbn(ly) = max(0.001, soil(ihru)%phys(ly)%cbn) !! assume 0.001% carbon if zero
else
soil1(ihru)%cbn(ly) = soil(isol)%phys(ly)%cbn
soil1(ihru)%cbn(ly) = soil(ihru)%phys(ly)%cbn
endif
enddo

Expand Down