Equazione di Euler-Lagrange¶

Consideriamo un sistema meccanico classico descritto mediante il formalismo lagrangiano. Il tempo è rappresentato dalla variabile indipendente $t$ e le coordinate generalizzate sono funzioni del tempo $q(t)$.

La velocità generalizzata è definita come $$ \dot{q}(t) = \frac{dq}{dt}. $$

Il cuore dell’esercizio è la funzione $euler\_lagrange$, che implementa in forma simbolica l’equazione di Eulero--Lagrange associata a un lagrangiano $$ \mathcal{L}(q,\dot{q},t). $$

L’equazione di Eulero--Lagrange è $$ \frac{d}{dt}\left( \frac{\partial \mathcal{L}}{\partial \dot{q}} \right)- \frac{\partial \mathcal{L}}{\partial q} = 0. $$

Nel codice:

  • si calcola la derivata parziale del lagrangiano rispetto a $q$,
  • si calcola la derivata parziale del lagrangiano rispetto a $\dot{q}$,
  • si deriva quest’ultima rispetto al tempo,
  • si restituisce la differenza tra i due termini.

Come esempio viene considerato l’oscillatore armonico unidimensionale, il cui lagrangiano è $$ \mathcal{L} = \frac{1}{2} m \dot{q}^2 - \frac{1}{2} k q^2, $$ dove $m$ è la massa e $k$ la costante elastica.

Applicando l’equazione di Eulero--Lagrange si ottiene $$ m \ddot{q} + k q = 0, $$ che è l’equazione del moto dell’oscillatore armonico.

Successivamente il codice generalizza il formalismo a sistemi con più gradi di libertà. Dato un insieme di coordinate generalizzate $$ \{q_1(t), q_2(t), \dots\}, $$ il lagrangiano totale viene costruito come $$ \mathcal{L} = T - V, $$ dove l’energia cinetica è $$ T = \sum_i \frac{1}{2} m_i \dot{q}_i^2 $$ e il potenziale $V$ può dipendere da tutte le coordinate.

La funzione $hamilton\_principle$ applica il principio di Hamilton, calcolando un’equazione di Eulero--Lagrange per ciascuna coordinata generalizzata. Il risultato è un sistema di equazioni differenziali del secondo ordine che descrive la dinamica completa del sistema.

Infine, il codice tenta di risolvere simbolicamente le equazioni del moto utilizzando $dsolve$. Questo passaggio è puramente computazionale e dipende dalla complessità del potenziale scelto.

In sintesi, l’esercizio mostra come tradurre in modo diretto e rigoroso il formalismo variazionale della meccanica classica in un algoritmo simbolico, capace di:

  • costruire un lagrangiano,
  • derivare automaticamente le equazioni di Eulero--Lagrange,
  • estendersi a sistemi con più gradi di libertà.

Approccio simbolico¶

In [15]:
import sympy as sp

# Definiamo il tempo
t = sp.symbols('t')

# Coordinate generalizzate come funzioni del tempo
q = sp.Function('q')(t)
dq = sp.diff(q, t)

def euler_lagrange(L, q):
    """
    Calcola l'equazione di Eulero-Lagrange per il lagrangiano L(q, dq, t)
    """
    dq = sp.diff(q, t)
    dL_dq = sp.diff(L, q)
    dL_ddq = sp.diff(L, dq)
    ddt_dL_ddq = sp.diff(dL_ddq, t)

    return sp.simplify(ddt_dL_ddq - dL_dq)

# Esempio: oscillatore armonico
m, k = sp.symbols('m k', positive=True)
L_osc = sp.Rational(1, 2) * m * dq**2 - sp.Rational(1, 2) * k * q**2

eq_motion = euler_lagrange(L_osc, q)
aaa = sp.simplify(eq_motion)
print("Eulero-Lagrange Equation:")
display(aaa)

# For systems with multiple degrees of freedom
def multi_dof_lagrangian(masses, potentials, coordinates):
    """
    Construct Lagrangian for a system with multiple degrees of
    freedom.
        :param masses: List of mass coefficients.
        :param potentials: List of potential energy terms.
        :param coordinates: List of generalized coordinates.
    :retum: 
        Lagrangian as a sympy expression.
    """
    kinetic = sum((1/2) * m * sp.diff(q, t)**2 for m, q in zip(masses, coordinates))
    potential = sum(potentials)
    return kinetic - potential

# Coordinate generalizzate
q_1 = sp.Function('q_1')(t)
q_2 = sp.Function('q_2')(t)
coordinates = [q_1, q_2]

# Masse simboliche
m1, m2 = sp.symbols('m1 m2')
masses = [m1, m2]

# Potenziale (esempio generico)
V = sp.Function('V')(q_1, q_2)
potentials = [V]
L_multi_dof = multi_dof_lagrangian(masses, potentials, coordinates)
print("Eulero-Lagrange Equation for multi-dof:")
display(L_multi_dof)

# Hamilton's Principle computational method
def hamilton_principle(initial_conditions, L):
    """
    Apply Hamilton's principle to derive the equations of motion.
        :param initial_conditions: Dictionary of initial conditions.
        :param L: Lagrangian of the system.
    :return: 
        System of Euler-Lagrange equations.
    """
    equations = []
    for coord in initial_conditions.keys():
        equations.append(euler_lagrange(L, coord))
    return equations

initial_conditions = {q_1: 1, q_2: 1}
eom_multi_dof = hamilton_principle(initial_conditions, L_multi_dof)
print("Hamilton Principle")
display(eom_multi_dof[0])
display(eom_multi_dof[1])

# Computational approach to solve E-L equation
def solve_ode(equations, initial_conditions, t_span):
    solutions = {}
    for eq in equations:
        # eq = m * q'' + dV/dq
        ode = sp.Eq(sp.diff(eq, t), 0)  # simbolico placeholder
        try:
            sol = sp.dsolve(eq)
            solutions[str(eq)] = sol
        except Exception as e:
            solutions[str(eq)] = f"Non risolvibile simbolicamente: {e}"
    return solutions

t_span = (0, 10)
solutions_ode = solve_ode(eom_multi_dof, initial_conditions, t_span)
print("Equations of Motion (Harmonic Oscillator):")
display(eq_motion)

"""
print("Equations of Motion (Multi-DOF System):", eom_multi_dof)
print("ODE Solutions:", solutions_ode)
"""
a=1
Eulero-Lagrange Equation:
$\displaystyle k q{\left(t \right)} + m \frac{d^{2}}{d t^{2}} q{\left(t \right)}$
Eulero-Lagrange Equation for multi-dof:
$\displaystyle 0.5 m_{1} \left(\frac{d}{d t} q_{1}{\left(t \right)}\right)^{2} + 0.5 m_{2} \left(\frac{d}{d t} q_{2}{\left(t \right)}\right)^{2} - V{\left(q_{1}{\left(t \right)},q_{2}{\left(t \right)} \right)}$
Hamilton Principle
$\displaystyle 1.0 m_{1} \frac{d^{2}}{d t^{2}} q_{1}{\left(t \right)} + \frac{d}{d q_{1}{\left(t \right)}} V{\left(q_{1}{\left(t \right)},q_{2}{\left(t \right)} \right)}$
$\displaystyle 1.0 m_{2} \frac{d^{2}}{d t^{2}} q_{2}{\left(t \right)} + \frac{d}{d q_{2}{\left(t \right)}} V{\left(q_{1}{\left(t \right)},q_{2}{\left(t \right)} \right)}$
Equations of Motion (Harmonic Oscillator):
$\displaystyle k q{\left(t \right)} + m \frac{d^{2}}{d t^{2}} q{\left(t \right)}$

Esempio numerico : due oscillatori accoppiati¶

Potenziale = $V(q_1​,q_2​)=\frac{1}{2}k(q_1^2​+q_2^2​)+\frac{1}{2}​kc​(q_1​−q_2​)^2$¶

Mostra fenomeni interessanti: battimenti, modi normali, trasferimento di energia¶

In [66]:
import sympy as sp
import numpy as np
from scipy.integrate import solve_ivp
import matplotlib.pyplot as plt

# Parameters
m1_val, m2_val = 1.0, 1.0
k_val, kc_val = 2.0, 0.5

# ODE system manually defined (coupled harmonic oscillators)
def system(t, y):
    q1, dq1, q2, dq2 = y
    ddq1 = -(k_val + kc_val)*q1 + kc_val*q2
    ddq2 = kc_val*q1 - (k_val + kc_val)*q2
    return [dq1, ddq1, dq2, ddq2]

# Initial conditions
y0 = [0.0, 0.0, 1.0, 0.0]

# Time span
t_eval = np.linspace(0, 20, 2000)

sol = solve_ivp(system, (0, 20), y0, t_eval=t_eval)

# Plot
plt.figure(figsize=(6,3))
plt.plot(sol.t, sol.y[0], label="q1(t)")
plt.plot(sol.t, sol.y[2], label="q2(t)")
plt.xlabel("t")
plt.ylabel("q")
plt.legend()
plt.title("Evoluzione q1(t) e q2(t) per oscillatori accoppiati")
plt.show()
No description has been provided for this image
In [ ]: