diff --git a/flux_subs.py b/flux_subs.py
index 780de7339a48de26f084e205373c0c394859b07c..e59dd282a35056df45fcd4c033a3d356781c6394 100755
--- a/flux_subs.py
+++ b/flux_subs.py
@@ -8,107 +8,9 @@ kappa = 0.4  # NOTE: 0.41
 # ---------------------------------------------------------------------
 
 
-def charnock_C35(wind, u10n, usr, seastate, waveage, wcp, sigH, lat):
-    """ Calculates Charnock number following Edson et al. 2013 based on 
-    C35 matlab code (coare35vn.m)
-    
-    Parameters
-    ----------
-    wind : float
-        wind speed (m/s)
-    u10n : float
-        neutral 10m wind speed (m/s)
-    usr  : float
-        friction velocity (m/s)
-    seastate : bool
-        0 or 1
-    waveage  : bool
-        0 or 1
-    wcp      : float
-        phase speed of dominant waves (m/s)
-    sigH     : float
-        significant wave height (m)
-    lat      : float
-        latitude (deg)
-    
-    Returns
-    -------
-    ac : float
-        Charnock number
-    """
-    g = gc(lat, None)
-    a1, a2 = 0.0017, -0.0050
-    charnC = np.where(u10n > 19, a1*19+a2, a1*u10n+a2)
-    A, B = 0.114, 0.622  # wave-age dependent coefficients
-    Ad, Bd = 0.091, 2.0  # Sea-state/wave-age dependent coefficients
-    charnW = A*(usr/wcp)**B
-    zoS = sigH*Ad*(usr/wcp)**Bd
-    charnS = (zoS*g)/usr**2
-    charn = np.where(wind > 10, 0.011+(wind-10)/(18-10)*(0.018-0.011),
-                     np.where(wind > 18, 0.018, 0.011*np.ones(np.shape(wind))))
-    if waveage:
-        if seastate:
-            charn = charnS
-        else:
-            charn = charnW
-    else:
-        charn = charnC
-    ac = np.zeros((len(wind), 3))
-    ac[:, 0] = charn
-    ac[:, 1] = charnS
-    ac[:, 2] = charnW
-    return ac
-# ---------------------------------------------------------------------
-
-
-def cd_C35(u10n, wind, usr, charn, monob, Ta, hh_in, lat):
-    """ Calculates exchange coefficients following Edson et al. 2013 based on 
-    C35 matlab code (coare35vn.m)
-    
-    Parameters
-    ----------
-    u10n : float
-        neutral 10m wind speed (m/s)
-    wind : float
-        wind speed (m/s)    
-    charn : float
-        Charnock number
-    monob : float
-        Monin-Obukhov stability length
-    Ta    : float
-        air temperature (K)
-    hh_in : float
-        input sensor's height (m)
-    lat      : float
-        latitude (deg)
-    
-    Returns
-    -------
-    zo : float
-        surface roughness (m)
-    cdhf : float
-        drag coefficient
-    cthf : float
-        heat exchange coefficient
-    cqhf : float
-        moisture exchange coefficient
-    """
-    g = gc(lat, None)
-    zo = charn*usr**2/g+0.11*visc_air(Ta)/usr  # surface roughness
-    rr = zo*usr/visc_air(Ta)
-    # These thermal roughness lengths give Stanton and
-    zoq = np.where(5.8e-5/rr**0.72 > 1.6e-4, 1.6e-4, 5.8e-5/rr**0.72)
-    zot = zoq  # Dalton numbers that closely approximate COARE 3.0
-    cdhf = kappa/(np.log(hh_in[0]/zo)-psiu_26(hh_in[0]/monob))
-    cthf = kappa/(np.log(hh_in[1]/zot)-psit_26(hh_in[1]/monob))
-    cqhf = kappa/(np.log(hh_in[2]/zoq)-psit_26(hh_in[2]/monob))
-    return zo, cdhf, cthf, cqhf
-# ---------------------------------------------------------------------
-
-
-def cdn_calc(u10n, Ta, Tp, method="S80"):
+def cdn_calc(u10n, Ta, Tp, lat, meth="S80"):
     """ Calculates neutral drag coefficient
-    
+
     Parameters
     ----------
     u10n : float
@@ -117,39 +19,40 @@ def cdn_calc(u10n, Ta, Tp, method="S80"):
         air temperature (K)
     Tp   : float
         wave period
-    method : str
-    
+    meth : str
+
     Returns
     -------
     cdn : float
     """
-    if (method == "S80"):
+    if (meth == "S80"):
         cdn = np.where(u10n <= 3, (0.61+0.567/u10n)*0.001,
                        (0.61+0.063*u10n)*0.001)
-    elif (method == "LP82"):
+    elif (meth == "LP82"):
         cdn = np.where((u10n < 11) & (u10n >= 4), 1.2*0.001,
                        np.where((u10n <= 25) & (u10n >= 11),
                        (0.49+0.065*u10n)*0.001, 1.14*0.001))
-    elif (method == "S88" or method == "UA" or method == "ERA5"):
-        cdn = cdn_from_roughness(u10n, Ta, None, method)
-    elif (method == "YT96"):
+    elif (meth == "S88" or meth == "UA" or meth == "ERA5" or meth == "C30" or
+          meth == "C35" or meth == "C40"):
+        cdn = cdn_from_roughness(u10n, Ta, None, lat, meth)
+    elif (meth == "YT96"):
         # for u<3 same as S80
         cdn = np.where((u10n < 6) & (u10n >= 3),
                        (0.29+3.1/u10n+7.7/u10n**2)*0.001,
                        np.where((u10n <= 26) & (u10n >= 6),
                        (0.60 + 0.070*u10n)*0.001, (0.61+0.567/u10n)*0.001))
-    elif (method == "LY04"):
+    elif (meth == "LY04"):
         cdn = np.where(u10n >= 0.5,
                        (0.142+(2.7/u10n)+(u10n/13.09))*0.001, np.nan)
     else:
-        print("unknown method cdn: "+method)
+        print("unknown method cdn: "+meth)
     return cdn
 # ---------------------------------------------------------------------
 
 
-def cdn_from_roughness(u10n, Ta, Tp, method="S88"):
+def cdn_from_roughness(u10n, Ta, Tp, lat, meth="S88"):
     """ Calculates neutral drag coefficient from roughness length
-    
+
     Parameters
     ----------
     u10n : float
@@ -158,42 +61,59 @@ def cdn_from_roughness(u10n, Ta, Tp, method="S88"):
         air temperature (K)
     Tp   : float
         wave period
-    method : str
-    
+    meth : str
+
     Returns
     -------
     cdn : float
     """
-    g, tol = 9.812, 0.000001
+    g, tol = gc(lat, None), 0.000001
     cdn, usr = np.zeros(Ta.shape), np.zeros(Ta.shape)
     cdnn = (0.61+0.063*u10n)*0.001
     zo, zc, zs = np.zeros(Ta.shape), np.zeros(Ta.shape), np.zeros(Ta.shape)
     for it in range(5):
         cdn = np.copy(cdnn)
         usr = np.sqrt(cdn*u10n**2)
-        if (method == "S88"):
+        if (meth == "S88"):
             # .....Charnock roughness length (equn 4 in Smith 88)
             zc = 0.011*np.power(usr, 2)/g
             # .....smooth surface roughness length (equn 6 in Smith 88)
             zs = 0.11*visc_air(Ta)/usr
             zo = zc + zs  # .....equns 7 & 8 in Smith 88 to calculate new CDN
-        elif (method == "UA"):
+        elif (meth == "UA"):
             # valid for 0<u<18m/s # Zeng et al. 1998 (24)
             zo = 0.013*np.power(usr, 2)/g+0.11*visc_air(Ta)/usr
-        elif (method == "ERA5"):
+        elif (meth == "C30"):
+            a = 0.011*np.ones(Ta.shape)
+            a = np.where(u10n > 10, 0.011+(u10n-10)/(18-10)*(0.018-0.011),
+                         np.where(u10n > 18, 0.018, a))
+            zo = a*np.power(usr, 2)/g+0.11*visc_air(Ta)/usr
+        elif (meth == "C35"):
+            a = 0.011*np.ones(Ta.shape)
+            a = np.where(u10n > 18, 0.0017*19-0.0050,
+                         np.where((u10n > 7) & (u10n <= 18),
+                                  0.0017*u10n-0.0050, a))
+#            charn = np.where(wind > 10, 0.011+(wind-10)/(18-10)*(0.018-0.011),
+#                     np.where(wind > 18, 0.018, 0.011*np.ones(np.shape(wind))))
+            zo = 0.11*visc_air(Ta)/usr+a*np.power(usr, 2)/g
+        elif (meth == "C40"):
+            a = 0.011*np.ones(Ta.shape)
+            a = np.where(u10n > 22, 0.0016*22-0.0035, 0.0016*u10n-0.0035)
+            zo = a*np.power(usr, 2)/g+0.11*visc_air(Ta)/usr # surface roughness
+        elif (meth == "ERA5"):
             # eq. (3.26) p.40 over sea IFS Documentation cy46r1
             zo = 0.11*visc_air(Ta)/usr+0.018*np.power(usr, 2)/g
         else:
-            print("unknown method for cdn_from_roughness "+method)
+            print("unknown method for cdn_from_roughness "+meth)
         cdnn = (kappa/np.log(10/zo))**2
     cdn = np.where(np.abs(cdnn-cdn) < tol, cdnn, np.nan)
     return cdnn
 # ---------------------------------------------------------------------
 
 
-def ctcqn_calc(zol, cdn, u10n, zo, Ta, method="S80"):
+def ctcqn_calc(zol, cdn, u10n, zo, Ta, meth="S80"):
     """ Calculates neutral heat and moisture exchange coefficients
-    
+
     Parameters
     ----------
     zol  : float
@@ -206,8 +126,8 @@ def ctcqn_calc(zol, cdn, u10n, zo, Ta, method="S80"):
         surface roughness (m)
     Ta   : float
         air temperature (K)
-    method : str
-    
+    meth : str
+
     Returns
     -------
     ctn : float
@@ -215,27 +135,57 @@ def ctcqn_calc(zol, cdn, u10n, zo, Ta, method="S80"):
     cqn : float
         neutral moisture exchange coefficient
     """
-    if (method == "S80" or method == "S88" or method == "YT96"):
+    if (meth == "S80" or meth == "S88" or meth == "YT96"):
         cqn = np.ones(Ta.shape)*1.20*0.001  # from S88
         ctn = np.ones(Ta.shape)*1.00*0.001
-    elif (method == "LP82"):
+    elif (meth == "LP82"):
         cqn = np.where((zol <= 0) & (u10n > 4) & (u10n < 14), 1.15*0.001,
                        np.nan)
         ctn = np.where((zol <= 0) & (u10n > 4) & (u10n < 25), 1.13*0.001,
                        0.66*0.001)
-    elif (method == "LY04"):
-        cqn = 34.6*0.001*cdn**0.5
-        ctn = np.where(zol <= 0, 32.7*0.001*cdn**0.5, 18*0.001*cdn**0.5)
-    elif (method == "UA"):
-        usr = (cdn * u10n**2)**0.5
+    elif (meth == "LY04"):
+        cqn = 34.6*0.001*np.sqrt(cdn)
+        ctn = np.where(zol <= 0, 32.7*0.001*np.sqrt(cdn), 18*0.001*np.sqrt(cdn))
+    elif (meth == "UA"):
+        usr = np.sqrt(cdn*np.power(u10n, 2))
         # Zeng et al. 1998 (25)
-        zoq = zo*np.exp(-(2.67*np.power(usr*zo/visc_air(Ta), 1/4)-2.57))
+        re=usr*zo/visc_air(Ta)
+        zoq = zo/np.exp(2.67*np.power(re, 1/4)-2.57)
         zot = zoq
         cqn = np.where((u10n > 0.5) & (u10n < 18), np.power(kappa, 2) /
                        (np.log(10/zo)*np.log(10/zoq)), np.nan)
         ctn = np.where((u10n > 0.5) & (u10n < 18), np.power(kappa, 2) /
                        (np.log(10/zo)*np.log(10/zoq)), np.nan)
-    elif (method == "ERA5"):
+    elif (meth == "C30"):
+        usr = np.sqrt(cdn*np.power(u10n, 2))
+        rr = zo*usr/visc_air(Ta)
+        zoq = np.where(5e-5/np.power(rr, 0.6) > 1.15e-4, 1.15e-4,
+                       5e-5/np.power(rr, 0.6))  # moisture roughness
+        zot=zoq  # temperature roughness
+        cqn = kappa**2/np.log(10/zo)/np.log(10/zoq)
+        ctn = kappa**2/np.log(10/zo)/np.log(10/zot)
+    elif (meth == "C35"):
+        usr = np.sqrt(cdn*np.power(u10n, 2))
+        rr = zo*usr/visc_air(Ta)
+        zoq = np.where(5.8e-5/np.power(rr, 0.72) > 1.6e-4, 1.6e-4,
+                       5.8e-5/np.power(rr, 0.72))  # moisture roughness
+        zot=zoq  # temperature roughness
+        cqn = kappa**2/np.log(10/zo)/np.log(10/zoq)
+        ctn = kappa**2/np.log(10/zo)/np.log(10/zot)
+    elif (meth == "C40"):
+        usr = np.sqrt(cdn*np.power(u10n, 2))
+        rr = zo*usr/visc_air(Ta)
+        zot = np.where(1.0e-4/np.power(rr, 0.55) > 2.4e-4/np.power(rr, 1.2),
+                       2.4e-4/np.power(rr, 1.2),
+                       1.0e-4/np.power(rr, 0.55)) # temperature roughness
+        zoq = np.where(2.0e-5/np.power(rr,0.22) > 1.1e-4/np.power(rr,0.9),
+                       1.1e-4/np.power(rr,0.9), 2.0e-5/np.power(rr,0.22))
+        # moisture roughness determined by the CLIMODE, GASEX and CBLAST data
+#        zoq = np.where(5e-5/np.power(rr, 0.6) > 1.15e-4, 1.15e-4,
+#                       5e-5/np.power(rr, 0.6))  # moisture roughness as in C30
+        cqn = kappa**2/np.log(10/zo)/np.log(10/zoq)
+        ctn = kappa**2/np.log(10/zo)/np.log(10/zot)
+    elif (meth == "ERA5"):
         # eq. (3.26) p.40 over sea IFS Documentation cy46r1
         usr = np.sqrt(cdn*np.power(u10n, 2))
         zot = 0.40*visc_air(Ta)/usr
