Example #1
0
    def get_volume(self, units=None):
        """
        return the volume released during the spill. The default units for
        volume are as defined in 'volume_units' property. User can also specify
        desired output units in the function.
        """
        if self._volume is None:
            return self._volume

        if units is None:
            return unit_conversion.convert('Volume', 'm^3',
                                           self.volume_units, self._volume)
        else:
            self._check_units(units)
            return unit_conversion.convert('Volume', 'm^3', units,
                    self._volume)
    def Calculate(self, depth, gas_oil_ratio,
                  oil_jet_velocity=None, oil_jet_density=None,
                  source_pressure=None,
                  output_metric=False):
        if oil_jet_velocity and oil_jet_density:
            # N/m^2  or Pa units (Pascals)
            # equavelent to 950 psi
            source_pressure = (oil_jet_density * (oil_jet_velocity ** 2)) / 2
        elif not source_pressure:
            raise ValueError('need either '
                             'oil_jet_velocity and oil_jet_density, '
                             'or source_pressure')

        if self.metric_inputs:
            depth = convert('Length', 'meter', 'foot', depth)
            gas_oil_ratio = Volume.CubicMeterRatioToScfPerStb(gas_oil_ratio)
            source_pressure = Force.PascalsToPsi(source_pressure)

        # Start-Equation 1.5, page 8
        # Calculating ambient pressure outside leak at depth in psi.
        # We will go off the document, but here are some considerations
        # regarding this calculation:
        # - The ambient atmospheric pressure at sea level is not constant.
        #   It varies with the weather, but averages around 100 kPa
        #   One bar is 100kPa or approximately ambient pressure at sea level
        # - One atmosphere(atm) is also approximately the ambient pressure
        #   at sea level and is equal to 14.7 psi or 1.01325 bar
        # - Ambient water pressure increases linearly with depth.
        #   Roughly, each 10 meters (33 ft) of depth adds another bar
        #   to the ambient pressure.  Assuming the density of sea water
        #   to be 1025 kg/m^3 (in fact it is slightly variable),
        #   pressure increases by 1 atm with each 10 m of depth
        ambient_pressure_at_depth = self.ambient_pressure_at_sea_level + (0.446533 * depth);

        # Start-Equation 1.4, page 8
        # The relative pressure, deltaPrel, difference over the leak point is
        relative_pressure_delta = source_pressure / ambient_pressure_at_depth

        # Start- Table 1.3, page 11
        # Maximum released volume fraction, frel
        max_release_fraction, max_release_occurrence = self.release_fraction_lu[relative_pressure_delta]

        # Start-Section 1.3.5
        #
        # Table 1.4 GOR reduction factors, page 11
        gor_reduction_factor = self.gor_reduction_factor_lu.get_gas_oil_reduction_factor(gas_oil_ratio,
                                                                                         max_release_occurrence)

        if output_metric:
            source_pressure = Force.PsiToPascals(source_pressure)
            ambient_pressure_at_depth = Force.PsiToPascals(ambient_pressure_at_depth)
            max_release_occurrence = Volume.ScfPerStbToCubicMeterRatio(max_release_occurrence)

        return self.gor_results(source_pressure,
                                ambient_pressure_at_depth,
                                relative_pressure_delta,
                                max_release_fraction,
                                max_release_occurrence,
                                gor_reduction_factor)
Example #3
0
    def _convert_units(self, data, ts_format, from_unit, to_unit):
        '''
        Private method to convert units for the 'value' stored in the
        date/time value pair
        '''
        if from_unit != to_unit:
            data[:, 0] = unit_conversion.convert('Velocity',
                                                 from_unit, to_unit,
                                                 data[:, 0])

            if ts_format == basic_types.ts_format.uv:
                # TODO: avoid clobbering the 'ts_format' namespace
                data[:, 1] = unit_conversion.convert('Velocity',
                                                     from_unit, to_unit,
                                                     data[:, 1])

        return data
def test_invalid_unit_convert():
    with pytest.raises(unit_conversion.InvalidUnitError):
        unit_conversion.convert("length", "flintstones", "meters", 1.0)
    with pytest.raises(unit_conversion.InvalidUnitError):
        unit_conversion.convert("length", "feet", "flintstones", 1.0)

    with pytest.raises(unit_conversion.InvalidUnitError):
        unit_conversion.convert("temperature", "feet", "C", 1.0)
    with pytest.raises(unit_conversion.InvalidUnitError):
        unit_conversion.convert("temperature", "f", "feet", 1.0)
def test_invalid_unit_convert():
    with pytest.raises(unit_conversion.InvalidUnitError):
        unit_conversion.convert("length", "flintstones", "meters", 1.0)
    with pytest.raises(unit_conversion.InvalidUnitError):
        unit_conversion.convert("length", "feet", "flintstones", 1.0)

    with pytest.raises(unit_conversion.InvalidUnitError):
        unit_conversion.convert("temperature", "feet", "C", 1.0)
    with pytest.raises(unit_conversion.InvalidUnitError):
        unit_conversion.convert("temperature", "f", "feet", 1.0)
Example #6
0
 def set_volume(self, volume, units):
     """
     set the volume released during the spill. The default units for
     volume are as defined in 'volume_units' property. User can also specify
     desired output units in the function.
     """
     self._check_units(units)
     self._volume = unit_conversion.convert('Volume', units, 'm^3', volume)
     self.volume_units = units
Example #7
0
    def get_density(self, units='kg/m^3'):
        """
        :param units=kg/m^3: optional input if output units should be
            something other than kg/m^3
        """

        if self.oil.api is None:
            raise ValueError("Oil with name '{0}' does not contain 'api'"\
                " property.".format(self.oil.name))

        if units not in self.valid_density_units:
            raise unit_conversion.InvalidUnitError("Desired density units"\
                " must be from following list to be valid: {0}".\
                format(self.valid_density_units))

        # since Oil object can have various densities depending on temperature, 
        # lets return API in correct units
        return unit_conversion.convert('Density', 'API degree', units,
                self.oil.api)
Example #8
0
def test_read_file_init():
    """
    initialize from a long wind file
    """

    wind = environment.Wind(filename=file_)
    wm = WindMover(wind)
    wind_ts = wind.get_timeseries(format='uv', units='meter per second')
    _defaults(wm)  # check defaults set correctly
    cpp_timeseries = _get_timeseries_from_cpp(wm)
    _assert_timeseries_equivalence(cpp_timeseries, wind_ts)

    # make sure default units is correct and correctly called
    # NOTE: Following functionality is already tested in test_wind.py,
    #       but what the heck - do it here too.

    wind_ts = wind.get_timeseries(format=ts_format.uv)
    cpp_timeseries['value'] = unit_conversion.convert('Velocity',
            'meter per second', wind.units, cpp_timeseries['value'])

    _assert_timeseries_equivalence(cpp_timeseries, wind_ts)
Example #9
0
def test_wind_circ_fixture(wind_circ):
    """
    check 'uv' values for wind_circ fixture are correct
    """
    wm = wind_circ['wind']

    # output is in knots

    gtime_val = wm.get_timeseries(format='uv').view(dtype=np.recarray)
    assert np.all(gtime_val.time == wind_circ['uv'].time)
    assert np.allclose(gtime_val.value, wind_circ['uv'].value, atol, rtol)

    # output is in meter per second

    gtime_val = wm.get_timeseries(format='uv', units='meter per second'
                                  ).view(dtype=np.recarray)
    expected = unit_conversion.convert('Velocity', wm.units,
            'meter per second', wind_circ['uv'].value)

    assert np.all(gtime_val.time == wind_circ['uv'].time)
    assert np.allclose(gtime_val.value, expected, atol, rtol)
