-
Notifications
You must be signed in to change notification settings - Fork 340
Add soil NO fluxes into the N cycle. #2290
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -472,6 +472,13 @@ subroutine NBalanceCheck(this, bounds, num_soilc, filter_soilc, & | |
| smin_no3_leached => soilbiogeochem_nitrogenflux_inst%smin_no3_leached_col , & ! Input: [real(r8) (:) ] (gN/m2/s) soil mineral NO3 pool loss to leaching | ||
| smin_no3_runoff => soilbiogeochem_nitrogenflux_inst%smin_no3_runoff_col , & ! Input: [real(r8) (:) ] (gN/m2/s) soil mineral NO3 pool loss to runoff | ||
| f_n2o_nit => soilbiogeochem_nitrogenflux_inst%f_n2o_nit_col , & ! Input: [real(r8) (:) ] (gN/m2/s) flux of N2o from nitrification | ||
| !mvm soil NOx 06/19/2023 | ||
| f_n2o_denit => soilbiogeochem_nitrogenflux_inst%f_n2o_denit_col , & ! Input: [real(r8) (:) ] (gN/m2/s) flux of N2o from denitrification | ||
| f_n2_denit => soilbiogeochem_nitrogenflux_inst%f_n2_denit_col , & ! Input: [real(r8) (:) ] (gN/m2/s) flux of N2 from denitrification | ||
| f_nox_denit_atmos => soilbiogeochem_nitrogenflux_inst%f_nox_denit_atmos_col , & ! Input:[real(r8) (:) ] (gN/m2/s) flux of NOx from denitrification; added by mvm for NOx emission | ||
| f_nox_denit => soilbiogeochem_nitrogenflux_inst%f_nox_denit_col , & ! Input:[real(r8) (:) ] (gN/m2/s) flux of NOx from denitrification; added by mvm for NOx emission | ||
| f_nox_nit_atmos => soilbiogeochem_nitrogenflux_inst%f_nox_nit_atmos_col, & ! Input: [real(r8) (:) ] (gN/m2/s) flux of NOx from nitrification; added by mvm for NOx emission | ||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should there be an
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. in theory it should be a f_nox_nit as well. I'll check the code!
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. actually, only the _atmos fluxes are lost to the atmosphere. The f_nox_denit was there for debugging, in case there is an issue with the N balance and can be output during debugging. I'll add f_nox_nit for consistency. |
||
| som_n_leached => soilbiogeochem_nitrogenflux_inst%som_n_leached_col , & ! Input: [real(r8) (:) ] (gN/m2/s) total SOM N loss from vertical transport | ||
|
|
||
| col_fire_nloss => cnveg_nitrogenflux_inst%fire_nloss_col , & ! Input: [real(r8) (:) ] (gN/m2/s) total column-level fire N loss | ||
|
|
@@ -513,7 +520,12 @@ subroutine NBalanceCheck(this, bounds, num_soilc, filter_soilc, & | |
| col_ninputs_partial(c) = col_ninputs(c) | ||
|
|
||
| ! calculate total column-level outputs | ||
| col_noutputs(c) = denit(c) + col_fire_nloss(c) + gru_conv_nflux(c) | ||
| !mvm commneted as denit equals now N2Odenit+N2+NOxdenit | ||
| !col_noutputs(c) = denit(c) + col_fire_nloss(c) + gru_conv_nflux(c) | ||
| col_noutputs(c) = f_n2_denit(c)+f_n2o_denit(c) + col_fire_nloss(c)+ gru_conv_nflux(c) | ||
| !mvm: only atmos NOx denit leaves the system, NOx denit trapped in the canopy stays in the system. | ||
| col_noutputs(c) = col_noutputs(c)+f_nox_denit_atmos(c) | ||
|
|
||
|
|
||
| ! Fluxes to product pools are included in column-level outputs: the product | ||
| ! pools are not included in totcoln, so are outside the system with respect to | ||
|
|
@@ -529,6 +541,8 @@ subroutine NBalanceCheck(this, bounds, num_soilc, filter_soilc, & | |
| col_noutputs(c) = col_noutputs(c) + sminn_leached(c) | ||
| else | ||
| col_noutputs(c) = col_noutputs(c) + f_n2o_nit(c) | ||
| !mvm added for NOx nit 06/19/2023 | ||
| col_noutputs(c) = col_noutputs(c) + f_nox_nit_atmos(c) | ||
|
|
||
| col_noutputs(c) = col_noutputs(c) + smin_no3_leached(c) + smin_no3_runoff(c) | ||
| end if | ||
|
|
@@ -551,7 +565,7 @@ subroutine NBalanceCheck(this, bounds, num_soilc, filter_soilc, & | |
| if (abs(col_errnb(c)) > this%nwarning) then | ||
| write(iulog,*) 'nbalance warning at c =', c, col_errnb(c), col_endnb(c) | ||
| write(iulog,*)'inputs,ffix,nfix,ndep = ',ffix_to_sminn(c)*dt,nfix_to_sminn(c)*dt,ndep_to_sminn(c)*dt | ||
| write(iulog,*)'outputs,lch,roff,dnit = ',smin_no3_leached(c)*dt, smin_no3_runoff(c)*dt,f_n2o_nit(c)*dt | ||
| write(iulog,*)'outputs,lch,roff,dnit = ',smin_no3_leached(c)*dt, smin_no3_runoff(c)*dt,denit(c)*dt | ||
| end if | ||
|
|
||
| end do ! end of columns loop | ||
|
|
@@ -567,7 +581,7 @@ subroutine NBalanceCheck(this, bounds, num_soilc, filter_soilc, & | |
| write(iulog,*)'output mass = ',col_noutputs(c)*dt | ||
| write(iulog,*)'net flux = ',(col_ninputs(c)-col_noutputs(c))*dt | ||
| write(iulog,*)'inputs,ffix,nfix,ndep = ',ffix_to_sminn(c)*dt,nfix_to_sminn(c)*dt,ndep_to_sminn(c)*dt | ||
| write(iulog,*)'outputs,lch,roff,dnit = ',smin_no3_leached(c)*dt, smin_no3_runoff(c)*dt,f_n2o_nit(c)*dt | ||
| write(iulog,*)'outputs,lch,roff,dnit = ',smin_no3_leached(c)*dt, smin_no3_runoff(c)*dt,denit(c)*dt | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Make sure that denit is calculated somewhere. I did not see it anywhere but may have missed it. |
||
| call endrun(subgrid_index=c, subgrid_level=subgrid_level_column, msg=errMsg(sourcefile, __LINE__)) | ||
| end if | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -84,7 +84,8 @@ Module DryDepVelocity | |
|
|
||
| real(r8), pointer, public :: velocity_patch (:,:) ! Dry Deposition Velocity | ||
| real(r8), pointer, private :: rs_drydep_patch (:) ! Stomatal resistance associated with dry deposition velocity for Ozone | ||
|
|
||
| !mvm for soil Nox canopy reduction function | ||
| real(r8), pointer, public :: crf_drydep_patch (:) ! Canopy reduction factor for NO associated with dry deposition velocity | ||
| contains | ||
|
|
||
| procedure , public :: Init | ||
|
|
@@ -136,6 +137,8 @@ subroutine InitAllocate(this, bounds) | |
| if ( n_drydep > 0 )then | ||
| allocate(this%velocity_patch(begp:endp, n_drydep)); this%velocity_patch(:,:) = nan | ||
| allocate(this%rs_drydep_patch(begp:endp)) ; this%rs_drydep_patch(:) = nan | ||
| !mvm 06/19/2023 soil NOx | ||
| allocate(this%crf_drydep_patch(begp:endp)) ; this%crf_drydep_patch(:) = nan | ||
| end if | ||
|
|
||
| end subroutine InitAllocate | ||
|
|
@@ -179,6 +182,11 @@ subroutine InitHistory(this, bounds) | |
| call hist_addfld1d ( fname='RS_DRYDEP_O3', units='s/m', & | ||
| avgflag='A', long_name='Stomatal Resistance Associated with Ozone Dry Deposition Velocity', & | ||
| ptr_patch=this%rs_drydep_patch, default='inactive' ) | ||
| !mvm for soil NOx | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this variable have a more descriptive name (e.g.,
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. noted! |
||
| this%crf_drydep_patch(begp:endp)= spval | ||
| call hist_addfld1d ( fname='CRF_DRYDEP', units='unitless', & | ||
| avgflag='A', long_name='Canopy Reduction Factor Associated with NO Dry Deposition Velocity', & | ||
| ptr_patch=this%crf_drydep_patch, default='inactive') | ||
|
|
||
| end subroutine InitHistory | ||
|
|
||
|
|
@@ -250,7 +258,8 @@ subroutine depvel_compute( bounds, & | |
| real(r8) :: minlai ! minimum of monthly lai | ||
| real(r8) :: maxlai ! maximum of monthly lai | ||
| real(r8) :: rds ! resistance for aerosols | ||
|
|
||
| !mvm 06/16/2023 for canopy redcution factor | ||
| real(r8) :: ratio_sai_lai !ratio of stomata area index to lai [unitless] | ||
| !mvm 11/30/2013 | ||
| real(r8) :: rlu_lai ! constant to calculate rlu over bulk canopy | ||
|
|
||
|
|
@@ -308,7 +317,8 @@ subroutine depvel_compute( bounds, & | |
| annlai => canopystate_inst%annlai_patch , & ! Input: [real(r8) (:,:) ] 12 months of monthly lai from input data set | ||
|
|
||
| velocity => drydepvel_inst%velocity_patch , & ! Output: [real(r8) (:,:) ] cm/sec | ||
| rs_drydep => drydepvel_inst%rs_drydep_patch & ! Output: [real(r8) (:) ] stomatal resistance associated with Ozone dry deposition velocity (s/m) | ||
| rs_drydep => drydepvel_inst%rs_drydep_patch , & ! Output: [real(r8) (:) ] stomatal resistance associated with Ozone dry deposition velocity (s/m) | ||
| crf_drydep => drydepvel_inst%crf_drydep_patch & ! Output: [real(r8) (:) ] canopy reduction factor for NO associated with dry deposition velocity [unitless] mvm for soil NOx | ||
| ) | ||
|
|
||
| !_________________________________________________________________ | ||
|
|
@@ -654,6 +664,60 @@ subroutine depvel_compute( bounds, & | |
| rc = 1._r8/((1._r8/rsmx(ispec))+(1._r8/rlux(ispec)) + & | ||
| (1._r8/(rdc+rclx(ispec)))+(1._r8/(rac(index_season,wesveg)+rgsx(ispec)))) | ||
| rc = max( 10._r8, rc) | ||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it seems like setting the parameter
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, 2-d variable with dimensions for PFT and season would make it easier for changes and sensitivity tests in the future.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can try to do that, I'm not really familiar with the CTSM coding convention though so not sure how to create this 2-D variable with season and PFT.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, I didn't realize this was a time varying variable. Since this is something we're already calculating elsewhere in the model, should we just use the ratio of SAI and LAI for consistency? I realize this may change answers scientifically that you'd want to evaluate? The easier option would be to keep this as is for CLM6/CESM3?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I left it as it is for now
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The model has another sai = stem area index. Better to call this one stai to prevent confusion? |
||
|
|
||
|
|
||
| !!!! CANOPY REDUCTION FACTOR FOR soil NO fluxes!!!! mvm 06/15/2023 | ||
| ! canopy reduction factor for soil NO emission flux | ||
| ! based on Yan et al 2005 and Yienger and Levy 1995 | ||
| !Probably there may be a cleaner way to code this. | ||
| if ( drydep_list(ispec) == 'NO') then | ||
|
|
||
| !no canopy reduction factor (ie zero update) over bare land or elai < 0. | ||
| if( clmveg == noveg) then | ||
| crf_drydep(pi)=1._r8 | ||
| else | ||
| !sai=elai(pi)*ratio_sai_lai | ||
| !ratio_sai_lai from Yienger and Levy 1995 Table 6 | ||
|
|
||
| !needleaf forest (coniferous forest) | ||
| if (clmveg == ndllf_evr_tmp_tree .or. clmveg == ndllf_evr_brl_tree .or. clmveg == ndllf_dcd_brl_tree ) ratio_sai_lai = 0.03_r8 | ||
|
|
||
| !broadleaf evergreen (rainforest) | ||
| if (clmveg == nbrdlf_evr_trp_tree .or. clmveg == nbrdlf_evr_tmp_tree ) ratio_sai_lai = 0.015_r8 | ||
|
|
||
| !broadleaf decidouos | ||
| if (clmveg == nbrdlf_dcd_trp_tree .or. clmveg == nbrdlf_dcd_tmp_tree .or. clmveg == nbrdlf_dcd_brl_tree) then | ||
| if (index_season == 1 .or. index_season == 5) then | ||
| ! spring/summer | ||
| ratio_sai_lai = 0.015_r8 | ||
| else | ||
| !winter/fall | ||
| ratio_sai_lai = 0.005_r8 | ||
| endif | ||
| endif | ||
|
|
||
| !shrubs | ||
| if (clmveg == nbrdlf_evr_shrub .or. clmveg == nbrdlf_dcd_tmp_shrub .or. clmveg == nbrdlf_dcd_brl_shrub ) ratio_sai_lai = 0.005_r8 | ||
|
|
||
| !grass | ||
| if (clmveg == nc3_arctic_grass .or. clmveg == nc3_nonarctic_grass .or. clmveg == nc4_grass ) ratio_sai_lai = 0.005_r8 | ||
|
|
||
| !crops | ||
| if (clmveg == nc3crop .or. clmveg == nc3irrig ) ratio_sai_lai = 0.008_r8 | ||
| if (clmveg >= npcropmin .and. clmveg <= npcropmax ) ratio_sai_lai = 0.008_r8 | ||
|
|
||
| !CRF=exp((-ks*SAI)+exp(-kc*LAI))/2 | ||
| !ks=11.6 m2/m2 kc=0.32 m2/m2 (Yan et al 2005) | ||
| !ks=8.75 kc=0.24 (Yienger and levy 1995) | ||
|
|
||
| crf_drydep(pi)=(exp(-11.6_r8*elai(pi)*ratio_sai_lai)+exp(-0.32*elai(pi)))/2 | ||
|
|
||
| endif !no veg | ||
| endif ! CRF for NOx | ||
|
|
||
|
|
||
|
|
||
| ! | ||
| ! assume no surface resistance for SO2 over water | ||
| ! | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mvalmartin here and throughout the PR can you remove the comments with your initials and the date
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, and please also delete commented-out lines of code that your new code is replacing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can do that, no problem!