Skip to content

Commit 08bb140

Browse files
authored
Merge pull request #462 from rgknox/cxu-rgknox-gpp-season-cycle
leaf age classifications
2 parents 1ca837f + 1191c88 commit 08bb140

21 files changed

+999
-421
lines changed

biogeochem/EDCanopyStructureMod.F90

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1242,7 +1242,7 @@ subroutine canopy_summarization( nsites, sites, bc_in )
12421242

12431243
currentCohort%treelai = tree_lai(leaf_c, &
12441244
currentCohort%pft, currentCohort%c_area, currentCohort%n, &
1245-
currentCohort%canopy_layer, currentPatch%canopy_layer_tlai )
1245+
currentCohort%canopy_layer, currentPatch%canopy_layer_tlai,currentCohort%vcmax25top )
12461246

12471247
canopy_leaf_area = canopy_leaf_area + currentCohort%treelai *currentCohort%c_area
12481248

@@ -1417,11 +1417,11 @@ subroutine leaf_area_profile( currentSite , snow_depth_si, frac_sno_eff_si)
14171417

14181418
currentCohort%treelai = tree_lai(leaf_c, currentCohort%pft, currentCohort%c_area, &
14191419
currentCohort%n, currentCohort%canopy_layer, &
1420-
currentPatch%canopy_layer_tlai )
1420+
currentPatch%canopy_layer_tlai,currentCohort%vcmax25top )
14211421

14221422
currentCohort%treesai = tree_sai(currentCohort%pft, currentCohort%dbh, currentCohort%canopy_trim, &
14231423
currentCohort%c_area, currentCohort%n, currentCohort%canopy_layer, &
1424-
currentPatch%canopy_layer_tlai, currentCohort%treelai )
1424+
currentPatch%canopy_layer_tlai, currentCohort%treelai ,currentCohort%vcmax25top)
14251425

14261426
currentCohort%lai = currentCohort%treelai *currentCohort%c_area/currentPatch%total_canopy_area
14271427
currentCohort%sai = currentCohort%treesai *currentCohort%c_area/currentPatch%total_canopy_area

biogeochem/EDCohortDynamicsMod.F90

Lines changed: 168 additions & 31 deletions
Large diffs are not rendered by default.

biogeochem/EDPatchDynamicsMod.F90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ subroutine spawn_patches( currentSite, bc_in)
407407
currentCohort => currentPatch%shortest
408408
do while(associated(currentCohort))
409409

410-
allocate(nc)
410+
allocate(nc)
411411
if(hlm_use_planthydro.eq.itrue) call InitHydrCohort(CurrentSite,nc)
412412
call InitPRTCohort(nc)
413413
call zero_cohort(nc)

biogeochem/EDPhysiologyMod.F90

Lines changed: 122 additions & 132 deletions
Large diffs are not rendered by default.

biogeochem/FatesAllometryMod.F90

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,7 @@ end subroutine storage_fraction_of_target
550550

551551
! =====================================================================================
552552

553-
real(r8) function tree_lai( leaf_c, pft, c_area, nplant, cl, canopy_lai)
553+
real(r8) function tree_lai( leaf_c, pft, c_area, nplant, cl, canopy_lai, vcmax25top)
554554

555555
! -----------------------------------------------------------------------------------
556556
! LAI of individual trees is a function of the total leaf area and the total
@@ -565,6 +565,8 @@ real(r8) function tree_lai( leaf_c, pft, c_area, nplant, cl, canopy_lai)
565565
integer, intent(in) :: cl ! canopy layer index
566566
real(r8), intent(in) :: canopy_lai(nclmax) ! total leaf area index of
567567
! each canopy layer
568+
real(r8), intent(in) :: vcmax25top ! maximum carboxylation rate at canopy
569+
! top, ref 25C
568570

569571
! !LOCAL VARIABLES:
570572
real(r8) :: leafc_per_unitarea ! KgC of leaf per m2 area of ground.
@@ -601,7 +603,7 @@ real(r8) function tree_lai( leaf_c, pft, c_area, nplant, cl, canopy_lai)
601603
end if
602604

603605
! Coefficient for exponential decay of 1/sla with canopy depth:
604-
kn = decay_coeff_kn(pft)
606+
kn = decay_coeff_kn(pft,vcmax25top)
605607

