Тест симплектичного інтегратора 3-го порядку проти 4-го порядку із дивним результатом


10

У своїй відповіді на запитання про MSE щодо 2D-моделювання фізики Гамільтонів я запропонував використовувати симплектичний інтегратор вищого порядку .

Тоді я подумав, що може бути гарною ідеєю продемонструвати вплив різних часових кроків на глобальну точність методів з різними порядками, і я написав і запустив сценарій Python / Pylab для цього ефекту. Для порівняння я вибрав:

Дивна річ у тому, який би часовий крок я не вибрав, метод Рут 3-го порядку здається більш точним у моєму тесті, ніж метод Рут 4-го порядку, навіть на порядок.

Моє запитання тому: що я тут роблю неправильно? Деталі нижче.

Методи розгортають свою силу в системах з відокремленими гамільтоніанами, тобто в тих, які можна записати як

H(q,p)=T(p)+V(q)
де q містить усі координати положення, p містить спряжений момент, T являє кінетичну енергія та V потенційна енергія.

У нашому налаштуванні ми можемо нормалізувати сили та імпульси за допомогою мас, до яких вони застосовуються. Таким чином сили перетворюються на прискорення, а моменти перетворюються на швидкості.

Симплектична інтегратори йдуть зі спеціальними (враховуючи, постійні) коефіцієнти , які я маркують a1,,an і b1,,bn . З цими коефіцієнтами один крок для розвитку системи від часу t до часу t+δt приймає форму

  • Для i=1,,n :

    1. Обчисліть вектор g всіх прискорень, задавши вектор q усіх положень
    2. Змініть вектор v усіх швидкостей на bigδt
    3. Зміна вектора q всіх позицій по aivδt

Мудрість тепер полягає в коефіцієнтах. Це

[a1a2b1b2]=[121201](leap2)[a1a2a3b1b2b3]=[2323172434124](ruth3)[a1a2a3a4b1b2b3b4]=1223[12123212321201231](ruth4)

Для тестування я вибрав задачу з початковим значенням 1D

y+y=0y(0)=1y(0)=0
(y(t),y(t))=(cost,sint)
який має відокремлений гамільтоніан. Тут(q,v) ототожнюються з(y,y) .

Я інтегрував IVP з вищезазначеними методами над t[0,2π] зі ступенем розміру δt=2πN з цілим числомNобраним десь між10 і 100 . Враховуючи швидкість стрибка2 , я потроїв N для цього методу. Потім я побудував отримані криві у фазовому просторі і збільшив масштаб (1,0) де криві в ідеалі повинні знову прийти до t=2π .

Ось графіки та масштаби для N=12 та N=36 :

N = 12N = 12, збільшення

N = 36N = 36, збільшення

Для N=12 , стрибок2 з розміром кроку 2π3N2πNN=36

Ось сценарій Python / Pylab:

import numpy as np
import matplotlib.pyplot as plt

def symplectic_integrate_step(qvt0, accel, dt, coeffs):
    q,v,t = qvt0
    for ai,bi in coeffs.T:
        v += bi * accel(q,v,t) * dt
        q += ai * v * dt
        t += ai * dt
    return q,v,t

def symplectic_integrate(qvt0, accel, t, coeffs):
    q = np.empty_like(t)
    v = np.empty_like(t)
    qvt = qvt0
    q[0] = qvt[0]
    v[0] = qvt[1]
    for i in xrange(1, len(t)):
        qvt = symplectic_integrate_step(qvt, accel, t[i]-t[i-1], coeffs)
        q[i] = qvt[0]
        v[i] = qvt[1]
    return q,v

c = np.math.pow(2.0, 1.0/3.0)
ruth4 = np.array([[0.5, 0.5*(1.0-c), 0.5*(1.0-c), 0.5],
                  [0.0,         1.0,          -c, 1.0]]) / (2.0 - c)
ruth3 = np.array([[2.0/3.0, -2.0/3.0, 1.0], [7.0/24.0, 0.75, -1.0/24.0]])
leap2 = np.array([[0.5, 0.5], [0.0, 1.0]])

accel = lambda q,v,t: -q
qvt0 = (1.0, 0.0, 0.0)
tmax = 2.0 * np.math.pi
N = 36

fig, ax = plt.subplots(1, figsize=(6, 6))
ax.axis([-1.3, 1.3, -1.3, 1.3])
ax.set_aspect('equal')
ax.set_title(r"Phase plot $(y(t),y'(t))$")
ax.grid(True)
t = np.linspace(0.0, tmax, 3*N+1)
q,v = symplectic_integrate(qvt0, accel, t, leap2)
ax.plot(q, v, label='leap2 (%d steps)' % (3*N), color='black')
t = np.linspace(0.0, tmax, N+1)
q,v = symplectic_integrate(qvt0, accel, t, ruth3)
ax.plot(q, v, label='ruth3 (%d steps)' % N, color='red')
q,v = symplectic_integrate(qvt0, accel, t, ruth4)
ax.plot(q, v, label='ruth4 (%d steps)' % N, color='blue')
ax.legend(loc='center')
fig.show()

Я вже перевірив прості помилки:

  • Немає друку у Вікіпедії. Я перевірив посилання, зокрема ( 1 , 2 , 3 ).
  • Я правильно зрозумів послідовність коефіцієнтів. Якщо ви порівнюєте з замовленням Вікіпедії, зауважте, що послідовність роботи програми оператора працює справа наліво. Моя нумерація погоджується з Candy / Rozmus . І якщо я все ж спробую інше замовлення, результати погіршаться.

Мої підозри:

  • N=360
  • Неправильний тест: Щось особливе в моєму тесті дозволяє методу Рут 3-го порядку вести себе як метод вищого порядку?

Чи можете ви навести числові значення помилок? Трохи важко сказати з сюжету. Як масштабуються помилки зі зміною ? Чи вони масштабують, як очікувалося від замовлень методів? Зазвичай можна побудувати помилки проти N на графіку журналу журналу, щоб перевірити це. NN
Кирило

@Kirill: Робота над цим. Незабаром відредагуємо
ccorn

1
Мені подобається одне, що є вибір лінійного резуса: помилки врізання методів зазвичай залежать від високої похідної резус, тому якщо всі високі похідні rhs зникають, ви можете спостерігати деяку дивну поведінку конвергенції. Напевно, варто спробувати більш незвичайний резус.
Кирило

Відповіді:


9

NN

ϵ(N)=z~(2π)z~(0)2wherez~(t)=(y~(t),y~(t))
z~

введіть тут опис зображення

41100

Цікаво. Мені доведеться досліджувати далі, можливо, пробуючи інші тести.

До речі, ось доповнення до сценарію Python для графіку помилок:

def int_error(qvt0, accel, qvt1, Ns, coeffs):
    e = np.empty((len(Ns),))
    for i,N in enumerate(Ns):
        t = np.linspace(qvt0[2], qvt1[2], N+1)
        q,v = symplectic_integrate(qvt0, accel, t, coeffs)
        e[i] = np.math.sqrt((q[-1]-qvt1[0])**2+(v[-1]-qvt1[1])**2)
    return e

qvt1 = (1.0, 0.0, tmax)
Ns = [12,16,20,24,32,40,48,64,80,96,128,160,192,
      256,320,384,512,640,768,1024,1280,1536,2048,2560,3072]

fig, ax = plt.subplots(1)
ax.set_xscale('log')
ax.set_xlabel(r"$N$")
ax.set_yscale('log')
ax.set_ylabel(r"$\|z(2\pi)-z(0)\|$")
ax.set_title(r"Error after 1 period vs #steps")
ax.grid(True)
e = int_error(qvt0, accel, qvt1, Ns, leap2)
ax.plot(Ns, e, label='leap2', color='black')
e = int_error(qvt0, accel, qvt1, Ns, ruth3)
ax.plot(Ns, e, label='ruth3', color='red')
e = int_error(qvt0, accel, qvt1, Ns, ruth4)
ax.plot(Ns, e, label='ruth4', color='blue')
ax.legend(loc='upper right')
fig.show()

Не стосується питання, але чи можете ви, будь ласка, вносити зміни та оновлення до самого питання, а не публікувати як окрему відповідь? Це може дотримуватись конвенції, що відповіді повинні відповісти на питання.
Кирило

1
@Kirill: Це є відповіддю. ruth3 справді має вищий порядок і менші константи. Виявлено через вашу пропозицію зробити графік помилки журналу журналу. Отже, на запитання дано відповідь, і я рішуче не змінюю суть питання після того, як на нього надійде відповідь, навіть якщо відповідь була складена мною.
ccorn

З цього приводу я би радий прийняти подальший аналіз. (Питання з
самовідповіддю

2
p00V(q)=1/q+logqV має мало високих похідних, але в моїх тестах, здається, початкові умови та періодичність мають більше спільного з цим.
Кирило

2
Це прояв суперконвергенції. Прості проблеми з тестом, як це, виникають у багатьох випадках. Використання лінійного рівняння може дати таку поведінку, і багато разів непарні умови серії Тейлора можуть скасувати, коли це станеться. Нелінійна проблема тесту без аналітичного рішення набагато рідше ця ситуація виникає.
Кріс Раккаукас

2

q¨=qq(0)=1,q˙(0)=0

введіть тут опис зображення

Як і очікувалося, графіки збільшення кількості під інтервалів все більше наближаються до граничної кривої, яка є провідним коефіцієнтом помилок. У всьому, крім одного сюжету, ця конвергенція помітно швидка, розбіжностей майже немає. Це означає, що навіть при відносно великих розмірах кроків провідний термін помилки домінує над усіма іншими термінами.

p компонента виявляється рівним нулю, видима гранична крива близька або дорівнює горизонтальній осі. На видимих ​​графіках чітко видно переважання терміна помилки 4-го порядку. Масштабування помилки четвертого порядку дає сюжет, подібний до інших.

qt=2πp

q3π/2


q¨=sin(q)q(0)=1.3, q˙(0)=0

введіть тут опис зображення

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.