@@ -20,6 +20,7 @@ module EDPhysiologyMod
2020 use EDCohortDynamicsMod , only : create_cohort, sort_cohorts
2121 use FatesAllometryMod , only : tree_lai
2222 use FatesAllometryMod , only : tree_sai
23+ use FatesAllometryMod , only : decay_coeff_kn
2324
2425 use EDTypesMod , only : numWaterMem
2526 use EDTypesMod , only : dl_sf, dinc_ed
@@ -162,40 +163,59 @@ subroutine trim_canopy( currentSite )
162163 ! Canopy trimming / leaf optimisation. Removes leaves in negative annual carbon balance.
163164 !
164165 ! !USES:
165- !
166- !
166+
167167 ! !ARGUMENTS
168168 type (ed_site_type),intent (inout ), target :: currentSite
169169 !
170170 ! !LOCAL VARIABLES:
171171 type (ed_cohort_type) , pointer :: currentCohort
172172 type (ed_patch_type) , pointer :: currentPatch
173173
174- integer :: z ! leaf layer
175- integer :: ipft ! pft index
176- integer :: trimmed ! was this layer trimmed in this year? If not expand the canopy.
177- real (r8 ) :: tar_bl ! target leaf biomass (leaves flushed, trimmed)
178- real (r8 ) :: tar_bfr ! target fine-root biomass (leaves flushed, trimmed)
179- real (r8 ) :: bfr_per_bleaf ! ratio of fine root per leaf biomass
174+ integer :: z ! leaf layer
175+ integer :: ipft ! pft index
176+ logical :: trimmed ! was this layer trimmed in this year? If not expand the canopy.
177+ real (r8 ) :: tar_bl ! target leaf biomass (leaves flushed, trimmed)
178+ real (r8 ) :: tar_bfr ! target fine-root biomass (leaves flushed, trimmed)
179+ real (r8 ) :: bfr_per_bleaf ! ratio of fine root per leaf biomass
180+ real (r8 ) :: sla_levleaf ! sla at leaf level z
181+ real (r8 ) :: nscaler_levleaf ! nscaler value at leaf level z
182+ integer :: cl ! canopy layer index
183+ real (r8 ) :: kn ! nitrogen decay coefficient
184+ real (r8 ) :: sla_max ! Observational constraint on how large sla (m2/gC) can become
185+
186+ real (r8 ) :: leaf_inc ! LAI-only portion of the vegetation increment of dinc_ed
187+ real (r8 ) :: lai_canopy_above ! the LAI in the canopy layers above the layer of interest
188+ real (r8 ) :: lai_layers_above ! the LAI in the leaf layers, within the current canopy,
189+ ! above the leaf layer of interest
190+ real (r8 ) :: lai_current ! the LAI in the current leaf layer
191+ real (r8 ) :: cumulative_lai ! the cumulative LAI, top down, to the leaf layer of interest
180192
181193 !- ---------------------------------------------------------------------
182194
183195 currentPatch = > currentSite% youngest_patch
184-
185196 do while (associated (currentPatch))
197+
186198 currentCohort = > currentPatch% tallest
187199 do while (associated (currentCohort))
188- trimmed = 0
200+
201+ trimmed = .false.
189202 ipft = currentCohort% pft
190203 call carea_allom(currentCohort% dbh,currentCohort% n,currentSite% spread,currentCohort% pft,currentCohort% c_area)
191- currentCohort% treelai = tree_lai(currentCohort% bl, currentCohort% status_coh, currentCohort% pft, &
192- currentCohort% c_area, currentCohort% n )
193- currentCohort% treesai = tree_sai(currentCohort% dbh, currentCohort% pft, currentCohort% canopy_trim, &
194- currentCohort% c_area, currentCohort% n)
195- currentCohort% nv = ceiling ((currentCohort% treelai+ currentCohort% treesai)/ dinc_ed)
204+ currentCohort% treelai = tree_lai(currentCohort% bl, currentCohort% pft, currentCohort% c_area, &
205+ currentCohort% n, currentCohort% canopy_layer, &
206+ currentPatch% canopy_layer_tlai )
207+
208+ currentCohort% treesai = tree_sai(currentCohort% pft, currentCohort% dbh, currentCohort% canopy_trim, &
209+ currentCohort% c_area, currentCohort% n, currentCohort% canopy_layer, &
210+ currentPatch% canopy_layer_tlai, currentCohort% treelai )
211+
212+ currentCohort% nv = ceiling ((currentCohort% treelai+ currentCohort% treesai)/ dinc_ed)
213+
196214 if (currentCohort% nv > nlevleaf)then
197- write (fates_log(),* ) ' nv > nlevleaf' ,currentCohort% nv,currentCohort% treelai,currentCohort% treesai, &
198- currentCohort% c_area,currentCohort% n,currentCohort% bl
215+ write (fates_log(),* ) ' nv > nlevleaf' ,currentCohort% nv, &
216+ currentCohort% treelai,currentCohort% treesai, &
217+ currentCohort% c_area,currentCohort% n,currentCohort% bl
218+ call endrun(msg= errMsg(sourcefile, __LINE__))
199219 endif
200220
201221 call bleaf(currentcohort% dbh,ipft,currentcohort% canopy_trim,tar_bl)
@@ -206,35 +226,68 @@ subroutine trim_canopy( currentSite )
206226 bfr_per_bleaf = tar_bfr/ tar_bl
207227 endif
208228
229+ ! Identify current canopy layer (cl)
230+ cl = currentCohort% canopy_layer
231+
232+ ! PFT-level maximum SLA value, even if under a thick canopy (same units as slatop)
233+ sla_max = EDPftvarcon_inst% slamax(ipft)
234+
209235 ! Leaf cost vs netuptake for each leaf layer.
210- do z = 1 ,nlevleaf
211- if (currentCohort% year_net_uptake(z) /= 999._r8 )then ! there was activity this year in this leaf layer.
236+ do z = 1 , currentCohort% nv
237+
238+ ! Calculate the cumulative total vegetation area index (no snow occlusion, stems and leaves)
239+
240+ leaf_inc = dinc_ed * &
241+ currentCohort% treelai/ (currentCohort% treelai+ currentCohort% treesai)
242+
243+ ! Now calculate the cumulative top-down lai of the current layer's midpoint
244+ lai_canopy_above = sum (currentPatch% canopy_layer_tlai(1 :cl-1 ))
245+ lai_layers_above = leaf_inc * (z-1 )
246+ lai_current = min (leaf_inc, currentCohort% treelai - lai_layers_above)
247+ cumulative_lai = lai_canopy_above + lai_layers_above + 0.5 * lai_current
248+
249+ if (currentCohort% year_net_uptake(z) /= 999._r8 )then ! there was activity this year in this leaf layer.
250+
251+
252+ ! Calculate sla_levleaf following the sla profile with overlying leaf area
253+ ! Scale for leaf nitrogen profile
254+ kn = decay_coeff_kn(ipft)
255+ ! Nscaler value at leaf level z
256+ nscaler_levleaf = exp (- kn * cumulative_lai)
257+ ! Sla value at leaf level z after nitrogen profile scaling (m2/gC)
258+ sla_levleaf = EDPftvarcon_inst% slatop(ipft)/ nscaler_levleaf
259+
260+ if (sla_levleaf > sla_max)then
261+ sla_levleaf = sla_max
262+ end if
263+
212264 ! Leaf Cost kgC/m2/year-1
213265 ! decidous costs.
214266 if (EDPftvarcon_inst% season_decid(ipft) == 1.or . &
215267 EDPftvarcon_inst% stress_decid(ipft) == 1 )then
216268
217-
218- currentCohort% leaf_cost = 1._r8 / (EDPftvarcon_inst % slatop(ipft) * 1000.0_r8 )
269+ ! Leaf cost at leaf level z accounting for sla profile (kgC/m2)
270+ currentCohort% leaf_cost = 1._r8 / (sla_levleaf * 1000.0_r8 )
219271
220272 if ( int (EDPftvarcon_inst% allom_fmode(ipft)) .eq. 1 ) then
221273 ! if using trimmed leaf for fine root biomass allometry, add the cost of the root increment
222274 ! to the leaf increment; otherwise do not.
223275 currentCohort% leaf_cost = currentCohort% leaf_cost + &
224- 1.0_r8 / (EDPftvarcon_inst % slatop(ipft) * 1000.0_r8 ) * &
276+ 1.0_r8 / (sla_levleaf * 1000.0_r8 ) * &
225277 bfr_per_bleaf / EDPftvarcon_inst% root_long(ipft)
226278 endif
227279
228280 currentCohort% leaf_cost = currentCohort% leaf_cost * &
229281 (EDPftvarcon_inst% grperc(ipft) + 1._r8 )
230282 else ! evergreen costs
231- currentCohort% leaf_cost = 1.0_r8 / (EDPftvarcon_inst% slatop(ipft)* &
283+ ! Leaf cost at leaf level z accounting for sla profile
284+ currentCohort% leaf_cost = 1.0_r8 / (sla_levleaf* &
232285 EDPftvarcon_inst% leaf_long(ipft)* 1000.0_r8 ) ! convert from sla in m2g-1 to m2kg-1
233286 if ( int (EDPftvarcon_inst% allom_fmode(ipft)) .eq. 1 ) then
234287 ! if using trimmed leaf for fine root biomass allometry, add the cost of the root increment
235288 ! to the leaf increment; otherwise do not.
236289 currentCohort% leaf_cost = currentCohort% leaf_cost + &
237- 1.0_r8 / (EDPftvarcon_inst % slatop(ipft) * 1000.0_r8 ) * &
290+ 1.0_r8 / (sla_levleaf * 1000.0_r8 ) * &
238291 bfr_per_bleaf / EDPftvarcon_inst% root_long(ipft)
239292 endif
240293 currentCohort% leaf_cost = currentCohort% leaf_cost * &
@@ -256,15 +309,15 @@ subroutine trim_canopy( currentSite )
256309 currentCohort% laimemory = currentCohort% laimemory * &
257310 (1.0_r8 - EDPftvarcon_inst% trim_inc(ipft))
258311 endif
259- trimmed = 1
312+ trimmed = .true.
260313 endif
261314 endif
262315 endif
263316 endif ! leaf activity?
264317 enddo ! z
265318
266319 currentCohort% year_net_uptake(:) = 999.0_r8
267- if (trimmed == 0 .and .currentCohort% canopy_trim < 1.0_r8 )then
320+ if ( ( .not. trimmed) .and. currentCohort% canopy_trim < 1.0_r8 )then
268321 currentCohort% canopy_trim = currentCohort% canopy_trim + EDPftvarcon_inst% trim_inc(ipft)
269322 endif
270323
@@ -2416,4 +2469,9 @@ subroutine flux_into_litter_pools(nsites, sites, bc_in, bc_out)
24162469
24172470 end subroutine flux_into_litter_pools
24182471
2472+ ! ===================================================================================
2473+
2474+
2475+
2476+
24192477end module EDPhysiologyMod
0 commit comments