D’Alembert’s Principle¶

da PowerShell -- jupyter nbconvert --to html notebook.ipynb

Il moto di un sistema può essere visto come un equilibrio virtuale, se alle forze reali si aggiungono opportune forze d’inerzia¶

  • un problema dinamico viene ricondotto a una forma statica
  • ma formulata in termini di lavori virtuali

$\large F-m\cdot a=0 \qquad$ D'Alembert interpreta $m\cdot a$ come una forza fittizia detta forza d’inerzia

  • Nei lavori virtuali classici:
    • il sistema è in equilibrio
    • non c’è accelerazione
    • le forze d’inerzia sono nulle

-

- Con D’Alembert: - il sistema può essere in moto - le accelerazioni sono non nulle - ma la struttura matematica è la stessa

Interpretazione fisica¶

  • D’Alembert dice: se ti metti su un sistema che “segue” l’accelerazione del punto, il punto sembra in equilibrio sotto l’azione delle forze reali e di una forza opposta all’accelerazione.
  • Non è un artificio matematico fine a sé stesso:
  • è un modo per descrivere la dinamica
  • usando gli strumenti concettuali della statica

Cosa succede alle reazioni vincolari¶

  • Esattamente come nei lavori virtuali:
  • gli spostamenti virtuali rispettano i vincoli
  • le reazioni ideali non compiono lavoro virtuale
  • quindi spariscono dalla formulazione
  • Questo è uno dei punti più potenti del principio.

Trave incernierata a sinistra, scorrevole in orizzontale a destra, soggetta a suo peso¶

  • lo spostamento virtuale ammissibile è $\delta \theta$ nella cerniera
  • lo spostamento del baridentro (compon. vert.) è dato da $\delta_{yG}=L/2\, cos(\theta)\, d\theta$

Forze reali¶

  • forza di fravità $mg$ applicata a baricentro

Forze d'inerzia (D'Alembert)¶

  • forza traslazionale $F_{inerzia}=m\, a_G$
  • momento rotazionale $M_{inerzia}=-I_G\, \ddot{\theta} \qquad$ $I_G$ = momento di inerzia rispetto al baricentro

Lavori virtuali¶

  • Lavoro virtuale del peso
$$\large \delta L_P=mg\, \delta_{yG}=-mg\frac{L}{2}cos\theta\, d\theta$$
  • Lavoro virtuale delle forze d’inerzia
$$\large \delta L_{inerzia}=-I_O\, \ddot \theta \delta \theta \qquad dove \qquad I_O = momento\; rispetto\; alla\; cerniera$$$$\large I_O=I_G+m\left( \frac{L}{2} \right)^2=\frac{1}{3}mL^2$$

Principio di D’Alembert¶

  • La somma dei lavori virtuali deve essere nulla:
$$\large \delta L_P+\delta L_{inerzia}=0 \qquad cioè$$$$\large \left( -mg\frac{L}{2}cos\theta-I_O\ddot \theta \right)\, \delta \theta=0 \qquad poiché\; \delta \theta \qquad è\; arbitrario$$$$\large I_O\, \ddot \theta+mg\frac{L}{2}cos\theta =0 \qquad sostituendo \qquad I_O=\frac{1}{3}mL^2$$$$\large \frac{1}{3}mL^2 \ddot \theta+mg\frac{L}{2}cos\theta =0 \qquad semplificando \qquad \ddot \theta+\frac{3g}{2L}cos\theta=0$$

Interpretazione fisica¶

  • Non esiste equilibrio statico
  • Il peso genera un momento motore
  • La trave ruota accelerando
  • L’equazione è non lineare (coseno)

-

#### D’Alembert ti ha permesso di: - ignorare completamente le reazioni - lavorare su un solo grado di libertà - ottenere direttamente l’equazione del moto
In [34]:
import numpy as np
from scipy.integrate import solve_ivp
import matplotlib.pyplot as plt

# parametri fisici
g = 9.81      # m/s^2
L = 1.0       # m

# sistema dinamico
def trave_dalembert(t, x):
    theta, theta_dot = x
    theta_ddot = -(3 * g / (2 * L)) * np.cos(theta)
    return [theta_dot, theta_ddot]

# condizioni iniziali
theta0 = 0.2        # rad
theta_dot0 = 0.0   # rad/s
x0 = [theta0, theta_dot0]

# intervallo temporale
t_span = (0.0, 5.0)
t_eval = np.linspace(*t_span, 1000)

# integrazione
sol = solve_ivp(
    trave_dalembert,
    t_span,
    x0,
    t_eval=t_eval,
    rtol=1e-9,
    atol=1e-9
)

# grafico
plt.plot(sol.t, sol.y[0])
plt.xlabel("tempo [s]")
plt.ylabel("theta [rad]")
plt.grid(True)
plt.show()
No description has been provided for this image
In [3]:
import numpy as np 

def compute_inertial_forces(masses, accelerations):
    """
    Compute inertial forces for a set of particles.
        :param masses: List of masses for each particle.
        :param accelerations: List of accelerations for each particle.
    :return: List of inertial forces.
    """
    return [-m * a for m, a in zip(masses, accelerations)]

def calculate_virtual_work(forces, virtual_displacements):
    """
    Calculate virtual work done by forces during virtual displacements.
        :param forces: List of forces acting on each particle.
        :param virtual_displacements: List of virtual displacements for
         each particle.
    :return: Total virtual work.
    """
    return sum(f * d for f, d in zip(forces, virtual_displacements))

def solve_equations_of_motion(masses, applied_forces, initial_conditions, time_step, total_time):
    positions, velocities = initial_conditions
    times = np.arange(0, total_time, time_step)

    num_particles = len(masses)
    trajectories = np.zeros((len(times), num_particles * 2))

    for t_idx, t in enumerate(times):

        # D'Alembert -> m a = F
        accelerations = [f / m for f, m in zip(applied_forces, masses)]

        # procedo con Eulero
        for i in range(num_particles):
            velocities[i] += accelerations[i] * time_step
            positions[i] += velocities[i] * time_step

            trajectories[t_idx, i] = positions[i]
            trajectories[t_idx, i + num_particles] = velocities[i]

    return trajectories
    
# Example usage
masses = [1.0, 2.0] # masses of two particles
applied_forces = [10.0, 5.0] # forces applied on two particles
initial_conditions = (np.array([0.0, 0.0]), np.array([0.0, 0.0])) # initial positions and velocities
time_step = 0.01
total_time =2.0

trajectories = solve_equations_of_motion(masses, applied_forces, initial_conditions, time_step, total_time)
x = trajectories[:,0]
y = trajectories[:,1]
times = np.arange(0, total_time, time_step)
ax = trajectories[:,2]
ay = trajectories[:,3]

import matplotlib.pyplot as plt
plt.xlabel("Tempo [s]")
plt.ylabel("Posizione x(t)")
plt.plot(times,x)
plt.title("Moto ottenuto tramite PLV + d'Alembert")
plt.grid()
plt.show()
No description has been provided for this image
In [58]:
import numpy as np
import matplotlib.pyplot as plt

# --- Parametri del problema ---
m = 1.0           # massa (kg)
F = 2.0           # forza costante (N)
x0 = 0.0          # posizione iniziale
v0 = 0.0          # velocità iniziale
dt = 0.01         # passo temporale
T = 2.0           # tempo totale di simulazione

# --- Equazione ottenuta dal PLV ---
# m * a = F  ->  a = F/m

def acceleration(x, v):
    return F / m

# --- Integrazione numerica semplice (Euler) ---
times = np.arange(0, T + dt, dt)
x = np.zeros_like(times)
v = np.zeros_like(times)

x[0] = x0
v[0] = v0

for i in range(len(times) - 1):
    a = acceleration(x[i], v[i])

    # Aggiornamento (schema di Eulero)
    v[i+1] = v[i] + a * dt
    x[i+1] = x[i] + v[i] * dt

# --- Output finale ---
print("Posizione finale:", x[-1])
print("Velocità finale:", v[-1])

# --- Grafico ---
plt.plot(times, x)
plt.xlabel("Tempo [s]")
plt.ylabel("Posizione x(t)")
plt.title("Moto ottenuto tramite PLV + d'Alembert")
plt.grid()
plt.show()
Posizione finale: 3.980000000000002
Velocità finale: 4.000000000000003
No description has been provided for this image
In [ ]: