Skip to content

Commit b538407

Browse files
Argo floats in shallow waters (#263)
* use bathymetry criterion to raise argos in shallow waters * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * add logging messages when encountering shallow waters * throw error where waypoint is too shallow for Argo * add bathymetry to test argo fieldset * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * remove todo --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent c9cc9d7 commit b538407

File tree

2 files changed

+55
-4
lines changed

2 files changed

+55
-4
lines changed

src/virtualship/instruments/argo_float.py

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ class ArgoFloat:
5353
Variable("vertical_speed", dtype=np.float32),
5454
Variable("cycle_days", dtype=np.int32),
5555
Variable("drift_days", dtype=np.int32),
56+
Variable("grounded", dtype=np.int32, initial=0),
5657
]
5758
)
5859

@@ -64,10 +65,23 @@ class ArgoFloat:
6465
def _argo_float_vertical_movement(particle, fieldset, time):
6566
if particle.cycle_phase == 0:
6667
# Phase 0: Sinking with vertical_speed until depth is drift_depth
67-
particle_ddepth += ( # noqa Parcels defines particle_* variables, which code checkers cannot know.
68+
particle_ddepth += ( # noqa
6869
particle.vertical_speed * particle.dt
6970
)
70-
if particle.depth + particle_ddepth <= particle.drift_depth:
71+
72+
# bathymetry at particle location
73+
loc_bathy = fieldset.bathymetry.eval(
74+
time, particle.depth, particle.lat, particle.lon
75+
)
76+
if particle.depth + particle_ddepth <= loc_bathy:
77+
particle_ddepth = loc_bathy - particle.depth + 50.0 # 50m above bathy
78+
particle.cycle_phase = 1
79+
particle.grounded = 1
80+
print(
81+
"Shallow bathymetry warning: Argo float grounded at bathymetry depth during sinking to drift depth. Raising by 50m above bathymetry and continuing cycle."
82+
)
83+
84+
elif particle.depth + particle_ddepth <= particle.drift_depth:
7185
particle_ddepth = particle.drift_depth - particle.depth
7286
particle.cycle_phase = 1
7387

@@ -81,7 +95,17 @@ def _argo_float_vertical_movement(particle, fieldset, time):
8195
elif particle.cycle_phase == 2:
8296
# Phase 2: Sinking further to max_depth
8397
particle_ddepth += particle.vertical_speed * particle.dt
84-
if particle.depth + particle_ddepth <= particle.max_depth:
98+
loc_bathy = fieldset.bathymetry.eval(
99+
time, particle.depth, particle.lat, particle.lon
100+
)
101+
if particle.depth + particle_ddepth <= loc_bathy:
102+
particle_ddepth = loc_bathy - particle.depth + 50.0 # 50m above bathy
103+
particle.cycle_phase = 3
104+
particle.grounded = 1
105+
print(
106+
"Shallow bathymetry warning: Argo float grounded at bathymetry depth during sinking to max depth. Raising by 50m above bathymetry and continuing cycle."
107+
)
108+
elif particle.depth + particle_ddepth <= particle.max_depth:
85109
particle_ddepth = particle.max_depth - particle.depth
86110
particle.cycle_phase = 3
87111

@@ -91,6 +115,7 @@ def _argo_float_vertical_movement(particle, fieldset, time):
91115
particle.cycle_age += (
92116
particle.dt
93117
) # solve issue of not updating cycle_age during ascent
118+
particle.grounded = 0
94119
if particle.depth + particle_ddepth >= particle.min_depth:
95120
particle_ddepth = particle.min_depth - particle.depth
96121
particle.temperature = (
@@ -148,7 +173,7 @@ def __init__(self, expedition, from_data):
148173
super().__init__(
149174
expedition,
150175
variables,
151-
add_bathymetry=False,
176+
add_bathymetry=True,
152177
allow_time_extrapolation=False,
153178
verbose_progress=True,
154179
spacetime_buffer_size=spacetime_buffer_size,
@@ -171,6 +196,22 @@ def simulate(self, measurements, out_path) -> None:
171196

172197
fieldset = self.load_input_data()
173198

199+
shallow_waypoints = {}
200+
for i, m in enumerate(measurements):
201+
loc_bathy = fieldset.bathymetry.eval(
202+
time=0,
203+
z=0,
204+
y=m.spacetime.location.lat,
205+
x=m.spacetime.location.lon,
206+
)
207+
if abs(loc_bathy) < 50.0:
208+
shallow_waypoints[f"Waypoint {i + 1}"] = f"{abs(loc_bathy):.2f}m depth"
209+
210+
if len(shallow_waypoints) > 0:
211+
raise ValueError(
212+
f"{self.__class__.__name__} cannot be deployed in waters shallower than 50m. The following waypoints are too shallow: {shallow_waypoints}."
213+
)
214+
174215
# define parcel particles
175216
argo_float_particleset = ParticleSet(
176217
fieldset=fieldset,

tests/instruments/test_argo_float.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ def test_simulate_argo_floats(tmpdir) -> None:
2727
u = np.full((2, 2, 2), 1.0)
2828
t = np.full((2, 2, 2), CONST_TEMPERATURE)
2929
s = np.full((2, 2, 2), CONST_SALINITY)
30+
bathy = np.full((2, 2), -5000.0)
3031

3132
fieldset = FieldSet.from_data(
3233
{"V": v, "U": u, "T": t, "S": s},
@@ -39,6 +40,15 @@ def test_simulate_argo_floats(tmpdir) -> None:
3940
],
4041
},
4142
)
43+
fieldset.add_field(
44+
FieldSet.from_data(
45+
{"bathymetry": bathy},
46+
{
47+
"lon": np.array([0.0, 10.0]),
48+
"lat": np.array([0.0, 10.0]),
49+
},
50+
).bathymetry
51+
)
4252

4353
# argo floats to deploy
4454
argo_floats = [

0 commit comments

Comments
 (0)