Пример #1
0
    def normal_current(self, U, V):
        """Sample normal component of velocity field"""

        # Interpolerer foreløpig langs s-flater

        # Offset for interpolation from U and V grid
        deltaU = -0.5 + self.grid.i0 - self.grid.i0_u
        deltaV = -0.5 + self.grid.j0 - self.grid.j0_v
        Usec = np.zeros((self.N, self.nseg))
        Vsec = np.zeros((self.N, self.nseg))
        for k in range(self.N):
            Usec[k, :] = sample2D(U[k, :, :], self.Xm+deltaU, self.Ym)
            Vsec[k, :] = sample2D(V[k, :, :], self.Xm, self.Ym+deltaV)
        return self.nx*Usec + self.ny*Vsec
Пример #2
0
    def test_masked(self):
        """Interpolates correctly in the presence of mask"""
        A = np.array([[1, 1, 1, 1],   # j=0
                      [0, 1, 1, 1],   # j=1
                      [0, 1, 0, 0],   # j=2
                      [1, 1, 0, 0]])  # j=3
        M = A

        # sea point outside halo
        x, y = 1.8, 0.8
        self.assertEqual(sample2D(A, x, y), 1)
        self.assertEqual(sample2D(A, x, y, mask=M), 1)

        # sea point in halo
        x, y = 1.8, 1.3
        self.assertAlmostEqual(sample2D(A, x, y), 1-0.8*0.3)
        self.assertEqual(sample2D(A, x, y, mask=M), 1)

        # land point in halo
        x, y = 1.8, 1.8
        b_unmask = sample2D(A, x, y, undef_value=np.nan)
        self.assertAlmostEqual(b_unmask, 1-0.8*0.8)
        b_mask = sample2D(A, x, y, mask=M, undef_value=np.nan)
        self.assertEqual(b_mask, 1)

        # land point outside halo
        x, y = 2.8, 2.4
        b_unmask = sample2D(A, x, y, undef_value=np.nan)
        self.assertEqual(b_unmask, 0)
        b_mask = sample2D(A, x, y, mask=M, undef_value=np.nan)
        self.assertTrue(np.isnan(b_mask))
Пример #3
0
    def __init__(self, grid, X, Y):

        self.grid = grid
        # Vertices, in subgrid coordinates
        self.X = X - grid.i0
        self.Y = Y - grid.j0

        # Nodes
        self.Xm = 0.5*(self.X[:-1] + self.X[1:])
        self.Ym = 0.5*(self.Y[:-1] + self.Y[1:])

        # Section size
        self.nseg = len(self.Xm)  # Number of segments = Number of nodes
        self.N = len(self.grid.Cs_r)

        # Compatible with both SGrid and grdClass
        try:
            self.h = sample2D(self.grid.h, self.Xm, self.Ym,
                              mask=self.grid.mask_rho, undef_value=0.0)
        except AttributeError:
            self.h = sample2D(self.grid.depth, self.Xm, self.Ym)

        pm = sample2D(self.grid.pm, self.Xm, self.Ym)
        pn = sample2D(self.grid.pn, self.Xm, self.Ym)

        # Unit normal vector (nx, ny)
        # Sjekk om dette er korrekt hvis pm og pn er ulike
        dX = (X[1:]-X[:-1]) / pm
        dY = (Y[1:]-Y[:-1]) / pn

        # Length of segments
        #   Kan kanskje forbedres med sfærisk avstand
        self.dS = np.sqrt(dX*dX+dY*dY)
        # Cumulative distance (at vertices)s
        self.S = np.concatenate(([0], np.add.accumulate(self.dS)))

        nx, ny = dY, -dX
        norm = np.sqrt(nx*nx + ny*ny)
        self.nx, self.ny = nx/norm, ny/norm

        # Vertical structure
        self.z_r = sdepth(self.h, self.grid.hc, self.grid.Cs_r,
                          stagger='rho', Vtransform=self.grid.Vtransform)
        self.z_w = sdepth(self.h, self.grid.hc, self.grid.Cs_w,
                          stagger='w', Vtransform=self.grid.Vtransform)
        self.dZ = self.z_w[1:, :]-self.z_w[:-1, :]

        self.Area = self.dZ * self.dS
Пример #4
0
 def test_outside(self):
     """Handle outside values correctly"""
     imax, jmax = 10, 7
     A = np.zeros((jmax, imax))
     x, y = 9.2, 4
     self.assertRaises(ValueError, sample2D, A, x, y)
     b = sample2D(A, x, y, outside_value=np.nan)
     self.assertTrue(np.isnan(b))
Пример #5
0
 def test_nodes(self):
     """Exact at nodes"""
     f = lambda x, y : x**2 + y**2
     imax, jmax = 10, 7
     JJ, II = np.meshgrid(np.arange(jmax), np.arange(imax))
     A = f(JJ, II)
     i, j = 4, 3
     B = sample2D(A, i, j)
     self.assertEqual(B, A[j,i])
Пример #6
0
    def sample3D(self, F):
        """Sample a 3D field in rho-points with shape (N,Mp,Lp)"""

        # Not masked ??

        Fsec = np.zeros((self.N, self.L))
        for k in range(self.N):
            Fsec[k, :] = sample2D(F[k, :, :], self.X, self.Y,
                                  mask=self.grid.mask_rho)
        return Fsec
Пример #7
0
 def test_bilinear(self):
     """Exact for bilinear function"""
     f = lambda x, y: 3.0 + 2*x + 1.4*y + 0.2*x*y
     imax, jmax = 10, 7
     JJ, II = np.meshgrid(np.arange(jmax), np.arange(imax))
     A = f(JJ, II)
     X, Y = 5.2, 4.1
     Z = f(X, Y)
     B = sample2D(A, X, Y)
     self.assertEqual(B, Z)
Пример #8
0
    def __init__(self, grid, X, Y):

        self.grid = grid
        # Vertices, in subgrid coordinates
        self.X = X
        self.Y = Y

        # Section size
        self.L = len(self.X)         # Number of nodes
        self.N = len(self.grid.Cs_r)

        # Topography
        self.h = sample2D(self.grid.h, self.X, self.Y,
                          mask=self.grid.mask_rho, undef_value=1.0)

        # Metric
        pm = sample2D(self.grid.pm, self.X, self.Y)
        pn = sample2D(self.grid.pn, self.X, self.Y)
        dX = 2 * (X[1:]-X[:-1]) / (pm[:-1] + pm[1:])      # unit = meter
        dY = 2 * (Y[1:]-Y[:-1]) / (pn[:-1] + pn[1:])
        # Assume spacing is close enough to approximate distance
        self.dS = np.sqrt(dX*dX+dY*dY)
        # Cumulative distance
        self.S = np.concatenate(([0], np.add.accumulate(self.dS)))
        # Weights for trapez integration (linear interpolation)
        self.W = 0.5*np.concatenate(([self.dS[0]],
                                     self.dS[:-1] + self.dS[1:],
                                     [self.dS[-1]]))

        # nx, ny  = dY, -dX
        # norm = np.sqrt(nx*nx + ny*ny)
        # self.nx, self.ny = nx/norm, ny/norm

        # Vertical structure
        self.z_r = sdepth(self.h, self.grid.hc, self.grid.Cs_r,
                          stagger='rho', Vtransform=self.grid.Vtransform)
        self.z_w = sdepth(self.h, self.grid.hc, self.grid.Cs_w,
                          stagger='w', Vtransform=self.grid.Vtransform)
        self.dZ = self.z_w[1:, :]-self.z_w[:-1, :]

        self.Area = self.dZ * self.W
Пример #9
0
    def sample3D(self, F):
        """Sample a 3D field in rho-points with shape (N,Mp,Lp)"""

        # Interpolerer foreløpig langs s-flater
        # Sikkert OK for plotting, Godt nok for flux-beregning?

        Fsec = np.zeros((self.grid.N, self.nseg))
        for k in range(self.grid.N):
            Fsec[k, :] = sample2D(F[k, :, :], self.Xm, self.Ym,
                                  mask=self.grid.mask_rho)
        Fsec = np.ma.masked_where(self.extend_vertically(self.h) == 0, Fsec)
        return Fsec
Пример #10
0
    def test_arguments(self):
        # Make a grid for testing
        imax, jmax = 10, 7
        A = np.zeros((jmax, imax))

        # Scalars
        X, Y = 2.7, 3.5
        self.assertTrue(np.isscalar(sample2D(A, X, Y)))

        # Conformal arrays
        X = np.array([1,2])
        Y = np.array([3,4])
        B = sample2D(A, X, Y)
        self.assertEqual(B.shape, (2,))

        # Conformal arrays 2
        X = np.arange(6).reshape(2,3)
        Y = np.array([1,2]).reshape(2,1)
        B = sample2D(A, X, Y)
        self.assertEqual(B.shape, (2,3))

        # Scalar and array
        X = 4
        Y = np.array([1,2])
        B = sample2D(A, X, Y)
        self.assertEqual(B.shape, (2,))

        # Nonconformal arrays
        X = np.arange(6).reshape(2,3)
        Y = np.array([1,2])
        self.assertRaises(ValueError, sample2D, A, X, Y)

        # 1D sequences such as lists
        X = [1.1, 2.2, 3.3]
        Y = [3.5]
        B = sample2D(A, X, Y)
        self.assertEqual(B.shape, (3,))
Пример #11
0
 def sample2D(self, F):
     return sample2D(F, self.Xm, self.Ym)
Пример #12
0
 def sample2D(self, F):
     """Sample a horizontal field at rho poins with shape (Mp, Lp)"""
     return sample2D(F, self.X, self.Y, mask=self.grid.mask_rho)
Пример #13
0
 def xy2ll(self, x, y):
     return (sample2D(self.lon_rho, x-self.i0, y-self.j0),
             sample2D(self.lat_rho, x-self.i0, y-self.j0))
Пример #14
0
 def test_boundary(self):
     """Works correctly close to boundary"""
     imax, jmax = 10, 7
     A = np.ones((jmax, imax))
     x, y = 0.2, 5.9
     self.assertEqual(sample2D(A, x, y), 1)