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_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_noparticles_model_run_after_release_time(self): """ Tests that the spill doesn't release anything if the first call to release elements is after the release time. This so that if the user sets the model start time after the spill, they don't get anything. """ sp = PointLineSource(num_elements=self.num_elements, start_position=self.start_position, release_time=self.release_time) # Test no particles released for following conditions # current_time > spill's release_time # current_time + timedelta > spill's release_time for rel_delay in range(1, 3): num = sp.num_elements_to_release(self.release_time + timedelta(hours=rel_delay), time_step=30 * 60) #assert num is None assert num == 0 # rewind and it should work sp.rewind() data_arrays = self.release_and_assert(sp, self.release_time, 30 * 60, {}, self.num_elements) assert np.alltrue(data_arrays['positions'] == self.start_position)
def test_inst_point_release(self): """ Test all particles for an instantaneous point release are released correctly. - also tests that once all particles have been released, no new particles are released in subsequent steps """ sp = PointLineSource(num_elements=self.num_elements, start_position=self.start_position, release_time=self.release_time) timestep = 3600 # seconds # release all particles data_arrays = self.release_and_assert(sp, self.release_time, timestep, {}, self.num_elements) assert np.alltrue(data_arrays['positions'] == self.start_position) # no more particles to release since all particles have been released num = sp.num_elements_to_release(self.release_time + timedelta(10), timestep) #assert num is None assert num == 0 # reset and try again sp.rewind() assert sp.num_released == 0 num = sp.num_elements_to_release(self.release_time - timedelta(10), timestep) #assert num is None assert num == 0 assert sp.num_released == 0 # release all particles data_arrays = self.release_and_assert(sp, self.release_time, timestep, {}, self.num_elements) assert np.alltrue(data_arrays['positions'] == self.start_position)
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 = PointLineSource(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.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.num_elements, 3) assert np.array_equal(data_arrays['positions'][0], sp.start_position) assert np.array_equal(data_arrays['positions'][-1], sp.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.end_position - sp.start_position) / (sp.num_elements - 1) assert np.all(delta_p == sp.delta_pos) assert np.allclose(delta_p, np.diff(data_arrays['positions'], axis=0), 0, 1e-10)
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 = PointLineSource(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))
def test_noparticles_model_run_before_release_time(self): """ Tests that the spill doesn't release anything if the first call to num_elements_to_release is before the release_time + timestep. """ sp = PointLineSource(num_elements=self.num_elements, start_position=self.start_position, release_time=self.release_time) print 'release_time:', self.release_time timestep = 360 # seconds # right before the release num = sp.num_elements_to_release(self.release_time - timedelta(seconds=360), timestep) #assert num is None assert num == 0 # right after the release data_arrays = self.release_and_assert(sp, self.release_time - timedelta(seconds=1), timestep, {}, self.num_elements) assert np.alltrue(data_arrays['positions'] == self.start_position)