gnome.weatherers

Submodules

Package Contents

Classes

Weatherer

Base Weathering agent. This is almost exactly like the base Mover

HalfLifeWeatherer

Give half-life for all components and decay accordingly

Skimmer

Just need to add a few internal methods for Skimmer + Burn common code

Burn

Just need to add a few internal methods for Skimmer + Burn common code

ChemicalDispersion

Just need to add a few internal methods for Skimmer + Burn common code

Beaching

It isn't really a response/cleanup option; however, it works in the same

Evaporation

Base Weathering agent. This is almost exactly like the base Mover

NaturalDispersion

Base Weathering agent. This is almost exactly like the base Mover

Dissolution

Dissolution is still under development and not recommended for use.

Emulsification

Base Weathering agent. This is almost exactly like the base Mover

Biodegradation

Base Weathering agent. This is almost exactly like the base Mover

Langmuir

Easiest to define this as a weathering process that updates 'area' array

FayGravityViscous

Model the FayGravityViscous spreading of the oil. For instantaneous release,

ConstantArea

Used for testing and diagnostics

ROC_Burn

Base Weathering agent. This is almost exactly like the base Mover

ROC_Disperse

Base Weathering agent. This is almost exactly like the base Mover

ROC_Skim

Base Weathering agent. This is almost exactly like the base Mover

Functions

weatherer_sort(weatherer)

Returns an int describing the sorting order of the weatherer

Attributes

sort_order

weatherer_schemas

weatherers_idx

weatherers_by_name

standard_weatherering_sets

class gnome.weatherers.Weatherer(**kwargs)

Bases: gnome.movers.movers.Process

Base Weathering agent. This is almost exactly like the base Mover in the way that it acts upon the model. It contains the same API as the mover as well. Not Serializable since it does is partial implementation

Base weatherer class; defines the API for all weatherers Passes optional arguments to base (Process) class via super. See base class for optional arguments: gnome.movers.mover.Process

adds ‘mass_components’, ‘mass’ to array_types since all weatherers need these.

_schema
__repr__()

Return repr(self).

initialize_data(sc, num_released)

Let weatherers have a way to customize the initialization of data arrays. Currently, only some weatherers use this to customize initialization of data arrays. If movers also move towards this implementation, then move to ‘Process’ base class.

prepare_for_model_run(sc)

Override for weatherers so they can initialize correct ‘mass_balance’ key and set initial value to 0.0

weather_elements(sc, time_step, model_time)

Run the equivalent of get_move for weathering processes. It modifies the SpillContainer’s data arrays; most weatherers update ‘mass_components’ and ‘mass’

Some objects do not implement this since they update arrays like ‘area’ in model_step_is_done()

_halflife(M_0, factors, time)

Assumes our factors are half-life values

_exp_decay(M_0, lambda_, time)

Exponential decay: x(t) = exp(lambda_*time) The lambda_ should be ‘negative’ in order for function to decay

get_wind_speed(points, model_time, min_val=0, coord_sys='r', fill_value=1.0)

Wrapper for the weatherers so they can get wind speeds

check_time(wind, model_time)

Should have an option to extrapolate but for now we do by default

TODO, FIXME: This function does not appear to be used by anything.

Removing it does not break any of the unit tests. If it is not used, it should probably go away.

class gnome.weatherers.HalfLifeWeatherer(half_lives=(15.0 * 60,), **kwargs)

Bases: Weatherer

Give half-life for all components and decay accordingly

The half_lives are a property of HalfLifeWeatherer. If the

len(half_lives) != gnome.array_types.mass_components.shape[0]

then, only keep the number of elements of half_lives that equal the length of half_lives and consequently the mass_components array. The default is 5, it is possible to change default but not easily done. HalfLifeWeatherer is currently more for testing, so will change this if it becomes more widely used and there is a need for user to change default number of mass components.

half_lives could be constants or could be something more complex like a function of time (not implemented yet). Not storing ‘half_lives’ in data_arrays since they are neither time-varying nor varying per LE.

property half_lives
_schema
weather_elements(sc, time_step, model_time)

weather elements over time_step

class gnome.weatherers.Skimmer(amount=0, units=None, water=None, **kwargs)

Bases: CleanUpBase

Just need to add a few internal methods for Skimmer + Burn common code Currently defined as a base class.

initialize Skimmer object - calls base class __init__ using super() active_range is required cleanup operations must have a valid datetime - cannot use -inf and inf active_range is used to get the mass removal rate

property units

return units for amount skimmed

_schema
_ref_as = 'skimmer'
_req_refs = ['water']
_validunits(value)

checks if units are either valid_vol_units or valid_mass_units

prepare_for_model_run(sc)

no need to call base class since no new array_types were added

prepare_for_model_step(sc, time_step, model_time)

Do sub timestep resolution here so numbers add up correctly Mark LEs to be skimmed - do them in order right now. Assume all LEs that are released together will be skimmed together since they would be closer to each other in position.

Assumes: there is more mass in water than amount of mass to be skimmed. The LEs marked for Skimming are marked only once - code checks to see if any LEs are marked for skimming and if none are found, it marks them.

_mass_to_remove(substance)

use density at 15C, ie corresponding with API to do mass/volume conversion

weather_elements(sc, time_step, model_time)

Assumes there is only ever 1 substance being modeled! remove mass equally from LEs marked to be skimmed

class gnome.weatherers.Burn(area=None, thickness=None, active_range=(InfDateTime('-inf'), InfDateTime('inf')), area_units='m^2', thickness_units='m', efficiency=1.0, wind=None, water=None, **kwargs)

Bases: CleanUpBase

Just need to add a few internal methods for Skimmer + Burn common code Currently defined as a base class.

Set the area of boomed oil to be burned. Cleanup operations must have a valid datetime for active start, cannot use -inf. Cannot set active stop - burn automatically stops when oil/water thickness reaches 2mm.

Parameters:
  • area (float) – area of boomed oil/water mixture to burn

  • thickness (float) – thickness of boomed oil/water mixture

  • active_range (datetime) – time when the burn starts is the only thing we track. However we give a range to be consistent with all other weatherers.

  • area_units (str) – default is ‘m^2’

  • thickness_units (str) – default is ‘m’

  • efficiency (float) – burn efficiency, must be greater than 0 and less than or equal to 1.0

  • wind – gnome.environment.Wind object. Only used to set efficiency if efficiency is None. Efficiency is defined as: 1 - 0.07 * wind.get_value(model_time) where wind.get_value(model_time) is value of wind at model_time

Kwargs passed onto base class:

Parameters:
  • name (str) – name of object

  • on (bool) – whether object is on or not for the run

property area_units
property active_range
property thickness
property thickness_units
_schema
_ref_as = 'burn'
_req_refs = ['water', 'wind']
valid_area_units
valid_length_units
_log_thickness_warning()

when thickness or thickness_units are updated, check to see that the value in SI units is > _min_thickness. If it is not, then log a warning

prepare_for_model_run(sc)

resets internal _oilwater_thickness variable to initial thickness specified by user and active stop to ‘inf’ again. initializes sc.mass_balance[‘burned’] = 0.0

prepare_for_model_step(sc, time_step, model_time)
  1. set ‘active’ flag based on active start, and model_time

  2. Mark LEs to be burned - do them in order right now. Assume all LEs that are released together will be burned together since they would be closer to each other in position. Assumes: there is more mass in water than amount of mass to be burned. The LEs marked for Burning are marked only once - during the very first step that the object becomes active

_init_rate_duration(avg_frac_oil=1)

burn duration based on avg_frac_oil content for LEs marked for burn __init__ invokes this to initialize all parameters assuming frac_water = 0.0

_set_burn_params(sc, substance)

Once LEs are marked for burn, the frac_water does not change set burn rate for oil/water thickness, as well as volume burn rate for oil:

If data contains LEs marked for burning, then:

avg_frac_oil = mass_weighed_avg(1 - data[‘frac_water’]) _oilwater_thick_burnrate = 0.000058 * avg_frac_oil _oil_vol_burnrate = _oilwater_thick_burnrate * avg_frac_oil * area

The burn duration is also known if efficiency is constant. However, if efficiency is based on variable wind, then duration cannot be computed.

_set_efficiency(points, model_time)

return burn efficiency either from efficiency attribute or computed from wind

weather_elements(sc, time_step, model_time)
  1. figure out the mass to remove for current timestep based on rate and efficiency. Find fraction of total mass and remove equally from all ‘mass_components’ of LEs marked for burning.

  2. update ‘mass’ array and the amount burned in mass_balance dict

  3. append to _burn_duration for each timestep

class gnome.weatherers.ChemicalDispersion(fraction_sprayed, active_range=(InfDateTime('-inf'), InfDateTime('inf')), waves=None, efficiency=1.0, **kwargs)

Bases: CleanUpBase

Just need to add a few internal methods for Skimmer + Burn common code Currently defined as a base class.

another mass removal mechanism. The volume specified gets dispersed with efficiency based on wave conditions.

Parameters:
  • volume (float) – volume of oil (not oil/water?) applied with surfactant

  • units (str) – volume units

  • active_range (2-tuple of datetimes) – Range of datetimes for when the mover should be active

  • waves (an object with same interface as gnome.environment.Waves) – waves object - query to get height. It must contain get_value() method. Default is None to support object creation by WebClient before a waves object is defined

Optional Argument: Either efficiency or waves must be set before running the model. If efficiency is not set, then use wave height to estimate an efficiency

Parameters:

efficiency (float between 0 and 1) – efficiency of operation.

remaining kwargs include ‘on’ and ‘name’ and these are passed to base class via super

_schema
_ref_as = 'chem_dispersion'
_req_refs = ['waves']
prepare_for_model_run(sc)

reset _rate to None. It gets set when LEs are marked to be dispersed.

prepare_for_model_step(sc, time_step, model_time)
  1. invoke base class method (using super) to set active flag

  2. mark LEs for removal

  3. set internal _rate attribute for mass removal [kg/sec]

_set_efficiency(points, model_time)
weather_elements(sc, time_step, model_time)

for now just take away 0.1% at every step

class gnome.weatherers.Beaching(active_range, units='m^3', timeseries=None, water=None, **kwargs)

Bases: gnome.weatherers.cleanup.RemoveMass, gnome.weatherers.Weatherer

It isn’t really a response/cleanup option; however, it works in the same manner in that Beaching removes mass at a user specified rate. Mixin the RemoveMass functionality.

Initialization for the manual beaching events.

Parameters:

timeseries – array containing the volume of oil beached at specified time. The time corresponds with end time of the beaching contains: [(t0, v0), (t1, v1), ..] Assumes the delta time (t1 - t0) is larger than model’s time_step.

Note

Assumes the model’s time_step is smaller than the timeseries timestep, meaning the

fixme: water is never used – it should be removed.

property timeseries
property units
_schema
convert_to_internal_volume()
prepare_for_model_run(sc)

Preparation of data arrays related to beaching

_remove_mass(time_step, model_time, substance)
returns the mass to be removed over time interval:

(model_time, model_time + time_step)

Note

invoked by weather_elements only if object is active for the step.

fixme: the conversion to mass should happen all at once when the

timeseries is set. and it should use substance.standard_density

weather_elements(sc, time_step, model_time)

remove equal fraction of mass from each component.

class gnome.weatherers.Evaporation(water=None, wind=None, **kwargs)

Bases: gnome.weatherers.Weatherer

Base Weathering agent. This is almost exactly like the base Mover in the way that it acts upon the model. It contains the same API as the mover as well. Not Serializable since it does is partial implementation

Parameters:
  • conditions – gnome.environment.Conditions object which contains things like water temperature

  • wind (Wind API, specifically must have get_value(time) method) – wind object for obtaining speed at specified time

_schema
_ref_as = 'evaporation'
_req_refs = ['water', 'wind']
prepare_for_model_run(sc)

add evaporated key to mass_balance for now also add ‘density’ key here Assumes all spills have the same type of oil

_mass_transport_coeff(points, model_time)

Is wind a function of only model_time? How about time_step? at present yes since wind only contains timeseries data

K = c * U ** 0.78 if U <= 10 m/s K = 0.06 * c * U ** 2 if U > 10 m/s

If K is expressed in m/sec, then Buchanan and Hurford set c = 0.0025 U is wind_speed 10m above the surface

Note

wind speed is at least 1 m/s, unless there is an ice aware wind.

Note

ice aware wind enforces minimum speed before applying coverage factor.

_set_evap_decay_constant(points, model_time, data, substance, time_step)
weather_elements(sc, time_step, model_time)

weather elements over time_step

  • sets ‘evaporation’ in sc.mass_balance

  • currently also sets ‘density’ in sc.mass_balance but may update this as we add more weatherers and perhaps density gets set elsewhere

Following diff eq models rate of change each pseudocomponent of oil:

dm(t)/dt = -(1 - fw) * A/B * m(t)

Over a time-step, A, B, C are assumed constant. m(t) is the component mass at beginning of timestep; m(t + Dt) is mass at end of timestep:

