The TELEMAC-MASCARET system  trunk
couple_mod.F
Go to the documentation of this file.
1  MODULE couple_mod
2 !******************************************************************
3 ! THAT MODULE CONTAINS THE SUBROUTINES NEEDED TO EXCHANGE VALUES OF VARIABLE
4 ! BETWEEN TWO MODULES (TILL NOW TELEMAC2D AND TOMAWAC) WHEN THEY DEAL
5 ! WITH DIFFERENT MESH.
6 ! ASSUMPTIONS:
7 ! SAME NUMBER OF PROCESSES ON BOTH COUPLED MODELS
8 !******************************************************************
9 
10  USE bief
14 
15  TYPE couple_data_type
16  ! RECEIVER DATA
17 
18  ! SENDER DATA
19  INTEGER, POINTER, DIMENSION(:,:) :: send_list
20  INTEGER, POINTER, DIMENSION(:) :: npoin_all
21 
22  ! LIST WITH FOR EACH PROCESS
23  ! LOCAL NODE ID WHERE TO GET DATA FROM FOR SENDING
24  INTEGER, POINTER, DIMENSION(:,:) :: send_map
25 
26  ! LIST WITH FOR EACH PROCESS
27  ! LOCAL NODE ID WHERE TO PUT DATA THAT IS RECEIVED
28  ! THIRD DIMENSION IS USED TO HAVE INFLUENCE OF MULTIPLE POINTS.
29  ! E.G. FOR INTERPOLATION
30  INTEGER, POINTER, DIMENSION(:,:,:) :: recv_map
31 
32  !NUMBER OF POINTS TO SEND TO OTHER PROCESSES
33  INTEGER, POINTER, DIMENSION(:) :: poin2send
34  !NUMBER OF POINTS TO SRECEIVE FROM OTHER PROCESSES
35  INTEGER, POINTER, DIMENSION(:) :: poin2recv
36 
37  ! MAXIMUM NUMBER OF POINTS ON ANY PROCESS
38  INTEGER:: maxpoin
39  ! NUMBER OF POINTS ON EACH PROCESS SENDING DATA
40  INTEGER, POINTER, DIMENSION(:) :: send_npoin
41  !GLOBAL NODE NUMBER OF THE SENDER
42  INTEGER, POINTER, DIMENSION(:) :: send_knolg
43 
44  !NUMBER OF PROCCESS TO SEND TO (INCLUDING LOCAL)
45  INTEGER :: np_send
46  !NUMBRE OF PROCESSES TO RECEIVE FROM (INCLUDING LOCAL)
47  INTEGER :: np_recv
48  !NUMBER OF PROCCESS TO SEND TO (EXCLUDING LOCAL)
49  INTEGER :: np_send_noloc
50  !NUMBRE OF PROCESSES TO RECEIVE FROM (EXCLUDING LOCAL)
51  INTEGER :: np_recv_noloc
52 
53  !BUFFER FOR SENDING DATA; FIRST DIMENSION: ID; SECOND DIMENSION: PROCESS
54  DOUBLE PRECISION, POINTER, DIMENSION(:,:) :: send_buf
55  !BUFFER FOR RECEIVING DATA; FIRST DIMENSION: ID; SECOND DIMENSION: PROCESS
56  DOUBLE PRECISION, POINTER, DIMENSION(:,:) :: recv_buf
57  !LIST OF MPI_REQUEST FOR MPI WAIT_ALL
58  INTEGER, POINTER, DIMENSION(:) :: reqlist
59 
60  !MAXIMUM NUMBER OF NODES USED TO CALCULATE VALUES (USING INTERPOLATION)
61  INTEGER :: npp
62  !INTERPOLATION WEIGHTS
63  DOUBLE PRECISION, POINTER, DIMENSION(:,:) :: weights
64 
65  END TYPE
66 
67  !RECV_LIST: NPX2 LIST WITH IN THE FIRST COLUMN THE LOCAL POINT NUMBER
68  ! ON THE SENDER AND ON THE SECOND COLUMN THE PROCESS ID
69 
70  type(couple_data_type), ALLOCATABLE, DIMENSION(:) :: cpld
71  INTEGER :: nrcouple
72 ! MAXIMUM OF MODULES COUPLING 2 ARE NEEDED FOR THE MOMENT
73  INTEGER, PARAMETER :: maxcouple = 4
74 ! MAXIMUM OF VARIABLES TO EXCHANGE
75  INTEGER, PARAMETER :: maxvar = 10
76 ! MAXIMUM OF POINTS TO INTERPOLATE ON A POINT ON THE OTHER MESH.
77  INTEGER, PARAMETER :: maxnpp = 20
78 
79  LOGICAL :: do_couple = .false.
80 
81  SAVE
82  PRIVATE
83 
86 
87  CONTAINS
88 
89 ! **********************
90  SUBROUTINE init_couple
91 ! **********************
92  &()
93 !
94 !***********************************************************************
95 !BRIEF CONSTRUCTOR FOR COUPLING ROUTINE
96 !
97 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
98 
99  IMPLICIT NONE
100 !
101 !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
102  INTEGER :: ICOUPLE, IERR
103 !
104 !-----------------------------------------------------------------------
105 !
106 !INITIALIZE COUPLING DATA
107 
108  do_couple = .true.
109  nrcouple = 0
110  ALLOCATE(cpld(maxcouple),stat=ierr)
111  CALL check_allocate(ierr,'CPLD')
112 
113  !TODO CHECK IF NEEDED
114  DO icouple=1,maxcouple
115  ALLOCATE(cpld(icouple)%SEND_NPOIN(max(ncsize,1)),stat=ierr)
116  CALL check_allocate(ierr,'SEND_NPOIN')
117  ENDDO
118 !
119 !-----------------------------------------------------------------------
120 !
121  RETURN
122  END SUBROUTINE
123 
124 ! **********************
125  SUBROUTINE add_sender
126 ! **********************
127  &(mesh_send,cid)
128 !
129 !***********************************************************************
130 !
131 !BRIEF .
132 !
133 !NOTE: SENDER MUST BE ADDED BEFORE RECIEVER IS ADDED
134 !
135 
136 !
137 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
138 !| CID |-->| ID OF THE COUPLING (STARTS AT 1)
139 !| MESH_SEND |-->| MESH (LOCAL) OF THE SENDER
140 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
141 
142  IMPLICIT NONE
143 !
144 !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
145 !
146  INTEGER , INTENT(IN) :: CID
147  type(bief_mesh), INTENT(IN) :: mesh_send
148 !
149 !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
150 
151  INTEGER :: NPOIN, IERR , IPOIN, IPROC, ITAG, IREQ
152  INTEGER , DIMENSION(1) :: SEND_BUF
153  INTEGER , DIMENSION(:), ALLOCATABLE :: RECV_BUF
154 !
155 !-----------------------------------------------------------------------
156 !
157  ALLOCATE(cpld(cid)%REQLIST(max(ncsize,1)-1),stat=ierr)
158  CALL check_allocate(ierr,'REQLIST')
159 
160  ALLOCATE (recv_buf(max(ncsize,1)),stat=ierr)
161  CALL check_allocate(ierr,'RECV_BUF')
162  recv_buf = 0
163  !COUNT NUMBER OF COUPLINGS
164  nrcouple = nrcouple +1
165  npoin = mesh_send%NPOIN
166 
167  !ADD NUMBER OF POINTS OF SENDER TO ALL PROCESSES
168  send_buf(1) = npoin
169 
170 #if defined (HAVE_MPI)
171  IF (ncsize.GT.1) THEN
172  CALL mpi_allgather(send_buf, 1, mpi_integer, recv_buf, 1,
173  & mpi_integer, comm, ierr)
174  ELSE
175  recv_buf(1) = send_buf(1)
176  ENDIF
177 #else
178  recv_buf(1) = send_buf(1)
179 #endif
180 
181  IF (ierr.NE.0) THEN
182  WRITE (lu,*) 'ALL TO ALL PROBLEM IN ADD_SENDER'
183  CALL plante(1)
184  ENDIF
185 
186 
187  IF (ncsize.GT.1) THEN
188  CALL p_sync
189  ENDIF
190 
191  cpld(cid)%SEND_NPOIN(1:max(ncsize,1)) = recv_buf(1:max(ncsize,1))
192  DEALLOCATE (recv_buf)
193  cpld(cid)%MAXPOIN = maxval(cpld(cid)%SEND_NPOIN(1:max(ncsize,1)))
194 
195  ! SAVE GLOBAL POINT NUMBERS
196 
197  ALLOCATE(cpld(cid)%SEND_KNOLG(npoin),stat=ierr)
198  CALL check_allocate(ierr,'SEND_KNOLG')
199  IF (ncsize.GT.1) THEN
200  DO ipoin = 1,npoin
201  cpld(cid)%SEND_KNOLG(ipoin)=mesh_send%KNOLG%I(ipoin)
202  ENDDO
203  ELSE
204  ! NOT SURE IF THIS IS NEEDED
205  DO ipoin = 1,npoin
206  cpld(cid)%SEND_KNOLG(ipoin)= ipoin
207  ENDDO
208  ENDIF
209 
210  ! SEND GLOBAL POINT NUMBERS TO ALL OTHER PROCS
211  ! ALREADY WORKS ON 1 PROCESSOR
212  ireq = 0
213  DO iproc = 0,max(ncsize,1)-1
214  IF (iproc.EQ.ipid) THEN
215  cycle
216  ENDIF
217  itag = ipid+iproc*ncsize
218  ireq = ireq+1
219  CALL p_iwriti(cpld(cid)%SEND_KNOLG,npoin,
220  & iproc,itag,cpld(cid)%REQLIST(ireq))
221  ENDDO
222 
223  RETURN
224  END SUBROUTINE
225 
226 !-----------------------------------------------------------------------
227 !
228 ! ***********************
229  SUBROUTINE read_recv
230 ! ***********************
231  & (file_recv,recv_var,cid,npoin,send_node,npp)
232 !
233 !***********************************************************************
234 !
235 !BRIEF READS THE VARIABLE(S) IN THE SELAFIN CONTAINING THE MAPPING
236 ! BETWEEN TWO COUPLED MODELS
237 !
238 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
245 
246 
247 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
248 
249  IMPLICIT NONE
250 !
251 !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
252 !
253  INTEGER , INTENT(IN) :: CID, NPOIN
254  TYPE(bief_file) , INTENT(IN) :: FILE_RECV
255  CHARACTER(LEN=16), INTENT(IN) :: RECV_VAR
256  DOUBLE PRECISION, INTENT(OUT), DIMENSION(:,:), ALLOCATABLE ::
257  & send_node
258  INTEGER, INTENT(INOUT) :: NPP
259  CHARACTER(LEN=2) :: STRI
260  CHARACTER(LEN=16), ALLOCATABLE :: VAR_LIST(:)
261  CHARACTER(LEN=16), ALLOCATABLE :: UNIT_LIST(:)
262  CHARACTER(LEN=16) :: VARNAME
263 !
264 !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
265  INTEGER :: IERR, NVAR, IVAR, INUM, I, INDVAR, IPOIN, NRFOUND
266  DOUBLE PRECISION :: TMP
267 
268  ! DETERMINE NUMBER OF POINTS USED IN INTERPOLATIONS (FROM FIND_VARIABLE)
269 
270  ! READ VARIABLE NAMES FROM SLF FILE
271  CALL get_data_nvar(file_recv%FMT,file_recv%LU,nvar,ierr)
272  CALL check_call(ierr, 'FIND_VARIABLE:GET_DATA_NVAR')
273  ALLOCATE(var_list(nvar),stat=ierr)
274  ALLOCATE(unit_list(nvar),stat=ierr)
275  CALL check_allocate(ierr, 'VAR_LIST')
276  CALL get_data_var_list(file_recv%FMT,file_recv%LU,nvar,
277  & var_list,unit_list,ierr)
278  CALL check_call(ierr, 'FIND_VARIABLE:GET_DATA_VAR_LIST')
279 
280  ! LOOK FOR SPACE IN VARIABLE NAME
281  inum = 0
282  DO i=1,16
283  IF (recv_var(i:i).EQ.' ') THEN
284  inum = i
285  EXIT
286  ENDIF
287  ENDDO
288  IF (inum.EQ.0) THEN
289  WRITE (lu,*) 'INVALID VARIABLE NAME FOR COUPLING: ', recv_var
290  CALL plante (1)
291  ENDIF
292  nrfound = 0
293  DO ivar = 1,nvar
294  IF (var_list(ivar)(1:inum-1).EQ.recv_var(1:inum-1).AND.
295  & var_list(ivar)(inum:inum).NE. 'W') THEN
296  nrfound = nrfound + 1
297  ENDIF
298  ENDDO
299  IF (nrfound.EQ.0) THEN
300  WRITE (lu,*) 'ERROR: COUPLE_MOD NO COUPLING INFO FOR ',
301  & recv_var
302  CALL plante(1)
303  ENDIF
304 
305 
306  ! LOOK FOR THE HIGHEST VARIABLE NUMBER.
307  ! IT IS ASSUMED THAT VARIABLES ARE NUMBERED CONTINUOUSLY
308  ! THIS IS CHECKED LATER WHEN READING THE VARIABLES
309  npp = 0
310  DO ivar = 1,nvar
311  IF (var_list(ivar)(1:inum-1).EQ.recv_var(1:inum-1).AND.
312  & var_list(ivar)(inum:inum).NE. 'W') THEN
313  READ (var_list(ivar)(inum:inum+1),*) indvar
314  IF (indvar.GT.maxnpp .OR. indvar.LE.0) THEN
315  WRITE (lu,*) 'INVALID NUMBER FOR ',recv_var,': ',indvar
316  CALL plante (1)
317  ENDIF
318  npp = max(npp,indvar)
319  ENDIF
320  ENDDO
321 
322  DEALLOCATE(var_list)
323  DEALLOCATE(unit_list)
324 
325 !----------------------------------------------------------------------
326 ! ALLOCATE MEMORY FOR WEIGHTS AND SEND NODES
327 
328  ALLOCATE(send_node(npoin,npp),stat=ierr)
329  CALL check_allocate(ierr,'SEND_NODE')
330 
331  ALLOCATE(cpld(cid)%WEIGHTS(npoin,npp),stat=ierr)
332  CALL check_allocate(ierr,'WEIGHTS')
333 
334 
335  ! LOOP OVER ALL NEEDED VARIABLES
336  DO i=1,npp
337  WRITE(stri,'(I2.2)') i
338  varname = recv_var(1:inum-1)//stri
339  ! READ ID FROM WHERE TO RECEIVE DATA (GLOBAL ID OF THE SENDER)
340  CALL find_variable(file_recv%FMT,file_recv%LU,varname,
341  & send_node(:,i),npoin,ierr)
342  IF (ierr.NE.0) THEN
343  WRITE (lu,*) 'VARIABLE ',varname, ' CANNOT BE READ '
344  CALL plante(1)
345  ENDIF
346 
347  ! READ INTERPOLATION WEIGHTS
348  varname = recv_var(1:inum-1)//'WTS'//stri
349  CALL find_variable(file_recv%FMT,file_recv%LU,varname,
350  & cpld(cid)%WEIGHTS(:,i),npoin,ierr)
351  IF (ierr.NE.0) THEN
352  WRITE (lu,*) 'VARIABLE ',varname, ' CANNOT BE READ '
353  CALL plante(1)
354  ENDIF
355  ENDDO
356  ! CHECK WEIGHTS SUM TO ONE IN CASE NO DEFAULT IS USED
357  DO ipoin=1,npoin
358  IF (any(send_node(ipoin,:).GT.0)) THEN
359  tmp = sum(cpld(cid)%WEIGHTS(ipoin,:))
360  ! NOTE THRESHOLD IS HIGH. PROBABLY DUE TO SINGLE PRECISION IN SLF FILE
361  IF (abs(tmp-1.0d0).GT.1.0d-4) THEN
362  WRITE (lu,*) 'WRONG WEIGHTS IN POINT ', npoin
363  WRITE (lu,*) 'WEIGHST ARE: ', cpld(cid)%WEIGHTS(ipoin,:)
364  CALL plante(1)
365  ELSE ! MAKE SURE THEY ARE ALSO ACCURATE IN DOUBLE PRECISION
366  cpld(cid)%WEIGHTS(ipoin,:)=cpld(cid)%WEIGHTS(ipoin,:)/tmp
367  ENDIF
368  ENDIF
369  ENDDO
370 
371  RETURN
372  END SUBROUTINE
373 !
374 !-----------------------------------------------------------------------
375 !
376 ! ***********************
377  SUBROUTINE add_receiver
378 ! ***********************
379  & (mesh_recv,file_recv,recv_var,cid)
380 !
381 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
382 !| MESH_RECV |-->| MESH (LOCAL) OF THE RECEIVER
383 !| FILE_RECV |-->| FILE WITH INFORMATION FROM WHERE TO RECEIVE DATA
384 !| RECV_VAR |-->| NAME OF VARIABLE WHICH CONTAINS THE NODE NR OF THE SENDER
385 !| CID |-->| ID OF THE COUPLING (STARTS AT 1)
386 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
387 
388  IMPLICIT NONE
389 !
390 !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
391 !
392  INTEGER , INTENT(IN) :: CID
393  TYPE(bief_file) , INTENT(IN) :: FILE_RECV
394  TYPE(bief_mesh), INTENT(IN) :: MESH_RECV
395  CHARACTER(LEN=16), INTENT(IN) :: RECV_VAR
396 !
397 !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
398  INTEGER :: IERR, NPOIN , IPROC, IP_S, IP_R, IP_P
399  INTEGER :: MAXP, IPOIN, NP, ITMP, ITAG , IREQ, NPR,NPS, NPP
400 
401  INTEGER, ALLOCATABLE, DIMENSION(:) :: NSEND
402 
403  DOUBLE PRECISION, ALLOCATABLE, DIMENSION(:,:) :: SEND_NODE
404  INTEGER, ALLOCATABLE, DIMENSION(:,:) :: TMP_SEND, LOC_SEND_MAP
405  LOGICAL, ALLOCATABLE, DIMENSION(:,:) :: DO_SEND
406  INTEGER, ALLOCATABLE, DIMENSION(:) :: TMP_KNOLG
407  LOGICAL, ALLOCATABLE, DIMENSION(:) :: TMP_LOG
408 
409  ! LIST WITH FOR EACH POINT, FROM WHERE TO RECEIVE DATA
410  !1.) LOCAL NODE NR
411  !2.) PROCES ID
412  INTEGER, ALLOCATABLE, DIMENSION(:,:,:) :: RECV_LIST
413 !
414 !-----------------------------------------------------------------------
415 !
416 
417  npoin = mesh_recv%NPOIN
418  maxp = cpld(cid)%MAXPOIN
419 
420  ! READ WEIGHTS AND NODEINDICES FROM SELAFIN FILE
421  CALL read_recv(file_recv,recv_var,cid,npoin,send_node,npp)
422  cpld(cid)%NPP = npp
423 
424  !ALLOCATE DATA
425  ALLOCATE(recv_list(npoin,2,npp),stat=ierr)
426  CALL check_allocate(ierr,'RECV_LIST')
427  recv_list = 0
428 
429  ALLOCATE(tmp_knolg(maxp),stat=ierr)
430  CALL check_allocate(ierr,'TMP_KNOLG')
431 
432 ! FIND CORRESPONDING LOCAL NUMBERS ON SENDER
433 ! (ONLY WORKS IF SENDER IS ALREADY ADDED)
434 
435  recv_list = 0
436  DO iproc = 0,max(ncsize,1)-1
437  ! RECEIVE KNOLG FROM SENDER
438  ! BLOCKING RECEIVE TO LIMIT AMOUNT OF DATA
439  np = cpld(cid)%SEND_NPOIN(iproc+1)
440  IF (iproc.NE.ipid) THEN
441  itag = ipid*ncsize+iproc
442  !DEFACTO BLOCKING RECEIVE
443  CALL p_ireadi(tmp_knolg,np,
444  & iproc,itag,cpld(cid)%REQLIST(1))
445  CALL p_wait_paraco(cpld(cid)%REQLIST(1:1),1)
446  ELSE
447  ! DATA IS ALREADY ON THE SAME PROCESS
448  tmp_knolg(1:np) = cpld(cid)%SEND_KNOLG(1:np)
449  ENDIF
450 
451  !FIND MATCHING POINTS
452  DO ip_p = 1,npp
453  DO ip_r = 1,npoin
454  DO ip_s = 1,np
455  IF (nint(send_node(ip_r,ip_p)).EQ.tmp_knolg(ip_s)) THEN
456  recv_list(ip_r,1,ip_p) = ip_s
457  recv_list(ip_r,2,ip_p) = iproc+1
458  EXIT
459  ENDIF
460  ENDDO !IP_R
461  ENDDO !IP_S
462  ENDDO ! IP_P
463  ENDDO ! IPROC
464 
465 !----------------------------------------------------------------------
466 ! BUILD UP SEND LIST AND RECEIVE LIST
467 
468  !COMMUNICATED DATA
469  ALLOCATE(cpld(cid)%SEND_MAP(maxp,max(ncsize,1)),stat=ierr)
470  CALL check_allocate(ierr,'SEND_MAP')
471  ALLOCATE(loc_send_map(maxp,max(ncsize,1)),stat=ierr)
472  CALL check_allocate(ierr,'_LOC_SEND_MAP')
473  loc_send_map = 0
474 
475  ALLOCATE(cpld(cid)%RECV_MAP(max(ncsize,1),npoin,npp),stat=ierr)
476  CALL check_allocate(ierr,'RECV_MAP')
477 
478  !NUMBER OF POINTS TO COMMUNICATE
479  ALLOCATE(cpld(cid)%POIN2SEND(max(ncsize,1)),stat=ierr)
480  CALL check_allocate(ierr,'POIN2SEND')
481  ALLOCATE(cpld(cid)%POIN2RECV(max(ncsize,1)),stat=ierr)
482  CALL check_allocate(ierr,'POIN2RECV')
483 
484 
485  ALLOCATE(do_send(max(ncsize,1),maxp),stat=ierr)
486  do_send = .false.
487  ALLOCATE(tmp_send(max(ncsize,1),maxp),stat=ierr)
488  tmp_send =0
489 
490  ALLOCATE(nsend(max(ncsize,1)),stat=ierr)
491  CALL check_allocate(ierr,'NSEND')
492  nsend = 0
493 
494  cpld(cid)%POIN2SEND = 0
495  cpld(cid)%POIN2RECV = 0
496  cpld(cid)%RECV_MAP = 0
497  cpld(cid)%SEND_MAP = 0
498 
499 !----------------------------------------------------------------------
500  ! STORE NUMBER OF POINTS
501  ! THIS VARIABLE MAPS NUMBER OF POINTS ON SENDER TO NUMBER OF POINTS ON RECEIVER
502 
503  !LOOK FOR EACH POINT WHERE IT COMES FROM
504  DO ip_p = 1,npp
505  DO ip_r=1,npoin
506  ! VALUES FROM GLOBAL LIST
507  ip_s = recv_list(ip_r,1,ip_p)
508  iproc = recv_list(ip_r,2,ip_p)
509  IF (ip_s.GT.0) THEN
510  IF (.NOT.do_send(iproc,ip_s)) THEN
511  !POINT NOT YET SEND TO THIS PROCESS. ADD TO THE LISTS
512  do_send(iproc,ip_s) = .true.
513  nsend(iproc) = nsend(iproc)+1
514  cpld(cid)%RECV_MAP(iproc,ip_r,ip_p) = nsend(iproc)
515  ! NOTE ORDER OF ARGUMENTS IS OPPOSITE IN LOC_SEND_MAP
516  ! THIS IS NEEDED FOR MPI_SCATTER LATER
517  loc_send_map(nsend(iproc),iproc) = ip_s
518  tmp_send(iproc,ip_s) = nsend(iproc)
519  ELSE
520  ! POINT IS ALREADY ON THE LIST. LOOK UP ITS ID
521  cpld(cid)%RECV_MAP(iproc,ip_r,ip_p) = tmp_send(iproc,ip_s)
522  ENDIF
523  ENDIF
524  ENDDO !IP_R
525  ENDDO !IP_P
526 
527  ! STORE NUMBER OF POINTS
528  DO iproc = 1,max(ncsize,1)
529  cpld(cid)%POIN2RECV(iproc) = nsend(iproc)
530  ENDDO
531 
532 !----------------------------------------------------------------------
533 
534  ! COMMUNICATE NUMBER OF POINTS TO OTHER PROCESSES
535 #if defined (HAVE_MPI)
536  DO iproc = 0,max(ncsize,1)-1
537  CALL mpi_scatter(cpld(cid)%POIN2RECV,1,mpi_integer,
538  & cpld(cid)%POIN2SEND(iproc+1),1,mpi_integer,iproc,comm,ierr)
539  CALL p_sync()
540  ENDDO
541 
542  !NUMBER OF PROCESSES FOR COMMUNICATION
543  cpld(cid)%NP_SEND = count(cpld(cid)%POIN2SEND.GT.0)
544  cpld(cid)%NP_RECV = count(cpld(cid)%POIN2RECV.GT.0)
545  IF (cpld(cid)%POIN2SEND(ipid+1).GT.0) THEN
546  cpld(cid)%NP_SEND_NOLOC = cpld(cid)%NP_SEND - 1
547  ELSE
548  cpld(cid)%NP_SEND_NOLOC = cpld(cid)%NP_SEND
549  ENDIF
550  IF (cpld(cid)%POIN2RECV(ipid+1).GT.0) THEN
551  cpld(cid)%NP_RECV_NOLOC = cpld(cid)%NP_RECV - 1
552  ELSE
553  cpld(cid)%NP_RECV_NOLOC = cpld(cid)%NP_RECV
554  ENDIF
555 
556 #else
557  cpld(cid)%POIN2SEND(1) = cpld(cid)%POIN2RECV(1)
558  cpld(cid)%NP_SEND = 1
559  cpld(cid)%NP_RECV = 1
560 #endif
561  IF (ierr.NE.0) THEN
562  WRITE (lu,*) 'ERROR IN MPI_SCATTER POIN2SEND'
563  CALL plante(1)
564  ENDIF
565 
566 !----------------------------------------------------------------------
567 ! COMMUNICATE SEND LIST TO SENDER (DUMMY VALUES ARE ALSO COPIED)
568  ireq = 0
569  DO iproc = 0,max(ncsize,1)-1
570  np = cpld(cid)%POIN2RECV(iproc+1)
571  IF (np.GT.0) THEN
572  IF (iproc.NE.ipid) THEN
573  ireq = ireq + 1
574  itag = ipid+iproc*ncsize
575  CALL p_iwriti(loc_send_map(1:np,iproc+1),
576  & np,iproc,itag,cpld(cid)%REQLIST(ireq))
577  ENDIF
578  ENDIF
579  ENDDO
580 
581  ! RECEIVE LIST AT SENDER
582  ireq = 0
583  DO iproc = 0,max(ncsize,1)-1
584  np = cpld(cid)%POIN2SEND(iproc+1)
585  IF (np.GT.0) THEN
586  IF (iproc.NE.ipid) THEN
587  ireq = ireq + 1
588  itag = iproc+ipid*ncsize
589  CALL p_ireadi(cpld(cid)%SEND_MAP(1:np,iproc+1),np,
590  & iproc,itag,cpld(cid)%REQLIST(ireq))
591  ELSE
592  ! LOCAL COPY
593  DO ipoin = 1,np
594  cpld(cid)%SEND_MAP(ipoin,iproc+1) =
595  & loc_send_map(ipoin,iproc+1)
596  ENDDO
597  ENDIF
598  ENDIF
599  ENDDO
600 
601  IF (ncsize.GT.1) THEN
602  IF (ireq.GT.0) THEN
603  CALL p_wait_paraco(cpld(cid)%REQLIST(1:ireq),ireq)
604  ENDIF
605  ENDIF
606 
607  ! THIS P_SYNC SOLVES A SEG_FAULT; NO IDEA WHY
608  IF (ncsize.GT.1) THEN
609  CALL p_sync
610  ENDIF
611 
612 !----------------------------------------------------------------------
613 
614  !MAXIMUM NUMBER OF POINTS SEND TO THIS PROCESS
615 
616  nps = cpld(cid)%NP_SEND
617  npr = cpld(cid)%NP_RECV
618 
619  !ALLOCATE DATA FOR SENDING AND RECEIVING
620  IF (nps.GT.0) THEN
621  maxp = maxval(cpld(cid)%POIN2SEND(1:max(ncsize,1)))
622  ALLOCATE(cpld(cid)%SEND_BUF(maxvar*maxp,nps),stat=ierr)
623  cpld(cid)%SEND_BUF = -99
624  CALL check_allocate(ierr,'SEND_DATA')
625  ENDIF
626 
627  IF (npr.GT.0) THEN
628  maxp = maxval(cpld(cid)%POIN2RECV(1:max(ncsize,1)))
629  ALLOCATE(cpld(cid)%RECV_BUF(maxvar*maxp,npr),stat=ierr)
630  cpld(cid)%RECV_BUF = -999
631  CALL check_allocate(ierr,'RECV_BUF')
632  ENDIF
633 
634  !DEALLOCATE DATA THAT IS NOT NEEDED ANYMORE
635 
636  DEALLOCATE (cpld(cid)%SEND_NPOIN,stat=ierr)
637  CALL check_allocate(ierr,'DEAL:SEND_NPOIN')
638 
639  DEALLOCATE (cpld(cid)%SEND_KNOLG,stat=ierr)
640  CALL check_allocate(ierr,'DEAL:SEND_KNOLG')
641 
642  DEALLOCATE(tmp_knolg,stat=ierr)
643  CALL check_allocate(ierr,'DEAL:TMP_KNOLG')
644 
645  DEALLOCATE(send_node,stat=ierr)
646  CALL check_allocate(ierr,'DEAL:SEND_NODE')
647 
648  DEALLOCATE(recv_list,stat=ierr)
649  CALL check_allocate(ierr,'DEAL:RECV_LIST')
650 
651  DEALLOCATE(nsend,stat=ierr)
652  CALL check_allocate(ierr,'DEAL:NSEND')
653 
654  DEALLOCATE(do_send,stat=ierr)
655  CALL check_allocate(ierr,'DEAL:DO_SEND')
656 
657  DEALLOCATE(tmp_send,stat=ierr)
658  CALL check_allocate(ierr,'DEAL:TMP_SEND')
659 
660  DEALLOCATE(loc_send_map,stat=ierr)
661  CALL check_allocate(ierr,'DEAL:LOC_SEND_MAP')
662 
663  !----------------------------------
664  ! CHECK THAT ALL POINTS RECEIVE INFORMATION
665 
666  ALLOCATE(tmp_log(npoin),stat=ierr)
667  CALL check_allocate(ierr,'AL:TMPLOG')
668  tmp_log = .false.
669  DO ip_p=1,npp
670  DO iproc =1,max(ncsize,1)
671  np = cpld(cid)%POIN2RECV(iproc)
672  IF (np.GT.0) THEN
673  ! EXTRACT DATA FROM SEND STRUCTURE
674  DO ipoin = 1,npoin
675  itmp = cpld(cid)%RECV_MAP(iproc,ipoin,ip_p)
676  IF (itmp.GT.0) THEN
677  tmp_log(ipoin) = .true.
678  ENDIF
679  ENDDO
680  ENDIF
681  ENDDO
682  ENDDO
683 
684  IF (all(tmp_log)) THEN
685  WRITE (lu,*) 'ALL NODES RECEIVE INFORMATION'
686  ELSE
687  WRITE (lu,*) 'WARNING: NO INFORMATION FOR ',
688  & count(.NOT.tmp_log), ' NODES OUT OF ', npoin
689  ENDIF
690  DEALLOCATE(tmp_log,stat=ierr)
691  CALL check_allocate(ierr,'DEAL:TMPLOG')
692 
693 !
694 !-----------------------------------------------------------------------
695 !
696  RETURN
697  END SUBROUTINE
698 
699 
700 ! **********************
701  SUBROUTINE send_couple
702 ! **********************
703  &(cid,npoin,nvar,varcouple)
704 !
705 !BRIEF .
706 !
707 !
708 ! NOTES: IT IS ASSUMED THAT THE RECEIVE CALL FOLLOWS THE SEND CALL
709 ! AND THAT TWO CONSECUTIVE SENDS DO NOT OCCUR. HOWEVER, THIS IS
710 ! NOT CHECKED
711 !
712 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
717 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
718 
719  IMPLICIT NONE
720 !
721 !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
722 !
723  INTEGER , INTENT(IN) :: NPOIN, NVAR,CID
724  TYPE(bief_obj), INTENT(IN) :: VARCOUPLE
725 !
726 !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
727  INTEGER :: IPOIN, IVAR, I, ITMP, NP, IPROC,IP,IPB, DUMMY
728  INTEGER :: IREQ, ITAG , NPV, NOERR, IERR
729 
730 !
731 !-----------------------------------------------------------------------
732 
733 ! CHECK INPUT
734  IF (nvar.GT.maxvar) THEN
735  WRITE (lu,*) 'TOO MANY VARIABLES'
736  CALL plante(1)
737  ENDIF
738  IF (nvar.EQ.0) THEN
739  RETURN
740  ENDIF
741 
742 ! ALLOCATE REQLIST, AS IT IS AUTOMATICALLY DEALLOCATED BY WAIT
743  IF (ncsize.GT.1) THEN
744  ALLOCATE(cpld(cid)%REQLIST(max(ncsize,1)-1),stat=ierr)
745  CALL check_allocate(ierr,'REQLIST')
746  ENDIF
747 ! ALREADY RECEIVE THE DATA TO OPTIMIZE MPI COMMUNICATION
748 ! THE REAL RECEIVE WILL BE FINISHED BY THE MPI_WAIT CALL
749  ip = 0
750  ipb = 0
751  DO iproc =1,max(ncsize,1)
752  np = cpld(cid)%POIN2RECV(iproc)
753  npv = np*nvar
754  IF (np.GT.0) THEN
755  ipb = ipb + 1
756  IF (ipid.NE.iproc-1) THEN
757  !RECEIVE DATA (NON-BLOCKING)
758  ip = ip + 1
759  itag = (iproc-1)+ipid*ncsize
760  CALL p_iread(cpld(cid)%RECV_BUF(1:npv,ipb),npv,8,iproc-1,
761  & itag,cpld(cid)%REQLIST(ip))
762  ENDIF
763  ENDIF
764  ENDDO
765 
766  IF (ncsize.GT.1) THEN
767  CALL p_sync
768  ENDIF
769 
770  ireq = 0
771 ! ADD DATA TO SEND STRUCTURE
772  ip = 0
773  noerr = 0
774  DO iproc=1,max(ncsize,1)
775  i = 1
776  np = cpld(cid)%POIN2SEND(iproc)
777  IF (np.GT.0) THEN
778  ip = ip +1
779  DO ivar =1,nvar
780  DO ipoin=1,np
781  itmp = cpld(cid)%SEND_MAP(ipoin,iproc)
782  IF (itmp.GT.npoin.OR. itmp.LT.1) THEN
783  WRITE (lu,*) 'WRONG VALUE FOR SENDMAP: ',
784  & itmp, ' FOR ',ipoin,ivar,ip,i
785  noerr = noerr + 1
786  cycle
787  ENDIF
788  cpld(cid)%SEND_BUF(i,ip) = varcouple%ADR(ivar)%P%R(itmp)
789  i = i+1
790  ENDDO
791  ENDDO
792  ENDIF
793  ENDDO
794  IF (ncsize.GT.1) THEN
795  CALL p_sync
796  ENDIF
797 
798 ! SEND DATA (NON BLOCKING)
799  ip = 0
800  DO iproc=1,max(ncsize,1)
801  np = cpld(cid)%POIN2SEND(iproc)*nvar
802  IF (np.GT.0) THEN
803  ip = ip + 1
804  IF (iproc-1.NE.ipid) THEN
805  itag = (iproc-1)*ncsize+ipid
806  ireq = ireq+1
807  CALL p_iwrit(cpld(cid)%SEND_BUF(1:np,ip),
808  & np,8,iproc-1,itag,dummy)
809  ELSE
810  ! COPY DATA ON THE SAME PROCESSOR
811  itmp = count(cpld(cid)%POIN2RECV(1:iproc).GT.0)
812  cpld(cid)%RECV_BUF(1:np,itmp) =
813  & cpld(cid)%SEND_BUF(1:np,ip)
814  ENDIF
815  ENDIF
816  ENDDO
817 
818  ! SHUT DOWN IF THERE IS AN ERROR
819  IF (ncsize.GT.1) THEN
820  CALL p_sync
821  ENDIF
822  IF (noerr.GT.0) THEN
823  CALL plante(1)
824  ENDIF
825 !
826 !-----------------------------------------------------------------------
827 !
828  RETURN
829  END SUBROUTINE
830 !
831 !-----------------------------------------------------------------------
832 !
833 ! *************************************
834  SUBROUTINE receive_couple
835 ! *************************************
836  & (cid,npoin,nvar,varcouple,default_val)
837 !
838 !BRIEF .
839 !
840 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
846 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
847 
848  IMPLICIT NONE
849 !
850 !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
851 !
852  INTEGER ,INTENT(IN ) :: NPOIN, CID, NVAR
853  DOUBLE PRECISION, INTENT(IN), DIMENSION(NVAR), OPTIONAL ::
854  & default_val
855  type(bief_obj), INTENT(INOUT) :: varcouple
856 
857 !
858 !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
859  INTEGER :: IPROC, ITMP , NP, I, IP, IVAR , IPR, NPR
860  INTEGER :: NOERR, IPP,NPP
861  DOUBLE PRECISION :: WP
862  DOUBLE PRECISION, DIMENSION(NVAR) :: DEF_VAR
863 !-----------------------------------------------------------------------
864 !
865 ! TODO: CHECK THAT NUMBER OF VARIABLES SEND AND RECEIVED IS EQUAL
866 
867  CALL debug_info('RECVMAP-START')
868 
869 ! CHECK INPUT
870  IF (nvar.GT.maxvar) THEN
871  WRITE (lu,*) 'TOO MANY VARIABLES'
872  CALL plante(1)
873  ENDIF
874  IF (nvar.EQ.0) THEN
875  RETURN
876  ENDIF
877 
878 ! SET DEFAULT VALUES (IN CASE NO VALUE IS SPECIFIED)
879  IF (PRESENT(default_val)) THEN
880  def_var = default_val
881  ELSE
882  def_var =0.0
883  ENDIF
884 
885  DO ip = 1,npoin
886  DO ivar=1,nvar
887  varcouple%ADR(ivar)%P%R(ip) = def_var(ivar)
888  ENDDO
889  ENDDO
890 
891  npp = cpld(cid)%NPP
892 
893  ! WAIT UNTIL ALL DATA ARE RECEIVED
894  npr = cpld(cid)%NP_RECV_NOLOC
895  IF (ncsize.GT.1) THEN
896  IF (npr.GT.0) THEN
897  CALL p_wait_paraco(cpld(cid)%REQLIST(1:npr),npr)
898  ENDIF
899  ENDIF
900 
901  !UNPACK DATA
902  noerr = 0
903 
904  DO ipp = 1,npp
905  ipr = 0
906  DO iproc =1,max(ncsize,1)
907  np = cpld(cid)%POIN2RECV(iproc)
908  IF (np.GT.0) THEN
909  ipr = ipr + 1
910  ! EXTRACT DATA FROM SEND STRUCTURE
911  DO ip = 1,npoin
912  itmp = cpld(cid)%RECV_MAP(iproc,ip,ipp)
913  IF (itmp.GT.0) THEN
914  ! ERROR CHECKING
915  IF (itmp.GT.np) THEN
916  noerr = noerr + 1
917  cycle
918  ENDIF
919  wp = cpld(cid)%WEIGHTS(ip,ipp)
920  IF (ipp.EQ.1) THEN
921  DO ivar=1,nvar
922  i = itmp+(ivar-1)*np
923  varcouple%ADR(ivar)%P%R(ip) =
924  & wp*cpld(cid)%RECV_BUF(i,ipr)
925  ENDDO
926  ELSE
927  DO ivar=1,nvar
928  i = itmp+(ivar-1)*np
929  varcouple%ADR(ivar)%P%R(ip) =
930  & varcouple%ADR(ivar)%P%R(ip) +
931  & wp*cpld(cid)%RECV_BUF(i,ipr)
932  ENDDO
933  ENDIF
934  ENDIF
935  ENDDO
936  ENDIF
937  ENDDO
938  ENDDO
939 
940  ! SHUT DOWN IF THERE IS AN ERROR
941  IF (ncsize.GT.1) THEN
942  CALL p_sync
943  ENDIF
944  IF (noerr.GT.0) THEN
945  CALL plante(1)
946  ENDIF
947 
948  CALL debug_info('END UNPACK')
949 !
950 !-----------------------------------------------------------------------
951 !
952  RETURN
953  END SUBROUTINE
954 
955 ! *********************
956  SUBROUTINE end_couple
957 ! *********************
958 !
959 !BRIEF DEALLOCATE VARIABLE NEEDED FOR COUPLING
960 !
961 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
962 
963  IMPLICIT NONE
964 !
965 !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
966  INTEGER :: ICPL, IERR
967 !
968 !-----------------------------------------------------------------------
969 !
970  !DEACCLOCATE DATA FROM COUPLING STRUCTURES
971 
972  DO icpl =1,nrcouple
973  !MAPPING
974  DEALLOCATE(cpld(icpl)%POIN2RECV,stat=ierr)
975  DEALLOCATE(cpld(icpl)%POIN2SEND,stat=ierr)
976  DEALLOCATE(cpld(icpl)%SEND_MAP,stat=ierr)
977  DEALLOCATE(cpld(icpl)%RECV_MAP,stat=ierr)
978 
979  !DATA BUFFERS
980  !TODO: THESE TWO POINTERS MAY NOT BE ALLOCATED
981  DEALLOCATE(cpld(icpl)%RECV_BUF,stat=ierr)
982  DEALLOCATE(cpld(icpl)%SEND_BUF,stat=ierr)
983  DEALLOCATE(cpld(icpl)%REQLIST,stat=ierr)
984  DEALLOCATE(cpld(icpl)%WEIGHTS,stat=ierr)
985  ENDDO
986 
987  DO icpl =1,maxcouple
988  DEALLOCATE(cpld(icpl)%SEND_NPOIN,stat=ierr)
989  ENDDO
990  !
991  DEALLOCATE(cpld,stat=ierr)
992 
993 !-----------------------------------------------------------------------
994 !
995  RETURN
996  END SUBROUTINE
997 
998 !-----------------------------------------------------------------------
999  SUBROUTINE debug_info (DEBUG_STRING,DEBUG_INT)
1000 
1001 !BRIEF PRINT INFORMATION ABOUT A VARIABLE.
1002 !
1003 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1006 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1007 
1008  IMPLICIT NONE
1009 
1010  CHARACTER (LEN=*), INTENT(IN) :: DEBUG_STRING
1011  INTEGER, OPTIONAL, INTENT(IN) :: DEBUG_INT
1012  WRITE (lu,*) ''
1013  WRITE (lu,*) '***********************************************'
1014  IF (PRESENT(debug_int)) THEN
1015  WRITE (lu,*) debug_string, debug_int
1016  ELSE
1017  WRITE (lu,*) debug_string
1018  ENDIF
1019  WRITE (lu,*) '***********************************************'
1020  WRITE (lu,*)''
1021  END SUBROUTINE
1022 
1023  END MODULE couple_mod
subroutine get_data_nvar(FFORMAT, FID, NVAR, IERR)
Definition: get_data_nvar.f:7
type(couple_data_type), dimension(:), allocatable cpld
Definition: couple_mod.F:71
subroutine get_data_var_list(FFORMAT, FID, NVAR, VARLIST, UNITLIST, IERR)
subroutine p_iwrit(BUFFER, N, BYTES, DEST, ITAG, IREQ)
Definition: p_iwrit.F:7
integer, parameter maxvar
Definition: couple_mod.F:76
integer, parameter mpi_integer
integer, parameter maxnpp
Definition: couple_mod.F:78
logical, public do_couple
Definition: couple_mod.F:80
integer nrcouple
Definition: couple_mod.F:72
subroutine, public init_couple()
Definition: couple_mod.F:94
subroutine, public add_sender(MESH_SEND, CID)
Definition: couple_mod.F:129
subroutine p_iread(BUFFER, N, BYTES, SOURCE, ITAG, IREQ)
Definition: p_iread.F:6
subroutine, public send_couple(CID, NPOIN, NVAR, VARCOUPLE)
Definition: couple_mod.F:705
subroutine p_ireadi(BUFFER, NVAL, SOURCE, ITAG, IREQ)
Definition: p_ireadi.F:7
subroutine, public add_receiver(MESH_RECV, FILE_RECV, RECV_VAR, CID)
Definition: couple_mod.F:381
subroutine find_variable(FFORMAT, FID, VAR_NAME, RES, N, IERR, TIME, EPS_TIME, RECORD, TIME_RECORD, OFFSET)
Definition: find_variable.f:8
subroutine read_recv(FILE_RECV, RECV_VAR, CID, NPOIN, SEND_NODE, NPP)
Definition: couple_mod.F:233
subroutine p_wait_paraco(IBUF, NB)
Definition: p_wait_paraco.F:7
subroutine debug_info(DEBUG_STRING, DEBUG_INT)
Definition: couple_mod.F:1001
subroutine p_sync
Definition: p_sync.F:4
subroutine p_iwriti(BUFFER, NVAL, DEST, ITAG, IREQ)
Definition: p_iwriti.F:7
subroutine, public receive_couple(CID, NPOIN, NVAR, VARCOUPLE, DEFAULT_VAL)
Definition: couple_mod.F:838
integer, parameter maxcouple
Definition: couple_mod.F:74
subroutine, public end_couple
Definition: couple_mod.F:958
Definition: bief.f:3