def test_randomvonmises(mode, mu, kappa, npart=10000): fieldset = zeros_fieldset() # Parameters for random.vonmisesvariate fieldset.mu = mu fieldset.kappa = kappa # Set random seed random.seed(1234) class AngleParticle(ptype[mode]): angle = Variable('angle') pset = ParticleSet(fieldset=fieldset, pclass=AngleParticle, lon=np.zeros(npart), lat=np.zeros(npart), depth=np.zeros(npart)) def vonmises(particle, fieldset, time): particle.angle = random.vonmisesvariate(fieldset.mu, fieldset.kappa) pset.execute(vonmises, runtime=1, dt=1) angles = np.array([p.angle for p in pset]) assert np.allclose(np.mean(angles), mu, atol=.1) scipy_mises = stats.vonmises.rvs(kappa, loc=mu, size=10000) assert np.allclose(np.mean(angles), np.mean(scipy_mises), atol=.1) assert np.allclose(np.std(angles), np.std(scipy_mises), atol=.1)
def test_fieldKh_Brownian(mesh, mode, xdim=200, ydim=100, kh_zonal=100, kh_meridional=50): mesh_conversion = 1/1852./60 if mesh is '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 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 == '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)) 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 test_OFAM(mode, chunk_mode): # here, coordinates for lon are 0 < lon < 360 if chunk_mode == 'auto': dask.config.set({'array.chunk-size': '4MiB'}) else: dask.config.set({'array.chunk-size': '128MiB'}) random.seed(0) field_set = fieldset_from_OFAM(chunk_mode) npart = 4096 lonp = [i for i in -20.0 - 5.0 + np.random.rand(npart) * 2.0 * 5.0 ] # -20.0 * np.ones(npart) latp = [i for i in -75.0 + np.random.rand(npart) * 2.0 * 75.0] compute_OFAM_particle_advection(field_set, mode, lonp, latp) # MITgcm sample file dimensions: y=1500, x=3600, w=51 assert (len(field_set.U.grid.load_chunk) == len( field_set.V.grid.load_chunk)) assert (len(field_set.U.grid.load_chunk) == len( field_set.W.grid.load_chunk)) if chunk_mode is False: assert (len(field_set.U.grid.load_chunk) == 1) elif chunk_mode == 'auto': assert (len(field_set.U.grid.load_chunk) != 1) elif chunk_mode == 'specific': numblocks = [i for i in field_set.U.grid.chunk_info[1:4]] dblocks = 0 for bsize in field_set.U.grid.chunk_info[4:4 + numblocks[0]]: dblocks += bsize vblocks = 0 for bsize in field_set.U.grid.chunk_info[4 + numblocks[0]:4 + numblocks[0] + numblocks[1]]: vblocks += bsize ublocks = 0 for bsize in field_set.U.grid.chunk_info[4 + numblocks[0] + numblocks[1]:4 + numblocks[0] + numblocks[1] + numblocks[2]]: ublocks += bsize matching_numblocks = (ublocks == 3600 and vblocks == 1500 and dblocks == 51) matching_fields = (field_set.U.grid.chunk_info == field_set.V.grid.chunk_info == field_set.W.grid.chunk_info) matching_uniformblocks = (len( field_set.U.grid.load_chunk) == (int(math.ceil(51.0 / 8.0)) * int(math.ceil(1500.0 / 96.0)) * int(math.ceil(3600.0 / 128.0)))) assert (matching_uniformblocks or (matching_fields and matching_numblocks)) return True
def test_randomexponential(mode, lambd, npart=1000): fieldset = zeros_fieldset() # Rate parameter for random.expovariate fieldset.lambd = lambd # Set random seed random.seed(1234) pset = ParticleSet(fieldset=fieldset, pclass=ptype[mode], lon=np.zeros(npart), lat=np.zeros(npart), depth=np.zeros(npart)) def vertical_randomexponential(particle, fieldset, time): # Kernel for random exponential variable in depth direction particle.depth = random.expovariate(fieldset.lambd) pset.execute(vertical_randomexponential, runtime=1, dt=1) depth = np.array([particle.depth for particle in pset.particles]) expected_mean = 1./fieldset.lambd assert np.allclose(np.mean(depth), expected_mean, rtol=.1)
age=age_par, weights=weights, time=starttime, repeatdt=repeatStep) elif scenario == 3: pset = ParticleSet(fieldset=fieldset, pclass=shoreTypeBeachingResuspensionParticle, lon=lons, lat=lats, beach=beached, age=age_par, weights=weights, time=starttime, repeatdt=repeatStep) random.seed(int(time.time()) * 100000) #%% os.system('echo "Loading the relevant kernels"') ############################################################################### # The delete particle Kernel # ############################################################################### def DeleteParticle(particle, fieldset, time): particle.delete() ############################################################################### # The beaching kernel # ###############################################################################