Skip to content

Consistent wind metric - #791

Open
thomasmelvin wants to merge 10 commits into
MetOffice:mainfrom
thomasmelvin:consistent_wind_metric
Open

thomasmelvin wants to merge 10 commits into
MetOffice:mainfrom
thomasmelvin:consistent_wind_metric

Conversation

@thomasmelvin

@thomasmelvin thomasmelvin commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

PR Summary

Sci/Tech Reviewer: Thomas Bendall (@tommbendall)
Code Reviewer: Matthew Walker (@mattatmet)

The application of consistent wind metric terms is detailed in Section 5.3.3 of the Cartesian Gungho paper: https://rmets.onlinelibrary.wiley.com/doi/10.1002/qj.3501 here the methodology is extended to general coordinate systems and transport schemes.

It has been shown (see references in https://rmets.onlinelibrary.wiley.com/doi/10.1002/qj.3501) that with terrain following coordinates an inconsistency can develop between the orographic gradient (dz/dx like terms) used to compute the wind along terrain following coordinates (which in lfric will use the finite element basis polynomials) and the dz/dx term in transporting a strongly height dependent term (which will use whatever reconstruction term is used in the transport scheme). This inconsistency manifests as a distortion in the orographic waves produced over orography. The solution is it modify the vertical wind term that is used to transport fields so that the dz/dx term that comes from the finite element basis polynomials is replaced by one computed using the reconstruction used in the transport scheme.

Currently this code is only tested in a few gungho tests. I have included some comparison lfric_atm tests with this turned on for reference but it is currently off by default in this PR pending further, fuller, assesment in case studies.

Scheme Schar Result
Consistent FFSL Schar-ffsl-consistent-all-fields
Inconsistent FFSL Schar-ffsl-p1XYZ
Consistent MoL Schar-mol-consistent-all-fields
Inconsistent MoL Schar-mol-p1XYZ

Code Quality Checklist

  • I have performed a self-review of my own code
  • My code follows the project's style guidelines
  • Comments have been included that aid understanding and enhance the readability of the code
  • My changes generate no new warnings
  • All automated checks in the CI pipeline have completed successfully

Testing

  • I have tested this change locally, using the LFRic Apps rose-stem suite
  • If any tests fail (rose-stem or CI) the reason is understood and acceptable (e.g. kgo changes)
  • I have added tests to cover new functionality as appropriate (e.g. system tests, unit tests, etc.)
  • Any new tests have been assigned an appropriate amount of compute resource and have been allocated to an appropriate testing group (i.e. the developer tests are for jobs which use a small amount of compute resource and complete in a matter of minutes)

trac.log

thomas.melvin@cazldf0000D5:]:>cat ../results/consistent_metrics/trac.log

Test Suite Results - lfric_apps - consistent_wind_metric/run18

Suite Information

Item Value
Suite Name consistent_wind_metric/run18
Suite User thomas.melvin
Workflow Start 2026-09-15T15:21:07
Groups Run developer
Dependency Reference Main Like
casim MetOffice/casim@2026.07.1 True
jules MetOffice/jules@2026.07.1 True
lfric_apps thomasmelvin/lfric_apps@consistent_wind_metric False
lfric_core MetOffice/lfric_core@2026.07.1 True
moci MetOffice/moci@2026.07.1 True
SimSys_Scripts MetOffice/SimSys_Scripts@2026.07.1 True
socrates MetOffice/socrates@2026.07.1 True
socrates-spectral MetOffice/socrates-spectral@2026.07.1 True
ukca MetOffice/ukca@2026.07.1 True

Task Information

✅ succeeded tasks - 1213

Security Considerations

  • I have reviewed my changes for potential security issues
  • Sensitive data is properly handled (if applicable)
  • Authentication and authorisation are properly implemented (if applicable)

Performance Impact

  • Performance of the code has been considered and, if applicable, suitable performance measurements have been conducted

AI Assistance and Attribution

  • Some of the content of this change has been produced with the assistance of Generative AI tool name (e.g., Met Office Github Copilot Enterprise, Github Copilot Personal, ChatGPT GPT-4, etc) and I have followed the Simulation Systems AI policy (including attribution labels)

