Skip to content

Commit 4035447

Browse files
Merge pull request #1999 from OceanParcels/remove-time-extrapolation-option
Remove allow_time_extrapolation attribute on Field
2 parents 277038c + 1d44b69 commit 4035447

4 files changed

Lines changed: 22 additions & 16 deletions

File tree

parcels/_index_search.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
# from .grid import Grid
2626

2727

28-
def _search_time_index(field: Field, time: datetime, allow_time_extrapolation=True):
28+
def _search_time_index(field: Field, time: datetime):
2929
"""Find and return the index and relative coordinate in the time array associated with a given time.
3030
3131
Parameters
@@ -37,8 +37,12 @@ def _search_time_index(field: Field, time: datetime, allow_time_extrapolation=Tr
3737
Note that we normalize to either the first or the last index
3838
if the sampled value is outside the time value range.
3939
"""
40-
if not allow_time_extrapolation and (time < field.data.time[0] or time > field.data.time[-1]):
40+
if field.time_interval is None:
41+
return 0
42+
43+
if time in field.time_interval:
4144
_raise_time_extrapolation_error(time, field=None)
45+
4246
time_index = field.data.time <= time
4347

4448
if time_index.all():

parcels/field.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,6 @@ def __init__(
148148
grid: ux.Grid | Grid,
149149
mesh_type: Mesh = "flat",
150150
interp_method: Callable | None = None,
151-
allow_time_extrapolation: bool | None = None,
152151
):
153152
if not isinstance(data, (ux.UxDataArray, xr.DataArray)):
154153
raise ValueError(
@@ -209,10 +208,8 @@ def __init__(
209208
else:
210209
raise ValueError("Unsupported mesh type in data array attributes. Choose either: 'spherical' or 'flat'")
211210

212-
if allow_time_extrapolation is None:
213-
self.allow_time_extrapolation = True if len(getattr(self.data, "time", [])) == 1 else False
214-
else:
215-
self.allow_time_extrapolation = allow_time_extrapolation
211+
if "time" not in self.data.dims:
212+
raise ValueError("Field is missing a 'time' dimension. ")
216213

217214
def __repr__(self):
218215
return field_repr(self)
@@ -366,7 +363,7 @@ def _search_indices_structured(self, z, y, x, ei=None, search2D=False):
366363
return (zeta, eta, xsi, zi, yi, xi)
367364

368365
def _search_indices(self, time: datetime, z, y, x, ei=None, search2D=False):
369-
tau, ti = _search_time_index(self, time, self.allow_time_extrapolation)
366+
tau, ti = _search_time_index(self, time)
370367

371368
if ei is None:
372369
_ei = None
@@ -679,7 +676,7 @@ def _assert_compatible_combination(data: xr.DataArray | ux.UxDataArray, grid: ux
679676

680677

681678
def get_time_interval(data: xr.DataArray | ux.UxDataArray) -> TimeInterval | None:
682-
if "time" not in data.dims:
679+
if len(data.time) == 1:
683680
return None
684681

685682
return TimeInterval(data.time.values[0], data.time.values[-1])

parcels/fieldset.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,14 +164,15 @@ def add_constant_field(self, name: str, value, mesh: Mesh = "flat"):
164164
"""
165165
da = xr.DataArray(
166166
data=np.full((1, 1, 1, 1), value),
167-
dims=["T", "ZG", "YG", "XG"],
167+
dims=["time", "ZG", "YG", "XG"],
168168
coords={
169169
"ZG": (["ZG"], np.arange(1), {"axis": "Z"}),
170170
"YG": (["YG"], np.arange(1), {"axis": "Y"}),
171171
"XG": (["XG"], np.arange(1), {"axis": "X"}),
172172
"lon": (["XG"], np.arange(1), {"axis": "X"}),
173173
"lat": (["YG"], np.arange(1), {"axis": "Y"}),
174174
"depth": (["ZG"], np.arange(1), {"axis": "Z"}),
175+
"time": (["time"], np.arange(1), {"axis": "T"}),
175176
},
176177
)
177178
grid = Grid(da)
@@ -253,6 +254,10 @@ class CalendarError(Exception): # TODO: Move to a parcels errors module
253254

254255
def assert_compatible_calendars(fields: Iterable[Field]):
255256
time_intervals = [f.time_interval for f in fields if f.time_interval is not None]
257+
258+
if len(time_intervals) == 0: # All time intervals are none
259+
return
260+
256261
reference_datetime_object = time_intervals[0].left
257262

258263
for field in fields:

parcels/particleset.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
from tqdm import tqdm
1212

1313
from parcels._compat import MPI
14+
from parcels._core.utils.time import TimeInterval
1415
from parcels._reprs import particleset_repr
1516
from parcels.application_kernels.advection import AdvectionRK4
16-
from parcels.field import Field
1717
from parcels.grid import GridType
1818
from parcels.interaction.interactionkernel import InteractionKernel
1919
from parcels.interaction.neighborsearch import (
@@ -162,8 +162,8 @@ def ArrayClass_init(self, *args, **kwargs):
162162
raise NotImplementedError("If fieldset.time_origin is not a date, time of a particle must be a double")
163163
time = np.array([self.time_origin.reltime(t) if _convert_to_reltime(t) else t for t in time])
164164
assert lon.size == time.size, "time and positions (lon, lat, depth) do not have the same lengths."
165-
if isinstance(fieldset.U, Field) and (not fieldset.U.allow_time_extrapolation):
166-
_warn_particle_times_outside_fieldset_time_bounds(time, fieldset.U.grid.time)
165+
if fieldset.time_interval:
166+
_warn_particle_times_outside_fieldset_time_bounds(time, fieldset.time_interval)
167167

168168
if lonlatdepth_dtype is None:
169169
lonlatdepth_dtype = self.lonlatdepth_dtype_from_field_interp_method(fieldset.U)
@@ -1127,17 +1127,17 @@ def _warn_outputdt_release_desync(outputdt: float, starttime: float, release_tim
11271127
)
11281128

11291129

1130-
def _warn_particle_times_outside_fieldset_time_bounds(release_times: np.ndarray, time: np.ndarray):
1130+
def _warn_particle_times_outside_fieldset_time_bounds(release_times: np.ndarray, time: np.ndarray | TimeInterval):
11311131
if np.any(release_times):
11321132
if np.any(release_times < time[0]):
11331133
warnings.warn(
1134-
"Some particles are set to be released before the fieldset's first time and allow_time_extrapolation is set to False.",
1134+
"Some particles are set to be released outside the FieldSet's executable time domain.",
11351135
ParticleSetWarning,
11361136
stacklevel=2,
11371137
)
11381138
if np.any(release_times > time[-1]):
11391139
warnings.warn(
1140-
"Some particles are set to be released after the fieldset's last time and allow_time_extrapolation is set to False.",
1140+
"Some particles are set to be released after the fieldset's last time and the fields are not constant in time.",
11411141
ParticleSetWarning,
11421142
stacklevel=2,
11431143
)

0 commit comments

Comments
 (0)