Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
b4d9c2b
refactor error classes removing custom inits
VeckoTheGecko Jan 7, 2025
681f668
update to use _raise_out_of_bound_error
VeckoTheGecko Jan 7, 2025
6990c02
update to use _raise_out_of_bound_error
VeckoTheGecko Jan 7, 2025
44fc36a
update to use _raise_out_of_bound_surface_error
VeckoTheGecko Jan 7, 2025
08f560c
Rename parse_particletime
VeckoTheGecko Jan 7, 2025
a3f978c
update to use _raise_field_sampling_error
VeckoTheGecko Jan 7, 2025
13348b4
Renaming functions
VeckoTheGecko Jan 7, 2025
71d9532
Add exception helper
VeckoTheGecko Jan 7, 2025
912b84f
Remove implementation for deprecated public interpolation methods
VeckoTheGecko Jan 7, 2025
4b7ac56
Move search_indices_vertical_z and search_indices_vertical_s to _inte…
VeckoTheGecko Jan 7, 2025
33f9e31
Lift field name during interpolation error handling into _spatial_int…
VeckoTheGecko Jan 7, 2025
3a75f83
Refactoring
VeckoTheGecko Jan 7, 2025
c274704
Rename file
VeckoTheGecko Jan 7, 2025
14b2d9b
Refactor 2D interpolators into separate file
VeckoTheGecko Jan 7, 2025
debce8a
Refactor 3D interpolators into separate file
VeckoTheGecko Jan 8, 2025
892c155
Move interpolation call
VeckoTheGecko Jan 8, 2025
43f75a5
Temporarily add interp_method to 3D interpolation context
VeckoTheGecko Jan 8, 2025
a89e906
Add test_interpolation.py
VeckoTheGecko Jan 8, 2025
088bedd
Add some tests for interpolation methods
VeckoTheGecko Jan 8, 2025
94c4fa3
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jan 8, 2025
8dbb106
Supporting code for 3d interpolation refactor
VeckoTheGecko Jan 9, 2025
e908e53
Update fixture use method
VeckoTheGecko Jan 10, 2025
24b3c37
Add test_full_depth_provided_to_interpolators
VeckoTheGecko Jan 14, 2025
deb02d7
Fix test pollution
VeckoTheGecko Jan 15, 2025
9a01d4c
Redefine zdim based on data array
VeckoTheGecko Jan 16, 2025
8a16e18
Refactor using unit_square_to_target() function
VeckoTheGecko Jan 16, 2025
fded9ce
Change order to eta, xsi
VeckoTheGecko Jan 16, 2025
15f2abc
refactor to get_3d_f0_f1
VeckoTheGecko Jan 16, 2025
42561a7
Split up 3d interpolation functions
VeckoTheGecko Jan 16, 2025
fe0866b
Force kwargs
VeckoTheGecko Jan 16, 2025
3347cdf
add z_layer_interp
VeckoTheGecko Jan 16, 2025
10d02a0
Reduce code duplication
VeckoTheGecko Jan 16, 2025
bf58f67
Add interpolation testing for each grid cell
VeckoTheGecko Jan 17, 2025
78429eb
Delete old 3d interpolator
VeckoTheGecko Jan 16, 2025
a235874
update comment
VeckoTheGecko Jan 16, 2025
46fc3c3
Review feedback
VeckoTheGecko Jan 16, 2025
5ed3310
patch indexerror
VeckoTheGecko Jan 16, 2025
bf79d18
Rename file _indexing.py -> _index_search.py
VeckoTheGecko Jan 16, 2025
353d220
Refactor test
VeckoTheGecko Jan 16, 2025
d604ae1
Rename test data function
VeckoTheGecko Jan 17, 2025
b9d9242
review feedback
VeckoTheGecko Jan 17, 2025
7052b26
Move `calc_cell_edge_sizes`, and `cell_areas` out of field.py
VeckoTheGecko Jan 20, 2025
cb0ba68
Move methods _search_indices_curvilinear, _search_indices_rectilinear…
VeckoTheGecko Jan 20, 2025
8a861c3
move tests
VeckoTheGecko Jan 20, 2025
77d8a8e
Move reconnect_bnd_indices to grid.py
VeckoTheGecko Jan 20, 2025
76c6865
Remove casts to float32
VeckoTheGecko Jan 20, 2025
d88bce7
Remove msg from TimeExtrapolation constructor
VeckoTheGecko Jan 20, 2025
7d2e762
Fix citations
VeckoTheGecko Jan 20, 2025
3854ea1
review feedback
VeckoTheGecko Jan 24, 2025
a0a0336
Adding a unit test to compare JIT and SciPy interpolation/integration
erikvansebille Jan 27, 2025
8ac1593
Review edits
VeckoTheGecko Jan 27, 2025
af8ffe8
Review feedback
VeckoTheGecko Jan 29, 2025
d61563f
cleanup test_interpolation.py
VeckoTheGecko Jan 29, 2025
46a2853
xfail cgrid_velocity on test_scipy_vs_jit
VeckoTheGecko Jan 29, 2025
09aec5e
Relaxing jit-vs-scipy tolerance
erikvansebille Jan 29, 2025
baaf04c
Merge branch 'main' into v/refactor-interp
erikvansebille Jan 31, 2025
10a44f8
Copying #1834 changes into new _index_search functions
erikvansebille Jan 31, 2025
cc87fcd
Patch unit test
VeckoTheGecko Feb 3, 2025
0a8d593
Merge remote-tracking branch 'origin/main' into v/refactor-interp
VeckoTheGecko Feb 3, 2025
47c9ae6
Fixing timestep in unit test
erikvansebille Feb 3, 2025
d029cf8
Reducing velocity strengths (to avoid out-of-bounds deletions)
erikvansebille Feb 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions parcels/_compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,17 @@
from sklearn.cluster import KMeans # type: ignore[no-redef]
except ModuleNotFoundError:
pass


def add_note(e: Exception, note: str, *, before=False) -> Exception: # TODO: Remove once py3.10 support is dropped
"""Implements something similar to PEP 678 but for python <3.11.

https://stackoverflow.com/a/75549200/15545258
"""
args = e.args
if not args:
arg0 = note
else:
arg0 = f"{note}\n{args[0]}" if before else f"{args[0]}\n{note}"
e.args = (arg0,) + args[1:]
return e
337 changes: 337 additions & 0 deletions parcels/_index_search.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,337 @@
from __future__ import annotations

from typing import TYPE_CHECKING

import numpy as np

from parcels._typing import (
GridIndexingType,
InterpMethodOption,
)
from parcels.tools.statuscodes import (
FieldOutOfBoundError,
FieldOutOfBoundSurfaceError,
_raise_field_out_of_bound_error,
_raise_field_out_of_bound_surface_error,
_raise_field_sampling_error,
)

from .grid import GridType

if TYPE_CHECKING:
from .field import Field
from .grid import Grid


def search_indices_vertical_z(grid: Grid, gridindexingtype: GridIndexingType, z: float):
if grid.depth[-1] > grid.depth[0]:
if z < grid.depth[0]:
# Since MOM5 is indexed at cell bottom, allow z at depth[0] - dz where dz = (depth[1] - depth[0])
if gridindexingtype == "mom5" and z > 2 * grid.depth[0] - grid.depth[1]:
return (-1, z / grid.depth[0])
else:
_raise_field_out_of_bound_surface_error(z, None, None)
elif z > grid.depth[-1]:
# In case of CROCO, allow particles in last (uppermost) layer using depth[-1]
if gridindexingtype in ["croco"] and z < 0:
return (-2, 1)
_raise_field_out_of_bound_error(z, None, None)
depth_indices = grid.depth < z
if z >= grid.depth[-1]:
zi = len(grid.depth) - 2
else:
zi = depth_indices.argmin() - 1 if z > grid.depth[0] else 0
else:
if z > grid.depth[0]:
_raise_field_out_of_bound_surface_error(z, None, None)
elif z < grid.depth[-1]:
_raise_field_out_of_bound_error(z, None, None)

Check warning on line 48 in parcels/_index_search.py

View check run for this annotation

Codecov / codecov/patch

parcels/_index_search.py#L48

Added line #L48 was not covered by tests
depth_indices = grid.depth > z
if z <= grid.depth[-1]:
zi = len(grid.depth) - 2

Check warning on line 51 in parcels/_index_search.py

View check run for this annotation

Codecov / codecov/patch

parcels/_index_search.py#L51

Added line #L51 was not covered by tests
else:
zi = depth_indices.argmin() - 1 if z < grid.depth[0] else 0
zeta = (z - grid.depth[zi]) / (grid.depth[zi + 1] - grid.depth[zi])
while zeta > 1:
zi += 1
zeta = (z - grid.depth[zi]) / (grid.depth[zi + 1] - grid.depth[zi])

Check warning on line 57 in parcels/_index_search.py

View check run for this annotation

Codecov / codecov/patch

parcels/_index_search.py#L57

Added line #L57 was not covered by tests
while zeta < 0:
zi -= 1
zeta = (z - grid.depth[zi]) / (grid.depth[zi + 1] - grid.depth[zi])

Check warning on line 60 in parcels/_index_search.py

View check run for this annotation

Codecov / codecov/patch

parcels/_index_search.py#L60

Added line #L60 was not covered by tests
return (zi, zeta)


def search_indices_vertical_s(
grid: Grid,
interp_method: InterpMethodOption,
time: float,
z: float,
y: float,
x: float,
ti: int,
yi: int,
xi: int,
eta: float,
xsi: float,
):
if interp_method in ["bgrid_velocity", "bgrid_w_velocity", "bgrid_tracer"]:
xsi = 1
eta = 1
if time < grid.time[ti]:
ti -= 1
if grid._z4d:
if ti == len(grid.time) - 1:
depth_vector = (
(1 - xsi) * (1 - eta) * grid.depth[-1, :, yi, xi]
+ xsi * (1 - eta) * grid.depth[-1, :, yi, xi + 1]
+ xsi * eta * grid.depth[-1, :, yi + 1, xi + 1]
+ (1 - xsi) * eta * grid.depth[-1, :, yi + 1, xi]

Check warning on line 88 in parcels/_index_search.py

View check run for this annotation

Codecov / codecov/patch

parcels/_index_search.py#L84-L88

Added lines #L84 - L88 were not covered by tests
)
else:
dv2 = (
(1 - xsi) * (1 - eta) * grid.depth[ti : ti + 2, :, yi, xi]
+ xsi * (1 - eta) * grid.depth[ti : ti + 2, :, yi, xi + 1]
+ xsi * eta * grid.depth[ti : ti + 2, :, yi + 1, xi + 1]
+ (1 - xsi) * eta * grid.depth[ti : ti + 2, :, yi + 1, xi]

Check warning on line 95 in parcels/_index_search.py

View check run for this annotation

Codecov / codecov/patch

parcels/_index_search.py#L92-L95

Added lines #L92 - L95 were not covered by tests
)
tt = (time - grid.time[ti]) / (grid.time[ti + 1] - grid.time[ti])
assert tt >= 0 and tt <= 1, "Vertical s grid is being wrongly interpolated in time"
depth_vector = dv2[0, :] * (1 - tt) + dv2[1, :] * tt
else:
depth_vector = (
(1 - xsi) * (1 - eta) * grid.depth[:, yi, xi]
+ xsi * (1 - eta) * grid.depth[:, yi, xi + 1]
+ xsi * eta * grid.depth[:, yi + 1, xi + 1]
+ (1 - xsi) * eta * grid.depth[:, yi + 1, xi]

Check warning on line 105 in parcels/_index_search.py

View check run for this annotation

Codecov / codecov/patch

parcels/_index_search.py#L102-L105

Added lines #L102 - L105 were not covered by tests
)
z = np.float32(z) # type: ignore # TODO: remove type ignore once we migrate to float64

