Skip to content
This repository was archived by the owner on Jul 25, 2023. It is now read-only.

Commit bc860b4

Browse files
author
Jordi
committed
Diffusion and Advection
Materials for Diffusion and Advection classes on days 7 and 8.
1 parent 6ab787a commit bc860b4

File tree

9 files changed

+512
-0
lines changed

9 files changed

+512
-0
lines changed

day_7/Diffusion/Poisson1D

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#!/usr/bin/env python
2+
"""
3+
Solution of a 1D Poisson equation: -u_xx = f
4+
Domain: [0,1]
5+
BC: u(0) = u(1) = 0
6+
with f = (3*x + x^2)*exp(x)
7+
8+
Analytical solution: -x*(x-1)*exp(x)
9+
10+
Finite differences (FD) discretization: second-order diffusion operator
11+
"""
12+
__author__ = 'Jordi Vila-Pérez'
13+
__email__ = 'jvilap@mit.edu'
14+
15+
16+
import numpy as np
17+
import matplotlib.pyplot as plt
18+
import matplotlib.animation as animation #We have to load this
19+
from math import pi
20+
%matplotlib qt
21+
plt.close()
22+
23+
"Number of points"
24+
N = 8
25+
Dx = 1/N
26+
x = np.linspace(0,1,N+1)
27+
28+
"System matrix and RHS term"
29+
A = (1/Dx**2)*(2*np.diag(np.ones(N-1)) - np.diag(np.ones(N-2),-1) - np.diag(np.ones(N-2),1))
30+
F = (3*x[1:N] + x[1:N]**2)*np.exp(x[1:N])
31+
32+
"Solution of the linear system AU=F"
33+
U = np.linalg.solve(A,F)
34+
u = np.concatenate(([0],U,[0]))
35+
ua = -x*(x-1)*np.exp(x)
36+
37+
"Plotting solution"
38+
plt.plot(x,ua,'-r',linewidth=2,label='$u_a$')
39+
plt.plot(x,u,':ob',linewidth=2,label='$\widehat{u}$')
40+
plt.legend(fontsize=12,loc='upper left')
41+
plt.grid()
42+
plt.axis([0, 1,0, 0.5])
43+
plt.xlabel("x",fontsize=16)
44+
plt.ylabel("u",fontsize=16)
45+
46+
"Compute error"
47+
error = np.max(np.abs(u-ua))
48+
print("Linf error u: %g\n" % error)
49+
50+
51+
52+
53+
54+
55+

day_7/Diffusion/PoissonSpherical1D

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#!/usr/bin/env python
2+
"""
3+
Solution of a 1D Poisson equation in spherical coordinates: -u_rr - (2/r)*u_r = f
4+
Domain: [r0,r0+1] IMPORTANT r>0
5+
BC: u(r0) = u0, u'(r0+1) = 0
6+
with f = 2*(2*A(rt)/r + B(rt))*erp(rt), being A(rt) = 2*rt^2 + rt - 3, and B(rt) = 2*rt^2 + 5*rt -2
7+
and rt = r-r0
8+
9+
Analytical solution: 2*(rt)*(3-2*(rt))*exp(rt) + u0
10+
11+
Finite differences (FD) discretization: second-order daccuracy
12+
13+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14+
Introduce first-order derivative with second-order accuracy
15+
16+
"""
17+
__author__ = 'Jordi Vila-Pérez'
18+
__email__ = 'jvilap@mit.edu'
19+
20+
21+
import numpy as np
22+
import matplotlib.pyplot as plt
23+
import matplotlib.animation as animation #We have to load this
24+
from math import pi
25+
%matplotlib qt
26+
plt.close()
27+
28+
"Number of points"
29+
N = 16
30+
r0 = 13
31+
Dr = 1/N
32+
r = np.linspace(0,1,N+1) + r0
33+
rN = np.concatenate((r, [r[N]+Dr]))
34+
rNt = rN-r0
35+
36+
"Dirichlet boundary condition at r0"
37+
u0 = 1
38+
39+
"System matrir and RHS term"
40+
A = (1/Dr**2)*(2*np.diag(np.ones(N+2)) - np.diag(np.ones(N+1),-1) - np.diag(np.ones(N+1),1))
41+
"First-order term"
42+
A = A + (1/Dr)*(np.diag(1/rN[1:N+2],-1) - np.diag(1/rN[0:N+1],1))
43+
44+
"New source term"
45+
Ar = 2*rNt**2 + rNt - 3
46+
Br = 2*rNt**2 + 5*rNt - 2
47+
F = 2*(2*Ar/rN + Br)*np.exp(rNt)
48+
49+
"Boundary condition at r=0"
50+
A[0,:] = np.concatenate(([1], np.zeros(N+1)))
51+
F[0] = u0
52+
53+
"Boundary condition at r=0"
54+
A[N+1,:] = (0.5/Dr)*np.concatenate((np.zeros(N-1),[-1, 0, 1]))
55+
F[N+1] = 0
56+
57+
"Solution of the linear system AU=F"
58+
u = np.linalg.solve(A,F)
59+
u = u[0:N+1]
60+
61+
rt = r-r0
62+
ua = 2*rt*(3-2*rt)*np.exp(rt)+u0
63+
64+
plt.plot(r,ua,'-r',linewidth=2,label='$u_a$')
65+
plt.plot(r,u,':ob',linewidth=2,label='$\widehat{u}$')
66+
plt.legend(fontsize=12,loc='upper left')
67+
plt.grid()
68+
plt.xlabel("x",fontsize=16)
69+
plt.ylabel("u",fontsize=16)
70+
71+
"Compute error"
72+
error = np.max(np.abs(u-ua))
73+
print("Linf error u: %g\n" % error)
74+
3.56 MB
Binary file not shown.

