Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
f4494ea
added grazing and burn fluxes as bc_out variables so that HLMs can ca…
ckoven Mar 7, 2025
26832fa
fixes on new bc_out vars
ckoven Mar 7, 2025
dc87f5b
merge conflicts to do with dist_type use
rosiealice Apr 29, 2025
8816e46
adding references to fates constants
rosiealice Apr 29, 2025
d5ae053
change name of internal FATES_NEP
rosiealice May 13, 2025
3dea7ea
add the calculation of instantaneous site NPP to the accumulatefluxes…
rosiealice May 20, 2025
ba6a701
add bc_out C flux variables to fatesinterface
rosiealice May 20, 2025
f3771b9
add the total carbon stock to the bc_out variable
rosiealice May 20, 2025
df85c8c
change logic in EDaccumulatefluxes
rosiealice May 25, 2025
c953c44
rename FATES_NEP
rosiealice Jun 5, 2025
47ffce8
added grazing and burn fluxes as bc_out variables so that HLMs can ca…
ckoven Mar 7, 2025
6f591b7
fixes on new bc_out vars
ckoven Mar 7, 2025
29c11ed
merge conflicts to do with dist_type use
rosiealice Apr 29, 2025
f492cc5
adding references to fates constants
rosiealice Apr 29, 2025
1ce8da8
change name of internal FATES_NEP
rosiealice May 13, 2025
dca5d75
add the calculation of instantaneous site NPP to the accumulatefluxes…
rosiealice May 20, 2025
c9db9bd
add bc_out C flux variables to fatesinterface
rosiealice May 20, 2025
7a304a2
add the total carbon stock to the bc_out variable
rosiealice May 20, 2025
a99ed54
change logic in EDaccumulatefluxes
rosiealice May 25, 2025
96979bf
rename FATES_NEP
rosiealice Jun 5, 2025
ee13fbd
Merge branch 'nbp_nobalancechec' into ros_nbp
mvdebolskiy Jun 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 37 additions & 23 deletions biogeochem/EDPatchDynamicsMod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ module EDPatchDynamicsMod
use FatesConstantsMod , only : nocomp_bareground
use FatesInterfaceTypesMod , only : hlm_use_planthydro
use FatesInterfaceTypesMod , only : bc_in_type
use FatesInterfaceTypesMod , only : bc_out_type
use FatesInterfaceTypesMod , only : numpft
use FatesInterfaceTypesMod , only : hlm_stepsize
use FatesInterfaceTypesMod , only : hlm_use_sp
Expand Down Expand Up @@ -482,7 +483,7 @@ end subroutine disturbance_rates

! ============================================================================

subroutine spawn_patches( currentSite, bc_in)
subroutine spawn_patches( currentSite, bc_in, bc_out)
!
! !DESCRIPTION:
! In this subroutine, the following happens,
Expand All @@ -509,6 +510,7 @@ subroutine spawn_patches( currentSite, bc_in)
! !ARGUMENTS:
type (ed_site_type), intent(inout) :: currentSite
type (bc_in_type), intent(in) :: bc_in
type (bc_out_type), intent(inout) :: bc_out
!
! !LOCAL VARIABLES:
type (fates_patch_type) , pointer :: newPatch
Expand Down Expand Up @@ -753,7 +755,9 @@ subroutine spawn_patches( currentSite, bc_in)

call CopyPatchMeansTimers(currentPatch, newPatch)

call TransLitterNewPatch( currentSite, currentPatch, newPatch, patch_site_areadis, i_disturbance_type)

call TransLitterNewPatch( currentSite, currentPatch, newPatch, patch_site_areadis, bc_out, i_disturbance_type)


! Transfer in litter fluxes from plants in various contexts of death and destruction
select case(i_disturbance_type)
Expand All @@ -768,13 +772,13 @@ subroutine spawn_patches( currentSite, bc_in)
end if
case (dtype_ifire)
call fire_litter_fluxes(currentSite, currentPatch, &
newPatch, patch_site_areadis,bc_in)
newPatch, patch_site_areadis,bc_in, bc_out)
case (dtype_ifall)
call mortality_litter_fluxes(currentSite, currentPatch, &
newPatch, patch_site_areadis,bc_in)
case (dtype_ilandusechange)
call landusechange_litter_fluxes(currentSite, currentPatch, &
newPatch, patch_site_areadis,bc_in, &
newPatch, patch_site_areadis,bc_in, bc_out, &
clearing_matrix(i_donorpatch_landuse_type,i_landusechange_receiverpatchlabel))

