#include <misc.h> #include <preproc.h> module CASAMod 12,9 #if (defined CASA) !----------------------------------------------------------------------- !BOP ! ! !MODULE: CASAMod ! ! !DESCRIPTION: ! Terrestrial carbon cycle submodel patterned after the CASA model. ! ! !USES: use shr_kind_mod, only : r8 => shr_kind_r8 use abortutils , only : endrun use clmtype use clm_atmlnd , only : clm_a2l use clm_varcon , only : denh2o, hvap, istsoil, tfrz, spval use clm_varpar , only : numpft, nlevsoi, nlevgrnd use clm_varctl , only : iulog use spmdMod , only : masterproc use CASAPhenologyMod, only : CASAPhenology ! ! !PUBLIC TYPES: implicit none save ! ----------------------------------------------------------------- ! source file: casa_params.h ! purpose: CASA V2.1 parameters and variables ! modified for LSM/CASA interface by J.John (2001) ! ----------------------------------------------------------------- ! Namelist parameters for CASA integer :: spunup ! 0=no, 1=yes (used with nsrest/=1 only) integer :: lalloc ! 0=fixed allocation, 1=dynamic allocation integer :: lnpp ! 1=gpp*gppfact,2=fn(lgrow)*gppfact real(r8) :: q10 character(len=256) :: fcpool ! Carbon Pool initial state filename ! Logical to flag whether C pools have been read in on initial dataset logical :: cpool_inic = .false. ! Define parameters used in CASA ! Pool Definitions integer, parameter :: nlive = 3 integer, parameter :: ndead = 9 integer, parameter :: npools = nlive + ndead integer, parameter :: LEAF = 1 integer, parameter :: WOOD = 2 integer, parameter :: FROOT = 3 integer, parameter :: SURFMET = 4 integer, parameter :: SURFSTR = 5 integer, parameter :: SOILMET = 6 integer, parameter :: SOILSTR = 7 integer, parameter :: CWD = 8 integer, parameter :: SURFMIC = 9 integer, parameter :: SOILMIC = 10 integer, parameter :: SLOW = 11 integer, parameter :: PASSIVE = 12 integer, parameter :: npool_types = 4 integer, parameter :: LIVE_TYPE = 1 integer, parameter :: LITTER_TYPE = 2 integer, parameter :: SOIL_TYPE = 3 integer, parameter :: CWD_TYPE = 4 ! Tracer Definitions integer, parameter :: ptrace = 2 integer, parameter :: Carbon = 1 integer, parameter :: Nitrogen = 2 ! Respiration definitions integer, parameter :: nresp_pools = 14 integer resp_pool_index(2,nresp_pools) ! Indices of Respiring Pools in the integer pool_type_index(npools) ! Index of pool type ! type definitions for pools in the order specified above data pool_type_index/ & LIVE_TYPE, & LIVE_TYPE, & LIVE_TYPE, & LITTER_TYPE, & LITTER_TYPE, & LITTER_TYPE, & LITTER_TYPE, & CWD_TYPE, & SOIL_TYPE, & SOIL_TYPE, & SOIL_TYPE, & SOIL_TYPE/ ! order that respiration is called data resp_pool_index/ & SLOW ,PASSIVE, & SLOW ,SOILMIC, & SURFMET ,SURFMIC, & SURFSTR ,SURFMIC, & SURFSTR ,SLOW , & SOILMET ,SOILMIC, & SOILSTR ,SOILMIC, & SOILSTR ,SLOW , & CWD ,SURFMIC, & CWD ,SLOW , & SURFMIC ,SLOW , & SOILMIC ,PASSIVE, & SOILMIC ,SLOW , & PASSIVE ,SOILMIC/ ! C:N ratio for pools real(r8) CNratio(npools) data CNratio/ & 30.0_r8, & ! C:N ratio of leaf pool 130.0_r8, & ! C:N ratio of wood pool 55.0_r8, & ! C:N ratio of froot pool 30.0_r8, & ! C:N ratio of surfmet pool 50.0_r8, & ! C:N ratio of surfstr pool 25.0_r8, & ! C:N ratio of soilmet pool 50.0_r8, & ! C:N ratio of soilstr pool 135.0_r8, & ! C:N ratio of cwd pool 12.5_r8, & ! C:N ratio of surfmic pool 12.5_r8, & ! C:N ratio of soilmic pool 12.5_r8, & ! C:N ratio of slow pool 8.5_r8/ ! C:N ratio of passive pool ! LSM PFT assigned to CASA veg type ! 02/07/08 assign LSM PFT 14 (bare) to CASA type 8 (which does not exist) ! LSM: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ! CASA: 4 5 1 2 6 7 9 11 10 10 12 12 6 8 ! Mapping of LSM types to CLM types ! CLM : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ! LSM : 1 1 2 3 3 5 4 4 7 8 9 10 6 13 11 11 ! set values of parameters/constants used to determine PLAI ! min/max values of PLAI ! July 8 2002 - From Inez ! (2) Leaf and Roots: Max LAI ! Trees - PFT 1,2,3,4,5: Max lai=6 ! grass and crops - PFT 6,10, 11, 12, 13: Max lai=3 ! shrubs - PFT 7,8,9 - Max lai=1.5 ! bare: PFT 14: max lai=0 !(3) Leaf and Roots - min LAI = 0.4 for photosynthesis. ! I got this by looking at non-zero gai values in vegconi.F (Figure 2). I am ! hopeful that LGROW will turn off photosynthesis during the winter. ! CAVEAT: On page 19 of LSM documentation, it seems that leaf and stem ! areas enter into the calculation of albedo. I am not sure where to set ! the min LAI, so that min LAI does not contribute to winter albedos. !.. 03/02/28 change plai_min to Dickinson value real(r8) plai_min(0:numpft) ! min value of PLAI !.. mod 02/07/17 these are peak gai values from LSM1.1 (see vegconi.F) real(r8) plai_max(0:numpft) ! max value of PLAI data plai_min/0.0_r8, 16*0.8_r8/ data plai_max/0.0_r8, 5.0_r8, 5.0_r8, 2.6_r8, 4.5_r8, 4.5_r8, 3.0_r8, 4.7_r8, 4.7_r8, & 1.0_r8, 0.9_r8, 1.4_r8, 3.5_r8, 3.5_r8, 3.5_r8, 3.0_r8, 3.0_r8/ ! sla values below were used in LSM_CASA ! see initCasa below for current CLM values ! Specific Leaf area from Dickinson et al. (J.Clim, Nov. 1998) ! as inferred from summary of observed values by Schulze et al. ! Unit is m2 leaf area/kg C ! Veg Type SLA (m2/kg C) LSM veg type ! crops 60 11,12 ! short grass 40 6,13 ! needleleaf evergreen 10 1 ! deciduous needleleaf 30 2 ! deciduous broadleaf 30 4,5 ! broadleaf evergreen 25 3 ! evergreen shrubs 25 7 ! deciduous shrubs 25 8,9 ! tall grass 35 6,13 ! tundra and semidesert 20 10 ! check SLA values for LSM veg types 5, 6/13, 8/9, 10, 11/12 ! data sla/ ! & 10.0, 30.0, 25.0, 30.0, 30.0, 40.0, 25.0, ! & 25.0, 25.0, 20.0, 60.0, 60.0, 35.0, 0.0/ real(r8) lrage(0:numpft) real(r8) woodage(0:numpft) real(r8) litcn(0:numpft) real(r8) lignin(0:numpft) ! age characteristic parameters data lrage/ 0.00_r8, & 5.00_r8, 5.00_r8, 1.80_r8, 1.80_r8, 1.80_r8, 1.80_r8, 1.20_r8, 1.20_r8, & 1.00_r8, 1.00_r8, 2.80_r8, 2.80_r8, 1.50_r8, 1.80_r8, 1.00_r8, 1.00_r8/ data woodage/0.00_r8, & 42.00_r8,42.00_r8,27.00_r8,41.00_r8,41.00_r8,25.00_r8,58.00_r8,58.00_r8, & 5.50_r8, 1.00_r8, 5.50_r8, 5.50_r8, 0.00_r8,25.00_r8, 0.00_r8, 0.00_r8/ ! litter characteristic parameters - lignin:N, C:N, lignin data litcn/ 0.0_r8, & 80.0_r8, 80.0_r8, 50.0_r8, 40.0_r8, 40.0_r8, 50.0_r8, 50.0_r8, 50.0_r8, & 65.0_r8, 50.0_r8, 50.0_r8, 50.0_r8, 50.0_r8, 50.0_r8, 40.0_r8, 40.0_r8/ data lignin/ 0.0_r8, & 0.25_r8, 0.25_r8, 0.20_r8, 0.20_r8, 0.20_r8, 0.15_r8, 0.20_r8, 0.20_r8, & 0.20_r8, 0.15_r8, 0.15_r8, 0.15_r8, 0.10_r8, 0.15_r8, 0.10_r8, 0.10_r8/ ! Estimate of lignin content of wood C real(r8), parameter :: woodligninfract = 0.40_r8 ! scaling factors for NPP real(r8), parameter :: gppfact = 0.5_r8 ! converts GPP to NPP ! 30cm depth for watdry, watopt, smoist, soilt (m) real(r8), parameter :: z30 = 0.3_r8 ! 30cm depth for smoist, soilt (m) ! set up array of nonwood types (based on pft) used in allocation ! lnonwood=1 if nonwoods (ivt = 6,7,8, 11, 12, 13, 14) ! lnonwood=0 if wood ! Look at LSM Table 2 - PFT composition of surface_types. Note at ! "nonwoods" category. All grass, shrubs are non-woods. However, if you ! look at stembvt, artic shrub and arctic grass have 0.1 kg/m2. So I ! suggest initial wood biomass = 0 for PFT types 6,7,8, 11, 12, 13, 14. ! For CLM, this corresponds to pfts: 9, 10, 13, 14, 15, 16 integer :: lnonwood(0:numpft) data lnonwood/0, & 0, 0, 0, 0, 0, 0, 0, 0, & 1, 1, 0, 0, 1, 1, 1, 1/ ! ! !PUBLIC MEMBER FUNCTIONS: public :: initCASA ! initialize the CASA submodel public :: CASA_ecosystemDyn ! the main submodel interface public :: CASARest ! CASA restart ! ! !REVISION HISTORY: ! Ported to the Community Land Model (CLM) by Jasmin John, Sam Levis, and ! Mariana Vertenstein. ! 2004.06.08 Vectorized and reformatted by Forrest Hoffman ! !----------------------------------------------------------------------- ! !PRIVATE DATA MEMBERS: !EOP real(r8) sla(0:numpft) ! specific leaf area real(r8) leafmin(0:numpft) ! min leafmass (g C/m2 ground) real(r8) leafmax(0:numpft) ! max leafmass (g C/m2 ground) real(r8) solubfract(0:numpft) real(r8) lignineffect(0:numpft) real(r8) structurallignin(0:numpft) real(r8) fact_soilmic(0:numpft) real(r8) fact_slow(0:numpft) real(r8) fact_passive(0:numpft) real(r8) annK(0:numpft,npools) real(r8) kdt(0:numpft,npools) !----------------------------------------------------------------------- private :: CASAPot_Evptr ! potential evapotranspiration computation contains !----------------------------------------------------------------------- !BOP ! ! !IROUTINE: initCASA ! ! !INTERFACE: subroutine initCASA() 1,45 ! ! !DESCRIPTION: ! Initialize the CASA submodel. ! ! !USES: use fileutils , only : getfil use ncdio , only : check_ret,check_dim,ncd_iolocal,ncd_close use shr_const_mod, only : SHR_CONST_CDAY use decompMod , only : get_proc_bounds, get_proc_global use clm_varctl , only : nsrest use clm_varpar , only : lsmlon, lsmlat, max_pft_per_gcell use spmdMod , only : masterproc use clm_time_manager , only : get_step_size use pftvarcon , only : noveg, nc3_nonarctic_grass ! ! !ARGUMENTS: implicit none include "netcdf.inc" ! ! !LOCAL VARIABLES: real(r8), parameter :: plai_min_ic = 0.8_r8 ! init plai => Dickinson value real(r8), parameter :: secpy = 365._r8*SHR_CONST_CDAY ! no of secs/yr ! local variables character(len=256) locfn ! local file name integer :: ncid ! netCDF file id integer :: varid ! netCDF variable id logical :: varpresent ! netCDF variable present flag integer :: begp, endp ! per-proc beginning and ending pft indices integer :: begc, endc ! per-proc beginning and ending column indices integer :: begl, endl ! per-proc beginning and ending landunit indices integer :: begg, endg ! per-proc gridcell ending gridcell indices integer :: numg ! total number of gridcells across all processors integer :: numl ! total number of landunits across all processors integer :: numc ! total number of columns across all processors integer :: nump ! total number of pfts across all processors integer :: g,c,i,j,l,m,n,p,pi integer :: ier, ret ! error return code real(r8) dtime !land model time step (sec) real(r8) lnscl real(r8) hardwire_sla(0:numpft) real(r8), pointer :: sumwts(:) real(r8), pointer :: vege_wts(:) real(r8), pointer :: wood_wts(:) real(r8), pointer :: vege_scale(:) real(r8), pointer :: wood_scale(:) real(r8), pointer :: rloc(:) ! pointers integer , pointer :: pgridcell(:) ! gridcell index of corresponding pft integer , pointer :: pcolumn(:) ! pft's column integer , pointer :: plandunit(:) ! landunit index associated with pft integer , pointer :: npfts(:) ! number of pfts on gridcell integer , pointer :: pfti(:) ! initial pft on gridcell integer , pointer :: ltype(:) ! landunit type for corresponding pft integer , pointer :: ivt(:) ! pft vegetation type real(r8), pointer :: wtgcell(:) ! pft weight relative to gridcell real(r8), pointer :: XSCpool(:) real(r8), pointer :: eff(:,:) real(r8), pointer :: frac_donor(:,:) real(r8), pointer :: Tpool_C(:,:) ! Total C pool size real(r8), pointer :: plai(:) ! prognostic LAI (m2 leaf/m2 ground) real(r8), pointer :: sandfrac(:) real(r8), pointer :: clayfrac(:) real(r8), pointer :: co2flux(:) ! net CO2 flux (gC/m2/s) [+ = to atm] real(r8), pointer :: fnpp(:) ! NPP (gC/m2/sec) real(r8), pointer :: Resp_C(:,:) ! could dimension by ndead, but caution!!! real(r8), pointer :: Cflux(:) real(r8), pointer :: watopt(:) !optimal soil water content for et for top 30cm (mm3/mm3) real(r8), pointer :: watdry(:) !soil water when et stops for top 30cm (mm3/mm3) real(r8), pointer :: sz(:) !thickness of soil layers contributing to output real(r8), pointer :: watoptc(:) !optimal soil water content for et for entire column (mm3/mm3) real(r8), pointer :: watdryc(:) !soil water when et stops for entire column (mm3/mm3) real(r8), pointer :: szc(:) !thickness of soil layers contributing to output real(r8), pointer :: watsat(:,:) !saturated volumetric soil water content (porosity) real(r8), pointer :: sucsat(:,:) ! minimum soil suction (mm) real(r8), pointer :: bsw(:,:) !Clapp and Hornberger "b" (nlevsoi) real(r8), pointer :: z(:,:) ! soil layer depth (m) real(r8), pointer :: dz(:,:) ! soil layer thickness (m) character(len=32) :: subname='initCasa' ! subroutine name ! ! !CALLED FROM: ! initialize in initializeMod ! ! !REVISION HISTORY: ! 2004.06.08 Vectorized and reformatted by Forrest Hoffman ! !EOP !----------------------------------------------------------------------- pgridcell => clm3%g%l%c%p%gridcell pcolumn => clm3%g%l%c%p%column plandunit => clm3%g%l%c%p%landunit npfts => clm3%g%npfts pfti => clm3%g%pfti ltype => clm3%g%l%itype ivt => clm3%g%l%c%p%itype wtgcell => clm3%g%l%c%p%wtgcell eff => clm3%g%l%c%p%pps%eff frac_donor => clm3%g%l%c%p%pps%frac_donor XSCpool => clm3%g%l%c%p%pps%XSCpool Tpool_C => clm3%g%l%c%p%pps%Tpool_C plai => clm3%g%l%c%p%pps%plai sandfrac => clm3%g%l%c%p%pps%sandfrac clayfrac => clm3%g%l%c%p%pps%clayfrac co2flux => clm3%g%l%c%p%pps%co2flux fnpp => clm3%g%l%c%p%pps%fnpp Resp_C => clm3%g%l%c%p%pps%Resp_C Cflux => clm3%g%l%c%p%pps%Cflux watdry => clm3%g%l%c%p%pps%watdry watopt => clm3%g%l%c%p%pps%watopt sz => clm3%g%l%c%p%pps%sz watdryc => clm3%g%l%c%p%pps%watdryc watoptc => clm3%g%l%c%p%pps%watoptc szc => clm3%g%l%c%p%pps%szc watsat => clm3%g%l%c%cps%watsat sucsat => clm3%g%l%c%cps%sucsat bsw => clm3%g%l%c%cps%bsw z => clm3%g%l%c%cps%z dz => clm3%g%l%c%cps%dz call get_proc_bounds(begg, endg, begl, endl, begc, endc, begp, endp) call get_proc_global(numg, numl, numc, nump) !iyf ========= set up decay constants =============================== ! EXPONENTIAL RATE CONSTANTS (per year) - convert to per second ! these are veg dependent (for live pools only), but not time dependent ! we have chosen to put inside time loop for clarity !iyf turnover times of live pools. Want annK in sec-1. !iyf 02/07/11 ! stressCD to be added to "annK(m,LEAF)" and "annK(m,FROOT)" ! in casa_litterfall.F do m = 0, numpft if(lrage(m) > 0.0_r8)then annK(m,LEAF) = 1.0_r8/(lrage(m)*secpy) annK(m,FROOT) = 1.0_r8/(lrage(m)*secpy) else annK(m,LEAF) = 1.0e-40_r8 annK(m,FROOT) = 1.0e-40_r8 end if if(woodage(m) > 0.0_r8)then annK(m,WOOD) = 1.0_r8/(woodage(m)*secpy) else annK(m,WOOD) = 1.0e-40_r8 end if ! mod 03/07/16 multiply dead pool turnover times by 4 to account ! for effective turnover time (bgtemp*bgmoist) in casa_bgfluxes.F ! mod 03/08/19 multiply passive pool annK by 1/10 ! want turnover time of passive pool to be 1000 years ! mod 03/11/21 remove factor of 4 from annK (as of lbgc.17f) !iyf: 1/(turnover times) for dead pools. Want annK in sec-1. annK(m,SURFMET) = 14.8_r8 /secpy annK(m,SURFMIC) = 6.0_r8 /secpy annK(m,SURFSTR) = 3.9_r8 /secpy annK(m,SOILMET) = 18.5_r8 /secpy annK(m,SOILMIC) = 7.3_r8 /secpy annK(m,SOILSTR) = 4.9_r8 /secpy ! 4.8 in casa v3.0 annK(m,CWD) = 0.2424_r8/secpy annK(m,SLOW) = 0.2_r8 /secpy !orig annK(m,PASSIVE) = 0.0045/secpy !.. 03/04/03 change turnover time of passive pool to 50 years annK(m,PASSIVE) = 0.1_r8 * 0.02_r8 /secpy end do ! Maximum RATE CONSTANTS FOR EACH POOL SCALED TO LENGTH OF TIME STEP ! For small delta_t, kdt is the same as annK*delta_t !iyf: Consider dM/dt = - M/tau !iyf: Analytic solution: M(t) = M0 exp (-t/tau) !iyf: Integrate Flux*dt from t=(n-1)*dt to t=n*dt: !iyf: integral = M(n*dt) - M[(n-1)*dt] !iyf: = - M[(n-1)*dt] {1 - exp [-dt/tau]} !iyf: approx = M[(n-1)*dt] * [dt/tau] !iyf: variable kdt was previously Krate in CASA ! NOTE: kdt will be used for WOOD and dead pools only ! so no need to worry about adding stressCD to annK here dtime = get_step_size() do n = 1, npools do m = 1, numpft kdt(m,n)= 1.0_r8 - (exp(-annK(m,n)*dtime)) end do kdt(0,n)= 0.0_r8 end do do m = 0, numpft ! LIGNIN TO NITROGEN SCALAR lnscl = litcn(m) * lignin(m) * 2.22_r8 ! DETERMINE FRACTION OF LITTER THAT WILL BE METABOLIC FROM lignin:N RATIO solubfract(m) = 0.85_r8 - (0.018_r8 * lnscl) if(solubfract(m) < 0.0_r8)solubfract(m)=0.0_r8 ! DETERMINE FRACTION OF C IN STRUCTURAL LITTER POOLS FROM LIGNIN ! For leaf and root structurallignin(m) = (lignin(m) * 0.65_r8 * 2.22_r8) & / (1._r8 - solubfract(m)) ! DETERMINE EFFECT OF LIGNIN CONTENT ON DECOMPOSITION RATES lignineffect(m) = exp(-3.0_r8 * structurallignin(m)) end do ! 01/10/01 see Jim Randerson's version of CASA ! assign fact_soilmic, fact_slow, fact_passive for cultivation ! used in casa_bgfluxes.F do m = 0, numpft fact_soilmic(m) = 0.0_r8 fact_slow(m) = 0.0_r8 fact_passive(m) = 0.0_r8 if(m == 15 .or. m == 16)then ! crops (corn, wheat in CLM) fact_soilmic(m) = 1.25_r8 fact_slow(m) = 1.50_r8 fact_passive(m) = 1.50_r8 else fact_soilmic(m) = 1.00_r8 fact_slow(m) = 1.00_r8 fact_passive(m) = 1.00_r8 end if end do ! sla values below are hardwired in biogeochem/VOCEmissionMod.F90 hardwire_sla( 0) = 0._r8 hardwire_sla( 1) = 0.0125_r8 !needleleaf hardwire_sla( 2) = 0.0125_r8 !Gordon Bonan suggests NET = 0.0076 hardwire_sla( 3) = 0.0125_r8 !Gordon Bonan suggests NDT = 0.0200 hardwire_sla( 4) = 0.0250_r8 !broadleaf hardwire_sla( 5) = 0.0250_r8 !Gordon Bonan suggests BET = 0.0178 hardwire_sla( 6) = 0.0250_r8 !Gordon Bonan suggests BDT = 0.0274 hardwire_sla( 7) = 0.0250_r8 hardwire_sla( 8) = 0.0250_r8 hardwire_sla( 9) = 0.0250_r8 hardwire_sla(10) = 0.0250_r8 hardwire_sla(11) = 0.0250_r8 hardwire_sla(12) = 0.0200_r8 !grass hardwire_sla(13) = 0.0200_r8 hardwire_sla(14) = 0.0200_r8 hardwire_sla(15) = 0.0200_r8 hardwire_sla(16) = 0.0200_r8 !numpft = 16 do m = 0, numpft sla(m) = hardwire_sla(m) * 1000.0_r8 ! m2/kg C ! 02/07/22 assign min leafmass, max leafmass ! used in casa_bgfluxes.F if (sla(m) /= 0.0_r8) then leafmin(m) = (plai_min(m)/sla(m))*1.e3_r8 ! g C/m2 ground leafmax(m) = (plai_max(m)/sla(m))*1.e3_r8 ! g C/m2 ground else leafmin(m) = 0.0_r8 leafmax(m) = 0.0_r8 end if end do do p = begp,endp l = plandunit(p) plai(p) = 0.0_r8 if (ltype(l) == istsoil) then plai(p) = plai_min_ic ! CHECK !!! ! soil textures should be checked for soil depth ! These are now set in iniTimeConst !sandfrac(p) = sand3d(ixy(pgridcell(p)),jxy(pgridcell(p)),1)/100.0 !clayfrac = clay3d(ixy(pgridcell(p)),jxy(pgridcell(p)),1)/100.0 eff(p, 1) = 0.45_r8 ! SLOW,PASSIVE eff(p, 2) = 0.45_r8 ! SLOW,SOILMIC eff(p, 3) = 0.40_r8 ! SURFMET,SURFMIC eff(p, 4) = 0.40_r8 ! SURFSTR,SURFMIC eff(p, 5) = 0.70_r8 ! SURFSTR,SLOW eff(p, 6) = 0.45_r8 ! SOILMET,SOILMIC eff(p, 7) = 0.45_r8 ! SOILSTR,SOILMIC eff(p, 8) = 0.70_r8 ! SOILSTR,SLOW eff(p, 9) = 0.40_r8 ! CWD,SURFMIC eff(p,10) = 0.70_r8 ! CWD,SLOW eff(p,11) = 0.40_r8 ! SURFMIC,SLOW eff(p,12) = 0.85_r8 - (0.68_r8 * (1.0_r8 - sandfrac(p))) ! SOILMIC,PASSIVE eff(p,13) = 0.85_r8 - (0.68_r8 * (1.0_r8 - sandfrac(p))) ! SOILMIC,SLOW eff(p,14) = 0.45_r8 ! PASSIVE,SOILMIC ! EXTRA RESPIRATION TRANSFER EFFICIENCIES frac_donor(p, 1) = 0.003_r8 + (0.009_r8*clayfrac(p)) frac_donor(p, 2) = 1.0_r8 - frac_donor(p,1) frac_donor(p, 3) = 1.0_r8 frac_donor(p, 4) = 1.0_r8 - structurallignin(ivt(p)) frac_donor(p, 5) = structurallignin(ivt(p)) frac_donor(p, 6) = 1.0_r8 frac_donor(p, 7) = 1.0_r8 - structurallignin(ivt(p)) frac_donor(p, 8) = structurallignin(ivt(p)) frac_donor(p, 9) = 1.0_r8 - woodligninfract frac_donor(p,10) = woodligninfract frac_donor(p,11) = 1.0_r8 frac_donor(p,12) = 0.003_r8 + (0.032_r8*clayfrac(p)) frac_donor(p,13) = 1.0_r8 - frac_donor(p,12) frac_donor(p,14) = 1.0_r8 end if end do ! Initialize Pool Sizes to 0.0 or to spun up data (Tpool_C only) !!! 04/01/15 JJ !!! modify to set Tpool = 0 on initial start (nsrest=0) !!! BUT, if SPUNPUP=1 and nsrest ne 1, then read in initial pool size data !!! ie on initial or branch run, if SPUNUP=1, use initial pool data. if (nsrest == 0 .and. .not. cpool_inic) then if (masterproc) & write(iulog,*)'WARNING: Initializing Tpool_C and XSCpool to 0.0' do n = 1, npools do p = begp, endp Tpool_C(p,n) = 0.0_r8 end do end do do p = begp, endp XSCpool(p) = 0.0_r8 end do end if !!! read spun up Tpool if available (use only for initial or branch runs) !!! don't overwrite restart values if (SPUNUP == 1 .and. nsrest /= 1) then ! Allocate dynamic memory allocate(sumwts(begg:endg), vege_wts(begg:endg), wood_wts(begg:endg), stat=ier) if (ier /= 0) then call endrun('allocation error for sumwts, vege_wts, and wood_wts') end if allocate(vege_scale(begp:endp), wood_scale(begp:endp), stat=ier) if (ier /= 0) then call endrun('allocation error for vege_scale and wood_scale') end if allocate(rloc(begg:endg), stat=ier) if (ier /= 0) then call endrun('allocation error for rloc') end if ! Compute vegetated and woody scale factor to adjust initial carbon ! pools accounting for bare ground patches. This will scale up initial ! values for vegetated PFTs mixed with bare ground and provide a zero ! multiplier for non-vegetated and non-woody patches. sumwts(begg:endg) = 0._r8 vege_wts(begg:endg) = 0._r8 wood_wts(begg:endg) = 0._r8 do pi = 1,max_pft_per_gcell do g = begg, endg if (pi <= npfts(g)) then p = pfti(g) + pi - 1 sumwts(g) = sumwts(g) + wtgcell(p) if (ivt(p) > noveg) vege_wts(g) = vege_wts(g) + wtgcell(p) if (ivt(p) > noveg .and. ivt(p) < nc3_nonarctic_grass ) wood_wts(g) = wood_wts(g) + wtgcell(p) end if end do end do do p = begp,endp g = pgridcell(p) if (ivt(p) > noveg .and. vege_wts(g) > 0._r8) then !vege_scale(p) = sumwts(g) / vege_wts(g) vege_scale(p) = 1._r8 else vege_scale(p) = 0._r8 end if if (ivt(p) > noveg .and. ivt(p) < nc3_nonarctic_grass .and. vege_wts(g) > 0._r8) then !wood_scale(p) = sumwts(g) / wood_wts(g) wood_scale(p) = 1._r8 else wood_scale(p) = 0._r8 end if end do ! Read file if (masterproc) then call getfil(fcpool, locfn, 0) write(iulog,*)'Reading initial carbon pools from ',locfn call check_ret(nf_open(locfn, nf_nowrite, ncid), subname) call check_dim(ncid, 'longitude', lsmlon) call check_dim(ncid, 'latitude', lsmlat) end if ! TPOOL_C_LEAF call ncd_iolocal(ncid,'TPOOL_C_LEAF','read',rloc,nameg,status=ret) if (ret /= 0) call endrun( trim(subname)//' ERROR: TPOOL_C_LEAF NOT on fcpool file' ) do p = begp,endp Tpool_C(p,LEAF) = rloc(pgridcell(p)) * vege_scale(p) end do ! TPOOL_C_WOOD call ncd_iolocal(ncid,'TPOOL_C_WOOD','read',rloc,nameg,status=ret) if (ret /= 0) call endrun( trim(subname)//' ERROR: TPOOL_C_WOOD NOT on fcpool file' ) do p = begp,endp Tpool_C(p,WOOD) = rloc(pgridcell(p)) * wood_scale(p) end do ! TPOOL_C_FROOT call ncd_iolocal(ncid,'TPOOL_C_FROOT','read',rloc,nameg,status=ret) if (ret /= 0) call endrun( trim(subname)//' ERROR: TPOOL_C_FROOT NOT on fcpool file' ) do p = begp,endp Tpool_C(p,FROOT) = rloc(pgridcell(p)) * vege_scale(p) end do ! TPOOL_C_SURFMET call ncd_iolocal(ncid,'TPOOL_C_SURFMET','read',rloc,nameg,status=ret) if (ret /= 0) call endrun( trim(subname)//' ERROR: TPOOL_C_SURFMET NOT on fcpool file' ) do p = begp,endp Tpool_C(p,SURFMET) = rloc(pgridcell(p)) * vege_scale(p) end do ! TPOOL_C_SURFSTR call ncd_iolocal(ncid,'TPOOL_C_SURFSTR','read',rloc,nameg,status=ret) if (ret /= 0) call endrun( trim(subname)//' ERROR: TPOOL_C_SURFSTR NOT on fcpool file' ) do p = begp,endp Tpool_C(p,SURFSTR) = rloc(pgridcell(p)) * vege_scale(p) end do ! TPOOL_C_SOILMET call ncd_iolocal(ncid,'TPOOL_C_SOILMET','read',rloc,nameg,status=ret) if (ret /= 0) call endrun( trim(subname)//' ERROR: TPOOL_C_SOILMET NOT on fcpool file' ) do p = begp, endp Tpool_C(p,SOILMET) = rloc(pgridcell(p)) * vege_scale(p) end do ! TPOOL_C_SOILSTR call ncd_iolocal(ncid,'TPOOL_C_SOILSTR','read',rloc,nameg,status=ret) if (ret /= 0) call endrun( trim(subname)//' ERROR: TPOOL_C_SOILSTR NOT on fcpool file' ) do p = begp,endp Tpool_C(p,SOILSTR) = rloc(pgridcell(p)) * vege_scale(p) end do ! TPOOL_C_CWD call ncd_iolocal(ncid,'TPOOL_C_CWD','read',rloc,nameg,status=ret) if (ret /= 0) call endrun( trim(subname)//' ERROR: TPOOL_C_CWD NOT on fcpool file' ) do p = begp,endp Tpool_C(p,CWD) = rloc(pgridcell(p)) * wood_scale(p) end do ! TPOOL_C_SURFMIC call ncd_iolocal(ncid,'TPOOL_C_SURFMIC','read',rloc,nameg,status=ret) if (ret /= 0) call endrun( trim(subname)//' ERROR: TPOOL_C_SURFMIC NOT on fcpool file' ) do p = begp,endp Tpool_C(p,SURFMIC) = rloc(pgridcell(p)) * vege_scale(p) end do ! TPOOL_C_SOILMIC call ncd_iolocal(ncid,'TPOOL_C_SOILMIC','read',rloc,nameg,status=ret) if (ret /= 0) call endrun( trim(subname)//' ERROR: TPOOL_C_SOILMIC NOT on fcpool file' ) do p = begp, endp Tpool_C(p,SOILMIC) = rloc(pgridcell(p)) * vege_scale(p) end do ! TPOOL_C_SLOW call ncd_iolocal(ncid,'TPOOL_C_SLOW','read',rloc,nameg,status=ret) if (ret /= 0) call endrun( trim(subname)//' ERROR: TPOOL_C_SLOW NOT on fcpool file' ) do p = begp,endp Tpool_C(p,SLOW) = rloc(pgridcell(p)) * vege_scale(p) end do ! TPOOL_C_PASSIVE call ncd_iolocal(ncid,'TPOOL_C_PASSIVE','read',rloc,nameg,status=ret) if (ret /= 0) call endrun( trim(subname)//' ERROR: TPOOL_C_PASSIVE NOT on fcpool file' ) do p = begp,endp Tpool_C(p,PASSIVE) = rloc(pgridcell(p)) * vege_scale(p) end do ! Close netcdf file if (masterproc) call ncd_close(ncid, subname) ! Deallocate dynamic memory deallocate(sumwts, vege_wts, wood_wts) deallocate(vege_scale, wood_scale) deallocate(rloc) call casa_write_cpool() end if ! SPUNUP = 1 ! Initialize all fluxes to 0._r8 co2flux(begp:endp) = 0._r8 fnpp(begp:endp) = 0._r8 Cflux(begp:endp) = 0._r8 Resp_C(begp:endp,1:npools) = 0._r8 ! Initialize watdry, watopt, sz and watdryc, watoptc, szc do p = begp,endp l = plandunit(p) if (ltype(l) == istsoil) then ! top 30cm watdry(p) = 0._r8 watopt(p) = 0._r8 sz(p) = 0._r8 ! entire water column watdryc(p) = 0._r8 watoptc(p) = 0._r8 szc(p) = 0._r8 end if end do ! Compute watdry, watopt, and watdryc, watoptc in mm^3/mm^3 do j = 1, nlevsoi do p = begp,endp c = pcolumn(p) l = plandunit(p) if (ltype(l) == istsoil) then ! top 30cm if (z(c,j)+0.5_r8*dz(c,j) <= z30) then watdry(p) = watdry(p) + watsat(c,j) * ((316230._r8/sucsat(c,j)) ** (-1._r8/bsw(c,j))) * dz(c,j) watopt(p) = watopt(p) + watsat(c,j) * ((158490._r8/sucsat(c,j)) ** (-1._r8/bsw(c,j))) * dz(c,j) sz(p) = sz(p) + dz(c,j) end if ! entire water column watdryc(p) = watdryc(p) + watsat(c,j) * ((316230._r8/sucsat(c,j)) ** (-1._r8/bsw(c,j))) * dz(c,j) watoptc(p) = watoptc(p) + watsat(c,j) * ((158490._r8/sucsat(c,j)) ** (-1._r8/bsw(c,j))) * dz(c,j) szc(p) = szc(p) + dz(c,j) end if end do end do do p = begp,endp l = plandunit(p) if (ltype(l) == istsoil) then ! top 30cm watdry(p) = watdry(p)/sz(p) watopt(p) = watopt(p)/sz(p) ! entire water column watdryc(p) = watdryc(p)/szc(p) watoptc(p) = watoptc(p)/szc(p) end if end do ! get fcap and wp - used in allocation ! wp = permanent wilting point (mm3/mm3) ! fcap = field capacity (mm3/mm3) ! do p = begp, endp ! l = plandunit(p) ! if (ltype(l) == istsoil) then ! sand1 = sand(p) ! already in pct ! clay1 = clay(p) ! already in pct ! sand2 = sand1 * sand1 ! clay2 = clay1 * clay1 ! soilalpha = exp(-4.396 - 0.0715*clay1 ! & - 4.88e-4*sand2 - 4.285e-5*sand2*clay1) ! soilbeta = -3.140 - 0.00222*clay2 ! & - 3.484e-5*sand2*clay1 ! convert to mm3 (x1000) - CHECK units ! if ((soilalpha.ne.0.0).and.(soilbeta.ne.0.0)) then ! fcap(p) = ((0.3333/soilalpha)**(1.0/soilbeta))*1000.0 ! wp(p) = ((15.0/soilalpha)**(1.0/soilbeta))*1000.0 ! end if ! end if ! end do end subroutine initCASA !----------------------------------------------------------------------- !BOP ! ! !IROUTINE: casa_write_cpool ! ! !INTERFACE: subroutine casa_write_cpool() 1,58 ! ! !DESCRIPTION: ! Writes out a CPOOL_INITIAL file containing the mapped carbon pools. It ! may be read later in initCASA() during initialization. This file is not ! saved or shipped to the Mass Storage System since it is really just for ! debugging. Carbon pool states are saved now in initial datasets. ! ! !USES: use decompMod , only : get_proc_bounds, get_proc_global use ncdio , only : check_ret,ncd_defvar,ncd_ioglobal,ncd_iolocal, ncd_create, & ncd_close, ncd_clobber use subgridAveMod, only : p2g use domainMod , only : ldomain, llatlon use clm_varpar , only : lsmlon, lsmlat use spmdMod , only : masterproc ! ! !ARGUMENTS: implicit none include "netcdf.inc" ! ! !LOCAL VARIABLES: integer :: ncid ! netCDF file id integer :: omode ! netCDF mode returned integer :: dimid ! netCDF dimension id integer :: begp, endp ! per-proc beginning and ending pft indices integer :: begc, endc ! per-proc beginning and ending column indices integer :: begl, endl ! per-proc beginning and ending landunit indices integer :: begg, endg ! per-proc gridcell ending gridcell indices integer :: numg ! total number of gridcells across all processors integer :: numl ! total number of landunits across all processors integer :: numc ! total number of columns across all processors integer :: nump ! total number of pfts across all processors integer :: ier ! error flag integer :: n,m,g ! index real(r8), pointer :: histi(:,:) real(r8), pointer :: histo(:,:) real(r8), pointer :: hist1do(:) character(len=32) :: subname='casa_write_cpool' ! subroutine name ! pointers real(r8), pointer :: Tpool_C(:,:) ! Total C pool size ! ! !CALLED FROM: ! initCASA() for debugging. ! ! !REVISION HISTORY: ! 2004.08.17 Created by Forrest Hoffman ! ! !EOP !----------------------------------------------------------------------- Tpool_C => clm3%g%l%c%p%pps%Tpool_C call get_proc_bounds(begg, endg, begl, endl, begc, endc, begp, endp) call get_proc_global(numg, numl, numc, nump) if (masterproc) then call ncd_create('CPOOL_INITIAL.nc',ncd_clobber,ncid,subname) call check_ret(nf_set_fill(ncid, nf_nofill, omode), subname) call check_ret(nf_def_dim(ncid, 'longitude', lsmlon, dimid), subname) call check_ret(nf_def_dim(ncid, 'latitude', lsmlat, dimid), subname) call ncd_defvar(ncid=ncid, varname='longitude', xtype=nf_double, & dim1name='longitude', long_name='coordinate longitude', & units='degrees_east') call ncd_defvar(ncid=ncid, varname='latitude', xtype=nf_double, & dim1name='latitude', long_name='coordinate latitude', & units='degrees_north') call ncd_defvar(ncid=ncid, varname='landfrac', xtype=nf_double, & dim1name='longitude', dim2name='latitude', long_name='land fraction') call ncd_defvar(ncid=ncid, varname='landmask', xtype=nf_int, & dim1name='longitude', dim2name='latitude', & long_name='land/ocean mask (0.=ocean and 1.=land)') call ncd_defvar(ncid=ncid, varname='TPOOL_C_LEAF', & xtype=nf_double, dim1name='longitude', dim2name='latitude', & long_name='total C in leaf pool', & missing_value=spval, fill_value=spval) call ncd_defvar(ncid=ncid, varname='TPOOL_C_WOOD', & xtype=nf_double, dim1name='longitude', dim2name='latitude', & long_name='total C in wood pool', & missing_value=spval, fill_value=spval) call ncd_defvar(ncid=ncid, varname='TPOOL_C_CWD', & xtype=nf_double, dim1name='longitude', dim2name='latitude', & long_name='total C in coarse woody debris pool', & missing_value=spval, fill_value=spval) call ncd_defvar(ncid=ncid, varname='TPOOL_C_FROOT', & xtype=nf_double, dim1name='longitude', dim2name='latitude', & long_name='total C in fine root pool', & missing_value=spval, fill_value=spval) call ncd_defvar(ncid=ncid, varname='TPOOL_C_SURFMET', & xtype=nf_double, dim1name='longitude', dim2name='latitude', & long_name='total C in pool', & missing_value=spval, fill_value=spval) call ncd_defvar(ncid=ncid, varname='TPOOL_C_SURFSTR', & xtype=nf_double, dim1name='longitude', dim2name='latitude', & long_name='total C in pool', & missing_value=spval, fill_value=spval) call ncd_defvar(ncid=ncid, varname='TPOOL_C_SOILMET', & xtype=nf_double, dim1name='longitude', dim2name='latitude', & long_name='total C in pool', & missing_value=spval, fill_value=spval) call ncd_defvar(ncid=ncid, varname='TPOOL_C_SOILSTR', & xtype=nf_double, dim1name='longitude', dim2name='latitude', & long_name='total C in pool', & missing_value=spval, fill_value=spval) call ncd_defvar(ncid=ncid, varname='TPOOL_C_SURFMIC', & xtype=nf_double, dim1name='longitude', dim2name='latitude', & long_name='total C in pool', & missing_value=spval, fill_value=spval) call ncd_defvar(ncid=ncid, varname='TPOOL_C_SOILMIC', & xtype=nf_double, dim1name='longitude', dim2name='latitude', & long_name='total C in pool', & missing_value=spval, fill_value=spval) call ncd_defvar(ncid=ncid, varname='TPOOL_C_SLOW', & xtype=nf_double, dim1name='longitude', dim2name='latitude', & long_name='total C in pool', & missing_value=spval, fill_value=spval) call ncd_defvar(ncid=ncid, varname='TPOOL_C_PASSIVE', & xtype=nf_double, dim1name='longitude', dim2name='latitude', & long_name='total C in pool', & missing_value=spval, fill_value=spval) call check_ret(nf_enddef(ncid), subname) end if if (masterproc) then call ncd_ioglobal(varname='longitude', data=llatlon%lonc, ncid=ncid, flag='write') call ncd_ioglobal(varname='latitude', data=llatlon%latc, ncid=ncid, flag='write') endif call ncd_iolocal(varname='landfrac', data=ldomain%frac, ncid=ncid, & flag='write', dim1name=grlnd) call ncd_iolocal(varname='landmask', data=ldomain%mask, ncid=ncid, & flag='write', dim1name=grlnd) allocate(histi(begp:endp, 1),histo(begg:endg,1),hist1do(begg:endg), stat=ier) if (ier /= 0) then write(iulog,*) 'Allocation error for TPOOL_C write' end if ! TPOOL_C_LEAF histi(begp:endp,1) = Tpool_C(begp:endp,LEAF) histo(begg:endg,1) = spval call p2g(begp, endp, begc, endc, begl, endl, begg, endg, 1, & histi, histo, 'unity', 'unity', 'unity') hist1do(begg:endg) = histo(begg:endg, 1) call ncd_iolocal(flag='write', varname='TPOOL_C_LEAF', dim1name=grlnd, & data=hist1do, ncid=ncid) ! TPOOL_C_WOOD histi(begp:endp,1) = Tpool_C(begp:endp,WOOD) histo(begg:endg,1) = spval call p2g(begp, endp, begc, endc, begl, endl, begg, endg, 1, & histi, histo, 'unity', 'unity', 'unity') hist1do(begg:endg) = histo(begg:endg, 1) call ncd_iolocal(flag='write', varname='TPOOL_C_WOOD', dim1name=grlnd, & data=hist1do, ncid=ncid) ! TPOOL_C_CWD histi(begp:endp,1) = Tpool_C(begp:endp,CWD) histo(begg:endg,1) = spval call p2g(begp, endp, begc, endc, begl, endl, begg, endg, 1, & histi, histo, 'unity', 'unity', 'unity') hist1do(begg:endg) = histo(begg:endg, 1) call ncd_iolocal(flag='write', varname='TPOOL_C_CWD', dim1name=grlnd, & data=hist1do, ncid=ncid) ! TPOOL_C_FROOT histi(begp:endp,1) = Tpool_C(begp:endp,FROOT) histo(begg:endg,1) = spval call p2g(begp, endp, begc, endc, begl, endl, begg, endg, 1, & histi, histo, 'unity', 'unity', 'unity') hist1do(begg:endg) = histo(begg:endg, 1) call ncd_iolocal(flag='write', varname='TPOOL_C_FROOT', dim1name=grlnd, & data=hist1do, ncid=ncid) ! TPOOL_C_SURFMET histi(begp:endp,1) = Tpool_C(begp:endp,SURFMET) histo(begg:endg,1) = spval call p2g(begp, endp, begc, endc, begl, endl, begg, endg, 1, & histi, histo, 'unity', 'unity', 'unity') hist1do(begg:endg) = histo(begg:endg, 1) call ncd_iolocal(flag='write', varname='TPOOL_C_SURFMET', dim1name=grlnd, & data=hist1do, ncid=ncid) ! TPOOL_C_SURFSTR histi(begp:endp,1) = Tpool_C(begp:endp,SURFSTR) histo(begg:endg,1) = spval call p2g(begp, endp, begc, endc, begl, endl, begg, endg, 1, & histi, histo, 'unity', 'unity', 'unity') hist1do(begg:endg) = histo(begg:endg, 1) call ncd_iolocal(flag='write', varname='TPOOL_C_SURFSTR', dim1name=grlnd, & data=hist1do, ncid=ncid) ! TPOOL_C_SOILMET histi(begp:endp,1) = Tpool_C(begp:endp,SOILMET) histo(begg:endg,1) = spval call p2g(begp, endp, begc, endc, begl, endl, begg, endg, 1, & histi, histo, 'unity', 'unity', 'unity') hist1do(begg:endg) = histo(begg:endg, 1) call ncd_iolocal(flag='write', varname='TPOOL_C_SOILMET', dim1name=grlnd, & data=hist1do, ncid=ncid) ! TPOOL_C_SOILSTR histi(begp:endp,1) = Tpool_C(begp:endp,SOILSTR) histo(begg:endg,1) = spval call p2g(begp, endp, begc, endc, begl, endl, begg, endg, 1, & histi, histo, 'unity', 'unity', 'unity') hist1do(begg:endg) = histo(begg:endg, 1) call ncd_iolocal(flag='write', varname='TPOOL_C_SOILSTR', dim1name=grlnd, & data=hist1do, ncid=ncid) ! TPOOL_C_SURFMIC histi(begp:endp,1) = Tpool_C(begp:endp,SURFMIC) histo(begg:endg,1) = spval call p2g(begp, endp, begc, endc, begl, endl, begg, endg, 1, & histi, histo, 'unity', 'unity', 'unity') hist1do(begg:endg) = histo(begg:endg, 1) call ncd_iolocal(flag='write', varname='TPOOL_C_SURFMIC', dim1name=grlnd, & data=hist1do, ncid=ncid) ! TPOOL_C_SOILMIC histi(begp:endp,1) = Tpool_C(begp:endp,SOILMIC) histo(begg:endg,1) = spval call p2g(begp, endp, begc, endc, begl, endl, begg, endg, 1, & histi, histo, 'unity', 'unity', 'unity') hist1do(begg:endg) = histo(begg:endg, 1) call ncd_iolocal(flag='write', varname='TPOOL_C_SOILMIC', dim1name=grlnd, & data=hist1do, ncid=ncid) ! TPOOL_C_SLOW histi(begp:endp,1) = Tpool_C(begp:endp,SLOW) histo(begg:endg,1) = spval call p2g(begp, endp, begc, endc, begl, endl, begg, endg, 1, & histi, histo, 'unity', 'unity', 'unity') hist1do(begg:endg) = histo(begg:endg, 1) call ncd_iolocal(flag='write', varname='TPOOL_C_SLOW', dim1name=grlnd, & data=hist1do, ncid=ncid) ! TPOOL_C_PASSIVE histi(begp:endp,1) = Tpool_C(begp:endp,PASSIVE) histo(begg:endg,1) = spval call p2g(begp, endp, begc, endc, begl, endl, begg, endg, 1, & histi, histo, 'unity', 'unity', 'unity') hist1do(begg:endg) = histo(begg:endg, 1) call ncd_iolocal(flag='write', varname='TPOOL_C_PASSIVE', dim1name=grlnd, & data=hist1do, ncid=ncid) deallocate(hist1do) deallocate(histo) deallocate(histi) if (masterproc) call check_ret(nf_close(ncid), subname) end subroutine casa_write_cpool !=============================================================================== !BOP ! ! !IROUTINE: casa_ecosystemDyn ! ! !INTERFACE: subroutine casa_ecosystemDyn(begc,endc, begp,endp, num_soilc,filter_soilc, & 2,6 num_soilp,filter_soilp, doalb, init) ! ! !DESCRIPTION: ! Primary calling interface to the CASA submodel. ! ! !CALLED FROM: ! clm_driver1 and initSurfAlb ! ! !REVISION HISTORY: ! 2004.06.08 F. Hoffman: Vectorized and reformatted ! 2008.11.12 B. Kauffman: include phenology, vegStruct, rename "ecosystemDyn" ! ! !ARGUMENTS: implicit none integer, intent(in) :: begc, endc ! column bounds integer, intent(in) :: begp, endp ! pft bounds integer, intent(in) :: num_soilc ! number of soil points in column filter integer, intent(in) :: filter_soilc(:) ! column filter for soil points integer, intent(in) :: num_soilp ! number of soil points in pft filter integer, intent(in) :: filter_soilp(:) ! pft filter for soil points logical, intent(in), optional :: doalb ! T => run phase call and albedo timestep logical, intent(in), optional :: init ! T => init phase call: for albedo init ! !EOP !--- local variables --- integer :: f, p ! indicies logical :: linit ! local init logical :: ldoalb ! local doalb ! implicit intent inout !============================================================ real(r8), pointer :: plai(:) ! prognostic LAI (m2 leaf/m2 ground) character(*),parameter :: subname='(casa_ecosystemDyn) ' !------------------------------------------------------------------------------- ! !------------------------------------------------------------------------------- linit = .false. if (present(init)) lInit = init ldoalb = .false. if (present(doalb)) ldoalb = doalb ! phenology call CASAPhenology(begp, endp, num_soilp, filter_soilp) if ( linit) then if (masterproc) write(iulog,*) subName,"initialize option is ON" ! explicitly set prognostic LAI to zero when called from initSurfAlb plai => clm3%g%l%c%p%pps%plai do f = 1,num_soilp p = filter_soilp(f) plai(p) = 0.0_r8 end do else !--- potential evapo-transpiration --- call CASAPot_Evptr(begp, endp, num_soilp, filter_soilp) !--- carbon allocation --- call casa_allocate(begp, endp, num_soilp, filter_soilp) !--- plant net primary production --- call casa_npp(begp,endp, num_soilp,filter_soilp) ! bgfluxes (litterfall, soil respiration) ! Compute Carbon flux to send to atm ! fnpp (gC/m2/sec), Cflux (gC/m2/sec), co2flux (gC/m2/sec) call casa_bgfluxes(begp, endp, num_soilp, filter_soilp) #if (defined CLAMP) call CASASummary(begp, endp, num_soilp, filter_soilp ) #endif end if end subroutine casa_ecosystemDyn !=============================================================================== !BOP ! ! !IROUTINE: CASAPot_Evptr ! ! !INTERFACE: subroutine CASAPot_Evptr(lbp, ubp, num_soilp, filter_soilp) 1 ! ! !DESCRIPTION: ! Potential Evapotranspiration ! Priestely-Taylor Equation ! Baldocchi et al. (2000): Climate and vegetation controls on boreal ! zone energy exchange. Global Change Biology, 6, (Suppl. 1), 69-83. ! ! In Baldocchi et al, PET (equilibrium evaporation) is calculated ! for time step - as he compares the instantaneous evapotranspiration ! to the eqm evapotranspiration. ! I think that this is simplest, and avoids the definition of ! an averaging period. iyf 2002/05/09 ! ! The following calculation is done at every land point. ! No explicit discrimination among veg type or soil type ! Local ecology is implictly dealt with in the energy fluxes. ! !************************************************************************* ! the model partitions the latent heat flux into three components: ! o fcev: evaporation of intercepted water ! o fctr: transpiration ! o fgev: soil evaporation or snow sublimation ! ! the model conserves surface energy fluxes as: ! o -fsa + fira + fsh + (fcev+fctr+fgev) + fcst + fgr + fsm = 0 ! o fsa + fsr = [solad(1)+solad(2)+solai(1)+solai(2)] ! = total incident solar ! o fira = -firgcm + fire ! currently canopy heat storage fcst = 0 ! ! ------------------------ code history --------------------------- ! pot_evptr.F - From Inez ! modified for LSM/CASA interface by J.John (2002) ! ----------------------------------------------------------------- ! ! !ARGUMENTS: implicit none integer, intent(in) :: lbp, ubp ! pft bounds integer, intent(in) :: num_soilp ! number of soil points in pft filter integer, intent(in) :: filter_soilp(ubp-lbp+1) ! pft filter for soil points ! ! !LOCAL VARIABLES: integer :: f ! filter index integer :: g ! gridcell index integer :: p ! pft index real(r8) :: qstar_net, q_grd, flh real(r8) :: tdegC, tadd, e_s, s, gamma, Q_E, factor, a_psy real(r8) :: fcst !canopy heat storage (w/m**2) ! inputs: integer , pointer :: pgridcell(:) ! gridcell index of corresponding pft real(r8), pointer :: t_ref2m(:) !2m surface air temperature (K) real(r8), pointer :: forc_pbot(:) !atmospheric pressure (Pa) real(r8), pointer :: fsa(:) !absorbed solar radiation (w/m**2) real(r8), pointer :: eflx_lwrad_net(:) !net infrared (longwave) rad (w/m**2) [+ = to atm] real(r8), pointer :: eflx_sh_tot(:) !sensible heat flux (w/m**2) [+ to atm] real(r8), pointer :: eflx_lh_vege(:) !veg evaporation heat flux (w/m**2) [+ to atm] real(r8), pointer :: eflx_lh_grnd(:) !ground evaporation heat flux (w/m**2) [+ to atm] real(r8), pointer :: eflx_lh_vegt(:) !veg transpiration heat flux (w/m**2) [+ to atm] ! outputs: real(r8), pointer :: pet(:) !potential evaporation (mm h2o/s) ! ! !CALLED FROM: ! Casa in CASAMod ! ! !REVISION HISTORY: ! 2004.06.08 Vectorized and reformatted by Forrest Hoffman ! !EOP !----------------------------------------------------------------------- ! implicit intent in !============================================================ pgridcell => clm3%g%l%c%p%gridcell t_ref2m => clm3%g%l%c%p%pes%t_ref2m eflx_lwrad_net => clm3%g%l%c%p%pef%eflx_lwrad_net eflx_sh_tot => clm3%g%l%c%p%pef%eflx_sh_tot eflx_lh_vege => clm3%g%l%c%p%pef%eflx_lh_vege eflx_lh_vegt => clm3%g%l%c%p%pef%eflx_lh_vegt eflx_lh_grnd => clm3%g%l%c%p%pef%eflx_lh_grnd fsa => clm3%g%l%c%p%pef%fsa forc_pbot => clm_a2l%forc_pbot ! implicit intent inout !============================================================ pet => clm3%g%l%c%p%pps%pet ! ---------------------------------------------------------------------- ! reminder: watt = joule/sec ! latent heat of vaporization = 2.5e6 ! J/kg ! density h2o = 1.e3 ! kg/m3 factor = hvap * denh2o * 1.e-3_r8 ! to convert to mm ! gamma: phychromatic constant ! a_psy = 0.000662 for ventilated, u~5 m/s ! a_psy = 0.000800 for naturally ventilated, u~1 m/s a_psy = 0.000662_r8 ! unit is s-1 do f = 1,num_soilp p = filter_soilp(f) g = pgridcell(p) ! set fcst to zero fcst = 0.0_r8 ! net radiation abs by canopy = SW_net - LW_net ! CHECK SIGN CONVENTION qstar_net = fsa(p) - eflx_lwrad_net(p) ! soil conductive heat flux (W/m2) ! CHECK SIGN CONVENTION flh = eflx_lh_grnd(p)+eflx_lh_vege(p)+eflx_lh_vegt(p) ! latent heat q_grd = qstar_net - eflx_sh_tot(p) - flh ! compare to fgr !....................................................................... tdegC = t_ref2m(p) - tfrz ! Kelvin to deg C tadd = tdegC + 237.3_r8 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! e_s(T) is Clausius Clapeyron relationship ! = 0.6108 exp[ (17.27 T )/ (T+237.3) ] (T is in deg C) ! !**** cross-check: T=0C, e_s=6.11mb !**** T=20C, e_s~20 mb !**** see also Andrews page 37, Holton page 484 etc. ! unit of e_s is kPa ! ! at T= 0C, e_s(T) = 0.6108 kPa = 6.108 mb ! at T=20C, e_s(T) = 2.338 kPa = 23.38 mb ! ! s is slope of Clausius Clapeyron relationship = d/dT (e_s(T)) ! unit is kPa/deg C ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! e_s = 0.6108_r8 * exp(17.27_r8*tdegC/tadd) ! kPa s = 4098._r8 * e_s / (tadd*tadd) ! kPa/deg C ! ! gamma: phychromatic constant ! a_psy = 0.000662 for ventilated, u~5 m/s ! a_psy = 0.000800 for naturally ventilated, u~1 m/s gamma = a_psy * (forc_pbot(g)*1.e-3_r8) ! surface pressure converted to kPa ! ! latent heat of evaporation (in same units W/m2 as energy fluxes) ! According to Baldocchi reference, (s/s+gamma) is a strong function of ! temperature. = 0.32 at -5C and =0.47 at +5C. ! Q_E = (s/(s+gamma))*(qstar_net - q_grd - fcst) ! Potential evapotranspiration ! Pierre Friedlingstein's allocation code expects PET in (mm h20/s) ! Check units ! Q_E is in W/m2 = J/s * 1/m2 ! factor has units of 1.e-3 * J/m3 pet(p) = Q_E/factor ! mm/sec end do end subroutine CASAPot_Evptr !----------------------------------------------------------------------- !BOP ! ! !IROUTINE: casa_npp ! ! !INTERFACE: subroutine casa_npp(lbp, ubp, num_soilp, filter_soilp) 1 ! ! !DESCRIPTION: ! Compute NPP from GPP. ! ------------------------ code history --------------------------- ! casa_npp.f - get NPP from GPP ! modified for LSM/CASA interface by J.John (2001) ! ----------------------------------------------------------------- ! ! !ARGUMENTS: implicit none integer, intent(in) :: lbp, ubp ! pft bounds integer, intent(in) :: num_soilp ! number of soil points in pft filter integer, intent(in) :: filter_soilp(ubp-lbp+1) ! pft filter for soil points ! ! !LOCAL VARIABLES: integer :: p ! pft index integer :: f ! filter index ! pointers real(r8), pointer :: fpsn(:) real(r8), pointer :: lgrow(:) ! growing season index (0 or 1) real(r8), pointer :: fnpp(:) ! NPP (g/m2/sec) ! ! !CALLED FROM: ! Casa in CASAMod ! ! !REVISION HISTORY: ! 2004.06.08 Vectorized and reformatted by Forrest Hoffman ! !EOP !----------------------------------------------------------------------- ! implicit intent in !============================================================ fpsn => clm3%g%l%c%p%pcf%fpsn lgrow => clm3%g%l%c%p%pps%lgrow ! implicit intent out !============================================================ fnpp => clm3%g%l%c%p%pps%fnpp do f = 1,num_soilp p = filter_soilp(f) !.. LSM overestimates FPSN: use scaled GPP to get npp !.. LNPP = 1 - no lgrow fnpp(p) = gppfact * fpsn(p) * 12.0_r8 * 1.e-6_r8 ! umolC/m2/sec to gC/m2/sec !.. LNPP = 2 - use lgrow and scaled GPP to get npp if (LNPP == 2) then if (lgrow(p) /= 1.0_r8) then fnpp(p) = 0.0_r8 end if end if end do end subroutine casa_npp !----------------------------------------------------------------------- !BOP ! ! !IROUTINE: casa_allocate ! ! !INTERFACE: subroutine casa_allocate(lbp, ubp, num_soilp, filter_soilp) 1 ! ! !DESCRIPTION: ! Provides dynamic or fixed carbon allocation. ! ------------------------ code history --------------------------- ! allocate.f - Allocation Sub-model ! modified from allocate.c - Allocation Sub-model ! ! Version 2.1 ! ! Designed by: Pierre Freidlingstein ! Implemented: 12-12-97 Greg Asner ! Modified: 9-14-98 Greg Asner ! Modified: 08-31-00 Jeff Hicke ! modified for LSM/CASA interface by J.John (2001) ! ! ----------------------------------------------------------------- ! ! ------------------------ notes ---------------------------------- ! ! This code allows for either fixed or dynamic allocation using a flag ! Need to check units for all variables (CASA vs LSM) ! ! code only executed for soils (ist = 1) ! ! ----------------------------------------------------------------- ! ! !ARGUMENTS: implicit none integer, intent(in) :: lbp, ubp ! pft bounds integer, intent(in) :: num_soilp ! number of soil points in pft filter integer, intent(in) :: filter_soilp(ubp-lbp+1) ! pft filter for soil points ! ! !LOCAL VARIABLES: integer f,c,g,j,l,p real(r8) livesum real(r8) leaf_fract real(r8) wood_fract real(r8) root_fract real(r8) tfact real(r8) pfact real(r8) Llim real(r8) Nutrient real(r8) WorN real(r8), parameter :: fixed_leaf = 0.33333333_r8 real(r8), parameter :: fixed_stem = 0.33333333_r8 real(r8), parameter :: fixed_root = 0.33333333_r8 real(r8), parameter :: S0 = 0.30_r8 real(r8), parameter :: R0 = 0.30_r8 real(r8), parameter :: Llim_min = 0.1_r8 ! Light limitation min value real(r8), parameter :: Llim_max = 1.0_r8 ! Light limitation max value real(r8), parameter :: Nut_min = 0.1_r8 ! Nutrient limitation min value real(r8), parameter :: Nut_max = 1.0_r8 ! Nutrient limitation max value real(r8), parameter :: pfact_min = 0.5_r8 ! min value of precip real(r8), parameter :: pfact_mid = 1.0_r8 ! mid value of precip real(r8), parameter :: pfact_max = 2.0_r8 ! max value of precip real(r8), parameter :: tfact_min = 0.5_r8 ! min value of temperature real(r8), parameter :: tfact_max = 1.0_r8 ! max value of temperature real(r8), parameter :: Wlim_min = 0.1_r8 ! Water limitation min value real(r8), parameter :: Wlim_max = 1.0_r8 ! Water limitation max value ! ------------------------ input/output variables ----------------- ! input integer , pointer :: pgridcell(:) !gridcell index of corresponding pft integer , pointer :: pcolumn(:) !pft's column integer , pointer :: ivt(:) !pft vegetation type real(r8), pointer :: btran(:) ! transpiration factor (0 to 1) real(r8), pointer :: tlai(:) ! leaf area index, one-sided, unadjust for burying by snow real(r8), pointer :: forc_rain(:) ! convective precipitation (mm h2o /s) real(r8), pointer :: forc_snow(:) ! large-scale precipitation (mm h2o /s) real(r8), pointer :: z(:,:) ! soil layer depth (m) real(r8), pointer :: dz(:,:) ! soil layer thickness (m) real(r8), pointer :: sz(:) !thickness of soil layers contributing to output real(r8), pointer :: szc(:) !thickness of soil layers contributing to output real(r8), pointer :: t_soisno(:,:) ! soil temperature (K) real(r8), pointer :: h2osoi_liq(:,:) ! liquid water (kg/m2) real(r8), pointer :: livefr(:,:) !live fraction real(r8), pointer :: soilt(:) !soil temp for top 30cm real(r8), pointer :: smoist(:) !soil moisture for top 30cm real(r8), pointer :: soiltc(:) !soil temp for entire column real(r8), pointer :: smoistc(:) !soil moisture for entire column real(r8), pointer :: watoptc(:) !optimal soil water content for et for entire column (mm3/mm3) real(r8), pointer :: watdryc(:) !soil water when et stops for entire column (mm3/mm3) real(r8), pointer :: Wlim(:) ! ! !CALLED FROM: ! Casa in CASAMod ! ! !REVISION HISTORY: ! 2004.06.08 Vectorized and reformatted by Forrest Hoffman ! !EOP !----------------------------------------------------------------------- ! implicit intent in !============================================================ pgridcell => clm3%g%l%c%p%gridcell pcolumn => clm3%g%l%c%p%column ivt => clm3%g%l%c%p%itype dz => clm3%g%l%c%cps%dz z => clm3%g%l%c%cps%z sz => clm3%g%l%c%p%pps%sz szc => clm3%g%l%c%p%pps%szc h2osoi_liq => clm3%g%l%c%cws%h2osoi_liq t_soisno => clm3%g%l%c%ces%t_soisno forc_rain => clm_a2l%forc_rain forc_snow => clm_a2l%forc_snow btran => clm3%g%l%c%p%pps%btran tlai => clm3%g%l%c%p%pps%tlai livefr => clm3%g%l%c%p%pps%livefr soilt => clm3%g%l%c%p%pps%soilt smoist => clm3%g%l%c%p%pps%smoist soiltc => clm3%g%l%c%p%pps%soiltc smoistc => clm3%g%l%c%p%pps%smoistc watoptc => clm3%g%l%c%p%pps%watoptc watdryc => clm3%g%l%c%p%pps%watdryc Wlim => clm3%g%l%c%p%pps%Wlim !============================================================ ! Get avg soil moisture, avg soil temperature over all layers ! only for soils (ist = 1) do f = 1,num_soilp p = filter_soilp(f) soilt(p) = 0._r8 smoist(p) = 0._r8 soiltc(p) = 0._r8 smoistc(p) = 0._r8 end do !! convert soil temperature to deg C do j = 1, nlevgrnd do f = 1,num_soilp p = filter_soilp(f) c = pcolumn(p) !! top 30 cm if (z(c,j)+0.5_r8*dz(c,j) <= z30) then soilt(p) = soilt(p) + (t_soisno(c,j)-tfrz)*dz(c,j) end if !! entire column soiltc(p) = soiltc(p) + (t_soisno(c,j)-tfrz)*dz(c,j) end do end do !! convert liquid water to m3/m3 (need mm3/mm3 to match watsat, watdry, watopt) !! h2osoi_liq /(denh2o*dz) gives m3/m3 do j = 1, nlevsoi do f = 1,num_soilp p = filter_soilp(f) c = pcolumn(p) !! top 30 cm if (z(c,j)+0.5_r8*dz(c,j) <= z30) then smoistc(p) = smoistc(p) + h2osoi_liq(c,j)/denh2o ! dz cancels end if !! entire column smoistc(p) = smoistc(p) + h2osoi_liq(c,j)/denh2o ! dz cancels end do end do do f = 1,num_soilp p = filter_soilp(f) soilt(p) = soilt(p)/sz(p) smoist(p) = smoist(p)/sz(p) soiltc(p) = soiltc(p)/szc(p) smoistc(p) = smoistc(p)/szc(p) end do ! ----------------------------------------------------------------- ! dynamic allocation; Pierre's model (LALLOC=1) ! ----------------------------------------------------------------- if (LALLOC == 1) then do f = 1,num_soilp p = filter_soilp(f) g = pgridcell(p) ! Light limitation calculation ! ---------------------------- Llim = exp(-0.5_r8 * tlai(p)) if (Llim <= Llim_min) Llim = Llim_min if (Llim >= Llim_max) Llim = Llim_max ! Pseudo-nutrient limitation calculation ! -------------------------------------- ! set pfact = bevap (entire column) if (soiltc(p) > 0.0_r8) then pfact = min( max(smoistc(p)-watdryc(p),0._r8) / & (watoptc(p)-watdryc(p)), 1._r8 ) else pfact = 0.01_r8 end if tfact = Q10**((soilt(p)-30.0_r8)/10.0_r8) ! why not soiltc ? if (tfact >= tfact_max) tfact = tfact_max if (tfact <= tfact_min) tfact = tfact_min Nutrient = pfact*tfact if (Nutrient <= Nut_min) Nutrient = Nut_min if (Nutrient >= Nut_max) Nutrient = Nut_max ! Water limitation calculation ! ---------------------------- ! set Wlim = btran (entire column) Wlim(p)=btran(p) if (Wlim(p) <= Wlim_min) Wlim(p) = Wlim_min if (Wlim(p) >= Wlim_max) Wlim(p) = Wlim_max WorN = min(Wlim(p),Nutrient) !! determine fraction allocated to live pools if (lnonwood(ivt(p)) == 0) then livefr(p,FROOT) = R0 * 3.0_r8 * Llim/(Llim+2.0_r8*WorN) livefr(p,WOOD) = S0 * 3.0_r8 * WorN/(2.0_r8*Llim+WorN) livefr(p,LEAF) = 1.0_r8 - livefr(p,FROOT) - livefr(p,WOOD) else livefr(p,FROOT) = R0 * 3.0_r8 * Llim/(Llim+2.0_r8*WorN) livefr(p,WOOD) = 0._r8 livefr(p,LEAF) = 1.0_r8 - livefr(p,FROOT) end if end do ! end do loop end if ! end dynamic allocation ! ----------------------------------------------------------------- ! fixed allocation ! this determines allocation based on vegetation type - if there is ! wood in the vegetation class, 1/3 of NPP is given to wood litter - ! the remainder is divided evenly between leaf and root material ! ----------------------------------------------------------------- if (LALLOC == 0) then do f = 1,num_soilp p = filter_soilp(f) if (lnonwood(ivt(p)) == 0) then wood_fract = fixed_stem ! (1/3) else wood_fract = 0._r8 end if leaf_fract = (1.0_r8 - wood_fract)/2.0_r8 root_fract = (1.0_r8 - wood_fract)/2.0_r8 livefr(p,LEAF) = leaf_fract livefr(p,WOOD) = wood_fract livefr(p,FROOT) = root_fract end do end if end subroutine casa_allocate !----------------------------------------------------------------------- !BOP ! ! !IROUTINE: casa_bgfluxes ! ! !INTERFACE: subroutine casa_bgfluxes(lbp, ubp, num_soilp, filter_soilp) 1,5 ! ! !DESCRIPTION: ! Compute biogeochemical fluxes. ! ! ------------------------ code history --------------------------- ! bgfluxes_BASIC.c - BG Spin-Up Flux Sub-model VERSION 1.0 ! ! Version 2.1 ! ! Created 7-13-99 by Greg Asner ! Modified for CASA2a on 8-14-00 by Greg Asner ! Gleaned from CASA2b ! modified for LSM/CASA interface by J.John (2001) !iyf modified 7-18-01 Inez: all modifications marked by iyf ! ! ----------------------------------------------------------------- ! code only executed for soils (ist = 1) ! ! !USES: use clm_time_manager , only : get_step_size ! ! !ARGUMENTS: implicit none integer, intent(in) :: lbp, ubp ! pft bounds integer, intent(in) :: num_soilp ! number of soil points in pft filter integer, intent(in) :: filter_soilp(ubp-lbp+1) ! pft filter for soil points ! ! !LOCAL VARIABLES: integer f,g,i,j,l,n,p integer iptype real(r8) leafmass real(r8) dtime !land model time step (sec) ! ------------------------ input/output variables ----------------- ! input integer , pointer :: ivt(:) !pft vegetation type real(r8), pointer :: fnpp(:) !NPP (gC/m2/sec) real(r8), pointer :: excessC(:) !excess Carbon (gC/m2/timestep) real(r8), pointer :: bgtemp(:) !temperature dependence for C pools real(r8), pointer :: bgmoist(:) !moisture dependence for C pools real(r8), pointer :: soilt(:) !soil temp for top 30cm real(r8), pointer :: smoist(:) !soil moisture for top 30cm real(r8), pointer :: watopt(:) real(r8), pointer :: watdry(:) real(r8), pointer :: Wlim(:) real(r8), pointer :: livefr(:,:) !live fraction real(r8), pointer :: sandfrac(:) ! implicit intent inout !============================================================ real(r8), pointer :: plai(:) ! prognostic LAI (m2 leaf/m2 ground) real(r8), pointer :: Closs(:,:) real(r8), pointer :: Ctrans(:,:) ! C transfers out of pool types real(r8), pointer :: Resp_C(:,:) ! could dimension by ndead, but caution!!! real(r8), pointer :: Tpool_C(:,:) real(r8), pointer :: Cflux(:) real(r8), pointer :: XSCpool(:) real(r8), pointer :: co2flux(:) !net CO2 flux (gC/m2/s) [+ = to atm] ! ! !CALLED FROM: ! Casa in CASAMod ! ! !REVISION HISTORY: ! 2004.06.08 Vectorized and reformatted by Forrest Hoffman ! !EOP !----------------------------------------------------------------------- ivt => clm3%g%l%c%p%itype fnpp => clm3%g%l%c%p%pps%fnpp bgtemp => clm3%g%l%c%p%pps%bgtemp bgmoist => clm3%g%l%c%p%pps%bgmoist excessC => clm3%g%l%c%p%pps%excessC plai => clm3%g%l%c%p%pps%plai Closs => clm3%g%l%c%p%pps%Closs Ctrans => clm3%g%l%c%p%pps%Ctrans Resp_C => clm3%g%l%c%p%pps%Resp_C Tpool_C => clm3%g%l%c%p%pps%Tpool_C XSCpool => clm3%g%l%c%p%pps%XSCpool Cflux => clm3%g%l%c%p%pps%Cflux soilt => clm3%g%l%c%p%pps%soilt smoist => clm3%g%l%c%p%pps%smoist watdry => clm3%g%l%c%p%pps%watdry watopt => clm3%g%l%c%p%pps%watopt Wlim => clm3%g%l%c%p%pps%Wlim co2flux => clm3%g%l%c%p%pps%co2flux livefr => clm3%g%l%c%p%pps%livefr sandfrac => clm3%g%l%c%p%pps%sandfrac ! ----------------------------------------------------------------- ! Get step size dtime = get_step_size() !---Step 1: growth and allocation ----------------------------- ! INCREMENT PLANT CARBON POOLS (Initialized in casainit.F) ! Allocation (livefr) may or may not depend on climate ! Tpool is unit of gC/m2 do n = 1, nlive do f = 1,num_soilp p = filter_soilp(f) Tpool_C(p,n) = Tpool_C(p,n) + livefr(p,n) * fnpp(p) * dtime end do end do do f = 1,num_soilp p = filter_soilp(f) !iyf ***** !iyf 02/07/22 !iyf Keep track of fluxes !iyf Transfer excess leaf carbon to root !jgj 02/09/19 !>> root pool is getting too big - don't dump excess carbon into root pool !>> save excess in separate (phothosynthate) pool for diagnostic purposes !>> dump excess into autotrophic respiration (see below: litterfall) excessC(p) = max(Tpool_C(p,LEAF)-leafmax(ivt(p)), 0.0_r8) Tpool_C(p,LEAF) = min(Tpool_C(p,LEAF), leafmax(ivt(p))) XSCpool(p) = XSCpool(p) + excessC(p) !iyf - end1 ***** end do !---Step 1a: determine prognostic LAI -------------------------------- ! Leaf mass (gC/m2 ground) to LAI (m2 leaf/m2 ground) ! use Specific Leaf Area (m2 leaf/kgC) from Dickinson et al. ! SLA is a function of veg type ! Tpool is unit of gC/m2 do f = 1,num_soilp p = filter_soilp(f) leafmass = Tpool_C(p,LEAF)*1.e-3_r8 ! (kg C/m2 ground) plai(p) = leafmass * sla(ivt(p))! m2 leaf/m2 ground !iyf upper limit is placed here on leaf mass in this subroutine above !iyf lower limit is placed on CLoss in casa_litterfall.F if(plai(p) >= plai_max(ivt(p)))plai(p) = plai_max(ivt(p)) if(plai(p) <= plai_min(ivt(p)))plai(p) = plai_min(ivt(p)) end do !---Step 2: death and litterfall ------------------------------- ! COMPUTE FLUXES FROM LITTERFALL !iyf: these use "annK" for the three live pools ! 03/03/11 dump excessC into CLOSS101 (g/m2/timestep) call casa_litscl(lbp, ubp) call casa_litterfall(lbp, ubp, num_soilp, filter_soilp) !---Step 3: respiration --------------------------------------- !iyf this should be heterotrophic respiration only !.. Initialize respiration fluxes each timestep !.. Note: these should be over dead pools only (see resp_pool_index) !iyf: Resp in unit of gC/m2/timestep do n = 1, npools do f = 1,num_soilp p = filter_soilp(f) Resp_C(p,n) = 0._r8 ! could dimension by ndead, but caution later!!! end do end do !---Step 3a: TEMPERATURE AND MOISTURE CONSTRAINTS ON DECOMP ! bgmoist currently set to 0.5 for all points ! 01/07/04 change bgmoist to CLM2/LPJ temperature dependence do f = 1,num_soilp p = filter_soilp(f) ! temperature dependence bgtemp(p) = (Q10 ** ((soilt(p) - 30.0_r8) / 10.0_r8)) !................................................................... ! moisture dependence ! this is like Water limitation calculation in casa_allocate.F ! moist_resp = 0.25 + 0.75 * clm%wf ! ! there are different parametrizations of moisture dependence ! eg bgmoist = 0.5 ! eg: Pierre Friedlingstein's moisture dependence - fn(Wlim) !................................................................... ! mod 02/07/17 go back to linear calculation of bgmoist ! mimic calculation of bevap in surphy.F to get Wlim ! but use smoist,soilt instead of h2osoi,tsoi and watsat instead of watopt ! watdry = water content when evapotranspiration stops = wp ! watsat = volumetric soil water content, saturation (porosity) = fcap if (soilt(p) > 0.0_r8) then Wlim(p) = min( max(smoist(p)-watdry(p),0._r8) / & (watopt(p)-watdry(p)), 1._r8 ) else Wlim(p) = 0.01_r8 end if bgmoist(p) = 0.25_r8 + 0.75_r8*Wlim(p) !................................................................... end do !------------------------------------------------------------------------- !---Step 3b: DETERMINE loss of C FROM EACH DEAD POOL (donor) PER TIMESTEP !iyf: Closs is the amount of carbon each pool loses in gC/m2/timestep. !iyf: A fraction of Closs is transferred to another pool (receiver pool), !iyf: the remainder to the atm (resp). !iyf: The distribution of Closs is done in subroutine casa_respire, Step 3c. do n = nlive+1, npools do f = 1,num_soilp p = filter_soilp(f) Closs(p,n) = Tpool_C(p,n) * kdt(ivt(p),n) * bgtemp(p) * bgmoist(p) end do end do do f = 1,num_soilp p = filter_soilp(f) !* adjust pools Closs(p,SURFSTR) = Closs(p,SURFSTR) * lignineffect(ivt(p)) Closs(p,SOILSTR) = Closs(p,SOILSTR) * lignineffect(ivt(p)) Closs(p,SOILMIC) = Closs(p,SOILMIC) & * (1.0_r8 - 0.75_r8*(1.0_r8 - sandfrac(p))) * fact_soilmic(ivt(p)) Closs(p,SLOW) = Closs(p,SLOW) * fact_slow(ivt(p)) Closs(p,PASSIVE) = Closs(p,PASSIVE) * fact_passive(ivt(p)) end do !iyf: limits on loss from dead pools. do n = nlive+1,npools do f = 1,num_soilp p = filter_soilp(f) !iyf - replace IF test with MIN/MAX functions. !iyf - No need to track limits on loss rate !iyf (only need to track limits on inventories) Closs(p,n)=min(Closs(p,n),Tpool_C(p,n)) end do end do !---step 3c: SOM C DECOMPOSITION !iyf: update Tpool's: C is transferred between donor and receiver pools !iyf: Resp is the amount of C to atm, in gC/m2/timestep call casa_respire(lbp, ubp, num_soilp, filter_soilp) !---Step 4----------------------------------------------------------- ! CALCULATE NITROGEN POOLS ! do n = 1,npools ! do f = 1,num_soilp ! p = filter_soilp(f) ! Tpool_N(p,n)=Tpool_C(p,n)/CNratio(n) ! end do ! end do !--- Step 5 -------------------------------------------------------- ! Get Total C Fluxes to atm = Sum over respiring (dead) pools/dtlsm ! Note: Resp for live pools should be zero !iyf: Cflux in gC/m2/s Cflux(lbp:ubp)=0._r8 do n = nlive+1,npools do f = 1,num_soilp p = filter_soilp(f) Resp_C(p,n)=Resp_C(p,n)/dtime ! g/m2/s instead of g/m2/timestep Cflux(p)=Cflux(p)+Resp_C(p,n) end do end do do n = 1,npools do f = 1,num_soilp p = filter_soilp(f) Closs(p,n)=Closs(p,n)/dtime ! Nloss(p,n)=Nloss(p,n)/dtime ! not used end do end do ! Loop over all pool types to adjust units on Ctrans to gC/m2/s do iptype = 1, npool_types do f = 1,num_soilp p = filter_soilp(f) Ctrans(p,iptype) = Ctrans(p,iptype) / dtime end do end do do f = 1,num_soilp p = filter_soilp(f) ! compute co2flux co2flux(p) = (-fnpp(p) + Cflux(p)) end do end subroutine casa_bgfluxes !----------------------------------------------------------------------- !BOP ! ! !IROUTINE: casa_litscl ! ! !INTERFACE: subroutine casa_litscl(lbp, ubp) 1 ! ! !DESCRIPTION: ! Compute litter fall scalars ! ! ------------------------ code history --------------------------- ! casa_litscl.F - Litterfall scalars ! modified for LSM/CASA interface by J.John (2001) ! ! ----------------------------------------------------------------- ! Notes: ! ! These need to be changed (dependent on monthly LAI) ! ! code only executed for soils (ist = 1) ! ! ----------------------------------------------------------------- ! !ARGUMENTS: implicit none integer, intent(in) :: lbp, ubp ! pft bounds ! ! !LOCAL VARIABLES: integer l,p ! ------------------------ input/output variables ----------------- ! inputs: integer , pointer :: ltype(:) ! landunit type for corresponding pft integer , pointer :: plandunit(:) ! landunit index associated with each pft real(r8), pointer :: litterscalar(:) real(r8), pointer :: rootlitscalar(:) ! ! !CALLED FROM: ! casa_bgfluxes in CASAMod ! ! !REVISION HISTORY: ! 2004.06.08 Vectorized and reformatted by Forrest Hoffman ! !EOP !----------------------------------------------------------------------- ltype => clm3%g%l%itype plandunit => clm3%g%l%c%p%landunit litterscalar => clm3%g%l%c%p%pps%litterscalar rootlitscalar => clm3%g%l%c%p%pps%rootlitscalar ! These need to be changed (dependent on monthly LAI) do p = lbp, ubp l = plandunit(p) if (ltype(l) == istsoil) then litterscalar(p) = 1.0_r8 rootlitscalar(p) = 1.0_r8 else litterscalar(p) = 0.0_r8 rootlitscalar(p) = 0.0_r8 end if end do end subroutine casa_litscl !----------------------------------------------------------------------- !BOP ! ! !IROUTINE: casa_litterfall ! ! !INTERFACE: subroutine casa_litterfall(lbp, ubp, num_soilp, filter_soilp) 1,3 ! ! !DESCRIPTION: ! Compute dynamic litter fall. ! ! ------------------------ code history --------------------------- ! litterfall_BASIC.c - Litterfall Spin-up Sub-model VERSION 1.0 ! ! Version 2.1 ! ! Implemented by: 4-22-99 Greg Asner ! Dynamic litterfall by Jim Randerson ! modified for LSM/CASA interface by J.John (2001) ! ! ----------------------------------------------------------------- ! ! This routine is used to determine the timing of litterfall ! code only executed for soils (ist = 1) ! ! !USES: use clm_time_manager , only : get_step_size, get_nstep ! ! !ARGUMENTS: implicit none integer, intent(in) :: lbp, ubp ! pft bounds integer, intent(in) :: num_soilp ! number of soil points in pft filter integer, intent(in) :: filter_soilp(ubp-lbp+1) ! pft filter for soil points ! ! !LOCAL VARIABLES: integer f,l,p,n integer nstep real(r8) dtime !land model time step (sec) ! ------------------------ input/output variables ----------------- ! inputs: integer , pointer :: ivt(:) !pft vegetation type real(r8), pointer :: stressCD(:) ! cold and drought stress function (sec-1) ! add to "annK(m,LEAF)" and "annK(m,FROOT)" ! in casa_litterfall.F real(r8), pointer :: excessC(:) ! excess Carbon (gC/m2/timestep) real(r8), pointer :: Closs(:,:) ! C lost to atm real(r8), pointer :: Tpool_C(:,:) ! Total C pool size real(r8), pointer :: litterscalar(:) real(r8), pointer :: rootlitscalar(:) ! ! !CALLED FROM: ! casa_bgfluxes in CASAMod ! ! !REVISION HISTORY: ! 2004.06.08 Vectorized and reformatted by Forrest Hoffman ! !EOP !----------------------------------------------------------------------- ivt => clm3%g%l%c%p%itype stressCD => clm3%g%l%c%p%pps%stressCD excessC => clm3%g%l%c%p%pps%excessC Closs => clm3%g%l%c%p%pps%Closs Tpool_C => clm3%g%l%c%p%pps%Tpool_C litterscalar => clm3%g%l%c%p%pps%litterscalar rootlitscalar => clm3%g%l%c%p%pps%rootlitscalar ! ---------------------------------------------------------- ! Get step size dtime = get_step_size() nstep = get_nstep() ! FOLIAGE and ROOT LOSS; Jim's model; Needs to be checked do f = 1,num_soilp p = filter_soilp(f) ! Carbon lost as litter per timestep ! dL/dt = -L/tau ! Closs = L(n) - L(n+1) = M*delta_t/tau !iyf 02/07/11 ! stressCD to be added to "annK(m,LEAF)" and "annK(m,FROOT)" ! iyf 02/07/17 apply stressCD to leaves only (not to roots) ! in casa_litterfall.F ! kdt is used for WOOD and dead pools only (ie no stressCD needed) Closs(p,LEAF) = Tpool_C(p,LEAF) & * ((annK(ivt(p),LEAF)+stressCD(p))*dtime) * litterscalar(p) Closs(p,WOOD) = Tpool_C(p,WOOD) & * kdt(ivt(p),WOOD) Closs(p,FROOT) = Tpool_C(p,FROOT) & * ((annK(ivt(p),FROOT) )*dtime) * rootlitscalar(p) !.. mod IYF 02/07/22 !iyf !iyf Maintain a minimum Leaf Mass. Pretend LeafMin=photosynthate to start !iyf photosynthesis in the spring. !iyf If (Tpool_C(p,LEAF) > leafmin(ivt(p))) then Closs(p,LEAF) = & MIN(Tpool_C(p,LEAF)-leafmin(ivt(p)),Closs(p,LEAF)) else Closs(p,LEAF) = 0._r8 end if end do ! Decrement plant C pools : LEAF, WOOD, FROOT do n = 1,nlive do f = 1,num_soilp p = filter_soilp(f) Tpool_C(p,n) = Tpool_C(p,n)-Closs(p,n) end do end do do f = 1,num_soilp p = filter_soilp(f) !iyf 03/03/25 ! add excessC to CLOSS101 (g/m2/timestep) ! excessC is going from NPP to litter, without going through leaves. Closs(p,LEAF) = Closs(p,LEAF) + excessC(p) !Increment litter carbon pools Tpool_C(p,CWD) = Tpool_C(p,CWD) & + Closs(p,WOOD) Tpool_C(p,SURFMET) = Tpool_C(p,SURFMET) & + Closs(p,LEAF) * solubfract(ivt(p)) Tpool_C(p,SOILMET) = Tpool_C(p,SOILMET) & + Closs(p,FROOT) * solubfract(ivt(p)) Tpool_C(p,SURFSTR) = Tpool_C(p,SURFSTR) & + Closs(p,LEAF) & * (1._r8 - solubfract(ivt(p))) Tpool_C(p,SOILSTR) = Tpool_C(p,SOILSTR) & + Closs(p,FROOT) & * (1._r8 - solubfract(ivt(p))) end do end subroutine casa_litterfall !----------------------------------------------------------------------- !BOP ! ! !IROUTINE: casa_respire ! ! !INTERFACE: subroutine casa_respire(lbp, ubp, num_soilp, filter_soilp) 1 ! ! !DESCRIPTION: ! Compute respiration. ! ! ------------------------ code history --------------------------- ! respire_BASIC.c - Respiration Sub-model VERSION 1.0 ! ! Version 2.1 ! ! Created 7-13-99 by Greg Asner ! Modified for CASA2a on 8-16-00 by Greg Asner ! Gleaned from CASA2b ! modified for LSM/CASA interface by J.John (2001) ! ! ----------------------------------------------------------------- ! ! code only executed for soils (ist = 1) ! ! !ARGUMENTS: implicit none integer, intent(in) :: lbp, ubp ! pft bounds integer, intent(in) :: num_soilp ! number of soil points in pft filter integer, intent(in) :: filter_soilp(ubp-lbp+1) ! pft filter for soil points ! ! !LOCAL VARIABLES: ! ------------------------ input/output variables ----------------- ! implicit intent in !============================================================ real(r8), pointer :: Closs(:,:) ! C lost to atm real(r8), pointer :: Ctrans(:,:) ! C transfers out of pool types real(r8), pointer :: eff(:,:) real(r8), pointer :: frac_donor(:,:) ! implicit intent out !============================================================ real(r8), pointer :: Resp_C(:,:) ! real(r8), pointer :: Tpool_C(:,:) ! Total C pool size ! ------------------------ local variables ----------------- integer f,l,p,n integer irtype,iptype integer donor_pool integer recvr_pool integer donor_type integer recvr_type real(r8) Out ! ! !CALLED FROM: ! casa_bgfluxes in CASAMod ! ! !REVISION HISTORY: ! 2004.06.08 Vectorized and reformatted by Forrest Hoffman ! !EOP !----------------------------------------------------------------------- Closs => clm3%g%l%c%p%pps%Closs Ctrans => clm3%g%l%c%p%pps%Ctrans Resp_C => clm3%g%l%c%p%pps%Resp_C Tpool_C => clm3%g%l%c%p%pps%Tpool_C eff => clm3%g%l%c%p%pps%eff frac_donor => clm3%g%l%c%p%pps%frac_donor ! Loop over all pool types to initialize transfer to zero do iptype = 1, npool_types do f = 1,num_soilp p = filter_soilp(f) Ctrans(p,iptype) = 0._r8 end do end do ! Loop over all respiring pools do irtype = 1, nresp_pools donor_pool = resp_pool_index(1,irtype) recvr_pool = resp_pool_index(2,irtype) donor_type = pool_type_index(donor_pool) recvr_type = pool_type_index(recvr_pool) ! Loop over pfts do f = 1,num_soilp p = filter_soilp(f) Out = Closs(p,donor_pool) * frac_donor(p,irtype) ! accumulate total pool transfers by pool type if (donor_type .ne. recvr_type) then Ctrans(p,donor_type) = Ctrans(p,donor_type) + (Out * eff(p,irtype)) end if Tpool_C(p,donor_pool) = Tpool_C(p,donor_pool) & - Out Tpool_C(p,recvr_pool) = Tpool_C(p,recvr_pool) & + (Out * eff(p,irtype)) Resp_C(p,donor_pool) = Resp_C(p,donor_pool) & + Out * (1._r8 - eff(p,irtype)) ! make sure donor pool does not fall below zero if (Tpool_C(p,donor_pool) <= 0.0_r8) then Tpool_C(p,donor_pool) = 0.0_r8 end if end do ! end number of points end do ! end number of pools ! Stuff the total C lost by live pools into live pool type transfers do n = 1, nlive do f = 1,num_soilp p = filter_soilp(f) Ctrans(p,pool_type_index(n)) = Ctrans(p,pool_type_index(n)) + & Closs(p,n) end do end do ! Add in the respired C to transfers out of pool types do n = nlive+1, npools do f = 1,num_soilp p = filter_soilp(f) Ctrans(p,pool_type_index(n)) = Ctrans(p,pool_type_index(n)) + & Resp_C(p,n) end do end do end subroutine casa_respire !----------------------------------------------------------------------- !BOP ! ! !IROUTINE: CASARest ! ! !INTERFACE: subroutine CASARest(ncid, flag) 3,74 ! ! !DESCRIPTION: ! Read/Write CASA information to/from restart file. ! ! !USES: use clmtype use ncdio ! ! !ARGUMENTS: implicit none integer, intent(in) :: ncid !netcdf id character(len=*), intent(in) :: flag !'read' or 'write' ! ! !CALLED FROM: ! restart in restFileMod ! ! !REVISION HISTORY: ! Author: Mariana Vertenstein ! 2004.06.08 Vectorized and reformatted by Forrest Hoffman ! ! !LOCAL VARIABLES: integer :: p,j ! indices logical :: readvar ! determine if variable is on initial file type(gridcell_type), pointer :: gptr ! pointer to gridcell derived subtype type(landunit_type), pointer :: lptr ! pointer to landunit derived subtype type(column_type) , pointer :: cptr ! pointer to column derived subtype type(pft_type) , pointer :: pptr ! pointer to pft derived subtype !EOP !----------------------------------------------------------------------- ! Set pointers into derived type gptr => clm3%g lptr => clm3%g%l cptr => clm3%g%l%c pptr => clm3%g%l%c%p ! pft type physical state variable - livefr if (flag == 'define') then call ncd_defvar(ncid=ncid, varname='livefr', xtype=nf_double, & dim1name='pft', dim2name='nlive',& long_name='',units='') else if (flag == 'read' .or. flag == 'write') then call ncd_iolocal(varname='livefr', data=pptr%pps%livefr, & dim1name=namep, dim2name='nlive', & ncid=ncid, flag=flag, readvar=readvar) if (flag=='read' .and. .not. readvar) then if (is_restart()) call endrun end if end if ! pft type physical state variable - Tpool_C (Tracer 1) if (flag == 'define') then call ncd_defvar(ncid=ncid, varname='Tpool_C', xtype=nf_double, & dim1name='pft', dim2name='npools',& long_name='',units='') else if (flag == 'read' .or. flag == 'write') then call ncd_iolocal(varname='Tpool_C', data=pptr%pps%Tpool_C, & dim1name=namep, dim2name='npools', & ncid=ncid, flag=flag, readvar=readvar) if (flag=='read') then if (.not. readvar) then if (is_restart()) then call endrun else if (masterproc) & write(iulog,*)'WARNING: TPOOL_C not contained on initial/restart dataset' end if else if (masterproc) & write(iulog,*)'TPOOL_C read from initial/restart dataset' cpool_inic = .true. end if end if end if ! pft type physical state variable - lgrow if (flag == 'define') then call ncd_defvar(ncid=ncid, varname='lgrow', xtype=nf_double, & dim1name='pft',long_name='',units='') else if (flag == 'read' .or. flag == 'write') then call ncd_iolocal(varname='lgrow', data=pptr%pps%lgrow, & dim1name=namep, ncid=ncid, flag=flag, readvar=readvar) if (flag=='read' .and. .not. readvar) then if (is_restart()) call endrun end if end if ! pft type physical state variable - iseabeg if (flag == 'define') then call ncd_defvar(ncid=ncid, varname='iseabeg', xtype=nf_double, & dim1name='pft',long_name='',units='') else if (flag == 'read' .or. flag == 'write') then call ncd_iolocal(varname='iseabeg', data=pptr%pps%iseabeg, & dim1name=namep, ncid=ncid, flag=flag, readvar=readvar) if (flag=='read' .and. .not. readvar) then if (is_restart()) call endrun end if end if ! pft type physical state variable - nstepbeg if (flag == 'define') then call ncd_defvar(ncid=ncid, varname='nstepbeg', xtype=nf_double, & dim1name='pft',long_name='',units='') else if (flag == 'read' .or. flag == 'write') then call ncd_iolocal(varname='nstepbeg', data=pptr%pps%nstepbeg, & dim1name=namep, ncid=ncid, flag=flag, readvar=readvar) if (flag=='read' .and. .not. readvar) then if (is_restart()) call endrun end if end if ! pft type physical state variable - degday if (flag == 'define') then call ncd_defvar(ncid=ncid, varname='degday', xtype=nf_double, & dim1name='pft',long_name='',units='') else if (flag == 'read' .or. flag == 'write') then call ncd_iolocal(varname='degday', data=pptr%pps%degday, & dim1name=namep, ncid=ncid, flag=flag, readvar=readvar) if (flag=='read' .and. .not. readvar) then if (is_restart()) call endrun end if end if ! pft type physical state variable - ndegday if (flag == 'define') then call ncd_defvar(ncid=ncid, varname='ndegday', xtype=nf_double, & dim1name='pft',long_name='',units='') else if (flag == 'read' .or. flag == 'write') then call ncd_iolocal(varname='ndegday', data=pptr%pps%ndegday, & dim1name=namep, ncid=ncid, flag=flag, readvar=readvar) if (flag=='read' .and. .not. readvar) then if (is_restart()) call endrun end if end if ! pft type physical state variable - tday if (flag == 'define') then call ncd_defvar(ncid=ncid, varname='tday', xtype=nf_double, & dim1name='pft',long_name='',units='') else if (flag == 'read' .or. flag == 'write') then call ncd_iolocal(varname='tday', data=pptr%pps%tday, & dim1name=namep, ncid=ncid, flag=flag, readvar=readvar) if (flag=='read' .and. .not. readvar) then if (is_restart()) call endrun end if end if ! pft type physical state variable - tcount if (flag == 'define') then call ncd_defvar(ncid=ncid, varname='tcount', xtype=nf_double, & dim1name='pft',long_name='',units='') else if (flag == 'read' .or. flag == 'write') then call ncd_iolocal(varname='tcount', data=pptr%pps%tcount, & dim1name=namep, ncid=ncid, flag=flag, readvar=readvar) if (flag=='read' .and. .not. readvar) then if (is_restart()) call endrun end if end if ! pft type physical state variable - tdayavg if (flag == 'define') then call ncd_defvar(ncid=ncid, varname='tdayavg', xtype=nf_double, & dim1name='pft',long_name='',units='') else if (flag == 'read' .or. flag == 'write') then call ncd_iolocal(varname='tdayavg', data=pptr%pps%tdayavg, & dim1name=namep, ncid=ncid, flag=flag, readvar=readvar) if (flag=='read' .and. .not. readvar) then if (is_restart()) call endrun end if end if ! pft type physical state variable - stressCD if (flag == 'define') then call ncd_defvar(ncid=ncid, varname='stressCD', xtype=nf_double, & dim1name='pft',long_name='',units='') else if (flag == 'read' .or. flag == 'write') then call ncd_iolocal(varname='stressCD', data=pptr%pps%stressCD, & dim1name=namep, ncid=ncid, flag=flag, readvar=readvar) if (flag=='read' .and. .not. readvar) then if (is_restart()) call endrun end if end if !! added so history output is correct ! pft type physical state variable - stressT if (flag == 'define') then call ncd_defvar(ncid=ncid, varname='stressT', xtype=nf_double, & dim1name='pft',long_name='',units='') else if (flag == 'read' .or. flag == 'write') then call ncd_iolocal(varname='stressT', data=pptr%pps%stressT, & dim1name=namep, ncid=ncid, flag=flag, readvar=readvar) if (flag=='read' .and. .not. readvar) then if (is_restart()) call endrun end if end if ! pft type physical state variable - stressW if (flag == 'define') then call ncd_defvar(ncid=ncid, varname='stressW', xtype=nf_double, & dim1name='pft',long_name='',units='') else if (flag == 'read' .or. flag == 'write') then call ncd_iolocal(varname='stressW', data=pptr%pps%stressW, & dim1name=namep, ncid=ncid, flag=flag, readvar=readvar) if (flag=='read' .and. .not. readvar) then if (is_restart()) call endrun end if end if !! end addition ! pft type physical state variable - XSCpool if (flag == 'define') then call ncd_defvar(ncid=ncid, varname='XSCpool', xtype=nf_double, & dim1name='pft',long_name='',units='') else if (flag == 'read' .or. flag == 'write') then call ncd_iolocal(varname='XSCpool', data=pptr%pps%XSCpool, & dim1name=namep, ncid=ncid, flag=flag, readvar=readvar) if (flag=='read' .and. .not. readvar) then if (is_restart()) call endrun end if end if ! eflx_lwrad_net => clm3%g%l%c%p%pef%eflx_lwrad_net if (flag == 'define') then call ncd_defvar(ncid=ncid, varname='eflx_lwrad_net', xtype=nf_double, & dim1name='pft',long_name='',units='') else if (flag == 'read' .or. flag == 'write') then call ncd_iolocal(varname='eflx_lwrad_net', data=pptr%pef%eflx_lwrad_net, & dim1name=namep, ncid=ncid, flag=flag, readvar=readvar) if (flag=='read' .and. .not. readvar) then if (is_restart()) call endrun end if end if ! eflx_lh_grnd => clm3%g%l%c%p%pef%eflx_lh_grnd if (flag == 'define') then call ncd_defvar(ncid=ncid, varname='eflx_lh_grnd', xtype=nf_double, & dim1name='pft',long_name='',units='') else if (flag == 'read' .or. flag == 'write') then call ncd_iolocal(varname='eflx_lh_grnd', data=pptr%pef%eflx_lh_grnd, & dim1name=namep, ncid=ncid, flag=flag, readvar=readvar) if (flag=='read' .and. .not. readvar) then if (is_restart()) call endrun end if end if ! eflx_lh_vege => clm3%g%l%c%p%pef%eflx_lh_vege if (flag == 'define') then call ncd_defvar(ncid=ncid, varname='eflx_lh_vege', xtype=nf_double, & dim1name='pft',long_name='',units='') else if (flag == 'read' .or. flag == 'write') then call ncd_iolocal(varname='eflx_lh_vege', data=pptr%pef%eflx_lh_vege, & dim1name=namep, ncid=ncid, flag=flag, readvar=readvar) if (flag=='read' .and. .not. readvar) then if (is_restart()) call endrun end if end if ! eflx_lh_vegt => clm3%g%l%c%p%pef%eflx_lh_vegt if (flag == 'define') then call ncd_defvar(ncid=ncid, varname='eflx_lh_vegt', xtype=nf_double, & dim1name='pft',long_name='',units='') else if (flag == 'read' .or. flag == 'write') then call ncd_iolocal(varname='eflx_lh_vegt', data=pptr%pef%eflx_lh_vegt, & dim1name=namep, ncid=ncid, flag=flag, readvar=readvar) if (flag=='read' .and. .not. readvar) then if (is_restart()) call endrun end if end if end subroutine CASARest !----------------------------------------------------------------------- !BOP ! ! !IROUTINE: is_restart ! ! !INTERFACE: logical function is_restart( ) 307,6 ! ! !DESCRIPTION: ! Determine if restart run ! ! !USES: use clm_varctl, only : nsrest ! ! !ARGUMENTS: implicit none ! ! !CALLED FROM: ! subroutine initialize in this module ! ! !REVISION HISTORY: ! Created by Mariana Vertenstein ! !EOP !----------------------------------------------------------------------- if (nsrest == 1) then is_restart = .true. else is_restart = .false. end if end function is_restart #if (defined CLAMP) !=============================================================================== !BOP ! ! !IROUTINE: CASASummary ! ! !INTERFACE: subroutine CASASummary(lbp, ubp, num_soilp, filter_soilp) 1,2 ! ! !DESCRIPTION: ! Perform pft carbon summary calculations ! ! !USES: use clm_time_manager, only: get_step_size ! ! !ARGUMENTS: implicit none integer, intent(in) :: lbp, ubp ! pft bounds integer, intent(in) :: num_soilp ! number of soil points in pft filter integer, intent(in) :: filter_soilp(ubp-lbp+1) ! pft filter for soil points ! ! !CALLED FROM: ! subroutine casa_ecocystemDyn ! ! !REVISION HISTORY: ! 22 Sept 2006: Created by Forrest Hoffman ! ! !LOCAL VARIABLES: ! local pointers to implicit in scalars real(r8), pointer :: fpsn(:) !photosynthesis (umol CO2 /m**2 /s) real(r8), pointer :: Tpool_C(:,:) ! Total C by pool real(r8), pointer :: Resp_C(:,:) ! Respired C by pool real(r8), pointer :: Closs(:,:) ! Lost C by pool real(r8), pointer :: Ctrans(:,:) ! Transferred C by pool type real(r8), pointer :: Cflux(:) ! C flux real(r8), pointer :: livefr(:,:) ! Live fraction real(r8), pointer :: fnpp(:) ! NPP (gC/m2/sec) real(r8), pointer :: co2flux(:) ! net CO2 flux (gC/m2/s) [+= atm] ! ! ! local pointers to implicit in/out scalars ! ! ! local pointers to implicit out scalars real(r8), pointer :: casa_agnpp(:) ! above-ground net primary production [gC/m2/s] real(r8), pointer :: casa_ar(:) ! autotrophic respiration [gC/m2/s] real(r8), pointer :: casa_bgnpp(:) ! below-ground net primary production [gC/m2/s] real(r8), pointer :: casa_cwdc(:) ! coarse woody debris C [gC/m2] real(r8), pointer :: casa_cwdc_hr(:) ! cwd heterotrophic respiration [gC/m2/s] real(r8), pointer :: casa_cwdc_loss(:) ! cwd C loss [gC/m2/s] real(r8), pointer :: casa_frootc(:) ! fine root C [gC/m2] real(r8), pointer :: casa_frootc_alloc(:) ! fine root C allocation [gC/m2/s] real(r8), pointer :: casa_frootc_loss(:) ! fine root C loss [gC/m2/s] real(r8), pointer :: casa_gpp(:) ! gross primary production [gC/m2/s] real(r8), pointer :: casa_hr(:) ! total heterotrophic respiration [gC/m2/s] real(r8), pointer :: casa_leafc(:) ! leaf C [gC/m2] real(r8), pointer :: casa_leafc_alloc(:) ! leaf C allocation [gC/m2/s] real(r8), pointer :: casa_leafc_loss(:) ! leaf C loss [gC/m2/s] real(r8), pointer :: casa_litterc(:) ! total litter C (excluding cwd C) [gC/m2] real(r8), pointer :: casa_litterc_hr(:) ! litter heterotrophic respiration [gC/m2/s] real(r8), pointer :: casa_litterc_loss(:) ! litter C loss [gC/m2/s] real(r8), pointer :: casa_nee(:) ! net ecosystem exchange [gC/m2/s] real(r8), pointer :: casa_nep(:) ! net ecosystem production [gC/m2/s] real(r8), pointer :: casa_npp(:) ! net primary production [gC/m2/s] real(r8), pointer :: casa_soilc(:) ! total soil organic matter C (excluding cwd and litter C) [gC/m2] real(r8), pointer :: casa_soilc_hr(:) ! soil heterotrophic respiration [gC/m2/s] real(r8), pointer :: casa_soilc_loss(:) ! total soil organic matter C loss [gC/m2/s] real(r8), pointer :: casa_woodc(:) ! wood C [gC/m2] real(r8), pointer :: casa_woodc_alloc(:) ! wood C allocation [gC/m2/s] real(r8), pointer :: casa_woodc_loss(:) ! wood C loss [gC/m2/s] ! ! ! !OTHER LOCAL VARIABLES: integer :: f,p ! indices real(r8):: dtime ! land model time step (sec) !EOP !----------------------------------------------------------------------- ! assign local pointers at the pft level fpsn => clm3%g%l%c%p%pcf%fpsn Tpool_C => clm3%g%l%c%p%pps%Tpool_C Resp_C => clm3%g%l%c%p%pps%Resp_C Closs => clm3%g%l%c%p%pps%Closs Ctrans => clm3%g%l%c%p%pps%Ctrans Cflux => clm3%g%l%c%p%pps%Cflux livefr => clm3%g%l%c%p%pps%livefr fnpp => clm3%g%l%c%p%pps%fnpp co2flux => clm3%g%l%c%p%pps%co2flux casa_agnpp => clm3%g%l%c%p%pps%casa_agnpp casa_ar => clm3%g%l%c%p%pps%casa_ar casa_bgnpp => clm3%g%l%c%p%pps%casa_bgnpp casa_cwdc => clm3%g%l%c%p%pps%casa_cwdc casa_cwdc_hr => clm3%g%l%c%p%pps%casa_cwdc_hr casa_cwdc_loss => clm3%g%l%c%p%pps%casa_cwdc_loss casa_frootc => clm3%g%l%c%p%pps%casa_frootc casa_frootc_alloc => clm3%g%l%c%p%pps%casa_frootc_alloc casa_frootc_loss => clm3%g%l%c%p%pps%casa_frootc_loss casa_gpp => clm3%g%l%c%p%pps%casa_gpp casa_hr => clm3%g%l%c%p%pps%casa_hr casa_leafc => clm3%g%l%c%p%pps%casa_leafc casa_leafc_alloc => clm3%g%l%c%p%pps%casa_leafc_alloc casa_leafc_loss => clm3%g%l%c%p%pps%casa_leafc_loss casa_litterc => clm3%g%l%c%p%pps%casa_litterc casa_litterc_hr => clm3%g%l%c%p%pps%casa_litterc_hr casa_litterc_loss => clm3%g%l%c%p%pps%casa_litterc_loss casa_nee => clm3%g%l%c%p%pps%casa_nee casa_nep => clm3%g%l%c%p%pps%casa_nep casa_npp => clm3%g%l%c%p%pps%casa_npp casa_soilc => clm3%g%l%c%p%pps%casa_soilc casa_soilc_hr => clm3%g%l%c%p%pps%casa_soilc_hr casa_soilc_loss => clm3%g%l%c%p%pps%casa_soilc_loss casa_woodc => clm3%g%l%c%p%pps%casa_woodc casa_woodc_alloc => clm3%g%l%c%p%pps%casa_woodc_alloc casa_woodc_loss => clm3%g%l%c%p%pps%casa_woodc_loss ! Get step size dtime = get_step_size() ! pft loop do f = 1, num_soilp p = filter_soilp(f) ! calculate pft-level summary carbon fluxes and states ! autotrophic respiration casa_ar(p) = gppfact * fpsn(p) * 12.0_r8 * 1.e-6_r8 ! umolC/m2/s to gC/m2/s ! gross primary production casa_gpp(p) = fpsn(p) * 12.0_r8 * 1.e-6_r8 ! umolC/m2/s to gC/m2/s ! total heterotrophic respiration casa_hr(p) = Cflux(p) ! net ecosystem exchange casa_nee(p) = co2flux(p) ! net ecosystem production casa_nep(p) = -1._r8 * co2flux(p) ! net primary production casa_npp(p) = fnpp(p) ! above-ground and below-ground NPP casa_agnpp(p) = (livefr(p,LEAF) + 0.8_r8 * livefr(p,WOOD)) * fnpp(p) casa_bgnpp(p) = (livefr(p,FROOT) + 0.2_r8 * livefr(p,WOOD)) * fnpp(p) ! leaf C casa_leafc(p) = Tpool_C(p,LEAF) casa_leafc_alloc(p) = livefr(p,LEAF) * fnpp(p) casa_leafc_loss(p) = Closs(p,LEAF) ! wood C casa_woodc(p) = Tpool_C(p,WOOD) casa_woodc_alloc(p) = livefr(p,WOOD) * fnpp(p) casa_woodc_loss(p) = Closs(p,WOOD) ! fine root C casa_frootc(p) = Tpool_C(p,FROOT) casa_frootc_alloc(p) = livefr(p,FROOT) * fnpp(p) casa_frootc_loss(p) = Closs(p,FROOT) ! coarse woody debris C casa_cwdc(p) = Tpool_C(p,CWD) casa_cwdc_hr(p) = Resp_C(p,CWD) casa_cwdc_loss(p) = Ctrans(p,CWD_TYPE) ! litter C casa_litterc(p) = Tpool_C(p,SURFMET) + Tpool_C(p,SURFSTR) + & Tpool_C(p,SOILMET) + Tpool_C(p,SOILSTR) casa_litterc_hr(p) = Resp_C(p,SURFMET) + Resp_C(p,SURFSTR) + & Resp_C(p,SOILMET) + Resp_C(p,SOILSTR) casa_litterc_loss(p) = Ctrans(p,LITTER_TYPE) ! soil C casa_soilc(p) = Tpool_C(p,SURFMIC) + Tpool_C(p,SOILMIC) + & Tpool_C(p,SLOW) + Tpool_C(p,PASSIVE) casa_soilc_hr(p) = Resp_C(p,SURFMIC) + Resp_C(p,SOILMIC) + & Resp_C(p,SLOW) + Resp_C(p,PASSIVE) casa_soilc_loss(p) = Ctrans(p,SOIL_TYPE) end do ! end of pfts loop end subroutine CASASummary !=============================================================================== #endif #endif end module CASAMod