示例#1
0
def test_brownian_example(mode, npart=3000):
    fieldset = brownian_fieldset()

    # Set diffusion constants.
    fieldset.Kh_meridional = 100.
    fieldset.Kh_zonal = 100.

    # Set random seed
    random.seed(123456)

    ptcls_start = 300000.  # Start all particles at same location in middle of grid.
    pset = ParticleSet.from_line(fieldset=fieldset, size=npart, pclass=ptype[mode],
                                 start=(ptcls_start, ptcls_start),
                                 finish=(ptcls_start, ptcls_start))

    endtime = delta(days=1)
    dt = delta(hours=1)
    interval = delta(hours=1)

    k_brownian = pset.Kernel(two_dim_brownian_flat)

    pset.execute(k_brownian, endtime=endtime, dt=dt, interval=interval,
                 output_file=pset.ParticleFile(name="BrownianParticle"),
                 show_movie=False)

    lats = np.array([particle.lat for particle in pset.particles])
    lons = np.array([particle.lon for particle in pset.particles])
    expected_std_lat = np.sqrt(2*fieldset.Kh_meridional*endtime.total_seconds())
    expected_std_lon = np.sqrt(2*fieldset.Kh_zonal*endtime.total_seconds())

    assert np.allclose(np.std(lats), expected_std_lat, rtol=.1)
    assert np.allclose(np.std(lons), expected_std_lon, rtol=.1)
    assert np.allclose(np.mean(lons), ptcls_start, rtol=.1)
    assert np.allclose(np.mean(lats), ptcls_start, rtol=.1)
示例#2
0
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
    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(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)
示例#3
0
def test_recursive_errorhandling(mode, xdim=2, ydim=2):
    """Example script to show how recursaive error handling can work.

    In this example, a set of Particles is started at Longitude 0.5.
    These are run through a Kernel that throws an error if the
    Longitude is smaller than 0.7.
    The error Kernel then draws a new random number between 0 and 1

    Importantly, the 'normal' Kernel and Error Kernel keep iterating
    until a particle does have a longitude larger than 0.7.

    This behaviour can be useful if particles need to be 'pushed out'
    from e.g. land. Note however that current under-the-hood
    implementation is not extremely efficient, so code could be slow."""

    dimensions = {
        'lon': np.linspace(0., 1., xdim, dtype=np.float32),
        'lat': np.linspace(0., 1., ydim, dtype=np.float32)
    }
    data = {
        'U': np.zeros((ydim, xdim), dtype=np.float32),
        'V': np.zeros((ydim, xdim), dtype=np.float32)
    }
    fieldset = FieldSet.from_data(data, dimensions, mesh='flat')

    # Set minimum value for valid longitudes (i.e. all longitudes < minlon are 'land')
    fieldset.add_constant('minlon', 0.7)

    # create a ParticleSet with all particles starting at centre of Field
    pset = ParticleSet.from_line(fieldset=fieldset,
                                 pclass=ptype[mode],
                                 start=(0.5, 0.5),
                                 finish=(0.5, 0.5),
                                 size=10)

    def TestLon(particle, fieldset, time):
        """Kernel to check whether a longitude is larger than fieldset.minlon.
        If not, the Kernel throws an error"""
        if particle.lon <= fieldset.minlon:
            return ErrorCode.Error

    def Error_RandomiseLon(particle, fieldset, time):
        """Error handling kernel that draws a new longitude.
        Note that this new longitude can be smaller than fieldset.minlon"""
        particle.lon = random.uniform(0., 1.)

    random.seed(123456)

    # The .execute below is only run for one timestep. Yet the
    # recovery={ErrorCode.Error: Error_RandomiseLon} assures Parcels keeps
    # attempting to move all particles beyond 0.7 longitude
    pset.execute(pset.Kernel(TestLon),
                 runtime=1,
                 dt=1,
                 recovery={ErrorCode.Error: Error_RandomiseLon})

    assert (np.array([p.lon for p in pset]) > fieldset.minlon).all()
示例#4
0
def two_dim_brownian_flat(particle, grid, time, dt):
    # Kernel for simple Brownian particle diffusion in zonal and meridional direction.
    # Seed is called on first call only, when time is zero

    if time == 0:
        random.seed(grid.seedval)

    particle.lat += random.normalvariate(0, 1) * math.sqrt(
        2 * dt * grid.Kh_meridional)
    particle.lon += random.normalvariate(0, 1) * math.sqrt(
        2 * dt * grid.Kh_zonal)
示例#5
0
def run_brownian(fieldset, npart, outfilename):

    # Set diffusion constants.
    fieldset.Kh_meridional = 100.
    fieldset.Kh_zonal = 100.

    # Set random seed
    random.seed(123456)

    pset = ParticleSet.from_line(fieldset=fieldset, size=npart, pclass=JITParticle,
                                 start=(0., 0.), finish=(0., 0.))

    pset.execute(two_dim_brownian_flat, runtime=delta(days=1), dt=delta(minutes=5))
    pset.ParticleFile(name=outfilename).write(pset, pset[0].time)
示例#6
0
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)
示例#7
0
fieldset = FieldSet.from_nemo(filenames, variables, dimensions,
                              indices)  #, transpose=True)
fieldset.add_constant('maxage', 40. * 86400)
fieldset.temp.interp_method = 'nearest'

# Create field of Kh_zonal and Kh_meridional, using same grid as U
#[time, depth, particle.lon, particle.lat] # Think this order is correct for here
size4D = (30, 30, fieldset.U.grid.ydim, fieldset.U.grid.xdim)
fieldset.add_field(
    Field('Kh_zonal', Kh_zonal * np.ones(size4D), grid=fieldset.temp.grid))
fieldset.add_field(
    Field('Kh_meridional',
          Kh_meridional * np.ones(size4D),
          grid=fieldset.temp.grid))

random.seed(123456)  # Set random seed


class SampleParticle(JITParticle):  # Define a new particle class
    age = Variable('age', dtype=np.float32, initial=0.)  # initialise age
    temp = Variable('temp', dtype=np.float32,
                    initial=fieldset.temp)  # initialise temperature
    bathy = Variable('bathy', dtype=np.float32,
                     initial=fieldset.bathy)  # initialise bathy
    distance = Variable('distance', initial=0.,
                        dtype=np.float32)  # the distance travelled
    prev_lon = Variable('prev_lon',
                        dtype=np.float32,
                        to_write=False,
                        initial=attrgetter('lon'))  # the previous longitude
    prev_lat = Variable('prev_lat',