diff --git a/biogeochem/EDPhysiologyMod.F90 b/biogeochem/EDPhysiologyMod.F90 index 016102dde0..85d04dccac 100644 --- a/biogeochem/EDPhysiologyMod.F90 +++ b/biogeochem/EDPhysiologyMod.F90 @@ -20,6 +20,7 @@ module EDPhysiologyMod use FatesInterfaceTypesMod, only : hlm_use_nocomp use EDParamsMod , only : crop_lu_pft_vector use EDParamsMod , only : GetNVegLayers + use EDParamsMod , only : cwd_hr_frag_frac use FatesInterfaceTypesMod, only : hlm_use_tree_damage use FatesInterfaceTypesMod, only : hlm_use_ed_prescribed_phys use FatesConstantsMod, only : r8 => fates_r8 @@ -490,6 +491,9 @@ subroutine PreDisturbanceLitterFluxes( currentSite, currentPatch, bc_in ) sum(litt%leaf_fines_frag) + sum(litt%root_fines_frag) + & sum(litt%seed_decay) + sum(litt%seed_germ_decay)) + site_mass%funghr_out = site_mass%funghr_out + currentPatch%area * & + (sum(litt%ag_cwd_funghr) + sum(litt%bg_cwd_funghr)) + ! Track total seed decay diagnostic in [kg/m2/day] diag%tot_seed_turnover = diag%tot_seed_turnover + & (sum(litt%seed_decay) + sum(litt%seed_germ_decay))*currentPatch%area*area_inv @@ -562,11 +566,12 @@ subroutine PreDisturbanceIntegrateLitter(currentPatch) ! ----------------------------------------------------------------------------------- nlevsoil = size(litt%bg_cwd,dim=2) do c = 1,ncwd - litt%ag_cwd(c) = litt%ag_cwd(c) + litt%ag_cwd_in(c) - litt%ag_cwd_frag(c) + litt%ag_cwd(c) = litt%ag_cwd(c) + litt%ag_cwd_in(c) - litt%ag_cwd_frag(c) - litt%ag_cwd_funghr(c) do ilyr=1,nlevsoil litt%bg_cwd(c,ilyr) = litt%bg_cwd(c,ilyr) & + litt%bg_cwd_in(c,ilyr) & - - litt%bg_cwd_frag(c,ilyr) + - litt%bg_cwd_frag(c,ilyr) & + - litt%bg_cwd_funghr(c,ilyr) enddo end do @@ -3269,6 +3274,9 @@ subroutine CWDOut( litt, fragmentation_scaler, nlev_eff_decomp ) integer :: ilyr ! Soil layer index integer :: dcmpy ! Decomposibility pool indexer integer :: soil_layer_index = 1 ! Soil layer index associated with above ground litter + real(r8) :: decomp_rate ! per-mass per-day loss rate due to fragmentation AND fungal HR + real(r8) :: cwd_hr_frag_frac_eff ! Effective (element specific) proportion of + ! losses due to HR !---------------------------------------------------------------------- @@ -3276,14 +3284,25 @@ subroutine CWDOut( litt, fragmentation_scaler, nlev_eff_decomp ) ! moisture scalars and fragmentation scalar associated with specified index value ! is used for ag_cwd_frag and root_fines_frag calculations. - do c = 1,ncwd - litt%ag_cwd_frag(c) = litt%ag_cwd(c) * SF_val_max_decomp(c) * & - years_per_day * fragmentation_scaler(soil_layer_index) + ! Heterotrophic respiration can only be applied to the carbon pool! + if( litt%element_id.eq.carbon12_element) then + cwd_hr_frag_frac_eff = cwd_hr_frag_frac + else + cwd_hr_frag_frac_eff = 0._r8 + end if + + + do c = 1,ncwd + decomp_rate = SF_val_max_decomp(c) * years_per_day * fragmentation_scaler(soil_layer_index) + litt%ag_cwd_frag(c) = litt%ag_cwd(c) * decomp_rate * (1._r8-cwd_hr_frag_frac_eff) + litt%ag_cwd_funghr(c) = litt%ag_cwd(c) * decomp_rate * cwd_hr_frag_frac_eff + do ilyr = 1,nlev_eff_decomp - litt%bg_cwd_frag(c,ilyr) = litt%bg_cwd(c,ilyr) * SF_val_max_decomp(c) * & - years_per_day * fragmentation_scaler(ilyr) + decomp_rate = SF_val_max_decomp(c) * years_per_day * fragmentation_scaler(ilyr) + litt%bg_cwd_frag(c,ilyr) = litt%bg_cwd(c,ilyr) * decomp_rate * (1._r8-cwd_hr_frag_frac_eff) + litt%bg_cwd_funghr(c,ilyr) = litt%bg_cwd(c,ilyr) * decomp_rate * cwd_hr_frag_frac_eff enddo end do diff --git a/biogeochem/FatesLitterMod.F90 b/biogeochem/FatesLitterMod.F90 index fb0d8c95fe..854dcff5df 100644 --- a/biogeochem/FatesLitterMod.F90 +++ b/biogeochem/FatesLitterMod.F90 @@ -101,6 +101,9 @@ module FatesLitterMod real(r8),allocatable :: leaf_fines_frag(:) ! above ground fines fragmentation flux [kg/m2/day] real(r8),allocatable :: root_fines_frag(:,:) ! kg/m2/day + real(r8) :: ag_cwd_funghr(ncwd) ! above ground Fungal respiration flux [kg/m2/day] + real(r8),allocatable :: bg_cwd_funghr(:,:) ! below ground fungal respiration flux [kg/m2/day] + real(r8), allocatable :: seed_decay(:) ! decay of viable seeds to litter [kg/m2/day] real(r8), allocatable :: seed_germ_decay(:) ! decay of germinated seeds to litter [kg/m2/day] real(r8), allocatable :: seed_germ_in(:) ! flux from viable to germinated seed [kg/m2/day] @@ -164,6 +167,8 @@ subroutine FuseLitter(this,self_area,donor_area,donor_litt) donor_litt%ag_cwd_in(c) * donor_weight this%ag_cwd_frag(c) = this%ag_cwd_frag(c) *self_weight + & donor_litt%ag_cwd_frag(c) * donor_weight + this%ag_cwd_funghr(c) = this%ag_cwd_funghr(c) * self_weight + & + donor_litt%ag_cwd_funghr(c) * donor_weight do ilyr = 1,nlevsoil this%bg_cwd(c,ilyr) = this%bg_cwd(c,ilyr) * self_weight + & donor_litt%bg_cwd(c,ilyr) * donor_weight @@ -171,6 +176,8 @@ subroutine FuseLitter(this,self_area,donor_area,donor_litt) donor_litt%bg_cwd_in(c,ilyr) * donor_weight this%bg_cwd_frag(c,ilyr) = this%bg_cwd_frag(c,ilyr) * self_weight + & donor_litt%bg_cwd_frag(c,ilyr) * donor_weight + this%bg_cwd_funghr(c,ilyr) = this%bg_cwd_funghr(c,ilyr) * self_weight + & + donor_litt%bg_cwd_funghr(c,ilyr) * donor_weight end do end do @@ -234,11 +241,13 @@ subroutine CopyLitter(this,donor_litt) this%ag_cwd(:) = donor_litt%ag_cwd(:) this%ag_cwd_in(:) = donor_litt%ag_cwd_in(:) this%ag_cwd_frag(:) = donor_litt%ag_cwd_frag(:) + this%ag_cwd_funghr(:) = donor_litt%ag_cwd_funghr(:) this%bg_cwd(:,:) = donor_litt%bg_cwd(:,:) this%bg_cwd_in(:,:) = donor_litt%bg_cwd_in(:,:) this%bg_cwd_frag(:,:) = donor_litt%bg_cwd_frag(:,:) - + this%bg_cwd_funghr(:,:) = donor_litt%bg_cwd_funghr(:,:) + this%leaf_fines(:) = donor_litt%leaf_fines(:) this%seed(:) = donor_litt%seed(:) this%seed_germ(:) = donor_litt%seed_germ(:) @@ -272,7 +281,8 @@ subroutine InitAllocate(this,numpft,numlevsoil,element_id) allocate(this%bg_cwd_in(ncwd,numlevsoil)) allocate(this%bg_cwd(ncwd,numlevsoil)) allocate(this%bg_cwd_frag(ncwd,numlevsoil)) - + allocate(this%bg_cwd_funghr(ncwd,numlevsoil)) + allocate(this%leaf_fines(ndcmpy)) allocate(this%root_fines(ndcmpy,numlevsoil)) allocate(this%leaf_fines_in(ndcmpy)) @@ -304,7 +314,9 @@ subroutine InitAllocate(this,numpft,numlevsoil,element_id) this%seed_in_extern(:) = fates_unset_r8 this%ag_cwd_frag(:) = fates_unset_r8 + this%ag_cwd_funghr(:) = fates_unset_r8 this%bg_cwd_frag(:,:) = fates_unset_r8 + this%bg_cwd_funghr(:,:) = fates_unset_r8 this%leaf_fines_frag(:) = fates_unset_r8 this%root_fines_frag(:,:) = fates_unset_r8 @@ -383,6 +395,7 @@ subroutine DeallocateLitt(this) deallocate(this%seed_in_extern) deallocate(this%bg_cwd_frag) + deallocate(this%bg_cwd_funghr) deallocate(this%leaf_fines_frag) deallocate(this%root_fines_frag) @@ -407,7 +420,9 @@ subroutine ZeroFlux(this) this%seed_in_extern(:) = 0._r8 this%ag_cwd_frag(:) = 0._r8 + this%ag_cwd_funghr(:) = 0._r8 this%bg_cwd_frag(:,:) = 0._r8 + this%bg_cwd_funghr(:,:) = 0._r8 this%leaf_fines_frag(:) = 0._r8 this%root_fines_frag(:,:) = 0._r8 diff --git a/main/ChecksBalancesMod.F90 b/main/ChecksBalancesMod.F90 index d93aa88a21..c01bd9ecfe 100644 --- a/main/ChecksBalancesMod.F90 +++ b/main/ChecksBalancesMod.F90 @@ -325,13 +325,14 @@ subroutine CheckIntegratedMassPools(site) - ediag%tot_seed_turnover) ! Flux for litter: veg turnover + seed turnover - "these are tot_litter_input" - ! fragmentation - + ! fragmentation - fungal respiration ! burned litter ibal%iflux_litter = ibal%iflux_litter + & tot_litter_input - & (site_mass%frag_out*area_inv - ediag%tot_seed_turnover) - & - (sum(site_mass%burn_flux_to_atm(:))*area_inv - ediag%burned_liveveg) + (sum(site_mass%burn_flux_to_atm(:))*area_inv - ediag%burned_liveveg) - & + site_mass%funghr_out*area_inv ediag%err_liveveg = ibal%iflux_liveveg - ibal%state_liveveg diff --git a/main/EDMainMod.F90 b/main/EDMainMod.F90 index f07a3c75de..690510179f 100644 --- a/main/EDMainMod.F90 +++ b/main/EDMainMod.F90 @@ -1015,6 +1015,7 @@ subroutine TotalBalanceCheck (currentSite, call_index, is_restarting ) site_mass%seed_out + & site_mass%flux_generic_out + & site_mass%frag_out + & + site_mass%funghr_out + & site_mass%aresp_acc + & site_mass%herbivory_flux_out end if @@ -1049,6 +1050,7 @@ subroutine TotalBalanceCheck (currentSite, call_index, is_restarting ) write(fates_log(),*) 'seed_out: ',site_mass%seed_out write(fates_log(),*) 'flux_generic_out: ',site_mass%flux_generic_out write(fates_log(),*) 'frag_out: ',site_mass%frag_out + write(fates_log(),*) 'funghr_out: ',site_mass%funghr_out write(fates_log(),*) 'aresp_acc: ',site_mass%aresp_acc write(fates_log(),*) 'herbivory_flux_out: ',site_mass%herbivory_flux_out write(fates_log(),*) 'error=net_flux-dstock:', error diff --git a/main/EDParamsMod.F90 b/main/EDParamsMod.F90 index 369eb6b9ec..adc88f10dd 100644 --- a/main/EDParamsMod.F90 +++ b/main/EDParamsMod.F90 @@ -44,6 +44,8 @@ module EDParamsMod real(r8),protected, public :: comp_excln_exp ! weighting factor (exponent) for canopy layer exclusion and promotion real(r8),protected, public :: ED_val_nignitions ! number of annual ignitions per square km real(r8),protected, public :: ED_val_understorey_death ! fraction of plants in understorey cohort impacted by overstorey tree-fall + real(r8),protected, public :: cwd_hr_frag_frac ! fraction of losses from CWD pool that are due to + ! fungal heterotrophic respiration as opposed to fragmentation real(r8),protected, public :: ED_val_cwd_fcel ! Cellulose fraction for CWD real(r8),protected, public :: ED_val_cwd_flig ! Lignin fraction of coarse woody debris real(r8),protected, public :: maintresp_nonleaf_baserate ! Base maintenance respiration rate for plant tissues @@ -227,6 +229,7 @@ subroutine FatesParamsInit() comp_excln_exp = nan ED_val_nignitions = nan ED_val_understorey_death = nan + cwd_hr_frag_frac = nan ED_val_cwd_fcel = nan ED_val_cwd_flig = nan maintresp_nonleaf_baserate = nan @@ -339,6 +342,9 @@ subroutine TransferParamsGeneric(pstruct) param_p => pstruct%GetParamFromName("fates_frag_cwd_flig") ED_val_cwd_flig = param_p%r_data_scalar + + param_p => pstruct%GetParamFromName("fates_cwd_hrfrag_frac") + cwd_hr_frag_frac = param_p%r_data_scalar param_p => pstruct%GetParamFromName("fates_maintresp_nonleaf_baserate") maintresp_nonleaf_baserate = param_p%r_data_scalar @@ -514,6 +520,7 @@ subroutine FatesReportParams(is_master) write(fates_log(),fmt0) 'comp_excln_exp = ',comp_excln_exp write(fates_log(),fmt0) 'ED_val_nignitions = ',ED_val_nignitions write(fates_log(),fmt0) 'ED_val_understorey_death = ',ED_val_understorey_death + write(fates_log(),fmt0) 'cwd_hr_frag_frac= ', cwd_hr_frag_frac write(fates_log(),fmt0) 'ED_val_cwd_fcel = ',ED_val_cwd_fcel write(fates_log(),fmt0) 'ED_val_cwd_flig = ',ED_val_cwd_flig write(fates_log(),fmt0) 'fates_maintresp_nonleaf_baserate = ', maintresp_nonleaf_baserate diff --git a/main/EDTypesMod.F90 b/main/EDTypesMod.F90 index 5aca294987..53245e526f 100644 --- a/main/EDTypesMod.F90 +++ b/main/EDTypesMod.F90 @@ -294,6 +294,8 @@ module EDTypesMod real(r8) :: frag_out ! Litter and coarse woody debris fragmentation flux [kg/site/day] + real(r8) :: funghr_out ! Losses to fungal respiration [kg/site/day] + real(r8) :: wood_product_harvest(maxpft) ! Total mass exported as wood product from wood harvest [kg/site/day] real(r8) :: wood_product_landusechange(maxpft) ! Total mass exported as wood product from land use change [kg/site/day] @@ -715,6 +717,7 @@ subroutine ZeroMassBalFlux(this) this%seed_in = 0._r8 this%seed_out = 0._r8 this%frag_out = 0._r8 + this%funghr_out = 0._r8 this%wood_product_harvest(:) = 0._r8 this%wood_product_landusechange(:) = 0._r8 this%burn_flux_to_atm(:) = 0._r8 diff --git a/main/FatesConstantsMod.F90 b/main/FatesConstantsMod.F90 index 4d535f9de4..e8c12e33c4 100644 --- a/main/FatesConstantsMod.F90 +++ b/main/FatesConstantsMod.F90 @@ -286,7 +286,6 @@ module FatesConstantsMod ! Conversion: megajoules per joule real(fates_r8), parameter, public :: megajoules_per_joule = 1.0E-6_fates_r8 - ! Conversion: days per second real(fates_r8), parameter, public :: days_per_sec = 1.0_fates_r8/86400.0_fates_r8 diff --git a/main/FatesHistoryInterfaceMod.F90 b/main/FatesHistoryInterfaceMod.F90 index 22e207cffc..1a03b1611c 100644 --- a/main/FatesHistoryInterfaceMod.F90 +++ b/main/FatesHistoryInterfaceMod.F90 @@ -402,6 +402,7 @@ module FatesHistoryInterfaceMod integer :: ih_tveg_si integer :: ih_nep_si integer :: ih_hr_si + integer :: ih_hr_cwdfung_si integer :: ih_c_stomata_si integer :: ih_c_lblayer_si @@ -5179,11 +5180,12 @@ subroutine update_history_hifrq_sitelevel(this,nc,nsites,sites,bc_in,dt_tstep) real(r8) :: dt_tstep_inv ! inverse timestep (1/sec) real(r8) :: n_perm2 ! number of plants per square meter real(r8) :: sum_area_rad ! sum of patch canopy areas + real(r8) :: cwdfung_hr real(r8),allocatable :: age_area_rad(:) type(fates_patch_type),pointer :: cpatch type(fates_cohort_type),pointer :: ccohort - + type(litter_type), pointer :: litt ! Generic pointer to any litter pool associate( hio_gpp_si => this%hvars(ih_gpp_si)%r81d, & hio_npp_si => this%hvars(ih_npp_si)%r81d, & @@ -5196,6 +5198,7 @@ subroutine update_history_hifrq_sitelevel(this,nc,nsites,sites,bc_in,dt_tstep) hio_nir_rad_err_si => this%hvars(ih_nir_rad_err_si)%r81d, & hio_nep_si => this%hvars(ih_nep_si)%r81d, & hio_hr_si => this%hvars(ih_hr_si)%r81d, & + hio_hr_cwdfung_si => this%hvars(ih_hr_cwdfung_si)%r81d, & hio_gpp_canopy_si => this%hvars(ih_gpp_canopy_si)%r81d, & hio_ar_canopy_si => this%hvars(ih_ar_canopy_si)%r81d, & hio_gpp_understory_si => this%hvars(ih_gpp_understory_si)%r81d, & @@ -5246,6 +5249,17 @@ subroutine update_history_hifrq_sitelevel(this,nc,nsites,sites,bc_in,dt_tstep) age_class = get_age_class_index(cpatch%age) age_area_rad(age_class) = age_area_rad(age_class) + cpatch%total_canopy_area end if + + litt => cpatch%litter(element_pos(carbon12_element)) + + ! scale fungal resp to from /m2 patch to /m2 site (ie area weighted average) + ! convert time units from kg/m2/day to kg/m2/s + cwdfung_hr = cpatch%area*(sum(litt%ag_cwd_funghr) + sum(litt%bg_cwd_funghr))*area_inv*days_per_sec + + hio_hr_si(io_si) = hio_hr_si(io_si) + cwdfung_hr + hio_nep_si(io_si) = hio_nep_si(io_si) + cwdfung_hr + hio_hr_cwdfung_si(io_si) = hio_hr_cwdfung_si(io_si) + cwdfung_hr + cpatch => cpatch%younger end do @@ -9108,6 +9122,11 @@ subroutine define_history_vars(this, initialize_variables) use_default='active', avgflag='A', vtype=site_r8, hlms='CLM:ALM', & upfreq=group_hifr_simple, ivar=ivar, initialize=initialize_variables, index = ih_hr_si) + call this%set_history_var(vname='FATES_CWDFUNGAL_HET_RESP', units='kg m-2 s-1', & + long='heterotrophic respiration strictly from fungal activity in CWD', & + use_default='active', avgflag='A', vtype=site_r8, hlms='CLM:ALM', & + upfreq=group_hifr_simple, ivar=ivar, initialize=initialize_variables, index = ih_hr_cwdfung_si) + hydro_active_if0: if(hlm_use_planthydro.eq.itrue) then call this%set_history_var(vname='FATES_SAPFLOW', units='kg m-2 s-1', & long='areal sap flow rate in kg per m2 ground area per second', & diff --git a/parameter_files/fates_params_default.json b/parameter_files/fates_params_default.json index fbdba0c78b..222bb42e92 100644 --- a/parameter_files/fates_params_default.json +++ b/parameter_files/fates_params_default.json @@ -1640,6 +1640,7 @@ "units": "yr-1", "data": [0.52, 0.383, 0.383, 0.19, 1.0, 999.0] }, + "fates_frag_cwd_frac": { "dtype": "float", "dims": ["fates_NCWD"], @@ -1682,6 +1683,13 @@ "units": "unitless", "data": [0.8] }, + "fates_cwd_hrfrag_frac": { + "dtype": "float", + "dims": ["scalar"], + "long_name": "fraction of cwd losses due to fungal heterotrophic respiration and not fragmentation", + "units": "-", + "data": [0.5] + }, "fates_cnp_eca_plant_escalar": { "dtype": "float", "dims": ["scalar"],