コード例 #1
0
ファイル: entrain_plume.py プロジェクト: blairvanandel/A405
def calcBuoy(height, thetae0, interpTenv, interpTdEnv, interpPress):
    """function to calculate buoyant acceleration for an ascending saturated parcel
       this version neglects liquid water loading
    
    Parameters
    ----------
    
    height: float
            parcel height (m)
    thetae0: float
            parcel thetae (K)

    interpTenv: func
                interp1d function for environmental temperature T(z) 
    interpTdEnv: func
                interp1d function for environmental dewpoint temperature Td(z)
    interpPress: func
                interp1d function for presusure  p(z)

    Returns
    -------

    buoy: float
          buoyancy (m/s/s)
    """
    #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=find_Tmoist(thetae0,press) #K
    rvcloud=find_rsat(Tcloud,press); #kg/kg
    Tvcloud=Tcloud*(1. + c.eps*rvcloud)
    Tenv=interpTenv(height) + c.Tc
    Tdenv=interpTdEnv(height) + c.Tc
    rvenv=find_rsat(Tdenv,press); #kg/kg
    Tvenv=Tenv*(1. + c.eps*rvenv)
    TvDiff=Tvcloud - Tvenv
    buoy = c.g0*(TvDiff/Tvenv)
    return buoy
コード例 #2
0
ファイル: midterm_2016_sols.py プロジェクト: phaustin/A405
def rv_diff(press,thetae_mix,rT_mix):
    """
      the lcl is is the pressure where rv=rT_mix
      we want a difference that changes sign at cloud base
      so below cloud set rv = rsat(temp,press) and 
      rT_mix - rv will be negative below cloud base and 
      positive above cloud base
    """
    Temp, rv, rl = tinvert_thetae(thetae_mix,rT_mix,press)
    #
    # below cloud rl ~ 0, so switch to rv=rsat
    #
    if rl < 1.e-5:
        rv=find_rsat(Temp,press)
    diff = rT_mix - rv
    return diff
コード例 #3
0
ファイル: entrain_plume.py プロジェクト: blairvanandel/A405
def derivs(t, y, entrain_rate, interpTenv, interpTdEnv, interpPress):
    """Function that computes derivative vector for ode integrator
       see http://clouds.eos.ubc.ca/~phil/courses/atsc405/docs/entrain.pdf for equations

    Parameters
    ----------
    
    t: float
       time (s)
    y: vector
       4-vector containing wvel (m/s), height (m), thetae (K), rT (kg/kg)
    entrain_rate: float
                  1/m dm/dt (s-1)
    interpTenv: func
                interp1d function for environmental temperature T(z) 
    interpTdEnv: func
                interp1d function for environmental dewpoint temperature Td(z)
    interpPress: func
                interp1d function for presusure  p(z)

    Returns
    -------

    yp: vector
       4-vector containing time derivatives of wvel (m/s^2), height (m/s), thetae (K/s), rT (kg/kg/s)
    """
    yp = np.zeros((4,1))
    velocity = y[0]
    height = y[1]
    thetae_cloud = y[2]
    rT_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
    rTenv = find_rsat(Tdenv, press) #kg/kg
    thetaeEnv = find_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 rT_cloud
    yp[3] = entrain_rate*(rTenv - rT_cloud)
    return yp
コード例 #4
0
ファイル: cape.py プロジェクト: phaustin/A405
ax,skew = makeSkewWet(ax,corners=corners,skew=skew)
ax.plot(xcoord_T,sounding['pres'],color='k',label='temp')
ax.plot(xcoord_Td,sounding['pres'],color='g',label='dew')
[line.set(linewidth=3) for line in ax.lines[-2:]]
out=ax.set(title=title)


# In[9]:

from a405thermo.thermlib import find_Tmoist,find_thetaep,find_rsat,find_Tv
#
# find thetae of the surface air
#
sfc_press,sfc_temp,sfc_td =[sounding[key][0] for key in ['pres','temp','dwpt']]
sfc_press,sfc_temp,sfc_td = sfc_press*100.,sfc_temp+c.Tc,sfc_td+c.Tc
sfc_rvap = find_rsat(sfc_temp,sfc_press)
sfc_thetae=find_thetaep(sfc_td,sfc_temp,sfc_press)
press=sounding['pres'].values*100.
#
# find the index for 200 hPa pressure -- searchsorted requires
# the pressure array to be increasing, so flip it for the search,
# then flip the index.  Above 200 hPa thetae goes bananas, so
# so trim so we only have 
#
toplim=len(press) - np.searchsorted(press[::-1],2.e4)
press=press[:toplim]
#
# find temps along that adiabat
#
adia_temps= np.array([find_Tmoist(sfc_thetae,the_press) for the_press in press])
adia_rvaps = find_rsat(adia_temps,press)
コード例 #5
0
ファイル: makeSkewII.py プロジェクト: bjansens/A405
def makeSkewWet(ax, corners=[-30, 25], skew=30):
    """       
      draw a skew-T lnP diagram on an axis

      Parameters
      ----------
      
      ax : matplotlib.axes
           matplotlib figure axis

      corners : [float]
                x axis temperature limits (degC)

      skew : float

             adjustable coefficient to make isotherms slope
             compared to adiabats

      Returns
      -------
      
      ax : matplotlib.axes
           the modified figure axis

      """
    yplot = range(1000, 190, -6)  #
    xcorners = find_corners(corners, skew=skew)
    xplot = list(np.linspace(xcorners[0], xcorners[1], 45))
    pvals = np.size(yplot)
    tvals = np.size(xplot)
    temp = np.zeros([pvals, tvals])
    theTheta = np.zeros_like(temp)
    the_rsat = np.zeros_like(temp)
    theThetae = np.zeros([pvals, tvals])

    # 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 presshPa in yplot:  #loop over pressures
        for skewed in xplot:  #loop over skewed xcoords
            # Note that we don't have to transform the y
            # coordinate, as it is still pressure.
            iInd = yplot.index(presshPa)
            jInd = xplot.index(skewed)
            temp[iInd, jInd] = convertSkewToTemp(skewed, presshPa, skew)
            Tk = c.Tc + temp[iInd, jInd]
            pressPa = presshPa * 100.
            theTheta[iInd, jInd] = find_theta(Tk, pressPa)
            rs = find_rsat(Tk, pressPa)
            the_rsat[iInd, jInd] = rs
            theThetae[iInd, jInd] = find_thetaet(Tk,rs,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, 5)
    ax.contour(xplot, yplot, temp, tempLabels, \
                          colors='k')
    #
    # contour theta
    #
    thetaLabels = list(range(200, 390, 10))
    thetaLevs = ax.contour(xplot, yplot, theTheta, thetaLabels, \
                      colors='b')
    #
    # contour rsat
    #
    rsLabels = [0.1, 0.25, 0.5, 1, 2, 3] + list(range(4, 28, 2)) #+ [26,  28]
    rsLevs = ax.contour(xplot,
                        yplot,
                        the_rsat * 1.e3,
                        levels=rsLabels,
                        colors='g',
                        linewidths=.5)

    thetaeLabels = np.arange(250, 410, 10)
    thetaeLevs = ax.contour(xplot, yplot, theThetae, thetaeLabels, \
                      colors='r')
    #
    # Customize the plot
    #
    ax.set_yscale('log')
    locs = np.array(range(100, 1100, 100))
    labels = locs
    ax.set_yticks(locs)
    ax.set_yticklabels(labels)  # Conventionally labels semilog graph.
    ax.set_ybound((200, 1000))
    plt.setp(ax.get_xticklabels(), weight='bold')
    plt.setp(ax.get_yticklabels(), weight='bold')
    ax.yaxis.grid(True)

    ax.set_title('skew T - lnp chart')
    ax.set_ylabel('pressure (hPa)')
    ax.set_xlabel('temperature (deg C)')

    #
    # Crop image to a more usable size
    #

    TempTickLabels = range(-30, 40, 5)

    TempTickCoords = TempTickLabels
    skewTickCoords = convertTempToSkew(TempTickCoords, 1.e3, skew)
    ax.set_xticks(skewTickCoords)
    ax.set_xticklabels(TempTickLabels)

    skewLimits = convertTempToSkew([-15, 35], 1.e3, skew)

    ax.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.

    #tempLevs.clabel(inline=ovrlp, inline_spacing=0,fmt='%2d', fontsize=fntsz,use_clabeltext=True)
    thetaLevs.clabel(inline=ovrlp,
                     inline_spacing=0,
                     fmt='%3d',
                     fontsize=fntsz,
                     use_clabeltext=True)
    rsLevs.clabel(inline=ovrlp,
                  inline_spacing=0,
                  fmt='%3.2g',
                  fontsize=fntsz,
                  use_clabeltext=True)
    thetaeLevs.clabel(thetaeLabels,
                      inline_spacing=0,
                      inline=ovrlp,
                      fmt='%5g',
                      fontsize=fntsz,
                      use_clabeltext=True)

    ax.invert_yaxis()
    #ax.figure.canvas.draw()
    xcorners = find_corners(corners, skew=skew)
    ax.set(ylim=(1000, 300), xlim=xcorners)
    return ax, skew
コード例 #6
0
ファイル: makeSkewII.py プロジェクト: shepherdmeng/atsc500
def makeSkewWet(ax, corners=[-30, 25], skew=30):
    """       
      draw a skew-T lnP diagram on an axis

      Parameters
      ----------
      
      ax : matplotlib.axes
           matplotlib figure axis

      corners : [float]
                x axis temperature limits (degC)

      skew : float

             adjustable coefficient to make isotherms slope
             compared to adiabats

      Returns
      -------
      
      ax : matplotlib.axes
           the modified figure axis

      """
    yplot = range(1000, 190, -6)  #
    xcorners = find_corners(corners, skew=skew)
    xplot = list(np.linspace(xcorners[0], xcorners[1], 45))
    pvals = np.size(yplot)
    tvals = np.size(xplot)
    temp = np.zeros([pvals, tvals])
    theTheta = np.zeros_like(temp)
    the_rsat = np.zeros_like(temp)
    theThetae = np.zeros([pvals, tvals])

    # 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 presshPa in yplot:  #loop over pressures
        for skewed in xplot:  #loop over skewed xcoords
            # Note that we don't have to transform the y
            # coordinate, as it is still pressure.
            iInd = yplot.index(presshPa)
            jInd = xplot.index(skewed)
            temp[iInd, jInd] = convertSkewToTemp(skewed, presshPa, skew)
            Tk = c.Tc + temp[iInd, jInd]
            pressPa = presshPa * 100.
            theTheta[iInd, jInd] = find_theta(Tk, pressPa)
            rs = find_rsat(Tk, pressPa)
            the_rsat[iInd, jInd] = rs
            theThetae[iInd, jInd] = find_thetaet(Tk, rs, 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)
    ax.contour(xplot, yplot, temp, tempLabels, \
                          colors='k')
    #
    # contour theta
    #
    thetaLabels = list(range(200, 390, 10))
    thetaLevs = ax.contour(xplot, yplot, theTheta, thetaLabels, \
                      colors='b')
    #
    # contour rsat
    #
    rsLabels = [0.1, 0.25, 0.5, 1, 2, 3] + list(range(4, 28, 2))  #+ [26,  28]
    rsLevs = ax.contour(xplot,
                        yplot,
                        the_rsat * 1.e3,
                        levels=rsLabels,
                        colors='g',
                        linewidths=.5)

    thetaeLabels = np.arange(250, 410, 10)
    thetaeLevs = ax.contour(xplot, yplot, theThetae, thetaeLabels, \
                      colors='r')
    #
    # Customize the plot
    #
    ax.set_yscale('log')
    locs = np.array(range(100, 1100, 100))
    labels = locs
    ax.set_yticks(locs)
    ax.set_yticklabels(labels)  # Conventionally labels semilog graph.
    ax.set_ybound((200, 1000))
    plt.setp(ax.get_xticklabels(), weight='bold')
    plt.setp(ax.get_yticklabels(), weight='bold')
    ax.yaxis.grid(True)

    ax.set_title('skew T - lnp chart')
    ax.set_ylabel('pressure (hPa)')
    ax.set_xlabel('temperature (deg C)')

    #
    # Crop image to a more usable size
    #

    TempTickLabels = range(-30, 40, 5)

    TempTickCoords = TempTickLabels
    skewTickCoords = convertTempToSkew(TempTickCoords, 1.e3, skew)
    ax.set_xticks(skewTickCoords)
    ax.set_xticklabels(TempTickLabels)

    skewLimits = convertTempToSkew([-15, 35], 1.e3, skew)

    ax.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.

    #tempLevs.clabel(inline=ovrlp, inline_spacing=0,fmt='%2d', fontsize=fntsz,use_clabeltext=True)
    thetaLevs.clabel(inline=ovrlp,
                     inline_spacing=0,
                     fmt='%3d',
                     fontsize=fntsz,
                     use_clabeltext=True)
    rsLevs.clabel(inline=ovrlp,
                  inline_spacing=0,
                  fmt='%3.2g',
                  fontsize=fntsz,
                  use_clabeltext=True)
    thetaeLevs.clabel(thetaeLabels,
                      inline_spacing=0,
                      inline=ovrlp,
                      fmt='%5g',
                      fontsize=fntsz,
                      use_clabeltext=True)

    ax.invert_yaxis()
    #ax.figure.canvas.draw()
    xcorners = find_corners(corners, skew=skew)
    ax.set(ylim=(1000, 300), xlim=xcorners)
    return ax, skew
コード例 #7
0
ファイル: convec.py プロジェクト: phaustin/A405
  #put on the top and bottom LCLs and the thetae sounding
  Tlcl = np.zeros_like(press)
  pLCL = np.zeros_like(press)
  theTheta = np.zeros_like(press)
  theThetae = np.zeros_like(press)
  Tpseudo = np.zeros_like(press)
  rTotal = np.zeros_like(press)

  #
  # calculate the rTotal,thetae sounding from the original dewpoint and temperture
  #

  numPoints, = press.shape
  for i in range(0, numPoints):
      rTotal[i] = find_rsat(Tdew[i] + c.Tc, press[i] * hPa2pa)
      Tlcl[i], pLCL[i] = find_lcl(Tdew[i] + c.Tc, Temp[i] + c.Tc,
                                  press[i] * hPa2pa)
      theThetae[i] = find_thetaep(Tdew[i] + c.Tc, Temp[i] + c.Tc,
                                  press[i] * hPa2pa)
      #find the temperature along the pseudo adiabat at press[i]
      Tpseudo[i] = find_Tmoist(theThetae[i], press[i] * hPa2pa)


  #
  # given the total water and thetae, calcultate temp,dewpoint for pressure vector press
  #
  Tdew, Temp, Tpseudo = lift_sounding(rTotal,theThetae,press)

  fig, ax = plt.subplots(1, 1, figsize=(10, 10))
  ax, skew = makeSkewWet(ax,corners=[5,25])
コード例 #8
0
ファイル: entrain_plume.py プロジェクト: blairvanandel/A405
def integ_entrain(df_sounding,entrain_rate):
    """integrate an ascending parcel given a constant entrainment rate
       this version hardwired to start parcel at 800 hPa with cloud base
       values of environment at 900 hPa

    Parameters
    ----------

    df_sounding: pandas dataframe 
               : cloumns are temperature, dewpoint, height, press

    entrain_rate: float
                  1/m dm/dt (s-1)

    Returns
    -------

    df_out: dataframe
          dataframe containing wvel (m/s) ,cloud_height (m) , thetae (K), rT (kg/kg) for assending parcel

   interpPress: func
              interp1d function for presusure  p(z) (used for plotting)
    """
    press = df_sounding['pres'].values
    height = df_sounding['hght'].values
    temp = df_sounding['temp'].values
    dewpoint = df_sounding['dwpt'].values
    envHeight= nudge(height)

    interpTenv = interp1d(envHeight,temp)
    interpTdEnv = interp1d(envHeight,dewpoint)
    interpPress = interp1d(envHeight,press)
    #
    # call this cloudbase
    #
    p900_level = len(press) - np.searchsorted(press[::-1],900.)
    thetaeVal=find_thetaep(dewpoint[p900_level] + c.Tc,temp[p900_level] + c.Tc,press[p900_level]*100.)
    rTcloud = find_rsat(dewpoint[p900_level] + c.Tc, press[p900_level]*100.)
    #
    # start parcel here
    #
    p800_level = len(press) - np.searchsorted(press[::-1],800.)
    height_800=height[p800_level]
    winit = 0.5 #initial velocity (m/s)
    yinit = [winit, height_800, thetaeVal, rTcloud]  
    tinit = 0  #seconds
    tfin = 2500  #seconds
    dt = 10   #seconds

    #want to integrate derivs using dopr15 runge kutta described at
    # http://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.ode.html
    #
    r = ode(derivs).set_integrator('dopri5')
    r.set_f_params(entrain_rate, interpTenv, interpTdEnv, interpPress)
    r.set_initial_value(yinit, tinit)
    
    #the while loop below  integrates every dt seconds
    #we stop tracking the parcel when the time runs out, or if the parcel stops moving/is desecnding
    #
    var_out = []
    time_out =[]
    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 = integral of derivs(t) and r.t = time 
        #where derivs is a vector with the variables to be integrated
        #
        # move ahead by dt
        #
        r.integrate(r.t+dt)
        #
        # stop if there is negative vertical velocity
        #
        if r.y[0] <= 0:
            break
        #
        #save values for dataframe
        #
        var_out.append(r.y)
        time_out.append(r.t)
    #
    # convert the output into a datafram
    #
    colnames=['wvel','cloud_height','thetae_cloud','rT_cloud']
    df_out=pd.DataFrame.from_records(var_out,columns=colnames)
    df_out['time'] = time_out
    return df_out,interpPress
コード例 #9
0
ファイル: trop_engine.py プロジェクト: phaustin/A405
ax.plot(trop_adiabat,pressrange,'r-',lw=10)
B_press=400.e2  #Pa
temp,rv,rl = tinvert_thetae(thetae_trop,A_tup.rt,B_press)
rl = 0.2*rl  #rain out 80% of liquid
B_dict = dict(zip(fields,('B',temp,rv,rl,B_press)))
ax.text(trop_adiabat[-1],B_press*pa2hPa,'B',fontsize=30)
B_tup = calc_enthalpy(B_dict)
print(format_tup(B_tup))


# In[202]:

top_temp,top_rv,top_rl = tinvert_thetae(A_thetae,B_tup.rt,B_tup.press)
C_temp = top_temp - 20.
C_rt = B_tup.rt  #conserve total water from B to C
C_rv = find_rsat(C_temp,B_tup.press) 
C_rl = C_rt - C_rv  #cool and condense more liquid with constant rt

C_dict = dict(zip(fields,('C',C_temp,C_rv,C_rl,B_tup.press)))
C_tup = calc_enthalpy(C_dict)
C_thetae = find_thetaet(C_tup.temp,C_tup.rt,C_tup.temp,B_tup.press)
xplot=convertTempToSkew(C_tup.temp - c.Tc,C_tup.press*pa2hPa,skew)
top=ax.plot(xplot, C_tup.press*pa2hPa, 'ko', markersize=14, markerfacecolor='g')
ax.text(xplot*0.99, C_tup.press*pa2hPa,'C',fontsize=30)
print(format_tup(C_tup))
display(fig)


# ### D. descend adiabatically to surface

# In[203]:
コード例 #10
0
ファイル: midterm_2016_sols.py プロジェクト: phaustin/A405
from importlib import reload
import a405skewT.makeSkewII
reload(a405skewT.makeSkewII)
from a405skewT.makeSkewII import makeSkewWet
fig, ax = plt.subplots(1, 1, figsize=(12, 8))
ax, skew = makeSkewWet(ax,corners=[10,30])
ax.set(ylim=[1000,700])
from a405thermo.thermlib import find_Tmoist,find_rsat,find_Td,tinvert_thetae,convertTempToSkew,              find_lcl
import a405thermo.thermlib as tl
#
# set the lcl for 900 hPa to 860 hPa and thetae to 338 K
#
press=860.e2
thetae_900=338.  #K
Temp_860=find_Tmoist(thetae_900,press)
rv_860=find_rsat(Temp_860,press)
rv_900 = rv_860  #vapor is conserved
Tdew_860=Temp_860
print("temp,Tdew,rv at LCL press:  {} hPa {} C {} C {} kg/kg"      .format(n(press*1.e-2),e(k2c(Temp_860)),e(k2c(Tdew_860)),e(rv_900)))
#
# now descend adiabatically to 900 hPa
#
press=900.e2
Temp_900,rv_900,rl_900=tinvert_thetae(thetae_900,rv_900,press)
Tdew_900=find_Td(rv_900,press)
print("temperature and dewpoint at {} hPa hPa = {} C {} C".format(n(press*1.e-2),e(k2c(Temp_900)), e(k2c(Tdew_900))))
#
#  draw these on the sounding at 900 hPa as a red circle and blue diamond
#
xplot=convertTempToSkew(Temp_900 - c.Tc,press*pa2hPa,skew)
bot=ax.plot(xplot, press*pa2hPa, 'ro', markersize=14, markerfacecolor='r')