#include <misc.h> #include <preproc.h> module CNPhenologyMod 1,2 #ifdef CN !----------------------------------------------------------------------- !BOP ! ! !MODULE: CNPhenologyMod ! ! !DESCRIPTION: ! Module holding routines used in phenology model for coupled carbon ! nitrogen code. ! ! !USES: use clmtype use shr_kind_mod, only: r8 => shr_kind_r8 implicit none save private ! local variables to the whole module ! !PUBLIC MEMBER FUNCTIONS: public :: CNPhenology ! ! !REVISION HISTORY: ! 8/1/03: Created by Peter Thornton ! 10/23/03, Peter Thornton: migrated all routines to vector data structures ! !EOP !----------------------------------------------------------------------- contains !----------------------------------------------------------------------- !BOP ! ! !IROUTINE: CNPhenology ! ! !INTERFACE: subroutine CNPhenology (num_soilc, filter_soilc, num_soilp, filter_soilp) 1,9 ! ! !DESCRIPTION: ! Dynamic phenology routine for coupled carbon-nitrogen code (CN) ! 1. grass phenology ! ! !USES: ! ! !ARGUMENTS: integer, intent(in) :: num_soilc ! number of soil columns in filter integer, intent(in) :: filter_soilc(:) ! filter for soil columns integer, intent(in) :: num_soilp ! number of soil pfts in filter integer, intent(in) :: filter_soilp(:) ! filter for soil pfts ! ! !CALLED FROM: ! subroutine CNEcosystemDyn in module CNEcosystemDynMod.F90 ! ! !REVISION HISTORY: ! 7/28/03: Created by Peter Thornton ! 9/05/03, Peter Thornton: moved from call with (p) to call with (c) ! 10/3/03, Peter Thornton: added subroutine calls for different phenology types ! 11/7/03, Peter Thornton: moved phenology type tests into phenology type ! routines, and moved onset, offset, background litfall routines into ! main phenology call. ! !LOCAL VARIABLES: ! local pointers to implicit in arrays ! ! local pointers to implicit in/out scalars ! ! local pointers to implicit out scalars ! ! !OTHER LOCAL VARIABLES: !EOP !----------------------------------------------------------------------- ! each of the following phenology type routines includes a filter ! to operate only on the relevant pfts call CNPhenologyClimate(num_soilp, filter_soilp) call CNEvergreenPhenology(num_soilp, filter_soilp) call CNSeasonDecidPhenology(num_soilp, filter_soilp) call CNStressDecidPhenology(num_soilp, filter_soilp) ! 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) call CNOffsetLitterfall(num_soilp, filter_soilp) call CNBackgroundLitterfall(num_soilp, filter_soilp) call CNLivewoodTurnover(num_soilp, filter_soilp) ! gather all pft-level litterfall fluxes to the column ! for litter C and N inputs call CNLitterToColumn(num_soilc, filter_soilc) end subroutine CNPhenology !----------------------------------------------------------------------- !----------------------------------------------------------------------- !BOP ! ! !IROUTINE: CNPhenologyClimate ! ! !INTERFACE: subroutine CNPhenologyClimate (num_soilp, filter_soilp) 1,2 ! ! !DESCRIPTION: ! For coupled carbon-nitrogen code (CN). ! ! !USES: use clm_time_manager, only: get_step_size ! ! !ARGUMENTS: integer, intent(in) :: num_soilp ! number of soil pfts in filter integer, intent(in) :: filter_soilp(:) ! filter for soil pfts ! ! !CALLED FROM: ! subroutine CNPhenology ! ! !REVISION HISTORY: ! 3/13/07: Created by Peter Thornton ! ! !LOCAL VARIABLES: ! local pointers to implicit in scalars ! integer , pointer :: ivt(:) ! pft vegetation type ! ecophysiological constants real(r8), pointer :: t_ref2m(:) ! 2m air temperature (K) real(r8), pointer :: tempavg_t2m(:) ! temp. avg 2m air temperature (K) ! ! local pointers to implicit in/out scalars ! ! ! local pointers to implicit out scalars ! ! !OTHER LOCAL VARIABLES: integer :: p ! indices integer :: fp !lake filter pft index real(r8):: dt !radiation time step delta t (seconds) real(r8):: fracday !dtime as a fraction of day !EOP !----------------------------------------------------------------------- ! assign local pointers to derived type arrays ivt => clm3%g%l%c%p%itype t_ref2m => clm3%g%l%c%p%pes%t_ref2m tempavg_t2m => clm3%g%l%c%p%pepv%tempavg_t2m ! set time steps dt = real( get_step_size(), r8 ) fracday = dt/86400.0_r8 do fp = 1,num_soilp p = filter_soilp(fp) tempavg_t2m(p) = tempavg_t2m(p) + t_ref2m(p) * (fracday/365._r8) end do end subroutine CNPhenologyClimate !----------------------------------------------------------------------- !----------------------------------------------------------------------- !BOP ! ! !IROUTINE: CNEvergreenPhenology ! ! !INTERFACE: subroutine CNEvergreenPhenology (num_soilp, filter_soilp) 1 ! ! !DESCRIPTION: ! For coupled carbon-nitrogen code (CN). ! ! !USES: ! ! !ARGUMENTS: integer, intent(in) :: num_soilp ! number of soil pfts in filter integer, intent(in) :: filter_soilp(:) ! filter for soil pfts ! ! !CALLED FROM: ! subroutine CNPhenology ! ! !REVISION HISTORY: ! 10/2/03: Created by Peter Thornton ! ! !LOCAL VARIABLES: ! local pointers to implicit in scalars ! integer , pointer :: ivt(:) ! pft vegetation type ! ecophysiological constants real(r8), pointer :: evergreen(:) ! binary flag for evergreen leaf habit (0 or 1) real(r8), pointer :: leaf_long(:) ! leaf longevity (yrs) ! ! local pointers to implicit in/out scalars ! real(r8), pointer :: bglfr(:) ! background litterfall rate (1/s) real(r8), pointer :: bgtr(:) ! background transfer growth rate (1/s) real(r8), pointer :: lgsf(:) ! long growing season factor [0-1] ! ! local pointers to implicit out scalars ! ! !OTHER LOCAL VARIABLES: integer :: p ! indices integer :: fp ! lake filter pft index !EOP !----------------------------------------------------------------------- ! assign local pointers to derived type arrays ivt => clm3%g%l%c%p%itype evergreen => pftcon%evergreen leaf_long => pftcon%leaf_long bglfr => clm3%g%l%c%p%pepv%bglfr bgtr => clm3%g%l%c%p%pepv%bgtr lgsf => clm3%g%l%c%p%pepv%lgsf do fp = 1,num_soilp p = filter_soilp(fp) if (evergreen(ivt(p)) == 1._r8) then bglfr(p) = 1._r8/(leaf_long(ivt(p))*365._r8*86400._r8) bgtr(p) = 0._r8 lgsf(p) = 0._r8 end if end do end subroutine CNEvergreenPhenology !----------------------------------------------------------------------- !----------------------------------------------------------------------- !BOP ! ! !IROUTINE: CNSeasonDecidPhenology ! ! !INTERFACE: subroutine CNSeasonDecidPhenology (num_soilp, filter_soilp) 1,3 ! ! !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 clm_time_manager, only: get_step_size use shr_const_mod, only: SHR_CONST_TKFRZ, SHR_CONST_PI ! ! !ARGUMENTS: integer, intent(in) :: num_soilp ! number of soil pfts in filter integer, intent(in) :: filter_soilp(:) ! filter for soil pfts ! ! !CALLED FROM: ! subroutine CNPhenology ! ! !REVISION HISTORY: ! 10/6/03: Created by Peter Thornton ! 10/24/03, Peter Thornton: migrated to vector data structures ! ! !LOCAL VARIABLES: ! local pointers to implicit in scalars integer , pointer :: ivt(:) ! pft vegetation type integer , pointer :: pcolumn(:) ! pft's column index integer , pointer :: pgridcell(:) ! pft's gridcell index real(r8), pointer :: latdeg(:) ! latitude (radians) real(r8), pointer :: decl(:) ! solar declination (radians) real(r8), pointer :: t_soisno(:,:) ! soil temperature (Kelvin) (-nlevsno+1:nlevgrnd) real(r8), pointer :: soilpsi(:,:) ! soil water potential in each soil layer (MPa) real(r8), pointer :: leafc_storage(:) ! (kgC/m2) leaf C storage real(r8), pointer :: frootc_storage(:) ! (kgC/m2) fine root C storage real(r8), pointer :: livestemc_storage(:) ! (kgC/m2) live stem C storage real(r8), pointer :: deadstemc_storage(:) ! (kgC/m2) dead stem C storage real(r8), pointer :: livecrootc_storage(:) ! (kgC/m2) live coarse root C storage real(r8), pointer :: deadcrootc_storage(:) ! (kgC/m2) dead coarse root C storage real(r8), pointer :: gresp_storage(:) ! (kgC/m2) growth respiration storage real(r8), pointer :: leafn_storage(:) ! (kgN/m2) leaf N storage real(r8), pointer :: frootn_storage(:) ! (kgN/m2) fine root N storage real(r8), pointer :: livestemn_storage(:) ! (kgN/m2) live stem N storage real(r8), pointer :: deadstemn_storage(:) ! (kgN/m2) dead stem N storage real(r8), pointer :: livecrootn_storage(:) ! (kgN/m2) live coarse root N storage real(r8), pointer :: deadcrootn_storage(:) ! (kgN/m2) dead coarse root N storage ! ecophysiological constants real(r8), pointer :: season_decid(:) ! binary flag for seasonal-deciduous leaf habit (0 or 1) real(r8), pointer :: woody(:) ! binary flag for woody lifeform (1=woody, 0=not woody) ! ! local pointers to implicit in/out scalars real(r8), pointer :: dormant_flag(:) ! dormancy flag real(r8), pointer :: days_active(:) ! number of days since last dormancy real(r8), pointer :: onset_flag(:) ! onset flag real(r8), pointer :: onset_counter(:) ! onset counter (seconds) real(r8), pointer :: onset_gddflag(:) ! onset freeze flag real(r8), pointer :: onset_gdd(:) ! onset growing degree days real(r8), pointer :: offset_flag(:) ! offset flag real(r8), pointer :: offset_counter(:) ! offset counter (seconds) real(r8), pointer :: dayl(:) ! daylength (seconds) real(r8), pointer :: prev_dayl(:) ! daylength from previous albedo timestep (seconds) real(r8), pointer :: annavg_t2m(:) ! annual average 2m air temperature (K) real(r8), pointer :: prev_leafc_to_litter(:) ! previous timestep leaf C litterfall flux (gC/m2/s) real(r8), pointer :: prev_frootc_to_litter(:) ! previous timestep froot C litterfall flux (gC/m2/s) real(r8), pointer :: lgsf(:) ! long growing season factor [0-1] real(r8), pointer :: bglfr(:) ! background litterfall rate (1/s) real(r8), pointer :: bgtr(:) ! background transfer growth rate (1/s) real(r8), pointer :: leafc_xfer_to_leafc(:) real(r8), pointer :: frootc_xfer_to_frootc(:) real(r8), pointer :: livestemc_xfer_to_livestemc(:) real(r8), pointer :: deadstemc_xfer_to_deadstemc(:) real(r8), pointer :: livecrootc_xfer_to_livecrootc(:) real(r8), pointer :: deadcrootc_xfer_to_deadcrootc(:) real(r8), pointer :: leafn_xfer_to_leafn(:) real(r8), pointer :: frootn_xfer_to_frootn(:) real(r8), pointer :: livestemn_xfer_to_livestemn(:) real(r8), pointer :: deadstemn_xfer_to_deadstemn(:) real(r8), pointer :: livecrootn_xfer_to_livecrootn(:) real(r8), pointer :: deadcrootn_xfer_to_deadcrootn(:) real(r8), pointer :: leafc_xfer(:) ! (kgC/m2) leaf C transfer real(r8), pointer :: frootc_xfer(:) ! (kgC/m2) fine root C transfer real(r8), pointer :: livestemc_xfer(:) ! (kgC/m2) live stem C transfer real(r8), pointer :: deadstemc_xfer(:) ! (kgC/m2) dead stem C transfer real(r8), pointer :: livecrootc_xfer(:) ! (kgC/m2) live coarse root C transfer real(r8), pointer :: deadcrootc_xfer(:) ! (kgC/m2) dead coarse root C transfer real(r8), pointer :: leafn_xfer(:) ! (kgN/m2) leaf N transfer real(r8), pointer :: frootn_xfer(:) ! (kgN/m2) fine root N transfer real(r8), pointer :: livestemn_xfer(:) ! (kgN/m2) live stem N transfer real(r8), pointer :: deadstemn_xfer(:) ! (kgN/m2) dead stem N transfer real(r8), pointer :: livecrootn_xfer(:) ! (kgN/m2) live coarse root N transfer real(r8), pointer :: deadcrootn_xfer(:) ! (kgN/m2) dead coarse root N transfer real(r8), pointer :: leafc_storage_to_xfer(:) real(r8), pointer :: frootc_storage_to_xfer(:) real(r8), pointer :: livestemc_storage_to_xfer(:) real(r8), pointer :: deadstemc_storage_to_xfer(:) real(r8), pointer :: livecrootc_storage_to_xfer(:) real(r8), pointer :: deadcrootc_storage_to_xfer(:) real(r8), pointer :: gresp_storage_to_xfer(:) real(r8), pointer :: leafn_storage_to_xfer(:) real(r8), pointer :: frootn_storage_to_xfer(:) real(r8), pointer :: livestemn_storage_to_xfer(:) real(r8), pointer :: deadstemn_storage_to_xfer(:) real(r8), pointer :: livecrootn_storage_to_xfer(:) real(r8), pointer :: deadcrootn_storage_to_xfer(:) #if (defined CNDV) logical , pointer :: pftmayexist(:) ! exclude seasonal decid pfts from tropics #endif ! ! local pointers to implicit out scalars ! ! !OTHER LOCAL VARIABLES: integer :: c,p !indices integer :: fp !lake filter pft index 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):: ws_flag !winter-summer solstice flag (0 or 1) real(r8):: crit_onset_gdd !critical onset growing degree-day sum real(r8):: ndays_on !number of days to complete onset real(r8):: ndays_off !number of days to complete offset real(r8):: soilt real(r8):: lat !latitude (radians) real(r8):: temp !temporary variable for daylength calculation real(r8):: fstor2tran !fraction of storage to move to transfer on each onset !EOP !----------------------------------------------------------------------- ! Assign local pointers to derived type arrays (in) ivt => clm3%g%l%c%p%itype pcolumn => clm3%g%l%c%p%column pgridcell => clm3%g%l%c%p%gridcell latdeg => clm3%g%latdeg decl => clm3%g%l%c%cps%decl t_soisno => clm3%g%l%c%ces%t_soisno leafc_storage => clm3%g%l%c%p%pcs%leafc_storage frootc_storage => clm3%g%l%c%p%pcs%frootc_storage livestemc_storage => clm3%g%l%c%p%pcs%livestemc_storage deadstemc_storage => clm3%g%l%c%p%pcs%deadstemc_storage livecrootc_storage => clm3%g%l%c%p%pcs%livecrootc_storage deadcrootc_storage => clm3%g%l%c%p%pcs%deadcrootc_storage gresp_storage => clm3%g%l%c%p%pcs%gresp_storage leafn_storage => clm3%g%l%c%p%pns%leafn_storage frootn_storage => clm3%g%l%c%p%pns%frootn_storage livestemn_storage => clm3%g%l%c%p%pns%livestemn_storage deadstemn_storage => clm3%g%l%c%p%pns%deadstemn_storage livecrootn_storage => clm3%g%l%c%p%pns%livecrootn_storage deadcrootn_storage => clm3%g%l%c%p%pns%deadcrootn_storage season_decid => pftcon%season_decid woody => pftcon%woody ! Assign local pointers to derived type arrays (out) dormant_flag => clm3%g%l%c%p%pepv%dormant_flag days_active => clm3%g%l%c%p%pepv%days_active onset_flag => clm3%g%l%c%p%pepv%onset_flag onset_counter => clm3%g%l%c%p%pepv%onset_counter onset_gddflag => clm3%g%l%c%p%pepv%onset_gddflag onset_gdd => clm3%g%l%c%p%pepv%onset_gdd offset_flag => clm3%g%l%c%p%pepv%offset_flag offset_counter => clm3%g%l%c%p%pepv%offset_counter dayl => clm3%g%l%c%p%pepv%dayl prev_dayl => clm3%g%l%c%p%pepv%prev_dayl annavg_t2m => clm3%g%l%c%p%pepv%annavg_t2m prev_leafc_to_litter => clm3%g%l%c%p%pepv%prev_leafc_to_litter prev_frootc_to_litter => clm3%g%l%c%p%pepv%prev_frootc_to_litter bglfr => clm3%g%l%c%p%pepv%bglfr bgtr => clm3%g%l%c%p%pepv%bgtr lgsf => clm3%g%l%c%p%pepv%lgsf leafc_xfer_to_leafc => clm3%g%l%c%p%pcf%leafc_xfer_to_leafc frootc_xfer_to_frootc => clm3%g%l%c%p%pcf%frootc_xfer_to_frootc livestemc_xfer_to_livestemc => clm3%g%l%c%p%pcf%livestemc_xfer_to_livestemc deadstemc_xfer_to_deadstemc => clm3%g%l%c%p%pcf%deadstemc_xfer_to_deadstemc livecrootc_xfer_to_livecrootc => clm3%g%l%c%p%pcf%livecrootc_xfer_to_livecrootc deadcrootc_xfer_to_deadcrootc => clm3%g%l%c%p%pcf%deadcrootc_xfer_to_deadcrootc leafn_xfer_to_leafn => clm3%g%l%c%p%pnf%leafn_xfer_to_leafn frootn_xfer_to_frootn => clm3%g%l%c%p%pnf%frootn_xfer_to_frootn livestemn_xfer_to_livestemn => clm3%g%l%c%p%pnf%livestemn_xfer_to_livestemn deadstemn_xfer_to_deadstemn => clm3%g%l%c%p%pnf%deadstemn_xfer_to_deadstemn livecrootn_xfer_to_livecrootn => clm3%g%l%c%p%pnf%livecrootn_xfer_to_livecrootn deadcrootn_xfer_to_deadcrootn => clm3%g%l%c%p%pnf%deadcrootn_xfer_to_deadcrootn leafc_xfer => clm3%g%l%c%p%pcs%leafc_xfer frootc_xfer => clm3%g%l%c%p%pcs%frootc_xfer livestemc_xfer => clm3%g%l%c%p%pcs%livestemc_xfer deadstemc_xfer => clm3%g%l%c%p%pcs%deadstemc_xfer livecrootc_xfer => clm3%g%l%c%p%pcs%livecrootc_xfer deadcrootc_xfer => clm3%g%l%c%p%pcs%deadcrootc_xfer leafn_xfer => clm3%g%l%c%p%pns%leafn_xfer frootn_xfer => clm3%g%l%c%p%pns%frootn_xfer livestemn_xfer => clm3%g%l%c%p%pns%livestemn_xfer deadstemn_xfer => clm3%g%l%c%p%pns%deadstemn_xfer livecrootn_xfer => clm3%g%l%c%p%pns%livecrootn_xfer deadcrootn_xfer => clm3%g%l%c%p%pns%deadcrootn_xfer leafc_storage_to_xfer => clm3%g%l%c%p%pcf%leafc_storage_to_xfer frootc_storage_to_xfer => clm3%g%l%c%p%pcf%frootc_storage_to_xfer livestemc_storage_to_xfer => clm3%g%l%c%p%pcf%livestemc_storage_to_xfer deadstemc_storage_to_xfer => clm3%g%l%c%p%pcf%deadstemc_storage_to_xfer livecrootc_storage_to_xfer => clm3%g%l%c%p%pcf%livecrootc_storage_to_xfer deadcrootc_storage_to_xfer => clm3%g%l%c%p%pcf%deadcrootc_storage_to_xfer gresp_storage_to_xfer => clm3%g%l%c%p%pcf%gresp_storage_to_xfer leafn_storage_to_xfer => clm3%g%l%c%p%pnf%leafn_storage_to_xfer frootn_storage_to_xfer => clm3%g%l%c%p%pnf%frootn_storage_to_xfer livestemn_storage_to_xfer => clm3%g%l%c%p%pnf%livestemn_storage_to_xfer deadstemn_storage_to_xfer => clm3%g%l%c%p%pnf%deadstemn_storage_to_xfer livecrootn_storage_to_xfer => clm3%g%l%c%p%pnf%livecrootn_storage_to_xfer deadcrootn_storage_to_xfer => clm3%g%l%c%p%pnf%deadcrootn_storage_to_xfer #if (defined CNDV) pftmayexist => clm3%g%l%c%p%pdgvs%pftmayexist #endif ! set time steps dt = real( get_step_size(), r8 ) fracday = dt/86400.0_r8 ! critical daylength from Biome-BGC, v4.1.2 crit_dayl = 39300._r8 ndays_on = 30._r8 ndays_off = 15._r8 ! transfer parameters fstor2tran = 0.5_r8 ! start pft loop do fp = 1,num_soilp p = filter_soilp(fp) c = pcolumn(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)) ! use solar declination information stored during Surface Albedo() ! and latitude from gps to calcluate daylength (convert latitude from degrees to radians) ! the constant 13750.9871 is the number of seconds per radian of hour-angle prev_dayl(p) = dayl(p) lat = (SHR_CONST_PI/180._r8)*latdeg(pgridcell(p)) temp = -(sin(lat)*sin(decl(c)))/(cos(lat) * cos(decl(c))) temp = min(1._r8,max(-1._r8,temp)) dayl(p) = 2.0_r8 * 13750.9871_r8 * acos(temp) ! set flag for solstice period (winter->summer = 1, summer->winter = 0) if (dayl(p) >= prev_dayl(p)) 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 (defined CNDV) pftmayexist(p) = .true. #endif ! 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 * 86400.0_r8 ! 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 (defined CNDV) ! If days_active > 355, then remove pft in ! CNDVEstablishment at the end of the year. ! days_active > 355 is a symptom of seasonal decid. pfts 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. #endif ! only begin to test for offset daylength once past the summer sol if (ws_flag == 0._r8 .and. dayl(p) < crit_dayl) then offset_flag(p) = 1._r8 offset_counter(p) = ndays_off * 86400.0_r8 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 pft loop end subroutine CNSeasonDecidPhenology !----------------------------------------------------------------------- !----------------------------------------------------------------------- !BOP ! ! !IROUTINE: CNStressDecidPhenology ! ! !INTERFACE: subroutine CNStressDecidPhenology (num_soilp, filter_soilp) 1,3 ! ! !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_step_size use shr_const_mod, only: SHR_CONST_TKFRZ, SHR_CONST_PI ! ! !ARGUMENTS: integer, intent(in) :: num_soilp ! number of soil pfts in filter integer, intent(in) :: filter_soilp(:) ! filter for soil pfts ! ! !CALLED FROM: ! subroutine CNPhenology ! ! !REVISION HISTORY: ! 10/27/03: Created by Peter Thornton ! 01/29/04: Made onset_gdd critical sum a function of temperature, as in ! seasonal deciduous algorithm. ! ! !LOCAL VARIABLES: ! local pointers to implicit in scalars ! integer , pointer :: ivt(:) ! pft vegetation type integer , pointer :: pcolumn(:) ! pft's column index integer , pointer :: pgridcell(:) ! pft's gridcell index real(r8), pointer :: latdeg(:) ! latitude (radians) real(r8), pointer :: decl(:) ! solar declination (radians) real(r8), pointer :: leafc_storage(:) ! (kgC/m2) leaf C storage real(r8), pointer :: frootc_storage(:) ! (kgC/m2) fine root C storage real(r8), pointer :: livestemc_storage(:) ! (kgC/m2) live stem C storage real(r8), pointer :: deadstemc_storage(:) ! (kgC/m2) dead stem C storage real(r8), pointer :: livecrootc_storage(:) ! (kgC/m2) live coarse root C storage real(r8), pointer :: deadcrootc_storage(:) ! (kgC/m2) dead coarse root C storage real(r8), pointer :: gresp_storage(:) ! (kgC/m2) growth respiration storage real(r8), pointer :: leafn_storage(:) ! (kgN/m2) leaf N storage real(r8), pointer :: frootn_storage(:) ! (kgN/m2) fine root N storage real(r8), pointer :: livestemn_storage(:) ! (kgN/m2) live stem N storage real(r8), pointer :: deadstemn_storage(:) ! (kgN/m2) dead stem N storage real(r8), pointer :: livecrootn_storage(:) ! (kgN/m2) live coarse root N storage real(r8), pointer :: deadcrootn_storage(:) ! (kgN/m2) dead coarse root N storage real(r8), pointer :: t_soisno(:,:) ! soil temperature (Kelvin) (-nlevsno+1:nlevgrnd) real(r8), pointer :: soilpsi(:,:) ! soil water potential in each soil layer (MPa) real(r8), pointer :: leaf_long(:) ! leaf longevity (yrs) real(r8), pointer :: stress_decid(:) ! binary flag for stress-deciduous leaf habit (0 or 1) real(r8), pointer :: woody(:) ! binary flag for woody lifeform (1=woody, 0=not woody) ! ! local pointers to implicit in/out scalars ! real(r8), pointer :: dormant_flag(:) ! dormancy flag real(r8), pointer :: days_active(:) ! number of days since last dormancy real(r8), pointer :: onset_flag(:) ! onset flag real(r8), pointer :: onset_counter(:) ! onset counter (seconds) real(r8), pointer :: onset_gddflag(:) ! onset freeze flag real(r8), pointer :: onset_fdd(:) ! onset freezing degree days counter real(r8), pointer :: onset_gdd(:) ! onset growing degree days real(r8), pointer :: onset_swi(:) ! onset soil water index real(r8), pointer :: offset_flag(:) ! offset flag real(r8), pointer :: offset_counter(:) ! offset counter (seconds) real(r8), pointer :: dayl(:) ! daylength (seconds) real(r8), pointer :: offset_fdd(:) ! offset freezing degree days counter real(r8), pointer :: offset_swi(:) ! offset soil water index real(r8), pointer :: annavg_t2m(:) ! annual average 2m air temperature (K) real(r8), pointer :: lgsf(:) ! long growing season factor [0-1] real(r8), pointer :: bglfr(:) ! background litterfall rate (1/s) real(r8), pointer :: bgtr(:) ! background transfer growth rate (1/s) real(r8), pointer :: prev_leafc_to_litter(:) ! previous timestep leaf C litterfall flux (gC/m2/s) real(r8), pointer :: prev_frootc_to_litter(:) ! previous timestep froot C litterfall flux (gC/m2/s) real(r8), pointer :: leafc_xfer_to_leafc(:) real(r8), pointer :: frootc_xfer_to_frootc(:) real(r8), pointer :: livestemc_xfer_to_livestemc(:) real(r8), pointer :: deadstemc_xfer_to_deadstemc(:) real(r8), pointer :: livecrootc_xfer_to_livecrootc(:) real(r8), pointer :: deadcrootc_xfer_to_deadcrootc(:) real(r8), pointer :: leafn_xfer_to_leafn(:) real(r8), pointer :: frootn_xfer_to_frootn(:) real(r8), pointer :: livestemn_xfer_to_livestemn(:) real(r8), pointer :: deadstemn_xfer_to_deadstemn(:) real(r8), pointer :: livecrootn_xfer_to_livecrootn(:) real(r8), pointer :: deadcrootn_xfer_to_deadcrootn(:) real(r8), pointer :: leafc_xfer(:) ! (kgC/m2) leaf C transfer real(r8), pointer :: frootc_xfer(:) ! (kgC/m2) fine root C transfer real(r8), pointer :: livestemc_xfer(:) ! (kgC/m2) live stem C transfer real(r8), pointer :: deadstemc_xfer(:) ! (kgC/m2) dead stem C transfer real(r8), pointer :: livecrootc_xfer(:) ! (kgC/m2) live coarse root C transfer real(r8), pointer :: deadcrootc_xfer(:) ! (kgC/m2) dead coarse root C transfer real(r8), pointer :: leafn_xfer(:) ! (kgN/m2) leaf N transfer real(r8), pointer :: frootn_xfer(:) ! (kgN/m2) fine root N transfer real(r8), pointer :: livestemn_xfer(:) ! (kgN/m2) live stem N transfer real(r8), pointer :: deadstemn_xfer(:) ! (kgN/m2) dead stem N transfer real(r8), pointer :: livecrootn_xfer(:) ! (kgN/m2) live coarse root N transfer real(r8), pointer :: deadcrootn_xfer(:) ! (kgN/m2) dead coarse root N transfer real(r8), pointer :: leafc_storage_to_xfer(:) real(r8), pointer :: frootc_storage_to_xfer(:) real(r8), pointer :: livestemc_storage_to_xfer(:) real(r8), pointer :: deadstemc_storage_to_xfer(:) real(r8), pointer :: livecrootc_storage_to_xfer(:) real(r8), pointer :: deadcrootc_storage_to_xfer(:) real(r8), pointer :: gresp_storage_to_xfer(:) real(r8), pointer :: leafn_storage_to_xfer(:) real(r8), pointer :: frootn_storage_to_xfer(:) real(r8), pointer :: livestemn_storage_to_xfer(:) real(r8), pointer :: deadstemn_storage_to_xfer(:) real(r8), pointer :: livecrootn_storage_to_xfer(:) real(r8), pointer :: deadcrootn_storage_to_xfer(:) ! ! local pointers to implicit out scalars ! ! ! !OTHER LOCAL VARIABLES: integer :: c,p ! indices integer :: fp ! lake filter pft index real(r8):: fracday ! dtime as a fraction of day real(r8):: dt ! radiation time step delta t (seconds) real(r8):: crit_onset_fdd ! critical number of freezing days real(r8):: crit_onset_gdd ! degree days for onset trigger real(r8):: crit_offset_fdd ! critical number of freezing degree days ! to trigger offset real(r8):: crit_onset_swi ! water stress days for offset trigger real(r8):: crit_offset_swi ! water stress days for offset trigger real(r8):: soilpsi_on ! water potential for onset trigger (MPa) real(r8):: soilpsi_off ! water potential for offset trigger (MPa) real(r8):: ndays_on ! number of days to complete onset real(r8):: ndays_off ! number of days to complete offset real(r8):: soilt ! temperature of top soil layer real(r8):: psi ! water stress of top soil layer real(r8):: lat !latitude (radians) real(r8):: temp !temporary variable for daylength calculation real(r8):: fstor2tran ! fraction of storage to move to transfer ! on each onset !EOP !----------------------------------------------------------------------- ! Assign local pointers to derived type arrays (in) ivt => clm3%g%l%c%p%itype pcolumn => clm3%g%l%c%p%column pgridcell => clm3%g%l%c%p%gridcell latdeg => clm3%g%latdeg decl => clm3%g%l%c%cps%decl leafc_storage => clm3%g%l%c%p%pcs%leafc_storage frootc_storage => clm3%g%l%c%p%pcs%frootc_storage livestemc_storage => clm3%g%l%c%p%pcs%livestemc_storage deadstemc_storage => clm3%g%l%c%p%pcs%deadstemc_storage livecrootc_storage => clm3%g%l%c%p%pcs%livecrootc_storage deadcrootc_storage => clm3%g%l%c%p%pcs%deadcrootc_storage gresp_storage => clm3%g%l%c%p%pcs%gresp_storage leafn_storage => clm3%g%l%c%p%pns%leafn_storage frootn_storage => clm3%g%l%c%p%pns%frootn_storage livestemn_storage => clm3%g%l%c%p%pns%livestemn_storage deadstemn_storage => clm3%g%l%c%p%pns%deadstemn_storage livecrootn_storage => clm3%g%l%c%p%pns%livecrootn_storage deadcrootn_storage => clm3%g%l%c%p%pns%deadcrootn_storage soilpsi => clm3%g%l%c%cps%soilpsi t_soisno => clm3%g%l%c%ces%t_soisno leaf_long => pftcon%leaf_long woody => pftcon%woody stress_decid => pftcon%stress_decid ! Assign local pointers to derived type arrays (out) dormant_flag => clm3%g%l%c%p%pepv%dormant_flag days_active => clm3%g%l%c%p%pepv%days_active onset_flag => clm3%g%l%c%p%pepv%onset_flag onset_counter => clm3%g%l%c%p%pepv%onset_counter onset_gddflag => clm3%g%l%c%p%pepv%onset_gddflag onset_fdd => clm3%g%l%c%p%pepv%onset_fdd onset_gdd => clm3%g%l%c%p%pepv%onset_gdd onset_swi => clm3%g%l%c%p%pepv%onset_swi offset_flag => clm3%g%l%c%p%pepv%offset_flag offset_counter => clm3%g%l%c%p%pepv%offset_counter dayl => clm3%g%l%c%p%pepv%dayl offset_fdd => clm3%g%l%c%p%pepv%offset_fdd offset_swi => clm3%g%l%c%p%pepv%offset_swi annavg_t2m => clm3%g%l%c%p%pepv%annavg_t2m prev_leafc_to_litter => clm3%g%l%c%p%pepv%prev_leafc_to_litter prev_frootc_to_litter => clm3%g%l%c%p%pepv%prev_frootc_to_litter lgsf => clm3%g%l%c%p%pepv%lgsf bglfr => clm3%g%l%c%p%pepv%bglfr bgtr => clm3%g%l%c%p%pepv%bgtr leafc_xfer_to_leafc => clm3%g%l%c%p%pcf%leafc_xfer_to_leafc frootc_xfer_to_frootc => clm3%g%l%c%p%pcf%frootc_xfer_to_frootc livestemc_xfer_to_livestemc => clm3%g%l%c%p%pcf%livestemc_xfer_to_livestemc deadstemc_xfer_to_deadstemc => clm3%g%l%c%p%pcf%deadstemc_xfer_to_deadstemc livecrootc_xfer_to_livecrootc => clm3%g%l%c%p%pcf%livecrootc_xfer_to_livecrootc deadcrootc_xfer_to_deadcrootc => clm3%g%l%c%p%pcf%deadcrootc_xfer_to_deadcrootc leafn_xfer_to_leafn => clm3%g%l%c%p%pnf%leafn_xfer_to_leafn frootn_xfer_to_frootn => clm3%g%l%c%p%pnf%frootn_xfer_to_frootn livestemn_xfer_to_livestemn => clm3%g%l%c%p%pnf%livestemn_xfer_to_livestemn deadstemn_xfer_to_deadstemn => clm3%g%l%c%p%pnf%deadstemn_xfer_to_deadstemn livecrootn_xfer_to_livecrootn => clm3%g%l%c%p%pnf%livecrootn_xfer_to_livecrootn deadcrootn_xfer_to_deadcrootn => clm3%g%l%c%p%pnf%deadcrootn_xfer_to_deadcrootn leafc_xfer => clm3%g%l%c%p%pcs%leafc_xfer frootc_xfer => clm3%g%l%c%p%pcs%frootc_xfer livestemc_xfer => clm3%g%l%c%p%pcs%livestemc_xfer deadstemc_xfer => clm3%g%l%c%p%pcs%deadstemc_xfer livecrootc_xfer => clm3%g%l%c%p%pcs%livecrootc_xfer deadcrootc_xfer => clm3%g%l%c%p%pcs%deadcrootc_xfer leafn_xfer => clm3%g%l%c%p%pns%leafn_xfer frootn_xfer => clm3%g%l%c%p%pns%frootn_xfer livestemn_xfer => clm3%g%l%c%p%pns%livestemn_xfer deadstemn_xfer => clm3%g%l%c%p%pns%deadstemn_xfer livecrootn_xfer => clm3%g%l%c%p%pns%livecrootn_xfer deadcrootn_xfer => clm3%g%l%c%p%pns%deadcrootn_xfer leafc_storage_to_xfer => clm3%g%l%c%p%pcf%leafc_storage_to_xfer frootc_storage_to_xfer => clm3%g%l%c%p%pcf%frootc_storage_to_xfer livestemc_storage_to_xfer => clm3%g%l%c%p%pcf%livestemc_storage_to_xfer deadstemc_storage_to_xfer => clm3%g%l%c%p%pcf%deadstemc_storage_to_xfer livecrootc_storage_to_xfer => clm3%g%l%c%p%pcf%livecrootc_storage_to_xfer deadcrootc_storage_to_xfer => clm3%g%l%c%p%pcf%deadcrootc_storage_to_xfer gresp_storage_to_xfer => clm3%g%l%c%p%pcf%gresp_storage_to_xfer leafn_storage_to_xfer => clm3%g%l%c%p%pnf%leafn_storage_to_xfer frootn_storage_to_xfer => clm3%g%l%c%p%pnf%frootn_storage_to_xfer livestemn_storage_to_xfer => clm3%g%l%c%p%pnf%livestemn_storage_to_xfer deadstemn_storage_to_xfer => clm3%g%l%c%p%pnf%deadstemn_storage_to_xfer livecrootn_storage_to_xfer => clm3%g%l%c%p%pnf%livecrootn_storage_to_xfer deadcrootn_storage_to_xfer => clm3%g%l%c%p%pnf%deadcrootn_storage_to_xfer ! set time steps dt = real( get_step_size(), r8 ) fracday = dt/86400.0_r8 ! set some local parameters - these will be moved into ! parameter file after testing ! onset parameters crit_onset_fdd = 15.0_r8 ! 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 = 15.0_r8 soilpsi_on = -2.0_r8 ndays_on = 30.0_r8 ! offset parameters crit_offset_fdd = 15.0_r8 crit_offset_swi = 15.0_r8 soilpsi_off = -2.0_r8 ndays_off = 15.0_r8 ! transfer parameters fstor2tran = 0.5_r8 do fp = 1,num_soilp p = filter_soilp(fp) c = pcolumn(p) if (stress_decid(ivt(p)) == 1._r8) then soilt = t_soisno(c,3) psi = soilpsi(c,3) ! use solar declination information stored during Surface Albedo() ! and latitude from gps to calcluate daylength (convert latitude from degrees to radians) ! the constant 13750.9871 is the number of seconds per radian of hour-angle lat = (SHR_CONST_PI/180._r8)*latdeg(pgridcell(p)) temp = -(sin(lat)*sin(decl(c)))/(cos(lat) * cos(decl(c))) temp = min(1._r8,max(-1._r8,temp)) dayl(p) = 2.0_r8 * 13750.9871_r8 * acos(temp) ! 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 if (psi >= soilpsi_on) onset_swi(p) = onset_swi(p) + fracday ! if critical soil water index is exceeded, set onset_flag, and ! then test for soil temperature criteria if (onset_swi(p) > crit_onset_swi) 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(p) <= 21600._r8) 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 * 86400._r8 ! 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(p) <= 21600._r8) 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 * 86400._r8 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 365. lgsf(p) = max(min((days_active(p)-365._r8)/365._r8, 1._r8),0._r8) ! 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))*365._r8*86400._r8))*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/(365._r8*86400._r8))*lgsf(p) ! set carbon fluxes for shifting storage pools to transfer pools leafc_storage_to_xfer(p) = leafc_storage(p) * bgtr(p) frootc_storage_to_xfer(p) = frootc_storage(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 pft loop end subroutine CNStressDecidPhenology !----------------------------------------------------------------------- !----------------------------------------------------------------------- !BOP ! ! !IROUTINE: CNOnsetGrowth ! ! !INTERFACE: subroutine CNOnsetGrowth (num_soilp, filter_soilp) 1,2 ! ! !DESCRIPTION: ! Determines the flux of stored C and N from transfer pools to display ! pools during the phenological onset period. ! ! !USES: use clm_time_manager, only: get_step_size ! ! !ARGUMENTS: integer, intent(in) :: num_soilp ! number of soil pfts in filter integer, intent(in) :: filter_soilp(:) ! filter for soil pfts ! ! !CALLED FROM: ! subroutine CNPhenology ! ! !REVISION HISTORY: ! 10/27/03: Created by Peter Thornton ! ! !LOCAL VARIABLES: ! local pointers to implicit in scalars ! integer , pointer :: ivt(:) ! pft vegetation type real(r8), pointer :: onset_flag(:) ! onset flag real(r8), pointer :: onset_counter(:) ! onset days counter real(r8), pointer :: leafc_xfer(:) ! (kgC/m2) leaf C transfer real(r8), pointer :: frootc_xfer(:) ! (kgC/m2) fine root C transfer real(r8), pointer :: livestemc_xfer(:) ! (kgC/m2) live stem C transfer real(r8), pointer :: deadstemc_xfer(:) ! (kgC/m2) dead stem C transfer real(r8), pointer :: livecrootc_xfer(:) ! (kgC/m2) live coarse root C transfer real(r8), pointer :: deadcrootc_xfer(:) ! (kgC/m2) dead coarse root C transfer real(r8), pointer :: leafn_xfer(:) ! (kgN/m2) leaf N transfer real(r8), pointer :: frootn_xfer(:) ! (kgN/m2) fine root N transfer real(r8), pointer :: livestemn_xfer(:) ! (kgN/m2) live stem N transfer real(r8), pointer :: deadstemn_xfer(:) ! (kgN/m2) dead stem N transfer real(r8), pointer :: livecrootn_xfer(:) ! (kgN/m2) live coarse root N transfer real(r8), pointer :: deadcrootn_xfer(:) ! (kgN/m2) dead coarse root N transfer real(r8), pointer :: woody(:) ! binary flag for woody lifeform (1=woody, 0=not woody) real(r8), pointer :: bgtr(:) ! background transfer growth rate (1/s) ! ! local pointers to implicit in/out scalars ! real(r8), pointer :: leafc_xfer_to_leafc(:) real(r8), pointer :: frootc_xfer_to_frootc(:) real(r8), pointer :: livestemc_xfer_to_livestemc(:) real(r8), pointer :: deadstemc_xfer_to_deadstemc(:) real(r8), pointer :: livecrootc_xfer_to_livecrootc(:) real(r8), pointer :: deadcrootc_xfer_to_deadcrootc(:) real(r8), pointer :: leafn_xfer_to_leafn(:) real(r8), pointer :: frootn_xfer_to_frootn(:) real(r8), pointer :: livestemn_xfer_to_livestemn(:) real(r8), pointer :: deadstemn_xfer_to_deadstemn(:) real(r8), pointer :: livecrootn_xfer_to_livecrootn(:) real(r8), pointer :: deadcrootn_xfer_to_deadcrootn(:) ! ! local pointers to implicit out scalars ! ! !OTHER LOCAL VARIABLES: integer :: p ! indices integer :: fp ! lake filter pft index real(r8):: dt ! radiation time step delta t (seconds) real(r8):: t1 ! temporary variable !EOP !----------------------------------------------------------------------- ! assign local pointers to derived type arrays (in) ivt => clm3%g%l%c%p%itype onset_flag => clm3%g%l%c%p%pepv%onset_flag onset_counter => clm3%g%l%c%p%pepv%onset_counter leafc_xfer => clm3%g%l%c%p%pcs%leafc_xfer frootc_xfer => clm3%g%l%c%p%pcs%frootc_xfer livestemc_xfer => clm3%g%l%c%p%pcs%livestemc_xfer deadstemc_xfer => clm3%g%l%c%p%pcs%deadstemc_xfer livecrootc_xfer => clm3%g%l%c%p%pcs%livecrootc_xfer deadcrootc_xfer => clm3%g%l%c%p%pcs%deadcrootc_xfer leafn_xfer => clm3%g%l%c%p%pns%leafn_xfer frootn_xfer => clm3%g%l%c%p%pns%frootn_xfer livestemn_xfer => clm3%g%l%c%p%pns%livestemn_xfer deadstemn_xfer => clm3%g%l%c%p%pns%deadstemn_xfer livecrootn_xfer => clm3%g%l%c%p%pns%livecrootn_xfer deadcrootn_xfer => clm3%g%l%c%p%pns%deadcrootn_xfer bgtr => clm3%g%l%c%p%pepv%bgtr woody => pftcon%woody ! assign local pointers to derived type arrays (out) leafc_xfer_to_leafc => clm3%g%l%c%p%pcf%leafc_xfer_to_leafc frootc_xfer_to_frootc => clm3%g%l%c%p%pcf%frootc_xfer_to_frootc livestemc_xfer_to_livestemc => clm3%g%l%c%p%pcf%livestemc_xfer_to_livestemc deadstemc_xfer_to_deadstemc => clm3%g%l%c%p%pcf%deadstemc_xfer_to_deadstemc livecrootc_xfer_to_livecrootc => clm3%g%l%c%p%pcf%livecrootc_xfer_to_livecrootc deadcrootc_xfer_to_deadcrootc => clm3%g%l%c%p%pcf%deadcrootc_xfer_to_deadcrootc leafn_xfer_to_leafn => clm3%g%l%c%p%pnf%leafn_xfer_to_leafn frootn_xfer_to_frootn => clm3%g%l%c%p%pnf%frootn_xfer_to_frootn livestemn_xfer_to_livestemn => clm3%g%l%c%p%pnf%livestemn_xfer_to_livestemn deadstemn_xfer_to_deadstemn => clm3%g%l%c%p%pnf%deadstemn_xfer_to_deadstemn livecrootn_xfer_to_livecrootn => clm3%g%l%c%p%pnf%livecrootn_xfer_to_livecrootn deadcrootn_xfer_to_deadcrootn => clm3%g%l%c%p%pnf%deadcrootn_xfer_to_deadcrootn ! set time steps dt = real( get_step_size(), r8 ) ! pft 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 pft loop end subroutine CNOnsetGrowth !----------------------------------------------------------------------- !----------------------------------------------------------------------- !BOP ! ! !IROUTINE: CNOffsetLitterfall ! ! !INTERFACE: subroutine CNOffsetLitterfall (num_soilp, filter_soilp) 1,2 ! ! !DESCRIPTION: ! Determines the flux of C and N from displayed pools to litter ! pools during the phenological offset period. ! ! !USES: use clm_time_manager, only: get_step_size ! ! !ARGUMENTS: integer, intent(in) :: num_soilp ! number of soil pfts in filter integer, intent(in) :: filter_soilp(:) ! filter for soil pfts ! ! !CALLED FROM: ! subroutine CNPhenology ! ! !REVISION HISTORY: ! 10/27/03: Created by Peter Thornton ! ! !LOCAL VARIABLES: ! local pointers to implicit in scalars ! integer , pointer :: ivt(:) ! pft vegetation type real(r8), pointer :: offset_flag(:) ! offset flag real(r8), pointer :: offset_counter(:) ! offset days counter real(r8), pointer :: leafc(:) ! (kgC/m2) leaf C real(r8), pointer :: frootc(:) ! (kgC/m2) fine root C real(r8), pointer :: cpool_to_leafc(:) real(r8), pointer :: cpool_to_frootc(:) real(r8), pointer :: leafcn(:) ! leaf C:N (gC/gN) real(r8), pointer :: lflitcn(:) ! leaf litter C:N (gC/gN) real(r8), pointer :: frootcn(:) ! fine root C:N (gC/gN) ! ! local pointers to implicit in/out scalars ! real(r8), pointer :: prev_leafc_to_litter(:) ! previous timestep leaf C litterfall flux (gC/m2/s) real(r8), pointer :: prev_frootc_to_litter(:) ! previous timestep froot C litterfall flux (gC/m2/s) real(r8), pointer :: leafc_to_litter(:) real(r8), pointer :: frootc_to_litter(:) real(r8), pointer :: leafn_to_litter(:) real(r8), pointer :: leafn_to_retransn(:) real(r8), pointer :: frootn_to_litter(:) ! ! local pointers to implicit out scalars ! ! ! !OTHER LOCAL VARIABLES: integer :: p, c ! indices integer :: fp ! lake filter pft index real(r8):: dt ! radiation time step delta t (seconds) real(r8):: t1 ! temporary variable !EOP !----------------------------------------------------------------------- ! assign local pointers to derived type arrays (in) ivt => clm3%g%l%c%p%itype offset_flag => clm3%g%l%c%p%pepv%offset_flag offset_counter => clm3%g%l%c%p%pepv%offset_counter leafc => clm3%g%l%c%p%pcs%leafc frootc => clm3%g%l%c%p%pcs%frootc cpool_to_leafc => clm3%g%l%c%p%pcf%cpool_to_leafc cpool_to_frootc => clm3%g%l%c%p%pcf%cpool_to_frootc leafcn => pftcon%leafcn lflitcn => pftcon%lflitcn frootcn => pftcon%frootcn ! assign local pointers to derived type arrays (out) prev_leafc_to_litter => clm3%g%l%c%p%pepv%prev_leafc_to_litter prev_frootc_to_litter => clm3%g%l%c%p%pepv%prev_frootc_to_litter leafc_to_litter => clm3%g%l%c%p%pcf%leafc_to_litter frootc_to_litter => clm3%g%l%c%p%pcf%frootc_to_litter leafn_to_litter => clm3%g%l%c%p%pnf%leafn_to_litter leafn_to_retransn => clm3%g%l%c%p%pnf%leafn_to_retransn frootn_to_litter => clm3%g%l%c%p%pnf%frootn_to_litter ! set time steps dt = real( get_step_size(), r8 ) ! 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 leafc_to_litter(p) = t1 * leafc(p) + cpool_to_leafc(p) frootc_to_litter(p) = t1 * frootc(p) + cpool_to_frootc(p) 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 ! 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) ! calculate fine root N litterfall (no retranslocation of fine root N) frootn_to_litter(p) = frootc_to_litter(p) / frootcn(ivt(p)) ! 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 pft loop end subroutine CNOffsetLitterfall !----------------------------------------------------------------------- !----------------------------------------------------------------------- !BOP ! ! !IROUTINE: CNBackgroundLitterfall ! ! !INTERFACE: subroutine CNBackgroundLitterfall (num_soilp, filter_soilp) 1,2 ! ! !DESCRIPTION: ! Determines the flux of C and N from displayed pools to litter ! pools as the result of background litter fall. ! ! !USES: use clm_time_manager, only: get_step_size ! ! !ARGUMENTS: integer, intent(in) :: num_soilp ! number of soil pfts in filter integer, intent(in) :: filter_soilp(:) ! filter for soil pfts ! ! !CALLED FROM: ! subroutine CNPhenology ! ! !REVISION HISTORY: ! 10/2/03: Created by Peter Thornton ! 10/24/03, Peter Thornton: migrated to vector data structures ! ! !LOCAL VARIABLES: ! local pointers to implicit in scalars ! ! pft level integer , pointer :: ivt(:) ! pft vegetation type real(r8), pointer :: bglfr(:) ! background litterfall rate (1/s) real(r8), pointer :: leafc(:) ! (kgC/m2) leaf C real(r8), pointer :: frootc(:) ! (kgC/m2) fine root C ! ecophysiological constants real(r8), pointer :: leafcn(:) ! leaf C:N (gC/gN) real(r8), pointer :: lflitcn(:) ! leaf litter C:N (gC/gN) real(r8), pointer :: frootcn(:) ! fine root C:N (gC/gN) ! ! local pointers to implicit in/out scalars ! real(r8), pointer :: leafc_to_litter(:) real(r8), pointer :: frootc_to_litter(:) real(r8), pointer :: leafn_to_litter(:) real(r8), pointer :: leafn_to_retransn(:) real(r8), pointer :: frootn_to_litter(:) ! ! local pointers to implicit out scalars ! ! ! !OTHER LOCAL VARIABLES: integer :: p ! indices integer :: fp ! lake filter pft index real(r8):: dt ! decomp timestep (seconds) !EOP !----------------------------------------------------------------------- ! assign local pointers to derived type arrays (in) ivt => clm3%g%l%c%p%itype bglfr => clm3%g%l%c%p%pepv%bglfr leafc => clm3%g%l%c%p%pcs%leafc frootc => clm3%g%l%c%p%pcs%frootc leafcn => pftcon%leafcn lflitcn => pftcon%lflitcn frootcn => pftcon%frootcn ! assign local pointers to derived type arrays (out) leafc_to_litter => clm3%g%l%c%p%pcf%leafc_to_litter frootc_to_litter => clm3%g%l%c%p%pcf%frootc_to_litter leafn_to_litter => clm3%g%l%c%p%pnf%leafn_to_litter leafn_to_retransn => clm3%g%l%c%p%pnf%leafn_to_retransn frootn_to_litter => clm3%g%l%c%p%pnf%frootn_to_litter ! set time steps dt = real( get_step_size(), r8 ) ! pft 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) ! 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) ! calculate fine root N litterfall (no retranslocation of fine root N) frootn_to_litter(p) = frootc_to_litter(p) / frootcn(ivt(p)) end if end do end subroutine CNBackgroundLitterfall !----------------------------------------------------------------------- !----------------------------------------------------------------------- !BOP ! ! !IROUTINE: CNLivewoodTurnover ! ! !INTERFACE: subroutine CNLivewoodTurnover (num_soilp, filter_soilp) 1,2 ! ! !DESCRIPTION: ! Determines the flux of C and N from live wood to ! dead wood pools, for stem and coarse root. ! ! !USES: use clm_time_manager, only: get_step_size ! ! !ARGUMENTS: integer, intent(in) :: num_soilp ! number of soil pfts in filter integer, intent(in) :: filter_soilp(:) ! filter for soil pfts ! ! !CALLED FROM: ! subroutine CNPhenology ! ! !REVISION HISTORY: ! 12/5/03: created by Peter Thornton ! ! !LOCAL VARIABLES: ! local pointers to implicit in scalars ! ! pft level integer , pointer :: ivt(:) ! pft vegetation type real(r8), pointer :: livestemc(:) ! (gC/m2) live stem C real(r8), pointer :: livecrootc(:) ! (gC/m2) live coarse root C real(r8), pointer :: livestemn(:) ! (gN/m2) live stem N real(r8), pointer :: livecrootn(:) ! (gN/m2) live coarse root N ! ecophysiological constants real(r8), pointer :: woody(:) ! binary flag for woody lifeform (1=woody, 0=not woody) real(r8), pointer :: livewdcn(:) ! live wood (phloem and ray parenchyma) C:N (gC/gN) real(r8), pointer :: deadwdcn(:) ! dead wood (xylem and heartwood) C:N (gC/gN) ! ! local pointers to implicit in/out scalars ! real(r8), pointer :: livestemc_to_deadstemc(:) real(r8), pointer :: livecrootc_to_deadcrootc(:) real(r8), pointer :: livestemn_to_deadstemn(:) real(r8), pointer :: livestemn_to_retransn(:) real(r8), pointer :: livecrootn_to_deadcrootn(:) real(r8), pointer :: livecrootn_to_retransn(:) ! ! local pointers to implicit out scalars ! ! ! !OTHER LOCAL VARIABLES: integer :: p ! indices integer :: fp ! lake filter pft index real(r8):: dt ! decomp timestep (seconds) real(r8):: lwtop ! live wood turnover proportion (annual fraction) real(r8):: ctovr ! temporary variable for carbon turnover real(r8):: ntovr ! temporary variable for nitrogen turnover !EOP !----------------------------------------------------------------------- ! assign local pointers to derived type arrays (in) ivt => clm3%g%l%c%p%itype livestemc => clm3%g%l%c%p%pcs%livestemc livecrootc => clm3%g%l%c%p%pcs%livecrootc livestemn => clm3%g%l%c%p%pns%livestemn livecrootn => clm3%g%l%c%p%pns%livecrootn woody => pftcon%woody livewdcn => pftcon%livewdcn deadwdcn => pftcon%deadwdcn ! assign local pointers to derived type arrays (out) livestemc_to_deadstemc => clm3%g%l%c%p%pcf%livestemc_to_deadstemc livecrootc_to_deadcrootc => clm3%g%l%c%p%pcf%livecrootc_to_deadcrootc livestemn_to_deadstemn => clm3%g%l%c%p%pnf%livestemn_to_deadstemn livestemn_to_retransn => clm3%g%l%c%p%pnf%livestemn_to_retransn livecrootn_to_deadcrootn => clm3%g%l%c%p%pnf%livecrootn_to_deadcrootn livecrootn_to_retransn => clm3%g%l%c%p%pnf%livecrootn_to_retransn ! set time steps dt = real( get_step_size(), r8 ) ! set the global parameter for livewood turnover rate ! define as an annual fraction (0.7), and convert to fraction per second lwtop = 0.7_r8 / 31536000.0_r8 ! pft 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)) 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)) livecrootn_to_retransn(p) = ntovr - livecrootn_to_deadcrootn(p) end if end do end subroutine CNLivewoodTurnover !----------------------------------------------------------------------- !----------------------------------------------------------------------- !BOP ! ! !IROUTINE: CNLitterToColumn ! ! !INTERFACE: subroutine CNLitterToColumn (num_soilc, filter_soilc) 1,1 ! ! !DESCRIPTION: ! called at the end of cn_phenology to gather all pft-level litterfall fluxes ! to the column level and assign them to the three litter pools ! ! !USES: use clm_varpar, only : max_pft_per_col ! ! !ARGUMENTS: integer, intent(in) :: num_soilc ! number of soil columns in filter integer, intent(in) :: filter_soilc(:) ! filter for soil columns ! ! !CALLED FROM: ! subroutine CNPhenology ! ! !REVISION HISTORY: ! 9/8/03: Created by Peter Thornton ! ! !LOCAL VARIABLES: ! local pointers to implicit in scalars ! integer , pointer :: ivt(:) ! pft vegetation type real(r8), pointer :: wtcol(:) ! weight (relative to column) for this pft (0-1) real(r8), pointer :: pwtgcell(:) ! weight of pft relative to corresponding gridcell real(r8), pointer :: leafc_to_litter(:) real(r8), pointer :: frootc_to_litter(:) real(r8), pointer :: leafn_to_litter(:) real(r8), pointer :: frootn_to_litter(:) real(r8), pointer :: lf_flab(:) ! leaf litter labile fraction real(r8), pointer :: lf_fcel(:) ! leaf litter cellulose fraction real(r8), pointer :: lf_flig(:) ! leaf litter lignin fraction real(r8), pointer :: fr_flab(:) ! fine root litter labile fraction real(r8), pointer :: fr_fcel(:) ! fine root litter cellulose fraction real(r8), pointer :: fr_flig(:) ! fine root litter lignin fraction integer , pointer :: npfts(:) ! number of pfts for each column integer , pointer :: pfti(:) ! beginning pft index for each column ! ! local pointers to implicit in/out scalars ! real(r8), pointer :: leafc_to_litr1c(:) real(r8), pointer :: leafc_to_litr2c(:) real(r8), pointer :: leafc_to_litr3c(:) real(r8), pointer :: frootc_to_litr1c(:) real(r8), pointer :: frootc_to_litr2c(:) real(r8), pointer :: frootc_to_litr3c(:) real(r8), pointer :: leafn_to_litr1n(:) real(r8), pointer :: leafn_to_litr2n(:) real(r8), pointer :: leafn_to_litr3n(:) real(r8), pointer :: frootn_to_litr1n(:) real(r8), pointer :: frootn_to_litr2n(:) real(r8), pointer :: frootn_to_litr3n(:) ! ! local pointers to implicit out scalars ! ! ! !OTHER LOCAL VARIABLES: integer :: fc,c,pi,p !EOP !----------------------------------------------------------------------- ! assign local pointers to derived type arrays (in) ivt => clm3%g%l%c%p%itype wtcol => clm3%g%l%c%p%wtcol pwtgcell => clm3%g%l%c%p%wtgcell leafc_to_litter => clm3%g%l%c%p%pcf%leafc_to_litter frootc_to_litter => clm3%g%l%c%p%pcf%frootc_to_litter leafn_to_litter => clm3%g%l%c%p%pnf%leafn_to_litter frootn_to_litter => clm3%g%l%c%p%pnf%frootn_to_litter npfts => clm3%g%l%c%npfts pfti => clm3%g%l%c%pfti lf_flab => pftcon%lf_flab lf_fcel => pftcon%lf_fcel lf_flig => pftcon%lf_flig fr_flab => pftcon%fr_flab fr_fcel => pftcon%fr_fcel fr_flig => pftcon%fr_flig ! assign local pointers to derived type arrays (out) leafc_to_litr1c => clm3%g%l%c%ccf%leafc_to_litr1c leafc_to_litr2c => clm3%g%l%c%ccf%leafc_to_litr2c leafc_to_litr3c => clm3%g%l%c%ccf%leafc_to_litr3c frootc_to_litr1c => clm3%g%l%c%ccf%frootc_to_litr1c frootc_to_litr2c => clm3%g%l%c%ccf%frootc_to_litr2c frootc_to_litr3c => clm3%g%l%c%ccf%frootc_to_litr3c leafn_to_litr1n => clm3%g%l%c%cnf%leafn_to_litr1n leafn_to_litr2n => clm3%g%l%c%cnf%leafn_to_litr2n leafn_to_litr3n => clm3%g%l%c%cnf%leafn_to_litr3n frootn_to_litr1n => clm3%g%l%c%cnf%frootn_to_litr1n frootn_to_litr2n => clm3%g%l%c%cnf%frootn_to_litr2n frootn_to_litr3n => clm3%g%l%c%cnf%frootn_to_litr3n do pi = 1,max_pft_per_col do fc = 1,num_soilc c = filter_soilc(fc) if ( pi <= npfts(c) ) then p = pfti(c) + pi - 1 if (pwtgcell(p)>0._r8) then ! leaf litter carbon fluxes leafc_to_litr1c(c) = leafc_to_litr1c(c) + leafc_to_litter(p) * lf_flab(ivt(p)) * wtcol(p) leafc_to_litr2c(c) = leafc_to_litr2c(c) + leafc_to_litter(p) * lf_fcel(ivt(p)) * wtcol(p) leafc_to_litr3c(c) = leafc_to_litr3c(c) + leafc_to_litter(p) * lf_flig(ivt(p)) * wtcol(p) ! leaf litter nitrogen fluxes leafn_to_litr1n(c) = leafn_to_litr1n(c) + leafn_to_litter(p) * lf_flab(ivt(p)) * wtcol(p) leafn_to_litr2n(c) = leafn_to_litr2n(c) + leafn_to_litter(p) * lf_fcel(ivt(p)) * wtcol(p) leafn_to_litr3n(c) = leafn_to_litr3n(c) + leafn_to_litter(p) * lf_flig(ivt(p)) * wtcol(p) ! fine root litter carbon fluxes frootc_to_litr1c(c) = frootc_to_litr1c(c) + frootc_to_litter(p) * fr_flab(ivt(p)) * wtcol(p) frootc_to_litr2c(c) = frootc_to_litr2c(c) + frootc_to_litter(p) * fr_fcel(ivt(p)) * wtcol(p) frootc_to_litr3c(c) = frootc_to_litr3c(c) + frootc_to_litter(p) * fr_flig(ivt(p)) * wtcol(p) ! fine root litter nitrogen fluxes frootn_to_litr1n(c) = frootn_to_litr1n(c) + frootn_to_litter(p) * fr_flab(ivt(p)) * wtcol(p) frootn_to_litr2n(c) = frootn_to_litr2n(c) + frootn_to_litter(p) * fr_fcel(ivt(p)) * wtcol(p) frootn_to_litr3n(c) = frootn_to_litr3n(c) + frootn_to_litter(p) * fr_flig(ivt(p)) * wtcol(p) end if end if end do end do end subroutine CNLitterToColumn !----------------------------------------------------------------------- #endif end module CNPhenologyMod