{ "cells": [ { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# ENV/ATM 415: Climate Laboratory\n", "\n", "[Brian E. J. Rose](http://www.atmos.albany.edu/facstaff/brose/index.html), University at Albany\n", "\n", "# Lecture 2: Global energy balance, equilibrium temperature, and numerical timestepping\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "First, some thoughts on modeling from [xkcd](https://xkcd.com)\n", "\n", "![physicists](https://imgs.xkcd.com/comics/physicists.png)\n", "\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## The observed global energy budget\n", "\n", "Let's look again at the observations:" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "![Observed global energy flows from Trenberth and Fasullo (2012)](http://www.atmos.albany.edu/facstaff/brose/classes/ENV415_Spring2018/images/GlobalEnergyBudget.png)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Recap of our simple greenhouse model\n", "\n", "Last class we introduced a very simple model for the **OLR** or Outgoing Longwave Radiation to space:\n", "\n", "$$ \\text{OLR} = \\tau \\sigma T_s^4 $$\n", "\n", "where $\\tau$ is the **transmissivity** of the atmosphere, a number less than 1 that represents the greenhouse effect of Earth's atmosphere." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "We also tuned this model to the observations by choosing $ \\tau \\approx 0.61$.\n", "\n", "More precisely:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "OLRobserved = 238.5 # in W/m2\n", "sigma = 5.67E-8 # S-B constant\n", "Tsobserved = 288. # global average surface temperature\n", "tau = OLRobserved / sigma / Tsobserved**4 # solve for tuned value of transmissivity\n", "print(tau)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "Let's now deal with the shortwave (solar) side of the energy budget." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Absorbed Shortwave Radiation (ASR) and Planetary Albedo\n", "\n", "Let's define a few terms." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "#### Global mean insolation\n", "\n", "From the observations, the area-averaged incoming solar radiation or **insolation** is 341.3 W m$^{-2}$.\n", "\n", "Let's denote this quantity by $Q$." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "Q = 341.3 # the insolation" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "#### Planetary albedo\n", "\n", "Some of the incoming radiation is not absorbed at all but simply reflected back to space. Let's call this quantity $F_{reflected}$\n", "\n", "From observations we have:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "Freflected = 101.9 # reflected shortwave flux in W/m2" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "\n", "The **planetary albedo** is the fraction of $Q$ that is reflected.\n", "\n", "We will denote the planetary albedo by $\\alpha$.\n", "\n", "From the observations:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "alpha = Freflected / Q\n", "print(alpha)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "That is, about 30% of the incoming radiation is reflected back to space." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "#### Absorbed Shortwave Radiation\n", "\n", "The **Absorbed Shortwave Radiation** or ASR is the part of the incoming sunlight that is *not* reflected back to space, i.e. that part that is absorbed somewhere within the Earth system.\n", "\n", "Mathematically we write\n", "\n", "$$ \\text{ASR} = Q - F_{reflected} = (1-\\alpha) Q $$" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "From the observations:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ASRobserved = Q - Freflected\n", "print(ASRobserved)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "As we noted last time, this number is *just slightly greater* than the observed OLR of 238.5 W m$^{-2}$." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Equilibrium temperature" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "*This is one of the central concepts in climate modeling.*\n", "\n", "The Earth system is in **energy balance** when energy in = energy out, i.e. when\n", "\n", "$$ \\text{ASR} = \\text{OLR} $$" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "We want to know:\n", "\n", "- What surface temperature do we need to have this balance?\n", "- By how much would the temperature change in response to other changes in Earth system?\n", " - Changes in greenhouse gases\n", " - Changes in cloudiness\n", " - etc.\n", "\n", "\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "With our simple greenhouse model, we can get an **exact solution** for the equilibrium temperature.\n", "\n", "First, write down our statement of energy balance:\n", "\n", "$$ (1-\\alpha) Q = \\tau \\sigma T_s^4 $$" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "Rearrange to solve for $T_s$:\n", "\n", "$$ T_s^4 = \\frac{(1-\\alpha) Q}{\\tau \\sigma} $$\n", "\n", "and take the fourth root, denoting our **equilibrium temperature** as $T_{eq}$:\n", "\n", "$$ T_{eq} = \\left( \\frac{(1-\\alpha) Q}{\\tau \\sigma} \\right)^\\frac{1}{4} $$" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "Plugging the observed values back in, we compute:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# define a reusable function!\n", "def equilibrium_temperature(alpha,Q,tau):\n", " return ((1-alpha)*Q/(tau*sigma))**(1/4)\n", "\n", "Teq_observed = equilibrium_temperature(alpha,Q,tau)\n", "print(Teq_observed)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "And this equilibrium temperature is *just slightly warmer* than 288 K. Why?" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### A climate change scenario\n", "\n", "Suppose that, due to global warming (changes in atmospheric composition and subsequent changes in cloudiness):\n", "\n", "- The longwave transmissitivity decreases to $\\tau = 0.57$ \n", "- The planetary albedo increases to $\\alpha = 0.32$\n", "\n", "What is the new equilibrium temperature?" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "For this very simple model, we can work out the answer exactly:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "Teq_new = equilibrium_temperature(0.32,Q,0.57)\n", "# an example of formatted print output, limiting to two or one decimal places\n", "print('The new equilibrium temperature is {:.2f} K.'.format(Teq_new))\n", "print('The equilibrium temperature increased by about {:.1f} K.'.format(Teq_new-Teq_observed))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "Most climate models are more complicated mathematically, and solving directly for the equilibrium temperature will not be possible! \n", "\n", "Instead, we will be able to use the model to calculate the terms in the energy budget (ASR and OLR)." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Python exercise\n", "\n", "- Write Python functions to calculate ASR and OLR for *arbitrary parameter values*.\n", "- Verify the following:\n", " - With the new parameter values but the old temperature T = 288 K, is ASR greater or lesser than OLR? \n", " - Is the Earth gaining or losing energy?\n", " - How does your answer change if T = 295 K (or any other temperature greater than 291 K)?" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## A time-dependent Energy Balance Model" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The above exercise shows us that if some properties of the climate system change in such a way that the **equilibrium temperature goes up**, then the Earth system *receives more energy from the sun than it is losing to space*. The system is **no longer in energy balance**.\n", "\n", "The temperature must then increase to get back into balance. The increase will not happen all at once! It will take time for energy to accumulate in the climate system. We want to model this **time-dependent adjustment** of the system.\n", "\n", "In fact almost all climate models are **time-dependent**, meaning the model calculates **time derivatives** (rates of change) of climate variables." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### An energy balance equation\n", "\n", "We will write the **total energy budget** of the Earth system as\n", "\n", "$$ C \\frac{dT_s}{dt} = \\text{ASR} - \\text{OLR} $$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "where\n", "\n", "- $C$ is the **heat capacity** of Earth system, in units of J m$^{-2}$ K$^{-1}$.\n", "- $\\frac{dT}{dt}$ is the rate of change of global average surface temperature." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "By adopting this equation, we are assuming that the energy content of the Earth system (atmosphere, ocean, ice, etc.) is *proportional to surface temperature*.\n", "\n", "Important things to think about:\n", "\n", "- Why is this a sensible assumption?\n", "- What determines the heat capacity $C$?\n", "- What are some limitations of this assumption?\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "For our purposes here we are going to use a value of C equivalent to heating 100 meters of water:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "c_w = 4E3 # Specific heat of water in J/kg/K\n", "rho_w = 1E3 # Density of water in kg/m3\n", "H = 100. # Depth of water in m\n", "C = c_w * rho_w * H # Heat capacity of the model \n", "print('The effective heat capacity is {:.1e} J/m2/K'.format(C))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Representing time derivatives on a computer" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Recall that the derivative is the **instantaneous rate of change**. It is defined as \n", "\n", "$$ \\frac{dT}{dt} = \\lim_{\\Delta t\\rightarrow 0}⁡ \\frac{\\Delta T}{\\Delta t}$$\n", "\n", "- **On the computer there is no such thing as an instantaneous change.** \n", "- We are always dealing with *discrete quantities*.\n", "- So we approximate the derivative with $\\Delta T/ \\Delta t$. \n", "- So long as we take the time interval $\\Delta t$ \"small enough\", the approximation is valid and useful.\n", "- (The meaning of \"small enough\" varies widely in practice. Let's not talk about it now)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "So we write our model as\n", "\n", "$$ C \\frac{\\Delta T}{\\Delta t} \\approx \\text{ASR} - \\text{OLR}$$\n", "\n", "where $\\Delta T$ is the **change in temperature predicted by our model** over a short time interval $\\Delta t$." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can now use this to **make a prediction**: \n", "\n", "Given a current temperature $T_1$ at time $t_1$, what is the temperature $T_2$ at a future time $t_2$?" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "We can write\n", "\n", "$$ \\Delta T = T_2-T_1 $$\n", "$$ \\Delta t = t_2-t_1 $$\n", "\n", "and so our model says\n", "\n", "$$ C \\frac{T_2-T_1}{\\Delta t} = \\text{ASR} - \\text{OLR} $$\n", "\n", "Which we can rearrange to **solve for the future temperature**:\n", "\n", "$$ T_2 = T_1 + \\frac{\\Delta t}{C} \\left( \\text{ASR} - \\text{OLR}(T_1) \\right) $$\n", "\n", "We now have a formula with which to make our prediction!\n", "\n", "Notice that we have written the OLR as a *function of temperature*. We will use the current temperature $T_1$ to compute the OLR, and use that OLR to determine the future temperature." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Numerical solution of the Energy Balance Model" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The quantity $\\Delta t$ is called a **timestep**. It is the smallest time interval represented in our model.\n", "\n", "Here we're going to use a timestep of 1 year:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "dt = 60. * 60. * 24. * 365. # one year expressed in seconds" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "slide" } }, "outputs": [], "source": [ "# Try a single timestep, assuming we have working functions for ASR and OLR\n", "T1 = 288.\n", "T2 = T1 + dt / C * ( ASR(alpha) - OLR(T1, tau=0.57) )\n", "print(T2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "What happened? Why?" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "Try another timestep" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "T1 = T2\n", "T2 = T1 + dt / C * ( ASR(alpha) - OLR(T1, tau=0.57) )\n", "print(T2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Warmed up again, but by a smaller amount." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "But this is tedious typing. Time to **define a function** to make things easier and more reliable:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def step_forward(T):\n", " return T + dt / C * ( ASR(alpha) - OLR(T, tau=0.57) )" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "Try it out with an arbitrary temperature:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "step_forward(300.)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Notice that our function calls other functions and variables we have already defined." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "#### Python fact 10: Functions can access variables and other functions defined outside of the function. \n", "\n", "This is both very useful and occasionally confusing." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "Now let's really harness the power of the computer by **making a loop** (and storing values in arrays):" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "\n", "numsteps = 20\n", "Tsteps = np.zeros(numsteps+1)\n", "Years = np.zeros(numsteps+1)\n", "Tsteps[0] = 288. \n", "for n in range(numsteps):\n", " Years[n+1] = n+1\n", " Tsteps[n+1] = step_forward( Tsteps[n] )\n", "print(Tsteps)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "What did we just do?\n", "\n", "- Created an array of zeros\n", "- set the initial temperature to 288 K\n", "- repeated our time step 20 times. \n", "- Stored the results of each time step into the array." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "#### Python fact 11: the `for` statement executes a statement (or series of statements) a specified number of times (a loop!)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "#### Python fact 12: Use square bracket [ ] to refer to elements of an array or list. Use round parentheses ( ) for function arguments. " ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Plotting the result\n", "\n", "Now let's draw a picture of our result!" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# a special instruction for the Jupyter notebook\n", "# Display all plots inline in the notebook\n", "%matplotlib inline \n", "# import the plotting package\n", "import matplotlib.pyplot as plt" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "plt.plot( Years, Tsteps )\n", "plt.xlabel('Years')\n", "plt.ylabel('Global mean temperature (K)');" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "Note how the temperature *adjusts smoothly toward the equilibrium temperature*, that is, the temperature at which\n", "ASR = OLR.\n", "\n", "**If the planetary energy budget is out of balance, the temperature must change so that the OLR gets closer to the ASR!**\n", "\n", "The adjustment is actually an *exponential decay* process: The rate of adjustment slows as the temperature approaches equilibrium. \n", "\n", "The temperature gets very very close to equilibrium but never reaches it exactly." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "#### Python fact 13: We can easily make simple graphs with the function plot(x,y), where x and y are arrays of the same size. But we must import it first. \n", "\n", "This is actually not native Python, but uses a special graphics library called `matplotlib`. \n", "\n", "Just about all of our notebooks will start with this:\n", "```\n", "%matplotlib inline\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "```" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Summary\n", "\n", "- We looked at the flows of energy in and out of the Earth system. \n", "- These are determined by radiation at the top of the Earth's atmosphere.\n", "- Any imbalance between shortwave absorption (ASR) and longwave emission (OLR) drives a change in temperature\n", "- We built a climate model!\n", "- This **Zero-Dimensional Energy Balance Model** solves for the global, annual mean surface temperature $T_s$\n", "- Two key assumptions:\n", " - Energy content of the Earth system varies proportionally to $T_s$\n", " - The OLR increases as $\\tau \\sigma T_s^4$ (our simple greenhouse model)\n", "- The model has an **equilibrium temperature** $T_{eq}$ at which ASR = OLR\n", "- If $T_s < T_{eq}$, the model will warm up.\n", "- We can represent the **continous warming process** on the computer using **discrete timesteps**.\n", "- We can plot the result." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "skip" } }, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.2" } }, "nbformat": 4, "nbformat_minor": 2 }