if depth_vector[-1] > depth_vector[0]:
if z < depth_vector[0]:
_raise_field_out_of_bound_error(z, None, None)

Check warning on line 111 in parcels/_index_search.py

View check run for this annotation

Codecov / codecov/patch

parcels/_index_search.py#L111

Added line #L111 was not covered by tests
elif z > depth_vector[-1]:
_raise_field_out_of_bound_error(z, None, None)
depth_indices = depth_vector < z
if z >= depth_vector[-1]:
zi = len(depth_vector) - 2

Check warning on line 116 in parcels/_index_search.py

View check run for this annotation

Codecov / codecov/patch

parcels/_index_search.py#L116

Added line #L116 was not covered by tests
else:
zi = depth_indices.argmin() - 1 if z > depth_vector[0] else 0
else:
if z > depth_vector[0]:
_raise_field_out_of_bound_error(z, None, None)
elif z < depth_vector[-1]:
_raise_field_out_of_bound_error(z, None, None)
depth_indices = depth_vector > z
if z <= depth_vector[-1]:
zi = len(depth_vector) - 2

Check warning on line 126 in parcels/_index_search.py

View check run for this annotation

Codecov / codecov/patch

parcels/_index_search.py#L120-L126

Added lines #L120 - L126 were not covered by tests
else:
zi = depth_indices.argmin() - 1 if z < depth_vector[0] else 0

Check warning on line 128 in parcels/_index_search.py

View check run for this annotation

Codecov / codecov/patch

parcels/_index_search.py#L128

Added line #L128 was not covered by tests
zeta = (z - depth_vector[zi]) / (depth_vector[zi + 1] - depth_vector[zi])
while zeta > 1:
zi += 1
zeta = (z - depth_vector[zi]) / (depth_vector[zi + 1] - depth_vector[zi])

Check warning on line 132 in parcels/_index_search.py

View check run for this annotation

Codecov / codecov/patch

parcels/_index_search.py#L132

Added line #L132 was not covered by tests
while zeta < 0:
zi -= 1
zeta = (z - depth_vector[zi]) / (depth_vector[zi + 1] - depth_vector[zi])

Check warning on line 135 in parcels/_index_search.py

View check run for this annotation

Codecov / codecov/patch

parcels/_index_search.py#L135

Added line #L135 was not covered by tests
return (zi, zeta)


def _search_indices_rectilinear(
field: Field, time: float, z: float, y: float, x: float, ti=-1, particle=None, search2D=False
):
grid = field.grid

if grid.xdim > 1 and (not grid.zonal_periodic):
if x < grid.lonlat_minmax[0] or x > grid.lonlat_minmax[1]:
_raise_field_out_of_bound_error(z, y, x)
if grid.ydim > 1 and (y < grid.lonlat_minmax[2] or y > grid.lonlat_minmax[3]):
_raise_field_out_of_bound_error(z, y, x)

if grid.xdim > 1:
if grid.mesh != "spherical":
lon_index = grid.lon < x
if lon_index.all():
xi = len(grid.lon) - 2

Check warning on line 154 in parcels/_index_search.py

View check run for this annotation

Codecov / codecov/patch

parcels/_index_search.py#L154

Added line #L154 was not covered by tests
else:
xi = lon_index.argmin() - 1 if lon_index.any() else 0
xsi = (x - grid.lon[xi]) / (grid.lon[xi + 1] - grid.lon[xi])
if xsi < 0:
xi -= 1
xsi = (x - grid.lon[xi]) / (grid.lon[xi + 1] - grid.lon[xi])

