:py:mod:`gnome.weatherers.spreading` ==================================== .. py:module:: gnome.weatherers.spreading .. autoapi-nested-parse:: objects used to model the spreading of oil Include the Langmuir process here as well Module Contents --------------- Classes ~~~~~~~ .. autoapisummary:: gnome.weatherers.spreading.FayGravityViscous gnome.weatherers.spreading.ConstantArea gnome.weatherers.spreading.Langmuir Attributes ~~~~~~~~~~ .. autoapisummary:: gnome.weatherers.spreading.PI gnome.weatherers.spreading.PISQUARED .. py:data:: PI .. py:data:: PISQUARED .. py:class:: FayGravityViscous(water=None, thickness_limit=None, **kwargs) Bases: :py:obj:`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. .. py:attribute:: _schema .. py:attribute:: _ref_as :value: 'spreading' .. py:attribute:: _req_refs :value: ['water'] .. py:method:: _gravity_spreading_t0(water_viscosity, relative_buoyancy, blob_init_vol, spreading_const) :staticmethod: 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. .. py:method:: _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 .. py:method:: 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 :param water_viscosity: viscosity of water :type water_viscosity: float :param blob_init_volume: total initial volume of all LEs released together :type blob_init_volume: float :param relative_buoyancy: relative buoyancy of oil wrt water: (rho_water - rho_oil)/rho_water where rho is the density :type relative_buoyancy: float Equation for gravity spreading: :: A0 = PI*(k2**4/k1**2)*((V0**5*g*dbuoy)/(nu_h2o**2))**(1./6.) .. py:method:: 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 :param water_viscosity: viscosity of water :type water_viscosity: float :param relative_buoyancy: relative buoyancy of oil wrt water at release time. This does not change over time. :type relative_buoyancy: float :param blob_init_volume: 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. :type blob_init_volume: numpy array :param area: 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. :type area: numpy array :param max_area_le: 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. :type max_area_le: numpy array of bools :param time_step: time step of simulation, which is in seconds. :type max_area_le: float :param vol_frac_le_st: 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. :type vol_frac_le_st: numpy array of int32 :param age: 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. :type age: numpy array of int32 :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. .. py:method:: get_thickness_limit(vo) :staticmethod: 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 .. py:method:: _set_thickness_limit(vo) sets internal thickness_limit variable .. py:method:: prepare_for_model_run(sc) Assumes only one type of substance is spilled That's now TRUE! .. py:method:: _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. .. py:method:: 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 .. py:method:: 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 .. py:class:: ConstantArea(area, **kwargs) Bases: :py:obj:`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. .. py:attribute:: _ref_as :value: 'spreading' .. py:method:: initialize_data(sc, num_released) If on is False, then arrays should not be included - dont' initialize .. py:method:: 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. .. py:class:: Langmuir(water=None, wind=None, **kwargs) Bases: :py:obj:`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 .. py:attribute:: _schema .. py:attribute:: _ref_as :value: 'langmuir' .. py:attribute:: _req_refs :value: ['water', 'wind'] .. py:method:: _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 .. py:method:: _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 .. py:method:: 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