Dans ma réponse à une question sur MSE concernant une simulation physique hamiltonienne 2D, j'ai suggéré d'utiliser un intégrateur symplectique d' ordre supérieur .
Ensuite, j'ai pensé que ce pourrait être une bonne idée de démontrer les effets de différents pas de temps sur la précision globale des méthodes avec différents ordres, et j'ai écrit et exécuté un script Python / Pylab à cet effet. Pour comparaison j'ai choisi:
- ( leap2 ) Exemple de second ordre de Wikipédia que je connais bien que je le connaisse sous le nom de leapfrog ,
- ( ruth3 ) L'intégrateur symplectique de 3e ordre de Ruth ,
- ( ruth4 ) L'intégrateur symplectique de 4ème ordre de Ruth .
Ce qui est étrange, quel que soit le pas de temps que je choisis, la méthode de 3e ordre de Ruth semble être plus précise dans mon test que la méthode de 4e ordre de Ruth, même d'un ordre de grandeur.
Ma question est donc la suivante: que fais-je de mal ici? Détails ci-dessous.
Les méthodes déploient leur force dans des systèmes avec des hamiltoniens séparables , c'est-à-dire ceux qui peuvent être écrits comme
où comprend toutes les coordonnées de position,
comprend les moments conjugués,
représente la cinétique énergie et énergie potentielle
Dans notre configuration, nous pouvons normaliser les forces et les impulsions par les masses auxquelles elles sont appliquées. Ainsi, les forces se transforment en accélérations et les impulsions se transforment en vitesses.
Les intégrateurs symplectiques sont livrés avec des coefficients spéciaux (donnés, constants) que je et . Avec ces coefficients, une étape pour faire évoluer le système du temps au temps prend la forme
Pour :
- Calculer le vecteur de toutes les accélérations, étant donné le vecteur de toutes les positions
- Changer le vecteur de toutes les vitesses de
- Changer le vecteur de toutes les positions par
La sagesse réside maintenant dans les coefficients. Ce sont
Pour les tests, j'ai choisi le problème de valeur initiale 1D
qui a un hamiltonien séparable. Ici, sont identifiés par .
J'ai intégré l'IVP avec les méthodes ci-dessus sur avec un pas de avec un entier choisi entre et . Compte tenu de la vitesse de leap2 , j'ai triplé pour cette méthode. J'ai ensuite tracé les courbes résultantes dans l'espace des phases et zoomé à où les courbes devraient idéalement arriver à nouveau à .N(1,0)t=2π
Voici des tracés et des zooms pour et :
Pour , le saut 2 avec la taille de pas arrive plus près de la maison que ruth4 avec la taille de pas . Pour , ruth4 l' emporte sur leap2 . Cependant, ruth3 , avec la même taille de pas que ruth4 , arrive beaucoup plus près de chez nous que les deux autres, dans tous les paramètres que j'ai testés jusqu'à présent.2 π 2π
Voici le 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()
J'ai déjà vérifié les erreurs simples:
- Aucune faute de frappe sur Wikipedia. J'ai vérifié les références, notamment ( 1 , 2 , 3 ).
- J'ai la bonne séquence de coefficients. Si vous comparez avec l'ordre de Wikipédia, notez que le séquencement de l'application opérateur fonctionne de droite à gauche. Ma numérotation est en accord avec Candy / Rozmus . Et si j'essaye quand même une autre commande, les résultats empirent.
Mes soupçons:
- Mauvais ordre de taille: peut-être que le schéma de 3e ordre de Ruth a des constantes implicites beaucoup plus petites, et si la taille de pas était vraiment petite, alors la méthode de 4e ordre gagnerait? Mais j'ai même essayé , et la méthode du 3ème ordre est toujours supérieure.
- Mauvais test: quelque chose de spécial dans mon test permet à la méthode de 3e ordre de Ruth de se comporter comme une méthode de plus haut niveau?
la source
Réponses:
Suite à la suggestion de Kirill , j'ai exécuté le test avec partir d'une liste de valeurs grossièrement géométriquement croissantes, et pour chaque calculé l'erreur comme où représente l'approximation obtenu par intégration numérique. Voici le résultat dans un tracé log-log:N ϵ ( N ) = ‖ ˜ z ( 2 π ) - ˜ z ( 0 ) ‖ 2N N ˜ z
Donc ruth3 a en effet le même ordre que ruth4 pour ce cas de test et des constantes implicites de seulement magnitude.14 1100
Intéressant. Je vais devoir enquêter davantage, peut-être en essayant d'autres tests.
À propos, voici les ajouts au script Python pour le tracé d'erreur:
la source
Tracer l'erreur de , sur l'intervalle complet, mis à l'échelle par la puissance de la taille de pas donnée par l'ordre attendu, donne les tracésq¨=−q q(0)=1,q˙(0)=0
Comme prévu, les graphiques pour l'augmentation du nombre de sous-intervalles se rapprochent de plus en plus d'une courbe limite qui est le coefficient d'erreur principal. Dans toutes les parcelles sauf une, cette convergence est visiblement rapide, il n'y a presque pas de divergence. Cela signifie que même pour des tailles de pas relativement grandes, le terme d'erreur dominant domine tous les autres termes.
Dans la méthode Ruth du 3ème ordre, le coefficient de tête de la composante semble être nul, la courbe limite visible est proche ou égale à l'axe horizontal. Les graphiques visibles montrent clairement la dominance du terme d'erreur du 4ème ordre. La mise à l'échelle pour une erreur de 4e ordre donne un tracé similaire aux autres.p
Comme on peut le voir, dans les 3 cas, le coefficient d'erreur de l'ordre principal dans la composante est nul à après une période complète. En combinant les erreurs des deux composantes, le comportement de la composante domine donc, donnant faussement l'impression d'une méthode de 4ème ordre dans le graphique du loglog.q t=2π p
Un coefficient maximal dans la composante peut être trouvé autour de . Le tracé du journal devrait refléter les ordres d'erreur globale corrects.q 3π/2
Le fait que la disparition du terme d'erreur du 3ème degré dans Ruth3p soit un artefact de la simplicité de l'équation linéaire montre l'exemple non linéaire , avec les tracés correspondantsq¨=−sin(q) q(0)=1.3, q˙(0)=0
la source