/[escript]/trunk/finley/test/python/seismic_wave.py
ViewVC logotype

Contents of /trunk/finley/test/python/seismic_wave.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 866 - (show annotations)
Mon Oct 9 03:50:20 2006 UTC (13 years, 4 months ago) by gross
File MIME type: text/x-python
File size: 11720 byte(s)
now GEAR scheme is used
1 """
2 seismic wave propagation
3
4 @var __author__: name of author
5 @var __licence__: licence agreement
6 @var __url__: url entry point on documentation
7 @var __version__: version
8 @var __date__: date of the version
9 """
10
11 __copyright__=""" Copyright (c) 2006 by ACcESS MNRF
12 http://www.access.edu.au
13 Primary Business: Queensland, Australia"""
14 __license__="""Licensed under the Open Software License version 3.0
15 http://www.opensource.org/licenses/osl-3.0.php"""
16 __author__="Lutz Gross, l.gross@uq.edu.au"
17 __url__="http://www.iservo.edu.au/esys/escript"
18 __version__="$Revision$"
19 __date__="$Date$"
20
21 from esys.escript import *
22 from esys.escript.linearPDEs import LinearPDE
23 from esys.finley import Brick
24 import time
25
26 output=True
27 n_end=10000
28
29 resolution=1000. # number of elements per m in the finest region
30 o=1 # element order
31
32 l=100000. # width and length m (without obsorber)
33 h=30000. # height in m (without obsorber)
34 d_absorber=l*0.10 # thickness of absorbing layer
35
36 l_sand=20000. # thickness of sand region on surface
37 h_sand=5000. # thickness of sand layer under the water
38
39 l_x_water=10000. # length of water in x
40 l_y_water=10000. # length of water in y
41 h_water=2000. # depth of water region
42
43 x_sand=l/2-l_x_water/2-l_sand # x coordinate of location of sand region (without obsorber)
44 y_sand=l/2-l_y_water/2-l_sand # y coordinate of location of sand region (without obsorber)
45
46
47 # origin
48 origin={"x": -d_absorber, "y" : -d_absorber , "z" : -h-d_absorber }
49 # location and geometrical size of event reltive to origin:
50 xc=[l*0.2,l*0.3,-h*0.7]
51 src_radius = 2*resolution
52 # direction of event:
53 event=numarray.array([0.,0.,1.])*1.e6
54 # time and length of the event
55 tc=2.
56 tc_length=0.5
57
58 # material properties:
59 bedrock=0
60 absorber=1
61 water=2
62 sand=3
63
64 rho_tab={}
65 rho_tab[bedrock]=8e3
66 rho_tab[absorber]=rho_tab[bedrock]
67 rho_tab[water]=1e3
68 rho_tab[sand]=5e3
69
70 mu_tab={}
71 mu_tab[bedrock]=1.7e11
72 mu_tab[absorber]=mu_tab[bedrock]
73 mu_tab[water]=0.
74 mu_tab[sand]=1.5e10
75
76 lmbd_tab={}
77 lmbd_tab[bedrock]=1.7e11
78 lmbd_tab[absorber]=lmbd_tab[bedrock]
79 lmbd_tab[water]=1.e9
80 lmbd_tab[sand]=1.5e10
81
82 eta_tab={}
83 eta_tab[absorber]=-log(0.05)*sqrt(rho_tab[absorber]*(lmbd_tab[absorber]+2*mu_tab[absorber]))/d_absorber
84 eta_tab[sand]=eta_tab[absorber]/40.
85 eta_tab[water]=eta_tab[absorber]/40.
86 eta_tab[bedrock]=eta_tab[absorber]/40.
87
88
89 # material properties:
90 bedrock=0
91 absorber=1
92 water=2
93 sand=3
94
95 rho={}
96 rho[bedrock]=8e3
97 rho[absorber]=rho[bedrock]
98 rho[water]=1e3
99 rho[sand]=5e3
100
101 mu={}
102 mu[bedrock]=1.7e11
103 mu[absorber]=mu[bedrock]
104 mu[water]=0.
105 mu[sand]=1.5e10
106
107 lmbd={}
108 lmbd[bedrock]=1.7e11
109 lmbd_absorber=lmbd[bedrock]
110 lmbd[water]=1.e9
111 lmbd[sand]=1.5e10
112
113 eta={}
114 eta[absorber]=-log(0.05)*sqrt(rho[absorber]*(lmbd_absorber+2*mu[absorber]))/d_absorber
115 eta[sand]=eta[absorber]/40.
116 eta[water]=eta[absorber]/40.
117 eta[bedrock]=eta[absorber]/40.
118
119 if output:
120 print "event location = ",xc
121 print "radius of event = ",src_radius
122 print "time of event = ",tc
123 print "length of event = ",tc_length
124 print "direction = ",event
125
126 t_end=30.
127 dt_write=0.1
128
129
130 def getDomain():
131 """
132 this defines a dom as a brick of length and width l and hight h
133
134
135 """
136 global netotal
137
138 v_p={}
139 for tag in rho_tab.keys():
140 v_p[tag]=sqrt((2*mu_tab[tag]+lmbd_tab[tag])/rho_tab[tag])
141 v_p_ref=min(v_p.values())
142 print "velocities: bedrock = %s, sand = %s, water =%s, absorber =%s, reference =%s"%(v_p[bedrock],v_p[sand],v_p[water],v_p[absorber],v_p_ref)
143
144 sections={}
145 sections["x"]=[d_absorber, x_sand, l_sand, l_x_water, l_sand, l-x_sand-2*l_sand-l_x_water, d_absorber]
146 sections["y"]=[d_absorber, y_sand, l_sand, l_y_water, l_sand, l-y_sand-2*l_sand-l_y_water, d_absorber]
147 sections["z"]=[d_absorber,h-h_water-h_sand,h_sand,h_water]
148 if output:
149 print "sections x = ",sections["x"]
150 print "sections y = ",sections["y"]
151 print "sections z = ",sections["z"]
152
153 mats= [
154 [ [absorber, absorber, absorber, absorber, absorber, absorber, absorber],
155 [absorber, absorber, absorber, absorber, absorber, absorber, absorber],
156 [absorber, absorber, absorber, absorber, absorber, absorber, absorber],
157 [absorber, absorber, absorber, absorber, absorber, absorber, absorber],
158 [absorber, absorber, absorber, absorber, absorber, absorber, absorber],
159 [absorber, absorber, absorber, absorber, absorber, absorber, absorber],
160 [absorber, absorber, absorber, absorber, absorber, absorber, absorber] ],
161
162 [ [absorber, absorber, absorber, absorber, absorber, absorber, absorber],
163 [absorber, bedrock , bedrock , bedrock , bedrock , bedrock , absorber],
164 [absorber, bedrock , bedrock , bedrock , bedrock , bedrock , absorber],
165 [absorber, bedrock , bedrock , bedrock , bedrock , bedrock , absorber],
166 [absorber, bedrock , bedrock , bedrock , bedrock , bedrock , absorber],
167 [absorber, bedrock , bedrock , bedrock , bedrock , bedrock , absorber],
168 [absorber, absorber, absorber, absorber, absorber, absorber, absorber] ],
169
170 [ [absorber, absorber, absorber, absorber, absorber, absorber, absorber],
171 [absorber, bedrock , bedrock , bedrock , bedrock , bedrock , absorber],
172 [absorber, bedrock , sand , sand , sand , bedrock , absorber],
173 [absorber, bedrock , sand , sand , sand , bedrock , absorber],
174 [absorber, bedrock , sand , sand , sand , bedrock , absorber],
175 [absorber, bedrock , bedrock , bedrock , bedrock , bedrock , absorber],
176 [absorber, absorber, absorber, absorber, absorber, absorber, absorber] ],
177
178 [ [absorber, absorber, absorber, absorber, absorber, absorber, absorber],
179 [absorber, bedrock , bedrock , bedrock , bedrock , bedrock , absorber],
180 [absorber, bedrock , sand , sand , sand , bedrock , absorber],
181 [absorber, bedrock , sand , water , sand , bedrock , absorber],
182 [absorber, bedrock , sand , sand , sand , bedrock , absorber],
183 [absorber, bedrock , bedrock , bedrock , bedrock , bedrock , absorber],
184 [absorber, absorber, absorber, absorber, absorber, absorber, absorber] ] ]
185
186 num_elem={}
187 for d in sections:
188 num_elem[d]=[]
189 for i in range(len(sections[d])):
190 if d=="x":
191 v_p_min=v_p[mats[0][0][i]]
192 for q in range(len(sections["y"])):
193 for r in range(len(sections["z"])):
194 v_p_min=min(v_p[mats[r][q][i]],v_p_min)
195 elif d=="y":
196 v_p_min=v_p[mats[0][i][0]]
197 for q in range(len(sections["x"])):
198 for r in range(len(sections["z"])):
199 v_p_min=min(v_p[mats[r][i][q]],v_p_min)
200 elif d=="z":
201 v_p_min=v_p[mats[i][0][0]]
202 for q in range(len(sections["x"])):
203 for r in range(len(sections["y"])):
204 v_p_min=min(v_p[mats[i][r][q]],v_p_min)
205 num_elem[d].append(max(1,int(sections[d][i] * v_p_ref/v_p_min /resolution+0.5)))
206
207 ne_x=sum(num_elem["x"])
208 ne_y=sum(num_elem["y"])
209 ne_z=sum(num_elem["z"])
210 netotal=ne_x*ne_y*ne_z
211 if output: print "grid : %s x %s x %s (%s elements)"%(ne_x,ne_y,ne_z,netotal)
212 dom=Brick(ne_x,ne_y,ne_z,l0=o*ne_x,l1=o*ne_y,l2=o*ne_z,order=o)
213 x_old=dom.getX()
214 x_new=0
215
216 for d in sections:
217 if d=="x":
218 i=0
219 f=[1,0,0]
220 if d=="y":
221 i=1
222 f=[0,1,0]
223 if d=="z":
224 i=2
225 f=[0,0,1]
226 x=x_old[i]
227
228 p=origin[d]
229 ne=0
230 s=0.
231
232 for i in range(len(sections[d])-1):
233 msk=whereNonPositive(x-o*ne+0.5)
234 s=s*msk + (sections[d][i]/(o*num_elem[d][i])*(x-o*ne)+p)*(1.-msk)
235 ne+=num_elem[d][i]
236 p+=sections[d][i]
237 x_new=x_new + s * f
238 dom.setX(x_new)
239
240 fs=Function(dom)
241 x=Function(dom).getX()
242 x0=x[0]
243 x1=x[1]
244 x2=x[2]
245 p_z=origin["z"]
246 for i in range(len(mats)):
247 f_z=wherePositive(x2-p_z)*wherePositive(x2-p_z+sections["z"][i])
248 p_y=origin["y"]
249 for j in range(len(mats[i])):
250 f_y=wherePositive(x1-p_y)*wherePositive(x1-p_z+sections["y"][j])
251 p_x=origin["x"]
252 for k in range(len(mats[i][j])):
253 f_x=wherePositive(x0-p_x)*wherePositive(x0-p_x+sections["x"][k])
254 fs.setTags(mats[i][j][k],f_x*f_y*f_z)
255 p_x+=sections["x"][k]
256 p_y+=sections["y"][j]
257 p_z+=sections["z"][i]
258 return dom
259
260 def getMaterialProperties(dom):
261 rho =Scalar(rho_tab[bedrock],Function(dom))
262 eta =Scalar(eta_tab[bedrock],Function(dom))
263 mu =Scalar(mu_tab[bedrock],Function(dom))
264 lmbd=Scalar(lmbd_tab[bedrock],Function(dom))
265 tags=Scalar(bedrock,Function(dom))
266
267 for tag in rho_tab.keys():
268 rho.setTaggedValue(tag,rho_tab[tag])
269 eta.setTaggedValue(tag,eta_tab[tag])
270 mu.setTaggedValue(tag,mu_tab[tag])
271 lmbd.setTaggedValue(tag,lmbd_tab[tag])
272 tags.setTaggedValue(tag,tag)
273 return rho,mu,lmbd,eta
274
275 def wavePropagation(dom,rho,mu,lmbd,eta):
276 x=Function(dom).getX()
277 # ... open new PDE ...
278 mypde=LinearPDE(dom)
279 mypde.setSolverMethod(LinearPDE.LUMPING)
280 k=kronecker(Function(dom))
281 mypde.setValue(D=k*rho)
282
283 dt=(1./5.)*inf(dom.getSize()/sqrt((2*mu+lmbd)/rho))
284 if output: print "time step size = ",dt
285 # ... set initial values ....
286 n=0
287 t=0
288 t_write=0.
289 n_write=0
290 # initial value of displacement at point source is constant (U0=0.01)
291 # for first two time steps
292 u=Vector(0.,Solution(dom))
293 v=Vector(0.,Solution(dom))
294 a=Vector(0.,Solution(dom))
295 a2=Vector(0.,Solution(dom))
296 v=Vector(0.,Solution(dom))
297
298 starttime = time.clock()
299 while t<t_end and n<n_end:
300 if output: print n+1,"-th time step t ",t+dt," max u and F: ",Lsup(u),
301 # prediction:
302 u_pr=u+dt*v+(dt**2/2)*a+(dt**3/6)*a2
303 v_pr=v+dt*a+(dt**2/2)*a2
304 a_pr=a+dt*a2
305 # ... get current stress ....
306 eps=symmetric(grad(u_pr))
307 stress=lmbd*trace(eps)*k+2*mu*eps
308 # ... force due to event:
309 if abs(t-tc)<5*tc_length:
310 F=exp(-((t-tc)/tc_length)**2)*exp(-(length(x-xc)/src_radius)**2)*event
311 if output: print Lsup(F)
312 else:
313 if output: print 0.
314 # ... get new acceleration ....
315 mypde.setValue(X=-stress,Y=F-eta*v_pr)
316 a=mypde.getSolution()
317 # ... get new displacement ...
318 da=a-a_pr
319 u=u_pr+(dt**2/12.)*da
320 v=v_pr+(5*dt/12.)*da
321 a2+=da/dt
322 # ... save current acceleration in units of gravity and displacements
323 if output:
324 if t>=t_write:
325 saveVTK("disp.%i.vtu"%n,displacement=u, amplitude=length(u))
326 t_write+=dt_write
327 n_write+=1
328 t+=dt
329 n+=1
330
331 endtime = time.clock()
332 totaltime = endtime-starttime
333 global netotal
334 print ">>number of elements: %s, total time: %s, per time step: %s <<"%(netotal,totaltime,totaltime/n)
335 if __name__ =="__main__":
336 dom=getDomain()
337 rho,mu,lmbd,eta=getMaterialProperties(dom)
338 wavePropagation(dom,rho,mu,lmbd,eta)

  ViewVC Help
Powered by ViewVC 1.1.26