In Section 6.8, a model of the atmosphere was developed and the Exercises investigated the effects of making changes to the parameterised albedo and emissivity. Here, you will build upon that model by considering how changes in atmospheric water vapour may affect the modelled temperatures.
If the temperature of the atmosphere warms, the carrying capacity of water in the air increases and the evaporation of water increases. This could have two effects.
Firstly, as water vapour is a very powerful greenhouse gas, the emissivity of the atmosphere increases; i.e., the greenhouse effect increases. This is a positive feedback because a warming climate could produce a stronger greenhouse effect that will warm the planet further allowing more water vapour that will in turn produce more warming, etc. If the feedback is strong enough, this could cause a runaway greenhouse effect where the ocean could boil. Atmospheric emissivity at atmospheric temperature Ta can be modelled by the linear relation
\[ \begin{align*} \epsilon_a &= \epsilon_{ac}(T_a-T_{a0})\ + \epsilon_{ao} \tag{1} \end{align*} \] where εac is the emissivity variation coefficient, and εao is the emissivity at the reference atmospheric temperature Ta0. Note: emissivity values are only valid between 0 and 1.
The second feedback due to water vapour could be that the larger amount of water vapour could produce more clouds that could increase the planetary albedo. This would reflect more sunlight back to space thus cooling the planet. This feedback is a negative feedback. If warming is caused by some other factor, more clouds will limit the warming. Also, if there was some other effect to cool the planet, the lower albedo, due to fewer clouds, would tend to heat the planet. It is a negative feedback because the original perturbation is made smaller. Albedo at atmospheric temperature Ta can be modelled by the linear relation
\[ \begin{align*} \alpha &= \alpha_{c}(T_a-T_{a0})\ + \alpha_{o} \tag{2} \end{align*} \] where αc is the albedo variation coefficient, Ta0 is a reference atmospheric temperature and αo is the albedo at the reference temperature. Note: albedo values are only valid between 0 and 1.
# 1. Start a function that takes the model parameters that might change as arguments i.e albedo and emissivity
ClimateChangeModel<- function(Propn.ocean, No.Years, StartingT.s, T.a0, alpha.c, alpha.o, epsilon.ac, epsilon.ao, plot=T){
# 2. SET MODEL PARAMETERS
A = 4*pi*(6378000^2) #earths surface area
C = (A*Propn.ocean*100*1025*3.993)+(A*(1-Propn.ocean)*5*1600*0.8) # total surface heat capacity
S = 1368 #solar constant, in Watts
sigma = 5.6704e-8 # Stefan-Boltzmann constant using scientific notation
Time.int = (365/2)*24*60*60 # Time interval: the number of seconds in half a year
# T.a0 = 240
# epsilon.ac = 0.01 # emissivity variation coefficient, in K^-1
# epsilon.ao = 0.78
# alpha.c = 0.01 # albedo variation coefficient, in K^-1
# alpha.o = 0.3
# 3. INITIATE VECTORS
Year = seq(from=0, to=20, by=0.5) # 6-month intervals
Rate.in = rep(S/4, length(Year)) # Rate in is a constant
Rate.out = numeric(length(Year)) # Empty Vectors
DeltaT = numeric(length(Year))
T.s = numeric(length(Year))
alpha = numeric(length(Year))
epsilon = numeric(length(Year))
T.s[1] = StartingT.s # Set initial T.s
T.a = numeric(length(Year))
# 4. LOOP for every timestep
for (i in 1:length(Year)) {
# calculate T.a from T.s for the ith timestep
T.a[i] = T.s[i]/(2^0.25)
# calculate alpha for the ith timestep
alpha[i] = alpha.c * (T.a[i] - T.a0) + alpha.o
# print(alpha[i])
# calculate epsilon for the ith timestep
epsilon[i] = epsilon.ac * (T.a[i] - T.a0) + epsilon.ao
# print(epsilon[i])
# calculate rate out for the ith timestep
Rate.out[i] = alpha[i]*S/4 + (1-epsilon[i])*sigma*T.s[i]^4 + epsilon[i]*sigma*T.a[i]^4
# Calculate DeltaT for the ith timestep
DeltaT[i] = (1/C)*(Rate.in[i]-Rate.out[i])*(A/1000)*Time.int
# If we have not reached the last timestep, Add the change in temperature to the surface
# tempeture to be used in the next timestep. If it is the last timestep, do nothing
if (i < length(Year)) {
T.s[i+1] = T.s[i] + DeltaT[i]
} else {}
}
# 5. COMBINE INTO DATA FRAME FOR PLOTTING
ClimateChange = data.frame(Year, Rate.in, Rate.out, DeltaT, T.s, T.a, alpha, epsilon)
# print(round((ClimateChange),5))
# 6. PLOT RESULTS
if (plot==T){
with(ClimateChange, plot(T.s ~ Year, type="o", col="blue",
ylim=c(min(T.a)-10,max(T.s)+10), ylab="Temperature (K)", xlab = "Time (years)",
main = "Climate Change Model"))
lines(T.a ~ Year, type="o", col="red")
axis(1, at = seq(1,20, by=1), labels = FALSE, tcl = -0.25)
axis(2, at = seq(0,400, by=10), labels = FALSE, tcl = -0.25)
legend("topright", c(expression(T[s]), expression(T[a])), lty = c(1, 1), col = c("blue", "red"), horiz = TRUE)
}
return(ClimateChange)
}
test <- ClimateChangeModel(Propn.ocean=0.7, No.Years=20, StartingT.s = 288, T.a0 = 240, alpha.c = 0.01, alpha.o = 0.3, epsilon.ac = 0.01, epsilon.ao = 0.78)
no_variation.test <- ClimateChangeModel(Propn.ocean=0.7, No.Years=20, StartingT.s = 288, T.a0 = 240, alpha.c = 0, alpha.o = 0.3, epsilon.ac = 0, epsilon.ao = 0.78)
Explore the model using various values of αc and εac. First, increment (up and down) the albedo variation coefficient, including use of negative values, whilst holding the emissivity variation coefficient constant. Test if the albedo and/or atmospheric emissivity can be made to go outside the valid range; record temperature values where convergence occurs.
results <- data.frame(alpha.c = numeric(0), alpha_out_of_range = logical(0), epsilon_out_of_range = logical(0))
for (alpha.c in seq(-1, 1, 0.01)) {
result <- ClimateChangeModel(
Propn.ocean = 0.7,
No.Years = 20,
StartingT.s = 288,
T.a0 = 240,
alpha.c = alpha.c,
alpha.o = 0.3,
epsilon.ac = 0.01,
epsilon.ao = 0.78,
plot = FALSE
)
alpha_out_of_range <- any(result$alpha < 0 | result$alpha > 1)
epsilon_out_of_range <- any(result$epsilon < 0 | result$epsilon > 1)
results <- rbind(results, data.frame(alpha.c, alpha_out_of_range, epsilon_out_of_range))
}
# print(results)
valid_range <- round(results$alpha.c[!results$epsilon_out_of_range & !results$alpha_out_of_range],3)
paste("The maximum and minimum values of the albedo variation coefficient for which valid values of albedo and emissivity occur is", max(valid_range), "and", min(valid_range), "respectively.")
## [1] "The maximum and minimum values of the albedo variation coefficient for which valid values of albedo and emissivity occur is 0.12 and 0 respectively."
Second, vary the emissivity variation coefficient, including use of negative values, whilst holding the albedo variation coefficient constant (repeat the tests; record values).
results <- data.frame(epsilon.ac = numeric(0), alpha_out_of_range = logical(0), epsilon_out_of_range = logical(0))
for (epsilon.ac in seq(-1, 1, 0.01)) {
result <- ClimateChangeModel(
Propn.ocean = 0.7,
No.Years = 20,
StartingT.s = 288,
T.a0 = 240,
alpha.c = 0.01,
alpha.o = 0.3,
epsilon.ac = epsilon.ac,
epsilon.ao = 0.78,
plot = FALSE
)
alpha_out_of_range <- any(result$alpha < 0 | result$alpha > 1)
epsilon_out_of_range <- any(result$epsilon < 0 | result$epsilon > 1)
results <- rbind(results, data.frame(epsilon.ac, alpha_out_of_range, epsilon_out_of_range))
}
# print(results)
valid_range <- round(results$epsilon.ac[!results$epsilon_out_of_range & !results$alpha_out_of_range],3)
paste("The maximum and minimum values of the emissivity variation coefficient for which valid values of albedo and emissivity occur is", max(valid_range), "and", min(valid_range), "respectively.")
## [1] "The maximum and minimum values of the emissivity variation coefficient for which valid values of albedo and emissivity occur is 0.02 and -0.16 respectively."
Third, vary both parameters (guided by the values found when varying only one parameter at a time) and repeat the tests/record values.
Year = seq(0, 20, 0.5)
alpha.c_params <- c(0.12,0,0.01,0.01,0.03,0.04,0.01)
epsilon.ac_params <- c(0.01,0.01,-0.16,0.02,-0.01,-0.03,-0.05)
plot(Year, numeric(length(Year)), ylim=c(283.5,292), ylab = "Surface temperature (K)", xlab = "Time (years)",
main = "Surface Temperatures", type="l", col = "white")
axis(1, at = seq(1,20, by=1), labels = FALSE, tcl = -0.25)
colours = rainbow(length(alpha.c_params))
t.s_legend <- data.frame(epsilon.ac = epsilon.ac_params, alpha.c = alpha.c_params)
for (i in 1:8) {
surface_temp <- ClimateChangeModel(Propn.ocean = 0.7, No.Years = 20, StartingT.s = 288, T.a0 = 240, alpha.o = 0.3, epsilon.ao = 0.78, plot = FALSE, epsilon.ac = epsilon.ac_params[i], alpha.c = alpha.c_params[i])
lines(surface_temp$Year, surface_temp$T.s, type="o", col = colours[i])
}
legend("topright", legend = paste(t.s_legend$epsilon.ac, t.s_legend$alpha.c), col = colours, lty = 1,
title = " ε.ac α.c", cex = 0.8)
plot(Year, numeric(length(Year)), ylim=c(238,246), ylab = "Atmospheric temperature (K)", xlab = "Time (years)",
main = "Atmospheric Temperatures", type="l", col = "white")
axis(1, at = seq(1,20, by=1), labels = FALSE, tcl = -0.25)
for (i in 1:8) {
surface_temp <- ClimateChangeModel(Propn.ocean = 0.7, No.Years = 20, StartingT.s = 288, T.a0 = 240, alpha.o = 0.3, epsilon.ao = 0.78, plot = FALSE, epsilon.ac = epsilon.ac_params[i], alpha.c = alpha.c_params[i])
lines(surface_temp$Year, surface_temp$T.a, type="o", col = colours[i])
}
legend("topright", legend = paste(t.s_legend$epsilon.ac, t.s_legend$alpha.c), col = colours, lty = 1,
title = " ε.ac α.c", cex = 0.8)
As αc is negative feedback and εac is positive feedback, we would expect increasing αc decreasing εac to have a roughly similar effect on temperature. When αc and εac are at their extremes (0.12 and -0.16 respectively), we see a greater decrease in temperature for αc, indicating a greater sensitivity towards it. So, the albedo feedback mechanism could influence temperature more, hence, changes in αc have a greater impact on outcome and the model is more sensitive to changes in αc compared to εac.
| εac | αc = 0.00 | αc = 0.01 | αc = 0.04 | αc = 0.06 | αc = 0.08 | αc = 0.10 | αc = 0.12 | |
|---|---|---|---|---|---|---|---|---|
| 0.02 | x* | 288.899 | 286.267 | 285.981 | 285.838† | 285.753† | 285.673† | |
| 0.01 | 291.480 | 287.606 | 286.162 | 285.933 | 285.811† | 285.735† | 284.788† | |
| 0.00 | 288.433 | 287.024 | 286.080 | 285.892 | 285.786† | 285.719† | x*† | |
| -0.01 | 287.435 | 286.689 | 286.015 | 285.857 | 285.765† | 285.702† | x*† | |
| -0.04 | 286.433 | 286.200† | 285.878† | 285.778† | 285.713† | x*† | x*† | |
| -0.10 | 285.925† | 285.858† | 285.732† | 284.023† | x*† | x*† | x*† | |
| -0.16 | 285.755† | 285.723† | x*† | x*† | x*† | x*† | x*† |
Generally, as the variation coefficients get more extreme, the function tends to oscillate. This can be interpreted as the feedback mechanisms of albedo and emissivity having a larger effect compared to other determinants of temperature. At a certain point, the variation coefficients overtake other properties entirely, and temperature diverges. It’s worth noting that some cases on the plots in #4 appear to have reached an asymptote (e.g. εac = -0.16, αc = 0.01), but are just oscillating by miniscule amounts.
When changing the variation coefficents in the direction opposite to their feedback loop, εac negative and αc positive, in moderate amounts, we see lower temperatures from less energy emitted and more energy reflected in a down right through the table. The reverse occurs when changing them in the direction of their feedback loops, (i.e. εac = 0.02, αc = 0.01 and εac = 0.01, αc = 0).
In Equation 1, replace the atmospheric temperature, Ta, with surface temperature, Ts (including resetting the reference temperature to Ts0 = 288 K).
## [1] "The maximum and minimum values of the albedo variation coefficient for which valid values of albedo and emissivity occur is 0.12 and 0 respectively."
## [1] "The maximum and minimum values of the emissivity variation coefficient for which valid values of albedo and emissivity occur is 0.03 and -0.16 respectively."
Step 4B
Step 5B
The range of αc is identical, but εac maximum and minimums are slightly different. The key difference compared to part A is εa appears to follow a positive feedback loop as well. This can be seen when εac = 0.02, αc = 0.01, where the curve is decreasing instead of increasing to an asymptote. Additionally, some curves are diverging (e.g. εac = -0.16, αc = 0.01), despite having all valid values, meaning the values likely become invalid after the 20 years.
Step 6B
| εac | αc = 0.00 | αc = 0.01 | αc = 0.04 | αc = 0.06 | αc = 0.08 | αc = 0.10 | αc = 0.12 | |
|---|---|---|---|---|---|---|---|---|
| 0.02 | x* | 288.899 | 286.267 | 285.981† | 285.838† | 285.231† | 285.263† | |
| 0.01 | 289.012 | 287.606 | 286.162 | 285.933† | 285.811† | 285.576† | 284.979† | |
| 0.00 | 288.433 | 287.024 | 286.080 | 285.892† | 285.786† | 285.719† | x*† | |
| -0.01 | 288.272 | 287.257 | 286.300 | 286.071† | 285.936† | 285.842† | x*† | |
| -0.04 | 288.129 | 287.568 | 286.737† | 286.464† | 286.282† | x*† | x*† | |
| -0.10 | 288.063† | 285.858† | 285.732† | x† | x*† | x*† | x*† | |
| -0.16 | 288.042† | x† | x*† | x*† | x*† | x*† | x*† |
Step 7B
Similar trends as observed in #4, with the notable case of (e.g. εac = -0.16, αc = 0.01), where the curve diverges, but has valid values, although they likely will become invalid after the set time. Oscillating curves generally occur with lower values of αc as well, at 0.06 here compared to 0.04 in part A.
Replace the linear function of Equation 1 with a non-linear form for emissivity.
\[ \begin{align*} \epsilon_{a} &= ke_s =k\ 6.1094e^{\frac{17.625\ \cdot\ (T_a - 273.15)}{243.04\ +\ (T_a - 273.15)}} \end{align*} \] (the August-Roche-Magnus formula; see https://en.wikipedia.org/wiki/Clausius-Clapeyron_relation).
\[ \begin{align*} \epsilon_{a} &=k\ 6.1094e^{\frac{17.625\ \cdot\ (T_a - 273.15)}{243.04\ +\ (T_a - 273.15)}} \\ 0.78 &=k\ 6.1094e^{\frac{17.625\ \cdot\ (240 - 273.15)}{243.04\ +\ (240 - 273.15)}} \\ 0.78 &=k\cdot 0.37766... \\ k &= 2.06555... \approx2.066 \end{align*} \]
## [1] "The maximum and minimum values of the albedo variation coefficient for which valid values of albedo and emissivity occur is 0.15 and 0.05 respectively."
Step 4C
Step 5C
The range of αc is notably different here, between 0.05 to 0.15, potentially due to the more rapid rate of change of εac, so higher values are required to compensate and stablise the curve. But overall, the curves are more predictable as we are only increasing one variable (εac is no longer a parameter).
Step 6C
| αc = 0.05 | αc = 0.07 | αc = 0.09 | αc = 0.11 | αc = 0.13 | αc = 0.15 |
|---|---|---|---|---|---|
| 287.855 | 286.325 | 286.000 | 285.847† | 285.758† | 285.693† |
Step 7C
Again, a more predictable and simple table as only εac is being altered. We can see the point where oscillation occurs at αc = 0.11. All albedo and epsilon values are valid here, as they are within the limits, and we don’t see the interaction between the changing of both loops at once.
Code for Step 6A
alpha.c_params <- c(0,0.01,0.04,0.06,0.08,0.10,0.12)
epsilon.ac_params <- c(0.02,0.01,0,-0.01,-0.04,-0.10,-0.16)
results.vals <- data.frame(matrix(ncol = length(epsilon.ac_params) + 1, nrow = length(alpha.c_params)))
names(results.vals) <- c("alpha.c", as.character(epsilon.ac_params))
results.vals$alpha.c <- alpha.c_params
results.oscillates <- data.frame(matrix(ncol = length(epsilon.ac_params) + 1, nrow = length(alpha.c_params)))
names(results.oscillates) <- c("alpha.c", as.character(epsilon.ac_params))
results.oscillates$alpha.c <- alpha.c_params
results.valid <- data.frame(matrix(ncol = length(epsilon.ac_params) + 1, nrow = length(alpha.c_params)))
names(results.valid) <- c("alpha.c", as.character(epsilon.ac_params))
results.valid$alpha.c <- alpha.c_params
for (i in 1:length(epsilon.ac_params)) {
for (j in 1:length(alpha.c_params)) {
result <- ClimateChangeModel(
Propn.ocean = 0.7,
No.Years = 20,
StartingT.s = 288,
T.a0 = 240,
alpha.c = alpha.c_params[j],
alpha.o = 0.3,
epsilon.ac = epsilon.ac_params[i],
epsilon.ao = 0.78,
plot = FALSE
)
temp.diff <- result$DeltaT
is_asymptotic <- TRUE
is_oscillating <- FALSE
if (abs(temp.diff[3]) >= abs(temp.diff[2])) {
is_asymptotic <- FALSE
}
for (year in 2:length(temp.diff) - 1) {
if (!is.na(temp.diff[year]) && !is.na(temp.diff[year + 1]) && sign(temp.diff[year]) != sign(temp.diff[year + 1])) {
is_oscillating <- TRUE #checks for sign differences between temp diffs over years
break
}
}
asymptote.val <- 0
if (is_asymptotic & !is_oscillating) {
asymptote.val <- round(result$T.s[length(result$T.s)-1], 3)
}
if (is_asymptotic & is_oscillating) {
asymptote.val <- round(mean(result$T.s[length(result$T.s)-1], result$T.s[length(result$T.s)-2]), 3)
}
if (!is_asymptotic) {
asymptote.val <- NA
}
results.vals[j, i + 1] <- asymptote.val
results.oscillates[j, i + 1] <- is_oscillating
is.valid <- TRUE
alpha_out_of_range <- any(result$alpha < 0 | result$alpha > 1)
epsilon_out_of_range <- any(result$epsilon < 0 | result$epsilon > 1)
if (alpha_out_of_range | epsilon_out_of_range) {
is.valid <- FALSE
}
results.valid[j, i + 1] <- is.valid
}
}
library(knitr)
kable(results.vals)
kable(results.oscillates)
kable(results.valid)
Model used for Question 8
# 1. Start a function that takes the model parameters that might change as arguments i.e albedo and emissivity
ClimateChangeModelB<- function(Propn.ocean, No.Years, StartingT.s, T.a0, alpha.c, alpha.o, epsilon.ac, epsilon.ao, plot=T){
# 2. SET MODEL PARAMETERS
A = 4*pi*(6378000^2) #earths surface area
C = (A*Propn.ocean*100*1025*3.993)+(A*(1-Propn.ocean)*5*1600*0.8) # total surface heat capacity
S = 1368 #solar constant, in Watts
sigma = 5.6704e-8 # Stefan-Boltzmann constant using scientific notation
Time.int = (365/2)*24*60*60 # Time interval: the number of seconds in half a year
# T.a0 = 240
# epsilon.ac = 0.01 # emissivity variation coefficient, in K^-1
# epsilon.ao = 0.78
# alpha.c = 0.01 # albedo variation coefficient, in K^-1
# alpha.o = 0.3
# 3. INITIATE VECTORS
Year = seq(from=0, to=20, by=0.5) # 6-month intervals
Rate.in = rep(S/4, length(Year)) # Rate in is a constant
Rate.out = numeric(length(Year)) # Empty Vectors
DeltaT = numeric(length(Year))
T.s = numeric(length(Year))
alpha = numeric(length(Year))
epsilon = numeric(length(Year))
T.s[1] = StartingT.s # Set initial T.s
T.a = numeric(length(Year))
# 4. LOOP for every timestep
for (i in 1:length(Year)) {
# calculate T.a from T.s for the ith timestep
T.a[i] = T.s[i]/(2^0.25)
# calculate alpha for the ith timestep
alpha[i] = alpha.c * (T.a[i] - T.a0) + alpha.o
# print(alpha[i])
# calculate epsilon for the ith timestep
epsilon[i] = epsilon.ac * (T.s[i] - StartingT.s) + epsilon.ao
# print(epsilon[i])
# calculate rate out for the ith timestep
Rate.out[i] = alpha[i]*S/4 + (1-epsilon[i])*sigma*T.s[i]^4 + epsilon[i]*sigma*T.a[i]^4
# Calculate DeltaT for the ith timestep
DeltaT[i] = (1/C)*(Rate.in[i]-Rate.out[i])*(A/1000)*Time.int
# If we have not reached the last timestep, Add the change in temperature to the surface
# tempeture to be used in the next timestep. If it is the last timestep, do nothing
if (i < length(Year)) {
T.s[i+1] = T.s[i] + DeltaT[i]
} else {}
}
# 5. COMBINE INTO DATA FRAME FOR PLOTTING
ClimateChange = data.frame(Year, Rate.in, Rate.out, DeltaT, T.s, T.a, alpha, epsilon)
# print(round((ClimateChange),5))
# 6. PLOT RESULTS
if (plot==T){
with(ClimateChange, plot(T.s ~ Year, type="o", col="blue",
ylim=c(min(T.a)-10,max(T.s)+10), ylab="Temperature (K)", xlab = "Time (years)",
main = "Climate Change Model"))
lines(T.a ~ Year, type="o", col="red")
axis(1, at = seq(1,20, by=1), labels = FALSE, tcl = -0.25)
axis(2, at = seq(0,400, by=10), labels = FALSE, tcl = -0.25)
legend("topright", c(expression(T[s]), expression(T[a])), lty = c(1, 1), col = c("blue", "red"), horiz = TRUE)
}
return(ClimateChange)
}
Code for Step 6B
alpha.c_params <- c(0,0.01,0.04,0.06,0.08,0.10,0.12)
epsilon.ac_params <- c(0.03,0.01,0,-0.01,-0.04,-0.10,-0.16)
results.vals <- data.frame(matrix(ncol = length(epsilon.ac_params) + 1, nrow = length(alpha.c_params)))
names(results.vals) <- c("alpha.c", as.character(epsilon.ac_params))
results.vals$alpha.c <- alpha.c_params
results.oscillates <- data.frame(matrix(ncol = length(epsilon.ac_params) + 1, nrow = length(alpha.c_params)))
names(results.oscillates) <- c("alpha.c", as.character(epsilon.ac_params))
results.oscillates$alpha.c <- alpha.c_params
results.valid <- data.frame(matrix(ncol = length(epsilon.ac_params) + 1, nrow = length(alpha.c_params)))
names(results.valid) <- c("alpha.c", as.character(epsilon.ac_params))
results.valid$alpha.c <- alpha.c_params
for (i in 1:length(epsilon.ac_params)) {
for (j in 1:length(alpha.c_params)) {
result <- ClimateChangeModelB(
Propn.ocean = 0.7,
No.Years = 20,
StartingT.s = 288,
T.a0 = 240,
alpha.c = alpha.c_params[j],
alpha.o = 0.3,
epsilon.ac = epsilon.ac_params[i],
epsilon.ao = 0.78,
plot = FALSE
)
temp.diff <- result$DeltaT
is_asymptotic <- TRUE
is_oscillating <- FALSE
if (abs(temp.diff[3]) >= abs(temp.diff[2])) {
is_asymptotic <- FALSE
}
for (year in 2:length(temp.diff) - 1) {
if (!is.na(temp.diff[year]) && !is.na(temp.diff[year + 1]) && sign(temp.diff[year]) != sign(temp.diff[year + 1])) {
is_oscillating <- TRUE #checks for sign differences between temp diffs over years
break
}
}
asymptote.val <- 0
if (is_asymptotic & !is_oscillating) {
asymptote.val <- round(result$T.s[length(result$T.s)-1], 3)
}
if (is_asymptotic & is_oscillating) {
asymptote.val <- round(mean(result$T.s[length(result$T.s)-1], result$T.s[length(result$T.s)-2]), 3)
}
if (!is_asymptotic) {
asymptote.val <- NA
}
results.vals[j, i + 1] <- asymptote.val
results.oscillates[j, i + 1] <- is_oscillating
is.valid <- TRUE
alpha_out_of_range <- any(result$alpha < 0 | result$alpha > 1)
epsilon_out_of_range <- any(result$epsilon < 0 | result$epsilon > 1)
if (alpha_out_of_range | epsilon_out_of_range) {
is.valid <- FALSE
}
results.valid[j, i + 1] <- is.valid
}
}
library(knitr)
kable(results.vals)
kable(results.oscillates)
kable(results.valid)
Model used for Question 9
# 1. Start a function that takes the model parameters that might change as arguments i.e albedo and emissivity
ClimateChangeModelC<- function(Propn.ocean, No.Years, StartingT.s, T.a0, alpha.c, alpha.o, epsilon.ao, plot=T){
# 2. SET MODEL PARAMETERS
A = 4*pi*(6378000^2) #earths surface area
C = (A*Propn.ocean*100*1025*3.993)+(A*(1-Propn.ocean)*5*1600*0.8) # total surface heat capacity
S = 1368 #solar constant, in Watts
sigma = 5.6704e-8 # Stefan-Boltzmann constant using scientific notation
Time.int = (365/2)*24*60*60 # Time interval: the number of seconds in half a year
# T.a0 = 240
# epsilon.ac = 0.01 # emissivity variation coefficient, in K^-1
# epsilon.ao = 0.78
# alpha.c = 0.01 # albedo variation coefficient, in K^-1
# alpha.o = 0.3
# 3. INITIATE VECTORS
Year = seq(from=0, to=20, by=0.5) # 6-month intervals
Rate.in = rep(S/4, length(Year)) # Rate in is a constant
Rate.out = numeric(length(Year)) # Empty Vectors
DeltaT = numeric(length(Year))
T.s = numeric(length(Year))
alpha = numeric(length(Year))
epsilon = numeric(length(Year))
T.s[1] = StartingT.s # Set initial T.s
T.a = numeric(length(Year))
k = epsilon.ao / (6.1094 * exp((17.625 * (T.a0 - 273.15)) / (243.04 + (T.a0 - 273.15))))
# 4. LOOP for every timestep
for (i in 1:length(Year)) {
# calculate T.a from T.s for the ith timestep
T.a[i] = T.s[i]/(2^0.25)
# calculate alpha for the ith timestep
alpha[i] = alpha.c * (T.a[i] - T.a0) + alpha.o
# print(alpha[i])
# calculate epsilon for the ith timestep
epsilon[i] = k * 6.1094 * exp((17.625 * (T.a[i] - 273.15)) / (243.04 + (T.a[i] - 273.15)))
# print(epsilon[i])
# calculate rate out for the ith timestep
Rate.out[i] = alpha[i]*S/4 + (1-epsilon[i])*sigma*T.s[i]^4 + epsilon[i]*sigma*T.a[i]^4
# Calculate DeltaT for the ith timestep
DeltaT[i] = (1/C)*(Rate.in[i]-Rate.out[i])*(A/1000)*Time.int
# If we have not reached the last timestep, Add the change in temperature to the surface
# tempeture to be used in the next timestep. If it is the last timestep, do nothing
if (i < length(Year)) {
T.s[i+1] = T.s[i] + DeltaT[i]
} else {}
}
# 5. COMBINE INTO DATA FRAME FOR PLOTTING
ClimateChange = data.frame(Year, Rate.in, Rate.out, DeltaT, T.s, T.a, alpha, epsilon)
# print(round((ClimateChange),5))
# 6. PLOT RESULTS
if (plot==T){
with(ClimateChange, plot(T.s ~ Year, type="o", col="blue",
ylim=c(min(T.a)-10,max(T.s)+10), ylab="Temperature (K)", xlab = "Time (years)",
main = "Climate Change Model"))
lines(T.a ~ Year, type="o", col="red")
axis(1, at = seq(1,20, by=1), labels = FALSE, tcl = -0.25)
axis(2, at = seq(0,400, by=10), labels = FALSE, tcl = -0.25)
legend("topright", c(expression(T[s]), expression(T[a])), lty = c(1, 1), col = c("blue", "red"), horiz = TRUE)
}
return(ClimateChange)
}
Code for Step 6C
alpha.c_params <- c(0.05,0.07,0.09,0.11,0.13,0.15)
epsilon.ac_params <- c(0)
results.vals <- data.frame(matrix(ncol = length(epsilon.ac_params) + 1, nrow = length(alpha.c_params)))
names(results.vals) <- c("alpha.c", as.character(epsilon.ac_params))
results.vals$alpha.c <- alpha.c_params
results.oscillates <- data.frame(matrix(ncol = length(epsilon.ac_params) + 1, nrow = length(alpha.c_params)))
names(results.oscillates) <- c("alpha.c", as.character(epsilon.ac_params))
results.oscillates$alpha.c <- alpha.c_params
results.valid <- data.frame(matrix(ncol = length(epsilon.ac_params) + 1, nrow = length(alpha.c_params)))
names(results.valid) <- c("alpha.c", as.character(epsilon.ac_params))
results.valid$alpha.c <- alpha.c_params
for (i in 1:length(epsilon.ac_params)) {
for (j in 1:length(alpha.c_params)) {
result <- ClimateChangeModelC(
Propn.ocean = 0.7,
No.Years = 20,
StartingT.s = 288,
T.a0 = 240,
alpha.c = alpha.c_params[j],
alpha.o = 0.3,
epsilon.ao = 0.78,
plot = FALSE
)
temp.diff <- result$DeltaT
is_asymptotic <- TRUE
is_oscillating <- FALSE
if (abs(temp.diff[3]) >= abs(temp.diff[2])) {
is_asymptotic <- FALSE
}
for (year in 2:length(temp.diff) - 1) {
if (!is.na(temp.diff[year]) && !is.na(temp.diff[year + 1]) && sign(temp.diff[year]) != sign(temp.diff[year + 1])) {
is_oscillating <- TRUE #checks for sign differences between temp diffs over years
break
}
}
asymptote.val <- 0
if (is_asymptotic & !is_oscillating) {
asymptote.val <- round(result$T.s[length(result$T.s)-1], 3)
}
if (is_asymptotic & is_oscillating) {
asymptote.val <- round(mean(result$T.s[length(result$T.s)-1], result$T.s[length(result$T.s)-2]), 3)
}
if (!is_asymptotic) {
asymptote.val <- NA
}
results.vals[j, i + 1] <- asymptote.val
results.oscillates[j, i + 1] <- is_oscillating
is.valid <- TRUE
alpha_out_of_range <- any(result$alpha < 0 | result$alpha > 1)
epsilon_out_of_range <- any(result$epsilon < 0 | result$epsilon > 1)
if (alpha_out_of_range | epsilon_out_of_range) {
is.valid <- FALSE
}
results.valid[j, i + 1] <- is.valid
}
}
library(knitr)
kable(results.vals)
kable(results.oscillates)
kable(results.valid)