Пример #1
0
def pwpgo(forcing, params, pwp_out, diagnostics):
    """
    This is the main driver of the PWP module.
    """

    #unpack some of the variables
    #This is not necessary, but I don't want to update all the variable names just yet.
    q_in = forcing['q_in']
    q_out = forcing['q_out']
    emp = forcing['emp']
    taux = forcing['tx']
    tauy = forcing['ty']
    absrb = forcing['absrb']

    z = pwp_out['z']
    dz = pwp_out['dz']
    dt = pwp_out['dt']
    zlen = len(z)
    tlen = len(pwp_out['time'])

    rb = params['rb']
    rg = params['rg']
    f = params['f']
    cpw = params['cpw']
    g = params['g']
    ucon = params['ucon']

    printDragWarning = True

    print("Number of time steps: %s" % tlen)

    for n in range(1, tlen):
        percent_comp = 100 * n / float(tlen)
        print('Loop iter. %s (%.1f %%)' % (n, percent_comp))

        #select for previous profile data
        temp = pwp_out['temp'][:, n - 1]
        sal = pwp_out['sal'][:, n - 1]
        dens = pwp_out['dens'][:, n - 1]
        uvel = pwp_out['uvel'][:, n - 1]
        vvel = pwp_out['vvel'][:, n - 1]

        ### Absorb solar radiation and FWF in surf layer ###

        #save initial T,S (may not be necessary)
        temp_old = pwp_out['temp'][0, n - 1]
        sal_old = pwp_out['sal'][0, n - 1]

        #update layer 1 temp and sal
        temp[0] = temp[0] + (q_in[n - 1] * absrb[0] -
                             q_out[n - 1]) * dt / (dz * dens[0] * cpw)
        sal[0] = sal[0] / (1 - emp[n - 1] * dt / dz)

        #check if temp is less than freezing point
        T_fz = sw.fp(sal_old, 1)  #why use sal_old? Need to recheck
        if temp[0] < T_fz:
            temp[0] = T_fz

        ### Absorb rad. at depth ###
        temp[1:] = temp[1:] + q_in[n - 1] * absrb[1:] * dt / (dz * dens[1:] *
                                                              cpw)

        ### compute new density ###
        dens = sw.dens0(sal, temp)

        ### relieve static instability ###
        temp, sal, dens, uvel, vvel = remove_si(temp, sal, dens, uvel, vvel)

        ### Compute MLD ###
        #find ml index
        ml_thresh = params['mld_thresh']
        mld_idx = np.flatnonzero(dens - dens[0] > ml_thresh)[
            0]  #finds the first index that exceed ML threshold

        #check to ensure that ML is defined
        assert mld_idx.size is not 0, "Error: Mixed layer depth is undefined."

        #get surf MLD
        mld = z[mld_idx]

        ### Rotate u,v do wind input, rotate again, apply mixing ###
        ang = -f * dt / 2
        uvel, vvel = rot(uvel, vvel, ang)
        du = (taux[n - 1] / (mld * dens[0])) * dt
        dv = (tauy[n - 1] / (mld * dens[0])) * dt
        uvel[:mld_idx] = uvel[:mld_idx] + du
        vvel[:mld_idx] = vvel[:mld_idx] + dv

        ### Apply drag to current ###
        #Original comment: this is a horrible parameterization of inertial-internal wave dispersion
        if params['drag_ON']:
            if ucon > 1e-10:
                uvel = uvel * (1 - dt * ucon)
                vvel = vvel * (1 - dt * ucon)
        else:
            if printDragWarning:
                print(
                    "Warning: Parameterization for inertial-internal wave dispersion is turned off."
                )
                printDragWarning = False

        uvel, vvel = rot(uvel, vvel, ang)

        ### Apply Bulk Richardson number instability form of mixing (as in PWP) ###
        if rb > 1e-5:
            temp, sal, dens, uvel, vvel = bulk_mix(temp, sal, dens, uvel, vvel,
                                                   g, rb, zlen, z, mld_idx)

        ### Do the gradient Richardson number instability form of mixing ###
        if rg > 0:
            temp, sal, dens, uvel, vvel = grad_mix(temp, sal, dens, uvel, vvel,
                                                   dz, g, rg, zlen)

        ### Apply diffusion ###
        if params['rkz'] > 0:
            temp = diffus(params['dstab'], zlen, temp)
            sal = diffus(params['dstab'], zlen, sal)
            dens = sw.dens0(sal, temp)
            uvel = diffus(params['dstab'], zlen, uvel)
            vvel = diffus(params['dstab'], zlen, vvel)

        ### update output profile data ###
        pwp_out['temp'][:, n] = temp
        pwp_out['sal'][:, n] = sal
        pwp_out['dens'][:, n] = dens
        pwp_out['uvel'][:, n] = uvel
        pwp_out['vvel'][:, n] = vvel
        pwp_out['mld'][n] = mld

        #do diagnostics
        if diagnostics == 1:
            phf.livePlots(pwp_out, n)

    return pwp_out
def test(fileout='python-test.txt'):
    r"""Copy of the Matlab test.

    Modifications: Phil Morgan
                   03-12-12. Lindsay Pender, Converted to ITS-90.
    """
    f = open(fileout, 'w')
    asterisks = '*' * 76

    f.write(asterisks)
    f.write('\n    TEST REPORT    ')
    f.write('\n')
    f.write('\n SEA WATER LIBRARY %s' % sw.__version__)
    f.write('\n')
    # Show some info about this Python.
    f.write('\npython version: %s' % sys.version)
    f.write('\n on %s computer %s' % (uname()[0], uname()[-1]))
    f.write('\n')
    f.write('\n')
    f.write(asctime(localtime()))
    f.write('\n')
    f.write('\n')

    # Test main module  ptmp.
    f.write('\n%s' % asterisks)
    f.write('\n**  TESTING MODULE: ptmp')
    f.write('\n**  and SUB-MODULE: adtg')
    f.write('\n%s' % asterisks)
    f.write('\n')
    f.write('\n')

    # Test 1 - data from Unesco 1983 p45.
    T = np.array([[0, 0, 0, 0, 0, 0], [10, 10, 10, 10, 10, 10],
                  [20, 20, 20, 20, 20, 20], [30, 30, 30, 30, 30, 30],
                  [40, 40, 40, 40, 40, 40]])

    T = T / 1.00024

    S = np.array([[25, 25, 25, 35, 35, 35], [25, 25, 25, 35, 35, 35],
                  [25, 25, 25, 35, 35, 35], [25, 25, 25, 35, 35, 35],
                  [25, 25, 25, 35, 35, 35]])

    P = np.array([[0, 5000, 10000, 0, 5000, 10000],
                  [0, 5000, 10000, 0, 5000, 10000],
                  [0, 5000, 10000, 0, 5000, 10000],
                  [0, 5000, 10000, 0, 5000, 10000],
                  [0, 5000, 10000, 0, 5000, 10000]])

    Pr = np.array([0, 0, 0, 0, 0, 0])

    UN_ptmp = np.array([[0, -0.3061, -0.9667, 0, -0.3856, -1.0974],
                        [10, 9.3531, 8.4684, 10, 9.2906, 8.3643],
                        [20, 19.0438, 17.9426, 20, 18.9985, 17.8654],
                        [30, 28.7512, 27.4353, 30, 28.7231, 27.3851],
                        [40, 38.4607, 36.9254, 40, 38.4498, 36.9023]])

    PT = sw.ptmp(S, T, P, Pr) * 1.00024

    # Display results.
    f.write('\n')
    f.write('\n%s' % asterisks)
    f.write('\nComparison of accepted values from UNESCO 1983 ')
    f.write('\n (Unesco Tech. Paper in Marine Sci. No. 44, p45)')
    f.write('\n%s' % asterisks)
    f.write('\n')

    m, n = S.shape  # TODO: so many loops there must be a better way.
    for icol in range(0, n):
        f.write('\n   Sal  Temp  Press     PTMP       ptmp')
        f.write('\n  (psu)  (C)   (db)     (C)          (C)\n')
        result = np.vstack(
            (S[:, icol], T[:, icol], P[:, icol], UN_ptmp[:, icol], PT[:,
                                                                      icol]))
        for iline in range(0, m):
            f.write(" %4.0f  %4.0f   %5.0f   %8.4f  %11.5f\n" %
                    tuple(result[:, iline]))

    # Test main module svan.
    f.write('\n%s' % asterisks)
    f.write('\n**  TESTING MODULE: svan')
    f.write('\n**  and SUB-MODULE: dens dens0 smow seck pden ptmp')
    f.write('\n%s' % asterisks)

    # Test data FROM: Unesco Tech. Paper in Marine Sci. No. 44, p22.
    s = np.array([0, 0, 0, 0, 35, 35, 35, 35])
    p = np.array([0, 10000, 0, 10000, 0, 10000, 0, 10000])
    t = np.array([0, 0, 30, 30, 0, 0, 30, 30]) / 1.00024

    UN_svan = np.array(
        [2749.54, 2288.61, 3170.58, 3147.85, 0.0, 0.00, 607.14, 916.34])

    SVAN = sw.svan(s, t, p)

    # DISPLAY RESULTS
    f.write('\n')
    f.write('\n%s' % asterisks)
    f.write('\n')
    f.write('\nComparison of accepted values from UNESCO 1983')
    f.write('\n (Unesco Tech. Paper in Marine Sci. No. 44, p22)')
    f.write('\n%s' % asterisks)
    f.write('\n')
    f.write('\n   Sal  Temp  Press        SVAN        svan')
    f.write('\n  (psu)  (C)   (db)    (1e-8*m3/kg)  (1e-8*m3/kg)\n')
    result = np.vstack([s, t, p, UN_svan, 1e+8 * SVAN])
    for iline in range(0, len(SVAN)):
        f.write(" %4.0f  %4.0f   %5.0f   %11.2f    %11.3f\n" %
                tuple(result[:, iline]))

    # Test main module salt.
    f.write('\n%s' % asterisks)
    f.write('\n**  TESTING MODULE: salt')
    f.write('\n**  and SUB-MODULE: salrt salrp sals')
    f.write('\n%s' % asterisks)
    f.write('\n')

    # Test 1 - data from Unesco 1983 p9.
    R = np.array([1, 1.2, 0.65])  # cndr = R.
    T = np.array([15, 20, 5]) / 1.00024
    P = np.array([0, 2000, 1500])
    #Rt   = np.array([  1, 1.0568875, 0.81705885])
    UN_S = np.array([35, 37.245628, 27.995347])

    S = sw.salt(R, T, P)

    # Display results.
    f.write('\n')
    f.write('\n%s' % asterisks)
    f.write('\nComparison of accepted values from UNESCO 1983 ')
    f.write('\n(Unesco Tech. Paper in Marine Sci. No. 44, p9)')
    f.write('\n%s' % asterisks)
    f.write('\n')

    f.write('\n   Temp    Press       R              S           salt')
    f.write('\n   (C)     (db)    (no units)       (psu)          (psu)\n')
    table = np.vstack([T, P, R, UN_S, S])
    m, n = table.shape
    for iline in range(0, n):
        f.write(" %4.0f       %4.0f  %8.2f      %11.6f  %14.7f\n" %
                tuple(table[:, iline]))

    # Test main module cndr.
    f.write('\n%s' % asterisks)
    f.write('\n**  TESTING MODULE: cndr')
    f.write('\n**  and SUB-MODULE: salds')
    f.write('\n%s' % asterisks)

    # Test 1 - data from Unesco 1983 p9.
    T = np.array([0, 10, 0, 10, 10, 30]) / 1.00024
    P = np.array([0, 0, 1000, 1000, 0, 0])
    S = np.array([25, 25, 25, 25, 40, 40])
    UN_R = np.array(
        [0.498088, 0.654990, 0.506244, 0.662975, 1.000073, 1.529967])
    R = sw.cndr(S, T, P)

    # Display results.
    f.write('\n')
    f.write('\n%s' % asterisks)
    f.write('\nComparison of accepted values from UNESCO 1983 ')
    f.write('\n (Unesco Tech. Paper in Marine Sci. No. 44, p14)')
    f.write('\n%s' % asterisks)
    f.write('\n')
    f.write('\n')

    f.write('\n   Temp    Press       S            cndr         cndr')
    f.write('\n   (C)     (db)      (psu)        (no units)    (no units)\n')
    table = np.vstack([T, P, S, UN_R, R])
    m, n = table.shape
    for iline in range(0, n):
        f.write(" %4.0f       %4.0f   %8.6f   %11.6f  %14.8f\n" %
                tuple(table[:, iline]))

    # Test main module depth.
    f.write('\n%s' % asterisks)
    f.write('\n**  TESTING MODULE: depth')
    f.write('\n%s' % asterisks)

    # Test data - matrix "pressure", vector "lat"  Unesco 1983 data p30.
    lat = np.array([0, 30, 45, 90])
    P = np.array([[500, 500, 500, 500], [5000, 5000, 5000, 5000],
                  [10000, 10000, 10000, 10000]])

    UN_dpth = np.array([[496.65, 496.00, 495.34, 494.03],
                        [4915.04, 4908.56, 4902.08, 4889.13],
                        [9725.47, 9712.65, 9699.84, 9674.23]])

    dpth = sw.dpth(P, lat)

    # Display results.
    f.write('\n')
    f.write('\n%s' % asterisks)
    f.write('\nComparison of accepted values from Unesco 1983 ')
    f.write('\n(Unesco Tech. Paper in Marine Sci. No. 44, p28)')
    f.write('\n%s' % asterisks)
    f.write('\n')

    f.write('\n')
    for irow in range(0, 3):
        f.write('\n    Lat       Press     DPTH      dpth')
        f.write('\n  (degree)    (db)     (meter)    (meter)\n')
        table = np.vstack([lat, P[irow, :], UN_dpth[irow, :], dpth[irow, :]])
        m, n = table.shape
        for iline in range(0, n):
            f.write("  %6.3f     %6.0f   %8.2f   %8.3f\n" %
                    tuple(table[:, iline]))

    # Test main module fp.
    f.write('\n%s' % asterisks)
    f.write('\n**  TESTING MODULE: fp')
    f.write('\n%s' % asterisks)

    # Test 1 - UNESCO data p.30.
    S = np.array([[5, 10, 15, 20, 25, 30, 35, 40],
                  [5, 10, 15, 20, 25, 30, 35, 40]])

    P = np.array([[0, 0, 0, 0, 0, 0, 0, 0],
                  [500, 500, 500, 500, 500, 500, 500, 500]])

    UN_fp = np.array(
        [[-0.274, -0.542, -0.812, -1.083, -1.358, -1.638, -1.922, -2.212],
         [-0.650, -0.919, -1.188, -1.460, -1.735, -2.014, -2.299, -2.589]])

    FP = sw.fp(S, P)

    # Display results.
    f.write('\n')
    f.write('\n%s' % asterisks)
    f.write('\nComparison of accepted values from UNESCO 1983 ')
    f.write('\n (Unesco Tech. Paper in Marine Sci. No. 44, p30)')
    f.write('\n%s' % asterisks)
    f.write('\n')

    f.write('\n')
    for irow in range(0, 2):
        f.write('\n   Sal   Press      fp        fp')
        f.write('\n  (psu)   (db)      (C)        (C)\n')
        table = np.vstack(
            [S[irow, :], P[irow, :], UN_fp[irow, :], FP[irow, :]])
        m, n = table.shape
        for iline in range(0, n):
            f.write(" %4.0f   %5.0f   %8.3f  %11.4f\n" %
                    tuple(table[:, iline]))

    # Test main module cp.
    f.write('\n%s' % asterisks)
    f.write('\n**  TESTING MODULE: cp')
    f.write('\n%s' % asterisks)

    # Test 1.
    # Data from Pond and Pickard Intro. Dynamical Oceanography 2nd ed. 1986
    T = np.array([[0, 0, 0, 0, 0, 0], [10, 10, 10, 10, 10, 10],
                  [20, 20, 20, 20, 20, 20], [30, 30, 30, 30, 30, 30],
                  [40, 40, 40, 40, 40, 40]]) / 1.00024

    S = np.array([[25, 25, 25, 35, 35, 35], [25, 25, 25, 35, 35, 35],
                  [25, 25, 25, 35, 35, 35], [25, 25, 25, 35, 35, 35],
                  [25, 25, 25, 35, 35, 35]])

    P = np.array([[0, 5000, 10000, 0, 5000, 10000],
                  [0, 5000, 10000, 0, 5000, 10000],
                  [0, 5000, 10000, 0, 5000, 10000],
                  [0, 5000, 10000, 0, 5000, 10000],
                  [0, 5000, 10000, 0, 5000, 10000]])

    UN_cp = np.array([[4048.4, 3896.3, 3807.7, 3986.5, 3849.3, 3769.1],
                      [4041.8, 3919.6, 3842.3, 3986.3, 3874.7, 3804.4],
                      [4044.8, 3938.6, 3866.7, 3993.9, 3895.0, 3828.3],
                      [4049.1, 3952.0, 3883.0, 4000.7, 3909.2, 3844.3],
                      [4051.2, 3966.1, 3905.9, 4003.5, 3923.9, 3868.3]])

    CP = sw.cp(S, T, P)

    # Display results.
    f.write('\n')
    f.write('\n%s' % asterisks)
    f.write('\nComparison of accepted values from UNESCO 1983 ')
    f.write('\n (Unesco Tech. Paper in Marine Sci. No. 44, p37)')
    f.write('\n%s' % asterisks)
    f.write('\n')

    m, n = S.shape
    f.write('\n')
    for icol in range(0, n):
        f.write('\n   Sal  Temp  Press      Cp        cp')
        f.write('\n  (psu)  (C)   (db)    (J/kg.C)   (J/kg.C)\n')
        result = np.vstack(
            [S[:, icol], T[:, icol], P[:, icol], UN_cp[:, icol], CP[:, icol]])
        for iline in range(0, m):
            f.write(" %4.0f  %4.0f   %5.0f   %8.1f  %11.2f\n" %
                    tuple(result[:, iline]))

    # Test main module svel.
    f.write('\n%s' % asterisks)
    f.write('\n**  TESTING MODULE: svel')
    f.write('\n%s' % asterisks)

    # Test 1.
    # Data from Pond and Pickard Intro. Dynamical Oceanography 2nd ed. 1986
    T = np.array([[0, 0, 0, 0, 0, 0], [10, 10, 10, 10, 10, 10],
                  [20, 20, 20, 20, 20, 20], [30, 30, 30, 30, 30, 30],
                  [40, 40, 40, 40, 40, 40]]) / 1.00024

    S = np.array([[25, 25, 25, 35, 35, 35], [25, 25, 25, 35, 35, 35],
                  [25, 25, 25, 35, 35, 35], [25, 25, 25, 35, 35, 35],
                  [25, 25, 25, 35, 35, 35]])

    P = np.array([[0, 5000, 10000, 0, 5000, 10000],
                  [0, 5000, 10000, 0, 5000, 10000],
                  [0, 5000, 10000, 0, 5000, 10000],
                  [0, 5000, 10000, 0, 5000, 10000],
                  [0, 5000, 10000, 0, 5000, 10000]])

    UN_svel = np.array([[1435.8, 1520.4, 1610.4, 1449.1, 1534.0, 1623.2],
                        [1477.7, 1561.3, 1647.4, 1489.8, 1573.4, 1659.0],
                        [1510.3, 1593.6, 1676.8, 1521.5, 1604.5, 1687.2],
                        [1535.2, 1619.0, 1700.6, 1545.6, 1629.0, 1710.1],
                        [1553.4, 1638.0, 1719.2, 1563.2, 1647.3, 1727.8]])

    SVEL = sw.svel(S, T, P)

    # Display results.
    f.write('\n')
    f.write('\n%s' % asterisks)
    f.write('\nComparison of accepted values from UNESCO 1983 ')
    f.write('\n (Unesco Tech. Paper in Marine Sci. No. 44, p50)')
    f.write('\n%s' % asterisks)
    f.write('\n')

    m, n = SVEL.shape
    f.write('\n')
    for icol in range(0, n):
        f.write('\n   Sal  Temp  Press     SVEL       svel')
        f.write('\n  (psu)  (C)   (db)     (m/s)       (m/s)\n')

        result = np.vstack([
            S[:, icol], T[:, icol], P[:, icol], UN_svel[:, icol], SVEL[:, icol]
        ])
        for iline in range(0, m):
            f.write(" %4.0f  %4.0f   %5.0f   %8.1f  %11.3f\n" %
                    tuple(result[:, iline]))

    # Test submodules alpha beta aonb.
    f.write('\n%s' % asterisks)
    f.write('\n**  and SUB-MODULE: alpha beta aonb')
    f.write('\n%s' % asterisks)

    # Data from McDouogall 1987.
    s = 40
    PT = 10
    p = 4000
    beta_lit = 0.72088e-03
    aonb_lit = 0.34763
    alpha_lit = aonb_lit * beta_lit

    BETA = sw.beta(s, PT, p, pt=True)
    ALPHA = sw.alpha(s, PT, p, pt=True)
    AONB = sw.aonb(s, PT, p, pt=True)

    # Display results.
    f.write('\n')
    f.write('\n%s' % asterisks)
    f.write('\nComparison of accepted values from MCDOUGALL 1987 ')
    f.write('\n%s' % asterisks)
    f.write('\n')
    f.write('\n')

    f.write('\n   Sal  Temp  Press     BETA       beta')
    f.write('\n  (psu)  (C)   (db)   (psu^-1)     (psu^-1)\n')
    table = np.hstack([s, PT, p, beta_lit, BETA])
    f.write(" %4.0f  %4.0f   %5.0f   %11.4e  %11.5e\n" % tuple(table))

    f.write('\n   Sal  Temp  Press     AONB       aonb')
    f.write('\n  (psu)  (C)   (db)   (psu C^-1)   (psu C^-1)\n')
    table = np.hstack([s, PT, p, aonb_lit, AONB])
    f.write(" %4.0f  %4.0f   %5.0f   %8.5f  %11.6f\n" % tuple(table))

    f.write('\n   Sal  Temp  Press     ALPHA       alpha')
    f.write('\n  (psu)  (C)   (db)    (psu^-1)     (psu^-1)\n')
    table = np.hstack([s, PT, p, alpha_lit, ALPHA])
    f.write(" %4.0f  %4.0f   %5.0f   %11.4e  %11.4e\n" % tuple(table))

    # Test main moduleS  satO2 satN2 satAr.
    f.write('\n%s' % asterisks)
    f.write('\n**  TESTING MODULE: satO2 satN2 satAr')
    f.write('\n%s' % asterisks)
    f.write('\n')

    # Data from Weiss 1970.
    T = np.array([[-1, -1], [10, 10], [20, 20], [40, 40]]) / 1.00024

    S = np.array([[20, 40], [20, 40], [20, 40], [20, 40]])

    lit_O2 = np.array([[9.162, 7.984], [6.950, 6.121], [5.644, 5.015],
                       [4.050, 3.656]])

    lit_N2 = np.array([[16.28, 14.01], [12.64, 11.01], [10.47, 9.21],
                       [7.78, 6.95]])

    lit_Ar = np.array([[0.4456, 0.3877], [0.3397, 0.2989], [0.2766, 0.2457],
                       [0.1986, 0.1794]])

    O2 = sw.satO2(S, T)
    N2 = sw.satN2(S, T)
    Ar = sw.satAr(S, T)

    # Display results.
    f.write('\n')
    f.write('\n%s' % asterisks)
    f.write('\nComparison of accepted values from Weiss, R.F. 1979 ')
    f.write('\n"The solubility of nitrogen, oxygen and argon in water')
    f.write('\n and seawater." Deep-Sea Research., 1970, Vol 17, pp721-735.')
    f.write('\n%s' % asterisks)
    f.write('\n')

    m, n = S.shape
    f.write('\n')
    for icol in range(0, n):
        f.write('\n   Sal  Temp      O2         satO2')
        f.write('\n  (psu)  (C)      (ml/l)     (ml/l)\n')
        result = np.vstack(
            [S[:, icol], T[:, icol], lit_O2[:, icol], O2[:, icol]])
        for iline in range(0, m):
            f.write(" %4.0f  %4.0f    %8.2f   %9.3f\n" %
                    tuple(result[:, iline]))

    for icol in range(0, n):
        f.write('\n   Sal  Temp      N2         satN2')
        f.write('\n  (psu)  (C)      (ml/l)     (ml/l)\n')
        result = np.vstack(
            [S[:, icol], T[:, icol], lit_N2[:, icol], N2[:, icol]])
        for iline in range(0, m):
            f.write(" %4.0f  %4.0f    %8.2f  %9.3f\n" %
                    tuple(result[:, iline]))

    for icol in range(0, n):
        f.write('\n   Sal  Temp      Ar         satAr')
        f.write('\n  (psu)  (C)      (ml/l)     (ml/l)\n')
        result = np.vstack(
            [S[:, icol], T[:, icol], lit_Ar[:, icol], Ar[:, icol]])
        for iline in range(0, m):
            f.write(" %4.0f  %4.0f     %8.4f  %9.4f\n" %
                    tuple(result[:, iline]))
Пример #3
0
def pwpgo(forcing, params, pwp_out, diagnostics):

    """
    This is the main driver of the PWP module.
    """
    
    #unpack some of the variables (I could probably do this more elegantly)
    q_in = forcing['q_in']
    q_out = forcing['q_out']
    emp = forcing['emp']
    taux = forcing['tx']
    tauy = forcing['ty']
    absrb = forcing['absrb']
    
    z = pwp_out['z']
    dz = pwp_out['dz']
    dt = pwp_out['dt']
    zlen = len(z)
    tlen = len(pwp_out['time'])
    
    rb = params['rb']
    rg = params['rg']
    f = params['f']
    cpw = params['cpw']
    g = params['g']
    ucon = params['ucon']
    
    for n in xrange(1,tlen):
        print 'Loop iter. %s' %n
        
        #select for previous profile data
        temp = pwp_out['temp'][:, n-1]
        sal = pwp_out['sal'][:, n-1]
        dens = pwp_out['dens'][:, n-1]
        uvel = pwp_out['uvel'][:, n-1]
        vvel = pwp_out['vvel'][:, n-1]
    
        ### Absorb solar radiation and FWF in surf layer ###
        
        #save initial T,S (may not be necessary)
        temp_old = pwp_out['temp'][0, n-1]
        sal_old = pwp_out['sal'][0, n-1] 
    
        #update layer 1 temp and sal
        temp[0] = temp[0] + (q_in[n-1]*absrb[0]-q_out[n-1])*dt/(dz*dens[0]*cpw)
        sal[0] = sal[0]/(1-emp[n-1]*dt/dz)
    
        #check if temp is less than freezing point
        T_fz = sw.fp(sal_old, 1) #why use sal_old? Need to recheck
        if temp[0] < T_fz:
            temp[0] = T_fz
        
        ### Absorb rad. at depth ###
        temp[1:] = temp[1:] + q_in[n-1]*absrb[1:]*dt/(dz*dens[1:]*cpw)
    
        ### compute new density ###
        dens = sw.dens0(sal, temp)
    
        ### relieve static instability ###
        temp, sal, dens, uvel, vvel = remove_si(temp, sal, dens, uvel, vvel)
    
        ### Compute MLD ###       
        #find ml index
        ml_thresh = params['mld_thresh']
        ml_idx = np.flatnonzero(np.diff(dens)>ml_thresh)[0] #finds the first index that exceed ML threshold
        ml_idx = ml_idx+1
    
        #check to ensure that ML is defined
        assert ml_idx.size is not 0, "Error: Mixed layer depth is undefined."
    
        #get surf MLD
        mld = z[ml_idx]    
        
        ### Rotate u,v do wind input, rotate again, apply mixing ###
        ang = -f*dt/2
        uvel, vvel = rot(uvel, vvel, ang)
        du = (taux[n-1]/(mld*dens[0]))*dt
        dv = (tauy[n-1]/(mld*dens[0]))*dt
        uvel[:ml_idx] = uvel[:ml_idx]+du
        vvel[:ml_idx] = vvel[:ml_idx]+dv
    

        ### Apply drag to current ###
        #Original comment: this is a horrible parameterization of inertial-internal wave dispersion
        if ucon > 1e-10:
            uvel = uvel*(1-dt*ucon) 
            vvel = vvel*(1-dt*ucon) 
    
        uvel, vvel = rot(uvel, vvel, ang)
    
        ### Apply Bulk Richardson number instability form of mixing (as in PWP) ###
        if rb > 1e-5:
            temp, sal, dens, uvel, vvel = bulk_mix(temp, sal, dens, uvel, vvel, dz, g, rb, zlen, z, ml_idx)
    
        ### Do the gradient Richardson number instability form of mixing ###
        if rg > 0:
            temp, sal, dens, uvel, vvel = grad_mix(temp, sal, dens, uvel, vvel, dz, g, rg, zlen)
            
        
        ### Apply diffusion ###
        if params['rkz'] > 0:
            temp = diffus(params['dstab'], zlen, temp) 
            sal = diffus(params['dstab'], zlen, sal) 
            dens = sw.dens0(sal, temp)
            uvel = diffus(params['dstab'], zlen, uvel)
            vvel = diffus(params['dstab'], zlen, vvel)
        
        ### update output profile data ###
        pwp_out['temp'][:, n] = temp 
        pwp_out['sal'][:, n] = sal 
        pwp_out['dens'][:, n] = dens
        pwp_out['uvel'][:, n] = uvel
        pwp_out['vvel'][:, n] = vvel
        pwp_out['mld'][n] = mld
    
        #do diagnostics
        if diagnostics==1:
            phf.livePlots(pwp_out, n)
        
    return pwp_out
Пример #4
0
def model_timestep(T,
                   S,
                   U,
                   V,
                   z,
                   I,
                   L,
                   E,
                   P,
                   tau_x,
                   tau_y,
                   dt,
                   nabla_b=None,
                   Ekman_Q_flux=None,
                   use_static_stability=True,
                   use_mixed_layer_stability=True,
                   use_shear_stability=True,
                   use_Ekman_flux=False,
                   use_MLI=False,
                   tracer=None,
                   vert_diffusivity=None,
                   verbose=False,
                   I1=0.62,
                   I2=None,
                   lambda1=.6,
                   lambda2=20,
                   T0=0,
                   S0=34,
                   rho0=None,
                   alpha=None,
                   beta=None,
                   f=sw.f(40),
                   return_MLD=False,
                   advection=False,
                   l_poly=1e4,
                   phi=5e-2,
                   T_cdw=1,
                   S_cdw=34.5,
                   shelf_thick=350,
                   debug=False,
                   T_out=-1,
                   S_out=33.8,
                   return_dTdS=False,
                   return_TSrelax=False,
                   return_vel=False):

    # define initial variables
    c = 4218  # heat capacity (J kg^-1 K^-1)
    if I2 is None:
        I2 = 1 - I1
    if I1 + I2 != 1:
        raise Exception('Shortwave insolation amplitudes need to sum to unity')
    if rho0 is None:
        rho0 = sw.dens(S0, T0, 0)
    if alpha is None:
        alpha = -sw.alpha(
            S0, T0, 0
        ) * rho0  # multiply by rho to fit into nice equation of state (see get_rho function)
    if beta is None:
        beta = sw.beta(
            S0, T0, 0
        ) * rho0  # # multiply by rho to fit into nice equation of state (see get_rho function)

    dz = z[1] - z[0]

    if use_Ekman_flux and Ekman_Q_flux is None:
        raise Exception(
            'Using Ekman-induced buoyacy flux but no buoyancy gradients were given.'
        )
    if use_MLI and MLI_flux is None:
        raise Exception('Using MLI but no horizontal buoyancy gradient given.')

    T = T.copy()
    S = S.copy()
    U = U.copy()
    V = V.copy()
    # so don't overwrite data
    if tracer is not None:
        tracer = tracer.copy()

    # make initial heat profile
    I_profile = -I / dz * (
        I1 * np.exp(-z / lambda1) *
        (np.exp(-dz / 2 / lambda1) - np.exp(dz / 2 / lambda1)) +
        I2 * np.exp(-z / lambda2) *
        (np.exp(-dz / 2 / lambda2) - np.exp(dz / 2 / lambda2)))
    L_profile = np.zeros(len(z))
    L_profile[0] = L / dz
    Q_profile = I_profile + L_profile

    if use_Ekman_flux:
        A = 0.1  # eddy viscosity m^2 s^-1
        z_Ek = np.sqrt(A / np.abs(f))
        if verbose:
            print('Using Ekman depth of %d m' % z_Ek)
        z_Ek_ind = np.where(z > z_Ek)[0][0]
        Q_Ek_profile = np.zeros(len(z))
        Q_Ek_profile[0:z_Ek_ind] = Ekman_Q_flux / z_Ek * dz
        Q_profile += Q_Ek_profile

    if advection == True:

        Tf = sw.fp(S, z)
        #freezing temperature for the column using salinity and pressure
        Tf_mean = np.mean(T[51::] - Tf[51::])
        #find temperature of no motion
        v_profile = ((T - Tf) - Tf_mean) * phi
        #create the velocity profile
        v_profile[0:50] = 0
        #there is no mean advection in the top 25 m
        h_interface = (np.abs(v_profile[51::] - 0)).argmin() + 50
        #find the depth of the point of no motion

        inv_time_length = np.zeros(shape=len(z))
        inv_time_length = np.absolute(v_profile) / l_poly
        #create 1/tau

        #Create the relaxation profiles for S and T
        T_relax = np.zeros(shape=len(z))
        T_relax = np.tanh((z - z[h_interface]) /
                          100) * (T_cdw - T_out) / 2 + (T_cdw + T_out) / 2
        T_relax[h_interface:len(z)] = T_relax[h_interface:len(z)] + 0.6 * (
            (z[h_interface:len(z)] - z[h_interface]) / 1000)

        S_relax = np.zeros(shape=len(z))
        S_relax = np.tanh((z - z[h_interface]) /
                          100) * (S_cdw - S_out) / 2 + (S_cdw + S_out) / 2
        S_relax[h_interface:len(z)] = S_relax[h_interface:len(z)] + 0.25 * (
            (z[h_interface:len(z)] - z[h_interface]) / 1000)

    # update temperature
    if advection == False:
        dTdt = Q_profile / (c * rho0)
    else:
        dTdt = Q_profile / (c * rho0) + inv_time_length * (T_relax - T)

        if debug == True:
            print('inv_time_length*(T_relax-T): ',
                  inv_time_length[0:100] * (T_relax[0:100] - T[0:100]))

    if use_MLI:
        mld_ind = get_mld_ind(T, S, U, V, z)
        mld = z[mld_ind]
        C_e = 0.06
        g = 9.81
        # gravitational acceleration (m s^-2)
        c = 4218
        # heat capacity (J kg^-1 degC^-1
        MLI_dTdt = -C_e * nabla_b**2 * mld**2 * rho0 / (np.abs(f) * alpha * g)
        vert_profile = 4 / mld * (1 - 2 * z / mld) * (
            16 + 10 *
            (1 - 2 * z / mld)**2) / 21  # this is vertical derivative of mu(z)
        vert_profile[mld_ind::] = 0
        vert_profile[0:mld_ind] -= np.mean(
            vert_profile[0:mld_ind]
        )  # just to ensure that no heat added to system
        dTdt += MLI_dTdt * vert_profile

    T += dTdt * dt

    # update salinity
    dSdt_0 = S[0] * (E - P) / dz / 1000
    S[0] += dSdt_0 * dt
    if advection == True:
        dSdt = inv_time_length * (S_relax - S)
        S += dSdt * dt

    if use_MLI:

        rho = get_rho(T, S, T0, S0, rho0, alpha, beta)
        half_mld_ind = int(mld_ind / 2)
        if np.any(np.diff(rho[half_mld_ind::]) < 0):
            if verbose:
                print(
                    'Need to homogenize discontinuity at base of previous mixed layer'
                )
            # get rid of discontinuity at base of previous mixed layer
            # homogenize the region of water from mld/2 to z*
            # z* is the shallowest value (> mld/2) such that the homogenized rho <= rho(z*)
            zstar_ind = mld_ind.copy()
            while np.mean(rho[half_mld_ind:zstar_ind]) >= rho[zstar_ind]:
                if verbose:
                    print('Deepening z*...')
                zstar_ind += 1
            T[half_mld_ind:zstar_ind] = np.mean(T[half_mld_ind:zstar_ind])
            S[half_mld_ind:zstar_ind] = np.mean(S[half_mld_ind:zstar_ind])
            if tracer is not None:
                tracer[:, half_mld_ind:zstar_ind] = np.atleast_2d(
                    np.mean(tracer[:, half_mld_ind:zstar_ind], axis=1)).T
        elif verbose:
            print('No need to homogenize base of previous mixed layer')

    # update momentum
    # first rotate momentum halfway
    angle = -f * dt / 2  # currently assuming this is in rad
    U, V = rotate(angle, U, V)
    # then add wind stress
    mld_ind = get_mld_ind(T, S, U, V, z)
    mld = z[mld_ind]
    U[0:mld_ind] += tau_x / mld / rho0 * dz * dt
    V[0:mld_ind] += tau_y / mld / rho0 * dz * dt
    # then rotate second half
    U, V = rotate(angle, U, V)

    if use_static_stability:
        T, S, U, V = static_stability(T, S, U, V, z, T0, S0, rho0, alpha, beta)
        if get_mld_ind(T, S, U, V, z) == (T.size - 1):

            use_mixed_layer_stability = False
            use_shear_stability = False
    if use_mixed_layer_stability:
        T, S, U, V = mixed_layer_stability(T,
                                           S,
                                           U,
                                           V,
                                           z,
                                           T0,
                                           S0,
                                           rho0,
                                           alpha,
                                           beta,
                                           verbose=verbose)
    if use_shear_stability:
        T, S, U, V = shear_stability(T,
                                     S,
                                     U,
                                     V,
                                     z,
                                     T0,
                                     S0,
                                     rho0,
                                     alpha,
                                     beta,
                                     verbose=verbose)

    if vert_diffusivity is not None:
        dTdt_vd = np.zeros(len(T))
        dTdt_vd[1:-1] = np.diff(np.diff(T)) / dz**2
        T += vert_diffusivity * dTdt_vd * dt

        dSdt_vd = np.zeros(len(S))
        dSdt_vd[1:-1] = np.diff(np.diff(S)) / dz**2
        S += vert_diffusivity * dSdt_vd * dt

        dUdt = np.zeros(len(U))
        dUdt[1:-1] = np.diff(np.diff(U)) / dz**2
        U += vert_diffusivity * dUdt * dt

        dVdt = np.zeros(len(V))
        dVdt[1:-1] = np.diff(np.diff(V)) / dz**2
        V += vert_diffusivity * dVdt * dt

        if tracer is not None:
            dtdt = np.zeros(shape=tracer.shape)
            dtdt[:, 1:-1] = np.diff(np.diff(tracer, axis=1), axis=1) / dz**2
            tracer += vert_diffusivity * dtdt * dt

    return_variables = (T, S, U, V)
    if tracer is not None:
        return_variables += (tracer, )
    if return_MLD:
        return_variables += (get_mld(T, S, U, V, z), )
    if return_dTdS:
        return_variables += (
            dTdt,
            dSdt,
        )
    if return_TSrelax:
        return_variables += (
            T_relax,
            S_relax,
        )
    if return_vel:
        return_variables += (v_profile, )
    return return_variables
Пример #5
0
def test(fileout='python-test.txt'):
    r"""Copy of the Matlab test.

    Modifications: Phil Morgan
                   03-12-12. Lindsay Pender, Converted to ITS-90.
    """
    f = open(fileout, 'w')
    asterisks = '*' * 76

    f.write(asterisks)
    f.write('\n    TEST REPORT    ')
    f.write('\n')
    f.write('\n SEA WATER LIBRARY %s' % sw.__version__)
    f.write('\n')
    # Show some info about this Python.
    f.write('\npython version: %s' % sys.version)
    f.write('\n on %s computer %s' % (uname()[0], uname()[-1]))
    f.write('\n')
    f.write('\n')
    f.write(asctime(localtime()))
    f.write('\n')
    f.write('\n')

    # Test main module  ptmp.
    f.write('\n%s' % asterisks)
    f.write('\n**  TESTING MODULE: ptmp')
    f.write('\n**  and SUB-MODULE: adtg')
    f.write('\n%s' % asterisks)
    f.write('\n')
    f.write('\n')

    # Test 1 - data from Unesco 1983 p45.
    T = np.array([[0,  0,  0,  0,  0,  0],
                  [10, 10, 10, 10, 10, 10],
                  [20, 20, 20, 20, 20, 20],
                  [30, 30, 30, 30, 30, 30],
                  [40, 40, 40, 40, 40, 40]])

    T = T / 1.00024

    S = np.array([[25, 25, 25, 35, 35, 35],
                  [25, 25, 25, 35, 35, 35],
                  [25, 25, 25, 35, 35, 35],
                  [25, 25, 25, 35, 35, 35],
                  [25, 25, 25, 35, 35, 35]])

    P = np.array([[0, 5000, 10000, 0, 5000, 10000],
                  [0, 5000, 10000, 0, 5000, 10000],
                  [0, 5000, 10000, 0, 5000, 10000],
                  [0, 5000, 10000, 0, 5000, 10000],
                  [0, 5000, 10000, 0, 5000, 10000]])

    Pr = np.array([0, 0, 0, 0, 0, 0])

    UN_ptmp = np.array([[0, -0.3061, -0.9667,  0, -0.3856, -1.0974],
                        [10,  9.3531,  8.4684, 10,  9.2906,  8.3643],
                        [20, 19.0438, 17.9426, 20, 18.9985, 17.8654],
                        [30, 28.7512, 27.4353, 30, 28.7231, 27.3851],
                        [40, 38.4607, 36.9254, 40, 38.4498, 36.9023]])

    PT = sw.ptmp(S, T, P, Pr) * 1.00024

    # Display results.
    f.write('\n')
    f.write('\n%s' % asterisks)
    f.write('\nComparison of accepted values from UNESCO 1983 ')
    f.write('\n (Unesco Tech. Paper in Marine Sci. No. 44, p45)')
    f.write('\n%s' % asterisks)
    f.write('\n')

    m, n = S.shape  # TODO: so many loops there must be a better way.
    for icol in range(0, n):
        f.write('\n   Sal  Temp  Press     PTMP       ptmp')
        f.write('\n  (psu)  (C)   (db)     (C)          (C)\n')
        result = np.vstack((S[:, icol], T[:, icol], P[:, icol],
                            UN_ptmp[:, icol], PT[:, icol]))
        for iline in range(0, m):
            f.write(" %4.0f  %4.0f   %5.0f   %8.4f  %11.5f\n" %
                    tuple(result[:, iline]))

    # Test main module svan.
    f.write('\n%s' % asterisks)
    f.write('\n**  TESTING MODULE: svan')
    f.write('\n**  and SUB-MODULE: dens dens0 smow seck pden ptmp')
    f.write('\n%s' % asterisks)

    # Test data FROM: Unesco Tech. Paper in Marine Sci. No. 44, p22.
    s = np.array([0,     0,  0,     0, 35,    35, 35,   35])
    p = np.array([0, 10000,  0, 10000,  0, 10000,  0, 10000])
    t = np.array([0,     0, 30,    30,  0,     0, 30,    30]) / 1.00024

    UN_svan = np.array([2749.54, 2288.61, 3170.58, 3147.85,
                        0.0,    0.00,  607.14,  916.34])

    SVAN = sw.svan(s, t, p)

    # DISPLAY RESULTS
    f.write('\n')
    f.write('\n%s' % asterisks)
    f.write('\n')
    f.write('\nComparison of accepted values from UNESCO 1983')
    f.write('\n (Unesco Tech. Paper in Marine Sci. No. 44, p22)')
    f.write('\n%s' % asterisks)
    f.write('\n')
    f.write('\n   Sal  Temp  Press        SVAN        svan')
    f.write('\n  (psu)  (C)   (db)    (1e-8*m3/kg)  (1e-8*m3/kg)\n')
    result = np.vstack([s, t, p, UN_svan, 1e+8 * SVAN])
    for iline in range(0, len(SVAN)):
        f.write(" %4.0f  %4.0f   %5.0f   %11.2f    %11.3f\n" %
                tuple(result[:, iline]))

    # Test main module salt.
    f.write('\n%s' % asterisks)
    f.write('\n**  TESTING MODULE: salt')
    f.write('\n**  and SUB-MODULE: salrt salrp sals')
    f.write('\n%s' % asterisks)
    f.write('\n')

    # Test 1 - data from Unesco 1983 p9.
    R = np.array([1, 1.2, 0.65])  # cndr = R.
    T = np.array([15, 20, 5]) / 1.00024
    P = np.array([0, 2000, 1500])
    #Rt   = np.array([  1, 1.0568875, 0.81705885])
    UN_S = np.array([35, 37.245628,  27.995347])

    S = sw.salt(R, T, P)

    # Display results.
    f.write('\n')
    f.write('\n%s' % asterisks)
    f.write('\nComparison of accepted values from UNESCO 1983 ')
    f.write('\n(Unesco Tech. Paper in Marine Sci. No. 44, p9)')
    f.write('\n%s' % asterisks)
    f.write('\n')

    f.write('\n   Temp    Press       R              S           salt')
    f.write('\n   (C)     (db)    (no units)       (psu)          (psu)\n')
    table = np.vstack([T, P, R, UN_S, S])
    m, n = table.shape
    for iline in range(0, n):
        f.write(" %4.0f       %4.0f  %8.2f      %11.6f  %14.7f\n" %
                tuple(table[:, iline]))

    # Test main module cndr.
    f.write('\n%s' % asterisks)
    f.write('\n**  TESTING MODULE: cndr')
    f.write('\n**  and SUB-MODULE: salds')
    f.write('\n%s' % asterisks)

    # Test 1 - data from Unesco 1983 p9.
    T = np.array([0, 10, 0, 10, 10, 30]) / 1.00024
    P = np.array([0,  0, 1000, 1000, 0, 0])
    S = np.array([25, 25, 25, 25, 40, 40])
    UN_R = np.array([0.498088, 0.654990, 0.506244, 0.662975, 1.000073,
                     1.529967])
    R = sw.cndr(S, T, P)

    # Display results.
    f.write('\n')
    f.write('\n%s' % asterisks)
    f.write('\nComparison of accepted values from UNESCO 1983 ')
    f.write('\n (Unesco Tech. Paper in Marine Sci. No. 44, p14)')
    f.write('\n%s' % asterisks)
    f.write('\n')
    f.write('\n')

    f.write('\n   Temp    Press       S            cndr         cndr')
    f.write('\n   (C)     (db)      (psu)        (no units)    (no units)\n')
    table = np.vstack([T, P, S, UN_R, R])
    m, n = table.shape
    for iline in range(0, n):
        f.write(" %4.0f       %4.0f   %8.6f   %11.6f  %14.8f\n" %
                tuple(table[:, iline]))

    # Test main module depth.
    f.write('\n%s' % asterisks)
    f.write('\n**  TESTING MODULE: depth')
    f.write('\n%s' % asterisks)

    # Test data - matrix "pressure", vector "lat"  Unesco 1983 data p30.
    lat = np.array([0, 30, 45, 90])
    P = np.array([[500,   500,   500,  500],
                  [5000,  5000,  5000, 5000],
                  [10000, 10000, 10000, 10000]])

    UN_dpth = np.array([[496.65,  496.00,  495.34,  494.03],
                        [4915.04, 4908.56, 4902.08, 4889.13],
                        [9725.47, 9712.65, 9699.84, 9674.23]])

    dpth = sw.dpth(P, lat)

    # Display results.
    f.write('\n')
    f.write('\n%s' % asterisks)
    f.write('\nComparison of accepted values from Unesco 1983 ')
    f.write('\n(Unesco Tech. Paper in Marine Sci. No. 44, p28)')
    f.write('\n%s' % asterisks)
    f.write('\n')

    f.write('\n')
    for irow in range(0, 3):
        f.write('\n    Lat       Press     DPTH      dpth')
        f.write('\n  (degree)    (db)     (meter)    (meter)\n')
        table = np.vstack([lat, P[irow, :], UN_dpth[irow, :], dpth[irow, :]])
        m, n = table.shape
        for iline in range(0, n):
            f.write("  %6.3f     %6.0f   %8.2f   %8.3f\n" %
                    tuple(table[:, iline]))

    # Test main module fp.
    f.write('\n%s' % asterisks)
    f.write('\n**  TESTING MODULE: fp')
    f.write('\n%s' % asterisks)

    # Test 1 - UNESCO data p.30.
    S = np.array([[5, 10, 15, 20, 25, 30, 35, 40],
                  [5, 10, 15, 20, 25, 30, 35, 40]])

    P = np.array([[0,   0,   0,   0,   0,   0,   0,   0],
                  [500, 500, 500, 500, 500, 500, 500, 500]])

    UN_fp = np.array([[-0.274, -0.542, -0.812, -1.083, -1.358, -1.638, -1.922,
                       -2.212], [-0.650, -0.919, -1.188, -1.460, -1.735,
                                 -2.014, -2.299, -2.589]])

    FP = sw.fp(S, P)

    # Display results.
    f.write('\n')
    f.write('\n%s' % asterisks)
    f.write('\nComparison of accepted values from UNESCO 1983 ')
    f.write('\n (Unesco Tech. Paper in Marine Sci. No. 44, p30)')
    f.write('\n%s' % asterisks)
    f.write('\n')

    f.write('\n')
    for irow in range(0, 2):
        f.write('\n   Sal   Press      fp        fp')
        f.write('\n  (psu)   (db)      (C)        (C)\n')
        table = np.vstack([S[irow, :], P[irow, :], UN_fp[irow, :],
                           FP[irow, :]])
        m, n = table.shape
        for iline in range(0, n):
            f.write(" %4.0f   %5.0f   %8.3f  %11.4f\n" %
                    tuple(table[:, iline]))

    # Test main module cp.
    f.write('\n%s' % asterisks)
    f.write('\n**  TESTING MODULE: cp')
    f.write('\n%s' % asterisks)

    # Test 1.
    # Data from Pond and Pickard Intro. Dynamical Oceanography 2nd ed. 1986
    T = np.array([[0,  0,  0,  0,  0,  0],
                  [10, 10, 10, 10, 10, 10],
                  [20, 20, 20, 20, 20, 20],
                  [30, 30, 30, 30, 30, 30],
                  [40, 40, 40, 40, 40, 40]]) / 1.00024

    S = np.array([[25, 25, 25, 35, 35, 35],
                  [25, 25, 25, 35, 35, 35],
                  [25, 25, 25, 35, 35, 35],
                  [25, 25, 25, 35, 35, 35],
                  [25, 25, 25, 35, 35, 35]])

    P = np.array([[0, 5000, 10000, 0, 5000, 10000],
                  [0, 5000, 10000, 0, 5000, 10000],
                  [0, 5000, 10000, 0, 5000, 10000],
                  [0, 5000, 10000, 0, 5000, 10000],
                  [0, 5000, 10000, 0, 5000, 10000]])

    UN_cp = np.array([[4048.4,  3896.3,  3807.7,  3986.5,  3849.3,  3769.1],
                      [4041.8,  3919.6,  3842.3,  3986.3,  3874.7,  3804.4],
                      [4044.8,  3938.6,  3866.7,  3993.9,  3895.0,  3828.3],
                      [4049.1,  3952.0,  3883.0,  4000.7,  3909.2,  3844.3],
                      [4051.2,  3966.1,  3905.9,  4003.5,  3923.9,  3868.3]])

    CP = sw.cp(S, T, P)

    # Display results.
    f.write('\n')
    f.write('\n%s' % asterisks)
    f.write('\nComparison of accepted values from UNESCO 1983 ')
    f.write('\n (Unesco Tech. Paper in Marine Sci. No. 44, p37)')
    f.write('\n%s' % asterisks)
    f.write('\n')

    m, n = S.shape
    f.write('\n')
    for icol in range(0, n):
        f.write('\n   Sal  Temp  Press      Cp        cp')
        f.write('\n  (psu)  (C)   (db)    (J/kg.C)   (J/kg.C)\n')
        result = np.vstack([S[:, icol], T[:, icol], P[:, icol],
                            UN_cp[:, icol], CP[:, icol]])
        for iline in range(0, m):
            f.write(" %4.0f  %4.0f   %5.0f   %8.1f  %11.2f\n" %
                    tuple(result[:, iline]))

    # Test main module svel.
    f.write('\n%s' % asterisks)
    f.write('\n**  TESTING MODULE: svel')
    f.write('\n%s' % asterisks)

    # Test 1.
    # Data from Pond and Pickard Intro. Dynamical Oceanography 2nd ed. 1986
    T = np.array([[0,  0,  0,  0,  0,  0],
                  [10, 10, 10, 10, 10, 10],
                  [20, 20, 20, 20, 20, 20],
                  [30, 30, 30, 30, 30, 30],
                  [40, 40, 40, 40, 40, 40]]) / 1.00024

    S = np.array([[25, 25, 25, 35, 35, 35],
                  [25, 25, 25, 35, 35, 35],
                  [25, 25, 25, 35, 35, 35],
                  [25, 25, 25, 35, 35, 35],
                  [25, 25, 25, 35, 35, 35]])

    P = np.array([[0, 5000, 10000, 0, 5000, 10000],
                  [0, 5000, 10000, 0, 5000, 10000],
                  [0, 5000, 10000, 0, 5000, 10000],
                  [0, 5000, 10000, 0, 5000, 10000],
                  [0, 5000, 10000, 0, 5000, 10000]])

    UN_svel = np.array([[1435.8, 1520.4, 1610.4, 1449.1, 1534.0, 1623.2],
                        [1477.7, 1561.3, 1647.4, 1489.8, 1573.4, 1659.0],
                        [1510.3, 1593.6, 1676.8, 1521.5, 1604.5, 1687.2],
                        [1535.2, 1619.0, 1700.6, 1545.6, 1629.0, 1710.1],
                        [1553.4, 1638.0, 1719.2, 1563.2, 1647.3, 1727.8]])

    SVEL = sw.svel(S, T, P)

    # Display results.
    f.write('\n')
    f.write('\n%s' % asterisks)
    f.write('\nComparison of accepted values from UNESCO 1983 ')
    f.write('\n (Unesco Tech. Paper in Marine Sci. No. 44, p50)')
    f.write('\n%s' % asterisks)
    f.write('\n')

    m, n = SVEL.shape
    f.write('\n')
    for icol in range(0, n):
        f.write('\n   Sal  Temp  Press     SVEL       svel')
        f.write('\n  (psu)  (C)   (db)     (m/s)       (m/s)\n')

        result = np.vstack([S[:, icol], T[:, icol], P[:, icol],
                            UN_svel[:, icol], SVEL[:, icol]])
        for iline in range(0, m):
            f.write(" %4.0f  %4.0f   %5.0f   %8.1f  %11.3f\n" %
                    tuple(result[:, iline]))

    # Test submodules alpha beta aonb.
    f.write('\n%s' % asterisks)
    f.write('\n**  and SUB-MODULE: alpha beta aonb')
    f.write('\n%s' % asterisks)

    # Data from McDouogall 1987.
    s = 40
    PT = 10
    p = 4000
    beta_lit = 0.72088e-03
    aonb_lit = 0.34763
    alpha_lit = aonb_lit * beta_lit

    BETA = sw.beta(s, PT, p, pt=True)
    ALPHA = sw.alpha(s, PT, p, pt=True)
    AONB = sw.aonb(s, PT, p, pt=True)

    # Display results.
    f.write('\n')
    f.write('\n%s' % asterisks)
    f.write('\nComparison of accepted values from MCDOUGALL 1987 ')
    f.write('\n%s' % asterisks)
    f.write('\n')
    f.write('\n')

    f.write('\n   Sal  Temp  Press     BETA       beta')
    f.write('\n  (psu)  (C)   (db)   (psu^-1)     (psu^-1)\n')
    table = np.hstack([s, PT, p, beta_lit, BETA])
    f.write(" %4.0f  %4.0f   %5.0f   %11.4e  %11.5e\n" %
            tuple(table))

    f.write('\n   Sal  Temp  Press     AONB       aonb')
    f.write('\n  (psu)  (C)   (db)   (psu C^-1)   (psu C^-1)\n')
    table = np.hstack([s, PT, p, aonb_lit, AONB])
    f.write(" %4.0f  %4.0f   %5.0f   %8.5f  %11.6f\n" %
            tuple(table))

    f.write('\n   Sal  Temp  Press     ALPHA       alpha')
    f.write('\n  (psu)  (C)   (db)    (psu^-1)     (psu^-1)\n')
    table = np.hstack([s, PT, p, alpha_lit, ALPHA])
    f.write(" %4.0f  %4.0f   %5.0f   %11.4e  %11.4e\n" %
            tuple(table))

    # Test main moduleS  satO2 satN2 satAr.
    f.write('\n%s' % asterisks)
    f.write('\n**  TESTING MODULE: satO2 satN2 satAr')
    f.write('\n%s' % asterisks)
    f.write('\n')

    # Data from Weiss 1970.
    T = np.array([[-1, -1],
                  [10, 10],
                  [20, 20],
                  [40, 40]]) / 1.00024

    S = np.array([[20, 40],
                  [20, 40],
                  [20, 40],
                  [20, 40]])

    lit_O2 = np.array([[9.162, 7.984],
                       [6.950, 6.121],
                       [5.644, 5.015],
                       [4.050, 3.656]])

    lit_N2 = np.array([[16.28, 14.01],
                       [12.64, 11.01],
                       [10.47,  9.21],
                       [7.78,  6.95]])

    lit_Ar = np.array([[0.4456, 0.3877],
                       [0.3397, 0.2989],
                       [0.2766, 0.2457],
                       [0.1986, 0.1794]])

    O2 = sw.satO2(S, T)
    N2 = sw.satN2(S, T)
    Ar = sw.satAr(S, T)

    # Display results.
    f.write('\n')
    f.write('\n%s' % asterisks)
    f.write('\nComparison of accepted values from Weiss, R.F. 1979 ')
    f.write('\n"The solubility of nitrogen, oxygen and argon in water')
    f.write('\n and seawater." Deep-Sea Research., 1970, Vol 17, pp721-735.')
    f.write('\n%s' % asterisks)
    f.write('\n')

    m, n = S.shape
    f.write('\n')
    for icol in range(0, n):
        f.write('\n   Sal  Temp      O2         satO2')
        f.write('\n  (psu)  (C)      (ml/l)     (ml/l)\n')
        result = np.vstack([S[:, icol], T[:, icol],
                            lit_O2[:, icol], O2[:, icol]])
        for iline in range(0, m):
            f.write(" %4.0f  %4.0f    %8.2f   %9.3f\n" %
                    tuple(result[:, iline]))

    for icol in range(0, n):
        f.write('\n   Sal  Temp      N2         satN2')
        f.write('\n  (psu)  (C)      (ml/l)     (ml/l)\n')
        result = np.vstack([S[:, icol], T[:, icol],
                            lit_N2[:, icol], N2[:, icol]])
        for iline in range(0, m):
            f.write(" %4.0f  %4.0f    %8.2f  %9.3f\n" %
                    tuple(result[:, iline]))

    for icol in range(0, n):
        f.write('\n   Sal  Temp      Ar         satAr')
        f.write('\n  (psu)  (C)      (ml/l)     (ml/l)\n')
        result = np.vstack([S[:, icol], T[:, icol],
                            lit_Ar[:, icol], Ar[:, icol]])
        for iline in range(0, m):
            f.write(" %4.0f  %4.0f     %8.4f  %9.4f\n" %
                    tuple(result[:, iline]))