The TELEMAC-MASCARET system  trunk
partitioner.F
Go to the documentation of this file.
1 ! **************
2  SUBROUTINE partitioner
3 ! **************
4  & (pmethod, nelem, npoin, ndp, nparts, ikles, epart, npart)
5 !
6 !
7 !***********************************************************************
8 ! PARALLEL V6P2 21/08/2010
9 !***********************************************************************
10 !
11 !brief call to the partionning software
12 !
13 !history R. KOPMANN (BAW)
14 !+
15 !+
16 !+ created
17 !
18 !
19 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
20 !| PMETHOD |<--| 1: FOR METIS 2: FOR SCOTCH
21 !| NELEM |<--| THE NUMBER OF ELEMENTS
22 !| NDP |<--| THE NUMBE OF POINT PER ELEMENT
23 !| NPARTS |<--| NUMBER OF PARTITIONS
24 !| IKLES |<--| CONNECTIVITY TABLE
25 !| EPART |-->| PARTITION NUMBER OF AN ELEMENT
26 !| MYPART |-->| PARTITION NUMBER OF A POINT
27 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
28 !
29  USE iso_c_binding
30 !
32  USE c_binding
33  IMPLICIT NONE
34 #if defined HAVE_SCOTCH
35  include 'scotchf.h'
36 #endif
37 !
38  INTEGER, INTENT(IN) :: pmethod
39  INTEGER, INTENT(IN) :: nelem
40  INTEGER, INTENT(IN) :: npoin
41  INTEGER, INTENT(IN) :: ndp
42  INTEGER, INTENT(IN) :: ikles(nelem*ndp)
43  INTEGER, INTENT(IN) :: nparts
44  INTEGER, INTENT(OUT) :: epart(nelem)
45  INTEGER, INTENT(OUT) :: npart(npoin)
46 !
47 !-----------------------------------------------------------------------
48 !
49 !
50 !
51  INTEGER i,j,k,err,numflag,edgecut,ncommonnodes
52  INTEGER, ALLOCATABLE :: eptr(:), eind(:)
53 !
54 ! SCOTCH
55 !
56 #if defined HAVE_SCOTCH
57  REAL*8, DIMENSION(SCOTCH_GRAPHDIM) :: scotchgraph
58  REAL*8, DIMENSION(SCOTCH_STRATDIM) :: scotchstrat
59  TYPE(c_ptr), POINTER :: ptxadj(:), ptadjncy(:)
60  INTEGER, ALLOCATABLE :: recvbuf(:)
61  INTEGER, POINTER :: xadj2(:), adjncy2(:)
62 #endif
63 
64  IF(pmethod.EQ.1) THEN
65  WRITE(lu,*) 'BEGIN PARTITIONING WITH METIS'
66 ! NEW METIS INTERFACE (>= VERSION 5) :
67 !
68 ! EPTR, EIND: THESE ARRAYS SPECIFIES THE ELEMENTS
69 ! THAT ARE STORED LOCALLY AT EACH PROCESSOR.
70 ! CF. DISCUSSION IN SECTION 4.3 (?)
71 !
72  ALLOCATE(eptr(nelem+1),stat=err)
73  CALL check_allocate(err,'EPTR')
74  ALLOCATE(eind(nelem*ndp),stat=err)
75  CALL check_allocate(err,'EIND')
76 !
77 !
78  DO i=1,nelem+1
79  eptr(i) = (i-1)*ndp + 1
80  ENDDO
81 !
82  k=1
83  DO i=1,nelem
84  DO j=1,ndp
85  eind(k) = ikles((i-1)*ndp+j)
86  k = k + 1
87  ENDDO
88  ENDDO
89 !
90 ! END OF CORRECTION JMH 04/07/2012
91 !
92 ! SWITCH TO C NUMBERING
93  eind = eind -1
94  eptr = eptr -1
95 !
96 ! METIS REQUIRES THE NUMBER OF COMMON POINT NEEDED BETWEEN 2 ELEMENTS TO MAKE AN EDGE
97 ! NCOMMONNODES = 2 FOR TRIANGLE OR RECTANGLE
98 ! NCOMMONNODES = 3 FOR TETRAHEDRE
99 ! NCOMMONNODES = 4 FOR HEXAHEDRE
100 
101 !
102  IF (ndp==3.OR.ndp==6) THEN
103  ncommonnodes = 2 ! FOR TRIANGLE OR PRISM
104  ELSE IF(ndp==4) THEN
105  ncommonnodes = 3 ! FORT TETRAHEDRON
106  ELSE
107  WRITE(lu,*) 'METIS: IMPLEMENTED FOR TRIANGLES OR PRISMS ONLY'
108  CALL plante(1)
109  ENDIF
110 !
111 ! WE ONLY USE METIS_PARTMESHDUAL AS ONLY THE FINITE ELEMENTS PARTITION
112 ! IS RELEVANT HERE.
113 !
114 ! IMPORTANT: WE USE FORTRAN-LIKE FIELD ELEMENTS NUMBERING 1...N
115 ! IN C VERSION, 0...N-1 NUMBERING IS APPLIED!!!
116 !
117  numflag = 1
118 !
119 #if defined HAVE_MPI
121  & (nelem, npoin, eptr, eind,
122  & ncommonnodes, nparts,
123  & edgecut, epart, npart)
124 #else
125  WRITE(lu,*) 'ERROR: TRY TO RUN PARTEL WITH A '//
126  & 'SERIAL CONFIGURATION'
127  CALL plante(1)
128 #endif
129 !
130 ! DEALLOCATING TEMPORARY ARRAYS FOR METIS
131 !
132 ! EPART IS AN ARRAY
133  epart = epart+1
134  DEALLOCATE(eptr)
135  DEALLOCATE(eind)
136  ELSE IF(pmethod.EQ.2) THEN
137 #if defined HAVE_SCOTCH
138 !
139 ! SCOTCH PARTITIONER
140 !
141  WRITE(lu,*) 'BEGIN PARTITIONING WITH SCOTCH'
142  ALLOCATE (eptr(nelem+1),stat=err)
143  CALL check_allocate(err,"EPTR")
144  ALLOCATE (eind(nelem*ndp),stat=err)
145  CALL check_allocate(err,"EIND")
146 !
147 ! bUILDING EPTR AND EIND SAME AS BEFORE.
148 !
149  DO i=1,nelem+1
150  eptr(i) = (i-1)*ndp + 1
151  ENDDO
152 !
153  k=1
154  DO i=1,nelem
155  DO j=1,ndp
156  eind(k) = ikles((i-1)*ndp+j)
157  k = k + 1
158  ENDDO
159  ENDDO
160 ! THE NUMBER OF COMMON POINT NEEDED BETWEEN 2 ELEMENTS TO MAKE AN
161 ! EDGE
162 ! NCOMMONNODES = 2 FOR TRIANGLE OR RECTANGLE
163 ! NCOMMONNODES = 3 FOR TETRAHEDRE
164 ! NCOMMONNODES = 4 FOR HEXAHEDRE
165  IF (ndp==3.OR.ndp==6) THEN
166  ncommonnodes = 2 ! FOR TRIANGLE OR RECTANGLE
167  ELSE
168  WRITE(lu,*)'SCOTCH: IMPLEMENTED FOR TRIANGLES OR PRISMS ONLY'
169  CALL plante(1)
170  ENDIF
171 
172 !
173 ! mETIS_MESHTODUAL USES POINTER OF POINTER (PTXADJ, PTADJNCY) SO IN ORDER TO USE THAT
174 ! IN FORTRAN WE USE THE ISO_BINDING MODULE
175 !
176  ALLOCATE(ptxadj(1))
177  ALLOCATE(ptadjncy(1))
178 !
179 ! BUILD THE DUAL GRAPH BY CALLING THE METIS SUBROUTINE
180 !
181  numflag = 1
182  CALL metis_meshtodual
183  & (nelem, npoin, eptr, eind, ncommonnodes, numflag,
184  & ptxadj, ptadjncy)
185 
186 !
187 ! TRANSFORM THE C POINTER OF POINTER BACK TO A FORTRAN ARRAY
188 !
189  ALLOCATE(recvbuf(1))
190  recvbuf(1) = nelem+1
191  CALL c_f_pointer(ptxadj(1),xadj2,recvbuf)
192 !
193  recvbuf(1) = xadj2(nelem+1)-1
194  CALL c_f_pointer(ptadjncy(1),adjncy2,recvbuf)
195  DEALLOCATE(recvbuf)
196 !
197 ! INITIALIZE THE GRAPH AND THE STRATEGY USED BY SCOTCH FOR THE
198 ! PARTITIONING WE USE THE DEFAULT STRATEGY
199 !
200  CALL scotchfstratinit(scotchstrat, err)
201  IF (err.NE.0) THEN
202  WRITE(lu,*) 'SCOTCH ERROR: CANNOT INITIALIZE STRAT'
203  CALL plante(1)
204  ENDIF
205 !
206  CALL scotchfgraphinit(scotchgraph, err)
207  IF (err.NE.0) THEN
208  WRITE(lu,*) 'SCOTCH ERROR: CANNOT INITIALIZE GRAPH'
209  CALL plante(1)
210  ENDIF
211 !
212  CALL scotchfgraphbuild ( scotchgraph, ! GRAFDAT
213  & numflag, ! BASEVAL
214  & nelem, ! VERTNBR
215  & xadj2(1:nelem), ! VERTTAB
216  & xadj2(2:nelem+1), ! VENDTAB
217  & xadj2(1:nelem), ! VELOTAB, VERTEX WEIGHTS (nULL)
218  & xadj2(1:nelem), ! VLBLTAB, VERTEX LABELS (nULL)
219  & xadj2(nelem+1)-1, ! EDGENBR
220  & adjncy2, ! EDGETAB
221  & adjncy2, ! EDLOTAB (nULL)
222  & err )
223 !
224  IF (err.NE.0) THEN
225  WRITE(lu,*) 'SCOTCH ERROR: CANNOT BUILD GRAPH'
226  CALL plante(1)
227  ENDIF
228 !
229  CALL scotchfgraphcheck(scotchgraph,err)
230  IF (err.NE.0) THEN
231  WRITE(lu,*) 'SCOTCH ERROR: GRAPH NOT CONSISTANT'
232  CALL plante(1)
233  ENDIF
234 !
235  ! RUN PARTITIONING
236  CALL scotchfgraphpart ( scotchgraph,
237  & nparts,
238  & scotchstrat,
239  & epart,
240  & err )
241 !
242  IF (err.NE.0) THEN
243  WRITE(lu,*) 'SCOTCH ERROR: CANNOT PARTITION GRAPH'
244  CALL plante(1)
245  END IF
246 !!!! CHANGING EPART NUMBERING TO 1-NPART
247  epart = epart + 1
248 
249  CALL scotchfgraphexit (scotchgraph)
250  CALL scotchfstratexit (scotchstrat)
251 
252 !
253 ! THOSE DEALLOCATION CAN GENERATE ERROR WITH SOME COMPILER
254 ! DEALLOCATE(XADJ2)
255 ! DEALLOCATE(ADJNCY2)
256  DEALLOCATE(ptxadj)
257  DEALLOCATE(ptadjncy)
258  DEALLOCATE(eind)
259  DEALLOCATE(eptr)
260 #else
261  WRITE(lu,*) "TRYING TO USE SCOTCH TO PARTIONNE WHEN SCOTCH",
262  & " IS NOT INSTALLED"
263  CALL plante(1)
264 #endif
265  ENDIF
266  END SUBROUTINE partitioner
267 
subroutine mymetis_partmeshdual(NELEM, NPOIN, EPTR, EIND, NCOMMONNODES, NPARTS, EDGECUT, EPART, NPART)
Definition: c_binding.F:55