Método de Runge-Kutta 2ª e 4ª ordem: mudanças entre as edições

De Física Computacional
Ir para navegação Ir para pesquisar
Jhordan (discussão | contribs)
Criou página com '= Runge-Kutta 2ª ordem = No método explícito de euler tínhamos: <math display="block">\begin{align} y_{n+1} & =y_{n}+f\left(t_{n},y_{n}\right)\Delta t\end{align}</math>...'
 
Jhordan (discussão | contribs)
Sem resumo de edição
 
(4 revisões intermediárias pelo mesmo usuário não estão sendo mostradas)
Linha 32: Linha 32:
<math display="block">y\left(t+\Delta t\right)=y\left(t\right)+y'\left(t\right)\Delta t+\left(\frac{\partial f}{\partial t}+f\left(t,y\right)\frac{\partial f}{\partial y}\right)\frac{\Delta t^{2}}{2}+\mathcal{O}\left(\Delta^{3}\right)\qquad\left(2\right)</math>
<math display="block">y\left(t+\Delta t\right)=y\left(t\right)+y'\left(t\right)\Delta t+\left(\frac{\partial f}{\partial t}+f\left(t,y\right)\frac{\partial f}{\partial y}\right)\frac{\Delta t^{2}}{2}+\mathcal{O}\left(\Delta^{3}\right)\qquad\left(2\right)</math>


Vamos expandir <math display="inline">k_{2}</math>. Uma expansão de Taylor de primeira ordem para uma função de 2 variáveis em torno de <math display="inline">\left(a,b\right)</math> é dado por<ref>[https://math.libretexts.org/Bookshelves/Calculus/Supplemental_Modules_(Calculus)/Multivariable_Calculus/3%3A_Topics_in_Partial_Derivatives/Taylor__Polynomials_of_Functions_of_Two_Variables
Vamos expandir <math display="inline">k_{2}</math>. Uma expansão de Taylor de primeira ordem para uma função de 2 variáveis em torno de <math display="inline">\left(a,b\right)</math> é dado por <ref> [https://math.libretexts.org/Bookshelves/Calculus/Supplemental_Modules_(Calculus)/Multivariable_Calculus/3%3A_Topics_in_Partial_Derivatives/Taylor__Polynomials_of_Functions_of_Two_Variables Taylor Polynomials of Functions of Two Variables] ( Paul Seeburger, LibreTexts)</ref>:
  Taylor Polynomials of Functions of Two Variables ] ( Paul Seeburger, LibreTexts)</ref>:


<math display="block">f\left(x,y\right)\approx f\left(a,b\right)+f_{x}\left(a,b\right)\left(x-a\right)+f_{y}\left(a,b\right)\left(y-b\right)</math>
<math display="block">f\left(x,y\right)\approx f\left(a,b\right)+f_{x}\left(a,b\right)\left(x-a\right)+f_{y}\left(a,b\right)\left(y-b\right)</math>
Linha 58: Linha 57:
a+b & =1\\
a+b & =1\\
bd & =\frac{1}{2}\\
bd & =\frac{1}{2}\\
bc & =\frac{1}{2}\end{align}</math> Diferentes conjuntos de valore satisfazem este sistema. O método do ponto médio é obtido se ecolhermos: <math display="inline">d=c=\frac{1}{2}</math>, <math display="inline">b=1</math> e <math display="inline">a=-1</math>:
bc & =\frac{1}{2}\end{align}</math> Diferentes conjuntos de valore satisfazem este sistema. O método do ponto médio é obtido se ecolhermos: <math display="inline">d=c=\frac{1}{2}</math>, <math display="inline">b=1</math> e <math display="inline">a=0</math>:


* <math display="inline">k_{2}=f\left(t_{n}+\frac{\Delta t}{2},y_{n}+\frac{k_{1}}{2}\right)\Delta t</math>
* <math display="inline">k_{2}=f\left(t_{n}+\frac{\Delta t}{2},y_{n}+\frac{k_{1}}{2}\right)\Delta t</math>
Linha 75: Linha 74:
y_{n+1} & =y_{n}+\left(k_{1}+k_{2}\right)\frac{1}{2}\end{align}</math>
y_{n+1} & =y_{n}+\left(k_{1}+k_{2}\right)\frac{1}{2}\end{align}</math>


Uma observação, é que o erro global no algoritmo de Runge-Kutta de segunda ordem é <math> \mathcal{O}\left(\Delta^{2}\right) </math) e o local é <math>\mathcal{O}\left(\Delta^{3}\right) </math>.
Uma observação, é que o erro global no algoritmo de Runge-Kutta de segunda ordem é <math> \mathcal{O}\left(\Delta^{2}\right) </math> e o local é <math>\mathcal{O}\left(\Delta^{3}\right) </math>.


==Exemplo ==
==Exemplo ==
Aplicando o algoritmo para o sistema massa-mola visto no [[Método de Euler-Cromer | método de Euler-Cromer]]:
<math display="block"> \frac{d^{2}x}{dt^{2}}=-\frac{k}{m}x=-\omega^{2}x </math>
Podemos ressaltar ainda que <math>a =-\omega^{2}x </math>  e <math>  \frac{dv}{dt}=\frac{d^{2}x}{dt^{2}}</math>.


<pre>
<pre>
import matplotlib.pyplot as plt            #Biblioteca para plotar gráficos
import numpy as np                        #Biblitoeca de cálculos científicos
#Taxas de variação
def fv(x,w2):      #Velocidade
  return (-w2*x)
def fx(v):
  return (v)      #Posição
#Constantes
m=1  ; k= 1.; w2= k/m
#Parâmetros
dt  = 0.0001 ; tau = 2*np.pi; tf=4*tau ; Np= int(tf/dt)
#Valores iniciais
x=[1]; v=[0]; t=[0]; E=[k*x[0]**2/2+m*v[0]**2/2]
#Método Range-Kutta de segunda ordem, no método do ponto médio
for it  in range(Np):
  #Primeira etapa
  k1x = fx(v[it])*dt
  k1v = fv(x[it],w2)*dt
  #Segunda etapa
  k2x = fx(v[it]+k1v/2)*dt
  k2v = fv(x[it]+k1x/2,w2)*dt
  #Solução
  x.append(x[it]+k2x)
  v.append(v[it]+k2v)
  #Energia
  E.append(k*x[it+1]**2/2+m*v[it+1]**2/2)
  #Tempo
  t.append(dt+it*dt)


#plt.plot(t,x)
#plt.plot(t,v)
#plt.plot(t,E)
plt.plot(x,v)
</pre>
</pre>


= Runge-Kutta 4ª ordem =
= Runge-Kutta 4ª ordem =
O método de Runge-Kutta de quarta ordem segue uma ideia similar e pode ser obtido utilizando a mesma técnica. Porém agora vamos ignorar termos de ordem <math display="inline">\Delta t^{5}</math> ou superior, então será necessário lidar com uma enorme quantidade de termos, o que torna a tarefa exaustiva e repetitiva. Logo não será feito esta demonstração aqui, mas o algoritmo de Runge-Kutta de quarta ordem pode ser dado por:


* <math display="inline"> k_{1}=f\left(y_{n},t_{n}\right)\Delta t </math>
* <math display="inline"> k_{2}=f\left(y_{n}+\frac{k_{1}}{2},t_{n}+\frac{\Delta t}{2}\right)\Delta t </math>
* <math display="inline"> k_{3}=f\left(y_{n}+\frac{k_{2}}{2},t_{n}+\frac{\Delta t}{2}\right)\Delta t </math>
* <math display="inline"> k_{4}=f\left(y_{n}+k_{3},t_{n}+\Delta t\right)\Delta t </math>
E por fim, temos então que o novo valor será dado por:
<math display="block">
y_{n+1}=y_{n}+\frac{1}{6}\left(k_{1}+2k_{2}+2k_{3}+k_{4}\right)
</math>