! if land use change, then may need to change nocomp pft, so tag as having transitioned LU
Expand Down Expand Up @@ -1068,11 +1072,8 @@ subroutine spawn_patches( currentSite, bc_in)
currentSite%mass_balance(el)%burn_flux_to_atm + &
leaf_burn_frac * leaf_m * nc%n

! This diagnostic only tracks
currentSite%flux_diags%elem(el)%burned_liveveg = &
currentSite%flux_diags%elem(el)%burned_liveveg + &
leaf_burn_frac * leaf_m * nc%n * area_inv

bc_out%fire_closs_to_atm_si = bc_out%fire_closs_to_atm_si + &
leaf_burn_frac * leaf_m * nc%n * ha_per_m2 * days_per_sec
end do

! Here the mass is removed from the plant
Expand Down Expand Up @@ -1421,7 +1422,7 @@ subroutine spawn_patches( currentSite, bc_in)

allocate(temp_patch)

call split_patch(currentSite, currentPatch, temp_patch, fraction_to_keep, newp_area)
call split_patch(currentSite, currentPatch, temp_patch, fraction_to_keep, newp_area, bc_out)
!
temp_patch%nocomp_pft_label = 0

Expand Down Expand Up @@ -1524,7 +1525,7 @@ subroutine spawn_patches( currentSite, bc_in)
! split buffer patch in two, keeping the smaller buffer patch to put into new patches
allocate(temp_patch)

call split_patch(currentSite, buffer_patch, temp_patch, fraction_to_keep, newp_area)
call split_patch(currentSite, buffer_patch, temp_patch, fraction_to_keep, newp_area, bc_out)

! give the new patch the intended nocomp PFT label
temp_patch%nocomp_pft_label = i_pft
Expand Down Expand Up @@ -1633,7 +1634,7 @@ end subroutine spawn_patches

! -----------------------------------------------------------------------------------------

