이 글은
2023.02.09 - [수학의 재미/아름다운 이론] - 2차원 Heat Equation의 풀이 #2 : OSM 예제풀이
2차원 Heat Equation의 풀이 #2 : OSM 예제풀이
이 글은 2023.02.06 - [수학의 재미/아름다운 이론] - 2차원 Heat Equation의 풀이 #1 : Operator Splitting Method(OSM) 2차원 Heat Equation의 풀이 #1 : Operator Splitting Method(OSM) 예전 글에서 우리는 Heat Equation(열방정식)
sine-qua-none.tistory.com
에 이어, 재미있는 예제를 하나 소개할까 합니다.
2차원 Heat Equation 예제
다음의 열방정식을 풀어봅시다.
∂u∂t=β(∂2u∂x2+∂2u∂y2) , 0≤t≤10 , 0≤x≤1 , 0≤y≤1 ○ 경계조건 : u(t,x,0)=30,u(t,x,1)=100,u(t,0,y)=0,u(t,1,y)=0 ○ 초기조건: u(0,x,y)=0,0<x,y<1 |
이 방정식의 정확한 해는 잘 모르지만, 앞서 보았던 OSM 방법으로 해결할 수 있습니다.
위 방정식의 경계조건을 그려보면 다음과 같습니다.

