def test_nemo_grid(mode): data_path = path.join(path.dirname(__file__), 'test_data/') filenames = { 'U': data_path + 'Uu_eastward_nemo_cross_180lon.nc', 'V': data_path + 'Vv_eastward_nemo_cross_180lon.nc', 'mesh_mask': data_path + 'mask_nemo_cross_180lon.nc' } variables = {'U': 'U', 'V': 'V'} dimensions = {'lon': 'glamf', 'lat': 'gphif'} field_set = FieldSet.from_nemo(filenames, variables, dimensions) # test ParticleSet.from_field on curvilinear grids ParticleSet.from_field(field_set, ptype[mode], start_field=field_set.U, size=5) def sampleVel(particle, fieldset, time, dt): (particle.zonal, particle.meridional) = fieldset.UV[time, particle.lon, particle.lat, particle.depth] class MyParticle(ptype[mode]): zonal = Variable('zonal', dtype=np.float32, initial=0.) meridional = Variable('meridional', dtype=np.float32, initial=0.) lonp = 175.5 latp = 81.5 pset = ParticleSet.from_list(field_set, MyParticle, lon=[lonp], lat=[latp]) pset.execute(pset.Kernel(sampleVel), runtime=0, dt=0) u = field_set.U.units.to_source(pset[0].zonal, lonp, latp, 0) v = field_set.V.units.to_source(pset[0].meridional, lonp, latp, 0) assert abs(u - 1) < 1e-4 assert abs(v) < 1e-4
def test_random_field(mode, k_sample_p, xdim=20, ydim=20, npart=100): """Sampling test that tests for overshoots by sampling a field of random numbers between 0 and 1. """ np.random.seed(123456) dimensions = { 'lon': np.linspace(0., 1., xdim, dtype=np.float32), 'lat': np.linspace(0., 1., ydim, dtype=np.float32) } data = { 'U': np.zeros((xdim, ydim), dtype=np.float32), 'V': np.zeros((xdim, ydim), dtype=np.float32), 'P': np.random.uniform(0, 1., size=(xdim, ydim)), 'start': np.ones((xdim, ydim), dtype=np.float32) } fieldset = FieldSet.from_data(data, dimensions, mesh='flat', transpose=True) pset = ParticleSet.from_field(fieldset, size=npart, pclass=pclass(mode), start_field=fieldset.start) pset.execute(k_sample_p, endtime=1., dt=1.0) sampled = pset.p assert ((sampled >= 0.).all())
def test_pset_create_field_curvi(npart=100): np.random.seed(123456) r_v = np.linspace(.25, 2, 20) theta_v = np.linspace(0, np.pi / 2, 200) dtheta = theta_v[1] - theta_v[0] dr = r_v[1] - r_v[0] (r, theta) = np.meshgrid(r_v, theta_v) x = -1 + r * np.cos(theta) y = -1 + r * np.sin(theta) grid = CurvilinearZGrid(x, y) u = np.ones(x.shape) v = np.where(np.logical_and(theta > np.pi / 4, theta < np.pi / 3), 1, 0) ufield = Field('U', u, grid=grid) vfield = Field('V', v, grid=grid) fieldset = FieldSet(ufield, vfield) pset = ParticleSet.from_field(fieldset, size=npart, pclass=ptype['scipy'], start_field=fieldset.V) lons = np.array([p.lon + 1 for p in pset]) lats = np.array([p.lat + 1 for p in pset]) thetas = np.arctan2(lats, lons) rs = np.sqrt(lons * lons + lats * lats) test = np.pi / 4 - dtheta < thetas test *= thetas < np.pi / 3 + dtheta test *= rs > .25 - dr test *= rs < 2 + dr assert np.all(test)
def test_random_field(mode, k_sample_p, xdim=20, ydim=20, npart=100): """Sampling test that test for overshoots by sampling a field of random numbers between 0 and 1. """ np.random.seed(123456) lon = np.linspace(0., 1., xdim, dtype=np.float32) lat = np.linspace(0., 1., ydim, dtype=np.float32) U = np.zeros((xdim, ydim), dtype=np.float32) V = np.zeros((xdim, ydim), dtype=np.float32) P = np.random.uniform(0, 1., size=(xdim, ydim)) S = np.ones((xdim, ydim), dtype=np.float32) grid = Grid.from_data(U, lon, lat, V, lon, lat, mesh='flat', field_data={ 'P': np.asarray(P, dtype=np.float32), 'start': S }) pset = ParticleSet.from_field(grid, size=npart, pclass=pclass(mode), start_field=grid.start) pset.execute(k_sample_p, endtime=1., dt=1.0) sampled = np.array([p.p for p in pset]) assert ((sampled >= 0.).all())
def test_pset_create_field(fieldset, mode, npart=100): np.random.seed(123456) shape = (fieldset.U.lon.size, fieldset.U.lat.size) K = Field('K', lon=fieldset.U.lon, lat=fieldset.U.lat, data=np.ones(shape, dtype=np.float32), transpose=True) pset = ParticleSet.from_field(fieldset, size=npart, pclass=ptype[mode], start_field=K) assert (np.array([p.lon for p in pset]) <= K.lon[-1]).all() assert (np.array([p.lon for p in pset]) >= K.lon[0]).all() assert (np.array([p.lat for p in pset]) <= K.lat[-1]).all() assert (np.array([p.lat for p in pset]) >= K.lat[0]).all()
def test_from_field_exact_val(staggered_grid): xdim = 4 ydim = 3 lon = np.linspace(-1, 2, xdim, dtype=np.float32) lat = np.linspace(50, 52, ydim, dtype=np.float32) dimensions = {'lat': lat, 'lon': lon} if staggered_grid == 'Agrid': U = np.zeros((ydim, xdim), dtype=np.float32) V = np.zeros((ydim, xdim), dtype=np.float32) data = { 'U': np.array(U, dtype=np.float32), 'V': np.array(V, dtype=np.float32) } mask = np.array([[1, 1, 0, 0], [1, 1, 1, 0], [1, 1, 1, 1]]) fieldset = FieldSet.from_data(data, dimensions, mesh='flat') FMask = Field('mask', mask, lon, lat) fieldset.add_field(FMask) elif staggered_grid == 'Cgrid': U = np.array([[0, 0, 0, 0], [1, 0, 0, 0], [1, 1, 0, 0]]) V = np.array([[0, 1, 0, 0], [0, 1, 0, 0], [0, 1, 1, 0]]) data = { 'U': np.array(U, dtype=np.float32), 'V': np.array(V, dtype=np.float32) } mask = np.array([[-1, -1, -1, -1], [-1, 1, 0, 0], [-1, 1, 1, 0]]) fieldset = FieldSet.from_data(data, dimensions, mesh='flat') fieldset.U.interp_method = 'cgrid_velocity' fieldset.V.interp_method = 'cgrid_velocity' FMask = Field('mask', mask, lon, lat, interp_method='cgrid_tracer') fieldset.add_field(FMask) class SampleParticle(ptype['scipy']): mask = Variable('mask', initial=fieldset.mask) pset = ParticleSet.from_field(fieldset, size=400, pclass=SampleParticle, start_field=FMask, time=0) # pset.show(field=FMask) assert np.allclose([p.mask for p in pset], 1) assert (np.array([p.lon for p in pset]) <= 1).all() test = np.logical_or( np.array([p.lon for p in pset]) <= 0, np.array([p.lat for p in pset]) >= 51) assert test.all()
def test_pset_create_field(grid, mode, npart=100): np.random.seed(123456) shape = (grid.U.lon.size, grid.U.lat.size) K = Field('K', lon=grid.U.lon, lat=grid.U.lat, data=np.ones(shape, dtype=np.float32)) pset = ParticleSet.from_field(grid, size=npart, pclass=ptype[mode], start_field=K) assert (np.array([p.lon for p in pset]) <= 1.).all() assert (np.array([p.lon for p in pset]) >= 0.).all() assert (np.array([p.lat for p in pset]) <= 1.).all() assert (np.array([p.lat for p in pset]) >= 0.).all()
def test_pset_from_field(mode, xdim=10, ydim=20, npart=10000): np.random.seed(123456) dimensions = {'lon': np.linspace(0., 1., xdim, dtype=np.float32), 'lat': np.linspace(0., 1., ydim, dtype=np.float32)} startfield = np.ones((xdim, ydim), dtype=np.float32) for x in range(xdim): startfield[x, :] = x data = {'U': np.zeros((xdim, ydim), dtype=np.float32), 'V': np.zeros((xdim, ydim), dtype=np.float32), 'start': startfield} fieldset = FieldSet.from_data(data, dimensions, mesh='flat', transpose=True) pset = ParticleSet.from_field(fieldset, size=npart, pclass=pclass(mode), start_field=fieldset.start) densfield = Field(name='densfield', data=np.zeros((xdim+1, ydim+1), dtype=np.float32), lon=np.linspace(-1./(xdim*2), 1.+1./(xdim*2), xdim+1, dtype=np.float32), lat=np.linspace(-1./(ydim*2), 1.+1./(ydim*2), ydim+1, dtype=np.float32), transpose=True) pdens = pset.density(field=densfield, relative=True)[:-1, :-1] assert np.allclose(np.transpose(pdens), startfield/np.sum(startfield), atol=1e-2)
def test_pset_from_field(xdim=10, ydim=10, npart=10000): np.random.seed(123456) dimensions = { 'lon': np.linspace(0., 1., xdim, dtype=np.float32), 'lat': np.linspace(0., 1., ydim, dtype=np.float32) } startfield = np.ones((xdim, ydim), dtype=np.float32) for x in range(xdim): startfield[x, :] = x data = { 'U': np.zeros((xdim, ydim), dtype=np.float32), 'V': np.zeros((xdim, ydim), dtype=np.float32), 'start': startfield } fieldset = FieldSet.from_data(data, dimensions, mesh='flat') pset = ParticleSet.from_field(fieldset, size=npart, pclass=JITParticle, start_field=fieldset.start) pdens = pset.density(area_scale=False, relative=True) assert np.allclose(pdens, startfield / np.sum(startfield), atol=5e-3)