Documentation

  • Where appropriate I have updated documentation related to this change and confirmed that it builds correctly

PSyclone Approval

  • If you have edited any PSyclone-related code (e.g. PSyKAl-lite, Kernel interface, optimisation scripts, LFRic data structure code) then please contact the HPC Optimisation Team

Sci/Tech Review

  • I understand this area of code and the changes being added
  • The proposed changes correspond to the pull request description
  • Documentation is sufficient (do documentation papers need updating)
  • Sufficient testing has been completed

(Please alert the code reviewer via a tag when you have approved the SR)

Code Review

  • All dependencies have been resolved
  • Related Issues have been properly linked and addressed
  • CLA compliance has been confirmed
  • Code quality standards have been met
  • Tests are adequate and have passed
  • Documentation is complete and accurate
  • Security considerations have been addressed
  • Performance impact is acceptable

@thomasmelvin

Copy link
Copy Markdown
Contributor Author

Comparison results from weekly lfric_atm suite
lfric_atm_comparison.pdf

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

Unresolved critical and moderate transport-consistency and test-compatibility issues remain.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Adds opt-in consistent wind-metric corrections for Gungho transport, including reconstruction kernels, controller integration, tests, configuration, and Rose-stem coverage.

Changes:

  • Adds cubic SL metric reconstruction and unit tests.
  • Integrates consistent-wind processing into transport control.
  • Adds configuration, tasks, and updated reference checksums.

Review findings:

  • Critical (2 votes): FFSL is incorrectly treated as cubic SL; add FFSL-specific reconstruction or reject the combination.
  • Critical (1 vote): cheap_update reinitialises the controller with uncorrected winds; reapply the correction or avoid replacing it.
  • Moderate (1 vote): A single reconstruction chosen from potential-temperature metadata is applied to fields with independently selected methods.
  • Moderate (1 vote): Consistent-wind test arguments remain r_tran after the interface changed to r_def.
  • Moderate (1 vote): Metric-kernel tests pass r_tran to r_def arguments.
  • Moderate (1 vote): The metric kernel hard-codes Nirvana reconstruction despite FFSL supporting other orders.
  • Nit (1 vote): Fix three typos: suroutines, horzontal, and componenet.
  • Nit (2 votes): Add test coverage for the dzdy path using non-zero meridional winds and varying profiles.
File summaries
File Description
science/gungho/unit-test/kernel/transport/sl/horizontal_cubic_sl_metric_kernel_mod_test.pf Tests metric reconstruction.
science/gungho/source/kernel/transport/sl/horizontal_cubic_sl_metric_kernel_mod.F90 Implements cubic SL metric gradients.
science/gungho/source/kernel/transport/sl/horizontal_cubic_sl_kernel_mod.F90 Updates copyright year.
science/gungho/source/kernel/transport/mol/consistent_wind_kernel_mod.F90 Updates consistent-wind precision and averaging.
science/gungho/source/configuration/check_configuration_mod.F90 Removes spherical-geometry validation.
science/gungho/source/algorithm/transport/mol/wt_advective_update_alg_mod.x90 Removes the legacy consistent-wind path.
science/gungho/source/algorithm/transport/control/gungho_transport_control_alg_mod.X90 Invokes consistent-wind processing.
science/gungho/source/algorithm/transport/control/consistent_wind_alg_mod.X90 Adds consistent-wind orchestration.
rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_straka_200m-alt2-BiP256x16-200x50_op_ex1a_gnu_fast-debug-64bit.txt Updates the reference checksum.
rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_schar_cart-alt2-BiP100x4-1000x1000_ex1a_gnu_fast-debug-64bit.txt Updates the reference checksum.
rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_straka_200m-alt2-BiP256x16-200x50_op_azspice_gnu_fast-debug-64bit.txt Updates the reference checksum.
rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_schar_cart-alt2-BiP100x4-1000x1000_azspice_gnu_fast-debug-64bit.txt Updates the reference checksum.
rose-stem/site/meto/groups/groups_gungho_model.cylc Adds the consistent Schär test group.
rose-stem/site/common/gungho_model/tasks_gungho_model.cylc Defines the consistent-metric task.
rose-stem/app/gungho_model/opt/rose-app-consistent_metric.conf Enables the option.
Review details