m(t + Dt) = m(t) * exp(-L * Dt)
L := (1 - fw) * A/B

Define properties for each pseudocomponent of oil and constants:

vp: vapor pressure
mw: molecular weight

The following quantities are defined for a given blob of oil. The thickness of the blob is same for all LEs regardless of how many LEs are used to model the blob:

area: area computed from fay spreading
m_i: mass of component 'i'
sum_m_mw: sum(m_i/mw_i) over all components

effect of wind - mass transport coefficient:

K: See _mass_transport_coeff()

Finally, Evaporation of component ‘i’ for blob of oil:

A = area * K * vp
B = gas_constant * water_temp * sum_m_mw
L becomes::

L = (1 - fw) * area * K * vp/(gas_constant * water_temp * sum_m_mw)

class gnome.weatherers.NaturalDispersion(waves=None, water=None, algorithm='D&S1988', **kwargs)

Bases: gnome.weatherers.Weatherer

Base Weathering agent. This is almost exactly like the base Mover in the way that it acts upon the model. It contains the same API as the mover as well. Not Serializable since it does is partial implementation

Parameters:
  • conditions – gnome.environment.Conditions object which contains things like water temperature

  • waves – waves object for obtaining wave_height, etc at given time

_schema
_ref_as = 'dispersion'
_req_refs = ['waves', 'water']
_algorithms_opts
prepare_for_model_run(sc)

add dispersion and sedimentation keys to mass_balance Assumes all spills have the same type of oil

prepare_for_model_step(sc, time_step, model_time)

Set/update arrays used by dispersion module for this timestep:

weather_elements(sc, time_step, model_time)

weather elements over time_step - sets ‘natural_dispersion’ and ‘sedimentation’ in sc.mass_balance

disperse_oil_Li(time_step, frac_water, mass, viscosity, density, area, disp_out, sed_out, droplet_avg_size, frac_breaking_waves, disp_wave_energy, wave_height, visc_w, rho_w, sediment, V_entrain, ka)

Oil natural dispersion algorithm developed by Li et al., (2017)

disperse_oil_DS(time_step, frac_water, mass, viscosity, density, area, disp_out, sed_out, droplet_avg_size, frac_breaking_waves, disp_wave_energy, wave_height, visc_w, rho_w, sediment, V_entrain, ka)

Oil natural dispersion model developed by Delvgine and Sweeney (1988) Right now we just want to recreate what the lib_gnome dispersion function is doing…but in python. This will allow us to more easily refactor, and we can always then put it back into lib_gnome if necessary. (TODO: Not quite finished with the function yet.)

class gnome.weatherers.Dissolution(waves=None, wind=None, **kwargs)

Bases: gnome.weatherers.Weatherer

Dissolution is still under development and not recommended for use.

Parameters:

waves – waves object for obtaining wave_height, etc. at a given time

_schema
_ref_as = 'dissolution'
_req_refs = ['waves', 'wind']
prepare_for_model_run(sc)

Add dissolution key to mass_balance if it doesn’t exist. - Assumes all spills have the same type of oil - let’s only define this the first time

prepare_for_model_step(sc, time_step, model_time)

Set/update arrays used by dispersion module for this timestep

initialize_data(sc, num_released)

initialize the newly released portions of our data arrays:

If on is False, then arrays should not be included - dont’ initialize

_initialize_k_ow(sc, num_released)

Initialize the molar averaged oil/water partition coefficient.

Actually, there is nothing to do to initialize our partition coefficient, as it is recalculated in dissolve_oil()

dissolve_oil(data, substance, **kwargs)

Here is where we calculate the dissolved oil. We will outline the steps as we go along, but off the top of my head:

  • recalculate the partition coefficient (K_ow)

  • droplet distribution per LE should be calculated by the natural dispersion process and saved in the data arrays before the dissolution weathering process.

  • for each LE:

    Note

    right now the natural dispersion process only calculates a single average droplet size. But we still treat it as an iterable.

    • for each droplet size category:

      • calculate the water phase transfer velocity (k_w)

      • calculate the mass xfer rate coefficient (beta)

      • calculate the water column time fraction (f_wc)

      • calculate the mass dissolved during refloat period

    • calculate the mass dissolved from the slick during the calm period.

  • the mass dissolved in the water column and the slick is summed per mass fraction (should only be aromatic fractions)

  • the sum of dissolved masses are compared to the existing mass fractions and adjusted to make sure we don’t dissolve more mass than exists in the mass fractions.

