Skip to content

Commit

Permalink
Merge remote-tracking branch 'rgknox/rgknox/lnd/fates-cnp-lambda'(PR E…
Browse files Browse the repository at this point in the history
…3SM-Project#6222)

This implements a fix to the FATES phosphatase dynamics in the capacitance based formulation.
This had previously been using an uninitialized critical value for phosphatse concentrations.
An updated scheme has been applied that does not use the critical value (lambda).
Also, a history diagnostic that tracks the number of iterations necessary for the land-surface energy solve was added.

Fixes E3SM-Project#6186
[non-BFB] fates eca
  • Loading branch information
peterdschwartz committed Mar 15, 2024
2 parents 93e511d + b211e59 commit bfe354e
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 16 deletions.
9 changes: 8 additions & 1 deletion components/elm/bld/namelist_files/namelist_defaults.xml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,14 @@ attributes from the config_cache.xml file (with keys converted to upper-case).

<!-- Supplmental Nitrogen mode -->
<suplnitro use_cn=".true." >NONE</suplnitro>
<suplnitro use_fates=".true." >NONE</suplnitro>

<!-- Supplemental N and P for FATES -->
<!-- With c-only FATES, don't want partial N and P dynamics -->
<!-- this is also true at different phases of spin-up -->
<!-- so more cases than not, FATES wants supplemented N and P -->
<suplnitro use_fates=".true." >ALL</suplnitro>
<suplphos use_fates=".true." >ALL</suplphos>


<!-- Nutrient competition pathway -->
<nu_com>RD</nu_com>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ fates_parteh_mode = 2
use_lch4 = .true.
fates_spitfire_mode = 1
hist_empty_htapes = .true.
suplphos = 'NONE'
suplnitro = 'NONE'
hist_fincl1 = 'FATES_NCOHORTS', 'FATES_TRIMMING', 'FATES_AREA_PLANTS',
'FATES_AREA_TREES', 'FATES_COLD_STATUS', 'FATES_GDD',
'FATES_NCHILLDAYS', 'FATES_NCOLDDAYS', 'FATES_DAYSINCE_COLDLEAFOFF',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ fates_parteh_mode = 2
use_lch4 = .true.
fates_spitfire_mode = 1
hist_empty_htapes = .true.
suplphos = 'NONE'
suplnitro = 'NONE'
hist_fincl1 = 'FATES_NCOHORTS', 'FATES_TRIMMING', 'FATES_AREA_PLANTS',
'FATES_AREA_TREES', 'FATES_COLD_STATUS', 'FATES_GDD',
'FATES_NCHILLDAYS', 'FATES_NCOLDDAYS', 'FATES_DAYSINCE_COLDLEAFOFF',
Expand Down
27 changes: 15 additions & 12 deletions components/elm/src/biogeochem/PhosphorusDynamicsMod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -605,8 +605,8 @@ subroutine PhosphorusBiochemMin_balance(bounds,num_soilc, filter_soilc, &
km_ptase => veg_vp%km_ptase , &
alpha_ptase => veg_vp%alpha_ptase , &
decomp_ppools_vr_col => col_ps%decomp_ppools_vr, &
lamda_ptase => veg_vp%lamda_ptase, &
! critical value of nitrogen cost of phosphatase activity induced phosphorus uptake
lamda_ptase => veg_vp%lamda_ptase , &
cn_scalar => cnstate_vars%cn_scalar , &
cp_scalar => cnstate_vars%cp_scalar , &
is_soil => decomp_cascade_con%is_soil)
Expand Down Expand Up @@ -639,28 +639,31 @@ subroutine PhosphorusBiochemMin_balance(bounds,num_soilc, filter_soilc, &

if(use_fates) then
do j = 1,nlevdecomp
do p = 1, alm_fates%fates(ci)%bc_out(s)%num_plant_comps

lamda_up = alm_fates%fates(ci)%bc_out(s)%cp_scalar(p)/ &
max(alm_fates%fates(ci)%bc_out(s)%cn_scalar(p),1e-20_r8)
lamda_up = min(max(lamda_up,0.0_r8), 150.0_r8)
do p = 1, alm_fates%fates(ci)%bc_out(s)%num_plant_comps

pft = alm_fates%fates(ci)%bc_out(s)%ft_index(p)

fr_frac = alm_fates%fates(ci)%bc_out(s)%veg_rootc(p,j) / &
sum(alm_fates%fates(ci)%bc_out(s)%veg_rootc(p,:))
sum(alm_fates%fates(ci)%bc_out(s)%veg_rootc(:,:))

! lamda is not used currently with fates, fates also does not
! scale by the cn_ and cp_scalars
! Also, we do not currently allow phosphatase released P
! to go directly to the plants in FATES. This implies as an alpha of 0.
! lamda_ptase = alm_fates%fates(ci)%bc_pconst%eca_lambda_ptase(pft)

pft = alm_fates%fates(ci)%bc_out(s)%ft_index(p)
ptase_tmp = alm_fates%fates(ci)%bc_pconst%eca_vmax_ptase(pft) * &
fr_frac * max(lamda_up - lamda_ptase, 0.0_r8) / &
( alm_fates%fates(ci)%bc_pconst%eca_km_ptase(pft) + &
max(lamda_up - alm_fates%fates(ci)%bc_pconst%eca_lambda_ptase(pft), 0.0_r8))
fr_frac/dzsoi_decomp(j) / ( alm_fates%fates(ci)%bc_pconst%eca_km_ptase(pft) + 1._r8)

biochem_pmin_to_plant_vr_patch(p,j) = ptase_tmp * alm_fates%fates(ci)%bc_pconst%eca_alpha_ptase(pft)
biochem_pmin_vr(c,j) = biochem_pmin_vr(c,j) + ptase_tmp*(1._r8 - alm_fates%fates(ci)%bc_pconst%eca_alpha_ptase(pft))
biochem_pmin_to_plant_vr_patch(p,j) = 0._r8
biochem_pmin_vr(c,j) = biochem_pmin_vr(c,j) + ptase_tmp !*(1._r8 - alm_fates%fates(ci)%bc_pconst%eca_alpha_ptase(pft))
biochem_pmin_to_ecosysp_vr_col_pot(c,j) = biochem_pmin_to_ecosysp_vr_col_pot(c,j) + ptase_tmp

end do
end do
else

do j = 1,nlevdecomp
do p = col_pp%pfti(c), col_pp%pftf(c)
if (veg_pp%active(p).and. (veg_pp%itype(p) .ne. noveg)) then
Expand Down
4 changes: 3 additions & 1 deletion components/elm/src/biogeophys/BareGroundFluxesMod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ subroutine BareGroundFluxes(bounds, num_nolakeurbanp, filter_nolakeurbanp, &
qflx_ev_h2osfc => veg_wf%qflx_ev_h2osfc , & ! Output: [real(r8) (:) ] evaporation flux from h2osfc (W/m**2) [+ to atm]
qflx_evap_soi => veg_wf%qflx_evap_soi , & ! Output: [real(r8) (:) ] soil evaporation (mm H2O/s) (+ = to atm)
qflx_evap_tot => veg_wf%qflx_evap_tot , & ! Output: [real(r8) (:) ] qflx_evap_soi + qflx_evap_can + qflx_tran_veg
num_iter => frictionvel_vars%num_iter_patch , & ! Output: number of iterations required
begp => bounds%begp , &
endp => bounds%endp &
)
Expand Down Expand Up @@ -252,7 +253,7 @@ subroutine BareGroundFluxes(bounds, num_nolakeurbanp, filter_nolakeurbanp, &
! Initialize Monin-Obukhov length and wind speed

call MoninObukIni(ur(p), thv(c), dthv, zldis(p), z0mg_patch(p), um(p), obu(p))

num_iter(p) = 0._r8
end do

! Perform stability iteration
Expand Down Expand Up @@ -322,6 +323,7 @@ subroutine BareGroundFluxes(bounds, num_nolakeurbanp, filter_nolakeurbanp, &
fn = 0
do f = 1, fnold
p = filterp(f)
num_iter(p) = real(iter,r8)
if (.not. (abs(tau_diff(p)) < dtaumin)) then
fn = fn + 1
filterp(fn) = p
Expand Down
5 changes: 4 additions & 1 deletion components/elm/src/biogeophys/CanopyFluxesMod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,7 @@ subroutine CanopyFluxes(bounds, num_nolakeurbanp, filter_nolakeurbanp, &
z0hv => frictionvel_vars%z0hv_patch , & ! Output: [real(r8) (:) ] roughness length over vegetation, sensible heat [m]
z0qv => frictionvel_vars%z0qv_patch , & ! Output: [real(r8) (:) ] roughness length over vegetation, latent heat [m]
rb1 => frictionvel_vars%rb1_patch , & ! Output: [real(r8) (:) ] boundary layer resistance (s/m)
num_iter => frictionvel_vars%num_iter_patch , & ! Output: number of iterations required

t_h2osfc => col_es%t_h2osfc , & ! Input: [real(r8) (:) ] surface water temperature
t_soisno => col_es%t_soisno , & ! Input: [real(r8) (:,:) ] soil temperature (Kelvin)
Expand Down Expand Up @@ -749,7 +750,8 @@ subroutine CanopyFluxes(bounds, num_nolakeurbanp, filter_nolakeurbanp, &
! Initialize Monin-Obukhov length and wind speed

call MoninObukIni(ur(p), thv(c), dthv(p), zldis(p), z0mv(p), um(p), obu(p))

num_iter(p) = 0._r8

end do

! Set counter for leaf temperature iteration (itlef)
Expand Down Expand Up @@ -1157,6 +1159,7 @@ subroutine CanopyFluxes(bounds, num_nolakeurbanp, filter_nolakeurbanp, &
dele(p) = abs(efe(p)-efeb(p))
efeb(p) = efe(p)
det(p) = max(del(p),del2(p))
num_iter(p) = real(itlef,r8)
end do
fnold = fn
fn = 0
Expand Down
10 changes: 9 additions & 1 deletion components/elm/src/biogeophys/FrictionVelocityType.F90
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ module FrictionVelocityType
real(r8), pointer :: z0mg_col (:) ! col roughness length over ground, momentum [m]
real(r8), pointer :: z0hg_col (:) ! col roughness length over ground, sensible heat [m]
real(r8), pointer :: z0qg_col (:) ! col roughness length over ground, latent heat [m]

real(r8), pointer :: num_iter_patch (:) ! number of iterations performed to find a solution
! to the land-energy flux balance in CanopyFluxes()

contains

procedure, public :: Init
Expand Down Expand Up @@ -102,6 +104,7 @@ subroutine InitAllocate(this, bounds)
allocate(this%z0mv_patch (begp:endp)) ; this%z0mv_patch (:) = spval
allocate(this%z0hv_patch (begp:endp)) ; this%z0hv_patch (:) = spval
allocate(this%z0qv_patch (begp:endp)) ; this%z0qv_patch (:) = spval
allocate(this%num_iter_patch (begp:endp)) ; this%num_iter_patch (:) = spval
allocate(this%z0mg_col (begc:endc)) ; this%z0mg_col (:) = spval
allocate(this%z0qg_col (begc:endc)) ; this%z0qg_col (:) = spval
allocate(this%z0hg_col (begc:endc)) ; this%z0hg_col (:) = spval
Expand Down Expand Up @@ -209,6 +212,11 @@ subroutine InitHistory(this, bounds)
ptr_patch=this%z0qv_patch, default='inactive')
end if

this%num_iter_patch(begp:endp) = spval
call hist_addfld1d(fname='ITER_LND_EBAL_AVG', units='count', &
avgflag='A', long_name='average number of iterations performed in land-energy balance', &
ptr_patch=this%num_iter_patch, default = 'inactive')

end subroutine InitHistory

!-----------------------------------------------------------------------
Expand Down

0 comments on commit bfe354e

Please sign in to comment.