The Virial Theorem¶
da PowerShell -- jupyter nbconvert --to html notebook.ipynb
Teorema del Viriale¶
Il teorema del Viriale stabilisce una relazione profonda tra l'energia cinetica media di un sistema e le forze che agiscono sulle sue parti. Esso non dipende dai dettagli microscopici del moto, ma solo dalla struttura generale delle interazioni e dal fatto che il sistema sia legato e in equilibrio statistico o dinamico.
Il suo significato fisico è quello di collegare il $\textit{moto}$ alla $\textit{struttura}$ del sistema.
Enunciato generale¶
Per un sistema classico di particelle con Hamiltoniana $$\large H = \sum_i \frac{p_i^2}{2m_i} + V(\{\mathbf{r}_i\}), $$
il teorema del Viriale afferma che, in media temporale o d'insieme, $$\large 2\langle K \rangle = \left\langle \sum_i \mathbf{r}_i \cdot \mathbf{F}_i \right\rangle, $$
dove $K$ è l'energia cinetica totale e $\mathbf{F}_i = -\nabla_i V$ è la forza agente sulla particella $i$.
Potenziali omogenei¶
Se il potenziale è una funzione omogenea delle coordinate di grado $n$, ossia $$\large V(\lambda \mathbf{r}) = \lambda^n V(\mathbf{r}), $$
allora vale la relazione $$\large \sum_i \mathbf{r}_i \cdot \mathbf{F}_i = -n V. $$
Il teorema del Viriale assume quindi la forma semplice $$\large 2\langle K \rangle = n \langle V \rangle. $$
Significato fisico fondamentale¶
Il teorema del Viriale afferma che, per un sistema legato, l'energia cinetica media non è indipendente dal potenziale, ma è determinata dalla $\textit{legge di forza}$ che tiene insieme il sistema.
In altre parole:
- la cinetica misura quanto ``si muovono'' le particelle;
- il potenziale misura quanto ``sono confinate'';
- il Viriale lega questi due aspetti in modo universale.
Esempi fisici¶
Oscillatore armonico¶
Per un potenziale armonico $$\large V = \frac{1}{2} k r^2, $$
si ha $n=2$ e quindi $$\large \langle K \rangle = \langle V \rangle. $$
Fisicamente, il sistema passa in media tanto tempo a muoversi quanto a essere immagazzinato nel potenziale elastico.
Interazione gravitazionale o coulombiana¶
Per $$\large V(r) \propto -\frac{1}{r}, $$
si ha $n=-1$ e quindi $$\large 2\langle K \rangle = -\langle V \rangle. $$
Ne segue che l'energia totale è $$\large E = \langle K \rangle + \langle V \rangle = -\langle K \rangle < 0, $$
condizione caratteristica di un sistema legato.
Interpretazione geometrica¶
Il teorema del Viriale può essere interpretato come una relazione
tra la pressione dinamica dovuta al moto delle particelle
e la forza di richiamo che ne limita l'estensione spaziale.
Esso esprime un bilancio tra tendenza all'espansione (cinetica) e tendenza alla contrazione (potenziale).
Significato statistico¶
In meccanica statistica, il teorema del Viriale giustifica il teorema di equipartizione e spiega perché, in molti sistemi, l'energia media dipenda solo dalla temperatura e non dai dettagli microscopici delle interazioni.
In questo senso, il teorema del Viriale è un ponte concettuale tra meccanica classica e termodinamica.
Conclusione¶
Il teorema del Viriale non è semplicemente una formula, ma una legge strutturale che descrive come un sistema fisico mantiene il proprio equilibrio.
Esso afferma che la forma del potenziale determina come l'energia si distribuisce tra moto e configurazione, indipendentemente dalla complessità del moto stesso.
Legato significa $E_0<0$ cioè a dire orbita ellittica $\rightarrow$ $⟨2T⟩ \sim ⟨|V|⟩$¶
import numpy as np
# --- Parametri sistema ---
N = 10 # Numero di particelle
G = 1.0 # Costante gravitazionale
m = 1.0 # Massa particella
eps = 0.1 # Softening per evitare divergenze
dt = 0.01 # Passo temporale
steps = 15000 # Numero di step totali
relax_steps = 5000 # Numero di step da scartare per rilassamento
# --- Funzione forze e potenziale 3D ---
def gravitational_forces(q, G=1.0, m=1.0, eps=0.1):
N = len(q)
F = np.zeros_like(q)
V = 0.0
for i in range(N):
for j in range(i+1, N):
dx = q[i] - q[j]
r = np.sqrt(np.sum(dx**2) + eps**2)
f = -G * m**2 * dx / r**3
F[i] += f
F[j] -= f
V -= G * m**2 / r
return F, V
# --- Integratore Velocity-Verlet ---
def velocity_verlet(q, p, dt):
F, V = gravitational_forces(q)
p_half = p + 0.5 * F * dt
q_new = q + p_half * dt
F_new, V_new = gravitational_forces(q_new)
p_new = p_half + 0.5 * F_new * dt
return q_new, p_new, V_new
# --- Energia cinetica ---
def kinetic_energy(p):
return 0.5 * np.sum(p**2)
# --- Inizializzazione posizioni ---
q = np.random.uniform(-0.5, 0.5, (N,3))
# --- Calcolo potenziale iniziale ---
_, V0 = gravitational_forces(q)
# --- Impostiamo velocità iniziali per rapporto viriale ~0.5 ---
T_target = 0.5 * abs(V0) # 2T ~ |V|
sigma = np.sqrt(2*T_target / (3*N))
p = np.random.normal(0, sigma, (N,3))
# Rimuoviamo il moto del centro di massa
p -= np.mean(p, axis=0)
print("Energia totale iniziale:", kinetic_energy(p) + V0)
# --- Loop temporale ---
T_acc = 0.0
V_acc = 0.0
count = 0
for i in range(steps):
q, p, V = velocity_verlet(q, p, dt)
T = kinetic_energy(p)
# Consideriamo media solo dopo rilassamento
if i >= relax_steps:
T_acc += 2*T
V_acc += abs(V)
count += 1
# --- Medie finali ---
print("⟨2T⟩ =", T_acc / count)
print("⟨|V|⟩ =", V_acc / count)
#
# ----- tramite FORTRAN con N=100 ratio = 1.06
Energia totale iniziale: -50.57697878411028 ⟨2T⟩ = 45.7372636616797 ⟨|V|⟩ = 71.93998677502071