source: branches/ORCHIDEE_EXT/ORCHIDEE/src_parallel/data_para.f90 @ 257

Last change on this file since 257 was 257, checked in by didier.solyga, 13 years ago

Externalized version merged with the trunk

File size: 15.9 KB
Line 
1! Definition and allocation of parallel datas.
2! Initialization of parallel or sequentiel IOs.
3! Definition of Load Balancing functions.
4
5!-
6!- $Header: /home/ssipsl/CVSREP/ORCHIDEE/src_parallel/data_para.f90,v 1.7 2010/04/06 14:31:57 ssipsl Exp $
7!-
8
9MODULE data_para
10
11!-
12  USE defprec
13  USE ioipsl
14!-
15#include "src_parallel.h"
16!-
17!-
18! Unit for output messages
19  INTEGER(i_std), SAVE :: numout = 6
20
21  INTEGER, SAVE :: mpi_size                                           !! Number of parallel processes
22  INTEGER, SAVE :: mpi_rank                                           !! my rank num
23  INTEGER, SAVE :: root_prc                                           !! rank of root proc
24  LOGICAL, SAVE :: is_root_prc                                        !! Only root proc is true
25  INTEGER, SAVE :: nbp_loc                                            !! number of local continental points
26  INTEGER, SAVE :: nbp_glo                                            !! number of global continental points
27  INTEGER,SAVE,ALLOCATABLE,DIMENSION(:) :: nbp_para_nb
28  INTEGER,SAVE,ALLOCATABLE,DIMENSION(:) :: nbp_para_begin
29  INTEGER,SAVE,ALLOCATABLE,DIMENSION(:) :: nbp_para_end
30 
31  INTEGER,SAVE :: iim_g, jjm_g                                  !! Dimension of global fields
32  ! i x j 2D points (not land points) index
33  INTEGER,SAVE,allocatable,dimension(:) :: ij_para_nb           ! Number of 2D points for each mpi_rank block
34  INTEGER,SAVE,allocatable,dimension(:) :: ij_para_begin        ! First 2D point for each mpi_rank block
35  INTEGER,SAVE,allocatable,dimension(:) :: ij_para_end          ! Last 2D point for each mpi_rank block
36  ! i 2D index
37  INTEGER,SAVE,allocatable,dimension(:) :: ii_para_begin        ! First i index of 2D point for each mpi_rank block
38  INTEGER,SAVE,allocatable,dimension(:) :: ii_para_end          ! Last i index of 2D point for each mpi_rank block
39  ! j 2D index
40  INTEGER,SAVE,allocatable,dimension(:) :: jj_para_nb           ! Number of complete j lines for each mpi_rank block
41  INTEGER,SAVE,allocatable,dimension(:) :: jj_para_begin        ! First j index of 2D point for each mpi_rank block
42  INTEGER,SAVE,allocatable,dimension(:) :: jj_para_end          ! Last j index of 2D point for each mpi_rank block
43 
44  INTEGER,SAVE :: ii_begin
45  INTEGER,SAVE :: ii_end
46  INTEGER,SAVE :: jj_begin
47  INTEGER,SAVE :: jj_end
48  INTEGER,SAVE :: jj_nb
49  INTEGER,SAVE :: ij_begin
50  INTEGER,SAVE :: ij_end
51  INTEGER,SAVE :: ij_nb
52 
53 
54  !! Global array used by stomate and sechiba
55  !-
56  !! index of land points on the 2D map
57  INTEGER(i_std),ALLOCATABLE,DIMENSION(:),SAVE   :: index_g
58  !-
59  !! indices of the 4 neighbours of each grid point (1=N, 2=E, 3=S, 4=W)
60  INTEGER(i_std),ALLOCATABLE,DIMENSION(:,:),SAVE :: neighbours_g
61  !-
62  !! resolution at each grid point in m (1=E-W, 2=N-S)
63  REAL(r_std),ALLOCATABLE,DIMENSION(:,:),SAVE    :: resolution_g 
64  REAL(r_std),ALLOCATABLE,DIMENSION(:),SAVE    :: area_g 
65  !-
66  !! Geographical coordinates
67  REAL(r_std),ALLOCATABLE,DIMENSION(:,:),SAVE    :: lalo_g
68  ! Global grid, for all process
69  REAL(r_std), ALLOCATABLE, DIMENSION(:,:), SAVE     :: lon_g, lat_g, zlev_g
70  !-
71  !! Fraction of continents
72  REAL(r_std),ALLOCATABLE,DIMENSION(:),SAVE      :: contfrac_g
73 
74  INTEGER, SAVE :: MPI_COMM_ORCH
75  INTEGER, SAVE :: MPI_REAL_ORCH
76  INTEGER, SAVE :: MPI_INT_ORCH
77  LOGICAL, SAVE :: cpl_lmdz
78 
79  INTEGER, SAVE :: orch_domain_id
80 
81CONTAINS
82 
83  SUBROUTINE init_para(cpl_lmdz_x, communicator)
84
85    IMPLICIT NONE
86   
87#ifdef CPP_PARA
88    INCLUDE 'mpif.h'
89#endif
90    LOGICAL :: cpl_lmdz_x
91    INTEGER,OPTIONAL :: communicator
92    INTEGER :: ierr
93    CHARACTER(LEN=20) :: filename
94    INTEGER :: i, div
95    CHARACTER(LEN=4) :: num
96    LOGICAL, PARAMETER :: check = .FALSE.
97
98    cpl_lmdz=cpl_lmdz_x
99     
100#ifdef CPP_PARA
101    ! Orchidee communicator :
102    IF (.NOT. cpl_lmdz) THEN
103       CALL MPI_INIT(ierr)
104       IF (ierr /= 0) THEN
105          WRITE(*,*) 'INIT_PARA : MPI_INIT failed with ',ierr
106          STOP "INIT_PARA"         
107       ENDIF
108       MPI_COMM_ORCH=MPI_COMM_WORLD
109    ELSE
110       MPI_COMM_ORCH=communicator
111    ENDIF
112         
113   
114    ! Int and real precision
115    IF (MPI_VERSION == 1) THEN
116       ! Version MPI 1.x
117       IF (i_std==i_4) THEN
118          MPI_INT_ORCH=MPI_INTEGER
119       ELSEIF (i_std==i_8) THEN
120          MPI_INT_ORCH=MPI_INTEGER
121       ELSE
122          MPI_INT_ORCH=MPI_INTEGER
123       ENDIF
124       
125       IF (r_std==r_4) THEN
126          MPI_REAL_ORCH=MPI_REAL
127       ELSEIF (r_std==r_8) THEN
128          MPI_REAL_ORCH=MPI_DOUBLE_PRECISION
129       ELSE
130          MPI_REAL_ORCH=MPI_REAL
131       ENDIF
132    ELSE
133       ! Others MPI
134       IF (i_std==i_4) THEN
135          MPI_INT_ORCH=MPI_INTEGER4
136       ELSEIF (i_std==i_8) THEN
137          MPI_INT_ORCH=MPI_INTEGER8
138       ELSE
139          MPI_INT_ORCH=MPI_INTEGER
140       ENDIF
141         
142       IF (r_std==r_4) THEN
143          MPI_REAL_ORCH=MPI_REAL4
144       ELSEIF (r_std==r_8) THEN
145          MPI_REAL_ORCH=MPI_REAL8
146       ELSE
147          MPI_REAL_ORCH=MPI_REAL
148       ENDIF
149    ENDIF
150     
151    CALL MPI_COMM_SIZE(MPI_COMM_ORCH,mpi_size,ierr)
152    IF (ierr /= 0) THEN
153       WRITE(*,*) 'INIT_PARA : MPI_COMM_SIZE failed with ',ierr
154       STOP "INIT_PARA"
155    ENDIF
156    CALL MPI_COMM_RANK(MPI_COMM_ORCH,mpi_rank,ierr)
157    IF (ierr /= 0) THEN
158       WRITE(*,*) 'INIT_PARA : MPI_COMM_RANK failed with ',ierr
159       STOP "INIT_PARA"
160    ENDIF
161     
162#else
163    mpi_rank=0
164    mpi_size=1   
165#endif
166    root_prc=0
167     
168    IF (mpi_rank==0) THEN
169       is_root_prc=.TRUE.
170    ELSE
171       is_root_prc=.FALSE.
172    ENDIF
173
174    ! Open mpi_rank outputs or select stdout
175    IF (mpi_size > 1) THEN
176       write(num,'(I4.4)') mpi_rank
177       
178       numout = 100
179       
180       filename =  'out_orchidee_'//num
181       
182       OPEN(UNIT=numout,FILE=TRIM(filename),ACTION='write',STATUS='unknown',FORM='formatted',IOSTAT=ierr) 
183       IF (ierr /= 0) THEN
184#ifdef CPP_PARA
185          CALL MPI_FINALIZE(ierr)
186#endif
187          WRITE(*,*) "Erreur can't open file ", filename
188          STOP "INIT_PARA"
189       ENDIF
190    ELSE
191       numout = 6
192    ENDIF
193
194    IF (check) THEN
195#ifdef CPP_PARA
196       WRITE(numout,*) 'version MPI ', MPI_VERSION, MPI_SUBVERSION
197       WRITE(numout,*) 'INTEGERS ',MPI_INTEGER4,MPI_INTEGER8,MPI_INTEGER,MPI_INT_ORCH
198       WRITE(numout,*) 'REALS ',MPI_REAL4,MPI_REAL8,MPI_REAL,MPI_REAL_ORCH
199#endif
200       WRITE(numout,*) 'RANK ',mpi_rank,' SIZE ',mpi_size
201       WRITE(numout,*) "Am I root process ?",is_root_prc
202       WRITE(numout,*) "Init_para : For process number ",mpi_rank, "output file = ",filename
203    ENDIF
204     
205  END SUBROUTINE init_para
206 
207  SUBROUTINE init_data_para(iim,jjm,nbpoints,index_x)
208
209    IMPLICIT NONE
210#ifdef CPP_PARA
211    INCLUDE 'mpif.h'
212#endif
213
214    INTEGER,INTENT(IN) :: iim
215    INTEGER,INTENT(IN) :: jjm
216    INTEGER,INTENT(IN) :: nbpoints
217    INTEGER,DIMENSION(:),INTENT(IN) :: index_x
218
219    INTEGER,ALLOCATABLE,DIMENSION(:) :: index_l
220    INTEGER,ALLOCATABLE,DIMENSION(:) :: displs
221#ifdef CPP_PARA
222    INTEGER :: ierr
223#endif 
224    INTEGER :: i
225    LOGICAL, PARAMETER :: check=.FALSE.
226
227
228    IF (check) WRITE(numout,*) 'INIT_DATA_PARA',iim,jjm,nbpoints,index_x
229    ALLOCATE(nbp_para_nb(0:mpi_size-1))
230    ALLOCATE(nbp_para_begin(0:mpi_size-1))
231    ALLOCATE(nbp_para_end(0:mpi_size-1))
232    ALLOCATE(jj_para_nb(0:mpi_size-1))
233    ALLOCATE(jj_para_begin(0:mpi_size-1))
234    ALLOCATE(jj_para_end(0:mpi_size-1))
235    ALLOCATE(ii_para_begin(0:mpi_size-1))
236    ALLOCATE(ii_para_end(0:mpi_size-1))
237    ALLOCATE(ij_para_nb(0:mpi_size-1))
238    ALLOCATE(ij_para_begin(0:mpi_size-1))
239    ALLOCATE(ij_para_end(0:mpi_size-1))
240
241    IF (cpl_lmdz) THEN
242#ifdef CPP_PARA
243       CALL MPI_GATHER(nbpoints,1,MPI_INT_ORCH,nbp_para_nb,1,MPI_INT_ORCH,root_prc,MPI_COMM_ORCH,ierr)
244#else
245       nbp_para_nb(0)=nbpoints
246#endif
247
248       IF (is_root_prc) THEN
249          nbp_glo=sum(nbp_para_nb)
250          ALLOCATE(displs(0:mpi_size-1))
251          ALLOCATE(index_l(nbp_glo))
252          displs(0)=0
253          DO i=1,mpi_size-1
254             displs(i)=displs(i-1)+nbp_para_nb(i-1)
255          ENDDO
256       ENDIF
257#ifdef CPP_PARA
258       CALL MPI_BCAST(nbp_glo,1,MPI_INT_ORCH,root_prc,MPI_COMM_ORCH,ierr)
259       CALL MPI_GATHERV(index_x,nbpoints,MPI_INT_ORCH,index_l,nbp_para_nb,displs,&
260            MPI_INT_ORCH,root_prc,MPI_COMM_ORCH,ierr) 
261#else
262       ! if not parallized, nb_glo=nbpoints=nbp_para_nb
263       IF (is_root_prc) index_l(:)=index_x(1:nbp_glo)
264#endif
265    ELSE
266       IF (is_root_prc) THEN
267          nbp_glo=nbpoints
268          ALLOCATE(index_l(nbp_glo))
269          index_l(:)=index_x(1:nbp_glo)
270          CALL Read_Load_Balance(nbpoints,nbp_para_nb)
271       ENDIF
272    ENDIF
273
274    IF (is_root_prc) THEN
275
276       IF (check) WRITE(numout,*) '==== DISTRIB ====',nbpoints,nbp_para_nb
277
278       nbp_para_begin(0)=1
279       nbp_para_end(0)=nbp_para_nb(0)
280
281       DO i=1,mpi_size-1
282          nbp_para_begin(i)=nbp_para_end(i-1)+1
283          nbp_para_end(i)=nbp_para_begin(i)+nbp_para_nb(i)-1
284       ENDDO
285
286       nbp_loc=nbp_para_nb(mpi_rank)
287
288       iim_g=iim
289       jjm_g=jjm
290
291
292       ij_para_begin(0)=1
293       ij_para_end(0)=index_l(nbp_para_end(0))
294       ij_para_nb(0)=ij_para_end(0)-ij_para_begin(0)+1
295
296       DO i=1,mpi_size-1
297          ij_para_begin(i)=ij_para_end(i-1)+1
298          ij_para_end(i)=index_l(nbp_para_end(i))
299          ij_para_nb(i)=ij_para_end(i)-ij_para_begin(i)+1
300       ENDDO
301
302       ij_para_end(mpi_size-1)=iim*jjm
303       ij_para_nb(mpi_size-1)=ij_para_end(mpi_size-1)-ij_para_begin(mpi_size-1)+1
304
305
306       DO i=0,mpi_size-1
307          jj_para_begin(i)=(ij_para_begin(i)-1)/iim + 1
308          jj_para_end(i)=(ij_para_end(i)-1)/iim + 1
309          jj_para_nb(i)=jj_para_end(i)-jj_para_begin(i)+1
310
311          ii_para_begin(i)=MOD(ij_para_begin(i)-1,iim)+1
312          ii_para_end(i)=MOD(ij_para_end(i)-1,iim)+1
313       ENDDO
314
315       IF (check) THEN
316          WRITE(numout,*) '==== DECOUP ===='
317          WRITE(numout,*) 'nbp_para_begin=',nbp_para_begin
318          WRITE(numout,*) 'nbp_para_end  =',nbp_para_end
319          WRITE(numout,*) 'nbp_loc=',nbp_loc
320
321          WRITE(numout,*) 'ij_para_begin=',ij_para_begin
322          WRITE(numout,*) 'ij_para_end=',ij_para_end
323          WRITE(numout,*) 'ij_para_nb=',ij_para_nb
324          WRITE(numout,*) 'jj_para_begin=',jj_para_begin
325          WRITE(numout,*) 'jj_para_end=',jj_para_end
326          WRITE(numout,*) 'jj_para_nb=',jj_para_nb     
327          WRITE(numout,*) 'ii_para_begin=',ii_para_begin
328          WRITE(numout,*) 'ii_para_end=',ii_para_end
329       ENDIF
330
331       !
332       !- Root need the global variables
333       !-
334       ALLOCATE(resolution_g(nbp_glo,2),area_g(nbp_glo),lalo_g(nbp_glo,2))
335       ALLOCATE(neighbours_g(nbp_glo,8),contfrac_g(nbp_glo),index_g(nbp_glo))
336       ALLOCATE(lon_g(iim_g, jjm_g), lat_g(iim_g, jjm_g), zlev_g(iim_g, jjm_g))
337
338       index_g(:)=index_l(1:nbp_glo)
339    ENDIF
340
341#ifdef CPP_PARA
342    IF (is_root_prc) WRITE(numout,*) 'nbp_para_nb =',nbp_para_nb
343    CALL MPI_BCAST(nbp_para_nb,mpi_size,MPI_INT_ORCH,root_prc,MPI_COMM_ORCH,ierr)
344    CALL MPI_BCAST(nbp_para_begin,mpi_size,MPI_INT_ORCH,root_prc,MPI_COMM_ORCH,ierr)
345    CALL MPI_BCAST(nbp_para_end,mpi_size,MPI_INT_ORCH,root_prc,MPI_COMM_ORCH,ierr)
346    CALL MPI_BCAST(jj_para_nb,mpi_size,MPI_INT_ORCH,root_prc,MPI_COMM_ORCH,ierr)
347    CALL MPI_BCAST(jj_para_begin,mpi_size,MPI_INT_ORCH,root_prc,MPI_COMM_ORCH,ierr)
348    CALL MPI_BCAST(jj_para_end,mpi_size,MPI_INT_ORCH,root_prc,MPI_COMM_ORCH,ierr)
349    CALL MPI_BCAST(ii_para_begin,mpi_size,MPI_INT_ORCH,root_prc,MPI_COMM_ORCH,ierr)
350    CALL MPI_BCAST(ii_para_end,mpi_size,MPI_INT_ORCH,root_prc,MPI_COMM_ORCH,ierr)
351    CALL MPI_BCAST(ij_para_nb,mpi_size,MPI_INT_ORCH,root_prc,MPI_COMM_ORCH,ierr)
352    CALL MPI_BCAST(ij_para_begin,mpi_size,MPI_INT_ORCH,root_prc,MPI_COMM_ORCH,ierr)
353    CALL MPI_BCAST(ij_para_end,mpi_size,MPI_INT_ORCH,root_prc,MPI_COMM_ORCH,ierr)
354    CALL MPI_BCAST(iim_g,1,MPI_INT_ORCH,root_prc,MPI_COMM_ORCH,ierr)
355    CALL MPI_BCAST(jjm_g,1,MPI_INT_ORCH,root_prc,MPI_COMM_ORCH,ierr)
356    CALL MPI_BCAST(nbp_glo,1,MPI_INT_ORCH,root_prc,MPI_COMM_ORCH,ierr)
357#endif
358
359    nbp_loc=nbp_para_nb(mpi_rank)
360
361    ij_nb=ij_para_nb(mpi_rank)
362    ij_begin=ij_para_begin(mpi_rank)
363    ij_end=ij_para_end(mpi_rank)
364
365    jj_nb=jj_para_nb(mpi_rank)
366    jj_begin=jj_para_begin(mpi_rank)
367    jj_end=jj_para_end(mpi_rank)
368
369    ii_begin=ii_para_begin(mpi_rank)
370    ii_end=ii_para_end(mpi_rank)
371
372    IF (check) &
373         WRITE(numout,*) 'Init_io_para'
374    CALL Init_io_para
375
376    IF (is_root_prc ) THEN
377       DEALLOCATE(index_l)
378       IF ( cpl_lmdz) THEN
379          DEALLOCATE(displs)
380       ENDIF
381    ENDIF
382
383    IF (check) &
384         WRITE(numout,*)  'DATA PARA',nbp_loc,nbp_glo,jj_begin,jj_end,ii_begin,ii_end       
385  END SUBROUTINE init_data_para
386 
387
388  SUBROUTINE Init_io_para
389    USE ioipsl
390    IMPLICIT NONE
391   
392    INTEGER,DIMENSION(2) :: ddid
393    INTEGER,DIMENSION(2) :: dsg
394    INTEGER,DIMENSION(2) :: dsl
395    INTEGER,DIMENSION(2) :: dpf
396    INTEGER,DIMENSION(2) :: dpl
397    INTEGER,DIMENSION(2) :: dhs
398    INTEGER,DIMENSION(2) :: dhe 
399
400    ddid=(/ 1,2 /)
401    dsg=(/ iim_g, jjm_g /)
402    dsl=(/ iim_g, jj_nb /)
403    dpf=(/ 1,jj_begin /)
404    dpl=(/ iim_g, jj_end /)
405    dhs=(/ ii_begin-1,0 /)
406    if (mpi_rank==mpi_size-1) then
407      dhe=(/0,0/)
408    else
409      dhe=(/ iim_g-ii_end,0 /) 
410    endif
411   
412    call flio_dom_set(mpi_size,mpi_rank,ddid,dsg,dsl,dpf,dpl,dhs,dhe, &
413                      'APPLE',orch_domain_id)
414  END SUBROUTINE Init_io_para
415 
416  SUBROUTINE Read_Load_balance(NbPoints,Nbpoints_loc)
417
418    IMPLICIT NONE
419    INTEGER,INTENT(IN)  :: NbPoints
420    INTEGER,INTENT(OUT) :: Nbpoints_loc(0:mpi_size-1)
421#ifdef CPP_PARA 
422    INTEGER :: unit_number=10
423    CHARACTER(len=255)  :: filename='Load_balance_orchidee.dat'
424    INTEGER :: j
425#endif
426    INTEGER :: i,s,ierr
427   
428    Nbpoints_loc(:) = 0
429
430#ifdef CPP_PARA
431    OPEN(UNIT=unit_number,FILE=trim(filename),STATUS='old',FORM='formatted',IOSTAT=ierr) 
432#else
433    ierr=1
434#endif   
435    s=0
436
437#ifdef CPP_PARA 
438    IF (ierr==0) THEN
439       i=0
440       !- Reading for any balancing file (even with a bad structure)
441       DO WHILE (i < mpi_size .AND. ierr == 0) 
442          READ (unit_number,*,IOSTAT=ierr) j,Nbpoints_loc(i)
443          s=s+Nbpoints_loc(i)
444          i=i+1
445       ENDDO
446       CLOSE(unit_number)
447    ENDIF
448#endif   
449   
450    !- Correction of bad balancing file (or an empty file) => same nb of points for each procs
451    IF (ierr/=0 .OR. s/=Nbpoints) THEN
452       DO i=0,mpi_size-1
453          Nbpoints_loc(i)=Nbpoints/mpi_size
454          IF (MOD(Nbpoints,mpi_size) > i) Nbpoints_loc(i)=Nbpoints_loc(i)+1
455       ENDDO
456    ENDIF
457   
458  END SUBROUTINE Read_Load_balance
459 
460  SUBROUTINE Write_Load_balance(times)
461    IMPLICIT NONE
462    REAL(r_std),INTENT(IN) :: times
463 
464#ifdef CPP_PARA 
465    CHARACTER(len=255)  :: filename='Load_balance_orchidee.dat'
466    INTEGER :: unit_number=10
467    INTEGER :: i,ierr
468    REAL :: All_Times(0:mpi_size-1)
469    REAL :: average
470    REAL :: efficiency
471    INTEGER :: dp,S
472    INTEGER :: New_nbpoints(0:mpi_size-1)
473#endif
474   
475    WRITE(numout,*) 'time',times
476#ifndef CPP_PARA
477    RETURN
478#else
479
480    CALL MPI_GATHER(times,1,MPI_REAL_ORCH,All_times,1,MPI_REAL_ORCH,root_prc,MPI_COMM_ORCH,ierr)
481    IF (is_root_prc) WRITE(numout,*) 'ALL_times',All_times
482
483    IF (is_root_prc) THEN
484     
485       OPEN(UNIT=unit_number,FILE=trim(filename),STATUS='replace',FORM='formatted',IOSTAT=ierr)
486       
487       average=sum(All_times(:))/mpi_size
488       DO i=0,mpi_size-1
489          efficiency=All_times(i)/Nbp_para_nb(i)
490          New_nbpoints(i)=Nbp_para_nb(i)-(All_times(i)-average)/efficiency
491       ENDDO
492       
493       S=sum(new_nbpoints(:))
494       dp=nbp_glo-S
495       
496       IF ( dp > 0 ) THEN
497          DO WHILE ( dp > 0 )
498             New_nbpoints(MOD(dp,mpi_size))=New_nbpoints(MOD(dp,mpi_size))+1
499             dp=dp-1
500          ENDDO
501       ELSE
502          dp=-dp
503          DO WHILE ( dp > 0 )
504             New_nbpoints(MOD(dp,mpi_size))=New_nbpoints(MOD(dp,mpi_size))-1
505             dp=dp-1
506          ENDDO
507       ENDIF
508       
509       ! If this algorithm diverge, we use previous repartition.
510       IF ( ANY(New_nbpoints(:) .LE. 0) ) THEN
511          New_nbpoints(:)=Nbp_para_nb(:)
512       ENDIF
513       
514       DO i=0,mpi_size-1
515          WRITE(Unit_number,*) i,New_nbpoints(i)
516       ENDDO
517       CLOSE(Unit_number)
518    ENDIF
519#endif
520 
521  END SUBROUTINE Write_Load_Balance
522 
523 
524 
525END MODULE data_para
526
527#include "mpi_dummy.h"
Note: See TracBrowser for help on using the repository browser.