42
43
44
45
46
47
48
49
50
51 USE nodal_arrays_mod
53 USE shooting_node_mod
54 USE intbufdef_mod
55 use element_mod , only : nixs,nixc,nixt,nixp,nixr,nixtg
56
57
58
59 USE spmd_comm_world_mod, ONLY : spmd_comm_world
60#include "implicit_f.inc"
61
62
63
64#include "spmd.inc"
65
66
67
68#include "com01_c.inc"
69#include "task_c.inc"
70#include "com04_c.inc"
71#include "scr17_c.inc"
72#include "param_c.inc"
73
74
75
76 INTEGER, DIMENSION(2,NSPMD+1), INTENT(in) :: IAD_ELEM
77 TYPE(nodal_arrays_), INTENT(INOUT) :: NODES
78 TYPE(shooting_node_type), INTENT(inout) :: SHOOT_STRUCT
79 TYPE(INTBUF_STRUCT_), DIMENSION(NINTER), INTENT(inout) :: INTBUF_TAB
80 INTEGER, DIMENSION(NINTER), INTENT(inout) :: NEWFRONT
81 INTEGER, DIMENSION(NIXS,NUMELS),TARGET, INTENT(in) :: IXS
82 INTEGER, DIMENSION(NIXC,NUMELC),TARGET, INTENT(in) :: IXC
83 INTEGER, DIMENSION(NIXT,NUMELT),TARGET, INTENT(in) :: IXT
84 INTEGER, DIMENSION(NIXP,NUMELP),TARGET, INTENT(in) :: IXP
85 INTEGER, DIMENSION(NIXR,NUMELR),TARGET, INTENT(in) :: IXR
86 INTEGER, DIMENSION(NIXTG,NUMELTG),TARGET, INTENT(in) :: IXTG
87 INTEGER, DIMENSION(6,NUMELS10), INTENT(in) :: IXS10
88 INTEGER, DIMENSION(0:NUMNOD+1), INTENT(in) :: ADDCNEL
89 INTEGER, DIMENSION(NPARI,NINTER), INTENT(in) :: IPARI
90 my_real,
DIMENSION(NPROPG,NUMGEO),
INTENT(in) :: geo
91 INTEGER, DIMENSION(0:LCNEL), INTENT(in) :: CNEL
92 INTEGER, DIMENSION(NUMNOD), INTENT(inout) :: TAG_NODE
93 INTEGER, DIMENSION(NUMELS+NUMELQ+NUMELC+NUMELT+NUMELP+NUMELR+NUMELTG), INTENT(inout) :: TAG_ELEM
94#ifdef MPI
95
96
97
98 INTEGER :: I,J,K
99 INTEGER :: MSGTYP,MSGOFF1,MSGOFF2
100 INTEGER :: PROC_ID,SIZE_BUFFER_R
101 INTEGER :: RECV_NB,RECV_SURF_NB
102 INTEGER, DIMENSION(2,NSPMD) :: SURF_PER_PROC,REMOTE_SURF_PER_PROC,REMOTE_SURF_PER_PROC_2
103 INTEGER, DIMENSION(NSPMD) :: INDEX_PROC,INDEX_BUFFER_R,INDEX_R_PROC,INDEX_R_PROC_2,INDEX_BUFFER_R_2
104 INTEGER, DIMENSION(NSPMD) :: REQUEST_SIZE_R,REQUEST_SIZE_S
105 INTEGER, DIMENSION(NSPMD) :: REQUEST_SURF_R,REQUEST_SURF_S
106
107 INTEGER, DIMENSION(MPI_STATUS_SIZE) :: STATUS_MPI
108 INTEGER, DIMENSION(MPI_STATUS_SIZE,NSPMD) :: ARRAY_STATUSES
109 INTEGER :: IERROR,FRONTIER_ELM,NB_SURFACE,ADDRESS,NB_EDGE
110
111 INTEGER, DIMENSION(:), ALLOCATABLE :: BUFFER_R
112 TYPE(array_type), DIMENSION(NSPMD) :: BUFFER_S
113
114 DATA msgoff1/13010/
115 DATA msgoff2/13011/
116
117
118
119 surf_per_proc(1:2,1:nspmd) = 0
120 remote_surf_per_proc(1:2,1:nspmd) = 0
121
122
123
124 DO i=1,shoot_struct%SAVE_PROC_NB,5
125 proc_id = shoot_struct%SAVE_PROC(i)
126 surf_per_proc(1,proc_id) = surf_per_proc(1,proc_id) + 1
127 ENDDO
128
129
130 DO i=1,shoot_struct%SAVE_PROC_NB_EDGE,3
131 proc_id = shoot_struct%SAVE_PROC_EDGE(i)
132 surf_per_proc(2,proc_id) = surf_per_proc(2,proc_id) + 1
133 ENDDO
134
135
136 index_proc(1:nspmd) = 0
137 DO i=1,nspmd
138 buffer_s(i)%SIZE_INT_ARRAY_1D = 4*surf_per_proc(1,i) +
139 . 2 * surf_per_proc(2,i)
141 ENDDO
142
143
144
145 DO i=1,shoot_struct%SAVE_PROC_NB,5
146 proc_id = shoot_struct%SAVE_PROC(i)
147 DO j=1,4
148 index_proc(proc_id) = index_proc(proc_id) + 1
149 buffer_s(proc_id)%INT_ARRAY_1D( index_proc(proc_id) ) = shoot_struct%SAVE_PROC(i+j)
150 ENDDO
151 ENDDO
152
153
154 DO i=1,shoot_struct%SAVE_PROC_NB_EDGE,3
155 proc_id = shoot_struct%SAVE_PROC_EDGE(i)
156 DO j=1,2
157 index_proc(proc_id) = index_proc(proc_id) + 1
158 buffer_s(proc_id)%INT_ARRAY_1D( index_proc(proc_id) ) = shoot_struct%SAVE_PROC_EDGE(i
159 ENDDO
160 ENDDO
161
162
163
164
165 recv_nb = 0
166 DO i=1,nspmd
167 frontier_elm = iad_elem(1,i+1)-iad_elem(1,i)
168 IF(frontier_elm>0) THEN
169 recv_nb = recv_nb + 1
170 index_r_proc(recv_nb) = i
171 msgtyp = msgoff1
172 CALL mpi_irecv( remote_surf_per_proc(1,recv_nb),2,mpi_integer,it_spmd(i),msgtyp,
173 . spmd_comm_world,request_size_r(recv_nb),ierror )
174 ENDIF
175 ENDDO
176
177
178
179
180 DO i=1,nspmd
181 frontier_elm = iad_elem(1,i+1)-iad_elem(1,i)
182 IF(frontier_elm>0) THEN
183 msgtyp = msgoff1
184 CALL mpi_isend( surf_per_proc(1,i),2,mpi_integer,it_spmd(i),msgtyp,
185 . spmd_comm_world,request_size_s(i),ierror )
186 ENDIF
187 ENDDO
188
189
190
191
192 IF(recv_nb>0)
CALL mpi_waitall(recv_nb,request_size_r,array_statuses,ierror)
193
194 size_buffer_r = 0
195 index_buffer_r(1:nspmd) = 0
196 index_buffer_r(1) = 1
197 DO i=1,recv_nb
198 IF(i>1) index_buffer_r(i) = index_buffer_r(i-1) + 4*remote_surf_per_proc(1,i-1) +
199 . 2 * remote_surf_per_proc(2,i-1)
200 size_buffer_r = size_buffer_r + 4*remote_surf_per_proc(1,i) + 2*remote_surf_per_proc(2,i)
201 ENDDO
202 ALLOCATE( buffer_r( size_buffer_r ) )
203
204
205
206
207 recv_surf_nb = 0
208 index_buffer_r_2(1:nspmd) = 0
209 remote_surf_per_proc_2(1:2,1:nspmd) = 0
210 index_r_proc_2(1:nspmd) = 0
211 DO i=1,recv_nb
212 IF(remote_surf_per_proc(1,i)+remote_surf_per_proc(2,i)>0) THEN
213 proc_id = index_r_proc(i)
214 msgtyp = msgoff2
215 recv_surf_nb = recv_surf_nb + 1
216 index_r_proc_2(recv_surf_nb) = index_r_proc(i)
217 index_buffer_r_2(recv_surf_nb) = index_buffer_r(i)
218 remote_surf_per_proc_2(1:2,recv_surf_nb) = remote_surf_per_proc(1:2,i)
219 CALL mpi_irecv( buffer_r(index_buffer_r(i)),4*remote_surf_per_proc(1,i)+2*remote_surf_per_proc(2,i),
220 . mpi_integer,it_spmd(proc_id),msgtyp,
221 . spmd_comm_world,request_surf_r(recv_surf_nb),ierror )
222 ENDIF
223 ENDDO
224
225
226
227
228
229 DO i=1,nspmd
230 IF(surf_per_proc(1,i)+surf_per_proc(2,i)>0) THEN
231 msgtyp = msgoff2
232 CALL mpi_isend( buffer_s(i)%INT_ARRAY_1D,index_proc(i),mpi_integer,it_spmd(i),msgtyp,
233 . spmd_comm_world,request_surf_s(i),ierror )
234 ENDIF
235 ENDDO
236
237
238
239 DO i=1,recv_surf_nb
240 CALL mpi_waitany(recv_surf_nb,request_surf_r,k,status_mpi,ierror)
241 proc_id = index_r_proc_2(k)
242 nb_surface = remote_surf_per_proc_2(1,k)
243 address = index_buffer_r_2(k)
244
246 . ipari,geo,
247 . ixs,ixc,ixt,ixp,ixr,ixtg,ixs10,
248 . addcnel,cnel,tag_node,tag_elem )
249 nb_edge = remote_surf_per_proc_2(2,k)
250 address = index_buffer_r_2(k)+4*nb_surface
252 . newfront,ipari,geo,
253 . ixs,ixc,ixt,ixp,ixr,ixtg,ixs10,
254 . addcnel,cnel,tag_node,tag_elem )
255 ENDDO
256
257
258
259 DO i=1,nspmd
260 frontier_elm = iad_elem(1,i+1)-iad_elem(1,i)
261 IF(frontier_elm>0) THEN
262 CALL mpi_wait(request_size_s(i),status_mpi,ierror)
263 ENDIF
264 ENDDO
265
266 DO i=1,nspmd
267 IF(surf_per_proc(1,i)+surf_per_proc(2,i)>0) THEN
268 CALL mpi_wait(request_surf_s(i),status_mpi,ierror)
269 ENDIF
270 ENDDO
271
272
273
274 DO i=1,nspmd
276 ENDDO
277
278#endif
279 RETURN
subroutine find_edge_from_remote_proc(shoot_struct, nb_edge, list_node, intbuf_tab, nodes, newfront, ipari, geo, ixs, ixc, ixt, ixp, ixr, ixtg, ixs10, addcnel, cnel, tag_node, tag_elem)
subroutine find_surface_from_remote_proc(shoot_struct, nb_surface, list_node, intbuf_tab, nodes, ipari, geo, ixs, ixc, ixt, ixp, ixr, ixtg, ixs10, addcnel, cnel, tag_node, tag_elem)
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)