Equação de Klein-Gordon: mudanças entre as edições

De Física Computacional
Ir para navegação Ir para pesquisar
 
(Uma revisão intermediária pelo mesmo usuário não está sendo mostrada)
Linha 100: Linha 100:


import numpy as np
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from matplotlib.animation import FuncAnimation


# Parâmetros gerais
 
L = 10.0          # Comprimento da simulação
L = 10.0          # Comprimento da simulação
Nx = 100          # Número de pontos espaciais
Nx = 100          # Número de pontos espaciais
dx = L / Nx      # Passo espacial
dx = L / Nx      # Passo espacial
T_max = 30        # Tempo máximo de simulação
T_max = 30        # Tempo máximo de simulação
m = 1.0          # Massa da partícula
m = 1.0          # Massa da partícula
c = 1.0          # Velocidade da luz
c = 1.0          # Velocidade da luz
hbar = 1.0        # Constante de Planck reduzida
hbar = 1.0        # Constante de Planck reduzida


# Parâmetros para o pulso gaussiano
 
A = 1.0          # Amplitude do pulso
A = 1.0          # Amplitude do pulso
x0 = L / 2        # Posição central do pulso
x0 = L / 2        # Posição central do pulso
sigma = 0.5      # Largura do pulso
sigma = 0.5      # Largura do pulso


# Discretização espacial
 
x = np.linspace(0, L, Nx)
x = np.linspace(0, L, Nx)


# Função de onda inicial: pulso gaussiano
 
phi_0 = A * np.exp(-((x - x0)**2) / (2 * sigma**2))
phi_0 = A * np.exp(-((x - x0)**2) / (2 * sigma**2))
dphi_0 = np.zeros(Nx)  # Derivada inicial nula
dphi_0 = np.zeros(Nx)  # Derivada inicial nula


# Parâmetros para estabilidade
#estabilidade
alpha_stable = 0.5  # Valor estável para alpha (c * dt / dx)
alpha_stable = 0.5  # Valor estável para alpha (c * dt / dx)
dt_stable = alpha_stable * dx / c
dt_stable = alpha_stable * dx / c
alpha_unstable = 1.5  # Valor instável para alpha (c * dt / dx)
alpha_unstable = 1.5  # Valor instável para alpha (c * dt / dx)
dt_unstable = alpha_unstable * dx / c
dt_unstable = alpha_unstable * dx / c


Nt_stable = int(T_max / dt_stable)
Nt_stable = int(T_max / dt_stable)
Nt_unstable = int(T_max / dt_unstable)
Nt_unstable = int(T_max / dt_unstable)


# Função para evolução temporal
 
def evolve_wave(dt, Nt):
def evolve_wave(dt, Nt):
     phi = np.zeros((Nt, Nx))
     phi = np.zeros((Nt, Nx))
     phi[0, :] = phi_0
     phi[0, :] = phi_0
     phi[1, :] = phi_0 + dt * dphi_0
     phi[1, :] = phi_0 + dt * dphi_0


     for n in range(1, Nt-1):
     for n in range(1, Nt-1):
         for i in range(1, Nx-1):
         for i in range(1, Nx-1):
             phi[n+1, i] = 2 * phi[n, i] - phi[n-1, i] + (dt**2) * (
             phi[n+1, i] = 2 * phi[n, i] - phi[n-1, i] + (dt**2) * (
                 (phi[n, i+1] - 2 * phi[n, i] + phi[n, i-1]) / dx**2  
                 (phi[n, i+1] - 2 * phi[n, i] + phi[n, i-1]) / dx**2  
                 - (m**2 * c**2 / hbar**2) * phi[n, i]
                 - (m**2 * c**2 / hbar**2) * phi[n, i]
             )
             )
Linha 148: Linha 172:
     return phi
     return phi


# Evoluir para casos estável e instável
 
phi_stable = evolve_wave(dt_stable, Nt_stable)
phi_stable = evolve_wave(dt_stable, Nt_stable)
phi_unstable = evolve_wave(dt_unstable, Nt_unstable)
phi_unstable = evolve_wave(dt_unstable, Nt_unstable)


# Inicializando o gráfico
 
fig, ax = plt.subplots(2, 1, figsize=(10, 8))
fig, ax = plt.subplots(2, 1, figsize=(10, 8))


# Estável
 
