Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
InitComm.f90
Go to the documentation of this file.
1 !*********************************************************************
2 !* Illinois Open Source License *
3 !* *
4 !* University of Illinois/NCSA *
5 !* Open Source License *
6 !* *
7 !* Copyright@2008, University of Illinois. All rights reserved. *
8 !* *
9 !* Developed by: *
10 !* *
11 !* Center for Simulation of Advanced Rockets *
12 !* *
13 !* University of Illinois *
14 !* *
15 !* www.csar.uiuc.edu *
16 !* *
17 !* Permission is hereby granted, free of charge, to any person *
18 !* obtaining a copy of this software and associated documentation *
19 !* files (the "Software"), to deal with the Software without *
20 !* restriction, including without limitation the rights to use, *
21 !* copy, modify, merge, publish, distribute, sublicense, and/or *
22 !* sell copies of the Software, and to permit persons to whom the *
23 !* Software is furnished to do so, subject to the following *
24 !* conditions: *
25 !* *
26 !* *
27 !* @ Redistributions of source code must retain the above copyright *
28 !* notice, this list of conditions and the following disclaimers. *
29 !* *
30 !* @ Redistributions in binary form must reproduce the above *
31 !* copyright notice, this list of conditions and the following *
32 !* disclaimers in the documentation and/or other materials *
33 !* provided with the distribution. *
34 !* *
35 !* @ Neither the names of the Center for Simulation of Advanced *
36 !* Rockets, the University of Illinois, nor the names of its *
37 !* contributors may be used to endorse or promote products derived *
38 !* from this Software without specific prior written permission. *
39 !* *
40 !* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, *
41 !* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES *
42 !* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND *
43 !* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR *
44 !* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
45 !* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
46 !* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
47 !* USE OR OTHER DEALINGS WITH THE SOFTWARE. *
48 !*********************************************************************
49 !* Please acknowledge The University of Illinois Center for *
50 !* Simulation of Advanced Rockets in works and publications *
51 !* resulting from this software or its derivatives. *
52 !*********************************************************************
53 
54 !!****
55 !!
56 !! NAME
57 !! InitComm1
58 !!
59 !! FUNCTION
60 !! Initializes global communication variables for communicating
61 !! boundary data from this proc to other procs
62 !!
63 !! INPUTS
64 !! none
65 !!
66 !! OUTPUTS
67 !! none
68 !!
69 !! USES
70 !! MPI
71 !!
72 !!****
73 
74 SUBROUTINE initcomm1(global)
75 
76  USE precision
77  USE implicit_global
79 
80  IMPLICIT NONE
81 
82  include 'mpif.h'
83 
84  TYPE(rocfrac_global) :: global
85  INTEGER :: i, j, counter ! counters
86  INTEGER :: tempnodes
87  INTEGER, ALLOCATABLE, DIMENSION(:) :: numcommnodesfromall ! Number of nodes to be recieved from all processors
88 
89 
90 
91 !
92 ! Determine communications to be sent to other procs
93 !
94 
95 
96  ! Count the processors to be communicated with
97  numcommprocs1 = 0
98  DO i = 0, nprocs
99  IF (i /= myid) THEN
100  counter = 0
101  DO j = 1, global%NumNp
102  IF (nodeproc(j) == i) THEN
103  counter = 1
104  EXIT
105  ENDIF
106  ENDDO
107  IF (counter == 1) THEN ! New proc found
108  numcommprocs1 = numcommprocs1 + 1
109  ENDIF
110  ENDIF
111  ENDDO
112 
113  ! Number the processors to be communicated with
114  ALLOCATE(commprocs1(1:numcommprocs1))
115  counter = 0
116  DO i = 0, nprocs
117  IF (i /= myid) THEN
118  DO j = 1, global%NumNp
119  IF (nodeproc(j) == i) THEN
120  counter = counter + 1
121  commprocs1(counter) = i
122  EXIT
123  ENDIF
124  ENDDO
125  ENDIF
126  ENDDO
127 
128  ! Count the nodes to be sent to each processor
129  ALLOCATE(numcommnodes1(1:numcommprocs1))
130  DO i = 1, numcommprocs1
131  numcommnodes1(i) = 0
132  DO j = 1, global%NumNp
133  IF (nodeproc(j) == commprocs1(i)) THEN
134  numcommnodes1(i) = numcommnodes1(i) + 1
135  ENDIF
136  ENDDO
137  ENDDO
138 
139  ! Number the nodes to be sent to each processor
140  maxnumcommnodes1 = maxval(numcommnodes1)
141  ALLOCATE(commnodes1(1:numcommprocs1,1:maxnumcommnodes1))
142  DO i = 1, numcommprocs1
143  commnodes1(i,1:maxnumcommnodes1) = -1 ! Flag everything as unused
144  counter = 0
145  DO j = 1, global%NumNp
146  IF (nodeproc(j) == commprocs1(i)) THEN
147  counter = counter + 1
148  commnodes1(i,counter) = j
149  ENDIF
150  ENDDO
151  ENDDO
152 
153 
154 !
155 ! Communicate how many nodes will be sent to each processor
156 !
157 
158  ! Allocate MPI arrays
159  ALLOCATE(frmproc(0:nprocs-1))
160  ALLOCATE(req_rcv(1:nprocs))
161  ALLOCATE(stat_rcv(1:mpi_status_size,1:nprocs))
162  ALLOCATE(req_snd(1:nprocs))
163  ALLOCATE(stat_snd(1:mpi_status_size,1:nprocs))
164  DO i = 1, nprocs
165  req_rcv(i) = 0
166  req_snd(i) = 0
167  DO j = 1, mpi_status_size
168  stat_rcv(1,i) = 0
169  stat_snd(j,i) = 0
170  ENDDO
171  ENDDO
172 
173  ! Perform the communication
174  ALLOCATE(numcommnodesfromall(0:nprocs-1))
175  DO i = 0, nprocs-1
176  CALL mpi_irecv(numcommnodesfromall(i),1, &
177  mpi_integer,i,10,rocstar_communicator, &
178  req_rcv(i+1),ierr)
179  ENDDO
180  DO i = 0, nprocs-1
181  tempnodes = 0
182  DO j = 1, numcommprocs1
183  IF (commprocs1(j) == i) THEN
184  tempnodes = numcommnodes1(j)
185  ENDIF
186  ENDDO
187  CALL mpi_isend(tempnodes,1,mpi_integer, &
188  i,10,rocstar_communicator,req_snd(i+1),ierr)
189  ENDDO
190  CALL mpi_waitall(nprocs,req_rcv,stat_rcv,ierr)
191  CALL mpi_waitall(nprocs,req_snd,stat_snd,ierr)
192 
193  ! Deallocate MPI arrays
194  DEALLOCATE(frmproc)
195  DEALLOCATE(req_rcv)
196  DEALLOCATE(stat_rcv)
197  DEALLOCATE(req_snd)
198  DEALLOCATE(stat_snd)
199 
200  ! Count the number of procs that will send me data
201  numcommprocsfrom1 = 0
202  DO i = 0, nprocs-1
203  IF (numcommnodesfromall(i) > 0) THEN
204  numcommprocsfrom1 = numcommprocsfrom1 + 1
205  ENDIF
206  ENDDO
207 
208  ! Number the procs that will send me data
209  ALLOCATE(commprocsfrom1(1:numcommprocsfrom1))
210  ALLOCATE(numcommnodesfrom1(1:numcommprocsfrom1))
211  counter = 0
212  DO i = 0, nprocs-1
213  IF (numcommnodesfromall(i) > 0) THEN
214  counter = counter + 1
215  commprocsfrom1(counter) = i
216  numcommnodesfrom1(counter) = numcommnodesfromall(i)
217  ENDIF
218  ENDDO
219 
220 
221  ! Deallocate stuff
222  DEALLOCATE(numcommnodesfromall)
223 
224 
225 
226 END SUBROUTINE initcomm1
227 
228 
229 
230 
231 
232 
233 
234 
235 
236 
237 
238 
239 
240 
241 
242 
243 
244 
245 !!****
246 !!
247 !! NAME
248 !! InitComm2
249 !!
250 !! FUNCTION
251 !! Initializes global communication variables for communicating
252 !! boundary data from other procs to this proc
253 !!
254 !! INPUTS
255 !! none
256 !!
257 !! OUTPUTS
258 !! none
259 !!
260 !! USES
261 !! MPI
262 !!
263 !!****
264 
265 SUBROUTINE initcomm2(global)
266 
267  USE precision
268  USE implicit_global
269 
270  IMPLICIT NONE
271 
272  include 'mpif.h'
273 
274  TYPE(rocfrac_global) :: global
275  INTEGER :: i, j, counter ! counters
276  INTEGER :: tempnodes
277  INTEGER, ALLOCATABLE, DIMENSION(:) :: numcommnodesfromall ! Number of nodes to be recieved from all processors
278  INTEGER, ALLOCATABLE, DIMENSION(:,:) :: commnodesfrom2
279  REAL(kind=wp), ALLOCATABLE, DIMENSION(:) :: bufsnd ! MPI send buffer
280 
281 
282 !
283 ! Determine communications to be sent to other procs
284 !
285 
286 
287  ! Count the processors that will send me data
288  numcommprocsfrom2 = 0
289  DO i = 0, nprocs
290  IF (i /= myid) THEN
291  counter = 0
292  DO j = 1, global%NumNp
293  IF (nodeproc(j) == i) THEN
294  counter = 1
295  EXIT
296  ENDIF
297  ENDDO
298  IF (counter == 1) THEN ! New proc found
299  numcommprocsfrom2 = numcommprocsfrom2 + 1
300  ENDIF
301  ENDIF
302  ENDDO
303 
304  ! Number the processors that will send me data
305  ALLOCATE(commprocsfrom2(1:numcommprocsfrom2))
306  counter = 0
307  DO i = 0, nprocs
308  IF (i /= myid) THEN
309  DO j = 1, global%NumNp
310  IF (nodeproc(j) == i) THEN
311  counter = counter + 1
312  commprocsfrom2(counter) = i
313  EXIT
314  ENDIF
315  ENDDO
316  ENDIF
317  ENDDO
318 
319  ! Count the nodes to be received from each processor
320  ALLOCATE(numcommnodesfrom2(1:numcommprocsfrom2))
321  DO i = 1, numcommprocsfrom2
322  numcommnodesfrom2(i) = 0
323  DO j = 1, global%NumNp
324  IF (nodeproc(j) == commprocsfrom2(i)) THEN
325  numcommnodesfrom2(i) = numcommnodesfrom2(i) + 1
326  ENDIF
327  ENDDO
328  ENDDO
329 
330 
331 !
332 ! Communicate how many nodes are needed to each processor
333 !
334 
335  ! Allocate MPI arrays
336  ALLOCATE(frmproc(0:nprocs-1))
337  ALLOCATE(req_rcv(1:nprocs))
338  ALLOCATE(stat_rcv(1:mpi_status_size,1:nprocs))
339  ALLOCATE(req_snd(1:nprocs))
340  ALLOCATE(stat_snd(1:mpi_status_size,1:nprocs))
341  DO i = 1, nprocs
342  req_rcv(i) = 0
343  req_snd(i) = 0
344  DO j = 1, mpi_status_size
345  stat_rcv(1,i) = 0
346  stat_snd(j,i) = 0
347  ENDDO
348  ENDDO
349 
350  ! Perform the communication
351  ALLOCATE(numcommnodesfromall(0:nprocs-1))
352  DO i = 0, nprocs-1
353  CALL mpi_irecv(numcommnodesfromall(i),1, &
354  mpi_integer,i,10,rocstar_communicator, &
355  req_rcv(i+1),ierr)
356  ENDDO
357  DO i = 0, nprocs-1
358  tempnodes = 0
359  DO j = 1, numcommprocsfrom2
360  IF (commprocsfrom2(j) == i) THEN
361  tempnodes = numcommnodesfrom2(j)
362  ENDIF
363  ENDDO
364  CALL mpi_isend(tempnodes,1,mpi_integer, &
365  i,10,rocstar_communicator,req_snd(i+1),ierr)
366  ENDDO
367  CALL mpi_waitall(nprocs,req_rcv,stat_rcv,ierr)
368  CALL mpi_waitall(nprocs,req_snd,stat_snd,ierr)
369 
370  ! Deallocate MPI arrays
371  DEALLOCATE(frmproc)
372  DEALLOCATE(req_rcv)
373  DEALLOCATE(stat_rcv)
374  DEALLOCATE(req_snd)
375  DEALLOCATE(stat_snd)
376 
377  ! Count the number of procs that I will send data to
378  numcommprocs2 = 0
379  DO i = 0, nprocs-1
380  IF (numcommnodesfromall(i) > 0) THEN
381  numcommprocs2 = numcommprocs2 + 1
382  ENDIF
383  ENDDO
384 
385  ! Number the procs that I will send data to
386  ALLOCATE(commprocs2(1:numcommprocs2))
387  ALLOCATE(numcommnodes2(1:numcommprocs2))
388  counter = 0
389  DO i = 0, nprocs-1
390  IF (numcommnodesfromall(i) > 0) THEN
391  counter = counter + 1
392  commprocs2(counter) = i
393  numcommnodes2(counter) = numcommnodesfromall(i)
394  ENDIF
395  ENDDO
396 
397 
398  ! Deallocate stuff
399  DEALLOCATE(numcommnodesfromall)
400 
401  ! Number the nodes to be received from each processor
402  maxnumcommnodes2 = maxval(numcommnodesfrom2)
403  ALLOCATE(commnodesfrom2(1:numcommprocsfrom2,1:maxnumcommnodes2))
404  DO i = 1, numcommprocsfrom2
405  commnodesfrom2(i,1:maxnumcommnodes2) = -1 ! Flag everything as unused
406  counter = 0
407  DO j = 1, global%NumNp
408  IF (nodeproc(j) == commprocsfrom2(i)) THEN
409  counter = counter + 1
410  commnodesfrom2(i,counter) = j
411  ENDIF
412  ENDDO
413  ENDDO
414 
415  !DO i = 1, NumCommProcs
416  ! print*,myid,' has to receive info about ',NumCommNodesFrom(i),' nodes from proc ',CommProcsFrom(i)
417  ! print*,myid,' CommNodesFrom(i,:) = ',Local2Global(CommNodesFrom(i,:))
418  !ENDDO
419 
420 
421 !
422 ! Communicate which nodes are needed to each processor
423 !
424 
425  ! Allocate MPI arrays
426  !ALLOCATE(req_rcv(1:NumCommProcs2))
427  !ALLOCATE(req_snd(1:NumCommProcsFrom2))
428  !ALLOCATE(stat_snd(1:MPI_STATUS_SIZE,1:NumCommProcsFrom2))
429  !ALLOCATE(stat_rcv(1:MPI_STATUS_SIZE,1:NumCommProcs2))
430  ALLOCATE(req_rcv(1:nprocs))
431  ALLOCATE(req_snd(1:nprocs))
432  ALLOCATE(stat_snd(1:mpi_status_size,1:nprocs))
433  ALLOCATE(stat_rcv(1:mpi_status_size,1:nprocs))
434  DO i = 1, nprocs
435  req_rcv(i) = 0
436  req_snd(i) = 0
437  DO j = 1, mpi_status_size
438  stat_rcv(1,i) = 0
439  stat_snd(j,i) = 0
440  ENDDO
441  ENDDO
442 
443  ! Perform the communication
444  ALLOCATE(frmproc(1:numcommprocs2))
445  DO i = 1, numcommprocs2
446  ALLOCATE(frmproc(i)%rcvbuf(1:numcommnodes2(i)))
447  CALL mpi_irecv(frmproc(i)%rcvbuf(1),numcommnodes2(i), &
448  mpi_double_precision,commprocs2(i),10,rocstar_communicator, &
449  req_rcv(i+1),ierr)
450  ENDDO
451  DO i = 1, numcommprocsfrom2
452  ALLOCATE(bufsnd(1:numcommnodesfrom2(i)))
453  DO j = 1, numcommnodesfrom2(i)
454  bufsnd(j) = local2global(commnodesfrom2(i,j))
455  ENDDO
456  !print*,myid,' bufsnd = ',bufsnd(:)
457  CALL mpi_isend(bufsnd,numcommnodesfrom2(i),mpi_double_precision, &
458  commprocsfrom2(i),10,rocstar_communicator,req_snd(i+1),ierr)
459  DEALLOCATE(bufsnd)
460  ENDDO
461  !CALL MPI_WAITALL(NumCommProcs2,req_rcv,stat_rcv,ierr)
462  !CALL MPI_WAITALL(NumCommProcsFrom2,req_snd,stat_snd,ierr)
463  CALL mpi_waitall(nprocs,req_rcv,stat_rcv,ierr)
464  CALL mpi_waitall(nprocs,req_snd,stat_snd,ierr)
465 
466  ! Deallocate MPI arrays
467  DEALLOCATE(req_rcv)
468  DEALLOCATE(stat_rcv)
469  DEALLOCATE(req_snd)
470  DEALLOCATE(stat_snd)
471 
472  !DO i = 1, NumCommProcs
473  ! DO j = 1, NumCommNodes(i)
474  ! print*,myid,' has to send info about global node ',frmproc(i)%rcvbuf(j),' to proc ',CommProcs(i)
475  ! ENDDO
476  !ENDDO
477 
478  ! Number the nodes to be sent to each processor
479  maxnumcommnodes2 = maxval(numcommnodes2)
480  ALLOCATE(commnodes2(1:numcommprocs2,1:maxnumcommnodes2))
481  DO i = 1, numcommprocs2
482  commnodes2(i,1:maxnumcommnodes2) = -1 ! Flag everything as unused
483  DO j = 1, numcommnodes2(i)
484  commnodes2(i,j) = int(frmproc(i)%rcvbuf(j))
485  ENDDO
486  ENDDO
487 
488  ! Deallocate stuff
489  DEALLOCATE(frmproc)
490  DEALLOCATE(commnodesfrom2)
491 
492 
493 
494 END SUBROUTINE initcomm2
495 
subroutine initcomm1(global)
Definition: InitComm.f90:74
subroutine initcomm2(global)
Definition: InitComm.f90:265
blockLoc i
Definition: read.cpp:79
j indices j
Definition: Indexing.h:6