Note
Go to the end to download the full example code.
Element dependent environment
from datetime import datetime
import matplotlib.pyplot as plt
import numpy as np
from opendrift.models.oceandrift import OceanDrift
import trajan as ta
OpenDrift elements have properties such as lon, lat, z, size etc. These elements are moved and changed based on environment properties such as current, wind, temperature etc. In principle the element properties do not affect the environment, however, for sensitivity studies it can be of interest to let different elements of the same simulation be exposed to different environment. This is made possible by specifying the (constant) environment values for all elements of a seed call as illustrated below
First an example with two different seedings with two different environments
o = OceanDrift(loglevel=20)
# First seeding 200 elements that will be exposed to eastward current and a horizontal diffusivity of 10 m2/s
number = 200
o.seed_elements(lon=-60, lat=40, time=datetime(2022,1,1), number=number, radius=10,
environment={'horizontal_diffusivity': 10,
'x_sea_water_velocity': 1,
'y_sea_water_velocity': 0})
# Then seeding 100 elements that will be exposed to northward current and less diffusivity (1 m2/s)
number = 100
o.seed_elements(lon=-60, lat=40, time=datetime(2022,1,1), number=number, radius=10,
environment={'horizontal_diffusivity': 1,
'x_sea_water_velocity': 0,
'y_sea_water_velocity': .5})
o.run(steps=10)
o.plot()

16:22:02 INFO opendrift:576: OpenDriftSimulation initialised (version 1.14.8 / v1.14.8-15-ge839285)
16:22:02 INFO opendrift.models.basemodel.environment:203: Adding a global landmask from GSHHG
16:22:07 INFO opendrift.models.basemodel.environment:227: Fallback values will be used for the following variables which have no readers:
16:22:07 INFO opendrift.models.basemodel.environment:230: x_sea_water_velocity: 0.000000
16:22:07 INFO opendrift.models.basemodel.environment:230: y_sea_water_velocity: 0.000000
16:22:07 INFO opendrift.models.basemodel.environment:230: sea_surface_height: 0.000000
16:22:07 INFO opendrift.models.basemodel.environment:230: x_wind: 0.000000
16:22:07 INFO opendrift.models.basemodel.environment:230: y_wind: 0.000000
16:22:07 INFO opendrift.models.basemodel.environment:230: upward_sea_water_velocity: 0.000000
16:22:07 INFO opendrift.models.basemodel.environment:230: ocean_vertical_diffusivity: 0.000000
16:22:07 INFO opendrift.models.basemodel.environment:230: horizontal_diffusivity: 0.000000
16:22:07 INFO opendrift.models.basemodel.environment:230: sea_surface_wave_significant_height: 0.000000
16:22:07 INFO opendrift.models.basemodel.environment:230: sea_surface_wave_stokes_drift_x_velocity: 0.000000
16:22:07 INFO opendrift.models.basemodel.environment:230: sea_surface_wave_stokes_drift_y_velocity: 0.000000
16:22:07 INFO opendrift.models.basemodel.environment:230: ocean_mixed_layer_thickness: 50.000000
16:22:07 INFO opendrift.models.basemodel.environment:230: sea_floor_depth_below_sea_level: 10000.000000
16:22:07 INFO opendrift:1836: Skipping environment variable ocean_vertical_diffusivity because of condition ['drift:vertical_mixing', 'is', False]
16:22:07 INFO opendrift:1836: Skipping environment variable ocean_mixed_layer_thickness because of condition ['drift:vertical_mixing', 'is', False]
16:22:07 INFO opendrift:1847: Storing previous values of element property lon because of condition (('general:coastline_action', 'in', ['stranding', 'previous']), 'or', ('general:seafloor_action', 'in', ['previous']))
16:22:07 INFO opendrift:1847: Storing previous values of element property lat because of condition (('general:coastline_action', 'in', ['stranding', 'previous']), 'or', ('general:seafloor_action', 'in', ['previous']))
16:22:07 INFO opendrift:1855: Storing previous values of environment variable sea_surface_height because of condition ['drift:vertical_advection', 'is', True]
16:22:07 INFO opendrift:955: Using existing reader for land_binary_mask to move elements to ocean
16:22:07 INFO opendrift:986: All points are in ocean
16:22:07 INFO opendrift:2144: 2022-01-01 00:00:00 - step 1 of 10 - 300 active elements (0 deactivated)
16:22:07 INFO opendrift:2144: 2022-01-01 01:00:00 - step 2 of 10 - 300 active elements (0 deactivated)
16:22:07 INFO opendrift:2144: 2022-01-01 02:00:00 - step 3 of 10 - 300 active elements (0 deactivated)
16:22:08 INFO opendrift:2144: 2022-01-01 03:00:00 - step 4 of 10 - 300 active elements (0 deactivated)
16:22:08 INFO opendrift:2144: 2022-01-01 04:00:00 - step 5 of 10 - 300 active elements (0 deactivated)
16:22:08 INFO opendrift:2144: 2022-01-01 05:00:00 - step 6 of 10 - 300 active elements (0 deactivated)
16:22:08 INFO opendrift:2144: 2022-01-01 06:00:00 - step 7 of 10 - 300 active elements (0 deactivated)
16:22:08 INFO opendrift:2144: 2022-01-01 07:00:00 - step 8 of 10 - 300 active elements (0 deactivated)
16:22:08 INFO opendrift:2144: 2022-01-01 08:00:00 - step 9 of 10 - 300 active elements (0 deactivated)
16:22:08 INFO opendrift:2144: 2022-01-01 09:00:00 - step 10 of 10 - 300 active elements (0 deactivated)
(<GeoAxes: title={'center': 'OpenDrift - OceanDrift\n2022-01-01 00:00 to 2022-01-01 10:00 UTC (11 steps)'}>, <Figure size 1100x639.989 with 1 Axes>)
Second example with a single seeding where each element will be exposed to different diffusivity values
o = OceanDrift(loglevel=20)
# Seeding 1000 elements that will be exposed to north-eastward current with diffusivities ranging from 0 to 50 m2/s
number = 1000
diffusivity_values = [0, 1, 5, 10, 50]
# Repeating values so that 200 elements get each diffusivity
diffusivities = np.repeat(diffusivity_values, number/len(diffusivity_values))
o.seed_elements(lon=-60, lat=40, time=datetime(2022,1,1), number=number, radius=10,
environment={'horizontal_diffusivity': diffusivities,
'x_sea_water_velocity': .2,
'y_sea_water_velocity': .2})
ds = o.run(steps=10)
ds.traj.plot(land=None, margin=0)
# Plotting the convex hull around end positions separately for each diffusivity value
ds = ds.isel(time=-1)
colors = plt.cm.jet(np.linspace(0, 1, 5))
for d, color in zip(diffusivity_values, colors):
ds.where(ds.horizontal_diffusivity==d).traj.plot.convex_hull(label=f'Diffusivity {d} m2/s', color=color)
plt.legend()
plt.show()

16:22:10 INFO opendrift:576: OpenDriftSimulation initialised (version 1.14.8 / v1.14.8-15-ge839285)
16:22:10 INFO opendrift.models.basemodel.environment:203: Adding a global landmask from GSHHG
16:22:10 INFO opendrift.models.basemodel.environment:227: Fallback values will be used for the following variables which have no readers:
16:22:10 INFO opendrift.models.basemodel.environment:230: x_sea_water_velocity: 0.000000
16:22:10 INFO opendrift.models.basemodel.environment:230: y_sea_water_velocity: 0.000000
16:22:10 INFO opendrift.models.basemodel.environment:230: sea_surface_height: 0.000000
16:22:10 INFO opendrift.models.basemodel.environment:230: x_wind: 0.000000
16:22:10 INFO opendrift.models.basemodel.environment:230: y_wind: 0.000000
16:22:10 INFO opendrift.models.basemodel.environment:230: upward_sea_water_velocity: 0.000000
16:22:10 INFO opendrift.models.basemodel.environment:230: ocean_vertical_diffusivity: 0.000000
16:22:10 INFO opendrift.models.basemodel.environment:230: horizontal_diffusivity: 0.000000
16:22:10 INFO opendrift.models.basemodel.environment:230: sea_surface_wave_significant_height: 0.000000
16:22:10 INFO opendrift.models.basemodel.environment:230: sea_surface_wave_stokes_drift_x_velocity: 0.000000
16:22:10 INFO opendrift.models.basemodel.environment:230: sea_surface_wave_stokes_drift_y_velocity: 0.000000
16:22:10 INFO opendrift.models.basemodel.environment:230: ocean_mixed_layer_thickness: 50.000000
16:22:10 INFO opendrift.models.basemodel.environment:230: sea_floor_depth_below_sea_level: 10000.000000
16:22:10 INFO opendrift:1836: Skipping environment variable ocean_vertical_diffusivity because of condition ['drift:vertical_mixing', 'is', False]
16:22:10 INFO opendrift:1836: Skipping environment variable ocean_mixed_layer_thickness because of condition ['drift:vertical_mixing', 'is', False]
16:22:10 INFO opendrift:1847: Storing previous values of element property lon because of condition (('general:coastline_action', 'in', ['stranding', 'previous']), 'or', ('general:seafloor_action', 'in', ['previous']))
16:22:10 INFO opendrift:1847: Storing previous values of element property lat because of condition (('general:coastline_action', 'in', ['stranding', 'previous']), 'or', ('general:seafloor_action', 'in', ['previous']))
16:22:10 INFO opendrift:1855: Storing previous values of environment variable sea_surface_height because of condition ['drift:vertical_advection', 'is', True]
16:22:10 INFO opendrift:955: Using existing reader for land_binary_mask to move elements to ocean
16:22:10 INFO opendrift:986: All points are in ocean
16:22:10 INFO opendrift:2144: 2022-01-01 00:00:00 - step 1 of 10 - 1000 active elements (0 deactivated)
16:22:10 INFO opendrift:2144: 2022-01-01 01:00:00 - step 2 of 10 - 1000 active elements (0 deactivated)
16:22:10 INFO opendrift:2144: 2022-01-01 02:00:00 - step 3 of 10 - 1000 active elements (0 deactivated)
16:22:10 INFO opendrift:2144: 2022-01-01 03:00:00 - step 4 of 10 - 1000 active elements (0 deactivated)
16:22:10 INFO opendrift:2144: 2022-01-01 04:00:00 - step 5 of 10 - 1000 active elements (0 deactivated)
16:22:10 INFO opendrift:2144: 2022-01-01 05:00:00 - step 6 of 10 - 1000 active elements (0 deactivated)
16:22:10 INFO opendrift:2144: 2022-01-01 06:00:00 - step 7 of 10 - 1000 active elements (0 deactivated)
16:22:10 INFO opendrift:2144: 2022-01-01 07:00:00 - step 8 of 10 - 1000 active elements (0 deactivated)
16:22:10 INFO opendrift:2144: 2022-01-01 08:00:00 - step 9 of 10 - 1000 active elements (0 deactivated)
16:22:10 INFO opendrift:2144: 2022-01-01 09:00:00 - step 10 of 10 - 1000 active elements (0 deactivated)
The above could also be achieved by performing separate simulations for each value of diffusivity, but with more computational overhead/time and more complexity
Total running time of the script: (0 minutes 18.454 seconds)