44from typing import ClassVar
55
66import numpy as np
7+
78from parcels import (
89 AdvectionRK4 ,
910 JITParticle ,
1011 ParticleSet ,
1112 StatusCode ,
1213 Variable ,
1314)
14-
1515from virtualship .instruments .base import Instrument
1616from virtualship .instruments .types import InstrumentType
1717from virtualship .models .spacetime import Spacetime
@@ -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,24 @@ class ArgoFloat:
6465def _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+ # TODO: print statments not working properly with JIT compiler...
81+ # print(
82+ # f"Argo float grounded at bathymetry depth: {loc_bathy}m during sinking to drift depth. Location: ({particle.lat}, {particle.lon}). Raising by 50m above bathymetry and continuing cycle."
83+ # )
84+
85+ elif particle .depth + particle_ddepth <= particle .drift_depth :
7186 particle_ddepth = particle .drift_depth - particle .depth
7287 particle .cycle_phase = 1
7388
@@ -81,7 +96,17 @@ def _argo_float_vertical_movement(particle, fieldset, time):
8196 elif particle .cycle_phase == 2 :
8297 # Phase 2: Sinking further to max_depth
8398 particle_ddepth += particle .vertical_speed * particle .dt
84- if particle .depth + particle_ddepth <= particle .max_depth :
99+ loc_bathy = fieldset .bathymetry .eval (
100+ time , particle .depth , particle .lat , particle .lon
101+ )
102+ if particle .depth + particle_ddepth <= loc_bathy :
103+ particle_ddepth = loc_bathy - particle .depth + 50.0 # 50m above bathy
104+ particle .cycle_phase = 3
105+ particle .grounded = 1
106+ # print(
107+ # f"Argo float grounded at bathymetry depth: {loc_bathy}m during sinking to max depth. Location: ({particle.lat}, {particle.lon}). Raising by 50m above bathymetry and continuing cycle."
108+ # )
109+ elif particle .depth + particle_ddepth <= particle .max_depth :
85110 particle_ddepth = particle .max_depth - particle .depth
86111 particle .cycle_phase = 3
87112
@@ -91,6 +116,7 @@ def _argo_float_vertical_movement(particle, fieldset, time):
91116 particle .cycle_age += (
92117 particle .dt
93118 ) # solve issue of not updating cycle_age during ascent
119+ particle .grounded = 0
94120 if particle .depth + particle_ddepth >= particle .min_depth :
95121 particle_ddepth = particle .min_depth - particle .depth
96122 particle .temperature = (
@@ -148,7 +174,7 @@ def __init__(self, expedition, from_data):
148174 super ().__init__ (
149175 expedition ,
150176 variables ,
151- add_bathymetry = False ,
177+ add_bathymetry = True ,
152178 allow_time_extrapolation = False ,
153179 verbose_progress = True ,
154180 spacetime_buffer_size = spacetime_buffer_size ,
@@ -162,6 +188,8 @@ def simulate(self, measurements, out_path) -> None:
162188 OUTPUT_DT = timedelta (minutes = 5 )
163189 ENDTIME = None
164190
191+ # TODO: insert checker that none of the waypoints are under 50m depth; if so, raise error.
192+
165193 if len (measurements ) == 0 :
166194 print (
167195 "No Argo floats provided. Parcels currently crashes when providing an empty particle set, so no argo floats simulation will be done and no files will be created."
@@ -191,7 +219,7 @@ def simulate(self, measurements, out_path) -> None:
191219 out_file = argo_float_particleset .ParticleFile (
192220 name = out_path ,
193221 outputdt = OUTPUT_DT ,
194- chunks = [len (argo_float_particleset ), 100 ],
222+ chunks = [len (argo_float_particleset ), 100 ], # TODO: is this necessary?
195223 )
196224
197225 # get earliest between fieldset end time and provide end time
0 commit comments