@@ -243,14 +193,14 @@ def ctcqn_calc(zol, cdn, u10n, zo, Ta, method="S80"):
         cqn = kappa**2/np.log(10/zo)/np.log(10/zoq)
         ctn = kappa**2/np.log(10/zo)/np.log(10/zot)
     else:
-        print("unknown method ctcqn: "+method)
+        print("unknown method ctcqn: "+meth)
     return ctn, cqn
 # ---------------------------------------------------------------------
 
 
 def cd_calc(cdn, height, ref_ht, psim):
     """ Calculates drag coefficient at reference height
-    
+
     Parameters
     ----------
     cdn : float
@@ -261,7 +211,7 @@ def cd_calc(cdn, height, ref_ht, psim):
         reference height (m)
     psim : float
         momentum stability function
-    
+
     Returns
     -------
     cd : float
@@ -274,7 +224,7 @@ def cd_calc(cdn, height, ref_ht, psim):
 
 def ctcq_calc(cdn, cd, ctn, cqn, h_t, h_q, ref_ht, psit, psiq):
     """ Calculates heat and moisture exchange coefficients at reference height
-    
+
     Parameters
     ----------
     cdn : float
@@ -295,7 +245,7 @@ def ctcq_calc(cdn, cd, ctn, cqn, h_t, h_q, ref_ht, psit, psiq):
         heat stability function
     psiq : float
         moisture stability function
-    
+
     Returns
     -------
     ct : float
@@ -307,24 +257,26 @@ def ctcq_calc(cdn, cd, ctn, cqn, h_t, h_q, ref_ht, psit, psiq):
 # ---------------------------------------------------------------------
 
 
-def psim_calc(zol, method="S80"):
+def psim_calc(zol, meth="S80"):
     """ Calculates momentum stability function
-    
+
     Parameters
     ----------
     zol : float
         height over MO length
-    method : str
-    
+    meth : str
+
     Returns
     -------
     psim : float
     """
-    coeffs = get_stabco(method)
+    coeffs = get_stabco(meth)
     alpha, beta, gamma = coeffs[0], coeffs[1], coeffs[2]
-    if (method == "ERA5"):
+    if (meth == "ERA5"):
         psim = np.where(zol < 0, psim_conv(zol, alpha, beta, gamma),
                         psim_stab_era5(zol, alpha, beta, gamma))
+    elif (meth == "C30" or meth == "C35" or meth == "C40"):
+        psim = psiu_26(zol, meth)
     else:
         psim = np.where(zol < 0, psim_conv(zol, alpha, beta, gamma),
                         psim_stab(zol, alpha, beta, gamma))
@@ -332,24 +284,26 @@ def psim_calc(zol, method="S80"):
 # ---------------------------------------------------------------------
 
 
-def psit_calc(zol, method="S80"):
+def psit_calc(zol, meth="S80"):
     """ Calculates heat stability function
-    
+
     Parameters
     ----------
     zol : float
         height over MO length
-    method : str
-    
+    meth : str
+
     Returns
     -------
     psit : float
     """
-    coeffs = get_stabco(method)
+    coeffs = get_stabco(meth)
     alpha, beta, gamma = coeffs[0], coeffs[1], coeffs[2]
-    if (method == "ERA5"):
+    if (meth == "ERA5"):
         psit = np.where(zol < 0, psi_conv(zol, alpha, beta, gamma),
                         psi_stab_era5(zol, alpha, beta, gamma))
