Solving Time-Indepdendent PDEs#

Teng-Jui Lin

Content adapted from UW CHEME 375, Chemical Engineering Computer Skills, in Spring 2021.

  • Python skills and numerical methods

    • Finite difference method for PDEs

  • ChemE applications

    • Time-independent 2D heat transfer

Time-independent 2D heat transfer#

Problem Statement. We have a thin metal slab at steady-state, having different temperatures on its four sides. Determine the equilibrium temperature of the slab of points in the interval [1,3]×[1,3] with equal spacing of 1.

Given boundary conditions T(0,y)=75C,T(4,y)=50C,T(x,0)=0C,T(x,4)=100C.

Analytic expression#

Solution. We have the heat transport governing equation

k2T+q˙+Φ=ρCVTt

where 2=2x2+2y2+2z2.

Based on the problem statement, we have the assumptions:

  • No heat source/generation

    • q˙=0

  • No fluid or heat movement

    • Φ=0

  • Steady-state system no time dependence

    • Tt=0

  • Thin metal slab 2D heat transfer (no heat transfer in z direction)

    • 2Tz2=0

  • Constant thermal conductivity kf(x,y,z,t)

    • k can be simplified

Therefore, we can simplify the governing equation:

k2T+q˙+Φ=ρCVTtk2T=02T=0(2x2+2y2+2z2)T=02Tx2+2Ty2=0

Numerical approximations#

By central finite difference, we approximate the derivatives by

2Tx2Ti1,j2Ti,j+Ti+1,jΔx2
2Ty2Ti,j12Ti,j+Ti,j+1Δy2

Assume that the spacing in x and y directions are the same Δx=Δy=1, we have from the original equation:

2Tx2+2Ty2=0Ti1,j2Ti,j+Ti+1,jΔx2+Ti,j12Ti,j+Ti,j+1Δy2=0Ti1,j2Ti,j+Ti+1,j+Ti,j12Ti,j+Ti,j+1=0

For each point in the slab, we write out the expression from the above equation. We also replace the boundary conditions with numerical values. For example, at point (i,j)=(1,1), we have

T0,12T1,1+T2,1+T1,02T1,1+T1,2=0T0,1+T1,04T1,1+T1,2+T2,1=04T1,1+T1,2+T2,1=T0,1T1,04T1,1+T1,2+T2,1=75

From PDE to linear algebra#

We can repeat the process for all the points. In this case, we have 9 points, therefore 9 equations and 9 unknowns:

+4T1,1T2,1T1,2=75T1,1+4T2,1T3,1T2,2=0T2,1+4T3,1T3,2=50T1,1+4T1,2T2,2T1,3=75T2,1T1,2+4T2,2T3,2T2,3=0T3,1T2,2+4T3,2T3,3=50T1,2+4T1,3T2,3=175T2,2T1,3+4T2,3T3,3=100T3,2T2,3+4T3,3=150

so we have the system Ax=b, where

A=[+4111+4111+411+41111+41111+411+4111+4111+4],x=[T1,1T2,1T3,1T1,2T2,2T3,2T1,3T2,3T3,3],b=[7505075050175100150]

We can then solve the system of linear equations.

Implementation#

In this approach, we use numpy.linalg.solve() to solve the linear system obtained from simplifying the PDE.

import numpy as np
import matplotlib.pyplot as plt
# create the (sparse) matrix
A_size = 9
A = np.zeros((A_size, A_size))
for i in range(A_size):
    A[i, i] = 4

band_num = 4-1
for i in range(A_size-band_num):
    A[3+i, i] = -1
for i in range(A_size-band_num):
    A[i, 3+i] = -1

band_num = 2-1
for i in range(A_size-band_num):
    A[band_num+i, i] = -1
for i in range(A_size-band_num):
    A[i, band_num+i] = -1
    
for i in range(2, A_size-band_num, 3):
    A[band_num+i, i] = 0
for i in range(2, A_size-band_num, 3):
    A[i, band_num+i] = 0
A
array([[ 4., -1.,  0., -1.,  0.,  0.,  0.,  0.,  0.],
       [-1.,  4., -1.,  0., -1.,  0.,  0.,  0.,  0.],
       [ 0., -1.,  4.,  0.,  0., -1.,  0.,  0.,  0.],
       [-1.,  0.,  0.,  4., -1.,  0., -1.,  0.,  0.],
       [ 0., -1.,  0., -1.,  4., -1.,  0., -1.,  0.],
       [ 0.,  0., -1.,  0., -1.,  4.,  0.,  0., -1.],
       [ 0.,  0.,  0., -1.,  0.,  0.,  4., -1.,  0.],
       [ 0.,  0.,  0.,  0., -1.,  0., -1.,  4., -1.],
       [ 0.,  0.,  0.,  0.,  0., -1.,  0., -1.,  4.]])
b = np.array([75, 0, 50, 75, 0, 50, 175, 100, 150])
temperatures = np.linalg.solve(A, b)
temperatures
array([42.85714286, 33.25892857, 33.92857143, 63.16964286, 56.25      ,
       52.45535714, 78.57142857, 76.11607143, 69.64285714])
row = 3
col = 3
T_profile = temperatures.reshape(row, col)
for i in np.arange(6, -1, -3):
    print('{:.2f} | {:.2f} | {:.2f}'.format(*temperatures[i:i+3]))
78.57 | 76.12 | 69.64
63.17 | 56.25 | 52.46
42.86 | 33.26 | 33.93

Plotting annotated heatmap#

# plot settings
%config InlineBackend.figure_format = 'retina'
%matplotlib inline

plt.rcParams.update({
    'font.family': 'Arial',  # Times New Roman, Calibri
    'font.weight': 'normal',
    'mathtext.fontset': 'cm',
    'font.size': 18,
    
    'lines.linewidth': 2,
    
    'axes.linewidth': 2,
    'axes.spines.top': False,
    'axes.spines.right': False,
    'axes.titleweight': 'bold',
    'axes.titlesize': 18,
    'axes.labelweight': 'bold',
    
    'xtick.major.size': 8,
    'xtick.major.width': 2,
    'ytick.major.size': 8,
    'ytick.major.width': 2,
    
    'figure.dpi': 80,
    
    'legend.framealpha': 1, 
    'legend.edgecolor': 'black',
    'legend.fancybox': False,
    'legend.fontsize': 14
})
import seaborn as sns
T_heatmap = sns.heatmap(T_profile, square=True, cbar=True,
                        annot=True, fmt=".1f", cmap='Reds',
                        cbar_kws={'label': '$T \ [^\circ C]$', 
                                  'format': '%i', 
                                  'ticks': np.linspace(temperatures.min(), temperatures.max(), 5)})
T_heatmap.set_title('Temperature of thin slab')
T_heatmap.invert_yaxis()
../../_images/85b00d4bfa00903acf4d4dd0397eb104813356858597b4f0837d1bb5c012e52f.png