diff --git a/biogeochem/EDPhysiologyMod.F90 b/biogeochem/EDPhysiologyMod.F90 index 12cab3db61..e11563a1de 100644 --- a/biogeochem/EDPhysiologyMod.F90 +++ b/biogeochem/EDPhysiologyMod.F90 @@ -174,8 +174,6 @@ module EDPhysiologyMod integer :: istat ! return status code character(len=255) :: smsg ! Message string for deallocation errors - - integer, parameter :: dleafon_drycheck = 100 ! Drought deciduous leaves max days on check parameter real(r8), parameter :: decid_leaf_long_max = 1.0_r8 ! Maximum leaf lifespan for ! deciduous PFTs [years] @@ -479,7 +477,7 @@ subroutine PreDisturbanceLitterFluxes( currentSite, currentPatch, bc_in ) ! Calculate seed germination rate, the status flags prevent ! germination from occuring when the site is in a drought ! (for drought deciduous) or too cold (for cold deciduous) - call SeedGermination(litt, currentSite%cstatus, currentSite%dstatus(1:numpft), bc_in, currentPatch) + call SeedGermination(litt, currentSite%phen_status(1:numpft), bc_in, currentPatch) ! Send fluxes from newly created litter into the litter pools ! This litter flux is from non-disturbance inducing mortality, as well @@ -912,11 +910,6 @@ subroutine phenology( currentSite, bc_in ) ! ! !USES: use FatesConstantsMod, only : tfrz => t_water_freeze_k_1atm - use EDParamsMod, only : ED_val_phen_a, ED_val_phen_b, ED_val_phen_c - use EDParamsMod, only : ED_val_phen_chiltemp - use EDParamsMod, only : ED_val_phen_mindayson - use EDParamsMod, only : ED_val_phen_ncolddayslim - use EDParamsMod, only : ED_val_phen_coldtemp use EDBtranMod, only : check_layer_water ! ! !ARGUMENTS: @@ -944,6 +937,7 @@ subroutine phenology( currentSite, bc_in ) real(r8) :: rootfrac_notop ! Total rooting fraction excluding the top soil layer integer :: ncdstart ! beginning of counting period for chilling degree days. integer :: gddstart ! beginning of counting period for growing degree days. + integer :: gddend ! end of counting period for growing degree days. integer :: nlevroot ! Number of rooting levels to consider real(r8) :: temp_in_C ! daily averaged temperature in celsius real(r8) :: temp_wgt ! canopy area weighting factor for daily average @@ -955,6 +949,27 @@ subroutine phenology( currentSite, bc_in ) ! lifespan and the maximum lifespan of drought ! deciduous (see parameter decid_leaf_long_max ! at the beginning of this file). + + ! The three parameters below are for the growing degree days + ! threshold function, which is modulated by the number of + ! chilling days (NCD): GDD_Thresh = a + b * exp (c * NCD) + real(r8) :: phen_gddthresh_a ! - a parameter (intercept) + real(r8) :: phen_gddthresh_b ! - b parameter (multiplier) + real(r8) :: phen_gddthresh_c ! - c parameter (exponent) + + real(r8) :: phen_gddtemp ! (Lower) Temperature threshold for accumulating + ! growing degree days (used for leaf flushing) + real(r8) :: phen_chilltemp ! (Upper) Temperature threshold for accumulating + ! number of chilling days (used for leaf flushing) + real(r8) :: phen_coldtemp ! (Upper) daily average temperature threshold below which the + ! day is considered cold and will count towards leaf + ! abscission + real(r8) :: phen_mindayson ! Minimum number of days that plants must remain with leaves + ! flushed before they can abscise leaves again. + real(r8) :: phen_mindaysoff ! Minimum number of days that plants must remain leafless + ! before theu can flush leaves again. + real(r8) :: phen_ncolddayslim ! Minimum number of recent days below the temperature threshold + ! that initiates temperature-driven leaf abscission. real(r8) :: phen_drought_threshold ! For drought hard-deciduous, this is the threshold ! below which plants will abscise leaves, and ! above which plants will flush leaves. For semi- @@ -972,8 +987,6 @@ subroutine phenology( currentSite, bc_in ) ! the values are soil matric potential [mm]. ! Ignored for hard-deciduous and evergreen ! plants. - real(r8) :: phen_doff_time ! Minimum number of days that plants must remain - ! leafless before flushing leaves again. ! Logical tests to make code more readable logical :: smoist_below_threshold ! Is soil moisture below threshold? @@ -984,6 +997,7 @@ subroutine phenology( currentSite, bc_in ) logical :: prolonged_on_period ! Has leaves been flushed for too long? logical :: prolonged_off_period ! Have leaves been abscissed for too long? logical :: last_flush_long_ago ! Has it been a very long time since last flushing? + logical :: growing_season ! Is this the growing season for cold-deciduous? ! This is the integer model day. The first day of the simulation is 1, and it @@ -1023,170 +1037,181 @@ subroutine phenology( currentSite, bc_in ) !Zero growing degree and chilling day counters if (currentSite%lat > 0)then - ncdstart = 270 !Northern Hemisphere begining November - gddstart = 1 !Northern Hemisphere begining January + ncdstart = 270 ! Northern Hemisphere begining November + gddstart = 1 ! Northern Hemisphere begining January + gddend = 180 ! Northern Hemisphere ending June else - ncdstart = 120 !Southern Hemisphere beginning May - gddstart = 181 !Northern Hemisphere begining July + ncdstart = 120 ! Southern Hemisphere beginning May + gddstart = 181 ! Southern Hemisphere begining July + gddend = 365 ! Southern Hemisphere ending December endif + ! Define growing season based on start and end dates. Check for cases in which the growing season + ! includes 31 December and 1 January. + if (gddend >= gddstart) then + growing_season = hlm_day_of_year >= gddstart .and. hlm_day_of_year <= gddend + else + growing_season = hlm_day_of_year >= gddstart .or. hlm_day_of_year <= gddend + end if + + ! Count the number of chilling days over a seasonal window. ! For comparing against GDD, we start calculating chilling ! in the late autumn. ! This value is used to determine the GDD exceedance threshold if (hlm_day_of_year == ncdstart)then - currentSite%nchilldays = 0 + currentSite%nchilldays(1:numpft) = 0 endif - - !Accumulate growing/chilling days after start of counting period - if (temp_in_C < ED_val_phen_chiltemp)then - currentSite%nchilldays = currentSite%nchilldays + 1 + ! + ! reset GDD on set dates + if (hlm_day_of_year == gddstart)then + currentSite%grow_deg_days(1:numpft) = 0._r8 endif - !GDD accumulation function, which also depends on chilling days. - ! -68 + 638 * (-0.001 * ncd) - gdd_threshold = ED_val_phen_a + ED_val_phen_b*exp(ED_val_phen_c*real(currentSite%nchilldays,r8)) - !Accumulate temperature of last 10 days. currentSite%vegtemp_memory(2:num_vegtemp_mem) = currentSite%vegtemp_memory(1:num_vegtemp_mem-1) currentSite%vegtemp_memory(1) = temp_in_C - !count number of days for leaves off - ncolddays = 0 - do i_tmem = 1,num_vegtemp_mem - if (currentSite%vegtemp_memory(i_tmem) < ED_val_phen_coldtemp)then - ncolddays = ncolddays + 1 - endif - enddo - ! Here is where we do the GDD accumulation calculation - ! - ! reset GDD on set dates - if (hlm_day_of_year == gddstart)then - currentSite%grow_deg_days = 0._r8 - endif - ! - ! accumulate the GDD using daily mean temperatures - ! Don't accumulate GDD during the growing season (that wouldn't make sense) - if (temp_in_C .gt. 0._r8 .and. currentSite%cstatus == phen_cstat_iscold) then - currentSite%grow_deg_days = currentSite%grow_deg_days + temp_in_C - endif + ! Loop through every PFT to assign the elongation factor. + ! Add PFT loop to account for different parameters and PFT-specific rooting depth profiles. + pft_elong_loop: do ipft=1,numpft + ! Copy values to a local variable to make code more legible. + phen_gddthresh_a = prt_params%phen_gddthresh_a (ipft) + phen_gddthresh_b = prt_params%phen_gddthresh_b (ipft) + phen_gddthresh_c = prt_params%phen_gddthresh_c (ipft) + phen_gddtemp = prt_params%phen_gddtemp (ipft) + phen_chilltemp = prt_params%phen_chilltemp (ipft) + phen_coldtemp = prt_params%phen_coldtemp (ipft) + phen_mindayson = prt_params%phen_mindayson (ipft) + phen_mindaysoff = prt_params%phen_mindaysoff (ipft) + phen_ncolddayslim = prt_params%phen_ncolddayslim (ipft) + phen_drought_threshold = prt_params%phen_drought_threshold(ipft) + phen_moist_threshold = prt_params%phen_moist_threshold (ipft) - !this logic is to prevent GDD accumulating after the leaves have fallen and before the - ! beginnning of the accumulation period, to prevend erroneous autumn leaf flushing. - if(model_day_int> ndays_per_year)then !only do this after the first year to prevent odd behaviour + ! Calculate the number of days since the last leaf flushing and leaf abscission + ! events. If this is the beginning of the simulation, that day might not had occured + ! yet, so set it to last year to get things rolling. + if (model_day_int < currentSite%leafoffdate(ipft)) then + currentSite%ndaysleafoff(ipft) = model_day_int - (currentSite%leafoffdate(ipft) - ndays_per_year) + else + currentSite%ndaysleafoff(ipft) = model_day_int - currentSite%leafoffdate(ipft) + end if - if(currentSite%lat .gt. 0.0_r8)then !Northern Hemisphere - ! In the north, don't accumulate when we are past the leaf fall date. - ! Accumulation starts on day 1 of year in NH. - ! The 180 is to prevent going into an 'always off' state after initialization - if( model_day_int .gt. currentSite%cleafoffdate.and.hlm_day_of_year.gt.180)then ! - currentSite%grow_deg_days = 0._r8 - endif - else !Southern Hemisphere - ! In the South, don't accumulate after the leaf off date, and before the start of - ! the accumulation phase (day 181). - if(model_day_int .gt. currentSite%cleafoffdate.and.hlm_day_of_year.lt.gddstart) then! - currentSite%grow_deg_days = 0._r8 - endif - endif - endif !year1 + if (model_day_int < currentSite%leafondate(ipft)) then + currentSite%ndaysleafon(ipft) = model_day_int - (currentSite%leafondate(ipft) - ndays_per_year) + else + currentSite%ndaysleafon(ipft) = model_day_int - currentSite%leafondate(ipft) + end if - ! Calculate the number of days since the leaves last came on - ! and off. If this is the beginning of the simulation, that day might - ! not had occured yet, so set it to last year to get things rolling + !---~--- + ! COLD (SEASON) DECIDUOUS + !---~--- + case_cold_phen: select case (prt_params%season_decid(ipft)) + case (itrue) - if (model_day_int < currentSite%cleafoffdate) then - currentSite%cndaysleafoff = model_day_int - (currentSite%cleafoffdate - ndays_per_year) - else - currentSite%cndaysleafoff = model_day_int - currentSite%cleafoffdate - end if + ! Accumulate growing/chilling days after start of counting period + if (temp_in_C < phen_chilltemp) then + currentSite%nchilldays(ipft) = currentSite%nchilldays(ipft) + 1 + end if - if (model_day_int < currentSite%cleafondate) then - currentSite%cndaysleafon = model_day_int - (currentSite%cleafondate - ndays_per_year) - else - currentSite%cndaysleafon = model_day_int - currentSite%cleafondate - end if + ! GDD accumulation function, which also depends on chilling days. + ! -68 + 638 * (-0.001 * ncd) + gdd_threshold = phen_gddthresh_a + & + phen_gddthresh_b * exp(phen_gddthresh_c*real(currentSite%nchilldays(ipft),r8)) + ! Count number of days for leaves off + ncolddays = count(currentSite%vegtemp_memory(1:num_vegtemp_mem) < phen_coldtemp) + ! Accumulate the GDD using daily mean temperatures + ! Don't accumulate GDD during the growing season (that wouldn't make sense) + if ( temp_in_C > phen_gddtemp .and. currentSite%phen_status(ipft) == phen_cstat_iscold ) then + currentSite%grow_deg_days(ipft) = currentSite%grow_deg_days(ipft) + & + temp_in_C - phen_gddtemp + end if - !LEAF ON: COLD DECIDUOUS. Needs to - !1) have exceeded the growing degree day threshold - !2) The leaves should not be on already - !3) There should have been at least one chilling day in the counting period. - ! this prevents tropical or warm climate plants that are "cold-deciduous" - ! from ever re-flushing after they have reached their maximum age (thus - ! preventing them from competing + ! This logic is to prevent GDD accumulating after the leaves have fallen and before the + ! beginnning of the accumulation period, to prevend erroneous autumn leaf flushing. + ! We only do this after the first year to prevent odd behaviour. + if ( ( model_day_int > ndays_per_year ) .and. & ! Past the first year + ( model_day_int > currentSite%leafoffdate(ipft) ) .and. & ! Past the abscission date + ( .not. growing_season ) ) then ! Not in the growing season + currentSite%grow_deg_days(ipft) = 0._r8 + end if - if ( any(currentSite%cstatus == [phen_cstat_iscold,phen_cstat_nevercold]) .and. & - (currentSite%grow_deg_days > gdd_threshold) .and. & - (currentSite%cndaysleafoff > ED_val_phen_mindayson) .and. & - (currentSite%nchilldays >= 1)) then - currentSite%cstatus = phen_cstat_notcold ! Set to not-cold status (leaves can come on) - currentSite%cleafondate = model_day_int - currentSite%cndaysleafon = 0 - currentSite%grow_deg_days = 0._r8 ! zero GDD for the rest of the year until counting season begins. - if ( debug ) write(fates_log(),*) 'leaves on' - endif !GDD + ! LEAF ON: COLD DECIDUOUS. Needs to + ! 1) have exceeded the growing degree day threshold + ! 2) The leaves should not be on already + ! 3) There should have been at least one chilling day in the counting period. + ! this prevents tropical or warm climate plants that are "cold-deciduous" + ! from ever re-flushing after they have reached their maximum age (thus + ! preventing them from competing). + if ( any(currentSite%phen_status(ipft) == [phen_cstat_iscold,phen_cstat_nevercold]) .and. & + (currentSite%grow_deg_days(ipft) > gdd_threshold ) .and. & + (currentSite%ndaysleafoff (ipft) > phen_mindaysoff) .and. & + (currentSite%nchilldays(ipft) >= 1)) then + currentSite%phen_status (ipft) = phen_cstat_notcold ! Set to not-cold status (leaves can come on) + currentSite%leafondate (ipft) = model_day_int ! Record flushing date + currentSite%ndaysleafon (ipft) = 0 ! Reset time since flushing + currentSite%grow_deg_days(ipft) = 0._r8 ! zero GDD for the rest of the year until counting season begins. + if ( debug ) write(fates_log(),*) 'leaves on' + end if !GDD - !LEAF OFF: COLD THRESHOLD - !Needs to: - !1) have exceeded the number of cold days threshold - !2) have exceeded the minimum leafon time. - !3) The leaves should not be off already - !4) The day of simulation should be larger than the counting period. - if ( (currentSite%cstatus == phen_cstat_notcold) .and. & - (model_day_int > num_vegtemp_mem) .and. & - (ncolddays > ED_val_phen_ncolddayslim) .and. & - (currentSite%cndaysleafon > ED_val_phen_mindayson) )then - currentSite%grow_deg_days = 0._r8 ! The equations for Botta et al - ! are for calculations of - ! first flush, but if we dont - ! clear this value, it will cause - ! leaves to flush later in the year - currentSite%cstatus = phen_cstat_iscold ! alter status of site to 'leaves off' - currentSite%cleafoffdate = model_day_int ! record leaf off date - currentSite%cndaysleafoff = 0 + ! LEAF OFF: COLD THRESHOLD. Needs to: + ! 1) have exceeded the number of cold days threshold + ! 2) have exceeded the minimum leafon time. + ! 3) The leaves should not be off already + ! 4) The day of simulation should be larger than the counting period. - if ( debug ) write(fates_log(),*) 'leaves off' - endif + if ( (currentSite%phen_status(ipft) == phen_cstat_notcold) .and. & + (model_day_int > num_vegtemp_mem) .and. & + (ncolddays > phen_ncolddayslim) .and. & + (currentSite%ndaysleafon(ipft) > phen_mindayson) )then - ! LEAF OFF: COLD LIFESPAN THRESHOLD - ! NOTE: Some areas of the planet will never generate a cold day - ! and thus %nchilldays will never go from zero to 1. The following logic - ! when coupled with this fact will essentially prevent cold-deciduous - ! plants from re-emerging in areas without at least some cold days - - if( (currentSite%cstatus == phen_cstat_notcold) .and. & - (currentSite%cndaysleafoff > 400)) then ! remove leaves after a whole year, - ! when there is no 'off' period. - currentSite%grow_deg_days = 0._r8 - - currentSite%cstatus = phen_cstat_nevercold ! alter status of site to imply that this - ! site is never really cold enough - ! for cold deciduous - currentSite%cleafoffdate = model_day_int ! record leaf off date - currentSite%cndaysleafoff = 0 - - if ( debug ) write(fates_log(),*) 'leaves off' - endif + ! The equations for Botta et al. (2000) are for calculations of first flush, but if we don't + ! clear this value, it will cause leaves to flush later in the year + ! MLO - I wonder if this wouldn't be desirable in some cases (e.g., recovery from spring frost damage) + currentSite%grow_deg_days(ipft) = 0._r8 + currentSite%phen_status (ipft) = phen_cstat_iscold ! Alter status of site to 'leaves off' + currentSite%leafoffdate (ipft) = model_day_int ! Record abscission date + currentSite%ndaysleafoff (ipft) = 0 ! Reset time since abscission + if ( debug ) write(fates_log(),*) 'leaves off' + end if - ! Loop through every PFT to assign the elongation factor. - ! Add PFT look to account for different PFT rooting depth profiles. - pft_elong_loop: do ipft=1,numpft + ! LEAF OFF: COLD LIFESPAN THRESHOLD. + ! + ! Remove leaves after an entire year has passed and no temperature-driven abscission event + ! ocurred. + ! + ! NOTE: Some areas of the planet will never generate a cold day + ! and thus %nchilldays will never go from zero to 1. The following logic + ! when coupled with this fact will essentially prevent cold-deciduous + ! plants from re-emerging in areas without at least some cold days + + if ( (currentSite%phen_status(ipft) == phen_cstat_notcold) .and. & + (currentSite%ndaysleafoff(ipft) > 400) ) then + currentSite%grow_deg_days(ipft) = 0._r8 ! Reset GDD + currentSite%phen_status (ipft) = phen_cstat_nevercold ! Alter status to imply that this site + ! is never really cold enough for + ! this cold deciduous PFT + currentSite%leafoffdate (ipft) = model_day_int ! Record abscission date + currentSite%ndaysleafoff (ipft) = 0 ! Reset time since abscission + + if ( debug ) write(fates_log(),*) 'leaves off' + end if + end select case_cold_phen - ! Copy values to a local variable to make code more legible. - phen_drought_threshold = prt_params%phen_drought_threshold(ipft) - phen_moist_threshold = prt_params%phen_moist_threshold (ipft) - phen_doff_time = prt_params%phen_doff_time (ipft) + !---~--- + ! HYDRO (STRESS) DECIDUOUS + !---~--- ! Update soil moisture information memory (we always track the last 10 days) @@ -1251,20 +1276,6 @@ subroutine phenology( currentSite, bc_in ) smoist_below_threshold = mean_10day_smp < phen_drought_threshold end if - ! Calculate days since last flushing and shedding event, but make a provision - ! for the first year of simulation, we have to assume leaf drop / leaf flush - ! dates to start, so if that is in the future, set it to last year - if (model_day_int < currentSite%dleafoffdate(ipft)) then - currentSite%dndaysleafoff(ipft) = model_day_int - (currentSite%dleafoffdate(ipft)-ndays_per_year) - else - currentSite%dndaysleafoff(ipft) = model_day_int - currentSite%dleafoffdate(ipft) - end if - if (model_day_int < currentSite%dleafondate(ipft)) then - currentSite%dndaysleafon(ipft) = model_day_int - (currentSite%dleafondate(ipft)-ndays_per_year) - else - currentSite%dndaysleafon(ipft) = model_day_int - currentSite%dleafondate(ipft) - end if - ! Elongation factor from the previous step. elongf_prev = currentSite%elong_factor(ipft) @@ -1314,27 +1325,27 @@ subroutine phenology( currentSite, bc_in ) !---~--- ! Leaves have been "on" for longer than the minimum number of days. exceed_min_on_period = & - any( currentSite%dstatus(ipft) == [phen_dstat_timeon,phen_dstat_moiston] ) .and. & - (currentSite%dndaysleafon(ipft) > dleafon_drycheck) + any( currentSite%phen_status(ipft) == [phen_dstat_timeon,phen_dstat_moiston] ) .and. & + ( currentSite%ndaysleafon(ipft) > phen_mindayson ) ! Leaves have been "off" for longer than the minimum number of days. exceed_min_off_period = & - ( currentSite%dstatus(ipft) == phen_dstat_timeoff ) .and. & - ( currentSite%dndaysleafoff(ipft) > min_daysoff_dforcedflush ) + ( currentSite%phen_status(ipft) == phen_dstat_timeoff ) .and. & + ( currentSite%ndaysleafoff(ipft) > min_daysoff_dforcedflush ) ! Leaves have been "on" for longer than the leaf lifetime. prolonged_on_period = & - any( currentSite%dstatus(ipft) == [phen_dstat_timeon,phen_dstat_moiston] ) .and. & - ( currentSite%dndaysleafon(ipft) > ndays_pft_leaf_lifespan ) + any( currentSite%phen_status(ipft) == [phen_dstat_timeon,phen_dstat_moiston] ) .and. & + ( currentSite%ndaysleafon(ipft) > ndays_pft_leaf_lifespan ) ! Leaves have been "off" for a sufficiently long time and the last flushing ! was about one year ago (+/- tolerance). prolonged_off_period = & - any( currentSite%dstatus(ipft) == [phen_dstat_timeoff,phen_dstat_moistoff] ) .and. & - ( currentSite%dndaysleafoff(ipft) > phen_doff_time ) .and. & - ( currentSite%dndaysleafon(ipft) >= ndays_per_year-dd_offon_toler ) .and. & - ( currentSite%dndaysleafon(ipft) <= ndays_per_year+dd_offon_toler ) + any( currentSite%phen_status(ipft) == [phen_dstat_timeoff,phen_dstat_moistoff] ) .and. & + ( currentSite%ndaysleafoff(ipft) > phen_mindaysoff ) .and. & + ( currentSite%ndaysleafon(ipft) >= ndays_per_year-dd_offon_toler ) .and. & + ( currentSite%ndaysleafon(ipft) <= ndays_per_year+dd_offon_toler ) ! Last flushing was a very long time ago. last_flush_long_ago = & - ( currentSite%dstatus(ipft) == phen_dstat_moistoff ) .and. & - ( currentSite%dndaysleafon(ipft) > ndays_per_year+dd_offon_toler ) + ( currentSite%phen_status(ipft) == phen_dstat_moistoff ) .and. & + ( currentSite%ndaysleafon(ipft) > ndays_per_year+dd_offon_toler ) !---~--- @@ -1353,9 +1364,9 @@ subroutine phenology( currentSite, bc_in ) ! a) a year, plus or minus 1 month since we last had leaf-on? ! b) Has there also been at least a nominaly short amount of "leaf-off"? ! c) Is the soil moisture sufficiently high? - currentSite%dstatus(ipft) = phen_dstat_moiston ! set status to leaf-on - currentSite%dleafondate(ipft) = model_day_int ! save the model day we start flushing - currentSite%dndaysleafon(ipft) = 0 + currentSite%phen_status(ipft) = phen_dstat_moiston ! set status to leaf-on + currentSite%leafondate(ipft) = model_day_int ! save the model day we start flushing + currentSite%ndaysleafon(ipft) = 0 currentSite%elong_factor(ipft) = 1. elseif ( last_flush_long_ago ) then @@ -1367,9 +1378,9 @@ subroutine phenology( currentSite, bc_in ) ! So we trigger bud-burst at the end of the month since ! last year's bud-burst. If this is imposed, then we set the new ! status to indicate bud-burst was forced by timing - currentSite%dstatus(ipft) = phen_dstat_timeon ! force budburst! - currentSite%dleafondate(ipft) = model_day_int ! record leaf on date - currentSite%dndaysleafon(ipft) = 0 + currentSite%phen_status(ipft) = phen_dstat_timeon ! force budburst! + currentSite%leafondate(ipft) = model_day_int ! record leaf on date + currentSite%ndaysleafon(ipft) = 0 currentSite%elong_factor(ipft) = 1. elseif ( exceed_min_off_period ) then @@ -1377,26 +1388,26 @@ subroutine phenology( currentSite, bc_in ) ! Leaves were off due to time, not really moisture, so we allow them to ! flush again as soon as they exceed a minimum off time ! This typically occurs in a perennially wet system. - currentSite%dstatus(ipft) = phen_dstat_timeon ! force budburst! - currentSite%dleafondate(ipft) = model_day_int ! record leaf on date - currentSite%dndaysleafon(ipft) = 0 + currentSite%phen_status(ipft) = phen_dstat_timeon ! force budburst! + currentSite%leafondate(ipft) = model_day_int ! record leaf on date + currentSite%ndaysleafon(ipft) = 0 currentSite%elong_factor(ipft) = 1. elseif ( prolonged_on_period ) then ! LEAF OFF: DROUGHT DECIDUOUS LIFESPAN ! Are the leaves rouhgly at the end of their lives? If so, shed leaves ! even if it is not dry. - currentSite%dstatus(ipft) = phen_dstat_timeoff !alter status of site to 'leaves off' - currentSite%dleafoffdate(ipft) = model_day_int !record leaf on date - currentSite%dndaysleafoff(ipft) = 0 + currentSite%phen_status(ipft) = phen_dstat_timeoff !alter status of site to 'leaves off' + currentSite%leafoffdate(ipft) = model_day_int !record leaf on date + currentSite%ndaysleafoff(ipft) = 0 currentSite%elong_factor(ipft) = 0. elseif ( exceed_min_on_period .and. smoist_below_threshold ) then ! LEAF OFF: DROUGHT DECIDUOUS DRYNESS - if the soil gets too dry, ! and the leaves have already been on a while... - currentSite%dstatus(ipft) = phen_dstat_moistoff ! alter status of site to 'leaves off' - currentSite%dleafoffdate(ipft) = model_day_int ! record leaf on date - currentSite%dndaysleafoff(ipft) = 0 + currentSite%phen_status(ipft) = phen_dstat_moistoff ! alter status of site to 'leaves off' + currentSite%leafoffdate(ipft) = model_day_int ! record leaf on date + currentSite%ndaysleafoff(ipft) = 0 currentSite%elong_factor(ipft) = 0. end if drought_smoist_ifelse end if past_spinup_ifelse @@ -1435,16 +1446,16 @@ subroutine phenology( currentSite, bc_in ) !---~--- ! Leaves have been flushing for a short period of time. recent_flush = elongf_prev >= elongf_min .and. & - ( currentSite%dndaysleafon(ipft) <= dleafon_drycheck ) + ( currentSite%ndaysleafon(ipft) <= phen_mindayson ) ! Leaves have been abscissing for a short period of time. recent_abscission = elongf_prev < elongf_min .and. & - ( currentSite%dndaysleafoff(ipft) <= min_daysoff_dforcedflush ) + ( currentSite%ndaysleafoff(ipft) <= min_daysoff_dforcedflush ) ! Leaves have been flushing for longer than their time span. prolonged_on_period = all( [elongf_prev,elongf_1st] >= elongf_min ) .and. & - ( currentSite%dndaysleafon(ipft) > ndays_pft_leaf_lifespan ) + ( currentSite%ndaysleafon(ipft) > ndays_pft_leaf_lifespan ) ! It's been a long time since the plants had flushed their leaves. last_flush_long_ago = all( [elongf_prev,elongf_1st] < elongf_min ) .and. & - ( currentSite%dndaysleafon(ipft) > ndays_per_year+dd_offon_toler ) + ( currentSite%ndaysleafon(ipft) > ndays_per_year+dd_offon_toler ) !---~--- @@ -1456,26 +1467,26 @@ subroutine phenology( currentSite, bc_in ) elseif ( prolonged_on_period ) then ! Leaves have been on for too long and exceeded leaf lifespan. Force abscission currentSite%elong_factor(ipft) = 0.0_r8 ! Force full budburst - currentSite%dstatus(ipft) = phen_dstat_timeoff ! Flag that this has been forced - currentSite%dleafoffdate(ipft) = model_day_int ! Record leaf off date - currentSite%dndaysleafoff(ipft) = 0 ! Reset clock + currentSite%phen_status(ipft) = phen_dstat_timeoff ! Flag that this has been forced + currentSite%leafoffdate(ipft) = model_day_int ! Record leaf off date + currentSite%ndaysleafoff(ipft) = 0 ! Reset clock elseif ( last_flush_long_ago ) then ! Plant has not flushed at all for a very long time. Force flushing currentSite%elong_factor(ipft) = elongf_min ! Force minimum budburst - currentSite%dstatus(ipft) = phen_dstat_timeon ! Flag that this has been forced - currentSite%dleafondate(ipft) = model_day_int ! Record leaf on date - currentSite%dndaysleafon(ipft) = 0 ! Reset clock + currentSite%phen_status(ipft) = phen_dstat_timeon ! Flag that this has been forced + currentSite%leafondate(ipft) = model_day_int ! Record leaf on date + currentSite%ndaysleafon(ipft) = 0 ! Reset clock elseif ( recent_flush .and. elongf_1st < elongf_prev ) then ! Leaves have only recently reached flushed status. Elongation factor cannot decrease currentSite%elong_factor(ipft) = elongf_prev ! Elongation factor cannot decrease - currentSite%dstatus(ipft) = phen_dstat_timeon ! Flag that this has been forced + currentSite%phen_status(ipft) = phen_dstat_timeon ! Flag that this has been forced elseif ( recent_abscission .and. elongf_1st > elongf_min ) then ! Leaves have only recently abscissed. Prevent plant to flush leaves. currentSite%elong_factor(ipft) = 0.0_r8 ! Elongation factor must remain 0. - currentSite%dstatus(ipft) = phen_dstat_timeoff ! Flag that this has been forced + currentSite%phen_status(ipft) = phen_dstat_timeoff ! Flag that this has been forced elseif ( elongf_1st < elongf_min ) then ! First guess of elongation factor below minimum. Impose full abscission. @@ -1483,9 +1494,9 @@ subroutine phenology( currentSite, bc_in ) if (elongf_prev >= elongf_min ) then ! This is the first day moisture fell below minimum. Flag change of status. - currentSite%dstatus(ipft) = phen_dstat_moistoff ! Flag that this has not been forced - currentSite%dleafoffdate(ipft) = model_day_int ! Record leaf off date - currentSite%dndaysleafoff(ipft) = 0 ! Reset clock + currentSite%phen_status(ipft) = phen_dstat_moistoff ! Flag that this has not been forced + currentSite%leafoffdate(ipft) = model_day_int ! Record leaf off date + currentSite%ndaysleafoff(ipft) = 0 ! Reset clock end if else @@ -1495,11 +1506,11 @@ subroutine phenology( currentSite, bc_in ) if (elongf_prev < elongf_min ) then ! This is the first day moisture allows leaves to exist. Flag change of status. - currentSite%dstatus(ipft) = phen_dstat_moiston ! Flag that this has not been forced - currentSite%dleafondate(ipft) = model_day_int ! Record leaf on date - currentSite%dndaysleafon(ipft) = 0 ! Reset clock + currentSite%phen_status(ipft) = phen_dstat_moiston ! Flag that this has not been forced + currentSite%leafondate(ipft) = model_day_int ! Record leaf on date + currentSite%ndaysleafon(ipft) = 0 ! Reset clock elseif (elongf_1st < elongf_prev) then - currentSite%dstatus(ipft) = phen_dstat_pshed ! Flag partial shedding, + currentSite%phen_status(ipft) = phen_dstat_pshed ! Flag partial shedding, ! but do not reset the clock end if end if drought_gradual_ifelse @@ -1510,7 +1521,7 @@ subroutine phenology( currentSite, bc_in ) ! of non-drought deciduous. In the future we may consider other drought deciduous ! strategies (e.g., abscission driven by moisture, flushing driven by photo- ! period). - currentSite%dstatus(ipft) = phen_dstat_moiston + currentSite%phen_status(ipft) = phen_dstat_moiston ! Assign elongation factors for non-drought deciduous PFTs, which will be used ! to define the cohort status. @@ -1520,7 +1531,7 @@ subroutine phenology( currentSite, bc_in ) currentSite%elong_factor(ipft) = 1.0_r8 case (ihard_season_decid) ! Cold-deciduous. Define elongation factor based on cold status - select case (currentSite%cstatus) + select case (currentSite%phen_status(ipft)) case (phen_cstat_nevercold,phen_cstat_iscold) currentSite%elong_factor(ipft) = 0.0_r8 case (phen_cstat_notcold) @@ -1621,10 +1632,10 @@ subroutine phenology_leafonoff(currentSite) case (ihard_season_decid) ! Cold deciduous ! A. Is this the time for COLD LEAVES to switch to ON? - is_flushing_time = ( currentSite%cstatus == phen_cstat_notcold .and. & ! We just moved to leaves being on + is_flushing_time = ( currentSite%phen_status(ipft) == phen_cstat_notcold .and. & ! We just moved to leaves being on currentCohort%status_coh == leaves_off ) ! Leaves are currently off ! B. Is this the time for COLD LEAVES to switch to OFF? - is_shedding_time = any(currentSite%cstatus == [phen_cstat_nevercold,phen_cstat_iscold]) .and. & ! Past leaf drop day or too cold + is_shedding_time = any(currentSite%phen_status(ipft) == [phen_cstat_nevercold,phen_cstat_iscold]) .and. & ! Past leaf drop day or too cold currentCohort%status_coh == leaves_on .and. & ! Leaves have not dropped yet ( currentCohort%dbh > EDPftvarcon_inst%phen_cold_size_threshold(ipft) .or. & ! Grasses are big enough or... prt_params%woody(ipft) == itrue ) ! this is a woody PFT. @@ -1632,11 +1643,11 @@ subroutine phenology_leafonoff(currentSite) case (ihard_stress_decid,isemi_stress_decid) ! Drought deciduous ! A. Is this the time for DROUGHT LEAVES to switch to ON? - is_flushing_time = any( currentSite%dstatus(ipft) == [phen_dstat_moiston,phen_dstat_timeon] ) .and. & ! Leaf flushing time (moisture or time) + is_flushing_time = any( currentSite%phen_status(ipft) == [phen_dstat_moiston,phen_dstat_timeon] ) .and. & ! Leaf flushing time (moisture or time) any( currentCohort%status_coh == [leaves_off,leaves_shedding] ) ! B. Is this the time for DROUGHT LEAVES to switch to OFF? ! This will be true when leaves are abscissing (partially or fully) due to moisture or time - is_shedding_time = any( currentSite%dstatus(ipft) == [phen_dstat_moistoff,phen_dstat_timeoff,phen_dstat_pshed] ) .and. & + is_shedding_time = any( currentSite%phen_status(ipft) == [phen_dstat_moistoff,phen_dstat_timeoff,phen_dstat_pshed] ) .and. & any( currentCohort%status_coh == [leaves_on,leaves_shedding] ) case (ievergreen) ! This PFT is not deciduous. @@ -2352,7 +2363,7 @@ subroutine SeedDecay( litt , currentPatch, bc_in ) end subroutine SeedDecay ! ============================================================================ - subroutine SeedGermination( litt, cold_stat, drought_stat, bc_in, currentPatch ) + subroutine SeedGermination( litt, phen_stat, bc_in, currentPatch ) ! ! !DESCRIPTION: ! Flux from seed bank into the seedling pool @@ -2362,8 +2373,7 @@ subroutine SeedGermination( litt, cold_stat, drought_stat, bc_in, currentPatch ) ! ! !ARGUMENTS type(litter_type) :: litt - integer , intent(in) :: cold_stat ! Is the site in cold leaf-off status? - integer, dimension(numpft), intent(in) :: drought_stat ! Is the site in drought leaf-off status? + integer, dimension(numpft), intent(in) :: phen_stat ! Phenological status type(bc_in_type), intent(in) :: bc_in type(fates_patch_type), intent(in) :: currentPatch ! @@ -2576,7 +2586,7 @@ subroutine recruitment(currentSite, currentPatch, bc_in) ! look for cases in which leaves should be off select case (prt_params%phen_leaf_habit(ft)) case (ihard_season_decid) - select case(currentSite%cstatus) + select case(currentSite%phen_status(pft)) case (phen_cstat_nevercold, phen_cstat_iscold) ! If the plant is seasonally (cold) deciduous, and the site status is flagged ! as "cold", then set the cohort's status to leaves_off. diff --git a/main/EDInitMod.F90 b/main/EDInitMod.F90 index 314a93adbd..d391dbee6b 100644 --- a/main/EDInitMod.F90 +++ b/main/EDInitMod.F90 @@ -53,6 +53,7 @@ module EDInitMod use EDTypesMod , only : phen_dstat_moistoff use EDTypesMod , only : phen_cstat_notcold use EDTypesMod , only : phen_dstat_moiston + use EDTypesMod , only : phen_estat_evergreen use FatesInterfaceTypesMod , only : bc_in_type,bc_out_type use FatesInterfaceTypesMod , only : hlm_use_planthydro use FatesInterfaceTypesMod , only : hlm_use_inventory_init @@ -264,20 +265,15 @@ subroutine zero_site( site_in ) ! PHENOLOGY - site_in%cstatus = fates_unset_int ! are leaves in this pixel on or off? - site_in%dstatus(:) = fates_unset_int - site_in%grow_deg_days = nan ! growing degree days + site_in%phen_status(:) = fates_unset_int ! are leaves in this pixel on or off? + site_in%grow_deg_days(:) = nan ! growing degree days site_in%snow_depth = nan - site_in%nchilldays = fates_unset_int - site_in%ncolddays = fates_unset_int - site_in%cleafondate = fates_unset_int ! doy of leaf on (cold) - site_in%cleafoffdate = fates_unset_int ! doy of leaf off (cold) - site_in%dleafondate(:) = fates_unset_int ! doy of leaf on (drought) - site_in%dleafoffdate(:) = fates_unset_int ! doy of leaf off (drought) - site_in%cndaysleafon = fates_unset_int ! days since leaf on (cold) - site_in%cndaysleafoff = fates_unset_int ! days since leaf off (cold) - site_in%dndaysleafon(:) = fates_unset_int ! days since leaf on (drought) - site_in%dndaysleafoff(:) = fates_unset_int ! days since leaf off (drought) + site_in%nchilldays(:) = fates_unset_int ! number of chilling days + site_in%ncolddays(:) = fates_unset_int ! number of cold days + site_in%leafondate(:) = fates_unset_int ! doy of last leaf flushing event + site_in%leafoffdate(:) = fates_unset_int ! doy of last leaf abscission event + site_in%ndaysleafon(:) = fates_unset_int ! days since last leaf flushing + site_in%ndaysleafoff(: ) = fates_unset_int ! days since last leaf abscission site_in%elong_factor(:) = nan ! Elongation factor (0 - full abscission; 1 - fully flushed) site_in%liqvol_memory(:,:) = nan @@ -396,6 +392,7 @@ subroutine set_site_properties( nsites, sites,bc_in ) ! ! !LOCAL VARIABLES: integer :: s + integer :: estat ! evergreen phenology flag integer :: cstat ! cold status phenology flag real(r8) :: GDD integer :: dstat ! drought status phenology flag @@ -427,15 +424,16 @@ subroutine set_site_properties( nsites, sites,bc_in ) if ( hlm_is_restart == ifalse ) then - GDD = 30.0_r8 - cleafon = 100 - cleafoff = 300 + GDD = 30.0_r8 + cleafon = 100 + cleafoff = 300 cndleafon = 0 cndleafoff = 0 - cstat = phen_cstat_notcold ! Leaves are on - dstat = phen_dstat_moiston ! Leaves are on - dleafoff = 300 - dleafon = 100 + estat = phen_estat_evergreen + cstat = phen_cstat_notcold ! Leaves are on + dstat = phen_dstat_moiston ! Leaves are on + dleafoff = 300 + dleafon = 100 dndleafon = 0 dndleafoff = 0 liqvolmem = 0.5_r8 @@ -443,28 +441,52 @@ subroutine set_site_properties( nsites, sites,bc_in ) elong_factor = 1._r8 do s = 1,nsites - sites(s)%nchilldays = 0 - sites(s)%ncolddays = 0 ! recalculated in phenology + sites(s)%nchilldays(1:numpft) = 0 + sites(s)%ncolddays(1:numpft) = 0 ! recalculated in phenology ! immediately, so yes this ! is memory-less, but needed ! for first value in history file sites(s)%phen_model_date = 0 - sites(s)%cleafondate = cleafon - hlm_day_of_year - sites(s)%cleafoffdate = cleafoff - hlm_day_of_year - sites(s)%cndaysleafon = cndleafon - sites(s)%cndaysleafoff = cndleafoff - sites(s)%dleafoffdate (1:numpft) = dleafoff - hlm_day_of_year - sites(s)%dleafondate (1:numpft) = dleafon - hlm_day_of_year - sites(s)%dndaysleafon (1:numpft) = dndleafon - sites(s)%dndaysleafoff(1:numpft) = dndleafoff - sites(s)%grow_deg_days = GDD + sites(s)%grow_deg_days(1:numpft) = GDD sites(s)%liqvol_memory(1:numWaterMem,1:numpft) = liqvolmem sites(s)%smp_memory(1:numWaterMem,1:numpft) = smpmem sites(s)%vegtemp_memory(1:num_vegtemp_mem) = 0._r8 - sites(s)%cstatus = cstat - sites(s)%dstatus(1:numpft) = dstat + do ft = 1, numpft + ! These must be updated once the new parameter is integrated to FATES. + select case (prt_params%evergreen(ft)) + case (itrue) + ! Evergreens. These variables are not used, set them to any state + sites(s)%phen_status (ft) = estat + sites(s)%leafondate (ft) = cleafon - hlm_day_of_year + sites(s)%leafoffdate (ft) = cleafoff - hlm_day_of_year + sites(s)%ndaysleafon (ft) = 0 + sites(s)%ndaysleafoff(ft) = 0 + end select + + select case (prt_params%season_decid(ft)) + case (itrue) + ! Cold deciduous + sites(s)%phen_status (ft) = cstat + sites(s)%leafondate (ft) = cleafon - hlm_day_of_year + sites(s)%leafoffdate (ft) = cleafoff - hlm_day_of_year + sites(s)%ndaysleafon (ft) = cndleafon + sites(s)%ndaysleafoff(ft) = cndleafoff + end select + + + select case (prt_params%stress_decid(ft)) + case (ihard_stress_decid,isemi_stress_decid) + ! Drought deciduous + sites(s)%phen_status (ft) = dstat + sites(s)%leafondate (ft) = dleafon - hlm_day_of_year + sites(s)%leafoffdate (ft) = dleafoff - hlm_day_of_year + sites(s)%ndaysleafon (ft) = dndleafon + sites(s)%ndaysleafoff(ft) = dndleafoff + end select + end do + sites(s)%elong_factor(1:numpft) = elong_factor sites(s)%NF = 0.0_r8 @@ -1148,7 +1170,7 @@ subroutine init_cohorts(site_in, patch_in, bc_in) ! use built-in phenology phen_select: select case (prt_params%phen_leaf_habit(pft)) case (ihard_season_decid) - if ( any(site_in%cstatus == [phen_cstat_nevercold, phen_cstat_iscold]) ) then + if ( any(site_in%phen_status(pft) == [phen_cstat_nevercold, phen_cstat_iscold]) ) then ! Cold deciduous, off season, assume complete abscission efleaf_coh = 0.0_r8 effnrt_coh = 1.0_r8 - fnrt_drop_fraction diff --git a/main/EDMainMod.F90 b/main/EDMainMod.F90 index bfba6d7d56..8de5bc265d 100644 --- a/main/EDMainMod.F90 +++ b/main/EDMainMod.F90 @@ -553,7 +553,7 @@ subroutine ed_integrate_state_variables(currentSite, bc_in, bc_out ) ! Conduct Maintenance Turnover (parteh) if(debug) call currentCohort%prt%CheckMassConservation(ft,3) - if(any(currentSite%dstatus(ft) == [phen_dstat_moiston,phen_dstat_timeon])) then + if(any(currentSite%phen_status(ft) == [phen_dstat_moiston,phen_dstat_timeon])) then is_drought = .false. else is_drought = .true. diff --git a/main/EDParamsMod.F90 b/main/EDParamsMod.F90 index b90b547dad..10567c1e86 100644 --- a/main/EDParamsMod.F90 +++ b/main/EDParamsMod.F90 @@ -52,13 +52,6 @@ module EDParamsMod real(r8),protected, public :: ED_val_cwd_fcel ! Cellulose fraction for CWD real(r8),protected, public :: ED_val_cwd_flig ! Lignin fraction of coarse woody debris real(r8),protected, public :: maintresp_nonleaf_baserate ! Base maintenance respiration rate for plant tissues - real(r8),protected, public :: ED_val_phen_a ! GDD accumulation function, intercept parameter: gdd_thesh = a + b exp(c*ncd) - real(r8),protected, public :: ED_val_phen_b ! GDD accumulation function, multiplier parameter: gdd_thesh = a + b exp(c*ncd) - real(r8),protected, public :: ED_val_phen_c ! GDD accumulation function, exponent parameter: gdd_thesh = a + b exp(c*ncd) - real(r8),protected, public :: ED_val_phen_chiltemp ! chilling day counting threshold for vegetation - real(r8),protected, public :: ED_val_phen_mindayson ! day threshold compared against days since leaves became on-allometry - real(r8),protected, public :: ED_val_phen_ncolddayslim ! day threshold exceedance for temperature leaf-drop - real(r8),protected, public :: ED_val_phen_coldtemp ! vegetation temperature exceedance that flags a cold-day for leaf-drop real(r8),protected, public :: ED_val_cohort_size_fusion_tol ! minimum fraction in difference in dbh between cohorts real(r8),protected, public :: ED_val_cohort_age_fusion_tol ! minimum fraction in differece in cohort age between cohorts real(r8),protected, public :: ED_val_patch_fusion_tol ! minimum fraction in difference in profiles between patches @@ -141,13 +134,6 @@ module EDParamsMod character(len=param_string_length),parameter,public :: ED_name_cwd_fcel= "fates_frag_cwd_fcel" character(len=param_string_length),parameter,public :: ED_name_cwd_flig= "fates_frag_cwd_flig" character(len=param_string_length),parameter,public :: fates_name_maintresp_nonleaf_baserate= "fates_maintresp_nonleaf_baserate" - character(len=param_string_length),parameter,public :: ED_name_phen_a= "fates_phen_gddthresh_a" - character(len=param_string_length),parameter,public :: ED_name_phen_b= "fates_phen_gddthresh_b" - character(len=param_string_length),parameter,public :: ED_name_phen_c= "fates_phen_gddthresh_c" - character(len=param_string_length),parameter,public :: ED_name_phen_chiltemp= "fates_phen_chilltemp" - character(len=param_string_length),parameter,public :: ED_name_phen_mindayson= "fates_phen_mindayson" - character(len=param_string_length),parameter,public :: ED_name_phen_ncolddayslim= "fates_phen_ncolddayslim" - character(len=param_string_length),parameter,public :: ED_name_phen_coldtemp= "fates_phen_coldtemp" character(len=param_string_length),parameter,public :: ED_name_cohort_size_fusion_tol= "fates_cohort_size_fusion_tol" character(len=param_string_length),parameter,public :: ED_name_cohort_age_fusion_tol = "fates_cohort_age_fusion_tol" character(len=param_string_length),parameter,public :: ED_name_patch_fusion_tol= "fates_patch_fusion_tol" @@ -310,13 +296,6 @@ subroutine FatesParamsInit() ED_val_cwd_fcel = nan ED_val_cwd_flig = nan maintresp_nonleaf_baserate = nan - ED_val_phen_a = nan - ED_val_phen_b = nan - ED_val_phen_c = nan - ED_val_phen_chiltemp = nan - ED_val_phen_mindayson = nan - ED_val_phen_ncolddayslim = nan - ED_val_phen_coldtemp = nan ED_val_cohort_size_fusion_tol = nan ED_val_cohort_age_fusion_tol = nan ED_val_patch_fusion_tol = nan @@ -422,27 +401,6 @@ subroutine FatesRegisterParams(fates_params) call fates_params%RegisterParameter(name=fates_name_maintresp_nonleaf_baserate, dimension_shape=dimension_shape_scalar, & dimension_names=dim_names_scalar) - call fates_params%RegisterParameter(name=ED_name_phen_a, dimension_shape=dimension_shape_scalar, & - dimension_names=dim_names_scalar) - - call fates_params%RegisterParameter(name=ED_name_phen_b, dimension_shape=dimension_shape_scalar, & - dimension_names=dim_names_scalar) - - call fates_params%RegisterParameter(name=ED_name_phen_c, dimension_shape=dimension_shape_scalar, & - dimension_names=dim_names_scalar) - - call fates_params%RegisterParameter(name=ED_name_phen_chiltemp, dimension_shape=dimension_shape_scalar, & - dimension_names=dim_names_scalar) - - call fates_params%RegisterParameter(name=ED_name_phen_mindayson, dimension_shape=dimension_shape_scalar, & - dimension_names=dim_names_scalar) - - call fates_params%RegisterParameter(name=ED_name_phen_ncolddayslim, dimension_shape=dimension_shape_scalar, & - dimension_names=dim_names_scalar) - - call fates_params%RegisterParameter(name=ED_name_phen_coldtemp, dimension_shape=dimension_shape_scalar, & - dimension_names=dim_names_scalar) - call fates_params%RegisterParameter(name=ED_name_cohort_size_fusion_tol, dimension_shape=dimension_shape_scalar, & dimension_names=dim_names_scalar) @@ -632,27 +590,6 @@ subroutine FatesReceiveParams(fates_params) call fates_params%RetrieveParameter(name=fates_name_maintresp_nonleaf_baserate, & data=maintresp_nonleaf_baserate) - call fates_params%RetrieveParameter(name=ED_name_phen_a, & - data=ED_val_phen_a) - - call fates_params%RetrieveParameter(name=ED_name_phen_b, & - data=ED_val_phen_b) - - call fates_params%RetrieveParameter(name=ED_name_phen_c, & - data=ED_val_phen_c) - - call fates_params%RetrieveParameter(name=ED_name_phen_chiltemp, & - data=ED_val_phen_chiltemp) - - call fates_params%RetrieveParameter(name=ED_name_phen_mindayson, & - data=ED_val_phen_mindayson) - - call fates_params%RetrieveParameter(name=ED_name_phen_ncolddayslim, & - data=ED_val_phen_ncolddayslim) - - call fates_params%RetrieveParameter(name=ED_name_phen_coldtemp, & - data=ED_val_phen_coldtemp) - call fates_params%RetrieveParameter(name=ED_name_cohort_size_fusion_tol, & data=ED_val_cohort_size_fusion_tol) @@ -832,13 +769,6 @@ subroutine FatesReportParams(is_master) write(fates_log(),fmt0) 'ED_val_cwd_fcel = ',ED_val_cwd_fcel write(fates_log(),fmt0) 'ED_val_cwd_flig = ',ED_val_cwd_flig write(fates_log(),fmt0) 'fates_maintresp_nonleaf_baserate = ', maintresp_nonleaf_baserate - write(fates_log(),fmt0) 'ED_val_phen_a = ',ED_val_phen_a - write(fates_log(),fmt0) 'ED_val_phen_b = ',ED_val_phen_b - write(fates_log(),fmt0) 'ED_val_phen_c = ',ED_val_phen_c - write(fates_log(),fmt0) 'ED_val_phen_chiltemp = ',ED_val_phen_chiltemp - write(fates_log(),fmt0) 'ED_val_phen_mindayson = ',ED_val_phen_mindayson - write(fates_log(),fmt0) 'ED_val_phen_ncolddayslim = ',ED_val_phen_ncolddayslim - write(fates_log(),fmt0) 'ED_val_phen_coldtemp = ',ED_val_phen_coldtemp write(fates_log(),fmt0) 'ED_val_cohort_size_fusion_tol = ',ED_val_cohort_size_fusion_tol write(fates_log(),fmt0) 'ED_val_cohort_age_fusion_tol = ',ED_val_cohort_age_fusion_tol write(fates_log(),fmt0) 'ED_val_patch_fusion_tol = ',ED_val_patch_fusion_tol diff --git a/main/EDTypesMod.F90 b/main/EDTypesMod.F90 index 701a95eeb2..1e0b382252 100644 --- a/main/EDTypesMod.F90 +++ b/main/EDTypesMod.F90 @@ -93,18 +93,21 @@ module EDTypesMod ! BIOLOGY/BIOGEOCHEMISTRY integer , parameter, public :: num_vegtemp_mem = 10 ! Window of time over which we track temp for cold sensecence (days) - ! Phenology status flag definitions (cold type is cstat, dry type is dstat) - - integer, parameter, public :: phen_cstat_nevercold = 0 ! This (location/plant) has not experienced a cold period over a large number - ! of days, leaves are dropped and flagged as non-cold region - integer, parameter, public :: phen_cstat_iscold = 1 ! This (location/plant) is in a cold-state where leaves should have fallen - integer, parameter, public :: phen_cstat_notcold = 2 ! This site is in a warm-state where leaves are allowed to flush - - integer, parameter, public :: phen_dstat_timeoff = 0 ! Leaves off due to time exceedance (drought phenology) - integer, parameter, public :: phen_dstat_moistoff = 1 ! Leaves off due to moisture avail (drought phenology) - integer, parameter, public :: phen_dstat_moiston = 2 ! Leaves on due to moisture avail (drought phenology) - integer, parameter, public :: phen_dstat_timeon = 3 ! Leaves on due to time exceedance (drought phenology) - integer, parameter, public :: phen_dstat_pshed = 4 ! Leaves partially abscissing (drought phenology) + ! Phenology status flag definitions (cold type is cstat, dry type is dstat). + ! MLO - Now that the phenology status is shared across both cold and drought deciduous, make sure these indices are unique + ! The default phen_estat_evergreen is a dummy value reserved for evergreen PFTs. + + integer, parameter, public :: phen_estat_evergreen = 0 ! This PFT is evergreen. + integer, parameter, public :: phen_cstat_nevercold = 1 ! This (location/plant) has not experienced a cold period over a large number + ! of days, leaves are dropped and flagged as non-cold region + integer, parameter, public :: phen_cstat_iscold = 2 ! This (location/plant) is in a cold-state where leaves should have fallen + integer, parameter, public :: phen_cstat_notcold = 3 ! This site is in a warm-state where leaves are allowed to flush + + integer, parameter, public :: phen_dstat_timeoff = 4 ! Leaves off due to time exceedance (drought phenology) + integer, parameter, public :: phen_dstat_moistoff = 5 ! Leaves off due to moisture avail (drought phenology) + integer, parameter, public :: phen_dstat_moiston = 6 ! Leaves on due to moisture avail (drought phenology) + integer, parameter, public :: phen_dstat_timeon = 7 ! Leaves on due to time exceedance (drought phenology) + integer, parameter, public :: phen_dstat_pshed = 8 ! Leaves partially abscissing (drought phenology) ! PATCH FUSION real(r8), parameter, public :: force_patchfuse_min_biomass = 0.005_r8 ! min biomass (kg / m2 patch area) below which to force-fuse patches @@ -413,40 +416,37 @@ module EDTypesMod ! PHENOLOGY - real(r8) :: grow_deg_days ! Phenology growing degree days real(r8) :: snow_depth ! site-level snow depth (used for ELAI/TLAI calcs) - integer :: cstatus ! are leaves in this pixel on or off for cold decid - ! 0 = this site has not experienced a cold period over at least + real(r8), dimension(maxpft) :: grow_deg_days ! Phenology growing degree days + integer, dimension(maxpft) :: phen_status ! Phenology status of this PFT. This is shared by all + ! phenology habits: + ! 0 = this is an evergreen PFT + ! 1 = this site has not experienced a cold period over at least ! 400 days, leaves are dropped and flagged as non-cold region - ! 1 = this site is in a cold-state where leaves should have fallen - ! 2 = this site is in a warm-state where leaves are allowed to flush - integer :: dstatus(maxpft) ! are leaves in this pixel on or off for drought decid - ! 0 = leaves off due to time exceedance - ! 1 = leaves off due to moisture avail - ! 2 = leaves on due to moisture avail - ! 3 = leaves on due to time exceedance - ! 4 = leaves partially on (ED2-like phenology) - integer :: nchilldays ! num chilling days: (for botta gdd trheshold calculation) - integer :: ncolddays ! num cold days: (must exceed threshold to drop leaves) - real(r8) :: vegtemp_memory(num_vegtemp_mem) ! record of last 10 days temperature for senescence model. deg C - integer :: cleafondate ! model date (day integer) of leaf on (cold):- - integer :: cleafoffdate ! model date (day integer) of leaf off (cold):- - integer :: cndaysleafon ! number of days since leaf on period started (cold) - integer :: cndaysleafoff ! number of days since leaf off period started (cold) - integer :: dleafondate(maxpft) ! model date (day integer) of leaf on drought:- - integer :: dleafoffdate(maxpft) ! model date (day integer) of leaf off drought:- - integer :: dndaysleafon(maxpft) ! number of days since leaf on period started (drought) - integer :: dndaysleafoff(maxpft) ! number of days since leaf off period started (drought) - real(r8) :: elong_factor(maxpft) ! Elongation factor (ED2-like phenology). This is zero when leaves are + ! 2 = this site is in a cold-state where leaves should have fallen + ! 3 = this site is in a warm-state where leaves are allowed to flush + ! 4 = leaves off due to time exceedance + ! 5 = leaves off due to moisture avail + ! 6 = leaves on due to moisture avail + ! 7 = leaves on due to time exceedance + ! 8 = leaves partially on (ED2-like phenology) + integer, dimension(maxpft) :: nchilldays ! Number of chilling days (for Botta's GDD trheshold calculation) + integer, dimension(maxpft) :: ncolddays ! Number of cold days (for temperature-driven leaf abscission) + real(r8), dimension(num_vegtemp_mem) :: vegtemp_memory ! record of last 10 days temperature for senescence model. deg C + integer, dimension(maxpft) :: leafondate ! Model date (day integer) of last leaf flushing event + integer, dimension(maxpft) :: leafoffdate ! Model date (day integer) of last leaf abscission event + integer, dimension(maxpft) :: ndaysleafon ! Number of days since last leaf flushing event + integer, dimension(maxpft) :: ndaysleafoff ! Number of days since last leaf abscission event + real(r8), dimension(maxpft) :: elong_factor ! Elongation factor (ED2-like phenology). This is zero when leaves are ! completely off, and one when they are completely flushed. integer :: phen_model_date ! current model date (day integer) ! this date stays continuous when ! in runs that are restarted, regardless of ! the conditions of restart - real(r8) :: liqvol_memory(numWaterMem,maxpft) ! last 10 days of soil liquid water volume (drought phenology) - real(r8) :: smp_memory(numWaterMem,maxpft) ! last 10 days of soil matric potential (drought phenology) + real(r8), dimension(numWaterMem,maxpft) :: liqvol_memory ! last 10 days of soil liquid water volume (drought phenology) + real(r8), dimension(numWaterMem,maxpft) :: smp_memory ! last 10 days of soil matric potential (drought phenology) ! FIRE diff --git a/main/FatesHistoryInterfaceMod.F90 b/main/FatesHistoryInterfaceMod.F90 index 86d3bbeddb..7b45e47723 100644 --- a/main/FatesHistoryInterfaceMod.F90 +++ b/main/FatesHistoryInterfaceMod.F90 @@ -56,7 +56,6 @@ module FatesHistoryInterfaceMod use FatesInterfaceTypesMod , only : hlm_parteh_mode use FatesInterfaceTypesMod , only : hlm_use_sp use EDParamsMod , only : ED_val_comp_excln - use EDParamsMod , only : ED_val_phen_coldtemp use EDParamsMod , only : nlevleaf use EDParamsMod , only : ED_val_history_height_bin_edges use EDParamsMod , only : ED_val_history_ageclass_bin_edges @@ -438,13 +437,6 @@ module FatesHistoryInterfaceMod integer :: ih_h2oveg_hydro_err_si integer :: ih_lai_si integer :: ih_elai_si - - integer :: ih_site_cstatus_si - integer :: ih_gdd_si - integer :: ih_site_nchilldays_si - integer :: ih_site_ncolddays_si - integer :: ih_cleafoff_si - integer :: ih_cleafon_si integer :: ih_nesterov_fire_danger_si integer :: ih_fire_nignitions_si @@ -627,9 +619,12 @@ module FatesHistoryInterfaceMod integer :: ih_crownarea_si_cnlf integer :: ih_gpp_si_pft integer :: ih_npp_si_pft - integer :: ih_site_dstatus_si_pft - integer :: ih_dleafoff_si_pft - integer :: ih_dleafon_si_pft + integer :: ih_site_phen_status_si_pft + integer :: ih_gdd_si_pft + integer :: ih_site_nchilldays_si_pft + integer :: ih_site_ncolddays_si_pft + integer :: ih_leafoff_si_pft + integer :: ih_leafon_si_pft integer :: ih_meanliqvol_si_pft integer :: ih_meansmp_si_pft integer :: ih_elong_factor_si_pft @@ -2472,12 +2467,6 @@ subroutine update_history_dyn_sitelevel(this,nc,nsites,sites,bc_in) hio_canopy_mortality_carbonflux_si => this%hvars(ih_canopy_mortality_carbonflux_si)%r81d, & hio_ustory_mortality_carbonflux_si => this%hvars(ih_understory_mortality_carbonflux_si)%r81d, & hio_woodproduct_si => this%hvars(ih_woodproduct_si)%r81d, & - hio_gdd_si => this%hvars(ih_gdd_si)%r81d, & - hio_site_ncolddays_si => this%hvars(ih_site_ncolddays_si)%r81d, & - hio_site_nchilldays_si => this%hvars(ih_site_nchilldays_si)%r81d, & - hio_site_cstatus_si => this%hvars(ih_site_cstatus_si)%r81d, & - hio_cleafoff_si => this%hvars(ih_cleafoff_si)%r81d, & - hio_cleafon_si => this%hvars(ih_cleafon_si)%r81d, & hio_cbal_err_fates_si => this%hvars(ih_cbal_err_fates_si)%r81d, & hio_tveg24 => this%hvars(ih_tveg24_si)%r81d, & hio_tlongterm => this%hvars(ih_tlongterm_si)%r81d, & @@ -2531,20 +2520,6 @@ subroutine update_history_dyn_sitelevel(this,nc,nsites,sites,bc_in) ! Canopy spread index (0-1) hio_canopy_spread_si(io_si) = sites(s)%spread - ! Update the site status for cold deciduous (drought deciduous is now PFT dependent) - hio_site_cstatus_si(io_si) = real(sites(s)%cstatus,r8) - - ! Number of chill days and cold days - hio_site_nchilldays_si(io_si) = real(sites(s)%nchilldays,r8) - hio_site_ncolddays_si(io_si) = real(sites(s)%ncolddays,r8) - - ! Growing degree-days - hio_gdd_si(io_si) = sites(s)%grow_deg_days - - ! Model days elapsed since leaf on/off for cold-deciduous - hio_cleafoff_si(io_si) = real(sites(s)%phen_model_date - sites(s)%cleafoffdate,r8) - hio_cleafon_si(io_si) = real(sites(s)%phen_model_date - sites(s)%cleafondate,r8) - ! track total wood product accumulation at the site level hio_woodproduct_si(io_si) = sites(s)%resources_management%trunk_product_site & * AREA_INV @@ -3079,8 +3054,6 @@ subroutine update_history_dyn_subsite(this,nc,nsites,sites,bc_in) real(r8) :: storep_understory_scpf(numpft*nlevsclass) real(r8) :: storec_canopy_scpf(numpft*nlevsclass) real(r8) :: storec_understory_scpf(numpft*nlevsclass) - real(r8) :: a_sapw ! sapwood area [m^2] - real(r8) :: c_sapw ! sapwood biomass [kgC] integer :: i_dist, j_dist @@ -3263,9 +3236,13 @@ subroutine update_history_dyn_subsite(this,nc,nsites,sites,bc_in) hio_crownarea_cl => this%hvars(ih_crownarea_cl)%r82d) ! Break up associates for NAG compilers - associate( hio_site_dstatus_si_pft => this%hvars(ih_site_dstatus_si_pft)%r82d, & - hio_dleafoff_si_pft => this%hvars(ih_dleafoff_si_pft)%r82d, & - hio_dleafon_si_pft => this%hvars(ih_dleafon_si_pft)%r82d, & + associate( & + hio_gdd_si_pft => this%hvars(ih_gdd_si_pft)%r82d, & + hio_site_ncolddays_si_pft => this%hvars(ih_site_ncolddays_si_pft)%r82d, & + hio_site_nchilldays_si_pft => this%hvars(ih_site_nchilldays_si_pft)%r82d, & + hio_site_phen_status_si_pft => this%hvars(ih_site_phen_status_si_pft)%r82d, & + hio_leafoff_si_pft => this%hvars(ih_leafoff_si_pft)%r82d, & + hio_leafon_si_pft => this%hvars(ih_leafon_si_pft)%r82d, & hio_meanliqvol_si_pft => this%hvars(ih_meanliqvol_si_pft)%r82d, & hio_meansmp_si_pft => this%hvars(ih_meansmp_si_pft)%r82d, & hio_elong_factor_si_pft => this%hvars(ih_elong_factor_si_pft)%r82d, & @@ -3342,14 +3319,22 @@ subroutine update_history_dyn_subsite(this,nc,nsites,sites,bc_in) end do - ! Update drought deciduous information (now separated by PFT). + ! Update deciduous information (now separated by PFT). do ft = 1,numpft - ! Update the site-PFT status for drought deciduous - hio_site_dstatus_si_pft(io_si,ft) = real(sites(s)%dstatus(ft),r8) - ! Model days elapsed since leaf off/on for drought deciduous - hio_dleafoff_si_pft(io_si,ft) = real(sites(s)%dndaysleafon (ft),r8) - hio_dleafon_si_pft(io_si,ft) = real(sites(s)%dndaysleafoff(ft),r8) + ! Update the site phenological status for this PFT + hio_site_phen_status_si_pft(io_si,ft) = real(sites(s)%phen_status(ft),r8) + + ! Number of chill days and cold days + hio_site_nchilldays_si_pft(io_si,ft) = real(sites(s)%nchilldays(ft),r8) + hio_site_ncolddays_si_pft(io_si,ft) = real(sites(s)%ncolddays(ft),r8) + + ! Growing degree-days + hio_gdd_si_pft(io_si,ft) = sites(s)%grow_deg_days(ft) + + ! Model days elapsed since leaf on/off for deciduous + hio_leafoff_si_pft(io_si,ft) = real(sites(s)%ndaysleafoff(ft),r8) + hio_leafon_si_pft(io_si,ft) = real(sites(s)%ndaysleafon (ft),r8) ! Leaf elongation factor (0 means fully abscissed, 1 means fully flushed). hio_elong_factor_si_pft(io_si,ft) = sites(s)%elong_factor(ft) @@ -6290,41 +6275,6 @@ subroutine define_history_vars(this, initialize_variables) upfreq=group_dyna_simple, ivar=ivar, initialize=initialize_variables, & index=ih_ca_weighted_height_si) - call this%set_history_var(vname='FATES_COLD_STATUS', units='', & - long='site-level cold status, 0=not cold-dec, 1=too cold for leaves, 2=not too cold', & - use_default='active', avgflag='A', vtype=site_r8, hlms='CLM:ALM', & - upfreq=group_dyna_simple, ivar=ivar, initialize=initialize_variables, & - index=ih_site_cstatus_si) - - call this%set_history_var(vname='FATES_GDD', units='degree_Celsius', & - long='site-level growing degree days', use_default='active', & - avgflag='A', vtype=site_r8, hlms='CLM:ALM', & - upfreq=group_dyna_simple, ivar=ivar, initialize=initialize_variables, index=ih_gdd_si) - - call this%set_history_var(vname='FATES_NCHILLDAYS', units = 'days', & - long='site-level number of chill days', use_default='active', & - avgflag='A', vtype=site_r8, hlms='CLM:ALM', & - upfreq=group_dyna_simple, ivar=ivar, initialize=initialize_variables, & - index=ih_site_nchilldays_si) - - call this%set_history_var(vname='FATES_NCOLDDAYS', units = 'days', & - long='site-level number of cold days', use_default='active', & - avgflag='A', vtype=site_r8, hlms='CLM:ALM', & - upfreq=group_dyna_simple, ivar=ivar, initialize=initialize_variables, & - index=ih_site_ncolddays_si) - - call this%set_history_var(vname='FATES_DAYSINCE_COLDLEAFOFF', & - units='days', long='site-level days elapsed since cold leaf drop', & - use_default='active', avgflag='A', vtype=site_r8, hlms='CLM:ALM', & - upfreq=group_dyna_simple, ivar=ivar, initialize=initialize_variables, & - index=ih_cleafoff_si) - - call this%set_history_var(vname='FATES_DAYSINCE_COLDLEAFON', & - units='days', long='site-level days elapsed since cold leaf flush', & - use_default='active', avgflag='A', vtype=site_r8, hlms='CLM:ALM', & - upfreq=group_dyna_simple, ivar=ivar, initialize=initialize_variables, & - index=ih_cleafon_si) - call this%set_history_var(vname='FATES_CANOPY_SPREAD', units='', & long='scaling factor (0-1) between tree basal area and canopy area', & use_default='active', avgflag='A', vtype=site_r8, hlms='CLM:ALM', & @@ -7065,26 +7015,43 @@ subroutine define_history_vars(this, initialize_variables) upfreq=group_dyna_complx, ivar=ivar, initialize=initialize_variables, & index=ih_mortality_si_pft) - !MLO - Drought-deciduous phenology variables are now defined for each PFT. - call this%set_history_var(vname='FATES_DROUGHT_STATUS_PF', & - units='', & - long='PFT-level drought status, <2 too dry for leaves, >=2 not too dry', & - use_default='active', avgflag='A', vtype=site_pft_r8, hlms='CLM:ALM', & - upfreq=group_dyna_complx, ivar=ivar, initialize=initialize_variables, & - index=ih_site_dstatus_si_pft) - - call this%set_history_var(vname='FATES_DAYSINCE_DROUGHTLEAFOFF_PF', & - units='days', long='PFT-level days elapsed since drought leaf drop', & - use_default='active', avgflag='A', vtype=site_pft_r8, hlms='CLM:ALM', & - upfreq=group_dyna_complx, ivar=ivar, initialize=initialize_variables, & - index=ih_dleafoff_si_pft) + !MLO - Phenology variables are now defined for each PFT. - call this%set_history_var(vname='FATES_DAYSINCE_DROUGHTLEAFON_PF', & - units='days', & - long='PFT-level days elapsed since drought leaf flush', & + call this%set_history_var(vname='FATES_PHEN_STATUS_PF', units='', & + long='Phenology status: 0 evergreen; 1 never cold; 2 cold state; 3 warm state; 4 forced abscission;'// & + ' 5 dry state; 6 moist state; 7 forced flush; 8 partial abscission', & use_default='active', avgflag='A', vtype=site_pft_r8, hlms='CLM:ALM', & - upfreq=group_dyna_complx, ivar=ivar, initialize=initialize_variables, & - index=ih_dleafon_si_pft) + upfreq=group_dyna_simple, ivar=ivar, initialize=initialize_variables, & + index=ih_site_phen_status_si_pft) + + call this%set_history_var(vname='FATES_GDD_PF', units='degree_Celsius', & + long='PFT-level growing degree days', use_default='active', & + avgflag='A', vtype=site_pft_r8, hlms='CLM:ALM', & + upfreq=group_dyna_simple, ivar=ivar, initialize=initialize_variables, index=ih_gdd_si_pft) + + call this%set_history_var(vname='FATES_NCHILLDAYS_PF', units = 'days', & + long='PFT-level number of chill days', use_default='active', & + avgflag='A', vtype=site_pft_r8, hlms='CLM:ALM', & + upfreq=group_dyna_simple, ivar=ivar, initialize=initialize_variables, & + index=ih_site_nchilldays_si_pft) + + call this%set_history_var(vname='FATES_NCOLDDAYS_PF', units = 'days', & + long='PFT-level number of cold days', use_default='active', & + avgflag='A', vtype=site_pft_r8, hlms='CLM:ALM', & + upfreq=group_dyna_simple, ivar=ivar, initialize=initialize_variables, & + index=ih_site_ncolddays_si_pft) + + call this%set_history_var(vname='FATES_DAYSINCE_LEAFOFF_PF', & + units='days', long='PFT-level days elapsed since last leaf abscission event', & + use_default='active', avgflag='A', vtype=site_pft_r8, hlms='CLM:ALM', & + upfreq=group_dyna_simple, ivar=ivar, initialize=initialize_variables, & + index=ih_leafoff_si_pft) + + call this%set_history_var(vname='FATES_DAYSINCE_LEAFON_PF', & + units='days', long='PFT-level days elapsed since last leaf flushing event', & + use_default='active', avgflag='A', vtype=site_pft_r8, hlms='CLM:ALM', & + upfreq=group_dyna_simple, ivar=ivar, initialize=initialize_variables, & + index=ih_leafon_si_pft) call this%set_history_var(vname='FATES_MEANLIQVOL_DROUGHTPHEN_PF', & units='m3 m-3', & @@ -8895,6 +8862,13 @@ subroutine define_history_vars(this, initialize_variables) ! over the short timestep. We turn off these variables when we want ! to save time (and some space) + call this%set_history_var(vname='FATES_NPP_AP', units='kg m-2 s-1', & + long='net primary productivity by age bin in kg carbon per m2 per second'// & + this%per_ageclass_norm_info('FATES_PATCHAREA/FATES_PATCHAREA_AP'), & + use_default='inactive', avgflag='A', vtype=site_age_r8, & + hlms='CLM:ALM', upfreq=group_hifr_complx, ivar=ivar, initialize=initialize_variables, & + index = ih_npp_si_age) + call this%set_history_var(vname='FATES_GPP_AP', units='kg m-2 s-1', & long='gross primary productivity by age bin in kg carbon per m2 per second'// & this%per_ageclass_norm_info('FATES_PATCHAREA/FATES_PATCHAREA_AP'), & diff --git a/main/FatesInventoryInitMod.F90 b/main/FatesInventoryInitMod.F90 index 6673f4b819..59894c2cbf 100644 --- a/main/FatesInventoryInitMod.F90 +++ b/main/FatesInventoryInitMod.F90 @@ -971,6 +971,15 @@ subroutine set_inventory_cohort_type1(csite,bc_in,css_file_unit,npatches, & fnrt_drop_fraction = prt_params%phen_fnrt_drop_fraction(temp_cohort%pft) stem_drop_fraction = prt_params%phen_stem_drop_fraction(temp_cohort%pft) +<<<<<<< HEAD + if( prt_params%season_decid(temp_cohort%pft) == itrue .and. & + any(csite%phen_status(temp_cohort%pft) == [phen_cstat_nevercold,phen_cstat_iscold])) then + ! Cold deciduous and season is for leaves off. Set leaf status and + ! elongation factors accordingly + temp_cohort%efleaf_coh = 0.0_r8 + temp_cohort%effnrt_coh = 1._r8 - fnrt_drop_fraction + temp_cohort%efstem_coh = 1._r8 - stem_drop_fraction +======= phen_select: select case (prt_params%phen_leaf_habit(temp_cohort%pft)) case (ihard_season_decid) if ( any(csite%cstatus == [phen_cstat_nevercold,phen_cstat_iscold]) ) then @@ -987,6 +996,7 @@ subroutine set_inventory_cohort_type1(csite,bc_in,css_file_unit,npatches, & temp_cohort%efstem_coh = 1.0_r8 temp_cohort%status_coh = leaves_on end if +>>>>>>> api40 case (ihard_stress_decid,isemi_stress_decid) ! Drought deciduous. For the default approach, elongation factor is either diff --git a/main/FatesRestartInterfaceMod.F90 b/main/FatesRestartInterfaceMod.F90 index f2c78051a1..0a86af6af4 100644 --- a/main/FatesRestartInterfaceMod.F90 +++ b/main/FatesRestartInterfaceMod.F90 @@ -96,16 +96,8 @@ module FatesRestartInterfaceMod ! Indices to the restart variable object integer :: ir_npatch_si - integer :: ir_cd_status_si - integer :: ir_nchill_days_si - integer :: ir_ncold_days_si - integer :: ir_cleafondate_si - integer :: ir_cleafoffdate_si - integer :: ir_cndaysleafon_si - integer :: ir_cndaysleafoff_si integer :: ir_phenmodeldate_si integer :: ir_fireweather_index_si - integer :: ir_gdd_si integer :: ir_min_allowed_landuse_fraction_si integer :: ir_landuse_vector_gt_min_si integer :: ir_area_bareground_si @@ -225,11 +217,14 @@ module FatesRestartInterfaceMod integer :: ir_litter_moisture_pa_nfsc ! Site level - integer :: ir_dd_status_sift - integer :: ir_dleafondate_sift - integer :: ir_dleafoffdate_sift - integer :: ir_dndaysleafon_sift - integer :: ir_dndaysleafoff_sift + integer :: ir_phen_status_sift + integer :: ir_nchill_days_sift + integer :: ir_ncold_days_sift + integer :: ir_leafondate_sift + integer :: ir_leafoffdate_sift + integer :: ir_ndaysleafon_sift + integer :: ir_ndaysleafoff_sift + integer :: ir_gdd_sift integer :: ir_elong_factor_sift integer :: ir_liqvolmem_siwmft integer :: ir_smpmem_siwmft @@ -683,34 +678,6 @@ subroutine define_restart_vars(this, initialize_variables) long_name='Total number of FATES patches per column', units='none', flushval = flushinvalid, & hlms='CLM:ALM', initialize=initialize_variables, ivar=ivar, index = ir_npatch_si ) - call this%set_restart_var(vname='fates_cold_dec_status', vtype=site_int, & - long_name='status flag for cold deciduous plants', units='unitless', flushval = flushinvalid, & - hlms='CLM:ALM', initialize=initialize_variables, ivar=ivar, index = ir_cd_status_si ) - - call this%set_restart_var(vname='fates_chilling_days', vtype=site_int, & - long_name='chilling day counter', units='unitless', flushval = flushinvalid, & - hlms='CLM:ALM', initialize=initialize_variables, ivar=ivar, index = ir_nchill_days_si ) - - call this%set_restart_var(vname='fates_cold_days', vtype=site_int, & - long_name='cold day counter', units='unitless', flushval = flushinvalid, & - hlms='CLM:ALM', initialize=initialize_variables, ivar=ivar, index = ir_ncold_days_si ) - - call this%set_restart_var(vname='fates_cold_leafondate', vtype=site_int, & - long_name='the model day of last cold leaf on', units='absolute integer day', flushval = flushinvalid, & - hlms='CLM:ALM', initialize=initialize_variables, ivar=ivar, index = ir_cleafondate_si ) - - call this%set_restart_var(vname='fates_cold_leafoffdate', vtype=site_int, & - long_name='the model day last cold leaf off', units='absolute integer day', flushval = flushinvalid, & - hlms='CLM:ALM', initialize=initialize_variables, ivar=ivar, index = ir_cleafoffdate_si ) - - call this%set_restart_var(vname='fates_cold_ndaysleafon', vtype=site_int, & - long_name='number of days since leaf on (cold deciduous)', units='days', flushval = flushinvalid, & - hlms='CLM:ALM', initialize=initialize_variables, ivar=ivar, index = ir_cndaysleafon_si ) - - call this%set_restart_var(vname='fates_cold_ndaysleafoff', vtype=site_int, & - long_name='number of days since leaf off (cold deciduous)', units='days', flushval = flushinvalid, & - hlms='CLM:ALM', initialize=initialize_variables, ivar=ivar, index = ir_cndaysleafoff_si ) - call this%set_restart_var(vname='fates_phen_model_date', vtype=site_int, & long_name='integer model day used for phen timing', units='absolute integer day', flushval = flushinvalid, & hlms='CLM:ALM', initialize=initialize_variables, ivar=ivar, index = ir_phenmodeldate_si ) @@ -719,10 +686,6 @@ subroutine define_restart_vars(this, initialize_variables) long_name='a nesterov index accumulator', units='unitless', flushval = flushzero, & hlms='CLM:ALM', initialize=initialize_variables, ivar=ivar, index = ir_fireweather_index_si ) - call this%set_restart_var(vname='fates_gdd_site', vtype=site_r8, & - long_name='growing degree days at each site', units='degC days', flushval = flushzero, & - hlms='CLM:ALM', initialize=initialize_variables, ivar=ivar, index = ir_gdd_si ) - call this%set_restart_var(vname='fates_min_allowed_landuse_fraction_site', vtype=site_r8, & long_name='minimum allowed land use fraction at each site', units='fraction', flushval = flushzero, & hlms='CLM:ALM', initialize=initialize_variables, ivar=ivar, index = ir_min_allowed_landuse_fraction_si ) @@ -1304,25 +1267,37 @@ subroutine define_restart_vars(this, initialize_variables) ! site x time level vars ! - call this%set_restart_var(vname='fates_drought_dec_status', vtype=cohort_int, & - long_name='status flag for drought deciduous plants', units='unitless', flushval = flushinvalid, & - hlms='CLM:ALM', initialize=initialize_variables, ivar=ivar, index = ir_dd_status_sift ) + call this%set_restart_var(vname='fates_phen_status', vtype=site_int, & + long_name='phenology status flag', units='unitless', flushval = flushinvalid, & + hlms='CLM:ALM', initialize=initialize_variables, ivar=ivar, index = ir_phen_status_sift ) + + call this%set_restart_var(vname='fates_chilling_days', vtype=site_int, & + long_name='chilling day counter', units='unitless', flushval = flushinvalid, & + hlms='CLM:ALM', initialize=initialize_variables, ivar=ivar, index = ir_nchill_days_sift ) + + call this%set_restart_var(vname='fates_cold_days', vtype=site_int, & + long_name='cold day counter', units='unitless', flushval = flushinvalid, & + hlms='CLM:ALM', initialize=initialize_variables, ivar=ivar, index = ir_ncold_days_sift ) - call this%set_restart_var(vname='fates_drought_leafondate', vtype=cohort_int, & - long_name='the day of year for drought based leaf-on', units='day of year', flushval = flushinvalid, & - hlms='CLM:ALM', initialize=initialize_variables, ivar=ivar, index = ir_dleafondate_sift ) + call this%set_restart_var(vname='fates_phen_leafondate', vtype=site_int, & + long_name='the model day of last leaf flushing event', units='absolute integer day', flushval = flushinvalid, & + hlms='CLM:ALM', initialize=initialize_variables, ivar=ivar, index = ir_leafondate_sift ) - call this%set_restart_var(vname='fates_drought_leafoffdate', vtype=cohort_int, & - long_name='the day of year for drought based leaf-off', units='day of year', flushval = flushinvalid, & - hlms='CLM:ALM', initialize=initialize_variables, ivar=ivar, index = ir_dleafoffdate_sift ) + call this%set_restart_var(vname='fates_phen_leafoffdate', vtype=site_int, & + long_name='the model day last leaf abscission event', units='absolute integer day', flushval = flushinvalid, & + hlms='CLM:ALM', initialize=initialize_variables, ivar=ivar, index = ir_leafoffdate_sift ) - call this%set_restart_var(vname='fates_drought_ndaysleafon', vtype=cohort_int, & - long_name='number of days since leaf on (drought deciduous)', units='days', flushval = flushinvalid, & - hlms='CLM:ALM', initialize=initialize_variables, ivar=ivar, index = ir_dndaysleafon_sift ) + call this%set_restart_var(vname='fates_phen_ndaysleafon', vtype=site_int, & + long_name='number of days since last leaf flushing event', units='days', flushval = flushinvalid, & + hlms='CLM:ALM', initialize=initialize_variables, ivar=ivar, index = ir_ndaysleafon_sift ) - call this%set_restart_var(vname='fates_drought_ndaysleafoff', vtype=cohort_int, & - long_name='number of days since leaf off (drought deciduous)', units='days', flushval = flushinvalid, & - hlms='CLM:ALM', initialize=initialize_variables, ivar=ivar, index = ir_dndaysleafoff_sift ) + call this%set_restart_var(vname='fates_phen_ndaysleafoff', vtype=site_int, & + long_name='number of days since last leaf abscission event', units='days', flushval = flushinvalid, & + hlms='CLM:ALM', initialize=initialize_variables, ivar=ivar, index = ir_ndaysleafoff_sift ) + + call this%set_restart_var(vname='fates_gdd_site', vtype=site_r8, & + long_name='growing degree days at each site', units='degC days', flushval = flushzero, & + hlms='CLM:ALM', initialize=initialize_variables, ivar=ivar, index = ir_gdd_sift ) call this%set_restart_var(vname='fates_elong_factor', vtype=cohort_r8, & long_name='leaf elongation factor (0 - completely abscissed; 1 - completely flushed)', units='unitless', flushval = flushinvalid, & @@ -2104,16 +2079,8 @@ subroutine set_restart_vectors(this,nc,nsites,sites) associate( rio_npatch_si => this%rvars(ir_npatch_si)%int1d, & - rio_cd_status_si => this%rvars(ir_cd_status_si)%int1d, & - rio_nchill_days_si => this%rvars(ir_nchill_days_si)%int1d, & - rio_ncold_days_si => this%rvars(ir_ncold_days_si)%int1d, & - rio_cleafondate_si => this%rvars(ir_cleafondate_si)%int1d, & - rio_cleafoffdate_si => this%rvars(ir_cleafoffdate_si)%int1d, & - rio_cndaysleafon_si => this%rvars(ir_cndaysleafon_si)%int1d, & - rio_cndaysleafoff_si => this%rvars(ir_cndaysleafoff_si)%int1d, & rio_phenmodeldate_si => this%rvars(ir_phenmodeldate_si)%int1d, & rio_fireweather_index_si => this%rvars(ir_fireweather_index_si)%r81d, & - rio_gdd_si => this%rvars(ir_gdd_si)%r81d, & rio_min_allowed_landuse_fraction_si => this%rvars(ir_min_allowed_landuse_fraction_si)%r81d, & rio_landuse_vector_gt_min_si => this%rvars(ir_landuse_vector_gt_min_si)%int1d, & rio_area_bareground_si => this%rvars(ir_area_bareground_si)%r81d, & @@ -2170,11 +2137,14 @@ subroutine set_restart_vectors(this,nc,nsites,sites) rio_agesinceanthrodist_pa => this%rvars(ir_agesinceanthrodist_pa)%r81d, & rio_nocomp_pft_label_pa => this%rvars(ir_nocomp_pft_label_pa)%int1d, & rio_area_pa => this%rvars(ir_area_pa)%r81d, & - rio_dd_status_sift => this%rvars(ir_dd_status_sift)%int1d, & - rio_dleafondate_sift => this%rvars(ir_dleafondate_sift)%int1d, & - rio_dleafoffdate_sift => this%rvars(ir_dleafoffdate_sift)%int1d, & - rio_dndaysleafon_sift => this%rvars(ir_dndaysleafon_sift)%int1d, & - rio_dndaysleafoff_sift => this%rvars(ir_dndaysleafoff_sift)%int1d, & + rio_phen_status_sift => this%rvars(ir_phen_status_sift)%int1d, & + rio_nchill_days_sift => this%rvars(ir_nchill_days_sift)%int1d, & + rio_ncold_days_sift => this%rvars(ir_ncold_days_sift)%int1d, & + rio_leafondate_sift => this%rvars(ir_leafondate_sift)%int1d, & + rio_leafoffdate_sift => this%rvars(ir_leafoffdate_sift)%int1d, & + rio_ndaysleafon_sift => this%rvars(ir_ndaysleafon_sift)%int1d, & + rio_ndaysleafoff_sift => this%rvars(ir_ndaysleafoff_sift)%int1d, & + rio_gdd_sift => this%rvars(ir_gdd_sift)%r81d, & rio_elong_factor_sift => this%rvars(ir_elong_factor_sift)%r81d, & rio_liqvolmem_siwmft => this%rvars(ir_liqvolmem_siwmft)%r81d, & rio_smpmem_siwmft => this%rvars(ir_smpmem_siwmft)%r81d, & @@ -2324,14 +2294,19 @@ subroutine set_restart_vectors(this,nc,nsites,sites) rio_fmortcflux_cano_sipft(io_idx_si_pft) = sites(s)%fmort_carbonflux_canopy(i_pft) rio_fmortcflux_usto_sipft(io_idx_si_pft) = sites(s)%fmort_carbonflux_ustory(i_pft) rio_imortcflux_sipft(io_idx_si_pft) = sites(s)%imort_carbonflux(i_pft) - rio_dd_status_sift(io_idx_si_pft) = sites(s)%dstatus(i_pft) - rio_dleafondate_sift(io_idx_si_pft) = sites(s)%dleafondate(i_pft) - rio_dleafoffdate_sift(io_idx_si_pft) = sites(s)%dleafoffdate(i_pft) - rio_dndaysleafon_sift(io_idx_si_pft) = sites(s)%dndaysleafon(i_pft) - rio_dndaysleafoff_sift(io_idx_si_pft) = sites(s)%dndaysleafoff(i_pft) + + rio_phen_status_sift(io_idx_si_pft) = sites(s)%phen_status(i_pft) + rio_nchill_days_sift(io_idx_si_pft) = sites(s)%nchilldays(i_pft) + rio_ncold_days_sift(io_idx_si_pft) = sites(s)%ncolddays(i_pft) + rio_leafondate_sift(io_idx_si_pft) = sites(s)%leafondate(i_pft) + rio_leafoffdate_sift(io_idx_si_pft) = sites(s)%leafoffdate(i_pft) + rio_ndaysleafon_sift(io_idx_si_pft) = sites(s)%ndaysleafon(i_pft) + rio_ndaysleafoff_sift(io_idx_si_pft) = sites(s)%ndaysleafoff(i_pft) + rio_gdd_sift(io_idx_si_pft) = sites(s)%grow_deg_days(i_pft) rio_elong_factor_sift(io_idx_si_pft) = sites(s)%elong_factor(i_pft) rio_seed_in_sift(io_idx_si_pft) = sites(s)%seed_in(i_pft) - rio_seed_out_sift(io_idx_si_pft) = sites(s)%seed_out(i_pft) + rio_seed_out_sift(io_idx_si_pft) = sites(s)%seed_out(i_pft) + io_idx_si_pft = io_idx_si_pft + 1 end do @@ -2728,14 +2703,6 @@ subroutine set_restart_vectors(this,nc,nsites,sites) rio_fmortcarea_cano_si(io_idx_si) = sites(s)%fmort_crownarea_canopy rio_fmortcarea_usto_si(io_idx_si) = sites(s)%fmort_crownarea_ustory - rio_cd_status_si(io_idx_si) = sites(s)%cstatus - rio_nchill_days_si(io_idx_si) = sites(s)%nchilldays - rio_ncold_days_si(io_idx_si) = sites(s)%ncolddays - rio_cleafondate_si(io_idx_si) = sites(s)%cleafondate - rio_cleafoffdate_si(io_idx_si) = sites(s)%cleafoffdate - rio_cndaysleafon_si(io_idx_si) = sites(s)%cndaysleafon - rio_cndaysleafoff_si(io_idx_si) = sites(s)%cndaysleafoff - rio_gdd_si(io_idx_si) = sites(s)%grow_deg_days rio_phenmodeldate_si(io_idx_si) = sites(s)%phen_model_date rio_solar_zenith_angle(io_idx_si) = sites(s)%coszen @@ -3102,16 +3069,8 @@ subroutine get_restart_vectors(this, nc, nsites, sites) integer :: i_term_type ! loop counter for termination type associate( rio_npatch_si => this%rvars(ir_npatch_si)%int1d, & - rio_cd_status_si => this%rvars(ir_cd_status_si)%int1d, & - rio_nchill_days_si => this%rvars(ir_nchill_days_si)%int1d, & - rio_ncold_days_si => this%rvars(ir_ncold_days_si)%int1d, & - rio_cleafondate_si => this%rvars(ir_cleafondate_si)%int1d, & - rio_cleafoffdate_si => this%rvars(ir_cleafoffdate_si)%int1d, & - rio_cndaysleafon_si => this%rvars(ir_cndaysleafon_si)%int1d, & - rio_cndaysleafoff_si => this%rvars(ir_cndaysleafoff_si)%int1d, & rio_phenmodeldate_si => this%rvars(ir_phenmodeldate_si)%int1d, & rio_fireweather_index_si => this%rvars(ir_fireweather_index_si)%r81d, & - rio_gdd_si => this%rvars(ir_gdd_si)%r81d, & rio_min_allowed_landuse_fraction_si => this%rvars(ir_min_allowed_landuse_fraction_si)%r81d, & rio_landuse_vector_gt_min_si => this%rvars(ir_landuse_vector_gt_min_si)%int1d, & rio_area_bareground_si => this%rvars(ir_area_bareground_si)%r81d, & @@ -3168,11 +3127,14 @@ subroutine get_restart_vectors(this, nc, nsites, sites) rio_agesinceanthrodist_pa => this%rvars(ir_agesinceanthrodist_pa)%r81d, & rio_nocomp_pft_label_pa => this%rvars(ir_nocomp_pft_label_pa)%int1d, & rio_area_pa => this%rvars(ir_area_pa)%r81d, & - rio_dd_status_sift => this%rvars(ir_dd_status_sift)%int1d, & - rio_dleafondate_sift => this%rvars(ir_dleafondate_sift)%int1d, & - rio_dleafoffdate_sift => this%rvars(ir_dleafoffdate_sift)%int1d, & - rio_dndaysleafon_sift => this%rvars(ir_dndaysleafon_sift)%int1d, & - rio_dndaysleafoff_sift => this%rvars(ir_dndaysleafoff_sift)%int1d, & + rio_phen_status_sift => this%rvars(ir_phen_status_sift)%int1d, & + rio_nchill_days_sift => this%rvars(ir_nchill_days_sift)%int1d, & + rio_ncold_days_sift => this%rvars(ir_ncold_days_sift)%int1d, & + rio_leafondate_sift => this%rvars(ir_leafondate_sift)%int1d, & + rio_leafoffdate_sift => this%rvars(ir_leafoffdate_sift)%int1d, & + rio_ndaysleafon_sift => this%rvars(ir_ndaysleafon_sift)%int1d, & + rio_ndaysleafoff_sift => this%rvars(ir_ndaysleafoff_sift)%int1d, & + rio_gdd_sift => this%rvars(ir_gdd_sift)%r81d, & rio_elong_factor_sift => this%rvars(ir_elong_factor_sift)%r81d, & rio_liqvolmem_siwmft => this%rvars(ir_liqvolmem_siwmft)%r81d, & rio_smpmem_siwmft => this%rvars(ir_smpmem_siwmft)%r81d, & @@ -3309,11 +3271,14 @@ subroutine get_restart_vectors(this, nc, nsites, sites) sites(s)%fmort_carbonflux_canopy(i_pft) = rio_fmortcflux_cano_sipft(io_idx_si_pft) sites(s)%fmort_carbonflux_ustory(i_pft) = rio_fmortcflux_usto_sipft(io_idx_si_pft) sites(s)%imort_carbonflux(i_pft) = rio_imortcflux_sipft(io_idx_si_pft) - sites(s)%dstatus(i_pft) = rio_dd_status_sift(io_idx_si_pft) - sites(s)%dleafondate(i_pft) = rio_dleafondate_sift(io_idx_si_pft) - sites(s)%dleafoffdate(i_pft) = rio_dleafoffdate_sift(io_idx_si_pft) - sites(s)%dndaysleafon(i_pft) = rio_dndaysleafon_sift(io_idx_si_pft) - sites(s)%dndaysleafoff(i_pft) = rio_dndaysleafoff_sift(io_idx_si_pft) + sites(s)%phen_status(i_pft) = rio_phen_status_sift(io_idx_si_pft) + sites(s)%nchilldays(i_pft) = rio_nchill_days_sift(io_idx_si_pft) + sites(s)%ncolddays(i_pft) = rio_ncold_days_sift(io_idx_si_pft) + sites(s)%leafondate(i_pft) = rio_leafondate_sift(io_idx_si_pft) + sites(s)%leafoffdate(i_pft) = rio_leafoffdate_sift(io_idx_si_pft) + sites(s)%ndaysleafon(i_pft) = rio_ndaysleafon_sift(io_idx_si_pft) + sites(s)%ndaysleafoff(i_pft) = rio_ndaysleafoff_sift(io_idx_si_pft) + sites(s)%grow_deg_days(i_pft) = rio_gdd_sift(io_idx_si_pft) sites(s)%elong_factor(i_pft) = rio_elong_factor_sift(io_idx_si_pft) sites(s)%seed_in(i_pft) = rio_seed_in_sift(io_idx_si_pft) sites(s)%seed_out(i_pft) = rio_seed_out_sift(io_idx_si_pft) @@ -3759,16 +3724,6 @@ subroutine get_restart_vectors(this, nc, nsites, sites) sites(s)%demotion_carbonflux = rio_democflux_si(io_idx_si) sites(s)%promotion_carbonflux = rio_promcflux_si(io_idx_si) - ! Site level phenology status flags - - sites(s)%cstatus = rio_cd_status_si(io_idx_si) - sites(s)%nchilldays = rio_nchill_days_si(io_idx_si) - sites(s)%ncolddays = rio_ncold_days_si(io_idx_si) - sites(s)%cleafondate = rio_cleafondate_si(io_idx_si) - sites(s)%cleafoffdate = rio_cleafoffdate_si(io_idx_si) - sites(s)%cndaysleafon = rio_cndaysleafon_si(io_idx_si) - sites(s)%cndaysleafoff = rio_cndaysleafoff_si(io_idx_si) - sites(s)%grow_deg_days = rio_gdd_si(io_idx_si) sites(s)%phen_model_date= rio_phenmodeldate_si(io_idx_si) sites(s)%coszen = rio_solar_zenith_angle(io_idx_si) diff --git a/parameter_files/fates_params_default.cdl b/parameter_files/fates_params_default.cdl index 9fb97c811f..d3ad0edea1 100644 --- a/parameter_files/fates_params_default.cdl +++ b/parameter_files/fates_params_default.cdl @@ -486,9 +486,15 @@ variables: double fates_nonhydro_smpso(fates_pft) ; fates_nonhydro_smpso:units = "mm" ; fates_nonhydro_smpso:long_name = "Soil water potential at full stomatal opening" ; + double fates_phen_chilltemp(fates_pft) ; + fates_phen_chilltemp:units = "degrees C" ; + fates_phen_chilltemp:long_name = "(Upper) Temperature threshold for accumulating number of chilling days (used for leaf flushing)" ; double fates_phen_cold_size_threshold(fates_pft) ; fates_phen_cold_size_threshold:units = "cm" ; fates_phen_cold_size_threshold:long_name = "the dbh size above which will lead to phenology-related stem and leaf drop" ; + double fates_phen_coldtemp(fates_pft) ; + fates_phen_coldtemp:units = "degrees C" ; + fates_phen_coldtemp:long_name = "(Upper) daily average temperature threshold below which the day is considered cold and will count towards leaf abscission" ; double fates_phen_drought_threshold(fates_pft) ; fates_phen_drought_threshold:units = "m3/m3 or mm" ; fates_phen_drought_threshold:long_name = "threshold for drought phenology (or lower threshold for semi-deciduous PFTs); the quantity depends on the sign: if positive, the threshold is volumetric soil moisture (m3/m3). If negative, the threshold is soil matric potentical (mm)" ; @@ -498,15 +504,33 @@ variables: double fates_phen_fnrt_drop_fraction(fates_pft) ; fates_phen_fnrt_drop_fraction:units = "fraction" ; fates_phen_fnrt_drop_fraction:long_name = "fraction of fine roots to drop during drought/cold" ; + double fates_phen_gddtemp(fates_pft) ; + fates_phen_gddtemp:units = "degrees C" ; + fates_phen_gddtemp:long_name = "(Lower) Temperature threshold for accumulating growing degree days (used for leaf flushing)" ; + double fates_phen_gddthresh_a(fates_pft) ; + fates_phen_gddthresh_a:units = "degrees C" ; + fates_phen_gddthresh_a:long_name = "Intercept (a) of the growing degree days (GDD) threshold modulated by number of chilling days (NCD), GDD = a + b * exp(c*NCD)" ; + double fates_phen_gddthresh_b(fates_pft) ; + fates_phen_gddthresh_b:units = "degrees C" ; + fates_phen_gddthresh_b:long_name = "Slope (b) of the growing degree days (GDD) threshold modulated by number of chilling days (NCD), GDD = a + b * exp(c*NCD)" ; + double fates_phen_gddthresh_c(fates_pft) ; + fates_phen_gddthresh_c:units = "1/days" ; + fates_phen_gddthresh_c:long_name = "Exponent slope (c) of the growing degree days (GDD) threshold modulated by number of chilling days (NCD), GDD = a + b * exp(c*NCD)" ; double fates_phen_leaf_habit(fates_pft) ; fates_phen_leaf_habit:units = "flag" ; fates_phen_leaf_habit:long_name = "Flag for leaf phenology habit. 1 - evergreen; 2 - season (cold) deciduous; 3 - stress (hydro) deciduous; 4 - stress (hydro) semi-deciduous" ; double fates_phen_mindaysoff(fates_pft) ; fates_phen_mindaysoff:units = "days" ; - fates_phen_mindaysoff:long_name = "day threshold compared against days since leaves abscised (shed)" ; + fates_phen_mindaysoff:long_name = "Minimum number of days that plants must remain leafless before flushing leaves again" ; + double fates_phen_mindayson(fates_pft) ; + fates_phen_mindayson:units = "days" ; + fates_phen_mindayson:long_name = "Minimum number of days that plants must remain with leaves flushed before they can abscise leaves again" ; double fates_phen_moist_threshold(fates_pft) ; fates_phen_moist_threshold:units = "m3/m3 or mm" ; fates_phen_moist_threshold:long_name = "upper threshold for drought phenology (only for drought semi-deciduous PFTs); the quantity depends on the sign: if positive, the threshold is volumetric soil moisture (m3/m3). If negative, the threshold is soil matric potentical (mm)" ; + double fates_phen_ncolddayslim(fates_pft) ; + fates_phen_ncolddayslim:units = "days" ; + fates_phen_ncolddayslim:long_name = "Minimum number of recent days below the temperature threshold that initiates temperature-driven leaf abscission" ; double fates_phen_stem_drop_fraction(fates_pft) ; fates_phen_stem_drop_fraction:units = "fraction" ; fates_phen_stem_drop_fraction:long_name = "fraction of stems to drop for non-woody species during drought/cold" ; @@ -867,27 +891,6 @@ variables: double fates_patch_fusion_tol ; fates_patch_fusion_tol:units = "unitless" ; fates_patch_fusion_tol:long_name = "minimum fraction in difference in profiles between patches" ; - double fates_phen_chilltemp ; - fates_phen_chilltemp:units = "degrees C" ; - fates_phen_chilltemp:long_name = "chilling day counting threshold for vegetation" ; - double fates_phen_coldtemp ; - fates_phen_coldtemp:units = "degrees C" ; - fates_phen_coldtemp:long_name = "vegetation temperature exceedance that flags a cold-day for leaf-drop" ; - double fates_phen_gddthresh_a ; - fates_phen_gddthresh_a:units = "none" ; - fates_phen_gddthresh_a:long_name = "GDD accumulation function, intercept parameter: gdd_thesh = a + b exp(c*ncd)" ; - double fates_phen_gddthresh_b ; - fates_phen_gddthresh_b:units = "none" ; - fates_phen_gddthresh_b:long_name = "GDD accumulation function, multiplier parameter: gdd_thesh = a + b exp(c*ncd)" ; - double fates_phen_gddthresh_c ; - fates_phen_gddthresh_c:units = "none" ; - fates_phen_gddthresh_c:long_name = "GDD accumulation function, exponent parameter: gdd_thesh = a + b exp(c*ncd)" ; - double fates_phen_mindayson ; - fates_phen_mindayson:units = "days" ; - fates_phen_mindayson:long_name = "day threshold compared against days since leaves became on-allometry" ; - double fates_phen_ncolddayslim ; - fates_phen_ncolddayslim:units = "days" ; - fates_phen_ncolddayslim:long_name = "day threshold exceedance for temperature leaf-drop" ; double fates_q10_froz ; fates_q10_froz:units = "unitless" ; fates_q10_froz:long_name = "Q10 for frozen-soil respiration rates" ; @@ -1459,8 +1462,13 @@ data: fates_nonhydro_smpso = -66000, -66000, -66000, -66000, -66000, -66000, -66000, -66000, -66000, -66000, -66000, -66000, -66000, -66000 ; + fates_phen_chilltemp = 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 ; + fates_phen_cold_size_threshold = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; + fates_phen_coldtemp = 7.5, 7.5, 7.5, 7.5, 7.5, 7.5, 7.5, 7.5, 7.5, 7.5, + 7.5, 7.5, 7.5, 7.5 ; + fates_phen_drought_threshold = -152957.4, -152957.4, -152957.4, -152957.4, -152957.4, -152957.4, -152957.4, -152957.4, -152957.4, -152957.4, -152957.4, -152957.4, -152957.4, -152957.4 ; @@ -1470,15 +1478,33 @@ data: fates_phen_fnrt_drop_fraction = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; + fates_phen_gddtemp = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; + + fates_phen_gddthresh_a = -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68 ; + + fates_phen_gddthresh_b = 638, 638, 638, 638, 638, 638, 638, 638, 638, 638, + 638, 638, 638, 638 ; + + fates_phen_gddthresh_c = -0.01, -0.01, -0.01, -0.01, -0.01, -0.01, -0.01, + -0.01, -0.01, -0.01, -0.01, -0.01, -0.01, -0.01 ; + fates_phen_leaf_habit = 1, 1, 2, 1, 3, 2, 1, 3, 2, 1, 2, 2, 3, 3 ; - fates_phen_mindaysoff = 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, - 100, 100, 100, 100 ; + fates_phen_mindaysoff = 100, 100, 90, 100, 100, 90, 100, 100, 90, 100, + 90, 90, 100, 100 ; + + fates_phen_mindayson = 90, 90, 90, 90, 100, 90, 90, 100, 90, 90, 90, 90, + 100, 100 ; fates_phen_moist_threshold = -122365.9, -122365.9, -122365.9, -122365.9, -122365.9, -122365.9, -122365.9, -122365.9, -122365.9, -122365.9, -122365.9, -122365.9, -122365.9, -122365.9 ; + fates_phen_ncolddayslim = 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 ; + + fates_phen_season_decid = 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0 ; + fates_phen_stem_drop_fraction = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; fates_prescribed_npp_canopy = 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, @@ -1810,20 +1836,6 @@ data: fates_patch_fusion_tol = 0.05 ; - fates_phen_chilltemp = 5 ; - - fates_phen_coldtemp = 7.5 ; - - fates_phen_gddthresh_a = -68 ; - - fates_phen_gddthresh_b = 638 ; - - fates_phen_gddthresh_c = -0.01 ; - - fates_phen_mindayson = 90 ; - - fates_phen_ncolddayslim = 5 ; - fates_q10_froz = 1.5 ; fates_q10_mr = 1.5 ; diff --git a/parteh/PRTParametersMod.F90 b/parteh/PRTParametersMod.F90 index 66202da6c5..58c93c2ac7 100644 --- a/parteh/PRTParametersMod.F90 +++ b/parteh/PRTParametersMod.F90 @@ -21,8 +21,29 @@ module PRTParametersMod ! - isemi_stress_decid - drought semi-deciduous (i.e., ! partial abscission and flushing are allowed). ! Drop fraction for tissues other than leaves (PFT-dependent) - real(r8), allocatable :: phen_fnrt_drop_fraction(:) ! Abscission fraction of fine roots - real(r8), allocatable :: phen_stem_drop_fraction(:) ! Abscission fraction of stems + + real(r8), allocatable :: phen_fnrt_drop_fraction(:) ! Abscission fraction of fine roots + real(r8), allocatable :: phen_stem_drop_fraction(:) ! Abscission fraction of stems + + ! The three parameters below are for the growing degree days + ! threshold function, which is modulated by the number of + ! chilling days (NCD): GDD_Thresh = a + b * exp (c * NCD) + real(r8), allocatable :: phen_gddthresh_a(:) ! - a parameter (intercept) + real(r8), allocatable :: phen_gddthresh_b(:) ! - b parameter (multiplier) + real(r8), allocatable :: phen_gddthresh_c(:) ! - c parameter (exponent) + + real(r8), allocatable :: phen_gddtemp(:) ! (Lower) Temperature threshold for accumulating + ! growing degree days (used for leaf flushing) + real(r8), allocatable :: phen_chilltemp(:) ! (Upper) Temperature threshold for accumulating + ! number of chilling days (used for leaf flushing) + real(r8), allocatable :: phen_coldtemp(:) ! (Upper) daily average temperature threshold below which the + ! day is considered cold and will count towards leaf abscission + real(r8), allocatable :: phen_mindayson(:) ! Minimum number of days that plants must remain with leaves + ! flushed before they can abscise leaves again. + real(r8), allocatable :: phen_mindaysoff(:) ! Minimum number of days that plants must remain leafless + ! before flushing leaves again. + real(r8), allocatable :: phen_ncolddayslim(:) ! Minimum number of recent days below the temperature threshold + ! that initiates temperature-driven leaf abscission. real(r8), allocatable :: phen_drought_threshold(:) ! For obligate (hard) drought deciduous, this is the threshold ! below which plants will abscise leaves, and ! above which plants will flush leaves. For semi-deciduous @@ -36,8 +57,6 @@ module PRTParametersMod ! are soil volumetric water content [m3/m3]. If ! negative, the values are soil matric potential [mm]. ! Ignored for non-deciduous plants. - real(r8), allocatable :: phen_doff_time(:) ! Minimum number of days that plants must remain leafless before - ! flushing leaves again. ! Growth and Turnover Parameters diff --git a/parteh/PRTParamsFATESMod.F90 b/parteh/PRTParamsFATESMod.F90 index a668d6529d..2742040573 100644 --- a/parteh/PRTParamsFATESMod.F90 +++ b/parteh/PRTParamsFATESMod.F90 @@ -166,10 +166,42 @@ subroutine PRTRegisterPFT(fates_params) call fates_params%RegisterParameter(name=name, dimension_shape=dimension_shape_1d, & dimension_names=dim_names, lower_bounds=dim_lower_bound) + name = 'fates_phen_gddthresh_a' + call fates_params%RegisterParameter(name=name, dimension_shape=dimension_shape_1d, & + dimension_names=dim_names, lower_bounds=dim_lower_bound) + + name = 'fates_phen_gddthresh_b' + call fates_params%RegisterParameter(name=name, dimension_shape=dimension_shape_1d, & + dimension_names=dim_names, lower_bounds=dim_lower_bound) + + name = 'fates_phen_gddthresh_c' + call fates_params%RegisterParameter(name=name, dimension_shape=dimension_shape_1d, & + dimension_names=dim_names, lower_bounds=dim_lower_bound) + + name = 'fates_phen_gddtemp' + call fates_params%RegisterParameter(name=name, dimension_shape=dimension_shape_1d, & + dimension_names=dim_names, lower_bounds=dim_lower_bound) + + name = 'fates_phen_chilltemp' + call fates_params%RegisterParameter(name=name, dimension_shape=dimension_shape_1d, & + dimension_names=dim_names, lower_bounds=dim_lower_bound) + + name = 'fates_phen_coldtemp' + call fates_params%RegisterParameter(name=name, dimension_shape=dimension_shape_1d, & + dimension_names=dim_names, lower_bounds=dim_lower_bound) + + name = 'fates_phen_mindayson' + call fates_params%RegisterParameter(name=name, dimension_shape=dimension_shape_1d, & + dimension_names=dim_names, lower_bounds=dim_lower_bound) + name = 'fates_phen_mindaysoff' call fates_params%RegisterParameter(name=name, dimension_shape=dimension_shape_1d, & dimension_names=dim_names, lower_bounds=dim_lower_bound) + name = 'fates_phen_ncolddayslim' + call fates_params%RegisterParameter(name=name, dimension_shape=dimension_shape_1d, & + dimension_names=dim_names, lower_bounds=dim_lower_bound) + name = 'fates_phen_drought_threshold' call fates_params%RegisterParameter(name=name, dimension_shape=dimension_shape_1d, & dimension_names=dim_names, lower_bounds=dim_lower_bound) @@ -460,9 +492,41 @@ subroutine PRTReceivePFT(fates_params) call fates_params%RetrieveParameterAllocate(name=name, & data=prt_params%phen_fnrt_drop_fraction) + name = 'fates_phen_gddthresh_a' + call fates_params%RetrieveParameterAllocate(name=name, & + data=prt_params%phen_gddthresh_a) + + name = 'fates_phen_gddthresh_b' + call fates_params%RetrieveParameterAllocate(name=name, & + data=prt_params%phen_gddthresh_b) + + name = 'fates_phen_gddthresh_c' + call fates_params%RetrieveParameterAllocate(name=name, & + data=prt_params%phen_gddthresh_c) + + name = 'fates_phen_gddtemp' + call fates_params%RetrieveParameterAllocate(name=name, & + data=prt_params%phen_gddtemp) + + name = 'fates_phen_chilltemp' + call fates_params%RetrieveParameterAllocate(name=name, & + data=prt_params%phen_chilltemp) + + name = 'fates_phen_coldtemp' + call fates_params%RetrieveParameterAllocate(name=name, & + data=prt_params%phen_coldtemp) + + name = 'fates_phen_mindayson' + call fates_params%RetrieveParameterAllocate(name=name, & + data=prt_params%phen_mindayson) + name = 'fates_phen_mindaysoff' call fates_params%RetrieveParameterAllocate(name=name, & - data=prt_params%phen_doff_time) + data=prt_params%phen_mindaysoff) + + name = 'fates_phen_ncolddayslim' + call fates_params%RetrieveParameterAllocate(name=name, & + data=prt_params%phen_ncolddayslim) name = 'fates_phen_drought_threshold' call fates_params%RetrieveParameterAllocate(name=name, & @@ -972,7 +1036,15 @@ subroutine FatesReportPFTParams(is_master) write(fates_log(),fmti) 'phen_leaf_habit = ',prt_params%phen_leaf_habit write(fates_log(),fmt0) 'phen_fnrt_drop_fraction = ',prt_params%phen_fnrt_drop_fraction write(fates_log(),fmt0) 'phen_stem_drop_fraction = ',prt_params%phen_stem_drop_fraction - write(fates_log(),fmt0) 'phen_doff_time = ',prt_params%phen_doff_time + write(fates_log(),fmt0) 'phen_gddthresh_a = ',prt_params%phen_gddthresh_a + write(fates_log(),fmt0) 'phen_gddthresh_b = ',prt_params%phen_gddthresh_b + write(fates_log(),fmt0) 'phen_gddthresh_c = ',prt_params%phen_gddthresh_c + write(fates_log(),fmt0) 'phen_gddtemp = ',prt_params%phen_gddtemp + write(fates_log(),fmt0) 'phen_chilltemp = ',prt_params%phen_chilltemp + write(fates_log(),fmt0) 'phen_coldtemp = ',prt_params%phen_coldtemp + write(fates_log(),fmt0) 'phen_mindayson = ',prt_params%phen_mindayson + write(fates_log(),fmt0) 'phen_mindaysoff = ',prt_params%phen_mindaysoff + write(fates_log(),fmt0) 'phen_ncolddayslim = ',prt_params%phen_ncolddayslim write(fates_log(),fmt0) 'phen_drought_threshold = ',prt_params%phen_drought_threshold write(fates_log(),fmt0) 'phen_moist_threshold = ',prt_params%phen_moist_threshold write(fates_log(),fmt0) 'wood_density = ',prt_params%wood_density diff --git a/testing/testing_shr/FatesFactoryMod.F90 b/testing/testing_shr/FatesFactoryMod.F90 index 81c0288a36..92a359a7b6 100644 --- a/testing/testing_shr/FatesFactoryMod.F90 +++ b/testing/testing_shr/FatesFactoryMod.F90 @@ -112,7 +112,7 @@ subroutine InitializeGlobals(step_size) do i = 2,nlevleaf dlower_vai(i) = dlower_vai(i-1) + dinc_vai(i-1) end do - + end subroutine InitializeGlobals !---------------------------------------------------------------------------------------