def test_correct_particles_set_by_initializers(fcn, arr_types, spill): ''' Tests that the correct elements (ones that were released last) are initialized ''' # let's only set the values for the last 10 elements # this is not how it would be used, but this is just to make sure # the values for the correct elements are set data_arrays = mock_append_data_arrays(arr_types, num_elems) data_arrays = mock_append_data_arrays(arr_types, num_elems, data_arrays) substance = OilProps('oil_conservative') if spill is not None: spill.release.num_elements = 10 fcn.initialize(num_elems, spill, data_arrays, substance) assert_dataarray_shape_size(arr_types, data_arrays, num_elems * 2) # contrived example since particles will be initialized for every timestep # when they are released. But just to make sure that only values for the # latest released elements are set for key in data_arrays: assert np.all(0 == data_arrays[key][:num_elems]) # values for these particles should be initialized to non-zero assert np.any(0 != data_arrays[key][-num_elems:])
def release_elements(sp, release_time, time_step, data_arrays={}): """ Common code for all spatial release tests """ num = sp.num_elements_to_release(release_time, time_step) if num > 0: # release elements and set their initial values data_arrays = mock_append_data_arrays(arr_types, num, data_arrays) sp.set_newparticle_values(num, release_time, time_step, data_arrays) else: if data_arrays == {}: # initialize arrays w/ 0 elements if nothing is released data_arrays = mock_append_data_arrays(arr_types, 0, data_arrays) return (data_arrays, num)
def test_line_release_with_big_timestep(): """ a line release: where the timestep spans before to after the release time """ release_time = datetime(2012, 1, 1) end_time = release_time + timedelta(seconds=100) time_step = timedelta(seconds=300) start_pos = np.array((0., 0., 0.)) end_pos = np.array((1.0, 2.0, 0.)) sp = PointLineSource(num_elements=10, start_position=start_pos, release_time=release_time, end_position=end_pos, end_release_time=end_time) num = sp.num_elements_to_release(release_time - timedelta(seconds=100), time_step.total_seconds()) assert num == sp.num_elements data_arrays = mock_append_data_arrays(arr_types, num) sp.set_newparticle_values(num, release_time - timedelta(seconds=100), time_step.total_seconds(), data_arrays) # all axes should release particles with same, evenly spaced delta_position for ix in range(3): assert np.allclose(data_arrays['positions'][:, ix], np.linspace(start_pos[ix], end_pos[ix], sp.num_elements))
def test_line_release_with_one_element(): """ one element with a line release -- doesn't really make sense, but it shouldn't crash """ release_time = datetime(2012, 1, 1) end_time = release_time + timedelta(seconds=100) time_step = timedelta(seconds=10) start_pos = np.array((0., 0., 0.)) end_pos = np.array((1.0, 2.0, 0.)) sp = PointLineSource(num_elements=1, start_position=start_pos, release_time=release_time, end_position=end_pos, end_release_time=end_time) num = sp.num_elements_to_release(release_time, time_step.total_seconds()) data_arrays = mock_append_data_arrays(arr_types, num) assert num == 1 sp.set_newparticle_values(num, release_time, time_step.total_seconds(), data_arrays) assert sp.num_released == 1 assert np.array_equal(data_arrays['positions'], [start_pos])
def test_initailize_InitMassFromVolume(): data_arrays = mock_append_data_arrays(mass_array, num_elems) fcn = InitMassFromVolume() spill = Spill() spill.volume = num_elems / (spill.oil_props.get_density('kg/m^3') * 1000) fcn.initialize(num_elems, spill, data_arrays) assert_dataarray_shape_size(mass_array, data_arrays, num_elems) assert np.all(1. == data_arrays['mass'])
def release_and_assert(self, sp, release_time, timestep, data_arrays, expected_num_released): """ Helper function. All tests except one invoke this function. For each release test in this function, group the common actions in this function. :param sp: spill object :param release_time: release time for particles :param timestep: timestep to use for releasing particles :param data_arrays: data_arrays to which new elements are appended. dict containing numpy arrays for values. Serves the same function as gnome.spill_container.SpillContainer().data_arrays :param expected_num_released: number of particles that we expect to release for this timestep. This is used for assertions. It returns a copy of the data_arrays after appending the newly released particles to it. This is so the caller can do more assertions against it. Also so we can keep appending to data_arrays since that is what the SpillContainer will work until a rewind. """ prev_num_rel = sp.num_released num = sp.num_elements_to_release(release_time, timestep) assert num == expected_num_released # updated after set_newparticle_values is called assert prev_num_rel == sp.num_released if num > 0: # only invoked if particles are released data_arrays = mock_append_data_arrays(arr_types, num, data_arrays) sp.set_newparticle_values(num, release_time, timestep, data_arrays) assert sp.num_released == prev_num_rel + expected_num_released else: # initialize all data arrays even if no particles are released if data_arrays == {}: data_arrays = mock_append_data_arrays(arr_types, num, data_arrays) assert data_arrays['positions'].shape == (sp.num_released, 3) return data_arrays
def test_initailize_InitMassFromVolume(): data_arrays = mock_append_data_arrays(mass_array, num_elems) substance = OilProps('oil_conservative') spill = Spill(Release(10)) spill.volume = num_elems / (substance.get_density('kg/m^3') * 1000) fcn = InitMassFromVolume() fcn.initialize(num_elems, spill, data_arrays, substance) assert_dataarray_shape_size(mass_array, data_arrays, num_elems) assert np.all(1. == data_arrays['mass'])
def test_initialize_InitRiseVelFromDist_uniform(): 'Test initialize data_arrays with uniform dist' data_arrays = mock_append_data_arrays(rise_vel_array, num_elems) fcn = InitRiseVelFromDist() fcn.initialize(num_elems, None, data_arrays) assert_dataarray_shape_size(rise_vel_array, data_arrays, num_elems) assert np.all(0 != data_arrays['rise_vel']) assert np.all(data_arrays['rise_vel'] <= 1) assert np.all(data_arrays['rise_vel'] >= 0)
def test_initailize_InitConstantWindageRange(self, fcn, array): 'tests initialize method' data_arrays = mock_append_data_arrays(array, num_elems) fcn.initialize(num_elems, None, data_arrays) assert_dataarray_shape_size(array, data_arrays, num_elems) assert np.all(data_arrays['windage_range'] == fcn.windage_range) assert np.all(data_arrays['windage_persist'] == fcn.windage_persist) np.all(data_arrays['windages'] != 0) np.all(data_arrays['windages'] >= data_arrays['windage_range'][:, 0]) np.all(data_arrays['windages'] <= data_arrays['windage_range'][:, 1])
def test_initailize_InitMassFromTotalMass(): data_arrays = mock_append_data_arrays(mass_array, num_elems) substance = OilProps('oil_conservative') spill = Spill(Release()) spill.release.num_elements = 10 spill.mass = num_elems fcn = InitMassFromTotalMass() fcn.initialize(num_elems, spill, data_arrays, substance) assert_dataarray_shape_size(mass_array, data_arrays, num_elems) assert np.all(1. == data_arrays['mass'])
def test_initailize_InitMassFromTotalMass(): data_arrays = mock_append_data_arrays(mass_array, num_elems) substance = OilProps("oil_conservative") spill = Spill(Release(datetime.now())) spill.release.num_elements = 10 spill.set_mass(num_elems, units="g") fcn = InitMassFromTotalMass() fcn.initialize(num_elems, spill, data_arrays, substance) assert_dataarray_shape_size(mass_array, data_arrays, num_elems) assert np.all(1.0 == data_arrays["mass"])
def test_initialize_InitRiseVelFromDist_normal(): """ test initialize data_arrays with normal dist assume normal distribution works fine - so statistics (mean, var) are not tested """ num_elems = 1000 data_arrays = mock_append_data_arrays(rise_vel_array, num_elems) fcn = InitRiseVelFromDist('normal') fcn.initialize(num_elems, None, data_arrays) assert_dataarray_shape_size(rise_vel_array, data_arrays, num_elems) assert np.all(0 != data_arrays['rise_vel'])
def test_cont_line_release_single_elem_over_multiple_timesteps(self, start_position, end_position): """ testing a release that is releasing while moving over time - less than one elements is released per step. A single element is released over multiple time steps. Test it's right for the full release """ sp = point_line_release_spill(num_elements=10, start_position=start_position, release_time=self.release_time, end_position=end_position, end_release_time=self.release_time + timedelta(minutes=50)) # start before release time = self.release_time - timedelta(minutes=2) delta_t = timedelta(minutes=2) timestep = delta_t.total_seconds() data_arrays = {} # end after release while time < sp.release.end_release_time + delta_t: """ keep releasing particles - no need to use self.release_and_assert since computing expected_number_of_particles_released is cumbersome Also, other tests verify that expected number of particles are being released - keep this easy to understand and follow """ num = sp.num_elements_to_release(time, timestep) data_arrays = mock_append_data_arrays(arr_types, num, data_arrays) sp.set_newparticle_values(num, time, timestep, data_arrays) time += delta_t assert data_arrays['positions'].shape == (sp.release.num_elements, 3) assert np.array_equal(data_arrays['positions'][0], sp.release.start_position) assert np.array_equal(data_arrays['positions'][-1], sp.release.end_position) # the delta position is a constant and is given by # (sp.end_position-sp.start_position)/(sp.num_elements-1) delta_p = ((sp.release.end_position - sp.release.start_position) / (sp.release.num_elements - 1)) assert np.all(delta_p == sp.release.delta_pos) assert np.allclose(delta_p, np.diff(data_arrays['positions'], axis=0), 0, 1e-10)
def test_initialize_InitRiseVelFromDropletDist_weibull(): "Test initialize data_arrays with Weibull dist" num_elems = 10 data_arrays = mock_append_data_arrays(rise_vel_diameter_array, num_elems) substance = OilProps("oil_conservative") spill = Spill(Release(datetime.now())) # (.001*.2) / (.693 ** (1 / 1.8)) - smaller droplet test case, in mm # so multiply by .001 dist = WeibullDistribution(alpha=1.8, lambda_=0.000248) fcn = InitRiseVelFromDropletSizeFromDist(dist) fcn.initialize(num_elems, spill, data_arrays, substance) assert_dataarray_shape_size(rise_vel_array, data_arrays, num_elems) assert np.all(0 != data_arrays["rise_vel"]) assert np.all(0 != data_arrays["droplet_diameter"])
def test_initialize_InitRiseVelFromDropletDist_weibull_with_min_max(): "Test initialize data_arrays with Weibull dist" num_elems = 1000 data_arrays = mock_append_data_arrays(rise_vel_diameter_array, num_elems) substance = OilProps("oil_conservative") spill = Spill(Release(datetime.now())) # (.001*3.8) / (.693 ** (1 / 1.8)) - larger droplet test case, in mm # so multiply by .001 dist = WeibullDistribution(min_=0.002, max_=0.004, alpha=1.8, lambda_=0.00456) fcn = InitRiseVelFromDropletSizeFromDist(dist) fcn.initialize(num_elems, spill, data_arrays, substance) # test for the larger droplet case above assert np.all(data_arrays["droplet_diameter"] >= 0.002) # test for the larger droplet case above assert np.all(data_arrays["droplet_diameter"] <= 0.004)
def test_single_line(num_elements): """ various numbers of elemenets over ten time steps, so release is less than one, one and more than one per time step. """ print 'using num_elements:', num_elements release_time = datetime(2012, 1, 1) end_time = release_time + timedelta(seconds=100) time_step = timedelta(seconds=10) start_pos = np.array((0., 0., 0.)) end_pos = np.array((1.0, 2.0, 0.)) sp = point_line_release_spill(num_elements=num_elements, start_position=start_pos, release_time=release_time, end_position=end_pos, end_release_time=end_time) time = release_time data_arrays = {} while time <= end_time + time_step * 2: #data = sp.release_elements(time, time_step.total_seconds()) num = sp.num_elements_to_release(time, time_step.total_seconds()) data_arrays = mock_append_data_arrays(arr_types, num, data_arrays) if num > 0: sp.set_newparticle_values(num, time, time_step.total_seconds(), data_arrays) time += time_step assert len(data_arrays['positions']) == num_elements assert np.allclose(data_arrays['positions'][0], start_pos) assert np.allclose(data_arrays['positions'][-1], end_pos) # all axes should release particles with same, evenly spaced delta_position for ix in range(3): assert np.allclose(data_arrays['positions'][:, ix], np.linspace(start_pos[ix], end_pos[ix], num_elements))