Na minha resposta a uma pergunta no MSE referente a uma simulação física hamiltoniana 2D, sugeri o uso de um integrador simplético de ordem superior .
Então achei que seria uma boa ideia demonstrar os efeitos de diferentes etapas no tempo na precisão global de métodos com ordens diferentes, e escrevi e executei um script Python / Pylab para esse efeito. Para comparação, eu escolhi:
- ( salto 2 ) O exemplo de 2ª ordem da Wikipedia com o qual eu estou familiarizado, embora eu conheça com o nome de salto ,
- ( ruth3 ) O integrador simplético de terceira ordem de Ruth ,
- ( ruth4 ) Integrador simplético de quarta ordem de Ruth .
O estranho é que, qualquer que seja o passo que eu escolher, o método de 3ª ordem de Ruth parece ser mais preciso em meu teste do que o método de 4ª ordem de Ruth, mesmo que por uma ordem de magnitude.
Minha pergunta é, portanto: o que estou fazendo de errado aqui? Detalhes abaixo.
Os métodos desdobram sua força em sistemas com hamiltonianos separáveis , ou seja, aqueles que podem ser escritos como
Em nossa configuração, podemos normalizar forças e momentos pelas massas às quais são aplicadas. Assim, as forças se transformam em acelerações, e os momentos se transformam em velocidades.
Os integradores simpléticos vêm com coeficientes especiais (dados, constantes) que vou rotular como e . Com esses coeficientes, um passo para a evolução do sistema de tempos ao tempo toma a forma
Para :
- Calcular o vetor de todas as acelerações, dado o vetor de todas as posições
- Altere o vetor de todas as velocidades por
- Altere o vetor de todas as posições por
A sabedoria agora reside nos coeficientes. Estes são
Para testar, escolhi o problema do valor inicial 1D
Integrei o IVP com os métodos acima em com um tamanho escalonado de com um número inteiroescolhido entree. Levandoem conta a velocidade dosalto 2,tripliqueinesse método. Em seguida, plotei as curvas resultantes no espaço de fase e ampliei o zoom em onde as curvas deveriam idealmente chegar novamente em.
Aqui estão plotagens e zooms para e :
Para , salto 2 com o tamanho da etapa chega mais perto de casa do queruth4 com tamanho de passo . Para,ruth4vence osalto2. No entanto, oruth3, com o mesmo tamanho de passo que oruth4, chega muito mais perto de casa que os outros, em todas as configurações que testei até agora.
Aqui está o 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()
Eu já verifiquei erros simples:
- Nenhum erro de digitação da Wikipedia. Eu verifiquei as referências, em particular ( 1 , 2 , 3 ).
- Eu tenho a sequência do coeficiente correta. Se você comparar com os pedidos da Wikipedia, observe que o seqüenciamento do aplicativo do operador funciona da direita para a esquerda. Minha numeração concorda com Candy / Rozmus . E se eu tentar outro pedido, no entanto, os resultados pioram.
Minhas suspeitas:
- Ordem de tamanho de etapa incorreta: Talvez o esquema de terceira ordem de Ruth possua constantes implícitas muito menores e, se o tamanho da etapa fosse muito pequeno, o método de quarta ordem venceria? Mas eu até tentei , e o método de terceira ordem ainda é superior.
- Teste errado: algo especial no meu teste permite que o método de terceira ordem de Ruth se comporte como um método de ordem superior?
fonte
Respostas:
Seguindo Kirill sugestão 's, corri o teste com a partir de uma lista de valores de cerca de geometricamente crescentes, e para cada um de N calculado como o erro ε ( N ) = ‖ ~ Z ( 2 π ) - ~ z ( 0 ) ‖ doisN N
onde ˜ z representa a aproximação obtida pela integraçao numérica. Aqui está o resultado em um gráfico de log-log:
Portanto, ruth3 realmente tem a mesma ordem que ruth4 para esse caso de teste e constantes implícitas de apenas 14 a magnitude.1 1100
Interessante. Vou ter que investigar mais, talvez tentando outros testes.
A propósito, aqui estão as adições ao script Python para o gráfico de erros:
fonte
Como esperado, os gráficos para aumentar o número de subintervalos aproximam-se cada vez mais de uma curva limite que é o principal coeficiente de erro. Em apenas um gráfico, essa convergência é visivelmente rápida, quase não há divergências. Isso significa que, mesmo para tamanhos de etapas relativamente grandes, o termo de erro principal domina todos os outros termos.
fonte