コード例 #1
0
ファイル: test_grid.py プロジェクト: dham/parcels
def test_moving_eddies_file_subsettime(
        indstime, gridfile='examples/MovingEddies_data/moving_eddies'):
    gridfull = Grid.from_nemo(gridfile, extra_vars={'P': 'P'})
    gridsub = Grid.from_nemo(gridfile,
                             extra_vars={'P': 'P'},
                             indices={'time': indstime})
    assert np.allclose(gridsub.P.time, gridfull.P.time[indstime])
    assert np.allclose(gridsub.P.data, gridfull.P.data[indstime, :, :])
コード例 #2
0
ファイル: test_grid.py プロジェクト: dham/parcels
def test_grid_from_nemo(xdim, ydim, tmpdir, filename='test_nemo'):
    """ Simple test for grid initialisation from NEMO file format. """
    filepath = tmpdir.join(filename)
    u, v, lon, lat, depth, time = generate_grid(xdim, ydim)
    grid_out = Grid.from_data(u, lon, lat, v, lon, lat, depth, time)
    grid_out.write(filepath)
    grid = Grid.from_nemo(filepath)
    u_t = np.transpose(u).reshape((lat.size, lon.size))
    v_t = np.transpose(v).reshape((lat.size, lon.size))
    assert len(grid.U.data.shape) == 3  # Will be 4 once we use depth
    assert len(grid.V.data.shape) == 3
    assert np.allclose(grid.U.data[0, :], u_t, rtol=1e-12)
    assert np.allclose(grid.V.data[0, :], v_t, rtol=1e-12)
コード例 #3
0
def test_grid_from_nemo(xdim, ydim, tmpdir, filename='test_nemo'):
    """ Simple test for grid initialisation from NEMO file format. """
    filepath = tmpdir.join(filename)
    u, v, lon, lat, depth, time = generate_grid(xdim, ydim)
    grid_out = Grid.from_data(u, lon, lat, v, lon, lat, depth, time)
    grid_out.write(filepath)
    grid = Grid.from_nemo(filepath)
    u_t = np.transpose(u).reshape((lat.size, lon.size))
    v_t = np.transpose(v).reshape((lat.size, lon.size))
    assert len(grid.U.data.shape) == 3  # Will be 4 once we use depth
    assert len(grid.V.data.shape) == 3
    assert np.allclose(grid.U.data[0, :], u_t, rtol=1e-12)
    assert np.allclose(grid.V.data[0, :], v_t, rtol=1e-12)
コード例 #4
0
ファイル: test_grid_sampling.py プロジェクト: dham/parcels
def test_nearest_neighbour_interpolation(mode, k_sample_p, npart=81):
    dims = (2, 2)
    lon = np.linspace(0., 1., dims[0], dtype=np.float32)
    lat = np.linspace(0., 1., dims[1], dtype=np.float32)
    U = np.zeros(dims, dtype=np.float32)
    V = np.zeros(dims, dtype=np.float32)
    P = np.zeros(dims, dtype=np.float32)
    P[0, 0] = 1.
    grid = Grid.from_data(U,
                          lon,
                          lat,
                          V,
                          lon,
                          lat,
                          mesh='flat',
                          field_data={'P': np.asarray(P, dtype=np.float32)})
    grid.P.interp_method = 'nearest'
    xv, yv = np.meshgrid(np.linspace(0.1, 0.9, np.sqrt(npart)),
                         np.linspace(0.1, 0.9, np.sqrt(npart)))
    pset = ParticleSet(grid,
                       pclass=pclass(mode),
                       lon=xv.flatten(),
                       lat=yv.flatten())
    pset.execute(k_sample_p, endtime=1, dt=1)
    assert np.allclose(np.array(
        [p.p for p in pset if p.lon < 0.5 and p.lat < 0.5]),
                       1.0,
                       rtol=1e-5)
    assert np.allclose(np.array(
        [p.p for p in pset if p.lon > 0.5 or p.lat > 0.5]),
                       0.0,
                       rtol=1e-5)
コード例 #5
0
def radial_rotation_grid(
        xdim=200,
        ydim=200):  # Define 2D flat, square grid for testing purposes.

    lon = np.linspace(0, 60, xdim, dtype=np.float32)
    lat = np.linspace(0, 60, ydim, dtype=np.float32)

    x0 = 30.  # Define the origin to be the centre of the grid.
    y0 = 30.

    U = np.zeros((xdim, ydim), dtype=np.float32)
    V = np.zeros((xdim, ydim), dtype=np.float32)

    T = delta(days=1)
    omega = 2 * np.pi / T.total_seconds(
    )  # Define the rotational period as 1 day.

    for i in range(lon.size):
        for j in range(lat.size):

            r = np.sqrt((lon[i] - x0)**2 +
                        (lat[j] - y0)**2)  # Define radial displacement.
            assert (r >= 0.)
            assert (r <= np.sqrt(x0**2 + y0**2))

            theta = math.atan2((lat[j] - y0),
                               (lon[i] - x0))  # Define the polar angle.
            assert (abs(theta) <= np.pi)

            U[i, j] = r * math.sin(theta) * omega
            V[i, j] = -r * math.cos(theta) * omega

    return Grid.from_data(U, lon, lat, V, lon, lat, mesh='flat')
コード例 #6
0
def radial_rotation_grid(xdim=200, ydim=200):  # Define 2D flat, square grid for testing purposes.

    lon = np.linspace(0, 60, xdim, dtype=np.float32)
    lat = np.linspace(0, 60, ydim, dtype=np.float32)

    x0 = 30.                                   # Define the origin to be the centre of the grid.
    y0 = 30.

    U = np.zeros((xdim, ydim), dtype=np.float32)
    V = np.zeros((xdim, ydim), dtype=np.float32)

    T = delta(days=1)
    omega = 2*np.pi/T.total_seconds()          # Define the rotational period as 1 day.

    for i in range(lon.size):
        for j in range(lat.size):

            r = np.sqrt((lon[i]-x0)**2 + (lat[j]-y0)**2)  # Define radial displacement.
            assert(r >= 0.)
            assert(r <= np.sqrt(x0**2 + y0**2))

            theta = math.atan2((lat[j]-y0), (lon[i]-x0))  # Define the polar angle.
            assert(abs(theta) <= np.pi)

            U[i, j] = r * math.sin(theta) * omega
            V[i, j] = -r * math.cos(theta) * omega

    return Grid.from_data(U, lon, lat, V, lon, lat, mesh='flat')
コード例 #7
0
ファイル: test_grid_sampling.py プロジェクト: dham/parcels
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())
コード例 #8
0
ファイル: example_ofam.py プロジェクト: OceanPARCELS/parcels
def set_ofam_grid():
    filenames = {'U': "examples/OFAM_example_data/OFAM_simple_U.nc",
                 'V': "examples/OFAM_example_data/OFAM_simple_V.nc"}
    variables = {'U': 'u', 'V': 'v'}
    dimensions = {'lat': 'yu_ocean', 'lon': 'xu_ocean', 'depth': 'st_ocean',
                  'time': 'Time'}
    return Grid.from_netcdf(filenames, variables, dimensions)
コード例 #9
0
def test_delay_start_example(mode, npart=10, show_movie=False):
    """Example script that shows how to 'delay' the start of particle advection.
    This is useful for example when particles need to be started at different times

    In this example, we use pset.add statements to add one particle every hour
    in the peninsula grid. Note that the title in the movie may not show correct time"""

    grid = Grid.from_nemo('examples/Peninsula_data/peninsula', extra_vars={'P': 'P'})

    # Initialise particles as in the Peninsula example
    x = 3. * (1. / 1.852 / 60)  # 3 km offset from boundary
    y = (grid.U.lat[0] + x, grid.U.lat[-1] - x)  # latitude range, including offsets

    lat = np.linspace(y[0], y[1], npart, dtype=np.float32)
    pset = grid.ParticleSet(0, lon=[], lat=[], pclass=ptype[mode])

    delaytime = delta(hours=1)  # delay time between particle releases
    for t in range(npart):
        pset.add(ptype[mode](lon=x, lat=lat[t], grid=grid))
        pset.execute(AdvectionRK4, runtime=delaytime, dt=delta(minutes=5),
                     interval=delta(hours=1), show_movie=show_movie)

    # Note that time on the movie is not parsed correctly
    pset.execute(AdvectionRK4, runtime=delta(hours=24)-npart*delaytime,
                 dt=delta(minutes=5), interval=delta(hours=1), show_movie=show_movie)

    londist = np.array([(p.lon - x) for p in pset])
    assert(londist > 0.1).all()