Suppressed comments (12)

science/gungho/source/algorithm/transport/control/consistent_wind_alg_mod.X90:160

  • When cheap_update_step is true, transport_controller%initialise computes the transporting wind as 0.5*(wind_np1-wind_n) (see transport_controller_mod.x90:269-273). Passing wind_adv as both arguments here therefore makes the transporting wind exactly zero, so every cheap-update outer loop performs no transport. Preserve distinct corrected n/np1 winds, or initialise with a directly corrected transporting wind instead of reusing one field for both.
    call transport_controller%finalise()
    call transport_controller%initialise(                                      &
            config, model_clock, rho_d_latest, wind_adv, wind_adv_ptr, outer,  &
            cheap_update_step                                                  &

science/gungho/source/algorithm/transport/control/consistent_wind_alg_mod.X90:142

  • For a spherical cubed-sphere mesh, the normal SL path uses horizontal_cubic_sl_sphere_kernel_type with panel and edge handling (horizontal_sl_advective_alg.x90:273-285), but this path always uses the planar CROSS2D metric kernel. Removing the former spherical-geometry validation now allows consistent_metric=.true. to compute a different, invalid horizontal metric at panel edges. Keep the restriction or provide a sphere-aware metric kernel.
      ! With SL
      call invoke(horizontal_cubic_sl_metric_kernel_type(chi3_inc, chi3, stencil_depth, wind_h) )
    end if

science/gungho/source/algorithm/transport/control/consistent_wind_alg_mod.X90:107

  • This chooses the reconstruction solely from the potential_temperature metadata, but the rebuilt controller is then used for density, wind, moisture, and tracer transports, whose metadata is selected independently and may specify different horizontal methods. In those valid per-variable configurations, the single correction cannot match every transport reconstruction. Either validate that all affected fields use a compatible method when this option is enabled, or compute method-specific corrections/controllers.
    ! Transport the height field
    call log_event( "Computing consistent vertical wind...", LOG_LEVEL_INFO)
    transport_metadata =>                                                      &
        transport_metadata_collection%get_transport_metadata('potential_temperature')

science/gungho/source/algorithm/transport/control/consistent_wind_alg_mod.X90:37

  • Correct the typo in this new comment: suroutines should be subroutines.
  ! Contained suroutines

science/gungho/source/algorithm/transport/control/consistent_wind_alg_mod.X90:110

  • Correct the typo in this new comment: horzontal should be horizontal.
    ! Split out the horzontal and vertical components of the wind

science/gungho/source/algorithm/transport/control/consistent_wind_alg_mod.X90:144

  • Correct the typo in this new comment: componenet should be component.
    ! Modify the vertical componenet of the transporting wind

science/gungho/source/algorithm/transport/control/gungho_transport_control_alg_mod.X90:336

  • The old configuration check prevented consistent_metric on spherical geometry, but this unconditional call now enables it without a spherical metric path. The invoked kernel only has a CROSS2D stencil and no panel ID/edge-distance or component-rotation inputs, whereas the normal spherical transport dispatches to panel-edge-aware kernels; cells crossing cubed-sphere panel edges will therefore use the wrong reconstructed wind. Restore the restriction or dispatch to a spherical metric implementation.
    if (consistent_metric) call consistent_wind_alg(config,               &
                                                    transport_controller, &
                                                    rho_d_latest_ptr,     &
                                                    wind_for_adv,         &
                                                    wind_np1,             &
                                                    model_clock,          &
                                                    outer,                &
                                                    cheap_update_step)

science/gungho/source/kernel/transport/mol/consistent_wind_kernel_mod.F90:119

  • Changing these field arguments from r_tran to r_def leaves consistent_wind_kernel_mod_test.pf passing real(r_tran) arrays. That test deliberately handles both 32- and 64-bit transport precision; when r_tran differs from r_def, the explicit module-procedure call is kind-mismatched and the unit-test build fails. Update the test arguments to r_def (or keep the kernel interface consistent with its callers).
  real(kind=r_def), dimension(undf_w2v), intent(inout) :: consistent_wind
  real(kind=r_def), dimension(undf_wt),  intent(in)    :: theta_metrics
  real(kind=r_def), dimension(undf_w2),  intent(in)    :: wind
  real(kind=r_def), dimension(undf_wx),  intent(in)    :: height

science/gungho/source/kernel/transport/sl/horizontal_cubic_sl_metric_kernel_mod.F90:102

  • The new kernel interface requires real(kind=r_def), but its unit test passes real(kind=r_tran) arrays, and the existing consistent_wind_kernel_mod_test.pf still does the same after that kernel was changed to r_def. The tests explicitly support r_tran differing from real64; with a differing transport precision, these explicit module-procedure calls are kind-mismatched and will not compile. Use r_def in the field arguments of these tests (or provide a matching interface).
    real(kind=r_def),   intent(inout) :: increment(undf_wf)
    real(kind=r_def),   intent(in)    :: z(undf_wf)
    real(kind=r_def),   intent(in)    :: wind(undf_w2h)

science/gungho/source/kernel/transport/sl/horizontal_cubic_sl_metric_kernel_mod.F90:116

  • The metric reconstruction is hard-coded to the Nirvana coefficients here, while FFSL selects constant, Nirvana, or PPM reconstruction from its configured order (ffsl_flux_xy_kernel_mod.F90:545-578, with orders 0, 1, and 2). With consistent_metric enabled and an FFSL order other than Nirvana, the vertical-wind correction therefore does not use the same reconstruction as the horizontal transport. Pass the configured reconstruction/order to this kernel or reject incompatible configurations.
    ! Interpolation coefficients
    real(kind=r_def), parameter :: b0 = -1.0_r_def/6.0_r_def
    real(kind=r_def), parameter :: b1 = 5.0_r_def/6.0_r_def
    real(kind=r_def), parameter :: b2 = 2.0_r_def/6.0_r_def
    real(kind=r_def), parameter :: c1 = 2.0_r_def/6.0_r_def
    real(kind=r_def), parameter :: c2 = 5.0_r_def/6.0_r_def
    real(kind=r_def), parameter :: c3 = -1.0_r_def/6.0_r_def

science/gungho/source/kernel/transport/sl/horizontal_cubic_sl_metric_kernel_mod.F90:10

  • The reconstruction name is misspelled as Nivana in both new documentation lines; use the established scheme name Nirvana.
!> @brief Compute advective increment u.grad(z) using the Nivana scheme used in
!!        the ffsl and sl transport schemes.
!> @details Compute the advective increment u.grad(z) = u*dz/dx + v*dz/dy where
!! the horizontal gradients are computed using the same reconstruction method as
!! the transport scheme (in this case Nivana).

science/gungho/unit-test/kernel/transport/sl/horizontal_cubic_sl_metric_kernel_mod_test.pf:10

  • The production metric kernel declares its field arguments as real(kind=r_def), but this test allocates the fields as r_tran. That is an explicit-interface kind mismatch when transport precision differs from default precision (and the same mismatch remains in the existing consistent-wind kernel test after its interface change), so the non-64-bit test configuration cannot reliably compile or exercise this kernel. Use the same kind as the kernel for the test fields and update the tolerance logic accordingly.
  use constants_mod, only : i_def, r_tran
  • Files reviewed: 15/15 changed files
  • Comments generated: 3
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@thomasmelvin
thomasmelvin marked this pull request as ready for review September 17, 2026 13:13
@github-actions

Copy link
Copy Markdown

⚠️ Hello thomasmelvin!

Your CLA signature was found on the base branch, but you appear to have modified the CONTRIBUTORS.md file in this PR.

Please do not edit the CONTRIBUTORS.md file. If you have already signed the CLA, revert changes to the file and your signature will be picked up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla-modified The CLA has been modified as part of this PR - added by GA

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants