0% found this document useful (0 votes)
12 views34 pages

assign 02 fizza (1)

Uploaded by

fizzak5155
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
12 views34 pages

assign 02 fizza (1)

Uploaded by

fizzak5155
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 34

Computational Fluid Dynamics (CHE-481)

Grading
Obtained Marks:
Total Marks:

Assignment no. 02

Submitted to Dr. Muhammad Nadeem


Submitted by Fizza Khalid
Registration no. 11-3-1-010-2021
Date of submission 17-12-2024

Department of Chemical Engineering


Pakistan Institute of Engineering and Applied Sciences
P. O. Nilore, Islamabad, Pakistan
0
Table of Contents
List of Figures..................................................................................................................................3

Abstract............................................................................................................................................4

Introduction......................................................................................................................................5

1. Problem description.............................................................................................................5

2. Theory..................................................................................................................................6

2.1. Finite volume method..................................................................................................6

2.2. Central difference discretization..................................................................................6

2.3. Gauss-Seidel iterative scheme.....................................................................................6

2.4. TDMA line-by-line technique.....................................................................................7

Methodology....................................................................................................................................7

1. Governing Equation and Discretization...............................................................................7

2. Boundary Conditions...........................................................................................................7

3. Solution Techniques................................................................................................................8

4. Grid Specifications..................................................................................................................8

4. Implementation........................................................................................................................8

Results and Discussion....................................................................................................................9

1. Results..................................................................................................................................9

2. Discussion..........................................................................................................................11

Conclusion.....................................................................................................................................12

Appendix........................................................................................................................................13

1. Python Codes:....................................................................................................................13

1.1. Gauss-Seidel codes:.......................................................................................................13

1.2. TDMA:...........................................................................................................................21

1
1.3. Non-uniform grid:...........................................................................................................28

References......................................................................................................................................32

2
List of Figures
Figure 1............................................................................................................................................5
Figure 2. Non- uniform grid............................................................................................................6
Figure 3. Gauss-seidel with uniform grid without mixed boundary condition with Δx=Δy=0.1 m 9
Figure 4. Gauss-seidel with uniform grid with mixed boundary condition and Δx = Δy = 0.05 m
.........................................................................................................................................................9
Figure 5. TDMA with uniform grid with mixed boundary condition and Δx = Δy = 0.1 m.........10
Figure 6.TDMA with uniform grid with mixed boundary condition and Δx = Δy = 0.05 m........10
Figure 7. Results with Non-uniform grid......................................................................................11

3
Abstract
This report presents a computational approach to solve the steady-state
temperature distribution of a two-dimensional plate using the finite volume
method (FVM). The problem incorporates central difference discretization
and employs iterative techniques such as the Gauss-Seidel method and the
Tri-Diagonal Matrix Algorithm (TDMA) for numerical solutions. Boundary
conditions include a steady heat flux on the west side, insulation on other
sides, and a mixed boundary condition replacing one insulated side. Various
grid configurations, including uniform and non-uniform grids, were analyzed
to assess their influence on the accuracy and convergence of temperature
distribution results. The study highlights the computational efficiency and
accuracy of these numerical techniques for heat transfer simulations.

Keywords: steady-state temperature distribution; finite volume method;


Gauss-Seidel method; Tri-Diagonal Matrix Algorithm

4
Introduction

1. Problem description
In this assignment Python code is established to find steady state temperature distribution of a
two-dimensional plate of thickness 1 cm is shown in figure 1 by finite volume method using
central difference discretization scheme by incorporating the functions of
 Gauss-Seidel iterative scheme and
 TDMA line-by-line technique

Figure 1

By using following boundary conditions:


 The west boundary receives a steady heat flux of 500 kW/m2 and the south and east
boundaries are insulated. The north boundary is maintained at a temperature of 100°C
 Replacing one of the insulted boundaries with mixed boundary condition with h = 200
W/(m².°C), and T∞ = 20°C.

5
With the following specifications:
 Uniform grid with Δx = Δy = 0.1 m
 Uniform grid with Δx = Δy = 0.05 m
 A non-uniform grid as shown in figure with
x = (0.000 0.033 0.084 0.150 0.216 0.267 0.300)
y = (0.000 0.031 0.075 0.133 0.200 0.267 0.325 0.369 0.400)

The thermal conductivity of the plate material is k = 1000 W/m.K.


Figure 2. Non- uniform grid

2. Theory

2.1. Finite volume method


The Finite Volume Method (FVM) in CFD is a numerical technique used to solve partial
differential equations governing fluid flow and heat transfer. It involves dividing the
computational domain into small control volumes and applying the conservation laws (mass,
momentum, energy, etc.) to each control volume. The method integrates these equations over
each control volume, ensuring fluxes across the boundaries are conserved, leading to robust
solutions for complex geometries and boundary conditions.

2.2. Central difference discretization


The Central Difference Discretization Scheme is a numerical method used to discretize partial
differential equations. It calculates the derivative at a point by averaging the values at
neighboring points, resulting in a second-order accurate representation. While it is simple and
accurate for uniform grids, it can lead to numerical instability for convection-dominated flows
due to its lack of inherent damping of oscillations

2.3. Gauss-Seidel iterative scheme


The Gauss-Seidel Iterative Scheme is a numerical method used to solve linear systems of
equations, often arising from the discretization of governing equations. It updates each variable
sequentially using the most recent values, ensuring faster convergence compared to the Jacobi
method. Although efficient for well-conditioned systems, its convergence can be slow for large
or ill-conditioned problems, often requiring preconditioning or acceleration techniques.

6
2.4. TDMA line-by-line technique
The TDMA technique is an efficient method for solving systems of linear equations with a tri-
diagonal coefficient matrix, typically arising from finite difference discretization. In the line-by-
line approach, the domain is swept row-by-row or column-by-column, treating each line as a
one-dimensional problem. The TDMA, also known as the Thomas algorithm, solves these
efficiently with minimal computational cost, making it ideal for structured grids in two-
dimensional problems.

Methodology
The problem involves determining the steady-state temperature distribution of a two-dimensional
plate using finite volume methods (FVM) under the specified boundary conditions and grid
configurations. The methodology is structured as follows:

1. Governing Equation and Discretization


The steady-state heat conduction equation is used as the governing equation. For a two-
dimensional plate, it is expressed as:

2 2
∂T ∂ T
2
+ 2 =0
∂x ∂ y

This equation is discretized using the finite volume method (FVM) with the central difference
scheme for spatial derivatives. The discretization ensures energy conservation over control
volumes and provides a set of linear algebraic equations representing the temperature at grid
points .

2. Boundary Conditions
The boundary conditions are applied as follows:
1. West boundary: Steady heat flux of 500 kW/m2
2. North boundary: Fixed temperature of 100 0C
3. South and east boundaries: Initially insulated (no heat flux). For the second case, one
boundary is replaced by a mixed boundary condition :

7
∂T
−k =h (T −T ∞)
∂y

where h=200 W/m2 and T∞=20 0C.

3. Solution Techniques
Two numerical techniques are employed to solve the discretized equations:
1. Gauss-Seidel Iterative Scheme: A point-by-point iterative solver, suitable for handling
large, sparse systems of linear equations, ensuring stability and convergence for
structured grids.
2. Tri-Diagonal Matrix Algorithm (TDMA): A line-by-line technique that reduces the 2D
problem into a series of 1D problems, providing faster convergence and computational
efficiency.

4. Grid Specifications
Three grid configurations are used:
1. Uniform grid with Δx=Δy=0.1 m
2. Uniform grid with Δx=Δy=0.05 m
3. Non-uniform grid with given coordinates.

4. Implementation
The numerical implementation involves defining the grids, initializing temperature fields,
applying boundary conditions, and iterating using the specified solution techniques until
convergence. The results are analyzed to assess the temperature distribution for different grid
configurations and boundary condition scenarios.

Results and Discussion

8
1. Results
a)

Figure 3. Gauss-seidel with uniform grid without mixed boundary condition with Δx=Δy=0.1 m

b)

9
orm grid with mixed boundary condition and Δx = Δy = 0.05 m

c)

10
Figure 5. TDMA with uniform grid with mixed boundary condition and Δx = Δy = 0.1 m

d)

Figure 6.TDMA with uniform grid with mixed boundary condition and Δx = Δy = 0.05 m

11
e)

Figure 7. Results with Non-uniform grid

12
2. Discussion
The numerical results obtained from the Gauss-Seidel and TDMA methods under different grid
configurations provide insights into the behaviour of steady-state heat conduction. Key
observations include:
1. Uniform Grids: For uniform grids with Δx = Δy = 0.1 m and Δx = Δy = 0.05 m, both
methods demonstrated consistent convergence and accurate temperature distributions.
However, a finer grid (Δx = Δy = 0.05 m) yielded higher resolution results, capturing
thermal gradients more precisely.
2. Non-Uniform Grids: Non-uniform grids introduced flexibility in spatial resolution,
allowing focused accuracy in regions of interest. The results showed that non-uniform
grids could provide comparable accuracy with reduced computational effort, though they
required careful implementation to ensure stability.
3. Boundary Conditions: The mixed boundary condition significantly influenced
temperature distributions, emphasizing the importance of boundary specification in heat
transfer problems. The results aligned well with theoretical expectations for both
insulated and mixed boundary conditions.
4. Comparison of Methods: TDMA was computationally more efficient than the Gauss-
Seidel method due to its ability to solve tridiagonal systems directly, reducing the number
of iterations required for convergence. However, Gauss-Seidel remained robust and
simpler to implement for general scenarios.
Sources of Error and Limitations: Minor discrepancies between theoretical and numerical
results may stem from discretization errors, especially at coarser grids, and the assumption of
steady-state conditions. Future studies could include transient analyses and higher-order
discretization schemes for improved accuracy

13
Conclusion
The study successfully demonstrated the application of finite volume methods and iterative
solvers for modeling heat conduction in a two-dimensional plate. Key findings include the
influence of grid resolution on accuracy, the efficacy of TDMA for structured grids, and the
impact of boundary conditions on temperature profiles. These insights are critical for optimizing
computational resources and improving the accuracy of thermal simulations in engineering
applications. Future work may extend this methodology to three-dimensional and transient heat
transfer problems to address more complex real-world scenarios.

Appendix
1. Python Codes:
1.1. Gauss-Seidel codes:
a)
2. # Fizza Khalid
3. # Assignment 02 _ Part 2
4. # (delx=del y=0.05) guass seidal
5. import numpy as np
6. import matplotlib.pyplot as plt
7.
8. Lx = 0.3 # Width of the plate, m
9. Ly = 0.4 # Height of the plate, m
10. Lz = 0.01 # Thickness of the plate,m
11. k = 1000.0 # Thermal conductivity, W/m.K
12. h=200 # heat transfer coefficent at right (W/m2 C)
13. T_amb=20 # ambiant temperature (C)
14.
15. # Boundary Conditions
16. Tn = 100.0 # Fixed temperature at North boundary, deg C
17. qw = 500e+3 # Given heat flux at West boundary, w/m2
18. # Grid size
19. dx = 0.05

14
20. dy = dx
21. Nx = round(Lx/dx)
22. Ny = round(Ly/dy)
23. Area = Lz * dy # m2
24. # Define R_eq
25. R_eq=h/(1+(h*dx)/(2*k))
26.
27. A = np.zeros((Nx * Ny, Nx * Ny))
28. b = np.zeros(Nx * Ny)
29. T_b = np.zeros(Ny)
30. def Gauss_Seidel(a,b):
31. n = len(b)
32. tol = 1e-5
33. x = np.zeros(n)
34. k = 0
35. eval = np.ones(n)
36.
37. while np.max(eval) > tol:
38. x_old = np.copy(x)
39. for i in range(n):
40. sigma = 0
41. for j in range(i):
42. sigma += A[i, j] * x[j]
43. for j in range(i + 1, n):
44. sigma += A[i, j] * x_old[j]
45. x[i] = (1 / A[i, i]) * (b[i] - sigma)
46.
47. k += 1
48. eval = np.abs(x_old - x)
49.
50. print(f"Solution converged in {k} iterations by Gauss-
Seidel Method")
51. return x
52.
53. # Neighbouring Coefficients
54. aE = k * Area / dx
55. aW = k * Area / dx
56. aN = k * Area / dy
57. aS = k * Area / dy
58.
59. # Contributions from various sources
60. bW = qw * Area # Specified heat flux at left
(west)
61. bE = R_eq*Lz*dy*T_amb; # Mixed BC at
right (east)

15
62. bN = 2 * k * Area / dy * Tn # Constant Temp term at top
63. bS = 0. # Insulated
64. SpN = -2 * k * Area / dy
65. SpE = -R_eq*dy*Lz
66.
67. # For South-West (bottom-left) Corner
68. A[0, 0] = aE + aN
69. A[0, 1] = -aN
70. A[0, Ny] = -aE
71. b[0] = bW + bS
72.
73. # For West (left) Boundary Nodes
74. for j in range(1, Ny - 1):
75. A[j, j - 1] = -aS
76. A[j, j + 1] = -aN
77. A[j, j + Ny] = -aE
78. A[j, j] = aE + aN + aS
79. b[j] = bW
80.
81. # For North-West (top-left) Corner
82. idx = Ny - 1
83. A[idx, idx - 1] = -aS
84. A[idx, idx + Ny] = -aE
85. A[idx, idx] = aE + aS - SpN
86. b[idx] = bW + bN
87.
88. # For Interior Nodes
89. for i in range(1, Nx - 1):
90. for j in range(1, Ny-1 ):
91. idx = i * Ny + j
92. A[idx, idx - Ny] = -aW
93. A[idx, idx - 1] = -aS
94. A[idx, idx] = aW + aE + aN + aS
95. A[idx, idx + 1] = -aN
96. A[idx, idx + Ny] = -aE
97.
98. # For South-East (bottom-right) Corner
99. idx = Ny * (Nx - 1)
100. A[idx, idx - Ny] = -aW
101. A[idx, idx + 1] = -aN
102. A[idx, idx] = aW + aN - SpE
103. b[idx] = bE + bS
104.
105. # For East Boundary (right) Nodes
106. for j in range(1, Ny - 1):

16
107. idx = Ny * (Nx - 1) + j
108. A[idx, idx - Ny] = -aW
109. A[idx, idx - 1] = -aS
110. A[idx, idx + 1] = -aN
111. A[idx, idx] = aW + aN + aS - SpE
112. b[idx] = bE
113.
114. # For North-East (top-right) Corner
115. idx = Nx * Ny - 1
116. A[idx, idx - Ny] = -aW
117. A[idx, idx - 1] = -aS
118. A[idx, idx] = aS + aW - SpN - SpE
119. b[idx] = bN + bE
120.
121. # For South Boundary (bottom) Nodes
122. for i in range(1, Nx - 1):
123. idx = Ny * i
124. A[idx, idx - Ny] = -aW
125. A[idx, idx] = aW + aE + aN
126. A[idx, idx + 1] = -aN
127. A[idx, idx + Ny] = -aE
128. b[idx] = bS
129.
130. # For North Boundary (top) Nodes
131. for i in range(1, Nx - 1):
132. idx = Ny * (i + 1) - 1
133. A[idx, idx - Ny] = -aW
134. A[idx, idx - 1] = -aS
135. A[idx, idx] = aW + aE + aS - SpN
136. A[idx, idx + Ny] = -aE
137. b[idx] = bN
138.
139. # Solution of descritized equations
140. # T = np.linalg.solve(A, b)
141. T = Gauss_Seidel(A,b)
142. T2 = np.reshape(T, (Nx, Ny)).T
143.
144. # Postprocessing for contour plot
145. x = np.linspace(0, Lx, Nx)
146. y = np.linspace(0, Ly, Ny)
147. X, Y = np.meshgrid(x, y)
148.

149. # Create a filled contour plot

17
150. plt.figure(1)
151. contour_plot = plt.contourf(X, Y, T2, levels=10, cmap='Reds')
# viridis, cividis Reds, cool
152. plt.colorbar()
153. # contour_lines = plt.contour(X, Y, T2,
levels=contour_plot.levels, colors='k', linewidths=0.5)
154. # plt.axis('scaled')
155. plt.axis('image')
156. plt.title('Temperature distribution (K)')
157. plt.xlabel('Width of plate (m)')
158. plt.ylabel('Height of plate (m)')
159.
160. plt.figure(2)
161. plt.imshow(T2, origin='lower', extent=[0, Lx, 0, Ly],
cmap='Reds')
162. plt.colorbar()
163. plt.xlabel('Width of plate (m)')
164. plt.ylabel('Height of plate (m)')
165. plt.show()
166.
167. # Calculation for T_b (Boundary temperature)
168. for j in range(Ny):
169. idx = Ny * (Nx - 1) + j
170. T_b[j] = ((h * T_amb) + (2 * k * T[idx]) / dx) / (h + (2 *
k / dx))
171. print("T_b corresponding to point",idx+1,":", T_b[j])
172.

