Escolar Documentos
Profissional Documentos
Cultura Documentos
6
Morais & Nogueira – Física Computacional com Python
7
Morais & Nogueira – Física Computacional com Python
Métodos Newton-Raphson
O método de Newton-Raphson é uma maneira para encontrar as raízes de equações não
lineares e é um dos algoritmos mais comuns para encontrar raízes devido à sua relativa
simplicidade e velocidade. O método usa a derivada da função 𝑓 ′ (𝑥) e a função original
𝑓(𝑥).
Iteração Newton-Raphson
O chute inicial da raiz é denotado por 𝑥1 . A raiz verdadeira é 𝑥0 e pode ser expressa como
𝑥0 = 𝑥1 + ℎ, onde ℎ é a distância entre a estimativa e o valor verdadeiro da raiz. Como ℎ será
pequeno, uma linha tangente linear é usada para aproximar a localização da raiz e pode ser
escrita como:
𝑓(𝑥0 ) = 0 = 𝑓(𝑥1 + ℎ) ≅ 𝑓(𝑥1 ) + ℎ𝑓 ′ (𝑥1 ) + ⋯
1
Assim, ℎ ≈ −𝑓(𝑥1 )/𝑓 ′ (𝑥1 ), desde que 𝑓 ′ (𝑥1 ) ≠ 0. Podemos então escrever
𝑓(𝑥1 )
𝑥0 = 𝑥1 + ℎ ≈ 𝑥1 −
𝑓 ′ (𝑥1 )
Todavia, podemos iterar mais uma vez e estimar
𝑓(𝑥1 )
𝑥2 ≈ 𝑥1 −
𝑓 ′ (𝑥1 )
𝑓(𝑥2 )
𝑥3 ≈ 𝑥2 −
𝑓 ′ (𝑥2 )
⋮
𝑓(𝑥𝑛 )
𝑥𝑛+1 ≈ 𝑥𝑛 −
𝑓 ′ (𝑥𝑛 )
2
8
Morais & Nogueira – Física Computacional com Python
Compare a rapidez desse método com o método proposto no início da sessão. Essa
velocidade é o que torna o Método de Newton-Raphson amplamente difundido e utilizado.
Métodos da Secante
Um método semelhante, é o método da secante. Ele consiste em aproximar a derivada
encontrada no Método de Newton-Raphson por uma equação de diferença. Sejam os valores
iniciais 𝑥0 e 𝑥1 , é possível construir uma linha passando pelos pontos [𝑥0 , 𝑓(𝑥0 )] e
[𝑥1 , 𝑓(𝑥1 )]. A equação da reta que passa por esses dois pontos é
𝑓(𝑥1 ) − 𝑓(𝑥0 )
𝑦= (𝑥 − 𝑥1 ) + 𝑓(𝑥1 )
𝑥1 − 𝑥0
3
9
Morais & Nogueira – Física Computacional com Python
Utilizando Gráficos
Uma das grandes vantagens de se escrever os códigos em Python em comparação com
linguagens mais robustas como C, C++, Fortran e Assembler é a fácil visualização das
simulações. Uma das bibliotecas mais utilizadas é a matplotlib.pyplot. É possível representar
graficamente funções com certa facilidade. Vamos tentar...
onde 𝜎 é a separação mínima entre duas moléculas de “caroço duro”1 (hard core) e 𝜖 é o
valor mínimo do potencial chamado de profundidade do poço expresso em kJ/mol. Sejam
𝜖 = 1,77kJ/mol e 𝜎 = 4,1 × 10−10 m no potencial de Lennard-Jones (equação Erro! Fonte d
e referência não encontrada.) para um átomo de xenônio, vamos escrever um programa
1
Chamamos de caroço duro as moléculas que preservam sua forma sem que haja a sobreposição de
duas partículas caroço duro, quando pressionadas uma contra a outra, i.e., se comportam como um corpo rígido.
10
Morais & Nogueira – Física Computacional com Python
Exercício. Por simplicidade, vamos supor que o movimento ocorra somente na direção 𝑋, tal
que a forma do potencial de Lennard-Jones é
𝜎 12 𝜎 6
𝑉(𝑥) = 4𝜖 [( ) − ( ) ]
𝑥 𝑥
1
e a energia total é 𝐸 = 2 𝑚𝑣𝑥2 + 𝑉(𝑥). A partícula estará confinada se 𝐸 < 0 entre os pontos
𝑥𝑚í𝑛 e 𝑥𝑚á𝑥 .
Faça um programa para encontrar os pontos 𝑥𝑚í𝑛 e 𝑥𝑚á𝑥 da órbita de uma partícula com
energia total 𝐸 = −4 × 10−12 J se o potencial tem os seguintes parâmetros 𝜎 = 2 × 10−9 m e
𝜖 = 5 × 10−12 J.
Máximos e Mínimos
É extremamente comum em Física a busca pelo valor de extremos de uma função. Ela
surge em muitas situações como a procura dos pontos de equilíbrio em funções de energia
potencial na Mecânica Clássica e na Mecânica Quântica, do equilíbrio dos potenciais
termodinâmicos e do melhor caminho óptico. Muitas linguagens, incluindo o Python,
apresentam funções implícitas e módulos para obtenção de máximos e mínimos em conjunto
de dados, mas vamos pelo caminho mais lógico antes de utilizar este atalho.
Seja a função 𝑓(𝑥), tal que esta função apresenta um máximo local na região de
interesse estudado [𝑥1 ; 𝑥2 ]. A busca por esse máximo consiste em varrer a região de interesse
e guardar o ponto em que a função 𝑓(𝑥) tem o maior valor.
import matplotlib.pyplot as plt
x_1 = 1.
x_2 = 5.
itera = 0
h = (x_2-x_1)/10
tolera = 0.000000001
# Definimos a função funcao(x) igual a equação que desejamos encontrar a
raiz
def funcao(x):
return 5-((x-3.77)**2)
# Escolhemos o chute inicial de x
x = x_1
# A variável Booleana achou que determina se a solução exata foi encontrada
achou = False
# A variável Booleana primeiro determina se o valor de x na iteração passou
da raiz pela primeira vez
primeiro = False
passou = False
fmax = funcao(x)
xmax=x
11
Morais & Nogueira – Física Computacional com Python
while abs(h)>tolera:
passou = False
if x<x_1 and x>x_2:
break
while passou == False:
itera += 1
x=x+h
# plotando os pontos em cada iteração
plt.scatter(x, funcao(x),)
if(funcao(x)>fmax):
xmax=x
fmax=funcao(x)
else:
passou = True
primeiro = True
x=x-h
h=-h*2./3.
# Plotando a função(x)
h=(x_2-x_1)/100.
x=x_1
xpontos=([x])
ypontos=([funcao(x)])
while x<x_2:
x=x+h
xpontos=xpontos+[x]
ypontos=ypontos+[funcao(x)]
plt.xlabel('x')
plt.ylabel('função (x)')
plt.plot(xpontos, ypontos)
xpontos2 = ([xmax,xmax])
ypontos2 = ([-3,6])
plt.plot(xpontos2,ypontos2)
plt.show()
Interferência de ondas
Uma onda é uma perturbação de propagação de uma ou mais quantidades. As ondas
ocorrem em vários sistemas físicos, desde a perturbação que se propaga em um lago quando
se joga uma pedra, passando por vibrações estacionárias nas cordas de um violão e chegando
às ondas eletromagnéticas. Veremos mais a frente como as propriedades dos sistemas físicos
resultam na geração e propagação das ondas específicas nestes meios. Por hora, vamos nos
ater a solução mais simples da equação de onda clássica: a onda harmônica simples. Nela, a
12
Morais & Nogueira – Física Computacional com Python
amplitude 𝐴 , que é o valor do campo oscilante medido, é constante. Por exemplo, em uma
onda no lago, a amplitude é a altura máxima da água na onda em relação a água não-
perturbada no resto do lago. Matematicamente, a onda pode ser escrita na forma
𝜙 = 𝐴 sin(𝑘𝑥 ± 𝜔𝑡 + 𝛿)
Aqui, 𝑘 é o número de onda, 𝜔 é a frequência angular de oscilação da onda e 𝛿 é uma
constante de fase. Note que a unidade de medida para 𝑘 é o radiano por metro (rad/m) e a
unidade de 𝜔 é o radiano por segundo (rad/s), assim restando a unidade de 𝛿 como radiano. É
comum expressar o número de onda em termos do comprimento de onda 𝜆 através da
2𝜋
relação𝑘 = 𝜆 . A frequência angular pode ser expressa como 𝜔 = 2𝜋𝑓 , onde 𝑓 é a
frequência da onda. 𝑓 e 𝜔 estão relacionados com a velocidade de fase da onda 𝑣 por 𝑣 =
𝜆𝑓 . A forma da onda pode ser escrita como
2𝜋𝑥
𝜙 = 𝐴 sen ( ± 2𝜋𝑓𝑡 + 𝛿)
𝜆
Suponha então duas ondas distintas cujas formas são
𝜙1 = 𝐴1 sen(𝑘1 𝑥 ± 𝜔1 𝑡)
𝜙2 = 𝐴2 sen(𝑘2 𝑥 ± 𝜔2 𝑡 + 𝛿2 )
A onda resultante da superposição destas ondas é a soma algébrica de suas formas
𝜙𝑅 = 𝜙1 + 𝜙2
𝐴+𝐵 𝐴−𝐵
Usando a relação trigonométrica para a soma dos senos sen 𝐴 + sen 𝐵 = 2 sen cos ,
2 2
temos
𝜙𝑅
𝐴1 − 𝐴2
= 𝜙1
𝐴1
(𝑘1 + 𝑘2 )𝑥 ± (𝜔1 + 𝜔2 )𝑡 + 𝛿2 (𝑘1 − 𝑘2 )𝑥 ± (𝜔1 − 𝜔2 )𝑡 − 𝛿2
+ 2𝐴2 sen cos
2 2
No caso em que as amplitudes são iguais, 𝐴1 = 𝐴2 = 𝐴, temos
(𝑘1 + 𝑘2 )𝑥 ± (𝜔1 + 𝜔2 )𝑡 + 𝛿2 (𝑘1 − 𝑘2 )𝑥 ± (𝜔1 − 𝜔2 )𝑡 − 𝛿2
𝜙𝑅 = 2𝐴 sen cos
2 2
Para o caso das duas ondas se propagarem no mesmo meio (longe da interface entre meios) e
supondo que as ondas tenham a mesma frequência, temos
𝛿2 𝛿2
𝜙𝑅 = 2𝐴 sen (𝑘𝑥 ± 𝜔𝑡 + ) cos
2 2
Batimento de ondas
Um fenômeno adjacente a qualquer interação de ondas é o chamado batimento. Ele
ocorre quando duas ondas sonoras com frequências próximas atingem o receptor. Neste caso,
vamos considerar 𝑥 = 0 e as ondas em fase, 𝛿2 = 0, tal que
13
Morais & Nogueira – Física Computacional com Python
(𝜔1 + 𝜔2 ) (𝜔1 − 𝜔2 )
𝜙𝑅 = (𝐴1 − 𝐴2 ) sen(𝜔1 𝑡) + 2𝐴2 sen 𝑡 cos 𝑡
2 2
No caso de as frequências serem próximas, podemos escrever a frequência da onda 2
como 𝜔1 = 𝜔2 + Δ𝜔, com Δ𝜔 → 0. Podemos aproximar a onda resultante por
Δ𝜔
𝜙𝑅 ≅ {𝐴1 + 𝐴2 [2 cos ( 𝑡) − 1]} sen(𝜔1 𝑡)
2
E no caso em que as amplitudes são iguais 𝐴1 = 𝐴2 = 𝐴, temos
Δ𝜔
𝜙𝑅 ≅ 2𝐴 cos ( 𝑡) sen(𝜔1 𝑡)
2
import math as m
import matplotlib.pyplot as plt
import numpy as np
# Seja Tamanho o comprimento que se deseja observar da interferência
Tamanho = 2.*m.pi
# O incremento é o tamanho dividio pelo número de pontos
N = 1000
h = Tamanho/N
# Definindo os valores da onda 1
a1 = 1
k1 = 8*m.pi
fi1 = 0.
# Definindo os valores da onda 2
a2 = 1
k2 = 8.5*m.pi
fi2 = 0
def onda(a,k,x,fi):
return a*m.sin(k*x+fi)
x=([0.])
S1 = ([onda(a1,k1,x[-1],fi1)])
S2 = ([onda(a2,k2,x[-1],fi2)])
# A onda resultante é a soma das duas ondas
resultante = ([onda(a1,k1,x[-1],fi1)+onda(a2,k2,x[-1],fi2)])
itera=0
while x[-1]<Tamanho:
itera += 1
x = x+[itera*h]
S1 = S1+[onda(a1,k1,x[-1],fi1)]
S2 = S2+[onda(a2,k2,x[-1],fi2)]
resultante = resultante+ [onda(a1,k1,x[-1],fi1)+onda(a2,k2,x[-1],fi2)]
# Gráficos
plt.plot(x, S1,label="Onda 1")
plt.plot(x, S2,label="Onda 2")
plt.plot(x, resultante,label="Resultante")
# Caso a intensidade seja de interesse, descomente as três linhas abaixo
#Intensidade = np.array(resultante)
#Intensidade = Intensidade**2
#plt.plot(x, Intensidade,label="Intensidade")
plt.xlabel("Espaço (m)")
plt.ylabel("Valores das Funções")
plt.legend()
plt.show()
14
Morais & Nogueira – Física Computacional com Python
Figura 7- Saída gráfica do programa para interação de ondas. Os valores do batimento mostrado referem-se às
ondas …
Polarização da Luz
A polarização é uma propriedade das ondas transversais a qual especifica a orientação
geométrica da direção de oscilação da onda. Em uma onda transversal, a direção da oscilação
é sempre perpendicular à direção do movimento da onda, como as vibrações que viajam ao
longo de uma corda esticada. Dependendo de como a corda é acionada, as vibrações podem
ser na direção vertical, horizontal ou em qualquer ângulo perpendicular à corda. Em
contraste, em ondas longitudinais, como ondas sonoras em um líquido ou gás, o
deslocamento das partículas na oscilação é sempre na direção de propagação, de modo que
essas ondas não apresentam polarização. Ondas transversais que exibem polarização incluem
ondas eletromagnéticas, como ondas de luz e rádio, ondas gravitacionais e ondas sonoras
transversais (ondas de cisalhamento) em sólidos.
As ondas eletromagnéticas
15
Morais & Nogueira – Física Computacional com Python
16
Morais & Nogueira – Física Computacional com Python
TetaB = TetaB-4
# round(Numero, casas decimais)
Texto = 'Ângulo de Brewster = ' + str(round(TetaB+4,3))
plt.text(TetaB, 0.1, Texto, rotation=90)
plt.legend()
plt.show()
Figura 8- Saída gráfica do programa das Equações de Fresnel e algoritmo de busca do máximo para encontrar o
ângulo de polarização de Brewster.
17
Morais & Nogueira – Física Computacional com Python
18
Morais & Nogueira – Física Computacional com Python
Velocidade Terminal
Uma esfera sólida, que tem um movimento relativo a um fluido, experimenta uma
força de arrasto de modo a resistir o movimento. A força de arrasto é proporcional à
velocidade para escoamentos lentos e ao quadrado da velocidade para escoamentos de alta
velocidade. A quantificação do que é lento ou rápido requer a definição de um parâmetro,
chamado de Número de Reynolds, o qual definiremos no capítulo X. Por hora, vamos
apenas utilizar o resultado obtido por George Stokes, em 1851, da força de arrasto de uma
esfera passando lentamente por um fluido viscoso. Essa força é conhecida como Lei de
Stokes e sua forma para uma esfera de raio 𝑅 viajando a uma velocidade relativa 𝑣⃗ em
relação a um fluido cuja viscosidade é 𝜇 é
𝐹⃗ = −6𝜋𝜇𝑅𝑣⃗
Note que a viscosidade tem unidades de newton-segundo por metro quadrado ou
pascal vezes segundo, no SI.
19
Morais & Nogueira – Física Computacional com Python
import math as mt
import matplotlib.pyplot as plt
m = 80
grav = 9.8
b = 10
v = 0.
t = 0.
h = 0.01
# Vamos definir a função de dv/dt
def g(grav,b,m,v):
return grav-(b*v/m)
vterm = m*grav/b
print('A velocidade terminal para o problema é ', vterm, 'm/s')
tpontos = [t]
vpontos = [v]
while v<.999*vterm:
t += h
v += h*g(grav,b,m,v)
tpontos += [t]
vpontos += [v]
2
No escoamento laminar as partículas de fluido seguem caminhos suaves em lâminas, com cada
lâmina movendo-se suavemente pelas lâminas vizinhas com pouca ou nenhuma mistura. Em baixas velocidades,
o fluido tende a fluir sem mistura lateral, e camadas adjacentes deslizam umas sobre as outras.
3
O escoamento turbulento é o movimento do fluido caracterizado por mudanças caóticas na pressão e
na velocidade do escoamento.
20
Morais & Nogueira – Física Computacional com Python
# Gráficos
# Definindo os rótulos x e y
plt.xlabel('Tempo (s)')
plt.ylabel('Velocidade (m/s)')
# Definindo os limites do gráfico
plt.xlim(0, t)
plt.ylim(0, 1.1*v)
# Plotando os pontos da velocidade
plt.plot(tpontos,vpontos,label='v(t)')
# Plotando os pontos da linha auxiliar
linhaauxiliart = [0]
linhaauxiliarv = [vterm]
linhaauxiliart += [t]
linhaauxiliarv += [vterm]
plt.plot(linhaauxiliart,linhaauxiliarv,':',label='Velocidade Terminal')
plt.legend()
plt.show()
Esta é a solução extada função, seja ela qual for. Subtraindo da equação acima, a
aproximação de Euler, temos
21
Morais & Nogueira – Física Computacional com Python
∞
𝑑𝑖 𝑓 ℎ𝑖
𝑓(𝑥 + ℎ) − 𝑓𝑛+1 = ∑ (𝑥)
𝑑𝑥 𝑖 𝑖!
𝑖=2
Método de Taylor
Como vimos, a propagação de erro no Método de Euler em equações não-lineares
impossibilita sua utilização devido ao custo computacional, desde que o erro não é
amortizado. Ao invés de utilizarmos a definição da derivada para aproximar a primeira
derivada, podemos utilizar uma expansão em séries de Taylor da função 𝑓(𝑥) em torno de ℎ :
𝑑𝑓 ℎ2 𝑑 2 𝑓
𝑓(𝑥 + ℎ) ≈ 𝑓(𝑥) + ℎ (𝑥) + (𝑥) + ⋯
𝑑𝑥 2 𝑑𝑥 2
𝑑𝑓
Note que 𝑔 = 𝑑𝑥 , que é uma derivada total. Logo
𝑑𝑔 𝜕𝑔 𝑑𝑥 𝜕𝑔 𝑑𝑓 𝜕𝑔 𝜕𝑔
= + = + 𝑔
𝑑𝑥 𝜕𝑥 𝑑𝑥 𝜕𝑓 𝑑𝑥 𝜕𝑥 𝜕𝑓
Introduzindo a equação X na equação acima, temos
ℎ2 𝜕𝑔 𝜕𝑔
𝑓(𝑥 + ℎ) ≈ 𝑓(𝑥) + ℎ𝑔(𝑥) + [ (𝑥) + (𝑥)𝑔(𝑥)] + ⋯
2 𝜕𝑥 𝜕𝑓
Na nossa notação de equação de diferença, fica
ℎ2 𝜕𝑔 𝜕𝑔
𝑓𝑛+1 ≈ 𝑓𝑛 + ℎ𝑔𝑛 + ( + 𝑔) + ⋯
2 𝜕𝑥 𝜕𝑓 𝑛
Claramente, as derivadas de 𝑔 são calculadas em 𝑥𝑛 . Note que o erro local é na
segunda ordem e o de truncamento é da ordem de ℎ3 .
Exemplo: Vamos encontrar a solução da seguinte equação diferencial de primeira
ordem
𝑑𝑦
= −𝑥 2 𝑦
𝑑𝑥
Equação 6
com condição de contorno 𝑦(0) = 1 pelos métodos de Euler e Taylor. Vamos chamar
𝜕𝑓 𝜕𝑓
𝑓(𝑥) = −𝑥 2 𝑦. Assim, as derivadas aparecendo no Método de Taylor são 𝜕𝑥 = −2𝑥𝑦 e 𝜕𝑦 =
−𝑥 2 .
A solução analítica desta equação pode ser obtida diretamente da integração simples,
𝑥3
resultando em 𝑦(𝑥) = 𝑒 − 3 .
Código Usando o Método de Euler
import math as mt
import matplotlib.pyplot as plt
22
Morais & Nogueira – Física Computacional com Python
23
Morais & Nogueira – Física Computacional com Python
Figura 9 - Saída do programa para solução de 𝑦(𝑥) = −𝑥 2 𝑦 pelo método de Euler. A figura de baixa mostra a
propagação do erro fracional.
Figura 10- Saída do programa para solução de 𝑦(𝑥) = −𝑥 2 𝑦 pelo método de Taylor. A figura de baixa mostra a
propagação do erro fracional
24
Morais & Nogueira – Física Computacional com Python
contador = 0
# Definindo as condições de contorno
x=x0
y=y0
xpontos=([x0])
ypontos=([y0])
yexato =([y0])
Erro =([0.])
# Gráficos
plt.figure()
plt.subplot(211)
plt.plot(xpontos, ypontos, label=("Taylor h="+str(h)), color='tab:blue')
plt.plot(xpontos, yexato, label="Analítico", color='black')
plt.legend()
plt.ylabel("y")
plt.subplot(212)
plt.plot(xpontos, Erro, label="1 - Calculado/Exato", color='tab:orange',
linestyle='--')
plt.xlabel("x")
plt.ylabel("Erro")
plt.legend()
plt.show()
Método de Adams-Bashforth
25
Morais & Nogueira – Física Computacional com Python
Podemos melhorar a precisão, podemos fazer uso de relações que envolvam mais ordens na
equação de diferença, ide est, além de 𝑓𝑛+1 e 𝑓𝑛 , podemos invocar 𝑓𝑛−1, 𝑓𝑛−2, et cetera.
Desde que
𝑑𝑓
= 𝑔(𝑥, 𝑓)
𝑑𝑥
podemos integrar para obter
𝑓𝑛+1 𝑥𝑛+1
∫ 𝑑𝑓 = ∫ 𝑔(𝑥, 𝑓)𝑑𝑥
𝑓𝑛 𝑥𝑛
𝑥𝑛+1
𝑔𝑛 − 𝑔𝑛−1 2 𝑔𝑛 − 𝑔𝑛−1
𝑓𝑛+1 ≈ 𝑓𝑛 + (𝑥𝑛+1 − 𝑥𝑛2 ) + (𝑔𝑛 − 𝑥𝑛 ) (𝑥𝑛+1 − 𝑥𝑛 )
2ℎ ℎ
𝑔𝑛 − 𝑔𝑛−1 2 𝑔𝑛 − 𝑔𝑛−1
𝑓𝑛+1 ≈ 𝑓𝑛 + (𝑥𝑛+1 − 𝑥𝑛2 ) + (𝑔𝑛 − 𝑥𝑛 ) ℎ
2ℎ ℎ
𝑔𝑛 − 𝑔𝑛−1 𝑔𝑛 − 𝑔𝑛−1
𝑓𝑛+1 ≈ 𝑓𝑛 + (𝑥𝑛+1 + 𝑥𝑛 )(𝑥𝑛+1 − 𝑥𝑛 ) + (𝑔𝑛 − 𝑥𝑛 ) ℎ
2ℎ ℎ
𝑔𝑛 − 𝑔𝑛−1 𝑔𝑛 − 𝑔𝑛−1
𝑓𝑛+1 ≈ 𝑓𝑛 + ℎ(𝑥𝑛+1 + 𝑥𝑛 ) + (𝑔𝑛 − 𝑥𝑛 ) ℎ
2ℎ ℎ
𝑔𝑛 − 𝑔𝑛−1
𝑓𝑛+1 ≈ 𝑓𝑛 + ℎ(𝑥𝑛+1 − 2𝑥𝑛 + 𝑥𝑛 ) + 𝑔𝑛 ℎ
2ℎ
𝑔𝑛 − 𝑔𝑛−1
𝑓𝑛+1 ≈ 𝑓𝑛 + ℎ(𝑥𝑛+1 − 𝑥𝑛 ) + 𝑔𝑛 ℎ
2ℎ
26
Morais & Nogueira – Física Computacional com Python
𝑔𝑛 − 𝑔𝑛−1
𝑓𝑛+1 ≈ 𝑓𝑛 + ℎ + 𝑔𝑛 ℎ
2
3 1
𝑓𝑛+1 ≈ 𝑓𝑛 + ℎ ( 𝑔𝑛 − 𝑔𝑛−1 )
2 2
A ordem do erro local neste método de passo duplo é ℎ2 . Poderíamos ter aproximado
a função 𝑔(𝑥) no intervalo por uma outra função polinomial, resultando em uma precisão
maior e num maior número de passos.
27
Morais & Nogueira – Física Computacional com Python
print(Ipontos)
plt.xlabel("Tempo (s)")
plt.ylabel("Corrente (ampères)")
plt.plot(tpontos,Ipontos,label='I(t)')
# definindo a reta assintótica da corrente
auxiliart = [0]
auxiliarI = [V/R]
auxiliart += [tempo]
auxiliarI += [V/R]
plt.plot(auxiliart,auxiliarI,':', label='Corrente máxima')
plt.legend()
plt.show()
28
Morais & Nogueira – Física Computacional com Python
Figura 12- Solução numérica do circuito RL com o método de Adams-Bashforth. Note que a corrente do circuito
evolui assintoticamente para o valor da corrente máxima para quando o indutor está carregado.
𝑑𝑞
= 𝐼,
𝑑𝑡
8
29
Morais & Nogueira – Física Computacional com Python
tau = L/R
freq0 = 1./mt.sqrt(L*C)
fatordecarga = R/(2*L)
freq = mt.sqrt((freq0**2)-(fatordecarga**2))
periodo = (2*mt.pi)/freq
#print('A constante de fase do circuito RL é ',tau,' segundos')
print('A frequencia de ressonancia do circuito RLC é ',
round(freq0),'rad/s')
print('O fator de carga é ',round(fatordecarga))
print('A frequencia de ressonancia com carga é ', round(freq),'rad/s')
print(periodo)
# vanmos definir a função governante do problema
def g(V,L,R,I,q,C):
return (V/L)-(R*I/L)-(q/(L*C))
# vamos definir o incremento temporal em termos da constante de fase
h = 0.01*tau
tpontos=[tempo]
qpontos=[q]
Ipontos=[I]
# Precisamos dos pontos n e n-1 para aplicar o método de Adams-Bahsforth.
# assim, vamos realizar um passo de Euler para ter dois passos.
tempo += h
q += h*I
I += h*g(V,L,R,I,q,C)
tpontos +=[tempo]
qpontos +=[q]
Ipontos +=[I]
while tempo < 4*tau:
tempo += h
q += h*(1.5*Ipontos[-1]-0.5*Ipontos[-2])
I += h*(1.5*g(V,L,R,Ipontos[-1],qpontos[-1],C)-0.5*g(V,L,R,Ipontos[-
2],qpontos[-2],C))
qpontos += [q]
tpontos +=[tempo]
Ipontos +=[I]
plt.xlabel("Tempo (s)")
plt.ylabel("Corrente (ampères)")
plt.xlim(0,tempo)
plt.ylim(-1.1*max(Ipontos),1.1*max(Ipontos))
plt.plot(tpontos,Ipontos,label='I(t)')
# definindo a reta assintótica da corrente
auxiliart = [0]
auxiliarI = [0]
auxiliart += [tempo]
auxiliarI += [0]
plt.plot(auxiliart,auxiliarI,':')
# Desenhando o período da oscilação no gráfico
auxiliar2t = [periodo]
30
Morais & Nogueira – Física Computacional com Python
auxiliar2I = [0.25*max(Ipontos)]
auxiliar2t += [2.*periodo]
auxiliar2I += [0.25*max(Ipontos)]
plt.plot(auxiliar2t,auxiliar2I,'o',color='green')
plt.plot(auxiliar2t,auxiliar2I,color='green')
plt.text(1.5*periodo, 0.3*max(Ipontos),'Período',
horizontalalignment='center')
Métodos de Runge-Kutta
Os métodos Runge-Kutta de solução de EDOs são os mais utilizados. Ele consiste em
calculas as inclinações em cada passo. Por exemplo, o passo seguinte para a terceira ordem é
na forma
𝑓𝑛+1 = 𝑓𝑛 + ℎ(𝑎1 𝑘1 + 𝑎2 𝑘2 + 𝑎3 𝑘3 )
com
𝑘1 = 𝑔(𝑥𝑛 , 𝑓𝑛 ),
𝑘2 = 𝑔(𝑥𝑛 + 𝑝1 ℎ, 𝑓𝑛 + 𝑞11 ℎ𝑘1 )
𝑘3 = 𝑔(𝑥𝑛 + 𝑝2 ℎ, 𝑓𝑛 + 𝑞21 ℎ𝑘1 + 𝑞22 ℎ𝑘2 )
A expansão em séries de Taylor de 𝑓(𝑥𝑛 + ℎ) em torno de 𝑥𝑛 até a quarta ordem é
ℎ2 𝜕𝑔 𝜕𝑔
𝑓𝑛+1 = 𝑓𝑛 + ℎ𝑔(𝑥𝑛 , 𝑓𝑛 ) + ( +𝑔 )
2 𝜕𝑥 𝜕𝑓
3 2 2
ℎ 𝜕 𝑔 𝜕 𝑔 𝜕𝑔 𝜕𝑔 𝜕 2𝑔 𝜕𝑔 𝜕𝑔
+ ( 2 + 2𝑔 + + 𝑔2 2
+𝑔 )+⋯
6 𝜕𝑥 𝜕𝑥𝜕𝑓 𝜕𝑥 𝜕𝑓 𝜕𝑓 𝜕𝑓 𝜕𝑓
Equação 9
A expansão de Taylor dos termos em é mostrada até a quarta ordem, em vez de até a quinta,
como deveríamos para verificar se os termos de ordem mais alta eventualmente se cancelam,
31
Morais & Nogueira – Física Computacional com Python
mas assumiremos que o método não pode alcançar melhor precisão local do que a quarta
ordem, ou equivalentemente, o erro global de terceira ordem. Isso nos poupará de entrar na
expansão de terceiro nível da função 𝑔 de duas variáveis, que tem 18 termos e não seria
apropriada devido ao seu tamanho. Após prepararmos a expansão em série de Taylor,
precisamos ajustar a equação de recorrência do método, de forma que possa ser comparada
com a série de Taylor (Equação 9).
𝑓𝑛+1 = 𝑓𝑛 + ℎ𝑎1 𝑔
𝜕𝑔 𝜕𝑔
+ ℎ𝑎2 [𝑔 + 𝑝1 ℎ
+ 𝑞11 ℎ 𝑔
𝜕𝑥 𝜕𝑓
2 2 2
ℎ 𝜕 𝑔 𝜕 𝑔 𝜕𝑔 𝜕𝑔
+ (𝑝12 2 + 𝑞11
2 2
𝑔 2
+ 2𝑝1 𝑞11 𝑔 ) + 𝑂2 (ℎ3 )]
2 𝜕𝑥 𝜕𝑓 𝜕𝑥 𝜕𝑓
𝜕𝑔
+ ℎ𝑎3 {𝑔 + 𝑝2 ℎ
𝜕𝑥
𝜕𝑔 𝜕𝑔 𝜕𝑔
+ [𝑞21 ℎ𝑔 + 𝑞22 ℎ (𝑔 + 𝑝1 ℎ + 𝑞11 ℎ𝑔 + 𝑂3 (ℎ2 ))]
𝜕𝑓 𝜕𝑥 𝜕𝑓
1 2
𝜕 2𝑔
+ [(𝑝2 ℎ)
2 𝜕𝑥 2
2
𝜕 2𝑔 𝜕𝑔 𝜕𝑔
+ ℎ2 2 (𝑞21 𝑔 + 𝑞22 (𝑔 + 𝑝1 ℎ + 𝑞11 ℎ 𝑔 + 𝑂4 (ℎ2 )) )]
𝜕𝑓 𝜕𝑥 𝜕𝑓
𝜕𝑔 𝜕𝑔 𝜕𝑔 𝜕𝑔
+ 2𝑝2 ℎ2 [𝑞21 𝑔 + 𝑞22 (𝑔 + 𝑝1 ℎ + 𝑞11 ℎ𝑔 + 𝑂4 (ℎ2 ))]}
𝜕𝑥 𝜕𝑓 𝜕𝑥 𝜕𝑓
Agora, precisamos agrupar os termos da mesma forma que eles são agrupados na série de
Taylor (Equação 9), de modo que possamos estabelecer as condições nos parâmetros que
produzirão os mesmos termos da expansão de Taylor até os termos contendo ℎ4 .
𝑓𝑛+1 = 𝑓𝑛 + ℎ(𝑎1 + 𝑎2 + 𝑎3 )𝑔(𝑥𝑛 , 𝑓𝑛 )
𝜕𝑔 𝜕𝑔 𝜕𝑔 𝜕𝑔 𝜕𝑔
+ ℎ2 [𝑎2 (𝑝1 + 𝑞11 𝑔 ) + 𝑎3 (𝑝2 + 𝑞21 𝑔 + 𝑞22 𝑔 )]
𝜕𝑥 𝜕𝑓 𝜕𝑥 𝜕𝑓 𝜕𝑓
2 2
𝑎2 𝜕 𝑔 𝜕 𝑔 𝜕𝑔 𝜕𝑔
+ ℎ3 { (𝑝12 2 + 𝑞11 2 2
𝑔 2
+ 2𝑝1 𝑞11 𝑔 )
2 𝜕𝑥 𝜕𝑓 𝜕𝑓 𝜕𝑓
𝜕𝑔 𝜕𝑔 𝜕𝑔 𝜕𝑔
+ 𝑎3 (𝑞22 𝑝1 + 𝑞11 𝑞22 𝑔 )
𝜕𝑓 𝜕𝑓 𝜕𝑓 𝜕𝑓
1 𝜕 2𝑔 𝜕 2𝑔 𝜕𝑔 𝜕𝑔
+ [𝑝22 2 + 𝑔2 (𝑞21 + 𝑞22 )2 + 2𝑝 2 𝑔(𝑞 21 + 𝑞22 ) ]}
2 𝜕𝑥 𝜕𝑓 2 𝜕𝑥 𝜕𝑓
3) 2 2 )𝑞
𝜕𝑔 3
𝜕 2𝑔
+ [ℎ𝑂2 (ℎ + ℎ 𝑂3 (ℎ 22 𝑎3 + 𝑞22 𝑎3 𝑔ℎ 𝑂 (ℎ)]
𝜕𝑓 𝜕𝑓 2 5
Equação 10
32
Morais & Nogueira – Física Computacional com Python
𝑎1 + 𝑎2 + 𝑎3 = 1
Equação 11
1
𝑝1 𝑎1 + 𝑝2 𝑎3 =
2
Equação 12
1
𝑞11 𝑎2 + 𝑎3 (𝑞21 + 𝑞22 ) =
2
Equação 13
1
𝑎2 𝑝12 + 𝑎3 𝑝22 =
3
Equação 14
1
𝑎2 𝑝1 𝑞11 + 𝑎3 𝑝22 =
3
Equação 15
1
𝑎3 𝑞22 𝑝1 =
6
Equação 16
2
1
𝑎2 𝑞11 + 𝑎3 (𝑞21 + 𝑞22 )2 =
3
Equação 17
1
𝑎3 𝑞22 𝑞11 =
6
Equação 18
Por exemplo, podemos escolher que 𝑝2 = 1, 𝑞11 = 1/2, então obtemos a seguinte equação
de recorrência.
ℎ
𝑓𝑛+1 = 𝑓𝑛 + (𝑘1 + 4𝑘2 + 𝑘3 )
6
com
33
Morais & Nogueira – Física Computacional com Python
𝑘1 = 𝑔(𝑥𝑛 , 𝑓𝑛 )
ℎ ℎ
𝑘2 = 𝑔 (𝑥𝑛 + , 𝑓𝑛 + 𝑘1 )
2 2
𝑘3 = 𝑔(𝑥𝑛 + ℎ, 𝑓𝑛 − ℎ𝑘1 + 2ℎ𝑘2 )
Agora que terminamos o algoritmo de terceira ordem, você pode se aventurar a tentar obter o
algoritmo de quarta de ordem. Eu me sinto satisfeito e vou apenas postar o algoritmo de
quarta ordem.
ℎ
𝑓𝑛+1 = 𝑓𝑛 + (𝑘1 + 2𝑘2 + 2𝑘3 + 𝑘4 )
6
com
𝑘1 = 𝑔(𝑥𝑛 , 𝑓𝑛 )
ℎ ℎ
𝑘2 = 𝑔 (𝑥𝑛 + , 𝑓𝑛 + 𝑘1 )
2 2
ℎ ℎ
𝑘3 = 𝑔 (𝑥𝑛 + , 𝑓𝑛 + 𝑘2 )
2 2
𝑘4 = 𝑔(𝑥𝑛 + ℎ, 𝑓𝑛 + ℎ𝑘3 )
34
Morais & Nogueira – Física Computacional com Python
L = 10
def condutividade(T):
return (3*T/302)-1
def qponto(x,L):
return 500*mt.log(1+x/L)
x = 0
T = 300
xpontos = [x]
Tpontos = [T]
h = L/200
while x<L:
x+=h
# Passo 1 do Runge-Kutta de ordem 3
k1 = (qponto(x,L)/condutividade(T))
# Passo 2 do Runge-Kutta de ordem 3
k2 = (qponto(x+0.5*h,L)/condutividade(T+0.5+h*k1))
# Passo 3 do Runge-Kutta de ordem 3
k3 = (qponto(x+h,L)/condutividade(T-h*k1+2*h*k2))
# Passo final do Runge-Kutta de ordem 3
T += h*(k1+4*k2+k3)/6
xpontos += [x]
35
Morais & Nogueira – Física Computacional com Python
Tpontos += [T]
# Gráficos
plt.xlim(0,x)
plt.ylim(300,T)
plt.plot(xpontos,Tpontos)
plt.xlabel('Comprimento (m)')
plt.ylabel('Temperatura (K)')
plt.show()
Figura 14- Solução numérica da propagação de calor por condução com condutividade com dependência linear
pelo método de Runge-Kutta de terceira ordem.
Modelo de Lotka-Volterra
36
Morais & Nogueira – Física Computacional com Python
Neste caso a solução das equações diferenciais é determinística e contínua. Isso, por
sua vez, implica que as gerações do predador e da presa estão continuamente se sobrepondo.
Sejam 𝑥(𝑡) a população de presas e 𝑦(𝑡) a população de predadores. Podemos considerar que
a taxa com que a população de presas cresce é proporcional ao seu tamanho 𝑑𝑥/𝑑𝑡 ∝ 𝑥 e o a
taxa de mortalidade é proporcional ao número de encontros entre presas e predadores. Esses
encontros são modelados considerando que quanto maior a população de presas e predadores,
mais a probabilidade destes encontros, tal que
37
Morais & Nogueira – Física Computacional com Python
𝑑𝑥
= 𝑎𝑥 − 𝑏𝑥𝑦,
𝑑𝑡
16
38
Morais & Nogueira – Física Computacional com Python
def gx(a,b,x,y):
return (a*x)-(b*x*y)
def gy(c,d,x,y):
return (c*x*y)-(d*y)
while t<tempofinal:
x1 = x
y1 = y
kx1 = gx(a,b,x1,y1)
ky1 = gy(c,d,x1,y1)
x2 = x+0.5*h*kx1
y2 = y+0.5*h*ky1
kx2 = gx(a,b,x2,y2)
ky2 = gy(c,d,x2,y2)
x3 = x+0.5*h*kx2
y3 = y+0.5*h*ky2
kx3 = gx(a,b,x3,y3)
ky3 = gy(c,d,x3,y3)
x4 = x+h*kx3
y4 = y+h*ky3
kx4 = gx(a,b,x4,y4)
ky4 = gy(c,d,x4,y4)
x += h*(kx1+2*kx2+2*kx3+kx4)/6
y += h*(ky1+2*ky2+2*ky3+ky4)/6
t += h
tpontos += [t]
xpontos += [x]
ypontos += [y]
plt.xlim(0,tempofinal)
plt.ylim(0,1.05*max(xpontos))
axs[0].plot(tpontos,xpontos, label='coelhos')
axs[0].plot(tpontos,ypontos, label='raposas')
39
Morais & Nogueira – Física Computacional com Python
plt.scatter(xeq,yeq,color='r',label='ponto de equilibrio')
plt.xlim(min(xpontos),max(xpontos))
plt.ylim(min(ypontos),max(ypontos))
axs[1].plot(xpontos,ypontos)
axs[1].legend()
plt.show()
40
Morais & Nogueira – Física Computacional com Python
𝑃
1 𝑎0 2𝜋𝑡 𝑎0
𝑎̅ = ∫ [1 + cos ( )] 𝑑𝑡 =
𝑃 2 𝑃 2
0
Vamos ver como esse sistema se comporta com um período 𝑃 = 0,25 anos:
m = 20
grav = 9.8
b = 5
41
Morais & Nogueira – Física Computacional com Python
tempo = 0
x = 0
y = 0
vx = v0*mt.cos(ang)
vy = v0*mt.sin(ang)
xpontos = [x]
ypontos = [y]
vxpontos = [vx]
vypontos = [vy]
h = 0.01
print('A velocidade incial na direção x é v0x =', round(vx,3),'m/s')
print('A velocidade incial na direção y é v0y =', round(vy,3),'m/s')
def gvx(b,m,vx):
return -(b/m)*vx
def gvy(grav,b,m,vx):
return -grav-(b/m)*vy
42
Morais & Nogueira – Física Computacional com Python
plt.text(0.3*max(xpontos),0.25*max(ypontos),'Altura máxima =
'+str(round(max(ypontos),2))+' m')
plt.text(0.3*max(xpontos),0.1*max(ypontos),'Alcance =
'+str(round(max(xpontos),2))+' m')
plt.legend()
plt.show()
plt.savefig(‘nome.png’,dpi=200)
Figura 17- Solução pelo método Runge-Kutta de terceira ordem do lançamento de projéteis com resistência do ar
para uma esfera de massa 20 kg, b = 5 N.s/m.
43
Morais & Nogueira – Física Computacional com Python
Para diferentes cenários do terreno, o valor de 𝑘 e 𝑦0 são diferentes. A rugosidade pode ser
modelada como
0,001 𝑚 𝐷𝑒𝑠𝑐𝑎𝑚𝑝𝑎𝑑𝑜/á𝑔𝑢𝑎
𝑦0 = { 1,5 𝑚 𝑆𝑢𝑏ú𝑟𝑏𝑖𝑜
3m 𝐶𝑖𝑑𝑎𝑑𝑒 𝑐𝑜𝑚 𝑝𝑟é𝑑𝑖𝑜𝑠 𝑎𝑙𝑡𝑜𝑠
21
Aqui, vamos utilizar a constante de von Kármán igual a 0,4. A forma do perfil de vento pode
ser vista através do código abaixo.
import matplotlib.pyplot as plt
import math as mt
k =0.4
print('Digite o número para o terreno desejado')
print('1 - terreno descampado')
print('2 - terreno de subúrbio (casas baixas)')
print('3 - terreno de cidade')
opcao = float(input())
if opcao==1:
y0 = 0.001
if opcao==2:
y0 = 1.5
if opcao==3:
y0 = 3
def vento(k,u0,y0,d,y):
return (u0/k)*mt.log((y-d)/y0)
44
Morais & Nogueira – Física Computacional com Python
plt.xlim(0,u)
plt.ylim(0,y)
plt.plot(upontos,ypontos)
plt.xlabel('Velocidade do vento (m/s)')
plt.ylabel('Altura (m)')
plt.show()
Figura 18- Perfil logaritmíco da velocidae do vento na direção horizontal com valores de 𝑦0 definidos no
programa. Constante de von Kármán 𝑘 = 0,4, 𝑑 = 10 m e 𝑢0 = 12 m/s.
Um projétil lançado com velocidade 𝑣⃗0 , onde 𝑣⃗0 faz um ângulo 𝜃 com a direção
perpendicular à aceleração da gravidade está sujeito ao peso dele e a resistência do ar
1
𝐹⃗𝑎 = 𝜌𝐶 𝐴𝑣 ∗ 2 𝑣̂ ∗ ,
2 𝐴
22
45
Morais & Nogueira – Física Computacional com Python
rho0 = 1.225
Tr = 288.15
yr = 0
R = 8.3144598
M = 0.0289644
g0 = 9.81
constante=g0*M/(R*Tr)
def densidade(rho0,y,yr):
return rho0*mt.exp(-constante*(y-yr))
while(y<10000):
y += h
d = densidade(rho0,y,yr)
ypontos += [y]
dpontos += [d]
print(y,d)
plt.xlim(rho0,d)
plt.ylim(0,y)
plt.plot(dpontos,ypontos)
plt.xlabel('Densidade (kg/m3)')
plt.ylabel('Altura (m)')
46
Morais & Nogueira – Física Computacional com Python
plt.show()
Por fim, o problema do lançamento de projéteis sem propulsão próximo à superfície da Terra4
pode ser descrito através das equações (Segunda Lei de Newton)
𝑑𝑥 𝑑𝑣𝑥 𝐹𝐴𝑥
= 𝑣𝑥 , =− ,
𝑑𝑡 𝑑𝑡 𝑚
𝑑𝑦 𝑑𝑣𝑥 𝐹𝐴𝑦
= 𝑣𝑦 , = −𝑔 − ,
𝑑𝑡 𝑑𝑡 𝑚
25
onde
1 2
𝑣𝑥 − 𝑢𝑥 1 (𝑣𝑥 − 𝑢𝑥 )3
𝐹𝐴𝑥 = 𝜌𝐶𝐴 𝐴(𝑣𝑥 − 𝑢𝑥 ) = 𝜌𝐶𝐴 𝐴 ,
2 √(𝑣𝑥 − 𝑢𝑥 )2 + 𝑣𝑦2 2 √(𝑣𝑥 − 𝑢𝑥 )2 + 𝑣𝑦2
26
1 𝑣𝑦 1 𝑣𝑦3
𝐹𝐴𝑦 = 𝜌𝐶𝐴 𝐴𝑣𝑦2 = 𝜌𝐶𝐴 𝐴 ,
2 √(𝑣𝑥 − 𝑢𝑥 )2 + 𝑣𝑦2 2 √(𝑣𝑥 − 𝑢𝑥 )2 + 𝑣𝑦2
27
4
Note que desprezamos as forças inerciais devido a rotação da Terra (força centrífuga e força de
Coriolis), o efeito da curvatura da Terra e a variação da aceleração da gravidade local devido a altura.
47
Morais & Nogueira – Física Computacional com Python
Caso você queira ser mais rigoroso, você poderá utilizar a expressão para a aceleração
da gravidade via Lei da Gravitação Universal de Newton:
𝐺𝑀𝑇 𝐺𝑀𝑇 1 𝑔0
𝑔= = 2 2 = ,
(𝑅𝑇 + 𝑦) 2 𝑅𝑇 𝑦 𝑦 2
(1 + 𝑅 ) (1 + 𝑅 )
𝑇 𝑇
28
Pêndulo Simples
Um exemplo de movimento harmônico simples é o movimento de um pêndulo. Um pêndulo
simples é uma partícula de massa 𝑚 presa por um fio de comprimento 𝐿 e massa desprezível.
Se a partícula for afastada lateralmente até uma posição onde o fio faz um ângulo 𝜃0 com a
direção vertical, e, em seguida, abandonada, o pêndulo oscilará entre a posição inicial e uma
posição simétrica espelhada na direção vertical.
Para determinar o tipo de oscilação, precisamos escrever a equação de movimento da
partícula. A partícula se move num arco de círculo com raio 𝐿. As forças que agem sobre a
⃗⃗ no fio. A componente tangencial da força resultante é
partícula são o peso 𝑚𝑔⃗ e a tensão 𝑇
𝐹𝑇 = −𝑚𝑔 sen 𝜃,
onde o sinal negativo aparece porque ela tem sentido oposto ao deslocamento. A equação
para o movimento tangencial é a segunda lei de Newton 𝐹𝑇 = 𝑚𝑎, e, como a partícula se
move ao longo de um círculo de raio 𝐿 podemos usar o fato que o arco do ângulo 𝜃 é 𝑠 = 𝐿𝜃,
tal que 𝑎 = 𝑑2 𝑠/𝑑𝑡 2 = 𝐿𝑑2 𝜃/𝑑𝑡 2 . A equação para o movimento tangencial é, portanto,
𝑑2𝜃 𝑔
2
= − sen 𝜃 = −𝜔02 sen 𝜃,
𝑑𝑡 𝐿
onde 𝜔0 = √𝑔/𝐿 é a frequência de oscilação do pêndulo para pequenas oscilações. A
solução deste problema analiticamente requer métodos de aproximação, mas o problema se
torna bastante simples se considerarmos apenas pequenas oscilações, tais que sen 𝜃 ≈ 𝜃,
resultando em
48
Morais & Nogueira – Física Computacional com Python
𝑑2 𝜃
= −𝜔02 θ
𝑑𝑡 2
Esta equação tem solução analítica simples e é um oscilador harmônico simples com período
bem definido
𝐿 2𝜋
𝑃0 = 2𝜋√ =
𝑔 𝜔0
Todavia, para oscilações não tão pequenas, podemos mostrar que o período é melhor
aproximado para
2𝜋 1 𝜃0 9 𝜃0
𝑃= (1 + sen2 + sen4 + ⋯ )
𝜔0 4 2 64 2
Vamos escrever um código para obter numericamente o período em função do ângulo inicial
𝜃0 utilizando o Método de Runge-Kutta.
import numpy as np
import math as mt
import matplotlib.pyplot as plt
# definido a equação
def f(an):
# definindo as condições de operação
g = 9.82 # m/s^2
L = 1.00 # m
return -(g/L)*mt.sin(an)
g = 9.82 # m/s^2
L = 1.00 # m
P0 = 2*mt.pi*mt.sqrt(L/g)
# Definindo o incremento do tempo na simulação
h = 0.000025
angulo0 = np.zeros(400)
periodo = np.zeros(400)
for i in range(1,401):
# fazendo um incremento de meio grau no angulo inicial a cada execução
an = mt.radians(0.1*i)
w = 0.
t = 0.
verifica = True
j = 1
while verifica:
an1 = an
w1 = w
t1 = t
ka1 = w1
kw1 = f(an1)
an2 = an+0.5*h*ka1
w2 = w +0.5*h*kw1
t2 = t+0.5*h
ka2 = w2
kw2 = f(an2)
an3 = an+0.5*h*ka2
w3 = w +0.5*h*kw2
49
Morais & Nogueira – Física Computacional com Python
t3 = t+0.5*h
ka3 = w3
kw3 = f(an3)
an4 = an+h*ka3
w4 = w +h*kw3
t4 = t+h
ka4 = w4
kw4 = f(an4)
an += h*(ka1+2*ka2+2*ka3+ka4)/6
w += h*(kw1+2*kw2+2*kw3+kw4)/6
t += h
if (an<=0):
verifica = False
tempoF = t
angulo0[i-1] = 0.1*i
periodo[i-1] = 4.*(tempoF)/P0
# imprimindo o gráfico
plt.xlim(0,40.1)
plt.ylim(1,1.04)
taux = [0]
taux += [40.1]
angaux = [1.01]
angaux += [1.01]
plt.plot(angulo0,periodo,label='P/P0')
plt.plot(taux,angaux,'--',label='linha de 1%')
plt.xlabel('ângulo (graus)')
plt.ylabel('P/P0')
plt.legend()
plt.show()
50
Morais & Nogueira – Física Computacional com Python
Biblioteca SciPy
Até aqui, desenvolvemos todos os nossos códigos, tal que você pode facilmente ecrevê-los
em outras linguagens de programação. Todavia, existem bibliotecas em Python específicas
para integração numérica. O SciPy é uma coleção de algoritmos matemáticos e funções de
conveniência construídas na extensão NumPy do Python. Ele adiciona poder significativo à
sessão interativa do Python, fornecendo ao usuário comandos e classes de alto nível para
manipular e visualizar dados.
Por exemplo, encontramos o método de Runge-Kutta de 4º ordem na SciPy. A formulação
utilizada é descrita em (Dormand & Prince, 1980).
Exemplos
Considere o caso descrito na seção Velocidade Terminal. Vamos utilizar a função
odeint (integração de EDO usando o RK4) para resolver o mesmo problema.
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
# condição inicial
v0 = 0 # m/s
# intervalo de integração
tinicial = 0 #tempo inicial
tfinal = 50 # tempo final
h = 0.01 # incremento temporal
# Esta função arrange cria um vetor entre a e b incrementado de h
t = np.arange(tinicial, tfinal, h)
# solve ODE
v = odeint(modelo,v0,t)
# plot results
plt.plot(t,v)
plt.xlabel('tempo')
plt.ylabel('v(t)')
plt.show()
51
Morais & Nogueira – Física Computacional com Python
52
Morais & Nogueira – Física Computacional com Python
Método Numerov
53
Morais & Nogueira – Física Computacional com Python
𝑑2𝑦
= 𝑔(𝑥)𝑦(𝑥) + 𝑠(𝑥)
𝑑𝑥 2
Equação 29
onde 𝑔(𝑥) e 𝑠(𝑥) são funções de 𝑥 . As expansões em séries de Taylor em torno de 𝑥𝑛 com
passo ℎ são:
𝑑𝑦 ℎ2 𝑑 2 𝑦 ℎ3 𝑑 3 𝑦 ℎ4 𝑑 4 𝑦
𝑦𝑛+1 = 𝑦𝑛 + ℎ ( ) + ( 2) + ( 3) + ( 4) + ⋯
𝑑𝑥 𝑛 2 𝑑𝑥 𝑛 6 𝑑𝑥 𝑛 24 𝑑𝑥 𝑛
𝑑𝑦 ℎ2 𝑑 2 𝑦 ℎ3 𝑑 3 𝑦 ℎ4 𝑑 4 𝑦
𝑦𝑛−1 = 𝑦𝑛 − ℎ ( ) + ( 2 ) − ( 3 ) + ( 4 ) + ⋯
𝑑𝑥 𝑛 2 𝑑𝑥 𝑛 6 𝑑𝑥 𝑛 24 𝑑𝑥 𝑛
onde 𝑦𝑛+1 = 𝑦(𝑥𝑛 + ℎ) e 𝑦𝑛−1 = 𝑦(𝑥𝑛 − ℎ). Somando as duas equações acima, temos
𝑑2 𝑦
2
ℎ4 𝑑 4 𝑦
𝑦𝑛+1 + 𝑦𝑛−1 = 2𝑦𝑛 + ℎ ( 2 ) + ( 4 ) + ⋯
𝑑𝑥 𝑛 12 𝑑𝑥 𝑛
𝑑2 𝑦
Uma vez que 𝑑𝑥 2 = 𝑔𝑛 𝑦𝑛 + 𝑠𝑛 = 𝑓𝑛 , temos
2
ℎ4 𝑑 2 𝑓
𝑦𝑛+1 + 𝑦𝑛−1 = 2𝑦𝑛 + ℎ 𝑓𝑛 + ( ) +⋯
12 𝑑𝑥 2 𝑛
Equação 30
𝑑𝑓 ℎ2 𝑑 2 𝑓 ℎ3 𝑑 3 𝑓 ℎ4 𝑑 4 𝑓
𝑓𝑛−1 = 𝑓𝑛 − ℎ ( ) + ( 2 ) − ( 3 ) + ( ) +⋯
𝑑𝑥 𝑛 2 𝑑𝑥 𝑛 6 𝑑𝑥 𝑛 24 𝑑𝑥 4 𝑛
Note que os termos de maior ordem foram desprezados, visto que 𝑓 já a derivada segunda de
𝑦. Substituindo Equação 31 na Equação 30, temos
ℎ2
𝑦𝑛+1 = 2𝑦𝑛 − 𝑦𝑛−1 + ℎ2 𝑓𝑛 + (𝑓 + 𝑓𝑛−1 − 2𝑓𝑛 )
12 𝑛+1
ou
𝑦𝑛+1 = 2𝑦𝑛 − 𝑦𝑛−1 + ℎ2 (𝑔𝑛 𝑦𝑛 + 𝑠𝑛 )
ℎ2
+ (𝑔𝑛+1 𝑦𝑛+1 + 𝑠𝑛+1 + 𝑔𝑛−1 𝑦𝑛−1 + 𝑠𝑛−1 − 2𝑔𝑛 𝑦𝑛 − 2𝑠𝑛 )
12
Agrupando os termos em cada passo específico, temos
54
Morais & Nogueira – Física Computacional com Python
5ℎ2 ℎ2 ℎ2
2𝑦𝑛 (1 + 𝑔𝑛 ) − 𝑦𝑛−1 (1 − 𝑔𝑛−1 ) + (𝑠 + 10𝑠𝑛 + 𝑠𝑛−1 )
12 12 12 𝑛+1
𝑦𝑛+1 =
ℎ2
(1 − 𝑔𝑛+1 )
12
32
Note que a iteração da equação 32 requer o conhecimento de dois valores de 𝑦 nos passos 𝑛 e
𝑛 − 1, como requerido para solução de qualquer equação diferencial ordinária de ordem 2.
Exemplo. Considere novamente o exemplo do circuito LC com fonte alternada 𝑉 =
𝑉0 sen 𝜔𝑉 𝑡 (veja equação 7) dada pelas equações
𝑑2𝑞 𝑞 𝑉0
2
=− + sen 𝜔𝑉 𝑡
𝑑𝑡 𝐿𝐶 𝐿
33
L = 0.1
C = 0.00045
# as variáveis são
q0 = 0.
I0 = 0.
t0 = 0
# definindo as funções no método de Numerov
g = -1/(L*C)
tau = 2*mt.pi*mt.sqrt(L*C)
# vamos definir o incremento temporal em termos do período
h = 0.01*tau
K = h*h/12
tempo = t0
55
Morais & Nogueira – Física Computacional com Python
q = [q0]
t = [tempo]
#passo de Euler
tempo += h
t += [tempo]
q += [I0*h]
#passos Numerov
while tempo < 5*tau:
tempo += h
t += [tempo]
q += [(2*q[-1]*(1+5*K*g)-(q[-2]*(1-
K*g))+K*(s(tempo+h)+10*s(tempo)+s(tempo-h)))/(1-K*g)]
plt.xlabel("Tempo (s)")
plt.ylabel("Carga (coulombs)")
plt.xlim(0,tempo)
plt.ylim(-1.1*max(q),1.1*max(q))
plt.plot(t,q,label='q(t)')
plt.legend()
plt.show()
56
Morais & Nogueira – Física Computacional com Python
Figura 20- Carga no capacitor com fonte alternada. Note que a carga vai de valores positivos a negativos,
alternando a polaridade no capacitor.
Existe uma grande quantidade de maneiras de se fazer animações em Python. Vamos utilizar
aqui duas maneiras diferentes usando as bibliotecas PIL e Matplotlib Animation. Estas
animações nos serão úteis mais a frente para visualização da dinâmica de sistema de algumas
partículas, como no caso de uma descrição quali-quantitativa da Teoria Cinética dos Gases de
Daniel Bernoulli e da descrição do pêndulo duplo, por exemplo.
Vamos iniciar nossa descrição
# parâmetros
T = 10.
m = 2.
g = 9.8
b = 0.1
v0 = 15
teta = mt.pi/3
v0x = v0*mt.cos(teta)
v0y = v0*mt.sin(teta)
b = 0.1
57
Morais & Nogueira – Física Computacional com Python
# setting a timestep to be 50 ms
dt = 0.05 #s
N = int(T/dt)
# initial conditions:
r[0] = np.array([0., 0.])
v[0] = np.array([v0x, v0y])
# Definindo as forças
def forcax(b,v):
return -b*v
def forcay(b,m,g,v):
return -(m*g)-(b*v)
# Dinâmica dentro do intervalo de pontos N
for n in range(N):
v[n+1,0] = v[n,0] + forcax(b,v[n,0])*dt/m
v[n+1,1] = v[n,1] + forcay(b,m,g,v[n,1])*dt/m
r[n+1] = r[n] + v[n]*dt
# Condição de reflexão elástica no chão
if r[n+1,1]<0:
v[n+1,1]=-v[n+1,1]
# Valores máximos obtidos de x e y
rmaximo = np.max(r,axis=0)
alturay = 15*rmaximo[1]/rmaximo[0]
# Configurando os eixos da figura
fig, ax = plt.subplots(figsize=(15,alturay))
## Ajsutando os limites dos eixos
ax.set(xlim=(0, 1.05*rmaximo[0]), ylim=(0, 1.05*rmaximo[1]), xlabel='x
(m)', ylabel='Altura (m)',title='Esfera com resistência do ar')
# Desenhando o primeiro ponto como círculo marker='o' com cor verde c='g'
de green
# vermelho (red) c='r', azul (blue) c='b', etc e tamanho (size) igual a
s=150
scat = ax.scatter(r[0,0], r[0,1], marker='o', c='r', s=200)
# Animando
def animate(i):
scat.set_offsets(r[i])
ani = animation.FuncAnimation(fig, func=animate, frames=N)
## Esta função cria vários arquivos .png na pasta 'esfera-frames' e cria
uma
# página de simulação html que pode ser aberta em qualquer navegador
ani.save('esfera.html', writer=animation.HTMLWriter(fps= 1//dt))
plt.close()
# Este comando salva um filme em formato .mp4
#ani.save('pedra.mp4', fps= 1//dt)
58
Morais & Nogueira – Física Computacional com Python
calor, que corresponde simplesmente a energia cinética do seu movimento. A teoria não foi
imediatamente aceita, em parte por causa da conservação de energia que não estava bem
estabelecida, e ainda, não era óbvio aos físicos que as colisões entre as moléculas poderiam
ser perfeitamente elásticas.
Considere no nosso problema 𝑁 moléculas idênticas e enumeráveis cada qual com massa 𝑚
localizadas respectivamente nas posições 𝑟⃗𝑖 e tendo velocidades 𝑣⃗𝑖 = 𝑑𝑟⃗𝑖 /𝑑𝑡. A energia
1
cinética de cada molécula é 𝑇𝑖 = 2 𝑚𝑣𝑖2 e a energia cinética total do sistema é
𝑁
1
𝑇 = ∑ 𝑚𝑣𝑖2
2
𝑖=1
Lei de Hooke
Vamos considerar agora o caso em que quatro partículas de massas idênticas estão presas
umas às outras através de molas invisíveis de comprimento 𝐿 e sem massa que obedece a Lei
de Hooke. Isto é, a força agindo entre elas é
𝑟𝑖𝑗 − 𝐿
𝐹𝑖𝑗 = −𝑘 (𝑟⃗𝑖 − 𝑟⃗𝑗 ),
𝑟𝑖𝑗
onde 𝑘 é a constante elástica da mola, 𝑟⃗𝑖 é a posição da partícula 𝑖 e 𝑟𝑖𝑗 = √𝑟⃗𝑖 − 𝑟⃗𝑗 é a
distância entre as partículas. No programa abaixo, vamos utilizar as bibliotecas numpy e
matplotlib. As posições e velocidades iniciais são definidas e as partículas estão confinadas
em uma caixa de lado sete metros centrada na origem.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import animation
fig, ax = plt.subplots(figsize=(6,6))
ax.set(xlim=(-3.5, 3.5), ylim=(-3.5, 3.5), ylabel='metros',
xlabel='metros', title='Quatro Corpos')
# parametros do problema:
# tempo total de simulação
T = 30.
# massa das partículas
m = 1.
# constante da mola
k = 1.
# comprimento da mola
L = 0.5
59
Morais & Nogueira – Física Computacional com Python
v = np.zeros((N+1, 4, 2))
# forças
f = np.zeros((N+1, 4, 2))
# condições iniciais
r[0,0] = np.array([0., 2.])
r[0,1] = np.array([2., 0.])
r[0,2] = np.array([-1., 0.])
r[0,3] = np.array([-1., 1.])
v[0,0] = np.array([0., 1.])
v[0,1] = np.array([0., 1.])
v[0,2] = np.array([0., -1.])
v[0,3] = np.array([-1., 0.])
# Desenhando a animação
scat = ax.scatter(r[0,:,0], r[0,:,1], marker='o', c=['b', 'k', 'r','g'],
s=100)
def animate(i):
scat.set_offsets(r[i])
Pêndulo Simples
60
Morais & Nogueira – Física Computacional com Python
import numpy as np
import math as mt
import matplotlib.pyplot as plt
# definido a equação
def f(an):
# definindo as condições de operação
g = 9.82 # m/s^2
L = 1.00 # m
return -(g/L)*mt.sin(an)
g = 9.82 # m/s^2
L = 1.00 # m
P0 = 2*mt.pi*mt.sqrt(L/g)
# Definindo o incremento do tempo na simulação
h = 0.000025
angulo0 = np.zeros(400)
periodo = np.zeros(400)
for i in range(1,401):
# fazendo um incremento de meio grau no angulo inicial a cada execução
an = mt.radians(0.1*i)
w = 0.
t = 0.
verifica = True
j = 1
while verifica:
an1 = an
w1 = w
t1 = t
ka1 = w1
kw1 = f(an1)
an2 = an+0.5*h*ka1
w2 = w +0.5*h*kw1
t2 = t+0.5*h
61
Morais & Nogueira – Física Computacional com Python
ka2 = w2
kw2 = f(an2)
an3 = an+0.5*h*ka2
w3 = w +0.5*h*kw2
t3 = t+0.5*h
ka3 = w3
kw3 = f(an3)
an4 = an+h*ka3
w4 = w +h*kw3
t4 = t+h
ka4 = w4
kw4 = f(an4)
an += h*(ka1+2*ka2+2*ka3+ka4)/6
w += h*(kw1+2*kw2+2*kw3+kw4)/6
t += h
if (an<=0):
verifica = False
tempoF = t
angulo0[i-1] = 0.1*i
periodo[i-1] = 4.*(tempoF)/P0
print(P0,4*tempoF)
plt.xlim(0,40.1)
plt.ylim(1,1.04)
taux = [0]
taux += [40.1]
angaux = [1.01]
angaux += [1.01]
plt.plot(angulo0,periodo,label='P/P0')
plt.plot(taux,angaux,'--',label='linha de 1%')
plt.xlabel('ângulo (graus)')
plt.ylabel('P/P0')
plt.legend()
plt.show()
Bolinha passando
from PIL import Image, ImageDraw
62
Morais & Nogueira – Física Computacional com Python
frames.append(ellipse(x, y, offset))
x += 10
y += 10
frame_one = frames[0]
frame_one.save("circle.gif", format="GIF", append_images=frames,
save_all=True, duration=100, loop=0)
if _name_ == "_main_":
make_gif()
Pêndulo
# pêndulo
import numpy as np
import matplotlib.pyplot as plt
import math as mt
from matplotlib import animation
# parâmetros
T = 30.
m = 1.
g = 9.8
L = 1.
teta0 = (mt.pi/2)+(mt.pi/6)
teta = teta0
# setting a timestep to be 50 ms
dt = 0.05 #s
N = int(T/dt)
63
Morais & Nogueira – Física Computacional com Python
ymaximo = L*mt.cos(teta)
# vamos guardar os valores de tempo, teta e as posições x e y.
# os valores de x e y iremos guardar no array de duas dimensões r que tem
Nx2 lugares
r = np.zeros((N+1, 2))
r[0] = np.array([xmaximo, ymaximo])
omega = 0.
tempo = 0.
tpontos = [tempo]
tetapts = [(mt.pi-teta)*180/mt.pi]
F0 = 1.
omegaF = mt.sqrt(g/L)#mt.pi
def forca(g,L,teta,F0,omegaF,tempo):
return (g/L)*mt.sin(teta) + F0*mt.sin(omegaF*tempo)
fig, ax = plt.subplots(figsize=(8,8))
## Ajsutando os limites dos eixos
ax.set(xlim=(-1.05, 1.05), ylim=(-1.05, 1.05), xlabel='x (m)', ylabel='y
(m)',title='Pêndulo Forçado')
# Desenhando o primeiro ponto como círculo marker='o' com cor verde c='g'
de green
# vermelho (red) c='r', azul (blue) c='b', etc e tamanho (size) igual a
s=150
scat = ax.scatter(r[0,0],r[0,1], marker='o', c='r', s=400)
def animate(i):
scat.set_offsets(r[i])
# scot.set_offsets(r[i])
ani = animation.FuncAnimation(fig, func=animate, frames=N)
## Esta função cria vários arquivos .png na pasta 'esfera-frames' e cria
uma
# página de simulação html que pode ser aberta em qualquer navegador
ani.save('pendulo.html', writer=animation.HTMLWriter(fps= 1//dt))
64
Morais & Nogueira – Física Computacional com Python
plt.xlabel('tempo (s)')
plt.ylabel('Ângulo (graus)')
plt.xlim(0,T)
plt.ylim(-100,100)
plt.plot(tpontos,tetapts,label=('Ângulo inicial ='+str((mt.pi-
teta0)*180/mt.pi)))
plt.legend()
plt.show()
Pêndulo Duplo
g = 9.8 # m/s^2
L1 = 0.5 # m
L2 = 1.0 # m
L = L1 + L2 # m
m1 = 1.0 # kg
m2 = 1.0 # kg
t_total = 5 # tempo de simulação
history_len = 20 # pontos a serem mostrados
65
Morais & Nogueira – Física Computacional com Python
# condição inicial
state = np.radians([an1, w1, an2, w2])
x1 = L1*sin(y[:, 0])
y1 = -L1*cos(y[:, 0])
x2 = L2*sin(y[:, 2]) + x1
y2 = -L2*cos(y[:, 2]) + y1
def animate(i):
thisx = [0, x1[i], x2[i]]
thisy = [0, y1[i], y2[i]]
if i == 0:
history_x.clear()
history_y.clear()
history_x.appendleft(thisx[2])
history_y.appendleft(thisy[2])
line.set_data(thisx, thisy)
trace.set_data(history_x, history_y)
time_text.set_text(time_template % (i*dt))
return line, trace, time_text
ani = animation.FuncAnimation(
fig, animate, len(y), interval=dt*1000, blit=True)
66
Morais & Nogueira – Física Computacional com Python
plt.show()
67