정보통신기술(ICT)

2D 라플라스 방정식을 풀기 위한 함수

해머슴 2024. 10. 23. 12:11
import numpy as np
import matplotlib.pyplot as plt
from tkinter import Tk, Label, Entry, Button, Toplevel, messagebox

def solve_laplace(nx=50, ny=50, top=100, bottom=0, left=0, right=0, tolerance=1e-4, max_iterations=10000):
    # 격자 초기화
    u = np.zeros((nx, ny))

    # 경계 조건 설정
    u[0, :] = top    # 위쪽 경계 조건
    u[-1, :] = bottom # 아래쪽 경계 조건
    u[:, 0] = left   # 왼쪽 경계 조건
    u[:, -1] = right  # 오른쪽 경계 조건

    # 반복 설정
    iteration = 0
    error = 1.0

    # Jacobi 반복법
    while error > tolerance and iteration < max_iterations:
        u_old = u.copy()
        u[1:-1, 1:-1] = 0.25 * (u_old[1:-1, :-2] + u_old[1:-1, 2:] + u_old[:-2, 1:-1] + u_old[2:, 1:-1])
       
        # 최대 오차 계산
        error = np.max(np.abs(u - u_old))
        iteration += 1

    return u

def run_laplace():
    try:
        # 입력값 가져오기
        nx = int(nx_entry.get())
        ny = int(ny_entry.get())
        top = float(top_entry.get())
        bottom = float(bottom_entry.get())
        left = float(left_entry.get())
        right = float(right_entry.get())
        tolerance = float(tolerance_entry.get())
        max_iterations = int(max_iterations_entry.get())

        # 라플라스 방정식 풀기
        result = solve_laplace(nx, ny, top, bottom, left, right, tolerance, max_iterations)

        # 결과 시각화
        plt.imshow(result, cmap='hot', interpolation='nearest')
        plt.colorbar(label='Potential')
        plt.title('Laplace Equation Solution')
        plt.show()

    except ValueError:
        messagebox.showerror("입력 오류", "모든 입력 값을 올바르게 입력하세요.")

# GUI 설정
root = Tk()
root.title("Laplace Equation Solver")

# 입력 필드 생성
Label(root, text="격자의 x 크기 (nx):").grid(row=0, column=0)
nx_entry = Entry(root)
nx_entry.grid(row=0, column=1)

Label(root, text="격자의 y 크기 (ny):").grid(row=1, column=0)
ny_entry = Entry(root)
ny_entry.grid(row=1, column=1)

Label(root, text="위쪽 경계 조건 값:").grid(row=2, column=0)
top_entry = Entry(root)
top_entry.grid(row=2, column=1)

Label(root, text="아래쪽 경계 조건 값:").grid(row=3, column=0)
bottom_entry = Entry(root)
bottom_entry.grid(row=3, column=1)

Label(root, text="왼쪽 경계 조건 값:").grid(row=4, column=0)
left_entry = Entry(root)
left_entry.grid(row=4, column=1)

Label(root, text="오른쪽 경계 조건 값:").grid(row=5, column=0)
right_entry = Entry(root)
right_entry.grid(row=5, column=1)

Label(root, text="수렴 조건 (tolerance):").grid(row=6, column=0)
tolerance_entry = Entry(root)
tolerance_entry.grid(row=6, column=1)

Label(root, text="최대 반복 횟수 (max_iterations):").grid(row=7, column=0)
max_iterations_entry = Entry(root)
max_iterations_entry.grid(row=7, column=1)

# 실행 버튼 생성
Button(root, text="실행", command=run_laplace).grid(row=8, column=0, columnspan=2)

# 기본값 설정
nx_entry.insert(0, "50")
ny_entry.insert(0, "50")
top_entry.insert(0, "100")
bottom_entry.insert(0, "0")
left_entry.insert(0, "0")
right_entry.insert(0, "0")
tolerance_entry.insert(0, "1e-4")
max_iterations_entry.insert(0, "10000")

# GUI 실행
root.mainloop()