Skip to content

Commit 1dfca6b

Browse files
authored
Merge pull request #341 from ckoven/reduce_respiration
Reduce respiration when carbon storage is low
2 parents 9ae322a + 662573f commit 1dfca6b

File tree

4 files changed

+93
-12
lines changed

4 files changed

+93
-12
lines changed

biogeochem/EDMortalityFunctionsMod.F90

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ module EDMortalityFunctionsMod
1212
use EDTypesMod , only : ed_patch_type
1313
use FatesConstantsMod , only : itrue,ifalse
1414
use FatesAllometryMod , only : bleaf
15+
use FatesAllometryMod , only : storage_fraction_of_target
1516
use FatesInterfaceMod , only : bc_in_type
1617
use FatesInterfaceMod , only : hlm_use_ed_prescribed_phys
1718
use FatesInterfaceMod , only : hlm_freq_day
@@ -57,7 +58,7 @@ subroutine mortality_rates( cohort_in,bc_in,cmort,hmort,bmort,frmort )
5758
real(r8),intent(out) :: frmort ! freezing stress mortality
5859

5960
real(r8) :: frac ! relativised stored carbohydrate
60-
real(r8) :: b_leaf ! leaf biomass kgC
61+
real(r8) :: b_leaf ! target leaf biomass kgC
6162
real(r8) :: hf_sm_threshold ! hydraulic failure soil moisture threshold
6263
real(r8) :: temp_dep ! Temp. function (freezing mortality)
6364
real(r8) :: temp_in_C ! Daily averaged temperature in Celcius
@@ -85,11 +86,11 @@ subroutine mortality_rates( cohort_in,bc_in,cmort,hmort,bmort,frmort )
8586
! Carbon Starvation induced mortality.
8687
if ( cohort_in%dbh > 0._r8 ) then
8788
call bleaf(cohort_in%dbh,cohort_in%pft,cohort_in%canopy_trim,b_leaf)
88-
if( b_leaf > 0._r8 .and. cohort_in%bstore <= b_leaf )then
89-
frac = cohort_in%bstore/ b_leaf
89+
call storage_fraction_of_target(b_leaf, cohort_in%bstore, frac)
90+
if( frac .lt. 1._r8) then
9091
cmort = max(0.0_r8,EDPftvarcon_inst%mort_scalar_cstarvation(cohort_in%pft) * &
9192
(1.0_r8 - frac))
92-
else
93+
else
9394
cmort = 0.0_r8
9495
endif
9596

biogeochem/FatesAllometryMod.F90

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ module FatesAllometryMod
102102
public :: bagw_allom ! Generic AGWB (above grnd. woody bio) wrapper
103103
public :: blmax_allom ! Generic maximum leaf biomass wrapper
104104
public :: bleaf ! Generic actual leaf biomass wrapper
105+
public :: storage_fraction_of_target ! storage as fraction of leaf biomass
105106
public :: tree_lai ! Calculate tree-level LAI from actual leaf biomass
106107
public :: tree_sai ! Calculate tree-level SAI from target leaf biomass
107108
public :: bsap_allom ! Generic sapwood wrapper
@@ -458,9 +459,7 @@ subroutine carea_allom(d,nplant,site_spread,ipft,c_area)
458459

459460
end associate
460461
return
461-
end subroutine carea_allom
462-
463-
462+
end subroutine carea_allom
464463

465464
! =====================================================================================
466465

@@ -500,6 +499,27 @@ subroutine bleaf(d,ipft,canopy_trim,bl,dbldd)
500499
return
501500
end subroutine bleaf
502501

502+
! =====================================================================================
503+
504+
subroutine storage_fraction_of_target(b_leaf, bstore, frac)
505+
506+
!--------------------------------------------------------------------------------
507+
! returns the storage pool as a fraction of its target (only if it is below its target)
508+
! used in both the carbon starvation mortlaity scheme as wella s the optional respiration throttling logic
509+
!--------------------------------------------------------------------------------
510+
511+
real(r8),intent(in) :: b_leaf
512+
real(r8),intent(in) :: bstore
513+
real(r8),intent(out) :: frac
514+
515+
if( b_leaf > 0._r8 .and. bstore <= b_leaf )then
516+
frac = bstore/ b_leaf
517+
else
518+
frac = 1._r8
519+
endif
520+
521+
end subroutine storage_fraction_of_target
522+
503523
! =====================================================================================
504524

505525
real(r8) function tree_lai( bl, status_coh, pft, c_area, n )

biogeophys/FatesPlantRespPhotosynthMod.F90

Lines changed: 64 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ subroutine FatesPlantRespPhotosynthDrive (nsites, sites,bc_in,bc_out,dtime)
8282
use FatesParameterDerivedMod, only : param_derived
8383
use EDPatchDynamicsMod, only: set_root_fraction
8484
use EDParamsMod, only : ED_val_bbopt_c3, ED_val_bbopt_c4, ED_val_base_mr_20
85+
use FatesAllometryMod, only : bleaf, storage_fraction_of_target
8586

