64 lines
2.0 KiB
Python
64 lines
2.0 KiB
Python
|
# Task 1.1, 1.2
|
||
|
import numpy as np
|
||
|
from typing import Callable
|
||
|
from matplotlib import pyplot as plt
|
||
|
|
||
|
# Config
|
||
|
D = 1e-6 # diffusion coefficient
|
||
|
h = 1 # space domain (max x size)
|
||
|
T = 2e6 # solution end time
|
||
|
nx = 50 # nr of space discretization points
|
||
|
nt = 20000 # nr of time discretization points
|
||
|
|
||
|
# derived constants
|
||
|
dx = h / (nx - 1) # space step size
|
||
|
dt = T / (nt - 1) # time step size
|
||
|
d = dt * D / dx**2 # stability/stepsize coefficient
|
||
|
|
||
|
# report stability
|
||
|
if d > 0.5:
|
||
|
print("NOT Stable")
|
||
|
else:
|
||
|
print("Stable")
|
||
|
|
||
|
# explicit scheme integration for `u_t - D u_xx = 0` with boundary conditions
|
||
|
# enforced by `set_bounds` and initial conditions `initial`.
|
||
|
def integrate(*, name: str, initial: np.array, set_bounds: Callable[[np.array], None]) -> None:
|
||
|
C = initial
|
||
|
# Setup boundary conditions
|
||
|
set_bounds(C)
|
||
|
|
||
|
i = 0 # index for plot generation
|
||
|
plt.figure(figsize = (8, 6), dpi = 100)
|
||
|
for t in range(nt):
|
||
|
# every 400'th time step save a plot
|
||
|
if t % (nt // 400) == 0:
|
||
|
plt.clf()
|
||
|
plt.plot(np.linspace(0, h, nx), C)
|
||
|
plt.xlim([0, h])
|
||
|
plt.ylim([0, 1.2])
|
||
|
plt.savefig(f"plots/{name}_{i:0>5}.png")
|
||
|
i += 1
|
||
|
# update solution using the explicit schema
|
||
|
C[1:-1] += d * (C[2:] - 2 * C[1:-1] + C[:-2])
|
||
|
# update right Neumann BC
|
||
|
set_bounds(C)
|
||
|
|
||
|
# Subtask 1 boundary conditions (Dirichlet and Neumann)
|
||
|
def bounds_1(C):
|
||
|
C[0] = 1
|
||
|
C[-1] = C[-2]
|
||
|
|
||
|
# Subtask 2 boundary conditions (two Dirichlet)
|
||
|
def bounds_2(C):
|
||
|
C[0] = 1
|
||
|
C[-1] = 0
|
||
|
|
||
|
# run simulations
|
||
|
integrate(name = 'task01_1', initial = np.zeros(nx), set_bounds = bounds_1)
|
||
|
integrate(name = 'task01_2', initial = np.zeros(nx), set_bounds = bounds_2)
|
||
|
|
||
|
# to convert generated image sequence to video use:
|
||
|
# $> ffmpeg -r 60 -i plots/task01_1_%05d.png -pix_fmt yuv420p video_1_1.mp4
|
||
|
# $> ffmpeg -r 60 -i plots/task01_2_%05d.png -pix_fmt yuv420p video_1_2.mp4
|