Nella mia risposta a una domanda sull'MSE riguardante una simulazione di fisica hamiltoniana 2D, ho suggerito di utilizzare un integratore simplettico di ordine superiore .
Quindi ho pensato che sarebbe stata una buona idea dimostrare gli effetti di diversi passaggi temporali sull'accuratezza globale dei metodi con ordini diversi, e ho scritto ed eseguito uno script Python / Pylab in tal senso. Per confronto ho scelto:
- ( leap2 ) L'esempio del 2 ° ordine di Wikipedia con cui ho familiarità, sebbene lo conosca con il nome leapfrog ,
- ( ruth3 ) Integratore simplettico del 3 ° ordine di Ruth ,
- ( ruth4 ) Integratore simplettico del 4 ° ordine di Ruth .
La cosa strana è, qualunque sia il timestep che scelgo, il metodo del 3 ° ordine di Ruth sembra essere più accurato nel mio test rispetto al metodo del 4 ° ordine di Ruth, anche di un ordine di grandezza.
La mia domanda è quindi: cosa sto facendo di sbagliato qui? Dettagli sotto.
I metodi spiegano la loro forza in sistemi con Hamiltoniani separabili , cioè quelli che possono essere scritti come
Nella nostra configurazione, possiamo normalizzare forze e momenti in base alle masse a cui sono applicati. Quindi le forze si trasformano in accelerazioni e i momenti si trasformano in velocità.
Gli integratori simplettici vengono con coefficienti speciali (dati, costanti) che etichetterò e . Con questi coefficienti, un passo per far evolvere il sistema da tempo a tempo assume la forma
Per :
- Calcola il vettore di tutte le accelerazioni, dato il vettore di tutte le posizioni
- Cambia vettore di tutte le velocità di
- Cambia il vettore di tutte le posizioni con
La saggezza ora sta nei coefficienti. Questi sono
Per il test, ho scelto il problema del valore iniziale 1D
Ho integrato l'IVP con i metodi sopra sopra con una dimensione di con un numero interoscelto da qualche parte trae. Tenendocontodella velocità dileap2, ho triplicatoper quel metodo. Ho quindi tracciato le curve risultanti nello spazio delle fasi e ingrandito a dove le curve dovrebbero idealmente arrivare di nuovo a.
Ecco grafici e zoom per e :
Per , leap2 con passo sembra arrivare più vicino a casa diruth4 con passo . Per,ruth4vince sulsalto2. Tuttavia,ruth3, con le stesse dimensioni diruth4, arriva molto più vicino a casa di entrambi gli altri, in tutte le impostazioni che ho testato finora.
Ecco lo script 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()
Ho già verificato errori semplici:
- Nessun refuso di Wikipedia. Ho verificato i riferimenti, in particolare ( 1 , 2 , 3 ).
- Ho corretto la sequenza dei coefficienti. Se si confronta con l'ordinamento di Wikipedia, notare che il sequenziamento dell'applicazione operatore funziona da destra a sinistra. La mia numerazione concorda con Candy / Rozmus . E se provo comunque un altro ordine, i risultati peggiorano.
I miei sospetti:
- Ordine errato di dimensioni ridotte: forse lo schema del 3 ° ordine di Ruth ha in qualche modo costanti implicite molto più piccole, e se la dimensione del passo fosse resa davvero piccola, allora il metodo del 4 ° ordine vincerebbe? Ma ho anche provato e il metodo del 3 ° ordine è ancora superiore.
- Test sbagliato: qualcosa di speciale nel mio test consente al metodo di Ruth di 3 ° ordine di comportarsi come un metodo di ordine superiore?