Example #10
0
def test_init(wind_circ):
    """
    figure out how to pass the parameter to above fixture
    """

    wm = wind_circ['wind']

    # output is in knots

    gtime_val = wm.get_timeseries(format='uv').view(dtype=np.recarray)
    assert np.all(gtime_val.time == wind_circ['uv'].time)
    assert np.allclose(gtime_val.value, wind_circ['uv'].value, atol,
                       rtol)

    # output is in meter per second

    gtime_val = wm.get_timeseries(format='uv', units='meter per second'
                                  ).view(dtype=np.recarray)
    expected = unit_conversion.convert('Velocity', wm.units,
            'meter per second', wind_circ['uv'].value)
    assert np.all(gtime_val.time == wind_circ['uv'].time)
    assert np.allclose(gtime_val.value, expected, atol, rtol)
Example #11
0
    def __init__(
        self,
        release,
        element_type=None,
        on=True,
        volume=None,
        volume_units='m^3',
        # Is this total mass of the spill?
        mass=None,
        mass_units='g',
        id=None,
        ):
        """
        Base spill class. Spill used by a gnome model derive from this class

        :param num_elements: number of LEs - default is 0.
        :type num_elements: int

        Optional parameters (kwargs):

        :param on: Toggles the spill on/off (bool). Default is 'on'.
        :type on: bool
        :type id: str
        :param volume: oil spilled volume (used to compute mass per particle)
            Default is None.
        :type volume: float
        :param volume_units=m^3: volume units
        :type volume_units: str
        :param windage_range=(0.01, 0.04): the windage range of the elements
            default is (0.01, 0.04) from 1% to 4%.
        :type windage_range: tuple: (min, max)
        :param windage_persist=-1: Default is 900s, so windage is updated every
            900 sec. -1 means the persistence is infinite so it is only set at
            the beginning of the run.
        :type windage_persist: integer seconds
        :param id: Unique Id identifying the newly created mover (a UUID as a
            string), used when loading from a persisted model
        :param element_type=None: list of various element_type that are
            released. These are spill specific properties of the elements.
        :type element_type: list of gnome.element_type.* objects
        """

        #self.num_elements = num_elements
        self.release = release
        if element_type is None:
            element_type = elements.floating()
        self.element_type = element_type

        self.on = on    # spill is active or not

        # mass/volume, type of oil spilled
        self._check_units(volume_units)
        self._volume_units = volume_units   # user defined for display
        self._volume = volume
        if volume is not None:
            self._volume = unit_conversion.convert('Volume', volume_units,
                'm^3', volume)

        self._check_units(mass_units, 'Mass')
        self._mass_units = mass_units   # user defined for display
        self._mass = mass
        if mass is not None:
            self._mass = uc.convert('Mass', mass_units, 'g', mass)

        if mass is not None and volume is not None:
            raise ValueError("'mass' and 'volume' cannot both be set")

#==============================================================================
#         if windage_range is not None:
#             if 'windages' not in self.element_type.initializers:
#                 raise TypeError("'windage_range' cannot be set for specified"
#                                 " element_type: {0}".format(element_type))
#             (self.element_type.initializers['windages']).windage_range = \
#                     windage_range
# 
#         if windage_persist is not None:
#             if 'windages' not in self.element_type.initializers:
#                 raise TypeError("'windage_persist' cannot be set for specified"
#                                 " element_type: {0}".format(element_type))
#             (self.element_type.initializers['windages']).windage_persist = \
#                 windage_persist
#==============================================================================

        self._gnome_id = GnomeId(id)
