New URL for NEMO forge!   http://forge.nemo-ocean.eu

Since March 2022 along with NEMO 4.2 release, the code development moved to a self-hosted GitLab.
This present forge is now archived and remained online for history.
mppini.F90 in trunk/NEMOGCM/NEMO/OPA_SRC/LBC – NEMO

source: trunk/NEMOGCM/NEMO/OPA_SRC/LBC/mppini.F90 @ 2731

Last change on this file since 2731 was 2715, checked in by rblod, 13 years ago

First attempt to put dynamic allocation on the trunk

  • Property svn:keywords set to Id
File size: 17.0 KB
Line 
1MODULE mppini
2   !!==============================================================================
3   !!                       ***  MODULE mppini   ***
4   !! Ocean initialization : distributed memory computing initialization
5   !!==============================================================================
6
7   !!----------------------------------------------------------------------
8   !!   mpp_init       : Lay out the global domain over processors
9   !!   mpp_init2      : Lay out the global domain over processors
10   !!                    with land processor elimination
11   !!   mpp_init_ioispl: IOIPSL initialization in mpp
12   !!----------------------------------------------------------------------
13   !! * Modules used
14   USE dom_oce         ! ocean space and time domain
15   USE in_out_manager  ! I/O Manager
16   USE lib_mpp         ! distribued memory computing library
17   USE ioipsl
18
19   IMPLICIT NONE
20   PRIVATE
21
22   PUBLIC mpp_init       ! called by opa.F90
23   PUBLIC mpp_init2      ! called by opa.F90
24
25   !! * Substitutions
26#  include "domzgr_substitute.h90"
27   !!----------------------------------------------------------------------
28   !! NEMO/OPA 3.3 , NEMO Consortium (2010)
29   !! $Id$
30   !! Software governed by the CeCILL licence     (NEMOGCM/NEMO_CeCILL.txt)
31   !!----------------------------------------------------------------------
32CONTAINS
33
34#if ! defined key_mpp_mpi
35   !!----------------------------------------------------------------------
36   !!   Default option :                            shared memory computing
37   !!----------------------------------------------------------------------
38
39   SUBROUTINE mpp_init
40      !!----------------------------------------------------------------------
41      !!                  ***  ROUTINE mpp_init  ***
42      !!
43      !! ** Purpose :   Lay out the global domain over processors.
44      !!
45      !! ** Method  :   Shared memory computing, set the local processor
46      !!      variables to the value of the global domain
47      !!
48      !! History :
49      !!   9.0  !  04-01  (G. Madec, J.M. Molines)  F90 : free form, north fold jpni >1
50      !!----------------------------------------------------------------------
51
52      ! No mpp computation
53      nimpp  = 1
54      njmpp  = 1
55      nlci   = jpi
56      nlcj   = jpj
57      nldi   = 1
58      nldj   = 1
59      nlei   = jpi
60      nlej   = jpj
61      nperio = jperio
62      nbondi = 2
63      nbondj = 2
64      nidom  = FLIO_DOM_NONE
65      npolj = jperio
66
67      IF(lwp) THEN
68         WRITE(numout,*)
69         WRITE(numout,*) 'mpp_init(2) : NO massively parallel processing'
70         WRITE(numout,*) '~~~~~~~~~~~: '
71         WRITE(numout,*) '         nperio = ', nperio
72         WRITE(numout,*) '         npolj  = ', npolj
73         WRITE(numout,*) '         nimpp  = ', nimpp
74         WRITE(numout,*) '         njmpp  = ', njmpp
75      ENDIF
76
77      IF(  jpni /= 1 .OR. jpnj /= 1 .OR. jpnij /= 1 ) &
78          CALL ctl_stop( 'equality  jpni = jpnj = jpnij = 1 is not satisfied',   &
79          &              'the domain is lay out for distributed memory computing! ' )
80
81   END SUBROUTINE mpp_init
82
83
84   SUBROUTINE mpp_init2 
85      CALL mpp_init                             ! same routine as mpp_init
86   END SUBROUTINE mpp_init2
87
88#else
89   !!----------------------------------------------------------------------
90   !!   'key_mpp_mpi'          OR         MPI massively parallel processing
91   !!----------------------------------------------------------------------
92
93   SUBROUTINE mpp_init
94      !!----------------------------------------------------------------------
95      !!                  ***  ROUTINE mpp_init  ***
96      !!                   
97      !! ** Purpose :   Lay out the global domain over processors.
98      !!
99      !! ** Method  :   Global domain is distributed in smaller local domains.
100      !!      Periodic condition is a function of the local domain position
101      !!      (global boundary or neighbouring domain) and of the global
102      !!      periodic
103      !!      Type :         jperio global periodic condition
104      !!                     nperio local  periodic condition
105      !!
106      !! ** Action  : - set domain parameters
107      !!                    nimpp     : longitudinal index
108      !!                    njmpp     : latitudinal  index
109      !!                    nperio    : lateral condition type
110      !!                    narea     : number for local area
111      !!                    nlci      : first dimension
112      !!                    nlcj      : second dimension
113      !!                    nbondi    : mark for "east-west local boundary"
114      !!                    nbondj    : mark for "north-south local boundary"
115      !!                    nproc     : number for local processor
116      !!                    noea      : number for local neighboring processor
117      !!                    nowe      : number for local neighboring processor
118      !!                    noso      : number for local neighboring processor
119      !!                    nono      : number for local neighboring processor
120      !!
121      !! History :
122      !!        !  94-11  (M. Guyon)  Original code
123      !!        !  95-04  (J. Escobar, M. Imbard)
124      !!        !  98-02  (M. Guyon)  FETI method
125      !!        !  98-05  (M. Imbard, J. Escobar, L. Colombet )  SHMEM and MPI versions
126      !!   8.5  !  02-08  (G. Madec)  F90 : free form
127      !!----------------------------------------------------------------------
128      INTEGER  ::   ji, jj, jn   ! dummy loop indices
129      INTEGER  ::   ii, ij, ifreq, il1, il2            ! local integers
130      INTEGER  ::   iresti, irestj, ijm1, imil, inum   !   -      -
131      REAL(wp) ::   zidom, zjdom                       ! local scalars
132      INTEGER, DIMENSION(jpni,jpnj) ::   iimppt, ijmppt, ilcit, ilcjt   ! local workspace
133      !!----------------------------------------------------------------------
134
135      IF(lwp) WRITE(numout,*)
136      IF(lwp) WRITE(numout,*) 'mpp_init : Message Passing MPI'
137      IF(lwp) WRITE(numout,*) '~~~~~~~~'
138
139
140      !  1. Dimension arrays for subdomains
141      ! -----------------------------------
142      !  Computation of local domain sizes ilcit() ilcjt()
143      !  These dimensions depend on global sizes jpni,jpnj and jpiglo,jpjglo
144      !  The subdomains are squares leeser than or equal to the global
145      !  dimensions divided by the number of processors minus the overlap
146      !  array (cf. par_oce.F90).
147     
148      nreci  = 2 * jpreci
149      nrecj  = 2 * jprecj
150      iresti = MOD( jpiglo - nreci , jpni )
151      irestj = MOD( jpjglo - nrecj , jpnj )
152
153      IF(  iresti == 0 )   iresti = jpni
154      DO jj = 1, jpnj
155         DO ji = 1, iresti
156            ilcit(ji,jj) = jpi
157         END DO
158         DO ji = iresti+1, jpni
159            ilcit(ji,jj) = jpi -1
160         END DO
161      END DO
162     
163      IF( irestj == 0 )   irestj = jpnj
164      DO ji = 1, jpni
165         DO jj = 1, irestj
166            ilcjt(ji,jj) = jpj
167         END DO
168         DO jj = irestj+1, jpnj
169            ilcjt(ji,jj) = jpj -1
170         END DO
171      END DO
172     
173      IF(lwp) THEN
174         WRITE(numout,*)
175         WRITE(numout,*) '           defines mpp subdomains'
176         WRITE(numout,*) '           ----------------------'
177         WRITE(numout,*) '           iresti=',iresti,' irestj=',irestj
178         WRITE(numout,*) '           jpni  =',jpni  ,' jpnj  =',jpnj
179         ifreq = 4
180         il1   = 1
181         DO jn = 1, (jpni-1)/ifreq+1
182            il2 = MIN( jpni, il1+ifreq-1 )
183            WRITE(numout,*)
184            WRITE(numout,9200) ('***',ji = il1,il2-1)
185            DO jj = jpnj, 1, -1
186               WRITE(numout,9203) ('   ',ji = il1,il2-1)
187               WRITE(numout,9202) jj, ( ilcit(ji,jj),ilcjt(ji,jj),ji = il1,il2 )
188               WRITE(numout,9203) ('   ',ji = il1,il2-1)
189               WRITE(numout,9200) ('***',ji = il1,il2-1)
190            END DO
191            WRITE(numout,9201) (ji,ji = il1,il2)
192            il1 = il1+ifreq
193         END DO
194 9200    FORMAT('     ***',20('*************',a3))
195 9203    FORMAT('     *     ',20('         *   ',a3))
196 9201    FORMAT('        ',20('   ',i3,'          '))
197 9202    FORMAT(' ',i3,' *  ',20(i3,'  x',i3,'   *   '))
198      ENDIF
199
200      zidom = nreci
201      DO ji = 1, jpni
202         zidom = zidom + ilcit(ji,1) - nreci
203      END DO
204      IF(lwp) WRITE(numout,*)
205      IF(lwp) WRITE(numout,*)' sum ilcit(i,1) = ', zidom, ' jpiglo = ', jpiglo
206     
207      zjdom = nrecj
208      DO jj = 1, jpnj
209         zjdom = zjdom + ilcjt(1,jj) - nrecj
210      END DO
211      IF(lwp) WRITE(numout,*)' sum ilcit(1,j) = ', zjdom, ' jpjglo = ', jpjglo
212      IF(lwp) WRITE(numout,*)
213     
214
215      !  2. Index arrays for subdomains
216      ! -------------------------------
217     
218      iimppt(:,:) = 1
219      ijmppt(:,:) = 1
220     
221      IF( jpni > 1 ) THEN
222         DO jj = 1, jpnj
223            DO ji = 2, jpni
224               iimppt(ji,jj) = iimppt(ji-1,jj) + ilcit(ji-1,jj) - nreci
225            END DO
226         END DO
227      ENDIF
228
229      IF( jpnj > 1 ) THEN
230         DO jj = 2, jpnj
231            DO ji = 1, jpni
232               ijmppt(ji,jj) = ijmppt(ji,jj-1)+ilcjt(ji,jj-1)-nrecj
233            END DO
234         END DO
235      ENDIF
236     
237      ! 3. Subdomain description
238      ! ------------------------
239
240      DO jn = 1, jpnij
241         ii = 1 + MOD( jn-1, jpni )
242         ij = 1 + (jn-1) / jpni
243         nimppt(jn) = iimppt(ii,ij)
244         njmppt(jn) = ijmppt(ii,ij)
245         nlcit (jn) = ilcit (ii,ij)     
246         nlci       = nlcit (jn)     
247         nlcjt (jn) = ilcjt (ii,ij)     
248         nlcj       = nlcjt (jn)
249         nbondj = -1                                   ! general case
250         IF( jn   >  jpni          )   nbondj = 0      ! first row of processor
251         IF( jn   >  (jpnj-1)*jpni )   nbondj = 1      ! last  row of processor
252         IF( jpnj == 1             )   nbondj = 2      ! one processor only in j-direction
253         ibonjt(jn) = nbondj
254         
255         nbondi = 0                                    !
256         IF( MOD( jn, jpni ) == 1 )   nbondi = -1      !
257         IF( MOD( jn, jpni ) == 0 )   nbondi =  1      !
258         IF( jpni            == 1 )   nbondi =  2      ! one processor only in i-direction
259         ibonit(jn) = nbondi
260         
261         nldi =  1   + jpreci
262         nlei = nlci - jpreci
263         IF( nbondi == -1 .OR. nbondi == 2 )   nldi = 1
264         IF( nbondi ==  1 .OR. nbondi == 2 )   nlei = nlci
265         nldj =  1   + jprecj
266         nlej = nlcj - jprecj
267         IF( nbondj == -1 .OR. nbondj == 2 )   nldj = 1
268         IF( nbondj ==  1 .OR. nbondj == 2 )   nlej = nlcj
269         nldit(jn) = nldi
270         nleit(jn) = nlei
271         nldjt(jn) = nldj
272         nlejt(jn) = nlej
273      END DO
274     
275
276      ! 4. From global to local
277      ! -----------------------
278
279      nperio = 0
280      IF( jperio == 2 .AND. nbondj == -1 )   nperio = 2
281
282
283      ! 5. Subdomain neighbours
284      ! ----------------------
285
286      nproc = narea - 1
287      noso  = nproc - jpni
288      nowe  = nproc - 1
289      noea  = nproc + 1
290      nono  = nproc + jpni
291      ! great neighbours
292      npnw = nono - 1
293      npne = nono + 1
294      npsw = noso - 1
295      npse = noso + 1
296      nbsw = 1
297      nbnw = 1
298      IF( MOD( nproc, jpni ) == 0 ) THEN
299         nbsw = 0
300         nbnw = 0
301      ENDIF
302      nbse = 1
303      nbne = 1
304      IF( MOD( nproc, jpni ) == jpni-1 ) THEN
305         nbse = 0
306         nbne = 0
307      ENDIF
308      IF(nproc < jpni) THEN
309         nbsw = 0
310         nbse = 0
311      ENDIF
312      IF( nproc >= (jpnj-1)*jpni ) THEN
313         nbnw = 0
314         nbne = 0
315      ENDIF
316      nlcj = nlcjt(narea) 
317      nlci = nlcit(narea) 
318      nldi = nldit(narea)
319      nlei = nleit(narea)
320      nldj = nldjt(narea)
321      nlej = nlejt(narea)
322      nbondi = ibonit(narea)
323      nbondj = ibonjt(narea)
324      nimpp  = nimppt(narea) 
325      njmpp  = njmppt(narea) 
326
327     ! Save processor layout in layout.dat file
328       IF (lwp) THEN
329        CALL ctl_opn( inum, 'layout.dat', 'REPLACE', 'FORMATTED', 'SEQUENTIAL', -1, numout, .FALSE., narea )
330        WRITE(inum,'(a)') '   jpnij     jpi     jpj     jpk  jpiglo  jpjglo'
331        WRITE(inum,'(6i8)') jpnij,jpi,jpj,jpk,jpiglo,jpjglo
332        WRITE(inum,'(a)') 'NAREA nlci nlcj nldi nldj nlei nlej nimpp njmpp'
333
334        DO  jn = 1, jpnij
335         WRITE(inum,'(9i5)') jn, nlcit(jn), nlcjt(jn), &
336                                      nldit(jn), nldjt(jn), &
337                                      nleit(jn), nlejt(jn), &
338                                      nimppt(jn), njmppt(jn)
339        END DO
340        CLOSE(inum)   
341      END IF
342
343
344      ! w a r n i n g  narea (zone) /= nproc (processors)!
345
346      IF( jperio == 1 .OR. jperio == 4 .OR. jperio == 6 ) THEN
347         IF( jpni == 1 )THEN
348            nbondi = 2
349            nperio = 1
350         ELSE
351            nbondi = 0
352         ENDIF
353         IF( MOD( narea, jpni ) == 0 ) THEN
354            noea = nproc-(jpni-1)
355            npne = npne-jpni
356            npse = npse-jpni
357         ENDIF
358         IF( MOD( narea, jpni ) == 1 ) THEN
359            nowe = nproc+(jpni-1)
360            npnw = npnw+jpni
361            npsw = npsw+jpni
362         ENDIF
363         nbsw = 1
364         nbnw = 1
365         nbse = 1
366         nbne = 1
367         IF( nproc < jpni ) THEN
368            nbsw = 0
369            nbse = 0
370         ENDIF
371         IF( nproc >= (jpnj-1)*jpni ) THEN
372            nbnw = 0
373            nbne = 0
374         ENDIF
375      ENDIF
376      npolj = 0
377      IF( jperio == 3 .OR. jperio == 4 ) THEN
378         ijm1 = jpni*(jpnj-1)
379         imil = ijm1+(jpni+1)/2
380         IF( narea > ijm1 ) npolj = 3
381         IF( MOD(jpni,2) == 1 .AND. narea == imil ) npolj = 4
382         IF( npolj == 3 ) nono = jpni*jpnj-narea+ijm1
383      ENDIF
384      IF( jperio == 5 .OR. jperio == 6 ) THEN
385          ijm1 = jpni*(jpnj-1)
386          imil = ijm1+(jpni+1)/2
387          IF( narea > ijm1) npolj = 5
388          IF( MOD(jpni,2) == 1 .AND. narea == imil ) npolj = 6
389          IF( npolj == 5 ) nono = jpni*jpnj-narea+ijm1
390      ENDIF
391
392      ! Periodicity : no corner if nbondi = 2 and nperio != 1
393
394      IF(lwp) THEN
395         WRITE(numout,*) ' nproc  = ', nproc
396         WRITE(numout,*) ' nowe   = ', nowe  , ' noea   =  ', noea
397         WRITE(numout,*) ' nono   = ', nono  , ' noso   =  ', noso
398         WRITE(numout,*) ' nbondi = ', nbondi
399         WRITE(numout,*) ' nbondj = ', nbondj
400         WRITE(numout,*) ' npolj  = ', npolj
401         WRITE(numout,*) ' nperio = ', nperio
402         WRITE(numout,*) ' nlci   = ', nlci
403         WRITE(numout,*) ' nlcj   = ', nlcj
404         WRITE(numout,*) ' nimpp  = ', nimpp
405         WRITE(numout,*) ' njmpp  = ', njmpp
406         WRITE(numout,*) ' nbse   = ', nbse  , ' npse   = ', npse
407         WRITE(numout,*) ' nbsw   = ', nbsw  , ' npsw   = ', npsw
408         WRITE(numout,*) ' nbne   = ', nbne  , ' npne   = ', npne
409         WRITE(numout,*) ' nbnw   = ', nbnw  , ' npnw   = ', npnw
410      ENDIF
411
412      IF( nperio == 1 .AND. jpni /= 1 ) CALL ctl_stop( ' mpp_init: error on cyclicity' )
413
414      ! Prepare mpp north fold
415
416      IF (jperio >= 3 .AND. jperio <= 6 .AND. jpni > 1 ) THEN
417         CALL mpp_ini_north
418      END IF
419
420      ! Prepare NetCDF output file (if necessary)
421      CALL mpp_init_ioipsl
422
423   END SUBROUTINE mpp_init
424
425#  include "mppini_2.h90"
426
427# if defined key_dimgout
428   !!----------------------------------------------------------------------
429   !!   'key_dimgout'                  NO use of NetCDF files
430   !!----------------------------------------------------------------------
431   SUBROUTINE mpp_init_ioipsl       ! Dummy routine
432   END SUBROUTINE mpp_init_ioipsl 
433# else
434   SUBROUTINE mpp_init_ioipsl
435      !!----------------------------------------------------------------------
436      !!                  ***  ROUTINE mpp_init_ioipsl  ***
437      !!
438      !! ** Purpose :   
439      !!
440      !! ** Method  :   
441      !!
442      !! History :
443      !!   9.0  !  04-03  (G. Madec )  MPP-IOIPSL
444      !!   " "  !  08-12  (A. Coward)  addition in case of jpni*jpnj < jpnij
445      !!----------------------------------------------------------------------
446      INTEGER, DIMENSION(2) ::   iglo, iloc, iabsf, iabsl, ihals, ihale, idid
447      !!----------------------------------------------------------------------
448
449      ! The domain is split only horizontally along i- or/and j- direction
450      ! So we need at the most only 1D arrays with 2 elements.
451      ! Set idompar values equivalent to the jpdom_local_noextra definition
452      ! used in IOM. This works even if jpnij .ne. jpni*jpnj.
453      iglo(1) = jpiglo
454      iglo(2) = jpjglo
455      iloc(1) = nlci
456      iloc(2) = nlcj
457      iabsf(1) = nimppt(narea)
458      iabsf(2) = njmppt(narea)
459      iabsl(:) = iabsf(:) + iloc(:) - 1
460      ihals(1) = nldi - 1
461      ihals(2) = nldj - 1
462      ihale(1) = nlci - nlei
463      ihale(2) = nlcj - nlej
464      idid(1) = 1
465      idid(2) = 2
466
467      IF(lwp) THEN
468          WRITE(numout,*)
469          WRITE(numout,*) 'mpp_init_ioipsl :   iloc  = ', iloc (1), iloc (2)
470          WRITE(numout,*) '~~~~~~~~~~~~~~~     iabsf = ', iabsf(1), iabsf(2)
471          WRITE(numout,*) '                    ihals = ', ihals(1), ihals(2)
472          WRITE(numout,*) '                    ihale = ', ihale(1), ihale(2)
473      ENDIF
474      !
475      CALL flio_dom_set ( jpnij, nproc, idid, iglo, iloc, iabsf, iabsl, ihals, ihale, 'BOX', nidom)
476      !
477   END SUBROUTINE mpp_init_ioipsl 
478
479# endif
480#endif
481
482   !!======================================================================
483END MODULE mppini
Note: See TracBrowser for help on using the repository browser.