MFIX  2016-1
mpi_comm_des_mod.f
Go to the documentation of this file.
1 !------------------------------------------------------------------------
2 ! Module : desmpi
3 ! Purpose : Contains wrapper class for mpi communications- send,recv
4 !
5 ! Author : Pradeep.G
6 !
7 ! Purpose : Module contains subroutines and variables related to
8 ! des mpi communication.
9 !
10 ! Comments : do_nsearch flag should be set to true before calling
11 ! des_par_exchange; when do_nsearch is true ghost particles of the
12 ! system will be updated, which will be later used to generate
13 ! neighbour list.
14 
15 !------------------------------------------------------------------------
16  module mpi_comm_des
17 
18 !-----------------------------------------------
19 ! Modules
20 !-----------------------------------------------
21  use parallel_mpi
22  use mpi_utility
23  use discretelement
24  use desgrid
25  use compar
26  use physprop
27  use sendrecv
28  use des_bc
29  use desmpi_wrapper
30  use sendrecvnode
31  use mfix_pic
32  use des_thermo
33  use run, only: energy_eq,any_species_eq
34  use param, only: dimension_n_s
35  use des_rxns
36 
37  use desmpi
38 
39 !-----------------------------------------------
40 
41 ! generic interface definition
42  interface des_gather
43  module procedure des_gather_l,des_gather_i,des_gather_d
44  end interface
45 
46  contains
47 
48 !------------------------------------------------------------------------
49 ! Subroutine : desmpi_sendrecv_init
50 ! Purpose : posts asynchronous send and recv and updates the request id
51 !
52 ! Parameters : pface - face number (1to6)
53 ! debug - for printing debug statments
54 !------------------------------------------------------------------------
55  subroutine desmpi_sendrecv_init(pface,pdebug)
56 !-----------------------------------------------
57  implicit none
58 !-----------------------------------------------
59 ! dummy variables
60 !-----------------------------------------------
61  integer,intent(in) :: pface
62  integer,intent(in),optional :: pdebug
63 !-----------------------------------------------
64 ! local variables
65 !-----------------------------------------------
66  character(len=80), parameter :: name = 'desmpi_sendrecv_init'
67  integer :: ldebug,ltag,lerr,lrecvface
68 !-----------------------------------------------
69 
70 ! set the debug flag
71  ldebug = 0
72  if (present(pdebug)) then
73  ldebug = pdebug
74  endif
75 
76 
77 
78 !direct copy in case of single processor
79  lrecvface = pface+mod(pface,2)-mod(pface+1,2)
80 
81 
82 
83 
84  if (ineighproc(pface).eq.mype) then
85  drecvbuf(1+mod(lrecvface,2))%facebuf(1:isendcnt(pface)) = &
86  dsendbuf(1+mod(pface,2))%facebuf(1:isendcnt(pface))
87  else
88  ltag = message_tag(ineighproc(pface),mype,pface)
89  call des_mpi_irecv(drecvbuf(1+mod(pface,2))%facebuf(:),imaxbuf, &
90  ineighproc(pface),ltag,irecvreq(pface),lerr)
91  call mpi_check( name //':mpi_irecv ', lerr )
92 
93  ltag = message_tag(mype,ineighproc(pface),lrecvface)
94  call des_mpi_isend(dsendbuf(1+mod(pface,2))%facebuf(:),isendcnt(pface), &
95  ineighproc(pface),ltag,isendreq(pface),lerr)
96  call mpi_check( name //':mpi_isend ', lerr )
97 
98  end if
99  return
100 
101  contains
102 
103  integer function message_tag(lsource,ldest,lrecvface)
104  implicit none
105  integer, intent(in) :: lsource,ldest,lrecvface
106  message_tag = lsource+numpes*ldest+numpes*numpes*lrecvface+100
107  end function message_tag
108 
109  end subroutine desmpi_sendrecv_init
110 
111 !------------------------------------------------------------------------
112 ! Subroutine : desmpi_sendrecv_wait
113 ! Purpose : waits for the communication for the specified interface
114 !
115 ! Parameters : pface - face number (1to6)
116 ! debug - for printing debug statments
117 !------------------------------------------------------------------------
118  subroutine desmpi_sendrecv_wait(pface,pdebug)
119 !-----------------------------------------------
120  implicit none
121 !-----------------------------------------------
122 ! dummy variables
123 !-----------------------------------------------
124  integer,intent(in) :: pface
125  integer,intent(in),optional :: pdebug
126 !-----------------------------------------------
127 ! local variables
128 !-----------------------------------------------
129  character(len=80), parameter :: name = 'desmpi_sendrecv_wait'
130  integer :: ldebug,lerr
131 !-----------------------------------------------
132 
133 ! set the debug flag
134  ldebug = 0
135  if (present(pdebug)) then
136  ldebug = pdebug
137  endif
138 
139 ! wait for both send and recv request completes
140  if (ineighproc(pface).ne.mype) then
141  call des_mpi_wait(isendreq(pface),lerr)
142  call mpi_check( name //':mpi_wait-send', lerr )
143  call des_mpi_wait(irecvreq(pface),lerr)
144  call mpi_check( name //':mpi_wait-recv', lerr )
145  end if
146  return
147  end subroutine desmpi_sendrecv_wait
148 
149 
150 !------------------------------------------------------------------------
151 ! Subroutine : desmpi_scatterv
152 ! Purpose : scatters the particle from PE_IO
153 ! Parameters : ptype - flag for datatype integer (1) or double precision (2)
154 ! pdebug - optional flag for debugging
155 !------------------------------------------------------------------------
156  subroutine desmpi_scatterv(ptype,pdebug)
157 !-----------------------------------------------
158  implicit none
159 !-----------------------------------------------
160 ! dummy variables
161 !-----------------------------------------------
162  integer, intent(in) :: ptype
163  integer, intent(in),optional :: pdebug
164 !-----------------------------------------------
165 ! local variables
166 !-----------------------------------------------
167  integer lroot,lidebug,lerr
168  character(len=80), parameter :: name = 'desmpi_scatterv'
169 !-----------------------------------------------
170 
171  lroot = pe_io
172  if (.not. present(pdebug)) then
173  lidebug = 0
174  else
175  lidebug = pdebug
176  endif
177 
178  if (ptype .eq. 1) then
180  iprocbuf,iscr_recvcnt,lroot,lerr)
181  else
183  dprocbuf,iscr_recvcnt,lroot,lerr)
184  end if
185  call mpi_check( name //':MPI_Scatterv', lerr )
186 
187  return
188  end subroutine desmpi_scatterv
189 
190 
191 !------------------------------------------------------------------------
192 ! Subroutine : desmpi_gatherv
193 ! Purpose : gathers the particle from local proc to root proc
194 ! Parameters : ptype - flag for datatype integer (1) or double precision (2)
195 ! pdebug - optional flag for debugging
196 !------------------------------------------------------------------------
197  subroutine desmpi_gatherv(ptype,pdebug)
198 !-----------------------------------------------
199  implicit none
200 !-----------------------------------------------
201 ! dummy variables
202 !-----------------------------------------------
203  integer, intent(in) :: ptype
204  integer, intent(in),optional :: pdebug
205 !-----------------------------------------------
206 ! local variables
207 !-----------------------------------------------
208  integer lroot,lidebug,lerr
209  character(len=80), parameter :: name = 'des_gather'
210 !-----------------------------------------------
211 
212  lroot = pe_io
213  if (.not. present(pdebug)) then
214  lidebug = 0
215  else
216  lidebug = pdebug
217  endif
218  if(ptype.eq.1) then
220  igathercnts,idispls,lroot,lerr)
221  else
223  igathercnts,idispls,lroot,lerr)
224  end if
225  call mpi_check( name //':MPI_Gatherv', lerr )
226 
227  return
228  end subroutine desmpi_gatherv
229 
230 
231 !------------------------------------------------------------------------
232 ! Subroutine : des_gather_d
233 ! Purpose : gathers double precision array from local to root
234 ! Parameters :
235 ! parray - array to be writen
236 !------------------------------------------------------------------------
237  subroutine des_gather_d(parray)
238 !-----------------------------------------------
239  implicit none
240 !-----------------------------------------------
241 ! dummy variables
242 !-----------------------------------------------
243  double precision, dimension(:) :: parray
244 !-----------------------------------------------
245 ! local variables
246 !-----------------------------------------------
247  integer :: lcurpar,lparcount,lcount
248 !-----------------------------------------------
249 
250 ! pack the variables in case of
251  lparcount = 1
252  lcount = 0
253  do lcurpar = 1, max_pip
254  if (lparcount.gt.pip) exit
255  if (is_nonexistent(lcurpar)) cycle
256  lparcount = lparcount +1
257  if(is_ghost(lcurpar) .or. is_entering_ghost(lcurpar) .or. is_exiting_ghost(lcurpar)) cycle
258  lcount = lcount + 1
259  dprocbuf(lcount) = parray(lcurpar)
260  end do
261  call desmpi_gatherv(ptype=2)
262  end subroutine des_gather_d
263 
264 !------------------------------------------------------------------------
265 ! Subroutine : des_gather_l
266 ! Purpose : gathers logical array from local to root
267 ! Parameters :
268 ! parray - array to be writen
269 !------------------------------------------------------------------------
270  subroutine des_gather_l(parray)
271 !-----------------------------------------------
272  implicit none
273 !-----------------------------------------------
274 ! dummy variables
275 !-----------------------------------------------
276  logical, dimension(:) :: parray
277 !-----------------------------------------------
278 ! local variables
279 !-----------------------------------------------
280  integer :: lcurpar,lparcount,lcount
281 !-----------------------------------------------
282 
283 ! pack the variables in proc buffer
284  lparcount = 1
285  lcount = 0
286  do lcurpar = 1, max_pip
287  if (lparcount.gt.pip) exit
288  if (is_nonexistent(lcurpar)) cycle
289  lparcount = lparcount +1
290  if(is_ghost(lcurpar) .or. is_entering_ghost(lcurpar) .or. is_exiting_ghost(lcurpar)) cycle
291  lcount = lcount + 1
292  if(parray(lcurpar)) then
293  iprocbuf(lcount) = 1
294  else
295  iprocbuf(lcount) = 0
296  end if
297  end do
298  call desmpi_gatherv(ptype=1)
299 
300  end subroutine des_gather_l
301 
302 !------------------------------------------------------------------------
303 ! Subroutine : des_gather_i
304 ! Purpose : gathers integer array from local to root
305 ! Parameters :
306 ! parray - array to be writen
307 ! ploc2glb - this flag is used to conver local particle
308 ! number into global particle number (used for history
309 ! and neighbour terms)
310 !------------------------------------------------------------------------
311  subroutine des_gather_i(parray,ploc2glb)
312 !-----------------------------------------------
313  implicit none
314 !-----------------------------------------------
315 ! dummy variables
316 !-----------------------------------------------
317  integer, dimension(:) :: parray
318  logical,optional :: ploc2glb
319 !-----------------------------------------------
320 ! local variables
321 !-----------------------------------------------
322  integer :: lcurpar,lparcount,lcount
323  logical :: lloc2glb
324 !-----------------------------------------------
325 
326  if (present(ploc2glb)) then
327  lloc2glb = ploc2glb
328  else
329  lloc2glb = .false.
330  end if
331 ! pack the variables in proc buffer
332  lparcount = 1
333  lcount = 0
334  if (lloc2glb) then
335  do lcurpar = 1, max_pip
336  if (lparcount.gt.pip) exit
337  if (is_nonexistent(lcurpar)) cycle
338  lparcount = lparcount +1
339  if(is_ghost(lcurpar) .or. is_entering_ghost(lcurpar) .or. is_exiting_ghost(lcurpar)) cycle
340  lcount = lcount + 1
341  if(parray(lcurpar).gt.0) then
342  iprocbuf(lcount) = iglobal_id(parray(lcurpar))
343  else
344  iprocbuf(lcount) = 0
345  end if
346  end do
347  else
348  do lcurpar = 1, max_pip
349  if (lparcount.gt.pip) exit
350  if (is_nonexistent(lcurpar)) cycle
351  lparcount = lparcount +1
352  if(is_ghost(lcurpar) .or. is_entering_ghost(lcurpar) .or. is_exiting_ghost(lcurpar)) cycle
353  lcount = lcount + 1
354  iprocbuf(lcount) = parray(lcurpar)
355  end do
356  end if
357  call desmpi_gatherv(ptype=1)
358 
359  end subroutine des_gather_i
360 
361  end module mpi_comm_des
subroutine desmpi_scatterv(ptype, pdebug)
integer, dimension(:), allocatable igathercnts
Definition: desmpi_mod.f:48
subroutine des_gather_i(parray, ploc2glb)
subroutine desmpi_sendrecv_init(pface, pdebug)
double precision, dimension(:), allocatable dprocbuf
Definition: desmpi_mod.f:42
subroutine desmpi_sendrecv_wait(pface, pdebug)
subroutine des_mpi_wait(preq, perr)
subroutine desmpi_gatherv(ptype, pdebug)
subroutine des_gather_d(parray)
integer, dimension(:), allocatable irootbuf
Definition: desmpi_mod.f:43
type(array), dimension(:), allocatable dsendbuf
Definition: desmpi_mod.f:27
integer numpes
Definition: compar_mod.f:24
integer, dimension(:), allocatable isendreq
Definition: desmpi_mod.f:31
integer pe_io
Definition: compar_mod.f:30
type(array), dimension(:), allocatable drecvbuf
Definition: desmpi_mod.f:28
integer, dimension(:), allocatable iprocbuf
Definition: desmpi_mod.f:44
integer function message_tag(lsource, ldest, lrecvface)
logical any_species_eq
Definition: run_mod.f:118
Definition: run_mod.f:13
Definition: param_mod.f:2
subroutine mpi_check(msg, ierr)
integer imaxbuf
Definition: desmpi_mod.f:37
integer mype
Definition: compar_mod.f:24
logical energy_eq
Definition: run_mod.f:100
integer, dimension(:), allocatable idispls
Definition: desmpi_mod.f:46
integer igath_sendcnt
Definition: desmpi_mod.f:51
integer, dimension(:), allocatable ineighproc
Definition: desmpi_mod.f:16
integer iscr_recvcnt
Definition: desmpi_mod.f:50
integer, dimension(:), allocatable isendcnt
Definition: desmpi_mod.f:30
double precision, dimension(:), allocatable drootbuf
Definition: desmpi_mod.f:41
integer dimension_n_s
Definition: param_mod.f:21
integer, dimension(:), allocatable irecvreq
Definition: desmpi_mod.f:32
integer, dimension(:), allocatable iscattercnts
Definition: desmpi_mod.f:47
subroutine des_gather_l(parray)