def update_stable(frame):
def update_stable(frame):
     ax[0].cla()
     ax[0].cla()
     ax[0].plot(x, phi_stable[frame, :], label=f'Tempo: {frame * dt_stable:.2f}s')
     ax[0].plot(x, phi_stable[frame, :], label=f'Tempo: {frame * dt_stable:.2f}s')
     ax[0].set_title("Evolução Estável")
     ax[0].set_title("Evolução Estável")
     ax[0].set_xlim(0, L)
     ax[0].set_xlim(0, L)
     ax[0].set_ylim(-1.5, 1.5)
     ax[0].set_ylim(-1.5, 1.5)
     ax[0].legend()
     ax[0].legend()


# Instável
 
def update_unstable(frame):
def update_unstable(frame):
     ax[1].cla()
     ax[1].cla()
     ax[1].plot(x, phi_unstable[frame, :], label=f'Tempo: {frame * dt_unstable:.2f}s')
     ax[1].plot(x, phi_unstable[frame, :], label=f'Tempo: {frame * dt_unstable:.2f}s')
     ax[1].set_title("Evolução Instável")
     ax[1].set_title("Evolução Instável")
     ax[1].set_xlim(0, L)
     ax[1].set_xlim(0, L)
     ax[1].set_ylim(-1.5, 1.5)
     ax[1].set_ylim(-1.5, 1.5)
     ax[1].legend()
     ax[1].legend()


# Função de inicialização
 
def init():
def init():
     for a in ax:
     for a in ax:
         a.clear()
         a.clear()
     return ax
     return ax


# Atualização combinada para animação
# Atualização combinada para animação
def update(frame):
def update(frame):
     update_stable(frame)
     update_stable(frame)
     update_unstable(frame)
     update_unstable(frame)
     return ax
     return ax


