From e2d192e2c3914200d561d188abf548fb37320301 Mon Sep 17 00:00:00 2001 From: Peter Lawrence Date: Thu, 1 Mar 2018 15:04:31 -0700 Subject: [PATCH 01/27] Added new files to allow Gross Unrepresented Land Use transition --- src/biogeochem/CNBalanceCheckMod.F90 | 10 +- src/biogeochem/CNCIsoFluxMod.F90 | 279 +++++++++ src/biogeochem/CNCStateUpdate2Mod.F90 | 115 ++++ src/biogeochem/CNDriverMod.F90 | 54 +- src/biogeochem/CNNStateUpdate2Mod.F90 | 108 ++++ src/biogeochem/CNProductsMod.F90 | 86 ++- src/biogeochem/CNVegCarbonFluxType.F90 | 302 +++++++++- src/biogeochem/CNVegNitrogenFluxType.F90 | 151 ++++- src/biogeochem/CNVegetationFacade.F90 | 9 + src/biogeochem/dynConsBiogeochemMod.F90 | 70 ++- src/biogeochem/dynGrossUnrepMod.F90 | 528 ++++++++++++++++++ src/dyn_subgrid/dynSubgridControlMod.F90 | 35 ++ src/dyn_subgrid/dynSubgridDriverMod.F90 | 11 + .../SoilBiogeochemCarbonStateType.F90 | 27 +- .../SoilBiogeochemNitrogenStateType.F90 | 27 +- 15 files changed, 1719 insertions(+), 93 deletions(-) create mode 100644 src/biogeochem/dynGrossUnrepMod.F90 diff --git a/src/biogeochem/CNBalanceCheckMod.F90 b/src/biogeochem/CNBalanceCheckMod.F90 index f2811d290a..4a34f95f9c 100644 --- a/src/biogeochem/CNBalanceCheckMod.F90 +++ b/src/biogeochem/CNBalanceCheckMod.F90 @@ -141,6 +141,8 @@ subroutine CBalanceCheck(this, bounds, num_soilc, filter_soilc, & col_begcb => this%begcb_col , & ! Input: [real(r8) (:) ] (gC/m2) carbon mass, beginning of time step col_endcb => this%endcb_col , & ! Output: [real(r8) (:) ] (gC/m2) carbon mass, end of time step wood_harvestc => cnveg_carbonflux_inst%wood_harvestc_col , & ! Input: [real(r8) (:) ] (gC/m2/s) wood harvest (to product pools) + gru_conv_cflux => cnveg_carbonflux_inst%gru_conv_cflux_col , & ! Input: [real(r8) (:) ] (gC/m2/s) wood harvest (to product pools) + gru_wood_productc_gain => cnveg_carbonflux_inst%gru_wood_productc_gain_col , & ! Input: [real(r8) (:) ] (gC/m2/s) wood harvest (to product pools) grainc_to_cropprodc => cnveg_carbonflux_inst%grainc_to_cropprodc_col , & ! Input: [real(r8) (:) ] (gC/m2/s) grain C to 1-year crop product pool gpp => cnveg_carbonflux_inst%gpp_col , & ! Input: [real(r8) (:) ] (gC/m2/s) gross primary production er => cnveg_carbonflux_inst%er_col , & ! Input: [real(r8) (:) ] (gC/m2/s) total ecosystem respiration, autotrophic + heterotrophic @@ -167,7 +169,7 @@ subroutine CBalanceCheck(this, bounds, num_soilc, filter_soilc, & ! calculate total column-level outputs ! er = ar + hr, col_fire_closs includes patch-level fire losses - col_coutputs = er(c) + col_fire_closs(c) + col_hrv_xsmrpool_to_atm(c) + col_coutputs = er(c) + col_fire_closs(c) + col_hrv_xsmrpool_to_atm(c) + gru_conv_cflux(c) ! Fluxes to product pools are included in column-level outputs: the product ! pools are not included in totcolc, so are outside the system with respect to @@ -176,6 +178,7 @@ subroutine CBalanceCheck(this, bounds, num_soilc, filter_soilc, & ! after the dwt term has already been taken out.) col_coutputs = col_coutputs + & wood_harvestc(c) + & + gru_wood_productc_gain(c) + & grainc_to_cropprodc(c) ! subtract leaching flux @@ -268,6 +271,8 @@ subroutine NBalanceCheck(this, bounds, num_soilc, filter_soilc, & col_fire_nloss => cnveg_nitrogenflux_inst%fire_nloss_col , & ! Input: [real(r8) (:) ] (gN/m2/s) total column-level fire N loss wood_harvestn => cnveg_nitrogenflux_inst%wood_harvestn_col , & ! Input: [real(r8) (:) ] (gN/m2/s) wood harvest (to product pools) + gru_conv_nflux => cnveg_nitrogenflux_inst%gru_conv_nflux_col , & ! Input: [real(r8) (:) ] (gC/m2/s) wood harvest (to product pools) + gru_wood_productn_gain => cnveg_nitrogenflux_inst%gru_wood_productn_gain_col , & ! Input: [real(r8) (:) ] (gC/m2/s) wood harvest (to product pools) grainn_to_cropprodn => cnveg_nitrogenflux_inst%grainn_to_cropprodn_col , & ! Input: [real(r8) (:) ] (gN/m2/s) grain N to 1-year crop product pool totcoln => cnveg_nitrogenstate_inst%totn_col & ! Input: [real(r8) (:) ] (gN/m2) total column nitrogen, incl veg @@ -295,7 +300,7 @@ subroutine NBalanceCheck(this, bounds, num_soilc, filter_soilc, & end if ! calculate total column-level outputs - col_noutputs(c) = denit(c) + col_fire_nloss(c) + col_noutputs(c) = denit(c) + col_fire_nloss(c) + gru_conv_nflux(c) ! Fluxes to product pools are included in column-level outputs: the product ! pools are not included in totcoln, so are outside the system with respect to @@ -304,6 +309,7 @@ subroutine NBalanceCheck(this, bounds, num_soilc, filter_soilc, & ! after the dwt term has already been taken out.) col_noutputs(c) = col_noutputs(c) + & wood_harvestn(c) + & + gru_wood_productn_gain(c) + & grainn_to_cropprodn(c) if (.not. use_nitrif_denitrif) then diff --git a/src/biogeochem/CNCIsoFluxMod.F90 b/src/biogeochem/CNCIsoFluxMod.F90 index a92ab44e47..4d5e88a247 100644 --- a/src/biogeochem/CNCIsoFluxMod.F90 +++ b/src/biogeochem/CNCIsoFluxMod.F90 @@ -28,12 +28,14 @@ module CNCIsoFluxMod public :: CIsoFlux1 public :: CIsoFlux2 public :: CIsoFlux2h + public :: CIsoFlux2g public :: CIsoFlux3 ! ! !PRIVATE MEMBER FUNCTIONS: private :: CNCIsoLitterToColumn private :: CNCIsoGapPftToColumn private :: CNCIsoHarvestPftToColumn + private :: CNCIsoGrossUnrepPftToColumn private :: CIsoFluxCalc character(len=*), parameter, private :: sourcefile = & @@ -803,6 +805,157 @@ subroutine CIsoFlux2h(num_soilc , filter_soilc, num_soilp , filter_soilp, & end subroutine CIsoFlux2h + !----------------------------------------------------------------------- + subroutine CIsoFlux2g(num_soilc , filter_soilc, num_soilp , filter_soilp, & + soilbiogeochem_state_inst, & + cnveg_carbonflux_inst, cnveg_carbonstate_inst, & + iso_cnveg_carbonflux_inst, iso_cnveg_carbonstate_inst, isotope) + ! + ! !DESCRIPTION: + ! set the carbon isotopic fluxes for gross unrepresented landcover change mortality + ! + ! !ARGUMENTS: + integer , intent(in) :: num_soilc ! number of soil columns filter + integer , intent(in) :: filter_soilc(:) ! filter for soil columns + integer , intent(in) :: num_soilp ! number of soil patches in filter + integer , intent(in) :: filter_soilp(:) ! filter for soil patches + type(soilbiogeochem_state_type) , intent(in) :: soilbiogeochem_state_inst + type(cnveg_carbonflux_type) , intent(in) :: cnveg_carbonflux_inst + type(cnveg_carbonstate_type) , intent(in) :: cnveg_carbonstate_inst + type(cnveg_carbonflux_type) , intent(inout) :: iso_cnveg_carbonflux_inst + type(cnveg_carbonstate_type) , intent(in) :: iso_cnveg_carbonstate_inst + character(len=*) , intent(in) :: isotope ! 'c13' or 'c14' + + !----------------------------------------------------------------------- + + associate( & + cnveg_cf => cnveg_carbonflux_inst , & + cnveg_cs => cnveg_carbonstate_inst , & + iso_cnveg_cf => iso_cnveg_carbonflux_inst , & + iso_cnveg_cs => iso_cnveg_carbonstate_inst & + ) + + ! patch-level gap mortality fluxes + + call CIsoFluxCalc(& + iso_cnveg_cf%gru_leafc_to_litter_patch , cnveg_cf%gru_leafc_to_litter_patch, & + iso_cnveg_cs%leafc_patch , cnveg_cs%leafc_patch, & + num_soilp , filter_soilp, 1._r8, 0, isotope) + + call CIsoFluxCalc(& + iso_cnveg_cf%gru_leafc_storage_to_atm_patch , cnveg_cf%gru_leafc_storage_to_atm_patch, & + iso_cnveg_cs%leafc_storage_patch , cnveg_cs%leafc_storage_patch, & + num_soilp , filter_soilp, 1._r8, 0, isotope) + + call CIsoFluxCalc(& + iso_cnveg_cf%gru_leafc_xfer_to_atm_patch , cnveg_cf%gru_leafc_xfer_to_atm_patch, & + iso_cnveg_cs%leafc_xfer_patch , cnveg_cs%leafc_xfer_patch, & + num_soilp , filter_soilp, 1._r8, 0, isotope) + + call CIsoFluxCalc(& + iso_cnveg_cf%gru_frootc_to_litter_patch , cnveg_cf%gru_frootc_to_litter_patch, & + iso_cnveg_cs%frootc_patch , cnveg_cs%frootc_patch, & + num_soilp , filter_soilp, 1._r8, 0, isotope) + + call CIsoFluxCalc(& + iso_cnveg_cf%gru_frootc_storage_to_atm_patch , cnveg_cf%gru_frootc_storage_to_atm_patch, & + iso_cnveg_cs%frootc_storage_patch , cnveg_cs%frootc_storage_patch, & + num_soilp , filter_soilp, 1._r8, 0, isotope) + + call CIsoFluxCalc(& + iso_cnveg_cf%gru_frootc_xfer_to_atm_patch , cnveg_cf%gru_frootc_xfer_to_atm_patch, & + iso_cnveg_cs%frootc_xfer_patch , cnveg_cs%frootc_xfer_patch, & + num_soilp , filter_soilp, 1._r8, 0, isotope) + + call CIsoFluxCalc(& + iso_cnveg_cf%gru_livestemc_to_atm_patch , cnveg_cf%gru_livestemc_to_atm_patch, & + iso_cnveg_cs%livestemc_patch , cnveg_cs%livestemc_patch, & + num_soilp , filter_soilp, 1._r8, 0, isotope) + + call CIsoFluxCalc(& + iso_cnveg_cf%gru_livestemc_storage_to_atm_patch , cnveg_cf%gru_livestemc_storage_to_atm_patch, & + iso_cnveg_cs%livestemc_storage_patch , cnveg_cs%livestemc_storage_patch, & + num_soilp , filter_soilp, 1._r8, 0, isotope) + + call CIsoFluxCalc(& + iso_cnveg_cf%gru_livestemc_xfer_to_atm_patch , cnveg_cf%gru_livestemc_xfer_to_atm_patch, & + iso_cnveg_cs%livestemc_xfer_patch , cnveg_cs%livestemc_xfer_patch, & + num_soilp , filter_soilp, 1._r8, 0, isotope) + + call CIsoFluxCalc(& + iso_cnveg_cf%gru_deadstemc_to_atm_patch , cnveg_cf%gru_deadstemc_to_atm_patch, & + iso_cnveg_cs%deadstemc_patch , cnveg_cs%deadstemc_patch, & + num_soilp , filter_soilp, 1._r8, 0, isotope) + + call CIsoFluxCalc(& + iso_cnveg_cf%gru_wood_productc_gain_patch , cnveg_cf%gru_wood_productc_gain_patch, & + iso_cnveg_cs%deadstemc_patch , cnveg_cs%deadstemc_patch, & + num_soilp , filter_soilp, 1._r8, 0, isotope) + + call CIsoFluxCalc(& + iso_cnveg_cf%gru_deadstemc_storage_to_atm_patch , cnveg_cf%gru_deadstemc_storage_to_atm_patch, & + iso_cnveg_cs%deadstemc_storage_patch , cnveg_cs%deadstemc_storage_patch, & + num_soilp , filter_soilp, 1._r8, 0, isotope) + + call CIsoFluxCalc(& + iso_cnveg_cf%gru_deadstemc_xfer_to_atm_patch , cnveg_cf%gru_deadstemc_xfer_to_atm_patch, & + iso_cnveg_cs%deadstemc_xfer_patch , cnveg_cs%deadstemc_xfer_patch, & + num_soilp , filter_soilp, 1._r8, 0, isotope) + + call CIsoFluxCalc(& + iso_cnveg_cf%gru_livecrootc_to_litter_patch , cnveg_cf%gru_livecrootc_to_litter_patch, & + iso_cnveg_cs%livecrootc_patch , cnveg_cs%livecrootc_patch, & + num_soilp , filter_soilp, 1._r8, 0, isotope) + + call CIsoFluxCalc(& + iso_cnveg_cf%gru_livecrootc_storage_to_atm_patch , cnveg_cf%gru_livecrootc_storage_to_atm_patch, & + iso_cnveg_cs%livecrootc_storage_patch , cnveg_cs%livecrootc_storage_patch, & + num_soilp , filter_soilp, 1._r8, 0, isotope) + + call CIsoFluxCalc(& + iso_cnveg_cf%gru_livecrootc_xfer_to_atm_patch , cnveg_cf%gru_livecrootc_xfer_to_atm_patch, & + iso_cnveg_cs%livecrootc_xfer_patch , cnveg_cs%livecrootc_xfer_patch, & + num_soilp , filter_soilp, 1._r8, 0, isotope) + + call CIsoFluxCalc(& + iso_cnveg_cf%gru_deadcrootc_to_litter_patch , cnveg_cf%gru_deadcrootc_to_litter_patch, & + iso_cnveg_cs%deadcrootc_patch , cnveg_cs%deadcrootc_patch, & + num_soilp , filter_soilp, 1._r8, 0, isotope) + + call CIsoFluxCalc(& + iso_cnveg_cf%gru_deadcrootc_storage_to_atm_patch , cnveg_cf%gru_deadcrootc_storage_to_atm_patch, & + iso_cnveg_cs%deadcrootc_storage_patch , cnveg_cs%deadcrootc_storage_patch, & + num_soilp , filter_soilp, 1._r8, 0, isotope) + + call CIsoFluxCalc(& + iso_cnveg_cf%gru_deadcrootc_xfer_to_atm_patch , cnveg_cf%gru_deadcrootc_xfer_to_atm_patch, & + iso_cnveg_cs%deadcrootc_xfer_patch , cnveg_cs%deadcrootc_xfer_patch, & + num_soilp , filter_soilp, 1._r8, 0, isotope) + + call CIsoFluxCalc(& + iso_cnveg_cf%gru_gresp_storage_to_atm_patch , cnveg_cf%gru_gresp_storage_to_atm_patch, & + iso_cnveg_cs%gresp_storage_patch , cnveg_cs%gresp_storage_patch, & + num_soilp , filter_soilp, 1._r8, 0, isotope) + + call CIsoFluxCalc(& + iso_cnveg_cf%gru_gresp_xfer_to_atm_patch , cnveg_cf%gru_gresp_xfer_to_atm_patch, & + iso_cnveg_cs%gresp_xfer_patch , cnveg_cs%gresp_xfer_patch, & + num_soilp , filter_soilp, 1._r8, 0, isotope) + + call CIsoFluxCalc(& + iso_cnveg_cf%gru_xsmrpool_to_atm_patch , cnveg_cf%gru_xsmrpool_to_atm_patch, & + iso_cnveg_cs%totvegc_patch , cnveg_cs%totvegc_patch, & + num_soilp , filter_soilp, 1._r8, 0, isotope) + + ! call routine to shift patch-level gap mortality fluxes to column, + ! for isotopes the non-isotope version of this routine is in CNGapMortalityMod.F90. + + call CNCIsoGrossUnrepPftToColumn(num_soilc, filter_soilc, soilbiogeochem_state_inst, iso_cnveg_carbonflux_inst) + + end associate + + end subroutine CIsoFlux2g + !----------------------------------------------------------------------- subroutine CIsoFlux3(num_soilc , filter_soilc, num_soilp , filter_soilp, & soilbiogeochem_state_inst , soilbiogeochem_carbonstate_inst, & @@ -1550,6 +1703,132 @@ subroutine CNCIsoHarvestPftToColumn (num_soilc, filter_soilc, & end subroutine CNCIsoHarvestPftToColumn + !----------------------------------------------------------------------- + subroutine CNCIsoGrossUnrepPftToColumn (num_soilc, filter_soilc, & + soilbiogeochem_state_inst, iso_cnveg_carbonflux_inst) + ! + ! !DESCRIPTION: + ! gather all patch-level gross unrepresented landcover change mortality fluxes + ! to the column level and assign them to the litter, cwd, and wood product pools + ! + ! !ARGUMENTS: + integer , intent(in) :: num_soilc ! number of soil columns in filter + integer , intent(in) :: filter_soilc(:) ! soil column filter + type(soilbiogeochem_state_type) , intent(in) :: soilbiogeochem_state_inst + type(cnveg_carbonflux_type) , intent(inout) :: iso_cnveg_carbonflux_inst + ! + ! !LOCAL VARIABLES: + integer :: fc,c,pi,p,j ! indices + !----------------------------------------------------------------------- + + associate( & + ivt => patch%itype , & ! Input: [integer (:) ] patch vegetation type + wtcol => patch%wtcol , & ! Input: [real(r8) (:) ] patch weight relative to column (0-1) + + lf_flab => pftcon%lf_flab , & ! Input: leaf litter labile fraction + lf_fcel => pftcon%lf_fcel , & ! Input: leaf litter cellulose fraction + lf_flig => pftcon%lf_flig , & ! Input: leaf litter lignin fraction + fr_flab => pftcon%fr_flab , & ! Input: fine root litter labile fraction + fr_fcel => pftcon%fr_fcel , & ! Input: fine root litter cellulose fraction + fr_flig => pftcon%fr_flig , & ! Input: fine root litter lignin fraction + + leaf_prof => soilbiogeochem_state_inst%leaf_prof_patch , & ! Input: [real(r8) (:,:) ] (1/m) profile of leaves + froot_prof => soilbiogeochem_state_inst%froot_prof_patch , & ! Input: [real(r8) (:,:) ] (1/m) profile of fine roots + croot_prof => soilbiogeochem_state_inst%croot_prof_patch , & ! Input: [real(r8) (:,:) ] (1/m) profile of coarse roots + stem_prof => soilbiogeochem_state_inst%stem_prof_patch , & ! Input: [real(r8) (:,:) ] (1/m) profile of stems + + gru_leafc_to_litter => iso_cnveg_carbonflux_inst%gru_leafc_to_litter_patch , & ! Input: [real(r8) (:) ] + gru_frootc_to_litter => iso_cnveg_carbonflux_inst%gru_frootc_to_litter_patch , & ! Input: [real(r8) (:) ] + gru_livestemc_to_atm => iso_cnveg_carbonflux_inst%gru_livestemc_to_atm_patch , & ! Input: [real(r8) (:) ] + gru_deadstemc_to_atm => iso_cnveg_carbonflux_inst%gru_deadstemc_to_atm_patch , & ! Input: [real(r8) (:) ] + gru_wood_productc_gain => iso_cnveg_carbonflux_inst%gru_wood_productc_gain_patch , & ! Input: [real(r8) (:) ] + gru_livecrootc_to_litter => iso_cnveg_carbonflux_inst%gru_livecrootc_to_litter_patch , & ! Input: [real(r8) (:) ] + gru_deadcrootc_to_litter => iso_cnveg_carbonflux_inst%gru_deadcrootc_to_litter_patch , & ! Input: [real(r8) (:) ] + gru_leafc_storage_to_atm => iso_cnveg_carbonflux_inst%gru_leafc_storage_to_atm_patch , & ! Input: [real(r8) (:) ] + gru_frootc_storage_to_atm => iso_cnveg_carbonflux_inst%gru_frootc_storage_to_atm_patch , & ! Input: [real(r8) (:) ] + gru_livestemc_storage_to_atm => iso_cnveg_carbonflux_inst%gru_livestemc_storage_to_atm_patch , & ! Input: [real(r8) (:) ] + gru_deadstemc_storage_to_atm => iso_cnveg_carbonflux_inst%gru_deadstemc_storage_to_atm_patch , & ! Input: [real(r8) (:) ] + gru_livecrootc_storage_to_atm => iso_cnveg_carbonflux_inst%gru_livecrootc_storage_to_atm_patch , & ! Input: [real(r8) (:) ] + gru_deadcrootc_storage_to_atm => iso_cnveg_carbonflux_inst%gru_deadcrootc_storage_to_atm_patch , & ! Input: [real(r8) (:) ] + gru_gresp_storage_to_atm => iso_cnveg_carbonflux_inst%gru_gresp_storage_to_atm_patch , & ! Input: [real(r8) (:) ] + gru_leafc_xfer_to_atm => iso_cnveg_carbonflux_inst%gru_leafc_xfer_to_atm_patch , & ! Input: [real(r8) (:) ] + gru_frootc_xfer_to_atm => iso_cnveg_carbonflux_inst%gru_frootc_xfer_to_atm_patch , & ! Input: [real(r8) (:) ] + gru_livestemc_xfer_to_atm => iso_cnveg_carbonflux_inst%gru_livestemc_xfer_to_atm_patch , & ! Input: [real(r8) (:) ] + gru_deadstemc_xfer_to_atm => iso_cnveg_carbonflux_inst%gru_deadstemc_xfer_to_atm_patch , & ! Input: [real(r8) (:) ] + gru_livecrootc_xfer_to_atm => iso_cnveg_carbonflux_inst%gru_livecrootc_xfer_to_atm_patch , & ! Input: [real(r8) (:) ] + gru_deadcrootc_xfer_to_atm => iso_cnveg_carbonflux_inst%gru_deadcrootc_xfer_to_atm_patch , & ! Input: [real(r8) (:) ] + gru_gresp_xfer_to_atm => iso_cnveg_carbonflux_inst%gru_gresp_xfer_to_atm_patch , & ! Input: [real(r8) (:) ] + cwood_harvestc => iso_cnveg_carbonflux_inst%wood_harvestc_col , & ! Output: [real(r8) (:) ] + gru_c_to_litr_met_c => iso_cnveg_carbonflux_inst%gru_c_to_litr_met_c_col , & ! Output: [real(r8) (:,:) ] C fluxes associated with harvest to litter metabolic pool (gC/m3/s) + gru_c_to_litr_cel_c => iso_cnveg_carbonflux_inst%gru_c_to_litr_cel_c_col , & ! Output: [real(r8) (:,:) ] C fluxes associated with harvest to litter cellulose pool (gC/m3/s) + gru_c_to_litr_lig_c => iso_cnveg_carbonflux_inst%gru_c_to_litr_lig_c_col , & ! Output: [real(r8) (:,:) ] C fluxes associated with harvest to litter lignin pool (gC/m3/s) + gru_c_to_cwdc_c => iso_cnveg_carbonflux_inst%gru_c_to_cwdc_col , & ! Output: [real(r8) (:,:) ] C fluxes associated with harvest to CWD pool (gC/m3/s) + gru_wood_productc_gain_c => iso_cnveg_carbonflux_inst%gru_wood_productc_gain_col & ! Input: [real(r8) (:) ] + ) + + do j = 1, nlevdecomp + do pi = 1,maxpatch_pft + do fc = 1,num_soilc + c = filter_soilc(fc) + + if (pi <= col%npatches(c)) then + p = col%patchi(c) + pi - 1 + + if (patch%active(p)) then + + ! leaf gross unrepresented landcover change mortality carbon fluxes + gru_c_to_litr_met_c(c,j) = gru_c_to_litr_met_c(c,j) + & + gru_leafc_to_litter(p) * lf_flab(ivt(p)) * wtcol(p) * leaf_prof(p,j) + gru_c_to_litr_cel_c(c,j) = gru_c_to_litr_cel_c(c,j) + & + gru_leafc_to_litter(p) * lf_fcel(ivt(p)) * wtcol(p) * leaf_prof(p,j) + gru_c_to_litr_lig_c(c,j) = gru_c_to_litr_lig_c(c,j) + & + gru_leafc_to_litter(p) * lf_flig(ivt(p)) * wtcol(p) * leaf_prof(p,j) + + ! fine root gross unrepresented landcover change mortality carbon fluxes + gru_c_to_litr_met_c(c,j) = gru_c_to_litr_met_c(c,j) + & + gru_frootc_to_litter(p) * fr_flab(ivt(p)) * wtcol(p) * froot_prof(p,j) + gru_c_to_litr_cel_c(c,j) = gru_c_to_litr_cel_c(c,j) + & + gru_frootc_to_litter(p) * fr_fcel(ivt(p)) * wtcol(p) * froot_prof(p,j) + gru_c_to_litr_lig_c(c,j) = gru_c_to_litr_lig_c(c,j) + & + gru_frootc_to_litter(p) * fr_flig(ivt(p)) * wtcol(p) * froot_prof(p,j) + + ! coarse root gross unrepresented landcover change mortality carbon fluxes + gru_c_to_cwdc_c(c,j) = gru_c_to_cwdc_c(c,j) + & + gru_livecrootc_to_litter(p) * wtcol(p) * croot_prof(p,j) + gru_c_to_cwdc_c(c,j) = gru_c_to_cwdc_c(c,j) + & + gru_deadcrootc_to_litter(p) * wtcol(p) * croot_prof(p,j) + + end if + end if + + end do + + end do + end do + + do pi = 1,maxpatch_pft + do fc = 1,num_soilc + c = filter_soilc(fc) + + if (pi <= col%npatches(c)) then + p = col%patchi(c) + pi - 1 + + if (patch%active(p)) then + ! wood gross unrepresented landcover change mortality carbon fluxes to product pools + gru_wood_productc_gain_c(c) = gru_wood_productc_gain_c(c) + & + gru_wood_productc_gain(p) * wtcol(p) + + end if + end if + + end do + + end do + + end associate + + end subroutine CNCIsoGrossUnrepPftToColumn + !----------------------------------------------------------------------- subroutine CIsoFluxCalc(& ciso_flux, ctot_flux, & diff --git a/src/biogeochem/CNCStateUpdate2Mod.F90 b/src/biogeochem/CNCStateUpdate2Mod.F90 index ef1f6f9345..38bf5bcfc5 100644 --- a/src/biogeochem/CNCStateUpdate2Mod.F90 +++ b/src/biogeochem/CNCStateUpdate2Mod.F90 @@ -20,6 +20,7 @@ module CNCStateUpdate2Mod ! !PUBLIC MEMBER FUNCTIONS: public:: CStateUpdate2 public:: CStateUpdate2h + public:: CStateUpdate2g !----------------------------------------------------------------------- contains @@ -244,4 +245,118 @@ subroutine CStateUpdate2h(num_soilc, filter_soilc, num_soilp, filter_soilp, & end subroutine CStateUpdate2h + !----------------------------------------------------------------------- + subroutine CStateUpdate2g(num_soilc, filter_soilc, num_soilp, filter_soilp, & + cnveg_carbonflux_inst, cnveg_carbonstate_inst, soilbiogeochem_carbonstate_inst) + ! + ! !DESCRIPTION: + ! Update all the prognostic carbon state + ! variables affected by gross unrepresented landcover change mortality fluxes + ! + ! !ARGUMENTS: + integer , intent(in) :: num_soilc ! number of soil columns in filter + integer , intent(in) :: filter_soilc(:) ! filter for soil columns + integer , intent(in) :: num_soilp ! number of soil patches in filter + integer , intent(in) :: filter_soilp(:) ! filter for soil patches + type(cnveg_carbonflux_type) , intent(in) :: cnveg_carbonflux_inst + type(cnveg_carbonstate_type) , intent(inout) :: cnveg_carbonstate_inst + type(soilbiogeochem_carbonstate_type) , intent(inout) :: soilbiogeochem_carbonstate_inst + ! + ! !LOCAL VARIABLES: + integer :: c,p,j,k,l ! indices + integer :: fp,fc ! lake filter indices + real(r8):: dt ! radiation time step (seconds) + !----------------------------------------------------------------------- + + associate( & + cf_veg => cnveg_carbonflux_inst , & + cs_veg => cnveg_carbonstate_inst , & + cs_soil => soilbiogeochem_carbonstate_inst & + ) + + ! set time steps + dt = real( get_step_size(), r8 ) + + ! column level carbon fluxes from gross unrepresented landcover change mortality + do j = 1, nlevdecomp + do fc = 1,num_soilc + c = filter_soilc(fc) + + ! column gross unrepresented landcover change fluxes + cs_soil%decomp_cpools_vr_col(c,j,i_met_lit) = & + cs_soil%decomp_cpools_vr_col(c,j,i_met_lit) + cf_veg%gru_c_to_litr_met_c_col(c,j) * dt + cs_soil%decomp_cpools_vr_col(c,j,i_cel_lit) = & + cs_soil%decomp_cpools_vr_col(c,j,i_cel_lit) + cf_veg%gru_c_to_litr_cel_c_col(c,j) * dt + cs_soil%decomp_cpools_vr_col(c,j,i_lig_lit) = & + cs_soil%decomp_cpools_vr_col(c,j,i_lig_lit) + cf_veg%gru_c_to_litr_lig_c_col(c,j) * dt + cs_soil%decomp_cpools_vr_col(c,j,i_cwd) = & + cs_soil%decomp_cpools_vr_col(c,j,i_cwd) + cf_veg%gru_c_to_cwdc_col(c,j) * dt + + ! wood to product pools - states updated in CNProducts + end do + end do + + ! patch loop + do fp = 1,num_soilp + p = filter_soilp(fp) + + ! patch-level carbon fluxes from gross unrepresented landcover change mortality + ! displayed pools + cs_veg%leafc_patch(p) = cs_veg%leafc_patch(p) & + - cf_veg%gru_leafc_to_litter_patch(p) * dt + cs_veg%frootc_patch(p) = cs_veg%frootc_patch(p) & + - cf_veg%gru_frootc_to_litter_patch(p) * dt + cs_veg%livestemc_patch(p) = cs_veg%livestemc_patch(p) & + - cf_veg%gru_livestemc_to_atm_patch(p) * dt + cs_veg%deadstemc_patch(p) = cs_veg%deadstemc_patch(p) & + - cf_veg%gru_deadstemc_to_atm_patch(p) * dt + cs_veg%deadstemc_patch(p) = cs_veg%deadstemc_patch(p) & + - cf_veg%gru_wood_productc_gain_patch(p) * dt + cs_veg%livecrootc_patch(p) = cs_veg%livecrootc_patch(p) & + - cf_veg%gru_livecrootc_to_litter_patch(p) * dt + cs_veg%deadcrootc_patch(p) = cs_veg%deadcrootc_patch(p) & + - cf_veg%gru_deadcrootc_to_litter_patch(p) * dt + + ! xsmrpool + cs_veg%xsmrpool_patch(p) = cs_veg%xsmrpool_patch(p) & + - cf_veg%gru_xsmrpool_to_atm_patch(p) * dt + + ! storage pools + cs_veg%leafc_storage_patch(p) = cs_veg%leafc_storage_patch(p) & + - cf_veg%gru_leafc_storage_to_atm_patch(p) * dt + cs_veg%frootc_storage_patch(p) = cs_veg%frootc_storage_patch(p) & + - cf_veg%gru_frootc_storage_to_atm_patch(p) * dt + cs_veg%livestemc_storage_patch(p) = cs_veg%livestemc_storage_patch(p) & + - cf_veg%gru_livestemc_storage_to_atm_patch(p) * dt + cs_veg%deadstemc_storage_patch(p) = cs_veg%deadstemc_storage_patch(p) & + - cf_veg%gru_deadstemc_storage_to_atm_patch(p) * dt + cs_veg%livecrootc_storage_patch(p) = cs_veg%livecrootc_storage_patch(p) & + - cf_veg%gru_livecrootc_storage_to_atm_patch(p) * dt + cs_veg%deadcrootc_storage_patch(p) = cs_veg%deadcrootc_storage_patch(p) & + - cf_veg%gru_deadcrootc_storage_to_atm_patch(p) * dt + cs_veg%gresp_storage_patch(p) = cs_veg%gresp_storage_patch(p) & + - cf_veg%gru_gresp_storage_to_atm_patch(p) * dt + + ! transfer pools + cs_veg%leafc_xfer_patch(p) = cs_veg%leafc_xfer_patch(p) & + - cf_veg%gru_leafc_xfer_to_atm_patch(p) * dt + cs_veg%frootc_xfer_patch(p) = cs_veg%frootc_xfer_patch(p) & + - cf_veg%gru_frootc_xfer_to_atm_patch(p) * dt + cs_veg%livestemc_xfer_patch(p) = cs_veg%livestemc_xfer_patch(p) & + - cf_veg%gru_livestemc_xfer_to_atm_patch(p) * dt + cs_veg%deadstemc_xfer_patch(p) = cs_veg%deadstemc_xfer_patch(p) & + - cf_veg%gru_deadstemc_xfer_to_atm_patch(p) * dt + cs_veg%livecrootc_xfer_patch(p) = cs_veg%livecrootc_xfer_patch(p) & + - cf_veg%gru_livecrootc_xfer_to_atm_patch(p) * dt + cs_veg%deadcrootc_xfer_patch(p) = cs_veg%deadcrootc_xfer_patch(p) & + - cf_veg%gru_deadcrootc_xfer_to_atm_patch(p) * dt + cs_veg%gresp_xfer_patch(p) = cs_veg%gresp_xfer_patch(p) & + - cf_veg%gru_gresp_xfer_to_atm_patch(p) * dt + + end do ! end of patch loop + + end associate + + end subroutine CStateUpdate2g + end module CNCStateUpdate2Mod diff --git a/src/biogeochem/CNDriverMod.F90 b/src/biogeochem/CNDriverMod.F90 index a8ed44cd97..31804bbf0a 100644 --- a/src/biogeochem/CNDriverMod.F90 +++ b/src/biogeochem/CNDriverMod.F90 @@ -7,7 +7,7 @@ module CNDriverMod ! !USES: use shr_kind_mod , only : r8 => shr_kind_r8 use clm_varctl , only : use_c13, use_c14, use_fates, use_dynroot - use dynSubgridControlMod , only : get_do_harvest + use dynSubgridControlMod , only : get_do_harvest, get_do_grossunrep use decompMod , only : bounds_type use perf_mod , only : t_startf, t_stopf use clm_varctl , only : use_century_decomp, use_nitrif_denitrif, use_nguardrail @@ -111,16 +111,17 @@ subroutine CNDriverNoLeaching(bounds, use CNPhenologyMod , only: CNPhenology use CNGRespMod , only: CNGResp use CNFireMethodMod , only: cnfire_method_type - use CNCIsoFluxMod , only: CIsoFlux1, CIsoFlux2, CIsoFlux2h, CIsoFlux3 + use CNCIsoFluxMod , only: CIsoFlux1, CIsoFlux2, CIsoFlux2h, CIsoFlux2g, CIsoFlux3 use CNC14DecayMod , only: C14Decay use CNCStateUpdate1Mod , only: CStateUpdate1,CStateUpdate0 - use CNCStateUpdate2Mod , only: CStateUpdate2, CStateUpdate2h + use CNCStateUpdate2Mod , only: CStateUpdate2, CStateUpdate2h, CStateUpdate2g use CNCStateUpdate3Mod , only: CStateUpdate3 use CNNStateUpdate1Mod , only: NStateUpdate1 - use CNNStateUpdate2Mod , only: NStateUpdate2, NStateUpdate2h + use CNNStateUpdate2Mod , only: NStateUpdate2, NStateUpdate2h, NStateUpdate2g use CNGapMortalityMod , only: CNGapMortality use CNSharedParamsMod , only: use_fun use dynHarvestMod , only: CNHarvest + use dynGrossUnrepMod , only: CNGrossUnrep use SoilBiogeochemDecompCascadeBGCMod , only: decomp_rate_constants_bgc use SoilBiogeochemDecompCascadeCNMod , only: decomp_rate_constants_cn use SoilBiogeochemCompetitionMod , only: SoilBiogeochemCompetition @@ -690,6 +691,47 @@ subroutine CNDriverNoLeaching(bounds, call NStateUpdate2h(num_soilc, filter_soilc, num_soilp, filter_soilp, & cnveg_nitrogenflux_inst, cnveg_nitrogenstate_inst, soilbiogeochem_nitrogenstate_inst) + + !-------------------------------------------- + ! Update2g (gross unrepresented landcover change) + !-------------------------------------------- + + ! Set gross unrepresented landcover change mortality routine + if (get_do_grossunrep()) then + call CNGrossUnrep(num_soilc, filter_soilc, num_soilp, filter_soilp, & + soilbiogeochem_state_inst, cnveg_carbonstate_inst, cnveg_nitrogenstate_inst, & + cnveg_carbonflux_inst, cnveg_nitrogenflux_inst) + end if + + if ( use_c13 ) then + call CIsoFlux2g(num_soilc, filter_soilc, num_soilp, filter_soilp, & + soilbiogeochem_state_inst, & + cnveg_carbonflux_inst, cnveg_carbonstate_inst, & + c13_cnveg_carbonflux_inst, c13_cnveg_carbonstate_inst, & + isotope='c13') + end if + if ( use_c14 ) then + call CIsoFlux2g(num_soilc, filter_soilc, num_soilp, filter_soilp, & + soilbiogeochem_state_inst, & + cnveg_carbonflux_inst, cnveg_carbonstate_inst, & + c14_cnveg_carbonflux_inst, c14_cnveg_carbonstate_inst, & + isotope='c14') + end if + + call CStateUpdate2g( num_soilc, filter_soilc, num_soilp, filter_soilp, & + cnveg_carbonflux_inst, cnveg_carbonstate_inst, soilbiogeochem_carbonstate_inst) + if ( use_c13 ) then + call CStateUpdate2g(num_soilc, filter_soilc, num_soilp, filter_soilp, & + c13_cnveg_carbonflux_inst, c13_cnveg_carbonstate_inst, c13_soilbiogeochem_carbonstate_inst) + end if + if ( use_c14 ) then + call CStateUpdate2g(num_soilc, filter_soilc, num_soilp, filter_soilp, & + c14_cnveg_carbonflux_inst, c14_cnveg_carbonstate_inst, c14_soilbiogeochem_carbonstate_inst) + end if + + call NStateUpdate2g(num_soilc, filter_soilc, num_soilp, filter_soilp, & + cnveg_nitrogenflux_inst, cnveg_nitrogenstate_inst, soilbiogeochem_nitrogenstate_inst) + call t_stopf('CNUpdate2') if ( use_nguardrail ) then @@ -708,6 +750,7 @@ subroutine CNDriverNoLeaching(bounds, call c_products_inst%UpdateProducts(bounds, & num_soilp, filter_soilp, & dwt_wood_product_gain_patch = cnveg_carbonflux_inst%dwt_wood_productc_gain_patch(begp:endp), & + gru_wood_product_gain_patch = cnveg_carbonflux_inst%gru_wood_productc_gain_patch(begp:endp), & wood_harvest_patch = cnveg_carbonflux_inst%wood_harvestc_patch(begp:endp), & dwt_crop_product_gain_patch = cnveg_carbonflux_inst%dwt_crop_productc_gain_patch(begp:endp), & grain_to_cropprod_patch = cnveg_carbonflux_inst%grainc_to_cropprodc_patch(begp:endp)) @@ -717,6 +760,7 @@ subroutine CNDriverNoLeaching(bounds, call c13_products_inst%UpdateProducts(bounds, & num_soilp, filter_soilp, & dwt_wood_product_gain_patch = c13_cnveg_carbonflux_inst%dwt_wood_productc_gain_patch(begp:endp), & + gru_wood_product_gain_patch = c13_cnveg_carbonflux_inst%gru_wood_productc_gain_patch(begp:endp), & wood_harvest_patch = c13_cnveg_carbonflux_inst%wood_harvestc_patch(begp:endp), & dwt_crop_product_gain_patch = c13_cnveg_carbonflux_inst%dwt_crop_productc_gain_patch(begp:endp), & grain_to_cropprod_patch = c13_cnveg_carbonflux_inst%grainc_to_cropprodc_patch(begp:endp)) @@ -726,6 +770,7 @@ subroutine CNDriverNoLeaching(bounds, call c14_products_inst%UpdateProducts(bounds, & num_soilp, filter_soilp, & dwt_wood_product_gain_patch = c14_cnveg_carbonflux_inst%dwt_wood_productc_gain_patch(begp:endp), & + gru_wood_product_gain_patch = c14_cnveg_carbonflux_inst%gru_wood_productc_gain_patch(begp:endp), & wood_harvest_patch = c14_cnveg_carbonflux_inst%wood_harvestc_patch(begp:endp), & dwt_crop_product_gain_patch = c14_cnveg_carbonflux_inst%dwt_crop_productc_gain_patch(begp:endp), & grain_to_cropprod_patch = c14_cnveg_carbonflux_inst%grainc_to_cropprodc_patch(begp:endp)) @@ -734,6 +779,7 @@ subroutine CNDriverNoLeaching(bounds, call n_products_inst%UpdateProducts(bounds, & num_soilp, filter_soilp, & dwt_wood_product_gain_patch = cnveg_nitrogenflux_inst%dwt_wood_productn_gain_patch(begp:endp), & + gru_wood_product_gain_patch = cnveg_nitrogenflux_inst%gru_wood_productn_gain_patch(begp:endp), & wood_harvest_patch = cnveg_nitrogenflux_inst%wood_harvestn_patch(begp:endp), & dwt_crop_product_gain_patch = cnveg_nitrogenflux_inst%dwt_crop_productn_gain_patch(begp:endp), & grain_to_cropprod_patch = cnveg_nitrogenflux_inst%grainn_to_cropprodn_patch(begp:endp)) diff --git a/src/biogeochem/CNNStateUpdate2Mod.F90 b/src/biogeochem/CNNStateUpdate2Mod.F90 index 24070f6890..e3548694c6 100644 --- a/src/biogeochem/CNNStateUpdate2Mod.F90 +++ b/src/biogeochem/CNNStateUpdate2Mod.F90 @@ -20,6 +20,7 @@ module CNNStateUpdate2Mod ! !PUBLIC MEMBER FUNCTIONS: public:: NStateUpdate2 public:: NStateUpdate2h + public:: NStateUpdate2g !----------------------------------------------------------------------- contains @@ -235,4 +236,111 @@ subroutine NStateUpdate2h(num_soilc, filter_soilc, num_soilp, filter_soilp, & end subroutine NStateUpdate2h + !----------------------------------------------------------------------- + subroutine NStateUpdate2g(num_soilc, filter_soilc, num_soilp, filter_soilp, & + cnveg_nitrogenflux_inst, cnveg_nitrogenstate_inst, soilbiogeochem_nitrogenstate_inst) + ! + ! !DESCRIPTION: + ! Update all the prognostic nitrogen state + ! variables affected by gross unrepresented landcover change mortality fluxes + ! NOTE - associate statements have been removed where there are + ! no science equations. This increases readability and maintainability + ! + ! !ARGUMENTS: + integer , intent(in) :: num_soilc ! number of soil columns in filter + integer , intent(in) :: filter_soilc(:) ! filter for soil columns + integer , intent(in) :: num_soilp ! number of soil patches in filter + integer , intent(in) :: filter_soilp(:) ! filter for soil patches + type(cnveg_nitrogenflux_type) , intent(in) :: cnveg_nitrogenflux_inst + type(cnveg_nitrogenstate_type) , intent(inout) :: cnveg_nitrogenstate_inst + type(soilbiogeochem_nitrogenstate_type) , intent(inout) :: soilbiogeochem_nitrogenstate_inst + ! + ! !LOCAL VARIABLES: + integer :: c,p,j,l ! indices + integer :: fp,fc ! lake filter indices + real(r8):: dt ! radiation time step (seconds) + !----------------------------------------------------------------------- + + associate( & + nf_veg => cnveg_nitrogenflux_inst , & + ns_veg => cnveg_nitrogenstate_inst , & + ns_soil => soilbiogeochem_nitrogenstate_inst & + ) + + ! set time steps + dt = real( get_step_size(), r8 ) + + ! column-level nitrogen fluxes from gross unrepresented landcover change mortality + + do j = 1,nlevdecomp + do fc = 1,num_soilc + c = filter_soilc(fc) + ns_soil%decomp_npools_vr_col(c,j,i_met_lit) = & + ns_soil%decomp_npools_vr_col(c,j,i_met_lit) + nf_veg%gru_n_to_litr_met_n_col(c,j) * dt + ns_soil%decomp_npools_vr_col(c,j,i_cel_lit) = & + ns_soil%decomp_npools_vr_col(c,j,i_cel_lit) + nf_veg%gru_n_to_litr_cel_n_col(c,j) * dt + ns_soil%decomp_npools_vr_col(c,j,i_lig_lit) = & + ns_soil%decomp_npools_vr_col(c,j,i_lig_lit) + nf_veg%gru_n_to_litr_lig_n_col(c,j) * dt + ns_soil%decomp_npools_vr_col(c,j,i_cwd) = & + ns_soil%decomp_npools_vr_col(c,j,i_cwd) + nf_veg%gru_n_to_cwdn_col(c,j) * dt + end do + end do + + ! patch-level nitrogen fluxes from gross unrepresented landcover change mortality + + do fp = 1,num_soilp + p = filter_soilp(fp) + + ! displayed pools + ns_veg%leafn_patch(p) = ns_veg%leafn_patch(p) & + - nf_veg%gru_leafn_to_litter_patch(p) * dt + ns_veg%frootn_patch(p) = ns_veg%frootn_patch(p) & + - nf_veg%gru_frootn_to_litter_patch(p) * dt + ns_veg%livestemn_patch(p) = ns_veg%livestemn_patch(p) & + - nf_veg%gru_livestemn_to_atm_patch(p) * dt + ns_veg%deadstemn_patch(p) = ns_veg%deadstemn_patch(p) & + - nf_veg%gru_deadstemn_to_atm_patch(p) * dt + ns_veg%deadstemn_patch(p) = ns_veg%deadstemn_patch(p) & + - nf_veg%gru_wood_productn_gain_patch(p) * dt + ns_veg%livecrootn_patch(p) = ns_veg%livecrootn_patch(p) & + - nf_veg%gru_livecrootn_to_litter_patch(p) * dt + ns_veg%deadcrootn_patch(p) = ns_veg%deadcrootn_patch(p) & + - nf_veg%gru_deadcrootn_to_litter_patch(p) * dt + ns_veg%retransn_patch(p) = ns_veg%retransn_patch(p) & + - nf_veg%gru_retransn_to_litter_patch(p) * dt + + ! storage pools + ns_veg%leafn_storage_patch(p) = ns_veg%leafn_storage_patch(p) & + - nf_veg%gru_leafn_storage_to_atm_patch(p) * dt + ns_veg%frootn_storage_patch(p) = ns_veg%frootn_storage_patch(p) & + - nf_veg%gru_frootn_storage_to_atm_patch(p) * dt + ns_veg%livestemn_storage_patch(p) = ns_veg%livestemn_storage_patch(p) & + - nf_veg%gru_livestemn_storage_to_atm_patch(p) * dt + ns_veg%deadstemn_storage_patch(p) = ns_veg%deadstemn_storage_patch(p) & + - nf_veg%gru_deadstemn_storage_to_atm_patch(p) * dt + ns_veg%livecrootn_storage_patch(p) = ns_veg%livecrootn_storage_patch(p) & + - nf_veg%gru_livecrootn_storage_to_atm_patch(p) * dt + ns_veg%deadcrootn_storage_patch(p) = ns_veg%deadcrootn_storage_patch(p) & + - nf_veg%gru_deadcrootn_storage_to_atm_patch(p) * dt + + ! transfer pools + ns_veg%leafn_xfer_patch(p) = ns_veg%leafn_xfer_patch(p) & + - nf_veg%gru_leafn_xfer_to_atm_patch(p) *dt + ns_veg%frootn_xfer_patch(p) = ns_veg%frootn_xfer_patch(p) & + - nf_veg%gru_frootn_xfer_to_atm_patch(p) *dt + ns_veg%livestemn_xfer_patch(p) = ns_veg%livestemn_xfer_patch(p) & + - nf_veg%gru_livestemn_xfer_to_atm_patch(p) *dt + ns_veg%deadstemn_xfer_patch(p) = ns_veg%deadstemn_xfer_patch(p) & + - nf_veg%gru_deadstemn_xfer_to_atm_patch(p) *dt + ns_veg%livecrootn_xfer_patch(p) = ns_veg%livecrootn_xfer_patch(p) & + - nf_veg%gru_livecrootn_xfer_to_atm_patch(p) *dt + ns_veg%deadcrootn_xfer_patch(p) = ns_veg%deadcrootn_xfer_patch(p) & + - nf_veg%gru_deadcrootn_xfer_to_atm_patch(p) *dt + + end do + + end associate + + end subroutine NStateUpdate2g + end module CNNStateUpdate2Mod diff --git a/src/biogeochem/CNProductsMod.F90 b/src/biogeochem/CNProductsMod.F90 index 59891ba330..046a01d482 100644 --- a/src/biogeochem/CNProductsMod.F90 +++ b/src/biogeochem/CNProductsMod.F90 @@ -43,6 +43,11 @@ module CNProductsMod real(r8), pointer :: dwt_prod100_gain_grc(:) ! (g[C or N]/m2/s) dynamic landcover addition to 100-year wood product pool real(r8), pointer :: dwt_woodprod_gain_grc(:) ! (g[C or N]/m2/s) dynamic landcover addition to wood product pools real(r8), pointer :: dwt_cropprod1_gain_grc(:) ! (g[C or N]/m2/s) dynamic landcover addition to 1-year crop product pool + real(r8), pointer :: gru_prod10_gain_patch(:) ! (g[C or N]/m2/s) gross unrepresented landcover addition to 10-year wood product pool + real(r8), pointer :: gru_prod10_gain_grc(:) ! (g[C or N]/m2/s) gross unrepresented landcover addition to 10-year wood product pool + real(r8), pointer :: gru_prod100_gain_patch(:) ! (g[C or N]/m2/s) gross unrepresented landcover addition to 100-year wood product pool + real(r8), pointer :: gru_prod100_gain_grc(:) ! (g[C or N]/m2/s) gross unrepresented landcover addition to 100-year wood product pool + real(r8), pointer :: gru_woodprod_gain_grc(:) ! (g[C or N]/m2/s) gross unrepresented landcover addition to wood product pools real(r8), pointer :: hrv_deadstem_to_prod10_patch(:) ! (g[C or N]/m2/s) dead stem harvest to 10-year wood product pool real(r8), pointer :: hrv_deadstem_to_prod10_grc(:) ! (g[C or N]/m2/s) dead stem harvest to 10-year wood product pool real(r8), pointer :: hrv_deadstem_to_prod100_patch(:) ! (g[C or N]/m2/s) dead stem harvest to 100-year wood product pool @@ -133,9 +138,14 @@ subroutine InitAllocate(this, bounds) allocate(this%dwt_cropprod1_gain_grc(begg:endg)) ; this%dwt_cropprod1_gain_grc(:) = nan + allocate(this%gru_prod10_gain_patch(begp:endp)) ; this%gru_prod10_gain_patch(:) = nan + allocate(this%gru_prod10_gain_grc(begg:endg)) ; this%gru_prod10_gain_grc(:) = nan + allocate(this%gru_prod100_gain_patch(begp:endp)) ; this%gru_prod100_gain_patch(:) = nan + allocate(this%gru_prod100_gain_grc(begg:endg)) ; this%gru_prod100_gain_grc(:) = nan + allocate(this%gru_woodprod_gain_grc(begg:endg)) ; this%gru_woodprod_gain_grc(:) = nan + allocate(this%hrv_deadstem_to_prod10_patch(begp:endp)) ; this%hrv_deadstem_to_prod10_patch(:) = nan allocate(this%hrv_deadstem_to_prod10_grc(begg:endg)) ; this%hrv_deadstem_to_prod10_grc(:) = nan - allocate(this%hrv_deadstem_to_prod100_patch(begp:endp)) ; this%hrv_deadstem_to_prod100_patch(:) = nan allocate(this%hrv_deadstem_to_prod100_grc(begg:endg)) ; this%hrv_deadstem_to_prod100_grc(:) = nan @@ -233,6 +243,22 @@ subroutine InitHistory(this, bounds) long_name = 'landcover change-driven addition to 1-year crop product pool', & ptr_gcell = this%dwt_cropprod1_gain_grc) + this%gru_prod10_gain_grc(begg:endg) = spval + call hist_addfld1d( & + fname = this%species%hist_fname('GRU_PROD10', suffix='_GAIN'), & + units = 'g' // this%species%get_species() // '/m^2/s', & + avgflag = 'A', & + long_name = 'gross unrepresented landcover change addition to 10-yr wood product pool', & + ptr_gcell = this%gru_prod10_gain_grc, default='inactive') + + this%gru_prod100_gain_grc(begg:endg) = spval + call hist_addfld1d( & + fname = this%species%hist_fname('GRU_PROD100', suffix='_GAIN'), & + units = 'g' // this%species%get_species() // '/m^2/s', & + avgflag = 'A', & + long_name = 'gross unrepresented landcover change addition to 100-yr wood product pool', & + ptr_gcell = this%gru_prod100_gain_grc, default='inactive') + this%cropprod1_loss_grc(begg:endg) = spval call hist_addfld1d( & fname = this%species%hist_fname('CROPPROD1', suffix='_LOSS'), & @@ -291,6 +317,8 @@ subroutine InitCold(this, bounds) do p = bounds%begp, bounds%endp this%hrv_deadstem_to_prod10_patch(p) = 0._r8 this%hrv_deadstem_to_prod100_patch(p) = 0._r8 + this%gru_prod10_gain_patch(p) = 0._r8 + this%gru_prod100_gain_patch(p) = 0._r8 this%grain_to_cropprod1_patch(p) = 0._r8 end do @@ -428,6 +456,7 @@ end subroutine Restart subroutine UpdateProducts(this, bounds, & num_soilp, filter_soilp, & dwt_wood_product_gain_patch, & + gru_wood_product_gain_patch, & wood_harvest_patch, & dwt_crop_product_gain_patch, & grain_to_cropprod_patch) @@ -446,6 +475,9 @@ subroutine UpdateProducts(this, bounds, & ! a patch-level flux, it is expressed per unit GRIDCELL area real(r8), intent(in) :: dwt_wood_product_gain_patch( bounds%begp: ) + ! gross unrepresented landcover addition to wood product pools (g/m2/s) [patch] + real(r8), intent(in) :: gru_wood_product_gain_patch( bounds%begp: ) + ! wood harvest addition to wood product pools (g/m2/s) [patch] real(r8), intent(in) :: wood_harvest_patch( bounds%begp: ) @@ -465,6 +497,7 @@ subroutine UpdateProducts(this, bounds, & !----------------------------------------------------------------------- SHR_ASSERT_ALL((ubound(dwt_wood_product_gain_patch) == (/bounds%endp/)), errMsg(sourcefile, __LINE__)) + SHR_ASSERT_ALL((ubound(gru_wood_product_gain_patch) == (/bounds%endp/)), errMsg(sourcefile, __LINE__)) SHR_ASSERT_ALL((ubound(wood_harvest_patch) == (/bounds%endp/)), errMsg(sourcefile, __LINE__)) SHR_ASSERT_ALL((ubound(dwt_crop_product_gain_patch) == (/bounds%endp/)), errMsg(sourcefile, __LINE__)) SHR_ASSERT_ALL((ubound(grain_to_cropprod_patch) == (/bounds%endp/)), errMsg(sourcefile, __LINE__)) @@ -472,6 +505,7 @@ subroutine UpdateProducts(this, bounds, & call this%PartitionWoodFluxes(bounds, & num_soilp, filter_soilp, & dwt_wood_product_gain_patch(bounds%begp:bounds%endp), & + gru_wood_product_gain_patch(bounds%begp:bounds%endp), & wood_harvest_patch(bounds%begp:bounds%endp)) call this%PartitionGrainFluxes(bounds, & @@ -504,6 +538,10 @@ subroutine UpdateProducts(this, bounds, & this%prod10_grc(g) = this%prod10_grc(g) + this%dwt_prod10_gain_grc(g)*dt this%prod100_grc(g) = this%prod100_grc(g) + this%dwt_prod100_gain_grc(g)*dt + ! fluxes into wood & grain product pools, from gross unrepresented landcover change + this%prod10_grc(g) = this%prod10_grc(g) + this%gru_prod10_gain_grc(g)*dt + this%prod100_grc(g) = this%prod100_grc(g) + this%gru_prod100_gain_grc(g)*dt + ! fluxes into wood & grain product pools, from harvest this%cropprod1_grc(g) = this%cropprod1_grc(g) + this%grain_to_cropprod1_grc(g)*dt this%prod10_grc(g) = this%prod10_grc(g) + this%hrv_deadstem_to_prod10_grc(g)*dt @@ -524,6 +562,7 @@ end subroutine UpdateProducts subroutine PartitionWoodFluxes(this, bounds, & num_soilp, filter_soilp, & dwt_wood_product_gain_patch, & + gru_wood_product_gain_patch, & wood_harvest_patch) ! ! !DESCRIPTION: @@ -543,6 +582,9 @@ subroutine PartitionWoodFluxes(this, bounds, & ! a patch-level flux, it is expressed per unit GRIDCELL area real(r8), intent(in) :: dwt_wood_product_gain_patch( bounds%begp: ) + ! gross unrepresented landcover addition to wood product pools (g/m2/s) [patch] + real(r8), intent(in) :: gru_wood_product_gain_patch( bounds%begp: ) + ! wood harvest addition to wood product pools (g/m2/s) [patch] real(r8), intent(in) :: wood_harvest_patch( bounds%begp: ) @@ -560,6 +602,44 @@ subroutine PartitionWoodFluxes(this, bounds, & character(len=*), parameter :: subname = 'PartitionWoodFluxes' !----------------------------------------------------------------------- + ! Partition patch-level gross unrepresented fluxes to 10 and 100-year product pools + do fp = 1, num_soilp + p = filter_soilp(fp) + + pprod10 = pftcon%pprod10(patch%itype(p)) + pprod100 = pftcon%pprod100(patch%itype(p)) + pprod_tot = pprod10 + pprod100 + if (pprod_tot > 0) then + pprod10_frac = pprod10 / pprod_tot + pprod100_frac = pprod100 / pprod_tot + else + ! Avoid divide by 0 + pprod10_frac = 0._r8 + pprod100_frac = 0._r8 + end if + + this%gru_prod10_gain_patch(p) = & + gru_wood_product_gain_patch(p) * pprod10_frac + this%gru_prod100_gain_patch(p) = & + gru_wood_product_gain_patch(p) * pprod100_frac + + end do + + ! Average gross unrepresented fluxes from patch to gridcell + call p2g(bounds, & + this%gru_prod10_gain_patch(bounds%begp:bounds%endp), & + this%gru_prod10_gain_grc(bounds%begg:bounds%endg), & + p2c_scale_type = 'unity', & + c2l_scale_type = 'unity', & + l2g_scale_type = 'unity') + + call p2g(bounds, & + this%gru_prod100_gain_patch(bounds%begp:bounds%endp), & + this%gru_prod100_gain_grc(bounds%begg:bounds%endg), & + p2c_scale_type = 'unity', & + c2l_scale_type = 'unity', & + l2g_scale_type = 'unity') + ! Partition patch-level harvest fluxes to 10 and 100-year product pools do fp = 1, num_soilp p = filter_soilp(fp) @@ -733,6 +813,10 @@ subroutine ComputeSummaryVars(this, bounds) this%dwt_woodprod_gain_grc(g) = & this%dwt_prod100_gain_grc(g) + & this%dwt_prod10_gain_grc(g) + + this%gru_woodprod_gain_grc(g) = & + this%gru_prod100_gain_grc(g) + & + this%gru_prod10_gain_grc(g) end do end subroutine ComputeSummaryVars diff --git a/src/biogeochem/CNVegCarbonFluxType.F90 b/src/biogeochem/CNVegCarbonFluxType.F90 index 57cee383d5..22f57ed9da 100644 --- a/src/biogeochem/CNVegCarbonFluxType.F90 +++ b/src/biogeochem/CNVegCarbonFluxType.F90 @@ -263,13 +263,49 @@ module CNVegCarbonFluxType real(r8), pointer :: dwt_conv_cflux_dribbled_grc (:) ! (gC/m2/s) dwt_conv_cflux_grc dribbled evenly throughout the year real(r8), pointer :: dwt_wood_productc_gain_patch (:) ! (gC/m2/s) addition to wood product pools from landcover change; although this is a patch-level flux, it is expressed per unit GRIDCELL area real(r8), pointer :: dwt_crop_productc_gain_patch (:) ! (gC/m2/s) addition to crop product pools from landcover change; although this is a patch-level flux, it is expressed per unit GRIDCELL area - real(r8), pointer :: dwt_slash_cflux_col (:) ! (gC/m2/s) conversion slash flux due to landcover change + real(r8), pointer :: dwt_slash_cflux_patch (:) ! (gC/m2/s) conversion slash flux due to landcover change + real(r8), pointer :: dwt_slash_cflux_grc (:) ! (gC/m2/s) dwt_slash_cflux_patch summed to the gridcell-level real(r8), pointer :: dwt_frootc_to_litr_met_c_col (:,:) ! (gC/m3/s) fine root to litter due to landcover change real(r8), pointer :: dwt_frootc_to_litr_cel_c_col (:,:) ! (gC/m3/s) fine root to litter due to landcover change real(r8), pointer :: dwt_frootc_to_litr_lig_c_col (:,:) ! (gC/m3/s) fine root to litter due to landcover change real(r8), pointer :: dwt_livecrootc_to_cwdc_col (:,:) ! (gC/m3/s) live coarse root to CWD due to landcover change real(r8), pointer :: dwt_deadcrootc_to_cwdc_col (:,:) ! (gC/m3/s) dead coarse root to CWD due to landcover change + ! gross unrepresented landcover fluxes + real(r8), pointer :: gru_leafc_to_litter_patch (:) ! leaf C gross unrepresented landcover change mortality (gC/m2/s) + real(r8), pointer :: gru_leafc_storage_to_atm_patch (:) ! leaf C storage gross unrepresented landcover change mortality (gC/m2/s) + real(r8), pointer :: gru_leafc_xfer_to_atm_patch (:) ! leaf C transfer gross unrepresented landcover change mortality (gC/m2/s) + real(r8), pointer :: gru_frootc_to_litter_patch (:) ! fine root C gross unrepresented landcover change mortality (gC/m2/s) + real(r8), pointer :: gru_frootc_storage_to_atm_patch (:) ! fine root C storage gross unrepresented landcover change mortality (gC/m2/s) + real(r8), pointer :: gru_frootc_xfer_to_atm_patch (:) ! fine root C transfer gross unrepresented landcover change mortality (gC/m2/s) + real(r8), pointer :: gru_livestemc_to_atm_patch (:) ! live stem C gross unrepresented landcover change mortality (gC/m2/s) + real(r8), pointer :: gru_livestemc_storage_to_atm_patch (:) ! live stem C storage gross unrepresented landcover change mortality (gC/m2/s) + real(r8), pointer :: gru_livestemc_xfer_to_atm_patch (:) ! live stem C transfer gross unrepresented landcover change mortality (gC/m2/s) + real(r8), pointer :: gru_deadstemc_to_atm_patch (:) ! dead stem C gross unrepresented landcover change mortality to the atmosphere (gC/m2/s) + real(r8), pointer :: gru_deadstemc_storage_to_atm_patch (:) ! dead stem C storage gross unrepresented landcover change mortality (gC/m2/s) + real(r8), pointer :: gru_deadstemc_xfer_to_atm_patch (:) ! dead stem C transfer gross unrepresented landcover change mortality (gC/m2/s) + real(r8), pointer :: gru_livecrootc_to_litter_patch (:) ! live coarse root C gross unrepresented landcover change mortality (gC/m2/s) + real(r8), pointer :: gru_livecrootc_storage_to_atm_patch (:) ! live coarse root C storage gross unrepresented landcover change mortality (gC/m2/s) + real(r8), pointer :: gru_livecrootc_xfer_to_atm_patch (:) ! live coarse root C transfer gross unrepresented landcover change mortality (gC/m2/s) + real(r8), pointer :: gru_deadcrootc_to_litter_patch (:) ! dead coarse root C gross unrepresented landcover change mortality (gC/m2/s) + real(r8), pointer :: gru_deadcrootc_storage_to_atm_patch (:) ! dead coarse root C storage gross unrepresented landcover change mortality (gC/m2/s) + real(r8), pointer :: gru_deadcrootc_xfer_to_atm_patch (:) ! dead coarse root C transfer gross unrepresented landcover change mortality (gC/m2/s) + real(r8), pointer :: gru_gresp_storage_to_atm_patch (:) ! growth respiration storage gross unrepresented landcover change mortality (gC/m2/s) + real(r8), pointer :: gru_gresp_xfer_to_atm_patch (:) ! growth respiration transfer gross unrepresented landcover change mortality (gC/m2/s) + real(r8), pointer :: gru_xsmrpool_to_atm_patch (:) ! excess MR pool gross unrepresented landcover change mortality (gC/m2/s) + + real(r8), pointer :: gru_conv_cflux_patch (:) ! (gC/m2/s) conversion C flux (immediate loss to atm) + real(r8), pointer :: gru_conv_cflux_col (:) ! (gC/m2/s) gru_conv_cflux_patch summed to the column-level + real(r8), pointer :: gru_conv_cflux_grc (:) ! (gC/m2/s) gru_conv_cflux_patch summed to the gridcell-level + real(r8), pointer :: gru_conv_cflux_dribbled_grc (:) ! (gC/m2/s) gru_conv_cflux_grc dribbled evenly throughout the year + real(r8), pointer :: gru_wood_productc_gain_patch (:) ! (gC/m2/s) addition to wood product pools from gross unrepresented landcover change + real(r8), pointer :: gru_wood_productc_gain_col (:) ! (gC/m2/s) gru_wood_productc_gain_patch summed to the column-level + real(r8), pointer :: gru_slash_cflux_patch (:) ! (gC/m2/s) conversion slash flux due to gross unrepresented landcover change + real(r8), pointer :: gru_c_to_litr_met_c_col (:,:) ! (gC/m3/s) C to litter due to gross unrepresented landcover change + real(r8), pointer :: gru_c_to_litr_cel_c_col (:,:) ! (gC/m3/s) C to litter due to gross unrepresented landcover change + real(r8), pointer :: gru_c_to_litr_lig_c_col (:,:) ! (gC/m3/s) C to litter due to gross unrepresented landcover change + real(r8), pointer :: gru_c_to_cwdc_col (:,:) ! (gC/m3/s) C to CWD due to gross unrepresented landcover change + ! crop fluxes real(r8), pointer :: crop_seedc_to_leaf_patch (:) ! (gC/m2/s) seed source to leaf, for crops @@ -340,7 +376,7 @@ module CNVegCarbonFluxType real(r8), pointer :: nee_grc (:) ! (gC/m2/s) net ecosystem exchange of carbon, includes fire and hrv_xsmrpool, excludes landuse and harvest flux, positive for source ! Dynamic landcover fluxnes - real(r8), pointer :: landuseflux_grc(:) ! (gC/m2/s) dwt_conv_cflux+product_closs + real(r8), pointer :: landuseflux_grc(:) ! (gC/m2/s) dwt_conv_cflux+gru_conv_cflux+product_closs real(r8), pointer :: npp_Nactive_patch (:) ! C used by mycorrhizal uptake (gC/m2/s) real(r8), pointer :: npp_burnedoff_patch (:) ! C that cannot be used for N uptake (gC/m2/s) real(r8), pointer :: npp_Nnonmyc_patch (:) ! C used by non-myc uptake (gC/m2/s) @@ -366,6 +402,7 @@ module CNVegCarbonFluxType ! Objects that help convert once-per-year dynamic land cover changes into fluxes ! that are dribbled throughout the year type(annual_flux_dribbler_type) :: dwt_conv_cflux_dribbler + type(annual_flux_dribbler_type) :: gru_conv_cflux_dribbler type(annual_flux_dribbler_type) :: hrv_xsmrpool_to_atm_dribbler contains @@ -378,6 +415,7 @@ module CNVegCarbonFluxType procedure , private :: RestartAllIsotopes ! Handle restart fields present for both bulk C and isotopes procedure , public :: SetValues procedure , public :: ZeroDWT + procedure , public :: ZeroGRU procedure , public :: Summary => Summary_carbonflux end type cnveg_carbonflux_type @@ -629,7 +667,8 @@ subroutine InitAllocate(this, bounds, carbon_type) allocate(this%harvest_c_to_litr_lig_c_col (begc:endc,1:nlevdecomp_full)); this%harvest_c_to_litr_lig_c_col (:,:)=nan allocate(this%harvest_c_to_cwdc_col (begc:endc,1:nlevdecomp_full)); this%harvest_c_to_cwdc_col (:,:)=nan - allocate(this%dwt_slash_cflux_col (begc:endc)) ; this%dwt_slash_cflux_col (:) =nan + allocate(this%dwt_slash_cflux_patch (begp:endp)) ; this%dwt_slash_cflux_patch (:) =nan + allocate(this%dwt_slash_cflux_grc (begg:endg)) ; this%dwt_slash_cflux_grc (:) =nan allocate(this%dwt_frootc_to_litr_met_c_col (begc:endc,1:nlevdecomp_full)); this%dwt_frootc_to_litr_met_c_col (:,:)=nan allocate(this%dwt_frootc_to_litr_cel_c_col (begc:endc,1:nlevdecomp_full)); this%dwt_frootc_to_litr_cel_c_col (:,:)=nan allocate(this%dwt_frootc_to_litr_lig_c_col (begc:endc,1:nlevdecomp_full)); this%dwt_frootc_to_litr_lig_c_col (:,:)=nan @@ -646,6 +685,40 @@ subroutine InitAllocate(this, bounds, carbon_type) allocate(this%dwt_wood_productc_gain_patch (begp:endp)) ; this%dwt_wood_productc_gain_patch(:) =nan allocate(this%dwt_crop_productc_gain_patch (begp:endp)) ; this%dwt_crop_productc_gain_patch(:) =nan + allocate(this%gru_leafc_to_litter_patch (begp:endp)) ; this%gru_leafc_to_litter_patch (:) = nan + allocate(this%gru_leafc_storage_to_atm_patch (begp:endp)) ; this%gru_leafc_storage_to_atm_patch (:) = nan + allocate(this%gru_leafc_xfer_to_atm_patch (begp:endp)) ; this%gru_leafc_xfer_to_atm_patch (:) = nan + allocate(this%gru_frootc_to_litter_patch (begp:endp)) ; this%gru_frootc_to_litter_patch (:) = nan + allocate(this%gru_frootc_storage_to_atm_patch (begp:endp)) ; this%gru_frootc_storage_to_atm_patch (:) = nan + allocate(this%gru_frootc_xfer_to_atm_patch (begp:endp)) ; this%gru_frootc_xfer_to_atm_patch (:) = nan + allocate(this%gru_livestemc_to_atm_patch (begp:endp)) ; this%gru_livestemc_to_atm_patch (:) = nan + allocate(this%gru_livestemc_storage_to_atm_patch (begp:endp)) ; this%gru_livestemc_storage_to_atm_patch (:) = nan + allocate(this%gru_livestemc_xfer_to_atm_patch (begp:endp)) ; this%gru_livestemc_xfer_to_atm_patch (:) = nan + allocate(this%gru_deadstemc_to_atm_patch (begp:endp)) ; this%gru_deadstemc_to_atm_patch (:) = nan + allocate(this%gru_deadstemc_storage_to_atm_patch (begp:endp)) ; this%gru_deadstemc_storage_to_atm_patch (:) = nan + allocate(this%gru_deadstemc_xfer_to_atm_patch (begp:endp)) ; this%gru_deadstemc_xfer_to_atm_patch (:) = nan + allocate(this%gru_livecrootc_to_litter_patch (begp:endp)) ; this%gru_livecrootc_to_litter_patch (:) = nan + allocate(this%gru_livecrootc_storage_to_atm_patch (begp:endp)) ; this%gru_livecrootc_storage_to_atm_patch (:) = nan + allocate(this%gru_livecrootc_xfer_to_atm_patch (begp:endp)) ; this%gru_livecrootc_xfer_to_atm_patch (:) = nan + allocate(this%gru_deadcrootc_to_litter_patch (begp:endp)) ; this%gru_deadcrootc_to_litter_patch (:) = nan + allocate(this%gru_deadcrootc_storage_to_atm_patch (begp:endp)) ; this%gru_deadcrootc_storage_to_atm_patch (:) = nan + allocate(this%gru_deadcrootc_xfer_to_atm_patch (begp:endp)) ; this%gru_deadcrootc_xfer_to_atm_patch (:) = nan + allocate(this%gru_gresp_storage_to_atm_patch (begp:endp)) ; this%gru_gresp_storage_to_atm_patch (:) = nan + allocate(this%gru_gresp_xfer_to_atm_patch (begp:endp)) ; this%gru_gresp_xfer_to_atm_patch (:) = nan + allocate(this%gru_xsmrpool_to_atm_patch (begp:endp)) ; this%gru_xsmrpool_to_atm_patch (:) = nan + + allocate(this%gru_conv_cflux_patch (begp:endp)) ; this%gru_conv_cflux_patch (:) =nan + allocate(this%gru_conv_cflux_col (begc:endc)) ; this%gru_conv_cflux_col (:) =nan + allocate(this%gru_conv_cflux_grc (begg:endg)) ; this%gru_conv_cflux_grc (:) =nan + allocate(this%gru_conv_cflux_dribbled_grc (begg:endg)) ; this%gru_conv_cflux_dribbled_grc (:) =nan + allocate(this%gru_wood_productc_gain_patch (begp:endp)) ; this%gru_wood_productc_gain_patch (:) =nan + allocate(this%gru_wood_productc_gain_col (begc:endc)) ; this%gru_wood_productc_gain_col (:) =nan + allocate(this%gru_slash_cflux_patch (begp:endp)) ; this%gru_slash_cflux_patch (:) =nan + allocate(this%gru_c_to_litr_met_c_col (begc:endc,1:nlevdecomp_full)); this%gru_c_to_litr_met_c_col (:,:)=nan + allocate(this%gru_c_to_litr_cel_c_col (begc:endc,1:nlevdecomp_full)); this%gru_c_to_litr_cel_c_col (:,:)=nan + allocate(this%gru_c_to_litr_lig_c_col (begc:endc,1:nlevdecomp_full)); this%gru_c_to_litr_lig_c_col (:,:)=nan + allocate(this%gru_c_to_cwdc_col (begc:endc,1:nlevdecomp_full)); this%gru_c_to_cwdc_col (:,:)=nan + allocate(this%crop_seedc_to_leaf_patch (begp:endp)) ; this%crop_seedc_to_leaf_patch (:) =nan allocate(this%cwdc_hr_col (begc:endc)) ; this%cwdc_hr_col (:) =nan @@ -763,6 +836,11 @@ subroutine InitAllocate(this, bounds, carbon_type) name = 'dwt_conv_flux_' // carbon_type_suffix, & units = 'gC/m^2', & allows_non_annual_delta = allows_non_annual_delta) + this%gru_conv_cflux_dribbler = annual_flux_dribbler_gridcell( & + bounds = bounds, & + name = 'gru_conv_flux_' // carbon_type_suffix, & + units = 'gC/m^2', & + allows_non_annual_delta = allows_non_annual_delta) this%hrv_xsmrpool_to_atm_dribbler = annual_flux_dribbler_gridcell( & bounds = bounds, & name = 'hrv_xsmrpool_to_atm_' // carbon_type_suffix, & @@ -2878,10 +2956,19 @@ subroutine InitHistory(this, bounds, carbon_type) '(per-area-gridcell; only makes sense with dov2xy=.false.)', & ptr_patch=this%dwt_wood_productc_gain_patch, default='inactive') - this%dwt_slash_cflux_col(begc:endc) = spval - call hist_addfld1d (fname='DWT_SLASH_CFLUX', units='gC/m^2/s', & - avgflag='A', long_name='slash C flux to litter and CWD due to land use', & - ptr_col=this%dwt_slash_cflux_col) + this%dwt_slash_cflux_grc(begg:endg) = spval + call hist_addfld1d (fname='DWT_SLASH_CFLUX', units='gC/m^2/s', & + avgflag='A', & + long_name='slash C flux (to litter diagnostic only) (0 at all times except first timestep of year)', & + ptr_gcell=this%dwt_slash_cflux_grc) + + this%dwt_slash_cflux_patch(begp:endp) = spval + call hist_addfld1d (fname='DWT_SLASH_CFLUX_PATCH', units='gC/m^2/s', & + avgflag='A', & + long_name='patch-level slash C flux (to litter diagnostic only) ' // & + '(0 at all times except first timestep of year) ' // & + '(per-area-gridcell; only makes sense with dov2xy=.false.)', & + ptr_patch=this%dwt_slash_cflux_patch, default='inactive') this%dwt_frootc_to_litr_met_c_col(begc:endc,:) = spval call hist_addfld_decomp (fname='DWT_FROOTC_TO_LITR_MET_C', units='gC/m^2/s', type2d='levdcmp', & @@ -2908,6 +2995,27 @@ subroutine InitHistory(this, bounds, carbon_type) avgflag='A', long_name='dead coarse root to CWD due to landcover change', & ptr_col=this%dwt_deadcrootc_to_cwdc_col, default='inactive') + this%gru_conv_cflux_patch(begp:endp) = spval + call hist_addfld1d (fname='GRU_CONV_CFLUX', units='gC/m^2/s', & + avgflag='A', long_name='gross unrepresented conversion C flux (immediate loss to atm) (0 at all times except first timestep of year)', & + ptr_patch=this%gru_conv_cflux_patch) + + this%gru_conv_cflux_dribbled_grc(begg:endg) = spval + call hist_addfld1d (fname='GRU_CONV_CFLUX_DRIBBLED', units='gC/m^2/s', & + avgflag='A', & + long_name='gross unrepresented conversion C flux (immediate loss to atm), dribbled throughout the year', & + ptr_gcell=this%gru_conv_cflux_dribbled_grc) + + this%gru_wood_productc_gain_patch(begp:endp) = spval + call hist_addfld1d (fname='GRU_WOODPRODC_GAIN', units='gC/m^2/s', & + avgflag='A', long_name='gross unrepresented landcover change driven addition to wood product carbon pools (0 at all times except first timestep of year)', & + ptr_patch=this%gru_wood_productc_gain_patch) + + this%gru_slash_cflux_patch(begp:endp) = spval + call hist_addfld1d (fname='GRU_SLASH_CFLUX', units='gC/m^2/s', & + avgflag='A', long_name='slash gross unrepresented landcover change carbon (to litter)', & + ptr_patch=this%gru_slash_cflux_patch) + this%crop_seedc_to_leaf_patch(begp:endp) = spval call hist_addfld1d (fname='CROP_SEEDC_TO_LEAF', units='gC/m^2/s', & avgflag='A', long_name='crop seed source to leaf', & @@ -3052,10 +3160,19 @@ subroutine InitHistory(this, bounds, carbon_type) long_name='C13 conversion C flux (immediate loss to atm), dribbled throughout the year', & ptr_gcell=this%dwt_conv_cflux_dribbled_grc) - this%dwt_slash_cflux_col(begc:endc) = spval - call hist_addfld1d (fname='C13_DWT_SLASH_CFLUX', units='gC/m^2/s', & - avgflag='A', long_name='C13 slash C flux to litter and CWD due to land use', & - ptr_col=this%dwt_slash_cflux_col) + this%dwt_slash_cflux_grc(begg:endg) = spval + call hist_addfld1d (fname='C13_DWT_SLASH_CFLUX', units='gC13/m^2/s', & + avgflag='A', long_name='C13 slash C flux (to litter diagnostic only)' // & + '(0 at all times except first timestep of year)', & + ptr_gcell=this%dwt_slash_cflux_grc) + + this%dwt_slash_cflux_patch(begp:endp) = spval + call hist_addfld1d (fname='C13_DWT_SLASH_CFLUX_PATCH', units='gC13/m^2/s', & + avgflag='A', & + long_name='patch-level C13 slash C flux (to litter diagnostic only) ' // & + '(0 at all times except first timestep of year) ' // & + '(per-area-gridcell; only makes sense with dov2xy=.false.)', & + ptr_patch=this%dwt_slash_cflux_patch, default='inactive') this%dwt_frootc_to_litr_met_c_col(begc:endc,:) = spval call hist_addfld_decomp (fname='C13_DWT_FROOTC_TO_LITR_MET_C', units='gC13/m^2/s', type2d='levdcmp', & @@ -3201,10 +3318,19 @@ subroutine InitHistory(this, bounds, carbon_type) long_name='C14 conversion C flux (immediate loss to atm), dribbled throughout the year', & ptr_gcell=this%dwt_conv_cflux_dribbled_grc) - this%dwt_slash_cflux_col(begc:endc) = spval - call hist_addfld1d (fname='C14_DWT_SLASH_CFLUX', units='gC/m^2/s', & - avgflag='A', long_name='C14 slash C flux to litter and CWD due to land use', & - ptr_col=this%dwt_slash_cflux_col) + this%dwt_slash_cflux_grc(begg:endg) = spval + call hist_addfld1d (fname='C14_DWT_SLASH_CFLUX', units='gC14/m^2/s', & + avgflag='A', long_name='C14 slash C flux (to litter diagnostic only)' // & + '(0 at all times except first timestep of year)', & + ptr_gcell=this%dwt_slash_cflux_grc) + + this%dwt_slash_cflux_patch(begp:endp) = spval + call hist_addfld1d (fname='C14_DWT_SLASH_CFLUX_PATCH', units='gC14/m^2/s', & + avgflag='A', & + long_name='patch-level C14 slash C flux (to litter diagnostic only)' // & + '(0 at all times except first timestep of year) ' // & + '(per-area-gridcell; only makes sense with dov2xy=.false.)', & + ptr_patch=this%dwt_slash_cflux_patch, default='inactive') this%dwt_frootc_to_litr_met_c_col(begc:endc,:) = spval call hist_addfld_decomp (fname='C14_DWT_FROOTC_TO_LITR_MET_C', units='gC14/m^2/s', type2d='levdcmp', & @@ -3352,7 +3478,6 @@ subroutine InitCold(this, bounds) ! also initialize dynamic landcover fluxes so that they have ! real values on first timestep, prior to calling pftdyn_cnbal if (lun%itype(l) == istsoil .or. lun%itype(l) == istcrop) then - this%dwt_slash_cflux_col(c) = 0._r8 do j = 1, nlevdecomp_full this%dwt_frootc_to_litr_met_c_col(c,j) = 0._r8 this%dwt_frootc_to_litr_cel_c_col(c,j) = 0._r8 @@ -3363,6 +3488,21 @@ subroutine InitCold(this, bounds) end if end do + do c = bounds%begc, bounds%endc + l = col%landunit(c) + + ! also initialize gross unrepresented landcover fluxes so that they have + ! real values on first timestep, prior to calling pftdyn_cnbal + if (lun%itype(l) == istsoil .or. lun%itype(l) == istcrop) then + do j = 1, nlevdecomp_full + this%gru_c_to_litr_met_c_col(c,j) = 0._r8 + this%gru_c_to_litr_cel_c_col(c,j) = 0._r8 + this%gru_c_to_litr_lig_c_col(c,j) = 0._r8 + this%gru_c_to_cwdc_col(c,j) = 0._r8 + end do + end if + end do + do p = bounds%begp,bounds%endp l = patch%landunit(p) @@ -3596,6 +3736,7 @@ subroutine RestartAllIsotopes ( this, bounds, ncid, flag ) !----------------------------------------------------------------------- call this%dwt_conv_cflux_dribbler%Restart(bounds, ncid, flag) + call this%gru_conv_cflux_dribbler%Restart(bounds, ncid, flag) call this%hrv_xsmrpool_to_atm_dribbler%Restart(bounds, ncid, flag) end subroutine RestartAllIsotopes @@ -3666,6 +3807,32 @@ subroutine SetValues ( this, & this%hrv_gresp_xfer_to_litter_patch(i) = value_patch this%hrv_xsmrpool_to_atm_patch(i) = value_patch + this%gru_leafc_to_litter_patch(i) = value_patch + this%gru_leafc_storage_to_atm_patch(i) = value_patch + this%gru_leafc_xfer_to_atm_patch(i) = value_patch + this%gru_frootc_to_litter_patch(i) = value_patch + this%gru_frootc_storage_to_atm_patch(i) = value_patch + this%gru_frootc_xfer_to_atm_patch(i) = value_patch + this%gru_livestemc_to_atm_patch(i) = value_patch + this%gru_livestemc_storage_to_atm_patch(i) = value_patch + this%gru_livestemc_xfer_to_atm_patch(i) = value_patch + this%gru_deadstemc_to_atm_patch(i) = value_patch + this%gru_deadstemc_storage_to_atm_patch(i) = value_patch + this%gru_deadstemc_xfer_to_atm_patch(i) = value_patch + this%gru_livecrootc_to_litter_patch(i) = value_patch + this%gru_livecrootc_storage_to_atm_patch(i) = value_patch + this%gru_livecrootc_xfer_to_atm_patch(i) = value_patch + this%gru_deadcrootc_to_litter_patch(i) = value_patch + this%gru_deadcrootc_storage_to_atm_patch(i) = value_patch + this%gru_deadcrootc_xfer_to_atm_patch(i) = value_patch + this%gru_gresp_storage_to_atm_patch(i) = value_patch + this%gru_gresp_xfer_to_atm_patch(i) = value_patch + this%gru_xsmrpool_to_atm_patch(i) = value_patch + + this%gru_conv_cflux_patch(i) = value_patch + this%gru_wood_productc_gain_patch(i) = value_patch + this%gru_slash_cflux_patch(i) = value_patch + this%m_leafc_to_fire_patch(i) = value_patch this%m_leafc_storage_to_fire_patch(i) = value_patch this%m_leafc_xfer_to_fire_patch(i) = value_patch @@ -3840,6 +4007,11 @@ subroutine SetValues ( this, & this%harvest_c_to_litr_lig_c_col(i,j) = value_column this%harvest_c_to_cwdc_col(i,j) = value_column + this%gru_c_to_litr_met_c_col(i,j) = value_column + this%gru_c_to_litr_cel_c_col(i,j) = value_column + this%gru_c_to_litr_lig_c_col(i,j) = value_column + this%gru_c_to_cwdc_col(i,j) = value_column + end do end do @@ -3924,6 +4096,8 @@ subroutine SetValues ( this, & this%fire_closs_col(i) = value_column this%wood_harvestc_col(i) = value_column this%hrv_xsmrpool_to_atm_col(i) = value_column + this%gru_conv_cflux_col(i) = value_column + this%gru_wood_productc_gain_col(i) = value_column this%nep_col(i) = value_column @@ -3951,10 +4125,7 @@ subroutine ZeroDwt( this, bounds ) this%dwt_seedc_to_leaf_grc(g) = 0._r8 this%dwt_seedc_to_deadstem_grc(g) = 0._r8 this%dwt_conv_cflux_grc(g) = 0._r8 - end do - - do c = bounds%begc,bounds%endc - this%dwt_slash_cflux_col(c) = 0._r8 + this%dwt_slash_cflux_grc(g) = 0._r8 end do do j = 1, nlevdecomp_full @@ -3969,6 +4140,28 @@ subroutine ZeroDwt( this, bounds ) end subroutine ZeroDwt + !----------------------------------------------------------------------- + subroutine ZeroGru( this, bounds ) + ! + ! !DESCRIPTION + ! Initialize flux variables needed for dynamic land use. + ! + ! !ARGUMENTS: + class(cnveg_carbonflux_type) :: this + type(bounds_type), intent(in) :: bounds + ! + ! !LOCAL VARIABLES: + integer :: c, g, j ! indices + !----------------------------------------------------------------------- + + ! set conversion and product pool fluxes to 0 at the beginning of every timestep + + do g = bounds%begg, bounds%endg + this%gru_conv_cflux_grc(g) = 0._r8 + end do + + end subroutine ZeroGru + !----------------------------------------------------------------------- subroutine Summary_carbonflux(this, & bounds, num_soilc, filter_soilc, num_soilp, filter_soilp, & @@ -4011,6 +4204,7 @@ subroutine Summary_carbonflux(this, & real(r8) :: hrv_xsmrpool_to_atm_delta_grc(bounds%begg:bounds%endg) ! hrv_xsmrpool_to_atm_col averaged to gridcell, expressed as a delta (not a flux) (gC/m2) real(r8) :: hrv_xsmrpool_to_atm_dribbled_grc(bounds%begg:bounds%endg) ! hrv_xsmrpool_to_atm, dribbled over the year (gC/m2/s) real(r8) :: dwt_conv_cflux_delta_grc(bounds%begg:bounds%endg) ! dwt_conv_cflux_grc expressed as a total delta (not a flux) (gC/m2) + real(r8) :: gru_conv_cflux_delta_grc(bounds%begg:bounds%endg) ! gru_conv_cflux_grc expressed as a total delta (not a flux) (gC/m2) !----------------------------------------------------------------------- SHR_ASSERT_ALL((ubound(product_closs_grc) == (/bounds%endg/)), errMsg(sourcefile, __LINE__)) @@ -4243,7 +4437,12 @@ subroutine Summary_carbonflux(this, & this%hrv_deadcrootc_storage_to_litter_patch(p) + & this%hrv_deadcrootc_xfer_to_litter_patch(p) + & this%hrv_gresp_storage_to_litter_patch(p) + & - this%hrv_gresp_xfer_to_litter_patch(p) + this%hrv_gresp_xfer_to_litter_patch(p) + & + + this%gru_leafc_to_litter_patch(p) + & + this%gru_frootc_to_litter_patch(p) + & + this%gru_livecrootc_to_litter_patch(p) + & + this%gru_deadcrootc_to_litter_patch(p) if ( use_crop .and. patch%itype(p) >= npcropmin )then this%litfall_patch(p) = & @@ -4316,6 +4515,7 @@ subroutine Summary_carbonflux(this, & this%m_leafc_to_fire_patch(p) + & this%m_leafc_to_litter_fire_patch(p) + & this%hrv_leafc_to_litter_patch(p) + & + this%gru_leafc_to_litter_patch(p) + & this%leafc_to_litter_patch(p) ! (WOODC_ALLOC) - wood C allocation @@ -4350,7 +4550,20 @@ subroutine Summary_carbonflux(this, & this%hrv_livecrootc_xfer_to_litter_patch(p) + & this%hrv_deadcrootc_to_litter_patch(p) + & this%hrv_deadcrootc_storage_to_litter_patch(p) + & - this%hrv_deadcrootc_xfer_to_litter_patch(p) + this%hrv_deadcrootc_xfer_to_litter_patch(p) + & + this%gru_livestemc_to_atm_patch(p) + & + this%gru_livestemc_storage_to_atm_patch(p) + & + this%gru_livestemc_xfer_to_atm_patch(p) + & + this%gru_deadstemc_to_atm_patch(p) + & + this%gru_wood_productc_gain_patch(p) + & + this%gru_deadstemc_storage_to_atm_patch(p) + & + this%gru_deadstemc_xfer_to_atm_patch(p) + & + this%gru_livecrootc_to_litter_patch(p) + & + this%gru_livecrootc_storage_to_atm_patch(p) + & + this%gru_livecrootc_xfer_to_atm_patch(p) + & + this%gru_deadcrootc_to_litter_patch(p) + & + this%gru_deadcrootc_storage_to_atm_patch(p) + & + this%gru_deadcrootc_xfer_to_atm_patch(p) ! (Slash Harvest Flux) - Additional Wood Harvest Veg C Losses this%slash_harvestc_patch(p) = & @@ -4371,10 +4584,36 @@ subroutine Summary_carbonflux(this, & this%hrv_deadcrootc_to_litter_patch(p) + & this%hrv_deadcrootc_storage_to_litter_patch(p) + & this%hrv_deadcrootc_xfer_to_litter_patch(p) + & - this%hrv_xsmrpool_to_atm_patch(p) + & this%hrv_gresp_storage_to_litter_patch(p) + & this%hrv_gresp_xfer_to_litter_patch(p) + ! (Gross Unrepresented Landcover Change Conversion Flux) - Direct Veg C Loss to Atmosphere + this%gru_conv_cflux_patch(p) = & + this%gru_livestemc_to_atm_patch(p) + & + this%gru_deadstemc_to_atm_patch(p) + & + this%gru_xsmrpool_to_atm_patch(p) + & + this%gru_leafc_storage_to_atm_patch(p) + & + this%gru_frootc_storage_to_atm_patch(p) + & + this%gru_livestemc_storage_to_atm_patch(p) + & + this%gru_deadstemc_storage_to_atm_patch(p) + & + this%gru_livecrootc_storage_to_atm_patch(p) + & + this%gru_deadcrootc_storage_to_atm_patch(p) + & + this%gru_gresp_storage_to_atm_patch(p) + & + this%gru_leafc_xfer_to_atm_patch(p) + & + this%gru_frootc_xfer_to_atm_patch(p) + & + this%gru_livestemc_xfer_to_atm_patch(p) + & + this%gru_deadstemc_xfer_to_atm_patch(p) + & + this%gru_livecrootc_xfer_to_atm_patch(p) + & + this%gru_deadcrootc_xfer_to_atm_patch(p) + & + this%gru_gresp_xfer_to_atm_patch(p) + + ! (Gross Unrepresented Landcover Change Slash Flux) - Direct Veg C Loss to Atmosphere + this%gru_slash_cflux_patch(p) = & + this%gru_leafc_to_litter_patch(p) + & + this%gru_frootc_to_litter_patch(p) + & + this%gru_livecrootc_to_litter_patch(p) + & + this%gru_deadcrootc_to_litter_patch(p) + end do ! end of patches loop !------------------------------------------------ @@ -4387,6 +4626,10 @@ subroutine Summary_carbonflux(this, & this%hrv_xsmrpool_to_atm_patch(bounds%begp:bounds%endp), & this%hrv_xsmrpool_to_atm_col(bounds%begc:bounds%endc)) + call p2c(bounds, num_soilc, filter_soilc, & + this%gru_conv_cflux_patch(bounds%begp:bounds%endp), & + this%gru_conv_cflux_col(bounds%begc:bounds%endc)) + call p2c(bounds, num_soilc, filter_soilc, & this%fire_closs_patch(bounds%begp:bounds%endp), & this%fire_closs_p2c_col(bounds%begc:bounds%endc)) @@ -4515,6 +4758,18 @@ subroutine Summary_carbonflux(this, & call this%dwt_conv_cflux_dribbler%get_curr_flux(bounds, & this%dwt_conv_cflux_dribbled_grc(bounds%begg:bounds%endg)) + call c2g( bounds = bounds, & + carr = this%gru_conv_cflux_col(bounds%begc:bounds%endc), & + garr = this%gru_conv_cflux_grc(bounds%begg:bounds%endg), & + c2l_scale_type = 'unity', & + l2g_scale_type = 'unity') + gru_conv_cflux_delta_grc(bounds%begg:bounds%endg) = & + this%gru_conv_cflux_grc(bounds%begg:bounds%endg) * dtime + call this%gru_conv_cflux_dribbler%set_curr_delta(bounds, & + gru_conv_cflux_delta_grc(bounds%begg:bounds%endg)) + call this%gru_conv_cflux_dribbler%get_curr_flux(bounds, & + this%gru_conv_cflux_dribbled_grc(bounds%begg:bounds%endg)) + do g = bounds%begg, bounds%endg ! net ecosystem exchange of carbon, includes fire flux and hrv_xsmrpool flux, ! positive for source (NEE) @@ -4525,6 +4780,7 @@ subroutine Summary_carbonflux(this, & this%landuseflux_grc(g) = & this%dwt_conv_cflux_dribbled_grc(g) + & + this%gru_conv_cflux_dribbled_grc(g) + & product_closs_grc(g) ! net biome production of carbon, positive for sink diff --git a/src/biogeochem/CNVegNitrogenFluxType.F90 b/src/biogeochem/CNVegNitrogenFluxType.F90 index 1bb630c687..1bb3e223f9 100644 --- a/src/biogeochem/CNVegNitrogenFluxType.F90 +++ b/src/biogeochem/CNVegNitrogenFluxType.F90 @@ -205,6 +205,37 @@ module CNVegNitrogenFluxType real(r8), pointer :: dwt_livecrootn_to_cwdn_col (:,:) ! col (gN/m3/s) live coarse root to CWD due to landcover change real(r8), pointer :: dwt_deadcrootn_to_cwdn_col (:,:) ! col (gN/m3/s) dead coarse root to CWD due to landcover change + ! gross unrepresented landcover fluxes + real(r8), pointer :: gru_leafn_to_litter_patch (:) ! patch leaf N gross unrepresented landcover change mortality (gN/m2/s) + real(r8), pointer :: gru_leafn_storage_to_atm_patch (:) ! patch leaf N storage gross unrepresented landcover change mortality (gN/m2/s) + real(r8), pointer :: gru_leafn_xfer_to_atm_patch (:) ! patch leaf N transfer gross unrepresented landcover change mortality (gN/m2/s) + real(r8), pointer :: gru_frootn_to_litter_patch (:) ! patch fine root N gross unrepresented landcover change mortality (gN/m2/s) + real(r8), pointer :: gru_frootn_storage_to_atm_patch (:) ! patch fine root N storage gross unrepresented landcover change mortality (gN/m2/s) + real(r8), pointer :: gru_frootn_xfer_to_atm_patch (:) ! patch fine root N transfer gross unrepresented landcover change mortality (gN/m2/s) + real(r8), pointer :: gru_livestemn_to_atm_patch (:) ! patch live stem N gross unrepresented landcover change mortality (gN/m2/s) + real(r8), pointer :: gru_livestemn_storage_to_atm_patch (:) ! patch live stem N storage gross unrepresented landcover change mortality (gN/m2/s) + real(r8), pointer :: gru_livestemn_xfer_to_atm_patch (:) ! patch live stem N transfer gross unrepresented landcover change mortality (gN/m2/s) + real(r8), pointer :: gru_deadstemn_to_atm_patch (:) ! patch dead stem N gross unrepresented landcover change mortality to the atmosphere (gC/m2/s) + real(r8), pointer :: gru_deadstemn_storage_to_atm_patch (:) ! patch dead stem N storage gross unrepresented landcover change mortality (gN/m2/s) + real(r8), pointer :: gru_deadstemn_xfer_to_atm_patch (:) ! patch dead stem N transfer gross unrepresented landcover change mortality (gN/m2/s) + real(r8), pointer :: gru_livecrootn_to_litter_patch (:) ! patch live coarse root N gross unrepresented landcover change mortality (gN/m2/s) + real(r8), pointer :: gru_livecrootn_storage_to_atm_patch (:) ! patch live coarse root N storage gross unrepresented landcover change mortality (gN/m2/s) + real(r8), pointer :: gru_livecrootn_xfer_to_atm_patch (:) ! patch live coarse root N transfer gross unrepresented landcover change mortality (gN/m2/s) + real(r8), pointer :: gru_deadcrootn_to_litter_patch (:) ! patch dead coarse root N gross unrepresented landcover change mortality (gN/m2/s) + real(r8), pointer :: gru_deadcrootn_storage_to_atm_patch (:) ! patch dead coarse root N storage gross unrepresented landcover change mortality (gN/m2/s) + real(r8), pointer :: gru_deadcrootn_xfer_to_atm_patch (:) ! patch dead coarse root N transfer gross unrepresented landcover change mortality (gN/m2/s) + real(r8), pointer :: gru_retransn_to_litter_patch (:) ! patch retranslocated N pool gross unrepresented landcover change mortality (gN/m2/s) + + real(r8), pointer :: gru_conv_nflux_patch (:) ! (gN/m2/s) conversion N flux (immediate loss to atm) + real(r8), pointer :: gru_conv_nflux_col (:) ! (gN/m2/s) conversion N flux (immediate loss to atm) + real(r8), pointer :: gru_conv_nflux_grc (:) ! (gN/m2/s) gru_conv_nflux_patch summed to the gridcell-level + real(r8), pointer :: gru_wood_productn_gain_patch (:) ! patch (gN/m2/s) addition to wood product pools from gross unrepresented landcover change + real(r8), pointer :: gru_wood_productn_gain_col (:) ! patch (gN/m2/s) addition to wood product pools from gross unrepresented landcover change + real(r8), pointer :: gru_n_to_litr_met_n_col (:,:) ! col (gN/m3/s) N to litter due to gross unrepresented landcover change + real(r8), pointer :: gru_n_to_litr_cel_n_col (:,:) ! col (gN/m3/s) N to litter due to gross unrepresented landcover change + real(r8), pointer :: gru_n_to_litr_lig_n_col (:,:) ! col (gN/m3/s) N to litter due to gross unrepresented landcover change + real(r8), pointer :: gru_n_to_cwdn_col (:,:) ! col (gN/m3/s) N to CWD due to gross unrepresented landcover change + ! crop fluxes real(r8), pointer :: crop_seedn_to_leaf_patch (:) ! patch (gN/m2/s) seed source to leaf, for crops @@ -249,6 +280,7 @@ module CNVegNitrogenFluxType procedure , public :: Restart procedure , public :: SetValues procedure , public :: ZeroDWT + procedure , public :: ZeroGRU procedure , public :: Summary => Summary_nitrogenflux procedure , private :: InitAllocate procedure , private :: InitHistory @@ -447,6 +479,36 @@ subroutine InitAllocate(this, bounds) allocate(this%dwt_livecrootn_to_cwdn_col (begc:endc,1:nlevdecomp_full)) ; this%dwt_livecrootn_to_cwdn_col (:,:) = nan allocate(this%dwt_deadcrootn_to_cwdn_col (begc:endc,1:nlevdecomp_full)) ; this%dwt_deadcrootn_to_cwdn_col (:,:) = nan + allocate(this%gru_leafn_to_litter_patch (begp:endp)) ; this%gru_leafn_to_litter_patch (:) = nan + allocate(this%gru_leafn_storage_to_atm_patch (begp:endp)) ; this%gru_leafn_storage_to_atm_patch (:) = nan + allocate(this%gru_leafn_xfer_to_atm_patch (begp:endp)) ; this%gru_leafn_xfer_to_atm_patch (:) = nan + allocate(this%gru_frootn_to_litter_patch (begp:endp)) ; this%gru_frootn_to_litter_patch (:) = nan + allocate(this%gru_frootn_storage_to_atm_patch (begp:endp)) ; this%gru_frootn_storage_to_atm_patch (:) = nan + allocate(this%gru_frootn_xfer_to_atm_patch (begp:endp)) ; this%gru_frootn_xfer_to_atm_patch (:) = nan + allocate(this%gru_livestemn_to_atm_patch (begp:endp)) ; this%gru_livestemn_to_atm_patch (:) = nan + allocate(this%gru_livestemn_storage_to_atm_patch (begp:endp)) ; this%gru_livestemn_storage_to_atm_patch (:) = nan + allocate(this%gru_livestemn_xfer_to_atm_patch (begp:endp)) ; this%gru_livestemn_xfer_to_atm_patch (:) = nan + allocate(this%gru_deadstemn_to_atm_patch (begp:endp)) ; this%gru_deadstemn_storage_to_atm_patch (:) = nan + allocate(this%gru_deadstemn_storage_to_atm_patch (begp:endp)) ; this%gru_deadstemn_storage_to_atm_patch (:) = nan + allocate(this%gru_deadstemn_xfer_to_atm_patch (begp:endp)) ; this%gru_deadstemn_xfer_to_atm_patch (:) = nan + allocate(this%gru_livecrootn_storage_to_atm_patch (begp:endp)) ; this%gru_livecrootn_storage_to_atm_patch (:) = nan + allocate(this%gru_livecrootn_xfer_to_atm_patch (begp:endp)) ; this%gru_livecrootn_xfer_to_atm_patch (:) = nan + allocate(this%gru_livecrootn_to_litter_patch (begp:endp)) ; this%gru_livecrootn_to_litter_patch (:) = nan + allocate(this%gru_deadcrootn_storage_to_atm_patch (begp:endp)) ; this%gru_deadcrootn_storage_to_atm_patch (:) = nan + allocate(this%gru_deadcrootn_xfer_to_atm_patch (begp:endp)) ; this%gru_deadcrootn_xfer_to_atm_patch (:) = nan + allocate(this%gru_deadcrootn_to_litter_patch (begp:endp)) ; this%gru_deadcrootn_to_litter_patch (:) = nan + allocate(this%gru_retransn_to_litter_patch (begp:endp)) ; this%gru_retransn_to_litter_patch (:) = nan + + allocate(this%gru_conv_nflux_patch (begp:endp)) ; this%gru_conv_nflux_patch (:) =nan + allocate(this%gru_conv_nflux_col (begc:endc)) ; this%gru_conv_nflux_col (:) =nan + allocate(this%gru_conv_nflux_grc (begg:endg)) ; this%gru_conv_nflux_grc (:) =nan + allocate(this%gru_wood_productn_gain_patch (begp:endp)) ; this%gru_wood_productn_gain_patch (:) =nan + allocate(this%gru_wood_productn_gain_col (begc:endc)) ; this%gru_wood_productn_gain_col (:) =nan + allocate(this%gru_n_to_litr_met_n_col (begc:endc,1:nlevdecomp_full)); this%gru_n_to_litr_met_n_col (:,:)=nan + allocate(this%gru_n_to_litr_cel_n_col (begc:endc,1:nlevdecomp_full)); this%gru_n_to_litr_cel_n_col (:,:)=nan + allocate(this%gru_n_to_litr_lig_n_col (begc:endc,1:nlevdecomp_full)); this%gru_n_to_litr_lig_n_col (:,:)=nan + allocate(this%gru_n_to_cwdn_col (begc:endc,1:nlevdecomp_full)); this%gru_n_to_cwdn_col (:,:)=nan + allocate(this%crop_seedn_to_leaf_patch (begp:endp)) ; this%crop_seedn_to_leaf_patch (:) = nan allocate(this%m_decomp_npools_to_fire_vr_col (begc:endc,1:nlevdecomp_full,1:ndecomp_pools)) @@ -1059,6 +1121,16 @@ subroutine InitHistory(this, bounds) avgflag='A', long_name='dead coarse root to CWD due to landcover change', & ptr_col=this%dwt_deadcrootn_to_cwdn_col, default='inactive') + this%gru_conv_nflux_patch(begp:endp) = spval + call hist_addfld1d (fname='GRU_CONV_NFLUX', units='gN/m^2/s', & + avgflag='A', long_name='gross unrepresented conversion N flux (immediate loss to atm) (0 at all times except first timestep of year)', & + ptr_patch=this%gru_conv_nflux_patch) + + this%gru_wood_productn_gain_patch(begp:endp) = spval + call hist_addfld1d (fname='GRU_WOODPRODN_GAIN', units='gN/m^2/s', & + avgflag='A', long_name='gross unrepresented landcover change driven addition to wood product nitrogen pools (0 at all times except first timestep of year)', & + ptr_patch=this%gru_wood_productn_gain_patch) + this%crop_seedn_to_leaf_patch(begp:endp) = spval call hist_addfld1d (fname='CROP_SEEDN_TO_LEAF', units='gN/m^2/s', & avgflag='A', long_name='crop seed source to leaf', & @@ -1577,6 +1649,26 @@ subroutine SetValues ( this, & this%hrv_deadcrootn_to_litter_patch(i) = value_patch this%hrv_retransn_to_litter_patch(i) = value_patch + this%gru_leafn_to_litter_patch(i) = value_patch + this%gru_leafn_storage_to_atm_patch(i) = value_patch + this%gru_leafn_xfer_to_atm_patch(i) = value_patch + this%gru_frootn_to_litter_patch(i) = value_patch + this%gru_frootn_storage_to_atm_patch(i) = value_patch + this%gru_frootn_xfer_to_atm_patch(i) = value_patch + this%gru_livestemn_to_atm_patch(i) = value_patch + this%gru_livestemn_storage_to_atm_patch(i) = value_patch + this%gru_livestemn_xfer_to_atm_patch(i) = value_patch + this%gru_deadstemn_to_atm_patch(i) = value_patch + this%gru_deadstemn_storage_to_atm_patch(i) = value_patch + this%gru_deadstemn_xfer_to_atm_patch(i) = value_patch + this%gru_livecrootn_to_litter_patch(i) = value_patch + this%gru_livecrootn_storage_to_atm_patch(i) = value_patch + this%gru_livecrootn_xfer_to_atm_patch(i) = value_patch + this%gru_deadcrootn_storage_to_atm_patch(i) = value_patch + this%gru_deadcrootn_xfer_to_atm_patch(i) = value_patch + this%gru_deadcrootn_to_litter_patch(i) = value_patch + this%gru_retransn_to_litter_patch(i) = value_patch + this%m_leafn_to_fire_patch(i) = value_patch this%m_leafn_storage_to_fire_patch(i) = value_patch this%m_leafn_xfer_to_fire_patch(i) = value_patch @@ -1597,6 +1689,8 @@ subroutine SetValues ( this, & this%m_deadcrootn_xfer_to_fire_patch(i) = value_patch this%m_retransn_to_fire_patch(i) = value_patch + this%gru_conv_nflux_patch(i) = value_patch + this%gru_wood_productn_gain_patch(i) = value_patch this%m_leafn_to_litter_fire_patch(i) = value_patch this%m_leafn_storage_to_litter_fire_patch(i) = value_patch @@ -1703,6 +1797,12 @@ subroutine SetValues ( this, & this%harvest_n_to_litr_cel_n_col(i,j) = value_column this%harvest_n_to_litr_lig_n_col(i,j) = value_column this%harvest_n_to_cwdn_col(i,j) = value_column + + ! gross unrepresented landcover change + this%gru_n_to_litr_met_n_col(i,j) = value_column + this%gru_n_to_litr_cel_n_col(i,j) = value_column + this%gru_n_to_litr_lig_n_col(i,j) = value_column + this%gru_n_to_cwdn_col(i,j) = value_column end do end do @@ -1715,6 +1815,8 @@ subroutine SetValues ( this, & ! Zero p2c column fluxes this%fire_nloss_col(i) = value_column this%wood_harvestn_col(i) = value_column + this%gru_conv_nflux_col(i) = value_column + this%gru_wood_productn_gain_col(i) = value_column end do do k = 1, ndecomp_pools @@ -1767,13 +1869,33 @@ subroutine ZeroDwt( this, bounds ) end subroutine ZeroDwt + !----------------------------------------------------------------------- + subroutine ZeroGru( this, bounds ) + ! + ! !DESCRIPTION + ! Initialize flux variables needed for dynamic land use. + ! + ! !ARGUMENTS: + class(cnveg_nitrogenflux_type) :: this + type(bounds_type), intent(in) :: bounds + ! + ! !LOCAL VARIABLES: + integer :: c, g, j ! indices + !----------------------------------------------------------------------- + + do g = bounds%begg, bounds%endg + this%gru_conv_nflux_grc(g) = 0._r8 + end do + + end subroutine ZeroGru + !----------------------------------------------------------------------- subroutine Summary_nitrogenflux(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soilp) ! ! !USES: use clm_varpar , only: nlevdecomp,ndecomp_cascade_transitions,ndecomp_pools use clm_varctl , only: use_nitrif_denitrif - use subgridAveMod , only: p2c + use subgridAveMod , only: p2c, c2g ! ! !ARGUMENTS: class (cnveg_nitrogenflux_type) :: this @@ -1820,12 +1942,39 @@ subroutine Summary_nitrogenflux(this, bounds, num_soilc, filter_soilc, num_soilp this%m_deadcrootn_xfer_to_fire_patch(p) + & this%m_retransn_to_fire_patch(p) + ! (Gross Unrepresented Landcover Change Conversion Flux) - Direct Veg N Loss to Atmosphere + this%gru_conv_nflux_patch(p) = & + this%gru_livestemn_to_atm_patch(p) + & + this%gru_deadstemn_to_atm_patch(p) + & + this%gru_leafn_storage_to_atm_patch(p) + & + this%gru_frootn_storage_to_atm_patch(p) + & + this%gru_livestemn_storage_to_atm_patch(p) + & + this%gru_deadstemn_storage_to_atm_patch(p) + & + this%gru_livecrootn_storage_to_atm_patch(p) + & + this%gru_deadcrootn_storage_to_atm_patch(p) + & + this%gru_leafn_xfer_to_atm_patch(p) + & + this%gru_frootn_xfer_to_atm_patch(p) + & + this%gru_livestemn_xfer_to_atm_patch(p) + & + this%gru_deadstemn_xfer_to_atm_patch(p) + & + this%gru_livecrootn_xfer_to_atm_patch(p) + & + this%gru_deadcrootn_xfer_to_atm_patch(p) + end do call p2c(bounds, num_soilc, filter_soilc, & this%fire_nloss_patch(bounds%begp:bounds%endp), & this%fire_nloss_p2c_col(bounds%begc:bounds%endc)) + call p2c(bounds, num_soilc, filter_soilc, & + this%gru_conv_nflux_patch(bounds%begp:bounds%endp), & + this%gru_conv_nflux_col(bounds%begc:bounds%endc)) + + call c2g( bounds = bounds, & + carr = this%gru_conv_nflux_col(bounds%begc:bounds%endc), & + garr = this%gru_conv_nflux_grc(bounds%begg:bounds%endg), & + c2l_scale_type = 'unity', & + l2g_scale_type = 'unity') + ! vertically integrate column-level fire N losses do k = 1, ndecomp_pools do j = 1, nlevdecomp diff --git a/src/biogeochem/CNVegetationFacade.F90 b/src/biogeochem/CNVegetationFacade.F90 index 10c8164baa..c1ff66f675 100644 --- a/src/biogeochem/CNVegetationFacade.F90 +++ b/src/biogeochem/CNVegetationFacade.F90 @@ -558,6 +558,15 @@ subroutine InitEachTimeStep(this, bounds, num_soilc, filter_soilc) call this%cnveg_carbonstate_inst%ZeroDWT(bounds) call this%cnveg_nitrogenstate_inst%ZeroDWT(bounds) + call this%cnveg_carbonflux_inst%ZeroGRU(bounds) + if (use_c13) then + call this%c13_cnveg_carbonflux_inst%ZeroGRU(bounds) + end if + if (use_c14) then + call this%c14_cnveg_carbonflux_inst%ZeroGRU(bounds) + end if + call this%cnveg_nitrogenflux_inst%ZeroGRU(bounds) + end subroutine InitEachTimeStep !----------------------------------------------------------------------- diff --git a/src/biogeochem/dynConsBiogeochemMod.F90 b/src/biogeochem/dynConsBiogeochemMod.F90 index e233653ca7..096ab102fb 100644 --- a/src/biogeochem/dynConsBiogeochemMod.F90 +++ b/src/biogeochem/dynConsBiogeochemMod.F90 @@ -587,36 +587,6 @@ subroutine dyn_cnbal_patch(bounds, & end do - ! calculate patch-to-column slash fluxes into litter and CWD pools - do p = bounds%begp, bounds%endp - c = patch%column(p) - - ! fine and coarse root to litter and CWD slash carbon fluxes - cnveg_carbonflux_inst%dwt_slash_cflux_col(c) = & - cnveg_carbonflux_inst%dwt_slash_cflux_col(c) + & - dwt_frootc_to_litter(p)/dt + & - dwt_livecrootc_to_litter(p)/dt + & - dwt_deadcrootc_to_litter(p)/dt - - if ( use_c13 ) then - c13_cnveg_carbonflux_inst%dwt_slash_cflux_col(c) = & - c13_cnveg_carbonflux_inst%dwt_slash_cflux_col(c) + & - dwt_frootc13_to_litter(p)/dt + & - dwt_livecrootc13_to_litter(p)/dt + & - dwt_deadcrootc13_to_litter(p)/dt - endif - - if ( use_c14 ) then - c14_cnveg_carbonflux_inst%dwt_slash_cflux_col(c) = & - c14_cnveg_carbonflux_inst%dwt_slash_cflux_col(c) + & - dwt_frootc14_to_litter(p)/dt + & - dwt_livecrootc14_to_litter(p)/dt + & - dwt_deadcrootc14_to_litter(p)/dt - endif - - end do - - ! calculate patch-to-column for fluxes into litter and CWD pools do j = 1, nlevdecomp do p = bounds%begp, bounds%endp @@ -787,6 +757,46 @@ subroutine dyn_cnbal_patch(bounds, & end do + ! calculate patch-to-gridcell slash fluxes into litter and CWD pools + ! Note that patch-level fluxes are stored per unit GRIDCELL area - thus, we don't + ! need to multiply by the patch's gridcell weight when translating patch-level + ! fluxes into gridcell-level fluxes. + + do p = bounds%begp, bounds%endp + g = patch%gridcell(p) + + ! fine and coarse root to litter and CWD slash carbon fluxes + cnveg_carbonflux_inst%dwt_slash_cflux_patch(p) = & + dwt_frootc_to_litter(p)/dt + & + dwt_livecrootc_to_litter(p)/dt + & + dwt_deadcrootc_to_litter(p)/dt + cnveg_carbonflux_inst%dwt_slash_cflux_grc(g) = & + cnveg_carbonflux_inst%dwt_slash_cflux_grc(g) + & + cnveg_carbonflux_inst%dwt_slash_cflux_patch(p) + + if ( use_c13 ) then + c13_cnveg_carbonflux_inst%dwt_slash_cflux_patch(p) = & + dwt_frootc13_to_litter(p)/dt + & + dwt_livecrootc13_to_litter(p)/dt + & + dwt_deadcrootc13_to_litter(p)/dt + c13_cnveg_carbonflux_inst%dwt_slash_cflux_grc(g) = & + c13_cnveg_carbonflux_inst%dwt_slash_cflux_grc(g) + & + c13_cnveg_carbonflux_inst%dwt_slash_cflux_patch(p) + endif + + if ( use_c14 ) then + c14_cnveg_carbonflux_inst%dwt_slash_cflux_patch(p) = & + dwt_frootc14_to_litter(p)/dt + & + dwt_livecrootc14_to_litter(p)/dt + & + dwt_deadcrootc14_to_litter(p)/dt + c14_cnveg_carbonflux_inst%dwt_slash_cflux_grc(g) = & + c14_cnveg_carbonflux_inst%dwt_slash_cflux_grc(g) + & + c14_cnveg_carbonflux_inst%dwt_slash_cflux_patch(p) + endif + + end do + + ! Deallocate patch-level flux arrays deallocate(dwt) deallocate(dwt_leafc_seed) diff --git a/src/biogeochem/dynGrossUnrepMod.F90 b/src/biogeochem/dynGrossUnrepMod.F90 new file mode 100644 index 0000000000..15d5db95a6 --- /dev/null +++ b/src/biogeochem/dynGrossUnrepMod.F90 @@ -0,0 +1,528 @@ +module dynGrossUnrepMod + +#include "shr_assert.h" + + !--------------------------------------------------------------------------- + ! !DESCRIPTION: + ! Handle reading of the gross unrepresented landcover change data, as well as the + ! state updates that happen as a result. + ! + ! !USES: + use shr_kind_mod , only : r8 => shr_kind_r8 + use shr_log_mod , only : errMsg => shr_log_errMsg + use decompMod , only : bounds_type, BOUNDS_LEVEL_PROC + use abortutils , only : endrun + use dynFileMod , only : dyn_file_type + use dynVarTimeUninterpMod , only : dyn_var_time_uninterp_type + use CNVegCarbonStateType , only : cnveg_carbonstate_type + use CNVegCarbonFluxType , only : cnveg_carbonflux_type + use CNVegNitrogenStateType , only : cnveg_nitrogenstate_type + use CNVegNitrogenFluxType , only : cnveg_nitrogenflux_type + use SoilBiogeochemStateType , only : soilbiogeochem_state_type + use pftconMod , only : pftcon + use clm_varcon , only : grlnd + use clm_varpar , only : natpft_size + use ColumnType , only : col + use PatchType , only : patch + ! + ! !PUBLIC MEMBER FUNCTIONS: + implicit none + private + ! + public :: dynGrossUnrep_init ! initialize data structures for grossunrep information + public :: dynGrossUnrep_interp ! get grossunrep data for current time step, if needed + public :: CNGrossUnrep ! grossunrep mortality routine for CN code + ! + ! !PRIVATE MEMBER FUNCTIONS: + private :: CNGrossUnrepPftToColumn ! gather patch-level grossunrep fluxes to the column level + ! + ! !PRIVATE TYPES: + + ! Note that, since we have our own dyngrossunrep_file object (distinct from dynpft_file), + ! we could theoretically have a separate file providing grossunrep data from that providing + ! the pftdyn data + type(dyn_file_type), target :: dyngrossunrep_file ! information for the file containing grossunrep data + + ! Define the underlying grossunrep variables + character(len=64), parameter :: grossunrep_varname = 'UNREPRESENTED_PFT_LULCC' + + type(dyn_var_time_uninterp_type) :: gru_inst ! value of gross unrepresented variable + + real(r8) , allocatable :: grossunrepfrac(:,:) ! gross unrepresented landcover change fraction + logical :: do_grossunrep ! whether we're in a period when we should do gross unrepresented landcover change + character(len=*), parameter, private :: sourcefile = & + __FILE__ + !--------------------------------------------------------------------------- + +contains + + !----------------------------------------------------------------------- + subroutine dynGrossUnrep_init(bounds, grossunrep_filename) + ! + ! !DESCRIPTION: + ! Initialize data structures for grossunrep information. + ! This should be called once, during model initialization. + ! + ! !USES: + use dynVarTimeUninterpMod , only : dyn_var_time_uninterp_type + use dynTimeInfoMod , only : YEAR_POSITION_START_OF_TIMESTEP + ! + ! !ARGUMENTS: + type(bounds_type) , intent(in) :: bounds ! proc-level bounds + character(len=*) , intent(in) :: grossunrep_filename ! name of file containing grossunrep information + ! + ! !LOCAL VARIABLES: + integer :: num_points ! number of spatial points + integer :: ier ! error code + + character(len=*), parameter :: subname = 'dynGrossUnrep_init' + !----------------------------------------------------------------------- + + SHR_ASSERT_ALL(bounds%level == BOUNDS_LEVEL_PROC, subname // ': argument must be PROC-level bounds') + + allocate(grossunrepfrac(bounds%begg:bounds%endg,0:natpft_size-1),stat=ier) + if (ier /= 0) then + call endrun(msg=' allocation error for grossunrep'//errMsg(sourcefile, __LINE__)) + end if + + ! Get the year from the START of the timestep for consistency with other dyn file + ! stuff (though it shouldn't actually matter for grossunrep, given the way the + ! once-per-year grossunrep is applied). + dyngrossunrep_file = dyn_file_type(grossunrep_filename, YEAR_POSITION_START_OF_TIMESTEP) + + ! Get initial grossunrep data + num_points = (bounds%endg - bounds%begg + 1) + gru_inst = dyn_var_time_uninterp_type( & + dyn_file=dyngrossunrep_file, varname=grossunrep_varname, & + dim1name=grlnd, conversion_factor=1.0_r8, & + do_check_sums_equal_1=.false., data_shape=[num_points,natpft_size]) + + end subroutine dynGrossUnrep_init + + + !----------------------------------------------------------------------- + subroutine dynGrossUnrep_interp(bounds) + ! + ! !DESCRIPTION: + ! Get grossunrep data for model time, when needed. + ! + ! Note that grossunrep data are stored as rates (not weights) and so time interpolation + ! is not necessary - the grossunrep rate is held constant through the year. This is + ! consistent with the treatment of changing PFT weights, where interpolation of the + ! annual endpoint weights leads to a constant rate of change in PFT weight through the + ! year, with abrupt changes in the rate at annual boundaries. + ! + ! !USES: + use dynTimeInfoMod , only : time_info_type + ! + ! !ARGUMENTS: + type(bounds_type), intent(in) :: bounds ! proc-level bounds + ! + ! !LOCAL VARIABLES: + + character(len=*), parameter :: subname = 'dyngru_interp' + !----------------------------------------------------------------------- + + SHR_ASSERT_ALL(bounds%level == BOUNDS_LEVEL_PROC, subname // ': argument must be PROC-level bounds') + + call dyngrossunrep_file%time_info%set_current_year() + + ! Get total grossunrep for this time step + grossunrepfrac(bounds%begg:bounds%endg,0:natpft_size-1) = 0._r8 + + if (dyngrossunrep_file%time_info%is_before_time_series()) then + ! Turn off grossunrep before the start of the grossunrep time series + do_grossunrep = .false. + else + ! Note that do_grossunrep stays true even past the end of the time series. This + ! means that grossunrep rates will be maintained at the rate given in the last + ! year of the file for all years past the end of this specified time series. + do_grossunrep = .true. + call gru_inst%get_current_data(grossunrepfrac) + end if + + end subroutine dynGrossUnrep_interp + + + !----------------------------------------------------------------------- + subroutine CNGrossUnrep (num_soilc, filter_soilc, num_soilp, filter_soilp, & + soilbiogeochem_state_inst, cnveg_carbonstate_inst, cnveg_nitrogenstate_inst, & + cnveg_carbonflux_inst, cnveg_nitrogenflux_inst) + ! + ! !DESCRIPTION: + ! GrossUnrep mortality routine for coupled carbon-nitrogen code (CN) + ! + ! !USES: + use pftconMod , only : noveg, nbrdlf_evr_shrub, nc4_grass + use clm_varcon , only : secspday + use clm_time_manager, only : get_step_size_real, is_beg_curr_year + ! + ! !ARGUMENTS: + integer , intent(in) :: num_soilc ! number of soil columns in filter + integer , intent(in) :: filter_soilc(:) ! column filter for soil points + integer , intent(in) :: num_soilp ! number of soil patches in filter + integer , intent(in) :: filter_soilp(:) ! patch filter for soil points + type(soilbiogeochem_state_type) , intent(in) :: soilbiogeochem_state_inst + type(cnveg_carbonstate_type) , intent(in) :: cnveg_carbonstate_inst + type(cnveg_nitrogenstate_type) , intent(in) :: cnveg_nitrogenstate_inst + type(cnveg_carbonflux_type) , intent(inout) :: cnveg_carbonflux_inst + type(cnveg_nitrogenflux_type) , intent(inout) :: cnveg_nitrogenflux_inst + ! + ! !LOCAL VARIABLES: + integer :: p ! patch index + integer :: g ! gridcell index + integer :: fp ! patch filter index + real(r8):: thistreec ! carbon in this tree for calculating grossunrep fraction (gC/m2) + real(r8):: cm ! rate for carbon grossunrep mortality (gC/m2/yr) + real(r8):: am ! rate for fractional grossunrep mortality (1/yr) + real(r8):: m ! rate for fractional grossunrep mortality (1/s) + real(r8):: dtime ! model time step (s) + !----------------------------------------------------------------------- + + associate(& + ivt => patch%itype , & ! Input: [integer (:)] pft vegetation type + convfrac => pftcon%pconv , & ! Input: [real (:)] pft conversion to atmosphere fraction + + leafc => cnveg_carbonstate_inst%leafc_patch , & ! Input: [real(r8) (:)] (gC/m2) leaf C + frootc => cnveg_carbonstate_inst%frootc_patch , & ! Input: [real(r8) (:)] (gC/m2) fine root C + livestemc => cnveg_carbonstate_inst%livestemc_patch , & ! Input: [real(r8) (:)] (gC/m2) live stem C + deadstemc => cnveg_carbonstate_inst%deadstemc_patch , & ! Input: [real(r8) (:)] (gC/m2) dead stem C + livecrootc => cnveg_carbonstate_inst%livecrootc_patch , & ! Input: [real(r8) (:)] (gC/m2) live coarse root C + deadcrootc => cnveg_carbonstate_inst%deadcrootc_patch , & ! Input: [real(r8) (:)] (gC/m2) dead coarse root C + xsmrpool => cnveg_carbonstate_inst%xsmrpool_patch , & ! Input: [real(r8) (:)] (gC/m2) abstract C pool to meet excess MR demand + leafc_storage => cnveg_carbonstate_inst%leafc_storage_patch , & ! Input: [real(r8) (:)] (gC/m2) leaf C storage + frootc_storage => cnveg_carbonstate_inst%frootc_storage_patch , & ! Input: [real(r8) (:)] (gC/m2) fine root C storage + livestemc_storage => cnveg_carbonstate_inst%livestemc_storage_patch , & ! Input: [real(r8) (:)] (gC/m2) live stem C storage + deadstemc_storage => cnveg_carbonstate_inst%deadstemc_storage_patch , & ! Input: [real(r8) (:)] (gC/m2) dead stem C storage + livecrootc_storage => cnveg_carbonstate_inst%livecrootc_storage_patch , & ! Input: [real(r8) (:)] (gC/m2) live coarse root C storage + deadcrootc_storage => cnveg_carbonstate_inst%deadcrootc_storage_patch , & ! Input: [real(r8) (:)] (gC/m2) dead coarse root C storage + gresp_storage => cnveg_carbonstate_inst%gresp_storage_patch , & ! Input: [real(r8) (:)] (gC/m2) growth respiration storage + leafc_xfer => cnveg_carbonstate_inst%leafc_xfer_patch , & ! Input: [real(r8) (:)] (gC/m2) leaf C transfer + frootc_xfer => cnveg_carbonstate_inst%frootc_xfer_patch , & ! Input: [real(r8) (:)] (gC/m2) fine root C transfer + livestemc_xfer => cnveg_carbonstate_inst%livestemc_xfer_patch , & ! Input: [real(r8) (:)] (gC/m2) live stem C transfer + deadstemc_xfer => cnveg_carbonstate_inst%deadstemc_xfer_patch , & ! Input: [real(r8) (:)] (gC/m2) dead stem C transfer + livecrootc_xfer => cnveg_carbonstate_inst%livecrootc_xfer_patch , & ! Input: [real(r8) (:)] (gC/m2) live coarse root C transfer + deadcrootc_xfer => cnveg_carbonstate_inst%deadcrootc_xfer_patch , & ! Input: [real(r8) (:)] (gC/m2) dead coarse root C transfer + gresp_xfer => cnveg_carbonstate_inst%gresp_xfer_patch , & ! Input: [real(r8) (:)] (gC/m2) growth respiration transfer + + leafn => cnveg_nitrogenstate_inst%leafn_patch , & ! Input: [real(r8) (:)] (gN/m2) leaf N + frootn => cnveg_nitrogenstate_inst%frootn_patch , & ! Input: [real(r8) (:)] (gN/m2) fine root N + livestemn => cnveg_nitrogenstate_inst%livestemn_patch , & ! Input: [real(r8) (:)] (gN/m2) live stem N + deadstemn => cnveg_nitrogenstate_inst%deadstemn_patch , & ! Input: [real(r8) (:)] (gN/m2) dead stem N + livecrootn => cnveg_nitrogenstate_inst%livecrootn_patch , & ! Input: [real(r8) (:)] (gN/m2) live coarse root N + deadcrootn => cnveg_nitrogenstate_inst%deadcrootn_patch , & ! Input: [real(r8) (:)] (gN/m2) dead coarse root N + retransn => cnveg_nitrogenstate_inst%retransn_patch , & ! Input: [real(r8) (:)] (gN/m2) plant pool of retranslocated N + leafn_storage => cnveg_nitrogenstate_inst%leafn_storage_patch , & ! Input: [real(r8) (:)] (gN/m2) leaf N storage + frootn_storage => cnveg_nitrogenstate_inst%frootn_storage_patch , & ! Input: [real(r8) (:)] (gN/m2) fine root N storage + livestemn_storage => cnveg_nitrogenstate_inst%livestemn_storage_patch , & ! Input: [real(r8) (:)] (gN/m2) live stem N storage + deadstemn_storage => cnveg_nitrogenstate_inst%deadstemn_storage_patch , & ! Input: [real(r8) (:)] (gN/m2) dead stem N storage + livecrootn_storage => cnveg_nitrogenstate_inst%livecrootn_storage_patch , & ! Input: [real(r8) (:)] (gN/m2) live coarse root N storage + deadcrootn_storage => cnveg_nitrogenstate_inst%deadcrootn_storage_patch , & ! Input: [real(r8) (:)] (gN/m2) dead coarse root N storage + leafn_xfer => cnveg_nitrogenstate_inst%leafn_xfer_patch , & ! Input: [real(r8) (:)] (gN/m2) leaf N transfer + frootn_xfer => cnveg_nitrogenstate_inst%frootn_xfer_patch , & ! Input: [real(r8) (:)] (gN/m2) fine root N transfer + livestemn_xfer => cnveg_nitrogenstate_inst%livestemn_xfer_patch , & ! Input: [real(r8) (:)] (gN/m2) live stem N transfer + deadstemn_xfer => cnveg_nitrogenstate_inst%deadstemn_xfer_patch , & ! Input: [real(r8) (:)] (gN/m2) dead stem N transfer + livecrootn_xfer => cnveg_nitrogenstate_inst%livecrootn_xfer_patch , & ! Input: [real(r8) (:)] (gN/m2) live coarse root N transfer + deadcrootn_xfer => cnveg_nitrogenstate_inst%deadcrootn_xfer_patch , & ! Input: [real(r8) (:)] (gN/m2) dead coarse root N transfer + + gru_leafc_to_litter => cnveg_carbonflux_inst%gru_leafc_to_litter_patch , & ! Output: [real(r8) (:)] + gru_frootc_to_litter => cnveg_carbonflux_inst%gru_frootc_to_litter_patch , & ! Output: [real(r8) (:)] + gru_livestemc_to_atm => cnveg_carbonflux_inst%gru_livestemc_to_atm_patch , & ! Output: [real(r8) (:)] + gru_deadstemc_to_atm => cnveg_carbonflux_inst%gru_deadstemc_to_atm_patch , & ! Output: [real(r8) (:)] + gru_wood_productc_gain => cnveg_carbonflux_inst%gru_wood_productc_gain_patch , & ! Output: [real(r8) (:)] + gru_livecrootc_to_litter => cnveg_carbonflux_inst%gru_livecrootc_to_litter_patch , & ! Output: [real(r8) (:)] + gru_deadcrootc_to_litter => cnveg_carbonflux_inst%gru_deadcrootc_to_litter_patch , & ! Output: [real(r8) (:)] + gru_xsmrpool_to_atm => cnveg_carbonflux_inst%gru_xsmrpool_to_atm_patch , & ! Output: [real(r8) (:)] + gru_leafc_storage_to_atm => cnveg_carbonflux_inst%gru_leafc_storage_to_atm_patch , & ! Output: [real(r8) (:)] + gru_frootc_storage_to_atm => cnveg_carbonflux_inst%gru_frootc_storage_to_atm_patch , & ! Output: [real(r8) (:)] + gru_livestemc_storage_to_atm => cnveg_carbonflux_inst%gru_livestemc_storage_to_atm_patch , & ! Output: [real(r8) (:)] + gru_deadstemc_storage_to_atm => cnveg_carbonflux_inst%gru_deadstemc_storage_to_atm_patch , & ! Output: [real(r8) (:)] + gru_livecrootc_storage_to_atm => cnveg_carbonflux_inst%gru_livecrootc_storage_to_atm_patch , & ! Output: [real(r8) (:)] + gru_deadcrootc_storage_to_atm => cnveg_carbonflux_inst%gru_deadcrootc_storage_to_atm_patch , & ! Output: [real(r8) (:)] + gru_gresp_storage_to_atm => cnveg_carbonflux_inst%gru_gresp_storage_to_atm_patch , & ! Output: [real(r8) (:)] + gru_leafc_xfer_to_atm => cnveg_carbonflux_inst%gru_leafc_xfer_to_atm_patch , & ! Output: [real(r8) (:)] + gru_frootc_xfer_to_atm => cnveg_carbonflux_inst%gru_frootc_xfer_to_atm_patch , & ! Output: [real(r8) (:)] + gru_livestemc_xfer_to_atm => cnveg_carbonflux_inst%gru_livestemc_xfer_to_atm_patch , & ! Output: [real(r8) (:)] + gru_deadstemc_xfer_to_atm => cnveg_carbonflux_inst%gru_deadstemc_xfer_to_atm_patch , & ! Output: [real(r8) (:)] + gru_livecrootc_xfer_to_atm => cnveg_carbonflux_inst%gru_livecrootc_xfer_to_atm_patch , & ! Output: [real(r8) (:)] + gru_deadcrootc_xfer_to_atm => cnveg_carbonflux_inst%gru_deadcrootc_xfer_to_atm_patch , & ! Output: [real(r8) (:)] + gru_gresp_xfer_to_atm => cnveg_carbonflux_inst%gru_gresp_xfer_to_atm_patch , & ! Output: [real(r8) (:)] + + gru_leafn_to_litter => cnveg_nitrogenflux_inst%gru_leafn_to_litter_patch , & ! Output: [real(r8) (:)] + gru_frootn_to_litter => cnveg_nitrogenflux_inst%gru_frootn_to_litter_patch , & ! Output: [real(r8) (:)] + gru_livestemn_to_atm => cnveg_nitrogenflux_inst%gru_livestemn_to_atm_patch , & ! Output: [real(r8) (:)] + gru_deadstemn_to_atm => cnveg_nitrogenflux_inst%gru_deadstemn_to_atm_patch , & ! Output: [real(r8) (:)] + gru_wood_productn_gain => cnveg_nitrogenflux_inst%gru_wood_productn_gain_patch , & ! Output: [real(r8) (:)] + gru_livecrootn_to_litter => cnveg_nitrogenflux_inst%gru_livecrootn_to_litter_patch , & ! Output: [real(r8) (:)] + gru_deadcrootn_to_litter => cnveg_nitrogenflux_inst%gru_deadcrootn_to_litter_patch , & ! Output: [real(r8) (:)] + gru_retransn_to_litter => cnveg_nitrogenflux_inst%gru_retransn_to_litter_patch , & ! Output: [real(r8) (:)] + gru_leafn_storage_to_atm => cnveg_nitrogenflux_inst%gru_leafn_storage_to_atm_patch , & ! Output: [real(r8) (:)] + gru_frootn_storage_to_atm => cnveg_nitrogenflux_inst%gru_frootn_storage_to_atm_patch , & ! Output: [real(r8) (:)] + gru_livestemn_storage_to_atm => cnveg_nitrogenflux_inst%gru_livestemn_storage_to_atm_patch , & ! Output: [real(r8) (:)] + gru_deadstemn_storage_to_atm => cnveg_nitrogenflux_inst%gru_deadstemn_storage_to_atm_patch , & ! Output: [real(r8) (:)] + gru_livecrootn_storage_to_atm => cnveg_nitrogenflux_inst%gru_livecrootn_storage_to_atm_patch , & ! Output: [real(r8) (:)] + gru_deadcrootn_storage_to_atm => cnveg_nitrogenflux_inst%gru_deadcrootn_storage_to_atm_patch , & ! Output: [real(r8) (:)] + gru_leafn_xfer_to_atm => cnveg_nitrogenflux_inst%gru_leafn_xfer_to_atm_patch , & ! Output: [real(r8) (:)] + gru_frootn_xfer_to_atm => cnveg_nitrogenflux_inst%gru_frootn_xfer_to_atm_patch , & ! Output: [real(r8) (:)] + gru_livestemn_xfer_to_atm => cnveg_nitrogenflux_inst%gru_livestemn_xfer_to_atm_patch , & ! Output: [real(r8) (:)] + gru_deadstemn_xfer_to_atm => cnveg_nitrogenflux_inst%gru_deadstemn_xfer_to_atm_patch , & ! Output: [real(r8) (:)] + gru_livecrootn_xfer_to_atm => cnveg_nitrogenflux_inst%gru_livecrootn_xfer_to_atm_patch , & ! Output: [real(r8) (:)] + gru_deadcrootn_xfer_to_atm => cnveg_nitrogenflux_inst%gru_deadcrootn_xfer_to_atm_patch & ! Output: [real(r8) (:)] + ) + + dtime = get_step_size_real() + + ! patch loop + do fp = 1,num_soilp + p = filter_soilp(fp) + g = patch%gridcell(p) + + ! If this is a natural pft, then + ! get the annual grossunrep "mortality" rate (am) from grossunrep array + ! and convert to rate per second + if (ivt(p) > noveg .and. ivt(p) <= nc4_grass) then + + if (do_grossunrep) then + am = grossunrepfrac(g,ivt(p)) + + ! Apply all grossunrep at the start of the year + if (is_beg_curr_year()) then + m = am/dtime + else + m = 0._r8 + end if + else + m = 0._r8 + end if + + ! patch-level gross unrepresented landcover change carbon fluxes + ! displayed pools + gru_leafc_to_litter(p) = leafc(p) * m + gru_frootc_to_litter(p) = frootc(p) * m + gru_livestemc_to_atm(p) = livestemc(p) * m + gru_deadstemc_to_atm(p) = deadstemc(p) * m * convfrac(ivt(p)) + gru_wood_productc_gain(p) = deadstemc(p) * m * (1._r8 - convfrac(ivt(p))) + gru_livecrootc_to_litter(p) = livecrootc(p) * m + gru_deadcrootc_to_litter(p) = deadcrootc(p) * m + gru_xsmrpool_to_atm(p) = xsmrpool(p) * m + + ! storage pools + gru_leafc_storage_to_atm(p) = leafc_storage(p) * m + gru_frootc_storage_to_atm(p) = frootc_storage(p) * m + gru_livestemc_storage_to_atm(p) = livestemc_storage(p) * m + gru_deadstemc_storage_to_atm(p) = deadstemc_storage(p) * m + gru_livecrootc_storage_to_atm(p) = livecrootc_storage(p) * m + gru_deadcrootc_storage_to_atm(p) = deadcrootc_storage(p) * m + gru_gresp_storage_to_atm(p) = gresp_storage(p) * m + + ! transfer pools + gru_leafc_xfer_to_atm(p) = leafc_xfer(p) * m + gru_frootc_xfer_to_atm(p) = frootc_xfer(p) * m + gru_livestemc_xfer_to_atm(p) = livestemc_xfer(p) * m + gru_deadstemc_xfer_to_atm(p) = deadstemc_xfer(p) * m + gru_livecrootc_xfer_to_atm(p) = livecrootc_xfer(p) * m + gru_deadcrootc_xfer_to_atm(p) = deadcrootc_xfer(p) * m + gru_gresp_xfer_to_atm(p) = gresp_xfer(p) * m + + ! patch-level gross unrepresented landcover change mortality nitrogen fluxes + ! displayed pools + gru_leafn_to_litter(p) = leafn(p) * m + gru_frootn_to_litter(p) = frootn(p) * m + gru_livestemn_to_atm(p) = livestemn(p) * m + gru_deadstemn_to_atm(p) = deadstemn(p) * m * convfrac(ivt(p)) + gru_wood_productn_gain(p) = deadstemn(p) * m * (1._r8 - convfrac(ivt(p))) + gru_livecrootn_to_litter(p) = livecrootn(p) * m + gru_deadcrootn_to_litter(p) = deadcrootn(p) * m + gru_retransn_to_litter(p) = retransn(p) * m + + ! storage pools + gru_leafn_storage_to_atm(p) = leafn_storage(p) * m + gru_frootn_storage_to_atm(p) = frootn_storage(p) * m + gru_livestemn_storage_to_atm(p) = livestemn_storage(p) * m + gru_deadstemn_storage_to_atm(p) = deadstemn_storage(p) * m + gru_livecrootn_storage_to_atm(p) = livecrootn_storage(p) * m + gru_deadcrootn_storage_to_atm(p) = deadcrootn_storage(p) * m + + ! transfer pools + gru_leafn_xfer_to_atm(p) = leafn_xfer(p) * m + gru_frootn_xfer_to_atm(p) = frootn_xfer(p) * m + gru_livestemn_xfer_to_atm(p) = livestemn_xfer(p) * m + gru_deadstemn_xfer_to_atm(p) = deadstemn_xfer(p) * m + gru_livecrootn_xfer_to_atm(p) = livecrootn_xfer(p) * m + gru_deadcrootn_xfer_to_atm(p) = deadcrootn_xfer(p) * m + + end if ! end tree block + + end do ! end of pft loop + + ! gather all patch-level litterfall fluxes from grossunrep to the column + ! for litter C and N inputs + + call CNGrossUnrepPftToColumn(num_soilc, filter_soilc, & + soilbiogeochem_state_inst, cnveg_carbonflux_inst, cnveg_nitrogenflux_inst) + + end associate + + end subroutine CNGrossUnrep + + !----------------------------------------------------------------------- + subroutine CNGrossUnrepPftToColumn (num_soilc, filter_soilc, & + soilbiogeochem_state_inst, CNVeg_carbonflux_inst, cnveg_nitrogenflux_inst) + ! + ! !DESCRIPTION: + ! called at the end of CNGrossUnrep to gather all patch-level grossunrep litterfall fluxes + ! to the column level and assign them to the three litter pools + ! + ! !USES: + use clm_varpar , only : maxpatch_pft, nlevdecomp, numpft + ! + ! !ARGUMENTS: + integer , intent(in) :: num_soilc ! number of soil columns in filter + integer , intent(in) :: filter_soilc(:) ! soil column filter + type(soilbiogeochem_state_type) , intent(in) :: soilbiogeochem_state_inst + type(cnveg_carbonflux_type) , intent(inout) :: cnveg_carbonflux_inst + type(cnveg_nitrogenflux_type) , intent(inout) :: cnveg_nitrogenflux_inst + ! + ! !LOCAL VARIABLES: + integer :: fc,c,pi,p,j ! indices + !----------------------------------------------------------------------- + + associate( & + ivt => patch%itype , & ! Input: [integer (:) ] pft vegetation type + wtcol => patch%wtcol , & ! Input: [real(r8) (:) ] pft weight relative to column (0-1) + + lf_flab => pftcon%lf_flab , & ! Input: leaf litter labile fraction + lf_fcel => pftcon%lf_fcel , & ! Input: leaf litter cellulose fraction + lf_flig => pftcon%lf_flig , & ! Input: leaf litter lignin fraction + fr_flab => pftcon%fr_flab , & ! Input: fine root litter labile fraction + fr_fcel => pftcon%fr_fcel , & ! Input: fine root litter cellulose fraction + fr_flig => pftcon%fr_flig , & ! Input: fine root litter lignin fraction + + leaf_prof => soilbiogeochem_state_inst%leaf_prof_patch , & ! Input: [real(r8) (:,:) ] (1/m) profile of leaves + froot_prof => soilbiogeochem_state_inst%froot_prof_patch , & ! Input: [real(r8) (:,:) ] (1/m) profile of fine roots + croot_prof => soilbiogeochem_state_inst%croot_prof_patch , & ! Input: [real(r8) (:,:) ] (1/m) profile of coarse roots + stem_prof => soilbiogeochem_state_inst%stem_prof_patch , & ! Input: [real(r8) (:,:) ] (1/m) profile of stems + + gru_leafc_to_litter => cnveg_carbonflux_inst%gru_leafc_to_litter_patch , & ! Input: [real(r8) (:)] + gru_frootc_to_litter => cnveg_carbonflux_inst%gru_frootc_to_litter_patch , & ! Input: [real(r8) (:)] + gru_wood_productc_gain => cnveg_carbonflux_inst%gru_wood_productc_gain_patch , & ! Input: [real(r8) (:)] + gru_livecrootc_to_litter => cnveg_carbonflux_inst%gru_livecrootc_to_litter_patch , & ! Input: [real(r8) (:)] + gru_deadcrootc_to_litter => cnveg_carbonflux_inst%gru_deadcrootc_to_litter_patch , & ! Input: [real(r8) (:)] + gru_conv_cflux => cnveg_carbonflux_inst%gru_conv_cflux_patch , & ! Input: [real(r8) (:) ] C fluxes associated with conversion (immediate loss to atm) + + gru_c_to_litr_met_c => cnveg_carbonflux_inst%gru_c_to_litr_met_c_col , & ! Output: [real(r8) (:,:) ] C fluxes associated with grossunrep to litter metabolic pool (gC/m3/s) + gru_c_to_litr_cel_c => cnveg_carbonflux_inst%gru_c_to_litr_cel_c_col , & ! Output: [real(r8) (:,:) ] C fluxes associated with grossunrep to litter cellulose pool (gC/m3/s) + gru_c_to_litr_lig_c => cnveg_carbonflux_inst%gru_c_to_litr_lig_c_col , & ! Output: [real(r8) (:,:) ] C fluxes associated with grossunrep to litter lignin pool (gC/m3/s) + gru_c_to_cwdc_c => cnveg_carbonflux_inst%gru_c_to_cwdc_col , & ! Output: [real(r8) (:,:) ] C fluxes associated with grossunrep to CWD pool (gC/m3/s) + + gru_wood_productc_gain_c => cnveg_carbonflux_inst%gru_wood_productc_gain_col , & ! Input: [real(r8) (:)] + + gru_leafn_to_litter => cnveg_nitrogenflux_inst%gru_leafn_to_litter_patch , & ! Input: [real(r8) (:)] + gru_frootn_to_litter => cnveg_nitrogenflux_inst%gru_frootn_to_litter_patch , & ! Input: [real(r8) (:)] + gru_wood_productn_gain => cnveg_nitrogenflux_inst%gru_wood_productn_gain_patch , & ! Input: [real(r8) (:)] + gru_livecrootn_to_litter => cnveg_nitrogenflux_inst%gru_livecrootn_to_litter_patch , & ! Input: [real(r8) (:)] + gru_deadcrootn_to_litter => cnveg_nitrogenflux_inst%gru_deadcrootn_to_litter_patch , & ! Input: [real(r8) (:)] + gru_retransn_to_litter => cnveg_nitrogenflux_inst%gru_retransn_to_litter_patch , & ! Input: [real(r8) (:)] + gru_conv_nflux => cnveg_nitrogenflux_inst%gru_conv_nflux_patch , & ! Input: [real(r8) (:) ] N fluxes associated with conversion (immediate loss to atm) + + gru_n_to_litr_met_c => cnveg_nitrogenflux_inst%gru_n_to_litr_met_n_col , & ! Output: [real(r8) (:,:) ] N fluxes associated with grossunrep to litter metabolic pool (gN/m3/s) + gru_n_to_litr_cel_c => cnveg_nitrogenflux_inst%gru_n_to_litr_cel_n_col , & ! Output: [real(r8) (:,:) ] N fluxes associated with grossunrep to litter cellulose pool (gN/m3/s) + gru_n_to_litr_lig_c => cnveg_nitrogenflux_inst%gru_n_to_litr_lig_n_col , & ! Output: [real(r8) (:,:) ] N fluxes associated with grossunrep to litter lignin pool (gN/m3/s) + gru_n_to_cwdn_c => cnveg_nitrogenflux_inst%gru_n_to_cwdn_col , & ! Output: [real(r8) (:,:) ] N fluxes associated with grossunrep to CWD pool (gN/m3/s) + + gru_wood_productn_gain_c => cnveg_nitrogenflux_inst%gru_wood_productn_gain_col & ! Input: [real(r8) (:)] + ) + + do j = 1, nlevdecomp + do pi = 1,maxpatch_pft + do fc = 1,num_soilc + c = filter_soilc(fc) + + if (pi <= col%npatches(c)) then + p = col%patchi(c) + pi - 1 + + if (patch%active(p)) then + + ! leaf gross unrepresented landcover change mortality carbon fluxes + gru_c_to_litr_met_c(c,j) = gru_c_to_litr_met_c(c,j) + & + gru_leafc_to_litter(p) * lf_flab(ivt(p)) * wtcol(p) * leaf_prof(p,j) + gru_c_to_litr_cel_c(c,j) = gru_c_to_litr_cel_c(c,j) + & + gru_leafc_to_litter(p) * lf_fcel(ivt(p)) * wtcol(p) * leaf_prof(p,j) + gru_c_to_litr_lig_c(c,j) = gru_c_to_litr_lig_c(c,j) + & + gru_leafc_to_litter(p) * lf_flig(ivt(p)) * wtcol(p) * leaf_prof(p,j) + + ! fine root gross unrepresented landcover change mortality carbon fluxes + gru_c_to_litr_met_c(c,j) = gru_c_to_litr_met_c(c,j) + & + gru_frootc_to_litter(p) * fr_flab(ivt(p)) * wtcol(p) * froot_prof(p,j) + gru_c_to_litr_cel_c(c,j) = gru_c_to_litr_cel_c(c,j) + & + gru_frootc_to_litter(p) * fr_fcel(ivt(p)) * wtcol(p) * froot_prof(p,j) + gru_c_to_litr_lig_c(c,j) = gru_c_to_litr_lig_c(c,j) + & + gru_frootc_to_litter(p) * fr_flig(ivt(p)) * wtcol(p) * froot_prof(p,j) + + ! coarse root gross unrepresented landcover change mortality carbon fluxes + gru_c_to_cwdc_c(c,j) = gru_c_to_cwdc_c(c,j) + & + gru_livecrootc_to_litter(p) * wtcol(p) * croot_prof(p,j) + gru_c_to_cwdc_c(c,j) = gru_c_to_cwdc_c(c,j) + & + gru_deadcrootc_to_litter(p) * wtcol(p) * croot_prof(p,j) + + ! leaf gross unrepresented landcover change mortality nitrogen fluxes + gru_n_to_litr_met_c(c,j) = gru_n_to_litr_met_c(c,j) + & + gru_leafn_to_litter(p) * lf_flab(ivt(p)) * wtcol(p) * leaf_prof(p,j) + gru_n_to_litr_cel_c(c,j) = gru_n_to_litr_cel_c(c,j) + & + gru_leafn_to_litter(p) * lf_fcel(ivt(p)) * wtcol(p) * leaf_prof(p,j) + gru_n_to_litr_lig_c(c,j) = gru_n_to_litr_lig_c(c,j) + & + gru_leafn_to_litter(p) * lf_flig(ivt(p)) * wtcol(p) * leaf_prof(p,j) + + ! fine root unrepresented landcover change mortality nitrogen fluxes + gru_n_to_litr_met_c(c,j) = gru_n_to_litr_met_c(c,j) + & + gru_frootn_to_litter(p) * fr_flab(ivt(p)) * wtcol(p) * froot_prof(p,j) + gru_n_to_litr_cel_c(c,j) = gru_n_to_litr_cel_c(c,j) + & + gru_frootn_to_litter(p) * fr_fcel(ivt(p)) * wtcol(p) * froot_prof(p,j) + gru_n_to_litr_lig_c(c,j) = gru_n_to_litr_lig_c(c,j) + & + gru_frootn_to_litter(p) * fr_flig(ivt(p)) * wtcol(p) * froot_prof(p,j) + + ! coarse root gross unrepresented landcover change mortality nitrogen fluxes + gru_n_to_cwdn_c(c,j) = gru_n_to_cwdn_c(c,j) + & + gru_livecrootn_to_litter(p) * wtcol(p) * croot_prof(p,j) + gru_n_to_cwdn_c(c,j) = gru_n_to_cwdn_c(c,j) + & + gru_deadcrootn_to_litter(p) * wtcol(p) * croot_prof(p,j) + + ! retranslocated N pool gross unrepresented landcover change mortality fluxes + gru_n_to_litr_met_c(c,j) = gru_n_to_litr_met_c(c,j) + & + gru_retransn_to_litter(p) * wtcol(p) * leaf_prof(p,j) + + end if + end if + + end do + + end do + end do + + do pi = 1,maxpatch_pft + do fc = 1,num_soilc + c = filter_soilc(fc) + + if (pi <= col%npatches(c)) then + p = col%patchi(c) + pi - 1 + + if (patch%active(p)) then + ! wood gross unrepresented landcover change mortality carbon fluxes to product pools + gru_wood_productc_gain_c(c) = gru_wood_productc_gain_c(c) + & + gru_wood_productc_gain(p) * wtcol(p) + + ! wood gross unrepresented landcover change mortality nitrogen fluxes to product pools + gru_wood_productn_gain_c(c) = gru_wood_productn_gain_c(c) + & + gru_wood_productn_gain(p) * wtcol(p) + end if + end if + + end do + + end do + + end associate + + end subroutine CNGrossUnrepPftToColumn + +end module dynGrossUnrepMod diff --git a/src/dyn_subgrid/dynSubgridControlMod.F90 b/src/dyn_subgrid/dynSubgridControlMod.F90 index 58e3a40359..3491057dc0 100644 --- a/src/dyn_subgrid/dynSubgridControlMod.F90 +++ b/src/dyn_subgrid/dynSubgridControlMod.F90 @@ -26,6 +26,7 @@ module dynSubgridControlMod public :: get_do_transient_crops ! return the value of the do_transient_crops control flag public :: run_has_transient_landcover ! returns true if any aspects of prescribed transient landcover are enabled public :: get_do_harvest ! return the value of the do_harvest control flag + public :: get_do_grossunrep ! return the value of the do_grossunrep control flag public :: get_for_testing_allow_non_annual_changes ! return true if user has requested to allow area changes at times other than the year boundary, for testing purposes public :: get_for_testing_zero_dynbal_fluxes ! return true if user has requested to set the dynbal water and energy fluxes to zero, for testing purposes ! @@ -40,6 +41,7 @@ module dynSubgridControlMod logical :: do_transient_pfts = .false. ! whether to apply transient natural PFTs from dataset logical :: do_transient_crops = .false. ! whether to apply transient crops from dataset logical :: do_harvest = .false. ! whether to apply harvest from dataset + logical :: do_grossunrep = .false. ! whether to apply gross unrepresented landcover change from dataset ! The following is only meant for testing: Whether area changes are allowed at times ! other than the year boundary. This should only arise in some test configurations @@ -114,6 +116,7 @@ subroutine read_namelist( NLFilename ) logical :: do_transient_pfts logical :: do_transient_crops logical :: do_harvest + logical :: do_grossunrep logical :: for_testing_allow_non_annual_changes logical :: for_testing_zero_dynbal_fluxes ! other local variables: @@ -136,6 +139,7 @@ subroutine read_namelist( NLFilename ) do_transient_pfts = .false. do_transient_crops = .false. do_harvest = .false. + do_grossunrep = .false. for_testing_allow_non_annual_changes = .false. for_testing_zero_dynbal_fluxes = .false. @@ -153,12 +157,14 @@ subroutine read_namelist( NLFilename ) end if close(nu_nml) call relavu( nu_nml ) + do_grossunrep = do_harvest endif call shr_mpi_bcast (flanduse_timeseries, mpicom) call shr_mpi_bcast (do_transient_pfts, mpicom) call shr_mpi_bcast (do_transient_crops, mpicom) call shr_mpi_bcast (do_harvest, mpicom) + call shr_mpi_bcast (do_grossunrep, mpicom) call shr_mpi_bcast (for_testing_allow_non_annual_changes, mpicom) call shr_mpi_bcast (for_testing_zero_dynbal_fluxes, mpicom) @@ -167,6 +173,7 @@ subroutine read_namelist( NLFilename ) do_transient_pfts = do_transient_pfts, & do_transient_crops = do_transient_crops, & do_harvest = do_harvest, & + do_grossunrep = do_grossunrep, & for_testing_allow_non_annual_changes = for_testing_allow_non_annual_changes, & for_testing_zero_dynbal_fluxes = for_testing_zero_dynbal_fluxes) @@ -211,6 +218,11 @@ subroutine check_namelist_consistency write(iulog,*) 'a flanduse_timeseries file (currently flanduse_timeseries is blank)' call endrun(msg=errMsg(sourcefile, __LINE__)) end if + if (dyn_subgrid_control_inst%do_grossunrep) then + write(iulog,*) 'ERROR: do_grossunrep can only be true if you are running with' + write(iulog,*) 'a flanduse_timeseries file (currently flanduse_timeseries is blank)' + call endrun(msg=errMsg(sourcefile, __LINE__)) + end if end if if (dyn_subgrid_control_inst%do_transient_pfts) then @@ -249,6 +261,17 @@ subroutine check_namelist_consistency end if end if + if (dyn_subgrid_control_inst%do_grossunrep) then + if (.not. use_cn) then + write(iulog,*) 'ERROR: do_grossunrep can only be true if use_cn is true' + call endrun(msg=errMsg(sourcefile, __LINE__)) + end if + if (use_fates) then + write(iulog,*) 'ERROR: do_grossunrep currently does not work with use_fates' + call endrun(msg=errMsg(sourcefile, __LINE__)) + end if + end if + end subroutine check_namelist_consistency !----------------------------------------------------------------------- @@ -312,6 +335,18 @@ logical function get_do_harvest() end function get_do_harvest + !----------------------------------------------------------------------- + logical function get_do_grossunrep() + ! !DESCRIPTION: + ! Return the value of the do_grossunrep control flag + !----------------------------------------------------------------------- + + SHR_ASSERT(dyn_subgrid_control_inst%initialized, errMsg(sourcefile, __LINE__)) + + get_do_grossunrep = dyn_subgrid_control_inst%do_grossunrep + + end function get_do_grossunrep + !----------------------------------------------------------------------- logical function get_for_testing_allow_non_annual_changes() ! diff --git a/src/dyn_subgrid/dynSubgridDriverMod.F90 b/src/dyn_subgrid/dynSubgridDriverMod.F90 index 8703fcb2d9..90bbd05abe 100644 --- a/src/dyn_subgrid/dynSubgridDriverMod.F90 +++ b/src/dyn_subgrid/dynSubgridDriverMod.F90 @@ -14,12 +14,14 @@ module dynSubgridDriverMod use dynSubgridControlMod , only : get_flanduse_timeseries use dynSubgridControlMod , only : get_do_transient_pfts, get_do_transient_crops use dynSubgridControlMod , only : get_do_harvest + use dynSubgridControlMod , only : get_do_grossunrep use dynPriorWeightsMod , only : prior_weights_type use dynPatchStateUpdaterMod , only : patch_state_updater_type use dynColumnStateUpdaterMod , only : column_state_updater_type use dynpftFileMod , only : dynpft_init, dynpft_interp use dyncropFileMod , only : dyncrop_init, dyncrop_interp use dynHarvestMod , only : dynHarvest_init, dynHarvest_interp + use dynGrossUnrepMod , only : dynGrossUnrep_init, dynGrossUnrep_interp use dynLandunitAreaMod , only : update_landunit_weights use subgridWeightsMod , only : compute_higher_order_weights, set_subgrid_diagnostic_fields use reweightMod , only : reweight_wrapup @@ -121,6 +123,11 @@ subroutine dynSubgrid_init(bounds_proc, glc_behavior, crop_inst) call dynHarvest_init(bounds_proc, harvest_filename=get_flanduse_timeseries()) end if + ! Initialize stuff for gross unrepresented landuse data. + if (get_do_grossunrep()) then + call dynGrossUnrep_init(bounds_proc, grossunrep_filename=get_flanduse_timeseries()) + end if + ! ------------------------------------------------------------------------ ! Set initial subgrid weights for aspects that are read from file. This is relevant ! for cold start and use_init_interp-based initialization. @@ -248,6 +255,10 @@ subroutine dynSubgrid_driver(bounds_proc, call dynHarvest_interp(bounds_proc) end if + if (get_do_grossunrep()) then + call dynGrossUnrep_interp(bounds_proc) + end if + ! ========================================================================== ! Do land cover change that does not require I/O ! ========================================================================== diff --git a/src/soilbiogeochem/SoilBiogeochemCarbonStateType.F90 b/src/soilbiogeochem/SoilBiogeochemCarbonStateType.F90 index 78be5efd44..62683d4256 100644 --- a/src/soilbiogeochem/SoilBiogeochemCarbonStateType.F90 +++ b/src/soilbiogeochem/SoilBiogeochemCarbonStateType.F90 @@ -38,7 +38,7 @@ module SoilBiogeochemCarbonStateType real(r8), pointer :: decomp_cpools_col (:,:) ! (gC/m2) decomposing (litter, cwd, soil) c pools real(r8), pointer :: dyn_cbal_adjustments_col (:) ! (gC/m2) adjustments to each column made in this timestep via dynamic column area adjustments (note: this variable only makes sense at the column-level: it is meaningless if averaged to the gridcell-level) integer :: restart_file_spinup_state ! spinup state as read from restart file, for determining whether to enter or exit spinup mode. - real(r8) :: totvegcthresh ! threshold for total vegetation carbon to zero out decomposition pools + real(r8) :: ccrit ! critical carbon value contains @@ -46,7 +46,7 @@ module SoilBiogeochemCarbonStateType procedure , public :: SetValues procedure , public :: Restart procedure , public :: Summary - procedure , public :: SetTotVgCThresh + procedure , public :: SetCCrit procedure , public :: DynamicColumnAdjustments ! adjust state variables when column areas change procedure , private :: InitAllocate procedure , private :: InitHistory @@ -70,7 +70,7 @@ subroutine Init(this, bounds, carbon_type, ratio, c12_soilbiogeochem_carbonstate real(r8) , intent(in) :: ratio type(soilbiogeochem_carbonstate_type) , intent(in), optional :: c12_soilbiogeochem_carbonstate_inst - this%totvegcthresh = nan + this%ccrit = nan call this%InitAllocate ( bounds) call this%InitHistory ( bounds, carbon_type ) if (present(c12_soilbiogeochem_carbonstate_inst)) then @@ -674,10 +674,6 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, totvegc_col, c12_so call endrun(msg=' CNRest: error in entering/exiting spinup - should occur only when nstep = 1'//& errMsg(sourcefile, __LINE__)) endif - if ( exit_spinup .and. isnan(this%totvegcthresh) )then - call endrun(msg=' CNRest: error in exit spinup - totvegcthresh was not set with SetTotVgCThresh'//& - errMsg(sourcefile, __LINE__)) - end if do k = 1, ndecomp_pools if ( exit_spinup ) then m = decomp_cascade_con%spinup_factor(k) @@ -694,7 +690,10 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, totvegc_col, c12_so ! reset decomp pools to near zero during exit_spinup to avoid very ! large and inert soil carbon stocks; note that only pools with spinup factor > 1 ! will be affected, which means that total SOMC and LITC pools will not be set to 0. - if (totvegc_col(c) <= this%totvegcthresh .and. lun%itype(l) /= istcrop) then +!KO if (totvegc_col(c) <= this%ccrit .and. lun%itype(l) /= istcrop) then +!KO + if (totvegc_col(c) <= 0.1_r8 .and. lun%itype(l) /= istcrop) then +!KO this%decomp_cpools_vr_col(c,j,k) = 0.0_r8 endif elseif ( abs(m - 1._r8) .gt. 0.000001_r8 .and. enter_spinup) then @@ -927,18 +926,14 @@ subroutine Summary(this, bounds, num_allc, filter_allc) end subroutine Summary !------------------------------------------------------------------------ - subroutine SetTotVgCThresh(this, totvegcthresh) + subroutine SetCCrit(this, ccrit) class(soilbiogeochem_carbonstate_type) :: this - real(r8) , intent(in) :: totvegcthresh + real(r8) , intent(in) :: ccrit - if ( totvegcthresh <= 0.0_r8 )then - call endrun(msg=' ERROR totvegcthresh is zero or negative and should be > 0'//& - errMsg(sourcefile, __LINE__)) - end if - this%totvegcthresh = totvegcthresh + this%ccrit = ccrit - end subroutine SetTotVgCThresh + end subroutine SetCCrit !----------------------------------------------------------------------- diff --git a/src/soilbiogeochem/SoilBiogeochemNitrogenStateType.F90 b/src/soilbiogeochem/SoilBiogeochemNitrogenStateType.F90 index ca09e63624..b776f77731 100644 --- a/src/soilbiogeochem/SoilBiogeochemNitrogenStateType.F90 +++ b/src/soilbiogeochem/SoilBiogeochemNitrogenStateType.F90 @@ -52,7 +52,7 @@ module SoilBiogeochemNitrogenStateType ! the N balance check real(r8), pointer :: dyn_no3bal_adjustments_col (:) ! (gN/m2) NO3 adjustments to each column made in this timestep via dynamic column area adjustments (only makes sense at the column-level: meaningless if averaged to the gridcell-level) real(r8), pointer :: dyn_nh4bal_adjustments_col (:) ! (gN/m2) NH4 adjustments to each column made in this timestep via dynamic column adjustments (only makes sense at the column-level: meaningless if averaged to the gridcell-level) - real(r8) :: totvegcthresh ! threshold for total vegetation carbon to zero out decomposition pools + real(r8) :: ncrit ! (gN/m2) critical value of nitrogen before truncation contains @@ -61,7 +61,7 @@ module SoilBiogeochemNitrogenStateType procedure , public :: SetValues procedure , public :: Summary procedure , public :: DynamicColumnAdjustments ! adjust state variables when column areas change - procedure , public :: SetTotVgCThresh ! Set value for totvegcthresh needed in Restart + procedure , public :: SetNCrit procedure , private :: InitAllocate procedure , private :: InitHistory procedure , private :: InitCold @@ -84,7 +84,7 @@ subroutine Init(this, bounds, & real(r8) , intent(in) :: decomp_cpools_col (bounds%begc:, 1:) real(r8) , intent(in) :: decomp_cpools_1m_col (bounds%begc:, 1:) - this%totvegcthresh = nan + this%ncrit = nan call this%InitAllocate (bounds ) call this%InitHistory (bounds) @@ -610,10 +610,6 @@ subroutine Restart ( this, bounds, ncid, flag, totvegc_col ) call endrun(msg=' Error in entering/exiting spinup - should occur only when nstep = 1'//& errMsg(sourcefile, __LINE__)) endif - if ( exit_spinup .and. isnan(this%totvegcthresh) )then - call endrun(msg=' Error in exit spinup - totvegcthresh was not set with SetTotVgCThresh'//& - errMsg(sourcefile, __LINE__)) - end if do k = 1, ndecomp_pools if ( exit_spinup ) then m = decomp_cascade_con%spinup_factor(k) @@ -635,7 +631,10 @@ subroutine Restart ( this, bounds, ncid, flag, totvegc_col ) ! pools with spinup factor > 1 ! will be affected, which means that total SOMN and LITN ! pools will not be set to 0. - if (totvegc_col(c) <= this%totvegcthresh .and. lun%itype(l) /= istcrop) then +!KO if (totvegc_col(c) <= this%ncrit .and. lun%itype(l) /= istcrop) then +!KO + if (totvegc_col(c) <= 0.1_r8 .and. lun%itype(l) /= istcrop) then +!KO this%decomp_npools_vr_col(c,j,k) = 0._r8 endif elseif ( abs(m - 1._r8) .gt. 0.000001_r8 .and. enter_spinup) then @@ -1007,17 +1006,13 @@ subroutine DynamicColumnAdjustments(this, bounds, clump_index, column_state_upda end subroutine DynamicColumnAdjustments !------------------------------------------------------------------------ - subroutine SetTotVgCThresh(this, totvegcthresh) + subroutine SetNCrit(this, ncrit) class(soilbiogeochem_nitrogenstate_type) :: this - real(r8) , intent(in) :: totvegcthresh + real(r8) , intent(in) :: ncrit - if ( totvegcthresh <= 0.0_r8 )then - call endrun(msg=' Error totvegcthresh is zero or negative and should be > 0'//& - errMsg(sourcefile, __LINE__)) - end if - this%totvegcthresh = totvegcthresh + this%ncrit = ncrit - end subroutine SetTotVgCThresh + end subroutine SetNCrit end module SoilBiogeochemNitrogenStateType From 30aac3ebd04e4c0e571bcadc1e2ffd6b5aa344ba Mon Sep 17 00:00:00 2001 From: Peter Lawrence Date: Mon, 5 Mar 2018 14:54:46 -0700 Subject: [PATCH 02/27] Removed soil biogeochem files that were not part of the shifting cultivation. These files were actually changes in r267 for Keith's simulations. By including the updated files this resulted in a build error. --- .../SoilBiogeochemCarbonStateType.F90 | 27 +++++++++++-------- .../SoilBiogeochemNitrogenStateType.F90 | 27 +++++++++++-------- 2 files changed, 32 insertions(+), 22 deletions(-) diff --git a/src/soilbiogeochem/SoilBiogeochemCarbonStateType.F90 b/src/soilbiogeochem/SoilBiogeochemCarbonStateType.F90 index 62683d4256..78be5efd44 100644 --- a/src/soilbiogeochem/SoilBiogeochemCarbonStateType.F90 +++ b/src/soilbiogeochem/SoilBiogeochemCarbonStateType.F90 @@ -38,7 +38,7 @@ module SoilBiogeochemCarbonStateType real(r8), pointer :: decomp_cpools_col (:,:) ! (gC/m2) decomposing (litter, cwd, soil) c pools real(r8), pointer :: dyn_cbal_adjustments_col (:) ! (gC/m2) adjustments to each column made in this timestep via dynamic column area adjustments (note: this variable only makes sense at the column-level: it is meaningless if averaged to the gridcell-level) integer :: restart_file_spinup_state ! spinup state as read from restart file, for determining whether to enter or exit spinup mode. - real(r8) :: ccrit ! critical carbon value + real(r8) :: totvegcthresh ! threshold for total vegetation carbon to zero out decomposition pools contains @@ -46,7 +46,7 @@ module SoilBiogeochemCarbonStateType procedure , public :: SetValues procedure , public :: Restart procedure , public :: Summary - procedure , public :: SetCCrit + procedure , public :: SetTotVgCThresh procedure , public :: DynamicColumnAdjustments ! adjust state variables when column areas change procedure , private :: InitAllocate procedure , private :: InitHistory @@ -70,7 +70,7 @@ subroutine Init(this, bounds, carbon_type, ratio, c12_soilbiogeochem_carbonstate real(r8) , intent(in) :: ratio type(soilbiogeochem_carbonstate_type) , intent(in), optional :: c12_soilbiogeochem_carbonstate_inst - this%ccrit = nan + this%totvegcthresh = nan call this%InitAllocate ( bounds) call this%InitHistory ( bounds, carbon_type ) if (present(c12_soilbiogeochem_carbonstate_inst)) then @@ -674,6 +674,10 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, totvegc_col, c12_so call endrun(msg=' CNRest: error in entering/exiting spinup - should occur only when nstep = 1'//& errMsg(sourcefile, __LINE__)) endif + if ( exit_spinup .and. isnan(this%totvegcthresh) )then + call endrun(msg=' CNRest: error in exit spinup - totvegcthresh was not set with SetTotVgCThresh'//& + errMsg(sourcefile, __LINE__)) + end if do k = 1, ndecomp_pools if ( exit_spinup ) then m = decomp_cascade_con%spinup_factor(k) @@ -690,10 +694,7 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, totvegc_col, c12_so ! reset decomp pools to near zero during exit_spinup to avoid very ! large and inert soil carbon stocks; note that only pools with spinup factor > 1 ! will be affected, which means that total SOMC and LITC pools will not be set to 0. -!KO if (totvegc_col(c) <= this%ccrit .and. lun%itype(l) /= istcrop) then -!KO - if (totvegc_col(c) <= 0.1_r8 .and. lun%itype(l) /= istcrop) then -!KO + if (totvegc_col(c) <= this%totvegcthresh .and. lun%itype(l) /= istcrop) then this%decomp_cpools_vr_col(c,j,k) = 0.0_r8 endif elseif ( abs(m - 1._r8) .gt. 0.000001_r8 .and. enter_spinup) then @@ -926,14 +927,18 @@ subroutine Summary(this, bounds, num_allc, filter_allc) end subroutine Summary !------------------------------------------------------------------------ - subroutine SetCCrit(this, ccrit) + subroutine SetTotVgCThresh(this, totvegcthresh) class(soilbiogeochem_carbonstate_type) :: this - real(r8) , intent(in) :: ccrit + real(r8) , intent(in) :: totvegcthresh - this%ccrit = ccrit + if ( totvegcthresh <= 0.0_r8 )then + call endrun(msg=' ERROR totvegcthresh is zero or negative and should be > 0'//& + errMsg(sourcefile, __LINE__)) + end if + this%totvegcthresh = totvegcthresh - end subroutine SetCCrit + end subroutine SetTotVgCThresh !----------------------------------------------------------------------- diff --git a/src/soilbiogeochem/SoilBiogeochemNitrogenStateType.F90 b/src/soilbiogeochem/SoilBiogeochemNitrogenStateType.F90 index b776f77731..ca09e63624 100644 --- a/src/soilbiogeochem/SoilBiogeochemNitrogenStateType.F90 +++ b/src/soilbiogeochem/SoilBiogeochemNitrogenStateType.F90 @@ -52,7 +52,7 @@ module SoilBiogeochemNitrogenStateType ! the N balance check real(r8), pointer :: dyn_no3bal_adjustments_col (:) ! (gN/m2) NO3 adjustments to each column made in this timestep via dynamic column area adjustments (only makes sense at the column-level: meaningless if averaged to the gridcell-level) real(r8), pointer :: dyn_nh4bal_adjustments_col (:) ! (gN/m2) NH4 adjustments to each column made in this timestep via dynamic column adjustments (only makes sense at the column-level: meaningless if averaged to the gridcell-level) - real(r8) :: ncrit ! (gN/m2) critical value of nitrogen before truncation + real(r8) :: totvegcthresh ! threshold for total vegetation carbon to zero out decomposition pools contains @@ -61,7 +61,7 @@ module SoilBiogeochemNitrogenStateType procedure , public :: SetValues procedure , public :: Summary procedure , public :: DynamicColumnAdjustments ! adjust state variables when column areas change - procedure , public :: SetNCrit + procedure , public :: SetTotVgCThresh ! Set value for totvegcthresh needed in Restart procedure , private :: InitAllocate procedure , private :: InitHistory procedure , private :: InitCold @@ -84,7 +84,7 @@ subroutine Init(this, bounds, & real(r8) , intent(in) :: decomp_cpools_col (bounds%begc:, 1:) real(r8) , intent(in) :: decomp_cpools_1m_col (bounds%begc:, 1:) - this%ncrit = nan + this%totvegcthresh = nan call this%InitAllocate (bounds ) call this%InitHistory (bounds) @@ -610,6 +610,10 @@ subroutine Restart ( this, bounds, ncid, flag, totvegc_col ) call endrun(msg=' Error in entering/exiting spinup - should occur only when nstep = 1'//& errMsg(sourcefile, __LINE__)) endif + if ( exit_spinup .and. isnan(this%totvegcthresh) )then + call endrun(msg=' Error in exit spinup - totvegcthresh was not set with SetTotVgCThresh'//& + errMsg(sourcefile, __LINE__)) + end if do k = 1, ndecomp_pools if ( exit_spinup ) then m = decomp_cascade_con%spinup_factor(k) @@ -631,10 +635,7 @@ subroutine Restart ( this, bounds, ncid, flag, totvegc_col ) ! pools with spinup factor > 1 ! will be affected, which means that total SOMN and LITN ! pools will not be set to 0. -!KO if (totvegc_col(c) <= this%ncrit .and. lun%itype(l) /= istcrop) then -!KO - if (totvegc_col(c) <= 0.1_r8 .and. lun%itype(l) /= istcrop) then -!KO + if (totvegc_col(c) <= this%totvegcthresh .and. lun%itype(l) /= istcrop) then this%decomp_npools_vr_col(c,j,k) = 0._r8 endif elseif ( abs(m - 1._r8) .gt. 0.000001_r8 .and. enter_spinup) then @@ -1006,13 +1007,17 @@ subroutine DynamicColumnAdjustments(this, bounds, clump_index, column_state_upda end subroutine DynamicColumnAdjustments !------------------------------------------------------------------------ - subroutine SetNCrit(this, ncrit) + subroutine SetTotVgCThresh(this, totvegcthresh) class(soilbiogeochem_nitrogenstate_type) :: this - real(r8) , intent(in) :: ncrit + real(r8) , intent(in) :: totvegcthresh - this%ncrit = ncrit + if ( totvegcthresh <= 0.0_r8 )then + call endrun(msg=' Error totvegcthresh is zero or negative and should be > 0'//& + errMsg(sourcefile, __LINE__)) + end if + this%totvegcthresh = totvegcthresh - end subroutine SetNCrit + end subroutine SetTotVgCThresh end module SoilBiogeochemNitrogenStateType From ac4d0d4cfcde04003511f2ea8901e2158ccf5454 Mon Sep 17 00:00:00 2001 From: Peter Lawrence Date: Mon, 2 Apr 2018 15:57:40 -0600 Subject: [PATCH 03/27] Update these two files to address Fail status in CLM5 testing. CLM tests all pass now with the note that the new code changes the DWT_SLASH_CFLUX history variable from the column to the grid cell to be consistent with the other DWT fluxes. An additional variable DWT_SLASH_CFLUX_PATCH has been added to allow subgrid calculation at the patch and column levels as done with other DWT fluxes. This change results in a failure in the ERS_Ly3.f10_f10.I1850Clm50BgcCrop test that requires the user_nl_clm file to specify the hist_fincl3 to use DWT_SLASH_CFLUX_PATCH rather than DWT_SLASH_CFLUX. After this change the test passes. . The result from the test suite are: ================================================================================ These tests failed ================================================================================ ERP_D_Lm9.f10_f10_musgs.IHistClm50BgcCrop.cheyenne_intel.clm-ciso_monthly EXPECTED ERS_Ly5_P72x1.f10_f10_musgs.IHistClm45BgcCrop.cheyenne_intel.clm-cropMonthOutput EXPECTED NCK_Ld1.f10_f10_musgs.I2000Clm50Sp.cheyenne_intel.clm-default EXPECTED SMS_D_Ld5.f45_f45_mg37.I2000Clm50Fates.cheyenne_intel.clm-Fates EXPECTED SMS_D_Lm13.f10_f10_musgs.IHistClm50BgcCrop.cheyenne_intel.clm-ciso_monthly EXPECTED SMS_D_Lm6.f45_f45_mg37.I2000Clm50Fates.cheyenne_intel.clm-Fates EXPECTED SMS_D_Lm6_P144x1.f45_f45_mg37.I2000Clm50Fates.cheyenne_intel.clm-Fates EXPECTED SMS_Ld1.f09_g16.I1850Clm40SpCruGs.cheyenne_intel.clm-40default EXPECTED --- src/biogeochem/CNVegNitrogenFluxType.F90 | 2 +- src/biogeochem/dynGrossUnrepMod.F90 | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/biogeochem/CNVegNitrogenFluxType.F90 b/src/biogeochem/CNVegNitrogenFluxType.F90 index 1bb3e223f9..64930e6c7c 100644 --- a/src/biogeochem/CNVegNitrogenFluxType.F90 +++ b/src/biogeochem/CNVegNitrogenFluxType.F90 @@ -488,7 +488,7 @@ subroutine InitAllocate(this, bounds) allocate(this%gru_livestemn_to_atm_patch (begp:endp)) ; this%gru_livestemn_to_atm_patch (:) = nan allocate(this%gru_livestemn_storage_to_atm_patch (begp:endp)) ; this%gru_livestemn_storage_to_atm_patch (:) = nan allocate(this%gru_livestemn_xfer_to_atm_patch (begp:endp)) ; this%gru_livestemn_xfer_to_atm_patch (:) = nan - allocate(this%gru_deadstemn_to_atm_patch (begp:endp)) ; this%gru_deadstemn_storage_to_atm_patch (:) = nan + allocate(this%gru_deadstemn_to_atm_patch (begp:endp)) ; this%gru_deadstemn_to_atm_patch (:) = nan allocate(this%gru_deadstemn_storage_to_atm_patch (begp:endp)) ; this%gru_deadstemn_storage_to_atm_patch (:) = nan allocate(this%gru_deadstemn_xfer_to_atm_patch (begp:endp)) ; this%gru_deadstemn_xfer_to_atm_patch (:) = nan allocate(this%gru_livecrootn_storage_to_atm_patch (begp:endp)) ; this%gru_livecrootn_storage_to_atm_patch (:) = nan diff --git a/src/biogeochem/dynGrossUnrepMod.F90 b/src/biogeochem/dynGrossUnrepMod.F90 index 15d5db95a6..0774a3a1a5 100644 --- a/src/biogeochem/dynGrossUnrepMod.F90 +++ b/src/biogeochem/dynGrossUnrepMod.F90 @@ -95,7 +95,8 @@ subroutine dynGrossUnrep_init(bounds, grossunrep_filename) gru_inst = dyn_var_time_uninterp_type( & dyn_file=dyngrossunrep_file, varname=grossunrep_varname, & dim1name=grlnd, conversion_factor=1.0_r8, & - do_check_sums_equal_1=.false., data_shape=[num_points,natpft_size]) + do_check_sums_equal_1=.false., data_shape=[num_points,natpft_size], & + allow_nodata=.true.) end subroutine dynGrossUnrep_init From ffc742eefaf10e516217117ebe90ecbcde4468af Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 4 Apr 2018 12:27:45 -0600 Subject: [PATCH 04/27] Switch DWT_SLASH_CFLUX for DWT_SLASH_CFLUX_PATCH as required in this branch for shifting cultivation --- cime_config/usermods_dirs/cmip6_output/user_nl_clm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cime_config/usermods_dirs/cmip6_output/user_nl_clm b/cime_config/usermods_dirs/cmip6_output/user_nl_clm index bd333a213b..88a9399a31 100644 --- a/cime_config/usermods_dirs/cmip6_output/user_nl_clm +++ b/cime_config/usermods_dirs/cmip6_output/user_nl_clm @@ -31,7 +31,7 @@ hist_fincl2 = 'GPP', 'NPP', 'AGNPP', 'TLAI', 'TOTVEGC', 'TSA','TREFMNAV','TREFMX hist_fincl3 = 'FSR', 'H2OSNO', 'Q2M', 'SNOWDP', 'TSA', 'TREFMNAV', 'TREFMXAV', 'TG', 'QRUNOFF', 'FSH', 'FIRE', 'FIRA', 'FGR', 'EFLX_LH_TOT', 'RH2M', 'TLAI', 'GPP', 'NPP', 'SOILWATER_10CM', 'TOTSOILLIQ', 'TOTSOILICE', 'AR', 'HR', 'DWT_CONV_CFLUX_PATCH', 'WOOD_HARVESTC', 'U10', 'DWT_WOOD_PRODUCTC_GAIN_PATCH', 'GRAINC_TO_FOOD', 'SLASH_HARVESTC', 'TSOI_10CM', 'COL_FIRE_CLOSS', -'DWT_SLASH_CFLUX','TOTSOMC:I', 'TOTSOMC_1m:I', 'TOTECOSYSC:I', 'TOTVEGC:I', 'WOODC:I', 'TOTLITC:I', 'LIVECROOTC:I', 'DEADCROOTC:I', +'DWT_SLASH_CFLUX_PATCH','TOTSOMC:I', 'TOTSOMC_1m:I', 'TOTECOSYSC:I', 'TOTVEGC:I', 'WOODC:I', 'TOTLITC:I', 'LIVECROOTC:I', 'DEADCROOTC:I', 'FROOTC:I' hist_fincl4 = 'PCT_CFT', 'PCT_GLC_MEC', 'SOIL1C_vr', 'SOIL1N_vr', 'SOIL2C_vr', 'SOIL2N_vr', 'SOIL3C_vr', 'SOIL3N_vr', 'CWDC_vr', From ee439c181d74130aefb9d08b432d3db61cb370dd Mon Sep 17 00:00:00 2001 From: Peter Lawrence Date: Sat, 22 Sep 2018 08:36:58 -0600 Subject: [PATCH 05/27] New changes to set up the namelist variable do_grossunrep. By default do_grossunrep is set to .false. When set to .true. do_grossunrep turns on shifting cultivation which is read off the landuse_timeseries file. --- bld/CLMBuildNamelist.pm | 60 +++++++++++++++++++ .../namelist_definition_clm4_5.xml | 7 +++ src/dyn_subgrid/dynSubgridControlMod.F90 | 2 +- 3 files changed, 68 insertions(+), 1 deletion(-) diff --git a/bld/CLMBuildNamelist.pm b/bld/CLMBuildNamelist.pm index 3595ec7461..58389e83e4 100755 --- a/bld/CLMBuildNamelist.pm +++ b/bld/CLMBuildNamelist.pm @@ -2473,6 +2473,7 @@ sub setup_logic_dynamic_subgrid { setup_logic_do_transient_pfts($opts, $nl_flags, $definition, $defaults, $nl, $physv); setup_logic_do_transient_crops($opts, $nl_flags, $definition, $defaults, $nl, $physv); setup_logic_do_harvest($opts, $nl_flags, $definition, $defaults, $nl, $physv); + setup_logic_do_grossunrep($opts, $nl_flags, $definition, $defaults, $nl, $physv); } @@ -2657,6 +2658,65 @@ sub setup_logic_do_harvest { #------------------------------------------------------------------------------- +sub setup_logic_do_grossunrep { + # + # Set do_grossunrep default value, and perform error checking on do_grossunrep + # + # Assumes the following are already set in the namelist (although it's okay + # for them to be unset if that will be their final state): + # - flanduse_timeseries + # - use_cn + # - use_fates + # + my ($opts, $nl_flags, $definition, $defaults, $nl, $physv) = @_; + + my $var = 'do_grossunrep'; + + if ($physv->as_long() >= $physv->as_long("clm4_5")) { + # Start by assuming a default value of '.true.'. Then check a number of + # conditions under which do_grossunrep cannot be true. Under these + # conditions: (1) set default value to '.false.'; (2) make sure that the + # value is indeed false (e.g., that the user didn't try to set it to true). + + my $default_val = ".false."; + + # cannot_be_true will be set to a non-empty string in any case where + # do_grossunrep should not be true; if it turns out that do_grossunrep IS true + # in any of these cases, a fatal error will be generated + my $cannot_be_true = ""; + + if (string_is_undef_or_empty($nl->get_value('flanduse_timeseries'))) { + $cannot_be_true = "$var can only be set to true when running a transient case (flanduse_timeseries non-blank)"; + } + elsif (!&value_is_true($nl->get_value('use_cn'))) { + $cannot_be_true = "$var can only be set to true when running with CN (use_cn = true)"; + } + elsif (&value_is_true($nl->get_value('use_fates'))) { + $cannot_be_true = "$var currently doesn't work with ED"; + } + + if ($cannot_be_true) { + $default_val = ".false."; + } + + if (!$cannot_be_true) { + # Note that, if the variable cannot be true, we don't call add_default + # - so that we don't clutter up the namelist with variables that don't + # matter for this case + add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $var, val=>$default_val); + } + + # Make sure the value is false when it needs to be false - i.e., that the + # user hasn't tried to set a true value at an inappropriate time. + + if (&value_is_true($nl->get_value($var)) && $cannot_be_true) { + $log->fatal_error($cannot_be_true); + } + + } +} + +#------------------------------------------------------------------------------- sub setup_logic_spinup { my ($opts, $nl_flags, $definition, $defaults, $nl, $physv) = @_; diff --git a/bld/namelist_files/namelist_definition_clm4_5.xml b/bld/namelist_files/namelist_definition_clm4_5.xml index 0a4bbd9a28..db030cd2a8 100644 --- a/bld/namelist_files/namelist_definition_clm4_5.xml +++ b/bld/namelist_files/namelist_definition_clm4_5.xml @@ -2225,6 +2225,13 @@ If TRUE, apply harvest from flanduse_timeseries file. (Also, only valid for use_cn = true.) + +If TRUE, apply grossunrep from flanduse_timeseries file. +(Only valid for transient runs, where there is a flanduse_timeseries file.) +(Also, only valid for use_cn = true.) + + If TRUE, allow area changes at times other than the year boundary. This should diff --git a/src/dyn_subgrid/dynSubgridControlMod.F90 b/src/dyn_subgrid/dynSubgridControlMod.F90 index 3491057dc0..ca057e9202 100644 --- a/src/dyn_subgrid/dynSubgridControlMod.F90 +++ b/src/dyn_subgrid/dynSubgridControlMod.F90 @@ -131,6 +131,7 @@ subroutine read_namelist( NLFilename ) do_transient_pfts, & do_transient_crops, & do_harvest, & + do_grossunrep, & for_testing_allow_non_annual_changes, & for_testing_zero_dynbal_fluxes @@ -157,7 +158,6 @@ subroutine read_namelist( NLFilename ) end if close(nu_nml) call relavu( nu_nml ) - do_grossunrep = do_harvest endif call shr_mpi_bcast (flanduse_timeseries, mpicom) From 9532135c3ddc51c5462f6cda4be4dab16b4f3205 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 6 Aug 2019 15:54:13 -0600 Subject: [PATCH 06/27] Change notes about ED to FATES, and add a test for do_grossunrep=T with transient, but SP instead of CN --- bld/CLMBuildNamelist.pm | 12 ++++++------ bld/unit_testers/build-namelist_test.pl | 7 ++++++- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/bld/CLMBuildNamelist.pm b/bld/CLMBuildNamelist.pm index 74ca2c8910..f34aff7993 100755 --- a/bld/CLMBuildNamelist.pm +++ b/bld/CLMBuildNamelist.pm @@ -734,7 +734,7 @@ sub setup_cmdl_fates_mode { $var = "use_fates"; if ( &value_is_true($nl_flags->{$var}) ) { - # This section is a place-holder to test for modules that are not allowed with ED + # This section is a place-holder to test for modules that are not allowed with FATES # the defaults which are set in the logic section of the namelist builder will # automatically set these correctly (well that is the assumption), but here we # want to set a catch to fail and warn users if they explicitly set incompatible user namelist @@ -1138,7 +1138,7 @@ sub setup_cmdl_spinup { $log->fatal_error("$var has an invalid value ($val). Valid values are: @valid_values"); } if ( $nl_flags->{'bgc_spinup'} eq "on" && (not &value_is_true( $nl_flags->{'use_cn'} )) && (not &value_is_true($nl_flags->{'use_fates'})) ) { - $log->fatal_error("$var can not be '$nl_flags->{'bgc_spinup'}' if neither CN nor ED is turned on (use_cn=$nl_flags->{'use_cn'}, use_fates=$nl_flags->{'use_fates'})."); + $log->fatal_error("$var can not be '$nl_flags->{'bgc_spinup'}' if neither CN nor FATES is turned on (use_cn=$nl_flags->{'use_cn'}, use_fates=$nl_flags->{'use_fates'})."); } if ( $nl->get_value("spinup_state") eq 0 && $nl_flags->{'bgc_spinup'} eq "on" ) { $log->fatal_error("Namelist spinup_state contradicts the command line option bgc_spinup" ); @@ -2488,7 +2488,7 @@ sub setup_logic_do_transient_crops { # In principle, use_fates should be compatible with # do_transient_crops. However, this hasn't been tested, so to be safe, # we are not allowing this combination for now. - $cannot_be_true = "$var has not been tested with ED, so for now these two options cannot be combined"; + $cannot_be_true = "$var has not been tested with FATES, so for now these two options cannot be combined"; } if ($cannot_be_true) { @@ -2559,7 +2559,7 @@ sub setup_logic_do_harvest { } elsif (!&value_is_true($nl->get_value('use_cn'))) { $cannot_be_true = "$var can only be set to true when running with CN (use_cn = true)"; } elsif (&value_is_true($nl->get_value('use_fates'))) { - $cannot_be_true = "$var currently doesn't work with ED"; + $cannot_be_true = "$var currently doesn't work with FATES"; } if ($cannot_be_true) { @@ -2616,7 +2616,7 @@ sub setup_logic_do_grossunrep { $cannot_be_true = "$var can only be set to true when running with CN (use_cn = true)"; } elsif (&value_is_true($nl->get_value('use_fates'))) { - $cannot_be_true = "$var currently doesn't work with ED"; + $cannot_be_true = "$var currently doesn't work with FATES"; } if ($cannot_be_true) { @@ -3419,7 +3419,7 @@ sub setup_logic_megan { if ($nl_flags->{'megan'} ) { if ( &value_is_true( $nl_flags->{'use_fates'} ) ) { - $log->fatal_error("MEGAN can NOT be on when ED is also on.\n" . + $log->fatal_error("MEGAN can NOT be on when FATES is also on.\n" . " Use the '-no-megan' option when '-bgc fates' is activated"); } add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'megan_specifier'); diff --git a/bld/unit_testers/build-namelist_test.pl b/bld/unit_testers/build-namelist_test.pl index 39756d8055..79253617e9 100755 --- a/bld/unit_testers/build-namelist_test.pl +++ b/bld/unit_testers/build-namelist_test.pl @@ -138,7 +138,7 @@ sub make_config_cache { # # Figure out number of tests that will run # -my $ntests = 927; +my $ntests = 928; if ( defined($opts{'compare'}) ) { $ntests += 588; } @@ -849,6 +849,11 @@ sub make_config_cache { GLC_TWO_WAY_COUPLING=>"FALSE", phys=>"clm5_0", }, + "dogrossandsp" =>{ options=>"-envxml_dir . -bgc sp -use_case 20thC_transient", + namelst=>"do_grossunrep=.true.", + GLC_TWO_WAY_COUPLING=>"FALSE", + phys=>"clm5_0", + }, "nocropwfert" =>{ options=>"-envxml_dir . -bgc sp -no-crop", namelst=>"use_fertilizer=T", GLC_TWO_WAY_COUPLING=>"FALSE", From 9704782c55eb657542abeb1411a66f5cb5234f7a Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 6 Aug 2019 16:24:10 -0600 Subject: [PATCH 07/27] Check that turning on do_grossunrep=T works for 20th century transient cases, so also turn on BGC and crop --- .../namelist_definition_ctsm.xml | 2 +- bld/unit_testers/build-namelist_test.pl | 2 +- .../usermods_dirs/cmip6_output/user_nl_clm | 77 ------------------- 3 files changed, 2 insertions(+), 79 deletions(-) delete mode 100644 cime_config/usermods_dirs/cmip6_output/user_nl_clm diff --git a/bld/namelist_files/namelist_definition_ctsm.xml b/bld/namelist_files/namelist_definition_ctsm.xml index 9d94b10be8..cd3eb0d5c6 100644 --- a/bld/namelist_files/namelist_definition_ctsm.xml +++ b/bld/namelist_files/namelist_definition_ctsm.xml @@ -2344,7 +2344,7 @@ If TRUE, apply harvest from flanduse_timeseries file. -If TRUE, apply grossunrep from flanduse_timeseries file. +If TRUE, apply gross unrepresented landuse/land-cover change from flanduse_timeseries file. (Only valid for transient runs, where there is a flanduse_timeseries file.) (Also, only valid for use_cn = true.) diff --git a/bld/unit_testers/build-namelist_test.pl b/bld/unit_testers/build-namelist_test.pl index 79253617e9..5535712803 100755 --- a/bld/unit_testers/build-namelist_test.pl +++ b/bld/unit_testers/build-namelist_test.pl @@ -1224,7 +1224,7 @@ sub make_config_cache { my $usecase = "20thC_transient"; my $GLC_NEC = 10; foreach my $res ( @tran_res ) { - $options = "-res $res -use_case $usecase -envxml_dir . "; + $options = "-res $res -use_case $usecase -envxml_dir . -bgc bgc -crop -namelist '&a do_grossunrep=T/'"; &make_env_run(); eval{ system( "$bldnml $options > $tempfile 2>&1 " ); }; is( $@, '', "$options" ); diff --git a/cime_config/usermods_dirs/cmip6_output/user_nl_clm b/cime_config/usermods_dirs/cmip6_output/user_nl_clm deleted file mode 100644 index 0df7c685eb..0000000000 --- a/cime_config/usermods_dirs/cmip6_output/user_nl_clm +++ /dev/null @@ -1,77 +0,0 @@ -!---------------------------------------------------------------------------------- -! Users should add all user specific namelist changes below in the form of -! namelist_var = new_namelist_value -! -! EXCEPTIONS: -! Set use_cndv by the compset you use and the CLM_BLDNML_OPTS -dynamic_vegetation setting -! Set use_vichydro by the compset you use and the CLM_BLDNML_OPTS -vichydro setting -! Set use_cn by the compset you use and CLM_BLDNML_OPTS -bgc setting -! Set use_crop by the compset you use and CLM_BLDNML_OPTS -crop setting -! Set spinup_state by the CLM_BLDNML_OPTS -bgc_spinup setting -! Set irrigate by the CLM_BLDNML_OPTS -irrig setting -! Set co2_ppmv with CCSM_CO2_PPMV option -! Set dtime with L_NCPL option -! Set fatmlndfrc with LND_DOMAIN_PATH/LND_DOMAIN_FILE options -! Set finidat with RUN_REFCASE/RUN_REFDATE/RUN_REFTOD options for hybrid or branch cases -! (includes $inst_string for multi-ensemble cases) -! Set maxpatch_glcmec with GLC_NEC option -! Set glc_do_dynglacier with GLC_TWO_WAY_COUPLING env variable -!---------------------------------------------------------------------------------- - -! h0 stream (monthly average, gridcell-level) -! Emon, Lmon, LIMon -hist_fexcl1 = 'PCT_CFT', 'PCT_GLC_MEC', 'SOIL1C_vr', 'SOIL1N_vr', 'SOIL2C_vr', 'SOIL2N_vr', 'SOIL3C_vr', 'SOIL3N_vr', 'CWDC_vr', -'LITR1C_vr', 'LITR2C_vr', 'LITR3C_vr', 'LITR1N_vr', 'LITR2N_vr', 'LITR3N_vr','CWDN_vr', -'PCT_NAT_PFT','SMIN_NO3_vr','CONC_O2_UNSAT', 'CONC_O2_SAT','SMIN_NH4_vr','SMINN_vr' - -! h0 stream ICE variables and other variables inactive by default (monthly average, gridcell-level) -! Emon, Lmon, LIMon -hist_fincl1 = 'EFLX_LH_TOT_ICE', 'FIRE_ICE', 'FLDS_ICE', 'FSH_ICE', 'FSNO_ICE', 'FSR_ICE', -'QFLX_SUB_SNOW_ICE', 'QRUNOFF_ICE', 'QSNOFRZ_ICE', 'QSNOMELT_ICE', 'RAIN_ICE', 'SNOW_ICE', -'SNOWICE_ICE', 'SNOWLIQ_ICE', 'SNOTXMASS_ICE', 'TG_ICE', 'TOPO_COL_ICE', 'TSA_ICE', 'TSOI_ICE', -'LEAFC_TO_LITTER', 'FROOTC_TO_LITTER','LITR1C_TO_SOIL1C','LITR1N_TO_SOIL1N','LITR2C_TO_SOIL1C', -'LITR2N_TO_SOIL1N','LITR3C_TO_SOIL2C','LITR3N_TO_SOIL2N','DWT_WOOD_PRODUCTC_GAIN_PATCH' - -! h1 stream (monthly average, finest sub-grid) -! Emon, Lmon -hist_fincl2 = 'GPP', 'NPP', 'AGNPP', 'TLAI', 'TOTVEGC', 'TSA','TREFMNAV','TREFMXAV', 'BTRANMN', 'NPP_NUPTAKE', 'GRAINC_TO_FOOD', -'Vcmx25Z', 'FSH', 'NFERTILIZATION', 'AR', 'VEGWP', 'FCTR', 'FCEV', 'FGEV', 'FIRE', 'FSR', 'HTOP', -'FIRA', 'FSA', 'HR', 'GSSUNLN', 'GSSHALN', 'TSKIN' - -! h2 stream (monthly average, landunit-level) -! Emon -! TOT_WOODPRODC:I, CROPPROD1C:I, and NEE are not available at the landunit level -hist_fincl3 = 'FSR', 'H2OSNO', 'Q2M', 'SNOWDP', 'TSA', 'TREFMNAV', 'TREFMXAV', 'TG', 'QRUNOFF', 'FSH', 'FIRE', 'FIRA', 'FGR', -'EFLX_LH_TOT', 'RH2M', 'TLAI', 'GPP', 'NPP', 'SOILWATER_10CM', 'TOTSOILLIQ', 'TOTSOILICE', 'AR', 'HR', 'DWT_CONV_CFLUX_PATCH', -'WOOD_HARVESTC', 'U10', 'DWT_WOOD_PRODUCTC_GAIN_PATCH', 'GRAINC_TO_FOOD', 'SLASH_HARVESTC', 'TSOI_10CM', 'COL_FIRE_CLOSS', -'DWT_SLASH_CFLUX_PATCH', 'QIRRIG', 'URBAN_HEAT', 'WASTEHEAT', 'HTOP', 'TSKIN', 'FROOTC:I' - -! h3 stream (yearly average, gridcell-level) -! Eyr -hist_fincl4 = 'PCT_CFT', 'PCT_GLC_MEC', 'SOIL1C_vr', 'SOIL1N_vr', 'SOIL2C_vr', 'SOIL2N_vr', 'SOIL3C_vr', 'SOIL3N_vr', 'CWDC_vr', -'LITR1C_vr', 'LITR2C_vr', 'LITR3C_vr', 'LITR1N_vr', 'LITR2N_vr', 'LITR3N_vr','CWDN_vr', 'QICE_FORC', 'TSRF_FORC', 'TOPO_FORC' -'PCT_NAT_PFT','PCT_LANDUNIT','TOTLITC:I','TOT_WOODPRODC:I','CROPPROD1C:I','TOTSOMC:I','TOTVEGC:I','FSNO_ICE' - -! h4 stream (yearly average, landunit-level) -! Eyr landuse tiles -hist_fincl5 = 'TOTSOMC:I', 'TOTSOMC_1m:I', 'TOTECOSYSC:I', 'TOTVEGC:I', 'WOODC:I', 'TOTLITC:I', 'LIVECROOTC:I', 'DEADCROOTC:I', 'FROOTC:I' - -! h5 stream (daily average, gridcell-level) -! day, Eday -hist_fincl6 = 'SOILWATER_10CM', 'TOTSOILLIQ', 'TOTSOILICE', 'GPP', 'NPP', 'AR', 'HR', 'EFLX_LH_TOT', 'FSH', 'FGR12', 'FSM', 'QSNOEVAP', 'TLAI', 'QDRAI', 'QDRAI_PERCH', 'QOVER', 'QFLX_SUB_SNOW', 'FSA', 'FIRA', 'H2OSNO', 'SNOCAN', 'QSNOFRZ', 'QFLX_SNOW_DRAIN', 'SNOWDP', 'H2OSFC', 'TV', 'TG', 'TAUX', 'TAUY', 'QVEGT', 'TWS', 'H2OCAN', 'ALT', 'QVEGE', 'QSOIL', 'TSKIN', 'FSDS','FSNO','SNOFSRVD','SNOFSRVI','SNOFSRND','SNOFSRNI','FSDSVD','FSDSVI','FSDSND','FSDSNI','SNOWLIQ','SOILICE','SOILLIQ','QINTR','SNOBCMSL','TSOI','SNOTXMASS','SNOWICE','SNOWLIQ','QRUNOFF','RAIN','SNOW' - -! h6 stream (daily average, landunit-level) -! Eday -hist_fincl7 = 'TREFMXAV','TREFMNAV' - -! h7 stream (3-hourly average, gridcell-level) -! 3hr, E3hr, CF3hr -! 3hr requires QRUNOFF for time mean, and SOILWATER_10CM, TSKIN for time point (I) -! E3hr requires GPP, AR, HR for time mean -! CF3hr requires QFLX_SUB_SNOW for time point (I) -hist_fincl8 = 'GPP','AR','HR','TSA','RH2M','SOILWATER_10CM:I','FSH','EFLX_LH_TOT','FSDS','QRUNOFF','QFLX_SUB_SNOW:I','TSKIN:I' - -hist_mfilt = 1,1,1,1,1,365,365,2920 -hist_dov2xy = .true.,.false.,.false.,.true.,.false.,.true.,.false.,.true. -hist_nhtfrq = 0,0,0,-8760,-8760,-24,-24,-3 -hist_type1d_pertape = ' ',' ','LAND',' ','LAND',' ','LAND',' ' From 9f73f6e9f0c6d6d8753c5b8f94c19764643b2d20 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 6 Aug 2019 22:41:50 -0600 Subject: [PATCH 08/27] Change maxpatch_pft to maxsoil_patches as it was changed, so now works compilers and runs --- src/biogeochem/CNCIsoFluxMod.F90 | 4 ++-- src/biogeochem/dynGrossUnrepMod.F90 | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/biogeochem/CNCIsoFluxMod.F90 b/src/biogeochem/CNCIsoFluxMod.F90 index 7c9697bbaf..f07e6b7a62 100644 --- a/src/biogeochem/CNCIsoFluxMod.F90 +++ b/src/biogeochem/CNCIsoFluxMod.F90 @@ -1767,7 +1767,7 @@ subroutine CNCIsoGrossUnrepPftToColumn (num_soilc, filter_soilc, & ) do j = 1, nlevdecomp - do pi = 1,maxpatch_pft + do pi = 1,maxsoil_patches do fc = 1,num_soilc c = filter_soilc(fc) @@ -1806,7 +1806,7 @@ subroutine CNCIsoGrossUnrepPftToColumn (num_soilc, filter_soilc, & end do end do - do pi = 1,maxpatch_pft + do pi = 1,maxsoil_patches do fc = 1,num_soilc c = filter_soilc(fc) diff --git a/src/biogeochem/dynGrossUnrepMod.F90 b/src/biogeochem/dynGrossUnrepMod.F90 index 0774a3a1a5..1ad01c9348 100644 --- a/src/biogeochem/dynGrossUnrepMod.F90 +++ b/src/biogeochem/dynGrossUnrepMod.F90 @@ -375,7 +375,7 @@ subroutine CNGrossUnrepPftToColumn (num_soilc, filter_soilc, & ! to the column level and assign them to the three litter pools ! ! !USES: - use clm_varpar , only : maxpatch_pft, nlevdecomp, numpft + use clm_varpar , only : maxsoil_patches, nlevdecomp ! ! !ARGUMENTS: integer , intent(in) :: num_soilc ! number of soil columns in filter @@ -435,7 +435,7 @@ subroutine CNGrossUnrepPftToColumn (num_soilc, filter_soilc, & ) do j = 1, nlevdecomp - do pi = 1,maxpatch_pft + do pi = 1,maxsoil_patches do fc = 1,num_soilc c = filter_soilc(fc) @@ -500,7 +500,7 @@ subroutine CNGrossUnrepPftToColumn (num_soilc, filter_soilc, & end do end do - do pi = 1,maxpatch_pft + do pi = 1,maxsoil_patches do fc = 1,num_soilc c = filter_soilc(fc) From a7c384e38c83c3e7ad8bc2bb5dde799b7ddcfc2b Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 6 Aug 2019 22:43:07 -0600 Subject: [PATCH 09/27] Change a test to do a test with transient Gross Unrepresented LULCC --- cime_config/testdefs/testlist_clm.xml | 4 ++-- .../clm/ciso_decStart_GU_LULCC/include_user_mods | 1 + .../testmods_dirs/clm/ciso_decStart_GU_LULCC/user_nl_clm | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 cime_config/testdefs/testmods_dirs/clm/ciso_decStart_GU_LULCC/include_user_mods create mode 100644 cime_config/testdefs/testmods_dirs/clm/ciso_decStart_GU_LULCC/user_nl_clm diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index 8409089613..8906c6c4bd 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -314,14 +314,14 @@ - + - + diff --git a/cime_config/testdefs/testmods_dirs/clm/ciso_decStart_GU_LULCC/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/ciso_decStart_GU_LULCC/include_user_mods new file mode 100644 index 0000000000..c0adfb5904 --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/ciso_decStart_GU_LULCC/include_user_mods @@ -0,0 +1 @@ +../ciso_decStart diff --git a/cime_config/testdefs/testmods_dirs/clm/ciso_decStart_GU_LULCC/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/ciso_decStart_GU_LULCC/user_nl_clm new file mode 100644 index 0000000000..8d3ca17778 --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/ciso_decStart_GU_LULCC/user_nl_clm @@ -0,0 +1 @@ +do_grossunrep = .true. From b91c593028ca1e28b0b7ba4c7168e649e0ca10a0 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 14 Aug 2019 15:51:28 -0600 Subject: [PATCH 10/27] Remove a git conflict leftover, and close the toosmall_* entries, so it will pass xmllint --- bld/namelist_files/namelist_definition_ctsm.xml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/bld/namelist_files/namelist_definition_ctsm.xml b/bld/namelist_files/namelist_definition_ctsm.xml index cd3eb0d5c6..f7d24e077a 100644 --- a/bld/namelist_files/namelist_definition_ctsm.xml +++ b/bld/namelist_files/namelist_definition_ctsm.xml @@ -1111,37 +1111,37 @@ If true, this directs the model to collapse the urban landunits to the dominant Percentage threshold above which the model keeps the soil landunit. Selecting the value 0 means DO NOTHING. Default: 0 Percentage threshold above which the model keeps the crop landunit. Selecting the value 0 means DO NOTHING. Default: 0 Percentage threshold above which the model keeps the glacier landunit. Selecting the value 0 means DO NOTHING. Default: 0 Percentage threshold above which the model keeps the lake landunit. Selecting the value 0 means DO NOTHING. Default: 0 Percentage threshold above which the model keeps the wetland landunit. Selecting the value 0 means DO NOTHING. Default: 0 Percentage threshold above which the model keeps the urban landunits. Selecting the value 0 means DO NOTHING. If collapse_urban = .false., the same threshold will apply to all three urban landunits if they are present. If collapse_urban = .true., this threshold will apply to the single collapsed urban landunit if presnet. Default: 0 @@ -2395,7 +2395,6 @@ continue run; it is an error for this to be set in a branch run. Furthermore, this setting has no effect in a cold start run. ->>>>>>> ctsm1.0.dev055:bld/namelist_files/namelist_definition_ctsm.xml If TRUE, allow area changes at times other than the year boundary. This should From cc7d56567044959b937d8ce4a2986279aeeb044d Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Thu, 15 Aug 2019 14:35:56 -0600 Subject: [PATCH 11/27] Move SLASH_HARVESTC to gridcell level list --- cime_config/usermods_dirs/output_bgc/user_nl_clm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cime_config/usermods_dirs/output_bgc/user_nl_clm b/cime_config/usermods_dirs/output_bgc/user_nl_clm index de136ad4b4..607c2ee25c 100644 --- a/cime_config/usermods_dirs/output_bgc/user_nl_clm +++ b/cime_config/usermods_dirs/output_bgc/user_nl_clm @@ -11,10 +11,10 @@ hist_fincl2 += 'GPP', 'NPP', 'AGNPP', 'TOTVEGC', 'NPP_NUPTAKE', 'AR', 'HR', 'HTO ! h2 stream (monthly average, landunit-level) ! TOT_WOODPRODC:I, CROPPROD1C:I, and NEE are not available at the landunit level -hist_fincl3 += 'GPP', 'NPP', 'AR', 'HR', 'DWT_CONV_CFLUX_PATCH', 'WOOD_HARVESTC', 'DWT_WOOD_PRODUCTC_GAIN_PATCH', 'SLASH_HARVESTC', 'COL_FIRE_CLOSS', 'DWT_SLASH_CFLUX', 'FROOTC:I', 'HTOP' +hist_fincl3 += 'GPP', 'NPP', 'AR', 'HR', 'DWT_CONV_CFLUX_PATCH', 'WOOD_HARVESTC', 'DWT_WOOD_PRODUCTC_GAIN_PATCH', 'COL_FIRE_CLOSS', 'DWT_SLASH_CFLUX', 'FROOTC:I', 'HTOP' ! h3 stream (yearly average, gridcell-level) -hist_fincl4 += 'SOILC_vr', 'SOILN_vr', 'CWDC_vr', 'LITR1C_vr', 'LITR2C_vr', 'LITR3C_vr', 'LITR1N_vr', 'LITR2N_vr', 'LITR3N_vr','CWDN_vr', 'TOTLITC:I', 'TOT_WOODPRODC:I', 'TOTSOMC:I','TOTVEGC:I' +hist_fincl4 += 'SOILC_vr', 'SOILN_vr', 'CWDC_vr', 'LITR1C_vr', 'LITR2C_vr', 'LITR3C_vr', 'LITR1N_vr', 'LITR2N_vr', 'LITR3N_vr','CWDN_vr', 'TOTLITC:I', 'TOT_WOODPRODC:I', 'TOTSOMC:I','TOTVEGC:I', 'SLASH_HARVESTC' ! h4 stream (yearly average, landunit-level) hist_fincl5 += 'TOTSOMC:I', 'TOTSOMC_1m:I', 'TOTECOSYSC:I', 'TOTVEGC:I', 'WOODC:I', 'TOTLITC:I', 'LIVECROOTC:I', 'DEADCROOTC:I', 'FROOTC:I' From 570e192f51338c417ee5cba07d56ec4c47ac3394 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Thu, 15 Aug 2019 14:53:34 -0600 Subject: [PATCH 12/27] Revert "Move SLASH_HARVESTC to gridcell level list" This reverts commit cc7d56567044959b937d8ce4a2986279aeeb044d. --- cime_config/usermods_dirs/output_bgc/user_nl_clm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cime_config/usermods_dirs/output_bgc/user_nl_clm b/cime_config/usermods_dirs/output_bgc/user_nl_clm index 607c2ee25c..de136ad4b4 100644 --- a/cime_config/usermods_dirs/output_bgc/user_nl_clm +++ b/cime_config/usermods_dirs/output_bgc/user_nl_clm @@ -11,10 +11,10 @@ hist_fincl2 += 'GPP', 'NPP', 'AGNPP', 'TOTVEGC', 'NPP_NUPTAKE', 'AR', 'HR', 'HTO ! h2 stream (monthly average, landunit-level) ! TOT_WOODPRODC:I, CROPPROD1C:I, and NEE are not available at the landunit level -hist_fincl3 += 'GPP', 'NPP', 'AR', 'HR', 'DWT_CONV_CFLUX_PATCH', 'WOOD_HARVESTC', 'DWT_WOOD_PRODUCTC_GAIN_PATCH', 'COL_FIRE_CLOSS', 'DWT_SLASH_CFLUX', 'FROOTC:I', 'HTOP' +hist_fincl3 += 'GPP', 'NPP', 'AR', 'HR', 'DWT_CONV_CFLUX_PATCH', 'WOOD_HARVESTC', 'DWT_WOOD_PRODUCTC_GAIN_PATCH', 'SLASH_HARVESTC', 'COL_FIRE_CLOSS', 'DWT_SLASH_CFLUX', 'FROOTC:I', 'HTOP' ! h3 stream (yearly average, gridcell-level) -hist_fincl4 += 'SOILC_vr', 'SOILN_vr', 'CWDC_vr', 'LITR1C_vr', 'LITR2C_vr', 'LITR3C_vr', 'LITR1N_vr', 'LITR2N_vr', 'LITR3N_vr','CWDN_vr', 'TOTLITC:I', 'TOT_WOODPRODC:I', 'TOTSOMC:I','TOTVEGC:I', 'SLASH_HARVESTC' +hist_fincl4 += 'SOILC_vr', 'SOILN_vr', 'CWDC_vr', 'LITR1C_vr', 'LITR2C_vr', 'LITR3C_vr', 'LITR1N_vr', 'LITR2N_vr', 'LITR3N_vr','CWDN_vr', 'TOTLITC:I', 'TOT_WOODPRODC:I', 'TOTSOMC:I','TOTVEGC:I' ! h4 stream (yearly average, landunit-level) hist_fincl5 += 'TOTSOMC:I', 'TOTSOMC_1m:I', 'TOTECOSYSC:I', 'TOTVEGC:I', 'WOODC:I', 'TOTLITC:I', 'LIVECROOTC:I', 'DEADCROOTC:I', 'FROOTC:I' From 5523c2d47338fec99ae7bbb210138186016734d2 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Thu, 15 Aug 2019 15:00:14 -0600 Subject: [PATCH 13/27] Remove DWT_SLASH_CFLUX from landunit average, and have it just output monthly on gridcell which it is by default --- cime_config/usermods_dirs/output_bgc/user_nl_clm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cime_config/usermods_dirs/output_bgc/user_nl_clm b/cime_config/usermods_dirs/output_bgc/user_nl_clm index de136ad4b4..0c0bcd52ff 100644 --- a/cime_config/usermods_dirs/output_bgc/user_nl_clm +++ b/cime_config/usermods_dirs/output_bgc/user_nl_clm @@ -11,7 +11,7 @@ hist_fincl2 += 'GPP', 'NPP', 'AGNPP', 'TOTVEGC', 'NPP_NUPTAKE', 'AR', 'HR', 'HTO ! h2 stream (monthly average, landunit-level) ! TOT_WOODPRODC:I, CROPPROD1C:I, and NEE are not available at the landunit level -hist_fincl3 += 'GPP', 'NPP', 'AR', 'HR', 'DWT_CONV_CFLUX_PATCH', 'WOOD_HARVESTC', 'DWT_WOOD_PRODUCTC_GAIN_PATCH', 'SLASH_HARVESTC', 'COL_FIRE_CLOSS', 'DWT_SLASH_CFLUX', 'FROOTC:I', 'HTOP' +hist_fincl3 += 'GPP', 'NPP', 'AR', 'HR', 'DWT_CONV_CFLUX_PATCH', 'WOOD_HARVESTC', 'DWT_WOOD_PRODUCTC_GAIN_PATCH', 'SLASH_HARVESTC', 'COL_FIRE_CLOSS', 'FROOTC:I', 'HTOP' ! h3 stream (yearly average, gridcell-level) hist_fincl4 += 'SOILC_vr', 'SOILN_vr', 'CWDC_vr', 'LITR1C_vr', 'LITR2C_vr', 'LITR3C_vr', 'LITR1N_vr', 'LITR2N_vr', 'LITR3N_vr','CWDN_vr', 'TOTLITC:I', 'TOT_WOODPRODC:I', 'TOTSOMC:I','TOTVEGC:I' From df7eb92131a074bd1b0a9a73faa243b14a3ee375 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Sat, 17 Aug 2019 02:23:14 -0600 Subject: [PATCH 14/27] Only output the GRU fields if do_grossunrep is actually turned on --- src/biogeochem/CNVegCarbonFluxType.F90 | 44 +++++++++++++----------- src/biogeochem/CNVegNitrogenFluxType.F90 | 19 +++++----- 2 files changed, 34 insertions(+), 29 deletions(-) diff --git a/src/biogeochem/CNVegCarbonFluxType.F90 b/src/biogeochem/CNVegCarbonFluxType.F90 index b9b7c69e4a..396a8088cc 100644 --- a/src/biogeochem/CNVegCarbonFluxType.F90 +++ b/src/biogeochem/CNVegCarbonFluxType.F90 @@ -22,7 +22,7 @@ module CNVegCarbonFluxType use ColumnType , only : col use PatchType , only : patch use AnnualFluxDribbler , only : annual_flux_dribbler_type, annual_flux_dribbler_gridcell - use dynSubgridControlMod , only : get_for_testing_allow_non_annual_changes + use dynSubgridControlMod , only : get_for_testing_allow_non_annual_changes, get_do_grossunrep use abortutils , only : endrun ! ! !PUBLIC TYPES: @@ -2993,26 +2993,28 @@ subroutine InitHistory(this, bounds, carbon_type) avgflag='A', long_name='dead coarse root to CWD due to landcover change', & ptr_col=this%dwt_deadcrootc_to_cwdc_col, default='inactive') - this%gru_conv_cflux_patch(begp:endp) = spval - call hist_addfld1d (fname='GRU_CONV_CFLUX', units='gC/m^2/s', & - avgflag='A', long_name='gross unrepresented conversion C flux (immediate loss to atm) (0 at all times except first timestep of year)', & - ptr_patch=this%gru_conv_cflux_patch) - - this%gru_conv_cflux_dribbled_grc(begg:endg) = spval - call hist_addfld1d (fname='GRU_CONV_CFLUX_DRIBBLED', units='gC/m^2/s', & - avgflag='A', & - long_name='gross unrepresented conversion C flux (immediate loss to atm), dribbled throughout the year', & - ptr_gcell=this%gru_conv_cflux_dribbled_grc) - - this%gru_wood_productc_gain_patch(begp:endp) = spval - call hist_addfld1d (fname='GRU_WOODPRODC_GAIN', units='gC/m^2/s', & - avgflag='A', long_name='gross unrepresented landcover change driven addition to wood product carbon pools (0 at all times except first timestep of year)', & - ptr_patch=this%gru_wood_productc_gain_patch) - - this%gru_slash_cflux_patch(begp:endp) = spval - call hist_addfld1d (fname='GRU_SLASH_CFLUX', units='gC/m^2/s', & - avgflag='A', long_name='slash gross unrepresented landcover change carbon (to litter)', & - ptr_patch=this%gru_slash_cflux_patch) + if ( get_do_grossunrep() )then + this%gru_conv_cflux_patch(begp:endp) = spval + call hist_addfld1d (fname='GRU_CONV_CFLUX', units='gC/m^2/s', & + avgflag='A', long_name='gross unrepresented conversion C flux (immediate loss to atm) (0 at all times except first timestep of year)', & + ptr_patch=this%gru_conv_cflux_patch) + + this%gru_conv_cflux_dribbled_grc(begg:endg) = spval + call hist_addfld1d (fname='GRU_CONV_CFLUX_DRIBBLED', units='gC/m^2/s', & + avgflag='A', & + long_name='gross unrepresented conversion C flux (immediate loss to atm), dribbled throughout the year', & + ptr_gcell=this%gru_conv_cflux_dribbled_grc) + + this%gru_wood_productc_gain_patch(begp:endp) = spval + call hist_addfld1d (fname='GRU_WOODPRODC_GAIN', units='gC/m^2/s', & + avgflag='A', long_name='gross unrepresented landcover change driven addition to wood product carbon pools (0 at all times except first timestep of year)', & + ptr_patch=this%gru_wood_productc_gain_patch) + + this%gru_slash_cflux_patch(begp:endp) = spval + call hist_addfld1d (fname='GRU_SLASH_CFLUX', units='gC/m^2/s', & + avgflag='A', long_name='slash gross unrepresented landcover change carbon (to litter)', & + ptr_patch=this%gru_slash_cflux_patch) + end if this%crop_seedc_to_leaf_patch(begp:endp) = spval call hist_addfld1d (fname='CROP_SEEDC_TO_LEAF', units='gC/m^2/s', & diff --git a/src/biogeochem/CNVegNitrogenFluxType.F90 b/src/biogeochem/CNVegNitrogenFluxType.F90 index d9e121ed78..d3bf84e1eb 100644 --- a/src/biogeochem/CNVegNitrogenFluxType.F90 +++ b/src/biogeochem/CNVegNitrogenFluxType.F90 @@ -11,6 +11,7 @@ module CNVegNitrogenFluxType use decompMod , only : bounds_type use abortutils , only : endrun use SoilBiogeochemDecompCascadeConType , only : decomp_cascade_con + use dynSubgridControlMod , only : get_do_grossunrep use LandunitType , only : lun use ColumnType , only : col use PatchType , only : patch @@ -1120,15 +1121,17 @@ subroutine InitHistory(this, bounds) avgflag='A', long_name='dead coarse root to CWD due to landcover change', & ptr_col=this%dwt_deadcrootn_to_cwdn_col, default='inactive') - this%gru_conv_nflux_patch(begp:endp) = spval - call hist_addfld1d (fname='GRU_CONV_NFLUX', units='gN/m^2/s', & - avgflag='A', long_name='gross unrepresented conversion N flux (immediate loss to atm) (0 at all times except first timestep of year)', & - ptr_patch=this%gru_conv_nflux_patch) + if ( get_do_grossunrep() )then + this%gru_conv_nflux_patch(begp:endp) = spval + call hist_addfld1d (fname='GRU_CONV_NFLUX', units='gN/m^2/s', & + avgflag='A', long_name='gross unrepresented conversion N flux (immediate loss to atm) (0 at all times except first timestep of year)', & + ptr_patch=this%gru_conv_nflux_patch) - this%gru_wood_productn_gain_patch(begp:endp) = spval - call hist_addfld1d (fname='GRU_WOODPRODN_GAIN', units='gN/m^2/s', & - avgflag='A', long_name='gross unrepresented landcover change driven addition to wood product nitrogen pools (0 at all times except first timestep of year)', & - ptr_patch=this%gru_wood_productn_gain_patch) + this%gru_wood_productn_gain_patch(begp:endp) = spval + call hist_addfld1d (fname='GRU_WOODPRODN_GAIN', units='gN/m^2/s', & + avgflag='A', long_name='gross unrepresented landcover change driven addition to wood product nitrogen pools (0 at all times except first timestep of year)', & + ptr_patch=this%gru_wood_productn_gain_patch) + end if this%crop_seedn_to_leaf_patch(begp:endp) = spval call hist_addfld1d (fname='CROP_SEEDN_TO_LEAF', units='gN/m^2/s', & From 0e09a64fc7f6d9239e1ebdba9c41e54dfe7be374 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 31 Jan 2023 16:39:46 -0700 Subject: [PATCH 15/27] Add tests for the Gross unrepresented LU change option --- .../clm/f09_dec1990Start_GU_LULCC/include_user_mods | 1 + .../testmods_dirs/clm/f09_dec1990Start_GU_LULCC/shell_commands | 2 ++ .../testmods_dirs/clm/f09_dec1990Start_GU_LULCC/user_nl_clm | 3 +++ .../clm/f09_dec1990Start_GU_LULCC_monthly/include_user_mods | 2 ++ 4 files changed, 8 insertions(+) create mode 100644 cime_config/testdefs/testmods_dirs/clm/f09_dec1990Start_GU_LULCC/include_user_mods create mode 100755 cime_config/testdefs/testmods_dirs/clm/f09_dec1990Start_GU_LULCC/shell_commands create mode 100644 cime_config/testdefs/testmods_dirs/clm/f09_dec1990Start_GU_LULCC/user_nl_clm create mode 100644 cime_config/testdefs/testmods_dirs/clm/f09_dec1990Start_GU_LULCC_monthly/include_user_mods diff --git a/cime_config/testdefs/testmods_dirs/clm/f09_dec1990Start_GU_LULCC/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/f09_dec1990Start_GU_LULCC/include_user_mods new file mode 100644 index 0000000000..fe0e18cf88 --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/f09_dec1990Start_GU_LULCC/include_user_mods @@ -0,0 +1 @@ +../default diff --git a/cime_config/testdefs/testmods_dirs/clm/f09_dec1990Start_GU_LULCC/shell_commands b/cime_config/testdefs/testmods_dirs/clm/f09_dec1990Start_GU_LULCC/shell_commands new file mode 100755 index 0000000000..4e10e7086a --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/f09_dec1990Start_GU_LULCC/shell_commands @@ -0,0 +1,2 @@ +./xmlchange RUN_STARTDATE=1990-12-25 +./xmlchange CLM_BLDNML_OPTS=-ignore_warnings --append diff --git a/cime_config/testdefs/testmods_dirs/clm/f09_dec1990Start_GU_LULCC/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/f09_dec1990Start_GU_LULCC/user_nl_clm new file mode 100644 index 0000000000..6a666f2684 --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/f09_dec1990Start_GU_LULCC/user_nl_clm @@ -0,0 +1,3 @@ + flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_map/ctsm5.1.dev052/landuse.timeseries_0.9x1.25_hist_78pfts_CMIP6_simyr1700-2021_c220825.nc' + fsurdat = '$DIN_LOC_ROOT/lnd/clm2/surfdata_map/ctsm5.1.dev052/surfdata_0.9x1.25_hist_78pfts_CMIP6_simyr1700_c220825.nc' + do_grossunrep = .true. diff --git a/cime_config/testdefs/testmods_dirs/clm/f09_dec1990Start_GU_LULCC_monthly/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/f09_dec1990Start_GU_LULCC_monthly/include_user_mods new file mode 100644 index 0000000000..24f76fbb9f --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/f09_dec1990Start_GU_LULCC_monthly/include_user_mods @@ -0,0 +1,2 @@ +../../f09_dec1990Start_GU_LULCC +../monthly From 0a087c5495283171450842d072ddbbf9869bfb6a Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 31 Jan 2023 16:42:33 -0700 Subject: [PATCH 16/27] Add tests to test list for Gross unrepresented land use change --- cime_config/testdefs/testlist_clm.xml | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index 8906c6c4bd..6cfe703c6d 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -317,11 +317,32 @@ - + + + + + + + + + + + + - + + + + + + + + + + + From 29f9b5971fb080318aabd0a78f132764aa2ef48d Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 31 Jan 2023 16:49:28 -0700 Subject: [PATCH 17/27] Add some comments and fix directory name --- .../testmods_dirs/clm/f09_dec1990Start_GU_LULCC/shell_commands | 1 + .../testmods_dirs/clm/f09_dec1990Start_GU_LULCC/user_nl_clm | 2 ++ .../clm/f09_dec1990Start_GU_LULCC_monthly/include_user_mods | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/cime_config/testdefs/testmods_dirs/clm/f09_dec1990Start_GU_LULCC/shell_commands b/cime_config/testdefs/testmods_dirs/clm/f09_dec1990Start_GU_LULCC/shell_commands index 4e10e7086a..972cd25f5c 100755 --- a/cime_config/testdefs/testmods_dirs/clm/f09_dec1990Start_GU_LULCC/shell_commands +++ b/cime_config/testdefs/testmods_dirs/clm/f09_dec1990Start_GU_LULCC/shell_commands @@ -1,2 +1,3 @@ ./xmlchange RUN_STARTDATE=1990-12-25 +# Ignore warnings because we are using crop, but starting from a different date than the initial conditions were for ./xmlchange CLM_BLDNML_OPTS=-ignore_warnings --append diff --git a/cime_config/testdefs/testmods_dirs/clm/f09_dec1990Start_GU_LULCC/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/f09_dec1990Start_GU_LULCC/user_nl_clm index 6a666f2684..efb3212d5f 100644 --- a/cime_config/testdefs/testmods_dirs/clm/f09_dec1990Start_GU_LULCC/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/f09_dec1990Start_GU_LULCC/user_nl_clm @@ -1,3 +1,5 @@ + ! Specify a dataset that has non-zero Gross Unrepresented Land Use change fields on it + ! And turn it on flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_map/ctsm5.1.dev052/landuse.timeseries_0.9x1.25_hist_78pfts_CMIP6_simyr1700-2021_c220825.nc' fsurdat = '$DIN_LOC_ROOT/lnd/clm2/surfdata_map/ctsm5.1.dev052/surfdata_0.9x1.25_hist_78pfts_CMIP6_simyr1700_c220825.nc' do_grossunrep = .true. diff --git a/cime_config/testdefs/testmods_dirs/clm/f09_dec1990Start_GU_LULCC_monthly/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/f09_dec1990Start_GU_LULCC_monthly/include_user_mods index 24f76fbb9f..b10682f861 100644 --- a/cime_config/testdefs/testmods_dirs/clm/f09_dec1990Start_GU_LULCC_monthly/include_user_mods +++ b/cime_config/testdefs/testmods_dirs/clm/f09_dec1990Start_GU_LULCC_monthly/include_user_mods @@ -1,2 +1,2 @@ -../../f09_dec1990Start_GU_LULCC +../f09_dec1990Start_GU_LULCC ../monthly From c96735b53ae9816e2de88b667f588a70b69cbeed Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Thu, 2 Feb 2023 16:25:56 -0700 Subject: [PATCH 18/27] Updating new tests, mainly with longer walltimes --- cime_config/testdefs/testlist_clm.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index 6cfe703c6d..4dfddb4a11 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -320,7 +320,7 @@ - + @@ -331,17 +331,17 @@ - + - + - + From 463c8b9a7eb483cd599b93a2f9a1f68304b68517 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Sat, 11 Feb 2023 18:01:22 -0700 Subject: [PATCH 19/27] Updating new tests with longer walltimes again ERP_D_Ld10.f09_f09_mg17.IHistClm50BgcCrop.cheyenne_gnu.clm-f09_dec1990Start ran out of time at 40 minutes, so I bumped it up to 59 and it passed --- cime_config/testdefs/testlist_clm.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index 4dfddb4a11..e602ac3597 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -331,7 +331,7 @@ - + From 8ef3f2882c56ce9275dd36b1da7e97eea4ba709b Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 22 Feb 2023 13:50:02 -0700 Subject: [PATCH 20/27] Use ERP_D_Ld10_P36x2 on cheyenne only; add ERP_D_Ld10 test on izumi These changes pertain to GU_LULCC tests in this commit. --- cime_config/testdefs/testlist_clm.xml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index 59251da53e..34e22e7272 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -462,10 +462,18 @@ + + + + + + + + + - From 093c07506bf758ab207405f3a06c7bd3e719e967 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 22 Feb 2023 14:12:56 -0700 Subject: [PATCH 21/27] Draft ChangeLog and ChangeSum --- doc/ChangeLog | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++ doc/ChangeSum | 1 + 2 files changed, 83 insertions(+) diff --git a/doc/ChangeLog b/doc/ChangeLog index 5870abdb23..6df1764ff4 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,4 +1,86 @@ =============================================================== +Tag name: ctsm5.1.dev119 +Originator(s): slevis (Samuel Levis,SLevis Consulting,303-665-1310), ekluzek Erik Kluzek), lawrencepj1 (Peter Lawrence) +Date: Wed Feb 22 13:57:36 MST 2023 +One-line Summary: Allow gross unrepresented land use transitions (PR #309) + +Purpose and description of changes +---------------------------------- + + Get gross unrepresented land use transitions working in CLM5.1. + +Significant changes to scientifically-supported configurations +-------------------------------------------------------------- + +Does this tag change answers significantly for any of the following physics +onfigurations? +(Details of any changes will be given in the "Answer changes" section below.) + + [Put an [X] in the box for any configuration with significant answer +hanges.] + +[ ] clm5_1 + +[ ] clm5_0 + +[ ] ctsm5_0-nwp + +[ ] clm4_5 + + +Bugs fixed or introduced +------------------------ +CTSM issues fixed (include CTSM Issue #): + I didn't find a corresponding issue. + +Notes of particular relevance for users +--------------------------------------- +Changes made to namelist defaults (e.g., changed parameter values): + New namelist variable: do_grossunrep + +Changes to the datasets (e.g., parameter, surface or initial files): + Surface datasets may now contain non-zero gross unrepresented land use + transitions. + +Substantial timing or memory changes: +[e.g., check PFS test in the test suite and look at timings, if you +expect possible significant timing changes] + + +Notes of particular relevance for developers: +--------------------------------------------- +Changes to tests or testing: + Erik introduced new tests that can be identified by the GU_LULCC in + their names. I ran these with the test-suites and generated baselines + for them. + +Testing summary: +---------------- + [PASS means all tests PASS; OK means tests PASS other than expected fails.] + + regular tests (aux_clm: https://github.com/ESCOMP/CTSM/wiki/System-Testing-Guide#pre-merge-system-testing): + + cheyenne ---- OK + izumi ------- OK + + +Answer changes +-------------- + +Changes answers relative to baseline: NO (unless see next) + + Code configurations: do_grossunrep = .true. and surface dataset + includes non-zero gross unrepresented land use + transitions. I (slevis) have not investigated the + nature of the changes. + +Other details +------------- +Pull Requests that document the changes (include PR ids): + https://github.com/ESCOMP/ctsm/pull/309 + +=============================================================== +=============================================================== Tag name: ctsm5.1.dev118 Originator(s): slevis (Samuel Levis,SLevis Consulting,303-665-1310) Date: Sun Feb 5 18:31:29 MST 2023 diff --git a/doc/ChangeSum b/doc/ChangeSum index 215517275f..66e229d06c 100644 --- a/doc/ChangeSum +++ b/doc/ChangeSum @@ -1,5 +1,6 @@ Tag Who Date Summary ============================================================================================================================ + ctsm5.1.dev119 slevis 02/22/2023 Allow gross unrepresented land use transition (PR #309) ctsm5.1.dev118 slevis 02/05/2023 Use conda environment rather than ncar_pylib with the fsurdat_modifier system test ctsm5.1.dev117 afoster 02/02/2023 Updates to facilitate running FATES at NEON sites ctsm5.1.dev116 erik 01/26/2023 Small answer changes with bug fixes, zetamaxstable=2 for BHS, new single point fsurdat files From 55c6be2362d53d060e68e80b46c53ef7981d4ec5 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 27 Feb 2023 14:55:10 -0700 Subject: [PATCH 22/27] Correct test number --- bld/unit_testers/build-namelist_test.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bld/unit_testers/build-namelist_test.pl b/bld/unit_testers/build-namelist_test.pl index 1cccae0e29..1c6d951f0e 100755 --- a/bld/unit_testers/build-namelist_test.pl +++ b/bld/unit_testers/build-namelist_test.pl @@ -163,7 +163,7 @@ sub cat_and_create_namelistinfile { # # Figure out number of tests that will run # -my $ntests = 1847; +my $ntests = 1848; if ( defined($opts{'compare'}) ) { $ntests += 1254; } From 3f6c67af23ea0b6891ff8002f43369f7597e9f10 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 27 Feb 2023 15:25:14 -0700 Subject: [PATCH 23/27] Returned hrv_xsmrpool_to_atm_patch to CNVegCarbonFluxType This was an unintentional line removal that Erik realized. I also reordered the error checks that Erik recommended in dynSubgridControlMod. --- src/biogeochem/CNVegCarbonFluxType.F90 | 1 + src/dyn_subgrid/dynSubgridControlMod.F90 | 11 +++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/biogeochem/CNVegCarbonFluxType.F90 b/src/biogeochem/CNVegCarbonFluxType.F90 index 585859beaa..7864007faf 100644 --- a/src/biogeochem/CNVegCarbonFluxType.F90 +++ b/src/biogeochem/CNVegCarbonFluxType.F90 @@ -4721,6 +4721,7 @@ subroutine Summary_carbonflux(this, & this%hrv_deadcrootc_to_litter_patch(p) + & this%hrv_deadcrootc_storage_to_litter_patch(p) + & this%hrv_deadcrootc_xfer_to_litter_patch(p) + & + this%hrv_xsmrpool_to_atm_patch(p) + & this%hrv_gresp_storage_to_litter_patch(p) + & this%hrv_gresp_xfer_to_litter_patch(p) diff --git a/src/dyn_subgrid/dynSubgridControlMod.F90 b/src/dyn_subgrid/dynSubgridControlMod.F90 index 12fce7b3f0..72e7229d0b 100644 --- a/src/dyn_subgrid/dynSubgridControlMod.F90 +++ b/src/dyn_subgrid/dynSubgridControlMod.F90 @@ -320,14 +320,17 @@ subroutine check_namelist_consistency end if if (dyn_subgrid_control_inst%do_grossunrep) then - if (.not. use_cn) then - write(iulog,*) 'ERROR: do_grossunrep can only be true if use_cn is true' - call endrun(msg=errMsg(sourcefile, __LINE__)) - end if + ! First check if use_fates. In this case the .not. use_cn error will not + ! appear. The .not. use_cn error will appea + ! if .not. use_fates and .not. use_cn. if (use_fates) then write(iulog,*) 'ERROR: do_grossunrep currently does not work with use_fates' call endrun(msg=errMsg(sourcefile, __LINE__)) end if + if (.not. use_cn) then + write(iulog,*) 'ERROR: do_grossunrep can only be true if use_cn is true' + call endrun(msg=errMsg(sourcefile, __LINE__)) + end if end if end subroutine check_namelist_consistency From 8ee4aeaee05810764a537ec177e472478de168a1 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 27 Feb 2023 15:54:20 -0700 Subject: [PATCH 24/27] Add additional tests do new do_grossunrepresentedlanduse option --- bld/unit_testers/build-namelist_test.pl | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/bld/unit_testers/build-namelist_test.pl b/bld/unit_testers/build-namelist_test.pl index 1c6d951f0e..8398e8359a 100755 --- a/bld/unit_testers/build-namelist_test.pl +++ b/bld/unit_testers/build-namelist_test.pl @@ -163,7 +163,7 @@ sub cat_and_create_namelistinfile { # # Figure out number of tests that will run # -my $ntests = 1848; +my $ntests = 1850; if ( defined($opts{'compare'}) ) { $ntests += 1254; } @@ -1066,6 +1066,16 @@ sub cat_and_create_namelistinfile { GLC_TWO_WAY_COUPLING=>"FALSE", phys=>"clm5_0", }, + "dogrossandfates" =>{ options=>"-envxml_dir . -bgc fates -use_case 20thC_transient", + namelst=>"do_grossunrep=.true.", + GLC_TWO_WAY_COUPLING=>"FALSE", + phys=>"clm5_0", + }, + "dogrossandnottrans" =>{ options=>"-envxml_dir . -bgc fates -use_case 2000_control", + namelst=>"do_grossunrep=.true.", + GLC_TWO_WAY_COUPLING=>"FALSE", + phys=>"clm5_0", + }, "nocropwfert" =>{ options=>"-envxml_dir . -bgc sp -no-crop", namelst=>"use_fertilizer=T", GLC_TWO_WAY_COUPLING=>"FALSE", From 179de38028116b3a60b60c6d51dc83f90b10d559 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 27 Feb 2023 15:54:59 -0700 Subject: [PATCH 25/27] Change order of if statement so that FATES error will trigger rather than the CN one for it --- bld/CLMBuildNamelist.pm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bld/CLMBuildNamelist.pm b/bld/CLMBuildNamelist.pm index e30b9b83f0..02d9799487 100755 --- a/bld/CLMBuildNamelist.pm +++ b/bld/CLMBuildNamelist.pm @@ -2866,12 +2866,12 @@ sub setup_logic_do_grossunrep { if (string_is_undef_or_empty($nl->get_value('flanduse_timeseries'))) { $cannot_be_true = "$var can only be set to true when running a transient case (flanduse_timeseries non-blank)"; } - elsif (!&value_is_true($nl->get_value('use_cn'))) { - $cannot_be_true = "$var can only be set to true when running with CN (use_cn = true)"; - } elsif (&value_is_true($nl->get_value('use_fates'))) { $cannot_be_true = "$var currently doesn't work with FATES"; } + elsif (!&value_is_true($nl->get_value('use_cn'))) { + $cannot_be_true = "$var can only be set to true when running with CN (use_cn = true)"; + } if ($cannot_be_true) { $default_val = ".false."; From 91bbef6c1da6ae2053487b359c3a5535adafa817 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 27 Feb 2023 17:17:28 -0700 Subject: [PATCH 26/27] Fix the new tests added in --- bld/unit_testers/build-namelist_test.pl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bld/unit_testers/build-namelist_test.pl b/bld/unit_testers/build-namelist_test.pl index 8398e8359a..79add93d88 100755 --- a/bld/unit_testers/build-namelist_test.pl +++ b/bld/unit_testers/build-namelist_test.pl @@ -1061,17 +1061,17 @@ sub cat_and_create_namelistinfile { GLC_TWO_WAY_COUPLING=>"FALSE", phys=>"clm5_0", }, - "dogrossandsp" =>{ options=>"-envxml_dir . -bgc sp -use_case 20thC_transient", + "dogrossandsp" =>{ options=>"--envxml_dir . --bgc sp --use_case 20thC_transient", namelst=>"do_grossunrep=.true.", GLC_TWO_WAY_COUPLING=>"FALSE", phys=>"clm5_0", }, - "dogrossandfates" =>{ options=>"-envxml_dir . -bgc fates -use_case 20thC_transient", + "dogrossandfates" =>{ options=>"--envxml_dir . --bgc fates --use_case 20thC_transient --no-megan", namelst=>"do_grossunrep=.true.", GLC_TWO_WAY_COUPLING=>"FALSE", phys=>"clm5_0", }, - "dogrossandnottrans" =>{ options=>"-envxml_dir . -bgc fates -use_case 2000_control", + "dogrossandnottrans" =>{ options=>"--envxml_dir . --bgc bgc --use_case 2000_control", namelst=>"do_grossunrep=.true.", GLC_TWO_WAY_COUPLING=>"FALSE", phys=>"clm5_0", From deb0866e03dd9dcff47e65ab6dac68216219a846 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Thu, 16 Mar 2023 14:14:00 -0600 Subject: [PATCH 27/27] Update change file --- doc/ChangeLog | 24 +++++++++++++----------- doc/ChangeSum | 2 +- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/doc/ChangeLog b/doc/ChangeLog index 6df1764ff4..a604f675f4 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,13 +1,16 @@ =============================================================== Tag name: ctsm5.1.dev119 Originator(s): slevis (Samuel Levis,SLevis Consulting,303-665-1310), ekluzek Erik Kluzek), lawrencepj1 (Peter Lawrence) -Date: Wed Feb 22 13:57:36 MST 2023 +Date: Thu Mar 16 14:13:37 MDT 2023 One-line Summary: Allow gross unrepresented land use transitions (PR #309) Purpose and description of changes ---------------------------------- - Get gross unrepresented land use transitions working in CLM5.1. + Get gross unrepresented land use transitions working in CLM5.1. This is additional optional + data added to the landuse.timeseries files for transient simulations. The current landuse.timseries + files have this data, but it's set to zero. This data will be part of the CTSM5.2 surface dataset + (that is upcoming) and be on by default for clm5_3 physics. Significant changes to scientifically-supported configurations -------------------------------------------------------------- @@ -30,9 +33,9 @@ hanges.] Bugs fixed or introduced ------------------------ -CTSM issues fixed (include CTSM Issue #): - I didn't find a corresponding issue. - + Known bugs introduced in this tag (include issue #): #1968 + #1968 -- Reduce the GULU tests down to one + Notes of particular relevance for users --------------------------------------- Changes made to namelist defaults (e.g., changed parameter values): @@ -42,11 +45,6 @@ Changes to the datasets (e.g., parameter, surface or initial files): Surface datasets may now contain non-zero gross unrepresented land use transitions. -Substantial timing or memory changes: -[e.g., check PFS test in the test suite and look at timings, if you -expect possible significant timing changes] - - Notes of particular relevance for developers: --------------------------------------------- Changes to tests or testing: @@ -77,7 +75,11 @@ Changes answers relative to baseline: NO (unless see next) Other details ------------- Pull Requests that document the changes (include PR ids): - https://github.com/ESCOMP/ctsm/pull/309 + https://github.com/ESCOMP/ctsm/pull/309 -- Added new files to allow Gross Unrepresented Land Use transition + https://github.com/ESCOMP/ctsm/pull/1965 -- update README + (NOT a PR) Update manage externals + + =============================================================== =============================================================== diff --git a/doc/ChangeSum b/doc/ChangeSum index 66e229d06c..e2bcff8e14 100644 --- a/doc/ChangeSum +++ b/doc/ChangeSum @@ -1,6 +1,6 @@ Tag Who Date Summary ============================================================================================================================ - ctsm5.1.dev119 slevis 02/22/2023 Allow gross unrepresented land use transition (PR #309) + ctsm5.1.dev119 slevis 03/16/2023 Allow gross unrepresented land use transition (PR #309) ctsm5.1.dev118 slevis 02/05/2023 Use conda environment rather than ncar_pylib with the fsurdat_modifier system test ctsm5.1.dev117 afoster 02/02/2023 Updates to facilitate running FATES at NEON sites ctsm5.1.dev116 erik 01/26/2023 Small answer changes with bug fixes, zetamaxstable=2 for BHS, new single point fsurdat files