Check warning on line 160 in parcels/_index_search.py

View check run for this annotation

Codecov / codecov/patch

parcels/_index_search.py#L160

Added line #L160 was not covered by tests
elif xsi > 1:
xi += 1
xsi = (x - grid.lon[xi]) / (grid.lon[xi + 1] - grid.lon[xi])

Check warning on line 163 in parcels/_index_search.py

View check run for this annotation

Codecov / codecov/patch

parcels/_index_search.py#L163

Added line #L163 was not covered by tests
else:
lon_fixed = grid.lon.copy()
indices = lon_fixed >= lon_fixed[0]
if not indices.all():
lon_fixed[indices.argmin() :] += 360

Check warning on line 168 in parcels/_index_search.py

View check run for this annotation

Codecov / codecov/patch

parcels/_index_search.py#L168

Added line #L168 was not covered by tests
if x < lon_fixed[0]:
lon_fixed -= 360

Check warning on line 170 in parcels/_index_search.py

View check run for this annotation

Codecov / codecov/patch

parcels/_index_search.py#L170

Added line #L170 was not covered by tests

lon_index = lon_fixed < x
if lon_index.all():
xi = len(lon_fixed) - 2

Check warning on line 174 in parcels/_index_search.py

View check run for this annotation

Codecov / codecov/patch

parcels/_index_search.py#L174

Added line #L174 was not covered by tests
else:
xi = lon_index.argmin() - 1 if lon_index.any() else 0
xsi = (x - lon_fixed[xi]) / (lon_fixed[xi + 1] - lon_fixed[xi])
if xsi < 0:
xi -= 1
xsi = (x - lon_fixed[xi]) / (lon_fixed[xi + 1] - lon_fixed[xi])

Check warning on line 180 in parcels/_index_search.py

View check run for this annotation

Codecov / codecov/patch

parcels/_index_search.py#L180

Added line #L180 was not covered by tests
elif xsi > 1:
xi += 1
xsi = (x - lon_fixed[xi]) / (lon_fixed[xi + 1] - lon_fixed[xi])

Check warning on line 183 in parcels/_index_search.py

View check run for this annotation

Codecov / codecov/patch

parcels/_index_search.py#L183

Added line #L183 was not covered by tests
else:
xi, xsi = -1, 0

if grid.ydim > 1:
lat_index = grid.lat < y
if lat_index.all():
yi = len(grid.lat) - 2

Check warning on line 190 in parcels/_index_search.py

View check run for this annotation

Codecov / codecov/patch

parcels/_index_search.py#L190

Added line #L190 was not covered by tests
else:
yi = lat_index.argmin() - 1 if lat_index.any() else 0

eta = (y - grid.lat[yi]) / (grid.lat[yi + 1] - grid.lat[yi])
if eta < 0:
yi -= 1
eta = (y - grid.lat[yi]) / (grid.lat[yi + 1] - grid.lat[yi])

Check warning on line 197 in parcels/_index_search.py

View check run for this annotation

Codecov / codecov/patch

parcels/_index_search.py#L197

Added line #L197 was not covered by tests
elif eta > 1:
yi += 1
eta = (y - grid.lat[yi]) / (grid.lat[yi + 1] - grid.lat[yi])

Check warning on line 200 in parcels/_index_search.py

View check run for this annotation

Codecov / codecov/patch

parcels/_index_search.py#L200

Added line #L200 was not covered by tests
else:
yi, eta = -1, 0

if grid.zdim > 1 and not search2D:
if grid._gtype == GridType.RectilinearZGrid:
try:
(zi, zeta) = search_indices_vertical_z(field.grid, field.gridindexingtype, z)
except FieldOutOfBoundError:
_raise_field_out_of_bound_error(z, y, x)
except FieldOutOfBoundSurfaceError:
_raise_field_out_of_bound_surface_error(z, y, x)
elif grid._gtype == GridType.RectilinearSGrid:
(zi, zeta) = search_indices_vertical_s(field.grid, field.interp_method, time, z, y, x, ti, yi, xi, eta, xsi)
else:
zi, zeta = -1, 0