b)
173. # Fizza Khalid
174. # Assignment 02 _ Part 2
175. # (delx=del y=0.05) guass seidal
176. import numpy as np
177. import matplotlib.pyplot as plt
178.
179. Lx = 0.3 # Width of the plate, m
180. Ly = 0.4 # Height of the plate, m
181. Lz = 0.01 # Thickness of the plate,m
182. k = 1000.0 # Thermal conductivity, W/m.K
183. h=200 # heat transfer coefficent at right (W/m2 C)
184. T_amb=20 # ambiant temperature (C)
185.
186. # Boundary Conditions

18
187. Tn = 100.0 # Fixed temperature at North boundary, deg C
188. qw = 500e+3 # Given heat flux at West boundary, w/m2
189. # Grid size
190. dx = 0.1
191. dy = dx
192. Nx = round(Lx/dx)
193. Ny = round(Ly/dy)
194. Area = Lz * dy # m2
195. # Define R_eq
196. R_eq=h/(1+(h*dx)/(2*k))
197.
198. A = np.zeros((Nx * Ny, Nx * Ny))
199. b = np.zeros(Nx * Ny)
200. T_b = np.zeros(Ny)
201. def Gauss_Seidel(a,b):
202. n = len(b)
203. tol = 1e-5
204. x = np.zeros(n)
205. k = 0
206. eval = np.ones(n)
207.
208. while np.max(eval) > tol:
209. x_old = np.copy(x)
210. for i in range(n):
211. sigma = 0
212. for j in range(i):
213. sigma += A[i, j] * x[j]
214. for j in range(i + 1, n):
215. sigma += A[i, j] * x_old[j]
216. x[i] = (1 / A[i, i]) * (b[i] - sigma)
217.
218. k += 1
219. eval = np.abs(x_old - x)
220.
221. print(f"Solution converged in {k} iterations by Gauss-
Seidel Method")
222. return x
223.
224. # Neighbouring Coefficients
225. aE = k * Area / dx
226. aW = k * Area / dx
227. aN = k * Area / dy
228. aS = k * Area / dy
229.
230. # Contributions from various sources

19
231. bW = qw * Area # Specified heat flux at left
(west)
232. bE = R_eq*Lz*dy*T_amb; # Mixed BC at
right (east)
233. bN = 2 * k * Area / dy * Tn # Constant Temp term at top
234. bS = 0. # Insulated
235. SpN = -2 * k * Area / dy
236. SpE = -R_eq*dy*Lz
237.
238. # For South-West (bottom-left) Corner
239. A[0, 0] = aE + aN
240. A[0, 1] = -aN
241. A[0, Ny] = -aE
242. b[0] = bW + bS
243.
244. # For West (left) Boundary Nodes
245. for j in range(1, Ny - 1):
246. A[j, j - 1] = -aS
247. A[j, j + 1] = -aN
248. A[j, j + Ny] = -aE
249. A[j, j] = aE + aN + aS
250. b[j] = bW
251.
252. # For North-West (top-left) Corner
253. idx = Ny - 1
254. A[idx, idx - 1] = -aS
255. A[idx, idx + Ny] = -aE
256. A[idx, idx] = aE + aS - SpN
257. b[idx] = bW + bN
258.
259. # For Interior Nodes
260. for i in range(1, Nx - 1):
261. for j in range(1, Ny-1 ):
262. idx = i * Ny + j
263. A[idx, idx - Ny] = -aW
264. A[idx, idx - 1] = -aS
265. A[idx, idx] = aW + aE + aN + aS
266. A[idx, idx + 1] = -aN
267. A[idx, idx + Ny] = -aE
268.
269. # For South-East (bottom-right) Corner
270. idx = Ny * (Nx - 1)
271. A[idx, idx - Ny] = -aW
272. A[idx, idx + 1] = -aN
273. A[idx, idx] = aW + aN - SpE

20
274. b[idx] = bE + bS
275.
276. # For East Boundary (right) Nodes
277. for j in range(1, Ny - 1):
278. idx = Ny * (Nx - 1) + j
279. A[idx, idx - Ny] = -aW
280. A[idx, idx - 1] = -aS
281. A[idx, idx + 1] = -aN
282. A[idx, idx] = aW + aN + aS - SpE
283. b[idx] = bE
284.
285. # For North-East (top-right) Corner
286. idx = Nx * Ny - 1
287. A[idx, idx - Ny] = -aW
288. A[idx, idx - 1] = -aS
289. A[idx, idx] = aS + aW - SpN - SpE
290. b[idx] = bN + bE
291.
292. # For South Boundary (bottom) Nodes
293. for i in range(1, Nx - 1):
294. idx = Ny * i
295. A[idx, idx - Ny] = -aW
296. A[idx, idx] = aW + aE + aN
297. A[idx, idx + 1] = -aN
298. A[idx, idx + Ny] = -aE
299. b[idx] = bS
300.
301. # For North Boundary (top) Nodes
302. for i in range(1, Nx - 1):
303. idx = Ny * (i + 1) - 1
304. A[idx, idx - Ny] = -aW
305. A[idx, idx - 1] = -aS
306. A[idx, idx] = aW + aE + aS - SpN
307. A[idx, idx + Ny] = -aE
308. b[idx] = bN
309.
310. # Solution of descritized equations
311. # T = np.linalg.solve(A, b)
312. T = Gauss_Seidel(A,b)
313. T2 = np.reshape(T, (Nx, Ny)).T
314.
315. # Postprocessing for contour plot
316. x = np.linspace(0, Lx, Nx)
317. y = np.linspace(0, Ly, Ny)
318. X, Y = np.meshgrid(x, y)

21
319.

320. # Create a filled contour plot


321. plt.figure(1)
322. contour_plot = plt.contourf(X, Y, T2, levels=10, cmap='Reds')
# viridis, cividis Reds, cool
323. plt.colorbar()
324. # contour_lines = plt.contour(X, Y, T2,
levels=contour_plot.levels, colors='k', linewidths=0.5)
325. # plt.axis('scaled')
326. plt.axis('image')
327. plt.title('Temperature distribution (K)')
328. plt.xlabel('Width of plate (m)')
329. plt.ylabel('Height of plate (m)')
330.
331. plt.figure(2)
332. plt.imshow(T2, origin='lower', extent=[0, Lx, 0, Ly],
cmap='Reds')
333. plt.colorbar()
334. plt.xlabel('Width of plate (m)')
335. plt.ylabel('Height of plate (m)')
336. plt.show()
337.
338. # Calculation for T_b (Boundary temperature)
339. for j in range(Ny):
340. idx = Ny * (Nx - 1) + j
341. T_b[j] = ((h * T_amb) + (2 * k * T[idx]) / dx) / (h + (2 *
k / dx))
342. print("T_b corresponding to point",idx+1,":", T_b[j])

