2
########################################################
4
# Copyright (c) 2003-2010 by University of Queensland
5
# Earth Systems Science Computational Center (ESSCC)
6
# http://www.uq.edu.au/esscc
8
# Primary Business: Queensland, Australia
9
# Licensed under the Open Software License version 3.0
10
# http://www.opensource.org/licenses/osl-3.0.php
12
########################################################
14
__copyright__="""Copyright (c) 2003-2010 by University of Queensland
15
Earth Systems Science Computational Center (ESSCC)
16
http://www.uq.edu.au/esscc
17
Primary Business: Queensland, Australia"""
18
__license__="""Licensed under the Open Software License version 3.0
19
http://www.opensource.org/licenses/osl-3.0.php"""
20
__url__="https://launchpad.net/escript-finley"
23
################################################
27
## 3D Rayleigh-Taylor instability benchmark ##
28
## by Laurent Bourgouin ##
30
################################################
34
from esys.escript import *
36
from esys.dudley import dudley
37
from esys.escript.linearPDEs import LinearPDE
38
from esys.escript.pdetools import Projector, SaddlePointProblem
42
### DEFINITION OF THE DOMAIN ###
47
mesh=esys.dudley.Brick(l0=l0, l1=l1, l2=l0, order=2, n0=n0, n1=n1, n2=n0)
49
### PARAMETERS OF THE SIMULATION ###
50
rho1 = 1.0e3 # DENSITY OF THE FLUID AT THE BOTTOM
51
rho2 = 1.01e3 # DENSITY OF THE FLUID ON TOP
52
eta1 = 1.0e2 # VISCOSITY OF THE FLUID AT THE BOTTOM
53
eta2 = 1.0e2 # VISCOSITY OF THE FLUID ON TOP
54
penalty = 1.0e3 # PENALTY FACTOR FOT THE PENALTY METHOD
58
reinit_max = 30 # NUMBER OF ITERATIONS DURING THE REINITIALISATION PROCEDURE
59
reinit_each = 3 # NUMBER OF TIME STEPS BETWEEN TWO REINITIALISATIONS
60
h = Lsup(mesh.getSize())
61
numDim = mesh.getDim()
62
smooth = h*2.0 # SMOOTHING PARAMETER FOR THE TRANSITION ACROSS THE INTERFACE
64
### DEFINITION OF THE PDE ###
65
velocityPDE = LinearPDE(mesh, numEquations=numDim)
67
advectPDE = LinearPDE(mesh)
68
advectPDE.setReducedOrderOn()
69
advectPDE.setValue(D=1.0)
70
advectPDE.setSolverMethod(solver=LinearPDE.DIRECT)
72
reinitPDE = LinearPDE(mesh, numEquations=1)
73
reinitPDE.setReducedOrderOn()
74
reinitPDE.setSolverMethod(solver=LinearPDE.LUMPING)
75
my_proj=Projector(mesh)
77
### BOUNDARY CONDITIONS ###
81
top = whereZero(zz-l1)
82
bottom = whereZero(zz)
84
right = whereZero(xx-l0)
86
back = whereZero(yy-l0)
87
b_c = (bottom+top)*[1.0, 1.0, 1.0] + (left+right)*[1.0,0.0, 0.0] + (front+back)*[0.0, 1.0, 0.0]
88
velocityPDE.setValue(q = b_c)
90
pressure = Scalar(0.0, ContinuousFunction(mesh))
91
velocity = Vector(0.0, ContinuousFunction(mesh))
93
### INITIALISATION OF THE INTERFACE ###
94
func = -(-0.1*cos(math.pi*xx/l0)*cos(math.pi*yy/l0)-zz+0.4)
95
phi = func.interpolate(ReducedSolution(mesh))
98
def advect(phi, velocity, dt):
99
### SOLVES THE ADVECTION EQUATION ###
101
Y = phi.interpolate(Function(mesh))
102
for i in range(numDim):
103
Y -= (dt/2.0)*velocity[i]*grad(phi)[i]
104
advectPDE.setValue(Y=Y)
105
phi_half = advectPDE.getSolution()
108
for i in range(numDim):
109
Y -= dt*velocity[i]*grad(phi_half)[i]
110
advectPDE.setValue(Y=Y)
111
phi = advectPDE.getSolution()
113
print "Advection step done"
116
def reinitialise(phi):
117
### SOLVES THE REINITIALISATION EQUATION ###
118
s = sign(phi.interpolate(Function(mesh)))
119
w = s*grad(phi)/length(grad(phi))
123
mask = whereNegative(abs(phi)-1.2*h)
124
reinitPDE.setValue(q=mask, r=phi)
125
print "Reinitialisation started."
126
while (iter<=reinit_max):
128
for i in range(numDim):
129
prod_scal += w[i]*grad(phi)[i]
130
coeff = s - prod_scal
132
for i in range(numDim):
133
ps2 += w[i]*grad(my_proj(coeff))[i]
134
reinitPDE.setValue(D=1.0, Y=phi+dtau*coeff-0.5*dtau**2*ps2)
135
phi = reinitPDE.getSolution()
136
error = Lsup((previous-phi)*whereNegative(abs(phi)-3.0*h))/h
137
print "Reinitialisation iteration :", iter, " error:", error
140
print "Reinitialisation finalized."
143
def update_phi(phi, velocity, dt, t_step):
144
### CALLS THE ADVECTION PROCEDURE AND THE REINITIALISATION IF NECESSARY ###
145
phi=advect(phi, velocity, dt)
146
if t_step%reinit_each ==0:
147
phi = reinitialise(phi)
150
def update_parameter(phi, param_neg, param_pos):
151
### UPDATES THE PARAMETERS TABLE USING THE SIGN OF PHI, A SMOOTH TRANSITION IS DONE ACROSS THE INTERFACE ###
152
mask_neg = whereNonNegative(-phi-smooth)
153
mask_pos = whereNonNegative(phi-smooth)
154
mask_interface = whereNegative(abs(phi)-smooth)
155
param = param_pos*mask_pos + param_neg*mask_neg + ((param_pos+param_neg)/2 +(param_pos-param_neg)*phi/(2.*smooth))*mask_interface
158
class StokesProblem(SaddlePointProblem):
160
simple example of saddle point problem
162
def __init__(self,domain,debug=False):
163
super(StokesProblem, self).__init__(self,debug)
165
self.__pde_u=LinearPDE(domain,numEquations=self.domain.getDim(),numSolutions=self.domain.getDim())
166
self.__pde_u.setSymmetryOn()
168
self.__pde_p=LinearPDE(domain)
169
self.__pde_p.setReducedOrderOn()
170
self.__pde_p.setSymmetryOn()
172
def initialize(self,f=Data(),fixed_u_mask=Data(),eta=1):
174
A =self.__pde_u.createCoefficientOfGeneralPDE("A")
175
for i in range(self.domain.getDim()):
176
for j in range(self.domain.getDim()):
177
A[i,j,j,i] += self.eta
178
A[i,j,i,j] += self.eta
179
self.__pde_p.setValue(D=1/self.eta)
180
self.__pde_u.setValue(A=A,q=fixed_u_mask,Y=f)
182
def inner(self,p0,p1):
183
return integrate(p0*p1,Function(self.__pde_p.getDomain()))
185
def solve_f(self,u,p,tol=1.e-8):
186
self.__pde_u.setTolerance(tol)
188
self.__pde_u.setValue(X=self.eta*symmetric(g)+p*kronecker(self.__pde_u.getDomain()))
189
return self.__pde_u.getSolution()
191
def solve_g(self,u,tol=1.e-8):
192
self.__pde_p.setTolerance(tol)
193
self.__pde_p.setValue(X=-u)
194
dp=self.__pde_p.getSolution()
197
sol=StokesProblem(velocity.getDomain(),debug=True)
198
def solve_vel_uszawa(rho, eta, velocity, pressure):
199
### SOLVES THE VELOCITY PROBLEM USING A PENALTY METHOD FOR THE INCOMPRESSIBILITY ###
200
Y = Vector(0.0,Function(mesh))
202
sol.initialize(fixed_u_mask=b_c,eta=eta,f=Y)
203
velocity,pressure=sol.solve(velocity,pressure,iter_max=100,tolerance=0.01) #,accepted_reduction=None)
204
return velocity, pressure
206
def solve_vel_penalty(rho, eta, velocity, pressure):
207
### SOLVES THE VELOCITY PROBLEM USING A PENALTY METHOD FOR THE INCOMPRESSIBILITY ###
208
velocityPDE.setSolverMethod(solver=LinearPDE.DIRECT)
212
while (error >= 1.0e-2):
214
A=Tensor4(0.0, Function(mesh))
215
for i in range(numDim):
216
for j in range(numDim):
219
A[i,i,j,j] += penalty*eta
221
Y = Vector(0.0,Function(mesh))
224
X = Tensor(0.0, Function(mesh))
225
for i in range(numDim):
228
velocityPDE.setValue(A=A, X=X, Y=Y)
229
velocity = velocityPDE.getSolution()
232
print "You're screwed..."
235
pressure -= penalty*eta*(trace(grad(velocity)))
236
error = penalty*Lsup(trace(grad(velocity)))/Lsup(grad(velocity))
237
print "\nPressure iteration number:", p_iter
241
return velocity, pressure
243
### MAIN LOOP, OVER TIME ###
244
while t_step <= t_step_end:
245
print "######################"
246
print "Time step:", t_step
247
print "######################"
248
rho = update_parameter(phi, rho1, rho2)
249
eta = update_parameter(phi, eta1, eta2)
251
velocity, pressure = solve_vel_uszawa(rho, eta, velocity, pressure)
252
dt = 0.3*Lsup(mesh.getSize())/Lsup(velocity)
253
phi = update_phi(phi, velocity, dt, t_step)
255
### PSEUDO POST-PROCESSING ###
256
print "########## Saving image", t_step, " ###########"
257
saveVTK("phi3D.%2.2i.vtk"%t_step,layer=phi)
261
# vim: expandtab shiftwidth=4: