Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hardening and frost mortality schemes in FATES #1865

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
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
5 changes: 3 additions & 2 deletions bld/CLMBuildNamelist.pm
Original file line number Diff line number Diff line change
Expand Up @@ -773,7 +773,7 @@ sub setup_cmdl_fates_mode {
} else {
# dis-allow fates specific namelist items with non-fates runs
my @list = ( "fates_spitfire_mode", "use_fates_planthydro", "use_fates_ed_st3", "use_fates_ed_prescribed_phys",
"use_fates_cohort_age_tracking",
"use_fates_cohort_age_tracking","use_fates_hydrohard","use_fates_frosthard",
"use_fates_inventory_init","use_fates_fixed_biogeog","use_fates_nocomp","use_fates_sp","fates_inventory_ctrl_filename","use_fates_logging","fates_parteh_mode","use_fates_tree_damage" );
# dis-allow fates specific namelist items with non-fates runs
foreach my $var ( @list ) {
Expand Down Expand Up @@ -4114,7 +4114,8 @@ sub setup_logic_fates {
add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'fates_paramfile', 'phys'=>$nl_flags->{'phys'});
my @list = ( "fates_spitfire_mode", "use_fates_planthydro", "use_fates_ed_st3", "use_fates_ed_prescribed_phys",
"use_fates_inventory_init","use_fates_fixed_biogeog","use_fates_nocomp",
"use_fates_logging","fates_parteh_mode", "use_fates_cohort_age_tracking","use_fates_tree_damage" );
"use_fates_logging","fates_parteh_mode", "use_fates_cohort_age_tracking","use_fates_tree_damage",
"use_fates_hydrohard","use_fates_frosthard");
foreach my $var ( @list ) {
add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $var, 'use_fates'=>$nl_flags->{'use_fates'},
'use_fates_sp'=>$nl_flags->{'use_fates_sp'} );
Expand Down
2 changes: 2 additions & 0 deletions bld/namelist_files/namelist_defaults_ctsm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2541,6 +2541,8 @@ lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_ne0np4.CONUS.ne30x8_hist_78pfts
<!-- ===== FATES DEFAULTS =========== -->
<fates_spitfire_mode use_fates=".true.">0</fates_spitfire_mode>
<use_fates_planthydro use_fates=".true.">.false.</use_fates_planthydro>
<use_fates_hydrohard use_fates=".true.">.false.</use_fates_hydrohard>
<use_fates_frosthard use_fates=".true.">.false.</use_fates_frosthard>
<use_fates_tree_damage use_fates=".true.">.false.</use_fates_tree_damage>
<use_fates_cohort_age_tracking use_fates=".true.">.false.</use_fates_cohort_age_tracking>
<use_fates_ed_st3 use_fates=".true.">.false.</use_fates_ed_st3>
Expand Down
12 changes: 12 additions & 0 deletions bld/namelist_files/namelist_definition_ctsm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -687,6 +687,18 @@ Toggle to turn on plant hydraulics
(Only relevant if FATES is on)
</entry>

<entry id="use_fates_hydrohard" type="logical" category="physics"
group="clm_inparm" valid_values="" value=".false.">
Toggle to turn on plant hydrohard (only relevant if FATES is on).
(use_fates_hydrohard=".true." is EXPERIMENTAL NOT SUPPORTED! Nor is it Tested!)
</entry>

<entry id="use_fates_frosthard" type="logical" category="physics"
group="clm_inparm" valid_values="" value=".false.">
Toggle to turn on plant frosthard (only relevant if FATES is on).
(use_fates_frosthard=".true." is EXPERIMENTAL NOT SUPPORTED! Nor is it Tested!)
</entry>

<entry id="use_fates_cohort_age_tracking" type="logical" category="physics"
group="clm_inparm" valid_values="" value=".false.">
Toggle to turn on cohort age tracking (by default FATES only tracks age of patches)
Expand Down
130 changes: 128 additions & 2 deletions src/main/atm2lndType.F90
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ module atm2lndType
use clm_varpar , only : numrad, ndst, nlevgrnd !ndst = number of dust bins.
use clm_varcon , only : rair, grav, cpair, hfus, tfrz, spval
use clm_varctl , only : iulog, use_c13, use_cn, use_lch4, use_cndv, use_fates, use_luna
use clm_varctl , only : use_fates_hydrohard,use_fates_frosthard
use decompMod , only : bounds_type
use abortutils , only : endrun
use PatchType , only : patch
Expand Down Expand Up @@ -114,6 +115,12 @@ module atm2lndType
real(r8) , pointer :: wind24_patch (:) => null() ! patch 24-hour running mean of wind
real(r8) , pointer :: t_mo_patch (:) => null() ! patch 30-day average temperature (Kelvin)
real(r8) , pointer :: t_mo_min_patch (:) => null() ! patch annual min of t_mo (Kelvin)
real(r8) , pointer :: temp24_patch (:) => null() ! patch 24hr average of temperature
real(r8) , pointer :: tmin24_patch (:) => null() ! patch 24hr average of minimum temperature
real(r8) , pointer :: tmin24_inst_patch (:) => null() ! patch 24hr average of temprary temperature
real(r8) , pointer :: t_mean_5yr_patch (:) => null() ! patch 5 year mean of minimum yearly 2 m height surface air temperature (K)
real(r8) , pointer :: t_min_yr_patch (:) => null()
real(r8) , pointer :: t_min_yr_inst_patch (:) => null()

contains

Expand Down Expand Up @@ -508,6 +515,14 @@ subroutine InitAllocate(this, bounds)
allocate(this%fsd240_patch (begp:endp)) ; this%fsd240_patch (:) = nan
allocate(this%fsi24_patch (begp:endp)) ; this%fsi24_patch (:) = nan
allocate(this%fsi240_patch (begp:endp)) ; this%fsi240_patch (:) = nan
if (use_fates_hydrohard .or. use_fates_frosthard) then
allocate(this%temp24_patch (begp:endp)) ; this%temp24_patch (:) = nan
allocate(this%tmin24_patch (begp:endp)) ; this%tmin24_patch (:) = nan
allocate(this%tmin24_inst_patch (begp:endp)) ; this%tmin24_inst_patch (:) = nan
allocate(this%t_min_yr_patch (begp:endp)) ; this%t_min_yr_patch (:) = nan
allocate(this%t_min_yr_inst_patch (begp:endp)) ; this%t_min_yr_inst_patch (:) = nan
allocate(this%t_mean_5yr_patch (begp:endp)) ; this%t_mean_5yr_patch (:) = nan
end if
if (use_fates) then
allocate(this%wind24_patch (begp:endp)) ; this%wind24_patch (:) = nan
end if
Expand Down Expand Up @@ -664,6 +679,17 @@ subroutine InitHistory(this, bounds)
ptr_patch=this%forc_pbot240_downscaled_patch, default='inactive')
endif