1.2. TDMA:
c)
# Fizza Khalid
# Assignment 02 _ Part 1
# (delx=del y=0.1) TDMA

import numpy as np
import matplotlib.pyplot as plt

# Parameters
Lx = 0.3 # Width of the plate, m

22
Ly = 0.4 # Height of the plate, m
Lz = 0.01 # Thickness of the plate, m
k = 1000.0 # Thermal conductivity, W/m.K
h = 200.0 # Heat transfer coefficient, W/m²·K
T_inf = 20.0 # Ambient temperature, °C

# Boundary Conditions
Tn = 100.0 # Fixed temperature at North boundary, °C
qw = 500e+3 # Given heat flux at West boundary, W/m²

# Discretization
Nx = 3 # Number of nodes in x-direction
Ny = 4 # Number of nodes in y-direction
dx = Lx / Nx
dy = Ly / Ny

# Area for heat transfer


Area = Lz * dy

# Equivalent thermal resistance at the East boundary (mixed boundary


condition)
R_eq = h / (1 + (h * dx) / (2 * k))

# Initialize the temperature field


T = np.zeros((Ny, Nx))

# Initialize boundary coefficients


aN = k * Area / dy
aS = k * Area / dy
aE = k * Area / dx
aW = k * Area / dx

# Source terms for the top and bottom boundary


bN = 2 * k * Area / dy # Constant Temp at the top
SpN = -2 * k * Area / dy # Penalty term for North boundary

# Initialize matrices for TDMA


A = np.zeros((Ny, Ny))
b = np.zeros(Ny)

# TDMA solver function for solving tridiagonal systems


def TDMA(a, b):
n = len(b)
P = np.zeros(n)

23
Q = np.zeros(n)
x = np.zeros(n)

# Forward elimination
P[0] = -a[0, 1] / a[0, 0]
Q[0] = b[0] / a[0, 0]

for i in range(1, n):


denominator = a[i, i] + a[i, i - 1] * P[i - 1]
if i < n - 1:
P[i] = -a[i, i + 1] / denominator
Q[i] = (b[i] - a[i, i - 1] * Q[i - 1]) / denominator

# Back substitution
x[-1] = Q[-1]
for i in range(n - 2, -1, -1):
x[i] = P[i] * x[i + 1] + Q[i]

return x

# Iteration loop for TDMA method


tol = 1e-5
error = 1.0
iterations = 0

while error > tol:


T_old = np.copy(T)

# Loop over each column in the x-direction


for i in range(Nx):
if i == 0: # West boundary (heat flux condition)
TE = T[:, i + 1] # East neighbor
aE = k * Area / dx
aW = 0.0
bw = qw * Area
TW = np.zeros(Ny) # No West neighbor (boundary condition)
elif i == Nx - 1: # East boundary (convection)
TE = np.zeros(Ny) # No East neighbor (boundary condition)
TW = T[:, i - 1] # West neighbor
aW = k * Area / dx
aE = R_eq * dy * Lz # Use equivalent resistance at East
boundary
bw = R_eq * dy * Lz * T_inf
else: # Interior nodes

24
TE = T[:, i + 1]
TW = T[:, i - 1]
aW = k * Area / dx
aE = k * Area / dx
bw = 0.0

# Bottom node (j=0)


A[0, 0] = aW + aE + aN
A[0, 1] = -aN
b[0] = aW * TW[0] + aE * TE[0] + bw

# Interior nodes (j=1 to Ny-2)


for j in range(1, Ny - 1):
A[j, j - 1] = -aS
A[j, j] = aW + aE + aS + aN
A[j, j + 1] = -aN
b[j] = aW * TW[j] + aE * TE[j] + bw

# Top node (j=Ny-1)


A[Ny - 1, Ny - 2] = -aS
A[Ny - 1, Ny - 1] = aW + aE + aS - SpN
b[Ny - 1] = aW * TW[Ny - 1] + aE * TE[Ny - 1] + bw + bN * Tn

# Solve using TDMA


T[:, i] = TDMA(A, b)

iterations += 1
error = np.max(np.abs(T - T_old))

print(f'Solution converged in {iterations} iterations using TDMA.')

# Plotting the result


x = np.linspace(0, Lx, Nx)
y = np.linspace(0, Ly, Ny)
X, Y = np.meshgrid(x, y)

# Postprocessing: East boundary temperatures


print('East Boundary Temperatures:')
for j in range(Ny):
idx = Ny * (Nx - 1) + j
T_east = T[j, Nx - 1] # Temperature at East boundary
T_b_value = (h * T_inf + 2 * k * T_east / dx) / (h + 2 * k / dx)
print(f'T_b at node {idx+1} is : {T_b_value:.2f} °C')

25
# Contour plot
plt.figure(1)
plt.contourf(X, Y, T, levels=10, cmap='Reds')
plt.colorbar()
plt.title('Temperature Distribution (°C)')
plt.xlabel('Width (m)')
plt.ylabel('Height (m)')

# Display temperature as an image


plt.figure(2)
plt.imshow(T, origin='lower', extent=[0, Lx, 0, Ly], cmap='Reds')
plt.colorbar()
plt.title('Temperature Distribution (°C)')
plt.xlabel('Width (m)')
plt.ylabel('Height (m)')

plt.show()

d)
# Fizza Khalid
# Assignment 02 _ Part 1
# (delx=del y=0.05) TDMA

import numpy as np
import matplotlib.pyplot as plt

# Parameters
Lx = 0.3 # Width of the plate, m
Ly = 0.4 # Height of the plate, m
Lz = 0.01 # Thickness of the plate, m
k = 1000.0 # Thermal conductivity, W/m.K
h = 200.0 # Heat transfer coefficient, W/m²·K
T_inf = 20.0 # Ambient temperature, °C

# Boundary Conditions
Tn = 100.0 # Fixed temperature at North boundary, °C
qw = 500e+3 # Given heat flux at West boundary, W/m²

# Discretization
Nx = 6 # Number of nodes in x-direction
Ny = 8 # Number of nodes in y-direction
dx = Lx / Nx
dy = Ly / Ny