+    elif (meth == "C30" or meth == "C35" or meth == "C40"):
+        psit = psit_26(zol)
     else:
         psit = np.where(zol < 0, psi_conv(zol, alpha, beta, gamma),
                         psi_stab(zol, alpha, beta, gamma))
@@ -357,26 +311,27 @@ def psit_calc(zol, method="S80"):
 # ---------------------------------------------------------------------
 
 
-def get_stabco(method="S80"):
+def get_stabco(meth="S80"):
     """ Gives the coefficients \\alpha, \\beta, \\gamma for stability functions
-    
+
     Parameters
     ----------
-    method : str
-    
+    meth : str
+
     Returns
     -------
     coeffs : float
     """
-    if (method == "S80" or method == "S88" or method == "LY04" or
-            method == "UA" or method == "ERA5"):
+    if (meth == "S80" or meth == "S88" or meth == "LY04" or
+        meth == "UA" or meth == "ERA5" or meth == "C30" or meth == "C35" or
+        meth == "C40"):
         alpha, beta, gamma = 16, 0.25, 5  # Smith 1980, from Dyer (1974)
-    elif (method == "LP82"):
+    elif (meth == "LP82"):
         alpha, beta, gamma = 16, 0.25, 7
-    elif (method == "YT96"):
+    elif (meth == "YT96"):
         alpha, beta, gamma = 20, 0.25, 5
     else:
-        print("unknown method stabco: "+method)
+        print("unknown method stabco: "+meth)
     coeffs = np.zeros(3)
     coeffs[0] = alpha
     coeffs[1] = beta
@@ -386,16 +341,16 @@ def get_stabco(method="S80"):
 
 
 def psi_stab_era5(zol, alpha, beta, gamma):
-    """ Calculates heat stability function for stable conditions 
+    """ Calculates heat stability function for stable conditions
         for method ERA5
-    
+
     Parameters
     ----------
     zol : float
         height over MO length
     alpha, beta, gamma : float
         constants given by get_stabco
-    
+
     Returns
     -------
     psit : float
@@ -406,16 +361,43 @@ def psi_stab_era5(zol, alpha, beta, gamma):
     return psit
 # ---------------------------------------------------------------------
 
+
+def psit_26(zol):
+    """ Computes temperature structure function as in C35
+
+    Parameters
+    ----------
+    zol : float
+        height over MO length
+
+    Returns
+    -------
+    psi : float
+    """
+    b, d = 2/3, 0.35
+    dzol = np.where(d*zol > 50, 50, d*zol)  # stable
+    psi = -((1+b*zol)**1.5+b*(zol-14.28)*np.exp(-dzol)+8.525)
+    psi = np.where(zol < 0, (1-(np.power(zol, 2)/(1+np.power(zol, 2))))*2 *
+                   np.log((1+np.sqrt(1-15*zol))/2)+(np.power(zol, 2) /
+                   (1+np.power(zol, 2))) *
+                   (1.5*np.log((1+np.power(1-34.15*zol, 1/3) +
+                   np.power(1-34.15*zol, 2/3))/3) -
+                   np.sqrt(3)*np.arctan((1+2*np.power(1-34.15*zol, 1/3)) /
+                   np.sqrt(3))+4*np.arctan(1)/np.sqrt(3)), psi)
+    return psi
+# ---------------------------------------------------------------------
+
+
 def psi_conv(zol, alpha, beta, gamma):
     """ Calculates heat stability function for unstable conditions
-    
+
     Parameters
     ----------
     zol : float
         height over MO length
     alpha, beta, gamma : float
         constants given by get_stabco
-    
+
     Returns
     -------
     psit : float
@@ -428,14 +410,14 @@ def psi_conv(zol, alpha, beta, gamma):
 
 def psi_stab(zol, alpha, beta, gamma):
     """ Calculates heat stability function for stable conditions
-    
+
     Parameters
     ----------
     zol : float
         height over MO length
     alpha, beta, gamma : float
         constants given by get_stabco
-    
+
     Returns
     -------
     psit : float
@@ -445,43 +427,17 @@ def psi_stab(zol, alpha, beta, gamma):
 # ---------------------------------------------------------------------
 
 
-def psit_26(zol):
-    """ Computes temperature structure function as in C35
-    
-    Parameters
-    ----------
-    zol : float
-        height over MO length
-        
-    Returns
-    -------
-    psi : float
-    """
-    dzol = np.where(0.35*zol > 50, 50, 0.35*zol)  # stable
-    psi = -((1+0.6667*zol)**1.5+0.6667*(zol-14.28)*np.exp(-dzol)+8.525)
-    k = np.where(zol < 0)  # unstable
-    x = (1-15*zol[k])**0.5
-    psik = 2*np.log((1+x)/2)
-    x = (1-34.15*zol[k])**0.3333
-    psic = (1.5*np.log((1+x+x**2)/3)-np.sqrt(3)*np.arctan((1+2*x) /
-            np.sqrt(3))+4*np.arctan(1)/np.sqrt(3))
-    f = zol[k]**2/(1+zol[k]**2)
-    psi[k] = (1-f)*psik+f*psic
-    return psi
-# ---------------------------------------------------------------------
-
-
 def psim_stab_era5(zol, alpha, beta, gamma):
-    """ Calculates momentum stability function for stable conditions 
+    """ Calculates momentum stability function for stable conditions
         for method ERA5
-    
+
     Parameters
     ----------
     zol : float
         height over MO length
     alpha, beta, gamma : float
         constants given by get_stabco
-    
+
     Returns
     -------
     psim : float
@@ -495,14 +451,14 @@ def psim_stab_era5(zol, alpha, beta, gamma):
 
 def psim_conv(zol, alpha, beta, gamma):
     """ Calculates momentum stability function for unstable conditions
-    
+
     Parameters
     ----------
     zol : float
         height over MO length
     alpha, beta, gamma : float
         constants given by get_stabco
-    
+
     Returns
     -------
     psim : float
@@ -516,14 +472,14 @@ def psim_conv(zol, alpha, beta, gamma):
 
 def psim_stab(zol, alpha, beta, gamma):
     """ Calculates momentum stability function for stable conditions
-    
+
     Parameters
     ----------
     zol : float
         height over MO length
     alpha, beta, gamma : float
         constants given by get_stabco
-    
+
     Returns
     -------
     psim : float
@@ -533,41 +489,54 @@ def psim_stab(zol, alpha, beta, gamma):
 # ---------------------------------------------------------------------
 
 
-def psiu_26(zol):
+def psiu_26(zol, meth):
     """ Computes velocity structure function C35
-    
+
     Parameters
     ----------
     zol : float
         height over MO length
-   
+
     Returns
     -------
     psi : float
     """
-    dzol = np.where(0.35*zol > 50, 50, 0.35*zol)  # stable
-    a, b, c, d = 0.7, 3/4, 5, 0.35
-    psi = -(a*zol+b*(zol-c/d)*np.exp(-dzol)+b*c/d)
-    k = np.where(zol < 0)  # unstable
-    x = (1-15*zol[k])**0.25
-    psik = 2*np.log((1+x)/2)+np.log((1+x**2)/2)-2*np.arctan(x)+2*np.arctan(1)
-    x = (1-10.15*zol[k])**0.3333
-    psic = (1.5*np.log((1+x+x**2)/3)-np.sqrt(3)*np.arctan((1+2*x)/np.sqrt(3)) +
-            4*np.arctan(1)/np.sqrt(3))
-    f = zol[k]**2/(1+zol[k]**2)
-    psi[k] = (1-f)*psik+f*psic
+    if (meth == "C30"):
+        dzol = np.where(0.35*zol > 50, 50, 0.35*zol) # stable
+        psi = -((1+zol)+0.6667*(zol-14.28)*np.exp(-dzol)+8.525)
+        k = np.where(zol < 0)  # unstable
+        x = np.power(1-15*zol[k], 0.25)
+        psik = (2*np.log((1+x)/2)+np.log((1+np.power(x, 2))/2)-2*np.arctan(x) +
+                2*np.arctan(1))
+        x = np.power(1-10.15*zol[k], 0.3333)
+        psic = (1.5*np.log((1+x+np.power(x, 2))/3)-np.sqrt(3) *
+                np.arctan((1+2*x)/np.sqrt(3))+4*np.arctan(1)/np.sqrt(3))
+        f = np.power(zol[k], 2)/(1+np.power(zol[k], 2))
+        psi[k] = (1-f)*psik+f*psic
+    elif (meth == "C35" or meth == "C40"):
+        dzol = np.where(0.35*zol > 50, 50, 0.35*zol)  # stable
+        a, b, c, d = 0.7, 3/4, 5, 0.35
+        psi = -(a*zol+b*(zol-c/d)*np.exp(-dzol)+b*c/d)
+        k = np.where(zol < 0)  # unstable
+        x = np.power(1-15*zol[k], 0.25)
+        psik = 2*np.log((1+x)/2)+np.log((1+x**2)/2)-2*np.arctan(x)+2*np.arctan(1)
+        x = np.power(1-10.15*zol[k], 0.3333)
+        psic = (1.5*np.log((1+x+np.power(x, 2))/3)-np.sqrt(3) *
+                np.arctan((1+2*x)/np.sqrt(3))+4*np.arctan(1)/np.sqrt(3))
+        f = np.power(zol[k], 2)/(1+np.power(zol[k], 2))
+        psi[k] = (1-f)*psik+f*psic
     return psi
 # ------------------------------------------------------------------------------
 
 
 def psiu_40(zol):
     """ Computes velocity structure function C35
-    
+
     Parameters
     ----------
     zol : float
         height over MO length
-   
+
     Returns
     -------
     psi : float
@@ -587,9 +556,9 @@ def psiu_40(zol):
 # ---------------------------------------------------------------------
 
 
-def get_skin(sst, qsea, rho, Rl, Rs, Rnl, cp, lv, usr, tsr, qsr, lat):
+def get_skin(sst, qsea, rho, Rl, Rs, Rnl, cp, lv, tkt, usr, tsr, qsr, lat):
     """ Computes cool skin
-    
+
     Parameters
     ----------
     sst : float
@@ -602,10 +571,14 @@ def get_skin(sst, qsea, rho, Rl, Rs, Rnl, cp, lv, usr, tsr, qsr, lat):
         downward longwave radiation (W/m^2)
     Rs : float
         downward shortwave radiation (W/m^2)
+    Rnl : float
+        upwelling IR radiation (W/m^2)
     cp : float
        specific heat of air at constant pressure
     lv : float
        latent heat of vaporization
+    tkt : float
+       cool skin thickness
     usr : float
        friction velocity
     tsr : float
@@ -614,12 +587,12 @@ def get_skin(sst, qsea, rho, Rl, Rs, Rnl, cp, lv, usr, tsr, qsr, lat):
        star humidity
     lat : float
        latitude
-    
+
     Returns
     -------
     dter : float
-    dqer : float      
-    
+    dqer : float
+
     """
     # coded following Saunders (1967) with lambda = 6
     g = gc(lat, None)
@@ -629,30 +602,31 @@ def get_skin(sst, qsea, rho, Rl, Rs, Rnl, cp, lv, usr, tsr, qsr, lat):
     # density of water, specific heat capacity of water, water viscosity,
     # thermal conductivity of water
     rhow, cpw, visw, tcw = 1022, 4000, 1e-6, 0.6
-    Al = 2.1e-5*(sst+3.2)**0.79
+    Al = 2.1e-5*np.power(sst+3.2, 0.79)
     be = 0.026
-    bigc = 16*g*cpw*(rhow*visw)**3/(tcw*tcw*rho*rho)
-    wetc = 0.622*lv*qsea/(287.1*(sst+273.16)**2)
+    bigc = 16*g*cpw*np.power(rhow*visw, 3)/(np.power(tcw, 2)*np.power(rho, 2))
+    wetc = 0.622*lv*qsea/(287.1*np.power(sst+273.16, 2))
     Rns = 0.945*Rs  # albedo correction
     hsb = -rho*cp*usr*tsr
     hlb = -rho*lv*usr*qsr
     qout = Rnl+hsb+hlb
-    tkt = 0.001*np.ones(np.shape(sst))
     dels = Rns*(0.065+11*tkt-6.6e-5/tkt*(1-np.exp(-tkt/8.0e-4)))
     qcol = qout-dels
     alq = Al*qcol+be*hlb*cpw/lv
+    xlamx = 6*np.ones(sst.shape)
     xlamx = np.where(alq > 0, 6/(1+(bigc*alq/usr**4)**0.75)**0.333, 6)
-    tkt = xlamx*visw/(np.sqrt(rho/rhow)*usr)
-    tkt = np.where(alq > 0, np.where(tkt > 0.01, 0.01, tkt), tkt)
+    tkt = np.where(alq > 0, xlamx*visw/(np.sqrt(rho/rhow)*usr),
+                   np.where(xlamx*visw/(np.sqrt(rho/rhow)*usr) > 0.01, 0.01,
+                   xlamx*visw/(np.sqrt(rho/rhow)*usr)))
     dter = qcol*tkt/tcw
     dqer = wetc*dter
-    return dter, dqer
+    return dter, dqer, tkt
 # ---------------------------------------------------------------------
 
 
 def get_gust(beta, Ta, usr, tsrv, zi, lat):
     """ Computes gustiness
-    
+
     Parameters
     ----------
     beta : float
@@ -667,17 +641,15 @@ def get_gust(beta, Ta, usr, tsrv, zi, lat):
         scale height of the boundary layer depth (m)
     lat : float
         latitude
-    
+
     Returns
     -------
     ug : float
     """
     if (np.max(Ta) < 200):  # convert to K if in Celsius
         Ta = Ta+273.16
-    if np.isnan(zi):
-        zi = 600
     g = gc(lat, None)
-    Bf = -g/Ta*usr*tsrv
+    Bf = (-g/Ta)*usr*tsrv
     ug = np.ones(np.shape(Ta))*0.2
     ug = np.where(Bf > 0, beta*np.power(Bf*zi, 1/3), 0.2)
     return ug
@@ -686,12 +658,12 @@ def get_gust(beta, Ta, usr, tsrv, zi, lat):
 
 def get_heights(h):
     """ Reads input heights for velocity, temperature and humidity
-    
+
     Parameters
     ----------
     h : float
         input heights (m)
-        
+
     Returns
     -------
     hh : array
@@ -709,12 +681,12 @@ def get_heights(h):
 
 def svp_calc(T):
     """ Calculates saturation vapour pressure
-    
+
     Parameters
     ----------
     T : float
         temperature (K)
-    
+
     Returns
     -------
     svp : float
@@ -729,17 +701,17 @@ def svp_calc(T):
 
 def qsea_calc(sst, pres):
     """ Computes specific humidity of the  sea surface air
-    
+
     Parameters
     ----------
     sst : float
         sea surface temperature (K)
     pres : float
         pressure (mb)
-    
+
     Returns
     -------
-    qsea : float 
+    qsea : float
         (kg/kg)
     """
     if (np.nanmin(sst) < 200):  # if sst in Celsius convert to Kelvin
@@ -754,7 +726,7 @@ def qsea_calc(sst, pres):
 
 def q_calc(Ta, rh, pres):
     """ Computes specific humidity following Haltiner and Martin p.24
-    
+
     Parameters
     ----------
     Ta : float
@@ -763,7 +735,7 @@ def q_calc(Ta, rh, pres):
         relative humidity (%)
     pres : float
         air pressure (mb)
-        
+
     Returns
     -------
     qair : float, (kg/kg)
@@ -778,14 +750,14 @@ def q_calc(Ta, rh, pres):
 
 def bucksat(T, P):
     """ Computes saturation vapor pressure (mb) as in C35
-    
+
     Parameters
     ----------
     T : float
         temperature ($^\\circ$\\,C)
     P : float
         pressure (mb)
-    
+
     Returns
     -------
     exx : float
@@ -800,14 +772,14 @@ def bucksat(T, P):
 
 def qsat26sea(T, P):
     """ Computes surface saturation specific humidity (g/kg) as in C35
-    
+
     Parameters
     ----------
     T : float
         temperature ($^\\circ$\\,C)
     P : float
         pressure (mb)
-        
+
     Returns
     -------
     qs : float
@@ -824,14 +796,14 @@ def qsat26sea(T, P):
 
 def qsat26air(T, P, rh):
     """ Computes saturation specific humidity (g/kg) as in C35
-    
+
     Parameters
     ----------
     T : float
         temperature ($^\circ$\,C)
     P : float
         pressure (mb)
-        
+
     Returns
     -------
     q : float
@@ -849,14 +821,14 @@ def qsat26air(T, P, rh):
 
 def gc(lat, lon=None):
     """ Computes gravity relative to latitude
-    
+
     Parameters
     ----------
     lat : float
         latitude ($^\circ$)
     lon : float
         longitude ($^\circ$, optional)
-    
+
     Returns
     -------
     gc : float
@@ -879,22 +851,23 @@ def gc(lat, lon=None):
 # ---------------------------------------------------------------------
 
 
-def visc_air(Ta):
+def visc_air(T):
     """ Computes the kinematic viscosity of dry air as a function of air temp.
     following Andreas (1989), CRREL Report 89-11.
-    
+
     Parameters
     ----------
     Ta : float
         air temperature ($^\circ$\,C)
-    
+
     Returns
     -------
     visa : float
         kinematic viscosity (m^2/s)
     """
-    Ta = np.asarray(Ta)
-    if (np.nanmin(Ta) > 200):  # if Ta in Kelvin convert to Celsius
-        Ta = Ta-273.16
-    visa = 1.326e-5 * (1 + 6.542e-3*Ta + 8.301e-6*Ta**2 - 4.84e-9*Ta**3)
+    T = np.asarray(T)
+    if (np.nanmin(T) > 200):  # if Ta in Kelvin convert to Celsius
+        T = T-273.16
+    visa = 1.326e-5*(1+6.542e-3*T+8.301e-6*np.power(T, 2) -
+                     4.84e-9*np.power(T, 3))
     return visa