Загрузка данных
import numpy as np
import matplotlib.pyplot as plt
# Общие параметры
KAPPA = 0.5
X_MIN, X_MAX = -5.0, 5.0
def exact_solution(x, t, kappa=KAPPA):
"""Точное решение задачи Коши для u_t = kappa * u_xx."""
return np.exp(-x**2 / (1 + 4 * kappa * t)) / np.sqrt(1 + 4 * kappa * t)
def solve_explicit(dx, T, kappa=KAPPA, r_target=0.4):
"""
Явная разностная схема для уравнения теплопроводности.
Возвращает: x, u, dt, число шагов по времени, фактическое r.
"""
n_x = int(round((X_MAX - X_MIN) / dx)) + 1
x = np.linspace(X_MIN, X_MAX, n_x)
# Подбираем dt так, чтобы r было около r_target, а конечное время было ровно T
dt0 = r_target * dx**2 / kappa
n_t = int(np.ceil(T / dt0))
dt = T / n_t
r = kappa * dt / dx**2
# Начальное условие u(x, 0) = exp(-x^2)
u = exact_solution(x, 0.0, kappa)
# Явная схема: обновляем только внутренние узлы
for _ in range(n_t):
u_new = np.zeros_like(u)
u_new[1:-1] = u[1:-1] + r * (u[:-2] - 2 * u[1:-1] + u[2:])
# Граничные условия: u = 0
u = u_new
return x, u, dt, n_t, r
def task1():
print("\n=== Задание 1. Точное решение ===")
x = np.linspace(X_MIN, X_MAX, 201)
times = [0.0, 0.2, 0.5, 1.0]
plt.figure(figsize=(9, 5))
for t in times:
u = exact_solution(x, t)
umax = np.max(u)
print(f"t = {t:.1f}: max u = {umax:.6f}")
plt.plot(x, u, label=f"t = {t:.1f}")
plt.title("Точное решение уравнения теплопроводности")
plt.xlabel("Координата x")
plt.ylabel("Температура u(x,t)")
plt.grid(True)
plt.legend()
plt.tight_layout()
plt.show()
def task2():
print("\n=== Задание 2. Численное решение явной схемой ===")
dx = 0.1
T = 1.0
x, u, dt, n_t, r = solve_explicit(dx, T, kappa=KAPPA, r_target=0.4)
print(f"dx = {dx}")
print(f"dt = {dt:.8f}")
print(f"Число шагов по времени = {n_t}")
print(f"Коэффициент r = {r:.6f}")
print("Условие устойчивости r <= 0.5:", r <= 0.5)
plt.figure(figsize=(9, 5))
plt.plot(x, u, label="численное решение, T = 1.0")
plt.title("Численное решение при T = 1.0")
plt.xlabel("Координата x")
plt.ylabel("Температура u")
plt.grid(True)
plt.legend()
plt.tight_layout()
plt.show()
return x, u, T
def task3(x, u_num, T):
print("\n=== Задание 3. Сравнение численного и точного решений ===")
u_exact = exact_solution(x, T)
error = np.abs(u_num - u_exact)
max_error = np.max(error)
print(f"Максимальная абсолютная ошибка = {max_error:.6e}")
plt.figure(figsize=(9, 5))
plt.plot(x, u_num, label="численное решение")
plt.plot(x, u_exact, "--", label="точное решение")
plt.title("Сравнение численного и точного решений при T = 1.0")
plt.xlabel("Координата x")
plt.ylabel("Температура u")
plt.grid(True)
plt.legend()
plt.tight_layout()
plt.show()
plt.figure(figsize=(9, 5))
plt.plot(x, error)
plt.title("Абсолютная ошибка по координате")
plt.xlabel("Координата x")
plt.ylabel("|u_числ - u_точн|")
plt.grid(True)
plt.tight_layout()
plt.show()
def task4():
print("\n=== Задание 4. Влияние шага сетки ===")
T = 1.0
dx_values = [0.2, 0.1, 0.05]
print(f"{'dx':>8} {'dt':>14} {'узлы':>8} {'шаги':>8} {'max error':>16} {'r':>10}")
print("-" * 70)
for dx in dx_values:
x, u, dt, n_t, r = solve_explicit(dx, T, kappa=KAPPA, r_target=0.4)
u_exact = exact_solution(x, T)
max_error = np.max(np.abs(u - u_exact))
print(
f"{dx:8.2f} {dt:14.8f} {len(x):8d} {n_t:8d} "
f"{max_error:16.6e} {r:10.6f}"
)
def task5():
print("\n=== Задание 5. Эксперимент с устойчивостью ===")
dx = 0.1
T = 0.5
plt.figure(figsize=(9, 5))
for name, r_target in [("A", 0.4), ("B", 0.6)]:
x, u, dt, n_t, r = solve_explicit(dx, T, kappa=KAPPA, r_target=r_target)
max_abs_u = np.max(np.abs(u))
print(f"\nВариант {name}:")
print(f" r_target = {r_target}")
print(f" фактическое r = {r:.6f}")
print(f" dt = {dt:.8f}")
print(f" число шагов = {n_t}")
print(f" max|u| на последнем слое = {max_abs_u:.6e}")
plt.plot(x, u, label=f"{name}: r = {r:.3f}, max|u| = {max_abs_u:.2e}")
plt.title("Влияние устойчивости явной схемы при T = 0.5")
plt.xlabel("Координата x")
plt.ylabel("Температура u")
plt.grid(True)
plt.legend()
plt.tight_layout()
plt.show()
def main():
task1()
x, u_num, T = task2()
task3(x, u_num, T)
task4()
task5()
if __name__ == "__main__":
main()