if not ((0 <= xsi <= 1) and (0 <= eta <= 1) and (0 <= zeta <= 1)):
_raise_field_sampling_error(z, y, x)

Check warning on line 218 in parcels/_index_search.py

View check run for this annotation

Codecov / codecov/patch

parcels/_index_search.py#L218

Added line #L218 was not covered by tests

if particle:
particle.xi[field.igrid] = xi
particle.yi[field.igrid] = yi
particle.zi[field.igrid] = zi

return (zeta, eta, xsi, zi, yi, xi)


def _search_indices_curvilinear(field: Field, time, z, y, x, ti=-1, particle=None, search2D=False):
if particle:
xi = particle.xi[field.igrid]
yi = particle.yi[field.igrid]
else:
xi = int(field.grid.xdim / 2) - 1
yi = int(field.grid.ydim / 2) - 1
xsi = eta = -1
grid = field.grid
invA = np.array([[1, 0, 0, 0], [-1, 1, 0, 0], [-1, 0, 0, 1], [1, -1, 1, -1]])
maxIterSearch = 1e6
it = 0
tol = 1.0e-10
if not grid.zonal_periodic:
if x < grid.lonlat_minmax[0] or x > grid.lonlat_minmax[1]:
if grid.lon[0, 0] < grid.lon[0, -1]:
_raise_field_out_of_bound_error(z, y, x)

Check warning on line 244 in parcels/_index_search.py

View check run for this annotation

Codecov / codecov/patch

parcels/_index_search.py#L244

Added line #L244 was not covered by tests
elif x < grid.lon[0, 0] and x > grid.lon[0, -1]: # This prevents from crashing in [160, -160]
_raise_field_out_of_bound_error(z, y, x)

Check warning on line 246 in parcels/_index_search.py

View check run for this annotation

Codecov / codecov/patch

parcels/_index_search.py#L246

Added line #L246 was not covered by tests
if y < grid.lonlat_minmax[2] or y > grid.lonlat_minmax[3]:
_raise_field_out_of_bound_error(z, y, x)

Check warning on line 248 in parcels/_index_search.py

View check run for this annotation

Codecov / codecov/patch

parcels/_index_search.py#L248

Added line #L248 was not covered by tests

while xsi < -tol or xsi > 1 + tol or eta < -tol or eta > 1 + tol:
px = np.array([grid.lon[yi, xi], grid.lon[yi, xi + 1], grid.lon[yi + 1, xi + 1], grid.lon[yi + 1, xi]])
if grid.mesh == "spherical":
px[0] = px[0] + 360 if px[0] < x - 225 else px[0]
px[0] = px[0] - 360 if px[0] > x + 225 else px[0]
px[1:] = np.where(px[1:] - px[0] > 180, px[1:] - 360, px[1:])
px[1:] = np.where(-px[1:] + px[0] > 180, px[1:] + 360, px[1:])
py = np.array([grid.lat[yi, xi], grid.lat[yi, xi + 1], grid.lat[yi + 1, xi + 1], grid.lat[yi + 1, xi]])
a = np.dot(invA, px)
b = np.dot(invA, py)

aa = a[3] * b[2] - a[2] * b[3]
bb = a[3] * b[0] - a[0] * b[3] + a[1] * b[2] - a[2] * b[1] + x * b[3] - y * a[3]
cc = a[1] * b[0] - a[0] * b[1] + x * b[1] - y * a[1]
if abs(aa) < 1e-12: # Rectilinear cell, or quasi
eta = -cc / bb
else:
det2 = bb * bb - 4 * aa * cc
if det2 > 0: # so, if det is nan we keep the xsi, eta from previous iter
det = np.sqrt(det2)
eta = (-bb + det) / (2 * aa)
if abs(a[1] + a[3] * eta) < 1e-12: # this happens when recti cell rotated of 90deg
xsi = ((y - py[0]) / (py[1] - py[0]) + (y - py[3]) / (py[2] - py[3])) * 0.5

Check warning on line 272 in parcels/_index_search.py

View check run for this annotation

Codecov / codecov/patch

parcels/_index_search.py#L272

Added line #L272 was not covered by tests
else:
xsi = (x - a[0] - a[2] * eta) / (a[1] + a[3] * eta)
if xsi < 0 and eta < 0 and xi == 0 and yi == 0:
_raise_field_out_of_bound_error(0, y, x)

Check warning on line 276 in parcels/_index_search.py

View check run for this annotation

Codecov / codecov/patch

parcels/_index_search.py#L276

Added line #L276 was not covered by tests
if xsi > 1 and eta > 1 and xi == grid.xdim - 1 and yi == grid.ydim - 1:
_raise_field_out_of_bound_error(0, y, x)

Check warning on line 278 in parcels/_index_search.py

View check run for this annotation

Codecov / codecov/patch

parcels/_index_search.py#L278

Added line #L278 was not covered by tests
if xsi < -tol:
xi -= 1
elif xsi > 1 + tol:
xi += 1
if eta < -tol:
yi -= 1
elif eta > 1 + tol:
yi += 1
(yi, xi) = _reconnect_bnd_indices(yi, xi, grid.ydim, grid.xdim, grid.mesh)
it += 1
if it > maxIterSearch:
print(f"Correct cell not found after {maxIterSearch} iterations")
_raise_field_out_of_bound_error(0, y, x)

Check warning on line 291 in parcels/_index_search.py

View check run for this annotation

Codecov / codecov/patch

parcels/_index_search.py#L291

Added line #L291 was not covered by tests
xsi = max(0.0, xsi)
eta = max(0.0, eta)
xsi = min(1.0, xsi)
eta = min(1.0, eta)

if grid.zdim > 1 and not search2D:
if grid._gtype == GridType.CurvilinearZGrid:
try:
(zi, zeta) = search_indices_vertical_z(field.grid, field.gridindexingtype, z)
except FieldOutOfBoundError:
_raise_field_out_of_bound_error(z, y, x)

Check warning on line 302 in parcels/_index_search.py

View check run for this annotation

Codecov / codecov/patch

parcels/_index_search.py#L302

Added line #L302 was not covered by tests
elif grid._gtype == GridType.CurvilinearSGrid:
(zi, zeta) = search_indices_vertical_s(field.grid, field.interp_method, time, z, y, x, ti, yi, xi, eta, xsi)
else:
zi = -1
zeta = 0

if not ((0 <= xsi <= 1) and (0 <= eta <= 1) and (0 <= zeta <= 1)):
_raise_field_sampling_error(z, y, x)

Check warning on line 310 in parcels/_index_search.py

View check run for this annotation

Codecov / codecov/patch

parcels/_index_search.py#L310

Added line #L310 was not covered by tests

if particle:
particle.xi[field.igrid] = xi
particle.yi[field.igrid] = yi
particle.zi[field.igrid] = zi

return (zeta, eta, xsi, zi, yi, xi)


def _reconnect_bnd_indices(yi: int, xi: int, ydim: int, xdim: int, sphere_mesh: bool):
if xi < 0:
if sphere_mesh:
xi = xdim - 2
else:
xi = 0
if xi > xdim - 2:
if sphere_mesh:
xi = 0
else:
xi = xdim - 2
if yi < 0:
yi = 0
if yi > ydim - 2:
yi = ydim - 2
if sphere_mesh:
xi = xdim - xi
return yi, xi
Loading
Loading