if (use_fates_hydrohard .or. use_fates_frosthard) then
this%temp24_patch(begp:endp) = spval
call hist_addfld1d (fname='TEMP24_CLM', units='K', &
avgflag='A', long_name='mean temp for hardening', &
ptr_patch=this%temp24_patch, default='active')
this%tmin24_patch(begp:endp) = spval
call hist_addfld1d (fname='TMIN24_CLM', units='K', &
avgflag='A', long_name='min temp for hardening', &
ptr_patch=this%tmin24_patch, default='active')
endif

end subroutine InitHistory

!-----------------------------------------------------------------------
Expand Down Expand Up @@ -724,6 +750,18 @@ subroutine InitAccBuffer (this, bounds)
call init_accum_field (name='pbot240', units='Pa', &
desc='10-day running mean of air pressure', accum_type='runmean', accum_period=-10, &
subgrid_type='pft', numlev=1, init_value=101325._r8)
endif

if (use_fates_hydrohard .or. use_fates_frosthard) then
this%temp24_patch(bounds%begp:bounds%endp) = spval
call init_accum_field (name='TEMP24', units='K', &
desc='24hr average temperature', accum_type='timeavg', accum_period=-1, &
subgrid_type='pft', numlev=1, init_value=0.0_r8)

this%t_mean_5yr_patch(bounds%begp:bounds%endp) = spval
call init_accum_field (name='THARD5', units='K', &
desc='5 year average of yearly min 2-m temperature for hardening', accum_type='runmean', accum_period=-5, &
subgrid_type='pft', numlev=1, init_value=0.0_r8)

