Simulated using reconstructed forcing by Crowley et al (2000)
Resconstructed temperatures from multiple proxy records by Mann et al (2008)
Causes of Climate Change Over the Past 1000 Years, Thomas J. Crowley, Science 289, 270 (2000);DOI: 10.1126/science.289.5477.270
This is a very simple model of climate response to forcing during the period 1000-1998. There are three major climate shifts to analyze: the Medieval Warm Period (roughly 1100-1400), the Little Ice Age (1500-1850), and the Modern Warming in the 20th Century.
Both reconstructed forcing and temperatures were provided by the NOAA National Climatic Data Center. Climate forcing due to volcanic eruptions, changes in solar output, greenhouse gases, and tropospheric aerosol were derived by Crowley (2000). Global mean temperatures over this period were reconstructed from multiple proxies as reported by Mann et al (2008).
The model simply adjusts the temperature upward or downward according to the prescribed forcing for each year, with a relaxation time toward an equilibrium temperature according to the user-specified climate sensitivity. Total forcing in each year is the sum of forcing due to volvanic aerosol, solar output, greenhouse gases, and tropospheric aerosol (all in Watts per square meter), derived from the reconstructions of Crowley (2000) and displayed in the “Forcing” tab to the right.
In each year beginning in AD 1000, an equilibrium temperature is computed from the forcing using the climate sensitivity (in degrees per Watt/m2) as:
temp.eq <- total.forcing[i] * sensitivity
Simulated temperature is then adjusted toward the equilibrium temperature according to the user-specified timescale as:
temp[i+1] <- temp[i] + (temp.eq - temp[i]) / timescale
The program that does the calculation is very simple, and the code that controls this website is surprisingly simple too! It is all written in the programming language R. You can read all about it on the “Website Code” tab to the right.
Crowley, T. J., 2000. Causes of Climate Change Over the Past 1000 Years. Science 289, 270. DOI: 10.1126/science.289.5477.270
Mann, M. E., Z. Zhang, M. K. Hughes, R. S. Bradley, S. K. Miller, S. Rutherford, and F. Ni, 2008. Proxy-based reconstructions of hemispheric and global surface temperature variations over the past two millennia. Proceedings of the National Academy of Sciences 105(36), 13252-13257, doi:10.1073/pnas.0805721105
This website is controlled using the R package “shiny.” There are four important components:
Scroll down or click links in the list above to read all about it!
ui.R:
library(shiny)
library(markdown)
# Define UI for slider demo application
shinyUI(pageWithSidebar(
# Application title
headerPanel("Climate Sensitivity: The Last 1000 Years"),
# Sidebar with sliders that adjust climate sensitivity
sidebarPanel(
img(src='198px-The_Skating_Minister.jpg'),
h4('Adjust Climate Properties'),
sliderInput("sensitivity", "Sensitivity (degrees per Watt/m2)",
min = 0.5, max = 1.5, value = 0.8, step=0.01),
sliderInput("timescale", "Climate adjustment time (years)",
min = 10, max = 200, value = 30, step=5)),
# Main panel consists of a tabset displays model output or model description
mainPanel(
tabsetPanel(
tabPanel("Climate Response",
h3("Reconstructed and Simulated Temperature Since the Year 1000"),
h4("Resconstructed from multiple proxy records
by Mann et al (2008)"),
h4("Simulated using reconstructed forcing by
Crowley et al (2000)"),
plotOutput("climate"),
tags$style(type="text/css", ".tab-content { overflow: visible; }")),
tabPanel("Forcing",
h3("Reconstructed Climate Forcing"),
p('Causes of Climate Change Over the Past 1000 Years, Thomas J. Crowley,
Science 289, 270 (2000);DOI: 10.1126/science.289.5477.270'),
plotOutput("forcing"),
tags$style(type="text/css", ".tab-content { overflow: visible; }")),
tabPanel("Description",
includeMarkdown('doc/model.description.md')),
tabPanel("Website Code",
includeMarkdown('doc/website.code.md'))
)
)
))
server.R:
library(shiny)
# Source required R scripts
source('model/climate.R')
source('model/compare.R')
source('model/plot.forcing.R')
source('model/read.forcing.R')
source('model/read.mann2008.R')
shinyServer(function(input, output) {
# Draw an annotated diagram of the model output
output$climate <- renderPlot(
compare(sensitivity=input$sensitivity, timescale=input$timescale), height=600)
# Make a simple line plot of temperature vs height
output$forcing <- renderPlot(plot.forcing(),height=800)
})
compare.R:
compare <- function(sensitivity=0.81, timescale=30) {
# Read climate forcing and reconstructed temperatures from files,
# then simulated temperatures from focring data and compare to
# reconstructed temperatuers in a single graph
# Read Croweley (2000) forcing from a file
forcing <- read.table(skip=52,
file='Data/volcanic.solar.GHG.tropAer.Crowley2000.txt',
col.names=c('year','volcanic','solar','GHG','trop'))
# Adjust volcanic forcing for daytime only and Earth's albedo
forcing$volcanic <- forcing$volcanic /4 * 0.7
# Add all the forcing terms together
total.forcing <- forcing$solar + forcing$volcanic + forcing$GHG + forcing$trop
# Predict the temperatures from the forcing
temp <- replicate(999,0)
for (i in 1:998) {
temp.eq <- total.forcing[i] * sensitivity
temp[i+1] <- temp[i] + (temp.eq - temp[i]) / timescale
}
# Subtract mean from predicted temperatures to get anomalies
predicted.temp <- temp - mean(temp)
# Read Mann et al (2008) reconstructed temperatres from a file
mann <- read.table('Data/mann2008.temp.txt', header=T)$temp
# Subtract mean reconstruced temperatuers to get anomalies
mann <- mann - mean(mann)
mann <- mann[1:999]
# Plot the predicetd and reconstructed temperatures on the same set of axes
orig.par <- par(no.readonly=T)
par(cex=1.5)
plot(1000:1998, mann, col='lightgray', ylim=c(-.5, .7),
ylab='Temperature Deviation from Mean (Celsius)',
xlab='Year')
lines(1000:1998, predicted.temp, col='red', lwd=5)
legend('topleft',c('simulated','reconstructed'),merge=TRUE,
col=c('red','darkgray'), lwd=c(5,1), lty=c(1,NA), pch=c(NA,1))
par(orig.par)
}
plot.forcing.R:
plot.forcing <- function(forcing){
forcing <- read.forcing()
# Set plot parameters: stack of three plots, large text, nice margins
orig.par <- par(no.readonly=TRUE) # Remember changable parameters to reset later
par (mfrow=c(3,1), cex=1.5, mar=c(3,2,2,1))
plot(forcing$year, forcing$volcanic, typ='l',col='red',lwd=3, cex.axis=1.2,
main='Volcanic Forcing')
plot(forcing$year, forcing$solar, typ='l', col='gold', lwd=3, cex.axis=1.2,
main='Solar Forcing')
plot(forcing$year, forcing$GHG, typ='l', col='red',lwd=3, ylim=c(-1,2.5), cex.axis=1.2,
xlab='Year',main='GHG and Tropospheric Aerosol Forcing')
lines(forcing$year, forcing$trop, typ='l', col='blue', lwd=3)
legend('topleft', c('Greenhouse gases','Tropospheric Aerosol'), lwd=c(3,3),
col=c('red','blue'), cex=1.3)
# Restore original plot parameters
par(orig.par)
}