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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.26