# Criando a animação
# Criando a animação
frames_stable = range(0, Nt_stable, max(1, Nt_stable // 150))
frames_stable = range(0, Nt_stable, max(1, Nt_stable // 150))
frames_unstable = range(0, Nt_unstable, max(1, Nt_unstable // 150))
frames_unstable = range(0, Nt_unstable, max(1, Nt_unstable // 150))
ani = FuncAnimation(fig, update, frames=min(len(frames_stable), len(frames_unstable)), init_func=init, blit=False)
 
ani = FuncAnimation(fig, update, frames=min(len(frames_stable), len(frames_unstable)),
 
init_func=init, blit=False)
 


# Salvando as animações
# Salvando as animações
fig.tight_layout()
fig.tight_layout()
ani.save('klein_gordon_stable_vs_unstable.gif', writer='pillow', fps=30)
ani.save('klein_gordon_stable_vs_unstable.gif', writer='pillow', fps=30)


plt.show()
plt.show()

Edição atual tal como às 17h21min de 8 de janeiro de 2025

INTRODUÇÃO

A equação de Klein-Gordon é uma das equações fundamentais na teoria quântica relativística. Ela descreve partículas escalares (partículas sem spin, como os bósons de Higgs) e é uma extensão relativística da equação de Schrödinger, incorporando a relação de energia relativística de Einstein E=p2c2+m2c4. A equação é nomeada em homenagem a Oskar Klein e Walter Gordon, que a formularam independentemente. De maneira geral, a equação pode ser escrita como:


(+m2c22)ψ(x,t)=0

onde (=2c2t22) é chamado operador de d'Alambert.

Abrindo a equação, é obtido:

2ψt2=c22ψm2c42ψ

2ψt2=c22ψx2m2c42ψ (em uma dimensão)

Inicialmente, a equação pode ser interpretada como uma equação de um campo escalar que pode ser quantizado, onde é introduzido um campo quantico que é descrito por partículas sem spin. No reino da física de partículas, as interações eletromagnéticas podem ser incorporadas formando o tópico da eletrodinâmica escalar, por exemplo. Entretando, a solução da equação não pode ser interpretada diretamente como a densidade de probabilidade vista na equação de Schrodinger, em vez disso, a densidade de probabilidade relativística é definida usando uma corrente de probabilidade associada. Na mecânica quântica relativística, a função de onda ψ(x,t) é usada para descrever o estado de uma partícula no espaço-tempo.

MÉTODO DAS DIFERENÇAS FINITAS

O método das diferenças finitas é uma técnica numérica amplamente utilizada para resolver EDPs. Ele envolve a discretização das variáveis contínuas (geralmente no tempo ou no espaço), transformando as equações diferenciais em sistemas algébricos que podem ser resolvidos numericamente. Os primeiros passos para utilizar o método é fazer a discretização no tempo e no espaço. Para uma equação no tempo você discretiza o tempo em intervalos Δt criando uma sequência de pontos tn=nΔt. Para uma equação no espaço você discretiza o espaço em intervalos Δx criando uma sequência de pontos xi=iΔx. Depois de discretizar o espaço e o tempo, as derivadas contínuas são aproximadas por diferenças finitas. Isso envolve substituir as derivadas por aproximações baseadas nos valores de uma função nos pontos discretos:

utuin+1uinΔt e 2ut2uin+12uin+uin1(Δt)2 para o tempo.

uxui+1nuinΔxe2ux2ui+1n2uin+ui1n(Δx)2 para o espaço.

Na equação de Klein-Gordon, escrevemos desta o método das diferenças finitas:

2ψ(x,t)t2ψ(x,t+Δt)2ψ(x,t)+ψ(x,tΔt)(Δt)2

2ψ(x,t)x2ψ(x+Δx,t)2ψ(x,t)+ψ(xΔx,t)(Δx)2

ou seja:

ψ(x,t+Δt)2ψ(x,t)+ψ(x,tΔt)(Δt)2=c2ψ(x+Δx,t)2ψ(x,t)+ψ(x,tΔt)(Δx)2m2c42ψ

isso nos leva a equação final:

ψ(x,t+Δt)2ψ(x,t)+ψ(x,tΔt)=c2Δt2Δx2ψ(x+Δx,t)2ψ(x,t)+ψ(x,tΔ,t)m2c4Δt22ψ

chamarei α=cΔtΔx e β=mc2Δt

portanto, ψ(x,t+Δt)2ψ(x,t)+ψ(x,tΔt)=α2ψ(x+Δx,t)2ψ(x,t)+ψ(x,tΔt)β2ψ

ou, mais usualmente: ψin+1=2ψinψin1+α2(ψi+1n2ψin+ψi1n)β2ψ

CRITÉRIO DE ESTABILIDADE

Forma Contínua e Discretização: A equação de Klein-Gordon contínua é: 2ψt2=c22ψx2m2c42ψ.

A forma discreta, usando diferenças finitas centralizadas no tempo e no espaço, é: ψin+1=2ψinψin1+c2Δt2Δx2(ψi+1n2ψin+ψi1n)m2c4Δt22ψin. Aqui, definimos os coeficientes: α=cΔtΔx,β=mc2Δt.

Suposição de Solução Harmônica: Substituímos uma solução da forma: ψin=Gneikxi, onde:

na equação: Gn+1eikxi=2GneikxiGn1eikxi+α2Gn(eikxi+12eikxi+eikxi1)β2Gneikxi.

Simplificação:

Como eikxi+1=eikxieikΔx e eikxi1=eikxieikΔx, o termo centralizado se torna: eikxi+12eikxi+eikxi1=eikxi(eikΔx2+eikΔx). Usando eikΔx+eikΔx=2cos(kΔx), temos: eikxi+12eikxi+eikxi1=eikxi(2+2cos(kΔx)). Substituímos isso na equação e cancelamos o fator eikxi, que nunca é zero: Gn+1=2GnGn1α2(22cos(kΔx))Gnβ2Gn.

Simplificando mais, obtemos: Gn+1=(2α2(22cos(kΔx))β2)GnGn1.

Equação Característica: Assumimos uma solução na forma de uma equação quadrática G: G2G(2α2(22cos(kΔx))β2)+1=0.

Condição de Estabilidade: Para estabilidade, as raízes de G devem satisfazer |G|1. Isso leva ao critério: α1,ou seja,cΔtΔx1.

Conclusão Matemática: A condição α1 garante que os termos oscilatórios na solução não crescem exponencialmente. Essa análise também mostra que:

Quanto menor o passo de tempo Δt, mais precisa e estável é a solução. A relação entre os passos de tempo e espaço é crucial: aumentar muito Δt sem ajustar Δx pode levar à instabilidade.

C.C e C.I

Condições iniciais e condições de contorno são fundamentais para a resolução da equação, já que elas ditam o comportamento da função oa longo do tempo e ao longo do espaço, para plotar a evolução temporal, utilizarei as seguintes condições iniciais e de contorno:

ψ(x,0)=Aexx02σ2 que define um pulso gaussiano como condição inicial.

e ψ(x,0)t=0 que define que, no instante de tempo t=0, a função não possui velocidade inicial, o que implica que o pulso está parado inicialmente e sua evolução se deve pela propagação de flutuações espaciais.

Nesta condição, A é a altura do pulso, x0 é a posição central do pulso e σ é a largura do pulso.

Utilizarei também as condições de contorno em que ψ(0,t)=0 e ψ(L,t)=0 o que garante que a função 'morra' nas pontas.

Utilizando estas condições iniciais e condições de contorno, foi feito um gif que mostra a evolução temporal da equação de Klein-Gordon utilizando o método das diferenças finitas:


Localização Inicial: No gráfico mostrado, ψ(x,t) tem um pico bem definido, o que sugere que a partícula está localizada inicialmente em torno de um ponto central no espaço. Isso significa que a probabilidade da partícula estar presente é maior nessa região (em torno do pico), e diminui nas bordas. No gráfico mostrado acima, ψ(x,t) tem um pico bem definido, o que sugere que a partícula está localizada inicialmente em torno de um ponto central no espaço. Isso significa que a probabilidade da partícula estar presente é maior nessa região (em torno do pico), e diminui nas bordas.


Código utilizado

import numpy as np

import matplotlib.pyplot as plt

from matplotlib.animation import FuncAnimation


L = 10.0 # Comprimento da simulação

Nx = 100 # Número de pontos espaciais

dx = L / Nx # Passo espacial

T_max = 30 # Tempo máximo de simulação

m = 1.0 # Massa da partícula

c = 1.0 # Velocidade da luz

hbar = 1.0 # Constante de Planck reduzida


A = 1.0 # Amplitude do pulso

x0 = L / 2 # Posição central do pulso

sigma = 0.5 # Largura do pulso


x = np.linspace(0, L, Nx)


phi_0 = A * np.exp(-((x - x0)**2) / (2 * sigma**2))

dphi_0 = np.zeros(Nx) # Derivada inicial nula

  1. estabilidade

alpha_stable = 0.5 # Valor estável para alpha (c * dt / dx)

dt_stable = alpha_stable * dx / c

alpha_unstable = 1.5 # Valor instável para alpha (c * dt / dx)

dt_unstable = alpha_unstable * dx / c


Nt_stable = int(T_max / dt_stable)

Nt_unstable = int(T_max / dt_unstable)


def evolve_wave(dt, Nt):

   phi = np.zeros((Nt, Nx))
   phi[0, :] = phi_0
   phi[1, :] = phi_0 + dt * dphi_0


   for n in range(1, Nt-1):
       for i in range(1, Nx-1):
           phi[n+1, i] = 2 * phi[n, i] - phi[n-1, i] + (dt**2) * (
               (phi[n, i+1] - 2 * phi[n, i] + phi[n, i-1]) / dx**2 
               - (m**2 * c**2 / hbar**2) * phi[n, i]
           )
   return phi


phi_stable = evolve_wave(dt_stable, Nt_stable)

phi_unstable = evolve_wave(dt_unstable, Nt_unstable)


fig, ax = plt.subplots(2, 1, figsize=(10, 8))


def update_stable(frame):

   ax[0].cla()
   ax[0].plot(x, phi_stable[frame, :], label=f'Tempo: {frame * dt_stable:.2f}s')
   ax[0].set_title("Evolução Estável")
   ax[0].set_xlim(0, L)
   ax[0].set_ylim(-1.5, 1.5)
   ax[0].legend()


def update_unstable(frame):

   ax[1].cla()
   ax[1].plot(x, phi_unstable[frame, :], label=f'Tempo: {frame * dt_unstable:.2f}s')
   ax[1].set_title("Evolução Instável")
   ax[1].set_xlim(0, L)
   ax[1].set_ylim(-1.5, 1.5)
   ax[1].legend()


def init():

   for a in ax:
       a.clear()
   return ax
  1. Atualização combinada para animação

def update(frame):

   update_stable(frame)
   update_unstable(frame)
   return ax
  1. Criando a animação

frames_stable = range(0, Nt_stable, max(1, Nt_stable // 150))

frames_unstable = range(0, Nt_unstable, max(1, Nt_unstable // 150))

ani = FuncAnimation(fig, update, frames=min(len(frames_stable), len(frames_unstable)),

init_func=init, blit=False)


  1. Salvando as animações

fig.tight_layout()

ani.save('klein_gordon_stable_vs_unstable.gif', writer='pillow', fps=30)

plt.show()