Source Code Difusi 1D

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")

About Istiarto

Dosen di Jurusan Teknik Sipil dan Lingkungan FT UGM, Ir. (Teknik Sipil Hidro, UGM), M.Eng. (Water Resources, AIT), Ph.D. (Hydraulics, EPFL).
This entry was posted in Kuliah-Ujian-Tugas-Praktikum and tagged . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.