コード例 #10
0
ファイル: example_stommel.py プロジェクト: dham/parcels
def stommel_grid(xdim=200, ydim=200):
    """Simulate a periodic current along a western boundary, with significantly
    larger velocities along the western edge than the rest of the region

    The original test description can be found in: N. Fabbroni, 2009,
    Numerical Simulation of Passive tracers dispersion in the sea,
    Ph.D. dissertation, University of Bologna
    http://amsdottorato.unibo.it/1733/1/Fabbroni_Nicoletta_Tesi.pdf
    """
    # Set NEMO grid variables
    depth = np.zeros(1, dtype=np.float32)
    time = np.linspace(0., 100000. * 86400., 2, dtype=np.float64)

    # Some constants
    A = 100
    eps = 0.05
    a = 10000
    b = 10000

    # Coordinates of the test grid (on A-grid in deg)
    lon = np.linspace(0, a, xdim, dtype=np.float32)
    lat = np.linspace(0, b, ydim, dtype=np.float32)

    # Define arrays U (zonal), V (meridional), W (vertical) and P (sea
    # surface height) all on A-grid
    U = np.zeros((lon.size, lat.size, time.size), dtype=np.float32)
    V = np.zeros((lon.size, lat.size, time.size), dtype=np.float32)
    P = np.zeros((lon.size, lat.size, time.size), dtype=np.float32)

    [x, y] = np.mgrid[:lon.size, :lat.size]
    l1 = (-1 + math.sqrt(1 + 4 * math.pi**2 * eps**2)) / (2 * eps)
    l2 = (-1 - math.sqrt(1 + 4 * math.pi**2 * eps**2)) / (2 * eps)
    c1 = (1 - math.exp(l2)) / (math.exp(l2) - math.exp(l1))
    c2 = -(1 + c1)
    for t in range(time.size):
        for i in range(lon.size):
            for j in range(lat.size):
                xi = lon[i] / a
                yi = lat[j] / b
                P[i, j,
                  t] = A * (c1 * math.exp(l1 * xi) + c2 * math.exp(l2 * xi) +
                            1) * math.sin(math.pi * yi)
        for i in range(lon.size - 2):
            for j in range(lat.size):
                V[i + 1, j, t] = (P[i + 2, j, t] - P[i, j, t]) / (2 * a / xdim)
        for i in range(lon.size):
            for j in range(lat.size - 2):
                U[i, j + 1,
                  t] = -(P[i, j + 2, t] - P[i, j, t]) / (2 * b / ydim)

    return Grid.from_data(U,
                          lon,
                          lat,
                          V,
                          lon,
                          lat,
                          depth,
                          time,
                          field_data={'P': P},
                          mesh='flat')
コード例 #11
0
def test_meridionalflow_sperical(mode, xdim=100, ydim=200):
    """ Create uniform NORTHWARD flow on sperical earth and advect particles

    As flow is so simple, it can be directly compared to analytical solution
    """

    maxvel = 1.
    lon = np.linspace(-180, 180, xdim, dtype=np.float32)
    lat = np.linspace(-90, 90, ydim, dtype=np.float32)
    U = np.zeros([xdim, ydim])
    V = maxvel * np.ones([xdim, ydim])

    grid = Grid.from_data(np.array(U, dtype=np.float32), lon, lat,
                          np.array(V, dtype=np.float32), lon, lat)

    lonstart = [0, 45]
    latstart = [0, 45]
    endtime = delta(hours=24)
    pset = grid.ParticleSet(2, pclass=pclass(mode), lon=lonstart, lat=latstart)
    pset.execute(pset.Kernel(AdvectionRK4), endtime=endtime, dt=delta(hours=1))

    assert(pset[0].lat - (latstart[0] + endtime.total_seconds() * maxvel / 1852 / 60) < 1e-4)
    assert(pset[0].lon - lonstart[0] < 1e-4)
    assert(pset[1].lat - (latstart[1] + endtime.total_seconds() * maxvel / 1852 / 60) < 1e-4)
    assert(pset[1].lon - lonstart[1] < 1e-4)
コード例 #12
0
def test_zonalflow_sperical(mode, k_sample_p, xdim=100, ydim=200):
    """ Create uniform EASTWARD flow on sperical earth and advect particles

    As flow is so simple, it can be directly compared to analytical solution
    Note that in this case the cosine conversion is needed
    """
    maxvel = 1.
    p_fld = 10
    lon = np.linspace(-180, 180, xdim, dtype=np.float32)
    lat = np.linspace(-90, 90, ydim, dtype=np.float32)
    V = np.zeros([xdim, ydim])
    U = maxvel * np.ones([xdim, ydim])
    P = p_fld * np.ones([xdim, ydim])

    grid = Grid.from_data(np.array(U, dtype=np.float32), lon, lat,
                          np.array(V, dtype=np.float32), lon, lat,
                          field_data={'P': np.array(P, dtype=np.float32)})

    lonstart = [0, 45]
    latstart = [0, 45]
    endtime = delta(hours=24)
    pset = grid.ParticleSet(2, pclass=pclass(mode), lon=lonstart, lat=latstart)
    pset.execute(pset.Kernel(AdvectionRK4) + k_sample_p,
                 endtime=endtime, dt=delta(hours=1))

    assert(pset[0].lat - latstart[0] < 1e-4)
    assert(pset[0].lon - (lonstart[0] + endtime.total_seconds() * maxvel / 1852 / 60
                          / cos(latstart[0] * pi / 180)) < 1e-4)
    assert(abs(pset[0].p - p_fld) < 1e-4)
    assert(pset[1].lat - latstart[1] < 1e-4)
    assert(pset[1].lon - (lonstart[1] + endtime.total_seconds() * maxvel / 1852 / 60
                          / cos(latstart[1] * pi / 180)) < 1e-4)
    assert(abs(pset[1].p - p_fld) < 1e-4)
コード例 #13
0
def test_zonalflow_sperical(mode, k_sample_p, xdim=100, ydim=200):
    """ Create uniform EASTWARD flow on sperical earth and advect particles

    As flow is so simple, it can be directly compared to analytical solution
    Note that in this case the cosine conversion is needed
    """
    maxvel = 1.
    p_fld = 10
    lon = np.linspace(-180, 180, xdim, dtype=np.float32)
    lat = np.linspace(-90, 90, ydim, dtype=np.float32)
    V = np.zeros([xdim, ydim])
    U = maxvel * np.ones([xdim, ydim])
    P = p_fld * np.ones([xdim, ydim])

    grid = Grid.from_data(np.array(U, dtype=np.float32), lon, lat,
                          np.array(V, dtype=np.float32), lon, lat,
                          field_data={'P': np.array(P, dtype=np.float32)})

    lonstart = [0, 45]
    latstart = [0, 45]
    endtime = delta(hours=24)
    pset = grid.ParticleSet(2, pclass=pclass(mode), lon=lonstart, lat=latstart)
    pset.execute(pset.Kernel(AdvectionRK4) + k_sample_p,
                 endtime=endtime, dt=delta(hours=1))

    assert(pset[0].lat - latstart[0] < 1e-4)
    assert(pset[0].lon - (lonstart[0] + endtime.total_seconds() * maxvel / 1852 / 60
                          / cos(latstart[0] * pi / 180)) < 1e-4)
    assert(abs(pset[0].p - p_fld) < 1e-4)
    assert(pset[1].lat - latstart[1] < 1e-4)
    assert(pset[1].lon - (lonstart[1] + endtime.total_seconds() * maxvel / 1852 / 60
                          / cos(latstart[1] * pi / 180)) < 1e-4)
    assert(abs(pset[1].p - p_fld) < 1e-4)