oil_avg_density(masses, densities)
oil_total_volume(masses, densities)
state_variable(masses, densities, arom_mask)
beta_coeff(k_w, K_ow, v_inert)
water_column_time_fraction(points, model_time, water_phase_xfer_velocity)
calm_between_wave_breaks(points, model_time, time_step, time_spent_in_wc=0.0)
oil_concentration(masses, densities)
droplet_subsurface_mass_xfer_rate(droplet_avg_size, k_w, oil_concentrations, partition_coeffs, arom_mask, total_volumes)

Here we are implementing something similar to equations

  • 1.26: this should estimate the mass xfer rate in kg/s

    Note

    For this equation to work, we need to estimate the total surface area of all droplets, not just a single one

  • 1.27: this should estimate the mass xfer rate per unit area in kg/(m^2 * s)

  • 1.28: combines equations 1.26 and 1.27

  • 1.29: estimates the surface area of a single droplet.

We return the mass xfer rate in units (kg/s)

Note

The Cohen equation (eq. 1.1, 1.27), I believe, is actually expressed in kg/(m^2 * hr). So we need to convert our time units.

Note

for now, we are receiving a single average droplet size, which we assume will account for 100% of the oil volume. In the future we will need to work with something like:

[(drop_size, vol_fraction, k_w_drop),
 ...
]

This is because each droplet bin will represent a fraction of the total oil volume (or mass?), and will have its own distinct rise velocity. oil_concentrations and partition coefficients will be the same regardless of droplet size.

slick_subsurface_mass_xfer_rate(points, model_time, oil_concentration, partition_coeff, slick_area, arom_mask)

Here we are implementing something similar to equation 1.21 of our dissolution document.

The Cohen equation (eq. 1.1), I believe, is actually expressed in kg/(m^2 * hr). So we need to convert our time units.

We return the mass xfer rate in units (kg/s)

weather_elements(sc, time_step, model_time)

weather elements over time_step

class gnome.weatherers.Emulsification(waves=None, **kwargs)

Bases: gnome.weatherers.Weatherer

Base Weathering agent. This is almost exactly like the base Mover in the way that it acts upon the model. It contains the same API as the mover as well. Not Serializable since it does is partial implementation

Parameters:
  • conditions – gnome.environment.Conditions object which contains things like water temperature

  • waves (get_emulsification_wind(model_time)) – waves object for obtaining emulsification wind speed at specified time

_schema
_ref_as = 'emulsification'
_req_refs = ['waves']
prepare_for_model_run(sc)

add water_content key to mass_balance Assumes all spills have the same type of oil

prepare_for_model_step(sc, time_step, model_time)

Set/update arrays used by emulsification module for this timestep:

weather_elements_lehr(sc, time_step, model_time)

weather elements over time_step - sets ‘water_content’ in sc.mass_balance

weather_elements_adios2(sc, time_step, model_time)

weather elements over time_step - sets ‘water_content’ in sc.mass_balance

weather_elements(sc, time_step, model_time)

weather elements over time_step - sets ‘water_content’ in sc.mass_balance

_H_log(k, x)

logistic function for turning on emulsification

_H_4(k, x)

symmetric function for turning on emulsification

_Bw(x_visc, x_sig_min, x_fasph, x_r, x_s)
_water_uptake_coeff(points, model_time, substance)

Use higher of wind or pseudo wind corresponding to wave height

if (H0 > 0) HU = 2.0286 * sqrt(g * H0) if (HU < 4.429) HU = pow(HU / .71, .813) if (U < HU) U = HU k_emul = 6.0 * K0Y * U * U / d_max

class gnome.weatherers.Biodegradation(waves=None, **kwargs)

Bases: gnome.weatherers.Weatherer

Base Weathering agent. This is almost exactly like the base Mover in the way that it acts upon the model. It contains the same API as the mover as well. Not Serializable since it does is partial implementation

Base weatherer class; defines the API for all weatherers Passes optional arguments to base (Process) class via super. See base class for optional arguments: gnome.movers.mover.Process

adds ‘mass_components’, ‘mass’ to array_types since all weatherers need these.

_schema
_ref_as = 'biodegradation'
_req_refs = ['waves']
prepare_for_model_run(sc)

Add biodegradation key to mass_balance if it doesn’t exist.

  • Assumes all spills have the same type of oil

  • let’s only define this the first time

