#Script for illustrating simple models of
#ice-albedo feedback
#
#
#Data on section of text which this script is associated with
Chapter = '3.**'
Figure = '**'
#
from ClimateUtilities import *
import phys
#Define albedo and OLR functions here
#Radiating pressure pRad, in mb, is passed as the
#optional second parameter. It can be used to
#pass parameters of other OLR expressions, e.g.
#CO2 concentrations
def OLR(T,param=None):
pRad = param
return phys.sigma * (T**4.)*(pRad/1000.)**(4.*2./7.)
#Comment out the preceding line and replace with the
#following one, to use a linear OLR fit
#return 113. + 2.177*(T-220.)
#Parameters of albedo function are globals
def albedo(T):
if T < T1:
return alpha_ice
elif (T >= T1)&(T<=T2):
r = (T-T2)**2/(T2-T1)**2
return alpha_0 + (alpha_ice - alpha_0)*r
else:
return alpha_0
#Main body of script starts here
L = 1.*1370. #1.2 times modern give marginal case w/o greenhouse
alpha_ice = .6
alpha_0 = .2
T1 = 260.
T2 = 290.
pRad = 1000.
Tlist = [200.+ 2.*i for i in range(70)]
SabsList = []
OLRlist = []
NetFluxlist = []
Glist = []
for T in Tlist:
SabsList.append((L/4.)*(1.-albedo(T)))
OLRlist.append(OLR(T,pRad))
NetFluxlist.append((L/4.)*(1.-albedo(T)) - OLR(T,pRad))
Glist.append(4.*OLR(T,pRad)/(1.-albedo(T)))
#Plot the results
c1 = Curve()
c1.addCurve(Tlist)
c1.addCurve(SabsList,'Sabs','Absorbed Solar')
c1.addCurve(OLRlist,'OLR','Outgoing Longwave')
c1.Xlabel = 'Temperature (K)'
c1.Ylabel = 'Flux (W/m**2)'
c1.PlotTitle = 'Energy Balance Diagram'
w1 = plot(c1)
c2 = Curve()
c2.addCurve(Tlist)
c2.addCurve(NetFluxlist,'Net','Net Flux')
c2.addCurve([0. for i in range(len(Glist))],'Zero','Equilibrium')
c2.Xlabel = 'Temperature (K)'
c2.Ylabel = 'Net Flux (W/m**2)'
c2.PlotTitle = 'Stability diagram'
w2 = plot(c2)
c3 = Curve()
c3.addCurve(Tlist)
c3.addCurve(Glist,'G','Balance Function')
c3.addCurve([L for i in range(len(Glist))],'S','Incident Solar')
c3.switchXY = True #Switches axis so it looks like a hysteresis plot
c3.PlotTitle = 'Bifurcation diagram, pRad = %f mb'%pRad
c3.Xlabel = 'Surface Temperature (K)'
c3.Ylabel = 'Solar Constant (W/m**2)'
w3 = plot(c3)
#Make a plot of the energy balance diagram with multiple
#different solar constants
Llist = [.9*L,L,1.1*L,1.7*L]
c4 = Curve()
c4.addCurve(Tlist,'T','Surface Temperature')
for L1 in Llist:
Solar = [(L1/4.)*(1.-albedo(T)) for T in Tlist]
c4.addCurve(Solar,'%f'%(L1),'L = %f'%(L1))
c4.Xlabel = 'Temperature (K)'
c4.Ylabel = 'Flux (W/m**2)'
c4.PlotTitle = 'Energy Balance Diagram'
c4.addCurve(OLRlist,'OLR','Outgoing Longwave')
w4 = plot(c4)
#Now make a bifurcation diagram with pRad as the control variable
#Note that if you have changed the OLR function in such a way that
#it is independent of its parameter, this calculation will fail,
#so you should comment it out. The technique will work, though,
#for pretty much any parameter characterizing the greenhouse
#effect, e.g. CO2 concentration.
#Note that since the control parameter is a single-valued function
#of the temperature T, we can actually make the graph much more
#swiftly by solving for, say, L in terms of T analytically, and
#then plotting L(T) instead of T(L). Since L(T) = OLR(T)/(1-albedo(T)),
#this curve can always be generated from arbitrary OLR and
#albedo functions. (it's the same curve as in the equilibrium
#ice-albedo script, and indeed perhaps part of the hysteresis stuff
#should be moved to that script).
#
#For hysteresis curves over a greenhouse parameter, one can
#proceed similarly. For the simple OLR above, one can solve
#for pRad analytically, but in the general case one
#first computes, for a specified T, F = (1. - albedo(T))*L/4
#then solves OLR(T,GreenhouseParam) = F, to find GreenhouseParam.
#Since OLR is generally monotonically decreasing in GreenhouseParam,
#this procedure essentially always yields a single-valued function.
def radPress(flux,T):
def g(p,const):
return OLR(const.T,p) - const.flux
root = newtSolve(g)
const= Dummy()
const.T = T
const.flux = flux
root.setParams(const)
return root(500.)
L = 1370.
TList = [220.+i for i in range(131)]
gList = [radPress((1.-albedo(T))*L/4.,T) for T in TList]
cG = Curve()
cG.addCurve(gList,'pRad')
cG.addCurve(TList,'T')
#Just for variety, here I've shown that instead of
# switching axes, you can just put the data into
# the Curve in a different order
cG.PlotTitle = 'Bifurcation diagram, L = %f W/m**2'%L
cG.Ylabel = 'Surface Temperature (K)'
cG.Xlabel = 'Radiating pressure (mb)'
cG.reverseX = True #Reverse pressure axis so warmer is to the right
plot(cG)