コード例 #14
0
def test_meridionalflow_sperical(mode, xdim=100, ydim=200):
    """ Create uniform NORTHWARD flow on sperical earth and advect particles

    As flow is so simple, it can be directly compared to analytical solution
    """

    maxvel = 1.
    lon = np.linspace(-180, 180, xdim, dtype=np.float32)
    lat = np.linspace(-90, 90, ydim, dtype=np.float32)
    U = np.zeros([xdim, ydim])
    V = maxvel * np.ones([xdim, ydim])

    grid = Grid.from_data(np.array(U, dtype=np.float32), lon, lat,
                          np.array(V, dtype=np.float32), lon, lat)

    lonstart = [0, 45]
    latstart = [0, 45]
    endtime = delta(hours=24)
    pset = grid.ParticleSet(2, pclass=pclass(mode), lon=lonstart, lat=latstart)
    pset.execute(pset.Kernel(AdvectionRK4), endtime=endtime, dt=delta(hours=1))

    assert(pset[0].lat - (latstart[0] + endtime.total_seconds() * maxvel / 1852 / 60) < 1e-4)
    assert(pset[0].lon - lonstart[0] < 1e-4)
    assert(pset[1].lat - (latstart[1] + endtime.total_seconds() * maxvel / 1852 / 60) < 1e-4)
    assert(pset[1].lon - lonstart[1] < 1e-4)
コード例 #15
0
def set_globcurrent_grid():
    filenames = {'U': "examples/GlobCurrent_example_data/20*-GLOBCURRENT-L4-CUReul_hs-ALT_SUM-v02.0-fv01.0.nc",
                 'V': "examples/GlobCurrent_example_data/20*-GLOBCURRENT-L4-CUReul_hs-ALT_SUM-v02.0-fv01.0.nc"}
    variables = {'U': 'eastward_eulerian_current_velocity', 'V': 'northward_eulerian_current_velocity'}
    dimensions = {'lat': 'lat', 'lon': 'lon',
                  'time': 'time'}
    return Grid.from_netcdf(filenames, variables, dimensions)
コード例 #16
0
def moving_eddies_grid(xdim=200, ydim=350):
    """Generate a grid encapsulating the flow field consisting of two
    moving eddies, one moving westward and the other moving northwestward.

    Note that this is not a proper geophysical flow. Rather, a Gaussian eddy
    is moved artificially with uniform velocities. Velocities are calculated
    from geostrophy.
    """
    # Set NEMO grid variables
    depth = np.zeros(1, dtype=np.float32)
    time = np.arange(0.0, 25.0 * 86400.0, 86400.0, dtype=np.float64)

    # Coordinates of the test grid (on A-grid in deg)
    lon = np.linspace(0, 4, xdim, dtype=np.float32)
    lat = np.linspace(45, 52, ydim, dtype=np.float32)

    # Grid spacing in m
    def cosd(x):
        return math.cos(math.radians(float(x)))

    dx = (lon[1] - lon[0]) * 1852 * 60 * cosd(lat.mean())
    dy = (lat[1] - lat[0]) * 1852 * 60

    # Define arrays U (zonal), V (meridional), W (vertical) and P (sea
    # surface height) all on A-grid
    U = np.zeros((lon.size, lat.size, time.size), dtype=np.float32)
    V = np.zeros((lon.size, lat.size, time.size), dtype=np.float32)
    P = np.zeros((lon.size, lat.size, time.size), dtype=np.float32)

    # Some constants
    corio_0 = 1.0e-4  # Coriolis parameter
    h0 = 1  # Max eddy height
    sig = 0.5  # Eddy e-folding decay scale (in degrees)
    g = 10  # Gravitational constant
    eddyspeed = 0.1  # Translational speed in m/s
    dX = eddyspeed * 86400 / dx  # Grid cell movement of eddy max each day
    dY = eddyspeed * 86400 / dy  # Grid cell movement of eddy max each day

    [x, y] = np.mgrid[: lon.size, : lat.size]
    for t in range(time.size):
        hymax_1 = lat.size / 7.0
        hxmax_1 = 0.75 * lon.size - dX * t
        hymax_2 = 3.0 * lat.size / 7.0 + dY * t
        hxmax_2 = 0.75 * lon.size - dX * t

        P[:, :, t] = h0 * np.exp(
            -(x - hxmax_1) ** 2 / (sig * lon.size / 4.0) ** 2 - (y - hymax_1) ** 2 / (sig * lat.size / 7.0) ** 2
        )
        P[:, :, t] += h0 * np.exp(
            -(x - hxmax_2) ** 2 / (sig * lon.size / 4.0) ** 2 - (y - hymax_2) ** 2 / (sig * lat.size / 7.0) ** 2
        )

        V[:-1, :, t] = -np.diff(P[:, :, t], axis=0) / dx / corio_0 * g
        V[-1, :, t] = V[-2, :, t]  # Fill in the last column

        U[:, :-1, t] = np.diff(P[:, :, t], axis=1) / dy / corio_0 * g
        U[:, -1, t] = U[:, -2, t]  # Fill in the last row

    return Grid.from_data(U, lon, lat, V, lon, lat, depth, time, field_data={"P": P})
コード例 #17
0
ファイル: test_grid.py プロジェクト: OceanPARCELS/parcels
def test_add_field(xdim, ydim, tmpdir, filename="test_add"):
    filepath = tmpdir.join(filename)
    u, v, lon, lat, depth, time = generate_grid(xdim, ydim)
    grid = Grid.from_data(u, lon, lat, v, lon, lat, depth, time)
    field = Field("newfld", grid.U.data, grid.U.lon, grid.U.lat)
    grid.add_field(field)
    assert grid.newfld.data.shape == grid.U.data.shape
    grid.write(filepath)
コード例 #18
0
ファイル: test_grid.py プロジェクト: dham/parcels
def test_add_field(xdim, ydim, tmpdir, filename='test_add'):
    filepath = tmpdir.join(filename)
    u, v, lon, lat, depth, time = generate_grid(xdim, ydim)
    grid = Grid.from_data(u, lon, lat, v, lon, lat, depth, time)
    field = Field('newfld', grid.U.data, grid.U.lon, grid.U.lat)
    grid.add_field(field)
    assert grid.newfld.data.shape == grid.U.data.shape
    grid.write(filepath)
コード例 #19
0
def grid(xdim=100, ydim=100):
    U = np.zeros((xdim, ydim), dtype=np.float32)
    V = np.zeros((xdim, ydim), dtype=np.float32)
    lon = np.linspace(0, 1, xdim, dtype=np.float32)
    lat = np.linspace(0, 1, ydim, dtype=np.float32)
    depth = np.zeros(1, dtype=np.float32)
    time = np.zeros(1, dtype=np.float64)
    return Grid.from_data(U, lon, lat, V, lon, lat, depth, time)
コード例 #20
0
def grid(xdim=100, ydim=100):
    U = np.zeros((xdim, ydim), dtype=np.float32)
    V = np.zeros((xdim, ydim), dtype=np.float32)
    lon = np.linspace(0, 1, xdim, dtype=np.float32)
    lat = np.linspace(0, 1, ydim, dtype=np.float32)
    depth = np.zeros(1, dtype=np.float32)
    time = np.zeros(1, dtype=np.float64)
    return Grid.from_data(U, lon, lat, V, lon, lat, depth, time)
コード例 #21
0
def grid(xdim=20, ydim=20):
    """ Standard unit mesh grid """
    lon = np.linspace(0., 1., xdim, dtype=np.float32)
    lat = np.linspace(0., 1., ydim, dtype=np.float32)
    U, V = np.meshgrid(lat, lon)
    return Grid.from_data(np.array(U, dtype=np.float32), lon, lat,
                          np.array(V, dtype=np.float32), lon, lat,
                          mesh='flat')
コード例 #22
0
def brownian_grid(xdim=200,
                  ydim=200):  # Define a flat grid of zeros, for simplicity.
    lon = np.linspace(0, 600000, xdim, dtype=np.float32)
    lat = np.linspace(0, 600000, ydim, dtype=np.float32)

    U = np.zeros((lon.size, lat.size), dtype=np.float32)
    V = np.zeros((lon.size, lat.size), dtype=np.float32)

    return Grid.from_data(U, lon, lat, V, lon, lat, mesh='flat')
コード例 #23
0
def periodicgrid(xdim, ydim, uvel, vvel):
    lon = np.linspace(
        0., 1., xdim + 1,
        dtype=np.float32)[1:]  # don't include both 0 and 1, for periodic b.c.
    lat = np.linspace(0., 1., ydim + 1, dtype=np.float32)[1:]

    U = uvel * np.ones((xdim, ydim), dtype=np.float32)
    V = vvel * np.ones((xdim, ydim), dtype=np.float32)
    return Grid.from_data(U, lon, lat, V, lon, lat, mesh='spherical')
コード例 #24
0
def peninsula_grid(xdim, ydim):
    """Construct a grid encapsulating the flow field around an
    idealised peninsula.

    :param xdim: Horizontal dimension of the generated grid
    :param xdim: Vertical dimension of the generated grid

    The original test description can be found in Fig. 2.2.3 in:
    North, E. W., Gallego, A., Petitgas, P. (Eds). 2009. Manual of
    recommended practices for modelling physical - biological
    interactions during fish early life.
    ICES Cooperative Research Report No. 295. 111 pp.
    http://archimer.ifremer.fr/doc/00157/26792/24888.pdf

    Note that the problem is defined on an A-grid while NEMO
    normally returns C-grids. However, to avoid accuracy
    problems with interpolation from A-grid to C-grid, we
    return NetCDF files that are on an A-grid.
    """
    # Set NEMO grid variables
    depth = np.zeros(1, dtype=np.float32)
    time = np.zeros(1, dtype=np.float64)

    # Generate the original test setup on A-grid in km
    dx = 100. / xdim / 2.
    dy = 50. / ydim / 2.
    La = np.linspace(dx, 100.-dx, xdim, dtype=np.float32)
    Wa = np.linspace(dy, 50.-dy, ydim, dtype=np.float32)

    # Define arrays U (zonal), V (meridional), W (vertical) and P (sea
    # surface height) all on A-grid
    U = np.zeros((xdim, ydim), dtype=np.float32)
    V = np.zeros((xdim, ydim), dtype=np.float32)
    W = np.zeros((xdim, ydim), dtype=np.float32)
    P = np.zeros((xdim, ydim), dtype=np.float32)

    u0 = 1
    x0 = 50.
    R = 0.32 * 50.

    # Create the fields
    x, y = np.meshgrid(La, Wa, sparse=True, indexing='ij')
    P = u0*R**2*y/((x-x0)**2+y**2)-u0*y
    U = u0-u0*R**2*((x-x0)**2-y**2)/(((x-x0)**2+y**2)**2)
    V = -2*u0*R**2*((x-x0)*y)/(((x-x0)**2+y**2)**2)

    # Set land points to NaN
    I = P >= 0.
    U[I] = np.nan
    V[I] = np.nan
    W[I] = np.nan

    # Convert from km to lat/lon
    lon = La / 1.852 / 60.
    lat = Wa / 1.852 / 60.

    return Grid.from_data(U, lon, lat, V, lon, lat, depth, time, field_data={'P': P})
コード例 #25
0
def test_peninsula_file(gridfile, mode):
    """Open grid files and execute"""
    grid = Grid.from_nemo(gridfile, extra_vars={'P': 'P'})
    pset = pensinsula_example(grid, 100, mode=mode, degree=1)
    # Test advection accuracy by comparing streamline values
    err_adv = np.array([abs(p.p_start - p.p) for p in pset])
    assert(err_adv <= 1.e-3).all()
    # Test grid sampling accuracy by comparing kernel against grid sampling
    err_smpl = np.array([abs(p.p - pset.grid.P[0., p.lon, p.lat]) for p in pset])
    assert(err_smpl <= 1.e-3).all()
コード例 #26
0
ファイル: test_grid.py プロジェクト: dham/parcels
def test_grid_from_data(xdim, ydim):
    """ Simple test for grid initialisation from data. """
    u, v, lon, lat, depth, time = generate_grid(xdim, ydim)
    grid = Grid.from_data(u, lon, lat, v, lon, lat, depth, time)
    u_t = np.transpose(u).reshape((lat.size, lon.size))
    v_t = np.transpose(v).reshape((lat.size, lon.size))
    assert len(grid.U.data.shape) == 3  # Will be 4 once we use depth
    assert len(grid.V.data.shape) == 3
    assert np.allclose(grid.U.data[0, :], u_t, rtol=1e-12)
    assert np.allclose(grid.V.data[0, :], v_t, rtol=1e-12)
コード例 #27
0
def grid(xdim=200, ydim=100):
    """ Standard grid spanning the earth's coordinates with U and V
        equivalent to longitude and latitude in deg.
    """
    lon = np.linspace(-180, 180, xdim, dtype=np.float32)
    lat = np.linspace(-90, 90, ydim, dtype=np.float32)
    U, V = np.meshgrid(lat, lon)
    return Grid.from_data(np.array(U, dtype=np.float32), lon, lat,
                          np.array(V, dtype=np.float32), lon, lat,
                          mesh='flat')
コード例 #28
0
def test_grid_from_data(xdim, ydim):
    """ Simple test for grid initialisation from data. """
    u, v, lon, lat, depth, time = generate_grid(xdim, ydim)
    grid = Grid.from_data(u, lon, lat, v, lon, lat, depth, time)
    u_t = np.transpose(u).reshape((lat.size, lon.size))
    v_t = np.transpose(v).reshape((lat.size, lon.size))
    assert len(grid.U.data.shape) == 3  # Will be 4 once we use depth
    assert len(grid.V.data.shape) == 3
    assert np.allclose(grid.U.data[0, :], u_t, rtol=1e-12)
    assert np.allclose(grid.V.data[0, :], v_t, rtol=1e-12)
コード例 #29
0
ファイル: test_grid.py プロジェクト: dham/parcels
def test_grid_from_file_subsets(indslon,
                                indslat,
                                tmpdir,
                                filename='test_subsets'):
    """ Test for subsetting grid from file using indices dict. """
    u, v, lon, lat, depth, time = generate_grid(100, 100)
    filepath = tmpdir.join(filename)
    gridfull = Grid.from_data(u, lon, lat, v, lon, lat, depth, time)
    gridfull.write(filepath)
    indices = {'lon': indslon, 'lat': indslat}
    gridsub = Grid.from_nemo(filepath, indices=indices)
    assert np.allclose(gridsub.U.lon, gridfull.U.lon[indices['lon']])
    assert np.allclose(gridsub.U.lat, gridfull.U.lat[indices['lat']])
    assert np.allclose(gridsub.V.lon, gridfull.V.lon[indices['lon']])
    assert np.allclose(gridsub.V.lat, gridfull.V.lat[indices['lat']])

    ixgrid = np.ix_([0], indices['lat'], indices['lon'])
    assert np.allclose(gridsub.U.data, gridfull.U.data[ixgrid])
    assert np.allclose(gridsub.V.data, gridfull.V.data[ixgrid])
コード例 #30
0
def grid(xdim=200, ydim=100):
    """ Standard grid spanning the earth's coordinates with U and V
        equivalent to longitude and latitude in deg.
    """
    lon = np.linspace(-180, 180, xdim, dtype=np.float32)
    lat = np.linspace(-90, 90, ydim, dtype=np.float32)
    U, V = np.meshgrid(lat, lon)
    return Grid.from_data(np.array(U, dtype=np.float32), lon, lat,
                          np.array(V, dtype=np.float32), lon, lat,
                          mesh='flat')
コード例 #31
0
def grid_geometric(xdim=200, ydim=100):
    """ Standard earth grid with U and V equivalent to lon/lat in m. """
    lon = np.linspace(-180, 180, xdim, dtype=np.float32)
    lat = np.linspace(-90, 90, ydim, dtype=np.float32)
    U, V = np.meshgrid(lat, lon)
    U *= 1000. * 1.852 * 60.
    V *= 1000. * 1.852 * 60.
    grid = Grid.from_data(np.array(U, dtype=np.float32), lon, lat,
                          np.array(V, dtype=np.float32), lon, lat)
    grid.U.units = Geographic()
    grid.V.units = Geographic()
    return grid
コード例 #32
0
def grid_stationary(xdim=100, ydim=100, maxtime=delta(hours=6)):
    """Generate a grid encapsulating the flow field of a stationary eddy.

    Reference: N. Fabbroni, 2009, "Numerical simulations of passive
    tracers dispersion in the sea"
    """
    lon = np.linspace(0, 25000, xdim, dtype=np.float32)
    lat = np.linspace(0, 25000, ydim, dtype=np.float32)
    time = np.arange(0., maxtime.total_seconds(), 60., dtype=np.float64)
    U = np.ones((xdim, ydim, 1), dtype=np.float32) * u_0 * np.cos(f * time)
    V = np.ones((xdim, ydim, 1), dtype=np.float32) * -u_0 * np.sin(f * time)
    return Grid.from_data(U, lon, lat, V, lon, lat, time=time, mesh='flat')
コード例 #33
0
def grid_stationary(xdim=100, ydim=100, maxtime=delta(hours=6)):
    """Generate a grid encapsulating the flow field of a stationary eddy.

    Reference: N. Fabbroni, 2009, "Numerical simulations of passive
    tracers dispersion in the sea"
    """
    lon = np.linspace(0, 25000, xdim, dtype=np.float32)
    lat = np.linspace(0, 25000, ydim, dtype=np.float32)
    time = np.arange(0., maxtime.total_seconds(), 60., dtype=np.float64)
    U = np.ones((xdim, ydim, 1), dtype=np.float32) * u_0 * np.cos(f * time)
    V = np.ones((xdim, ydim, 1), dtype=np.float32) * -u_0 * np.sin(f * time)
    return Grid.from_data(U, lon, lat, V, lon, lat, time=time, mesh='flat')
コード例 #34
0
def grid_geometric(xdim=200, ydim=100):
    """ Standard earth grid with U and V equivalent to lon/lat in m. """
    lon = np.linspace(-180, 180, xdim, dtype=np.float32)
    lat = np.linspace(-90, 90, ydim, dtype=np.float32)
    U, V = np.meshgrid(lat, lon)
    U *= 1000. * 1.852 * 60.
    V *= 1000. * 1.852 * 60.
    grid = Grid.from_data(np.array(U, dtype=np.float32), lon, lat,
                          np.array(V, dtype=np.float32), lon, lat)
    grid.U.units = Geographic()
    grid.V.units = Geographic()
    return grid
コード例 #35
0
def grid(xdim=20, ydim=20):
    """ Standard unit mesh grid """
    lon = np.linspace(0., 1., xdim, dtype=np.float32)
    lat = np.linspace(0., 1., ydim, dtype=np.float32)
    U, V = np.meshgrid(lat, lon)
    return Grid.from_data(np.array(U, dtype=np.float32),
                          lon,
                          lat,
                          np.array(V, dtype=np.float32),
                          lon,
                          lat,
                          mesh='flat')
コード例 #36
0
def test_delay_start_example(mode, npart=10, show_movie=False):
    """Example script that shows how to 'delay' the start of particle advection.
    This is useful for example when particles need to be started at different times

    In this example, we use pset.add statements to add one particle every hour
    in the peninsula grid. Note that the title in the movie may not show correct time"""

    grid = Grid.from_nemo('examples/Peninsula_data/peninsula',
                          extra_vars={'P': 'P'},
                          allow_time_extrapolation=True)

    # Initialise particles as in the Peninsula example
    x = 3. * (1. / 1.852 / 60)  # 3 km offset from boundary
    y = (grid.U.lat[0] + x, grid.U.lat[-1] - x
         )  # latitude range, including offsets

    lat = np.linspace(y[0], y[1], npart, dtype=np.float32)
    pset = ParticleSet(grid, lon=[], lat=[], pclass=ptype[mode])

    delaytime = delta(hours=1)  # delay time between particle releases

    # Since we are going to add particles during runtime, we need "indexed" NetCDF file
    output_file = pset.ParticleFile(name="DelayParticle", type="indexed")

    for t in range(npart):
        pset.add(ptype[mode](lon=x, lat=lat[t], grid=grid))
        pset.execute(AdvectionRK4,
                     runtime=delaytime,
                     dt=delta(minutes=5),
                     interval=delta(hours=1),
                     show_movie=show_movie,
                     starttime=delaytime * t,
                     output_file=output_file)

    # Note that time on the movie is not parsed correctly
    pset.execute(AdvectionRK4,
                 runtime=delta(hours=24) - npart * delaytime,
                 starttime=delaytime * npart,
                 dt=delta(minutes=5),
                 interval=delta(hours=1),
                 show_movie=show_movie,
                 output_file=output_file)

    londist = np.array([(p.lon - x) for p in pset])
    assert (londist > 0.1).all()

    # Test whether time was written away correctly in file
    pfile = Dataset("DelayParticle.nc", 'r')
    id = pfile.variables['trajectory'][:]
    time = pfile.variables['time'][id == id[0]]
    assert all(time[1:] - time[0:-1] == time[1] - time[0])
    pfile.close()
コード例 #37
0
def test_ofam_grid(filepath):
    filenames = {'U': path.join(filepath, "OFAM_simple_U.nc"),
                 'V': path.join(filepath, "OFAM_simple_V.nc")}
    variables = {'U': 'u', 'V': 'v'}
    dimensions = {'lat': 'yu_ocean', 'lon': 'xu_ocean', 'depth': 'st_ocean',
                  'time': 'Time'}
    grid = Grid.from_netcdf(filenames, variables, dimensions)
    assert(grid.U.lon.size == 2001)
    assert(grid.U.lat.size == 601)
    assert(grid.U.data.shape == (4, 601, 2001))
    assert(grid.V.lon.size == 2001)
    assert(grid.V.lat.size == 601)
    assert(grid.V.data.shape == (4, 601, 2001))
コード例 #38
0
def set_globcurrent_grid():
    filenames = {
        'U':
        "examples/GlobCurrent_example_data/20*-GLOBCURRENT-L4-CUReul_hs-ALT_SUM-v02.0-fv01.0.nc",
        'V':
        "examples/GlobCurrent_example_data/20*-GLOBCURRENT-L4-CUReul_hs-ALT_SUM-v02.0-fv01.0.nc"
    }
    variables = {
        'U': 'eastward_eulerian_current_velocity',
        'V': 'northward_eulerian_current_velocity'
    }
    dimensions = {'lat': 'lat', 'lon': 'lon', 'time': 'time'}
    return Grid.from_netcdf(filenames, variables, dimensions)
コード例 #39
0
def set_ofam_grid():
    filenames = {
        'U': "examples/OFAM_example_data/OFAM_simple_U.nc",
        'V': "examples/OFAM_example_data/OFAM_simple_V.nc"
    }
    variables = {'U': 'u', 'V': 'v'}
    dimensions = {
        'lat': 'yu_ocean',
        'lon': 'xu_ocean',
        'depth': 'st_ocean',
        'time': 'Time'
    }
    return Grid.from_netcdf(filenames, variables, dimensions)
コード例 #40
0
def test_advection_zonal(lon, lat, mode, npart=10):
    """ Particles at high latitude move geographically faster due to
        the pole correction in `GeographicPolar`.
    """
    U = np.ones((lon.size, lat.size), dtype=np.float32)
    V = np.zeros((lon.size, lat.size), dtype=np.float32)
    grid = Grid.from_data(U, lon, lat, V, lon, lat, mesh='spherical')

    pset = grid.ParticleSet(npart, pclass=ptype[mode],
                            lon=np.zeros(npart, dtype=np.float32) + 20.,
                            lat=np.linspace(0, 80, npart, dtype=np.float32))
    pset.execute(AdvectionRK4, endtime=delta(hours=2), dt=delta(seconds=30))
    assert (np.diff(np.array([p.lon for p in pset])) > 1.e-4).all()
コード例 #41
0
def test_globcurrent_grid():
    filenames = {'U': "examples/GlobCurrent_example_data/20*-GLOBCURRENT-L4-CUReul_hs-ALT_SUM-v02.0-fv01.0.nc",
                 'V': "examples/GlobCurrent_example_data/20*-GLOBCURRENT-L4-CUReul_hs-ALT_SUM-v02.0-fv01.0.nc"}
    variables = {'U': 'eastward_eulerian_current_velocity', 'V': 'northward_eulerian_current_velocity'}
    dimensions = {'lat': 'lat', 'lon': 'lon',
                  'time': 'time'}
    grid = Grid.from_netcdf(filenames, variables, dimensions)
    assert(grid.U.lon.size == 81)
    assert(grid.U.lat.size == 41)
    assert(grid.U.data.shape == (365, 41, 81))
    assert(grid.V.lon.size == 81)
    assert(grid.V.lat.size == 41)
    assert(grid.V.data.shape == (365, 41, 81))
コード例 #42
0
def test_advection_zonal(lon, lat, mode, npart=10):
    """ Particles at high latitude move geographically faster due to
        the pole correction in `GeographicPolar`.
    """
    U = np.ones((lon.size, lat.size), dtype=np.float32)
    V = np.zeros((lon.size, lat.size), dtype=np.float32)
    grid = Grid.from_data(U, lon, lat, V, lon, lat, mesh='spherical')

    pset = grid.ParticleSet(npart,
                            pclass=ptype[mode],
                            lon=np.zeros(npart, dtype=np.float32) + 20.,
                            lat=np.linspace(0, 80, npart, dtype=np.float32))
    pset.execute(AdvectionRK4, endtime=delta(hours=2), dt=delta(seconds=30))
    assert (np.diff(np.array([p.lon for p in pset])) > 1.e-4).all()
コード例 #43
0
def stommel_grid(xdim=200, ydim=200):
    """Simulate a periodic current along a western boundary, with significantly
    larger velocities along the western edge than the rest of the region

    The original test description can be found in: N. Fabbroni, 2009,
    Numerical Simulation of Passive tracers dispersion in the sea,
    Ph.D. dissertation, University of Bologna
    http://amsdottorato.unibo.it/1733/1/Fabbroni_Nicoletta_Tesi.pdf
    """
    # Set NEMO grid variables
    depth = np.zeros(1, dtype=np.float32)
    time = np.linspace(0., 100000. * 86400., 2, dtype=np.float64)

    # Some constants
    A = 100
    eps = 0.05
    a = 10000
    b = 10000

    # Coordinates of the test grid (on A-grid in deg)
    lon = np.linspace(0, a, xdim, dtype=np.float32)
    lat = np.linspace(0, b, ydim, dtype=np.float32)

    # Define arrays U (zonal), V (meridional), W (vertical) and P (sea
    # surface height) all on A-grid
    U = np.zeros((lon.size, lat.size, time.size), dtype=np.float32)
    V = np.zeros((lon.size, lat.size, time.size), dtype=np.float32)
    P = np.zeros((lon.size, lat.size, time.size), dtype=np.float32)

    [x, y] = np.mgrid[:lon.size, :lat.size]
    l1 = (-1 + math.sqrt(1 + 4 * math.pi**2 * eps**2)) / (2 * eps)
    l2 = (-1 - math.sqrt(1 + 4 * math.pi**2 * eps**2)) / (2 * eps)
    c1 = (1 - math.exp(l2)) / (math.exp(l2) - math.exp(l1))
    c2 = -(1 + c1)
    for t in range(time.size):
        for i in range(lon.size):
            for j in range(lat.size):
                xi = lon[i] / a
                yi = lat[j] / b
                P[i, j, t] = A * (c1*math.exp(l1*xi) + c2*math.exp(l2*xi) + 1) * math.sin(math.pi * yi)
        for i in range(lon.size-2):
            for j in range(lat.size):
                V[i+1, j, t] = (P[i+2, j, t] - P[i, j, t]) / (2 * a / xdim)
        for i in range(lon.size):
            for j in range(lat.size-2):
                U[i, j+1, t] = -(P[i, j+2, t] - P[i, j, t]) / (2 * b / ydim)

    return Grid.from_data(U, lon, lat, V, lon, lat, depth, time, field_data={'P': P}, mesh='flat')
コード例 #44
0
def grid_geometric_polar(xdim=200, ydim=100):
    """ Standard earth grid with U and V equivalent to lon/lat in m
        and the inversion of the pole correction applied to U.
    """
    lon = np.linspace(-180, 180, xdim, dtype=np.float32)
    lat = np.linspace(-90, 90, ydim, dtype=np.float32)
    U, V = np.meshgrid(lat, lon)
    # Apply inverse of pole correction to U
    for i, y in enumerate(lat):
        U[:, i] *= cos(y * pi / 180)
    U *= 1000. * 1.852 * 60.
    V *= 1000. * 1.852 * 60.
    grid = Grid.from_data(np.array(U, dtype=np.float32), lon, lat,
                          np.array(V, dtype=np.float32), lon, lat,
                          mesh='spherical')
    return grid
コード例 #45
0
def grid_geometric_polar(xdim=200, ydim=100):
    """ Standard earth grid with U and V equivalent to lon/lat in m
        and the inversion of the pole correction applied to U.
    """
    lon = np.linspace(-180, 180, xdim, dtype=np.float32)
    lat = np.linspace(-90, 90, ydim, dtype=np.float32)
    U, V = np.meshgrid(lat, lon)
    # Apply inverse of pole correction to U
    for i, y in enumerate(lat):
        U[:, i] *= cos(y * pi / 180)
    U *= 1000. * 1.852 * 60.
    V *= 1000. * 1.852 * 60.
    grid = Grid.from_data(np.array(U, dtype=np.float32), lon, lat,
                          np.array(V, dtype=np.float32), lon, lat,
                          mesh='spherical')
    return grid
コード例 #46
0
ファイル: test_grid.py プロジェクト: dham/parcels
def test_grid_constant(mode):
    u, v, lon, lat, depth, time = generate_grid(100, 100)
    grid = Grid.from_data(u, lon, lat, v, lon, lat, depth, time)
    westval = -0.2
    eastval = 0.3
    grid.add_constant('movewest', westval)
    grid.add_constant('moveeast', eastval)
    assert grid.movewest == westval

    pset = ParticleSet.from_line(grid,
                                 size=1,
                                 pclass=ptype[mode],
                                 start=(0.5, 0.5),
                                 finish=(0.5, 0.5))
    pset.execute(pset.Kernel(addConst), dt=1, runtime=1)
    assert abs(pset[0].lon - (0.5 + westval + eastval)) < 1e-4
コード例 #47
0
def test_zonalflow_sperical(mode, xdim=100, ydim=200):
    """ Create uniform EASTWARD flow on sperical earth and advect particles

    As flow is so simple, it can be directly compared to analytical solution
    Note that in this case the cosine conversion is needed
    """

    ParticleClass = JITParticle if mode == 'jit' else Particle

    class MyParticle(ParticleClass):
        user_vars = {'p': np.float32}

        def __init__(self, *args, **kwargs):
            super(MyParticle, self).__init__(*args, **kwargs)
            self.p = 1.

        def __repr__(self):
            return "P(%.4f, %.4f)[p=%.5f]" % (self.lon, self.lat, self.p)

    maxvel = 1.
    p_fld = 10
    lon = np.linspace(-180, 180, xdim, dtype=np.float32)
    lat = np.linspace(-90, 90, ydim, dtype=np.float32)
    V = np.zeros([xdim, ydim])
    U = maxvel * np.ones([xdim, ydim])
    P = p_fld * np.ones([xdim, ydim])

    grid = Grid.from_data(np.array(U, dtype=np.float32), lon, lat,
                          np.array(V, dtype=np.float32), lon, lat,
                          field_data={'P': np.array(P, dtype=np.float32)})

    lonstart = [0, 45]
    latstart = [0, 45]
    endtime = delta(hours=24)
    pset = grid.ParticleSet(2, pclass=MyParticle, lon=lonstart, lat=latstart)
    pset.execute(pset.Kernel(AdvectionRK4) + pset.Kernel(UpdateP),
                 endtime=endtime, dt=delta(hours=1))

    assert(pset[0].lat - latstart[0] < 1e-4)
    assert(pset[0].lon - (lonstart[0] + endtime.total_seconds() * maxvel / 1852 / 60
                          / cos(latstart[0] * pi / 180)) < 1e-4)
    assert(abs(pset[0].p - p_fld) < 1e-4)
    assert(pset[1].lat - latstart[1] < 1e-4)
    assert(pset[1].lon - (lonstart[1] + endtime.total_seconds() * maxvel / 1852 / 60
                          / cos(latstart[1] * pi / 180)) < 1e-4)
    assert(abs(pset[1].p - p_fld) < 1e-4)
コード例 #48
0
ファイル: test_grid_sampling.py プロジェクト: dham/parcels
def test_sampling_out_of_bounds_time(mode,
                                     allow_time_extrapolation,
                                     k_sample_p,
                                     xdim=10,
                                     ydim=10,
                                     tdim=10):
    lon = np.linspace(0., 1., xdim, dtype=np.float32)
    lat = np.linspace(0., 1., ydim, dtype=np.float32)
    time = np.linspace(0., 1., tdim, dtype=np.float64)
    U = np.zeros((xdim, ydim, tdim), dtype=np.float32)
    V = np.zeros((xdim, ydim, tdim), dtype=np.float32)
    P = np.ones((xdim, ydim, 1), dtype=np.float32) * time
    grid = Grid.from_data(U,
                          lon,
                          lat,
                          V,
                          lon,
                          lat,
                          time=time,
                          mesh='flat',
                          field_data={'P': np.asarray(P, dtype=np.float32)},
                          allow_time_extrapolation=allow_time_extrapolation)
    pset = ParticleSet.from_line(grid,
                                 size=1,
                                 pclass=pclass(mode),
                                 start=(0.5, 0.5),
                                 finish=(0.5, 0.5))
    if allow_time_extrapolation:
        pset.execute(k_sample_p, starttime=-1.0, endtime=-0.9, dt=0.1)
        assert np.allclose(np.array([p.p for p in pset]), 0.0, rtol=1e-5)
    else:
        with pytest.raises(RuntimeError):
            pset.execute(k_sample_p, starttime=-1.0, endtime=-0.9, dt=0.1)
    pset.execute(k_sample_p, starttime=0.0, endtime=0.1, dt=0.1)
    assert np.allclose(np.array([p.p for p in pset]), 0.0, rtol=1e-5)
    pset.execute(k_sample_p, starttime=0.5, endtime=0.6, dt=0.1)
    assert np.allclose(np.array([p.p for p in pset]), 0.5, rtol=1e-5)
    pset.execute(k_sample_p, starttime=1.0, endtime=1.1, dt=0.1)
    assert np.allclose(np.array([p.p for p in pset]), 1.0, rtol=1e-5)
    if allow_time_extrapolation:
        pset.execute(k_sample_p, starttime=2.0, endtime=2.1, dt=0.1)
        assert np.allclose(np.array([p.p for p in pset]), 1.0, rtol=1e-5)
    else:
        with pytest.raises(RuntimeError):
            pset.execute(k_sample_p, starttime=2.0, endtime=2.1, dt=0.1)
コード例 #49
0
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 = grid.ParticleSet(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())
コード例 #50
0
def stommel_grid(xdim=200, ydim=200):
    """Simulate a periodic current along a western boundary, with significantly
    larger velocities along the western edge than the rest of the region

    The original test description can be found in: N. Fabbroni, 2009,
    Numerical Simulation of Passive tracers dispersion in the sea,
    Ph.D. dissertation, University of Bologna
    http://amsdottorato.unibo.it/1733/1/Fabbroni_Nicoletta_Tesi.pdf
    """
    # Set NEMO grid variables
    depth = np.zeros(1, dtype=np.float32)
    time = np.linspace(0., 100000. * 86400., 2, dtype=np.float64)

    # Coordinates of the test grid (on A-grid in deg)
    lon = np.linspace(0, 60, xdim, dtype=np.float32)
    lat = np.linspace(0, 60, ydim, dtype=np.float32)

    # Define arrays U (zonal), V (meridional), W (vertical) and P (sea
    # surface height) all on A-grid
    U = np.zeros((lon.size, lat.size, time.size), dtype=np.float32)
    V = np.zeros((lon.size, lat.size, time.size), dtype=np.float32)

    # Some constants
    day = 11.6
    r = 1 / (day * 86400)
    beta = 2e-11
    a = 2000000
    e_s = r / (beta * a)

    [x, y] = np.mgrid[:lon.size, :lat.size]
    for t in range(time.size):
        for i in range(lon.size):
            for j in range(lat.size):
                U[i, j, t] = -(1 - math.exp(-lon[i] * math.pi / 180 / e_s) -
                               lon[i] * math.pi / 180) * math.pi ** 2 *\
                    math.cos(math.pi ** 2 * lat[j] / 180)
                V[i, j,
                  t] = (math.exp(-lon[i] * math.pi / 180 / e_s) / e_s -
                        1) * math.pi * math.sin(math.pi**2 * lat[j] / 180)

    return Grid.from_data(U, lon, lat, V, lon, lat, depth, time)
コード例 #51
0
def test_sampling_out_of_bounds_time(mode, k_sample_p, xdim=10, ydim=10, tdim=10):
    lon = np.linspace(0., 1., xdim, dtype=np.float32)
    lat = np.linspace(0., 1., ydim, dtype=np.float32)
    time = np.linspace(0., 1., tdim, dtype=np.float64)
    U = np.zeros((xdim, ydim, tdim), dtype=np.float32)
    V = np.zeros((xdim, ydim, tdim), dtype=np.float32)
    P = np.ones((xdim, ydim, 1), dtype=np.float32) * time
    grid = Grid.from_data(U, lon, lat, V, lon, lat, time=time,
                          mesh='flat', field_data={'P': P})
    pset = grid.ParticleSet(size=1, pclass=pclass(mode),
                            start=(0.5, 0.5), finish=(0.5, 0.5))
    pset.execute(k_sample_p, starttime=-1.0, endtime=-0.9, dt=0.1)
    assert np.allclose(np.array([p.p for p in pset]), 0.0, rtol=1e-5)
    pset.execute(k_sample_p, starttime=0.0, endtime=0.1, dt=0.1)
    assert np.allclose(np.array([p.p for p in pset]), 0.0, rtol=1e-5)
    pset.execute(k_sample_p, starttime=0.5, endtime=0.6, dt=0.1)
    assert np.allclose(np.array([p.p for p in pset]), 0.5, rtol=1e-5)
    pset.execute(k_sample_p, starttime=1.0, endtime=1.1, dt=0.1)
    assert np.allclose(np.array([p.p for p in pset]), 1.0, rtol=1e-5)
    pset.execute(k_sample_p, starttime=2.0, endtime=2.1, dt=0.1)
    assert np.allclose(np.array([p.p for p in pset]), 1.0, rtol=1e-5)
