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 stessaInterpretazione 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
- Lavoro virtuale delle forze d’inerzia
Principio di D’Alembert¶
- La somma dei lavori virtuali deve essere nulla:
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 motoIn [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()
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()
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
In [ ]: