167 ,ig_receiver_saving_incr&
168 ,lg_output_debug_file&
170 ,ig_hexa_receiver_unit&
176 real ,
dimension(ig_ncpu) :: rldum1
177 real ,
dimension(ig_ncpu) :: maxdmin_all_cpu
181 integer,
dimension(1) :: min_loc
182 integer,
dimension(ig_ncpu) :: ilrcpu
188 character(len=1) :: ctmp
189 character(len=6) :: crec
195 ig_nreceiver_hexa = 0
199 open(unit=100,file=trim(cg_prefix)//
".vor",status=
'old',iostat=ios)
201 if( (ios == 0) .and. (ig_receiver_saving_incr <= ig_ndt) )
then
203 if (ig_myrank == 0)
then
204 write(ig_lst_unit,
'(a)')
" "
205 write(ig_lst_unit,
'(a)')
"information about receivers in file "//trim(cg_prefix)//
".vor"
209 read(unit=100,fmt=*,iostat=ios) ctmp
211 ig_nreceiver_hexa = ig_nreceiver_hexa + 1
215 allocate(tlrinf(ig_nreceiver_hexa))
218 do irec = 1,ig_nreceiver_hexa
225 tlrinf(irec)%xi = 0.0
226 tlrinf(irec)%eta = 0.0
227 tlrinf(irec)%zeta = 0.0
228 tlrinf(irec)%dmin = huge(rldmin)
229 tlrinf(irec)%lag(:,:,:) = 0.0
230 tlrinf(irec)%gll(:,:,:) = 0
233 tlrinf(irec)%kgll = 0
234 tlrinf(irec)%lgll = 0
235 tlrinf(irec)%mgll = 0
236 tlrinf(irec)%rglo = 0
238 read(unit=100,fmt=*) tlrinf(irec)%x,tlrinf(irec)%y,tlrinf(irec)%z
242 ,tlrinf(irec)%kgll,tlrinf(irec)%lgll,tlrinf(irec)%mgll,tlrinf(irec)%iel )
245 call mpi_allgather(tlrinf(irec)%dmin,1,mpi_real,rldum1,1,mpi_real,mpi_comm_world,ios)
246 min_loc = minloc(rldum1(1:ig_ncpu))
248 if (min_loc(1) == ig_myrank+1)
then
249 tlrinf(irec)%cpu = ig_myrank + 1
252 tlrinf(irec)%cpu = min_loc(1)
260 allocate(tg_receiver_hexa(ilnrec))
262 do irec = 1,ig_nreceiver_hexa
263 if (tlrinf(irec)%cpu == ig_myrank+1)
then
265 tg_receiver_hexa(j) = tlrinf(irec)
266 tg_receiver_hexa(j)%rglo = irec
269 ig_nreceiver_hexa = ilnrec
271 ig_nreceiver_hexa = 0
276 call mpi_gather(ig_nreceiver_hexa,1,mpi_integer,ilrcpu,1,mpi_integer,0,mpi_comm_world,ios)
279 do irec = 1,ig_nreceiver_hexa
287 if (ig_nreceiver_hexa > 0)
then
289 maxdmin = -huge(maxdmin)
291 do irec = 1,ig_nreceiver_hexa
292 maxdmin = max(maxdmin,tg_receiver_hexa(irec)%dmin)
303 call mpi_gather(maxdmin,1,mpi_real,maxdmin_all_cpu,1,mpi_real,0,mpi_comm_world,ios)
305 if (ig_myrank == 0)
then
307 write(ig_lst_unit,
'(a,e14.7)')
"maximum localisation error of all receivers in free surface = ",maxval(maxdmin_all_cpu)
308 call flush(ig_lst_unit)
314 if ( ig_nreceiver_hexa > 0 )
then
316 allocate(ig_hexa_receiver_unit(ig_nreceiver_hexa))
318 do irec = 1,ig_nreceiver_hexa
320 write(crec,
'(i6.6)') tg_receiver_hexa(irec)%rglo
322 open(unit = get_newunit(ig_hexa_receiver_unit(irec))&
323 ,file = trim(cg_prefix)//
".vor."//trim(adjustl(crec))//
".gpl"&
326 ,access =
'sequential'&
327 ,form =
'unformatted'&
329 ,recordtype =
'stream')
335 if (lg_output_debug_file)
then
336 open(unit=100,file=
"debug.cpu."//trim(cg_myrank)//
".volume.receivers.info")
337 do irec = 1,ig_nreceiver_hexa
338 write(unit=100,fmt=
'(/,a,i10 )')
"Receiver ",tg_receiver_hexa(irec)%rglo
339 write(unit=100,fmt=
'( a,i10 )')
" in core ",tg_receiver_hexa(irec)%cpu-1
340 write(unit=100,fmt=
'( a,i10 )')
" in hexa ",tg_receiver_hexa(irec)%iel
341 write(unit=100,fmt=
'( 3a )')
" X ",
" Y ",
" Z "
342 write(unit=100,fmt=
'(3(e14.7,1x))') tg_receiver_hexa(irec)%x,tg_receiver_hexa(irec)%y,tg_receiver_hexa(irec)%z
343 write(unit=100,fmt=
'( 3a )')
" XI ",
" ETA ",
" ZETA "
344 write(unit=100,fmt=
'(3(e14.7,1x))') tg_receiver_hexa(irec)%xi,tg_receiver_hexa(irec)%eta,tg_receiver_hexa(irec)%zeta
351 if (ig_myrank == 0)
then
352 write(ig_lst_unit,
'(/a)')
"no volume receiver computed"
353 call flush(ig_lst_unit)
382 ,ig_quadf_gll_glonum&
383 ,ig_quadf_gnode_glonum&
389 ,ig_receiver_saving_incr&
390 ,lg_output_debug_file&
392 ,ig_quad_receiver_unit&
398 real ,
dimension(ig_ncpu) :: maxdmin_all_cpu
402 integer,
dimension(ig_ncpu) :: ilrcpu
410 character(len= 1) :: ctmp
411 character(len= 6) :: crec
412 character(len=255) :: info
415 logical,
dimension(ig_ncpu) :: is_inside_all_cpu
421 ig_nreceiver_quad = 0
425 open(unit=100,file=trim(cg_prefix)//
".fsr",status=
'old',iostat=ios)
427 if( (ios == 0) .and. (ig_receiver_saving_incr <= ig_ndt) )
then
429 if (ig_myrank == 0)
then
430 write(ig_lst_unit,
'(a)')
" "
431 write(ig_lst_unit,
'(a)')
"information about receivers in file "//trim(cg_prefix)//
".fsr"
435 read(unit=100,fmt=*,iostat=ios) ctmp
437 ig_nreceiver_quad = ig_nreceiver_quad + 1
441 allocate(tlrinf(ig_nreceiver_quad))
444 do irec = 1,ig_nreceiver_quad
451 tlrinf(irec)%xi = 0.0
452 tlrinf(irec)%eta = 0.0
453 tlrinf(irec)%dmin = huge(rldmin)
454 tlrinf(irec)%lag(:,:) = 0.0
455 tlrinf(irec)%gll(:,:) = 0
456 tlrinf(irec)%cpu = -1
458 tlrinf(irec)%lgll = 0
459 tlrinf(irec)%mgll = 0
460 tlrinf(irec)%rglo = 0
462 read(unit=100,fmt=*) tlrinf(irec)%x,tlrinf(irec)%y
466 if (ig_nquad_fsurf > 0)
then
468 call
is_inside_quad(tlrinf(irec)%x,tlrinf(irec)%y,ig_quadf_gnode_glonum,ig_nquad_fsurf,ig_quad_nnode,tlrinf(irec)%dmin,tlrinf(irec)%lgll,tlrinf(irec)%mgll,tlrinf(irec)%iel,is_inside)
478 call mpi_gather(is_inside,1,mpi_logical,is_inside_all_cpu,1,mpi_logical,0,mpi_comm_world,ios)
480 if (ig_myrank == 0)
then
486 if (is_inside_all_cpu(icpu))
then
497 write(info,
'(a)')
"error in subroutine init_quad_receiver: receiver not found over all cpus"
498 call error_stop(info)
502 do icpu = iloc+1,ig_ncpu
503 is_inside_all_cpu(icpu) = .false.
512 call mpi_scatter(is_inside_all_cpu,1,mpi_logical,is_inside,1,mpi_logical,0,mpi_comm_world,ios)
516 tlrinf(irec)%cpu = ig_myrank + 1
529 allocate(tg_receiver_quad(ilnrec))
532 do irec = 1,ig_nreceiver_quad
533 if (tlrinf(irec)%cpu == ig_myrank+1)
then
535 tg_receiver_quad(j) = tlrinf(irec)
536 tg_receiver_quad(j)%rglo = irec
540 ig_nreceiver_quad = ilnrec
544 ig_nreceiver_quad = 0
551 call mpi_gather(ig_nreceiver_quad,1,mpi_integer,ilrcpu,1,mpi_integer,0,mpi_comm_world,ios)
554 do irec = 1,ig_nreceiver_quad
562 if (ig_nreceiver_quad > 0)
then
564 maxdmin = -huge(maxdmin)
566 do irec = 1,ig_nreceiver_quad
567 maxdmin = max(maxdmin,tg_receiver_quad(irec)%dmin)
578 call mpi_gather(maxdmin,1,mpi_real,maxdmin_all_cpu,1,mpi_real,0,mpi_comm_world,ios)
580 if (ig_myrank == 0)
then
582 write(ig_lst_unit,
'(a,e14.7)')
"maximum localisation error of all receivers in free surface = ",maxval(maxdmin_all_cpu)
583 call flush(ig_lst_unit)
588 if ( ig_nreceiver_quad > 0 )
then
590 allocate(ig_quad_receiver_unit(ig_nreceiver_quad))
592 do irec = 1,ig_nreceiver_quad
594 write(crec,
'(i6.6)') tg_receiver_quad(irec)%rglo
596 open(unit = get_newunit(ig_quad_receiver_unit(irec))&
597 ,file = trim(cg_prefix)//
".fsr."//trim(adjustl(crec))//
".gpl"&
600 ,access =
'sequential'&
601 ,form =
'unformatted'&
603 ,recordtype =
'stream')
609 if (lg_output_debug_file)
then
610 open(unit=100,file=
"debug.cpu."//trim(cg_myrank)//
".freesurface.receivers.info")
611 do irec = 1,ig_nreceiver_quad
612 write(unit=100,fmt=
'(/,a,i10 )')
"Receiver ",tg_receiver_quad(irec)%rglo
613 write(unit=100,fmt=
'( a,i10 )')
" in core ",tg_receiver_quad(irec)%cpu-1
614 write(unit=100,fmt=
'( a,i10 )')
" in quad ",tg_receiver_quad(irec)%iel
615 write(unit=100,fmt=
'( 2a )')
" X ",
" Y "
616 write(unit=100,fmt=
'(2(e14.7,1x))') tg_receiver_quad(irec)%x,tg_receiver_quad(irec)%y
617 write(unit=100,fmt=
'( 2a )')
" XI ",
" ETA "
618 write(unit=100,fmt=
'(2(e14.7,1x))') tg_receiver_quad(irec)%xi,tg_receiver_quad(irec)%eta
625 if (ig_myrank == 0)
then
626 write(ig_lst_unit,
'(/a)')
"no free surface receiver computed"
627 call flush(ig_lst_unit)
663 real ,
intent(in) :: x
664 real ,
intent(in) :: y
665 real ,
intent(in) :: z
666 real ,
intent(out) :: dmin
667 integer,
intent(out) :: kgll
668 integer,
intent(out) :: lgll
669 integer,
intent(out) :: mgll
670 integer,
intent(out) :: iel
681 do ihexa = 1,ig_nhexa
686 igll = ig_hexa_gll_glonum(m,l,k,ihexa)
688 d = sqrt( (rg_gll_coordinate(1,igll) - x)**2 &
689 +(rg_gll_coordinate(2,igll) - y)**2 &
690 +(rg_gll_coordinate(3,igll) - z)**2 )
733 real ,
intent(in) :: x
734 real ,
intent(in) :: y
735 integer,
intent(in),
dimension(:,:,:) :: global_gll
737 real ,
intent(out) :: dmin
738 integer,
intent(out) :: lgll
739 integer,
intent(out) :: mgll
740 integer,
intent(out) :: iel
751 nquad =
size(global_gll,3)
757 igll = global_gll(m,l,iquad)
758 d = sqrt( (rg_gll_coordinate(1,igll) - x)**2 + (rg_gll_coordinate(2,igll) - y)**2 )
834 integer,
parameter :: iter_max=100
848 xisol = rg_gll_abscissa(tlxinf%mgll)
849 etsol = rg_gll_abscissa(tlxinf%lgll)
850 zesol = rg_gll_abscissa(tlxinf%kgll)
855 call
compute_hexa_jacobian(ihexa,xisol,etsol,zesol,dxidx,dxidy,dxidz,detdx,detdy,detdz,dzedx,dzedy,dzedz,deter)
862 dxi = dxidx*dx + dxidy*dy + dxidz*dz
863 det = detdx*dx + detdy*dy + detdz*dz
864 dze = dzedx*dx + dzedy*dy + dzedz*dz
868 dmin = sqrt( (newx-tlxinf%x)**2 + (newy-tlxinf%y)**2 + (newz-tlxinf%z)**2 )
872 if (mod(iter,iter_max) == 0)
then
890 igll = ig_hexa_gll_glonum(m,l,k,ihexa)
891 tlxinf%gll(m,l,k) = igll
900 tlxinf%lag(m,l,k) =
lagrap(m,tlxinf%xi,ig_ngll)*
lagrap(l,tlxinf%eta,ig_ngll)*
lagrap(k,tlxinf%zeta,ig_ngll)
924 ,ig_quadf_gll_glonum&
962 integer,
parameter :: iter_max=100
970 xisol = rg_gll_abscissa(tlxinf%mgll)
971 etsol = rg_gll_abscissa(tlxinf%lgll)
984 dxi = dxidx*dx + dxidy*dy
985 det = detdx*dx + detdy*dy
988 dmin = sqrt( (newx-tlxinf%x)**2 + (newy-tlxinf%y)**2 )
991 if (mod(iter,iter_max) == 0)
then
1007 igll = ig_quadf_gll_glonum(l,k,iquad)
1008 tlxinf%gll(l,k) = igll
1015 tlxinf%lag(l,k) =
lagrap(l,tlxinf%xi,ig_ngll)*
lagrap(k,tlxinf%eta,ig_ngll)
1035 ,rg_simu_current_time&
1038 ,rg_gll_displacement&
1040 ,rg_gll_acceleration&
1043 ,ig_hexa_receiver_unit&
1044 ,ig_quad_receiver_unit
1054 real,
dimension(IG_NDOF,IG_NGLL,IG_NGLL,IG_NGLL) :: gll_dis_hexa
1055 real,
dimension(IG_NDOF,IG_NGLL,IG_NGLL,IG_NGLL) :: gll_vel_hexa
1056 real,
dimension(IG_NDOF,IG_NGLL,IG_NGLL,IG_NGLL) :: gll_acc_hexa
1058 real,
dimension(IG_NDOF,IG_NGLL,IG_NGLL) :: gll_dis_quad
1059 real,
dimension(IG_NDOF,IG_NGLL,IG_NGLL) :: gll_vel_quad
1060 real,
dimension(IG_NDOF,IG_NGLL,IG_NGLL) :: gll_acc_quad
1079 do irec = 1,ig_nreceiver_hexa
1092 write(unit=ig_hexa_receiver_unit(irec)) rg_simu_current_time,dis_x,dis_y,dis_z,vel_x,vel_y,vel_z,acc_x,acc_y,acc_z
1093 call flush(ig_hexa_receiver_unit(irec))
1102 do irec = 1,ig_nreceiver_quad
1115 write(unit=ig_quad_receiver_unit(irec)) rg_simu_current_time,dis_x,dis_y,dis_z,vel_x,vel_y,vel_z,acc_x,acc_y,acc_z
1116 call flush(ig_quad_receiver_unit(irec))
1143 subroutine is_inside_quad(x,y,quad_gnode,nquad,quad_nnode,dmin,lgll,mgll,quad_num,is_inside)
1151 real ,
intent( in) :: x
1152 real ,
intent( in) :: y
1153 integer,
intent( in) :: nquad
1154 integer,
intent( in) :: quad_nnode
1155 integer,
intent( in),
dimension(quad_nnode,nquad) :: quad_gnode
1156 real ,
intent(out) :: dmin
1157 integer,
intent(out) :: lgll
1158 integer,
intent(out) :: mgll
1159 integer,
intent(out) :: quad_num
1160 logical,
intent(out) :: is_inside
1167 real ,
dimension(quad_nnode+1) :: quad_gnode_x
1168 real ,
dimension(quad_nnode+1) :: quad_gnode_y
1176 do inode = 1,quad_nnode
1178 node_num = quad_gnode(inode,iquad)
1180 quad_gnode_x(inode) = rg_gnode_x(node_num)
1181 quad_gnode_y(inode) = rg_gnode_y(node_num)
1185 quad_gnode_x(quad_nnode+1) = quad_gnode_x(1)
1186 quad_gnode_y(quad_nnode+1) = quad_gnode_y(1)
1196 dmin = sqrt( (quad_gnode_x(1)-x)**2 + (quad_gnode_y(1)-y)**2 )
1249 real ,
intent(in) :: x0
1250 real ,
intent(in) :: y0
1251 real ,
intent(in) :: x(n)
1252 real ,
intent(in) :: y(n)
1253 integer ,
intent(in) :: n
1254 integer ,
intent(out) :: l
1255 integer ,
intent(out) :: m
1257 real ,
parameter :: pix2 = 2.0*rg_pi
1275 if ( (x(1) == x(n)) .and. (y(1) == y(n)) ) n0 = n - 1
1283 if (u == 0.0 .and. v == 0.0)
then
1289 theta1 = atan2(v, u)
1298 if (u == 0.0 .and. v == 0.0)
then
1303 thetai = atan2(v, u)
1304 angle = abs(thetai - theta)
1306 if (abs(angle - rg_pi) < tol)
then
1311 if (angle > rg_pi) angle = angle - pix2
1312 if (theta > thetai ) angle = -angle
1319 angle = abs(theta1 - theta)
1320 if (abs(angle - rg_pi) < tol)
then
1324 if (angle > rg_pi ) angle = angle - pix2
1325 if (theta > theta1 ) angle = -angle
1329 m = abs(sum)/pix2 + 0.2
1332 if (sum < 0.0) m = -m
subroutine, public search_closest_quad_gll(x, y, global_gll, dmin, lgll, mgll, iel)
This subroutine searches among all free surface quadrangle elements in cpu myrank the closest GLL nod...
This module contains subroutines to compute information about receivers and to write receivers' time ...
real function, public lagrap(i, x, n)
function to compute value of order Lagrange polynomial of the GLL node i at abscissa : ...
subroutine, public search_closest_hexa_gll(x, y, z, dmin, kgll, lgll, mgll, iel)
This subroutine searches among all hexahedron elements in cpu myrank the closest GLL node to a point ...
subroutine, public compute_hexa_jacobian(ihexa, xisol, etsol, zesol, dxidx, dxidy, dxidz, detdx, detdy, detdz, dzedx, dzedy, dzedz, det)
This subroutine computes jacobian matrix and its determinant at location in hexahedron element ihexa...
subroutine, private is_inside_polygon(x0, y0, x, y, n, l, m)
This subroutine tests if a point P with coordinates is inside a polygonal line.
type for receivers (i.e., stations) located inside quadrangle elements
subroutine, public get_hexa_gll_value(gll_all_values, gll_global_number, gll_selected_values)
subroutine to get hexahedron element GLL values from an array ordered by global GLL nodes numbering...
This module defines all global variables of EFISPEC3D. Scalar variables are initialized directly in t...
subroutine, public init_quad_receiver()
This subroutine reads all receivers in file *.fsr; determines to which cpu they belong; computes thei...
subroutine, public compute_info_quad_receiver(tlxinf)
This subroutine computes local coordinates of a receiver in the quadrangle element it belongs...
This module contains subroutines to compute global -coordinates of a given point in the physical doma...
subroutine, public compute_hexa_point_coord(ihexa, xi, eta, zeta, x, y, z)
subroutine to compute -coordinates of a point knowing to which hexahedron element it belongs and its ...
real function, public compute_quad_point_coord_z(iquad, xi, eta)
function to compute -coordinates of a point knowing to which quadrangle element it belongs and its lo...
subroutine, public quad_lagrange_interp(gll_values, lag, x, y, z)
This subroutine interpolates GLL nodes -values of a quadrangle element using Lagrange polynomials...
type for receivers (i.e., stations) located inside hexahedron elements
subroutine, public init_hexa_receiver()
This subroutine reads all receivers in file *.vor; determines to which cpu they belong; computes thei...
subroutine, public write_receiver_output()
This subroutine writes -displacements, velocities and accelerations at receivers. ...
This module contains subroutines to get GLL nodes values from global GLL nodes numbering.
subroutine, public compute_quad_point_coord(iquad, xi, eta, x, y, z)
subroutine to compute -coordinates of a point knowing to which quadrangle element it belongs and its ...
subroutine, public compute_quad_jacobian(iquad, xisol, etsol, dxidx, dxidy, detdx, detdy, det)
This subroutine computes jacobian matrix and its determinant at location in quadrangle element iquad...
subroutine, public get_quad_gll_value(gll_all_values, gll_global_number, gll_selected_values)
subroutine to get quadrangle element GLL values from an array ordered by global GLL nodes numbering...
subroutine, public is_inside_quad(x, y, quad_gnode, nquad, quad_nnode, dmin, lgll, mgll, quad_num, is_inside)
This subroutine finds which quadrangle element contains a receiver.
This module contains functions to compute Lagrange polynomials and its derivatives; and to interpolat...
subroutine, public compute_info_hexa_receiver(tlxinf)
This subroutine computes local coordinates of a receiver in the hexahedron element it belongs...
This module contains subroutines to compute jacobian matrix.
subroutine, public hexa_lagrange_interp(gll_values, lag, x, y, z)
This subroutine interpolates GLL nodes -values of a hexahedron element using Lagrange polynomials...