From feaa22c0c022bbb5b086f16f1d130074220b0c3c Mon Sep 17 00:00:00 2001 From: Adam Hanbury-Brown Date: Thu, 12 Jan 2023 15:16:39 -0700 Subject: [PATCH 01/32] added adjusted paritioning of stem wood (struct and sapw) to cwd in EDPhysiologyMod --- biogeochem/EDPhysiologyMod.F90 | 97 ++++++++++++++++++++++++++++------ 1 file changed, 81 insertions(+), 16 deletions(-) diff --git a/biogeochem/EDPhysiologyMod.F90 b/biogeochem/EDPhysiologyMod.F90 index 5eacaf00aa..b738edc92c 100644 --- a/biogeochem/EDPhysiologyMod.F90 +++ b/biogeochem/EDPhysiologyMod.F90 @@ -145,7 +145,6 @@ module EDPhysiologyMod integer, parameter :: dleafon_drycheck = 100 ! Drought deciduous leaves max days on check parameter - ! ============================================================================ contains @@ -232,7 +231,7 @@ subroutine GenerateDamageAndLitterFluxes( csite, cpatch, bc_in ) real(r8) :: store_loss ! "" [kg] real(r8) :: struct_loss ! "" [kg] real(r8) :: dcmpy_frac ! fraction of mass going to each decomposition pool - + real(r8), allocatable :: SF_val_CWD_frac_adj(:) !SF_val_CWD_frac adjusted based on cohort dbh if(hlm_use_tree_damage .ne. itrue) return @@ -322,16 +321,18 @@ subroutine GenerateDamageAndLitterFluxes( csite, cpatch, bc_in ) flux_diags%leaf_litter_input(ipft) = & flux_diags%leaf_litter_input(ipft) + & (store_loss+leaf_loss+repro_loss) * ndcohort%n + + call adjust_SF_CWD_frac(currentCohort%dbh,ncwd,SF_val_CWD_frac,SF_val_CWD_frac_adj) do c = 1,ncwd litt%ag_cwd_in(c) = litt%ag_cwd_in(c) + & (sapw_loss + struct_loss) * & - SF_val_CWD_frac(c) * ndcohort%n / & + SF_val_CWD_frac_adj(c) * ndcohort%n / & cpatch%area flux_diags%cwd_ag_input(c) = flux_diags%cwd_ag_input(c) + & (struct_loss + sapw_loss) * & - SF_val_CWD_frac(c) * ndcohort%n + SF_val_CWD_frac_adj(c) * ndcohort%n end do end do do_element @@ -2347,6 +2348,8 @@ subroutine CWDInput( currentSite, currentPatch, litt, bc_in) integer :: pft integer :: dcmpy ! decomposability pool index integer :: numlevsoil ! Actual number of soil layers + + real(r8), allocatable :: SF_val_CWD_frac_adj(:) !SF_val_CWD_frac adjusted based on cohort dbh !---------------------------------------------------------------------- ! ----------------------------------------------------------------------------------- @@ -2365,6 +2368,7 @@ 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, & bc_in%max_rooting_depth_index_col) @@ -2437,18 +2441,22 @@ subroutine CWDInput( currentSite, currentPatch, litt, bc_in) ! Assumption: turnover from deadwood and sapwood are lumped together in CWD pool + !update partitioning of stem wood (struct + sapw) to cwd based on cohort dbh + call adjust_SF_CWD_frac(currentCohort%dbh,ncwd,SF_val_CWD_frac,SF_val_CWD_frac_adj) + + do c = 1,ncwd litt%ag_cwd_in(c) = litt%ag_cwd_in(c) + & (sapw_m_turnover + struct_m_turnover) * & - SF_val_CWD_frac(c) * plant_dens * & + SF_val_CWD_frac_adj(c) * plant_dens * & prt_params%allom_agb_frac(pft) flux_diags%cwd_ag_input(c) = flux_diags%cwd_ag_input(c) + & - (struct_m_turnover + sapw_m_turnover) * SF_val_CWD_frac(c) * & + (struct_m_turnover + sapw_m_turnover) * SF_val_CWD_frac_adj(c) * & prt_params%allom_agb_frac(pft) * currentCohort%n bg_cwd_tot = (sapw_m_turnover + struct_m_turnover) * & - SF_val_CWD_frac(c) * plant_dens * & + SF_val_CWD_frac_adj(c) * plant_dens * & (1.0_r8-prt_params%allom_agb_frac(pft)) do ilyr = 1, numlevsoil @@ -2529,7 +2537,7 @@ subroutine CWDInput( currentSite, currentPatch, litt, bc_in) ! Below-ground bg_cwd_tot = (struct_m + sapw_m) * & - SF_val_CWD_frac(c) * dead_n * & + SF_val_CWD_frac_adj(c) * dead_n * & (1.0_r8-prt_params%allom_agb_frac(pft)) do ilyr = 1, numlevsoil @@ -2548,7 +2556,7 @@ subroutine CWDInput( currentSite, currentPatch, litt, bc_in) trunk_wood = (struct_m + sapw_m) * & - SF_val_CWD_frac(c) * dead_n_dlogging * & + SF_val_CWD_frac_adj(c) * dead_n_dlogging * & prt_params%allom_agb_frac(pft) site_mass%wood_product = site_mass%wood_product + & @@ -2566,21 +2574,21 @@ subroutine CWDInput( currentSite, currentPatch, litt, bc_in) ! Add AG wood to litter from indirect anthro sources litt%ag_cwd_in(c) = litt%ag_cwd_in(c) + (struct_m + sapw_m) * & - SF_val_CWD_frac(c) * (dead_n_natural+dead_n_ilogging) * & + SF_val_CWD_frac_adj(c) * (dead_n_natural+dead_n_ilogging) * & prt_params%allom_agb_frac(pft) flux_diags%cwd_ag_input(c) = flux_diags%cwd_ag_input(c) + & - SF_val_CWD_frac(c) * (dead_n_natural+dead_n_ilogging) * & + SF_val_CWD_frac_adj(c) * (dead_n_natural+dead_n_ilogging) * & currentPatch%area * prt_params%allom_agb_frac(pft) else litt%ag_cwd_in(c) = litt%ag_cwd_in(c) + (struct_m + sapw_m) * & - SF_val_CWD_frac(c) * dead_n * & + SF_val_CWD_frac_adj(c) * dead_n * & prt_params%allom_agb_frac(pft) flux_diags%cwd_ag_input(c) = flux_diags%cwd_ag_input(c) + & - SF_val_CWD_frac(c) * dead_n * (struct_m + sapw_m) * & + SF_val_CWD_frac_adj(c) * dead_n * (struct_m + sapw_m) * & currentPatch%area * prt_params%allom_agb_frac(pft) end if @@ -2610,13 +2618,13 @@ subroutine CWDInput( currentSite, currentPatch, litt, bc_in) currentSite%resources_management%delta_litter_stock = & currentSite%resources_management%delta_litter_stock + & (struct_m + sapw_m) * & - SF_val_CWD_frac(c) * (dead_n_natural+dead_n_ilogging) * & + SF_val_CWD_frac_adj(c) * (dead_n_natural+dead_n_ilogging) * & currentPatch%area currentSite%resources_management%delta_biomass_stock = & currentSite%resources_management%delta_biomass_stock + & (struct_m + sapw_m) * & - SF_val_CWD_frac(c) * dead_n * currentPatch%area + SF_val_CWD_frac_adj(c) * dead_n * currentPatch%area end do ! Update diagnostics that track resource management @@ -2918,5 +2926,62 @@ subroutine SetRecruitL2FR(csite) return end subroutine SetRecruitL2FR - + + ! ======================================================================= + subroutine adjust_SF_CWD_frac(dbh,ncwd,SF_val_CWD_frac,SF_val_CWD_frac_adj) + + !DESCRIPTION + !Adjust the partitioning of struct + sawp into cwd pools based on + !cohort dbh. This avoids struct and sapw from small cohorts going to + !1,000 hr fuels. Instead, struct + sapw go to the appropriate cwd pools + !based on established fuel class diameter thresholds. + + !ARGUMENTS + real(r8), intent(in) :: dbh !dbh of cohort + type(integer), intent(in) :: ncwd !number of cwd pools + real(r8), intent(in) :: SF_val_CWD_frac + real(r8), intent(out) :: SF_val_CWD_frac_adj + ! + !LOCAL VARIABLES + !These diameter ranges are based on work by Fosberg et al., 1971 + ! + real(r8), parameter :: lb_max_diam = 7.6 !max diameter [cm] for large branch + real(r8), parameter :: sb_max_diam = 2.5 !max diameter [cm] for small branch + real(r8), parameter :: twig_max_diam = 0.6 !max diameter [cm] for twig + !------------------------------------------------------------------------------------ + + + SF_val_CWD_frac_adj = SF_val_CWD_frac + + !If dbh is larger than max size of a large branch then we don't change + !how biomass is partitioned among cwd classes. + if (dbh > lb_max_diam) then + return + + !When dbh is greater than the max size of a small branch but less than or + !equal to the max size of a large branch we send the biomass that would have + !gone to trunk fuel to large branch fuel instead. + else if (dbh > sb_max_diam .and. dbh .le. lb_max_diam) then + SF_val_CWD_frac_adj(ncwd) = 0.0_r8 + SF_val_CWD_frac_adj(ncwd-1) = sum(SF_val_CWD_frac(ncwd-1:ncwd)) + + !When dbh is greater than the max size of a twig but less than or + !equal to the max size of a small branch we send the biomass that would have + !gone to trunk fuel / larger branch to small branch fuel instead. + else if (dbh > twig_max_diam .and. dbh .le. sb_max_diam) then + SF_val_CWD_frac_adj(ncwd) = 0.0_r8 + SF_val_CWD_frac_adj(ncwd-1) = 0.0_r8 + SF_val_CWD_frac_adj(ncwd-2) = sum(SF_val_CWD_frac(ncwd-2:ncwd)) + + !If dbh is less than or equal to the max size of a twig we send all + !biomass to twigs + else if (dbh .le. twig_max_diam) then + SF_val_CWD_frac_adj(ncwd) = 0.0_r8 + SF_val_CWD_frac_adj(ncwd-1) = 0.0_r8 + SF_val_CWD_frac_adj(ncwd-2) = 0.0_r8 + SF_val_CWD_frac_adj(ncwd-3) = sum(SF_val_CWD_frac) + + endif + + end subroutine adjust_SF_CWD_frac end module EDPhysiologyMod From 96ef187fed7cceabd9bf226810c3ca702dd3e495 Mon Sep 17 00:00:00 2001 From: Adam Hanbury-Brown Date: Thu, 12 Jan 2023 20:00:42 -0700 Subject: [PATCH 02/32] added fixes to partitioning of wood to CWD. Model is running. --- biogeochem/EDCohortDynamicsMod.F90 | 14 ++++-- biogeochem/EDLoggingMortalityMod.F90 | 42 ++++++++-------- biogeochem/EDPatchDynamicsMod.F90 | 34 ++++++++----- biogeochem/EDPhysiologyMod.F90 | 64 ++----------------------- biogeochem/FatesLitterMod.F90 | 72 +++++++++++++++++++++++++++- 5 files changed, 127 insertions(+), 99 deletions(-) diff --git a/biogeochem/EDCohortDynamicsMod.F90 b/biogeochem/EDCohortDynamicsMod.F90 index 70756393d8..3570b5a1a3 100644 --- a/biogeochem/EDCohortDynamicsMod.F90 +++ b/biogeochem/EDCohortDynamicsMod.F90 @@ -33,6 +33,7 @@ Module EDCohortDynamicsMod use FatesLitterMod , only : ncwd use FatesLitterMod , only : ndcmpy use FatesLitterMod , only : litter_type + use FatesLitterMod , only : adjust_SF_CWD_frac use EDParamsMod , only : max_cohort_per_patch use EDTypesMod , only : AREA use EDTypesMod , only : min_npm2, min_nppatch @@ -974,7 +975,7 @@ subroutine SendCohortToLitter(csite,cpatch,ccohort,nplant,bc_in) integer :: crowndamage ! the crown damage class of the cohort integer :: sl ! loop index for soil layers integer :: dcmpy ! loop index for decomposability - + real(r8) :: SF_val_CWD_frac_adj(4) !Updated wood partitioning to CWD based on dbh !---------------------------------------------------------------------- pft = ccohort%pft @@ -1004,29 +1005,32 @@ subroutine SendCohortToLitter(csite,cpatch,ccohort,nplant,bc_in) litt => cpatch%litter(el) flux_diags => csite%flux_diags(el) + !adjust how wood is partitioned between the cwd classes based on cohort dbh + call adjust_SF_CWD_frac(ccohort%dbh,ncwd,SF_val_CWD_frac,SF_val_CWD_frac_adj) + do c=1,ncwd ! above ground CWD litt%ag_cwd(c) = litt%ag_cwd(c) + plant_dens * & - (struct_m+sapw_m) * SF_val_CWD_frac(c) * & + (struct_m+sapw_m) * SF_val_CWD_frac_adj(c) * & prt_params%allom_agb_frac(pft) ! below ground CWD do sl=1,csite%nlevsoil litt%bg_cwd(c,sl) = litt%bg_cwd(c,sl) + plant_dens * & - (struct_m+sapw_m) * SF_val_CWD_frac(c) * & + (struct_m+sapw_m) * SF_val_CWD_frac_adj(c) * & (1.0_r8 - prt_params%allom_agb_frac(pft)) * & csite%rootfrac_scr(sl) enddo ! above ground flux_diags%cwd_ag_input(c) = flux_diags%cwd_ag_input(c) + & - (struct_m+sapw_m) * SF_val_CWD_frac(c) * & + (struct_m+sapw_m) * SF_val_CWD_frac_adj(c) * & prt_params%allom_agb_frac(pft) * nplant ! below ground flux_diags%cwd_bg_input(c) = flux_diags%cwd_bg_input(c) + & - (struct_m + sapw_m) * SF_val_CWD_frac(c) * & + (struct_m + sapw_m) * SF_val_CWD_frac_adj(c) * & (1.0_r8 - prt_params%allom_agb_frac(pft)) * nplant enddo diff --git a/biogeochem/EDLoggingMortalityMod.F90 b/biogeochem/EDLoggingMortalityMod.F90 index ab0b77b737..603307d7d6 100644 --- a/biogeochem/EDLoggingMortalityMod.F90 +++ b/biogeochem/EDLoggingMortalityMod.F90 @@ -21,6 +21,7 @@ module EDLoggingMortalityMod use FatesLitterMod , only : ncwd use FatesLitterMod , only : ndcmpy use FatesLitterMod , only : litter_type + use FatesLitterMod , only : adjust_SF_CWD_frac use EDTypesMod , only : ed_site_type use EDTypesMod , only : ed_resources_management_type use EDTypesMod , only : dtype_ilog @@ -502,7 +503,7 @@ subroutine logging_litter_fluxes(currentSite, currentPatch, newPatch, patch_site integer :: nlevsoil ! number of soil layers integer :: ilyr ! soil layer loop index integer :: el ! elemend loop index - + real(r8) :: SF_val_CWD_frac_adj(4) !Updated wood partitioning to CWD based on dbh nlevsoil = currentSite%nlevsoil @@ -601,37 +602,40 @@ subroutine logging_litter_fluxes(currentSite, currentPatch, newPatch, patch_site prt_params%allom_agb_frac(currentCohort%pft) bg_wood = (direct_dead+indirect_dead) * (struct_m + sapw_m ) * & (1._r8 - prt_params%allom_agb_frac(currentCohort%pft)) - - do c = 1,ncwd-1 + + !adjust how wood is partitioned between the cwd classes based on cohort dbh + call adjust_SF_CWD_frac(currentCohort%dbh,ncwd,SF_val_CWD_frac,SF_val_CWD_frac_adj) + + do c = 1,ncwd-1 new_litt%ag_cwd(c) = new_litt%ag_cwd(c) + & - ag_wood * SF_val_CWD_frac(c) * donate_frac/newPatch%area + ag_wood * SF_val_CWD_frac_adj(c) * donate_frac/newPatch%area cur_litt%ag_cwd(c) = cur_litt%ag_cwd(c) + & - ag_wood * SF_val_CWD_frac(c) * retain_frac/remainder_area + ag_wood * SF_val_CWD_frac_adj(c) * retain_frac/remainder_area do ilyr = 1,nlevsoil new_litt%bg_cwd(c,ilyr) = new_litt%bg_cwd(c,ilyr) + & bg_wood * currentSite%rootfrac_scr(ilyr) * & - SF_val_CWD_frac(c) * donate_frac/newPatch%area + SF_val_CWD_frac_adj(c) * donate_frac/newPatch%area cur_litt%bg_cwd(c,ilyr) = cur_litt%bg_cwd(c,ilyr) + & bg_wood * currentSite%rootfrac_scr(ilyr) * & - SF_val_CWD_frac(c) * retain_frac/remainder_area + SF_val_CWD_frac_adj(c) * retain_frac/remainder_area end do ! Diagnostics on fluxes into the AG and BG CWD pools flux_diags%cwd_ag_input(c) = flux_diags%cwd_ag_input(c) + & - SF_val_CWD_frac(c) * ag_wood + SF_val_CWD_frac_adj(c) * ag_wood flux_diags%cwd_bg_input(c) = flux_diags%cwd_bg_input(c) + & - SF_val_CWD_frac(c) * bg_wood + SF_val_CWD_frac_adj(c) * bg_wood ! Diagnostic specific to resource management code if( element_id .eq. carbon12_element) then delta_litter_stock = delta_litter_stock + & - (ag_wood + bg_wood) * SF_val_CWD_frac(c) + (ag_wood + bg_wood) * SF_val_CWD_frac_adj(c) end if enddo @@ -646,39 +650,39 @@ subroutine logging_litter_fluxes(currentSite, currentPatch, newPatch, patch_site (1._r8 - prt_params%allom_agb_frac(currentCohort%pft)) new_litt%ag_cwd(ncwd) = new_litt%ag_cwd(ncwd) + ag_wood * & - SF_val_CWD_frac(ncwd) * donate_frac/newPatch%area + SF_val_CWD_frac_adj(ncwd) * donate_frac/newPatch%area cur_litt%ag_cwd(ncwd) = cur_litt%ag_cwd(ncwd) + ag_wood * & - SF_val_CWD_frac(ncwd) * retain_frac/remainder_area + SF_val_CWD_frac_adj(ncwd) * retain_frac/remainder_area do ilyr = 1,nlevsoil new_litt%bg_cwd(ncwd,ilyr) = new_litt%bg_cwd(ncwd,ilyr) + & bg_wood * currentSite%rootfrac_scr(ilyr) * & - SF_val_CWD_frac(ncwd) * donate_frac/newPatch%area + SF_val_CWD_frac_adj(ncwd) * donate_frac/newPatch%area cur_litt%bg_cwd(ncwd,ilyr) = cur_litt%bg_cwd(ncwd,ilyr) + & bg_wood * currentSite%rootfrac_scr(ilyr) * & - SF_val_CWD_frac(ncwd) * retain_frac/remainder_area + SF_val_CWD_frac_adj(ncwd) * retain_frac/remainder_area end do flux_diags%cwd_ag_input(ncwd) = flux_diags%cwd_ag_input(ncwd) + & - SF_val_CWD_frac(ncwd) * ag_wood + SF_val_CWD_frac_adj(ncwd) * ag_wood flux_diags%cwd_bg_input(ncwd) = flux_diags%cwd_bg_input(ncwd) + & - SF_val_CWD_frac(ncwd) * bg_wood + SF_val_CWD_frac_adj(ncwd) * bg_wood if( element_id .eq. carbon12_element) then delta_litter_stock = delta_litter_stock + & - (ag_wood+bg_wood) * SF_val_CWD_frac(ncwd) + (ag_wood+bg_wood) * SF_val_CWD_frac_adj(ncwd) end if ! --------------------------------------------------------------------------------------- ! Handle below-ground trunk flux for directly logged trees (c = ncwd) ! ---------------------------------------------------------------------------------------- - bg_wood = direct_dead * (struct_m + sapw_m ) * SF_val_CWD_frac(ncwd) * & + bg_wood = direct_dead * (struct_m + sapw_m ) * SF_val_CWD_frac_adj(ncwd) * & (1._r8 - prt_params%allom_agb_frac(currentCohort%pft)) do ilyr = 1,nlevsoil @@ -705,7 +709,7 @@ subroutine logging_litter_fluxes(currentSite, currentPatch, newPatch, patch_site ag_wood = direct_dead * (struct_m + sapw_m ) * & prt_params%allom_agb_frac(currentCohort%pft) * & - SF_val_CWD_frac(ncwd) + SF_val_CWD_frac_adj(ncwd) trunk_product_site = trunk_product_site + & ag_wood * logging_export_frac diff --git a/biogeochem/EDPatchDynamicsMod.F90 b/biogeochem/EDPatchDynamicsMod.F90 index dba1a67d13..38e1c583c1 100644 --- a/biogeochem/EDPatchDynamicsMod.F90 +++ b/biogeochem/EDPatchDynamicsMod.F90 @@ -16,6 +16,7 @@ module EDPatchDynamicsMod use FatesLitterMod , only : ncwd use FatesLitterMod , only : ndcmpy use FatesLitterMod , only : litter_type + use FatesLitterMod , only : adjust_SF_CWD_frac use EDTypesMod , only : homogenize_seed_pfts use EDTypesMod , only : n_dbh_bins, area, patchfusion_dbhbin_loweredges use EDtypesMod , only : force_patchfuse_min_biomass @@ -90,7 +91,7 @@ module EDPatchDynamicsMod use EDParamsMod, only : maxpatch_secondary use EDParamsMod, only : maxpatch_total use FatesRunningMeanMod, only : ema_24hr, fixed_24hr, ema_lpa - + ! CIME globals use shr_infnan_mod , only : nan => shr_infnan_nan, assignment(=) use shr_log_mod , only : errMsg => shr_log_errMsg @@ -1603,7 +1604,7 @@ subroutine fire_litter_fluxes(currentSite, currentPatch, & integer :: pft ! loop index for plant functional types integer :: dcmpy ! loop index for decomposability pool integer :: element_id ! parteh compatible global element index - + real(r8) :: SF_val_CWD_frac_adj(4) !Updated wood partitioning to CWD based on dbh !--------------------------------------------------------------------- ! Only do this if there was a fire in this actual patch. @@ -1736,9 +1737,13 @@ subroutine fire_litter_fluxes(currentSite, currentPatch, & bcroot = (sapw_m + struct_m) * (1.0_r8 - prt_params%allom_agb_frac(pft) ) ! below ground coarse woody debris from burned trees + + !adjust the how wood is partitioned between the cwd classes based on cohort dbh + call adjust_SF_CWD_frac(currentCohort%dbh,ncwd,SF_val_CWD_frac,SF_val_CWD_frac_adj) + do c = 1,ncwd do sl = 1,currentSite%nlevsoil - donatable_mass = num_dead_trees * SF_val_CWD_frac(c) * & + donatable_mass = num_dead_trees * SF_val_CWD_frac_adj(c) * & bcroot * currentSite%rootfrac_scr(sl) new_litt%bg_cwd(c,sl) = new_litt%bg_cwd(c,sl) + & @@ -1759,10 +1764,10 @@ subroutine fire_litter_fluxes(currentSite, currentPatch, & ! Above ground coarse woody debris from twigs and small branches ! a portion of this pool may burn do c = 1,ncwd - donatable_mass = num_dead_trees * SF_val_CWD_frac(c) * bstem + donatable_mass = num_dead_trees * SF_val_CWD_frac_adj(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_adj(c) * bstem * & currentCohort%fraction_crown_burned site_mass%burn_flux_to_atm = site_mass%burn_flux_to_atm + burned_mass endif @@ -1835,7 +1840,8 @@ subroutine mortality_litter_fluxes(currentSite, currentPatch, & integer :: el ! element loop index integer :: sl ! soil layer index integer :: element_id ! parteh compatible global element index - real(r8) :: dcmpy_frac ! decomposability fraction + real(r8) :: dcmpy_frac ! decomposability fraction + real(r8) :: SF_val_CWD_frac_adj(4) !Updated wood partitioning to CWD based on dbh !--------------------------------------------------------------------- remainder_area = currentPatch%area - patch_site_areadis @@ -1933,24 +1939,26 @@ subroutine mortality_litter_fluxes(currentSite, currentPatch, & call set_root_fraction(currentSite%rootfrac_scr, pft, currentSite%zi_soil, & bc_in%max_rooting_depth_index_col) + ! Adjust how wood is partitioned between the cwd classes based on cohort dbh + call adjust_SF_CWD_frac(currentCohort%dbh,ncwd,SF_val_CWD_frac,SF_val_CWD_frac_adj) do c=1,ncwd - + ! Transfer wood of dying trees to AG CWD pools new_litt%ag_cwd(c) = new_litt%ag_cwd(c) + ag_wood * & - SF_val_CWD_frac(c) * donate_m2 + SF_val_CWD_frac_adj(c) * donate_m2 curr_litt%ag_cwd(c) = curr_litt%ag_cwd(c) + ag_wood * & - SF_val_CWD_frac(c) * retain_m2 + SF_val_CWD_frac_adj(c) * retain_m2 ! Transfer wood of dying trees to BG CWD pools do sl = 1,currentSite%nlevsoil new_litt%bg_cwd(c,sl) = new_litt%bg_cwd(c,sl) + bg_wood * & - currentSite%rootfrac_scr(sl) * SF_val_CWD_frac(c) * & + currentSite%rootfrac_scr(sl) * SF_val_CWD_frac_adj(c) * & donate_m2 curr_litt%bg_cwd(c,sl) = curr_litt%bg_cwd(c,sl) + bg_wood * & - currentSite%rootfrac_scr(sl) * SF_val_CWD_frac(c) * & + currentSite%rootfrac_scr(sl) * SF_val_CWD_frac_adj(c) * & retain_m2 end do end do @@ -1986,10 +1994,10 @@ subroutine mortality_litter_fluxes(currentSite, currentPatch, & ! track diagnostic fluxes do c=1,ncwd flux_diags%cwd_ag_input(c) = & - flux_diags%cwd_ag_input(c) + SF_val_CWD_frac(c) * ag_wood + flux_diags%cwd_ag_input(c) + SF_val_CWD_frac_adj(c) * ag_wood flux_diags%cwd_bg_input(c) = & - flux_diags%cwd_bg_input(c) + SF_val_CWD_frac(c) * bg_wood + flux_diags%cwd_bg_input(c) + SF_val_CWD_frac_adj(c) * bg_wood end do flux_diags%leaf_litter_input(pft) = flux_diags%leaf_litter_input(pft) + & diff --git a/biogeochem/EDPhysiologyMod.F90 b/biogeochem/EDPhysiologyMod.F90 index b738edc92c..6d5fa103df 100644 --- a/biogeochem/EDPhysiologyMod.F90 +++ b/biogeochem/EDPhysiologyMod.F90 @@ -48,6 +48,7 @@ module EDPhysiologyMod use FatesLitterMod , only : ilabile use FatesLitterMod , only : ilignin use FatesLitterMod , only : icellulose + use FatesLitterMod , only : adjust_SF_CWD_frac use EDTypesMod , only : nclmax use EDTypesMod , only : AREA,AREA_INV use EDTypesMod , only : nlevleaf @@ -231,7 +232,7 @@ subroutine GenerateDamageAndLitterFluxes( csite, cpatch, bc_in ) real(r8) :: store_loss ! "" [kg] real(r8) :: struct_loss ! "" [kg] real(r8) :: dcmpy_frac ! fraction of mass going to each decomposition pool - real(r8), allocatable :: SF_val_CWD_frac_adj(:) !SF_val_CWD_frac adjusted based on cohort dbh + real(r8) :: SF_val_CWD_frac_adj(4) !SF_val_CWD_frac adjusted based on cohort dbh if(hlm_use_tree_damage .ne. itrue) return @@ -322,7 +323,7 @@ subroutine GenerateDamageAndLitterFluxes( csite, cpatch, bc_in ) flux_diags%leaf_litter_input(ipft) + & (store_loss+leaf_loss+repro_loss) * ndcohort%n - call adjust_SF_CWD_frac(currentCohort%dbh,ncwd,SF_val_CWD_frac,SF_val_CWD_frac_adj) + call adjust_SF_CWD_frac(ndcohort%dbh,ncwd,SF_val_CWD_frac,SF_val_CWD_frac_adj) do c = 1,ncwd litt%ag_cwd_in(c) = litt%ag_cwd_in(c) + & @@ -2349,7 +2350,7 @@ subroutine CWDInput( currentSite, currentPatch, litt, bc_in) integer :: dcmpy ! decomposability pool index integer :: numlevsoil ! Actual number of soil layers - real(r8), allocatable :: SF_val_CWD_frac_adj(:) !SF_val_CWD_frac adjusted based on cohort dbh + real(r8) :: SF_val_CWD_frac_adj(4) !SF_val_CWD_frac adjusted based on cohort dbh !---------------------------------------------------------------------- ! ----------------------------------------------------------------------------------- @@ -2927,61 +2928,4 @@ subroutine SetRecruitL2FR(csite) return end subroutine SetRecruitL2FR - ! ======================================================================= - subroutine adjust_SF_CWD_frac(dbh,ncwd,SF_val_CWD_frac,SF_val_CWD_frac_adj) - - !DESCRIPTION - !Adjust the partitioning of struct + sawp into cwd pools based on - !cohort dbh. This avoids struct and sapw from small cohorts going to - !1,000 hr fuels. Instead, struct + sapw go to the appropriate cwd pools - !based on established fuel class diameter thresholds. - - !ARGUMENTS - real(r8), intent(in) :: dbh !dbh of cohort - type(integer), intent(in) :: ncwd !number of cwd pools - real(r8), intent(in) :: SF_val_CWD_frac - real(r8), intent(out) :: SF_val_CWD_frac_adj - ! - !LOCAL VARIABLES - !These diameter ranges are based on work by Fosberg et al., 1971 - ! - real(r8), parameter :: lb_max_diam = 7.6 !max diameter [cm] for large branch - real(r8), parameter :: sb_max_diam = 2.5 !max diameter [cm] for small branch - real(r8), parameter :: twig_max_diam = 0.6 !max diameter [cm] for twig - !------------------------------------------------------------------------------------ - - - SF_val_CWD_frac_adj = SF_val_CWD_frac - - !If dbh is larger than max size of a large branch then we don't change - !how biomass is partitioned among cwd classes. - if (dbh > lb_max_diam) then - return - - !When dbh is greater than the max size of a small branch but less than or - !equal to the max size of a large branch we send the biomass that would have - !gone to trunk fuel to large branch fuel instead. - else if (dbh > sb_max_diam .and. dbh .le. lb_max_diam) then - SF_val_CWD_frac_adj(ncwd) = 0.0_r8 - SF_val_CWD_frac_adj(ncwd-1) = sum(SF_val_CWD_frac(ncwd-1:ncwd)) - - !When dbh is greater than the max size of a twig but less than or - !equal to the max size of a small branch we send the biomass that would have - !gone to trunk fuel / larger branch to small branch fuel instead. - else if (dbh > twig_max_diam .and. dbh .le. sb_max_diam) then - SF_val_CWD_frac_adj(ncwd) = 0.0_r8 - SF_val_CWD_frac_adj(ncwd-1) = 0.0_r8 - SF_val_CWD_frac_adj(ncwd-2) = sum(SF_val_CWD_frac(ncwd-2:ncwd)) - - !If dbh is less than or equal to the max size of a twig we send all - !biomass to twigs - else if (dbh .le. twig_max_diam) then - SF_val_CWD_frac_adj(ncwd) = 0.0_r8 - SF_val_CWD_frac_adj(ncwd-1) = 0.0_r8 - SF_val_CWD_frac_adj(ncwd-2) = 0.0_r8 - SF_val_CWD_frac_adj(ncwd-3) = sum(SF_val_CWD_frac) - - endif - - end subroutine adjust_SF_CWD_frac end module EDPhysiologyMod diff --git a/biogeochem/FatesLitterMod.F90 b/biogeochem/FatesLitterMod.F90 index be5ec48aa9..7198e1a92b 100644 --- a/biogeochem/FatesLitterMod.F90 +++ b/biogeochem/FatesLitterMod.F90 @@ -44,6 +44,7 @@ module FatesLitterMod implicit none private + public :: adjust_SF_CWD_frac integer, public, parameter :: ncwd = 4 ! number of coarse woody debris pools ! (twig,s branch,l branch, trunk) @@ -57,7 +58,6 @@ module FatesLitterMod type, public :: litter_type - ! This object is allocated for each element (C, N, P, etc) that we wish to track. @@ -424,6 +424,74 @@ function GetTotalLitterMass(this) result(total_mass) return end function GetTotalLitterMass - + + ! ===================================================== + + subroutine adjust_SF_CWD_frac(dbh,ncwd,SF_val_CWD_frac,SF_val_CWD_frac_adj) + + !DESCRIPTION + !Adjust the partitioning of struct + sawp into cwd pools based on + !cohort dbh. This avoids struct and sapw from small cohorts going to + !1,000 hr fuels. Instead, struct + sapw go to the appropriate cwd pools + !based on established fuel class diameter thresholds. + + !ARGUMENTS + real(r8), intent(in) :: dbh !dbh of cohort + type(integer), intent(in) :: ncwd !number of cwd pools + real(r8), intent(in) :: SF_val_CWD_frac(:) + real(r8), intent(out) :: SF_val_CWD_frac_adj(:) + ! + !LOCAL VARIABLES + !These diameter ranges are based on work by Fosberg et al., 1971 + ! + real(r8), parameter :: lb_max_diam = 7.6 !max diameter [cm] for large branch + real(r8), parameter :: sb_max_diam = 2.5 !max diameter [cm] for small branch + real(r8), parameter :: twig_max_diam = 0.6 !max diameter [cm] for twig + !------------------------------------------------------------------------------------ + + + write(fates_log(),*) "SFvalCWDFrac:",SF_val_CWD_frac + write(fates_log(),*) "SFvalCWDFrac sum:",sum(SF_val_CWD_frac(2:4)) + write(fates_log(),*) "ncwd:",ncwd + !write(fates_log(),*) "SFvalCWDFrac:",SF_val_CWD_frac + + SF_val_CWD_frac_adj = SF_val_CWD_frac + + !If dbh is larger than max size of a large branch then we don't change + !how biomass is partitioned among cwd classes. + if (dbh > lb_max_diam) then + return + + !When dbh is greater than the max size of a small branch but less than or + !equal to the max size of a large branch we send the biomass that would have + !gone to trunk fuel to large branch fuel instead. + else if (dbh > sb_max_diam .and. dbh .le. lb_max_diam) then + SF_val_CWD_frac_adj(4) = 0.0 + !SF_val_CWD_frac_adj(ncwd-1) = sum(SF_val_CWD_frac((ncwd-1):ncwd)) + SF_val_CWD_frac_adj(3) = sum(SF_val_CWD_frac(3:4)) + + write(fates_log(),*) "using ahb trunk fuel fix", SF_val_CWD_frac_adj + + !When dbh is greater than the max size of a twig but less than or + !equal to the max size of a small branch we send the biomass that would have + !gone to trunk fuel / larger branch to small branch fuel instead. + else if (dbh > twig_max_diam .and. dbh .le. sb_max_diam) then + !SF_val_CWD_frac_adj(ncwd) = 0.0_r8 + SF_val_CWD_frac_adj(4) = 0.0 + !SF_val_CWD_frac_adj(ncwd-1) = 0.0_r8 + SF_val_CWD_frac_adj(3) = 0.0 + !SF_val_CWD_frac_adj(ncwd-2) = sum(SF_val_CWD_frac((ncwd-2):ncwd)) + SF_val_CWD_frac_adj(2) = sum(SF_val_CWD_frac(2:4)) + + !If dbh is less than or equal to the max size of a twig we send all + !biomass to twigs + else if (dbh .le. twig_max_diam) then + SF_val_CWD_frac_adj(ncwd) = 0.0 + SF_val_CWD_frac_adj(ncwd-1) = 0.0 + SF_val_CWD_frac_adj(ncwd-2) = 0.0 + SF_val_CWD_frac_adj(ncwd-3) = sum(SF_val_CWD_frac) + + endif + end subroutine adjust_SF_CWD_frac end module FatesLitterMod From 30352b166bc343f3890667165cf41a96be41cec1 Mon Sep 17 00:00:00 2001 From: Adam Hanbury-Brown Date: Wed, 25 Jan 2023 18:18:27 -0700 Subject: [PATCH 03/32] cleaned up the cwd adjust subroutine --- biogeochem/FatesLitterMod.F90 | 47 ++++++++++++++++------------------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/biogeochem/FatesLitterMod.F90 b/biogeochem/FatesLitterMod.F90 index 7198e1a92b..1bb03e99fd 100644 --- a/biogeochem/FatesLitterMod.F90 +++ b/biogeochem/FatesLitterMod.F90 @@ -432,8 +432,9 @@ subroutine adjust_SF_CWD_frac(dbh,ncwd,SF_val_CWD_frac,SF_val_CWD_frac_adj) !DESCRIPTION !Adjust the partitioning of struct + sawp into cwd pools based on !cohort dbh. This avoids struct and sapw from small cohorts going to - !1,000 hr fuels. Instead, struct + sapw go to the appropriate cwd pools - !based on established fuel class diameter thresholds. + !fuel classes that are too large. Instead, struct + sapw go to the cwd + !class based on established fuel class diameter thresholds (Fosberg et al., 1971; + !Rothermel, 1983) !ARGUMENTS real(r8), intent(in) :: dbh !dbh of cohort @@ -443,45 +444,41 @@ subroutine adjust_SF_CWD_frac(dbh,ncwd,SF_val_CWD_frac,SF_val_CWD_frac_adj) ! !LOCAL VARIABLES !These diameter ranges are based on work by Fosberg et al., 1971 - ! + real(r8), parameter :: lb_max_diam = 7.6 !max diameter [cm] for large branch real(r8), parameter :: sb_max_diam = 2.5 !max diameter [cm] for small branch real(r8), parameter :: twig_max_diam = 0.6 !max diameter [cm] for twig !------------------------------------------------------------------------------------ - write(fates_log(),*) "SFvalCWDFrac:",SF_val_CWD_frac - write(fates_log(),*) "SFvalCWDFrac sum:",sum(SF_val_CWD_frac(2:4)) - write(fates_log(),*) "ncwd:",ncwd - !write(fates_log(),*) "SFvalCWDFrac:",SF_val_CWD_frac - SF_val_CWD_frac_adj = SF_val_CWD_frac - !If dbh is larger than max size of a large branch then we don't change + !If dbh is larger than max size of a large branch (1,000 hr) then we don't change !how biomass is partitioned among cwd classes. if (dbh > lb_max_diam) then return - !When dbh is greater than the max size of a small branch but less than or + !When dbh is greater than the max size of a small branch (10 hr) but less than or !equal to the max size of a large branch we send the biomass that would have - !gone to trunk fuel to large branch fuel instead. + !gone to trunk fuel to large branch fuel (100 hr) instead. else if (dbh > sb_max_diam .and. dbh .le. lb_max_diam) then - SF_val_CWD_frac_adj(4) = 0.0 - !SF_val_CWD_frac_adj(ncwd-1) = sum(SF_val_CWD_frac((ncwd-1):ncwd)) - SF_val_CWD_frac_adj(3) = sum(SF_val_CWD_frac(3:4)) - - write(fates_log(),*) "using ahb trunk fuel fix", SF_val_CWD_frac_adj + SF_val_CWD_frac_adj(ncwd) = 0.0 + SF_val_CWD_frac_adj(ncwd-1) = sum(SF_val_CWD_frac((ncwd-1):ncwd)) + + + !SF_val_CWD_frac_adj(3) = sum(SF_val_CWD_frac(3:4)) + !write(fates_log(),*) "using ahb trunk fuel fix", SF_val_CWD_frac_adj - !When dbh is greater than the max size of a twig but less than or - !equal to the max size of a small branch we send the biomass that would have + !When dbh is greater than the max size of a twig (1 hr) but less than or + !equal to the max size of a small branch (10 hr) we send the biomass that would have !gone to trunk fuel / larger branch to small branch fuel instead. else if (dbh > twig_max_diam .and. dbh .le. sb_max_diam) then - !SF_val_CWD_frac_adj(ncwd) = 0.0_r8 - SF_val_CWD_frac_adj(4) = 0.0 - !SF_val_CWD_frac_adj(ncwd-1) = 0.0_r8 - SF_val_CWD_frac_adj(3) = 0.0 - !SF_val_CWD_frac_adj(ncwd-2) = sum(SF_val_CWD_frac((ncwd-2):ncwd)) - SF_val_CWD_frac_adj(2) = sum(SF_val_CWD_frac(2:4)) + SF_val_CWD_frac_adj(ncwd) = 0.0 + !SF_val_CWD_frac_adj(4) = 0.0 + SF_val_CWD_frac_adj(ncwd-1) = 0.0 + !SF_val_CWD_frac_adj(3) = 0.0 + SF_val_CWD_frac_adj(ncwd-2) = sum(SF_val_CWD_frac((ncwd-2):ncwd)) + !SF_val_CWD_frac_adj(2) = sum(SF_val_CWD_frac(2:4)) !If dbh is less than or equal to the max size of a twig we send all !biomass to twigs @@ -491,7 +488,7 @@ subroutine adjust_SF_CWD_frac(dbh,ncwd,SF_val_CWD_frac,SF_val_CWD_frac_adj) SF_val_CWD_frac_adj(ncwd-2) = 0.0 SF_val_CWD_frac_adj(ncwd-3) = sum(SF_val_CWD_frac) - endif + endif end subroutine adjust_SF_CWD_frac end module FatesLitterMod From dfa40ecb862666d1052ed57981f07df75d201701 Mon Sep 17 00:00:00 2001 From: Adam Hanbury-Brown Date: Fri, 3 Feb 2023 13:38:15 -0700 Subject: [PATCH 04/32] updated cwd paritioning to send more to the smaller fuel classes --- biogeochem/FatesLitterMod.F90 | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/biogeochem/FatesLitterMod.F90 b/biogeochem/FatesLitterMod.F90 index 1bb03e99fd..1b779be374 100644 --- a/biogeochem/FatesLitterMod.F90 +++ b/biogeochem/FatesLitterMod.F90 @@ -463,22 +463,18 @@ subroutine adjust_SF_CWD_frac(dbh,ncwd,SF_val_CWD_frac,SF_val_CWD_frac_adj) !gone to trunk fuel to large branch fuel (100 hr) instead. else if (dbh > sb_max_diam .and. dbh .le. lb_max_diam) then SF_val_CWD_frac_adj(ncwd) = 0.0 - SF_val_CWD_frac_adj(ncwd-1) = sum(SF_val_CWD_frac((ncwd-1):ncwd)) - - - !SF_val_CWD_frac_adj(3) = sum(SF_val_CWD_frac(3:4)) - !write(fates_log(),*) "using ahb trunk fuel fix", SF_val_CWD_frac_adj - + SF_val_CWD_frac_adj(ncwd-1) = SF_val_CWD_frac(ncwd) + SF_val_CWD_frac_adj(ncwd-2) = SF_val_CWD_frac(ncwd-1) + SF_val_CWD_frac_adj(ncwd-3) = sum(SF_val_CWD_frac((ncwd-3):(ncwd-2))) + !When dbh is greater than the max size of a twig (1 hr) but less than or !equal to the max size of a small branch (10 hr) we send the biomass that would have - !gone to trunk fuel / larger branch to small branch fuel instead. + !gone to trunk fuel and large branch fuel to small branch fuel instead. else if (dbh > twig_max_diam .and. dbh .le. sb_max_diam) then SF_val_CWD_frac_adj(ncwd) = 0.0 - !SF_val_CWD_frac_adj(4) = 0.0 SF_val_CWD_frac_adj(ncwd-1) = 0.0 - !SF_val_CWD_frac_adj(3) = 0.0 - SF_val_CWD_frac_adj(ncwd-2) = sum(SF_val_CWD_frac((ncwd-2):ncwd)) - !SF_val_CWD_frac_adj(2) = sum(SF_val_CWD_frac(2:4)) + SF_val_CWD_frac_adj(ncwd-2) = SF_val_CWD_frac(ncwd) + SF_val_CWD_frac_adj(ncwd-3) = sum(SF_val_CWD_frac((ncwd-3):(ncwd-1))) !If dbh is less than or equal to the max size of a twig we send all !biomass to twigs From 530afce45a92fb3b32f3f22a57b7abfc5521d7c5 Mon Sep 17 00:00:00 2001 From: Adam Hanbury-Brown Date: Thu, 16 Feb 2023 15:30:47 -0700 Subject: [PATCH 05/32] updated the cwd partitioning to keep the proportions the same among the burnable classes --- biogeochem/FatesLitterMod.F90 | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/biogeochem/FatesLitterMod.F90 b/biogeochem/FatesLitterMod.F90 index 1b779be374..c19857473a 100644 --- a/biogeochem/FatesLitterMod.F90 +++ b/biogeochem/FatesLitterMod.F90 @@ -459,23 +459,26 @@ subroutine adjust_SF_CWD_frac(dbh,ncwd,SF_val_CWD_frac,SF_val_CWD_frac_adj) return !When dbh is greater than the max size of a small branch (10 hr) but less than or - !equal to the max size of a large branch we send the biomass that would have - !gone to trunk fuel to large branch fuel (100 hr) instead. + !equal to the max size of a large branch we redistribute the biomass among the smaller + !pools, keeping the biomass proportions the same among the combustible classes. else if (dbh > sb_max_diam .and. dbh .le. lb_max_diam) then SF_val_CWD_frac_adj(ncwd) = 0.0 - SF_val_CWD_frac_adj(ncwd-1) = SF_val_CWD_frac(ncwd) - SF_val_CWD_frac_adj(ncwd-2) = SF_val_CWD_frac(ncwd-1) - SF_val_CWD_frac_adj(ncwd-3) = sum(SF_val_CWD_frac((ncwd-3):(ncwd-2))) + SF_val_CWD_frac_adj(ncwd-1) = SF_val_CWD_frac(ncwd-1) / (1.0_r - SF_val_CWD_frac(ncwd) ) + SF_val_CWD_frac_adj(ncwd-2) = SF_val_CWD_frac(ncwd-2) / (1.0_r - SF_val_CWD_frac(ncwd) ) + SF_val_CWD_frac_adj(ncwd-3) = SF_val_CWD_frac(ncwd-3) / (1.0_r - SF_val_CWD_frac(ncwd) ) + !When dbh is greater than the max size of a twig (1 hr) but less than or - !equal to the max size of a small branch (10 hr) we send the biomass that would have - !gone to trunk fuel and large branch fuel to small branch fuel instead. + !equal to the max size of a small branch (10 hr) we redistribute the biomass among the smaller + !pools, keeping the biomass proportions the same among the combustible classes. else if (dbh > twig_max_diam .and. dbh .le. sb_max_diam) then SF_val_CWD_frac_adj(ncwd) = 0.0 SF_val_CWD_frac_adj(ncwd-1) = 0.0 - SF_val_CWD_frac_adj(ncwd-2) = SF_val_CWD_frac(ncwd) - SF_val_CWD_frac_adj(ncwd-3) = sum(SF_val_CWD_frac((ncwd-3):(ncwd-1))) - + SF_val_CWD_frac_adj(ncwd-2) = SF_val_CWD_frac(ncwd-2) / (1.0_r - (SF_val_CWD_frac(ncwd) + & + SF_val_CWD_frac(ncwd-1))) + SF_val_CWD_frac_adj(ncwd-3) = SF_val_CWD_frac(ncwd-3) / (1.0_r - (SF_val_CWD_frac(ncwd) + & + SF_val_CWD_frac(ncwd-1))) + !If dbh is less than or equal to the max size of a twig we send all !biomass to twigs else if (dbh .le. twig_max_diam) then From 90bf6464729ef57d14fb7202f4599d1d3776fc46 Mon Sep 17 00:00:00 2001 From: Adam Hanbury-Brown Date: Wed, 22 Feb 2023 16:05:27 -0700 Subject: [PATCH 06/32] cleaned up fix to cwd change --- biogeochem/FatesLitterMod.F90 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/biogeochem/FatesLitterMod.F90 b/biogeochem/FatesLitterMod.F90 index c19857473a..ddb7a7689b 100644 --- a/biogeochem/FatesLitterMod.F90 +++ b/biogeochem/FatesLitterMod.F90 @@ -463,9 +463,9 @@ subroutine adjust_SF_CWD_frac(dbh,ncwd,SF_val_CWD_frac,SF_val_CWD_frac_adj) !pools, keeping the biomass proportions the same among the combustible classes. else if (dbh > sb_max_diam .and. dbh .le. lb_max_diam) then SF_val_CWD_frac_adj(ncwd) = 0.0 - SF_val_CWD_frac_adj(ncwd-1) = SF_val_CWD_frac(ncwd-1) / (1.0_r - SF_val_CWD_frac(ncwd) ) - SF_val_CWD_frac_adj(ncwd-2) = SF_val_CWD_frac(ncwd-2) / (1.0_r - SF_val_CWD_frac(ncwd) ) - SF_val_CWD_frac_adj(ncwd-3) = SF_val_CWD_frac(ncwd-3) / (1.0_r - SF_val_CWD_frac(ncwd) ) + SF_val_CWD_frac_adj(ncwd-1) = SF_val_CWD_frac(ncwd-1) / (1.0_r8 - SF_val_CWD_frac(ncwd) ) + SF_val_CWD_frac_adj(ncwd-2) = SF_val_CWD_frac(ncwd-2) / (1.0_r8 - SF_val_CWD_frac(ncwd) ) + SF_val_CWD_frac_adj(ncwd-3) = SF_val_CWD_frac(ncwd-3) / (1.0_r8 - SF_val_CWD_frac(ncwd) ) !When dbh is greater than the max size of a twig (1 hr) but less than or @@ -474,9 +474,9 @@ subroutine adjust_SF_CWD_frac(dbh,ncwd,SF_val_CWD_frac,SF_val_CWD_frac_adj) else if (dbh > twig_max_diam .and. dbh .le. sb_max_diam) then SF_val_CWD_frac_adj(ncwd) = 0.0 SF_val_CWD_frac_adj(ncwd-1) = 0.0 - SF_val_CWD_frac_adj(ncwd-2) = SF_val_CWD_frac(ncwd-2) / (1.0_r - (SF_val_CWD_frac(ncwd) + & + SF_val_CWD_frac_adj(ncwd-2) = SF_val_CWD_frac(ncwd-2) / (1.0_r8 - (SF_val_CWD_frac(ncwd) + & SF_val_CWD_frac(ncwd-1))) - SF_val_CWD_frac_adj(ncwd-3) = SF_val_CWD_frac(ncwd-3) / (1.0_r - (SF_val_CWD_frac(ncwd) + & + SF_val_CWD_frac_adj(ncwd-3) = SF_val_CWD_frac(ncwd-3) / (1.0_r8 - (SF_val_CWD_frac(ncwd) + & SF_val_CWD_frac(ncwd-1))) !If dbh is less than or equal to the max size of a twig we send all From 457522b856fc8d8052081aa129aba3d31c34d6c4 Mon Sep 17 00:00:00 2001 From: Adam Hanbury-Brown Date: Wed, 22 Feb 2023 16:09:56 -0700 Subject: [PATCH 07/32] flag --- main/EDMainMod.F90 | 1 + 1 file changed, 1 insertion(+) diff --git a/main/EDMainMod.F90 b/main/EDMainMod.F90 index 025969b07a..dc4775b833 100644 --- a/main/EDMainMod.F90 +++ b/main/EDMainMod.F90 @@ -185,6 +185,7 @@ subroutine ed_ecosystem_dynamics(currentSite, bc_in, bc_out) !FIX(SPM,032414) take this out. On startup these values are all zero and on restart it !zeros out values read in the restart file + write(fates_log(),*) 'cwd fix 02223' ! Zero turnover rates and growth diagnostics call ZeroAllocationRates(currentSite) From 397a574c380f5580b40df15f07e1f05e784151f2 Mon Sep 17 00:00:00 2001 From: Adam Hanbury-Brown Date: Thu, 23 Feb 2023 11:41:01 -0700 Subject: [PATCH 08/32] removed flags --- main/EDMainMod.F90 | 1 - 1 file changed, 1 deletion(-) diff --git a/main/EDMainMod.F90 b/main/EDMainMod.F90 index dc4775b833..025969b07a 100644 --- a/main/EDMainMod.F90 +++ b/main/EDMainMod.F90 @@ -185,7 +185,6 @@ subroutine ed_ecosystem_dynamics(currentSite, bc_in, bc_out) !FIX(SPM,032414) take this out. On startup these values are all zero and on restart it !zeros out values read in the restart file - write(fates_log(),*) 'cwd fix 02223' ! Zero turnover rates and growth diagnostics call ZeroAllocationRates(currentSite) From 5e5a04af905934dabe2245c5bec73c441af89eaa Mon Sep 17 00:00:00 2001 From: Adam Hanbury-Brown Date: Tue, 28 Mar 2023 15:08:58 -0600 Subject: [PATCH 09/32] cleaned up comments in cwd_partitioning_adj subroutine --- biogeochem/FatesLitterMod.F90 | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/biogeochem/FatesLitterMod.F90 b/biogeochem/FatesLitterMod.F90 index ddb7a7689b..d50e942134 100644 --- a/biogeochem/FatesLitterMod.F90 +++ b/biogeochem/FatesLitterMod.F90 @@ -432,15 +432,17 @@ subroutine adjust_SF_CWD_frac(dbh,ncwd,SF_val_CWD_frac,SF_val_CWD_frac_adj) !DESCRIPTION !Adjust the partitioning of struct + sawp into cwd pools based on !cohort dbh. This avoids struct and sapw from small cohorts going to - !fuel classes that are too large. Instead, struct + sapw go to the cwd - !class based on established fuel class diameter thresholds (Fosberg et al., 1971; + !fuel classes that are larger than their dbh. Here, struct + sapw are sent to the cwd + !class consistent with fuel class diameter thresholds (Fosberg et al., 1971; !Rothermel, 1983) !ARGUMENTS - real(r8), intent(in) :: dbh !dbh of cohort + real(r8), intent(in) :: dbh !dbh of cohort [cm] type(integer), intent(in) :: ncwd !number of cwd pools - real(r8), intent(in) :: SF_val_CWD_frac(:) - real(r8), intent(out) :: SF_val_CWD_frac_adj(:) + real(r8), intent(in) :: SF_val_CWD_frac(:) !fates parameter specifying the + !fraction of struct + sapw going + !to each CWD class + real(r8), intent(out) :: SF_val_CWD_frac_adj(:) !Updated cwd paritions ! !LOCAL VARIABLES !These diameter ranges are based on work by Fosberg et al., 1971 @@ -453,14 +455,16 @@ subroutine adjust_SF_CWD_frac(dbh,ncwd,SF_val_CWD_frac,SF_val_CWD_frac_adj) SF_val_CWD_frac_adj = SF_val_CWD_frac - !If dbh is larger than max size of a large branch (1,000 hr) then we don't change + !If dbh is larger than max size of a large branch (1,000 hr fuel) then we don't change !how biomass is partitioned among cwd classes. if (dbh > lb_max_diam) then return - !When dbh is greater than the max size of a small branch (10 hr) but less than or - !equal to the max size of a large branch we redistribute the biomass among the smaller - !pools, keeping the biomass proportions the same among the combustible classes. + !When dbh is greater than the max size of a small branch (10 hr fuel) but less than or + !equal to the max size of a large branch (e.g. saplings where dbh > 2.5 cm and < 7.5 cm) + !we redistribute the biomass that would have gone to 1,000 hr fuel among the smaller cwd classes. + !This keeps the biomass proportions among the combustible classes the same as the scenario + !where a fraction of struct + sawp goes to 1,000 hr fuel. else if (dbh > sb_max_diam .and. dbh .le. lb_max_diam) then SF_val_CWD_frac_adj(ncwd) = 0.0 SF_val_CWD_frac_adj(ncwd-1) = SF_val_CWD_frac(ncwd-1) / (1.0_r8 - SF_val_CWD_frac(ncwd) ) @@ -468,9 +472,9 @@ subroutine adjust_SF_CWD_frac(dbh,ncwd,SF_val_CWD_frac,SF_val_CWD_frac_adj) SF_val_CWD_frac_adj(ncwd-3) = SF_val_CWD_frac(ncwd-3) / (1.0_r8 - SF_val_CWD_frac(ncwd) ) - !When dbh is greater than the max size of a twig (1 hr) but less than or - !equal to the max size of a small branch (10 hr) we redistribute the biomass among the smaller - !pools, keeping the biomass proportions the same among the combustible classes. + !When dbh is greater than the max size of a twig (1 hr fuel) but less than or + !equal to the max size of a small branch (10 hr fuel) we redistribute the biomass among the smaller + !pools. else if (dbh > twig_max_diam .and. dbh .le. sb_max_diam) then SF_val_CWD_frac_adj(ncwd) = 0.0 SF_val_CWD_frac_adj(ncwd-1) = 0.0 @@ -480,7 +484,7 @@ subroutine adjust_SF_CWD_frac(dbh,ncwd,SF_val_CWD_frac,SF_val_CWD_frac_adj) SF_val_CWD_frac(ncwd-1))) !If dbh is less than or equal to the max size of a twig we send all - !biomass to twigs + !biomass to twigs. else if (dbh .le. twig_max_diam) then SF_val_CWD_frac_adj(ncwd) = 0.0 SF_val_CWD_frac_adj(ncwd-1) = 0.0 From a9cbc6205509f9a81494cba28b6b68cb53a16beb Mon Sep 17 00:00:00 2001 From: Adam Hanbury-Brown Date: Tue, 28 Mar 2023 15:42:30 -0600 Subject: [PATCH 10/32] added testing print statements --- biogeochem/FatesLitterMod.F90 | 1 + 1 file changed, 1 insertion(+) diff --git a/biogeochem/FatesLitterMod.F90 b/biogeochem/FatesLitterMod.F90 index d50e942134..aa559fe2c6 100644 --- a/biogeochem/FatesLitterMod.F90 +++ b/biogeochem/FatesLitterMod.F90 @@ -471,6 +471,7 @@ subroutine adjust_SF_CWD_frac(dbh,ncwd,SF_val_CWD_frac,SF_val_CWD_frac_adj) SF_val_CWD_frac_adj(ncwd-2) = SF_val_CWD_frac(ncwd-2) / (1.0_r8 - SF_val_CWD_frac(ncwd) ) SF_val_CWD_frac_adj(ncwd-3) = SF_val_CWD_frac(ncwd-3) / (1.0_r8 - SF_val_CWD_frac(ncwd) ) + write(fates_log(),*) 'Using CWD scheme ahb 032823' !When dbh is greater than the max size of a twig (1 hr fuel) but less than or !equal to the max size of a small branch (10 hr fuel) we redistribute the biomass among the smaller From 0f2ec37656e0f043450f8d2c2665a24ab0451938 Mon Sep 17 00:00:00 2001 From: Adam Hanbury-Brown Date: Tue, 28 Mar 2023 16:43:04 -0600 Subject: [PATCH 11/32] deleted diagnostic print statements --- biogeochem/FatesLitterMod.F90 | 2 -- 1 file changed, 2 deletions(-) diff --git a/biogeochem/FatesLitterMod.F90 b/biogeochem/FatesLitterMod.F90 index aa559fe2c6..21a459b61f 100644 --- a/biogeochem/FatesLitterMod.F90 +++ b/biogeochem/FatesLitterMod.F90 @@ -471,8 +471,6 @@ subroutine adjust_SF_CWD_frac(dbh,ncwd,SF_val_CWD_frac,SF_val_CWD_frac_adj) SF_val_CWD_frac_adj(ncwd-2) = SF_val_CWD_frac(ncwd-2) / (1.0_r8 - SF_val_CWD_frac(ncwd) ) SF_val_CWD_frac_adj(ncwd-3) = SF_val_CWD_frac(ncwd-3) / (1.0_r8 - SF_val_CWD_frac(ncwd) ) - write(fates_log(),*) 'Using CWD scheme ahb 032823' - !When dbh is greater than the max size of a twig (1 hr fuel) but less than or !equal to the max size of a small branch (10 hr fuel) we redistribute the biomass among the smaller !pools. From 2786dc36c4de36a46cfb00be15aecbe337f64b32 Mon Sep 17 00:00:00 2001 From: adrifoster Date: Fri, 21 Apr 2023 09:58:01 -0600 Subject: [PATCH 12/32] add parameter check for fates_rad_leaf_xl --- biogeophys/EDSurfaceAlbedoMod.F90 | 4 +++- main/EDPftvarcon.F90 | 10 ++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/biogeophys/EDSurfaceAlbedoMod.F90 b/biogeophys/EDSurfaceAlbedoMod.F90 index 48b9d1e448..b6b368aabe 100644 --- a/biogeophys/EDSurfaceAlbedoMod.F90 +++ b/biogeophys/EDSurfaceAlbedoMod.F90 @@ -363,7 +363,9 @@ subroutine PatchNormanRadiation (currentPatch, & cosz = max(0.001_r8, currentPatch%solar_zenith_angle ) !copied from previous radiation code... do ft = 1,numpft sb = (90._r8 - (acos(cosz)*180._r8/pi_const)) * (pi_const / 180._r8) - chil = xl(ft) !min(max(xl(ft), -0.4_r8), 0.6_r8 ) + !chil should be between -0.6 and 0.4 + ! Bonan (2019) doi:10.1017/9781107339217 pg. 238 + chil = min(max(xl(ft), -0.4_r8), 0.6_r8 ) if ( abs(chil) <= 0.01_r8) then chil = 0.01_r8 end if diff --git a/main/EDPftvarcon.F90 b/main/EDPftvarcon.F90 index faf0e78bb7..f9dd7d9a27 100644 --- a/main/EDPftvarcon.F90 +++ b/main/EDPftvarcon.F90 @@ -1641,8 +1641,6 @@ subroutine FatesCheckParams(is_master) call endrun(msg=errMsg(sourcefile, __LINE__)) end select - - ! logging parameters, make sure they make sense if ( (logging_mechanical_frac + logging_collateral_frac + logging_direct_frac) .gt. 1._r8) then write(fates_log(),*) 'the sum of logging_mechanical_frac + logging_collateral_frac + logging_direct_frac' @@ -1675,6 +1673,14 @@ subroutine FatesCheckParams(is_master) do ipft = 1,npft + ! xl must be between -0.6 and 0.4 according to Bonan (2019) doi:10.1017/9781107339217 pg. 238 + !----------------------------------------------------------------------------------- + if (EDPftvarcon_inst%xl(ipft) < -0.6 .or. EDPftvarcon_inst%xl(ipft) > 0.4) then + write(fates_log(),*) 'fates_rad_leaf_xl for pft ', ipft, ' is outside the allowed range of -0.6 to 0.4' + write(fates_log(),*) 'Aborting' + call endrun(msg=errMsg(sourcefile, __LINE__)) + end if + ! Check that parameter ranges for age-dependent mortality make sense !----------------------------------------------------------------------------------- if ( ( EDPftvarcon_inst%mort_ip_age_senescence(ipft) < fates_check_param_set ) .and. & From 774b699fff075a8ec8ef13e969d76a400da275cf Mon Sep 17 00:00:00 2001 From: adrifoster Date: Fri, 21 Apr 2023 10:38:32 -0600 Subject: [PATCH 13/32] update indentation to match style --- main/EDPftvarcon.F90 | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/main/EDPftvarcon.F90 b/main/EDPftvarcon.F90 index f9dd7d9a27..e7b2761538 100644 --- a/main/EDPftvarcon.F90 +++ b/main/EDPftvarcon.F90 @@ -1672,14 +1672,13 @@ subroutine FatesCheckParams(is_master) do ipft = 1,npft - - ! xl must be between -0.6 and 0.4 according to Bonan (2019) doi:10.1017/9781107339217 pg. 238 - !----------------------------------------------------------------------------------- - if (EDPftvarcon_inst%xl(ipft) < -0.6 .or. EDPftvarcon_inst%xl(ipft) > 0.4) then - write(fates_log(),*) 'fates_rad_leaf_xl for pft ', ipft, ' is outside the allowed range of -0.6 to 0.4' - write(fates_log(),*) 'Aborting' - call endrun(msg=errMsg(sourcefile, __LINE__)) - end if + ! xl must be between -0.6 and 0.4 according to Bonan (2019) doi:10.1017/9781107339217 pg. 238 + !----------------------------------------------------------------------------------- + if (EDPftvarcon_inst%xl(ipft) < -0.6 .or. EDPftvarcon_inst%xl(ipft) > 0.4) then + write(fates_log(),*) 'fates_rad_leaf_xl for pft ', ipft, ' is outside the allowed range of -0.6 to 0.4' + write(fates_log(),*) 'Aborting' + call endrun(msg=errMsg(sourcefile, __LINE__)) + end if ! Check that parameter ranges for age-dependent mortality make sense !----------------------------------------------------------------------------------- From 733c72b99b4ee207d6e578ecfe8b88d3b75b8ea3 Mon Sep 17 00:00:00 2001 From: jessica needham Date: Fri, 21 Apr 2023 16:06:48 -0700 Subject: [PATCH 14/32] Add termination mortality to the mortality_cflux history variable --- main/FatesHistoryInterfaceMod.F90 | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/main/FatesHistoryInterfaceMod.F90 b/main/FatesHistoryInterfaceMod.F90 index 106acdeb34..4cec9c89bc 100644 --- a/main/FatesHistoryInterfaceMod.F90 +++ b/main/FatesHistoryInterfaceMod.F90 @@ -3849,7 +3849,9 @@ subroutine update_history_dyn(this,nc,nsites,sites,bc_in) hio_mortality_carbonflux_si_pft(io_si,i_pft) = hio_mortality_carbonflux_si_pft(io_si,i_pft) + & (sites(s)%fmort_carbonflux_canopy(i_pft) + & sites(s)%fmort_carbonflux_ustory(i_pft) + & - sites(s)%imort_carbonflux(i_pft) ) / g_per_kg ! cdk + sites(s)%imort_carbonflux(i_pft) ) / g_per_kg + & ! cdk + sites(s)%term_carbonflux_ustory(i_pft) * days_per_sec * ha_per_m2 + & + sites(s)%term_carbonflux_canopy(i_pft) * days_per_sec * ha_per_m2 hio_firemortality_carbonflux_si_pft(io_si,i_pft) = sites(s)%fmort_carbonflux_canopy(i_pft) / g_per_kg end do @@ -6716,7 +6718,7 @@ subroutine define_history_vars(this, initialize_variables) upfreq=1, ivar=ivar, initialize=initialize_variables, & index=ih_firemortality_carbonflux_si_pft) - call this%set_history_var(vname='FATES_MORTALITY_HYDRAULIC_CFLUX_PF', units='kg m-2 s-1', & + call this%set_history_var(vname='FATES_MORTALITY_HYDRO_CFLUX_PF', units='kg m-2 s-1', & long='PFT-level flux of biomass carbon from live to dead pool from hydraulic failure mortality', & use_default='active', avgflag='A', vtype=site_pft_r8, hlms='CLM:ALM', & upfreq=1, ivar=ivar, initialize=initialize_variables, & From fcffb8155f62cca5bacfffe85baceb803231449b Mon Sep 17 00:00:00 2001 From: adrifoster Date: Mon, 24 Apr 2023 13:24:58 -0600 Subject: [PATCH 15/32] fix numbers --- biogeophys/EDSurfaceAlbedoMod.F90 | 9 +++++---- main/EDPftvarcon.F90 | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/biogeophys/EDSurfaceAlbedoMod.F90 b/biogeophys/EDSurfaceAlbedoMod.F90 index b6b368aabe..2b0f7e0930 100644 --- a/biogeophys/EDSurfaceAlbedoMod.F90 +++ b/biogeophys/EDSurfaceAlbedoMod.F90 @@ -363,12 +363,13 @@ subroutine PatchNormanRadiation (currentPatch, & cosz = max(0.001_r8, currentPatch%solar_zenith_angle ) !copied from previous radiation code... do ft = 1,numpft sb = (90._r8 - (acos(cosz)*180._r8/pi_const)) * (pi_const / 180._r8) - !chil should be between -0.6 and 0.4 + !chil should be between -0.4 and 0.6 ! Bonan (2019) doi:10.1017/9781107339217 pg. 238 chil = min(max(xl(ft), -0.4_r8), 0.6_r8 ) - if ( abs(chil) <= 0.01_r8) then - chil = 0.01_r8 - end if + ! chil being close to zero shouldn't affect things + !if ( abs(chil) <= 0.01_r8) then + ! chil = 0.01_r8 + !end if phi1b(ft) = 0.5_r8 - 0.633_r8*chil - 0.330_r8*chil*chil phi2b(ft) = 0.877_r8 * (1._r8 - 2._r8*phi1b(ft)) !0 = horiz leaves, 1 - vert leaves. gdir = phi1b(ft) + phi2b(ft) * sin(sb) diff --git a/main/EDPftvarcon.F90 b/main/EDPftvarcon.F90 index e7b2761538..e21f7207fb 100644 --- a/main/EDPftvarcon.F90 +++ b/main/EDPftvarcon.F90 @@ -1672,9 +1672,9 @@ subroutine FatesCheckParams(is_master) do ipft = 1,npft - ! xl must be between -0.6 and 0.4 according to Bonan (2019) doi:10.1017/9781107339217 pg. 238 + ! xl must be between -0.4 and 0.6 according to Bonan (2019) doi:10.1017/9781107339217 pg. 238 !----------------------------------------------------------------------------------- - if (EDPftvarcon_inst%xl(ipft) < -0.6 .or. EDPftvarcon_inst%xl(ipft) > 0.4) then + if (EDPftvarcon_inst%xl(ipft) < -0.4 .or. EDPftvarcon_inst%xl(ipft) > 0.6) then write(fates_log(),*) 'fates_rad_leaf_xl for pft ', ipft, ' is outside the allowed range of -0.6 to 0.4' write(fates_log(),*) 'Aborting' call endrun(msg=errMsg(sourcefile, __LINE__)) From c8b81d2986f7e30b74c9f53f37bc878ce729e2c8 Mon Sep 17 00:00:00 2001 From: Adam Hanbury-Brown Date: Mon, 24 Apr 2023 15:15:27 -0600 Subject: [PATCH 16/32] updated comments in adjust_SF_CWD_frac subroutine in response to review from ZR --- biogeochem/FatesLitterMod.F90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/biogeochem/FatesLitterMod.F90 b/biogeochem/FatesLitterMod.F90 index 21a459b61f..e0ef9c80aa 100644 --- a/biogeochem/FatesLitterMod.F90 +++ b/biogeochem/FatesLitterMod.F90 @@ -447,15 +447,15 @@ subroutine adjust_SF_CWD_frac(dbh,ncwd,SF_val_CWD_frac,SF_val_CWD_frac_adj) !LOCAL VARIABLES !These diameter ranges are based on work by Fosberg et al., 1971 - real(r8), parameter :: lb_max_diam = 7.6 !max diameter [cm] for large branch - real(r8), parameter :: sb_max_diam = 2.5 !max diameter [cm] for small branch - real(r8), parameter :: twig_max_diam = 0.6 !max diameter [cm] for twig + real(r8), parameter :: lb_max_diam = 7.6 !max diameter [cm] for large branch (100 hr fuel) + real(r8), parameter :: sb_max_diam = 2.5 !max diameter [cm] for small branch (10 hr fuel) + real(r8), parameter :: twig_max_diam = 0.6 !max diameter [cm] for twig (1 hr fuel) !------------------------------------------------------------------------------------ SF_val_CWD_frac_adj = SF_val_CWD_frac - !If dbh is larger than max size of a large branch (1,000 hr fuel) then we don't change + !If dbh is > 7.6 cm diameter then the main stem is 1,000 hr fuel and we don't change !how biomass is partitioned among cwd classes. if (dbh > lb_max_diam) then return From 83a51408a97f2e7a2468e810899db857b3b689b0 Mon Sep 17 00:00:00 2001 From: jessica needham Date: Mon, 24 Apr 2023 16:34:04 -0700 Subject: [PATCH 17/32] Fix units on carbonflux variables in EDTypesMod --- main/EDTypesMod.F90 | 6 +++--- main/FatesHistoryInterfaceMod.F90 | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/main/EDTypesMod.F90 b/main/EDTypesMod.F90 index 834561deaa..fd697f89d1 100644 --- a/main/EDTypesMod.F90 +++ b/main/EDTypesMod.F90 @@ -843,10 +843,10 @@ module EDTypesMod ! were terminated this timestep, on size x pft real(r8), allocatable :: term_carbonflux_canopy(:) ! carbon flux from live to dead pools associated - ! with termination mortality, per canopy level + ! with termination mortality, per canopy level. [kg C/ha/day] real(r8), allocatable :: term_carbonflux_ustory(:) ! carbon flux from live to dead pools associated - ! with termination mortality, per canopy level - real(r8), allocatable :: imort_carbonflux(:) ! biomass of individuals killed due to impact mortality per year. [kgC/ha/day] + ! with termination mortality, per canopy level. [kg C/ha/day] + real(r8), allocatable :: imort_carbonflux(:) ! biomass of individuals killed due to impact mortality per year. [gC/m2/sec] real(r8), allocatable :: fmort_carbonflux_canopy(:) ! biomass of canopy indivs killed due to fire per year. [gC/m2/sec] real(r8), allocatable :: fmort_carbonflux_ustory(:) ! biomass of understory indivs killed due to fire per year [gC/m2/sec] diff --git a/main/FatesHistoryInterfaceMod.F90 b/main/FatesHistoryInterfaceMod.F90 index 4cec9c89bc..d63af9f00d 100644 --- a/main/FatesHistoryInterfaceMod.F90 +++ b/main/FatesHistoryInterfaceMod.F90 @@ -3849,7 +3849,7 @@ subroutine update_history_dyn(this,nc,nsites,sites,bc_in) hio_mortality_carbonflux_si_pft(io_si,i_pft) = hio_mortality_carbonflux_si_pft(io_si,i_pft) + & (sites(s)%fmort_carbonflux_canopy(i_pft) + & sites(s)%fmort_carbonflux_ustory(i_pft) + & - sites(s)%imort_carbonflux(i_pft) ) / g_per_kg + & ! cdk + sites(s)%imort_carbonflux(i_pft) ) / g_per_kg + & sites(s)%term_carbonflux_ustory(i_pft) * days_per_sec * ha_per_m2 + & sites(s)%term_carbonflux_canopy(i_pft) * days_per_sec * ha_per_m2 From e46721eb3644bd5196268c73578cd641b2b798ba Mon Sep 17 00:00:00 2001 From: jessica needham Date: Mon, 24 Apr 2023 17:05:25 -0700 Subject: [PATCH 18/32] Tidying units on imort_carbonflux. Add logging imort to imort_agb_flux --- biogeochem/EDPatchDynamicsMod.F90 | 14 ++++++++++---- main/EDTypesMod.F90 | 10 +++++----- main/FatesHistoryInterfaceMod.F90 | 10 +++++----- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/biogeochem/EDPatchDynamicsMod.F90 b/biogeochem/EDPatchDynamicsMod.F90 index 4c4efca18f..ae42cbc754 100644 --- a/biogeochem/EDPatchDynamicsMod.F90 +++ b/biogeochem/EDPatchDynamicsMod.F90 @@ -760,14 +760,13 @@ subroutine spawn_patches( currentSite, bc_in) currentSite%imort_carbonflux(currentCohort%pft) = & currentSite%imort_carbonflux(currentCohort%pft) + & (nc%n * ED_val_understorey_death / hlm_freq_day ) * & - total_c * g_per_kg * days_per_sec * years_per_day * ha_per_m2 + total_c * days_per_sec * years_per_day * ha_per_m2 currentSite%imort_abg_flux(currentCohort%size_class, currentCohort%pft) = & currentSite%imort_abg_flux(currentCohort%size_class, currentCohort%pft) + & (nc%n * ED_val_understorey_death / hlm_freq_day ) * & ( (sapw_c + struct_c + store_c) * prt_params%allom_agb_frac(currentCohort%pft) + & - leaf_c ) * & - g_per_kg * days_per_sec * years_per_day * ha_per_m2 + leaf_c ) * days_per_sec * years_per_day * ha_per_m2 ! Step 2: Apply survivor ship function based on the understory death fraction @@ -1020,7 +1019,14 @@ subroutine spawn_patches( currentSite, bc_in) currentSite%imort_carbonflux(currentCohort%pft) + & (nc%n * currentPatch%fract_ldist_not_harvested * & logging_coll_under_frac/ hlm_freq_day ) * & - total_c * g_per_kg * days_per_sec * years_per_day * ha_per_m2 + total_c * days_per_sec * years_per_day * ha_per_m2 + + currentSite%imort_abg_flux(currentCohort%size_class, currentCohort%pft) = & + currentSite%imort_abg_flux(currentCohort%size_class, currentCohort%pft) + & + (nc%n * currentPatch%fract_ldist_not_harvested * & + logging_coll_under_frac/ hlm_freq_day ) * & + ( ( sapw_c + struct_c + store_c) * prt_params%allom_agb_frac(currentCohort%pft) + & + leaf_c ) * days_per_sec * years_per_day * ha_per_m2 ! Step 2: Apply survivor ship function based on the understory death fraction diff --git a/main/EDTypesMod.F90 b/main/EDTypesMod.F90 index fd697f89d1..9bd01ef5e7 100644 --- a/main/EDTypesMod.F90 +++ b/main/EDTypesMod.F90 @@ -843,15 +843,15 @@ module EDTypesMod ! were terminated this timestep, on size x pft real(r8), allocatable :: term_carbonflux_canopy(:) ! carbon flux from live to dead pools associated - ! with termination mortality, per canopy level. [kg C/ha/day] + ! with termination mortality, per canopy level. [kgC/ha/day] real(r8), allocatable :: term_carbonflux_ustory(:) ! carbon flux from live to dead pools associated - ! with termination mortality, per canopy level. [kg C/ha/day] - real(r8), allocatable :: imort_carbonflux(:) ! biomass of individuals killed due to impact mortality per year. [gC/m2/sec] + ! with termination mortality, per canopy level. [kgC/ha/day] + real(r8), allocatable :: imort_carbonflux(:) ! biomass of individuals killed due to impact mortality per year. [kgC/m2/sec] real(r8), allocatable :: fmort_carbonflux_canopy(:) ! biomass of canopy indivs killed due to fire per year. [gC/m2/sec] real(r8), allocatable :: fmort_carbonflux_ustory(:) ! biomass of understory indivs killed due to fire per year [gC/m2/sec] real(r8), allocatable :: term_abg_flux(:,:) ! aboveground biomass lost due to termination mortality x size x pft - real(r8), allocatable :: imort_abg_flux(:,:) ! aboveground biomass lost due to impact mortality x size x pft + real(r8), allocatable :: imort_abg_flux(:,:) ! aboveground biomass lost due to impact mortality x size x pft [kgC/m2/sec] real(r8), allocatable :: fmort_abg_flux(:,:) ! aboveground biomass lost due to fire mortality x size x pft @@ -880,7 +880,7 @@ module EDTypesMod real(r8), allocatable :: fmort_rate_ustory_damage(:,:,:) ! number of individuals per damage class that die from fire - ustory real(r8), allocatable :: fmort_cflux_canopy_damage(:,:) ! cflux per damage class that die from fire - canopy real(r8), allocatable :: fmort_cflux_ustory_damage(:,:) ! cflux per damage class that die from fire - ustory - real(r8), allocatable :: imort_cflux_damage(:,:) ! carbon flux from impact mortality by damage class + real(r8), allocatable :: imort_cflux_damage(:,:) ! carbon flux from impact mortality by damage class [kgC/m2/sec] real(r8), allocatable :: term_cflux_canopy_damage(:,:) ! carbon flux from termination mortality by damage class real(r8), allocatable :: term_cflux_ustory_damage(:,:) ! carbon flux from termination mortality by damage class diff --git a/main/FatesHistoryInterfaceMod.F90 b/main/FatesHistoryInterfaceMod.F90 index d63af9f00d..d71087353b 100644 --- a/main/FatesHistoryInterfaceMod.F90 +++ b/main/FatesHistoryInterfaceMod.F90 @@ -3843,13 +3843,13 @@ subroutine update_history_dyn(this,nc,nsites,sites,bc_in) ! treat carbon flux from imort the same way hio_understory_mortality_carbonflux_si(io_si) = hio_understory_mortality_carbonflux_si(io_si) + & - sum(sites(s)%imort_carbonflux(:)) / g_per_kg + sum(sites(s)%imort_carbonflux(:)) do i_pft = 1, numpft hio_mortality_carbonflux_si_pft(io_si,i_pft) = hio_mortality_carbonflux_si_pft(io_si,i_pft) + & (sites(s)%fmort_carbonflux_canopy(i_pft) + & - sites(s)%fmort_carbonflux_ustory(i_pft) + & - sites(s)%imort_carbonflux(i_pft) ) / g_per_kg + & + sites(s)%fmort_carbonflux_ustory(i_pft) ) / g_per_kg + & + sites(s)%imort_carbonflux(i_pft) + & sites(s)%term_carbonflux_ustory(i_pft) * days_per_sec * ha_per_m2 + & sites(s)%term_carbonflux_canopy(i_pft) * days_per_sec * ha_per_m2 @@ -3862,8 +3862,8 @@ subroutine update_history_dyn(this,nc,nsites,sites,bc_in) i_scpf = (i_pft-1)*nlevsclass + i_scls hio_abg_mortality_cflux_si_scpf(io_si,i_scpf) = hio_abg_mortality_cflux_si_scpf(io_si,i_scpf) + & (sites(s)%fmort_abg_flux(i_scls,i_pft) / g_per_kg ) + & - (sites(s)%imort_abg_flux(i_scls,i_pft) / g_per_kg) + & - (sites(s)%term_abg_flux(i_scls,i_pft) * days_per_sec * ha_per_m2 ) ! jfn + sites(s)%imort_abg_flux(i_scls,i_pft) + & + (sites(s)%term_abg_flux(i_scls,i_pft) * days_per_sec * ha_per_m2 ) end do end do From c77dff19e09f7c910f1050999ab0094a938e76ba Mon Sep 17 00:00:00 2001 From: adrifoster Date: Fri, 5 May 2023 15:04:57 -0600 Subject: [PATCH 19/32] remove chil check in EDSurfaceAlbedoMod --- biogeophys/EDSurfaceAlbedoMod.F90 | 3 --- 1 file changed, 3 deletions(-) diff --git a/biogeophys/EDSurfaceAlbedoMod.F90 b/biogeophys/EDSurfaceAlbedoMod.F90 index 2b0f7e0930..465cefff52 100644 --- a/biogeophys/EDSurfaceAlbedoMod.F90 +++ b/biogeophys/EDSurfaceAlbedoMod.F90 @@ -363,9 +363,6 @@ subroutine PatchNormanRadiation (currentPatch, & cosz = max(0.001_r8, currentPatch%solar_zenith_angle ) !copied from previous radiation code... do ft = 1,numpft sb = (90._r8 - (acos(cosz)*180._r8/pi_const)) * (pi_const / 180._r8) - !chil should be between -0.4 and 0.6 - ! Bonan (2019) doi:10.1017/9781107339217 pg. 238 - chil = min(max(xl(ft), -0.4_r8), 0.6_r8 ) ! chil being close to zero shouldn't affect things !if ( abs(chil) <= 0.01_r8) then ! chil = 0.01_r8 From 9692da0aa0d42f2d6ddaee859dd21216c5d02e7e Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Mon, 8 May 2023 11:53:24 -0700 Subject: [PATCH 20/32] Update phi1b calculation to use xl directly --- biogeophys/EDSurfaceAlbedoMod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biogeophys/EDSurfaceAlbedoMod.F90 b/biogeophys/EDSurfaceAlbedoMod.F90 index 465cefff52..2f1696a1db 100644 --- a/biogeophys/EDSurfaceAlbedoMod.F90 +++ b/biogeophys/EDSurfaceAlbedoMod.F90 @@ -367,7 +367,7 @@ subroutine PatchNormanRadiation (currentPatch, & !if ( abs(chil) <= 0.01_r8) then ! chil = 0.01_r8 !end if - phi1b(ft) = 0.5_r8 - 0.633_r8*chil - 0.330_r8*chil*chil + phi1b(ft) = 0.5_r8 - 0.633_r8*xl(ft) - 0.330_r8*xl(ft)*xl(ft) phi2b(ft) = 0.877_r8 * (1._r8 - 2._r8*phi1b(ft)) !0 = horiz leaves, 1 - vert leaves. gdir = phi1b(ft) + phi2b(ft) * sin(sb) !how much direct light penetrates a singleunit of lai? From 009e4574b04002efedb613792ef88275fcca0052 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Tue, 9 May 2023 15:31:32 -0700 Subject: [PATCH 21/32] remove old chil local variable and commented out code --- biogeophys/EDSurfaceAlbedoMod.F90 | 5 ----- 1 file changed, 5 deletions(-) diff --git a/biogeophys/EDSurfaceAlbedoMod.F90 b/biogeophys/EDSurfaceAlbedoMod.F90 index 2f1696a1db..18d29c0109 100644 --- a/biogeophys/EDSurfaceAlbedoMod.F90 +++ b/biogeophys/EDSurfaceAlbedoMod.F90 @@ -265,7 +265,6 @@ subroutine PatchNormanRadiation (currentPatch, & integer :: fp,iv,s ! array indices integer :: ib ! waveband number real(r8) :: cosz ! 0.001 <= coszen <= 1.000 - real(r8) :: chil real(r8) :: gdir @@ -363,10 +362,6 @@ subroutine PatchNormanRadiation (currentPatch, & cosz = max(0.001_r8, currentPatch%solar_zenith_angle ) !copied from previous radiation code... do ft = 1,numpft sb = (90._r8 - (acos(cosz)*180._r8/pi_const)) * (pi_const / 180._r8) - ! chil being close to zero shouldn't affect things - !if ( abs(chil) <= 0.01_r8) then - ! chil = 0.01_r8 - !end if phi1b(ft) = 0.5_r8 - 0.633_r8*xl(ft) - 0.330_r8*xl(ft)*xl(ft) phi2b(ft) = 0.877_r8 * (1._r8 - 2._r8*phi1b(ft)) !0 = horiz leaves, 1 - vert leaves. gdir = phi1b(ft) + phi2b(ft) * sin(sb) From efde58c2873a1e7a3224da55fb283e6e55965981 Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Fri, 23 Jun 2023 11:58:23 -0600 Subject: [PATCH 22/32] Fix to the restart order issue --- main/FatesRestartInterfaceMod.F90 | 130 +++++++++++++++--------------- 1 file changed, 65 insertions(+), 65 deletions(-) diff --git a/main/FatesRestartInterfaceMod.F90 b/main/FatesRestartInterfaceMod.F90 index 6efceb3191..3e20b7528b 100644 --- a/main/FatesRestartInterfaceMod.F90 +++ b/main/FatesRestartInterfaceMod.F90 @@ -2087,6 +2087,8 @@ subroutine set_restart_vectors(this,nc,nsites,sites) io_idx_si_cacls= io_idx_co_1st io_idx_si_cdsc = io_idx_co_1st io_idx_si_cdpf = io_idx_co_1st + io_idx_si_scpf = io_idx_co_1st + io_idx_si_pft = io_idx_co_1st ! recruitment rate do i_pft = 1,numpft @@ -2101,6 +2103,32 @@ subroutine set_restart_vectors(this,nc,nsites,sites) rio_area_pft_sift(io_idx_co_1st+i_pft-1) = sites(s)%area_pft(i_pft) end do + do i_scls = 1, nlevsclass + do i_pft = 1, numpft + rio_fmortrate_cano_siscpf(io_idx_si_scpf) = sites(s)%fmort_rate_canopy(i_scls, i_pft) + rio_fmortrate_usto_siscpf(io_idx_si_scpf) = sites(s)%fmort_rate_ustory(i_scls, i_pft) + rio_imortrate_siscpf(io_idx_si_scpf) = sites(s)%imort_rate(i_scls, i_pft) + rio_fmortrate_crown_siscpf(io_idx_si_scpf) = sites(s)%fmort_rate_crown(i_scls, i_pft) + rio_fmortrate_cambi_siscpf(io_idx_si_scpf) = sites(s)%fmort_rate_cambial(i_scls, i_pft) + rio_termnindiv_cano_siscpf(io_idx_si_scpf) = sites(s)%term_nindivs_canopy(i_scls,i_pft) + rio_termnindiv_usto_siscpf(io_idx_si_scpf) = sites(s)%term_nindivs_ustory(i_scls,i_pft) + rio_growflx_fusion_siscpf(io_idx_si_scpf) = sites(s)%growthflux_fusion(i_scls, i_pft) + rio_abg_term_flux_siscpf(io_idx_si_scpf) = sites(s)%term_abg_flux(i_scls, i_pft) + rio_abg_imort_flux_siscpf(io_idx_si_scpf) = sites(s)%imort_abg_flux(i_scls, i_pft) + rio_abg_fmort_flux_siscpf(io_idx_si_scpf) = sites(s)%fmort_abg_flux(i_scls, i_pft) + io_idx_si_scpf = io_idx_si_scpf + 1 + end do + end do + + do i_pft = 1, numpft + rio_termcflux_cano_sipft(io_idx_si_pft) = sites(s)%term_carbonflux_canopy(i_pft) + rio_termcflux_usto_sipft(io_idx_si_pft) = sites(s)%term_carbonflux_ustory(i_pft) + rio_fmortcflux_cano_sipft(io_idx_si_pft) = sites(s)%fmort_carbonflux_canopy(i_pft) + rio_fmortcflux_usto_sipft(io_idx_si_pft) = sites(s)%fmort_carbonflux_ustory(i_pft) + rio_imortcflux_sipft(io_idx_si_pft) = sites(s)%imort_carbonflux(i_pft) + io_idx_si_pft = io_idx_si_pft + 1 + end do + if(hlm_use_sp.eq.ifalse)then do el = 1, num_elements @@ -2128,6 +2156,8 @@ subroutine set_restart_vectors(this,nc,nsites,sites) end do end if + + ! canopy spread term rio_spread_si(io_idx_si) = sites(s)%spread @@ -2136,7 +2166,7 @@ subroutine set_restart_vectors(this,nc,nsites,sites) ! new column, reset num patches patchespersite = 0 - do while(associated(cpatch)) + do_patch: do while(associated(cpatch)) ! found patch, increment patchespersite = patchespersite + 1 @@ -2414,31 +2444,12 @@ subroutine set_restart_vectors(this,nc,nsites,sites) cpatch => cpatch%younger - enddo ! cpatch do while - - io_idx_si_scpf = io_idx_co_1st + enddo do_patch ! cpatch do while ! Fill the site level diagnostics arrays do i_scls = 1, nlevsclass - do i_pft = 1, numpft - - rio_fmortrate_cano_siscpf(io_idx_si_scpf) = sites(s)%fmort_rate_canopy(i_scls, i_pft) - rio_fmortrate_usto_siscpf(io_idx_si_scpf) = sites(s)%fmort_rate_ustory(i_scls, i_pft) - rio_imortrate_siscpf(io_idx_si_scpf) = sites(s)%imort_rate(i_scls, i_pft) - rio_fmortrate_crown_siscpf(io_idx_si_scpf) = sites(s)%fmort_rate_crown(i_scls, i_pft) - rio_fmortrate_cambi_siscpf(io_idx_si_scpf) = sites(s)%fmort_rate_cambial(i_scls, i_pft) - rio_termnindiv_cano_siscpf(io_idx_si_scpf) = sites(s)%term_nindivs_canopy(i_scls,i_pft) - rio_termnindiv_usto_siscpf(io_idx_si_scpf) = sites(s)%term_nindivs_ustory(i_scls,i_pft) - rio_growflx_fusion_siscpf(io_idx_si_scpf) = sites(s)%growthflux_fusion(i_scls, i_pft) - - rio_abg_term_flux_siscpf(io_idx_si_scpf) = sites(s)%term_abg_flux(i_scls, i_pft) - rio_abg_imort_flux_siscpf(io_idx_si_scpf) = sites(s)%imort_abg_flux(i_scls, i_pft) - rio_abg_fmort_flux_siscpf(io_idx_si_scpf) = sites(s)%fmort_abg_flux(i_scls, i_pft) - io_idx_si_scpf = io_idx_si_scpf + 1 - end do - - rio_demorate_sisc(io_idx_si_sc) = sites(s)%demotion_rate(i_scls) + rio_demorate_sisc(io_idx_si_sc) = sites(s)%demotion_rate(i_scls) rio_promrate_sisc(io_idx_si_sc) = sites(s)%promotion_rate(i_scls) io_idx_si_sc = io_idx_si_sc + 1 @@ -2479,16 +2490,6 @@ subroutine set_restart_vectors(this,nc,nsites,sites) rio_democflux_si(io_idx_si) = sites(s)%demotion_carbonflux rio_promcflux_si(io_idx_si) = sites(s)%promotion_carbonflux - io_idx_si_pft = io_idx_co_1st - do i_pft = 1, numpft - rio_termcflux_cano_sipft(io_idx_si_pft) = sites(s)%term_carbonflux_canopy(i_pft) - rio_termcflux_usto_sipft(io_idx_si_pft) = sites(s)%term_carbonflux_ustory(i_pft) - rio_fmortcflux_cano_sipft(io_idx_si_pft) = sites(s)%fmort_carbonflux_canopy(i_pft) - rio_fmortcflux_usto_sipft(io_idx_si_pft) = sites(s)%fmort_carbonflux_ustory(i_pft) - rio_imortcflux_sipft(io_idx_si_pft) = sites(s)%imort_carbonflux(i_pft) - io_idx_si_pft = io_idx_si_pft + 1 - end do - rio_imortcarea_si(io_idx_si) = sites(s)%imort_crownarea rio_fmortcarea_cano_si(io_idx_si) = sites(s)%fmort_crownarea_canopy rio_fmortcarea_usto_si(io_idx_si) = sites(s)%fmort_crownarea_ustory @@ -3008,6 +3009,8 @@ subroutine get_restart_vectors(this, nc, nsites, sites) io_idx_si_cacls= io_idx_co_1st io_idx_si_cdsc = io_idx_co_1st io_idx_si_cdpf = io_idx_co_1st + io_idx_si_scpf = io_idx_co_1st + io_idx_si_pft = io_idx_co_1st ! read seed_bank info(site-level, but PFT-resolved) do i_pft = 1,numpft @@ -3029,6 +3032,33 @@ subroutine get_restart_vectors(this, nc, nsites, sites) endif endif + do i_scls = 1,nlevsclass + do i_pft = 1, numpft + sites(s)%fmort_rate_canopy(i_scls, i_pft) = rio_fmortrate_cano_siscpf(io_idx_si_scpf) + sites(s)%fmort_rate_ustory(i_scls, i_pft) = rio_fmortrate_usto_siscpf(io_idx_si_scpf) + sites(s)%imort_rate(i_scls, i_pft) = rio_imortrate_siscpf(io_idx_si_scpf) + sites(s)%fmort_rate_crown(i_scls, i_pft) = rio_fmortrate_crown_siscpf(io_idx_si_scpf) + sites(s)%fmort_rate_cambial(i_scls, i_pft) = rio_fmortrate_cambi_siscpf(io_idx_si_scpf) + sites(s)%term_nindivs_canopy(i_scls,i_pft) = rio_termnindiv_cano_siscpf(io_idx_si_scpf) + sites(s)%term_nindivs_ustory(i_scls,i_pft) = rio_termnindiv_usto_siscpf(io_idx_si_scpf) + sites(s)%growthflux_fusion(i_scls, i_pft) = rio_growflx_fusion_siscpf(io_idx_si_scpf) + sites(s)%term_abg_flux(i_scls,i_pft) = rio_abg_term_flux_siscpf(io_idx_si_scpf) + sites(s)%imort_abg_flux(i_scls,i_pft) = rio_abg_imort_flux_siscpf(io_idx_si_scpf) + sites(s)%fmort_abg_flux(i_scls,i_pft) = rio_abg_fmort_flux_siscpf(io_idx_si_scpf) + io_idx_si_scpf = io_idx_si_scpf + 1 + end do + end do + + do i_pft = 1, numpft + sites(s)%term_carbonflux_canopy(i_pft) = rio_termcflux_cano_sipft(io_idx_si_pft) + sites(s)%term_carbonflux_ustory(i_pft) = rio_termcflux_usto_sipft(io_idx_si_pft) + sites(s)%fmort_carbonflux_canopy(i_pft) = rio_fmortcflux_cano_sipft(io_idx_si_pft) + sites(s)%fmort_carbonflux_ustory(i_pft) = rio_fmortcflux_usto_sipft(io_idx_si_pft) + sites(s)%imort_carbonflux(i_pft) = rio_imortcflux_sipft(io_idx_si_pft) + io_idx_si_pft = io_idx_si_pft + 1 + end do + + ! Mass balance and diagnostics across elements at the site level if(hlm_use_sp.eq.ifalse)then do el = 1, num_elements @@ -3061,7 +3091,7 @@ subroutine get_restart_vectors(this, nc, nsites, sites) patchespersite = 0 cpatch => sites(s)%oldest_patch - do while(associated(cpatch)) + do_patch: do while(associated(cpatch)) patchespersite = patchespersite + 1 @@ -3333,8 +3363,7 @@ subroutine get_restart_vectors(this, nc, nsites, sites) end if cpatch => cpatch%younger - - enddo ! patch do while + enddo do_patch if(patchespersite .ne. rio_npatch_si(io_idx_si)) then write(fates_log(),*) 'Number of patches per site during retrieval does not match allocation' @@ -3391,30 +3420,11 @@ subroutine get_restart_vectors(this, nc, nsites, sites) ! Fill the site level diagnostics arrays ! ----------------------------------------------------------------------------- - - io_idx_si_scpf = io_idx_co_1st - do i_scls = 1,nlevsclass - do i_pft = 1, numpft - sites(s)%fmort_rate_canopy(i_scls, i_pft) = rio_fmortrate_cano_siscpf(io_idx_si_scpf) - sites(s)%fmort_rate_ustory(i_scls, i_pft) = rio_fmortrate_usto_siscpf(io_idx_si_scpf) - sites(s)%imort_rate(i_scls, i_pft) = rio_imortrate_siscpf(io_idx_si_scpf) - sites(s)%fmort_rate_crown(i_scls, i_pft) = rio_fmortrate_crown_siscpf(io_idx_si_scpf) - sites(s)%fmort_rate_cambial(i_scls, i_pft) = rio_fmortrate_cambi_siscpf(io_idx_si_scpf) - sites(s)%term_nindivs_canopy(i_scls,i_pft) = rio_termnindiv_cano_siscpf(io_idx_si_scpf) - sites(s)%term_nindivs_ustory(i_scls,i_pft) = rio_termnindiv_usto_siscpf(io_idx_si_scpf) - sites(s)%growthflux_fusion(i_scls, i_pft) = rio_growflx_fusion_siscpf(io_idx_si_scpf) - - sites(s)%term_abg_flux(i_scls,i_pft) = rio_abg_term_flux_siscpf(io_idx_si_scpf) - sites(s)%imort_abg_flux(i_scls,i_pft) = rio_abg_imort_flux_siscpf(io_idx_si_scpf) - sites(s)%fmort_abg_flux(i_scls,i_pft) = rio_abg_fmort_flux_siscpf(io_idx_si_scpf) - - io_idx_si_scpf = io_idx_si_scpf + 1 - end do sites(s)%demotion_rate(i_scls) = rio_demorate_sisc(io_idx_si_sc) sites(s)%promotion_rate(i_scls) = rio_promrate_sisc(io_idx_si_sc) - + io_idx_si_sc = io_idx_si_sc + 1 end do @@ -3452,16 +3462,6 @@ subroutine get_restart_vectors(this, nc, nsites, sites) sites(s)%demotion_carbonflux = rio_democflux_si(io_idx_si) sites(s)%promotion_carbonflux = rio_promcflux_si(io_idx_si) - io_idx_si_pft = io_idx_co_1st - do i_pft = 1, numpft - sites(s)%term_carbonflux_canopy(i_pft) = rio_termcflux_cano_sipft(io_idx_si_pft) - sites(s)%term_carbonflux_ustory(i_pft) = rio_termcflux_usto_sipft(io_idx_si_pft) - sites(s)%fmort_carbonflux_canopy(i_pft) = rio_fmortcflux_cano_sipft(io_idx_si_pft) - sites(s)%fmort_carbonflux_ustory(i_pft) = rio_fmortcflux_usto_sipft(io_idx_si_pft) - sites(s)%imort_carbonflux(i_pft) = rio_imortcflux_sipft(io_idx_si_pft) - io_idx_si_pft = io_idx_si_pft + 1 - end do - ! Site level phenology status flags sites(s)%cstatus = rio_cd_status_si(io_idx_si) From 49f82ab05ae0c088fc0e4bac976fc43bf4e56f54 Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Fri, 23 Jun 2023 12:48:24 -0600 Subject: [PATCH 23/32] moved nlevsclass calculation earlier in subroutine --- main/FatesInterfaceMod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/FatesInterfaceMod.F90 b/main/FatesInterfaceMod.F90 index 82b4357ea7..47fb444d38 100644 --- a/main/FatesInterfaceMod.F90 +++ b/main/FatesInterfaceMod.F90 @@ -822,6 +822,7 @@ subroutine SetFatesGlobalElements2(use_fates) nleafage = size(prt_params%leaf_long,dim=2) end if + nlevsclass = size(ED_val_history_sizeclass_bin_edges,dim=1) ! These values are used to define the restart file allocations and general structure ! of memory for the cohort arrays @@ -885,7 +886,6 @@ subroutine SetFatesGlobalElements2(use_fates) ! Identify number of size and age class bins for history output ! assume these arrays are 1-indexed - nlevsclass = size(ED_val_history_sizeclass_bin_edges,dim=1) nlevage = size(ED_val_history_ageclass_bin_edges,dim=1) nlevheight = size(ED_val_history_height_bin_edges,dim=1) nlevcoage = size(ED_val_history_coageclass_bin_edges,dim=1) From 180ba13a58c357a41b7ffc455eef8e2d1b6b92f2 Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Mon, 26 Jun 2023 11:58:25 -0400 Subject: [PATCH 24/32] Moved restart calls for new phen variables to different location --- main/FatesRestartInterfaceMod.F90 | 39 +++++++++++-------------------- 1 file changed, 14 insertions(+), 25 deletions(-) diff --git a/main/FatesRestartInterfaceMod.F90 b/main/FatesRestartInterfaceMod.F90 index 3e20b7528b..ec0e4ffc1f 100644 --- a/main/FatesRestartInterfaceMod.F90 +++ b/main/FatesRestartInterfaceMod.F90 @@ -2126,10 +2126,15 @@ subroutine set_restart_vectors(this,nc,nsites,sites) rio_fmortcflux_cano_sipft(io_idx_si_pft) = sites(s)%fmort_carbonflux_canopy(i_pft) rio_fmortcflux_usto_sipft(io_idx_si_pft) = sites(s)%fmort_carbonflux_ustory(i_pft) rio_imortcflux_sipft(io_idx_si_pft) = sites(s)%imort_carbonflux(i_pft) + rio_dd_status_sift(io_idx_si_pft) = sites(s)%dstatus(i_pft) + rio_dleafondate_sift(io_idx_si_pft) = sites(s)%dleafondate(i_pft) + rio_dleafoffdate_sift(io_idx_si_pft) = sites(s)%dleafoffdate(i_pft) + rio_dndaysleafon_sift(io_idx_si_pft) = sites(s)%dndaysleafon(i_pft) + rio_dndaysleafoff_sift(io_idx_si_pft) = sites(s)%dndaysleafoff(i_pft) + rio_elong_factor_sift(io_idx_si_pft) = sites(s)%elong_factor(i_pft) io_idx_si_pft = io_idx_si_pft + 1 end do - if(hlm_use_sp.eq.ifalse)then do el = 1, num_elements @@ -2504,18 +2509,7 @@ subroutine set_restart_vectors(this,nc,nsites,sites) rio_gdd_si(io_idx_si) = sites(s)%grow_deg_days rio_phenmodeldate_si(io_idx_si) = sites(s)%phen_model_date - ! Drought-deciduous phenology are now PFT dependent - io_idx_si_pft = io_idx_co_1st - do i_pft = 1,numpft - rio_dd_status_sift(io_idx_si_pft) = sites(s)%dstatus(i_pft) - rio_dleafondate_sift(io_idx_si_pft) = sites(s)%dleafondate(i_pft) - rio_dleafoffdate_sift(io_idx_si_pft) = sites(s)%dleafoffdate(i_pft) - rio_dndaysleafon_sift(io_idx_si_pft) = sites(s)%dndaysleafon(i_pft) - rio_dndaysleafoff_sift(io_idx_si_pft) = sites(s)%dndaysleafoff(i_pft) - rio_elong_factor_sift(io_idx_si_pft) = sites(s)%elong_factor(i_pft) - - io_idx_si_pft = io_idx_si_pft + 1 - end do + rio_acc_ni_si(io_idx_si) = sites(s)%acc_NI @@ -3055,10 +3049,15 @@ subroutine get_restart_vectors(this, nc, nsites, sites) sites(s)%fmort_carbonflux_canopy(i_pft) = rio_fmortcflux_cano_sipft(io_idx_si_pft) sites(s)%fmort_carbonflux_ustory(i_pft) = rio_fmortcflux_usto_sipft(io_idx_si_pft) sites(s)%imort_carbonflux(i_pft) = rio_imortcflux_sipft(io_idx_si_pft) + sites(s)%dstatus(i_pft) = rio_dd_status_sift(io_idx_si_pft) + sites(s)%dleafondate(i_pft) = rio_dleafondate_sift(io_idx_si_pft) + sites(s)%dleafoffdate(i_pft) = rio_dleafoffdate_sift(io_idx_si_pft) + sites(s)%dndaysleafon(i_pft) = rio_dndaysleafon_sift(io_idx_si_pft) + sites(s)%dndaysleafoff(i_pft) = rio_dndaysleafoff_sift(io_idx_si_pft) + sites(s)%elong_factor(i_pft) = rio_elong_factor_sift(io_idx_si_pft) io_idx_si_pft = io_idx_si_pft + 1 end do - ! Mass balance and diagnostics across elements at the site level if(hlm_use_sp.eq.ifalse)then do el = 1, num_elements @@ -3474,17 +3473,7 @@ subroutine get_restart_vectors(this, nc, nsites, sites) sites(s)%grow_deg_days = rio_gdd_si(io_idx_si) sites(s)%phen_model_date= rio_phenmodeldate_si(io_idx_si) - ! Fill drought-deciduous variables, which are now PFT variables. - io_idx_si_pft = io_idx_co_1st - do i_pft = 1,numpft - sites(s)%dstatus(i_pft) = rio_dd_status_sift(io_idx_si_pft) - sites(s)%dleafondate(i_pft) = rio_dleafondate_sift(io_idx_si_pft) - sites(s)%dleafoffdate(i_pft) = rio_dleafoffdate_sift(io_idx_si_pft) - sites(s)%dndaysleafon(i_pft) = rio_dndaysleafon_sift(io_idx_si_pft) - sites(s)%dndaysleafoff(i_pft) = rio_dndaysleafoff_sift(io_idx_si_pft) - sites(s)%elong_factor(i_pft) = rio_elong_factor_sift(io_idx_si_pft) - io_idx_si_pft = io_idx_si_pft + 1 - end do + sites(s)%acc_NI = rio_acc_ni_si(io_idx_si) sites(s)%snow_depth = rio_snow_depth_si(io_idx_si) From fa431f59cea75634a37c61b802eccf241f1f718c Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Mon, 26 Jun 2023 11:34:16 -0600 Subject: [PATCH 25/32] removed change of vcmax parameter --- parameter_files/archive/api25.4.0_041023_pr958.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/parameter_files/archive/api25.4.0_041023_pr958.xml b/parameter_files/archive/api25.4.0_041023_pr958.xml index 16b3af5890..4c1e7d673a 100644 --- a/parameter_files/archive/api25.4.0_041023_pr958.xml +++ b/parameter_files/archive/api25.4.0_041023_pr958.xml @@ -53,7 +53,6 @@ day threshold compared against days since leaves abscised (shed) - fates_pft 50, 62, 39, 61, 58, 58, 62, 54, 54, 78, 78, 78 From bd82b5fe27cf26269a3d6618177e1375117e9f55 Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Mon, 26 Jun 2023 14:56:15 -0400 Subject: [PATCH 26/32] updating the default parameter file per fixes in the api update xml to vcmax --- parameter_files/fates_params_default.cdl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/parameter_files/fates_params_default.cdl b/parameter_files/fates_params_default.cdl index a3a210d658..46f3cea4f5 100644 --- a/parameter_files/fates_params_default.cdl +++ b/parameter_files/fates_params_default.cdl @@ -365,7 +365,7 @@ variables: double fates_leaf_stomatal_slope_medlyn(fates_pft) ; fates_leaf_stomatal_slope_medlyn:units = "KPa**0.5" ; fates_leaf_stomatal_slope_medlyn:long_name = "stomatal slope parameter, as per Medlyn" ; - double fates_leaf_vcmax25top(fates_pft) ; + double fates_leaf_vcmax25top(fates_leafage_class, fates_pft) ; fates_leaf_vcmax25top:units = "umol CO2/m^2/s" ; fates_leaf_vcmax25top:long_name = "maximum carboxylation rate of Rub. at 25C, canopy top" ; double fates_leaf_vcmaxha(fates_pft) ; @@ -1265,7 +1265,8 @@ data: fates_leaf_stomatal_slope_medlyn = 4.1, 2.3, 2.3, 4.1, 4.4, 4.4, 4.7, 4.7, 4.7, 2.2, 5.3, 1.6 ; - fates_leaf_vcmax25top = 50, 62, 39, 61, 58, 58, 62, 54, 54, 78, 78, 78 ; + fates_leaf_vcmax25top = + 50, 62, 39, 61, 58, 58, 62, 54, 54, 78, 78, 78 ; fates_leaf_vcmaxha = 65330, 65330, 65330, 65330, 65330, 65330, 65330, 65330, 65330, 65330, 65330, 65330 ; From facbf556b848e089ba98e1a003b8b2deaf736a30 Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Mon, 26 Jun 2023 18:49:01 -0600 Subject: [PATCH 27/32] fix to the parameter file --- parameter_files/fates_params_default.cdl | 205 ++++------------------- 1 file changed, 30 insertions(+), 175 deletions(-) diff --git a/parameter_files/fates_params_default.cdl b/parameter_files/fates_params_default.cdl index a3a210d658..d461cb6fbb 100644 --- a/parameter_files/fates_params_default.cdl +++ b/parameter_files/fates_params_default.cdl @@ -1,4 +1,4 @@ -netcdf tmp { +netcdf fates_params_default { dimensions: fates_NCWD = 4 ; fates_history_age_bins = 7 ; @@ -365,7 +365,7 @@ variables: double fates_leaf_stomatal_slope_medlyn(fates_pft) ; fates_leaf_stomatal_slope_medlyn:units = "KPa**0.5" ; fates_leaf_stomatal_slope_medlyn:long_name = "stomatal slope parameter, as per Medlyn" ; - double fates_leaf_vcmax25top(fates_pft) ; + double fates_leaf_vcmax25top(fates_leafage_class, fates_pft) ; fates_leaf_vcmax25top:units = "umol CO2/m^2/s" ; fates_leaf_vcmax25top:long_name = "maximum carboxylation rate of Rub. at 25C, canopy top" ; double fates_leaf_vcmaxha(fates_pft) ; @@ -437,24 +437,15 @@ variables: double fates_phen_cold_size_threshold(fates_pft) ; fates_phen_cold_size_threshold:units = "cm" ; fates_phen_cold_size_threshold:long_name = "the dbh size above which will lead to phenology-related stem and leaf drop" ; - double fates_phen_drought_threshold(fates_pft) ; - fates_phen_drought_threshold:units = "m3/m3 or mm" ; - fates_phen_drought_threshold:long_name = "threshold for drought phenology (or lower threshold for semi-deciduous PFTs); the quantity depends on the sign: if positive, the threshold is volumetric soil moisture (m3/m3). If negative, the threshold is soil matric potentical (mm)" ; double fates_phen_evergreen(fates_pft) ; fates_phen_evergreen:units = "logical flag" ; fates_phen_evergreen:long_name = "Binary flag for evergreen leaf habit" ; double fates_phen_flush_fraction(fates_pft) ; fates_phen_flush_fraction:units = "fraction" ; fates_phen_flush_fraction:long_name = "Upon bud-burst, the maximum fraction of storage carbon used for flushing leaves" ; - double fates_phen_fnrt_drop_fraction(fates_pft) ; - fates_phen_fnrt_drop_fraction:units = "fraction" ; - fates_phen_fnrt_drop_fraction:long_name = "fraction of fine roots to drop during drought/cold" ; - double fates_phen_mindaysoff(fates_pft) ; - fates_phen_mindaysoff:units = "days" ; - fates_phen_mindaysoff:long_name = "day threshold compared against days since leaves abscised (shed)" ; - double fates_phen_moist_threshold(fates_pft) ; - fates_phen_moist_threshold:units = "m3/m3 or mm" ; - fates_phen_moist_threshold:long_name = "upper threshold for drought phenology (only for drought semi-deciduous PFTs); the quantity depends on the sign: if positive, the threshold is volumetric soil moisture (m3/m3). If negative, the threshold is soil matric potentical (mm)" ; + double fates_phen_fnrt_drop_frac(fates_pft) ; + fates_phen_fnrt_drop_frac:units = "fraction" ; + fates_phen_fnrt_drop_frac:long_name = "fraction of fine roots to drop during drought or cold" ; double fates_phen_season_decid(fates_pft) ; fates_phen_season_decid:units = "logical flag" ; fates_phen_season_decid:long_name = "Binary flag for seasonal-deciduous leaf habit" ; @@ -536,60 +527,6 @@ variables: double fates_trim_limit(fates_pft) ; fates_trim_limit:units = "m2/m2" ; fates_trim_limit:long_name = "Arbitrary limit to reductions in leaf area with stress" ; - double fates_trs_repro_alloc_a(fates_pft) ; - fates_trs_repro_alloc_a:units = "fraction" ; - fates_trs_repro_alloc_a:long_name = "shape parameter for sigmoidal function relating dbh to reproductive allocation" ; - double fates_trs_repro_alloc_b(fates_pft) ; - fates_trs_repro_alloc_b:units = "fraction" ; - fates_trs_repro_alloc_b:long_name = "intercept parameter for sigmoidal function relating dbh to reproductive allocation" ; - double fates_trs_repro_frac_seed(fates_pft) ; - fates_trs_repro_frac_seed:units = "fraction" ; - fates_trs_repro_frac_seed:long_name = "fraction of reproductive mass that is seed" ; - double fates_trs_seedling_a_emerg(fates_pft) ; - fates_trs_seedling_a_emerg:units = "day -1" ; - fates_trs_seedling_a_emerg:long_name = "mean fraction of seed bank emerging" ; - double fates_trs_seedling_b_emerg(fates_pft) ; - fates_trs_seedling_b_emerg:units = "day -1" ; - fates_trs_seedling_b_emerg:long_name = "seedling emergence sensitivity to soil moisture" ; - double fates_trs_seedling_background_mort(fates_pft) ; - fates_trs_seedling_background_mort:units = "yr-1" ; - fates_trs_seedling_background_mort:long_name = "background seedling mortality rate" ; - double fates_trs_seedling_h2o_mort_a(fates_pft) ; - fates_trs_seedling_h2o_mort_a:units = "-" ; - fates_trs_seedling_h2o_mort_a:long_name = "coefficient in moisture-based seedling mortality" ; - double fates_trs_seedling_h2o_mort_b(fates_pft) ; - fates_trs_seedling_h2o_mort_b:units = "-" ; - fates_trs_seedling_h2o_mort_b:long_name = "coefficient in moisture-based seedling mortality" ; - double fates_trs_seedling_h2o_mort_c(fates_pft) ; - fates_trs_seedling_h2o_mort_c:units = "-" ; - fates_trs_seedling_h2o_mort_c:long_name = "coefficient in moisture-based seedling mortality" ; - double fates_trs_seedling_light_mort_a(fates_pft) ; - fates_trs_seedling_light_mort_a:units = "-" ; - fates_trs_seedling_light_mort_a:long_name = "light-based seedling mortality coefficient" ; - double fates_trs_seedling_light_mort_b(fates_pft) ; - fates_trs_seedling_light_mort_b:units = "-" ; - fates_trs_seedling_light_mort_b:long_name = "light-based seedling mortality coefficient" ; - double fates_trs_seedling_light_rec_a(fates_pft) ; - fates_trs_seedling_light_rec_a:units = "-" ; - fates_trs_seedling_light_rec_a:long_name = "coefficient in light-based seedling to sapling transition" ; - double fates_trs_seedling_light_rec_b(fates_pft) ; - fates_trs_seedling_light_rec_b:units = "-" ; - fates_trs_seedling_light_rec_b:long_name = "coefficient in light-based seedling to sapling transition" ; - double fates_trs_seedling_mdd_crit(fates_pft) ; - fates_trs_seedling_mdd_crit:units = "mm H2O day" ; - fates_trs_seedling_mdd_crit:long_name = "critical moisture deficit (suction) day accumulation for seedling moisture-based seedling mortality to begin" ; - double fates_trs_seedling_par_crit_germ(fates_pft) ; - fates_trs_seedling_par_crit_germ:units = "MJ m-2 day-1" ; - fates_trs_seedling_par_crit_germ:long_name = "critical light level for germination" ; - double fates_trs_seedling_psi_crit(fates_pft) ; - fates_trs_seedling_psi_crit:units = "mm H2O" ; - fates_trs_seedling_psi_crit:long_name = "critical soil moisture (suction) for seedling stress" ; - double fates_trs_seedling_psi_emerg(fates_pft) ; - fates_trs_seedling_psi_emerg:units = "mm h20 suction" ; - fates_trs_seedling_psi_emerg:long_name = "critical soil moisture for seedling emergence" ; - double fates_trs_seedling_root_depth(fates_pft) ; - fates_trs_seedling_root_depth:units = "m" ; - fates_trs_seedling_root_depth:long_name = "rooting depth of seedlings" ; double fates_turb_displar(fates_pft) ; fates_turb_displar:units = "unitless" ; fates_turb_displar:long_name = "Ratio of displacement height to canopy top height" ; @@ -607,7 +544,7 @@ variables: fates_turnover_fnrt:long_name = "root longevity (alternatively, turnover time)" ; double fates_turnover_leaf(fates_leafage_class, fates_pft) ; fates_turnover_leaf:units = "yr" ; - fates_turnover_leaf:long_name = "Leaf longevity (ie turnover timescale). For drought-deciduous PFTs, this also indicates the maximum length of the growing (i.e., leaves on) season." ; + fates_turnover_leaf:long_name = "Leaf longevity (ie turnover timescale)" ; double fates_turnover_senleaf_fdrought(fates_pft) ; fates_turnover_senleaf_fdrought:units = "unitless[0-1]" ; fates_turnover_senleaf_fdrought:long_name = "multiplication factor for leaf longevity of senescent leaves during drought" ; @@ -818,6 +755,12 @@ variables: double fates_phen_coldtemp ; fates_phen_coldtemp:units = "degrees C" ; fates_phen_coldtemp:long_name = "vegetation temperature exceedance that flags a cold-day for leaf-drop" ; + double fates_phen_drought_model ; + fates_phen_drought_model:units = "unitless" ; + fates_phen_drought_model:long_name = "which method to use for drought phenology: 0 - FATES default; 1 - Semi-deciduous (ED2-like)" ; + double fates_phen_drought_threshold ; + fates_phen_drought_threshold:units = "m3/m3 or mm" ; + fates_phen_drought_threshold:long_name = "threshold for drought phenology (or lower threshold when fates_phen_drought_model = 1); the quantity depends on the sign: if positive, the threshold is volumetric soil moisture (m3/m3). If negative, the threshold is soil matric potentical (mm)" ; double fates_phen_gddthresh_a ; fates_phen_gddthresh_a:units = "none" ; fates_phen_gddthresh_a:long_name = "GDD accumulation function, intercept parameter: gdd_thesh = a + b exp(c*ncd)" ; @@ -827,9 +770,15 @@ variables: double fates_phen_gddthresh_c ; fates_phen_gddthresh_c:units = "none" ; fates_phen_gddthresh_c:long_name = "GDD accumulation function, exponent parameter: gdd_thesh = a + b exp(c*ncd)" ; + double fates_phen_mindaysoff ; + fates_phen_mindaysoff:units = "days" ; + fates_phen_mindaysoff:long_name = "day threshold compared against days since leaves became off-allometry" ; double fates_phen_mindayson ; fates_phen_mindayson:units = "days" ; fates_phen_mindayson:long_name = "day threshold compared against days since leaves became on-allometry" ; + double fates_phen_moist_threshold ; + fates_phen_moist_threshold:units = "m3/m3 or mm" ; + fates_phen_moist_threshold:long_name = "upper threshold for drought phenology (only for fates_phen_drought_model=1); the quantity depends on the sign: if positive, the threshold is volumetric soil moisture (m3/m3). If negative, the threshold is soil matric potentical (mm)" ; double fates_phen_ncolddayslim ; fates_phen_ncolddayslim:units = "days" ; fates_phen_ncolddayslim:long_name = "day threshold exceedance for temperature leaf-drop" ; @@ -839,27 +788,9 @@ variables: double fates_q10_mr ; fates_q10_mr:units = "unitless" ; fates_q10_mr:long_name = "Q10 for maintenance respiration" ; - double fates_rad_model ; - fates_rad_model:units = "unitless" ; - fates_rad_model:long_name = "switch designating the model for canopy radiation, 1 = Norman, 2 = Two-stream (experimental)" ; - double fates_regeneration_model ; - fates_regeneration_model:units = "-" ; - fates_regeneration_model:long_name = "switch for choosing between FATES\'s: 1) default regeneration scheme , 2) the Tree Recruitment Scheme (Hanbury-Brown et al., 2022), or (3) the Tree Recruitment Scheme without seedling dynamics" ; double fates_soil_salinity ; fates_soil_salinity:units = "ppt" ; fates_soil_salinity:long_name = "soil salinity used for model when not coupled to dynamic soil salinity" ; - double fates_trs_seedling2sap_par_timescale ; - fates_trs_seedling2sap_par_timescale:units = "days" ; - fates_trs_seedling2sap_par_timescale:long_name = "Length of the window for the exponential moving average of par at the seedling layer used to calculate seedling to sapling transition rates" ; - double fates_trs_seedling_emerg_h2o_timescale ; - fates_trs_seedling_emerg_h2o_timescale:units = "days" ; - fates_trs_seedling_emerg_h2o_timescale:long_name = "Length of the window for the exponential moving average of smp used to calculate seedling emergence" ; - double fates_trs_seedling_mdd_timescale ; - fates_trs_seedling_mdd_timescale:units = "days" ; - fates_trs_seedling_mdd_timescale:long_name = "Length of the window for the exponential moving average of moisture deficit days used to calculate seedling mortality" ; - double fates_trs_seedling_mort_par_timescale ; - fates_trs_seedling_mort_par_timescale:units = "days" ; - fates_trs_seedling_mort_par_timescale:long_name = "Length of the window for the exponential moving average of par at the seedling layer used to calculate seedling mortality" ; double fates_vai_top_bin_width ; fates_vai_top_bin_width:units = "m2/m2" ; fates_vai_top_bin_width:long_name = "width in VAI units of uppermost leaf+stem layer scattering element in each canopy layer" ; @@ -926,7 +857,7 @@ data: 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 ; - fates_alloc_storage_cushion = 1.2, 1.2, 1.2, 1.2, 2.4, 1.2, 1.2, 2.4, 1.2, + fates_alloc_storage_cushion = 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2 ; fates_alloc_store_priority_frac = 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, @@ -1265,7 +1196,8 @@ data: fates_leaf_stomatal_slope_medlyn = 4.1, 2.3, 2.3, 4.1, 4.4, 4.4, 4.7, 4.7, 4.7, 2.2, 5.3, 1.6 ; - fates_leaf_vcmax25top = 50, 62, 39, 61, 58, 58, 62, 54, 54, 78, 78, 78 ; + fates_leaf_vcmax25top = + 50, 62, 39, 61, 41, 58, 62, 54, 54, 78, 78, 78 ; fates_leaf_vcmaxha = 65330, 65330, 65330, 65330, 65330, 65330, 65330, 65330, 65330, 65330, 65330, 65330 ; @@ -1330,23 +1262,12 @@ data: fates_phen_cold_size_threshold = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; - fates_phen_drought_threshold = -152957.4, -152957.4, -152957.4, -152957.4, - -152957.4, -152957.4, -152957.4, -152957.4, -152957.4, -152957.4, - -152957.4, -152957.4 ; - fates_phen_evergreen = 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 ; fates_phen_flush_fraction = _, _, 0.5, _, 0.5, 0.5, _, 0.5, 0.5, 0.5, 0.5, 0.5 ; - fates_phen_fnrt_drop_fraction = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; - - fates_phen_mindaysoff = 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, - 100, 100 ; - - fates_phen_moist_threshold = -122365.9, -122365.9, -122365.9, -122365.9, - -122365.9, -122365.9, -122365.9, -122365.9, -122365.9, -122365.9, - -122365.9, -122365.9 ; + fates_phen_fnrt_drop_frac = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; fates_phen_season_decid = 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0 ; @@ -1437,68 +1358,6 @@ data: fates_trim_limit = 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3 ; - fates_trs_repro_alloc_a = 0.0049, 0.0049, 0.0049, 0.0049, 0.0049, 0.0049, - 0.0049, 0.0049, 0.0049, 0.0049, 0.0049, 0.0049 ; - - fates_trs_repro_alloc_b = -2.6171, -2.6171, -2.6171, -2.6171, -2.6171, - -2.6171, -2.6171, -2.6171, -2.6171, -2.6171, -2.6171, -2.6171 ; - - fates_trs_repro_frac_seed = 0.24, 0.24, 0.24, 0.24, 0.24, 0.24, 0.24, 0.24, - 0.24, 0.24, 0.24, 0.24 ; - - fates_trs_seedling_a_emerg = 0.0003, 0.0003, 0.0003, 0.0003, 0.0003, 0.0003, - 0.0003, 0.0003, 0.0003, 0.0003, 0.0003, 0.0003 ; - - fates_trs_seedling_b_emerg = 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, - 1.2, 1.2, 1.2 ; - - fates_trs_seedling_background_mort = 0.1085371, 0.1085371, 0.1085371, - 0.1085371, 0.1085371, 0.1085371, 0.1085371, 0.1085371, 0.1085371, - 0.1085371, 0.1085371, 0.1085371 ; - - fates_trs_seedling_h2o_mort_a = 4.070565e-17, 4.070565e-17, 4.070565e-17, - 4.070565e-17, 4.070565e-17, 4.070565e-17, 4.070565e-17, 4.070565e-17, - 4.070565e-17, 4.070565e-17, 4.070565e-17, 4.070565e-17 ; - - fates_trs_seedling_h2o_mort_b = -6.390757e-11, -6.390757e-11, -6.390757e-11, - -6.390757e-11, -6.390757e-11, -6.390757e-11, -6.390757e-11, - -6.390757e-11, -6.390757e-11, -6.390757e-11, -6.390757e-11, -6.390757e-11 ; - - fates_trs_seedling_h2o_mort_c = 1.268992e-05, 1.268992e-05, 1.268992e-05, - 1.268992e-05, 1.268992e-05, 1.268992e-05, 1.268992e-05, 1.268992e-05, - 1.268992e-05, 1.268992e-05, 1.268992e-05, 1.268992e-05 ; - - fates_trs_seedling_light_mort_a = -0.009897694, -0.009897694, -0.009897694, - -0.009897694, -0.009897694, -0.009897694, -0.009897694, -0.009897694, - -0.009897694, -0.009897694, -0.009897694, -0.009897694 ; - - fates_trs_seedling_light_mort_b = -7.154063, -7.154063, -7.154063, - -7.154063, -7.154063, -7.154063, -7.154063, -7.154063, -7.154063, - -7.154063, -7.154063, -7.154063 ; - - fates_trs_seedling_light_rec_a = 0.007, 0.007, 0.007, 0.007, 0.007, 0.007, - 0.007, 0.007, 0.007, 0.007, 0.007, 0.007 ; - - fates_trs_seedling_light_rec_b = 0.8615, 0.8615, 0.8615, 0.8615, 0.8615, - 0.8615, 0.8615, 0.8615, 0.8615, 0.8615, 0.8615, 0.8615 ; - - fates_trs_seedling_mdd_crit = 1400000, 1400000, 1400000, 1400000, 1400000, - 1400000, 1400000, 1400000, 1400000, 1400000, 1400000, 1400000 ; - - fates_trs_seedling_par_crit_germ = 0.656, 0.656, 0.656, 0.656, 0.656, 0.656, - 0.656, 0.656, 0.656, 0.656, 0.656, 0.656 ; - - fates_trs_seedling_psi_crit = -251995.7, -251995.7, -251995.7, -251995.7, - -251995.7, -251995.7, -251995.7, -251995.7, -251995.7, -251995.7, - -251995.7, -251995.7 ; - - fates_trs_seedling_psi_emerg = -15744.65, -15744.65, -15744.65, -15744.65, - -15744.65, -15744.65, -15744.65, -15744.65, -15744.65, -15744.65, - -15744.65, -15744.65 ; - - fates_trs_seedling_root_depth = 0.06, 0.06, 0.06, 0.06, 0.06, 0.06, 0.06, - 0.06, 0.06, 0.06, 0.06, 0.06 ; - fates_turb_displar = 0.67, 0.67, 0.67, 0.67, 0.67, 0.67, 0.67, 0.67, 0.67, 0.67, 0.67, 0.67 ; @@ -1670,34 +1529,30 @@ data: fates_phen_coldtemp = 7.5 ; + fates_phen_drought_model = 0 ; + + fates_phen_drought_threshold = 0.15 ; + fates_phen_gddthresh_a = -68 ; fates_phen_gddthresh_b = 638 ; fates_phen_gddthresh_c = -0.01 ; + fates_phen_mindaysoff = 100 ; + fates_phen_mindayson = 90 ; + fates_phen_moist_threshold = 0.18 ; + fates_phen_ncolddayslim = 5 ; fates_q10_froz = 1.5 ; fates_q10_mr = 1.5 ; - fates_rad_model = 1 ; - - fates_regeneration_model = 1 ; - fates_soil_salinity = 0.4 ; - fates_trs_seedling2sap_par_timescale = 32 ; - - fates_trs_seedling_emerg_h2o_timescale = 7 ; - - fates_trs_seedling_mdd_timescale = 126 ; - - fates_trs_seedling_mort_par_timescale = 32 ; - fates_vai_top_bin_width = 1 ; fates_vai_width_increase_factor = 1 ; From 59f56ee08e8e177db9e05737664b8e719b4e9626 Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Tue, 27 Jun 2023 11:39:26 -0400 Subject: [PATCH 28/32] reapplied parameter update from xml, something got lost in a merge --- parameter_files/fates_params_default.cdl | 198 ++++++++++++++++++++--- 1 file changed, 172 insertions(+), 26 deletions(-) diff --git a/parameter_files/fates_params_default.cdl b/parameter_files/fates_params_default.cdl index 2ca43a0672..f1521d70d6 100644 --- a/parameter_files/fates_params_default.cdl +++ b/parameter_files/fates_params_default.cdl @@ -437,15 +437,24 @@ variables: double fates_phen_cold_size_threshold(fates_pft) ; fates_phen_cold_size_threshold:units = "cm" ; fates_phen_cold_size_threshold:long_name = "the dbh size above which will lead to phenology-related stem and leaf drop" ; + double fates_phen_drought_threshold(fates_pft) ; + fates_phen_drought_threshold:units = "m3/m3 or mm" ; + fates_phen_drought_threshold:long_name = "threshold for drought phenology (or lower threshold for semi-deciduous PFTs); the quantity depends on the sign: if positive, the threshold is volumetric soil moisture (m3/m3). If negative, the threshold is soil matric potentical (mm)" ; double fates_phen_evergreen(fates_pft) ; fates_phen_evergreen:units = "logical flag" ; fates_phen_evergreen:long_name = "Binary flag for evergreen leaf habit" ; double fates_phen_flush_fraction(fates_pft) ; fates_phen_flush_fraction:units = "fraction" ; fates_phen_flush_fraction:long_name = "Upon bud-burst, the maximum fraction of storage carbon used for flushing leaves" ; - double fates_phen_fnrt_drop_frac(fates_pft) ; - fates_phen_fnrt_drop_frac:units = "fraction" ; - fates_phen_fnrt_drop_frac:long_name = "fraction of fine roots to drop during drought or cold" ; + double fates_phen_fnrt_drop_fraction(fates_pft) ; + fates_phen_fnrt_drop_fraction:units = "fraction" ; + fates_phen_fnrt_drop_fraction:long_name = "fraction of fine roots to drop during drought/cold" ; + double fates_phen_mindaysoff(fates_pft) ; + fates_phen_mindaysoff:units = "days" ; + fates_phen_mindaysoff:long_name = "day threshold compared against days since leaves abscised (shed)" ; + double fates_phen_moist_threshold(fates_pft) ; + fates_phen_moist_threshold:units = "m3/m3 or mm" ; + fates_phen_moist_threshold:long_name = "upper threshold for drought phenology (only for drought semi-deciduous PFTs); the quantity depends on the sign: if positive, the threshold is volumetric soil moisture (m3/m3). If negative, the threshold is soil matric potentical (mm)" ; double fates_phen_season_decid(fates_pft) ; fates_phen_season_decid:units = "logical flag" ; fates_phen_season_decid:long_name = "Binary flag for seasonal-deciduous leaf habit" ; @@ -527,6 +536,60 @@ variables: double fates_trim_limit(fates_pft) ; fates_trim_limit:units = "m2/m2" ; fates_trim_limit:long_name = "Arbitrary limit to reductions in leaf area with stress" ; + double fates_trs_repro_alloc_a(fates_pft) ; + fates_trs_repro_alloc_a:units = "fraction" ; + fates_trs_repro_alloc_a:long_name = "shape parameter for sigmoidal function relating dbh to reproductive allocation" ; + double fates_trs_repro_alloc_b(fates_pft) ; + fates_trs_repro_alloc_b:units = "fraction" ; + fates_trs_repro_alloc_b:long_name = "intercept parameter for sigmoidal function relating dbh to reproductive allocation" ; + double fates_trs_repro_frac_seed(fates_pft) ; + fates_trs_repro_frac_seed:units = "fraction" ; + fates_trs_repro_frac_seed:long_name = "fraction of reproductive mass that is seed" ; + double fates_trs_seedling_a_emerg(fates_pft) ; + fates_trs_seedling_a_emerg:units = "day -1" ; + fates_trs_seedling_a_emerg:long_name = "mean fraction of seed bank emerging" ; + double fates_trs_seedling_b_emerg(fates_pft) ; + fates_trs_seedling_b_emerg:units = "day -1" ; + fates_trs_seedling_b_emerg:long_name = "seedling emergence sensitivity to soil moisture" ; + double fates_trs_seedling_background_mort(fates_pft) ; + fates_trs_seedling_background_mort:units = "yr-1" ; + fates_trs_seedling_background_mort:long_name = "background seedling mortality rate" ; + double fates_trs_seedling_h2o_mort_a(fates_pft) ; + fates_trs_seedling_h2o_mort_a:units = "-" ; + fates_trs_seedling_h2o_mort_a:long_name = "coefficient in moisture-based seedling mortality" ; + double fates_trs_seedling_h2o_mort_b(fates_pft) ; + fates_trs_seedling_h2o_mort_b:units = "-" ; + fates_trs_seedling_h2o_mort_b:long_name = "coefficient in moisture-based seedling mortality" ; + double fates_trs_seedling_h2o_mort_c(fates_pft) ; + fates_trs_seedling_h2o_mort_c:units = "-" ; + fates_trs_seedling_h2o_mort_c:long_name = "coefficient in moisture-based seedling mortality" ; + double fates_trs_seedling_light_mort_a(fates_pft) ; + fates_trs_seedling_light_mort_a:units = "-" ; + fates_trs_seedling_light_mort_a:long_name = "light-based seedling mortality coefficient" ; + double fates_trs_seedling_light_mort_b(fates_pft) ; + fates_trs_seedling_light_mort_b:units = "-" ; + fates_trs_seedling_light_mort_b:long_name = "light-based seedling mortality coefficient" ; + double fates_trs_seedling_light_rec_a(fates_pft) ; + fates_trs_seedling_light_rec_a:units = "-" ; + fates_trs_seedling_light_rec_a:long_name = "coefficient in light-based seedling to sapling transition" ; + double fates_trs_seedling_light_rec_b(fates_pft) ; + fates_trs_seedling_light_rec_b:units = "-" ; + fates_trs_seedling_light_rec_b:long_name = "coefficient in light-based seedling to sapling transition" ; + double fates_trs_seedling_mdd_crit(fates_pft) ; + fates_trs_seedling_mdd_crit:units = "mm H2O day" ; + fates_trs_seedling_mdd_crit:long_name = "critical moisture deficit (suction) day accumulation for seedling moisture-based seedling mortality to begin" ; + double fates_trs_seedling_par_crit_germ(fates_pft) ; + fates_trs_seedling_par_crit_germ:units = "MJ m-2 day-1" ; + fates_trs_seedling_par_crit_germ:long_name = "critical light level for germination" ; + double fates_trs_seedling_psi_crit(fates_pft) ; + fates_trs_seedling_psi_crit:units = "mm H2O" ; + fates_trs_seedling_psi_crit:long_name = "critical soil moisture (suction) for seedling stress" ; + double fates_trs_seedling_psi_emerg(fates_pft) ; + fates_trs_seedling_psi_emerg:units = "mm h20 suction" ; + fates_trs_seedling_psi_emerg:long_name = "critical soil moisture for seedling emergence" ; + double fates_trs_seedling_root_depth(fates_pft) ; + fates_trs_seedling_root_depth:units = "m" ; + fates_trs_seedling_root_depth:long_name = "rooting depth of seedlings" ; double fates_turb_displar(fates_pft) ; fates_turb_displar:units = "unitless" ; fates_turb_displar:long_name = "Ratio of displacement height to canopy top height" ; @@ -544,7 +607,7 @@ variables: fates_turnover_fnrt:long_name = "root longevity (alternatively, turnover time)" ; double fates_turnover_leaf(fates_leafage_class, fates_pft) ; fates_turnover_leaf:units = "yr" ; - fates_turnover_leaf:long_name = "Leaf longevity (ie turnover timescale)" ; + fates_turnover_leaf:long_name = "Leaf longevity (ie turnover timescale). For drought-deciduous PFTs, this also indicates the maximum length of the growing (i.e., leaves on) season." ; double fates_turnover_senleaf_fdrought(fates_pft) ; fates_turnover_senleaf_fdrought:units = "unitless[0-1]" ; fates_turnover_senleaf_fdrought:long_name = "multiplication factor for leaf longevity of senescent leaves during drought" ; @@ -755,12 +818,6 @@ variables: double fates_phen_coldtemp ; fates_phen_coldtemp:units = "degrees C" ; fates_phen_coldtemp:long_name = "vegetation temperature exceedance that flags a cold-day for leaf-drop" ; - double fates_phen_drought_model ; - fates_phen_drought_model:units = "unitless" ; - fates_phen_drought_model:long_name = "which method to use for drought phenology: 0 - FATES default; 1 - Semi-deciduous (ED2-like)" ; - double fates_phen_drought_threshold ; - fates_phen_drought_threshold:units = "m3/m3 or mm" ; - fates_phen_drought_threshold:long_name = "threshold for drought phenology (or lower threshold when fates_phen_drought_model = 1); the quantity depends on the sign: if positive, the threshold is volumetric soil moisture (m3/m3). If negative, the threshold is soil matric potentical (mm)" ; double fates_phen_gddthresh_a ; fates_phen_gddthresh_a:units = "none" ; fates_phen_gddthresh_a:long_name = "GDD accumulation function, intercept parameter: gdd_thesh = a + b exp(c*ncd)" ; @@ -770,15 +827,9 @@ variables: double fates_phen_gddthresh_c ; fates_phen_gddthresh_c:units = "none" ; fates_phen_gddthresh_c:long_name = "GDD accumulation function, exponent parameter: gdd_thesh = a + b exp(c*ncd)" ; - double fates_phen_mindaysoff ; - fates_phen_mindaysoff:units = "days" ; - fates_phen_mindaysoff:long_name = "day threshold compared against days since leaves became off-allometry" ; double fates_phen_mindayson ; fates_phen_mindayson:units = "days" ; fates_phen_mindayson:long_name = "day threshold compared against days since leaves became on-allometry" ; - double fates_phen_moist_threshold ; - fates_phen_moist_threshold:units = "m3/m3 or mm" ; - fates_phen_moist_threshold:long_name = "upper threshold for drought phenology (only for fates_phen_drought_model=1); the quantity depends on the sign: if positive, the threshold is volumetric soil moisture (m3/m3). If negative, the threshold is soil matric potentical (mm)" ; double fates_phen_ncolddayslim ; fates_phen_ncolddayslim:units = "days" ; fates_phen_ncolddayslim:long_name = "day threshold exceedance for temperature leaf-drop" ; @@ -788,9 +839,27 @@ variables: double fates_q10_mr ; fates_q10_mr:units = "unitless" ; fates_q10_mr:long_name = "Q10 for maintenance respiration" ; + double fates_rad_model ; + fates_rad_model:units = "unitless" ; + fates_rad_model:long_name = "switch designating the model for canopy radiation, 1 = Norman, 2 = Two-stream (experimental)" ; + double fates_regeneration_model ; + fates_regeneration_model:units = "-" ; + fates_regeneration_model:long_name = "switch for choosing between FATES\'s: 1) default regeneration scheme , 2) the Tree Recruitment Scheme (Hanbury-Brown et al., 2022), or (3) the Tree Recruitment Scheme without seedling dynamics" ; double fates_soil_salinity ; fates_soil_salinity:units = "ppt" ; fates_soil_salinity:long_name = "soil salinity used for model when not coupled to dynamic soil salinity" ; + double fates_trs_seedling2sap_par_timescale ; + fates_trs_seedling2sap_par_timescale:units = "days" ; + fates_trs_seedling2sap_par_timescale:long_name = "Length of the window for the exponential moving average of par at the seedling layer used to calculate seedling to sapling transition rates" ; + double fates_trs_seedling_emerg_h2o_timescale ; + fates_trs_seedling_emerg_h2o_timescale:units = "days" ; + fates_trs_seedling_emerg_h2o_timescale:long_name = "Length of the window for the exponential moving average of smp used to calculate seedling emergence" ; + double fates_trs_seedling_mdd_timescale ; + fates_trs_seedling_mdd_timescale:units = "days" ; + fates_trs_seedling_mdd_timescale:long_name = "Length of the window for the exponential moving average of moisture deficit days used to calculate seedling mortality" ; + double fates_trs_seedling_mort_par_timescale ; + fates_trs_seedling_mort_par_timescale:units = "days" ; + fates_trs_seedling_mort_par_timescale:long_name = "Length of the window for the exponential moving average of par at the seedling layer used to calculate seedling mortality" ; double fates_vai_top_bin_width ; fates_vai_top_bin_width:units = "m2/m2" ; fates_vai_top_bin_width:long_name = "width in VAI units of uppermost leaf+stem layer scattering element in each canopy layer" ; @@ -857,7 +926,7 @@ data: 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 ; - fates_alloc_storage_cushion = 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, + fates_alloc_storage_cushion = 1.2, 1.2, 1.2, 1.2, 2.4, 1.2, 1.2, 2.4, 1.2, 1.2, 1.2, 1.2 ; fates_alloc_store_priority_frac = 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, @@ -1262,12 +1331,23 @@ data: fates_phen_cold_size_threshold = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; + fates_phen_drought_threshold = -152957.4, -152957.4, -152957.4, -152957.4, + -152957.4, -152957.4, -152957.4, -152957.4, -152957.4, -152957.4, + -152957.4, -152957.4 ; + fates_phen_evergreen = 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 ; fates_phen_flush_fraction = _, _, 0.5, _, 0.5, 0.5, _, 0.5, 0.5, 0.5, 0.5, 0.5 ; - fates_phen_fnrt_drop_frac = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; + fates_phen_fnrt_drop_fraction = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; + + fates_phen_mindaysoff = 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, + 100, 100 ; + + fates_phen_moist_threshold = -122365.9, -122365.9, -122365.9, -122365.9, + -122365.9, -122365.9, -122365.9, -122365.9, -122365.9, -122365.9, + -122365.9, -122365.9 ; fates_phen_season_decid = 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0 ; @@ -1358,6 +1438,68 @@ data: fates_trim_limit = 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3 ; + fates_trs_repro_alloc_a = 0.0049, 0.0049, 0.0049, 0.0049, 0.0049, 0.0049, + 0.0049, 0.0049, 0.0049, 0.0049, 0.0049, 0.0049 ; + + fates_trs_repro_alloc_b = -2.6171, -2.6171, -2.6171, -2.6171, -2.6171, + -2.6171, -2.6171, -2.6171, -2.6171, -2.6171, -2.6171, -2.6171 ; + + fates_trs_repro_frac_seed = 0.24, 0.24, 0.24, 0.24, 0.24, 0.24, 0.24, 0.24, + 0.24, 0.24, 0.24, 0.24 ; + + fates_trs_seedling_a_emerg = 0.0003, 0.0003, 0.0003, 0.0003, 0.0003, 0.0003, + 0.0003, 0.0003, 0.0003, 0.0003, 0.0003, 0.0003 ; + + fates_trs_seedling_b_emerg = 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, + 1.2, 1.2, 1.2 ; + + fates_trs_seedling_background_mort = 0.1085371, 0.1085371, 0.1085371, + 0.1085371, 0.1085371, 0.1085371, 0.1085371, 0.1085371, 0.1085371, + 0.1085371, 0.1085371, 0.1085371 ; + + fates_trs_seedling_h2o_mort_a = 4.070565e-17, 4.070565e-17, 4.070565e-17, + 4.070565e-17, 4.070565e-17, 4.070565e-17, 4.070565e-17, 4.070565e-17, + 4.070565e-17, 4.070565e-17, 4.070565e-17, 4.070565e-17 ; + + fates_trs_seedling_h2o_mort_b = -6.390757e-11, -6.390757e-11, -6.390757e-11, + -6.390757e-11, -6.390757e-11, -6.390757e-11, -6.390757e-11, + -6.390757e-11, -6.390757e-11, -6.390757e-11, -6.390757e-11, -6.390757e-11 ; + + fates_trs_seedling_h2o_mort_c = 1.268992e-05, 1.268992e-05, 1.268992e-05, + 1.268992e-05, 1.268992e-05, 1.268992e-05, 1.268992e-05, 1.268992e-05, + 1.268992e-05, 1.268992e-05, 1.268992e-05, 1.268992e-05 ; + + fates_trs_seedling_light_mort_a = -0.009897694, -0.009897694, -0.009897694, + -0.009897694, -0.009897694, -0.009897694, -0.009897694, -0.009897694, + -0.009897694, -0.009897694, -0.009897694, -0.009897694 ; + + fates_trs_seedling_light_mort_b = -7.154063, -7.154063, -7.154063, + -7.154063, -7.154063, -7.154063, -7.154063, -7.154063, -7.154063, + -7.154063, -7.154063, -7.154063 ; + + fates_trs_seedling_light_rec_a = 0.007, 0.007, 0.007, 0.007, 0.007, 0.007, + 0.007, 0.007, 0.007, 0.007, 0.007, 0.007 ; + + fates_trs_seedling_light_rec_b = 0.8615, 0.8615, 0.8615, 0.8615, 0.8615, + 0.8615, 0.8615, 0.8615, 0.8615, 0.8615, 0.8615, 0.8615 ; + + fates_trs_seedling_mdd_crit = 1400000, 1400000, 1400000, 1400000, 1400000, + 1400000, 1400000, 1400000, 1400000, 1400000, 1400000, 1400000 ; + + fates_trs_seedling_par_crit_germ = 0.656, 0.656, 0.656, 0.656, 0.656, 0.656, + 0.656, 0.656, 0.656, 0.656, 0.656, 0.656 ; + + fates_trs_seedling_psi_crit = -251995.7, -251995.7, -251995.7, -251995.7, + -251995.7, -251995.7, -251995.7, -251995.7, -251995.7, -251995.7, + -251995.7, -251995.7 ; + + fates_trs_seedling_psi_emerg = -15744.65, -15744.65, -15744.65, -15744.65, + -15744.65, -15744.65, -15744.65, -15744.65, -15744.65, -15744.65, + -15744.65, -15744.65 ; + + fates_trs_seedling_root_depth = 0.06, 0.06, 0.06, 0.06, 0.06, 0.06, 0.06, + 0.06, 0.06, 0.06, 0.06, 0.06 ; + fates_turb_displar = 0.67, 0.67, 0.67, 0.67, 0.67, 0.67, 0.67, 0.67, 0.67, 0.67, 0.67, 0.67 ; @@ -1529,30 +1671,34 @@ data: fates_phen_coldtemp = 7.5 ; - fates_phen_drought_model = 0 ; - - fates_phen_drought_threshold = 0.15 ; - fates_phen_gddthresh_a = -68 ; fates_phen_gddthresh_b = 638 ; fates_phen_gddthresh_c = -0.01 ; - fates_phen_mindaysoff = 100 ; - fates_phen_mindayson = 90 ; - fates_phen_moist_threshold = 0.18 ; - fates_phen_ncolddayslim = 5 ; fates_q10_froz = 1.5 ; fates_q10_mr = 1.5 ; + fates_rad_model = 1 ; + + fates_regeneration_model = 1 ; + fates_soil_salinity = 0.4 ; + fates_trs_seedling2sap_par_timescale = 32 ; + + fates_trs_seedling_emerg_h2o_timescale = 7 ; + + fates_trs_seedling_mdd_timescale = 126 ; + + fates_trs_seedling_mort_par_timescale = 32 ; + fates_vai_top_bin_width = 1 ; fates_vai_width_increase_factor = 1 ; From e4cf214b99f4ed7ad5bc5c47be84d4a3ad120498 Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Tue, 27 Jun 2023 19:20:22 -0600 Subject: [PATCH 29/32] provisions for frozen/arid conditions on drought deciduous suction triggers --- biogeochem/EDPhysiologyMod.F90 | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/biogeochem/EDPhysiologyMod.F90 b/biogeochem/EDPhysiologyMod.F90 index b92c330d2b..d0d66b219b 100644 --- a/biogeochem/EDPhysiologyMod.F90 +++ b/biogeochem/EDPhysiologyMod.F90 @@ -898,7 +898,7 @@ subroutine phenology( currentSite, bc_in ) use EDParamsMod, only : ED_val_phen_mindayson use EDParamsMod, only : ED_val_phen_ncolddayslim use EDParamsMod, only : ED_val_phen_coldtemp - + use EDBtranMod, only : check_layer_water ! ! !ARGUMENTS: type(ed_site_type), intent(inout), target :: currentSite @@ -913,6 +913,7 @@ subroutine phenology( currentSite, bc_in ) integer :: i_wmem ! Loop counter for water mem days integer :: i_tmem ! Loop counter for veg temp mem days integer :: ipft ! plant functional type index + integer :: j ! Soil layer index real(r8) :: mean_10day_liqvol ! mean soil liquid volume over last 10 days [m3/m3] real(r8) :: mean_10day_smp ! mean soil matric potential over last 10 days [mm] real(r8) :: leaf_c ! leaf carbon [kg] @@ -1183,12 +1184,25 @@ subroutine phenology( currentSite, bc_in ) ! Set the memory to be the weighted average of the soil properties, using the ! root fraction of each layer (except the topmost one) as the weighting factor. + currentSite%liqvol_memory(1,ipft) = sum( bc_in%h2o_liqvol_sl (2:nlevroot) * & currentSite%rootfrac_scr(2:nlevroot) ) / & - rootfrac_notop - currentSite%smp_memory (1,ipft) = sum( bc_in%smp_sl (2:nlevroot) * & - currentSite%rootfrac_scr(2:nlevroot) ) / & - rootfrac_notop + rootfrac_notop + currentSite%smp_memory (1,ipft) = 0._r8 + do j = 2,nlevroot + if(check_layer_water(bc_in%h2o_liqvol_sl(j),bc_in%tempk_sl(j)) ) then + currentSite%smp_memory (1,ipft) = currentSite%smp_memory (1,ipft) + & + bc_in%smp_sl (j) * & + currentSite%rootfrac_scr(j) / & + rootfrac_notop + else + ! Nominal extreme suction for frozen or unreasonably dry soil + currentSite%smp_memory (1,ipft) = currentSite%smp_memory (1,ipft) + & + -10000._r8* & + currentSite%rootfrac_scr(j) / & + rootfrac_notop + end if + end do ! Calculate the mean soil moisture ( liquid volume (m3/m3) and matric potential (mm)) ! over the last 10 days From 8d2d76585f97e6a38994afbf3bde47f5540a29a6 Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Tue, 27 Jun 2023 21:28:37 -0400 Subject: [PATCH 30/32] Updating parameter file --- parameter_files/archive/api25.4.0_041023_pr958.xml | 14 ++++++++++++++ parameter_files/fates_params_default.cdl | 12 ++++++------ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/parameter_files/archive/api25.4.0_041023_pr958.xml b/parameter_files/archive/api25.4.0_041023_pr958.xml index 4c1e7d673a..5ad6134ffe 100644 --- a/parameter_files/archive/api25.4.0_041023_pr958.xml +++ b/parameter_files/archive/api25.4.0_041023_pr958.xml @@ -26,6 +26,20 @@ fates_params_default.cdl 1,2,3,4,5,6,7,8,9,10,11,12 + + maintresp_reduction_upthresh + fates_pft + unitless (0-1) + upper threshold for storage biomass (relative to leaf biomass) above which MR is not reduced + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 + + + fates_mort_upthresh_cstarvation + fates_pft + unitless + threshold for storage biomass (relative to target leaf biomass) above which carbon starvation is zero + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 + fates_phen_fnrt_drop_fraction fraction of fine roots to drop during drought/cold diff --git a/parameter_files/fates_params_default.cdl b/parameter_files/fates_params_default.cdl index 95fdaecb86..aeb33a74b8 100644 --- a/parameter_files/fates_params_default.cdl +++ b/parameter_files/fates_params_default.cdl @@ -1,4 +1,4 @@ -netcdf fates_params_default { +netcdf tmp { dimensions: fates_NCWD = 4 ; fates_history_age_bins = 7 ; @@ -389,9 +389,6 @@ variables: double fates_maintresp_reduction_intercept(fates_pft) ; fates_maintresp_reduction_intercept:units = "unitless (0-1)" ; fates_maintresp_reduction_intercept:long_name = "intercept of MR reduction as f(carbon storage), 0=no throttling, 1=max throttling" ; - double fates_maintresp_reduction_upthresh(fates_pft) ; - fates_maintresp_reduction_upthresh:units = "unitless (0-1)" ; - fates_maintresp_reduction_upthresh:long_name = "upper threshold for storage biomass (relative to leaf biomass) above which MR is not reduced" ; double fates_mort_bmort(fates_pft) ; fates_mort_bmort:units = "1/yr" ; fates_mort_bmort:long_name = "background mortality rate" ; @@ -623,6 +620,9 @@ variables: double fates_woody(fates_pft) ; fates_woody:units = "logical flag" ; fates_woody:long_name = "Binary woody lifeform flag" ; + double maintresp_reduction_upthresh(fates_pft) ; + maintresp_reduction_upthresh:units = "unitless (0-1)" ; + maintresp_reduction_upthresh:long_name = "upper threshold for storage biomass (relative to leaf biomass) above which MR is not reduced" ; double fates_hlm_pft_map(fates_hlm_pftno, fates_pft) ; fates_hlm_pft_map:units = "area fraction" ; fates_hlm_pft_map:long_name = "In fixed biogeog mode, fraction of HLM area associated with each FATES PFT" ; @@ -1295,8 +1295,6 @@ data: fates_maintresp_reduction_intercept = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ; - fates_maintresp_reduction_upthresh = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ; - fates_mort_bmort = 0.014, 0.014, 0.014, 0.014, 0.014, 0.014, 0.014, 0.014, 0.014, 0.014, 0.014, 0.014 ; @@ -1533,6 +1531,8 @@ data: fates_woody = 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 ; + maintresp_reduction_upthresh = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ; + fates_hlm_pft_map = 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, From f87ea87757c01e96a979ac588f513f15c9ae1566 Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Tue, 27 Jun 2023 22:57:27 -0400 Subject: [PATCH 31/32] fixed parameter name --- parameter_files/archive/api25.4.0_041023_pr958.xml | 2 +- parameter_files/fates_params_default.cdl | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/parameter_files/archive/api25.4.0_041023_pr958.xml b/parameter_files/archive/api25.4.0_041023_pr958.xml index 5ad6134ffe..fb424d93e0 100644 --- a/parameter_files/archive/api25.4.0_041023_pr958.xml +++ b/parameter_files/archive/api25.4.0_041023_pr958.xml @@ -27,7 +27,7 @@ 1,2,3,4,5,6,7,8,9,10,11,12 - maintresp_reduction_upthresh + fates_maintresp_reduction_upthresh fates_pft unitless (0-1) upper threshold for storage biomass (relative to leaf biomass) above which MR is not reduced diff --git a/parameter_files/fates_params_default.cdl b/parameter_files/fates_params_default.cdl index aeb33a74b8..6a48bdaa41 100644 --- a/parameter_files/fates_params_default.cdl +++ b/parameter_files/fates_params_default.cdl @@ -389,6 +389,9 @@ variables: double fates_maintresp_reduction_intercept(fates_pft) ; fates_maintresp_reduction_intercept:units = "unitless (0-1)" ; fates_maintresp_reduction_intercept:long_name = "intercept of MR reduction as f(carbon storage), 0=no throttling, 1=max throttling" ; + double fates_maintresp_reduction_upthresh(fates_pft) ; + fates_maintresp_reduction_upthresh:units = "unitless (0-1)" ; + fates_maintresp_reduction_upthresh:long_name = "upper threshold for storage biomass (relative to leaf biomass) above which MR is not reduced" ; double fates_mort_bmort(fates_pft) ; fates_mort_bmort:units = "1/yr" ; fates_mort_bmort:long_name = "background mortality rate" ; @@ -620,9 +623,6 @@ variables: double fates_woody(fates_pft) ; fates_woody:units = "logical flag" ; fates_woody:long_name = "Binary woody lifeform flag" ; - double maintresp_reduction_upthresh(fates_pft) ; - maintresp_reduction_upthresh:units = "unitless (0-1)" ; - maintresp_reduction_upthresh:long_name = "upper threshold for storage biomass (relative to leaf biomass) above which MR is not reduced" ; double fates_hlm_pft_map(fates_hlm_pftno, fates_pft) ; fates_hlm_pft_map:units = "area fraction" ; fates_hlm_pft_map:long_name = "In fixed biogeog mode, fraction of HLM area associated with each FATES PFT" ; @@ -1295,6 +1295,8 @@ data: fates_maintresp_reduction_intercept = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ; + fates_maintresp_reduction_upthresh = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ; + fates_mort_bmort = 0.014, 0.014, 0.014, 0.014, 0.014, 0.014, 0.014, 0.014, 0.014, 0.014, 0.014, 0.014 ; @@ -1531,8 +1533,6 @@ data: fates_woody = 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 ; - maintresp_reduction_upthresh = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ; - fates_hlm_pft_map = 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, From 5830b351853faf8459cbaf848746aed776847c2f Mon Sep 17 00:00:00 2001 From: Marcos Longo <5891904+mpaiao@users.noreply.github.com> Date: Wed, 28 Jun 2023 09:07:26 -0700 Subject: [PATCH 32/32] Update EDPhysiologyMod.F90 Revised the lower threshold for soil potential (and turned into a local constant). --- biogeochem/EDPhysiologyMod.F90 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/biogeochem/EDPhysiologyMod.F90 b/biogeochem/EDPhysiologyMod.F90 index b5d7f1d4a9..9040343100 100644 --- a/biogeochem/EDPhysiologyMod.F90 +++ b/biogeochem/EDPhysiologyMod.F90 @@ -178,6 +178,9 @@ module EDPhysiologyMod ! computational problems. The current threshold ! is the same used in ED-2.2. + real(r8), parameter :: smp_lwr_bound = -1000000._r8 ! Imposed soil matric potential lower bound for + ! frozen or excessively dry soils, used when + ! computing water stress. ! ============================================================================ contains @@ -1202,7 +1205,7 @@ subroutine phenology( currentSite, bc_in ) else ! Nominal extreme suction for frozen or unreasonably dry soil currentSite%smp_memory (1,ipft) = currentSite%smp_memory (1,ipft) + & - -10000._r8* & + smp_lwr_bound * & currentSite%rootfrac_scr(j) / & rootfrac_notop end if