# # Smoke simulation with wavelet turbulence # (This is a simpler example, a more generic and automated example can be found in waveletTurbObs.py) # from manta import * import os, shutil, math, sys # how much to upres the XL sim? upres = 2 # turbulence strength wltStrength = 0.4 # solver params dim = 2 res = 80 gs = vec3(res,int(1.5*res),res) if (dim==2): gs.z = 1 # 2D sm = Solver(name='main', gridSize = gs, dim=dim) sm.timestep = 1.5 timings = Timings() # note - world space velocity, convert to grid space later velInflow = vec3(0.025, 0, 0) # inflow noise field noise = NoiseField( parent=sm, fixedSeed=265, loadFromFile=True) noise.posScale = vec3(20) noise.clamp = True noise.clampNeg = 0 noise.clampPos = 2 noise.valScale = 1 noise.valOffset = 0.075 noise.timeAnim = 0.3 source = Cylinder( parent=sm, center=gs*vec3(0.3,0.2,0.5), radius=res*0.081, z=gs*vec3(0.081, 0, 0)) sourceVel = Cylinder( parent=sm, center=gs*vec3(0.3,0.2,0.5), radius=res*0.15, z=gs*vec3(0.15, 0, 0)) # larger solver, recompute sizes... xl_gs = vec3(upres*gs.x,upres*gs.y,upres*gs.z) if (dim==2): xl_gs.z = 1 # 2D xl = Solver(name='larger', gridSize = xl_gs, dim=dim) xl.timestep = sm.timestep xl_flags = xl.create(FlagGrid) xl_vel = xl.create(MACGrid) xl_density = xl.create(RealGrid) xl_weight = xl.create(RealGrid) xl_flags.initDomain() xl_flags.fillGrid() xl_source = Cylinder( parent=xl, center=xl_gs*vec3(0.3,0.2,0.5), radius=xl_gs.x*0.081, z=xl_gs*vec3(0.081, 0, 0)) xl_noise = NoiseField( parent=xl, fixedSeed=265, loadFromFile=True) xl_noise.posScale = noise.posScale xl_noise.clamp = noise.clamp xl_noise.clampNeg = noise.clampNeg xl_noise.clampPos = noise.clampPos xl_noise.valScale = noise.valScale xl_noise.valOffset = noise.valOffset xl_noise.timeAnim = noise.timeAnim * upres # wavelet turbulence octaves wltnoise = NoiseField( parent=xl, loadFromFile=True) # scale according to lowres sim , smaller numbers mean larger vortices wltnoise.posScale = vec3( int(1.0*gs.x) ) * 0.5 wltnoise.timeAnim = 0.1 wltnoise2 = NoiseField( parent=xl, loadFromFile=True) wltnoise2.posScale = wltnoise.posScale * 2.0 wltnoise2.timeAnim = 0.1 wltnoise3 = NoiseField( parent=xl, loadFromFile=True) wltnoise3.posScale = wltnoise2.posScale * 2.0 wltnoise3.timeAnim = 0.1 # allocate low-res grids flags = sm.create(FlagGrid) vel = sm.create(MACGrid) density = sm.create(RealGrid) pressure = sm.create(RealGrid) energy = sm.create(RealGrid) bWidth=0 flags.initDomain(boundaryWidth=bWidth) flags.fillGrid() setOpenBound(flags,bWidth,'Y',FlagOutflow|FlagEmpty) if (GUI): gui = Gui() gui.show() # main loop for t in range(200): mantaMsg('\nFrame %i, simulation time %f' % (sm.frame, sm.timeTotal)) advectSemiLagrange(flags=flags, vel=vel, grid=density, order=2) advectSemiLagrange(flags=flags, vel=vel, grid=vel, order=2, openBounds=True, boundaryWidth=bWidth ) applyInflow=False if (sm.timeTotal>=0 and sm.timeTotal<50.): densityInflow( flags=flags, density=density, noise=noise, shape=source, scale=1, sigma=0.5 ) sourceVel.applyToGrid( grid=vel , value=(velInflow*float(res)) ) applyInflow=True setWallBcs(flags=flags, vel=vel) addBuoyancy(density=density, vel=vel, gravity=vec3(0,-1e-3,0), flags=flags) vorticityConfinement( vel=vel, flags=flags, strength=0.3 ) #applyNoiseVec3( flags=flags, target=vel, noise=noise, scale=1 ) # just to test, add everywhere... solvePressure(flags=flags, vel=vel, pressure=pressure , cgMaxIterFac=1.0, cgAccuracy=0.01 ) setWallBcs(flags=flags, vel=vel) computeEnergy(flags=flags, vel=vel, energy=energy) # standard weights for wavelet turbulence computeWaveletCoeffs(energy) # other possibilities of generating turbulence weights: #computeVorticity( vel=vel, vorticity=vort, norm=energy); #computeStrainRateMag( vel=vel, vorticity=vort, mag=energy); sm.step() # xl solver, update up-res'ed grids ... # same inflow interpolateGrid( target=xl_weight, source=energy ) interpolateMACGrid( source=vel, target=xl_vel ) applyNoiseVec3( flags=xl_flags, target=xl_vel, noise=wltnoise, scale=wltStrength*1.0 , weight=xl_weight) # manually weight and apply further octaves applyNoiseVec3( flags=xl_flags, target=xl_vel, noise=wltnoise2, scale=wltStrength*0.6 , weight=xl_weight) applyNoiseVec3( flags=xl_flags, target=xl_vel, noise=wltnoise3, scale=wltStrength*0.6*0.6 , weight=xl_weight) for substep in range(upres): advectSemiLagrange(flags=xl_flags, vel=xl_vel, grid=xl_density, order=2) if (applyInflow): densityInflow( flags=xl_flags, density=xl_density, noise=xl_noise, shape=xl_source, scale=1, sigma=0.5 ) #xl_density.save('densityXl08_%04d.vol' % t) #gui.screenshot( 'waveletTurb_%04d.png' % t ); #timings.display() xl.step()