#
# Simple example of a free-surface simulation with level-set
# (Optionally, demos outflow boundaries)
#
from manta import *
# solver params
dim = 3
res = 64
gs = vec3(res,res,res)
if (dim==2):
gs.z=1
s = Solver(name='main', gridSize = gs, dim=dim)
s.timestep = 0.25
# scene file params
ghostFluid = True
doOpen = False
accuracy = 5e-4
# using fast marching is more accurate, but currently causes asymmetries
useMarching = False
# level set advection 1st/2nd order, 2nd order also introduces slight asymmetries
lsOrder = 1
# prepare grids and particles
flags = s.create(FlagGrid)
vel = s.create(MACGrid)
pressure = s.create(RealGrid)
mesh = s.create(Mesh)
phiBackup = s.create(LevelsetGrid)
# scene setup
bWidth=1
flags.initDomain(boundaryWidth=bWidth)
basin = Box( parent=s, p0=gs*vec3(0,0,0), p1=gs*vec3(1,0.2,1))
drop = Sphere( parent=s , center=gs*vec3(0.5,0.5,0.5), radius=res*0.125)
phi = basin.computeLevelset()
phi.join(drop.computeLevelset())
flags.updateFromLevelset(phi)
# optionally, enable open boundaries here and below...
if doOpen:
setOpenBound(flags,bWidth,'xXzZ',FlagOutflow|FlagEmpty)
if (GUI):
gui = Gui()
gui.show()
#gui.pause()
#main loop
for t in range(2000):
mantaMsg('\nFrame %i, simulation time %f' % (s.frame, s.timeTotal))
# update and advect levelset
if useMarching:
phi.reinitMarching(flags=flags, velTransport=vel)
else:
extrapolateLsSimple(phi=phi, distance=5, inside=False)
extrapolateLsSimple(phi=phi, distance=5, inside=True )
extrapolateMACSimple( flags=flags, vel=vel, distance=5 )
advectSemiLagrange(flags=flags, vel=vel, grid=phi, order=lsOrder)
phi.setBoundNeumann(bWidth)
if doOpen:
resetOutflow(flags=flags,phi=phi) # open boundaries
flags.updateFromLevelset(phi)
# velocity self-advection
advectSemiLagrange(flags=flags, vel=vel, grid=vel, order=2, openBounds=doOpen, boundaryWidth=bWidth )
addGravity(flags=flags, vel=vel, gravity=vec3(0,-0.025,0))
# pressure solve
setWallBcs(flags=flags, vel=vel)
if ghostFluid:
solvePressure(flags=flags, vel=vel, pressure=pressure, cgMaxIterFac=0.5, cgAccuracy=accuracy, phi=phi )
else:
solvePressure(flags=flags, vel=vel, pressure=pressure, cgMaxIterFac=0.5, cgAccuracy=accuracy)
setWallBcs(flags=flags, vel=vel)
# note: these meshes are created by fast marching only, should smooth
# geometry and normals before rendering (only in 3D for now)
if (dim==3):
phi.createMesh(mesh)
#mesh.save('phi%04d.bobj.gz' % t)
s.step()
#gui.screenshot( 'freesurface_%04d.png' % t );