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)
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)
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)
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)
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