The TELEMAC-MASCARET system  trunk
voisin31.f
Go to the documentation of this file.
1 ! *******************
2  SUBROUTINE voisin31
3 ! *******************
4 !
5  &(ifabor,nelem,nelmax,ielm,ikle,sizikl,npoin,nbor,nptfr,
6  & lihbor,klog,indpu,iklestr,neleb2)
7 !
8 !***********************************************************************
9 ! BIEF V6P3 21/08/2010
10 !***********************************************************************
11 !
12 !brief BUILDS THE ARRAY IFABOR, WHERE IFABOR(IELEM, IFACE) IS
13 !+ THE GLOBAL NUMBER OF THE NEIGHBOUR OF SIDE IFACE OF
14 !+ ELEMENT IELEM (IF THIS NEIGHBOUR EXISTS) AND 0 IF THE
15 !+ SIDE IS ON THE DOMAIN BOUNDARY.
16 !
17 !history REGINA NEBAUER (LNHE)
18 !+ 22/01/08
19 !+ V5P8
20 !+
21 !
22 !history N.DURAND (HRW), S.E.BOURBAN (HRW)
23 !+ 13/07/2010
24 !+ V6P0
25 !+ Translation of French comments within the FORTRAN sources into
26 !+ English comments
27 !
28 !history N.DURAND (HRW), S.E.BOURBAN (HRW)
29 !+ 21/08/2010
30 !+ V6P0
31 !+ Creation of DOXYGEN tags for automated documentation and
32 !+ cross-referencing of the FORTRAN sources
33 !
34 !history J-M HERVOUET (LNHE)
35 !+ 10/09/2012
36 !+ V6P3
37 !+ Treatment of prisms cut into tetrahedra added (IELM=51)
38 !+ and simplifications.
39 !
40 !history S.E.BOURBAN (HRW)
41 !+ 21/03/2017
42 !+ V7P3
43 !+ Replacement of the DATA declarations by the PARAMETER associates
44 !
45 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
46 !| IELM |-->| 31: TETRAHEDRA
47 !| | | 51: PRISMS CUT INTO TETRAHEDRA
48 !| IFABOR |-->| ELEMENTS BEHIND THE EDGES OF A TRIANGLE
49 !| | | IF NEGATIVE OR ZERO, THE EDGE IS A LIQUID
50 !| | | BOUNDARY
51 !| IKLE |-->| CONNECTIVITY TABLE.
52 !| INDPU |-->| IF NOT 0, INTERFACE POINT IN PARALLEL
53 !| IKLESTR |-->| CONNECTIVITY TABLE OF BOUNDARY TRIANGLES
54 !| KLOG |-->| CONVENTION FOR SOLID BOUNDARY
55 !| LIHBOR |-->| TYPE OF BOUNDARY CONDITIONS ON DEPTH
56 !| NBOR |-->| GLOBAL NUMBER OF BOUNDARY POINTS
57 !| NELEM |-->| NUMBER OF ELEMENTS
58 !| NELEB2 |-->| NUMBER OF BOUNDARY TRIANGLES (oversized)
59 !| NELMAX |-->| MAXIMUM NUMBER OF ELEMENTS
60 !| NPOIN |-->| NUMBER OF POINTS
61 !| NPTFR |-->| NUMBER OF BOUNDARY POINTS
62 !| SIZIKL |-->| FIRST DIMENSION OF IKLE
63 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
64 !
65  USE bief, ex_voisin31 => voisin31
66 !
68  IMPLICIT NONE
69 !
70 !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
71 !
72  INTEGER, INTENT(IN) :: IELM,NPTFR,NELEM,NELMAX,NPOIN,SIZIKL,KLOG
73  INTEGER, INTENT(IN) :: NBOR(nptfr)
74  INTEGER, INTENT(INOUT):: IFABOR(nelmax,4)
75  INTEGER, INTENT(IN) :: IKLE(sizikl,4),LIHBOR(*)
76  INTEGER, INTENT(IN) :: INDPU(*)
77  INTEGER, INTENT(IN) :: NELEB2
78  INTEGER, INTENT(IN) :: IKLESTR(neleb2,3)
79 !
80 !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
81 !
82 ! LOCAL VARIABLES
83 !
84  ! ARRAY WHICH IS THE REVERSE OF NBOR
85  ! (GIVES FOR EACH NODE IN THE DOMAIN THE BOUNDARY NODE NUMBER E,
86  ! OR 0 IF IT IS AN INTERIOR NODE)
87  INTEGER, DIMENSION(: ), ALLOCATABLE :: NBOR_INV
88  ! ARRAY DEFINING THE NUMBER OF ELEMENT (TETRAHEDRONS) NEIGHBOURING
89  ! A NODE
90  INTEGER, DIMENSION(:), ALLOCATABLE :: NVOIS
91  ! ARRAY DEFINING THE IDENTIFIERS OF THE ELEMENTS NEIGHBOURING
92  ! EACH NODE
93  INTEGER, DIMENSION(: ), ALLOCATABLE :: NEIGH
94  INTEGER, DIMENSION(:,:), ALLOCATABLE :: IKLE_TRI
95  INTEGER, DIMENSION(:,:), ALLOCATABLE :: VOIS_TRI
96  ! ARRAY DEFINING THE ADDRESSES OF THE VARIOUS ENTRIES IN
97  ! ARRAY NEIGH
98  INTEGER, DIMENSION(NPOIN) :: IADR
99  ! THE VALUE OF AN ENTRY IN THIS ARRAY
100  INTEGER :: ADR
101 !
102  ! THE MAXIMUM NUMBER OF ELEMENTS NEIGHBOURING A NODE
103  INTEGER :: NMXVOISIN
104  INTEGER :: IMAX ! SIZE OF ARRAY IADR
105 !
106  INTEGER :: NFACE ! NUMBER OF SIDES TO ELEMENT (TETRA: 4)
107  INTEGER :: NBTRI ! NUMBER OF DEFINED TRIANGLES
108 !
109  INTEGER :: IELEM ! ELEMENTS COUNTER
110  INTEGER :: IELEM2 ! ELEMENTS COUNTER
111  INTEGER :: IPOIN ! DOMAIN NODES COUNTER
112  INTEGER :: INOEUD ! TETRAHEDRONS/TRIANGLES NODES COUNTER
113  INTEGER :: IFACE ! SIDE COUNTER
114  INTEGER :: IFACE2 ! SIDE COUNTER
115  INTEGER :: ITRI ! TRIANGLES COUNTER
116  INTEGER :: IVOIS ! NEIGHBOURS COUNTER
117  INTEGER :: NV ! NUMBER OF NEIGHBOURS
118 !
119  INTEGER :: ERR ! ERROR CODE FOR MEMORY ALLOCATION
120 !
121  LOGICAL :: FOUND ! FOUND OR NOT ...
122 !
123  INTEGER :: I1, I2, I3 ! THE THREE NODES OF A TRIANGLE
124  INTEGER :: M1, M2, M3 ! SAME THING, ORDERED
125 !
126  INTEGER :: I,J,K ! USEFUL ...
127 !
128  INTEGER :: IR4,IR5,IR6,COMPT
129  LOGICAL :: BORD
130 !
131 ! DEFINES THE FOUR TRIANGLES OF THE TETRAHEDRON: THE FIRST
132 ! DIMENSION IS THE NUMBER OF THE TRIANGLE, THE SECOND GIVES
133 ! THE NODE NUMBERS OF THE NODES OF TETRAHEDRONS WHICH DEFINE IT.
134  INTEGER :: SOMFAC(3,4)
135  parameter( somfac = reshape( (/
136  & 1,2,3 , 4,1,2 , 2,3,4 , 3,4,1 /), shape=(/ 3,4 /) ) )
137 !
138 !-----------------------------------------------------------------------
139 ! START
140 !-----------------------------------------------------------------------
141 !
142 ! CHECKS FIRST THAT WE ARE INDEED DEALING WITH TETRAHEDRONS. IF NOT,
143 ! GOODBYE.
144 !
145  IF(ielm.EQ.31.OR.ielm.EQ.51) THEN
146  nface = 4
147  ELSE
148  WRITE(lu,99) ielm
149 99 FORMAT(1x,'VOISIN31: IELM=',1i6,' TYPE OF ELEMENT NOT AVAILABLE')
150  CALL plante(1)
151  stop
152  ENDIF
153 !
154 ! ALLOCATES TEMPORARY ARRAYS
155 !
156  ALLOCATE(nbor_inv(npoin),stat=err)
157  CALL check_allocate(err,'VOISIN31:NBOR_INV')
158 !
159 ! ALLOCATES TEMPORARY ARRAYS
160 !
161  ALLOCATE(nvois(npoin),stat=err)
162  CALL check_allocate(err,'VOISIN31:NVOIS')
163 !
164 !-----------------------------------------------------------------------
165 ! STEP 1: COUNTS THE NUMBER OF ELEMENTS NEIGHBOURING A NODE
166 !-----------------------------------------------------------------------
167 ! COMPUTES THE NUMBER OF ELEMENTS NEIGHBOURING EACH NODE OF THE MESH.
168 ! RESULT: NVOIS(INOEUD) GIVES THE NUMBER OF ELEMENTS NEIGHBOURING
169 ! NODE INOEUD
170 !
171  ! INITIALISES THE NEIGHBOURING ELEMENT COUNTER TO 0
172  !
173  DO i = 1,npoin
174  nvois(i) = 0
175  ENDDO
176  ! COUNTS THE NEIGHBOURING ELEMENTS
177  ! USING THE CONNECTIVITY TABLE, THE COUNTER IS INCREMENTED
178  ! EACH TIME THAT AN ELEMENT REFERENCES NODE IPOIN
179  ! LOOP ON THE 4 NODES OF THE ELEMENT
180  DO inoeud = 1, 4
181  ! LOOP ON THE ELEMENTS
182  DO ielem = 1,nelem
183  ! THE ID OF NODE I OF ELEMENT IELEM
184  ipoin = ikle( ielem , inoeud )
185  ! INCREMENT THE COUNTER
186  nvois(ipoin) = nvois(ipoin) + 1
187  ENDDO
188  ENDDO
189 !
190 !-----------------------------------------------------------------------
191 ! STEP 2: DETERMINES THE SIZE OF ARRAY NEIGH() AND OF AUXILIARY
192 ! ARRAY TO INDEX NEIGH. ALLOCATES NEIGH
193 !-----------------------------------------------------------------------
194 ! CREATES AN ARRAY WHICH WILL CONTAIN THE IDENTIFIERS OF THE ELEMENTS
195 ! NEIGHBOURING EACH NODE. SINCE THE NUMBER OF NEIGHBOURS IS A PRIORI
196 ! DIFFERENT FOR EACH NODE, AND IN AN EFFORT NOT TO CREATE A (TOO) BIG
197 ! ARRAY FOR NO REASON, AN AUXILIARY ARRAY IS REQUIRED THAT GIVES THE
198 ! ADDRESS OF THE ENTRIES FOR A GIVEN NODE. THIS ARRAY HAS AS MANY
199 ! ENTRIES AS THERE ARE NODES.
200 ! WILL ALSO COMPUTE THE MAXIMUM NUMBER OF NEIGHBOURS, SOME TIME.
201 !
202  ! THE FIRST ENTRY IN THE ID OF THE NEIGHBOURS ARRAY IS 1
203  adr = 1
204  iadr(1) = adr
205  ! THE MAX NUMBER OF NEIGHBOURING ELEMENTS
206  nv = nvois(1)
207  nmxvoisin = nv
208 !
209  DO ipoin = 2,npoin
210  ! ADDRESS FOR THE OTHER ENTRIES:
211  adr = adr + nv
212  iadr(ipoin) = adr
213  nv = nvois(ipoin)
214  ! IDENTIFIES THE MAX. NUMBER OF NEIGHBOURS
215  nmxvoisin = max(nmxvoisin,nv)
216  ENDDO
217 !
218  ! THE TOTAL NUMBER OF NEIGHBOURING ELEMENTS FOR ALL THE NODES
219  ! GIVES THE SIZE OF THE NEIGHBOURS ARRAY:
220  imax = iadr(npoin) + nvois(npoin)
221  ! ALLOCATES THE ARRAY CONTAINING THE IDENTIFIERS OF THE ELEMENTS
222  ! NEIGHBOURING EACH NODE
223  ALLOCATE(neigh(imax),stat=err)
224  IF(err.NE.0) GOTO 999
225 !
226 !-----------------------------------------------------------------------
227 ! STEP 3: INITIALISES NEIGH
228 !-----------------------------------------------------------------------
229 ! NEEDS TO FILL NEIGH NOW THAT IT'S BEEN ALLOCATED: I.E.
230 ! STARTS AGAIN THE LOOP ON THE 4 NODES OF EACH ELEMENT AND THIS
231 ! TIME, ALSO STORES THE IDENTIFIER IN ARRAY NEIGH.
232 !
233 !
234  ! RE-INITIALISES THE COUNTER OF THE NEIGHBOURING ELEMENTS TO 0,
235  ! TO KNOW WHERE WE ARE AT
236  DO i = 1,npoin
237  nvois(i) = 0
238  ENDDO
239 ! NVOIS(:) = 0
240  ! FOR EACH NODE OF THE ELEMENTS, STORES THE IDENTIFIER
241  DO inoeud = 1, 4 ! LOOP ON THE ELEMENT NODES
242  DO ielem=1,nelem ! LOOP ON THE ELEMENTS
243  ipoin = ikle( ielem , inoeud )
244  ! ONE MORE NEIGHBOUR
245  nv = nvois(ipoin) + 1
246  nvois(ipoin) = nv
247  ! STORES THE IDENTIFIER OF THE NEIGHBOURING ELEMENT IN THE ARRAY
248  neigh(iadr(ipoin)+nv) = ielem
249  ENDDO ! END OF LOOP ELEMENTS
250  ENDDO ! END OF LOOP NODES
251 !
252 !-----------------------------------------------------------------------
253 ! STEP 4: IDENTIFIES COMMON FACES OF THE TETRAHEDRONS AND FILLS IN
254 ! ARRAY IFABOR
255 !-----------------------------------------------------------------------
256 ! TO IDENTIFY FACES COMMON TO THE ELEMENTS :
257 ! FROM THE ELEMENTS THAT SHARE A NODE, AT LEAST 2 SHARE A FACE
258 ! (IF THE NODE IS NOT A BOUNDARY NODE).
259 ! THE ALGORITHM PRINCIPLE:
260 ! BUILDS THE TRIANGLES OF THE TETRAHEDRON FACES, ONCE HAVE IDENTIFIED
261 ! THOSE THAT SHARE NODE IPOIN.
262 ! IF 2 TRIANGLES SHARE THE SAME NODES, IT MEANS THAT THE TETRAHEDRONS
263 ! DEFINING THEM ARE NEIGHBOURS.
264 ! IF NO NEIGHBOUR CAN BE FOUND, IT MEANS THAT THE TRIANGLE IS A
265 ! BOUNDARY FACE.
266 ! BASED ON THE ASSUMPTION THAT A TRIANGLE CANNOT BE DEFINED BY MORE
267 ! THAN 2 TETRAHEDRONS.
268 ! IF THAT WAS NOT THE CASE, IT WOULD MEAN THAT THERE WAS A PROBLEM WITH
269 ! THE MESH; AND THIS IS NOT CATERED FOR ...
270 !
271 ! ADVANTAGES:
272 ! SAVES QUITE A BIT OF MEMORY, BY STORING THE TRIANGLES AROUND A NODE.
273 ! DISADVANTAGES:
274 ! COULD BE DOING TOO MANY (USELESS) COMPUTATIONS (TO GET TO THE STAGE
275 ! WHERE THE CONNECTIVITY TABLE FOR THE TRIANGLES IS DEFINED)
276 ! COULD MAYBE SKIP THIS STEP BY CHECKING IF IFABOR ALREADY CONTAINS
277 ! SOMETHING OR NOT ...
278 !
279 ! BUILDS THE CONNECTIVITY TABLE FOR THE TRIANGLES
280 ! THIS CONNECTIVITY TABLE IS NOT SUPPOSED TO MAKE A LIST OF ALL
281 ! THE TRIANGLES, BUT MERELY THOSE AROUND A NODE.
282 ! THE MAXIMUM NUMBER OF (TETRAHEDRONS) NEIGHBOURS IS KNOWN FOR A
283 ! NODE. IN THE WORST CASE, THE NODE IS A BOUNDARY NODE.
284 ! WILL MAXIMISE (A LOT) BY ASSUMING THAT THE MAXIMUM NUMBER OF
285 ! TRIANGLES AROUND A NODE CAN BE THE NUMBER OF NEIGHBOURING
286 ! TETRAHEDRONS.
287 ! ALSO BUILDS THE ARRAY VOIS_TRI CONTAINING THE ID OF THE TETRAHEDRON
288 ! ELEMENT THAT DEFINED IT FIRST (AND THAT WILL BE NEIGHBOUR TO THE
289 ! TETRAHEDRON THAT WILL FIND THAT ANOTHER ONE ALREADY DEFINES IT)
290 ! THIS ARRAY HAS 2 ENTRIES : THE ID OF THE ELEMENT AND THE ID OF THE SIDE.
291 !
292  nbtri = nmxvoisin * 3
293 !
294  ALLOCATE(ikle_tri(nbtri,3),stat=err)
295  IF(err.NE.0) GOTO 999
296  ALLOCATE(vois_tri(nbtri,2),stat=err)
297  IF(err.NE.0) GOTO 999
298 !
299 ! ALL FACES PRESUMED SOLID TO START WITH...
300 !
301  ! ASSUMING SOLID BOUNDARIES EVERYWHERE
302  ifabor(:,:) = -1
303 !
304  ! LOOP ON ALL THE NODES IN THE MESH
305  DO ipoin = 1, npoin
306  ! FOR EACH NODE, CHECKS THE NEIGHBOURING TETRAHEDRON ELEMENTS
307  ! (MORE PRECISELY: THE TRIANGULAR FACES THAT MAKE IT)
308  ! RE-INITIALISES THE CONNECTIVITY TABLE FOR THE TETRAHEDRON
309  ! TRIANGLES TO 0, AND THE NUMBER OF TRIANGLES WHICH HAVE BEEN
310  ! FOUND:
311  !
312  ikle_tri(:,:) = 0
313  ! SAME THING FOR THE ARRAY THAT IDENTIFIES WHICH ELEMENT HAS
314  ! ALREADY DEFINED THE TRIANGLE :
315  vois_tri(:,:) = 0
316  ! STARTS COUNTING THE TRIANGLES AGAIN:
317  nbtri = 0
318  nv = nvois(ipoin)
319  adr = iadr(ipoin)
320  DO ivois = 1, nv
321  ! THE IDENTIFIER OF THE NEIGHBOURING ELEMENT IVOIS TO
322  ! THE NODE IPOIN:
323  ielem = neigh(adr+ivois)
324  ! LOOP ON THE 4 SIDES OF THIS ELEMENT
325  DO iface = 1 , nface
326  ! IF THIS SIDE ALREADY HAS A NEIGHBOUR, THAT'S
327  ! ENOUGH AND GOES TO NEXT.
328  ! OTHERWISE, LOOKS FOR IT...
329  IF ( ifabor(ielem,iface) .LE. 0 ) THEN
330  ! EACH FACE DEFINES A TRIANGLE. THE TRIANGLE IS
331  ! GIVEN BY 3 NODES.
332  i1 = ikle(ielem,somfac(1,iface))
333  i2 = ikle(ielem,somfac(2,iface))
334  i3 = ikle(ielem,somfac(3,iface))
335  ! THESE 3 NODES ARE ORDERED, M1 IS THE NODE WITH
336  ! THE SMALLEST IDENTIFIER, M3 THAT WITH THE
337  ! LARGEST IDENTIFIER AND M2 IS IN THE MIDDLE:
338  m1 = max(i1,(max(i2,i3)))
339  m3 = min(i1,(min(i2,i3)))
340  m2 = i1+i2+i3-m1-m3
341  ! GOES THROUGH THE ARRAY WITH TRIANGLES ALREADY DEFINED
342  ! TO SEE IF ONE OF THEM BEGINS WITH M1.
343  ! IF THAT'S THE CASE, CHECKS THAT IT ALSO HAS NODES
344  ! M2 AND M3. IF THAT'S THE CASE, HAS FOUND A NEIGHBOUR.
345  ! OTHERWISE, A NEW TRIANGLE ENTRY IS CREATED.
346  !
347  found = .false.
348  DO itri = 1, nbtri
349  IF ( ikle_tri(itri,1) .EQ. m1 ) THEN
350  IF ( ikle_tri(itri,2) .EQ. m2 .AND.
351  & ikle_tri(itri,3) .EQ. m3 ) THEN
352  ! FOUND IT! ALL IS WELL.
353  ! STORES THE INFORMATION IN VOIS_TRI.
354  ! (I.E. THE ELEMENT THAT HAS ALREADY
355  ! DEFINED THE TRIANGLE AND THE FACE)
356  ielem2 = vois_tri(itri,1)
357  iface2 = vois_tri(itri,2)
358  IF ( ielem2 .EQ. ielem ) THEN
359  WRITE(lu,909) ielm
360 909 FORMAT(1x,'VOISIN: IELM=',1i6,',
361  & NEIGHBOUR PROBLEM')
362  CALL plante(1)
363  stop
364  END IF
365  ! TO BE SURE :
366  IF ( ielem2 .EQ. 0 .OR.
367  & iface2 .EQ. 0 ) THEN
368  WRITE(lu,919) ielem2,iface2
369 919 FORMAT(1x,'VOISIN31:UNDEFINED TRIANGLE,
370  & IELEM=',1i6,'IFACE=',1i6)
371  CALL plante(1)
372  stop
373  END IF
374  ! THE ELEMENT AND ITS NEIGHBOUR : STORES
375  ! THE CONNECTION IN IFABOR.
376  ifabor(ielem ,iface ) = ielem2
377  ifabor(ielem2,iface2) = ielem
378  found = .true.
379  END IF
380  END IF
381  END DO
382  ! NO, THIS TRIANGLE WAS NOT ALREADY THERE; THEREFORE
383  ! CREATES A NEW ENTRY.
384  IF ( .NOT. found) THEN
385  nbtri = nbtri + 1
386  ikle_tri(nbtri,1) = m1
387  ikle_tri(nbtri,2) = m2
388  ikle_tri(nbtri,3) = m3
389  vois_tri(nbtri,1) = ielem
390  vois_tri(nbtri,2) = iface
391  END IF
392  END IF ! IFABOR 0
393  END DO ! END OF LOOP ON FACES OF THE NEIGHBOURING ELEMENTS
394 !
395  END DO ! END OF LOOP ON ELEMENTS NEIGHBOURING THE NODE
396  END DO ! END OF LOOP ON NODES
397 !
398  DEALLOCATE(neigh)
399  DEALLOCATE(ikle_tri)
400  DEALLOCATE(vois_tri)
401 !
402 !-----------------------------------------------------------------------
403 ! STEP 5: FACES BETWEEN DIFFERENT COMPUTATION DOMAIN
404 !-----------------------------------------------------------------------
405 !
406  IF(ncsize.GT.1) THEN
407  !
408  ! WHY A DIFFERENT ALGORITHM ?
409  ! a) Partitionning method : 51 submeshes are obtained from a 2D mesh
410  ! b) No iklestr is available
411  ! c) Some pathological cases with 31
412  IF (ielm.EQ.51) THEN
413  !
414  DO iface=1,nface
415  DO ielem=1,nelem
416 ! IF A FACE HAS 3 POINTS WHICH ARE INTERFACES BETWEEN SUB-DOMAINS
417 ! IT IS ASSIGNED A VALUE OF -2
418 !
419  i1=ikle(ielem,somfac(1,iface))
420  i2=ikle(ielem,somfac(2,iface))
421  i3=ikle(ielem,somfac(3,iface))
422 !
423  IF( indpu(i1).NE.0.AND.
424  & indpu(i2).NE.0.AND.
425  & indpu(i3).NE.0 ) ifabor(ielem,iface)=-2
426 !
427  ENDDO
428  ENDDO
429 !
430  ELSE IF (ielm.EQ.31) THEN
431 !
432  DO iface=1,nface
433  DO ielem=1,nelem
434 ! IF A FACE HAS 3 POINTS WHICH ARE INTERFACES BETWEEN SUB-DOMAINS
435 ! IT IS ASSIGNED A VALUE OF -2
436 
437 ! PATHOLOGIC CASES (THANKS TO OLIVIER BOITEAU, EDF R&D/SINETICS)
438 ! a) 3 nodes may have INDPU /= 0, this doesn't mean automatically
439 ! that the triangle is an interface one (case of true unstructured tetra mesh)
440 ! b) a border triangle may have INDPU /= 0 on its 3 nodes
441 ! => priority to border triangles
442 ! c) 3 nodes of a triangle may be on the boundary and have INDPU /= 0
443 ! this doesn't mean automatically that the triangle is on the boundary.
444 
445  IF (ifabor(ielem,iface).EQ.-1) THEN
446 !
447  i1=ikle(ielem,somfac(1,iface))
448  i2=ikle(ielem,somfac(2,iface))
449  i3=ikle(ielem,somfac(3,iface))
450 
451  IF ( indpu(i1).NE.0.AND.
452  & indpu(i2).NE.0.AND.
453  & indpu(i3).NE.0 ) THEN
454 
455 ! THESE ARE INTERFACE NODES; DO THEY CORRESPOND TO A
456 ! (VIRTUAL) INTERFACE TRIANGLE OR TO A BOUNDARY TRIANGLE ?
457 
458 ! THE FOLLOWING TEST IS NOT SUFFICIENT
459 ! IF (.NOT. (IR5.EQ.1.AND.IR4.EQ.1.AND.IR6.EQ.1)) IFABOR(IELEM,IFACE)=-2
460 !
461  bord=.false.
462  ir4=0
463  ir5=0
464  ir6=0
465  DO j=1,nptfr
466  IF (i1.EQ.nbor(j)) ir5=1
467  IF (i2.EQ.nbor(j)) ir4=1
468  IF (i3.EQ.nbor(j)) ir6=1
469  ENDDO ! J
470 
471 ! THEY ARE ALSO BOUNDARY NODES
472  IF (ir5.EQ.1.AND.ir4.EQ.1.AND.ir6.EQ.1) THEN
473 !
474  DO j=1,neleb2
475 ! IT IS A BOUNDARY TRIANGLE
476  compt=0
477  DO i=1,3
478  IF (iklestr(j,i)==i1) compt=compt+1
479  IF (iklestr(j,i)==i2) compt=compt+10
480  IF (iklestr(j,i)==i3) compt=compt+100
481  ENDDO
482 ! THESE 3 NODES INDEED BELONG TO THE SAME BOUNDARY TRIANGLE
483  IF (compt==111) THEN
484  bord=.true.
485 ! WRITE(LU,*)'VERTICES OF A BOUNDARY TRIANGLE'
486  EXIT
487  ENDIF
488  ENDDO
489  ENDIF
490  IF (.NOT.bord) THEN
491 ! THESE 3 NODES BELONG TO AN INTERFACE MESH
492 ! WRITE(LU,*) 'INTERFACE NODES'
493  ifabor(ielem,iface)=-2
494  ENDIF
495  ENDIF
496  ENDIF
497  ENDDO
498  ENDDO
499  ENDIF
500  ENDIF
501 !
502 !
503 !-----------------------------------------------------------------------
504 !
505 ! WITH ELEMENT 51 THE DIFFERENCE BETWEEN SOLID AND LIQUID
506 ! BOUNDARIES IS DONE LATER
507 ! AND I DOUBT THAT THE CODE BELOW WITH LIHBOR CAN WORK WITH
508 ! REAL TETRAHEDRA
509 !
510  IF((ielm.EQ.51).OR.(ielm.EQ.31)) GO TO 1000
511 !
512 !-----------------------------------------------------------------------
513 !
514 ! IFABOR DISTINGUISHES BETWEEN THE BOUNDARY FACES AND THE LIQUID FACES
515 !
516 ! INITIALISES NBOR_INV TO 0
517 !
518  DO ipoin=1,npoin
519  nbor_inv(ipoin) = 0
520  ENDDO
521 !
522 ! CONNECTS GLOBAL NUMBERING TO BOUNDARY NUMBERING
523 !
524  DO k = 1, nptfr
525  nbor_inv(nbor(k)) = k
526  ENDDO
527 !
528 ! LOOP ON ALL THE SIDES OF ALL THE ELEMENTS:
529 !
530  DO iface = 1 , nface
531  DO ielem = 1 , nelem
532 !
533  IF(ifabor(ielem,iface).EQ.-1) THEN
534 !
535 ! IT IS A TRUE BOUNDARY SIDE (IN PARALLEL MODE THE INTERNAL SIDES
536 ! ARE INDICATED WITH -2).
537 ! GLOBAL NUMBERS OF THE NODES OF THE SIDE :
538 !
539  i1 = ikle( ielem , somfac(1,iface) )
540  i2 = ikle( ielem , somfac(2,iface) )
541  i3 = ikle( ielem , somfac(3,iface) )
542 !
543 ! A LIQUID SIDE IS IDENTIFIED WITH THE BOUNDARY CONDITION ON H
544 !
545  IF(nptfr.GT.0) THEN
546  IF(lihbor(nbor_inv(i1)).NE.klog.AND.lihbor(nbor_inv(i2)).NE.klog
547  & .AND.lihbor(nbor_inv(i3)).NE.klog ) THEN
548 ! LIQUID SIDE : IFABOR=0 SOLID SIDE : IFABOR=-1
549  ifabor(ielem,iface)=0
550  ENDIF
551  ENDIF
552 !
553  ENDIF
554 !
555  ENDDO ! IELEM
556  ENDDO ! IFACE
557 !
558 !
559 1000 CONTINUE
560 !
561 !-----------------------------------------------------------------------
562 !
563  RETURN
564 !
565 !-----------------------------------------------------------------------
566 !
567 999 WRITE(lu,2000) err
568 2000 FORMAT(1x,'VOISIN31: ERROR DURING ALLOCATION OF MEMORY: ',/,1x,
569  & 'ERROR CODE: ',1i6)
570  CALL plante(1)
571  stop
572 !
573 !-----------------------------------------------------------------------
574 !
575  END
subroutine voisin31(IFABOR, NELEM, NELMAX, IELM, IKLE, SIZIKL, NPOIN, NBOR, NPTFR, LIHBOR, KLOG, INDPU, IKLESTR, NELEB2)
Definition: voisin31.f:8
Definition: bief.f:3