endif

Expand All @@ -741,6 +779,7 @@ subroutine InitAccVars(this, bounds)
! !USES
use accumulMod , only : extract_accum_field
use clm_time_manager , only : get_nstep
use clm_varctl , only : nsrest, nsrStartup
!
! !ARGUMENTS:
class(atm2lnd_type) :: this
Expand Down Expand Up @@ -810,6 +849,20 @@ subroutine InitAccVars(this, bounds)

endif

if (use_fates_hydrohard .or. use_fates_frosthard) then
call extract_accum_field ('TEMP24', rbufslp, nstep)
this%temp24_patch(begp:endp) = rbufslp(begp:endp)

call extract_accum_field ('THARD5', rbufslp, nstep)
this%t_mean_5yr_patch(begp:endp) = rbufslp(begp:endp)

if (nsrest == nsrStartup) then
this%t_min_yr_patch(begp:endp) = spval
this%tmin24_patch(begp:endp) = spval
this%t_min_yr_inst_patch(begp:endp) = spval
end if
end if

deallocate(rbufslp)
deallocate(rbufslc)

Expand All @@ -819,7 +872,8 @@ end subroutine InitAccVars
subroutine UpdateAccVars (this, bounds)
!
! USES
use clm_time_manager, only : get_nstep
use clm_time_manager, only : get_nstep,get_step_size
use clm_time_manager, only : is_end_curr_year,is_end_curr_day,get_curr_date
use accumulMod , only : update_accum_field, extract_accum_field
!
! !ARGUMENTS:
Expand All @@ -831,16 +885,23 @@ subroutine UpdateAccVars (this, bounds)
integer :: dtime ! timestep size [seconds]
integer :: nstep ! timestep number
integer :: ier ! error status
integer :: year ! year (0, ...) for nstep
integer :: month ! month (1, ..., 12) for nstep
integer :: day ! day of month (1, ..., 31) for nstep
integer :: secs ! seconds into current date for nstep
integer :: begp, endp
integer :: begc, endc
real(r8), pointer :: rbufslp(:) ! temporary single level - patch level
real(r8), pointer :: rbufslc(:) ! temporary single level - column level
logical :: end_cd ! temporary for is_end_curr_day() value
logical :: end_yr ! temporary for is_end_curr_year() value
!---------------------------------------------------------------------

begp = bounds%begp; endp = bounds%endp
begc = bounds%begc; endc = bounds%endc

dtime = get_step_size()
nstep = get_nstep()
call get_curr_date (year, month, day, secs)

! Allocate needed dynamic memory for single level patch field
allocate(rbufslp(begp:endp), stat=ier)
Expand Down Expand Up @@ -876,6 +937,48 @@ subroutine UpdateAccVars (this, bounds)
call extract_accum_field ('FSI240', this%fsi240_patch , nstep)


if (use_fates_hydrohard .or. use_fates_frosthard) then
do p = begp,endp
c = patch%column(p)
rbufslp(p) = this%forc_t_downscaled_col(c)
end do
call update_accum_field ('TEMP24' , rbufslp , nstep)
call extract_accum_field ('TEMP24' , this%temp24_patch , nstep)
end_cd = is_end_curr_day()
do p = begp,endp
if (rbufslp(p) /= spval) then
this%tmin24_inst_patch(p) = min(rbufslp(p), this%tmin24_inst_patch(p))
endif
if (end_cd) then
this%tmin24_patch(p) = this%tmin24_inst_patch(p)
this%tmin24_inst_patch(p) = spval
else if (secs == dtime) then
this%tmin24_patch(p) = spval
endif
end do
do p = begp,endp
this%temp24_patch(p) = rbufslp(p)
end do
! Start 1 year minimum temperature loop for hardening
end_yr = is_end_curr_year()
do p = begp,endp
if (rbufslp(p) /= spval) then
this%t_min_yr_inst_patch(p) = min(rbufslp(p), this%t_min_yr_inst_patch(p))
endif
if (end_yr) then
this%t_min_yr_patch(p) = this%t_min_yr_inst_patch(p)
rbufslp(p)=this%t_min_yr_inst_patch(p)
this%t_min_yr_inst_patch(p) = spval
else if (secs == dtime) then
this%t_min_yr_patch(p) = spval
endif
end do
if (end_yr) then
call update_accum_field ('THARD5', rbufslp, nstep)
call extract_accum_field ('THARD5', this%t_mean_5yr_patch, nstep)
end if
endif

