Beispiel #1
0
    def test_depth_kwarg(self):
        nz = 20
        zin = 0.5 * nz**-1 + np.arange(nz, dtype=np.float64) / nz
        N2 = np.full(nz, 1.)
        f0 = 1.

        with self.assertRaises(ValueError):
            z, def_radius, bc_modes = modes.neutral_modes_from_N2_profile(
                zin, N2, f0, depth=zin[-5])

        # no error expected
        z, def_radius, bc_modes = modes.neutral_modes_from_N2_profile(
            zin, N2, f0, depth=1.1)
Beispiel #2
0
    def test_depth_kwarg(self):
        nz = 20
        zin = 0.5*nz**-1 + np.arange(nz, dtype=np.float64)/nz
        N2 = np.full(nz, 1.)
        f0 = 1.

        with self.assertRaises(ValueError):
            z, def_radius, bc_modes = modes.neutral_modes_from_N2_profile(
                zin, N2, f0, depth=zin[-5]
            )

        # no error expected
        z, def_radius, bc_modes = modes.neutral_modes_from_N2_profile(
            zin, N2, f0, depth=1.1
        )
Beispiel #3
0
    def test_N2_const_equal_spacing(self):
        # prepare a test N^2 profile
        nz = 20
        depth = 0.5*nz**-1 + np.arange(nz, dtype=np.float64)/nz

        N2 = np.full(nz, 1.)
        f0 = 1.

        z, def_radius, bc_modes = modes.neutral_modes_from_N2_profile(
            depth, N2, f0
        )

        # make sure we got the right number of modes
        # NOPE! don't want all the modes and scipy.sparse.linalg.eigs won't
        # compute them
        #self.assertEqual(nz, len(def_radius))
        # make sure the modes themselves have the right structure
        self.assertEqual(nz+1, bc_modes.shape[0],
            msg='modes array must the right shape')

        self.assertTrue(np.all(np.diff(def_radius[1:]) < 0),
            msg='modes should be sorted in order of decreasing deformation radius')

        nmodes = len(def_radius)
        zero_crossings = np.abs(np.diff(np.sign(bc_modes), axis=0)/2).sum(axis=0)
        self.assertListEqual(list(range(nmodes)), list(zero_crossings),
            msg='modes should have the correct number of zero crossings')

        mode_amplitudes = (bc_modes**2).sum(axis=0)
        self.assertTrue(np.allclose(np.ones(nmodes), mode_amplitudes),
            msg='modes should be normalized to amplitude of 1')
Beispiel #4
0
    def test_N2_const_equal_spacing(self):
        # prepare a test N^2 profile
        nz = 20
        depth = 0.5 * nz**-1 + np.arange(nz, dtype=np.float64) / nz

        N2 = np.full(nz, 1.)
        f0 = 1.

        z, def_radius, bc_modes = modes.neutral_modes_from_N2_profile(
            depth, N2, f0)

        self.assertEqual(nz + 1,
                         bc_modes.shape[0],
                         msg='modes array must the right shape')

        self.assertTrue(
            np.all(np.diff(def_radius[1:]) < 0),
            msg=
            'modes should be sorted in order of decreasing deformation radius')

        nmodes = len(def_radius)
        zero_crossings = np.abs(np.diff(np.sign(bc_modes), axis=0) /
                                2).sum(axis=0)
        self.assertListEqual(
            list(range(nmodes)),
            list(zero_crossings),
            msg='modes should have the correct number of zero crossings')

        mode_amplitudes = (bc_modes**2).sum(axis=0)
        self.assertTrue(np.allclose(np.ones(nmodes), mode_amplitudes),
                        msg='modes should be normalized to amplitude of 1')
Beispiel #5
0
    def test_neutral_mode_args(self):
        nz = 10
        N2 = np.zeros(nz)
        depth = np.arange(nz)
        # check for unequal lengths of arrays
        with self.assertRaises(ValueError):
            _, _, _ = modes.neutral_modes_from_N2_profile(depth[1:], N2, 1.)
        with self.assertRaises(ValueError):
            _, _, _ = modes.neutral_modes_from_N2_profile(depth, N2[1:], 1.)

        depth_non_monotonic = depth
        depth_non_monotonic[0] = 5
        # check for non-monotonic profile
        with self.assertRaises(ValueError) as cm:
            _, _, _ = modes.neutral_modes_from_N2_profile(
                depth_non_monotonic, N2, 1.)
Beispiel #6
0
    def test_neutral_mode_OCCA_GulfStream(self):
        """ Test profile in the Gulf Stream in the OCCA data set
        """
        zN2 = np.array([  -10.00006115,   -20.00006114,   -30.00006113,   -40.00006112,
         -50.0000611 ,   -60.00006109,   -70.00256358,   -80.01506451,
         -90.06006328,  -100.20256308,  -110.5900682 ,  -121.51007976,
        -133.44509256,  -147.10512803,  -163.43519352,  -183.5678012 ,
        -208.72298023,  -240.09073926,  -278.70109317,  -325.30655719,
        -380.30712264,  -443.70276088,  -515.09343642,  -593.72659767,
        -678.57216844,  -768.44015906,  -862.11055267,  -958.45325725,
       -1056.53586028, -1155.72595435, -1255.87608991, -1357.68378579,
       -1463.12934261, -1575.64299213, -1699.66489761, -1839.65538686,
       -1999.10931291, -2180.15155508, -2383.76440293, -2610.28273438,
       -2859.78914881, -3132.29607118, -3427.80347989, -3746.3113517 ,
       -4087.81966191, -4452.32838443, -4839.83749199, -5250.34695635,
       -5683.85674858])
        N2 = np.array([  4.49013733e-05,   1.32619531e-04,   1.67213349e-04,
         1.39980381e-04,   1.08620176e-04,   8.89353316e-05,
         7.59696940e-05,   6.85660114e-05,   6.13053056e-05,
         4.96623307e-05,   4.26153730e-05,   3.83933836e-05,
         3.33244718e-05,   3.14573673e-05,   2.74780120e-05,
         2.50869570e-05,   2.35907064e-05,   2.26047540e-05,
         2.06309696e-05,   1.93499569e-05,   1.85802260e-05,
         1.73887368e-05,   1.49995125e-05,   1.25945779e-05,
         1.06210281e-05,   9.69791903e-06,   9.18845407e-06,
         7.56655382e-06,   5.00383224e-06,   2.83633215e-06,
         1.67170878e-06,   1.19350982e-06,   9.87252978e-07,
         9.54096555e-07,   1.05979705e-06,   1.18957478e-06,
         1.23432375e-06,   1.22190029e-06,   1.20084648e-06,
         1.18287498e-06,   1.14801849e-06,   1.08643614e-06,
         9.36511867e-07,   6.17342678e-07,   3.35507108e-07,
         3.19646379e-07,   2.60733349e-07,              np.nan,
                    np.nan])
        f0 = 9.276710625272244e-05
        nz = len(zN2)
        kwargs = {'num_eigen': 2, 'init_vector': None, 'num_Lanczos': nz*10, 'iteration': nz*100, 'tolerance': 0}
        zphi, Rd, v = modes.neutral_modes_from_N2_profile(
                        -zN2, N2, f0, **kwargs)
        
        self.assertTrue(np.isclose(Rd[1], 25787.38588731),
            msg='Rossby radius should be exact to the solution')

        self.assertTrue(np.allclose(np.diff(v[:, 0]), 0.),
            msg='The barotropic vertical mode should have all same value')
        
        v1 = np.array([ 0.2287108,  0.22844163,  0.22738221,  0.22538205,  0.22315635,  0.22100572,
          0.21890111,  0.21681132,  0.21466035,  0.21249153,  0.21051281,  0.20857709,
          0.20653185,  0.20436013,  0.20172795,  0.19864415,  0.19475028,  0.18960952,
          0.18268901,  0.17391394,  0.16270843,  0.14845062,  0.13133273,  0.11305419,
          0.09473064,  0.07691331,  0.05874788,  0.04009015,  0.02387257,  0.01278873,
          0.00637754,  0.00253038, -0.00029387, -0.00275014, -0.00532013, -0.00849032,
         -0.01248929, -0.01713441, -0.02220176, -0.02756655, -0.0331077,  -0.03857259,
         -0.04363333, -0.04770119, -0.05004272, -0.05105026, -0.05168191, -0.05185931])
        self.assertTrue(np.allclose(np.absolute(v[:, 1]), np.absolute(v1)),
            msg='The amplitude of vertical modes should have the exact elements')
Beispiel #7
0
    def test_neutral_mode_args(self):
        nz = 10
        N2 = np.zeros(nz)
        depth = np.arange(nz)
        # check for unequal lengths of arrays
        with self.assertRaises(ValueError):
            _, _, _ = modes.neutral_modes_from_N2_profile(
                depth[1:], N2, 1.
            )
        with self.assertRaises(ValueError):
            _, _, _ = modes.neutral_modes_from_N2_profile(
                depth, N2[1:], 1.
            )

        depth_non_monotonic = depth
        depth_non_monotonic[0] = 5
        # check for non-monotonic profile
        with self.assertRaises(ValueError) as cm:
            _, _, _ = modes.neutral_modes_from_N2_profile(
                depth_non_monotonic, N2, 1.
            )