day_7/Diffusion/diffusion.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
---
2+
title:
3+
description: Finite Difference Discretization of Elliptic Problems: the Heat Equation
4+
author: Jordi Vila-Pérez
5+
keywords: space-weather,finite differences, diffusion, heat equation, Poisson
6+
---
7+
8+
Jordi Vila-Pérez | jvilap@mit.edu
9+
10+
----------
11+
12+
## Objectives
13+
14+
- Understand basic concepts of discretization of simple PDE models using finite differences.
15+
- Be able to discretize a 1D elliptic problem (steady and transient).
16+
- Learn how to model different kinds of boundary conditions and how to approximate them numerically.
17+
- Get used to write and read code to solve PDEs numerically.
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#!/usr/bin/env python
2+
"""
3+
Solution of a 1D Convection-Diffusion equation: -nu*u_xx + c*u_x = f
4+
Domain: [0,1]
5+
BC: u(0) = u(1) = 0
6+
with f = 1
7+
8+
Analytical solution: (1/c)*(x-((1-exp(c*x/nu))/(1-exp(c/nu))))
9+
10+
Finite differences (FD) discretization:
11+
- Second-order cntered differences advection scheme
12+
13+
"""
14+
__author__ = 'Jordi Vila-Pérez'
15+
__email__ = 'jvilap@mit.edu'
16+
17+
18+
import numpy as np
19+
import matplotlib.pyplot as plt
20+
from math import pi
21+
%matplotlib qt
22+
plt.close()
23+
import matplotlib.animation as animation
24+
25+
"Flow parameters"
26+
nu = 0.01
27+
c = 2
28+
29+
"Number of points"
30+
N = 128
31+
Dx = 1/N
32+
x = np.linspace(0,1,N+1)
33+
34+
"System matrix and RHS term"
35+
"Diffusion term"
36+
Diff = nu*(1/Dx**2)*(2*np.diag(np.ones(N-1)) - np.diag(np.ones(N-2),-1) - np.diag(np.ones(N-2),1))
37+
"Advection term: centered differences"
38+
Advp = -0.5*c*np.diag(np.ones(N-2),-1)
39+
Advm = -0.5*c*np.diag(np.ones(N-2),1)
40+
Adv = (1/Dx)*(Advp-Advm)
41+
A = Diff + Adv
42+
"Source term"
43+
F = np.ones(N-1)
44+
45+
46+
"Solution of the linear system AU=F"
47+
U = np.linalg.solve(A,F)
48+
u = np.concatenate(([0],U,[0]))
49+
ua = (1/c)*(x-((1-np.exp(c*x/nu))/(1-np.exp(c/nu))))
50+
51+
plt.plot(x,ua,'-r',linewidth=2,label='$u_a$')
52+
plt.plot(x,u,':ob',linewidth=2,label='$\widehat{u}$')
53+
plt.legend(fontsize=12,loc='upper left')
54+
plt.grid()
55+
plt.axis([0, 1,0, 2/c])
56+
plt.xlabel("x",fontsize=16)
57+
plt.ylabel("u",fontsize=16)
58+
59+
60+
"Compute error"
61+
error = np.max(np.abs(u-ua))
62+
print("Linf error u: %g\n" % error)
63+
64+
"Peclet number"
65+
P = np.abs(c*Dx/nu)
66+
print("Pe number Pe=%g\n" % P);
67+
68+
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
#!/usr/bin/env python
2+
"""
3+
Solution of a 1D Convection-Diffusion equation: -nu*u_xx + c*u_x = f
4+
Domain: [0,1]
5+
BC: u(0) = u(1) = 0
6+
with f = 1
7+
8+
Analytical solution: (1/c)*(x-((1-exp(c*x/nu))/(1-exp(c/nu))))
9+
10+
Finite differences (FD) discretization:
11+
- Second-order cntered differences advection scheme
12+
- First-order upwind
13+
14+
"""
15+
__author__ = 'Jordi Vila-Pérez'
16+
__email__ = 'jvilap@mit.edu'
17+
18+
19+
import numpy as np
20+
import matplotlib.pyplot as plt
21+
from math import pi
22+
%matplotlib qt
23+
plt.close()
24+
import matplotlib.animation as animation
25+
26+
"Flow parameters"
27+
nu = 0.01
28+
c = 2
29+
30+
"Scheme parameters"
31+
beta = 1
32+
33+
"Number of points"
34+
N = 256
35+
Dx = 1/N
36+
x = np.linspace(0,1,N+1)
37+
38+
"Time parameters"
39+
dt = 0.1
40+
time = np.arange(0,3+dt,dt)
41+
nt = np.size(time)
42+
43+
"Initialize solution variable"
44+
U = np.zeros((N-1,nt))
45+
46+
47+
for it in range(nt-1):
48+
49+
"System matrix and RHS term"
50+
"Diffusion term"
51+
Diff = nu*(1/Dx**2)*(2*np.diag(np.ones(N-1)) - np.diag(np.ones(N-2),-1) - np.diag(np.ones(N-2),1))
52+
53+
"Advection term:"
54+
55+
"Sensor"
56+
U0 = U[:,it]
57+
uaux = np.concatenate(([0],U0,[0]))
58+
Du = uaux[1:N+1] - uaux[0:N] + 1e-8
59+
r = Du[0:N-1]/Du[1:N]
60+
61+
"Limiter"
62+
if beta>0:
63+
phi = np.minimum(np.minimum(beta*r,1),np.minimum(r,beta))
64+
phi = np.maximum(0,phi)
65+
else:
66+
phi = 2*r/(r**2 + 1)
67+
68+
phim = phi[0:N-2]
69+
phip = phi[1:N-1]
70+
71+
72+
"Upwind scheme"
73+
cp = np.max([c,0])
74+
cm = np.min([c,0])
75+
76+
Advp = cp*(np.diag(1-phi) - np.diag(1-phip,-1))
77+
Advm = cm*(np.diag(1-phi) - np.diag(1-phim,1))
78+
Alow = Advp-Advm
79+
"Centered differences"
80+
Advp = -0.5*c*np.diag(phip,-1)
81+
Advm = -0.5*c*np.diag(phim,1)
82+
Ahigh = Advp-Advm
83+
84+
Adv = (1/Dx)*(Ahigh + Alow)
85+
A = Diff + Adv
86+
"Source term"
87+
F = np.ones(N-1)
88+
89+
"Temporal terms"
90+
A = A + (1/dt)*np.diag(np.ones(N-1))
91+
F = F + U0/dt
92+
93+
94+
"Solution of the linear system AU=F"
95+
u = np.linalg.solve(A,F)
96+
U[:,it+1] = u
97+
u = np.concatenate(([0],u,[0]))
98+
99+
100+
ua = (1/c)*(x-((1-np.exp(c*x/nu))/(1-np.exp(c/nu))))
101+
102+
"Animation of the results"
103+
fig = plt.figure()
104+
ax = plt.axes(xlim =(0, 1),ylim =(0,1/c))
105+
plt.plot(x,ua,'-r',linewidth=2,label='$u_a$')
106+
myAnimation, = ax.plot([], [],':ob',linewidth=2)
107+
plt.grid()
108+
plt.xlabel("x",fontsize=16)
109+
plt.ylabel("u",fontsize=16)
110+
111+
def animate(i):
112+
113+
u = np.concatenate(([0],U[0:N+1,i],[0]))
114+
plt.plot(x,u)
115+
myAnimation.set_data(x, u)
116+
return myAnimation,
117+
118+
anim = animation.FuncAnimation(fig,animate,frames=range(1,nt),blit=True,repeat=False)
119+
120+
"Compute error"
121+
error = np.max(np.abs(u-ua))
122+
print("Linf error u: %g\n" % error)
123+
124+
"Peclet number"
125+
P = np.abs(c*Dx/nu)
126+
print("Pe number Pe=%g\n" % P);
127+
128+
"CFL number"
129+
CFL = np.abs(c*dt/Dx)
130+
print("CFL number CFL=%g\n" % CFL);
131+

0 commit comments

Comments
 (0)