Тест симплектичного інтегратора 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]=[23−23172434−124](ruth3)[a1a2a3a4b1b2b3b4]=12−23[121−2321−2321201−231](ruth4)

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

y″+y=0y(0)=1y′(0)=0
∴(y(t),y′(t))=(cos⁡t,−sin⁡t)
який має відокремлений гамільтоніан. Тут(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
p0≠0V(q)=1/q+log⁡qV має мало високих похідних, але в моїх тестах, здається, початкові умови та періодичність мають більше спільного з цим.
— Кирило

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.