Распространение звуковой волны от источника к стене очень долгое, настолько долгое что это просто невозможно.
Максимально оптимизируй код
```python
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from numba import njit

# Параметры волны
c = 343.0             # Скорость звука в воздухе (м/с)
f = 5.0               # Частота источника (Гц)
omega = 2 * np.pi * f # Угловая частота
k = omega / c         # Волновое число

# Параметры области моделирования
nx, ny = 200, 100        # Количество точек по осям X и Y
dx = 0.02                # Расстояние между точками по X (метры)
dy = dx                  # Расстояние между точками по Y (метры)

x = np.linspace(0, (nx-1)*dx, nx)
y = np.linspace(0, (ny-1)*dy, ny)
X, Y = np.meshgrid(x, y)

# Параметры временной дискретизации
dt = 0.3 * dx / c        # Временной шаг (секунды), согласно условию стабильности CFL
nt = 800                 # Количество временных шагов

# Инициализация полей давления
p_prev = np.zeros((ny, nx), dtype=np.float32)   # p at time t - dt
p = np.zeros((ny, nx), dtype=np.float32)        # p at time t
p_next = np.zeros((ny, nx), dtype=np.float32)   # p at time t + dt

# Параметры источника
source_x_cell, source_y_cell = 40, ny // 2    # Позиция источника в ячейках сетки
source_radius = 5                             # Радиус источника (в ячейках сетки)

# Коэффициент затухания
alpha = 0.002  # Затухание волны

# Создание маски источника
distance = np.sqrt((X - x[source_x_cell])**2 + (Y - y[source_y_cell])**2)
source_mask = distance <= (source_radius * dx)

# Усиление амплитуды источника для лучшей видимости
source_amplitude = 1.0

@njit
def update_wave_numba(p_prev, p, p_next, omega, dt, c, alpha, source_mask, source_amplitude, t):
    ny, nx = p.shape
    for i in range(1, ny-1):
        for j in range(1, nx-1):
            laplacian = (p[i+1, j] + p[i-1, j] + p[i, j+1] + p[i, j-1] - 4.0 * p[i, j]) / dx**2
            p_next[i, j] = (2.0 * p[i, j] - p_prev[i, j] + (c**2 * dt**2) * laplacian) - alpha * (p_next[i, j] - p_prev[i, j])
    # Добавление источника
    for i in range(ny):
        for j in range(nx):
            if source_mask[i, j]:
                p_next[i, j] += source_amplitude * np.sin(omega * t) * dt**2
    return p_next

# Граничные условия
@njit
def apply_boundary_conditions_numba(p):
    ny, nx = p.shape
    # Правая грань (стена) - отражающая
    for i in range(ny):
        p[i, nx-1] = p[i, nx-2]
    # Левая грань (поглощающая)
    for i in range(ny):
        p[i, 0] = p[i, 1]
    # Верхняя граница (поглощающая)
    for j in range(nx):
        p[0, j] = p[1, j]
    # Нижняя граница (поглощающая)
    for j in range(nx):
        p[ny-1, j] = p[ny-2, j]
    return p

# Настройка графика
fig, ax = plt.subplots(figsize=(12, 6))
# Инициализация с первого кадра
initial_p = p.copy()
cax = ax.imshow(initial_p, extent=(x.min(), x.max(), y.min(), y.max()),
                cmap='RdBu', vmin=-source_amplitude, vmax=source_amplitude, origin='lower')
ax.set_title('Распространение звуковой волны от источника к стене')
ax.set_xlabel('X (м)')
ax.set_ylabel('Y (м)')
fig.colorbar(cax, label='Звуковое давление')

# Рисование стены (правая грань)
ax.axvline(x=(nx-1)*dx, color='k', linewidth=2, label='Стена')
# Добавление маркера источника (условный человек)
ax.plot(x[source_x_cell], y[source_y_cell], 'ko', markersize=8, label='Источник')
ax.legend(loc='upper right')

# Функция обновления для анимации
def animate(frame):
    global p_prev, p, p_next
    t = frame * dt
    p_next = update_wave_numba(p_prev, p, p_next, omega, dt, c, alpha, source_mask, source_amplitude, t)
    p_next = apply_boundary_conditions_numba(p_next)
    
    # Обновление полей
    p_prev, p = p, p_next

    # Обновление визуализации
    cax.set_data(p)
    ax.set_title(f'Распространение звуковой волны от источника к стене\nВремя: {t:.3f} с')
    return [cax]

# Создание анимации
ani = animation.FuncAnimation(
    fig, animate, frames=nt, interval=30, blit=False, repeat=False
)

# Отображение анимации
plt.show()
```