Skip to content

Commit 138fa18

Browse files
committed
updats compute_arrays_source** routines for moment-tensor and force solutions; updates source location calls
1 parent 90c5a9c commit 138fa18

15 files changed

Lines changed: 325 additions & 364 deletions

src/shared/read_source_file.f90

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ subroutine read_source_file(NSOURCES,BROADCAST_AFTER_READ)
308308
case (0)
309309
write(IMAIN,*) ' Normalized Gaussian:'
310310
write(IMAIN,*) ' Frequency = ',f0_source(i_source), &
311-
' (-> half-duration = ',sngl(1.d0/f0_source(i_source)),' s)'
311+
' (half-duration = ',sngl(1.d0/f0_source(i_source)),' s)'
312312
if (f0_source(i_source) == f0_sampling) write(IMAIN,*) ' (Frequency limited by sampling rate DT ',sngl(DT),' s)'
313313
write(IMAIN,*) ' delay = ',tshift_src(i_source)
314314
case (1)
@@ -349,19 +349,19 @@ subroutine read_source_file(NSOURCES,BROADCAST_AFTER_READ)
349349
case (12)
350350
write(IMAIN,*) ' Brune source time function'
351351
write(IMAIN,*) ' Frequency = ',f0_source(i_source), &
352-
' (-> rise time = ',sngl(1.d0/f0_source(i_source)),' s)'
352+
' (rise time = ',sngl(1.d0/f0_source(i_source)),' s)'
353353
write(IMAIN,*) ' delay = ',tshift_src(i_source)
354354
case (13)
355355
write(IMAIN,*) ' Smoothed Brune source time function'
356356
write(IMAIN,*) ' Frequency = ',f0_source(i_source), &
357-
' (-> rise time = ',sngl(1.d0/f0_source(i_source)),' s)'
357+
' (rise time = ',sngl(1.d0/f0_source(i_source)),' s)'
358358
write(IMAIN,*) ' delay = ',tshift_src(i_source)
359359
case (14)
360360
write(IMAIN,*) ' Regularized Yoffe:'
361-
write(IMAIN,*) ' Frequency = ',f0_source(i_source),&
362-
' (-> slip acceleration duration: T_acc = ',sngl(1.d0/f0_source(i_source)),' s)'
361+
write(IMAIN,*) ' Frequency = ',f0_source(i_source), &
362+
' (slip acceleration duration: T_acc = ',sngl(1.d0/f0_source(i_source)),' s)'
363363
write(IMAIN,*) ' burst band width = ',burst_band_width(i_source), &
364-
' (-> effective final duration : T_eff = ',sngl(1.d0/burst_band_width(i_source)),' s)'
364+
' (effective final duration : T_eff = ',sngl(1.d0/burst_band_width(i_source)),' s)'
365365
write(IMAIN,*) ' delay = ',tshift_src(i_source)
366366
case default
367367
call stop_the_code('Error invalid source time function type! must be between 1 and 9, exiting...')

src/specfem2D/comp_source_time_function.f90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -782,7 +782,7 @@ double precision function comp_source_time_function_Yoffe(t,f0,burst_band_width)
782782

783783
! regularized Yoffe function defined in Appendix (A13) - (A20) of
784784
! Tinti et al. (2005),
785-
! A Kinematic Source-Time Function Compatible with Earthquake Dynamics,
785+
! A kinematic source-time function compatible with earthquake dynamics,
786786
! BSSA, 95 (4), 1211-1223. https://doi.org/10.1785/0120040177
787787

788788
! fixed parameter example:

src/specfem2D/compute_add_sources_acoustic.f90

Lines changed: 53 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,12 @@ subroutine compute_add_sources_acoustic_moving_sources(potential_dot_dot_acousti
9898

9999
use specfem_par, only: ispec_is_acoustic,nglob_acoustic, &
100100
NSOURCES,source_type,source_time_function, &
101-
islice_selected_source,ispec_selected_source, &
102-
hxis_store,hgammas_store,ibool,kappastore,myrank,DT,t0,tshift_src, &
101+
islice_selected_source,ispec_selected_source,sourcearrays, &
102+
ibool,kappastore,myrank,DT,t0,tshift_src, &
103103
coord,nspec,nglob,xigll,zigll,NPROC,xi_source, &
104104
gamma_source,coorg,knods,NGNOD,npgeo,iglob_source,x_source,z_source, &
105-
vx_source,vz_source, time_stepping_scheme, &
106-
SOURCE_IS_MOVING, &
107-
hxis,hpxis,hgammas,hpgammas
105+
anglesource,vx_source,vz_source,time_stepping_scheme, &
106+
AXISYM,xiglj,is_on_the_axis,SOURCE_IS_MOVING
108107

109108
use moving_sources_par, only: locate_source_moving
110109

@@ -113,10 +112,14 @@ subroutine compute_add_sources_acoustic_moving_sources(potential_dot_dot_acousti
113112
real(kind=CUSTOM_REAL), dimension(nglob_acoustic),intent(inout) :: potential_dot_dot_acoustic
114113
integer,intent(in) :: it,i_stage
115114

116-
!local variables
115+
! local variables
117116
integer :: i_source,i,j,iglob,ispec
118-
double precision :: hlagrange
117+
real(kind=CUSTOM_REAL) :: stf_used
119118
double precision :: xsrc,zsrc,timeval,t_used
119+
! Lagrange interpolators at source position
120+
double precision, dimension(NGLLX) :: hxis,hpxis
121+
double precision, dimension(NGLLZ) :: hgammas,hpgammas
122+
! single source array
120123
real(kind=CUSTOM_REAL), dimension(NDIM,NGLLX,NGLLZ) :: sourcearray
121124

122125
! checks if anything to do
@@ -157,6 +160,7 @@ subroutine compute_add_sources_acoustic_moving_sources(potential_dot_dot_acousti
157160
enddo
158161
endif
159162

163+
! updates source positions and re-calculates source arrays
160164
do i_source = 1,NSOURCES
161165
if (abs(source_time_function(i_source,it,i_stage)) > TINYVAL) then
162166
t_used = (timeval-t0-tshift_src(i_source))
@@ -165,40 +169,55 @@ subroutine compute_add_sources_acoustic_moving_sources(potential_dot_dot_acousti
165169
xsrc = x_source(i_source) + vx_source(i_source)*t_used
166170
zsrc = z_source(i_source) + vz_source(i_source)*t_used
167171

168-
! collocated force source
172+
! gets source positioning
169173
! TODO: this would be more efficient compled with first guess as in init_moving_sources_GPU
170174
!call locate_source_moving(xsrc,zsrc, &
171175
! ispec_selected_source(i_source),islice_selected_source(i_source), &
172-
! NPROC,myrank,xi_source(i_source),gamma_source(i_source),.true.)
176+
! NPROC,myrank,xi_source(i_source),gamma_source(i_source),..
173177
call locate_source(ibool,coord,nspec,nglob,xigll,zigll, &
174178
xsrc,zsrc, &
175179
ispec_selected_source(i_source),islice_selected_source(i_source), &
176180
NPROC,myrank,xi_source(i_source),gamma_source(i_source),coorg,knods,NGNOD,npgeo, &
177-
iglob_source(i_source),.true.)
181+
iglob_source(i_source),source_type(i_source))
178182

179183
! print *,ispec_selected_source(i_source) > nspec, "xmin:", &
180184
! coord(1,ibool(1,1,ispec_selected_source(i_source))), &
181185
! "xmax:", coord(1,ibool(NGLLX,1,ispec_selected_source(i_source)))
182186

183-
! define and store Lagrange interpolators (hxis,hpxis,hgammas,hpgammas) at all the sources
184-
!if (AXISYM) then
185-
! if (is_on_the_axis(ispec_selected_source(i_source)) .and. myrank == islice_selected_source(i_source)) then
186-
! call lagrange_any(xi_source(i_source),NGLJ,xiglj,hxis,hpxis)
187-
! !do j = 1,NGLJ ! ABAB same result with that loop, this is good
188-
! ! hxis(j) = hglj(j-1,xi_source(i),xiglj,NGLJ)
189-
! !enddo
190-
! else
191-
! call lagrange_any(xi_source(i_source),NGLLX,xigll,hxis,hpxis)
192-
! endif
193-
!else
194-
call lagrange_any(xi_source(i_source),NGLLX,xigll,hxis,hpxis)
195-
!endif
196-
call lagrange_any(gamma_source(i_source),NGLLZ,zigll,hgammas,hpgammas)
197-
198-
! stores Lagrangians for source
199-
hxis_store(i_source,:) = hxis(:)
200-
hgammas_store(i_source,:) = hgammas(:)
201-
187+
if (myrank == islice_selected_source(i_source)) then
188+
! element containing source
189+
ispec = ispec_selected_source(i_source)
190+
191+
! only for acoustic source elements
192+
if (.not. ispec_is_acoustic(ispec)) cycle
193+
194+
! Lagrange interpolators
195+
if (AXISYM) then
196+
if (is_on_the_axis(ispec)) then
197+
call lagrange_any(xi_source(i_source),NGLJ,xiglj,hxis,hpxis)
198+
else
199+
call lagrange_any(xi_source(i_source),NGLLX,xigll,hxis,hpxis)
200+
endif
201+
else
202+
call lagrange_any(xi_source(i_source),NGLLX,xigll,hxis,hpxis)
203+
endif
204+
call lagrange_any(gamma_source(i_source),NGLLZ,zigll,hgammas,hpgammas)
205+
206+
! computes source arrays
207+
sourcearray(:,:,:) = 0._CUSTOM_REAL
208+
209+
select case (source_type(i_source))
210+
case (1)
211+
! collocated force source
212+
call compute_arrays_source_forcesolution(ispec,hxis,hgammas,sourcearray,anglesource(i_source))
213+
case (2)
214+
! moment-tensor source
215+
call exit_MPI(myrank,'Cannot have moment tensor source in acoustic element')
216+
end select
217+
218+
! stores sourcearray for all sources
219+
sourcearrays(:,:,:,i_source) = sourcearray(:,:,:)
220+
endif
202221
endif
203222
enddo
204223

@@ -212,6 +231,10 @@ subroutine compute_add_sources_acoustic_moving_sources(potential_dot_dot_acousti
212231
ispec = ispec_selected_source(i_source)
213232

214233
if (ispec_is_acoustic(ispec)) then
234+
235+
! source time function
236+
stf_used = source_time_function(i_source,it,i_stage)
237+
215238
! collocated force
216239
! beware, for acoustic medium, source is: pressure divided by Kappa of the fluid
217240
! the sign is negative because pressure p = - Chi_dot_dot therefore we need
@@ -222,16 +245,10 @@ subroutine compute_add_sources_acoustic_moving_sources(potential_dot_dot_acousti
222245
do i = 1,NGLLX
223246
iglob = ibool(i,j,ispec)
224247

225-
hlagrange = hxis_store(i_source,i) * hgammas_store(i_source,j)
226-
sourcearray(1,i,j) = hlagrange
227-
228248
potential_dot_dot_acoustic(iglob) = potential_dot_dot_acoustic(iglob) &
229-
+ source_time_function(i_source,it,i_stage) * sourcearray(1,i,j) / kappastore(i,j,ispec)
249+
+ sourcearrays(1,i,j,i_source) * stf_used / kappastore(i,j,ispec)
230250
enddo
231251
enddo
232-
! moment tensor
233-
else if (source_type(i_source) == 2) then
234-
call exit_MPI(myrank,'Cannot have moment tensor source in acoustic element')
235252
endif
236253
endif
237254
endif ! if this processor core carries the source and the source element is acoustic

src/specfem2D/compute_add_sources_viscoelastic.f90

Lines changed: 27 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,9 @@ subroutine compute_add_sources_viscoelastic_moving_sources(accel_elastic,it,i_st
109109
ibool,coord,nspec,nglob,xigll,zigll,NPROC, &
110110
xi_source,gamma_source,coorg,knods,NGNOD,npgeo,iglob_source,x_source,z_source, &
111111
vx_source,vz_source,DT,t0,myrank, &
112-
time_stepping_scheme,hxis_store,hgammas_store,tshift_src,source_type,ispec_is_acoustic, &
113-
hxis,hpxis,hgammas,hpgammas,anglesource,ispec_is_poroelastic,Mxx,Mxz,Mzz,gammax,gammaz,xix,xiz, &
114-
AXISYM,xiglj,is_on_the_axis,initialfield,SOURCE_IS_MOVING
112+
time_stepping_scheme,tshift_src,source_type, &
113+
anglesource,Mxx,Mxz,Mzz,gammax,gammaz,xix,xiz, &
114+
AXISYM,xiglj,is_on_the_axis,SOURCE_IS_MOVING
115115

116116
use moving_sources_par, only: locate_source_moving
117117

@@ -120,11 +120,13 @@ subroutine compute_add_sources_viscoelastic_moving_sources(accel_elastic,it,i_st
120120
real(kind=CUSTOM_REAL), dimension(NDIM,nglob_elastic) :: accel_elastic
121121
integer :: it, i_stage
122122

123-
!local variable
123+
! local variables
124124
integer :: i_source,i,j,iglob,ispec
125125
real(kind=CUSTOM_REAL) :: stf_used
126-
double precision :: hlagrange
127126
double precision :: xsrc,zsrc,timeval,t_used
127+
! Lagrange interpolators at source position
128+
double precision, dimension(NGLLX) :: hxis,hpxis
129+
double precision, dimension(NGLLZ) :: hgammas,hpgammas
128130
! single source array
129131
real(kind=CUSTOM_REAL), dimension(NDIM,NGLLX,NGLLZ) :: sourcearray
130132

@@ -165,6 +167,7 @@ subroutine compute_add_sources_viscoelastic_moving_sources(accel_elastic,it,i_st
165167
enddo
166168
endif
167169

170+
! updates source positions and re-calculates source arrays
168171
do i_source = 1,NSOURCES
169172
if (abs(source_time_function(i_source,it,i_stage)) > TINYVAL) then
170173
t_used = (timeval-t0-tshift_src(i_source))
@@ -173,43 +176,28 @@ subroutine compute_add_sources_viscoelastic_moving_sources(accel_elastic,it,i_st
173176
xsrc = x_source(i_source) + vx_source(i_source)*t_used
174177
zsrc = z_source(i_source) + vz_source(i_source)*t_used
175178

176-
! collocated force source
177-
if (source_type(i_source) == 1) then
178-
! TODO: this would be more efficient compled with first guess as in init_moving_sources_GPU()
179-
!call locate_source_moving(xsrc,zsrc, &
180-
! ispec_selected_source(i_source),islice_selected_source(i_source), &
181-
! NPROC,myrank,xi_source(i_source),gamma_source(i_source),.true.)
182-
call locate_source(ibool,coord,nspec,nglob,xigll,zigll, &
183-
xsrc,zsrc, &
184-
ispec_selected_source(i_source),islice_selected_source(i_source), &
185-
NPROC,myrank,xi_source(i_source),gamma_source(i_source),coorg,knods,NGNOD,npgeo, &
186-
iglob_source(i_source),.true.)
187-
188-
else if (source_type(i_source) == 2) then
189-
! moment-tensor source
190-
call locate_source(ibool,coord,nspec,nglob,xigll,zigll, &
191-
xsrc,zsrc, &
192-
ispec_selected_source(i_source),islice_selected_source(i_source), &
193-
NPROC,myrank,xi_source(i_source),gamma_source(i_source),coorg,knods,NGNOD,npgeo, &
194-
iglob_source(i_source),.false.)
195-
196-
else if (.not. initialfield) then
197-
198-
call exit_MPI(myrank,'incorrect source type')
179+
! gets source positioning
180+
! TODO: this would be more efficient compled with first guess as in init_moving_sources_GPU()
181+
!call locate_source_moving(xsrc,zsrc, &
182+
! ispec_selected_source(i_source),islice_selected_source(i_source), &
183+
! NPROC,myrank,xi_source(i_source),gamma_source(i_source),..
184+
call locate_source(ibool,coord,nspec,nglob,xigll,zigll, &
185+
xsrc,zsrc, &
186+
ispec_selected_source(i_source),islice_selected_source(i_source), &
187+
NPROC,myrank,xi_source(i_source),gamma_source(i_source),coorg,knods,NGNOD,npgeo, &
188+
iglob_source(i_source),source_type(i_source))
199189

200-
endif
190+
if (myrank == islice_selected_source(i_source)) then
191+
! element containing source
192+
ispec = ispec_selected_source(i_source)
201193

202-
ispec = ispec_selected_source(i_source)
194+
! only for elastic source elements
195+
if (.not. ispec_is_elastic(ispec)) cycle
203196

204-
! source element is elastic
205-
if (ispec_is_elastic(ispec)) then
206197
! Lagrange interpolators
207198
if (AXISYM) then
208199
if (is_on_the_axis(ispec)) then
209200
call lagrange_any(xi_source(i_source),NGLJ,xiglj,hxis,hpxis)
210-
!do j = 1,NGLJ ! ABAB same result with that loop, this is good
211-
! hxis(j) = hglj(j-1,xi_source(i_source),xiglj,NGLJ)
212-
!enddo
213201
else
214202
call lagrange_any(xi_source(i_source),NGLLX,xigll,hxis,hpxis)
215203
endif
@@ -231,79 +219,21 @@ subroutine compute_add_sources_viscoelastic_moving_sources(accel_elastic,it,i_st
231219
endif
232220
endif
233221

234-
! stores Lagrangians for source
235-
hxis_store(i_source,:) = hxis(:)
236-
hgammas_store(i_source,:) = hgammas(:)
237-
222+
! computes source arrays
238223
sourcearray(:,:,:) = 0._CUSTOM_REAL
239224

240-
! computes source arrays
241225
select case (source_type(i_source))
242226
case (1)
243227
! collocated force source
244-
do j = 1,NGLLZ
245-
do i = 1,NGLLX
246-
hlagrange = hxis_store(i_source,i) * hgammas_store(i_source,j)
247-
248-
! source element is acoustic
249-
if (ispec_is_acoustic(ispec)) then
250-
sourcearray(:,i,j) = real(hlagrange,kind=CUSTOM_REAL)
251-
endif
252-
253-
! source element is elastic
254-
if (ispec_is_elastic(ispec)) then
255-
if (P_SV) then
256-
! P_SV case
257-
! sourcearray(1,i,j) = real(- sin(anglesource(i_source)) * hlagrange,kind=CUSTOM_REAL)
258-
! sourcearray(2,i,j) = real( cos(anglesource(i_source)) * hlagrange,kind=CUSTOM_REAL)
259-
!! DK DK May 2018: the sign of the source was inverted compared to the analytical solution for a simple elastic benchmark
260-
!! DK DK May 2018: with a force source (the example that is in EXAMPLES/check_absolute_amplitude_of_force_source_seismograms),
261-
!! DK DK May 2018: which means that the sign was not right here. I changed it. Please do NOT revert that change,
262-
!! DK DK May 2018: otherwise the code will give inverted seismograms compared to analytical solutions for benchmarks,
263-
!! DK DK May 2018: and more generally compared to reality
264-
sourcearray(1,i,j) = real(+ sin(anglesource(i_source)) * hlagrange,kind=CUSTOM_REAL)
265-
sourcearray(2,i,j) = real(- cos(anglesource(i_source)) * hlagrange,kind=CUSTOM_REAL)
266-
else
267-
! SH case (membrane)
268-
sourcearray(:,i,j) = real(hlagrange,kind=CUSTOM_REAL)
269-
endif
270-
endif
271-
272-
! source element is poroelastic
273-
if (ispec_is_poroelastic(ispec)) then
274-
! sourcearray(1,i,j) = real(- sin(anglesource(i_source)) * hlagrange,kind=CUSTOM_REAL)
275-
! sourcearray(2,i,j) = real( cos(anglesource(i_source)) * hlagrange,kind=CUSTOM_REAL)
276-
!! DK DK May 2018: the sign of the source was inverted compared to the analytical solution for a simple elastic benchmark
277-
!! DK DK May 2018: with a force source (the example that is in EXAMPLES/check_absolute_amplitude_of_force_source_seismograms),
278-
!! DK DK May 2018: which means that the sign was not right here. I changed it. Please do NOT revert that change,
279-
!! DK DK May 2018: otherwise the code will give inverted seismograms compared to analytical solutions for benchmarks,
280-
!! DK DK May 2018: and more generally compared to reality
281-
sourcearray(1,i,j) = real(+ sin(anglesource(i_source)) * hlagrange,kind=CUSTOM_REAL)
282-
sourcearray(2,i,j) = real(- cos(anglesource(i_source)) * hlagrange,kind=CUSTOM_REAL)
283-
endif
284-
285-
enddo
286-
enddo
287-
228+
call compute_arrays_source_forcesolution(ispec,hxis,hgammas,sourcearray,anglesource(i_source))
288229
case (2)
289230
! moment-tensor source
290-
call compute_arrays_source(ispec,xi_source(i_source),gamma_source(i_source),sourcearray, &
291-
Mxx(i_source),Mzz(i_source),Mxz(i_source),xix,xiz,gammax,gammaz,xigll,zigll,nspec)
292-
! checks source
293-
if (ispec_is_acoustic(ispec)) then
294-
call exit_MPI(myrank,'cannot have moment tensor source in acoustic element')
295-
endif
296-
297-
! checks wave type
298-
if (ispec_is_elastic(ispec)) then
299-
if (.not. P_SV ) call exit_MPI(myrank,'cannot have moment tensor source in SH (membrane) waves calculation')
300-
endif
301-
231+
call compute_arrays_source_cmt(ispec,hxis,hgammas,hpxis,hpgammas,sourcearray, &
232+
Mxx(i_source),Mzz(i_source),Mxz(i_source),xix,xiz,gammax,gammaz,nspec)
302233
end select
303234

304235
! stores sourcearray for all sources
305236
sourcearrays(:,:,:,i_source) = sourcearray(:,:,:)
306-
307237
endif
308238
endif
309239
enddo

0 commit comments

Comments
 (0)