Сохранение энергии как тест интегратора
Хотите узнать, какой интегратор лучше? Прогоните его подольше и посмотрите на энергию — она не врёт.
Дрейф энергии — систематическое отклонение полной энергии симуляции от истинного постоянного значения, вызванное численным методом.
Энергия как объективный судья
В первых разделах мы интуитивно говорили: явный Эйлер «раздувает» энергию, симплектические методы — нет. Теперь у нас есть инструмент, чтобы это измерить. Возьмём одну и ту же физическую задачу (осциллятор $a = -x$), одни и те же шаг и длительность, и прогоним тремя методами, сравнив итоговую энергию с начальной. Отношение $E/E_0$ — честная оценка качества: идеал — единица, отклонение — мера погрешности.
Тройное сравнение
def run(method, dt=0.05, T=50.0):
x, v = 1.0, 0.0
if method == "verlet":
a = -x
xp = x - v*dt + 0.5*a*dt*dt
for _ in range(int(T/dt)):
a = -x
if method == "euler":
xn = x + v*dt; v = v + a*dt; x = xn
elif method == "semi":
v = v + a*dt; x = x + v*dt
elif method == "verlet":
xn = 2*x - xp + a*dt*dt; xp, x = x, xn
if method == "verlet":
v = (x - xp)/dt
return (0.5*v*v + 0.5*x*x) / 0.5
for m, name in [("euler", "явный Эйлер"),
("semi", "полу-неявный"),
("verlet","Верле")]:
print(f"{name:14s}: E/E0 = {run(m):.4f}")
Вывод:
явный Эйлер : E/E0 = 12.1445 полу-неявный : E/E0 = 1.0125 Верле : E/E0 = 1.0130
Приговор однозначен. За $50$ секунд явный Эйлер раздул энергию в $12$ раз — в такой симуляции маятник раскачался бы до абсурда, а планета улетела бы. Полу-неявный Эйлер и Верле удержали энергию в пределах $1.3\%$ от исходной — оба пригодны для долгой работы. Это численное подтверждение всего, что мы обсуждали теоретически: симплектичность решает.
Что именно измеряет тест
Дрейф энергии ловит самую коварную ошибку — систематическую, ту, что копится в одну сторону. Случайный шум усреднился бы и не вырос, но направленный дрейф энергии за тысячи шагов превращается в катастрофу. Поэтому энергетический тест особенно ценен для долгих симуляций: орбит, молекулярной динамики, тканей. Короткие задачи (одиночный бросок на пару секунд) такой тест может и не завалить даже у плохого метода — но в долгой работе он беспощаден.
Как работает под капотом
Тонкость симплектических методов: они сохраняют не точную энергию, а близкую «теневую» величину, поэтому реальная $E$ слегка колеблется (наши $1.3\%$) — но не дрейфует. На графике это выглядит как лёгкая рябь вокруг постоянного уровня, а не как восходящая или нисходящая линия. Именно отсутствие тренда, а не идеальная константа, — признак хорошего метода. Полезный приём при разработке движка: завести функцию, считающую полную энергию системы, и в отладочном режиме печатать её каждые $N$ шагов. Линия с трендом мгновенно укажет на проблему — будь то неверный интегратор, утечка из-за коллизий или ошибка в силах.
Частые ошибки
- Судить о методе по короткому прогону. На паре секунд даже явный Эйлер может выглядеть прилично; дефект виден только на длинной дистанции.
- Ожидать строгой константы у симплектического метода. Колебание энергии нормально; важно отсутствие тренда.
- Сравнивать методы при разных шагах. Честное сравнение — при одинаковых $\Delta t$ и $T$; иначе вывод нечестный.
Итог
- Отношение $E/E_0$ после долгого прогона — объективная оценка интегратора.
- Явный Эйлер раздувает энергию в разы; симплектические методы удерживают её около $1$.
- Тест ловит систематический дрейф — самую опасную ошибку долгих симуляций.
- Признак хорошего метода — отсутствие тренда энергии, а не идеальная константа.