subroutine split_patch(currentSite, currentPatch, new_patch, fraction_to_keep, area_to_remove)
subroutine split_patch(currentSite, currentPatch, new_patch, fraction_to_keep, area_to_remove, bc_out)
!
! !DESCRIPTION:
! Split a patch into two patches that are identical except in their areas
Expand All @@ -1644,6 +1645,7 @@ subroutine split_patch(currentSite, currentPatch, new_patch, fraction_to_keep, a
type(fates_patch_type) , intent(inout), pointer :: new_patch ! New Patch
real(r8), intent(in) :: fraction_to_keep ! fraction of currentPatch to keep, the rest goes to newpatch
real(r8), intent(in), optional :: area_to_remove ! area of currentPatch to remove, the rest goes to newpatch
type(bc_out_type) , intent(inout) :: bc_out
!
! !LOCAL VARIABLES:
integer :: el ! element loop index
Expand Down Expand Up @@ -1680,7 +1682,8 @@ subroutine split_patch(currentSite, currentPatch, new_patch, fraction_to_keep, a

call CopyPatchMeansTimers(currentPatch, new_patch)

call TransLitterNewPatch( currentSite, currentPatch, new_patch, temp_area, 0)
call TransLitterNewPatch( currentSite, currentPatch, new_patch, temp_area, bc_out, 0)


! Next, we loop through the cohorts in the donor patch, copy them with
! area modified number density into the new-patch, and apply survivorship.
Expand Down Expand Up @@ -1814,8 +1817,7 @@ end subroutine check_patch_area
subroutine TransLitterNewPatch(currentSite, &
currentPatch, &
newPatch, &
patch_site_areadis, &
dist_type)
patch_site_areadis, bc_out, dist_type)

! -----------------------------------------------------------------------------------
!
Expand Down Expand Up @@ -1864,8 +1866,8 @@ subroutine TransLitterNewPatch(currentSite, &
type(fates_patch_type) , intent(inout) :: newPatch ! New patch
real(r8) , intent(in) :: patch_site_areadis ! Area being donated
! by current patch
type(bc_out_type) , intent(inout) :: bc_out
integer, intent(in) :: dist_type ! disturbance type


! locals
type(site_massbal_type), pointer :: site_mass
Expand Down Expand Up @@ -1989,7 +1991,9 @@ subroutine TransLitterNewPatch(currentSite, &
curr_litt%ag_cwd(c) = curr_litt%ag_cwd(c) + donatable_mass*retain_m2

site_mass%burn_flux_to_atm = site_mass%burn_flux_to_atm + burned_mass


bc_out%fire_closs_to_atm_si = bc_out%fire_closs_to_atm_si + burned_mass * ha_per_m2 * days_per_sec

! Transfer below ground CWD (none burns)

do sl = 1,currentSite%nlevsoil
Expand Down Expand Up @@ -2018,7 +2022,9 @@ subroutine TransLitterNewPatch(currentSite, &
curr_litt%leaf_fines(dcmpy) = curr_litt%leaf_fines(dcmpy) + donatable_mass*retain_m2

site_mass%burn_flux_to_atm = site_mass%burn_flux_to_atm + burned_mass


bc_out%fire_closs_to_atm_si = bc_out%fire_closs_to_atm_si + burned_mass * ha_per_m2 * days_per_sec

! Transfer root fines (none burns)
do sl = 1,currentSite%nlevsoil
donatable_mass = curr_litt%root_fines(dcmpy,sl) * patch_site_areadis
Expand Down Expand Up @@ -2068,7 +2074,7 @@ end subroutine TransLitterNewPatch
! ============================================================================

subroutine fire_litter_fluxes(currentSite, currentPatch, &
newPatch, patch_site_areadis, bc_in)
newPatch, patch_site_areadis, bc_in, bc_out)
!
! !DESCRIPTION:
! CWD pool burned by a fire.
Expand All @@ -2088,6 +2094,7 @@ subroutine fire_litter_fluxes(currentSite, currentPatch, &
type(fates_patch_type) , intent(inout), target :: newPatch ! New Patch
real(r8) , intent(in) :: patch_site_areadis ! Area being donated
type(bc_in_type) , intent(in) :: bc_in
type(bc_out_type) , intent(inout) :: bc_out

!
! !LOCAL VARIABLES:
Expand Down Expand Up @@ -2229,8 +2236,8 @@ subroutine fire_litter_fluxes(currentSite, currentPatch, &

site_mass%burn_flux_to_atm = site_mass%burn_flux_to_atm + burned_mass


bc_out%fire_closs_to_atm_si = bc_out%fire_closs_to_atm_si + burned_mass * ha_per_m2 * days_per_sec

call set_root_fraction(currentSite%rootfrac_scr, pft, currentSite%zi_soil, &
bc_in%max_rooting_depth_index_col)

Expand Down Expand Up @@ -2292,6 +2299,7 @@ subroutine fire_litter_fluxes(currentSite, currentPatch, &
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
bc_out%fire_closs_to_atm_si = bc_out%fire_closs_to_atm_si + burned_mass * ha_per_m2 * days_per_sec
endif
new_litt%ag_cwd(c) = new_litt%ag_cwd(c) + donatable_mass * donate_m2
curr_litt%ag_cwd(c) = curr_litt%ag_cwd(c) + donatable_mass * retain_m2
Expand Down Expand Up @@ -2542,7 +2550,7 @@ end subroutine mortality_litter_fluxes
! ============================================================================

subroutine landusechange_litter_fluxes(currentSite, currentPatch, &
newPatch, patch_site_areadis, bc_in, &
newPatch, patch_site_areadis, bc_in, bc_out, &
clearing_matrix_element)
!
! !DESCRIPTION:
Expand All @@ -2559,6 +2567,7 @@ subroutine landusechange_litter_fluxes(currentSite, currentPatch, &
type(fates_patch_type) , intent(inout), target :: newPatch ! New Patch
real(r8) , intent(in) :: patch_site_areadis ! Area being donated
type(bc_in_type) , intent(in) :: bc_in
type(bc_out_type) , intent(inout) :: bc_out
logical , intent(in) :: clearing_matrix_element ! whether or not to clear vegetation

!
Expand Down Expand Up @@ -2702,7 +2711,9 @@ subroutine landusechange_litter_fluxes(currentSite, currentPatch, &
end do

site_mass%burn_flux_to_atm = site_mass%burn_flux_to_atm + burned_mass


bc_out%fire_closs_to_atm_si = bc_out%fire_closs_to_atm_si + burned_mass * ha_per_m2 * days_per_sec

call set_root_fraction(currentSite%rootfrac_scr, pft, currentSite%zi_soil, &
bc_in%max_rooting_depth_index_col)

Expand Down Expand Up @@ -2762,6 +2773,7 @@ subroutine landusechange_litter_fluxes(currentSite, currentPatch, &
EDPftvarcon_inst%landusechange_frac_burned(pft)

site_mass%burn_flux_to_atm = site_mass%burn_flux_to_atm + burned_mass
bc_out%fire_closs_to_atm_si = bc_out%fire_closs_to_atm_si + burned_mass * ha_per_m2 * days_per_sec
else ! all other pools can end up as timber products or burn or go to litter
donatable_mass = donatable_mass * (1.0_r8-EDPftvarcon_inst%landusechange_frac_exported(pft)) * &
(1.0_r8-EDPftvarcon_inst%landusechange_frac_burned(pft))
Expand All @@ -2775,6 +2787,8 @@ subroutine landusechange_litter_fluxes(currentSite, currentPatch, &

site_mass%burn_flux_to_atm = site_mass%burn_flux_to_atm + burned_mass

bc_out%fire_closs_to_atm_si = bc_out%fire_closs_to_atm_si + burned_mass * ha_per_m2 * days_per_sec

trunk_product_site = trunk_product_site + &
woodproduct_mass

Expand Down
72 changes: 39 additions & 33 deletions biogeochem/EDPhysiologyMod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ module EDPhysiologyMod
use FatesConstantsMod, only : megajoules_per_joule
use FatesConstantsMod, only : mpa_per_mm_suction
use FatesConstantsMod, only : g_per_kg
use FatesConstantsMod, only : ha_per_m2
use FatesConstantsMod, only : days_per_sec
use FatesConstantsMod, only : ndays_per_year
use FatesConstantsMod, only : nocomp_bareground
use FatesConstantsMod, only : nocomp_bareground_land
Expand Down Expand Up @@ -432,16 +434,15 @@ end subroutine GenerateDamageAndLitterFluxes

! ============================================================================

subroutine PreDisturbanceLitterFluxes( currentSite, currentPatch, bc_in )
subroutine PreDisturbanceLitterFluxes( currentSite, currentPatch, bc_in, bc_out )

! -----------------------------------------------------------------------------------
!
! This subroutine calculates all of the different litter input and output fluxes
! associated with seed turnover, seed influx, litterfall from live and
! dead plants, germination, and fragmentation.
!
! At this time we do not have explicit herbivory, and burning losses to litter
! are handled elsewhere.
! Herbivory is handled here. burning losses to litter are handled elsewhere.
!
! Note: The processes conducted here DO NOT handle litter fluxes associated
! with disturbance. Those fluxes are handled elsewhere (EDPatchDynamcisMod)
Expand All @@ -455,6 +456,7 @@ subroutine PreDisturbanceLitterFluxes( currentSite, currentPatch, bc_in )
type(ed_site_type), intent(inout) :: currentSite
type(fates_patch_type), intent(inout) :: currentPatch
type(bc_in_type), intent(in) :: bc_in
type(bc_out_type), intent(inout) :: bc_out

!
! !LOCAL VARIABLES:
Expand All @@ -473,34 +475,33 @@ subroutine PreDisturbanceLitterFluxes( currentSite, currentPatch, bc_in )
site_mass => currentSite%mass_balance(el), &
diag => currentSite%flux_diags%elem(el))

! Calculate loss rate of viable seeds to litter
call SeedDecay(litt, currentPatch, bc_in)

! Calculate seed germination rate, the status flags prevent
! germination from occuring when the site is in a drought
! (for drought deciduous) or too cold (for cold deciduous)
call SeedGermination(litt, currentSite%cstatus, currentSite%dstatus(1:numpft), bc_in, currentPatch)

! Send fluxes from newly created litter into the litter pools
! This litter flux is from non-disturbance inducing mortality, as well
! as litter fluxes from live trees
call CWDInput(currentSite, currentPatch, litt,bc_in)

! Only calculate fragmentation flux over layers that are active
! (RGK-Mar2019) SHOULD WE MAX THIS AT 1? DONT HAVE TO

nlev_eff_decomp = max(bc_in%max_rooting_depth_index_col, 1)
call CWDOut(litt,currentPatch%fragmentation_scaler,nlev_eff_decomp)

! Fragmentation flux to soil decomposition model [kg/site/day]
site_mass%frag_out = site_mass%frag_out + currentPatch%area * &
( sum(litt%ag_cwd_frag) + sum(litt%bg_cwd_frag) + &
sum(litt%leaf_fines_frag) + sum(litt%root_fines_frag) + &
sum(litt%seed_decay) + sum(litt%seed_germ_decay))

! Track total seed decay diagnostic in [kg/m2/day]
diag%tot_seed_turnover = diag%tot_seed_turnover + &
(sum(litt%seed_decay) + sum(litt%seed_germ_decay))*currentPatch%area*area_inv
! Calculate loss rate of viable seeds to litter
call SeedDecay(litt, currentPatch, bc_in)


! Calculate seed germination rate, the status flags prevent
! germination from occuring when the site is in a drought
! (for drought deciduous) or too cold (for cold deciduous)
call SeedGermination(litt, currentSite%cstatus, currentSite%dstatus(1:numpft), bc_in, currentPatch)

! Send fluxes from newly created litter into the litter pools
! This litter flux is from non-disturbance inducing mortality, as well
! as litter fluxes from live trees
call CWDInput(currentSite, currentPatch, litt,bc_in, bc_out)

! Only calculate fragmentation flux over layers that are active
! (RGK-Mar2019) SHOULD WE MAX THIS AT 1? DONT HAVE TO

nlev_eff_decomp = max(bc_in%max_rooting_depth_index_col, 1)
call CWDOut(litt,currentPatch%fragmentation_scaler,nlev_eff_decomp)


! Fragmentation flux to soil decomposition model [kg/site/day]
site_mass%frag_out = site_mass%frag_out + currentPatch%area * &
( sum(litt%ag_cwd_frag) + sum(litt%bg_cwd_frag) + &
sum(litt%leaf_fines_frag) + sum(litt%root_fines_frag) + &
sum(litt%seed_decay) + sum(litt%seed_germ_decay))


end associate
end do
Expand Down Expand Up @@ -2785,7 +2786,7 @@ end subroutine recruitment

! ======================================================================================

subroutine CWDInput( currentSite, currentPatch, litt, bc_in)
subroutine CWDInput( currentSite, currentPatch, litt, bc_in, bc_out)

!
! !DESCRIPTION:
Expand All @@ -2805,6 +2806,7 @@ subroutine CWDInput( currentSite, currentPatch, litt, bc_in)
type(fates_patch_type),intent(inout), target :: currentPatch
type(litter_type),intent(inout),target :: litt
type(bc_in_type),intent(in) :: bc_in
type(bc_out_type),intent(inout) :: bc_out

!
! !LOCAL VARIABLES:
Expand Down Expand Up @@ -2952,12 +2954,16 @@ subroutine CWDInput( currentSite, currentPatch, litt, bc_in)
elflux_diags%root_litter_input(pft) + &
(fnrt_m_turnover + store_m_turnover ) * currentCohort%n

! send the part of the herbivory flux that doesn't go to litter to the atmosphere
! send the part of the herbivory flux that doesn't go to litter to the atmosphere (and also for tracking)

site_mass%herbivory_flux_out = &
site_mass%herbivory_flux_out + &
leaf_herbivory * (1._r8 - herbivory_element_use_efficiency) * currentCohort%n

bc_out%grazing_closs_to_atm_si = bc_out%grazing_closs_to_atm_si + &
leaf_herbivory * (1._r8 - herbivory_element_use_efficiency) * currentCohort%n * &
ha_per_m2 * days_per_sec

! 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
Expand Down
Loading