SPEED
GET_CFL4NHE.f90
Go to the documentation of this file.
1! Copyright (C) 2012 The SPEED FOUNDATION
2! Author: Ilario Mazzieri
3!
4! This file is part of SPEED.
5!
6! SPEED is free software; you can redistribute it and/or modify it
7! under the terms of the GNU Affero General Public License as
8! published by the Free Software Foundation, either version 3 of the
9! License, or (at your option) any later version.
10!
11! SPEED is distributed in the hope that it will be useful, but
12! WITHOUT ANY WARRANTY; without even the implied warranty of
13! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14! Affero General Public License for more details.
15!
16! You should have received a copy of the GNU Affero General Public License
17! along with SPEED. If not, see <http://www.gnu.org/licenses/>.
18
38! 'not' deltat could be changed if is extremely small for the time integration
46
47 subroutine get_cfl4nhe(time_step, nn_loc, loc_n_num, nm, tm, pm, sdeg, &
48 xx_loc, yy_loc, zz_loc, cs_nnz_loc, cs_loc, &
49 rho_nhe, lambda_nhe, mu_nhe, &
50 time_step_cfl, fmax, deltat_fixed, &
51 mpi_comm, mpi_np, mpi_id, b_failCFL)
52
54
55 implicit none
56
57 include 'SPEED.MPI'
58
59 character*3 :: deltat_fixed
60
61 integer*4 :: nm, im, nn_loc, cs_nnz_loc, mpi_comm, mpi_np, mpi_err, mpi_id
62 integer*4 :: ie, i, j, k, nn, mcode, smcode, sdeg_deltat_cfl, sdeg_npoints
63 integer*4 :: nel_loc, ic1, ic2, n1, n2, istart, ifin
64
65 integer*4, dimension(1) :: pos
66 integer*4, dimension(nm) :: tm, sdeg
67 integer*4, dimension(nn_loc) :: loc_n_num
68 integer*4, dimension(0:cs_nnz_loc) :: cs_loc
69
70 real*8 :: time_step, time_step_cfl, fmax
71 real*8 :: length_min,length,vs_length_min,vs_length,length_vp_min,length_vp
72 real*8 :: percent_deltat
73 real*8 :: num_of_points,vs_npoints,vp_deltat_cfl
74 real*8 :: rho,lambda,mu,vs,vp
75 real*8 :: x1_length_vp_min,y1_length_vp_min,z1_length_vp_min
76 real*8 :: x2_length_vp_min,y2_length_vp_min,z2_length_vp_min
77
78 real*8, dimension(:), allocatable :: ct,ww
79 real*8, dimension(:), allocatable :: time_step_glo
80 real*8, dimension(nn_loc) :: xx_loc, yy_loc, zz_loc
81 real*8, dimension(nn_loc) :: rho_nhe, lambda_nhe, mu_nhe
82
83 real*8, dimension(nm,4) :: pm
84 real*8, dimension(:,:), allocatable :: dd
85
86 real*8, dimension(:,:,:), allocatable :: rho_el, lambda_el, mu_el, gamma_el
87
88 logical :: b_failCFL, b_CFL_failure = .false.
89
90 nel_loc = cs_loc(0) - 1
91
92 length_vp_min = 1.d30
93 vs_length_min = 1.d30
94
95
96 do ie = 1, nel_loc
97 im = cs_loc(cs_loc(ie -1) +0)
98
99 nn = sdeg(im) +1
100 allocate(rho_el(nn,nn,nn), lambda_el(nn,nn,nn),mu_el(nn,nn,nn),gamma_el(nn,nn,nn))
101
102 rho_el = pm(im,1)
103 lambda_el = pm(im,2)
104 mu_el = pm(im,3)
105 gamma_el = pm(im,4)
106
107 call get_mech_prop_nh_enhanced(ie, nn, nn_loc, cs_nnz_loc, cs_loc, &
108 rho_nhe, lambda_nhe, mu_nhe, 100.d0, fmax, &
109 rho_el, lambda_el, mu_el, gamma_el)
110
111 smcode=sdeg(im)
112 rho = 0.d0
113 lambda = 0.d0
114 mu = 0.d0
115
116 do i = 1, nn
117 do j = 1, nn
118 do k = 1, nn
119 rho = rho + rho_el(i,j,k)
120 lambda = lambda + lambda_el(i,j,k)
121 mu = mu + mu_el(i,j,k)
122 enddo
123 enddo
124 enddo
125
126 rho = rho/(nn**3)
127 lambda = lambda/(nn**3)
128 mu = mu/(nn**3)
129
130 vs = dsqrt(mu/rho)
131 vp = dsqrt((lambda+2*mu)/rho)
132
133 n1 = nn*nn*(1 -1) +nn*(1 -1) +1
134 n2 = nn*nn*(nn -1) +nn*(nn -1) +nn
135 istart = cs_loc(ie -1) +n1
136 ifin = cs_loc(ie -1) +n2
137
138
139 do ic1 = istart, ifin
140 do ic2 = ic1 + 1, ifin
141
142 if(cs_loc(ic1) .ne. 0 .and. cs_loc(ic2) .ne. 0) then
143
144 length=dsqrt((xx_loc(cs_loc(ic1))-xx_loc(cs_loc(ic2)))**2 + &
145 (yy_loc(cs_loc(ic1))-yy_loc(cs_loc(ic2)))**2 + &
146 (zz_loc(cs_loc(ic1))-zz_loc(cs_loc(ic2)))**2)
147
148 length_vp = length/vp
149 if (length_vp_min .gt. length_vp) then
150 length_vp_min = length_vp
151 x1_length_vp_min = xx_loc(cs_loc(ic1))
152 y1_length_vp_min = yy_loc(cs_loc(ic1))
153 z1_length_vp_min = zz_loc(cs_loc(ic1))
154 x2_length_vp_min = xx_loc(cs_loc(ic2))
155 y2_length_vp_min = yy_loc(cs_loc(ic2))
156 z2_length_vp_min = zz_loc(cs_loc(ic2))
157 vp_deltat_cfl = vp
158 sdeg_deltat_cfl = smcode
159 length_min = length
160 endif
161
162
163 vs_length = vs/length
164
165 if (vs_length_min.gt.vs_length) then
166 vs_length_min = vs_length
167 vs_npoints = vs
168 sdeg_npoints = smcode
169 endif
170
171 endif
172
173 enddo
174 enddo
175
176 deallocate(lambda_el, gamma_el, mu_el, rho_el)
177
178 enddo
179
180 nn = sdeg_deltat_cfl + 1
181
182 time_step_cfl=length_vp_min !/((nn-1)**2)
183
184 allocate(time_step_glo(mpi_np))
185
186 call mpi_barrier(mpi_comm, mpi_err)
187 call mpi_allgather(time_step_cfl, 1, speed_double, time_step_glo, 1, speed_double, mpi_comm, mpi_err)
188
189
190 pos = minloc(time_step_glo)
191
192 deallocate(time_step_glo)
193
194 if((mpi_id + 1) .eq. pos(1)) then
195
196 write(*,'(A)')' '
197 write(*,'(A)') '--------Stability for time advancing algorithm --------'
198 write(*,'(A,E12.4)') 'Mininum distance beteween grid nodes :', length_vp_min*vp_deltat_cfl
199 write(*,'(A,E12.4)') 'Vp for CFL condition :', vp_deltat_cfl
200 write(*,'(A,E12.4,E12.4,E12.4)')'Min. node 1 : ',x1_length_vp_min,y1_length_vp_min,z1_length_vp_min
201 write(*,'(A,E12.4,E12.4,E12.4)')'Min. node 2 : ',x2_length_vp_min,y2_length_vp_min,z2_length_vp_min
202 write(*,'(A)') '-------------------------------------------------------'
203 if (time_step.le.time_step_cfl) then
204 percent_deltat=time_step/time_step_cfl*100
205 if (percent_deltat.le.1) then
206 write(*,'(A,E12.4)')'WARNING!!! deltat CFL =',&
207 time_step_cfl
208 write(*,'(A,F6.2,A)')'You are using ',percent_deltat,&
209 '% of critical time step.'
210 write(*,'(A)')'This time step is excedingly lower the deltat CFL'
211 if (deltat_fixed.eq.'not') then
212 write(*,'(A)')'deltat chosen will be substituted with 10% of deltat CFL'
213 time_step=time_step_cfl*0.1
214 write(*,'(A,E12.4)')'deltat chosen :',time_step
215 endif
216 elseif (percent_deltat.le.25) then
217 write(*,'(A,E12.4)')'OK!!! deltat CFL =',&
218 time_step_cfl
219 write(*,'(A,F6.2,A)')'You are using ',percent_deltat,&
220 '% of critical time step.'
221 else
222 write(*,'(A,E12.4)')'WARNING!!! deltat CFL =',&
223 time_step_cfl
224 write(*,'(A,F6.2,A)')'You are using ',percent_deltat,&
225 '% of critical time step.'
226 write(*,'(A)')'This could be not enough for the correct working of ABC'
227 if (deltat_fixed.eq.'not') then
228 write(*,'(A)')'deltat chosen will be substituted with 20% of deltat CFL'
229 time_step=time_step_cfl*0.2
230 write(*,'(A,E12.4)')'deltat chosen :',time_step
231 endif
232 endif
233 elseif (time_step.gt.time_step_cfl) then
234 write(*,'(2X,A,E12.4)')'ERROR!!! deltat CFL = ',&
235 time_step_cfl,' < deltat = ',time_step
236 write(*,'(A)')'The time advancing scheme will be unstable!'
237 if (deltat_fixed.eq.'not') then
238 write(*,'(A)')'deltat chosen will be substituted with 20% of deltat CFL'
239 time_step=time_step_cfl*0.2
240 write(*,'(A,E12.4)')'deltat chosen :',time_step
241 else
242 b_cfl_failure = .true.
243 endif
244 endif
245 write(*,'(A)')'-------------------------------------------------------'
246 write(*,'(A)')' '
247
248 if (b_failcfl .and. b_cfl_failure) then
249 write(*,*) 'CFL does NOT hold, asked to quit. Program finished.'
250 call mpi_finalize(mpi_err)
251 call exit(exit_cfl)
252 endif
253
254 !Writing of the results for the maximum number of points per wave length
255
256 allocate(ct(nn),ww(nn),dd(nn,nn))
257 call make_lgl_nw(nn,ct,ww,dd)
258
259 num_of_points = vs_length_min*(ct(1)-ct(nn))/(ct(int(nn/2))-ct(int(nn/2)+1))/fmax
260
261 write(*,'(A)')'-----------Number of points per wave length------------'
262 !write(*,'(A,E12.4)')'Max. el. length :',1/vs_length_min*vs_npoints !length
263 write(*,'(A,E12.4)')'Minum vs wrt max frequency :',vs_npoints
264 write(*,'(A,E12.4)')'Points per wavelength :',num_of_points
265 write(*,'(A)') ' '
266
267 deallocate(ct,ww,dd)
268 endif
269
270 call mpi_barrier(mpi_comm, mpi_err)
271
272 return
273
274 end subroutine get_cfl4nhe
275
subroutine get_mech_prop_nh_enhanced(ie, nn, nn_loc, cs_nnz_loc, cs_loc, rho_nhe, lambda_nhe, mu_nhe, qs_nh, fmax, rho_el, lambda_el, mu_el, gamma_el)
...Not-Honoring Enhanced (NHE) Implementation
subroutine make_lgl_nw(nb_pnt, xq, wq, dd)
Makes Gauss-Legendre-Lobatto nodes, weigths and spectral derivatives.
SPEED exit codes.
Definition MODULES.f90:25
integer, parameter exit_cfl
Definition MODULES.f90:30