def calculateDensityRatio(dfiles, output): Fields = [] for dfile in dfiles: print("Loading %s" % dfile) Fields.append(Field.from_netcdf(dfile, dimensions={'lon': 'nav_lon', 'lat': 'nav_lat', 'time': 'time_counter', 'data': 'TagDensity'}, filenames=[dfile])) limits = [0, 0, 0, 0] limits[0] = np.max([field.lon[0] for field in Fields]) limits[1] = np.min([field.lon[-1] for field in Fields]) limits[2] = np.max([field.lat[0] for field in Fields]) limits[3] = np.min([field.lat[-1] for field in Fields]) #limits[1] = (np.min(field.lon[-1]) for field in Fields) #limits[2] = (np.max(field.lat[0]) for field in Fields) #limits[3] = (np.min(field.lat[-1]) for field in Fields) time_lim = [np.max([field.time[0] for field in Fields]), np.min([field.time[-1] for field in Fields])] #time_lim = [Fields[0].time[0], Fields[0].time[-1]] lon = np.arange(start=limits[0], stop=limits[1]+1, dtype=np.float32) lat = np.arange(start=limits[2], stop=limits[3]+1, dtype=np.float32) time = np.arange(time_lim[0], time_lim[1]+1, 30*24*60*60, dtype=np.float32) Ratio = np.zeros([len(time), len(lat), len(lon)], dtype=np.float32) print(limits) print(Fields[0].lon) print(Fields[1].lon) print(lon) print(Fields[0].lat) print(Fields[1].lat) print(lat) print(Fields[0].time) print(Fields[1].time) print(time) for t in range(len(time)): for x in range(len(lon)): for y in range(len(lat)): tagged = Fields[0].data[np.where(Fields[0].time == time[t])[0][0], np.where(Fields[0].lat == lat[y])[0][0], np.where(Fields[0].lon == lon[x])[0][0]] pop = Fields[1].data[np.where(Fields[1].time == time[t])[0][0], np.where(Fields[1].lat == lat[y])[0][0], np.where(Fields[1].lon == lon[x])[0][0]] #print('%s - %s' % (tagged, pop)) if pop == 0: Ratio[t, y, x] = 0 else: Ratio[t, y, x] = tagged/pop Ratios = Field('DensityRatio', Ratio, lon, lat, time=time) Ratios.write(filename=output)
def test_sampling_multigrids_non_vectorfield(mode, npart): xdim, ydim = 100, 200 U = Field('U', np.zeros((ydim, xdim), dtype=np.float32), lon=np.linspace(0., 1., xdim, dtype=np.float32), lat=np.linspace(0., 1., ydim, dtype=np.float32)) V = Field('V', np.zeros((ydim, xdim), dtype=np.float32), lon=np.linspace(0., 1., xdim, dtype=np.float32), lat=np.linspace(0., 1., ydim, dtype=np.float32)) B = Field('B', np.ones((3 * ydim, 4 * xdim), dtype=np.float32), lon=np.linspace(0., 1., 4 * xdim, dtype=np.float32), lat=np.linspace(0., 1., 3 * ydim, dtype=np.float32)) fieldset = FieldSet(U, V) fieldset.add_field(B, 'B') fieldset.add_constant('sample_depth', 2.5) assert fieldset.U.grid is fieldset.V.grid assert fieldset.U.grid is not fieldset.B.grid class TestParticle(ptype[mode]): sample_var = Variable('sample_var', initial=0.) pset = ParticleSet.from_line(fieldset, pclass=TestParticle, start=[0.3, 0.3], finish=[0.7, 0.7], size=npart) def test_sample(particle, fieldset, time): particle.sample_var += fieldset.B[time, fieldset.sample_depth, particle.lat, particle.lon] kernels = pset.Kernel(AdvectionRK4) + pset.Kernel(test_sample) pset.execute(kernels, runtime=10, dt=1) assert np.allclose(pset.sample_var, 10.0) if mode == 'jit': assert len(pset.xi.shape) == 2 assert pset.xi.shape[0] == len(pset.lon) assert pset.xi.shape[1] == fieldset.gridset.size assert np.all(pset.xi >= 0) assert np.all(pset.xi[:, fieldset.B.igrid] < xdim * 4) assert np.all(pset.xi[:, 0] < xdim) assert pset.yi.shape[0] == len(pset.lon) assert pset.yi.shape[1] == fieldset.gridset.size assert np.all(pset.yi >= 0) assert np.all(pset.yi[:, fieldset.B.igrid] < ydim * 3) assert np.all(pset.yi[:, 0] < ydim)
def test_fieldKh_SpatiallyVaryingBrownianMotion(mesh, mode, xdim=200, ydim=100): """Test SpatiallyVaryingDiffusion on a non-uniform diffusivity field with a linear gradient in one direction""" mesh_conversion = 1 / 1852. / 60 if mesh is 'spherical' else 1 fieldset = zeros_fieldset(mesh=mesh, xdim=xdim, ydim=ydim, mesh_conversion=mesh_conversion) Kh = np.zeros((ydim, xdim), dtype=np.float32) for x in range(xdim): Kh[:, x] = np.tanh(fieldset.U.lon[x] / fieldset.U.lon[-1] * 10.) * xdim / 2. + xdim / 2. + 100. grid = RectilinearZGrid(lon=fieldset.U.lon, lat=fieldset.U.lat, mesh=mesh) fieldset.add_field(Field('Kh_zonal', Kh, grid=grid)) fieldset.add_field(Field('Kh_meridional', Kh, grid=grid)) dKh_zonal_dx, _ = fieldset.Kh_zonal.gradient() _, dKh_meridional_dy = fieldset.Kh_meridional.gradient() fieldset.add_field(Field('dKh_zonal_dx', dKh_zonal_dx, grid=grid)) fieldset.add_field(Field('dKh_meridional_dy', dKh_meridional_dy, grid=grid)) if mesh is 'spherical': fieldset.dKh_zonal_dx.units = GeographicPolar() fieldset.dKh_meridional_dy.units = Geographic() npart = 100 runtime = delta(days=1) random.seed(1234) pset = ParticleSet(fieldset=fieldset, pclass=ptype[mode], lon=np.zeros(npart), lat=np.zeros(npart)) pset.execute(pset.Kernel(SpatiallyVaryingBrownianMotion2D), runtime=runtime, dt=delta(hours=1)) lats = np.array([p.lat for p in pset]) lons = np.array([p.lon for p in pset]) tol = 2000 * mesh_conversion # effectively 2000 m errors (because of low numbers of particles) assert np.allclose(np.mean(lons), 0, atol=tol) assert np.allclose(np.mean(lats), 0, atol=tol) assert (stats.skew(lons) > stats.skew(lats))
def CheckParticlesOnLand_MERCATOR(fieldset, locs): """ Function to creat a Field with 1's at land points and 0's at ocean points and then check if initial position of the particles are located on land or at sea. If on land, particles will be deleted. """ fieldset.computeTimeChunk(0, 1) f_u = fieldset.U[0].data[0, :] f_v = fieldset.V[0].data[0, :] f_uv = np.sqrt(f_u**2 + f_v**2) a_u = np.ma.masked_equal(f_uv, 0) aa_u = np.ma.masked_invalid(a_u) fieldset.add_field( Field('Land_UV', aa_u.mask * 1, lat=fieldset.U[0].grid.lat, lon=fieldset.U[0].grid.lon, depth=fieldset.U[0].grid.depth, mesh='spherical', interp_method='nearest')) jj = [] for i in range(locs.shape[0]): lu = fieldset.Land_UV[0, fieldset.Land_UV.grid.depth[0], locs[i, 3], locs[i, 2]] if lu > 0: jj.append(i) print("Particle: %d from area: %d initiated on Land. Deleting" % (i, locs[i, 1])) if jj: locs = np.delete(locs, np.asarray(jj), axis=0) return locs
def test_3d_2dfield_sampling(mode): data_path = path.join(path.dirname(__file__), 'NemoNorthSeaORCA025-N006_data/') ufiles = sorted(glob(data_path + 'ORCA*U.nc')) vfiles = sorted(glob(data_path + 'ORCA*V.nc')) mesh_mask = data_path + 'coordinates.nc' filenames = {'U': {'lon': mesh_mask, 'lat': mesh_mask, 'data': ufiles}, 'V': {'lon': mesh_mask, 'lat': mesh_mask, 'data': vfiles}, 'nav_lon': {'lon': mesh_mask, 'lat': mesh_mask, 'data': [ufiles[0], ]}} variables = {'U': 'uo', 'V': 'vo', 'nav_lon': 'nav_lon'} dimensions = {'U': {'lon': 'glamf', 'lat': 'gphif', 'time': 'time_counter'}, 'V': {'lon': 'glamf', 'lat': 'gphif', 'time': 'time_counter'}, 'nav_lon': {'lon': 'glamf', 'lat': 'gphif'}} fieldset = FieldSet.from_nemo(filenames, variables, dimensions, field_chunksize=False) fieldset.nav_lon.data = np.ones(fieldset.nav_lon.data.shape, dtype=np.float32) fieldset.add_field(Field('rectilinear_2D', np.ones((2, 2)), lon=np.array([-10, 20]), lat=np.array([40, 80]), field_chunksize=False)) class MyParticle(ptype[mode]): sample_var_curvilinear = Variable('sample_var_curvilinear') sample_var_rectilinear = Variable('sample_var_rectilinear') pset = ParticleSet(fieldset, pclass=MyParticle, lon=2.5, lat=52) def Sample2D(particle, fieldset, time): particle.sample_var_curvilinear += fieldset.nav_lon[time, particle.depth, particle.lat, particle.lon] particle.sample_var_rectilinear += fieldset.rectilinear_2D[time, particle.depth, particle.lat, particle.lon] runtime, dt = 86400*4, 6*3600 pset.execute(pset.Kernel(AdvectionRK4) + Sample2D, runtime=runtime, dt=dt) assert pset.sample_var_rectilinear == runtime/dt assert pset.sample_var_curvilinear == runtime/dt
def run_particles(fieldsetname): if fieldsetname == 'cmems_surface': fieldset = set_cmems_surface_fieldset() elif fieldsetname == 'cmems_50m': fieldset = set_cmems_50m_fieldset() dz = np.gradient(fieldset.U.depth) DZ = np.moveaxis(np.tile(dz, (fieldset.U.grid.ydim, fieldset.U.grid.xdim+10, 1)), [0, 1, 2], [1, 2, 0]) def compute(fieldset): # Calculating vertical weighted average for f in [fieldset.U, fieldset.V]: for tind in f.loaded_time_indices: f.data[tind, :] = np.sum(f.data[tind, :] * DZ, axis=0) / sum(dz) fieldset.compute_on_defer = compute elif fieldsetname == 'skimulator': # requires ncatted -a units,time,o,c,"days since 2016-01-01 00:00:00" scisoc_trpac_compressed.nc for decode_cf fieldset = set_skimulator_fieldset() else: raise NotImplementedError('FieldSet %s not implemented') fieldset.add_constant('max_drift_time', delta(days=180).total_seconds()) size2D = (fieldset.U.grid.ydim, fieldset.U.grid.xdim) fieldset.add_field(Field('Kh_zonal', data=10*np.ones(size2D), lon=fieldset.U.grid.lon, lat=fieldset.U.grid.lat, mesh='spherical', allow_time_extrapolation=True)) fieldset.add_field(Field('Kh_meridional', data=10*np.ones(size2D), lon=fieldset.U.grid.lon, lat=fieldset.U.grid.lat, mesh='spherical', allow_time_extrapolation=True)) fieldset.add_periodic_halo(zonal=True, meridional=False, halosize=5) fieldset.add_field(Field.from_netcdf('EEZ_Field.nc', 'EEZ', {'lon': 'lon', 'lat': 'lat'}, allow_time_extrapolation=True)) pset = createFADset(fieldset, 'dFADsets.txt', nperid=10) pset.execute(SampleEEZ, dt=-1, runtime=0) # setting the EEZ ofile = pset.ParticleFile(name='fadtracks_antibeaching_%s' % fieldsetname, outputdt=delta(days=5)) kernels = WrapLon + pset.Kernel(AdvectionRK4) + BrownianMotion2D + AntiBeaching + \ SampleEEZ + DriftTime pset.execute(kernels, dt=delta(minutes=-10), output_file=ofile, recovery={ErrorCode.ErrorOutOfBounds: OutOfBounds})
def test_rectilinear_s_grids_advect1(mode): # Constant water transport towards the east. check that the particle stays at the same relative depth (z/bath) lon_g0 = np.linspace(0, 1e4, 21, dtype=np.float32) lat_g0 = np.linspace(0, 1000, 2, dtype=np.float32) depth_g0 = np.zeros((lon_g0.size, lat_g0.size, 5), dtype=np.float32) def bath_func(lon): return lon / 1000. + 10 bath = bath_func(lon_g0) for i in range(depth_g0.shape[0]): for k in range(depth_g0.shape[2]): depth_g0[i, :, k] = bath[i] * k / (depth_g0.shape[2] - 1) depth_g0 = depth_g0.transpose( ) # we don't change it on purpose, to check if the transpose op if fixed in jit grid = RectilinearSGrid(lon_g0, lat_g0, depth=depth_g0) zdim = depth_g0.shape[0] u_data = np.zeros((zdim, lat_g0.size, lon_g0.size), dtype=np.float32) v_data = np.zeros((zdim, lat_g0.size, lon_g0.size), dtype=np.float32) w_data = np.zeros((zdim, lat_g0.size, lon_g0.size), dtype=np.float32) for i in range(lon_g0.size): u_data[:, :, i] = 1 * 10 / bath[i] for k in range(zdim): w_data[k, :, i] = u_data[k, :, i] * depth_g0[k, :, i] / bath[i] * 1e-3 u_field = Field('U', u_data, grid=grid) v_field = Field('V', v_data, grid=grid) w_field = Field('W', w_data, grid=grid) field_set = FieldSet(u_field, v_field, fields={'W': w_field}) lon = np.zeros((11)) lat = np.zeros((11)) ratio = [min(i / 10., .99) for i in range(11)] depth = bath_func(lon) * ratio pset = ParticleSet.from_list(field_set, ptype[mode], lon=lon, lat=lat, depth=depth) pset.execute(AdvectionRK4_3D, runtime=10000, dt=500) assert np.allclose([p.depth / bath_func(p.lon) for p in pset], ratio)
def test_brownian_example(mode, mesh, npart=3000): fieldset = FieldSet.from_data({ 'U': 0, 'V': 0 }, { 'lon': 0, 'lat': 0 }, mesh=mesh) # Set diffusion constants. kh_zonal = 100 # in m^2/s kh_meridional = 100 # in m^2/s # Create field of constant Kh_zonal and Kh_meridional fieldset.add_field(Field('Kh_zonal', kh_zonal, lon=0, lat=0, mesh=mesh)) fieldset.add_field( Field('Kh_meridional', kh_meridional, lon=0, lat=0, mesh=mesh)) # Set random seed ParcelsRandom.seed(123456) runtime = delta(days=1) ParcelsRandom.seed(1234) pset = ParticleSet(fieldset=fieldset, pclass=ptype[mode], lon=np.zeros(npart), lat=np.zeros(npart)) pset.execute(pset.Kernel(DiffusionUniformKh), runtime=runtime, dt=delta(hours=1)) expected_std_x = np.sqrt(2 * kh_zonal * runtime.total_seconds()) expected_std_y = np.sqrt(2 * kh_meridional * runtime.total_seconds()) ys = pset.lat * mesh_conversion(mesh) xs = pset.lon * mesh_conversion( mesh ) # since near equator, we do not need to care about curvature effect tol = 200 # 200m tolerance assert np.allclose(np.std(xs), expected_std_x, atol=tol) assert np.allclose(np.std(ys), expected_std_y, atol=tol) assert np.allclose(np.mean(xs), 0, atol=tol) assert np.allclose(np.mean(ys), 0, atol=tol)
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_fieldKh_Brownian(mesh, mode, xdim=200, ydim=100, kh_zonal=100, kh_meridional=50): mesh_conversion = 1 / 1852. / 60 if mesh == 'spherical' else 1 fieldset = zeros_fieldset(mesh=mesh, xdim=xdim, ydim=ydim, mesh_conversion=mesh_conversion) vec = np.linspace(-1e5 * mesh_conversion, 1e5 * mesh_conversion, 2) grid = RectilinearZGrid(lon=vec, lat=vec, mesh=mesh) fieldset.add_field(Field('Kh_zonal', kh_zonal * np.ones((2, 2)), grid=grid)) fieldset.add_field( Field('Kh_meridional', kh_meridional * np.ones((2, 2)), grid=grid)) npart = 1000 runtime = delta(days=1) random.seed(1234) pset = ParticleSet(fieldset=fieldset, pclass=ptype[mode], lon=np.zeros(npart), lat=np.zeros(npart)) pset.execute(pset.Kernel(BrownianMotion2D), runtime=runtime, dt=delta(hours=1)) expected_std_lon = np.sqrt(2 * kh_zonal * mesh_conversion**2 * runtime.total_seconds()) expected_std_lat = np.sqrt(2 * kh_meridional * mesh_conversion**2 * runtime.total_seconds()) lats = np.array([p.lat for p in pset]) lons = np.array([p.lon for p in pset]) tol = 200 * mesh_conversion # effectively 200 m errors assert np.allclose(np.std(lats), expected_std_lat, atol=tol) assert np.allclose(np.std(lons), expected_std_lon, atol=tol) assert np.allclose(np.mean(lons), 0, atol=tol) assert np.allclose(np.mean(lats), 0, atol=tol)
def add_Kh(field_set, lat, lon, kh): """ Adds constant diffusion coefficient to the fieldset :param field_set: :param lat: :param lon: :param kh: :return: """ kh_mer = Field('Kh_meridional', kh * np.ones((len(lat), len(lon)), dtype=np.float32), lon=lon, lat=lat, allow_time_extrapolation=True, fieldtype='Kh_meridional', mesh='spherical', field_chunksize=(2048,2048)) kh_zonal = Field('Kh_zonal', kh * np.ones((len(lat), len(lon)), dtype=np.float32), lon=lon, lat=lat, allow_time_extrapolation=True, fieldtype='Kh_zonal', mesh='spherical', field_chunksize=(2048,2048)) field_set.add_field(kh_mer, 'Kh_meridional') field_set.add_field(kh_zonal, 'Kh_zonal')
def test_sampling_multiple_grid_sizes(pset_mode, mode, ugridfactor): xdim, ydim = 10, 20 U = Field('U', np.zeros((ydim*ugridfactor, xdim*ugridfactor), dtype=np.float32), lon=np.linspace(0., 1., xdim*ugridfactor, dtype=np.float32), lat=np.linspace(0., 1., ydim*ugridfactor, dtype=np.float32)) V = Field('V', np.zeros((ydim, xdim), dtype=np.float32), lon=np.linspace(0., 1., xdim, dtype=np.float32), lat=np.linspace(0., 1., ydim, dtype=np.float32)) fieldset = FieldSet(U, V) pset = pset_type[pset_mode]['pset'](fieldset, pclass=pclass(mode), lon=[0.8], lat=[0.9]) if ugridfactor > 1: assert fieldset.U.grid is not fieldset.V.grid else: assert fieldset.U.grid is fieldset.V.grid pset.execute(AdvectionRK4, runtime=10, dt=1) assert np.isclose(pset.lon[0], 0.8) assert np.all((0 <= pset.xi) & (pset.xi < xdim*ugridfactor))
def set_diffusion(fieldset, diffusivity): fname = '/home/philippe/data/ORCA0083-N06_meshSize.nc' dimensions = {'lon': 'glamt', 'lat': 'gphit'} meshSize = Field.from_netcdf(fname, 'meshSize', dimensions, interp_method='nearest') fieldset.add_field(meshSize) fieldset.add_field( Field('Kh_zonal', data=diffusivity * np.ones(meshSize.data.shape), grid=meshSize.grid, mesh='spherical')) fieldset.add_field( Field('Kh_meridional', data=diffusivity * np.ones(meshSize.data.shape), grid=meshSize.grid, mesh='spherical'))
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_summedfields(mode, with_W, k_sample_p, mesh): xdim = 10 ydim = 20 zdim = 4 gf = 10 # factor by which the resolution of grid1 is higher than of grid2 U1 = Field('U', 0.2*np.ones((zdim*gf, ydim*gf, xdim*gf), dtype=np.float32), lon=np.linspace(0., 1., xdim*gf, dtype=np.float32), lat=np.linspace(0., 1., ydim*gf, dtype=np.float32), depth=np.linspace(0., 20., zdim*gf, dtype=np.float32), mesh=mesh) U2 = Field('U', 0.1*np.ones((zdim, ydim, xdim), dtype=np.float32), lon=np.linspace(0., 1., xdim, dtype=np.float32), lat=np.linspace(0., 1., ydim, dtype=np.float32), depth=np.linspace(0., 20., zdim, dtype=np.float32), mesh=mesh) V1 = Field('V', np.zeros((zdim*gf, ydim*gf, xdim*gf), dtype=np.float32), grid=U1.grid, fieldtype='V') V2 = Field('V', np.zeros((zdim, ydim, xdim), dtype=np.float32), grid=U2.grid, fieldtype='V') fieldsetS = FieldSet(U1+U2, V1+V2) conv = 1852*60 if mesh == 'spherical' else 1. assert np.allclose(fieldsetS.U[0, 0, 0, 0]*conv, 0.3) P1 = Field('P', 30*np.ones((zdim*gf, ydim*gf, xdim*gf), dtype=np.float32), grid=U1.grid) P2 = Field('P', 20*np.ones((zdim, ydim, xdim), dtype=np.float32), grid=U2.grid) P3 = Field('P', 10*np.ones((zdim, ydim, xdim), dtype=np.float32), grid=U2.grid) P4 = Field('P', 0*np.ones((zdim, ydim, xdim), dtype=np.float32), grid=U2.grid) fieldsetS.add_field((P1+P4)+(P2+P3), name='P') assert np.allclose(fieldsetS.P[0, 0, 0, 0], 60) if with_W: W1 = Field('W', 2*np.ones((zdim * gf, ydim * gf, xdim * gf), dtype=np.float32), grid=U1.grid) W2 = Field('W', np.ones((zdim, ydim, xdim), dtype=np.float32), grid=U2.grid) fieldsetS.add_field(W1+W2, name='W') pset = ParticleSet(fieldsetS, pclass=pclass(mode), lon=[0], lat=[0.9]) pset.execute(AdvectionRK4_3D+pset.Kernel(k_sample_p), runtime=2, dt=1) assert np.isclose(pset[0].depth, 6) else: pset = ParticleSet(fieldsetS, pclass=pclass(mode), lon=[0], lat=[0.9]) pset.execute(AdvectionRK4+pset.Kernel(k_sample_p), runtime=2, dt=1) assert np.isclose(pset[0].p, 60) assert np.isclose(pset[0].lon*conv, 0.6, atol=1e-3) assert np.isclose(pset[0].lat, 0.9) assert np.allclose(fieldsetS.UV[0][0, 0, 0, 0], [.2/conv, 0])
def test_rectilinear_s_grids_advect2(mode): # Move particle towards the east, check relative depth evolution lon_g0 = np.linspace(0, 1e4, 21, dtype=np.float32) lat_g0 = np.linspace(0, 1000, 2, dtype=np.float32) depth_g0 = np.zeros((5, lat_g0.size, lon_g0.size), dtype=np.float32) def bath_func(lon): return lon / 1000. + 10 bath = bath_func(lon_g0) zdim = depth_g0.shape[0] for i in range(lon_g0.size): for k in range(zdim): depth_g0[k, :, i] = bath[i] * k / (zdim-1) grid = RectilinearSGrid(lon_g0, lat_g0, depth=depth_g0) u_data = np.zeros((zdim, lat_g0.size, lon_g0.size), dtype=np.float32) v_data = np.zeros((zdim, lat_g0.size, lon_g0.size), dtype=np.float32) rel_depth_data = np.zeros((zdim, lat_g0.size, lon_g0.size), dtype=np.float32) for k in range(1, zdim): rel_depth_data[k, :, :] = k / (zdim-1.) u_field = Field('U', u_data, grid=grid) v_field = Field('V', v_data, grid=grid) rel_depth_field = Field('relDepth', rel_depth_data, grid=grid) field_set = FieldSet(u_field, v_field, fields={'relDepth': rel_depth_field}) class MyParticle(ptype[mode]): relDepth = Variable('relDepth', dtype=np.float32, initial=20.) def moveEast(particle, fieldset, time): particle.lon += 5 * particle.dt particle.relDepth = fieldset.relDepth[time, particle.depth, particle.lat, particle.lon] depth = .9 pset = ParticleSet.from_list(field_set, MyParticle, lon=[0], lat=[0], depth=[depth]) kernel = pset.Kernel(moveEast) for _ in range(10): pset.execute(kernel, runtime=100, dt=50) assert np.allclose(pset.relDepth[0], depth/bath_func(pset.lon[0]))
def set_cmems(fieldset): data_dir = '/projects/0/topios/hydrodynamic_data/CMEMS/NORTHWESTSHELF_REANALYSIS_PHYS_004_009/MetO-NWS-REAN-PHYS-daily-CUR/' fnames = [] years = range(2000, 2005) for y in years: basepath = data_dir + str( y) + '/*/' + 'metoffice_foam1_amm7_NWS_RFVL_dm*.nc' fnames += sorted(glob(str(basepath))) dimensionsU = {'lon': 'lon', 'lat': 'lat', 'time': 'time'} dimensionsV = {'lon': 'lon', 'lat': 'lat', 'time': 'time'} indices = { 'lon': range(1, 296), 'lat': range(1, 374) } # cmems puts nan values at its borders Ucmems = Field.from_netcdf(fnames, ('Ucmems', 'vozocrtx'), dimensionsU, fieldtype='U', indices=indices, allow_time_extrapolation=False) Vcmems = Field.from_netcdf(fnames, ('Vcmems', 'vomecrty'), dimensionsV, fieldtype='V', indices=indices, allow_time_extrapolation=False, grid=Ucmems.grid, dataFiles=Ucmems.dataFiles) fieldset.add_field(Ucmems) fieldset.add_field(Vcmems) fieldset.Ucmems.vmax = 5 fieldset.Vcmems.vmax = 5 fieldset.Unemo = fieldset.U fieldset.Unemo.name = 'Unemo' fieldset.Vnemo = fieldset.V fieldset.Vnemo.name = 'Vnemo' U = NestedField('U', [fieldset.Ucmems, fieldset.Unemo]) V = NestedField('V', [fieldset.Vcmems, fieldset.Vnemo]) fieldset.U = U fieldset.V = V fieldset.cmems = True
def test_brownian_example(mode, npart=3000): fieldset = zeros_fieldset() # Set diffusion constants. kh_zonal = 100 kh_meridional = 100 # Create field of Kh_zonal and Kh_meridional, using same grid as U grid = fieldset.U.grid fieldset.add_field(Field('Kh_zonal', kh_zonal * np.ones((2, 2)), grid=grid)) fieldset.add_field( Field('Kh_meridional', kh_meridional * np.ones((2, 2)), grid=grid)) # Set random seed random.seed(123456) runtime = delta(days=1) random.seed(1234) pset = ParticleSet(fieldset=fieldset, pclass=ptype[mode], lon=np.zeros(npart), lat=np.zeros(npart)) pset.execute(pset.Kernel(BrownianMotion2D), runtime=runtime, dt=delta(hours=1)) expected_std_x = np.sqrt(2 * kh_zonal * runtime.total_seconds()) expected_std_y = np.sqrt(2 * kh_meridional * runtime.total_seconds()) conversion = (1852 * 60) # to convert from degrees to m ys = np.array([p.lat for p in pset]) * conversion xs = np.array( [p.lon for p in pset] ) * conversion # since near equator, we do not need to care about curvature effect tol = 200 # 200m tolerance assert np.allclose(np.std(xs), expected_std_x, atol=tol) assert np.allclose(np.std(ys), expected_std_y, atol=tol) assert np.allclose(np.mean(xs), 0, atol=tol) assert np.allclose(np.mean(ys), 0, atol=tol)
def test_summedfields_slipinterp_warning(boundaryslip): xdim = 10 ydim = 20 zdim = 4 gf = 10 # factor by which the resolution of grid1 is higher than of grid2 U1 = Field('U', 0.2*np.ones((zdim*gf, ydim*gf, xdim*gf), dtype=np.float32), lon=np.linspace(0., 1., xdim*gf, dtype=np.float32), lat=np.linspace(0., 1., ydim*gf, dtype=np.float32), depth=np.linspace(0., 20., zdim*gf, dtype=np.float32), interp_method=boundaryslip) U2 = Field('U', 0.1*np.ones((zdim, ydim, xdim), dtype=np.float32), lon=np.linspace(0., 1., xdim, dtype=np.float32), lat=np.linspace(0., 1., ydim, dtype=np.float32), depth=np.linspace(0., 20., zdim, dtype=np.float32)) V1 = Field('V', np.zeros((zdim*gf, ydim*gf, xdim*gf), dtype=np.float32), grid=U1.grid, fieldtype='V') V2 = Field('V', np.zeros((zdim, ydim, xdim), dtype=np.float32), grid=U2.grid, fieldtype='V') fieldsetS = FieldSet(U1+U2, V1+V2) with pytest.warns(UserWarning): fieldsetS.check_complete()
def add_unbeaching_field(field_set, lat, lon, input_file): """ Adds the unbeaching field from the specified input_file into the current field_set :param field_set: :param lat: :param lon: :param input_file: :return: """ ds = Dataset(input_file, "r+", format="NETCDF4") unBeachU= Field('unBeachU', ds['unBeachU'][:,:], lon=lon, lat=lat, allow_time_extrapolation=True, fieldtype='Kh_meridional', mesh='spherical', field_chunksize=(2048,2048)) unBeachV= Field('unBeachV', ds['unBeachV'][:,:], lon=lon, lat=lat, allow_time_extrapolation=True, fieldtype='Kh_zonal', mesh='spherical', field_chunksize=(2048,2048)) field_set.add_field(unBeachU, 'unBeachU') field_set.add_field(unBeachV, 'unBeachV')
def test_multigrids_pointer(mode): lon_g0 = np.linspace(0, 1e4, 21, dtype=np.float32) lat_g0 = np.linspace(0, 1000, 2, dtype=np.float32) depth_g0 = np.zeros((lon_g0.size, lat_g0.size, 5), dtype=np.float32) def bath_func(lon): return lon / 1000. + 10 bath = bath_func(lon_g0) for i in range(depth_g0.shape[0]): for k in range(depth_g0.shape[2]): depth_g0[i, :, k] = bath[i] * k / (depth_g0.shape[2] - 1) grid_0 = RectilinearSGrid(lon_g0, lat_g0, depth=depth_g0) grid_1 = RectilinearSGrid(lon_g0, lat_g0, depth=depth_g0) u_data = np.zeros((lon_g0.size, lat_g0.size, depth_g0.shape[2]), dtype=np.float32) v_data = np.zeros((lon_g0.size, lat_g0.size, depth_g0.shape[2]), dtype=np.float32) w_data = np.zeros((lon_g0.size, lat_g0.size, depth_g0.shape[2]), dtype=np.float32) u_field = Field('U', u_data, grid=grid_0, transpose=True) v_field = Field('V', v_data, grid=grid_0, transpose=True) w_field = Field('W', w_data, grid=grid_1, transpose=True) field_set = FieldSet(u_field, v_field, fields={'W': w_field}) assert (u_field.grid == v_field.grid) assert (u_field.grid == w_field.grid ) # w_field.grid is now supposed to be grid_1 pset = ParticleSet.from_list(field_set, ptype[mode], lon=[0], lat=[0], depth=[1]) for i in range(10): pset.execute(AdvectionRK4_3D, runtime=1000, dt=500)
def test_sampling_multiple_grid_sizes(mode): """Sampling test that tests for FieldSet with different grid sizes While this currently works fine in Scipy mode, it fails in JIT mode with an out_of_bounds_error because there is only one (xi, yi, zi) for each particle A solution would be to define xi, yi, zi for each field separately """ xdim = 10 ydim = 20 gf = 10 # factor by which the resolution of U is higher than of V U = Field('U', np.zeros((ydim*gf, xdim*gf), dtype=np.float32), lon=np.linspace(0., 1., xdim*gf, dtype=np.float32), lat=np.linspace(0., 1., ydim*gf, dtype=np.float32)) V = Field('V', np.zeros((ydim, xdim), dtype=np.float32), lon=np.linspace(0., 1., xdim, dtype=np.float32), lat=np.linspace(0., 1., ydim, dtype=np.float32)) fieldset = FieldSet(U, V) pset = ParticleSet(fieldset, pclass=pclass(mode), lon=[0.8], lat=[0.9]) pset.execute(AdvectionRK4, runtime=10, dt=1) assert np.isclose(pset[0].lon, 0.8)
def GetOFESLandArray(filename, fieldname): """ Function to return a Field with 1's at land points and 0's at ocean points, based on python basemap :param f: a field of the .nc file, but not a parcels field object! For OFES, land points are masked. This is used here! """ pfile = Dataset(filename, 'r') Lon = pfile.variables['LONN1799_1800'][:] Lat = pfile.variables['LAT'][:] f = pfile.variables[fieldname][:] f = f[0, 0, :, :] Land = Field('Land', f, transpose=False, lon=Lon, lat=Lat) return Land
def test_moving_eddy(fieldset_moving, mode, method, rtol, diffField, npart=1): fieldset = fieldset_moving if diffField: fieldset.add_field( Field('Kh_zonal', np.zeros(fieldset.U.data.shape), grid=fieldset.U.grid)) fieldset.add_field( Field('Kh_meridional', np.zeros(fieldset.V.data.shape), grid=fieldset.V.grid)) fieldset.add_constant('dres', 0.1) lon = np.linspace(12000, 21000, npart) lat = np.linspace(12500, 12500, npart) pset = ParticleSet(fieldset, pclass=ptype[mode], lon=lon, lat=lat) endtime = delta(hours=6).total_seconds() pset.execute(kernel[method], dt=delta(minutes=3), endtime=endtime) exp_lon = [truth_moving(x, y, endtime)[0] for x, y, in zip(lon, lat)] exp_lat = [truth_moving(x, y, endtime)[1] for x, y, in zip(lon, lat)] assert np.allclose(pset.lon, exp_lon, rtol=rtol) assert np.allclose(pset.lat, exp_lat, rtol=rtol)
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 = grid.ParticleSet(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 prepare(fieldset, Cs=0.1): """ Add cell_areas field and gradients of U and V that are both necessary for Smagorinsky parametrization. :param fieldset: mod:`parcels.fieldset.FieldSet` object to add necessary fields to """ fieldset.add_constant('Cs', Cs) fieldset.add_constant('resolutionx',fieldset.U.grid.lon[1]-fieldset.U.grid.lon[0]) fieldset.add_constant('resolutiony',fieldset.U.grid.lat[1]-fieldset.U.grid.lat[0]) x = fieldset.U.grid.lon y = fieldset.U.grid.lat cell_areas = Field(name='cell_areas', data=fieldset.U.cell_areas(), lon=x, lat=y) fieldset.add_field(cell_areas) fieldset.U.calc_cell_edge_sizes() cell_edge_sizes_x = Field(name='cell_edge_sizes_x', data=fieldset.U.cell_edge_sizes['x'], lon=x, lat=y) cell_edge_sizes_y = Field(name='cell_edge_sizes_y', data=fieldset.U.cell_edge_sizes['y'], lon=x, lat=y) fieldset.add_field(cell_edge_sizes_x) fieldset.add_field(cell_edge_sizes_y)
def test_fieldKh_SpatiallyVaryingDiffusion(mesh, mode, pset_mode, kernel, xdim=200, ydim=100): """Test advection-diffusion kernels on a non-uniform diffusivity field with a linear gradient in one direction""" mesh_conversion = 1 / 1852. / 60 if mesh == 'spherical' else 1 fieldset = zeros_fieldset(mesh=mesh, xdim=xdim, ydim=ydim, mesh_conversion=mesh_conversion) Kh = np.zeros((ydim, xdim), dtype=np.float32) for x in range(xdim): Kh[:, x] = np.tanh(fieldset.U.lon[x] / fieldset.U.lon[-1] * 10.) * xdim / 2. + xdim / 2. + 100. grid = RectilinearZGrid(lon=fieldset.U.lon, lat=fieldset.U.lat, mesh=mesh) fieldset.add_field(Field('Kh_zonal', Kh, grid=grid)) fieldset.add_field(Field('Kh_meridional', Kh, grid=grid)) fieldset.add_constant('dres', fieldset.U.lon[1] - fieldset.U.lon[0]) npart = 100 runtime = delta(days=1) ParcelsRandom.seed(1636) pset = pset_type[pset_mode]['pset'](fieldset=fieldset, pclass=ptype[mode], lon=np.zeros(npart), lat=np.zeros(npart)) pset.execute(pset.Kernel(kernel), runtime=runtime, dt=delta(hours=1)) lats = pset.lat lons = pset.lon tol = 2000 * mesh_conversion # effectively 2000 m errors (because of low numbers of particles) assert np.allclose(np.mean(lons), 0, atol=tol) assert np.allclose(np.mean(lats), 0, atol=tol) assert (stats.skew(lons) > stats.skew(lats))
def test_multiple_grid_addlater_error(): xdim, ydim = 10, 20 U = Field('U', np.zeros((ydim, xdim), dtype=np.float32), lon=np.linspace(0., 1., xdim, dtype=np.float32), lat=np.linspace(0., 1., ydim, dtype=np.float32)) V = Field('V', np.zeros((ydim, xdim), dtype=np.float32), lon=np.linspace(0., 1., xdim, dtype=np.float32), lat=np.linspace(0., 1., ydim, dtype=np.float32)) fieldset = FieldSet(U, V) pset = pset_type['soa']['pset'](fieldset, pclass=pclass('jit'), lon=[0.8], lat=[0.9]) # noqa ; to trigger fieldset.check_complete P = Field('P', np.zeros((ydim*10, xdim*10), dtype=np.float32), lon=np.linspace(0., 1., xdim*10, dtype=np.float32), lat=np.linspace(0., 1., ydim*10, dtype=np.float32)) fail = False try: fieldset.add_field(P) except RuntimeError: fail = True assert fail
def test_multigrids_pointer(pset_mode, mode): lon_g0 = np.linspace(0, 1e4, 21, dtype=np.float32) lat_g0 = np.linspace(0, 1000, 2, dtype=np.float32) depth_g0 = np.zeros((5, lat_g0.size, lon_g0.size), dtype=np.float32) def bath_func(lon): return lon / 1000. + 10 bath = bath_func(lon_g0) zdim = depth_g0.shape[0] for i in range(lon_g0.size): for k in range(zdim): depth_g0[k, :, i] = bath[i] * k / (zdim - 1) grid_0 = RectilinearSGrid(lon_g0, lat_g0, depth=depth_g0) grid_1 = RectilinearSGrid(lon_g0, lat_g0, depth=depth_g0) u_data = np.zeros((zdim, lat_g0.size, lon_g0.size), dtype=np.float32) v_data = np.zeros((zdim, lat_g0.size, lon_g0.size), dtype=np.float32) w_data = np.zeros((zdim, lat_g0.size, lon_g0.size), dtype=np.float32) u_field = Field('U', u_data, grid=grid_0) v_field = Field('V', v_data, grid=grid_0) w_field = Field('W', w_data, grid=grid_1) field_set = FieldSet(u_field, v_field, fields={'W': w_field}) assert (u_field.grid == v_field.grid) assert (u_field.grid == w_field.grid ) # w_field.grid is now supposed to be grid_1 pset = pset_type[pset_mode]['pset'].from_list(field_set, ptype[mode], lon=[0], lat=[0], depth=[1]) for i in range(10): pset.execute(AdvectionRK4_3D, runtime=1000, dt=500)
def GetGlobCurrentLandArray(filename, fieldname): """ Function to return a Field with 1's at land points and 0's at ocean points, based on python basemap :param f: a field of the .nc file, but not a parcels field object! For OFES, land points are masked. This is used here! """ pfile = Dataset(filename, 'r') Lon = pfile.variables['lon'][:] Lat = pfile.variables['lat'][:] f = pfile.variables[fieldname][:] f = f[0] L= np.ma.getmask(f) Land=Field('Land',L,transpose=False,lon=Lon,lat=Lat) return Land
def set_unbeaching(fieldset): files = '/home/philippe/data/ORCA%s-N06_unbeaching_vel.nc' % fieldset.nemo_res filenames = files variables = {'Unemo_unbeach': 'unBeachU', 'Vnemo_unbeach': 'unBeachV'} dimensions = {'lon': 'glamf', 'lat': 'gphif'} fieldsetUnBeach = FieldSet.from_nemo(filenames, variables, dimensions, tracer_interp_method='cgrid_velocity') fieldset.add_field(fieldsetUnBeach.Unemo_unbeach) fieldset.add_field(fieldsetUnBeach.Vnemo_unbeach) if fieldset.cmems: fname = '/home/philippe/data/cmems_NWS_rean_004_009_unbeaching_vel.nc' dimensionsU = {'lon': 'lon', 'lat': 'lat'} Ucmems_unbeach = Field.from_netcdf(fname, ('Ucmems_unbeach', 'unBeachU'), dimensionsU, fieldtype='U') dimensionsV = {'lon': 'lon', 'lat': 'lat'} Vcmems_unbeach = Field.from_netcdf(fname, ('Vcmems_unbeach', 'unBeachV'), dimensionsV, fieldtype='V') fieldset.add_field(Ucmems_unbeach) fieldset.add_field(Vcmems_unbeach) UVnemo_unbeach = VectorField('UVnemo_unbeach', fieldset.Unemo_unbeach, fieldset.Vnemo_unbeach) UVcmems_unbeach = VectorField('UVcmems_unbeach', fieldset.Ucmems_unbeach, fieldset.Vcmems_unbeach) UVunbeach = NestedField('UVunbeach', [UVcmems_unbeach, UVnemo_unbeach]) fieldset.add_vector_field(UVunbeach) else: UVunbeach = VectorField('UVunbeach', fieldset.Unemo_unbeach, fieldset.Vnemo_unbeach) fieldset.add_vector_field(UVunbeach)
def Ratio_Test(dfile): Field.from_netcdf(dfile, dimensions={'lon': 'nav_lon', 'lat': 'nav_lat', 'time': 'time_counter', 'data': 'TagDensity'}, filenames=[dfile])