Skip to content

Commit 797d95d

Browse files
Merge remote-tracking branch 'origin/benchmarking-running-bugs' into particle_time_as_float
2 parents e6b4f05 + 5a7d7d2 commit 797d95d

5 files changed

Lines changed: 31 additions & 6 deletions

File tree

parcels/_index_search.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ def _search_time_index(field: Field, time: datetime):
3939
"""
4040
ti = np.argmin(field._time_float <= time) - 1
4141
tau = (time - field._time_float[ti]) / (field._time_float[ti + 1] - field._time_float[ti])
42+
if tau < 0 or tau > 1: # TODO only for debugging; test can go?
43+
raise ValueError(f"Time {time} is out of bounds for field time data {field.data.time.data}.")
4244
return tau, ti
4345

4446

parcels/field.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,19 @@ def _check_velocitysampling(self):
246246
stacklevel=2,
247247
)
248248

249+
def _load_timesteps(self, time):
250+
"""Load the appropriate timesteps of a field."""
251+
ti = np.argmin(self._time_float <= time) - 1 # TODO also implement dt < 0
252+
if not hasattr(self, "data"):
253+
self.data = self.data_full.isel({"time": slice(ti, ti + 2)}).load()
254+
elif self.data_full.time.data[ti] == self.data.time.data[1]:
255+
self.data = xr.concat([self.data[1, :], self.data_full.isel({"time": ti + 1}).load()], dim="time")
256+
elif self.data_full.time.data[ti] != self.data.time.data[0]:
257+
self.data = self.data_full.isel({"time": slice(ti, ti + 2)}).load()
258+
assert (
259+
len(self.data.time) == 2
260+
), f"Field {self.name} has not been loaded correctly. Expected 2 timesteps, but got {len(self.data.time)}."
261+
249262
def eval(self, time: datetime, z, y, x, particle=None, applyConversion=True):
250263
"""Interpolate field values in space and time.
251264

parcels/fieldset.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,13 @@ def time_interval(self):
8282
return None
8383
return functools.reduce(lambda x, y: x.intersection(y), time_intervals)
8484

85+
def _load_timesteps(self, time):
86+
"""Load the appropriate timesteps of all fields in the fieldset."""
87+
for fldname in self.fields:
88+
field = self.fields[fldname]
89+
if isinstance(field, Field):
90+
field._load_timesteps(time)
91+
8592
def add_field(self, field: Field, name: str | None = None):
8693
"""Add a :class:`parcels.field.Field` object to the FieldSet.
8794

parcels/particleset.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from parcels._reprs import particleset_repr
1313
from parcels.application_kernels.advection import AdvectionRK4
1414
from parcels.basegrid import GridType
15+
from parcels.field import Field
1516
from parcels.interaction.interactionkernel import InteractionKernel
1617
from parcels.kernel import Kernel
1718
from parcels.particle import Particle, Variable
@@ -813,14 +814,14 @@ def execute(
813814

814815
time = start_time
815816

816-
for fld in [self.fieldset.U, self.fieldset.V]: # TODO generalise to all fields and move to better place
817-
fld._time_float = (fld.data_full.time.data - fld.time_interval.left) / np.timedelta64(1, "s")
817+
for fldname in self.fieldset.fields:
818+
field = self.fieldset.fields[fldname]
819+
if isinstance(field, Field):
820+
field._time_float = (field.data_full.time.data - field.time_interval.left) / np.timedelta64(1, "s")
818821

819822
while sign_dt * (time - end_time) < 0:
820-
for fld in [self.fieldset.U, self.fieldset.V]: # TODO generalise to all fields
821-
ti = np.argmin(fld._time_float <= self._data["time_nextloop"][0]) - 1 # TODO also implement dt < 0
822-
if not hasattr(fld, "data") or fld.data_full.time.data[ti] != fld.data.time.data[0]:
823-
fld.data = fld.data_full.isel({"time": slice(ti, ti + 2)}).load()
823+
# Load the appropriate timesteps of the fieldset
824+
self.fieldset._load_timesteps(self._data["time_nextloop"][0])
824825

825826
if sign_dt > 0:
826827
next_time = min(time + dt, end_time)

parcels/xgrid.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,8 @@ def _search_1d_array(
457457
return 0, 0.0
458458
i = np.argmin(arr <= x) - 1
459459
bcoord = (x - arr[i]) / (arr[i + 1] - arr[i])
460+
if bcoord < 0 or bcoord > 1: # TODO only for debugging; test can go?
461+
raise ValueError(f"Position {x} is out of bounds for array {arr}.")
460462
return i, bcoord
461463

462464

0 commit comments

Comments
 (0)