From 0d6527dd24a68579dd3d6c0263bba7ec6dfad2d7 Mon Sep 17 00:00:00 2001 From: ZacharyRobbins Date: Tue, 16 Aug 2022 09:50:05 -0600 Subject: [PATCH] Grass PFT only creates leaves not cwd In response to issue #884 Modified EDCohortDynamicsMod.F90 (@ln970): if the pft is grass then all of its organs are treated as leaves for calculation of coarse woody debris(cwd). EDPatchDynamicsMod.F90 (@ln 1641): When patches spawn, only tree pft donate dead tress or cwd, and mass to the new patch, if pft is grass it assumed that grass was consumed in fire. This may not resolve fluxes to the atmosphere accurately. EDPhysiologyMod.F90 (@ln 2199): When other litter fluxes occur, if pft is grass, then it only turnsover or contributes leaves not coarse woody debris. --- biogeochem/EDCohortDynamicsMod.F90 | 26 ++++++++++---- biogeochem/EDPatchDynamicsMod.F90 | 33 +++++++++--------- biogeochem/EDPhysiologyMod.F90 | 54 +++++++++++++++++++++--------- 3 files changed, 76 insertions(+), 37 deletions(-) diff --git a/biogeochem/EDCohortDynamicsMod.F90 b/biogeochem/EDCohortDynamicsMod.F90 index 4948f68129..957c3847ae 100644 --- a/biogeochem/EDCohortDynamicsMod.F90 +++ b/biogeochem/EDCohortDynamicsMod.F90 @@ -967,12 +967,26 @@ subroutine SendCohortToLitter(csite,cpatch,ccohort,nplant,bc_in) do el=1,num_elements - leaf_m = ccohort%prt%GetState(leaf_organ, element_list(el)) - store_m = ccohort%prt%GetState(store_organ, element_list(el)) - sapw_m = ccohort%prt%GetState(sapw_organ, element_list(el)) - fnrt_m = ccohort%prt%GetState(fnrt_organ, element_list(el)) - struct_m = ccohort%prt%GetState(struct_organ, element_list(el)) - repro_m = ccohort%prt%GetState(repro_organ, element_list(el)) + if ( prt_params%woody(pft) == itrue) then !trees only + leaf_m = ccohort%prt%GetState(leaf_organ, element_list(el)) + store_m = ccohort%prt%GetState(store_organ, element_list(el)) + sapw_m = ccohort%prt%GetState(sapw_organ, element_list(el)) + fnrt_m = ccohort%prt%GetState(fnrt_organ, element_list(el)) + struct_m = ccohort%prt%GetState(struct_organ, element_list(el)) + repro_m = ccohort%prt%GetState(repro_organ, element_list(el)) + else + leaf_m = ccohort%prt%GetState(leaf_organ, element_list(el))+ & + ccohort%prt%GetState(store_organ, element_list(el))+ & + ccohort%prt%GetState(sapw_organ, element_list(el))+ & + ccohort%prt%GetState(fnrt_organ, element_list(el))+ & + ccohort%prt%GetState(struct_organ, element_list(el))+ & + ccohort%prt%GetState(repro_organ, element_list(el)) + store_m = 0_r8 + sapw_m = 0_r8 + fnrt_m = 0_r8 + struct_m = 0_r8 + repro_m = 0_r8 + end if litt => cpatch%litter(el) flux_diags => csite%flux_diags(el) diff --git a/biogeochem/EDPatchDynamicsMod.F90 b/biogeochem/EDPatchDynamicsMod.F90 index d1c9a79b3d..dc4ef3d989 100644 --- a/biogeochem/EDPatchDynamicsMod.F90 +++ b/biogeochem/EDPatchDynamicsMod.F90 @@ -1637,13 +1637,17 @@ subroutine fire_litter_fluxes(currentSite, currentPatch, & ! across ground surface. ! ----------------------------------------------------------------------- - sapw_m = currentCohort%prt%GetState(sapw_organ, element_id) - struct_m = currentCohort%prt%GetState(struct_organ, element_id) - leaf_m = currentCohort%prt%GetState(leaf_organ, element_id) - fnrt_m = currentCohort%prt%GetState(fnrt_organ, element_id) - store_m = currentCohort%prt%GetState(store_organ, element_id) - repro_m = currentCohort%prt%GetState(repro_organ, element_id) - + if ( prt_params%woody(pft) == itrue) then !trees only, May require additional accounting for the atm_fluxes when PFT is grass. + ! Goal was to not add to pools in the event of grass fire. Grass would typically not introduce a flux of dead leaves + ! or coarse woody debris. This may be too coarse a solution in the long term. + leaf_m = currentCohort%prt%GetState(leaf_organ, element_list(el)) + store_m = currentCohort%prt%GetState(store_organ, element_list(el)) + sapw_m = currentCohort%prt%GetState(sapw_organ, element_list(el)) + fnrt_m = currentCohort%prt%GetState(fnrt_organ, element_list(el)) + struct_m = currentCohort%prt%GetState(struct_organ, element_list(el)) + repro_m = currentCohort%prt%GetState(repro_organ, element_list(el)) + + ! Absolute number of dead trees being transfered in with the donated area num_dead_trees = (currentCohort%fire_mort*currentCohort%n * & patch_site_areadis/currentPatch%area) @@ -1654,7 +1658,7 @@ subroutine fire_litter_fluxes(currentSite, currentPatch, & ! Contribution of dead trees to leaf burn-flux burned_mass = num_dead_trees * (leaf_m+repro_m) * currentCohort%fraction_crown_burned - + do dcmpy=1,ndcmpy dcmpy_frac = GetDecompyFrac(pft,leaf_organ,dcmpy) new_litt%leaf_fines(dcmpy) = new_litt%leaf_fines(dcmpy) + & @@ -1667,9 +1671,7 @@ subroutine fire_litter_fluxes(currentSite, currentPatch, & call set_root_fraction(currentSite%rootfrac_scr, pft, currentSite%zi_soil, & bc_in%max_rooting_depth_index_col) - - ! Contribution of dead trees to root litter (no root burn flux to atm) - do dcmpy=1,ndcmpy + do dcmpy=1,ndcmpy dcmpy_frac = GetDecompyFrac(pft,fnrt_organ,dcmpy) do sl = 1,currentSite%nlevsoil donatable_mass = num_dead_trees * (fnrt_m+store_m) * currentSite%rootfrac_scr(sl) @@ -1688,10 +1690,10 @@ subroutine fire_litter_fluxes(currentSite, currentPatch, & flux_diags%root_litter_input(pft) = & flux_diags%root_litter_input(pft) + & (fnrt_m + store_m) * num_dead_trees - + ! coarse root biomass per tree bcroot = (sapw_m + struct_m) * (1.0_r8 - prt_params%allom_agb_frac(pft) ) - + ! below ground coarse woody debris from burned trees do c = 1,ncwd do sl = 1,currentSite%nlevsoil @@ -1719,14 +1721,15 @@ subroutine fire_litter_fluxes(currentSite, currentPatch, & donatable_mass = num_dead_trees * SF_val_CWD_frac(c) * bstem if (c == 1 .or. c == 2) then donatable_mass = donatable_mass * (1.0_r8-currentCohort%fraction_crown_burned) - burned_mass = num_dead_trees * SF_val_CWD_frac(c) * bstem * & + burned_mass = num_dead_trees * SF_val_CWD_frac(c) * bstem * & currentCohort%fraction_crown_burned site_mass%burn_flux_to_atm = site_mass%burn_flux_to_atm + burned_mass endif new_litt%ag_cwd(c) = new_litt%ag_cwd(c) + donatable_mass * donate_m2 curr_litt%ag_cwd(c) = curr_litt%ag_cwd(c) + donatable_mass * retain_m2 flux_diags%cwd_ag_input(c) = flux_diags%cwd_ag_input(c) + donatable_mass - enddo + enddo + endif currentCohort => currentCohort%taller diff --git a/biogeochem/EDPhysiologyMod.F90 b/biogeochem/EDPhysiologyMod.F90 index 9a43af3226..71c483b2df 100644 --- a/biogeochem/EDPhysiologyMod.F90 +++ b/biogeochem/EDPhysiologyMod.F90 @@ -2193,24 +2193,46 @@ subroutine CWDInput( currentSite, currentPatch, litt, bc_in) currentCohort => currentPatch%shortest do while(associated(currentCohort)) pft = currentCohort%pft - - call set_root_fraction(currentSite%rootfrac_scr, pft, currentSite%zi_soil, & + call set_root_fraction(currentSite%rootfrac_scr, pft, currentSite%zi_soil, & bc_in%max_rooting_depth_index_col) - leaf_m_turnover = currentCohort%prt%GetTurnover(leaf_organ,element_id) - store_m_turnover = currentCohort%prt%GetTurnover(store_organ,element_id) - fnrt_m_turnover = currentCohort%prt%GetTurnover(fnrt_organ,element_id) - sapw_m_turnover = currentCohort%prt%GetTurnover(sapw_organ,element_id) - struct_m_turnover = currentCohort%prt%GetTurnover(struct_organ,element_id) - repro_m_turnover = currentCohort%prt%GetTurnover(repro_organ,element_id) - - leaf_m = currentCohort%prt%GetState(leaf_organ,element_id) - store_m = currentCohort%prt%GetState(store_organ,element_id) - fnrt_m = currentCohort%prt%GetState(fnrt_organ,element_id) - sapw_m = currentCohort%prt%GetState(sapw_organ,element_id) - struct_m = currentCohort%prt%GetState(struct_organ,element_id) - repro_m = currentCohort%prt%GetState(repro_organ,element_id) - + if ( prt_params%woody(pft) == itrue) then !trees only + leaf_m_turnover = currentCohort%prt%GetTurnover(leaf_organ, element_id) + store_m_turnover = currentCohort%prt%GetTurnover(store_organ,element_id) + sapw_m_turnover = currentCohort%prt%GetTurnover(sapw_organ, element_id) + fnrt_m_turnover = currentCohort%prt%GetTurnover(fnrt_organ, element_id) + struct_m_turnover = currentCohort%prt%GetTurnover(struct_organ, element_id) + repro_m_turnover = currentCohort%prt%GetTurnover(repro_organ, element_id) + leaf_m = currentCohort%prt%GetState(leaf_organ, element_id) + store_m = currentCohort%prt%GetState(store_organ, element_id) + sapw_m = currentCohort%prt%GetState(sapw_organ, element_id) + fnrt_m = currentCohort%prt%GetState(fnrt_organ, element_id) + struct_m = currentCohort%prt%GetState(struct_organ, element_id) + repro_m = currentCohort%prt%GetState(repro_organ, element_id) + else ! grass PFTs should not spawn anything other than leaves. + leaf_m_turnover = currentCohort%prt%GetTurnover(leaf_organ, element_id)+ & + currentCohort%prt%GetTurnover(store_organ, element_id)+ & + currentCohort%prt%GetTurnover(sapw_organ, element_id)+ & + currentCohort%prt%GetTurnover(fnrt_organ, element_id)+ & + currentCohort%prt%GetTurnover(struct_organ, element_id)+ & + currentCohort%prt%GetTurnover(repro_organ, element_id) + store_m_turnover = 0_r8 + sapw_m_turnover = 0_r8 + fnrt_m_turnover = 0_r8 + struct_m_turnover = 0_r8 + repro_m_turnover = 0_r8 + leaf_m = currentCohort%prt%GetState(leaf_organ, element_id)+ & + currentCohort%prt%GetState(store_organ, element_id)+ & + currentCohort%prt%GetState(sapw_organ, element_id)+ & + currentCohort%prt%GetState(fnrt_organ, element_id)+ & + currentCohort%prt%GetState(struct_organ, element_id)+ & + currentCohort%prt%GetState(repro_organ, element_id) + store_m = 0_r8 + sapw_m = 0_r8 + fnrt_m = 0_r8 + struct_m = 0_r8 + repro_m = 0_r8 + end if plant_dens = currentCohort%n/currentPatch%area ! ---------------------------------------------------------------------------------