entropia_auto.py

Created by gianfranco-oddenino

Created on November 03, 2022

1.65 KB

Script che simula l’espansione libera di un gas perfetto e costruisce in tempo reale la distribuzione delle molecole fra il lato sinistro e il lato destro del contenitore.
All’inizio le molecole sono tutte confinate nella metà sinistra mediante un setto divisorio posto a metà del contenitore. Dopo alcuni secondi il setto divisorio viene rimosso e le molecole possono muoversi liberamente in tutto il contenitore. Contemporaneamente nella parte bassa dello schermo vengono conteggiate le frequenze dei microstati attraverso i quali passa il sistema durante la sua evoluzione. A tal proposito viene utilizzata come variabile atta a caratterizzare i vari microstati la percentuale di molecole presente nella metà sinistra della scatola. Dopo breve tempo si osserva che il sistema evolve verso gli stati a massima probabilità (massima entropia) in cui il 50% delle molecole è nella metà sinistra e l’altro 50% nella metà destra del contenitore.
Numero di molecole: 100
Velocità massima: 10


from random import *
from kandinsky import *

# imposta numero molecole e Vmax
n=100
v=10

# crea l'array f (frequenze)
f=[0 for i in range(n+1)]

# genera n valori casuali per x, y, vx, vy
x=[uniform(50,150) for i in range(n)]
y=[uniform(50,150) for i in range(n)]
vx=[uniform(-v,v) for i in range(n)]
vy=[uniform(-v,v) for i in range(n)]

# disegna l'asse dell'istogramma
fill_rect(50,200,200,1,color(0,0,0))
fill_rect(50,200,1,5,color(0,0,0))
fill_rect(150,200,1,5,color(0,0,0))
fill_rect(250,200,1,5,color(0,0,0))
draw_string("0%        50%      100% sx",41,205)

# disegna la scatola e il setto divisorio
fill_rect(48,48,206,106,color(0,0,0))
fill_rect(50,50,202,102,color(255,255,255))
fill_rect(152,50,1,102,color(0,0,0))

# posizione setto divisorio
d=150; d2=300; setto=True

# inizia la simulazione
h=0
while h<45:
  sx=0
  for i in range(n):
    fill_rect(round(x[i]),round(y[i]),2,2,color(255,255,255))
    x[i]+=vx[i]
    if x[i]<50:
      x[i]=100-x[i]
      vx[i]=-vx[i]
    if x[i]>d:
      x[i]=d2-x[i]
      vx[i]=-vx[i]
    y[i]+=vy[i]
    if y[i]<50:
      y[i]=100-y[i]
      vy[i]=-vy[i]
    if y[i]>150:
      y[i]=300-y[i]
      vy[i]=-vy[i]
    fill_rect(round(x[i]),round(y[i]),2,2,color(0,0,0))

    # conteggia le molecola a sinistra
    if x[i]<150:
      sx+=1
  
  # aggiorna l'istogramma
  f[sx]+=1
  h=round(f[sx]*n/400)
  set_pixel(50+round(sx/n*200),200-h,color(0,0,255))
  draw_string(str(round(sx/n*100))+"%  ",90,30)
  draw_string(str(round((n-sx)/n*100))+"%  ",190,30)
  
  # dopo alcuni secondi rimuove il setto divisorio
  if setto:
    if h>40:
      fill_rect(152,50,1,102,color(255,255,255))
      d=250; d2=500
      setto=False