Example #12
0
    def __init__(
        self,
        num_elements=0,
        on=True,
        volume=None,
        volume_units='m^3',
        mass=None,
        mass_units='g',
        oil='oil_conservative',
        windage_range=None,
        windage_persist=None,
        element_type=None,
        id=None,
        ):
        """
        Base spill class. Spill used by a gnome model derive from this class

        :param num_elements: number of LEs - default is 0.
        :type num_elements: int

        Optional parameters (kwargs):

        :param on: Toggles the spill on/off (bool). Default is 'on'.
        :type on: bool
        :type id: str
        :param volume: oil spilled volume (used to compute mass per particle)
            Default is None.
        :type volume: float
        :param volume_units=m^3: volume units
        :type volume_units: str
        :param oil='oil_conservative': Type of oil spilled.
            If this is a string, or an oillibrary.models.Oil object, then
            create gnome.spill.OilProps(oil) object. If this is a
            gnome.spill.OilProps object, then simply instance oil_props
            variable to it: self.oil_props = oil
        :type oil: either str, or oillibrary.models.Oil object or
            gnome.spill.OilProps
        :param windage_range: A tuple defining the min/max % of wind acting on
            each LE. Default (0.01, 0.04)
        :type windage_range: a tuple of size 2 (min, max)
        :param id: Unique Id identifying the newly created mover (a UUID as a
            string), used when loading from a persisted model
        :param element_type=None: list of various element_type that are
            released. These are spill specific properties of the elements.
        :type element_type: list of gnome.element_type.* objects
        """

        self.num_elements = num_elements
        self.on = on    # spill is active or not

        # mass/volume, type of oil spilled
        self._check_units(volume_units)
        self._volume_units = volume_units   # user defined for display
        self._volume = volume
        if volume is not None:
            self._volume = unit_conversion.convert('Volume', volume_units,
                'm^3', volume)

        self.oil_props = OilProps(oil)

        self._gnome_id = GnomeId(id)
        if element_type is None:
            element_type = elements.Floating()

        self.element_type = element_type

        if windage_range is not None:
            if 'windages' not in self.element_type.initializers:
                raise TypeError("'windage_range' cannot be set for specified"
                                " element_type: {0}".format(element_type))
            (self.element_type.initializers['windages']).windage_range = \
                windage_range

        if windage_persist is not None:
            if 'windages' not in self.element_type.initializers:
                raise TypeError("'windage_persist' cannot be set for specified"
                                " element_type: {0}".format(element_type))
            (self.element_type.initializers['windages']).windage_persist = \
                windage_persist

        # number of new particles released at each timestep
        self.num_released = 0
        self.elements_not_released = True

        # flag determines if the first time is valid. If the first call to
        # self.num_elements_to_release(current_time, time_step) has
        # current_time > self.release_time, then no particles are ever released
        # if current_time <= self.release_time, then toggle this flag since
        # model start time is valid
        self.start_time_invalid = True
Example #13
0
from hazpy import unit_conversion
import sqlalchemy

from hazpy import unit_conversion
from itertools import chain
from gnome.db.oil_library.models import Oil, DBSession
from gnome.db.oil_library.initializedb import initialize_sql, \
    load_database
from gnome.utilities.remote_data import get_datafile


# Some standard oils - scope is module level, non-public
_sample_oils = {
    'oil_gas': {'Oil Name': 'oil_gas',
                'API': unit_conversion.convert('Density',
                'gram per cubic centimeter', 'API degree', 0.75)},
    'oil_jetfuels': {'Oil Name': 'oil_jetfuels',
                     'API': unit_conversion.convert('Density',
                     'gram per cubic centimeter', 'API degree',
                     0.81)},
    'oil_diesel': {'Oil Name': 'oil_diesel',
                   'API': unit_conversion.convert('Density',
                   'gram per cubic centimeter', 'API degree',
                   0.87)},
    'oil_4': {'Oil Name': 'oil_4',
              'API': unit_conversion.convert('Density',
              'gram per cubic centimeter', 'API degree', 0.90)},
    'oil_crude': {'Oil Name': 'oil_crude',
                  'API': unit_conversion.convert('Density',
                  'gram per cubic centimeter', 'API degree',
                  0.90)},