@@ -85,10 +85,19 @@ class Grid:
8585 # for a 2-d grid for which one of the dimensions is a size 2 dummy
8686 # dimension.
8787 dummy_size_2_dimension : bool = False
88- # Whether or not the grid is a UGRID mesh topology.
89- mesh : bool = False
88+ # The location on a UGRID mesh topology of the grid cells. An
89+ # empty string means that the grid is not a UGRID mesh
90+ # topology. E.g. '' or 'face'.
91+ mesh_location : str = ""
9092 # Only used if `mesh` is True. TODOUGRID
9193 domain_topology : Any = None
94+ # The domain axis identifiers of new axes resulting from the
95+ # regridding having changed the number of data axes (e.g. by
96+ # regridding a source UGRID grid to a destination non-UGRID grid,
97+ # or vice versa). An empty list means that the regridding did not
98+ # change the number of data axes. E.g. [], ['domainaxis3',
99+ # 'domainaxis4'], ['domainaxis4']
100+ new_axis_keys : list = field (default_factory = list )
92101
93102
94103def regrid (
@@ -529,8 +538,6 @@ def regrid(
529538 min_weight = min_weight ,
530539 )
531540
532- # TODOUGRID del src data mesh
533-
534541 # ----------------------------------------------------------------
535542 # Update the regridded metadata
536543 # ----------------------------------------------------------------
@@ -543,7 +550,7 @@ def regrid(
543550 # ----------------------------------------------------------------
544551 # Insert regridded data into the new field
545552 # ----------------------------------------------------------------
546- src . set_data ( regridded_data , axes = src . get_data_axes (), copy = False )
553+ update_data ( src , regridded_data , src_grid )
547554
548555 if coord_sys == "spherical" and not src_grid .mesh :
549556 # Set the cyclicity of the longitude axis of the new field
@@ -801,7 +808,7 @@ def spherical_grid(f, name=None, method=None, cyclic=None, axes=None):
801808 aux_coords_2d = False
802809 aux_coords_1d = False
803810 domain_topology = None
804- mesh_location = None
811+ mesh_location = ""
805812
806813 # Look for 1-d X and Y dimension coordinates
807814 lon_key_1d , lon_1d = f .dimension_coordinate (
@@ -1935,7 +1942,7 @@ def get_bounds(method, coords, mesh_location):
19351942 coords: sequence of `Coordinate`
19361943 The coordinates that define an `esmpy.Grid`.
19371944
1938- mesh_location: `str` or `None`
1945+ mesh_location: `str`
19391946 TODOUGRID
19401947
19411948 .. versionadded:: UGRIDVER
@@ -2048,47 +2055,69 @@ def update_coordinates(src, dst, src_grid, dst_grid):
20482055 src_axis_keys = src_grid .axis_keys
20492056 dst_axis_keys = dst_grid .axis_keys
20502057
2051- # Remove the source coordinates of new field
2052- for key in src .coordinates (
2053- filter_by_axis = src_axis_keys , axis_mode = "or" , todict = True
2058+ # Remove the source coordinate, domain topology and cell
2059+ # connectivity from new field.
2060+ for key in src .constructs (
2061+ filter_by_type = ("dimension_coordinate" ,
2062+ "auxiliary_coordinate" ,
2063+ "domain_topology" ,
2064+ "cell_connectivity" ),
2065+ filter_by_axis = src_axis_keys ,
2066+ axis_mode = "or" ,
2067+ todict = True
20542068 ):
20552069 src .del_construct (key )
20562070
20572071 # Domain axes
20582072 src_domain_axes = src .domain_axes (todict = True )
20592073 dst_domain_axes = dst .domain_axes (todict = True )
2060- # TODOUGRID: if src grid is mesh and dst grid is not then
2061- # src_axis_keys and dst_axis_keys might have different lengths
2062- # (and vice versa)
2063- for src_axis , dst_axis in zip (src_axis_keys , dst_axis_keys ):
2064- src_domain_axis = src_domain_axes [src_axis ]
2065- dst_domain_axis = dst_domain_axes [dst_axis ]
2066-
2067- src_domain_axis .set_size (dst_domain_axis .size )
2068-
2069- ncdim = dst_domain_axis .nc_get_dimension (None )
2070- if ncdim is not None :
2071- src_domain_axis .nc_set_dimension (ncdim )
2072-
2073- if len (src_axis_keys ) == 1 and len (dst_axis_keys ) == 2 :
2074- src .del_construct (src_axis_keys [0 ]) # # what about other constructs spanningthis axis?
2075- xaxis = src .set_construct (Domain (dst_domain_axes [dst_axis_keys [0 ]].size ))
2076- yaxis = src .set_construct (Domain (dst_domain_axes [dst_axis_keys [1 ]].size ))
2077-
2078- # Coordinates
2074+ if len (src_axis_keys ) != len (dst_axis_keys ) :
2075+ for src_axis , dst_axis in zip (src_axis_keys , dst_axis_keys ):
2076+ src_domain_axis = src_domain_axes [src_axis ]
2077+ dst_domain_axis = dst_domain_axes [dst_axis ]
2078+
2079+ src_domain_axis .set_size (dst_domain_axis .size )
2080+
2081+ ncdim = dst_domain_axis .nc_get_dimension (None )
2082+ if ncdim is not None :
2083+ src_domain_axis .nc_set_dimension (ncdim )
2084+ else :
2085+ # The regridding has changed the number of data axes (e.g. by
2086+ # regridding a source mesh grid to a destination non-mesh
2087+ # grid, or vice versa).
2088+ src_axis_keys = [
2089+ src .set_construct ( dst_domain_axes [dst_axis ].copy ())
2090+ for dst_axis in dst_axis_keys
2091+ ]
2092+ src_grid .new_axis_keys = src_axis_keys
2093+
2094+ # Coordinates constructs
20792095 axis_map = {
20802096 dst_axis : src_axis
20812097 for dst_axis , src_axis in zip (dst_axis_keys , src_axis_keys )
20822098 }
20832099 dst_data_axes = dst .constructs .data_axes ()
20842100
2085- for key , aux in dst .coordinates (
2101+ for key , coord in dst .coordinates (
20862102 filter_by_axis = dst_axis_keys , axis_mode = "subset" , todict = True
20872103 ).items ():
20882104 axes = [axis_map [axis ] for axis in dst_data_axes [key ]]
2089- src .set_construct (aux , axes = axes )
2105+ src .set_construct (coord , axes = axes )
2106+
2107+ # Domain topology and cell connectivity constructs
2108+ if dst_grid .mesh_location :
2109+ for key , topology in dst .constructs (
2110+ filter_by_type = ("domain_topology" , "cell_connectivity" ),
2111+ filter_by_axis = dst_axis_keys ,
2112+ axis_mode = "exact" ,
2113+ todict = True
2114+ ).items ():
2115+ axes = [axis_map [axis ] for axis in dst_data_axes [key ]]
2116+ src .set_construct (topology , axes = axes )
20902117
20912118
2119+
2120+
20922121def update_non_coordinates (
20932122 src , dst , regrid_operator , src_grid = None , dst_grid = None
20942123):
@@ -2138,14 +2167,18 @@ def update_non_coordinates(
21382167 src .del_coordinate_reference (ref_key )
21392168
21402169 # ----------------------------------------------------------------
2141- # Delete source grid cell measures and field ancillaries that span
2142- # any of the regridding axes
2170+ # Delete source grid cell measure and field ancillary constructs
2171+ # that span any of the regridding axes.
21432172 # ----------------------------------------------------------------
21442173 for key in src .constructs (
2145- filter_by_type = ("cell_measure" , "field_ancillary" ), todict = True
2174+ filter_by_type = ("cell_measure" ,
2175+ "field_ancillary" ),
2176+ filter_by_axis = src_axis_keys ,
2177+ axis_mode = "or" ,
2178+ todict = True
21462179 ):
2147- if set (data_axes [key ]).intersection (src_axis_keys ):
2148- src .del_construct (key )
2180+ # if set(data_axes[key]).intersection(src_axis_keys):
2181+ src .del_construct (key )
21492182
21502183 # ----------------------------------------------------------------
21512184 # Regrid any remaining source domain ancillaries that span all of
@@ -2216,13 +2249,51 @@ def update_non_coordinates(
22162249 if axes and set (axes ).issubset (dst_axis_keys ):
22172250 src .set_coordinate_reference (ref , parent = dst , strict = True )
22182251
2252+
2253+ def update_data (src , regridded_data , src_grid ):
2254+ """TODOUGRID
2255+
2256+ .. versionadded:: UGRIDVER
2257+
2258+ .. seealso: `update_coordinates`, `update_non_coordinates`
2259+
2260+ :Parameters:
2261+
2262+ :Returns:
2263+
2264+ """
2265+ data_axes = src .get_data_axes ()
2266+
2267+ if src_grid .new_axis_keys :
2268+ # The regridding has changed the number of data axes (e.g. by
2269+ # regridding a source UGRID grid to a destination non-UGRID
2270+ # grid, or vice versa).
2271+ data_axes = list (data_axes )
2272+ index = data_axes .index (src_grid .axes_keys [0 ])
2273+ for axis in src_grid .axes_keys :
2274+ data_axes .remove (axis )
2275+ src .del_construct (axis )
2276+
2277+ data_axes [index :index ] = src_grid .new_axis_keys
2278+
2279+ src .set_data (regridded_data , axes = data_axes , copy = False )
2280+
2281+
22192282def ffff (f , name ):
2220- """TODOUGRID"""
2283+ """TODOUGRID
2284+
2285+ .. versionadded:: UGRIDVER
2286+
2287+ :Parameters:
2288+
2289+ :Returns:
2290+
2291+ """
22212292 key , domain_topology = f .domain_topology (item = True , default = (None , None ))
22222293 if domain_topology is None :
22232294 return (None , None , None )
22242295
2225- mesh_location = domain_topology .get_cell (None )
2296+ mesh_location = domain_topology .get_cell ("" )
22262297 if mesh_location != "face" :
22272298 raise ValueError (
22282299 "Can't regrid when the {name} grid is an unstructured mesh "
0 commit comments