Processing math: 100%

Keplerova úloha - pohyb v centrálním poli

Vložení knihoven

In [10]:
import numpy as np # efektivně implementovaná numerická pole
from scipy.optimize import newton # Newtonova metoda hledání kořene transcendentní rovnice
import matplotlib.pyplot as plt # grafy
import matplotlib.animation as animation # animace

Uvažujeme pohyb v rovině xy, centrum umístěme do počátku soustavy souřadnic. Označme velikost momentu hybnosti (nenulová je pouze z-tová složka). Dále označme E celkovou energii částice, E=12m(˙r2+r2˙ϕ2)αr. Potom s označením p=2mα,e=1+2E2mα2 dostaneme rovnici dráhy pr=1+ecosϕ a dále parametrickou rovnici trajektorie ra=1ecosξ,tτ=ξesinξ, kde a=pe21,τ=ma3α. V kartézských souřadnicích dostaneme xa=cosξe,ya=1e2sinξ,tτ=ξesinξ. Vzdálenosti budeme měřit v jednotkách a a časy v jednotkách τ. Zadat stačí pouze jeden parametr a to excentricitu e elipsy.

In [4]:
e = 0.6

Rozdělíme časový interval [0,π] na N podintervalů.

In [25]:
N = 100
t = np.linspace(0,np.pi,N)

Dále nadefinujeme funkci jejíž kořen budeme hledat, tj. třetí z rovnic trajektorie, její derivaci a Newtonovou metodou provedeme její inverzi. Dále provedeme vektorizaci funkce, tj. aplikujeme na pole t a získáme pole xi.

In [26]:
def koren_kepler(t):
    def kepler_t(x):
        return x - e*np.sin(x)-t
    
    def d_kepler_t(x):
        return 1 -e*np.cos(x)
    
    return newton(kepler_t,t,fprime=d_kepler_t)

vek_koren_kepler = np.vectorize(koren_kepler)

xi = vek_koren_kepler(t)

Dále nadefinujeme pomocí parametru ξ x-ovou a y-ovou souřadnici, rovněž rovnou pomocí polí.

In [27]:
f = (1-e**2)**(1/2)
xp = np.cos(xi) + e
yp = f*np.sin(xi)
x = np.concatenate((xp,np.flipud(xp)))
y = np.concatenate((yp,-np.flipud(yp)))
In [30]:
dt = np.pi/N # časový krok
In [31]:
ax = plt.gca()
%matplotlib inline 
from IPython.display import HTML # pro zobrazení animace v HTML

fig = plt.figure() 

ax.grid(False)
ax = fig.add_subplot(111, autoscale_on=False,aspect='equal', xlim=(-1+e-0.1, 1+e+0.1), ylim=(-f-0.1, f+0.1))

cara, = ax.plot([], [], 'o-', lw=2)
cas_template = 'Čas = %.1f'
cas_text = ax.text(0.05, 0.9, '', transform=ax.transAxes)


def init():
    cara.set_data([], [])
    cas_text.set_text('')
    return cara, cas_text


def animuj(i):
    thisx = [0, x[i]]
    thisy = [0, y[i]]

    cara.set_data(thisx, thisy)
    cas_text.set_text(cas_template % (i*dt))
    return cara, cas_text


ani = animation.FuncAnimation(fig, animuj, np.arange(1, len(y)),
                              interval=25, blit=True, init_func=init)
plt.close()

ani.save('Keplerova_uloha.mp4', fps=15) # animaci uložíme jako video
In [32]:
HTML(ani.to_html5_video())
Out[32]:
In [ ]: