From b73a84c8e7f41819a6b14eafbdfd7242354688b9 Mon Sep 17 00:00:00 2001 From: Knut-Frode Dagestad Date: Fri, 15 Mar 2024 09:47:18 +0100 Subject: [PATCH] Oil biodegradation decay is now specified with half time in days, instead of decay rate --- examples/example_biodegradation.py | 10 +++++----- examples/example_chemicaldrift.py | 2 +- opendrift/models/openoil/openoil.py | 24 +++++++++++++----------- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/examples/example_biodegradation.py b/examples/example_biodegradation.py index daca5a864..45c6ab8a2 100755 --- a/examples/example_biodegradation.py +++ b/examples/example_biodegradation.py @@ -15,19 +15,19 @@ # No motion is needed for this test o.set_config('environment:constant', {k: 0 for k in ['x_wind', 'y_wind', 'x_sea_water_velocity', 'y_sea_water_velocity']}) -o.set_config('drift', {'current_uncertainty': 0, 'wind_uncertainty': 0, 'horizontal_diffusivity': 100}) +o.set_config('drift', {'current_uncertainty': 0, 'wind_uncertainty': 0, 'horizontal_diffusivity': 10}) #%% # Seeding some particles o.set_config('drift:vertical_mixing', True) o.set_config('processes:biodegradation', True) -o.set_config('biodegradation:method', 'decay_rate') +o.set_config('biodegradation:method', 'half_time') #%% # Fast decay for droplets, and slow decay for slick -decay = {'biodegradation_decay_rate_slick': np.log(2)/timedelta(days=5).total_seconds(), - 'biodegradation_decay_rate_droplet': np.log(2)/timedelta(days=1).total_seconds(), - 'oil_type': 'GENERIC MEDIUM CRUDE', 'm3_per_hour': .5, 'diameter': 1e-9} # small droplets +decay = {'biodegradation_half_time_slick': 5, # days + 'biodegradation_half_time_droplet': 1, # days, + 'oil_type': 'GENERIC MEDIUM CRUDE', 'm3_per_hour': .5, 'diameter': 1e-5} # small droplets #%% # Seed 500 oil elements at surface, and 500 elements at 50m depth diff --git a/examples/example_chemicaldrift.py b/examples/example_chemicaldrift.py index e350d1c30..8100e6fd8 100755 --- a/examples/example_chemicaldrift.py +++ b/examples/example_chemicaldrift.py @@ -101,7 +101,7 @@ o.animation(color='specie', markersize='mass', - markersize_scaling=30, + markersize_scaling=100, alpha=.5, vmin=0,vmax=o.nspecies-1, colorbar=False, diff --git a/opendrift/models/openoil/openoil.py b/opendrift/models/openoil/openoil.py index c340655d0..0caccbdee 100644 --- a/opendrift/models/openoil/openoil.py +++ b/opendrift/models/openoil/openoil.py @@ -171,10 +171,12 @@ class Oil(Lagrangian3DArray): 'seed': False, 'default': 0 }), - ('biodegradation_decay_rate_droplet', # TODO: should have valid_min and valid_max for element properties - {'dtype': np.float32, 'units': 'kg', 'seed': False, 'default': np.log(2)/(3600*24)}), # 1 day default - ('biodegradation_decay_rate_slick', - {'dtype': np.float32, 'units': 'kg', 'seed': False, 'default': np.log(2)/(3600*24*3)}), # 3 days default + ('biodegradation_half_time_droplet', + {'dtype': np.float32, 'units': 'days', 'seed': False, 'default': 1, + 'description': 'Biodegradation half time in days for submerged oil droplets'}), + ('biodegradation_half_time_slick', + {'dtype': np.float32, 'units': 'days', 'seed': False, 'default': 3, + 'description': 'Biodegradation half time in days for surface oil slick'}), ('fraction_evaporated', { 'dtype': np.float32, 'units': '%', # TODO: should be fraction and not percent @@ -436,7 +438,7 @@ def __init__(self, weathering_model='noaa', *args, **kwargs): }, 'biodegradation:method': { 'type': 'enum', - 'enum': ['Adcroft', 'decay_rate'], + 'enum': ['Adcroft', 'half_time'], 'default': 'Adcroft', 'level': CONFIG_LEVEL_ADVANCED, 'description': 'Alogorithm to be used for biodegradation of oil' }, @@ -552,17 +554,17 @@ def biodegradation(self): logger.debug(f'Calculating: biodegradation ({method})') if method == 'Adcroft': self.biodegradation_adcroft() - elif method == 'decay_rate': - self.biodegradation_decay_rate() + elif method == 'half_time': + self.biodegradation_half_time() - def biodegradation_decay_rate(self): + def biodegradation_half_time(self): '''Oil biodegradation with exponential decay''' surface = np.where(self.elements.z == 0)[0] # of active elements - age0 = self.time_step.total_seconds() + age0 = self.time_step.total_seconds()/(3600*24) # days - half_time = np.log(2) / self.elements.biodegradation_decay_rate_droplet - half_time[surface] = np.log(2) / self.elements.biodegradation_decay_rate_slick[surface] + half_time = self.elements.biodegradation_half_time_droplet.copy() + half_time[surface] = self.elements.biodegradation_half_time_slick[surface] fraction_biodegraded = (1 - np.exp(-age0 / half_time)) biodegraded_now = self.elements.mass_oil * fraction_biodegraded