diff --git a/biogeochem/EDPatchDynamicsMod.F90 b/biogeochem/EDPatchDynamicsMod.F90 index b1fc9af66d..1d8b824f92 100644 --- a/biogeochem/EDPatchDynamicsMod.F90 +++ b/biogeochem/EDPatchDynamicsMod.F90 @@ -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 @@ -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, @@ -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 @@ -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) @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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. @@ -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) ! ----------------------------------------------------------------------------------- ! @@ -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 @@ -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 @@ -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 @@ -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. @@ -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: @@ -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) @@ -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 @@ -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: @@ -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 ! @@ -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) @@ -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)) @@ -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 diff --git a/biogeochem/EDPhysiologyMod.F90 b/biogeochem/EDPhysiologyMod.F90 index 1f247de245..c58b718a1f 100644 --- a/biogeochem/EDPhysiologyMod.F90 +++ b/biogeochem/EDPhysiologyMod.F90 @@ -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 @@ -432,7 +434,7 @@ end subroutine GenerateDamageAndLitterFluxes ! ============================================================================ - subroutine PreDisturbanceLitterFluxes( currentSite, currentPatch, bc_in ) + subroutine PreDisturbanceLitterFluxes( currentSite, currentPatch, bc_in, bc_out ) ! ----------------------------------------------------------------------------------- ! @@ -440,8 +442,7 @@ subroutine PreDisturbanceLitterFluxes( currentSite, currentPatch, bc_in ) ! 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) @@ -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: @@ -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 @@ -2785,7 +2786,7 @@ end subroutine recruitment ! ====================================================================================== - subroutine CWDInput( currentSite, currentPatch, litt, bc_in) + subroutine CWDInput( currentSite, currentPatch, litt, bc_in, bc_out) ! ! !DESCRIPTION: @@ -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: @@ -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 diff --git a/biogeophys/EDAccumulateFluxesMod.F90 b/biogeophys/EDAccumulateFluxesMod.F90 index b4f93ba5c9..9befde6321 100644 --- a/biogeophys/EDAccumulateFluxesMod.F90 +++ b/biogeophys/EDAccumulateFluxesMod.F90 @@ -41,7 +41,12 @@ subroutine AccumulateFluxes_ED(nsites, sites, bc_in, bc_out, dt_time) use FatesPatchMod, only : fates_patch_type use FatesCohortMod, only : fates_cohort_type use FatesInterfaceTypesMod , only : bc_in_type,bc_out_type - + use EDtypesMod , only : AREA_INV + use clm_time_manager , only : get_curr_days_per_year + use FatesConstantsMod , only : sec_per_day + use FatesConstantsMod , only : days_per_year + use FatesConstantsMod , only : g_per_kg + ! ! !ARGUMENTS integer, intent(in) :: nsites @@ -57,8 +62,9 @@ subroutine AccumulateFluxes_ED(nsites, sites, bc_in, bc_out, dt_time) integer :: c ! clm/alm column integer :: s ! ed site integer :: ifp ! index fates patch + real :: ind_per_m2 !---------------------------------------------------------------------- - + do s = 1, nsites ! Note: Do not attempt to accumulate or log any @@ -66,6 +72,9 @@ subroutine AccumulateFluxes_ED(nsites, sites, bc_in, bc_out, dt_time) ! It is likely this has not been calculated yet (ELM/CLM) cpatch => sites(s)%oldest_patch + bc_out(s)%npp_acc_site = 0._r8 + bc_out(s)%npp_site = 0._r8 + do while (associated(cpatch)) ifp = cpatch%patchno @@ -75,13 +84,35 @@ subroutine AccumulateFluxes_ED(nsites, sites, bc_in, bc_out, dt_time) if( bc_in(s)%filter_photo_pa(ifp) == 3 ) then ccohort => cpatch%shortest do while(associated(ccohort)) + ind_per_m2 = ccohort%n * AREA_INV ! Accumulate fluxes from hourly to daily values. ! _tstep fluxes are KgC/indiv/timestep _acc are KgC/indiv/day - ccohort%gpp_acc = ccohort%gpp_acc + ccohort%gpp_tstep ccohort%resp_m_acc = ccohort%resp_m_acc + ccohort%resp_m_tstep + ! Make npp_acc variable for the site level to add to the NBP balance check + ! Convert from kgC/ind to gC/m2 + if(.not.ccohort%isnew)then + bc_out(s)%npp_acc_site = bc_out(s)%npp_acc_site + & + (ccohort%gpp_acc - ccohort%resp_m_acc) & + * ind_per_m2 * g_per_kg & + -(ccohort%resp_g_acc_hold+ccohort%resp_excess_hold) * & + ind_per_m2 * g_per_kg * dt_time/(days_per_year*sec_per_day) + ! gresp is converted from kgC/indiv/year to gC/m2/timestep. + endif + + ! Net Ecosystem Production [kgC/m2/s]. Use yesterday's growth respiration + ! This is taken from the NEP history variable calculation. + ! first add GPP-Rm and convert units from kgC/indiv/timestep to gC/m2/s + ! then smooth out yesterdays's calculated growth respiration and + ! convert units from kgC/indiv/year to gC/m2/s. + if(.not.ccohort%isnew)then + bc_out(s)%npp_site = bc_out(s)%npp_site + (ccohort%gpp_tstep-ccohort%resp_m_tstep) & + * ind_per_m2 * g_per_kg / dt_time - & + (ccohort%resp_g_acc_hold+ccohort%resp_excess_hold) * & + ind_per_m2 * g_per_kg / (days_per_year*sec_per_day) + endif ccohort%sym_nfix_daily = ccohort%sym_nfix_daily + ccohort%sym_nfix_tstep ! weighted mean of D13C by gpp @@ -107,7 +138,8 @@ subroutine AccumulateFluxes_ED(nsites, sites, bc_in, bc_out, dt_time) cpatch => cpatch%younger end do ! while(associated(cpatch)) - end do + + end do return end subroutine AccumulateFluxes_ED diff --git a/main/EDMainMod.F90 b/main/EDMainMod.F90 index bfba6d7d56..8fa97d3b6d 100644 --- a/main/EDMainMod.F90 +++ b/main/EDMainMod.F90 @@ -294,7 +294,7 @@ subroutine ed_ecosystem_dynamics(currentSite, bc_in, bc_out) ! make new patches from disturbed land if (do_patch_dynamics.eq.itrue ) then - call spawn_patches(currentSite, bc_in) + call spawn_patches(currentSite, bc_in, bc_out) call TotalBalanceCheck(currentSite,3) @@ -320,7 +320,6 @@ subroutine ed_ecosystem_dynamics(currentSite, bc_in, bc_out) ! Final instantaneous mass balance check call TotalBalanceCheck(currentSite,5) - end subroutine ed_ecosystem_dynamics !-------------------------------------------------------------------------------! @@ -642,8 +641,9 @@ subroutine ed_integrate_state_variables(currentSite, bc_in, bc_out ) bc_out%gpp_site = bc_out%gpp_site + currentCohort%gpp_acc_hold * & AREA_INV * currentCohort%n / real( hlm_days_per_year,r8) / sec_per_day bc_out%ar_site = bc_out%ar_site + (currentCohort%resp_m_acc_hold + & - currentCohort%resp_g_acc_hold + currentCohort%resp_excess_hold*real(hlm_days_per_year,r8) ) * & - AREA_INV * currentCohort%n / real( hlm_days_per_year,r8) / sec_per_day + currentCohort%resp_g_acc_hold + currentCohort%resp_excess_hold) * & + AREA_INV * currentCohort%n / hlm_days_per_year / sec_per_day + ! Update the mass balance tracking for the daily nutrient uptake flux ! Then zero out the daily uptakes, they have been used @@ -784,7 +784,7 @@ subroutine ed_integrate_state_variables(currentSite, bc_in, bc_out ) call GenerateDamageAndLitterFluxes( currentSite, currentPatch, bc_in) - call PreDisturbanceLitterFluxes( currentSite, currentPatch, bc_in) + call PreDisturbanceLitterFluxes( currentSite, currentPatch, bc_in, bc_out) call PreDisturbanceIntegrateLitter(currentPatch ) @@ -837,6 +837,11 @@ subroutine ed_update_site( currentSite, bc_in, bc_out, is_restarting ) type(bc_out_type) , intent(inout) :: bc_out logical,intent(in) :: is_restarting ! is this called during restart read? ! + real(r8) :: biomass_stock ! total biomass in Kg/site + real(r8) :: litter_stock ! total litter in Kg/site + real(r8) :: seed_stock ! total seed mass in Kg/site + real(r8) :: total_stock ! total ED carbon in Kg/site + ! !LOCAL VARIABLES: type (fates_patch_type) , pointer :: currentPatch !----------------------------------------------------------------------- @@ -858,6 +863,9 @@ subroutine ed_update_site( currentSite, bc_in, bc_out, is_restarting ) call TotalBalanceCheck(currentSite,final_check_id) + call SiteMassStock(currentSite,1,total_stock,biomass_stock,litter_stock,seed_stock) + bc_out%fates_total_carbon_site = total_stock + ! Update recruit L2FRs based on new canopy position call SetRecruitL2FR(currentSite) @@ -970,7 +978,7 @@ subroutine TotalBalanceCheck (currentSite, call_index ) call SiteMassStock(currentSite,el,total_stock,biomass_stock,litter_stock,seed_stock) change_in_stock = total_stock - site_mass%old_stock - + flux_in = site_mass%seed_in + & site_mass%net_root_uptake + & site_mass%gpp_acc + & diff --git a/main/FatesInterfaceMod.F90 b/main/FatesInterfaceMod.F90 index e949f4acab..27326c8b9d 100644 --- a/main/FatesInterfaceMod.F90 +++ b/main/FatesInterfaceMod.F90 @@ -371,7 +371,11 @@ subroutine zero_bcs(fates,s) write(fates_log(), *) 'hlm_parteh_mode: ',hlm_parteh_mode call endrun(msg=errMsg(sourcefile, __LINE__)) end select - + + ! carbon loss to atmosphere pathways + fates%bc_out(s)%grazing_closs_to_atm_si = 0.0_r8 + fates%bc_out(s)%fire_closs_to_atm_si = 0.0_r8 + fates%bc_out(s)%rssun_pa(:) = 0.0_r8 fates%bc_out(s)%rssha_pa(:) = 0.0_r8 @@ -408,6 +412,9 @@ subroutine zero_bcs(fates,s) ! Land Use realated fates%bc_out(s)%gpp_site = 0.0_r8 fates%bc_out(s)%ar_site = 0.0_r8 + fates%bc_out(s)%npp_site = 0.0_r8 + fates%bc_out(s)%npp_acc_site = 0.0_r8 + fates%bc_out(s)%fates_total_carbon_site = 0.0_r8 fates%bc_out(s)%hrv_deadstemc_to_prod10c = 0.0_r8 fates%bc_out(s)%hrv_deadstemc_to_prod100c = 0.0_r8 diff --git a/main/FatesInterfaceTypesMod.F90 b/main/FatesInterfaceTypesMod.F90 index 9655d833e0..16aa9563bd 100644 --- a/main/FatesInterfaceTypesMod.F90 +++ b/main/FatesInterfaceTypesMod.F90 @@ -804,6 +804,13 @@ module FatesInterfaceTypesMod real(r8) :: hrv_deadstemc_to_prod100c ! Harvested C flux to 100-yr wood product pool [Site-Level, gC m-2 s-1] real(r8) :: gpp_site ! Site level GPP, for NBP diagnosis in HLM [Site-Level, gC m-2 s-1] real(r8) :: ar_site ! Site level Autotrophic Resp, for NBP diagnosis in HLM [Site-Level, gC m-2 s-1] + real(r8) :: npp_site ! Site level timestep-specific NPP, for NBP diagnosis in HLM [Site-Level, gC m-2 s-1] + real(r8) :: npp_acc_site ! Sitelevel, timestep-specific accumulated NPP to account for assimilate but not allocated C in HLM balance check + real(r8) :: fates_total_carbon_site ! Site level total carbon in FATES (g/m2) for HLM balance check + + ! direct carbon loss to atm pathways + real(r8) :: grazing_closs_to_atm_si ! Loss of carbon to atmosphere via grazing [Site-Level, gC m-2 s-1] + real(r8) :: fire_closs_to_atm_si ! Loss of carbon to atmosphere via burning (includes burning from land use change) [Site-Level, gC m-2 s-1] end type bc_out_type