The TELEMAC-MASCARET system  trunk
util_pares.f
Go to the documentation of this file.
1  MODULE util_pares
2 
3  IMPLICIT NONE
4 
5  CONTAINS
6 
7  FUNCTION i2char2 (INT_IN)
8  !-----------------------------------------------------------------------
9  ! DESCRIPTION:
10  !
11  ! CONVERTS AN INTEGER INTO A STRING. MAXIMUM OF 12 DIGITS.
12  ! THE INTEGER IS FORMATTED PROPERLY SO THAT THE RETURNED STRING CAN
13  ! THEN BE TRIMMED ( TRIM(I2CHAR() )
14  !-----------------------------------------------------------------------
15  IMPLICIT NONE
16  !-----------------------------------------------------------------------
17  ! ARGUMENTS
18  INTEGER, INTENT(IN) :: INT_IN ! THE INTEGER TO CONVERT
19  CHARACTER (LEN=12) :: I2CHAR2
20  !-----------------------------------------------------------------------
21  ! LOCAL VARIABLES
22  CHARACTER(LEN=12) :: STRING ! TEMPORARY STRING
23  CHARACTER(LEN=5) :: THEFORMAT ! FORMAT TO USE FOR THE INTEGER
24  INTEGER :: N ! NUMBER OF DECIMALS IN THE INTEGER
25  !-----------------------------------------------------------------------
26  ! WE LOOK FOR N SUCH THAT 10^{N-1} < INT_IN < 10^{N}
27  ! THIS IS DONE TO MAKE SURE THAT WE DO NOT CREATE A FORMAT "OVERFLOW"
28  n = 1
29  DO WHILE (int_in.GE.10**n)
30  n = n + 1
31  ENDDO
32 
33  ! CHECK ON THE "LENGTH" OF THE INTEGER
34  IF (n .LE. 9) THEN
35 
36  ! WRITE THE INTEGER IN A STRING WITH THE RIGHT FORMAT
37  WRITE(unit=theformat,fmt='(''(I'',I1,'')'')') n
38  WRITE(unit=string,fmt=theformat) int_in
39 
40  ELSE IF ( (n .GE. 10) .AND. (n .LE. 12) ) THEN
41 
42  ! WRITE THE INTEGER IN A STRING WITH THE RIGHT FORMAT
43  WRITE(unit=theformat,fmt='(''I'',I2)') n
44  WRITE(unit=string,fmt=theformat) int_in
45 
46  ELSE
47  ! IT IS NOT POSSIBLE TO OUTPUT THIS INTEGER WITHT HE DEFAULT FORMAT
48  WRITE(*,*)'FORMAT ERROR IN I2CHAR2.'
49  ENDIF
50 
51  ! TRIM THE STRING AND RETURN
52  i2char2 = trim(string)
53  !-----------------------------------------------------------------------
54  END FUNCTION i2char2
55 
56 ! ---------------------------------------------------
57 
58  SUBROUTINE calc_neleb(IKLE, NELEM, NPOIN,NELEB)
59 
60  !-----------------------------------------------------------------------
61 
62  IMPLICIT NONE
63 
64  !-----------------------------------------------------------------------
65  ! GLOBAL VARIABLES
66  !VOIR LA SUBROUTINE VOISIN31.F DONT CETTE PROCEDURE EST DIRECTEMENT INSPIRE
67  !
68  INTEGER, INTENT(IN) :: NELEM
69  INTEGER, INTENT(IN) :: NPOIN
70  INTEGER, INTENT(IN) :: IKLE(nelem,4)
71  INTEGER, INTENT(OUT) :: NELEB
72  !-----------------------------------------------------------------------
73  ! VARIABLES LOCALES
74 
75  INTEGER :: NVOIS(npoin),IADR(npoin)
76  INTEGER :: I,INOEUD,IELEM,IPOIN,ADR,IMAX,NBTRI,NV,NMXVOISIN,
77  & ivois,iface,m1,m2,m3,i1,i2,i3,nface,itri,ielem2,iface2
78  INTEGER, DIMENSION(:), ALLOCATABLE :: NEIGH
79  INTEGER, DIMENSION(:,:), ALLOCATABLE :: IKLE_TRI,VOIS_TRI,IFABOR
80  LOGICAL :: FOUND
81  ! ~~~~~~~~~~~~~~~~~~~~~~~
82  ! DEFINITION DES QUATRE TRIANGLES DU TETRAEDRE : LA PREMIERE
83  ! DIMENSION DU TABLEAU EST LE NUMERO DU TRIANGLE, LA DEUXIEME DONNE
84  ! LES NUMEROS DES NOEUDS DE TETRAEDRES QUI LE DEFINISSENT.
85  INTEGER :: SOMFAC(3,4)
86  parameter( somfac = reshape((/ 1,2,3 , 4,1,2 ,
87  & 2,3,4 , 3,4,1 /),(/3,4/) ))
88 
89 !-----------------------------------------------------------------------
90  nface=4
91 !-----------------------------------------------------------------------
92 ! ETAPE 1 : Comptage du nombre d'elements voisins d'un noeud.
93 !-----------------------------------------------------------------------
94  DO i = 1, npoin
95  nvois(i) = 0
96  END DO
97  DO inoeud = 1, 4
98  DO ielem = 1,nelem
99  ipoin = ikle( ielem , inoeud )
100  nvois(ipoin) = nvois(ipoin) + 1
101  END DO
102  END DO
103 
104 !-----------------------------------------------------------------------
105 ! ETAPE 2 : Determination de la taille du tableau NEIGH() et de la
106 ! table auxiliaire pour indexer NEIGH. allocation de NEIGH
107 !-----------------------------------------------------------------------
108  adr = 1
109  iadr(1) = adr
110  nv = nvois(1)
111  nmxvoisin = nv
112 
113  DO ipoin = 2,npoin
114  adr = adr + nv
115  iadr(ipoin) = adr
116  nv = nvois(ipoin)
117  nmxvoisin = max(nmxvoisin,nv)
118  END DO
119 
120  imax = iadr(npoin) + nvois(npoin)
121 
122  ALLOCATE(neigh(imax))
123 !-----------------------------------------------------------------------
124 ! ETAPE 3 : initialisation de NEIGH
125 !-----------------------------------------------------------------------
126  nvois(:) = 0
127 
128  DO inoeud = 1, 4
129  DO ielem=1,nelem
130  ipoin = ikle( ielem , inoeud )
131  nv = nvois(ipoin) + 1
132  nvois(ipoin) = nv
133  neigh(iadr(ipoin)+nv) = ielem
134  END DO
135  END DO
136 !-----------------------------------------------------------------------
137 ! ETAPE 4 : Reperer les faces communes des tetraedres et remplir le
138 ! tableau IFABOR.
139 !-----------------------------------------------------------------------
140  nbtri = nmxvoisin * 3
141 !
142  ALLOCATE(ikle_tri(nbtri,3))
143  ALLOCATE(vois_tri(nbtri,2))
144  ALLOCATE(ifabor(nelem,4))
145  ifabor(:,:) = 0
146  DO ipoin = 1, npoin
147  ikle_tri(:,:) = 0
148  vois_tri(:,:) = 0
149  nbtri = 0
150  nv = nvois(ipoin)
151  adr = iadr(ipoin)
152  DO ivois = 1, nv
153  ielem = neigh(adr+ivois)
154  DO iface = 1 , nface
155  IF ( ifabor(ielem,iface) .EQ. 0 ) THEN
156  i1 = ikle(ielem,somfac(1,iface))
157  i2 = ikle(ielem,somfac(2,iface))
158  i3 = ikle(ielem,somfac(3,iface))
159  m1 = max(i1,(max(i2,i3)))
160  m3 = min(i1,(min(i2,i3)))
161  m2 = i1+i2+i3-m1-m3
162  found = .false.
163  DO itri = 1, nbtri
164  IF ( ikle_tri(itri,1) .EQ. m1 ) THEN
165  IF ( ikle_tri(itri,2) .EQ. m2 .AND.
166  & ikle_tri(itri,3) .EQ. m3 ) THEN
167  ielem2 = vois_tri(itri,1)
168  iface2 = vois_tri(itri,2)
169  ifabor(ielem ,iface ) = ielem2
170  ifabor(ielem2,iface2) = ielem
171  found = .true.
172  END IF
173  END IF
174  END DO
175  IF ( .NOT. found) THEN
176  nbtri = nbtri + 1
177  ikle_tri(nbtri,1) = m1
178  ikle_tri(nbtri,2) = m2
179  ikle_tri(nbtri,3) = m3
180  vois_tri(nbtri,1) = ielem
181  vois_tri(nbtri,2) = iface
182  END IF
183  END IF
184  END DO
185 !
186  END DO
187  END DO
188  !
189  neleb = count(ifabor==0)
190  DEALLOCATE(neigh)
191  DEALLOCATE(ikle_tri)
192  DEALLOCATE(vois_tri)
193  DEALLOCATE(ifabor)
194  !-----------------------------------------------------------------------
195  RETURN
196  END SUBROUTINE calc_neleb
197 
198  END MODULE util_pares