따라서 위 방정식은,
초기온도가 모두 0인 정사각형 영역에서,
- 왼쪽, 오른쪽에는 항상 0도로 유지되는 금속 막대기를 설치하고,
- 위쪽에는 항상 100도로 유지되는 금속 막대기를 설치
- 아래쪽에는 항상 30도로 유지되는 금속 막대기를 설치
했을 때,
주어진 영역안에서 온도가 어떻게 퍼질까? 를 구해보는 것입니다.
OSM FDM 을 쓰기 위한 이산화
지난 글의 예제 와는 달리, β라는 상수와, 경계 조건에 0이 아닌 값이 포함되어 있어, OSM을 위한 Tridiagonal 행렬을 만들 때 주의할 점이 있습니다.
x축 방향으로의 풀이
고정된 j, 0≤j≤J에 대해,
un+1/2ij−unijk=βun+1/2i−1,j−2un+1/2ij+un+1/2i+1,jh2x
따라서
un+1/2ij−unijk=αxβ(un+1/2i−1,j−2un+1/2ij+un+1/2i+1,j)
즉,
−αxβun+1/2i−1,j+(1+2αxβ)un+1/2ij−αxβun+1/2i+1,j=unij
입니다. 따라서 i=1 일 때는,
−αxβun+1/20,j+(1+2αxβ)un+1/21,j−αxβun+1/22,j=un1,j
이고 이고 un+1/20,j=uleft 이라 하면,
(1+2αxβ)un+1/21,j−αxβun+1/22,j=un1,j+αxβ⋅uleft
입니다.
마찬가지로, un+1/2I,j=uright 이라 하면,
(1+2αxβ)un+1/2I−2,j−αxβun+1/2I−1,j=unI−1,j+αxβ⋅uright
입니다.
위 예에서는 uleft=uright=0인 상황이죠.
y축 방향으로의 풀이
고정된 i, 0≤i≤I에 대해,
un+1ij−un+1/2ijk=βun+1i,j−1−2un+1ij+un+1i,j+1h2y
로 이산화됩니다. 따라서
un+1ij−un+1/2ijk=αyβ(un+1i,j−1−2un+1ij+un+1i,j+1)
즉, −αyβun+1i,j−1+(1+2αyβ)un+1ij−αyβun+1i,j+1=un+1/2ij
입니다. 따라서 j=1 일 때는,
−αyβun+1i,0+(1+2αyβ)un+1i,1−αyβun+1i,2=un+1/2i,1
이고 이고 un+1i,0=ubottom 이라 하면,
(1+2αyβ)un+1i,1−αyβun+1i,2=un+1/2i,1+αyβ⋅ubottom
입니다. 마찬가지로, un+1i,J=utop 이라 하면,
(1+2αyβ)un+1i,J−2−αyβun+1i,J−1=un+1/2i,J−1+αyβ⋅utop
입니다.
위 예에서는 ubottom=30 , utop=100인 상황입니다.
[중요]
즉 요지는, 함축적 방법(implicit method)에서 tridiagonal matrix를 풀 때, 아래 소개할 code에서 known 벡터에 적절한 경계조건이 반영이 되어야 한다는 뜻입니다.
Python Code: OSM으로 예시 풀기
이제 python code를 통하여 위 예시를 풀어보겠습니다.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import animation # 애니메이션 효과를 주기위한 animation import
def thomas(a, b, c, d):
""" A is the tridiagnonal coefficient matrix and d is the RHS matrix"""
"""
a is lower diagonal a2,a3,..,a_N, meaning
b is diagonal b1,b2,b3,..,b_N meaning
c is upper diagonal c1,c2,c3,.. c_{N-1} meaning
"""
N = len(a)
cp = np.zeros(N, dtype='float64') # store tranformed c or c'
dp = np.zeros(N, dtype='float64') # store transformed d or d'
X = np.zeros(N, dtype='float64') # store unknown coefficients
# Perform Forward Sweep
# Equation 1 indexed as 0 in python
cp[0] = c[0] / b[0]
dp[0] = d[0] / b[0]
# Equation 2, ..., N (indexed 1 - N-1 in Python)
for i in np.arange(1, (N), 1):
dnum = b[i] - a[i] * cp[i - 1]
cp[i] = c[i] / dnum
dp[i] = (d[i] - a[i] * dp[i - 1]) / dnum
# Perform Back Substitution
X[(N - 1)] = dp[N - 1] # Obtain last xn
for i in np.arange((N - 2), -1, -1): # use x[i+1] to obtain x[i]
X[i] = (dp[i]) - (cp[i]) * (X[i + 1])
return (X)
def HeatEqaution_2D_ImplicitFDM_AnotherExam():
# u_t(t,x,y) = beta *(u_xx(t,x,y) + u_{yy}(t,x,y)) 0<x,y<1, t>0
# u(0,x,y) = 0
# u(t,0,y) = u(t,1,y) =0
# u(t,x,0)= 30, u(t,x,1) = 100
beta = 0.01
t_min, t_max, NSize = 0, 10, 100 # 시점 [0,10]을 100등분
x_min, x_max, ISize = 0, 1, 100 # x=[0,1]을 100등분
y_min, y_max, JSize = 0, 1, 100 # y=[0,1]을 100등분
tSeq = np.linspace(t_min, t_max, NSize + 1)
xSeq = np.linspace(x_min, x_max, ISize + 1)
ySeq = np.linspace(y_min, y_max, JSize + 1)
hx = xSeq[1] - xSeq[0] # time level 분할 간격
hy = ySeq[1] - ySeq[0] # x 분할간격
k = tSeq[1] - tSeq[0] # y 분할간격
alphaX, alphaY = k / hx ** 2, k / hy ** 2 # 연립방정식 풀이에 나오는 α 계산
xval, yval = np.meshgrid(xSeq, ySeq)
# u 그리드 판 설계
u = np.empty((NSize + 1, ISize + 1, JSize + 1))
# -----initial condition--------------------
u[0, :, :] = 0
# -----boundary condition--------------------
u_left= 0 # x=0 인 부분의 경계조건
u_right = 0 # x=1 인 부분의 경계조건
u_top =100 # y=1 인 부분의 경계조건
u_bottom = 30 # y=0 인 부분의 경계조건
u[:, 0, :] = u_left # u(t,x_min,y)=0
u[:, -1, :] = u_right # u(t,x_max, y) =0
u[:, :, 0] = u_bottom # u(t,x,y_min)=0
u[:, :, -1] = u_top # u(t,x,y_max)=0
# x direction Thomas algorithm matrix
diagX = np.ones(ISize - 1) * (1 + 2 * alphaX * beta) # 식 ①로 만든 행렬의 계수 (Tridiagonal matrix)
underX = np.ones(ISize - 1) * (-alphaX * beta)
overX = np.ones(ISize - 1) * (-alphaX * beta)
# y direction Thomas algorithm matrix
diagY = np.ones(JSize - 1) * (1 + 2 * alphaY * beta) # 식 ②로 만든 행렬의 계수 (Tridiagonal matrix)
underY = np.ones(JSize - 1) * (-alphaY * beta)
overY = np.ones(JSize - 1) * (-alphaY * beta)
for tval in range(NSize): # 각 시점에 대해 (t=0,1,..,NSize-1 까지)
u_temp = u[tval, :, :].copy() # time level이 고정된 2차원 격자판 설정
# x축 방향으로 먼저 해결. y값을 고정시키고 x축으로 implicit method 적용
for j in range(1, JSize): # 고정된 j에 대해 (j=1,2,..,JSize-1)
knownX = u[tval, 1:ISize, j].copy() # Ax =b , A: tridiagonal matrix, b=known
knownX[-1] += alphaX * beta * u_right # [중요] 참고
knownX[0] += alphaX * beta * u_left # [중요] 참고 u[1:ISize]의 첫번째, 마지막 원소에 경계조건 반영
u_temp[1:ISize, j] = thomas(underX, diagX, overX, knownX) # Thomas algorithm
u_temp[0, j] = u_left # boundary 값 설정
u_temp[-1, j] = u_right # boundary 값 설정
# 그다음, y축 방향으로 해결, x 값을 고정 후 y축으로 implicit method 적용
for i in range(1, ISize):
knownY = u[tval, i, 1:JSize].copy()
knownY[-1] += alphaY * beta * u_top # [중요] 참고
knownY[0] += alphaY * beta * u_bottom # [중요] 참고
u_temp[i, 1:JSize] = thomas(underY, diagY, overY, knownY)
u_temp[i, 0] = u_bottom # boundray 값 설정
u_temp[i, -1] = u_top # boundary 값 설정
u[tval + 1, :, :] = u_temp.copy() # 그 다음 time level에 적용함
def plotheatmap(u_k, k):
# Clear the current plot figure
plt.clf()
plt.title('Temperature at t = {:.2f}'.format(tSeq[k]))
plt.xlabel("x")
plt.ylabel("y")
# This is to plot u_k (u at time-step k)
plt.pcolormesh(u_k, cmap=plt.cm.jet, vmin=0, vmax=100)
plt.colorbar()
def animate(k):
plotheatmap(u[k, :, :].T, k)
anim = animation.FuncAnimation(plt.figure(), animate, interval=500, frames=NSize, repeat=False)
anim.save("heat_equation_solution.gif", fps=10)
plt.show()
if __name__ == '__main__':
HeatEqaution_2D_ImplicitFDM_AnotherExam()
애니메이션 부분은 이 블로그를 참고했습니다.
실행시켜 볼까요?

시간이 흐를수록 위의 뜨거운 열이 아래로 전달되는 과정을 볼 수 있습니다.
그럴싸하네요.
'수학의 재미 > 아름다운 이론' 카테고리의 다른 글
테일러 전개 : 파생상품 헤지의 준비 이론 (0) | 2023.04.25 |
---|---|
2차원 Heat Equation의 풀이 #2 : OSM 예제풀이 (0) | 2023.02.09 |
2차원 Heat Equation의 풀이 #1 : Operator Splitting Method(OSM) (0) | 2023.02.06 |
FDM #10, Laplace Equation의 풀이(2) Python Code (0) | 2023.02.02 |
FDM #9, Laplace Equation의 풀이(1) (0) | 2023.02.02 |
댓글