UXARRAY / uxarray

Xarray-styled package for reading and directly operating on unstructured grid datasets following UGRID conventions
https://uxarray.readthedocs.io/
Apache License 2.0
142 stars 31 forks source link

Support ICON Grids #773

Open philipc2 opened 2 months ago

philipc2 commented 2 months ago

Proposed new feature or change: Add support for encoding ICON grids in the UGRID conventions

There have been many community requests to support the ICON grid format. Some work has already been made in https://github.com/jcanton/icon_uxarray

The ICON format is similar to MPAS grids.

References

https://mpimet.mpg.de/en/research/modeling

https://www.ecmwf.int/sites/default/files/elibrary/2004/14151-icon-project-design-and-performance-unstructured-grid-approach-global-triangular-grid-model.pdf

https://scivis2017.dkrz.de/hd-cp-2/en-icon_grid.pdf

egparedes commented 2 months ago

Hi Philip and thank you for opening this issue.

In the ETH EXCLAIM project we are interested in using UXarray with the ICON grid (the mentioned icon_uxarray repo belongs to Jacopo Canton, researcher at EXCLAIM). We think that basic support for loading the ICON grid with UXarray does not involve a lot of work: it basically requires renaming variables and translating connectivities from 1-based indexing to 0-based indexing, and UGRID conventions in theory support both features.

In the linked repo, the translation of the connectivities is done by manually shifting the indices, because this feature was not implemented in UXarray when we first tried some months ago. If this feature is still missing, you might want to take a look to a minimal implementation I quickly drafted here: https://github.com/egparedes/uxarray/commit/f8424c1d68d4f852f46e1d98460415ec892faaad

Using that branch, loading the ICON grid file could be simplified to roughly something like this:

grid_file = "icon_grid_file.nc"
grid_ds = xr.open_dataset(grid_file)

for var in grid_ds.values():
    if var.dtype == np.dtype(np.int32):
        var.attrs["start_index"] = 1

grid_ds["mesh"] = xr.DataArray(
    -1, # A dummy value for creating the DataArray with the actual attributes
    attrs=dict(
        cf_role="mesh_topology",
        topology_dimension=2,
        node_coordinates="vlon vlat",
        edge_dimension="edge",
        edge_node_connectivity="edge_vertices",
        edge_coordinates="elon elat",
        face_dimension="cell",
        face_coordinates="clon clat",
        face_node_connectivity="vertex_of_cell",
        face_edge_connectivity="edge_of_cell",
        face_face_connectivity="neighbor_cell_index",
        edge_face_connectivity="adjacent_cell_of_edge",
    ),
)

ugrid = ux.open_grid(grid_ds)
ugrid.validate()

I could open a PR with those changes, if you are interested but I'm not actively working on this anymore. For questions about handling the ICON grid in Python, I think @halungge would be the most appropriate contact person from our team.

philipc2 commented 2 months ago

Hi @egparedes

Thanks for sharing this! This'll be extremely helpful. I'll be working on this in #774

Would you happen to have any small datasets I could use for testing?

halungge commented 1 month ago

A lot of standard ICON grid files can be downloaded from MPI-M here The smallest ones being the R02B04 and R02B05 with 160km and 80km resolution globally. (The R and B parameters describe the construction of the idosahedral grid)

halungge commented 1 month ago

As you mention above the ICON grid is similar to MPAS, (the dual and primal grids being somehow inverted) as I understand, the model itself does not use a lot of the dual grid (hexagons for ICON) anymore. So far we only experimented with using the UGRID conventions on the triangle mesh, I once started an experiment "loading an icon grid as an MPAs grid type with uxarray" but got distracted...