initialize_data(sc, num_released)

Initialize needed weathering data arrays but only if ‘on’ is True

bio_degradate_oil(K, data, yield_factor)

Calculate oil bio degradation

K - biodegradation rate coefficients are calculated for

temperate or arctic environment conditions

yield_factor - specific surface value (sq meter per kg)

yield_factor = 1 / ( d * ro) where

d - droplet diameter

ro - droplet density

data[‘mass_components’] - mass of pseudocomponents

get_K_comp_rates(type_and_bp)

Get bio degradation rate coefficient based on component type and its boiling point for temparate or arctic environment conditions. It must take into consideration saturates below C30 and aromatics only.

type_and_bp - a tuple (‘type’, ‘boiling_point’)
  • ‘type’: component type, string

  • ‘boiling_point’: float value

self.arctic - flag for arctic conditions
  • TRUE if arctic conditions (below 6 deg C)

  • FALSE if temperate

Rate units: kg/m^2 per day(!)

weather_elements(sc, time_step, model_time)

weather elements over time_step

class gnome.weatherers.Langmuir(water=None, wind=None, **kwargs)

Bases: gnome.weatherers.core.Weatherer

Easiest to define this as a weathering process that updates ‘area’ array

initialize wind to (0, 0) if it is None

_schema
_ref_as = 'langmuir'
_req_refs = ['water', 'wind']
_get_frac_coverage(points, model_time, rel_buoy, thickness)

return fractional coverage for a blob of oil with inputs; relative_buoyancy, and thickness

Assumes the thickness is the minimum oil thickness associated with max area achievable by Fay Spreading

Frac coverage bounds are constants. If computed frac_coverge is outside the bounds of (0.1, or 1.0), then limit it to:

0.1 <= frac_cov <= 1.0

_wind_speed_bound(rel_buoy, thickness)

return min/max wind speed for given rel_buoy, thickness such that Langmuir effect is within bounds:

0.1 <= frac_coverage <= 1.0

weather_elements(sc, time_step, model_time)

set the ‘area’ array based on the Langmuir process This only applies to particles marked for weathering on the surface: ie fate_status is surface_weather

class gnome.weatherers.FayGravityViscous(water=None, thickness_limit=None, **kwargs)

Bases: gnome.weatherers.core.Weatherer

Model the FayGravityViscous spreading of the oil. For instantaneous release, this assumes all LEs released together spread as a blob following Fay (1971). The blob can be partitioned into ‘N’ LEs and the assumption is that the thickness and initial volume of the blob applies to all LEs in it. For continuous release, the spreading algorithm is similar to Dodge et al., (1983), where blob volume is considered as the cumulative volume of oil varying with time during the release period

initialize object - invoke super, add required data_arrays.

_schema
_ref_as = 'spreading'
_req_refs = ['water']
static _gravity_spreading_t0(water_viscosity, relative_buoyancy, blob_init_vol, spreading_const)

time for the initial transient phase of spreading to complete. This depends on blob volume, but is on the order of minutes. Cache up to 10 inputs - don’t expect 10 or more spills in one scenario.

_time_to_reach_max_area(water_viscosity, rel_buoy, blob_init_vol)

just a convenience function to compute the time to reach max area All inputs are scalars

init_area(water_viscosity, relative_buoyancy, blob_init_vol)

This takes scalars inputs since water_viscosity, init_volume and relative_buoyancy for a bunch of LEs released together will be the same

Parameters:
  • water_viscosity (float) – viscosity of water

  • blob_init_volume (float) – total initial volume of all LEs released together

  • relative_buoyancy (float) – relative buoyancy of oil wrt water: (rho_water - rho_oil)/rho_water where rho is the density

Equation for gravity spreading:

A0 = PI*(k2**4/k1**2)*((V0**5*g*dbuoy)/(nu_h2o**2))**(1./6.)
update_area(water_viscosity, relative_buoyancy, blob_init_vol, area, max_area_le, time_step, vol_frac_le_st, age)

update area array in place, also return area array each blob is defined by its age. This updates the area of each blob, as such, use the mean relative_buoyancy for each blob. Still check and ensure relative buoyancy is > 0 for all LEs

Parameters:
  • water_viscosity (float) – viscosity of water

  • relative_buoyancy (float) – relative buoyancy of oil wrt water at release time. This does not change over time.

  • blob_init_volume (numpy array) – numpy array of floats containing initial release volume of blob. This is the same for all LEs released together. Note that for continuous release, the blob_init_vol will be updated as cumulative volume within the release duration.

  • area (numpy array) – numpy array of floats containing area of each LE. Assume The LEs with same age belong to the same blob. Sum these up to get the area of the blob to compare it to max_area (or min thickness). Keep updating blob area till max_area is achieved. Equally divide updated_blob_area into the number of LEs used to model the blob.

  • max_area_le (float) – bool array. If a LE area reaches max_area_le beyond which it will not spread, toggle the LEs associated with that LE to True. Max spreading is based on min thickness based on initial viscosity of oil. This is used by Langmuir since the process acts on particles after spreading completes.

  • time_step – time step of simulation, which is in seconds.

  • vol_frac_le_st (numpy array of int32) – numpy array the same size as area. This is the volume fraction of each LE. It is used to convert the computation into element-based.

  • age (numpy array of int32) – numpy array the same size as area and blob_init_volume. This is the age of each LE. The LEs with the same age belong to the same blob. Age is in seconds.

Returns:

(updated ‘area’ array, updated ‘at_max_area’ array). It also changes the input ‘area’ array and the ‘at_max_area’ bool array inplace. However, the input arrays could be copies so best to also return the updates.

static get_thickness_limit(vo)

return the spreading thickness limit based on viscosity todo: documented in langmiur docs

  1. vo >= 1e-4; limit = 1e-4 m

  2. 1e-4 > vo >= 1e-6; limit = 1e-5 + 0.9091*(vo - 1e-6) m

  3. 1e-6 > vo; limit = 1e-5 m

_set_thickness_limit(vo)

sets internal thickness_limit variable

prepare_for_model_run(sc)

Assumes only one type of substance is spilled

That’s now TRUE!

_set_init_relative_buoyancy(substance)

set the initial relative buoyancy of oil wrt water use temperature of water to get oil density if relative_buoyancy < 0 raises a GnomeRuntimeError - particles will sink.

initialize_data(sc, num_released)

initialize ‘relative_buoyancy’. Note that initialization of spreading area for LEs is done in release object.

If on is False, then arrays should not be included - dont’ initialize

weather_elements(sc, time_step, model_time)

Update ‘area’, ‘fay_area’ for previously released particles The updated ‘area’, ‘fay_area’ is associated with age of particles at:

model_time + time_step

class gnome.weatherers.ConstantArea(area, **kwargs)

Bases: gnome.weatherers.core.Weatherer

Used for testing and diagnostics - must be manually hooked up

Base weatherer class; defines the API for all weatherers Passes optional arguments to base (Process) class via super. See base class for optional arguments: gnome.movers.mover.Process

adds ‘mass_components’, ‘mass’ to array_types since all weatherers need these.

_ref_as = 'spreading'
initialize_data(sc, num_released)

If on is False, then arrays should not be included - dont’ initialize

weather_elements(sc, time_step, model_time)

return the area array as it was entered since that contains area per LE if there is more than one LE. Kept the interface the same as FayGravityViscous since WeatheringData will call it the same way.

class gnome.weatherers.ROC_Burn(offset=None, boom_length=None, boom_draft=None, speed=None, throughput=None, burn_efficiency_type=None, units=_si_units, **kwargs)

Bases: Response

Base Weathering agent. This is almost exactly like the base Mover in the way that it acts upon the model. It contains the same API as the mover as well. Not Serializable since it does is partial implementation

Base weatherer class; defines the API for all weatherers Passes optional arguments to base (Process) class via super. See base class for optional arguments: gnome.movers.mover.Process

adds ‘mass_components’, ‘mass’ to array_types since all weatherers need these.

_si_units
_units_type
_ref_as = 'roc_burn'
_schema
prepare_for_model_run(sc)

Override for weatherers so they can initialize correct ‘mass_balance’ key and set initial value to 0.0

prepare_for_model_step(sc, time_step, model_time)
  1. set ‘active’ flag based on timeseries and model_time

  2. Mark LEs to be burned, do them in order right now. assume all LEs that are released together will be burned together since they would be closer to each other in position.

_collect(sc, time_step, model_time)
_transit(sc, time_step, model_time)
_burn(sc, time_step, model_time)
_clean(sc, time_step, model_time)
weather_elements(sc, time_step, model_time)

Remove mass from each le equally for now, no flagging for not just make sure it’s from floating oil.

class gnome.weatherers.ROC_Disperse(transit=None, pass_length=4, dosage=None, dosage_type='auto', cascade_on=False, cascade_distance=None, loading_type='simultaneous', pass_type='bidirectional', disp_oil_ratio=None, disp_eff=None, platform=None, units=None, wind=None, onsite_reload_refuel=False, **kwargs)

Bases: Response

Base Weathering agent. This is almost exactly like the base Mover in the way that it acts upon the model. It contains the same API as the mover as well. Not Serializable since it does is partial implementation

Base weatherer class; defines the API for all weatherers Passes optional arguments to base (Process) class via super. See base class for optional arguments: gnome.movers.mover.Process

adds ‘mass_components’, ‘mass’ to array_types since all weatherers need these.

_attr
_si_units
_units_type
_ref_as = 'roc_disperse'
_req_refs = ['wind']
_schema
wind_eff_list = [15, 30, 45, 60, 70, 78, 80, 82, 83, 84, 84, 84, 84, 84, 83, 83, 82, 80, 79, 78, 77, 75, 73, 71,...
visc_eff_table
get_mission_data(dosage=None, area=None, pass_len=None, efficiency=None, units=None)

Given a dosage and an area to spray, will return a tuple of information as follows: Minimize number of passes by using high swath_width. If pump rate cannot get to the dosage necessary, reduce the swath width until it can. Default units are (‘gal/acre’, ‘m^3, ‘nm’, percent)

Return tuple is as below (num_passes, disp/pass, oil/pass) (number, gal, ft, gal/min)

prepare_for_model_run(sc)

Override for weatherers so they can initialize correct ‘mass_balance’ key and set initial value to 0.0

dosage_from_thickness(sc)
get_disp_eff_avg(sc, model_time)
get_disp_eff(sc, model_time)
prepare_for_model_step(sc, time_step, model_time)
simulate_boat(sc, time_step, model_time)
simulate_plane(sc, time_step, model_time)
reset_for_return_to_base(model_time, message)
update_time(time_remaining, model_time, time_step)
dispersable_oil_idxs(sc)
dispersable_oil_amount(sc, units='gal')
weather_elements(sc, time_step, model_time)

Run the equivalent of get_move for weathering processes. It modifies the SpillContainer’s data arrays; most weatherers update ‘mass_components’ and ‘mass’

Some objects do not implement this since they update arrays like ‘area’ in model_step_is_done()

class gnome.weatherers.ROC_Skim(speed=None, storage=None, swath_width=None, group=None, throughput=None, nameplate_pump=None, skim_efficiency_type=None, recovery=None, recovery_ef=None, decant=None, decant_pump=None, discharge_pump=None, rig_time=None, transit_time=None, units=_si_units, **kwargs)

Bases: Response

Base Weathering agent. This is almost exactly like the base Mover in the way that it acts upon the model. It contains the same API as the mover as well. Not Serializable since it does is partial implementation

Base weatherer class; defines the API for all weatherers Passes optional arguments to base (Process) class via super. See base class for optional arguments: gnome.movers.mover.Process

adds ‘mass_components’, ‘mass’ to array_types since all weatherers need these.

_si_units
_units_type
_schema
prepare_for_model_run(sc)

Override for weatherers so they can initialize correct ‘mass_balance’ key and set initial value to 0.0

prepare_for_model_step(sc, time_step, model_time)

sets active flag based on time_span and on flag. Object is active if following hold and ‘on’ is True:

  1. active start <= (model_time + time_step/2) so object is on for more than half the timestep

  2. (model_time + time_step/2) <= active_stop so again the object is on for at least half the time step flag to true.

Parameters:
  • sc – an instance of gnome.spill_container.SpillContainer class

  • time_step – time step in seconds

  • model_time_datetime – current model time as datetime object

_collect(sc, time_step, model_time)
_transit(sc, time_step, model_time)
_offload(sc, time_step, model_time)
weather_elements(sc, time_step, model_time)

Remove mass from each le equally for now, no flagging for now just make sure the mass is from floating oil.

_getRecoveryEfficiency()
gnome.weatherers.sort_order
gnome.weatherers.weatherer_schemas
gnome.weatherers.weatherers_idx
gnome.weatherers.weatherers_by_name
gnome.weatherers.standard_weatherering_sets
gnome.weatherers.weatherer_sort(weatherer)

Returns an int describing the sorting order of the weatherer or None if an order is not defined for the weatherer

Parameters:

weatherer – weatherer instance