1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155 | #
# 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()
|