Skip to content

Commit f09b7bd

Browse files
authored
Merge pull request #1641 from knutfrode/dev
Implemented correction activated by config drift:vertical_velocity_co…
2 parents b1a4b0c + 8cc6027 commit f09b7bd

3 files changed

Lines changed: 87 additions & 1 deletion

File tree

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#!/usr/bin/env python
2+
"""
3+
Vertical advection correction
4+
=============================
5+
"""
6+
7+
#%%
8+
# In OpenDrift, element depth (z) is relative to actual surface, and not mean sea level.
9+
# Vertical velocity from ocean models contain a contribution which is due to
10+
# change in sea surface elevation, however, this should in OpenDrift be subtracted
11+
# due to the choice of defining z relative to actual surface elevation
12+
# This correction is activated with config setting 'drift:vertical_advection_correction'
13+
# The effect is illustrated with the simulations below.
14+
15+
16+
from datetime import datetime, timedelta
17+
import numpy as np
18+
import matplotlib.pyplot as plt
19+
from opendrift.readers import reader_oscillating
20+
from opendrift.models.oceandrift import OceanDrift
21+
22+
time = datetime.now()
23+
reader_tidal = reader_oscillating.Reader('sea_surface_height', amplitude=-1,
24+
period=timedelta(hours=6), zero_time=time)
25+
lat=59.8113; lon=10.5517 # Oslo fjord
26+
z = np.arange(0, -60, -5) # Seeding one particle every 5 meter from surface to 60m depth
27+
28+
# Without stetching
29+
o = OceanDrift(loglevel=0)
30+
o.add_reader(reader_tidal)
31+
o.add_readers_from_list(['https://thredds.met.no/thredds/dodsC/sea/norkyst800m/1h/aggregate_be'])
32+
o.set_config('drift:water_column_stretching', False)
33+
o.set_config('drift:vertical_advection', True)
34+
o.seed_elements(lon=lon, lat=lat, time=time, z=z, number=len(z))
35+
o.run(duration=timedelta(hours=24), time_step=1800)
36+
37+
# With stetching
38+
o2 = OceanDrift(loglevel=0)
39+
o2.add_reader(reader_tidal)
40+
o2.add_readers_from_list(['https://thredds.met.no/thredds/dodsC/sea/norkyst800m/1h/aggregate_be'])
41+
o2.set_config('drift:water_column_stretching', True)
42+
o2.set_config('drift:vertical_advection', True)
43+
o2.seed_elements(lon=lon, lat=lat, time=time, z=z, number=len(z))
44+
o2.run(duration=timedelta(hours=24), time_step=1800)
45+
46+
# With w correction
47+
o3 = OceanDrift(loglevel=0)
48+
o3.add_reader(reader_tidal)
49+
o3.add_readers_from_list(['https://thredds.met.no/thredds/dodsC/sea/norkyst800m/1h/aggregate_be'])
50+
o3.set_config('drift:water_column_stretching', False)
51+
o3.set_config('drift:vertical_advection', True)
52+
o3.set_config('drift:vertical_advection_correction', True)
53+
o3.seed_elements(lon=lon, lat=lat, time=time, z=z, number=len(z))
54+
o3.run(duration=timedelta(hours=24), time_step=1800)
55+
56+
57+
plt.subplot(3,1,1)
58+
o.result.z.plot.line(x='time', add_legend=False, color='k')
59+
o2.result.z.plot.line(x='time', add_legend=False, color='r')
60+
o3.result.z.plot.line(x='time', add_legend=False, color='g')
61+
plt.plot([], [], color='k', label='No stretching or correction')
62+
plt.plot([], [], color='r', label='Column stretching')
63+
plt.plot([], [], color='g', label='Vertical velocity correction')
64+
plt.legend()
65+
plt.subplot(3,1,2)
66+
o.result.sea_floor_depth_below_sea_level.plot.line(x='time', add_legend=False, color='k')
67+
plt.subplot(3,1,3)
68+
o.result.upward_sea_water_velocity.plot.line(x='time', add_legend=False, color='k')
69+
plt.show()

examples/example_water_column_stretching.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
# This lifting is in this case unphysical.
4646

4747
#%%
48+
# We then make a simulation wih correction for the stretching/contraction of the water column.
4849
o = OceanDrift(loglevel=20)
4950
o.add_reader(reader_tidal)
5051
o.set_config('drift:water_column_stretching', True)
@@ -54,6 +55,7 @@
5455
o.result.z.plot.line(x='time', add_legend=False)
5556
plt.show()
5657

58+
#%%
5759
# Here we see that element depth (z, relative to surface) is changed so that
5860
# elements at surface and seafloor remain at resp surface (z=0) and
5961
# seafloor (z = sea_floor_depth + sea_surface_elevation)

opendrift/models/oceandrift.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,9 @@ def __init__(self, *args, **kwargs):
124124
'drift:water_column_stretching': {'type': 'bool', 'default': False, 'description':
125125
'If sea surface elevation changes, vertical particle position (element property "z" is relative to surface, and not absolute zero-level) is adjusted so that elements at surface and seafloor remains at resp surface and seafloor.',
126126
'level': CONFIG_LEVEL_ADVANCED},
127+
'drift:vertical_advection_correction': {'type': 'bool', 'default': False, 'description':
128+
'The vertical velocity from ocean model is partly due to sea level changes. But since element depth in OpenDrift (elements.z) is relative to actual surface, this part should be subtracted.',
129+
'level': CONFIG_LEVEL_ADVANCED},
127130
'drift:vertical_mixing': {'type': 'bool', 'default': False, 'level': CONFIG_LEVEL_BASIC,
128131
'description': 'Activate vertical mixing scheme with inner loop'},
129132
'drift:vertical_mixing_at_surface': {'type': 'bool', 'default': False, 'description':
@@ -301,6 +304,7 @@ def water_column_stretching(self):
301304
delta_zeta = self.environment.sea_surface_height - self.environment_previous.sea_surface_height
302305
logger.info('Compensating for change in surface elevation')
303306
self.elements.z = self.elements.z + delta_zeta*(self.elements.z/self.environment.sea_floor_depth_below_sea_level)
307+
self.elements.z = self.elements.z.data
304308

305309
def vertical_advection(self):
306310
"""Move particles vertically according to vertical ocean current
@@ -321,8 +325,19 @@ def vertical_advection(self):
321325

322326
if len(applicable) > 0:
323327
w = self.environment.upward_sea_water_velocity[applicable]
328+
329+
if self.get_config('drift:vertical_advection_correction', None) is True:
330+
logger.debug('Subtracting motion due to elevation change from vertical water velocity')
331+
delta_zeta = self.environment.sea_surface_height[applicable] - self.environment_previous.sea_surface_height[applicable]
332+
w_surface = delta_zeta / self.time_step.total_seconds()
333+
total_depth = self.environment.sea_surface_height[applicable] + \
334+
self.environment.sea_floor_depth_below_sea_level[applicable]
335+
w_elevation = w_surface * (self.elements.z[applicable] + total_depth) / total_depth
336+
w = w - w_elevation
337+
324338
self.elements.z[applicable] = np.minimum(0,
325-
self.elements.z[applicable] + self.elements.moving[applicable] * w * self.time_step.total_seconds())
339+
self.elements.z[applicable] + self.elements.moving[applicable] * w *
340+
self.time_step.total_seconds())
326341

327342
def vertical_buoyancy(self):
328343
"""Move particles vertically according to their buoyancy"""

0 commit comments

Comments
 (0)