def sample_sc_wd_spreading(self, num_elements, rel_time):
        '''
        return sample SC, WeatheringData object and FayGravityViscous object
        objects are constructed and prepare_for_model_run() is invoked on all
        '''
        spread = FayGravityViscous()
        (sc, wd) = self.sample_sc_intrinsic(num_elements,
                                            rel_time,
                                            spread.array_types)
        spread.water = wd.water
        spread.prepare_for_model_run(sc)

        return (sc, wd, spread)
    def mk_test_objs(cls, water=None):
        '''
        create SpillContainer and test WeatheringData object test objects so
        we can run Skimmer, Burn like a model without using a full on Model

        NOTE: Use this function to define class level objects. Other methods
            in this class expect sc, and weatherers to be class level objects
        '''
        # spreading does not need to be initialized correctly for these tests,
        # but since we are mocking the model, let's do it correctly
        if water is None:
            water = Water()

        # keep this order
        weatherers = [WeatheringData(water), FayGravityViscous(water)]
        weatherers.sort(key=weatherer_sort)
        sc = SpillContainer()
        print "******************"
        print "Adding a spill to spill container"
        sc.spills += point_line_release_spill(10, (0, 0, 0),
                                              rel_time,
                                              substance=test_oil,
                                              amount=amount,
                                              units='kg',
                                              water=water)
        return (sc, weatherers)
Exemple #3
0
def weathering_data_arrays(n_arrays,
                           water=None,
                           time_step=15.*60,
                           element_type=None,
                           langmuir=False):
    '''
    function to initialize data_arrays set by WeatheringData. Weatherer tests
    can use this function to release elements and initialize data without
    defining a model
    '''
    if water is None:
        water = Water()
    rqd_weatherers = [WeatheringData(water), FayGravityViscous(water)]
    arrays = set()
    arrays.update(n_arrays)
    for wd in rqd_weatherers:
        arrays.update(wd.array_types)

    if element_type is None:
        element_type = floating(substance=test_oil)

    sc = sample_sc_release(num_elements=2,
                           element_type=element_type,
                           arr_types=arrays,
                           time_step=time_step)
    for wd in rqd_weatherers:
        wd.prepare_for_model_run(sc)
        wd.initialize_data(sc, sc.num_released)

    return (sc, time_step, rqd_weatherers)
Exemple #4
0
def weathering_data_arrays(n_arrays,
                           water=None,
                           time_step=15. * 60,
                           substance=None,
                           langmuir=False,
                           num_elements=2,
                           units='g',
                           amount_per_element=1.0):
    '''
    function to initialize data_arrays set by WeatheringData. Weatherer tests
    can use this function to release elements and initialize data without
    defining a model
    '''
    if water is None:
        water = Water()
    rqd_weatherers = [WeatheringData(water), FayGravityViscous(water)]
    arrays = dict()
    arrays.update(n_arrays)
    for wd in rqd_weatherers:
        arrays.update(wd.array_types)

    if isinstance(substance, six.string_types):
        substance = GnomeOil(substance)
    if substance is None:
        substance = GnomeOil(test_oil)
    arrays.update(substance.array_types)

    sc = sample_sc_release(num_elements=num_elements,
                           substance=substance,
                           arr_types=arrays,
                           time_step=time_step,
                           units=units,
                           amount_per_element=amount_per_element)
    for wd in rqd_weatherers:
        wd.prepare_for_model_run(sc)
        wd.initialize_data(sc, sc.num_released)

    return (sc, time_step, rqd_weatherers)
