/[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 865 - (hide annotations)
Fri Oct 6 10:02:18 2006 UTC (14 years, 6 months ago) by gross
File MIME type: text/x-python
File size: 11006 byte(s)
some functions for minimizing a function added. there is still some work required but successfully applied in an aplication
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 844 output=True
27     n_end=10000
28 gross 843
29 gross 865 resolution=1000. # number of elements per m in the finest region
30     o=1 # element order
31 gross 842
32 gross 865 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 gross 842
36 gross 865 l_sand=5000. # thickness of sand region on surface
37     h_sand=2000. # thickness of sand layer under the water
38 gross 842
39 gross 865 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 gross 842
43 gross 865 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 gross 842
46    
47 gross 865 # 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 gross 862 src_radius = 2*resolution
52 gross 842 # direction of event:
53 gross 862 event=numarray.array([0.,0.,1.])*1.e6
54 gross 842 # time and length of the event
55 gross 865 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 gross 843 if output:
89     print "event location = ",xc
90     print "radius of event = ",src_radius
91     print "time of event = ",tc
92     print "length of event = ",tc_length
93     print "direction = ",event
94 gross 842
95 gross 862 t_end=30.
96 gross 865 dt_write=0.1
97 gross 842
98 gross 865
99 gross 842 def getDomain():
100     """
101     this defines a dom as a brick of length and width l and hight h
102    
103    
104     """
105 gross 843 global netotal
106 gross 844
107 gross 865 v_p={}
108     for tag in rho_tab.keys():
109     v_p[tag]=sqrt((2*mu_tab[tag]+lmbd_tab[tag])/rho_tab[tag])
110     v_p_ref=min(v_p.values())
111 gross 844
112 gross 865 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)
113 gross 844
114 gross 865 sections={}
115     sections["x"]=[d_absorber, x_sand, l_sand, l_x_water, l_sand, l-x_sand-2*l_sand-l_x_water, d_absorber]
116     sections["y"]=[d_absorber, y_sand, l_sand, l_y_water, l_sand, l-y_sand-2*l_sand-l_y_water, d_absorber]
117     sections["z"]=[d_absorber,h-h_water-h_sand,h_sand,h_water]
118     if output:
119     print "sections x = ",sections["x"]
120     print "sections y = ",sections["y"]
121     print "sections z = ",sections["z"]
122 gross 844
123 gross 865 mats= [
124     [ [absorber, absorber, absorber, absorber, absorber, absorber, absorber],
125     [absorber, absorber, absorber, absorber, absorber, absorber, absorber],
126     [absorber, absorber, absorber, absorber, absorber, absorber, absorber],
127     [absorber, absorber, absorber, absorber, absorber, absorber, absorber],
128     [absorber, absorber, absorber, absorber, absorber, absorber, absorber],
129     [absorber, absorber, absorber, absorber, absorber, absorber, absorber],
130     [absorber, absorber, absorber, absorber, absorber, absorber, absorber] ],
131 gross 844
132 gross 865 [ [absorber, absorber, absorber, absorber, absorber, absorber, absorber],
133     [absorber, bedrock , bedrock , bedrock , bedrock , bedrock , absorber],
134     [absorber, bedrock , bedrock , bedrock , bedrock , bedrock , absorber],
135     [absorber, bedrock , bedrock , bedrock , bedrock , bedrock , absorber],
136     [absorber, bedrock , bedrock , bedrock , bedrock , bedrock , absorber],
137     [absorber, bedrock , bedrock , bedrock , bedrock , bedrock , absorber],
138     [absorber, absorber, absorber, absorber, absorber, absorber, absorber] ],
139 gross 844
140 gross 865 [ [absorber, absorber, absorber, absorber, absorber, absorber, absorber],
141     [absorber, bedrock , bedrock , bedrock , bedrock , bedrock , absorber],
142     [absorber, bedrock , sand , sand , sand , bedrock , absorber],
143     [absorber, bedrock , sand , sand , sand , bedrock , absorber],
144     [absorber, bedrock , sand , sand , sand , bedrock , absorber],
145     [absorber, bedrock , bedrock , bedrock , bedrock , bedrock , absorber],
146     [absorber, absorber, absorber, absorber, absorber, absorber, absorber] ],
147    
148     [ [absorber, absorber, absorber, absorber, absorber, absorber, absorber],
149     [absorber, bedrock , bedrock , bedrock , bedrock , bedrock , absorber],
150     [absorber, bedrock , sand , sand , sand , bedrock , absorber],
151     [absorber, bedrock , sand , water , sand , bedrock , absorber],
152     [absorber, bedrock , sand , sand , sand , bedrock , absorber],
153     [absorber, bedrock , bedrock , bedrock , bedrock , bedrock , absorber],
154     [absorber, absorber, absorber, absorber, absorber, absorber, absorber] ] ]
155 gross 844
156 gross 865 num_elem={}
157     for d in sections:
158     num_elem[d]=[]
159     for i in range(len(sections[d])):
160     if d=="x":
161     v_p_min=v_p[mats[0][0][i]]
162     for q in range(len(sections["y"])):
163     for r in range(len(sections["z"])):
164     v_p_min=min(v_p[mats[r][q][i]],v_p_min)
165     elif d=="y":
166     v_p_min=v_p[mats[0][i][0]]
167     for q in range(len(sections["x"])):
168     for r in range(len(sections["z"])):
169     v_p_min=min(v_p[mats[r][i][q]],v_p_min)
170     elif d=="z":
171     v_p_min=v_p[mats[i][0][0]]
172     for q in range(len(sections["x"])):
173     for r in range(len(sections["y"])):
174     v_p_min=min(v_p[mats[i][r][q]],v_p_min)
175     num_elem[d].append(max(1,int(sections[d][i] * v_p_ref/v_p_min /resolution+0.5)))
176    
177     ne_x=sum(num_elem["x"])
178     ne_y=sum(num_elem["y"])
179     ne_z=sum(num_elem["z"])
180     netotal=ne_x*ne_y*ne_z
181     if output: print "grid : %s x %s x %s (%s elements)"%(ne_x,ne_y,ne_z,netotal)
182     dom=Brick(ne_x,ne_y,ne_z,l0=o*ne_x,l1=o*ne_y,l2=o*ne_z,order=o)
183     x_old=dom.getX()
184     x_new=0
185 gross 844
186 gross 865 for d in sections:
187     if d=="x":
188     i=0
189     f=[1,0,0]
190     if d=="y":
191     i=1
192     f=[0,1,0]
193     if d=="z":
194     i=2
195     f=[0,0,1]
196     x=x_old[i]
197 gross 844
198 gross 865 p=origin[d]
199     ne=0
200     s=0.
201    
202     for i in range(len(sections[d])-1):
203     msk=whereNonPositive(x-o*ne+0.5)
204     s=s*msk + (sections[d][i]/(o*num_elem[d][i])*(x-o*ne)+p)*(1.-msk)
205     ne+=num_elem[d][i]
206     p+=sections[d][i]
207     x_new=x_new + s * f
208     dom.setX(x_new)
209 gross 844
210 gross 842 fs=Function(dom)
211     x=Function(dom).getX()
212 gross 865 x0=x[0]
213     x1=x[1]
214     x2=x[2]
215     p_z=origin["z"]
216     for i in range(len(mats)):
217     f_z=wherePositive(x2-p_z)*wherePositive(x2-p_z+sections["z"][i])
218     p_y=origin["y"]
219     for j in range(len(mats[i])):
220     f_y=wherePositive(x1-p_y)*wherePositive(x1-p_z+sections["y"][j])
221     p_x=origin["x"]
222     for k in range(len(mats[i][j])):
223     f_x=wherePositive(x0-p_x)*wherePositive(x0-p_x+sections["x"][k])
224     fs.setTags(mats[i][j][k],f_x*f_y*f_z)
225     p_x+=sections["x"][k]
226     p_y+=sections["y"][j]
227     p_z+=sections["z"][i]
228 gross 842 return dom
229    
230     def getMaterialProperties(dom):
231 gross 865 rho =Scalar(rho_tab[bedrock],Function(dom))
232     eta =Scalar(eta_tab[bedrock],Function(dom))
233     mu =Scalar(mu_tab[bedrock],Function(dom))
234     lmbd=Scalar(lmbd_tab[bedrock],Function(dom))
235     tags=Scalar(bedrock,Function(dom))
236    
237     for tag in rho_tab.keys():
238     rho.setTaggedValue(tag,rho_tab[tag])
239     eta.setTaggedValue(tag,eta_tab[tag])
240     mu.setTaggedValue(tag,mu_tab[tag])
241     lmbd.setTaggedValue(tag,lmbd_tab[tag])
242     tags.setTaggedValue(tag,tag)
243     return rho,mu,lmbd,eta
244 gross 842
245    
246 gross 865 def wavePropagation(dom,rho,mu,lmbd,eta):
247 gross 842 x=Function(dom).getX()
248     # ... open new PDE ...
249     mypde=LinearPDE(dom)
250     mypde.setSolverMethod(LinearPDE.LUMPING)
251     k=kronecker(Function(dom))
252     mypde.setValue(D=k*rho)
253    
254 gross 865 dt=(1./5.)*inf(dom.getSize()/sqrt((2*mu+lmbd)/rho))
255 gross 843 if output: print "time step size = ",dt
256 gross 842 # ... set initial values ....
257     n=0
258     t=0
259 gross 865 t_write=0.
260     n_write=0
261 gross 842 # initial value of displacement at point source is constant (U0=0.01)
262     # for first two time steps
263     u =Vector(0.,Solution(dom))
264     u_last=Vector(0.,Solution(dom))
265 gross 865 v=Vector(0.,Solution(dom))
266 gross 842
267 gross 843 starttime = time.clock()
268     while t<t_end and n<n_end:
269     if output: print n+1,"-th time step t ",t+dt," max u and F: ",Lsup(u),
270 gross 842 # ... get current stress ....
271     eps=symmetric(grad(u))
272 gross 865 stress=lmbd*trace(eps)*k+2*mu*eps
273 gross 842 # ... force due to event:
274     F=exp(-((t-tc)/tc_length)**2)*exp(-(length(x-xc)/src_radius)**2)*event
275 gross 843 if output: print Lsup(F)
276 gross 842 # ... get new acceleration ....
277 gross 865 mypde.setValue(X=-stress,Y=F-eta*v)
278 gross 842 a=mypde.getSolution()
279     # ... get new displacement ...
280     u_new=2*u-u_last+dt**2*a
281     # ... shift displacements ....
282 gross 865 v=(u_new-u)/dt
283 gross 842 u_last,u=u,u_new
284     # ... save current acceleration in units of gravity and displacements
285 gross 843 if output:
286 gross 862 if t>=t_write:
287 gross 865 saveVTK("disp.%i.vtu"%n,displacement=u, amplitude=length(u))
288     t_write+=dt_write
289     n_write+=1
290 gross 842 t+=dt
291     n+=1
292    
293 gross 843 endtime = time.clock()
294     totaltime = endtime-starttime
295     global netotal
296     print ">>number of elements: %s, total time: %s, per time step: %s <<"%(netotal,totaltime,totaltime/n)
297 gross 842 if __name__ =="__main__":
298     dom=getDomain()
299 gross 865 rho,mu,lmbd,eta=getMaterialProperties(dom)
300     wavePropagation(dom,rho,mu,lmbd,eta)

  ViewVC Help
Powered by ViewVC 1.1.26