'''
This script computes the moist adiabat for an atmosphere
which is a mixture of a noncondensing and a condensing
component. It also computes the vertical profile of
the mass specific concentration of the condensible
component, and does plots
When doing plots using the plot(...) function
implemented with Ngl, the exponents on the axes are sometimes
hard to read; in particular, the powers of 10 on the concentration
axis are negative, though you need good eyes to see it.
Note that a version of the MoistAdiabat function, analogous
to the satvps_function used for saturation vapor pressures,
is located in the phys module. Type help(phys.MoistAdiabat)
for more information.
'''
#Data on section of text which this script is associated with
Chapter = '2.**'
Figure = '**'
import phys
from ClimateUtilities import *
from math import *
#Choose your mix of gases here
condensible = phys.H2O
noncon = phys.air
#Thermodynamic constants (needed for dry adiabat
#and one-component saturated adiabat computations)
L = condensible.L_vaporization
Ra = noncon.R
Rc = condensible.R
cpa = noncon.cp
Tr = condensible.TriplePointT
psat_ref = condensible.TriplePointP
#Dry and one-component adiabat functions, for comparison
#Note that the use of Numeric.log lets this take
#an array as an argument for p. The rest of the arithmetic,
#including the exponentiation in the dry adiabat, works
#equally well for a Numeric array as for a regular number
#
#**ToDo: Note that the formula for Tdry uses R/cp for dry air for
#comparison. This is what was used in the first edition
#of the Principles of Planetary Climate. However for high
#temperatures, the condensible concentration alters the
#value of R/cp, so it would be more appropriate to use the value
#of R/cp based on the actual mix of condensible and noncondensible.
#This may not matter much, though, since the main point of the comparison
#is to show the convergence to the dry adiabat at low temperatures.
def Tsat(p):
return(1./(1./Tr - (Rc/L)*Numeric.log(p/psat_ref)))
def Tdry(Ts,p):
return Ts*(p/p[0])**(Ra/cpa)
#**ToDo: Add controls on resolution, top of atmosphere, etc.
def MoistAdiabat(ps,Ts,condensible=phys.H2O,noncondensible = phys.air):
#Set up saturation vapor pressure function
satvp = phys.satvps_function(condensible)
#Set up thermodynamic constants
eps = condensible.MolecularWeight/noncon.MolecularWeight
L = condensible.L_vaporization
Ra = noncon.R
Rc = condensible.R
cpa = noncon.cp
cpc = condensible.cp
#
#Set up derivative function for integrator
def slope(logpa,logT):
pa = exp(logpa)
T = exp(logT)
qsat = eps*(satvp(T)/pa)
num = (1. + (L/(Ra*T))*qsat)*Ra
den = cpa + (cpc + (L/(Rc*T) - 1.)*(L/T))*qsat
return num/den
#Initial conditions
step = -.05 #Step size for integration
ptop = 1000. #Where to stop integratoin
#
#
logpa = log(ps)
logT = log(Ts)
ad = integrator(slope,logpa,logT,step )
#Initialize lists to save results
pL = [exp(logpa) + satvp(exp(logT))]
molarConL = [satvp(exp(logT))/pL[0]]
TL = [exp(logT)]
#Integration loop
p = 1.e30 #Dummy initial value, to get started
while p > ptop:
ans = ad.next()
pa = exp(ans[0])
T = exp(ans[1])
p = pa+satvp(T)
pL.append(p)
molarConL.append(satvp(T)/p)
TL.append(T)
pL = Numeric.array(pL)
TL = Numeric.array(TL)
molarConL = Numeric.array(molarConL)
#Compute the mass specific concentration
Mc = condensible.MolecularWeight
Mnc = noncon.MolecularWeight
Mbar = molarConL*Mc +(1.-molarConL)*Mnc
qL = (Mc/Mbar)*molarConL
return pL,TL,molarConL,qL
ps = 1.e5
Ts = 325.
p,T,molarCon,q = MoistAdiabat(ps,Ts,condensible,noncon)
#Plot temperature
c = Curve()
c.addCurve(p,'p','Pressure (Pa)')
c.addCurve(T,'T','Temperature (K)')
c.addCurve(Tdry(Ts,p),'Tdry','Dry adiabat')
c.addCurve(Tsat(p),'Tad1','One component adiabat')
c.switchXY = c.reverseY = c.YlogAxis = True
c.PlotTitle = "Temperature Profile"
c.Ylabel = "Temperature (K)"
c.Xlabel = "Pressure (Pa)"
plot(c)
#Plot Molar Concentration
c1 = Curve()
c1.switchXY = c1.reverseY = c1.YlogAxis = c1.XlogAxis = True
c1.addCurve(p,'p','Pressure (Pa)')
c1.addCurve(molarCon+1.e-30,'molarCon','Molar concentration of condensible')
c1.PlotTitle = "Molar Concentration Profile"
c1.Ylabel = "Concentration (fraction)"
c1.Xlabel = "Pressure (Pa)"
plot(c1)
#Plot Mass Concentration
c2 = Curve()
c2.switchXY = c2.reverseY = c2.YlogAxis = c2.XlogAxis = True
c2.addCurve(p,'p','Pressure (Pa)')
c2.addCurve(q+1.e-30,'q','Mass specific concentration of condensible')
c2.PlotTitle = "Mass Concentration Profile"
c2.Ylabel = "Concentration (fraction)"
c2.Xlabel = "Pressure (Pa)"
plot(c2)