Exemple #5
0
class TestFayGravityViscous:
    spread = FayGravityViscous()
    spread._set_thickness_limit(1e-4)  # thickness_limit based on viscosity

    def expected(self, init_vol, p_age, dbuoy=rel_buoy):
        '''
        Use this to ensure equations entered correctly in FayGravityViscous
        Equations are easier to examine here
        '''
        k1 = self.spread.spreading_const[0]
        k2 = self.spread.spreading_const[1]
        g = constants.gravity
        nu_h2o = water_viscosity
        A0 = np.pi * (k2**4 / k1**2) * (((init_vol)**5 * g * dbuoy) /
                                        (nu_h2o**2))**(1. / 6.)

        p_area = (np.pi * k2**2 *
                  (init_vol**2 * g * dbuoy * p_age**1.5)**(1. / 3) /
                  (nu_h2o**(1. / 6.)))

        return (A0, p_area)

    def test_exceptions(self):
        '''
        if relative_bouyancy is < 0, it just raises an exception
        '''
        with pytest.raises(ValueError):
            'relative_bouyancy >= 0'
            self.spread.init_area(water_viscosity, -rel_buoy, bulk_init_vol)

        with pytest.raises(ValueError):
            'age must be > 0'
            (bulk_init_volume, relative_bouyancy, age, area) = \
                data_arrays()
            self.spread.update_area(water_viscosity, relative_bouyancy,
                                    bulk_init_volume, age, area)

    @pytest.mark.parametrize("num", (1, 10))
    def test_values_same_age(self, num):
        '''
        Compare output of _init_area and _update_thickness to expected output
        returned by self.expected() function.
        '''
        (bulk_init_volume, age, area) = \
            data_arrays(num)
        area[:] = self.spread.init_area(water_viscosity, rel_buoy,
                                        bulk_init_volume[0]) / len(area)

        # bulk_init_volume[0] and age[0] represents the volume and age of all
        # particles released at once
        # computes the init_area and updated area for particles at 900 sec
        (A0, p_area) = self.expected(bulk_init_volume[0], default_ts)
        assert A0 == area.sum()

        age[:] = 900
        self.spread.update_area(water_viscosity, rel_buoy, bulk_init_volume,
                                area, age)

        assert np.isclose(area.sum(), p_area)

    def test_values_vary_age(self):
        '''
        test update_area works correctly for a continuous spill with varying
        age array
        '''
        (bulk_init_volume, age, area) = \
            data_arrays(10)
        (a0, area_900) = self.expected(bulk_init_volume[0], 900)
        age[0::2] = 900
        area[0::2] = a0 / len(area[0::2])  # initialize else divide by 0 error

        (a0, area_1800) = self.expected(bulk_init_volume[1], 1800)
        age[1::2] = 1800
        area[1::2] = a0 / len(area[1::2])  # initialize else divide by 0 error

        # now invoke update_area
        area[:] = self.spread.update_area(water_viscosity, rel_buoy,
                                          bulk_init_volume, area, age)
        assert np.isclose(area[0::2].sum(), area_900)
        assert np.isclose(area[1::2].sum(), area_1800)

    def test_values_vary_age_bulk_init_vol(self):
        '''
        vary bulk_init_vol and age
        '''
        (bulk_init_volume, age, area) = \
            data_arrays(10)
        age[0::2] = 900
        bulk_init_volume[0::2] = 60
        (a0, area_900) = self.expected(bulk_init_volume[0], age[0], rel_buoy)
        area[0::2] = a0 / len(area[0::2])  # initialize else divide by 0 error

        age[1::2] = 1800
        (a0, area_1800) = self.expected(bulk_init_volume[1], age[1])
        area[1::2] = a0 / len(area[1::2])  # initialize else divide by 0 error

        # now invoke update_area
        area[:] = self.spread.update_area(water_viscosity, rel_buoy,
                                          bulk_init_volume, area, age)
        assert np.isclose(area[0::2].sum(), area_900)
        assert np.isclose(area[1::2].sum(), area_1800)

    def test_minthickness_values(self):
        '''
        tests that when blob reaches minimum thickness, area no longer changes
        '''
        (bulk_init_volume, age, area) = \
            data_arrays()
        area[:] = self.spread.init_area(water_viscosity, rel_buoy,
                                        bulk_init_volume[0])

        # elements with same age have the same area since area is computed for
        # blob released at given time. So age must be different to
        # differentiate two blobs
        time = self.spread._time_to_reach_max_area(water_viscosity, rel_buoy,
                                                   bulk_init_volume[0])
        age[:4] = np.ceil(time)
        # divide max blob area into 4 LEs
        i_area = bulk_init_volume[0] / self.spread.thickness_limit / 4

        age[4:] = 900

        self.spread.update_area(water_viscosity, rel_buoy, bulk_init_volume,
                                area, age)
        assert np.all(area[:4] == i_area)
        assert np.all(area[4:] < i_area)
Exemple #6
0
    def test_update_intrinsic_props(self):
        '''
        test multiple spills with same substance
        '''
        weatherers = [WeatheringData(water), FayGravityViscous(water)]

        rel_time = datetime.now().replace(microsecond=0)
        end_time = rel_time + timedelta(hours=1)
        spills = [
            point_line_release_spill(100, (0, 0, 0),
                                     rel_time,
                                     end_release_time=end_time,
                                     amount=100,
                                     units='kg',
                                     substance=test_oil),
            point_line_release_spill(50, (0, 0, 0),
                                     rel_time + timedelta(hours=.25),
                                     substance=test_oil,
                                     amount=100,
                                     units='kg')
        ]
        sc = SpillContainer()
        sc.spills += spills
        at = dict()
        for w in weatherers:
            at.update(w.array_types)

        sc.prepare_for_model_run(at)

        # test initialization as well
        for w in weatherers:
            w.prepare_for_model_run(sc)

        for val in sc.mass_balance.values():
            assert val == 0.0

        # test initialization as well

        ts = 900
        for i in range(-1, 5):
            curr_time = rel_time + timedelta(seconds=i * ts)
            num_released = sc.release_elements(ts, curr_time)

            if num_released > 0:
                for w in weatherers:
                    w.initialize_data(sc, num_released)

            for w in weatherers:
                self.step(w, sc, curr_time)

            for key, val in sc.mass_balance.iteritems():
                if len(sc) > 0 and key not in ('beached', 'non_weathering',
                                               'off_maps'):
                    assert val > 0
                else:
                    # everything, including avg_density is 0 if nothing is
                    # released
                    assert val == 0.0

            if len(sc) > 0:
                # area arrays initialized correctly
                mask = sc['age'] == 0
                if np.any(~mask):
                    # sc['fay_area'][mask] is initial area of blob
                    # sc['fay_area'][~mask] is area of aged blob
                    assert (sc['fay_area'][mask].sum() !=
                            sc['fay_area'][~mask].sum())

                assert all(sc['fay_area'] > 0)
                assert all(sc['init_mass'] > 0)

                # wd props arrays initialized correctly
                assert all(sc['density'] > 0)
                assert all(sc['viscosity'] > 0)

            sc['age'] += ts  # model would do this operation
            print 'Completed step: ', i