MFIX  2016-1
read_res1_des_mod.f
Go to the documentation of this file.
1  MODULE read_res1_des
2 
3  use cdist, only: bdist_io
4  use compar, only: pe_io
5  use compar, only: mype
6  use des_allocate
7  use desmpi
8  use error_manager
10  use mpi_comm_des, only: desmpi_scatterv
11 
12  IMPLICIT NONE
13 
14  PRIVATE
15 
16  PUBLIC :: init_read_res_des
17  PUBLIC :: finl_read_res_des
18 
19  PUBLIC :: read_par_pos
20  PUBLIC :: read_par_col
21 
22  PUBLIC :: read_res_des
23  PUBLIC :: read_res_parray
24  PUBLIC :: read_res_carray
25 
26  INTERFACE read_res_des
27  MODULE PROCEDURE read_res_des_0i
28  MODULE PROCEDURE read_res_des_1i
29  MODULE PROCEDURE read_res_des_0d
30  MODULE PROCEDURE read_res_des_1d
31  MODULE PROCEDURE read_res_des_0l
32  MODULE PROCEDURE read_res_des_1l
33  END INTERFACE
34 
35  INTERFACE read_res_parray
36  MODULE PROCEDURE read_res_parray_1b
37  MODULE PROCEDURE read_res_parray_1i
38  MODULE PROCEDURE read_res_parray_1d
39  MODULE PROCEDURE read_res_parray_1l
40  END INTERFACE
41 
42  INTERFACE read_res_carray
43  MODULE PROCEDURE read_res_carray_1i
44  MODULE PROCEDURE read_res_carray_1d
45  MODULE PROCEDURE read_res_carray_1l
46  END INTERFACE
47 
48 
49  INTEGER, PARAMETER :: rdes_unit = 901
50 
51  INTEGER :: pin_count
52  INTEGER :: cin_count
53 
54 ! Send/Recv parameters for Particle arrays:
55  INTEGER :: prootcnt, pproccnt
56  INTEGER :: precv
57  INTEGER, allocatable :: pscatter(:)
58  INTEGER, allocatable :: pdispls(:)
59 
60 ! Variables used for reading restart file
61  INTEGER, ALLOCATABLE :: prestartmap(:)
62  INTEGER, ALLOCATABLE :: crestartmap(:)
63 
64 ! Send/Recv parameters for Particle arrays:
65  INTEGER :: crootcnt, cproccnt
66  INTEGER :: crecv
67  INTEGER, allocatable :: cscatter(:)
68  INTEGER, allocatable :: cdispls(:)
69 
70  INTEGER, ALLOCATABLE :: ipar_col(:,:)
71 
72  CONTAINS
73 
74 !``````````````````````````````````````````````````````````````````````!
75 ! Subroutine: INIT_READ_RES_DES !
76 ! !
77 ! Purpose: Construct the file name and open the DES RES file. !
78 !``````````````````````````````````````````````````````````````````````!
79  SUBROUTINE init_read_res_des(BASE, lVERSION, lNEXT_REC)
80 
81  use discretelement, only: max_pip, pip
82  use discretelement, only: ighost_cnt
83  use discretelement, only: neigh_num
84 
85  use compar, only: numpes
86  use machine, only: open_n1
87 
88  use mpi_utility, only: bcast
89  use mpi_utility, only: global_all_sum
90 
91  implicit none
92 
93  CHARACTER(len=*), INTENT(IN) :: BASE
94  DOUBLE PRECISION, INTENT(OUT) :: lVERSION
95  INTEGER, INTENT(OUT) :: lNEXT_REC
96 
97  CHARACTER(len=32) :: lFNAME
98 
99 ! Integer Error Flag
100  INTEGER :: IER
101 
102 
103  allocate(pscatter(0:numpes-1))
104  allocate(pdispls(0:numpes-1))
105 
106  allocate(cscatter(0:numpes-1))
107  allocate(cdispls(0:numpes-1))
108 
109 
110  IF(bdist_io) THEN
111 
112  WRITE(lfname,'(A,I4.4,A)') base//'_DES_',mype,'.RES'
113  OPEN(convert='BIG_ENDIAN',unit=rdes_unit, file=lfname, &
114  form='UNFORMATTED', status='UNKNOWN', access='DIRECT', &
115  recl=open_n1)
116 
117  READ(rdes_unit, rec=1) lversion
118  READ(rdes_unit, rec=2) pin_count
119  READ(rdes_unit, rec=3) ighost_cnt
120  READ(rdes_unit, rec=4) cin_count
121 
122  IF(pip > max_pip) THEN
123  write(*,*) "From des_read_restart:"
124  write(*,*) "Error: The pip is grater than current max_pip"
125  write(*,*) "pip=" ,pip,"; max_pip =", max_pip
126 
127  ENDIF
128 
129  pip = pin_count
130  neigh_num = cin_count
131 
132  CALL particle_grow(neigh_num)
133 
134  ELSE
135 
136  IF(mype == pe_io) THEN
137  WRITE(lfname,'(A,A)') base//'_DES.RES'
138  OPEN(convert='BIG_ENDIAN',unit=rdes_unit, file=lfname, &
139  form='UNFORMATTED', status='UNKNOWN', access='DIRECT', &
140  recl=open_n1)
141 
142  READ(rdes_unit, rec=1) pin_count
143 
144  READ(rdes_unit, rec=1) lversion
145  READ(rdes_unit, rec=2) pin_count
146 ! READ(RDES_UNIT, REC=3) -NOTHING-
147  READ(rdes_unit, rec=4) cin_count
148 
149  ELSE
150  pin_count = 10
151  ENDIF
152 
153  ier = 0
154 
155 ! Allocate the particle restart map. This is used in determining were
156 ! particle data is sent. Only process zero needs this array.
157  allocate( prestartmap(pin_count), stat=ier)
158  IF(ier/=0) THEN
159  WRITE(err_msg, 1200) 'pRestartMap', trim(ival(pin_count))
160  CALL flush_err_msg
161  ENDIF
162 
163  CALL bcast(lversion, pe_io)
164 
165 ! Allocate the collision restart map array. All ranks allocatet this
166 ! array so that mapping the collision data can be done in parallel.
167  CALL bcast(cin_count, pe_io)
168  allocate( crestartmap(cin_count), stat=ier)
169  IF(ier/=0) THEN
170  WRITE(err_msg, 1200) 'cRestartMap', trim(ival(cin_count))
171  CALL flush_err_msg
172  ENDIF
173 
174  1200 FORMAT('Error 1200: Unable to allocate sufficient memory to ',&
175  'read in DES',/'restart file. size(',a,') = ',a)
176 
177  CALL global_all_sum(ier)
178  IF(ier/=0) CALL mfix_exit(mype)
179 
180  ENDIF
181 
182  lnext_rec = 5
183 
184  RETURN
185  END SUBROUTINE init_read_res_des
186 
187 
188 !``````````````````````````````````````````````````````````````````````!
189 ! Subroutine: CLOSE_RES_DES !
190 ! !
191 ! Purpose: Close the DES RES file. !
192 !``````````````````````````````````````````````````````````````````````!
193  SUBROUTINE finl_read_res_des
195 
196  IF(bdist_io .OR. mype == pe_io) close(rdes_unit)
197 
198  IF(allocated(dprocbuf)) deallocate(dprocbuf)
199  IF(allocated(drootbuf)) deallocate(drootbuf)
200  IF(allocated(iprocbuf)) deallocate(iprocbuf)
201  IF(allocated(irootbuf)) deallocate(irootbuf)
202 
203  IF(allocated(prestartmap)) deallocate(prestartmap)
204  IF(allocated(crestartmap)) deallocate(crestartmap)
205 
206  IF(allocated(pscatter)) deallocate(pscatter)
207  IF(allocated(pdispls)) deallocate(pdispls)
208 
209  IF(allocated(cscatter)) deallocate(cscatter)
210  IF(allocated(cdispls)) deallocate(cdispls)
211 
212 
213 
214 
215  RETURN
216  END SUBROUTINE finl_read_res_des
217 
218 
219 
220 !``````````````````````````````````````````````````````````````````````!
221 ! Subroutine: READ_PAR_POS !
222 ! !
223 ! Purpose: Generates the mapping used by the scatter routines to send !
224 ! read data to the correct rank. !
225 !``````````````````````````````````````````````````````````````````````!
226  SUBROUTINE read_par_pos(lNEXT_REC)
228  use discretelement, only: pip
229  use discretelement, only: des_pos_new
230  use geometry, only: no_k
231  use compar, only: numpes
232 
233  use mpi_utility, only: global_sum
234  USE in_binary_512
235 
236  implicit none
237 
238  INTEGER, INTENT(INOUT) :: lNEXT_REC
239 
240  INTEGER :: lDIMN
241  INTEGER :: LC1, lPROC
242  INTEGER :: lScatterCNTS(0:numpes-1)
243 ! The number of particles on each process.
244  INTEGER :: PAR_CNT(0:numpes-1)
245 
246 !-----------------------------------------------
247 
248  CALL init_err_msg("READ_PAR_POS")
249 
250  ldimn = merge(2,3,no_k)
251 
252 
253 ! All process read positions for distributed IO restarts.
254  IF(bdist_io) THEN
255  DO lc1 = 1, ldimn
256  CALL read_res_des(lnext_rec, des_pos_new(:,lc1))
257  ENDDO
258  RETURN
259  ENDIF
260 
261  allocate( dpar_pos(pin_count, ldimn))
262 
263 ! Only the IO proccess reads positions.
264  IF(mype == pe_io) THEN
265  DO lc1=1, merge(2,3,no_k)
266  CALL in_bin_512(rdes_unit, dpar_pos(:,lc1), &
267  pin_count, lnext_rec)
268  ENDDO
269  ENDIF
270 
271 ! Use the particle postions and the domain coverage of each process
272 ! to determine which processor each particle belongs.
273  CALL map_parray_to_proc(par_cnt)
274 
275 ! Send the particle position data to the individual ranks.
276  CALL scatter_par_pos(par_cnt)
277 
278 ! Set up the read/scatter arrary information.
279  pproccnt = pip
280  prootcnt = pin_count
281 
282 ! Set the recv count for this process.
283  precv = pip
284 
285 ! Construct an array for the Root process that states the number of
286 ! (real) particles on each process.
287  lscattercnts(:) = 0; lscattercnts(mype) = pip
288  CALL global_sum(lscattercnts,pscatter)
289 
290 ! Calculate the displacements for each process in the global array.
291  pdispls(0) = 0
292  DO lproc = 1, numpes-1
293  pdispls(lproc) = pdispls(lproc-1) + pscatter(lproc-1)
294  ENDDO
295 
296  IF(allocated(dpar_pos)) deallocate(dpar_pos)
297 
298  CALL finl_err_msg
299 
300  RETURN
301  END SUBROUTINE read_par_pos
302 
303 
304 !``````````````````````````````````````````````````````````````````````!
305 ! Subroutine: MAP_pARRAY_TO_PROC !
306 ! !
307 ! Purpose: Use the particle positions to determine which processor !
308 ! they live on and count the number of particles on each process. !
309 !``````````````````````````````````````````````````````````````````````!
310  SUBROUTINE map_parray_to_proc(lPAR_CNT)
312  use discretelement, only: pip
313  use discretelement, only: xe, yn, zt
314  use geometry, only: imin1, imax1
315  use geometry, only: jmin1, jmax1
316  use geometry, only: kmin1, kmax1
317  use geometry, only: no_k, do_k
318  use compar, only: numpes
319  use compar, only: istart1_all, iend1_all
320  use compar, only: jstart1_all, jend1_all
321  use compar, only: kstart1_all, kend1_all
322 
323  use mpi_utility, only: bcast
324  use mpi_utility, only: global_all_sum
325 
326  implicit none
327 
328  INTEGER, INTENT(OUT) :: lPAR_CNT(0:numpes-1)
329 
330 ! Data dimensionality flag.
331  INTEGER :: lDIMN
332 ! Loop counters.
333  INTEGER :: LC1, lPROC
334 ! Error flag.
335  INTEGER :: IER(0:numpes-1)
336 ! The X/Y/Z bounds of the physical space "owned" by each process.
337  DOUBLE PRECISION :: lxmin(0:numpes-1), lxmax(0:numpes-1)
338  DOUBLE PRECISION :: lymin(0:numpes-1), lymax(0:numpes-1)
339  DOUBLE PRECISION :: lzmin(0:numpes-1), lzmax(0:numpes-1)
340 !-----------------------------------------------
341 
342  CALL init_err_msg("MAP_pARRAY_TO_PROC")
343 
344 ! Initialize the error flag.
345  ier = 0
346 
347  ldimn = merge(2, 3, no_k)
348 
349 ! set the domain range for each processor
350  DO lproc= 0, numpes-1
351  lxmin(lproc) = xe(istart1_all(lproc)-1)
352  lxmax(lproc) = xe(iend1_all(lproc))
353  lymin(lproc) = yn(jstart1_all(lproc)-1)
354  lymax(lproc) = yn(jend1_all(lproc))
355  lzmin(lproc) = zt(kstart1_all(lproc)-1)
356  lzmax(lproc) = zt(kend1_all(lproc))
357 
358 ! modify the range for mass inlet and outlet, as particles injected
359 ! can lie outside the domain and not ghost particles
360  IF(istart1_all(lproc).eq.imin1) &
361  lxmin(lproc) = xe(istart1_all(lproc)-2)
362  IF(iend1_all(lproc).eq.imax1) &
363  lxmax(lproc) = xe(iend1_all(lproc)+1)
364  IF(jstart1_all(lproc).eq.jmin1) &
365  lymin(lproc) = yn(jstart1_all(lproc)-2)
366  IF(jend1_all(lproc).eq.jmax1) &
367  lymax(lproc) = yn(jend1_all(lproc)+1)
368  IF(kstart1_all(lproc).eq.kmin1 .AND. do_k) &
369  lzmin(lproc) = zt(kstart1_all(lproc)-2)
370  IF(kend1_all(lproc).eq.kmax1 .AND. do_k) &
371  lzmax(lproc) = zt(kend1_all(lproc)+1)
372  ENDDO
373 
374 ! build the send buffer in PE_IO proc
375 ! first pass to get the count of particles
376  ier = 0
377  prestartmap(:) = -1
378  lpar_cnt(:) = 0
379  IF(mype == pe_io) THEN
380  DO lc1 = 1, pin_count
381  DO lproc=0, numpes-1
382  IF(dpar_pos(lc1,1) >= lxmin(lproc) .AND. &
383  dpar_pos(lc1,1) < lxmax(lproc) .AND. &
384  dpar_pos(lc1,2) >= lymin(lproc) .AND. &
385  dpar_pos(lc1,2) < lymax(lproc)) THEN
386  IF(no_k)THEN
387  lpar_cnt(lproc) = lpar_cnt(lproc) + 1
388  prestartmap(lc1) = lproc
389  EXIT
390  ELSE
391  IF(dpar_pos(lc1,3) >= lzmin(lproc) .AND. &
392  dpar_pos(lc1,3) < lzmax(lproc)) THEN
393  lpar_cnt(lproc) = lpar_cnt(lproc) + 1
394  prestartmap(lc1) = lproc
395  EXIT
396  ENDIF
397  ENDIF
398  ENDIF
399  ENDDO ! Loop over processes
400  IF (prestartmap(lc1) == -1) then
401  ier(mype) = -1
402  WRITE(err_msg,1000) trim(ival(lc1))
403  CALL flush_err_msg(footer=.false.)
404  IF(no_k) THEN
405  WRITE(err_msg,1001) dpar_pos(lc1,1:2)
406  CALL flush_err_msg(header=.false.)
407  ELSE
408  WRITE(err_msg,1002) dpar_pos(lc1,1:3)
409  CALL flush_err_msg(header=.false.)
410  ENDIF
411  ENDIF
412  ENDDO ! Loop over particles
413  ENDIF
414 
415  1000 FORMAT('Error 1000: Unable to locate particle inside domain:',/&
416  3x,'Particle Number:',a)
417  1001 FORMAT(3x,'X POS: ',g12.5,/3x,'Y POS: ',g12.5)
418  1002 FORMAT(3x,'X POS: ',g12.5,/3x,'Y POS: ',g12.5,/3x,'Z POS: ',g12.5)
419 
420 ! Send out the error flag and exit if needed.
421  CALL bcast(ier, pe_io)
422  IF(ier(pe_io) /= 0) CALL mfix_exit(mype)
423 
424 ! PE_IO sends out the number of particles for each process.
425  CALL bcast(lpar_cnt(0:numpes-1), pe_io)
426 
427 ! Each process stores the number of particles-on-its-process. The error
428 ! flag is set if that number exceeds the maximum.
429  pip = lpar_cnt(mype)
430  CALL particle_grow(pip)
431 
432 ! Global collection of error flags to abort it the max was exceeded.
433  CALL global_all_sum(ier)
434  IF(sum(ier) /= 0) THEN
435  WRITE(err_msg,1100)
436  CALL flush_err_msg(footer=.false.)
437  DO lc1=0, numpes-1
438  IF(ier(lc1) /= 0) THEN
439  WRITE(err_msg,"(3(2x,I10))")lc1,ier(lc1)-1,lpar_cnt(lc1)
440  CALL flush_err_msg(header=.false., footer=.false.)
441  ENDIF
442  ENDDO
443  WRITE(err_msg,"('Aborting.')")
444  CALL flush_err_msg(header=.false.,abort=.true.)
445  ENDIF
446 
447  1100 FORMAT('Error 1100: Maximum number of particles exceeded.',2/ &
448  5x,'Process',5x,'Maximum',7x,'Count')
449 
450 
451  CALL finl_err_msg
452 
453  RETURN
454  END SUBROUTINE map_parray_to_proc
455 
456 
457 
458 !``````````````````````````````````````````````````````````````````````!
459 ! Subroutine: DES_RESTART_MAP !
460 ! !
461 ! Purpose: Generates the mapping used by the scatter routines to send !
462 ! read data to the correct rank. !
463 !``````````````````````````````````````````````````````````````````````!
464  SUBROUTINE scatter_par_pos(lPAR_CNT)
466  use compar, only: numpes
467 
468  use discretelement, only: des_pos_new
469  use discretelement, only: pip
470  use functions, only: set_normal
471  use geometry, only: no_k
472 
473  implicit none
474 
475 ! Number of particles on each process.
476  INTEGER, INTENT(INOUT) :: lPAR_CNT(0:numpes-1)
477 ! Dimensionality flag.
478  INTEGER :: lDIMN
479 ! Loop counters.
480  INTEGER :: LC1, lPROC, lBuf
481 
482  ldimn = merge(2,3,no_k)
483 
484 ! Set up the recv count and allocate the local process buffer.
485  iscr_recvcnt = pip*ldimn
486  allocate (dprocbuf(iscr_recvcnt))
487 
488 ! Allocate the buffer for the root.
489  IF (mype == pe_io) THEN
490  allocate (drootbuf(pin_count*ldimn))
491  ELSE
492  allocate (drootbuf(10))
493  ENDIF
494 
495 ! The IO processor builds drootbuffer and iDISLS
496  IF(mype == pe_io) THEN
497 ! Determine the offsets for each process and the amount of data that
498 ! is to be scattered to each.
499  idispls(0) = 0
500  iscattercnts(0) = lpar_cnt(0)*ldimn
501  DO lproc = 1, numpes-1
502  idispls(lproc) = idispls(lproc-1) + iscattercnts(lproc-1)
503  iscattercnts(lproc) = lpar_cnt(lproc)*ldimn
504  ENDDO
505 ! Copy the position data into the root buffer, mapped to the owner
506 ! process.
507  lpar_cnt(:) = 0
508  DO lc1 = 1,pin_count
509  lproc = prestartmap(lc1)
510  lbuf = idispls(lproc) + lpar_cnt(lproc)*ldimn+1
511  drootbuf(lbuf:lbuf+ldimn-1) = dpar_pos(lc1,1:ldimn)
512  lbuf = lbuf + ldimn
513  lpar_cnt(lproc) = lpar_cnt(lproc) + 1
514  ENDDO
515  ENDIF
516  CALL desmpi_scatterv(ptype=2)
517 
518 ! Unpack the particle data.
519  DO lc1 = 1, pip
520  lbuf = (lc1-1)*ldimn+1
521  des_pos_new(lc1,1:ldimn) = dprocbuf(lbuf:lbuf+ldimn-1)
522  lbuf = lbuf + ldimn
523  CALL set_normal(lc1)
524  ENDDO
525 
526  IF(allocated(drootbuf)) deallocate(drootbuf)
527  IF(allocated(dprocbuf)) deallocate(dprocbuf)
528  IF(allocated(dpar_pos)) deallocate(dpar_pos)
529 
530  RETURN
531  END SUBROUTINE scatter_par_pos
532 
533 !``````````````````````````````````````````````````````````````````````!
534 ! Subroutine: READ_PAR_COL !
535 ! !
536 ! Purpose: Generates the mapping used by the scatter routines to send !
537 ! read data to the correct rank. !
538 !``````````````````````````````````````````````````````````````````````!
539  SUBROUTINE read_par_col(lNEXT_REC)
541  use discretelement, only: neighbors, neigh_num
542  use compar, only: numpes
543 
545  use mpi_utility, only: bcast
546  use mpi_utility, only: global_sum
547  use mpi_utility, only: global_all_sum
548  use in_binary_512i
549 
550  implicit none
551 
552  INTEGER, INTENT(INOUT) :: lNEXT_REC
553 
554  INTEGER :: LC1, lPROC
555  INTEGER :: lScatterCNTS(0:numpes-1)
556 ! The number of particles on each process.
557  INTEGER :: COL_CNT(0:numpes-1)
558 
559 !-----------------------------------------------
560 
561  CALL init_err_msg("READ_PAR_COL")
562 
563 ! All process read positions for distributed IO restarts.
564  IF(bdist_io) THEN
565  CALL read_res_des(lnext_rec, neighbors(:))
566  ENDIF
567 
568  CALL des_restart_ghost
569 
570  allocate(ipar_col(2, cin_count))
571  ipar_col = 0
572 
573 ! Only the IO proccess reads positions.
574  IF(mype == pe_io) THEN
575  DO lc1=1, 2
576  CALL in_bin_512i(rdes_unit, ipar_col(lc1,:), &
577  cin_count, lnext_rec)
578  ENDDO
579  ENDIF
580 
581 ! Broadcast collision data to all the other processes.
582  CALL global_all_sum(ipar_col)
583 
584 ! Determine which process owns the neighbor datasets. This is done either
585 ! through matching global ids or a search. The actual method depends
586 ! on the ability to allocate a large enough array.
587  CALL map_carray_to_proc(col_cnt)
588 
589 ! Send the particle position data to the individual ranks.
590  CALL global_to_loc_col
591 
592 ! Set up the read/scatter arrary information.
593  cproccnt = neigh_num
594  crootcnt = cin_count
595 
596 ! Set the recv count for this process.
597  crecv = neigh_num
598 
599 ! Construct an array for the Root process that states the number of
600 ! (real) particles on each process.
601  lscattercnts(:) = 0; lscattercnts(mype) = neigh_num
602  CALL global_sum(lscattercnts,cscatter)
603 
604 ! Calculate the displacements for each process in the global array.
605  cdispls(0) = 0
606  DO lproc = 1, numpes-1
607  cdispls(lproc) = cdispls(lproc-1) + cscatter(lproc-1)
608  ENDDO
609 
610  CALL finl_err_msg
611 
612  RETURN
613  END SUBROUTINE read_par_col
614 
615 
616 !``````````````````````````````````````````````````````````````````````!
617 ! Subroutine: MAP_cARRAY_TO_PROC !
618 ! !
619 ! Purpose: Use the particle positions to determine which processor !
620 ! they live on and count the number of particles on each process. !
621 !``````````````````````````````````````````````````````````````````````!
622  SUBROUTINE map_carray_to_proc(lCOL_CNT)
624  use compar, only: numpes, mype
625  use discretelement, only: iglobal_id
626  use discretelement, only: pip
627  use discretelement, only: neigh_num
628  use functions, only: is_ghost, is_entering_ghost, is_exiting_ghost
629 
630  use mpi_utility, only: global_all_sum
631  use mpi_utility, only: global_all_max
632 
633  implicit none
634 
635  INTEGER, INTENT(OUT) :: lCOL_CNT(0:numpes-1)
636 
637 ! Loop counters.
638  INTEGER :: LC1, LC2
639 ! Error flag.
640  INTEGER :: IER
641 ! Max global id.
642  INTEGER :: MAX_ID, lSTAT
643 
644  INTEGER, ALLOCATABLE :: lGLOBAL_OWNER(:)
645 
646 !-----------------------------------------------
647 
648  CALL init_err_msg("MAP_cARRAY_TO_PROC")
649 
650 ! Initialize the error flag.
651  ier = 0
652 
653  max_id = maxval(iglobal_id(1:pip))
654  CALL global_all_max(max_id)
655 
656  allocate(lglobal_owner(max_id), stat=lstat)
657  CALL global_all_sum(lstat)
658 
659 ! All ranks successfully allocated the array. This permits a crude
660 ! but much faster collision owner detection.
661  IF(lstat == 0) THEN
662 
663  WRITE(err_msg,"('Matching DES neighbor data by global owner.')")
664  CALL flush_err_msg(header=.false.,footer=.false.)
665 
666  lglobal_owner = 0
667  DO lc1=1, pip
668  IF(.NOT.is_ghost(lc1) .AND. .NOT.is_entering_ghost(lc1) &
669  .AND. .NOT.is_exiting_ghost(lc1)) &
670  lglobal_owner(iglobal_id(lc1)) = mype + 1
671  ENDDO
672 
673 ! Loop over the neighbor list and match the read global ID to
674 ! one of the global IDs.
675  lcol_cnt = 0
676  crestartmap = 0
677  DO lc1=1, cin_count
678  IF(lglobal_owner(ipar_col(1,lc1)) == mype + 1) THEN
679  crestartmap(lc1) = mype + 1
680  lcol_cnt(mype) = lcol_cnt(mype) + 1
681  ENDIF
682  ENDDO
683 ! One or more ranks could not allocate the memory needed to do the
684 ! quick and dirty match so do a search instead.
685  ELSE
686 
687  WRITE(err_msg,"('Matching DES neighbor data by search.')")
688  CALL flush_err_msg(header=.false.,footer=.false.)
689 
690 ! Loop over the neighbor list and match the read global ID to
691 ! one of the global IDs.
692  lcol_cnt = 0
693  crestartmap = 0
694  lc1_lp: DO lc1=1, cin_count
695  DO lc2=1, pip!-iGHOST_CNT
696  IF(ipar_col(1,lc1) == iglobal_id(lc2)) THEN
697  crestartmap(lc1) = mype + 1
698  lcol_cnt(mype) = lcol_cnt(mype) + 1
699  cycle lc1_lp
700  ENDIF
701  ENDDO
702  ENDDO lc1_lp
703 
704  ENDIF
705 
706 ! Clean up the large array as it is no longer needed.
707  IF(allocated(lglobal_owner)) deallocate(lglobal_owner)
708 
709 ! Calculate the number of matched collisions over all processes. Throw
710 ! and error if it doesn't match the number of read collisions.
711  CALL global_all_sum(lcol_cnt)
712  IF(sum(lcol_cnt) /= cin_count) THEN
713  WRITE(err_msg,1000) cin_count, sum(lcol_cnt)
714  CALL flush_err_msg(abort=.true.)
715  ENDIF
716 
717 1000 FORMAT('Error 1000: Unable to establish the own of all read ', &
718  'collision data.',/3x,'Number of Collisions: ',i10,/3x, &
719  'Matched Collisions: ',i10)
720 
721 ! Sync the collision restart map arcross all ranks.
722  CALL global_all_sum(crestartmap)
723 
724 ! Error checking and cleanup.
725  DO lc1 = 1, cin_count
726 ! Verify that each collision is owned by a rank.
727  IF (crestartmap(lc1) == 0) THEN
728  ier = -1
729  WRITE(err_msg,1100) trim(ival(lc1)), trim(ival( &
730  ipar_col(1,lc1))), trim(ival(ipar_col(2,lc1)))
731  CALL flush_err_msg(abort=.true.)
732 
733  1100 FORMAT('Error 1100: Unable to locate process neighbor owner:',/ &
734  3x,'Neighbor Number:',a,/3x,'Particles: ',a,' and ',a)
735 
736  ELSEIF(crestartmap(lc1) > numpes) THEN
737 
738  ier = -1
739  WRITE(err_msg,1101) trim(ival(lc1)), trim(ival( &
740  ipar_col(1,lc1))), trim(ival(ipar_col(2,lc1)))
741  CALL flush_err_msg(abort=.true.)
742 
743  1101 FORMAT('Error 1101: More than one process neighbor owner:',/ &
744  3x,'Neighbor Number:',a,/3x,'Particles: ',a,' and ',a)
745 
746 ! Shift the rank ID to the correct value.
747  ELSE
748  crestartmap(lc1) = crestartmap(lc1) - 1
749  ENDIF
750  ENDDO
751 
752 ! Send out the error flag and exit if needed.
753  CALL global_all_sum(ier, pe_io)
754  IF(ier /= 0) CALL mfix_exit(mype)
755 
756 ! Each process stores the number of particles-on-its-process. The error
757 ! flag is set if that number exceeds the maximum.
758  neigh_num = lcol_cnt(mype)
759 
760  CALL neighbor_grow(neigh_num)
761 
762  CALL finl_err_msg
763 
764  RETURN
765  END SUBROUTINE map_carray_to_proc
766 
767 
768 !``````````````````````````````````````````````````````````````````````!
769 ! Subroutine: GLOBAL_TO_LOC_COL !
770 ! !
771 ! Purpose: Generates the mapping used by the scatter routines to send !
772 ! read data to the correct rank. !
773 !``````````````````````````````````````````````````````````````````````!
774  SUBROUTINE global_to_loc_col
776  use discretelement, only: iglobal_id
777  use discretelement, only: pip
778 
779  use mpi_utility, only: global_all_sum
780  use mpi_utility, only: global_all_max
781 
782  use funits, only: dmp_log
783 
784  use error_manager
785 
786  implicit none
787 
788 ! Loop counters.
789  INTEGER :: LC1, LC2, LC3, IER
790  INTEGER :: UNMATCHED
791  INTEGER, ALLOCATABLE :: iLOCAL_ID(:)
792 
793 ! Max global id.
794  INTEGER :: MAX_ID, lSTAT
795 ! Debug flags.
796  LOGICAL :: dFlag
797  LOGICAL, parameter :: setDBG = .false.
798 
799  CALL init_err_msg("GLOBAL_TO_LOC_COL")
800 
801 ! Initialize the error flag.
802  ier = 0
803 
804 ! Set the local debug flag.
805  dflag = (dmp_log .AND. setdbg)
806 
807  max_id = maxval(iglobal_id(1:pip))
808  CALL global_all_max(max_id)
809 
810  allocate(ilocal_id(max_id), stat=lstat)
811  CALL global_all_sum(lstat)
812 
813 ! All ranks successfully allocated the array. This permits a crude
814 ! but much faster collision owner detection.
815  IF(lstat /= 0) THEN
816  WRITE(err_msg,1000)
817  CALL flush_err_msg(abort=.true.)
818  ENDIF
819 
820  1000 FORMAT('Error 1000: Unable to allocate sufficient memory to ',&
821  'generate the',/'map from global to local particle IDs.')
822 
823  ilocal_id = 0
824  DO lc1=1, pip
825  ilocal_id(iglobal_id(lc1)) = lc1
826  ENDDO
827 
828 ! Store the particle data.
829  lc3 = 1
830  lc2 = 0
831  unmatched = 0
832 
833 ! FIXME Fix Restart
834 ! LP1: DO LC1 = 1, cIN_COUNT
835 ! IF(cRestartMap(LC1) == myPE) THEN
836 ! LC2 = LC2 + 1
837 ! NEIGHBORS(LC2) = iLOCAL_ID(iPAR_COL(1,LC1))
838 ! NEIGHBORS(2,LC2) = iLOCAL_ID(iPAR_COL(2,LC1))
839 ! ! Verify that the local indices are valid. If they do not match it is
840 ! ! likely because one of the neighbor was removed via an outlet at the time
841 ! ! the RES file was written but the ghost data wasn't updated.
842 ! IF(NEIGHBORS(1,LC2) == 0 .OR. NEIGHBORS(2,LC2) == 0) THEN
843 ! UNMATCHED = UNMATCHED + 1
844 ! IF(dFLAG) THEN
845 ! WRITE(ERR_MSG,1100) iPAR_COL(1,LC1), NEIGHBORS(1,LC2), &
846 ! iPAR_COL(2,LC1), NEIGHBORS(2,LC2)
847 ! CALL FLUSH_ERR_MSG(ABORT=.FALSE.)
848 ! ENDIF
849 ! DO WHILE(PEA(LC3,1))
850 ! LC3 = LC3 + 1
851 ! ENDDO
852 ! NEIGHBORS(2,LC2) = LC3
853 ! ENDIF
854 ! ENDIF
855 ! ENDDO LP1
856 
857 ! 1100 FORMAT('Error 1100: Particle neighbor local indices are invalid.',/ &
858 ! 5x,'Global-ID Local-ID',/' 1: ',2(3x,I9),/' 2: ',2(3x,I9))
859 
860  CALL global_all_sum(unmatched)
861  IF(unmatched /= 0) THEN
862  WRITE(err_msg,1101) trim(ival(unmatched))
863  CALL flush_err_msg
864  ENDIF
865 
866  1101 FORMAT(' Warning: 1101: ',a,' particle neighbor datasets were ',&
867  'not matched',/' during restart.')
868 
869  IF(allocated(ilocal_id)) deallocate(ilocal_id)
870 
871  CALL finl_err_msg
872 
873  RETURN
874  END SUBROUTINE global_to_loc_col
875 
876 
877 
878 !``````````````````````````````````````````````````````````````````````!
879 ! Subroutine: READ_RES_DES_0I !
880 ! !
881 ! Purpose: Write scalar integers to RES file. !
882 !``````````````````````````````````````````````````````````````````````!
883  SUBROUTINE read_res_des_0i(lNEXT_REC, INPUT_I)
885  use mpi_utility, only: bcast
886 
887  IMPLICIT NONE
888 
889  INTEGER, INTENT(INOUT) :: lNEXT_REC
890  INTEGER, INTENT(OUT) :: INPUT_I
891 
892  IF(bdist_io) THEN
893  READ(rdes_unit, rec=lnext_rec) input_i
894  ELSE
895  IF(mype == pe_io) READ(rdes_unit, rec=lnext_rec) input_i
896  CALL bcast(input_i, pe_io)
897  ENDIF
898 
899  lnext_rec = lnext_rec + 1
900 
901  RETURN
902  END SUBROUTINE read_res_des_0i
903 
904 
905 !``````````````````````````````````````````````````````````````````````!
906 ! Subroutine: READ_RES_1I !
907 ! !
908 ! Purpose: Write scalar integers to RES file. !
909 !``````````````````````````````````````````````````````````````````````!
910  SUBROUTINE read_res_des_1i(lNEXT_REC, INPUT_I)
912  use mpi_utility, only: bcast
913  USE in_binary_512i
914 
915  IMPLICIT NONE
916 
917  INTEGER, INTENT(INOUT) :: lNEXT_REC
918  INTEGER, INTENT(OUT) :: INPUT_I(:)
919 
920  INTEGER :: lSIZE
921 
922  lsize = size(input_i)
923 
924  IF(bdist_io) THEN
925  CALL in_bin_512i(rdes_unit, input_i, lsize, lnext_rec)
926  ELSE
927  IF(mype == pe_io) &
928  CALL in_bin_512i(rdes_unit, input_i, lsize, lnext_rec)
929  CALL bcast(input_i, pe_io)
930  ENDIF
931 
932 
933  RETURN
934  END SUBROUTINE read_res_des_1i
935 
936 
937 !``````````````````````````````````````````````````````````````````````!
938 ! Subroutine: READ_RES_DES_0D !
939 ! !
940 ! Purpose: Write scalar double percision values to RES file. !
941 !``````````````````````````````````````````````````````````````````````!
942  SUBROUTINE read_res_des_0d(lNEXT_REC, INPUT_D)
944  use mpi_utility, only: bcast
945 
946  INTEGER, INTENT(INOUT) :: lNEXT_REC
947  DOUBLE PRECISION, INTENT(OUT) :: INPUT_D
948 
949  IF(bdist_io) THEN
950  READ(rdes_unit, rec=lnext_rec) input_d
951  ELSE
952  IF(mype == pe_io) READ(rdes_unit, rec=lnext_rec) input_d
953  CALL bcast(input_d, pe_io)
954  ENDIF
955  lnext_rec = lnext_rec + 1
956 
957  RETURN
958  END SUBROUTINE read_res_des_0d
959 
960 
961 !``````````````````````````````````````````````````````````````````````!
962 ! Subroutine: READ_RES_DES_1D !
963 ! !
964 ! Purpose: Write scalar integers to RES file. !
965 !``````````````````````````````````````````````````````````````````````!
966  SUBROUTINE read_res_des_1d(lNEXT_REC, INPUT_D)
968  use mpi_utility, only: bcast
969  USE in_binary_512
970 
971  IMPLICIT NONE
972 
973  INTEGER, INTENT(INOUT) :: lNEXT_REC
974  DOUBLE PRECISION, INTENT(OUT) :: INPUT_D(:)
975 
976  INTEGER :: lSIZE
977 
978  lsize = size(input_d)
979 
980  IF(bdist_io) THEN
981  CALL in_bin_512(rdes_unit, input_d, lsize, lnext_rec)
982  ELSE
983  IF(mype == pe_io) &
984  CALL in_bin_512(rdes_unit, input_d, lsize, lnext_rec)
985  CALL bcast(input_d, pe_io)
986  ENDIF
987 
988 
989  RETURN
990  END SUBROUTINE read_res_des_1d
991 
992 
993 !``````````````````````````````````````````````````````````````````````!
994 ! Subroutine: READ_RES_DES_0L !
995 ! !
996 ! Purpose: Write scalar logical values to RES file. !
997 !``````````````````````````````````````````````````````````````````````!
998  SUBROUTINE read_res_des_0l(lNEXT_REC, OUTPUT_L)
1000  use mpi_utility, only: bcast
1001 
1002  INTEGER, INTENT(INOUT) :: lNEXT_REC
1003  LOGICAL, INTENT(OUT) :: OUTPUT_L
1004 
1005  INTEGER :: OUTPUT_I
1006 
1007  output_l = .true.
1008 
1009  IF(bdist_io)THEN
1010  READ(rdes_unit, rec=lnext_rec) output_i
1011  ELSE
1012  IF(mype == pe_io) READ(rdes_unit, rec=lnext_rec) output_i
1013  CALL bcast(output_i, pe_io)
1014  ENDIF
1015 
1016  IF(output_i == 1) output_l = .true.
1017  lnext_rec = lnext_rec + 1
1018 
1019  RETURN
1020  END SUBROUTINE read_res_des_0l
1021 
1022 
1023 !``````````````````````````````````````````````````````````````````````!
1024 ! Subroutine: READ_RES_DES_1L !
1025 ! !
1026 ! Purpose: Write scalar integers to RES file. !
1027 !``````````````````````````````````````````````````````````````````````!
1028  SUBROUTINE read_res_des_1l(lNEXT_REC, INPUT_L)
1030  use mpi_utility, only: bcast
1031  USE in_binary_512i
1032 
1033  IMPLICIT NONE
1034 
1035  INTEGER, INTENT(INOUT) :: lNEXT_REC
1036  LOGICAL, INTENT(OUT) :: INPUT_L(:)
1037 
1038  INTEGER, ALLOCATABLE :: INPUT_I(:)
1039 
1040  INTEGER :: lSIZE, LC1
1041 
1042  lsize = size(input_i)
1043  ALLOCATE( input_i(lsize))
1044 
1045  IF(bdist_io) THEN
1046  CALL in_bin_512i(rdes_unit, input_i, lsize, lnext_rec)
1047  ELSE
1048  IF(mype == pe_io) &
1049  CALL in_bin_512i(rdes_unit, input_i, lsize, lnext_rec)
1050  CALL bcast(input_i, pe_io)
1051  ENDIF
1052 
1053  DO lc1=1, lsize
1054  IF(input_i(lc1) == 1) THEN
1055  input_l(lc1) = .true.
1056  ELSE
1057  input_l(lc1) = .false.
1058  ENDIF
1059  ENDDO
1060 
1061  IF(allocated(input_i)) deallocate(input_i)
1062 
1063  RETURN
1064  END SUBROUTINE read_res_des_1l
1065 
1066 !``````````````````````````````````````````````````````````````````````!
1067 ! Subroutine: READ_RES_DES_1B !
1068 ! !
1069 ! Purpose: Write scalar bytes to RES file. !
1070 !``````````````````````````````````````````````````````````````````````!
1071  SUBROUTINE read_res_parray_1b(lNEXT_REC, OUTPUT_B)
1073  use discretelement, only: pip
1074 
1075  use desmpi, only: irootbuf
1076  use desmpi, only: iprocbuf
1077 
1078  use compar, only: numpes
1079  USE in_binary_512i
1080 
1081  IMPLICIT NONE
1082 
1083  INTEGER, INTENT(INOUT) :: lNEXT_REC
1084  INTEGER(KIND=1), INTENT(OUT) :: OUTPUT_B(:)
1085 
1086 ! Loop counters
1087  INTEGER :: LC1
1088 
1089  INTEGER :: lPROC
1090 
1091  INTEGER, ALLOCATABLE :: OUTPUT_I(:)
1092  INTEGER, ALLOCATABLE :: lBUF_I(:)
1093  INTEGER, ALLOCATABLE :: lCOUNT(:)
1094 
1095  allocate(iprocbuf(pproccnt))
1096  allocate(irootbuf(prootcnt))
1097 
1098 
1099  idispls = pdispls
1100  iscr_recvcnt = precv
1101  iscattercnts = pscatter
1102 
1103  allocate(output_i(size(output_b)))
1104  output_i(:) = output_b(:)
1105 
1106  IF(bdist_io) THEN
1107  CALL in_bin_512i(rdes_unit, output_i, pin_count, lnext_rec)
1108  output_b(:) = output_i(:)
1109  ELSE
1110 
1111  IF(mype == pe_io) THEN
1112  allocate(lbuf_i(pin_count))
1113  allocate(lcount(0:numpes-1))
1114 
1115  CALL in_bin_512i(rdes_unit, lbuf_i, pin_count, lnext_rec)
1116 
1117  lcount = 0
1118  DO lc1=1, pin_count
1119  lproc = prestartmap(lc1)
1120  lcount(lproc) = lcount(lproc) + 1
1121  irootbuf(idispls(lproc) + lcount(lproc)) = lbuf_i(lc1)
1122  ENDDO
1123 
1124  deallocate(lbuf_i)
1125  deallocate(lcount)
1126  ENDIF
1127  CALL desmpi_scatterv(ptype=1)
1128  DO lc1=1, pip
1129  output_b(lc1) = iprocbuf(lc1)
1130  ENDDO
1131 
1132  ENDIF
1133 
1134  deallocate(iprocbuf)
1135  deallocate(irootbuf)
1136  deallocate(output_i)
1137 
1138  RETURN
1139  END SUBROUTINE read_res_parray_1b
1140 
1141 !``````````````````````````````````````````````````````````````````````!
1142 ! Subroutine: READ_RES_DES_1I !
1143 ! !
1144 ! Purpose: Write scalar integers to RES file. !
1145 !``````````````````````````````````````````````````````````````````````!
1146  SUBROUTINE read_res_parray_1i(lNEXT_REC, OUTPUT_I)
1148  use discretelement, only: pip
1149 
1150  use desmpi, only: irootbuf
1151  use desmpi, only: iprocbuf
1152 
1153  use compar, only: numpes
1154  USE in_binary_512i
1155 
1156  IMPLICIT NONE
1157 
1158  INTEGER, INTENT(INOUT) :: lNEXT_REC
1159  INTEGER, INTENT(OUT) :: OUTPUT_I(:)
1160 
1161 ! Loop counters
1162  INTEGER :: LC1
1163 
1164  INTEGER :: lPROC
1165 
1166  INTEGER, ALLOCATABLE :: lBUF_I(:)
1167  INTEGER, ALLOCATABLE :: lCOUNT(:)
1168 
1169 
1170  allocate(iprocbuf(pproccnt))
1171  allocate(irootbuf(prootcnt))
1172 
1173  idispls = pdispls
1174  iscr_recvcnt = precv
1175  iscattercnts = pscatter
1176 
1177  IF(bdist_io) THEN
1178  CALL in_bin_512i(rdes_unit, output_i, pin_count, lnext_rec)
1179  ELSE
1180 
1181  IF(mype == pe_io) THEN
1182  allocate(lbuf_i(pin_count))
1183  allocate(lcount(0:numpes-1))
1184 
1185  CALL in_bin_512i(rdes_unit, lbuf_i, pin_count, lnext_rec)
1186 
1187  lcount = 0
1188  DO lc1=1, pin_count
1189  lproc = prestartmap(lc1)
1190  lcount(lproc) = lcount(lproc) + 1
1191  irootbuf(idispls(lproc) + lcount(lproc)) = lbuf_i(lc1)
1192  ENDDO
1193 
1194  deallocate(lbuf_i)
1195  deallocate(lcount)
1196  ENDIF
1197  CALL desmpi_scatterv(ptype=1)
1198  DO lc1=1, pip
1199  output_i(lc1) = iprocbuf(lc1)
1200  ENDDO
1201 
1202  ENDIF
1203 
1204  deallocate(iprocbuf)
1205  deallocate(irootbuf)
1206 
1207  RETURN
1208  END SUBROUTINE read_res_parray_1i
1209 
1210 
1211 
1212 !``````````````````````````````````````````````````````````````````````!
1213 ! Subroutine: READ_RES_pARRAY_1D !
1214 ! !
1215 ! Purpose: Write scalar integers to RES file. !
1216 !``````````````````````````````````````````````````````````````````````!
1217  SUBROUTINE read_res_parray_1d(lNEXT_REC, OUTPUT_D)
1219  use discretelement, only: pip
1220  use desmpi, only: drootbuf
1221  use desmpi, only: dprocbuf
1222  use compar, only: numpes
1223  USE in_binary_512
1224 
1225  IMPLICIT NONE
1226 
1227  INTEGER, INTENT(INOUT) :: lNEXT_REC
1228  DOUBLE PRECISION, INTENT(OUT) :: OUTPUT_D(:)
1229 
1230 ! Loop counters
1231  INTEGER :: LC1
1232 
1233  INTEGER :: lPROC
1234 
1235  DOUBLE PRECISION, ALLOCATABLE :: lBUF_D(:)
1236  INTEGER, ALLOCATABLE :: lCOUNT(:)
1237 
1238 
1239  allocate(dprocbuf(pproccnt))
1240  allocate(drootbuf(prootcnt))
1241 
1242  idispls = pdispls
1243  iscr_recvcnt = precv
1244  iscattercnts = pscatter
1245 
1246  IF(bdist_io) THEN
1247  CALL in_bin_512(rdes_unit, output_d, pin_count, lnext_rec)
1248  ELSE
1249  IF(mype == pe_io) THEN
1250  allocate(lbuf_d(pin_count))
1251  allocate(lcount(0:numpes-1))
1252 
1253  CALL in_bin_512(rdes_unit, lbuf_d, pin_count, lnext_rec)
1254 
1255  lcount = 0
1256  DO lc1=1, pin_count
1257  lproc = prestartmap(lc1)
1258  lcount(lproc) = lcount(lproc) + 1
1259  drootbuf(idispls(lproc) + lcount(lproc)) = lbuf_d(lc1)
1260  ENDDO
1261 
1262  deallocate(lbuf_d)
1263  deallocate(lcount)
1264  ENDIF
1265  CALL desmpi_scatterv(ptype=2)
1266  DO lc1=1, pip
1267  output_d(lc1) = dprocbuf(lc1)
1268  ENDDO
1269  ENDIF
1270 
1271  deallocate(dprocbuf)
1272  deallocate(drootbuf)
1273 
1274  RETURN
1275  END SUBROUTINE read_res_parray_1d
1276 
1277 
1278 !``````````````````````````````````````````````````````````````````````!
1279 ! Subroutine: READ_RES_pARRAY_1L !
1280 ! !
1281 ! Purpose: Write scalar integers to RES file. !
1282 !``````````````````````````````````````````````````````````````````````!
1283  SUBROUTINE read_res_parray_1l(lNEXT_REC, OUTPUT_L)
1285  use discretelement, only: pip
1286  use desmpi, only: irootbuf
1287  use desmpi, only: iprocbuf
1288  use compar, only: numpes
1289  USE in_binary_512i
1290 
1291  IMPLICIT NONE
1292 
1293  INTEGER, INTENT(INOUT) :: lNEXT_REC
1294  LOGICAL, INTENT(OUT) :: OUTPUT_L(:)
1295 
1296 ! Loop counters
1297  INTEGER :: LC1
1298 
1299  INTEGER :: lPROC
1300 
1301  INTEGER, ALLOCATABLE :: lBUF_I(:)
1302  INTEGER, ALLOCATABLE :: lCOUNT(:)
1303 
1304  allocate(iprocbuf(pproccnt))
1305  allocate(irootbuf(prootcnt))
1306 
1307  idispls = pdispls
1308  iscr_recvcnt = precv
1309  iscattercnts = pscatter
1310 
1311  IF(bdist_io) THEN
1312  allocate(lbuf_i(pin_count))
1313  CALL in_bin_512i(rdes_unit, lbuf_i, pin_count, lnext_rec)
1314  DO lc1=1,pin_count
1315  IF(lbuf_i(lc1) == 1) THEN
1316  output_l(lc1) = .true.
1317  ELSE
1318  output_l(lc1) = .false.
1319  ENDIF
1320  ENDDO
1321  deallocate(lbuf_i)
1322  ELSE
1323  IF(mype == pe_io) THEN
1324  allocate(lbuf_i(pin_count))
1325  allocate(lcount(0:numpes-1))
1326 
1327  CALL in_bin_512i(rdes_unit, lbuf_i, pin_count, lnext_rec)
1328 
1329  lcount = 0
1330  DO lc1=1, pin_count
1331  lproc = prestartmap(lc1)
1332  lcount(lproc) = lcount(lproc) + 1
1333  irootbuf(idispls(lproc) + lcount(lproc)) = lbuf_i(lc1)
1334  ENDDO
1335 
1336  deallocate(lbuf_i)
1337  deallocate(lcount)
1338  ENDIF
1339  CALL desmpi_scatterv(ptype=1)
1340  DO lc1=1, pip
1341  IF(iprocbuf(lc1) == 1) THEN
1342  output_l(lc1) = .true.
1343  ELSE
1344  output_l(lc1) = .false.
1345  ENDIF
1346  ENDDO
1347  ENDIF
1348 
1349  deallocate(iprocbuf)
1350  deallocate(irootbuf)
1351 
1352  RETURN
1353  END SUBROUTINE read_res_parray_1l
1354 
1355 
1356 !``````````````````````````````````````````````````````````````````````!
1357 ! Subroutine: READ_RES_DES_1I !
1358 ! !
1359 ! Purpose: Write scalar integers to RES file. !
1360 !``````````````````````````````````````````````````````````````````````!
1361  SUBROUTINE read_res_carray_1i(lNEXT_REC, OUTPUT_I)
1363  use desmpi, only: irootbuf
1364  use desmpi, only: iprocbuf
1365  use compar, only: numpes
1366  use discretelement, only: neigh_num
1367  USE in_binary_512i
1368 
1369  IMPLICIT NONE
1370 
1371  INTEGER, INTENT(INOUT) :: lNEXT_REC
1372  INTEGER, INTENT(OUT) :: OUTPUT_I(:)
1373 
1374 ! Loop counters
1375  INTEGER :: LC1
1376 
1377  INTEGER :: lPROC
1378 
1379  INTEGER, ALLOCATABLE :: lBUF_I(:)
1380  INTEGER, ALLOCATABLE :: lCOUNT(:)
1381 
1382 
1383  allocate(iprocbuf(cproccnt))
1384  allocate(irootbuf(crootcnt))
1385 
1386  idispls = cdispls
1387  iscr_recvcnt = crecv
1388  iscattercnts = cscatter
1389 
1390  IF(bdist_io) THEN
1391  CALL in_bin_512i(rdes_unit, output_i, cin_count, lnext_rec)
1392  ELSE
1393  IF(mype == pe_io) THEN
1394  allocate(lbuf_i(cin_count))
1395  allocate(lcount(0:numpes-1))
1396 
1397  CALL in_bin_512i(rdes_unit, lbuf_i, cin_count, lnext_rec)
1398 
1399  lcount = 0
1400  DO lc1=1, cin_count
1401  lproc = crestartmap(lc1)
1402  lcount(lproc) = lcount(lproc) + 1
1403  irootbuf(idispls(lproc) + lcount(lproc)) = lbuf_i(lc1)
1404  ENDDO
1405 
1406  deallocate(lbuf_i)
1407  deallocate(lcount)
1408  ENDIF
1409  CALL desmpi_scatterv(ptype=1)
1410  DO lc1=1, neigh_num
1411  output_i(lc1) = iprocbuf(lc1)
1412  ENDDO
1413  ENDIF
1414 
1415  deallocate(iprocbuf)
1416  deallocate(irootbuf)
1417 
1418  RETURN
1419  END SUBROUTINE read_res_carray_1i
1420 
1421 
1422 !``````````````````````````````````````````````````````````````````````!
1423 ! Subroutine: READ_RES_cARRAY_1D !
1424 ! !
1425 ! Purpose: Write scalar integers to RES file. !
1426 !``````````````````````````````````````````````````````````````````````!
1427  SUBROUTINE read_res_carray_1d(lNEXT_REC, OUTPUT_D)
1429  use compar, only: numpes
1430  use discretelement, only: neigh_num
1431  use desmpi, only: drootbuf
1432  use desmpi, only: dprocbuf
1433  USE in_binary_512
1434 
1435  IMPLICIT NONE
1436 
1437  INTEGER, INTENT(INOUT) :: lNEXT_REC
1438  DOUBLE PRECISION, INTENT(OUT) :: OUTPUT_D(:)
1439 
1440 ! Loop counters
1441  INTEGER :: LC1
1442 
1443  INTEGER :: lPROC
1444 
1445  DOUBLE PRECISION, ALLOCATABLE :: lBUF_D(:)
1446  INTEGER, ALLOCATABLE :: lCOUNT(:)
1447 
1448 
1449  allocate(dprocbuf(cproccnt))
1450  allocate(drootbuf(crootcnt))
1451 
1452  idispls = cdispls
1453  iscr_recvcnt = crecv
1454  iscattercnts = cscatter
1455 
1456 
1457  IF(bdist_io) THEN
1458  CALL in_bin_512(rdes_unit, output_d, cin_count, lnext_rec)
1459  ELSE
1460  IF(mype == pe_io) THEN
1461  allocate(lbuf_d(cin_count))
1462  allocate(lcount(0:numpes-1))
1463 
1464  CALL in_bin_512(rdes_unit, lbuf_d, cin_count, lnext_rec)
1465 
1466  lcount = 0
1467  DO lc1=1, cin_count
1468  lproc = crestartmap(lc1)
1469  lcount(lproc) = lcount(lproc) + 1
1470  drootbuf(idispls(lproc) + lcount(lproc)) = lbuf_d(lc1)
1471  ENDDO
1472 
1473  deallocate(lbuf_d)
1474  deallocate(lcount)
1475  ENDIF
1476  CALL desmpi_scatterv(ptype=2)
1477  DO lc1=1, neigh_num
1478  output_d(lc1) = dprocbuf(lc1)
1479  ENDDO
1480  ENDIF
1481 
1482  deallocate(dprocbuf)
1483  deallocate(drootbuf)
1484 
1485  RETURN
1486  END SUBROUTINE read_res_carray_1d
1487 
1488 
1489 !``````````````````````````````````````````````````````````````````````!
1490 ! Subroutine: READ_RES_pARRAY_1L !
1491 ! !
1492 ! Purpose: Write scalar integers to RES file. !
1493 !``````````````````````````````````````````````````````````````````````!
1494  SUBROUTINE read_res_carray_1l(lNEXT_REC, OUTPUT_L)
1496  use compar, only: numpes
1497  use discretelement, only: neigh_num
1498  use desmpi, only: irootbuf
1499  use desmpi, only: iprocbuf
1500  USE in_binary_512i
1501 
1502  IMPLICIT NONE
1503 
1504  INTEGER, INTENT(INOUT) :: lNEXT_REC
1505  LOGICAL, INTENT(OUT) :: OUTPUT_L(:)
1506 
1507 ! Loop counters
1508  INTEGER :: LC1
1509 
1510  INTEGER :: lPROC
1511 
1512  INTEGER, ALLOCATABLE :: lBUF_I(:)
1513  INTEGER, ALLOCATABLE :: lCOUNT(:)
1514 
1515  allocate(iprocbuf(cproccnt))
1516  allocate(irootbuf(crootcnt))
1517 
1518  idispls = cdispls
1519  iscr_recvcnt = crecv
1520  iscattercnts = cscatter
1521 
1522  IF(bdist_io) THEN
1523  allocate(lbuf_i(cin_count))
1524  CALL in_bin_512i(rdes_unit, lbuf_i, cin_count, lnext_rec)
1525  DO lc1=1,cin_count
1526  IF(lbuf_i(lc1) == 1) THEN
1527  output_l(lc1) = .true.
1528  ELSE
1529  output_l(lc1) = .false.
1530  ENDIF
1531  ENDDO
1532  deallocate(lbuf_i)
1533  ELSE
1534  IF(mype == pe_io) THEN
1535  allocate(lbuf_i(cin_count))
1536  allocate(lcount(0:numpes-1))
1537 
1538  CALL in_bin_512i(rdes_unit, lbuf_i, cin_count, lnext_rec)
1539 
1540  lcount = 0
1541  DO lc1=1, cin_count
1542  lproc = crestartmap(lc1)
1543  lcount(lproc) = lcount(lproc) + 1
1544  irootbuf(idispls(lproc) + lcount(lproc)) = lbuf_i(lc1)
1545  ENDDO
1546 
1547  deallocate(lbuf_i)
1548  deallocate(lcount)
1549  ENDIF
1550  CALL desmpi_scatterv(ptype=1)
1551  DO lc1=1, neigh_num
1552  IF(iprocbuf(lc1) == 1) THEN
1553  output_l(lc1) = .true.
1554  ELSE
1555  output_l(lc1) = .false.
1556  ENDIF
1557  ENDDO
1558  ENDIF
1559 
1560  deallocate(iprocbuf)
1561  deallocate(irootbuf)
1562 
1563  RETURN
1564  END SUBROUTINE read_res_carray_1l
1565 
1566  END MODULE read_res1_des
integer, dimension(:), allocatable istart1_all
Definition: compar_mod.f:65
integer, dimension(:), allocatable kstart1_all
Definition: compar_mod.f:65
logical dmp_log
Definition: funits_mod.f:6
subroutine desmpi_scatterv(ptype, pdebug)
logical bdist_io
Definition: cdist_mod.f:4
subroutine finl_err_msg
integer, dimension(:), allocatable kend1_all
Definition: compar_mod.f:65
integer open_n1
Definition: machine_mod.f:5
double precision, dimension(:), allocatable dprocbuf
Definition: desmpi_mod.f:42
subroutine read_res_des_0i(lNEXT_REC, INPUT_I)
subroutine in_bin_512(IUNIT, ARRAY, N, NEXT_REC)
subroutine desmpi_gatherv(ptype, pdebug)
integer, dimension(:), allocatable irootbuf
Definition: desmpi_mod.f:43
subroutine, public finl_read_res_des
subroutine, public read_par_col(lNEXT_REC)
subroutine neighbor_grow(new_neigh_max)
subroutine read_res_parray_1i(lNEXT_REC, OUTPUT_I)
integer numpes
Definition: compar_mod.f:24
subroutine read_res_des_1l(lNEXT_REC, INPUT_L)
subroutine init_err_msg(CALLER)
integer pe_io
Definition: compar_mod.f:30
subroutine read_res_parray_1b(lNEXT_REC, OUTPUT_B)
integer kmax1
Definition: geometry_mod.f:58
integer imax1
Definition: geometry_mod.f:54
Definition: cdist_mod.f:2
subroutine read_res_parray_1d(lNEXT_REC, OUTPUT_D)
integer, dimension(:), allocatable iprocbuf
Definition: desmpi_mod.f:44
double precision, dimension(:,:), allocatable dpar_pos
Definition: desmpi_mod.f:58
subroutine, public read_par_pos(lNEXT_REC)
integer jmax1
Definition: geometry_mod.f:56
integer, dimension(:), allocatable jstart1_all
Definition: compar_mod.f:65
logical no_k
Definition: geometry_mod.f:28
subroutine read_res_des_1i(lNEXT_REC, INPUT_I)
integer jmin1
Definition: geometry_mod.f:42
logical do_k
Definition: geometry_mod.f:30
subroutine, public init_read_res_des(BASE, lVERSION, lNEXT_REC)
integer mype
Definition: compar_mod.f:24
subroutine read_res_carray_1l(lNEXT_REC, OUTPUT_L)
integer, dimension(:), allocatable idispls
Definition: desmpi_mod.f:46
subroutine read_res_des_0d(lNEXT_REC, INPUT_D)
integer, dimension(:), allocatable jend1_all
Definition: compar_mod.f:65
subroutine in_bin_512i(IUNIT, ARRAY, NN, NEXT_REC)
subroutine map_carray_to_proc(lCOL_CNT)
subroutine map_parray_to_proc(lPAR_CNT)
character(len=line_length), dimension(line_count) err_msg
subroutine global_to_loc_col
subroutine read_res_carray_1i(lNEXT_REC, OUTPUT_I)
integer iscr_recvcnt
Definition: desmpi_mod.f:50
subroutine read_res_parray_1l(lNEXT_REC, OUTPUT_L)
subroutine scatter_par_pos(lPAR_CNT)
subroutine, public particle_grow(new_max_pip)
subroutine des_restart_ghost
subroutine read_res_des_0l(lNEXT_REC, OUTPUT_L)
double precision, dimension(:), allocatable drootbuf
Definition: desmpi_mod.f:41
integer imin1
Definition: geometry_mod.f:40
subroutine read_res_des_1d(lNEXT_REC, INPUT_D)
integer kmin1
Definition: geometry_mod.f:44
integer, dimension(:), allocatable iend1_all
Definition: compar_mod.f:65
subroutine flush_err_msg(DEBUG, HEADER, FOOTER, ABORT, LOG, CALL_TREE)
integer, dimension(:), allocatable iscattercnts
Definition: desmpi_mod.f:47
subroutine read_res_carray_1d(lNEXT_REC, OUTPUT_D)