initial_temperature <- 90 # degrees C
ambient <- 22 # degrees C
k <- 0.15 # per minute
target <- 47 # degrees C; owner's preference
end_time <- 12 # minutes
delta_t <- 2
time_2 <- seq(0, end_time, by = delta_t)
euler_2 <- numeric(length(time_2))
rk2_2 <- numeric(length(time_2))
euler_2[1] <- initial_temperature
rk2_2[1] <- initial_temperature
for (i in 2:length(time_2)) {
# Euler: use the old Euler temperature to find its starting rate.
# TODO: update euler_2[i].
# RK2: use the old RK2 temperature to find its starting rate.
# TODO: predict the endpoint using an Euler step.
# TODO: find the rate at that prediction.
# TODO: update rk2_2[i] using the average of the two rates.
}
results_2 <- data.frame(time = time_2, euler = euler_2, rk2 = rk2_2)
head(results_2, 2)Model and assumptions
Explain the cooling-rate formula in your own words. Why does cooling slow down over time? State two assumptions.
First step by hand
With a two-minute step, calculate the first Euler update. Then show the Euler prediction, predicted ending rate, average rate, and corrected RK2 update. Include units.
Two-minute simulations
Complete the loop. Remove #| eval: false when your code is ready to run.
Compare the second row with your hand calculation. Do they agree?
Graph and first recorded target time
Make a graph of the two-minute Euler and RK2 simulations and the exact cooling curve. Find the first recorded time at or below 47°C for each method. The pattern which(temperature <= target)[1] gives the position of the first qualifying value.
exact_2 <- ambient + (initial_temperature - ambient) *
exp(-k * time_2)
# TODO: plot exact_2 versus time_2.
# TODO: add Euler and RK2 lines, a legend, and axis labels with units.
# TODO: use which() to find the first qualifying position for each method.
# TODO: look up the corresponding times in time_2.Describe the difference between the three curves. Which simulated method first records a temperature at or below 47°C sooner?
Half-minute simulations
Repeat both methods with a 0.5-minute step. Copy and adapt the loop above, using new vector names so that you keep the two-minute results. Remove #| eval: false when the code is ready.
delta_t <- 0.5
time_05 <- seq(0, end_time, by = delta_t)
euler_05 <- numeric(length(time_05))
rk2_05 <- numeric(length(time_05))
euler_05[1] <- initial_temperature
rk2_05[1] <- initial_temperature
for (i in 2:length(time_05)) {
# TODO: Euler update using euler_05[i - 1].
# TODO: RK2 prediction and corrected update using rk2_05[i - 1].
}
# TODO: find the first recorded time at or below 47 C for each method.Results and numerical error
Use the given exact formula to find the temperature at minute 12. Calculate the absolute error of all four simulated temperatures at minute 12. Create a small table containing the method, step size, minute-12 temperature, absolute error, and first recorded target time.
exact_at_12 <- ambient + (initial_temperature - ambient) *
exp(-k * end_time)
# TODO: collect the four final temperatures and four first target times.
# TODO: calculate abs(simulated_temperature - exact_at_12).
# TODO: put the results in a data frame and display it.How do method and step size affect the error? Remember that an accurate solution to a model is not proof that the model fits a real drink.
Recommendation
How long should this owner wait according to your simulations? Explain your choice and one reason the prediction could differ from a real temperature measurement.