mppini.F90 18 KB

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