Advertisement
575

numlab1

575
Mar 7th, 2023 (edited)
621
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.55 KB | None | 0 0
  1. import numpy as np, matplotlib.pyplot as plt
  2.  
  3.  
  4. def analyt_func(x, a, c, t):
  5.     return np.exp((c - a) * t) * np.sin(x)
  6.  
  7. def func_border1(a, c, t):
  8.     return np.exp((c - a) * t)
  9.  
  10. def func_border2(a, c, t):
  11.     return np.exp((c - a) * t)
  12.  
  13. def run_through(a, b, c, d, s):
  14.     P = np.zeros(s + 1)
  15.     Q = np.zeros(s + 1)
  16.  
  17.     P[0] = -c[0] / b[0]
  18.     Q[0] = d[0] / b[0]
  19.    
  20.     k = s - 1
  21.     for i in range(1, s):
  22.         P[i] = -c[i] / (b[i] + a[i] * P[i - 1])
  23.         Q[i] = (d[i] - a[i] * Q[i - 1]) / (b[i] + a[i] * P[i - 1])
  24.     P[k] = 0
  25.     Q[k] = (d[k] - a[k] * Q[k - 1]) / (b[k] + a[k] * P[k - 1])
  26.  
  27.     x = np.zeros(s)
  28.     x[k] = Q[k]
  29.  
  30.     for i in range(s - 2, -1, -1):
  31.         x[i] = P[i] * x[i + 1] + Q[i]
  32.  
  33.     return x
  34.  
  35. def explicit(K, t, tau, h, a, c, x, approx):
  36.     N = len(x)
  37.     U = np.zeros((K, N))
  38.     for j in range(N):
  39.             U[0, j] = np.sin(x[j])
  40.  
  41.     for k in range(K - 1):
  42.         t += tau
  43.         for j in range(1, N - 1):
  44.             U[k + 1, j] = tau * (a * (U[k, j - 1] - 2 * U[k, j] + U[k, j + 1]) / h**2 + \
  45.             + c * U[k, j]) + U[k, j]
  46.         if approx == 1:
  47.             U[k + 1, 0] = U[k + 1, 1] - h * func_border1(a, c, t)
  48.             U[k + 1, N - 1] = func_border2(a, c, t)
  49.         elif approx == 2:
  50.             U[k + 1, 0] = (2 * h * func_border1(a, c, t) - 4 * U[k + 1, 1] + U[k + 1, 2]) / (2 * h - 3)
  51.             U[k + 1, N - 1] = func_border2(a, c, t)
  52.         elif approx == 3:
  53.             U[k + 1, 0] = (func_border1(a, c, t) * h * tau * 2 - U[k + 1, 1] * (2 * tau) - U[k, 0] * h**2) / \
  54.             (-2 * tau - h**2 + c * tau * h**2 + h * tau * 2)
  55.             U[k + 1, N - 1] = func_border2(a, c, t)
  56.            
  57.     return U
  58.  
  59. def implicit(K, t, tau, h, a1, c1, x, approx):
  60.     N = len(x)
  61.     U = np.zeros((K, N))
  62.     for j in range(N):
  63.             U[0, j] = np.sin(x[j])
  64.    
  65.     for k in range(0, K - 1):
  66.         a = np.zeros(N)
  67.         b = np.zeros(N)
  68.         c = np.zeros(N)
  69.         d = np.zeros(N)
  70.         t += tau
  71.  
  72.         for j in range(1, N - 1):
  73.             a[j] = tau * (a1 / h**2 - 0 / (2 * h))
  74.             b[j] = tau * ((-2 * a1) / h**2 + c1) - 1
  75.             c[j] = tau * (a1 / h**2 + 0 / (2 * h))
  76.             d[j] = -U[k][j]
  77.  
  78.         if approx == 1:
  79.             b[0] = 0 - 1 / h
  80.             c[0] = 1 / h
  81.             d[0] = func_border1(a1, c1, t)
  82.  
  83.             a[N - 1] = 0
  84.             b[N - 1] = 1
  85.             d[N - 1] = func_border2(a1, c1, t)
  86.         elif approx == 2:
  87.             k0 = 1 / (2 * h) / c[1]
  88.             b[0] = (-3 / (2 * h)) + 1 + a[1] * k0
  89.             c[0] = 2 / h + b[1] * k0
  90.             d[0] = func_border1(a1, c1, t) + d[1] * k0
  91.  
  92.             k1 = -(1 / (h * 2)) / a[N - 2]
  93.             a[N - 1] = (-2 / h) + b[N - 2] * k1
  94.             b[N - 1] = (3 / (h * 2)) + 1 + c[N - 2] * k1
  95.             d[N - 1] = func_border2(a1, c1, t) + d[N - 2] * k1
  96.         elif approx == 3:
  97.             b[0] = 2 * a1**2 / h + h / tau - c1 * h - 2
  98.             c[0] = - 2 * a1**2 / h
  99.             d[0] = (h / tau) * U[k - 1][0] - func_border1(a1, c1, t) * 2
  100.  
  101.             a[N - 1] = -2 * a1**2 / h
  102.             b[N - 1] = 2 * a1**2 / h + h / tau - c1 * h + 2
  103.             d[N - 1] = (h / tau) * U[k - 1][N - 1] + func_border2(a1, c1, t) * 2
  104.  
  105.         u_new = run_through(a, b, c, d, N)
  106.         for i in range(N):
  107.             U[k + 1, i] = u_new[i]
  108.  
  109.     return U
  110.  
  111. def Krank_Nikolson(K, t, tau, h, a1, c1, x, approx, theta):
  112.     N = len(x)
  113.     if theta == 0:
  114.         U = explicit(K, t, tau, h, a1, c1, x, approx)
  115.     elif theta == 1:
  116.         U = implicit(K, t, tau, h, a1, c1, x, approx)
  117.     else:
  118.         U_ex = explicit(K, t, tau, h, a1, c1, x, approx)
  119.         U_im = implicit(K, t, tau, h, a1, c1, x, approx)
  120.         U = np.zeros((K, N))
  121.         for i in range(K):
  122.             for j in range(N):
  123.                 U[i, j] = theta * U_im[i][j] + (1 - theta) * U_ex[i][j]
  124.  
  125.     return U
  126.  
  127. def main(N, K, time):
  128.     h = (np.pi - 0) / N
  129.     tau = time / K
  130.     x = np.arange(0, np.pi / 2 + h / 2 - 1e-4, h)
  131.     T = np.arange(0, time, tau)
  132.     a = 1
  133.     ##b = 1.55
  134.     c = -1
  135.     t = 0
  136.  
  137.     while (1):
  138.         print("Выберите метод:\n"
  139.             "1 - явная конечно-разностная схема\n"
  140.             "2 - неявная конечно-разностная схема\n"
  141.             "3 - схема Кранка-Николсона\n"
  142.             "0 - выход из программы")
  143.         method = int(input())
  144.         if method == 0:
  145.             break
  146.         else:
  147.             print("Выберите уровень апроксимации:\n"
  148.                 "1 - двухточечная аппроксимация с первым порядком\n"
  149.                 "2 - трехточечная аппроксимация со вторым порядком\n"
  150.                 "3 - двухточечная аппроксимация со вторым порядком")
  151.             approx = int(input())
  152.  
  153.             if method == 1:
  154.                 if a * tau / h**2 <= 0.5:
  155.                     print("Условие Куррента выполнено:", a * tau / h**2, "<= 0.5\n")
  156.                     U = explicit(K, t, tau, h, a, c, x, approx)
  157.                 else:
  158.                     print("Условие Куррента не выполнено:", a * tau / h**2, "> 0.5")
  159.                     break
  160.             elif method == 2:
  161.                 U = implicit(K, t, tau, h, a, c, x, approx)
  162.             elif method == 3:
  163.                 ##theta = float(input("Введите параметр theta от 0 до 1:"))
  164.                 theta = 0.5;
  165.                 U = Krank_Nikolson(K, t, tau, h, a, c, x, approx, theta)
  166.  
  167.         dt = int(input("Введите момент времени:"))
  168.         U_analytic = analyt_func(x, a, c, T[dt])
  169.         error = abs(U_analytic - U[dt, :])
  170.         plt.title("График точного и численного решения задачи")
  171.         plt.plot(x, U_analytic, label = "Точное решение", color = "red")
  172.         plt.scatter(x, U[dt, :], label = "Численное решение")
  173.         plt.xlabel("x")
  174.         plt.ylabel("U")
  175.         plt.text(0.2, -0.8, "Максимальная ошибка метода: " + str(max(error)))
  176.         plt.axis([-0.2, 3.3, -1, 1])
  177.         plt.grid()
  178.         plt.legend()
  179.         plt.show()
  180.  
  181.         plt.title("График ошибки по шагам")
  182.         error_time = np.zeros(len(T))
  183.         for i in range(len(T)):
  184.             error_time[i] = max(abs(analyt_func(x, a, c, T[i]) - U[i, :]))
  185.         plt.plot(T, error_time, label = "По времени")
  186.         plt.plot(x, error, label = "По пространству в выбранный момент времени")
  187.         plt.legend()
  188.         plt.grid()
  189.         plt.show()
  190.  
  191.     return 0
  192.  
  193. #закомментировать секцию для вычисления погрешности
  194. N = 50
  195. K = 7000
  196. time = 3
  197. main(N, K, time)
  198. #конец секции
  199.  
  200. N = 50
  201. K = 7000
  202. time = 3
  203.  
  204. tau = time / K
  205. T = np.arange(0, time, tau)
  206. h = []
  207. a = 1  
  208. c = -1
  209. t = 0
  210. t1 = 500
  211. for i in range(0, 40, 2):
  212.     h.append(np.pi / (50 - i))
  213.  
  214. er_ex = np.zeros(len(h))
  215. tau = time / K
  216.  
  217. for i in range(len(h)):
  218.     x = np.arange(0, np.pi / 2 + h[i] / 2 - 1e-4, h[i])
  219.  
  220.     if a * tau / h[i] ** 2 <= 0.5:
  221.         Uex_1 = explicit(K, t, tau, h[i], a, c, x, 1)
  222.  
  223.     er_ex[i] = max(abs(analyt_func(x, a, c, T[t1]) - Uex_1[t1, :]))
  224.  
  225. print(er_ex)
  226.  
  227. plt.title('Ошибка явной схемы')
  228. plt.xlabel('h')
  229. plt.ylabel('error')
  230. plt.plot(h, er_ex)
  231. plt.show()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement