#369: Allow coarse-grid fields with ndata levels: vn3.1 read coarse 2d#369
#369: Allow coarse-grid fields with ndata levels: vn3.1 read coarse 2d#369Mohit Dalvi (mcdalvi) wants to merge 6 commits into
Conversation
…a) coarse mesh field, as horiz dimensions should match
Thomas Bendall (tommbendall)
left a comment
There was a problem hiding this comment.
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.
Matthew Hambley (MatthewHambley)
left a comment
There was a problem hiding this comment.
This is a small change but may have large implications.
| if ( mesh%get_extrusion_id() == TWOD ) then | ||
| mesh => mesh_collection%get_mesh_variant( mesh, PRIME_EXTRUSION ) | ||
| end if |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
The fix in this PR makes sure that they do use the same name, so it addresses the problem you just described!
There was a problem hiding this comment.
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.
| 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 ) |
There was a problem hiding this comment.
| 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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
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
Testing
trac.log
Test Suite Results - lfric_core - vn3.1_read_coarse_2d/run1
Suite Information
Task Information
✅ succeeded tasks - 402
Security Considerations
Performance Impact
AI Assistance and Attribution
Documentation
PSyclone Approval
Sci/Tech Review
(Please alert the code reviewer via a tag when you have approved the SR)
Code Review