diff --git a/biogeochem/EDCohortDynamicsMod.F90 b/biogeochem/EDCohortDynamicsMod.F90 index 39929612e3..8224e70531 100644 --- a/biogeochem/EDCohortDynamicsMod.F90 +++ b/biogeochem/EDCohortDynamicsMod.F90 @@ -1067,11 +1067,14 @@ subroutine fuse_cohorts(currentSite, currentPatch, bc_in) nextc%n*nextc%gpp_acc)/newn currentCohort%npp_acc = (currentCohort%n*currentCohort%npp_acc + & nextc%n*nextc%npp_acc)/newn - currentCohort%resp_acc = (currentCohort%n*currentCohort%resp_acc + & - nextc%n*nextc%resp_acc)/newn - currentCohort%resp_acc_hold = & - (currentCohort%n*currentCohort%resp_acc_hold + & - nextc%n*nextc%resp_acc_hold)/newn + currentCohort%resp_m_acc = (currentCohort%n*currentCohort%resp_m_acc + & + nextc%n*nextc%resp_m_acc)/newn + currentCohort%resp_m_acc_hold = & + (currentCohort%n*currentCohort%resp_m_acc_hold + & + nextc%n*nextc%resp_m_acc_hold)/newn + currentCohort%resp_g_acc_hold = & + (currentCohort%n*currentCohort%resp_g_acc_hold + & + nextc%n*nextc%resp_g_acc_hold)/newn currentCohort%npp_acc_hold = & (currentCohort%n*currentCohort%npp_acc_hold + & nextc%n*nextc%npp_acc_hold)/newn @@ -1079,8 +1082,9 @@ subroutine fuse_cohorts(currentSite, currentPatch, bc_in) (currentCohort%n*currentCohort%gpp_acc_hold + & nextc%n*nextc%gpp_acc_hold)/newn - currentCohort%resp_excess = (currentCohort%n*currentCohort%resp_excess + & - nextc%n*nextc%resp_excess)/newn + currentCohort%resp_excess_hold = & + (currentCohort%n*currentCohort%resp_excess_hold + & + nextc%n*nextc%resp_excess_hold)/newn currentCohort%dmort = (currentCohort%n*currentCohort%dmort + & nextc%n*nextc%dmort)/newn diff --git a/biogeochem/FatesCohortMod.F90 b/biogeochem/FatesCohortMod.F90 index 6dc6f515da..96669a1112 100644 --- a/biogeochem/FatesCohortMod.F90 +++ b/biogeochem/FatesCohortMod.F90 @@ -133,21 +133,24 @@ module FatesCohortMod ! after the dynamics call-sequence is completed. [kgC/indiv/day] ! _acc_hold: While _acc is zero'd after the dynamics call sequence and then integrated, ! _acc_hold "holds" the integrated value until the next time dynamics is - ! called. This is necessary for restarts. This variable also has units - ! converted to a useful rate [kgC/indiv/yr] + ! called. This is useful because growth and excess respiration + ! are calculated once daily, but we want to remove the average + ! flux from the daily NEP signal, so we remove it from the next day. + ! The hold variables are also useful for rebuilding history on restart. + ! Units converted to a useful rate [kgC/indiv/yr] ! -------------------------------------------------------------------------- real(r8) :: gpp_tstep ! Gross Primary Production (see above *) real(r8) :: gpp_acc real(r8) :: gpp_acc_hold - real(r8) :: npp_tstep ! Net Primary Production (see above *) real(r8) :: npp_acc real(r8) :: npp_acc_hold - real(r8) :: resp_tstep ! Autotrophic respiration (see above *) - real(r8) :: resp_acc - real(r8) :: resp_acc_hold + real(r8) :: resp_m_tstep ! Maintenance respiration (see above *) + real(r8) :: resp_m_acc + real(r8) :: resp_m_acc_hold + real(r8) :: resp_g_acc_hold real(r8) :: c13disc_clm ! carbon 13 discrimination in new synthesized carbon at each indiv/timestep [ppm] real(r8) :: c13disc_acc ! carbon 13 discrimination in new synthesized carbon at each indiv/day @@ -202,11 +205,15 @@ module FatesCohortMod integer :: twostr_col ! The column index in the two-stream solution that this cohort is part of ! RESPIRATION COMPONENTS + real(r8) :: resp_excess_hold ! respiration of excess carbon [kgC/indiv/yr] + ! note: this is flagged "hold" because it is calculated + ! at the end of the day (dynamics) but is used + ! on the following day (like growth respiration) + ! to aid in reporting a more accurate sub-daily + ! NEP + real(r8) :: rdark ! dark respiration [kgC/indiv/s] - real(r8) :: resp_g_tstep ! growth respiration [kgC/indiv/timestep] - real(r8) :: resp_m ! maintenance respiration [kgC/indiv/timestep] real(r8) :: resp_m_unreduced ! diagnostic-only unreduced maintenance respiration [kgC/indiv/timestep] - real(r8) :: resp_excess ! respiration of excess carbon [kgC/indiv/day] real(r8) :: livestem_mr ! aboveground live stem maintenance respiration [kgC/indiv/s] real(r8) :: livecroot_mr ! belowground live stem maintenance respiration [kgC/indiv/s] real(r8) :: froot_mr ! live fine root maintenance respiration [kgC/indiv/s] @@ -375,12 +382,12 @@ subroutine NanValues(this) this%gpp_tstep = nan this%gpp_acc = nan this%gpp_acc_hold = nan - this%npp_tstep = nan this%npp_acc = nan this%npp_acc_hold = nan - this%resp_tstep = nan - this%resp_acc = nan - this%resp_acc_hold = nan + this%resp_m_tstep = nan + this%resp_m_acc = nan + this%resp_m_acc_hold = nan + this%resp_g_acc_hold = nan this%c13disc_clm = nan this%c13disc_acc = nan this%vcmax25top = nan @@ -410,10 +417,8 @@ subroutine NanValues(this) ! RESPIRATION COMPONENTS this%rdark = nan - this%resp_g_tstep = nan - this%resp_m = nan this%resp_m_unreduced = nan - this%resp_excess = nan + this%resp_excess_hold = nan this%livestem_mr = nan this%livecroot_mr = nan this%froot_mr = nan @@ -477,17 +482,18 @@ subroutine ZeroValues(this) this%size_class_lasttimestep = 0 this%gpp_tstep = 0._r8 this%gpp_acc = 0._r8 - this%npp_tstep = 0._r8 this%npp_acc = 0._r8 - this%resp_tstep = 0._r8 - this%resp_acc = 0._r8 + this%resp_m_tstep = 0._r8 + this%resp_m_acc = 0._r8 ! do not zero these, they are not built ! so more appropriate to leave unzerod ! to prevent uninitialized use ! this%gpp_acc_hold = nan ! this%npp_acc_hold = nan - ! this%resp_acc_hold = nan + ! this%resp_m_acc_hold = nan + ! this%resp_g_acc_hold = nan + ! this%resp_excess_hold = nan this%c13disc_clm = 0._r8 this%c13disc_acc = 0._r8 @@ -516,10 +522,7 @@ subroutine ZeroValues(this) this%daily_p_demand = -9._r8 this%seed_prod = 0._r8 this%rdark = 0._r8 - this%resp_g_tstep = 0._r8 - this%resp_m = 0._r8 this%resp_m_unreduced = 0._r8 - this%resp_excess = 0._r8 this%livestem_mr = 0._r8 this%livecroot_mr = 0._r8 this%froot_mr = 0._r8 @@ -706,12 +709,12 @@ subroutine Copy(this, copyCohort) copyCohort%gpp_tstep = this%gpp_tstep copyCohort%gpp_acc = this%gpp_acc copyCohort%gpp_acc_hold = this%gpp_acc_hold - copyCohort%npp_tstep = this%npp_tstep copyCohort%npp_acc = this%npp_acc copyCohort%npp_acc_hold = this%npp_acc_hold - copyCohort%resp_tstep = this%resp_tstep - copyCohort%resp_acc = this%resp_acc - copyCohort%resp_acc_hold = this%resp_acc_hold + copyCohort%resp_m_tstep = this%resp_m_tstep + copyCohort%resp_m_acc = this%resp_m_acc + copyCohort%resp_m_acc_hold = this%resp_m_acc_hold + copyCohort%resp_g_acc_hold = this%resp_g_acc_hold copyCohort%c13disc_clm = this%c13disc_clm copyCohort%c13disc_acc = this%c13disc_acc copyCohort%vcmax25top = this%vcmax25top @@ -744,10 +747,8 @@ subroutine Copy(this, copyCohort) ! RESPIRATION COMPONENTS copyCohort%rdark = this%rdark - copyCohort%resp_g_tstep = this%resp_g_tstep - copyCohort%resp_m = this%resp_m copyCohort%resp_m_unreduced = this%resp_m_unreduced - copyCohort%resp_excess = this%resp_excess + copyCohort%resp_excess_hold = this%resp_excess_hold copyCohort%livestem_mr = this%livestem_mr copyCohort%livecroot_mr = this%livecroot_mr copyCohort%froot_mr = this%froot_mr @@ -880,7 +881,7 @@ subroutine InitPRTBoundaryConditions(this) call this%prt%RegisterBCIn(acnp_bc_in_id_cdamage, bc_ival=this%crowndamage) call this%prt%RegisterBCInOut(acnp_bc_inout_id_dbh, bc_rval=this%dbh) - call this%prt%RegisterBCInOut(acnp_bc_inout_id_resp_excess, bc_rval=this%resp_excess) + call this%prt%RegisterBCInOut(acnp_bc_inout_id_resp_excess, bc_rval=this%resp_excess_hold) call this%prt%RegisterBCInOut(acnp_bc_inout_id_l2fr, bc_rval=this%l2fr) call this%prt%RegisterBCInOut(acnp_bc_inout_id_cx_int, bc_rval=this%cx_int) call this%prt%RegisterBCInOut(acnp_bc_inout_id_emadcxdt, bc_rval=this%ema_dcxdt) @@ -1047,14 +1048,12 @@ subroutine Dump(this) write(fates_log(),*) 'cohort%gpp_acc = ', this%gpp_acc write(fates_log(),*) 'cohort%gpp_tstep = ', this%gpp_tstep write(fates_log(),*) 'cohort%npp_acc_hold = ', this%npp_acc_hold - write(fates_log(),*) 'cohort%npp_tstep = ', this%npp_tstep write(fates_log(),*) 'cohort%npp_acc = ', this%npp_acc - write(fates_log(),*) 'cohort%resp_tstep = ', this%resp_tstep - write(fates_log(),*) 'cohort%resp_acc = ', this%resp_acc - write(fates_log(),*) 'cohort%resp_acc_hold = ', this%resp_acc_hold + write(fates_log(),*) 'cohort%resp_m_tstep = ', this%resp_m_tstep + write(fates_log(),*) 'cohort%resp_m_acc = ', this%resp_m_acc + write(fates_log(),*) 'cohort%resp_m_acc_hold = ', this%resp_m_acc_hold + write(fates_log(),*) 'cohort%resp_g_acc_hold = ', this%resp_g_acc_hold write(fates_log(),*) 'cohort%rdark = ', this%rdark - write(fates_log(),*) 'cohort%resp_m = ', this%resp_m - write(fates_log(),*) 'cohort%resp_g_tstep = ', this%resp_g_tstep write(fates_log(),*) 'cohort%livestem_mr = ', this%livestem_mr write(fates_log(),*) 'cohort%livecroot_mr = ', this%livecroot_mr write(fates_log(),*) 'cohort%froot_mr = ', this%froot_mr diff --git a/biogeochem/FatesSoilBGCFluxMod.F90 b/biogeochem/FatesSoilBGCFluxMod.F90 index 5cc25c697a..2dd3f816a4 100644 --- a/biogeochem/FatesSoilBGCFluxMod.F90 +++ b/biogeochem/FatesSoilBGCFluxMod.F90 @@ -123,9 +123,7 @@ subroutine UnPackNutrientAquisitionBCs(sites, bc_in) ! Locals integer :: nsites ! number of sites integer :: s ! site loop index - integer :: j ! soil layer integer :: icomp ! competitor index - integer :: id ! decomp layer index integer :: pft ! pft index type(fates_patch_type), pointer :: cpatch ! current patch pointer type(fates_cohort_type), pointer :: ccohort ! current cohort pointer @@ -350,9 +348,10 @@ subroutine PrepCH4BCs(csite,bc_in,bc_out) ! this is a best (bad) guess at fine root MR + total root GR ! (kgC/indiv/yr) -> gC/m2/s bc_out%root_resp(1:bc_in%nlevsoil) = bc_out%root_resp(1:bc_in%nlevsoil) + & - ccohort%resp_acc_hold*years_per_day*g_per_kg*days_per_sec* & + (ccohort%resp_m_acc_hold + ccohort%resp_g_acc_hold)*years_per_day*g_per_kg*days_per_sec* & ccohort%n*area_inv*(1._r8-prt_params%allom_agb_frac(pft)) * csite%rootfrac_scr(1:bc_in%nlevsoil) - + + end if if( prt_params%woody(pft)==itrue ) then @@ -646,7 +645,6 @@ subroutine FluxIntoLitterPools(csite, bc_in, bc_out) integer :: nlev_eff_decomp ! number of effective decomp layers real(r8) :: area_frac ! fraction of site's area of current patch real(r8) :: z_decomp ! Used for calculating depth midpoints of decomp layers - integer :: s ! Site index integer :: el ! Element index (C,N,P,etc) integer :: j ! Soil layer index integer :: id ! Decomposition layer index diff --git a/biogeophys/EDAccumulateFluxesMod.F90 b/biogeophys/EDAccumulateFluxesMod.F90 index 6a1bb001c0..5bab6b5191 100644 --- a/biogeophys/EDAccumulateFluxesMod.F90 +++ b/biogeophys/EDAccumulateFluxesMod.F90 @@ -3,7 +3,7 @@ module EDAccumulateFluxesMod !------------------------------------------------------------------------------ ! !DESCRIPTION: ! This routine accumulates NPP, GPP and respiration of each cohort over the course of each 24 hour period. - ! The fluxes are stored per cohort, and the npp_tstep (etc) fluxes are calcualted in EDPhotosynthesis + ! The fluxes are stored per cohort, and the gpp_tstep (etc) fluxes are calculated in EDPhotosynthesis ! This routine cannot be in EDPhotosynthesis because EDPhotosynthesis is a loop and therefore would ! erroneously add these things up multiple times. ! Rosie Fisher. March 2014. @@ -80,17 +80,8 @@ subroutine AccumulateFluxes_ED(nsites, sites, bc_in, bc_out, dt_time) ! Accumulate fluxes from hourly to daily values. ! _tstep fluxes are KgC/indiv/timestep _acc are KgC/indiv/day - if ( debug ) then - - write(fates_log(),*) 'EDAccumFlux 64 ',ccohort%npp_tstep - write(fates_log(),*) 'EDAccumFlux 66 ',ccohort%gpp_tstep - write(fates_log(),*) 'EDAccumFlux 67 ',ccohort%resp_tstep - - endif - - ccohort%npp_acc = ccohort%npp_acc + ccohort%npp_tstep ccohort%gpp_acc = ccohort%gpp_acc + ccohort%gpp_tstep - ccohort%resp_acc = ccohort%resp_acc + ccohort%resp_tstep + ccohort%resp_m_acc = ccohort%resp_m_acc + ccohort%resp_m_tstep ccohort%sym_nfix_daily = ccohort%sym_nfix_daily + ccohort%sym_nfix_tstep diff --git a/biogeophys/FatesPlantRespPhotosynthMod.F90 b/biogeophys/FatesPlantRespPhotosynthMod.F90 index b37e3630a0..d1413f1b15 100644 --- a/biogeophys/FatesPlantRespPhotosynthMod.F90 +++ b/biogeophys/FatesPlantRespPhotosynthMod.F90 @@ -739,11 +739,10 @@ subroutine FatesPlantRespPhotosynthDrive (nsites, sites,bc_in,bc_out,dtime) end do leaf_layer_loop ! Zero cohort flux accumulators. - currentCohort%npp_tstep = 0.0_r8 - currentCohort%resp_tstep = 0.0_r8 + + currentCohort%resp_m_tstep = 0.0_r8 currentCohort%gpp_tstep = 0.0_r8 currentCohort%rdark = 0.0_r8 - currentCohort%resp_m = 0.0_r8 currentCohort%ts_net_uptake = 0.0_r8 currentCohort%c13disc_clm = 0.0_r8 @@ -968,47 +967,24 @@ subroutine FatesPlantRespPhotosynthDrive (nsites, sites,bc_in,bc_out,dtime) ! calcualate some fluxes that are sums and nets of the base fluxes ! ------------------------------------------------------------------ - if ( debug ) write(fates_log(),*) 'EDPhoto 904 ', currentCohort%resp_m - if ( debug ) write(fates_log(),*) 'EDPhoto 905 ', currentCohort%rdark - if ( debug ) write(fates_log(),*) 'EDPhoto 906 ', currentCohort%livestem_mr - if ( debug ) write(fates_log(),*) 'EDPhoto 907 ', currentCohort%livecroot_mr - if ( debug ) write(fates_log(),*) 'EDPhoto 908 ', currentCohort%froot_mr - - - ! add on whole plant respiration values in kgC/indiv/s-1 - currentCohort%resp_m = currentCohort%livestem_mr + & + currentCohort%resp_m_tstep = currentCohort%livestem_mr + & currentCohort%livecroot_mr + & - currentCohort%froot_mr - + currentCohort%froot_mr + & + currentCohort%rdark + ! no drought response right now.. something like: - ! resp_m = resp_m * (1.0_r8 - currentPatch%btran_ft(currentCohort%pft) * & + ! resp_m_tstep = resp_m_tstep * (1.0_r8 - currentPatch%btran_ft(currentCohort%pft) * & ! EDPftvarcon_inst%resp_drought_response(ft)) - currentCohort%resp_m = currentCohort%resp_m + currentCohort%rdark - - ! save as a diagnostic the un-throttled maintenance respiration to be able to know how strong this is - currentCohort%resp_m_unreduced = currentCohort%resp_m / maintresp_reduction_factor - ! convert from kgC/indiv/s to kgC/indiv/timestep - currentCohort%resp_m = currentCohort%resp_m * dtime + currentCohort%resp_m_tstep = currentCohort%resp_m_tstep * dtime currentCohort%gpp_tstep = currentCohort%gpp_tstep * dtime currentCohort%ts_net_uptake = currentCohort%ts_net_uptake * dtime - - if ( debug ) write(fates_log(),*) 'EDPhoto 911 ', currentCohort%gpp_tstep - if ( debug ) write(fates_log(),*) 'EDPhoto 912 ', currentCohort%resp_tstep - if ( debug ) write(fates_log(),*) 'EDPhoto 913 ', currentCohort%resp_m - - - currentCohort%resp_g_tstep = prt_params%grperc(ft) * & - (max(0._r8,currentCohort%gpp_tstep - currentCohort%resp_m)) - - - currentCohort%resp_tstep = currentCohort%resp_m + & - currentCohort%resp_g_tstep ! kgC/indiv/ts - currentCohort%npp_tstep = currentCohort%gpp_tstep - & - currentCohort%resp_tstep ! kgC/indiv/ts - + + ! save as a diagnostic the un-throttled maintenance respiration to be able to know how strong this is + currentCohort%resp_m_unreduced = currentCohort%resp_m_tstep / maintresp_reduction_factor + ! Accumulate the combined conductance (stomatal+leaf boundary layer) ! Note that currentCohort%g_sb_laweight is weighted by the leaf area ! of each cohort and has units of [m/s] * [m2 leaf] diff --git a/main/EDMainMod.F90 b/main/EDMainMod.F90 index 1e7ee14e13..01111c0626 100644 --- a/main/EDMainMod.F90 +++ b/main/EDMainMod.F90 @@ -102,6 +102,7 @@ module EDMainMod use PRTGenericMod, only : repro_organ use PRTGenericMod, only : struct_organ use PRTLossFluxesMod, only : PRTMaintTurnover + use PRTParametersMod , only : prt_params use EDPftvarcon, only : EDPftvarcon_inst use FatesHistoryInterfaceMod, only : fates_hist @@ -232,7 +233,7 @@ subroutine ed_ecosystem_dynamics(currentSite, bc_in, bc_out) ! values. If we aren't entering that sequence, we need to set the flag ! Make sure cohorts are marked as non-recruits - call bypass_dynamics(currentSite) + call bypass_dynamics(currentSite,bc_out) end if @@ -340,7 +341,8 @@ subroutine ed_integrate_state_variables(currentSite, bc_in, bc_out ) use FatesConstantsMod, only : itrue use FatesConstantsMod , only : nearzero use EDCanopyStructureMod , only : canopy_structure - + + ! !ARGUMENTS: type(ed_site_type) , intent(inout) :: currentSite @@ -481,6 +483,7 @@ subroutine ed_integrate_state_variables(currentSite, bc_in, bc_out ) currentPatch%age_since_anthro_disturbance, current_fates_landuse_state_vector(primaryland), & current_fates_landuse_state_vector(secondaryland), harvestable_forest_c, harvest_tag) + ! ----------------------------------------------------------------------------- ! Apply Plant Allocation and Reactive Transport ! ----------------------------------------------------------------------------- @@ -503,7 +506,7 @@ subroutine ed_integrate_state_variables(currentSite, bc_in, bc_out ) ! We don't explicitly define a respiration rate for prescribe phys ! but we do need to pass mass balance. So we say it is zero respiration currentCohort%gpp_acc = currentCohort%npp_acc - currentCohort%resp_acc = 0._r8 + currentCohort%resp_m_acc = 0._r8 end if @@ -519,15 +522,29 @@ subroutine ed_integrate_state_variables(currentSite, bc_in, bc_out ) ! photosynthesis step ! ----------------------------------------------------------------------------- - currentCohort%npp_acc_hold = currentCohort%npp_acc * real(hlm_days_per_year,r8) currentCohort%gpp_acc_hold = currentCohort%gpp_acc * real(hlm_days_per_year,r8) - currentCohort%resp_acc_hold = currentCohort%resp_acc * real(hlm_days_per_year,r8) + currentCohort%resp_m_acc_hold = currentCohort%resp_m_acc * real(hlm_days_per_year,r8) + + ! at this point we have the info we need to calculate growth respiration + ! as a "tax" on the difference between daily GPP and daily maintenance respiration + if (hlm_use_ed_prescribed_phys .eq. ifalse) then + + currentCohort%resp_g_acc_hold = prt_params%grperc(ft) * & + max(0._r8,(currentCohort%gpp_acc - currentCohort%resp_m_acc)) * real(hlm_days_per_year,r8) - ! Passing gpp_acc_hold to HLM - bc_out%gpp_site = bc_out%gpp_site + currentCohort%gpp_acc_hold * & - AREA_INV * currentCohort%n / hlm_days_per_year / sec_per_day - bc_out%ar_site = bc_out%ar_site + currentCohort%resp_acc_hold * & - AREA_INV * currentCohort%n / hlm_days_per_year / sec_per_day + else + ! set growth respiration to zero in prescribed physiology mode, + ! that way the npp_acc vars will be set to the nominal gpp values set above. + currentCohort%resp_g_acc_hold = 0._r8 + endif + + ! calculate the npp as the difference between gpp and autotrophic respiration + ! (NPP is also updated if there is any excess respiration from nutrient limitations) + currentCohort%npp_acc = currentCohort%gpp_acc - & + (currentCohort%resp_m_acc + currentCohort%resp_g_acc_hold/real(hlm_days_per_year,r8)) + currentCohort%npp_acc_hold = currentCohort%gpp_acc_hold - & + (currentCohort%resp_m_acc_hold + currentCohort%resp_g_acc_hold) + ! Conduct Maintenance Turnover (parteh) if(debug) call currentCohort%prt%CheckMassConservation(ft,3) @@ -555,7 +572,7 @@ subroutine ed_integrate_state_variables(currentSite, bc_in, bc_out ) currentCohort%daily_n_gain = currentCohort%daily_nh4_uptake + & currentCohort%daily_no3_uptake + currentCohort%sym_nfix_daily - currentCohort%resp_excess = 0._r8 + currentCohort%resp_excess_hold = 0._r8 end if if_not_newlyrecovered @@ -604,11 +621,30 @@ subroutine ed_integrate_state_variables(currentSite, bc_in, bc_out ) end if call currentCohort%prt%DailyPRT(phase=3) + + ! If nutrients are limiting growth, and carbon continues + ! to accumulate beyond the plant's storage capacity, then + ! it will burn carbon as what we call "excess respiration" + ! We must subtract this term from NPP. We do not need to subtract it from + ! currentCohort%npp_acc, it has already been removed from this in + ! the daily growth code (PARTEH). + + currentCohort%npp_acc_hold = currentCohort%npp_acc_hold - currentCohort%resp_excess_hold + + ! Passing gpp_acc_hold to HLM + bc_out%gpp_site = bc_out%gpp_site + currentCohort%gpp_acc_hold * & + AREA_INV * currentCohort%n / hlm_days_per_year / 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) * & + 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 ! ----------------------------------------------------------------------------- + + call EffluxIntoLitterPools(currentSite, currentPatch, currentCohort, bc_in ) @@ -633,14 +669,16 @@ subroutine ed_integrate_state_variables(currentSite, bc_in, bc_out ) ! Save NPP diagnostic for flux accounting [kg/m2/day] currentSite%flux_diags%npp = currentSite%flux_diags%npp + & - (currentCohort%npp_acc_hold/hlm_days_per_year - currentCohort%resp_excess) * currentCohort%n * area_inv + currentCohort%npp_acc_hold/hlm_days_per_year * currentCohort%n * area_inv ! And simultaneously add the input fluxes to mass balance accounting site_cmass%gpp_acc = site_cmass%gpp_acc + & currentCohort%gpp_acc * currentCohort%n site_cmass%aresp_acc = site_cmass%aresp_acc + & - (currentCohort%resp_acc+currentCohort%resp_excess) * currentCohort%n + currentCohort%resp_m_acc*currentCohort%n + & + (currentCohort%resp_g_acc_hold+currentCohort%resp_excess_hold) * & + currentCohort%n/real( hlm_days_per_year,r8) call currentCohort%prt%CheckMassConservation(ft,5) @@ -664,7 +702,7 @@ subroutine ed_integrate_state_variables(currentSite, bc_in, bc_out ) currentCohort%npp_acc = 0.0_r8 currentCohort%gpp_acc = 0.0_r8 - currentCohort%resp_acc = 0.0_r8 + currentCohort%resp_m_acc = 0.0_r8 ! BOC...update tree 'hydraulic geometry' ! (size --> heights of elements --> hydraulic path lengths --> @@ -1004,7 +1042,7 @@ subroutine TotalBalanceCheck (currentSite, call_index ) write(fates_log(),*) 'leaf: ',leaf_m,' structure: ',struct_m,' store: ',store_m write(fates_log(),*) 'fineroot: ',fnrt_m,' repro: ',repro_m,' sapwood: ',sapw_m write(fates_log(),*) 'num plant: ',currentCohort%n - write(fates_log(),*) 'resp excess: ',currentCohort%resp_excess*currentCohort%n + write(fates_log(),*) 'resp excess: ',currentCohort%resp_excess_hold*currentCohort%n if(element_list(el).eq.nitrogen_element) then write(fates_log(),*) 'NH4 uptake: ',currentCohort%daily_nh4_uptake*currentCohort%n @@ -1043,7 +1081,7 @@ end subroutine TotalBalanceCheck ! ===================================================================================== - subroutine bypass_dynamics(currentSite) + subroutine bypass_dynamics(currentSite, bc_out) ! ---------------------------------------------------------------------------------- ! If dynamics are bypassed, various fluxes, rates and flags need to be set @@ -1053,12 +1091,16 @@ subroutine bypass_dynamics(currentSite) ! ---------------------------------------------------------------------------------- ! Arguments - type(ed_site_type) , intent(inout), target :: currentSite - + type(ed_site_type) , intent(inout) :: currentSite + type(bc_out_type) , intent(inout) :: bc_out + ! Locals type(fates_patch_type), pointer :: currentPatch type(fates_cohort_type), pointer :: currentCohort + bc_out%gpp_site = 0._r8 + bc_out%ar_site = 0._r8 + currentPatch => currentSite%youngest_patch do while(associated(currentPatch)) currentCohort => currentPatch%shortest @@ -1066,13 +1108,17 @@ subroutine bypass_dynamics(currentSite) currentCohort%isnew=.false. + currentCohort%resp_g_acc_hold = prt_params%grperc(currentCohort%pft) * & + max(0._r8,(currentCohort%gpp_acc - currentCohort%resp_m_acc))*real(hlm_days_per_year,r8) + currentCohort%npp_acc_hold = currentCohort%npp_acc * real(hlm_days_per_year,r8) currentCohort%gpp_acc_hold = currentCohort%gpp_acc * real(hlm_days_per_year,r8) - currentCohort%resp_acc_hold = currentCohort%resp_acc * real(hlm_days_per_year,r8) - + currentCohort%resp_m_acc_hold = currentCohort%resp_m_acc * real(hlm_days_per_year,r8) + + currentCohort%resp_excess_hold = 0._r8 currentCohort%npp_acc = 0.0_r8 currentCohort%gpp_acc = 0.0_r8 - currentCohort%resp_acc = 0.0_r8 + currentCohort%resp_m_acc = 0.0_r8 ! No need to set the "net_art" terms to zero ! they are zeroed at the beginning of the daily step @@ -1095,6 +1141,13 @@ subroutine bypass_dynamics(currentSite) ! as they should just be zero, no uptake ! in ST3 mode. + ! Passing + bc_out%gpp_site = bc_out%gpp_site + currentCohort%gpp_acc_hold * & + AREA_INV * currentCohort%n / hlm_days_per_year / 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) * & + AREA_INV * currentCohort%n / hlm_days_per_year / sec_per_day + currentCohort => currentCohort%taller enddo currentPatch => currentPatch%older diff --git a/main/FatesHistoryInterfaceMod.F90 b/main/FatesHistoryInterfaceMod.F90 index 1215f1745a..55287c40f5 100644 --- a/main/FatesHistoryInterfaceMod.F90 +++ b/main/FatesHistoryInterfaceMod.F90 @@ -352,11 +352,9 @@ module FatesHistoryInterfaceMod integer :: ih_understory_biomass_si integer :: ih_maint_resp_unreduced_si - integer :: ih_npp_secondary_si + ! these "secondary" flux diagnostics should be reorganized to be site x land-use type rather than just secondary, and also moved to daily timestep. integer :: ih_gpp_secondary_si - integer :: ih_aresp_secondary_si integer :: ih_maint_resp_secondary_si - integer :: ih_growth_resp_secondary_si integer :: ih_primaryland_fusion_error_si @@ -2160,7 +2158,7 @@ subroutine update_history_nutrflux(this,csite) ! Excess carbon respired this%hvars(ih_excess_resp_si)%r81d(io_si) = & this%hvars(ih_excess_resp_si)%r81d(io_si) + & - ccohort%resp_excess*uconv + ccohort%resp_excess_hold*uconv/days_per_year case (nitrogen_element) @@ -2424,6 +2422,9 @@ subroutine update_history_dyn1(this,nc,nsites,sites,bc_in) hio_sum_fuel_si => this%hvars(ih_sum_fuel_si)%r81d, & hio_litter_in_si => this%hvars(ih_litter_in_si)%r81d, & hio_litter_out_si => this%hvars(ih_litter_out_si)%r81d, & + hio_npp_si => this%hvars(ih_npp_si)%r81d, & + hio_aresp_si => this%hvars(ih_aresp_si)%r81d, & + hio_growth_resp_si => this%hvars(ih_growth_resp_si)%r81d, & hio_seed_bank_si => this%hvars(ih_seed_bank_si)%r81d, & hio_ungerm_seed_bank_si => this%hvars(ih_ungerm_seed_bank_si)%r81d, & hio_seedling_pool_si => this%hvars(ih_seedling_pool_si)%r81d, & @@ -2867,6 +2868,16 @@ subroutine update_history_dyn1(this,nc,nsites,sites,bc_in) ! have any meaning, otherwise they are just inialization values notnew: if( .not.(ccohort%isnew) ) then + hio_npp_si(io_si) = hio_npp_si(io_si) + & + ccohort%npp_acc_hold * n_perm2 / days_per_year / sec_per_day + + hio_growth_resp_si(io_si) = hio_growth_resp_si(io_si) + & + ccohort%resp_g_acc_hold * n_perm2 / days_per_year / sec_per_day + + hio_aresp_si(io_si) = hio_aresp_si(io_si) + & + (ccohort%resp_g_acc_hold + ccohort%resp_m_acc_hold + & + ccohort%resp_excess_hold) * n_perm2 / days_per_year / sec_per_day + ! Turnover pools [kgC/day] * [day/yr] = [kgC/yr] sapw_m_turnover = ccohort%prt%GetTurnover(sapw_organ, carbon12_element) * days_per_year store_m_turnover = ccohort%prt%GetTurnover(store_organ, carbon12_element) * days_per_year @@ -3121,7 +3132,7 @@ subroutine update_history_dyn2(this,nc,nsites,sites,bc_in) hio_canopycrownarea_si_pft => this%hvars(ih_canopycrownarea_si_pft)%r82d, & hio_gpp_si_pft => this%hvars(ih_gpp_si_pft)%r82d, & hio_gpp_sec_si_pft => this%hvars(ih_gpp_sec_si_pft)%r82d, & - hio_npp_si_pft => this%hvars(ih_npp_si_pft)%r82d, & + hio_npp_si_pft => this%hvars(ih_npp_si_pft)%r82d, & hio_npp_sec_si_pft => this%hvars(ih_npp_sec_si_pft)%r82d, & hio_fragmentation_scaler_sl => this%hvars(ih_fragmentation_scaler_sl)%r82d, & hio_litter_in_elem => this%hvars(ih_litter_in_elem)%r82d, & @@ -3273,6 +3284,7 @@ subroutine update_history_dyn2(this,nc,nsites,sites,bc_in) hio_npatches_si_age => this%hvars(ih_npatches_si_age)%r82d, & hio_zstar_si_age => this%hvars(ih_zstar_si_age)%r82d, & hio_biomass_si_age => this%hvars(ih_biomass_si_age)%r82d, & + hio_npp_si_age => this%hvars(ih_npp_si_age)%r82d, & hio_agesince_anthrodist_si_age => this%hvars(ih_agesince_anthrodist_si_age)%r82d, & hio_secondarylands_area_si_age => this%hvars(ih_secondarylands_area_si_age)%r82d, & hio_area_si_landuse => this%hvars(ih_area_si_landuse)%r82d, & @@ -3937,6 +3949,11 @@ subroutine update_history_dyn2(this,nc,nsites,sites,bc_in) hio_biomass_si_scls(io_si,scls) = hio_biomass_si_scls(io_si,scls) + & total_m * ccohort%n * AREA_INV + ! age-resolved cohort-based areas + + hio_npp_si_age(io_si,cpatch%age_class) = hio_npp_si_age(io_si,cpatch%age_class) + & + ccohort%n * ccohort%npp_acc_hold * AREA_INV / days_per_year / sec_per_day + ! update size-class x patch-age related quantities iscag = get_sizeage_class_index(ccohort%dbh,cpatch%age) @@ -4003,7 +4020,8 @@ subroutine update_history_dyn2(this,nc,nsites,sites,bc_in) hio_gpp_canopy_si_scpf(io_si,scpf) = hio_gpp_canopy_si_scpf(io_si,scpf) + & n_perm2*ccohort%gpp_acc_hold / days_per_year / sec_per_day hio_ar_canopy_si_scpf(io_si,scpf) = hio_ar_canopy_si_scpf(io_si,scpf) + & - n_perm2*ccohort%resp_acc_hold / days_per_year / sec_per_day + n_perm2*(ccohort%resp_m_acc_hold + ccohort%resp_g_acc_hold + & + ccohort%resp_excess_hold) / days_per_year / sec_per_day ! growth increment hio_ddbh_canopy_si_scpf(io_si,scpf) = hio_ddbh_canopy_si_scpf(io_si,scpf) + & ccohort%ddbhdt*ccohort%n * m_per_cm / m2_per_ha @@ -4138,7 +4156,8 @@ subroutine update_history_dyn2(this,nc,nsites,sites,bc_in) hio_gpp_understory_si_scpf(io_si,scpf) = hio_gpp_understory_si_scpf(io_si,scpf) + & n_perm2*ccohort%gpp_acc_hold / days_per_year / sec_per_day hio_ar_understory_si_scpf(io_si,scpf) = hio_ar_understory_si_scpf(io_si,scpf) + & - n_perm2*ccohort%resp_acc_hold / days_per_year / sec_per_day + n_perm2*(ccohort%resp_m_acc_hold + ccohort%resp_g_acc_hold + & + ccohort%resp_excess_hold) / days_per_year / sec_per_day ! growth increment hio_ddbh_understory_si_scpf(io_si,scpf) = hio_ddbh_understory_si_scpf(io_si,scpf) + & @@ -4941,14 +4960,8 @@ subroutine update_history_hifrq1(this,nc,nsites,sites,bc_in,bc_out,dt_tstep) associate( hio_gpp_si => this%hvars(ih_gpp_si)%r81d, & hio_gpp_secondary_si => this%hvars(ih_gpp_secondary_si)%r81d, & - hio_npp_si => this%hvars(ih_npp_si)%r81d, & - hio_npp_secondary_si => this%hvars(ih_npp_secondary_si)%r81d, & - hio_aresp_si => this%hvars(ih_aresp_si)%r81d, & - hio_aresp_secondary_si => this%hvars(ih_aresp_secondary_si)%r81d, & hio_maint_resp_si => this%hvars(ih_maint_resp_si)%r81d, & hio_maint_resp_secondary_si => this%hvars(ih_maint_resp_secondary_si)%r81d, & - hio_growth_resp_si => this%hvars(ih_growth_resp_si)%r81d, & - hio_growth_resp_secondary_si => this%hvars(ih_growth_resp_secondary_si)%r81d, & hio_c_stomata_si => this%hvars(ih_c_stomata_si)%r81d, & hio_c_lblayer_si => this%hvars(ih_c_lblayer_si)%r81d, & hio_vis_rad_err_si => this%hvars(ih_vis_rad_err_si)%r81d, & @@ -5084,44 +5097,27 @@ subroutine update_history_hifrq1(this,nc,nsites,sites,bc_in,bc_out,dt_tstep) ! scale up cohort fluxes to the site level ! these fluxes have conversions of [kg/plant/timestep] -> [kg/m2/s] - hio_npp_si(io_si) = hio_npp_si(io_si) + & - ccohort%npp_tstep * n_perm2 * dt_tstep_inv - - ! Net Ecosystem Production [kgC/m2/s] + ! Net Ecosystem Production [kgC/m2/s]. Use yesterday's growth respiration hio_nep_si(io_si) = hio_nep_si(io_si) + & - ccohort%npp_tstep * n_perm2 * dt_tstep_inv + (ccohort%gpp_tstep-ccohort%resp_m_tstep) * n_perm2 * dt_tstep_inv - & + (ccohort%resp_g_acc_hold+ccohort%resp_excess_hold) * n_perm2 / days_per_year / sec_per_day hio_gpp_si(io_si) = hio_gpp_si(io_si) + & ccohort%gpp_tstep * n_perm2 * dt_tstep_inv - hio_aresp_si(io_si) = hio_aresp_si(io_si) + & - ccohort%resp_tstep * n_perm2 * dt_tstep_inv - - hio_growth_resp_si(io_si) = hio_growth_resp_si(io_si) + & - ccohort%resp_g_tstep * n_perm2 * dt_tstep_inv - hio_maint_resp_si(io_si) = hio_maint_resp_si(io_si) + & - ccohort%resp_m * n_perm2 * dt_tstep_inv + ccohort%resp_m_tstep * n_perm2 * dt_tstep_inv hio_maint_resp_unreduced_si(io_si) = hio_maint_resp_unreduced_si(io_si) + & ccohort%resp_m_unreduced * n_perm2 * dt_tstep_inv ! Secondary forest only if(cpatch%land_use_label .eq. secondaryland) then - hio_npp_secondary_si(io_si) = hio_npp_secondary_si(io_si) + & - ccohort%npp_tstep * n_perm2 * dt_tstep_inv - hio_gpp_secondary_si(io_si) = hio_gpp_secondary_si(io_si) + & ccohort%gpp_tstep * n_perm2 * dt_tstep_inv - hio_aresp_secondary_si(io_si) = hio_aresp_secondary_si(io_si) + & - ccohort%resp_tstep * n_perm2 * dt_tstep_inv - - hio_growth_resp_secondary_si(io_si) = hio_growth_resp_secondary_si(io_si) + & - ccohort%resp_g_tstep * n_perm2 * dt_tstep_inv - hio_maint_resp_secondary_si(io_si) = hio_maint_resp_secondary_si(io_si) + & - ccohort%resp_m * n_perm2 * dt_tstep_inv + ccohort%resp_m_tstep * n_perm2 * dt_tstep_inv end if ! Maintenance respiration of different organs @@ -5141,17 +5137,11 @@ subroutine update_history_hifrq1(this,nc,nsites,sites,bc_in,bc_out,dt_tstep) hio_gpp_canopy_si(io_si) = hio_gpp_canopy_si(io_si) + & ccohort%gpp_tstep * n_perm2 * dt_tstep_inv - hio_ar_canopy_si(io_si) = hio_ar_canopy_si(io_si) + & - ccohort%resp_tstep * n_perm2 * dt_tstep_inv - else hio_gpp_understory_si(io_si) = hio_gpp_understory_si(io_si) + & ccohort%gpp_tstep * n_perm2 * dt_tstep_inv - hio_ar_understory_si(io_si) = hio_ar_understory_si(io_si) + & - ccohort%resp_tstep * n_perm2 * dt_tstep_inv - end if end if if_notnew @@ -5197,15 +5187,12 @@ subroutine update_history_hifrq2(this,nc,nsites,sites,bc_in,bc_out,dt_tstep) integer :: ivar ! index of IO variable object vector integer :: ft ! functional type index real(r8) :: n_density ! individual of cohort per m2. - real(r8) :: resp_g ! growth respiration per timestep [kgC/indiv/step] - real(r8) :: npp ! npp for this time-step (adjusted for g resp) [kgC/indiv/step] - real(r8) :: aresp ! autotrophic respiration (adjusted for g resp) [kgC/indiv/step] real(r8) :: n_perm2 ! individuals per m2 for the whole column real(r8) :: patch_area_by_age(nlevage) ! patch area in each bin for normalizing purposes real(r8) :: canopy_area_by_age(nlevage) ! canopy area in each bin for normalizing purposes real(r8) :: site_area_veg_inv ! 1/area of the site that is not bare-ground integer :: ipa2 ! patch incrementer - integer :: clllpf_indx, cnlf_indx, ipft, ican, ileaf ! more iterators and indices + integer :: clllpf_indx, cnlf_indx, ipft, ican, ileaf ! more iterators and indices real(r8) :: clllpf_area ! area footprint (m2) for the current cl x ll x pft bin real(r8) :: clll_area ! area footprint (m2) for the cl x ll bin (ie adds up pfts in parallel) real(r8) :: cl_area ! total weight of all ll x pft bins in the canopy layer @@ -5234,7 +5221,6 @@ subroutine update_history_hifrq2(this,nc,nsites,sites,bc_in,bc_out,dt_tstep) hio_resp_g_understory_si_scls => this%hvars(ih_resp_g_understory_si_scls)%r82d, & hio_resp_m_understory_si_scls => this%hvars(ih_resp_m_understory_si_scls)%r82d, & hio_gpp_si_age => this%hvars(ih_gpp_si_age)%r82d, & - hio_npp_si_age => this%hvars(ih_npp_si_age)%r82d, & hio_c_stomata_si_age => this%hvars(ih_c_stomata_si_age)%r82d, & hio_c_lblayer_si_age => this%hvars(ih_c_lblayer_si_age)%r82d, & hio_parsun_z_si_cnlf => this%hvars(ih_parsun_z_si_cnlf)%r82d, & @@ -5297,8 +5283,6 @@ subroutine update_history_hifrq2(this,nc,nsites,sites,bc_in,bc_out,dt_tstep) canopy_area_by_age(cpatch%age_class) = & canopy_area_by_age(cpatch%age_class) + cpatch%total_canopy_area - - ! Canopy resitance terms hio_c_stomata_si_age(io_si,cpatch%age_class) = & hio_c_stomata_si_age(io_si,cpatch%age_class) + & @@ -5315,25 +5299,22 @@ subroutine update_history_hifrq2(this,nc,nsites,sites,bc_in,bc_out,dt_tstep) if ( .not. ccohort%isnew ) then - npp = ccohort%npp_tstep - resp_g = ccohort%resp_g_tstep - aresp = ccohort%resp_tstep - ! Calculate index for the scpf class associate( scpf => ccohort%size_by_pft_class, & scls => ccohort%size_class ) ! Total AR (kgC/m2/s) = (kgC/plant/step) / (s/step) * (plant/m2) hio_ar_si_scpf(io_si,scpf) = hio_ar_si_scpf(io_si,scpf) + & - (ccohort%resp_tstep*dt_tstep_inv) * n_perm2 + (ccohort%resp_m_tstep*dt_tstep_inv) * n_perm2 + & + (ccohort%resp_g_acc_hold + ccohort%resp_excess_hold)* n_perm2 / days_per_year / sec_per_day - ! Growth AR (kgC/m2/s) + ! Growth AR (kgC/m2/s) ! CDK: this should be daily hio_ar_grow_si_scpf(io_si,scpf) = hio_ar_grow_si_scpf(io_si,scpf) + & - (resp_g*dt_tstep_inv) * n_perm2 + ccohort%resp_g_acc_hold * n_perm2 / days_per_year / sec_per_day ! Maint AR (kgC/m2/s) hio_ar_maint_si_scpf(io_si,scpf) = hio_ar_maint_si_scpf(io_si,scpf) + & - (ccohort%resp_m*dt_tstep_inv) * n_perm2 + (ccohort%resp_m_tstep*dt_tstep_inv) * n_perm2 ! Maintenance AR partition variables are stored as rates (kgC/plant/s) ! (kgC/m2/s) = (kgC/plant/s) * (plant/m2) @@ -5356,9 +5337,6 @@ subroutine update_history_hifrq2(this,nc,nsites,sites,bc_in,bc_out,dt_tstep) hio_gpp_si_age(io_si,cpatch%age_class) = hio_gpp_si_age(io_si,cpatch%age_class) & + ccohort%gpp_tstep * ccohort%n * dt_tstep_inv - hio_npp_si_age(io_si,cpatch%age_class) = hio_npp_si_age(io_si,cpatch%age_class) & - + npp * ccohort%n * dt_tstep_inv - ! accumulate fluxes on canopy- and understory- separated fluxes if (ccohort%canopy_layer .eq. 1) then @@ -5372,9 +5350,9 @@ subroutine update_history_hifrq2(this,nc,nsites,sites,bc_in,bc_out,dt_tstep) hio_froot_mr_canopy_si_scls(io_si,scls) = hio_froot_mr_canopy_si_scls(io_si,scls) + & ccohort%froot_mr * ccohort%n * ha_per_m2 hio_resp_g_canopy_si_scls(io_si,scls) = hio_resp_g_canopy_si_scls(io_si,scls) + & - resp_g * ccohort%n * dt_tstep_inv * ha_per_m2 + ccohort%resp_g_acc_hold * n_perm2 / days_per_year / sec_per_day hio_resp_m_canopy_si_scls(io_si,scls) = hio_resp_m_canopy_si_scls(io_si,scls) + & - ccohort%resp_m * ccohort%n * dt_tstep_inv * ha_per_m2 + ccohort%resp_m_tstep * ccohort%n * dt_tstep_inv * ha_per_m2 else ! size-resolved respiration fluxes are in kg C / m2 / s @@ -5387,9 +5365,9 @@ subroutine update_history_hifrq2(this,nc,nsites,sites,bc_in,bc_out,dt_tstep) hio_froot_mr_understory_si_scls(io_si,scls) = hio_froot_mr_understory_si_scls(io_si,scls) + & ccohort%froot_mr * ccohort%n * ha_per_m2 hio_resp_g_understory_si_scls(io_si,scls) = hio_resp_g_understory_si_scls(io_si,scls) + & - resp_g * ccohort%n * dt_tstep_inv * ha_per_m2 + ccohort%resp_g_acc_hold * n_perm2 / days_per_year / sec_per_day hio_resp_m_understory_si_scls(io_si,scls) = hio_resp_m_understory_si_scls(io_si,scls) + & - ccohort%resp_m * ccohort%n * dt_tstep_inv * ha_per_m2 + ccohort%resp_m_tstep * ccohort%n * dt_tstep_inv * ha_per_m2 endif end associate endif @@ -5593,11 +5571,8 @@ subroutine update_history_hifrq2(this,nc,nsites,sites,bc_in,bc_out,dt_tstep) if (patch_area_by_age(ipa2) .gt. nearzero) then hio_gpp_si_age(io_si, ipa2) = & hio_gpp_si_age(io_si, ipa2) / (patch_area_by_age(ipa2)) - hio_npp_si_age(io_si, ipa2) = & - hio_npp_si_age(io_si, ipa2) / (patch_area_by_age(ipa2)) else hio_gpp_si_age(io_si, ipa2) = 0._r8 - hio_npp_si_age(io_si, ipa2) = 0._r8 endif ! Normalize resistance diagnostics @@ -6431,6 +6406,23 @@ subroutine define_history_vars(this, initialize_variables) upfreq=group_dyna_simple, ivar=ivar, initialize=initialize_variables, & index = ih_reproc_si) + call this%set_history_var(vname='FATES_NPP', units='kg m-2 s-1', & + long='net primary production in kg carbon per m2 per second', & + use_default='active', avgflag='A', vtype=site_r8, hlms='CLM:ALM', & + upfreq=group_dyna_simple, ivar=ivar, initialize=initialize_variables, index = ih_npp_si) + + call this%set_history_var(vname='FATES_AUTORESP', units='kg m-2 s-1', & + long='autotrophic respiration in kg carbon per m2 per second', & + use_default='active', avgflag='A', vtype=site_r8, hlms='CLM:ALM', & + upfreq=group_dyna_simple, ivar=ivar, initialize=initialize_variables, index = ih_aresp_si) + + call this%set_history_var(vname='FATES_GROWTH_RESP', units='kg m-2 s-1', & + long='growth respiration in kg carbon per m2 per second', & + use_default='active', avgflag='A', vtype=site_r8, hlms='CLM:ALM', & + upfreq=group_dyna_simple, ivar=ivar, initialize=initialize_variables, & + index = ih_growth_resp_si) + + ! Output specific to the chemical species dynamics used (parteh) call this%set_history_var(vname='FATES_L2FR', units='kg kg-1', & long='The leaf to fineroot biomass multiplier for target allometry', & @@ -7476,6 +7468,12 @@ subroutine define_history_vars(this, initialize_variables) hlms='CLM:ALM', upfreq=group_dyna_complx, ivar=ivar, & initialize=initialize_variables, index = ih_npp_si_agepft) + call this%set_history_var(vname='FATES_NPP_AP', units='kg m-2 s-1', & + long='net primary productivity by age bin in kg carbon per m2 per second', & + use_default='inactive', avgflag='A', vtype=site_age_r8, & + hlms='CLM:ALM', upfreq=group_dyna_complx, ivar=ivar, initialize=initialize_variables, & + index = ih_npp_si_age) + call this%set_history_var(vname='FATES_VEGC_APPF',units = 'kg m-2', & long='biomass per PFT in each age bin in kg carbon per m2', & use_default='inactive', avgflag='A', vtype=site_agepft_r8, & @@ -8593,16 +8591,6 @@ subroutine define_history_vars(this, initialize_variables) ! Ecosystem Carbon Fluxes (updated rapidly, upfreq=group_hifr_simple) - call this%set_history_var(vname='FATES_NPP', units='kg m-2 s-1', & - long='net primary production in kg carbon per m2 per second', & - use_default='active', avgflag='A', vtype=site_r8, hlms='CLM:ALM', & - upfreq=group_hifr_simple, ivar=ivar, initialize=initialize_variables, index = ih_npp_si) - - call this%set_history_var(vname='FATES_NPP_SECONDARY', units='kg m-2 s-1', & - long='net primary production in kg carbon per m2 per second, secondary patches', & - use_default='active', avgflag='A', vtype=site_r8, hlms='CLM:ALM', & - upfreq=group_hifr_simple, ivar=ivar, initialize=initialize_variables, index = ih_npp_secondary_si) - call this%set_history_var(vname='FATES_GPP', units='kg m-2 s-1', & long='gross primary production in kg carbon per m2 per second', & use_default='active', avgflag='A', vtype=site_r8, hlms='CLM:ALM', & @@ -8613,28 +8601,6 @@ subroutine define_history_vars(this, initialize_variables) use_default='active', avgflag='A', vtype=site_r8, hlms='CLM:ALM', & upfreq=group_hifr_simple, ivar=ivar, initialize=initialize_variables, index = ih_gpp_secondary_si) - call this%set_history_var(vname='FATES_AUTORESP', units='kg m-2 s-1', & - long='autotrophic respiration in kg carbon per m2 per second', & - use_default='active', avgflag='A', vtype=site_r8, hlms='CLM:ALM', & - upfreq=group_hifr_simple, ivar=ivar, initialize=initialize_variables, index = ih_aresp_si) - - call this%set_history_var(vname='FATES_AUTORESP_SECONDARY', units='kg m-2 s-1', & - long='autotrophic respiration in kg carbon per m2 per second, secondary patches', & - use_default='active', avgflag='A', vtype=site_r8, hlms='CLM:ALM', & - upfreq=group_hifr_simple, ivar=ivar, initialize=initialize_variables, index = ih_aresp_secondary_si) - - call this%set_history_var(vname='FATES_GROWTH_RESP', units='kg m-2 s-1', & - long='growth respiration in kg carbon per m2 per second', & - use_default='active', avgflag='A', vtype=site_r8, hlms='CLM:ALM', & - upfreq=group_hifr_simple, ivar=ivar, initialize=initialize_variables, & - index = ih_growth_resp_si) - - call this%set_history_var(vname='FATES_GROWTH_RESP_SECONDARY', units='kg m-2 s-1', & - long='growth respiration in kg carbon per m2 per second, secondary patches', & - use_default='active', avgflag='A', vtype=site_r8, hlms='CLM:ALM', & - upfreq=group_hifr_simple, ivar=ivar, initialize=initialize_variables, & - index = ih_growth_resp_secondary_si) - call this%set_history_var(vname='FATES_MAINT_RESP', units='kg m-2 s-1', & long='maintenance respiration in kg carbon per m2 land area per second', & use_default='active', avgflag='A', vtype=site_r8, hlms='CLM:ALM', & @@ -8775,12 +8741,6 @@ subroutine define_history_vars(this, initialize_variables) ! over the short timestep. We turn off these variables when we want ! to save time (and some space) - call this%set_history_var(vname='FATES_NPP_AP', units='kg m-2 s-1', & - long='net primary productivity by age bin in kg carbon per m2 per second', & - use_default='inactive', avgflag='A', vtype=site_age_r8, & - hlms='CLM:ALM', upfreq=group_hifr_complx, ivar=ivar, initialize=initialize_variables, & - index = ih_npp_si_age) - call this%set_history_var(vname='FATES_GPP_AP', units='kg m-2 s-1', & long='gross primary productivity by age bin in kg carbon per m2 per second', & use_default='inactive', avgflag='A', vtype=site_age_r8, & diff --git a/main/FatesInventoryInitMod.F90 b/main/FatesInventoryInitMod.F90 index 2ca4c3554f..4b945741fd 100644 --- a/main/FatesInventoryInitMod.F90 +++ b/main/FatesInventoryInitMod.F90 @@ -798,6 +798,7 @@ subroutine set_inventory_cohort_type1(csite,bc_in,css_file_unit,npatches, & class(prt_vartypes), pointer :: prt_obj real(r8) :: c_time ! Time patch was recorded character(len=patchname_strlen) :: p_name ! The patch associated with this cohort + character(len=patchname_strlen) :: c_name ! Cohort name real(r8) :: c_dbh ! diameter at breast height (cm) real(r8) :: c_height ! tree height (m) integer :: c_pft ! plant functional type index @@ -840,11 +841,17 @@ subroutine set_inventory_cohort_type1(csite,bc_in,css_file_unit,npatches, & real(r8), parameter :: abnormal_large_dbh = 500.0_r8 ! I've never heard of a tree > 3m real(r8), parameter :: abnormal_large_height = 500.0_r8 ! I've never heard of a tree > 500m tall integer, parameter :: recruitstatus = 0 + logical, parameter :: old_type1_override = .false. - - read(css_file_unit,fmt=*,iostat=ios) c_time, p_name, c_dbh, & - c_height, c_pft, c_nplant - + if(old_type1_override) then + ! time patch cohort dbh hite pft nplant bdead alive Avgrg + read(css_file_unit,fmt=*,iostat=ios) c_time, p_name, c_name, c_dbh, & + c_height, c_pft, c_nplant + else + read(css_file_unit,fmt=*,iostat=ios) c_time, p_name, c_dbh, & + c_height, c_pft, c_nplant + end if + if( debug_inv) then write(*,fmt=wr_fmt) & c_time, p_name, c_dbh, c_height, c_pft, c_nplant diff --git a/main/FatesRestartInterfaceMod.F90 b/main/FatesRestartInterfaceMod.F90 index 7f890e5ecc..bf63274d0e 100644 --- a/main/FatesRestartInterfaceMod.F90 +++ b/main/FatesRestartInterfaceMod.F90 @@ -138,10 +138,11 @@ module FatesRestartInterfaceMod integer :: ir_nplant_co integer :: ir_gpp_acc_co integer :: ir_npp_acc_co - integer :: ir_resp_acc_co + integer :: ir_resp_m_acc_co integer :: ir_gpp_acc_hold_co integer :: ir_npp_acc_hold_co - integer :: ir_resp_acc_hold_co + integer :: ir_resp_m_acc_hold_co + integer :: ir_resp_g_acc_hold_co integer :: ir_resp_excess_co integer :: ir_bmort_co integer :: ir_hmort_co @@ -186,7 +187,7 @@ module FatesRestartInterfaceMod integer :: ir_ddbhdt_co - integer :: ir_resp_tstep_co + integer :: ir_resp_m_tstep_co integer :: ir_pft_co integer :: ir_status_co integer :: ir_efleaf_co @@ -881,10 +882,10 @@ subroutine define_restart_vars(this, initialize_variables) units='kgC/indiv', flushval = flushzero, & hlms='CLM:ALM', initialize=initialize_variables, ivar=ivar, index = ir_npp_acc_co ) - call this%set_restart_var(vname='fates_resp_acc', vtype=cohort_r8, & - long_name='ed cohort - accumulated respiration over dynamics step', & + call this%set_restart_var(vname='fates_resp_m_acc', vtype=cohort_r8, & + long_name='ed cohort - accumulated maintenance respiration over dynamics step', & units='kgC/indiv', flushval = flushzero, & - hlms='CLM:ALM', initialize=initialize_variables, ivar=ivar, index = ir_resp_acc_co ) + hlms='CLM:ALM', initialize=initialize_variables, ivar=ivar, index = ir_resp_m_acc_co ) call this%set_restart_var(vname='fates_gpp_acc_hold', vtype=cohort_r8, & long_name='ed cohort - current step gpp', & @@ -896,10 +897,15 @@ subroutine define_restart_vars(this, initialize_variables) units='kgC/indiv/year', flushval = flushzero, & hlms='CLM:ALM', initialize=initialize_variables, ivar=ivar, index = ir_npp_acc_hold_co ) - call this%set_restart_var(vname='fates_resp_acc_hold', vtype=cohort_r8, & - long_name='ed cohort - current step resp', & + call this%set_restart_var(vname='fates_resp_m_acc_hold', vtype=cohort_r8, & + long_name='ed cohort - current step maint resp', & units='kgC/indiv/year', flushval = flushzero, & - hlms='CLM:ALM', initialize=initialize_variables, ivar=ivar, index = ir_resp_acc_hold_co ) + hlms='CLM:ALM', initialize=initialize_variables, ivar=ivar, index = ir_resp_m_acc_hold_co ) + + call this%set_restart_var(vname='fates_resp_g_acc_hold', vtype=cohort_r8, & + long_name='ed cohort - current step growth resp', & + units='kgC/indiv/year', flushval = flushzero, & + hlms='CLM:ALM', initialize=initialize_variables, ivar=ivar, index = ir_resp_g_acc_hold_co ) call this%set_restart_var(vname='fates_resp_excess', vtype=cohort_r8, & long_name='ed cohort - maintenance respiration deficit', & @@ -963,10 +969,10 @@ subroutine define_restart_vars(this, initialize_variables) units='cm/year', flushval = flushzero, & hlms='CLM:ALM', initialize=initialize_variables, ivar=ivar, index = ir_ddbhdt_co ) - call this%set_restart_var(vname='fates_resp_tstep', vtype=cohort_r8, & - long_name='ed cohort - autotrophic respiration over timestep', & + call this%set_restart_var(vname='fates_resp_m_tstep', vtype=cohort_r8, & + long_name='ed cohort - maintenance respiration over timestep', & units='kgC/indiv/timestep', flushval = flushzero, & - hlms='CLM:ALM', initialize=initialize_variables, ivar=ivar, index = ir_resp_tstep_co ) + hlms='CLM:ALM', initialize=initialize_variables, ivar=ivar, index = ir_resp_m_tstep_co ) call this%set_restart_var(vname='fates_pft', vtype=cohort_int, & long_name='ed cohort - plant functional type', units='index', flushval = flushzero, & @@ -2118,9 +2124,10 @@ subroutine set_restart_vectors(this,nc,nsites,sites) rio_nplant_co => this%rvars(ir_nplant_co)%r81d, & rio_gpp_acc_co => this%rvars(ir_gpp_acc_co)%r81d, & rio_npp_acc_co => this%rvars(ir_npp_acc_co)%r81d, & - rio_resp_acc_co => this%rvars(ir_resp_acc_co)%r81d, & + rio_resp_m_acc_co => this%rvars(ir_resp_m_acc_co)%r81d, & rio_gpp_acc_hold_co => this%rvars(ir_gpp_acc_hold_co)%r81d, & - rio_resp_acc_hold_co => this%rvars(ir_resp_acc_hold_co)%r81d, & + rio_resp_m_acc_hold_co => this%rvars(ir_resp_m_acc_hold_co)%r81d, & + rio_resp_g_acc_hold_co => this%rvars(ir_resp_g_acc_hold_co)%r81d, & rio_npp_acc_hold_co => this%rvars(ir_npp_acc_hold_co)%r81d, & rio_resp_excess_co => this%rvars(ir_resp_excess_co)%r81d, & rio_bmort_co => this%rvars(ir_bmort_co)%r81d, & @@ -2134,7 +2141,7 @@ subroutine set_restart_vectors(this,nc,nsites,sites) rio_lmort_collateral_co => this%rvars(ir_lmort_collateral_co)%r81d, & rio_lmort_infra_co => this%rvars(ir_lmort_infra_co)%r81d, & rio_ddbhdt_co => this%rvars(ir_ddbhdt_co)%r81d, & - rio_resp_tstep_co => this%rvars(ir_resp_tstep_co)%r81d, & + rio_resp_m_tstep_co => this%rvars(ir_resp_m_tstep_co)%r81d, & rio_pft_co => this%rvars(ir_pft_co)%int1d, & rio_status_co => this%rvars(ir_status_co)%int1d, & rio_efleaf_co => this%rvars(ir_efleaf_co)%r81d, & @@ -2464,12 +2471,13 @@ subroutine set_restart_vectors(this,nc,nsites,sites) rio_nplant_co(io_idx_co) = ccohort%n rio_gpp_acc_co(io_idx_co) = ccohort%gpp_acc rio_npp_acc_co(io_idx_co) = ccohort%npp_acc - rio_resp_acc_co(io_idx_co) = ccohort%resp_acc + rio_resp_m_acc_co(io_idx_co) = ccohort%resp_m_acc rio_gpp_acc_hold_co(io_idx_co) = ccohort%gpp_acc_hold - rio_resp_acc_hold_co(io_idx_co) = ccohort%resp_acc_hold + rio_resp_m_acc_hold_co(io_idx_co) = ccohort%resp_m_acc_hold + rio_resp_g_acc_hold_co(io_idx_co) = ccohort%resp_g_acc_hold rio_npp_acc_hold_co(io_idx_co) = ccohort%npp_acc_hold - rio_resp_excess_co(io_idx_co) = ccohort%resp_excess + rio_resp_excess_co(io_idx_co) = ccohort%resp_excess_hold rio_bmort_co(io_idx_co) = ccohort%bmort rio_hmort_co(io_idx_co) = ccohort%hmort @@ -2486,7 +2494,7 @@ subroutine set_restart_vectors(this,nc,nsites,sites) rio_lmort_infra_co(io_idx_co) = ccohort%lmort_infra rio_ddbhdt_co(io_idx_co) = ccohort%ddbhdt - rio_resp_tstep_co(io_idx_co) = ccohort%resp_tstep + rio_resp_m_tstep_co(io_idx_co) = ccohort%resp_m_tstep rio_pft_co(io_idx_co) = ccohort%pft rio_status_co(io_idx_co) = ccohort%status_coh rio_efleaf_co(io_idx_co) = ccohort%efleaf_coh @@ -3119,9 +3127,10 @@ subroutine get_restart_vectors(this, nc, nsites, sites) rio_nplant_co => this%rvars(ir_nplant_co)%r81d, & rio_gpp_acc_co => this%rvars(ir_gpp_acc_co)%r81d, & rio_npp_acc_co => this%rvars(ir_npp_acc_co)%r81d, & - rio_resp_acc_co => this%rvars(ir_resp_acc_co)%r81d, & + rio_resp_m_acc_co => this%rvars(ir_resp_m_acc_co)%r81d, & rio_gpp_acc_hold_co => this%rvars(ir_gpp_acc_hold_co)%r81d, & - rio_resp_acc_hold_co => this%rvars(ir_resp_acc_hold_co)%r81d, & + rio_resp_m_acc_hold_co => this%rvars(ir_resp_m_acc_hold_co)%r81d, & + rio_resp_g_acc_hold_co => this%rvars(ir_resp_g_acc_hold_co)%r81d, & rio_npp_acc_hold_co => this%rvars(ir_npp_acc_hold_co)%r81d, & rio_resp_excess_co => this%rvars(ir_resp_excess_co)%r81d, & rio_bmort_co => this%rvars(ir_bmort_co)%r81d, & @@ -3135,7 +3144,7 @@ subroutine get_restart_vectors(this, nc, nsites, sites) rio_lmort_collateral_co => this%rvars(ir_lmort_collateral_co)%r81d, & rio_lmort_infra_co => this%rvars(ir_lmort_infra_co)%r81d, & rio_ddbhdt_co => this%rvars(ir_ddbhdt_co)%r81d, & - rio_resp_tstep_co => this%rvars(ir_resp_tstep_co)%r81d, & + rio_resp_m_tstep_co => this%rvars(ir_resp_m_tstep_co)%r81d, & rio_pft_co => this%rvars(ir_pft_co)%int1d, & rio_status_co => this%rvars(ir_status_co)%int1d, & rio_efleaf_co => this%rvars(ir_efleaf_co)%r81d, & @@ -3429,11 +3438,12 @@ subroutine get_restart_vectors(this, nc, nsites, sites) ccohort%n = rio_nplant_co(io_idx_co) ccohort%gpp_acc = rio_gpp_acc_co(io_idx_co) ccohort%npp_acc = rio_npp_acc_co(io_idx_co) - ccohort%resp_acc = rio_resp_acc_co(io_idx_co) + ccohort%resp_m_acc = rio_resp_m_acc_co(io_idx_co) ccohort%gpp_acc_hold = rio_gpp_acc_hold_co(io_idx_co) - ccohort%resp_acc_hold = rio_resp_acc_hold_co(io_idx_co) + ccohort%resp_m_acc_hold = rio_resp_m_acc_hold_co(io_idx_co) + ccohort%resp_g_acc_hold = rio_resp_g_acc_hold_co(io_idx_co) ccohort%npp_acc_hold = rio_npp_acc_hold_co(io_idx_co) - ccohort%resp_excess = rio_resp_excess_co(io_idx_co) + ccohort%resp_excess_hold = rio_resp_excess_co(io_idx_co) ccohort%bmort = rio_bmort_co(io_idx_co) ccohort%hmort = rio_hmort_co(io_idx_co) @@ -3451,7 +3461,7 @@ subroutine get_restart_vectors(this, nc, nsites, sites) ccohort%lmort_infra = rio_lmort_infra_co(io_idx_co) ccohort%ddbhdt = rio_ddbhdt_co(io_idx_co) - ccohort%resp_tstep = rio_resp_tstep_co(io_idx_co) + ccohort%resp_m_tstep = rio_resp_m_tstep_co(io_idx_co) ccohort%pft = rio_pft_co(io_idx_co) ccohort%status_coh = rio_status_co(io_idx_co) ccohort%efleaf_coh = rio_efleaf_co(io_idx_co)