Beispiel #8
0
    def test_neutral_mode_OCCA_GulfStream(self):
        """ Test profile in the Gulf Stream in the OCCA data set
        """
        zN2 = np.array([
            -10.00006115, -20.00006114, -30.00006113, -40.00006112,
            -50.0000611, -60.00006109, -70.00256358, -80.01506451,
            -90.06006328, -100.20256308, -110.5900682, -121.51007976,
            -133.44509256, -147.10512803, -163.43519352, -183.5678012,
            -208.72298023, -240.09073926, -278.70109317, -325.30655719,
            -380.30712264, -443.70276088, -515.09343642, -593.72659767,
            -678.57216844, -768.44015906, -862.11055267, -958.45325725,
            -1056.53586028, -1155.72595435, -1255.87608991, -1357.68378579,
            -1463.12934261, -1575.64299213, -1699.66489761, -1839.65538686,
            -1999.10931291, -2180.15155508, -2383.76440293, -2610.28273438,
            -2859.78914881, -3132.29607118, -3427.80347989, -3746.3113517,
            -4087.81966191, -4452.32838443, -4839.83749199, -5250.34695635,
            -5683.85674858
        ])
        N2 = np.array([
            4.49013733e-05, 1.32619531e-04, 1.67213349e-04, 1.39980381e-04,
            1.08620176e-04, 8.89353316e-05, 7.59696940e-05, 6.85660114e-05,
            6.13053056e-05, 4.96623307e-05, 4.26153730e-05, 3.83933836e-05,
            3.33244718e-05, 3.14573673e-05, 2.74780120e-05, 2.50869570e-05,
            2.35907064e-05, 2.26047540e-05, 2.06309696e-05, 1.93499569e-05,
            1.85802260e-05, 1.73887368e-05, 1.49995125e-05, 1.25945779e-05,
            1.06210281e-05, 9.69791903e-06, 9.18845407e-06, 7.56655382e-06,
            5.00383224e-06, 2.83633215e-06, 1.67170878e-06, 1.19350982e-06,
            9.87252978e-07, 9.54096555e-07, 1.05979705e-06, 1.18957478e-06,
            1.23432375e-06, 1.22190029e-06, 1.20084648e-06, 1.18287498e-06,
            1.14801849e-06, 1.08643614e-06, 9.36511867e-07, 6.17342678e-07,
            3.35507108e-07, 3.19646379e-07, 2.60733349e-07, np.nan, np.nan
        ])
        f0 = 9.276710625272244e-05
        nz = len(zN2)
        kwargs = {
            'num_eigen': 2,
            'init_vector': None,
            'num_Lanczos': nz * 10,
            'iteration': nz * 100,
            'tolerance': 0
        }
        zphi, Rd, v = modes.neutral_modes_from_N2_profile(
            -zN2, N2, f0, **kwargs)

        self.assertTrue(np.isclose(Rd[1], 25787.38588731),
                        msg='Rossby radius should be exact to the solution')

        self.assertTrue(
            np.allclose(np.diff(v[:, 0]), 0.),
            msg='The barotropic vertical mode should have all same value')

        v1 = np.array([
            0.2287108, 0.22844163, 0.22738221, 0.22538205, 0.22315635,
            0.22100572, 0.21890111, 0.21681132, 0.21466035, 0.21249153,
            0.21051281, 0.20857709, 0.20653185, 0.20436013, 0.20172795,
            0.19864415, 0.19475028, 0.18960952, 0.18268901, 0.17391394,
            0.16270843, 0.14845062, 0.13133273, 0.11305419, 0.09473064,
            0.07691331, 0.05874788, 0.04009015, 0.02387257, 0.01278873,
            0.00637754, 0.00253038, -0.00029387, -0.00275014, -0.00532013,
            -0.00849032, -0.01248929, -0.01713441, -0.02220176, -0.02756655,
            -0.0331077, -0.03857259, -0.04363333, -0.04770119, -0.05004272,
            -0.05105026, -0.05168191, -0.05185931
        ])
        self.assertTrue(
            np.allclose(np.absolute(v[:, 1]), np.absolute(v1)),
            msg='The amplitude of vertical modes should have the exact elements'
        )