Skip to content

Conversation

mvalmartin
Copy link

@mvalmartin mvalmartin commented Jul 16, 2025

Description of changes

This PR merges the soil NO from #2290 into the NO3 vertical movement scheme in #2992.

The soil NO scheme is based on Parton et al (2001), and includes canopy reduction (Yan et al, 2005) and rain pulses (Yan et al 2005; Hudman et al 2012).

The scheme uses a fixed soil pH value of 6.5, as defined in SoilBiogeochemCompetitionMod.F90

In addition, the scheme does not includes the dependency of the N mineralization-based term on potential nitrification rates proposed in Parton et al. (2001), which is missing in CLM5 as pointed out by Nevison et al., (2022). Although that was implemented in #2290, it is now removed because it substantially affected N plant uptake and the broader carbon cycle.

A more complex version of this scheme, which includes spatially distributed soil pH, weathering effects on denitrification and soil NH3 volatilization, is described and validated in Val Martin et al (2023).

References

Hudman, R. C., Moore, N. E., Mebust, A. K., Martin, R. V., Russell, A. R., Valin, L. C., and Cohen, R. C.: Steps towards a mechanistic model of global soil nitric oxide emissions: implementation and space based-constraints, Atmos. Chem. Phys., 12, 7779–7795, https://doi.org/10.5194/acp-12-7779-2012, 2012.

Nevison, C., Goodale, C., Hess, P., Wieder, W. R., Vira, J., and Groffman, P. M.: Nitrification and Denitrification in the Community Land Model Compared with Observations at Hubbard Brook Forest, Ecol. Appl., 32, e2530, https://doi.org/10.1002/eap.2530, 2022

Parton, W. J., Holland, E. A., Del Grosso, S. J., Hartman, M. D., Martin, R. E., Mosier, A. R., Ojima, D. S., and Schimel, D. S.: Generalized model for NOx and N2O emissions from soils, J. Geophys. Res.-Atmos., 106, 17403–17419, https://doi.org/10.1029/2001JD900101, 2001.

Val Martin, M., Blanc-Betes, E., Fung, K. M., Kantzas, E. P., Kantola, I. B., Chiaravalloti, I., Taylor, L. L., Emmons, L. K., Wieder, W. R., Planavsky, N. J., Masters, M. D., DeLucia, E. H., Tai, A. P. K., and Beerling, D. J.: Improving nitrogen cycling in a land surface model (CLM5) to quantify soil N2O, NO, and NH3 emissions from enhanced rock weathering with croplands, Geosci. Model Dev., 16, 5783–5801, https://doi.org/10.5194/gmd-16-5783-2023, 2023.

Yan, X., Ohara, T., and Akimoto, H.: Statistical modelling of global soil NOx emissions, Global Biogeochem. Cy., 19, GB3019, https://doi.org/10.1029/2004GB002276, 2005.

Specific notes

Contributors other than yourself, if any: @lkemmons, @slevis-lmwg & @wwieder

