Coriolis and Centrifugal Forces¶

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

L’esercizio implementa una simulazione del moto di una particella osservata in un sistema di riferimento non inerziale in rotazione.

Dato un sistema che ruota con velocità angolare $\boldsymbol{\omega}$, vengono calcolate le principali forze fittizie:

  • forza centrifuga $-m\,\boldsymbol{\omega}\times(\boldsymbol{\omega}\times\mathbf{r}')$,
  • forza di Coriolis $-2m\,\boldsymbol{\omega}\times\mathbf{v}'$,
  • forza di Eulero (se $\dot{\boldsymbol{\omega}}\neq 0$),
  • contributo dovuto all’accelerazione lineare del riferimento.

La forza totale agente sulla particella è ottenuta sommando le forze reali e quelle fittizie. Da essa si ricava l’accelerazione totale, che viene utilizzata per aggiornare velocità e posizione tramite uno schema di integrazione esplicito di Eulero:

$$\large \mathbf{v}'_{n+1} = \mathbf{v}'_n + \mathbf{a}\,\Delta t, \qquad \mathbf{r}'_{n+1} = \mathbf{r}'_n + \mathbf{v}'_{n+1}\,\Delta t. $$

L’esempio finale mostra un singolo passo temporale del moto di una particella in un sistema rotante con asse $z$.

In [2]:
import numpy as np 

def compute_fictitious_forces(m, omega, r_prime, v_prime, a_0=None, dom_dt=None) :
    """
    Calculate fictitious forces (centrifugal and Coriolis) in a
    rotating frame.
        :param m: Mass of the object.
        :param omega: Angular velocity vector.
        :param r_prime: Position vector in the rotating frame.
        :param v_prime: Velocity vector in the rotating frame.
        :param a_0: Linear acceleration of the rotating frame (default
         is None, meaning stationary frame).
        :param dom_dt: Time derivative of angular velocity (default is
         None for constant angular velocity).
    :return: 
        Total fictitious force vector.
    """
    centrifugal = -m * np.cross(omega, np.cross(omega, r_prime))
    coriolis = -2 * m * np.cross(omega, v_prime)
    euler = np.cross(dom_dt, r_prime) if dom_dt is not None else 0
    inertial = m * (a_0 if a_0 is not None else 0)
    return centrifugal + coriolis + euler - inertial 

def update_system_state(r_prime, v_prime, f_real, m, omega, dt, a_0=None):
    """
    Update the position and velocity of an object in a rotating
    frame considering fictitious forces.
        :param r_prime: Initial position vector in the rotating frame.
        :param v_prime: Initial velocity vector in the rotating frame.
        :param f_real: Real force acting on the object.
        :param m: Mass of the object.
        :param omega: Angular velocity vector.
        :param dt: Time step for the simulation.
        :param a_0: Linear acceleration of the rotating frame (default
         is None, meaning stationary frame).
    :return: 
        Updated position and velocity vectors.
    """
    f_fictitious = compute_fictitious_forces(m, omega, r_prime, v_prime, a_0)
    a_total = (f_real + f_fictitious) / m
    # Update velocity
    v_prime_new = v_prime + a_total * dt
    # Update position
    r_prime_new = r_prime + v_prime_new * dt
    return r_prime_new, v_prime_new

# Example parameters for simulation
m = 1.0
omega = np.array([0, 0, 1])
r_prime = np.array([1, 0, 0])
v_prime = np.array([0, 1, 0])
f_real = np.array([0, 0, 0])
dt = 0.01 # Running the simulation for a single update
r_updated, v_updated = update_system_state(r_prime, v_prime, f_real, m, omega, dt)
print("Updated Position:", r_updated)
print("Updated Velocity:", v_updated)
Updated Position: [1.0003 0.01   0.    ]
Updated Velocity: [0.03 1.   0.  ]
In [ ]: