SFEMaNS  version 4.1 (work in progress)
Reference documentation for SFEMaNS
 All Classes Files Functions Variables Groups Pages
metis_distribution_sfemans.f90
Go to the documentation of this file.
3  PRIVATE
4  REAL(KIND=8) :: epsilon = 1.d-10
5 !!$ Dummy for metis...
6  INTEGER :: METIS_NOPTIONS=40, METIS_OPTION_NUMBERING=18
7  !==Go see in metis.h the actual values assigned to METIS_NOPTIONS, METIS_OPTION_NUMBERING
8 !!$ Dummy for metis...
9 #include "petsc/finclude/petsc.h"
10 CONTAINS
11  !===Convention: Domain NS \subset domain Temp \subset Domain H
12  SUBROUTINE part_mesh_m_t_h_phi(nb_proc,list_u, list_T_in, list_h_in, list_phi ,mesh,list_of_interfaces,part,my_periodic)
13  USE def_type_mesh
14  USE my_util
15  USE sub_plot
16  USE periodic
17  IMPLICIT NONE
18  TYPE(mesh_type) :: mesh
19  INTEGER, DIMENSION(mesh%me) :: part
20  INTEGER, DIMENSION(:) :: list_of_interfaces
21  INTEGER, DIMENSION(:) :: list_u, list_t_in, list_h_in, list_phi
22  TYPE(periodic_data), OPTIONAL :: my_periodic
23 
24  LOGICAL, DIMENSION(mesh%mes) :: virgins
25  INTEGER, DIMENSION(3,mesh%me) :: neigh_new
26  INTEGER, DIMENSION(5) :: opts
27  INTEGER, DIMENSION(SIZE(mesh%jjs,1)) :: i_loc
28  INTEGER, DIMENSION(:), ALLOCATABLE :: xadj_u, xadj_t, xadj_h, xadj_phi, list_h, list_t
29  INTEGER, DIMENSION(:), ALLOCATABLE :: xind_u, xind_t, xind_h, xind_phi
30  INTEGER, DIMENSION(:), ALLOCATABLE :: vwgt, adjwgt
31  INTEGER, DIMENSION(:), ALLOCATABLE :: u2glob, t2glob, h2glob, phi2glob
32  INTEGER, DIMENSION(:), ALLOCATABLE :: part_u, part_t, part_h, part_phi
33  INTEGER, DIMENSION(1) :: jm_loc
34  INTEGER, DIMENSION(mesh%np,3) :: per_pts
35  INTEGER, DIMENSION(mesh%me) :: glob2loc
36  INTEGER, DIMENSION(mesh%np) :: indicator
37  INTEGER, DIMENSION(3) :: j_loc
38  INTEGER :: nb_neigh, edge, m, ms, n, nb, numflag, p, wgtflag, j, &
39  ns, nws, msop, nsop, proc, iop, mop, s2, k, me_u, me_t, me_h, me_phi, idm
40  REAL(KIND=8) :: err
41  LOGICAL :: test
42  REAL(KIND=8), DIMENSION(:), ALLOCATABLE :: tpwgts
43  INTEGER, DIMENSION(METIS_NOPTIONS) :: metis_opt
44  REAL(KIND=8), DIMENSION(1) :: ubvec
45  petscmpiint :: nb_proc
46 !!$ WARNING, FL 1/2/13 : TO BE ADDED IN NEEDED
47  petscerrorcode :: ierr
48  petscmpiint :: rank
49 !!$ WARNING, FL 1/2/13 : TO BE ADDED IN NEEDED
50 
51  IF (nb_proc==1) THEN
52  part = 1
53  RETURN
54  END IF
55  glob2loc = 0
56 
57  !===Create list_T = list_T_in \ list_u
58  nb = 0
59  DO j = 1, SIZE(list_t_in)
60  IF (minval(abs(list_t_in(j)-list_u))==0) cycle
61  nb = nb + 1
62  END DO
63  ALLOCATE(list_t(nb))
64  nb = 0
65  DO j = 1, SIZE(list_t_in)
66  IF (minval(abs(list_t_in(j)-list_u))==0) cycle
67  nb = nb + 1
68  list_t(nb) = list_t_in(j)
69  END DO
70  !==Done with list_T
71 
72  !===Create list_h = list_h_in \ list_T_in
73  nb = 0
74  DO j = 1, SIZE(list_h_in)
75  IF (minval(abs(list_h_in(j)-list_t_in))==0) cycle
76  nb = nb + 1
77  END DO
78  ALLOCATE(list_h(nb))
79  nb = 0
80  DO j = 1, SIZE(list_h_in)
81  IF (minval(abs(list_h_in(j)-list_t_in))==0) cycle
82  nb = nb + 1
83  list_h(nb) = list_h_in(j)
84  END DO
85  !==Done with list_h
86 
87  !===Create neigh_new for interfaces
88  nws = SIZE( mesh%jjs,1)
89  neigh_new = mesh%neigh
90  IF (SIZE(list_of_interfaces)/=0) THEN
91  virgins = .true.
92  DO ms = 1, mesh%mes
93  IF (.NOT.virgins(ms)) cycle
94  IF (minval(abs(mesh%sides(ms)-list_of_interfaces))/=0) cycle !==ms not on a cut
95  i_loc = mesh%jjs(:,ms)
96  DO msop = 1, mesh%mes
97  IF (msop==ms .OR. .NOT.virgins(msop)) cycle
98  IF (minval(abs(mesh%sides(msop)-list_of_interfaces))/=0) cycle !==msop not on a cut
99  DO ns = 1, nws
100  test = .false.
101  DO nsop = 1, nws
102  iop = mesh%jjs(nsop,msop)
103  IF (maxval(abs(mesh%rr(:,i_loc(ns))-mesh%rr(:,iop))).LT.epsilon) THEN
104  test = .true.
105  EXIT
106  END IF
107  END DO
108  IF (.NOT.test) THEN
109  EXIT !==This msop does not coincide with ms
110  END IF
111  END DO
112  IF (test) EXIT
113  END DO
114  IF (.NOT.test) THEN
115  CALL error_petsc(.NOT.'BUG in part_mesh_M_T_H_phi, test ')
116  END IF
117  DO n = 1, 3
118  IF (neigh_new(n,mesh%neighs(msop))==0) THEN
119  neigh_new(n,mesh%neighs(msop)) = mesh%neighs(ms)
120  END IF
121  IF (neigh_new(n,mesh%neighs(ms))==0) THEN
122  neigh_new(n,mesh%neighs(ms)) = mesh%neighs(msop)
123  END IF
124  END DO
125  virgins(ms) = .false.
126  virgins(msop) = .false.
127  END DO
128  END IF
129  !===End Create neigh_new for interfaces
130 
131  !===Create neigh_new for periodic faces
132  IF (present(my_periodic)) THEN
133  IF (my_periodic%nb_periodic_pairs/=0) THEN
134  DO ms = 1, mesh%mes
135  m = mesh%neighs(ms)
136  IF (minval(abs(mesh%sides(ms)-my_periodic%list_periodic(1,:))) == 0) THEN
137  jm_loc = minloc(abs(mesh%sides(ms)-my_periodic%list_periodic(1,:)))
138  s2 = my_periodic%list_periodic(2,jm_loc(1))
139  test = .false.
140  DO msop = 1, mesh%mes
141  IF (mesh%sides(msop) /= s2) cycle
142 
143  err = 0.d0
144  DO ns = 1, SIZE(my_periodic%vect_e,1)
145  err = err + abs(sum(mesh%rr(ns,mesh%jjs(:,ms))-mesh%rr(ns,mesh%jjs(:,msop)) &
146  +my_periodic%vect_e(ns,jm_loc(1))))
147  END DO
148 
149  IF (err .LE. epsilon) THEN
150  test = .true.
151  EXIT
152  END IF
153  END DO
154  IF (.NOT.test) THEN
155  CALL error_petsc('BUG in part_mesh_M_T_H_phi, mop not found')
156  END IF
157  mop = mesh%neighs(msop)
158  DO n = 1, 3
159  IF (neigh_new(n,m) == 0) THEN
160  neigh_new(n,m) = mop
161  END IF
162  IF (neigh_new(n,mop) == 0) THEN
163  neigh_new(n,mop) = m
164  END IF
165  END DO
166  END IF
167  END DO
168  END IF
169  END IF
170  !===End Create neigh_new for periodic faces
171 
172  !===Create glob2loc and u2glob, T2glob, h2glob, phi2glob
173  me_u = 0
174  me_t = 0
175  me_h = 0
176  me_phi = 0
177  DO m = 1, mesh%me
178  idm = mesh%i_d(m)
179  IF (minval(abs(idm-list_u))==0) THEN
180  me_u = me_u + 1
181  ELSE IF (minval(abs(idm-list_t))==0) THEN
182  me_t = me_t + 1
183  ELSE IF (minval(abs(idm-list_h))==0) THEN
184  me_h = me_h + 1
185  ELSE IF (minval(abs(idm-list_phi))==0) THEN
186  me_phi = me_phi + 1
187  ELSE
188  CALL error_petsc('BUG in part_mesh_M_T_H_phi : element not in the mesh')
189  END IF
190  END DO
191  ALLOCATE(u2glob(me_u), t2glob(me_t), h2glob(me_h), phi2glob(me_phi))
192  me_u = 0
193  me_t = 0
194  me_h = 0
195  me_phi = 0
196  DO m = 1, mesh%me
197  idm = mesh%i_d(m)
198  IF (minval(abs(idm-list_u))==0) THEN
199  me_u = me_u + 1
200  u2glob(me_u) = m
201  glob2loc(m) = me_u
202  ELSE IF (minval(abs(idm-list_t))==0) THEN
203  me_t = me_t + 1
204  t2glob(me_t) = m
205  glob2loc(m) = me_t
206  ELSE IF (minval(abs(idm-list_h))==0) THEN
207  me_h = me_h + 1
208  h2glob(me_h) = m
209  glob2loc(m) = me_h
210  ELSE IF (minval(abs(idm-list_phi))==0) THEN
211  me_phi = me_phi + 1
212  phi2glob(me_phi) = m
213  glob2loc(m) = me_phi
214  ELSE
215  CALL error_petsc('BUG in part_mesh_M_T_H_phi: element not in the mesh')
216  END IF
217  END DO
218  !===End Create glob2loc and u2glob, T2glob, h2glob, phi2glob
219 
220  !===Create the connectivity arrays Xind and Xadj based on neigh (for Metis)
221  nb_neigh = SIZE(mesh%neigh,1)
222  ALLOCATE(xind_u(me_u+1), xind_t(me_t+1), xind_h(me_h+1), xind_phi(me_phi+1))
223  xind_u(1) = 1
224  DO k = 1, me_u
225  m = u2glob(k)
226  nb = 0
227  DO n = 1, nb_neigh
228  mop = neigh_new(n,m)
229  IF (mop==0) cycle
230  IF (minval(abs(mesh%i_d(mop)-list_u))/=0) cycle
231  nb = nb + 1
232  END DO
233  xind_u(k+1) = xind_u(k) + nb
234  END DO
235  xind_t(1) = 1
236  DO k = 1, me_t
237  m = t2glob(k)
238  nb = 0
239  DO n = 1, nb_neigh
240  mop = neigh_new(n,m)
241  IF (mop==0) cycle
242  IF (minval(abs(mesh%i_d(mop)-list_t))/=0) cycle
243  nb = nb + 1
244  END DO
245  xind_t(k+1) = xind_t(k) + nb
246  END DO
247  xind_h(1) = 1
248  DO k = 1, me_h
249  m = h2glob(k)
250  nb = 0
251  DO n = 1, nb_neigh
252  mop = neigh_new(n,m)
253  IF (mop==0) cycle
254  IF (minval(abs(mesh%i_d(mop)-list_h))/=0) cycle
255  nb = nb + 1
256  END DO
257  xind_h(k+1) = xind_h(k) + nb
258  END DO
259  xind_phi(1) = 1
260  DO k = 1, me_phi
261  m = phi2glob(k)
262  nb = 0
263  DO n = 1, nb_neigh
264  mop = neigh_new(n,m)
265  IF (mop==0) cycle
266  IF (minval(abs(mesh%i_d(mop)-list_phi))/=0) cycle
267  nb = nb + 1
268  END DO
269  xind_phi(k+1) = xind_phi(k) + nb
270  END DO
271 
272  ALLOCATE(xadj_u(xind_u(me_u+1)-1))
273  ALLOCATE(xadj_t(xind_t(me_t+1)-1))
274  ALLOCATE(xadj_h(xind_h(me_h+1)-1))
275  ALLOCATE(xadj_phi(xind_phi(me_phi+1)-1))
276  p = 0
277  DO k = 1, me_u
278  m = u2glob(k)
279  DO n = 1, nb_neigh
280  mop = neigh_new(n,m)
281  IF (mop==0) cycle
282  IF (minval(abs(mesh%i_d(mop)-list_u))/=0) cycle
283  p = p + 1
284  xadj_u(p) = glob2loc(mop)
285  END DO
286  END DO
287  IF (p/=xind_u(me_u+1)-1) THEN
288  CALL error_petsc('BUG in part_mesh_M_T_H_phi, p/=xind_u(me_u+1)-1')
289  END IF
290  p = 0
291  DO k = 1, me_t
292  m = t2glob(k)
293  DO n = 1, nb_neigh
294  mop = neigh_new(n,m)
295  IF (mop==0) cycle
296  IF (minval(abs(mesh%i_d(mop)-list_t))/=0) cycle
297  p = p + 1
298  xadj_t(p) = glob2loc(mop)
299  END DO
300  END DO
301  IF (p/=xind_t(me_t+1)-1) THEN
302  CALL error_petsc('BUG in part_mesh_M_T_H_phi, p/=xind_T(me_T+1)-1')
303  END IF
304  p = 0
305  DO k = 1, me_h
306  m = h2glob(k)
307  DO n = 1, nb_neigh
308  mop = neigh_new(n,m)
309  IF (mop==0) cycle
310  IF (minval(abs(mesh%i_d(mop)-list_h))/=0) cycle
311  p = p + 1
312  xadj_h(p) = glob2loc(mop)
313  END DO
314  END DO
315  IF (p/=xind_h(me_h+1)-1) THEN
316  CALL error_petsc('BUG in part_mesh_M_T_H_phi, p/=xind_h(me_h+1)-1')
317  END IF
318  p = 0
319  DO k = 1, me_phi
320  m = phi2glob(k)
321  DO n = 1, nb_neigh
322  mop = neigh_new(n,m)
323  IF (mop==0) cycle
324  IF (minval(abs(mesh%i_d(mop)-list_phi))/=0) cycle
325  p = p + 1
326  xadj_phi(p) = glob2loc(mop)
327  END DO
328  END DO
329  IF (p/=xind_phi(me_phi+1)-1) THEN
330  CALL error_petsc('BUG in part_mesh_M_T_H_phi, p/=xind_phi(me_phi+1)-1')
331  END IF
332  !===End Create the connectivity arrays Xind and Xadj based on neigh (for Metis)
333 
334  !===Create partitions
335  opts = 0
336  numflag = 1
337  wgtflag = 2
338  ALLOCATE(tpwgts(nb_proc))
339  tpwgts=1.d0/nb_proc
340  CALL metis_setdefaultoptions(metis_opt)
341  metis_opt(metis_option_numbering)=1
342  ubvec=1.01
343  IF (me_u /= 0) THEN
344  ALLOCATE(vwgt(me_u), adjwgt(SIZE(xadj_u)), part_u(me_u))
345  vwgt = 1
346  adjwgt = 1
347  CALL metis_partgraphrecursive(me_u, 1, xind_u, xadj_u, vwgt, vwgt, adjwgt, nb_proc, tpwgts, ubvec, metis_opt, edge, part_u)
348  END IF
349  IF (me_t /= 0) THEN
350  IF (ALLOCATED(vwgt)) THEN
351  DEALLOCATE(vwgt, adjwgt)
352  END IF
353  ALLOCATE(vwgt(me_t), adjwgt(SIZE(xadj_t)), part_t(me_t))
354  vwgt = 1
355  adjwgt = 1
356  CALL metis_partgraphrecursive(me_t, 1, xind_t, xadj_t, vwgt, vwgt, adjwgt, nb_proc, tpwgts, ubvec, metis_opt, edge, part_t)
357  END IF
358  IF (me_h /= 0) THEN
359  IF (ALLOCATED(vwgt)) THEN
360  DEALLOCATE(vwgt, adjwgt)
361  END IF
362  ALLOCATE(vwgt(me_h), adjwgt(SIZE(xadj_h)), part_h(me_h))
363  vwgt = 1
364  adjwgt = 1
365  CALL metis_partgraphrecursive(me_h, 1, xind_h, xadj_h, vwgt, vwgt, adjwgt, nb_proc,tpwgts, ubvec, metis_opt, edge, part_h)
366  END IF
367  IF (me_phi /= 0) THEN
368  IF (ALLOCATED(vwgt)) THEN
369  DEALLOCATE(vwgt, adjwgt)
370  END IF
371  ALLOCATE(vwgt(me_phi), adjwgt(SIZE(xadj_phi)), part_phi(me_phi))
372  vwgt = 1
373  adjwgt = 1
374  CALL metis_partgraphrecursive(me_phi, 1, xind_phi,xadj_phi,vwgt, vwgt, adjwgt, nb_proc,tpwgts, &
375  ubvec, metis_opt, edge, part_phi)
376  END IF
377  !===Create global partition 'part'
378  part = -1
379  IF (me_u/=0) THEN
380  part(u2glob(:)) = part_u
381  END IF
382  IF (me_t/=0) THEN
383  part(t2glob(:)) = part_t
384  END IF
385  IF (me_h/=0) THEN
386  part(h2glob(:)) = part_h
387  END IF
388  IF (me_phi/=0) THEN
389  part(phi2glob(:)) = part_phi
390  END IF
391  IF (minval(part)==-1) THEN
392  CALL error_petsc('BUG in part_mesh_mhd_bis, MINVAL(part) == -1')
393  END IF
394  !===End Create global partition
395 
396  !===Create parts and modify part
397  !===Search on the boundary whether ms is on a cut.
398  IF (SIZE(mesh%jj,1)/=3) THEN
399  write(*,*) 'SIZE(mesh%jj,1)', SIZE(mesh%jj,1)
400  CALL error_petsc('BUG in part_mesh_M_T_H_phi, SIZE(mesh%jj,1)/=3')
401  END IF
402  indicator = -1
403  nws = SIZE( mesh%jjs,1)
404  IF (SIZE(list_of_interfaces)/=0) THEN
405  virgins = .true.
406  DO ms = 1, mesh%mes
407  IF (.NOT.virgins(ms)) cycle
408  IF (minval(abs(mesh%sides(ms)-list_of_interfaces))/=0) cycle !==ms not on a cut
409  i_loc = mesh%jjs(:,ms)
410  DO msop = 1, mesh%mes
411  IF (msop==ms .OR. .NOT.virgins(msop)) cycle
412  IF (minval(abs(mesh%sides(msop)-list_of_interfaces))/=0) cycle !==msop not on a cut
413  DO ns = 1, nws
414  test = .false.
415  DO nsop = 1, nws
416  iop = mesh%jjs(nsop,msop)
417  IF (maxval(abs(mesh%rr(:,i_loc(ns))-mesh%rr(:,iop))).LT.epsilon) THEN
418  test = .true.
419  EXIT
420  END IF
421  END DO
422  IF (.NOT.test) THEN
423  EXIT !==This msop does not coincide with ms
424  END IF
425  END DO
426  IF (test) EXIT
427  END DO
428  IF (.NOT.test) THEN
429  CALL error_petsc(.NOT.'BUG in part_mesh_M_T_H_phi, test ')
430  END IF
431  IF (part(mesh%neighs(ms)) == part(mesh%neighs(msop))) cycle !==ms is an internal cut
432  proc = min(part(mesh%neighs(ms)),part(mesh%neighs(msop)))
433  part(mesh%neighs(ms)) = proc !make sure interface are internal
434  part(mesh%neighs(msop)) = proc !make sure interface are internal
435  virgins(ms) = .false.
436  virgins(msop) = .false.
437  indicator(mesh%jjs(:,ms)) = proc
438  indicator(mesh%jjs(:,msop)) = proc
439  END DO
440  END IF
441  !===Fix the partition so that all the cells having one vertex on an
442  !===interface belong to the same processor as those sharing this vertices and
443  !===having two vertices on the interface (JLG + DCQ July 22 2015)
444  DO m = 1, mesh%me
445  j_loc = mesh%jj(:,m)
446  n = maxval(indicator(j_loc))
447  IF (n == -1) cycle
448  IF (indicator(j_loc(1))*indicator(j_loc(2))*indicator(j_loc(3))<0) cycle
449  part(m) = n
450  END DO
451  !===End create parts and modify part
452 
453  !===Move the two elements with one periodic face on same processor
454  IF (present(my_periodic)) THEN
455  IF (my_periodic%nb_periodic_pairs/=0) THEN
456  DO j = 1, mesh%np
457  per_pts(j,1) = j
458  END DO
459  per_pts(:,2:3) = 0
460  DO ms = 1, mesh%mes
461  m = mesh%neighs(ms)
462  IF ((minval(abs(mesh%sides(ms)-my_periodic%list_periodic(1,:))) /=0) .AND. &
463  (minval(abs(mesh%sides(ms)-my_periodic%list_periodic(2,:))) /=0) ) cycle
464  DO ns = 1, SIZE(mesh%jjs,1)
465  j = mesh%jjs(ns,ms)
466  per_pts(j,2) = m
467  DO msop = 1, mesh%mes
468  IF (minval(abs(mesh%sides(msop)-my_periodic%list_periodic(:,:))) /=0 ) cycle
469  IF (msop == ms) cycle
470  DO nsop = 1, SIZE(mesh%jjs,1)
471  IF (mesh%jjs(nsop,msop)==j) THEN
472  per_pts(j,3) = mesh%neighs(msop)
473  END IF
474  END DO
475  END DO
476  END DO
477  END DO
478  CALL reassign_per_pts(mesh, part, per_pts)
479  DO ms = 1, mesh%mes
480  m = mesh%neighs(ms)
481  IF (minval(abs(mesh%sides(ms)-my_periodic%list_periodic(1,:))) /= 0) cycle
482  jm_loc = minloc(abs(mesh%sides(ms)-my_periodic%list_periodic(1,:)))
483  s2 = my_periodic%list_periodic(2,jm_loc(1))
484  test = .false.
485  DO msop = 1, mesh%mes
486  IF (mesh%sides(msop) /= s2) cycle
487  err = 0.d0
488  DO ns = 1, SIZE(my_periodic%vect_e,1)
489  err = err + abs(sum(mesh%rr(ns,mesh%jjs(:,ms))-mesh%rr(ns,mesh%jjs(:,msop)) &
490  +my_periodic%vect_e(ns,jm_loc(1))))
491  END DO
492  IF (err .LE. epsilon) THEN
493  test = .true.
494  EXIT
495  END IF
496  END DO
497  IF (.NOT.test) THEN
498  CALL error_petsc('BUG in part_mesh_M_T_H_phi, mop not found')
499  END IF
500  IF (part(mesh%neighs(ms)) /= part(mesh%neighs(msop))) THEN !==ms is an internal cut
501  proc = min(part(mesh%neighs(ms)),part(mesh%neighs(msop)))
502  part(mesh%neighs(ms)) = proc !make sure interface are internal
503  part(mesh%neighs(msop)) = proc !make sure interface are internal
504  END IF
505  END DO
506  END IF
507  END IF
508  !===End Move the two elements with one periodic face on same processor
509 
510 !!$ WARNING, FL 1/2/13 : TO BE ADDED IF NEEDED
511  !================================================
512  CALL mpi_comm_rank(mpi_comm_world,rank,ierr)
513  IF (rank==0) THEN
514  CALL plot_const_p1_label(mesh%jj, mesh%rr, 1.d0*part, 'dd.plt')
515  END IF
516  !================================================
517 !!$ WARNING, FL 1/2/13 : TO BE ADDED IF NEEDED
518 
519  DEALLOCATE(vwgt,adjwgt)
520  IF (ALLOCATED(xadj_u)) DEALLOCATE(xadj_u)
521  IF (ALLOCATED(xadj_t)) DEALLOCATE(xadj_t)
522  IF (ALLOCATED(xadj_h)) DEALLOCATE(xadj_h)
523  IF (ALLOCATED(xadj_phi)) DEALLOCATE(xadj_phi)
524  IF (ALLOCATED(list_t)) DEALLOCATE(list_t)
525  IF (ALLOCATED(list_h)) DEALLOCATE(list_h)
526  IF (ALLOCATED(xind_u)) DEALLOCATE(xind_u)
527  IF (ALLOCATED(xind_t)) DEALLOCATE(xind_t)
528  IF (ALLOCATED(xind_h)) DEALLOCATE(xind_h)
529  IF (ALLOCATED(xind_phi)) DEALLOCATE(xind_phi)
530  IF (ALLOCATED(u2glob)) DEALLOCATE(u2glob)
531  IF (ALLOCATED(t2glob)) DEALLOCATE(t2glob)
532  IF (ALLOCATED(h2glob)) DEALLOCATE(h2glob)
533  IF (ALLOCATED(phi2glob)) DEALLOCATE(phi2glob)
534  IF (ALLOCATED(part_u)) DEALLOCATE(part_u)
535  IF (ALLOCATED(part_t)) DEALLOCATE(part_t)
536  IF (ALLOCATED(part_h)) DEALLOCATE(part_h)
537  IF (ALLOCATED(part_phi)) DEALLOCATE(part_phi)
538 
539  DEALLOCATE(tpwgts)
540 
541  END SUBROUTINE part_mesh_m_t_h_phi
542 
543  SUBROUTINE part_mesh_mhd(nb_proc,vwgt,mesh,list_of_interfaces,part,my_periodic)
544  USE def_type_mesh
545  USE my_util
546  USE sub_plot
547  USE periodic
548  IMPLICIT NONE
549  TYPE(mesh_type) :: mesh
550  INTEGER, DIMENSION(mesh%me+1) :: xind
551  INTEGER, DIMENSION(mesh%me) :: vwgt, part
552  INTEGER, DIMENSION(:) :: list_of_interfaces
553  TYPE(periodic_data), OPTIONAL :: my_periodic
554 
555  LOGICAL, DIMENSION(mesh%mes) :: virgins
556  INTEGER, DIMENSION(3,mesh%me) :: neigh_new
557  INTEGER, DIMENSION(5) :: opts
558  INTEGER, DIMENSION(SIZE(mesh%jjs,1)) :: i_loc
559  INTEGER, DIMENSION(:), ALLOCATABLE :: xadj, adjwgt
560  INTEGER, DIMENSION(1) :: jm_loc
561  INTEGER, DIMENSION(mesh%np,3) :: per_pts
562  INTEGER :: nb_neigh, edge, m, ms, n, nb, numflag, p, wgtflag, j, &
563  ns, nws, msop, nsop, proc, iop, mop, s2
564  REAL(KIND=8) :: err
565  REAL(KIND=8), DIMENSION(:), ALLOCATABLE :: tpwgts
566  INTEGER, DIMENSION(METIS_NOPTIONS) :: metis_opt
567  REAL(KIND=8), DIMENSION(1) :: ubvec
568  LOGICAL :: test
569  petscmpiint :: nb_proc
570 !!$ WARNING, FL 1/2/13 : TO BE ADDED IN NEEDED
571  petscerrorcode :: ierr
572  petscmpiint :: rank
573 !!$ WARNING, FL 1/2/13 : TO BE ADDED IN NEEDED
574 
575  IF (nb_proc==1) THEN
576  part = 1
577  RETURN
578  END IF
579  nws = SIZE( mesh%jjs,1)
580  neigh_new = mesh%neigh
581  IF (SIZE(list_of_interfaces)/=0) THEN
582  virgins = .true.
583  DO ms = 1, mesh%mes
584  IF (.NOT.virgins(ms)) cycle
585  IF (minval(abs(mesh%sides(ms)-list_of_interfaces))/=0) cycle !==ms not on a cut
586  i_loc = mesh%jjs(:,ms)
587  DO msop = 1, mesh%mes
588  IF (msop==ms .OR. .NOT.virgins(msop)) cycle
589  IF (minval(abs(mesh%sides(msop)-list_of_interfaces))/=0) cycle !==msop not on a cut
590  DO ns = 1, nws
591  test = .false.
592  DO nsop = 1, nws
593  iop = mesh%jjs(nsop,msop)
594  IF (maxval(abs(mesh%rr(:,i_loc(ns))-mesh%rr(:,iop))).LT.epsilon) THEN
595  test = .true.
596  EXIT
597  END IF
598  END DO
599  IF (.NOT.test) THEN
600  EXIT !==This msop does not coincide with ms
601  END IF
602  END DO
603  IF (test) EXIT
604  END DO
605  IF (.NOT.test) THEN
606  CALL error_petsc(.NOT.'BUG in part_mesh_mhd, test ')
607  END IF
608  DO n = 1, 3
609  IF (neigh_new(n,mesh%neighs(msop))==0) THEN
610  neigh_new(n,mesh%neighs(msop)) = mesh%neighs(ms)
611  END IF
612  IF (neigh_new(n,mesh%neighs(ms))==0) THEN
613  neigh_new(n,mesh%neighs(ms)) = mesh%neighs(msop)
614  END IF
615  END DO
616  virgins(ms) = .false.
617  virgins(msop) = .false.
618  END DO
619  END IF
620 
621  !=================TEST PERIODIC==================
622  IF (present(my_periodic)) THEN
623  IF (my_periodic%nb_periodic_pairs/=0) THEN
624  DO ms = 1, mesh%mes
625  m = mesh%neighs(ms)
626  IF (minval(abs(mesh%sides(ms)-my_periodic%list_periodic(1,:))) == 0) THEN
627  jm_loc = minloc(abs(mesh%sides(ms)-my_periodic%list_periodic(1,:)))
628  s2 = my_periodic%list_periodic(2,jm_loc(1))
629  test = .false.
630  DO msop = 1, mesh%mes
631  IF (mesh%sides(msop) /= s2) cycle
632 
633  err = 0.d0
634  DO ns = 1, SIZE(my_periodic%vect_e,1)
635  err = err + abs(sum(mesh%rr(ns,mesh%jjs(:,ms))-mesh%rr(ns,mesh%jjs(:,msop)) &
636  +my_periodic%vect_e(ns,jm_loc(1))))
637  END DO
638 
639  IF (err .LE. epsilon) THEN
640  test = .true.
641  EXIT
642  END IF
643  END DO
644  IF (.NOT.test) THEN
645  CALL error_petsc('BUG, mop non trouve')
646  END IF
647  mop = mesh%neighs(msop)
648  DO n = 1, 3
649  IF (neigh_new(n,m) == 0) THEN
650  neigh_new(n,m) = mop
651  END IF
652  IF (neigh_new(n,mop) == 0) THEN
653  neigh_new(n,mop) = m
654  END IF
655  END DO
656  END IF
657  END DO
658  END IF
659  END IF
660  !================================================
661 
662 
663  ! Create the connectivity array based on neigh
664  nb_neigh = SIZE(mesh%neigh,1)
665  xind(1) = 1
666  DO m = 1, mesh%me
667  nb = 0
668  DO n = 1, nb_neigh
669  IF (neigh_new(n,m)==0) cycle
670  nb = nb + 1
671  END DO
672  xind(m+1) = xind(m) + nb
673  END DO
674  ALLOCATE(xadj(xind(mesh%me+1)-1))
675  p = 0
676  DO m = 1, mesh%me
677  DO n = 1, nb_neigh
678  IF (neigh_new(n,m)==0) cycle
679  p = p + 1
680  xadj(p) = neigh_new(n,m)
681  END DO
682  END DO
683  IF (p/=xind(mesh%me+1)-1) THEN
684  CALL error_petsc('BUG, p/=xind(mesh%me+1)-1')
685  END IF
686  ! End create the connectivity array based on neigh
687 
688  ALLOCATE(adjwgt(SIZE(xadj)))
689  opts = 0
690  !vwgt = 1
691  adjwgt = 1
692  numflag = 1 ! Fortran numbering of processors
693  wgtflag = 2
694  ALLOCATE(tpwgts(nb_proc))
695  tpwgts=1.d0/nb_proc
696  CALL metis_setdefaultoptions(metis_opt)
697  metis_opt(metis_option_numbering)=1
698  ubvec=1.01
699  CALL metis_partgraphrecursive(mesh%me, 1, xind,xadj,vwgt, vwgt, adjwgt, nb_proc,tpwgts , ubvec, metis_opt, edge, part)
700 !!$ CALL METIS_PartGraphRecursive(mesh%me,xind,xadj,vwgt,adjwgt,wgtflag, numflag, nb_proc, opts, edge, part)
701 
702  ! Create parts and modify part
703  !==Search on the boundary whether ms is on a cut.
704  nws = SIZE( mesh%jjs,1)
705  IF (SIZE(list_of_interfaces)/=0) THEN
706  virgins = .true.
707  DO ms = 1, mesh%mes
708  IF (.NOT.virgins(ms)) cycle
709  IF (minval(abs(mesh%sides(ms)-list_of_interfaces))/=0) cycle !==ms not on a cut
710  i_loc = mesh%jjs(:,ms)
711  DO msop = 1, mesh%mes
712  IF (msop==ms .OR. .NOT.virgins(msop)) cycle
713  IF (minval(abs(mesh%sides(msop)-list_of_interfaces))/=0) cycle !==msop not on a cut
714  DO ns = 1, nws
715  test = .false.
716  DO nsop = 1, nws
717  iop = mesh%jjs(nsop,msop)
718  IF (maxval(abs(mesh%rr(:,i_loc(ns))-mesh%rr(:,iop))).LT.epsilon) THEN
719  test = .true.
720  EXIT
721  END IF
722  END DO
723  IF (.NOT.test) THEN
724  EXIT !==This msop does not coincide with ms
725  END IF
726  END DO
727  IF (test) EXIT
728  END DO
729  IF (.NOT.test) THEN
730  CALL error_petsc(.NOT.'BUG in create_local_mesh, test ')
731  END IF
732  IF (part(mesh%neighs(ms)) == part(mesh%neighs(msop))) cycle !==ms is an internal cut
733  proc = min(part(mesh%neighs(ms)),part(mesh%neighs(msop)))
734  part(mesh%neighs(ms)) = proc !make sure interface are internal
735  part(mesh%neighs(msop)) = proc !make sure interface are internal
736  virgins(ms) = .false.
737  virgins(msop) = .false.
738  END DO
739  END IF
740  ! End create parts and modify part
741 
742  !=================TEST PERIODIC==================
743  IF (present(my_periodic)) THEN
744  IF (my_periodic%nb_periodic_pairs/=0) THEN
745 
746 
747  DO j = 1, mesh%np
748  per_pts(j,1) = j
749  END DO
750  per_pts(:,2:3) = 0
751  DO ms = 1, mesh%mes
752  m = mesh%neighs(ms)
753  IF ((minval(abs(mesh%sides(ms)-my_periodic%list_periodic(1,:))) /=0) .AND. &
754  (minval(abs(mesh%sides(ms)-my_periodic%list_periodic(2,:))) /=0) ) cycle
755  DO ns = 1, SIZE(mesh%jjs,1)
756  j = mesh%jjs(ns,ms)
757  per_pts(j,2) = m
758  DO msop = 1, mesh%mes
759  IF (minval(abs(mesh%sides(msop)-my_periodic%list_periodic(:,:))) /=0 ) cycle
760  IF (msop == ms) cycle
761  DO nsop = 1, SIZE(mesh%jjs,1)
762  IF (mesh%jjs(nsop,msop)==j) THEN
763  per_pts(j,3) = mesh%neighs(msop)
764  END IF
765  END DO
766  END DO
767  END DO
768  END DO
769 !!$ WRITE(*,*) per_pts(:,2)
770  CALL reassign_per_pts(mesh, part, per_pts)
771 
772  DO ms = 1, mesh%mes
773  m = mesh%neighs(ms)
774  IF (minval(abs(mesh%sides(ms)-my_periodic%list_periodic(1,:))) /= 0) cycle
775  jm_loc = minloc(abs(mesh%sides(ms)-my_periodic%list_periodic(1,:)))
776  s2 = my_periodic%list_periodic(2,jm_loc(1))
777  test = .false.
778  DO msop = 1, mesh%mes
779  IF (mesh%sides(msop) /= s2) cycle
780 
781  err = 0.d0
782  DO ns = 1, SIZE(my_periodic%vect_e,1)
783  err = err + abs(sum(mesh%rr(ns,mesh%jjs(:,ms))-mesh%rr(ns,mesh%jjs(:,msop)) &
784  +my_periodic%vect_e(ns,jm_loc(1))))
785  END DO
786 
787  IF (err .LE. epsilon) THEN
788  test = .true.
789  EXIT
790  END IF
791  END DO
792  IF (.NOT.test) THEN
793  CALL error_petsc('BUG, mop non trouve')
794  END IF
795  IF (part(mesh%neighs(ms)) /= part(mesh%neighs(msop))) THEN !==ms is an internal cut
796  proc = min(part(mesh%neighs(ms)),part(mesh%neighs(msop)))
797  part(mesh%neighs(ms)) = proc !make sure interface are internal
798  part(mesh%neighs(msop)) = proc !make sure interface are internal
799  END IF
800  END DO
801 
802  END IF
803  END IF
804 
805 !!$ WARNING, FL 1/2/13 : TO BE ADDED IN NEEDED
806  !================================================
807  CALL mpi_comm_rank(mpi_comm_world,rank,ierr)
808  IF (rank==0) THEN
809  CALL plot_const_p1_label(mesh%jj, mesh%rr, 1.d0*part, 'dd.plt')
810  END IF
811  !================================================
812 !!$ WARNING, FL 1/2/13 : TO BE ADDED IN NEEDED
813 
814  DEALLOCATE(xadj,adjwgt)
815  DEALLOCATE(tpwgts)
816 
817  END SUBROUTINE part_mesh_mhd
818 
819 
820  SUBROUTINE part_mesh_mhd_bis(nb_proc,list_u, list_h_in, list_phi ,mesh,list_of_interfaces,part,my_periodic)
821  USE def_type_mesh
822  USE my_util
823  USE sub_plot
824  USE periodic
825  IMPLICIT NONE
826  TYPE(mesh_type) :: mesh
827  INTEGER, DIMENSION(mesh%me) :: part
828  INTEGER, DIMENSION(:) :: list_of_interfaces
829  INTEGER, DIMENSION(:) :: list_u, list_h_in, list_phi
830  TYPE(periodic_data), OPTIONAL :: my_periodic
831 
832  LOGICAL, DIMENSION(mesh%mes) :: virgins
833  INTEGER, DIMENSION(3,mesh%me) :: neigh_new
834  INTEGER, DIMENSION(5) :: opts
835  INTEGER, DIMENSION(SIZE(mesh%jjs,1)) :: i_loc
836  INTEGER, DIMENSION(:), ALLOCATABLE :: xadj_u, xadj_h, xadj_phi, list_h
837  INTEGER, DIMENSION(:), ALLOCATABLE :: xind_u, xind_h, xind_phi
838  INTEGER, DIMENSION(:), ALLOCATABLE :: vwgt, adjwgt
839  INTEGER, DIMENSION(:), ALLOCATABLE :: u2glob, h2glob, phi2glob
840  INTEGER, DIMENSION(:), ALLOCATABLE :: part_u, part_h, part_phi
841  INTEGER, DIMENSION(1) :: jm_loc
842 !!$ INTEGER, DIMENSION(1) :: jloc
843  INTEGER, DIMENSION(mesh%np,3) :: per_pts
844  INTEGER, DIMENSION(mesh%me) :: glob2loc
845  INTEGER, DIMENSION(mesh%np) :: indicator
846  INTEGER, DIMENSION(3) :: j_loc
847  INTEGER :: nb_neigh, edge, m, ms, n, nb, numflag, p, wgtflag, j, &
848  ns, nws, msop, nsop, proc, iop, mop, s2, k, me_u, me_h, me_phi, idm
849  REAL(KIND=8) :: err
850  LOGICAL :: test
851  REAL(KIND=8), DIMENSION(:), ALLOCATABLE :: tpwgts
852  INTEGER, DIMENSION(METIS_NOPTIONS) :: metis_opt
853  REAL(KIND=8), DIMENSION(1) :: ubvec
854  petscmpiint :: nb_proc
855 !!$ WARNING, FL 1/2/13 : TO BE ADDED IN NEEDED
856  petscerrorcode :: ierr
857  petscmpiint :: rank
858 !!$ WARNING, FL 1/2/13 : TO BE ADDED IN NEEDED
859 
860  IF (nb_proc==1) THEN
861  part = 1
862  RETURN
863  END IF
864  glob2loc = 0
865  !Create list_h = list_h_in \ list_ns
866  nb = 0
867  DO j = 1, SIZE(list_h_in)
868  IF (minval(abs(list_h_in(j)-list_u))==0) cycle
869  nb = nb + 1
870  END DO
871  ALLOCATE(list_h(nb))
872  nb = 0
873  DO j = 1, SIZE(list_h_in)
874  IF (minval(abs(list_h_in(j)-list_u))==0) cycle
875  nb = nb + 1
876  list_h(nb) = list_h_in(j)
877  END DO
878 
879  !Done with list_h
880 
881  nws = SIZE( mesh%jjs,1)
882  neigh_new = mesh%neigh
883  IF (SIZE(list_of_interfaces)/=0) THEN
884  virgins = .true.
885  DO ms = 1, mesh%mes
886  IF (.NOT.virgins(ms)) cycle
887  IF (minval(abs(mesh%sides(ms)-list_of_interfaces))/=0) cycle !==ms not on a cut
888  i_loc = mesh%jjs(:,ms)
889  DO msop = 1, mesh%mes
890  IF (msop==ms .OR. .NOT.virgins(msop)) cycle
891  IF (minval(abs(mesh%sides(msop)-list_of_interfaces))/=0) cycle !==msop not on a cut
892  DO ns = 1, nws
893  test = .false.
894  DO nsop = 1, nws
895  iop = mesh%jjs(nsop,msop)
896  IF (maxval(abs(mesh%rr(:,i_loc(ns))-mesh%rr(:,iop))).LT.epsilon) THEN
897  test = .true.
898  EXIT
899  END IF
900  END DO
901  IF (.NOT.test) THEN
902  EXIT !==This msop does not coincide with ms
903  END IF
904  END DO
905  IF (test) EXIT
906  END DO
907  IF (.NOT.test) THEN
908  CALL error_petsc(.NOT.'BUG in part_mesh_mhd, test ')
909  END IF
910  DO n = 1, 3
911  IF (neigh_new(n,mesh%neighs(msop))==0) THEN
912  neigh_new(n,mesh%neighs(msop)) = mesh%neighs(ms)
913  END IF
914  IF (neigh_new(n,mesh%neighs(ms))==0) THEN
915  neigh_new(n,mesh%neighs(ms)) = mesh%neighs(msop)
916  END IF
917  END DO
918  virgins(ms) = .false.
919  virgins(msop) = .false.
920  END DO
921  END IF
922 
923  !=================TEST PERIODIC==================
924 
925  IF (present(my_periodic)) THEN
926  IF (my_periodic%nb_periodic_pairs/=0) THEN
927  DO ms = 1, mesh%mes
928  m = mesh%neighs(ms)
929  IF (minval(abs(mesh%sides(ms)-my_periodic%list_periodic(1,:))) == 0) THEN
930  jm_loc = minloc(abs(mesh%sides(ms)-my_periodic%list_periodic(1,:)))
931  s2 = my_periodic%list_periodic(2,jm_loc(1))
932  test = .false.
933  DO msop = 1, mesh%mes
934  IF (mesh%sides(msop) /= s2) cycle
935 
936  err = 0.d0
937  DO ns = 1, SIZE(my_periodic%vect_e,1)
938  err = err + abs(sum(mesh%rr(ns,mesh%jjs(:,ms))-mesh%rr(ns,mesh%jjs(:,msop)) &
939  +my_periodic%vect_e(ns,jm_loc(1))))
940  END DO
941 
942  IF (err .LE. epsilon) THEN
943  test = .true.
944  EXIT
945  END IF
946  END DO
947  IF (.NOT.test) THEN
948  CALL error_petsc('BUG, mop non trouve')
949  END IF
950  mop = mesh%neighs(msop)
951  DO n = 1, 3
952  IF (neigh_new(n,m) == 0) THEN
953  neigh_new(n,m) = mop
954  END IF
955  IF (neigh_new(n,mop) == 0) THEN
956  neigh_new(n,mop) = m
957  END IF
958  END DO
959  END IF
960  END DO
961  END IF
962  END IF
963 
964  !================================================
965  me_u = 0
966  me_h = 0
967  me_phi = 0
968  DO m = 1, mesh%me
969  idm = mesh%i_d(m)
970  IF (minval(abs(idm-list_u))==0) THEN
971  me_u = me_u + 1
972  ELSE IF (minval(abs(idm-list_h))==0) THEN
973  me_h = me_h + 1
974  ELSE IF (minval(abs(idm-list_phi))==0) THEN
975  me_phi = me_phi + 1
976  ELSE
977  CALL error_petsc('BUG in part_mesh_mhd_bis : element not in the mesh')
978  END IF
979  END DO
980  ALLOCATE(u2glob(me_u), h2glob(me_h),phi2glob(me_phi))
981  me_u = 0
982  me_h = 0
983  me_phi = 0
984  DO m = 1, mesh%me
985  idm = mesh%i_d(m)
986  IF (minval(abs(idm-list_u))==0) THEN
987  me_u = me_u + 1
988  u2glob(me_u) = m
989  glob2loc(m) = me_u
990  ELSE IF (minval(abs(idm-list_h))==0) THEN
991  me_h = me_h + 1
992  h2glob(me_h) = m
993  glob2loc(m) = me_h
994  ELSE IF (minval(abs(idm-list_phi))==0) THEN
995  me_phi = me_phi + 1
996  phi2glob(me_phi) = m
997  glob2loc(m) = me_phi
998  ELSE
999  CALL error_petsc('BUG in part_mesh_mhd_bis : element not in the mesh')
1000  END IF
1001  END DO
1002  ! Create the connectivity arrays based on neigh
1003  nb_neigh = SIZE(mesh%neigh,1)
1004  ALLOCATE(xind_u(me_u+1), xind_h(me_h+1), xind_phi(me_phi+1))
1005  xind_u(1) = 1
1006  DO k = 1, me_u
1007  m = u2glob(k)
1008  nb = 0
1009  DO n = 1, nb_neigh
1010  mop = neigh_new(n,m)
1011  IF (mop==0) cycle
1012  IF (minval(abs(mesh%i_d(mop)-list_u))/=0) cycle
1013  nb = nb + 1
1014  END DO
1015  xind_u(k+1) = xind_u(k) + nb
1016  END DO
1017  xind_h(1) = 1
1018  DO k = 1, me_h
1019  m = h2glob(k)
1020  nb = 0
1021  DO n = 1, nb_neigh
1022  mop = neigh_new(n,m)
1023  IF (mop==0) cycle
1024  IF (minval(abs(mesh%i_d(mop)-list_h))/=0) cycle
1025  nb = nb + 1
1026  END DO
1027  xind_h(k+1) = xind_h(k) + nb
1028  END DO
1029  xind_phi(1) = 1
1030  DO k = 1, me_phi
1031  m = phi2glob(k)
1032  nb = 0
1033  DO n = 1, nb_neigh
1034  mop = neigh_new(n,m)
1035  IF (mop==0) cycle
1036  IF (minval(abs(mesh%i_d(mop)-list_phi))/=0) cycle
1037  nb = nb + 1
1038  END DO
1039  xind_phi(k+1) = xind_phi(k) + nb
1040  END DO
1041 
1042  ALLOCATE(xadj_u(xind_u(me_u+1)-1))
1043  ALLOCATE(xadj_h(xind_h(me_h+1)-1))
1044  ALLOCATE(xadj_phi(xind_phi(me_phi+1)-1))
1045  p = 0
1046  DO k = 1, me_u
1047  m = u2glob(k)
1048  DO n = 1, nb_neigh
1049  mop = neigh_new(n,m)
1050  IF (mop==0) cycle
1051  IF (minval(abs(mesh%i_d(mop)-list_u))/=0) cycle
1052 !!$ jloc = MINLOC(ABS(u2glob-mop))
1053  p = p + 1
1054 !!$ xadj_u(p) = jloc(1)
1055  xadj_u(p) = glob2loc(mop)
1056  END DO
1057  END DO
1058  IF (p/=xind_u(me_u+1)-1) THEN
1059  CALL error_petsc('BUG, p/=xind_u(me_u+1)-1')
1060  END IF
1061  p = 0
1062  DO k = 1, me_h
1063  m = h2glob(k)
1064  DO n = 1, nb_neigh
1065  mop = neigh_new(n,m)
1066  IF (mop==0) cycle
1067  IF (minval(abs(mesh%i_d(mop)-list_h))/=0) cycle
1068 !!$ jloc = MINLOC(ABS(h2glob-mop))
1069  p = p + 1
1070 !!$ xadj_h(p) = jloc(1)
1071  xadj_h(p) = glob2loc(mop)
1072  END DO
1073  END DO
1074  IF (p/=xind_h(me_h+1)-1) THEN
1075  CALL error_petsc('BUG, p/=xind_h(me_h+1)-1')
1076  END IF
1077  p = 0
1078  DO k = 1, me_phi
1079  m = phi2glob(k)
1080  DO n = 1, nb_neigh
1081  mop = neigh_new(n,m)
1082  IF (mop==0) cycle
1083  IF (minval(abs(mesh%i_d(mop)-list_phi))/=0) cycle
1084 !!$ jloc = MINLOC(ABS(phi2glob-mop))
1085  p = p + 1
1086 !!$ xadj_phi(p) = jloc(1)
1087  xadj_phi(p) = glob2loc(mop)
1088  END DO
1089  END DO
1090  IF (p/=xind_phi(me_phi+1)-1) THEN
1091  CALL error_petsc('BUG, p/=xind_phi(me_phi+1)-1')
1092  END IF
1093 
1094  opts = 0
1095  numflag = 1
1096  wgtflag = 2
1097  ! Create partitions
1098  ALLOCATE(tpwgts(nb_proc))
1099  tpwgts=1.d0/nb_proc
1100  CALL metis_setdefaultoptions(metis_opt)
1101  metis_opt(metis_option_numbering)=1
1102  ubvec=1.01
1103  IF (me_u /= 0) THEN
1104  ALLOCATE(vwgt(me_u), adjwgt(SIZE(xadj_u)), part_u(me_u))
1105  vwgt = 1
1106  adjwgt = 1
1107  CALL metis_partgraphrecursive(me_u, 1, xind_u,xadj_u,vwgt, vwgt, adjwgt, nb_proc,tpwgts , ubvec, metis_opt, edge, part_u)
1108 !!$ CALL METIS_PartGraphRecursive(me_u,xind_u,xadj_u,vwgt,adjwgt,wgtflag, numflag, nb_proc, opts, edge, part_u)
1109  END IF
1110  IF (me_h /= 0) THEN
1111  IF (ALLOCATED(vwgt)) THEN
1112  DEALLOCATE(vwgt, adjwgt)
1113  END IF
1114  ALLOCATE(vwgt(me_h), adjwgt(SIZE(xadj_h)), part_h(me_h))
1115  vwgt = 1
1116  adjwgt = 1
1117  CALL metis_partgraphrecursive(me_h, 1, xind_h,xadj_h,vwgt, vwgt, adjwgt, nb_proc,tpwgts , ubvec, metis_opt, edge, part_h)
1118 !!$ CALL METIS_PartGraphRecursive(me_h,xind_h,xadj_h,vwgt,adjwgt,wgtflag, numflag, nb_proc, opts, edge, part_h)
1119  END IF
1120  IF (me_phi /= 0) THEN
1121  IF (ALLOCATED(vwgt)) THEN
1122  DEALLOCATE(vwgt, adjwgt)
1123  END IF
1124  ALLOCATE(vwgt(me_phi), adjwgt(SIZE(xadj_phi)), part_phi(me_phi))
1125  vwgt = 1
1126  adjwgt = 1
1127  CALL metis_partgraphrecursive(me_phi, 1, xind_phi,xadj_phi,vwgt, vwgt, adjwgt, nb_proc,tpwgts, &
1128  ubvec, metis_opt, edge, part_phi)
1129 !!$ CALL METIS_PartGraphRecursive(me_phi,xind_phi,xadj_phi,vwgt,adjwgt,wgtflag, numflag, nb_proc, opts, edge, part_phi)
1130  END IF
1131 !!$!TESTTT
1132 !!$ do m = 1, mesh%me
1133 !!$ if (part_phi(m) ==1) THEN
1134 !!$ part_phi(m) =2
1135 !!$ ELSE if (part_phi(m) ==2) then
1136 !!$ part_phi(m) =1
1137 !!$ ELSE if (part_phi(m) ==3) then
1138 !!$ part_phi(m) =4
1139 !!$ ELSE if (part_phi(m) ==4) then
1140 !!$ part_phi(m) =3
1141 !!$ END IF
1142 !!$ end do
1143 !!$!TESTTT
1144  ! Create global partition 'part'
1145  part = -1
1146  IF (me_u/=0) THEN
1147  part(u2glob(:)) = part_u
1148  END IF
1149  IF (me_h/=0) THEN
1150  part(h2glob(:)) = part_h
1151  END IF
1152  IF (me_phi/=0) THEN
1153  part(phi2glob(:)) = part_phi
1154  END IF
1155  IF (minval(part)==-1) THEN
1156  CALL error_petsc('BUG in part_mesh_mhd_bis, MINVAL(part) == -1')
1157  END IF
1158  ! End Create global partition
1159 
1160  ! Create parts and modify part
1161  !==Search on the boundary whether ms is on a cut.
1162  IF (SIZE(mesh%jj,1)/=3) THEN
1163  write(*,*) 'SIZE(mesh%jj,1)', SIZE(mesh%jj,1)
1164  CALL error_petsc('BUG in part_mesh_mhd_bis, SIZE(mesh%jj,1)/=3')
1165  END IF
1166  indicator = -1
1167  nws = SIZE( mesh%jjs,1)
1168  IF (SIZE(list_of_interfaces)/=0) THEN
1169  virgins = .true.
1170  DO ms = 1, mesh%mes
1171  IF (.NOT.virgins(ms)) cycle
1172  IF (minval(abs(mesh%sides(ms)-list_of_interfaces))/=0) cycle !==ms not on a cut
1173  i_loc = mesh%jjs(:,ms)
1174  DO msop = 1, mesh%mes
1175  IF (msop==ms .OR. .NOT.virgins(msop)) cycle
1176  IF (minval(abs(mesh%sides(msop)-list_of_interfaces))/=0) cycle !==msop not on a cut
1177  DO ns = 1, nws
1178  test = .false.
1179  DO nsop = 1, nws
1180  iop = mesh%jjs(nsop,msop)
1181  IF (maxval(abs(mesh%rr(:,i_loc(ns))-mesh%rr(:,iop))).LT.epsilon) THEN
1182  test = .true.
1183  EXIT
1184  END IF
1185  END DO
1186  IF (.NOT.test) THEN
1187  EXIT !==This msop does not coincide with ms
1188  END IF
1189  END DO
1190  IF (test) EXIT
1191  END DO
1192  IF (.NOT.test) THEN
1193  CALL error_petsc(.NOT.'BUG in create_local_mesh, test ')
1194  END IF
1195  IF (part(mesh%neighs(ms)) == part(mesh%neighs(msop))) cycle !==ms is an internal cut
1196  proc = min(part(mesh%neighs(ms)),part(mesh%neighs(msop)))
1197  part(mesh%neighs(ms)) = proc !make sure interface are internal
1198  part(mesh%neighs(msop)) = proc !make sure interface are internal
1199  virgins(ms) = .false.
1200  virgins(msop) = .false.
1201  indicator(mesh%jjs(:,ms)) = proc
1202  indicator(mesh%jjs(:,msop)) = proc
1203  END DO
1204  END IF
1205  !===Fix the partition so that all the cells having one vertex on an
1206  !===interface belong to the same processor as those sharing this vertices and
1207  !===having two vertices on the interface (JLG + DCL July 22 2015)
1208  DO m = 1, mesh%me
1209  j_loc = mesh%jj(:,m)
1210  n = maxval(indicator(j_loc))
1211  IF (n == -1) cycle
1212  IF (indicator(j_loc(1))*indicator(j_loc(2))*indicator(j_loc(3))<0) cycle
1213  part(m) = n
1214  END DO
1215  ! End create parts and modify part
1216 
1217  !=================TEST PERIODIC==================
1218  IF (present(my_periodic)) THEN
1219  IF (my_periodic%nb_periodic_pairs/=0) THEN
1220 
1221 
1222  DO j = 1, mesh%np
1223  per_pts(j,1) = j
1224  END DO
1225  per_pts(:,2:3) = 0
1226  DO ms = 1, mesh%mes
1227  m = mesh%neighs(ms)
1228  IF ((minval(abs(mesh%sides(ms)-my_periodic%list_periodic(1,:))) /=0) .AND. &
1229  (minval(abs(mesh%sides(ms)-my_periodic%list_periodic(2,:))) /=0) ) cycle
1230  DO ns = 1, SIZE(mesh%jjs,1)
1231  j = mesh%jjs(ns,ms)
1232  per_pts(j,2) = m
1233  DO msop = 1, mesh%mes
1234  IF (minval(abs(mesh%sides(msop)-my_periodic%list_periodic(:,:))) /=0 ) cycle
1235  IF (msop == ms) cycle
1236  DO nsop = 1, SIZE(mesh%jjs,1)
1237  IF (mesh%jjs(nsop,msop)==j) THEN
1238  per_pts(j,3) = mesh%neighs(msop)
1239  END IF
1240  END DO
1241  END DO
1242  END DO
1243  END DO
1244 !!$ WRITE(*,*) per_pts(:,2)
1245  CALL reassign_per_pts(mesh, part, per_pts)
1246 
1247  DO ms = 1, mesh%mes
1248  m = mesh%neighs(ms)
1249  IF (minval(abs(mesh%sides(ms)-my_periodic%list_periodic(1,:))) /= 0) cycle
1250  jm_loc = minloc(abs(mesh%sides(ms)-my_periodic%list_periodic(1,:)))
1251  s2 = my_periodic%list_periodic(2,jm_loc(1))
1252  test = .false.
1253  DO msop = 1, mesh%mes
1254  IF (mesh%sides(msop) /= s2) cycle
1255 
1256  err = 0.d0
1257  DO ns = 1, SIZE(my_periodic%vect_e,1)
1258  err = err + abs(sum(mesh%rr(ns,mesh%jjs(:,ms))-mesh%rr(ns,mesh%jjs(:,msop)) &
1259  +my_periodic%vect_e(ns,jm_loc(1))))
1260  END DO
1261 
1262  IF (err .LE. epsilon) THEN
1263  test = .true.
1264  EXIT
1265  END IF
1266  END DO
1267  IF (.NOT.test) THEN
1268  CALL error_petsc('BUG, mop non trouve')
1269  END IF
1270  IF (part(mesh%neighs(ms)) /= part(mesh%neighs(msop))) THEN !==ms is an internal cut
1271  proc = min(part(mesh%neighs(ms)),part(mesh%neighs(msop)))
1272  part(mesh%neighs(ms)) = proc !make sure interface are internal
1273  part(mesh%neighs(msop)) = proc !make sure interface are internal
1274  END IF
1275  END DO
1276 
1277  END IF
1278  END IF
1279 
1280 !!$ WARNING, FL 1/2/13 : TO BE ADDED IN NEEDED
1281  !================================================
1282  CALL mpi_comm_rank(mpi_comm_world,rank,ierr)
1283  IF (rank==0) THEN
1284  CALL plot_const_p1_label(mesh%jj, mesh%rr, 1.d0*part, 'dd.plt')
1285  END IF
1286  !================================================
1287 !!$ WARNING, FL 1/2/13 : TO BE ADDED IN NEEDED
1288 
1289  DEALLOCATE(vwgt,adjwgt)
1290  IF (ALLOCATED(xadj_u)) DEALLOCATE(xadj_u)
1291  IF (ALLOCATED(xadj_h)) DEALLOCATE(xadj_h)
1292  IF (ALLOCATED(xadj_phi)) DEALLOCATE(xadj_phi)
1293  IF (ALLOCATED(list_h)) DEALLOCATE(list_h)
1294  IF (ALLOCATED(xind_u)) DEALLOCATE(xind_u)
1295  IF (ALLOCATED(xind_h)) DEALLOCATE(xind_h)
1296  IF (ALLOCATED(xind_phi)) DEALLOCATE(xind_phi)
1297  IF (ALLOCATED(u2glob)) DEALLOCATE(u2glob)
1298  IF (ALLOCATED(h2glob)) DEALLOCATE(h2glob)
1299  IF (ALLOCATED(phi2glob)) DEALLOCATE(phi2glob)
1300  IF (ALLOCATED(part_u)) DEALLOCATE(part_u)
1301  IF (ALLOCATED(part_h)) DEALLOCATE(part_h)
1302  IF (ALLOCATED(part_phi)) DEALLOCATE(part_phi)
1303 
1304  DEALLOCATE(tpwgts)
1305 
1306  END SUBROUTINE part_mesh_mhd_bis
1307 
1308  SUBROUTINE extract_mesh(communicator,nb_proc,mesh_glob,part,list_dom,mesh,mesh_loc)
1309  USE def_type_mesh
1310  USE my_util
1311  IMPLICIT NONE
1312  TYPE(mesh_type) :: mesh_glob, mesh, mesh_loc
1313  INTEGER, DIMENSION(:) :: part, list_dom
1314  INTEGER, DIMENSION(mesh_glob%me) :: bat
1315  INTEGER, DIMENSION(mesh_glob%np) :: i_old_to_new
1316  INTEGER, DIMENSION(mesh_glob%mes) :: parts
1317  INTEGER, DIMENSION(nb_proc) :: nblmt_per_proc, start, displ
1318  INTEGER, DIMENSION(2) :: np_loc, me_loc, mes_loc
1319  INTEGER, DIMENSION(:), ALLOCATABLE :: list_m, tab, tabs
1320  INTEGER :: nb_proc, ms, i, index, m, mop, n
1321  petscerrorcode :: ierr
1322  petscmpiint :: rank
1323  mpi_comm :: communicator
1324  CALL mpi_comm_rank(communicator,rank,ierr)
1325 
1326  ! Create parts
1327  parts = part(mesh_glob%neighs)
1328  ! End create parts
1329 
1330  ! Create list_m
1331  i = 0
1332  DO m = 1, mesh_glob%me
1333  IF (minval(abs(list_dom-mesh_glob%i_d(m)))/=0) cycle
1334  i = i + 1
1335  END DO
1336  mesh%me = i
1337  ALLOCATE (list_m(mesh%me))
1338  i = 0
1339  DO m = 1, mesh_glob%me
1340  IF (minval(abs(list_dom-mesh_glob%i_d(m)))/=0) cycle
1341  i = i + 1
1342  list_m(i) = m
1343  END DO
1344  !End create list_m
1345 
1346  ! Count elements on processors
1347  nblmt_per_proc = 0
1348  DO i = 1, mesh%me
1349  m = list_m(i)
1350  nblmt_per_proc(part(m)) = nblmt_per_proc(part(m)) + 1
1351  END DO
1352  start(1) = 0
1353  DO n = 2, nb_proc
1354  start(n) = start(n-1) + nblmt_per_proc(n-1)
1355  END DO
1356  me_loc(1) = start(rank+1) + 1
1357  me_loc(2) = start(rank+1) + nblmt_per_proc(rank+1)
1358  displ = start
1359  ! End count elements on processors
1360 
1361  ! Re-order elements
1362  ALLOCATE(tab(mesh%me))
1363  bat = 0
1364  DO i = 1, mesh%me
1365  m = list_m(i)
1366  start(part(m)) = start(part(m)) + 1
1367  tab(start(part(m))) = m
1368  bat(m) = start(part(m))
1369  END DO
1370  ! Re-order elements
1371 
1372  ! Create mesh%jj
1373  mesh%gauss%n_w = SIZE(mesh_glob%jj,1)
1374  ALLOCATE(mesh%jj(SIZE(mesh_glob%jj,1),mesh%me))
1375  i_old_to_new = 0
1376  index = 0
1377  DO m = 1, mesh%me
1378  DO n = 1, SIZE(mesh_glob%jj,1)
1379  i = mesh_glob%jj(n,tab(m))
1380  IF (i_old_to_new(i)/=0) THEN
1381  mesh%jj(n,m) = i_old_to_new(i)
1382  ELSE
1383  index = index + 1
1384  i_old_to_new(i) = index
1385  mesh%jj(n,m) = i_old_to_new(i)
1386  END IF
1387  END DO
1388  END DO
1389  ! End Create mesh%jj
1390 
1391  ! Create mesh%rr
1392  mesh%np = index
1393  ALLOCATE(mesh%rr(2,mesh%np))
1394  DO i = 1, mesh_glob%np
1395  IF (i_old_to_new(i)==0) cycle
1396  mesh%rr(:,i_old_to_new(i)) = mesh_glob%rr(:,i)
1397  END DO
1398  !End Create mesh%rr
1399 
1400  ! Create mesh%neigh
1401  ALLOCATE(mesh%neigh(3,mesh%me))
1402  DO m = 1, mesh%me
1403  DO n = 1, 3
1404  mop = mesh_glob%neigh(n,tab(m))
1405  IF (mop==0) THEN
1406  mesh%neigh(n,m) = 0
1407  ELSE
1408  mesh%neigh(n,m) = bat(mop)
1409  END IF
1410  END DO
1411  END DO
1412  ! End Create mesh%neigh
1413 
1414  ! Create mesh%i_d
1415  ALLOCATE(mesh%i_d(mesh%me))
1416  mesh%i_d = mesh_glob%i_d(tab)
1417  ! End mesh%i_d
1418 
1419  ! Create np_loc
1420  IF (displ(rank+1)/=0) THEN
1421  np_loc(1) = maxval(mesh%jj(:,1:displ(rank+1))) + 1
1422  ELSE
1423  np_loc(1) = 1
1424  END IF
1425  np_loc(2) = np_loc(1) - 1
1426  IF (me_loc(1).LE.me_loc(2)) THEN
1427  np_loc(2) = maxval(mesh%jj(:,me_loc(1):me_loc(2)))
1428  END IF
1429  IF (np_loc(2) .LT. np_loc(1)-1) THEN
1430  np_loc(2) = np_loc(1) - 1
1431  END IF
1432  ! End create np_loc
1433 
1434  ! Create mes_loc
1435  nblmt_per_proc=0
1436  DO ms = 1, mesh_glob%mes
1437  IF (minval(abs(list_dom-mesh_glob%i_d(mesh_glob%neighs(ms))))/=0) cycle
1438  n = parts(ms)
1439  nblmt_per_proc(n) = nblmt_per_proc(n) + 1
1440  END DO
1441  start(1) = 0
1442  DO n = 2, nb_proc
1443  start(n) = start(n-1) + nblmt_per_proc(n-1)
1444  END DO
1445  mes_loc(1) = start(rank+1) + 1
1446  mes_loc(2) = start(rank+1) + nblmt_per_proc(rank+1)
1447  mesh%mes = sum(nblmt_per_proc)
1448  ! End create mes_loc
1449 
1450  ! Create tabs and sbat
1451  ALLOCATE(tabs(mesh%mes))
1452  DO ms = 1, mesh_glob%mes
1453  IF (minval(abs(list_dom-mesh_glob%i_d(mesh_glob%neighs(ms))))/=0) cycle
1454  start(parts(ms)) = start(parts(ms)) + 1
1455  tabs(start(parts(ms))) = ms
1456  END DO
1457  ! End create tabs and sbat
1458 
1459  ! Create neighs
1460  ALLOCATE(mesh%neighs(mesh%mes))
1461  mesh%neighs = bat(mesh_glob%neighs(tabs))
1462  ! End create neighs
1463 
1464  ! Re-order sides
1465  ALLOCATE(mesh%sides(mesh%mes))
1466  mesh%sides = mesh_glob%sides(tabs)
1467  ! End re-order sides
1468 
1469  ! Re-order jjs
1470  mesh%gauss%n_ws = SIZE(mesh_glob%jjs,1)
1471  ALLOCATE(mesh%jjs(SIZE(mesh_glob%jjs,1),mesh%mes))
1472 
1473  DO n = 1, SIZE(mesh%jjs,1)
1474  mesh%jjs(n,:) = i_old_to_new(mesh_glob%jjs(n,tabs))
1475  END DO
1476  ! End re-order jjs
1477 
1478  !==We create the local mesh now
1479  mesh%edge_stab = .false.
1480  CALL create_local_mesh(mesh, mesh_loc, me_loc, mes_loc, np_loc)
1481 
1482  DEALLOCATE(list_m, tab, tabs)
1483 
1484  END SUBROUTINE extract_mesh
1485 
1486  SUBROUTINE create_local_mesh(mesh, mesh_loc, me_loc, mes_loc, np_loc)
1487  USE def_type_mesh
1488  USE my_util
1489  IMPLICIT NONE
1490  TYPE(mesh_type) :: mesh, mesh_loc
1491  INTEGER, DIMENSION(2), INTENT(IN) :: me_loc, mes_loc, np_loc
1492  INTEGER, DIMENSION(mesh%me) :: m_glob_to_loc
1493  INTEGER, DIMENSION(:), ALLOCATABLE :: m_loc_to_glob
1494  INTEGER, DIMENSION(mesh%np) :: glob_to_loc,loc_to_glob
1495  LOGICAL, DIMENSION(mesh%np) :: virgin
1496  INTEGER :: dim, nws, nw, m, ms, mop, ns, msup, minf, dof, &
1497  dom_me, nwc, dom_mes, dom_np, n, i
1498  LOGICAL :: test
1499 
1500  dim = SIZE(mesh%rr,1)
1501  nws = SIZE(mesh%jjs,1)
1502  nw = SIZE(mesh%jj,1)
1503  nwc = SIZE(mesh%neigh,1)
1504  !==Test if one proc only
1505  IF (me_loc(2) - me_loc(1) + 1==mesh%me) THEN
1506  mesh_loc%me = mesh%me
1507  mesh_loc%np = mesh%np
1508  mesh_loc%mes = mesh%mes
1509  mesh_loc%dom_me = mesh%me
1510  mesh_loc%dom_np = mesh%np
1511  mesh_loc%dom_mes = mesh%mes
1512  mesh_loc%gauss%n_w = nw
1513  ALLOCATE(mesh_loc%jj(nw,mesh%me))
1514  mesh_loc%jj = mesh%jj
1515  ALLOCATE(mesh_loc%loc_to_glob(mesh%np))
1516  DO n = 1, mesh%np
1517  mesh_loc%loc_to_glob(n) = n
1518  END DO
1519  ALLOCATE(mesh_loc%rr(dim,mesh%np))
1520  mesh_loc%rr=mesh%rr
1521  ALLOCATE(mesh_loc%neigh(nwc,mesh%me))
1522  mesh_loc%neigh = mesh%neigh
1523  ALLOCATE(mesh_loc%i_d(mesh%me))
1524  mesh_loc%i_d = mesh%i_d
1525  ALLOCATE(mesh_loc%neighs(mesh_loc%mes))
1526  mesh_loc%neighs = mesh%neighs
1527  ALLOCATE(mesh_loc%sides(mesh_loc%mes))
1528  mesh_loc%sides = mesh%sides
1529  mesh_loc%gauss%n_ws = nws
1530  ALLOCATE(mesh_loc%jjs(nws,mesh_loc%mes))
1531  mesh_loc%jjs = mesh%jjs
1532  RETURN
1533  END IF
1534  !==End test if one proc only
1535 
1536 
1537  !==Create the new mesh
1538  dom_me = me_loc(2) - me_loc(1) + 1
1539  dom_mes = mes_loc(2) - mes_loc(1) + 1
1540  dom_np = np_loc(2) - np_loc(1) + 1
1541  mesh_loc%me = dom_me
1542  mesh_loc%mes = dom_mes
1543  mesh_loc%dom_me = dom_me
1544  mesh_loc%dom_np = dom_np
1545  mesh_loc%dom_mes = dom_mes
1546 
1547  IF (dom_me==0) THEN
1548  ALLOCATE(mesh_loc%jj(0,0))
1549  ALLOCATE(mesh_loc%loc_to_glob(0))
1550  ALLOCATE(mesh_loc%rr(0,0))
1551  ALLOCATE(mesh_loc%neigh(0,0))
1552  ALLOCATE(mesh_loc%i_d(0))
1553  ALLOCATE(mesh_loc%neighs(0))
1554  ALLOCATE(mesh_loc%sides(0))
1555  ALLOCATE(mesh_loc%jjs(0,0))
1556  mesh_loc%gauss%n_w = 0
1557  mesh_loc%gauss%n_ws = 0
1558  RETURN
1559  ELSE IF (dom_me<0) THEN
1560  CALL error_petsc('BUG in create_local_mesh, dom_me<0 ')
1561  ELSE
1562  mesh_loc%gauss%n_w = nw
1563  mesh_loc%gauss%n_ws = nws
1564  END IF
1565 
1566  !==Re-order jj
1567  virgin = .true.
1568  dof = 0
1569  DO m = me_loc(1), me_loc(2)
1570  DO n = 1, nw
1571  i = mesh%jj(n,m)
1572  IF(.NOT.virgin(i) .OR. i.GE.np_loc(1)) cycle
1573  virgin(i) = .false.
1574  dof = dof + 1
1575  END DO
1576  END DO
1577  ALLOCATE(mesh_loc%jj(nw,mesh_loc%me))
1578 
1579  ALLOCATE(m_loc_to_glob(mesh_loc%me))
1580  m_glob_to_loc = 0
1581  virgin = .true.
1582  dof = dom_np
1583  DO m = me_loc(1), me_loc(2)
1584  DO n = 1, nw
1585  i = mesh%jj(n,m)
1586  IF(virgin(i)) THEN
1587  virgin(i) = .false.
1588  IF (i .LT. np_loc(1)) THEN
1589  dof = dof + 1
1590  glob_to_loc(i) = dof
1591  loc_to_glob(dof) = i
1592  ELSE
1593  glob_to_loc(i) = i-np_loc(1) + 1
1594  loc_to_glob(i-np_loc(1) + 1) = i
1595  END IF
1596  END IF
1597  END DO
1598  m_loc_to_glob(m-me_loc(1)+1) = m
1599  m_glob_to_loc(m) = m-me_loc(1)+1
1600  END DO
1601 
1602  DO n = 1, nw
1603  mesh_loc%jj(n,1:dom_me) = glob_to_loc(mesh%jj(n,me_loc(1):me_loc(2)))
1604  END DO
1605  !==End re-order jj
1606 
1607  !==Create mesh%loc_to_glob
1608  IF (maxval(mesh_loc%jj)/=dof) THEN
1609  CALL error_petsc('BUG in create_local_mesh, mesh_loc%jj)/=dof')
1610  END IF
1611  mesh_loc%np = dof
1612  ALLOCATE(mesh_loc%loc_to_glob(mesh_loc%np))
1613  mesh_loc%loc_to_glob = loc_to_glob(1:mesh_loc%np)
1614  !==End create mesh%loc_to_glob
1615 
1616  !==Re-order rr
1617  ALLOCATE(mesh_loc%rr(dim,mesh_loc%np))
1618  DO n = 1, mesh_loc%np
1619  mesh_loc%rr(:,n) = mesh%rr(:,mesh_loc%loc_to_glob(n))
1620  END DO
1621  !==End re-order rr
1622 
1623  !==Re-order neigh
1624  ALLOCATE(mesh_loc%neigh(nwc,mesh_loc%me))
1625  msup = maxval(m_loc_to_glob)
1626  minf = minval(m_loc_to_glob)
1627  DO m = 1, mesh_loc%me
1628  DO n = 1, nwc
1629  mop = mesh%neigh(n,m_loc_to_glob(m))
1630  IF (mop==0) THEN
1631  mesh_loc%neigh(n,m) = 0
1632  ELSE IF(mop<minf .OR. mop>msup) THEN
1633  !mesh_loc%neigh(n,m) = mop
1634  mesh_loc%neigh(n,m) = -mop !JLG AUG 13 2015
1635  ELSE
1636  mesh_loc%neigh(n,m) = m_glob_to_loc(mop)
1637  END IF
1638  END DO
1639  END DO
1640  !==End re-order neigh
1641 
1642  !==Re-order i_d
1643  ALLOCATE(mesh_loc%i_d(mesh_loc%me))
1644  mesh_loc%i_d = mesh%i_d(m_loc_to_glob)
1645  !==End re-order i_d
1646 
1647  !==Re-order neighs
1648  ALLOCATE(mesh_loc%neighs(mesh_loc%mes))
1649  mesh_loc%neighs = m_glob_to_loc(mesh%neighs(mes_loc(1):mes_loc(2)))
1650  !==End re-order neighs
1651 
1652 
1653  !==Re-order sides
1654  ALLOCATE(mesh_loc%sides(mesh_loc%mes))
1655  mesh_loc%sides = mesh%sides(mes_loc(1):mes_loc(2))
1656  !==End re-order sides
1657 
1658  !==Re-order jjs
1659  ALLOCATE(mesh_loc%jjs(nws,mesh_loc%mes))
1660  DO ns = 1, nws
1661  mesh_loc%jjs(ns,:) = glob_to_loc(mesh%jjs(ns,mes_loc(1):mes_loc(2)))
1662  END DO
1663  !==End re-order jjs
1664 
1665  !TEST
1666 
1667  DO ms = 1, mesh_loc%mes
1668  m = mesh_loc%neighs(ms)
1669  DO ns = 1, nws
1670  test = .true.
1671  DO n = 1, nw
1672  IF (maxval(abs(mesh_loc%rr(:,mesh_loc%jj(n,m))-mesh_loc%rr(:,mesh_loc%jjs(ns,ms)))) .LT. 1.d-10) THEN
1673  test = .false.
1674  END IF
1675  END DO
1676  IF (test) THEN
1677  WRITE(*,*) 'bug in create local mesh, non consistent numbering'
1678  END IF
1679  END DO
1680  END DO
1681 
1682 
1683  !TEST
1684 
1685  DEALLOCATE(m_loc_to_glob)
1686 
1687  END SUBROUTINE create_local_mesh
1688 
1689  SUBROUTINE free_mesh(mesh)
1690  USE def_type_mesh
1691  USE my_util
1692  IMPLICIT NONE
1693  TYPE(mesh_type) :: mesh
1694 
1695  DEALLOCATE(mesh%jj)
1696  DEALLOCATE(mesh%jjs)
1697  DEALLOCATE(mesh%rr)
1698  DEALLOCATE(mesh%neigh)
1699  DEALLOCATE(mesh%sides)
1700  DEALLOCATE(mesh%neighs)
1701  DEALLOCATE(mesh%i_d)
1702 
1703  nullify(mesh%loc_to_glob)
1704  nullify(mesh%disp)
1705  nullify(mesh%domnp)
1706  nullify(mesh%j_s)
1707 
1708  IF (mesh%edge_stab) THEN
1709  DEALLOCATE(mesh%iis)
1710  nullify(mesh%jji)
1711  DEALLOCATE(mesh%jjsi)
1712  DEALLOCATE(mesh%neighi)
1713  END IF
1714 
1715  mesh%dom_me = 0
1716  mesh%dom_np = 0
1717  mesh%dom_mes = 0
1718  mesh%me = 0
1719  mesh%mes = 0
1720  mesh%np = 0
1721  mesh%nps = 0
1722  mesh%mi =0
1723  mesh%edge_stab = .false.
1724 
1725  END SUBROUTINE free_mesh
1726 
1727  SUBROUTINE free_interface(interf)
1728  USE def_type_mesh
1729  USE my_util
1730  IMPLICIT NONE
1731  TYPE(interface_type) :: interf
1732 
1733  interf%mes = 0
1734  DEALLOCATE(interf%mesh1)
1735  DEALLOCATE(interf%mesh2)
1736  DEALLOCATE(interf%jjs1)
1737  DEALLOCATE(interf%jjs2)
1738  END SUBROUTINE free_interface
1739 
1740  SUBROUTINE reassign_per_pts(mesh, partition, list_pts)
1741  USE def_type_mesh
1742  USE my_util
1743  IMPLICIT NONE
1744 
1745  TYPE(mesh_type) , INTENT(IN) :: mesh
1746  INTEGER, DIMENSION(mesh%me), INTENT(INOUT) :: partition
1747  INTEGER, DIMENSION(mesh%np,3), INTENT(IN) :: list_pts
1748 
1749  INTEGER :: i, j_loc, proc_min, index, i_loc, m, mop, n, proc1, proc2
1750  INTEGER, DIMENSION(50) :: list_elmts
1751  LOGICAL :: okay
1752 
1753 
1754  list_elmts = 0
1755  DO i = 1, mesh%np
1756  IF (list_pts(i,2)==0) cycle
1757  j_loc = list_pts(i,1)
1758  list_elmts=0
1759  index = 1
1760  list_elmts(index) = list_pts(i,2)
1761  okay = .true.
1762  DO WHILE (okay)
1763  m=list_elmts(index)
1764  okay = .false.
1765  i_loc=index
1766  DO n = 1, 3
1767  mop = mesh%neigh(n, m)
1768  IF (mop == 0) cycle
1769  IF (minval(abs(mesh%jj(:,mop)-j_loc)) /=0) cycle
1770  IF (minval(abs(mop-list_elmts))==0) cycle
1771  okay=.true.
1772  i_loc = i_loc + 1
1773  IF (i_loc-index==2) THEN
1774  CALL error_petsc('BUG in reassign_per_pts, how is that possible?')
1775  END IF
1776  list_elmts(i_loc) = mop
1777  END DO
1778  index = i_loc
1779  END DO
1780 !!$ WRITE(*,*) i, list_elmts(1:index)
1781  IF (list_pts(i,3) == 0) THEN ! point au bord du bord periodique, ou sur une arete
1782  proc_min = minval(partition(list_elmts(1:index)))
1783  partition(list_elmts(1)) = proc_min
1784  ELSE ! deux elements du bord periodique touchent le point
1785  IF (list_elmts(index) /= list_pts(i,3)) THEN
1786  CALL error_petsc('BUG in reassign_per_pts, wrong element')
1787  END IF
1788  proc1 = partition(list_elmts(1))
1789  proc2 = partition(list_elmts(2))
1790  partition(list_elmts(2:index-1)) = min(proc1,proc2)
1791  END IF
1792  END DO
1793 
1794  END SUBROUTINE reassign_per_pts
1795 
1796 
1797 END MODULE metis_sfemans
subroutine, public free_interface(interf)
subroutine, public free_mesh(mesh)
subroutine loc_to_glob(mesh_loc, mesh_glob, l_t_g)
subroutine, public part_mesh_m_t_h_phi(nb_proc, list_u, list_T_in, list_h_in, list_phi, mesh, list_of_interfaces, part, my_periodic)
subroutine, public extract_mesh(communicator, nb_proc, mesh_glob, part, list_dom, mesh, mesh_loc)
subroutine create_local_mesh(mesh, mesh_loc, me_loc, mes_loc, np_loc, news, inter_news)
subroutine, public part_mesh_mhd(nb_proc, vwgt, mesh, list_of_interfaces, part, my_periodic)
subroutine plot_const_p1_label(jj, rr, uu, file_name)
Definition: sub_plot.f90:264
subroutine reassign_per_pts(mesh, partition, list_pts)
subroutine error_petsc(string)
Definition: my_util.f90:15
subroutine, public part_mesh_mhd_bis(nb_proc, list_u, list_h_in, list_phi, mesh, list_of_interfaces, part, my_periodic)