def calcTvDiff(press, thetae0, interpTenv, interpTdEnv): """ Calculates the virtual temperature difference between the thetae0 moist adiabat and a given sounding at some pressure. Parameters - - - - - - press: pressure (Pa) thetae0: equivalent potential temperature of the adiabat (K) interpTenv: interpolator for environmental temperature (deg C) interpTdEnv: interpolator for environmental dew point temperature (deg C) Returns - - - - - - TvDiff: the virtual temperature difference at pressure press between the thetae0 moist adiabat and the given sounding (K). """ c = constants() Tcloud=findTmoist(thetae0,press) wvcloud=wsat(Tcloud,press) Tvcloud=Tcloud*(1. + c.eps*wvcloud) Tenv=interpTenv(press*1.e-2) + c.Tc Tdenv=interpTdEnv(press*1.e-2) + c.Tc wvenv=wsat(Tdenv,press) Tvenv=Tenv*(1. + c.eps*wvenv) return Tvcloud - Tvenv
def calcBuoy(height, thetae0, interpTenv, interpTdEnv, interpPress): #input: height (m), thetae0 (K), plus function handles for #T,Td, press soundings #output: Bout = buoyant acceleration in m/s^2 #neglect liquid water loading in the virtual temperature press=interpPress(height)*100.#%Pa Tcloud=findTmoist(thetae0,press) #K wvcloud=wsat(Tcloud,press); #kg/kg Tvcloud=Tcloud*(1. + c.eps*wvcloud) Tenv=interpTenv(height) + c.Tc Tdenv=interpTdEnv(height) + c.Tc wvenv=wsat(Tdenv,press); #kg/kg Tvenv=Tenv*(1. + c.eps*wvenv) TvDiff=Tvcloud - Tvenv #print '%10.3f %10.3f %10.3f\n' %(press*0.01,height,TvDiff) return c.g0*(TvDiff/Tvenv)
def F(t, y, entrain_rate, interpTenv, interpTdEnv, interpPress): yp = np.zeros((4,1)) velocity = y[0] height = y[1] thetae_cloud = y[2] wT_cloud = y[3] #yp[0] is the acceleration, in this case the buoyancy yp[0] = calcBuoy(height, thetae_cloud, interpTenv, interpTdEnv, interpPress) press = interpPress(height)*100. #Pa Tdenv = interpTdEnv(height) + c.Tc #K Tenv = interpTenv(height) + c.Tc #K wTenv = wsat(Tdenv, press) #kg/kg thetaeEnv = thetaep(Tdenv, Tenv, press) #yp[1] is the rate of change of height yp[1] = velocity #yp[2] is the rate of change of thetae_cloud yp[2] = entrain_rate*(thetaeEnv - thetae_cloud) #yp[3] is the rate of change of wT_cloud yp[3] = entrain_rate*(wTenv - wT_cloud) return yp
def answer_entrain(): filename = 'littlerock.nc' print 'reading file: %s\n' %(filename) nc_file = Dataset(filename) var_names = nc_file.variables.keys() print nc_file.ncattrs() print nc_file.units print nc_file.col_names sound_var = nc_file.variables[var_names[3]] press = sound_var[:,0] height = sound_var[:,1] temp = sound_var[:,2] dewpoint = sound_var[:,3] #height must have unique values envHeight= nudge(height) #Tenv and TdEnv interpolators return temp. in deg C, given height in m #Press interpolator returns pressure in hPa given height in m interpTenv = lambda zVals: np.interp(zVals, envHeight, temp) interpTdEnv = lambda zVals: np.interp(zVals, envHeight, dewpoint) interpPress = lambda zVals: np.interp(zVals, envHeight, press) p900_level = np.where(abs(900 - press) < 2.) p800_level = np.where(abs(800 - press) < 7.) thetaeVal=thetaep(dewpoint[p900_level] + c.Tc,temp[p900_level] + c.Tc,press[p900_level]*100.) height_800=height[p800_level] wTcloud = wsat(dewpoint[p900_level] + c.Tc, press[p900_level]*100.) entrain_rate = 2.e-4 winit = 0.5 #initial velocity (m/s) yinit = [winit, height_800, thetaeVal, wTcloud] tinit = 0 tfin = 2500 dt = 10 #want to integrate F using ode45 (from MATLAB) equivalent integrator r = ode(F).set_integrator('dopri5') r.set_f_params(entrain_rate, interpTenv, interpTdEnv, interpPress) r.set_initial_value(yinit, tinit) y = np.array(yinit) t = np.array(tinit) #stop tracking the parcel when the time runs out, or if the parcel stops moving/is desecnding while r.successful() and r.t < tfin and r.y[0] > 0: #find y at the next time step #(r.integrate(t) updates the fields r.y and r.t so that r.y = F(t) and r.t = t #where F is the function being integrated) r.integrate(r.t+dt) if r.y[0] <= 0: break #keep track of y at each time step y = np.vstack((y, r.y)) t = np.vstack((t, r.t)) wvel = y[:,0] cloud_height = y[:,1] thetae_cloud = y[:,2] wT_cloud = y[:,3] plt.figure(1) plt.plot(wvel, cloud_height) plt.xlabel('vertical velocity (m/s)') plt.ylabel('height above surface (m)') plt.gca().set_title('vertical velocity of a cloud parcel vs height,\ entrainment rate of %4.1e $s^{-1}$' %entrain_rate) Tcloud = np.zeros(cloud_height.size) wvCloud = np.zeros(cloud_height.size) wlCloud = np.zeros(cloud_height.size) for i in range(0, len(cloud_height)): the_press = interpPress(cloud_height[i])*100. Tcloud[i], wvCloud[i], wlCloud[i] = tinvert_thetae(thetae_cloud[i], wT_cloud[i], the_press) Tadia= np.zeros(cloud_height.size) wvAdia = np.zeros(cloud_height.size) wlAdia = np.zeros(cloud_height.size) for i in range(0, len(cloud_height)): the_press = interpPress(cloud_height[i])*100. Tadia[i], wvAdia[i], wlAdia[i] = tinvert_thetae(thetae_cloud[0], wT_cloud[0], the_press) plt.figure(2) TcloudHandle, = plt.plot(Tcloud - c.Tc, cloud_height, 'r-') TenvHandle, = plt.plot(temp, envHeight, 'g-') TadiaHandle, = plt.plot(Tadia - c.Tc, cloud_height, 'b-') plt.xlabel('temperature (deg C)') plt.ylabel('height above surface (m)') plt.gca().set_title('temp. of rising cloud parcel vs height,\ entrainment rate of %4.1e $s^{-1}$' %entrain_rate) plt.gca().legend([TcloudHandle, TenvHandle, TadiaHandle],['cloud', 'environment', 'moist adiabat']) plt.show()
def convecSkew(figNum): """ Usage: convecSkew(figNum) Input: figNum = integer Takes any integer, creates figure(figNum), and plots a skewT logp thermodiagram. Output: skew=30 and the handle for the plot """ fig=plt.figure(figNum) fig.clf() ax1=fig.add_subplot(111) 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) tempLevs = ax1.contour(xplot, yplot, temp, tempLabels, \ colors='k') # # Customize the plot # ax1.set_yscale('log') locs = np.array(range(100, 1100, 100)) labels = locs ax1.set_yticks(locs) ax1.set_yticklabels(labels) # Conventionally labels semilog graph. ax1.set_ybound((200, 1000)) plt.setp(ax1.get_xticklabels(), weight='bold') plt.setp(ax1.get_yticklabels(), weight='bold') ax1.yaxis.grid(True) thetaLabels = range(200, 390, 10) thetaLevs = ax1.contour(xplot, yplot, theTheta, thetaLabels, \ colors='b') wsLabels =[0.1,0.25,0.5,1,2,3] + range(4, 20, 2) + [20,24,28] wsLevs = ax1.contour(xplot, yplot, (ws * 1.e3), wsLabels, \ colors='g') thetaeLabels = np.arange(250, 410, 10) thetaeLevs = ax1.contour(xplot, yplot, theThetae, thetaeLabels, \ colors='r') # Transform the temperature,dewpoint from data coords to # plotting coords. ax1.set_title('skew T - lnp chart') ax1.set_ylabel('pressure (hPa)') ax1.set_xlabel('temperature (deg C)') # # Crop image to a more usable size # TempTickLabels = range(-15, 40, 5) TempTickCoords = TempTickLabels skewTickCoords = convertTempToSkew(TempTickCoords, 1.e3, skew) ax1.set_xticks(skewTickCoords) ax1.set_xticklabels(TempTickLabels) skewLimits = convertTempToSkew([-15, 35], 1.e3, skew) ax1.axis([skewLimits[0], skewLimits[1], 300, 1.e3]) # # Create line labels # fntsz = 9 # Handle for 'fontsize' of the line label. ovrlp = True # Handle for 'inline'. Any integer other than 0 # creates a white space around the label. thetaeLevs.clabel(thetaeLabels, inline=ovrlp, fmt='%5d', fontsize=fntsz,use_clabeltext=True) tempLevs.clabel(inline=ovrlp, fmt='%2d', fontsize=fntsz,use_clabeltext=True) thetaLevs.clabel(inline=ovrlp, fmt='%5d', fontsize=fntsz,use_clabeltext=True) wsLevs.clabel(inline=ovrlp, fmt='%2d', fontsize=fntsz,use_clabeltext=True) #print thetaeLabels # # Flip the y axis # ax1.invert_yaxis() ax1.figure.canvas.draw() return skew, ax1
xplot2=convertTempToSkew(Tdew,press,skew) TdHandle, = plt.plot(xplot2,press,'b--', linewidth=2.5) plt.title('convectively unstable sounding: base at 900 hPa') plt.show() #print -dpdf initial_sound.pdf #put on the top and bottom LCLs and the thetae sounding Tlcl=np.zeros(numPoints) pLCL=np.zeros(numPoints) theTheta=np.zeros(numPoints) theThetae=np.zeros(numPoints) Tpseudo=np.zeros(numPoints) wtotal=np.zeros(numPoints) for i in range(0, numPoints): wtotal[i]=wsat(Tdew[i] + c.Tc,press[i]*100.); Tlcl[i],pLCL[i]=LCLfind(Tdew[i] + c.Tc,Temp[i]+c.Tc,press[i]*100.) theThetae[i]=thetaep(Tdew[i] + c.Tc,Temp[i] + c.Tc,press[i]*100.) #find the temperature along the pseudo adiabat at press[i] Tpseudo[i]=findTmoist(theThetae[i],press[i]*100.) #no liquid water in sounding xplot=convertTempToSkew(Tlcl[0] - c.Tc,pLCL[0]*0.01,skew); bot,=plt.plot(xplot,pLCL[0]*0.01,'ro',markersize=12, markerfacecolor ='r') xplot=convertTempToSkew(Tlcl[-1] - c.Tc,pLCL[-1]*0.01,skew) top,=plt.plot(xplot,pLCL[-1]*0.01,'bd',markersize=12,markerfacecolor='b') #print -dpdf initial_lcls.pdf xplot=convertTempToSkew(Tpseudo - c.Tc,press,skew) thetaEhandle,=plt.plot(xplot,press,'c-', linewidth=2.5) ax.legend([Thandle, TdHandle, bot, top, thetaEhandle], ['Temp (deg C)','Dewpoint (deg C)', 'LCL bot (835 hPa)','LCL top (768 hPa)','$\\theta_e$']) plt.title('convectively unstable sounding: base at 900 hPa')
def convecSkew(figNum): """ Skew-T diagram for the level of free convection. Take any integer, creates figure(figNum), and plots a skewT logp thermodiagram. """ fig = plt.figure(figNum) fig.clf() ax1 = fig.add_subplot(111) 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: # 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) tempLevs = ax1.contour(xplot, yplot, temp, tempLabels, \ colors="k") # Customize the plot ax1.set_yscale("log") locs = np.array(range(100, 1100, 100)) labels = locs ax1.set_yticks(locs) ax1.set_yticklabels(labels) # Conventionally labels semilog graph. ax1.set_ybound((200, 1000)) plt.setp(ax1.get_xticklabels(), weight="bold") plt.setp(ax1.get_yticklabels(), weight="bold") ax1.yaxis.grid(True) thetaLabels = range(200, 390, 10) thetaLevs = ax1.contour(xplot, yplot, theTheta, thetaLabels, \ colors="b") wsLabels = [0.1, 0.25, 0.5, 1, 2, 3] + range(4, 20, 2) + [20, 24, 28] wsLevs = ax1.contour(xplot, yplot, (ws * 1.e3), wsLabels, \ colors="g") thetaeLabels = np.arange(250, 410, 10) thetaeLevs = ax1.contour(xplot, yplot, theThetae, thetaeLabels, \ colors="r") # Transform the temperature,dewpoint from data coords to # plotting coords. ax1.set_title("skew T - lnp chart") ax1.set_ylabel("pressure (hPa)") ax1.set_xlabel("temperature (deg C)") # # Crop image to a more usable size # TempTickLabels = range(-15, 40, 5) TempTickCoords = TempTickLabels skewTickCoords = convertTempToSkew(TempTickCoords, 1.e3, skew) ax1.set_xticks(skewTickCoords) ax1.set_xticklabels(TempTickLabels) skewLimits = convertTempToSkew([-15, 35], 1.e3, skew) ax1.axis([skewLimits[0], skewLimits[1], 300, 1.e3]) # # Create line labels # fntsz = 9 # Handle for fontsize of the line label. ovrlp = True # Handle for inline. Any integer other than 0 # creates a white space around the label. thetaeLevs.clabel(thetaeLabels, inline=ovrlp, fmt="%5d", fontsize=fntsz, use_clabeltext=True) tempLevs.clabel(inline=ovrlp, fmt="%2d", fontsize=fntsz, use_clabeltext=True) thetaLevs.clabel(inline=ovrlp, fmt="%5d", fontsize=fntsz, use_clabeltext=True) wsLevs.clabel(inline=ovrlp, fmt="%2d", fontsize=fntsz, use_clabeltext=True) #print thetaeLabels # # Flip the y axis # ax1.invert_yaxis() ax1.figure.canvas.draw() return skew, ax1
for i in range(0, len(pvec)): Tvec_eq[i], wv[i], wl[i] = tinvert_thetae(thetae_eq, eqwv_bot, pvec[i]) xcoord_eq[i] = convertTempToSkew(Tvec_eq[i] - c.Tc, pvec[i]*0.01, skew) Tvec_sf[i], wv[i], wl[i] = tinvert_thetae(thetae_sf, sfwv_bot, pvec[i]) xcoord_sf[i] = convertTempToSkew(Tvec_sf[i] - c.Tc, pvec[i]*0.01, skew) tempA=Tvec_sf[len(Tvec_sf)-1] pressA=pbot tempB=Tvec_eq[len(Tvec_eq)-1] pressB=pbot tempC=Tvec_eq[0] pressC=ptop tempD=Tvec_sf[0] pressD=ptop; wvD=wsat(tempD,ptop) wvC=wsat(tempC,ptop) hot_adiabat=plt.plot(xcoord_eq,pvec*0.01,'r-',linewidth=3) cold_adiabat=plt.plot(xcoord_sf,pvec*0.01,'b-', linewidth=3) plt.axis([convertTempToSkew(-15.,1000.,skew), convertTempToSkew(35.,1000.,skew), 1020, 350]) xtempA=convertTempToSkew(tempA - c.Tc,pressA*0.01,skew); xtempB=convertTempToSkew(tempB - c.Tc,pressB*0.01,skew); xtempC=convertTempToSkew(tempC - c.Tc,pressC*0.01,skew); xtempD=convertTempToSkew(tempD - c.Tc,pressD*0.01,skew); plt.text(xtempA,pressA*0.01,'A', fontweight='bold',fontsize= 22, color='b'); plt.text(xtempB,pressB*0.01,'B', fontweight='bold',fontsize= 22,color='b');
#equate kinetic and potential energy to get maximum #updraft speed plt.figure(5) maxvel=np.sqrt(2*cumCAPE); plt.plot(maxvel, presslevs[1:]*0.01,'k-'); plt.title('maximum updraft (m/s) vs. pressure (hPa)'); plt.gca().invert_yaxis() plt.show() # # find storm indices # # lifted index thetaeVal=thetaep(dewpoint[0] + c.Tc,temp[0] + c.Tc,press[0]*100.) wT=wsat(dewpoint[0] + c.Tc,press[0]*100.) Tadia_500,wv,wl=tinvert_thetae(thetaeVal,wT,500.e2) Temp_500=interpTenv(500.) + c.Tc lifted_index= Temp_500 - Tadia_500 # total totals = vertical totals plus cross totals Temp_850=interpTenv(850.) + c.Tc dew_850 = interpTdenv(850.) + c.Tc TT_index=Temp_850 + dew_850 - 2*Temp_500 # Sholwater thetaeVal=thetaep(dew_850,Temp_850,850.*100.) wT=wsat(dew_850,850*100.) Tadia_500,wv,wl=tinvert_thetae(thetaeVal,wT,500.e2) sholwater=Temp_500 - Tadia_500 # SWEAT speed_850=interpSpeed(850.) speed_500=interpSpeed(500.)
for i in range(0, len(pvec)): Tvec_eq[i], wv[i], wl[i] = tinvert_thetae(thetae_eq, eqwv_bot, pvec[i]) xcoord_eq[i] = convertTempToSkew(Tvec_eq[i] - c.Tc, pvec[i]*0.01, skew) Tvec_sf[i], wv[i], wl[i] = tinvert_thetae(thetae_sf, sfwv_bot, pvec[i]) xcoord_sf[i] = convertTempToSkew(Tvec_sf[i] - c.Tc, pvec[i]*0.01, skew) tempA = Tvec_sf[len(Tvec_sf)-1] pressA = pbot tempB = Tvec_eq[len(Tvec_eq)-1] pressB = pbot tempC = Tvec_eq[0] pressC = ptop tempD = Tvec_sf[0] pressD = ptop wvD = wsat(tempD, ptop) wvC = wsat(tempC, ptop) hot_adiabat = plt.plot(xcoord_eq,pvec*0.01, "r-", linewidth=3) cold_adiabat = plt.plot(xcoord_sf,pvec*0.01, "b-", linewidth=3) plt.axis([convertTempToSkew(-15.,1000.,skew), convertTempToSkew(35.,1000.,skew), 1020, 350]) # transform along the coordinates xtempA = convertTempToSkew(tempA - c.Tc,pressA*0.01, skew) xtempB = convertTempToSkew(tempB - c.Tc,pressB*0.01, skew) xtempC = convertTempToSkew(tempC - c.Tc,pressC*0.01, skew) xtempD = convertTempToSkew(tempD - c.Tc,pressD*0.01, skew) # plot plt.text(xtempA,pressA*0.01, "A", fontweight="bold", fontsize= 22, color="b")
# during this rise? import site site.addsitedir('C:\Users\Den\mya405\python\\thermlib') from constants import constants as c from new_thermo import wsat, thetaep, tinvert_thetae from findLCL0 import findLCL0 from findTmoist import findTmoist press0=1.e5 Temp0=15 + c.Tc Td0=2 + c.Tc # #step 1: find the lcl # wv0=wsat(Td0,press0) plcl, Tlcl =findLCL0(wv0,press0,Temp0) print 'found Plcl=%8.2f (hPa) and Tlcl=%8.2f (deg C)\n' %(plcl*1.e-2, Tlcl - c.Tc) the_thetae=thetaep(Tlcl,Tlcl,plcl) # step 2 raise air 200 hPa above plcl along pseudo adiabat, # find wsat at that temperature, compare to wv0 to find the amount # of liquid water condensed pnew = plcl - 200.e2 newTemp, newWv, newWl = tinvert_thetae(the_thetae, wv0, pnew) #check: