From ca9c1abc1c4e9991491a555ef5c9e59bab64d816 Mon Sep 17 00:00:00 2001 From: chen693 Date: Fri, 10 Jan 2020 17:01:25 -0800 Subject: [PATCH 01/75] add switchgrass and miscanthus --- src/biogeochem/CNPhenologyMod.F90 | 62 ++++++++++++++++++++++--- src/biogeochem/CNVegStructUpdateMod.F90 | 8 +++- 2 files changed, 63 insertions(+), 7 deletions(-) diff --git a/src/biogeochem/CNPhenologyMod.F90 b/src/biogeochem/CNPhenologyMod.F90 index 400d46e11a..a0c34e7472 100644 --- a/src/biogeochem/CNPhenologyMod.F90 +++ b/src/biogeochem/CNPhenologyMod.F90 @@ -1436,6 +1436,10 @@ subroutine CropPhenology(num_pcropp, filter_pcropp , & use pftconMod , only : ntrp_corn, nsugarcane, ntrp_soybean, ncotton, nrice use pftconMod , only : nirrig_trp_corn, nirrig_sugarcane, nirrig_trp_soybean use pftconMod , only : nirrig_cotton, nirrig_rice + + ! Y. Cheng + use pftconMod , only : nmiscanthus, nirrig_miscanthus, nswitchgrass, nirrig_switchgrass + use clm_varcon , only : spval, secspday use clm_varctl , only : use_fertilizer use clm_varctl , only : use_c13, use_c14 @@ -1728,9 +1732,13 @@ subroutine CropPhenology(num_pcropp, filter_pcropp , & ivt(p) == ntrp_soybean .or. ivt(p) == nirrig_trp_soybean) then gddmaturity(p) = min(gdd1020(p), hybgdd(ivt(p))) end if + + ! Y. Cheng, add switchgrass and Miscanthus if (ivt(p) == ntmp_corn .or. ivt(p) == nirrig_tmp_corn .or. & ivt(p) == ntrp_corn .or. ivt(p) == nirrig_trp_corn .or. & - ivt(p) == nsugarcane .or. ivt(p) == nirrig_sugarcane) then + ivt(p) == nsugarcane .or. ivt(p) == nirrig_sugarcane .or. & + ivt(p) == nmiscanthus .or. ivt(p) == nirrig_miscanthus .or. & + ivt(p) == nswitchgrass .or. ivt(p) == nirrig_switchgrass) then gddmaturity(p) = max(950._r8, min(gdd820(p)*0.85_r8, hybgdd(ivt(p)))) gddmaturity(p) = max(950._r8, min(gddmaturity(p)+150._r8, 1850._r8)) end if @@ -1777,9 +1785,13 @@ subroutine CropPhenology(num_pcropp, filter_pcropp , & ivt(p) == ntrp_soybean .or. ivt(p) == nirrig_trp_soybean) then gddmaturity(p) = min(gdd1020(p), hybgdd(ivt(p))) end if + + ! Y. Cheng, add switchgrass and Miscanthus if (ivt(p) == ntmp_corn .or. ivt(p) == nirrig_tmp_corn .or. & ivt(p) == ntrp_corn .or. ivt(p) == nirrig_trp_corn .or. & - ivt(p) == nsugarcane .or. ivt(p) == nirrig_sugarcane) then + ivt(p) == nsugarcane .or. ivt(p) == nirrig_sugarcane .or. & + ivt(p) == nmiscanthus .or. ivt(p) == nirrig_miscanthus .or. & + ivt(p) == nswitchgrass .or. ivt(p) == nirrig_switchgrass) then gddmaturity(p) = max(950._r8, min(gdd820(p)*0.85_r8, hybgdd(ivt(p)))) end if if (ivt(p) == nswheat .or. ivt(p) == nirrig_swheat .or. & @@ -1838,9 +1850,12 @@ subroutine CropPhenology(num_pcropp, filter_pcropp , & ! calculate linear relationship between huigrain fraction and relative ! maturity rating for maize + ! Y. Cheng, add switchgrass and Miscanthus if (ivt(p) == ntmp_corn .or. ivt(p) == nirrig_tmp_corn .or. & ivt(p) == ntrp_corn .or. ivt(p) == nirrig_trp_corn .or. & - ivt(p) == nsugarcane .or. ivt(p) == nirrig_sugarcane) then + ivt(p) == nsugarcane .or. ivt(p) == nirrig_sugarcane .or. & + ivt(p) == nmiscanthus .or. ivt(p) == nirrig_miscanthus .or. & + ivt(p) == nswitchgrass .or. ivt(p) == nirrig_switchgrass) then ! the following estimation of crmcorn from gddmaturity is based on a linear ! regression using data from Pioneer-brand corn hybrids (Kucharik, 2003, ! Earth Interactions 7:1-33: fig. 2) @@ -2373,6 +2388,9 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, & ! ! !USES: use pftconMod , only : npcropmin + ! Y. Cheng + use pftconMod , only : nmiscanthus, nirrig_miscanthus, nswitchgrass, nirrig_switchgrass + use CNSharedParamsMod, only : use_fun use clm_varctl , only : CNratio_floating ! @@ -2452,8 +2470,22 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, & if (offset_counter(p) == dt) then t1 = 1.0_r8 / dt - leafc_to_litter(p) = t1 * leafc(p) + cpool_to_leafc(p) + !leafc_to_litter(p) = t1 * leafc(p) + cpool_to_leafc(p) frootc_to_litter(p) = t1 * frootc(p) + cpool_to_frootc(p) + + ! Y. Cheng, cut 70% AGB for switchgrass and Miscanthus and move to grainc_to_food + if (ivt(p)==nmiscanthus .or. ivt(p)==nirrig_miscanthus .or. ivt(p)==nswitchgrass .or. ivt(p)==nirrig_switchgrass) then + leafc_to_litter(p) = t1 * leafc(p)*0.3 + cpool_to_leafc(p) + grainc_to_food(p) =grainc_to_food(p)+ t1 * leafc(p) * 0.7 + grainn_to_food(p) =grainn_to_food(p)+ t1 * leafn(p) * 0.7 + +! leafc_to_litter(p) = (t1 * leafc(p) + cpool_to_leafc(p))*0.3 +! grainc_to_food(p) =grainc_to_food(p)+ (t1 * leafc(p) + cpool_to_leafc(p))*0.7 +! grainn_to_food(p) =grainn_to_food(p)+ t1 * leafn(p) * 0.7 + else + leafc_to_litter(p) = t1 * leafc(p) + cpool_to_leafc(p) + end if + ! this assumes that offset_counter == dt for crops ! if this were ever changed, we'd need to add code to the "else" if (ivt(p) >= npcropmin) then @@ -2464,8 +2496,15 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, & grainc_to_seed(p) = t1 * min(-cropseedc_deficit(p), grainc(p)) grainn_to_seed(p) = t1 * min(-cropseedn_deficit(p), grainn(p)) ! Send the remaining grain to the food product pool - grainc_to_food(p) = t1 * grainc(p) + cpool_to_grainc(p) - grainc_to_seed(p) - grainn_to_food(p) = t1 * grainn(p) + npool_to_grainn(p) - grainn_to_seed(p) + + ! Y. Cheng, because I calculated grainc_to_food and grainn_to_food earlier + if (ivt(p)==nmiscanthus .or. ivt(p)==nirrig_miscanthus .or. ivt(p)==nswitchgrass .or. ivt(p)==nirrig_switchgrass) then + grainc_to_food(p) = grainc_to_food(p) + t1 * grainc(p) + cpool_to_grainc(p) - grainc_to_seed(p) + grainn_to_food(p) = grainn_to_food(p) + t1 * grainn(p) + npool_to_grainn(p) - grainn_to_seed(p) + else + grainc_to_food(p) = t1 * grainc(p) + cpool_to_grainc(p) - grainc_to_seed(p) + grainn_to_food(p) = t1 * grainn(p) + npool_to_grainn(p) - grainn_to_seed(p) + end if livestemc_to_litter(p) = t1 * livestemc(p) + cpool_to_livestemc(p) end if @@ -2556,6 +2595,17 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, & prev_leafc_to_litter(p) = leafc_to_litter(p) prev_frootc_to_litter(p) = frootc_to_litter(p) + + ! Y. Cheng, cut 70% AGB for switchgrass and Miscanthus + if (offset_counter(p) == dt) then + if (ivt(p)==nmiscanthus .or. ivt(p)==nirrig_miscanthus .or. ivt(p)==nswitchgrass .or. ivt(p)==nirrig_switchgrass) then + grainc(p) = grainc(p) + leafc(p)*0.7 + leafc(p) = leafc(p) * 0.3 + grainn(p) = grainn(p) + leafn(p)*0.7 + leafn(p) = leafn(p) * 0.3 + end if + end if + end if ! end if offset period end do ! end patch loop diff --git a/src/biogeochem/CNVegStructUpdateMod.F90 b/src/biogeochem/CNVegStructUpdateMod.F90 index 6a990ce89a..b3556a367e 100644 --- a/src/biogeochem/CNVegStructUpdateMod.F90 +++ b/src/biogeochem/CNVegStructUpdateMod.F90 @@ -41,6 +41,9 @@ subroutine CNVegStructUpdate(num_soilp, filter_soilp, & use pftconMod , only : ntmp_corn, nirrig_tmp_corn use pftconMod , only : ntrp_corn, nirrig_trp_corn use pftconMod , only : nsugarcane, nirrig_sugarcane + ! Y. Cheng + use pftconMod , only : nmiscanthus, nirrig_miscanthus, nswitchgrass, nirrig_switchgrass + use pftconMod , only : pftcon use clm_varctl , only : spinup_state use clm_time_manager , only : get_rad_step_size @@ -230,9 +233,12 @@ subroutine CNVegStructUpdate(num_soilp, filter_soilp, & if (tlai(p) >= laimx(ivt(p))) peaklai(p) = 1 ! used in CNAllocation + ! Y. Cheng, add switchgrass and Miscanthus if (ivt(p) == ntmp_corn .or. ivt(p) == nirrig_tmp_corn .or. & ivt(p) == ntrp_corn .or. ivt(p) == nirrig_trp_corn .or. & - ivt(p) == nsugarcane .or. ivt(p) == nirrig_sugarcane) then + ivt(p) == nsugarcane .or. ivt(p) == nirrig_sugarcane .or. & + ivt(p) == nmiscanthus .or. ivt(p) == nirrig_miscanthus .or. & + ivt(p) == nswitchgrass .or. ivt(p) == nirrig_switchgrass) then tsai(p) = 0.1_r8 * tlai(p) else tsai(p) = 0.2_r8 * tlai(p) From cf476b41f384cdc10fcb7a3ecf2f953113eef1c3 Mon Sep 17 00:00:00 2001 From: chen693 Date: Mon, 24 Feb 2020 13:57:52 -0800 Subject: [PATCH 02/75] add a parameter for cutting a certain fraction of crop leaf biomass at harvest --- src/main/pftconMod.F90 | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/pftconMod.F90 b/src/main/pftconMod.F90 index 27a61403bc..4e5e60b3bb 100644 --- a/src/main/pftconMod.F90 +++ b/src/main/pftconMod.F90 @@ -134,6 +134,7 @@ module pftconMod real(r8), allocatable :: slatop (:) ! SLA at top of canopy [m^2/gC] real(r8), allocatable :: dsladlai (:) ! dSLA/dLAI [m^2/gC] real(r8), allocatable :: leafcn (:) ! leaf C:N [gC/gN] + real(r8), allocatable :: harvfrac (:) ! cut fraction for harvest [-] real(r8), allocatable :: flnr (:) ! fraction of leaf N in Rubisco [no units] real(r8), allocatable :: woody (:) ! woody lifeform flag (0 or 1) real(r8), allocatable :: lflitcn (:) ! leaf litter C:N (gC/gN) @@ -356,7 +357,8 @@ subroutine InitAllocate (this) allocate( this%fnitr (0:mxpft) ) allocate( this%slatop (0:mxpft) ) allocate( this%dsladlai (0:mxpft) ) - allocate( this%leafcn (0:mxpft) ) + allocate( this%leafcn (0:mxpft) ) + allocate( this%harvfrac (0:mxpft) ) allocate( this%flnr (0:mxpft) ) allocate( this%woody (0:mxpft) ) allocate( this%lflitcn (0:mxpft) ) @@ -658,6 +660,10 @@ subroutine InitRead(this) call ncd_io('leafcn', this%leafcn, 'read', ncid, readvar=readv, posNOTonfile=.true.) if ( .not. readv ) call endrun(msg=' ERROR: error in reading in pft data'//errMsg(sourcefile, __LINE__)) + + ! Y. Cheng, harvest fraction for crops during offset period + call ncd_io('harvfrac', this%harvfrac, 'read', ncid, readvar=readv, posNOTonfile=.true.) + if ( .not. readv ) call endrun(msg=' ERROR: error in reading in pft data'//errMsg(sourcefile, __LINE__)) call ncd_io('flnr', this%flnr, 'read', ncid, readvar=readv, posNOTonfile=.true.) if ( .not. readv ) call endrun(msg=' ERROR: error in reading in pft data'//errMsg(sourcefile, __LINE__)) @@ -1282,6 +1288,7 @@ subroutine Clean(this) deallocate( this%slatop) deallocate( this%dsladlai) deallocate( this%leafcn) + deallocate( this%harvfrac) deallocate( this%flnr) deallocate( this%woody) deallocate( this%lflitcn) From da3b1a0ac0e9b4d10596e108b3faf1e8af5676d1 Mon Sep 17 00:00:00 2001 From: chen693 Date: Mon, 24 Feb 2020 14:02:38 -0800 Subject: [PATCH 03/75] add a new biofuelc_harvest flux to store the cut fraction of crop carbon during offset period --- src/biogeochem/CNVegCarbonFluxType.F90 | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/biogeochem/CNVegCarbonFluxType.F90 b/src/biogeochem/CNVegCarbonFluxType.F90 index 5729a1a9f2..5a5aa3f448 100644 --- a/src/biogeochem/CNVegCarbonFluxType.F90 +++ b/src/biogeochem/CNVegCarbonFluxType.F90 @@ -134,6 +134,10 @@ module CNVegCarbonFluxType real(r8), pointer :: frootc_to_litter_patch (:) ! fine root C litterfall (gC/m2/s) real(r8), pointer :: livestemc_to_litter_patch (:) ! live stem C litterfall (gC/m2/s) real(r8), pointer :: grainc_to_food_patch (:) ! grain C to food for prognostic crop(gC/m2/s) + + ! Y. Cheng + real(r8), pointer :: biofuelc_harvest_patch (:) ! biofuel C for bioenergy crops that are harvested (gC/m2/s) + real(r8), pointer :: grainc_to_seed_patch (:) ! grain C to seed for prognostic crop(gC/m2/s) ! maintenance respiration fluxes @@ -596,6 +600,7 @@ subroutine InitAllocate(this, bounds, carbon_type) allocate(this%cpool_to_grainc_storage_patch (begp:endp)) ; this%cpool_to_grainc_storage_patch (:) = nan allocate(this%livestemc_to_litter_patch (begp:endp)) ; this%livestemc_to_litter_patch (:) = nan allocate(this%grainc_to_food_patch (begp:endp)) ; this%grainc_to_food_patch (:) = nan + allocate(this%biofuelc_harvest_patch (begp:endp)) ; this%biofuelc_harvest_patch (:) = nan allocate(this%grainc_to_seed_patch (begp:endp)) ; this%grainc_to_seed_patch (:) = nan allocate(this%grainc_xfer_to_grainc_patch (begp:endp)) ; this%grainc_xfer_to_grainc_patch (:) = nan allocate(this%cpool_grain_gr_patch (begp:endp)) ; this%cpool_grain_gr_patch (:) = nan @@ -825,6 +830,13 @@ subroutine InitHistory(this, bounds, carbon_type) avgflag='A', long_name='grain C to food', & ptr_patch=this%grainc_to_food_patch) + ! Y. Cheng + this%biofuelc_harvest_patch(begp:endp) = spval + call hist_addfld1d (fname='BIOFUELC_HARVEST', units='gC/m^2/s', & + avgflag='A', long_name='biofuel C harvest', & + ptr_patch=this%biofuelc_harvest_patch) + + this%grainc_to_seed_patch(begp:endp) = spval call hist_addfld1d (fname='GRAINC_TO_SEED', units='gC/m^2/s', & avgflag='A', long_name='grain C to seed', & @@ -3511,6 +3523,13 @@ subroutine RestartBulkOnly ( this, bounds, ncid, flag ) dim1name='pft', & long_name='grain C to food', units='gC/m2/s', & interpinic_flag='interp', readvar=readvar, data=this%grainc_to_food_patch) + + + ! Y. Cheng + call restartvar(ncid=ncid, flag=flag, varname='biofuelc_harvest', xtype=ncd_double, & + dim1name='pft', & + long_name='biofuelc harvest', units='gC/m2/s', & + interpinic_flag='interp', readvar=readvar, data=this%biofuelc_harvest_patch) call restartvar(ncid=ncid, flag=flag, varname='cpool_to_grainc', xtype=ncd_double, & dim1name='pft', & @@ -3848,6 +3867,9 @@ subroutine SetValues ( this, & this%xsmrpool_to_atm_patch(i) = value_patch this%livestemc_to_litter_patch(i) = value_patch this%grainc_to_food_patch(i) = value_patch + + this%biofuelc_harvest_patch(i) = value_patch + this%grainc_to_seed_patch(i) = value_patch this%grainc_xfer_to_grainc_patch(i) = value_patch this%cpool_to_grainc_patch(i) = value_patch @@ -4292,7 +4314,8 @@ subroutine Summary_carbonflux(this, & if (.not. use_grainproduct) then this%litfall_patch(p) = & this%litfall_patch(p) + & - this%grainc_to_food_patch(p) + this%grainc_to_food_patch(p) + & + this%biofuelc_harvest_patch(p) !Y.Cheng end if end if From 32db2413c712d755c760128fa8256cc343e12e31 Mon Sep 17 00:00:00 2001 From: chen693 Date: Mon, 24 Feb 2020 14:03:27 -0800 Subject: [PATCH 04/75] add calculation for the new biofuelc_harvest flux --- src/biogeochem/CNCIsoFluxMod.F90 | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/biogeochem/CNCIsoFluxMod.F90 b/src/biogeochem/CNCIsoFluxMod.F90 index 07e693c540..8c79e50d33 100644 --- a/src/biogeochem/CNCIsoFluxMod.F90 +++ b/src/biogeochem/CNCIsoFluxMod.F90 @@ -404,6 +404,13 @@ subroutine CIsoFlux1(num_soilc, filter_soilc, num_soilp, filter_soilp, & iso_cnveg_cs%grainc_patch , cnveg_cs%grainc_patch, & num_soilp , filter_soilp, 1._r8, 0, isotope) + ! Y. Cheng + call CIsoFluxCalc(& + iso_cnveg_cf%biofuelc_harvest_patch , cnveg_cf%biofuelc_harvest_patch, & + iso_cnveg_cs%grainc_patch , cnveg_cs%grainc_patch, & + num_soilp , filter_soilp, 1._r8, 0, isotope) + + call CIsoFluxCalc(& iso_cnveg_cf%grainc_to_seed_patch , cnveg_cf%grainc_to_seed_patch, & iso_cnveg_cs%grainc_patch , cnveg_cs%grainc_patch, & @@ -1193,6 +1200,9 @@ subroutine CNCIsoLitterToColumn (num_soilc, filter_soilc, & !DML livestemc_to_litter => iso_cnveg_carbonflux_inst%livestemc_to_litter_patch , & ! Input: [real(r8) (:) ] grainc_to_food => iso_cnveg_carbonflux_inst%grainc_to_food_patch , & ! Input: [real(r8) (:) ] + + ! Y. Cheng + biofuelc_harvest => iso_cnveg_carbonflux_inst%biofuelc_harvest_patch , & ! Input: [real(r8) (:) ] !DML phenology_c_to_litr_met_c => iso_cnveg_carbonflux_inst%phenology_c_to_litr_met_c_col , & ! InOut: [real(r8) (:,:) ] C fluxes associated with phenology (litterfall and crop) to litter metabolic pool (gC/m3/s) phenology_c_to_litr_cel_c => iso_cnveg_carbonflux_inst%phenology_c_to_litr_cel_c_col , & ! InOut: [real(r8) (:,:) ] C fluxes associated with phenology (litterfall and crop) to litter cellulose pool (gC/m3/s) @@ -1232,15 +1242,18 @@ subroutine CNCIsoLitterToColumn (num_soilc, filter_soilc, & + livestemc_to_litter(p) * lf_fcel(ivt(p)) * wtcol(p) * leaf_prof(p,j) phenology_c_to_litr_lig_c(c,j) = phenology_c_to_litr_lig_c(c,j) & + livestemc_to_litter(p) * lf_flig(ivt(p)) * wtcol(p) * leaf_prof(p,j) - + ! Y. Cheng if (.not. use_grainproduct) then ! grain litter carbon fluxes phenology_c_to_litr_met_c(c,j) = phenology_c_to_litr_met_c(c,j) & - + grainc_to_food(p) * lf_flab(ivt(p)) * wtcol(p) * leaf_prof(p,j) + + grainc_to_food(p) * lf_flab(ivt(p)) * wtcol(p) * leaf_prof(p,j) & + + biofuelc_harvest(p) * lf_flab(ivt(p)) * wtcol(p) * leaf_prof(p,j) phenology_c_to_litr_cel_c(c,j) = phenology_c_to_litr_cel_c(c,j) & - + grainc_to_food(p) * lf_fcel(ivt(p)) * wtcol(p) * leaf_prof(p,j) + + grainc_to_food(p) * lf_fcel(ivt(p)) * wtcol(p) * leaf_prof(p,j) & + + biofuelc_harvest(p) * lf_fcel(ivt(p)) * wtcol(p) * leaf_prof(p,j) phenology_c_to_litr_lig_c(c,j) = phenology_c_to_litr_lig_c(c,j) & - + grainc_to_food(p) * lf_flig(ivt(p)) * wtcol(p) * leaf_prof(p,j) + + grainc_to_food(p) * lf_flig(ivt(p)) * wtcol(p) * leaf_prof(p,j) & + + biofuelc_harvest(p) * lf_flig(ivt(p)) * wtcol(p) * leaf_prof(p,j) end if end if From 526b28d48ae9acefb210dfb10d4564cf54587b35 Mon Sep 17 00:00:00 2001 From: chen693 Date: Mon, 24 Feb 2020 14:04:06 -0800 Subject: [PATCH 05/75] add a new biofueln_harvest flux to store the cut fraction of crop nitrogen during offset period --- src/biogeochem/CNVegNitrogenFluxType.F90 | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/biogeochem/CNVegNitrogenFluxType.F90 b/src/biogeochem/CNVegNitrogenFluxType.F90 index f9f2b37215..edfa857998 100644 --- a/src/biogeochem/CNVegNitrogenFluxType.F90 +++ b/src/biogeochem/CNVegNitrogenFluxType.F90 @@ -131,6 +131,7 @@ module CNVegNitrogenFluxType ! litterfall fluxes real(r8), pointer :: livestemn_to_litter_patch (:) ! patch livestem N to litter (gN/m2/s) real(r8), pointer :: grainn_to_food_patch (:) ! patch grain N to food for prognostic crop (gN/m2/s) + real(r8), pointer :: biofueln_harvest_patch (:) ! patch biofuel N for bioenergy crops that are harvested (gN/m2/s) real(r8), pointer :: grainn_to_seed_patch (:) ! patch grain N to seed for prognostic crop (gN/m2/s) real(r8), pointer :: leafn_to_litter_patch (:) ! patch leaf N litterfall (gN/m2/s) real(r8), pointer :: leafn_to_retransn_patch (:) ! patch leaf N to retranslocated N pool (gN/m2/s) @@ -413,6 +414,7 @@ subroutine InitAllocate(this, bounds) allocate(this%npool_to_grainn_storage_patch (begp:endp)) ; this%npool_to_grainn_storage_patch (:) = nan allocate(this%livestemn_to_litter_patch (begp:endp)) ; this%livestemn_to_litter_patch (:) = nan allocate(this%grainn_to_food_patch (begp:endp)) ; this%grainn_to_food_patch (:) = nan + allocate(this%biofueln_harvest_patch (begp:endp)) ; this%biofueln_harvest_patch (:) = nan allocate(this%grainn_to_seed_patch (begp:endp)) ; this%grainn_to_seed_patch (:) = nan allocate(this%grainn_xfer_to_grainn_patch (begp:endp)) ; this%grainn_xfer_to_grainn_patch (:) = nan allocate(this%grainn_storage_to_xfer_patch (begp:endp)) ; this%grainn_storage_to_xfer_patch (:) = nan @@ -1370,6 +1372,13 @@ subroutine Restart (this, bounds, ncid, flag ) long_name='grain N to food', units='gN/m2/s', & interpinic_flag='interp', readvar=readvar, data=this%grainn_to_food_patch) end if + + if (use_crop) then + call restartvar(ncid=ncid, flag=flag, varname='biofueln_harvest', xtype=ncd_double, & + dim1name='pft', & + long_name='biofuel N harvested', units='gN/m2/s', & + interpinic_flag='interp', readvar=readvar, data=this%biofueln_harvest_patch) + end if if (use_crop) then call restartvar(ncid=ncid, flag=flag, varname='npool_to_grainn', xtype=ncd_double, & @@ -1679,6 +1688,7 @@ subroutine SetValues ( this, & i = filter_patch(fi) this%livestemn_to_litter_patch(i) = value_patch this%grainn_to_food_patch(i) = value_patch + this%biofueln_harvest_patch(i) = value_patch this%grainn_to_seed_patch(i) = value_patch this%grainn_xfer_to_grainn_patch(i) = value_patch this%npool_to_grainn_patch(i) = value_patch From c71986216540425deb5c8178023d9ae6e8f6638a Mon Sep 17 00:00:00 2001 From: chen693 Date: Mon, 24 Feb 2020 14:29:44 -0800 Subject: [PATCH 06/75] cut a certain fraction of crop leaf biomass during offset period --- ...PhenologyMod_cut_newFlux_newCutParam_N.F90 | 3060 +++++++++++++++++ 1 file changed, 3060 insertions(+) create mode 100644 src/biogeochem/CNPhenologyMod_cut_newFlux_newCutParam_N.F90 diff --git a/src/biogeochem/CNPhenologyMod_cut_newFlux_newCutParam_N.F90 b/src/biogeochem/CNPhenologyMod_cut_newFlux_newCutParam_N.F90 new file mode 100644 index 0000000000..3079f12670 --- /dev/null +++ b/src/biogeochem/CNPhenologyMod_cut_newFlux_newCutParam_N.F90 @@ -0,0 +1,3060 @@ +module CNPhenologyMod + +#include "shr_assert.h" + + !----------------------------------------------------------------------- + ! !MODULE: CNPhenologyMod + ! + ! !DESCRIPTION: + ! Module holding routines used in phenology model for coupled carbon + ! nitrogen code. + ! + ! !USES: + use shr_kind_mod , only : r8 => shr_kind_r8 + use shr_log_mod , only : errMsg => shr_log_errMsg + use shr_sys_mod , only : shr_sys_flush + use decompMod , only : bounds_type + use clm_varpar , only : maxveg, nlevdecomp_full + use clm_varctl , only : iulog, use_cndv + use clm_varcon , only : tfrz + use abortutils , only : endrun + use CanopyStateType , only : canopystate_type + use CNDVType , only : dgvs_type + use CNVegstateType , only : cnveg_state_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 CropType , only : crop_type + use pftconMod , only : pftcon + use SoilStateType , only : soilstate_type + use TemperatureType , only : temperature_type + use WaterDiagnosticBulkType , only : waterdiagnosticbulk_type + use Wateratm2lndBulkType , only : wateratm2lndbulk_type + use ColumnType , only : col + use GridcellType , only : grc + use PatchType , only : patch + use atm2lndType , only : atm2lnd_type + use atm2lndType , only : atm2lnd_type + ! + implicit none + private + ! + ! !PUBLIC MEMBER FUNCTIONS: + public :: readParams ! Read parameters + public :: CNPhenologyreadNML ! Read namelist + public :: CNPhenologyInit ! Initialization + public :: CNPhenology ! Update + ! + ! !PRIVATE DATA MEMBERS: + type, private :: params_type + real(r8) :: crit_dayl ! critical day length for senescence + real(r8) :: ndays_on ! number of days to complete leaf onset + real(r8) :: ndays_off ! number of days to complete leaf offset + real(r8) :: fstor2tran ! fraction of storage to move to transfer for each onset + real(r8) :: crit_onset_fdd ! critical number of freezing days to set gdd counter + real(r8) :: crit_onset_swi ! critical number of days > soilpsi_on for onset + real(r8) :: soilpsi_on ! critical soil water potential for leaf onset + real(r8) :: crit_offset_fdd ! critical number of freezing days to initiate offset + real(r8) :: crit_offset_swi ! critical number of water stress days to initiate offset + real(r8) :: soilpsi_off ! critical soil water potential for leaf offset + real(r8) :: lwtop ! live wood turnover proportion (annual fraction) + end type params_type + + type(params_type) :: params_inst + + real(r8) :: dt ! radiation time step delta t (seconds) + real(r8) :: fracday ! dtime as a fraction of day + real(r8) :: crit_dayl ! critical daylength for offset (seconds) + real(r8) :: ndays_on ! number of days to complete onset + real(r8) :: ndays_off ! number of days to complete offset + real(r8) :: fstor2tran ! fraction of storage to move to transfer on each onset + real(r8) :: crit_onset_fdd ! critical number of freezing days + real(r8) :: crit_onset_swi ! water stress days for offset trigger + real(r8) :: soilpsi_on ! water potential for onset trigger (MPa) + real(r8) :: crit_offset_fdd ! critical number of freezing degree days to trigger offset + real(r8) :: crit_offset_swi ! water stress days for offset trigger + real(r8) :: soilpsi_off ! water potential for offset trigger (MPa) + real(r8) :: lwtop ! live wood turnover proportion (annual fraction) + + ! CropPhenology variables and constants + real(r8) :: p1d, p1v ! photoperiod factor constants for crop vernalization + real(r8) :: hti ! cold hardening index threshold for vernalization + real(r8) :: tbase ! base temperature for vernalization + + integer, parameter :: NOT_Planted = 999 ! If not planted yet in year + integer, parameter :: NOT_Harvested = 999 ! If not harvested yet in year + integer, parameter :: inNH = 1 ! Northern Hemisphere + integer, parameter :: inSH = 2 ! Southern Hemisphere + integer, pointer :: inhemi(:) ! Hemisphere that patch is in + + integer, allocatable :: minplantjday(:,:) ! minimum planting julian day + integer, allocatable :: maxplantjday(:,:) ! maximum planting julian day + integer :: jdayyrstart(inSH) ! julian day of start of year + + real(r8), private :: initial_seed_at_planting = 3._r8 ! Initial seed at planting + + character(len=*), parameter, private :: sourcefile = & + __FILE__ + !----------------------------------------------------------------------- + +contains + + !----------------------------------------------------------------------- + subroutine CNPhenologyReadNML( NLFilename ) + ! + ! !DESCRIPTION: + ! Read the namelist for CNPhenology + ! + ! !USES: + use fileutils , only : getavu, relavu, opnfil + use shr_nl_mod , only : shr_nl_find_group_name + use spmdMod , only : masterproc, mpicom + use shr_mpi_mod , only : shr_mpi_bcast + use clm_varctl , only : iulog + ! + ! !ARGUMENTS: + character(len=*), intent(in) :: NLFilename ! Namelist filename + ! + ! !LOCAL VARIABLES: + integer :: ierr ! error code + integer :: unitn ! unit for namelist file + + character(len=*), parameter :: subname = 'CNPhenologyReadNML' + character(len=*), parameter :: nmlname = 'cnphenology' + !----------------------------------------------------------------------- + namelist /cnphenology/ initial_seed_at_planting + + ! Initialize options to default values, in case they are not specified in + ! the namelist + + if (masterproc) then + unitn = getavu() + write(iulog,*) 'Read in '//nmlname//' namelist' + call opnfil (NLFilename, unitn, 'F') + call shr_nl_find_group_name(unitn, nmlname, status=ierr) + if (ierr == 0) then + read(unitn, nml=cnphenology, iostat=ierr) + if (ierr /= 0) then + call endrun(msg="ERROR reading "//nmlname//"namelist"//errmsg(sourcefile, __LINE__)) + end if + else + call endrun(msg="ERROR could NOT find "//nmlname//"namelist"//errmsg(sourcefile, __LINE__)) + end if + call relavu( unitn ) + end if + + call shr_mpi_bcast (initial_seed_at_planting, mpicom) + + if (masterproc) then + write(iulog,*) ' ' + write(iulog,*) nmlname//' settings:' + write(iulog,nml=cnphenology) + write(iulog,*) ' ' + end if + + + !----------------------------------------------------------------------- + + end subroutine CNPhenologyReadNML + + !----------------------------------------------------------------------- + subroutine readParams ( ncid ) + ! + ! !DESCRIPTION: + ! + ! !USES: + use ncdio_pio , only: file_desc_t,ncd_io + + ! !ARGUMENTS: + implicit none + type(file_desc_t),intent(inout) :: ncid ! pio netCDF file id + ! + ! !LOCAL VARIABLES: + character(len=32) :: subname = 'CNPhenolParamsType' + character(len=100) :: errCode = '-Error reading in parameters file:' + logical :: readv ! has variable been read in or not + real(r8) :: tempr ! temporary to read in parameter + character(len=100) :: tString ! temp. var for reading + !----------------------------------------------------------------------- + + ! + ! read in parameters + ! + tString='crit_dayl' + call ncd_io(varname=trim(tString),data=tempr, flag='read', ncid=ncid, readvar=readv) + if ( .not. readv ) call endrun( msg=trim(errCode)//trim(tString)//errMsg(sourcefile, __LINE__)) + params_inst%crit_dayl=tempr + + tString='ndays_on' + call ncd_io(varname=trim(tString),data=tempr, flag='read', ncid=ncid, readvar=readv) + if ( .not. readv ) call endrun( msg=trim(errCode)//trim(tString)//errMsg(sourcefile, __LINE__)) + params_inst%ndays_on=tempr + + tString='ndays_off' + call ncd_io(varname=trim(tString),data=tempr, flag='read', ncid=ncid, readvar=readv) + if ( .not. readv ) call endrun( msg=trim(errCode)//trim(tString)//errMsg(sourcefile, __LINE__)) + params_inst%ndays_off=tempr + + tString='fstor2tran' + call ncd_io(varname=trim(tString),data=tempr, flag='read', ncid=ncid, readvar=readv) + if ( .not. readv ) call endrun( msg=trim(errCode)//trim(tString)//errMsg(sourcefile, __LINE__)) + params_inst%fstor2tran=tempr + + tString='crit_onset_fdd' + call ncd_io(varname=trim(tString),data=tempr, flag='read', ncid=ncid, readvar=readv) + if ( .not. readv ) call endrun( msg=trim(errCode)//trim(tString)//errMsg(sourcefile, __LINE__)) + params_inst%crit_onset_fdd=tempr + + tString='crit_onset_swi' + call ncd_io(varname=trim(tString),data=tempr, flag='read', ncid=ncid, readvar=readv) + if ( .not. readv ) call endrun( msg=trim(errCode)//trim(tString)//errMsg(sourcefile, __LINE__)) + params_inst%crit_onset_swi=tempr + + tString='soilpsi_on' + call ncd_io(varname=trim(tString),data=tempr, flag='read', ncid=ncid, readvar=readv) + if ( .not. readv ) call endrun( msg=trim(errCode)//trim(tString)//errMsg(sourcefile, __LINE__)) + params_inst%soilpsi_on=tempr + + tString='crit_offset_fdd' + call ncd_io(varname=trim(tString),data=tempr, flag='read', ncid=ncid, readvar=readv) + if ( .not. readv ) call endrun( msg=trim(errCode)//trim(tString)//errMsg(sourcefile, __LINE__)) + params_inst%crit_offset_fdd=tempr + + tString='crit_offset_swi' + call ncd_io(varname=trim(tString),data=tempr, flag='read', ncid=ncid, readvar=readv) + if ( .not. readv ) call endrun( msg=trim(errCode)//trim(tString)//errMsg(sourcefile, __LINE__)) + params_inst%crit_offset_swi=tempr + + tString='soilpsi_off' + call ncd_io(varname=trim(tString),data=tempr, flag='read', ncid=ncid, readvar=readv) + if ( .not. readv ) call endrun( msg=trim(errCode)//trim(tString)//errMsg(sourcefile, __LINE__)) + params_inst%soilpsi_off=tempr + + tString='lwtop_ann' + call ncd_io(varname=trim(tString),data=tempr, flag='read', ncid=ncid, readvar=readv) + if ( .not. readv ) call endrun( msg=trim(errCode)//trim(tString)//errMsg(sourcefile, __LINE__)) + params_inst%lwtop=tempr + + end subroutine readParams + + !----------------------------------------------------------------------- + subroutine CNPhenology (bounds, num_soilc, filter_soilc, num_soilp, & + filter_soilp, num_pcropp, filter_pcropp, & + doalb, waterdiagnosticbulk_inst, wateratm2lndbulk_inst, temperature_inst, atm2lnd_inst, crop_inst, & + canopystate_inst, soilstate_inst, dgvs_inst, & + cnveg_state_inst, cnveg_carbonstate_inst, cnveg_carbonflux_inst, & + cnveg_nitrogenstate_inst, cnveg_nitrogenflux_inst, & + c13_cnveg_carbonstate_inst, c14_cnveg_carbonstate_inst, & + leaf_prof_patch, froot_prof_patch, phase) + ! !USES: + use CNSharedParamsMod, only: use_fun + ! + ! !DESCRIPTION: + ! Dynamic phenology routine for coupled carbon-nitrogen code (CN) + ! 1. grass phenology + ! + ! !ARGUMENTS: + type(bounds_type) , intent(in) :: bounds + 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 + integer , intent(in) :: num_pcropp ! number of prog. crop patches in filter + integer , intent(in) :: filter_pcropp(:)! filter for prognostic crop patches + logical , intent(in) :: doalb ! true if time for sfc albedo calc + type(waterdiagnosticbulk_type) , intent(in) :: waterdiagnosticbulk_inst + type(wateratm2lndbulk_type) , intent(in) :: wateratm2lndbulk_inst + type(temperature_type) , intent(inout) :: temperature_inst + type(atm2lnd_type) , intent(in) :: atm2lnd_inst + type(crop_type) , intent(inout) :: crop_inst + type(canopystate_type) , intent(in) :: canopystate_inst + type(soilstate_type) , intent(in) :: soilstate_inst + type(dgvs_type) , intent(inout) :: dgvs_inst + type(cnveg_state_type) , intent(inout) :: cnveg_state_inst + type(cnveg_carbonstate_type) , intent(inout) :: cnveg_carbonstate_inst + type(cnveg_carbonflux_type) , intent(inout) :: cnveg_carbonflux_inst + type(cnveg_nitrogenstate_type) , intent(inout) :: cnveg_nitrogenstate_inst + type(cnveg_nitrogenflux_type) , intent(inout) :: cnveg_nitrogenflux_inst + type(cnveg_carbonstate_type) , intent(inout) :: c13_cnveg_carbonstate_inst + type(cnveg_carbonstate_type) , intent(inout) :: c14_cnveg_carbonstate_inst + real(r8) , intent(in) :: leaf_prof_patch(bounds%begp:,1:) + real(r8) , intent(in) :: froot_prof_patch(bounds%begp:,1:) + integer , intent(in) :: phase + !----------------------------------------------------------------------- + + SHR_ASSERT_ALL_FL((ubound(leaf_prof_patch) == (/bounds%endp,nlevdecomp_full/)), sourcefile, __LINE__) + SHR_ASSERT_ALL_FL((ubound(froot_prof_patch) == (/bounds%endp,nlevdecomp_full/)), sourcefile, __LINE__) + + ! each of the following phenology type routines includes a filter + ! to operate only on the relevant patches + + + if ( phase == 1 ) then + call CNPhenologyClimate(num_soilp, filter_soilp, num_pcropp, filter_pcropp, & + temperature_inst, cnveg_state_inst, crop_inst) + + call CNEvergreenPhenology(num_soilp, filter_soilp, & + cnveg_state_inst, cnveg_carbonstate_inst, cnveg_nitrogenstate_inst, cnveg_carbonflux_inst, cnveg_nitrogenflux_inst) + + call CNSeasonDecidPhenology(num_soilp, filter_soilp, & + temperature_inst, cnveg_state_inst, dgvs_inst, & + cnveg_carbonstate_inst, cnveg_nitrogenstate_inst, cnveg_carbonflux_inst, cnveg_nitrogenflux_inst) + + call CNStressDecidPhenology(num_soilp, filter_soilp, & + soilstate_inst, temperature_inst, atm2lnd_inst, wateratm2lndbulk_inst, cnveg_state_inst, & + cnveg_carbonstate_inst, cnveg_nitrogenstate_inst, cnveg_carbonflux_inst, cnveg_nitrogenflux_inst) + + if (doalb .and. num_pcropp > 0 ) then + call CropPhenology(num_pcropp, filter_pcropp, & + waterdiagnosticbulk_inst, temperature_inst, crop_inst, canopystate_inst, cnveg_state_inst, & + cnveg_carbonstate_inst, cnveg_nitrogenstate_inst, cnveg_carbonflux_inst, cnveg_nitrogenflux_inst, & + c13_cnveg_carbonstate_inst, c14_cnveg_carbonstate_inst) + end if + else if ( phase == 2 ) then + ! the same onset and offset routines are called regardless of + ! phenology type - they depend only on onset_flag, offset_flag, bglfr, and bgtr + + call CNOnsetGrowth(num_soilp, filter_soilp, & + cnveg_state_inst, & + cnveg_carbonstate_inst, cnveg_nitrogenstate_inst, cnveg_carbonflux_inst, cnveg_nitrogenflux_inst) + + call CNOffsetLitterfall(num_soilp, filter_soilp, & + cnveg_state_inst, cnveg_carbonstate_inst, cnveg_nitrogenstate_inst, cnveg_carbonflux_inst, cnveg_nitrogenflux_inst) + + call CNBackgroundLitterfall(num_soilp, filter_soilp, & + cnveg_state_inst, cnveg_carbonstate_inst, cnveg_nitrogenstate_inst, cnveg_carbonflux_inst, cnveg_nitrogenflux_inst) + + call CNLivewoodTurnover(num_soilp, filter_soilp, & + cnveg_carbonstate_inst, cnveg_nitrogenstate_inst, cnveg_carbonflux_inst, cnveg_nitrogenflux_inst) + + call CNGrainToProductPools(bounds, num_soilp, filter_soilp, num_soilc, filter_soilc, & + cnveg_carbonflux_inst, cnveg_nitrogenflux_inst) + + ! gather all patch-level litterfall fluxes to the column for litter C and N inputs + + call CNLitterToColumn(bounds, num_soilc, filter_soilc, & + cnveg_state_inst, cnveg_carbonflux_inst, cnveg_nitrogenflux_inst, & + leaf_prof_patch(bounds%begp:bounds%endp,1:nlevdecomp_full), & + froot_prof_patch(bounds%begp:bounds%endp,1:nlevdecomp_full)) + else + call endrun( 'bad phase' ) + end if + + end subroutine CNPhenology + + !----------------------------------------------------------------------- + subroutine CNPhenologyInit(bounds) + ! + ! !DESCRIPTION: + ! Initialization of CNPhenology. Must be called after time-manager is + ! initialized, and after pftcon file is read in. + ! + ! !USES: + use clm_time_manager, only: get_step_size_real + use clm_varctl , only: use_crop + use clm_varcon , only: secspday + ! + ! !ARGUMENTS: + type(bounds_type), intent(in) :: bounds + !------------------------------------------------------------------------ + + ! + ! Get time-step and what fraction of a day it is + ! + dt = get_step_size_real() + fracday = dt/secspday + + ! set constants for CNSeasonDecidPhenology + ! (critical daylength from Biome-BGC, v4.1.2) + crit_dayl=params_inst%crit_dayl + + ! Set constants for CNSeasonDecidPhenology and CNStressDecidPhenology + ndays_on=params_inst%ndays_on + ndays_off=params_inst%ndays_off + + ! set transfer parameters + fstor2tran=params_inst%fstor2tran + + ! ----------------------------------------- + ! Constants for CNStressDecidPhenology + ! ----------------------------------------- + + ! onset parameters + crit_onset_fdd=params_inst%crit_onset_fdd + ! critical onset gdd now being calculated as a function of annual + ! average 2m temp. + ! crit_onset_gdd = 150.0 ! c3 grass value + ! crit_onset_gdd = 1000.0 ! c4 grass value + crit_onset_swi=params_inst%crit_onset_swi + soilpsi_on=params_inst%soilpsi_on + + ! offset parameters + crit_offset_fdd=params_inst%crit_offset_fdd + crit_offset_swi=params_inst%crit_offset_swi + soilpsi_off=params_inst%soilpsi_off + + ! ----------------------------------------- + ! Constants for CNLivewoodTurnover + ! ----------------------------------------- + + ! set the global parameter for livewood turnover rate + ! define as an annual fraction (0.7), and convert to fraction per second + lwtop=params_inst%lwtop/31536000.0_r8 !annual fraction converted to per second + + ! ----------------------------------------- + ! Call any subroutine specific initialization routines + ! ----------------------------------------- + + if ( use_crop ) call CropPhenologyInit(bounds) + + end subroutine CNPhenologyInit + + !----------------------------------------------------------------------- + subroutine CNPhenologyClimate (num_soilp, filter_soilp, num_pcropp, filter_pcropp, & + temperature_inst, cnveg_state_inst, crop_inst) + ! + ! !DESCRIPTION: + ! For coupled carbon-nitrogen code (CN). + ! + ! !USES: + use clm_time_manager , only : get_days_per_year + use clm_time_manager , only : get_curr_date, is_first_step + ! + ! !ARGUMENTS: + integer , intent(in) :: num_soilp ! number of soil patches in filter + integer , intent(in) :: filter_soilp(:) ! filter for soil patches + integer , intent(in) :: num_pcropp ! number of prognostic crops in filter + integer , intent(in) :: filter_pcropp(:)! filter for prognostic crop patches + type(temperature_type) , intent(inout) :: temperature_inst + type(cnveg_state_type) , intent(inout) :: cnveg_state_inst + type(crop_type) , intent(inout) :: crop_inst + ! + ! !LOCAL VARIABLES: + integer :: p ! indices + integer :: fp ! lake filter patch index + real(r8) :: dayspyr ! days per year (days) + integer :: kyr ! current year + integer :: kmo ! month of year (1, ..., 12) + integer :: kda ! day of month (1, ..., 31) + integer :: mcsec ! seconds of day (0, ..., seconds/day) + real(r8), parameter :: yravg = 20.0_r8 ! length of years to average for gdd + real(r8), parameter :: yravgm1 = yravg-1.0_r8 ! minus 1 of above + !----------------------------------------------------------------------- + + associate( & + nyrs_crop_active => crop_inst%nyrs_crop_active_patch, & ! InOut: [integer (:) ] number of years this crop patch has been active + + t_ref2m => temperature_inst%t_ref2m_patch , & ! Input: [real(r8) (:) ] 2m air temperature (K) + gdd0 => temperature_inst%gdd0_patch , & ! Output: [real(r8) (:) ] growing deg. days base 0 deg C (ddays) + gdd8 => temperature_inst%gdd8_patch , & ! Output: [real(r8) (:) ] " " " " 8 " " " + gdd10 => temperature_inst%gdd10_patch , & ! Output: [real(r8) (:) ] " " " " 10 " " " + gdd020 => temperature_inst%gdd020_patch , & ! Output: [real(r8) (:) ] 20-yr mean of gdd0 (ddays) + gdd820 => temperature_inst%gdd820_patch , & ! Output: [real(r8) (:) ] 20-yr mean of gdd8 (ddays) + gdd1020 => temperature_inst%gdd1020_patch , & ! Output: [real(r8) (:) ] 20-yr mean of gdd10 (ddays) + + tempavg_t2m => cnveg_state_inst%tempavg_t2m_patch & ! Output: [real(r8) (:) ] temp. avg 2m air temperature (K) + ) + + ! set time steps + + dayspyr = get_days_per_year() + + do fp = 1,num_soilp + p = filter_soilp(fp) + tempavg_t2m(p) = tempavg_t2m(p) + t_ref2m(p) * (fracday/dayspyr) + end do + + ! + ! The following crop related steps are done here rather than CropPhenology + ! so that they will be completed each time-step rather than with doalb. + ! + ! The following lines come from ibis's climate.f + stats.f + ! gdd SUMMATIONS ARE RELATIVE TO THE PLANTING DATE (see subr. updateAccFlds) + + if (num_pcropp > 0) then + ! get time-related info + call get_curr_date(kyr, kmo, kda, mcsec) + end if + + do fp = 1,num_pcropp + p = filter_pcropp(fp) + if (kmo == 1 .and. kda == 1 .and. nyrs_crop_active(p) == 0) then ! YR 1: + gdd020(p) = 0._r8 ! set gdd..20 variables to 0 + gdd820(p) = 0._r8 ! and crops will not be planted + gdd1020(p) = 0._r8 + end if + if (kmo == 1 .and. kda == 1 .and. mcsec == 0) then ! <-- END of EVERY YR: + if (nyrs_crop_active(p) == 1) then ! <-- END of YR 1 + gdd020(p) = gdd0(p) ! <-- END of YR 1 + gdd820(p) = gdd8(p) ! <-- END of YR 1 + gdd1020(p) = gdd10(p) ! <-- END of YR 1 + end if ! <-- END of YR 1 + gdd020(p) = (yravgm1* gdd020(p) + gdd0(p)) / yravg ! gdd..20 must be long term avgs + gdd820(p) = (yravgm1* gdd820(p) + gdd8(p)) / yravg ! so ignore results for yrs 1 & 2 + gdd1020(p) = (yravgm1* gdd1020(p) + gdd10(p)) / yravg + end if + end do + + end associate + + end subroutine CNPhenologyClimate + + !----------------------------------------------------------------------- + subroutine CNEvergreenPhenology (num_soilp, filter_soilp , & + cnveg_state_inst, cnveg_carbonstate_inst, cnveg_nitrogenstate_inst, cnveg_carbonflux_inst, cnveg_nitrogenflux_inst) + ! cnveg_state_inst) + ! + ! !DESCRIPTION: + ! For coupled carbon-nitrogen code (CN). + ! + ! !USES: + use clm_varcon , only : secspday + use clm_time_manager , only : get_days_per_year + use clm_varctl , only : CN_evergreen_phenology_opt + ! + ! !ARGUMENTS: + integer , intent(in) :: num_soilp ! number of soil patches in filter + integer , intent(in) :: filter_soilp(:) ! filter for soil patches + type(cnveg_state_type), intent(inout) :: cnveg_state_inst + type(cnveg_carbonstate_type) , intent(inout) :: cnveg_carbonstate_inst + type(cnveg_nitrogenstate_type) , intent(inout) :: cnveg_nitrogenstate_inst + type(cnveg_carbonflux_type) , intent(inout) :: cnveg_carbonflux_inst + type(cnveg_nitrogenflux_type) , intent(inout) :: cnveg_nitrogenflux_inst + ! + ! !LOCAL VARIABLES: + real(r8):: dayspyr ! Days per year + integer :: p ! indices + integer :: fp ! lake filter patch index + + real(r8):: tranr + real(r8):: t1 ! temporary variable + !----------------------------------------------------------------------- + + associate( & + ivt => patch%itype , & ! Input: [integer (:) ] patch vegetation type + + evergreen => pftcon%evergreen , & ! Input: binary flag for evergreen leaf habit (0 or 1) + leaf_long => pftcon%leaf_long , & ! Input: leaf longevity (yrs) + + woody => pftcon%woody , & ! Input: binary flag for woody lifeform (1=woody, 0=not woody) + + 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 , & ! InOut: [real(r8) (:)] (gC/m2) leaf C transfer + frootc_xfer => cnveg_carbonstate_inst%frootc_xfer_patch , & ! InOut: [real(r8) (:)] (gC/m2) fine root C transfer + livestemc_xfer => cnveg_carbonstate_inst%livestemc_xfer_patch , & ! InOut: [real(r8) (:)] (gC/m2) live stem C transfer + deadstemc_xfer => cnveg_carbonstate_inst%deadstemc_xfer_patch , & ! InOut: [real(r8) (:)] (gC/m2) dead stem C transfer + livecrootc_xfer => cnveg_carbonstate_inst%livecrootc_xfer_patch , & ! InOut: [real(r8) (:)] (gC/m2) live coarse root C transfer + deadcrootc_xfer => cnveg_carbonstate_inst%deadcrootc_xfer_patch , & ! InOut: [real(r8) (:)] (gC/m2) dead coarse root C transfer + + 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 , & ! InOut: [real(r8) (:)] (gN/m2) leaf N transfer + frootn_xfer => cnveg_nitrogenstate_inst%frootn_xfer_patch , & ! InOut: [real(r8) (:)] (gN/m2) fine root N transfer + livestemn_xfer => cnveg_nitrogenstate_inst%livestemn_xfer_patch , & ! InOut: [real(r8) (:)] (gN/m2) live stem N transfer + deadstemn_xfer => cnveg_nitrogenstate_inst%deadstemn_xfer_patch , & ! InOut: [real(r8) (:)] (gN/m2) dead stem N transfer + livecrootn_xfer => cnveg_nitrogenstate_inst%livecrootn_xfer_patch , & ! InOut: [real(r8) (:)] (gN/m2) live coarse root N transfer + deadcrootn_xfer => cnveg_nitrogenstate_inst%deadcrootn_xfer_patch , & ! InOut: [real(r8) (:)] (gN/m2) dead coarse root N transfer + + leafc_storage_to_xfer => cnveg_carbonflux_inst%leafc_storage_to_xfer_patch , & ! InOut: [real(r8) (:)] + frootc_storage_to_xfer => cnveg_carbonflux_inst%frootc_storage_to_xfer_patch , & ! InOut: [real(r8) (:)] + livestemc_storage_to_xfer => cnveg_carbonflux_inst%livestemc_storage_to_xfer_patch , & ! InOut: [real(r8) (:)] + deadstemc_storage_to_xfer => cnveg_carbonflux_inst%deadstemc_storage_to_xfer_patch , & ! InOut: [real(r8) (:)] + livecrootc_storage_to_xfer => cnveg_carbonflux_inst%livecrootc_storage_to_xfer_patch , & ! InOut: [real(r8) (:)] + deadcrootc_storage_to_xfer => cnveg_carbonflux_inst%deadcrootc_storage_to_xfer_patch , & ! InOut: [real(r8) (:)] + gresp_storage_to_xfer => cnveg_carbonflux_inst%gresp_storage_to_xfer_patch , & ! InOut: [real(r8) (:)] + leafc_xfer_to_leafc => cnveg_carbonflux_inst%leafc_xfer_to_leafc_patch , & ! InOut: [real(r8) (:)] + frootc_xfer_to_frootc => cnveg_carbonflux_inst%frootc_xfer_to_frootc_patch , & ! InOut: [real(r8) (:)] + livestemc_xfer_to_livestemc => cnveg_carbonflux_inst%livestemc_xfer_to_livestemc_patch , & ! InOut: [real(r8) (:)] + deadstemc_xfer_to_deadstemc => cnveg_carbonflux_inst%deadstemc_xfer_to_deadstemc_patch , & ! InOut: [real(r8) (:)] + livecrootc_xfer_to_livecrootc => cnveg_carbonflux_inst%livecrootc_xfer_to_livecrootc_patch , & ! InOut: [real(r8) (:)] + deadcrootc_xfer_to_deadcrootc => cnveg_carbonflux_inst%deadcrootc_xfer_to_deadcrootc_patch , & ! InOut: [real(r8) (:)] + + leafn_storage_to_xfer => cnveg_nitrogenflux_inst%leafn_storage_to_xfer_patch , & ! InOut: [real(r8) (:)] + frootn_storage_to_xfer => cnveg_nitrogenflux_inst%frootn_storage_to_xfer_patch , & ! InOut: [real(r8) (:)] + livestemn_storage_to_xfer => cnveg_nitrogenflux_inst%livestemn_storage_to_xfer_patch , & ! InOut: [real(r8) (:)] + deadstemn_storage_to_xfer => cnveg_nitrogenflux_inst%deadstemn_storage_to_xfer_patch , & ! InOut: [real(r8) (:)] + livecrootn_storage_to_xfer => cnveg_nitrogenflux_inst%livecrootn_storage_to_xfer_patch , & ! InOut: [real(r8) (:)] + deadcrootn_storage_to_xfer => cnveg_nitrogenflux_inst%deadcrootn_storage_to_xfer_patch , & ! InOut: [real(r8) (:)] + leafn_xfer_to_leafn => cnveg_nitrogenflux_inst%leafn_xfer_to_leafn_patch , & ! InOut: [real(r8) (:)] + frootn_xfer_to_frootn => cnveg_nitrogenflux_inst%frootn_xfer_to_frootn_patch , & ! InOut: [real(r8) (:)] + livestemn_xfer_to_livestemn => cnveg_nitrogenflux_inst%livestemn_xfer_to_livestemn_patch , & ! InOut: [real(r8) (:)] + deadstemn_xfer_to_deadstemn => cnveg_nitrogenflux_inst%deadstemn_xfer_to_deadstemn_patch , & ! InOut: [real(r8) (:)] + livecrootn_xfer_to_livecrootn => cnveg_nitrogenflux_inst%livecrootn_xfer_to_livecrootn_patch , & ! InOut: [real(r8) (:)] + deadcrootn_xfer_to_deadcrootn => cnveg_nitrogenflux_inst%deadcrootn_xfer_to_deadcrootn_patch , & ! InOut: [real(r8) (:)] + + bglfr => cnveg_state_inst%bglfr_patch , & ! Output: [real(r8) (:) ] background litterfall rate (1/s) + bgtr => cnveg_state_inst%bgtr_patch , & ! Output: [real(r8) (:) ] background transfer growth rate (1/s) + lgsf => cnveg_state_inst%lgsf_patch & ! Output: [real(r8) (:) ] long growing season factor [0-1] + ) + + dayspyr = get_days_per_year() + + do fp = 1,num_soilp + p = filter_soilp(fp) + if (evergreen(ivt(p)) == 1._r8) then + bglfr(p) = 1._r8/(leaf_long(ivt(p)) * dayspyr * secspday) + bgtr(p) = 0._r8 + lgsf(p) = 0._r8 + end if + end do + + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + if (CN_evergreen_phenology_opt == 1) then + do fp = 1,num_soilp + p = filter_soilp(fp) + if (evergreen(ivt(p)) == 1._r8) then + + tranr=0.0002_r8 + ! set carbon fluxes for shifting storage pools to transfer pools + leafc_storage_to_xfer(p) = tranr * leafc_storage(p)/dt + frootc_storage_to_xfer(p) = tranr * frootc_storage(p)/dt + if (woody(ivt(p)) == 1.0_r8) then + livestemc_storage_to_xfer(p) = tranr * livestemc_storage(p)/dt + deadstemc_storage_to_xfer(p) = tranr * deadstemc_storage(p)/dt + livecrootc_storage_to_xfer(p) = tranr * livecrootc_storage(p)/dt + deadcrootc_storage_to_xfer(p) = tranr * deadcrootc_storage(p)/dt + gresp_storage_to_xfer(p) = tranr * gresp_storage(p)/dt + end if + + ! set nitrogen fluxes for shifting storage pools to transfer pools + leafn_storage_to_xfer(p) = tranr * leafn_storage(p)/dt + frootn_storage_to_xfer(p) = tranr * frootn_storage(p)/dt + if (woody(ivt(p)) == 1.0_r8) then + livestemn_storage_to_xfer(p) = tranr * livestemn_storage(p)/dt + deadstemn_storage_to_xfer(p) = tranr * deadstemn_storage(p)/dt + livecrootn_storage_to_xfer(p) = tranr * livecrootn_storage(p)/dt + deadcrootn_storage_to_xfer(p) = tranr * deadcrootn_storage(p)/dt + end if + + t1 = 1.0_r8 / dt + + leafc_xfer_to_leafc(p) = t1 * leafc_xfer(p) + frootc_xfer_to_frootc(p) = t1 * frootc_xfer(p) + + leafn_xfer_to_leafn(p) = t1 * leafn_xfer(p) + frootn_xfer_to_frootn(p) = t1 * frootn_xfer(p) + if (woody(ivt(p)) == 1.0_r8) then + livestemc_xfer_to_livestemc(p) = t1 * livestemc_xfer(p) + deadstemc_xfer_to_deadstemc(p) = t1 * deadstemc_xfer(p) + livecrootc_xfer_to_livecrootc(p) = t1 * livecrootc_xfer(p) + deadcrootc_xfer_to_deadcrootc(p) = t1 * deadcrootc_xfer(p) + + livestemn_xfer_to_livestemn(p) = t1 * livestemn_xfer(p) + deadstemn_xfer_to_deadstemn(p) = t1 * deadstemn_xfer(p) + livecrootn_xfer_to_livecrootn(p) = t1 * livecrootn_xfer(p) + deadcrootn_xfer_to_deadcrootn(p) = t1 * deadcrootn_xfer(p) + end if + + end if ! end of if (evergreen(ivt(p)) == 1._r8) then + + end do ! end of pft loop + + end if ! end of if (CN_evergreen_phenology_opt == 1) then + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + end associate + + end subroutine CNEvergreenPhenology + + !----------------------------------------------------------------------- + subroutine CNSeasonDecidPhenology (num_soilp, filter_soilp , & + temperature_inst, cnveg_state_inst, dgvs_inst , & + cnveg_carbonstate_inst, cnveg_nitrogenstate_inst, cnveg_carbonflux_inst, cnveg_nitrogenflux_inst) + ! + ! !DESCRIPTION: + ! For coupled carbon-nitrogen code (CN). + ! This routine handles the seasonal deciduous phenology code (temperate + ! deciduous vegetation that has only one growing season per year). + ! + ! !USES: + use shr_const_mod , only: SHR_CONST_TKFRZ, SHR_CONST_PI + use clm_varcon , only: secspday + use clm_varctl , only: use_cndv + ! + ! !ARGUMENTS: + integer , intent(in) :: num_soilp ! number of soil patches in filter + integer , intent(in) :: filter_soilp(:) ! filter for soil patches + type(temperature_type) , intent(in) :: temperature_inst + type(cnveg_state_type) , intent(inout) :: cnveg_state_inst + type(dgvs_type) , intent(inout) :: dgvs_inst + type(cnveg_carbonstate_type) , intent(inout) :: cnveg_carbonstate_inst + type(cnveg_nitrogenstate_type) , intent(inout) :: cnveg_nitrogenstate_inst + type(cnveg_carbonflux_type) , intent(inout) :: cnveg_carbonflux_inst + type(cnveg_nitrogenflux_type) , intent(inout) :: cnveg_nitrogenflux_inst + ! + ! !LOCAL VARIABLES: + integer :: g,c,p !indices + integer :: fp !lake filter patch index + real(r8):: ws_flag !winter-summer solstice flag (0 or 1) + real(r8):: crit_onset_gdd !critical onset growing degree-day sum + real(r8):: soilt + !----------------------------------------------------------------------- + + associate( & + ivt => patch%itype , & ! Input: [integer (:) ] patch vegetation type + dayl => grc%dayl , & ! Input: [real(r8) (:) ] daylength (s) + prev_dayl => grc%prev_dayl , & ! Input: [real(r8) (:) ] daylength from previous time step (s) + + woody => pftcon%woody , & ! Input: binary flag for woody lifeform (1=woody, 0=not woody) + season_decid => pftcon%season_decid , & ! Input: binary flag for seasonal-deciduous leaf habit (0 or 1) + + t_soisno => temperature_inst%t_soisno_col , & ! Input: [real(r8) (:,:) ] soil temperature (Kelvin) (-nlevsno+1:nlevgrnd) + + pftmayexist => dgvs_inst%pftmayexist_patch , & ! Output: [logical (:) ] exclude seasonal decid patches from tropics + + annavg_t2m => cnveg_state_inst%annavg_t2m_patch , & ! Input: [real(r8) (:) ] annual average 2m air temperature (K) + dormant_flag => cnveg_state_inst%dormant_flag_patch , & ! Output: [real(r8) (:) ] dormancy flag + days_active => cnveg_state_inst%days_active_patch , & ! Output: [real(r8) (:) ] number of days since last dormancy + onset_flag => cnveg_state_inst%onset_flag_patch , & ! Output: [real(r8) (:) ] onset flag + onset_counter => cnveg_state_inst%onset_counter_patch , & ! Output: [real(r8) (:) ] onset counter (seconds) + onset_gddflag => cnveg_state_inst%onset_gddflag_patch , & ! Output: [real(r8) (:) ] onset freeze flag + onset_gdd => cnveg_state_inst%onset_gdd_patch , & ! Output: [real(r8) (:) ] onset growing degree days + offset_flag => cnveg_state_inst%offset_flag_patch , & ! Output: [real(r8) (:) ] offset flag + offset_counter => cnveg_state_inst%offset_counter_patch , & ! Output: [real(r8) (:) ] offset counter (seconds) + bglfr => cnveg_state_inst%bglfr_patch , & ! Output: [real(r8) (:) ] background litterfall rate (1/s) + bgtr => cnveg_state_inst%bgtr_patch , & ! Output: [real(r8) (:) ] background transfer growth rate (1/s) + lgsf => cnveg_state_inst%lgsf_patch , & ! Output: [real(r8) (:) ] long growing season factor [0-1] + + 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 , & ! Output: [real(r8) (:) ] (gC/m2) leaf C transfer + frootc_xfer => cnveg_carbonstate_inst%frootc_xfer_patch , & ! Output: [real(r8) (:) ] (gC/m2) fine root C transfer + livestemc_xfer => cnveg_carbonstate_inst%livestemc_xfer_patch , & ! Output: [real(r8) (:) ] (gC/m2) live stem C transfer + deadstemc_xfer => cnveg_carbonstate_inst%deadstemc_xfer_patch , & ! Output: [real(r8) (:) ] (gC/m2) dead stem C transfer + livecrootc_xfer => cnveg_carbonstate_inst%livecrootc_xfer_patch , & ! Output: [real(r8) (:) ] (gC/m2) live coarse root C transfer + deadcrootc_xfer => cnveg_carbonstate_inst%deadcrootc_xfer_patch , & ! Output: [real(r8) (:) ] (gC/m2) dead coarse root C transfer + + 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 , & ! Output: [real(r8) (:) ] (gN/m2) leaf N transfer + frootn_xfer => cnveg_nitrogenstate_inst%frootn_xfer_patch , & ! Output: [real(r8) (:) ] (gN/m2) fine root N transfer + livestemn_xfer => cnveg_nitrogenstate_inst%livestemn_xfer_patch , & ! Output: [real(r8) (:) ] (gN/m2) live stem N transfer + deadstemn_xfer => cnveg_nitrogenstate_inst%deadstemn_xfer_patch , & ! Output: [real(r8) (:) ] (gN/m2) dead stem N transfer + livecrootn_xfer => cnveg_nitrogenstate_inst%livecrootn_xfer_patch , & ! Output: [real(r8) (:) ] (gN/m2) live coarse root N transfer + deadcrootn_xfer => cnveg_nitrogenstate_inst%deadcrootn_xfer_patch , & ! Output: [real(r8) (:) ] (gN/m2) dead coarse root N transfer + + prev_leafc_to_litter => cnveg_carbonflux_inst%prev_leafc_to_litter_patch , & ! Output: [real(r8) (:) ] previous timestep leaf C litterfall flux (gC/m2/s) + prev_frootc_to_litter => cnveg_carbonflux_inst%prev_frootc_to_litter_patch , & ! Output: [real(r8) (:) ] previous timestep froot C litterfall flux (gC/m2/s) + leafc_xfer_to_leafc => cnveg_carbonflux_inst%leafc_xfer_to_leafc_patch , & ! Output: [real(r8) (:) ] + frootc_xfer_to_frootc => cnveg_carbonflux_inst%frootc_xfer_to_frootc_patch , & ! Output: [real(r8) (:) ] + livestemc_xfer_to_livestemc => cnveg_carbonflux_inst%livestemc_xfer_to_livestemc_patch , & ! Output: [real(r8) (:) ] + deadstemc_xfer_to_deadstemc => cnveg_carbonflux_inst%deadstemc_xfer_to_deadstemc_patch , & ! Output: [real(r8) (:) ] + livecrootc_xfer_to_livecrootc => cnveg_carbonflux_inst%livecrootc_xfer_to_livecrootc_patch , & ! Output: [real(r8) (:) ] + deadcrootc_xfer_to_deadcrootc => cnveg_carbonflux_inst%deadcrootc_xfer_to_deadcrootc_patch , & ! Output: [real(r8) (:) ] + leafc_storage_to_xfer => cnveg_carbonflux_inst%leafc_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] + frootc_storage_to_xfer => cnveg_carbonflux_inst%frootc_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] + livestemc_storage_to_xfer => cnveg_carbonflux_inst%livestemc_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] + deadstemc_storage_to_xfer => cnveg_carbonflux_inst%deadstemc_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] + livecrootc_storage_to_xfer => cnveg_carbonflux_inst%livecrootc_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] + deadcrootc_storage_to_xfer => cnveg_carbonflux_inst%deadcrootc_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] + gresp_storage_to_xfer => cnveg_carbonflux_inst%gresp_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] + + leafn_xfer_to_leafn => cnveg_nitrogenflux_inst%leafn_xfer_to_leafn_patch , & ! Output: [real(r8) (:) ] + frootn_xfer_to_frootn => cnveg_nitrogenflux_inst%frootn_xfer_to_frootn_patch , & ! Output: [real(r8) (:) ] + livestemn_xfer_to_livestemn => cnveg_nitrogenflux_inst%livestemn_xfer_to_livestemn_patch , & ! Output: [real(r8) (:) ] + deadstemn_xfer_to_deadstemn => cnveg_nitrogenflux_inst%deadstemn_xfer_to_deadstemn_patch , & ! Output: [real(r8) (:) ] + livecrootn_xfer_to_livecrootn => cnveg_nitrogenflux_inst%livecrootn_xfer_to_livecrootn_patch , & ! Output: [real(r8) (:) ] + deadcrootn_xfer_to_deadcrootn => cnveg_nitrogenflux_inst%deadcrootn_xfer_to_deadcrootn_patch , & ! Output: [real(r8) (:) ] + leafn_storage_to_xfer => cnveg_nitrogenflux_inst%leafn_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] + frootn_storage_to_xfer => cnveg_nitrogenflux_inst%frootn_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] + livestemn_storage_to_xfer => cnveg_nitrogenflux_inst%livestemn_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] + deadstemn_storage_to_xfer => cnveg_nitrogenflux_inst%deadstemn_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] + livecrootn_storage_to_xfer => cnveg_nitrogenflux_inst%livecrootn_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] + deadcrootn_storage_to_xfer => cnveg_nitrogenflux_inst%deadcrootn_storage_to_xfer_patch & ! Output: [real(r8) (:) ] + ) + + ! start patch loop + do fp = 1,num_soilp + p = filter_soilp(fp) + c = patch%column(p) + g = patch%gridcell(p) + + if (season_decid(ivt(p)) == 1._r8) then + + ! set background litterfall rate, background transfer rate, and + ! long growing season factor to 0 for seasonal deciduous types + bglfr(p) = 0._r8 + bgtr(p) = 0._r8 + lgsf(p) = 0._r8 + + ! onset gdd sum from Biome-BGC, v4.1.2 + crit_onset_gdd = exp(4.8_r8 + 0.13_r8*(annavg_t2m(p) - SHR_CONST_TKFRZ)) + + ! set flag for solstice period (winter->summer = 1, summer->winter = 0) + if (dayl(g) >= prev_dayl(g)) then + ws_flag = 1._r8 + else + ws_flag = 0._r8 + end if + + ! update offset_counter and test for the end of the offset period + if (offset_flag(p) == 1.0_r8) then + ! decrement counter for offset period + offset_counter(p) = offset_counter(p) - dt + + ! if this is the end of the offset_period, reset phenology + ! flags and indices + if (offset_counter(p) == 0.0_r8) then + ! this code block was originally handled by call cn_offset_cleanup(p) + ! inlined during vectorization + + offset_flag(p) = 0._r8 + offset_counter(p) = 0._r8 + dormant_flag(p) = 1._r8 + days_active(p) = 0._r8 + if (use_cndv) then + pftmayexist(p) = .true. + end if + + ! reset the previous timestep litterfall flux memory + prev_leafc_to_litter(p) = 0._r8 + prev_frootc_to_litter(p) = 0._r8 + end if + end if + + ! update onset_counter and test for the end of the onset period + if (onset_flag(p) == 1.0_r8) then + ! decrement counter for onset period + onset_counter(p) = onset_counter(p) - dt + + ! if this is the end of the onset period, reset phenology + ! flags and indices + if (onset_counter(p) == 0.0_r8) then + ! this code block was originally handled by call cn_onset_cleanup(p) + ! inlined during vectorization + + onset_flag(p) = 0.0_r8 + onset_counter(p) = 0.0_r8 + ! set all transfer growth rates to 0.0 + leafc_xfer_to_leafc(p) = 0.0_r8 + frootc_xfer_to_frootc(p) = 0.0_r8 + leafn_xfer_to_leafn(p) = 0.0_r8 + frootn_xfer_to_frootn(p) = 0.0_r8 + if (woody(ivt(p)) == 1.0_r8) then + livestemc_xfer_to_livestemc(p) = 0.0_r8 + deadstemc_xfer_to_deadstemc(p) = 0.0_r8 + livecrootc_xfer_to_livecrootc(p) = 0.0_r8 + deadcrootc_xfer_to_deadcrootc(p) = 0.0_r8 + livestemn_xfer_to_livestemn(p) = 0.0_r8 + deadstemn_xfer_to_deadstemn(p) = 0.0_r8 + livecrootn_xfer_to_livecrootn(p) = 0.0_r8 + deadcrootn_xfer_to_deadcrootn(p) = 0.0_r8 + end if + ! set transfer pools to 0.0 + leafc_xfer(p) = 0.0_r8 + leafn_xfer(p) = 0.0_r8 + frootc_xfer(p) = 0.0_r8 + frootn_xfer(p) = 0.0_r8 + if (woody(ivt(p)) == 1.0_r8) then + livestemc_xfer(p) = 0.0_r8 + livestemn_xfer(p) = 0.0_r8 + deadstemc_xfer(p) = 0.0_r8 + deadstemn_xfer(p) = 0.0_r8 + livecrootc_xfer(p) = 0.0_r8 + livecrootn_xfer(p) = 0.0_r8 + deadcrootc_xfer(p) = 0.0_r8 + deadcrootn_xfer(p) = 0.0_r8 + end if + end if + end if + + ! test for switching from dormant period to growth period + if (dormant_flag(p) == 1.0_r8) then + + ! Test to turn on growing degree-day sum, if off. + ! switch on the growing degree day sum on the winter solstice + + if (onset_gddflag(p) == 0._r8 .and. ws_flag == 1._r8) then + onset_gddflag(p) = 1._r8 + onset_gdd(p) = 0._r8 + end if + + ! Test to turn off growing degree-day sum, if on. + ! This test resets the growing degree day sum if it gets past + ! the summer solstice without reaching the threshold value. + ! In that case, it will take until the next winter solstice + ! before the growing degree-day summation starts again. + + if (onset_gddflag(p) == 1._r8 .and. ws_flag == 0._r8) then + onset_gddflag(p) = 0._r8 + onset_gdd(p) = 0._r8 + end if + + ! if the gdd flag is set, and if the soil is above freezing + ! then accumulate growing degree days for onset trigger + + soilt = t_soisno(c,3) + if (onset_gddflag(p) == 1.0_r8 .and. soilt > SHR_CONST_TKFRZ) then + onset_gdd(p) = onset_gdd(p) + (soilt-SHR_CONST_TKFRZ)*fracday + end if + + ! set onset_flag if critical growing degree-day sum is exceeded + if (onset_gdd(p) > crit_onset_gdd) then + onset_flag(p) = 1.0_r8 + dormant_flag(p) = 0.0_r8 + onset_gddflag(p) = 0.0_r8 + onset_gdd(p) = 0.0_r8 + onset_counter(p) = ndays_on * secspday + + ! move all the storage pools into transfer pools, + ! where they will be transfered to displayed growth over the onset period. + ! this code was originally handled with call cn_storage_to_xfer(p) + ! inlined during vectorization + + ! set carbon fluxes for shifting storage pools to transfer pools + leafc_storage_to_xfer(p) = fstor2tran * leafc_storage(p)/dt + frootc_storage_to_xfer(p) = fstor2tran * frootc_storage(p)/dt + if (woody(ivt(p)) == 1.0_r8) then + livestemc_storage_to_xfer(p) = fstor2tran * livestemc_storage(p)/dt + deadstemc_storage_to_xfer(p) = fstor2tran * deadstemc_storage(p)/dt + livecrootc_storage_to_xfer(p) = fstor2tran * livecrootc_storage(p)/dt + deadcrootc_storage_to_xfer(p) = fstor2tran * deadcrootc_storage(p)/dt + gresp_storage_to_xfer(p) = fstor2tran * gresp_storage(p)/dt + end if + + ! set nitrogen fluxes for shifting storage pools to transfer pools + leafn_storage_to_xfer(p) = fstor2tran * leafn_storage(p)/dt + frootn_storage_to_xfer(p) = fstor2tran * frootn_storage(p)/dt + if (woody(ivt(p)) == 1.0_r8) then + livestemn_storage_to_xfer(p) = fstor2tran * livestemn_storage(p)/dt + deadstemn_storage_to_xfer(p) = fstor2tran * deadstemn_storage(p)/dt + livecrootn_storage_to_xfer(p) = fstor2tran * livecrootn_storage(p)/dt + deadcrootn_storage_to_xfer(p) = fstor2tran * deadcrootn_storage(p)/dt + end if + end if + + ! test for switching from growth period to offset period + else if (offset_flag(p) == 0.0_r8) then + if (use_cndv) then + ! If days_active > 355, then remove patch in + ! CNDVEstablishment at the end of the year. + ! days_active > 355 is a symptom of seasonal decid. patches occurring in + ! gridcells where dayl never drops below crit_dayl. + ! This results in TLAI>1e4 in a few gridcells. + days_active(p) = days_active(p) + fracday + if (days_active(p) > 355._r8) pftmayexist(p) = .false. + end if + + ! only begin to test for offset daylength once past the summer sol + if (ws_flag == 0._r8 .and. dayl(g) < crit_dayl) then + offset_flag(p) = 1._r8 + offset_counter(p) = ndays_off * secspday + prev_leafc_to_litter(p) = 0._r8 + prev_frootc_to_litter(p) = 0._r8 + end if + end if + + end if ! end if seasonal deciduous + + end do ! end of patch loop + + end associate + + end subroutine CNSeasonDecidPhenology + + !----------------------------------------------------------------------- + subroutine CNStressDecidPhenology (num_soilp, filter_soilp , & + soilstate_inst, temperature_inst, atm2lnd_inst, wateratm2lndbulk_inst, cnveg_state_inst, & + cnveg_carbonstate_inst, cnveg_nitrogenstate_inst, & + cnveg_carbonflux_inst, cnveg_nitrogenflux_inst) + ! + ! !DESCRIPTION: + ! This routine handles phenology for vegetation types, such as grasses and + ! tropical drought deciduous trees, that respond to cold and drought stress + ! signals and that can have multiple growing seasons in a given year. + ! This routine allows for the possibility that leaves might persist year-round + ! in the absence of a suitable stress trigger, by switching to an essentially + ! evergreen habit, but maintaining a deciduous leaf longevity, while waiting + ! for the next stress trigger. This is in contrast to the seasonal deciduous + ! algorithm (for temperate deciduous trees) that forces a single growing season + ! per year. + ! + ! !USES: + use clm_time_manager , only : get_days_per_year + use CNSharedParamsMod, only : use_fun + use clm_varcon , only : secspday + use shr_const_mod , only : SHR_CONST_TKFRZ, SHR_CONST_PI + use CNSharedParamsMod, only : CNParamsShareInst + ! + ! !ARGUMENTS: + integer , intent(in) :: num_soilp ! number of soil patches in filter + integer , intent(in) :: filter_soilp(:) ! filter for soil patches + type(soilstate_type) , intent(in) :: soilstate_inst + type(temperature_type) , intent(in) :: temperature_inst + type(atm2lnd_type) , intent(in) :: atm2lnd_inst + type(wateratm2lndbulk_type) , intent(in) :: wateratm2lndbulk_inst + type(cnveg_state_type) , intent(inout) :: cnveg_state_inst + type(cnveg_carbonstate_type) , intent(inout) :: cnveg_carbonstate_inst + type(cnveg_nitrogenstate_type) , intent(inout) :: cnveg_nitrogenstate_inst + type(cnveg_carbonflux_type) , intent(inout) :: cnveg_carbonflux_inst + type(cnveg_nitrogenflux_type) , intent(inout) :: cnveg_nitrogenflux_inst + ! + ! !LOCAL VARIABLES: + real(r8),parameter :: secspqtrday = secspday / 4 ! seconds per quarter day + integer :: g,c,p ! indices + integer :: fp ! lake filter patch index + real(r8):: dayspyr ! days per year + real(r8):: crit_onset_gdd ! degree days for onset trigger + real(r8):: soilt ! temperature of top soil layer + real(r8):: psi ! water stress of top soil layer + real(r8):: rain_threshold ! rain threshold for leaf on [mm] + logical :: additional_onset_condition ! additional condition for leaf onset + !----------------------------------------------------------------------- + + associate( & + ivt => patch%itype , & ! Input: [integer (:) ] patch vegetation type + dayl => grc%dayl , & ! Input: [real(r8) (:) ] daylength (s) + + prec10 => wateratm2lndbulk_inst%prec10_patch , & ! Input: [real(r8) (:) ] 10-day running mean of tot. precipitation + leaf_long => pftcon%leaf_long , & ! Input: leaf longevity (yrs) + woody => pftcon%woody , & ! Input: binary flag for woody lifeform (1=woody, 0=not woody) + stress_decid => pftcon%stress_decid , & ! Input: binary flag for stress-deciduous leaf habit (0 or 1) + + soilpsi => soilstate_inst%soilpsi_col , & ! Input: [real(r8) (:,:) ] soil water potential in each soil layer (MPa) + + t_soisno => temperature_inst%t_soisno_col , & ! Input: [real(r8) (:,:) ] soil temperature (Kelvin) (-nlevsno+1:nlevgrnd) + dormant_flag => cnveg_state_inst%dormant_flag_patch , & ! Output: [real(r8) (:) ] dormancy flag + days_active => cnveg_state_inst%days_active_patch , & ! Output: [real(r8) (:) ] number of days since last dormancy + onset_flag => cnveg_state_inst%onset_flag_patch , & ! Output: [real(r8) (:) ] onset flag + onset_counter => cnveg_state_inst%onset_counter_patch , & ! Output: [real(r8) (:) ] onset counter (seconds) + onset_gddflag => cnveg_state_inst%onset_gddflag_patch , & ! Output: [real(r8) (:) ] onset freeze flag + onset_fdd => cnveg_state_inst%onset_fdd_patch , & ! Output: [real(r8) (:) ] onset freezing degree days counter + onset_gdd => cnveg_state_inst%onset_gdd_patch , & ! Output: [real(r8) (:) ] onset growing degree days + onset_swi => cnveg_state_inst%onset_swi_patch , & ! Output: [real(r8) (:) ] onset soil water index + offset_flag => cnveg_state_inst%offset_flag_patch , & ! Output: [real(r8) (:) ] offset flag + offset_counter => cnveg_state_inst%offset_counter_patch , & ! Output: [real(r8) (:) ] offset counter (seconds) + offset_fdd => cnveg_state_inst%offset_fdd_patch , & ! Output: [real(r8) (:) ] offset freezing degree days counter + offset_swi => cnveg_state_inst%offset_swi_patch , & ! Output: [real(r8) (:) ] offset soil water index + lgsf => cnveg_state_inst%lgsf_patch , & ! Output: [real(r8) (:) ] long growing season factor [0-1] + bglfr => cnveg_state_inst%bglfr_patch , & ! Output: [real(r8) (:) ] background litterfall rate (1/s) + bgtr => cnveg_state_inst%bgtr_patch , & ! Output: [real(r8) (:) ] background transfer growth rate (1/s) + annavg_t2m => cnveg_state_inst%annavg_t2m_patch , & ! Output: [real(r8) (:) ] annual average 2m air temperature (K) + 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 + 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 , & ! Output: [real(r8) (:) ] (gC/m2) leaf C transfer + frootc_xfer => cnveg_carbonstate_inst%frootc_xfer_patch , & ! Output: [real(r8) (:) ] (gC/m2) fine root C transfer + livestemc_xfer => cnveg_carbonstate_inst%livestemc_xfer_patch , & ! Output: [real(r8) (:) ] (gC/m2) live stem C transfer + deadstemc_xfer => cnveg_carbonstate_inst%deadstemc_xfer_patch , & ! Output: [real(r8) (:) ] (gC/m2) dead stem C transfer + livecrootc_xfer => cnveg_carbonstate_inst%livecrootc_xfer_patch , & ! Output: [real(r8) (:) ] (gC/m2) live coarse root C transfer + deadcrootc_xfer => cnveg_carbonstate_inst%deadcrootc_xfer_patch , & ! Output: [real(r8) (:) ] (gC/m2) dead coarse root C transfer + 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 , & ! Output: [real(r8) (:) ] (gN/m2) leaf N transfer + frootn_xfer => cnveg_nitrogenstate_inst%frootn_xfer_patch , & ! Output: [real(r8) (:) ] (gN/m2) fine root N transfer + livestemn_xfer => cnveg_nitrogenstate_inst%livestemn_xfer_patch , & ! Output: [real(r8) (:) ] (gN/m2) live stem N transfer + deadstemn_xfer => cnveg_nitrogenstate_inst%deadstemn_xfer_patch , & ! Output: [real(r8) (:) ] (gN/m2) dead stem N transfer + livecrootn_xfer => cnveg_nitrogenstate_inst%livecrootn_xfer_patch , & ! Output: [real(r8) (:) ] (gN/m2) live coarse root N transfer + deadcrootn_xfer => cnveg_nitrogenstate_inst%deadcrootn_xfer_patch , & ! Output: [real(r8) (:) ] (gN/m2) dead coarse root N transfer + + prev_leafc_to_litter => cnveg_carbonflux_inst%prev_leafc_to_litter_patch , & ! Output: [real(r8) (:) ] previous timestep leaf C litterfall flux (gC/m2/s) + prev_frootc_to_litter => cnveg_carbonflux_inst%prev_frootc_to_litter_patch , & ! Output: [real(r8) (:) ] previous timestep froot C litterfall flux (gC/m2/s) + leafc_xfer_to_leafc => cnveg_carbonflux_inst%leafc_xfer_to_leafc_patch , & ! Output: [real(r8) (:) ] + frootc_xfer_to_frootc => cnveg_carbonflux_inst%frootc_xfer_to_frootc_patch , & ! Output: [real(r8) (:) ] + livestemc_xfer_to_livestemc => cnveg_carbonflux_inst%livestemc_xfer_to_livestemc_patch , & ! Output: [real(r8) (:) ] + deadstemc_xfer_to_deadstemc => cnveg_carbonflux_inst%deadstemc_xfer_to_deadstemc_patch , & ! Output: [real(r8) (:) ] + livecrootc_xfer_to_livecrootc => cnveg_carbonflux_inst%livecrootc_xfer_to_livecrootc_patch , & ! Output: [real(r8) (:) ] + deadcrootc_xfer_to_deadcrootc => cnveg_carbonflux_inst%deadcrootc_xfer_to_deadcrootc_patch , & ! Output: [real(r8) (:) ] + leafc_storage_to_xfer => cnveg_carbonflux_inst%leafc_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] + frootc_storage_to_xfer => cnveg_carbonflux_inst%frootc_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] + livestemc_storage_to_xfer => cnveg_carbonflux_inst%livestemc_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] + deadstemc_storage_to_xfer => cnveg_carbonflux_inst%deadstemc_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] + livecrootc_storage_to_xfer => cnveg_carbonflux_inst%livecrootc_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] + deadcrootc_storage_to_xfer => cnveg_carbonflux_inst%deadcrootc_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] + gresp_storage_to_xfer => cnveg_carbonflux_inst%gresp_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] + + leafn_xfer_to_leafn => cnveg_nitrogenflux_inst%leafn_xfer_to_leafn_patch , & ! Output: [real(r8) (:) ] + frootn_xfer_to_frootn => cnveg_nitrogenflux_inst%frootn_xfer_to_frootn_patch , & ! Output: [real(r8) (:) ] + livestemn_xfer_to_livestemn => cnveg_nitrogenflux_inst%livestemn_xfer_to_livestemn_patch , & ! Output: [real(r8) (:) ] + deadstemn_xfer_to_deadstemn => cnveg_nitrogenflux_inst%deadstemn_xfer_to_deadstemn_patch , & ! Output: [real(r8) (:) ] + livecrootn_xfer_to_livecrootn => cnveg_nitrogenflux_inst%livecrootn_xfer_to_livecrootn_patch , & ! Output: [real(r8) (:) ] + deadcrootn_xfer_to_deadcrootn => cnveg_nitrogenflux_inst%deadcrootn_xfer_to_deadcrootn_patch , & ! Output: [real(r8) (:) ] + leafn_storage_to_xfer => cnveg_nitrogenflux_inst%leafn_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] + frootn_storage_to_xfer => cnveg_nitrogenflux_inst%frootn_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] + livestemn_storage_to_xfer => cnveg_nitrogenflux_inst%livestemn_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] + deadstemn_storage_to_xfer => cnveg_nitrogenflux_inst%deadstemn_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] + livecrootn_storage_to_xfer => cnveg_nitrogenflux_inst%livecrootn_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] + deadcrootn_storage_to_xfer => cnveg_nitrogenflux_inst%deadcrootn_storage_to_xfer_patch & ! Output: [real(r8) (:) ] + ) + + ! set time steps + dayspyr = get_days_per_year() + + ! specify rain threshold for leaf onset + rain_threshold = 20._r8 + + do fp = 1,num_soilp + p = filter_soilp(fp) + c = patch%column(p) + g = patch%gridcell(p) + + if (stress_decid(ivt(p)) == 1._r8) then + soilt = t_soisno(c,3) + psi = soilpsi(c,3) + + ! onset gdd sum from Biome-BGC, v4.1.2 + crit_onset_gdd = exp(4.8_r8 + 0.13_r8*(annavg_t2m(p) - SHR_CONST_TKFRZ)) + + + ! update offset_counter and test for the end of the offset period + if (offset_flag(p) == 1._r8) then + ! decrement counter for offset period + offset_counter(p) = offset_counter(p) - dt + + ! if this is the end of the offset_period, reset phenology + ! flags and indices + if (offset_counter(p) == 0._r8) then + ! this code block was originally handled by call cn_offset_cleanup(p) + ! inlined during vectorization + offset_flag(p) = 0._r8 + offset_counter(p) = 0._r8 + dormant_flag(p) = 1._r8 + days_active(p) = 0._r8 + + ! reset the previous timestep litterfall flux memory + prev_leafc_to_litter(p) = 0._r8 + prev_frootc_to_litter(p) = 0._r8 + end if + end if + + ! update onset_counter and test for the end of the onset period + if (onset_flag(p) == 1.0_r8) then + ! decrement counter for onset period + onset_counter(p) = onset_counter(p) - dt + + ! if this is the end of the onset period, reset phenology + ! flags and indices + if (onset_counter(p) == 0.0_r8) then + ! this code block was originally handled by call cn_onset_cleanup(p) + ! inlined during vectorization + onset_flag(p) = 0._r8 + onset_counter(p) = 0._r8 + ! set all transfer growth rates to 0.0 + leafc_xfer_to_leafc(p) = 0._r8 + frootc_xfer_to_frootc(p) = 0._r8 + leafn_xfer_to_leafn(p) = 0._r8 + frootn_xfer_to_frootn(p) = 0._r8 + if (woody(ivt(p)) == 1.0_r8) then + livestemc_xfer_to_livestemc(p) = 0._r8 + deadstemc_xfer_to_deadstemc(p) = 0._r8 + livecrootc_xfer_to_livecrootc(p) = 0._r8 + deadcrootc_xfer_to_deadcrootc(p) = 0._r8 + livestemn_xfer_to_livestemn(p) = 0._r8 + deadstemn_xfer_to_deadstemn(p) = 0._r8 + livecrootn_xfer_to_livecrootn(p) = 0._r8 + deadcrootn_xfer_to_deadcrootn(p) = 0._r8 + end if + ! set transfer pools to 0.0 + leafc_xfer(p) = 0._r8 + leafn_xfer(p) = 0._r8 + frootc_xfer(p) = 0._r8 + frootn_xfer(p) = 0._r8 + if (woody(ivt(p)) == 1.0_r8) then + livestemc_xfer(p) = 0._r8 + livestemn_xfer(p) = 0._r8 + deadstemc_xfer(p) = 0._r8 + deadstemn_xfer(p) = 0._r8 + livecrootc_xfer(p) = 0._r8 + livecrootn_xfer(p) = 0._r8 + deadcrootc_xfer(p) = 0._r8 + deadcrootn_xfer(p) = 0._r8 + end if + end if + end if + + ! test for switching from dormant period to growth period + if (dormant_flag(p) == 1._r8) then + + ! keep track of the number of freezing degree days in this + ! dormancy period (only if the freeze flag has not previously been set + ! for this dormancy period + + if (onset_gddflag(p) == 0._r8 .and. soilt < SHR_CONST_TKFRZ) onset_fdd(p) = onset_fdd(p) + fracday + + ! if the number of freezing degree days exceeds a critical value, + ! then onset will require both wet soils and a critical soil + ! temperature sum. If this case is triggered, reset any previously + ! accumulated value in onset_swi, so that onset now depends on + ! the accumulated soil water index following the freeze trigger + + if (onset_fdd(p) > crit_onset_fdd) then + onset_gddflag(p) = 1._r8 + onset_fdd(p) = 0._r8 + onset_swi(p) = 0._r8 + end if + + ! if the freeze flag is set, and if the soil is above freezing + ! then accumulate growing degree days for onset trigger + + if (onset_gddflag(p) == 1._r8 .and. soilt > SHR_CONST_TKFRZ) then + onset_gdd(p) = onset_gdd(p) + (soilt-SHR_CONST_TKFRZ)*fracday + end if + + ! if soils are wet, accumulate soil water index for onset trigger + additional_onset_condition = .true. + if(CNParamsShareInst%constrain_stress_deciduous_onset) then + ! if additional constraint condition not met, set to false + if ((prec10(p) * (3600.0_r8*10.0_r8*24.0_r8)) < rain_threshold) then + additional_onset_condition = .false. + endif + endif + + if (psi >= soilpsi_on) then + onset_swi(p) = onset_swi(p) + fracday + endif + + ! if critical soil water index is exceeded, set onset_flag, and + ! then test for soil temperature criteria + + ! Adding in Kyla's rainfall trigger when fun on. RF. prec10 (mm/s) needs to be higher than 8mm over 10 days. + + if (onset_swi(p) > crit_onset_swi.and. additional_onset_condition) then + onset_flag(p) = 1._r8 + + ! only check soil temperature criteria if freeze flag set since + ! beginning of last dormancy. If freeze flag set and growing + ! degree day sum (since freeze trigger) is lower than critical + ! value, then override the onset_flag set from soil water. + + if (onset_gddflag(p) == 1._r8 .and. onset_gdd(p) < crit_onset_gdd) onset_flag(p) = 0._r8 + end if + + ! only allow onset if dayl > 6hrs + if (onset_flag(p) == 1._r8 .and. dayl(g) <= secspqtrday) then + onset_flag(p) = 0._r8 + end if + + ! if this is the beginning of the onset period + ! then reset the phenology flags and indices + + if (onset_flag(p) == 1._r8) then + dormant_flag(p) = 0._r8 + days_active(p) = 0._r8 + onset_gddflag(p) = 0._r8 + onset_fdd(p) = 0._r8 + onset_gdd(p) = 0._r8 + onset_swi(p) = 0._r8 + onset_counter(p) = ndays_on * secspday + + ! call subroutine to move all the storage pools into transfer pools, + ! where they will be transfered to displayed growth over the onset period. + ! this code was originally handled with call cn_storage_to_xfer(p) + ! inlined during vectorization + + ! set carbon fluxes for shifting storage pools to transfer pools + leafc_storage_to_xfer(p) = fstor2tran * leafc_storage(p)/dt + frootc_storage_to_xfer(p) = fstor2tran * frootc_storage(p)/dt + if (woody(ivt(p)) == 1.0_r8) then + livestemc_storage_to_xfer(p) = fstor2tran * livestemc_storage(p)/dt + deadstemc_storage_to_xfer(p) = fstor2tran * deadstemc_storage(p)/dt + livecrootc_storage_to_xfer(p) = fstor2tran * livecrootc_storage(p)/dt + deadcrootc_storage_to_xfer(p) = fstor2tran * deadcrootc_storage(p)/dt + gresp_storage_to_xfer(p) = fstor2tran * gresp_storage(p)/dt + end if + + ! set nitrogen fluxes for shifting storage pools to transfer pools + leafn_storage_to_xfer(p) = fstor2tran * leafn_storage(p)/dt + frootn_storage_to_xfer(p) = fstor2tran * frootn_storage(p)/dt + if (woody(ivt(p)) == 1.0_r8) then + livestemn_storage_to_xfer(p) = fstor2tran * livestemn_storage(p)/dt + deadstemn_storage_to_xfer(p) = fstor2tran * deadstemn_storage(p)/dt + livecrootn_storage_to_xfer(p) = fstor2tran * livecrootn_storage(p)/dt + deadcrootn_storage_to_xfer(p) = fstor2tran * deadcrootn_storage(p)/dt + end if + end if + + ! test for switching from growth period to offset period + else if (offset_flag(p) == 0._r8) then + + ! if soil water potential lower than critical value, accumulate + ! as stress in offset soil water index + + if (psi <= soilpsi_off) then + offset_swi(p) = offset_swi(p) + fracday + + ! if the offset soil water index exceeds critical value, and + ! if this is not the middle of a previously initiated onset period, + ! then set flag to start the offset period and reset index variables + + if (offset_swi(p) >= crit_offset_swi .and. onset_flag(p) == 0._r8) offset_flag(p) = 1._r8 + + ! if soil water potential higher than critical value, reduce the + ! offset water stress index. By this mechanism, there must be a + ! sustained period of water stress to initiate offset. + + else if (psi >= soilpsi_on) then + offset_swi(p) = offset_swi(p) - fracday + offset_swi(p) = max(offset_swi(p),0._r8) + end if + + ! decrease freezing day accumulator for warm soil + if (offset_fdd(p) > 0._r8 .and. soilt > SHR_CONST_TKFRZ) then + offset_fdd(p) = offset_fdd(p) - fracday + offset_fdd(p) = max(0._r8, offset_fdd(p)) + end if + + ! increase freezing day accumulator for cold soil + if (soilt <= SHR_CONST_TKFRZ) then + offset_fdd(p) = offset_fdd(p) + fracday + + ! if freezing degree day sum is greater than critical value, initiate offset + if (offset_fdd(p) > crit_offset_fdd .and. onset_flag(p) == 0._r8) offset_flag(p) = 1._r8 + end if + + ! force offset if daylength is < 6 hrs + if (dayl(g) <= secspqtrday) then + offset_flag(p) = 1._r8 + end if + + ! if this is the beginning of the offset period + ! then reset flags and indices + if (offset_flag(p) == 1._r8) then + offset_fdd(p) = 0._r8 + offset_swi(p) = 0._r8 + offset_counter(p) = ndays_off * secspday + prev_leafc_to_litter(p) = 0._r8 + prev_frootc_to_litter(p) = 0._r8 + end if + end if + + ! keep track of number of days since last dormancy for control on + ! fraction of new growth to send to storage for next growing season + + if (dormant_flag(p) == 0.0_r8) then + days_active(p) = days_active(p) + fracday + end if + + ! calculate long growing season factor (lgsf) + ! only begin to calculate a lgsf greater than 0.0 once the number + ! of days active exceeds days/year. + lgsf(p) = max(min(3.0_r8*(days_active(p)-leaf_long(ivt(p))*dayspyr )/dayspyr, 1._r8),0._r8) + ! RosieF. 5 Nov 2015. Changed this such that the increase in leaf turnover is faster after + ! trees enter the 'fake evergreen' state. Otherwise, they have a whole year of + ! cheating, with less litterfall than they should have, resulting in very high LAI. + ! Further, the 'fake evergreen' state (where lgsf>0) is entered at the end of a single leaf lifespan + ! and not a whole year. The '3' is arbitrary, given that this entire system is quite abstract. + + + ! set background litterfall rate, when not in the phenological offset period + if (offset_flag(p) == 1._r8) then + bglfr(p) = 0._r8 + else + ! calculate the background litterfall rate (bglfr) + ! in units 1/s, based on leaf longevity (yrs) and correction for long growing season + + bglfr(p) = (1._r8/(leaf_long(ivt(p))*dayspyr*secspday))*lgsf(p) + end if + + ! set background transfer rate when active but not in the phenological onset period + if (onset_flag(p) == 1._r8) then + bgtr(p) = 0._r8 + else + ! the background transfer rate is calculated as the rate that would result + ! in complete turnover of the storage pools in one year at steady state, + ! once lgsf has reached 1.0 (after 730 days active). + + bgtr(p) = (1._r8/(dayspyr*secspday))*lgsf(p) + + ! set carbon fluxes for shifting storage pools to transfer pools + + ! reduced the amount of stored carbon flowing to display pool by only counting the delta + ! between leafc and leafc_store in the flux. RosieF, Nov5 2015. + leafc_storage_to_xfer(p) = max(0.0_r8,(leafc_storage(p)-leafc(p))) * bgtr(p) + frootc_storage_to_xfer(p) = max(0.0_r8,(frootc_storage(p)-frootc(p))) * bgtr(p) + if (woody(ivt(p)) == 1.0_r8) then + livestemc_storage_to_xfer(p) = livestemc_storage(p) * bgtr(p) + deadstemc_storage_to_xfer(p) = deadstemc_storage(p) * bgtr(p) + livecrootc_storage_to_xfer(p) = livecrootc_storage(p) * bgtr(p) + deadcrootc_storage_to_xfer(p) = deadcrootc_storage(p) * bgtr(p) + gresp_storage_to_xfer(p) = gresp_storage(p) * bgtr(p) + end if + + ! set nitrogen fluxes for shifting storage pools to transfer pools + leafn_storage_to_xfer(p) = leafn_storage(p) * bgtr(p) + frootn_storage_to_xfer(p) = frootn_storage(p) * bgtr(p) + if (woody(ivt(p)) == 1.0_r8) then + livestemn_storage_to_xfer(p) = livestemn_storage(p) * bgtr(p) + deadstemn_storage_to_xfer(p) = deadstemn_storage(p) * bgtr(p) + livecrootn_storage_to_xfer(p) = livecrootn_storage(p) * bgtr(p) + deadcrootn_storage_to_xfer(p) = deadcrootn_storage(p) * bgtr(p) + end if + end if + + end if ! end if stress deciduous + + end do ! end of patch loop + + end associate + + end subroutine CNStressDecidPhenology + + !----------------------------------------------------------------------- + subroutine CropPhenology(num_pcropp, filter_pcropp , & + waterdiagnosticbulk_inst, temperature_inst, crop_inst, canopystate_inst, cnveg_state_inst , & + cnveg_carbonstate_inst, cnveg_nitrogenstate_inst, cnveg_carbonflux_inst, cnveg_nitrogenflux_inst,& + c13_cnveg_carbonstate_inst, c14_cnveg_carbonstate_inst) + + ! !DESCRIPTION: + ! Code from AgroIBIS to determine crop phenology and code from CN to + ! handle CN fluxes during the phenological onset & offset periods. + + ! !USES: + use clm_time_manager , only : get_curr_date, get_curr_calday, get_days_per_year, get_rad_step_size + use pftconMod , only : ntmp_corn, nswheat, nwwheat, ntmp_soybean + use pftconMod , only : nirrig_tmp_corn, nirrig_swheat, nirrig_wwheat, nirrig_tmp_soybean + use pftconMod , only : ntrp_corn, nsugarcane, ntrp_soybean, ncotton, nrice + use pftconMod , only : nirrig_trp_corn, nirrig_sugarcane, nirrig_trp_soybean + use pftconMod , only : nirrig_cotton, nirrig_rice + + ! Y. Cheng + use pftconMod , only : nmiscanthus, nirrig_miscanthus, nswitchgrass, nirrig_switchgrass + + use clm_varcon , only : spval, secspday + use clm_varctl , only : use_fertilizer + use clm_varctl , only : use_c13, use_c14 + use clm_varcon , only : c13ratio, c14ratio + ! + ! !ARGUMENTS: + integer , intent(in) :: num_pcropp ! number of prog crop patches in filter + integer , intent(in) :: filter_pcropp(:) ! filter for prognostic crop patches + type(waterdiagnosticbulk_type) , intent(in) :: waterdiagnosticbulk_inst + type(temperature_type) , intent(in) :: temperature_inst + type(crop_type) , intent(inout) :: crop_inst + type(canopystate_type) , intent(in) :: canopystate_inst + type(cnveg_state_type) , intent(inout) :: cnveg_state_inst + type(cnveg_carbonstate_type) , intent(inout) :: cnveg_carbonstate_inst + type(cnveg_nitrogenstate_type) , intent(inout) :: cnveg_nitrogenstate_inst + type(cnveg_carbonflux_type) , intent(inout) :: cnveg_carbonflux_inst + type(cnveg_nitrogenflux_type) , intent(inout) :: cnveg_nitrogenflux_inst + type(cnveg_carbonstate_type) , intent(inout) :: c13_cnveg_carbonstate_inst + type(cnveg_carbonstate_type) , intent(inout) :: c14_cnveg_carbonstate_inst + ! + ! LOCAL VARAIBLES: + integer kyr ! current year + integer kmo ! month of year (1, ..., 12) + integer kda ! day of month (1, ..., 31) + integer mcsec ! seconds of day (0, ..., seconds/day) + integer jday ! julian day of the year + integer fp,p ! patch indices + integer c ! column indices + integer g ! gridcell indices + integer h ! hemisphere indices + integer idpp ! number of days past planting + real(r8) :: dtrad ! radiation time step delta t (seconds) + real(r8) dayspyr ! days per year + real(r8) crmcorn ! comparitive relative maturity for corn + real(r8) ndays_on ! number of days to fertilize + !------------------------------------------------------------------------ + + associate( & + ivt => patch%itype , & ! Input: [integer (:) ] patch vegetation type + + leaf_long => pftcon%leaf_long , & ! Input: leaf longevity (yrs) + leafcn => pftcon%leafcn , & ! Input: leaf C:N (gC/gN) + manunitro => pftcon%manunitro , & ! Input: max manure to be applied in total (kgN/m2) + mxmat => pftcon%mxmat , & ! Input: + minplanttemp => pftcon%minplanttemp , & ! Input: + planttemp => pftcon%planttemp , & ! Input: + gddmin => pftcon%gddmin , & ! Input: + hybgdd => pftcon%hybgdd , & ! Input: + lfemerg => pftcon%lfemerg , & ! Input: + grnfill => pftcon%grnfill , & ! Input: + + t_ref2m_min => temperature_inst%t_ref2m_min_patch , & ! Input: [real(r8) (:) ] daily minimum of average 2 m height surface air temperature (K) + t10 => temperature_inst%t_a10_patch , & ! Input: [real(r8) (:) ] 10-day running mean of the 2 m temperature (K) + a5tmin => temperature_inst%t_a5min_patch , & ! Input: [real(r8) (:) ] 5-day running mean of min 2-m temperature + a10tmin => temperature_inst%t_a10min_patch , & ! Input: [real(r8) (:) ] 10-day running mean of min 2-m temperature + gdd020 => temperature_inst%gdd020_patch , & ! Input: [real(r8) (:) ] 20 yr mean of gdd0 + gdd820 => temperature_inst%gdd820_patch , & ! Input: [real(r8) (:) ] 20 yr mean of gdd8 + gdd1020 => temperature_inst%gdd1020_patch , & ! Input: [real(r8) (:) ] 20 yr mean of gdd10 + + fertnitro => crop_inst%fertnitro_patch , & ! Input: [real(r8) (:) ] fertilizer nitrogen + hui => crop_inst%gddplant_patch , & ! Input: [real(r8) (:) ] gdd since planting (gddplant) + leafout => crop_inst%gddtsoi_patch , & ! Input: [real(r8) (:) ] gdd from top soil layer temperature + harvdate => crop_inst%harvdate_patch , & ! Output: [integer (:) ] harvest date + croplive => crop_inst%croplive_patch , & ! Output: [logical (:) ] Flag, true if planted, not harvested + cropplant => crop_inst%cropplant_patch , & ! Output: [logical (:) ] Flag, true if crop may be planted + vf => crop_inst%vf_patch , & ! Output: [real(r8) (:) ] vernalization factor + peaklai => cnveg_state_inst%peaklai_patch , & ! Output: [integer (:) ] 1: max allowed lai; 0: not at max + tlai => canopystate_inst%tlai_patch , & ! Input: [real(r8) (:) ] one-sided leaf area index, no burying by snow + + idop => cnveg_state_inst%idop_patch , & ! Output: [integer (:) ] date of planting + gddmaturity => cnveg_state_inst%gddmaturity_patch , & ! Output: [real(r8) (:) ] gdd needed to harvest + huileaf => cnveg_state_inst%huileaf_patch , & ! Output: [real(r8) (:) ] heat unit index needed from planting to leaf emergence + huigrain => cnveg_state_inst%huigrain_patch , & ! Output: [real(r8) (:) ] same to reach vegetative maturity + cumvd => cnveg_state_inst%cumvd_patch , & ! Output: [real(r8) (:) ] cumulative vernalization d?ependence? + hdidx => cnveg_state_inst%hdidx_patch , & ! Output: [real(r8) (:) ] cold hardening index? + bglfr => cnveg_state_inst%bglfr_patch , & ! Output: [real(r8) (:) ] background litterfall rate (1/s) + bgtr => cnveg_state_inst%bgtr_patch , & ! Output: [real(r8) (:) ] background transfer growth rate (1/s) + lgsf => cnveg_state_inst%lgsf_patch , & ! Output: [real(r8) (:) ] long growing season factor [0-1] + onset_flag => cnveg_state_inst%onset_flag_patch , & ! Output: [real(r8) (:) ] onset flag + offset_flag => cnveg_state_inst%offset_flag_patch , & ! Output: [real(r8) (:) ] offset flag + onset_counter => cnveg_state_inst%onset_counter_patch , & ! Output: [real(r8) (:) ] onset counter + offset_counter => cnveg_state_inst%offset_counter_patch , & ! Output: [real(r8) (:) ] offset counter + + leafc_xfer => cnveg_carbonstate_inst%leafc_xfer_patch , & ! Output: [real(r8) (:) ] (gC/m2) leaf C transfer + + crop_seedc_to_leaf => cnveg_carbonflux_inst%crop_seedc_to_leaf_patch, & ! Output: [real(r8) (:) ] (gC/m2/s) seed source to leaf + + fert_counter => cnveg_nitrogenflux_inst%fert_counter_patch , & ! Output: [real(r8) (:) ] >0 fertilize; <=0 not (seconds) + leafn_xfer => cnveg_nitrogenstate_inst%leafn_xfer_patch , & ! Output: [real(r8) (:) ] (gN/m2) leaf N transfer + crop_seedn_to_leaf => cnveg_nitrogenflux_inst%crop_seedn_to_leaf_patch, & ! Output: [real(r8) (:) ] (gN/m2/s) seed source to leaf + cphase => crop_inst%cphase_patch , & ! Output: [real(r8) (:)] phenology phase + fert => cnveg_nitrogenflux_inst%fert_patch & ! Output: [real(r8) (:) ] (gN/m2/s) fertilizer applied each timestep + ) + + ! get time info + dayspyr = get_days_per_year() + jday = get_curr_calday() + call get_curr_date(kyr, kmo, kda, mcsec) + dtrad = real( get_rad_step_size(), r8 ) + + if (use_fertilizer) then + ndays_on = 20._r8 ! number of days to fertilize + else + ndays_on = 0._r8 ! number of days to fertilize + end if + + do fp = 1, num_pcropp + p = filter_pcropp(fp) + c = patch%column(p) + g = patch%gridcell(p) + h = inhemi(p) + + ! background litterfall and transfer rates; long growing season factor + + bglfr(p) = 0._r8 ! this value changes later in a crop's life cycle + bgtr(p) = 0._r8 + lgsf(p) = 0._r8 + + ! --------------------------------- + ! from AgroIBIS subroutine planting + ! --------------------------------- + + ! in order to allow a crop to be planted only once each year + ! initialize cropplant = .false., but hold it = .true. through the end of the year + + ! initialize other variables that are calculated for crops + ! on an annual basis in cropresidue subroutine + + if ( jday == jdayyrstart(h) .and. mcsec == 0 )then + + ! make sure variables aren't changed at beginning of the year + ! for a crop that is currently planted, such as + ! WINTER TEMPERATE CEREAL = winter (wheat + barley + rye) + ! represented here by the winter wheat pft + + if (.not. croplive(p)) then + cropplant(p) = .false. + idop(p) = NOT_Planted + + ! keep next for continuous, annual winter temperate cereal crop; + ! if we removed elseif, + ! winter cereal grown continuously would amount to a cereal/fallow + ! rotation because cereal would only be planted every other year + + else if (croplive(p) .and. (ivt(p) == nwwheat .or. ivt(p) == nirrig_wwheat)) then + cropplant(p) = .false. + ! else ! not possible to have croplive and ivt==cornORsoy? (slevis) + end if + + end if + + if ( (.not. croplive(p)) .and. (.not. cropplant(p)) ) then + + ! gdd needed for * chosen crop and a likely hybrid (for that region) * + ! to reach full physiological maturity + + ! based on accumulated seasonal average growing degree days from + ! April 1 - Sept 30 (inclusive) + ! for corn and soybeans in the United States - + ! decided upon by what the typical average growing season length is + ! and the gdd needed to reach maturity in those regions + + ! first choice is used for spring temperate cereal and/or soybeans and maize + + ! slevis: ibis reads xinpdate in io.f from control.crops.nc variable name 'plantdate' + ! According to Chris Kucharik, the dataset of + ! xinpdate was generated from a previous model run at 0.5 deg resolution + + ! winter temperate cereal : use gdd0 as a limit to plant winter cereal + + if (ivt(p) == nwwheat .or. ivt(p) == nirrig_wwheat) then + + ! add check to only plant winter cereal after other crops (soybean, maize) + ! have been harvested + + ! *** remember order of planting is crucial - in terms of which crops you want + ! to be grown in what order *** + + ! in this case, corn or soybeans are assumed to be planted before + ! cereal would be in any particular year that both patches are allowed + ! to grow in the same grid cell (e.g., double-cropping) + + ! slevis: harvdate below needs cropplant(p) above to be cropplant(p,ivt(p)) + ! where ivt(p) has rotated to winter cereal because + ! cropplant through the end of the year for a harvested crop. + ! Also harvdate(p) should be harvdate(p,ivt(p)) and should be + ! updated on Jan 1st instead of at harvest (slevis) + if (a5tmin(p) /= spval .and. & + a5tmin(p) <= minplanttemp(ivt(p)) .and. & + jday >= minplantjday(ivt(p),h) .and. & + (gdd020(p) /= spval .and. & + gdd020(p) >= gddmin(ivt(p)))) then + + cumvd(p) = 0._r8 + hdidx(p) = 0._r8 + vf(p) = 0._r8 + croplive(p) = .true. + cropplant(p) = .true. + idop(p) = jday + harvdate(p) = NOT_Harvested + gddmaturity(p) = hybgdd(ivt(p)) + leafc_xfer(p) = initial_seed_at_planting + leafn_xfer(p) = leafc_xfer(p) / leafcn(ivt(p)) ! with onset + crop_seedc_to_leaf(p) = leafc_xfer(p)/dt + crop_seedn_to_leaf(p) = leafn_xfer(p)/dt + + ! because leafc_xfer is set above rather than incremneted through the normal process, must also set its isotope + ! pools here. use totvegc_patch as the closest analogue if nonzero, and use initial value otherwise + if (use_c13) then + if ( cnveg_carbonstate_inst%totvegc_patch(p) .gt. 0._r8) then + c13_cnveg_carbonstate_inst%leafc_xfer_patch(p) = leafc_xfer(p) * & + c13_cnveg_carbonstate_inst%totvegc_patch(p) / cnveg_carbonstate_inst%totvegc_patch(p) + else + c13_cnveg_carbonstate_inst%leafc_xfer_patch(p) = leafc_xfer(p) * c13ratio + endif + endif + if (use_c14) then + if ( cnveg_carbonstate_inst%totvegc_patch(p) .gt. 0._r8) then + c14_cnveg_carbonstate_inst%leafc_xfer_patch(p) = leafc_xfer(p) * & + c14_cnveg_carbonstate_inst%totvegc_patch(p) / cnveg_carbonstate_inst%totvegc_patch(p) + else + c14_cnveg_carbonstate_inst%leafc_xfer_patch(p) = leafc_xfer(p) * c14ratio + endif + endif + + ! latest possible date to plant winter cereal and after all other + ! crops were harvested for that year + + else if (jday >= maxplantjday(ivt(p),h) .and. & + gdd020(p) /= spval .and. & + gdd020(p) >= gddmin(ivt(p))) then + + cumvd(p) = 0._r8 + hdidx(p) = 0._r8 + vf(p) = 0._r8 + croplive(p) = .true. + cropplant(p) = .true. + idop(p) = jday + harvdate(p) = NOT_Harvested + gddmaturity(p) = hybgdd(ivt(p)) + leafc_xfer(p) = initial_seed_at_planting + leafn_xfer(p) = leafc_xfer(p) / leafcn(ivt(p)) ! with onset + crop_seedc_to_leaf(p) = leafc_xfer(p)/dt + crop_seedn_to_leaf(p) = leafn_xfer(p)/dt + + ! because leafc_xfer is set above rather than incremneted through the normal process, must also set its isotope + ! pools here. use totvegc_patch as the closest analogue if nonzero, and use initial value otherwise + if (use_c13) then + if ( cnveg_carbonstate_inst%totvegc_patch(p) .gt. 0._r8) then + c13_cnveg_carbonstate_inst%leafc_xfer_patch(p) = leafc_xfer(p) * & + c13_cnveg_carbonstate_inst%totvegc_patch(p) / cnveg_carbonstate_inst%totvegc_patch(p) + else + c13_cnveg_carbonstate_inst%leafc_xfer_patch(p) = leafc_xfer(p) * c13ratio + endif + endif + if (use_c14) then + if ( cnveg_carbonstate_inst%totvegc_patch(p) .gt. 0._r8) then + c14_cnveg_carbonstate_inst%leafc_xfer_patch(p) = leafc_xfer(p) * & + c14_cnveg_carbonstate_inst%totvegc_patch(p) / cnveg_carbonstate_inst%totvegc_patch(p) + else + c14_cnveg_carbonstate_inst%leafc_xfer_patch(p) = leafc_xfer(p) * c14ratio + endif + endif + else + gddmaturity(p) = 0._r8 + end if + + else ! not winter cereal... slevis: added distinction between NH and SH + ! slevis: The idea is that jday will equal idop sooner or later in the year + ! while the gdd part is either true or false for the year. + if (t10(p) /= spval.and. a10tmin(p) /= spval .and. & + t10(p) > planttemp(ivt(p)) .and. & + a10tmin(p) > minplanttemp(ivt(p)) .and. & + jday >= minplantjday(ivt(p),h) .and. & + jday <= maxplantjday(ivt(p),h) .and. & + t10(p) /= spval .and. a10tmin(p) /= spval .and. & + gdd820(p) /= spval .and. & + gdd820(p) >= gddmin(ivt(p))) then + + ! impose limit on growing season length needed + ! for crop maturity - for cold weather constraints + croplive(p) = .true. + cropplant(p) = .true. + idop(p) = jday + harvdate(p) = NOT_Harvested + + ! go a specified amount of time before/after + ! climatological date + if (ivt(p) == ntmp_soybean .or. ivt(p) == nirrig_tmp_soybean .or. & + ivt(p) == ntrp_soybean .or. ivt(p) == nirrig_trp_soybean) then + gddmaturity(p) = min(gdd1020(p), hybgdd(ivt(p))) + end if + + ! Y. Cheng, add switchgrass and Miscanthus + if (ivt(p) == ntmp_corn .or. ivt(p) == nirrig_tmp_corn .or. & + ivt(p) == ntrp_corn .or. ivt(p) == nirrig_trp_corn .or. & + ivt(p) == nsugarcane .or. ivt(p) == nirrig_sugarcane .or. & + ivt(p) == nmiscanthus .or. ivt(p) == nirrig_miscanthus .or. & + ivt(p) == nswitchgrass .or. ivt(p) == nirrig_switchgrass) then + gddmaturity(p) = max(950._r8, min(gdd820(p)*0.85_r8, hybgdd(ivt(p)))) + gddmaturity(p) = max(950._r8, min(gddmaturity(p)+150._r8, 1850._r8)) + end if + if (ivt(p) == nswheat .or. ivt(p) == nirrig_swheat .or. & + ivt(p) == ncotton .or. ivt(p) == nirrig_cotton .or. & + ivt(p) == nrice .or. ivt(p) == nirrig_rice) then + gddmaturity(p) = min(gdd020(p), hybgdd(ivt(p))) + end if + + leafc_xfer(p) = initial_seed_at_planting + leafn_xfer(p) = leafc_xfer(p) / leafcn(ivt(p)) ! with onset + crop_seedc_to_leaf(p) = leafc_xfer(p)/dt + crop_seedn_to_leaf(p) = leafn_xfer(p)/dt + + ! because leafc_xfer is set above rather than incremneted through the normal process, must also set its isotope + ! pools here. use totvegc_patch as the closest analogue if nonzero, and use initial value otherwise + if (use_c13) then + if ( cnveg_carbonstate_inst%totvegc_patch(p) .gt. 0._r8) then + c13_cnveg_carbonstate_inst%leafc_xfer_patch(p) = leafc_xfer(p) * & + c13_cnveg_carbonstate_inst%totvegc_patch(p) / cnveg_carbonstate_inst%totvegc_patch(p) + else + c13_cnveg_carbonstate_inst%leafc_xfer_patch(p) = leafc_xfer(p) * c13ratio + endif + endif + if (use_c14) then + if ( cnveg_carbonstate_inst%totvegc_patch(p) .gt. 0._r8) then + c14_cnveg_carbonstate_inst%leafc_xfer_patch(p) = leafc_xfer(p) * & + c14_cnveg_carbonstate_inst%totvegc_patch(p) / cnveg_carbonstate_inst%totvegc_patch(p) + else + c14_cnveg_carbonstate_inst%leafc_xfer_patch(p) = leafc_xfer(p) * c14ratio + endif + endif + + + ! If hit the max planting julian day -- go ahead and plant + else if (jday == maxplantjday(ivt(p),h) .and. gdd820(p) > 0._r8 .and. & + gdd820(p) /= spval ) then + croplive(p) = .true. + cropplant(p) = .true. + idop(p) = jday + harvdate(p) = NOT_Harvested + + if (ivt(p) == ntmp_soybean .or. ivt(p) == nirrig_tmp_soybean .or. & + ivt(p) == ntrp_soybean .or. ivt(p) == nirrig_trp_soybean) then + gddmaturity(p) = min(gdd1020(p), hybgdd(ivt(p))) + end if + + ! Y. Cheng, add switchgrass and Miscanthus + if (ivt(p) == ntmp_corn .or. ivt(p) == nirrig_tmp_corn .or. & + ivt(p) == ntrp_corn .or. ivt(p) == nirrig_trp_corn .or. & + ivt(p) == nsugarcane .or. ivt(p) == nirrig_sugarcane .or. & + ivt(p) == nmiscanthus .or. ivt(p) == nirrig_miscanthus .or. & + ivt(p) == nswitchgrass .or. ivt(p) == nirrig_switchgrass) then + gddmaturity(p) = max(950._r8, min(gdd820(p)*0.85_r8, hybgdd(ivt(p)))) + end if + if (ivt(p) == nswheat .or. ivt(p) == nirrig_swheat .or. & + ivt(p) == ncotton .or. ivt(p) == nirrig_cotton .or. & + ivt(p) == nrice .or. ivt(p) == nirrig_rice) then + gddmaturity(p) = min(gdd020(p), hybgdd(ivt(p))) + end if + + leafc_xfer(p) = initial_seed_at_planting + leafn_xfer(p) = leafc_xfer(p) / leafcn(ivt(p)) ! with onset + crop_seedc_to_leaf(p) = leafc_xfer(p)/dt + crop_seedn_to_leaf(p) = leafn_xfer(p)/dt + + ! because leafc_xfer is set above rather than incremneted through the normal process, must also set its isotope + ! pools here. use totvegc_patch as the closest analogue if nonzero, and use initial value otherwise + if (use_c13) then + if ( cnveg_carbonstate_inst%totvegc_patch(p) .gt. 0._r8) then + c13_cnveg_carbonstate_inst%leafc_xfer_patch(p) = leafc_xfer(p) * & + c13_cnveg_carbonstate_inst%totvegc_patch(p) / cnveg_carbonstate_inst%totvegc_patch(p) + else + c13_cnveg_carbonstate_inst%leafc_xfer_patch(p) = leafc_xfer(p) * c13ratio + endif + endif + if (use_c14) then + if ( cnveg_carbonstate_inst%totvegc_patch(p) .gt. 0._r8) then + c14_cnveg_carbonstate_inst%leafc_xfer_patch(p) = leafc_xfer(p) * & + c14_cnveg_carbonstate_inst%totvegc_patch(p) / cnveg_carbonstate_inst%totvegc_patch(p) + else + c14_cnveg_carbonstate_inst%leafc_xfer_patch(p) = leafc_xfer(p) * c14ratio + endif + endif + + else + gddmaturity(p) = 0._r8 + end if + end if ! crop patch distinction + + ! crop phenology (gdd thresholds) controlled by gdd needed for + ! maturity (physiological) which is based on the average gdd + ! accumulation and hybrids in United States from April 1 - Sept 30 + + ! calculate threshold from phase 1 to phase 2: + ! threshold for attaining leaf emergence (based on fraction of + ! gdd(i) -- climatological average) + ! Hayhoe and Dwyer, 1990, Can. J. Soil Sci 70:493-497 + ! Carlson and Gage, 1989, Agric. For. Met., 45: 313-324 + ! J.T. Ritchie, 1991: Modeling Plant and Soil systems + + huileaf(p) = lfemerg(ivt(p)) * gddmaturity(p) ! 3-7% in cereal + + ! calculate threshhold from phase 2 to phase 3: + ! from leaf emergence to beginning of grain-fill period + ! this hypothetically occurs at the end of tassling, not the beginning + ! tassel initiation typically begins at 0.5-0.55 * gddmaturity + + ! calculate linear relationship between huigrain fraction and relative + ! maturity rating for maize + + ! Y. Cheng, add switchgrass and Miscanthus + if (ivt(p) == ntmp_corn .or. ivt(p) == nirrig_tmp_corn .or. & + ivt(p) == ntrp_corn .or. ivt(p) == nirrig_trp_corn .or. & + ivt(p) == nsugarcane .or. ivt(p) == nirrig_sugarcane .or. & + ivt(p) == nmiscanthus .or. ivt(p) == nirrig_miscanthus .or. & + ivt(p) == nswitchgrass .or. ivt(p) == nirrig_switchgrass) then + ! the following estimation of crmcorn from gddmaturity is based on a linear + ! regression using data from Pioneer-brand corn hybrids (Kucharik, 2003, + ! Earth Interactions 7:1-33: fig. 2) + crmcorn = max(73._r8, min(135._r8, (gddmaturity(p)+ 53.683_r8)/13.882_r8)) + + ! the following adjustment of grnfill based on crmcorn is based on a tuning + ! of Agro-IBIS to give reasonable results for max LAI and the seasonal + ! progression of LAI growth (pers. comm. C. Kucharik June 10, 2010) + huigrain(p) = -0.002_r8 * (crmcorn - 73._r8) + grnfill(ivt(p)) + + huigrain(p) = min(max(huigrain(p), grnfill(ivt(p))-0.1_r8), grnfill(ivt(p))) + huigrain(p) = huigrain(p) * gddmaturity(p) ! Cabelguenne et + else + huigrain(p) = grnfill(ivt(p)) * gddmaturity(p) ! al. 1999 + end if + + end if ! crop not live nor planted + + ! ---------------------------------- + ! from AgroIBIS subroutine phenocrop + ! ---------------------------------- + + ! all of the phenology changes are based on the total number of gdd needed + ! to change to the next phase - based on fractions of the total gdd typical + ! for that region based on the April 1 - Sept 30 window of development + + ! crop phenology (gdd thresholds) controlled by gdd needed for + ! maturity (physiological) which is based on the average gdd + ! accumulation and hybrids in United States from April 1 - Sept 30 + + ! Phase 1: Planting to leaf emergence (now in CNAllocation) + ! Phase 2: Leaf emergence to beginning of grain fill (general LAI accumulation) + ! Phase 3: Grain fill to physiological maturity and harvest (LAI decline) + ! Harvest: if gdd past grain fill initiation exceeds limit + ! or number of days past planting reaches a maximum, the crop has + ! reached physiological maturity and plant is harvested; + ! crop could be live or dead at this stage - these limits + ! could lead to reaching physiological maturity or determining + ! a harvest date for a crop killed by an early frost (see next comments) + ! --- --- --- + ! keeping comments without the code (slevis): + ! if minimum temperature, t_ref2m_min <= freeze kill threshold, tkill + ! for 3 consecutive days and lai is above a minimum, + ! plant will be damaged/killed. This function is more for spring freeze events + ! or for early fall freeze events + + ! spring temperate cereal is affected by this, winter cereal kill function + ! is determined in crops.f - is a more elaborate function of + ! cold hardening of the plant + + ! currently simulates too many grid cells killed by freezing temperatures + + ! removed on March 12 2002 - C. Kucharik + ! until it can be a bit more refined, or used at a smaller scale. + ! we really have no way of validating this routine + ! too difficult to implement on 0.5 degree scale grid cells + ! --- --- --- + + onset_flag(p) = 0._r8 ! CN terminology to trigger certain + offset_flag(p) = 0._r8 ! carbon and nitrogen transfers + + if (croplive(p)) then + cphase(p) = 1._r8 + + ! call vernalization if winter temperate cereal planted, living, and the + ! vernalization factor is not 1; + ! vf affects the calculation of gddtsoi & gddplant + + if (t_ref2m_min(p) < 1.e30_r8 .and. vf(p) /= 1._r8 .and. & + (ivt(p) == nwwheat .or. ivt(p) == nirrig_wwheat)) then + call vernalization(p, & + canopystate_inst, temperature_inst, waterdiagnosticbulk_inst, cnveg_state_inst, & + crop_inst) + end if + + ! days past planting may determine harvest + + if (jday >= idop(p)) then + idpp = jday - idop(p) + else + idpp = int(dayspyr) + jday - idop(p) + end if + + ! onset_counter initialized to zero when .not. croplive + ! offset_counter relevant only at time step of harvest + + onset_counter(p) = onset_counter(p) - dt + + ! enter phase 2 onset for one time step: + ! transfer seed carbon to leaf emergence + + if (peaklai(p) >= 1) then + hui(p) = max(hui(p),huigrain(p)) + endif + + if (leafout(p) >= huileaf(p) .and. hui(p) < huigrain(p) .and. idpp < mxmat(ivt(p))) then + cphase(p) = 2._r8 + if (abs(onset_counter(p)) > 1.e-6_r8) then + onset_flag(p) = 1._r8 + onset_counter(p) = dt + fert_counter(p) = ndays_on * secspday + if (ndays_on .gt. 0) then + fert(p) = (manunitro(ivt(p)) * 1000._r8 + fertnitro(p))/ fert_counter(p) + else + fert(p) = 0._r8 + end if + else + ! this ensures no re-entry to onset of phase2 + ! b/c onset_counter(p) = onset_counter(p) - dt + ! at every time step + + onset_counter(p) = dt + end if + + ! enter harvest for one time step: + ! - transfer live biomass to litter and to crop yield + ! - send xsmrpool to the atmosphere + ! if onset and harvest needed to last longer than one timestep + ! the onset_counter would change from dt and you'd need to make + ! changes to the offset subroutine below + + else if (hui(p) >= gddmaturity(p) .or. idpp >= mxmat(ivt(p))) then + if (harvdate(p) >= NOT_Harvested) harvdate(p) = jday + croplive(p) = .false. ! no re-entry in greater if-block + cphase(p) = 4._r8 + if (tlai(p) > 0._r8) then ! plant had emerged before harvest + offset_flag(p) = 1._r8 + offset_counter(p) = dt + else ! plant never emerged from the ground + ! Revert planting transfers; this will replenish the crop seed deficit. + ! We subtract from any existing value in crop_seedc_to_leaf / + ! crop_seedn_to_leaf in the unlikely event that we enter this block of + ! code in the same time step where the planting transfer originally + ! occurred. + crop_seedc_to_leaf(p) = crop_seedc_to_leaf(p) - leafc_xfer(p)/dt + crop_seedn_to_leaf(p) = crop_seedn_to_leaf(p) - leafn_xfer(p)/dt + leafc_xfer(p) = 0._r8 + leafn_xfer(p) = leafc_xfer(p) / leafcn(ivt(p)) + if (use_c13) then + c13_cnveg_carbonstate_inst%leafc_xfer_patch(p) = 0._r8 + endif + if (use_c14) then + c14_cnveg_carbonstate_inst%leafc_xfer_patch(p) = 0._r8 + endif + + end if + + ! enter phase 3 while previous criteria fail and next is true; + ! in terms of order, phase 3 occurs before harvest, but when + ! harvest *can* occur, we want it to have first priority. + ! AgroIBIS uses a complex formula for lai decline. + ! Use CN's simple formula at least as a place holder (slevis) + + else if (hui(p) >= huigrain(p)) then + cphase(p) = 3._r8 + bglfr(p) = 1._r8/(leaf_long(ivt(p))*dayspyr*secspday) + end if + + ! continue fertilizer application while in phase 2; + ! assumes that onset of phase 2 took one time step only + + if (fert_counter(p) <= 0._r8) then + fert(p) = 0._r8 + else ! continue same fert application every timestep + fert_counter(p) = fert_counter(p) - dtrad + end if + + else ! crop not live + ! next 2 lines conserve mass if leaf*_xfer > 0 due to interpinic. + ! We subtract from any existing value in crop_seedc_to_leaf / + ! crop_seedn_to_leaf in the unlikely event that we enter this block of + ! code in the same time step where the planting transfer originally + ! occurred. + crop_seedc_to_leaf(p) = crop_seedc_to_leaf(p) - leafc_xfer(p)/dt + crop_seedn_to_leaf(p) = crop_seedn_to_leaf(p) - leafn_xfer(p)/dt + onset_counter(p) = 0._r8 + leafc_xfer(p) = 0._r8 + leafn_xfer(p) = leafc_xfer(p) / leafcn(ivt(p)) + if (use_c13) then + c13_cnveg_carbonstate_inst%leafc_xfer_patch(p) = 0._r8 + endif + if (use_c14) then + c14_cnveg_carbonstate_inst%leafc_xfer_patch(p) = 0._r8 + endif + end if ! croplive + + end do ! prognostic crops loop + + end associate + + end subroutine CropPhenology + + !----------------------------------------------------------------------- + subroutine CropPhenologyInit(bounds) + ! + ! !DESCRIPTION: + ! Initialization of CropPhenology. Must be called after time-manager is + ! initialized, and after pftcon file is read in. + ! + ! !USES: + use pftconMod , only: npcropmin, npcropmax + use clm_time_manager, only: get_calday + ! + ! !ARGUMENTS: + type(bounds_type), intent(in) :: bounds + ! + ! LOCAL VARAIBLES: + integer :: p,g,n,i ! indices + !------------------------------------------------------------------------ + + allocate( inhemi(bounds%begp:bounds%endp) ) + + allocate( minplantjday(0:maxveg,inSH)) ! minimum planting julian day + allocate( maxplantjday(0:maxveg,inSH)) ! minimum planting julian day + + ! Julian day for the start of the year (mid-winter) + jdayyrstart(inNH) = 1 + jdayyrstart(inSH) = 182 + + ! Convert planting dates into julian day + minplantjday(:,:) = huge(1) + maxplantjday(:,:) = huge(1) + do n = npcropmin, npcropmax + if (pftcon%is_pft_known_to_model(n)) then + minplantjday(n, inNH) = int( get_calday( pftcon%mnNHplantdate(n), 0 ) ) + maxplantjday(n, inNH) = int( get_calday( pftcon%mxNHplantdate(n), 0 ) ) + + minplantjday(n, inSH) = int( get_calday( pftcon%mnSHplantdate(n), 0 ) ) + maxplantjday(n, inSH) = int( get_calday( pftcon%mxSHplantdate(n), 0 ) ) + end if + end do + + ! Figure out what hemisphere each PATCH is in + do p = bounds%begp, bounds%endp + g = patch%gridcell(p) + ! Northern hemisphere + if ( grc%latdeg(g) > 0.0_r8 )then + inhemi(p) = inNH + else + inhemi(p) = inSH + end if + end do + + ! + ! Constants for Crop vernalization + ! + ! photoperiod factor calculation + ! genetic constant - can be modified + + p1d = 0.004_r8 ! average for genotypes from Ritchey, 1991. + ! Modeling plant & soil systems: Wheat phasic developmt + p1v = 0.003_r8 ! average for genotypes from Ritchey, 1991. + + hti = 1._r8 + tbase = 0._r8 + + end subroutine CropPhenologyInit + + !----------------------------------------------------------------------- + subroutine vernalization(p, & + canopystate_inst, temperature_inst, waterdiagnosticbulk_inst, cnveg_state_inst, crop_inst) + ! + ! !DESCRIPTION: + ! + ! * * * only call for winter temperate cereal * * * + ! + ! subroutine calculates vernalization and photoperiod effects on + ! gdd accumulation in winter temperate cereal varieties. Thermal time accumulation + ! is reduced in 1st period until plant is fully vernalized. During this + ! time of emergence to spikelet formation, photoperiod can also have a + ! drastic effect on plant development. + ! + ! !ARGUMENTS: + integer , intent(in) :: p ! PATCH index running over + type(canopystate_type) , intent(in) :: canopystate_inst + type(temperature_type) , intent(in) :: temperature_inst + type(waterdiagnosticbulk_type) , intent(in) :: waterdiagnosticbulk_inst + type(cnveg_state_type) , intent(inout) :: cnveg_state_inst + type(crop_type) , intent(inout) :: crop_inst + ! + ! LOCAL VARAIBLES: + real(r8) tcrown ! ? + real(r8) vd, vd1, vd2 ! vernalization dependence + real(r8) tkil ! Freeze kill threshold + integer c,g ! indices + !------------------------------------------------------------------------ + + associate( & + tlai => canopystate_inst%tlai_patch , & ! Input: [real(r8) (:) ] one-sided leaf area index, no burying by snow + + t_ref2m => temperature_inst%t_ref2m_patch , & ! Input: [real(r8) (:) ] 2 m height surface air temperature (K) + t_ref2m_min => temperature_inst%t_ref2m_min_patch , & ! Input: [real(r8) (:) ] daily minimum of average 2 m height surface air temperature (K) + t_ref2m_max => temperature_inst%t_ref2m_max_patch , & ! Input: [real(r8) (:) ] daily maximum of average 2 m height surface air temperature (K) + + snow_depth => waterdiagnosticbulk_inst%snow_depth_col , & ! Input: [real(r8) (:) ] snow height (m) + + hdidx => cnveg_state_inst%hdidx_patch , & ! Output: [real(r8) (:) ] cold hardening index? + cumvd => cnveg_state_inst%cumvd_patch , & ! Output: [real(r8) (:) ] cumulative vernalization d?ependence? + gddmaturity => cnveg_state_inst%gddmaturity_patch , & ! Output: [real(r8) (:) ] gdd needed to harvest + huigrain => cnveg_state_inst%huigrain_patch , & ! Output: [real(r8) (:) ] heat unit index needed to reach vegetative maturity + + vf => crop_inst%vf_patch & ! Output: [real(r8) (:) ] vernalization factor for cereal + ) + + c = patch%column(p) + + ! for all equations - temperatures must be in degrees (C) + ! calculate temperature of crown of crop (e.g., 3 cm soil temperature) + ! snow depth in centimeters + + if (t_ref2m(p) < tfrz) then !slevis: t_ref2m inst of td=daily avg (K) + tcrown = 2._r8 + (t_ref2m(p) - tfrz) * (0.4_r8 + 0.0018_r8 * & + (min(snow_depth(c)*100._r8, 15._r8) - 15._r8)**2) + else !slevis: snow_depth inst of adsnod=daily average (m) + tcrown = t_ref2m(p) - tfrz + end if + + ! vernalization factor calculation + ! if vf(p) = 1. then plant is fully vernalized - and thermal time + ! accumulation in phase 1 will be unaffected + ! refers to gddtsoi & gddplant, defined in the accumulation routines (slevis) + ! reset vf, cumvd, and hdidx to 0 at planting of crop (slevis) + + if (t_ref2m_max(p) > tfrz) then + if (t_ref2m_min(p) <= tfrz+15._r8) then + vd1 = 1.4_r8 - 0.0778_r8 * tcrown + vd2 = 0.5_r8 + 13.44_r8 / ((t_ref2m_max(p)-t_ref2m_min(p)+3._r8)**2) * tcrown + vd = max(0._r8, min(1._r8, vd1, vd2)) + cumvd(p) = cumvd(p) + vd + end if + + if (cumvd(p) < 10._r8 .and. t_ref2m_max(p) > tfrz+30._r8) then + cumvd(p) = cumvd(p) - 0.5_r8 * (t_ref2m_max(p) - tfrz - 30._r8) + end if + cumvd(p) = max(0._r8, cumvd(p)) ! must be > 0 + + vf(p) = 1._r8 - p1v * (50._r8 - cumvd(p)) + vf(p) = max(0._r8, min(vf(p), 1._r8)) ! must be between 0 - 1 + end if + + ! calculate cold hardening of plant + ! determines for winter cereal varieties whether the plant has completed + ! a period of cold hardening to protect it from freezing temperatures. If + ! not, then exposure could result in death or killing of plants. + + ! there are two distinct phases of hardening + + if (t_ref2m_min(p) <= tfrz-3._r8 .or. hdidx(p) /= 0._r8) then + if (hdidx(p) >= hti) then ! done with phase 1 + hdidx(p) = hdidx(p) + 0.083_r8 + hdidx(p) = min(hdidx(p), hti*2._r8) + end if + + if (t_ref2m_max(p) >= tbase + tfrz + 10._r8) then + hdidx(p) = hdidx(p) - 0.02_r8 * (t_ref2m_max(p)-tbase-tfrz-10._r8) + if (hdidx(p) > hti) hdidx(p) = hdidx(p) - 0.02_r8 * (t_ref2m_max(p)-tbase-tfrz-10._r8) + hdidx(p) = max(0._r8, hdidx(p)) + end if + + else if (tcrown >= tbase-1._r8) then + if (tcrown <= tbase+8._r8) then + hdidx(p) = hdidx(p) + 0.1_r8 - (tcrown-tbase+3.5_r8)**2 / 506._r8 + if (hdidx(p) >= hti .and. tcrown <= tbase + 0._r8) then + hdidx(p) = hdidx(p) + 0.083_r8 + hdidx(p) = min(hdidx(p), hti*2._r8) + end if + end if + + if (t_ref2m_max(p) >= tbase + tfrz + 10._r8) then + hdidx(p) = hdidx(p) - 0.02_r8 * (t_ref2m_max(p)-tbase-tfrz-10._r8) + if (hdidx(p) > hti) hdidx(p) = hdidx(p) - 0.02_r8 * (t_ref2m_max(p)-tbase-tfrz-10._r8) + hdidx(p) = max(0._r8, hdidx(p)) + end if + end if + + ! calculate what the cereal killing temperature + ! there is a linear inverse relationship between + ! hardening of the plant and the killing temperature or + ! threshold that the plant can withstand + ! when plant is fully-hardened (hdidx = 2), the killing threshold is -18 C + + ! will have to develop some type of relationship that reduces LAI and + ! biomass pools in response to cold damaged crop + + if (t_ref2m_min(p) <= tfrz - 6._r8) then + tkil = (tbase - 6._r8) - 6._r8 * hdidx(p) + if (tkil >= tcrown) then + if ((0.95_r8 - 0.02_r8 * (tcrown - tkil)**2) >= 0.02_r8) then + write (iulog,*) 'crop damaged by cold temperatures at p,c =', p,c + else if (tlai(p) > 0._r8) then ! slevis: kill if past phase1 + gddmaturity(p) = 0._r8 ! by forcing through + huigrain(p) = 0._r8 ! harvest + write (iulog,*) '95% of crop killed by cold temperatures at p,c =', p,c + end if + end if + end if + + end associate + + end subroutine vernalization + + !----------------------------------------------------------------------- + subroutine CNOnsetGrowth (num_soilp, filter_soilp, & + cnveg_state_inst, & + cnveg_carbonstate_inst, cnveg_nitrogenstate_inst, cnveg_carbonflux_inst, cnveg_nitrogenflux_inst) + ! + ! !DESCRIPTION: + ! Determines the flux of stored C and N from transfer pools to display + ! pools during the phenological onset period. + ! + ! !ARGUMENTS: + integer , intent(in) :: num_soilp ! number of soil patches in filter + integer , intent(in) :: filter_soilp(:) ! filter for soil patches + type(cnveg_state_type) , intent(in) :: cnveg_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 ! indices + integer :: fp ! lake filter patch index + real(r8):: t1 ! temporary variable + !----------------------------------------------------------------------- + + associate( & + ivt => patch%itype , & ! Input: [integer (:) ] patch vegetation type + + woody => pftcon%woody , & ! Input: binary flag for woody lifeform (1=woody, 0=not woody) + + onset_flag => cnveg_state_inst%onset_flag_patch , & ! Input: [real(r8) (:) ] onset flag + onset_counter => cnveg_state_inst%onset_counter_patch , & ! Input: [real(r8) (:) ] onset days counter + bgtr => cnveg_state_inst%bgtr_patch , & ! Input: [real(r8) (:) ] background transfer growth rate (1/s) + + 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 + + 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 + + leafc_xfer_to_leafc => cnveg_carbonflux_inst%leafc_xfer_to_leafc_patch , & ! Output: [real(r8) (:) ] + frootc_xfer_to_frootc => cnveg_carbonflux_inst%frootc_xfer_to_frootc_patch , & ! Output: [real(r8) (:) ] + livestemc_xfer_to_livestemc => cnveg_carbonflux_inst%livestemc_xfer_to_livestemc_patch , & ! Output: [real(r8) (:) ] + deadstemc_xfer_to_deadstemc => cnveg_carbonflux_inst%deadstemc_xfer_to_deadstemc_patch , & ! Output: [real(r8) (:) ] + livecrootc_xfer_to_livecrootc => cnveg_carbonflux_inst%livecrootc_xfer_to_livecrootc_patch , & ! Output: [real(r8) (:) ] + deadcrootc_xfer_to_deadcrootc => cnveg_carbonflux_inst%deadcrootc_xfer_to_deadcrootc_patch , & ! Output: [real(r8) (:) ] + + leafn_xfer_to_leafn => cnveg_nitrogenflux_inst%leafn_xfer_to_leafn_patch , & ! Output: [real(r8) (:) ] + frootn_xfer_to_frootn => cnveg_nitrogenflux_inst%frootn_xfer_to_frootn_patch , & ! Output: [real(r8) (:) ] + livestemn_xfer_to_livestemn => cnveg_nitrogenflux_inst%livestemn_xfer_to_livestemn_patch , & ! Output: [real(r8) (:) ] + deadstemn_xfer_to_deadstemn => cnveg_nitrogenflux_inst%deadstemn_xfer_to_deadstemn_patch , & ! Output: [real(r8) (:) ] + livecrootn_xfer_to_livecrootn => cnveg_nitrogenflux_inst%livecrootn_xfer_to_livecrootn_patch , & ! Output: [real(r8) (:) ] + deadcrootn_xfer_to_deadcrootn => cnveg_nitrogenflux_inst%deadcrootn_xfer_to_deadcrootn_patch & ! Output: [real(r8) (:) ] + ) + + ! patch loop + do fp = 1,num_soilp + p = filter_soilp(fp) + + ! only calculate these fluxes during onset period + if (onset_flag(p) == 1._r8) then + + ! The transfer rate is a linearly decreasing function of time, + ! going to zero on the last timestep of the onset period + + if (onset_counter(p) == dt) then + t1 = 1.0_r8 / dt + else + t1 = 2.0_r8 / (onset_counter(p)) + end if + leafc_xfer_to_leafc(p) = t1 * leafc_xfer(p) + frootc_xfer_to_frootc(p) = t1 * frootc_xfer(p) + leafn_xfer_to_leafn(p) = t1 * leafn_xfer(p) + frootn_xfer_to_frootn(p) = t1 * frootn_xfer(p) + if (woody(ivt(p)) == 1.0_r8) then + livestemc_xfer_to_livestemc(p) = t1 * livestemc_xfer(p) + deadstemc_xfer_to_deadstemc(p) = t1 * deadstemc_xfer(p) + livecrootc_xfer_to_livecrootc(p) = t1 * livecrootc_xfer(p) + deadcrootc_xfer_to_deadcrootc(p) = t1 * deadcrootc_xfer(p) + livestemn_xfer_to_livestemn(p) = t1 * livestemn_xfer(p) + deadstemn_xfer_to_deadstemn(p) = t1 * deadstemn_xfer(p) + livecrootn_xfer_to_livecrootn(p) = t1 * livecrootn_xfer(p) + deadcrootn_xfer_to_deadcrootn(p) = t1 * deadcrootn_xfer(p) + end if + + end if ! end if onset period + + ! calculate the background rate of transfer growth (used for stress + ! deciduous algorithm). In this case, all of the mass in the transfer + ! pools should be moved to displayed growth in each timestep. + + if (bgtr(p) > 0._r8) then + leafc_xfer_to_leafc(p) = leafc_xfer(p) / dt + frootc_xfer_to_frootc(p) = frootc_xfer(p) / dt + leafn_xfer_to_leafn(p) = leafn_xfer(p) / dt + frootn_xfer_to_frootn(p) = frootn_xfer(p) / dt + if (woody(ivt(p)) == 1.0_r8) then + livestemc_xfer_to_livestemc(p) = livestemc_xfer(p) / dt + deadstemc_xfer_to_deadstemc(p) = deadstemc_xfer(p) / dt + livecrootc_xfer_to_livecrootc(p) = livecrootc_xfer(p) / dt + deadcrootc_xfer_to_deadcrootc(p) = deadcrootc_xfer(p) / dt + livestemn_xfer_to_livestemn(p) = livestemn_xfer(p) / dt + deadstemn_xfer_to_deadstemn(p) = deadstemn_xfer(p) / dt + livecrootn_xfer_to_livecrootn(p) = livecrootn_xfer(p) / dt + deadcrootn_xfer_to_deadcrootn(p) = deadcrootn_xfer(p) / dt + end if + end if ! end if bgtr + + end do ! end patch loop + + end associate + + end subroutine CNOnsetGrowth + + !----------------------------------------------------------------------- + subroutine CNOffsetLitterfall (num_soilp, filter_soilp, & + cnveg_state_inst, cnveg_carbonstate_inst, cnveg_nitrogenstate_inst, cnveg_carbonflux_inst, cnveg_nitrogenflux_inst) + ! + ! !DESCRIPTION: + ! Determines the flux of C and N from displayed pools to litter + ! pools during the phenological offset period. + ! + ! !USES: + use pftconMod , only : npcropmin + ! Y. Cheng + use pftconMod , only : nmiscanthus, nirrig_miscanthus, nswitchgrass, nirrig_switchgrass + + use CNSharedParamsMod, only : use_fun + use clm_varctl , only : CNratio_floating + ! + ! !ARGUMENTS: + integer , intent(in) :: num_soilp ! number of soil patches in filter + integer , intent(in) :: filter_soilp(:) ! filter for soil patches + type(cnveg_state_type) , intent(inout) :: cnveg_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, c ! indices + integer :: fp ! lake filter patch index + real(r8):: t1 ! temporary variable + real(r8):: denom ! temporary variable for divisor + real(r8) :: ntovr_leaf + real(r8) :: fr_leafn_to_litter ! fraction of the nitrogen turnover that goes to litter; remaining fraction is retranslocated + !----------------------------------------------------------------------- + + associate( & + ivt => patch%itype , & ! Input: [integer (:) ] patch vegetation type + + leafcn => pftcon%leafcn , & ! Input: leaf C:N (gC/gN) + + ! Y. Cheng, add a new cut fraction for harvest parameter for bioenergy crops (miscanthus and switchgrass) + harvfrac => pftcon%harvfrac , & ! Input: cut fraction for harvest (-) + + lflitcn => pftcon%lflitcn , & ! Input: leaf litter C:N (gC/gN) + frootcn => pftcon%frootcn , & ! Input: fine root C:N (gC/gN) + graincn => pftcon%graincn , & ! Input: grain C:N (gC/gN) + + offset_flag => cnveg_state_inst%offset_flag_patch , & ! Input: [real(r8) (:) ] offset flag + offset_counter => cnveg_state_inst%offset_counter_patch , & ! Input: [real(r8) (:) ] offset days counter + + 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 + grainc => cnveg_carbonstate_inst%grainc_patch , & ! Input: [real(r8) (:) ] (gC/m2) grain C + cropseedc_deficit => cnveg_carbonstate_inst%cropseedc_deficit_patch , & ! Input: [real(r8) (:) ] (gC/m2) crop seed C deficit + livestemc => cnveg_carbonstate_inst%livestemc_patch , & ! Input: [real(r8) (:) ] (gC/m2) livestem C + cropseedn_deficit => cnveg_nitrogenstate_inst%cropseedn_deficit_patch , & ! Input: [real(r8) (:) ] (gC/m2) crop seed N deficit + livestemn => cnveg_nitrogenstate_inst%livestemn_patch , & ! Input: [real(r8) (:) ] (gN/m2) livestem N + + cpool_to_grainc => cnveg_carbonflux_inst%cpool_to_grainc_patch , & ! Input: [real(r8) (:) ] allocation to grain C (gC/m2/s) + npool_to_grainn => cnveg_nitrogenflux_inst%npool_to_grainn_patch , & ! Input: [real(r8) (:) ] allocation to grain N (gN/m2/s) + grainn => cnveg_nitrogenstate_inst%grainn_patch , & ! Input: [real(r8) (:) ] (kgN/m2) grain N + cpool_to_livestemc => cnveg_carbonflux_inst%cpool_to_livestemc_patch , & ! Input: [real(r8) (:) ] allocation to live stem C (gC/m2/s) + cpool_to_leafc => cnveg_carbonflux_inst%cpool_to_leafc_patch , & ! Input: [real(r8) (:) ] allocation to leaf C (gC/m2/s) + cpool_to_frootc => cnveg_carbonflux_inst%cpool_to_frootc_patch , & ! Input: [real(r8) (:) ] allocation to fine root C (gC/m2/s) + prev_leafc_to_litter => cnveg_carbonflux_inst%prev_leafc_to_litter_patch , & ! Output: [real(r8) (:) ] previous timestep leaf C litterfall flux (gC/m2/s) + prev_frootc_to_litter => cnveg_carbonflux_inst%prev_frootc_to_litter_patch , & ! Output: [real(r8) (:) ] previous timestep froot C litterfall flux (gC/m2/s) + leafc_to_litter => cnveg_carbonflux_inst%leafc_to_litter_patch , & ! Output: [real(r8) (:) ] leaf C litterfall (gC/m2/s) + frootc_to_litter => cnveg_carbonflux_inst%frootc_to_litter_patch , & ! Output: [real(r8) (:) ] fine root C litterfall (gC/m2/s) + livestemc_to_litter => cnveg_carbonflux_inst%livestemc_to_litter_patch , & ! Output: [real(r8) (:) ] live stem C litterfall (gC/m2/s) + grainc_to_food => cnveg_carbonflux_inst%grainc_to_food_patch , & ! Output: [real(r8) (:) ] grain C to food (gC/m2/s) + + ! Y. Cheng, put the cut fraction during offset period for bioenergy crops to this biofuelc_harvest flux + biofuelc_harvest => cnveg_carbonflux_inst%biofuelc_harvest_patch , & ! Output: [real(r8) (:) ] biofuel C that was cutted at harvest (gC/m2/s) + + grainc_to_seed => cnveg_carbonflux_inst%grainc_to_seed_patch , & ! Output: [real(r8) (:) ] grain C to seed (gC/m2/s) + 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_to_litter => cnveg_nitrogenflux_inst%livestemn_to_litter_patch , & ! Output: [real(r8) (:) ] livestem N to litter (gN/m2/s) + grainn_to_food => cnveg_nitrogenflux_inst%grainn_to_food_patch , & ! Output: [real(r8) (:) ] grain N to food (gN/m2/s) + biofueln_harvest => cnveg_nitrogenflux_inst%biofueln_harvest_patch , & ! Output: [real(r8) (:) ] biofuel N that was cutted (gC/m2/s) + grainn_to_seed => cnveg_nitrogenflux_inst%grainn_to_seed_patch , & ! Output: [real(r8) (:) ] grain N to seed (gN/m2/s) + leafn_to_litter => cnveg_nitrogenflux_inst%leafn_to_litter_patch , & ! Output: [real(r8) (:) ] leaf N litterfall (gN/m2/s) + leafn_to_retransn => cnveg_nitrogenflux_inst%leafn_to_retransn_patch , & ! Input: [real(r8) (:) ] leaf N to retranslocated N pool (gN/m2/s) + free_retransn_to_npool=> cnveg_nitrogenflux_inst%free_retransn_to_npool_patch , & ! Input: [real(r8) (:) ] free leaf N to retranslocated N pool (gN/m2/s) + paid_retransn_to_npool=> cnveg_nitrogenflux_inst%retransn_to_npool_patch, & ! Input: [real(r8) (:) ] free leaf N to retranslocated N pool (gN/m2/s) + frootn_to_litter => cnveg_nitrogenflux_inst%frootn_to_litter_patch , & ! Output: [real(r8) (:) ] fine root N litterfall (gN/m2/s) + leafc_to_litter_fun => cnveg_carbonflux_inst%leafc_to_litter_fun_patch , & ! Output: [real(r8) (:) ] leaf C litterfall used by FUN (gC/m2/s) + leafcn_offset => cnveg_state_inst%leafcn_offset_patch & ! Output: [real(r8) (:) ] Leaf C:N used by FUN + ) + + ! The litterfall transfer rate starts at 0.0 and increases linearly + ! over time, with displayed growth going to 0.0 on the last day of litterfall + + do fp = 1,num_soilp + p = filter_soilp(fp) + + ! only calculate fluxes during offset period + if (offset_flag(p) == 1._r8) then + + if (offset_counter(p) == dt) then + t1 = 1.0_r8 / dt + frootc_to_litter(p) = t1 * frootc(p) + cpool_to_frootc(p) + + ! Cut a certain fraction (i.e., harvfrac(ivt(p))) (e.g., harvfrac(ivt(p)=70% for bioenergy crops) of leafc for harvest + ! and move this cut fration to the biofuelc_harvest flux, rather than move it to litter + leafc_to_litter(p) = t1 * leafc(p)*(1._r8-harvfrac(ivt(p))) + cpool_to_leafc(p) + biofuelc_harvest(p) = t1 * leafc(p) * harvfrac(ivt(p)) + biofueln_harvest(p) = t1 * leafn(p) * harvfrac(ivt(p)) + + ! this assumes that offset_counter == dt for crops + ! if this were ever changed, we'd need to add code to the "else" + if (ivt(p) >= npcropmin) then + ! Replenish the seed deficits from grain, if there is enough + ! available grain. (If there is not enough available grain, the seed + ! deficits will accumulate until there is eventually enough grain to + ! replenish them.) + grainc_to_seed(p) = t1 * min(-cropseedc_deficit(p), grainc(p)) + grainn_to_seed(p) = t1 * min(-cropseedn_deficit(p), grainn(p)) + ! Send the remaining grain to the food product pool + grainc_to_food(p) = t1 * grainc(p) + cpool_to_grainc(p) - grainc_to_seed(p) + grainn_to_food(p) = t1 * grainn(p) + npool_to_grainn(p) - grainn_to_seed(p) + + livestemc_to_litter(p) = t1 * livestemc(p) + cpool_to_livestemc(p) + end if + else + t1 = dt * 2.0_r8 / (offset_counter(p) * offset_counter(p)) + leafc_to_litter(p) = prev_leafc_to_litter(p) + t1*(leafc(p) - prev_leafc_to_litter(p)*offset_counter(p)) + frootc_to_litter(p) = prev_frootc_to_litter(p) + t1*(frootc(p) - prev_frootc_to_litter(p)*offset_counter(p)) + + end if + + if ( use_fun ) then + if(leafc_to_litter(p)*dt.gt.leafc(p))then + leafc_to_litter(p) = leafc(p)/dt + cpool_to_leafc(p) + endif + if(frootc_to_litter(p)*dt.gt.frootc(p))then + frootc_to_litter(p) = frootc(p)/dt + cpool_to_frootc(p) + endif + end if + + + if ( use_fun ) then + leafc_to_litter_fun(p) = leafc_to_litter(p) + leafn_to_retransn(p) = paid_retransn_to_npool(p) + free_retransn_to_npool(p) + if (leafn(p).gt.0._r8) then + if (leafn(p)-leafn_to_retransn(p)*dt.gt.0._r8) then + leafcn_offset(p) = leafc(p)/(leafn(p)-leafn_to_retransn(p)*dt) + else + leafcn_offset(p) = leafc(p)/leafn(p) + end if + else + leafcn_offset(p) = leafcn(ivt(p)) + end if + leafn_to_litter(p) = leafc_to_litter(p)/leafcn_offset(p) - leafn_to_retransn(p) + leafn_to_litter(p) = max(leafn_to_litter(p),0._r8) + + denom = ( leafn_to_retransn(p) + leafn_to_litter(p) ) + if ( denom /= 0.0_r8 ) then + fr_leafn_to_litter = leafn_to_litter(p) / ( leafn_to_retransn(p) + leafn_to_litter(p) ) + else if ( leafn_to_litter(p) == 0.0_r8 ) then + fr_leafn_to_litter = 0.0_r8 + else + fr_leafn_to_litter = 1.0_r8 + end if + + else + if (CNratio_floating .eqv. .true.) then + fr_leafn_to_litter = 0.5_r8 ! assuming 50% of nitrogen turnover goes to litter + end if + ! calculate the leaf N litterfall and retranslocation + leafn_to_litter(p) = leafc_to_litter(p) / lflitcn(ivt(p)) + leafn_to_retransn(p) = (leafc_to_litter(p) / leafcn(ivt(p))) - leafn_to_litter(p) + + end if + + ! calculate fine root N litterfall (no retranslocation of fine root N) + frootn_to_litter(p) = frootc_to_litter(p) / frootcn(ivt(p)) + + if (CNratio_floating .eqv. .true.) then + if (leafc(p) == 0.0_r8) then + ntovr_leaf = 0.0_r8 + else + ntovr_leaf = leafc_to_litter(p) * (leafn(p) / leafc(p)) + end if + + leafn_to_litter(p) = fr_leafn_to_litter * ntovr_leaf + leafn_to_retransn(p) = ntovr_leaf - leafn_to_litter(p) + if (frootc(p) == 0.0_r8) then + frootn_to_litter(p) = 0.0_r8 + else + frootn_to_litter(p) = frootc_to_litter(p) * (frootn(p) / frootc(p)) + end if + end if + + if ( use_fun ) then + if(frootn_to_litter(p)*dt.gt.frootn(p))then + frootn_to_litter(p) = frootn(p)/dt + endif + end if + + if (ivt(p) >= npcropmin) then + ! NOTE(slevis, 2014-12) results in -ve livestemn and -ve totpftn + !X! livestemn_to_litter(p) = livestemc_to_litter(p) / livewdcn(ivt(p)) + ! NOTE(slevis, 2014-12) Beth Drewniak suggested this instead + livestemn_to_litter(p) = livestemn(p) / dt + end if + + ! save the current litterfall fluxes + prev_leafc_to_litter(p) = leafc_to_litter(p) + prev_frootc_to_litter(p) = frootc_to_litter(p) + + end if ! end if offset period + + end do ! end patch loop + + end associate + + end subroutine CNOffsetLitterfall + + !----------------------------------------------------------------------- + subroutine CNBackgroundLitterfall (num_soilp, filter_soilp, & + cnveg_state_inst, cnveg_carbonstate_inst, cnveg_nitrogenstate_inst, cnveg_carbonflux_inst, cnveg_nitrogenflux_inst) + ! + ! !DESCRIPTION: + ! Determines the flux of C and N from displayed pools to litter + ! pools as the result of background litter fall. + ! + ! !USES: + use CNSharedParamsMod , only : use_fun + use clm_varctl , only : CNratio_floating + ! !ARGUMENTS: + implicit none + integer , intent(in) :: num_soilp ! number of soil patches in filter + integer , intent(in) :: filter_soilp(:) ! filter for soil patches + type(cnveg_state_type) , intent(inout) :: cnveg_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 ! indices + integer :: fp ! lake filter patch index + real(r8) :: fr_leafn_to_litter ! fraction of the nitrogen turnover that goes to litter; remaining fraction is retranslocated + real(r8) :: ntovr_leaf + real(r8) :: denom + !----------------------------------------------------------------------- + + associate( & + ivt => patch%itype , & ! Input: [integer (:) ] patch vegetation type + + leafcn => pftcon%leafcn , & ! Input: leaf C:N (gC/gN) + lflitcn => pftcon%lflitcn , & ! Input: leaf litter C:N (gC/gN) + frootcn => pftcon%frootcn , & ! Input: fine root C:N (gC/gN) + + bglfr => cnveg_state_inst%bglfr_patch , & ! Input: [real(r8) (:) ] background litterfall rate (1/s) + + 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 + + leafc_to_litter => cnveg_carbonflux_inst%leafc_to_litter_patch , & ! Output: [real(r8) (:) ] + frootc_to_litter => cnveg_carbonflux_inst%frootc_to_litter_patch , & ! Output: [real(r8) (:) ] + + 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 + leafn_to_litter => cnveg_nitrogenflux_inst%leafn_to_litter_patch , & ! Output: [real(r8) (:) ] + leafn_to_retransn => cnveg_nitrogenflux_inst%leafn_to_retransn_patch , & ! Output: [real(r8) (:) ] + frootn_to_litter => cnveg_nitrogenflux_inst%frootn_to_litter_patch , & ! Output: [real(r8) (:) ] + leafc_to_litter_fun => cnveg_carbonflux_inst%leafc_to_litter_fun_patch, & ! Output: [real(r8) (:) ] leaf C litterfall used by FUN (gC/m2/s) + leafcn_offset => cnveg_state_inst%leafcn_offset_patch , & ! Output: [real(r8) (:) ] Leaf C:N used by FUN + free_retransn_to_npool=> cnveg_nitrogenflux_inst%free_retransn_to_npool_patch , & ! Input: [real(r8) (:) ] free leaf N to retranslocated N pool (gN/m2/s) + paid_retransn_to_npool=> cnveg_nitrogenflux_inst%retransn_to_npool_patch & ! Input: [real(r8) (:) ] free leaf N to retranslocated N pool (gN/m2/s) + ) + + ! patch loop + do fp = 1,num_soilp + p = filter_soilp(fp) + + ! only calculate these fluxes if the background litterfall rate is non-zero + if (bglfr(p) > 0._r8) then + ! units for bglfr are already 1/s + leafc_to_litter(p) = bglfr(p) * leafc(p) + frootc_to_litter(p) = bglfr(p) * frootc(p) + if ( use_fun ) then + leafc_to_litter_fun(p) = leafc_to_litter(p) + leafn_to_retransn(p) = paid_retransn_to_npool(p) + free_retransn_to_npool(p) + if (leafn(p).gt.0._r8) then + if (leafn(p)-leafn_to_retransn(p)*dt.gt.0._r8) then + leafcn_offset(p) = leafc(p)/(leafn(p)-leafn_to_retransn(p)*dt) + else + leafcn_offset(p) = leafc(p)/leafn(p) + end if + else + leafcn_offset(p) = leafcn(ivt(p)) + end if + leafn_to_litter(p) = leafc_to_litter(p)/leafcn_offset(p) - leafn_to_retransn(p) + leafn_to_litter(p) = max(leafn_to_litter(p),0._r8) + + denom = ( leafn_to_retransn(p) + leafn_to_litter(p) ) + if ( denom /= 0.0_r8 ) then + fr_leafn_to_litter = leafn_to_litter(p) / ( leafn_to_retransn(p) + leafn_to_litter(p) ) + else if ( leafn_to_litter(p) == 0.0_r8 ) then + fr_leafn_to_litter = 0.0_r8 + else + fr_leafn_to_litter = 1.0_r8 + end if + + + else + if (CNratio_floating .eqv. .true.) then + fr_leafn_to_litter = 0.5_r8 ! assuming 50% of nitrogen turnover goes to litter + end if + ! calculate the leaf N litterfall and retranslocation + leafn_to_litter(p) = leafc_to_litter(p) / lflitcn(ivt(p)) + leafn_to_retransn(p) = (leafc_to_litter(p) / leafcn(ivt(p))) - leafn_to_litter(p) + + end if + + ! calculate fine root N litterfall (no retranslocation of fine root N) + frootn_to_litter(p) = frootc_to_litter(p) / frootcn(ivt(p)) + + if (CNratio_floating .eqv. .true.) then + if (leafc(p) == 0.0_r8) then + ntovr_leaf = 0.0_r8 + else + ntovr_leaf = leafc_to_litter(p) * (leafn(p) / leafc(p)) + end if + + leafn_to_litter(p) = fr_leafn_to_litter * ntovr_leaf + leafn_to_retransn(p) = ntovr_leaf - leafn_to_litter(p) + if (frootc(p) == 0.0_r8) then + frootn_to_litter(p) = 0.0_r8 + else + frootn_to_litter(p) = frootc_to_litter(p) * (frootn(p) / frootc(p)) + end if + end if + + if ( use_fun ) then + if(frootn_to_litter(p)*dt.gt.frootn(p))then + frootn_to_litter(p) = frootn(p)/dt + endif + end if + + end if + + end do + + end associate + + end subroutine CNBackgroundLitterfall + + !----------------------------------------------------------------------- + subroutine CNLivewoodTurnover (num_soilp, filter_soilp, & + cnveg_carbonstate_inst, cnveg_nitrogenstate_inst, cnveg_carbonflux_inst, cnveg_nitrogenflux_inst) + ! + ! !DESCRIPTION: + ! Determines the flux of C and N from live wood to + ! dead wood pools, for stem and coarse root. + ! + use CNSharedParamsMod, only: use_fun + use clm_varctl , only : CNratio_floating + ! !ARGUMENTS: + integer , intent(in) :: num_soilp ! number of soil patches in filter + integer , intent(in) :: filter_soilp(:) ! filter for soil patches + 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 ! indices + integer :: fp ! lake filter patch index + real(r8):: ctovr ! temporary variable for carbon turnover + real(r8):: ntovr ! temporary variable for nitrogen turnover + !----------------------------------------------------------------------- + + associate( & + ivt => patch%itype , & ! Input: [integer (:) ] patch vegetation type + + woody => pftcon%woody , & ! Input: binary flag for woody lifeform (1=woody, 0=not woody) + livewdcn => pftcon%livewdcn , & ! Input: live wood (phloem and ray parenchyma) C:N (gC/gN) + deadwdcn => pftcon%deadwdcn , & ! Input: dead wood (xylem and heartwood) C:N (gC/gN) + + livestemc => cnveg_carbonstate_inst%livestemc_patch , & ! Input: [real(r8) (:) ] (gC/m2) live stem C + livecrootc => cnveg_carbonstate_inst%livecrootc_patch , & ! Input: [real(r8) (:) ] (gC/m2) live coarse root C + + livestemn => cnveg_nitrogenstate_inst%livestemn_patch , & ! Input: [real(r8) (:) ] (gN/m2) live stem N + livecrootn => cnveg_nitrogenstate_inst%livecrootn_patch , & ! Input: [real(r8) (:) ] (gN/m2) live coarse root N + + livestemc_to_deadstemc => cnveg_carbonflux_inst%livestemc_to_deadstemc_patch , & ! Output: [real(r8) (:) ] + livecrootc_to_deadcrootc => cnveg_carbonflux_inst%livecrootc_to_deadcrootc_patch , & ! Output: [real(r8) (:) ] + + livestemn_to_deadstemn => cnveg_nitrogenflux_inst%livestemn_to_deadstemn_patch , & ! Output: [real(r8) (:) ] + livestemn_to_retransn => cnveg_nitrogenflux_inst%livestemn_to_retransn_patch , & ! Output: [real(r8) (:) ] + livecrootn_to_deadcrootn => cnveg_nitrogenflux_inst%livecrootn_to_deadcrootn_patch , & ! Output: [real(r8) (:) ] + livecrootn_to_retransn => cnveg_nitrogenflux_inst%livecrootn_to_retransn_patch & ! Output: [real(r8) (:) ] + ) + + + + ! patch loop + do fp = 1,num_soilp + p = filter_soilp(fp) + + ! only calculate these fluxes for woody types + if (woody(ivt(p)) > 0._r8) then + + ! live stem to dead stem turnover + + ctovr = livestemc(p) * lwtop + ntovr = ctovr / livewdcn(ivt(p)) + livestemc_to_deadstemc(p) = ctovr + livestemn_to_deadstemn(p) = ctovr / deadwdcn(ivt(p)) + + if (CNratio_floating .eqv. .true.) then + if (livestemc(p) == 0.0_r8) then + ntovr = 0.0_r8 + else + ntovr = ctovr * (livestemn(p) / livestemc(p)) + end if + + livestemn_to_deadstemn(p) = 0.5_r8 * ntovr ! assuming 50% goes to deadstemn + end if + + livestemn_to_retransn(p) = ntovr - livestemn_to_deadstemn(p) + + ! live coarse root to dead coarse root turnover + + ctovr = livecrootc(p) * lwtop + ntovr = ctovr / livewdcn(ivt(p)) + livecrootc_to_deadcrootc(p) = ctovr + livecrootn_to_deadcrootn(p) = ctovr / deadwdcn(ivt(p)) + + if (CNratio_floating .eqv. .true.) then + if (livecrootc(p) == 0.0_r8) then + ntovr = 0.0_r8 + else + ntovr = ctovr * (livecrootn(p) / livecrootc(p)) + end if + + livecrootn_to_deadcrootn(p) = 0.5_r8 * ntovr ! assuming 50% goes to deadstemn + end if + + livecrootn_to_retransn(p) = ntovr - livecrootn_to_deadcrootn(p) + if(use_fun)then + !TURNED OFF FLUXES TO CORRECT N ACCUMULATION ISSUE. RF. Oct 2015. + livecrootn_to_retransn(p) = 0.0_r8 + livestemn_to_retransn(p) = 0.0_r8 + endif + + end if + + end do + + end associate + + end subroutine CNLivewoodTurnover + + !----------------------------------------------------------------------- + subroutine CNGrainToProductPools(bounds, num_soilp, filter_soilp, num_soilc, filter_soilc, & + cnveg_carbonflux_inst, cnveg_nitrogenflux_inst) + ! + ! !DESCRIPTION: + ! If using prognostic crop along with use_grainproduct, then move the patch-level + ! grain-to-food fluxes into the column-level grain-to-cropprod fluxes + ! + ! !USES: + use clm_varctl , only : use_crop + use clm_varctl , only : use_grainproduct + use subgridAveMod , only : p2c + ! + ! !ARGUMENTS: + type(bounds_type) , intent(in) :: bounds + integer , intent(in) :: num_soilp ! number of soil patches in filter + integer , intent(in) :: filter_soilp(:) ! filter for soil patches + integer , intent(in) :: num_soilc ! number of soil columns in filter + integer , intent(in) :: filter_soilc(:) ! filter for soil columns + type(cnveg_carbonflux_type) , intent(inout) :: cnveg_carbonflux_inst + type(cnveg_nitrogenflux_type) , intent(inout) :: cnveg_nitrogenflux_inst + ! + ! !LOCAL VARIABLES: + integer :: fp, p + + character(len=*), parameter :: subname = 'CNGrainToProductPools' + !----------------------------------------------------------------------- + + ! Explicitly checking use_crop is probably unnecessary here (because presumably + ! use_grainproduct is only true if use_crop is true), but we do it for safety because + ! the grain*_to_food_patch fluxes are not set if use_crop is false. + if (use_crop .and. use_grainproduct) then + do fp = 1, num_soilp + p = filter_soilp(fp) + cnveg_carbonflux_inst%grainc_to_cropprodc_patch(p) = & + cnveg_carbonflux_inst%grainc_to_food_patch(p) + cnveg_nitrogenflux_inst%grainn_to_cropprodn_patch(p) = & + cnveg_nitrogenflux_inst%grainn_to_food_patch(p) + end do + + call p2c (bounds, num_soilc, filter_soilc, & + cnveg_carbonflux_inst%grainc_to_cropprodc_patch(bounds%begp:bounds%endp), & + cnveg_carbonflux_inst%grainc_to_cropprodc_col(bounds%begc:bounds%endc)) + + call p2c (bounds, num_soilc, filter_soilc, & + cnveg_nitrogenflux_inst%grainn_to_cropprodn_patch(bounds%begp:bounds%endp), & + cnveg_nitrogenflux_inst%grainn_to_cropprodn_col(bounds%begc:bounds%endc)) + end if + + ! No else clause: if use_grainproduct is false, then the grain*_to_cropprod fluxes + ! will remain at their initial value (0). + + end subroutine CNGrainToProductPools + + !----------------------------------------------------------------------- + subroutine CNLitterToColumn (bounds, num_soilc, filter_soilc, & + cnveg_state_inst,cnveg_carbonflux_inst, cnveg_nitrogenflux_inst, & + leaf_prof_patch, froot_prof_patch) + ! + ! !DESCRIPTION: + ! called at the end of cn_phenology to gather all patch-level litterfall fluxes + ! to the column level and assign them to the three litter pools + ! + ! !USES: + use clm_varpar , only : max_patch_per_col, nlevdecomp + use pftconMod , only : npcropmin + use clm_varctl , only : use_grainproduct + ! + ! !ARGUMENTS: + type(bounds_type) , intent(in) :: bounds + integer , intent(in) :: num_soilc ! number of soil columns in filter + integer , intent(in) :: filter_soilc(:) ! filter for soil columns + type(cnveg_state_type) , intent(in) :: cnveg_state_inst + type(cnveg_carbonflux_type) , intent(inout) :: cnveg_carbonflux_inst + type(cnveg_nitrogenflux_type) , intent(inout) :: cnveg_nitrogenflux_inst + real(r8) , intent(in) :: leaf_prof_patch(bounds%begp:,1:) + real(r8) , intent(in) :: froot_prof_patch(bounds%begp:,1:) + ! + ! !LOCAL VARIABLES: + integer :: fc,c,pi,p,j ! indices + !----------------------------------------------------------------------- + + SHR_ASSERT_ALL_FL((ubound(leaf_prof_patch) == (/bounds%endp,nlevdecomp_full/)), sourcefile, __LINE__) + SHR_ASSERT_ALL_FL((ubound(froot_prof_patch) == (/bounds%endp,nlevdecomp_full/)), sourcefile, __LINE__) + + associate( & + leaf_prof => leaf_prof_patch , & ! Input: [real(r8) (:,:) ] (1/m) profile of leaves + froot_prof => froot_prof_patch , & ! Input: [real(r8) (:,:) ] (1/m) profile of fine roots + + ivt => patch%itype , & ! Input: [integer (:) ] patch vegetation type + wtcol => patch%wtcol , & ! Input: [real(r8) (:) ] weight (relative to column) for this patch (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 + + leafc_to_litter => cnveg_carbonflux_inst%leafc_to_litter_patch , & ! Input: [real(r8) (:) ] leaf C litterfall (gC/m2/s) + frootc_to_litter => cnveg_carbonflux_inst%frootc_to_litter_patch , & ! Input: [real(r8) (:) ] fine root N litterfall (gN/m2/s) + livestemc_to_litter => cnveg_carbonflux_inst%livestemc_to_litter_patch , & ! Input: [real(r8) (:) ] live stem C litterfall (gC/m2/s) + grainc_to_food => cnveg_carbonflux_inst%grainc_to_food_patch , & ! Input: [real(r8) (:) ] grain C to food (gC/m2/s) + + biofuelc_harvest => cnveg_carbonflux_inst%biofuelc_harvest_patch , & ! Input: [real(r8) (:) ] biofuel C (gC/m2/s) + + phenology_c_to_litr_met_c => cnveg_carbonflux_inst%phenology_c_to_litr_met_c_col , & ! Output: [real(r8) (:,:) ] C fluxes associated with phenology (litterfall and crop) to litter metabolic pool (gC/m3/s) + phenology_c_to_litr_cel_c => cnveg_carbonflux_inst%phenology_c_to_litr_cel_c_col , & ! Output: [real(r8) (:,:) ] C fluxes associated with phenology (litterfall and crop) to litter cellulose pool (gC/m3/s) + phenology_c_to_litr_lig_c => cnveg_carbonflux_inst%phenology_c_to_litr_lig_c_col , & ! Output: [real(r8) (:,:) ] C fluxes associated with phenology (litterfall and crop) to litter lignin pool (gC/m3/s) + + livestemn_to_litter => cnveg_nitrogenflux_inst%livestemn_to_litter_patch , & ! Input: [real(r8) (:) ] livestem N to litter (gN/m2/s) + grainn_to_food => cnveg_nitrogenflux_inst%grainn_to_food_patch , & ! Input: [real(r8) (:) ] grain N to food (gN/m2/s) + biofueln_harvest => cnveg_nitrogenflux_inst%biofueln_harvest_patch , & ! Input: [real(r8) (:) ] biofuel N (gN/m2/s) + leafn_to_litter => cnveg_nitrogenflux_inst%leafn_to_litter_patch , & ! Input: [real(r8) (:) ] leaf N litterfall (gN/m2/s) + frootn_to_litter => cnveg_nitrogenflux_inst%frootn_to_litter_patch , & ! Input: [real(r8) (:) ] fine root N litterfall (gN/m2/s) + phenology_n_to_litr_met_n => cnveg_nitrogenflux_inst%phenology_n_to_litr_met_n_col , & ! Output: [real(r8) (:,:) ] N fluxes associated with phenology (litterfall and crop) to litter metabolic pool (gN/m3/s) + phenology_n_to_litr_cel_n => cnveg_nitrogenflux_inst%phenology_n_to_litr_cel_n_col , & ! Output: [real(r8) (:,:) ] N fluxes associated with phenology (litterfall and crop) to litter cellulose pool (gN/m3/s) + phenology_n_to_litr_lig_n => cnveg_nitrogenflux_inst%phenology_n_to_litr_lig_n_col & ! Output: [real(r8) (:,:) ] N fluxes associated with phenology (litterfall and crop) to litter lignin pool (gN/m3/s) + ) + + do j = 1, nlevdecomp + do pi = 1,max_patch_per_col + 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 litter carbon fluxes + phenology_c_to_litr_met_c(c,j) = phenology_c_to_litr_met_c(c,j) & + + leafc_to_litter(p) * lf_flab(ivt(p)) * wtcol(p) * leaf_prof(p,j) + phenology_c_to_litr_cel_c(c,j) = phenology_c_to_litr_cel_c(c,j) & + + leafc_to_litter(p) * lf_fcel(ivt(p)) * wtcol(p) * leaf_prof(p,j) + phenology_c_to_litr_lig_c(c,j) = phenology_c_to_litr_lig_c(c,j) & + + leafc_to_litter(p) * lf_flig(ivt(p)) * wtcol(p) * leaf_prof(p,j) + + ! leaf litter nitrogen fluxes + phenology_n_to_litr_met_n(c,j) = phenology_n_to_litr_met_n(c,j) & + + leafn_to_litter(p) * lf_flab(ivt(p)) * wtcol(p) * leaf_prof(p,j) + phenology_n_to_litr_cel_n(c,j) = phenology_n_to_litr_cel_n(c,j) & + + leafn_to_litter(p) * lf_fcel(ivt(p)) * wtcol(p) * leaf_prof(p,j) + phenology_n_to_litr_lig_n(c,j) = phenology_n_to_litr_lig_n(c,j) & + + leafn_to_litter(p) * lf_flig(ivt(p)) * wtcol(p) * leaf_prof(p,j) + + ! fine root litter carbon fluxes + phenology_c_to_litr_met_c(c,j) = phenology_c_to_litr_met_c(c,j) & + + frootc_to_litter(p) * fr_flab(ivt(p)) * wtcol(p) * froot_prof(p,j) + phenology_c_to_litr_cel_c(c,j) = phenology_c_to_litr_cel_c(c,j) & + + frootc_to_litter(p) * fr_fcel(ivt(p)) * wtcol(p) * froot_prof(p,j) + phenology_c_to_litr_lig_c(c,j) = phenology_c_to_litr_lig_c(c,j) & + + frootc_to_litter(p) * fr_flig(ivt(p)) * wtcol(p) * froot_prof(p,j) + + ! fine root litter nitrogen fluxes + phenology_n_to_litr_met_n(c,j) = phenology_n_to_litr_met_n(c,j) & + + frootn_to_litter(p) * fr_flab(ivt(p)) * wtcol(p) * froot_prof(p,j) + phenology_n_to_litr_cel_n(c,j) = phenology_n_to_litr_cel_n(c,j) & + + frootn_to_litter(p) * fr_fcel(ivt(p)) * wtcol(p) * froot_prof(p,j) + phenology_n_to_litr_lig_n(c,j) = phenology_n_to_litr_lig_n(c,j) & + + frootn_to_litter(p) * fr_flig(ivt(p)) * wtcol(p) * froot_prof(p,j) + + ! agroibis puts crop stem litter together with leaf litter + ! so I've used the leaf lf_f* parameters instead of making + ! new ones for now (slevis) + ! also for simplicity I've put "food" into the litter pools + + if (ivt(p) >= npcropmin) then ! add livestemc to litter + ! stem litter carbon fluxes + phenology_c_to_litr_met_c(c,j) = phenology_c_to_litr_met_c(c,j) & + + livestemc_to_litter(p) * lf_flab(ivt(p)) * wtcol(p) * leaf_prof(p,j) + phenology_c_to_litr_cel_c(c,j) = phenology_c_to_litr_cel_c(c,j) & + + livestemc_to_litter(p) * lf_fcel(ivt(p)) * wtcol(p) * leaf_prof(p,j) + phenology_c_to_litr_lig_c(c,j) = phenology_c_to_litr_lig_c(c,j) & + + livestemc_to_litter(p) * lf_flig(ivt(p)) * wtcol(p) * leaf_prof(p,j) + + ! stem litter nitrogen fluxes + phenology_n_to_litr_met_n(c,j) = phenology_n_to_litr_met_n(c,j) & + + livestemn_to_litter(p) * lf_flab(ivt(p)) * wtcol(p) * leaf_prof(p,j) + phenology_n_to_litr_cel_n(c,j) = phenology_n_to_litr_cel_n(c,j) & + + livestemn_to_litter(p) * lf_fcel(ivt(p)) * wtcol(p) * leaf_prof(p,j) + phenology_n_to_litr_lig_n(c,j) = phenology_n_to_litr_lig_n(c,j) & + + livestemn_to_litter(p) * lf_flig(ivt(p)) * wtcol(p) * leaf_prof(p,j) + + if (.not. use_grainproduct) then + ! grain litter carbon fluxes + phenology_c_to_litr_met_c(c,j) = phenology_c_to_litr_met_c(c,j) & + + grainc_to_food(p) * lf_flab(ivt(p)) * wtcol(p) * leaf_prof(p,j) & + + biofuelc_harvest(p) * lf_flab(ivt(p)) * wtcol(p) * leaf_prof(p,j) ! biofuel + phenology_c_to_litr_cel_c(c,j) = phenology_c_to_litr_cel_c(c,j) & + + grainc_to_food(p) * lf_fcel(ivt(p)) * wtcol(p) * leaf_prof(p,j) & + + biofuelc_harvest(p) * lf_fcel(ivt(p)) * wtcol(p) * leaf_prof(p,j) ! biofuel + phenology_c_to_litr_lig_c(c,j) = phenology_c_to_litr_lig_c(c,j) & + + grainc_to_food(p) * lf_flig(ivt(p)) * wtcol(p) * leaf_prof(p,j) & + + biofuelc_harvest(p) * lf_flig(ivt(p)) * wtcol(p) * leaf_prof(p,j) ! biofuel + + ! grain litter nitrogen fluxes + phenology_n_to_litr_met_n(c,j) = phenology_n_to_litr_met_n(c,j) & + + grainn_to_food(p) * lf_flab(ivt(p)) * wtcol(p) * leaf_prof(p,j) & + + biofueln_harvest(p) * lf_flab(ivt(p)) * wtcol(p) * leaf_prof(p,j) ! biofuel + phenology_n_to_litr_cel_n(c,j) = phenology_n_to_litr_cel_n(c,j) & + + grainn_to_food(p) * lf_fcel(ivt(p)) * wtcol(p) * leaf_prof(p,j) & + + biofueln_harvest(p) * lf_fcel(ivt(p)) * wtcol(p) * leaf_prof(p,j) ! biofuel + phenology_n_to_litr_lig_n(c,j) = phenology_n_to_litr_lig_n(c,j) & + + grainn_to_food(p) * lf_flig(ivt(p)) * wtcol(p) * leaf_prof(p,j) & + + biofueln_harvest(p) * lf_flig(ivt(p)) * wtcol(p) * leaf_prof(p,j) ! biofuel + end if + + + end if + end if + end if + + end do + + end do + end do + + end associate + + end subroutine CNLitterToColumn + +end module CNPhenologyMod From e30e87bd4c44c6e3395c361fc076cabc5941030d Mon Sep 17 00:00:00 2001 From: chen693 Date: Mon, 24 Feb 2020 14:56:04 -0800 Subject: [PATCH 07/75] cut a certain fraction of crop leaf biomass during offset period --- src/biogeochem/CNPhenologyMod.F90 | 89 ++++++++++++++----------------- 1 file changed, 41 insertions(+), 48 deletions(-) diff --git a/src/biogeochem/CNPhenologyMod.F90 b/src/biogeochem/CNPhenologyMod.F90 index a0c34e7472..3079f12670 100644 --- a/src/biogeochem/CNPhenologyMod.F90 +++ b/src/biogeochem/CNPhenologyMod.F90 @@ -2415,7 +2415,11 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, & associate( & ivt => patch%itype , & ! Input: [integer (:) ] patch vegetation type - leafcn => pftcon%leafcn , & ! Input: leaf C:N (gC/gN) + leafcn => pftcon%leafcn , & ! Input: leaf C:N (gC/gN) + + ! Y. Cheng, add a new cut fraction for harvest parameter for bioenergy crops (miscanthus and switchgrass) + harvfrac => pftcon%harvfrac , & ! Input: cut fraction for harvest (-) + lflitcn => pftcon%lflitcn , & ! Input: leaf litter C:N (gC/gN) frootcn => pftcon%frootcn , & ! Input: fine root C:N (gC/gN) graincn => pftcon%graincn , & ! Input: grain C:N (gC/gN) @@ -2442,14 +2446,19 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, & leafc_to_litter => cnveg_carbonflux_inst%leafc_to_litter_patch , & ! Output: [real(r8) (:) ] leaf C litterfall (gC/m2/s) frootc_to_litter => cnveg_carbonflux_inst%frootc_to_litter_patch , & ! Output: [real(r8) (:) ] fine root C litterfall (gC/m2/s) livestemc_to_litter => cnveg_carbonflux_inst%livestemc_to_litter_patch , & ! Output: [real(r8) (:) ] live stem C litterfall (gC/m2/s) - grainc_to_food => cnveg_carbonflux_inst%grainc_to_food_patch , & ! Output: [real(r8) (:) ] grain C to food (gC/m2/s) + grainc_to_food => cnveg_carbonflux_inst%grainc_to_food_patch , & ! Output: [real(r8) (:) ] grain C to food (gC/m2/s) + + ! Y. Cheng, put the cut fraction during offset period for bioenergy crops to this biofuelc_harvest flux + biofuelc_harvest => cnveg_carbonflux_inst%biofuelc_harvest_patch , & ! Output: [real(r8) (:) ] biofuel C that was cutted at harvest (gC/m2/s) + grainc_to_seed => cnveg_carbonflux_inst%grainc_to_seed_patch , & ! Output: [real(r8) (:) ] grain C to seed (gC/m2/s) 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_to_litter => cnveg_nitrogenflux_inst%livestemn_to_litter_patch , & ! Output: [real(r8) (:) ] livestem N to litter (gN/m2/s) - grainn_to_food => cnveg_nitrogenflux_inst%grainn_to_food_patch , & ! Output: [real(r8) (:) ] grain N to food (gN/m2/s) - grainn_to_seed => cnveg_nitrogenflux_inst%grainn_to_seed_patch , & ! Output: [real(r8) (:) ] grain N to seed (gN/m2/s) + grainn_to_food => cnveg_nitrogenflux_inst%grainn_to_food_patch , & ! Output: [real(r8) (:) ] grain N to food (gN/m2/s) + biofueln_harvest => cnveg_nitrogenflux_inst%biofueln_harvest_patch , & ! Output: [real(r8) (:) ] biofuel N that was cutted (gC/m2/s) + grainn_to_seed => cnveg_nitrogenflux_inst%grainn_to_seed_patch , & ! Output: [real(r8) (:) ] grain N to seed (gN/m2/s) leafn_to_litter => cnveg_nitrogenflux_inst%leafn_to_litter_patch , & ! Output: [real(r8) (:) ] leaf N litterfall (gN/m2/s) leafn_to_retransn => cnveg_nitrogenflux_inst%leafn_to_retransn_patch , & ! Input: [real(r8) (:) ] leaf N to retranslocated N pool (gN/m2/s) free_retransn_to_npool=> cnveg_nitrogenflux_inst%free_retransn_to_npool_patch , & ! Input: [real(r8) (:) ] free leaf N to retranslocated N pool (gN/m2/s) @@ -2470,21 +2479,13 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, & if (offset_counter(p) == dt) then t1 = 1.0_r8 / dt - !leafc_to_litter(p) = t1 * leafc(p) + cpool_to_leafc(p) frootc_to_litter(p) = t1 * frootc(p) + cpool_to_frootc(p) - ! Y. Cheng, cut 70% AGB for switchgrass and Miscanthus and move to grainc_to_food - if (ivt(p)==nmiscanthus .or. ivt(p)==nirrig_miscanthus .or. ivt(p)==nswitchgrass .or. ivt(p)==nirrig_switchgrass) then - leafc_to_litter(p) = t1 * leafc(p)*0.3 + cpool_to_leafc(p) - grainc_to_food(p) =grainc_to_food(p)+ t1 * leafc(p) * 0.7 - grainn_to_food(p) =grainn_to_food(p)+ t1 * leafn(p) * 0.7 - -! leafc_to_litter(p) = (t1 * leafc(p) + cpool_to_leafc(p))*0.3 -! grainc_to_food(p) =grainc_to_food(p)+ (t1 * leafc(p) + cpool_to_leafc(p))*0.7 -! grainn_to_food(p) =grainn_to_food(p)+ t1 * leafn(p) * 0.7 - else - leafc_to_litter(p) = t1 * leafc(p) + cpool_to_leafc(p) - end if + ! Cut a certain fraction (i.e., harvfrac(ivt(p))) (e.g., harvfrac(ivt(p)=70% for bioenergy crops) of leafc for harvest + ! and move this cut fration to the biofuelc_harvest flux, rather than move it to litter + leafc_to_litter(p) = t1 * leafc(p)*(1._r8-harvfrac(ivt(p))) + cpool_to_leafc(p) + biofuelc_harvest(p) = t1 * leafc(p) * harvfrac(ivt(p)) + biofueln_harvest(p) = t1 * leafn(p) * harvfrac(ivt(p)) ! this assumes that offset_counter == dt for crops ! if this were ever changed, we'd need to add code to the "else" @@ -2496,17 +2497,10 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, & grainc_to_seed(p) = t1 * min(-cropseedc_deficit(p), grainc(p)) grainn_to_seed(p) = t1 * min(-cropseedn_deficit(p), grainn(p)) ! Send the remaining grain to the food product pool - - ! Y. Cheng, because I calculated grainc_to_food and grainn_to_food earlier - if (ivt(p)==nmiscanthus .or. ivt(p)==nirrig_miscanthus .or. ivt(p)==nswitchgrass .or. ivt(p)==nirrig_switchgrass) then - grainc_to_food(p) = grainc_to_food(p) + t1 * grainc(p) + cpool_to_grainc(p) - grainc_to_seed(p) - grainn_to_food(p) = grainn_to_food(p) + t1 * grainn(p) + npool_to_grainn(p) - grainn_to_seed(p) - else - grainc_to_food(p) = t1 * grainc(p) + cpool_to_grainc(p) - grainc_to_seed(p) - grainn_to_food(p) = t1 * grainn(p) + npool_to_grainn(p) - grainn_to_seed(p) - end if - - livestemc_to_litter(p) = t1 * livestemc(p) + cpool_to_livestemc(p) + grainc_to_food(p) = t1 * grainc(p) + cpool_to_grainc(p) - grainc_to_seed(p) + grainn_to_food(p) = t1 * grainn(p) + npool_to_grainn(p) - grainn_to_seed(p) + + livestemc_to_litter(p) = t1 * livestemc(p) + cpool_to_livestemc(p) end if else t1 = dt * 2.0_r8 / (offset_counter(p) * offset_counter(p)) @@ -2594,18 +2588,7 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, & ! save the current litterfall fluxes prev_leafc_to_litter(p) = leafc_to_litter(p) prev_frootc_to_litter(p) = frootc_to_litter(p) - - - ! Y. Cheng, cut 70% AGB for switchgrass and Miscanthus - if (offset_counter(p) == dt) then - if (ivt(p)==nmiscanthus .or. ivt(p)==nirrig_miscanthus .or. ivt(p)==nswitchgrass .or. ivt(p)==nirrig_switchgrass) then - grainc(p) = grainc(p) + leafc(p)*0.7 - leafc(p) = leafc(p) * 0.3 - grainn(p) = grainn(p) + leafn(p)*0.7 - leafn(p) = leafn(p) * 0.3 - end if - end if - + end if ! end if offset period end do ! end patch loop @@ -2955,13 +2938,17 @@ subroutine CNLitterToColumn (bounds, num_soilc, filter_soilc, & leafc_to_litter => cnveg_carbonflux_inst%leafc_to_litter_patch , & ! Input: [real(r8) (:) ] leaf C litterfall (gC/m2/s) frootc_to_litter => cnveg_carbonflux_inst%frootc_to_litter_patch , & ! Input: [real(r8) (:) ] fine root N litterfall (gN/m2/s) livestemc_to_litter => cnveg_carbonflux_inst%livestemc_to_litter_patch , & ! Input: [real(r8) (:) ] live stem C litterfall (gC/m2/s) - grainc_to_food => cnveg_carbonflux_inst%grainc_to_food_patch , & ! Input: [real(r8) (:) ] grain C to food (gC/m2/s) + grainc_to_food => cnveg_carbonflux_inst%grainc_to_food_patch , & ! Input: [real(r8) (:) ] grain C to food (gC/m2/s) + + biofuelc_harvest => cnveg_carbonflux_inst%biofuelc_harvest_patch , & ! Input: [real(r8) (:) ] biofuel C (gC/m2/s) + phenology_c_to_litr_met_c => cnveg_carbonflux_inst%phenology_c_to_litr_met_c_col , & ! Output: [real(r8) (:,:) ] C fluxes associated with phenology (litterfall and crop) to litter metabolic pool (gC/m3/s) phenology_c_to_litr_cel_c => cnveg_carbonflux_inst%phenology_c_to_litr_cel_c_col , & ! Output: [real(r8) (:,:) ] C fluxes associated with phenology (litterfall and crop) to litter cellulose pool (gC/m3/s) phenology_c_to_litr_lig_c => cnveg_carbonflux_inst%phenology_c_to_litr_lig_c_col , & ! Output: [real(r8) (:,:) ] C fluxes associated with phenology (litterfall and crop) to litter lignin pool (gC/m3/s) livestemn_to_litter => cnveg_nitrogenflux_inst%livestemn_to_litter_patch , & ! Input: [real(r8) (:) ] livestem N to litter (gN/m2/s) - grainn_to_food => cnveg_nitrogenflux_inst%grainn_to_food_patch , & ! Input: [real(r8) (:) ] grain N to food (gN/m2/s) + grainn_to_food => cnveg_nitrogenflux_inst%grainn_to_food_patch , & ! Input: [real(r8) (:) ] grain N to food (gN/m2/s) + biofueln_harvest => cnveg_nitrogenflux_inst%biofueln_harvest_patch , & ! Input: [real(r8) (:) ] biofuel N (gN/m2/s) leafn_to_litter => cnveg_nitrogenflux_inst%leafn_to_litter_patch , & ! Input: [real(r8) (:) ] leaf N litterfall (gN/m2/s) frootn_to_litter => cnveg_nitrogenflux_inst%frootn_to_litter_patch , & ! Input: [real(r8) (:) ] fine root N litterfall (gN/m2/s) phenology_n_to_litr_met_n => cnveg_nitrogenflux_inst%phenology_n_to_litr_met_n_col , & ! Output: [real(r8) (:,:) ] N fluxes associated with phenology (litterfall and crop) to litter metabolic pool (gN/m3/s) @@ -3035,19 +3022,25 @@ subroutine CNLitterToColumn (bounds, num_soilc, filter_soilc, & if (.not. use_grainproduct) then ! grain litter carbon fluxes phenology_c_to_litr_met_c(c,j) = phenology_c_to_litr_met_c(c,j) & - + grainc_to_food(p) * lf_flab(ivt(p)) * wtcol(p) * leaf_prof(p,j) + + grainc_to_food(p) * lf_flab(ivt(p)) * wtcol(p) * leaf_prof(p,j) & + + biofuelc_harvest(p) * lf_flab(ivt(p)) * wtcol(p) * leaf_prof(p,j) ! biofuel phenology_c_to_litr_cel_c(c,j) = phenology_c_to_litr_cel_c(c,j) & - + grainc_to_food(p) * lf_fcel(ivt(p)) * wtcol(p) * leaf_prof(p,j) + + grainc_to_food(p) * lf_fcel(ivt(p)) * wtcol(p) * leaf_prof(p,j) & + + biofuelc_harvest(p) * lf_fcel(ivt(p)) * wtcol(p) * leaf_prof(p,j) ! biofuel phenology_c_to_litr_lig_c(c,j) = phenology_c_to_litr_lig_c(c,j) & - + grainc_to_food(p) * lf_flig(ivt(p)) * wtcol(p) * leaf_prof(p,j) + + grainc_to_food(p) * lf_flig(ivt(p)) * wtcol(p) * leaf_prof(p,j) & + + biofuelc_harvest(p) * lf_flig(ivt(p)) * wtcol(p) * leaf_prof(p,j) ! biofuel ! grain litter nitrogen fluxes phenology_n_to_litr_met_n(c,j) = phenology_n_to_litr_met_n(c,j) & - + grainn_to_food(p) * lf_flab(ivt(p)) * wtcol(p) * leaf_prof(p,j) + + grainn_to_food(p) * lf_flab(ivt(p)) * wtcol(p) * leaf_prof(p,j) & + + biofueln_harvest(p) * lf_flab(ivt(p)) * wtcol(p) * leaf_prof(p,j) ! biofuel phenology_n_to_litr_cel_n(c,j) = phenology_n_to_litr_cel_n(c,j) & - + grainn_to_food(p) * lf_fcel(ivt(p)) * wtcol(p) * leaf_prof(p,j) + + grainn_to_food(p) * lf_fcel(ivt(p)) * wtcol(p) * leaf_prof(p,j) & + + biofueln_harvest(p) * lf_fcel(ivt(p)) * wtcol(p) * leaf_prof(p,j) ! biofuel phenology_n_to_litr_lig_n(c,j) = phenology_n_to_litr_lig_n(c,j) & - + grainn_to_food(p) * lf_flig(ivt(p)) * wtcol(p) * leaf_prof(p,j) + + grainn_to_food(p) * lf_flig(ivt(p)) * wtcol(p) * leaf_prof(p,j) & + + biofueln_harvest(p) * lf_flig(ivt(p)) * wtcol(p) * leaf_prof(p,j) ! biofuel end if From 7c3d10b864c39cdd2e90413d10e02d5c25ea3ee5 Mon Sep 17 00:00:00 2001 From: YanyanCheng <40185802+yanyanchengHydro@users.noreply.github.com> Date: Mon, 24 Feb 2020 14:56:59 -0800 Subject: [PATCH 08/75] Delete CNPhenologyMod_cut_newFlux_newCutParam_N.F90 --- ...PhenologyMod_cut_newFlux_newCutParam_N.F90 | 3060 ----------------- 1 file changed, 3060 deletions(-) delete mode 100644 src/biogeochem/CNPhenologyMod_cut_newFlux_newCutParam_N.F90 diff --git a/src/biogeochem/CNPhenologyMod_cut_newFlux_newCutParam_N.F90 b/src/biogeochem/CNPhenologyMod_cut_newFlux_newCutParam_N.F90 deleted file mode 100644 index 3079f12670..0000000000 --- a/src/biogeochem/CNPhenologyMod_cut_newFlux_newCutParam_N.F90 +++ /dev/null @@ -1,3060 +0,0 @@ -module CNPhenologyMod - -#include "shr_assert.h" - - !----------------------------------------------------------------------- - ! !MODULE: CNPhenologyMod - ! - ! !DESCRIPTION: - ! Module holding routines used in phenology model for coupled carbon - ! nitrogen code. - ! - ! !USES: - use shr_kind_mod , only : r8 => shr_kind_r8 - use shr_log_mod , only : errMsg => shr_log_errMsg - use shr_sys_mod , only : shr_sys_flush - use decompMod , only : bounds_type - use clm_varpar , only : maxveg, nlevdecomp_full - use clm_varctl , only : iulog, use_cndv - use clm_varcon , only : tfrz - use abortutils , only : endrun - use CanopyStateType , only : canopystate_type - use CNDVType , only : dgvs_type - use CNVegstateType , only : cnveg_state_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 CropType , only : crop_type - use pftconMod , only : pftcon - use SoilStateType , only : soilstate_type - use TemperatureType , only : temperature_type - use WaterDiagnosticBulkType , only : waterdiagnosticbulk_type - use Wateratm2lndBulkType , only : wateratm2lndbulk_type - use ColumnType , only : col - use GridcellType , only : grc - use PatchType , only : patch - use atm2lndType , only : atm2lnd_type - use atm2lndType , only : atm2lnd_type - ! - implicit none - private - ! - ! !PUBLIC MEMBER FUNCTIONS: - public :: readParams ! Read parameters - public :: CNPhenologyreadNML ! Read namelist - public :: CNPhenologyInit ! Initialization - public :: CNPhenology ! Update - ! - ! !PRIVATE DATA MEMBERS: - type, private :: params_type - real(r8) :: crit_dayl ! critical day length for senescence - real(r8) :: ndays_on ! number of days to complete leaf onset - real(r8) :: ndays_off ! number of days to complete leaf offset - real(r8) :: fstor2tran ! fraction of storage to move to transfer for each onset - real(r8) :: crit_onset_fdd ! critical number of freezing days to set gdd counter - real(r8) :: crit_onset_swi ! critical number of days > soilpsi_on for onset - real(r8) :: soilpsi_on ! critical soil water potential for leaf onset - real(r8) :: crit_offset_fdd ! critical number of freezing days to initiate offset - real(r8) :: crit_offset_swi ! critical number of water stress days to initiate offset - real(r8) :: soilpsi_off ! critical soil water potential for leaf offset - real(r8) :: lwtop ! live wood turnover proportion (annual fraction) - end type params_type - - type(params_type) :: params_inst - - real(r8) :: dt ! radiation time step delta t (seconds) - real(r8) :: fracday ! dtime as a fraction of day - real(r8) :: crit_dayl ! critical daylength for offset (seconds) - real(r8) :: ndays_on ! number of days to complete onset - real(r8) :: ndays_off ! number of days to complete offset - real(r8) :: fstor2tran ! fraction of storage to move to transfer on each onset - real(r8) :: crit_onset_fdd ! critical number of freezing days - real(r8) :: crit_onset_swi ! water stress days for offset trigger - real(r8) :: soilpsi_on ! water potential for onset trigger (MPa) - real(r8) :: crit_offset_fdd ! critical number of freezing degree days to trigger offset - real(r8) :: crit_offset_swi ! water stress days for offset trigger - real(r8) :: soilpsi_off ! water potential for offset trigger (MPa) - real(r8) :: lwtop ! live wood turnover proportion (annual fraction) - - ! CropPhenology variables and constants - real(r8) :: p1d, p1v ! photoperiod factor constants for crop vernalization - real(r8) :: hti ! cold hardening index threshold for vernalization - real(r8) :: tbase ! base temperature for vernalization - - integer, parameter :: NOT_Planted = 999 ! If not planted yet in year - integer, parameter :: NOT_Harvested = 999 ! If not harvested yet in year - integer, parameter :: inNH = 1 ! Northern Hemisphere - integer, parameter :: inSH = 2 ! Southern Hemisphere - integer, pointer :: inhemi(:) ! Hemisphere that patch is in - - integer, allocatable :: minplantjday(:,:) ! minimum planting julian day - integer, allocatable :: maxplantjday(:,:) ! maximum planting julian day - integer :: jdayyrstart(inSH) ! julian day of start of year - - real(r8), private :: initial_seed_at_planting = 3._r8 ! Initial seed at planting - - character(len=*), parameter, private :: sourcefile = & - __FILE__ - !----------------------------------------------------------------------- - -contains - - !----------------------------------------------------------------------- - subroutine CNPhenologyReadNML( NLFilename ) - ! - ! !DESCRIPTION: - ! Read the namelist for CNPhenology - ! - ! !USES: - use fileutils , only : getavu, relavu, opnfil - use shr_nl_mod , only : shr_nl_find_group_name - use spmdMod , only : masterproc, mpicom - use shr_mpi_mod , only : shr_mpi_bcast - use clm_varctl , only : iulog - ! - ! !ARGUMENTS: - character(len=*), intent(in) :: NLFilename ! Namelist filename - ! - ! !LOCAL VARIABLES: - integer :: ierr ! error code - integer :: unitn ! unit for namelist file - - character(len=*), parameter :: subname = 'CNPhenologyReadNML' - character(len=*), parameter :: nmlname = 'cnphenology' - !----------------------------------------------------------------------- - namelist /cnphenology/ initial_seed_at_planting - - ! Initialize options to default values, in case they are not specified in - ! the namelist - - if (masterproc) then - unitn = getavu() - write(iulog,*) 'Read in '//nmlname//' namelist' - call opnfil (NLFilename, unitn, 'F') - call shr_nl_find_group_name(unitn, nmlname, status=ierr) - if (ierr == 0) then - read(unitn, nml=cnphenology, iostat=ierr) - if (ierr /= 0) then - call endrun(msg="ERROR reading "//nmlname//"namelist"//errmsg(sourcefile, __LINE__)) - end if - else - call endrun(msg="ERROR could NOT find "//nmlname//"namelist"//errmsg(sourcefile, __LINE__)) - end if - call relavu( unitn ) - end if - - call shr_mpi_bcast (initial_seed_at_planting, mpicom) - - if (masterproc) then - write(iulog,*) ' ' - write(iulog,*) nmlname//' settings:' - write(iulog,nml=cnphenology) - write(iulog,*) ' ' - end if - - - !----------------------------------------------------------------------- - - end subroutine CNPhenologyReadNML - - !----------------------------------------------------------------------- - subroutine readParams ( ncid ) - ! - ! !DESCRIPTION: - ! - ! !USES: - use ncdio_pio , only: file_desc_t,ncd_io - - ! !ARGUMENTS: - implicit none - type(file_desc_t),intent(inout) :: ncid ! pio netCDF file id - ! - ! !LOCAL VARIABLES: - character(len=32) :: subname = 'CNPhenolParamsType' - character(len=100) :: errCode = '-Error reading in parameters file:' - logical :: readv ! has variable been read in or not - real(r8) :: tempr ! temporary to read in parameter - character(len=100) :: tString ! temp. var for reading - !----------------------------------------------------------------------- - - ! - ! read in parameters - ! - tString='crit_dayl' - call ncd_io(varname=trim(tString),data=tempr, flag='read', ncid=ncid, readvar=readv) - if ( .not. readv ) call endrun( msg=trim(errCode)//trim(tString)//errMsg(sourcefile, __LINE__)) - params_inst%crit_dayl=tempr - - tString='ndays_on' - call ncd_io(varname=trim(tString),data=tempr, flag='read', ncid=ncid, readvar=readv) - if ( .not. readv ) call endrun( msg=trim(errCode)//trim(tString)//errMsg(sourcefile, __LINE__)) - params_inst%ndays_on=tempr - - tString='ndays_off' - call ncd_io(varname=trim(tString),data=tempr, flag='read', ncid=ncid, readvar=readv) - if ( .not. readv ) call endrun( msg=trim(errCode)//trim(tString)//errMsg(sourcefile, __LINE__)) - params_inst%ndays_off=tempr - - tString='fstor2tran' - call ncd_io(varname=trim(tString),data=tempr, flag='read', ncid=ncid, readvar=readv) - if ( .not. readv ) call endrun( msg=trim(errCode)//trim(tString)//errMsg(sourcefile, __LINE__)) - params_inst%fstor2tran=tempr - - tString='crit_onset_fdd' - call ncd_io(varname=trim(tString),data=tempr, flag='read', ncid=ncid, readvar=readv) - if ( .not. readv ) call endrun( msg=trim(errCode)//trim(tString)//errMsg(sourcefile, __LINE__)) - params_inst%crit_onset_fdd=tempr - - tString='crit_onset_swi' - call ncd_io(varname=trim(tString),data=tempr, flag='read', ncid=ncid, readvar=readv) - if ( .not. readv ) call endrun( msg=trim(errCode)//trim(tString)//errMsg(sourcefile, __LINE__)) - params_inst%crit_onset_swi=tempr - - tString='soilpsi_on' - call ncd_io(varname=trim(tString),data=tempr, flag='read', ncid=ncid, readvar=readv) - if ( .not. readv ) call endrun( msg=trim(errCode)//trim(tString)//errMsg(sourcefile, __LINE__)) - params_inst%soilpsi_on=tempr - - tString='crit_offset_fdd' - call ncd_io(varname=trim(tString),data=tempr, flag='read', ncid=ncid, readvar=readv) - if ( .not. readv ) call endrun( msg=trim(errCode)//trim(tString)//errMsg(sourcefile, __LINE__)) - params_inst%crit_offset_fdd=tempr - - tString='crit_offset_swi' - call ncd_io(varname=trim(tString),data=tempr, flag='read', ncid=ncid, readvar=readv) - if ( .not. readv ) call endrun( msg=trim(errCode)//trim(tString)//errMsg(sourcefile, __LINE__)) - params_inst%crit_offset_swi=tempr - - tString='soilpsi_off' - call ncd_io(varname=trim(tString),data=tempr, flag='read', ncid=ncid, readvar=readv) - if ( .not. readv ) call endrun( msg=trim(errCode)//trim(tString)//errMsg(sourcefile, __LINE__)) - params_inst%soilpsi_off=tempr - - tString='lwtop_ann' - call ncd_io(varname=trim(tString),data=tempr, flag='read', ncid=ncid, readvar=readv) - if ( .not. readv ) call endrun( msg=trim(errCode)//trim(tString)//errMsg(sourcefile, __LINE__)) - params_inst%lwtop=tempr - - end subroutine readParams - - !----------------------------------------------------------------------- - subroutine CNPhenology (bounds, num_soilc, filter_soilc, num_soilp, & - filter_soilp, num_pcropp, filter_pcropp, & - doalb, waterdiagnosticbulk_inst, wateratm2lndbulk_inst, temperature_inst, atm2lnd_inst, crop_inst, & - canopystate_inst, soilstate_inst, dgvs_inst, & - cnveg_state_inst, cnveg_carbonstate_inst, cnveg_carbonflux_inst, & - cnveg_nitrogenstate_inst, cnveg_nitrogenflux_inst, & - c13_cnveg_carbonstate_inst, c14_cnveg_carbonstate_inst, & - leaf_prof_patch, froot_prof_patch, phase) - ! !USES: - use CNSharedParamsMod, only: use_fun - ! - ! !DESCRIPTION: - ! Dynamic phenology routine for coupled carbon-nitrogen code (CN) - ! 1. grass phenology - ! - ! !ARGUMENTS: - type(bounds_type) , intent(in) :: bounds - 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 - integer , intent(in) :: num_pcropp ! number of prog. crop patches in filter - integer , intent(in) :: filter_pcropp(:)! filter for prognostic crop patches - logical , intent(in) :: doalb ! true if time for sfc albedo calc - type(waterdiagnosticbulk_type) , intent(in) :: waterdiagnosticbulk_inst - type(wateratm2lndbulk_type) , intent(in) :: wateratm2lndbulk_inst - type(temperature_type) , intent(inout) :: temperature_inst - type(atm2lnd_type) , intent(in) :: atm2lnd_inst - type(crop_type) , intent(inout) :: crop_inst - type(canopystate_type) , intent(in) :: canopystate_inst - type(soilstate_type) , intent(in) :: soilstate_inst - type(dgvs_type) , intent(inout) :: dgvs_inst - type(cnveg_state_type) , intent(inout) :: cnveg_state_inst - type(cnveg_carbonstate_type) , intent(inout) :: cnveg_carbonstate_inst - type(cnveg_carbonflux_type) , intent(inout) :: cnveg_carbonflux_inst - type(cnveg_nitrogenstate_type) , intent(inout) :: cnveg_nitrogenstate_inst - type(cnveg_nitrogenflux_type) , intent(inout) :: cnveg_nitrogenflux_inst - type(cnveg_carbonstate_type) , intent(inout) :: c13_cnveg_carbonstate_inst - type(cnveg_carbonstate_type) , intent(inout) :: c14_cnveg_carbonstate_inst - real(r8) , intent(in) :: leaf_prof_patch(bounds%begp:,1:) - real(r8) , intent(in) :: froot_prof_patch(bounds%begp:,1:) - integer , intent(in) :: phase - !----------------------------------------------------------------------- - - SHR_ASSERT_ALL_FL((ubound(leaf_prof_patch) == (/bounds%endp,nlevdecomp_full/)), sourcefile, __LINE__) - SHR_ASSERT_ALL_FL((ubound(froot_prof_patch) == (/bounds%endp,nlevdecomp_full/)), sourcefile, __LINE__) - - ! each of the following phenology type routines includes a filter - ! to operate only on the relevant patches - - - if ( phase == 1 ) then - call CNPhenologyClimate(num_soilp, filter_soilp, num_pcropp, filter_pcropp, & - temperature_inst, cnveg_state_inst, crop_inst) - - call CNEvergreenPhenology(num_soilp, filter_soilp, & - cnveg_state_inst, cnveg_carbonstate_inst, cnveg_nitrogenstate_inst, cnveg_carbonflux_inst, cnveg_nitrogenflux_inst) - - call CNSeasonDecidPhenology(num_soilp, filter_soilp, & - temperature_inst, cnveg_state_inst, dgvs_inst, & - cnveg_carbonstate_inst, cnveg_nitrogenstate_inst, cnveg_carbonflux_inst, cnveg_nitrogenflux_inst) - - call CNStressDecidPhenology(num_soilp, filter_soilp, & - soilstate_inst, temperature_inst, atm2lnd_inst, wateratm2lndbulk_inst, cnveg_state_inst, & - cnveg_carbonstate_inst, cnveg_nitrogenstate_inst, cnveg_carbonflux_inst, cnveg_nitrogenflux_inst) - - if (doalb .and. num_pcropp > 0 ) then - call CropPhenology(num_pcropp, filter_pcropp, & - waterdiagnosticbulk_inst, temperature_inst, crop_inst, canopystate_inst, cnveg_state_inst, & - cnveg_carbonstate_inst, cnveg_nitrogenstate_inst, cnveg_carbonflux_inst, cnveg_nitrogenflux_inst, & - c13_cnveg_carbonstate_inst, c14_cnveg_carbonstate_inst) - end if - else if ( phase == 2 ) then - ! the same onset and offset routines are called regardless of - ! phenology type - they depend only on onset_flag, offset_flag, bglfr, and bgtr - - call CNOnsetGrowth(num_soilp, filter_soilp, & - cnveg_state_inst, & - cnveg_carbonstate_inst, cnveg_nitrogenstate_inst, cnveg_carbonflux_inst, cnveg_nitrogenflux_inst) - - call CNOffsetLitterfall(num_soilp, filter_soilp, & - cnveg_state_inst, cnveg_carbonstate_inst, cnveg_nitrogenstate_inst, cnveg_carbonflux_inst, cnveg_nitrogenflux_inst) - - call CNBackgroundLitterfall(num_soilp, filter_soilp, & - cnveg_state_inst, cnveg_carbonstate_inst, cnveg_nitrogenstate_inst, cnveg_carbonflux_inst, cnveg_nitrogenflux_inst) - - call CNLivewoodTurnover(num_soilp, filter_soilp, & - cnveg_carbonstate_inst, cnveg_nitrogenstate_inst, cnveg_carbonflux_inst, cnveg_nitrogenflux_inst) - - call CNGrainToProductPools(bounds, num_soilp, filter_soilp, num_soilc, filter_soilc, & - cnveg_carbonflux_inst, cnveg_nitrogenflux_inst) - - ! gather all patch-level litterfall fluxes to the column for litter C and N inputs - - call CNLitterToColumn(bounds, num_soilc, filter_soilc, & - cnveg_state_inst, cnveg_carbonflux_inst, cnveg_nitrogenflux_inst, & - leaf_prof_patch(bounds%begp:bounds%endp,1:nlevdecomp_full), & - froot_prof_patch(bounds%begp:bounds%endp,1:nlevdecomp_full)) - else - call endrun( 'bad phase' ) - end if - - end subroutine CNPhenology - - !----------------------------------------------------------------------- - subroutine CNPhenologyInit(bounds) - ! - ! !DESCRIPTION: - ! Initialization of CNPhenology. Must be called after time-manager is - ! initialized, and after pftcon file is read in. - ! - ! !USES: - use clm_time_manager, only: get_step_size_real - use clm_varctl , only: use_crop - use clm_varcon , only: secspday - ! - ! !ARGUMENTS: - type(bounds_type), intent(in) :: bounds - !------------------------------------------------------------------------ - - ! - ! Get time-step and what fraction of a day it is - ! - dt = get_step_size_real() - fracday = dt/secspday - - ! set constants for CNSeasonDecidPhenology - ! (critical daylength from Biome-BGC, v4.1.2) - crit_dayl=params_inst%crit_dayl - - ! Set constants for CNSeasonDecidPhenology and CNStressDecidPhenology - ndays_on=params_inst%ndays_on - ndays_off=params_inst%ndays_off - - ! set transfer parameters - fstor2tran=params_inst%fstor2tran - - ! ----------------------------------------- - ! Constants for CNStressDecidPhenology - ! ----------------------------------------- - - ! onset parameters - crit_onset_fdd=params_inst%crit_onset_fdd - ! critical onset gdd now being calculated as a function of annual - ! average 2m temp. - ! crit_onset_gdd = 150.0 ! c3 grass value - ! crit_onset_gdd = 1000.0 ! c4 grass value - crit_onset_swi=params_inst%crit_onset_swi - soilpsi_on=params_inst%soilpsi_on - - ! offset parameters - crit_offset_fdd=params_inst%crit_offset_fdd - crit_offset_swi=params_inst%crit_offset_swi - soilpsi_off=params_inst%soilpsi_off - - ! ----------------------------------------- - ! Constants for CNLivewoodTurnover - ! ----------------------------------------- - - ! set the global parameter for livewood turnover rate - ! define as an annual fraction (0.7), and convert to fraction per second - lwtop=params_inst%lwtop/31536000.0_r8 !annual fraction converted to per second - - ! ----------------------------------------- - ! Call any subroutine specific initialization routines - ! ----------------------------------------- - - if ( use_crop ) call CropPhenologyInit(bounds) - - end subroutine CNPhenologyInit - - !----------------------------------------------------------------------- - subroutine CNPhenologyClimate (num_soilp, filter_soilp, num_pcropp, filter_pcropp, & - temperature_inst, cnveg_state_inst, crop_inst) - ! - ! !DESCRIPTION: - ! For coupled carbon-nitrogen code (CN). - ! - ! !USES: - use clm_time_manager , only : get_days_per_year - use clm_time_manager , only : get_curr_date, is_first_step - ! - ! !ARGUMENTS: - integer , intent(in) :: num_soilp ! number of soil patches in filter - integer , intent(in) :: filter_soilp(:) ! filter for soil patches - integer , intent(in) :: num_pcropp ! number of prognostic crops in filter - integer , intent(in) :: filter_pcropp(:)! filter for prognostic crop patches - type(temperature_type) , intent(inout) :: temperature_inst - type(cnveg_state_type) , intent(inout) :: cnveg_state_inst - type(crop_type) , intent(inout) :: crop_inst - ! - ! !LOCAL VARIABLES: - integer :: p ! indices - integer :: fp ! lake filter patch index - real(r8) :: dayspyr ! days per year (days) - integer :: kyr ! current year - integer :: kmo ! month of year (1, ..., 12) - integer :: kda ! day of month (1, ..., 31) - integer :: mcsec ! seconds of day (0, ..., seconds/day) - real(r8), parameter :: yravg = 20.0_r8 ! length of years to average for gdd - real(r8), parameter :: yravgm1 = yravg-1.0_r8 ! minus 1 of above - !----------------------------------------------------------------------- - - associate( & - nyrs_crop_active => crop_inst%nyrs_crop_active_patch, & ! InOut: [integer (:) ] number of years this crop patch has been active - - t_ref2m => temperature_inst%t_ref2m_patch , & ! Input: [real(r8) (:) ] 2m air temperature (K) - gdd0 => temperature_inst%gdd0_patch , & ! Output: [real(r8) (:) ] growing deg. days base 0 deg C (ddays) - gdd8 => temperature_inst%gdd8_patch , & ! Output: [real(r8) (:) ] " " " " 8 " " " - gdd10 => temperature_inst%gdd10_patch , & ! Output: [real(r8) (:) ] " " " " 10 " " " - gdd020 => temperature_inst%gdd020_patch , & ! Output: [real(r8) (:) ] 20-yr mean of gdd0 (ddays) - gdd820 => temperature_inst%gdd820_patch , & ! Output: [real(r8) (:) ] 20-yr mean of gdd8 (ddays) - gdd1020 => temperature_inst%gdd1020_patch , & ! Output: [real(r8) (:) ] 20-yr mean of gdd10 (ddays) - - tempavg_t2m => cnveg_state_inst%tempavg_t2m_patch & ! Output: [real(r8) (:) ] temp. avg 2m air temperature (K) - ) - - ! set time steps - - dayspyr = get_days_per_year() - - do fp = 1,num_soilp - p = filter_soilp(fp) - tempavg_t2m(p) = tempavg_t2m(p) + t_ref2m(p) * (fracday/dayspyr) - end do - - ! - ! The following crop related steps are done here rather than CropPhenology - ! so that they will be completed each time-step rather than with doalb. - ! - ! The following lines come from ibis's climate.f + stats.f - ! gdd SUMMATIONS ARE RELATIVE TO THE PLANTING DATE (see subr. updateAccFlds) - - if (num_pcropp > 0) then - ! get time-related info - call get_curr_date(kyr, kmo, kda, mcsec) - end if - - do fp = 1,num_pcropp - p = filter_pcropp(fp) - if (kmo == 1 .and. kda == 1 .and. nyrs_crop_active(p) == 0) then ! YR 1: - gdd020(p) = 0._r8 ! set gdd..20 variables to 0 - gdd820(p) = 0._r8 ! and crops will not be planted - gdd1020(p) = 0._r8 - end if - if (kmo == 1 .and. kda == 1 .and. mcsec == 0) then ! <-- END of EVERY YR: - if (nyrs_crop_active(p) == 1) then ! <-- END of YR 1 - gdd020(p) = gdd0(p) ! <-- END of YR 1 - gdd820(p) = gdd8(p) ! <-- END of YR 1 - gdd1020(p) = gdd10(p) ! <-- END of YR 1 - end if ! <-- END of YR 1 - gdd020(p) = (yravgm1* gdd020(p) + gdd0(p)) / yravg ! gdd..20 must be long term avgs - gdd820(p) = (yravgm1* gdd820(p) + gdd8(p)) / yravg ! so ignore results for yrs 1 & 2 - gdd1020(p) = (yravgm1* gdd1020(p) + gdd10(p)) / yravg - end if - end do - - end associate - - end subroutine CNPhenologyClimate - - !----------------------------------------------------------------------- - subroutine CNEvergreenPhenology (num_soilp, filter_soilp , & - cnveg_state_inst, cnveg_carbonstate_inst, cnveg_nitrogenstate_inst, cnveg_carbonflux_inst, cnveg_nitrogenflux_inst) - ! cnveg_state_inst) - ! - ! !DESCRIPTION: - ! For coupled carbon-nitrogen code (CN). - ! - ! !USES: - use clm_varcon , only : secspday - use clm_time_manager , only : get_days_per_year - use clm_varctl , only : CN_evergreen_phenology_opt - ! - ! !ARGUMENTS: - integer , intent(in) :: num_soilp ! number of soil patches in filter - integer , intent(in) :: filter_soilp(:) ! filter for soil patches - type(cnveg_state_type), intent(inout) :: cnveg_state_inst - type(cnveg_carbonstate_type) , intent(inout) :: cnveg_carbonstate_inst - type(cnveg_nitrogenstate_type) , intent(inout) :: cnveg_nitrogenstate_inst - type(cnveg_carbonflux_type) , intent(inout) :: cnveg_carbonflux_inst - type(cnveg_nitrogenflux_type) , intent(inout) :: cnveg_nitrogenflux_inst - ! - ! !LOCAL VARIABLES: - real(r8):: dayspyr ! Days per year - integer :: p ! indices - integer :: fp ! lake filter patch index - - real(r8):: tranr - real(r8):: t1 ! temporary variable - !----------------------------------------------------------------------- - - associate( & - ivt => patch%itype , & ! Input: [integer (:) ] patch vegetation type - - evergreen => pftcon%evergreen , & ! Input: binary flag for evergreen leaf habit (0 or 1) - leaf_long => pftcon%leaf_long , & ! Input: leaf longevity (yrs) - - woody => pftcon%woody , & ! Input: binary flag for woody lifeform (1=woody, 0=not woody) - - 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 , & ! InOut: [real(r8) (:)] (gC/m2) leaf C transfer - frootc_xfer => cnveg_carbonstate_inst%frootc_xfer_patch , & ! InOut: [real(r8) (:)] (gC/m2) fine root C transfer - livestemc_xfer => cnveg_carbonstate_inst%livestemc_xfer_patch , & ! InOut: [real(r8) (:)] (gC/m2) live stem C transfer - deadstemc_xfer => cnveg_carbonstate_inst%deadstemc_xfer_patch , & ! InOut: [real(r8) (:)] (gC/m2) dead stem C transfer - livecrootc_xfer => cnveg_carbonstate_inst%livecrootc_xfer_patch , & ! InOut: [real(r8) (:)] (gC/m2) live coarse root C transfer - deadcrootc_xfer => cnveg_carbonstate_inst%deadcrootc_xfer_patch , & ! InOut: [real(r8) (:)] (gC/m2) dead coarse root C transfer - - 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 , & ! InOut: [real(r8) (:)] (gN/m2) leaf N transfer - frootn_xfer => cnveg_nitrogenstate_inst%frootn_xfer_patch , & ! InOut: [real(r8) (:)] (gN/m2) fine root N transfer - livestemn_xfer => cnveg_nitrogenstate_inst%livestemn_xfer_patch , & ! InOut: [real(r8) (:)] (gN/m2) live stem N transfer - deadstemn_xfer => cnveg_nitrogenstate_inst%deadstemn_xfer_patch , & ! InOut: [real(r8) (:)] (gN/m2) dead stem N transfer - livecrootn_xfer => cnveg_nitrogenstate_inst%livecrootn_xfer_patch , & ! InOut: [real(r8) (:)] (gN/m2) live coarse root N transfer - deadcrootn_xfer => cnveg_nitrogenstate_inst%deadcrootn_xfer_patch , & ! InOut: [real(r8) (:)] (gN/m2) dead coarse root N transfer - - leafc_storage_to_xfer => cnveg_carbonflux_inst%leafc_storage_to_xfer_patch , & ! InOut: [real(r8) (:)] - frootc_storage_to_xfer => cnveg_carbonflux_inst%frootc_storage_to_xfer_patch , & ! InOut: [real(r8) (:)] - livestemc_storage_to_xfer => cnveg_carbonflux_inst%livestemc_storage_to_xfer_patch , & ! InOut: [real(r8) (:)] - deadstemc_storage_to_xfer => cnveg_carbonflux_inst%deadstemc_storage_to_xfer_patch , & ! InOut: [real(r8) (:)] - livecrootc_storage_to_xfer => cnveg_carbonflux_inst%livecrootc_storage_to_xfer_patch , & ! InOut: [real(r8) (:)] - deadcrootc_storage_to_xfer => cnveg_carbonflux_inst%deadcrootc_storage_to_xfer_patch , & ! InOut: [real(r8) (:)] - gresp_storage_to_xfer => cnveg_carbonflux_inst%gresp_storage_to_xfer_patch , & ! InOut: [real(r8) (:)] - leafc_xfer_to_leafc => cnveg_carbonflux_inst%leafc_xfer_to_leafc_patch , & ! InOut: [real(r8) (:)] - frootc_xfer_to_frootc => cnveg_carbonflux_inst%frootc_xfer_to_frootc_patch , & ! InOut: [real(r8) (:)] - livestemc_xfer_to_livestemc => cnveg_carbonflux_inst%livestemc_xfer_to_livestemc_patch , & ! InOut: [real(r8) (:)] - deadstemc_xfer_to_deadstemc => cnveg_carbonflux_inst%deadstemc_xfer_to_deadstemc_patch , & ! InOut: [real(r8) (:)] - livecrootc_xfer_to_livecrootc => cnveg_carbonflux_inst%livecrootc_xfer_to_livecrootc_patch , & ! InOut: [real(r8) (:)] - deadcrootc_xfer_to_deadcrootc => cnveg_carbonflux_inst%deadcrootc_xfer_to_deadcrootc_patch , & ! InOut: [real(r8) (:)] - - leafn_storage_to_xfer => cnveg_nitrogenflux_inst%leafn_storage_to_xfer_patch , & ! InOut: [real(r8) (:)] - frootn_storage_to_xfer => cnveg_nitrogenflux_inst%frootn_storage_to_xfer_patch , & ! InOut: [real(r8) (:)] - livestemn_storage_to_xfer => cnveg_nitrogenflux_inst%livestemn_storage_to_xfer_patch , & ! InOut: [real(r8) (:)] - deadstemn_storage_to_xfer => cnveg_nitrogenflux_inst%deadstemn_storage_to_xfer_patch , & ! InOut: [real(r8) (:)] - livecrootn_storage_to_xfer => cnveg_nitrogenflux_inst%livecrootn_storage_to_xfer_patch , & ! InOut: [real(r8) (:)] - deadcrootn_storage_to_xfer => cnveg_nitrogenflux_inst%deadcrootn_storage_to_xfer_patch , & ! InOut: [real(r8) (:)] - leafn_xfer_to_leafn => cnveg_nitrogenflux_inst%leafn_xfer_to_leafn_patch , & ! InOut: [real(r8) (:)] - frootn_xfer_to_frootn => cnveg_nitrogenflux_inst%frootn_xfer_to_frootn_patch , & ! InOut: [real(r8) (:)] - livestemn_xfer_to_livestemn => cnveg_nitrogenflux_inst%livestemn_xfer_to_livestemn_patch , & ! InOut: [real(r8) (:)] - deadstemn_xfer_to_deadstemn => cnveg_nitrogenflux_inst%deadstemn_xfer_to_deadstemn_patch , & ! InOut: [real(r8) (:)] - livecrootn_xfer_to_livecrootn => cnveg_nitrogenflux_inst%livecrootn_xfer_to_livecrootn_patch , & ! InOut: [real(r8) (:)] - deadcrootn_xfer_to_deadcrootn => cnveg_nitrogenflux_inst%deadcrootn_xfer_to_deadcrootn_patch , & ! InOut: [real(r8) (:)] - - bglfr => cnveg_state_inst%bglfr_patch , & ! Output: [real(r8) (:) ] background litterfall rate (1/s) - bgtr => cnveg_state_inst%bgtr_patch , & ! Output: [real(r8) (:) ] background transfer growth rate (1/s) - lgsf => cnveg_state_inst%lgsf_patch & ! Output: [real(r8) (:) ] long growing season factor [0-1] - ) - - dayspyr = get_days_per_year() - - do fp = 1,num_soilp - p = filter_soilp(fp) - if (evergreen(ivt(p)) == 1._r8) then - bglfr(p) = 1._r8/(leaf_long(ivt(p)) * dayspyr * secspday) - bgtr(p) = 0._r8 - lgsf(p) = 0._r8 - end if - end do - - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - if (CN_evergreen_phenology_opt == 1) then - do fp = 1,num_soilp - p = filter_soilp(fp) - if (evergreen(ivt(p)) == 1._r8) then - - tranr=0.0002_r8 - ! set carbon fluxes for shifting storage pools to transfer pools - leafc_storage_to_xfer(p) = tranr * leafc_storage(p)/dt - frootc_storage_to_xfer(p) = tranr * frootc_storage(p)/dt - if (woody(ivt(p)) == 1.0_r8) then - livestemc_storage_to_xfer(p) = tranr * livestemc_storage(p)/dt - deadstemc_storage_to_xfer(p) = tranr * deadstemc_storage(p)/dt - livecrootc_storage_to_xfer(p) = tranr * livecrootc_storage(p)/dt - deadcrootc_storage_to_xfer(p) = tranr * deadcrootc_storage(p)/dt - gresp_storage_to_xfer(p) = tranr * gresp_storage(p)/dt - end if - - ! set nitrogen fluxes for shifting storage pools to transfer pools - leafn_storage_to_xfer(p) = tranr * leafn_storage(p)/dt - frootn_storage_to_xfer(p) = tranr * frootn_storage(p)/dt - if (woody(ivt(p)) == 1.0_r8) then - livestemn_storage_to_xfer(p) = tranr * livestemn_storage(p)/dt - deadstemn_storage_to_xfer(p) = tranr * deadstemn_storage(p)/dt - livecrootn_storage_to_xfer(p) = tranr * livecrootn_storage(p)/dt - deadcrootn_storage_to_xfer(p) = tranr * deadcrootn_storage(p)/dt - end if - - t1 = 1.0_r8 / dt - - leafc_xfer_to_leafc(p) = t1 * leafc_xfer(p) - frootc_xfer_to_frootc(p) = t1 * frootc_xfer(p) - - leafn_xfer_to_leafn(p) = t1 * leafn_xfer(p) - frootn_xfer_to_frootn(p) = t1 * frootn_xfer(p) - if (woody(ivt(p)) == 1.0_r8) then - livestemc_xfer_to_livestemc(p) = t1 * livestemc_xfer(p) - deadstemc_xfer_to_deadstemc(p) = t1 * deadstemc_xfer(p) - livecrootc_xfer_to_livecrootc(p) = t1 * livecrootc_xfer(p) - deadcrootc_xfer_to_deadcrootc(p) = t1 * deadcrootc_xfer(p) - - livestemn_xfer_to_livestemn(p) = t1 * livestemn_xfer(p) - deadstemn_xfer_to_deadstemn(p) = t1 * deadstemn_xfer(p) - livecrootn_xfer_to_livecrootn(p) = t1 * livecrootn_xfer(p) - deadcrootn_xfer_to_deadcrootn(p) = t1 * deadcrootn_xfer(p) - end if - - end if ! end of if (evergreen(ivt(p)) == 1._r8) then - - end do ! end of pft loop - - end if ! end of if (CN_evergreen_phenology_opt == 1) then - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - end associate - - end subroutine CNEvergreenPhenology - - !----------------------------------------------------------------------- - subroutine CNSeasonDecidPhenology (num_soilp, filter_soilp , & - temperature_inst, cnveg_state_inst, dgvs_inst , & - cnveg_carbonstate_inst, cnveg_nitrogenstate_inst, cnveg_carbonflux_inst, cnveg_nitrogenflux_inst) - ! - ! !DESCRIPTION: - ! For coupled carbon-nitrogen code (CN). - ! This routine handles the seasonal deciduous phenology code (temperate - ! deciduous vegetation that has only one growing season per year). - ! - ! !USES: - use shr_const_mod , only: SHR_CONST_TKFRZ, SHR_CONST_PI - use clm_varcon , only: secspday - use clm_varctl , only: use_cndv - ! - ! !ARGUMENTS: - integer , intent(in) :: num_soilp ! number of soil patches in filter - integer , intent(in) :: filter_soilp(:) ! filter for soil patches - type(temperature_type) , intent(in) :: temperature_inst - type(cnveg_state_type) , intent(inout) :: cnveg_state_inst - type(dgvs_type) , intent(inout) :: dgvs_inst - type(cnveg_carbonstate_type) , intent(inout) :: cnveg_carbonstate_inst - type(cnveg_nitrogenstate_type) , intent(inout) :: cnveg_nitrogenstate_inst - type(cnveg_carbonflux_type) , intent(inout) :: cnveg_carbonflux_inst - type(cnveg_nitrogenflux_type) , intent(inout) :: cnveg_nitrogenflux_inst - ! - ! !LOCAL VARIABLES: - integer :: g,c,p !indices - integer :: fp !lake filter patch index - real(r8):: ws_flag !winter-summer solstice flag (0 or 1) - real(r8):: crit_onset_gdd !critical onset growing degree-day sum - real(r8):: soilt - !----------------------------------------------------------------------- - - associate( & - ivt => patch%itype , & ! Input: [integer (:) ] patch vegetation type - dayl => grc%dayl , & ! Input: [real(r8) (:) ] daylength (s) - prev_dayl => grc%prev_dayl , & ! Input: [real(r8) (:) ] daylength from previous time step (s) - - woody => pftcon%woody , & ! Input: binary flag for woody lifeform (1=woody, 0=not woody) - season_decid => pftcon%season_decid , & ! Input: binary flag for seasonal-deciduous leaf habit (0 or 1) - - t_soisno => temperature_inst%t_soisno_col , & ! Input: [real(r8) (:,:) ] soil temperature (Kelvin) (-nlevsno+1:nlevgrnd) - - pftmayexist => dgvs_inst%pftmayexist_patch , & ! Output: [logical (:) ] exclude seasonal decid patches from tropics - - annavg_t2m => cnveg_state_inst%annavg_t2m_patch , & ! Input: [real(r8) (:) ] annual average 2m air temperature (K) - dormant_flag => cnveg_state_inst%dormant_flag_patch , & ! Output: [real(r8) (:) ] dormancy flag - days_active => cnveg_state_inst%days_active_patch , & ! Output: [real(r8) (:) ] number of days since last dormancy - onset_flag => cnveg_state_inst%onset_flag_patch , & ! Output: [real(r8) (:) ] onset flag - onset_counter => cnveg_state_inst%onset_counter_patch , & ! Output: [real(r8) (:) ] onset counter (seconds) - onset_gddflag => cnveg_state_inst%onset_gddflag_patch , & ! Output: [real(r8) (:) ] onset freeze flag - onset_gdd => cnveg_state_inst%onset_gdd_patch , & ! Output: [real(r8) (:) ] onset growing degree days - offset_flag => cnveg_state_inst%offset_flag_patch , & ! Output: [real(r8) (:) ] offset flag - offset_counter => cnveg_state_inst%offset_counter_patch , & ! Output: [real(r8) (:) ] offset counter (seconds) - bglfr => cnveg_state_inst%bglfr_patch , & ! Output: [real(r8) (:) ] background litterfall rate (1/s) - bgtr => cnveg_state_inst%bgtr_patch , & ! Output: [real(r8) (:) ] background transfer growth rate (1/s) - lgsf => cnveg_state_inst%lgsf_patch , & ! Output: [real(r8) (:) ] long growing season factor [0-1] - - 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 , & ! Output: [real(r8) (:) ] (gC/m2) leaf C transfer - frootc_xfer => cnveg_carbonstate_inst%frootc_xfer_patch , & ! Output: [real(r8) (:) ] (gC/m2) fine root C transfer - livestemc_xfer => cnveg_carbonstate_inst%livestemc_xfer_patch , & ! Output: [real(r8) (:) ] (gC/m2) live stem C transfer - deadstemc_xfer => cnveg_carbonstate_inst%deadstemc_xfer_patch , & ! Output: [real(r8) (:) ] (gC/m2) dead stem C transfer - livecrootc_xfer => cnveg_carbonstate_inst%livecrootc_xfer_patch , & ! Output: [real(r8) (:) ] (gC/m2) live coarse root C transfer - deadcrootc_xfer => cnveg_carbonstate_inst%deadcrootc_xfer_patch , & ! Output: [real(r8) (:) ] (gC/m2) dead coarse root C transfer - - 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 , & ! Output: [real(r8) (:) ] (gN/m2) leaf N transfer - frootn_xfer => cnveg_nitrogenstate_inst%frootn_xfer_patch , & ! Output: [real(r8) (:) ] (gN/m2) fine root N transfer - livestemn_xfer => cnveg_nitrogenstate_inst%livestemn_xfer_patch , & ! Output: [real(r8) (:) ] (gN/m2) live stem N transfer - deadstemn_xfer => cnveg_nitrogenstate_inst%deadstemn_xfer_patch , & ! Output: [real(r8) (:) ] (gN/m2) dead stem N transfer - livecrootn_xfer => cnveg_nitrogenstate_inst%livecrootn_xfer_patch , & ! Output: [real(r8) (:) ] (gN/m2) live coarse root N transfer - deadcrootn_xfer => cnveg_nitrogenstate_inst%deadcrootn_xfer_patch , & ! Output: [real(r8) (:) ] (gN/m2) dead coarse root N transfer - - prev_leafc_to_litter => cnveg_carbonflux_inst%prev_leafc_to_litter_patch , & ! Output: [real(r8) (:) ] previous timestep leaf C litterfall flux (gC/m2/s) - prev_frootc_to_litter => cnveg_carbonflux_inst%prev_frootc_to_litter_patch , & ! Output: [real(r8) (:) ] previous timestep froot C litterfall flux (gC/m2/s) - leafc_xfer_to_leafc => cnveg_carbonflux_inst%leafc_xfer_to_leafc_patch , & ! Output: [real(r8) (:) ] - frootc_xfer_to_frootc => cnveg_carbonflux_inst%frootc_xfer_to_frootc_patch , & ! Output: [real(r8) (:) ] - livestemc_xfer_to_livestemc => cnveg_carbonflux_inst%livestemc_xfer_to_livestemc_patch , & ! Output: [real(r8) (:) ] - deadstemc_xfer_to_deadstemc => cnveg_carbonflux_inst%deadstemc_xfer_to_deadstemc_patch , & ! Output: [real(r8) (:) ] - livecrootc_xfer_to_livecrootc => cnveg_carbonflux_inst%livecrootc_xfer_to_livecrootc_patch , & ! Output: [real(r8) (:) ] - deadcrootc_xfer_to_deadcrootc => cnveg_carbonflux_inst%deadcrootc_xfer_to_deadcrootc_patch , & ! Output: [real(r8) (:) ] - leafc_storage_to_xfer => cnveg_carbonflux_inst%leafc_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] - frootc_storage_to_xfer => cnveg_carbonflux_inst%frootc_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] - livestemc_storage_to_xfer => cnveg_carbonflux_inst%livestemc_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] - deadstemc_storage_to_xfer => cnveg_carbonflux_inst%deadstemc_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] - livecrootc_storage_to_xfer => cnveg_carbonflux_inst%livecrootc_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] - deadcrootc_storage_to_xfer => cnveg_carbonflux_inst%deadcrootc_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] - gresp_storage_to_xfer => cnveg_carbonflux_inst%gresp_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] - - leafn_xfer_to_leafn => cnveg_nitrogenflux_inst%leafn_xfer_to_leafn_patch , & ! Output: [real(r8) (:) ] - frootn_xfer_to_frootn => cnveg_nitrogenflux_inst%frootn_xfer_to_frootn_patch , & ! Output: [real(r8) (:) ] - livestemn_xfer_to_livestemn => cnveg_nitrogenflux_inst%livestemn_xfer_to_livestemn_patch , & ! Output: [real(r8) (:) ] - deadstemn_xfer_to_deadstemn => cnveg_nitrogenflux_inst%deadstemn_xfer_to_deadstemn_patch , & ! Output: [real(r8) (:) ] - livecrootn_xfer_to_livecrootn => cnveg_nitrogenflux_inst%livecrootn_xfer_to_livecrootn_patch , & ! Output: [real(r8) (:) ] - deadcrootn_xfer_to_deadcrootn => cnveg_nitrogenflux_inst%deadcrootn_xfer_to_deadcrootn_patch , & ! Output: [real(r8) (:) ] - leafn_storage_to_xfer => cnveg_nitrogenflux_inst%leafn_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] - frootn_storage_to_xfer => cnveg_nitrogenflux_inst%frootn_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] - livestemn_storage_to_xfer => cnveg_nitrogenflux_inst%livestemn_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] - deadstemn_storage_to_xfer => cnveg_nitrogenflux_inst%deadstemn_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] - livecrootn_storage_to_xfer => cnveg_nitrogenflux_inst%livecrootn_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] - deadcrootn_storage_to_xfer => cnveg_nitrogenflux_inst%deadcrootn_storage_to_xfer_patch & ! Output: [real(r8) (:) ] - ) - - ! start patch loop - do fp = 1,num_soilp - p = filter_soilp(fp) - c = patch%column(p) - g = patch%gridcell(p) - - if (season_decid(ivt(p)) == 1._r8) then - - ! set background litterfall rate, background transfer rate, and - ! long growing season factor to 0 for seasonal deciduous types - bglfr(p) = 0._r8 - bgtr(p) = 0._r8 - lgsf(p) = 0._r8 - - ! onset gdd sum from Biome-BGC, v4.1.2 - crit_onset_gdd = exp(4.8_r8 + 0.13_r8*(annavg_t2m(p) - SHR_CONST_TKFRZ)) - - ! set flag for solstice period (winter->summer = 1, summer->winter = 0) - if (dayl(g) >= prev_dayl(g)) then - ws_flag = 1._r8 - else - ws_flag = 0._r8 - end if - - ! update offset_counter and test for the end of the offset period - if (offset_flag(p) == 1.0_r8) then - ! decrement counter for offset period - offset_counter(p) = offset_counter(p) - dt - - ! if this is the end of the offset_period, reset phenology - ! flags and indices - if (offset_counter(p) == 0.0_r8) then - ! this code block was originally handled by call cn_offset_cleanup(p) - ! inlined during vectorization - - offset_flag(p) = 0._r8 - offset_counter(p) = 0._r8 - dormant_flag(p) = 1._r8 - days_active(p) = 0._r8 - if (use_cndv) then - pftmayexist(p) = .true. - end if - - ! reset the previous timestep litterfall flux memory - prev_leafc_to_litter(p) = 0._r8 - prev_frootc_to_litter(p) = 0._r8 - end if - end if - - ! update onset_counter and test for the end of the onset period - if (onset_flag(p) == 1.0_r8) then - ! decrement counter for onset period - onset_counter(p) = onset_counter(p) - dt - - ! if this is the end of the onset period, reset phenology - ! flags and indices - if (onset_counter(p) == 0.0_r8) then - ! this code block was originally handled by call cn_onset_cleanup(p) - ! inlined during vectorization - - onset_flag(p) = 0.0_r8 - onset_counter(p) = 0.0_r8 - ! set all transfer growth rates to 0.0 - leafc_xfer_to_leafc(p) = 0.0_r8 - frootc_xfer_to_frootc(p) = 0.0_r8 - leafn_xfer_to_leafn(p) = 0.0_r8 - frootn_xfer_to_frootn(p) = 0.0_r8 - if (woody(ivt(p)) == 1.0_r8) then - livestemc_xfer_to_livestemc(p) = 0.0_r8 - deadstemc_xfer_to_deadstemc(p) = 0.0_r8 - livecrootc_xfer_to_livecrootc(p) = 0.0_r8 - deadcrootc_xfer_to_deadcrootc(p) = 0.0_r8 - livestemn_xfer_to_livestemn(p) = 0.0_r8 - deadstemn_xfer_to_deadstemn(p) = 0.0_r8 - livecrootn_xfer_to_livecrootn(p) = 0.0_r8 - deadcrootn_xfer_to_deadcrootn(p) = 0.0_r8 - end if - ! set transfer pools to 0.0 - leafc_xfer(p) = 0.0_r8 - leafn_xfer(p) = 0.0_r8 - frootc_xfer(p) = 0.0_r8 - frootn_xfer(p) = 0.0_r8 - if (woody(ivt(p)) == 1.0_r8) then - livestemc_xfer(p) = 0.0_r8 - livestemn_xfer(p) = 0.0_r8 - deadstemc_xfer(p) = 0.0_r8 - deadstemn_xfer(p) = 0.0_r8 - livecrootc_xfer(p) = 0.0_r8 - livecrootn_xfer(p) = 0.0_r8 - deadcrootc_xfer(p) = 0.0_r8 - deadcrootn_xfer(p) = 0.0_r8 - end if - end if - end if - - ! test for switching from dormant period to growth period - if (dormant_flag(p) == 1.0_r8) then - - ! Test to turn on growing degree-day sum, if off. - ! switch on the growing degree day sum on the winter solstice - - if (onset_gddflag(p) == 0._r8 .and. ws_flag == 1._r8) then - onset_gddflag(p) = 1._r8 - onset_gdd(p) = 0._r8 - end if - - ! Test to turn off growing degree-day sum, if on. - ! This test resets the growing degree day sum if it gets past - ! the summer solstice without reaching the threshold value. - ! In that case, it will take until the next winter solstice - ! before the growing degree-day summation starts again. - - if (onset_gddflag(p) == 1._r8 .and. ws_flag == 0._r8) then - onset_gddflag(p) = 0._r8 - onset_gdd(p) = 0._r8 - end if - - ! if the gdd flag is set, and if the soil is above freezing - ! then accumulate growing degree days for onset trigger - - soilt = t_soisno(c,3) - if (onset_gddflag(p) == 1.0_r8 .and. soilt > SHR_CONST_TKFRZ) then - onset_gdd(p) = onset_gdd(p) + (soilt-SHR_CONST_TKFRZ)*fracday - end if - - ! set onset_flag if critical growing degree-day sum is exceeded - if (onset_gdd(p) > crit_onset_gdd) then - onset_flag(p) = 1.0_r8 - dormant_flag(p) = 0.0_r8 - onset_gddflag(p) = 0.0_r8 - onset_gdd(p) = 0.0_r8 - onset_counter(p) = ndays_on * secspday - - ! move all the storage pools into transfer pools, - ! where they will be transfered to displayed growth over the onset period. - ! this code was originally handled with call cn_storage_to_xfer(p) - ! inlined during vectorization - - ! set carbon fluxes for shifting storage pools to transfer pools - leafc_storage_to_xfer(p) = fstor2tran * leafc_storage(p)/dt - frootc_storage_to_xfer(p) = fstor2tran * frootc_storage(p)/dt - if (woody(ivt(p)) == 1.0_r8) then - livestemc_storage_to_xfer(p) = fstor2tran * livestemc_storage(p)/dt - deadstemc_storage_to_xfer(p) = fstor2tran * deadstemc_storage(p)/dt - livecrootc_storage_to_xfer(p) = fstor2tran * livecrootc_storage(p)/dt - deadcrootc_storage_to_xfer(p) = fstor2tran * deadcrootc_storage(p)/dt - gresp_storage_to_xfer(p) = fstor2tran * gresp_storage(p)/dt - end if - - ! set nitrogen fluxes for shifting storage pools to transfer pools - leafn_storage_to_xfer(p) = fstor2tran * leafn_storage(p)/dt - frootn_storage_to_xfer(p) = fstor2tran * frootn_storage(p)/dt - if (woody(ivt(p)) == 1.0_r8) then - livestemn_storage_to_xfer(p) = fstor2tran * livestemn_storage(p)/dt - deadstemn_storage_to_xfer(p) = fstor2tran * deadstemn_storage(p)/dt - livecrootn_storage_to_xfer(p) = fstor2tran * livecrootn_storage(p)/dt - deadcrootn_storage_to_xfer(p) = fstor2tran * deadcrootn_storage(p)/dt - end if - end if - - ! test for switching from growth period to offset period - else if (offset_flag(p) == 0.0_r8) then - if (use_cndv) then - ! If days_active > 355, then remove patch in - ! CNDVEstablishment at the end of the year. - ! days_active > 355 is a symptom of seasonal decid. patches occurring in - ! gridcells where dayl never drops below crit_dayl. - ! This results in TLAI>1e4 in a few gridcells. - days_active(p) = days_active(p) + fracday - if (days_active(p) > 355._r8) pftmayexist(p) = .false. - end if - - ! only begin to test for offset daylength once past the summer sol - if (ws_flag == 0._r8 .and. dayl(g) < crit_dayl) then - offset_flag(p) = 1._r8 - offset_counter(p) = ndays_off * secspday - prev_leafc_to_litter(p) = 0._r8 - prev_frootc_to_litter(p) = 0._r8 - end if - end if - - end if ! end if seasonal deciduous - - end do ! end of patch loop - - end associate - - end subroutine CNSeasonDecidPhenology - - !----------------------------------------------------------------------- - subroutine CNStressDecidPhenology (num_soilp, filter_soilp , & - soilstate_inst, temperature_inst, atm2lnd_inst, wateratm2lndbulk_inst, cnveg_state_inst, & - cnveg_carbonstate_inst, cnveg_nitrogenstate_inst, & - cnveg_carbonflux_inst, cnveg_nitrogenflux_inst) - ! - ! !DESCRIPTION: - ! This routine handles phenology for vegetation types, such as grasses and - ! tropical drought deciduous trees, that respond to cold and drought stress - ! signals and that can have multiple growing seasons in a given year. - ! This routine allows for the possibility that leaves might persist year-round - ! in the absence of a suitable stress trigger, by switching to an essentially - ! evergreen habit, but maintaining a deciduous leaf longevity, while waiting - ! for the next stress trigger. This is in contrast to the seasonal deciduous - ! algorithm (for temperate deciduous trees) that forces a single growing season - ! per year. - ! - ! !USES: - use clm_time_manager , only : get_days_per_year - use CNSharedParamsMod, only : use_fun - use clm_varcon , only : secspday - use shr_const_mod , only : SHR_CONST_TKFRZ, SHR_CONST_PI - use CNSharedParamsMod, only : CNParamsShareInst - ! - ! !ARGUMENTS: - integer , intent(in) :: num_soilp ! number of soil patches in filter - integer , intent(in) :: filter_soilp(:) ! filter for soil patches - type(soilstate_type) , intent(in) :: soilstate_inst - type(temperature_type) , intent(in) :: temperature_inst - type(atm2lnd_type) , intent(in) :: atm2lnd_inst - type(wateratm2lndbulk_type) , intent(in) :: wateratm2lndbulk_inst - type(cnveg_state_type) , intent(inout) :: cnveg_state_inst - type(cnveg_carbonstate_type) , intent(inout) :: cnveg_carbonstate_inst - type(cnveg_nitrogenstate_type) , intent(inout) :: cnveg_nitrogenstate_inst - type(cnveg_carbonflux_type) , intent(inout) :: cnveg_carbonflux_inst - type(cnveg_nitrogenflux_type) , intent(inout) :: cnveg_nitrogenflux_inst - ! - ! !LOCAL VARIABLES: - real(r8),parameter :: secspqtrday = secspday / 4 ! seconds per quarter day - integer :: g,c,p ! indices - integer :: fp ! lake filter patch index - real(r8):: dayspyr ! days per year - real(r8):: crit_onset_gdd ! degree days for onset trigger - real(r8):: soilt ! temperature of top soil layer - real(r8):: psi ! water stress of top soil layer - real(r8):: rain_threshold ! rain threshold for leaf on [mm] - logical :: additional_onset_condition ! additional condition for leaf onset - !----------------------------------------------------------------------- - - associate( & - ivt => patch%itype , & ! Input: [integer (:) ] patch vegetation type - dayl => grc%dayl , & ! Input: [real(r8) (:) ] daylength (s) - - prec10 => wateratm2lndbulk_inst%prec10_patch , & ! Input: [real(r8) (:) ] 10-day running mean of tot. precipitation - leaf_long => pftcon%leaf_long , & ! Input: leaf longevity (yrs) - woody => pftcon%woody , & ! Input: binary flag for woody lifeform (1=woody, 0=not woody) - stress_decid => pftcon%stress_decid , & ! Input: binary flag for stress-deciduous leaf habit (0 or 1) - - soilpsi => soilstate_inst%soilpsi_col , & ! Input: [real(r8) (:,:) ] soil water potential in each soil layer (MPa) - - t_soisno => temperature_inst%t_soisno_col , & ! Input: [real(r8) (:,:) ] soil temperature (Kelvin) (-nlevsno+1:nlevgrnd) - dormant_flag => cnveg_state_inst%dormant_flag_patch , & ! Output: [real(r8) (:) ] dormancy flag - days_active => cnveg_state_inst%days_active_patch , & ! Output: [real(r8) (:) ] number of days since last dormancy - onset_flag => cnveg_state_inst%onset_flag_patch , & ! Output: [real(r8) (:) ] onset flag - onset_counter => cnveg_state_inst%onset_counter_patch , & ! Output: [real(r8) (:) ] onset counter (seconds) - onset_gddflag => cnveg_state_inst%onset_gddflag_patch , & ! Output: [real(r8) (:) ] onset freeze flag - onset_fdd => cnveg_state_inst%onset_fdd_patch , & ! Output: [real(r8) (:) ] onset freezing degree days counter - onset_gdd => cnveg_state_inst%onset_gdd_patch , & ! Output: [real(r8) (:) ] onset growing degree days - onset_swi => cnveg_state_inst%onset_swi_patch , & ! Output: [real(r8) (:) ] onset soil water index - offset_flag => cnveg_state_inst%offset_flag_patch , & ! Output: [real(r8) (:) ] offset flag - offset_counter => cnveg_state_inst%offset_counter_patch , & ! Output: [real(r8) (:) ] offset counter (seconds) - offset_fdd => cnveg_state_inst%offset_fdd_patch , & ! Output: [real(r8) (:) ] offset freezing degree days counter - offset_swi => cnveg_state_inst%offset_swi_patch , & ! Output: [real(r8) (:) ] offset soil water index - lgsf => cnveg_state_inst%lgsf_patch , & ! Output: [real(r8) (:) ] long growing season factor [0-1] - bglfr => cnveg_state_inst%bglfr_patch , & ! Output: [real(r8) (:) ] background litterfall rate (1/s) - bgtr => cnveg_state_inst%bgtr_patch , & ! Output: [real(r8) (:) ] background transfer growth rate (1/s) - annavg_t2m => cnveg_state_inst%annavg_t2m_patch , & ! Output: [real(r8) (:) ] annual average 2m air temperature (K) - 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 - 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 , & ! Output: [real(r8) (:) ] (gC/m2) leaf C transfer - frootc_xfer => cnveg_carbonstate_inst%frootc_xfer_patch , & ! Output: [real(r8) (:) ] (gC/m2) fine root C transfer - livestemc_xfer => cnveg_carbonstate_inst%livestemc_xfer_patch , & ! Output: [real(r8) (:) ] (gC/m2) live stem C transfer - deadstemc_xfer => cnveg_carbonstate_inst%deadstemc_xfer_patch , & ! Output: [real(r8) (:) ] (gC/m2) dead stem C transfer - livecrootc_xfer => cnveg_carbonstate_inst%livecrootc_xfer_patch , & ! Output: [real(r8) (:) ] (gC/m2) live coarse root C transfer - deadcrootc_xfer => cnveg_carbonstate_inst%deadcrootc_xfer_patch , & ! Output: [real(r8) (:) ] (gC/m2) dead coarse root C transfer - 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 , & ! Output: [real(r8) (:) ] (gN/m2) leaf N transfer - frootn_xfer => cnveg_nitrogenstate_inst%frootn_xfer_patch , & ! Output: [real(r8) (:) ] (gN/m2) fine root N transfer - livestemn_xfer => cnveg_nitrogenstate_inst%livestemn_xfer_patch , & ! Output: [real(r8) (:) ] (gN/m2) live stem N transfer - deadstemn_xfer => cnveg_nitrogenstate_inst%deadstemn_xfer_patch , & ! Output: [real(r8) (:) ] (gN/m2) dead stem N transfer - livecrootn_xfer => cnveg_nitrogenstate_inst%livecrootn_xfer_patch , & ! Output: [real(r8) (:) ] (gN/m2) live coarse root N transfer - deadcrootn_xfer => cnveg_nitrogenstate_inst%deadcrootn_xfer_patch , & ! Output: [real(r8) (:) ] (gN/m2) dead coarse root N transfer - - prev_leafc_to_litter => cnveg_carbonflux_inst%prev_leafc_to_litter_patch , & ! Output: [real(r8) (:) ] previous timestep leaf C litterfall flux (gC/m2/s) - prev_frootc_to_litter => cnveg_carbonflux_inst%prev_frootc_to_litter_patch , & ! Output: [real(r8) (:) ] previous timestep froot C litterfall flux (gC/m2/s) - leafc_xfer_to_leafc => cnveg_carbonflux_inst%leafc_xfer_to_leafc_patch , & ! Output: [real(r8) (:) ] - frootc_xfer_to_frootc => cnveg_carbonflux_inst%frootc_xfer_to_frootc_patch , & ! Output: [real(r8) (:) ] - livestemc_xfer_to_livestemc => cnveg_carbonflux_inst%livestemc_xfer_to_livestemc_patch , & ! Output: [real(r8) (:) ] - deadstemc_xfer_to_deadstemc => cnveg_carbonflux_inst%deadstemc_xfer_to_deadstemc_patch , & ! Output: [real(r8) (:) ] - livecrootc_xfer_to_livecrootc => cnveg_carbonflux_inst%livecrootc_xfer_to_livecrootc_patch , & ! Output: [real(r8) (:) ] - deadcrootc_xfer_to_deadcrootc => cnveg_carbonflux_inst%deadcrootc_xfer_to_deadcrootc_patch , & ! Output: [real(r8) (:) ] - leafc_storage_to_xfer => cnveg_carbonflux_inst%leafc_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] - frootc_storage_to_xfer => cnveg_carbonflux_inst%frootc_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] - livestemc_storage_to_xfer => cnveg_carbonflux_inst%livestemc_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] - deadstemc_storage_to_xfer => cnveg_carbonflux_inst%deadstemc_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] - livecrootc_storage_to_xfer => cnveg_carbonflux_inst%livecrootc_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] - deadcrootc_storage_to_xfer => cnveg_carbonflux_inst%deadcrootc_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] - gresp_storage_to_xfer => cnveg_carbonflux_inst%gresp_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] - - leafn_xfer_to_leafn => cnveg_nitrogenflux_inst%leafn_xfer_to_leafn_patch , & ! Output: [real(r8) (:) ] - frootn_xfer_to_frootn => cnveg_nitrogenflux_inst%frootn_xfer_to_frootn_patch , & ! Output: [real(r8) (:) ] - livestemn_xfer_to_livestemn => cnveg_nitrogenflux_inst%livestemn_xfer_to_livestemn_patch , & ! Output: [real(r8) (:) ] - deadstemn_xfer_to_deadstemn => cnveg_nitrogenflux_inst%deadstemn_xfer_to_deadstemn_patch , & ! Output: [real(r8) (:) ] - livecrootn_xfer_to_livecrootn => cnveg_nitrogenflux_inst%livecrootn_xfer_to_livecrootn_patch , & ! Output: [real(r8) (:) ] - deadcrootn_xfer_to_deadcrootn => cnveg_nitrogenflux_inst%deadcrootn_xfer_to_deadcrootn_patch , & ! Output: [real(r8) (:) ] - leafn_storage_to_xfer => cnveg_nitrogenflux_inst%leafn_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] - frootn_storage_to_xfer => cnveg_nitrogenflux_inst%frootn_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] - livestemn_storage_to_xfer => cnveg_nitrogenflux_inst%livestemn_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] - deadstemn_storage_to_xfer => cnveg_nitrogenflux_inst%deadstemn_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] - livecrootn_storage_to_xfer => cnveg_nitrogenflux_inst%livecrootn_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] - deadcrootn_storage_to_xfer => cnveg_nitrogenflux_inst%deadcrootn_storage_to_xfer_patch & ! Output: [real(r8) (:) ] - ) - - ! set time steps - dayspyr = get_days_per_year() - - ! specify rain threshold for leaf onset - rain_threshold = 20._r8 - - do fp = 1,num_soilp - p = filter_soilp(fp) - c = patch%column(p) - g = patch%gridcell(p) - - if (stress_decid(ivt(p)) == 1._r8) then - soilt = t_soisno(c,3) - psi = soilpsi(c,3) - - ! onset gdd sum from Biome-BGC, v4.1.2 - crit_onset_gdd = exp(4.8_r8 + 0.13_r8*(annavg_t2m(p) - SHR_CONST_TKFRZ)) - - - ! update offset_counter and test for the end of the offset period - if (offset_flag(p) == 1._r8) then - ! decrement counter for offset period - offset_counter(p) = offset_counter(p) - dt - - ! if this is the end of the offset_period, reset phenology - ! flags and indices - if (offset_counter(p) == 0._r8) then - ! this code block was originally handled by call cn_offset_cleanup(p) - ! inlined during vectorization - offset_flag(p) = 0._r8 - offset_counter(p) = 0._r8 - dormant_flag(p) = 1._r8 - days_active(p) = 0._r8 - - ! reset the previous timestep litterfall flux memory - prev_leafc_to_litter(p) = 0._r8 - prev_frootc_to_litter(p) = 0._r8 - end if - end if - - ! update onset_counter and test for the end of the onset period - if (onset_flag(p) == 1.0_r8) then - ! decrement counter for onset period - onset_counter(p) = onset_counter(p) - dt - - ! if this is the end of the onset period, reset phenology - ! flags and indices - if (onset_counter(p) == 0.0_r8) then - ! this code block was originally handled by call cn_onset_cleanup(p) - ! inlined during vectorization - onset_flag(p) = 0._r8 - onset_counter(p) = 0._r8 - ! set all transfer growth rates to 0.0 - leafc_xfer_to_leafc(p) = 0._r8 - frootc_xfer_to_frootc(p) = 0._r8 - leafn_xfer_to_leafn(p) = 0._r8 - frootn_xfer_to_frootn(p) = 0._r8 - if (woody(ivt(p)) == 1.0_r8) then - livestemc_xfer_to_livestemc(p) = 0._r8 - deadstemc_xfer_to_deadstemc(p) = 0._r8 - livecrootc_xfer_to_livecrootc(p) = 0._r8 - deadcrootc_xfer_to_deadcrootc(p) = 0._r8 - livestemn_xfer_to_livestemn(p) = 0._r8 - deadstemn_xfer_to_deadstemn(p) = 0._r8 - livecrootn_xfer_to_livecrootn(p) = 0._r8 - deadcrootn_xfer_to_deadcrootn(p) = 0._r8 - end if - ! set transfer pools to 0.0 - leafc_xfer(p) = 0._r8 - leafn_xfer(p) = 0._r8 - frootc_xfer(p) = 0._r8 - frootn_xfer(p) = 0._r8 - if (woody(ivt(p)) == 1.0_r8) then - livestemc_xfer(p) = 0._r8 - livestemn_xfer(p) = 0._r8 - deadstemc_xfer(p) = 0._r8 - deadstemn_xfer(p) = 0._r8 - livecrootc_xfer(p) = 0._r8 - livecrootn_xfer(p) = 0._r8 - deadcrootc_xfer(p) = 0._r8 - deadcrootn_xfer(p) = 0._r8 - end if - end if - end if - - ! test for switching from dormant period to growth period - if (dormant_flag(p) == 1._r8) then - - ! keep track of the number of freezing degree days in this - ! dormancy period (only if the freeze flag has not previously been set - ! for this dormancy period - - if (onset_gddflag(p) == 0._r8 .and. soilt < SHR_CONST_TKFRZ) onset_fdd(p) = onset_fdd(p) + fracday - - ! if the number of freezing degree days exceeds a critical value, - ! then onset will require both wet soils and a critical soil - ! temperature sum. If this case is triggered, reset any previously - ! accumulated value in onset_swi, so that onset now depends on - ! the accumulated soil water index following the freeze trigger - - if (onset_fdd(p) > crit_onset_fdd) then - onset_gddflag(p) = 1._r8 - onset_fdd(p) = 0._r8 - onset_swi(p) = 0._r8 - end if - - ! if the freeze flag is set, and if the soil is above freezing - ! then accumulate growing degree days for onset trigger - - if (onset_gddflag(p) == 1._r8 .and. soilt > SHR_CONST_TKFRZ) then - onset_gdd(p) = onset_gdd(p) + (soilt-SHR_CONST_TKFRZ)*fracday - end if - - ! if soils are wet, accumulate soil water index for onset trigger - additional_onset_condition = .true. - if(CNParamsShareInst%constrain_stress_deciduous_onset) then - ! if additional constraint condition not met, set to false - if ((prec10(p) * (3600.0_r8*10.0_r8*24.0_r8)) < rain_threshold) then - additional_onset_condition = .false. - endif - endif - - if (psi >= soilpsi_on) then - onset_swi(p) = onset_swi(p) + fracday - endif - - ! if critical soil water index is exceeded, set onset_flag, and - ! then test for soil temperature criteria - - ! Adding in Kyla's rainfall trigger when fun on. RF. prec10 (mm/s) needs to be higher than 8mm over 10 days. - - if (onset_swi(p) > crit_onset_swi.and. additional_onset_condition) then - onset_flag(p) = 1._r8 - - ! only check soil temperature criteria if freeze flag set since - ! beginning of last dormancy. If freeze flag set and growing - ! degree day sum (since freeze trigger) is lower than critical - ! value, then override the onset_flag set from soil water. - - if (onset_gddflag(p) == 1._r8 .and. onset_gdd(p) < crit_onset_gdd) onset_flag(p) = 0._r8 - end if - - ! only allow onset if dayl > 6hrs - if (onset_flag(p) == 1._r8 .and. dayl(g) <= secspqtrday) then - onset_flag(p) = 0._r8 - end if - - ! if this is the beginning of the onset period - ! then reset the phenology flags and indices - - if (onset_flag(p) == 1._r8) then - dormant_flag(p) = 0._r8 - days_active(p) = 0._r8 - onset_gddflag(p) = 0._r8 - onset_fdd(p) = 0._r8 - onset_gdd(p) = 0._r8 - onset_swi(p) = 0._r8 - onset_counter(p) = ndays_on * secspday - - ! call subroutine to move all the storage pools into transfer pools, - ! where they will be transfered to displayed growth over the onset period. - ! this code was originally handled with call cn_storage_to_xfer(p) - ! inlined during vectorization - - ! set carbon fluxes for shifting storage pools to transfer pools - leafc_storage_to_xfer(p) = fstor2tran * leafc_storage(p)/dt - frootc_storage_to_xfer(p) = fstor2tran * frootc_storage(p)/dt - if (woody(ivt(p)) == 1.0_r8) then - livestemc_storage_to_xfer(p) = fstor2tran * livestemc_storage(p)/dt - deadstemc_storage_to_xfer(p) = fstor2tran * deadstemc_storage(p)/dt - livecrootc_storage_to_xfer(p) = fstor2tran * livecrootc_storage(p)/dt - deadcrootc_storage_to_xfer(p) = fstor2tran * deadcrootc_storage(p)/dt - gresp_storage_to_xfer(p) = fstor2tran * gresp_storage(p)/dt - end if - - ! set nitrogen fluxes for shifting storage pools to transfer pools - leafn_storage_to_xfer(p) = fstor2tran * leafn_storage(p)/dt - frootn_storage_to_xfer(p) = fstor2tran * frootn_storage(p)/dt - if (woody(ivt(p)) == 1.0_r8) then - livestemn_storage_to_xfer(p) = fstor2tran * livestemn_storage(p)/dt - deadstemn_storage_to_xfer(p) = fstor2tran * deadstemn_storage(p)/dt - livecrootn_storage_to_xfer(p) = fstor2tran * livecrootn_storage(p)/dt - deadcrootn_storage_to_xfer(p) = fstor2tran * deadcrootn_storage(p)/dt - end if - end if - - ! test for switching from growth period to offset period - else if (offset_flag(p) == 0._r8) then - - ! if soil water potential lower than critical value, accumulate - ! as stress in offset soil water index - - if (psi <= soilpsi_off) then - offset_swi(p) = offset_swi(p) + fracday - - ! if the offset soil water index exceeds critical value, and - ! if this is not the middle of a previously initiated onset period, - ! then set flag to start the offset period and reset index variables - - if (offset_swi(p) >= crit_offset_swi .and. onset_flag(p) == 0._r8) offset_flag(p) = 1._r8 - - ! if soil water potential higher than critical value, reduce the - ! offset water stress index. By this mechanism, there must be a - ! sustained period of water stress to initiate offset. - - else if (psi >= soilpsi_on) then - offset_swi(p) = offset_swi(p) - fracday - offset_swi(p) = max(offset_swi(p),0._r8) - end if - - ! decrease freezing day accumulator for warm soil - if (offset_fdd(p) > 0._r8 .and. soilt > SHR_CONST_TKFRZ) then - offset_fdd(p) = offset_fdd(p) - fracday - offset_fdd(p) = max(0._r8, offset_fdd(p)) - end if - - ! increase freezing day accumulator for cold soil - if (soilt <= SHR_CONST_TKFRZ) then - offset_fdd(p) = offset_fdd(p) + fracday - - ! if freezing degree day sum is greater than critical value, initiate offset - if (offset_fdd(p) > crit_offset_fdd .and. onset_flag(p) == 0._r8) offset_flag(p) = 1._r8 - end if - - ! force offset if daylength is < 6 hrs - if (dayl(g) <= secspqtrday) then - offset_flag(p) = 1._r8 - end if - - ! if this is the beginning of the offset period - ! then reset flags and indices - if (offset_flag(p) == 1._r8) then - offset_fdd(p) = 0._r8 - offset_swi(p) = 0._r8 - offset_counter(p) = ndays_off * secspday - prev_leafc_to_litter(p) = 0._r8 - prev_frootc_to_litter(p) = 0._r8 - end if - end if - - ! keep track of number of days since last dormancy for control on - ! fraction of new growth to send to storage for next growing season - - if (dormant_flag(p) == 0.0_r8) then - days_active(p) = days_active(p) + fracday - end if - - ! calculate long growing season factor (lgsf) - ! only begin to calculate a lgsf greater than 0.0 once the number - ! of days active exceeds days/year. - lgsf(p) = max(min(3.0_r8*(days_active(p)-leaf_long(ivt(p))*dayspyr )/dayspyr, 1._r8),0._r8) - ! RosieF. 5 Nov 2015. Changed this such that the increase in leaf turnover is faster after - ! trees enter the 'fake evergreen' state. Otherwise, they have a whole year of - ! cheating, with less litterfall than they should have, resulting in very high LAI. - ! Further, the 'fake evergreen' state (where lgsf>0) is entered at the end of a single leaf lifespan - ! and not a whole year. The '3' is arbitrary, given that this entire system is quite abstract. - - - ! set background litterfall rate, when not in the phenological offset period - if (offset_flag(p) == 1._r8) then - bglfr(p) = 0._r8 - else - ! calculate the background litterfall rate (bglfr) - ! in units 1/s, based on leaf longevity (yrs) and correction for long growing season - - bglfr(p) = (1._r8/(leaf_long(ivt(p))*dayspyr*secspday))*lgsf(p) - end if - - ! set background transfer rate when active but not in the phenological onset period - if (onset_flag(p) == 1._r8) then - bgtr(p) = 0._r8 - else - ! the background transfer rate is calculated as the rate that would result - ! in complete turnover of the storage pools in one year at steady state, - ! once lgsf has reached 1.0 (after 730 days active). - - bgtr(p) = (1._r8/(dayspyr*secspday))*lgsf(p) - - ! set carbon fluxes for shifting storage pools to transfer pools - - ! reduced the amount of stored carbon flowing to display pool by only counting the delta - ! between leafc and leafc_store in the flux. RosieF, Nov5 2015. - leafc_storage_to_xfer(p) = max(0.0_r8,(leafc_storage(p)-leafc(p))) * bgtr(p) - frootc_storage_to_xfer(p) = max(0.0_r8,(frootc_storage(p)-frootc(p))) * bgtr(p) - if (woody(ivt(p)) == 1.0_r8) then - livestemc_storage_to_xfer(p) = livestemc_storage(p) * bgtr(p) - deadstemc_storage_to_xfer(p) = deadstemc_storage(p) * bgtr(p) - livecrootc_storage_to_xfer(p) = livecrootc_storage(p) * bgtr(p) - deadcrootc_storage_to_xfer(p) = deadcrootc_storage(p) * bgtr(p) - gresp_storage_to_xfer(p) = gresp_storage(p) * bgtr(p) - end if - - ! set nitrogen fluxes for shifting storage pools to transfer pools - leafn_storage_to_xfer(p) = leafn_storage(p) * bgtr(p) - frootn_storage_to_xfer(p) = frootn_storage(p) * bgtr(p) - if (woody(ivt(p)) == 1.0_r8) then - livestemn_storage_to_xfer(p) = livestemn_storage(p) * bgtr(p) - deadstemn_storage_to_xfer(p) = deadstemn_storage(p) * bgtr(p) - livecrootn_storage_to_xfer(p) = livecrootn_storage(p) * bgtr(p) - deadcrootn_storage_to_xfer(p) = deadcrootn_storage(p) * bgtr(p) - end if - end if - - end if ! end if stress deciduous - - end do ! end of patch loop - - end associate - - end subroutine CNStressDecidPhenology - - !----------------------------------------------------------------------- - subroutine CropPhenology(num_pcropp, filter_pcropp , & - waterdiagnosticbulk_inst, temperature_inst, crop_inst, canopystate_inst, cnveg_state_inst , & - cnveg_carbonstate_inst, cnveg_nitrogenstate_inst, cnveg_carbonflux_inst, cnveg_nitrogenflux_inst,& - c13_cnveg_carbonstate_inst, c14_cnveg_carbonstate_inst) - - ! !DESCRIPTION: - ! Code from AgroIBIS to determine crop phenology and code from CN to - ! handle CN fluxes during the phenological onset & offset periods. - - ! !USES: - use clm_time_manager , only : get_curr_date, get_curr_calday, get_days_per_year, get_rad_step_size - use pftconMod , only : ntmp_corn, nswheat, nwwheat, ntmp_soybean - use pftconMod , only : nirrig_tmp_corn, nirrig_swheat, nirrig_wwheat, nirrig_tmp_soybean - use pftconMod , only : ntrp_corn, nsugarcane, ntrp_soybean, ncotton, nrice - use pftconMod , only : nirrig_trp_corn, nirrig_sugarcane, nirrig_trp_soybean - use pftconMod , only : nirrig_cotton, nirrig_rice - - ! Y. Cheng - use pftconMod , only : nmiscanthus, nirrig_miscanthus, nswitchgrass, nirrig_switchgrass - - use clm_varcon , only : spval, secspday - use clm_varctl , only : use_fertilizer - use clm_varctl , only : use_c13, use_c14 - use clm_varcon , only : c13ratio, c14ratio - ! - ! !ARGUMENTS: - integer , intent(in) :: num_pcropp ! number of prog crop patches in filter - integer , intent(in) :: filter_pcropp(:) ! filter for prognostic crop patches - type(waterdiagnosticbulk_type) , intent(in) :: waterdiagnosticbulk_inst - type(temperature_type) , intent(in) :: temperature_inst - type(crop_type) , intent(inout) :: crop_inst - type(canopystate_type) , intent(in) :: canopystate_inst - type(cnveg_state_type) , intent(inout) :: cnveg_state_inst - type(cnveg_carbonstate_type) , intent(inout) :: cnveg_carbonstate_inst - type(cnveg_nitrogenstate_type) , intent(inout) :: cnveg_nitrogenstate_inst - type(cnveg_carbonflux_type) , intent(inout) :: cnveg_carbonflux_inst - type(cnveg_nitrogenflux_type) , intent(inout) :: cnveg_nitrogenflux_inst - type(cnveg_carbonstate_type) , intent(inout) :: c13_cnveg_carbonstate_inst - type(cnveg_carbonstate_type) , intent(inout) :: c14_cnveg_carbonstate_inst - ! - ! LOCAL VARAIBLES: - integer kyr ! current year - integer kmo ! month of year (1, ..., 12) - integer kda ! day of month (1, ..., 31) - integer mcsec ! seconds of day (0, ..., seconds/day) - integer jday ! julian day of the year - integer fp,p ! patch indices - integer c ! column indices - integer g ! gridcell indices - integer h ! hemisphere indices - integer idpp ! number of days past planting - real(r8) :: dtrad ! radiation time step delta t (seconds) - real(r8) dayspyr ! days per year - real(r8) crmcorn ! comparitive relative maturity for corn - real(r8) ndays_on ! number of days to fertilize - !------------------------------------------------------------------------ - - associate( & - ivt => patch%itype , & ! Input: [integer (:) ] patch vegetation type - - leaf_long => pftcon%leaf_long , & ! Input: leaf longevity (yrs) - leafcn => pftcon%leafcn , & ! Input: leaf C:N (gC/gN) - manunitro => pftcon%manunitro , & ! Input: max manure to be applied in total (kgN/m2) - mxmat => pftcon%mxmat , & ! Input: - minplanttemp => pftcon%minplanttemp , & ! Input: - planttemp => pftcon%planttemp , & ! Input: - gddmin => pftcon%gddmin , & ! Input: - hybgdd => pftcon%hybgdd , & ! Input: - lfemerg => pftcon%lfemerg , & ! Input: - grnfill => pftcon%grnfill , & ! Input: - - t_ref2m_min => temperature_inst%t_ref2m_min_patch , & ! Input: [real(r8) (:) ] daily minimum of average 2 m height surface air temperature (K) - t10 => temperature_inst%t_a10_patch , & ! Input: [real(r8) (:) ] 10-day running mean of the 2 m temperature (K) - a5tmin => temperature_inst%t_a5min_patch , & ! Input: [real(r8) (:) ] 5-day running mean of min 2-m temperature - a10tmin => temperature_inst%t_a10min_patch , & ! Input: [real(r8) (:) ] 10-day running mean of min 2-m temperature - gdd020 => temperature_inst%gdd020_patch , & ! Input: [real(r8) (:) ] 20 yr mean of gdd0 - gdd820 => temperature_inst%gdd820_patch , & ! Input: [real(r8) (:) ] 20 yr mean of gdd8 - gdd1020 => temperature_inst%gdd1020_patch , & ! Input: [real(r8) (:) ] 20 yr mean of gdd10 - - fertnitro => crop_inst%fertnitro_patch , & ! Input: [real(r8) (:) ] fertilizer nitrogen - hui => crop_inst%gddplant_patch , & ! Input: [real(r8) (:) ] gdd since planting (gddplant) - leafout => crop_inst%gddtsoi_patch , & ! Input: [real(r8) (:) ] gdd from top soil layer temperature - harvdate => crop_inst%harvdate_patch , & ! Output: [integer (:) ] harvest date - croplive => crop_inst%croplive_patch , & ! Output: [logical (:) ] Flag, true if planted, not harvested - cropplant => crop_inst%cropplant_patch , & ! Output: [logical (:) ] Flag, true if crop may be planted - vf => crop_inst%vf_patch , & ! Output: [real(r8) (:) ] vernalization factor - peaklai => cnveg_state_inst%peaklai_patch , & ! Output: [integer (:) ] 1: max allowed lai; 0: not at max - tlai => canopystate_inst%tlai_patch , & ! Input: [real(r8) (:) ] one-sided leaf area index, no burying by snow - - idop => cnveg_state_inst%idop_patch , & ! Output: [integer (:) ] date of planting - gddmaturity => cnveg_state_inst%gddmaturity_patch , & ! Output: [real(r8) (:) ] gdd needed to harvest - huileaf => cnveg_state_inst%huileaf_patch , & ! Output: [real(r8) (:) ] heat unit index needed from planting to leaf emergence - huigrain => cnveg_state_inst%huigrain_patch , & ! Output: [real(r8) (:) ] same to reach vegetative maturity - cumvd => cnveg_state_inst%cumvd_patch , & ! Output: [real(r8) (:) ] cumulative vernalization d?ependence? - hdidx => cnveg_state_inst%hdidx_patch , & ! Output: [real(r8) (:) ] cold hardening index? - bglfr => cnveg_state_inst%bglfr_patch , & ! Output: [real(r8) (:) ] background litterfall rate (1/s) - bgtr => cnveg_state_inst%bgtr_patch , & ! Output: [real(r8) (:) ] background transfer growth rate (1/s) - lgsf => cnveg_state_inst%lgsf_patch , & ! Output: [real(r8) (:) ] long growing season factor [0-1] - onset_flag => cnveg_state_inst%onset_flag_patch , & ! Output: [real(r8) (:) ] onset flag - offset_flag => cnveg_state_inst%offset_flag_patch , & ! Output: [real(r8) (:) ] offset flag - onset_counter => cnveg_state_inst%onset_counter_patch , & ! Output: [real(r8) (:) ] onset counter - offset_counter => cnveg_state_inst%offset_counter_patch , & ! Output: [real(r8) (:) ] offset counter - - leafc_xfer => cnveg_carbonstate_inst%leafc_xfer_patch , & ! Output: [real(r8) (:) ] (gC/m2) leaf C transfer - - crop_seedc_to_leaf => cnveg_carbonflux_inst%crop_seedc_to_leaf_patch, & ! Output: [real(r8) (:) ] (gC/m2/s) seed source to leaf - - fert_counter => cnveg_nitrogenflux_inst%fert_counter_patch , & ! Output: [real(r8) (:) ] >0 fertilize; <=0 not (seconds) - leafn_xfer => cnveg_nitrogenstate_inst%leafn_xfer_patch , & ! Output: [real(r8) (:) ] (gN/m2) leaf N transfer - crop_seedn_to_leaf => cnveg_nitrogenflux_inst%crop_seedn_to_leaf_patch, & ! Output: [real(r8) (:) ] (gN/m2/s) seed source to leaf - cphase => crop_inst%cphase_patch , & ! Output: [real(r8) (:)] phenology phase - fert => cnveg_nitrogenflux_inst%fert_patch & ! Output: [real(r8) (:) ] (gN/m2/s) fertilizer applied each timestep - ) - - ! get time info - dayspyr = get_days_per_year() - jday = get_curr_calday() - call get_curr_date(kyr, kmo, kda, mcsec) - dtrad = real( get_rad_step_size(), r8 ) - - if (use_fertilizer) then - ndays_on = 20._r8 ! number of days to fertilize - else - ndays_on = 0._r8 ! number of days to fertilize - end if - - do fp = 1, num_pcropp - p = filter_pcropp(fp) - c = patch%column(p) - g = patch%gridcell(p) - h = inhemi(p) - - ! background litterfall and transfer rates; long growing season factor - - bglfr(p) = 0._r8 ! this value changes later in a crop's life cycle - bgtr(p) = 0._r8 - lgsf(p) = 0._r8 - - ! --------------------------------- - ! from AgroIBIS subroutine planting - ! --------------------------------- - - ! in order to allow a crop to be planted only once each year - ! initialize cropplant = .false., but hold it = .true. through the end of the year - - ! initialize other variables that are calculated for crops - ! on an annual basis in cropresidue subroutine - - if ( jday == jdayyrstart(h) .and. mcsec == 0 )then - - ! make sure variables aren't changed at beginning of the year - ! for a crop that is currently planted, such as - ! WINTER TEMPERATE CEREAL = winter (wheat + barley + rye) - ! represented here by the winter wheat pft - - if (.not. croplive(p)) then - cropplant(p) = .false. - idop(p) = NOT_Planted - - ! keep next for continuous, annual winter temperate cereal crop; - ! if we removed elseif, - ! winter cereal grown continuously would amount to a cereal/fallow - ! rotation because cereal would only be planted every other year - - else if (croplive(p) .and. (ivt(p) == nwwheat .or. ivt(p) == nirrig_wwheat)) then - cropplant(p) = .false. - ! else ! not possible to have croplive and ivt==cornORsoy? (slevis) - end if - - end if - - if ( (.not. croplive(p)) .and. (.not. cropplant(p)) ) then - - ! gdd needed for * chosen crop and a likely hybrid (for that region) * - ! to reach full physiological maturity - - ! based on accumulated seasonal average growing degree days from - ! April 1 - Sept 30 (inclusive) - ! for corn and soybeans in the United States - - ! decided upon by what the typical average growing season length is - ! and the gdd needed to reach maturity in those regions - - ! first choice is used for spring temperate cereal and/or soybeans and maize - - ! slevis: ibis reads xinpdate in io.f from control.crops.nc variable name 'plantdate' - ! According to Chris Kucharik, the dataset of - ! xinpdate was generated from a previous model run at 0.5 deg resolution - - ! winter temperate cereal : use gdd0 as a limit to plant winter cereal - - if (ivt(p) == nwwheat .or. ivt(p) == nirrig_wwheat) then - - ! add check to only plant winter cereal after other crops (soybean, maize) - ! have been harvested - - ! *** remember order of planting is crucial - in terms of which crops you want - ! to be grown in what order *** - - ! in this case, corn or soybeans are assumed to be planted before - ! cereal would be in any particular year that both patches are allowed - ! to grow in the same grid cell (e.g., double-cropping) - - ! slevis: harvdate below needs cropplant(p) above to be cropplant(p,ivt(p)) - ! where ivt(p) has rotated to winter cereal because - ! cropplant through the end of the year for a harvested crop. - ! Also harvdate(p) should be harvdate(p,ivt(p)) and should be - ! updated on Jan 1st instead of at harvest (slevis) - if (a5tmin(p) /= spval .and. & - a5tmin(p) <= minplanttemp(ivt(p)) .and. & - jday >= minplantjday(ivt(p),h) .and. & - (gdd020(p) /= spval .and. & - gdd020(p) >= gddmin(ivt(p)))) then - - cumvd(p) = 0._r8 - hdidx(p) = 0._r8 - vf(p) = 0._r8 - croplive(p) = .true. - cropplant(p) = .true. - idop(p) = jday - harvdate(p) = NOT_Harvested - gddmaturity(p) = hybgdd(ivt(p)) - leafc_xfer(p) = initial_seed_at_planting - leafn_xfer(p) = leafc_xfer(p) / leafcn(ivt(p)) ! with onset - crop_seedc_to_leaf(p) = leafc_xfer(p)/dt - crop_seedn_to_leaf(p) = leafn_xfer(p)/dt - - ! because leafc_xfer is set above rather than incremneted through the normal process, must also set its isotope - ! pools here. use totvegc_patch as the closest analogue if nonzero, and use initial value otherwise - if (use_c13) then - if ( cnveg_carbonstate_inst%totvegc_patch(p) .gt. 0._r8) then - c13_cnveg_carbonstate_inst%leafc_xfer_patch(p) = leafc_xfer(p) * & - c13_cnveg_carbonstate_inst%totvegc_patch(p) / cnveg_carbonstate_inst%totvegc_patch(p) - else - c13_cnveg_carbonstate_inst%leafc_xfer_patch(p) = leafc_xfer(p) * c13ratio - endif - endif - if (use_c14) then - if ( cnveg_carbonstate_inst%totvegc_patch(p) .gt. 0._r8) then - c14_cnveg_carbonstate_inst%leafc_xfer_patch(p) = leafc_xfer(p) * & - c14_cnveg_carbonstate_inst%totvegc_patch(p) / cnveg_carbonstate_inst%totvegc_patch(p) - else - c14_cnveg_carbonstate_inst%leafc_xfer_patch(p) = leafc_xfer(p) * c14ratio - endif - endif - - ! latest possible date to plant winter cereal and after all other - ! crops were harvested for that year - - else if (jday >= maxplantjday(ivt(p),h) .and. & - gdd020(p) /= spval .and. & - gdd020(p) >= gddmin(ivt(p))) then - - cumvd(p) = 0._r8 - hdidx(p) = 0._r8 - vf(p) = 0._r8 - croplive(p) = .true. - cropplant(p) = .true. - idop(p) = jday - harvdate(p) = NOT_Harvested - gddmaturity(p) = hybgdd(ivt(p)) - leafc_xfer(p) = initial_seed_at_planting - leafn_xfer(p) = leafc_xfer(p) / leafcn(ivt(p)) ! with onset - crop_seedc_to_leaf(p) = leafc_xfer(p)/dt - crop_seedn_to_leaf(p) = leafn_xfer(p)/dt - - ! because leafc_xfer is set above rather than incremneted through the normal process, must also set its isotope - ! pools here. use totvegc_patch as the closest analogue if nonzero, and use initial value otherwise - if (use_c13) then - if ( cnveg_carbonstate_inst%totvegc_patch(p) .gt. 0._r8) then - c13_cnveg_carbonstate_inst%leafc_xfer_patch(p) = leafc_xfer(p) * & - c13_cnveg_carbonstate_inst%totvegc_patch(p) / cnveg_carbonstate_inst%totvegc_patch(p) - else - c13_cnveg_carbonstate_inst%leafc_xfer_patch(p) = leafc_xfer(p) * c13ratio - endif - endif - if (use_c14) then - if ( cnveg_carbonstate_inst%totvegc_patch(p) .gt. 0._r8) then - c14_cnveg_carbonstate_inst%leafc_xfer_patch(p) = leafc_xfer(p) * & - c14_cnveg_carbonstate_inst%totvegc_patch(p) / cnveg_carbonstate_inst%totvegc_patch(p) - else - c14_cnveg_carbonstate_inst%leafc_xfer_patch(p) = leafc_xfer(p) * c14ratio - endif - endif - else - gddmaturity(p) = 0._r8 - end if - - else ! not winter cereal... slevis: added distinction between NH and SH - ! slevis: The idea is that jday will equal idop sooner or later in the year - ! while the gdd part is either true or false for the year. - if (t10(p) /= spval.and. a10tmin(p) /= spval .and. & - t10(p) > planttemp(ivt(p)) .and. & - a10tmin(p) > minplanttemp(ivt(p)) .and. & - jday >= minplantjday(ivt(p),h) .and. & - jday <= maxplantjday(ivt(p),h) .and. & - t10(p) /= spval .and. a10tmin(p) /= spval .and. & - gdd820(p) /= spval .and. & - gdd820(p) >= gddmin(ivt(p))) then - - ! impose limit on growing season length needed - ! for crop maturity - for cold weather constraints - croplive(p) = .true. - cropplant(p) = .true. - idop(p) = jday - harvdate(p) = NOT_Harvested - - ! go a specified amount of time before/after - ! climatological date - if (ivt(p) == ntmp_soybean .or. ivt(p) == nirrig_tmp_soybean .or. & - ivt(p) == ntrp_soybean .or. ivt(p) == nirrig_trp_soybean) then - gddmaturity(p) = min(gdd1020(p), hybgdd(ivt(p))) - end if - - ! Y. Cheng, add switchgrass and Miscanthus - if (ivt(p) == ntmp_corn .or. ivt(p) == nirrig_tmp_corn .or. & - ivt(p) == ntrp_corn .or. ivt(p) == nirrig_trp_corn .or. & - ivt(p) == nsugarcane .or. ivt(p) == nirrig_sugarcane .or. & - ivt(p) == nmiscanthus .or. ivt(p) == nirrig_miscanthus .or. & - ivt(p) == nswitchgrass .or. ivt(p) == nirrig_switchgrass) then - gddmaturity(p) = max(950._r8, min(gdd820(p)*0.85_r8, hybgdd(ivt(p)))) - gddmaturity(p) = max(950._r8, min(gddmaturity(p)+150._r8, 1850._r8)) - end if - if (ivt(p) == nswheat .or. ivt(p) == nirrig_swheat .or. & - ivt(p) == ncotton .or. ivt(p) == nirrig_cotton .or. & - ivt(p) == nrice .or. ivt(p) == nirrig_rice) then - gddmaturity(p) = min(gdd020(p), hybgdd(ivt(p))) - end if - - leafc_xfer(p) = initial_seed_at_planting - leafn_xfer(p) = leafc_xfer(p) / leafcn(ivt(p)) ! with onset - crop_seedc_to_leaf(p) = leafc_xfer(p)/dt - crop_seedn_to_leaf(p) = leafn_xfer(p)/dt - - ! because leafc_xfer is set above rather than incremneted through the normal process, must also set its isotope - ! pools here. use totvegc_patch as the closest analogue if nonzero, and use initial value otherwise - if (use_c13) then - if ( cnveg_carbonstate_inst%totvegc_patch(p) .gt. 0._r8) then - c13_cnveg_carbonstate_inst%leafc_xfer_patch(p) = leafc_xfer(p) * & - c13_cnveg_carbonstate_inst%totvegc_patch(p) / cnveg_carbonstate_inst%totvegc_patch(p) - else - c13_cnveg_carbonstate_inst%leafc_xfer_patch(p) = leafc_xfer(p) * c13ratio - endif - endif - if (use_c14) then - if ( cnveg_carbonstate_inst%totvegc_patch(p) .gt. 0._r8) then - c14_cnveg_carbonstate_inst%leafc_xfer_patch(p) = leafc_xfer(p) * & - c14_cnveg_carbonstate_inst%totvegc_patch(p) / cnveg_carbonstate_inst%totvegc_patch(p) - else - c14_cnveg_carbonstate_inst%leafc_xfer_patch(p) = leafc_xfer(p) * c14ratio - endif - endif - - - ! If hit the max planting julian day -- go ahead and plant - else if (jday == maxplantjday(ivt(p),h) .and. gdd820(p) > 0._r8 .and. & - gdd820(p) /= spval ) then - croplive(p) = .true. - cropplant(p) = .true. - idop(p) = jday - harvdate(p) = NOT_Harvested - - if (ivt(p) == ntmp_soybean .or. ivt(p) == nirrig_tmp_soybean .or. & - ivt(p) == ntrp_soybean .or. ivt(p) == nirrig_trp_soybean) then - gddmaturity(p) = min(gdd1020(p), hybgdd(ivt(p))) - end if - - ! Y. Cheng, add switchgrass and Miscanthus - if (ivt(p) == ntmp_corn .or. ivt(p) == nirrig_tmp_corn .or. & - ivt(p) == ntrp_corn .or. ivt(p) == nirrig_trp_corn .or. & - ivt(p) == nsugarcane .or. ivt(p) == nirrig_sugarcane .or. & - ivt(p) == nmiscanthus .or. ivt(p) == nirrig_miscanthus .or. & - ivt(p) == nswitchgrass .or. ivt(p) == nirrig_switchgrass) then - gddmaturity(p) = max(950._r8, min(gdd820(p)*0.85_r8, hybgdd(ivt(p)))) - end if - if (ivt(p) == nswheat .or. ivt(p) == nirrig_swheat .or. & - ivt(p) == ncotton .or. ivt(p) == nirrig_cotton .or. & - ivt(p) == nrice .or. ivt(p) == nirrig_rice) then - gddmaturity(p) = min(gdd020(p), hybgdd(ivt(p))) - end if - - leafc_xfer(p) = initial_seed_at_planting - leafn_xfer(p) = leafc_xfer(p) / leafcn(ivt(p)) ! with onset - crop_seedc_to_leaf(p) = leafc_xfer(p)/dt - crop_seedn_to_leaf(p) = leafn_xfer(p)/dt - - ! because leafc_xfer is set above rather than incremneted through the normal process, must also set its isotope - ! pools here. use totvegc_patch as the closest analogue if nonzero, and use initial value otherwise - if (use_c13) then - if ( cnveg_carbonstate_inst%totvegc_patch(p) .gt. 0._r8) then - c13_cnveg_carbonstate_inst%leafc_xfer_patch(p) = leafc_xfer(p) * & - c13_cnveg_carbonstate_inst%totvegc_patch(p) / cnveg_carbonstate_inst%totvegc_patch(p) - else - c13_cnveg_carbonstate_inst%leafc_xfer_patch(p) = leafc_xfer(p) * c13ratio - endif - endif - if (use_c14) then - if ( cnveg_carbonstate_inst%totvegc_patch(p) .gt. 0._r8) then - c14_cnveg_carbonstate_inst%leafc_xfer_patch(p) = leafc_xfer(p) * & - c14_cnveg_carbonstate_inst%totvegc_patch(p) / cnveg_carbonstate_inst%totvegc_patch(p) - else - c14_cnveg_carbonstate_inst%leafc_xfer_patch(p) = leafc_xfer(p) * c14ratio - endif - endif - - else - gddmaturity(p) = 0._r8 - end if - end if ! crop patch distinction - - ! crop phenology (gdd thresholds) controlled by gdd needed for - ! maturity (physiological) which is based on the average gdd - ! accumulation and hybrids in United States from April 1 - Sept 30 - - ! calculate threshold from phase 1 to phase 2: - ! threshold for attaining leaf emergence (based on fraction of - ! gdd(i) -- climatological average) - ! Hayhoe and Dwyer, 1990, Can. J. Soil Sci 70:493-497 - ! Carlson and Gage, 1989, Agric. For. Met., 45: 313-324 - ! J.T. Ritchie, 1991: Modeling Plant and Soil systems - - huileaf(p) = lfemerg(ivt(p)) * gddmaturity(p) ! 3-7% in cereal - - ! calculate threshhold from phase 2 to phase 3: - ! from leaf emergence to beginning of grain-fill period - ! this hypothetically occurs at the end of tassling, not the beginning - ! tassel initiation typically begins at 0.5-0.55 * gddmaturity - - ! calculate linear relationship between huigrain fraction and relative - ! maturity rating for maize - - ! Y. Cheng, add switchgrass and Miscanthus - if (ivt(p) == ntmp_corn .or. ivt(p) == nirrig_tmp_corn .or. & - ivt(p) == ntrp_corn .or. ivt(p) == nirrig_trp_corn .or. & - ivt(p) == nsugarcane .or. ivt(p) == nirrig_sugarcane .or. & - ivt(p) == nmiscanthus .or. ivt(p) == nirrig_miscanthus .or. & - ivt(p) == nswitchgrass .or. ivt(p) == nirrig_switchgrass) then - ! the following estimation of crmcorn from gddmaturity is based on a linear - ! regression using data from Pioneer-brand corn hybrids (Kucharik, 2003, - ! Earth Interactions 7:1-33: fig. 2) - crmcorn = max(73._r8, min(135._r8, (gddmaturity(p)+ 53.683_r8)/13.882_r8)) - - ! the following adjustment of grnfill based on crmcorn is based on a tuning - ! of Agro-IBIS to give reasonable results for max LAI and the seasonal - ! progression of LAI growth (pers. comm. C. Kucharik June 10, 2010) - huigrain(p) = -0.002_r8 * (crmcorn - 73._r8) + grnfill(ivt(p)) - - huigrain(p) = min(max(huigrain(p), grnfill(ivt(p))-0.1_r8), grnfill(ivt(p))) - huigrain(p) = huigrain(p) * gddmaturity(p) ! Cabelguenne et - else - huigrain(p) = grnfill(ivt(p)) * gddmaturity(p) ! al. 1999 - end if - - end if ! crop not live nor planted - - ! ---------------------------------- - ! from AgroIBIS subroutine phenocrop - ! ---------------------------------- - - ! all of the phenology changes are based on the total number of gdd needed - ! to change to the next phase - based on fractions of the total gdd typical - ! for that region based on the April 1 - Sept 30 window of development - - ! crop phenology (gdd thresholds) controlled by gdd needed for - ! maturity (physiological) which is based on the average gdd - ! accumulation and hybrids in United States from April 1 - Sept 30 - - ! Phase 1: Planting to leaf emergence (now in CNAllocation) - ! Phase 2: Leaf emergence to beginning of grain fill (general LAI accumulation) - ! Phase 3: Grain fill to physiological maturity and harvest (LAI decline) - ! Harvest: if gdd past grain fill initiation exceeds limit - ! or number of days past planting reaches a maximum, the crop has - ! reached physiological maturity and plant is harvested; - ! crop could be live or dead at this stage - these limits - ! could lead to reaching physiological maturity or determining - ! a harvest date for a crop killed by an early frost (see next comments) - ! --- --- --- - ! keeping comments without the code (slevis): - ! if minimum temperature, t_ref2m_min <= freeze kill threshold, tkill - ! for 3 consecutive days and lai is above a minimum, - ! plant will be damaged/killed. This function is more for spring freeze events - ! or for early fall freeze events - - ! spring temperate cereal is affected by this, winter cereal kill function - ! is determined in crops.f - is a more elaborate function of - ! cold hardening of the plant - - ! currently simulates too many grid cells killed by freezing temperatures - - ! removed on March 12 2002 - C. Kucharik - ! until it can be a bit more refined, or used at a smaller scale. - ! we really have no way of validating this routine - ! too difficult to implement on 0.5 degree scale grid cells - ! --- --- --- - - onset_flag(p) = 0._r8 ! CN terminology to trigger certain - offset_flag(p) = 0._r8 ! carbon and nitrogen transfers - - if (croplive(p)) then - cphase(p) = 1._r8 - - ! call vernalization if winter temperate cereal planted, living, and the - ! vernalization factor is not 1; - ! vf affects the calculation of gddtsoi & gddplant - - if (t_ref2m_min(p) < 1.e30_r8 .and. vf(p) /= 1._r8 .and. & - (ivt(p) == nwwheat .or. ivt(p) == nirrig_wwheat)) then - call vernalization(p, & - canopystate_inst, temperature_inst, waterdiagnosticbulk_inst, cnveg_state_inst, & - crop_inst) - end if - - ! days past planting may determine harvest - - if (jday >= idop(p)) then - idpp = jday - idop(p) - else - idpp = int(dayspyr) + jday - idop(p) - end if - - ! onset_counter initialized to zero when .not. croplive - ! offset_counter relevant only at time step of harvest - - onset_counter(p) = onset_counter(p) - dt - - ! enter phase 2 onset for one time step: - ! transfer seed carbon to leaf emergence - - if (peaklai(p) >= 1) then - hui(p) = max(hui(p),huigrain(p)) - endif - - if (leafout(p) >= huileaf(p) .and. hui(p) < huigrain(p) .and. idpp < mxmat(ivt(p))) then - cphase(p) = 2._r8 - if (abs(onset_counter(p)) > 1.e-6_r8) then - onset_flag(p) = 1._r8 - onset_counter(p) = dt - fert_counter(p) = ndays_on * secspday - if (ndays_on .gt. 0) then - fert(p) = (manunitro(ivt(p)) * 1000._r8 + fertnitro(p))/ fert_counter(p) - else - fert(p) = 0._r8 - end if - else - ! this ensures no re-entry to onset of phase2 - ! b/c onset_counter(p) = onset_counter(p) - dt - ! at every time step - - onset_counter(p) = dt - end if - - ! enter harvest for one time step: - ! - transfer live biomass to litter and to crop yield - ! - send xsmrpool to the atmosphere - ! if onset and harvest needed to last longer than one timestep - ! the onset_counter would change from dt and you'd need to make - ! changes to the offset subroutine below - - else if (hui(p) >= gddmaturity(p) .or. idpp >= mxmat(ivt(p))) then - if (harvdate(p) >= NOT_Harvested) harvdate(p) = jday - croplive(p) = .false. ! no re-entry in greater if-block - cphase(p) = 4._r8 - if (tlai(p) > 0._r8) then ! plant had emerged before harvest - offset_flag(p) = 1._r8 - offset_counter(p) = dt - else ! plant never emerged from the ground - ! Revert planting transfers; this will replenish the crop seed deficit. - ! We subtract from any existing value in crop_seedc_to_leaf / - ! crop_seedn_to_leaf in the unlikely event that we enter this block of - ! code in the same time step where the planting transfer originally - ! occurred. - crop_seedc_to_leaf(p) = crop_seedc_to_leaf(p) - leafc_xfer(p)/dt - crop_seedn_to_leaf(p) = crop_seedn_to_leaf(p) - leafn_xfer(p)/dt - leafc_xfer(p) = 0._r8 - leafn_xfer(p) = leafc_xfer(p) / leafcn(ivt(p)) - if (use_c13) then - c13_cnveg_carbonstate_inst%leafc_xfer_patch(p) = 0._r8 - endif - if (use_c14) then - c14_cnveg_carbonstate_inst%leafc_xfer_patch(p) = 0._r8 - endif - - end if - - ! enter phase 3 while previous criteria fail and next is true; - ! in terms of order, phase 3 occurs before harvest, but when - ! harvest *can* occur, we want it to have first priority. - ! AgroIBIS uses a complex formula for lai decline. - ! Use CN's simple formula at least as a place holder (slevis) - - else if (hui(p) >= huigrain(p)) then - cphase(p) = 3._r8 - bglfr(p) = 1._r8/(leaf_long(ivt(p))*dayspyr*secspday) - end if - - ! continue fertilizer application while in phase 2; - ! assumes that onset of phase 2 took one time step only - - if (fert_counter(p) <= 0._r8) then - fert(p) = 0._r8 - else ! continue same fert application every timestep - fert_counter(p) = fert_counter(p) - dtrad - end if - - else ! crop not live - ! next 2 lines conserve mass if leaf*_xfer > 0 due to interpinic. - ! We subtract from any existing value in crop_seedc_to_leaf / - ! crop_seedn_to_leaf in the unlikely event that we enter this block of - ! code in the same time step where the planting transfer originally - ! occurred. - crop_seedc_to_leaf(p) = crop_seedc_to_leaf(p) - leafc_xfer(p)/dt - crop_seedn_to_leaf(p) = crop_seedn_to_leaf(p) - leafn_xfer(p)/dt - onset_counter(p) = 0._r8 - leafc_xfer(p) = 0._r8 - leafn_xfer(p) = leafc_xfer(p) / leafcn(ivt(p)) - if (use_c13) then - c13_cnveg_carbonstate_inst%leafc_xfer_patch(p) = 0._r8 - endif - if (use_c14) then - c14_cnveg_carbonstate_inst%leafc_xfer_patch(p) = 0._r8 - endif - end if ! croplive - - end do ! prognostic crops loop - - end associate - - end subroutine CropPhenology - - !----------------------------------------------------------------------- - subroutine CropPhenologyInit(bounds) - ! - ! !DESCRIPTION: - ! Initialization of CropPhenology. Must be called after time-manager is - ! initialized, and after pftcon file is read in. - ! - ! !USES: - use pftconMod , only: npcropmin, npcropmax - use clm_time_manager, only: get_calday - ! - ! !ARGUMENTS: - type(bounds_type), intent(in) :: bounds - ! - ! LOCAL VARAIBLES: - integer :: p,g,n,i ! indices - !------------------------------------------------------------------------ - - allocate( inhemi(bounds%begp:bounds%endp) ) - - allocate( minplantjday(0:maxveg,inSH)) ! minimum planting julian day - allocate( maxplantjday(0:maxveg,inSH)) ! minimum planting julian day - - ! Julian day for the start of the year (mid-winter) - jdayyrstart(inNH) = 1 - jdayyrstart(inSH) = 182 - - ! Convert planting dates into julian day - minplantjday(:,:) = huge(1) - maxplantjday(:,:) = huge(1) - do n = npcropmin, npcropmax - if (pftcon%is_pft_known_to_model(n)) then - minplantjday(n, inNH) = int( get_calday( pftcon%mnNHplantdate(n), 0 ) ) - maxplantjday(n, inNH) = int( get_calday( pftcon%mxNHplantdate(n), 0 ) ) - - minplantjday(n, inSH) = int( get_calday( pftcon%mnSHplantdate(n), 0 ) ) - maxplantjday(n, inSH) = int( get_calday( pftcon%mxSHplantdate(n), 0 ) ) - end if - end do - - ! Figure out what hemisphere each PATCH is in - do p = bounds%begp, bounds%endp - g = patch%gridcell(p) - ! Northern hemisphere - if ( grc%latdeg(g) > 0.0_r8 )then - inhemi(p) = inNH - else - inhemi(p) = inSH - end if - end do - - ! - ! Constants for Crop vernalization - ! - ! photoperiod factor calculation - ! genetic constant - can be modified - - p1d = 0.004_r8 ! average for genotypes from Ritchey, 1991. - ! Modeling plant & soil systems: Wheat phasic developmt - p1v = 0.003_r8 ! average for genotypes from Ritchey, 1991. - - hti = 1._r8 - tbase = 0._r8 - - end subroutine CropPhenologyInit - - !----------------------------------------------------------------------- - subroutine vernalization(p, & - canopystate_inst, temperature_inst, waterdiagnosticbulk_inst, cnveg_state_inst, crop_inst) - ! - ! !DESCRIPTION: - ! - ! * * * only call for winter temperate cereal * * * - ! - ! subroutine calculates vernalization and photoperiod effects on - ! gdd accumulation in winter temperate cereal varieties. Thermal time accumulation - ! is reduced in 1st period until plant is fully vernalized. During this - ! time of emergence to spikelet formation, photoperiod can also have a - ! drastic effect on plant development. - ! - ! !ARGUMENTS: - integer , intent(in) :: p ! PATCH index running over - type(canopystate_type) , intent(in) :: canopystate_inst - type(temperature_type) , intent(in) :: temperature_inst - type(waterdiagnosticbulk_type) , intent(in) :: waterdiagnosticbulk_inst - type(cnveg_state_type) , intent(inout) :: cnveg_state_inst - type(crop_type) , intent(inout) :: crop_inst - ! - ! LOCAL VARAIBLES: - real(r8) tcrown ! ? - real(r8) vd, vd1, vd2 ! vernalization dependence - real(r8) tkil ! Freeze kill threshold - integer c,g ! indices - !------------------------------------------------------------------------ - - associate( & - tlai => canopystate_inst%tlai_patch , & ! Input: [real(r8) (:) ] one-sided leaf area index, no burying by snow - - t_ref2m => temperature_inst%t_ref2m_patch , & ! Input: [real(r8) (:) ] 2 m height surface air temperature (K) - t_ref2m_min => temperature_inst%t_ref2m_min_patch , & ! Input: [real(r8) (:) ] daily minimum of average 2 m height surface air temperature (K) - t_ref2m_max => temperature_inst%t_ref2m_max_patch , & ! Input: [real(r8) (:) ] daily maximum of average 2 m height surface air temperature (K) - - snow_depth => waterdiagnosticbulk_inst%snow_depth_col , & ! Input: [real(r8) (:) ] snow height (m) - - hdidx => cnveg_state_inst%hdidx_patch , & ! Output: [real(r8) (:) ] cold hardening index? - cumvd => cnveg_state_inst%cumvd_patch , & ! Output: [real(r8) (:) ] cumulative vernalization d?ependence? - gddmaturity => cnveg_state_inst%gddmaturity_patch , & ! Output: [real(r8) (:) ] gdd needed to harvest - huigrain => cnveg_state_inst%huigrain_patch , & ! Output: [real(r8) (:) ] heat unit index needed to reach vegetative maturity - - vf => crop_inst%vf_patch & ! Output: [real(r8) (:) ] vernalization factor for cereal - ) - - c = patch%column(p) - - ! for all equations - temperatures must be in degrees (C) - ! calculate temperature of crown of crop (e.g., 3 cm soil temperature) - ! snow depth in centimeters - - if (t_ref2m(p) < tfrz) then !slevis: t_ref2m inst of td=daily avg (K) - tcrown = 2._r8 + (t_ref2m(p) - tfrz) * (0.4_r8 + 0.0018_r8 * & - (min(snow_depth(c)*100._r8, 15._r8) - 15._r8)**2) - else !slevis: snow_depth inst of adsnod=daily average (m) - tcrown = t_ref2m(p) - tfrz - end if - - ! vernalization factor calculation - ! if vf(p) = 1. then plant is fully vernalized - and thermal time - ! accumulation in phase 1 will be unaffected - ! refers to gddtsoi & gddplant, defined in the accumulation routines (slevis) - ! reset vf, cumvd, and hdidx to 0 at planting of crop (slevis) - - if (t_ref2m_max(p) > tfrz) then - if (t_ref2m_min(p) <= tfrz+15._r8) then - vd1 = 1.4_r8 - 0.0778_r8 * tcrown - vd2 = 0.5_r8 + 13.44_r8 / ((t_ref2m_max(p)-t_ref2m_min(p)+3._r8)**2) * tcrown - vd = max(0._r8, min(1._r8, vd1, vd2)) - cumvd(p) = cumvd(p) + vd - end if - - if (cumvd(p) < 10._r8 .and. t_ref2m_max(p) > tfrz+30._r8) then - cumvd(p) = cumvd(p) - 0.5_r8 * (t_ref2m_max(p) - tfrz - 30._r8) - end if - cumvd(p) = max(0._r8, cumvd(p)) ! must be > 0 - - vf(p) = 1._r8 - p1v * (50._r8 - cumvd(p)) - vf(p) = max(0._r8, min(vf(p), 1._r8)) ! must be between 0 - 1 - end if - - ! calculate cold hardening of plant - ! determines for winter cereal varieties whether the plant has completed - ! a period of cold hardening to protect it from freezing temperatures. If - ! not, then exposure could result in death or killing of plants. - - ! there are two distinct phases of hardening - - if (t_ref2m_min(p) <= tfrz-3._r8 .or. hdidx(p) /= 0._r8) then - if (hdidx(p) >= hti) then ! done with phase 1 - hdidx(p) = hdidx(p) + 0.083_r8 - hdidx(p) = min(hdidx(p), hti*2._r8) - end if - - if (t_ref2m_max(p) >= tbase + tfrz + 10._r8) then - hdidx(p) = hdidx(p) - 0.02_r8 * (t_ref2m_max(p)-tbase-tfrz-10._r8) - if (hdidx(p) > hti) hdidx(p) = hdidx(p) - 0.02_r8 * (t_ref2m_max(p)-tbase-tfrz-10._r8) - hdidx(p) = max(0._r8, hdidx(p)) - end if - - else if (tcrown >= tbase-1._r8) then - if (tcrown <= tbase+8._r8) then - hdidx(p) = hdidx(p) + 0.1_r8 - (tcrown-tbase+3.5_r8)**2 / 506._r8 - if (hdidx(p) >= hti .and. tcrown <= tbase + 0._r8) then - hdidx(p) = hdidx(p) + 0.083_r8 - hdidx(p) = min(hdidx(p), hti*2._r8) - end if - end if - - if (t_ref2m_max(p) >= tbase + tfrz + 10._r8) then - hdidx(p) = hdidx(p) - 0.02_r8 * (t_ref2m_max(p)-tbase-tfrz-10._r8) - if (hdidx(p) > hti) hdidx(p) = hdidx(p) - 0.02_r8 * (t_ref2m_max(p)-tbase-tfrz-10._r8) - hdidx(p) = max(0._r8, hdidx(p)) - end if - end if - - ! calculate what the cereal killing temperature - ! there is a linear inverse relationship between - ! hardening of the plant and the killing temperature or - ! threshold that the plant can withstand - ! when plant is fully-hardened (hdidx = 2), the killing threshold is -18 C - - ! will have to develop some type of relationship that reduces LAI and - ! biomass pools in response to cold damaged crop - - if (t_ref2m_min(p) <= tfrz - 6._r8) then - tkil = (tbase - 6._r8) - 6._r8 * hdidx(p) - if (tkil >= tcrown) then - if ((0.95_r8 - 0.02_r8 * (tcrown - tkil)**2) >= 0.02_r8) then - write (iulog,*) 'crop damaged by cold temperatures at p,c =', p,c - else if (tlai(p) > 0._r8) then ! slevis: kill if past phase1 - gddmaturity(p) = 0._r8 ! by forcing through - huigrain(p) = 0._r8 ! harvest - write (iulog,*) '95% of crop killed by cold temperatures at p,c =', p,c - end if - end if - end if - - end associate - - end subroutine vernalization - - !----------------------------------------------------------------------- - subroutine CNOnsetGrowth (num_soilp, filter_soilp, & - cnveg_state_inst, & - cnveg_carbonstate_inst, cnveg_nitrogenstate_inst, cnveg_carbonflux_inst, cnveg_nitrogenflux_inst) - ! - ! !DESCRIPTION: - ! Determines the flux of stored C and N from transfer pools to display - ! pools during the phenological onset period. - ! - ! !ARGUMENTS: - integer , intent(in) :: num_soilp ! number of soil patches in filter - integer , intent(in) :: filter_soilp(:) ! filter for soil patches - type(cnveg_state_type) , intent(in) :: cnveg_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 ! indices - integer :: fp ! lake filter patch index - real(r8):: t1 ! temporary variable - !----------------------------------------------------------------------- - - associate( & - ivt => patch%itype , & ! Input: [integer (:) ] patch vegetation type - - woody => pftcon%woody , & ! Input: binary flag for woody lifeform (1=woody, 0=not woody) - - onset_flag => cnveg_state_inst%onset_flag_patch , & ! Input: [real(r8) (:) ] onset flag - onset_counter => cnveg_state_inst%onset_counter_patch , & ! Input: [real(r8) (:) ] onset days counter - bgtr => cnveg_state_inst%bgtr_patch , & ! Input: [real(r8) (:) ] background transfer growth rate (1/s) - - 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 - - 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 - - leafc_xfer_to_leafc => cnveg_carbonflux_inst%leafc_xfer_to_leafc_patch , & ! Output: [real(r8) (:) ] - frootc_xfer_to_frootc => cnveg_carbonflux_inst%frootc_xfer_to_frootc_patch , & ! Output: [real(r8) (:) ] - livestemc_xfer_to_livestemc => cnveg_carbonflux_inst%livestemc_xfer_to_livestemc_patch , & ! Output: [real(r8) (:) ] - deadstemc_xfer_to_deadstemc => cnveg_carbonflux_inst%deadstemc_xfer_to_deadstemc_patch , & ! Output: [real(r8) (:) ] - livecrootc_xfer_to_livecrootc => cnveg_carbonflux_inst%livecrootc_xfer_to_livecrootc_patch , & ! Output: [real(r8) (:) ] - deadcrootc_xfer_to_deadcrootc => cnveg_carbonflux_inst%deadcrootc_xfer_to_deadcrootc_patch , & ! Output: [real(r8) (:) ] - - leafn_xfer_to_leafn => cnveg_nitrogenflux_inst%leafn_xfer_to_leafn_patch , & ! Output: [real(r8) (:) ] - frootn_xfer_to_frootn => cnveg_nitrogenflux_inst%frootn_xfer_to_frootn_patch , & ! Output: [real(r8) (:) ] - livestemn_xfer_to_livestemn => cnveg_nitrogenflux_inst%livestemn_xfer_to_livestemn_patch , & ! Output: [real(r8) (:) ] - deadstemn_xfer_to_deadstemn => cnveg_nitrogenflux_inst%deadstemn_xfer_to_deadstemn_patch , & ! Output: [real(r8) (:) ] - livecrootn_xfer_to_livecrootn => cnveg_nitrogenflux_inst%livecrootn_xfer_to_livecrootn_patch , & ! Output: [real(r8) (:) ] - deadcrootn_xfer_to_deadcrootn => cnveg_nitrogenflux_inst%deadcrootn_xfer_to_deadcrootn_patch & ! Output: [real(r8) (:) ] - ) - - ! patch loop - do fp = 1,num_soilp - p = filter_soilp(fp) - - ! only calculate these fluxes during onset period - if (onset_flag(p) == 1._r8) then - - ! The transfer rate is a linearly decreasing function of time, - ! going to zero on the last timestep of the onset period - - if (onset_counter(p) == dt) then - t1 = 1.0_r8 / dt - else - t1 = 2.0_r8 / (onset_counter(p)) - end if - leafc_xfer_to_leafc(p) = t1 * leafc_xfer(p) - frootc_xfer_to_frootc(p) = t1 * frootc_xfer(p) - leafn_xfer_to_leafn(p) = t1 * leafn_xfer(p) - frootn_xfer_to_frootn(p) = t1 * frootn_xfer(p) - if (woody(ivt(p)) == 1.0_r8) then - livestemc_xfer_to_livestemc(p) = t1 * livestemc_xfer(p) - deadstemc_xfer_to_deadstemc(p) = t1 * deadstemc_xfer(p) - livecrootc_xfer_to_livecrootc(p) = t1 * livecrootc_xfer(p) - deadcrootc_xfer_to_deadcrootc(p) = t1 * deadcrootc_xfer(p) - livestemn_xfer_to_livestemn(p) = t1 * livestemn_xfer(p) - deadstemn_xfer_to_deadstemn(p) = t1 * deadstemn_xfer(p) - livecrootn_xfer_to_livecrootn(p) = t1 * livecrootn_xfer(p) - deadcrootn_xfer_to_deadcrootn(p) = t1 * deadcrootn_xfer(p) - end if - - end if ! end if onset period - - ! calculate the background rate of transfer growth (used for stress - ! deciduous algorithm). In this case, all of the mass in the transfer - ! pools should be moved to displayed growth in each timestep. - - if (bgtr(p) > 0._r8) then - leafc_xfer_to_leafc(p) = leafc_xfer(p) / dt - frootc_xfer_to_frootc(p) = frootc_xfer(p) / dt - leafn_xfer_to_leafn(p) = leafn_xfer(p) / dt - frootn_xfer_to_frootn(p) = frootn_xfer(p) / dt - if (woody(ivt(p)) == 1.0_r8) then - livestemc_xfer_to_livestemc(p) = livestemc_xfer(p) / dt - deadstemc_xfer_to_deadstemc(p) = deadstemc_xfer(p) / dt - livecrootc_xfer_to_livecrootc(p) = livecrootc_xfer(p) / dt - deadcrootc_xfer_to_deadcrootc(p) = deadcrootc_xfer(p) / dt - livestemn_xfer_to_livestemn(p) = livestemn_xfer(p) / dt - deadstemn_xfer_to_deadstemn(p) = deadstemn_xfer(p) / dt - livecrootn_xfer_to_livecrootn(p) = livecrootn_xfer(p) / dt - deadcrootn_xfer_to_deadcrootn(p) = deadcrootn_xfer(p) / dt - end if - end if ! end if bgtr - - end do ! end patch loop - - end associate - - end subroutine CNOnsetGrowth - - !----------------------------------------------------------------------- - subroutine CNOffsetLitterfall (num_soilp, filter_soilp, & - cnveg_state_inst, cnveg_carbonstate_inst, cnveg_nitrogenstate_inst, cnveg_carbonflux_inst, cnveg_nitrogenflux_inst) - ! - ! !DESCRIPTION: - ! Determines the flux of C and N from displayed pools to litter - ! pools during the phenological offset period. - ! - ! !USES: - use pftconMod , only : npcropmin - ! Y. Cheng - use pftconMod , only : nmiscanthus, nirrig_miscanthus, nswitchgrass, nirrig_switchgrass - - use CNSharedParamsMod, only : use_fun - use clm_varctl , only : CNratio_floating - ! - ! !ARGUMENTS: - integer , intent(in) :: num_soilp ! number of soil patches in filter - integer , intent(in) :: filter_soilp(:) ! filter for soil patches - type(cnveg_state_type) , intent(inout) :: cnveg_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, c ! indices - integer :: fp ! lake filter patch index - real(r8):: t1 ! temporary variable - real(r8):: denom ! temporary variable for divisor - real(r8) :: ntovr_leaf - real(r8) :: fr_leafn_to_litter ! fraction of the nitrogen turnover that goes to litter; remaining fraction is retranslocated - !----------------------------------------------------------------------- - - associate( & - ivt => patch%itype , & ! Input: [integer (:) ] patch vegetation type - - leafcn => pftcon%leafcn , & ! Input: leaf C:N (gC/gN) - - ! Y. Cheng, add a new cut fraction for harvest parameter for bioenergy crops (miscanthus and switchgrass) - harvfrac => pftcon%harvfrac , & ! Input: cut fraction for harvest (-) - - lflitcn => pftcon%lflitcn , & ! Input: leaf litter C:N (gC/gN) - frootcn => pftcon%frootcn , & ! Input: fine root C:N (gC/gN) - graincn => pftcon%graincn , & ! Input: grain C:N (gC/gN) - - offset_flag => cnveg_state_inst%offset_flag_patch , & ! Input: [real(r8) (:) ] offset flag - offset_counter => cnveg_state_inst%offset_counter_patch , & ! Input: [real(r8) (:) ] offset days counter - - 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 - grainc => cnveg_carbonstate_inst%grainc_patch , & ! Input: [real(r8) (:) ] (gC/m2) grain C - cropseedc_deficit => cnveg_carbonstate_inst%cropseedc_deficit_patch , & ! Input: [real(r8) (:) ] (gC/m2) crop seed C deficit - livestemc => cnveg_carbonstate_inst%livestemc_patch , & ! Input: [real(r8) (:) ] (gC/m2) livestem C - cropseedn_deficit => cnveg_nitrogenstate_inst%cropseedn_deficit_patch , & ! Input: [real(r8) (:) ] (gC/m2) crop seed N deficit - livestemn => cnveg_nitrogenstate_inst%livestemn_patch , & ! Input: [real(r8) (:) ] (gN/m2) livestem N - - cpool_to_grainc => cnveg_carbonflux_inst%cpool_to_grainc_patch , & ! Input: [real(r8) (:) ] allocation to grain C (gC/m2/s) - npool_to_grainn => cnveg_nitrogenflux_inst%npool_to_grainn_patch , & ! Input: [real(r8) (:) ] allocation to grain N (gN/m2/s) - grainn => cnveg_nitrogenstate_inst%grainn_patch , & ! Input: [real(r8) (:) ] (kgN/m2) grain N - cpool_to_livestemc => cnveg_carbonflux_inst%cpool_to_livestemc_patch , & ! Input: [real(r8) (:) ] allocation to live stem C (gC/m2/s) - cpool_to_leafc => cnveg_carbonflux_inst%cpool_to_leafc_patch , & ! Input: [real(r8) (:) ] allocation to leaf C (gC/m2/s) - cpool_to_frootc => cnveg_carbonflux_inst%cpool_to_frootc_patch , & ! Input: [real(r8) (:) ] allocation to fine root C (gC/m2/s) - prev_leafc_to_litter => cnveg_carbonflux_inst%prev_leafc_to_litter_patch , & ! Output: [real(r8) (:) ] previous timestep leaf C litterfall flux (gC/m2/s) - prev_frootc_to_litter => cnveg_carbonflux_inst%prev_frootc_to_litter_patch , & ! Output: [real(r8) (:) ] previous timestep froot C litterfall flux (gC/m2/s) - leafc_to_litter => cnveg_carbonflux_inst%leafc_to_litter_patch , & ! Output: [real(r8) (:) ] leaf C litterfall (gC/m2/s) - frootc_to_litter => cnveg_carbonflux_inst%frootc_to_litter_patch , & ! Output: [real(r8) (:) ] fine root C litterfall (gC/m2/s) - livestemc_to_litter => cnveg_carbonflux_inst%livestemc_to_litter_patch , & ! Output: [real(r8) (:) ] live stem C litterfall (gC/m2/s) - grainc_to_food => cnveg_carbonflux_inst%grainc_to_food_patch , & ! Output: [real(r8) (:) ] grain C to food (gC/m2/s) - - ! Y. Cheng, put the cut fraction during offset period for bioenergy crops to this biofuelc_harvest flux - biofuelc_harvest => cnveg_carbonflux_inst%biofuelc_harvest_patch , & ! Output: [real(r8) (:) ] biofuel C that was cutted at harvest (gC/m2/s) - - grainc_to_seed => cnveg_carbonflux_inst%grainc_to_seed_patch , & ! Output: [real(r8) (:) ] grain C to seed (gC/m2/s) - 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_to_litter => cnveg_nitrogenflux_inst%livestemn_to_litter_patch , & ! Output: [real(r8) (:) ] livestem N to litter (gN/m2/s) - grainn_to_food => cnveg_nitrogenflux_inst%grainn_to_food_patch , & ! Output: [real(r8) (:) ] grain N to food (gN/m2/s) - biofueln_harvest => cnveg_nitrogenflux_inst%biofueln_harvest_patch , & ! Output: [real(r8) (:) ] biofuel N that was cutted (gC/m2/s) - grainn_to_seed => cnveg_nitrogenflux_inst%grainn_to_seed_patch , & ! Output: [real(r8) (:) ] grain N to seed (gN/m2/s) - leafn_to_litter => cnveg_nitrogenflux_inst%leafn_to_litter_patch , & ! Output: [real(r8) (:) ] leaf N litterfall (gN/m2/s) - leafn_to_retransn => cnveg_nitrogenflux_inst%leafn_to_retransn_patch , & ! Input: [real(r8) (:) ] leaf N to retranslocated N pool (gN/m2/s) - free_retransn_to_npool=> cnveg_nitrogenflux_inst%free_retransn_to_npool_patch , & ! Input: [real(r8) (:) ] free leaf N to retranslocated N pool (gN/m2/s) - paid_retransn_to_npool=> cnveg_nitrogenflux_inst%retransn_to_npool_patch, & ! Input: [real(r8) (:) ] free leaf N to retranslocated N pool (gN/m2/s) - frootn_to_litter => cnveg_nitrogenflux_inst%frootn_to_litter_patch , & ! Output: [real(r8) (:) ] fine root N litterfall (gN/m2/s) - leafc_to_litter_fun => cnveg_carbonflux_inst%leafc_to_litter_fun_patch , & ! Output: [real(r8) (:) ] leaf C litterfall used by FUN (gC/m2/s) - leafcn_offset => cnveg_state_inst%leafcn_offset_patch & ! Output: [real(r8) (:) ] Leaf C:N used by FUN - ) - - ! The litterfall transfer rate starts at 0.0 and increases linearly - ! over time, with displayed growth going to 0.0 on the last day of litterfall - - do fp = 1,num_soilp - p = filter_soilp(fp) - - ! only calculate fluxes during offset period - if (offset_flag(p) == 1._r8) then - - if (offset_counter(p) == dt) then - t1 = 1.0_r8 / dt - frootc_to_litter(p) = t1 * frootc(p) + cpool_to_frootc(p) - - ! Cut a certain fraction (i.e., harvfrac(ivt(p))) (e.g., harvfrac(ivt(p)=70% for bioenergy crops) of leafc for harvest - ! and move this cut fration to the biofuelc_harvest flux, rather than move it to litter - leafc_to_litter(p) = t1 * leafc(p)*(1._r8-harvfrac(ivt(p))) + cpool_to_leafc(p) - biofuelc_harvest(p) = t1 * leafc(p) * harvfrac(ivt(p)) - biofueln_harvest(p) = t1 * leafn(p) * harvfrac(ivt(p)) - - ! this assumes that offset_counter == dt for crops - ! if this were ever changed, we'd need to add code to the "else" - if (ivt(p) >= npcropmin) then - ! Replenish the seed deficits from grain, if there is enough - ! available grain. (If there is not enough available grain, the seed - ! deficits will accumulate until there is eventually enough grain to - ! replenish them.) - grainc_to_seed(p) = t1 * min(-cropseedc_deficit(p), grainc(p)) - grainn_to_seed(p) = t1 * min(-cropseedn_deficit(p), grainn(p)) - ! Send the remaining grain to the food product pool - grainc_to_food(p) = t1 * grainc(p) + cpool_to_grainc(p) - grainc_to_seed(p) - grainn_to_food(p) = t1 * grainn(p) + npool_to_grainn(p) - grainn_to_seed(p) - - livestemc_to_litter(p) = t1 * livestemc(p) + cpool_to_livestemc(p) - end if - else - t1 = dt * 2.0_r8 / (offset_counter(p) * offset_counter(p)) - leafc_to_litter(p) = prev_leafc_to_litter(p) + t1*(leafc(p) - prev_leafc_to_litter(p)*offset_counter(p)) - frootc_to_litter(p) = prev_frootc_to_litter(p) + t1*(frootc(p) - prev_frootc_to_litter(p)*offset_counter(p)) - - end if - - if ( use_fun ) then - if(leafc_to_litter(p)*dt.gt.leafc(p))then - leafc_to_litter(p) = leafc(p)/dt + cpool_to_leafc(p) - endif - if(frootc_to_litter(p)*dt.gt.frootc(p))then - frootc_to_litter(p) = frootc(p)/dt + cpool_to_frootc(p) - endif - end if - - - if ( use_fun ) then - leafc_to_litter_fun(p) = leafc_to_litter(p) - leafn_to_retransn(p) = paid_retransn_to_npool(p) + free_retransn_to_npool(p) - if (leafn(p).gt.0._r8) then - if (leafn(p)-leafn_to_retransn(p)*dt.gt.0._r8) then - leafcn_offset(p) = leafc(p)/(leafn(p)-leafn_to_retransn(p)*dt) - else - leafcn_offset(p) = leafc(p)/leafn(p) - end if - else - leafcn_offset(p) = leafcn(ivt(p)) - end if - leafn_to_litter(p) = leafc_to_litter(p)/leafcn_offset(p) - leafn_to_retransn(p) - leafn_to_litter(p) = max(leafn_to_litter(p),0._r8) - - denom = ( leafn_to_retransn(p) + leafn_to_litter(p) ) - if ( denom /= 0.0_r8 ) then - fr_leafn_to_litter = leafn_to_litter(p) / ( leafn_to_retransn(p) + leafn_to_litter(p) ) - else if ( leafn_to_litter(p) == 0.0_r8 ) then - fr_leafn_to_litter = 0.0_r8 - else - fr_leafn_to_litter = 1.0_r8 - end if - - else - if (CNratio_floating .eqv. .true.) then - fr_leafn_to_litter = 0.5_r8 ! assuming 50% of nitrogen turnover goes to litter - end if - ! calculate the leaf N litterfall and retranslocation - leafn_to_litter(p) = leafc_to_litter(p) / lflitcn(ivt(p)) - leafn_to_retransn(p) = (leafc_to_litter(p) / leafcn(ivt(p))) - leafn_to_litter(p) - - end if - - ! calculate fine root N litterfall (no retranslocation of fine root N) - frootn_to_litter(p) = frootc_to_litter(p) / frootcn(ivt(p)) - - if (CNratio_floating .eqv. .true.) then - if (leafc(p) == 0.0_r8) then - ntovr_leaf = 0.0_r8 - else - ntovr_leaf = leafc_to_litter(p) * (leafn(p) / leafc(p)) - end if - - leafn_to_litter(p) = fr_leafn_to_litter * ntovr_leaf - leafn_to_retransn(p) = ntovr_leaf - leafn_to_litter(p) - if (frootc(p) == 0.0_r8) then - frootn_to_litter(p) = 0.0_r8 - else - frootn_to_litter(p) = frootc_to_litter(p) * (frootn(p) / frootc(p)) - end if - end if - - if ( use_fun ) then - if(frootn_to_litter(p)*dt.gt.frootn(p))then - frootn_to_litter(p) = frootn(p)/dt - endif - end if - - if (ivt(p) >= npcropmin) then - ! NOTE(slevis, 2014-12) results in -ve livestemn and -ve totpftn - !X! livestemn_to_litter(p) = livestemc_to_litter(p) / livewdcn(ivt(p)) - ! NOTE(slevis, 2014-12) Beth Drewniak suggested this instead - livestemn_to_litter(p) = livestemn(p) / dt - end if - - ! save the current litterfall fluxes - prev_leafc_to_litter(p) = leafc_to_litter(p) - prev_frootc_to_litter(p) = frootc_to_litter(p) - - end if ! end if offset period - - end do ! end patch loop - - end associate - - end subroutine CNOffsetLitterfall - - !----------------------------------------------------------------------- - subroutine CNBackgroundLitterfall (num_soilp, filter_soilp, & - cnveg_state_inst, cnveg_carbonstate_inst, cnveg_nitrogenstate_inst, cnveg_carbonflux_inst, cnveg_nitrogenflux_inst) - ! - ! !DESCRIPTION: - ! Determines the flux of C and N from displayed pools to litter - ! pools as the result of background litter fall. - ! - ! !USES: - use CNSharedParamsMod , only : use_fun - use clm_varctl , only : CNratio_floating - ! !ARGUMENTS: - implicit none - integer , intent(in) :: num_soilp ! number of soil patches in filter - integer , intent(in) :: filter_soilp(:) ! filter for soil patches - type(cnveg_state_type) , intent(inout) :: cnveg_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 ! indices - integer :: fp ! lake filter patch index - real(r8) :: fr_leafn_to_litter ! fraction of the nitrogen turnover that goes to litter; remaining fraction is retranslocated - real(r8) :: ntovr_leaf - real(r8) :: denom - !----------------------------------------------------------------------- - - associate( & - ivt => patch%itype , & ! Input: [integer (:) ] patch vegetation type - - leafcn => pftcon%leafcn , & ! Input: leaf C:N (gC/gN) - lflitcn => pftcon%lflitcn , & ! Input: leaf litter C:N (gC/gN) - frootcn => pftcon%frootcn , & ! Input: fine root C:N (gC/gN) - - bglfr => cnveg_state_inst%bglfr_patch , & ! Input: [real(r8) (:) ] background litterfall rate (1/s) - - 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 - - leafc_to_litter => cnveg_carbonflux_inst%leafc_to_litter_patch , & ! Output: [real(r8) (:) ] - frootc_to_litter => cnveg_carbonflux_inst%frootc_to_litter_patch , & ! Output: [real(r8) (:) ] - - 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 - leafn_to_litter => cnveg_nitrogenflux_inst%leafn_to_litter_patch , & ! Output: [real(r8) (:) ] - leafn_to_retransn => cnveg_nitrogenflux_inst%leafn_to_retransn_patch , & ! Output: [real(r8) (:) ] - frootn_to_litter => cnveg_nitrogenflux_inst%frootn_to_litter_patch , & ! Output: [real(r8) (:) ] - leafc_to_litter_fun => cnveg_carbonflux_inst%leafc_to_litter_fun_patch, & ! Output: [real(r8) (:) ] leaf C litterfall used by FUN (gC/m2/s) - leafcn_offset => cnveg_state_inst%leafcn_offset_patch , & ! Output: [real(r8) (:) ] Leaf C:N used by FUN - free_retransn_to_npool=> cnveg_nitrogenflux_inst%free_retransn_to_npool_patch , & ! Input: [real(r8) (:) ] free leaf N to retranslocated N pool (gN/m2/s) - paid_retransn_to_npool=> cnveg_nitrogenflux_inst%retransn_to_npool_patch & ! Input: [real(r8) (:) ] free leaf N to retranslocated N pool (gN/m2/s) - ) - - ! patch loop - do fp = 1,num_soilp - p = filter_soilp(fp) - - ! only calculate these fluxes if the background litterfall rate is non-zero - if (bglfr(p) > 0._r8) then - ! units for bglfr are already 1/s - leafc_to_litter(p) = bglfr(p) * leafc(p) - frootc_to_litter(p) = bglfr(p) * frootc(p) - if ( use_fun ) then - leafc_to_litter_fun(p) = leafc_to_litter(p) - leafn_to_retransn(p) = paid_retransn_to_npool(p) + free_retransn_to_npool(p) - if (leafn(p).gt.0._r8) then - if (leafn(p)-leafn_to_retransn(p)*dt.gt.0._r8) then - leafcn_offset(p) = leafc(p)/(leafn(p)-leafn_to_retransn(p)*dt) - else - leafcn_offset(p) = leafc(p)/leafn(p) - end if - else - leafcn_offset(p) = leafcn(ivt(p)) - end if - leafn_to_litter(p) = leafc_to_litter(p)/leafcn_offset(p) - leafn_to_retransn(p) - leafn_to_litter(p) = max(leafn_to_litter(p),0._r8) - - denom = ( leafn_to_retransn(p) + leafn_to_litter(p) ) - if ( denom /= 0.0_r8 ) then - fr_leafn_to_litter = leafn_to_litter(p) / ( leafn_to_retransn(p) + leafn_to_litter(p) ) - else if ( leafn_to_litter(p) == 0.0_r8 ) then - fr_leafn_to_litter = 0.0_r8 - else - fr_leafn_to_litter = 1.0_r8 - end if - - - else - if (CNratio_floating .eqv. .true.) then - fr_leafn_to_litter = 0.5_r8 ! assuming 50% of nitrogen turnover goes to litter - end if - ! calculate the leaf N litterfall and retranslocation - leafn_to_litter(p) = leafc_to_litter(p) / lflitcn(ivt(p)) - leafn_to_retransn(p) = (leafc_to_litter(p) / leafcn(ivt(p))) - leafn_to_litter(p) - - end if - - ! calculate fine root N litterfall (no retranslocation of fine root N) - frootn_to_litter(p) = frootc_to_litter(p) / frootcn(ivt(p)) - - if (CNratio_floating .eqv. .true.) then - if (leafc(p) == 0.0_r8) then - ntovr_leaf = 0.0_r8 - else - ntovr_leaf = leafc_to_litter(p) * (leafn(p) / leafc(p)) - end if - - leafn_to_litter(p) = fr_leafn_to_litter * ntovr_leaf - leafn_to_retransn(p) = ntovr_leaf - leafn_to_litter(p) - if (frootc(p) == 0.0_r8) then - frootn_to_litter(p) = 0.0_r8 - else - frootn_to_litter(p) = frootc_to_litter(p) * (frootn(p) / frootc(p)) - end if - end if - - if ( use_fun ) then - if(frootn_to_litter(p)*dt.gt.frootn(p))then - frootn_to_litter(p) = frootn(p)/dt - endif - end if - - end if - - end do - - end associate - - end subroutine CNBackgroundLitterfall - - !----------------------------------------------------------------------- - subroutine CNLivewoodTurnover (num_soilp, filter_soilp, & - cnveg_carbonstate_inst, cnveg_nitrogenstate_inst, cnveg_carbonflux_inst, cnveg_nitrogenflux_inst) - ! - ! !DESCRIPTION: - ! Determines the flux of C and N from live wood to - ! dead wood pools, for stem and coarse root. - ! - use CNSharedParamsMod, only: use_fun - use clm_varctl , only : CNratio_floating - ! !ARGUMENTS: - integer , intent(in) :: num_soilp ! number of soil patches in filter - integer , intent(in) :: filter_soilp(:) ! filter for soil patches - 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 ! indices - integer :: fp ! lake filter patch index - real(r8):: ctovr ! temporary variable for carbon turnover - real(r8):: ntovr ! temporary variable for nitrogen turnover - !----------------------------------------------------------------------- - - associate( & - ivt => patch%itype , & ! Input: [integer (:) ] patch vegetation type - - woody => pftcon%woody , & ! Input: binary flag for woody lifeform (1=woody, 0=not woody) - livewdcn => pftcon%livewdcn , & ! Input: live wood (phloem and ray parenchyma) C:N (gC/gN) - deadwdcn => pftcon%deadwdcn , & ! Input: dead wood (xylem and heartwood) C:N (gC/gN) - - livestemc => cnveg_carbonstate_inst%livestemc_patch , & ! Input: [real(r8) (:) ] (gC/m2) live stem C - livecrootc => cnveg_carbonstate_inst%livecrootc_patch , & ! Input: [real(r8) (:) ] (gC/m2) live coarse root C - - livestemn => cnveg_nitrogenstate_inst%livestemn_patch , & ! Input: [real(r8) (:) ] (gN/m2) live stem N - livecrootn => cnveg_nitrogenstate_inst%livecrootn_patch , & ! Input: [real(r8) (:) ] (gN/m2) live coarse root N - - livestemc_to_deadstemc => cnveg_carbonflux_inst%livestemc_to_deadstemc_patch , & ! Output: [real(r8) (:) ] - livecrootc_to_deadcrootc => cnveg_carbonflux_inst%livecrootc_to_deadcrootc_patch , & ! Output: [real(r8) (:) ] - - livestemn_to_deadstemn => cnveg_nitrogenflux_inst%livestemn_to_deadstemn_patch , & ! Output: [real(r8) (:) ] - livestemn_to_retransn => cnveg_nitrogenflux_inst%livestemn_to_retransn_patch , & ! Output: [real(r8) (:) ] - livecrootn_to_deadcrootn => cnveg_nitrogenflux_inst%livecrootn_to_deadcrootn_patch , & ! Output: [real(r8) (:) ] - livecrootn_to_retransn => cnveg_nitrogenflux_inst%livecrootn_to_retransn_patch & ! Output: [real(r8) (:) ] - ) - - - - ! patch loop - do fp = 1,num_soilp - p = filter_soilp(fp) - - ! only calculate these fluxes for woody types - if (woody(ivt(p)) > 0._r8) then - - ! live stem to dead stem turnover - - ctovr = livestemc(p) * lwtop - ntovr = ctovr / livewdcn(ivt(p)) - livestemc_to_deadstemc(p) = ctovr - livestemn_to_deadstemn(p) = ctovr / deadwdcn(ivt(p)) - - if (CNratio_floating .eqv. .true.) then - if (livestemc(p) == 0.0_r8) then - ntovr = 0.0_r8 - else - ntovr = ctovr * (livestemn(p) / livestemc(p)) - end if - - livestemn_to_deadstemn(p) = 0.5_r8 * ntovr ! assuming 50% goes to deadstemn - end if - - livestemn_to_retransn(p) = ntovr - livestemn_to_deadstemn(p) - - ! live coarse root to dead coarse root turnover - - ctovr = livecrootc(p) * lwtop - ntovr = ctovr / livewdcn(ivt(p)) - livecrootc_to_deadcrootc(p) = ctovr - livecrootn_to_deadcrootn(p) = ctovr / deadwdcn(ivt(p)) - - if (CNratio_floating .eqv. .true.) then - if (livecrootc(p) == 0.0_r8) then - ntovr = 0.0_r8 - else - ntovr = ctovr * (livecrootn(p) / livecrootc(p)) - end if - - livecrootn_to_deadcrootn(p) = 0.5_r8 * ntovr ! assuming 50% goes to deadstemn - end if - - livecrootn_to_retransn(p) = ntovr - livecrootn_to_deadcrootn(p) - if(use_fun)then - !TURNED OFF FLUXES TO CORRECT N ACCUMULATION ISSUE. RF. Oct 2015. - livecrootn_to_retransn(p) = 0.0_r8 - livestemn_to_retransn(p) = 0.0_r8 - endif - - end if - - end do - - end associate - - end subroutine CNLivewoodTurnover - - !----------------------------------------------------------------------- - subroutine CNGrainToProductPools(bounds, num_soilp, filter_soilp, num_soilc, filter_soilc, & - cnveg_carbonflux_inst, cnveg_nitrogenflux_inst) - ! - ! !DESCRIPTION: - ! If using prognostic crop along with use_grainproduct, then move the patch-level - ! grain-to-food fluxes into the column-level grain-to-cropprod fluxes - ! - ! !USES: - use clm_varctl , only : use_crop - use clm_varctl , only : use_grainproduct - use subgridAveMod , only : p2c - ! - ! !ARGUMENTS: - type(bounds_type) , intent(in) :: bounds - integer , intent(in) :: num_soilp ! number of soil patches in filter - integer , intent(in) :: filter_soilp(:) ! filter for soil patches - integer , intent(in) :: num_soilc ! number of soil columns in filter - integer , intent(in) :: filter_soilc(:) ! filter for soil columns - type(cnveg_carbonflux_type) , intent(inout) :: cnveg_carbonflux_inst - type(cnveg_nitrogenflux_type) , intent(inout) :: cnveg_nitrogenflux_inst - ! - ! !LOCAL VARIABLES: - integer :: fp, p - - character(len=*), parameter :: subname = 'CNGrainToProductPools' - !----------------------------------------------------------------------- - - ! Explicitly checking use_crop is probably unnecessary here (because presumably - ! use_grainproduct is only true if use_crop is true), but we do it for safety because - ! the grain*_to_food_patch fluxes are not set if use_crop is false. - if (use_crop .and. use_grainproduct) then - do fp = 1, num_soilp - p = filter_soilp(fp) - cnveg_carbonflux_inst%grainc_to_cropprodc_patch(p) = & - cnveg_carbonflux_inst%grainc_to_food_patch(p) - cnveg_nitrogenflux_inst%grainn_to_cropprodn_patch(p) = & - cnveg_nitrogenflux_inst%grainn_to_food_patch(p) - end do - - call p2c (bounds, num_soilc, filter_soilc, & - cnveg_carbonflux_inst%grainc_to_cropprodc_patch(bounds%begp:bounds%endp), & - cnveg_carbonflux_inst%grainc_to_cropprodc_col(bounds%begc:bounds%endc)) - - call p2c (bounds, num_soilc, filter_soilc, & - cnveg_nitrogenflux_inst%grainn_to_cropprodn_patch(bounds%begp:bounds%endp), & - cnveg_nitrogenflux_inst%grainn_to_cropprodn_col(bounds%begc:bounds%endc)) - end if - - ! No else clause: if use_grainproduct is false, then the grain*_to_cropprod fluxes - ! will remain at their initial value (0). - - end subroutine CNGrainToProductPools - - !----------------------------------------------------------------------- - subroutine CNLitterToColumn (bounds, num_soilc, filter_soilc, & - cnveg_state_inst,cnveg_carbonflux_inst, cnveg_nitrogenflux_inst, & - leaf_prof_patch, froot_prof_patch) - ! - ! !DESCRIPTION: - ! called at the end of cn_phenology to gather all patch-level litterfall fluxes - ! to the column level and assign them to the three litter pools - ! - ! !USES: - use clm_varpar , only : max_patch_per_col, nlevdecomp - use pftconMod , only : npcropmin - use clm_varctl , only : use_grainproduct - ! - ! !ARGUMENTS: - type(bounds_type) , intent(in) :: bounds - integer , intent(in) :: num_soilc ! number of soil columns in filter - integer , intent(in) :: filter_soilc(:) ! filter for soil columns - type(cnveg_state_type) , intent(in) :: cnveg_state_inst - type(cnveg_carbonflux_type) , intent(inout) :: cnveg_carbonflux_inst - type(cnveg_nitrogenflux_type) , intent(inout) :: cnveg_nitrogenflux_inst - real(r8) , intent(in) :: leaf_prof_patch(bounds%begp:,1:) - real(r8) , intent(in) :: froot_prof_patch(bounds%begp:,1:) - ! - ! !LOCAL VARIABLES: - integer :: fc,c,pi,p,j ! indices - !----------------------------------------------------------------------- - - SHR_ASSERT_ALL_FL((ubound(leaf_prof_patch) == (/bounds%endp,nlevdecomp_full/)), sourcefile, __LINE__) - SHR_ASSERT_ALL_FL((ubound(froot_prof_patch) == (/bounds%endp,nlevdecomp_full/)), sourcefile, __LINE__) - - associate( & - leaf_prof => leaf_prof_patch , & ! Input: [real(r8) (:,:) ] (1/m) profile of leaves - froot_prof => froot_prof_patch , & ! Input: [real(r8) (:,:) ] (1/m) profile of fine roots - - ivt => patch%itype , & ! Input: [integer (:) ] patch vegetation type - wtcol => patch%wtcol , & ! Input: [real(r8) (:) ] weight (relative to column) for this patch (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 - - leafc_to_litter => cnveg_carbonflux_inst%leafc_to_litter_patch , & ! Input: [real(r8) (:) ] leaf C litterfall (gC/m2/s) - frootc_to_litter => cnveg_carbonflux_inst%frootc_to_litter_patch , & ! Input: [real(r8) (:) ] fine root N litterfall (gN/m2/s) - livestemc_to_litter => cnveg_carbonflux_inst%livestemc_to_litter_patch , & ! Input: [real(r8) (:) ] live stem C litterfall (gC/m2/s) - grainc_to_food => cnveg_carbonflux_inst%grainc_to_food_patch , & ! Input: [real(r8) (:) ] grain C to food (gC/m2/s) - - biofuelc_harvest => cnveg_carbonflux_inst%biofuelc_harvest_patch , & ! Input: [real(r8) (:) ] biofuel C (gC/m2/s) - - phenology_c_to_litr_met_c => cnveg_carbonflux_inst%phenology_c_to_litr_met_c_col , & ! Output: [real(r8) (:,:) ] C fluxes associated with phenology (litterfall and crop) to litter metabolic pool (gC/m3/s) - phenology_c_to_litr_cel_c => cnveg_carbonflux_inst%phenology_c_to_litr_cel_c_col , & ! Output: [real(r8) (:,:) ] C fluxes associated with phenology (litterfall and crop) to litter cellulose pool (gC/m3/s) - phenology_c_to_litr_lig_c => cnveg_carbonflux_inst%phenology_c_to_litr_lig_c_col , & ! Output: [real(r8) (:,:) ] C fluxes associated with phenology (litterfall and crop) to litter lignin pool (gC/m3/s) - - livestemn_to_litter => cnveg_nitrogenflux_inst%livestemn_to_litter_patch , & ! Input: [real(r8) (:) ] livestem N to litter (gN/m2/s) - grainn_to_food => cnveg_nitrogenflux_inst%grainn_to_food_patch , & ! Input: [real(r8) (:) ] grain N to food (gN/m2/s) - biofueln_harvest => cnveg_nitrogenflux_inst%biofueln_harvest_patch , & ! Input: [real(r8) (:) ] biofuel N (gN/m2/s) - leafn_to_litter => cnveg_nitrogenflux_inst%leafn_to_litter_patch , & ! Input: [real(r8) (:) ] leaf N litterfall (gN/m2/s) - frootn_to_litter => cnveg_nitrogenflux_inst%frootn_to_litter_patch , & ! Input: [real(r8) (:) ] fine root N litterfall (gN/m2/s) - phenology_n_to_litr_met_n => cnveg_nitrogenflux_inst%phenology_n_to_litr_met_n_col , & ! Output: [real(r8) (:,:) ] N fluxes associated with phenology (litterfall and crop) to litter metabolic pool (gN/m3/s) - phenology_n_to_litr_cel_n => cnveg_nitrogenflux_inst%phenology_n_to_litr_cel_n_col , & ! Output: [real(r8) (:,:) ] N fluxes associated with phenology (litterfall and crop) to litter cellulose pool (gN/m3/s) - phenology_n_to_litr_lig_n => cnveg_nitrogenflux_inst%phenology_n_to_litr_lig_n_col & ! Output: [real(r8) (:,:) ] N fluxes associated with phenology (litterfall and crop) to litter lignin pool (gN/m3/s) - ) - - do j = 1, nlevdecomp - do pi = 1,max_patch_per_col - 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 litter carbon fluxes - phenology_c_to_litr_met_c(c,j) = phenology_c_to_litr_met_c(c,j) & - + leafc_to_litter(p) * lf_flab(ivt(p)) * wtcol(p) * leaf_prof(p,j) - phenology_c_to_litr_cel_c(c,j) = phenology_c_to_litr_cel_c(c,j) & - + leafc_to_litter(p) * lf_fcel(ivt(p)) * wtcol(p) * leaf_prof(p,j) - phenology_c_to_litr_lig_c(c,j) = phenology_c_to_litr_lig_c(c,j) & - + leafc_to_litter(p) * lf_flig(ivt(p)) * wtcol(p) * leaf_prof(p,j) - - ! leaf litter nitrogen fluxes - phenology_n_to_litr_met_n(c,j) = phenology_n_to_litr_met_n(c,j) & - + leafn_to_litter(p) * lf_flab(ivt(p)) * wtcol(p) * leaf_prof(p,j) - phenology_n_to_litr_cel_n(c,j) = phenology_n_to_litr_cel_n(c,j) & - + leafn_to_litter(p) * lf_fcel(ivt(p)) * wtcol(p) * leaf_prof(p,j) - phenology_n_to_litr_lig_n(c,j) = phenology_n_to_litr_lig_n(c,j) & - + leafn_to_litter(p) * lf_flig(ivt(p)) * wtcol(p) * leaf_prof(p,j) - - ! fine root litter carbon fluxes - phenology_c_to_litr_met_c(c,j) = phenology_c_to_litr_met_c(c,j) & - + frootc_to_litter(p) * fr_flab(ivt(p)) * wtcol(p) * froot_prof(p,j) - phenology_c_to_litr_cel_c(c,j) = phenology_c_to_litr_cel_c(c,j) & - + frootc_to_litter(p) * fr_fcel(ivt(p)) * wtcol(p) * froot_prof(p,j) - phenology_c_to_litr_lig_c(c,j) = phenology_c_to_litr_lig_c(c,j) & - + frootc_to_litter(p) * fr_flig(ivt(p)) * wtcol(p) * froot_prof(p,j) - - ! fine root litter nitrogen fluxes - phenology_n_to_litr_met_n(c,j) = phenology_n_to_litr_met_n(c,j) & - + frootn_to_litter(p) * fr_flab(ivt(p)) * wtcol(p) * froot_prof(p,j) - phenology_n_to_litr_cel_n(c,j) = phenology_n_to_litr_cel_n(c,j) & - + frootn_to_litter(p) * fr_fcel(ivt(p)) * wtcol(p) * froot_prof(p,j) - phenology_n_to_litr_lig_n(c,j) = phenology_n_to_litr_lig_n(c,j) & - + frootn_to_litter(p) * fr_flig(ivt(p)) * wtcol(p) * froot_prof(p,j) - - ! agroibis puts crop stem litter together with leaf litter - ! so I've used the leaf lf_f* parameters instead of making - ! new ones for now (slevis) - ! also for simplicity I've put "food" into the litter pools - - if (ivt(p) >= npcropmin) then ! add livestemc to litter - ! stem litter carbon fluxes - phenology_c_to_litr_met_c(c,j) = phenology_c_to_litr_met_c(c,j) & - + livestemc_to_litter(p) * lf_flab(ivt(p)) * wtcol(p) * leaf_prof(p,j) - phenology_c_to_litr_cel_c(c,j) = phenology_c_to_litr_cel_c(c,j) & - + livestemc_to_litter(p) * lf_fcel(ivt(p)) * wtcol(p) * leaf_prof(p,j) - phenology_c_to_litr_lig_c(c,j) = phenology_c_to_litr_lig_c(c,j) & - + livestemc_to_litter(p) * lf_flig(ivt(p)) * wtcol(p) * leaf_prof(p,j) - - ! stem litter nitrogen fluxes - phenology_n_to_litr_met_n(c,j) = phenology_n_to_litr_met_n(c,j) & - + livestemn_to_litter(p) * lf_flab(ivt(p)) * wtcol(p) * leaf_prof(p,j) - phenology_n_to_litr_cel_n(c,j) = phenology_n_to_litr_cel_n(c,j) & - + livestemn_to_litter(p) * lf_fcel(ivt(p)) * wtcol(p) * leaf_prof(p,j) - phenology_n_to_litr_lig_n(c,j) = phenology_n_to_litr_lig_n(c,j) & - + livestemn_to_litter(p) * lf_flig(ivt(p)) * wtcol(p) * leaf_prof(p,j) - - if (.not. use_grainproduct) then - ! grain litter carbon fluxes - phenology_c_to_litr_met_c(c,j) = phenology_c_to_litr_met_c(c,j) & - + grainc_to_food(p) * lf_flab(ivt(p)) * wtcol(p) * leaf_prof(p,j) & - + biofuelc_harvest(p) * lf_flab(ivt(p)) * wtcol(p) * leaf_prof(p,j) ! biofuel - phenology_c_to_litr_cel_c(c,j) = phenology_c_to_litr_cel_c(c,j) & - + grainc_to_food(p) * lf_fcel(ivt(p)) * wtcol(p) * leaf_prof(p,j) & - + biofuelc_harvest(p) * lf_fcel(ivt(p)) * wtcol(p) * leaf_prof(p,j) ! biofuel - phenology_c_to_litr_lig_c(c,j) = phenology_c_to_litr_lig_c(c,j) & - + grainc_to_food(p) * lf_flig(ivt(p)) * wtcol(p) * leaf_prof(p,j) & - + biofuelc_harvest(p) * lf_flig(ivt(p)) * wtcol(p) * leaf_prof(p,j) ! biofuel - - ! grain litter nitrogen fluxes - phenology_n_to_litr_met_n(c,j) = phenology_n_to_litr_met_n(c,j) & - + grainn_to_food(p) * lf_flab(ivt(p)) * wtcol(p) * leaf_prof(p,j) & - + biofueln_harvest(p) * lf_flab(ivt(p)) * wtcol(p) * leaf_prof(p,j) ! biofuel - phenology_n_to_litr_cel_n(c,j) = phenology_n_to_litr_cel_n(c,j) & - + grainn_to_food(p) * lf_fcel(ivt(p)) * wtcol(p) * leaf_prof(p,j) & - + biofueln_harvest(p) * lf_fcel(ivt(p)) * wtcol(p) * leaf_prof(p,j) ! biofuel - phenology_n_to_litr_lig_n(c,j) = phenology_n_to_litr_lig_n(c,j) & - + grainn_to_food(p) * lf_flig(ivt(p)) * wtcol(p) * leaf_prof(p,j) & - + biofueln_harvest(p) * lf_flig(ivt(p)) * wtcol(p) * leaf_prof(p,j) ! biofuel - end if - - - end if - end if - end if - - end do - - end do - end do - - end associate - - end subroutine CNLitterToColumn - -end module CNPhenologyMod From bbe7037fefd8880997a946c6314cf85bb9ed2645 Mon Sep 17 00:00:00 2001 From: chen693 Date: Sun, 15 Mar 2020 20:55:18 -0700 Subject: [PATCH 09/75] add a new biofuelc_harvest flux to store the cut fraction of crop carbon during offset period --- src/biogeochem/CNVegCarbonFluxType.F90 | 52 +++++++++++++++++--------- 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/src/biogeochem/CNVegCarbonFluxType.F90 b/src/biogeochem/CNVegCarbonFluxType.F90 index 5a5aa3f448..3cf3fe56ba 100644 --- a/src/biogeochem/CNVegCarbonFluxType.F90 +++ b/src/biogeochem/CNVegCarbonFluxType.F90 @@ -135,9 +135,8 @@ module CNVegCarbonFluxType real(r8), pointer :: livestemc_to_litter_patch (:) ! live stem C litterfall (gC/m2/s) real(r8), pointer :: grainc_to_food_patch (:) ! grain C to food for prognostic crop(gC/m2/s) - ! Y. Cheng - real(r8), pointer :: biofuelc_harvest_patch (:) ! biofuel C for bioenergy crops that are harvested (gC/m2/s) - + real(r8), pointer :: leafc_to_biofuelc_patch (:) ! leaf C to biofuel C (gC/m2/s) + real(r8), pointer :: livestemc_to_biofuelc_patch (:) ! livestem C to biofuel C (gC/m2/s) real(r8), pointer :: grainc_to_seed_patch (:) ! grain C to seed for prognostic crop(gC/m2/s) ! maintenance respiration fluxes @@ -249,6 +248,8 @@ module CNVegCarbonFluxType real(r8), pointer :: harvest_c_to_cwdc_col (:,:) ! C fluxes associated with harvest to CWD pool (gC/m3/s) real(r8), pointer :: grainc_to_cropprodc_patch (:) ! grain C to crop product pool (gC/m2/s) real(r8), pointer :: grainc_to_cropprodc_col (:) ! grain C to crop product pool (gC/m2/s) + real(r8), pointer :: biofuelc_to_cropprodc_patch (:) ! biofuel C to crop product pool (gC/m2/s) + real(r8), pointer :: biofuelc_to_cropprodc_col (:) ! biofuel C to crop product pool (gC/m2/s) ! fire fluxes real(r8), pointer :: m_decomp_cpools_to_fire_vr_col (:,:,:) ! vertically-resolved decomposing C fire loss (gC/m3/s) @@ -600,7 +601,8 @@ subroutine InitAllocate(this, bounds, carbon_type) allocate(this%cpool_to_grainc_storage_patch (begp:endp)) ; this%cpool_to_grainc_storage_patch (:) = nan allocate(this%livestemc_to_litter_patch (begp:endp)) ; this%livestemc_to_litter_patch (:) = nan allocate(this%grainc_to_food_patch (begp:endp)) ; this%grainc_to_food_patch (:) = nan - allocate(this%biofuelc_harvest_patch (begp:endp)) ; this%biofuelc_harvest_patch (:) = nan + allocate(this%leafc_to_biofuelc_patch (begp:endp)) ; this%leafc_to_biofuelc_patch (:) = nan + allocate(this%livestemc_to_biofuelc_patch (begp:endp)) ; this%livestemc_to_biofuelc_patch (:) = nan allocate(this%grainc_to_seed_patch (begp:endp)) ; this%grainc_to_seed_patch (:) = nan allocate(this%grainc_xfer_to_grainc_patch (begp:endp)) ; this%grainc_xfer_to_grainc_patch (:) = nan allocate(this%cpool_grain_gr_patch (begp:endp)) ; this%cpool_grain_gr_patch (:) = nan @@ -664,6 +666,12 @@ subroutine InitAllocate(this, bounds, carbon_type) allocate(this%grainc_to_cropprodc_col(begc:endc)) this%grainc_to_cropprodc_col(:) = nan + + allocate(this%biofuelc_to_cropprodc_patch(begp:endp)) + this%biofuelc_to_cropprodc_patch(:) = nan + + allocate(this%biofuelc_to_cropprodc_col(begc:endc)) + this%biofuelc_to_cropprodc_col(:) = nan allocate(this%m_decomp_cpools_to_fire_vr_col(begc:endc,1:nlevdecomp_full,1:ndecomp_pools)) this%m_decomp_cpools_to_fire_vr_col(:,:,:)= nan @@ -830,12 +838,15 @@ subroutine InitHistory(this, bounds, carbon_type) avgflag='A', long_name='grain C to food', & ptr_patch=this%grainc_to_food_patch) - ! Y. Cheng - this%biofuelc_harvest_patch(begp:endp) = spval - call hist_addfld1d (fname='BIOFUELC_HARVEST', units='gC/m^2/s', & - avgflag='A', long_name='biofuel C harvest', & - ptr_patch=this%biofuelc_harvest_patch) + this%leafc_to_biofuelc_patch(begp:endp) = spval + call hist_addfld1d (fname='LEAFC_TO_BIOFUELC', units='gC/m^2/s', & + avgflag='A', long_name='leaf C to biofuel C', & + ptr_patch=this%leafc_to_biofuelc_patch) + this%livestemc_to_biofuelc_patch(begp:endp) = spval + call hist_addfld1d (fname='LIVESTEMC_TO_BIOFUELC', units='gC/m^2/s', & + avgflag='A', long_name='livestem C to biofuel C', & + ptr_patch=this%livestemc_to_biofuelc_patch) this%grainc_to_seed_patch(begp:endp) = spval call hist_addfld1d (fname='GRAINC_TO_SEED', units='gC/m^2/s', & @@ -3523,14 +3534,17 @@ subroutine RestartBulkOnly ( this, bounds, ncid, flag ) dim1name='pft', & long_name='grain C to food', units='gC/m2/s', & interpinic_flag='interp', readvar=readvar, data=this%grainc_to_food_patch) - - - ! Y. Cheng - call restartvar(ncid=ncid, flag=flag, varname='biofuelc_harvest', xtype=ncd_double, & + + call restartvar(ncid=ncid, flag=flag, varname='leafc_to_biofuelc', xtype=ncd_double, & dim1name='pft', & - long_name='biofuelc harvest', units='gC/m2/s', & - interpinic_flag='interp', readvar=readvar, data=this%biofuelc_harvest_patch) + long_name='leaf C to biofuel C', units='gC/m2/s', & + interpinic_flag='interp', readvar=readvar, data=this%leafc_to_biofuelc_patch) + call restartvar(ncid=ncid, flag=flag, varname='livestemc_to_biofuelc', xtype=ncd_double, & + dim1name='pft', & + long_name='livestem C to biofuel C', units='gC/m2/s', & + interpinic_flag='interp', readvar=readvar, data=this%livestemc_to_biofuelc_patch) + call restartvar(ncid=ncid, flag=flag, varname='cpool_to_grainc', xtype=ncd_double, & dim1name='pft', & long_name='allocation to grain C', units='gC/m2/s', & @@ -3859,6 +3873,7 @@ subroutine SetValues ( this, & this%crop_seedc_to_leaf_patch(i) = value_patch this%grainc_to_cropprodc_patch(i) = value_patch + this%biofuelc_to_cropprodc_patch(i) = value_patch end do if ( use_crop )then @@ -3868,7 +3883,8 @@ subroutine SetValues ( this, & this%livestemc_to_litter_patch(i) = value_patch this%grainc_to_food_patch(i) = value_patch - this%biofuelc_harvest_patch(i) = value_patch + this%leafc_to_biofuelc_patch(i) = value_patch + this%livestemc_to_biofuelc_patch(i) = value_patch this%grainc_to_seed_patch(i) = value_patch this%grainc_xfer_to_grainc_patch(i) = value_patch @@ -3927,6 +3943,7 @@ subroutine SetValues ( this, & i = filter_column(fi) this%grainc_to_cropprodc_col(i) = value_column + this%biofuelc_to_cropprodc_col(i) = value_column this%cwdc_hr_col(i) = value_column this%cwdc_loss_col(i) = value_column this%litterc_loss_col(i) = value_column @@ -4314,8 +4331,7 @@ subroutine Summary_carbonflux(this, & if (.not. use_grainproduct) then this%litfall_patch(p) = & this%litfall_patch(p) + & - this%grainc_to_food_patch(p) + & - this%biofuelc_harvest_patch(p) !Y.Cheng + this%grainc_to_food_patch(p) end if end if From 515ffe3f4b44a6ac39b0c51b35671f0046155a62 Mon Sep 17 00:00:00 2001 From: chen693 Date: Sun, 15 Mar 2020 20:55:22 -0700 Subject: [PATCH 10/75] add a new biofueln_harvest flux to store the cut fraction of crop nitrogen during offset period --- src/biogeochem/CNVegNitrogenFluxType.F90 | 28 +++++++++++++++++++----- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/biogeochem/CNVegNitrogenFluxType.F90 b/src/biogeochem/CNVegNitrogenFluxType.F90 index edfa857998..b79f71986f 100644 --- a/src/biogeochem/CNVegNitrogenFluxType.F90 +++ b/src/biogeochem/CNVegNitrogenFluxType.F90 @@ -63,6 +63,8 @@ module CNVegNitrogenFluxType real(r8), pointer :: hrv_retransn_to_litter_patch (:) ! patch retranslocated N pool harvest mortality (gN/m2/s) real(r8), pointer :: grainn_to_cropprodn_patch (:) ! patch grain N to crop product pool (gN/m2/s) real(r8), pointer :: grainn_to_cropprodn_col (:) ! col grain N to crop product pool (gN/m2/s) + real(r8), pointer :: biofueln_to_cropprodn_patch (:) ! patch biofuel N to crop product pool (gN/m2/s) + real(r8), pointer :: biofueln_to_cropprodn_col (:) ! col biofuel N to crop product pool (gN/m2/s) real(r8), pointer :: m_n_to_litr_met_fire_col (:,:) ! col N from leaf, froot, xfer and storage N to litter labile N by fire (gN/m3/s) real(r8), pointer :: m_n_to_litr_cel_fire_col (:,:) ! col N from leaf, froot, xfer and storage N to litter cellulose N by fire (gN/m3/s) real(r8), pointer :: m_n_to_litr_lig_fire_col (:,:) ! col N from leaf, froot, xfer and storage N to litter lignin N by fire (gN/m3/s) @@ -131,7 +133,8 @@ module CNVegNitrogenFluxType ! litterfall fluxes real(r8), pointer :: livestemn_to_litter_patch (:) ! patch livestem N to litter (gN/m2/s) real(r8), pointer :: grainn_to_food_patch (:) ! patch grain N to food for prognostic crop (gN/m2/s) - real(r8), pointer :: biofueln_harvest_patch (:) ! patch biofuel N for bioenergy crops that are harvested (gN/m2/s) + real(r8), pointer :: leafn_to_biofueln_patch (:) ! patch leaf N to biofuel N (gN/m2/s) + real(r8), pointer :: livestemn_to_biofueln_patch (:) ! patch livestem N to biofuel N (gN/m2/s) real(r8), pointer :: grainn_to_seed_patch (:) ! patch grain N to seed for prognostic crop (gN/m2/s) real(r8), pointer :: leafn_to_litter_patch (:) ! patch leaf N litterfall (gN/m2/s) real(r8), pointer :: leafn_to_retransn_patch (:) ! patch leaf N to retranslocated N pool (gN/m2/s) @@ -414,7 +417,8 @@ subroutine InitAllocate(this, bounds) allocate(this%npool_to_grainn_storage_patch (begp:endp)) ; this%npool_to_grainn_storage_patch (:) = nan allocate(this%livestemn_to_litter_patch (begp:endp)) ; this%livestemn_to_litter_patch (:) = nan allocate(this%grainn_to_food_patch (begp:endp)) ; this%grainn_to_food_patch (:) = nan - allocate(this%biofueln_harvest_patch (begp:endp)) ; this%biofueln_harvest_patch (:) = nan + allocate(this%leafn_to_biofueln_patch (begp:endp)) ; this%leafn_to_biofueln_patch (:) = nan + allocate(this%livestemn_to_biofueln_patch (begp:endp)) ; this%livestemn_to_biofueln_patch (:) = nan allocate(this%grainn_to_seed_patch (begp:endp)) ; this%grainn_to_seed_patch (:) = nan allocate(this%grainn_xfer_to_grainn_patch (begp:endp)) ; this%grainn_xfer_to_grainn_patch (:) = nan allocate(this%grainn_storage_to_xfer_patch (begp:endp)) ; this%grainn_storage_to_xfer_patch (:) = nan @@ -424,6 +428,8 @@ subroutine InitAllocate(this, bounds) allocate(this%grainn_to_cropprodn_patch (begp:endp)) ; this%grainn_to_cropprodn_patch (:) = nan allocate(this%grainn_to_cropprodn_col (begc:endc)) ; this%grainn_to_cropprodn_col (:) = nan + allocate(this%biofueln_to_cropprodn_patch (begp:endp)) ; this%biofueln_to_cropprodn_patch (:) = nan + allocate(this%biofueln_to_cropprodn_col (begc:endc)) ; this%biofueln_to_cropprodn_col (:) = nan allocate(this%fire_nloss_col (begc:endc)) ; this%fire_nloss_col (:) = nan allocate(this%fire_nloss_p2c_col (begc:endc)) ; this%fire_nloss_p2c_col (:) = nan @@ -1374,10 +1380,17 @@ subroutine Restart (this, bounds, ncid, flag ) end if if (use_crop) then - call restartvar(ncid=ncid, flag=flag, varname='biofueln_harvest', xtype=ncd_double, & + call restartvar(ncid=ncid, flag=flag, varname='leafn_to_biofueln', xtype=ncd_double, & dim1name='pft', & - long_name='biofuel N harvested', units='gN/m2/s', & - interpinic_flag='interp', readvar=readvar, data=this%biofueln_harvest_patch) + long_name='leaf N to biofuel N', units='gN/m2/s', & + interpinic_flag='interp', readvar=readvar, data=this%leafn_to_biofueln_patch) + end if + + if (use_crop) then + call restartvar(ncid=ncid, flag=flag, varname='livestemn_to_biofueln', xtype=ncd_double, & + dim1name='pft', & + long_name='livestem N to biofuel N', units='gN/m2/s', & + interpinic_flag='interp', readvar=readvar, data=this%livestemn_to_biofueln_patch) end if if (use_crop) then @@ -1681,6 +1694,7 @@ subroutine SetValues ( this, & this%crop_seedn_to_leaf_patch(i) = value_patch this%grainn_to_cropprodn_patch(i) = value_patch + this%biofueln_to_cropprodn_patch(i) = value_patch end do if ( use_crop )then @@ -1688,7 +1702,8 @@ subroutine SetValues ( this, & i = filter_patch(fi) this%livestemn_to_litter_patch(i) = value_patch this%grainn_to_food_patch(i) = value_patch - this%biofueln_harvest_patch(i) = value_patch + this%leafn_to_biofueln_patch(i) = value_patch + this%livestemn_to_biofueln_patch(i) = value_patch this%grainn_to_seed_patch(i) = value_patch this%grainn_xfer_to_grainn_patch(i) = value_patch this%npool_to_grainn_patch(i) = value_patch @@ -1732,6 +1747,7 @@ subroutine SetValues ( this, & i = filter_column(fi) this%grainn_to_cropprodn_col(i) = value_column + this%biofueln_to_cropprodn_col(i) = value_column this%fire_nloss_col(i) = value_column ! Zero p2c column fluxes From 0845638aaafeace5db8bf25b6da4a11009de8026 Mon Sep 17 00:00:00 2001 From: chen693 Date: Sun, 15 Mar 2020 20:55:25 -0700 Subject: [PATCH 11/75] cut a certain fraction of crop aboveground biomass during offset period --- src/biogeochem/CNPhenologyMod.F90 | 71 +++++++++++++++---------------- 1 file changed, 35 insertions(+), 36 deletions(-) diff --git a/src/biogeochem/CNPhenologyMod.F90 b/src/biogeochem/CNPhenologyMod.F90 index 3079f12670..0439af76d4 100644 --- a/src/biogeochem/CNPhenologyMod.F90 +++ b/src/biogeochem/CNPhenologyMod.F90 @@ -1436,8 +1436,6 @@ subroutine CropPhenology(num_pcropp, filter_pcropp , & use pftconMod , only : ntrp_corn, nsugarcane, ntrp_soybean, ncotton, nrice use pftconMod , only : nirrig_trp_corn, nirrig_sugarcane, nirrig_trp_soybean use pftconMod , only : nirrig_cotton, nirrig_rice - - ! Y. Cheng use pftconMod , only : nmiscanthus, nirrig_miscanthus, nswitchgrass, nirrig_switchgrass use clm_varcon , only : spval, secspday @@ -1733,7 +1731,6 @@ subroutine CropPhenology(num_pcropp, filter_pcropp , & gddmaturity(p) = min(gdd1020(p), hybgdd(ivt(p))) end if - ! Y. Cheng, add switchgrass and Miscanthus if (ivt(p) == ntmp_corn .or. ivt(p) == nirrig_tmp_corn .or. & ivt(p) == ntrp_corn .or. ivt(p) == nirrig_trp_corn .or. & ivt(p) == nsugarcane .or. ivt(p) == nirrig_sugarcane .or. & @@ -1786,7 +1783,6 @@ subroutine CropPhenology(num_pcropp, filter_pcropp , & gddmaturity(p) = min(gdd1020(p), hybgdd(ivt(p))) end if - ! Y. Cheng, add switchgrass and Miscanthus if (ivt(p) == ntmp_corn .or. ivt(p) == nirrig_tmp_corn .or. & ivt(p) == ntrp_corn .or. ivt(p) == nirrig_trp_corn .or. & ivt(p) == nsugarcane .or. ivt(p) == nirrig_sugarcane .or. & @@ -1850,7 +1846,6 @@ subroutine CropPhenology(num_pcropp, filter_pcropp , & ! calculate linear relationship between huigrain fraction and relative ! maturity rating for maize - ! Y. Cheng, add switchgrass and Miscanthus if (ivt(p) == ntmp_corn .or. ivt(p) == nirrig_tmp_corn .or. & ivt(p) == ntrp_corn .or. ivt(p) == nirrig_trp_corn .or. & ivt(p) == nsugarcane .or. ivt(p) == nirrig_sugarcane .or. & @@ -2388,7 +2383,6 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, & ! ! !USES: use pftconMod , only : npcropmin - ! Y. Cheng use pftconMod , only : nmiscanthus, nirrig_miscanthus, nswitchgrass, nirrig_switchgrass use CNSharedParamsMod, only : use_fun @@ -2446,19 +2440,18 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, & leafc_to_litter => cnveg_carbonflux_inst%leafc_to_litter_patch , & ! Output: [real(r8) (:) ] leaf C litterfall (gC/m2/s) frootc_to_litter => cnveg_carbonflux_inst%frootc_to_litter_patch , & ! Output: [real(r8) (:) ] fine root C litterfall (gC/m2/s) livestemc_to_litter => cnveg_carbonflux_inst%livestemc_to_litter_patch , & ! Output: [real(r8) (:) ] live stem C litterfall (gC/m2/s) - grainc_to_food => cnveg_carbonflux_inst%grainc_to_food_patch , & ! Output: [real(r8) (:) ] grain C to food (gC/m2/s) - - ! Y. Cheng, put the cut fraction during offset period for bioenergy crops to this biofuelc_harvest flux - biofuelc_harvest => cnveg_carbonflux_inst%biofuelc_harvest_patch , & ! Output: [real(r8) (:) ] biofuel C that was cutted at harvest (gC/m2/s) - + grainc_to_food => cnveg_carbonflux_inst%grainc_to_food_patch , & ! Output: [real(r8) (:) ] grain C to food (gC/m2/s) grainc_to_seed => cnveg_carbonflux_inst%grainc_to_seed_patch , & ! Output: [real(r8) (:) ] grain C to seed (gC/m2/s) + leafc_to_biofuelc => cnveg_carbonflux_inst%leafc_to_biofuelc_patch , & ! Output: [real(r8) (:) ] leaf C to biofuel C (gC/m2/s) + livestemc_to_biofuelc => cnveg_carbonflux_inst%livestemc_to_biofuelc_patch , & ! Output: [real(r8) (:) ] livestem C to biofuel C (gC/m2/s) 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_to_litter => cnveg_nitrogenflux_inst%livestemn_to_litter_patch , & ! Output: [real(r8) (:) ] livestem N to litter (gN/m2/s) - grainn_to_food => cnveg_nitrogenflux_inst%grainn_to_food_patch , & ! Output: [real(r8) (:) ] grain N to food (gN/m2/s) - biofueln_harvest => cnveg_nitrogenflux_inst%biofueln_harvest_patch , & ! Output: [real(r8) (:) ] biofuel N that was cutted (gC/m2/s) - grainn_to_seed => cnveg_nitrogenflux_inst%grainn_to_seed_patch , & ! Output: [real(r8) (:) ] grain N to seed (gN/m2/s) + grainn_to_food => cnveg_nitrogenflux_inst%grainn_to_food_patch , & ! Output: [real(r8) (:) ] grain N to food (gN/m2/s) + grainn_to_seed => cnveg_nitrogenflux_inst%grainn_to_seed_patch , & ! Output: [real(r8) (:) ] grain N to seed (gN/m2/s) + leafn_to_biofueln => cnveg_nitrogenflux_inst%leafn_to_biofueln_patch , & ! Output: [real(r8) (:) ] leaf N to biofuel N (gN/m2/s) + livestemn_to_biofueln => cnveg_nitrogenflux_inst%livestemn_to_biofueln_patch, & ! Output: [real(r8) (:) ] livestem N to biofuel N (gN/m2/s) leafn_to_litter => cnveg_nitrogenflux_inst%leafn_to_litter_patch , & ! Output: [real(r8) (:) ] leaf N litterfall (gN/m2/s) leafn_to_retransn => cnveg_nitrogenflux_inst%leafn_to_retransn_patch , & ! Input: [real(r8) (:) ] leaf N to retranslocated N pool (gN/m2/s) free_retransn_to_npool=> cnveg_nitrogenflux_inst%free_retransn_to_npool_patch , & ! Input: [real(r8) (:) ] free leaf N to retranslocated N pool (gN/m2/s) @@ -2481,11 +2474,11 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, & t1 = 1.0_r8 / dt frootc_to_litter(p) = t1 * frootc(p) + cpool_to_frootc(p) - ! Cut a certain fraction (i.e., harvfrac(ivt(p))) (e.g., harvfrac(ivt(p)=70% for bioenergy crops) of leafc for harvest - ! and move this cut fration to the biofuelc_harvest flux, rather than move it to litter + ! Cut a certain fraction (i.e., harvfrac(ivt(p))) (e.g., harvfrac(ivt(p)=70% for bioenergy crops) of leaf C + ! and move this fration of leaf C to biofuel C, rather than move it to litter leafc_to_litter(p) = t1 * leafc(p)*(1._r8-harvfrac(ivt(p))) + cpool_to_leafc(p) - biofuelc_harvest(p) = t1 * leafc(p) * harvfrac(ivt(p)) - biofueln_harvest(p) = t1 * leafn(p) * harvfrac(ivt(p)) + leafc_to_biofuelc(p) = t1 * leafc(p) * harvfrac(ivt(p)) + leafn_to_biofueln(p) = t1 * leafn(p) * harvfrac(ivt(p)) ! this assumes that offset_counter == dt for crops ! if this were ever changed, we'd need to add code to the "else" @@ -2500,7 +2493,11 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, & grainc_to_food(p) = t1 * grainc(p) + cpool_to_grainc(p) - grainc_to_seed(p) grainn_to_food(p) = t1 * grainn(p) + npool_to_grainn(p) - grainn_to_seed(p) - livestemc_to_litter(p) = t1 * livestemc(p) + cpool_to_livestemc(p) + ! Cut a certain fraction (i.e., harvfrac(ivt(p))) (e.g., harvfrac(ivt(p)=70% for bioenergy crops) of livestem C + ! and move this fration of leaf C to biofuel C, rather than move it to litter + livestemc_to_litter(p) = t1 * livestemc(p)*(1._r8-harvfrac(ivt(p))) + cpool_to_livestemc(p) + livestemc_to_biofuelc(p) = t1 * livestemc(p) * harvfrac(ivt(p)) + livestemn_to_biofueln(p) = t1 * livestemn(p) * harvfrac(ivt(p)) end if else t1 = dt * 2.0_r8 / (offset_counter(p) * offset_counter(p)) @@ -2874,6 +2871,10 @@ subroutine CNGrainToProductPools(bounds, num_soilp, filter_soilp, num_soilc, fil cnveg_carbonflux_inst%grainc_to_food_patch(p) cnveg_nitrogenflux_inst%grainn_to_cropprodn_patch(p) = & cnveg_nitrogenflux_inst%grainn_to_food_patch(p) + cnveg_carbonflux_inst%biofuelc_to_cropprodc_patch(p) = & + cnveg_carbonflux_inst%leafc_to_biofuelc_patch(p)+cnveg_carbonflux_inst%livestemc_to_biofuelc_patch(p) + cnveg_nitrogenflux_inst%biofueln_to_cropprodn_patch(p) = & + cnveg_nitrogenflux_inst%leafn_to_biofueln_patch(p)+cnveg_nitrogenflux_inst%livestemn_to_biofueln_patch(p) end do call p2c (bounds, num_soilc, filter_soilc, & @@ -2883,6 +2884,14 @@ subroutine CNGrainToProductPools(bounds, num_soilp, filter_soilp, num_soilc, fil call p2c (bounds, num_soilc, filter_soilc, & cnveg_nitrogenflux_inst%grainn_to_cropprodn_patch(bounds%begp:bounds%endp), & cnveg_nitrogenflux_inst%grainn_to_cropprodn_col(bounds%begc:bounds%endc)) + + call p2c (bounds, num_soilc, filter_soilc, & + cnveg_carbonflux_inst%biofuelc_to_cropprodc_patch(bounds%begp:bounds%endp), & + cnveg_carbonflux_inst%biofuelc_to_cropprodc_col(bounds%begc:bounds%endc)) + + call p2c (bounds, num_soilc, filter_soilc, & + cnveg_nitrogenflux_inst%biofueln_to_cropprodn_patch(bounds%begp:bounds%endp), & + cnveg_nitrogenflux_inst%biofueln_to_cropprodn_col(bounds%begc:bounds%endc)) end if ! No else clause: if use_grainproduct is false, then the grain*_to_cropprod fluxes @@ -2938,17 +2947,13 @@ subroutine CNLitterToColumn (bounds, num_soilc, filter_soilc, & leafc_to_litter => cnveg_carbonflux_inst%leafc_to_litter_patch , & ! Input: [real(r8) (:) ] leaf C litterfall (gC/m2/s) frootc_to_litter => cnveg_carbonflux_inst%frootc_to_litter_patch , & ! Input: [real(r8) (:) ] fine root N litterfall (gN/m2/s) livestemc_to_litter => cnveg_carbonflux_inst%livestemc_to_litter_patch , & ! Input: [real(r8) (:) ] live stem C litterfall (gC/m2/s) - grainc_to_food => cnveg_carbonflux_inst%grainc_to_food_patch , & ! Input: [real(r8) (:) ] grain C to food (gC/m2/s) - - biofuelc_harvest => cnveg_carbonflux_inst%biofuelc_harvest_patch , & ! Input: [real(r8) (:) ] biofuel C (gC/m2/s) - + grainc_to_food => cnveg_carbonflux_inst%grainc_to_food_patch , & ! Input: [real(r8) (:) ] grain C to food (gC/m2/s) phenology_c_to_litr_met_c => cnveg_carbonflux_inst%phenology_c_to_litr_met_c_col , & ! Output: [real(r8) (:,:) ] C fluxes associated with phenology (litterfall and crop) to litter metabolic pool (gC/m3/s) phenology_c_to_litr_cel_c => cnveg_carbonflux_inst%phenology_c_to_litr_cel_c_col , & ! Output: [real(r8) (:,:) ] C fluxes associated with phenology (litterfall and crop) to litter cellulose pool (gC/m3/s) phenology_c_to_litr_lig_c => cnveg_carbonflux_inst%phenology_c_to_litr_lig_c_col , & ! Output: [real(r8) (:,:) ] C fluxes associated with phenology (litterfall and crop) to litter lignin pool (gC/m3/s) livestemn_to_litter => cnveg_nitrogenflux_inst%livestemn_to_litter_patch , & ! Input: [real(r8) (:) ] livestem N to litter (gN/m2/s) grainn_to_food => cnveg_nitrogenflux_inst%grainn_to_food_patch , & ! Input: [real(r8) (:) ] grain N to food (gN/m2/s) - biofueln_harvest => cnveg_nitrogenflux_inst%biofueln_harvest_patch , & ! Input: [real(r8) (:) ] biofuel N (gN/m2/s) leafn_to_litter => cnveg_nitrogenflux_inst%leafn_to_litter_patch , & ! Input: [real(r8) (:) ] leaf N litterfall (gN/m2/s) frootn_to_litter => cnveg_nitrogenflux_inst%frootn_to_litter_patch , & ! Input: [real(r8) (:) ] fine root N litterfall (gN/m2/s) phenology_n_to_litr_met_n => cnveg_nitrogenflux_inst%phenology_n_to_litr_met_n_col , & ! Output: [real(r8) (:,:) ] N fluxes associated with phenology (litterfall and crop) to litter metabolic pool (gN/m3/s) @@ -3022,25 +3027,19 @@ subroutine CNLitterToColumn (bounds, num_soilc, filter_soilc, & if (.not. use_grainproduct) then ! grain litter carbon fluxes phenology_c_to_litr_met_c(c,j) = phenology_c_to_litr_met_c(c,j) & - + grainc_to_food(p) * lf_flab(ivt(p)) * wtcol(p) * leaf_prof(p,j) & - + biofuelc_harvest(p) * lf_flab(ivt(p)) * wtcol(p) * leaf_prof(p,j) ! biofuel + + grainc_to_food(p) * lf_flab(ivt(p)) * wtcol(p) * leaf_prof(p,j) phenology_c_to_litr_cel_c(c,j) = phenology_c_to_litr_cel_c(c,j) & - + grainc_to_food(p) * lf_fcel(ivt(p)) * wtcol(p) * leaf_prof(p,j) & - + biofuelc_harvest(p) * lf_fcel(ivt(p)) * wtcol(p) * leaf_prof(p,j) ! biofuel + + grainc_to_food(p) * lf_fcel(ivt(p)) * wtcol(p) * leaf_prof(p,j) phenology_c_to_litr_lig_c(c,j) = phenology_c_to_litr_lig_c(c,j) & - + grainc_to_food(p) * lf_flig(ivt(p)) * wtcol(p) * leaf_prof(p,j) & - + biofuelc_harvest(p) * lf_flig(ivt(p)) * wtcol(p) * leaf_prof(p,j) ! biofuel + + grainc_to_food(p) * lf_flig(ivt(p)) * wtcol(p) * leaf_prof(p,j) ! grain litter nitrogen fluxes phenology_n_to_litr_met_n(c,j) = phenology_n_to_litr_met_n(c,j) & - + grainn_to_food(p) * lf_flab(ivt(p)) * wtcol(p) * leaf_prof(p,j) & - + biofueln_harvest(p) * lf_flab(ivt(p)) * wtcol(p) * leaf_prof(p,j) ! biofuel + + grainn_to_food(p) * lf_flab(ivt(p)) * wtcol(p) * leaf_prof(p,j) phenology_n_to_litr_cel_n(c,j) = phenology_n_to_litr_cel_n(c,j) & - + grainn_to_food(p) * lf_fcel(ivt(p)) * wtcol(p) * leaf_prof(p,j) & - + biofueln_harvest(p) * lf_fcel(ivt(p)) * wtcol(p) * leaf_prof(p,j) ! biofuel + + grainn_to_food(p) * lf_fcel(ivt(p)) * wtcol(p) * leaf_prof(p,j) phenology_n_to_litr_lig_n(c,j) = phenology_n_to_litr_lig_n(c,j) & - + grainn_to_food(p) * lf_flig(ivt(p)) * wtcol(p) * leaf_prof(p,j) & - + biofueln_harvest(p) * lf_flig(ivt(p)) * wtcol(p) * leaf_prof(p,j) ! biofuel + + grainn_to_food(p) * lf_flig(ivt(p)) * wtcol(p) * leaf_prof(p,j) end if From 6b75fcb7ce6f76ac08d9f7253f78c684ee55f74c Mon Sep 17 00:00:00 2001 From: chen693 Date: Sun, 15 Mar 2020 20:55:29 -0700 Subject: [PATCH 12/75] add calculation for the new biofuelc_to_cropprodc flux --- src/biogeochem/CNCIsoFluxMod.F90 | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/biogeochem/CNCIsoFluxMod.F90 b/src/biogeochem/CNCIsoFluxMod.F90 index 8c79e50d33..8461d1ef54 100644 --- a/src/biogeochem/CNCIsoFluxMod.F90 +++ b/src/biogeochem/CNCIsoFluxMod.F90 @@ -404,12 +404,15 @@ subroutine CIsoFlux1(num_soilc, filter_soilc, num_soilp, filter_soilp, & iso_cnveg_cs%grainc_patch , cnveg_cs%grainc_patch, & num_soilp , filter_soilp, 1._r8, 0, isotope) - ! Y. Cheng call CIsoFluxCalc(& - iso_cnveg_cf%biofuelc_harvest_patch , cnveg_cf%biofuelc_harvest_patch, & - iso_cnveg_cs%grainc_patch , cnveg_cs%grainc_patch, & + iso_cnveg_cf%leafc_to_biofuelc_patch , cnveg_cf%leafc_to_biofuelc_patch, & + iso_cnveg_cs%leafc_patch , cnveg_cs%leafc_patch, & num_soilp , filter_soilp, 1._r8, 0, isotope) + call CIsoFluxCalc(& + iso_cnveg_cf%livestemc_to_biofuelc_patch , cnveg_cf%livestemc_to_biofuelc_patch, & + iso_cnveg_cs%livestemc_patch , cnveg_cs%livestemc_patch, & + num_soilp , filter_soilp, 1._r8, 0, isotope) call CIsoFluxCalc(& iso_cnveg_cf%grainc_to_seed_patch , cnveg_cf%grainc_to_seed_patch, & @@ -470,6 +473,7 @@ subroutine CIsoFlux1(num_soilc, filter_soilc, num_soilp, filter_soilp, & do fp = 1,num_soilp p = filter_soilp(fp) iso_cnveg_cf%grainc_to_cropprodc_patch(p) = iso_cnveg_cf%grainc_to_food_patch(p) + iso_cnveg_cf%biofuelc_to_cropprodc_patch(p) = iso_cnveg_cf%leafc_to_biofuelc_patch(p)+iso_cnveg_cf%livestemc_to_biofuelc_patch(p) iso_cnveg_cf%grain_mr_patch(p) = iso_cnveg_cf%grain_xsmr_patch(p) + iso_cnveg_cf%grain_curmr_patch(p) end do endif @@ -1200,9 +1204,8 @@ subroutine CNCIsoLitterToColumn (num_soilc, filter_soilc, & !DML livestemc_to_litter => iso_cnveg_carbonflux_inst%livestemc_to_litter_patch , & ! Input: [real(r8) (:) ] grainc_to_food => iso_cnveg_carbonflux_inst%grainc_to_food_patch , & ! Input: [real(r8) (:) ] - - ! Y. Cheng - biofuelc_harvest => iso_cnveg_carbonflux_inst%biofuelc_harvest_patch , & ! Input: [real(r8) (:) ] + leafc_to_biofuelc => iso_cnveg_carbonflux_inst%leafc_to_biofuelc_patch , & ! Input: [real(r8) (:) ] + livestemc_to_biofuelc => iso_cnveg_carbonflux_inst%livestemc_to_biofuelc_patch , & ! Input: [real(r8) (:) ] !DML phenology_c_to_litr_met_c => iso_cnveg_carbonflux_inst%phenology_c_to_litr_met_c_col , & ! InOut: [real(r8) (:,:) ] C fluxes associated with phenology (litterfall and crop) to litter metabolic pool (gC/m3/s) phenology_c_to_litr_cel_c => iso_cnveg_carbonflux_inst%phenology_c_to_litr_cel_c_col , & ! InOut: [real(r8) (:,:) ] C fluxes associated with phenology (litterfall and crop) to litter cellulose pool (gC/m3/s) @@ -1242,18 +1245,15 @@ subroutine CNCIsoLitterToColumn (num_soilc, filter_soilc, & + livestemc_to_litter(p) * lf_fcel(ivt(p)) * wtcol(p) * leaf_prof(p,j) phenology_c_to_litr_lig_c(c,j) = phenology_c_to_litr_lig_c(c,j) & + livestemc_to_litter(p) * lf_flig(ivt(p)) * wtcol(p) * leaf_prof(p,j) - ! Y. Cheng + if (.not. use_grainproduct) then ! grain litter carbon fluxes phenology_c_to_litr_met_c(c,j) = phenology_c_to_litr_met_c(c,j) & - + grainc_to_food(p) * lf_flab(ivt(p)) * wtcol(p) * leaf_prof(p,j) & - + biofuelc_harvest(p) * lf_flab(ivt(p)) * wtcol(p) * leaf_prof(p,j) + + grainc_to_food(p) * lf_flab(ivt(p)) * wtcol(p) * leaf_prof(p,j) phenology_c_to_litr_cel_c(c,j) = phenology_c_to_litr_cel_c(c,j) & - + grainc_to_food(p) * lf_fcel(ivt(p)) * wtcol(p) * leaf_prof(p,j) & - + biofuelc_harvest(p) * lf_fcel(ivt(p)) * wtcol(p) * leaf_prof(p,j) + + grainc_to_food(p) * lf_fcel(ivt(p)) * wtcol(p) * leaf_prof(p,j) phenology_c_to_litr_lig_c(c,j) = phenology_c_to_litr_lig_c(c,j) & - + grainc_to_food(p) * lf_flig(ivt(p)) * wtcol(p) * leaf_prof(p,j) & - + biofuelc_harvest(p) * lf_flig(ivt(p)) * wtcol(p) * leaf_prof(p,j) + + grainc_to_food(p) * lf_flig(ivt(p)) * wtcol(p) * leaf_prof(p,j) end if end if From dbad63fee5e109f091586f6aa1b716f6af5d58cf Mon Sep 17 00:00:00 2001 From: chen693 Date: Sun, 15 Mar 2020 20:55:32 -0700 Subject: [PATCH 13/75] add calculation for biofuel product --- src/biogeochem/CNDriverMod.F90 | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/biogeochem/CNDriverMod.F90 b/src/biogeochem/CNDriverMod.F90 index abc18cdbfc..bca596477f 100644 --- a/src/biogeochem/CNDriverMod.F90 +++ b/src/biogeochem/CNDriverMod.F90 @@ -712,7 +712,8 @@ subroutine CNDriverNoLeaching(bounds, dwt_wood_product_gain_patch = cnveg_carbonflux_inst%dwt_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)) + grain_to_cropprod_patch = cnveg_carbonflux_inst%grainc_to_cropprodc_patch(begp:endp), & + biofuel_to_cropprod_patch = cnveg_carbonflux_inst%biofuelc_to_cropprodc_patch(begp:endp)) call t_stopf('CNWoodProducts') if (use_c13) then @@ -721,7 +722,8 @@ subroutine CNDriverNoLeaching(bounds, dwt_wood_product_gain_patch = c13_cnveg_carbonflux_inst%dwt_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)) + grain_to_cropprod_patch = c13_cnveg_carbonflux_inst%grainc_to_cropprodc_patch(begp:endp), & + biofuel_to_cropprod_patch = c13_cnveg_carbonflux_inst%biofuelc_to_cropprodc_patch(begp:endp)) end if if (use_c14) then @@ -730,7 +732,8 @@ subroutine CNDriverNoLeaching(bounds, dwt_wood_product_gain_patch = c14_cnveg_carbonflux_inst%dwt_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)) + grain_to_cropprod_patch = c14_cnveg_carbonflux_inst%grainc_to_cropprodc_patch(begp:endp), & + biofuel_to_cropprod_patch = c14_cnveg_carbonflux_inst%biofuelc_to_cropprodc_patch(begp:endp)) end if call n_products_inst%UpdateProducts(bounds, & @@ -738,7 +741,8 @@ subroutine CNDriverNoLeaching(bounds, dwt_wood_product_gain_patch = cnveg_nitrogenflux_inst%dwt_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)) + grain_to_cropprod_patch = cnveg_nitrogenflux_inst%grainn_to_cropprodn_patch(begp:endp), & + biofuel_to_cropprod_patch = cnveg_nitrogenflux_inst%biofueln_to_cropprodn_patch(begp:endp)) !-------------------------------------------- ! Calculate fire area and fluxes From 6582a3ebcd9de15fa9842e6c38463cef52cfc640 Mon Sep 17 00:00:00 2001 From: chen693 Date: Sun, 15 Mar 2020 20:55:35 -0700 Subject: [PATCH 14/75] add calculation for biofuel product --- src/biogeochem/CNProductsMod.F90 | 74 ++++++++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 4 deletions(-) diff --git a/src/biogeochem/CNProductsMod.F90 b/src/biogeochem/CNProductsMod.F90 index 0661c3b392..8c6134c445 100644 --- a/src/biogeochem/CNProductsMod.F90 +++ b/src/biogeochem/CNProductsMod.F90 @@ -34,6 +34,7 @@ module CNProductsMod ! States real(r8), pointer :: cropprod1_grc(:) ! (g[C or N]/m2) grain product pool, 1-year lifespan + real(r8), pointer :: biofuelprod1_grc(:) ! (g[C or N]/m2) biofuel product pool, 1-year lifespan real(r8), pointer :: prod10_grc(:) ! (g[C or N]/m2) wood product pool, 10-year lifespan real(r8), pointer :: prod100_grc(:) ! (g[C or N]/m2) wood product pool, 100-year lifespan real(r8), pointer :: tot_woodprod_grc(:) ! (g[C or N]/m2) total wood product pool @@ -49,9 +50,12 @@ module CNProductsMod real(r8), pointer :: hrv_deadstem_to_prod100_grc(:) ! (g[C or N]/m2/s) dead stem harvest to 100-year wood product pool real(r8), pointer :: grain_to_cropprod1_patch(:) ! (g[C or N]/m2/s) grain to 1-year crop product pool real(r8), pointer :: grain_to_cropprod1_grc(:) ! (g[C or N]/m2/s) grain to 1-year crop product pool + real(r8), pointer :: biofuel_to_cropprod1_patch(:) ! (g[C or N]/m2/s) biofuel to 1-year crop product pool + real(r8), pointer :: biofuel_to_cropprod1_grc(:) ! (g[C or N]/m2/s) biofuel to 1-year crop product pool ! Fluxes: losses real(r8), pointer :: cropprod1_loss_grc(:) ! (g[C or N]/m2/s) decomposition loss from 1-yr grain product pool + real(r8), pointer :: biofuelprod1_loss_grc(:) ! (g[C or N]/m2/s) decomposition loss from 1-yr biofuel product pool real(r8), pointer :: prod10_loss_grc(:) ! (g[C or N]/m2/s) decomposition loss from 10-yr wood product pool real(r8), pointer :: prod100_loss_grc(:) ! (g[C or N]/m2/s) decomposition loss from 100-yr wood product pool real(r8), pointer :: tot_woodprod_loss_grc(:) ! (g[C or N]/m2/s) decompomposition loss from all wood product pools @@ -123,6 +127,7 @@ subroutine InitAllocate(this, bounds) endg = bounds%endg allocate(this%cropprod1_grc(begg:endg)) ; this%cropprod1_grc(:) = nan + allocate(this%biofuelprod1_grc(begg:endg)) ; this%biofuelprod1_grc(:) = nan allocate(this%prod10_grc(begg:endg)) ; this%prod10_grc(:) = nan allocate(this%prod100_grc(begg:endg)) ; this%prod100_grc(:) = nan allocate(this%tot_woodprod_grc(begg:endg)) ; this%tot_woodprod_grc(:) = nan @@ -141,8 +146,11 @@ subroutine InitAllocate(this, bounds) allocate(this%grain_to_cropprod1_patch(begp:endp)) ; this%grain_to_cropprod1_patch(:) = nan allocate(this%grain_to_cropprod1_grc(begg:endg)) ; this%grain_to_cropprod1_grc(:) = nan + allocate(this%biofuel_to_cropprod1_patch(begp:endp)) ; this%biofuel_to_cropprod1_patch(:) = nan + allocate(this%biofuel_to_cropprod1_grc(begg:endg)) ; this%biofuel_to_cropprod1_grc(:) = nan allocate(this%cropprod1_loss_grc(begg:endg)) ; this%cropprod1_loss_grc(:) = nan + allocate(this%biofuelprod1_loss_grc(begg:endg)) ; this%biofuelprod1_loss_grc(:) = nan allocate(this%prod10_loss_grc(begg:endg)) ; this%prod10_loss_grc(:) = nan allocate(this%prod100_loss_grc(begg:endg)) ; this%prod100_loss_grc(:) = nan allocate(this%tot_woodprod_loss_grc(begg:endg)) ; this%tot_woodprod_loss_grc(:) = nan @@ -184,6 +192,14 @@ subroutine InitHistory(this, bounds) long_name = '1-yr grain product ' // this%species%get_species(), & ptr_gcell = this%cropprod1_grc, default=active_if_non_isotope) + this%biofuelprod1_grc(begg:endg) = spval + call hist_addfld1d( & + fname = this%species%hist_fname('BIOFUELPROD1'), & + units = 'g' // this%species%get_species() // '/m^2', & + avgflag = 'A', & + long_name = '1-yr biofuel product ' // this%species%get_species(), & + ptr_gcell = this%biofuelprod1_grc, default=active_if_non_isotope) + this%prod10_grc(begg:endg) = spval call hist_addfld1d( & fname = this%species%hist_fname('PROD10'), & @@ -248,6 +264,14 @@ subroutine InitHistory(this, bounds) long_name = 'loss from 1-yr grain product pool', & ptr_gcell = this%cropprod1_loss_grc, default=active_if_non_isotope) + this%biofuelprod1_loss_grc(begg:endg) = spval + call hist_addfld1d( & + fname = this%species%hist_fname('BIOFUELPROD1', suffix='_LOSS'), & + units = 'g' // this%species%get_species() // '/m^2/s', & + avgflag = 'A', & + long_name = 'loss from 1-yr biofuel product pool', & + ptr_gcell = this%biofuelprod1_loss_grc, default=active_if_non_isotope) + this%prod10_loss_grc(begg:endg) = spval call hist_addfld1d( & fname = this%species%hist_fname('PROD10', suffix='_LOSS'), & @@ -288,6 +312,7 @@ subroutine InitCold(this, bounds) do g = bounds%begg, bounds%endg this%cropprod1_grc(g) = 0._r8 + this%biofuelprod1_grc(g) = 0._r8 this%prod10_grc(g) = 0._r8 this%prod100_grc(g) = 0._r8 this%tot_woodprod_grc(g) = 0._r8 @@ -299,6 +324,7 @@ subroutine InitCold(this, bounds) this%hrv_deadstem_to_prod10_patch(p) = 0._r8 this%hrv_deadstem_to_prod100_patch(p) = 0._r8 this%grain_to_cropprod1_patch(p) = 0._r8 + this%biofuel_to_cropprod1_patch(p) = 0._r8 end do end subroutine InitCold @@ -359,6 +385,13 @@ subroutine Restart(this, bounds, ncid, flag, & xtype=ncd_double, dim1name='gridcell', & long_name='', units='', & interpinic_flag='interp', readvar=readvar, data=this%cropprod1_grc) + + call restartvar(ncid=ncid, flag=flag, & + varname=this%species%rest_fname('biofuelprod1', suffix='_g'), & + xtype=ncd_double, dim1name='gridcell', & + long_name='', units='', & + interpinic_flag='interp', readvar=readvar, data=this%biofuelprod1_grc) + if (flag == 'read' .and. .not. readvar) then ! BACKWARDS_COMPATIBILITY(wjs, 2016-03-31) If the gridcell-level field isn't ! present, try to find a column-level field (which may be present on an older @@ -370,12 +403,23 @@ subroutine Restart(this, bounds, ncid, flag, & data_grc = this%cropprod1_grc, & readvar = readvar) + call set_grc_field_from_col_field( & + bounds = bounds, & + ncid = ncid, & + varname = this%species%rest_fname('biofuelprod1'), & + data_grc = this%biofuelprod1_grc, & + readvar = readvar) + ! If we still haven't found an appropriate field on the restart file, then set ! this field from the template, if provided if (.not. readvar .and. template_provided) then call set_missing_from_template(this%cropprod1_grc, & template_for_missing_fields%cropprod1_grc, & multiplier = template_multiplier) + + call set_missing_from_template(this%biofuelprod1_grc, & + template_for_missing_fields%biofuelprod1_grc, & + multiplier = template_multiplier) end if end if @@ -437,7 +481,8 @@ subroutine UpdateProducts(this, bounds, & dwt_wood_product_gain_patch, & wood_harvest_patch, & dwt_crop_product_gain_patch, & - grain_to_cropprod_patch) + grain_to_cropprod_patch, & + biofuel_to_cropprod_patch) ! ! !DESCRIPTION: ! Update all loss fluxes from wood and grain product pools, and update product pool @@ -462,6 +507,9 @@ subroutine UpdateProducts(this, bounds, & ! grain to crop product pool (g/m2/s) [patch] real(r8), intent(in) :: grain_to_cropprod_patch( bounds%begp: ) + + ! biofuel to crop product pool (g/m2/s) [patch] + real(r8), intent(in) :: biofuel_to_cropprod_patch( bounds%begp: ) ! ! !LOCAL VARIABLES: integer :: g ! indices @@ -475,6 +523,7 @@ subroutine UpdateProducts(this, bounds, & SHR_ASSERT_ALL_FL((ubound(wood_harvest_patch) == (/bounds%endp/)), sourcefile, __LINE__) SHR_ASSERT_ALL_FL((ubound(dwt_crop_product_gain_patch) == (/bounds%endp/)), sourcefile, __LINE__) SHR_ASSERT_ALL_FL((ubound(grain_to_cropprod_patch) == (/bounds%endp/)), sourcefile, __LINE__) + SHR_ASSERT_ALL_FL((ubound(biofuel_to_cropprod_patch) == (/bounds%endp/)), sourcefile, __LINE__) call this%PartitionWoodFluxes(bounds, & num_soilp, filter_soilp, & @@ -484,7 +533,8 @@ subroutine UpdateProducts(this, bounds, & call this%PartitionGrainFluxes(bounds, & num_soilp, filter_soilp, & dwt_crop_product_gain_patch(bounds%begp:bounds%endp), & - grain_to_cropprod_patch(bounds%begp:bounds%endp)) + grain_to_cropprod_patch(bounds%begp:bounds%endp), & + biofuel_to_cropprod_patch(bounds%begp:bounds%endp)) ! calculate losses from product pools ! the following (1/s) rate constants result in ~90% loss of initial state over 1, 10 and 100 years, @@ -496,6 +546,7 @@ subroutine UpdateProducts(this, bounds, & do g = bounds%begg, bounds%endg ! calculate fluxes out of product pools (1/sec) this%cropprod1_loss_grc(g) = this%cropprod1_grc(g) * kprod1 + this%biofuelprod1_loss_grc(g) = this%biofuelprod1_grc(g) * kprod1 this%prod10_loss_grc(g) = this%prod10_grc(g) * kprod10 this%prod100_loss_grc(g) = this%prod100_grc(g) * kprod100 end do @@ -513,11 +564,13 @@ subroutine UpdateProducts(this, bounds, & ! fluxes into wood & grain product pools, from harvest this%cropprod1_grc(g) = this%cropprod1_grc(g) + this%grain_to_cropprod1_grc(g)*dt + this%biofuelprod1_grc(g) = this%biofuelprod1_grc(g) + this%biofuel_to_cropprod1_grc(g)*dt this%prod10_grc(g) = this%prod10_grc(g) + this%hrv_deadstem_to_prod10_grc(g)*dt this%prod100_grc(g) = this%prod100_grc(g) + this%hrv_deadstem_to_prod100_grc(g)*dt ! fluxes out of wood & grain product pools, from decomposition this%cropprod1_grc(g) = this%cropprod1_grc(g) - this%cropprod1_loss_grc(g)*dt + this%biofuelprod1_grc(g) = this%biofuelprod1_grc(g) - this%biofuelprod1_loss_grc(g)*dt this%prod10_grc(g) = this%prod10_grc(g) - this%prod10_loss_grc(g)*dt this%prod100_grc(g) = this%prod100_grc(g) - this%prod100_loss_grc(g)*dt @@ -632,7 +685,8 @@ end subroutine PartitionWoodFluxes subroutine PartitionGrainFluxes(this, bounds, & num_soilp, filter_soilp, & dwt_crop_product_gain_patch, & - grain_to_cropprod_patch) + grain_to_cropprod_patch, & + biofuel_to_cropprod_patch) ! ! !DESCRIPTION: ! Partition input grain fluxes into crop product pools @@ -657,6 +711,9 @@ subroutine PartitionGrainFluxes(this, bounds, & ! grain to crop product pool(s) (g/m2/s) [patch] real(r8) , intent(in) :: grain_to_cropprod_patch( bounds%begp: ) + + ! biofuel to crop product pool(s) (g/m2/s) [patch] + real(r8) , intent(in) :: biofuel_to_cropprod_patch( bounds%begp: ) ! ! !LOCAL VARIABLES: integer :: fp @@ -673,6 +730,7 @@ subroutine PartitionGrainFluxes(this, bounds, & ! For now all crop product is put in the 1-year crop product pool this%grain_to_cropprod1_patch(p) = grain_to_cropprod_patch(p) + this%biofuel_to_cropprod1_patch(p) = biofuel_to_cropprod_patch(p) end do call p2g(bounds, & @@ -682,6 +740,13 @@ subroutine PartitionGrainFluxes(this, bounds, & c2l_scale_type = 'unity', & l2g_scale_type = 'unity') + + call p2g(bounds, & + this%biofuel_to_cropprod1_patch(bounds%begp:bounds%endp), & + this%biofuel_to_cropprod1_grc(bounds%begg:bounds%endg), & + p2c_scale_type = 'unity', & + c2l_scale_type = 'unity', & + l2g_scale_type = 'unity') ! Determine gains from dynamic landcover do g = bounds%begg, bounds%endg @@ -735,7 +800,8 @@ subroutine ComputeSummaryVars(this, bounds) this%product_loss_grc(g) = & this%cropprod1_loss_grc(g) + & this%prod10_loss_grc(g) + & - this%prod100_loss_grc(g) + this%prod100_loss_grc(g) + & + this%biofuelprod1_loss_grc(g) this%dwt_woodprod_gain_grc(g) = & this%dwt_prod100_gain_grc(g) + & From c4996447764b9e3f6ccc44a1b25ca54b9401f118 Mon Sep 17 00:00:00 2001 From: chen693 Date: Sun, 15 Mar 2020 20:55:38 -0700 Subject: [PATCH 15/75] active pft ID for swithchgrass and miscanthus --- src/biogeochem/CNVegStructUpdateMod.F90 | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/biogeochem/CNVegStructUpdateMod.F90 b/src/biogeochem/CNVegStructUpdateMod.F90 index b3556a367e..6f5b19476e 100644 --- a/src/biogeochem/CNVegStructUpdateMod.F90 +++ b/src/biogeochem/CNVegStructUpdateMod.F90 @@ -41,7 +41,6 @@ subroutine CNVegStructUpdate(num_soilp, filter_soilp, & use pftconMod , only : ntmp_corn, nirrig_tmp_corn use pftconMod , only : ntrp_corn, nirrig_trp_corn use pftconMod , only : nsugarcane, nirrig_sugarcane - ! Y. Cheng use pftconMod , only : nmiscanthus, nirrig_miscanthus, nswitchgrass, nirrig_switchgrass use pftconMod , only : pftcon @@ -233,7 +232,6 @@ subroutine CNVegStructUpdate(num_soilp, filter_soilp, & if (tlai(p) >= laimx(ivt(p))) peaklai(p) = 1 ! used in CNAllocation - ! Y. Cheng, add switchgrass and Miscanthus if (ivt(p) == ntmp_corn .or. ivt(p) == nirrig_tmp_corn .or. & ivt(p) == ntrp_corn .or. ivt(p) == nirrig_trp_corn .or. & ivt(p) == nsugarcane .or. ivt(p) == nirrig_sugarcane .or. & From 6ab17385b0cee0a3cf84e7d9ca28984b2d8749ab Mon Sep 17 00:00:00 2001 From: chen693 Date: Sun, 15 Mar 2020 20:55:41 -0700 Subject: [PATCH 16/75] update leaf N and livestem N --- src/biogeochem/CNCStateUpdate1Mod.F90 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/biogeochem/CNCStateUpdate1Mod.F90 b/src/biogeochem/CNCStateUpdate1Mod.F90 index 0e4eb08fe1..628ad6ac43 100644 --- a/src/biogeochem/CNCStateUpdate1Mod.F90 +++ b/src/biogeochem/CNCStateUpdate1Mod.F90 @@ -171,6 +171,7 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, & ivt => patch%itype , & ! Input: [integer (:) ] patch vegetation type woody => pftcon%woody , & ! Input: binary flag for woody lifeform (1=woody, 0=not woody) + harvfrac => pftcon%harvfrac , & ! Input: cut fraction for harvest (-) cascade_donor_pool => decomp_cascade_con%cascade_donor_pool , & ! Input: [integer (:) ] which pool is C taken from for a given decomposition step cascade_receiver_pool => decomp_cascade_con%cascade_receiver_pool , & ! Input: [integer (:) ] which pool is C added to for a given decomposition step @@ -274,10 +275,8 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, & ! phenology: litterfall fluxes cs_veg%leafc_patch(p) = cs_veg%leafc_patch(p) - cf_veg%leafc_to_litter_patch(p)*dt + cs_veg%leafc_patch(p) = cs_veg%leafc_patch(p) - cf_veg%leafc_to_biofuelc_patch(p)*dt cs_veg%frootc_patch(p) = cs_veg%frootc_patch(p) - cf_veg%frootc_to_litter_patch(p)*dt - - - ! livewood turnover fluxes if (woody(ivt(p)) == 1._r8) then @@ -288,6 +287,7 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, & end if if (ivt(p) >= npcropmin) then ! skip 2 generic crops cs_veg%livestemc_patch(p) = cs_veg%livestemc_patch(p) - cf_veg%livestemc_to_litter_patch(p)*dt + cs_veg%livestemc_patch(p) = cs_veg%livestemc_patch(p) - cf_veg%livestemc_to_biofuelc_patch(p)*dt cs_veg%grainc_patch(p) = cs_veg%grainc_patch(p) & - (cf_veg%grainc_to_food_patch(p) + cf_veg%grainc_to_seed_patch(p))*dt cs_veg%cropseedc_deficit_patch(p) = cs_veg%cropseedc_deficit_patch(p) & From 8e91a2504323286d9aede28348b89983d1dda3c9 Mon Sep 17 00:00:00 2001 From: chen693 Date: Sun, 15 Mar 2020 20:55:45 -0700 Subject: [PATCH 17/75] update leaf N and livestem N --- src/biogeochem/CNNStateUpdate1Mod.F90 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/biogeochem/CNNStateUpdate1Mod.F90 b/src/biogeochem/CNNStateUpdate1Mod.F90 index 996426246a..8c6c0c2968 100644 --- a/src/biogeochem/CNNStateUpdate1Mod.F90 +++ b/src/biogeochem/CNNStateUpdate1Mod.F90 @@ -175,6 +175,7 @@ subroutine NStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp, & ! phenology: litterfall and retranslocation fluxes ns_veg%leafn_patch(p) = ns_veg%leafn_patch(p) - nf_veg%leafn_to_litter_patch(p)*dt + ns_veg%leafn_patch(p) = ns_veg%leafn_patch(p) - nf_veg%leafn_to_biofueln_patch(p)*dt ns_veg%frootn_patch(p) = ns_veg%frootn_patch(p) - nf_veg%frootn_to_litter_patch(p)*dt ns_veg%leafn_patch(p) = ns_veg%leafn_patch(p) - nf_veg%leafn_to_retransn_patch(p)*dt ns_veg%retransn_patch(p) = ns_veg%retransn_patch(p) + nf_veg%leafn_to_retransn_patch(p)*dt @@ -194,6 +195,7 @@ subroutine NStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp, & ns_veg%frootn_patch(p) = ns_veg%frootn_patch(p) - nf_veg%frootn_to_retransn_patch(p)*dt ns_veg%retransn_patch(p) = ns_veg%retransn_patch(p) + nf_veg%frootn_to_retransn_patch(p)*dt ns_veg%livestemn_patch(p) = ns_veg%livestemn_patch(p) - nf_veg%livestemn_to_litter_patch(p)*dt + ns_veg%livestemn_patch(p) = ns_veg%livestemn_patch(p) - nf_veg%livestemn_to_biofueln_patch(p)*dt ns_veg%livestemn_patch(p) = ns_veg%livestemn_patch(p) - nf_veg%livestemn_to_retransn_patch(p)*dt ns_veg%retransn_patch(p) = ns_veg%retransn_patch(p) + nf_veg%livestemn_to_retransn_patch(p)*dt ns_veg%grainn_patch(p) = ns_veg%grainn_patch(p) & From 9825116fe5cc298c64e0e300f30ac099c42cc841 Mon Sep 17 00:00:00 2001 From: chen693 Date: Sun, 15 Mar 2020 20:55:49 -0700 Subject: [PATCH 18/75] update CN balance check to include biofuel product pool --- src/biogeochem/CNBalanceCheckMod.F90 | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/biogeochem/CNBalanceCheckMod.F90 b/src/biogeochem/CNBalanceCheckMod.F90 index b9a5355d46..4f78fc6ac7 100644 --- a/src/biogeochem/CNBalanceCheckMod.F90 +++ b/src/biogeochem/CNBalanceCheckMod.F90 @@ -142,6 +142,7 @@ subroutine CBalanceCheck(this, bounds, num_soilc, filter_soilc, & 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) grainc_to_cropprodc => cnveg_carbonflux_inst%grainc_to_cropprodc_col , & ! Input: [real(r8) (:) ] (gC/m2/s) grain C to 1-year crop product pool + biofuelc_to_cropprodc => cnveg_carbonflux_inst%biofuelc_to_cropprodc_col , & ! Input: [real(r8) (:) ] (gC/m2/s) biofuel 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 col_fire_closs => cnveg_carbonflux_inst%fire_closs_col , & ! Input: [real(r8) (:) ] (gC/m2/s) total column-level fire C loss @@ -176,7 +177,8 @@ subroutine CBalanceCheck(this, bounds, num_soilc, filter_soilc, & ! after the dwt term has already been taken out.) col_coutputs = col_coutputs + & wood_harvestc(c) + & - grainc_to_cropprodc(c) + grainc_to_cropprodc(c) + & + biofuelc_to_cropprodc(c) ! subtract leaching flux col_coutputs = col_coutputs - som_c_leached(c) @@ -213,6 +215,7 @@ subroutine CBalanceCheck(this, bounds, num_soilc, filter_soilc, & write(iulog,*)'col_hrv_xsmrpool_to_atm = ',col_hrv_xsmrpool_to_atm(c)*dt write(iulog,*)'wood_harvestc = ',wood_harvestc(c)*dt write(iulog,*)'grainc_to_cropprodc = ',grainc_to_cropprodc(c)*dt + write(iulog,*)'biofuelc_to_cropprodc = ',biofuelc_to_cropprodc(c)*dt write(iulog,*)'-1*som_c_leached = ',som_c_leached(c)*dt call endrun(msg=errMsg(sourcefile, __LINE__)) end if @@ -269,7 +272,7 @@ 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) grainn_to_cropprodn => cnveg_nitrogenflux_inst%grainn_to_cropprodn_col , & ! Input: [real(r8) (:) ] (gN/m2/s) grain N to 1-year crop product pool - + biofueln_to_cropprodn => cnveg_nitrogenflux_inst%biofueln_to_cropprodn_col , & ! Input: [real(r8) (:) ] (gN/m2/s) biofuel N to 1-year crop product pool totcoln => cnveg_nitrogenstate_inst%totn_col & ! Input: [real(r8) (:) ] (gN/m2) total column nitrogen, incl veg ) @@ -304,7 +307,8 @@ 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) + & - grainn_to_cropprodn(c) + grainn_to_cropprodn(c) + & + biofueln_to_cropprodn(c) if (.not. use_nitrif_denitrif) then col_noutputs(c) = col_noutputs(c) + sminn_leached(c) From 39bdf9b5820835800e5492fe43dd77a1f481d314 Mon Sep 17 00:00:00 2001 From: chen693 Date: Sun, 15 Mar 2020 23:34:30 -0700 Subject: [PATCH 19/75] cut a certain fraction of crop aboveground biomass during offset period --- src/biogeochem/CNPhenologyMod.F90 | 1 - 1 file changed, 1 deletion(-) diff --git a/src/biogeochem/CNPhenologyMod.F90 b/src/biogeochem/CNPhenologyMod.F90 index 0439af76d4..1b62a3244a 100644 --- a/src/biogeochem/CNPhenologyMod.F90 +++ b/src/biogeochem/CNPhenologyMod.F90 @@ -2411,7 +2411,6 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, & leafcn => pftcon%leafcn , & ! Input: leaf C:N (gC/gN) - ! Y. Cheng, add a new cut fraction for harvest parameter for bioenergy crops (miscanthus and switchgrass) harvfrac => pftcon%harvfrac , & ! Input: cut fraction for harvest (-) lflitcn => pftcon%lflitcn , & ! Input: leaf litter C:N (gC/gN) From d2aad1fe43aa7339dc60379d9243cf42f78031df Mon Sep 17 00:00:00 2001 From: chen693 Date: Sun, 15 Mar 2020 23:42:06 -0700 Subject: [PATCH 20/75] add a parameter for cutting a certain fraction of crop aboveground biomass at harvest --- src/main/pftconMod.F90 | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/pftconMod.F90 b/src/main/pftconMod.F90 index 4e5e60b3bb..a7237531d9 100644 --- a/src/main/pftconMod.F90 +++ b/src/main/pftconMod.F90 @@ -661,7 +661,6 @@ subroutine InitRead(this) call ncd_io('leafcn', this%leafcn, 'read', ncid, readvar=readv, posNOTonfile=.true.) if ( .not. readv ) call endrun(msg=' ERROR: error in reading in pft data'//errMsg(sourcefile, __LINE__)) - ! Y. Cheng, harvest fraction for crops during offset period call ncd_io('harvfrac', this%harvfrac, 'read', ncid, readvar=readv, posNOTonfile=.true.) if ( .not. readv ) call endrun(msg=' ERROR: error in reading in pft data'//errMsg(sourcefile, __LINE__)) From ce983bac0aa20facd01ef77d006086111118cd6e Mon Sep 17 00:00:00 2001 From: Bill Sacks Date: Mon, 16 Mar 2020 15:49:21 -0600 Subject: [PATCH 21/75] Fix restart routine for new bioenergy pool --- src/biogeochem/CNProductsMod.F90 | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/src/biogeochem/CNProductsMod.F90 b/src/biogeochem/CNProductsMod.F90 index 8c6134c445..dee95a41eb 100644 --- a/src/biogeochem/CNProductsMod.F90 +++ b/src/biogeochem/CNProductsMod.F90 @@ -385,13 +385,6 @@ subroutine Restart(this, bounds, ncid, flag, & xtype=ncd_double, dim1name='gridcell', & long_name='', units='', & interpinic_flag='interp', readvar=readvar, data=this%cropprod1_grc) - - call restartvar(ncid=ncid, flag=flag, & - varname=this%species%rest_fname('biofuelprod1', suffix='_g'), & - xtype=ncd_double, dim1name='gridcell', & - long_name='', units='', & - interpinic_flag='interp', readvar=readvar, data=this%biofuelprod1_grc) - if (flag == 'read' .and. .not. readvar) then ! BACKWARDS_COMPATIBILITY(wjs, 2016-03-31) If the gridcell-level field isn't ! present, try to find a column-level field (which may be present on an older @@ -403,26 +396,26 @@ subroutine Restart(this, bounds, ncid, flag, & data_grc = this%cropprod1_grc, & readvar = readvar) - call set_grc_field_from_col_field( & - bounds = bounds, & - ncid = ncid, & - varname = this%species%rest_fname('biofuelprod1'), & - data_grc = this%biofuelprod1_grc, & - readvar = readvar) - ! If we still haven't found an appropriate field on the restart file, then set ! this field from the template, if provided if (.not. readvar .and. template_provided) then call set_missing_from_template(this%cropprod1_grc, & template_for_missing_fields%cropprod1_grc, & multiplier = template_multiplier) - - call set_missing_from_template(this%biofuelprod1_grc, & - template_for_missing_fields%biofuelprod1_grc, & - multiplier = template_multiplier) end if end if + call restartvar(ncid=ncid, flag=flag, & + varname=this%species%rest_fname('biofuelprod1', suffix='_g'), & + xtype=ncd_double, dim1name='gridcell', & + long_name='', units='', & + interpinic_flag='interp', readvar=readvar, data=this%biofuelprod1_grc) + if (.not. readvar .and. template_provided) then + call set_missing_from_template(this%biofuelprod1_grc, & + template_for_missing_fields%biofuelprod1_grc, & + multiplier = template_multiplier) + end if + call restartvar(ncid=ncid, flag=flag, & varname=this%species%rest_fname('prod10', suffix='_g'), & xtype=ncd_double, dim1name='gridcell', & From 3b3a330d74ad3344c01ad81cf1fd11b171366821 Mon Sep 17 00:00:00 2001 From: Bill Sacks Date: Mon, 16 Mar 2020 16:06:33 -0600 Subject: [PATCH 22/75] Whitespace cleanup --- src/biogeochem/CNProductsMod.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/biogeochem/CNProductsMod.F90 b/src/biogeochem/CNProductsMod.F90 index dee95a41eb..bcdfd95618 100644 --- a/src/biogeochem/CNProductsMod.F90 +++ b/src/biogeochem/CNProductsMod.F90 @@ -192,7 +192,7 @@ subroutine InitHistory(this, bounds) long_name = '1-yr grain product ' // this%species%get_species(), & ptr_gcell = this%cropprod1_grc, default=active_if_non_isotope) - this%biofuelprod1_grc(begg:endg) = spval + this%biofuelprod1_grc(begg:endg) = spval call hist_addfld1d( & fname = this%species%hist_fname('BIOFUELPROD1'), & units = 'g' // this%species%get_species() // '/m^2', & @@ -264,7 +264,7 @@ subroutine InitHistory(this, bounds) long_name = 'loss from 1-yr grain product pool', & ptr_gcell = this%cropprod1_loss_grc, default=active_if_non_isotope) - this%biofuelprod1_loss_grc(begg:endg) = spval + this%biofuelprod1_loss_grc(begg:endg) = spval call hist_addfld1d( & fname = this%species%hist_fname('BIOFUELPROD1', suffix='_LOSS'), & units = 'g' // this%species%get_species() // '/m^2/s', & From c45206ab30a09a5b0e831a6f3617afc1f6462e7d Mon Sep 17 00:00:00 2001 From: Bill Sacks Date: Mon, 16 Mar 2020 16:16:56 -0600 Subject: [PATCH 23/75] Remove unnecessary variable from associate --- src/biogeochem/CNCStateUpdate1Mod.F90 | 1 - 1 file changed, 1 deletion(-) diff --git a/src/biogeochem/CNCStateUpdate1Mod.F90 b/src/biogeochem/CNCStateUpdate1Mod.F90 index 628ad6ac43..47794240a5 100644 --- a/src/biogeochem/CNCStateUpdate1Mod.F90 +++ b/src/biogeochem/CNCStateUpdate1Mod.F90 @@ -171,7 +171,6 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, & ivt => patch%itype , & ! Input: [integer (:) ] patch vegetation type woody => pftcon%woody , & ! Input: binary flag for woody lifeform (1=woody, 0=not woody) - harvfrac => pftcon%harvfrac , & ! Input: cut fraction for harvest (-) cascade_donor_pool => decomp_cascade_con%cascade_donor_pool , & ! Input: [integer (:) ] which pool is C taken from for a given decomposition step cascade_receiver_pool => decomp_cascade_con%cascade_receiver_pool , & ! Input: [integer (:) ] which pool is C added to for a given decomposition step From 78da215cb2fd55be45b33c36c5843b76aded54d3 Mon Sep 17 00:00:00 2001 From: Bill Sacks Date: Mon, 16 Mar 2020 16:31:48 -0600 Subject: [PATCH 24/75] Bioenergy fluxes to product pools apply regardless of use_grainproduct --- src/biogeochem/CNCIsoFluxMod.F90 | 11 +++++-- src/biogeochem/CNPhenologyMod.F90 | 53 ++++++++++++++++--------------- 2 files changed, 36 insertions(+), 28 deletions(-) diff --git a/src/biogeochem/CNCIsoFluxMod.F90 b/src/biogeochem/CNCIsoFluxMod.F90 index 8461d1ef54..cfa280f678 100644 --- a/src/biogeochem/CNCIsoFluxMod.F90 +++ b/src/biogeochem/CNCIsoFluxMod.F90 @@ -404,12 +404,12 @@ subroutine CIsoFlux1(num_soilc, filter_soilc, num_soilp, filter_soilp, & iso_cnveg_cs%grainc_patch , cnveg_cs%grainc_patch, & num_soilp , filter_soilp, 1._r8, 0, isotope) - call CIsoFluxCalc(& + call CIsoFluxCalc(& iso_cnveg_cf%leafc_to_biofuelc_patch , cnveg_cf%leafc_to_biofuelc_patch, & iso_cnveg_cs%leafc_patch , cnveg_cs%leafc_patch, & num_soilp , filter_soilp, 1._r8, 0, isotope) - call CIsoFluxCalc(& + call CIsoFluxCalc(& iso_cnveg_cf%livestemc_to_biofuelc_patch , cnveg_cf%livestemc_to_biofuelc_patch, & iso_cnveg_cs%livestemc_patch , cnveg_cs%livestemc_patch, & num_soilp , filter_soilp, 1._r8, 0, isotope) @@ -469,11 +469,16 @@ subroutine CIsoFlux1(num_soilc, filter_soilc, num_soilp, filter_soilp, & iso_cnveg_cs%livestemc_patch , cnveg_cs%livestemc_patch, & num_soilp , filter_soilp, 1._r8, 0, isotope) + do fp = 1,num_soilp + p = filter_soilp(fp) + iso_cnveg_cf%biofuelc_to_cropprodc_patch(p) = iso_cnveg_cf%leafc_to_biofuelc_patch(p) + & + iso_cnveg_cf%livestemc_to_biofuelc_patch(p) + end do + if (use_grainproduct) then do fp = 1,num_soilp p = filter_soilp(fp) iso_cnveg_cf%grainc_to_cropprodc_patch(p) = iso_cnveg_cf%grainc_to_food_patch(p) - iso_cnveg_cf%biofuelc_to_cropprodc_patch(p) = iso_cnveg_cf%leafc_to_biofuelc_patch(p)+iso_cnveg_cf%livestemc_to_biofuelc_patch(p) iso_cnveg_cf%grain_mr_patch(p) = iso_cnveg_cf%grain_xsmr_patch(p) + iso_cnveg_cf%grain_curmr_patch(p) end do endif diff --git a/src/biogeochem/CNPhenologyMod.F90 b/src/biogeochem/CNPhenologyMod.F90 index 1b62a3244a..5c9c132d9e 100644 --- a/src/biogeochem/CNPhenologyMod.F90 +++ b/src/biogeochem/CNPhenologyMod.F90 @@ -328,7 +328,7 @@ subroutine CNPhenology (bounds, num_soilc, filter_soilc, num_soilp, & call CNLivewoodTurnover(num_soilp, filter_soilp, & cnveg_carbonstate_inst, cnveg_nitrogenstate_inst, cnveg_carbonflux_inst, cnveg_nitrogenflux_inst) - call CNGrainToProductPools(bounds, num_soilp, filter_soilp, num_soilc, filter_soilc, & + call CNCropHarvestToProductPools(bounds, num_soilp, filter_soilp, num_soilc, filter_soilc, & cnveg_carbonflux_inst, cnveg_nitrogenflux_inst) ! gather all patch-level litterfall fluxes to the column for litter C and N inputs @@ -2833,12 +2833,12 @@ subroutine CNLivewoodTurnover (num_soilp, filter_soilp, & end subroutine CNLivewoodTurnover !----------------------------------------------------------------------- - subroutine CNGrainToProductPools(bounds, num_soilp, filter_soilp, num_soilc, filter_soilc, & + subroutine CNCropHarvestToProductPools(bounds, num_soilp, filter_soilp, num_soilc, filter_soilc, & cnveg_carbonflux_inst, cnveg_nitrogenflux_inst) ! ! !DESCRIPTION: - ! If using prognostic crop along with use_grainproduct, then move the patch-level - ! grain-to-food fluxes into the column-level grain-to-cropprod fluxes + ! If using prognostic crop, then move any necessary harvested amounts into fluxes + ! destined for the product pools. ! ! !USES: use clm_varctl , only : use_crop @@ -2857,33 +2857,18 @@ subroutine CNGrainToProductPools(bounds, num_soilp, filter_soilp, num_soilc, fil ! !LOCAL VARIABLES: integer :: fp, p - character(len=*), parameter :: subname = 'CNGrainToProductPools' + character(len=*), parameter :: subname = 'CNCropHarvestToProductPools' !----------------------------------------------------------------------- - ! Explicitly checking use_crop is probably unnecessary here (because presumably - ! use_grainproduct is only true if use_crop is true), but we do it for safety because - ! the grain*_to_food_patch fluxes are not set if use_crop is false. - if (use_crop .and. use_grainproduct) then + if (use_crop) then do fp = 1, num_soilp p = filter_soilp(fp) - cnveg_carbonflux_inst%grainc_to_cropprodc_patch(p) = & - cnveg_carbonflux_inst%grainc_to_food_patch(p) - cnveg_nitrogenflux_inst%grainn_to_cropprodn_patch(p) = & - cnveg_nitrogenflux_inst%grainn_to_food_patch(p) cnveg_carbonflux_inst%biofuelc_to_cropprodc_patch(p) = & cnveg_carbonflux_inst%leafc_to_biofuelc_patch(p)+cnveg_carbonflux_inst%livestemc_to_biofuelc_patch(p) cnveg_nitrogenflux_inst%biofueln_to_cropprodn_patch(p) = & cnveg_nitrogenflux_inst%leafn_to_biofueln_patch(p)+cnveg_nitrogenflux_inst%livestemn_to_biofueln_patch(p) end do - call p2c (bounds, num_soilc, filter_soilc, & - cnveg_carbonflux_inst%grainc_to_cropprodc_patch(bounds%begp:bounds%endp), & - cnveg_carbonflux_inst%grainc_to_cropprodc_col(bounds%begc:bounds%endc)) - - call p2c (bounds, num_soilc, filter_soilc, & - cnveg_nitrogenflux_inst%grainn_to_cropprodn_patch(bounds%begp:bounds%endp), & - cnveg_nitrogenflux_inst%grainn_to_cropprodn_col(bounds%begc:bounds%endc)) - call p2c (bounds, num_soilc, filter_soilc, & cnveg_carbonflux_inst%biofuelc_to_cropprodc_patch(bounds%begp:bounds%endp), & cnveg_carbonflux_inst%biofuelc_to_cropprodc_col(bounds%begc:bounds%endc)) @@ -2891,12 +2876,30 @@ subroutine CNGrainToProductPools(bounds, num_soilp, filter_soilp, num_soilc, fil call p2c (bounds, num_soilc, filter_soilc, & cnveg_nitrogenflux_inst%biofueln_to_cropprodn_patch(bounds%begp:bounds%endp), & cnveg_nitrogenflux_inst%biofueln_to_cropprodn_col(bounds%begc:bounds%endc)) - end if - ! No else clause: if use_grainproduct is false, then the grain*_to_cropprod fluxes - ! will remain at their initial value (0). + if (use_grainproduct) then + do fp = 1, num_soilp + p = filter_soilp(fp) + cnveg_carbonflux_inst%grainc_to_cropprodc_patch(p) = & + cnveg_carbonflux_inst%grainc_to_food_patch(p) + cnveg_nitrogenflux_inst%grainn_to_cropprodn_patch(p) = & + cnveg_nitrogenflux_inst%grainn_to_food_patch(p) + end do + + call p2c (bounds, num_soilc, filter_soilc, & + cnveg_carbonflux_inst%grainc_to_cropprodc_patch(bounds%begp:bounds%endp), & + cnveg_carbonflux_inst%grainc_to_cropprodc_col(bounds%begc:bounds%endc)) + + call p2c (bounds, num_soilc, filter_soilc, & + cnveg_nitrogenflux_inst%grainn_to_cropprodn_patch(bounds%begp:bounds%endp), & + cnveg_nitrogenflux_inst%grainn_to_cropprodn_col(bounds%begc:bounds%endc)) + end if + ! No else clause: if use_grainproduct is false, then the grain*_to_cropprod fluxes + ! will remain at their initial value (0). + + end if - end subroutine CNGrainToProductPools + end subroutine CNCropHarvestToProductPools !----------------------------------------------------------------------- subroutine CNLitterToColumn (bounds, num_soilc, filter_soilc, & From 5beb9b1cfa7f4a6faad87ece106d4f507bfde475 Mon Sep 17 00:00:00 2001 From: Bill Sacks Date: Tue, 17 Mar 2020 14:30:41 -0600 Subject: [PATCH 25/75] Fix some indentation --- src/biogeochem/CNPhenologyMod.F90 | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/biogeochem/CNPhenologyMod.F90 b/src/biogeochem/CNPhenologyMod.F90 index 5c9c132d9e..af0908dce9 100644 --- a/src/biogeochem/CNPhenologyMod.F90 +++ b/src/biogeochem/CNPhenologyMod.F90 @@ -2474,11 +2474,11 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, & frootc_to_litter(p) = t1 * frootc(p) + cpool_to_frootc(p) ! Cut a certain fraction (i.e., harvfrac(ivt(p))) (e.g., harvfrac(ivt(p)=70% for bioenergy crops) of leaf C - ! and move this fration of leaf C to biofuel C, rather than move it to litter - leafc_to_litter(p) = t1 * leafc(p)*(1._r8-harvfrac(ivt(p))) + cpool_to_leafc(p) - leafc_to_biofuelc(p) = t1 * leafc(p) * harvfrac(ivt(p)) - leafn_to_biofueln(p) = t1 * leafn(p) * harvfrac(ivt(p)) - + ! and move this fration of leaf C to biofuel C, rather than move it to litter + leafc_to_litter(p) = t1 * leafc(p)*(1._r8-harvfrac(ivt(p))) + cpool_to_leafc(p) + leafc_to_biofuelc(p) = t1 * leafc(p) * harvfrac(ivt(p)) + leafn_to_biofueln(p) = t1 * leafn(p) * harvfrac(ivt(p)) + ! this assumes that offset_counter == dt for crops ! if this were ever changed, we'd need to add code to the "else" if (ivt(p) >= npcropmin) then @@ -2489,14 +2489,14 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, & grainc_to_seed(p) = t1 * min(-cropseedc_deficit(p), grainc(p)) grainn_to_seed(p) = t1 * min(-cropseedn_deficit(p), grainn(p)) ! Send the remaining grain to the food product pool - grainc_to_food(p) = t1 * grainc(p) + cpool_to_grainc(p) - grainc_to_seed(p) + grainc_to_food(p) = t1 * grainc(p) + cpool_to_grainc(p) - grainc_to_seed(p) grainn_to_food(p) = t1 * grainn(p) + npool_to_grainn(p) - grainn_to_seed(p) - ! Cut a certain fraction (i.e., harvfrac(ivt(p))) (e.g., harvfrac(ivt(p)=70% for bioenergy crops) of livestem C - ! and move this fration of leaf C to biofuel C, rather than move it to litter + ! Cut a certain fraction (i.e., harvfrac(ivt(p))) (e.g., harvfrac(ivt(p)=70% for bioenergy crops) of livestem C + ! and move this fration of leaf C to biofuel C, rather than move it to litter livestemc_to_litter(p) = t1 * livestemc(p)*(1._r8-harvfrac(ivt(p))) + cpool_to_livestemc(p) livestemc_to_biofuelc(p) = t1 * livestemc(p) * harvfrac(ivt(p)) - livestemn_to_biofueln(p) = t1 * livestemn(p) * harvfrac(ivt(p)) + livestemn_to_biofueln(p) = t1 * livestemn(p) * harvfrac(ivt(p)) end if else t1 = dt * 2.0_r8 / (offset_counter(p) * offset_counter(p)) From cefdaaa153c636ae692bcaba1b9eeff84a7debc3 Mon Sep 17 00:00:00 2001 From: chen693 Date: Sun, 22 Mar 2020 20:16:44 -0700 Subject: [PATCH 26/75] fix indentation and remove unnecessary restart variables --- src/biogeochem/CNVegCarbonFluxType.F90 | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/biogeochem/CNVegCarbonFluxType.F90 b/src/biogeochem/CNVegCarbonFluxType.F90 index 3cf3fe56ba..33f7fdb412 100644 --- a/src/biogeochem/CNVegCarbonFluxType.F90 +++ b/src/biogeochem/CNVegCarbonFluxType.F90 @@ -838,12 +838,12 @@ subroutine InitHistory(this, bounds, carbon_type) avgflag='A', long_name='grain C to food', & ptr_patch=this%grainc_to_food_patch) - this%leafc_to_biofuelc_patch(begp:endp) = spval + this%leafc_to_biofuelc_patch(begp:endp) = spval call hist_addfld1d (fname='LEAFC_TO_BIOFUELC', units='gC/m^2/s', & avgflag='A', long_name='leaf C to biofuel C', & ptr_patch=this%leafc_to_biofuelc_patch) - this%livestemc_to_biofuelc_patch(begp:endp) = spval + this%livestemc_to_biofuelc_patch(begp:endp) = spval call hist_addfld1d (fname='LIVESTEMC_TO_BIOFUELC', units='gC/m^2/s', & avgflag='A', long_name='livestem C to biofuel C', & ptr_patch=this%livestemc_to_biofuelc_patch) @@ -3534,16 +3534,6 @@ subroutine RestartBulkOnly ( this, bounds, ncid, flag ) dim1name='pft', & long_name='grain C to food', units='gC/m2/s', & interpinic_flag='interp', readvar=readvar, data=this%grainc_to_food_patch) - - call restartvar(ncid=ncid, flag=flag, varname='leafc_to_biofuelc', xtype=ncd_double, & - dim1name='pft', & - long_name='leaf C to biofuel C', units='gC/m2/s', & - interpinic_flag='interp', readvar=readvar, data=this%leafc_to_biofuelc_patch) - - call restartvar(ncid=ncid, flag=flag, varname='livestemc_to_biofuelc', xtype=ncd_double, & - dim1name='pft', & - long_name='livestem C to biofuel C', units='gC/m2/s', & - interpinic_flag='interp', readvar=readvar, data=this%livestemc_to_biofuelc_patch) call restartvar(ncid=ncid, flag=flag, varname='cpool_to_grainc', xtype=ncd_double, & dim1name='pft', & From cd591c2688dd60154563d7209fbabf337e40f60d Mon Sep 17 00:00:00 2001 From: chen693 Date: Sun, 22 Mar 2020 20:17:36 -0700 Subject: [PATCH 27/75] fix indentation --- src/biogeochem/CNVegNitrogenFluxType.F90 | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/biogeochem/CNVegNitrogenFluxType.F90 b/src/biogeochem/CNVegNitrogenFluxType.F90 index b79f71986f..a287d5dc0f 100644 --- a/src/biogeochem/CNVegNitrogenFluxType.F90 +++ b/src/biogeochem/CNVegNitrogenFluxType.F90 @@ -1379,20 +1379,6 @@ subroutine Restart (this, bounds, ncid, flag ) interpinic_flag='interp', readvar=readvar, data=this%grainn_to_food_patch) end if - if (use_crop) then - call restartvar(ncid=ncid, flag=flag, varname='leafn_to_biofueln', xtype=ncd_double, & - dim1name='pft', & - long_name='leaf N to biofuel N', units='gN/m2/s', & - interpinic_flag='interp', readvar=readvar, data=this%leafn_to_biofueln_patch) - end if - - if (use_crop) then - call restartvar(ncid=ncid, flag=flag, varname='livestemn_to_biofueln', xtype=ncd_double, & - dim1name='pft', & - long_name='livestem N to biofuel N', units='gN/m2/s', & - interpinic_flag='interp', readvar=readvar, data=this%livestemn_to_biofueln_patch) - end if - if (use_crop) then call restartvar(ncid=ncid, flag=flag, varname='npool_to_grainn', xtype=ncd_double, & dim1name='pft', & From c6f037aff98dcf50fabe39710c3390507731654c Mon Sep 17 00:00:00 2001 From: chen693 Date: Sun, 22 Mar 2020 20:21:11 -0700 Subject: [PATCH 28/75] move calculation of leafc_to_biofuelc to only for prognostic crops, change to longer growing season for bioenergy crops --- src/biogeochem/CNPhenologyMod.F90 | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/biogeochem/CNPhenologyMod.F90 b/src/biogeochem/CNPhenologyMod.F90 index af0908dce9..272747e61e 100644 --- a/src/biogeochem/CNPhenologyMod.F90 +++ b/src/biogeochem/CNPhenologyMod.F90 @@ -1972,7 +1972,11 @@ subroutine CropPhenology(num_pcropp, filter_pcropp , & ! the onset_counter would change from dt and you'd need to make ! changes to the offset subroutine below - else if (hui(p) >= gddmaturity(p) .or. idpp >= mxmat(ivt(p))) then + else if ((idpp >= mxmat(ivt(p)) .and. (ivt(p) == nmiscanthus .or. ivt(p) == nirrig_miscanthus .or. & + ivt(p) == nswitchgrass .or. ivt(p) == nirrig_switchgrass)) .or. & + ((hui(p) >= gddmaturity(p) .or. idpp >= mxmat(ivt(p))) .and. & + (ivt(p) /= nmiscanthus .and. ivt(p) /= nirrig_miscanthus .and. & + ivt(p) /= nswitchgrass .and. ivt(p) /= nirrig_switchgrass))) then if (harvdate(p) >= NOT_Harvested) harvdate(p) = jday croplive(p) = .false. ! no re-entry in greater if-block cphase(p) = 4._r8 @@ -2473,11 +2477,8 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, & t1 = 1.0_r8 / dt frootc_to_litter(p) = t1 * frootc(p) + cpool_to_frootc(p) - ! Cut a certain fraction (i.e., harvfrac(ivt(p))) (e.g., harvfrac(ivt(p)=70% for bioenergy crops) of leaf C - ! and move this fration of leaf C to biofuel C, rather than move it to litter + ! harvfrac is only non-zero for prognostic crops. leafc_to_litter(p) = t1 * leafc(p)*(1._r8-harvfrac(ivt(p))) + cpool_to_leafc(p) - leafc_to_biofuelc(p) = t1 * leafc(p) * harvfrac(ivt(p)) - leafn_to_biofueln(p) = t1 * leafn(p) * harvfrac(ivt(p)) ! this assumes that offset_counter == dt for crops ! if this were ever changed, we'd need to add code to the "else" @@ -2491,12 +2492,17 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, & ! Send the remaining grain to the food product pool grainc_to_food(p) = t1 * grainc(p) + cpool_to_grainc(p) - grainc_to_seed(p) grainn_to_food(p) = t1 * grainn(p) + npool_to_grainn(p) - grainn_to_seed(p) + + ! Cut a certain fraction (i.e., harvfrac(ivt(p))) (e.g., harvfrac(ivt(p)=70% for bioenergy crops) of leaf C + ! and move this fration of leaf C to biofuel C, rather than move it to litter + leafc_to_biofuelc(p) = t1 * leafc(p) * harvfrac(ivt(p)) + leafn_to_biofueln(p) = t1 * leafn(p) * harvfrac(ivt(p)) ! Cut a certain fraction (i.e., harvfrac(ivt(p))) (e.g., harvfrac(ivt(p)=70% for bioenergy crops) of livestem C ! and move this fration of leaf C to biofuel C, rather than move it to litter - livestemc_to_litter(p) = t1 * livestemc(p)*(1._r8-harvfrac(ivt(p))) + cpool_to_livestemc(p) + livestemc_to_litter(p) = t1 * livestemc(p)*(1._r8-harvfrac(ivt(p))) + cpool_to_livestemc(p) livestemc_to_biofuelc(p) = t1 * livestemc(p) * harvfrac(ivt(p)) - livestemn_to_biofueln(p) = t1 * livestemn(p) * harvfrac(ivt(p)) + livestemn_to_biofueln(p) = t1 * livestemn(p) * harvfrac(ivt(p)) end if else t1 = dt * 2.0_r8 / (offset_counter(p) * offset_counter(p)) @@ -2578,7 +2584,7 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, & ! NOTE(slevis, 2014-12) results in -ve livestemn and -ve totpftn !X! livestemn_to_litter(p) = livestemc_to_litter(p) / livewdcn(ivt(p)) ! NOTE(slevis, 2014-12) Beth Drewniak suggested this instead - livestemn_to_litter(p) = livestemn(p) / dt + livestemn_to_litter(p) = livestemn(p) / dt * (1 - harvfrac(ivt(p))) end if ! save the current litterfall fluxes From 39fcf0747e422f73d869abd8f7d40de52e741241 Mon Sep 17 00:00:00 2001 From: chen693 Date: Sun, 22 Mar 2020 21:01:12 -0700 Subject: [PATCH 29/75] remove unnecessary lines --- src/biogeochem/CNCIsoFluxMod.F90 | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/biogeochem/CNCIsoFluxMod.F90 b/src/biogeochem/CNCIsoFluxMod.F90 index cfa280f678..eeb6ebe435 100644 --- a/src/biogeochem/CNCIsoFluxMod.F90 +++ b/src/biogeochem/CNCIsoFluxMod.F90 @@ -1209,8 +1209,6 @@ subroutine CNCIsoLitterToColumn (num_soilc, filter_soilc, & !DML livestemc_to_litter => iso_cnveg_carbonflux_inst%livestemc_to_litter_patch , & ! Input: [real(r8) (:) ] grainc_to_food => iso_cnveg_carbonflux_inst%grainc_to_food_patch , & ! Input: [real(r8) (:) ] - leafc_to_biofuelc => iso_cnveg_carbonflux_inst%leafc_to_biofuelc_patch , & ! Input: [real(r8) (:) ] - livestemc_to_biofuelc => iso_cnveg_carbonflux_inst%livestemc_to_biofuelc_patch , & ! Input: [real(r8) (:) ] !DML phenology_c_to_litr_met_c => iso_cnveg_carbonflux_inst%phenology_c_to_litr_met_c_col , & ! InOut: [real(r8) (:,:) ] C fluxes associated with phenology (litterfall and crop) to litter metabolic pool (gC/m3/s) phenology_c_to_litr_cel_c => iso_cnveg_carbonflux_inst%phenology_c_to_litr_cel_c_col , & ! InOut: [real(r8) (:,:) ] C fluxes associated with phenology (litterfall and crop) to litter cellulose pool (gC/m3/s) From 38ca1b37f4fa2e281e221af91039a7fd992bb49d Mon Sep 17 00:00:00 2001 From: chen693 Date: Sun, 22 Mar 2020 21:01:59 -0700 Subject: [PATCH 30/75] fix indentation --- src/biogeochem/CNCStateUpdate1Mod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/biogeochem/CNCStateUpdate1Mod.F90 b/src/biogeochem/CNCStateUpdate1Mod.F90 index 47794240a5..7063c92214 100644 --- a/src/biogeochem/CNCStateUpdate1Mod.F90 +++ b/src/biogeochem/CNCStateUpdate1Mod.F90 @@ -274,7 +274,6 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, & ! phenology: litterfall fluxes cs_veg%leafc_patch(p) = cs_veg%leafc_patch(p) - cf_veg%leafc_to_litter_patch(p)*dt - cs_veg%leafc_patch(p) = cs_veg%leafc_patch(p) - cf_veg%leafc_to_biofuelc_patch(p)*dt cs_veg%frootc_patch(p) = cs_veg%frootc_patch(p) - cf_veg%frootc_to_litter_patch(p)*dt ! livewood turnover fluxes @@ -287,6 +286,7 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, & if (ivt(p) >= npcropmin) then ! skip 2 generic crops cs_veg%livestemc_patch(p) = cs_veg%livestemc_patch(p) - cf_veg%livestemc_to_litter_patch(p)*dt cs_veg%livestemc_patch(p) = cs_veg%livestemc_patch(p) - cf_veg%livestemc_to_biofuelc_patch(p)*dt + cs_veg%leafc_patch(p) = cs_veg%leafc_patch(p) - cf_veg%leafc_to_biofuelc_patch(p)*dt cs_veg%grainc_patch(p) = cs_veg%grainc_patch(p) & - (cf_veg%grainc_to_food_patch(p) + cf_veg%grainc_to_seed_patch(p))*dt cs_veg%cropseedc_deficit_patch(p) = cs_veg%cropseedc_deficit_patch(p) & From 8e141ad97043de3155426204b05de36bbd7554b5 Mon Sep 17 00:00:00 2001 From: chen693 Date: Sun, 22 Mar 2020 21:02:18 -0700 Subject: [PATCH 31/75] fix indentation --- src/biogeochem/CNNStateUpdate1Mod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/biogeochem/CNNStateUpdate1Mod.F90 b/src/biogeochem/CNNStateUpdate1Mod.F90 index 8c6c0c2968..e04e9dd831 100644 --- a/src/biogeochem/CNNStateUpdate1Mod.F90 +++ b/src/biogeochem/CNNStateUpdate1Mod.F90 @@ -175,7 +175,6 @@ subroutine NStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp, & ! phenology: litterfall and retranslocation fluxes ns_veg%leafn_patch(p) = ns_veg%leafn_patch(p) - nf_veg%leafn_to_litter_patch(p)*dt - ns_veg%leafn_patch(p) = ns_veg%leafn_patch(p) - nf_veg%leafn_to_biofueln_patch(p)*dt ns_veg%frootn_patch(p) = ns_veg%frootn_patch(p) - nf_veg%frootn_to_litter_patch(p)*dt ns_veg%leafn_patch(p) = ns_veg%leafn_patch(p) - nf_veg%leafn_to_retransn_patch(p)*dt ns_veg%retransn_patch(p) = ns_veg%retransn_patch(p) + nf_veg%leafn_to_retransn_patch(p)*dt @@ -196,6 +195,7 @@ subroutine NStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp, & ns_veg%retransn_patch(p) = ns_veg%retransn_patch(p) + nf_veg%frootn_to_retransn_patch(p)*dt ns_veg%livestemn_patch(p) = ns_veg%livestemn_patch(p) - nf_veg%livestemn_to_litter_patch(p)*dt ns_veg%livestemn_patch(p) = ns_veg%livestemn_patch(p) - nf_veg%livestemn_to_biofueln_patch(p)*dt + ns_veg%leafn_patch(p) = ns_veg%leafn_patch(p) - nf_veg%leafn_to_biofueln_patch(p)*dt ns_veg%livestemn_patch(p) = ns_veg%livestemn_patch(p) - nf_veg%livestemn_to_retransn_patch(p)*dt ns_veg%retransn_patch(p) = ns_veg%retransn_patch(p) + nf_veg%livestemn_to_retransn_patch(p)*dt ns_veg%grainn_patch(p) = ns_veg%grainn_patch(p) & From 0ec0288b3c342dd26799a7eb5a3d0b3d1179f391 Mon Sep 17 00:00:00 2001 From: chen693 Date: Sun, 22 Mar 2020 21:02:34 -0700 Subject: [PATCH 32/75] fix indentation --- src/biogeochem/CNBalanceCheckMod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/biogeochem/CNBalanceCheckMod.F90 b/src/biogeochem/CNBalanceCheckMod.F90 index 4f78fc6ac7..e780e4a804 100644 --- a/src/biogeochem/CNBalanceCheckMod.F90 +++ b/src/biogeochem/CNBalanceCheckMod.F90 @@ -272,7 +272,7 @@ 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) grainn_to_cropprodn => cnveg_nitrogenflux_inst%grainn_to_cropprodn_col , & ! Input: [real(r8) (:) ] (gN/m2/s) grain N to 1-year crop product pool - biofueln_to_cropprodn => cnveg_nitrogenflux_inst%biofueln_to_cropprodn_col , & ! Input: [real(r8) (:) ] (gN/m2/s) biofuel N to 1-year crop product pool + biofueln_to_cropprodn => cnveg_nitrogenflux_inst%biofueln_to_cropprodn_col , & ! Input: [real(r8) (:) ] (gN/m2/s) biofuel N to 1-year crop product pool totcoln => cnveg_nitrogenstate_inst%totn_col & ! Input: [real(r8) (:) ] (gN/m2) total column nitrogen, incl veg ) From 6e05416001e8a1b0bc960c5e615f625dbcfe612c Mon Sep 17 00:00:00 2001 From: chen693 Date: Sun, 29 Mar 2020 16:29:50 -0700 Subject: [PATCH 33/75] add the biofuel_harvfrac parameter for cutting a certain fraction of crop aboveground biomass for biofuel at harvest --- src/main/pftconMod.F90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/pftconMod.F90 b/src/main/pftconMod.F90 index a7237531d9..1fe80a9d31 100644 --- a/src/main/pftconMod.F90 +++ b/src/main/pftconMod.F90 @@ -134,7 +134,7 @@ module pftconMod real(r8), allocatable :: slatop (:) ! SLA at top of canopy [m^2/gC] real(r8), allocatable :: dsladlai (:) ! dSLA/dLAI [m^2/gC] real(r8), allocatable :: leafcn (:) ! leaf C:N [gC/gN] - real(r8), allocatable :: harvfrac (:) ! cut fraction for harvest [-] + real(r8), allocatable :: biofuel_harvfrac (:) ! cut a fraction of stem/leaf for biofuel [-] real(r8), allocatable :: flnr (:) ! fraction of leaf N in Rubisco [no units] real(r8), allocatable :: woody (:) ! woody lifeform flag (0 or 1) real(r8), allocatable :: lflitcn (:) ! leaf litter C:N (gC/gN) @@ -358,7 +358,7 @@ subroutine InitAllocate (this) allocate( this%slatop (0:mxpft) ) allocate( this%dsladlai (0:mxpft) ) allocate( this%leafcn (0:mxpft) ) - allocate( this%harvfrac (0:mxpft) ) + allocate( this%biofuel_harvfrac (0:mxpft) ) allocate( this%flnr (0:mxpft) ) allocate( this%woody (0:mxpft) ) allocate( this%lflitcn (0:mxpft) ) @@ -661,7 +661,7 @@ subroutine InitRead(this) call ncd_io('leafcn', this%leafcn, 'read', ncid, readvar=readv, posNOTonfile=.true.) if ( .not. readv ) call endrun(msg=' ERROR: error in reading in pft data'//errMsg(sourcefile, __LINE__)) - call ncd_io('harvfrac', this%harvfrac, 'read', ncid, readvar=readv, posNOTonfile=.true.) + call ncd_io('biofuel_harvfrac', this%biofuel_harvfrac, 'read', ncid, readvar=readv, posNOTonfile=.true.) if ( .not. readv ) call endrun(msg=' ERROR: error in reading in pft data'//errMsg(sourcefile, __LINE__)) call ncd_io('flnr', this%flnr, 'read', ncid, readvar=readv, posNOTonfile=.true.) @@ -1287,7 +1287,7 @@ subroutine Clean(this) deallocate( this%slatop) deallocate( this%dsladlai) deallocate( this%leafcn) - deallocate( this%harvfrac) + deallocate( this%biofuel_harvfrac) deallocate( this%flnr) deallocate( this%woody) deallocate( this%lflitcn) From 0bdea5127ce46baa6a32f5a12095209d0708e25f Mon Sep 17 00:00:00 2001 From: chen693 Date: Sun, 29 Mar 2020 16:31:10 -0700 Subject: [PATCH 34/75] add leafc_to_biofuelc and livestemc_to_biofuelc fluxes --- src/biogeochem/CNVegCarbonFluxType.F90 | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/biogeochem/CNVegCarbonFluxType.F90 b/src/biogeochem/CNVegCarbonFluxType.F90 index 33f7fdb412..7b57eadb70 100644 --- a/src/biogeochem/CNVegCarbonFluxType.F90 +++ b/src/biogeochem/CNVegCarbonFluxType.F90 @@ -248,8 +248,6 @@ module CNVegCarbonFluxType real(r8), pointer :: harvest_c_to_cwdc_col (:,:) ! C fluxes associated with harvest to CWD pool (gC/m3/s) real(r8), pointer :: grainc_to_cropprodc_patch (:) ! grain C to crop product pool (gC/m2/s) real(r8), pointer :: grainc_to_cropprodc_col (:) ! grain C to crop product pool (gC/m2/s) - real(r8), pointer :: biofuelc_to_cropprodc_patch (:) ! biofuel C to crop product pool (gC/m2/s) - real(r8), pointer :: biofuelc_to_cropprodc_col (:) ! biofuel C to crop product pool (gC/m2/s) ! fire fluxes real(r8), pointer :: m_decomp_cpools_to_fire_vr_col (:,:,:) ! vertically-resolved decomposing C fire loss (gC/m3/s) @@ -666,12 +664,6 @@ subroutine InitAllocate(this, bounds, carbon_type) allocate(this%grainc_to_cropprodc_col(begc:endc)) this%grainc_to_cropprodc_col(:) = nan - - allocate(this%biofuelc_to_cropprodc_patch(begp:endp)) - this%biofuelc_to_cropprodc_patch(:) = nan - - allocate(this%biofuelc_to_cropprodc_col(begc:endc)) - this%biofuelc_to_cropprodc_col(:) = nan allocate(this%m_decomp_cpools_to_fire_vr_col(begc:endc,1:nlevdecomp_full,1:ndecomp_pools)) this%m_decomp_cpools_to_fire_vr_col(:,:,:)= nan @@ -3863,7 +3855,6 @@ subroutine SetValues ( this, & this%crop_seedc_to_leaf_patch(i) = value_patch this%grainc_to_cropprodc_patch(i) = value_patch - this%biofuelc_to_cropprodc_patch(i) = value_patch end do if ( use_crop )then @@ -3933,7 +3924,6 @@ subroutine SetValues ( this, & i = filter_column(fi) this%grainc_to_cropprodc_col(i) = value_column - this%biofuelc_to_cropprodc_col(i) = value_column this%cwdc_hr_col(i) = value_column this%cwdc_loss_col(i) = value_column this%litterc_loss_col(i) = value_column From 69b0f941eee66e637346b03442bb10a28c0e3a6d Mon Sep 17 00:00:00 2001 From: chen693 Date: Sun, 29 Mar 2020 16:31:48 -0700 Subject: [PATCH 35/75] add leafn_to_biofueln and livestemn_to_biofueln fluxes --- src/biogeochem/CNVegNitrogenFluxType.F90 | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/biogeochem/CNVegNitrogenFluxType.F90 b/src/biogeochem/CNVegNitrogenFluxType.F90 index a287d5dc0f..1da724382b 100644 --- a/src/biogeochem/CNVegNitrogenFluxType.F90 +++ b/src/biogeochem/CNVegNitrogenFluxType.F90 @@ -63,8 +63,6 @@ module CNVegNitrogenFluxType real(r8), pointer :: hrv_retransn_to_litter_patch (:) ! patch retranslocated N pool harvest mortality (gN/m2/s) real(r8), pointer :: grainn_to_cropprodn_patch (:) ! patch grain N to crop product pool (gN/m2/s) real(r8), pointer :: grainn_to_cropprodn_col (:) ! col grain N to crop product pool (gN/m2/s) - real(r8), pointer :: biofueln_to_cropprodn_patch (:) ! patch biofuel N to crop product pool (gN/m2/s) - real(r8), pointer :: biofueln_to_cropprodn_col (:) ! col biofuel N to crop product pool (gN/m2/s) real(r8), pointer :: m_n_to_litr_met_fire_col (:,:) ! col N from leaf, froot, xfer and storage N to litter labile N by fire (gN/m3/s) real(r8), pointer :: m_n_to_litr_cel_fire_col (:,:) ! col N from leaf, froot, xfer and storage N to litter cellulose N by fire (gN/m3/s) real(r8), pointer :: m_n_to_litr_lig_fire_col (:,:) ! col N from leaf, froot, xfer and storage N to litter lignin N by fire (gN/m3/s) @@ -428,8 +426,6 @@ subroutine InitAllocate(this, bounds) allocate(this%grainn_to_cropprodn_patch (begp:endp)) ; this%grainn_to_cropprodn_patch (:) = nan allocate(this%grainn_to_cropprodn_col (begc:endc)) ; this%grainn_to_cropprodn_col (:) = nan - allocate(this%biofueln_to_cropprodn_patch (begp:endp)) ; this%biofueln_to_cropprodn_patch (:) = nan - allocate(this%biofueln_to_cropprodn_col (begc:endc)) ; this%biofueln_to_cropprodn_col (:) = nan allocate(this%fire_nloss_col (begc:endc)) ; this%fire_nloss_col (:) = nan allocate(this%fire_nloss_p2c_col (begc:endc)) ; this%fire_nloss_p2c_col (:) = nan @@ -1680,7 +1676,6 @@ subroutine SetValues ( this, & this%crop_seedn_to_leaf_patch(i) = value_patch this%grainn_to_cropprodn_patch(i) = value_patch - this%biofueln_to_cropprodn_patch(i) = value_patch end do if ( use_crop )then @@ -1733,7 +1728,6 @@ subroutine SetValues ( this, & i = filter_column(fi) this%grainn_to_cropprodn_col(i) = value_column - this%biofueln_to_cropprodn_col(i) = value_column this%fire_nloss_col(i) = value_column ! Zero p2c column fluxes From 0e7aac4bffec5d915a8bdacadbbb7e6cc09d7a30 Mon Sep 17 00:00:00 2001 From: chen693 Date: Sun, 29 Mar 2020 16:33:56 -0700 Subject: [PATCH 36/75] cut a certain fraction of crop aboveground biomass during offset period for biofuel and move the harvested amounts into grain_to_cropprod pool --- src/biogeochem/CNPhenologyMod.F90 | 60 +++++++++++++------------------ 1 file changed, 24 insertions(+), 36 deletions(-) diff --git a/src/biogeochem/CNPhenologyMod.F90 b/src/biogeochem/CNPhenologyMod.F90 index 272747e61e..6e501ccd9f 100644 --- a/src/biogeochem/CNPhenologyMod.F90 +++ b/src/biogeochem/CNPhenologyMod.F90 @@ -1972,11 +1972,7 @@ subroutine CropPhenology(num_pcropp, filter_pcropp , & ! the onset_counter would change from dt and you'd need to make ! changes to the offset subroutine below - else if ((idpp >= mxmat(ivt(p)) .and. (ivt(p) == nmiscanthus .or. ivt(p) == nirrig_miscanthus .or. & - ivt(p) == nswitchgrass .or. ivt(p) == nirrig_switchgrass)) .or. & - ((hui(p) >= gddmaturity(p) .or. idpp >= mxmat(ivt(p))) .and. & - (ivt(p) /= nmiscanthus .and. ivt(p) /= nirrig_miscanthus .and. & - ivt(p) /= nswitchgrass .and. ivt(p) /= nirrig_switchgrass))) then + else if (hui(p) >= gddmaturity(p) .or. idpp >= mxmat(ivt(p))) then if (harvdate(p) >= NOT_Harvested) harvdate(p) = jday croplive(p) = .false. ! no re-entry in greater if-block cphase(p) = 4._r8 @@ -2415,7 +2411,7 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, & leafcn => pftcon%leafcn , & ! Input: leaf C:N (gC/gN) - harvfrac => pftcon%harvfrac , & ! Input: cut fraction for harvest (-) + biofuel_harvfrac => pftcon%biofuel_harvfrac , & ! Input: cut fraction for biofuel (-) lflitcn => pftcon%lflitcn , & ! Input: leaf litter C:N (gC/gN) frootcn => pftcon%frootcn , & ! Input: fine root C:N (gC/gN) @@ -2477,8 +2473,8 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, & t1 = 1.0_r8 / dt frootc_to_litter(p) = t1 * frootc(p) + cpool_to_frootc(p) - ! harvfrac is only non-zero for prognostic crops. - leafc_to_litter(p) = t1 * leafc(p)*(1._r8-harvfrac(ivt(p))) + cpool_to_leafc(p) + ! biofuel_harvfrac is only non-zero for prognostic crops. + leafc_to_litter(p) = t1 * leafc(p)*(1._r8-biofuel_harvfrac(ivt(p))) + cpool_to_leafc(p) ! this assumes that offset_counter == dt for crops ! if this were ever changed, we'd need to add code to the "else" @@ -2493,16 +2489,16 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, & grainc_to_food(p) = t1 * grainc(p) + cpool_to_grainc(p) - grainc_to_seed(p) grainn_to_food(p) = t1 * grainn(p) + npool_to_grainn(p) - grainn_to_seed(p) - ! Cut a certain fraction (i.e., harvfrac(ivt(p))) (e.g., harvfrac(ivt(p)=70% for bioenergy crops) of leaf C + ! Cut a certain fraction (i.e., biofuel_harvfrac(ivt(p))) (e.g., biofuel_harvfrac(ivt(p)=70% for bioenergy crops) of leaf C ! and move this fration of leaf C to biofuel C, rather than move it to litter - leafc_to_biofuelc(p) = t1 * leafc(p) * harvfrac(ivt(p)) - leafn_to_biofueln(p) = t1 * leafn(p) * harvfrac(ivt(p)) + leafc_to_biofuelc(p) = t1 * leafc(p) * biofuel_harvfrac(ivt(p)) + leafn_to_biofueln(p) = t1 * leafn(p) * biofuel_harvfrac(ivt(p)) - ! Cut a certain fraction (i.e., harvfrac(ivt(p))) (e.g., harvfrac(ivt(p)=70% for bioenergy crops) of livestem C + ! Cut a certain fraction (i.e., biofuel_harvfrac(ivt(p))) (e.g., biofuel_harvfrac(ivt(p)=70% for bioenergy crops) of livestem C ! and move this fration of leaf C to biofuel C, rather than move it to litter - livestemc_to_litter(p) = t1 * livestemc(p)*(1._r8-harvfrac(ivt(p))) + cpool_to_livestemc(p) - livestemc_to_biofuelc(p) = t1 * livestemc(p) * harvfrac(ivt(p)) - livestemn_to_biofueln(p) = t1 * livestemn(p) * harvfrac(ivt(p)) + livestemc_to_litter(p) = t1 * livestemc(p)*(1._r8-biofuel_harvfrac(ivt(p))) + cpool_to_livestemc(p) + livestemc_to_biofuelc(p) = t1 * livestemc(p) * biofuel_harvfrac(ivt(p)) + livestemn_to_biofueln(p) = t1 * livestemn(p) * biofuel_harvfrac(ivt(p)) end if else t1 = dt * 2.0_r8 / (offset_counter(p) * offset_counter(p)) @@ -2584,7 +2580,7 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, & ! NOTE(slevis, 2014-12) results in -ve livestemn and -ve totpftn !X! livestemn_to_litter(p) = livestemc_to_litter(p) / livewdcn(ivt(p)) ! NOTE(slevis, 2014-12) Beth Drewniak suggested this instead - livestemn_to_litter(p) = livestemn(p) / dt * (1 - harvfrac(ivt(p))) + livestemn_to_litter(p) = livestemn(p) / dt * (1 - biofuel_harvfrac(ivt(p))) end if ! save the current litterfall fluxes @@ -2869,37 +2865,29 @@ subroutine CNCropHarvestToProductPools(bounds, num_soilp, filter_soilp, num_soil if (use_crop) then do fp = 1, num_soilp p = filter_soilp(fp) - cnveg_carbonflux_inst%biofuelc_to_cropprodc_patch(p) = & + cnveg_carbonflux_inst%grainc_to_cropprodc_patch(p) = & cnveg_carbonflux_inst%leafc_to_biofuelc_patch(p)+cnveg_carbonflux_inst%livestemc_to_biofuelc_patch(p) - cnveg_nitrogenflux_inst%biofueln_to_cropprodn_patch(p) = & + cnveg_nitrogenflux_inst%grainn_to_cropprodn_patch(p) = & cnveg_nitrogenflux_inst%leafn_to_biofueln_patch(p)+cnveg_nitrogenflux_inst%livestemn_to_biofueln_patch(p) end do - call p2c (bounds, num_soilc, filter_soilc, & - cnveg_carbonflux_inst%biofuelc_to_cropprodc_patch(bounds%begp:bounds%endp), & - cnveg_carbonflux_inst%biofuelc_to_cropprodc_col(bounds%begc:bounds%endc)) - - call p2c (bounds, num_soilc, filter_soilc, & - cnveg_nitrogenflux_inst%biofueln_to_cropprodn_patch(bounds%begp:bounds%endp), & - cnveg_nitrogenflux_inst%biofueln_to_cropprodn_col(bounds%begc:bounds%endc)) - if (use_grainproduct) then do fp = 1, num_soilp p = filter_soilp(fp) - cnveg_carbonflux_inst%grainc_to_cropprodc_patch(p) = & + cnveg_carbonflux_inst%grainc_to_cropprodc_patch(p) = cnveg_carbonflux_inst%grainc_to_cropprodc_patch(p) + & cnveg_carbonflux_inst%grainc_to_food_patch(p) - cnveg_nitrogenflux_inst%grainn_to_cropprodn_patch(p) = & + cnveg_nitrogenflux_inst%grainn_to_cropprodn_patch(p) = cnveg_nitrogenflux_inst%grainn_to_cropprodn_patch(p) + & cnveg_nitrogenflux_inst%grainn_to_food_patch(p) end do - - call p2c (bounds, num_soilc, filter_soilc, & - cnveg_carbonflux_inst%grainc_to_cropprodc_patch(bounds%begp:bounds%endp), & - cnveg_carbonflux_inst%grainc_to_cropprodc_col(bounds%begc:bounds%endc)) - - call p2c (bounds, num_soilc, filter_soilc, & - cnveg_nitrogenflux_inst%grainn_to_cropprodn_patch(bounds%begp:bounds%endp), & - cnveg_nitrogenflux_inst%grainn_to_cropprodn_col(bounds%begc:bounds%endc)) end if + + call p2c (bounds, num_soilc, filter_soilc, & + cnveg_carbonflux_inst%grainc_to_cropprodc_patch(bounds%begp:bounds%endp), & + cnveg_carbonflux_inst%grainc_to_cropprodc_col(bounds%begc:bounds%endc)) + + call p2c (bounds, num_soilc, filter_soilc, & + cnveg_nitrogenflux_inst%grainn_to_cropprodn_patch(bounds%begp:bounds%endp), & + cnveg_nitrogenflux_inst%grainn_to_cropprodn_col(bounds%begc:bounds%endc)) ! No else clause: if use_grainproduct is false, then the grain*_to_cropprod fluxes ! will remain at their initial value (0). From e8aa3d6c5e4b5d3a4684bd19958914c07f216c5f Mon Sep 17 00:00:00 2001 From: chen693 Date: Sun, 29 Mar 2020 16:38:14 -0700 Subject: [PATCH 37/75] move the harvested amounts into grain_to_cropprod pool at the radiation time step --- src/biogeochem/CNCIsoFluxMod.F90 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/biogeochem/CNCIsoFluxMod.F90 b/src/biogeochem/CNCIsoFluxMod.F90 index eeb6ebe435..922378b01f 100644 --- a/src/biogeochem/CNCIsoFluxMod.F90 +++ b/src/biogeochem/CNCIsoFluxMod.F90 @@ -471,14 +471,15 @@ subroutine CIsoFlux1(num_soilc, filter_soilc, num_soilp, filter_soilp, & do fp = 1,num_soilp p = filter_soilp(fp) - iso_cnveg_cf%biofuelc_to_cropprodc_patch(p) = iso_cnveg_cf%leafc_to_biofuelc_patch(p) + & + iso_cnveg_cf%grainc_to_cropprodc_patch(p) = iso_cnveg_cf%leafc_to_biofuelc_patch(p) + & iso_cnveg_cf%livestemc_to_biofuelc_patch(p) end do if (use_grainproduct) then do fp = 1,num_soilp p = filter_soilp(fp) - iso_cnveg_cf%grainc_to_cropprodc_patch(p) = iso_cnveg_cf%grainc_to_food_patch(p) + iso_cnveg_cf%grainc_to_cropprodc_patch(p) = iso_cnveg_cf%grainc_to_cropprodc_patch(p) + & + iso_cnveg_cf%grainc_to_food_patch(p) iso_cnveg_cf%grain_mr_patch(p) = iso_cnveg_cf%grain_xsmr_patch(p) + iso_cnveg_cf%grain_curmr_patch(p) end do endif From 93d88d335b26027884778a039a3c534290ffbbe4 Mon Sep 17 00:00:00 2001 From: chen693 Date: Sun, 29 Mar 2020 16:38:53 -0700 Subject: [PATCH 38/75] remove variables for biofuel product --- src/biogeochem/CNDriverMod.F90 | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/biogeochem/CNDriverMod.F90 b/src/biogeochem/CNDriverMod.F90 index bca596477f..abc18cdbfc 100644 --- a/src/biogeochem/CNDriverMod.F90 +++ b/src/biogeochem/CNDriverMod.F90 @@ -712,8 +712,7 @@ subroutine CNDriverNoLeaching(bounds, dwt_wood_product_gain_patch = cnveg_carbonflux_inst%dwt_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), & - biofuel_to_cropprod_patch = cnveg_carbonflux_inst%biofuelc_to_cropprodc_patch(begp:endp)) + grain_to_cropprod_patch = cnveg_carbonflux_inst%grainc_to_cropprodc_patch(begp:endp)) call t_stopf('CNWoodProducts') if (use_c13) then @@ -722,8 +721,7 @@ subroutine CNDriverNoLeaching(bounds, dwt_wood_product_gain_patch = c13_cnveg_carbonflux_inst%dwt_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), & - biofuel_to_cropprod_patch = c13_cnveg_carbonflux_inst%biofuelc_to_cropprodc_patch(begp:endp)) + grain_to_cropprod_patch = c13_cnveg_carbonflux_inst%grainc_to_cropprodc_patch(begp:endp)) end if if (use_c14) then @@ -732,8 +730,7 @@ subroutine CNDriverNoLeaching(bounds, dwt_wood_product_gain_patch = c14_cnveg_carbonflux_inst%dwt_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), & - biofuel_to_cropprod_patch = c14_cnveg_carbonflux_inst%biofuelc_to_cropprodc_patch(begp:endp)) + grain_to_cropprod_patch = c14_cnveg_carbonflux_inst%grainc_to_cropprodc_patch(begp:endp)) end if call n_products_inst%UpdateProducts(bounds, & @@ -741,8 +738,7 @@ subroutine CNDriverNoLeaching(bounds, dwt_wood_product_gain_patch = cnveg_nitrogenflux_inst%dwt_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), & - biofuel_to_cropprod_patch = cnveg_nitrogenflux_inst%biofueln_to_cropprodn_patch(begp:endp)) + grain_to_cropprod_patch = cnveg_nitrogenflux_inst%grainn_to_cropprodn_patch(begp:endp)) !-------------------------------------------- ! Calculate fire area and fluxes From 0e318324d9ffd0e8627368481fe7f52eb105bc19 Mon Sep 17 00:00:00 2001 From: chen693 Date: Sun, 29 Mar 2020 16:39:30 -0700 Subject: [PATCH 39/75] rm calculation for biofuel product --- src/biogeochem/CNProductsMod.F90 | 67 ++------------------------------ 1 file changed, 4 insertions(+), 63 deletions(-) diff --git a/src/biogeochem/CNProductsMod.F90 b/src/biogeochem/CNProductsMod.F90 index bcdfd95618..0661c3b392 100644 --- a/src/biogeochem/CNProductsMod.F90 +++ b/src/biogeochem/CNProductsMod.F90 @@ -34,7 +34,6 @@ module CNProductsMod ! States real(r8), pointer :: cropprod1_grc(:) ! (g[C or N]/m2) grain product pool, 1-year lifespan - real(r8), pointer :: biofuelprod1_grc(:) ! (g[C or N]/m2) biofuel product pool, 1-year lifespan real(r8), pointer :: prod10_grc(:) ! (g[C or N]/m2) wood product pool, 10-year lifespan real(r8), pointer :: prod100_grc(:) ! (g[C or N]/m2) wood product pool, 100-year lifespan real(r8), pointer :: tot_woodprod_grc(:) ! (g[C or N]/m2) total wood product pool @@ -50,12 +49,9 @@ module CNProductsMod real(r8), pointer :: hrv_deadstem_to_prod100_grc(:) ! (g[C or N]/m2/s) dead stem harvest to 100-year wood product pool real(r8), pointer :: grain_to_cropprod1_patch(:) ! (g[C or N]/m2/s) grain to 1-year crop product pool real(r8), pointer :: grain_to_cropprod1_grc(:) ! (g[C or N]/m2/s) grain to 1-year crop product pool - real(r8), pointer :: biofuel_to_cropprod1_patch(:) ! (g[C or N]/m2/s) biofuel to 1-year crop product pool - real(r8), pointer :: biofuel_to_cropprod1_grc(:) ! (g[C or N]/m2/s) biofuel to 1-year crop product pool ! Fluxes: losses real(r8), pointer :: cropprod1_loss_grc(:) ! (g[C or N]/m2/s) decomposition loss from 1-yr grain product pool - real(r8), pointer :: biofuelprod1_loss_grc(:) ! (g[C or N]/m2/s) decomposition loss from 1-yr biofuel product pool real(r8), pointer :: prod10_loss_grc(:) ! (g[C or N]/m2/s) decomposition loss from 10-yr wood product pool real(r8), pointer :: prod100_loss_grc(:) ! (g[C or N]/m2/s) decomposition loss from 100-yr wood product pool real(r8), pointer :: tot_woodprod_loss_grc(:) ! (g[C or N]/m2/s) decompomposition loss from all wood product pools @@ -127,7 +123,6 @@ subroutine InitAllocate(this, bounds) endg = bounds%endg allocate(this%cropprod1_grc(begg:endg)) ; this%cropprod1_grc(:) = nan - allocate(this%biofuelprod1_grc(begg:endg)) ; this%biofuelprod1_grc(:) = nan allocate(this%prod10_grc(begg:endg)) ; this%prod10_grc(:) = nan allocate(this%prod100_grc(begg:endg)) ; this%prod100_grc(:) = nan allocate(this%tot_woodprod_grc(begg:endg)) ; this%tot_woodprod_grc(:) = nan @@ -146,11 +141,8 @@ subroutine InitAllocate(this, bounds) allocate(this%grain_to_cropprod1_patch(begp:endp)) ; this%grain_to_cropprod1_patch(:) = nan allocate(this%grain_to_cropprod1_grc(begg:endg)) ; this%grain_to_cropprod1_grc(:) = nan - allocate(this%biofuel_to_cropprod1_patch(begp:endp)) ; this%biofuel_to_cropprod1_patch(:) = nan - allocate(this%biofuel_to_cropprod1_grc(begg:endg)) ; this%biofuel_to_cropprod1_grc(:) = nan allocate(this%cropprod1_loss_grc(begg:endg)) ; this%cropprod1_loss_grc(:) = nan - allocate(this%biofuelprod1_loss_grc(begg:endg)) ; this%biofuelprod1_loss_grc(:) = nan allocate(this%prod10_loss_grc(begg:endg)) ; this%prod10_loss_grc(:) = nan allocate(this%prod100_loss_grc(begg:endg)) ; this%prod100_loss_grc(:) = nan allocate(this%tot_woodprod_loss_grc(begg:endg)) ; this%tot_woodprod_loss_grc(:) = nan @@ -192,14 +184,6 @@ subroutine InitHistory(this, bounds) long_name = '1-yr grain product ' // this%species%get_species(), & ptr_gcell = this%cropprod1_grc, default=active_if_non_isotope) - this%biofuelprod1_grc(begg:endg) = spval - call hist_addfld1d( & - fname = this%species%hist_fname('BIOFUELPROD1'), & - units = 'g' // this%species%get_species() // '/m^2', & - avgflag = 'A', & - long_name = '1-yr biofuel product ' // this%species%get_species(), & - ptr_gcell = this%biofuelprod1_grc, default=active_if_non_isotope) - this%prod10_grc(begg:endg) = spval call hist_addfld1d( & fname = this%species%hist_fname('PROD10'), & @@ -264,14 +248,6 @@ subroutine InitHistory(this, bounds) long_name = 'loss from 1-yr grain product pool', & ptr_gcell = this%cropprod1_loss_grc, default=active_if_non_isotope) - this%biofuelprod1_loss_grc(begg:endg) = spval - call hist_addfld1d( & - fname = this%species%hist_fname('BIOFUELPROD1', suffix='_LOSS'), & - units = 'g' // this%species%get_species() // '/m^2/s', & - avgflag = 'A', & - long_name = 'loss from 1-yr biofuel product pool', & - ptr_gcell = this%biofuelprod1_loss_grc, default=active_if_non_isotope) - this%prod10_loss_grc(begg:endg) = spval call hist_addfld1d( & fname = this%species%hist_fname('PROD10', suffix='_LOSS'), & @@ -312,7 +288,6 @@ subroutine InitCold(this, bounds) do g = bounds%begg, bounds%endg this%cropprod1_grc(g) = 0._r8 - this%biofuelprod1_grc(g) = 0._r8 this%prod10_grc(g) = 0._r8 this%prod100_grc(g) = 0._r8 this%tot_woodprod_grc(g) = 0._r8 @@ -324,7 +299,6 @@ subroutine InitCold(this, bounds) this%hrv_deadstem_to_prod10_patch(p) = 0._r8 this%hrv_deadstem_to_prod100_patch(p) = 0._r8 this%grain_to_cropprod1_patch(p) = 0._r8 - this%biofuel_to_cropprod1_patch(p) = 0._r8 end do end subroutine InitCold @@ -405,17 +379,6 @@ subroutine Restart(this, bounds, ncid, flag, & end if end if - call restartvar(ncid=ncid, flag=flag, & - varname=this%species%rest_fname('biofuelprod1', suffix='_g'), & - xtype=ncd_double, dim1name='gridcell', & - long_name='', units='', & - interpinic_flag='interp', readvar=readvar, data=this%biofuelprod1_grc) - if (.not. readvar .and. template_provided) then - call set_missing_from_template(this%biofuelprod1_grc, & - template_for_missing_fields%biofuelprod1_grc, & - multiplier = template_multiplier) - end if - call restartvar(ncid=ncid, flag=flag, & varname=this%species%rest_fname('prod10', suffix='_g'), & xtype=ncd_double, dim1name='gridcell', & @@ -474,8 +437,7 @@ subroutine UpdateProducts(this, bounds, & dwt_wood_product_gain_patch, & wood_harvest_patch, & dwt_crop_product_gain_patch, & - grain_to_cropprod_patch, & - biofuel_to_cropprod_patch) + grain_to_cropprod_patch) ! ! !DESCRIPTION: ! Update all loss fluxes from wood and grain product pools, and update product pool @@ -500,9 +462,6 @@ subroutine UpdateProducts(this, bounds, & ! grain to crop product pool (g/m2/s) [patch] real(r8), intent(in) :: grain_to_cropprod_patch( bounds%begp: ) - - ! biofuel to crop product pool (g/m2/s) [patch] - real(r8), intent(in) :: biofuel_to_cropprod_patch( bounds%begp: ) ! ! !LOCAL VARIABLES: integer :: g ! indices @@ -516,7 +475,6 @@ subroutine UpdateProducts(this, bounds, & SHR_ASSERT_ALL_FL((ubound(wood_harvest_patch) == (/bounds%endp/)), sourcefile, __LINE__) SHR_ASSERT_ALL_FL((ubound(dwt_crop_product_gain_patch) == (/bounds%endp/)), sourcefile, __LINE__) SHR_ASSERT_ALL_FL((ubound(grain_to_cropprod_patch) == (/bounds%endp/)), sourcefile, __LINE__) - SHR_ASSERT_ALL_FL((ubound(biofuel_to_cropprod_patch) == (/bounds%endp/)), sourcefile, __LINE__) call this%PartitionWoodFluxes(bounds, & num_soilp, filter_soilp, & @@ -526,8 +484,7 @@ subroutine UpdateProducts(this, bounds, & call this%PartitionGrainFluxes(bounds, & num_soilp, filter_soilp, & dwt_crop_product_gain_patch(bounds%begp:bounds%endp), & - grain_to_cropprod_patch(bounds%begp:bounds%endp), & - biofuel_to_cropprod_patch(bounds%begp:bounds%endp)) + grain_to_cropprod_patch(bounds%begp:bounds%endp)) ! calculate losses from product pools ! the following (1/s) rate constants result in ~90% loss of initial state over 1, 10 and 100 years, @@ -539,7 +496,6 @@ subroutine UpdateProducts(this, bounds, & do g = bounds%begg, bounds%endg ! calculate fluxes out of product pools (1/sec) this%cropprod1_loss_grc(g) = this%cropprod1_grc(g) * kprod1 - this%biofuelprod1_loss_grc(g) = this%biofuelprod1_grc(g) * kprod1 this%prod10_loss_grc(g) = this%prod10_grc(g) * kprod10 this%prod100_loss_grc(g) = this%prod100_grc(g) * kprod100 end do @@ -557,13 +513,11 @@ subroutine UpdateProducts(this, bounds, & ! fluxes into wood & grain product pools, from harvest this%cropprod1_grc(g) = this%cropprod1_grc(g) + this%grain_to_cropprod1_grc(g)*dt - this%biofuelprod1_grc(g) = this%biofuelprod1_grc(g) + this%biofuel_to_cropprod1_grc(g)*dt this%prod10_grc(g) = this%prod10_grc(g) + this%hrv_deadstem_to_prod10_grc(g)*dt this%prod100_grc(g) = this%prod100_grc(g) + this%hrv_deadstem_to_prod100_grc(g)*dt ! fluxes out of wood & grain product pools, from decomposition this%cropprod1_grc(g) = this%cropprod1_grc(g) - this%cropprod1_loss_grc(g)*dt - this%biofuelprod1_grc(g) = this%biofuelprod1_grc(g) - this%biofuelprod1_loss_grc(g)*dt this%prod10_grc(g) = this%prod10_grc(g) - this%prod10_loss_grc(g)*dt this%prod100_grc(g) = this%prod100_grc(g) - this%prod100_loss_grc(g)*dt @@ -678,8 +632,7 @@ end subroutine PartitionWoodFluxes subroutine PartitionGrainFluxes(this, bounds, & num_soilp, filter_soilp, & dwt_crop_product_gain_patch, & - grain_to_cropprod_patch, & - biofuel_to_cropprod_patch) + grain_to_cropprod_patch) ! ! !DESCRIPTION: ! Partition input grain fluxes into crop product pools @@ -704,9 +657,6 @@ subroutine PartitionGrainFluxes(this, bounds, & ! grain to crop product pool(s) (g/m2/s) [patch] real(r8) , intent(in) :: grain_to_cropprod_patch( bounds%begp: ) - - ! biofuel to crop product pool(s) (g/m2/s) [patch] - real(r8) , intent(in) :: biofuel_to_cropprod_patch( bounds%begp: ) ! ! !LOCAL VARIABLES: integer :: fp @@ -723,7 +673,6 @@ subroutine PartitionGrainFluxes(this, bounds, & ! For now all crop product is put in the 1-year crop product pool this%grain_to_cropprod1_patch(p) = grain_to_cropprod_patch(p) - this%biofuel_to_cropprod1_patch(p) = biofuel_to_cropprod_patch(p) end do call p2g(bounds, & @@ -733,13 +682,6 @@ subroutine PartitionGrainFluxes(this, bounds, & c2l_scale_type = 'unity', & l2g_scale_type = 'unity') - - call p2g(bounds, & - this%biofuel_to_cropprod1_patch(bounds%begp:bounds%endp), & - this%biofuel_to_cropprod1_grc(bounds%begg:bounds%endg), & - p2c_scale_type = 'unity', & - c2l_scale_type = 'unity', & - l2g_scale_type = 'unity') ! Determine gains from dynamic landcover do g = bounds%begg, bounds%endg @@ -793,8 +735,7 @@ subroutine ComputeSummaryVars(this, bounds) this%product_loss_grc(g) = & this%cropprod1_loss_grc(g) + & this%prod10_loss_grc(g) + & - this%prod100_loss_grc(g) + & - this%biofuelprod1_loss_grc(g) + this%prod100_loss_grc(g) this%dwt_woodprod_gain_grc(g) = & this%dwt_prod100_gain_grc(g) + & From 4bc6598e1aa7e30b17bf525767f351b7042ad464 Mon Sep 17 00:00:00 2001 From: chen693 Date: Sun, 29 Mar 2020 16:41:14 -0700 Subject: [PATCH 40/75] rm CN balance check for biofuel_to_cropprod --- src/biogeochem/CNBalanceCheckMod.F90 | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/biogeochem/CNBalanceCheckMod.F90 b/src/biogeochem/CNBalanceCheckMod.F90 index e780e4a804..b9a5355d46 100644 --- a/src/biogeochem/CNBalanceCheckMod.F90 +++ b/src/biogeochem/CNBalanceCheckMod.F90 @@ -142,7 +142,6 @@ subroutine CBalanceCheck(this, bounds, num_soilc, filter_soilc, & 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) grainc_to_cropprodc => cnveg_carbonflux_inst%grainc_to_cropprodc_col , & ! Input: [real(r8) (:) ] (gC/m2/s) grain C to 1-year crop product pool - biofuelc_to_cropprodc => cnveg_carbonflux_inst%biofuelc_to_cropprodc_col , & ! Input: [real(r8) (:) ] (gC/m2/s) biofuel 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 col_fire_closs => cnveg_carbonflux_inst%fire_closs_col , & ! Input: [real(r8) (:) ] (gC/m2/s) total column-level fire C loss @@ -177,8 +176,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) + & - grainc_to_cropprodc(c) + & - biofuelc_to_cropprodc(c) + grainc_to_cropprodc(c) ! subtract leaching flux col_coutputs = col_coutputs - som_c_leached(c) @@ -215,7 +213,6 @@ subroutine CBalanceCheck(this, bounds, num_soilc, filter_soilc, & write(iulog,*)'col_hrv_xsmrpool_to_atm = ',col_hrv_xsmrpool_to_atm(c)*dt write(iulog,*)'wood_harvestc = ',wood_harvestc(c)*dt write(iulog,*)'grainc_to_cropprodc = ',grainc_to_cropprodc(c)*dt - write(iulog,*)'biofuelc_to_cropprodc = ',biofuelc_to_cropprodc(c)*dt write(iulog,*)'-1*som_c_leached = ',som_c_leached(c)*dt call endrun(msg=errMsg(sourcefile, __LINE__)) end if @@ -272,7 +269,7 @@ 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) grainn_to_cropprodn => cnveg_nitrogenflux_inst%grainn_to_cropprodn_col , & ! Input: [real(r8) (:) ] (gN/m2/s) grain N to 1-year crop product pool - biofueln_to_cropprodn => cnveg_nitrogenflux_inst%biofueln_to_cropprodn_col , & ! Input: [real(r8) (:) ] (gN/m2/s) biofuel N to 1-year crop product pool + totcoln => cnveg_nitrogenstate_inst%totn_col & ! Input: [real(r8) (:) ] (gN/m2) total column nitrogen, incl veg ) @@ -307,8 +304,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) + & - grainn_to_cropprodn(c) + & - biofueln_to_cropprodn(c) + grainn_to_cropprodn(c) if (.not. use_nitrif_denitrif) then col_noutputs(c) = col_noutputs(c) + sminn_leached(c) From baa70661b269103fd1b292200e8e5f3bae2997f9 Mon Sep 17 00:00:00 2001 From: chen693 Date: Sun, 29 Mar 2020 17:46:33 -0700 Subject: [PATCH 41/75] add more document for biofuel_harvfrac --- src/biogeochem/CNPhenologyMod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/biogeochem/CNPhenologyMod.F90 b/src/biogeochem/CNPhenologyMod.F90 index 6e501ccd9f..e841975986 100644 --- a/src/biogeochem/CNPhenologyMod.F90 +++ b/src/biogeochem/CNPhenologyMod.F90 @@ -2411,7 +2411,7 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, & leafcn => pftcon%leafcn , & ! Input: leaf C:N (gC/gN) - biofuel_harvfrac => pftcon%biofuel_harvfrac , & ! Input: cut fraction for biofuel (-) + biofuel_harvfrac => pftcon%biofuel_harvfrac , & ! Input: cut a fraction of leaf & stem for biofuel (-) lflitcn => pftcon%lflitcn , & ! Input: leaf litter C:N (gC/gN) frootcn => pftcon%frootcn , & ! Input: fine root C:N (gC/gN) From 5bf020b4e07b3093626913094899af8785a73ae1 Mon Sep 17 00:00:00 2001 From: chen693 Date: Sun, 29 Mar 2020 17:50:53 -0700 Subject: [PATCH 42/75] fix identical --- src/biogeochem/CNPhenologyMod.F90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/biogeochem/CNPhenologyMod.F90 b/src/biogeochem/CNPhenologyMod.F90 index e841975986..7ec60d0f42 100644 --- a/src/biogeochem/CNPhenologyMod.F90 +++ b/src/biogeochem/CNPhenologyMod.F90 @@ -2865,10 +2865,10 @@ subroutine CNCropHarvestToProductPools(bounds, num_soilp, filter_soilp, num_soil if (use_crop) then do fp = 1, num_soilp p = filter_soilp(fp) - cnveg_carbonflux_inst%grainc_to_cropprodc_patch(p) = & - cnveg_carbonflux_inst%leafc_to_biofuelc_patch(p)+cnveg_carbonflux_inst%livestemc_to_biofuelc_patch(p) - cnveg_nitrogenflux_inst%grainn_to_cropprodn_patch(p) = & - cnveg_nitrogenflux_inst%leafn_to_biofueln_patch(p)+cnveg_nitrogenflux_inst%livestemn_to_biofueln_patch(p) + cnveg_carbonflux_inst%grainc_to_cropprodc_patch(p) = cnveg_carbonflux_inst%leafc_to_biofuelc_patch(p) + & + cnveg_carbonflux_inst%livestemc_to_biofuelc_patch(p) + cnveg_nitrogenflux_inst%grainn_to_cropprodn_patch(p) = cnveg_nitrogenflux_inst%leafn_to_biofueln_patch(p) + & + cnveg_nitrogenflux_inst%livestemn_to_biofueln_patch(p) end do if (use_grainproduct) then From 9307d604baa020fdd115288632ddc3102996814e Mon Sep 17 00:00:00 2001 From: chen693 Date: Wed, 1 Apr 2020 14:49:42 -0700 Subject: [PATCH 43/75] remove unrelevant comment --- src/biogeochem/CNPhenologyMod.F90 | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/biogeochem/CNPhenologyMod.F90 b/src/biogeochem/CNPhenologyMod.F90 index 7ec60d0f42..5d2e96e058 100644 --- a/src/biogeochem/CNPhenologyMod.F90 +++ b/src/biogeochem/CNPhenologyMod.F90 @@ -2888,8 +2888,6 @@ subroutine CNCropHarvestToProductPools(bounds, num_soilp, filter_soilp, num_soil call p2c (bounds, num_soilc, filter_soilc, & cnveg_nitrogenflux_inst%grainn_to_cropprodn_patch(bounds%begp:bounds%endp), & cnveg_nitrogenflux_inst%grainn_to_cropprodn_col(bounds%begc:bounds%endc)) - ! No else clause: if use_grainproduct is false, then the grain*_to_cropprod fluxes - ! will remain at their initial value (0). end if From 03bf03da402e9ef47aa3ee0157c8850d2e4ec3b3 Mon Sep 17 00:00:00 2001 From: yanyanchengHydro Date: Wed, 15 Apr 2020 20:01:30 -0700 Subject: [PATCH 44/75] add documents for changes relevant to bioenergy crops --- .../CLM50_Tech_Note_CN_Allocation.rst | 10 +- .../CN_Pools/CLM50_Tech_Note_CN_Pools.rst | 5 +- .../CLM50_Tech_Note_Crop_Irrigation.rst | 233 +++++++++++++----- .../Fluxes/CLM50_Tech_Note_Fluxes.rst | 10 +- .../CLM50_Tech_Note_Introduction.rst | 16 +- .../CLM50_Tech_Note_Photosynthesis.rst | 6 +- ...LM50_Tech_Note_Photosynthetic_Capacity.rst | 4 + .../CLM50_Tech_Note_Plant_Hydraulics.rst | 8 + .../References/CLM50_Tech_Note_References.rst | 8 + .../CLM50_Tech_Note_Surface_Albedos.rst | 4 + ...ech_Note_Vegetation_Phenology_Turnover.rst | 24 +- 11 files changed, 249 insertions(+), 79 deletions(-) diff --git a/doc/source/tech_note/CN_Allocation/CLM50_Tech_Note_CN_Allocation.rst b/doc/source/tech_note/CN_Allocation/CLM50_Tech_Note_CN_Allocation.rst index 25b2215e81..e85a59439f 100644 --- a/doc/source/tech_note/CN_Allocation/CLM50_Tech_Note_CN_Allocation.rst +++ b/doc/source/tech_note/CN_Allocation/CLM50_Tech_Note_CN_Allocation.rst @@ -186,7 +186,15 @@ favorable growth environments (Allen et al., 2005; Vanninen and Makela, +----------------------------------+-----------------------+-----------------------+-----------------------+-----------------------+---------------------------+-------------------------+-------------------------+-------------------------+ | Soybean I | 2 | 0 | 0 | 1 | 25 | 42 | 50 | 500 | +----------------------------------+-----------------------+-----------------------+-----------------------+-----------------------+---------------------------+-------------------------+-------------------------+-------------------------+ - + | Miscanthus R | 2 | 0 | 0 | 1 | 25 | 42 | 50 | 500 | + +----------------------------------+-----------------------+-----------------------+-----------------------+-----------------------+---------------------------+-------------------------+-------------------------+-------------------------+ + | Miscanthus I | 2 | 0 | 0 | 1 | 25 | 42 | 50 | 500 | + +----------------------------------+-----------------------+-----------------------+-----------------------+-----------------------+---------------------------+-------------------------+-------------------------+-------------------------+ + | Switchgrass R | 2 | 0 | 0 | 1 | 25 | 42 | 50 | 500 | + +----------------------------------+-----------------------+-----------------------+-----------------------+-----------------------+---------------------------+-------------------------+-------------------------+-------------------------+ + | Switchgrass I | 2 | 0 | 0 | 1 | 25 | 42 | 50 | 500 | + +----------------------------------+-----------------------+-----------------------+-----------------------+-----------------------+---------------------------+-------------------------+-------------------------+-------------------------+ + Carbon to nitrogen ratios are defined for different tissue types as follows: diff --git a/doc/source/tech_note/CN_Pools/CLM50_Tech_Note_CN_Pools.rst b/doc/source/tech_note/CN_Pools/CLM50_Tech_Note_CN_Pools.rst index 9bddee21ca..77bd7af415 100644 --- a/doc/source/tech_note/CN_Pools/CLM50_Tech_Note_CN_Pools.rst +++ b/doc/source/tech_note/CN_Pools/CLM50_Tech_Note_CN_Pools.rst @@ -116,5 +116,8 @@ stoichiometry are described in Chapter :numref:`rst_CN Allocation`. +----------------------------------+-------------------+ | Tropical Soybean | 20.00 | +----------------------------------+-------------------+ - + | Miscanthus | 25.00 | + +----------------------------------+-------------------+ + | Switchgrass | 25.00 | + +----------------------------------+-------------------+ diff --git a/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst b/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst index 3b8f07f44c..a82f871e6d 100644 --- a/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst +++ b/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst @@ -42,7 +42,7 @@ These updates appear in detail in the sections below. Many also appear in .. _The crop model: -The crop model +The crop model: stable and bioenergy crops ------------------- Introduction @@ -102,18 +102,26 @@ Intercomparison Project (LUMIP), which is part of CMIP6 Land use timeseries (:ref:`Lawrence et al. 2016 `). For more details about how crop distributions are determined, see Chapter :numref:`rst_Transient Landcover Change`. -CLM5 includes eight actively managed crop types +CLM5 includes ten actively managed crop types (temperate soybean, tropical soybean, temperate corn, tropical -corn, spring wheat, cotton, rice, and sugarcane) that are chosen +corn, spring wheat, cotton, rice, sugarcane, miscanthus, and switchgrass) that are chosen based on the availability of corresponding algorithms in AgroIBIS and as developed by :ref:`Badger and Dirmeyer (2015)` and -described by :ref:`Levis et al. (2016)`. The representations of -sugarcane, rice, cotton, tropical corn, and tropical soy are new in CLM5. +described by :ref:`Levis et al. (2016)` and :ref:`Cheng et al. (2019)`. +The representations of sugarcane, rice, cotton, tropical corn, tropical soy, miscanthus, and switchgrass are new in CLM5. Sugarcane and tropical corn are both C4 plants and are therefore represented using the temperate corn functional form. Tropical soybean uses the temperate soybean functional form, while rice and cotton use the wheat functional form. In tropical regions, parameter values were developed for the Amazon Basin, and planting date window is shifted by six months relative to the Northern Hemisphere. +Plantation areas of bioenergy crops are projected to expand throughout the 21st century as a major energy source to +replace fossil fuels and mitigate climate changes. Miscanthus and switchgrass are perennial bioenergy crops and +have quite different physiological traits and land management practices than annual crops, +such as longer growing seasons, higher productivity, and less demands for nutrients and water. +About 70% of their aboveground biomass (leaf & livestem) is removed at harvest for biofuels. Parameter values were developed by using +observation data collected at the University of Illinois Energy Farm +located in Central Midwestern United States (:ref:`Cheng et al., 2019`). + In addition, CLM’s default list of plant functional types (pfts) includes an irrigated and unirrigated unmanaged C3 crop (:numref:`Table Crop plant functional types`) treated as a second C3 grass. @@ -197,10 +205,10 @@ managed crop types that are using the same parameter set. 68 irrigated sugarcane active irrigated sugarcane 69 rainfed sunflower inactive rainfed spring wheat 70 irrigated sunflower inactive irrigated spring wheat - 71 rainfed miscanthus inactive rainfed tropical corn - 72 irrigated miscanthus inactive irrigated tropical corn - 73 rainfed switchgrass inactive rainfed tropical corn - 74 irrigated switchgrass inactive irrigated tropical corn + 71 rainfed miscanthus active rainfed miscanthus + 72 irrigated miscanthus active irrigated miscanthus + 73 rainfed switchgrass active rainfed switchgrass + 74 irrigated switchgrass active irrigated switchgrass 75 rainfed tropical corn active rainfed tropical corn 76 irrigated tropical corn active irrigated tropical corn 77 rainfed tropical soybean active rainfed tropical soybean @@ -347,27 +355,27 @@ Harvest occurs in one time step using the BGC leaf offset algorithm. .. table:: Crop phenology and morphology parameters for the active crop plant functional types (pfts) in CLM5BGCCROP. Numbers in the first row correspond to the list of pfts in :numref:`Table Crop plant functional types`. - =================================== ========================= ========================== ========================== ========================== ========================== ========================= ========================= ========================== - \ temperate corn spring wheat temperatue soybean cotton rice sugarcane tropical corn tropical soybean - =================================== ========================= ========================== ========================== ========================== ========================== ========================= ========================= ========================== - IVT 17, 18 19, 20 23, 24 41, 42 61, 62 67, 68 75, 76 77, 78 - :math:`Date_{planting}^{min}` April 1 April 1 May 1 April 1 Janurary 1 Janurary 1 March 20 April 15 - :math:`Date_{planting}^{max}` June 15 June 15 June 15 May 31 Feburary 28 March 31 April 15 June 31 - :math:`T_{p}`\(K) 283.15 280.15 286.15 294.15 294.15 294.15 294.15 294.15 - :math:`T_{p}^{ min }`\(K) 279.15 272.15 279.15 283.15 283.15 283.15 283.15 283.15 - :math:`{GDD}_{min}`\(ºdays) 50 50 50 50 50 50 50 50 - base temperature for GDD (ºC) 8 0 10 10 10 10 10 10 - :math:`{GDD}_{mat}`\(ºdays) 950-1850 :math:`\mathrm{\le}`\ 1700 :math:`\mathrm{\le}`\ 1900 :math:`\mathrm{\le}`\ 1700 :math:`\mathrm{\le}`\ 2100 950-1850 950-1850 :math:`\mathrm{\le}`\ 2100 - Phase 2 % :math:`{GDD}_{mat}` 0.03 0.05 0.03 0.03 0.01 0.03 0.03 0.03 - Phase 3 % :math:`{GDD}_{mat}` 0.65 0.6 0.5 0.5 0.4 0.65 0.5 0.5 - Harvest: days past planting :math:`\mathrm{\le}`\ 165 :math:`\mathrm{\le}`\ 150 :math:`\mathrm{\le}`\ 150 :math:`\mathrm{\le}`\ 160 :math:`\mathrm{\le}`\ 150 :math:`\mathrm{\le}`\ 300 :math:`\mathrm{\le}`\ 160 :math:`\mathrm{\le}`\ 150 - :math:`z_{top}^{\max }` (m) 2.5 1.2 0.75 1.5 1.8 4 2.5 1 - SLA (m :sup:`2` leaf g :sup:`-1` C) 0.05 0.035 0.035 0.035 0.035 0.05 0.05 0.035 - :math:`\chi _{L}` index -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 - grperc 0.11 0.11 0.11 0.11 0.11 0.11 0.11 0.11 - flnr 0.293 0.41 0.41 0.41 0.41 0.293 0.293 0.41 - fcur 1 1 1 1 1 1 1 1 - =================================== ========================= ========================== ========================== ========================== ========================== ========================= ========================= ========================== + =================================== ========================= ========================== ========================== ========================== ========================== ========================= ========================= ========================== ========================== ========================== + \ temperate corn spring wheat temperatue soybean cotton rice sugarcane tropical corn tropical soybean miscanthus switchgrass + =================================== ========================= ========================== ========================== ========================== ========================== ========================= ========================= ========================== ========================== ========================== + IVT 17, 18 19, 20 23, 24 41, 42 61, 62 67, 68 75, 76 77, 78 71, 72 73, 74 + :math:`Date_{planting}^{min}` April 1 April 1 May 1 April 1 Janurary 1 Janurary 1 March 20 April 15 April 1 April 1 + :math:`Date_{planting}^{max}` June 15 June 15 June 15 May 31 Feburary 28 March 31 April 15 June 31 June 15 June 15 + :math:`T_{p}`\(K) 283.15 280.15 286.15 294.15 294.15 294.15 294.15 294.15 283.15 283.15 + :math:`T_{p}^{ min }`\(K) 279.15 272.15 279.15 283.15 283.15 283.15 283.15 283.15 279.15 279.15 + :math:`{GDD}_{min}`\(ºdays) 50 50 50 50 50 50 50 50 50 50 + base temperature for GDD (ºC) 8 0 10 10 10 10 10 10 8 8 + :math:`{GDD}_{mat}`\(ºdays) 950-1850 :math:`\mathrm{\le}`\ 1700 :math:`\mathrm{\le}`\ 1900 :math:`\mathrm{\le}`\ 1700 :math:`\mathrm{\le}`\ 2100 950-1850 950-1850 :math:`\mathrm{\le}`\ 2100 950-1850 950-1850 + Phase 2 % :math:`{GDD}_{mat}` 0.03 0.05 0.03 0.03 0.01 0.03 0.03 0.03 0.03 0.03 + Phase 3 % :math:`{GDD}_{mat}` 0.65 0.6 0.5 0.5 0.4 0.65 0.5 0.5 0.4 0.4 + Harvest: days past planting :math:`\mathrm{\le}`\ 165 :math:`\mathrm{\le}`\ 150 :math:`\mathrm{\le}`\ 150 :math:`\mathrm{\le}`\ 160 :math:`\mathrm{\le}`\ 150 :math:`\mathrm{\le}`\ 300 :math:`\mathrm{\le}`\ 160 :math:`\mathrm{\le}`\ 150 :math:`\mathrm{\le}`\ 210 :math:`\mathrm{\le}`\ 210 + :math:`z_{top}^{\max }` (m) 2.5 1.2 0.75 1.5 1.8 4 2.5 1 2.5 2.5 + SLA (m :sup:`2` leaf g :sup:`-1` C) 0.05 0.035 0.035 0.035 0.035 0.05 0.05 0.035 0.057 0.049 + :math:`\chi _{L}` index -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 + grperc 0.11 0.11 0.11 0.11 0.11 0.11 0.11 0.11 0.11 0.11 + flnr 0.293 0.41 0.41 0.41 0.41 0.293 0.293 0.41 0.293 0.293 + fcur 1 1 1 1 1 1 1 1 1 1 + =================================== ========================= ========================== ========================== ========================== ========================== ========================= ========================= ========================== ========================== ========================== Notes: :math:`Date_{planting}^{min}` and :math:`Date_{planting}^{max}` are the minimum and maximum planting date in the Northern Hemisphere, the corresponding dates @@ -535,24 +543,125 @@ fulfill plant nitrogen demands. Harvest '''''''''''''''''''''''''''''' -Variables track the flow of grain C and -N to food and of all other plant pools, including live stem C and N, to litter. Putting live -stem C and N into the litter pool is in contrast to the approach for unmanaged PFTs which -puts live stem C and N into dead stem pools first. Leaf and root C and N pools -are routed to the litter pools in the same manner as natural vegetation. Whereas food C and N -was formerly transferred to the litter pool, CLM5 routes food C and N +Variables track the flow of grain C and N to food and of all other plant pools, including live stem C and N, to litter, and to biofuel feedstock. +A fraction (determined by :math:`biofuel\_harvfrac`) of leaf/livestem C and N from bioenergy crops is removed at harvest for biofuels +(Equations :eq:`25.9`, :eq:`25.10`, :eq:`25.12`, and :eq:`25.13`), +with the remaining portions go to the litter pools (Equations :eq:`20.14)`, :eq:`25.11`, and :eq:`25.14`). +Putting live stem C and N into the litter and biofuel pools is in contrast to the approach for unmanaged PFTs which +puts live stem C and N into dead stem pools first. +Leaf C and N pools are routed to the little and biofuel pools, contrast to that of unmanaged PFTs which put leaf C and N to litter pools only. +Root C and N pools are routed to the litter pools in the same manner as natural vegetation. + +.. math:: + :label: 25.9 + + CF_{leaf,biofuel} = \left({CS_{leaf} \mathord{\left/ {\vphantom {CS_{leaf} \Delta t}} \right. \kern-\nulldelimiterspace} \Delta t} + \right) * biofuel\_harvfrac + +.. math:: + :label: 25.10 + + CF_{livestem,biofuel} = \left({CS_{livestem} \mathord{\left/ {\vphantom {CS_{leaf} \Delta t}} \right. \kern-\nulldelimiterspace} \Delta t} + \right) * biofuel\_harvfrac + +.. math:: + :label: 25.11 + + CF_{livestem,litter} = \left({CS_{livestem} \mathord{\left/ {\vphantom {CS_{livestem} \Delta t}} \right. \kern-\nulldelimiterspace} \Delta t} + \right) * \left( 1-biofuel\_harvfrac \right) +CF_{alloc,livestem} + +with corresponding nitrogen fluxes: + +.. math:: + :label: 25.12 + + NF_{leaf,biofuel} = \left({NS_{leaf} \mathord{\left/ {\vphantom {NS_{leaf} \Delta t}} \right. \kern-\nulldelimiterspace} \Delta t} + \right) * biofuel\_harvfrac + +.. math:: + :label: 25.13 + + NF_{livestem,biofuel} = \left({NS_{livestem} \mathord{\left/ {\vphantom {NS_{livestem} \Delta t}} \right. \kern-\nulldelimiterspace} \Delta t} + \right) * biofuel\_harvfrac + +.. math:: + :label: 25.14 + + NF_{livestem,litter} = \left({NS_{livestem} \mathord{\left/ {\vphantom {NS_{livestem} \Delta t}} \right. \kern-\nulldelimiterspace} \Delta t} + \right) * \left( 1-biofuel\_harvfrac \right) + +where :math:`biofuel\_harvfrac` is the harvested fraction of leaf/livestem for biofuel feedstocks. + +.. _Table Plant functional type (PFT) parameters for harvested fraction of leaf/livestem for bioenergy crops: + +.. table:: Plant functional type (PFT) parameters for harvested fraction of leaf/livestem for bioenergy crops. + + +----------------------------------+----------------------------+ + | PFT | :math:`biofuel\_harvfrac` | + +==================================+============================+ + | NET Temperate | 0.00 | + +----------------------------------+----------------------------+ + | NET Boreal | 0.00 | + +----------------------------------+----------------------------+ + | NDT Boreal | 0.00 | + +----------------------------------+----------------------------+ + | BET Tropical | 0.00 | + +----------------------------------+----------------------------+ + | BET temperate | 0.00 | + +----------------------------------+----------------------------+ + | BDT tropical | 0.00 | + +----------------------------------+----------------------------+ + | BDT temperate | 0.00 | + +----------------------------------+----------------------------+ + | BDT boreal | 0.00 | + +----------------------------------+----------------------------+ + | BES temperate | 0.00 | + +----------------------------------+----------------------------+ + | BDS temperate | 0.00 | + +----------------------------------+----------------------------+ + | BDS boreal | 0.00 | + +----------------------------------+----------------------------+ + | C\ :sub:`3` arctic grass | 0.00 | + +----------------------------------+----------------------------+ + | C\ :sub:`3` grass | 0.00 | + +----------------------------------+----------------------------+ + | C\ :sub:`4` grass | 0.00 | + +----------------------------------+----------------------------+ + | Temperate Corn | 0.00 | + +----------------------------------+----------------------------+ + | Spring Wheat | 0.00 | + +----------------------------------+----------------------------+ + | Temperate Soybean | 0.00 | + +----------------------------------+----------------------------+ + | Cotton | 0.00 | + +----------------------------------+----------------------------+ + | Rice | 0.00 | + +----------------------------------+----------------------------+ + | Sugarcane | 0.00 | + +----------------------------------+----------------------------+ + | Tropical Corn | 0.00 | + +----------------------------------+----------------------------+ + | Tropical Soybean | 0.00 | + +----------------------------------+----------------------------+ + | Miscanthus | 0.70 | + +----------------------------------+----------------------------+ + | Switchgrass | 0.70 | + +----------------------------------+----------------------------+ + +Whereas food C and N was formerly transferred to the litter pool, CLM5 routes food C and N to a grain product pool where the C and N decay to the atmosphere over one year, similar in structure to the wood product pools. +The biofuel C and N is also routed to the grain product pool and decay to the atmosphere over one year. Additionally, CLM5 accounts for the C and N required for crop seeding by removing the seed C and N from the grain product pool during harvest. The crop seed pool is then used to seed crops in the subsequent year. -Calcuating the crop yields (Equation :eq:`25.9`) requires that you sum the GRAINC_TO_FOOD variable +Calcuating the crop yields (Equation :eq:`25.15`) requires that you sum the GRAINC_TO_FOOD variable for each year, and must account for the proportion of C in the dry crop weight. Here, we assume that grain C is 45% of the total dry weight. Additionally, harvest is not typically 100% efficient, so analysis needs to assume that harvest efficiency is less. We assume a harvest efficiency of 85%. .. math:: - :label: 25.9 + :label: 25.15 Grain\ yield(g.m^{-2})=\frac{\sum(GRAINC\_ TO\_ FOOD)*0.85}{0.45} @@ -561,27 +670,27 @@ efficiency of 85%. .. table:: Crop allocation parameters for the active crop plant functional types (pfts) in CLM5BGCCROP. Numbers in the first row correspond to the list of pfts in :numref:`Table Crop plant functional types`. - =========================================== ============== ============ ================== ====== ====== ========= ============= ================ - \ temperate corn spring wheat temperatue soybean cotton rice sugarcane tropical corn tropical soybean - =========================================== ============== ============ ================== ====== ====== ========= ============= ================ - IVT 17, 18 19, 20 23, 24 41, 42 61, 62 67, 68 75, 76 77, 78 - :math:`a_{leaf}^{i}` 0.6 0.9 0.85 0.85 0.75 0.6 0.6 0.85 - :math:`{L}_{max}` (m :sup:`2` m :sup:`-2`) 5 7 6 6 7 5 5 6 - :math:`a_{froot}^{i}` 0.1 0.05 0.2 0.2 0.1 0.1 0.1 0.2 - :math:`a_{froot}^{f}` 0.05 0 0.2 0.2 0 0.05 0.05 0.2 - :math:`a_{leaf}^{f}` 0 0 0 0 0 0 0 0 - :math:`a_{livestem}^{f}` 0 0.05 0.3 0.3 0.05 0 0 0.3 - :math:`d_{L}` 1.05 1.05 1.05 1.05 1.05 1.05 1.05 1.05 - :math:`d_{alloc}^{stem}` 2 1 5 5 1 2 2 5 - :math:`d_{alloc}^{leaf}` 5 3 2 2 3 5 5 2 - :math:`{CN}_{leaf}` 25 20 20 20 20 25 25 20 - :math:`{CN}_{stem}` 50 50 50 50 50 50 50 50 - :math:`{CN}_{froot}` 42 42 42 42 42 42 42 42 - :math:`CN^f_{leaf}` 65 65 65 65 65 65 65 65 - :math:`CN^f_{stem}` 120 100 130 130 100 120 120 130 - :math:`CN^f_{froot}` 0 40 0 0 40 0 0 0 - :math:`{CN}_{grain}` 50 50 50 50 50 50 50 50 - =========================================== ============== ============ ================== ====== ====== ========= ============= ================ + =========================================== ============== ============ ================== ====== ====== ========= ============= ================ ================ ================ + \ temperate corn spring wheat temperatue soybean cotton rice sugarcane tropical corn tropical soybean miscanthus switchgrass + =========================================== ============== ============ ================== ====== ====== ========= ============= ================ ================ ================ + IVT 17, 18 19, 20 23, 24 41, 42 61, 62 67, 68 75, 76 77, 78 71, 72 73, 74 + :math:`a_{leaf}^{i}` 0.6 0.9 0.85 0.85 0.75 0.6 0.6 0.85 0.9 0.7 + :math:`{L}_{max}` (m :sup:`2` m :sup:`-2`) 5 7 6 6 7 5 5 6 10 6.5 + :math:`a_{froot}^{i}` 0.1 0.05 0.2 0.2 0.1 0.1 0.1 0.2 0.11 0.14 + :math:`a_{froot}^{f}` 0.05 0 0.2 0.2 0 0.05 0.05 0.2 0.09 0.09 + :math:`a_{leaf}^{f}` 0 0 0 0 0 0 0 0 0 0 + :math:`a_{livestem}^{f}` 0 0.05 0.3 0.3 0.05 0 0 0.3 0 0 + :math:`d_{L}` 1.05 1.05 1.05 1.05 1.05 1.05 1.05 1.05 1.05 1.05 + :math:`d_{alloc}^{stem}` 2 1 5 5 1 2 2 5 2 2 + :math:`d_{alloc}^{leaf}` 5 3 2 2 3 5 5 2 5 5 + :math:`{CN}_{leaf}` 25 20 20 20 20 25 25 20 25 25 + :math:`{CN}_{stem}` 50 50 50 50 50 50 50 50 50 50 + :math:`{CN}_{froot}` 42 42 42 42 42 42 42 42 42 42 + :math:`CN^f_{leaf}` 65 65 65 65 65 65 65 65 65 65 + :math:`CN^f_{stem}` 120 100 130 130 100 120 120 130 120 120 + :math:`CN^f_{froot}` 0 40 0 0 40 0 0 0 0 0 + :math:`{CN}_{grain}` 50 50 50 50 50 50 50 50 50 50 + =========================================== ============== ============ ================== ====== ====== ========= ============= ================ ================ ================ Notes: Crop growth phases and corresponding variables are described throughout the text. :math:`{CN}_{leaf}`, :math:`{CN}_{stem}`, and :math:`{CN}_{froot}` are @@ -609,7 +718,7 @@ and :math:`{z}_{bot}` (m), come from the AgroIBIS formulation: .. math:: - :label: 25.10 + :label: 25.16 \begin{array}{l} {z_{top} =z_{top}^{\max } \left(\frac{L}{L_{\max } -1} \right)^{2} \ge 0.05{\rm \; where\; }\frac{L}{L_{\max } -1} \le 1} \\ @@ -651,7 +760,7 @@ counter in seconds, *f*, is set as soon as the leaf emergence phase for crops initiates: .. math:: - :label: 25.11 + :label: 25.17 f = n \times 86400 @@ -682,7 +791,7 @@ the for both rainfed and irrigated spring wheat and sugarcane, the calculation o :math:`GDD_{T_{{\rm 2m}} }` allows for latitudinal variation: .. math:: - :label: 25.12 + :label: 25.18 latitudinal\ variation\ in\ base\ T = \left\{ \begin{array}{lr} diff --git a/doc/source/tech_note/Fluxes/CLM50_Tech_Note_Fluxes.rst b/doc/source/tech_note/Fluxes/CLM50_Tech_Note_Fluxes.rst index d967cd5ff0..047d4e6723 100644 --- a/doc/source/tech_note/Fluxes/CLM50_Tech_Note_Fluxes.rst +++ b/doc/source/tech_note/Fluxes/CLM50_Tech_Note_Fluxes.rst @@ -1351,7 +1351,15 @@ plus stem area for which :math:`z_{0m}` reaches its maximum. +----------------------------------+--------------------+------------------+-------------------------+ | Soybean I | 0.120 | 0.68 | 0.04 | +----------------------------------+--------------------+------------------+-------------------------+ - + | Miscanthus R | 0.120 | 0.68 | 0.04 | + +----------------------------------+--------------------+------------------+-------------------------+ + | Miscanthus I | 0.120 | 0.68 | 0.04 | + +----------------------------------+--------------------+------------------+-------------------------+ + | Switchgrass R | 0.120 | 0.68 | 0.04 | + +----------------------------------+--------------------+------------------+-------------------------+ + | Switchgrass I | 0.120 | 0.68 | 0.04 | + +----------------------------------+--------------------+------------------+-------------------------+ + .. _Numerical Implementation: Numerical Implementation diff --git a/doc/source/tech_note/Introduction/CLM50_Tech_Note_Introduction.rst b/doc/source/tech_note/Introduction/CLM50_Tech_Note_Introduction.rst index 7240dfa8d9..5969e4a2d1 100644 --- a/doc/source/tech_note/Introduction/CLM50_Tech_Note_Introduction.rst +++ b/doc/source/tech_note/Introduction/CLM50_Tech_Note_Introduction.rst @@ -13,7 +13,7 @@ ***Contributing Authors*** -**Ashehad Ali, Andrew Badger, Gautam Bisht, Patrick Broxton, Michael Brunke, Jonathan Buzan, Martyn Clark, Tony Craig, Kyla Dahlin, Beth Drewniak, Louisa Emmons, Josh Fisher, Mark Flanner, Pierre Gentine, Jan Lenaerts, Sam Levis, +**Ashehad Ali, Andrew Badger, Gautam Bisht, Patrick Broxton, Michael Brunke, Jonathan Buzan, Yanyan Cheng, Martyn Clark, Tony Craig, Kyla Dahlin, Beth Drewniak, Louisa Emmons, Josh Fisher, Mark Flanner, Pierre Gentine, Maoyi Huang, Jan Lenaerts, Sam Levis, L. Ruby Leung, William Lipscomb, Jon Pelletier, Daniel M. Ricciuto, Ben Sanderson, Jacquelyn Shuman, Andrew Slater, Zachary Subin, Jinyun Tang, Ahmed Tawfik, Quinn Thomas, Simone Tilmes, Francis Vitt, Xubin Zeng** @@ -524,11 +524,17 @@ light capture, carboxylation, and respiration are co-limiting. CLM5 applies a fixed allocation scheme for woody vegetation. The decision to use a fixed allocation scheme in CLM5, rather than a dynamic NPP-based allocation scheme, as was used in CLM4 and CLM4.5, was driven by the fact that observations indicate that biomass saturates with increasing productivity, in contrast to the behavior in CLM4 and CLM4.5 where biomass continuously increases with increasing productivity (:ref:`Negron-Juarez et al., 2015`). Soil carbon decomposition processes are unchanged in CLM5, but a new metric for apparent soil carbon turnover times (:ref:`Koven et al., 2017 `) suggested parameter changes that produce a weak intrinsic depth limitation on soil carbon turnover rates (rather than the strong depth limitaiton in CLM4.5) and that the thresholds for soil moisture limitation on soil carbon turnover rates in dry soils should be set at a wetter soil moisture level than that used in CLM4.5. -Representation of human management of the land (agriculture, wood harvest) is augmented in several ways. The CLM4.5 crop model is extended to operate globally through the addition of rice and sugarcane as well as tropical varieties of corn and soybean :ref:`(Badger and Dirmeyer, 2015` and :ref:`Levis et al., 2016)`. These crop types are added to the existing temperate corn, temperature soybean, spring wheat, and cotton crop types. -Fertilization rates and irrigation equipped area updated annually based on crop type and geographic region through an input dataset. The irrigation trigger is updated. Additional minor changes include crop phenological triggers that +Representation of human management of the land (agriculture, wood harvest) is augmented in several ways. +The CLM4.5 crop model is extended to operate globally through the addition of rice, sugarcane, +tropical varieties of corn and soybean :ref:`(Badger and Dirmeyer, 2015` and :ref:`Levis et al., 2016)`, +and perennial bioenergy crops :ref:`(Cheng et al., 2019)`. +These crop types are added to the existing temperate corn, temperature soybean, spring wheat, and cotton crop types. +Fertilization rates and irrigation equipped area updated annually based on crop type and geographic region through an input dataset. +The irrigation trigger is updated. Additional minor changes include crop phenological triggers that vary by latitude for selected crop types, grain C and N is now removed at harvest to a 1-year product pool with -the carbon for the next season's crop seed removed from the grain carbon at harvest. Through the introduction of -the capability to dynamically adjust landunit weights during a simulation, the crop model can now be run coincidentally +the carbon for the next season's crop seed removed from the grain carbon at harvest. +A fraction of leaf/livestem C and N from bioenergy crops is removed at harvest to the biofuel feedstock pools and added to the 1-year product pool. +Through the introduction of the capability to dynamically adjust landunit weights during a simulation, the crop model can now be run coincidentally with prescribed land use, which significantly expands the capabilities of the model. Mass-based rather than area-based wood harvest is applied. Several heat stress indices for both urban and rural areas are calculated and output by default :ref:`(Buzan et al., 2015)`. A more sophisticated and realistic building space heating and air conditioning submodel that prognoses interior building air temperature and includes more realistic space heating and air conditioning wasteheat factors is incorporated. diff --git a/doc/source/tech_note/Photosynthesis/CLM50_Tech_Note_Photosynthesis.rst b/doc/source/tech_note/Photosynthesis/CLM50_Tech_Note_Photosynthesis.rst index f7171f1a10..3f0c4849ae 100644 --- a/doc/source/tech_note/Photosynthesis/CLM50_Tech_Note_Photosynthesis.rst +++ b/doc/source/tech_note/Photosynthesis/CLM50_Tech_Note_Photosynthesis.rst @@ -136,7 +136,11 @@ atmospheric potential temperature (K). +----------------------------------+-------------------+ | Tropical Soybean | 5.79 | +----------------------------------+-------------------+ - + | Miscanthus | 1.79 | + +----------------------------------+-------------------+ + | Switchgrass | 1.79 | + +----------------------------------+-------------------+ + .. _Photosynthesis: Photosynthesis diff --git a/doc/source/tech_note/Photosynthetic_Capacity/CLM50_Tech_Note_Photosynthetic_Capacity.rst b/doc/source/tech_note/Photosynthetic_Capacity/CLM50_Tech_Note_Photosynthetic_Capacity.rst index c4dd5b03f9..c42d7971a8 100755 --- a/doc/source/tech_note/Photosynthetic_Capacity/CLM50_Tech_Note_Photosynthetic_Capacity.rst +++ b/doc/source/tech_note/Photosynthetic_Capacity/CLM50_Tech_Note_Photosynthetic_Capacity.rst @@ -136,6 +136,10 @@ and :math:`\text{LMA}` is the inverse of specific leaf area at the canopy top (: +----------------------------------+--------------------------+--------------------------+ | Tropical Soybean | 0.0350 | 0.4102 | +----------------------------------+--------------------------+--------------------------+ + | Miscanthus | 0.0570 | 0.2930 | + +----------------------------------+--------------------------+--------------------------+ + | Switchgrass | 0.0490 | 0.2930 | + +----------------------------------+--------------------------+--------------------------+ Notes: :math:`SLA_{\text{0}}` is the specific leaf area at the canopy top (m :sup:`2` leaf/g biomass), and :math:`N_{\text{cb}}` is the fraction of leaf nitrogen in Rubisco (g N in Rubisco g :sup:`-1` N) diff --git a/doc/source/tech_note/Plant_Hydraulics/CLM50_Tech_Note_Plant_Hydraulics.rst b/doc/source/tech_note/Plant_Hydraulics/CLM50_Tech_Note_Plant_Hydraulics.rst index 88d09d18a5..f33a6d96b5 100644 --- a/doc/source/tech_note/Plant_Hydraulics/CLM50_Tech_Note_Plant_Hydraulics.rst +++ b/doc/source/tech_note/Plant_Hydraulics/CLM50_Tech_Note_Plant_Hydraulics.rst @@ -93,6 +93,14 @@ distribution parameter adopted from :ref:`Jackson et al. (1996) +----------------------------------+------------------+ | Soybean I | 0.943 | +----------------------------------+------------------+ + | Miscanthus R | 0.943 | + +----------------------------------+------------------+ + | Miscanthus I | 0.943 | + +----------------------------------+------------------+ + | Switchgrass R | 0.943 | + +----------------------------------+------------------+ + | Switchgrass I | 0.943 | + +----------------------------------+------------------+ .. _Root Spacing: diff --git a/doc/source/tech_note/References/CLM50_Tech_Note_References.rst b/doc/source/tech_note/References/CLM50_Tech_Note_References.rst index f5ffc26b95..387d2e0a0d 100644 --- a/doc/source/tech_note/References/CLM50_Tech_Note_References.rst +++ b/doc/source/tech_note/References/CLM50_Tech_Note_References.rst @@ -274,6 +274,14 @@ Cao, M., Marshall, S. and Gregson, K., 1996. Global carbon exchange and methane emissions from natural wetlands: Application of a process-based model. J. Geophys. Res. 101(D9):14,399-14,414. +.. _Chengetal2019: + +Cheng, Y., Huang, M., et al., 2019. Parameterizing perennial bioenergy +crops in Version 5 of the Community Land Model Based on Site‐Level +Observations in the Central Midwestern United States. +Journal of Advances in Modeling Earth Systems, +2(2013), 1–24. https://doi.org/10.1029/2019MS001719 + .. _Chuangetal2006: Chuang Y.L., Oren R., Bertozzi A.L, Phillips N., Katul G.G. 2006. The diff --git a/doc/source/tech_note/Surface_Albedos/CLM50_Tech_Note_Surface_Albedos.rst b/doc/source/tech_note/Surface_Albedos/CLM50_Tech_Note_Surface_Albedos.rst index 2770917358..36bebbe56f 100644 --- a/doc/source/tech_note/Surface_Albedos/CLM50_Tech_Note_Surface_Albedos.rst +++ b/doc/source/tech_note/Surface_Albedos/CLM50_Tech_Note_Surface_Albedos.rst @@ -485,6 +485,10 @@ intercepted snow (:numref:`Table Intercepted snow optical properties`) are from +----------------------------------+----------------------+---------------------------------+---------------------------------+---------------------------------+---------------------------------+-------------------------------+-------------------------------+-------------------------------+-------------------------------+ | Tropical Soybean | -0.50 | 0.11 | 0.35 | 0.31 | 0.53 | 0.05 | 0.34 | 0.120 | 0.250 | +----------------------------------+----------------------+---------------------------------+---------------------------------+---------------------------------+---------------------------------+-------------------------------+-------------------------------+-------------------------------+-------------------------------+ + | Miscanthus | -0.50 | 0.11 | 0.35 | 0.31 | 0.53 | 0.05 | 0.34 | 0.120 | 0.250 | + +----------------------------------+----------------------+---------------------------------+---------------------------------+---------------------------------+---------------------------------+-------------------------------+-------------------------------+-------------------------------+-------------------------------+ + | Switchgrass | -0.50 | 0.11 | 0.35 | 0.31 | 0.53 | 0.05 | 0.34 | 0.120 | 0.250 | + +----------------------------------+----------------------+---------------------------------+---------------------------------+---------------------------------+---------------------------------+-------------------------------+-------------------------------+-------------------------------+-------------------------------+ .. _Table Intercepted snow optical properties: diff --git a/doc/source/tech_note/Vegetation_Phenology_Turnover/CLM50_Tech_Note_Vegetation_Phenology_Turnover.rst b/doc/source/tech_note/Vegetation_Phenology_Turnover/CLM50_Tech_Note_Vegetation_Phenology_Turnover.rst index 7ede3405e0..775494c300 100644 --- a/doc/source/tech_note/Vegetation_Phenology_Turnover/CLM50_Tech_Note_Vegetation_Phenology_Turnover.rst +++ b/doc/source/tech_note/Vegetation_Phenology_Turnover/CLM50_Tech_Note_Vegetation_Phenology_Turnover.rst @@ -5,8 +5,8 @@ Vegetation Phenology and Turnover The CLM phenology model consists of several algorithms controlling the transfer of stored carbon and nitrogen out of storage pools for the -display of new growth and into litter pools for losses of displayed -growth. PFTs are classified into three distinct phenological types that +display of new growth, into litter pools for losses of displayed +growth, and into biofuel pools for bioenergy. PFTs are classified into three distinct phenological types that are represented by separate algorithms: an evergreen type, for which some fraction of annual leaf growth persists in the displayed pool for longer than one year; a seasonal-deciduous type with a single growing @@ -132,12 +132,16 @@ periods as: .. math:: :label: 20.14) - CF_{leaf,litter}^{n} =\left\{\begin{array}{l} {CF_{leaf,litter}^{n-1} +r_{xfer\_ off} \left(CS_{leaf} -CF_{leaf,litter}^{n-1} {\kern 1pt} t_{offset} \right)\qquad {\rm for\; }t_{offset} \ne \Delta t} \\ {\left({CS_{leaf} \mathord{\left/ {\vphantom {CS_{leaf} \Delta t}} \right. \kern-\nulldelimiterspace} \Delta t} \right)+CF_{alloc,leaf} \qquad \qquad \qquad \qquad {\rm for\; }t_{offset} =\Delta t} \end{array}\right. + CF_{leaf,litter}^{n} =\left\{\begin{array}{l} {CF_{leaf,litter}^{n-1} + r_{xfer\_ off} \left(CS_{leaf} -CF_{leaf,litter}^{n-1} {\kern 1pt} t_{offset} \right)\qquad {\rm for\; }t_{offset} \ne \Delta t} + \\ {\left({CS_{leaf} \mathord{\left/ {\vphantom {CS_{leaf} \Delta t}} \right. \kern-\nulldelimiterspace} \Delta t} \right) + \left( 1-biofuel\_harvfrac \right) + +CF_{alloc,leaf} \qquad {\rm for\; }t_{offset} =\Delta t} \end{array}\right. .. math:: :label: 20.15) - CF_{froot,litter}^{n} =\left\{\begin{array}{l} {CF_{froot,litter}^{n-1} +r_{xfer\_ off} \left(CS_{froot} -CF_{froot,litter}^{n-1} {\kern 1pt} t_{offset} \right)\qquad {\rm for\; }t_{offset} \ne \Delta t} \\ {\left({CS_{froot} \mathord{\left/ {\vphantom {CS_{froot} \Delta t}} \right. \kern-\nulldelimiterspace} \Delta t} \right)+CF_{alloc,\, froot} \qquad \qquad \qquad {\rm for\; }t_{offset} =\Delta t} \end{array}\right. + CF_{froot,litter}^{n} =\left\{\begin{array}{l} {CF_{froot,litter}^{n-1} + + r_{xfer\_ off} \left(CS_{froot} -CF_{froot,litter}^{n-1} {\kern 1pt} t_{offset} \right)\qquad {\rm for\; }t_{offset} \ne \Delta t} \\ {\left({CS_{froot} \mathord{\left/ {\vphantom {CS_{froot} \Delta t}} \right. \kern-\nulldelimiterspace} \Delta t} \right)+CF_{alloc,\, froot} \qquad \qquad \qquad {\rm for\; }t_{offset} =\Delta t} \end{array}\right. .. math:: :label: 20.16) @@ -146,10 +150,14 @@ periods as: where superscripts *n* and *n-1* refer to fluxes on the current and previous timesteps, respectively. The rate coefficient :math:`{r}_{xfer\_off}` varies with time to produce a linearly -increasing litterfall rate throughout the offset period, and the special -case for fluxes in the final litterfall timestep -(:math:`{t}_{offset}` = :math:`\Delta t`\ ) ensures that all of the -displayed growth is sent to the litter pools for deciduous plant types. +increasing litterfall rate throughout the offset period. +The :math:`biofuel\_harvfrac` (:numref:`Table Plant functional type (PFT) parameters for harvested fraction of leaf/livestem for bioenergy crops`) +is the harvested fraction of aboveground biomass (leaf & livestem) for bioenergy crops. It is only non-zero for prognostic crops. +The special case for fluxes in the final litterfall timestep +(:math:`{t}_{offset}` = :math:`\Delta t`\ ) ensures that a fraction (:math:`1-biofuel\_harvfrac`) of the +displayed growth is sent to the litter pools for deciduous plant types, while the remaining fraction (:math:`biofuel\_harvfrac`) +of leaf biomass goes to the biofuel feedstock pools (Equation :eq:`25.9`). Modifications on livestem carbon pools can be found +in section :numref:`Harvest to food and seed` in Equations :eq:`25.9`-:eq:`25.14`. Corresponding nitrogen fluxes during litterfall take into account retranslocation of nitrogen out of the displayed leaf pool prior to litterfall (:math:`{NF}_{leaf,retrans}`, gN m\ :sup:`-2` s\ :sup:`-1`). Retranslocation of nitrogen out of fine roots is From e5591e81699d61285addaf969a09cefeddab623b Mon Sep 17 00:00:00 2001 From: yanyanchengHydro Date: Wed, 15 Apr 2020 20:05:29 -0700 Subject: [PATCH 45/75] add documents for changes relevant to bioenergy crops --- .../CLM50_Tech_Note_Vegetation_Phenology_Turnover.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/tech_note/Vegetation_Phenology_Turnover/CLM50_Tech_Note_Vegetation_Phenology_Turnover.rst b/doc/source/tech_note/Vegetation_Phenology_Turnover/CLM50_Tech_Note_Vegetation_Phenology_Turnover.rst index 775494c300..110883ff48 100644 --- a/doc/source/tech_note/Vegetation_Phenology_Turnover/CLM50_Tech_Note_Vegetation_Phenology_Turnover.rst +++ b/doc/source/tech_note/Vegetation_Phenology_Turnover/CLM50_Tech_Note_Vegetation_Phenology_Turnover.rst @@ -6,7 +6,7 @@ Vegetation Phenology and Turnover The CLM phenology model consists of several algorithms controlling the transfer of stored carbon and nitrogen out of storage pools for the display of new growth, into litter pools for losses of displayed -growth, and into biofuel pools for bioenergy. PFTs are classified into three distinct phenological types that +growth, and into biofuel feedstock pools for bioenergy. PFTs are classified into three distinct phenological types that are represented by separate algorithms: an evergreen type, for which some fraction of annual leaf growth persists in the displayed pool for longer than one year; a seasonal-deciduous type with a single growing From 52bd548aea0252308e08f56c5d05181538797be1 Mon Sep 17 00:00:00 2001 From: yanyanchengHydro Date: Wed, 15 Apr 2020 20:07:24 -0700 Subject: [PATCH 46/75] add documents for changes relevant to bioenergy crops --- .../CLM50_Tech_Note_Vegetation_Phenology_Turnover.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/source/tech_note/Vegetation_Phenology_Turnover/CLM50_Tech_Note_Vegetation_Phenology_Turnover.rst b/doc/source/tech_note/Vegetation_Phenology_Turnover/CLM50_Tech_Note_Vegetation_Phenology_Turnover.rst index 110883ff48..0d6576d0c7 100644 --- a/doc/source/tech_note/Vegetation_Phenology_Turnover/CLM50_Tech_Note_Vegetation_Phenology_Turnover.rst +++ b/doc/source/tech_note/Vegetation_Phenology_Turnover/CLM50_Tech_Note_Vegetation_Phenology_Turnover.rst @@ -156,8 +156,8 @@ is the harvested fraction of aboveground biomass (leaf & livestem) for bioenergy The special case for fluxes in the final litterfall timestep (:math:`{t}_{offset}` = :math:`\Delta t`\ ) ensures that a fraction (:math:`1-biofuel\_harvfrac`) of the displayed growth is sent to the litter pools for deciduous plant types, while the remaining fraction (:math:`biofuel\_harvfrac`) -of leaf biomass goes to the biofuel feedstock pools (Equation :eq:`25.9`). Modifications on livestem carbon pools can be found -in section :numref:`Harvest to food and seed` in Equations :eq:`25.9`-:eq:`25.14`. +of leaf biomass goes to the biofuel feedstock pools (Equation :eq:`25.9`). Modifications on livestem carbon pools for prognostic crops +can be found in section :numref:`Harvest to food and seed` in Equations :eq:`25.9`-:eq:`25.14`. Corresponding nitrogen fluxes during litterfall take into account retranslocation of nitrogen out of the displayed leaf pool prior to litterfall (:math:`{NF}_{leaf,retrans}`, gN m\ :sup:`-2` s\ :sup:`-1`). Retranslocation of nitrogen out of fine roots is From 9cc3609a3be1914655dce4f09fd53f0348ffc256 Mon Sep 17 00:00:00 2001 From: yanyanchengHydro Date: Fri, 24 Apr 2020 23:40:34 -0700 Subject: [PATCH 47/75] update tech note --- .../CLM50_Tech_Note_Crop_Irrigation.rst | 38 +++++++++++++------ .../References/CLM50_Tech_Note_References.rst | 2 +- ...ech_Note_Vegetation_Phenology_Turnover.rst | 4 +- 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst b/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst index a82f871e6d..9ddcd76f57 100644 --- a/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst +++ b/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst @@ -40,9 +40,17 @@ refers to the interactive crop management model and is included as an option wit These updates appear in detail in the sections below. Many also appear in :ref:`Levis et al. (2016) `. + +Available new features since the CLM5 release +^^^^^^^^^^^^^^^^^^^ +- Addition of bioenergy crops + + + + .. _The crop model: -The crop model: stable and bioenergy crops +The crop model: cash and bioenergy crops ------------------- Introduction @@ -107,18 +115,20 @@ CLM5 includes ten actively managed crop types corn, spring wheat, cotton, rice, sugarcane, miscanthus, and switchgrass) that are chosen based on the availability of corresponding algorithms in AgroIBIS and as developed by :ref:`Badger and Dirmeyer (2015)` and -described by :ref:`Levis et al. (2016)` and :ref:`Cheng et al. (2019)`. -The representations of sugarcane, rice, cotton, tropical corn, tropical soy, miscanthus, and switchgrass are new in CLM5. +described by :ref:`Levis et al. (2016)`, or from available observations +as described by :ref:`Cheng et al. (2019)`. +The representations of sugarcane, rice, cotton, tropical corn, and tropical soy are new in CLM5. +Miscanthus and switchgrass are added after the CLM5 release. Sugarcane and tropical corn are both C4 plants and are therefore represented using the temperate corn functional form. Tropical soybean uses the temperate soybean functional form, while rice and cotton use the wheat functional form. In tropical regions, parameter values were developed for the Amazon Basin, and planting date window is shifted by six months relative to the Northern Hemisphere. Plantation areas of bioenergy crops are projected to expand throughout the 21st century as a major energy source to -replace fossil fuels and mitigate climate changes. Miscanthus and switchgrass are perennial bioenergy crops and +replace fossil fuels and mitigate climate change. Miscanthus and switchgrass are perennial bioenergy crops and have quite different physiological traits and land management practices than annual crops, -such as longer growing seasons, higher productivity, and less demands for nutrients and water. -About 70% of their aboveground biomass (leaf & livestem) is removed at harvest for biofuels. Parameter values were developed by using +such as longer growing seasons, higher productivity, and lower demands for nutrients and water. +About 70% of biofuel aboveground biomass (leaf & livestem) is removed at harvest for biofuels. Parameter values were developed by using observation data collected at the University of Illinois Energy Farm located in Central Midwestern United States (:ref:`Cheng et al., 2019`). @@ -129,7 +139,7 @@ The unmanaged C3 crop is only used when the crop model is not active and has grid cell coverage assigned from satellite data, and the unmanaged C3 irrigated crop type is currently not used since irrigation requires the crop model to be active. -The default list of pfts also includes twenty-three inactive crop pfts +The default list of pfts also includes twenty-one inactive crop pfts that do not yet have associated parameters required for active management. Each of the inactive crop types is simulated using the parameters of the spatially closest associated crop type that is most similar to the functional type (e.g., C3 or C4), @@ -546,7 +556,7 @@ Harvest Variables track the flow of grain C and N to food and of all other plant pools, including live stem C and N, to litter, and to biofuel feedstock. A fraction (determined by :math:`biofuel\_harvfrac`) of leaf/livestem C and N from bioenergy crops is removed at harvest for biofuels (Equations :eq:`25.9`, :eq:`25.10`, :eq:`25.12`, and :eq:`25.13`), -with the remaining portions go to the litter pools (Equations :eq:`20.14)`, :eq:`25.11`, and :eq:`25.14`). +with the remaining portions going to the litter pools (Equations :eq:`20.14)`, :eq:`25.11`, and :eq:`25.14`). Putting live stem C and N into the litter and biofuel pools is in contrast to the approach for unmanaged PFTs which puts live stem C and N into dead stem pools first. Leaf C and N pools are routed to the little and biofuel pools, contrast to that of unmanaged PFTs which put leaf C and N to litter pools only. @@ -590,11 +600,12 @@ with corresponding nitrogen fluxes: NF_{livestem,litter} = \left({NS_{livestem} \mathord{\left/ {\vphantom {NS_{livestem} \Delta t}} \right. \kern-\nulldelimiterspace} \Delta t} \right) * \left( 1-biofuel\_harvfrac \right) -where :math:`biofuel\_harvfrac` is the harvested fraction of leaf/livestem for biofuel feedstocks. +where CF is the carbon flux, CS is stored carbon, NF is the nitrogen flux, NS is stored nitrogen, and + :math:`biofuel\_harvfrac` is the harvested fraction of leaf/livestem for biofuel feedstocks. -.. _Table Plant functional type (PFT) parameters for harvested fraction of leaf/livestem for bioenergy crops: +.. _Table Plant functional type (PFT) parameters for harvested fraction of leaf/livestem for bioenergy production: -.. table:: Plant functional type (PFT) parameters for harvested fraction of leaf/livestem for bioenergy crops. +.. table:: Plant functional type (PFT) parameters for harvested fraction of leaf/livestem for bioenergy production. +----------------------------------+----------------------------+ | PFT | :math:`biofuel\_harvfrac` | @@ -745,7 +756,10 @@ In transient simulations, annual fertilizer application is specified on the land file by the field FERTNITRO_CFT, which is also in g N/m\ :sup:`2`/yr. The values for both of these fields come from the LUMIP time series for each year. In addition to the industrial fertilizer, background manure fertilizer is specified -on the parameter file by the field 'manunitro'. For the current CLM5BGCCROP, +on the parameter file by the field 'manunitro'. For perennial bioenergy crops, +little fertilizer (56kg/ha/yr) is applied to switchgrass, no fertilizer is applied to Miscanthus. +Note this set up is only based on local land management practice at the University of Illinois Energy Farm +located in Central Midwestern United States :ref:`(Cheng et al., 2019)`. For the current CLM5BGCCROP, manure N is applied at a rate of 0.002 kg N/m\ :sup:`2`/yr. Because previous versions of CLM (e.g., CLM4) had rapid denitrification rates, fertilizer is applied slowly to minimize N loss (primarily through denitrification) and maximize plant uptake. diff --git a/doc/source/tech_note/References/CLM50_Tech_Note_References.rst b/doc/source/tech_note/References/CLM50_Tech_Note_References.rst index 387d2e0a0d..4bd7a2cf9b 100644 --- a/doc/source/tech_note/References/CLM50_Tech_Note_References.rst +++ b/doc/source/tech_note/References/CLM50_Tech_Note_References.rst @@ -276,7 +276,7 @@ model. J. Geophys. Res. 101(D9):14,399-14,414. .. _Chengetal2019: -Cheng, Y., Huang, M., et al., 2019. Parameterizing perennial bioenergy +Cheng, Y. et al., 2019. Parameterizing perennial bioenergy crops in Version 5 of the Community Land Model Based on Site‐Level Observations in the Central Midwestern United States. Journal of Advances in Modeling Earth Systems, diff --git a/doc/source/tech_note/Vegetation_Phenology_Turnover/CLM50_Tech_Note_Vegetation_Phenology_Turnover.rst b/doc/source/tech_note/Vegetation_Phenology_Turnover/CLM50_Tech_Note_Vegetation_Phenology_Turnover.rst index 0d6576d0c7..023344cbe6 100644 --- a/doc/source/tech_note/Vegetation_Phenology_Turnover/CLM50_Tech_Note_Vegetation_Phenology_Turnover.rst +++ b/doc/source/tech_note/Vegetation_Phenology_Turnover/CLM50_Tech_Note_Vegetation_Phenology_Turnover.rst @@ -5,8 +5,8 @@ Vegetation Phenology and Turnover The CLM phenology model consists of several algorithms controlling the transfer of stored carbon and nitrogen out of storage pools for the -display of new growth, into litter pools for losses of displayed -growth, and into biofuel feedstock pools for bioenergy. PFTs are classified into three distinct phenological types that +display of new growth and into litter pools for losses of displayed +growth. PFTs are classified into three distinct phenological types that are represented by separate algorithms: an evergreen type, for which some fraction of annual leaf growth persists in the displayed pool for longer than one year; a seasonal-deciduous type with a single growing From d666d831f8b9699be0052d58e0a2487a603d0cc4 Mon Sep 17 00:00:00 2001 From: yanyanchengHydro Date: Fri, 24 Apr 2020 23:44:00 -0700 Subject: [PATCH 48/75] update tech note --- .../Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst b/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst index 9ddcd76f57..e4ec4e1ab2 100644 --- a/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst +++ b/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst @@ -600,8 +600,8 @@ with corresponding nitrogen fluxes: NF_{livestem,litter} = \left({NS_{livestem} \mathord{\left/ {\vphantom {NS_{livestem} \Delta t}} \right. \kern-\nulldelimiterspace} \Delta t} \right) * \left( 1-biofuel\_harvfrac \right) -where CF is the carbon flux, CS is stored carbon, NF is the nitrogen flux, NS is stored nitrogen, and - :math:`biofuel\_harvfrac` is the harvested fraction of leaf/livestem for biofuel feedstocks. +where CF is the carbon flux, CS is stored carbon, NF is the nitrogen flux, +NS is stored nitrogen, and :math:`biofuel\_harvfrac` is the harvested fraction of leaf/livestem for biofuel feedstocks. .. _Table Plant functional type (PFT) parameters for harvested fraction of leaf/livestem for bioenergy production: From 1ebabc4e20843e71c8f65d749934e496cf92b757 Mon Sep 17 00:00:00 2001 From: YanyanCheng <40185802+yanyanchengHydro@users.noreply.github.com> Date: Sat, 9 May 2020 16:53:01 -0700 Subject: [PATCH 49/75] Update doc/source/tech_note/Vegetation_Phenology_Turnover/CLM50_Tech_Note_Vegetation_Phenology_Turnover.rst Co-authored-by: Danica Lombardozzi --- .../CLM50_Tech_Note_Vegetation_Phenology_Turnover.rst | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/doc/source/tech_note/Vegetation_Phenology_Turnover/CLM50_Tech_Note_Vegetation_Phenology_Turnover.rst b/doc/source/tech_note/Vegetation_Phenology_Turnover/CLM50_Tech_Note_Vegetation_Phenology_Turnover.rst index 023344cbe6..0b06295c43 100644 --- a/doc/source/tech_note/Vegetation_Phenology_Turnover/CLM50_Tech_Note_Vegetation_Phenology_Turnover.rst +++ b/doc/source/tech_note/Vegetation_Phenology_Turnover/CLM50_Tech_Note_Vegetation_Phenology_Turnover.rst @@ -154,9 +154,8 @@ increasing litterfall rate throughout the offset period. The :math:`biofuel\_harvfrac` (:numref:`Table Plant functional type (PFT) parameters for harvested fraction of leaf/livestem for bioenergy crops`) is the harvested fraction of aboveground biomass (leaf & livestem) for bioenergy crops. It is only non-zero for prognostic crops. The special case for fluxes in the final litterfall timestep -(:math:`{t}_{offset}` = :math:`\Delta t`\ ) ensures that a fraction (:math:`1-biofuel\_harvfrac`) of the -displayed growth is sent to the litter pools for deciduous plant types, while the remaining fraction (:math:`biofuel\_harvfrac`) -of leaf biomass goes to the biofuel feedstock pools (Equation :eq:`25.9`). Modifications on livestem carbon pools for prognostic crops +(:math:`{t}_{offset}` = :math:`\Delta t`\ ) ensures that all of the displayed growth is sent to the litter pools or biofuel feedstock pools. The fraction (:math:`biofuel\_harvfrac`) of leaf biomass going to the biofuel feedstock pools (Equation :eq:`25.9`) is defined in Table 26.3 and is only non-zero for prognostic crops. The remaining fraction of leaf biomass (:math:`1-biofuel\_harvfrac`) for deciduous plant types is sent to the litter pools. +Similar modifications made for livestem carbon pools for prognostic crops can be found in section :numref:`Harvest to food and seed` in Equations :eq:`25.9`-:eq:`25.14`. Corresponding nitrogen fluxes during litterfall take into account retranslocation of nitrogen out of the displayed leaf pool prior to @@ -873,4 +872,3 @@ fractions used for carbon fluxes: :label: 20.97) NF_{froot,lit3} =\sum _{p=0}^{npfts}NF_{froot,litter} f_{lig\_ froot,p} wcol_{p} . - From 9f73dfb180fff874238996cb069aaeff0c90ca8a Mon Sep 17 00:00:00 2001 From: YanyanCheng <40185802+yanyanchengHydro@users.noreply.github.com> Date: Sat, 9 May 2020 16:55:24 -0700 Subject: [PATCH 50/75] Update doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst Co-authored-by: Danica Lombardozzi --- .../Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst b/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst index e4ec4e1ab2..ce3679f4b3 100644 --- a/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst +++ b/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst @@ -128,7 +128,7 @@ Plantation areas of bioenergy crops are projected to expand throughout the 21st replace fossil fuels and mitigate climate change. Miscanthus and switchgrass are perennial bioenergy crops and have quite different physiological traits and land management practices than annual crops, such as longer growing seasons, higher productivity, and lower demands for nutrients and water. -About 70% of biofuel aboveground biomass (leaf & livestem) is removed at harvest for biofuels. Parameter values were developed by using +About 70% of biofuel aboveground biomass (leaf & livestem) is removed at harvest. Parameter values were developed by using observation data collected at the University of Illinois Energy Farm located in Central Midwestern United States (:ref:`Cheng et al., 2019`). @@ -945,4 +945,3 @@ river water storage is maintained above a specified threshold. temperate cereals (wheat, barley, and rye) (:ref:`Portmann et al. 2010 `), available online from *ftp://ftp.rz.uni-frankfurt.de/pub/uni-frankfurt/physische\_geographie/hydrologie/public/data/MIRCA2000/harvested\_area\_grids.* - From 4f40771108b0fff1e76762abf357b50dcc6b55e7 Mon Sep 17 00:00:00 2001 From: YanyanCheng <40185802+yanyanchengHydro@users.noreply.github.com> Date: Sat, 9 May 2020 16:55:56 -0700 Subject: [PATCH 51/75] Update doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst Co-authored-by: Danica Lombardozzi --- .../Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst b/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst index ce3679f4b3..10c51d31a6 100644 --- a/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst +++ b/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst @@ -366,7 +366,7 @@ Harvest occurs in one time step using the BGC leaf offset algorithm. .. table:: Crop phenology and morphology parameters for the active crop plant functional types (pfts) in CLM5BGCCROP. Numbers in the first row correspond to the list of pfts in :numref:`Table Crop plant functional types`. =================================== ========================= ========================== ========================== ========================== ========================== ========================= ========================= ========================== ========================== ========================== - \ temperate corn spring wheat temperatue soybean cotton rice sugarcane tropical corn tropical soybean miscanthus switchgrass + \ temperate corn spring wheat temperate soybean cotton rice sugarcane tropical corn tropical soybean miscanthus switchgrass =================================== ========================= ========================== ========================== ========================== ========================== ========================= ========================= ========================== ========================== ========================== IVT 17, 18 19, 20 23, 24 41, 42 61, 62 67, 68 75, 76 77, 78 71, 72 73, 74 :math:`Date_{planting}^{min}` April 1 April 1 May 1 April 1 Janurary 1 Janurary 1 March 20 April 15 April 1 April 1 From 7e31b643fe7ac8ce300e2ac19fbe5bc875539796 Mon Sep 17 00:00:00 2001 From: YanyanCheng <40185802+yanyanchengHydro@users.noreply.github.com> Date: Sat, 9 May 2020 16:56:31 -0700 Subject: [PATCH 52/75] Update doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst Co-authored-by: Danica Lombardozzi --- .../Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst b/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst index 10c51d31a6..9809f9ec82 100644 --- a/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst +++ b/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst @@ -559,7 +559,7 @@ A fraction (determined by :math:`biofuel\_harvfrac`) of leaf/livestem C and N fr with the remaining portions going to the litter pools (Equations :eq:`20.14)`, :eq:`25.11`, and :eq:`25.14`). Putting live stem C and N into the litter and biofuel pools is in contrast to the approach for unmanaged PFTs which puts live stem C and N into dead stem pools first. -Leaf C and N pools are routed to the little and biofuel pools, contrast to that of unmanaged PFTs which put leaf C and N to litter pools only. +Leaf C and N pools are routed to the litter and biofuel pools, in contrast to that of unmanaged PFTs and non-biofuel crops, which put leaf C and N into litter pools only. Root C and N pools are routed to the litter pools in the same manner as natural vegetation. .. math:: From 9977b0a3ccd2608fc9daafede0b0137d18da19d6 Mon Sep 17 00:00:00 2001 From: YanyanCheng <40185802+yanyanchengHydro@users.noreply.github.com> Date: Sat, 9 May 2020 16:56:57 -0700 Subject: [PATCH 53/75] Update doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst Co-authored-by: Danica Lombardozzi --- .../Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst b/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst index 9809f9ec82..6b6e8c8b33 100644 --- a/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst +++ b/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst @@ -554,7 +554,7 @@ Harvest '''''''''''''''''''''''''''''' Variables track the flow of grain C and N to food and of all other plant pools, including live stem C and N, to litter, and to biofuel feedstock. -A fraction (determined by :math:`biofuel\_harvfrac`) of leaf/livestem C and N from bioenergy crops is removed at harvest for biofuels +A fraction (determined by the :math:`biofuel\_harvfrac`, defined in Table 26.3) of leaf/livestem C and N from bioenergy crops is removed at harvest for biofuels (Equations :eq:`25.9`, :eq:`25.10`, :eq:`25.12`, and :eq:`25.13`), with the remaining portions going to the litter pools (Equations :eq:`20.14)`, :eq:`25.11`, and :eq:`25.14`). Putting live stem C and N into the litter and biofuel pools is in contrast to the approach for unmanaged PFTs which From 5d2106f4ecbda23fb529d0687ffee00d306b8f61 Mon Sep 17 00:00:00 2001 From: YanyanCheng <40185802+yanyanchengHydro@users.noreply.github.com> Date: Sat, 9 May 2020 16:57:33 -0700 Subject: [PATCH 54/75] Update doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst Co-authored-by: Danica Lombardozzi --- .../Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst b/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst index 6b6e8c8b33..e214a6e8a6 100644 --- a/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst +++ b/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst @@ -662,7 +662,7 @@ NS is stored nitrogen, and :math:`biofuel\_harvfrac` is the harvested fraction o Whereas food C and N was formerly transferred to the litter pool, CLM5 routes food C and N to a grain product pool where the C and N decay to the atmosphere over one year, similar in structure to the wood product pools. -The biofuel C and N is also routed to the grain product pool and decay to the atmosphere over one year. +The biofuel C and N is also routed to the grain product pool and decays to the atmosphere over one year. Additionally, CLM5 accounts for the C and N required for crop seeding by removing the seed C and N from the grain product pool during harvest. The crop seed pool is then used to seed crops in the subsequent year. Calcuating the crop yields (Equation :eq:`25.15`) requires that you sum the GRAINC_TO_FOOD variable From 26293d117b146f22630392b569aad3283c77ba75 Mon Sep 17 00:00:00 2001 From: YanyanCheng <40185802+yanyanchengHydro@users.noreply.github.com> Date: Sat, 9 May 2020 16:57:51 -0700 Subject: [PATCH 55/75] Update doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst Co-authored-by: Danica Lombardozzi --- .../Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst b/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst index e214a6e8a6..6a476e72f9 100644 --- a/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst +++ b/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst @@ -682,7 +682,7 @@ efficiency of 85%. .. table:: Crop allocation parameters for the active crop plant functional types (pfts) in CLM5BGCCROP. Numbers in the first row correspond to the list of pfts in :numref:`Table Crop plant functional types`. =========================================== ============== ============ ================== ====== ====== ========= ============= ================ ================ ================ - \ temperate corn spring wheat temperatue soybean cotton rice sugarcane tropical corn tropical soybean miscanthus switchgrass + \ temperate corn spring wheat temperate soybean cotton rice sugarcane tropical corn tropical soybean miscanthus switchgrass =========================================== ============== ============ ================== ====== ====== ========= ============= ================ ================ ================ IVT 17, 18 19, 20 23, 24 41, 42 61, 62 67, 68 75, 76 77, 78 71, 72 73, 74 :math:`a_{leaf}^{i}` 0.6 0.9 0.85 0.85 0.75 0.6 0.6 0.85 0.9 0.7 From ed0489c8c0e8097518de945cb2ba5d4c61dc49d8 Mon Sep 17 00:00:00 2001 From: YanyanCheng <40185802+yanyanchengHydro@users.noreply.github.com> Date: Sat, 9 May 2020 16:58:11 -0700 Subject: [PATCH 56/75] Update doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst Co-authored-by: Danica Lombardozzi --- .../Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst b/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst index 6a476e72f9..2d9f4c4679 100644 --- a/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst +++ b/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst @@ -758,8 +758,8 @@ The values for both of these fields come from the LUMIP time series for each yea In addition to the industrial fertilizer, background manure fertilizer is specified on the parameter file by the field 'manunitro'. For perennial bioenergy crops, little fertilizer (56kg/ha/yr) is applied to switchgrass, no fertilizer is applied to Miscanthus. -Note this set up is only based on local land management practice at the University of Illinois Energy Farm -located in Central Midwestern United States :ref:`(Cheng et al., 2019)`. For the current CLM5BGCCROP, +Note these rates only based on local land management practice at the University of Illinois Energy Farm +located in Central Midwestern United States :ref:`(Cheng et al., 2019)` rather than the LUMIP timeseries. For the current CLM5BGCCROP, manure N is applied at a rate of 0.002 kg N/m\ :sup:`2`/yr. Because previous versions of CLM (e.g., CLM4) had rapid denitrification rates, fertilizer is applied slowly to minimize N loss (primarily through denitrification) and maximize plant uptake. From d30cb5d49d159b714b8fcf8fa835fb6643991768 Mon Sep 17 00:00:00 2001 From: YanyanCheng <40185802+yanyanchengHydro@users.noreply.github.com> Date: Sat, 9 May 2020 16:58:29 -0700 Subject: [PATCH 57/75] Update doc/source/tech_note/Introduction/CLM50_Tech_Note_Introduction.rst Co-authored-by: Danica Lombardozzi --- .../tech_note/Introduction/CLM50_Tech_Note_Introduction.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/tech_note/Introduction/CLM50_Tech_Note_Introduction.rst b/doc/source/tech_note/Introduction/CLM50_Tech_Note_Introduction.rst index 5969e4a2d1..face74629b 100644 --- a/doc/source/tech_note/Introduction/CLM50_Tech_Note_Introduction.rst +++ b/doc/source/tech_note/Introduction/CLM50_Tech_Note_Introduction.rst @@ -528,7 +528,7 @@ Representation of human management of the land (agriculture, wood harvest) is au The CLM4.5 crop model is extended to operate globally through the addition of rice, sugarcane, tropical varieties of corn and soybean :ref:`(Badger and Dirmeyer, 2015` and :ref:`Levis et al., 2016)`, and perennial bioenergy crops :ref:`(Cheng et al., 2019)`. -These crop types are added to the existing temperate corn, temperature soybean, spring wheat, and cotton crop types. +These crop types are added to the existing temperate corn, temperate soybean, spring wheat, and cotton crop types. Fertilization rates and irrigation equipped area updated annually based on crop type and geographic region through an input dataset. The irrigation trigger is updated. Additional minor changes include crop phenological triggers that vary by latitude for selected crop types, grain C and N is now removed at harvest to a 1-year product pool with From 7c315ad9e0636005b067bf7acc7270764e0fef74 Mon Sep 17 00:00:00 2001 From: yanyanchengHydro Date: Sat, 9 May 2020 16:59:30 -0700 Subject: [PATCH 58/75] modify Vegetation_Phenology_Turnover --- .../CLM50_Tech_Note_Vegetation_Phenology_Turnover.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/source/tech_note/Vegetation_Phenology_Turnover/CLM50_Tech_Note_Vegetation_Phenology_Turnover.rst b/doc/source/tech_note/Vegetation_Phenology_Turnover/CLM50_Tech_Note_Vegetation_Phenology_Turnover.rst index 023344cbe6..4480dbec6e 100644 --- a/doc/source/tech_note/Vegetation_Phenology_Turnover/CLM50_Tech_Note_Vegetation_Phenology_Turnover.rst +++ b/doc/source/tech_note/Vegetation_Phenology_Turnover/CLM50_Tech_Note_Vegetation_Phenology_Turnover.rst @@ -151,8 +151,8 @@ periods as: where superscripts *n* and *n-1* refer to fluxes on the current and previous timesteps, respectively. The rate coefficient :math:`{r}_{xfer\_off}` varies with time to produce a linearly increasing litterfall rate throughout the offset period. -The :math:`biofuel\_harvfrac` (:numref:`Table Plant functional type (PFT) parameters for harvested fraction of leaf/livestem for bioenergy crops`) -is the harvested fraction of aboveground biomass (leaf & livestem) for bioenergy crops. It is only non-zero for prognostic crops. +The :math:`biofuel\_harvfrac` (:numref:`Table Plant functional type (PFT) parameters for harvested fraction of leaf/livestem for bioenergy production`) +is the harvested fraction of aboveground biomass (leaf & livestem) for bioenergy crops. The special case for fluxes in the final litterfall timestep (:math:`{t}_{offset}` = :math:`\Delta t`\ ) ensures that a fraction (:math:`1-biofuel\_harvfrac`) of the displayed growth is sent to the litter pools for deciduous plant types, while the remaining fraction (:math:`biofuel\_harvfrac`) From 1df2dd5dcfc3882cc481225136fc535283343b8b Mon Sep 17 00:00:00 2001 From: yanyanchengHydro Date: Sat, 9 May 2020 18:26:14 -0700 Subject: [PATCH 59/75] update tech note --- .../Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst b/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst index 2d9f4c4679..6b6a40b259 100644 --- a/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst +++ b/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst @@ -366,7 +366,7 @@ Harvest occurs in one time step using the BGC leaf offset algorithm. .. table:: Crop phenology and morphology parameters for the active crop plant functional types (pfts) in CLM5BGCCROP. Numbers in the first row correspond to the list of pfts in :numref:`Table Crop plant functional types`. =================================== ========================= ========================== ========================== ========================== ========================== ========================= ========================= ========================== ========================== ========================== - \ temperate corn spring wheat temperate soybean cotton rice sugarcane tropical corn tropical soybean miscanthus switchgrass + \ temperate corn spring wheat temperate soybean cotton rice sugarcane tropical corn tropical soybean miscanthus switchgrass =================================== ========================= ========================== ========================== ========================== ========================== ========================= ========================= ========================== ========================== ========================== IVT 17, 18 19, 20 23, 24 41, 42 61, 62 67, 68 75, 76 77, 78 71, 72 73, 74 :math:`Date_{planting}^{min}` April 1 April 1 May 1 April 1 Janurary 1 Janurary 1 March 20 April 15 April 1 April 1 @@ -554,7 +554,8 @@ Harvest '''''''''''''''''''''''''''''' Variables track the flow of grain C and N to food and of all other plant pools, including live stem C and N, to litter, and to biofuel feedstock. -A fraction (determined by the :math:`biofuel\_harvfrac`, defined in Table 26.3) of leaf/livestem C and N from bioenergy crops is removed at harvest for biofuels +A fraction (determined by the :math:`biofuel\_harvfrac`, defined in +:numref:`Table Plant functional type (PFT) parameters for harvested fraction of leaf/livestem for bioenergy production`) of leaf/livestem C and N from bioenergy crops is removed at harvest for biofuels (Equations :eq:`25.9`, :eq:`25.10`, :eq:`25.12`, and :eq:`25.13`), with the remaining portions going to the litter pools (Equations :eq:`20.14)`, :eq:`25.11`, and :eq:`25.14`). Putting live stem C and N into the litter and biofuel pools is in contrast to the approach for unmanaged PFTs which @@ -682,7 +683,7 @@ efficiency of 85%. .. table:: Crop allocation parameters for the active crop plant functional types (pfts) in CLM5BGCCROP. Numbers in the first row correspond to the list of pfts in :numref:`Table Crop plant functional types`. =========================================== ============== ============ ================== ====== ====== ========= ============= ================ ================ ================ - \ temperate corn spring wheat temperate soybean cotton rice sugarcane tropical corn tropical soybean miscanthus switchgrass + \ temperate corn spring wheat temperate soybean cotton rice sugarcane tropical corn tropical soybean miscanthus switchgrass =========================================== ============== ============ ================== ====== ====== ========= ============= ================ ================ ================ IVT 17, 18 19, 20 23, 24 41, 42 61, 62 67, 68 75, 76 77, 78 71, 72 73, 74 :math:`a_{leaf}^{i}` 0.6 0.9 0.85 0.85 0.75 0.6 0.6 0.85 0.9 0.7 @@ -719,7 +720,7 @@ Physical Crop Characteristics '''''''''''''''''''''''''''''' Leaf area index (*L*) is calculated as a function of specific leaf area (SLA, :numref:`Table Crop phenology parameters`) and leaf C. -Stem area index (*S*) is equal to 0.1\ *L* for temperate and tropical corn and sugarcane and 0.2\ *L* for +Stem area index (*S*) is equal to 0.1\ *L* for temperate and tropical corn, sugarcane, and perennial bioenergy crops and 0.2\ *L* for other crops, as in AgroIBIS. All live C and N pools go to 0 after crop harvest, but the *S* is kept at 0.25 to simulate a post-harvest “stubble” on the ground. From 6100ac1f7124b832a774346922d578a1a0bf90cd Mon Sep 17 00:00:00 2001 From: yanyanchengHydro Date: Mon, 11 May 2020 11:00:07 -0700 Subject: [PATCH 60/75] update tech note --- .../Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst b/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst index 6b6a40b259..c6d55a2fc0 100644 --- a/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst +++ b/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst @@ -720,7 +720,7 @@ Physical Crop Characteristics '''''''''''''''''''''''''''''' Leaf area index (*L*) is calculated as a function of specific leaf area (SLA, :numref:`Table Crop phenology parameters`) and leaf C. -Stem area index (*S*) is equal to 0.1\ *L* for temperate and tropical corn, sugarcane, and perennial bioenergy crops and 0.2\ *L* for +Stem area index (*S*) is equal to 0.1\ *L* for temperate and tropical corn, sugarcane, switchgrass, and miscanthus and 0.2\ *L* for other crops, as in AgroIBIS. All live C and N pools go to 0 after crop harvest, but the *S* is kept at 0.25 to simulate a post-harvest “stubble” on the ground. From 99f1b6e10b60f89875b8240d0829485b3413015d Mon Sep 17 00:00:00 2001 From: yanyanchengHydro Date: Thu, 14 May 2020 14:37:08 -0700 Subject: [PATCH 61/75] update tech note --- .../Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst b/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst index c6d55a2fc0..6fb9da4c55 100644 --- a/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst +++ b/doc/source/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.rst @@ -560,7 +560,7 @@ A fraction (determined by the :math:`biofuel\_harvfrac`, defined in with the remaining portions going to the litter pools (Equations :eq:`20.14)`, :eq:`25.11`, and :eq:`25.14`). Putting live stem C and N into the litter and biofuel pools is in contrast to the approach for unmanaged PFTs which puts live stem C and N into dead stem pools first. -Leaf C and N pools are routed to the litter and biofuel pools, in contrast to that of unmanaged PFTs and non-biofuel crops, which put leaf C and N into litter pools only. +Biofuel crop leaf C and N pools are routed to the litter and biofuel pools, in contrast to that of unmanaged PFTs and non-biofuel crops, which put leaf C and N into litter pools only. Root C and N pools are routed to the litter pools in the same manner as natural vegetation. .. math:: @@ -759,7 +759,7 @@ The values for both of these fields come from the LUMIP time series for each yea In addition to the industrial fertilizer, background manure fertilizer is specified on the parameter file by the field 'manunitro'. For perennial bioenergy crops, little fertilizer (56kg/ha/yr) is applied to switchgrass, no fertilizer is applied to Miscanthus. -Note these rates only based on local land management practice at the University of Illinois Energy Farm +Note these rates are only based on local land management practices at the University of Illinois Energy Farm located in Central Midwestern United States :ref:`(Cheng et al., 2019)` rather than the LUMIP timeseries. For the current CLM5BGCCROP, manure N is applied at a rate of 0.002 kg N/m\ :sup:`2`/yr. Because previous versions of CLM (e.g., CLM4) had rapid denitrification rates, fertilizer is applied slowly From 7562b5e1f8690328197ec81caea81cc49805ec00 Mon Sep 17 00:00:00 2001 From: Bill Sacks Date: Mon, 18 May 2020 16:31:20 -0600 Subject: [PATCH 62/75] Fix indentation --- src/biogeochem/CNCStateUpdate1Mod.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/biogeochem/CNCStateUpdate1Mod.F90 b/src/biogeochem/CNCStateUpdate1Mod.F90 index 047233a9d2..c5a717f2bc 100644 --- a/src/biogeochem/CNCStateUpdate1Mod.F90 +++ b/src/biogeochem/CNCStateUpdate1Mod.F90 @@ -287,8 +287,8 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, & end if if (ivt(p) >= npcropmin) then ! skip 2 generic crops cs_veg%livestemc_patch(p) = cs_veg%livestemc_patch(p) - cf_veg%livestemc_to_litter_patch(p)*dt - cs_veg%livestemc_patch(p) = cs_veg%livestemc_patch(p) - cf_veg%livestemc_to_biofuelc_patch(p)*dt - cs_veg%leafc_patch(p) = cs_veg%leafc_patch(p) - cf_veg%leafc_to_biofuelc_patch(p)*dt + cs_veg%livestemc_patch(p) = cs_veg%livestemc_patch(p) - cf_veg%livestemc_to_biofuelc_patch(p)*dt + cs_veg%leafc_patch(p) = cs_veg%leafc_patch(p) - cf_veg%leafc_to_biofuelc_patch(p)*dt cs_veg%grainc_patch(p) = cs_veg%grainc_patch(p) & - (cf_veg%grainc_to_food_patch(p) + cf_veg%grainc_to_seed_patch(p))*dt cs_veg%cropseedc_deficit_patch(p) = cs_veg%cropseedc_deficit_patch(p) & From 6f3537e4f770cbb66b1e9c0e398525163a26847f Mon Sep 17 00:00:00 2001 From: Bill Sacks Date: Tue, 19 May 2020 14:56:23 -0600 Subject: [PATCH 63/75] Point to new parameter files For clm5.0, this new file adds a biofuel_harvfrac variable and adds parameters for crop types switchgrass and miscanthus. For clm4.5, this just adds a biofuel_harvfrac variable: switchgrass and miscanthus are not enabled for clm4.5. --- bld/namelist_files/namelist_defaults_ctsm.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index 2752f17214..26be99134e 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -393,8 +393,8 @@ attributes from the config_cache.xml file (with keys converted to upper-case). -lnd/clm2/paramdata/clm5_params.c200402.nc -lnd/clm2/paramdata/clm_params.c200402.nc +lnd/clm2/paramdata/clm5_params.c200519.nc +lnd/clm2/paramdata/clm_params.c200519.nc From 3d3cb0e5948d577b7e8331f29790c3bcc7aec987 Mon Sep 17 00:00:00 2001 From: Bill Sacks Date: Wed, 20 May 2020 14:01:32 -0600 Subject: [PATCH 64/75] Reword a comment --- src/main/pftconMod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/pftconMod.F90 b/src/main/pftconMod.F90 index 1fe80a9d31..86b6846031 100644 --- a/src/main/pftconMod.F90 +++ b/src/main/pftconMod.F90 @@ -134,7 +134,7 @@ module pftconMod real(r8), allocatable :: slatop (:) ! SLA at top of canopy [m^2/gC] real(r8), allocatable :: dsladlai (:) ! dSLA/dLAI [m^2/gC] real(r8), allocatable :: leafcn (:) ! leaf C:N [gC/gN] - real(r8), allocatable :: biofuel_harvfrac (:) ! cut a fraction of stem/leaf for biofuel [-] + real(r8), allocatable :: biofuel_harvfrac (:) ! fraction of stem and leaf cut for harvest, sent to biofuels [unitless] real(r8), allocatable :: flnr (:) ! fraction of leaf N in Rubisco [no units] real(r8), allocatable :: woody (:) ! woody lifeform flag (0 or 1) real(r8), allocatable :: lflitcn (:) ! leaf litter C:N (gC/gN) From 4ca0f3164132bc65e496c0746d40b358ec7d667c Mon Sep 17 00:00:00 2001 From: Bill Sacks Date: Wed, 20 May 2020 14:08:10 -0600 Subject: [PATCH 65/75] Change some references to 'grain' to also mention 'biofuel' --- src/biogeochem/CNProductsMod.F90 | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/biogeochem/CNProductsMod.F90 b/src/biogeochem/CNProductsMod.F90 index 0661c3b392..dc216b0529 100644 --- a/src/biogeochem/CNProductsMod.F90 +++ b/src/biogeochem/CNProductsMod.F90 @@ -33,7 +33,7 @@ module CNProductsMod class(species_base_type), allocatable :: species ! C, N, C13, C14, etc. ! States - real(r8), pointer :: cropprod1_grc(:) ! (g[C or N]/m2) grain product pool, 1-year lifespan + real(r8), pointer :: cropprod1_grc(:) ! (g[C or N]/m2) crop product pool (grain + biofuel), 1-year lifespan real(r8), pointer :: prod10_grc(:) ! (g[C or N]/m2) wood product pool, 10-year lifespan real(r8), pointer :: prod100_grc(:) ! (g[C or N]/m2) wood product pool, 100-year lifespan real(r8), pointer :: tot_woodprod_grc(:) ! (g[C or N]/m2) total wood product pool @@ -51,7 +51,7 @@ module CNProductsMod real(r8), pointer :: grain_to_cropprod1_grc(:) ! (g[C or N]/m2/s) grain to 1-year crop product pool ! Fluxes: losses - real(r8), pointer :: cropprod1_loss_grc(:) ! (g[C or N]/m2/s) decomposition loss from 1-yr grain product pool + real(r8), pointer :: cropprod1_loss_grc(:) ! (g[C or N]/m2/s) decomposition loss from 1-yr crop product pool real(r8), pointer :: prod10_loss_grc(:) ! (g[C or N]/m2/s) decomposition loss from 10-yr wood product pool real(r8), pointer :: prod100_loss_grc(:) ! (g[C or N]/m2/s) decomposition loss from 100-yr wood product pool real(r8), pointer :: tot_woodprod_loss_grc(:) ! (g[C or N]/m2/s) decompomposition loss from all wood product pools @@ -181,7 +181,7 @@ subroutine InitHistory(this, bounds) fname = this%species%hist_fname('CROPPROD1'), & units = 'g' // this%species%get_species() // '/m^2', & avgflag = 'A', & - long_name = '1-yr grain product ' // this%species%get_species(), & + long_name = '1-yr crop product (grain+biofuel) ' // this%species%get_species(), & ptr_gcell = this%cropprod1_grc, default=active_if_non_isotope) this%prod10_grc(begg:endg) = spval @@ -245,7 +245,7 @@ subroutine InitHistory(this, bounds) fname = this%species%hist_fname('CROPPROD1', suffix='_LOSS'), & units = 'g' // this%species%get_species() // '/m^2/s', & avgflag = 'A', & - long_name = 'loss from 1-yr grain product pool', & + long_name = 'loss from 1-yr crop product pool', & ptr_gcell = this%cropprod1_loss_grc, default=active_if_non_isotope) this%prod10_loss_grc(begg:endg) = spval @@ -506,17 +506,17 @@ subroutine UpdateProducts(this, bounds, & ! update product state variables do g = bounds%begg, bounds%endg - ! fluxes into wood & grain product pools, from landcover change + ! fluxes into wood & crop product pools, from landcover change this%cropprod1_grc(g) = this%cropprod1_grc(g) + this%dwt_cropprod1_gain_grc(g)*dt 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 harvest + ! fluxes into wood & crop 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 this%prod100_grc(g) = this%prod100_grc(g) + this%hrv_deadstem_to_prod100_grc(g)*dt - ! fluxes out of wood & grain product pools, from decomposition + ! fluxes out of wood & crop product pools, from decomposition this%cropprod1_grc(g) = this%cropprod1_grc(g) - this%cropprod1_loss_grc(g)*dt this%prod10_grc(g) = this%prod10_grc(g) - this%prod10_loss_grc(g)*dt this%prod100_grc(g) = this%prod100_grc(g) - this%prod100_loss_grc(g)*dt From 40927b6c0d3c9cdf280633f6619d26c0cf239f91 Mon Sep 17 00:00:00 2001 From: Bill Sacks Date: Wed, 20 May 2020 14:17:35 -0600 Subject: [PATCH 66/75] Ensure that biofuel_harvfrac is only > 0 for prognostic crops --- src/main/pftconMod.F90 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/pftconMod.F90 b/src/main/pftconMod.F90 index 86b6846031..9b7eefa51b 100644 --- a/src/main/pftconMod.F90 +++ b/src/main/pftconMod.F90 @@ -1177,6 +1177,10 @@ subroutine InitRead(this) if ( this%pprodharv10(i) > 1.0_r8 .or. this%pprodharv10(i) < 0.0_r8 )then call endrun(msg=' ERROR: pprodharv10 outside of range.'//errMsg(sourcefile, __LINE__)) end if + if (i < npcropmin .and. this%biofuel_harvfrac(i) /= 0._r8) then + call endrun(msg=' ERROR: biofuel_harvfrac non-zero for a non-prognostic crop PFT.'//& + errMsg(sourcefile, __LINE__)) + end if end do end if From bb3f8e82927bc156fbb0e9ffcc6d65ee533fc4fa Mon Sep 17 00:00:00 2001 From: Bill Sacks Date: Wed, 20 May 2020 17:02:43 -0600 Subject: [PATCH 67/75] Change issue associated with smallville test failure I think it's really ESCOMP/CTSM#203 that's causing this failure, not ESCOMP/CTSM#158. --- cime_config/testdefs/ExpectedTestFails.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cime_config/testdefs/ExpectedTestFails.xml b/cime_config/testdefs/ExpectedTestFails.xml index 4b9b0ca8b0..a51b26d31c 100644 --- a/cime_config/testdefs/ExpectedTestFails.xml +++ b/cime_config/testdefs/ExpectedTestFails.xml @@ -33,7 +33,7 @@ FAIL - #158 + #203 From 633be0ebb88e649218f0d6fd15b9dc380334048c Mon Sep 17 00:00:00 2001 From: Bill Sacks Date: Wed, 20 May 2020 17:09:29 -0600 Subject: [PATCH 68/75] Initialize harvest variables to 0 when using all_veg I'm hopeful that this will address ESCOMP/CTSM#203 --- tools/mksurfdata_map/src/mksurfdat.F90 | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tools/mksurfdata_map/src/mksurfdat.F90 b/tools/mksurfdata_map/src/mksurfdat.F90 index acba4e8719..236740282c 100644 --- a/tools/mksurfdata_map/src/mksurfdat.F90 +++ b/tools/mksurfdata_map/src/mksurfdat.F90 @@ -93,6 +93,7 @@ program mksurfdat type(pct_pft_type), allocatable :: pctnatpft_max(:) ! % of grid cell maximum PFTs of the time series type(pct_pft_type), allocatable :: pctcft(:) ! % of grid cell that is crop, and breakdown into CFTs type(pct_pft_type), allocatable :: pctcft_max(:) ! % of grid cell maximum CFTs of the time series + real(r8) :: harvest_initval ! initial value for harvest variables real(r8), pointer :: harvest1D(:) ! harvest 1D data: normalized harvesting real(r8), pointer :: harvest2D(:,:) ! harvest 1D data: normalized harvesting real(r8), allocatable :: pctgla(:) ! percent of grid cell that is glacier @@ -568,7 +569,14 @@ program mksurfdat ndiag=ndiag, pctlnd_o=pctlnd_pft, pctnatpft_o=pctnatpft, pctcft_o=pctcft) ! Create harvesting data at model resolution - call mkharvest_init( ns_o, spval, harvdata, mksrf_fhrvtyp ) + if (all_veg) then + ! In this case, we don't call mkharvest, so we want the harvest variables to be + ! initialized reasonably. + harvest_initval = 0._r8 + else + harvest_initval = spval + end if + call mkharvest_init( ns_o, harvest_initval, harvdata, mksrf_fhrvtyp ) if ( .not. all_veg )then call mkharvest( ldomain, mapfname=map_fharvest, datfname=mksrf_fhrvtyp, & From d4cf60f7780bac1e18d68f4d4f6480786ac695d4 Mon Sep 17 00:00:00 2001 From: Bill Sacks Date: Thu, 21 May 2020 11:47:42 -0600 Subject: [PATCH 69/75] Point to new smallville year-2000 surface dataset Generated from this branch by running: make -f Makefile.data crop-smallville after first building mksurfdata_map using an environment loaded from a recent cheyenne_intel case. --- bld/namelist_files/namelist_defaults_ctsm.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index 2752f17214..08101357f3 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -781,7 +781,7 @@ lnd/clm2/surfdata_map/release-clm5.0.18/surfdata_4x5_hist_78pfts_CMIP6_simyr2000 lnd/clm2/surfdata_map/release-clm5.0.18/surfdata_1x1_numaIA_hist_78pfts_CMIP6_simyr2000_c190214.nc -lnd/clm2/surfdata_map/release-clm5.0.18/surfdata_1x1_smallvilleIA_hist_78pfts_CMIP6_simyr2000_c190214.nc +lnd/clm2/surfdata_map/ctsm1.0.dev094-2-g633be0eb/surfdata_1x1_smallvilleIA_hist_78pfts_CMIP6_simyr2000_c200521.nc lnd/clm2/surfdata_map/release-clm5.0.18/surfdata_ne30np4_hist_78pfts_CMIP6_simyr2000_c190303.nc From d112f2e89f42d6309c6eb1a343d8413a49e88085 Mon Sep 17 00:00:00 2001 From: Bill Sacks Date: Thu, 21 May 2020 12:09:37 -0600 Subject: [PATCH 70/75] Remove the cropColdStart testmods dir It was identical to coldStart --- cime_config/testdefs/testlist_clm.xml | 2 +- .../testdefs/testmods_dirs/clm/cropColdStart/include_user_mods | 1 - .../testdefs/testmods_dirs/clm/cropColdStart/shell_commands | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) delete mode 100644 cime_config/testdefs/testmods_dirs/clm/cropColdStart/include_user_mods delete mode 100755 cime_config/testdefs/testmods_dirs/clm/cropColdStart/shell_commands diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index d8e5bf02ff..8c8b8ad69c 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -348,7 +348,7 @@ - + diff --git a/cime_config/testdefs/testmods_dirs/clm/cropColdStart/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/cropColdStart/include_user_mods deleted file mode 100644 index fe0e18cf88..0000000000 --- a/cime_config/testdefs/testmods_dirs/clm/cropColdStart/include_user_mods +++ /dev/null @@ -1 +0,0 @@ -../default diff --git a/cime_config/testdefs/testmods_dirs/clm/cropColdStart/shell_commands b/cime_config/testdefs/testmods_dirs/clm/cropColdStart/shell_commands deleted file mode 100755 index 2a9f09bd75..0000000000 --- a/cime_config/testdefs/testmods_dirs/clm/cropColdStart/shell_commands +++ /dev/null @@ -1 +0,0 @@ -./xmlchange CLM_FORCE_COLDSTART="on" From 8368f222ca6ac6d68494935fd22f8850c132f9bc Mon Sep 17 00:00:00 2001 From: Bill Sacks Date: Thu, 21 May 2020 13:01:44 -0600 Subject: [PATCH 71/75] Change smallville ERS_Lm20 test to be cold start This was the intent when I first created the test: The point of this test is to test crop restart shortly after cold start. It later accidentally turned into a test that used spun-up initial conditions (when we changed just about everything to use spun-up initial conditions); this commit restores it to being cold start. --- cime_config/testdefs/testlist_clm.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index 8c8b8ad69c..4ea50c52e2 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -905,13 +905,13 @@ - + - + From a83bddfb4e7d91f4141c7a59162afe243fece50e Mon Sep 17 00:00:00 2001 From: Bill Sacks Date: Thu, 21 May 2020 13:12:55 -0600 Subject: [PATCH 72/75] Add a test covering switchgrass & miscanthus I particularly want isotopes to be on for this test --- cime_config/testdefs/testlist_clm.xml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index 4ea50c52e2..58a7e4344c 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -914,6 +914,15 @@ + + + + + + + + + From 28dad0479297309b9ebeabbcb8e5be10a52c3013 Mon Sep 17 00:00:00 2001 From: Bill Sacks Date: Thu, 20 Feb 2020 16:01:19 -0700 Subject: [PATCH 73/75] Make gindex_ocn intent(inout) rather than intent(out) Although gindex_ocn could be intent(out), intel18.0.3 generates a runtime segmentation fault in runs that don't have this argument present when this is declared intent(out). (It works fine on intel 19.0.2 when declared as intent(out).) Resolves ESCOMP/ctsm#930 --- src/main/clm_initializeMod.F90 | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/clm_initializeMod.F90 b/src/main/clm_initializeMod.F90 index dc5e8f8d40..442a77c36b 100644 --- a/src/main/clm_initializeMod.F90 +++ b/src/main/clm_initializeMod.F90 @@ -63,7 +63,12 @@ subroutine initialize1(gindex_ocn) use UrbanParamsType , only: UrbanInput, IsSimpleBuildTemp ! ! !ARGUMENTS - integer, pointer, optional, intent(out) :: gindex_ocn(:) ! If present, this will hold the decomposition of ocean points (which is needed for the nuopc interface); note that this variable is allocated here, and is assumed to start unallocated + ! COMPILER_BUG(wjs, 2020-02-20, intel18.0.3) Although gindex_ocn could be + ! intent(out), intel18.0.3 generates a runtime segmentation fault in runs that don't + ! have this argument present when this is declared intent(out). (It works fine on + ! intel 19.0.2 when declared as intent(out).) See also + ! https://github.com/ESCOMP/CTSM/issues/930. + integer, pointer, optional, intent(inout) :: gindex_ocn(:) ! If present, this will hold the decomposition of ocean points (which is needed for the nuopc interface); note that this variable is allocated here, and is assumed to start unallocated ! ! !LOCAL VARIABLES: integer :: ier ! error status From 4665c9ce138402076362133986823c5cb2e8928c Mon Sep 17 00:00:00 2001 From: Bill Sacks Date: Sun, 24 May 2020 15:58:24 -0600 Subject: [PATCH 74/75] SSP test: only do symlink if needed Resolves ESCOMP/CTSM#1021 (at least, I think it will: I'm about to test it) --- cime_config/SystemTests/ssp.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/cime_config/SystemTests/ssp.py b/cime_config/SystemTests/ssp.py index 892128ba5e..26337d323d 100644 --- a/cime_config/SystemTests/ssp.py +++ b/cime_config/SystemTests/ssp.py @@ -83,7 +83,14 @@ def run_phase(self): rest_path = os.path.join(dout_sr, "rest", "{}-{}".format(refdate, refsec)) for item in glob.glob("{}/*{}*".format(rest_path, refdate)): - os.symlink(item, os.path.join(rundir, os.path.basename(item))) + link_name = os.path.join(rundir, os.path.basename(item)) + if os.path.islink(link_name) and os.readlink(link_name) == item: + # Link is already set up correctly: do nothing + # (os.symlink raises an exception if you try to replace an + # existing file) + pass + else: + os.symlink(item, link_name) for item in glob.glob("{}/*rpointer*".format(rest_path)): shutil.copy(item, rundir) From 0e3aa2b4c50d2b5e1754d517aa946c47d37cd9c1 Mon Sep 17 00:00:00 2001 From: Bill Sacks Date: Mon, 25 May 2020 15:44:37 -0600 Subject: [PATCH 75/75] Update ChangeLog --- doc/ChangeLog | 189 ++++++++++++++++++++++++++++++++++++++++++++++++++ doc/ChangeSum | 1 + 2 files changed, 190 insertions(+) diff --git a/doc/ChangeLog b/doc/ChangeLog index 469769ba28..ef1b03e5c9 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,4 +1,193 @@ =============================================================== +Tag name: ctsm1.0.dev097 +Originator(s): ycheng (Yanyan Cheng) +Date: Mon May 25 15:14:56 MDT 2020 +One-line Summary: Add two bioenergy crops (switchgrass and miscanthus) + +Purpose of changes +------------------ + +Main change is from Yanyan Cheng: adding parameters and code for two +bioenergy crops, switchgrass and miscanthus. Along with this, there is a +new potential flux from crop leaves and stems to the crop product pool +at harvest, representing biofuel products; a new pft-specific parameter +controls this flux (biofuel_harvfrac). Currently, the out-of-the-box +surface datasets do not specify any area for these crops, but the new +parameter file will allow them to be present if specified on the surface +dataset or landuse_timeseries file. Note that this is only an option for +CLM5.0, NOT for CLM4.5. (See https://github.com/ESCOMP/CTSM/pull/884 for +details.) + +Also, some minor fixes from Bill Sacks: See notes under "bugs fixed" +below. + +Bugs fixed or introduced +------------------------ + +Issues fixed (include CTSM Issue #): +- Resolves ESCOMP/CTSM#203 - Fixes creation of harvest-related variables + on surface datasets created with the all_veg option - smallville, + PTCLM, etc. (documented in https://github.com/ESCOMP/CTSM/pull/1019) +- Resolves ESCOMP/CTSM#930 - Makes gindex_ocn intent(inout) rather than + intent(out) +- Resolves ESCOMP/CTSM#1021 - Changes SSP test to only do symlink if + needed + +Significant changes to scientifically-supported configurations +-------------------------------------------------------------- + +Does this tag change answers significantly for any of the following physics configurations? +(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 changes.] + +[ ] clm5_0 + +[ ] ctsm5_0-nwp + +[ ] clm4_5 + +Notes of particular relevance for users +--------------------------------------- + +Caveats for users (e.g., need to interpolate initial conditions): +- For transient crop cases, now more crops in memory. This creates a + need for interpolation of initial conditions for initial conditions + generated from a transient case. + +Changes to CTSM's user interface (e.g., new/renamed XML or namelist variables): none + +Changes made to namelist defaults (e.g., changed parameter values): +- Changed parameter values for switchgrass and miscanthus (only for clm5.0) +- New pft-specific parameter, biofuel_harvfrac (for both clm4.5 and clm5.0) + +Changes to the datasets (e.g., parameter, surface or initial files): +- New parameter files with the above changes + +Substantial timing or memory changes: none + +Notes of particular relevance for developers: (including Code reviews and testing) +--------------------------------------------- +NOTE: Be sure to review the steps in README.CHECKLIST.master_tags as well as the coding style in the Developers Guide + +Caveats for developers (e.g., code that is duplicated that requires double maintenance): none + +Changes to tests or testing: +- Changed smallville ERS_Lm20 test to be cold start (see comment in + commit 8368f222 for details) +- Added a multi-year smallville test that includes these new crops + +Code reviewed by: Bill Sacks, Danica Lombardozzi + + +CTSM testing: + + [PASS means all tests PASS and OK means tests PASS other than expected fails.] + + build-namelist tests: + + cheyenne - not run + + tools-tests (test/tools): + + cheyenne - ok + + Pass except for expected baseline failures + + Ran on 633be0eb, with comparison against ctsm1.0.dev095; tests pass + except these expected baseline failures: + + 030 blf84 TBLscript_tools.sh PTCLM PTCLMmkdata PTCLM_USUMB_clm4_5^buildtools ....................\c + rc=7 FAIL + + 032 blfc4 TBLscript_tools.sh PTCLM PTCLMmkdata PTCLM_USUMB_Cycle_clm4_5^buildtools ..............\c + rc=7 FAIL + + Diffs for these are just in the harvest-related fields on the surface dataset, as expected. + + PTCLM testing (tools/shared/PTCLM/test): + + cheyenne - not run + + python testing (see instructions in python/README.md; document testing done): + + (any machine) - not run + + regular tests (aux_clm): + + cheyenne ---- ok + izumi ------- pass + + For cheyenne testing: a few tests had baseline failures. The + differences just arise in the h1 (vector) files, due to differences + in dimension sizes. These differences are expected. See below for + details. + + Ran most testing on 8309c213. Reran two SSP tests on 4665c9ce + +If the tag used for baseline comparisons was NOT the previous tag, note that here: + + +Answer changes +-------------- + +Changes answers relative to baseline: YES, but diagnostic only due to +change in dimension sizes - does not change answers in any meaningful +way + + If a tag changes answers relative to baseline comparison the + following should be filled in (otherwise remove this section): + + Summarize any changes to answers, i.e., + - what code configurations: Transient CLM50 cases with crops; just + changes dimensions on vector (h1) history files + - what platforms/compilers: All + - nature of change (roundoff; larger than roundoff/same climate; new climate): + diagnostic change only + + Differences were observed in the following tests: + + ERS_Ly3_Mmpi-serial.1x1_smallvilleIA.IHistClm50BgcCropQianGs.cheyenne_gnu.clm-cropMonthOutput + SMS_Ld5.f10_f10_musgs.ISSP245Clm50BgcCrop.cheyenne_gnu.clm-ciso_dec2050Start + SMS_Ld5.f10_f10_musgs.ISSP370Clm50BgcCrop.cheyenne_gnu.clm-ciso_dec2050Start + ERP_D_Ld10_P36x2.f10_f10_musgs.IHistClm50BgcCrop.cheyenne_intel.clm-ciso_decStart + ERP_D_Ld5.f10_f10_musgs.IHistClm50BgcCrop.cheyenne_intel.clm-allActive + ERP_Ly3_P72x2.f10_f10_musgs.IHistClm50BgcCrop.cheyenne_intel.clm-cropMonthOutput + ERS_D_Ld7_Mmpi-serial.1x1_smallvilleIA.IHistClm50BgcCropGs.cheyenne_intel.clm-decStart1851_noinitial + ERS_Ly3_P72x2.f10_f10_musgs.IHistClm50BgcCropG.cheyenne_intel.clm-cropMonthOutput + ERS_Ly5_P144x1.f10_f10_musgs.IHistClm50BgcCrop.cheyenne_intel.clm-cropMonthOutput + ERS_Ly6_Mmpi-serial.1x1_smallvilleIA.IHistClm50BgcCropQianGs.cheyenne_intel.clm-cropMonthOutput + LCISO_Lm13.f10_f10_musgs.IHistClm50BgcCrop.cheyenne_intel.clm-ciso_monthly + SMS_Ld5.f10_f10_musgs.ISSP585Clm50BgcCrop.cheyenne_intel.clm-ciso_dec2050Start + + The differences just arise in the h1 files, due to differences in + dimension sizes. I reran these tests with a paramfile where I + reverted the mergeToPft variable; then they were all bfb with + master. + + Other than this, there were FIELDLIST differences, as expected. + + If bitwise differences were observed, how did you show they were no worse + than roundoff? N/A + + If this tag changes climate describe the run(s) done to evaluate the new + climate (put details of the simulations in the experiment database) + - casename: N/A + + URL for LMWG diagnostics output used to validate new climate: N/A + + +Detailed list of changes +------------------------ + +List any externals directories updated (cime, rtm, mosart, cism, fates, etc.): none + +Pull Requests that document the changes (include PR ids): +- https://github.com/ESCOMP/CTSM/pull/884 +- https://github.com/ESCOMP/CTSM/pull/1019 + +=============================================================== +=============================================================== Tag name: ctsm1.0.dev096 Originator(s): slevis (Samuel Levis,SLevis Consulting LLC,303-665-1310) Date: Thu May 21 19:18:24 MDT 2020 diff --git a/doc/ChangeSum b/doc/ChangeSum index d5d77f901d..70151ec457 100644 --- a/doc/ChangeSum +++ b/doc/ChangeSum @@ -1,5 +1,6 @@ Tag Who Date Summary ============================================================================================================================ + ctsm1.0.dev097 ycheng 05/25/2020 Add two bioenergy crops (switchgrass and miscanthus) ctsm1.0.dev096 slevis 05/21/2020 Gridcell-level balance checks for carbon and nitrogen ctsm1.0.dev095 sacks 05/21/2020 Update cime and cmeps externals; rework initialization of CNFire object ctsm1.0.dev094 sacks 05/15/2020 Minor bug fixes needed for latest cime