Skip to content

Instantly share code, notes, and snippets.

@juliusgeo
Last active June 21, 2023 10:58
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save juliusgeo/2e63efa2f9a61aa5e94d86b9b53444eb to your computer and use it in GitHub Desktop.
Save juliusgeo/2e63efa2f9a61aa5e94d86b9b53444eb to your computer and use it in GitHub Desktop.
ASCII Eulerian Fluid Simulation in 2kB of Python
import os
timestep=1./60
gravity=-9.81
tg=timestep*gravity
s_x,s_y=10,20
u=v=[[.0 for A in range(s_y)]for A in range(s_x)]
pr=[[.0 for A in range(s_y)]for A in range(s_x)]
st=[[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],[0,1,1,1,1,0,.1,0,0,.1,.1,.1,.1,.1,.1,.1,0,0,0,0],[0,1,1,1,1,1,.1,.1,.1,.1,.1,.1,.1,.1,.1,0,0,0,0,0],[0,1,1,1,1,1,.1,.1,.1,.1,.1,.1,.1,.1,.1,0,0,0,0,0],[0,.1,0,1,1,1,.1,.1,.1,.1,.1,.1,.1,.1,.1,0,0,0,0,0],[0,.1,0,.1,.1,.1,.1,.1,.1,.1,.1,.1,.1,.1,0,0,0,0,0,0],[0,.1,0,.2,.1,.1,.1,0,.1,.1,.1,.1,0,0,0,0,0,0,0,0],[0,.1,0,0,.2,.1,.1,0,.1,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0]]
C=1e3/timestep
loop=[(A,B)for A in range(1,len(u)-1)for B in range(1,len(u[0])-1)]
cl=lambda x,size:0 if x<=0 else size-1 if x>=size else x
sf=lambda i,j,field:((A:=cl(int(i-.5),s_x-1)),(C:=i-.5-A),(E:=cl(A+1,s_x-1)),(B:=cl(int(j-.5),s_y-1)),(D:=j-.5-B),(F:=cl(B+1,s_y-1)),(G:=1.-C),(H:=1.-D),G*H*field[A][B]+C*H*field[E][B]+C*D*field[E][F]+G*D*field[A][F])[-1]
ses='.',':','!','*','o','e','&','#','%','@'
for _ in range(2**10):
u=[[A+tg for A in A]for A in u];v=[[A+tg for A in A]for A in v]
for(i,j)in loop:
l,r,t,b=u[i][j],u[i+1][j],v[i][j],v[i][j+1];ls,rs,ts,bs=st[i-1][j],st[i+1][j],st[i][j-1],st[i][j+1]
if st[i][j]==0:continue
s=ls+rs+ts+bs;d=l-r+t-b;p=-d/s*1.9;pr[i][j]+=p*C;u[i][j],v[i+1][j],u[i][j],v[i][j+1]=l+d*ls,r+d*rs,t+d*ts,b+d*bs
for i in range(len(u)):u[i][0],u[i][s_y-1],v[0][j],v[s_x-1][j]=u[i][1],u[i][s_y-2],v[1][j],v[s_x-2][j]
new_u=new_v=[[.0 for A in range(s_y)]for A in range(s_x)]
for(i,j)in loop:
if st[i][j]!=0 and st[i-1][j]!=0:x,y=i,j+.5;nu,nv=u[i][j],sum((v[i][j],v[i+1][j],v[i][j],v[i][j+1]))/4;x-=timestep*nu;y-=timestep*nv;new_u[i][j]=sf(x//1,y//1,u)
if st[i][j]!=0 and st[i][j-1]!=0:x,y=i+.5,j;nu,nv=sum((u[i][j],u[i+1][j],u[i][j],u[i][j+1]))/4,v[i][j];x-=timestep*nu;y-=timestep*nv;new_v[i][j]=sf(x//1,y//1,v)
u,v=new_u,new_v;os.system('clear')
for line in pr:print(''.join([ses[min(int(abs(A)/C)//10,9)]for A in line]),flush=True)
@juliusgeo
Copy link
Author

juliusgeo commented Jun 20, 2023

asciicast

If you think this is cool, check out the International Obfuscated Python Code Competition

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment