Previously, I modeled a “hot box”, but ignored the effects of the sun. As anyone who has had to get into a car that has sat outside for a while on a hot summer day, the inside of the car is warmer than the outside air temperature, and my previous model didn’t allow that. So the sun is important. Consider the following information from The Humane Society.
It doesn’t have to be that warm outside for a car to become dangerously hot inside.
When it’s 72 degrees Fahrenheit outside, the temperature inside your car can heat up to 116 degrees Fahrenheit within an hour.
When it’s 80 degrees Fahrenheit outside, the temperature inside your car can heat up to 99 degrees Fahrenheit within 10 minutes.
Rolling down the windows has been shown to have little effect on the temperature inside a car.
Let’s translate these temperatures to Celsius and Kelvin
When it’s 22 degrees Celsius outside, the temperature inside your car can heat up to 47 degrees Celsius within an hour.
When it’s 27 degrees Celsius outside, the temperature inside your car can heat up to 37 degrees Celsius within 10 minutes.
My plan for this post is to assume that my heat box will heat up similarly to the above generic car, and see what sort of parameters I need to make that work.
Previous work
As before, I’ll model the system as a simple box, however, this time it will be car-sized, and I’ll use thermal properties that are common for metals like aluminum, rather than parameters used for building materials.
Code
import numpy as np# Heat parametersthermalDiffusivity =22.39e-6# meters^2/s for airheatTransferCoef =1# For a typical metal to air W/m^2KthermalConductivity =50# For a typical metal W/mKspecificHeat =1000# for aluminum J/kg KwallDensity =3000# kg/m^3 for aluminumsolarIntensity =1000# W/m^2# Length parameters (meters)L =3W =2H =1.5Deltax =0.05xmax =int(L/Deltax)ymax =int(W/Deltax)zmax =int(H/Deltax)xmid = xmax //2ymid = ymax //2zmid = zmax //2xgrid = np.linspace(0,L,xmax+1)ygrid = np.linspace(0,W,ymax+1)zgrid = np.linspace(0,H,zmax+1)u0 = np.empty((xmax,ymax,zmax))
Heat Equation
The heat equation is:
\[
\frac{\partial u}{\partial t} = \alpha \nabla^2u + \text{Internal Power Generation Term} + \text{Convection on the boundary}
\]
Where \(\alpha=\frac{k}{c\rho}\) is the thermal diffusivity of the material, and \(k\) is the thermal conductivity, \(c\) is the specific heat, and \(\rho\) is the density. The internal power generation term is going to be related to heat generation due to the absorption of sunlight, and will only be important on surfaces exposed to sunlight. The Boundary convection term will be, again only important on the exterior of the object being modeled. I’ll describe these terms in more detail later in this post.
When working numerically, it is common to employ a finite mesh of points and determine the system temperature at each of these points in space as follows: \[
u(x,y,z,t) \rightarrow u(x_i,y_j,z_k,t) = u_{i,j,k}(t)
\]
I will create this 3D array of functions in time, rather than a 4D array, with one of the dimensions being the evolution in time because when solving differential equations, it is often important to adjust the time step to suit the numerical needs of the system. This way, I will be able to use numerical differential equation solvers as I tackle this problem.
This has the meaning that for this model, the sun is directly overhead, and sunlight is only incident on the top of the box. The constant \(A\) should depend on material properties like specific heat and density as follows:
\[
A = \frac{1}{c\rho\delta_{\text{eff}}}
\]
where \(\delta_{\text{eff}}\) is an effective depth that the sunlight penetrates.
The power exchange per unit volume due to convection is proportional to the difference in temperature of air and the temperature at the boundary:
\[
B \left(T_{\text{air}}-u(x_S,y_S,z_S,t)\right)
\]
for points \((x_S,y_S,z_S)\) on the boundary of the object (assuming a uniform air temperature). Again, \(B\) is a constant that I will determine empirically. However, the constant \(B\) should depend on material properties like specific heat, density, and the heat transfer coefficient as follows:
\[
B = \frac{h}{c\rho\Delta_{\text{eff}}}
\]
where \(\Delta_{\text{eff}}\) is an effective thickness of the convection surface.
Lastly I have to deal with the Laplacian in the following cases:
Interior points
Boundary surfaces
Boundary edges
Boundary corners
In the finite difference method, the Laplacian is proportional to the average deviation of the current point from the nearest neighbors. I’ll show how this is calculated in later sections for surfaces, edges and corners. All in all this is quite tedious, and if you want to skip the math, navigate to the Analysis Plan section through the menu at the right.
Heat Equation on the interior of the box
The heat equation on the interior of the box has none of the contributions from the boundary terms: \[
\frac{\partial u(x,y,z,t)}{\partial t} = \alpha\nabla^2 u(x,y,z,t)
\]
When we apply the finite element approximation, we get the following:
\[\begin{align*}
\nabla^2 u(x,y,z,t) \rightarrow \frac{1}{\Delta x\Delta y\Delta z}
&\left(\Delta y \Delta z \frac{u_{i-1,j,k}(t) + u_{i+1,j,k}(t) -
2 u_{i,j,k}(t)}{\Delta x} \right.\\
&\quad + \Delta x \Delta z \frac{u_{i,j-1,k}(t) + u_{i,j+1,k}(t) - 2
u_{i,j,k}(t)}{\Delta y} \\
&\qquad \left. + \Delta x \Delta y \frac{u_{i,j,k-1}(t) + u_{i,j,k+1}(t)
- 2 u_{i,j,k}(t)}{\Delta z}\right) \\
\end{align*}\]
So if we are considering the \(x=0, i=0\) surface: \[
\frac{du_{0,j,k}(t)}{\partial t} = \alpha \nabla^2 u_{0,j,k}(t) + f_{0jk}(t) + \frac{h}{c\rho}(T_{\text{air}}-u_{0,j,k})
\] where
So if we are considering the \(x=0, i=0\), \(y=0, j=0\) edge: \[
\frac{du_{0,0,k}(t)}{\partial t} = \alpha \nabla^2 u_{0,0,k}(t) + f_{0,0,k}(t) + \frac{h}{c\rho}(T_{\text{air}}-u_{0,0,k})
\] where
So if we are considering the \(x=0, i=0\), \(y=0, j=0\), \(z=0, k=0\) corner: \[
\frac{du_{0,0,0}(t)}{\partial t} = \alpha \nabla^2 u_{0,0,0}(t) + f_{0,0,0}(t) + \frac{h}{c\rho}(T_{\text{air}}-u_{0,0,0})
\] where
I will have to flatten things as solve_ivp only solves a vector system of differential equations rather than the higher dimenionality matrix system that I’ve created.
def dudtFlat(t,uflat, alpha, intensity, dx, Tair, A, B): u = uflat.reshape(xmax,ymax,zmax)return dudt(t,u, alpha, intensity, dx, Tair, A, B).flatten()
Analysis plan
I will begin by choosing parameters \(A\) and \(B\) based on an initial guess, and then I will adjust those parameters to minimize the absolute difference between the result that I obtain and the target temperatures noted in these statements
When it’s 22 degrees Celsius outside, the temperature inside your car can heat up to 47 degrees Celsius within an hour.
When it’s 27 degrees Celsius outside, the temperature inside your car can heat up to 37 degrees Celsius within 10 minutes.
Calculation 1:
For parameters \(A\) and \(B\) (described above) find the difference between the average box temperature after an hour and 47 deg C, assuming an air temperature of 22 deg C.
For parameters \(A\) and \(B\) (described above) find the difference between the average box temperature after 10 minutes and 37 deg C, assuming an air temperature of 27 deg C.
Now I will find the parameters \(A\) and \(B\) that correctly model the statements given in the opening section of this post.
from scipy.optimize import minimizefrom scipy.optimize import Boundsbounds = ((0, None), (0, None))def totalTempDiff(x): A, B = x diff1 = np.abs(calc1(A,B)) diff2 = np.abs(calc2(A,B)) diff = diff1+diff2return diffestA =1/(specificHeat*wallDensity*(Deltax/10))estB = heatTransferCoef/(specificHeat*wallDensity*(Deltax/1000))x0 = np.array([estA,estB])res = minimize(totalTempDiff,x0,bounds=bounds)A,B = res.xdiff1 = np.abs(calc1(A,B))diff2 = np.abs(calc2(A,B))print(f'The temperature differences are {diff1:.3f} deg C for calculation 1 and {diff2:.3f} deg C for calculation 2')
The temperature differences are 0.000 deg C for calculation 1 and 0.030 deg C for calculation 2
Since we can interpret the parameters \(A\) and \(B\) through the properties of materials, as described above, we find:
print(f'A = {res.x[0]:2e} m^2K/Ws and B= {res.x[1]:2e} 1/s')D =1/(specificHeat*wallDensity*res.x[0])Delta = heatTransferCoef/(specificHeat*wallDensity*res.x[1])print(f'δ = {D:.5f} m and Δ = {Delta:.5f} m.')
A = 1.117617e-03 m^2K/Ws and B= 6.666691e-03 1/s
δ = 0.00030 m and Δ = 0.00005 m.
Plot the time evolution of the temperature
Finally, I’ll plot the time evolution of the average temperature for these systems.
Code
def plot1(A,B): oneHour =3600 airTemp =22 hotCarTemp =47 u0.fill(airTemp) time = np.arange(0,oneHour,10) oneHourCalc = solve_ivp(dudtFlat, t_span=[0,oneHour], y0=u0.flatten(), t_eval= time, args=[thermalDiffusivity,solarIntensity,Deltax,airTemp,A,B]) avgBoxTempCalc = np.mean(oneHourCalc.y,axis=0) plt.plot(time,avgBoxTempCalc,label='Avg Car Temp') plt.axhline(y=airTemp,label='Air Temp',ls='--',color='green') plt.axhline(y=hotCarTemp,label='Danger Temp',ls='--',color='red') plt.title(f'Average car temperature when air temp is {airTemp:.0f} C.') plt.xlabel('Time (s)') plt.ylabel('Temperature (C)') plt.legend() plt.show()def plot2(A,B): tenMin =60*10 airTemp =27 hotCarTemp =37 u0.fill(airTemp) time = np.arange(0,tenMin,10) tenMinCalc = solve_ivp(dudtFlat, t_span=[0,tenMin], y0=u0.flatten(), t_eval= time, args=[thermalDiffusivity,solarIntensity,Deltax,airTemp,A,B]) avgBoxTempCalc = np.mean(tenMinCalc.y,axis=0) plt.plot(time,avgBoxTempCalc,label='Avg Car Temp') plt.axhline(y=airTemp,label='Air Temp',ls='--',color='green') plt.axhline(y=hotCarTemp,label='Danger Temp',ls='--',color='red') plt.title(f'Average car temperature when air temp is {airTemp:.0f} C.') plt.xlabel('Time (s)') plt.ylabel('Temperature (C)') plt.legend() plt.show()A,B = res.xplot1(A,B)plot2(A,B)
This makes sense. In both systems the rate of heating decreases with time, suggesting that there is an upper limit to the temperature that the box will approach. Note that we need to put the ratio of the area of the top surface to the total surface area of the box in front of the solar generation term as the box is only gaining area through the top surface in this model, while convection is occurring everywhere on the surface of the box.
Given the system that I’m modeling, and values for \(A\) and \(B\) that I have found, we can calculate the difference between air temperature and the steady-state box temperature.
topArea = L*WboxArea =2*(L*W + L*H + W*H)solarBoost = A * solarIntensity/B * topArea/boxAreaprint(f'The temperature after a long time should approach a value that is {solarBoost:.2f} deg C warmer than the air temperature.')
The temperature after a long time should approach a value that is 37.25 deg C warmer than the air temperature.
Let’s verify this calculation by simulating this system for 10 hours.
And then I will plot the average temperature as a function of time, as well as the average temperature at a range of heights.
def plotTemperature(uflat): oneHour =3600 airTemp =27 eqTemp = airTemp + A*solarIntensity/B * L*W/(2*(L*W + L*H + W*H)) time = np.arange(0,10*oneHour,100) avgBoxTempCalc = np.mean(uflat,axis=0) avgBoxTempZ = np.empty((len(time),zmax))for l inrange(len(time)): umat = uflat[:, l].reshape((xmax,ymax,zmax))for k inrange(zmax): avgBoxTempZ[l,k] = np.mean(umat[:,:,k]) plt.plot(time,avgBoxTempCalc,label='Avg Car Temp')for k inreversed(range(0, zmax, 5)): zdim = k * Deltax labText =f'z = {zdim:.3f} m' plt.plot(time, avgBoxTempZ[:,k],label=labText,ls='dotted') plt.axhline(y=airTemp,label='Air Temp',ls='--',color='green') plt.axhline(y=eqTemp,label='Equilibrium Temp',ls='--',color='red') plt.title(f'Average car temperature when air temp is {airTemp:.0f} C.') plt.xlabel('Time (s)') plt.ylabel('Temperature (C)') plt.legend(bbox_to_anchor=(1.05,0.75)) plt.show()plotTemperature(longCalc.y)
As we see that the temperature is not uniform at every point in the hot box, it becomes clear that assumption of uniform temperature is not appropriate. Since we see there is still a temperature gradient along the z-direction, conduction is still important in this system, and contributes to the equilibrium. Still this rough approximation gave a good intuition about the dynamics of the system even if it wasn’t numerically accurate.
Note, this assumes that the sun stays at “high noon” for at least 10 hours, so it isn’t representative of a real car on the surface of the earth. As such, it’s not worth exploring this further, except for the purposes of developing better visualizations.
Coming soon
So far, this has been lots of equations, and not enough pictures. But this is a complex system, and I need to add one feature at a time to ensure that it is working correctly. My first order of business will be to make a surface heat map of what is going on so that it is easier to talk about and show everyone what is going on.
I also need to develop code which allows for the sun to change it’s position. And I’ll deal with other issues such as seasonal changes/the varying length of day/night. As well as deal with latitude. I’ve been fiddling with the math on the back of napkins, and that should work nicely with some pretty pictures. Then we can compare hot boxes in higher latitudes to those with lower latitudes.