コード例 #52
0
def test_sampling_out_of_bounds_time(mode, k_sample_p, xdim=10, ydim=10, tdim=10):
    lon = np.linspace(0., 1., xdim, dtype=np.float32)
    lat = np.linspace(0., 1., ydim, dtype=np.float32)
    time = np.linspace(0., 1., tdim, dtype=np.float64)
    U = np.zeros((xdim, ydim, tdim), dtype=np.float32)
    V = np.zeros((xdim, ydim, tdim), dtype=np.float32)
    P = np.ones((xdim, ydim, 1), dtype=np.float32) * time
    grid = Grid.from_data(U, lon, lat, V, lon, lat, time=time, mesh='flat',
                          field_data={'P': np.asarray(P, dtype=np.float32)})
    pset = grid.ParticleSet(size=1, pclass=pclass(mode),
                            start=(0.5, 0.5), finish=(0.5, 0.5))
    pset.execute(k_sample_p, starttime=-1.0, endtime=-0.9, dt=0.1)
    assert np.allclose(np.array([p.p for p in pset]), 0.0, rtol=1e-5)
    pset.execute(k_sample_p, starttime=0.0, endtime=0.1, dt=0.1)
    assert np.allclose(np.array([p.p for p in pset]), 0.0, rtol=1e-5)
    pset.execute(k_sample_p, starttime=0.5, endtime=0.6, dt=0.1)
    assert np.allclose(np.array([p.p for p in pset]), 0.5, rtol=1e-5)
    pset.execute(k_sample_p, starttime=1.0, endtime=1.1, dt=0.1)
    assert np.allclose(np.array([p.p for p in pset]), 1.0, rtol=1e-5)
    pset.execute(k_sample_p, starttime=2.0, endtime=2.1, dt=0.1)
    assert np.allclose(np.array([p.p for p in pset]), 1.0, rtol=1e-5)
コード例 #53
0
def grid_decaying(xdim=100, ydim=100, maxtime=delta(hours=6)):
    """Generate a grid encapsulating the flow field of a decaying eddy.

    Reference: N. Fabbroni, 2009, "Numerical simulations of passive
    tracers dispersion in the sea"
    """
    lon = np.linspace(0, 25000, xdim, dtype=np.float32)
    lat = np.linspace(0, 25000, ydim, dtype=np.float32)
    time = np.arange(0., maxtime.total_seconds(), 60., dtype=np.float64)
    U = np.ones((xdim, ydim, 1), dtype=np.float32) * u_g *\
        np.exp(-gamma_g * time) + (u_0 - u_g) * np.exp(-gamma * time) * np.cos(f * time)
    V = np.ones((xdim, ydim, 1), dtype=np.float32) * -(u_0 - u_g) *\
        np.exp(-gamma * time) * np.sin(f * time)
    return Grid.from_data(np.asarray(U, np.float32),
                          lon,
                          lat,
                          np.asarray(V, np.float32),
                          lon,
                          lat,
                          time=time,
                          mesh='flat')
コード例 #54
0
def stommel_grid(xdim=200, ydim=200):
    """Simulate a periodic current along a western boundary, with significantly
    larger velocities along the western edge than the rest of the region

    The original test description can be found in: N. Fabbroni, 2009,
    Numerical Simulation of Passive tracers dispersion in the sea,
    Ph.D. dissertation, University of Bologna
    http://amsdottorato.unibo.it/1733/1/Fabbroni_Nicoletta_Tesi.pdf
    """
    # Set NEMO grid variables
    depth = np.zeros(1, dtype=np.float32)
    time = np.linspace(0., 100000. * 86400., 2, dtype=np.float64)

    # Coordinates of the test grid (on A-grid in deg)
    lon = np.linspace(0, 60, xdim, dtype=np.float32)
    lat = np.linspace(0, 60, ydim, dtype=np.float32)

    # Define arrays U (zonal), V (meridional), W (vertical) and P (sea
    # surface height) all on A-grid
    U = np.zeros((lon.size, lat.size, time.size), dtype=np.float32)
    V = np.zeros((lon.size, lat.size, time.size), dtype=np.float32)

    # Some constants
    day = 11.6
    r = 1 / (day * 86400)
    beta = 2e-11
    a = 2000000
    e_s = r / (beta * a)

    [x, y] = np.mgrid[:lon.size, :lat.size]
    for t in range(time.size):
        for i in range(lon.size):
            for j in range(lat.size):
                U[i, j, t] = -(1 - math.exp(-lon[i] * math.pi / 180 / e_s) -
                               lon[i] * math.pi / 180) * math.pi ** 2 *\
                    math.cos(math.pi ** 2 * lat[j] / 180)
                V[i, j, t] = (math.exp(-lon[i] * math.pi / 180 / e_s) / e_s -
                              1) * math.pi * math.sin(math.pi ** 2 * lat[j] / 180)

    return Grid.from_data(U, lon, lat, V, lon, lat, depth, time)
コード例 #55
0
def decaying_moving_eddy_grid(xdim=2, ydim=2):  # Define 2D flat, square grid for testing purposes.
    """Simulate an ocean that accelerates subject to Coriolis force
    and dissipative effects, upon which a geostrophic current is
    superimposed.

    The original test description can be found in: N. Fabbroni, 2009,
    Numerical Simulation of Passive tracers dispersion in the sea,
    Ph.D. dissertation, University of Bologna
    http://amsdottorato.unibo.it/1733/1/Fabbroni_Nicoletta_Tesi.pdf
    """
    depth = np.zeros(1, dtype=np.float32)
    time = np.arange(0., 2. * 86400., 60.*5., dtype=np.float64)
    lon = np.linspace(0, 20000, xdim, dtype=np.float32)
    lat = np.linspace(5000, 12000, ydim, dtype=np.float32)

    U = np.zeros((lon.size, lat.size, time.size), dtype=np.float32)
    V = np.zeros((lon.size, lat.size, time.size), dtype=np.float32)

    for t in range(time.size):
        U[:, :, t] = u_g*np.exp(-gamma_g*time[t]) + (u_0-u_g)*np.exp(-gamma*time[t])*np.cos(f*time[t])
        V[:, :, t] = -(u_0-u_g)*np.exp(-gamma*time[t])*np.sin(f*time[t])

    return Grid.from_data(U, lon, lat, V, lon, lat, depth, time, mesh='flat')
コード例 #56
0
def test_random_field(mode, 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)
    K = 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={'K': K, 'start': S})

    class SampleParticle(ptype[mode]):
        user_vars = {'k': np.float32}
    pset = grid.ParticleSet(size=npart, pclass=SampleParticle,
                            start_field=grid.start)

    def SampleK(particle, grid, time, dt):
        particle.k = grid.K[time, particle.lon, particle.lat]
    pset.execute(SampleK, endtime=1., dt=1.0)
    sampled = np.array([p.k for p in pset])
    assert((sampled >= 0.).all())
コード例 #57
0
def test_moving_eddies_file(gridfile, mode):
    grid = Grid.from_nemo(gridfile, extra_vars={'P': 'P'})
    pset = moving_eddies_example(grid, 2, mode=mode)
    assert(pset[0].lon < 0.5 and 46.0 < pset[0].lat < 46.35)
    assert(pset[1].lon < 0.5 and 49.4 < pset[1].lat < 49.8)
コード例 #58
0
def grid(xdim=100, ydim=100):
    U = np.zeros((xdim, ydim), dtype=np.float32)
    V = np.zeros((xdim, ydim), dtype=np.float32)
    lon = np.linspace(0, 1, xdim, dtype=np.float32)
    lat = np.linspace(0, 1, ydim, dtype=np.float32)
    return Grid.from_data(U, lon, lat, V, lon, lat, mesh='flat')