Skip to content

Commit 4b622d3

Browse files
wyatt-fluidnumericsWyatt Sieminskipre-commit-ci[bot]fluidnumericsJoe
authored
Add windowarray ugrid tests (#2760)
* broke test_windowed_arrays_wraps_dask_but_not_numpy into structured and unstructured tests * Parameterized struc/unstruc tests and added unstructured advection test * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: Wyatt Sieminski <wyatt_sieminski@brown.edu> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Joe Schoonover <11430768+fluidnumericsJoe@users.noreply.github.com>
1 parent 1b1862b commit 4b622d3

1 file changed

Lines changed: 48 additions & 9 deletions

File tree

tests/test_windowed_array.py

Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from parcels import FieldSet, ParticleSet
99
from parcels._core._windowed_array import WindowedArray, maybe_windowed
1010
from parcels._datasets.structured.generated import simple_UV_dataset
11+
from parcels._datasets.unstructured.generic import _ux_constant_flow_face_centered_2D
1112
from parcels.kernels import AdvectionRK2
1213

1314

@@ -71,10 +72,17 @@ def test_windowed_isel_backward_clock_loads_once_and_evicts():
7172
assert max_cache <= 2 # only the bracketing levels resident
7273

7374

74-
def test_to_windowed_arrays_wraps_dask_but_not_numpy():
75-
ds = simple_UV_dataset(mesh="flat")
76-
fset_np = FieldSet.from_sgrid_conventions(ds, mesh="flat")
77-
fset_dk = FieldSet.from_sgrid_conventions(ds.chunk({"time": 1}), mesh="flat")
75+
@pytest.mark.parametrize(
76+
"fset_convention, ds",
77+
[
78+
(FieldSet.from_sgrid_conventions, simple_UV_dataset(mesh="flat")),
79+
(FieldSet.from_ugrid_conventions, _ux_constant_flow_face_centered_2D()),
80+
],
81+
ids=["structured", "unstructured"],
82+
)
83+
def test_windowed_arrays_wraps_dask_but_not_numpy(fset_convention: callable, ds: xr.Dataset):
84+
fset_np = fset_convention(ds, mesh="flat")
85+
fset_dk = fset_convention(ds.chunk({"time": 1}), mesh="flat")
7886

7987
# construction is never windowing -- it is opt-in via the fieldset method
8088
assert not isinstance(fset_np.U.data, WindowedArray)
@@ -92,9 +100,16 @@ def test_to_windowed_arrays_wraps_dask_but_not_numpy():
92100
assert fset_dk.U.data.shape == fset_np.U.data.shape
93101

94102

95-
def test_to_windowed_arrays_is_idempotent_and_forwards_max_levels():
96-
ds = simple_UV_dataset(mesh="flat")
97-
fs = FieldSet.from_sgrid_conventions(ds.chunk({"time": 1}), mesh="flat")
103+
@pytest.mark.parametrize(
104+
"fset_convention, ds",
105+
[
106+
(FieldSet.from_sgrid_conventions, simple_UV_dataset(mesh="flat")),
107+
(FieldSet.from_ugrid_conventions, _ux_constant_flow_face_centered_2D()),
108+
],
109+
ids=["structured", "unstructured"],
110+
)
111+
def test_to_windowed_arrays_is_idempotent_and_forwards_max_levels(fset_convention: callable, ds: xr.Dataset):
112+
fs = fset_convention(ds.chunk({"time": 1}), mesh="flat")
98113

99114
fs.to_windowed_arrays(max_levels=3)
100115
first = fs.U.data
@@ -141,10 +156,10 @@ def test_maybe_windowed_passthrough_for_non_time_leading():
141156

142157
@pytest.mark.parametrize("mesh", ["flat", "spherical"])
143158
@pytest.mark.parametrize("dt_minutes", [15, -15], ids=["forward", "backward"])
144-
def test_dask_advection_matches_numpy(mesh, dt_minutes):
159+
def test_dask_advection_matches_numpy_on_structured_grids(mesh, dt_minutes):
145160
"""An identical advection must give identical trajectories whether the field
146161
is numpy-backed or dask-backed (windowed) -- for both forward (dt > 0) and
147-
backward (dt < 0) integration.
162+
backward (dt < 0) integration on structured grids.
148163
"""
149164
ds = simple_UV_dataset(mesh=mesh)
150165
ds["U"].data[:] = 1.0 # steady zonal flow -> in-bounds, deterministic
@@ -162,3 +177,27 @@ def run(chunked):
162177
x_dk, y_dk = run(True)
163178
np.testing.assert_allclose(x_dk, x_np, atol=1e-9)
164179
np.testing.assert_allclose(y_dk, y_np, atol=1e-9)
180+
181+
182+
@pytest.mark.parametrize("mesh", ["flat", "spherical"])
183+
@pytest.mark.parametrize("dt_minutes", [15, -15], ids=["forward", "backward"])
184+
def test_dask_advection_matches_numpy_on_unstructured_grids(mesh, dt_minutes):
185+
"""An identical advection must give identical trajectories whether the field
186+
is numpy-backed or dask-backed (windowed) -- for both forward (dt > 0) and
187+
backward (dt < 0) integration on unstructured grids.
188+
"""
189+
ds = _ux_constant_flow_face_centered_2D()
190+
191+
def run(chunked):
192+
d = ds.chunk({"time": 1}) if chunked else ds
193+
fs = FieldSet.from_ugrid_conventions(d, mesh=mesh)
194+
if chunked:
195+
fs.to_windowed_arrays()
196+
pset = ParticleSet(fs, x=10 * np.ones(10), y=np.linspace(5, 15, 10))
197+
pset.execute(AdvectionRK2, runtime=3600, dt=np.timedelta64(dt_minutes, "m"))
198+
return np.array(pset.x), np.array(pset.y)
199+
200+
x_np, y_np = run(False)
201+
x_dk, y_dk = run(True)
202+
np.testing.assert_allclose(x_dk, x_np, atol=1e-9)
203+
np.testing.assert_allclose(y_dk, y_np, atol=1e-9)

0 commit comments

Comments
 (0)