if (use_cndv) then

! Accumulate and extract TDA (accumulates TBOT as 30-day average) and
Expand Down Expand Up @@ -968,6 +1071,21 @@ subroutine Restart(this, bounds, ncid, flag)
interpinic_flag='interp', readvar=readvar, data=this%forc_pbot240_downscaled_patch )
endif

if (use_fates_hydrohard .or. use_fates_frosthard) then
call restartvar(ncid=ncid, flag=flag, varname='THARD5', xtype=ncd_double, &
dim1name='pft', &
long_name='5 year average of min yearly 2-m temperature for hardening', units='K', &
interpinic_flag='interp', readvar=readvar, data=this%t_mean_5yr_patch)
call restartvar(ncid=ncid, flag=flag, varname='T1yrinst', xtype=ncd_double, &
dim1name='pft', &
long_name='instantenious 1yr min temperature', units='K', &
interpinic_flag='interp', readvar=readvar, data=this%t_min_yr_inst_patch)
call restartvar(ncid=ncid, flag=flag, varname='TEMP24', xtype=ncd_double, &
dim1name='pft', &
long_name='24h average temperature', units='K', &
interpinic_flag='interp', readvar=readvar, data=this%temp24_patch)
end if

end subroutine Restart

!-----------------------------------------------------------------------
Expand Down Expand Up @@ -1027,6 +1145,14 @@ subroutine Clean(this)
deallocate(this%fsi240_patch)
if (use_fates) then
deallocate(this%wind24_patch)
if (use_fates_hydrohard .or. use_fates_frosthard) then
deallocate(this%temp24_patch)
deallocate(this%tmin24_patch)
deallocate(this%tmin24_inst_patch)
deallocate(this%t_mean_5yr_patch)
deallocate(this%t_min_yr_inst_patch)
deallocate(this%t_min_yr_patch)
end if
end if
deallocate(this%t_mo_patch)
deallocate(this%t_mo_min_patch)
Expand Down
2 changes: 2 additions & 0 deletions src/main/clm_varctl.F90
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,8 @@ module clm_varctl
logical, public :: use_fates_tree_damage = .false. ! true => turn on tree damage module
logical, public :: use_fates_logging = .false. ! true => turn on logging module
logical, public :: use_fates_planthydro = .false. ! true => turn on fates hydro
logical, public :: use_fates_hydrohard = .false. ! true => turn on fates hydrohard
logical, public :: use_fates_frosthard = .false. ! true => turn on fates frosthard
logical, public :: use_fates_cohort_age_tracking = .false. ! true => turn on cohort age tracking
logical, public :: use_fates_ed_st3 = .false. ! true => static stand structure
logical, public :: use_fates_ed_prescribed_phys = .false. ! true => prescribed physiology
Expand Down
7 changes: 6 additions & 1 deletion src/main/controlMod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,8 @@ subroutine control_init(dtime)
use_fates_sp, &
fates_inventory_ctrl_filename, &
fates_parteh_mode, &
use_fates_tree_damage
use_fates_tree_damage, &
use_fates_hydrohard,use_fates_frosthard

