Source code di bawah ini menyelesaikan persamaan difusi 1D yang diaplikasikan dalam penjalaran (transpor, transfer) termal di sebuah batang baja. Lihat bahan ajar mata kuliah Solusi Numerik Persamaan Diferensial. Program dituliskan dalam bahasa pemrograman Python. Program dibuat sederhana agar mudah dibaca dan dimodifikasi oleh pengguna.
Metode Beda Hingga
import numpy as np # difusi 1D, metode beda hingga, skema implisit # noinspection PyShadowingNames def algoritma_thomas(a, b, c, d): n = len(d) # matriks asli disimpan ke matriks baru, lokal di sini cp = c.copy() bp = b.copy() dp = d.copy() # forward sweep for i in range(1, n): m = a[i - 1] / bp[i - 1] bp[i] = bp[i] - m * cp[i - 1] dp[i] = dp[i] - m * dp[i - 1] # back substitution x = np.zeros(n) x[-1] = dp[-1] / bp[-1] for i in range(n - 2, -1, -1): x[i] = (dp[i] - cp[i] * x[i + 1]) / bp[i] return x # data panjang = 10. k = 0.835 Delta_x = 1. Delta_t = 0.1 jnode = int(panjang / Delta_x) - 1 # jumlah titik hitung x = np.linspace(0, panjang, jnode + 2) # posisi titik dari pangkal x=0 s.d. ujung x=10 cm # variabel skalar dalam contoh kuliah adalah T (temperatur) # di program ini, variabel temperatur T diganti phi agar tidak rancu dengan variabel waktu t # syarat awal phi = np.zeros(jnode) # syarat awal, semua T = 0 # syarat batas phi_batas_kiri = 100. # syarat batas di pangkal (kiri) T = 100 phi_batas_kanan = 50. # syarat batas di ujung (kanan) T = 50 # koefisien matriks sistem persamaan linear aki = np.zeros(jnode - 1) # koefisien T_i-1 aka = np.zeros(jnode - 1) # koefisien T_i+1 ai = np.zeros(jnode) # koefisien T_i rhs = np.zeros(jnode) # konstanta di sisi kanan = # titik hitung ke-2 s.d. 1 dari batas kanan: i = 1, ..., jnode-2 (karena indeks di python mulai 0) koef_ki = k * Delta_t / Delta_x / Delta_x koef_ka = koef_ki for i in range(1, len(ai) - 1): aki[i - 1] = -1 * koef_ki aka[i] = -1 * koef_ka ai[i] = 1. + koef_ki + koef_ka rhs[i] = phi[i] # titik hitung pertama: i = 0 (node bertetangga dengan batas kiri) i = 0 aka[i] = -1 * koef_ka ai[i] = 1. + koef_ki + koef_ka rhs[i] = phi[i] + koef_ki * phi_batas_kiri # titik hitung paling kanan: i = jnode-1 (node bertetangga dengan batas kanan) i = len(ai) - 1 aki[i - 1] = -1 * koef_ki ai[i] = 1. + koef_ki + koef_ka rhs[i] = phi[i] + koef_ka * phi_batas_kanan # tulis judul kolom di baris pertama tulis_teks = " ".join(f"{jarak:9.1f}" for jarak in x) print(f" {tulis_teks}") # iterasi phi[i] terhadap waktu t --> t+dt t = 0. tulis_teks = " ".join(f"{angka:9.4f}" for angka in phi) print(f"{t:6.1f} {phi_batas_kiri:9.4f} {tulis_teks} {phi_batas_kanan:9.4f}") for n in range(1, 201): t = n * Delta_t phi = algoritma_thomas(aki, ai, aka, rhs) if (t % 1) == 0: tulis_teks = " ".join(f"{angka:9.4f}" for angka in phi) print(f"{t:6.1f} {phi_batas_kiri:9.4f} {tulis_teks} {phi_batas_kanan:9.4f}") rhs[0] = phi[0] + koef_ki * phi_batas_kiri for i in range(1, len(rhs) - 1): rhs[i] = phi[i] rhs[len(rhs) - 1] = phi[len(rhs) - 1] + koef_ka * phi_batas_kanan print("selesai")
Metode Volume Hingga
import numpy as np # TUGAS Makul SNPD # Difusi 1D, skema implisit, metode volume hingga # noinspection PyShadowingNames def algoritma_thomas(a, b, c, d): n = len(d) # matriks asli disimpan ke matriks baru, lokal di sini cp = c.copy() bp = b.copy() dp = d.copy() # forward sweep for i in range(1, n): m = a[i - 1] / bp[i - 1] bp[i] = bp[i] - m * cp[i - 1] dp[i] = dp[i] - m * dp[i - 1] # back substitution x = np.zeros(n) x[-1] = dp[-1] / bp[-1] for i in range(n - 2, -1, -1): x[i] = (dp[i] - cp[i] * x[i + 1]) / bp[i] return x # data panjang = 10. # cm Gamma = 0.835 # cm^2/s Delta_x = 1. # cm Delta_t = 0.1 # s diameter = 0.6 # cm luas = 0.25 * np.pi * diameter ** 2 Delta_V = luas * Delta_x jmlvc = int(panjang / Delta_x) # jumlah volume kontrol Delta_x = panjang / jmlvc # Delta_x dihitung ulang untuk penyesuaian dengan jumlah volume kontrol x1 = np.arange(Delta_x/2, panjang, Delta_x) # jarak/posisi volume kontrol x = np.concatenate(([0.], x1, [10.])) # jarak pangkal (x=0), volume kontrol, ujung (x=10) # syarat awal phi = np.zeros(jmlvc) # syarat batas phi_kiri = 100. # der C phi_kanan = 50. # der C # koefisien matriks tridiagonal aW = np.zeros(jmlvc - 1) # diagonal bawah: jumlah koefisien adalah jumlah vk-1 aE = np.zeros(jmlvc - 1) # diagonal atas: jumlah koefisien adalah jumlah vk-1 aP = np.zeros(jmlvc) # diagonal utama: jumlah koefisien adalah jumlah vk rhs = np.zeros(jmlvc) # konstanta di sisi kanan tanda kesamaan "=" # volume kontrol 2, 3, ..., jmlvc-1: i=1, 2, ..., jmlvc-2 koef_W = Gamma * luas * Delta_t / Delta_x / Delta_V koef_E = koef_W for i in range(1, jmlvc - 1): aW[i - 1] = -1 * koef_W aE[i] = -1 * koef_E aP[i] = koef_W + koef_E + 1. rhs[i] = phi[i] # volume kontrol 1: i=0 koef_kiri = Gamma * luas * Delta_t / (Delta_x / 2) / Delta_V aE[0] = -1 * koef_E aP[0] = koef_kiri + koef_E + 1. rhs[0] = phi[0] + koef_kiri * phi_kiri # volume kontrol paling kanan: i=jmlvc-1 koef_kanan = Gamma * luas * Delta_t / (Delta_x / 2) / Delta_V aW[jmlvc - 2] = -1 * koef_W aP[jmlvc - 1] = koef_W + koef_kanan + 1. rhs[jmlvc - 1] = phi[jmlvc - 1] + koef_kanan * phi_kanan # iterasi phi[i] terhadap waktu t --> t+dt t = 0. tulis_teks = " ".join(f"{angka:9.1f}" for angka in x) # Mengubah angka x menjadi teks print(f" {tulis_teks}") # Menuliskan posisi volume kontrol di baris pertama tulis_teks = " ".join(f"{angka:9.4f}" for angka in phi) # Mengubah angka phi menjadi teks print(f"{t:6.1f} {phi_kiri:9.4f} {tulis_teks} {phi_kanan:9.4f}") # Menuliskan nilai awal phi for n in range(1, 201): # Menghitung phi pada waktu t+Delta_t t = n * Delta_t phi = algoritma_thomas(aW, aP, aE, rhs) # Penyelesaian persamaan linear, matriks tridiagonal if (t % 1) == 0: # Mencetak hasil hitungan tiap detik tulis_teks = " ".join(f"{angka:9.4f}" for angka in phi) print(f"{t:6.1f} {phi_kiri:9.4f} {tulis_teks} {phi_kanan:9.4f}") rhs[0] = phi[0] + koef_kiri * phi_kiri for i in range(1, jmlvc - 1): rhs[i] = phi[i] rhs[jmlvc - 1] = phi[jmlvc - 1] + koef_kanan * phi_kanan print("selesai")