def thetaEchange(Tguess, thetaE0, press): """ thetaEchange(Tguess, thetaE0, press) Evaluates the equation and passes it back to brenth. Parameters - - - - - - Tguess : float Trial temperature value (K). ws0 : float Initial saturated mixing ratio (kg/kg). press : float Pressure (Pa). Returns - - - - theDiff : float The difference between the values of 'thetaEguess' and 'thetaE0'. This difference is then compared to the tolerance allowed by brenth. """ q = wsat(Tguess, press) #assume no liquid water thetaEguess = thermo.theta_e(Tguess, press, q, 0); #when this result is small enough we're done theDiff = thetaEguess - thetaE0; return theDiff
def thetaEchange(Tguess, thetaE0, press): """ thetaEchange(Tguess, thetaE0, press) Evaluates the equation and passes it back to brenth. Parameters - - - - - - Tguess : float Trial temperature value (K). ws0 : float Initial saturated mixing ratio (kg/kg). press : float Pressure (Pa). Returns - - - - theDiff : float The difference between the values of 'thetaEguess' and 'thetaE0'. This difference is then compared to the tolerance allowed by brenth. """ q = wsat(Tguess, press) #assume no liquid water thetaEguess = thermo.theta_e(Tguess, press, q, 0) #when this result is small enough we're done theDiff = thetaEguess - thetaE0 return theDiff
def thetaes(T, p): """ thetaes(T, p) Calculates the pseudo equivalent potential temperature of an air parcel. Parameters - - - - - - T : float Temperature (K). p : float Pressure (Pa). Returns - - - - thetaep : float Pseudo equivalent potential temperature (K). Notes - - - It should be noted that the pseudo equivalent potential temperature (thetaep) of an air parcel is not a conserved variable. References - - - - - - Emanuel 4.7.9 p. 132 Examples - - - - - >>> thetaes(300., 8.e4) 412.97362667593831 """ c = constants(); # The parcel is saturated - prohibit supersaturation with Td > T. Tlcl = T; wv = wsat(T, p); thetaval = theta(T, p, wv); power = 0.2854 * (1 - 0.28 * wv); thetaep = thetaval * np.exp(wv * (1 + 0.81 * wv) * \ (3376. / Tlcl - 2.54)) # # peg this at 450 so rootfinder won't blow up # if thetaep > 450.: thetaep = 450; return thetaep
def findWvWl(T, wT, p): """ findWvWl(T, wT, p) Computes the vapour and liquid water mixing ratios. Parameters - - - - - - T : float Temperature (K). wT : float Total water mixing ratio (kg/kg). p : float Pressure (Pa). Returns - - - - wv : float Water vapour mixing ratio (kg/kg). wl : float Liquid water mixing ratio (kg/kg). Raises - - - - AssertionError If any of the inputs are in vector form. Examples - - - - - >>> findWvWl(250., 0.01, 8.e4) (0.00074331469136857157, 0.0092566853086314283) >>> findWvWl(300., 0.01, 8.e4) (0.01, 0) >>> findWvWl([250.], 0.01, 8.e4) Traceback (most recent call last): ... AssertionError: A vector is not an acceptable input """ args = (T, wT, p) assert islist(*args) is False , \ 'A vector is not an acceptable input' wsVal = wsat(T, p) if wsVal > wT: #unsaturated wv = wT wl = 0 else: #saturated wv = wsVal wl = wT - wv return wv, wl
def thetaes(T, p): """ thetaes(T, p) Calculates the pseudo equivalent potential temperature of an air parcel. Parameters - - - - - - T : float Temperature (K). p : float Pressure (Pa). Returns - - - - thetaep : float Pseudo equivalent potential temperature (K). Notes - - - It should be noted that the pseudo equivalent potential temperature (thetaep) of an air parcel is not a conserved variable. References - - - - - - Emanuel 4.7.9 p. 132 Examples - - - - - >>> thetaes(300., 8.e4) 412.97362667593831 """ c = constants() # The parcel is saturated - prohibit supersaturation with Td > T. Tlcl = T wv = wsat(T, p) thetaval = theta(T, p, wv) power = 0.2854 * (1 - 0.28 * wv) thetaep = thetaval * np.exp(wv * (1 + 0.81 * wv) * \ (3376. / Tlcl - 2.54))\ #if thetaep > 550: # thetaep = 550 return thetaep
def equations(p): l_m, q_BLm, T_BLc = p q_BLm = f * wsat(T_BLc, p_s) #delz_trop = integrate.quad(thickness, p_t, p_BL)[0] #thetae0 = thermo.theta_e(T_s, p_s, q_sat, 0) #T_LCL = findTmoist(thetae0, p_BL) dels_trop = c.cpd * (T_BLc - T_t) + g * (-delz_trop) omega_BL = (g * Q_dtrop) / dels_trop coef = (2 / (PI_s - PI_BL)) * (omega_BL / (2 * delp_BL))**2 T_BLc_test = T_s + coef * (-0.5 * (2 * l_d**2 - (l_d**4 + l_m**4) / l_m**2) + (c_D / delz_BL) * ((-8 / 3) * l_d**3 + (l_d**4 + 2 * l_m**2 * l_d**2 - (1 / 3) * l_m**4) / l_m)) return (l_m - ((omega_BL*l_d**2)/(omega_BL - (g*Q_mtrop)/(dels_trop + (1+ alpha/(1-alpha))*L_v*(f*q_sat - q_FA))))**(0.5), \ q_BLm - q_sat + (2*zhat*(q_FAd - q_sat))/(l_d**2 - l_m**2)*(l_m + zhat - (zhat + l_d)*np.exp((l_m - l_d)/zhat)), \ T_BLc - T_BLc_test)
def convecSkew(figNum): """ Usage: convecSkew(figNum) Input: figNum = integer Takes any integer, creates figure(figNum), and plots a skewT logp thermodiagram. Output: skew=30. """ c = constants(); plt.figure(figNum); plt.clf(); yplot = range(1000,190,-10) xplot = range(-300,-139) pvals = np.size(yplot) tvals = np.size(xplot) temp = np.zeros([pvals, tvals]); theTheta = np.zeros([pvals, tvals]); ws = np.zeros([pvals, tvals]); theThetae = np.zeros([pvals, tvals]); skew = 30; #skewness factor (deg C) # lay down a reference grid that labels xplot,yplot points # in the new (skewT-lnP) coordinate system . # Each value of the temp matrix holds the actual (data) # temperature label (in deg C) of the xplot, yplot coordinate. # pairs. The transformation is given by W&H 3.56, p. 78. Note # that there is a sign difference, because rather than # taking y= -log(P) like W&H, I take y= +log(P) and # then reverse the y axis for i in yplot: for j in xplot: # Note that we don't have to transform the y # coordinate, as it is still pressure. iInd = yplot.index(i) jInd = xplot.index(j) temp[iInd, jInd] = convertSkewToTemp(j, i, skew); Tk = c.Tc + temp[iInd, jInd]; pressPa = i * 100.; theTheta[iInd, jInd] = theta(Tk, pressPa); ws[iInd, jInd] = wsat(Tk, pressPa); theThetae[iInd, jInd] = thetaes(Tk, pressPa); # # Contour the temperature matrix. # # First, make sure that all plotted lines are solid. mpl.rcParams['contour.negative_linestyle'] = 'solid' tempLabels = range(-40, 50, 10); output1 = plt.contour(xplot, yplot, temp, tempLabels, \ colors='k') # # Customize the plot # plt.setp(plt.gca(), yscale='log') locs = np.array(range(100, 1100, 100)) labels = locs plt.yticks(locs, labels) # Conventionally labels semilog graph. plt.setp(plt.gca(), ybound=(200, 1000)) plt.setp(plt.getp(plt.gca(), 'xticklabels'), fontweight='bold') plt.setp(plt.getp(plt.gca(),'yticklabels'), fontweight='bold') plt.grid(True) plt.setp(plt.gca().get_xgridlines(), visible=False) plt.hold(True); thetaLabels = range(200, 380, 10); output2 = plt.contour(xplot, yplot, theTheta, thetaLabels, \ colors='b'); wsLabels = range(6, 24, 2); output3 = plt.contour(xplot, yplot, (ws * 1.e3), wsLabels, \ colors='g'); thetaeLabels = range(250, 380, 10); output4 = plt.contour(xplot, yplot, theThetae, thetaeLabels, \ colors='r'); # Transform the temperature,dewpoint from data coords to # plotting coords. plt.title('skew T - lnp chart'); plt.ylabel('pressure (hPa)'); plt.xlabel('temperature (deg C)'); # # Crop image to a more usable size # TempTickLabels = range(5, 35, 5); TempTickCoords = TempTickLabels; skewTickCoords = convertTempToSkew(TempTickCoords, 1.e3, skew); plt.xticks(skewTickCoords, TempTickLabels) skewLimits = convertTempToSkew([5, 30], 1.e3, skew); plt.axis([skewLimits[0], skewLimits[1], 600, 1.e3]); # # Create line labels # fntsz = 9 # Handle for 'fontsize' of the line label. ovrlp = 1 # Handle for 'inline'. Any integer other than 0 # creates a white space around the label. plt.clabel(output1, inline=ovrlp, fmt='%1d', fontsize=fntsz); plt.clabel(output2, inline=ovrlp, fmt='%1d', fontsize=fntsz); plt.clabel(output3, inline=ovrlp, fmt='%1d', fontsize=fntsz); plt.clabel(output4, inline=ovrlp, fmt='%1d', fontsize=fntsz); # # Flip the y axis # plt.setp(plt.gca(), ylim=plt.gca().get_ylim()[::-1]) return skew
dsdz = (s[1:, :, :] - s[:-1, :, :]) / (diffz3D) W_adb = (c.cp * QRAD_tave[:-1, :, :]) / (dsdz * 3600 * 24) W_diab = W_tave[:-1, :, :] - blockave3D(W_adb, db) field_tave = W_diab #calculate RH elif varname == 'TABS': varname = 'RH' QV = varis3D['QV'][t3 - aveperiod3D:t3, :, :, :] QV_tave = np.mean(QV, axis=0) TABS = varis3D['TABS'][t3 - aveperiod3D:t3, :, :, :] TABS_tave = np.mean(TABS, axis=0) RH_tave = np.zeros(QV_tave.shape) for pi, plev in enumerate(p): wsat_tave = 1000 * wsat(TABS_tave[pi, :, :], plev) #convert to g/kg RH_tave[pi, :, :] = 100 * (QV_tave[pi, :, :] / wsat_tave ) #convert to percent field_tave = RH_tave field_tave = blockave3D(field_tave, db) elif varname == 'VERTMASSFLUX': w = varis3D['W'][t3 - aveperiod3D:t3, :, :, :] T = varis3D['TABS'][t3 - aveperiod3D:t3, :, :, :] nt = T.shape[0] p3D = np.zeros((ny, nx, nz)) p3D[:, :, :] = p p3D = p3D[:, :, :, np.newaxis] p4D = np.tile(p3D, nt) p4D = p4D.T gc.collect()
field_tave = np.mean(field_tave[t3/ntave3D-nave:t3/ntave3D,:,:,:],axis=0) delz3D = np.zeros((nx, ny, nz-1)) delz3D[:,:,:] = np.diff(z) delz3D = delz3D.T field_tave = field_tave*delz3D znew = z[:-1] #calculate relative humidity elif varname == 'TABS': varname = 'RH' QV = varis3D['QV'][t3-aveperiod3D:t3,:,:,:] T = varis3D['TABS'][t3-aveperiod3D:t3,:,:,:] T_tave = np.mean(T, axis=0) QV_tave = np.mean(QV, axis=0) RH_tave = np.zeros(QV_tave.shape) for i, plev in enumerate(p): wsat_tave = 1000*wsat(T_tave[i,:,:], plev) #convert to g/kg RH_tave[i,:,:] = 100*(QV_tave[i,:,:]/wsat_tave) #convert to percent field_tave = RH_tave ##UNCOMMENT TO CALCULATE TABS PERTURBATION #vari = varis3D['TABS'] #varname = 'TABSprime' #TABS = varis3D['TABS'][t3-aveperiod3D:t3,:,:,:] #T_tave = np.mean(TABS, axis=0) #T_bar = np.mean(np.mean(T_tave, axis=2), axis=1) #T_bar3D = np.zeros(T_tave.shape) #T_bar3D = T_bar3D.T #T_bar3D[:,:,:] = T_bar #T_bar3D = T_bar3D.T #Tprime = T_tave - T_bar3D #field_tave = Tprime
import site import sys site.addsitedir('/Users/cpatrizio/Dropbox/research/code/thermlib/') import findTmoist import findTmoist_new from wsat import wsat from constants import constants import numpy as np import thermo import matplotlib.pyplot as plt T_s = 302 p_s = 1000e2 p_t = 200e2 q_sat = wsat(T_s, p_s) thetae0 = thermo.theta_e(T_s, p_s, q_sat, 0) plevs = np.linspace(p_t, p_s, 1000)[::-1] delp = np.diff(plevs)[0] c = constants() gamma_m = 6.5 / 1000. #lapse rate in K m^-1 gamma_d = 9.8 / 1000. #lapse rate in K m^-1 Tgm = np.zeros(plevs.shape) Tgd = np.zeros(plevs.shape) Tgm[0] = T_s Tgd[0] = T_s
import site import sys site.addsitedir('/Users/cpatrizio/Dropbox/research/code/thermlib/') import findTmoist import findTmoist_new from wsat import wsat from constants import constants import numpy as np import thermo import matplotlib.pyplot as plt T_s = 302 p_s = 1000e2 p_t = 200e2 q_sat = wsat(T_s, p_s) thetae0 = thermo.theta_e(T_s, p_s, q_sat, 0) plevs = np.linspace(p_t, p_s, 1000)[::-1] delp = np.diff(plevs)[0] c = constants() gamma_m = 6.5/1000. #lapse rate in K m^-1 gamma_d = 9.8/1000. #lapse rate in K m^-1 Tgm = np.zeros(plevs.shape) Tgd = np.zeros(plevs.shape) Tgm[0] = T_s
axis=0) delz3D = np.zeros((nx, ny, nz - 1)) delz3D[:, :, :] = np.diff(z) delz3D = delz3D.T field_tave = field_tave * delz3D znew = z[:-1] #calculate relative humidity elif varname == 'TABS': varname = 'RH' QV = varis3D['QV'][t3 - aveperiod3D:t3, :, :, :] T = varis3D['TABS'][t3 - aveperiod3D:t3, :, :, :] T_tave = np.mean(T, axis=0) QV_tave = np.mean(QV, axis=0) RH_tave = np.zeros(QV_tave.shape) for i, plev in enumerate(p): wsat_tave = 1000 * wsat(T_tave[i, :, :], plev) #convert to g/kg RH_tave[i, :, :] = 100 * (QV_tave[i, :, :] / wsat_tave ) #convert to percent field_tave = RH_tave ##UNCOMMENT TO CALCULATE TABS PERTURBATION #vari = varis3D['TABS'] #varname = 'TABSprime' #TABS = varis3D['TABS'][t3-aveperiod3D:t3,:,:,:] #T_tave = np.mean(TABS, axis=0) #T_bar = np.mean(np.mean(T_tave, axis=2), axis=1) #T_bar3D = np.zeros(T_tave.shape) #T_bar3D = T_bar3D.T #T_bar3D[:,:,:] = T_bar #T_bar3D = T_bar3D.T #Tprime = T_tave - T_bar3D
RHs = np.zeros(len(domsizes)) Ps = np.zeros(len(domsizes)) delhs = np.zeros(len(domsizes)) p_LCLs = np.zeros(len(domsizes)) eps_BLs = np.linspace(0.1, 0.8, 10) eps_as = np.linspace(0.1, 0.8, 10) eps_BLss, eps_ass = np.meshgrid(eps_BLs, eps_as) p_outs = np.zeros(eps_BLss.shape) #p_BLs = np.zeros(eps_BLss.shape) #T_as = np.zeros(eps_BLss.shape) q_sat = wsat(T_s, p_s) #mixing ratio above sea surface (100% saturated) thetae0 = thermo.theta_e(T_s, p_s, q_sat, 0) #theta_e in moist region #use surface temperature to get moist adiabat plevs = np.linspace(50e2, p_s, 1000) Tadb = findTmoist(thetae0, plevs) for i, eps_BL in enumerate(eps_BLs): print 'eps_BL', eps_BL for j, eps_a in enumerate(eps_as): print 'eps_a', eps_a
LWupt[k] = epslw[k]*sig*T[k]**4 + (1-epslw[k])*LWupb[k] LWdownt[N-k] = LWdownb[N-k+1] LWdownb[N-k] = 0 SWdownt[N-k] = S SWdownb[N-k] = 0 else: LWupb[k] = LWupt[k-1] LWupt[k] = epslw[k]*sig*T[k]**4 + (1-epslw[k])*LWupb[k] LWdownt[N-k] = LWdownb[N-k+1] LWdownb[N-k] = epslw[N-k]*sig*T[N-k]**4 + (1-epslw[N-k])*LWdownt[N-k] SWdownt[N-k] = SWdownb[N-k+1] SWdownb[N-k] = (1-epssw[N-k])*SWdownt[N-k] Tslab = T[0] Tatm = T[1] qv[0] = wsat(T[0], p_s) #the boundary layer temp is the mean temp below delz_BL #T_BL = np.mean(T[1:BL_index]) SH = rho*cp*Ce*V*(Tslab - Tatm) qvflux = rho*Ce*V*(qv[0] - qv[1]) if qvflux < 0: qvflux = 0 LE = Lv*qvflux qv[1] = qv[1] + delz[0]*qvflux Fnet = LWupb - LWupt + LWdownt - LWdownb + SWdownt - SWdownb Fnet[0] = Fnet[0] - SH - LE Fnet[1] = Fnet[1] + SH + LE #distribute the sensible and latent heat evenly (and simultaneously) throughout the boundary layer. #for i in range(1, BL_index): # Fnet[i] = Fnet[i] + (SH + LE)*(delz[i]/delz_BL)
RHs = np.zeros(len(domsizes)) Ps = np.zeros(len(domsizes)) delhs = np.zeros(len(domsizes)) delhseff = np.zeros(len(domsizes)) p_LCLs = np.zeros(len(domsizes)) q_BLms = np.zeros(len(domsizes)) omega_ms = np.zeros(len(domsizes)) for j, domsize in enumerate(domsizes): l_d = domsize * 1000 print l_d / 1e3 r = np.linspace(0, l_d, 1e6) q_sat = wsat(T_s, p_s) #mixing ratio above sea surface (100% saturated) thetae0 = thermo.theta_e(T_s, p_s, q_sat, 0) #theta_e in moist region #use surface temperature to get moist adiaba T_BLtop = findTmoist(thetae0, p_BL) #temperature of boundary layer top T_t = findTmoist(thetae0, p_t) #temperature of tropopause (outflow region) #T_BL = (T_s + T_BLtop)/2. #temperature of boundary layer, consistent with well-mixed assumption (linear mixing) T_BL = T_s q_BLsat = wsat(T_BL, (p_s + p_BL) / 2.) q_BLtopsat = wsat(T_BLtop, p_BL) q_FA = wsat(T_t, p_t) #free troposphere water vapor mixing ratio #q_FA = 0.01 q_FAd = q_FA
dsdz = (s[1:,:,:] - s[:-1,:,:])/(diffz3D) W_adb = (c.cp*QRAD_tave[:-1,:,:])/(dsdz*3600*24) W_diab = W_tave[:-1,:,:] - blockave3D(W_adb, db) field_tave = W_diab #calculate RH elif varname == 'TABS': varname = 'RH' QV = varis3D['QV'][t3-aveperiod3D:t3,:,:,:] QV_tave = np.mean(QV, axis=0) TABS = varis3D['TABS'][t3-aveperiod3D:t3,:,:,:] TABS_tave = np.mean(TABS, axis=0) RH_tave = np.zeros(QV_tave.shape) for pi, plev in enumerate(p): wsat_tave = 1000*wsat(TABS_tave[pi,:,:], plev) #convert to g/kg RH_tave[pi,:,:] = 100*(QV_tave[pi,:,:]/wsat_tave) #convert to percent field_tave = RH_tave field_tave = blockave3D(field_tave, db) elif varname == 'VERTMASSFLUX': w = varis3D['W'][t3-aveperiod3D:t3,:,:,:] T = varis3D['TABS'][t3-aveperiod3D:t3,:,:,:] nt = T.shape[0] p3D = np.zeros((ny, nx, nz)) p3D[:,:,:] = p p3D = p3D[:,:,:,np.newaxis] p4D = np.tile(p3D,nt) p4D = p4D.T gc.collect() rho = p4D/(T*c.Rd)
LWdownb[N-k] = 0 SWdownt[N-k] = S SWdownb[N-k] = 0 else: LWupb[k] = LWupt[k-1] LWupt[k] = epslw[k]*sig*T[k]**4 + (1-epslw[k])*LWupb[k] LWdownt[N-k] = LWdownb[N-k+1] LWdownb[N-k] = epslw[N-k]*sig*T[N-k]**4 + (1-epslw[N-k])*LWdownt[N-k] SWdownt[N-k] = SWdownb[N-k+1] SWdownb[N-k] = (1-epssw[N-k])*SWdownt[N-k] Tslab = T[0] Tatm = T[1] #T_BL = np.mean(T[1:BL_index]) SH = rho*cp*Ce*V*(Tslab - Tatm) LE = Lv*rho*Ce*V*(wsat(T[0], p_s) - qv[0]) Q_ocean = 25 #horizontal heat transport by ocean (W m^-2) Fnet = LWupb - LWupt + LWdownt - LWdownb + SWdownt - SWdownb Fnet[0] = Fnet[0] - SH - Q_ocean - LE Fnet[1] = Fnet[1] + SH + LE #distribute the sensible and latent heat evenly (and simultaneously) throughout the boundary layer. #for i in range(1, BL_index): # Fnet[i] = Fnet[i] + (SH)*(delz[i]/delz_BL) # T[i] = T[i] + (deltat*Fnet[i])/(m*cp) #T[BL_index:] = T[BL_index:] + (deltat*Fnet[BL_index:])/(m*cp) T[1:] = T[1:] + (deltat*Fnet[1:])/(m*cp) T[0] = T[0] + (deltat*Fnet[0])/(h*cw*rhow) #T = T + (deltat*Fnet)/(m*cp)
LWdownt[N - k] = LWdownb[N - k + 1] LWdownb[N - k] = 0 SWdownt[N - k] = S SWdownb[N - k] = 0 else: LWupb[k] = LWupt[k - 1] LWupt[k] = epslw[k] * sig * T[k]**4 + (1 - epslw[k]) * LWupb[k] LWdownt[N - k] = LWdownb[N - k + 1] LWdownb[N - k] = epslw[N - k] * sig * T[N - k]**4 + ( 1 - epslw[N - k]) * LWdownt[N - k] SWdownt[N - k] = SWdownb[N - k + 1] SWdownb[N - k] = (1 - epssw[N - k]) * SWdownt[N - k] Tslab = T[0] Tatm = T[1] qv[0] = wsat(T[0], p_s) #the boundary layer temp is the mean temp below delz_BL #T_BL = np.mean(T[1:BL_index]) SH = rho * cp * Ce * V * (Tslab - Tatm) qvflux = rho * Ce * V * (qv[0] - qv[1]) if qvflux < 0: qvflux = 0 LE = Lv * qvflux qv[1] = qv[1] + delz[0] * qvflux Fnet = LWupb - LWupt + LWdownt - LWdownb + SWdownt - SWdownb Fnet[0] = Fnet[0] - SH - LE Fnet[1] = Fnet[1] + SH + LE #distribute the sensible and latent heat evenly (and simultaneously) throughout the boundary layer. #for i in range(1, BL_index): # Fnet[i] = Fnet[i] + (SH + LE)*(delz[i]/delz_BL)
p_BLs = np.zeros(eps_BLss.shape) #T_as = np.zeros(eps_BLss.shape) omega_BLs = np.zeros(eps_BLss.shape) w_BLs = np.zeros(eps_BLss.shape) w_ms = np.zeros(eps_BLss.shape) l_ms = np.zeros(eps_BLss.shape) T_BLs = np.zeros(eps_BLss.shape) netprecip = np.zeros(eps_BLss.shape) RH_ms = np.zeros(eps_BLss.shape) delhs = np.zeros(eps_BLss.shape) massbalance = np.zeros(eps_BLss.shape) p_LCLs = np.zeros(eps_BLss.shape) q_sat = wsat(T_s, p_s) #mixing ratio above sea surface (100% saturated) thetae0 = thermo.theta_e(T_s, p_s, q_sat, 0) #theta_e in moist region #use surface temperature to get moist adiabat plevs = np.linspace(50e2, p_s, 1000) #Tadb = findTmoist(thetae0, plevs) omega_BLs = np.zeros(eps_BLss.shape) w_BLs = np.zeros(eps_BLss.shape) T_out = findT(T_s, p_out) T_strat = T_out #T_strat = np.mean(findTmoist(thetae0, np.linspace(95,p_out,50))) #rho_BL = p_s/(c.Rd*T_BL) s_surf = c.cpd*T_s #dry static energy at surface q_FA = wsat(T_out, p_out)
def thetaep(Td, T, p): """ thetaep(Td, T, p) Calculates the pseudo equivalent potential temperature of a parcel. Parameters - - - - - - Td : float Dewpoint temperature (K). T : float Temperature (K). p : float Pressure (Pa). Returns - - - - thetaepOut : float Pseudo equivalent potential temperature (K). Notes - - - Note that the pseudo equivalent potential temperature of an air parcel is not a conserved variable. References - - - - - - Emanuel 4.7.9 p. 132 Examples - - - - - >>> thetaep(280., 300., 8.e4) # Parcel is unsaturated. 344.99830738253371 >>> thetaep(300., 280., 8.e4) # Parcel is saturated. 321.5302927767795 """ c = constants() if Td < T: #parcel is unsaturated [Tlcl, plcl] = LCLfind(Td, T, p) wv = wsat(Td, p) else: #parcel is saturated -- prohibit supersaturation with Td > T Tlcl = T wv = wsat(T, p) # $$$ disp('inside theate') # $$$ [Td,T,wv] thetaval = theta(T, p, wv) power = 0.2854 * (1 - 0.28 * wv) thetaep = thetaval * np.exp(wv * (1 + 0.81 * wv) \ * (3376. / Tlcl - 2.54)) # # peg this at 450 so rootfinder won't blow up # #thetaepOut = thetaep #if(thetaepOut > 450.): # thetaepOut = 450; return thetaep
p_BLs = np.zeros(eps_BLss.shape) #T_as = np.zeros(eps_BLss.shape) omega_BLs = np.zeros(eps_BLss.shape) w_BLs = np.zeros(eps_BLss.shape) w_ms = np.zeros(eps_BLss.shape) l_ms = np.zeros(eps_BLss.shape) T_BLs = np.zeros(eps_BLss.shape) netprecip = np.zeros(eps_BLss.shape) RH_ms = np.zeros(eps_BLss.shape) delhs = np.zeros(eps_BLss.shape) massbalance = np.zeros(eps_BLss.shape) p_LCLs = np.zeros(eps_BLss.shape) q_sat = wsat(T_s, p_s) #mixing ratio above sea surface (100% saturated) thetae0 = thermo.theta_e(T_s, p_s, q_sat, 0) #theta_e in moist region #use surface temperature to get moist adiabat plevs = np.linspace(50e2, p_s, 1000) #Tadb = findTmoist(thetae0, plevs) omega_BLs = np.zeros(eps_BLss.shape) w_BLs = np.zeros(eps_BLss.shape) #T_out = findT(T_s, p_out) T_out = findTmoist(thetae0, p_out) T_strat = T_out #T_strat = np.mean(findTmoist(thetae0, np.linspace(95,p_out,50))) #rho_BL = p_s/(c.Rd*T_BL) s_surf = c.cpd*T_s #dry static energy at surface
def findT(T_s, p): zeta = -h*np.log(p/p_s) if (zeta < zeta_T): T = T_s - gamma_PH*zeta else: T = T_s - gamma_PH*zeta_T return T for i, T_s in enumerate(fs): q_sat = wsat(T_s, p_s) #mixing ratio above sea surface (100% saturated) thetae0 = thermo.theta_e(p_s, T_s, q_sat, 0) #theta_e in moist region #use surface temperature to get moist adiabat T_t = findT(T_s, p_t) #temperature of tropopause (outflow region) T_BLtop = findT(T_s, p_BL) #temperature of boundary layer top T_BL = (T_s + T_BLtop)/2. #temperature of boundary layer, consistent with well-mixed assumption (linear mixing) q_BLsat = wsat(T_BL, (p_s + p_BL)/2.) q_BLtopsat = wsat(T_BLtop, p_BL) #p_lcl, T_lcl = findLCL0(f*q_sat, p_s, T_BL) M_trop = (p_BL - p_t)/g #mass of troposphere in kg m^-2 M_BL = (p_s - p_BL)/g #mass of boundary layer in kg m^-2 #delz_BL = ((c.Rd*T_BL)/g)*np.log(p_s/p_BL) #boundary layer thickness (m) rho_BLtop = p_BL/(c.Rd*T_BLtop)
SWdownt[N - k] = S SWdownb[N - k] = 0 else: LWupb[k] = LWupt[k - 1] LWupt[k] = epslw[k] * sig * T[k]**4 + (1 - epslw[k]) * LWupb[k] LWdownt[N - k] = LWdownb[N - k + 1] LWdownb[N - k] = epslw[N - k] * sig * T[N - k]**4 + ( 1 - epslw[N - k]) * LWdownt[N - k] SWdownt[N - k] = SWdownb[N - k + 1] SWdownb[N - k] = (1 - epssw[N - k]) * SWdownt[N - k] Tslab = T[0] Tatm = T[1] #T_BL = np.mean(T[1:BL_index]) SH = rho * cp * Ce * V * (Tslab - Tatm) LE = Lv * rho * Ce * V * (wsat(T[0], p_s) - qv[0]) Q_ocean = 25 #horizontal heat transport by ocean (W m^-2) Fnet = LWupb - LWupt + LWdownt - LWdownb + SWdownt - SWdownb Fnet[0] = Fnet[0] - SH - Q_ocean - LE Fnet[1] = Fnet[1] + SH + LE #distribute the sensible and latent heat evenly (and simultaneously) throughout the boundary layer. #for i in range(1, BL_index): # Fnet[i] = Fnet[i] + (SH)*(delz[i]/delz_BL) # T[i] = T[i] + (deltat*Fnet[i])/(m*cp) #T[BL_index:] = T[BL_index:] + (deltat*Fnet[BL_index:])/(m*cp) T[1:] = T[1:] + (deltat * Fnet[1:]) / (m * cp) T[0] = T[0] + (deltat * Fnet[0]) / (h * cw * rhow) #T = T + (deltat*Fnet)/(m*cp) #print 'radiative temp. profile', T
Ps = np.zeros(len(domsizes)) delhs = np.zeros(len(domsizes)) delhseff = np.zeros(len(domsizes)) p_LCLs = np.zeros(len(domsizes)) for j, domsize in enumerate(domsizes): l_d = domsize*1000 print l_d/1e3 r = np.linspace(0, l_d, 1e6) q_sat = wsat(T_s, p_s) #mixing ratio above sea surface (100% saturated) thetae0 = thermo.theta_e(T_s, p_s, q_sat, 0) #theta_e in moist region #use surface temperature to get moist adiaba T_BLtop = findTmoist(thetae0, p_BL) #temperature of boundary layer top T_t = findTmoist(thetae0, p_t) #temperature of tropopause (outflow region) #T_BL = (T_s + T_BLtop)/2. #temperature of boundary layer, consistent with well-mixed assumption (linear mixing) T_BL = T_s q_BLsat = wsat(T_BL, (p_s + p_BL)/2.) q_BLtopsat = wsat(T_BLtop, p_BL) q_FA = wsat(T_t, p_t) #free troposphere water vapor mixing ratio #q_FA = 0.01 q_FAd = q_FA
def thetaep(Td, T, p): """ thetaep(Td, T, p) Calculates the pseudo equivalent potential temperature of a parcel. Parameters - - - - - - Td : float Dewpoint temperature (K). T : float Temperature (K). p : float Pressure (Pa). Returns - - - - thetaepOut : float Pseudo equivalent potential temperature (K). Notes - - - Note that the pseudo equivalent potential temperature of an air parcel is not a conserved variable. References - - - - - - Emanuel 4.7.9 p. 132 Examples - - - - - >>> thetaep(280., 300., 8.e4) # Parcel is unsaturated. 344.99830738253371 >>> thetaep(300., 280., 8.e4) # Parcel is saturated. 321.5302927767795 """ c = constants(); if Td < T: #parcel is unsaturated [Tlcl, plcl] = LCLfind(Td, T, p); wv = wsat(Td, p); else: #parcel is saturated -- prohibit supersaturation with Td > T Tlcl = T; wv = wsat(T, p); # $$$ disp('inside theate') # $$$ [Td,T,wv] thetaval = theta(T, p, wv); power = 0.2854 * (1 - 0.28 * wv); thetaep = thetaval * np.exp(wv * (1 + 0.81 * wv) \ * (3376. / Tlcl - 2.54)); # # peg this at 450 so rootfinder won't blow up # if(thetaepOut > 450.): thetaepOut = 450; return thetaepOut