8687

8788
! ARGUMENTS:
@@ -159,6 +160,9 @@ subroutine FatesPlantRespPhotosynthDrive (nsites, sites,bc_in,bc_out,dtime)
159160
! nitrogen content (kgN/plant)
160161
real(r8) :: froot_n ! Fine root nitrogen content (kgN/plant)
161162
real(r8) :: gccanopy_pa ! Patch level canopy stomatal conductance [mmol m-2 s-1]
163+
real(r8) :: maintresp_reduction_factor ! factor by which to reduce maintenance respiration when storage pools are low
164+
real(r8) :: b_leaf ! leaf biomass kgC
165+
real(r8) :: frac ! storage pool as a fraction of target leaf biomass
162166

163167
! -----------------------------------------------------------------------------------
164168
! Keeping these two definitions in case they need to be added later
@@ -320,6 +324,10 @@ subroutine FatesPlantRespPhotosynthDrive (nsites, sites,bc_in,bc_out,dtime)
320324
ft = currentCohort%pft
321325
cl = currentCohort%canopy_layer
322326

327+
call bleaf(currentCohort%dbh,currentCohort%pft,currentCohort%canopy_trim,b_leaf)
328+
call storage_fraction_of_target(b_leaf, currentCohort%bstore, frac)
329+
call lowstorage_maintresp_reduction(frac,currentCohort%pft, &
330+
maintresp_reduction_factor)
323331

324332
! are there any leaves of this pft in this layer?
325333
if(currentPatch%canopy_mask(cl,ft) == 1)then
@@ -468,6 +476,7 @@ subroutine FatesPlantRespPhotosynthDrive (nsites, sites,bc_in,bc_out,dtime)
468476
currentCohort%treelai, & !in
469477
currentCohort%treesai, & !in
470478
bc_in(s)%rb_pa(ifp), & !in
479+
maintresp_reduction_factor, & !in
471480
currentCohort%gscan, & !out
472481
currentCohort%gpp_tstep, & !out
473482
currentCohort%rdark) !out
@@ -521,7 +530,7 @@ subroutine FatesPlantRespPhotosynthDrive (nsites, sites,bc_in,bc_out,dtime)
521530
if (woody(ft) == 1) then
522531
tcwood = q10**((bc_in(s)%t_veg_pa(ifp)-tfrz - 20.0_r8)/10.0_r8)
523532
! kgC/s = kgN * kgC/kgN/s
524-
currentCohort%livestem_mr = live_stem_n * ED_val_base_mr_20 * tcwood
533+
currentCohort%livestem_mr = live_stem_n * ED_val_base_mr_20 * tcwood * maintresp_reduction_factor
525534
else
526535
currentCohort%livestem_mr = 0._r8
527536
end if
@@ -533,7 +542,7 @@ subroutine FatesPlantRespPhotosynthDrive (nsites, sites,bc_in,bc_out,dtime)
533542
do j = 1,hlm_numlevsoil
534543
tcsoi = q10**((bc_in(s)%t_soisno_gl(j)-tfrz - 20.0_r8)/10.0_r8)
535544
currentCohort%froot_mr = currentCohort%froot_mr + &
536-
froot_n * ED_val_base_mr_20 * tcsoi * currentPatch%rootfr_ft(ft,j)
545+
froot_n * ED_val_base_mr_20 * tcsoi * currentPatch%rootfr_ft(ft,j) * maintresp_reduction_factor
537546
enddo
538547