26
# Area for heat transfer
Area = Lz * dy

# Equivalent thermal resistance at the East boundary (mixed boundary


condition)
R_eq = h / (1 + (h * dx) / (2 * k))

# Initialize the temperature field


T = np.zeros((Ny, Nx))

# Initialize boundary coefficients


aN = k * Area / dy
aS = k * Area / dy
aE = k * Area / dx
aW = k * Area / dx

# Source terms for the top and bottom boundary


bN = 2 * k * Area / dy # Constant Temp at the top
SpN = -2 * k * Area / dy # Penalty term for North boundary

# Initialize matrices for TDMA


A = np.zeros((Ny, Ny))
b = np.zeros(Ny)

# TDMA solver function for solving tridiagonal systems


def TDMA(a, b):
n = len(b)
P = np.zeros(n)
Q = np.zeros(n)
x = np.zeros(n)

# Forward elimination
P[0] = -a[0, 1] / a[0, 0]
Q[0] = b[0] / a[0, 0]

for i in range(1, n):


denominator = a[i, i] + a[i, i - 1] * P[i - 1]
if i < n - 1:
P[i] = -a[i, i + 1] / denominator
Q[i] = (b[i] - a[i, i - 1] * Q[i - 1]) / denominator

# Back substitution
x[-1] = Q[-1]

27
for i in range(n - 2, -1, -1):
x[i] = P[i] * x[i + 1] + Q[i]

return x

# Iteration loop for TDMA method


tol = 1e-5
error = 1.0
iterations = 0

while error > tol:


T_old = np.copy(T)

# Loop over each column in the x-direction


for i in range(Nx):
if i == 0: # West boundary (heat flux condition)
TE = T[:, i + 1] # East neighbor
aE = k * Area / dx
aW = 0.0
bw = qw * Area
TW = np.zeros(Ny) # No West neighbor (boundary condition)
elif i == Nx - 1: # East boundary (convection)
TE = np.zeros(Ny) # No East neighbor (boundary condition)
TW = T[:, i - 1] # West neighbor
aW = k * Area / dx
aE = R_eq * dy * Lz # Use equivalent resistance at East
boundary
bw = R_eq * dy * Lz * T_inf
else: # Interior nodes
TE = T[:, i + 1]
TW = T[:, i - 1]
aW = k * Area / dx
aE = k * Area / dx
bw = 0.0

# Bottom node (j=0)


A[0, 0] = aW + aE + aN
A[0, 1] = -aN
b[0] = aW * TW[0] + aE * TE[0] + bw

# Interior nodes (j=1 to Ny-2)


for j in range(1, Ny - 1):
A[j, j - 1] = -aS
A[j, j] = aW + aE + aS + aN

28
A[j, j + 1] = -aN
b[j] = aW * TW[j] + aE * TE[j] + bw

# Top node (j=Ny-1)


A[Ny - 1, Ny - 2] = -aS
A[Ny - 1, Ny - 1] = aW + aE + aS - SpN
b[Ny - 1] = aW * TW[Ny - 1] + aE * TE[Ny - 1] + bw + bN * Tn

# Solve using TDMA


T[:, i] = TDMA(A, b)

iterations += 1
error = np.max(np.abs(T - T_old))

print(f'Solution converged in {iterations} iterations using TDMA.')

# Plotting the result


x = np.linspace(0, Lx, Nx)
y = np.linspace(0, Ly, Ny)
X, Y = np.meshgrid(x, y)

# Postprocessing: East boundary temperatures


print('East Boundary Temperatures:')
for j in range(Ny):
idx = Ny * (Nx - 1) + j
T_east = T[j, Nx - 1] # Temperature at East boundary
T_b_value = (h * T_inf + 2 * k * T_east / dx) / (h + 2 * k / dx)
print(f'T_b at node {idx+1} is : {T_b_value:.2f} °C')

# Contour plot
plt.figure(1)
plt.contourf(X, Y, T, levels=10, cmap='Reds')
plt.colorbar()
plt.title('Temperature Distribution (°C)')
plt.xlabel('Width (m)')
plt.ylabel('Height (m)')

# Display temperature as an image


plt.figure(2)
plt.imshow(T, origin='lower', extent=[0, Lx, 0, Ly], cmap='Reds')
plt.colorbar()
plt.title('Temperature Distribution (°C)')
plt.xlabel('Width (m)')
plt.ylabel('Height (m)')

29
plt.show()

1.3. Non-uniform grid:


e)
# Fizza Khalid
# Assignment 02 _ Part 2
# non uniform
import numpy as np
import matplotlib.pyplot as plt

# Parameters
Lx = 0.3 # Width of the plate, m
Ly = 0.4 # Height of the plate, m
Lz = 0.01 # Thickness of the plate, m
k = 1000.0 # Thermal conductivity, W/m.K
Tn = 100 # Fixed temperature at North boundary, deg C
q = 500e+3 # Given heat flux at West boundary, W/m^2

x = np.array([0, 0.033, 0.084, 0.15, 0.216, 0.267, 0.3])


y = np.array([0, 0.031, 0.075, 0.133, 0.2, 0.267, 0.325, 0.369, 0.4])
dx = np.array([0.033, 0.051, 0.066, 0.066, 0.051, 0.033])
dy = np.array([0.031, 0.044, 0.058, 0.067, 0.067, 0.058, 0.044, 0.031])

Nx = len(dx) # No. of nodes in x-direction


Ny = len(dy) # No. of nodes in y-direction

T = np.zeros((Nx, Ny))
A = np.zeros((Ny, Ny))
b = np.zeros((Ny, 1))
T_old = np.zeros((Nx, Ny))
eval = np.ones((Nx, Ny))
tol = 1e-5
m = 0

while np.max(np.abs(eval)) > tol:


for i in range(Nx):
for j in range(Ny):
if j == 0: # South boundary
aN = k * dx[i] * Lz / ((dy[j] / 2) + (dy[j + 1] / 2))
aS = 0

30
if i == 0: # West boundary
aW = 0
bW = dy[j] * Lz * q
else:
aW = k * dy[j] * Lz / ((dx[i] / 2) + (dx[i - 1] / 2))
bW = 0
if i != Nx - 1: # East
aE = k * dy[j] * Lz / ((dx[i] / 2) + (dx[i + 1] / 2))
bE = 0
else: # East boundary
aE = 0
bE = 0
aP = aN + aE + aW + aS
A[j, j] = aP
if j + 1 < Ny:
A[j, j + 1] = -aN
if i == 0:
b[j, 0] = bW + aE * T[i + 1, j]
elif i != 0 and i != Nx - 1:
b[j, 0] = aW * T[i - 1, j] + aE * T[i + 1, j]
elif i == Nx - 1:
b[j, 0] = aW * T[i - 1, j] + bE
elif j != 0 and j != Ny - 1: # Middle nodes
aN = k * dx[i] * Lz / ((dy[j] / 2) + (dy[j + 1] / 2))
aS = k * dx[i] * Lz / ((dy[j] / 2) + (dy[j - 1] / 2))
if i != 0:
aW = k * dy[j] * Lz / ((dx[i] / 2) + (dx[i - 1] / 2))
bW = 0
else: # West boundary
aW = 0
bW = dy[j] * Lz * q
if i != Nx - 1:
aE = k * dy[j] * Lz / ((dx[i] / 2) + (dx[i + 1] / 2))
else: # East boundary
aE = 0
bE = 0
aP = aN + aE + aW + aS
A[j, j] = aP
A[j, j - 1] = -aS
if j + 1 < Ny:
A[j, j + 1] = -aN
if i == 0:
b[j, 0] = bW + aE * T[i + 1, j]
elif i != 0 and i != Nx - 1:
b[j, 0] = aW * T[i - 1, j] + aE * T[i + 1, j]

31
elif i == Nx - 1:
b[j, 0] = aW * T[i - 1, j] + bE
elif j == Ny - 1: # North boundary
aN = k * dx[i] * Lz / (dy[j] / 2)
aS = k * dx[i] * Lz / ((dy[j] / 2) + (dy[j - 1] / 2))
if i == 0:
aW = 0
bW = dy[j] * Lz * q
else:
aW = k * dy[j] * Lz / ((dx[i] / 2) + (dx[i - 1] / 2))
if i == Nx - 1:
aE = 0
bE = 0
else:
aE = k * dy[j] * Lz / ((dx[i] / 2) + (dx[i + 1] / 2))
aP = aN + aE + aW + aS
A[j, j] = aP
A[j, j - 1] = -aS
if i == 0:
b[j, 0] = bW + aE * T[i + 1, j] + aN * Tn
elif i != 0 and i != Nx - 1:
b[j, 0] = aW * T[i - 1, j] + aE * T[i + 1, j] + aN *
Tn
elif i == Nx - 1:
b[j, 0] = aW * T[i - 1, j] + bE + aN * Tn
T[i, :] = np.linalg.solve(A, b).flatten()

eval = T - T_old
T_old = np.copy(T)
m += 1

# Plot temperature distribution using contour


X, Y = np.meshgrid(x[0:Nx], y[0:Ny])
print((f"Solution converged in {m} iterations"))
# Contour plot
plt.figure()
plt.contourf(X.T, Y.T, T, 20,levels=10, cmap='Reds') # Transpose arrays
for correct orientation
plt.colorbar()
plt.title('Temperature Distribution (Contour)')
plt.xlabel('X (m)')
plt.ylabel('Y (m)')

# Imagesc plot
plt.figure()

32
plt.imshow(T.T, extent=[0, Lx, 0, Ly], origin='lower', cmap="Reds") #
Transpose and adjust axes
plt.colorbar()
plt.title('Temperature Distribution (Imagesc)')
plt.xlabel('X (m)')
plt.ylabel('Y (m)')

plt.show()

References

[1] H. K. Versteeg and W. Malalasekera, An Introduction to Computational Fluid Dynamics Second


Edition, n.d.

33

You might also like