Skip to content

Commit

Permalink
Add rhizome turnover
Browse files Browse the repository at this point in the history
  • Loading branch information
bsulman authored and fmyuan committed Jul 30, 2024
1 parent 358d5b0 commit 54dac66
Show file tree
Hide file tree
Showing 9 changed files with 139 additions and 5 deletions.
15 changes: 15 additions & 0 deletions components/elm/src/biogeochem/CarbonIsoFluxMod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,11 @@ subroutine CarbonIsoFlux1(num_soilc, filter_soilc, num_soilp, filter_soilp, &
isoveg_cf%livecrootc_to_deadcrootc , veg_cf%livecrootc_to_deadcrootc, &
isoveg_cs%livecrootc , veg_cs%livecrootc, &
num_soilp , filter_soilp, 1._r8, 0, isotope)

call CarbonIsoFluxCalc(&
isoveg_cf%livecrootc_to_litter , veg_cf%livecrootc_to_litter, &
isoveg_cs%livecrootc , veg_cs%livecrootc, &
num_soilp , filter_soilp, 1._r8, 0, isotope)

call CarbonIsoFluxCalc(&
isoveg_cf%leaf_curmr , veg_cf%leaf_curmr, &
Expand Down Expand Up @@ -937,9 +942,11 @@ subroutine CNCIsoLitterToColumn (num_soilc, filter_soilc, &

leaf_prof => cnstate_vars%leaf_prof_patch , & ! Input: [real(r8) (:,:) ] (1/m) profile of leaves
froot_prof => cnstate_vars%froot_prof_patch , & ! Input: [real(r8) (:,:) ] (1/m) profile of fine roots
croot_prof => cnstate_vars%croot_prof_patch , & ! Input: [real(r8) (:,:) ] (1/m) profile of coarse roots

leafc_to_litter => veg_cf%leafc_to_litter , & ! Input: [real(r8) (:) ]
frootc_to_litter => veg_cf%frootc_to_litter , & ! Input: [real(r8) (:) ]
livecrootc_to_litter => veg_cf%livecrootc_to_litter , & ! Input: [real(r8) (:) ]
phenology_c_to_litr_met_c => col_cf%phenology_c_to_litr_met_c , & ! InOut: [real(r8) (:,:) ] C fluxes associated with phenology (litterfall and crop) to litter metabolic pool (gC/m3/s)
phenology_c_to_litr_cel_c => col_cf%phenology_c_to_litr_cel_c , & ! InOut: [real(r8) (:,:) ] C fluxes associated with phenology (litterfall and crop) to litter cellulose pool (gC/m3/s)
phenology_c_to_litr_lig_c => col_cf%phenology_c_to_litr_lig_c & ! InOut: [real(r8) (:,:) ] C fluxes associated with phenology (litterfall and crop) to litter lignin pool (gC/m3/s)
Expand Down Expand Up @@ -968,6 +975,14 @@ subroutine CNCIsoLitterToColumn (num_soilc, filter_soilc, &
+ frootc_to_litter(p) * fr_fcel(ivt(p)) * wtcol(p) * froot_prof(p,j)
phenology_c_to_litr_lig_c(c,j) = phenology_c_to_litr_lig_c(c,j) &
+ frootc_to_litter(p) * fr_flig(ivt(p)) * wtcol(p) * froot_prof(p,j)

! nonwoody rhizome litter carbon fluxes
phenology_c_to_litr_met_c(c,j) = phenology_c_to_litr_met_c(c,j) &
+ livecrootc_to_litter(p) * fr_flab(ivt(p)) * wtcol(p) * croot_prof(p,j)
phenology_c_to_litr_cel_c(c,j) = phenology_c_to_litr_cel_c(c,j) &
+ livecrootc_to_litter(p) * fr_fcel(ivt(p)) * wtcol(p) * croot_prof(p,j)
phenology_c_to_litr_lig_c(c,j) = phenology_c_to_litr_lig_c(c,j) &
+ livecrootc_to_litter(p) * fr_flig(ivt(p)) * wtcol(p) * croot_prof(p,j)
end if
end if

Expand Down
2 changes: 2 additions & 0 deletions components/elm/src/biogeochem/CarbonStateUpdate1Mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,8 @@ subroutine CarbonStateUpdate1(bounds, &
veg_cs%deadstemc(p) = veg_cs%deadstemc(p) + veg_cf%livestemc_to_deadstemc(p)*dt
veg_cs%livecrootc(p) = veg_cs%livecrootc(p) - veg_cf%livecrootc_to_deadcrootc(p)*dt
veg_cs%deadcrootc(p) = veg_cs%deadcrootc(p) + veg_cf%livecrootc_to_deadcrootc(p)*dt
else ! nonwoody rhizome turnover (B Sulman)
veg_cs%livecrootc(p) = veg_cs%livecrootc(p) - veg_cf%livecrootc_to_litter(p)*dt
end if
if (ivt(p) >= npcropmin) then ! skip 2 generic crops
veg_cs%livestemc(p) = veg_cs%livestemc(p) - veg_cf%livestemc_to_litter(p)*dt
Expand Down
4 changes: 4 additions & 0 deletions components/elm/src/biogeochem/NitrogenStateUpdate1Mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,10 @@ subroutine NitrogenStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp
veg_ns%deadcrootn(p) = veg_ns%deadcrootn(p) + veg_nf%livecrootn_to_deadcrootn(p)*dt
veg_ns%livecrootn(p) = veg_ns%livecrootn(p) - veg_nf%livecrootn_to_retransn(p)*dt
veg_ns%retransn(p) = veg_ns%retransn(p) + veg_nf%livecrootn_to_retransn(p)*dt
else ! Nonwoody rhizome turnover (B Sulman)
veg_ns%livecrootn(p) = veg_ns%livecrootn(p) - veg_nf%livecrootn_to_litter(p)*dt
veg_ns%livecrootn(p) = veg_ns%livecrootn(p) - veg_nf%livecrootn_to_retransn(p)*dt
veg_ns%retransn(p) = veg_ns%retransn(p) + veg_nf%livecrootn_to_retransn(p)*dt
end if
if (ivt(p) >= npcropmin) then ! Beth adds retrans from froot
veg_ns%frootn(p) = veg_ns%frootn(p) - veg_nf%frootn_to_retransn(p)*dt
Expand Down
7 changes: 7 additions & 0 deletions components/elm/src/biogeochem/PhenologyFluxLimitMod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ module PhenologyFLuxLimitMod
integer :: f_livecrootc_xfer_to_livecrootc
integer :: f_livecrootc_storage_to_xfer
integer :: f_livecrootc_to_deadcrootc
integer :: f_livecrootc_to_litter
integer :: f_deadcrootc_xfer_to_deadcrootc
integer :: f_deadcrootc_storage_to_xfer
integer :: f_grainc_to_food
Expand Down Expand Up @@ -139,6 +140,7 @@ module PhenologyFLuxLimitMod
integer :: f_livecrootn_storage_to_xfer
integer :: f_livecrootn_xfer_to_livecrootn
integer :: f_livecrootn_to_deadcrootn
integer :: f_livecrootn_to_litter
integer :: f_livecrootn_to_retransn
integer :: f_deadstemn_storage_to_xfer
integer :: f_deadstemn_xfer_to_deadstem
Expand Down Expand Up @@ -264,6 +266,7 @@ subroutine init_phenofluxl_counters()
f_livecrootc_xfer_to_livecrootc= ic_next(id)
f_livecrootc_storage_to_xfer = ic_next(id)
f_livecrootc_to_deadcrootc = ic_next(id)
f_livecrootc_to_litter = ic_next(id)
f_deadcrootc_xfer_to_deadcrootc= ic_next(id)
f_deadcrootc_storage_to_xfer = ic_next(id)
f_grainc_to_food = ic_next(id)
Expand Down Expand Up @@ -329,6 +332,7 @@ subroutine init_phenofluxl_counters()
f_livestemn_to_retransn = ic_next(id)
f_livestemn_to_deadstemn = ic_next(id)
f_livecrootn_to_deadcrootn = ic_next(id)
f_livecrootn_to_litter = ic_next(id)
f_livecrootn_to_retransn = ic_next(id)
f_livecrootn_storage_to_xfer = ic_next(id)
f_livecrootn_xfer_to_livecrootn = ic_next(id)
Expand Down Expand Up @@ -387,6 +391,7 @@ subroutine InitPhenoFluxLimiter()
call spm_list_insert(spm_list, -1._r8, f_deadstemc_xfer_to_deadstemc , s_deadstemc_xfer, nelms)
call spm_list_insert(spm_list, -1._r8, f_deadstemc_storage_to_xfer , s_deadstemc_storage, nelms)
call spm_list_insert(spm_list, -1._r8, f_livecrootc_to_deadcrootc , s_livecrootc, nelms)
call spm_list_insert(spm_list, -1._r8, f_livecrootc_to_litter , s_livecrootc, nelms)
call spm_list_insert(spm_list, -1._r8, f_livecrootc_xfer_to_livecrootc, s_livecrootc_xfer, nelms)
call spm_list_insert(spm_list, -1._r8, f_livecrootc_storage_to_xfer , s_livecrootc_storage, nelms)
call spm_list_insert(spm_list, -1._r8, f_deadcrootc_xfer_to_deadcrootc, s_deadcrootc_xfer, nelms)
Expand Down Expand Up @@ -697,6 +702,7 @@ subroutine carbon_flux_limiter(bounds, num_soilc, filter_soilc,&
rfluxes(f_livecrootc_xfer_to_livecrootc)= veg_cf%livecrootc_xfer_to_livecrootc(p)
rfluxes(f_livecrootc_storage_to_xfer) = veg_cf%livecrootc_storage_to_xfer(p)
rfluxes(f_livecrootc_to_deadcrootc) = veg_cf%livecrootc_to_deadcrootc(p)
rfluxes(f_livecrootc_to_litter) = veg_cf%livecrootc_to_litter(p)
if (woody(ivt(p)) == 1._r8) then
rfluxes(f_cpool_to_livestemc) = veg_cf%cpool_to_livestemc(p)
rfluxes(f_cpool_to_livestemc_storage) = veg_cf%cpool_to_livestemc_storage(p)
Expand Down Expand Up @@ -750,6 +756,7 @@ subroutine carbon_flux_limiter(bounds, num_soilc, filter_soilc,&
call fpmax(rfluxes(f_livecrootc_xfer_to_livecrootc), veg_cf%livecrootc_xfer_to_livecrootc(p))
call fpmax(rfluxes(f_livecrootc_storage_to_xfer) , veg_cf%livecrootc_storage_to_xfer(p))
call fpmax(rfluxes(f_livecrootc_to_deadcrootc) , veg_cf%livecrootc_to_deadcrootc(p))
call fpmax(rfluxes(f_livecrootc_to_litter) , veg_cf%livecrootc_to_litter(p))

if (woody(ivt(p)) == 1._r8) then
call fpmax(rfluxes(f_cpool_to_livestemc) , veg_cf%cpool_to_livestemc(p))
Expand Down
58 changes: 57 additions & 1 deletion components/elm/src/biogeochem/PhenologyMod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -3416,6 +3416,8 @@ subroutine CNLivewoodTurnover (num_soilp, filter_soilp)
! Determines the flux of C and N from live wood to
! dead wood pools, for stem and coarse root.
! add phosphorus flux - X.YANG
use elm_varcon , only : secspday
use clm_time_manager , only : get_days_per_year
!
! !ARGUMENTS:
!$acc routine seq
Expand All @@ -3428,6 +3430,7 @@ subroutine CNLivewoodTurnover (num_soilp, filter_soilp)
real(r8):: ctovr ! temporary variable for carbon turnover
real(r8):: ntovr ! temporary variable for nitrogen turnover
real(r8):: ptovr ! temporary variable for phosphorus turnover
real(r8):: dayspyr ! days per year
!-----------------------------------------------------------------------

associate( &
Expand All @@ -3440,6 +3443,8 @@ subroutine CNLivewoodTurnover (num_soilp, filter_soilp)
livestemc => veg_cs%livestemc , & ! Input: [real(r8) (:) ] (gC/m2) live stem C
livecrootc => veg_cs%livecrootc , & ! Input: [real(r8) (:) ] (gC/m2) live coarse root C

rhizome_long => veg_vp%rhizome_long , & ! Input: [real(r8) (:) ] rhizome longevity (yrs)

livestemn => veg_ns%livestemn , & ! Input: [real(r8) (:) ] (gN/m2) live stem N
livecrootn => veg_ns%livecrootn , & ! Input: [real(r8) (:) ] (gN/m2) live coarse root N

Expand All @@ -3448,20 +3453,26 @@ subroutine CNLivewoodTurnover (num_soilp, filter_soilp)

livestemc_to_deadstemc => veg_cf%livestemc_to_deadstemc , & ! Output: [real(r8) (:) ]
livecrootc_to_deadcrootc => veg_cf%livecrootc_to_deadcrootc , & ! Output: [real(r8) (:) ]
livecrootc_to_litter => veg_cf%livecrootc_to_litter , & ! Output: [real(r8) (:) ]

livestemn_to_deadstemn => veg_nf%livestemn_to_deadstemn , & ! Output: [real(r8) (:) ]
livestemn_to_retransn => veg_nf%livestemn_to_retransn , & ! Output: [real(r8) (:) ]
livecrootn_to_deadcrootn => veg_nf%livecrootn_to_deadcrootn , & ! Output: [real(r8) (:) ]
livecrootn_to_retransn => veg_nf%livecrootn_to_retransn , & ! Output: [real(r8) (:) ]
livecrootn_to_litter => veg_nf%livecrootn_to_litter , & ! Output: [real(r8) (:) ]

livewdcp => veg_vp%livewdcp , & ! Input: [real(r8) (:) ] live wood (phloem and ray parenchyma) C:P (gC/gP)
deadwdcp => veg_vp%deadwdcp , & ! Input: [real(r8) (:) ] dead wood (xylem and heartwood) C:P (gC/gP)
livestemp_to_deadstemp => veg_pf%livestemp_to_deadstemp , & ! Output: [real(r8) (:) ]
livestemp_to_retransp => veg_pf%livestemp_to_retransp , & ! Output: [real(r8) (:) ]
livecrootp_to_deadcrootp => veg_pf%livecrootp_to_deadcrootp , & ! Output: [real(r8) (:) ]
livecrootp_to_retransp => veg_pf%livecrootp_to_retransp & ! Output: [real(r8) (:) ]
livecrootp_to_retransp => veg_pf%livecrootp_to_retransp , & ! Output: [real(r8) (:) ]
livecrootp_to_litter => veg_pf%livecrootp_to_litter & ! Output: [real(r8) (:) ]
)


dayspyr = get_days_per_year()

! patch loop
do fp = 1,num_soilp
p = filter_soilp(fp)
Expand Down Expand Up @@ -3520,6 +3531,20 @@ subroutine CNLivewoodTurnover (num_soilp, filter_soilp)
livecrootp_to_retransp(p) = ptovr - livecrootp_to_deadcrootp(p)
end if

else ! If not woody, do rhizome turnover
if ( nu_com .eq. 'RD') then
ctovr = livecrootc(p) / (rhizome_long(ivt(p))*dayspyr*secspday)
ntovr = ctovr / livewdcn(ivt(p))
ptovr = ctovr / livewdcp(ivt(p))

livecrootc_to_litter(p) = ctovr
livecrootn_to_litter(p) = ntovr ! This assumes no retranslocation
livecrootn_to_retransn(p) = 0.0_r8

livecrootp_to_litter(p) = ptovr
livecrootp_to_retransp(p) = 0.0_r8

end if
end if

end do
Expand Down Expand Up @@ -3564,16 +3589,19 @@ subroutine CNLitterToColumn (num_soilp, filter_soilp, &

leaf_prof => cnstate_vars%leaf_prof_patch , & ! Input: [real(r8) (:,:) ] (1/m) profile of leaves
froot_prof => cnstate_vars%froot_prof_patch , & ! Input: [real(r8) (:,:) ] (1/m) profile of fine roots
croot_prof => cnstate_vars%croot_prof_patch , & ! Input: [real(r8) (:,:) ] (1/m) profile of coarse roots

leafc_to_litter => veg_cf%leafc_to_litter , & ! Input: [real(r8) (:) ] leaf C litterfall (gC/m2/s)
frootc_to_litter => veg_cf%frootc_to_litter , & ! Input: [real(r8) (:) ] fine root N litterfall (gN/m2/s)
livestemc_to_litter => veg_cf%livestemc_to_litter , & ! Input: [real(r8) (:) ] live stem C litterfall (gC/m2/s)
livecrootc_to_litter => veg_cf%livecrootc_to_litter , & ! Input: [real(r8) (:) ] live coarse root/rhizome C litterfall (gC/m2/s)
! grainc_to_food => veg_cf%grainc_to_food , & ! Input: [real(r8) (:) ] grain C to food (gC/m2/s)
phenology_c_to_litr_met_c => col_cf%phenology_c_to_litr_met_c , & ! Output: [real(r8) (:,:) ] C fluxes associated with phenology (litterfall and crop) to litter metabolic pool (gC/m3/s)
phenology_c_to_litr_cel_c => col_cf%phenology_c_to_litr_cel_c , & ! Output: [real(r8) (:,:) ] C fluxes associated with phenology (litterfall and crop) to litter cellulose pool (gC/m3/s)
phenology_c_to_litr_lig_c => col_cf%phenology_c_to_litr_lig_c , & ! Output: [real(r8) (:,:) ] C fluxes associated with phenology (litterfall and crop) to litter lignin pool (gC/m3/s)

livestemn_to_litter => veg_nf%livestemn_to_litter , & ! Input: [real(r8) (:) ] livestem N to litter (gN/m2/s)
livecrootn_to_litter => veg_nf%livecrootn_to_litter , & ! Input: [real(r8) (:) ] livecroot/rhizome N to litter (gN/m2/s)
! grainn_to_food => veg_nf%grainn_to_food , & ! Input: [real(r8) (:) ] grain N to food (gN/m2/s)
leafn_to_litter => veg_nf%leafn_to_litter , & ! Input: [real(r8) (:) ] leaf N litterfall (gN/m2/s)
frootn_to_litter => veg_nf%frootn_to_litter , & ! Input: [real(r8) (:) ] fine root N litterfall (gN/m2/s)
Expand All @@ -3582,6 +3610,7 @@ subroutine CNLitterToColumn (num_soilp, filter_soilp, &
phenology_n_to_litr_lig_n => col_nf%phenology_n_to_litr_lig_n , & ! Output: [real(r8) (:,:) ] N fluxes associated with phenology (litterfall and crop) to litter lignin pool (gN/m3/s)

livestemp_to_litter => veg_pf%livestemp_to_litter , & ! Input: [real(r8) (:) ] livestem P to litter (gP/m2/s)
livecrootp_to_litter => veg_pf%livecrootp_to_litter , & ! Input: [real(r8) (:) ] livecroot/rhizome P to litter (gP/m2/s)
! grainp_to_food => veg_pf%grainp_to_food , & ! Input: [real(r8) (:) ] grain P to food (gP/m2/s)
leafp_to_litter => veg_pf%leafp_to_litter , & ! Input: [real(r8) (:) ] leaf P litterfall (gP/m2/s)
frootp_to_litter => veg_pf%frootp_to_litter , & ! Input: [real(r8) (:) ] fine root P litterfall (gP/m2/s)
Expand Down Expand Up @@ -3644,6 +3673,33 @@ subroutine CNLitterToColumn (num_soilp, filter_soilp, &
phenology_p_to_litr_lig_p(c,j) = phenology_p_to_litr_lig_p(c,j) &
+ frootp_to_litter(p) * fr_flig(ivt(p)) * wt_col * froot_prof(p,j)


! Rhizome litter carbon fluxes. Assume similar to fine roots (B Sulman)
phenology_c_to_litr_met_c(c,j) = phenology_c_to_litr_met_c(c,j) &
+ livecrootc_to_litter(p) * fr_flab(ivt(p)) * wtcol(p) * croot_prof(p,j)
phenology_c_to_litr_cel_c(c,j) = phenology_c_to_litr_cel_c(c,j) &
+ livecrootc_to_litter(p) * fr_fcel(ivt(p)) * wtcol(p) * croot_prof(p,j)
phenology_c_to_litr_lig_c(c,j) = phenology_c_to_litr_lig_c(c,j) &
+ livecrootc_to_litter(p) * fr_flig(ivt(p)) * wtcol(p) * croot_prof(p,j)

! fine root litter nitrogen fluxes
phenology_n_to_litr_met_n(c,j) = phenology_n_to_litr_met_n(c,j) &
+ livecrootn_to_litter(p) * fr_flab(ivt(p)) * wtcol(p) * croot_prof(p,j)
phenology_n_to_litr_cel_n(c,j) = phenology_n_to_litr_cel_n(c,j) &
+ livecrootn_to_litter(p) * fr_fcel(ivt(p)) * wtcol(p) * croot_prof(p,j)
phenology_n_to_litr_lig_n(c,j) = phenology_n_to_litr_lig_n(c,j) &
+ livecrootn_to_litter(p) * fr_flig(ivt(p)) * wtcol(p) * croot_prof(p,j)

! fine root litter phosphorus fluxes
phenology_p_to_litr_met_p(c,j) = phenology_p_to_litr_met_p(c,j) &
+ livecrootp_to_litter(p) * fr_flab(ivt(p)) * wtcol(p) * croot_prof(p,j)
phenology_p_to_litr_cel_p(c,j) = phenology_p_to_litr_cel_p(c,j) &
+ livecrootp_to_litter(p) * fr_fcel(ivt(p)) * wtcol(p) * croot_prof(p,j)
phenology_p_to_litr_lig_p(c,j) = phenology_p_to_litr_lig_p(c,j) &
+ livecrootp_to_litter(p) * fr_flig(ivt(p)) * wtcol(p) * croot_prof(p,j)



! agroibis puts crop stem litter together with leaf litter
! so I've used the leaf lf_f* parameters instead of making
! new ones for now (slevis)
Expand Down
6 changes: 5 additions & 1 deletion components/elm/src/biogeochem/PhosphorusStateUpdate1Mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,11 @@ subroutine PhosphorusStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soi
veg_ps%deadcrootp(p) = veg_ps%deadcrootp(p) + veg_pf%livecrootp_to_deadcrootp(p)*dt
veg_ps%livecrootp(p) = veg_ps%livecrootp(p) - veg_pf%livecrootp_to_retransp(p)*dt
veg_ps%retransp(p) = veg_ps%retransp(p) + veg_pf%livecrootp_to_retransp(p)*dt
end if
else ! Nonwoody rhizome turnover (B Sulman)
veg_ps%livecrootp(p) = veg_ps%livecrootp(p) - veg_pf%livecrootp_to_litter(p)*dt
veg_ps%livecrootp(p) = veg_ps%livecrootp(p) - veg_pf%livecrootp_to_retransp(p)*dt
veg_ps%retransp(p) = veg_ps%retransp(p) + veg_pf%livecrootp_to_retransp(p)*dt
end if
if (ivt(p) >= npcropmin) then ! Beth adds retrans from froot
veg_ps%frootp(p) = veg_ps%frootp(p) - veg_pf%frootp_to_retransp(p)*dt
veg_ps%retransp(p) = veg_ps%retransp(p) + veg_pf%frootp_to_retransp(p)*dt
Expand Down
Loading

0 comments on commit 54dac66

Please sign in to comment.