539548
! Coarse Root MR (kgC/plant/s) (below ground sapwood)
@@ -545,7 +554,7 @@ subroutine FatesPlantRespPhotosynthDrive (nsites, sites,bc_in,bc_out,dtime)
545554
tcsoi = q10**((bc_in(s)%t_soisno_gl(j)-tfrz - 20.0_r8)/10.0_r8)
546555
currentCohort%livecroot_mr = currentCohort%livecroot_mr + &
547556
live_croot_n * ED_val_base_mr_20 * tcsoi * &
548-
currentPatch%rootfr_ft(ft,j)
557+
currentPatch%rootfr_ft(ft,j) * maintresp_reduction_factor
549558
enddo
550559
else
551560
currentCohort%livecroot_mr = 0._r8
@@ -1016,6 +1025,7 @@ subroutine ScaleLeafLayerFluxToCohort(nv, & ! in currentCohort%nv
10161025
treelai, & ! in currentCohort%treelai
10171026
treesai, & ! in currentCohort%treesai
10181027
rb, & ! in bc_in(s)%rb_pa(ifp)
1028+
maintresp_reduction_factor, & ! in
10191029
gscan, & ! out currentCohort%gscan
10201030
gpp, & ! out currentCohort%gpp_tstep
10211031
rdark) ! out currentCohort%rdark
@@ -1043,7 +1053,7 @@ subroutine ScaleLeafLayerFluxToCohort(nv, & ! in currentCohort%nv
10431053
real(r8), intent(in) :: treelai ! m2/m2
10441054
real(r8), intent(in) :: treesai ! m2/m2
10451055
real(r8), intent(in) :: rb ! boundary layer resistance (s/m)
1046-
1056+
real(r8), intent(in) :: maintresp_reduction_factor ! factor by which to reduce maintenance respiration
10471057
real(r8), intent(out) :: gscan ! Canopy conductance of the cohort m/s
10481058
real(r8), intent(out) :: gpp ! GPP (kgC/indiv/s)
10491059
real(r8), intent(out) :: rdark ! Dark Leaf Respiration (kgC/indiv/s)
@@ -1078,6 +1088,8 @@ subroutine ScaleLeafLayerFluxToCohort(nv, & ! in currentCohort%nv
10781088
rdark = rdark + sum(lmr_llz(1:nv-1) * elai_llz(1:nv-1)) * tree_area
10791089
gscan = gscan + sum((1.0_r8/(rs_llz(1:nv-1) + rb ))) * tree_area
10801090
end if
1091+
1092+
rdark = rdark * maintresp_reduction_factor
10811093

10821094
! Convert dark respiration and GPP from umol/plant/s to kgC/plant/s
10831095

@@ -1631,4 +1643,52 @@ subroutine LeafLayerBiophysicalRates( parsun_lsl, &
16311643
return
16321644
end subroutine LeafLayerBiophysicalRates
16331645

1646+
subroutine lowstorage_maintresp_reduction(frac, pft, maintresp_reduction_factor)
1647+
1648+
! This subroutine reduces maintenance respiration rates when storage pool is low. The premise
1649+
! of this is that mortality of plants increases when storage is low because they are not able
1650+
! to repair tissues, generate defense compounds, etc. This reduction is reflected in a reduced
1651+
! maintenance demand. The output of this function takes the form of a curve between 0 and 1,
1652+
! and the curvature of the function is determined by a parameter.
1653+
1654+
! Uses
1655+
use EDPftvarcon , only : EDPftvarcon_inst
1656+
1657+
! Arguments
1658+
! ------------------------------------------------------------------------------
1659+
real(r8), intent(in) :: frac ! ratio of storage to target leaf biomass
1660+
integer, intent(in) :: pft ! what pft is this cohort?
1661+
real(r8), intent(out) :: maintresp_reduction_factor ! the factor by which to reduce maintenance respiration
1662+
1663+
! --------------------------------------------------------------------------------
1664+
! Parameters are at the PFT level:
1665+
! fates_maintresp_reduction_curvature controls the curvature of this.
1666+
! If this parameter is zero, then there is no reduction until the plant dies at storage = 0.
1667+
! If this parameter is one, then there is a linear reduction in respiration below the storage point.
1668+
! Intermediate values will give some (concave-downwards) curvature.
1669+
!
1670+
! maintresp_reduction_intercept controls the maximum amount of throttling.
1671+
! zero means no throttling at any point, so it turns this mechanism off completely and so
1672+
! allows an entire cohort to die via negative carbon-induced termination mortality.
1673+
! one means complete throttling, so no maintenance respiration at all, when out of carbon.
1674+
! ---------------------------------------------------------------------------------
1675+
1676+
if( frac .lt. 1._r8 )then
1677+
if ( EDPftvarcon_inst%maintresp_reduction_curvature(pft) .ne. 1._r8 ) then
1678+
maintresp_reduction_factor = (1._r8 - EDPftvarcon_inst%maintresp_reduction_intercept(pft)) + &
1679+
EDPftvarcon_inst%maintresp_reduction_intercept(pft) * &
1680+
(1._r8 - EDPftvarcon_inst%maintresp_reduction_curvature(pft)**frac) &
1681+
/ (1._r8-EDPftvarcon_inst%maintresp_reduction_curvature(pft))
1682+
else ! avoid nan answer for linear case
1683+
maintresp_reduction_factor = (1._r8 - EDPftvarcon_inst%maintresp_reduction_intercept(pft)) + &
1684+
EDPftvarcon_inst%maintresp_reduction_intercept(pft) * frac
1685+
endif
1686+
1687+
else
1688+
maintresp_reduction_factor = 1._r8
1689+
endif
1690+
1691+
1692+
end subroutine lowstorage_maintresp_reduction
1693+
16341694
end module FATESPlantRespPhotosynthMod

main/EDPftvarcon.F90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ module EDPftvarcon
175175
real(r8), allocatable :: hydr_fcap_node(:,:) ! fraction of (1-resid_node) that is capillary in source
176176
real(r8), allocatable :: hydr_pinot_node(:,:) ! osmotic potential at full turgor
177177
real(r8), allocatable :: hydr_kmax_node(:,:) ! maximum xylem conductivity per unit conducting xylem area
178-
178+
179179
contains
180180
procedure, public :: Init => EDpftconInit
181181
procedure, public :: Register

0 commit comments

Comments
 (0)