SPEED
MAKE_NH_Enhanced_NNSearch.f90
Go to the documentation of this file.
1
2! Copyright (C) 2012 The SPEED FOUNDATION
3! Author: Ilario Mazzieri
4!
5! This file is part of SPEED.
6!
7! SPEED is free software; you can redistribute it and/or modify it
8! under the terms of the GNU Affero General Public License as
9! published by the Free Software Foundation, either version 3 of the
10! License, or (at your option) any later version.
11!
12! SPEED is distributed in the hope that it will be useful, but
13! WITHOUT ANY WARRANTY; without even the implied warranty of
14! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15! Affero General Public License for more details.
16!
17! You should have received a copy of the GNU Affero General Public License
18! along with SPEED. If not, see <http://www.gnu.org/licenses/>.
19
20
25
36
37
38 subroutine make_nh_enhanced_nnsearch(nn_loc, count, mpi_id, mpi_np, &
39 mpi_comm, mpi_file, NN_src_ind_loc)
40
42
43 !use speed_par
44
46
47 implicit none
48
49 include 'SPEED.MPI'
50
51 integer*4 :: nn_loc, mpi_id, mpi_np, count, mpi_comm, mpi_ierr
52 integer*4, dimension(:), allocatable :: NN_src_ind_ip
53 integer*4, dimension(count) :: NN_src_ind_loc
54 integer*4, dimension(mpi_np) :: count_proc_nhe
55
56 character*70 :: file_tomo, mpi_file, file_nhe_nnind, file_nhe_proc
57 character*70 :: file_nhe_new, file_nhe_nnind_new
58 integer*4 :: npts_tomo, stat, error, n_neighbours
59 real(kdkind) :: query_vec(3)
60 real(kdkind), dimension(:), allocatable :: xs_ip, ys_ip, zs_ip
61 real(kdkind), dimension(:,:), allocatable :: nodes_in_xyz
62
63 type(kdtree2), pointer :: kd2_obj
64 type(kdtree2_result) :: result_temp(1)
65
66 real*8 :: t0, t1, time_elapsed
67 real*8, dimension(5) :: dummy
68 integer*4 :: i, j, ipt, inode, ip, ncount, unit_mpi
69
70
71 call mpi_barrier(mpi_comm, mpi_ierr)
72 call mpi_allgather(count, 1, speed_integer, count_proc_nhe, 1, speed_integer, mpi_comm, mpi_ierr)
73
74
75 if(mpi_id.eq.0) then
76 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
77 ! Reading Tomography Grid Points data
78 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
79 ! tomo_xyz_mech.in = text file with tomography data
80 ! 1st Line = No. of Tomo Points (npts_tomo)
81 ! 2nd to (npts_tomo+1)th line contains 8 columns:
82 ! x_cord y_cord z_cord Rho Vs Vp Qs Qp (Units must be same as given in *.mate file)
83 file_tomo = 'tomo_xyz_mech.in'
84
85 open(124,file=file_tomo)
86 read(124,*)
87 read(124,*) npts_tomo
88
89 allocate(nodes_in_xyz(3,npts_tomo),stat=error)
90 if (stat.ne.0) then
91 write(*,*)'error: couldnt allocate memory for array,',&
92 ' size=',npts_tomo
93 call exit(exit_normal)
94 endif
95
96 do ipt = 1, npts_tomo
97 read(124,*)(nodes_in_xyz(i,ipt), i=1,3), (dummy(j), j=1,5)
98 enddo
99 close(124)
100
101
102 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
103 ! Defining Kd-tree Object and then search
104 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
105
106 kd2_obj => kdtree2_create(nodes_in_xyz,sort=.false.,rearrange=.true.)
107 n_neighbours = 1
108
109
110 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
111 ! Getting NHE Nodes from Each MPI Process and Performing search
112 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
113 do ip = 0, mpi_np-1
114
115 ! Reading coordinates of nodes where NN search have to be performed
116 file_nhe_proc = 'nhexyz000000.mpi'
117 file_nhe_nnind = 'nhenni000000.mpi'
118 unit_mpi = 1500 + ip
119 if (ip.lt. 10) then
120 write(file_nhe_proc(12:12),'(i1)') ip
121 write(file_nhe_nnind(12:12),'(i1)') ip
122 else if (ip .lt. 100) then
123 write(file_nhe_proc(11:12),'(i2)') ip
124 write(file_nhe_nnind(11:12),'(i2)') ip
125 else if (ip .lt. 1000) then
126 write(file_nhe_proc(10:12),'(i3)') ip
127 write(file_nhe_nnind(10:12),'(i3)') ip
128 else if (ip .lt. 10000) then
129 write(file_nhe_proc(9:12),'(i4)') ip
130 write(file_nhe_nnind(9:12),'(i4)') ip
131 else if (ip .lt. 100000) then
132 write(file_nhe_proc(8:12),'(i5)') ip
133 write(file_nhe_nnind(8:12),'(i5)') ip
134 else if (ip .lt. 1000000) then
135 write(file_nhe_proc(7:12),'(i6)') ip
136 write(file_nhe_nnind(7:12),'(i6)') ip
137 endif
138
139 if(len_trim(mpi_file) .ne. 70) then
140 file_nhe_new = mpi_file(1:len_trim(mpi_file)) // '/' // file_nhe_proc
141 file_nhe_nnind_new = mpi_file(1:len_trim(mpi_file)) // '/' // file_nhe_nnind
142 else
143 file_nhe_new = file_nhe_proc
144 file_nhe_nnind_new = file_nhe_nnind
145 endif
146
147 open(unit_mpi,file=file_nhe_new)
148 read(unit_mpi,*) ncount
149 if(ncount.ne.count_proc_nhe(ip+1)) then
150 write(*,*)'ncount in NHE_proc files are not consistent'
151 call exit(exit_no_nodes)
152 endif
153
154 if (ncount.gt.0) then
155 allocate(xs_ip(ncount), ys_ip(ncount), zs_ip(ncount))
156 allocate(nn_src_ind_ip(ncount))
157 do inode = 1,ncount
158 read(unit_mpi,*) xs_ip(inode), ys_ip(inode), zs_ip(inode)
159 enddo
160 endif
161 close(unit_mpi)
162
163 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
164 ! Performing NN Search for nodes in each Partition
165 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
166 if (ncount.gt.0) then
167 do inode = 1,ncount
168 query_vec(1) = xs_ip(inode)
169 query_vec(2) = ys_ip(inode)
170 query_vec(3) = zs_ip(inode)
171 call kdtree2_n_nearest(kd2_obj,query_vec,n_neighbours,result_temp)
172 nn_src_ind_ip(inode) = result_temp(1)%idx ! Inder of Nearest Neighbor in Tomo Points
173 enddo
174 endif
175
176 open(unit_mpi,file=file_nhe_nnind_new)
177 if (ncount.gt.0) then
178 do i = 1,ncount
179 write(unit_mpi,*) nn_src_ind_ip(i)
180 enddo
181 deallocate(xs_ip, ys_ip, zs_ip, nn_src_ind_ip)
182 endif
183 close(unit_mpi)
184
185 enddo ! ip = 0, mpi_np-1
186
187
188 deallocate(nodes_in_xyz)
189 call kdtree2_destroy(kd2_obj)
190
191
192 endif !if mpi_id == 0
193
194 call mpi_barrier(mpi_comm, mpi_ierr)
195
196
197 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
198 ! Reading Back the results of NN Search (in respective processor now)
199 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
200
201 file_nhe_nnind = 'nhenni000000.mpi'
202 unit_mpi = 1500 + mpi_id
203 if (mpi_id.lt. 10) then
204 write(file_nhe_nnind(12:12),'(i1)') mpi_id
205 else if (mpi_id .lt. 100) then
206 write(file_nhe_nnind(11:12),'(i2)') mpi_id
207 else if (mpi_id .lt. 1000) then
208 write(file_nhe_nnind(10:12),'(i3)') mpi_id
209 else if (mpi_id .lt. 10000) then
210 write(file_nhe_nnind(9:12),'(i4)') mpi_id
211 else if (mpi_id .lt. 100000) then
212 write(file_nhe_nnind(8:12),'(i5)') mpi_id
213 else if (mpi_id .lt. 1000000) then
214 write(file_nhe_nnind(7:12),'(i6)') mpi_id
215 endif
216
217 if(len_trim(mpi_file) .ne. 70) then
218 file_nhe_nnind_new = mpi_file(1:len_trim(mpi_file)) // '/' // file_nhe_nnind
219 else
220 file_nhe_nnind_new = file_nhe_nnind
221 endif
222
223 open(unit_mpi,file=file_nhe_nnind_new)
224 if (count.gt.0) then
225 do inode = 1,count
226 read(unit_mpi,*) nn_src_ind_loc(inode)
227 enddo
228 endif
229 close(unit_mpi)
230
231 call mpi_barrier(mpi_comm, mpi_ierr)
232
233 end subroutine make_nh_enhanced_nnsearch
234
subroutine make_nh_enhanced_nnsearch(nn_loc, count, mpi_id, mpi_np, mpi_comm, mpi_file, nn_src_ind_loc)
...Not-Honoring Enhanced (NHE) Implementation
type(kdtree2) function, pointer, public kdtree2_create(input_data, dim, sort, rearrange)
Definition kdtree2.f90:612
subroutine, public kdtree2_destroy(tp)
Definition kdtree2.f90:989
subroutine, public kdtree2_n_nearest(tp, qv, nn, results)
Definition kdtree2.f90:1031
SPEED exit codes.
Definition MODULES.f90:25
integer, parameter exit_no_nodes
Definition MODULES.f90:41
integer, parameter exit_normal
Definition MODULES.f90:29