Skip to content

Commit fcffbbb

Browse files
Fix combining Fields with and without time in one FieldSet (#2741)
* Adding unit test to show combining fields with and without time doesn't currently work * Support for time_interval=None for individual fields * Remove time from kernelloop explanation
1 parent 4b622d3 commit fcffbbb

4 files changed

Lines changed: 22 additions & 7 deletions

File tree

docs/user_guide/examples/explanation_kernelloop.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,14 @@ import parcels.tutorial
5959
ds_fields = parcels.tutorial.open_dataset("CopernicusMarine_data_for_Argo_tutorial/data")
6060
6161
# Create an idealised wind field and add it to the dataset
62-
tdim, ydim, xdim = (len(ds_fields.time),len(ds_fields.latitude), len(ds_fields.longitude))
62+
ydim, xdim = len(ds_fields.latitude), len(ds_fields.longitude)
6363
ds_fields["UWind"] = xr.DataArray(
64-
data=0.5 * np.ones((tdim, ydim, xdim)) * np.sin(ds_fields.latitude.values - ds_fields.latitude.values.mean())[None, :, None],
65-
coords=[ds_fields.time, ds_fields.latitude, ds_fields.longitude])
64+
data=0.5 * np.ones((ydim, xdim)) * np.sin(ds_fields.latitude.values - ds_fields.latitude.values.mean())[:, None],
65+
coords=[ds_fields.latitude, ds_fields.longitude])
6666
6767
ds_fields["VWind"] = xr.DataArray(
68-
data=np.zeros((tdim, ydim, xdim)),
69-
coords=[ds_fields.time, ds_fields.latitude, ds_fields.longitude])
68+
data=np.zeros((ydim, xdim)),
69+
coords=[ds_fields.latitude, ds_fields.longitude])
7070
7171
fields = {
7272
"U": ds_fields["uo"],

src/parcels/_core/field.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,9 @@ def grid(self): # TODO PR: Remove in favour of referencing model grid directly
109109

110110
@property
111111
def time_interval(self): # TODO PR: Remove in favour of referencing model time_interval directly
112+
if "time" not in self.model.data[self.name].dims:
113+
# This field does not have a time-dimension
114+
return None
112115
return self.model.time_interval
113116

114117
def __repr__(self):

src/parcels/_core/index_search.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ def _search_time_index(field: Field, time: np.ndarray):
7777
if field.time_interval is None:
7878
return {
7979
"T": {
80-
"index": np.zeros(shape=time.shape, dtype=np.int32),
81-
"bcoord": np.zeros(shape=time.shape, dtype=np.float32),
80+
"index": np.zeros(shape=np.atleast_1d(time).shape, dtype=np.int32),
81+
"bcoord": np.zeros(shape=np.atleast_1d(time).shape, dtype=np.float32),
8282
}
8383
}
8484

tests/test_fieldset.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import numpy as np
77
import pandas as pd
88
import pytest
9+
import xarray as xr
910

1011
import parcels.tutorial
1112
from parcels import Field, ParticleFile, ParticleSet, XGrid, convert, open_raw_zarr
@@ -360,6 +361,17 @@ def test_fieldset_add():
360361
assert set(fields_before) == set(fset.fields.keys())
361362

362363

364+
def test_vectorfields_without_time():
365+
"""Test that vector fields without a time dimension can be evaluated."""
366+
ds1 = datasets_structured["ds_2d_left"][["U_A_grid", "V_A_grid", "grid"]].rename({"U_A_grid": "U", "V_A_grid": "V"})
367+
ds2 = ds1.isel(time=0).drop_vars("time").rename({"U": "U_const", "V": "V_const"})
368+
ds = xr.merge([ds1, ds2])
369+
370+
fset = FieldSet.from_sgrid_conventions(ds, mesh="flat", vector_fields={"UV_const": ("U_const", "V_const")})
371+
fset.UV_const.eval(t=0, z=0, y=0, x=0)
372+
fset.U_const.eval(t=0, z=0, y=0, x=0)
373+
374+
363375
def test_fieldset_add_error_on_duplicate_context_values():
364376
"""Test that adding FieldSets with overlapping context value names raises a ValueError."""
365377
ds1 = datasets_structured["ds_2d_left"][["U_A_grid", "grid"]].rename({"U_A_grid": "U1"})

0 commit comments

Comments
 (0)