CTSM Issues Fixed (include github issue #): Unknown

Are answers expected to change (and if so in what way)? I don't think so

Any User Interface Changes (namelist or namelist defaults changes)?
The soil NO scheme can be turned on and off within the user_nl_clm as use_soil_nox=.true. or .false.
As indicated by Jinmu Luo, the soil NO3 vertical movement scheme can also be turned on and off, but the switch is hardwire within SoilNitrogenMovementMod.F90

Does this create a need to change or add documentation? Did you do so?
To be determined

Testing performed, if any:
We performed 15-year runs using the new configuration, with the first 5 year treated as a pseudo-spin up, using the compset 2000_DATM%GSWP3v1_CLM50%BGC-CROP_SICE_SOCN_MOSART_CISM2%NOEVOLVE_SWAV

For evaluation we analyzed global annual timeseries and spatial distributions including changes between runs. Simulations were:

  1. Control (no NO3 vertical movement and no soil NOx)
  2. NO3VertMov (only soil NO3 vertical movement activated)
  3. NO3VertMov+SoilNOx (both soil NO3 vertical movemennt and soil NOx activated).

The main changes in the N cycle (eg soil NO2, denitrification and nitrfication) are driven by the NO3 vertical movement implementation. No significant changes are noticed in the carbon cycle (eg NPP, TOTECOSYSC).

plot_no3vertmov_soilnox_mvalmartin.pdf

@slevis-lmwg slevis-lmwg added the science Enhancement to or bug impacting science label Jul 17, 2025
@slevis-lmwg slevis-lmwg added the enhancement new capability or improved behavior of existing capability label Jul 17, 2025
@ekluzek
Copy link
Collaborator

ekluzek commented Jul 22, 2025

This is based off of: ctsm5.3.040

There is new work to update this to a newer version of CTSM.

@slevis-lmwg
Copy link
Contributor

This is based off of: ctsm5.3.040

There is new work to update this to a newer version of CTSM.

True and, more precisely, Maria's branch starts from @jinmuluo's branch #2992 that is based off of ctsm5.3.040.

@ekluzek ekluzek added the next this should get some attention in the next week or two. Normally each Thursday SE meeting. label Jul 24, 2025
@ekluzek
Copy link
Collaborator

ekluzek commented Jul 24, 2025

Adding next to make sure we know what is happening with all this work.

@ekluzek ekluzek removed the next this should get some attention in the next week or two. Normally each Thursday SE meeting. label Jul 24, 2025
@ekluzek ekluzek requested review from slevis-lmwg and wwieder July 24, 2025 16:17
@ekluzek ekluzek added this to the ctsm6.1.0 milestone Jul 24, 2025
@ekluzek
Copy link
Collaborator

ekluzek commented Jul 24, 2025

@wwieder and @slevis-lmwg will review. @slevis-lmwg meets with the group Monday, and will get more information then.

@slevis-lmwg
Copy link
Contributor

@wwieder (in case you want to look)
I made a diff file that compares this PR to #2992, because that's where Maria started from. The diff file is:
/glade/work/slevis/git_people/mvalmartin/ctsm_soilno/dif_from_jinmu

Copy link
Contributor

@slevis-lmwg slevis-lmwg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mvalmartin for starters I want to say that your coding here seems to me well organized, so thank you for this.

In my review I think I only made one comment, but you will find that I repeated it a few times.

Another request is this: Could you document in the PR (if you didn't already) how you tested your code changes? What types of simulations you performed (compsets, lengths, resolutions, ...)? What history fields you looked at to confirm model behavior? What model behavior you expected and what model behavior you saw?

if (clmveg == nc3crop .or. clmveg == nc3irrig ) ratio_stai_lai = 0.008_r8
if (clmveg >= npcropmin .and. clmveg <= npcropmax ) ratio_stai_lai = 0.008_r8

crf_drydep(pi)=(exp(-11.6_r8*elai(pi)*ratio_stai_lai)+exp(-0.32_r8*elai(pi)))/2
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be one big new section of code.

A comment for here and elsewhere:
When possible, we avoid hardwiring values without explanation. As a first step, could you name things like -11.6 and -0.32 to variable names?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also wonder if values like ratio_stai_lai should be PFT parameters on the parameter file to make this code easier to read? The only odd part is that values change by season for some PFTs?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the note and apologies for the slow 'action'. Working on your comments now!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the note and apologies for the slow 'action'. Working on your comments now!

@mvalmartin a heads up that I'm about to update your branch to the latest escomp/master tag. I'm mentioning in case you already started making changes to your local copy. If so, you would

  • "stash" your local changes (git stash)
  • pull my remote changes (git pull)
  • bring forward your local changes (git stash pop)
  • continue making changes as needed (git add, git commit, git push)

I hope all that works without trouble...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you didn't already start making changes, then you can simply skip the "git stash" and "git stash pop" steps. In other words just

  • git pull
  • make changes
  • git add
  • git commit
  • git push

if ( h2osoi_diff(c,j) > 0.005_r8 ) then
! Initialize new pulse factor (dry period hours)
if ( ldry_vr(c,j) > 72._r8 ) then
pfactor_vr(c,j) = 13._r8 *LOG(ldry_vr(c,j)) - 53.6_r8
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is another large section of the new code. It would be helpful again here to assign hardwired values to variable names (always with literature references when possible).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this comment. In the original code the hardwired values appear as simple scalars in the equations, without variable names or descriptions. I have now added the reference (article and equation number) for each equation to make this clearer.

afps_vr(c,j) = 1._r8-max(min(h2osoi_vol(c,j)/watsat(c,j), 1._r8), 0._r8)
Dr = 0.209_r8*afps_vr(c,j)**(4._r8/3._r8)

nox_n2o_ratio_vr(c,j) = 15.2_r8 + (35.5_r8 * atan(0.68_r8 * rpi * (10.0_r8 * Dr - 1.86_r8))) / rpi
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is another area with numerous hardwired values that need some kind of documentation, such as assigning variable names and literature refs to them.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case too. In the original code the hardwired values appear as simple scalars in the equations, without variable names or descriptions. I added the reference (article and equation number) for each equation to make this clearer.

Copy link
Contributor

@wwieder wwieder left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder we can rebase this PR can be to Jinmu's branch / PR #2992 so we just see the changes that were made for the NOx scheme? Maybe this will be be easier once Jinmu's PR comes to main?

if (clmveg == nc3crop .or. clmveg == nc3irrig ) ratio_stai_lai = 0.008_r8
if (clmveg >= npcropmin .and. clmveg <= npcropmax ) ratio_stai_lai = 0.008_r8

crf_drydep(pi)=(exp(-11.6_r8*elai(pi)*ratio_stai_lai)+exp(-0.32_r8*elai(pi)))/2
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also wonder if values like ratio_stai_lai should be PFT parameters on the parameter file to make this code easier to read? The only odd part is that values change by season for some PFTs?

@slevis-lmwg
Copy link
Contributor

@mvalmartin I will need "collaborator access" to your branch for when I end up working on it. This is how you give me access:

  • At the top of your PR, click on your branch: mvalmartin:ctsm_soilno
  • Now at the top-middle click Settings and then Collaborators and follow the prompts to add me (@slevis-lmwg) as a collaborator

@mvalmartin
Copy link
Author

mvalmartin commented Aug 5, 2025

@slevis-lmwg, I added you as collaborator in the PR, you should have received an invitation. Please let me know if you can't still access it. Thanks!

…_soilno

slevis resolved conflicts:
src/main/controlMod.F90
@slevis-lmwg
Copy link
Contributor

@mvalmartin thank you. I confirmed my access by merging the latest updates from @jinmuluo's branch to your branch here. A few points:

  • I will make such merges a few more times occasionally, including after merging @jinmuluo's branch to master eventually.
  • Do "git pull" in your local copy of ctsm_soilno to have the latest code from here.
  • Then modify ctsm_soilno as necessary (e.g. revisions in response to the code reviews above) and git push back to here, so that I can in turn git pull to my local copy of ctsm_soilno and that way stay up-to-date.

@slevis-lmwg slevis-lmwg moved this from Stalled to In Progress in LMWG: Sprint Planning Board Aug 26, 2025
Incorporating a new vertical movement scheme for soil nitrate

Work by Jinmu Luo of Cornell University.

use_nvmovement defaults to .false. and can be changed in user_nl_clm.
use_nvmovement cannot be true while use_nitrif_denitrif is false.
 We test the flag as .true. in two new tests:
 ERP_D_Ld5.f10_f10_mg37.I1850Clm60BgcCrop.derecho_intel.clm-nvmovement--clm-matrixcnOn
 ERP_D.f10_f10_mg37.IHistClm60Bgc.derecho_intel.clm-decStart--clm-nvmovement

PR ESCOMP#2992
@slevis-lmwg
Copy link
Contributor

slevis-lmwg commented Aug 26, 2025

Updated to ctsm5.3.073 and started ./run_sys_tests -s aux_clm -c ctsm5.3.073 --skip-generate
So far I see many RUN failures in the following tests, so debugging likely comes next...

  • izumi tests_0829-095644iz
  • derecho, still NLCOMP diffs? tests_0829-095437de
    Troubleshooting with SMS.f10_f10_mg37.I2000Clm50BgcCrop.derecho_intel.clm-crop (see latest submit 2025/9/3)

slevis-lmwg and others added 3 commits August 26, 2025 17:09
Update .gitmodules to cesm3_0_alpha07c

 Update ccs_config_cesm1.0.48 to ccs_config_cesm1.0.56.
 Update cime6.1.112 to cime6.1.113.
 Answers change in gnu and nvhpc tests on derecho (details in the PR).
 New bugs found and reported in issues
 ESCOMP#3453 FAIL MKSURFDATAESMF_...intel NLCOMP
 ESCOMP#3454 FAIL SUBSETDATA* tests NLCOMP

 PR ESCOMP#3422
…to add information about the schemes and parameters
Copy link
Contributor

@slevis-lmwg slevis-lmwg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mvalmartin thank you for these updates.

Another request that @samsrabin reminded me of when he reviewed @jinmuluo's PR is to pick more descriptive variable names for the code, rather than using the symbols used in the literature.

(No immediate rush, as I am working on other things at the moment, plus there are tests that this PR fails that I need to look into.)

fno3_co2 = max(0.16_r8*ratio_k1(c,j), ratio_k1(c,j)*exp(-0.8_r8 * ratio_no3_co2(c,j)))
n2_n2o_ratio_denit_vr(c,j) = max(0.1_r8,fno3_co2*fr_WFPS(c,j))

! Dr from Zhao et al. (2017) Equation A2 https://doi.org/10.5194/acp-17-9781-2017
Copy link
Contributor

@slevis-lmwg slevis-lmwg Sep 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mvalmartin
@samsrabin reminded me of this when he reviewed @jinmuluo's PR:
Please pick more descriptive variable names for the code, rather than using the symbols used in the literature (such as Dr here).

@slevis-lmwg slevis-lmwg moved this from In Progress to Stalled in LMWG: Sprint Planning Board Sep 16, 2025
@slevis-lmwg
Copy link
Contributor

@mvalmartin
other activities have lowered this PR's priority for me right now. If you could investigate why tests like SMS.f10_f10_mg37.I2000Clm50BgcCrop.derecho_intel.clm-crop fail, that would help move this work forward. To run this test, go to the /cime/scripts directory and run
create_test SMS.f10_f10_mg37.I2000Clm50BgcCrop.derecho_intel.clm-crop
The failure has been in the RUN phase.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement new capability or improved behavior of existing capability science Enhancement to or bug impacting science
Projects
Status: Stalled
Development

Successfully merging this pull request may close these issues.

4 participants