Kepler Problem¶
da PowerShell -- jupyter nbconvert --to html notebook.ipynb
Nel problema di Kepler si considera una particella di massa $m$ soggetta a un potenziale centrale gravitazionale $$\large V(r) = -\frac{k}{r}, $$ e si introduce l’Hamiltoniana del sistema in coordinate polari piane $$\large H(r,\theta,p_r,p_\theta) = \frac{p_r^2}{2m}\frac{p_\theta^2}{2mr^2}\frac{k}{r}. $$
Poiché l’angolo $\theta$ è una coordinata ciclica, il momento coniugato $$\large p_\theta = L $$ è una costante del moto e coincide con il momento angolare.
Il problema si riduce quindi a un moto unidimensionale nella variabile radiale, governato dall’Hamiltoniana efficace $$\large H_{\text{eff}}(r,p_r) = \frac{p_r^2}{2m} + V_{\text{eff}}(r), \qquad V_{\text{eff}}(r) = \frac{L^2}{2mr^2} - \frac{k}{r}. $$
Le equazioni di Hamilton per il moto radiale sono $$\large \dot r = \frac{\partial H_{\text{eff}}}{\partial p_r} = \frac{p_r}{m}, \qquad \dot p_r = -\frac{\partial H_{\text{eff}}}{\partial r}. $$
L’evoluzione temporale si ottiene integrando queste equazioni. In particolare, fissata l’energia totale $E$, il moto radiale è determinato dalla relazione $$\large \frac{1}{2} m \dot r^2 + V_{\text{eff}}(r) = E, $$ che consente di ricavare il tempo come funzione del raggio tramite $$\large t - t_0 = \int \frac{dr}{\sqrt{\frac{2}{m}\left(E - V_{\text{eff}}(r)\right)}}. $$
Una volta nota $r(t)$, l’evoluzione angolare segue da $$\large \dot\theta = \frac{\partial H}{\partial p_\theta} = \frac{L}{mr^2}, \qquad \theta(t) = \theta_0 + \int \frac{L}{m r(t)^2}\, dt. $$
In questo modo l’evoluzione temporale completa del sistema è ottenuta risolvendo separatamente il moto radiale e quello angolare, sfruttando la conservazione dell’energia e del momento angolare caratteristica del problema di Kepler.
import numpy as np
def reduced_mass(m1, m2):
"""
Calculate the reduced mass of two interacting bodies.
:param ml: Mass of the first body.
:param m2: Mass of the second body.
:return:
Reduced mass.
"""
return (m1 * m2) / (m1 + m2)
def lagrangian(mu, r, theta_dot, phi_dot):
"""
Compute the Lagrangian of the system.
:param mu: Reduced mass.
:param r: Radial distance.
:param theta_dot: Rate of change of theta.
:param phi_dot: Rate of change of phi.
:return:
Lagrangian value.
"""
T = 0.5 * mu * (r**2 * theta_dot**2 + r**2 * np.sin(theta)**2 * phi_dot**2)
U = -G * m1 * m2 / r
return T + U
def hamiltonian(p_r, p_theta, p_phi, mu, r, theta):
"""
Compute the Hamiltonian of the system.
:param p_r: Radial momentum.
:param p_theta: Theta momentum.
:param p_phi: Phi momentum.
:param mu: Reduced mass.
:param r: Radial distance.
:param theta: Theta angle.
:return:
Hamiltonian value.
"""
T = (p_r**2 / (2 * mu)) + (p_theta**2 / (2 * mu * r**2)) + (p_phi**2 / (2 * mu * r**2 * np. sin(theta)**2))
U = -G * m1 * m2 / r
return T + U
def kepler_orbit_simulation(r0, r_dot0, phi0, L, dt, T, mu, G, m1, m2):
t = 0.0
r = r0
r_dot = r_dot0
phi = phi0
r_list = [r]
phi_list = [phi]
while t < T:
# forza radiale efficace
F_r = (-G * m1 * m2 / r**2) + (L**2 / (mu * r**3))
# integrazione (Euler, coerente con il tuo codice)
r_dot += F_r * dt / mu
r += r_dot * dt
phi_dot = L / (mu * r**2)
phi += phi_dot * dt
r_list.append(r)
phi_list.append(phi)
t += dt
return np.array(r_list), np.array(phi_list)
# Parameters for a two-body system
m1 = 5.972e24 # Mass of the Earth (kg)
m2 = 1.989e30 # Mass of the Sun (kg)
G = 6.67430e-11 # Gravitational constant (m''3 kg'-l s'-2)
mu = reduced_mass(m1, m2)
r0 = 1.47e11 # Approximate distance at perihelion (m)
r_dot0 = 0.0 # Initial radial velocity (m/s)
L = 2.66e40 # Assumed angular momentum (kg m^/s)
dt = 86400 # Time step of one day (s)
T = 365.25 * dt # One year in seconds
phi0 = 0.0
r, phi = kepler_orbit_simulation(
r0, r_dot0, phi0, L, dt, T, mu, G, m1, m2
)
x = r * np.cos(phi)
y = r * np.sin(phi)
import matplotlib.pyplot as plt
plt.figure(figsize=(4, 4))
plt.plot(x, y, label="Orbita")
plt.scatter(0, 0, color="orange", s=100, label="Sole")
plt.xlabel("x [m]")
plt.ylabel("y [m]")
plt.axis("equal")
plt.grid()
plt.legend(loc="center left", bbox_to_anchor=(0.6, 0.5))
plt.tight_layout()
plt.title("Orbita kepleriana Terra–Sole")
plt.show()
# Simulating the orbit
#positions, velocities = kepler_orbit_simulation(r0, r_dot0, L, dt, T, mu, G, m1, m2)
# Print results for demonstration
#for i in range(len(positions)):
# print(f"Day {i}: Position (r) = {positions[i]} m. Velocity (r_dot) = {velocities [i]} m/s")