Метод Верле: точность через память о прошлом
Верле не хранит скорость явно — он помнит, где тело было шаг назад, и этого достаточно.
Метод Верле — симплектический интегратор второго порядка, вычисляющий новое положение по текущему, предыдущему положениям и ускорению, без явного хранения скорости.
Идея метода
Запишем разложение положения вперёд и назад по времени (ряд Тейлора) и сложим их. Члены с нечётными степенями (со скоростью) сократятся, и останется красивая формула:
$$x_{n+1} = 2 x_n - x_{n-1} + a_n \, \Delta t^2.$$
Скорость в неё вообще не входит! Чтобы продвинуть тело, достаточно знать его текущее и предыдущее положения и ускорение. Скорость, если нужна (например, для энергии), оценивается центральной разностью:
$$v_n \approx \frac{x_{n+1} - x_{n-1}}{2\Delta t}.$$
Метод имеет второй порядок точности — глобальная ошибка пропорциональна $\Delta t^2$. Это значит, что вдвое меньший шаг даёт вчетверо меньшую ошибку, а не вдвое, как у Эйлера. И при этом Верле тоже симплектичен — энергия не дрейфует.
Запуск симуляции
Тот же осциллятор $a = -x$, $\Delta t = 0.1$. Стартовую «предыдущую» точку $x_{-1}$ находим из начальной скорости. Следим за энергией.
x, v, dt = 1.0, 0.0, 0.1
a = -x
x_prev = x - v*dt + 0.5*a*dt*dt # стартовая «предыдущая» точка
for n in range(11):
a = -x
x_new = 2*x - x_prev + a*dt*dt
v_est = (x_new - x_prev) / (2*dt)
E = 0.5*v_est*v_est + 0.5*x*x
if n % 2 == 0:
print(f"n={n:2d} x={x:6.3f} v={v_est:6.3f} E={E:.4f}")
x_prev, x = x, x_new
Вывод:
n= 0 x= 1.000 v=-0.000 E=0.5000 n= 2 x= 0.980 v=-0.199 E=0.5000 n= 4 x= 0.921 v=-0.389 E=0.4998 n= 6 x= 0.825 v=-0.564 E=0.4996 n= 8 x= 0.696 v=-0.717 E=0.4994 n=10 x= 0.540 v=-0.841 E=0.4991
Энергия держится у $0.5$ практически идеально — отклонение в четвёртом знаке. Это заметно лучше полу-неявного Эйлера (который колебался около $0.48$) благодаря второму порядку точности. Неудивительно, что Верле — рабочая лошадка симуляций молекулярной динамики, тканей, верёвок и мягких тел.
Связь Верле с ограничениями
У Верле есть бонус, незаметный в формуле, но обожаемый разработчиками тканей. Поскольку скорость хранится неявно — как разность $x_n - x_{n-1}$, — можно прямо «телепортировать» точку в новое положение (например, чтобы две связанные точки не разъехались дальше длины нити), и скорость автоматически подстроится. В системах на пружинных связях (cloth, rope, ragdoll) это превращает обработку ограничений в простое подтягивание координат. Поэтому знаменитый физический движок ткани в играх 2000-х строился именно на Верле.
Как работает под капотом
Формула Верле — это центральная разность для второй производной: $a_n = \frac{x_{n+1} - 2x_n + x_{n-1}}{\Delta t^2}$, переписанная относительно $x_{n+1}$. Центральные разности симметричны во времени, поэтому метод не имеет систематического смещения вперёд или назад — отсюда и второй порядок, и отсутствие дрейфа энергии. Цена — нужно хранить две позиции и аккуратно инициализировать $x_{-1}$; неверный старт портит первые шаги.
Частые ошибки
- Неправильный старт $x_{-1}$. Если просто взять $x_{-1} = x_0$, начальная скорость окажется нулевой, что искажает движение. Используйте $x_{-1} = x_0 - v_0\Delta t + \frac{1}{2}a_0\Delta t^2$.
- Считать скорость наивно. В чистом Верле скорость — это центральная разность; «текущей» скорости в явном виде нет.
- Менять $\Delta t$ на лету. Классический Верле предполагает постоянный шаг; переменный шаг ломает симметрию (есть отдельные модификации).
Итог
- Верле: $x_{n+1}=2x_n-x_{n-1}+a_n\Delta t^2$, скорость хранится неявно.
- Второй порядок точности: ошибка $\sim \Delta t^2$; энергия почти не дрейфует.
- Идеален для тканей и связей: ограничения задаются прямым сдвигом координат.
- Требует аккуратной инициализации предыдущей точки и постоянного шага.