! ================================================================================================================================= ! MODULE : stomate_season ! ! CONTACT : orchidee-help _at_ listes.ipsl.fr ! ! LICENCE : IPSL (2006). This software is governed by the CeCILL licence see ORCHIDEE/ORCHIDEE_CeCILL.LIC ! !>\BRIEF This module calculates long-term meteorological parameters from daily temperatures !! and precipitations (essentially for phenology). !! !!\n DESCRIPTION: None !! !! RECENT CHANGE(S): None !! !! SVN : !! $HeadURL$ !! $Date$ !! $Revision$ !! \n !_ ================================================================================================================================= MODULE stomate_season ! modules used: USE xios_orchidee USE ioipsl_para USE stomate_data USE constantes USE constantes_soil USE pft_parameters USE solar USE grid USE time, ONLY : one_year, julian_diff, LastTsYear IMPLICIT NONE ! private & public routines PRIVATE PUBLIC season,season_clear LOGICAL, SAVE :: firstcall_season = .TRUE. !! first call (true/false) !$OMP THREADPRIVATE(firstcall_season) CONTAINS !! ================================================================================================================================ !! SUBROUTINE : season_clear !! !>\BRIEF Flag setting !! !! DESCRIPTION : This subroutine sets flags ::firstcall_season, to .TRUE., and therefore activates !! section 1.1 of the ::season subroutine which writes messages to the output. \n !! This subroutine is called at the end of the subroutine ::stomate_clear, in the !! module ::stomate. !! !! RECENT CHANGE(S):None !! !! MAIN OUTPUT VARIABLE(S): ::firstcall_season !! !! REFERENCE(S) : None !! !! FLOWCHART : None !! \n !_ ================================================================================================================================= SUBROUTINE season_clear firstcall_season=.TRUE. END SUBROUTINE season_clear !! ================================================================================================================================ !! SUBROUTINE : season !! !>\BRIEF This subroutine calculates many of the long-term biometeorological variables !! needed in the phenology subroutines and in the calculation of long-term vegetation !! dynamics in the LPJ DGVM. !! !! DESCRIPTION This subroutine is called by the module ::stomate before LPJ, and mainly deals !! with the calculation of long-term meteorological variables, carbon fluxes and !! vegetation-related variables that are used to calculate vegetation dynamics !! in the stomate modules relating to the phenology and to the longer-term !! changes in vegetation type and fractional cover in the LPJ DGVM modules. \n !! In sections 2 to 5, longer-term meteorological variables are calculated. The !! long-term moisture availabilities are used in the leaf onset and senescence !! phenological models ::stomate_phenology and ::stomate_turnover that require !! a moisture condition. The long term temperatures are also required for phenology !! but in addition they are used in calculations of C flux and the presence and !! establishment of vegetation patterns on a longer timescale in the LPJ DGVM modules. !! Finally the monthly soil humidity/relative soil moisture is used in the C !! allocation module ::stomate_alloc. \n !! Sections 12 to 14 also calculate long-term variables of C fluxes, including NPP, !! turnover and GPP. The first two are used to calculate long-term vegetation !! dynamics and land cover change in the LPJ DVGM modules. The weekly GPP is used !! to determine the dormancy onset and time-length, as described below. \n !! The long-term variables described above are are used in certain vegetation !! dynamics processes in order to maintain consistency with the basic hypotheses of the !! parameterisations of LPJ, which operates on a one year time step (Krinner et al., 2005). !! In order to reduce the computer memory requirements, short-term variables (e.g. daily !! temperatures) are not stored for averaging over a longer period. Instead !! the long-term variables (e.g. monthly temperature) are calculated at each time step !! using a linear relaxation method, following the equation: !! \latexonly !! \input{season_lin_relax_eqn1.tex} !! \endlatexonly !! \n !! The long-term variables are therefore updated on a daily basis. This method allows for !! smooth temporal variation of the long-term variables which are used to calculate !! vegetation dynamics (Krinner et al., 2005). \n !! Sections 6 to 11 calculate the variables required for to determine leaf onset in !! the module ::stomate_phenology. !! These include : !! - the dormance onset and time-length, when GPP is below a certain threshold \n !! - the growing degree days (GDD), which is the sum of daily temperatures greater than !! -5 degrees C, either since the onset of the dormancy period, or since midwinter \n !! - the number of chilling days, which is the number of days with a daily temperature !! lower than a PFT-dependent threshold since the beginning of the dormancy period \n !! - the number of growing days, which is the the number of days with a temperature !! greater than -5 degrees C since the onset of the dormancy period \n !! - the time since the minimum moisture availability in the dormancy period. \n !! These variables are used to determine the conditions needed for the start of the !! leaf growing season. The specific models to which they correspond are given below. \n !! Sections 15 to 20 are used to update the maximum/minimum or the sum of various !! meteorological and biological variables during the year that are required for !! calculating either leaf onset or longer-term vegetation dynamics the following year. \n !! At the end of the year, these variables are updated from "thisyear" to "lastyear", !! in Section 21 of this subroutine, for use the following year. \n !! Finally the probably amount of herbivore consumption is calculated in Section 22, !! following McNaughton et al. (1989). !! !! RECENT CHANGE(S): None !! !! MAIN OUTPUT VARIABLE(S): :: herbivores, !! :: maxmoiavail_lastyear, :: maxmoiavail_thisyear, !! :: minmoiavail_lastyear, :: minmoiavail_thisyear, !! :: maxgppweek_lastyear, :: maxgppweek_thisyear, !! :: gdd0_lastyear, :: gdd0_thisyear, !! :: precip_lastyear, :: precip_thisyear, !! :: lm_lastyearmax, :: lm_thisyearmax, !! :: maxfpc_lastyear, :: maxfpc_thisyear, !! :: moiavail_month, :: moiavail_week, !! :: t2m_longterm, :: t2m_month, :: t2m_week, !! :: tsoil_month, :: soilhum_month, !! :: npp_longterm, :: turnover_longterm, :: gpp_week, !! :: gdd_m5_dormance, :: gdd_midwinter, !! :: ncd_dormance, :: ngd_minus5, :: time_lowgpp, !! :: time_hum_min, :: hum_min_dormance !! !! REFERENCES : !! - Krinner, G., N. Viovy, N. de Noblet-Ducoudre, J. Ogee, J. Polcher, P. !! Friedlingstein, P. Ciais, S. Sitch and I.C. Prentice (2005), A dynamic global !! vegetation model for studies of the coupled atmosphere-biosphere system, Global !! Biogeochemical Cycles, 19, doi:10.1029/2003GB002199. !! - McNaughton, S.J., M. Oesterheld, D.A. Frank and K.J. Williams (1989), !! Ecosystem-level patterns of primary productivity and herbivory in terrestrial !! habitats, Nature, 341, 142-144. !! !! FLOWCHART : !! \latexonly !! \includegraphics[scale = 1]{season_flowchart_part1.png} !! \includegraphics[scale = 1]{season_flowchart_part2.png} !! \includegraphics[scale = 1]{season_flowchart_part3.png} !! \endlatexonly !! \n !_ ================================================================================================================================= SUBROUTINE season (npts, dt, veget_cov, veget_cov_max, & moiavail_daily, t2m_daily, tsoil_daily, soilhum_daily, lalo, & precip_daily, npp_daily, biomass, turnover_daily, gpp_daily, when_growthinit, & maxmoiavail_lastyear, maxmoiavail_thisyear, & minmoiavail_lastyear, minmoiavail_thisyear, & maxgppweek_lastyear, maxgppweek_thisyear, & gdd0_lastyear, gdd0_thisyear, & precip_lastyear, precip_thisyear, & lm_lastyearmax, lm_thisyearmax, & maxfpc_lastyear, maxfpc_thisyear, & moiavail_month, moiavail_week, t2m_longterm, tau_longterm, t2m_month, t2m_week, & tsoil_month, soilhum_month, & npp_longterm, turnover_longterm, gpp_week, & gdd_m5_dormance, gdd_midwinter, ncd_dormance, ngd_minus5, & time_hum_min, hum_min_dormance, gdd_init_date , & gdd_from_growthinit, herbivores, & Tseason, Tseason_length, Tseason_tmp, & Tmin_spring_time, t2m_min_daily, begin_leaves, onset_date) ! !! 0. Variable and parameter declaration ! ! !! 0.1 Input variables ! INTEGER(i_std), INTENT(in) :: npts !! Domain size - number of grid cells (unitless) REAL(r_std), INTENT(in) :: dt !! time step in days (dt_days) REAL(r_std), DIMENSION(npts,nvm), INTENT(in) :: veget_cov !! coverage fraction of a PFT. Here: fraction of !! total ground. (0-1, unitless) REAL(r_std), DIMENSION(npts,nvm), INTENT(in) :: veget_cov_max !! "maximal" coverage fraction of a PFT (for LAI -> !! infinity) (0-1, unitless)Here: fraction of !! total ground. REAL(r_std), DIMENSION(npts,nvm), INTENT(in) :: moiavail_daily !! Daily moisture availability (0-1, unitless) REAL(r_std), DIMENSION(npts), INTENT(in) :: t2m_daily !! Daily 2 meter temperature (K) REAL(r_std), DIMENSION(npts,nslm), INTENT(in) :: tsoil_daily !! Daily soil temperature (K) REAL(r_std), DIMENSION(npts,nslm), INTENT(in) :: soilhum_daily !! Daily soil humidity (0-1, unitless) REAL(r_std), DIMENSION(npts,2), INTENT(in) :: lalo !! array of lat/lon REAL(r_std), DIMENSION(npts), INTENT(in) :: precip_daily !! Daily mean precipitation @tex ($mm day^{-1}$) !! @endtex REAL(r_std), DIMENSION(npts,nvm), INTENT(in) :: npp_daily !! daily net primary productivity @tex ($gC m^{-2} !! day^{-1}$) @endtex REAL(r_std), DIMENSION(npts,nvm,nparts,nelements), INTENT(in) :: biomass !! biomass @tex ($gC m^{-2} of ground$) @endtex REAL(r_std), DIMENSION(npts,nvm,nparts,nelements), INTENT(in) :: turnover_daily !! Turnover rates @tex ($gC m^{-2} day^{-1}$) !! @endtex REAL(r_std), DIMENSION(npts,nvm), INTENT(in) :: gpp_daily !! daily gross primary productivity !! (Here: @tex $gC m^{-2} of total ground !! day^{-1}$) @endtex REAL(r_std), DIMENSION(npts,nvm), INTENT(in) :: when_growthinit !! how many days ago was the beginning of the !! growing season (days) LOGICAL, DIMENSION(npts,nvm), INTENT(in) :: begin_leaves !! signal to start putting leaves on (true/false) REAL(r_std), DIMENSION(npts), INTENT(in) :: t2m_min_daily !! Daily minimum 2-meter temperature (K) ! !! 0.2 Output variables ! (diagnostic) ! REAL(r_std), DIMENSION(npts,nvm), INTENT(out) :: herbivores !! time constant of probability of a leaf to be !! eaten by a herbivore (days) ! !! 0.3 Modified variables ! REAL(r_std), DIMENSION(npts,nvm), INTENT(inout) :: maxmoiavail_lastyear !! last year's maximum moisture !! availability (0-1, unitless) REAL(r_std), DIMENSION(npts,nvm), INTENT(inout) :: maxmoiavail_thisyear !! this year's maximum moisture !! availability (0-1, unitless) REAL(r_std), DIMENSION(npts,nvm), INTENT(inout) :: minmoiavail_lastyear !! last year's minimum moisture !! availability (0-1, unitless) REAL(r_std), DIMENSION(npts,nvm), INTENT(inout) :: minmoiavail_thisyear !! this year's minimum moisture !! availability (0-1, unitless) REAL(r_std), DIMENSION(npts,nvm), INTENT(inout) :: maxgppweek_lastyear !! last year's maximum weekly GPP !! @tex ($gC m^{-2} week^{-1}$) @endtex REAL(r_std), DIMENSION(npts,nvm), INTENT(inout) :: maxgppweek_thisyear !! this year's maximum weekly GPP !! @tex ($gC m^{-2} week^{-1}$) @endtex REAL(r_std), DIMENSION(npts), INTENT(inout) :: gdd0_lastyear !! last year's annual GDD0 (C) REAL(r_std), DIMENSION(npts), INTENT(inout) :: gdd0_thisyear !! this year's annual GDD0 (C) REAL(r_std), DIMENSION(npts), INTENT(inout) :: precip_lastyear !! last year's annual precipitation !! @tex ($mm year^{-1}$) @endtex REAL(r_std), DIMENSION(npts), INTENT(inout) :: precip_thisyear !! this year's annual precipitation !! @tex ($mm year^{-1}$) @endtex REAL(r_std), DIMENSION(npts,nvm), INTENT(inout) :: lm_lastyearmax !! last year's maximum leaf mass, for each !! PFT @tex ($gC m^{-2}$) @endtex REAL(r_std), DIMENSION(npts,nvm), INTENT(inout) :: lm_thisyearmax !! this year's maximum leaf mass, for each !! PFT @tex ($gC m^{-2}$) @endtex REAL(r_std), DIMENSION(npts,nvm), INTENT(inout) :: maxfpc_lastyear !! last year's maximum fpc for each PFT, on !! ground (0-1, unitless) REAL(r_std), DIMENSION(npts,nvm), INTENT(inout) :: maxfpc_thisyear !! this year's maximum fpc for each PFT, on !! ground (0-1, unitless) REAL(r_std), DIMENSION(npts,nvm), INTENT(inout) :: moiavail_month !! "monthly" moisture availability !! (0-1, unitless) REAL(r_std), DIMENSION(npts,nvm), INTENT(inout) :: moiavail_week !! "weekly" moisture availability !! (0-1, unitless) REAL(r_std), DIMENSION(npts), INTENT(inout) :: t2m_longterm !! "long term" 2-meter temperatures (K) REAL(r_std), INTENT(inout) :: tau_longterm REAL(r_std), DIMENSION(npts), INTENT(inout) :: t2m_month !! "monthly" 2-meter temperatures (K) REAL(r_std), DIMENSION(npts), INTENT(inout) :: t2m_week !! "weekly" 2-meter temperatures (K) REAL(r_std), DIMENSION(npts), INTENT(inout) :: Tseason !! "seasonal" 2-meter temperatures (K), !! used to constrain boreal treeline REAL(r_std), DIMENSION(npts), INTENT(inout) :: Tseason_tmp !! temporary variable to calculate Tseason REAL(r_std), DIMENSION(npts), INTENT(inout) :: Tseason_length !! temporary variable to calculate Tseason: !! number of days when t2m_week is higher than 0 degree REAL(r_std), DIMENSION(npts,nvm), INTENT(inout) :: Tmin_spring_time !! Number of days after begin_leaves (leaf onset) REAL(r_std), DIMENSION(npts,nvm), INTENT(inout) :: onset_date !! Date in the year at when the leaves started to grow(begin_leaves) REAL(r_std), DIMENSION(npts,nslm), INTENT(inout) :: tsoil_month !! "monthly" soil temperatures (K) REAL(r_std), DIMENSION(npts,nslm), INTENT(inout) :: soilhum_month !! "monthly" soil humidity (0-1, unitless) REAL(r_std), DIMENSION(npts,nvm), INTENT(inout) :: npp_longterm !! "long term" net primary productivity !! @tex ($gC m^{-2} year^{-1}$) @endtex REAL(r_std), DIMENSION(npts,nvm,nparts,nelements), INTENT(inout) :: turnover_longterm !! "long term" turnover rate !! @tex ($gC m^{-2} year^{-1}$) @endtex REAL(r_std), DIMENSION(npts,nvm), INTENT(inout) :: gpp_week !! "weekly" GPP @tex ($gC m^{-2} day^{-1}$) !! @endtex REAL(r_std), DIMENSION(npts,nvm), INTENT(inout) :: gdd_m5_dormance !! growing degree days above threshold -5 !! deg. C (C) REAL(r_std), DIMENSION(npts,nvm), INTENT(inout) :: gdd_midwinter !! growing degree days since midwinter (C) REAL(r_std), DIMENSION(npts,nvm), INTENT(inout) :: ncd_dormance !! number of chilling days since leaves !! were lost (days) REAL(r_std), DIMENSION(npts,nvm), INTENT(inout) :: ngd_minus5 !! number of growing days (days) REAL(r_std), DIMENSION(npts,nvm), INTENT(inout) :: time_hum_min !! time elapsed since strongest moisture !! availability (days) REAL(r_std), DIMENSION(npts,nvm), INTENT(inout) :: hum_min_dormance !! minimum moisture during dormance !! (0-1, unitless) REAL(r_std), DIMENSION(npts,2), INTENT(inout) :: gdd_init_date !! inital date for gdd count REAL(r_std), DIMENSION(npts,nvm), INTENT(inout) :: gdd_from_growthinit !! growing degree days, threshold 0 deg. C !! since beginning of season ! !! 0.4 Local variables ! INTEGER(i_std) :: j !! indices (unitless) REAL(r_std) :: ncd_max !! maximum ncd (to avoid floating point !! underflows) (days) REAL(r_std), DIMENSION(npts) :: sumfpc_nat !! sum of natural fpcs (0-1, unitless) !! [DISPENSABLE] REAL(r_std), DIMENSION(npts,nvm) :: weighttot !! weight of biomass @tex ($gC m^{-2}$) !! @endtex REAL(r_std), DIMENSION(npts,nvm) :: nlflong_nat !! natural long-term leaf NPP !! @tex ($gC m^{-2} year^{-1}$) @endtex REAL(r_std), DIMENSION(npts,nvm) :: green_age !! residence time of green tissue (years) REAL(r_std), DIMENSION(npts) :: consumption !! herbivore consumption !! @tex ($gC m^{-2} day^{-1}$) @endtex REAL(r_std), DIMENSION(npts) :: fracnat !! fraction of each gridcell occupied by !! natural vegetation (0-1, unitless) REAL(r_std), DIMENSION(npts) :: solad !! maximal radation during current day !! (clear sky condition) REAL(r_std), DIMENSION(npts) :: solai !! maximal radation during current day !! (clear sky condition) REAL(r_std), DIMENSION(npts) :: cloud !! cloud fraction !_ ================================================================================================================================= IF (printlev>=3) WRITE(numout,*) 'Entering season' ! !! 1. Initializations !! 1.1 Calculate ::ncd_max - the maximum possible NCD (number of chilling days) as: !! \latexonly !! \input{season_ncdmax_eqn2.tex} !! \endlatexonly !! \n !! where one_year is 1 year in seconds (defined in ::constantes). ! ncd_max = ncd_max_year * one_year IF ( firstcall_season ) THEN ! !! 1.2 first call - output message giving the setting of the ::gppfrac_dormance, !! ::hvc1, ::hvc2 and ::leaf_frac (as a percentage) parameters which are !! defined at the beginning of this subroutine. Also outputs the value of !! ::ncd_max. ! IF ( printlev>=2 ) THEN WRITE(numout,*) 'season: ' WRITE(numout,*) ' > maximum GPP/GGP_max ratio for dormance (::gppfrac_dormance) :',gppfrac_dormance !* WRITE(numout,*) ' > maximum possible ncd(days) (::ncd_max) : ',ncd_max !* WRITE(numout,*) ' > herbivore consumption C (gC/m2/d) as a function of NPP (gC/m2/d): (::hvc1) (::hvc2)' !* WRITE(numout,*) ' C=',hvc1,' * NPP^',hvc2 WRITE(numout,*) ' > for herbivores, suppose that (::leaf_frac_hvc)',leaf_frac_hvc*100., & '% of NPP is allocated to leaves' ENDIF ! !! 1.3 Check whether longer-term meteorological and phenology-related variables are not initialized !! to less than zero. If the following meteorological variables are less than ::min_stomate which is set !! to 1.E-8 in ::grid, then they are set to the current daily value. If the phenology- !! related variables are less than ::min_stomate, they are set to "undef". !! Warning messages are output in each case, and are also output if "long-term" C fluxes GPP, !! NPP and turnover are less than ::min_stomate. ! !! 1.3.1 moisture availabilities (i.e. relative soil moisture, including the root soil profile): !! 1.3.1.1 "monthly" (::moiavail_month) IF ( ABS( SUM( moiavail_month(:,2:nvm) ) ) .LT. min_stomate ) THEN ! in this case, set them it today's moisture availability WRITE(numout,*) 'Warning! We have to initialize the ''monthly'' moisture availabilities. ' moiavail_month(:,:) = moiavail_daily(:,:) ENDIF !! 1.3.1.2 "weekly" (::moiavail_week) IF ( ABS( SUM( moiavail_week(:,2:nvm) ) ) .LT. min_stomate ) THEN ! in this case, set them it today's moisture availability WRITE(numout,*) 'Warning! We have to initialize the ''weekly'' moisture availabilities. ' moiavail_week(:,:) = moiavail_daily(:,:) ENDIF !! 1.3.2 2-meter temperatures: !! "monthly" (::t2m_month) IF ( ABS( SUM( t2m_month(:) ) ) .LT. min_stomate ) THEN ! in this case, set them to today's temperature WRITE(numout,*) 'Warning! We have to initialize the ''monthly'' 2m temperatures.' t2m_month(:) = t2m_daily(:) ENDIF !! "weekly" (::2m_week) IF ( ABS( SUM( t2m_week(:) ) ) .LT. min_stomate ) THEN ! in this case, set them to today's temperature WRITE(numout,*) 'Warning! We have to initialize the ''weekly'' 2m temperatures.' t2m_week(:) = t2m_daily(:) ENDIF !! 1.3.3 "monthly" soil temperatures (::tsoil_month): !MM PAS PARALLELISE!! IF ( ABS( SUM( tsoil_month(:,:) ) ) .LT. min_stomate ) THEN ! in this case, set them to today's temperature WRITE(numout,*) 'Warning!'// & ' We have to initialize the ''monthly'' soil temperatures.' tsoil_month(:,:) = tsoil_daily(:,:) ENDIF !! 1.3.4 "monthly" soil humidity (::soilhum_month): IF ( ABS( SUM( soilhum_month(:,:) ) ) .LT. min_stomate ) THEN ! in this case, set them to today's humidity WRITE(numout,*) 'Warning!'// & ' We have to initialize the ''monthly'' soil humidity.' soilhum_month(:,:) = soilhum_daily(:,:) ENDIF !! 1.3.5 growing degree days, threshold -5 deg C (::gdd_m5_dormance): IF ( ABS( SUM( gdd_m5_dormance(:,2:nvm) ) ) .LT. min_stomate ) THEN WRITE(numout,*) 'Warning! Growing degree days (-5 deg) are initialized to ''undef''.' gdd_m5_dormance(:,:) = undef ENDIF !! 1.3.6 growing degree days since midwinter (::gdd_midwinter): IF ( ABS( SUM( gdd_midwinter(:,2:nvm) ) ) .LT. min_stomate ) THEN WRITE(numout,*) 'Warning! Growing degree days since midwinter' // & ' are initialized to ''undef''.' gdd_midwinter(:,:) = undef ENDIF !! 1.3.7 number of chilling days since leaves were lost (::ncd_dormance): IF ( ABS( SUM( ncd_dormance(:,2:nvm) ) ) .LT. min_stomate ) THEN WRITE(numout,*) 'Warning! Number of chilling days is initialized to ''undef''.' ncd_dormance(:,:) = undef ENDIF !! 1.3.8 number of growing days, threshold -5 deg C (::ngd_minus5): IF ( ABS( SUM( ngd_minus5(:,2:nvm) ) ) .LT. min_stomate ) THEN WRITE(numout,*) 'Warning! Number of growing days (-5 deg) is initialized to 0.' ENDIF !! 1.3.9 "long term" npp (::npp_longterm): IF ( ABS( SUM( npp_longterm(:,2:nvm) ) ) .LT. min_stomate ) THEN WRITE(numout,*) 'Warning! Long term NPP is initialized to 0.' ENDIF !! 1.3.10 "long term" turnover (::turnover_longterm): IF ( ABS( SUM( turnover_longterm(:,2:nvm,:,:) ) ) .LT. min_stomate ) THEN WRITE(numout,*) 'Warning! Long term turnover is initialized to 0.' ENDIF !! 1.3.11 "weekly" GPP (::gpp_week): IF ( ABS( SUM( gpp_week(:,2:nvm) ) ) .LT. min_stomate ) THEN WRITE(numout,*) 'Warning! Weekly GPP is initialized to 0.' ENDIF !! 1.3.12 minimum moisture availabilities (::minmoiavail_thisyear) !! In this case, if the minimum moisture !! is less than ::min_stomate, the variable is set to ::large_value, !! which is defined in ::stomate_constants as 1.E33_r_std: IF ( ABS( SUM( minmoiavail_thisyear(:,2:nvm) ) ) .LT. min_stomate ) THEN ! in this case, set them to a very high value WRITE(numout,*) 'Warning! We have to initialize this year''s minimum '// & 'moisture availabilities.' minmoiavail_thisyear(:,:) = large_value ENDIF ! !! 1.4 reset firstcall_season flag ! firstcall_season = .FALSE. ENDIF ! determine min yearly clear sky radiation (solstice) as beginning for gdd count cloud(:) = zero CALL downward_solar_flux (npts, lalo(:,1),julian_diff,12.,cloud,1,solad,solai) WHERE (solad(:) .LT. gdd_init_date(:,2)) gdd_init_date(:,1)= julian_diff gdd_init_date(:,2)= solad(:) ENDWHERE ! !! NOTE: Sections 2. to 5. compute slowly-varying, "long-term" (i.e. weekly/monthly) !! input variables using a linear relaxation method, following the equation: !! \latexonly !! \input{season_lin_relax_eqn1.tex} !! \endlatexonly !! \n !! as described in the introduction to this subroutine (see Krinner et al., 2005). !! The time constant in the above equation is given for each of the variables !! described. ! ! !! 2. Moisture availability (relative soil moisture, including the root profile) : !! The time constants (as in the above equation) for these calculations are !! given by the parameters ::tau_hum_month (for the monthly !! calculation) or ::tau_hum_week (for the weekly), !! which are set in ::stomate_data to be 20 and 7 days respectively. !! If the moisture availability is less than zero, it is set to zero. !! These variables are mostly used in the phenological leaf onset and senescence !! models in the modules ::stomate_phenology and ::stomate_turnover, !! respectively. They are used in models which require a moisture limitation !! condition. These are the 'hum', 'moi', 'humgdd' and 'moigdd' onset models, !! and the 'mixed' and 'dry' (weekly only) senescence models. In addition, !! the weekly moisture availability is used to calculate the limitation !! on the fraction of NPP allocated to different compartments in the module !! ::stomate_alloc. ! ! !! 2.1 "monthly" (::moiavail_month) ! moiavail_month = ( moiavail_month * ( tau_hum_month - dt ) + & moiavail_daily * dt ) / tau_hum_month DO j = 2,nvm ! Loop over # PFTs WHERE ( ABS(moiavail_month(:,j)) .LT. EPSILON(zero) ) moiavail_month(:,j) = zero ENDWHERE ENDDO ! !! 2.2 "weekly" (::moiavail_week) ! moiavail_week = ( moiavail_week * ( tau_hum_week - dt ) + & moiavail_daily * dt ) / tau_hum_week DO j = 2,nvm ! Loop over # PFTs WHERE ( ABS(moiavail_week(:,j)) .LT. EPSILON(zero) ) moiavail_week(:,j) = zero ENDWHERE ENDDO ! !! 3. 2-meter temperatures !! The time constants for the "long-term", "monthly" and "weekly" 2-meter !! temperatures are given by the parameters ::tau_longterm_max, !! ::tau_t2m_month, and ::tau_t2m_week, !! which are set in ::stomate_data to be 3 * one year (in seconds, as !! described above) and 20 and 7 days respectively. !! If the temperature is less than zero, it is set to zero. !! In addition the "long term" temperature is written to the history file. \n !! These variables are used in many different modules of STOMATE. !! The longterm t2m is limied to the intervall [tlong_ref_min, tlong_ref_max] !! using the equation: !! \latexonly !! \input{season_t2m_long_ref_eqn3.tex} !! \endlatexonly !! \n !! The "monthly" and "weekly" temperature is used in the modules !! ::stomate_phenology and ::stomate_turnover for the onset and senescence !! phenological models which require a temperature condition. In addition !! the "monthly" temperature is used in ::lpj_constraints to determine !! the presence and regeneration of the vegetation and in the module !! ::stomate_assimtemp to calculate photosynthesis temperatures. ! Update tau_longterm tau_longterm = MIN(tau_longterm+dt,tau_longterm_max) ! Recalculate the reference temperature using the old reference temperature and the current temperature t2m_longterm(:) = ( t2m_longterm(:) * ( tau_longterm - dt ) + & t2m_daily(:) * dt ) / tau_longterm ! The longterm reference is not allowed to go outside the interval [tlong_ref_min, tlong_ref_max] t2m_longterm(:) = MAX( tlong_ref_min, MIN( tlong_ref_max, t2m_longterm(:) ) ) CALL xios_orchidee_send_field("t2m_longterm",t2m_longterm) CALL histwrite_p (hist_id_stomate, 'T2M_LONGTERM', itime, & t2m_longterm, npts, hori_index) ! !! 3.3 "monthly" (::t2m_month) ! t2m_month = ( t2m_month * ( tau_t2m_month - dt ) + & t2m_daily * dt ) / tau_t2m_month WHERE ( ABS(t2m_month(:)) .LT. EPSILON(zero) ) t2m_month(:) = zero ENDWHERE ! Store the day in onset_date when the leaves started grow. julian_diff is the day in the year [1-366]. WHERE ( begin_leaves(:,:) ) onset_date(:,:)=julian_diff ELSEWHERE onset_date(:,:)=0 ENDWHERE ! Calculate "seasonal" temperature WHERE ( t2m_week (:) .GT. ZeroCelsius ) Tseason_tmp(:) = Tseason_tmp(:) + t2m_week(:) Tseason_length(:)=Tseason_length(:) + dt ENDWHERE ! calculate Tmin in spring (after onset) DO j=1, nvm IF (leaf_tab(j)==1 .AND. pheno_type(j)==2) THEN ! leaf_tab=broadleaf and pheno_typ=summergreen ! Only treat broadleag and summergreen pfts WHERE ( Tmin_spring_time(:,j)>0 .AND. (Tmin_spring_time(:,j)0), and is set to "undef" when there is GPP !! (::time_lowgpp=0), as it is not used during the growing season. \n !! ::gdd_m5_dormance is further scaled by (::tau_gdd -dt / ::tau_gdd), !! - ::tau_gdd is set to 40. in the module ::stomate_constants. \n ! Nicolas Viovy - not sure why this is... !! This variable is used in the ::stomate_phenology module for the !! 'humgdd' and 'moigdd' leaf onset models. \n !! Each PFT is looped over but ::gdd_m5_dormance is only calculated for !! those PFTs for which a critical GDD is defined, i.e. those which are !! assigned to the 'humgdd' or 'moigdd' models. \n !! Finally if GDD sum is less than zero, then it is set to zero. ! DO j = 2,nvm ! Loop over # PFTs IF (.NOT. natural(j)) THEN ! reset counter: start of the growing season WHERE ((when_growthinit(:,j) .EQ. zero)) gdd_from_growthinit(:,j) = zero ENDWHERE ! increase gdd counter WHERE ( t2m_daily(:) .GT. (ZeroCelsius) ) gdd_from_growthinit(:,j) = gdd_from_growthinit(:,j) + & dt * ( t2m_daily(:) - (ZeroCelsius) ) ENDWHERE ELSE gdd_from_growthinit(:,j) = undef ENDIF ! only for PFTs for which critical gdd is defined ! gdd_m5_dormance is set to 0 at the end of the growing season. It is set to undef ! at the beginning of the growing season. IF ( ALL(pheno_gdd_crit(j,:) .NE. undef) ) THEN ! !! 7.1 set to zero if undefined and there is no GPP ! WHERE (gdd_init_date(:,1) .EQ. julian_diff) gdd_m5_dormance(:,j) = zero ENDWHERE ! !! 7.2 set to undef if there is GPP ! WHERE ( when_growthinit(:,j) .EQ. zero ) gdd_m5_dormance(:,j) = undef ENDWHERE ! !! 7.3 normal update as described above where ::gdd_m5_dormance is defined (not set to "undef"). ! WHERE ( ( t2m_daily(:) .GT. ( ZeroCelsius - gdd_threshold ) ) .AND. & ( gdd_m5_dormance(:,j) .NE. undef ) ) gdd_m5_dormance(:,j) = gdd_m5_dormance(:,j) + & dt * ( t2m_daily(:) - ( ZeroCelsius - gdd_threshold ) ) ENDWHERE WHERE ( gdd_m5_dormance(:,j) .NE. undef ) gdd_m5_dormance(:,j) = gdd_m5_dormance(:,j) * & ( tau_gdd - dt ) / tau_gdd ENDWHERE ENDIF ENDDO ! !! 7.4 Set to zero if GDD is less than zero. DO j = 2,nvm ! Loop over # PFTs WHERE ( ABS(gdd_m5_dormance(:,j)) .LT. EPSILON(zero) ) gdd_m5_dormance(:,j) = zero ENDWHERE ENDDO ! !! 8. Calculate the growing degree days (GDD) since midwinter (::gdd_midwinter) !! This variable represents the GDD sum of temperatures higher than a PFT-dependent !! threshold (::ncdgdd_temp), since midwinter. !! Midwinter is detected if the monthly temperature (::t2m_month) is lower than the weekly !! temperature (::t2m_week) AND if the monthly temperature is lower than the long-term !! temperature (t2m_longterm). These variables were calculated earlier in this subroutine. \n !! ::gdd_midwinter is initialised to 0.0 when midwinter is detected, and from then on !! increased with each temperature greater than ::ncdgdd_temp, which is defined !! in the module ::stomate_constants. \n !! ::gdd_midwinter is set to "undef" when midsummer is detected, following the opposite !! conditions to those used to define midwinter. \n !! The variable is used in the ::stomate_phenology module for the leaf onset model 'ncdgdd'. !! Each PFT is looped over but the ::gdd_midwinter is only calculated for those !! PFTs for which a critical 'ncdgdd' temperature is defined, i.e. those which are !! assigned to the 'ncdgdd' model. \n ! DO j = 2,nvm ! Loop over # PFTs ! only for PFTs for which ncdgdd_crittemp is defined IF ( ncdgdd_temp(j) .NE. undef ) THEN ! !! 8.1 set to 0 if undef and if we detect "midwinter" ! !!$ WHERE ( ( gdd_midwinter(:,j) .EQ. undef ) .AND. & !!$ ( t2m_month(:) .LT. t2m_week(:) ) .AND. & !!$ ( t2m_month(:) .LT. t2m_longterm(:) ) ) WHERE (gdd_init_date(:,1) .EQ. julian_diff) gdd_midwinter(:,j) = zero ENDWHERE ! !! 8.2 set to undef if we detect "midsummer" ! WHERE ( ( t2m_month(:) .GT. t2m_week(:) ) .AND. & ( t2m_month(:) .GT. t2m_longterm(:) ) ) gdd_midwinter(:,j) = undef ENDWHERE ! !! 8.3 normal update as described above ! WHERE ( ( gdd_midwinter(:,j) .NE. undef ) .AND. & ( t2m_daily(:) .GT. ncdgdd_temp(j)+ZeroCelsius ) ) gdd_midwinter(:,j) = & gdd_midwinter(:,j) + & dt * ( t2m_daily(:) - ( ncdgdd_temp(j)+ZeroCelsius ) ) ENDWHERE ENDIF ENDDO ! !! 9. Calculate the number of chilling days (NCD) since leaves were lost (::ncd_dormance). !! This variable is initialised to 0 at the beginning of the dormancy period (::time_lowgpp>0) !! and increased by the stomate time step when the daily temperature is lower than the !! PFT-dependent threshold ::ncdgdd_temp, which is defined for each PFT !! in a table (::ncdgdd_temp_tab) in the module ::stomate_data. \n !! It is set to "undef" when there is GPP (::time_lowgpp=0) as it is not needed during !! the growing season. \n !! The variable is used in the ::stomate_phenology module for the leaf onset model 'ncdgdd'. !! Each PFT is looped over but the ::ncd_dormance is only calculated for those !! PFTs for which a critical 'ncdgdd' temperature is defined, i.e. those which are !! assigned to the 'ncdgdd' model. ! DO j = 2,nvm ! Loop over # PFTs IF ( ncdgdd_temp(j) .NE. undef ) THEN ! !! 9.1 set to zero if undefined and there is no GPP ! WHERE (gdd_init_date(:,1) .EQ. julian_diff) ncd_dormance(:,j) = zero ENDWHERE ! !! 9.2 set to undef if there is GPP ! WHERE ( when_growthinit(:,j) .EQ. zero ) ncd_dormance(:,j) = undef ENDWHERE ! !! 9.3 normal update, as described above, where ::ncd_dormance is defined ! WHERE ( ( ncd_dormance(:,j) .NE. undef ) .AND. & ( t2m_daily(:) .LE. ncdgdd_temp(j)+ZeroCelsius ) ) ncd_dormance(:,j) = MIN( ncd_dormance(:,j) + dt, ncd_max ) ENDWHERE ENDIF ENDDO ! !! 10. Calculate the number of growing days (NGD) since leaves were lost (::ngd_minus5). !! This variable is initialised to 0 at the beginning of the dormancy period (::time_lowgpp>0) !! and increased by the stomate time step when the daily temperature is higher than the threshold !! -5 degrees C. \n !! ::ngd_minus5 is further scaled by (::tau_ngd -dt / ::tau_ngd), !! - ::tau_ngd is set to 50. in the module ::stomate_constants. \n ! Nicolas Viovy - not sure why this is... !! The variable is used in the ::stomate_phenology module for the leaf onset model 'ngd'. !! Each PFT is looped over. !! If the NGD is less than zero, it is set to zero. ! DO j = 2,nvm ! Loop over # PFTs ! !! 10.1 Where there is GPP (i.e. ::time_lowgpp=0), set NGD to 0. !! This means that we only take into account NGDs when the leaves are off ! WHERE (gdd_init_date(:,1) .EQ. julian_diff) ngd_minus5(:,j) = zero ENDWHERE ! !! 10.2 normal update, as described above. ! WHERE ( t2m_daily(:) .GT. (ZeroCelsius - gdd_threshold) ) ngd_minus5(:,j) = ngd_minus5(:,j) + dt ENDWHERE ngd_minus5(:,j) = ngd_minus5(:,j) * ( tau_ngd - dt ) / tau_ngd ENDDO DO j = 2,nvm ! Loop over # PFTs WHERE ( ABS(ngd_minus5(:,j)) .LT. EPSILON(zero) ) ngd_minus5(:,j) = zero ENDWHERE ENDDO ! !! 11. Calculate the minimum humidity/relative soil moisture since dormance began (::hum_min_dormance) !! and the time elapsed since this minimum (::time_hum_min). \n !! The minimum moisture availability occurs when the monthly moisture availability, which is updated !! daily earlier in this subroutine as previously described, is at a minimum during the dormancy period. !! Therefore the ::hum_min_dormance is initialised to the monthly moisture availability !! at the beginning of the dormancy period (i.e. if it was previously set to undefined and the !! ::time_lowgpp>0) AND then whenever the monthly moisture availability is less than it has previously !! been. \n !! Consequently, the time counter (::time_hum_min) is initialised to 0 at the beginning of the dormancy !! period (i.e. if it was previously set to undefined and the ::time_lowgpp>0) AND when the minimum !! moisture availability is reached, and is increased by the stomate time step every day throughout !! the dormancy period. \n !! ::time_hum_min is used in the ::stomate_phenology module for the leaf onset models 'moi' and 'moigdd'. !! Each PFT is looped over but the two variables are only calculated for those !! PFTs for which the critical parameter ::hum_min_time is defined, i.e. !! those which are assigned to the 'moi' or 'moigdd' models. ! DO j = 2,nvm ! Loop over # PFTs IF ( hum_min_time(j) .NE. undef ) THEN ! !! 11.1 initialize if undefined and there is no GPP ! WHERE (when_growthinit(:,j) .EQ. zero) time_hum_min(:,j) = zero hum_min_dormance(:,j) = moiavail_month(:,j) ENDWHERE ! !! 11.3 normal update, as described above, where ::time_hum_min and ::hum_min_dormance are defined ! !! 11.3.1 increase time counter by the stomate time step WHERE ( hum_min_dormance(:,j) .NE. undef ) time_hum_min(:,j) = time_hum_min(:,j) + dt ENDWHERE !! 11.3.2 set time counter to zero if minimum is reached WHERE (( hum_min_dormance(:,j) .NE. undef ) .AND. & ( moiavail_month(:,j) .LE. hum_min_dormance(:,j) ) ) hum_min_dormance(:,j) = moiavail_month(:,j) time_hum_min(:,j) = zero ENDWHERE ENDIF ENDDO ! !! NOTE: Sections 12. to 14. compute slowly-varying, "long-term" (i.e. weekly/monthly) !! C fluxes (NPP, turnover, GPP) using the same linear relaxation method as in !! Sections 2. and 5. and described in the introduction to this section, as given !! by the following equation: !! \latexonly !! \input{season_lin_relax_eqn1.tex} !! \endlatexonly !! \n !! The following variables are calculated using the above equation, and the time constant !! is given for each. ! ! !! 12. Update the "long term" NPP. (::npp_daily in gC/m^2/day, ::npp_longterm in gC/m^2/year.) !! The time constant is given by the parameter ::tau_longterm, !! which is set in ::stomate_data to be 3 * one year (in seconds, as !! described above). If the ::npp_longterm is less than zero then set it to zero. \n !! ::npp_longterm is used in ::stomate_lpj in the calculation of long-term !! vegetation dynamics and in ::stomate_lcchange in the calculation of !! land cover change. It is also used to calculate diagnose the hebivory activity in !! Section 22 of this subroutine. ! npp_longterm = ( npp_longterm * ( tau_longterm - dt ) + & (npp_daily*one_year) * dt ) / & tau_longterm DO j = 2,nvm ! Loop over # PFTs WHERE ( ABS(npp_longterm(:,j)) .LT. EPSILON(zero) ) npp_longterm(:,j) = zero ENDWHERE ENDDO ! !! 13. Update the "long term" turnover rates (in gC/m^2/year). !! The time constant is given by the parameter ::tau_longterm, !! which is set in ::stomate_data to be 3 * one year (in seconds, as !! described above). If the ::turnover_longterm is less than zero then set it to zero.\n !! ::turnover_longterm is used in ::stomate_lpj and :: lpg_gap in the calculation !! of long-term vegetation dynamics. ! turnover_longterm(:,:,:,:) = ( turnover_longterm(:,:,:,:) * ( tau_longterm - dt ) + & (turnover_daily(:,:,:,:)*one_year) * dt ) / & tau_longterm DO j = 2,nvm ! Loop over # PFTs WHERE ( ABS(turnover_longterm(:,j,:,:)) .LT. EPSILON(zero) ) turnover_longterm(:,j,:,:) = zero ENDWHERE ENDDO ! !! 14. Update the "weekly" GPP (where there is vegetation), otherwise set to zero. !! The time constant is given by the parameter ::tau_gpp_week, !! which is set in ::stomate_data to be 7 days. If the ::gpp_week is !! less than zero then set it to zero. \n !! ::gpp_week is used to update the annual maximum weekly GPP (::maxgppweek_thisyear) !! in Section 16 of this subroutine, which is then used to update the variable !! ::maxgppweek_lastyear in Section 21 of this subroutine. Both ::gpp_week and !! ::maxgppweek_lastyear are used in Section 6 of this subroutine to calculate !! the onset and time-length of the dormancy period. ! Note: Used to be weekly GPP divided by veget_cov_max, i.e. per ground covered, but not anymore. ! WHERE ( veget_cov_max .GT. zero ) gpp_week = ( gpp_week * ( tau_gpp_week - dt ) + & gpp_daily * dt ) / tau_gpp_week ELSEWHERE gpp_week = zero ENDWHERE DO j = 2,nvm ! Loop over # PFTs WHERE ( ABS(gpp_week(:,j)) .LT. EPSILON(zero) ) gpp_week(:,j) = zero ENDWHERE ENDDO ! !! 15. Update the maximum and minimum moisture availabilities (::maxmoiavail_thisyear !! and ::minmoiavail_thisyear). If the daily moisture availability, ::moiavail_daily, !! which was calculated earlier in this subroutine, is greater or less than the current !! value of the maximum or minimum moisture availability, then set the value for the maximum !! or minimum to the current daily value respectively. \n !! ::maxmoiavail_thisyear and ::minmoiavail_thisyear are used to update the variables !! ::maxmoiavail_lastyear and ::minmoiavail_lastyear in Section 21 of this subroutine, !! which are used in the module ::stomate_phenology for the leaf onset models 'hum' and !! 'humgdd', and in the module ::stomate_turnover for the leaf senescence models 'dry' !! and 'mixed'. ! WHERE ( moiavail_daily .GT. maxmoiavail_thisyear ) maxmoiavail_thisyear = moiavail_daily ENDWHERE WHERE ( moiavail_daily .LT. minmoiavail_thisyear ) minmoiavail_thisyear = moiavail_daily ENDWHERE ! !! 16. Update the annual maximum weekly GPP (::maxgppweek_thisyear), if the weekly GPP !! is greater than the current value of the annual maximum weekly GPP. !! The use of this variable is described in Section 14. ! WHERE ( gpp_week .GT. maxgppweek_thisyear ) maxgppweek_thisyear = gpp_week ENDWHERE ! !! 17. Update the annual GDD0 by adding the current daily 2-meter temperature !! (multiplied by the stomate time step, which is one day), if it is greater !! than zero degrees C. \n !! This variable is mostly used in the module ::lpj_establish. ! WHERE ( t2m_daily .GT. ZeroCelsius ) gdd0_thisyear = gdd0_thisyear + dt * ( t2m_daily - ZeroCelsius ) ENDWHERE ! !! 18. Update the annual precipitation by adding the current daily precipitation !! amount (multiplied by the stomate time step, which is usually one day). \n ! precip_thisyear = precip_thisyear + dt * precip_daily ! !! 19. Update the annual maximum leaf mass for each PFT (::lm_thisyearmax) and the maximum fractional !! plant cover if the LPJ DGVM is activated. ! ! !! 19.1 If the LPJ DGVM is activated first the fraction of natural vegetation (::fracnat), i.e. non- !! agricultural vegetation (PFTs 2-11) is calculated for each PFT. Each PFT is looped over. ! IF(ok_dgvm ) THEN fracnat(:) = un DO j = 2,nvm ! Loop over # PFTs IF ( .NOT. natural(j) ) THEN fracnat(:) = fracnat(:) - veget_cov_max(:,j) ENDIF ENDDO ENDIF ! !! 19.2 If LPJ and STOMATE are activated, first the maximum fractional plant cover needs to be updated, !! and then this year's leaf biomass. Each PFT is looped over. !! Both are updated according to the linear relaxation method described above. !! \latexonly !! \input{season_lin_relax_eqn1.tex} !! \endlatexonly !! \n !! The time constant for this process is set as one year (in seconds) divided by the parameter !! ::leaflife_tab, which gives the leaf lifetime in years and is set for each PFT in the module !! ::stomate_constants. Each PFT is looped over. \n ! IF ( ok_stomate ) THEN IF(ok_dgvm ) THEN DO j=2,nvm ! Loop over # PFTs ! !! 19.2.1 Calculate maximum fractional plant cover (::maxfpc_lastyear). !! If natural vegetation is present in the grid cell, and the leaf !! biomass is greater than three-quarters of last year's leaf biomass, the maximum fractional plant !! cover for last year is updated. \n !! The short-term variable (Xs in the above equation) that is being used to update the long-term !! maximum fractional plant cover is the fractional cover of natural vegetation, specified as !! ::veget_cov/::fracnat. Last year's value is then set to be this year's value. ! IF ( natural(j) .AND. ok_dgvm ) THEN WHERE ( fracnat(:) .GT. min_stomate .AND. biomass(:,j,ileaf,icarbon).GT. lm_lastyearmax(:,j)*0.75 ) maxfpc_lastyear(:,j) = ( maxfpc_lastyear(:,j) * ( one_year/leaflife_tab(j)- dt ) + & veget_cov(:,j) / fracnat(:) * dt ) / (one_year/leaflife_tab(j)) ENDWHERE maxfpc_thisyear(:,j) = maxfpc_lastyear(:,j) ! just to initialise value ENDIF !NV : correct initialization !!$ WHERE(biomass(:,j,ileaf,icarbon).GT. lm_lastyearmax(:,j)*0.75) !!$ lm_lastyearmax(:,j) = ( lm_lastyearmax(:,j) * ( one_year/leaflife_tab(j)- dt ) + & !!$ biomass(:,j,ileaf,icarbon) * dt ) / (one_year/leaflife_tab(j)) !!$ ENDWHERE !!$ lm_thisyearmax(:,j)=lm_lastyearmax(:,j) ! just to initialise value ! !! 19.2.2 Update this year's leaf biomass (::lm_thisyearmax). !! The short-term variable (Xs in the above equation) that is being used to update the long-term !! this year's leaf biomass is the leaf biomass pool (::biomass(i,j,ileaf). ! WHERE (lm_thisyearmax(:,j) .GT. min_stomate) WHERE(biomass(:,j,ileaf,icarbon).GT. lm_thisyearmax(:,j)*0.75) lm_thisyearmax(:,j) = ( lm_thisyearmax(:,j) * ( one_year/leaflife_tab(j)- dt ) + & biomass(:,j,ileaf,icarbon) * dt ) / (one_year/leaflife_tab(j)) ENDWHERE ELSEWHERE lm_thisyearmax(:,j) =biomass(:,j,ileaf,icarbon) ENDWHERE ENDDO ELSE ! !! 19.3 If LPJ DGVM is not activated but STOMATE is, the maximum leaf mass is set to be the same !! as the leaf biomass (::biomass(i,j,ileaf), without a change in the maximum fractional plant cover. ! DO j = 2,nvm ! Loop over # PFTs WHERE ( biomass(:,j,ileaf,icarbon) .GT. lm_thisyearmax(:,j) ) lm_thisyearmax(:,j) = biomass(:,j,ileaf,icarbon) ENDWHERE ENDDO ENDIF !(ok_dgvm) ELSE ! !! 19.4 If STOMATE is not activated, the maximum leaf biomass is set to be the maximum possible !! LAI of the PFT. ! DO j = 2,nvm ! Loop over # PFTs lm_thisyearmax(:,j) = lai_max(j) / sla(j) ENDDO ENDIF !(ok_stomate) ! !! 20. Update the annual maximum fractional plant cover for each PFT if the current fractional cover !! (::veget_cov), is larger than the current maximum value. !! ::veget_cov is defined as fraction of total ground. Therefore, maxfpc_thisyear has the same unit. ! WHERE ( veget_cov(:,:) .GT. maxfpc_thisyear(:,:) ) maxfpc_thisyear(:,:) = veget_cov(:,:) ENDWHERE ! !! 21. At the end of the every year, last year's maximum and minimum moisture availability, !! annual GDD0, annual precipitation, annual max weekly GPP, and maximum leaf mass are !! updated with the value calculated for the current year, and then their value reset. !! Either to zero for the maximum variables, or to ::large_value (set to be 1.E33 in :: !! the module ::stomate_constants) for the minimum variable ::minmoiavail_thisyear. ! IF ( LastTsYear ) THEN ! !! 21.1 Update last year's values. \n !! The variables ::maxmoiavail_lastyear, ::minmoiavail_lastyear and ::maxgppweek_lastyear !! are updated using the relaxation method: !! \latexonly !! \input{season_lin_relax_eqn1.tex} !! \endlatexonly !! \n !! where Xs is this year's value, dt (Delta-t) is set to 1 (year), and the time constant (tau) !?? !! is set by the parameter ::tau_climatology, which is set to 20 years at the beginning !! of this subroutine. \n !! The other variables (::gdd0_lastyear, ::precip_lastyear, ::lm_lastyearmax and !! ::maxfpc_lastyear) are just replaced with this year's value. ! !NVMODIF maxmoiavail_lastyear(:,:) = (maxmoiavail_lastyear(:,:)*(tau_climatology-1)+ maxmoiavail_thisyear(:,:))/tau_climatology minmoiavail_lastyear(:,:) = (minmoiavail_lastyear(:,:)*(tau_climatology-1)+ minmoiavail_thisyear(:,:))/tau_climatology maxgppweek_lastyear(:,:) =( maxgppweek_lastyear(:,:)*(tau_climatology-1)+ maxgppweek_thisyear(:,:))/tau_climatology ! maxmoiavail_lastyear(:,:) = maxmoiavail_thisyear(:,:) ! minmoiavail_lastyear(:,:) = minmoiavail_thisyear(:,:) ! maxgppweek_lastyear(:,:) = maxgppweek_thisyear(:,:) gdd0_lastyear(:) = gdd0_thisyear(:) precip_lastyear(:) = precip_thisyear(:) lm_lastyearmax(:,:) = lm_thisyearmax(:,:) maxfpc_lastyear(:,:) = maxfpc_thisyear(:,:) ! Calculate Tseason Tseason(:) = zero WHERE ( Tseason_length(:) .GT. min_sechiba ) Tseason(:) = Tseason_tmp(:) / Tseason_length(:) ENDWHERE ! !! 21.2 Reset new values for the "this year" variables. \n !! The maximum variables are set to zero and the minimum variable ::minmoiavail_thisyear !! is set to ::large_value (set to be 1.E33 in the module ::stomate_constants). ! maxmoiavail_thisyear(:,:) = zero minmoiavail_thisyear(:,:) = large_value maxgppweek_thisyear(:,:) = zero gdd0_thisyear(:) = zero precip_thisyear(:) = zero lm_thisyearmax(:,:) = zero maxfpc_thisyear(:,:) = zero Tseason_tmp(:) = zero Tseason_length(:) =zero Tmin_spring_time(:,:)=zero onset_date(:,:)=zero ! ! 21.3 Special treatment for maxfpc. !?? !! 21.3 Set the maximum fractional plant cover for non-natural vegetation !! (i.e. agricultural C3 and C4 - PFT 12 and 13) vegetation for last year to be zero. ! ! ! 21.3.1 Only take into account natural PFTs ! DO j = 2,nvm ! Loop over # PFTs IF ( .NOT. natural(j) ) THEN maxfpc_lastyear(:,j) = zero ENDIF ENDDO ! 21.3.2 In Stomate, veget_cov is defined as a fraction of ground, not as a fraction ! of total ground. maxfpc_lastyear will be compared to veget_cov in lpj_light. ! Therefore, we have to transform maxfpc_lastyear. ! 21.3.3 The sum of the maxfpc_lastyear for natural PFT must not exceed fpc_crit (=.95). ! However, it can slightly exceed this value as not all PFTs reach their maximum ! fpc at the same time. Therefore, if sum(maxfpc_lastyear) for the natural PFTs ! exceeds fpc_crit, we scale the values of maxfpc_lastyear so that the sum is ! fpc_crit. !!$ ! calculate the sum of maxfpc_lastyear !!$ sumfpc_nat(:) = zero !!$ DO j = 2,nvm ! Loop over # PFTs !!$ sumfpc_nat(:) = sumfpc_nat(:) + maxfpc_lastyear(:,j) !!$ ENDDO !!$ !!$ ! scale so that the new sum is fpc_crit !!$ DO j = 2,nvm ! Loop over # PFTs !!$ WHERE ( sumfpc_nat(:) .GT. fpc_crit ) !!$ maxfpc_lastyear(:,j) = maxfpc_lastyear(:,j) * (fpc_crit/sumfpc_nat(:)) !!$ ENDWHERE !!$ ENDDO ENDIF ! LastTsYear ! !! 22. Diagnose herbivore activity (::herbivores), determined as probability for a leaf to be !! eaten in a day (follows McNaughton et al., 1989). \n !! The amount of herbivore activity is used in the modules ::lpj_establish !! and ::stomate_turnover. ! ! !! 22.1 First calculate the mean long-term leaf NPP in grid box, mean residence !! time (years) of green tissue to give the biomass available for herbivore consumption. !! Each PFT is looped over, though the calculation is only made for !! natural vegetation (PFTs 2-11). ! nlflong_nat(:,:) = zero weighttot(:,:) = zero green_age(:,:) = zero ! DO j = 2,nvm ! Loop over # PFTs ! IF ( natural(j) ) THEN ! !! 22.1.1 Calculate the total weight of the leaves (::weighttot) as last year's leaf biomass ! weighttot(:,j) = lm_lastyearmax(:,j) ! !! 22.1.2 Calculate the mean long-term leaf NPP as the long-term NPP calculated in Section 12 of !! this subroutine weighted by the leaf fraction (::leaf_frac), which is defined to be 0.33 !! at the beginning of this subroutine. ! nlflong_nat(:,j) = npp_longterm(:,j) * leaf_frac_hvc ! !! 22.1.3 Calculate the mean residence time of the green tissue (::green_age) !! This is calculated as the sum of 6 months !! for natural seasonal vegetation (i.e. PFTs 3, 6, 8-11), and 2 years for evergreen !! (PFTs 2, 4, 5, 8), multiplied by last year's leaf biomass for each PFT, divided by the !! total weight of the leaves for all PFTs. ! This is a crude approximation. !!?? By whom? !! The difference between seasonal and evergreen vegetation is determined by the parameter !! ::pheno_model, which specifies the onset model of the PFT. ! IF ( pheno_model(j) .EQ. 'none' ) THEN green_age(:,j) = green_age_ever * lm_lastyearmax(:,j) ELSE green_age(:,j) = green_age_dec * lm_lastyearmax(:,j) ENDIF ! ENDIF ! ENDDO ! WHERE ( weighttot(:,:) .GT. min_sechiba ) green_age(:,:) = green_age(:,:) / weighttot(:,:) ELSEWHERE green_age(:,:) = un ENDWHERE ! !! 22.2 McNaughton et al. (1989) give herbivore consumption as a function of mean, long-term leaf NPP. !! as it gives an estimate of the edible biomass. The consumption of biomass by herbivores and the !! resultant herbivore activity are calculated following the equations: !! \latexonly !! \input{season_consumption_eqn4.tex} !! \endlatexonly !! \n !! and !! \latexonly !! \input{season_herbivore_eqn5.tex} !! \endlatexonly !! \n ! DO j = 2,nvm ! Loop over # PFTs ! IF ( natural(j) ) THEN ! WHERE ( nlflong_nat(:,j) .GT. zero ) consumption(:) = hvc1 * nlflong_nat(:,j) ** hvc2 herbivores(:,j) = one_year * green_age(:,j) * nlflong_nat(:,j) / consumption(:) ELSEWHERE herbivores(:,j) = 100000. ENDWHERE ! ELSE ! herbivores(:,j) = 100000. ! ENDIF ! ENDDO herbivores(:,ibare_sechiba) = zero IF (printlev>=4) WRITE(numout,*) 'Leaving season' END SUBROUTINE season END MODULE stomate_season