Skip to content

Tendency application update#299

Merged
rhaesung merged 80 commits into
ufs-community:ufs/devfrom
grantfirl:feature/tendency_cleanup
Apr 3, 2026
Merged

Tendency application update#299
rhaesung merged 80 commits into
ufs-community:ufs/devfrom
grantfirl:feature/tendency_cleanup

Conversation

@grantfirl
Copy link
Copy Markdown
Collaborator

@grantfirl grantfirl commented Jul 14, 2025

Description of Changes:

See https://docs.google.com/presentation/d/1LJbCrCVGYDvm0UPo8SR4KP6fT1VFocg-xLG399qGQ1w/edit?slide=id.g371ddcb3c06_0_238#slide=id.g371ddcb3c06_0_238 for a complete description.

Main points:

  • Converts all primary schemes to return tendencies rather than modify the physics state
  • Adds code to interstitial schemes to apply tendencies based on control from the host
  • Other minor changes (including lots of metadata changes) to implement the above
  • Obsolete schemes removed:
    • GFS_MP_generic_pre.F90
    • GFS_DCNV_generic_pre.F90
    • GFS_SCNV_generic_pre.F90
    • GFS_suite_stateout_reset.F90
    • GFS_suite_stateout_update.F90
    • mp_tempo_pre.F90
    • mp_thompson_pre.F90
  • New schemes:
    • GFS_photochemistry_post.F90 (because there was no generic interstitial scheme for this to apply tendencies)
    • mynnedmf_wrapper_post.F90 (because it doesn't use GFS_PBL_generic_post.F90)

Tests Conducted:

See the linked slides. This was tested in the following ways:

  • standard UFS regression tests (should change baseline results for most/all tests that actually run physics, although changes SHOULD be similar to a compiler change; scientific results should NOT change)
  • SCM tests comparing selected suites before/after differences to compiler/debug mode differences
  • UFS tests comparing selected suites before/after differences to compiler/debug mode differences

Dependencies:

MYNN SFC Layer #27

Documentation:

TODO

Issue (optional):

None

Contributors (optional):

@grantfirl @VanderleiVargas-NOAA

grantfirl and others added 30 commits December 12, 2024 12:07
…emove *_of_new_state (default name refers to 'current' value)
…medmfvdifq return new tendencies and new tendency application block in GFS_PBL_generic_post
- Added tendency variables (`ten_t`, `ten_u`, `ten_v`) for temperature and wind tendencies in SAMF deep and shallow convection schemes.
- Updated relevant `.meta` files to reflect changes in variable intent (`inout` -> `in` where appropriate) and added tendencies.
- Modified Interstitials (`GFS_DCNV_generic_post`, `GFS_DCNV_generic_pre`, `GFS_SCNV_generic_post`, `GFS_SCNV_generic_pre`) to directly use tendencies instead of saved state variables.
- Removed redundant saved variables (`save_u`, `save_v`, `save_t`).
- Added `delt` to post interstitials.
…endency paradigm; cleanup saving of states no longer needed
Comment thread physics/Interstitials/UFS_SCM_NEPTUNE/ccpp_suite_simulator.meta
Comment thread physics/Interstitials/UFS_SCM_NEPTUNE/GFS_GWD_generic_post.F90
Comment thread physics/Interstitials/UFS_SCM_NEPTUNE/GFS_MP_generic_post.F90
Comment thread physics/Interstitials/UFS_SCM_NEPTUNE/GFS_PBL_generic_post.F90
Comment thread physics/Interstitials/UFS_SCM_NEPTUNE/GFS_photochemistry_post.F90
Comment thread physics/Interstitials/UFS_SCM_NEPTUNE/GFS_radiation_post.F90
Comment thread physics/Interstitials/UFS_SCM_NEPTUNE/GFS_radiation_post.F90
Comment thread physics/Interstitials/UFS_SCM_NEPTUNE/GFS_suite_interstitial_2.F90
@grantfirl
Copy link
Copy Markdown
Collaborator Author

grantfirl commented Mar 9, 2026

@grantfirl For MP, I just have a few questions:

  1. Since you mentioned the tracer array issue in convection, I was curious about ten_q in MP. Is the mapping from individual species (dqc, dqr, etc.) to the general ten_q array handled automatically now, or do we still need to keep an eye on manual updates? Just want to make sure we don't hit the same snag there!

It's automatic in the sense that individual species tendencies exist as slices of the entire tracer tendency array. That is, tendency_of_cloud_liquid_water_mixing_ratio, for example, resolves to a particular slice of the tendency_of_tracer_concentration array as defined in the host metadata. So, if a microphysics scheme wanted to operate on individual species, they can do that (as long as the entire tracer tendency array is re-initialized to zero before setting values for individual species) and the post interstitial scheme can successfully apply tendencies to those individual species only (since non-used tracer tendency slices are zero).

@grantfirl
Copy link
Copy Markdown
Collaborator Author

  1. On the precip variables (prcp, PREC), I noticed they're still intent(inout) without a guard flag like GWD's ugwp_seq_update. Are we worried about double-counting when generic_post kicks in, or is that handled elsewhere in the current UFS suites?

I'm not sure that I understand the question. The precip variables are surface variables that are independent of the tracer concentrations, right? I don't think that we're touching how these precip variables are handled in this PR. Since we're not changing how they're handled, I don't think that this PR could contribute to any double-counting. If a problem exists, it's not being fixed in this PR, but I'm not sure that one exists without specifics.

@grantfirl
Copy link
Copy Markdown
Collaborator Author

  1. Just a small safety check - I noticed some optional variables (like nc, nwfa) are accessed without present() checks.

I think that in Thompson and TEMPO, the use of nc, nwfa etc are guarded by logicals that resolve to True only when they should be allocated by the host, so they're safe in that sense, at least in the UFS. I think that you're right that there probably should be a check for present, perhaps in the init stage, though, for models other than the UFS who may not be allocating based on those same logical flags. I think that this is a separate issue that what is being addressed in this PR, though.

@rhaesung
Copy link
Copy Markdown
Collaborator

rhaesung commented Mar 9, 2026

  1. On the precip variables (prcp, PREC), I noticed they're still intent(inout) without a guard flag like GWD's ugwp_seq_update. Are we worried about double-counting when generic_post kicks in, or is that handled elsewhere in the current UFS suites?

I'm not sure that I understand the question. The precip variables are surface variables that are independent of the tracer concentrations, right? I don't think that we're touching how these precip variables are handled in this PR. Since we're not changing how they're handled, I don't think that this PR could contribute to any double-counting. If a problem exists, it's not being fixed in this PR, but I'm not sure that one exists without specifics.

I see. The reason I brought up it up is that as we move this into a generic_post, I noticed lines 522-526 still perform an explicit accumulation (totprcp = totprcp + rain).

My only concern was whether we should take this opportunity to add a guard flag - similar to the one for GWD - to make the routine more robust for different suites, just in case a scheme handles surface updates internally. But if you'd prefer to keep the legacy as-is for this PR, I'm okay with that!

@rhaesung
Copy link
Copy Markdown
Collaborator

rhaesung commented Mar 9, 2026

5. Just a small safety check - I noticed some optional variables (like nc, nwfa) are accessed without present() checks.

I think that in Thompson and TEMPO, the use of nc, nwfa etc are guarded by logicals that resolve to True only when they should be allocated by the host, so they're safe in that sense, at least in the UFS. I think that you're right that there probably should be a check for present, perhaps in the init stage, though, for models other than the UFS who may not be allocating based on those same logical flags. I think that this is a separate issue that what is being addressed in this PR, though.

Fair point. Since the UFS is currently guarded by those logical flags, I'm okay with leaving the formal present() checks for a future cleanup to keep this PR focused.

Copy link
Copy Markdown
Collaborator

@rhaesung rhaesung Mar 9, 2026

Choose a reason for hiding this comment

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

I know this is legacy logic, but with the new tend_opt_mp=2 option, gt0 is no longer updated, making gt0-save_t return zero. Should we change this to ten_t * dtp to match the tracer logic at L554 for consistency?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

It was kept as-is to try to return the correct diagnostic if temperature was being overwritten by radar or updated by the MP scheme, but I see your point. I will add some more logic to try to make sure that the diagnostic is updated correctly, even if the tendency isn't actually being applied within. Standby. There'll be a commit shortly.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

@rhaesung Please see 5ff0004 to see if this seems correct to you. If radar temperature tendencies are active, the code section above handles it, and it now uses ten_t. If the radar temperature tendencies are not active, the section below handles it, also using ten_t.

@grantfirl
Copy link
Copy Markdown
Collaborator Author

@grantfirl A few questions for the PBL schemes:

  1. Most schemes still modify legacy tracer arrays (rtg, dqdt) directly. Shouldn't we move these to ten_q to match the T, U, V strategy and your metadata?
  2. For 2D surface fluxes, some use = or += on intent(out). I saw a similar pattern in the MP schemes as well. Wouldn't it be better to handle these 2D variables using the same tendency guards as the 3D states?
  3. Many optional diagnostic arrays (like dtend) are missing present() checks.

The PBL schemes mostly still operate on the vertically-diffused tracer subset array. This is necessary since most schemes operate on the entire sub-array. Otherwise, there would need to be a lot of host-specific added in every PBL scheme to trigger which tracers get mixed.

I think that the question related to handling any variables besides the main state variables differently is probably a question for a different PR. The 2D surface flux and precipitation fields are always assumed to be instantaneous/current (diagnostic as opposed to prognostic) and, as far as I know, don't get time-stepped like the state variables that may necessitate different treatment in different hosts.

I think that all dtend usage is guarded by other logical flags like lssav, ldiag3d etc, which was deemed save enough by the code authors, hence the lack of present() checks.

@grantfirl
Copy link
Copy Markdown
Collaborator Author

@rhaesung During the last update from ufs/dev, I had to deal with the fact the the MYNN sfc layer scheme is now a submodule. So, now there is a pull request into the MYNN sfc layer submodule repo with the necessary changes (just metadata changes). There may be a conflict because the submodule hash that the ccpp-physics points to is now quite far behind the top of the main branch in the submodule, and the submodule PR is targeting the main branch. This is something that needs to get worked out between @joeolson42 @dustinswales and us. It may be necessary to have two branches in the submodule -- one for ongoing development by the developers, and another that the ccpp-physics points to.

@rhaesung
Copy link
Copy Markdown
Collaborator

@rhaesung During the last update from ufs/dev, I had to deal with the fact the the MYNN sfc layer scheme is now a submodule. So, now there is a pull request into the MYNN sfc layer submodule repo with the necessary changes (just metadata changes). There may be a conflict because the submodule hash that the ccpp-physics points to is now quite far behind the top of the main branch in the submodule, and the submodule PR is targeting the main branch. This is something that needs to get worked out between @joeolson42 @dustinswales and us. It may be necessary to have two branches in the submodule -- one for ongoing development by the developers, and another that the ccpp-physics points to.

Thanks for the heads-up. Submodule management can definitely get tricky when the hashes diverge that much. The two-branch strategy sounds like a solid way to bridge the gap.

Copy link
Copy Markdown
Collaborator

@rhaesung rhaesung left a comment

Choose a reason for hiding this comment

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

@grantfirl I really appreciate the detailed fixes and clarifications. LGTM and approving!

@gspetro-NOAA
Copy link
Copy Markdown

Testing for ufs-community/ufs-weather-model#2810 has completed successfully. This PR can be merged.

@rhaesung rhaesung merged commit 91d9790 into ufs-community:ufs/dev Apr 3, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.