! Ozone vegetation stress method
namelist / clm_inparam / o3_veg_stress_method
Expand Down Expand Up @@ -706,6 +707,8 @@ subroutine control_spmd()
call mpi_bcast (fates_spitfire_mode, 1, MPI_INTEGER, 0, mpicom, ier)
call mpi_bcast (use_fates_logging, 1, MPI_LOGICAL, 0, mpicom, ier)
call mpi_bcast (use_fates_planthydro, 1, MPI_LOGICAL, 0, mpicom, ier)
call mpi_bcast (use_fates_hydrohard, 1, MPI_LOGICAL, 0, mpicom, ier)
call mpi_bcast (use_fates_frosthard, 1, MPI_LOGICAL, 0, mpicom, ier)
call mpi_bcast (use_fates_tree_damage, 1, MPI_LOGICAL, 0, mpicom, ier)
call mpi_bcast (use_fates_cohort_age_tracking, 1, MPI_LOGICAL, 0, mpicom, ier)
call mpi_bcast (use_fates_ed_st3, 1, MPI_LOGICAL, 0, mpicom, ier)
Expand Down Expand Up @@ -1050,6 +1053,8 @@ subroutine control_print ()
write(iulog, *) ' fates_paramfile = ', fates_paramfile
write(iulog, *) ' fates_parteh_mode = ', fates_parteh_mode
write(iulog, *) ' use_fates_planthydro = ', use_fates_planthydro
write(iulog, *) ' use_fates_hydrohard = ', use_fates_hydrohard
write(iulog, *) ' use_fates_frosthard = ', use_fates_frosthard
write(iulog, *) ' use_fates_tree_damage = ', use_fates_tree_damage
write(iulog, *) ' use_fates_cohort_age_tracking = ', use_fates_cohort_age_tracking
write(iulog, *) ' use_fates_ed_st3 = ',use_fates_ed_st3
Expand Down
35 changes: 35 additions & 0 deletions src/utils/clmfates_interfaceMod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ module CLMFatesInterfaceMod
use clm_varctl , only : fates_spitfire_mode
use clm_varctl , only : use_fates_tree_damage
use clm_varctl , only : use_fates_planthydro
use clm_varctl , only : use_fates_hydrohard
use clm_varctl , only : use_fates_frosthard
use clm_varctl , only : use_fates_cohort_age_tracking
use clm_varctl , only : use_fates_ed_st3
use clm_varctl , only : use_fates_ed_prescribed_phys
Expand Down Expand Up @@ -349,6 +351,8 @@ subroutine CLMFatesGlobals2()
integer :: pass_logging
integer :: pass_ed_prescribed_phys
integer :: pass_planthydro
integer :: pass_hydrohard
integer :: pass_frosthard
integer :: pass_inventory_init
integer :: pass_is_restart
integer :: pass_cohort_age_tracking
Expand Down Expand Up @@ -463,6 +467,20 @@ subroutine CLMFatesGlobals2()
pass_planthydro = 0
end if
call set_fates_ctrlparms('use_planthydro',ival=pass_planthydro)

if(use_fates_hydrohard) then
pass_hydrohard = 1
else
pass_hydrohard = 0
end if
call set_fates_ctrlparms('use_hydrohard',ival=pass_hydrohard)

if(use_fates_frosthard) then
pass_frosthard = 1
else
pass_frosthard = 0
end if
call set_fates_ctrlparms('use_frosthard',ival=pass_frosthard)

if(use_fates_cohort_age_tracking) then
pass_cohort_age_tracking = 1
Expand Down Expand Up @@ -974,6 +992,23 @@ subroutine dynamics_driv(this, nc, bounds_clump, &
this%fates(nc)%bc_in(s)%h2o_liq_sisl(1:nlevsoil) = waterstatebulk_inst%h2osoi_liq_col(c,1:nlevsoil)
end if

if (use_fates_hydrohard .or. use_fates_frosthard) then
this%fates(nc)%bc_in(s)%temp24_si = &
atm2lnd_inst%temp24_patch(col%patchi(c))

this%fates(nc)%bc_in(s)%t_mean_5yr_si = &
atm2lnd_inst%t_mean_5yr_patch(col%patchi(c))

this%fates(nc)%bc_in(s)%t_min_yr_inst_si = &
atm2lnd_inst%t_min_yr_inst_patch(col%patchi(c))

this%fates(nc)%bc_in(s)%tmin24_si = &
atm2lnd_inst%tmin24_patch(col%patchi(c))

this%fates(nc)%bc_in(s)%dayl_si = grc%dayl(col%gridcell(c))
this%fates(nc)%bc_in(s)%prev_dayl_si = grc%prev_dayl(col%gridcell(c))
endif

! get the harvest data, which is by gridcell
! for now there is one veg column per gridcell, so store all harvest data in each site
! this will eventually change
Expand Down