Teste de integrador simplético de terceira ordem vs de quarta ordem com resultado estranho

10

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:

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

H(q,p)=T(p)+V(q)
onde compreende todas as coordenadas de posição, compreende a momenta conjugada, representa cinética energia e energia potencialqpTV

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 formaa1,,anb1,,bntt+δt

  • Para :Eu=1 1,,n

    1. Calcular o vetor de todas as acelerações, dado o vetor de todas as posiçõesgq
    2. Altere o vetor de todas as velocidades porvbEugδt
    3. Altere o vetor q de todas as posições por umaEuvδt

A sabedoria agora reside nos coeficientes. Estes são

[uma1 1uma2b1 1b2]=[1 121 120 01 1](salto 2)[uma1 1uma2uma3b1 1b2b3]=[23-231 172434-1 124](rute3)[uma1 1uma2uma3uma4b1 1b2b3b4]=1 12-23[1 121 1-2321 1-2321 120 01 1-231 1](rute4)

Para testar, escolhi o problema do valor inicial 1D

y+y=0 0y(0 0)=1 1y(0 0)=0 0
(y(t),y(t))=(porquet,-pecadot)
que possui um hamiltoniano separável. Aqui,(q,v)são identificados com(y,y).

Integrei o IVP com os métodos acima em t[0 0,2π] com um tamanho escalonado de δt=2πN com um número inteiroNescolhido entre10e100. Levandoem conta a velocidade dosalto 2,tripliqueiNnesse método. Em seguida, plotei as curvas resultantes no espaço de fase e ampliei o zoom em(1 1,0 0) onde as curvas deveriam idealmente chegar novamente emt=2π.

Aqui estão plotagens e zooms para N=12 e N=36. :

N = 12N = 12, ampliado

N = 36N = 36, ampliada

Para N=12 , salto 2 com o tamanho da etapa 2π3N chega mais perto de casa do queruth4 com tamanho de passo2πN . ParaN=36.,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 N=360 , 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?
ccorn
fonte
Você pode fornecer valores numéricos de erros? É um pouco difícil dizer da trama. Como os erros são dimensionados com a alteração de ? Eles escalam conforme o esperado a partir das ordens dos métodos? Geralmente, é possível plotar erros contra N em um gráfico de log-log para verificar isso. NN
Kirill
@ Kirill: Trabalhando nisso. Editará em breve.
Ccorn 22/08/2015
11
Suspeito de uma coisa é a escolha de um rhs linear: os erros de truncamento dos métodos geralmente dependem de alguma derivada alta do rhs; portanto, se todos os derivados altos do rhs desaparecerem, você poderá observar algum comportamento estranho de convergência. Provavelmente vale a pena tentar um rhs mais incomum.
22415 Kirill

Respostas:

9

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 ) doisNN onde ˜ z representa a aproximação obtida pela integraçao numérica. Aqui está o resultado em um gráfico de log-log:

ϵ(N)=__z~(2π)-z~(0 0)__2Ondez~(t)=(y~(t),y~(t))
z~

insira a descrição da imagem aqui

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:

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()
ccorn
fonte
Não é relevante para a pergunta, mas você pode colocar alterações e atualizações na própria pergunta, em vez de postar como uma resposta separada? Isso mantém a convenção de que as respostas devem responder à pergunta.
22415 Kirill
11
@Kirill: Ele é uma resposta. ruth3 realmente tem ordem superior e constantes menores aqui. Descoberto por sua sugestão de fazer um gráfico de erros de log-log. A pergunta é, portanto, respondida, e decididamente não mudarei o ponto de uma pergunta depois que ela for respondida, mesmo que a resposta tenha sido composta por mim.
Ccorn 22/08/2015
Dito isto, ficaria feliz em aceitar mais análises. (Perguntas de auto-respondidas ser aceito automaticamente, mas pode-se mudar isso suponho.)
ccorn
2
p0 00 0V(q)=1 1/q+registroqV
Kirill
2
Esta é uma demonstração de superconvergência. Problemas simples de teste como esse acabam tendo esse problema em muitos casos. O uso de uma equação linear pode dar esse comportamento, e muitas vezes os termos ímpares de uma série de Taylor podem ser cancelados quando isso acontece. Um problema de teste não linear sem uma solução analítica tem muito menos probabilidade de que isso ocorra.
Chris Rackauckas
2

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

insira a descrição da imagem aqui

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.

p

qt=2πp

q3π/2


q¨=-pecado(q)q(0 0)=1.3, q˙(0 0)=0 0

insira a descrição da imagem aqui

Lutz Lehmann
fonte