==Exemplo ==
==Exemplo ==
Vamos resolver o mesmo exemplo anterior, porém agora utilizando o Range-Kutta de quarta ordem.
<pre>
import matplotlib.pyplot as plt            #Biblioteca para plotar gráficos
import numpy as np                        #Biblitoeca de cálculos científicos


#Taxas de variação
def fv(x,w2):      #Velocidade
  return (-w2*x)
def fx(v):
  return (v)      #Posição


<pre>
#Constantes
m=1  ; k= 1.; w2= k/m
#Parâmetros
dt  = 0.01 ; tau = 2*np.pi; tf=4*tau ; Np= int(tf/dt)
#Valores iniciais
x=[1]; v=[0]; t=[0]; E=[k*x[0]**2/2+m*v[0]**2/2]
 
#Método Range-Kutta de quarta ordem
for it  in range(Np):
  #Primeira etapa
  k1x = fx(v[it])*dt
  k1v = fv(x[it]    ,w2)*dt
  #Segunda etapa
  k2x = fx(v[it]+k1v/2)*dt
  k2v = fv(x[it]+k1x/2,w2)*dt
  #Terceira etapa
  k3x = fx(v[it]+k2v/2)*dt
  k3v = fv(x[it]+k2x/2,w2)*dt
  #Quarta etapa
  k4x = fx(v[it]+k3v)*dt
  k4v = fv(x[it]+k3x,w2)*dt
  #Solução:
  x.append(x[it]+(k1x+2*k2x+2*k3x+k4x)/6)
  v.append(v[it]+(k1v+2*k2v+2*k3v+k4v)/6)
  #Energia
  E.append(k*x[it+1]**2/2+m*v[it+1]**2/2)
  #Tempo
  t.append(dt+it*dt)


plt.plot(t,x)
plt.plot(t,v)
plt.plot(t,E)
#plt.plot(x,v)
</pre>
</pre>
Ainda podemos chamar a atenção para o fato de que devemos intercalar os coeficientes <math>k_i</math> em ambos os métodos, uma vez que coeficientes seguintes dependem dos valores anteriores.


= Principais materiais utilizados =
= Principais materiais utilizados =


#[https://www.ufrgs.br/reamat/CalculoNumerico/livro-py/pdvi-metodos_de_runge-kutta_explicitos.html  Métodos de Runge-Kutta explícitos ] (REAMAT, UFRGS)
#[https://web.mit.edu/10.001/Web/Course_Notes/Differential_Equations_Notes/node5.html  Runge-Kutta Methods ] (Michael Zeltkevic, Instituto de Tecnologia de Massachusetts)
#[https://web.mit.edu/10.001/Web/Course_Notes/Differential_Equations_Notes/node5.html  Runge-Kutta Methods ] (Michael Zeltkevic, Instituto de Tecnologia de Massachusetts)
#[https://lpsa.swarthmore.edu/NumInt/NumIntSecond.html##section13  Second Order Runge-Kutta ] (Erik Cheever, Swarthmore)
#[https://lpsa.swarthmore.edu/NumInt/NumIntSecond.html##section13  Second Order Runge-Kutta ] (Erik Cheever, Swarthmore)

Edição atual tal como às 21h10min de 25 de março de 2022

Runge-Kutta 2ª ordem

No método explícito de euler tínhamos:

yn+1=yn+f(tn,yn)Δt

Sendo dydt=f(t,y). Podemos reescrever como:

yn+1=yn+ak1

Onde a=1 e k1=f(tn,yn)Δt. Agor se supormos uma solução:

yn+1=yn+ak1+bk2(1) Com o termo adicional dependendo de uma posição genérica yn+cf(tn,yn)Δt em um tempo genérico t+dΔt, isto é k2=f(tn+dΔt,yn+cf(tn,yn)Δt)Δt. Usando o fato de que k1=f(tn,yn)Δt, podemos escrever então que:

  • k1=f(tn,yn)Δt
  • k2=f(tn+dΔt,yn+ck1)Δt

Agora lembrando a expansão em série de taylor que também vimos no método explícito e Euler:

y(t+Δt)=y(t)+y(t)Δt+y(t)Δt22+n=3y(n)(t)Δtnn!

Abrindo a segunda derivada, temos:

y(t)=d2dt2y(t)=ddtf(t,y)=ft+fydydt=ft+f(t,y)fy

Substituindo então, e escrevendo apenas 𝒪(Δ3)=n=3y(n)(t)Δtnn!, temos a seguinte expansão em série de Taylor:

y(t+Δt)=y(t)+y(t)Δt+(ft+f(t,y)fy)Δt22+𝒪(Δ3)(2)

Vamos expandir k2. Uma expansão de Taylor de primeira ordem para uma função de 2 variáveis em torno de (a,b) é dado por [1]:

f(x,y)f(a,b)+fx(a,b)(xa)+fy(a,b)(yb)

Onde fa denota a derivada da função f na variável a. Para o nosso caso, temos então para uma expansão em torno de (x,y):

f(x+Δx,y+Δy)f(x,y)+fx(x,y)Δx+fy(x,y)Δy

Expandindo então k2 em torno de (tn,yn) temos:

k2[f(tn,yn)+dΔttf(tn,yn)+ck1yf(tn,yn)]Δt

Aqui podemos notar que Δt multiplica a expansão da função, então quando desprezamos os termos de segunda ordem da expansão de f(x+Δx,y+Δy), deprezamos os termos de terceira ordem de k2. Substituindo então o k2aproximado e k1 na equação 1, temos:

yn+1=yn+af(tn,yn)Δt+b[f(tn,yn)+dΔttf(tn,yn)+cf(tn,yn)Δtyf(tn,yn)]Δt

Manipulando:

yn+1=yn+(a+b)f(tn,yn)Δt+[2bdtf(tn,yn)+2bcf(tn,yn)yf(tn,yn)]Δt22(3)

Comparando a aproximação 3 com a expansão 2 temos a seguinte relação:

a+b=1bd=12bc=12 Diferentes conjuntos de valore satisfazem este sistema. O método do ponto médio é obtido se ecolhermos: d=c=12, b=1 e a=0:

  • k2=f(tn+Δt2,yn+k12)Δt

Então:

yn+1=yn+f(tn+Δt2,yn+f(tn,yn)Δt2)Δt

O método de Heun é obtido se for escolhido a=b=12 e c=d=1:

  • k1=f(tn,yn)Δt
  • k2=f(tn+Δt,yn+k1Δt)Δt

yn+1=yn+(k1+k2)12

Uma observação, é que o erro global no algoritmo de Runge-Kutta de segunda ordem é 𝒪(Δ2) e o local é 𝒪(Δ3).

Exemplo

Aplicando o algoritmo para o sistema massa-mola visto no método de Euler-Cromer: d2xdt2=kmx=ω2x

Podemos ressaltar ainda que a=ω2x e dvdt=d2xdt2.


import matplotlib.pyplot as plt            #Biblioteca para plotar gráficos
import numpy as np                         #Biblitoeca de cálculos científicos

#Taxas de variação
def fv(x,w2):      #Velocidade
  return (-w2*x)
def fx(v):
  return (v)       #Posição

#Constantes
m=1  ; k= 1.; w2= k/m
#Parâmetros
dt  = 0.0001 ; tau = 2*np.pi; tf=4*tau ; Np= int(tf/dt)
#Valores iniciais
x=[1]; v=[0]; t=[0]; E=[k*x[0]**2/2+m*v[0]**2/2]

#Método Range-Kutta de segunda ordem, no método do ponto médio
for it  in range(Np):
  #Primeira etapa
  k1x = fx(v[it])*dt
  k1v = fv(x[it],w2)*dt
  #Segunda etapa
  k2x = fx(v[it]+k1v/2)*dt
  k2v = fv(x[it]+k1x/2,w2)*dt
  #Solução
  x.append(x[it]+k2x)
  v.append(v[it]+k2v)
  #Energia
  E.append(k*x[it+1]**2/2+m*v[it+1]**2/2)
  #Tempo
  t.append(dt+it*dt)

#plt.plot(t,x)
#plt.plot(t,v)
#plt.plot(t,E)
plt.plot(x,v)

Runge-Kutta 4ª ordem

O método de Runge-Kutta de quarta ordem segue uma ideia similar e pode ser obtido utilizando a mesma técnica. Porém agora vamos ignorar termos de ordem Δt5 ou superior, então será necessário lidar com uma enorme quantidade de termos, o que torna a tarefa exaustiva e repetitiva. Logo não será feito esta demonstração aqui, mas o algoritmo de Runge-Kutta de quarta ordem pode ser dado por:


  • k1=f(yn,tn)Δt
  • k2=f(yn+k12,tn+Δt2)Δt
  • k3=f(yn+k22,tn+Δt2)Δt
  • k4=f(yn+k3,tn+Δt)Δt

E por fim, temos então que o novo valor será dado por:

yn+1=yn+16(k1+2k2+2k3+k4)

Exemplo

Vamos resolver o mesmo exemplo anterior, porém agora utilizando o Range-Kutta de quarta ordem.

import matplotlib.pyplot as plt            #Biblioteca para plotar gráficos
import numpy as np                         #Biblitoeca de cálculos científicos

#Taxas de variação
def fv(x,w2):      #Velocidade
  return (-w2*x)
def fx(v):
  return (v)       #Posição

#Constantes
m=1  ; k= 1.; w2= k/m
#Parâmetros
dt  = 0.01 ; tau = 2*np.pi; tf=4*tau ; Np= int(tf/dt)
#Valores iniciais
x=[1]; v=[0]; t=[0]; E=[k*x[0]**2/2+m*v[0]**2/2]

#Método Range-Kutta de quarta ordem
for it  in range(Np):
  #Primeira etapa
  k1x = fx(v[it])*dt
  k1v = fv(x[it]     ,w2)*dt
  #Segunda etapa
  k2x = fx(v[it]+k1v/2)*dt
  k2v = fv(x[it]+k1x/2,w2)*dt
  #Terceira etapa
  k3x = fx(v[it]+k2v/2)*dt
  k3v = fv(x[it]+k2x/2,w2)*dt
  #Quarta etapa
  k4x = fx(v[it]+k3v)*dt
  k4v = fv(x[it]+k3x,w2)*dt
  #Solução:
  x.append(x[it]+(k1x+2*k2x+2*k3x+k4x)/6)
  v.append(v[it]+(k1v+2*k2v+2*k3v+k4v)/6)
  #Energia
  E.append(k*x[it+1]**2/2+m*v[it+1]**2/2)
  #Tempo
  t.append(dt+it*dt)

plt.plot(t,x)
plt.plot(t,v)
plt.plot(t,E)
#plt.plot(x,v)

Ainda podemos chamar a atenção para o fato de que devemos intercalar os coeficientes ki em ambos os métodos, uma vez que coeficientes seguintes dependem dos valores anteriores.

Principais materiais utilizados

  1. Métodos de Runge-Kutta explícitos (REAMAT, UFRGS)
  2. Runge-Kutta Methods (Michael Zeltkevic, Instituto de Tecnologia de Massachusetts)
  3. Second Order Runge-Kutta (Erik Cheever, Swarthmore)

Citações