Skip to content

Commit 529b143

Browse files
committed
dev
1 parent e11422d commit 529b143

File tree

2 files changed

+119
-50
lines changed

2 files changed

+119
-50
lines changed

cf/regrid/regrid.py

Lines changed: 109 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -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

94103
def 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+
20922121
def 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+
22192282
def 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 "

cf/regrid/regridoperator.py

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ def __init__(
4040
dst_axes=None,
4141
dst=None,
4242
weights_file=None,
43-
src_mesh_location=None,
43+
src_mesh_location=None,
4444
dst_mesh_location=None,
4545
):
4646
"""**Initialisation**
@@ -126,15 +126,15 @@ def __init__(
126126
127127
.. versionadded:: 3.15.2
128128
129-
src_mesh_location: `bool`, optional
130-
Whether or not the source grid is an unstructured
131-
mesh. TODOUGRID
129+
src_mesh_location: `str` or `None`, optional
130+
The UGRID mesh element of the source grid
131+
(e.g. ``'face'``), or `None` for other grids.
132132
133133
.. versionadded:: UGRIDVER
134134
135-
dst_mesh_location: `bool`, optional
136-
Whether or not the destination grid is an unstructured
137-
mesh. TODOUGRID
135+
dst_mesh_location: `str` or `None`, optional
136+
The UGRID mesh element of the destination grid
137+
(e.g. ``'face'``), or `None` for other grids.
138138
139139
.. versionadded:: UGRIDVER
140140
@@ -238,9 +238,7 @@ def dst_mask(self):
238238

239239
@property
240240
def dst_mesh_location(self):
241-
"""Whether or not the destination grid is an unstructured mesh.
242-
243-
TODOUGRID
241+
"""The UGRID mesh element of the destination grid.
244242
245243
.. versionadded:: UGRIDVER
246244
@@ -342,8 +340,8 @@ def src_mask(self):
342340

343341
@property
344342
def src_mesh_location(self):
345-
"""Whether or not the source grid is an unstructured mesh.
346-
TODOUGRID
343+
"""The UGRID mesh element of the source grid.
344+
347345
.. versionadded:: UGRIDVER
348346
349347
"""

0 commit comments

Comments
 (0)