Skip to content

#369: Allow coarse-grid fields with ndata levels: vn3.1 read coarse 2d#369

Open
Mohit Dalvi (mcdalvi) wants to merge 6 commits into
MetOffice:mainfrom
mcdalvi:vn3.1_read_coarse_2d
Open

#369: Allow coarse-grid fields with ndata levels: vn3.1 read coarse 2d#369
Mohit Dalvi (mcdalvi) wants to merge 6 commits into
MetOffice:mainfrom
mcdalvi:vn3.1_read_coarse_2d

Conversation

@mcdalvi
Copy link
Copy Markdown

@mcdalvi Mohit Dalvi (mcdalvi) commented May 12, 2026

PR Summary

Sci/Tech Reviewer: Thomas Bendall (@tommbendall)
Code Reviewer: Matthew Hambley (@MatthewHambley)

This PR introduces the ability to define a LFRic field as coarse 2-D grid x ndata levels.
Currently trying to define a field as e.g. 'multigrid_l2' twod=.true. and ndata=XX leads to XIOS error searching for domain definitions for multigrid_l2_2d_face that does not exist.
This change allows a TWOD field not on the primary mesh to use the prime-mesh parameters for the 'face'/ domain, combined with user ndata levels (and time_axis).

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 Core rose-stem suite
  • If required (e.g. API changes) I have also run the LFRic Apps test suite using this branch
  • 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

Test Suite Results - lfric_core - vn3.1_read_coarse_2d/run1

Suite Information

Item Value
Suite Name vn3.1_read_coarse_2d/run1
Suite User mohit.dalvi
Workflow Start 2026-05-13T14:52:38
Groups Run all
Dependency Reference Main Like
lfric_core mcdalvi/lfric_core@vn3.1_read_coarse_2d False
SimSys_Scripts MetOffice/SimSys_Scripts@cab3315 True

Task Information

✅ succeeded tasks - 402

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 TCD 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

@github-actions github-actions Bot added the cla-required The CLA has not yet been signed by the author of this PR - added by GA label May 12, 2026
@mcdalvi Mohit Dalvi (mcdalvi) changed the title Vn3.1 read coarse 2d #369: Allow coarse-grid fields with ndata levels: vn3.1 read coarse 2d May 12, 2026
@mcdalvi Mohit Dalvi (mcdalvi) added the Linked Apps This PR is linked to a MetOffice/lfric_apps PR label May 12, 2026
@mcdalvi Mohit Dalvi (mcdalvi) added this to the Summer 2026 milestone May 12, 2026
@github-actions github-actions Bot added cla-signed The CLA has been signed as part of this PR - added by GA and removed cla-required The CLA has not yet been signed by the author of this PR - added by GA labels May 12, 2026
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Science Review

This is a simple PR to support the work to implement nudging of LFRic to ERA or AIFS data. It fixes a bug which allows us to read in data on a coarse 2D mesh.

I'm happy to approve this as is.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This is a small change but may have large implications.

Comment on lines +282 to +284
if ( mesh%get_extrusion_id() == TWOD ) then
mesh => mesh_collection%get_mesh_variant( mesh, PRIME_EXTRUSION )
end if
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

My concern here is that this seems to be very specific behaviour to address a problem the developer is tackling. What happens when someone passes a field, on a 2D mesh, and they expect to read data on a 2D mesh, not the 3D prime mesh?

I would guess that no one is doing that at the moment, otherwise testing would have failed. What guarantee do we have that no one is ever going to want to do that?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think the implications are less than you fear! We currently read 2D fields in all the time successfully, but until now have never tried to read in a coarse 2D field. So the change here relates to a confusing aspect to how our XIOS interface works for fields on different meshes...


Brief Interlude

We can consider meshes by their local mesh and their extrusion:

Prime extrusion 2D (1 layer)
Prime IO local mesh (generally our finest resolution mesh, used by the dynamics) 3D Prime mesh 2D Prime mesh
Other local mesh (e.g. used for multigrid, or now spectral nudging) 3D other mesh 2D other mesh (until now IO has not been tested on this mesh)

This portion of code sets up the dimensions up for XIOS. Line 267 is the top of this section:

 if (prime_io_mesh_is(mesh)) then

Confusingly, the prime_io_mesh_is function effectively checks on the local mesh, so returns true for 2D Prime fields. Any field with a prime local mesh uses a set of generic dimension names in the XIOS interface.

However, for any field not on the prime local mesh, the name of the mesh is appended to the dimensions used by XIOS. But in LFRic, the name of a "2D other mesh" is different to that of a "3D other mesh" -- however XIOS needs them to have the same horizontal dimensions, so the same name should be passed. Mohit's PR fixes that, and doesn't create problems for any existing 2D fields.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why is the name of the local meshes attached to (prime/2d) extruded 3d meshes (prime/2d) not the same? I'm not familiar with this area (Ed Hone (@EdHone) might be better placed to comment). Though I'd agree with Matthew Hambley (@MatthewHambley) concerns, the change here may well work though really doesn't seem to be appropriate here.

If the name other 2D other "local" mesh is not the same as the 3D other "local" mesh, then it would be better to make them the same. This would seem more sensible.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The fix in this PR makes sure that they do use the same name, so it addresses the problem you just described!

Copy link
Copy Markdown
Contributor

@mo-rickywong Ricky Wong (mo-rickywong) May 21, 2026

Choose a reason for hiding this comment

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

I think the fix should be that the 3D mesh (of one layer) with a 2D extrusion, should have same local_mesh name as the 3D mesh of the prime extrusion. The fix here is not doing that. it appears to be forcing lfric_xios to use an instance of a mesh different to the one passed in.

Comment on lines +282 to 286
if ( mesh%get_extrusion_id() == TWOD ) then
mesh => mesh_collection%get_mesh_variant( mesh, PRIME_EXTRUSION )
end if
if ( fs_id == W3 ) then
call xios_get_domain_attr( trim(adjustl(mesh%get_mesh_name()))//"_face", ni=domain_size )
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
if ( mesh%get_extrusion_id() == TWOD ) then
mesh => mesh_collection%get_mesh_variant( mesh, PRIME_EXTRUSION )
end if
if ( fs_id == W3 ) then
call xios_get_domain_attr( trim(adjustl(mesh%get_mesh_name()))//"_face", ni=domain_size )
! To set up XIOS domain for non-prime meshes, need to use "local" mesh name
! However the current mesh variable may be a 2D mesh, so to get "local" mesh
! name, first fetch the prime extrusion mesh
if ( mesh%get_extrusion_id() == TWOD ) then
prime_extrusion_mesh => mesh_collection%get_mesh_variant( mesh, PRIME_EXTRUSION )
local_mesh_name = prime_extrusion_mesh%get_mesh_name()
else
local_mesh_name = mesh%get_mesh_name()
end if
if ( fs_id == W3 ) then
call xios_get_domain_attr( trim(adjustl(local_mesh_name))//"_face", ni=domain_size )

Ricky Wong (@mo-rickywong) and Matthew Hambley (@MatthewHambley)
OK -- I think I understand your concerns. How about something like this, introducing a local_mesh_name variable? It makes it clear what the mesh variable was actually being used for here

Copy link
Copy Markdown
Contributor

@mo-rickywong Ricky Wong (mo-rickywong) May 21, 2026

Choose a reason for hiding this comment

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

I must be missing something, afaik(which may well be wrong), you need the local_mesh_name as xios writes/reads in 2d horizontal slices i.e. actual 2d-meshes (not a single-layer 3d mesh). For extrusions based on the same local mesh the local mesh name should be the same between the prime_extrusion/2d-extrusion no matter which mesh(prime or otherwise) is passed in.. Ideally something along the lines of:

mesh       => field_proxy%vspace%get_mesh()
local_mesh => mesh%get_local_mesh()
local_mesh_name = local_mesh%get_mesh_name()

I don't know why there is a test to check if it's on the prime mesh (Ed Hone (@EdHone) would know), though ideally you'd want to read from the field_proxy passed irrespective of the extrusion or mesh.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks Ricky. So until now we have been using the name of the 3D prime extrusion mesh -- if that's the same as the name of the local_mesh then I'm happy that what you've suggested is the right fix

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Not necessarily. If say, you read in a C24 from the mesh file, then the global mesh name will be C24. I you only have one 3d-mesh to run on in the model then it will be just the same name throughout i.e.

1 x Global mesh : C24
1 x Local mesh: C24
1 x 3D-Mesh: C24 (extruded using extrusion A)

However, you will most likely have multiple extrusions of the same local mesh in a run, i.e. single-layer, model-layers, so they can't all be called C24. So for the above case, but with multiple extrusions.

  • 3D-Mesh_Bert (extrusion A) uses local mesh C24
  • 3D-Mesh_Bob (extrusion B) uses local mesh C24
  • 3D-Mesh_Sally(extrusion C) uses local mesh C24

So its not the name of the 3D mesh you want to be using, its the common local_mesh_name, this is more consistent with XIOS anyway as it only cares about a horizontal slice, i.e. the local mesh your 3D mesh is based on.

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

Labels

cla-signed The CLA has been signed as part of this PR - added by GA Linked Apps This PR is linked to a MetOffice/lfric_apps PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants