41
42
43
44
45
46 USE intbufdef_mod
47 USE shooting_node_mod
49 use remove_neighbour_segment_mod , only : remove_neighbour_segment
50
51
52
53 USE spmd_comm_world_mod, ONLY : spmd_comm_world
54#include "implicit_f.inc"
55
56
57
58#include "spmd.inc"
59
60
61
62#include "task_c.inc"
63#include "com04_c.inc"
64#include "scr17_c.inc"
65#include "param_c.inc"
66
67
68#include "com01_c.inc"
69
70
71
72 INTEGER, INTENT(in) :: SURFARCE_NB
73 INTEGER, DIMENSION(SURFARCE_NB), INTENT(in) :: SURFACE_ID
74 INTEGER, DIMENSION(NINTER+1,2), INTENT(in) :: SHIFT_INTERFACE
75 TYPE(INTBUF_STRUCT_), DIMENSION(NINTER), INTENT(inout) :: INTBUF_TAB
76 INTEGER, DIMENSION(NPARI,NINTER), INTENT(in) :: IPARI
77 INTEGER, DIMENSION(2,NSPMD+1), INTENT(in) :: IAD_ELEM
78 TYPE(shooting_node_type), INTENT(inout) :: SHOOT_STRUCT
79
80
81
82 INTEGER :: I,K,J,IJK,FIRST,LAST
83 INTEGER :: NIN,ID_INTER,NUMBER_INTER,NRTM
84 INTEGER :: ITY,IDEL
85 INTEGER :: NODE_ID
86 INTEGER :: SHIFT
87 INTEGER :: DICHOTOMIC_SEARCH_I_ASC
88 TYPE(array_type), DIMENSION(:), ALLOCATABLE :: S_BUFFER
89 TYPE(array_type), DIMENSION(:), ALLOCATABLE :: R_BUFFER
90
91 INTEGER :: GLOBAL_SURFACE_ID
92 INTEGER :: PROC_ID,REMOTE_PROC
93 INTEGER :: NB_PROC
94 INTEGER :: FRONTIER_ELM
95 INTEGER, DIMENSION(NSPMD) :: NUMBER_REMOTE_SURF,NUMBER_REMOTE_SURF_R
96 LOGICAL, DIMENSION(NSPMD) :: ALREADY_DONE
97
98 INTEGER :: IERROR
99 INTEGER :: MSGTYP,MSGOFF1,MSGOFF2
100 INTEGER :: RECV_NB,RECV_NB_2
101 INTEGER :: SIZE_R,SIZE_S
102 INTEGER, DIMENSION(NSPMD) :: INDEX_R_PROC,INDEX_R_PROC_2
103 INTEGER, DIMENSION(NSPMD) :: REQUEST_SIZE_R,REQUEST_SIZE_R_2
104 INTEGER, DIMENSION(NSPMD) :: REQUEST_SIZE_S,REQUEST_SIZE_S_2
105#ifdef MPI
106 INTEGER, DIMENSION(MPI_STATUS_SIZE) :: STATUS_MPI
107 INTEGER, DIMENSION(MPI_STATUS_SIZE,NSPMD) :: ARRAY_STATUSES
108#endif
109 DATA msgoff1/13014/
110 DATA msgoff2/13015/
111
112 first = 1
113 last = surfarce_nb
114 number_inter = shift_interface(ninter+1,2)
115
116 ALLOCATE( s_buffer(nspmd), r_buffer(nspmd) )
117 s_buffer(1:nspmd)%SIZE_INT_ARRAY_2D(1) = 2
118 s_buffer(1:nspmd)%SIZE_INT_ARRAY_2D(2) = surfarce_nb
119 number_remote_surf(1:nspmd) = 0
120
121
122
123 DO i=first,last
124 k = surface_id(i)
126 nin = shift_interface(id_inter,2)
127 k = k - shift_interface(id_inter,1) + 1
128 ity = ipari(7,nin)
129 idel = ipari(17,nin)
130 nrtm = ipari(4,nin)
131
132
133
134
135
136
137
138
139
140
141
142 IF(ity==25) THEN
143 global_surface_id = k
144 ELSEIF(ity==24) THEN
145 global_surface_id = intbuf_tab(nin)%MSEGLO(k)
146 ENDIF
147
148
149
150 if(ity==24) then
151 call surface_deactivation(ity,nrtm,global_surface_id,intbuf_tab(nin)%mseglo,intbuf_tab(nin)%mvoisin)
152 elseif(ity==25) then
153 call remove_neighbour_segment( nin,global_surface_id,intbuf_tab(nin),shoot_struct )
154 endif
155
156
157 IF(nspmd>1) THEN
158
159 already_done(1:nspmd) = .false.
160 already_done(ispmd+1) = .true.
161 DO j=1,4
162 node_id = intbuf_tab(nin)%IRECTM((k-1)*4+j)
163 nb_proc = shoot_struct%SHIFT_M_NODE_PROC(node_id+1) - shoot_struct%SHIFT_M_NODE_PROC(node_id)
164 IF(nb_proc>1) THEN
165 shift = shoot_struct%SHIFT_M_NODE_PROC(node_id)
166 DO ijk=1,nb_proc
167 remote_proc = shoot_struct%M_NODE_PROC( shift+ijk )
168 IF(.NOT.already_done(remote_proc) ) THEN
169 already_done(remote_proc) = .true.
170 number_remote_surf(remote_proc) = number_remote_surf(remote_proc) + 1
171 IF(.NOT.ALLOCATED( s_buffer(remote_proc)%INT_ARRAY_2D ) ) THEN
173 ENDIF
174 IF(ity==24) THEN
175 s_buffer(remote_proc)%INT_ARRAY_2D(1,number_remote_surf(remote_proc)) = intbuf_tab(nin)%MSEGLO(k)
176 ELSEIF(ity==25) THEN
177 s_buffer(remote_proc)%INT_ARRAY_2D(1,number_remote_surf(remote_proc)) = -intbuf_tab(nin)%MSEGLO(k)
178 ENDIF
179 s_buffer(remote_proc)%INT_ARRAY_2D(2,number_remote_surf(remote_proc)) = nin
180 ENDIF
181 ENDDO
182 ENDIF
183 ENDDO
184
185 ENDIF
186 ENDDO
187
188
189 IF(nspmd>1) THEN
190#ifdef MPI
191
192
193
194 recv_nb = 0
195 DO i=1,nspmd
196 frontier_elm = iad_elem(1,i+1)-iad_elem(1,i)
197 IF(frontier_elm>0) THEN
198 recv_nb = recv_nb + 1
199 index_r_proc(recv_nb) = i
200
201 CALL mpi_irecv( number_remote_surf_r(i),1,mpi_integer,it_spmd(i),msgtyp,
202 . spmd_comm_world,request_size_r(recv_nb),ierror )
203 ENDIF
204 ENDDO
205
206
207
208
209 DO i=1,nspmd
210 frontier_elm = iad_elem(1,i+1)-iad_elem(1,i)
211 IF(frontier_elm>0) THEN
212 msgtyp = msgoff1
213 CALL mpi_isend( number_remote_surf(i),1,mpi_integer,it_spmd(i),msgtyp,
214 . spmd_comm_world,request_size_s(i),ierror )
215 ENDIF
216 ENDDO
217
218
219
220
221 IF(recv_nb>0)
CALL mpi_waitall(recv_nb,request_size_r,array_statuses,ierror)
222
223
224
225 recv_nb_2 = 0
226 DO i=1,recv_nb
227 proc_id = index_r_proc(i)
228 IF(number_remote_surf_r(proc_id)>0) THEN
229 recv_nb_2 = recv_nb_2 + 1
230 index_r_proc_2(recv_nb_2) = proc_id
231 r_buffer(proc_id)%SIZE_INT_ARRAY_2D(1) = 2
232 r_buffer(proc_id)%SIZE_INT_ARRAY_2D(2) = number_remote_surf_r(proc_id)
234 size_r = r_buffer(proc_id)%SIZE_INT_ARRAY_2D(1) * r_buffer(proc_id)%SIZE_INT_ARRAY_2D(2)
235 msgtyp = msgoff2
236 CALL mpi_irecv(r_buffer(proc_id)%INT_ARRAY_2D(1,1),size_r,
237 . mpi_integer,it_spmd(proc_id),msgtyp,
238 . spmd_comm_world,request_size_r_2(recv_nb_2),ierror )
239 ENDIF
240 ENDDO
241
242
243
244
245 DO i=1,nspmd
246 IF(number_remote_surf(i)>0) THEN
247 msgtyp
248 size_s = number_remote_surf(i) * s_buffer(i)%SIZE_INT_ARRAY_2D(1)
249 CALL mpi_isend( s_buffer(i)%INT_ARRAY_2D(1,1),size_s,mpi_integer,it_spmd(i),msgtyp,
250 .
251 ENDIF
252 ENDDO
253
254
255
256 DO i=1,recv_nb_2
257 CALL mpi_waitany(recv_nb_2,request_size_r_2,k,status_mpi,ierror)
258 proc_id = index_r_proc_2(k)
259
260 DO j=1,number_remote_surf_r(proc_id)
261 nin = r_buffer(proc_id)%INT_ARRAY_2D(2,j)
262 ity = ipari(7,nin)
263 idel = ipari(17,nin)
264 nrtm = ipari(4,nin)
265
266
267
268 global_surface_id = r_buffer(proc_id)%INT_ARRAY_2D(1,j)
269 if(ity==24)then
270 call surface_deactivation(ity,nrtm,global_surface_id,intbuf_tab(nin)%mseglo,intbuf_tab(nin)%mvoisin)
271 elseif(ity==25) then
272 call remove_neighbour_segment( nin,global_surface_id,intbuf_tab(nin),shoot_struct )
273 endif
274
275 ENDDO
277
278 ENDDO
279
280
281
282
283 DO i=1,nspmd
284 frontier_elm = iad_elem(1,i+1)-iad_elem(1,i)
285 IF(frontier_elm>0) THEN
286 CALL mpi_wait(request_size_s(i),status_mpi,ierror)
287 ENDIF
288 ENDDO
289
290
291
292
293 DO i=1,nspmd
294 IF(number_remote_surf(i)>0) THEN
295 CALL mpi_wait(request_size_s_2(i),status_mpi,ierror)
297 ENDIF
298 ENDDO
299
300#endif
301 ENDIF
302
303 DEALLOCATE( s_buffer, r_buffer )
304
305
306 RETURN
integer function dichotomic_search_i_asc(val, array, len)
subroutine mpi_isend(buf, cnt, datatype, dest, tag, comm, ireq, ierr)
subroutine mpi_wait(ireq, status, ierr)
subroutine mpi_waitall(cnt, array_of_requests, status, ierr)
subroutine mpi_waitany(cnt, array_of_requests, index, status, ierr)
subroutine mpi_irecv(buf, cnt, datatype, source, tag, comm, ireq, ierr)
subroutine dealloc_2d_array(this)
subroutine alloc_2d_array(this)
subroutine surface_deactivation(ity, nrtm, glocal_surface_id, mseglo, mvoisin)