Skip to content

Commit

Permalink
Merge pull request #120 from noaa-oar-arl/iso_loss
Browse files Browse the repository at this point in the history
Canopy loss factor.
  • Loading branch information
drnimbusrain authored Mar 19, 2024
2 parents 072f619 + d0cb84b commit 019958e
Show file tree
Hide file tree
Showing 10 changed files with 232 additions and 121 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,10 @@ You can also [generate global inputs using Python (see python/global_data_proces
| `ifcanbio` | logical canopy biogenic emissions option (default: `.FALSE.`) |
| `bio_cce` | user-set real value of MEGAN biogenic emissions "canopy environment coefficient" used to tune emissions to model inputs/calculations (default: `0.21`, based on Silva et al. 2020) |
| `biovert_opt` | user set biogenic vertical summing option (`0`: no sum, full leaf-level biogenic emissions, units=kg/m3/s; `1`: MEGANv3-like summing of LAD weighted activity coefficients using the canopy-app plant distributions, caution-- units=kg m-2 s-1 and puts the total emissions in the topmost canopy-app model layer only; `2`: Same as in option 1, but instead uses Gaussian/normally weighted activity coefficients acoss all sub-canopy layers -- also units of kg m-2 s-1 in topmost model layer; `3`: Same as in option 1, but instead uses evenly weighted activity coefficients acoss all sub-canopy layers -- also units of kg m-2 s-1 in topmost model layer |
| `loss_opt` | user set option to apply a canopy loss factor when the vertical summing option is used (`biovert_opt >= 1`) to facilitate comparison of top-of-canopy BVOC emissions with ground flux observations. (`0`: no loss factor applied, `1`: loss factor calculated based on Eq. 21 of [Guenther et al. (2006)](www.atmos-chem-phys.net/6/3181/2006/) based on the formulation and empirical parameters for isoprene, `2`: constant user set factor applied with `loss_set` below, Note: The loss factor can be applied to all or any single biogenic species (using `loss_ind` below), and caution must be used for other BVOC species besides isoprene. User may adjust the variable chemical lifetime (`lifetime`, default = 3600 s taken for approximate isoprene lifetime) below and re-run to target other specific BVOC species flux observation comparisons. |
| `loss_set` | Set default value for constant canopy loss factor applied used when `loss_opt=2` (Default = 0.96 based on Guenther et al. (2006) |
| `loss_ind` | Set default integer for applying canopy loss factor to all species (=0) or only specific biogenics species specific indice (> 0) based on Table 1 above (e.g., 1 = Isoprene, 2 = Myrcene, etc.) |
| `lifetime` | user-set real value of chemical lifetime (in seconds) used when `loss_opt=1`. Default = 3600 s based on approximate above canopy isoprene lifeftime of 1 hour. |
| `co2_opt` | user-set options for applying a CO2 inhibition factor for biogenic isoprene-only emissions using either the [Possell & Hewitt (2011)](https://doi.org/10.1111/j.1365-2486.2010.02306.x) (= `0`, default) or [Wilkinson et al. (2009)](https://doi.org/10.1111/j.1365-2486.2008.01803.x) method (= `1`). Use of option = `1` (Possell & Hewitt 2011) is especially recommended for sub-ambient CO2 concentrations. To turn off co2 inhibition factor set `co2_opt=2` |
| `co2_set` | user-set real value of atmospheric co2 concentration (ppmv) (only used if `co2_opt=0` or `co2_opt=1`) |
| `leafage_opt` | user-set options for applying leaf-age response to biogenic VOC emissions based on [Guenther et al. 2006](https://doi.org/10.5194/acp-6-3181-2006) (default is off i.e., `leafage_opt=1`, the corresponding $\gamma$ is set to 1). If turned on (`leafage_opt=0`), leafage $\gamma$ is calculated and the lai_tstep option needs to be set to ensure correct interpolation in this leafage_opt calculation. |
Expand Down
4 changes: 4 additions & 0 deletions input/namelist.canopy
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@
ifcanbio = .TRUE.
bio_cce = 0.21
biovert_opt = 0
loss_opt = 0
loss_set = 0.96
loss_ind = 0
lifetime = 3600.0
co2_opt = 0
co2_set = 400.0
lai_tstep = 86400
Expand Down
20 changes: 10 additions & 10 deletions src/canopy_alloc.F90
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,16 @@ SUBROUTINE canopy_alloc
if(.not.allocated(lad)) allocate(lad(nlat*nlon,modlays))
if(.not.allocated(lad_3d)) allocate(lad_3d(nlon,nlat,modlays))

if(.not.allocated(tleaf_sun24_tmp)) allocate(tleaf_sun24_tmp(nlat*nlon,modlays))
if(.not.allocated(tleaf_shade24_tmp)) allocate(tleaf_shade24_tmp(nlat*nlon,modlays))
if(.not.allocated(tleaf_ave24_tmp)) allocate(tleaf_ave24_tmp(nlat*nlon,modlays))
if(.not.allocated(ppfd_sun24_tmp)) allocate(ppfd_sun24_tmp(nlat*nlon,modlays))
if(.not.allocated(ppfd_shade24_tmp)) allocate(ppfd_shade24_tmp(nlat*nlon,modlays))
if(.not.allocated(tleaf_sun240_tmp)) allocate(tleaf_sun240_tmp(nlat*nlon,modlays))
if(.not.allocated(tleaf_shade240_tmp)) allocate(tleaf_shade240_tmp(nlat*nlon,modlays))
if(.not.allocated(tleaf_ave240_tmp)) allocate(tleaf_ave240_tmp(nlat*nlon,modlays))
if(.not.allocated(ppfd_sun240_tmp)) allocate(ppfd_sun240_tmp(nlat*nlon,modlays))
if(.not.allocated(ppfd_shade240_tmp)) allocate(ppfd_shade240_tmp(nlat*nlon,modlays))
if(.not.allocated(tleaf_sun24_tmp)) allocate(tleaf_sun24_tmp(ntime,nlat*nlon,modlays))
if(.not.allocated(tleaf_shade24_tmp)) allocate(tleaf_shade24_tmp(ntime,nlat*nlon,modlays))
if(.not.allocated(tleaf_ave24_tmp)) allocate(tleaf_ave24_tmp(ntime,nlat*nlon,modlays))
if(.not.allocated(ppfd_sun24_tmp)) allocate(ppfd_sun24_tmp(ntime,nlat*nlon,modlays))
if(.not.allocated(ppfd_shade24_tmp)) allocate(ppfd_shade24_tmp(ntime,nlat*nlon,modlays))
if(.not.allocated(tleaf_sun240_tmp)) allocate(tleaf_sun240_tmp(ntime,nlat*nlon,modlays))
if(.not.allocated(tleaf_shade240_tmp)) allocate(tleaf_shade240_tmp(ntime,nlat*nlon,modlays))
if(.not.allocated(tleaf_ave240_tmp)) allocate(tleaf_ave240_tmp(ntime,nlat*nlon,modlays))
if(.not.allocated(ppfd_sun240_tmp)) allocate(ppfd_sun240_tmp(ntime,nlat*nlon,modlays))
if(.not.allocated(ppfd_shade240_tmp)) allocate(ppfd_shade240_tmp(ntime,nlat*nlon,modlays))
if(.not.allocated(tleaf_sun24)) allocate(tleaf_sun24(nlat*nlon,modlays))
if(.not.allocated(tleaf_shade24)) allocate(tleaf_shade24(nlat*nlon,modlays))
if(.not.allocated(tleaf_ave24)) allocate(tleaf_ave24(nlat*nlon,modlays))
Expand Down
40 changes: 35 additions & 5 deletions src/canopy_bioemi_mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ SUBROUTINE CANOPY_BIO( ZK, FCLAI, FCH, LAI, FSUN, &
TLEAF240_AVE, TEMP2, LU_OPT, &
VTYPE, MODRES, CCE, VERT, CO2OPT, CO2SET, &
LEAFAGEOPT, PASTLAI, CURRENTLAI, TSTEPLAI, &
LOSSOPT, LOSSSET, LOSSIND, LIFETIME, USTAR, &
SOIMOPT, SOIM1, SOIM2, SOIM3, SOIM4, SOID1, SOID2, SOID3, &
SOID4, WILT, &
MODLAYS, EMI_IND, EMI_OUT)
Expand Down Expand Up @@ -46,7 +47,7 @@ SUBROUTINE CANOPY_BIO( ZK, FCLAI, FCH, LAI, FSUN, &
use canopy_const_mod, ONLY: rk,rgasuniv !constants for canopy models
use canopy_utils_mod, ONLY: interp_linear1_internal, &
GET_GAMMA_CO2,GET_GAMMA_LEAFAGE, &
GET_GAMMA_SOIM
GET_GAMMA_SOIM, GET_CANLOSS_BIO
use canopy_bioparm_mod
use canopy_tleaf_mod

Expand Down Expand Up @@ -94,6 +95,12 @@ SUBROUTINE CANOPY_BIO( ZK, FCLAI, FCH, LAI, FSUN, &
REAL(RK), INTENT( IN ) :: TSTEPLAI !Number of days between the past and current LAI

INTEGER, INTENT( IN ) :: MODLAYS ! Input total model layers
INTEGER, INTENT( IN ) :: LOSSOPT ! Option for canopy loss factor when summing top of canopy emissions
REAL(RK), INTENT( IN ) :: LIFETIME ! Above canopy chemical lifetime of VOC (s)
REAL(RK), INTENT( IN ) :: LOSSSET ! Input value for constant canopy loss factor applied used with loss_opt=2 (Default = 0.96)
INTEGER, INTENT( IN ) :: LOSSIND ! Input integer for applying canopy loss factor to all species (=0) or only specific biogenics specie indices (> 0)

REAL(RK), INTENT( IN ) :: USTAR ! Above canopy friction velocity (m/s)
INTEGER, INTENT( IN ) :: EMI_IND ! Input biogenic emissions index
REAL(RK), INTENT( OUT ) :: EMI_OUT(:) ! Output canopy layer volume emissions (kg m-3 s-1)

Expand Down Expand Up @@ -138,7 +145,7 @@ SUBROUTINE CANOPY_BIO( ZK, FCLAI, FCH, LAI, FSUN, &
REAL(RK) :: GAMMACO2 ! CO2 inhibition factor (isoprene only)

REAL(RK) :: GAMMALEAFAGE !(SIZE(ZK)) ! LEAF AGE factor

REAL(RK) :: CANLOSS_FAC !Canopy loss factor for summing option
integer i, LAYERS

! Constant Canopy Parameters
Expand Down Expand Up @@ -192,11 +199,34 @@ SUBROUTINE CANOPY_BIO( ZK, FCLAI, FCH, LAI, FSUN, &
ROOTA,ROOTB)

! Get LEAF AGE factor

TABOVECANOPY = TEMP2 !TEMP2 (above air temp) for TABOVECANOPY
!do i=1, SIZE(ZK)
GAMMALEAFAGE = GET_GAMMA_LEAFAGE(LEAFAGEOPT, PASTLAI, CURRENTLAI, TSTEPLAI, TABOVECANOPY, ANEW, AGRO, AMAT, AOLD)
!end do

! Get canopy loss factor (only used in vertical summing options and empirical formulation and parameters based on isoprene)
! Note: Allowed for other BVOCs but use caution when applying to compare with above canopy flux observations

CANLOSS_FAC = 1.0_rk !Initialize
! All species
if (LOSSIND .eq. 0) then
if (LOSSOPT .eq. 2) then !User set value from NL
CANLOSS_FAC = LOSSSET
else !Try and calculate if turned on
CANLOSS_FAC = GET_CANLOSS_BIO(LOSSOPT,LIFETIME,USTAR,FCH)
end if
end if

!Only for a specific biogenic species/indice
if (LOSSIND .eq. EMI_IND) then
if (LOSSOPT .eq. 2) then !User set value from NL
CANLOSS_FAC = LOSSSET
else !Try and calculate if turned on
CANLOSS_FAC = GET_CANLOSS_BIO(LOSSOPT,LIFETIME,USTAR,FCH)
end if
end if

! Calculate emissions profile in the canopy
EMI_OUT = 0.0_rk ! set initial emissions profile to zero
FLAI = 0.0_rk ! set initial fractional FLAI (LAD) profile to zero
Expand Down Expand Up @@ -234,7 +264,7 @@ SUBROUTINE CANOPY_BIO( ZK, FCLAI, FCH, LAI, FSUN, &
end if
end do
EMI_OUT(SIZE(ZK)) = LAI * EF * SUM(GammaTLEAF_AVE(1:LAYERS) * GammaPPFD_AVE(1:LAYERS) * &
VPGWT(1:LAYERS)) * GAMMACO2 * CCE * GAMMALEAFAGE * GAMMASOIM !put into top model layer (ug m-2 hr-1)
VPGWT(1:LAYERS)) * GAMMACO2 * CCE * GAMMALEAFAGE * GAMMASOIM * CANLOSS_FAC !put into top model layer (ug m-2 hr-1)
EMI_OUT = EMI_OUT * 2.7777777777778E-13_rk !convert emissions output to (kg m-2 s-1)
else if (VERT .eq. 2) then !"MEGANv3-like": Add weighted sum of activity coefficients using normal distribution
!across canopy layers using 5 layer numbers directly from MEGANv3
Expand Down Expand Up @@ -266,7 +296,7 @@ SUBROUTINE CANOPY_BIO( ZK, FCLAI, FCH, LAI, FSUN, &
VPGWT(i) = GAUSS(i)/sum(GAUSS(1:LAYERS))
end do
EMI_OUT(SIZE(ZK)) = LAI * EF * SUM(GammaTLEAF_AVE(1:LAYERS) * GammaPPFD_AVE(1:LAYERS) * &
VPGWT(1:LAYERS)) * GAMMACO2 * CCE * GAMMALEAFAGE * GAMMASOIM !put into top model layer (ug m-2 hr-1)
VPGWT(1:LAYERS)) * GAMMACO2 * CCE * GAMMALEAFAGE * GAMMASOIM * CANLOSS_FAC !put into top model layer (ug m-2 hr-1)
EMI_OUT = EMI_OUT * 2.7777777777778E-13_rk !convert emissions output to (kg m-2 s-1)
else if (VERT .eq. 3) then !"MEGANv3-like": Add weighted sum of activity coefficients equally
!across canopy layers
Expand All @@ -277,7 +307,7 @@ SUBROUTINE CANOPY_BIO( ZK, FCLAI, FCH, LAI, FSUN, &
VPGWT(i) = 1.0_rk/LAYERS
end do
EMI_OUT(SIZE(ZK)) = LAI * EF * SUM(GammaTLEAF_AVE(1:LAYERS) * GammaPPFD_AVE(1:LAYERS) * &
VPGWT(1:LAYERS)) * GAMMACO2 * CCE * GAMMALEAFAGE * GAMMASOIM !put into top model layer (ug m-2 hr-1)
VPGWT(1:LAYERS)) * GAMMACO2 * CCE * GAMMALEAFAGE * GAMMASOIM * CANLOSS_FAC !put into top model layer (ug m-2 hr-1)
EMI_OUT = EMI_OUT * 2.7777777777778E-13_rk !convert emissions output to (kg m-2 s-1)
else
write(*,*) 'Wrong BIOVERT_OPT choice of ', VERT, ' in namelist...exiting'
Expand Down
Loading

0 comments on commit 019958e

Please sign in to comment.