-
Notifications
You must be signed in to change notification settings - Fork 0
/
HeatEquation.py
75 lines (58 loc) · 2.2 KB
/
HeatEquation.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import matplotlib.animation as animation
import matplotlib.pyplot as plt
import numpy as np
from scipy.sparse import diags
class HeatEquation():
"""Finite Differences for the Heat Equation PDE"""
def __init__(self, f, L=1, T=1, dx=0.1, dt=0.00025):
"""Initialize the PDE.
Parameters
----------
f : function
The callable for the boundary condition
L : float
The rod length
T : float
Stopping time
dx : float
Step length in x-dimension
dt : float
Step length in t-dimension
"""
if dt <= 0 or dx <= 0:
raise ValueError("dt and dx must be greater than 0")
if L <= 0 or T <= 0:
raise ValueError("L and T must be greater than 0")
self.T = T # Stopping time
self.L = L # Rod length
self.dx = dx # x step
self.dt = dt # Time step
self.f = f # Initial conditions, callable
self.alpha = round(dt/dx**2, 5)
self.n_t = int(self.T/self.dt) + 1
self.n_x = int(self.L/self.dx) + 1
self.x = np.zeros(self.n_x)
self.t = np.zeros(self.n_t)
self.g = np.zeros((self.n_x, self.n_t))
self.t[:-1] = np.arange(0, self.T, self.dt)
self.t[-1] = self.T
self.x[:-1] = np.arange(0, self.L, self.dx)
self.x[-1] = self.L
self.g[0, :] = 0.0 # self.u = a(t), boundary condition u(0, t)
self.g[-1, :] = 0.0 # self.u = b(t), boundary condition u(L, t)
self.g[1:-1, 0] = self.f(self.x[1:-1]) # self.u = b(t), initial condition u(x, 0)
self.IsSolved = False
def __call__(self, j):
"""Return the x-space vector at j in time."""
return self.g[:, j]
def ExplicitEuler(self):
"""Solve PDE with explicit Euler method."""
a1 = 1 - 2 * self.alpha
a2 = self.alpha
# Set up sparse A-matrix
self.A = diags([a2, a1, a2],
[-1, 0, 1],
shape=(self.n_x - 2, self.n_x - 2))
for i in range(self.n_t - 1):
self.g[1:-1, i + 1] = self.A @ self.g[1:-1, i]
self.IsSolved = True