606608
! take PFT-level maximum SLA value, even if under a thick canopy (which has units of m2/gC),
607609
! and put into units of m2/kgC
@@ -677,7 +679,7 @@ end function tree_lai
677679

678680
! ============================================================================
679681

680-
real(r8) function tree_sai( pft, dbh, canopy_trim, c_area, nplant, cl, canopy_lai, treelai )
682+
real(r8) function tree_sai( pft, dbh, canopy_trim, c_area, nplant, cl, canopy_lai, treelai, vcmax25top )
681683

682684
! ============================================================================
683685
! SAI of individual trees is a function of the LAI of individual trees
@@ -692,13 +694,15 @@ real(r8) function tree_sai( pft, dbh, canopy_trim, c_area, nplant, cl, canopy_la
692694
real(r8), intent(in) :: canopy_lai(nclmax) ! total leaf area index of
693695
! each canopy layer
694696
real(r8), intent(in) :: treelai ! tree LAI for checking purposes only
697+
real(r8), intent(in) :: vcmax25top ! maximum carboxylation rate at top of crown
698+
695699

696700
real(r8) :: target_bleaf
697701
real(r8) :: target_lai
698702

699703
call bleaf(dbh,pft,canopy_trim,target_bleaf)
700704

701-
target_lai = tree_lai( target_bleaf, pft, c_area, nplant, cl, canopy_lai)
705+
target_lai = tree_lai( target_bleaf, pft, c_area, nplant, cl, canopy_lai, vcmax25top)
702706

703707
tree_sai = EDPftvarcon_inst%allom_sai_scaler(pft) * target_lai
704708

@@ -2109,7 +2113,7 @@ end subroutine jackson_beta_root_profile
21092113
! =====================================================================================
21102114

21112115

2112-
real(r8) function decay_coeff_kn(pft)
2116+
real(r8) function decay_coeff_kn(pft,vcmax25top)
21132117

21142118
! ---------------------------------------------------------------------------------
21152119
! This function estimates the decay coefficient used to estimate vertical
@@ -2123,6 +2127,8 @@ real(r8) function decay_coeff_kn(pft)
21232127

21242128
!ARGUMENTS
21252129
integer, intent(in) :: pft
2130+
real(r8),intent(in) :: vcmax25top
2131+
21262132

21272133
!LOCAL VARIABLES
21282134
! -----------------------------------------------------------------------------------
@@ -2131,7 +2137,7 @@ real(r8) function decay_coeff_kn(pft)
21312137
! kn = 0.11. Here, we derive kn from vcmax25 as in Lloyd et al
21322138
! (2010) Biogeosciences, 7, 1833-1859
21332139

2134-
decay_coeff_kn = exp(0.00963_r8 * EDPftvarcon_inst%vcmax25top(pft) - 2.43_r8)
2140+
decay_coeff_kn = exp(0.00963_r8 * vcmax25top - 2.43_r8)
21352141

21362142
return
21372143
end function decay_coeff_kn

biogeophys/FatesPlantRespPhotosynthMod.F90

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,15 @@ module FATESPlantRespPhotosynthMod
2424
use FatesGlobals, only : fates_log
2525
use FatesConstantsMod, only : r8 => fates_r8
2626
use FatesConstantsMod, only : itrue
27+
use FatesConstantsMod, only : nearzero
2728
use FatesInterfaceMod, only : hlm_use_planthydro
2829
use FatesInterfaceMod, only : hlm_parteh_mode
2930
use FatesInterfaceMod, only : numpft
31+
use FatesInterfaceMod, only : nleafage
3032
use EDTypesMod, only : maxpft
3133
use EDTypesMod, only : nlevleaf
3234
use EDTypesMod, only : nclmax
35+
use EDTypesMod, only : max_nleafage
3336
use EDTypesMod, only : do_fates_salinity
3437
use PRTGenericMod, only : prt_carbon_allom_hyp
3538
use PRTGenericMod, only : prt_cnp_flex_allom_hyp
@@ -156,7 +159,7 @@ subroutine FatesPlantRespPhotosynthDrive (nsites, sites,bc_in,bc_out,dtime)
156159
real(r8) :: co2_cpoint ! CO2 compensation point (Pa)
157160
real(r8) :: btran_eff ! effective transpiration wetness factor (0 to 1)
158161
real(r8) :: bbb ! Ball-Berry minimum leaf conductance (umol H2O/m**2/s)
159-
real(r8) :: kn(maxpft) ! leaf nitrogen decay coefficient
162+
real(r8) :: kn ! leaf nitrogen decay coefficient
160163
real(r8) :: cf ! s m**2/umol -> s/m (ideal gas conversion) [umol/m3]
161164
real(r8) :: gb_mol ! leaf boundary layer conductance (molar form: [umol /m**2/s])
162165
real(r8) :: ceair ! vapor pressure of air, constrained (Pa)
@@ -202,8 +205,6 @@ subroutine FatesPlantRespPhotosynthDrive (nsites, sites,bc_in,bc_out,dtime)
202205
real(r8) :: lai_current ! the LAI in the current leaf layer
203206
real(r8) :: cumulative_lai ! the cumulative LAI, top down, to the leaf layer of interest
204207

205-
206-
207208
! -----------------------------------------------------------------------------------
208209
! Keeping these two definitions in case they need to be added later
209210
!
@@ -214,6 +215,7 @@ subroutine FatesPlantRespPhotosynthDrive (nsites, sites,bc_in,bc_out,dtime)
214215
integer :: cl,s,iv,j,ps,ft,ifp ! indices
215216
integer :: nv ! number of leaf layers
216217
integer :: NCL_p ! number of canopy layers in patch
218+
integer :: iage ! loop counter for leaf age classes
217219

218220
! Parameters
219221
! -----------------------------------------------------------------------
@@ -313,11 +315,7 @@ subroutine FatesPlantRespPhotosynthDrive (nsites, sites,bc_in,bc_out,dtime)
313315

314316
do ft = 1,numpft
315317

316-
! Bonan et al (2011) JGR, 116, doi:10.1029/2010JG001593 used
317-
! kn = 0.11. Here, derive kn from vcmax25 as in Lloyd et al
318-
! (2010) Biogeosciences, 7, 1833-1859
319318

320-
kn(ft) = decay_coeff_kn(ft)
321319

322320

323321
! This is probably unnecessary and already calculated
@@ -373,7 +371,7 @@ subroutine FatesPlantRespPhotosynthDrive (nsites, sites,bc_in,bc_out,dtime)
373371

374372
! are there any leaves of this pft in this layer?
375373
if(currentPatch%canopy_mask(cl,ft) == 1)then
376-
374+
377375
! Loop over leaf-layers
378376
do iv = 1,currentCohort%nv
379377

@@ -385,14 +383,17 @@ subroutine FatesPlantRespPhotosynthDrive (nsites, sites,bc_in,bc_out,dtime)
385383
! cohort-layer combo of interest.
386384
! but in the vanilla case, we only re-calculate if it has
387385
! not been done yet.
386+
! Other cases where we need to solve for every cohort
387+
! in every leaf layer: nutrient dynamic mode, multiple leaf
388+
! age classes
388389
! ------------------------------------------------------------
389390

390391
if ( .not.rate_mask_z(iv,ft,cl) .or. &
391392
(hlm_use_planthydro.eq.itrue) .or. &
393+
(nleafage > 1) .or. &
392394
(hlm_parteh_mode .ne. prt_carbon_allom_hyp ) ) then
393395

394-
if (hlm_use_planthydro.eq.itrue) then
395-
396+
if (hlm_use_planthydro.eq.itrue ) then
396397

397398
bbb = max (bbbopt(nint(c3psn(ft)))*currentCohort%co_hydr%btran(1), 1._r8)
398399
btran_eff = currentCohort%co_hydr%btran(1)
@@ -427,10 +428,16 @@ subroutine FatesPlantRespPhotosynthDrive (nsites, sites,bc_in,bc_out,dtime)
427428
if(do_fates_salinity)then
428429
btran_eff = btran_eff*currentPatch%bstress_sal_ft(ft)
429430
endif
430-
431431

432+
433+
! Bonan et al (2011) JGR, 116, doi:10.1029/2010JG001593 used
434+
! kn = 0.11. Here, derive kn from vcmax25 as in Lloyd et al
435+
! (2010) Biogeosciences, 7, 1833-1859
436+
437+
kn = decay_coeff_kn(ft,currentCohort%vcmax25top)
438+
432439
! Scale for leaf nitrogen profile
433-
nscaler = exp(-kn(ft) * cumulative_lai)
440+
nscaler = exp(-kn * cumulative_lai)
434441

435442
! Leaf maintenance respiration to match the base rate used in CN
436443
! but with the new temperature functions for C3 and C4 plants.
@@ -473,13 +480,15 @@ subroutine FatesPlantRespPhotosynthDrive (nsites, sites,bc_in,bc_out,dtime)
473480
! These rates are the specific rates used in the actual photosynthesis
474481
! calculations that take localized environmental effects (temperature)
475482
! into consideration.
483+
484+
476485

477486
call LeafLayerBiophysicalRates(currentPatch%ed_parsun_z(cl,ft,iv), & ! in
478487
ft, & ! in
479-
EDPftvarcon_inst%vcmax25top(ft), & ! in
480-
param_derived%jmax25top(ft), & ! in
481-
param_derived%tpu25top(ft), & ! in
482-
param_derived%kp25top(ft), & ! in
488+
currentCohort%vcmax25top, & ! in
489+
currentCohort%jmax25top, & ! in
490+
currentCohort%tpu25top, & ! in
491+
currentCohort%kp25top, & ! in
483492
nscaler, & ! in
484493
bc_in(s)%t_veg_pa(ifp), & ! in
485494
btran_eff, & ! in
@@ -1742,7 +1751,7 @@ subroutine LeafLayerBiophysicalRates( parsun_lsl, &
17421751
! for this pft (umol electrons/m**2/s)
17431752
real(r8), intent(in) :: tpu25top_ft ! canopy top triose phosphate utilization rate at 25C
17441753
! for this pft (umol CO2/m**2/s)
1745-
real(r8), intent(in) :: co2_rcurve_islope25top_ft ! initial slope of CO2 response curve
1754+
real(r8), intent(in) :: co2_rcurve_islope25top_ft ! initial slope of CO2 response curve
17461755
! (C4 plants) at 25C, canopy top, this pft
17471756
real(r8), intent(in) :: veg_tempk ! vegetation temperature
17481757
real(r8), intent(in) :: btran ! transpiration wetness factor (0 to 1)
@@ -1803,6 +1812,8 @@ subroutine LeafLayerBiophysicalRates( parsun_lsl, &
18031812
tpu = 0._r8
18041813
co2_rcurve_islope = 0._r8
18051814
else ! day time
1815+
1816+
! Vcmax25top was already calculated to derive the nscaler function
18061817
vcmax25 = vcmax25top_ft * nscaler
18071818
jmax25 = jmax25top_ft * nscaler
18081819
tpu25 = tpu25top_ft * nscaler

main/EDInitMod.F90

Lines changed: 28 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,14 @@ module EDInitMod
2121
use EDTypesMod , only : AREA
2222
use EDTypesMod , only : init_spread_near_bare_ground
2323
use EDTypesMod , only : init_spread_inventory
24+
use EDTypesMod , only : first_leaf_aclass
25+
use EDTypesMod , only : leaves_on
26+
use EDTypesMod , only : leaves_off
2427
use FatesInterfaceMod , only : bc_in_type
2528
use FatesInterfaceMod , only : hlm_use_planthydro
2629
use FatesInterfaceMod , only : hlm_use_inventory_init
2730
use FatesInterfaceMod , only : numpft
31+
use FatesInterfaceMod , only : nleafage
2832
use ChecksBalancesMod , only : SiteCarbonStock
2933
use FatesInterfaceMod , only : nlevsclass
3034
use FatesAllometryMod , only : h2d_allom
@@ -105,8 +109,8 @@ subroutine zero_site( site_in )
105109
site_in%total_burn_flux_to_atm = 0._r8
106110

107111
! PHENOLOGY
108-
site_in%status = 0 ! are leaves in this pixel on or off?
109-
site_in%dstatus = 0
112+
site_in%is_cold = .false. ! Is cold deciduous leaf-off triggered?
113+
site_in%is_drought = .false. ! Is drought deciduous leaf-off triggered?
110114
site_in%ED_GDD_site = nan ! growing degree days
111115
site_in%ncd = nan ! no chilling days
112116
site_in%last_n_days(:) = 999 ! record of last 10 days temperature for senescence model.
@@ -182,10 +186,10 @@ subroutine set_site_properties( nsites, sites)
182186
integer :: s
183187
real(r8) :: leafon
184188
real(r8) :: leafoff
185-
real(r8) :: stat
189+
logical :: stat
186190
real(r8) :: NCD
187191
real(r8) :: GDD
188-
real(r8) :: dstat
192+
logical :: dstat
189193
real(r8) :: acc_NI
190194
real(r8) :: watermem
191195
integer :: dleafoff
@@ -198,9 +202,9 @@ subroutine set_site_properties( nsites, sites)
198202
GDD = 30.0_r8
199203
leafon = 100.0_r8
200204
leafoff = 300.0_r8
201-
stat = 2
205+
stat = .false.
202206
acc_NI = 0.0_r8
203-
dstat = 2
207+
dstat = .false.
204208
dleafoff = 300
205209
dleafon = 100
206210
watermem = 0.5_r8
@@ -211,9 +215,9 @@ subroutine set_site_properties( nsites, sites)
211215
GDD = 0.0_r8
212216
leafon = 0.0_r8
213217
leafoff = 0.0_r8
214-
stat = 1
218+
stat = .false.
215219
acc_NI = 0.0_r8
216-
dstat = 2
220+
dstat = .false.
217221
dleafoff = 300
218222
dleafon = 100
219223
watermem = 0.5_r8
@@ -232,9 +236,8 @@ subroutine set_site_properties( nsites, sites)
232236
sites(s)%water_memory(1:numWaterMem) = watermem
233237
end if
234238

235-
sites(s)%status = stat
236-
!start off with leaves off to initialise
237-
sites(s)%dstatus= dstat
239+
sites(s)%is_cold = stat
240+
sites(s)%is_drought = dstat
238241

239242
sites(s)%acc_NI = acc_NI
240243
sites(s)%frac_burnt = 0.0_r8
@@ -432,37 +435,27 @@ subroutine init_cohorts( site_in, patch_in, bc_in)
432435

433436
call bstore_allom(temp_cohort%dbh, pft, temp_cohort%canopy_trim, b_store)
434437

435-
436-
if( EDPftvarcon_inst%evergreen(pft) == 1) then
437-
temp_cohort%laimemory = 0._r8
438-
cstatus = 2
439-
endif
440-
441-
if( EDPftvarcon_inst%season_decid(pft) == 1 ) then !for dorment places
442-
if(site_in%status == 2)then
443-
temp_cohort%laimemory = 0.0_r8
444-
else
445-
temp_cohort%laimemory = b_leaf
446-
endif
447-
! reduce biomass according to size of store, this will be recovered when elaves com on.
448-
cstatus = site_in%status
438+
temp_cohort%laimemory = 0._r8
439+
cstatus = leaves_on
440+
441+
if( EDPftvarcon_inst%season_decid(pft) == itrue .and. site_in%is_cold ) then
442+
temp_cohort%laimemory = b_leaf
443+
b_leaf = 0._r8
444+
cstatus = leaves_off
449445
endif
450-
451-
if ( EDPftvarcon_inst%stress_decid(pft) == 1 ) then
452-
if(site_in%dstatus == 2)then
453-
temp_cohort%laimemory = 0.0_r8
454-
else
455-
temp_cohort%laimemory = b_leaf
456-
endif
457-
cstatus = site_in%dstatus
446+
447+
if ( EDPftvarcon_inst%stress_decid(pft) == itrue .and. site_in%is_drought ) then
448+
temp_cohort%laimemory = b_leaf
449+
b_leaf = 0._r8
450+
cstatus = leaves_off
458451
endif
459452

460453
if ( debug ) write(fates_log(),*) 'EDInitMod.F90 call create_cohort '
461454

462455
call create_cohort(site_in, patch_in, pft, temp_cohort%n, temp_cohort%hite, temp_cohort%dbh, &
463456
b_leaf, b_fineroot, b_sapwood, b_dead, b_store, &
464-
temp_cohort%laimemory, cstatus, rstatus, temp_cohort%canopy_trim, 1, site_in%spread, bc_in)
465-
457+
temp_cohort%laimemory, cstatus, rstatus, temp_cohort%canopy_trim, 1, &
458+
site_in%spread, first_leaf_aclass, bc_in)
466459

467460
deallocate(temp_cohort) ! get rid of temporary cohort
468461

0 commit comments

Comments
 (0)