The TELEMAC-MASCARET system  trunk
parini.f
Go to the documentation of this file.
1 ! *****************
2  SUBROUTINE parini
3 ! *****************
4 !
5  &(nhp,nhm,indpu,npoin2,nachb,nplan,mesh,nb_neighb,
6  & nb_neighb_seg,nelem2,ifapar,modass)
7 !
8 !***********************************************************************
9 ! BIEF V7P1
10 !***********************************************************************
11 !
12 !brief INITIALISES THE ARRAYS USED IN PARALLEL MODE.
13 !
14 !history N.DURAND (HRW), S.E.BOURBAN (HRW)
15 !+ 13/07/2010
16 !+ V6P0
17 !+ Translation of French comments within the FORTRAN sources into
18 !+ English comments
19 !
20 !history N.DURAND (HRW), S.E.BOURBAN (HRW)
21 !+ 21/08/2010
22 !+ V6P0
23 !+ Creation of DOXYGEN tags for automated documentation and
24 !+ cross-referencing of the FORTRAN sources
25 !
26 !history J-M HERVOUET (EDF R&D, LNHE)
27 !+ 09/05/2014
28 !+ V7P0
29 !+ Adding an allocation of BUF_SEND%I and BUF_RECV%I
30 !+ Adding an allocation of BUF_SENDI8 and BUF_RECVI8
31 !+ for I4 and I8 integer communications.
32 !
33 !history J-M HERVOUET (EDF R&D, LNHE)
34 !+ 30/07/2015
35 !+ V7P1
36 !+ FAC suppressed.
37 !
38 !history R.NHEILI (Univerte de Perpignan, DALI)
39 !+ 24/02/2016
40 !+ V7P3
41 !+ ADD ALLOCATION BUF_SEND_ERR AND BUF_RECV_ERR
42 !
43 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
44 !| IFAPAR |-->| IFAPAR(1:3,IELEM)=PROCESSOR NUMBERS BEHIND THE
45 !| | | 3 ELEMENT EDGES (NUMBERS FROM 0 TO NCSIZE-1)
46 !| | | IFAPAR(4:6,IELEM): -LOCAL- ELEMENT NUMBERS
47 !| | | BEHIND THE 3 EDGES
48 !| INDPU |<--| INDEX TABLE : IF 0: NOT AN INTERFACE POINT
49 !| | | IF NOT 0: ADDRESS IN THE LIST
50 !| | | OF BOUNDARY POINTS.
51 !| MESH |-->| MESH STRUCTURE
52 !| MODASS |-->| ASSEMBLY MODE 1: NORMAL 2: WITH INTEGERS 3: COMPENSATION
53 !| NACHB |-->| IF 'IL' IS THE LOCAL RANK OF A NEIGHBOURING
54 !| | | SUB-DOMAIN AND 'IP' ONE INTERFACE POINT
55 !| | | NACHB(IL,IP) WILL BE THE REAL NUMBER OF THIS
56 !| | | NEIGHBOURING SUB-DOMAIN
57 !| | | THE LIST IN NACHB IS ORDERED WITH THE
58 !| | | GLOBAL NUMBERS OF POINTS (HENCE THE POINTS
59 !| | | WILL BE FOUND IN THE SAME ORDER BY ALL
60 !| | | PROCESSORS)
61 !| NB_NEIGHB |<--| NUMBER OF NEIGHBOURING SUB-DOMAINS (FOR POINTS)
62 !| NB_NEIGHB_SEG |<--| NUMBER OF NEIGHBOURING SUB-DOMAINS (FOR EDGES)
63 !| NB_NEIGHB_PT_SEG |<--| NUMBER OF SEGMENTS SHARED WITH A NEIGHBOUR
64 !| NELEM2 |-->| NUMBER OF ELEMENTS IN 2D
65 !| NHM |<--| NODE NUMBERS OF PROCESSORS WITH SMALLER RANK
66 !| NHP |<--| NODE NUMBERS OF PROCESSORS WITH LARGER RANK
67 !| NPLAN |-->| NUMBER OF PLANES IN 3D
68 !| NPOIN2 |-->| NUMBER OF POINTS IN 2D
69 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
70 !
71  USE bief, ex_parini => parini
72 !
74  IMPLICIT NONE
75 !
76 !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
77 !
78  INTEGER, INTENT(IN) :: NPOIN2,NPLAN,NELEM2,MODASS
79  INTEGER, INTENT(INOUT) :: NB_NEIGHB,NB_NEIGHB_SEG
80  INTEGER, INTENT(INOUT) :: NHP(nbmaxdshare,nptir)
81  INTEGER, INTENT(INOUT) :: NHM(nbmaxdshare,nptir)
82  INTEGER, INTENT(IN) :: NACHB(nbmaxnshare,nptir)
83  INTEGER, INTENT(IN) :: IFAPAR(6,nelem2)
84  INTEGER, INTENT(INOUT) :: INDPU(npoin2)
85  TYPE(bief_mesh), INTENT(INOUT) :: MESH
86 !
87 !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
88 !
89  INTEGER IKP(nbmaxdshare,2),IKM(nbmaxdshare,2)
90  INTEGER I,J,IL,IZH,II,IMAX,IMIN,ILMAX,IELEM,IFACE
91  INTEGER ILP,ILM,IPA,IKA,IPB,IKB,NB_PT_MX,DIM1HCOM,CHECKSUM
92  LOGICAL NEW
93 !
94 !-----------------------------------------------------------------------
95 !
96 ! INITIALISES THE PROCESSOR NUMBERS FOR 2D MESSAGE-PASSING
97 !
98  DO i=1,nbmaxdshare
99  ikp(i,1)=-1
100  ikm(i,1)=-1
101  ikp(i,2)=0
102  ikm(i,2)=0
103  ENDDO
104 !
105 ! PREPARES COMMUNICATION
106 ! IN THE FOLLOWING SEQUENCE :
107 ! 1) SENDS TO PROCESSORS WITH NUMBER IPID + IL
108 ! 2) RECEIVES FROM PROCESSORS WITH NUMBER IPID - IL
109 ! 3) SENDS TO PROCESSORS WITH NUMBER IPID - IL
110 ! 4) RECEIVES FROM PROCESSORS WITH NUMBER IPID + IL
111 !
112 ! LEVEL IL : SENDS AND RECEIVES
113 !
114 !
115 ! SENDS TO PROCESSORS WITH NUMBER GREATER THAN IPID
116 !
117  imax=ipid
118 !
119  IF (ipid.NE.ncsize-1) THEN
120  izh=1
121  DO il=ipid+1,ncsize-1
122  ii=0
123  DO i=1,nptir
124  DO j=2,nbmaxnshare
125  IF(nachb(j,i).EQ.il) THEN
126  IF(izh.GT.nbmaxdshare) THEN
127  WRITE(lu,*) 'PARINI: NBMAXDSHARE TOO SMALL'
128  CALL plante(1)
129  stop
130  ENDIF
131  ii=ii+1
132  nhp(izh,ii)=nachb(1,i)
133  ENDIF
134  ENDDO ! J
135  ENDDO ! I
136  IF(ii.NE.0) THEN
137  ikp(izh,1)=il
138  ikp(izh,2)=ii
139  izh=izh+1
140  imax=il
141  ENDIF
142  ENDDO ! IL
143  ENDIF
144 !
145 !
146 ! RECEIVES FROM PROCESSORS WITH NUMBER LOWER THAN IPID
147 !
148  imin=ipid
149 !
150  IF (ipid.NE.0) THEN
151  izh=1
152  DO il=ipid-1,0,-1
153  ii=0
154  DO i=1,nptir
155  DO j=2,nbmaxnshare
156  IF(nachb(j,i).EQ.il) THEN
157  IF(izh.GT.nbmaxdshare) THEN
158  WRITE(lu,*) 'PARINI: NBMAXDSHARE TOO SMALL'
159  CALL plante(1)
160  stop
161  ENDIF
162  ii=ii+1
163  nhm(izh,ii)=nachb(1,i)
164  ENDIF
165  ENDDO ! J
166  ENDDO ! I
167  IF(ii.NE.0) THEN
168  ikm(izh,1)=il
169  ikm(izh,2)=ii
170  izh=izh+1
171  imin=il
172  ENDIF
173  ENDDO ! IL
174  ENDIF
175 !
176 !** DETERMINES ILMAX
177 !
178  ilmax=max(imax-ipid,ipid-imin)
179 !
180 !-----------------------------------------------------------------------
181 !
182 !==== COMPUTES THE NUMBER OF NEIGHBOURS
183 !
184  nb_pt_mx = 0
185  nb_neighb = 0
186  ilp = 1
187  ilm = 1
188 !** PROCESSOR OF HIGHER RANK
189  DO il=1,ilmax
190  ipa=ikp(ilp,1)
191  ika=ikp(ilp,2)
192  IF(ipa.EQ.ipid+il.AND.ika.NE.0) THEN
193  nb_neighb = nb_neighb + 1
194  IF(ika.GT.nb_pt_mx) nb_pt_mx=ika
195  ENDIF
196  IF(ipa.EQ.ipid+il) ilp=ilp+1
197  ENDDO
198 !** PROCESSOR OF LOWER RANK
199  DO il=1,ilmax
200  ipb=ikm(ilm,1)
201  ikb=ikm(ilm,2)
202  IF(ipb.EQ.ipid-il.AND.ikb.NE.0) THEN
203  nb_neighb = nb_neighb + 1
204  IF(ikb.GT.nb_pt_mx) nb_pt_mx=ikb
205  ENDIF
206  IF(ipb.EQ.ipid-il) ilm=ilm+1
207  ENDDO
208 !
209 !==== ENDS COMPUTATION OF THE NUMBER OF NEIGHBOURS
210 !
211  CALL bief_allvec(2,mesh%NB_NEIGHB_PT,'NBNGPT',
212  & nb_neighb,1,0,mesh)
213  CALL bief_allvec(2,mesh%LIST_SEND ,'LSSEND',
214  & nb_neighb,1,0,mesh)
215 !
216 ! ALIGNMENT ON 16 BYTES
217 !
218  dim1hcom = nb_pt_mx/4
219  IF(mod(nb_pt_mx,4).EQ.0) THEN
220  dim1hcom = dim1hcom*4
221  ELSE
222  dim1hcom = dim1hcom*4 + 4
223  ENDIF
224  CALL bief_allvec(2,mesh%NH_COM,'NH_COM',
225  & dim1hcom,nb_neighb,0,mesh)
226 !
227 !==== COMPUTES THE NUMBER OF INTERFACE POINTS PER NEIGHBOUR
228 !
229  nb_neighb = 0
230  ilp = 1
231  ilm = 1
232  DO il=1,ilmax
233  ipa=ikp(ilp,1)
234  ika=ikp(ilp,2)
235  IF(ipa.EQ.ipid+il.AND.ika.NE.0) THEN
236  nb_neighb = nb_neighb + 1
237  mesh%NB_NEIGHB_PT%I(nb_neighb) = ika
238  mesh%LIST_SEND%I(nb_neighb) = ipa
239  DO i=1,ika
240  mesh%NH_COM%I(dim1hcom*(nb_neighb-1)+i)=nhp(ilp,i)
241  ENDDO
242  ENDIF
243  IF(ipa.EQ.ipid+il) ilp=ilp+1
244  ENDDO
245  DO il=1,ilmax
246  ipb=ikm(ilm,1)
247  ikb=ikm(ilm,2)
248  IF(ipb.EQ.ipid-il.AND.ikb.NE.0) THEN
249  nb_neighb = nb_neighb + 1
250  mesh%NB_NEIGHB_PT%I(nb_neighb) = ikb
251  mesh%LIST_SEND%I(nb_neighb) = ipb
252  DO i=1,ikb
253  mesh%NH_COM%I(dim1hcom*(nb_neighb-1)+i)=nhm(ilm,i)
254  ENDDO
255  ENDIF
256  IF(ipb.EQ.ipid-il) ilm=ilm+1
257  ENDDO
258 !
259 !==== ENDS COMPUTATION OF THE NUMBER OF INTERFACE POINTS PER NEIGHBOUR
260 !
261 !=== POSSIBILITY OF SORTING LIST_SEND AND RECV FOR TORE BG
262 !
263 ! ALIGNMENT ON 16BYTES BOUNDARIES
264 !
265  nb_pt_mx = nb_pt_mx * nplan
266  il = nb_pt_mx/2
267  IF(mod(nb_pt_mx,2).EQ.0) THEN
268  il = il*2
269  ELSE
270  il = il*2 + 2
271  ENDIF
272  CALL bief_allvec(1,mesh%BUF_SEND,'BUSEND',il*3,nb_neighb,0,mesh)
273  CALL bief_allvec(1,mesh%BUF_RECV,'BURECV',il*3,nb_neighb,0,mesh)
274  IF (modass .EQ.3) THEN
275  CALL bief_allvec(1,mesh%BUF_SEND_ERR,'BSSERR',
276  & il*3,nb_neighb,0,mesh)
277  CALL bief_allvec(1,mesh%BUF_RECV_ERR,'BSRERR',
278  & il*3,nb_neighb,0,mesh)
279  ENDIF
280 !
281 ! ADDED FOR INTEGER I4 COMMUNICATIONS
282 !
283  ALLOCATE(mesh%BUF_SEND%I(il*3*nb_neighb))
284  ALLOCATE(mesh%BUF_RECV%I(il*3*nb_neighb))
285 !
286 ! ADDED FOR INTEGER I8 COMMUNICATIONS
287 !
288  IF(modass.EQ.2) THEN
289  ALLOCATE(mesh%BUF_SENDI8(il*3*nb_neighb))
290  ALLOCATE(mesh%BUF_RECVI8(il*3*nb_neighb))
291  ENDIF
292 !
293 !-----------------------------------------------------------------------
294 !
295 ! FOR SEGMENTS
296 !
297 ! WE ASSUME HERE THAT NB_NEIGHB.GE.NB_NEIGHB_SEG
298 !
299 ! NOTE: NH_COM_SEG IS FILLED WITH 4*IELEM+IFACE
300 ! THIS IS TO RETRIEVE IELEM AND IFACE ONCE ELTSEG IS KNOWN
301 ! THE FINAL VALUE OF NH_COM_SEG IS ELTSEG(IELEM,IFACE)
302 !
303  CALL bief_allvec(2,mesh%NB_NEIGHB_PT_SEG,'NBNGSG',
304  & nb_neighb,1,0,mesh)
305  CALL bief_allvec(2,mesh%LIST_SEND_SEG ,'LSSESG',
306  & nb_neighb,1,0,mesh)
307  CALL bief_allvec(2,mesh%NH_COM_SEG ,'NH_CSG',
308  & dim1hcom,nb_neighb,0,mesh)
309 !
310  nb_neighb_seg=0
311 !
312 ! INITIALISES NH_COM_SEG (SEE COMP_NH_COM_SEG)
313 !
314  DO i=1,dim1hcom*nb_neighb
315  mesh%NH_COM_SEG%I(i)=-999999
316  ENDDO
317 !
318  DO ielem=1,nelem2
319 !
320 ! LOOKS FOR A FACE WITH THE OTHER SIDE IN ANOTHER SUB-DOMAIN
321 !
322 ! ELEMENTS WITHOUT ANY INTERFACE SEGMENT HAVE 3 ZEROS
323  checksum=ifapar(1,ielem)**2+
324  & ifapar(2,ielem)**2+
325  & ifapar(3,ielem)**2
326 !
327  IF(checksum.NE.0) THEN
328  DO iface=1,3
329 !
330  ilm=ifapar(iface,ielem)
331  IF(ilm.GE.0.AND.ilm.NE.ipid) THEN
332 ! NEW INTERFACE SEGMENT FOUND
333  IF(nb_neighb_seg.EQ.0) THEN
334 ! THE FIRST ONE
335  nb_neighb_seg=1
336  mesh%NB_NEIGHB_PT_SEG%I(1)=1
337  mesh%LIST_SEND_SEG%I(1)=ilm
338  mesh%NH_COM_SEG%I(1)=4*ielem+iface
339  ELSE
340 ! FROM THE SECOND ON
341 ! IS IT A NEW PROCESSOR
342  new=.true.
343  DO il=1,nb_neighb_seg
344  IF(ilm.EQ.mesh%LIST_SEND_SEG%I(il)) THEN
345 ! NEW SEGMENT, OLD PROCESSOR
346  mesh%NB_NEIGHB_PT_SEG%I(il)=
347  & mesh%NB_NEIGHB_PT_SEG%I(il)+1
348  i=mesh%NB_NEIGHB_PT_SEG%I(il)
349  mesh%NH_COM_SEG%I(dim1hcom*(il-1)+i)=4*ielem+iface
350  new=.false.
351  EXIT
352  ENDIF
353  ENDDO
354  IF(new) THEN
355 ! NEW SEGMENT, NEW PROCESSOR
356  nb_neighb_seg=nb_neighb_seg+1
357  mesh%NB_NEIGHB_PT_SEG%I(nb_neighb_seg)=1
358  mesh%LIST_SEND_SEG%I(nb_neighb_seg)=ilm
359  mesh%NH_COM_SEG%I(dim1hcom*(nb_neighb_seg-1)+1)=
360  & 4*ielem+iface
361  ENDIF
362  ENDIF
363  ENDIF
364 !
365  ENDDO
366  ENDIF
367 !
368  ENDDO
369 !
370  IF(nb_neighb_seg.GT.nb_neighb) THEN
371  WRITE(lu,*) 'IN PARINI NB_NEIGHB =',nb_neighb
372  WRITE(lu,*) ' NB_NEIGHB_SEG=',nb_neighb_seg
373  CALL plante(1)
374  stop
375  ENDIF
376 !
377 !-----------------------------------------------------------------------
378 !
379 ! INDEX TABLE FOR BUFFER IN COMMUNICATION
380 !
381  DO i=1,npoin2
382  indpu(i)=0
383  ENDDO
384 !
385 ! COEFFICIENTS FOR THE SCALAR PRODUCT:
386 !
387  IF(nptir.GT.0) THEN
388  DO i=1,nptir
389  indpu(nachb(1,i))=i
390  ENDDO
391  ENDIF
392 !
393 !-----------------------------------------------------------------------
394 !
395  RETURN
396  END
subroutine parini(NHP, NHM, INDPU, NPOIN2, NACHB, NPLAN, MESH, NB_NEIGHB, NB_NEIGHB_SEG, NELEM2, IFAPAR, MODASS)
Definition: parini.f:8
subroutine bief_allvec(NAT, VEC, NOM, IELM, DIM2, STATUT, MESH)
Definition: bief_allvec.f:7
Definition: bief.f:3