def test_reader_boundary(self): # Check that the element outside reader coverage is # not deactivated if fallback value exist o = OceanDrift() nordic3d = reader_ROMS_native.Reader(o.test_data_folder() + '2Feb2016_Nordic_sigma_3d/Nordic-4km_SLEVELS_avg_00_subset2Feb2016.nc') lon = [12.0, 12.0] lat = [70.0, 70.5] o.add_reader(nordic3d) o.fallback_values['land_binary_mask'] = 0 o.seed_elements(lon, lat, number=2, radius=0, time=nordic3d.start_time) o.run(steps=2, time_step=3600) self.assertEqual(o.num_elements_active(), 2) self.assertEqual(o.num_elements_deactivated(), 0) # Check that the outside element is deactivated, # if no fallback value exists o = OceanDrift() del o.fallback_values['x_sea_water_velocity'] o.add_reader(nordic3d) o.fallback_values['land_binary_mask'] = 0 o.seed_elements(lon, lat, number=2, radius=0, time=nordic3d.start_time) o.run(steps=2, time_step=3600) self.assertEqual(o.num_elements_active(), 1) self.assertEqual(o.num_elements_deactivated(), 1)
def test_stranding_options(self): reader_osc = reader_oscillating.Reader( 'x_sea_water_velocity', amplitude=1, zero_time=datetime.now()) reader_basemap = reader_basemap_landmask.Reader( llcrnrlon=12, llcrnrlat=67.6, urcrnrlon=13.6, urcrnrlat=68.1, resolution='i', projection='merc') # Three different stranding options, with # expected final status and position options = ['stranding', 'previous', 'none'] status = ['stranded', 'active', 'active'] lons = [12.930, 13.348, 12.444] for i, option in enumerate(options): o = OceanDrift(loglevel=30) o.set_config('general:coastline_action', option) o.add_reader([reader_osc, reader_basemap]) # Adding northwards drift o.fallback_values['y_sea_water_velocity'] = .2 o.seed_elements(lon=12.2, lat=67.7, radius=0, time=reader_osc.zero_time) o.run(steps=28, time_step=3600*2) print 'Testing stranding: %s' % option if len(o.elements) == 1: el = o.elements else: el = o.elements_deactivated self.assertEqual(o.status_categories[int(el.status)], status[i]) self.assertAlmostEqual(el.lon, lons[i], 2)
def test_buffer_length_stranding(self): o1 = OceanDrift(loglevel=20) norkyst = reader_netCDF_CF_generic.Reader(o1.test_data_folder() + '16Nov2015_NorKyst_z_surface/norkyst800_subset_16Nov2015.nc') basemap = reader_basemap_landmask.Reader( llcrnrlon=1, llcrnrlat=59.8, urcrnrlon=6, urcrnrlat=61, resolution='i', projection='merc') o1.add_reader([basemap]) o1.fallback_values['x_sea_water_velocity'] = 1.0 # onshore drift o1.seed_elements(4.8, 60.2, radius=5000, number=100, time=norkyst.start_time) o1.run(steps=100, time_step=900, time_step_output=3600, export_buffer_length=10) # Without buffer o2 = OceanDrift(loglevel=20) o2.add_reader([basemap]) o2.fallback_values['x_sea_water_velocity'] = 1.0 # onshore drift o2.seed_elements(4.8, 60.2, radius=5000, number=100, time=norkyst.start_time) o2.run(steps=100, time_step=900, time_step_output=3600, outfile='test_buffer_length_stranding.nc') self.assertItemsEqual(o1.history['lon'].compressed(), o2.history['lon'].compressed()) self.assertItemsEqual(o1.history['status'].compressed(), o2.history['status'].compressed()) os.remove('test_buffer_length_stranding.nc')
def test_seed_on_land(self): o = OceanDrift(loglevel=0) o.set_config('general:basemap_resolution', 'c') o.seed_elements(lon=9, lat=60, time=datetime.now(), number=100) outfile='out.nc' with self.assertRaises(ValueError): o.run(steps=4, time_step=1800, time_step_output=3600, outfile=outfile) os.remove(outfile)
def test_output_time_step(self): o1 = OceanDrift(loglevel=30) norkyst = reader_netCDF_CF_generic.Reader(o1.test_data_folder() + '16Nov2015_NorKyst_z_surface/norkyst800_subset_16Nov2015.nc') basemap = reader_basemap_landmask.Reader( llcrnrlon=4.5, llcrnrlat=60.0, urcrnrlon=5.2, urcrnrlat=60.5, resolution='i', projection='merc') o1.add_reader([basemap, norkyst]) o1.seed_elements(4.96, 60.1, radius=3000, number=100, time=norkyst.start_time) o1.run(duration=timedelta(hours=12), time_step=timedelta(minutes=30), time_step_output=timedelta(minutes=30), outfile='test_time_step30.nc') # Check length of time array and output array time = o1.get_time_array()[0] self.assertEqual(o1.history.shape[1], len(time)) self.assertEqual(o1.start_time, time[0]) self.assertEqual(o1.time, time[-1]) # Second run, with larger output time step o2 = OceanDrift(loglevel=30) o2.add_reader([basemap, norkyst]) o2.seed_elements(4.96, 60.1, radius=3000, number=100, time=norkyst.start_time) o2.run(duration=timedelta(hours=12), time_step=timedelta(minutes=30), time_step_output=timedelta(minutes=60), outfile='test_time_step60.nc') self.assertEqual(o1.history.shape, (100,25)) self.assertEqual(o2.history.shape, (100,13)) # Check that start and end conditions (longitudes) are idential self.assertItemsEqual(o1.history['lon'][:,24].compressed(), o2.history['lon'][:,12].compressed()) self.assertItemsEqual(o1.history['lon'][:,0].compressed(), o2.history['lon'][:,0].compressed()) # Check that also run imported from file is identical o1i = OceanDrift(loglevel=20) o1i.io_import_file('test_time_step30.nc') o2i = OceanDrift(loglevel=20) o2i.io_import_file('test_time_step60.nc') os.remove('test_time_step30.nc') os.remove('test_time_step60.nc') self.assertItemsEqual(o2i.history['lon'][:,12].compressed(), o2.history['lon'][:,12].compressed()) # Check number of activated elements self.assertEqual(o1.num_elements_total(), o2.num_elements_total()) self.assertEqual(o1.num_elements_total(), o1i.num_elements_total()) self.assertEqual(o1.num_elements_total(), o2i.num_elements_total()) # Check number of deactivated elements self.assertEqual(o1.num_elements_deactivated(), o2.num_elements_deactivated()) self.assertEqual(o1.num_elements_deactivated(), o1i.num_elements_deactivated()) self.assertEqual(o1.num_elements_deactivated(), o2i.num_elements_deactivated())
def test_seed_on_land(self): o = OceanDrift(loglevel=50) o.set_config('general:basemap_resolution', 'c') o.seed_elements(lon=9, lat=60, time=datetime.now(), number=100) outfile='out.nc' o.run(steps=4, time_step=1800, time_step_output=3600, outfile=outfile) os.remove(outfile) o.write_netcdf_density_map(outfile) os.remove(outfile)
def test_ROMS_native_stranding(self): o = OceanDrift(loglevel=30) r = reader_ROMS_native.Reader( o.test_data_folder() + '2Feb2016_Nordic_sigma_3d/Nordic-4km_SLEVELS_avg_00_subset2Feb2016.nc' ) o.add_reader(r) o.set_config('general:use_auto_landmask', False) o.fallback_values['x_wind'] = 0 o.fallback_values['y_wind'] = 10 o.seed_elements(lon=15.2, lat=68.3, time=r.start_time, wind_drift_factor=.02, number=10, radius=1000) o.run(steps=8) self.assertEqual(o.num_elements_deactivated(), 4)
def test_interact_coastline(self): reader_basemap = reader_basemap_landmask.Reader(llcrnrlon=4.5, llcrnrlat=60.4, urcrnrlon=6, urcrnrlat=60.6, resolution='c', projection='merc') o = OceanDrift(loglevel=50) o.set_config('general:coastline_action', 'previous') o.add_reader(reader_basemap) o.fallback_values['x_sea_water_velocity'] = .7 o.seed_elements(lon=5, lat=60.5, time=datetime.now()) o.run(time_step=3600, steps=30) lons = o.history['lon'][0] self.assertAlmostEqual(lons[0], 5, 2) self.assertAlmostEqual(lons[-2], 5.366, 2) self.assertAlmostEqual(lons[-1], 5.366, 2)
def simulate_opendrift(source_url, lat, lon, wind_drift_factor=0.0, velocity_average=True, duration=23): """ source_url: url or local file or list of either with fielddata in NetCDF-format output_filename: name of file in which to save calculated trajectory lat, lon: initial coordinates of single drifter or lists with coordinates for multiple drifters. wind_drift_factor: fraction of wind-speed at which objects will be advected. Default is 0 (no direct wind-drift) velocity_average: Boolean variable deciding whether averaged horisontal velocities or surface velocities will be used. Default is average which is consistent with GPU Ocean duration: duration of the simulation in hours. Default is 24 hours. TODO: Add functionality to start drifters at a later time in the simulation like in GPU Ocean. Can quite easily make random distribution of starting position if comparing with GPU Monte Carlo. """ reader_norkyst = reader_netCDF_CF_generic.Reader(source_url) o = OceanDrift(loglevel=50) if velocity_average: reader_norkyst.variable_mapping['x_sea_water_velocity'] = 'ubar' reader_norkyst.variable_mapping['y_sea_water_velocity'] = 'vbar' o.add_reader(reader_norkyst, variables=[ 'x_sea_water_velocity', 'y_sea_water_velocity', 'x_wind', 'y_wind' ]) o.seed_elements(lon=lon, lat=lat, time=reader_norkyst.start_time, wind_drift_factor=wind_drift_factor) o.set_config( 'drift:scheme', 'runge-kutta4' ) #Set to runge-kutta4, which is the same as Parcels. Default is euler. o.run(duration=timedelta(hours=duration), time_step=300, time_step_output=300) return o
def test_valid_minmax(self): """Check that invalid values are replaced with fallback.""" o = OceanDrift() from opendrift.readers.basereader import variables minval = variables.standard_names['x_wind']['valid_min'] # Setting valid_min to -5, to check that replacement works variables.standard_names['x_wind']['valid_min'] = -5 reader_wind = reader_netCDF_CF_generic.Reader(o.test_data_folder() + '16Nov2015_NorKyst_z_surface/arome_subset_16Nov2015.nc') o.add_reader(reader_wind) o.set_config('environment:fallback:x_sea_water_velocity', 0) o.set_config('environment:fallback:x_wind', 2.0) o.set_config('environment:fallback:y_sea_water_velocity', 0) o.set_config('environment:fallback:land_binary_mask', 0) o.seed_elements(lon=4, lat=60, time=reader_wind.start_time) o.run(steps=1) variables.standard_names['x_wind']['valid_min'] = minval # reset w = o.get_property('x_wind')[0][0] self.assertAlmostEqual(w, 2.0, 1)
def test_buffer_length_stranding(self): o1 = OceanDrift(loglevel=30) norkyst = reader_netCDF_CF_generic.Reader( o1.test_data_folder() + '16Nov2015_NorKyst_z_surface/norkyst800_subset_16Nov2015.nc') basemap = reader_basemap_landmask.Reader(llcrnrlon=4.5, llcrnrlat=60.1, urcrnrlon=6.0, urcrnrlat=60.4, resolution='c', projection='merc') o1.add_reader([basemap]) o1.fallback_values['x_sea_water_velocity'] = 0.8 # onshore drift o1.seed_elements(4.8, 60.2, radius=5000, number=100, time=norkyst.start_time) o1.run(steps=100, time_step=900, time_step_output=3600, export_buffer_length=10) # Without buffer o2 = OceanDrift(loglevel=30) o2.add_reader([basemap]) o2.fallback_values['x_sea_water_velocity'] = 0.8 # onshore drift o2.seed_elements(4.8, 60.2, radius=5000, number=100, time=norkyst.start_time) o2.run(steps=100, time_step=900, time_step_output=3600, outfile='test_buffer_length_stranding.nc') self.assertIsNone( np.testing.assert_array_equal(o1.history['lon'].compressed(), o2.history['lon'].compressed())) self.assertIsNone( np.testing.assert_array_almost_equal( o1.history['status'].compressed(), o2.history['status'].compressed())) os.remove('test_buffer_length_stranding.nc')
def test_valid_minmax_nanvalues(self): from opendrift.readers.basereader import variables # Reducing max current speed to test masking maxval = variables.standard_names['x_sea_water_velocity']['valid_max'] variables.standard_names['x_sea_water_velocity']['valid_max'] = .1 o = OceanDrift(loglevel=20) o.set_config('environment:fallback:land_binary_mask', 0) norkyst = reader_netCDF_CF_generic.Reader( o.test_data_folder() + '14Jan2016_NorKyst_z_3d/NorKyst-800m_ZDEPTHS_his_00_3Dsubset.nc') o.add_reader(norkyst) o.seed_elements(lon=4.95, lat=62, number=10, time=norkyst.start_time) o.run(steps=2) variables.standard_names['x_sea_water_velocity'][ 'valid_max'] = maxval # reset u = o.get_property('x_sea_water_velocity')[0] self.assertAlmostEqual(u.max(), -.069, 3) # Some numerical error allowed
def test_no_active_but_still_unseeded_elements(self): o = OceanDrift(loglevel=20) # deactivate elements after 3 hours o.set_config('drift:max_age_seconds', 3600 * 3) norkyst = reader_netCDF_CF_generic.Reader( o.test_data_folder() + '14Jan2016_NorKyst_z_3d/NorKyst-800m_ZDEPTHS_his_00_3Dsubset.nc') o.add_reader(norkyst) # seed two elements at 6 hour interval o.seed_elements( number=2, lon=4, lat=62, time=[norkyst.start_time, norkyst.start_time + timedelta(hours=6)]) o.set_config('environment:fallback:land_binary_mask', 0) o.run(duration=timedelta(hours=8), outfile='test.nc') os.remove('test.nc') # Check that simulations has run until scheduled end self.assertEqual(o.steps_calculation, 8)
def test_export_step_interval(self): # Export to file only at end o1 = OceanDrift(loglevel=20) norkyst = reader_netCDF_CF_generic.Reader( o1.test_data_folder() + '16Nov2015_NorKyst_z_surface/norkyst800_subset_16Nov2015.nc') o1.add_reader(norkyst) o1.fallback_values['land_binary_mask'] = 0 o1.seed_elements(4.25, 60.2, radius=1000, number=10, time=norkyst.start_time) o1.run(steps=40) # Export to file during simulation o2 = OceanDrift(loglevel=20) o2.add_reader(norkyst) o2.fallback_values['land_binary_mask'] = 0 o2.seed_elements(4.25, 60.2, radius=1000, number=10, time=norkyst.start_time) o2.run(steps=40, export_buffer_length=6, outfile='export_step_interval.nc') self.assertItemsEqual(o1.history['lon'].compressed(), o2.history['lon'].compressed()) # Finally check when steps is multiple of export_buffer_length o3 = OceanDrift(loglevel=20) o3.add_reader(norkyst) o3.fallback_values['land_binary_mask'] = 0 o3.seed_elements(4.25, 60.2, radius=1000, number=10, time=norkyst.start_time) o3.run(steps=42) # Export to file during simulation o4 = OceanDrift(loglevel=20) o4.add_reader(norkyst) o4.fallback_values['land_binary_mask'] = 0 o4.seed_elements(4.25, 60.2, radius=1000, number=10, time=norkyst.start_time) o4.run(steps=42, export_buffer_length=6, outfile='export_step_interval.nc') self.assertItemsEqual(o3.history['lon'].compressed(), o4.history['lon'].compressed()) os.remove('export_step_interval.nc')
def test_outside_domain(self): o = OceanDrift(loglevel=50) reader_osc_x = reader_oscillating.Reader( 'x_sea_water_velocity', amplitude=1, zero_time=datetime.now()) reader_osc_y = reader_oscillating.Reader( 'y_sea_water_velocity', amplitude=1, zero_time=datetime.now()) o.add_reader([reader_osc_x, reader_osc_y]) o.set_config('drift:deactivate_east_of', 2.1) o.set_config('drift:deactivate_west_of', 1.9) o.set_config('drift:deactivate_south_of', 59.9) o.set_config('drift:deactivate_north_of', 60.1) o.fallback_values['land_binary_mask'] = 0 o.seed_elements(lon=2, lat=60, number=1000, time=datetime.now(), radius=10000) o.run(duration=timedelta(hours=5)) self.assertEqual(o.num_elements_deactivated(), 768) self.assertEqual(o.num_elements_active(), 232)
def test_profile(): o = OceanDrift() r = reader_netCDF_CF_unstructured.Reader(akvaplan, proj4=proj) o.add_reader(r) o.seed_elements(lon=17, lat=70, z=np.atleast_1d([0, -10, -50]), number=3, time=r.start_time) print(o) o.run(steps=3) #o.plot(linecolor='z') # Elements at 0 and 10m depth should not have same trajectory # This is ok assert o.elements.lon[0] != o.elements.lon[1] # Elements at 10 and 50m depth should not have same trajectory # This is presently failing assert o.elements.lon[1] != o.elements.lon[2]
def test_stranding_options(self): reader_osc = reader_oscillating.Reader( 'x_sea_water_velocity', amplitude=.5, period_seconds=3600*6, zero_time=datetime.now()) reader_global = reader_global_landmask.Reader() # Three different stranding options, with # expected final status and position options = ['stranding', 'previous', 'none'] status = ['stranded', 'active', 'active'] lons_backward = [16.157, 16.087, 16.167] lons_forward = [16.198, 16.115, 16.167] for i, option in enumerate(options): for direction in ['forward', 'backward']: if direction == 'forward': lons = lons_forward time_step = 900 else: lons = lons_backward time_step = -900 o = OceanDrift(loglevel=50) o.set_config('general:coastline_action', option) o.add_reader([reader_osc, reader_global]) # Adding northwards drift o.set_config('environment:constant:y_sea_water_velocity', .1) #o.seed_elements(lon=13.35, lat=68.0, radius=0, o.seed_elements(lon=16.12, lat=68.5, radius=0, time=reader_osc.zero_time) o.run(duration=timedelta(hours=22), time_step=time_step) #o.animation() #o.plot () print('Testing stranding: %s, %s' % (option, direction)) if len(o.elements) == 1: el = o.elements else: el = o.elements_deactivated self.assertEqual(o.status_categories[int(el.status)], status[i]) self.assertIsNone(np.testing.assert_array_almost_equal( el.lon, lons[i], 3))
def test_wind_and_current_drift_factor(self): lat=60 lon=4 o = OceanDrift(loglevel=50) o.seed_elements(lon=lon, lat=lat, time=datetime.now(), wind_drift_factor=0, current_drift_factor=1) o.set_config('general:use_auto_landmask', False) o.set_config('environment:constant:land_binary_mask', 0) o.set_config('environment:constant:x_wind', 5) o.set_config('environment:constant:y_sea_water_velocity', 1) o.run(duration=timedelta(hours=2)) o2 = OceanDrift() o2.seed_elements(lon=lon, lat=lat, time=datetime.now(), wind_drift_factor=0.02, current_drift_factor=.3) o2.set_config('general:use_auto_landmask', False) o2.set_config('environment:constant:land_binary_mask', 0) o2.set_config('environment:constant:x_wind', 5) o2.set_config('environment:constant:y_sea_water_velocity', 1) o2.run(duration=timedelta(hours=2)) self.assertAlmostEqual(o.elements.lat[0], lat + 0.0646, 3) self.assertAlmostEqual(o.elements.lon[0], lon) self.assertAlmostEqual(o2.elements.lat[0], lat + 0.0646*.3, 3) self.assertAlmostEqual(o2.elements.lon[0], lon + 0.0129, 3)
def test_density(self): """Test density""" outfile = 'test_xarray.nc' if os.path.exists(outfile): os.remove(outfile) o = OceanDrift(loglevel=20) o.set_config('environment:fallback:land_binary_mask', 0) t1 = datetime.now() t2 = t1 + timedelta(hours=6) o.seed_elements(time=t1, lon=4, lat=60, number=100, origin_marker=0) o.seed_elements(time=[t1, t2], lon=4.2, lat=60.2, number=100, origin_marker=1) o.seed_elements(time=[t1, t2], lon=4.1, lat=60.1, number=100, origin_marker=2) reader_x = reader_oscillating.Reader('x_sea_water_velocity', amplitude=1, zero_time=t1) reader_y = reader_oscillating.Reader('y_sea_water_velocity', amplitude=1, zero_time=t2) o.add_reader([reader_x, reader_y]) o.set_config('drift:horizontal_diffusivity', 10) o.run(duration=timedelta(hours=12), time_step=1800, outfile=outfile) #o.plot(fast=True) density_pixelsize_m=5000 H, Hsub, Hsurf, lon_array, lat_array = o.get_density_array(pixelsize_m=density_pixelsize_m) ox = opendrift.open_xarray(outfile) Hx = ox.get_histogram(pixelsize_m=density_pixelsize_m) self.assertAlmostEqual(lon_array[0], 3.94, 1) self.assertAlmostEqual(lon_array[-1], 4.76, 1) self.assertAlmostEqual(Hx.lon_bin[0].values, 3.90, 1) self.assertAlmostEqual(Hx.lon_bin[-1].values, 4.67, 1) self.assertEqual(Hx.sum(dim='origin_marker').shape, H.shape) Hsum = H.sum(axis=1).sum(axis=1) Hxsum = Hx.sum(('lon_bin', 'lat_bin', 'origin_marker')) self.assertEqual(Hsum[0], 118) self.assertEqual(Hxsum[0], 118) self.assertEqual(Hsum[-1], 300) self.assertEqual(Hxsum[-1], 300) os.remove(outfile)
def test_reader_order(self): # Check that we get the same output indepenently of reader order o = OceanDrift(loglevel=50) norkyst = reader_netCDF_CF_generic.Reader(o.test_data_folder() + '16Nov2015_NorKyst_z_surface/norkyst800_subset_16Nov2015.nc') arome = reader_netCDF_CF_generic.Reader(o.test_data_folder() + '16Nov2015_NorKyst_z_surface/arome_subset_16Nov2015.nc') basemap = reader_basemap_landmask.Reader( llcrnrlon=2, llcrnrlat=59.8, urcrnrlon=6, urcrnrlat=61, resolution='c', projection='merc') lon=4.; lat=60. # First run o.add_reader([basemap, norkyst, arome]) o.seed_elements(lon, lat, time=norkyst.start_time) o.run(steps=30) # Second run # Check that we get almost identical results with other projection o1 = OceanDrift(loglevel=50) o1.add_reader([norkyst, arome, basemap]) o1.seed_elements(lon, lat, time=norkyst.start_time) o1.run(steps=30) self.assertAlmostEqual(o.elements.lon, o1.elements.lon, 2) self.assertAlmostEqual(o.elements.lat, o1.elements.lat, 2) # Third run # Check that this is identical to run 1 if projection set equal o2 = OceanDrift(loglevel=50) o2.add_reader([norkyst, arome, basemap]) o2.seed_elements(lon, lat, time=norkyst.start_time) o2.set_projection(basemap.proj4) o2.run(steps=30) self.assertEqual(o.elements.lon, o2.elements.lon)
def test_reader_order(self): # Check that we get the same output indepenently of reader order o = OceanDrift(loglevel=50) norkyst = reader_netCDF_CF_generic.Reader(o.test_data_folder() + '16Nov2015_NorKyst_z_surface/norkyst800_subset_16Nov2015.nc') arome = reader_netCDF_CF_generic.Reader(o.test_data_folder() + '16Nov2015_NorKyst_z_surface/arome_subset_16Nov2015.nc') landmask = reader_global_landmask.Reader(extent = [2, 59.8, 6, 61]) lon=4.; lat=60. # First run o.add_reader([landmask, norkyst, arome]) o.seed_elements(lon, lat, time=norkyst.start_time) o.run(steps=30) # Second run # Check that we get almost identical results with other projection o1 = OceanDrift(loglevel=50) o1.add_reader([norkyst, arome, landmask]) o1.seed_elements(lon, lat, time=norkyst.start_time) o1.run(steps=30) np.testing.assert_array_almost_equal( o.elements.lon, o1.elements.lon, 2) np.testing.assert_array_almost_equal( o.elements.lat, o1.elements.lat, 2) # Third run # Check that this is identical to run 1 if projection set equal o2 = OceanDrift(loglevel=50) o2.add_reader([norkyst, arome, landmask]) o2.seed_elements(lon, lat, time=norkyst.start_time) o2.set_projection(landmask.proj4) o2.run(steps=30) np.testing.assert_array_almost_equal( o.elements.lon, o2.elements.lon, decimal=3)
def test_buffer_length_stranding(self): o1 = OceanDrift(loglevel=30) norkyst = reader_netCDF_CF_generic.Reader( o1.test_data_folder() + '16Nov2015_NorKyst_z_surface/norkyst800_subset_16Nov2015.nc') landmask = reader_global_landmask.Reader(extent=[4.5, 6.0, 60.1, 60.4]) o1.add_reader([landmask]) o1.set_config('environment:fallback:x_sea_water_velocity', 0.8) # onshore drift o1.seed_elements(4.8, 60.2, radius=5000, number=100, time=norkyst.start_time) o1.run(steps=100, time_step=900, time_step_output=3600, export_buffer_length=10) # Without buffer o2 = OceanDrift(loglevel=30) o2.add_reader([landmask]) o2.set_config('environment:fallback:x_sea_water_velocity', 0.8) # onshore drift o2.seed_elements(4.8, 60.2, radius=5000, number=100, time=norkyst.start_time) o2.run(steps=100, time_step=900, time_step_output=3600, outfile='test_buffer_length_stranding.nc') self.assertIsNone( np.testing.assert_array_equal(o1.history['lon'].compressed(), o2.history['lon'].compressed())) self.assertIsNone( np.testing.assert_array_almost_equal( o1.history['status'].compressed(), o2.history['status'].compressed())) os.remove('test_buffer_length_stranding.nc')
def test_stranding_options(self): reader_osc = reader_oscillating.Reader('x_sea_water_velocity', amplitude=1, zero_time=datetime.now()) reader_basemap = reader_basemap_landmask.Reader(llcrnrlon=12, llcrnrlat=67.6, urcrnrlon=13.6, urcrnrlat=68.1, resolution='i', projection='merc') # Three different stranding options, with # expected final status and position options = ['stranding', 'previous', 'none'] status = ['stranded', 'active', 'active'] lons = [12.930, 13.348, 12.444] for i, option in enumerate(options): o = OceanDrift(loglevel=30) o.set_config('general:coastline_action', option) o.add_reader([reader_osc, reader_basemap]) # Adding northwards drift o.fallback_values['y_sea_water_velocity'] = .2 o.seed_elements(lon=12.2, lat=67.7, radius=0, time=reader_osc.zero_time) o.run(steps=28, time_step=3600 * 2) #o.plot() print('Testing stranding: %s' % option) if len(o.elements) == 1: el = o.elements else: el = o.elements_deactivated self.assertEqual(o.status_categories[int(el.status)], status[i]) self.assertIsNone( np.testing.assert_array_almost_equal(el.lon, lons[i], 2))
def test_config_constant_fallback(self): o = OceanDrift(loglevel=0) reader_arome = reader_netCDF_CF_generic.Reader(o.test_data_folder() + '16Nov2015_NorKyst_z_surface/arome_subset_16Nov2015.nc') reader_norkyst = reader_netCDF_CF_generic.Reader(o.test_data_folder() + '16Nov2015_NorKyst_z_surface/norkyst800_subset_16Nov2015.nc') print(reader_norkyst, reader_arome) o.add_reader([reader_norkyst, reader_arome]) o.seed_elements(lon=4, lat=60, time=reader_arome.end_time - timedelta(hours=3), number=1) o.set_config('environment:fallback:land_binary_mask', 0) o.set_config('environment:fallback:x_sea_water_velocity', 1) o.set_config('environment:fallback:y_sea_water_velocity', 0) o.set_config('environment:constant:x_wind', 0) o.set_config('environment:constant:y_wind', 5) o.run(duration=timedelta(hours=6)) y_wind = np.array(o.get_property('y_wind')[0][:,0]) x_current = np.array(o.get_property('x_sea_water_velocity')[0][:,0]) # Check that constant wind is used for whole simulation self.assertAlmostEqual(y_wind[0], 5, 2) self.assertAlmostEqual(y_wind[-1], 5, 2) # Check that fallback current is used only after end of reader self.assertAlmostEqual(x_current[0], 0.155, 2) self.assertAlmostEqual(x_current[-1], 1, 2)
def test_MFDataset(self): reader_landmask = reader_global_landmask.Reader( extent=[13.5, 14.6, 67.1, 67.7]) o = OceanDrift(loglevel=30) nordicMF = reader_ROMS_native.Reader(o.test_data_folder() + '2Feb2016_Nordic_sigma_3d/Nordic_subset_day*.nc') nordicMF_all = reader_ROMS_native.Reader(o.test_data_folder() + '2Feb2016_Nordic_sigma_3d/Nordic_subset.nc') lon = 14.0 lat = 67.3 #nordic3d = reader_ROMS_native.Reader(o.test_data_folder() + # '2Feb2016_Nordic_sigma_3d/Nordic-4km_SLEVELS_avg_00_subset2Feb2016.nc') #o.add_reader(nordic3d) # Slightly different results # Subset is made with ncks, and should give identical result # e0=0, e1=20, x0=40, x1=70 # ncks -d eta_rho,0,$e1 -d eta_psi,0,$e1 -d eta_v,0,$e1 -d eta_u,0,$e1 -d xi_rho,$x0,$x1 -d xi_psi,$x0,$x1 -d xi_v,$x0,$x1 -d xi_u,$x0,$x1 Nordic-4km_SLEVELS_avg_00_subset2Feb2016.nc Nordic_subset.nc -O --fl_fmt=netcdf4_classic # ncks -O -d ocean_time,0 Nordic_subset.nc Nordic_subset_day1.nc o.add_reader([reader_landmask, nordicMF_all]) o.seed_elements(lon, lat, number=100, radius=5000, time=nordicMF_all.start_time) o.run(steps=48, time_step=3600) print('='*99) # Same run, with multi-file dataset o2 = OceanDrift(loglevel=30) o2.add_reader([reader_landmask, nordicMF]) o2.seed_elements(lon, lat, number=100, radius=5000, time=nordicMF_all.start_time) o2.run(steps=48, time_step=3600) #o.plot(filename='o1.png', background='sea_floor_depth_below_sea_level') #o2.plot(filename='o2.png', background='sea_floor_depth_below_sea_level') assert o.num_elements_active() == 44 assert o2.num_elements_active() == 44 assert o.num_elements_deactivated() == 56 assert o2.num_elements_deactivated() == 56 self.assertAlmostEqual(o.elements.lon[0], o2.elements.lon[0], 5)
def test_time_step_config(self): # Default o = OceanDrift(loglevel=50) o.set_config('environment:fallback:land_binary_mask', 0) o.seed_elements(lon=4, lat=60, time=datetime.now()) o.run(steps=2) self.assertEqual(o.time_step.total_seconds(), 3600) self.assertEqual(o.time_step_output.total_seconds(), 3600) # Setting time_step o = OceanDrift(loglevel=50) o.set_config('environment:fallback:land_binary_mask', 0) o.seed_elements(lon=4, lat=60, time=datetime.now()) o.run(steps=2, time_step=1800) self.assertEqual(o.time_step.total_seconds(), 1800) # Setting time_step and time_step_output o = OceanDrift(loglevel=50) o.set_config('environment:fallback:land_binary_mask', 0) o.seed_elements(lon=4, lat=60, time=datetime.now()) o.run(steps=2, time_step=1800, time_step_output=3600) self.assertEqual(o.time_step.total_seconds(), 1800) self.assertEqual(o.time_step_output.total_seconds(), 3600) # time_step from config o = OceanDrift(loglevel=50) o.set_config('environment:fallback:land_binary_mask', 0) o.seed_elements(lon=4, lat=60, time=datetime.now()) o.set_config('general:time_step_minutes', 15) o.run(steps=2) self.assertEqual(o.time_step.total_seconds(), 900) self.assertEqual(o.time_step_output.total_seconds(), 900) # time_step and time_step_output from config o = OceanDrift(loglevel=50) o.set_config('environment:fallback:land_binary_mask', 0) o.seed_elements(lon=4, lat=60, time=datetime.now()) o.set_config('general:time_step_minutes', 15) o.set_config('general:time_step_output_minutes', 120) o.run(steps=2) self.assertEqual(o.time_step.total_seconds(), 900) self.assertEqual(o.time_step_output.total_seconds(), 7200)
def test_runge_kutta(self): number = 50 # With Euler o = OceanDrift(loglevel=30, seed=0) norkyst = reader_netCDF_CF_generic.Reader( o.test_data_folder() + '14Jan2016_NorKyst_z_3d/NorKyst-800m_ZDEPTHS_his_00_3Dsubset.nc') o.set_config('environment:fallback:land_binary_mask', 0) o.add_reader([norkyst]) z = -40 * np.random.rand(number) o.seed_elements(5, 62.5, number=number, radius=5000, z=z, time=norkyst.start_time) o.run(steps=4 * 3, time_step=timedelta(minutes=15)) # With Runge-Kutta o2 = OceanDrift(loglevel=30, seed=0) norkyst = reader_netCDF_CF_generic.Reader( o.test_data_folder() + '14Jan2016_NorKyst_z_3d/NorKyst-800m_ZDEPTHS_his_00_3Dsubset.nc') o2.set_config('environment:fallback:land_binary_mask', 0) o2.add_reader([norkyst]) z = -40 * np.random.rand(number) o2.seed_elements(5, 62.5, number=number, radius=5000, z=z, time=norkyst.start_time) o2.set_config('drift:advection_scheme', 'runge-kutta') o2.run(steps=4 * 3, time_step=timedelta(minutes=15)) # And finally repeating the initial run to check that indetical o3 = OceanDrift(loglevel=30, seed=0) norkyst = reader_netCDF_CF_generic.Reader( o.test_data_folder() + '14Jan2016_NorKyst_z_3d/NorKyst-800m_ZDEPTHS_his_00_3Dsubset.nc') o3.set_config('environment:fallback:land_binary_mask', 0) o3.add_reader([norkyst]) z = -40 * np.random.rand(number) o3.seed_elements(5, 62.5, number=number, radius=5000, z=z, time=norkyst.start_time) o3.run(steps=4 * 3, time_step=timedelta(minutes=15)) # Check that we get some difference with Runge-Kutta: self.assertIsNone( np.testing.assert_array_almost_equal( (o2.elements.lon - o.elements.lon).max(), 0.0015, 3)) #(o2.elements.lon-o.elements.lon).max(), 0.013, 3)) # Check that runs with Euler are identical self.assertIsNone( np.testing.assert_array_almost_equal( (o3.elements.lon - o.elements.lon).max(), 0))
def test_environment_mapping(test_data): # Wind from NE r = reader_constant.Reader({ 'wind_speed': 5, 'wind_from_direction': 45, 'land_binary_mask': 0 }) o = OceanDrift(loglevel=50) o.set_config('general:use_auto_landmask', False) o.add_reader(r) o.seed_elements(lon=4, lat=60, time=datetime.now()) o.run(steps=15) np.testing.assert_almost_equal(o.elements.lon, 3.932, 3) np.testing.assert_almost_equal(o.elements.lat, 59.966, 3) # Wind from SW r = reader_constant.Reader({ 'wind_speed': 5, 'wind_from_direction': 225, 'land_binary_mask': 0 }) o = OceanDrift(loglevel=50) o.set_config('general:use_auto_landmask', False) o.add_reader(r) o.seed_elements(lon=4, lat=60, time=datetime.now()) o.run(steps=15) np.testing.assert_almost_equal(o.elements.lon, 4.068, 3) np.testing.assert_almost_equal(o.elements.lat, 60.034, 3) # land_binary_mask mapped from sea_floor_depth_below_sea_level r = reader_netCDF_CF_generic.Reader( o.test_data_folder() + '14Jan2016_NorKyst_z_3d/NorKyst-800m_ZDEPTHS_his_00_3Dsubset.nc') assert 'land_binary_mask' not in r.derived_variables # Disabled by default r.activate_environment_mapping('land_binary_mask_from_ocean_depth') assert 'land_binary_mask' in r.derived_variables
def test_export_step_interval(self): # Export to file only at end o1 = OceanDrift(loglevel=20) norkyst = reader_netCDF_CF_generic.Reader(o1.test_data_folder() + '16Nov2015_NorKyst_z_surface/norkyst800_subset_16Nov2015.nc') o1.add_reader(norkyst) o1.fallback_values['land_binary_mask'] = 0 o1.seed_elements(4.25, 60.2, radius=1000, number=10, time=norkyst.start_time) o1.run(steps=40) # Export to file during simulation o2 = OceanDrift(loglevel=20) o2.add_reader(norkyst) o2.fallback_values['land_binary_mask'] = 0 o2.seed_elements(4.25, 60.2, radius=1000, number=10, time=norkyst.start_time) o2.run(steps=40, export_buffer_length=6, outfile='export_step_interval.nc') self.assertItemsEqual(o1.history['lon'].compressed(), o2.history['lon'].compressed()) # Finally check when steps is multiple of export_buffer_length o3 = OceanDrift(loglevel=20) o3.add_reader(norkyst) o3.fallback_values['land_binary_mask'] = 0 o3.seed_elements(4.25, 60.2, radius=1000, number=10, time=norkyst.start_time) o3.run(steps=42) # Export to file during simulation o4 = OceanDrift(loglevel=20) o4.add_reader(norkyst) o4.fallback_values['land_binary_mask'] = 0 o4.seed_elements(4.25, 60.2, radius=1000, number=10, time=norkyst.start_time) o4.run(steps=42, export_buffer_length=6, outfile='export_step_interval.nc') self.assertItemsEqual(o3.history['lon'].compressed(), o4.history['lon'].compressed()) os.remove('export_step_interval.nc')
def test_truncate_ocean_model(self): o = OceanDrift(loglevel=30) reader_nordic = reader_ROMS_native.Reader(o.test_data_folder() + \ '2Feb2016_Nordic_sigma_3d/Nordic-4km_SLEVELS_avg_00_subset2Feb2016.nc') o.add_reader(reader_nordic) o.seed_elements(lon=15.0, lat=71.1, radius=0, number=10, z=np.linspace(-90, 0, 10), time=reader_nordic.start_time) o.set_config('general:use_auto_landmask', False) o.run(steps=5) o2 = OceanDrift(loglevel=30) o2.add_reader(reader_nordic) o2.set_config('drift:truncate_ocean_model_below_m', 50) o2.seed_elements(lon=15.0, lat=71.1, radius=0, number=10, z=np.linspace(-90, 0, 10), time=reader_nordic.start_time) o2.set_config('general:use_auto_landmask', False) o2.run(steps=5) o3 = OceanDrift(loglevel=30) o3.add_reader(reader_nordic) o3.set_config('drift:truncate_ocean_model_below_m', 50) o3.seed_elements(lon=15.0, lat=71.1, radius=0, number=10, z=np.linspace(-90, 0, 10), time=reader_nordic.start_time) o3.set_config('general:use_auto_landmask', False) o3.run(steps=5) # Final depths should not be affected self.assertIsNone( np.testing.assert_array_almost_equal(o.elements.z, o3.elements.z)) # Surface elements should not be affected self.assertEqual(o.elements.lat[-1], o3.elements.lat[-1]) # Elements at 90m depth should be somewht affected self.assertNotEqual(o.elements.lat[0], o3.elements.lat[0]) # For second run, only elements below 50m should be equal self.assertEqual(o2.elements.lat[1], o2.elements.lat[2]) self.assertNotEqual(o2.elements.lat[8], o2.elements.lat[9])
from opendrift.readers import reader_ArtificialOceanEddy from opendrift.models.oceandrift import OceanDrift o = OceanDrift(loglevel=0) # Set loglevel to 0 for debug information fake_eddy = reader_ArtificialOceanEddy.Reader(2, 62) reader_basemap = reader_basemap_landmask.Reader( llcrnrlon=-1.5, llcrnrlat=59, urcrnrlon=7, urcrnrlat=64, resolution='h') o.add_reader([fake_eddy, reader_basemap]) lon = 2.0; lat = 63.0; # Close to Station M # First run, with Euler scheme: o.set_config('drift:scheme', 'euler') o.seed_elements(lon, lat, radius=0, number=1, time=datetime(2015,1,1)) o.run(steps=300, time_step=3600) # Second run, with Runge-Kutta scheme: o2 = OceanDrift(loglevel=20) # Set loglevel to 0 for debug information o2.add_reader([fake_eddy, reader_basemap]) o2.set_config('drift:scheme', 'runge-kutta') o2.seed_elements(lon, lat, radius=0, number=1, time=datetime(2015,1,1)) o2.run(steps=300, time_step=3600) o.plot(compare=o2, legend=['Euler scheme', 'Runge-Kutta scheme']) #o2.plot() # Animate and compare the two runs o.animation(compare=o2, legend=['Euler scheme', 'Runge-Kutta scheme'])
o.add_reader([reader_natural, reader_nordic]) o.set_config('general:use_auto_landmask', False) o.set_config('general:coastline_action', 'stranding') #%% # Seeding elements on a grid lons = np.linspace(12, 14.5, 30) lats = np.linspace(67.5, 68.5, 30) lons, lats = np.meshgrid(lons, lats) lon = lons.ravel() lat = lats.ravel() time = reader_nordic.start_time o.seed_elements(lon, lat, radius=0, number=30 * 30, time=time) o.run(steps=48 * 2, time_step=3600) #%% # Print and plot results print(o) ax, _ = o.plot(hide_landmask=True, show=False) #%% # Show shapes ax.add_geometries(reader_natural.polys, ccrs.PlateCarree(), facecolor=cfeature.COLORS['land'], edgecolor='black') plt.show() o.animation()
# Landmask (Basemap) reader_basemap = reader_basemap_landmask.Reader( llcrnrlon=4.0, llcrnrlat=59.9, urcrnrlon=5.5, urcrnrlat=61.2, resolution='h', projection='merc') o.add_reader([reader_basemap, reader_norkyst]) # Seeding some particles lons = np.linspace(4.4, 4.6, 10) lats = np.linspace(60.0, 60.1, 10) lons, lats = np.meshgrid(lons, lats) lons = lons.ravel() lats = lats.ravel() # Seed oil elements on a grid at regular time interval start_time = reader_norkyst.start_time time_step = timedelta(hours=6) num_steps = 10 for i in range(num_steps+1): o.seed_elements(lons, lats, radius=0, number=100, time=start_time + i*time_step) # Running model (until end of driver data) o.run(steps=66*4, time_step=900) # Print and plot results print(o) o.animation()
proj4=proj) o.add_reader(fvcom) print(fvcom) # Seed elements at defined positions, depth and time N = 1000 z = -10 * np.random.uniform(0, 1, N) o.seed_elements(lon=18.0, lat=69.8, radius=2000, number=N, z=z, time=fvcom.start_time) #%% # Running model o.run(time_step=1800, duration=timedelta(hours=12)) #%% # Print and plot results print(o) #%% # Animation (current as background not yet working). o.animation(color='z') #%% # .. image:: /gallery/animations/example_fvcom_0.gif o.plot(fast=True, buffer=1.)
# This example works better using hourly input from Thredds than the daily data from test folder reader_nordic = reader_netCDF_CF_generic.Reader( 'http://thredds.met.no/thredds/dodsC/sea/nordic4km/zdepths1h/aggregate_be') #reader_nordic = reader_ROMS_native.Reader(o.test_data_folder() + # '2Feb2016_Nordic_sigma_3d/Nordic-4km_SLEVELS_avg_00_subset2Feb2016.nc') o.add_reader([reader_nordic]) o.set_config('general:coastline_action', 'previous') # Seeding elements on a grid lons = np.linspace(12, 14.5, 30) lats = np.linspace(67.5, 68.5, 30) lons, lats = np.meshgrid(lons, lats) lon = lons.ravel() lat = lats.ravel() time = reader_nordic.start_time o.seed_elements(lon, lat, radius=0, number=30 * 30, time=time) o.run(steps=24 * 2, time_step=3600) # Print and plot results print(o) o.plot() #o.plot(background=['x_sea_water_velocity', 'y_sea_water_velocity']) o.animation(filename='coastline.gif') #%% # .. image:: /gallery/animations/coastline.gif
class TestRun(unittest.TestCase): """Tests for (non-scalar) LagrangianArray""" def make_OceanDrift_object(self): self.o = OceanDrift(loglevel=20) self.fake_eddy = reader_ArtificialOceanEddy.Reader(2, 62) self.o.use_block = False self.reader_basemap = reader_basemap_landmask.Reader( llcrnrlon=-1.5, llcrnrlat=59, urcrnrlon=7, urcrnrlat=64, resolution='i') self.o.add_reader([self.fake_eddy, self.reader_basemap]) def test_seed(self): """Test seeding""" o = OceanDrift(loglevel=20) number = 3 lonvec = np.linspace(2, 5, number) latvec = np.linspace(60, 61, number) o.seed_elements(lonvec, latvec, number=number, time=datetime(2015, 1, 1, 12, 5, 17)) #time=[datetime(2015, 1, 1), datetime(2015, 1, 3)]) # Check that 6 elements are scheduled, but none seeded self.assertEqual(o.num_elements_scheduled(), number) self.assertEqual(o.num_elements_active(), 0) self.assertEqual(o.num_elements_activated(), 0) self.assertEqual(o.num_elements_deactivated(), 0) self.assertEqual(o.num_elements_total(), number) def test_seed_outside_coverage(self): """Test seeding""" o = OpenOil3D(loglevel=20) norkyst = reader_netCDF_CF_generic.Reader(o.test_data_folder() + '14Jan2016_NorKyst_z_3d/NorKyst-800m_ZDEPTHS_his_00_3Dsubset.nc') basemap = reader_basemap_landmask.Reader( llcrnrlon=4, llcrnrlat=60, urcrnrlon=6, urcrnrlat=64, resolution='c', projection='merc') o.add_reader([basemap, norkyst]) o.seed_elements(5, 63, number=5, time=norkyst.start_time - 24*timedelta(hours=24)) o.run(steps=3, time_step=timedelta(minutes=15)) def test_runge_kutta(self): number = 50 # With Euler o = OceanDrift3D(loglevel=20, seed=0) norkyst = reader_netCDF_CF_generic.Reader(o.test_data_folder() + '14Jan2016_NorKyst_z_3d/NorKyst-800m_ZDEPTHS_his_00_3Dsubset.nc') o.fallback_values['land_binary_mask'] = 0 o.add_reader([norkyst]) z=-40*np.random.rand(number) o.seed_elements(5, 62.5, number=number, radius=5000, z=z, time=norkyst.start_time) o.run(steps=4*3, time_step=timedelta(minutes=15)) # With Runge-Kutta o2 = OceanDrift3D(loglevel=20, seed=0) o2.fallback_values['land_binary_mask'] = 0 o2.add_reader([norkyst]) z=-40*np.random.rand(number) o2.seed_elements(5, 62.5, number=number, radius=5000, z=z, time=norkyst.start_time) o2.set_config('drift:scheme', 'runge-kutta') o2.run(steps=4*3, time_step=timedelta(minutes=15)) # And finally repeating the initial run to check that indetical o3 = OceanDrift3D(loglevel=20, seed=0) norkyst = reader_netCDF_CF_generic.Reader(o.test_data_folder() + '14Jan2016_NorKyst_z_3d/NorKyst-800m_ZDEPTHS_his_00_3Dsubset.nc') o3.fallback_values['land_binary_mask'] = 0 o3.add_reader([norkyst]) z=-40*np.random.rand(number) o3.seed_elements(5, 62.5, number=number, radius=5000, z=z, time=norkyst.start_time) o3.run(steps=4*3, time_step=timedelta(minutes=15)) # Check that we get some difference with Runge-Kutta: self.assertAlmostEqual((o2.elements.lon-o.elements.lon).max(), 0.0015, 3) # Check that runs with Euler are identical self.assertEqual((o3.elements.lon-o.elements.lon).max(), 0) def test_seed_polygon(self): o = OceanDrift(loglevel=20) number = 10 lonvec = np.array([2, 3, 3, 2]) latvec = np.array([60, 60, 61, 61]) time=datetime(2015, 1, 1, 12, 5, 17) o.seed_within_polygon(lonvec, latvec, number=number, time=time, wind_drift_factor=.09) self.assertEqual(o.num_elements_scheduled(), number) self.assertEqual(o.elements_scheduled_time[0], time) self.assertAlmostEqual(o.elements_scheduled.wind_drift_factor, .09) def test_seed_polygon_timespan(self): o = OceanDrift(loglevel=20) number = 10 lonvec = np.array([2, 3, 3, 2]) latvec = np.array([60, 60, 61, 61]) time=[datetime(2015, 1, 1, 12, 5, 17), datetime(2015, 1, 1, 18, 5, 17)] o.seed_within_polygon(lonvec, latvec, number=number, time=time) self.assertEqual(o.num_elements_scheduled(), number) self.assertEqual(o.elements_scheduled_time[0], time[0]) self.assertEqual(o.elements_scheduled_time[-1], time[-1]) @unittest.skipIf(has_ogr is False, 'OGR library needed to read shapefiles') def test_seed_shapefile(self): o = OceanDrift(loglevel=20) o.seed_from_shapefile(o.test_data_folder() + 'shapefile_spawning_areas/Torsk.shp', number=100, layername=None, featurenum=[2, 4], time=datetime.now()) self.assertEqual(len(o.elements_scheduled), 100) o.seed_from_shapefile(o.test_data_folder() + 'shapefile_spawning_areas/Torsk.shp', number=300, layername=None, featurenum=None, time=datetime.now()) self.assertEqual(len(o.elements_scheduled), 400) #@unittest.skipIf(has_ogr is False, # 'GDAL library needed to read shapefiles') #def test_write_geotiff(self): # o = OceanDrift(loglevel=20) # o.seed_elements(lon=4, lat=60, time=datetime(2016, 1, 1)) # o.run(steps=3) # o.write_geotiff('geotiff.tif') def test1_seed_single_point_over_time(self): """Test a model run""" self.make_OceanDrift_object() self.o.seed_elements(2.0, 61.0, radius=0, number=9, time=[datetime(2015, 1, 1), datetime(2015, 1, 3)]) # Check that 6 elements are scheduled, but none seeded self.assertEqual(self.o.num_elements_scheduled(), 9) self.assertEqual(self.o.num_elements_active(), 0) self.assertEqual(self.o.num_elements_activated(), 0) self.assertEqual(self.o.num_elements_deactivated(), 0) self.assertEqual(self.o.num_elements_total(), 9) # Run simulation self.o.run(steps=30, outfile='unittest.nc') # Check that 1 element is deactivated (stranded), # 1 yet not seeded and 4 active self.assertEqual(self.o.num_elements_scheduled(), 4) self.assertEqual(self.o.num_elements_active(), 5) self.assertEqual(self.o.num_elements_activated(), 5) self.assertEqual(self.o.num_elements_deactivated(), 0) self.assertEqual(self.o.num_elements_total(), 9) def test2_seed_elementss(self): """Test a model run""" self.make_OceanDrift_object() self.o.seed_elements([2.0, 4.5, 3.0], [61.0, 60.0, 62.0], radius=0, number=9, time=[datetime(2015, 1, 1), datetime(2015, 1, 3)]) # Check that 6 elements are scheduled, but none seeded self.assertEqual(self.o.num_elements_scheduled(), 9) self.assertEqual(self.o.num_elements_active(), 0) self.assertEqual(self.o.num_elements_activated(), 0) self.assertEqual(self.o.num_elements_deactivated(), 0) self.assertEqual(self.o.num_elements_total(), 9) # Run simulation self.o.run(steps=30, outfile='unittest.nc') # Check that 1 element is deactivated (stranded), # 1 yet not seeded and 4 active self.assertEqual(self.o.num_elements_scheduled(), 4) self.assertEqual(self.o.num_elements_active(), 4) self.assertEqual(self.o.num_elements_activated(), 5) self.assertEqual(self.o.num_elements_deactivated(), 1) self.assertEqual(self.o.num_elements_total(), 9) def test3_run_import(self): """Import output file from previous test, and check elements""" self.o = OceanDrift(loglevel=20) self.o.io_import_file('unittest.nc') self.assertEqual(self.o.num_elements_active(), 4) self.assertEqual(self.o.num_elements_activated(), 5) self.assertEqual(self.o.num_elements_deactivated(), 1) self.assertEqual(self.o.num_elements_total(), 5) def test4_cleaning(self): """Cleaning up""" os.remove('unittest.nc') def test_temporal_seed(self): self.o = OceanDrift(loglevel=20) self.o.fallback_values['x_sea_water_velocity'] = 1 self.o.fallback_values['land_binary_mask'] = 0 # Seed elements on a grid at regular time interval start_time = datetime(2016,9,16) time_step = timedelta(hours=6) num_steps = 10 lon = 4.4 lat = 60.0 for i in range(num_steps+1): self.o.seed_elements(lon, lat, radius=0, number=2, time=start_time + i*time_step) # Running model self.o.run(steps=20, time_step=3600, outfile='temporal_seed.nc') self.o = OceanDrift(loglevel=20) # Check that data imported is properly masked self.o.io_import_file('temporal_seed.nc') self.assertTrue(self.o.history['lon'].max() < 1000) self.assertTrue(self.o.history['lon'].min() > -1000) self.assertTrue(self.o.history['lon'].mask[5,5]) self.assertFalse(self.o.history['lon'].mask[1,1]) os.remove('temporal_seed.nc') def test_vertical_mixing(self): # Export to file only at end o1 = PelagicEggDrift(loglevel=20) # Profiles and vertical mixing norkyst = reader_netCDF_CF_generic.Reader(o1.test_data_folder() + '14Jan2016_NorKyst_z_3d/NorKyst-800m_ZDEPTHS_his_00_3Dsubset.nc') o1.add_reader([norkyst]) o1.fallback_values['x_wind'] = 8 o1.fallback_values['land_binary_mask'] = 0 o1.seed_elements(4.1, 63.3, radius=1000, number=100, time=norkyst.start_time) o1.set_config('turbulentmixing:timestep', 20.) # seconds o1.set_config('turbulentmixing:verticalresolution', 1.) # m o1.run(steps=20, time_step=300, time_step_output=1800, export_buffer_length=10, outfile='verticalmixing.nc') self.assertAlmostEqual(o1.history['z'].min(), -25.0) self.assertAlmostEqual(o1.history['z'].max(), 0.0) os.remove('verticalmixing.nc') def test_export_step_interval(self): # Export to file only at end o1 = OceanDrift(loglevel=20) norkyst = reader_netCDF_CF_generic.Reader(o1.test_data_folder() + '16Nov2015_NorKyst_z_surface/norkyst800_subset_16Nov2015.nc') o1.add_reader(norkyst) o1.fallback_values['land_binary_mask'] = 0 o1.seed_elements(4.25, 60.2, radius=1000, number=10, time=norkyst.start_time) o1.run(steps=40) # Export to file during simulation o2 = OceanDrift(loglevel=20) o2.add_reader(norkyst) o2.fallback_values['land_binary_mask'] = 0 o2.seed_elements(4.25, 60.2, radius=1000, number=10, time=norkyst.start_time) o2.run(steps=40, export_buffer_length=6, outfile='export_step_interval.nc') self.assertItemsEqual(o1.history['lon'].compressed(), o2.history['lon'].compressed()) # Finally check when steps is multiple of export_buffer_length o3 = OceanDrift(loglevel=20) o3.add_reader(norkyst) o3.fallback_values['land_binary_mask'] = 0 o3.seed_elements(4.25, 60.2, radius=1000, number=10, time=norkyst.start_time) o3.run(steps=42) # Export to file during simulation o4 = OceanDrift(loglevel=20) o4.add_reader(norkyst) o4.fallback_values['land_binary_mask'] = 0 o4.seed_elements(4.25, 60.2, radius=1000, number=10, time=norkyst.start_time) o4.run(steps=42, export_buffer_length=6, outfile='export_step_interval.nc') self.assertItemsEqual(o3.history['lon'].compressed(), o4.history['lon'].compressed()) os.remove('export_step_interval.nc') def test_buffer_length_stranding(self): o1 = OceanDrift(loglevel=20) norkyst = reader_netCDF_CF_generic.Reader(o1.test_data_folder() + '16Nov2015_NorKyst_z_surface/norkyst800_subset_16Nov2015.nc') basemap = reader_basemap_landmask.Reader( llcrnrlon=1, llcrnrlat=59.8, urcrnrlon=6, urcrnrlat=61, resolution='i', projection='merc') o1.add_reader([basemap]) o1.fallback_values['x_sea_water_velocity'] = 1.0 # onshore drift o1.seed_elements(4.8, 60.2, radius=5000, number=100, time=norkyst.start_time) o1.run(steps=100, time_step=900, time_step_output=3600, export_buffer_length=10) # Without buffer o2 = OceanDrift(loglevel=20) o2.add_reader([basemap]) o2.fallback_values['x_sea_water_velocity'] = 1.0 # onshore drift o2.seed_elements(4.8, 60.2, radius=5000, number=100, time=norkyst.start_time) o2.run(steps=100, time_step=900, time_step_output=3600, outfile='test_buffer_length_stranding.nc') self.assertItemsEqual(o1.history['lon'].compressed(), o2.history['lon'].compressed()) self.assertItemsEqual(o1.history['status'].compressed(), o2.history['status'].compressed()) os.remove('test_buffer_length_stranding.nc') def test_output_time_step(self): o1 = OceanDrift(loglevel=20) norkyst = reader_netCDF_CF_generic.Reader(o1.test_data_folder() + '16Nov2015_NorKyst_z_surface/norkyst800_subset_16Nov2015.nc') basemap = reader_basemap_landmask.Reader( llcrnrlon=4, llcrnrlat=59.8, urcrnrlon=6, urcrnrlat=61, resolution='i', projection='merc') o1.add_reader([basemap, norkyst]) o1.seed_elements(4.95, 60.1, radius=3000, number=100, time=norkyst.start_time) o1.run(duration=timedelta(hours=12), time_step=timedelta(minutes=30), time_step_output=timedelta(minutes=30), outfile='test_time_step30.nc') # Check length of time array and output array time = o1.get_time_array()[0] self.assertEqual(o1.history.shape[1], len(time)) self.assertEqual(o1.start_time, time[0]) self.assertEqual(o1.time, time[-1]) # Second run, with larger output time step o2 = OceanDrift(loglevel=20) o2.add_reader([basemap, norkyst]) o2.seed_elements(4.95, 60.1, radius=3000, number=100, time=norkyst.start_time) o2.run(duration=timedelta(hours=12), time_step=timedelta(minutes=30), time_step_output=timedelta(minutes=60), outfile='test_time_step60.nc') self.assertEqual(o1.history.shape, (100,25)) self.assertEqual(o2.history.shape, (100,13)) # Check that start and end conditions (longitudes) are idential self.assertItemsEqual(o1.history['lon'][:,24].compressed(), o2.history['lon'][:,12].compressed()) self.assertItemsEqual(o1.history['lon'][:,0].compressed(), o2.history['lon'][:,0].compressed()) # Check that also run imported from file is identical o1i = OceanDrift(loglevel=20) o1i.io_import_file('test_time_step30.nc') o2i = OceanDrift(loglevel=20) o2i.io_import_file('test_time_step60.nc') os.remove('test_time_step30.nc') os.remove('test_time_step60.nc') self.assertItemsEqual(o2i.history['lon'][:,12].compressed(), o2.history['lon'][:,12].compressed()) # Check number of activated elements self.assertEqual(o1.num_elements_total(), o2.num_elements_total()) self.assertEqual(o1.num_elements_total(), o1i.num_elements_total()) self.assertEqual(o1.num_elements_total(), o2i.num_elements_total()) # Check number of deactivated elements self.assertEqual(o1.num_elements_deactivated(), o2.num_elements_deactivated()) self.assertEqual(o1.num_elements_deactivated(), o1i.num_elements_deactivated()) self.assertEqual(o1.num_elements_deactivated(), o2i.num_elements_deactivated()) def test_reader_boundary(self): # Check that the element outside reader coverage is # not deactivated if fallback value exist o = OceanDrift() nordic3d = reader_ROMS_native.Reader(o.test_data_folder() + '2Feb2016_Nordic_sigma_3d/Nordic-4km_SLEVELS_avg_00_subset2Feb2016.nc') lon = [12.0, 12.0] lat = [70.0, 70.5] o.add_reader(nordic3d) o.fallback_values['land_binary_mask'] = 0 o.seed_elements(lon, lat, number=2, radius=0, time=nordic3d.start_time) o.run(steps=2, time_step=3600) self.assertEqual(o.num_elements_active(), 2) self.assertEqual(o.num_elements_deactivated(), 0) # Check that the outside element is deactivated, # if no fallback value exists o = OceanDrift() del o.fallback_values['x_sea_water_velocity'] o.add_reader(nordic3d) o.fallback_values['land_binary_mask'] = 0 o.seed_elements(lon, lat, number=2, radius=0, time=nordic3d.start_time) o.run(steps=2, time_step=3600) self.assertEqual(o.num_elements_active(), 1) self.assertEqual(o.num_elements_deactivated(), 1) def test_reader_order(self): # Check that we get the same output indepenently of reader order o = OceanDrift(loglevel=50) norkyst = reader_netCDF_CF_generic.Reader(o.test_data_folder() + '16Nov2015_NorKyst_z_surface/norkyst800_subset_16Nov2015.nc') arome = reader_netCDF_CF_generic.Reader(o.test_data_folder() + '16Nov2015_NorKyst_z_surface/arome_subset_16Nov2015.nc') basemap = reader_basemap_landmask.Reader( llcrnrlon=2, llcrnrlat=59.8, urcrnrlon=6, urcrnrlat=61, resolution='c', projection='merc') lon=4.; lat=60. # First run o.add_reader([basemap, norkyst, arome]) o.seed_elements(lon, lat, time=norkyst.start_time) o.run(steps=30) # Second run # Check that we get almost identical results with other projection o1 = OceanDrift(loglevel=50) o1.add_reader([norkyst, arome, basemap]) o1.seed_elements(lon, lat, time=norkyst.start_time) o1.run(steps=30) self.assertAlmostEqual(o.elements.lon, o1.elements.lon, 2) self.assertAlmostEqual(o.elements.lat, o1.elements.lat, 2) # Third run # Check that this is identical to run 1 if projection set equal o2 = OceanDrift(loglevel=50) o2.add_reader([norkyst, arome, basemap]) o2.seed_elements(lon, lat, time=norkyst.start_time) o2.set_projection(basemap.proj4) o2.run(steps=30) self.assertEqual(o.elements.lon, o2.elements.lon) def test_seed_seafloor(self): o = OpenOil3D(loglevel=20) reader_norkyst = reader_netCDF_CF_generic.Reader(o.test_data_folder() + '14Jan2016_NorKyst_z_3d/NorKyst-800m_ZDEPTHS_his_00_3Dsubset.nc') o.fallback_values['land_binary_mask'] = 0 o.add_reader([reader_norkyst]) lon = 4.5; lat = 62.0 o.seed_elements(lon, lat, z='seafloor', time=reader_norkyst.start_time, density=1000) o.set_config('processes:turbulentmixing', True) o.set_config('turbulentmixing:verticalresolution', 1) # m o.set_config('turbulentmixing:timestep', 1) # s o.run(steps=3, time_step=300, time_step_output=300) #o.plot_property('z') z, status = o.get_property('z') self.assertAlmostEqual(z[0,0], -151.2, 1) # Seeded at seafloor depth self.assertAlmostEqual(z[-1,0], -106.0, 2) # After some rising def test_seed_below_reader_coverage(self): o = OpenOil3D(loglevel=20) reader_norkyst = reader_netCDF_CF_generic.Reader(o.test_data_folder() + '14Jan2016_NorKyst_z_3d/NorKyst-800m_ZDEPTHS_his_00_3Dsubset.nc') o.fallback_values['land_binary_mask'] = 0 o.add_reader([reader_norkyst]) lon = 5.0; lat = 64.0 o.seed_elements(lon, lat, z=-350, time=reader_norkyst.start_time, density=1000) #o.set_config('turbulentmixing:TSprofiles', True) o.set_config('processes:turbulentmixing', True) o.set_config('turbulentmixing:verticalresolution', 1) # m o.set_config('turbulentmixing:timestep', 1) # s o.set_config('input:spill:droplet_diameter_min_subsea', 0.005) o.set_config('input:spill:droplet_diameter_max_subsea', 0.005) o.run(steps=3, time_step=300, time_step_output=300) z, status = o.get_property('z') self.assertAlmostEqual(z[-1,0], -305.0, 2) # After some rising def test_seed_below_seafloor(self): o = OpenOil3D(loglevel=20) reader_norkyst = reader_netCDF_CF_generic.Reader(o.test_data_folder() + '14Jan2016_NorKyst_z_3d/NorKyst-800m_ZDEPTHS_his_00_3Dsubset.nc') o.add_reader([reader_norkyst]) o.fallback_values['land_binary_mask'] = 0 lon = 4.5; lat = 62.0 o.seed_elements(lon, lat, z=-5000, time=reader_norkyst.start_time, density=1000) o.set_config('processes:turbulentmixing', True) o.set_config('turbulentmixing:verticalresolution', 1) # m o.set_config('turbulentmixing:timestep', 1) # s o.set_config('input:spill:droplet_diameter_min_subsea', 0.005) o.set_config('input:spill:droplet_diameter_max_subsea', 0.005) o.run(steps=3, time_step=300, time_step_output=300) z, status = o.get_property('z') self.assertAlmostEqual(z[0,0], -151.2, 1) # Seeded at seafloor depth self.assertAlmostEqual(z[-1,0], -106.0, 2) # After some rising def test_lift_above_seafloor(self): # See an element at some depth, and progapate towards coast # (shallower water) and check that it is not penetrating seafloor o = OceanDrift3D(loglevel=20, proj4='+proj=merc') o.max_speed = 100 reader_norkyst = reader_netCDF_CF_generic.Reader(o.test_data_folder() + '14Jan2016_NorKyst_z_3d/NorKyst-800m_ZDEPTHS_his_00_3Dsubset.nc') reader_norkyst.buffer = 200 o.add_reader([reader_norkyst], variables='sea_floor_depth_below_sea_level') o.fallback_values['x_sea_water_velocity'] = 100 # Pure eastward motion o.fallback_values['y_sea_water_velocity'] = 0 o.fallback_values['land_binary_mask'] = 0 o.seed_elements(3.0, 62.0, z=-200, time=reader_norkyst.start_time) o.set_config('processes:turbulentmixing', False) o.run(steps=26, time_step=30) seafloor_depth, status = o.get_property('sea_floor_depth_below_sea_level') z, status = o.get_property('z') # Uncomment to plot #import matplotlib.pyplot as plt #plt.plot(-seafloor_depth, label='Seafloor depth') #plt.plot(z, label='Element depth') #plt.legend(loc='best') #plt.show() # Check that element has not penetrated seafloor self.assertFalse(o.elements.z < -o.environment.sea_floor_depth_below_sea_level) self.assertAlmostEqual(o.elements.z, -159.6, 1) def test_seed_on_land(self): o = OceanDrift(loglevel=50) o.set_config('general:basemap_resolution', 'c') o.seed_elements(lon=9, lat=60, time=datetime.now(), number=100) outfile='out.nc' o.run(steps=4, time_step=1800, time_step_output=3600, outfile=outfile) os.remove(outfile) o.write_netcdf_density_map(outfile) os.remove(outfile)
o = OceanDrift(loglevel=0) # Set loglevel to 0 for debug information o.max_speed = 3 # This example works better using hourly input from Thredds than the daily data from test folder reader_nordic = reader_netCDF_CF_generic.Reader('http://thredds.met.no/thredds/dodsC/sea/nordic4km/zdepths1h/aggregate_be') #reader_nordic = reader_ROMS_native.Reader(o.test_data_folder() + # '2Feb2016_Nordic_sigma_3d/Nordic-4km_SLEVELS_avg_00_subset2Feb2016.nc') o.add_reader([reader_nordic]) o.set_config('general:basemap_resolution', 'h') o.set_config('general:coastline_action', 'previous') # Seeding elements on a grid lons = np.linspace(12, 14.5, 30) lats = np.linspace(67.5, 68.5, 30) lons, lats = np.meshgrid(lons, lats) lon = lons.ravel() lat = lats.ravel() time = reader_nordic.start_time o.seed_elements(lon, lat, radius=0, number=30*30, time=time) o.run(steps=24*2, time_step=3600) # Print and plot results print o o.plot() #o.plot(background=['x_sea_water_velocity', 'y_sea_water_velocity']) o.animation()
# of the elements. Typical empirical values are: # - 0.035 (3.5 %) for oil and iSphere driftes # - 0.01 (1 %) for CODE drifters partly submerged ~0.5 m # As there are large uncertainties, it makes sence to provide a statistical # distribution of wind_drift_factors # Using a constant value for all elements: #wind_drift_factor = 0.03 # Giving each element a unique (random) wind_drift_factor wind_drift_factor = np.random.uniform(0, 0.06, 2000) o.seed_elements(4.7, 59.9, radius=3000, number=2000, time=reader_current.start_time, wind_drift_factor=wind_drift_factor) ####################### # Running model ####################### o.run(time_step=timedelta(minutes=15), time_step_output=timedelta(minutes=60)) ########################### # Print and plot results ########################### print o o.animation() # Plot trajectories, colored by the wind_drift_factor of each element o.plot(linecolor='wind_drift_factor')
from datetime import datetime, timedelta import matplotlib.pyplot as plt from opendrift.readers import reader_netCDF_CF_generic from opendrift.models.oceandrift import OceanDrift lon = 4.9; lat = 60.0 o = OceanDrift() reader_norkyst = reader_netCDF_CF_generic.Reader(o.test_data_folder() + '16Nov2015_NorKyst_z_surface/norkyst800_subset_16Nov2015.nc') time = reader_norkyst.start_time o.add_reader([reader_norkyst]) o.seed_elements(lon, lat, radius=1000, number=1000, time=time) o.run(steps=20) # Store final field of x-component of current original_current = reader_norkyst.var_block_after["['y_sea_water_velocity', 'x_sea_water_velocity']"].data_dict['x_sea_water_velocity'].copy() # For the second run, the NorKyst currents are convolved with a kernel, # effectively lowering the spatial resolution. # <reader>.convolve may also be given as an array (kernel) directly N = 10 # Convolusion kernel size reader_norkyst.convolve = N # Using convolution kernel for second run o2 = OceanDrift() o2.add_reader([reader_norkyst]) o2.seed_elements(lon, lat, radius=1000, number=1000, time=time) o2.run(steps=20) # Store final field of x-component of (convolved) current convolved_current = reader_norkyst.var_block_after["['y_sea_water_velocity', 'x_sea_water_velocity']"].data_dict['x_sea_water_velocity']
from opendrift.models.oceandrift import OceanDrift o = OceanDrift(loglevel=20) # Set loglevel to 0 for debug information reader_norkyst = reader_netCDF_CF_generic.Reader(o.test_data_folder() + '16Nov2015_NorKyst_z_surface/norkyst800_subset_16Nov2015.nc') time = reader_norkyst.start_time reader_norkyst.interpolation = 'linearND' reader_basemap = reader_basemap_landmask.Reader( llcrnrlon=4, llcrnrlat=59.9, urcrnrlon=5.5, urcrnrlat=61.5, resolution='h') o.add_reader([reader_norkyst, reader_basemap]) lon = 4.5; lat = 60.0; # First run, with Euler scheme: o.set_config('drift:scheme', 'euler') o.seed_elements(lon, lat, radius=0, number=1, time=time) o.run(steps=66*2, time_step=1800) # Second run, with Runge-Kutta scheme: o2 = OceanDrift(loglevel=20) # Set loglevel to 0 for debug information o2.add_reader([reader_norkyst, reader_basemap]) o2.set_config('drift:scheme', 'runge-kutta') o2.seed_elements(lon, lat, radius=0, number=1, time=time) o2.run(steps=66*2, time_step=1800) # Animate and compare the two runs o.animation(compare=o2, legend=['Euler scheme', 'Runge-Kutta scheme'])
#!/usr/bin/env python from datetime import datetime from opendrift.models.oceandrift import OceanDrift o = OceanDrift(loglevel=0) # Set loglevel to 0 for debug information # Adding no input models, but instead constant northwards current of 1 m/s o.fallback_values['x_sea_water_velocity'] = 0 o.fallback_values['y_sea_water_velocity'] = 1 o.fallback_values['land_binary_mask'] = 0 # Seeding some particles lon = 4.3; lat = 60.0; # Outside Bergen time = datetime(2015, 9, 22, 6, 0, 0) # Seed elements at defined position and time o.seed_elements(lon, lat, radius=5000, number=100, time=time) print o # Running model for 50 hours o.run(steps=50) # Print and plot results print o o.plot()
#!/usr/bin/env python from datetime import datetime, timedelta from opendrift.models.oceandrift import OceanDrift # Basic ocean drift module: current + 2% of wind o = OceanDrift() # Adding readers for global Thredds datasets: # - Ocean forecast from UK Met Office (FOAM model) # - Weather forecast from NOAA/NCEP o.add_readers_from_list([ 'http://data.ncof.co.uk/thredds/dodsC/METOFFICE-GLO-AF-PHYS-HOURLY-CUR', 'http://oos.soest.hawaii.edu/thredds/dodsC/hioos/model/atm/ncep_global/NCEP_Global_Atmospheric_Model_best.ncd']) o.seed_elements(lat=24, lon=-81, time=datetime.now(), number=5000, radius=10000) o.run(time_step=timedelta(minutes=30), duration=timedelta(days=5)) o.animation()
o = OceanDrift(loglevel=0) # Set loglevel to 0 for debug information # Nordic 4km nordic_native = reader_ROMS_native.Reader(o.test_data_folder() + '2Feb2016_Nordic_sigma_3d/Nordic-4km_SLEVELS_avg_00_subset2Feb2016.nc') # Landmask (Basemap) reader_basemap = reader_basemap_landmask.Reader( llcrnrlon=11.0, llcrnrlat=67.5, urcrnrlon=16.0, urcrnrlat=69.0, resolution='h', projection='merc') o.add_reader([reader_basemap, nordic_native]) # Seeding some particles time = nordic_native.start_time lon = 12.0; lat = 68.3; # Seed oil elements at defined position and time o.seed_elements(lon, lat, radius=0, number=10, z=np.linspace(0, -150, 10), time=time) print o # Running model o.run(time_step=3600) # Print and plot results print o o.plot(linecolor='z') #o.animation()
lon = 4.5; lat = 60.0; # Outside Bergen o = OceanDrift(loglevel=0) # Set loglevel to 0 for debug information # Arome atmospheric model reader_arome = reader_netCDF_CF_generic.Reader(o.test_data_folder() + '16Nov2015_NorKyst_z_surface/arome_subset_16Nov2015.nc') # Norkyst ocean model reader_norkyst = reader_netCDF_CF_generic.Reader(o.test_data_folder() + '16Nov2015_NorKyst_z_surface/norkyst800_subset_16Nov2015.nc') # Uncomment to use live data from thredds #reader_arome = reader_netCDF_CF_generic.Reader('http://thredds.met.no/thredds/dodsC/meps25files/meps_det_extracted_2_5km_latest.nc') #reader_norkyst = reader_netCDF_CF_generic.Reader('http://thredds.met.no/thredds/dodsC/sea/norkyst800m/1h/aggregate_be') o.set_config('general:basemap_resolution', 'i') o.add_reader([reader_norkyst, reader_arome]) time = reader_arome.start_time o.seed_elements(lon, lat, radius=500, number=2000, time=time) o.set_config('drift:current_uncertainty', 0) # 0 is default o.run(duration=timedelta(hours=24)) # Second run, identical, except for added diffusion o2 = OceanDrift(loglevel=0) # Set loglevel to 0 for debug information o2.set_config('general:basemap_resolution', 'i') o2.add_reader([reader_norkyst, reader_arome]) o2.seed_elements(lon, lat, radius=500, number=2000, time=time) o2.set_config('drift:current_uncertainty', .2) # Difference from first run o2.run(duration=timedelta(hours=24)) # Comparing o2.animation(compare=o, legend=['0.2 m/s std for current components', 'No diffusion'], legend_loc='upper center')
def test_output_time_step(self): o1 = OceanDrift(loglevel=30) norkyst = reader_netCDF_CF_generic.Reader( o1.test_data_folder() + '16Nov2015_NorKyst_z_surface/norkyst800_subset_16Nov2015.nc') basemap = reader_basemap_landmask.Reader(llcrnrlon=4.5, llcrnrlat=60.0, urcrnrlon=5.2, urcrnrlat=60.5, resolution='i', projection='merc') o1.add_reader([basemap, norkyst]) o1.seed_elements(4.96, 60.1, radius=3000, number=100, time=norkyst.start_time) o1.run(duration=timedelta(hours=12), time_step=timedelta(minutes=30), time_step_output=timedelta(minutes=30), outfile='test_time_step30.nc') # Check length of time array and output array time = o1.get_time_array()[0] self.assertEqual(o1.history.shape[1], len(time)) self.assertEqual(o1.start_time, time[0]) self.assertEqual(o1.time, time[-1]) # Second run, with larger output time step o2 = OceanDrift(loglevel=30) o2.add_reader([basemap, norkyst]) o2.seed_elements(4.96, 60.1, radius=3000, number=100, time=norkyst.start_time) o2.run(duration=timedelta(hours=12), time_step=timedelta(minutes=30), time_step_output=timedelta(minutes=60), outfile='test_time_step60.nc') self.assertEqual(o1.history.shape, (100, 25)) self.assertEqual(o2.history.shape, (100, 13)) # Check that start and end conditions (longitudes) are idential self.assertItemsEqual(o1.history['lon'][:, 24].compressed(), o2.history['lon'][:, 12].compressed()) self.assertItemsEqual(o1.history['lon'][:, 0].compressed(), o2.history['lon'][:, 0].compressed()) # Check that also run imported from file is identical o1i = OceanDrift(loglevel=20) o1i.io_import_file('test_time_step30.nc') o2i = OceanDrift(loglevel=20) o2i.io_import_file('test_time_step60.nc') os.remove('test_time_step30.nc') os.remove('test_time_step60.nc') self.assertItemsEqual(o2i.history['lon'][:, 12].compressed(), o2.history['lon'][:, 12].compressed()) # Check number of activated elements self.assertEqual(o1.num_elements_total(), o2.num_elements_total()) self.assertEqual(o1.num_elements_total(), o1i.num_elements_total()) self.assertEqual(o1.num_elements_total(), o2i.num_elements_total()) # Check number of deactivated elements self.assertEqual(o1.num_elements_deactivated(), o2.num_elements_deactivated()) self.assertEqual(o1.num_elements_deactivated(), o1i.num_elements_deactivated()) self.assertEqual(o1.num_elements_deactivated(), o2i.num_elements_deactivated())
o = OceanDrift(loglevel=0) # Set loglevel to 0 for debug information # Adding nordic reader for coastline reader_nordic = reader_ROMS_native.Reader(o.test_data_folder() + '2Feb2016_Nordic_sigma_3d/Nordic-4km_SLEVELS_avg_00_subset2Feb2016.nc') reader_nordic.variables = ['land_binary_mask'] reader_osc = reader_oscillating.Reader('x_sea_water_velocity', amplitude=1, zero_time=reader_nordic.start_time) o.add_reader([reader_osc]) # Oscillating east-west current component o.fallback_values['y_sea_water_velocity'] = .2 # Adding northwards drift o.set_config('general:basemap_resolution', 'i') ########################################################## # Try different options: 'previous', 'stranding', 'none' o.set_config('general:coastline_action', 'previous') ########################################################## time = reader_osc.zero_time lon = 12.2; lat = 67.7 o.seed_elements(lon, lat, radius=5000, number=15, time=time) o.run(steps=36*4, time_step=900) # Print and plot results print o o.plot() #o.plot(background=['x_sea_water_velocity', 'y_sea_water_velocity']) o.animation()
class TestRun(unittest.TestCase): """Tests for (non-scalar) LagrangianArray""" def make_OceanDrift_object(self): self.o = OceanDrift(loglevel=30) self.fake_eddy = reader_ArtificialOceanEddy.Reader(2, 62) self.o.use_block = False self.reader_basemap = reader_basemap_landmask.Reader(llcrnrlon=-1.5, llcrnrlat=59, urcrnrlon=7, urcrnrlat=64, resolution='c') self.o.add_reader([self.fake_eddy, self.reader_basemap]) def test_seed(self): """Test seeding""" o = OceanDrift(loglevel=20) number = 3 lonvec = np.linspace(2, 5, number) latvec = np.linspace(60, 61, number) o.seed_elements(lonvec, latvec, number=number, time=datetime(2015, 1, 1, 12, 5, 17)) #time=[datetime(2015, 1, 1), datetime(2015, 1, 3)]) # Check that 6 elements are scheduled, but none seeded self.assertEqual(o.num_elements_scheduled(), number) self.assertEqual(o.num_elements_active(), 0) self.assertEqual(o.num_elements_activated(), 0) self.assertEqual(o.num_elements_deactivated(), 0) self.assertEqual(o.num_elements_total(), number) def test_seed_outside_coverage(self): """Test seeding""" o = OpenOil3D(loglevel=0) norkyst = reader_netCDF_CF_generic.Reader( o.test_data_folder() + '14Jan2016_NorKyst_z_3d/NorKyst-800m_ZDEPTHS_his_00_3Dsubset.nc') basemap = reader_basemap_landmask.Reader(llcrnrlon=4, llcrnrlat=60, urcrnrlon=6, urcrnrlat=64, resolution='c', projection='merc') o.add_reader([basemap, norkyst]) o.fallback_values['x_wind'] = 0 o.fallback_values['y_wind'] = 0 o.seed_elements(5, 63, number=5, time=norkyst.start_time - 24 * timedelta(hours=24)) with self.assertRaises(ValueError): o.run(steps=3, time_step=timedelta(minutes=15)) def test_runge_kutta(self): number = 50 # With Euler o = OceanDrift3D(loglevel=20, seed=0) norkyst = reader_netCDF_CF_generic.Reader( o.test_data_folder() + '14Jan2016_NorKyst_z_3d/NorKyst-800m_ZDEPTHS_his_00_3Dsubset.nc') o.fallback_values['land_binary_mask'] = 0 o.add_reader([norkyst]) z = -40 * np.random.rand(number) o.seed_elements(5, 62.5, number=number, radius=5000, z=z, time=norkyst.start_time) o.run(steps=4 * 3, time_step=timedelta(minutes=15)) # With Runge-Kutta o2 = OceanDrift3D(loglevel=20, seed=0) o2.fallback_values['land_binary_mask'] = 0 o2.add_reader([norkyst]) z = -40 * np.random.rand(number) o2.seed_elements(5, 62.5, number=number, radius=5000, z=z, time=norkyst.start_time) o2.set_config('drift:scheme', 'runge-kutta') o2.run(steps=4 * 3, time_step=timedelta(minutes=15)) # And finally repeating the initial run to check that indetical o3 = OceanDrift3D(loglevel=20, seed=0) norkyst = reader_netCDF_CF_generic.Reader( o.test_data_folder() + '14Jan2016_NorKyst_z_3d/NorKyst-800m_ZDEPTHS_his_00_3Dsubset.nc') o3.fallback_values['land_binary_mask'] = 0 o3.add_reader([norkyst]) z = -40 * np.random.rand(number) o3.seed_elements(5, 62.5, number=number, radius=5000, z=z, time=norkyst.start_time) o3.run(steps=4 * 3, time_step=timedelta(minutes=15)) # Check that we get some difference with Runge-Kutta: self.assertAlmostEqual((o2.elements.lon - o.elements.lon).max(), 0.0015, 3) # Check that runs with Euler are identical self.assertEqual((o3.elements.lon - o.elements.lon).max(), 0) def test_seed_polygon(self): o = OceanDrift(loglevel=20) number = 10 lonvec = np.array([2, 3, 3, 2]) latvec = np.array([60, 60, 61, 61]) time = datetime(2015, 1, 1, 12, 5, 17) o.seed_within_polygon(lonvec, latvec, number=number, time=time, wind_drift_factor=.09) self.assertEqual(o.num_elements_scheduled(), number) self.assertEqual(o.elements_scheduled_time[0], time) self.assertAlmostEqual(o.elements_scheduled.wind_drift_factor, .09) def test_seed_polygon_timespan(self): o = OceanDrift(loglevel=20) number = 10 lonvec = np.array([2, 3, 3, 2]) latvec = np.array([60, 60, 61, 61]) time = [ datetime(2015, 1, 1, 12, 5, 17), datetime(2015, 1, 1, 18, 5, 17) ] o.seed_within_polygon(lonvec, latvec, number=number, time=time) self.assertEqual(o.num_elements_scheduled(), number) self.assertEqual(o.elements_scheduled_time[0], time[0]) self.assertEqual(o.elements_scheduled_time[-1], time[-1]) @unittest.skipIf(has_ogr is False, 'OGR library needed to read shapefiles') def test_seed_shapefile(self): o = OceanDrift(loglevel=20) o.seed_from_shapefile(o.test_data_folder() + 'shapefile_spawning_areas/Torsk.shp', number=100, layername=None, featurenum=[2, 4], time=datetime.now()) self.assertEqual(len(o.elements_scheduled), 100) o.seed_from_shapefile(o.test_data_folder() + 'shapefile_spawning_areas/Torsk.shp', number=300, layername=None, featurenum=None, time=datetime.now()) self.assertEqual(len(o.elements_scheduled), 400) #@unittest.skipIf(has_ogr is False, # 'GDAL library needed to read shapefiles') #def test_write_geotiff(self): # o = OceanDrift(loglevel=20) # o.seed_elements(lon=4, lat=60, time=datetime(2016, 1, 1)) # o.run(steps=3) # o.write_geotiff('geotiff.tif') def test1_seed_single_point_over_time(self): """Test a model run""" self.make_OceanDrift_object() self.o.seed_elements(2.0, 61.0, radius=0, number=9, time=[datetime(2015, 1, 1), datetime(2015, 1, 3)]) # Check that 6 elements are scheduled, but none seeded self.assertEqual(self.o.num_elements_scheduled(), 9) self.assertEqual(self.o.num_elements_active(), 0) self.assertEqual(self.o.num_elements_activated(), 0) self.assertEqual(self.o.num_elements_deactivated(), 0) self.assertEqual(self.o.num_elements_total(), 9) # Run simulation self.o.run(steps=30, outfile='unittest.nc') # Check that 1 element is deactivated (stranded), # 1 yet not seeded and 4 active self.assertEqual(self.o.num_elements_scheduled(), 4) self.assertEqual(self.o.num_elements_active(), 5) self.assertEqual(self.o.num_elements_activated(), 5) self.assertEqual(self.o.num_elements_deactivated(), 0) self.assertEqual(self.o.num_elements_total(), 9) def test2_seed_elements(self): """Test a model run""" self.make_OceanDrift_object() self.o.seed_elements([2.0, 5.0, 3.0], [61.0, 60.0, 62.0], radius=0, number=9, time=[datetime(2015, 1, 1), datetime(2015, 1, 3)]) # Check that 6 elements are scheduled, but none seeded self.assertEqual(self.o.num_elements_scheduled(), 9) self.assertEqual(self.o.num_elements_active(), 0) self.assertEqual(self.o.num_elements_activated(), 0) self.assertEqual(self.o.num_elements_deactivated(), 0) self.assertEqual(self.o.num_elements_total(), 9) # Run simulation self.o.run(steps=30, outfile='unittest.nc') # Check that 1 element is deactivated (stranded), # 1 yet not seeded and 4 active self.assertEqual(self.o.num_elements_scheduled(), 4) self.assertEqual(self.o.num_elements_active(), 4) self.assertEqual(self.o.num_elements_activated(), 5) self.assertEqual(self.o.num_elements_deactivated(), 1) self.assertEqual(self.o.num_elements_total(), 9) def test3_run_import(self): """Import output file from previous test, and check elements""" self.o = OceanDrift(loglevel=20) self.o.io_import_file('unittest.nc') self.assertEqual(self.o.num_elements_active(), 4) self.assertEqual(self.o.num_elements_activated(), 5) self.assertEqual(self.o.num_elements_deactivated(), 1) self.assertEqual(self.o.num_elements_total(), 5) def test4_cleaning(self): """Cleaning up""" os.remove('unittest.nc') def test_temporal_seed(self): self.o = OceanDrift(loglevel=20) self.o.fallback_values['x_sea_water_velocity'] = 1 self.o.fallback_values['land_binary_mask'] = 0 # Seed elements on a grid at regular time interval start_time = datetime(2016, 9, 16) time_step = timedelta(hours=6) num_steps = 10 lon = 4.4 lat = 60.0 for i in range(num_steps + 1): self.o.seed_elements(lon, lat, radius=0, number=2, time=start_time + i * time_step) # Running model self.o.run(steps=20, time_step=3600, outfile='temporal_seed.nc') self.o = OceanDrift(loglevel=20) # Check that data imported is properly masked self.o.io_import_file('temporal_seed.nc') self.assertTrue(self.o.history['lon'].max() < 1000) self.assertTrue(self.o.history['lon'].min() > -1000) self.assertTrue(self.o.history['lon'].mask[5, 5]) self.assertFalse(self.o.history['lon'].mask[1, 1]) os.remove('temporal_seed.nc') def test_vertical_mixing(self): # Export to file only at end o1 = PelagicEggDrift(loglevel=20) # Profiles and vertical mixing norkyst = reader_netCDF_CF_generic.Reader( o1.test_data_folder() + '14Jan2016_NorKyst_z_3d/NorKyst-800m_ZDEPTHS_his_00_3Dsubset.nc') o1.add_reader([norkyst]) o1.fallback_values['x_wind'] = 8 o1.fallback_values['land_binary_mask'] = 0 o1.seed_elements(4.1, 63.3, radius=1000, number=100, time=norkyst.start_time) o1.set_config('turbulentmixing:timestep', 20.) # seconds o1.set_config('turbulentmixing:verticalresolution', 1.) # m o1.run(steps=20, time_step=300, time_step_output=1800, export_buffer_length=10, outfile='verticalmixing.nc') self.assertAlmostEqual(o1.history['z'].min(), -31.9, 1) self.assertAlmostEqual(o1.history['z'].max(), 0.0, 1) os.remove('verticalmixing.nc') def test_export_step_interval(self): # Export to file only at end o1 = OceanDrift(loglevel=20) norkyst = reader_netCDF_CF_generic.Reader( o1.test_data_folder() + '16Nov2015_NorKyst_z_surface/norkyst800_subset_16Nov2015.nc') o1.add_reader(norkyst) o1.fallback_values['land_binary_mask'] = 0 o1.seed_elements(4.25, 60.2, radius=1000, number=10, time=norkyst.start_time) o1.run(steps=40) # Export to file during simulation o2 = OceanDrift(loglevel=20) o2.add_reader(norkyst) o2.fallback_values['land_binary_mask'] = 0 o2.seed_elements(4.25, 60.2, radius=1000, number=10, time=norkyst.start_time) o2.run(steps=40, export_buffer_length=6, outfile='export_step_interval.nc') self.assertItemsEqual(o1.history['lon'].compressed(), o2.history['lon'].compressed()) # Finally check when steps is multiple of export_buffer_length o3 = OceanDrift(loglevel=20) o3.add_reader(norkyst) o3.fallback_values['land_binary_mask'] = 0 o3.seed_elements(4.25, 60.2, radius=1000, number=10, time=norkyst.start_time) o3.run(steps=42) # Export to file during simulation o4 = OceanDrift(loglevel=20) o4.add_reader(norkyst) o4.fallback_values['land_binary_mask'] = 0 o4.seed_elements(4.25, 60.2, radius=1000, number=10, time=norkyst.start_time) o4.run(steps=42, export_buffer_length=6, outfile='export_step_interval.nc') self.assertItemsEqual(o3.history['lon'].compressed(), o4.history['lon'].compressed()) os.remove('export_step_interval.nc') def test_buffer_length_stranding(self): o1 = OceanDrift(loglevel=30) norkyst = reader_netCDF_CF_generic.Reader( o1.test_data_folder() + '16Nov2015_NorKyst_z_surface/norkyst800_subset_16Nov2015.nc') basemap = reader_basemap_landmask.Reader(llcrnrlon=4.5, llcrnrlat=60.1, urcrnrlon=6.0, urcrnrlat=60.4, resolution='c', projection='merc') o1.add_reader([basemap]) o1.fallback_values['x_sea_water_velocity'] = 0.8 # onshore drift o1.seed_elements(4.8, 60.2, radius=5000, number=100, time=norkyst.start_time) o1.run(steps=100, time_step=900, time_step_output=3600, export_buffer_length=10) # Without buffer o2 = OceanDrift(loglevel=30) o2.add_reader([basemap]) o2.fallback_values['x_sea_water_velocity'] = 0.8 # onshore drift o2.seed_elements(4.8, 60.2, radius=5000, number=100, time=norkyst.start_time) o2.run(steps=100, time_step=900, time_step_output=3600, outfile='test_buffer_length_stranding.nc') self.assertItemsEqual(o1.history['lon'].compressed(), o2.history['lon'].compressed()) self.assertItemsEqual(o1.history['status'].compressed(), o2.history['status'].compressed()) os.remove('test_buffer_length_stranding.nc') def test_output_time_step(self): o1 = OceanDrift(loglevel=30) norkyst = reader_netCDF_CF_generic.Reader( o1.test_data_folder() + '16Nov2015_NorKyst_z_surface/norkyst800_subset_16Nov2015.nc') basemap = reader_basemap_landmask.Reader(llcrnrlon=4.5, llcrnrlat=60.0, urcrnrlon=5.2, urcrnrlat=60.5, resolution='i', projection='merc') o1.add_reader([basemap, norkyst]) o1.seed_elements(4.96, 60.1, radius=3000, number=100, time=norkyst.start_time) o1.run(duration=timedelta(hours=12), time_step=timedelta(minutes=30), time_step_output=timedelta(minutes=30), outfile='test_time_step30.nc') # Check length of time array and output array time = o1.get_time_array()[0] self.assertEqual(o1.history.shape[1], len(time)) self.assertEqual(o1.start_time, time[0]) self.assertEqual(o1.time, time[-1]) # Second run, with larger output time step o2 = OceanDrift(loglevel=30) o2.add_reader([basemap, norkyst]) o2.seed_elements(4.96, 60.1, radius=3000, number=100, time=norkyst.start_time) o2.run(duration=timedelta(hours=12), time_step=timedelta(minutes=30), time_step_output=timedelta(minutes=60), outfile='test_time_step60.nc') self.assertEqual(o1.history.shape, (100, 25)) self.assertEqual(o2.history.shape, (100, 13)) # Check that start and end conditions (longitudes) are idential self.assertItemsEqual(o1.history['lon'][:, 24].compressed(), o2.history['lon'][:, 12].compressed()) self.assertItemsEqual(o1.history['lon'][:, 0].compressed(), o2.history['lon'][:, 0].compressed()) # Check that also run imported from file is identical o1i = OceanDrift(loglevel=20) o1i.io_import_file('test_time_step30.nc') o2i = OceanDrift(loglevel=20) o2i.io_import_file('test_time_step60.nc') os.remove('test_time_step30.nc') os.remove('test_time_step60.nc') self.assertItemsEqual(o2i.history['lon'][:, 12].compressed(), o2.history['lon'][:, 12].compressed()) # Check number of activated elements self.assertEqual(o1.num_elements_total(), o2.num_elements_total()) self.assertEqual(o1.num_elements_total(), o1i.num_elements_total()) self.assertEqual(o1.num_elements_total(), o2i.num_elements_total()) # Check number of deactivated elements self.assertEqual(o1.num_elements_deactivated(), o2.num_elements_deactivated()) self.assertEqual(o1.num_elements_deactivated(), o1i.num_elements_deactivated()) self.assertEqual(o1.num_elements_deactivated(), o2i.num_elements_deactivated()) def test_reader_boundary(self): # Check that the element outside reader coverage is # not deactivated if fallback value exist o = OceanDrift() nordic3d = reader_ROMS_native.Reader( o.test_data_folder() + '2Feb2016_Nordic_sigma_3d/Nordic-4km_SLEVELS_avg_00_subset2Feb2016.nc' ) lon = [12.0, 12.0] lat = [70.0, 70.5] o.add_reader(nordic3d) o.fallback_values['land_binary_mask'] = 0 o.seed_elements(lon, lat, number=2, radius=0, time=nordic3d.start_time) o.run(steps=2, time_step=3600) self.assertEqual(o.num_elements_active(), 2) self.assertEqual(o.num_elements_deactivated(), 0) # Check that the outside element is deactivated, # if no fallback value exists o = OceanDrift() del o.fallback_values['x_sea_water_velocity'] o.add_reader(nordic3d) o.fallback_values['land_binary_mask'] = 0 o.seed_elements(lon, lat, number=2, radius=0, time=nordic3d.start_time) o.run(steps=2, time_step=3600) self.assertEqual(o.num_elements_active(), 1) self.assertEqual(o.num_elements_deactivated(), 1) def test_reader_order(self): # Check that we get the same output indepenently of reader order o = OceanDrift(loglevel=50) norkyst = reader_netCDF_CF_generic.Reader( o.test_data_folder() + '16Nov2015_NorKyst_z_surface/norkyst800_subset_16Nov2015.nc') arome = reader_netCDF_CF_generic.Reader( o.test_data_folder() + '16Nov2015_NorKyst_z_surface/arome_subset_16Nov2015.nc') basemap = reader_basemap_landmask.Reader(llcrnrlon=2, llcrnrlat=59.8, urcrnrlon=6, urcrnrlat=61, resolution='c', projection='merc') lon = 4. lat = 60. # First run o.add_reader([basemap, norkyst, arome]) o.seed_elements(lon, lat, time=norkyst.start_time) o.run(steps=30) # Second run # Check that we get almost identical results with other projection o1 = OceanDrift(loglevel=50) o1.add_reader([norkyst, arome, basemap]) o1.seed_elements(lon, lat, time=norkyst.start_time) o1.run(steps=30) self.assertAlmostEqual(o.elements.lon, o1.elements.lon, 2) self.assertAlmostEqual(o.elements.lat, o1.elements.lat, 2) # Third run # Check that this is identical to run 1 if projection set equal o2 = OceanDrift(loglevel=50) o2.add_reader([norkyst, arome, basemap]) o2.seed_elements(lon, lat, time=norkyst.start_time) o2.set_projection(basemap.proj4) o2.run(steps=30) self.assertEqual(o.elements.lon, o2.elements.lon) def test_seed_seafloor(self): o = OpenOil3D(loglevel=30) reader_norkyst = reader_netCDF_CF_generic.Reader( o.test_data_folder() + '14Jan2016_NorKyst_z_3d/NorKyst-800m_ZDEPTHS_his_00_3Dsubset.nc') o.fallback_values['land_binary_mask'] = 0 o.fallback_values['x_wind'] = 0 o.fallback_values['y_wind'] = 0 o.fallback_values['x_sea_water_velocity'] = 0 o.fallback_values['y_sea_water_velocity'] = 0 o.add_reader([reader_norkyst]) lon = 4.5 lat = 62.0 o.seed_elements(lon, lat, z='seafloor', time=reader_norkyst.start_time, density=1000) o.set_config('processes:turbulentmixing', True) o.set_config('turbulentmixing:verticalresolution', 1) # m o.set_config('turbulentmixing:timestep', 1) # s o.run(steps=3, time_step=300, time_step_output=300) #o.plot_property('z') z, status = o.get_property('z') self.assertAlmostEqual(z[0, 0], -151.7, 1) # Seeded at seafloor depth self.assertAlmostEqual(z[-1, 0], -91.3, 1) # After some rising def test_seed_above_seafloor(self): o = OpenOil3D(loglevel=20) reader_norkyst = reader_netCDF_CF_generic.Reader( o.test_data_folder() + '14Jan2016_NorKyst_z_3d/NorKyst-800m_ZDEPTHS_his_00_3Dsubset.nc') o.fallback_values['land_binary_mask'] = 0 o.fallback_values['x_wind'] = 0 o.fallback_values['y_wind'] = 0 o.fallback_values['x_sea_water_velocity'] = 0 o.fallback_values['y_sea_water_velocity'] = 0 o.add_reader([reader_norkyst]) lon = 4.5 lat = 62.0 # Seed elements 50 meters above seafloor: o.seed_elements(lon, lat, z='seafloor+50', time=reader_norkyst.start_time, density=1000) o.set_config('processes:turbulentmixing', True) o.set_config('turbulentmixing:verticalresolution', 1) # m o.set_config('turbulentmixing:timestep', 1) # s o.run(steps=3, time_step=300, time_step_output=300) #o.plot_property('z') z, status = o.get_property('z') self.assertAlmostEqual(z[0, 0], -101.7, 1) # Seeded at seafloor depth self.assertAlmostEqual(z[-1, 0], -41.7, 1) # After some rising def test_seed_below_reader_coverage(self): o = OpenOil3D(loglevel=20) reader_norkyst = reader_netCDF_CF_generic.Reader( o.test_data_folder() + '14Jan2016_NorKyst_z_3d/NorKyst-800m_ZDEPTHS_his_00_3Dsubset.nc') o.fallback_values['land_binary_mask'] = 0 o.fallback_values['x_wind'] = 0 o.fallback_values['y_wind'] = 0 o.add_reader([reader_norkyst]) lon = 5.0 lat = 64.0 o.seed_elements(lon, lat, z=-350, time=reader_norkyst.start_time, density=1000) #o.set_config('turbulentmixing:TSprofiles', True) o.set_config('processes:turbulentmixing', True) o.set_config('turbulentmixing:verticalresolution', 1) # m o.set_config('turbulentmixing:timestep', 1) # s o.set_config('input:spill:droplet_diameter_min_subsea', 0.005) o.set_config('input:spill:droplet_diameter_max_subsea', 0.005) o.run(steps=3, time_step=300, time_step_output=300) z, status = o.get_property('z') self.assertAlmostEqual(z[-1, 0], -289.2, 1) # After some rising def test_seed_below_seafloor(self): o = OpenOil3D(loglevel=20) reader_norkyst = reader_netCDF_CF_generic.Reader( o.test_data_folder() + '14Jan2016_NorKyst_z_3d/NorKyst-800m_ZDEPTHS_his_00_3Dsubset.nc') o.add_reader([reader_norkyst]) o.fallback_values['land_binary_mask'] = 0 o.fallback_values['x_wind'] = 0 o.fallback_values['y_wind'] = 0 o.fallback_values['x_sea_water_velocity'] = 0 o.fallback_values['y_sea_water_velocity'] = 0 lon = 4.5 lat = 62.0 o.seed_elements(lon, lat, z=-5000, time=reader_norkyst.start_time, density=1000) o.set_config('processes:turbulentmixing', True) o.set_config('turbulentmixing:verticalresolution', 1) # m o.set_config('turbulentmixing:timestep', 1) # s o.set_config('input:spill:droplet_diameter_min_subsea', 0.005) o.set_config('input:spill:droplet_diameter_max_subsea', 0.005) o.run(steps=3, time_step=300, time_step_output=300) z, status = o.get_property('z') self.assertAlmostEqual(z[0, 0], -151.7, 1) # Seeded at seafloor depth self.assertAlmostEqual(z[-1, 0], -91.3, 1) # After some rising def test_seed_below_seafloor_deactivating(self): o = OpenOil3D(loglevel=50) reader_norkyst = reader_netCDF_CF_generic.Reader( o.test_data_folder() + '14Jan2016_NorKyst_z_3d/NorKyst-800m_ZDEPTHS_his_00_3Dsubset.nc') o.add_reader([reader_norkyst]) o.fallback_values['land_binary_mask'] = 0 o.fallback_values['x_wind'] = 0 o.fallback_values['y_wind'] = 0 o.fallback_values['x_sea_water_velocity'] = 0 o.fallback_values['y_sea_water_velocity'] = 0 lon = 4.5 lat = 62.0 o.seed_elements(lon, lat, z=[-5000, -100], time=reader_norkyst.start_time, density=1000, number=2) o.set_config('drift:lift_to_seafloor', False) # This time we deactivate o.set_config('processes:turbulentmixing', True) o.set_config('turbulentmixing:verticalresolution', 1) # m o.set_config('turbulentmixing:timestep', 1) # s o.set_config('input:spill:droplet_diameter_min_subsea', 0.005) o.set_config('input:spill:droplet_diameter_max_subsea', 0.005) o.run(steps=3, time_step=300, time_step_output=300) z, status = o.get_property('z') self.assertEqual(o.num_elements_total(), 2) self.assertEqual(o.num_elements_active(), 1) self.assertEqual(o.num_elements_deactivated(), 1) self.assertAlmostEqual(z[0, 1], -100, 1) # Seeded at seafloor depth self.assertAlmostEqual(z[-1, 1], -34.6, 1) # After some rising def test_lift_above_seafloor(self): # See an element at some depth, and progapate towards coast # (shallower water) and check that it is not penetrating seafloor o = OceanDrift3D(loglevel=30, proj4='+proj=merc') o.max_speed = 100 reader_norkyst = reader_netCDF_CF_generic.Reader( o.test_data_folder() + '14Jan2016_NorKyst_z_3d/NorKyst-800m_ZDEPTHS_his_00_3Dsubset.nc') reader_norkyst.buffer = 200 o.add_reader([reader_norkyst], variables='sea_floor_depth_below_sea_level') o.fallback_values['x_sea_water_velocity'] = 100 # Pure eastward motion o.fallback_values['y_sea_water_velocity'] = 0 o.fallback_values['land_binary_mask'] = 0 o.seed_elements(3.0, 62.0, z=-200, time=reader_norkyst.start_time) o.set_config('processes:turbulentmixing', False) o.run(steps=26, time_step=30) seafloor_depth, status = o.get_property( 'sea_floor_depth_below_sea_level') z, status = o.get_property('z') # Uncomment to plot #import matplotlib.pyplot as plt #plt.plot(-seafloor_depth, label='Seafloor depth') #plt.plot(z, label='Element depth') #plt.legend(loc='best') #plt.show() # Check that element has not penetrated seafloor self.assertFalse( o.elements.z < -o.environment.sea_floor_depth_below_sea_level) self.assertAlmostEqual(o.elements.z, -160.06, 1) def test_seed_on_land(self): o = OceanDrift(loglevel=0) o.set_config('general:basemap_resolution', 'c') o.seed_elements(lon=9, lat=60, time=datetime.now(), number=100) outfile = 'out.nc' with self.assertRaises(ValueError): o.run(steps=4, time_step=1800, time_step_output=3600, outfile=outfile) os.remove(outfile) #o.write_netcdf_density_map(outfile) #os.remove(outfile) def test_plot_animation(self): o = OceanDrift(loglevel=0) o.set_config('general:basemap_resolution', 'c') o.fallback_values['x_sea_water_velocity'] = .5 o.fallback_values['y_sea_water_velocity'] = .3 o.seed_elements(lon=3, lat=60, radius=1000, time=datetime.now(), number=100) o.run(steps=5) o.plot(filename='test_plot.png') o.animation(filename='test_plot.mp4') assert os.path.exists('test_plot.png') assert os.path.exists('test_plot.mp4') os.remove('test_plot.png') os.remove('test_plot.mp4') def test_retirement(self): o = OceanDrift(loglevel=50) o.set_config('drift:max_age_seconds', 5000) o.fallback_values['x_sea_water_velocity'] = .5 o.fallback_values['y_sea_water_velocity'] = .3 o.fallback_values['land_binary_mask'] = 0 o.seed_elements( lon=0, lat=60, number=10, time=[datetime.now(), datetime.now() + timedelta(seconds=6000)]) o.run(time_step=1000, duration=timedelta(seconds=7000)) self.assertEqual(o.num_elements_deactivated(), 5)
from opendrift.readers import reader_ROMS_native from opendrift.models.oceandrift import OceanDrift lon = 14.75; lat = 68.1 o = OceanDrift(loglevel=0) reader_nordic = reader_ROMS_native.Reader(o.test_data_folder() + '2Feb2016_Nordic_sigma_3d/Nordic-4km_SLEVELS_avg_00_subset2Feb2016.nc') # First run, with landmask from Basemap o.add_reader([reader_nordic]) time = reader_nordic.start_time o.seed_elements(lon, lat, radius=3000, number=1000, time=time) o.set_config('general:use_basemap_landmask', True) o.run(end_time=reader_nordic.end_time, time_step=1800) # Second run, with landmask from ocean model o2 = OceanDrift(loglevel=0) o2.add_reader([reader_nordic]) lon = 14.75; lat = 68.1 o2.seed_elements(lon, lat, radius=3000, number=1000, time=time) o2.set_config('general:use_basemap_landmask', False) o2.run(end_time=reader_nordic.end_time, time_step=1800) # Animation illustrating that red particles strand at ocean model land cells, and black particles strand at Basemap land polygons o.animation(compare=o2, background='land_binary_mask', legend=['Basemap landmask', 'Ocean model landmask'])
from opendrift.readers import reader_double_gyre from opendrift.models.oceandrift import OceanDrift o = OceanDrift(loglevel=20) # Set loglevel to 0 for debug information o.fallback_values['land_binary_mask'] = 0 o.set_config('drift:scheme', 'runge-kutta4') double_gyre = reader_double_gyre.Reader(epsilon=.25, omega=0.628, A=0.1) print(double_gyre) o.add_reader(double_gyre) x = [.9] y = [.5] lon, lat = double_gyre.xy2lonlat(x, y) o.seed_elements(lon, lat, radius=.1, number=1000, time=double_gyre.initial_time) o.run(duration=timedelta(seconds=10), time_step=0.1) o.animation(buffer=0) #%% # .. image:: /gallery/animations/example_double_gyre_0.gif o.plot(buffer=0)
#!/usr/bin/env python from datetime import timedelta import numpy as np from opendrift.models.oceandrift import OceanDrift from opendrift.readers import reader_netCDF_CF_generic # Drift simulation using 10 member ensemble wind data # from MEPS model of MET Norway o = OceanDrift() r = reader_netCDF_CF_generic.Reader('http://thredds.met.no/thredds/dodsC/meps25files/meps_allmembers_extracted_2_5km_latest.nc') o.add_reader(r) #o.set_config('general:basemap_resolution', 'c') o.seed_elements(lat=60, lon=4.8, time=r.start_time, radius=1000, number=10000) o.run(duration=timedelta(hours=50), time_step=3600) # Ensemble members are recycled among the 10000 particles ensemble_number = np.remainder(o.history['ID'], 10) + 1 o.animation(filename='wind_drift_ensemble.mp4', color=ensemble_number, clabel='Ensemble number')