Note
Click here to download the full example code
Cooling coffee
A hot cup of coffee cools fast at first and then ever more slowly: its excess temperature over the room decays exponentially, Newton's law of cooling, and it approaches the room temperature without ever crossing it.
The coffee starts at 90 degrees in a room at 20 degrees, with the cooling rate k = 0.1 per minute. The default
blueprint shows the temperature over one hour.
import matplotlib.pyplot as plt
import numpy as np
from skcomplex.engine.runtime import Simulation
from skcomplex.engine.viz import RerunObserver
from skcomplex.models import create
MODEL = 'cooling_coffee'
system = create(MODEL, T=90.0, room=20.0, k=0.1)
observer = RerunObserver(MODEL, save_path=f'{MODEL}.rrd', blueprint='default', interval=1)
simulation = Simulation(system, dt=0.5, observers=[observer]).check().prepare().run(until=60)

Open the recording in the Rerun viewer
Exponential relaxation
The solution is T(t) = T_room + (T0 - T_room) exp(-k t), so the excess temperature T - T_room should fall on a
straight line of slope -k on a logarithmic axis, for every starting temperature.
times = np.asarray(simulation.trajectory_.times)
fig, ax = plt.subplots(figsize=(6, 4))
for start in [90.0, 60.0, 40.0]:
run = Simulation(create(MODEL, T=start, room=20.0, k=0.1), dt=0.5).check().prepare().run(until=60)
line = ax.semilogy(times, np.ravel(run.trajectory_.values('coffee.T')) - 20.0, label=f'T0 = {start:.0f}')[0]
ax.semilogy(times, (start - 20.0) * np.exp(-0.1 * times), '--', color=line.get_color())
ax.set_xlabel('time (minutes)')
ax.set_ylabel('T - T_room')
ax.set_title('Excess temperature decays as exp(-k t), dashed')
ax.legend()
plt.show()

Download Python source code: plot_cooling_coffee.py
Download Jupyter notebook: plot_cooling_coffee.ipynb
Gallery generated by mkdocs-gallery
About the model
A cup of coffee whose temperature relaxes to that of the room, T' = -k (T - T_room).
References
- Newton 1701
- Meadows 2008