Trasformazione di Legendre¶
da PowerShell -- jupyter nbconvert --to html notebook.ipynb
Due oscillatori armonici indipendenti - Approccio simbolico¶
In [17]:
import sympy as sp
def legendre_transform(L, q, q_dot, p):
"""
Trasforma un Lagrangiano simbolico in Hamiltoniana.
:param L: Lagrangiano simbolico in termini di q e q_dot
:param q: lista di coordinate simboliche [q1, q2, ...]
:param q_dot: lista di velocità simboliche [q1_dot, q2_dot, ...]
:param p: lista di simboli dei momenti generalizzati [p1, p2, ...]
:return: Hamiltoniana simbolica H(q, p)
"""
# p_i = ∂L/∂q̇_i
p_expr = [sp.diff(L, qd) for qd in q_dot]
# Equazioni p_i - ∂L/∂q̇_i = 0
eqs = [pi - pei for pi, pei in zip(p, p_expr)]
# Risolvi rispetto alle velocità
sol = sp.solve(eqs, q_dot, dict=True)[0]
# Hamiltoniana
H = sum(pi * sol[qd] for pi, qd in zip(p, q_dot)) - L
H = H.subs(sol)
return sp.simplify(H)
def compute_hamiltons_equations(H, q, p):
"""
Calcola le equazioni di Hamilton.
Computes Hamilton_s equations from a given Hamiltonian.
:param H: The Hamiltonian, a function of q, p, and t.
:param q: A list of generalized coordinates.
:param p: A list of generalized momenta.
:return:
List of Hamilton_s equations for q and p.
"""
q_dot_eqs = [sp.diff(H, pi) for pi in p]
p_dot_eqs = [-sp.diff(H, qi) for qi in q]
return q_dot_eqs, p_dot_eqs
# =========================
# ESEMPIO
# =========================
# Simboli
q1, q2 = sp.symbols('q1 q2')
q1_dot, q2_dot = sp.symbols('q1_dot q2_dot')
p1, p2 = sp.symbols('p1 p2')
q = [q1, q2]
q_dot = [q1_dot, q2_dot]
p = [p1, p2]
# Lagrangiano (oscillatore armonico 2D)
L = sp.Rational(1, 2)*(q1_dot**2 + q2_dot**2) \
- sp.Rational(1, 2)*(q1**2 + q2**2)
# Hamiltoniana
H = legendre_transform(L, q, q_dot, p)
# Equazioni di Hamilton
q_dot_eqs, p_dot_eqs = compute_hamiltons_equations(H, q, p)
print("Hamiltoniana H:")
display(H)
print("\nEquazioni di Hamilton:")
print("q_dot =", q_dot_eqs)
print("p_dot =", p_dot_eqs)
Hamiltoniana H:
$\displaystyle \frac{p_{1}^{2}}{2} + \frac{p_{2}^{2}}{2} + \frac{q_{1}^{2}}{2} + \frac{q_{2}^{2}}{2}$
Equazioni di Hamilton: q_dot = [p1, p2] p_dot = [-q1, -q2]
Due oscillatori armonici indipendenti - Approccio numerico¶
In [21]:
import sympy as sp
import numpy as np
from scipy.integrate import solve_ivp
import matplotlib.pyplot as plt
# -------------------------
# Funzioni simboliche
# -------------------------
def legendre_transform(L, q, q_dot, p):
"""Trasforma Lagrangiano simbolico in Hamiltoniana simbolica"""
H = sum(pi*qd for pi, qd in zip(p, q_dot)) - L
subs_dict = {qd: pi for qd, pi in zip(q_dot, p)}
return sp.simplify(H)
def compute_hamiltons_equations(H, q, p):
"""Genera le equazioni canoniche di Hamilton"""
q_dot_eqs = [sp.diff(H, pi) for pi in p]
p_dot_eqs = [-sp.diff(H, qi) for qi in q]
return q_dot_eqs, p_dot_eqs
import sympy as sp
import numpy as np
from scipy.integrate import solve_ivp
import matplotlib.pyplot as plt
# -------------------------
# 1️⃣ Simboli
# -------------------------
q1, q2 = sp.symbols('q1 q2')
p1, p2 = sp.symbols('p1 p2')
# Hamiltoniana H(p,q) direttamente
H = 0.5*(p1**2 + p2**2) + 0.5*(q1**2 + q2**2)
# Equazioni di Hamilton simboliche
q_dot_eqs = [sp.diff(H, pi) for pi in [p1, p2]]
p_dot_eqs = [-sp.diff(H, qi) for qi in [q1, q2]]
# -------------------------
# 2️⃣ Lambdify per numerico
# -------------------------
f_q_dot = sp.lambdify([q1, q2, p1, p2], q_dot_eqs, 'numpy')
f_p_dot = sp.lambdify([q1, q2, p1, p2], p_dot_eqs, 'numpy')
def hamilton_ode(t, Y):
q1_val, q2_val, p1_val, p2_val = Y
dq = f_q_dot(q1_val, q2_val, p1_val, p2_val)
dp = f_p_dot(q1_val, q2_val, p1_val, p2_val)
return [dq[0], dq[1], dp[0], dp[1]]
# -------------------------
# 3️⃣ Condizioni iniziali e integrazione
# -------------------------
Y0 = [1.0, 0.5, 0.0, 0.0] # [q1, q2, p1, p2]
t_span = (0, 20)
t_eval = np.linspace(t_span[0], t_span[1], 500)
sol = solve_ivp(hamilton_ode, t_span, Y0, t_eval=t_eval)
# -------------------------
# 4️⃣ Plot risultati
# -------------------------
plt.figure(figsize=(7,3))
plt.plot(sol.t, sol.y[0], label='q1(t)')
plt.plot(sol.t, sol.y[1], label='q2(t)')
plt.xlabel('t')
plt.ylabel('q1, q2')
plt.title('Oscillatore armonico 2D')
plt.legend()
plt.grid(True)
plt.show()
In [1]:
# Ecco un piccolo calcolo eseguito in Python che mostra come stimare
# un'efficienza "alla Carnot" per la fotosintesi con ipotesi semplici.
# Modifica i parametri (lunghezza d'onda, fotoni per O2, ΔG per glucosio) per esplorare.
import math
# costanti
h = 6.62607015e-34 # J*s
c = 299792458 # m/s
NA = 6.02214076e23 # 1/mol
# parametri (modificabili)
wavelength_nm = 680.0 # nm, tipico per PSII (modifica se vuoi)
photons_per_O2 = 8 # ipotesi comune per flusso lineare (esempio)
deltaG_glucose_kJ_per_mol = 2870.0 # kJ/mol; energia necessaria per formare 1 mol di glucosio da CO2+H2O
# conversioni e calcoli
wavelength_m = wavelength_nm * 1e-9
energy_photon_J = h * c / wavelength_m
energy_photon_kJ_per_mol = energy_photon_J * NA / 1000.0
# numero fotoni per glucosio (6 O2 prodotti per glucosio): photons_per_O2 * 6
photons_per_glucose = photons_per_O2 * 6
# energia luminosa assorbita per mol di glucosio (kJ/mol)
light_energy_per_glucose_kJ = photons_per_glucose * energy_photon_kJ_per_mol
# efficienza (frazione)
efficiency = deltaG_glucose_kJ_per_mol / light_energy_per_glucose_kJ
# stampa risultati
print(f"Lunghezza d'onda (nm): {wavelength_nm}")
print(f"Energia per fotone: {energy_photon_kJ_per_mol:.1f} kJ/mol di fotoni")
print(f"Fotoni per O2 (ipotesi): {photons_per_O2}")
print(f"Fotoni per glucosio (6 O2 prodotti): {photons_per_glucose}")
print(f"Energia luminosa assorbita per mol glucosio: {light_energy_per_glucose_kJ:.1f} kJ/mol")
print(f"ΔG formazione glucosio (ipotesi): {deltaG_glucose_kJ_per_mol:.1f} kJ/mol")
print(f"Efficienza teorica = energia immagazzinata / energia incidente = {efficiency*100:.1f}%")
# Mostriamo anche come cambia l'efficienza variando il numero di fotoni per O2
for p in [8, 10, 12, 15]:
photons = p * 6
light_kJ = photons * energy_photon_kJ_per_mol
eff = deltaG_glucose_kJ_per_mol / light_kJ
print(f" se fotoni/O2 = {p:2d} -> efficienza = {eff*100:5.2f}%")
Lunghezza d'onda (nm): 680.0 Energia per fotone: 175.9 kJ/mol di fotoni Fotoni per O2 (ipotesi): 8 Fotoni per glucosio (6 O2 prodotti): 48 Energia luminosa assorbita per mol glucosio: 8444.2 kJ/mol ΔG formazione glucosio (ipotesi): 2870.0 kJ/mol Efficienza teorica = energia immagazzinata / energia incidente = 34.0% se fotoni/O2 = 8 -> efficienza = 33.99% se fotoni/O2 = 10 -> efficienza = 27.19% se fotoni/O2 = 12 -> efficienza = 22.66% se fotoni/O2 = 15 -> efficienza = 18.13%
In [ ]: