Пример #1
0
def find_Tmoist(thetaE0, press):
    """
    Calculates the temperatures along a moist adiabat.
    
    Parameters
    ----------

    thetaE0 : float
        Initial equivalent potential temperature (K).
    press : float or array_like
        Pressure (Pa).

    Returns
    -------
    Temp : float or array_like
        Temperature (K) of thetaE0 adiabat at 'press'.

    Examples
    --------
    >>> np.array([find_Tmoist(300., 8.e4)])
    array([ 271.0638])
    >>> find_Tmoist(330., 8.e4)
    283.7226584032411
    """
    Tstart = c.Tc
    try:
        brackets = rf.find_interval(thetaes_diff, Tstart, thetaE0, press)
        Temp = rf.fzero(thetaes_diff, brackets, thetaE0, press)
    except BracketError as e:
        print("couldn't find bracket: debug info: ",e.extra_info)
        Temp = np.nan
    return Temp
Пример #2
0
def find_Tmoist(thetaE0, press):
    """
    Calculates the temperatures along a moist adiabat.
    
    Parameters
    ----------

    thetaE0 : float
        Initial equivalent potential temperature (K).
    press : float or array_like
        Pressure (Pa).

    Returns
    -------
    Temp : float or array_like
        Temperature (K) of thetaE0 adiabat at 'press'.

    Examples
    --------
    >>> find_Tmoist(300., 8.e4)
    270.59590841970277
    
    >>> find_Tmoist(330., 800)
    290.98965468303

    """
    Tstart=c.Tc
    brackets=rf.find_interval(thetaes_diff,Tstart,thetaE0,press)
    Temp = rf.fzero(thetaes_diff,brackets,thetaE0,press)
    return Temp
Пример #3
0
def temp_from_theta(theta,press):
    """
       input: theta (K), press (Pa)
       output: temp (K) found by rootfinder
    """     
    #
    #  use theta as guess for bracket and pass theta,press to theta_zero
    #
    brackets=rf.find_interval(theta_zero,theta,theta,press)
    the_temp = rf.fzero(theta_zero,brackets,theta,press)
    return the_temp
Пример #4
0
def tinvert_thetae(thetaeVal, rT, press):
    """
    temp,rv,rl=tinvert_thetae(thetaeVal, rT, press)

    Uses a rootfinder to determine the temperature for which the
    pseudo equivilant potential temperature (thetaepress) is equal to the
    equivilant potential temperature (thetae) of the parcel.

    Parameters
    ----------
    thetaeVal : float
        Thetae of parcel (K).
    rT : float
        Total water mixing ratio (kg/kg).
    press : float
        Pressure of parcel in (Pa).

    Returns
    -------

    theTemp : float
        Temperature for which thetaep equals the parcel thetae (K).
    rv : float
        Vapor mixing ratio of the parcel (kg/kg).
    rl : float
        liquid water mixing ratio of the parcel (kg/kg) at 'press'.

    Raises
    ------
    IOError
        If 'press' is larger than 100000 Pa.

    Examples
    --------

    >>> tinvert_thetae(300., 0.001, 8.e4)
    (278.4050485684102, 0.001, 0)
    
    """
    if press > 1.e5:
        raise IOError('expecting pressure level less than 100000 Pa')
    # The temperature has to be somewhere between thetae
    # (T at surface) and -40 deg. C (no ice).
    Tstart = c.Tc
    brackets = rf.find_interval(find_resid_thetae, Tstart, thetaeVal, rT,
                                press)
    theTemp = rf.fzero(find_resid_thetae, brackets, thetaeVal, rT, press)
    rv, rl = find_rvrl(theTemp, rT, press)
    return theTemp, rv, rl
Пример #5
0
def tinvert_rsat(Tstart,rsat,press):
    """
    rootfind the temp that produces rsat at press.

    Parameters
    ----------

    temp : float
           temperature (K)

    rsat : float
           saturation mixing ratio (kg/kg)

    press : float 
            pressure (hPa)

    Returns
    -------

    Tdew : temperature (K) at with air is saaturated
    """
    brackets=rf.find_interval(find_resid_rsat,Tstart,rsat,press)
    temp = rf.fzero(find_resid_rsat,brackets,rsat,press)
    return temp
Пример #6
0
cloud_vars['koehler_fun'] = koehler_fun


# ### find the equilibrium radius for each bin at saturation Sinit

# In[41]:

S_target = parcel.Sinit
logr_start = np.log(0.1e-6)

initial_radius = []
dry_radius = []
for mass in center_mass:
    brackets = np.array(find_interval(find_diff,logr_start,S_target,mass,koehler_fun))
    left_bracket, right_bracket = np.exp(brackets)*1.e6  #get brackets in microns for printing
    equil_rad = np.exp(fzero(find_diff,brackets,S_target,mass,koehler_fun))

    initial_radius.append(equil_rad)
    dry_rad = (mass/(4./3.*np.pi*aero.rhoaero))**(1./3.)
    dry_radius.append(dry_rad)

    print('mass = {mass:6.3g} kg'.format_map(locals()))
    print('equlibrium radius at S={} is {:5.3f} microns\n'.format(S_target,equil_rad*1.e6))


# ### now add the intial conditions to the cloud_vars dictionary and make it a namedtuple
# 
# the vector var_vec holds 30 droplet radii plus three extra variables at the
# end of the vector: the temperature, pressure and height.

# In[42]:
Пример #7
0
matplotlib.style.use('ggplot')
fig,ax = plt.subplots(1,1)
rvals=np.linspace(0.05,0.3,50)*1.e-6
Svals = find_S(rvals)
ax.plot(rvals*1.e6,(Svals -1)*1.e2)
out=ax.set(ylim=[-1,1],xlim = [0.05,0.3],
       ylabel='Supersaturation (e/es - 1) %',xlabel='radius (microns)')


# ### 2.  Find haze particle equilibrium radius at S=0.9

# In[21]:

def find_diff(r,S_target):
    return S_target - find_S(r)

S_target = 0.90
r_start = 0.1e-6
from a405thermo.rootfinder import find_interval, fzero
brackets = np.array(find_interval(find_diff,r_start,S_target))
print('left bracket = {:8.3e} microns, right bracket={:8.3e} microns'.format(*(brackets*1.e6)))

equil_rad = fzero(find_diff,brackets,S_target)
print('equlibrium radius at S={} is {:5.3f} microns'.format(S_target,equil_rad*1.e6))


# In[ ]:



Пример #8
0
print(help(rf.find_interval))


# ### example -- find a bracket for sin(x)=0 near x=12 radians ~ 700 degrees

# In[8]:

brackets=rf.find_interval(np.sin,12)
brackets


# ## now use the fzero wrapper to find the root of sin(x)=0  (720 degrees)

# In[9]:

print(rf.fzero(np.sin,brackets)*180/np.pi)


# ## Redo theta example with find_interval

# In[39]:

import a405thermo.rootfinder as rf
from importlib import reload
reload(rf)

def theta_zero(Tguess,theta,press):
    """Function we want to find the root of
       input: Tguess (K), target theta (K), press (Pa)
       output: difference between guess and target -- should be zero when x is a root
    """
Пример #9
0
def zero_find_es(temp):
    esguess=standard_es(temp)
    brackets=rf.find_interval(zero_es,esguess,temp)
    resid = rf.fzero(zero_es,brackets,temp)
    return resid
Пример #10
0
def find_diff(logr,S_target,m):
    """
    zero function for rootfinder
    """
    r = np.exp(logr)
    return S_target - koehler_fun(r,m)

S_target = parcel.Sinit
logr_start = np.log(0.1e-6)

initial_radius = []
for mass in center_mass:
    brackets = np.array(find_interval(find_diff,logr_start,S_target,mass))
    left_bracket, right_bracket = np.exp(brackets)*1.e6  #get brackets in microns for printing
    equil_rad = np.exp(fzero(find_diff,brackets,S_target,mass))
    
    Scrit=(4.*a**3./(27.*b*mass))**0.5
    
    initial_radius.append(equil_rad)
    print(('mass = {mass:6.3g} kg\n'
           'left bracket = {left_bracket:8.3e} microns\n'
           'right bracket={right_bracket:8.3e} microns\n'
           'critical supersaturation: {Scrit:6.3g}')
           .format_map(locals()))
    print('equlibrium radius at S={} is {:5.3f} microns\n'.format(S_target,equil_rad*1.e6))
   


# In[ ]:
Пример #11
0
# In[4]:

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

from a405thermo.rootfinder import find_interval,fzero
bracket=find_interval(rv_diff,7.e4,thetae_mix,rt_mix)
print('found bracket =',bracket)
lcl_press=fzero(rv_diff,bracket,thetae_mix,rt_mix)
print('the lcl pressure is {} hPa'.format(n(lcl_press*1.e-2)))


# In[ ]: