icblbc.F90 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932
  1. MODULE icblbc
  2. !!======================================================================
  3. !! *** MODULE icblbc ***
  4. !! Ocean physics: routines to handle boundary exchanges for icebergs
  5. !!======================================================================
  6. !! History : 3.3.1 ! 2010-01 (Martin&Adcroft) Original code
  7. !! - ! 2011-03 (Madec) Part conversion to NEMO form
  8. !! - ! Removal of mapping from another grid
  9. !! - ! 2011-04 (Alderson) Split into separate modules
  10. !! - ! 2011-05 (Alderson) MPP exchanges written based on lib_mpp
  11. !! - ! 2011-05 (Alderson) MPP and single processor boundary
  12. !! - ! conditions added
  13. !!----------------------------------------------------------------------
  14. !!----------------------------------------------------------------------
  15. !! icb_lbc : - Pass icebergs across cyclic boundaries
  16. !! icb_lbc_mpp : - In MPP pass icebergs from linked list between processors
  17. !! as they advect around
  18. !! - Lagrangian processes cannot be handled by existing NEMO MPP
  19. !! routines because they do not lie on regular jpi,jpj grids
  20. !! - Processor exchanges are handled as in lib_mpp whenever icebergs step
  21. !! across boundary of interior domain (nicbdi-nicbei, nicbdj-nicbej)
  22. !! so that iceberg does not exist in more than one processor
  23. !! - North fold exchanges controlled by three arrays:
  24. !! nicbflddest - unique processor numbers that current one exchanges with
  25. !! nicbfldproc - processor number that current grid point exchanges with
  26. !! nicbfldpts - packed i,j point in exchanging processor
  27. !!----------------------------------------------------------------------
  28. USE par_oce ! ocean parameters
  29. USE dom_oce ! ocean domain
  30. USE in_out_manager ! IO parameters
  31. USE lib_mpp ! MPI code and lk_mpp in particular
  32. USE icb_oce ! define iceberg arrays
  33. USE icbutl ! iceberg utility routines
  34. IMPLICIT NONE
  35. PRIVATE
  36. #if defined key_mpp_mpi
  37. !$AGRIF_DO_NOT_TREAT
  38. INCLUDE 'mpif.h'
  39. !$AGRIF_END_DO_NOT_TREAT
  40. TYPE, PUBLIC :: buffer
  41. INTEGER :: size=0
  42. REAL(wp), DIMENSION(:,:), POINTER :: data
  43. END TYPE buffer
  44. TYPE(buffer), POINTER :: obuffer_n=>NULL() , ibuffer_n=>NULL()
  45. TYPE(buffer), POINTER :: obuffer_s=>NULL() , ibuffer_s=>NULL()
  46. TYPE(buffer), POINTER :: obuffer_e=>NULL() , ibuffer_e=>NULL()
  47. TYPE(buffer), POINTER :: obuffer_w=>NULL() , ibuffer_w=>NULL()
  48. ! north fold exchange buffers
  49. TYPE(buffer), POINTER :: obuffer_f=>NULL() , ibuffer_f=>NULL()
  50. INTEGER, PARAMETER, PRIVATE :: jp_delta_buf = 25 ! Size by which to increment buffers
  51. INTEGER, PARAMETER, PRIVATE :: jp_buffer_width = 15+nkounts ! items to store for each berg
  52. #endif
  53. PUBLIC icb_lbc
  54. PUBLIC icb_lbc_mpp
  55. !!----------------------------------------------------------------------
  56. !! NEMO/OPA 3.3 , NEMO Consortium (2011)
  57. !! $Id: icblbc.F90 2355 2015-05-20 07:11:50Z ufla $
  58. !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
  59. !!----------------------------------------------------------------------
  60. CONTAINS
  61. SUBROUTINE icb_lbc()
  62. !!----------------------------------------------------------------------
  63. !! *** SUBROUTINE icb_lbc ***
  64. !!
  65. !! ** Purpose : in non-mpp case need to deal with cyclic conditions
  66. !! including north-fold
  67. !!----------------------------------------------------------------------
  68. TYPE(iceberg), POINTER :: this
  69. TYPE(point) , POINTER :: pt
  70. INTEGER :: iine
  71. !!----------------------------------------------------------------------
  72. !! periodic east/west boundaries
  73. !! =============================
  74. IF( nperio == 1 .OR. nperio == 4 .OR. nperio == 6 ) THEN
  75. this => first_berg
  76. DO WHILE( ASSOCIATED(this) )
  77. pt => this%current_point
  78. iine = INT( pt%xi + 0.5 )
  79. IF( iine > mig(nicbei) ) THEN
  80. pt%xi = ricb_right + MOD(pt%xi, 1._wp ) - 1._wp
  81. ELSE IF( iine < mig(nicbdi) ) THEN
  82. pt%xi = ricb_left + MOD(pt%xi, 1._wp )
  83. ENDIF
  84. this => this%next
  85. END DO
  86. !
  87. ENDIF
  88. !! north/south boundaries
  89. !! ======================
  90. ! south symmetric
  91. IF( nperio == 2 ) CALL ctl_stop(' south symmetric condition not implemented for icebergs')
  92. ! north fold
  93. IF( nperio == 3 .OR. nperio == 4 .OR. nperio == 5 .OR. nperio == 6 ) CALL icb_lbc_nfld()
  94. !
  95. END SUBROUTINE icb_lbc
  96. SUBROUTINE icb_lbc_nfld()
  97. !!----------------------------------------------------------------------
  98. !! *** SUBROUTINE icb_lbc_nfld ***
  99. !!
  100. !! ** Purpose : single processor north fold exchange
  101. !!----------------------------------------------------------------------
  102. TYPE(iceberg), POINTER :: this
  103. TYPE(point) , POINTER :: pt
  104. INTEGER :: iine, ijne, ipts
  105. INTEGER :: iiglo, ijglo
  106. !!----------------------------------------------------------------------
  107. !
  108. this => first_berg
  109. DO WHILE( ASSOCIATED(this) )
  110. pt => this%current_point
  111. ijne = INT( pt%yj + 0.5 )
  112. IF( ijne .GT. mjg(nicbej) ) THEN
  113. !
  114. iine = INT( pt%xi + 0.5 )
  115. ipts = nicbfldpts (mi1(iine))
  116. !
  117. ! moving across the cut line means both position and
  118. ! velocity must change
  119. ijglo = INT( ipts/nicbpack )
  120. iiglo = ipts - nicbpack*ijglo
  121. pt%xi = iiglo - ( pt%xi - REAL(iine,wp) )
  122. pt%yj = ijglo - ( pt%yj - REAL(ijne,wp) )
  123. pt%uvel = -1._wp * pt%uvel
  124. pt%vvel = -1._wp * pt%vvel
  125. ENDIF
  126. this => this%next
  127. END DO
  128. !
  129. END SUBROUTINE icb_lbc_nfld
  130. #if defined key_mpp_mpi
  131. !!----------------------------------------------------------------------
  132. !! 'key_mpp_mpi' MPI massively parallel processing library
  133. !!----------------------------------------------------------------------
  134. SUBROUTINE icb_lbc_mpp()
  135. !!----------------------------------------------------------------------
  136. !! *** SUBROUTINE icb_lbc_mpp ***
  137. !!
  138. !! ** Purpose : multi processor exchange
  139. !!
  140. !! ** Method : identify direction for exchange, pack into a buffer
  141. !! which is basically a real array and delete from linked list
  142. !! length of buffer is exchanged first with receiving processor
  143. !! then buffer is sent if necessary
  144. !!----------------------------------------------------------------------
  145. TYPE(iceberg) , POINTER :: tmpberg, this
  146. TYPE(point) , POINTER :: pt
  147. INTEGER :: ibergs_to_send_e, ibergs_to_send_w
  148. INTEGER :: ibergs_to_send_n, ibergs_to_send_s
  149. INTEGER :: ibergs_rcvd_from_e, ibergs_rcvd_from_w
  150. INTEGER :: ibergs_rcvd_from_n, ibergs_rcvd_from_s
  151. INTEGER :: i, ibergs_start, ibergs_end
  152. INTEGER :: iine, ijne
  153. INTEGER :: ipe_N, ipe_S, ipe_W, ipe_E
  154. REAL(wp), DIMENSION(2) :: zewbergs, zwebergs, znsbergs, zsnbergs
  155. INTEGER :: iml_req1, iml_req2, iml_req3, iml_req4
  156. INTEGER :: iml_req5, iml_req6, iml_req7, iml_req8, iml_err
  157. INTEGER, DIMENSION(MPI_STATUS_SIZE) :: iml_stat
  158. ! set up indices of neighbouring processors
  159. ipe_N = -1
  160. ipe_S = -1
  161. ipe_W = -1
  162. ipe_E = -1
  163. IF( nbondi .EQ. 0 .OR. nbondi .EQ. 1) ipe_W = nowe
  164. IF( nbondi .EQ. -1 .OR. nbondi .EQ. 0) ipe_E = noea
  165. IF( nbondj .EQ. 0 .OR. nbondj .EQ. 1) ipe_S = noso
  166. IF( nbondj .EQ. -1 .OR. nbondj .EQ. 0) ipe_N = nono
  167. !
  168. ! at northern line of processors with north fold handle bergs differently
  169. IF( npolj > 0 ) ipe_N = -1
  170. ! if there's only one processor in x direction then don't let mpp try to handle periodicity
  171. IF( jpni == 1 ) THEN
  172. ipe_E = -1
  173. ipe_W = -1
  174. ENDIF
  175. IF( nn_verbose_level >= 2 ) THEN
  176. WRITE(numicb,*) 'processor west : ', ipe_W
  177. WRITE(numicb,*) 'processor east : ', ipe_E
  178. WRITE(numicb,*) 'processor north : ', ipe_N
  179. WRITE(numicb,*) 'processor south : ', ipe_S
  180. WRITE(numicb,*) 'processor nimpp : ', nimpp
  181. WRITE(numicb,*) 'processor njmpp : ', njmpp
  182. WRITE(numicb,*) 'processor nbondi: ', nbondi
  183. WRITE(numicb,*) 'processor nbondj: ', nbondj
  184. CALL flush( numicb )
  185. ENDIF
  186. ! periodicity is handled here when using mpp when there is more than one processor in
  187. ! the i direction, but it also has to happen when jpni=1 case so this is dealt with
  188. ! in icb_lbc and called here
  189. IF( jpni == 1 ) CALL icb_lbc()
  190. ! Note that xi is adjusted when swapping because of periodic condition
  191. IF( nn_verbose_level > 0 ) THEN
  192. ! store the number of icebergs on this processor at start
  193. ibergs_start = icb_utl_count()
  194. ENDIF
  195. ibergs_to_send_e = 0
  196. ibergs_to_send_w = 0
  197. ibergs_to_send_n = 0
  198. ibergs_to_send_s = 0
  199. ibergs_rcvd_from_e = 0
  200. ibergs_rcvd_from_w = 0
  201. ibergs_rcvd_from_n = 0
  202. ibergs_rcvd_from_s = 0
  203. IF( ASSOCIATED(first_berg) ) THEN ! Find number of bergs that headed east/west
  204. this => first_berg
  205. DO WHILE (ASSOCIATED(this))
  206. pt => this%current_point
  207. iine = INT( pt%xi + 0.5 )
  208. IF( ipe_E >= 0 .AND. iine > mig(nicbei) ) THEN
  209. tmpberg => this
  210. this => this%next
  211. ibergs_to_send_e = ibergs_to_send_e + 1
  212. IF( nn_verbose_level >= 4 ) THEN
  213. WRITE(numicb,*) 'bergstep ',nktberg,' packing berg ',tmpberg%number(:),' for transfer to east'
  214. CALL flush( numicb )
  215. ENDIF
  216. ! deal with periodic case
  217. tmpberg%current_point%xi = ricb_right + MOD(tmpberg%current_point%xi, 1._wp ) - 1._wp
  218. ! now pack it into buffer and delete from list
  219. CALL icb_pack_into_buffer( tmpberg, obuffer_e, ibergs_to_send_e)
  220. CALL icb_utl_delete(first_berg, tmpberg)
  221. ELSE IF( ipe_W >= 0 .AND. iine < mig(nicbdi) ) THEN
  222. tmpberg => this
  223. this => this%next
  224. ibergs_to_send_w = ibergs_to_send_w + 1
  225. IF( nn_verbose_level >= 4 ) THEN
  226. WRITE(numicb,*) 'bergstep ',nktberg,' packing berg ',tmpberg%number(:),' for transfer to west'
  227. CALL flush( numicb )
  228. ENDIF
  229. ! deal with periodic case
  230. tmpberg%current_point%xi = ricb_left + MOD(tmpberg%current_point%xi, 1._wp )
  231. ! now pack it into buffer and delete from list
  232. CALL icb_pack_into_buffer( tmpberg, obuffer_w, ibergs_to_send_w)
  233. CALL icb_utl_delete(first_berg, tmpberg)
  234. ELSE
  235. this => this%next
  236. ENDIF
  237. END DO
  238. ENDIF
  239. IF( nn_verbose_level >= 3) THEN
  240. WRITE(numicb,*) 'bergstep ',nktberg,' send ew: ', ibergs_to_send_e, ibergs_to_send_w
  241. CALL flush(numicb)
  242. ENDIF
  243. ! send bergs east and receive bergs from west (ie ones that were sent east) and vice versa
  244. ! pattern here is copied from lib_mpp code
  245. SELECT CASE ( nbondi )
  246. CASE( -1 )
  247. zwebergs(1) = ibergs_to_send_e
  248. CALL mppsend( 12, zwebergs(1), 1, ipe_E, iml_req1)
  249. CALL mpprecv( 11, zewbergs(2), 1, ipe_E )
  250. IF( l_isend ) CALL mpi_wait( iml_req1, iml_stat, iml_err )
  251. ibergs_rcvd_from_e = INT( zewbergs(2) )
  252. CASE( 0 )
  253. zewbergs(1) = ibergs_to_send_w
  254. zwebergs(1) = ibergs_to_send_e
  255. CALL mppsend( 11, zewbergs(1), 1, ipe_W, iml_req2)
  256. CALL mppsend( 12, zwebergs(1), 1, ipe_E, iml_req3)
  257. CALL mpprecv( 11, zewbergs(2), 1, ipe_E )
  258. CALL mpprecv( 12, zwebergs(2), 1, ipe_W )
  259. IF( l_isend ) CALL mpi_wait( iml_req2, iml_stat, iml_err )
  260. IF( l_isend ) CALL mpi_wait( iml_req3, iml_stat, iml_err )
  261. ibergs_rcvd_from_e = INT( zewbergs(2) )
  262. ibergs_rcvd_from_w = INT( zwebergs(2) )
  263. CASE( 1 )
  264. zewbergs(1) = ibergs_to_send_w
  265. CALL mppsend( 11, zewbergs(1), 1, ipe_W, iml_req4)
  266. CALL mpprecv( 12, zwebergs(2), 1, ipe_W )
  267. IF( l_isend ) CALL mpi_wait( iml_req4, iml_stat, iml_err )
  268. ibergs_rcvd_from_w = INT( zwebergs(2) )
  269. END SELECT
  270. IF( nn_verbose_level >= 3) THEN
  271. WRITE(numicb,*) 'bergstep ',nktberg,' recv ew: ', ibergs_rcvd_from_w, ibergs_rcvd_from_e
  272. CALL flush(numicb)
  273. ENDIF
  274. SELECT CASE ( nbondi )
  275. CASE( -1 )
  276. IF( ibergs_to_send_e > 0 ) CALL mppsend( 14, obuffer_e%data, ibergs_to_send_e*jp_buffer_width, ipe_E, iml_req1 )
  277. IF( ibergs_rcvd_from_e > 0 ) THEN
  278. CALL icb_increase_ibuffer(ibuffer_e, ibergs_rcvd_from_e)
  279. CALL mpprecv( 13, ibuffer_e%data, ibergs_rcvd_from_e*jp_buffer_width )
  280. ENDIF
  281. IF( ibergs_to_send_e > 0 .AND. l_isend ) CALL mpi_wait( iml_req1, iml_stat, iml_err )
  282. DO i = 1, ibergs_rcvd_from_e
  283. IF( nn_verbose_level >= 4 ) THEN
  284. WRITE(numicb,*) 'bergstep ',nktberg,' unpacking berg ',INT(ibuffer_e%data(16,i)),' from east'
  285. CALL flush( numicb )
  286. ENDIF
  287. CALL icb_unpack_from_buffer(first_berg, ibuffer_e, i)
  288. ENDDO
  289. CASE( 0 )
  290. IF( ibergs_to_send_w > 0 ) CALL mppsend( 13, obuffer_w%data, ibergs_to_send_w*jp_buffer_width, ipe_W, iml_req2 )
  291. IF( ibergs_to_send_e > 0 ) CALL mppsend( 14, obuffer_e%data, ibergs_to_send_e*jp_buffer_width, ipe_E, iml_req3 )
  292. IF( ibergs_rcvd_from_e > 0 ) THEN
  293. CALL icb_increase_ibuffer(ibuffer_e, ibergs_rcvd_from_e)
  294. CALL mpprecv( 13, ibuffer_e%data, ibergs_rcvd_from_e*jp_buffer_width )
  295. ENDIF
  296. IF( ibergs_rcvd_from_w > 0 ) THEN
  297. CALL icb_increase_ibuffer(ibuffer_w, ibergs_rcvd_from_w)
  298. CALL mpprecv( 14, ibuffer_w%data, ibergs_rcvd_from_w*jp_buffer_width )
  299. ENDIF
  300. IF( ibergs_to_send_w > 0 .AND. l_isend ) CALL mpi_wait( iml_req2, iml_stat, iml_err )
  301. IF( ibergs_to_send_e > 0 .AND. l_isend ) CALL mpi_wait( iml_req3, iml_stat, iml_err )
  302. DO i = 1, ibergs_rcvd_from_e
  303. IF( nn_verbose_level >= 4 ) THEN
  304. WRITE(numicb,*) 'bergstep ',nktberg,' unpacking berg ',INT(ibuffer_e%data(16,i)),' from east'
  305. CALL flush( numicb )
  306. ENDIF
  307. CALL icb_unpack_from_buffer(first_berg, ibuffer_e, i)
  308. END DO
  309. DO i = 1, ibergs_rcvd_from_w
  310. IF( nn_verbose_level >= 4 ) THEN
  311. WRITE(numicb,*) 'bergstep ',nktberg,' unpacking berg ',INT(ibuffer_w%data(16,i)),' from west'
  312. CALL flush( numicb )
  313. ENDIF
  314. CALL icb_unpack_from_buffer(first_berg, ibuffer_w, i)
  315. ENDDO
  316. CASE( 1 )
  317. IF( ibergs_to_send_w > 0 ) CALL mppsend( 13, obuffer_w%data, ibergs_to_send_w*jp_buffer_width, ipe_W, iml_req4 )
  318. IF( ibergs_rcvd_from_w > 0 ) THEN
  319. CALL icb_increase_ibuffer(ibuffer_w, ibergs_rcvd_from_w)
  320. CALL mpprecv( 14, ibuffer_w%data, ibergs_rcvd_from_w*jp_buffer_width )
  321. ENDIF
  322. IF( ibergs_to_send_w > 0 .AND. l_isend ) CALL mpi_wait( iml_req4, iml_stat, iml_err )
  323. DO i = 1, ibergs_rcvd_from_w
  324. IF( nn_verbose_level >= 4 ) THEN
  325. WRITE(numicb,*) 'bergstep ',nktberg,' unpacking berg ',INT(ibuffer_w%data(16,i)),' from west'
  326. CALL flush( numicb )
  327. ENDIF
  328. CALL icb_unpack_from_buffer(first_berg, ibuffer_w, i)
  329. END DO
  330. END SELECT
  331. ! Find number of bergs that headed north/south
  332. ! (note: this block should technically go ahead of the E/W recv block above
  333. ! to handle arbitrary orientation of PEs. But for simplicity, it is
  334. ! here to accomodate diagonal transfer of bergs between PEs -AJA)
  335. IF( ASSOCIATED(first_berg) ) THEN
  336. this => first_berg
  337. DO WHILE (ASSOCIATED(this))
  338. pt => this%current_point
  339. ijne = INT( pt%yj + 0.5 )
  340. IF( ipe_N >= 0 .AND. ijne .GT. mjg(nicbej) ) THEN
  341. tmpberg => this
  342. this => this%next
  343. ibergs_to_send_n = ibergs_to_send_n + 1
  344. IF( nn_verbose_level >= 4 ) THEN
  345. WRITE(numicb,*) 'bergstep ',nktberg,' packing berg ',tmpberg%number(:),' for transfer to north'
  346. CALL flush( numicb )
  347. ENDIF
  348. CALL icb_pack_into_buffer( tmpberg, obuffer_n, ibergs_to_send_n)
  349. CALL icb_utl_delete(first_berg, tmpberg)
  350. ELSE IF( ipe_S >= 0 .AND. ijne .LT. mjg(nicbdj) ) THEN
  351. tmpberg => this
  352. this => this%next
  353. ibergs_to_send_s = ibergs_to_send_s + 1
  354. IF( nn_verbose_level >= 4 ) THEN
  355. WRITE(numicb,*) 'bergstep ',nktberg,' packing berg ',tmpberg%number(:),' for transfer to south'
  356. CALL flush( numicb )
  357. ENDIF
  358. CALL icb_pack_into_buffer( tmpberg, obuffer_s, ibergs_to_send_s)
  359. CALL icb_utl_delete(first_berg, tmpberg)
  360. ELSE
  361. this => this%next
  362. ENDIF
  363. END DO
  364. ENDIF
  365. if( nn_verbose_level >= 3) then
  366. write(numicb,*) 'bergstep ',nktberg,' send ns: ', ibergs_to_send_n, ibergs_to_send_s
  367. call flush(numicb)
  368. endif
  369. ! send bergs north
  370. ! and receive bergs from south (ie ones sent north)
  371. SELECT CASE ( nbondj )
  372. CASE( -1 )
  373. zsnbergs(1) = ibergs_to_send_n
  374. CALL mppsend( 16, zsnbergs(1), 1, ipe_N, iml_req1)
  375. CALL mpprecv( 15, znsbergs(2), 1, ipe_N )
  376. IF( l_isend ) CALL mpi_wait( iml_req1, iml_stat, iml_err )
  377. ibergs_rcvd_from_n = INT( znsbergs(2) )
  378. CASE( 0 )
  379. znsbergs(1) = ibergs_to_send_s
  380. zsnbergs(1) = ibergs_to_send_n
  381. CALL mppsend( 15, znsbergs(1), 1, ipe_S, iml_req2)
  382. CALL mppsend( 16, zsnbergs(1), 1, ipe_N, iml_req3)
  383. CALL mpprecv( 15, znsbergs(2), 1, ipe_N )
  384. CALL mpprecv( 16, zsnbergs(2), 1, ipe_S )
  385. IF( l_isend ) CALL mpi_wait( iml_req2, iml_stat, iml_err )
  386. IF( l_isend ) CALL mpi_wait( iml_req3, iml_stat, iml_err )
  387. ibergs_rcvd_from_n = INT( znsbergs(2) )
  388. ibergs_rcvd_from_s = INT( zsnbergs(2) )
  389. CASE( 1 )
  390. znsbergs(1) = ibergs_to_send_s
  391. CALL mppsend( 15, znsbergs(1), 1, ipe_S, iml_req4)
  392. CALL mpprecv( 16, zsnbergs(2), 1, ipe_S )
  393. IF( l_isend ) CALL mpi_wait( iml_req4, iml_stat, iml_err )
  394. ibergs_rcvd_from_s = INT( zsnbergs(2) )
  395. END SELECT
  396. if( nn_verbose_level >= 3) then
  397. write(numicb,*) 'bergstep ',nktberg,' recv ns: ', ibergs_rcvd_from_s, ibergs_rcvd_from_n
  398. call flush(numicb)
  399. endif
  400. SELECT CASE ( nbondj )
  401. CASE( -1 )
  402. IF( ibergs_to_send_n > 0 ) CALL mppsend( 18, obuffer_n%data, ibergs_to_send_n*jp_buffer_width, ipe_N, iml_req1 )
  403. IF( ibergs_rcvd_from_n > 0 ) THEN
  404. CALL icb_increase_ibuffer(ibuffer_n, ibergs_rcvd_from_n)
  405. CALL mpprecv( 17, ibuffer_n%data, ibergs_rcvd_from_n*jp_buffer_width )
  406. ENDIF
  407. IF( ibergs_to_send_n > 0 .AND. l_isend ) CALL mpi_wait( iml_req1, iml_stat, iml_err )
  408. DO i = 1, ibergs_rcvd_from_n
  409. IF( nn_verbose_level >= 4 ) THEN
  410. WRITE(numicb,*) 'bergstep ',nktberg,' unpacking berg ',INT(ibuffer_n%data(16,i)),' from north'
  411. CALL flush( numicb )
  412. ENDIF
  413. CALL icb_unpack_from_buffer(first_berg, ibuffer_n, i)
  414. END DO
  415. CASE( 0 )
  416. IF( ibergs_to_send_s > 0 ) CALL mppsend( 17, obuffer_s%data, ibergs_to_send_s*jp_buffer_width, ipe_S, iml_req2 )
  417. IF( ibergs_to_send_n > 0 ) CALL mppsend( 18, obuffer_n%data, ibergs_to_send_n*jp_buffer_width, ipe_N, iml_req3 )
  418. IF( ibergs_rcvd_from_n > 0 ) THEN
  419. CALL icb_increase_ibuffer(ibuffer_n, ibergs_rcvd_from_n)
  420. CALL mpprecv( 17, ibuffer_n%data, ibergs_rcvd_from_n*jp_buffer_width )
  421. ENDIF
  422. IF( ibergs_rcvd_from_s > 0 ) THEN
  423. CALL icb_increase_ibuffer(ibuffer_s, ibergs_rcvd_from_s)
  424. CALL mpprecv( 18, ibuffer_s%data, ibergs_rcvd_from_s*jp_buffer_width )
  425. ENDIF
  426. IF( ibergs_to_send_s > 0 .AND. l_isend ) CALL mpi_wait( iml_req2, iml_stat, iml_err )
  427. IF( ibergs_to_send_n > 0 .AND. l_isend ) CALL mpi_wait( iml_req3, iml_stat, iml_err )
  428. DO i = 1, ibergs_rcvd_from_n
  429. IF( nn_verbose_level >= 4 ) THEN
  430. WRITE(numicb,*) 'bergstep ',nktberg,' unpacking berg ',INT(ibuffer_n%data(16,i)),' from north'
  431. CALL flush( numicb )
  432. ENDIF
  433. CALL icb_unpack_from_buffer(first_berg, ibuffer_n, i)
  434. END DO
  435. DO i = 1, ibergs_rcvd_from_s
  436. IF( nn_verbose_level >= 4 ) THEN
  437. WRITE(numicb,*) 'bergstep ',nktberg,' unpacking berg ',INT(ibuffer_s%data(16,i)),' from south'
  438. CALL flush( numicb )
  439. ENDIF
  440. CALL icb_unpack_from_buffer(first_berg, ibuffer_s, i)
  441. ENDDO
  442. CASE( 1 )
  443. IF( ibergs_to_send_s > 0 ) CALL mppsend( 17, obuffer_s%data, ibergs_to_send_s*jp_buffer_width, ipe_S, iml_req4 )
  444. IF( ibergs_rcvd_from_s > 0 ) THEN
  445. CALL icb_increase_ibuffer(ibuffer_s, ibergs_rcvd_from_s)
  446. CALL mpprecv( 18, ibuffer_s%data, ibergs_rcvd_from_s*jp_buffer_width )
  447. ENDIF
  448. IF( ibergs_to_send_s > 0 .AND. l_isend ) CALL mpi_wait( iml_req4, iml_stat, iml_err )
  449. DO i = 1, ibergs_rcvd_from_s
  450. IF( nn_verbose_level >= 4 ) THEN
  451. WRITE(numicb,*) 'bergstep ',nktberg,' unpacking berg ',INT(ibuffer_s%data(16,i)),' from south'
  452. CALL flush( numicb )
  453. ENDIF
  454. CALL icb_unpack_from_buffer(first_berg, ibuffer_s, i)
  455. END DO
  456. END SELECT
  457. IF( nn_verbose_level > 0 ) THEN
  458. ! compare the number of icebergs on this processor from the start to the end
  459. ibergs_end = icb_utl_count()
  460. i = ( ibergs_rcvd_from_n + ibergs_rcvd_from_s + ibergs_rcvd_from_e + ibergs_rcvd_from_w ) - &
  461. ( ibergs_to_send_n + ibergs_to_send_s + ibergs_to_send_e + ibergs_to_send_w )
  462. IF( ibergs_end-(ibergs_start+i) .NE. 0 ) THEN
  463. WRITE( numicb,* ) 'send_bergs_to_other_pes: net change in number of icebergs'
  464. WRITE( numicb,1000) 'send_bergs_to_other_pes: ibergs_end=', &
  465. ibergs_end,' on PE',narea
  466. WRITE( numicb,1000) 'send_bergs_to_other_pes: ibergs_start=', &
  467. ibergs_start,' on PE',narea
  468. WRITE( numicb,1000) 'send_bergs_to_other_pes: delta=', &
  469. i,' on PE',narea
  470. WRITE( numicb,1000) 'send_bergs_to_other_pes: error=', &
  471. ibergs_end-(ibergs_start+i),' on PE',narea
  472. WRITE( numicb,1000) 'send_bergs_to_other_pes: ibergs_to_send_n=', &
  473. ibergs_to_send_n,' on PE',narea
  474. WRITE( numicb,1000) 'send_bergs_to_other_pes: ibergs_to_send_s=', &
  475. ibergs_to_send_s,' on PE',narea
  476. WRITE( numicb,1000) 'send_bergs_to_other_pes: ibergs_to_send_e=', &
  477. ibergs_to_send_e,' on PE',narea
  478. WRITE( numicb,1000) 'send_bergs_to_other_pes: ibergs_to_send_w=', &
  479. ibergs_to_send_w,' on PE',narea
  480. WRITE( numicb,1000) 'send_bergs_to_other_pes: ibergs_rcvd_from_n=', &
  481. ibergs_rcvd_from_n,' on PE',narea
  482. WRITE( numicb,1000) 'send_bergs_to_other_pes: ibergs_rcvd_from_s=', &
  483. ibergs_rcvd_from_s,' on PE',narea
  484. WRITE( numicb,1000) 'send_bergs_to_other_pes: ibergs_rcvd_from_e=', &
  485. ibergs_rcvd_from_e,' on PE',narea
  486. WRITE( numicb,1000) 'send_bergs_to_other_pes: ibergs_rcvd_from_w=', &
  487. ibergs_rcvd_from_w,' on PE',narea
  488. 1000 FORMAT(a,i5,a,i4)
  489. CALL ctl_stop('send_bergs_to_other_pes: lost or gained an iceberg or two')
  490. ENDIF
  491. ENDIF
  492. ! deal with north fold if we necessary when there is more than one top row processor
  493. ! note that for jpni=1 north fold has been dealt with above in call to icb_lbc
  494. IF( npolj /= 0 .AND. jpni > 1 ) CALL icb_lbc_mpp_nfld( )
  495. IF( nn_verbose_level > 0 ) THEN
  496. i = 0
  497. this => first_berg
  498. DO WHILE (ASSOCIATED(this))
  499. pt => this%current_point
  500. iine = INT( pt%xi + 0.5 )
  501. ijne = INT( pt%yj + 0.5 )
  502. IF( iine .LT. mig(nicbdi) .OR. &
  503. iine .GT. mig(nicbei) .OR. &
  504. ijne .LT. mjg(nicbdj) .OR. &
  505. ijne .GT. mjg(nicbej)) THEN
  506. i = i + 1
  507. WRITE(numicb,*) 'berg lost in halo: ', this%number(:),iine,ijne
  508. WRITE(numicb,*) ' ', nimpp, njmpp
  509. WRITE(numicb,*) ' ', nicbdi, nicbei, nicbdj, nicbej
  510. CALL flush( numicb )
  511. ENDIF
  512. this => this%next
  513. ENDDO ! WHILE
  514. CALL mpp_sum(i)
  515. IF( i .GT. 0 ) THEN
  516. WRITE( numicb,'(a,i4)') 'send_bergs_to_other_pes: # of bergs outside computational domain = ',i
  517. CALL ctl_stop('send_bergs_to_other_pes: there are bergs still in halos!')
  518. ENDIF ! root_pe
  519. ENDIF ! debug
  520. !
  521. CALL mppsync()
  522. !
  523. END SUBROUTINE icb_lbc_mpp
  524. SUBROUTINE icb_lbc_mpp_nfld()
  525. !!----------------------------------------------------------------------
  526. !! *** SUBROUTINE icb_lbc_mpp_nfld ***
  527. !!
  528. !! ** Purpose : north fold treatment in multi processor exchange
  529. !!
  530. !! ** Method :
  531. !!----------------------------------------------------------------------
  532. TYPE(iceberg) , POINTER :: tmpberg, this
  533. TYPE(point) , POINTER :: pt
  534. INTEGER :: ibergs_to_send
  535. INTEGER :: ibergs_to_rcv
  536. INTEGER :: iiglo, ijglo, jk, jn
  537. INTEGER :: ifldproc, iproc, ipts
  538. INTEGER :: iine, ijne
  539. INTEGER :: jjn
  540. REAL(wp), DIMENSION(0:3) :: zsbergs, znbergs
  541. INTEGER :: iml_req1, iml_req2, iml_err
  542. INTEGER, DIMENSION(MPI_STATUS_SIZE) :: iml_stat
  543. ! set up indices of neighbouring processors
  544. ! nicbfldproc is a list of unique processor numbers that this processor
  545. ! exchanges with (including itself), so we loop over this array; since
  546. ! its of fixed size, the first -1 marks end of list of processors
  547. !
  548. nicbfldnsend(:) = 0
  549. nicbfldexpect(:) = 0
  550. nicbfldreq(:) = 0
  551. !
  552. ! Since each processor may be communicating with more than one northern
  553. ! neighbour, cycle through the sends so that the receive order can be
  554. ! controlled.
  555. !
  556. ! First compute how many icebergs each active neighbour should expect
  557. DO jn = 1, jpni
  558. IF( nicbfldproc(jn) /= -1 ) THEN
  559. ifldproc = nicbfldproc(jn)
  560. nicbfldnsend(jn) = 0
  561. ! Find number of bergs that need to be exchanged
  562. ! Pick out exchanges with processor ifldproc
  563. ! if ifldproc is this processor then don't send
  564. !
  565. IF( ASSOCIATED(first_berg) ) THEN
  566. this => first_berg
  567. DO WHILE (ASSOCIATED(this))
  568. pt => this%current_point
  569. iine = INT( pt%xi + 0.5 )
  570. ijne = INT( pt%yj + 0.5 )
  571. iproc = nicbflddest(mi1(iine))
  572. IF( ijne .GT. mjg(nicbej) ) THEN
  573. IF( iproc == ifldproc ) THEN
  574. !
  575. IF( iproc /= narea ) THEN
  576. tmpberg => this
  577. nicbfldnsend(jn) = nicbfldnsend(jn) + 1
  578. ENDIF
  579. !
  580. ENDIF
  581. ENDIF
  582. this => this%next
  583. END DO
  584. ENDIF
  585. !
  586. ENDIF
  587. !
  588. END DO
  589. !
  590. ! Now tell each active neighbour how many icebergs to expect
  591. DO jn = 1, jpni
  592. IF( nicbfldproc(jn) /= -1 ) THEN
  593. ifldproc = nicbfldproc(jn)
  594. IF( ifldproc == narea ) CYCLE
  595. zsbergs(0) = narea
  596. zsbergs(1) = nicbfldnsend(jn)
  597. !IF ( nicbfldnsend(jn) .GT. 0) write(numicb,*) 'ICB sending ',nicbfldnsend(jn),' to ', ifldproc
  598. CALL mppsend( 21, zsbergs(0:1), 2, ifldproc-1, nicbfldreq(jn))
  599. ENDIF
  600. !
  601. END DO
  602. !
  603. ! and receive the heads-up from active neighbours preparing to send
  604. DO jn = 1, jpni
  605. IF( nicbfldproc(jn) /= -1 ) THEN
  606. ifldproc = nicbfldproc(jn)
  607. IF( ifldproc == narea ) CYCLE
  608. CALL mpprecv( 21, znbergs(1:2), 2 )
  609. DO jjn = 1,jpni
  610. IF( nicbfldproc(jjn) .eq. INT(znbergs(1)) ) EXIT
  611. END DO
  612. IF( jjn .GT. jpni ) write(numicb,*) 'ICB ERROR'
  613. nicbfldexpect(jjn) = INT( znbergs(2) )
  614. !IF ( nicbfldexpect(jjn) .GT. 0) write(numicb,*) 'ICB expecting ',nicbfldexpect(jjn),' from ', nicbfldproc(jjn)
  615. !CALL FLUSH(numicb)
  616. ENDIF
  617. !
  618. END DO
  619. !
  620. ! post the mpi waits if using immediate send protocol
  621. DO jn = 1, jpni
  622. IF( nicbfldproc(jn) /= -1 ) THEN
  623. ifldproc = nicbfldproc(jn)
  624. IF( ifldproc == narea ) CYCLE
  625. IF( l_isend ) CALL mpi_wait( nicbfldreq(jn), iml_stat, iml_err )
  626. ENDIF
  627. !
  628. END DO
  629. !
  630. ! Cycle through the icebergs again, this time packing and sending any
  631. ! going through the north fold. They will be expected.
  632. DO jn = 1, jpni
  633. IF( nicbfldproc(jn) /= -1 ) THEN
  634. ifldproc = nicbfldproc(jn)
  635. ibergs_to_send = 0
  636. ! Find number of bergs that need to be exchanged
  637. ! Pick out exchanges with processor ifldproc
  638. ! if ifldproc is this processor then don't send
  639. !
  640. IF( ASSOCIATED(first_berg) ) THEN
  641. this => first_berg
  642. DO WHILE (ASSOCIATED(this))
  643. pt => this%current_point
  644. iine = INT( pt%xi + 0.5 )
  645. ijne = INT( pt%yj + 0.5 )
  646. ipts = nicbfldpts (mi1(iine))
  647. iproc = nicbflddest(mi1(iine))
  648. IF( ijne .GT. mjg(nicbej) ) THEN
  649. IF( iproc == ifldproc ) THEN
  650. !
  651. ! moving across the cut line means both position and
  652. ! velocity must change
  653. ijglo = INT( ipts/nicbpack )
  654. iiglo = ipts - nicbpack*ijglo
  655. pt%xi = iiglo - ( pt%xi - REAL(iine,wp) )
  656. pt%yj = ijglo - ( pt%yj - REAL(ijne,wp) )
  657. pt%uvel = -1._wp * pt%uvel
  658. pt%vvel = -1._wp * pt%vvel
  659. !
  660. ! now remove berg from list and pack it into a buffer
  661. IF( iproc /= narea ) THEN
  662. tmpberg => this
  663. ibergs_to_send = ibergs_to_send + 1
  664. IF( nn_verbose_level >= 4 ) THEN
  665. WRITE(numicb,*) 'bergstep ',nktberg,' packing berg ',tmpberg%number(:),' for north fold'
  666. CALL flush( numicb )
  667. ENDIF
  668. CALL icb_pack_into_buffer( tmpberg, obuffer_f, ibergs_to_send)
  669. CALL icb_utl_delete(first_berg, tmpberg)
  670. ENDIF
  671. !
  672. ENDIF
  673. ENDIF
  674. this => this%next
  675. END DO
  676. ENDIF
  677. if( nn_verbose_level >= 3) then
  678. write(numicb,*) 'bergstep ',nktberg,' send nfld: ', ibergs_to_send
  679. call flush(numicb)
  680. endif
  681. !
  682. ! if we're in this processor, then we've done everything we need to
  683. ! so go on to next element of loop
  684. IF( ifldproc == narea ) CYCLE
  685. ! send bergs
  686. IF( ibergs_to_send > 0 ) &
  687. CALL mppsend( 12, obuffer_f%data, ibergs_to_send*jp_buffer_width, ifldproc-1, nicbfldreq(jn) )
  688. !
  689. ENDIF
  690. !
  691. END DO
  692. !
  693. ! Now receive the expected number of bergs from the active neighbours
  694. DO jn = 1, jpni
  695. IF( nicbfldproc(jn) /= -1 ) THEN
  696. ifldproc = nicbfldproc(jn)
  697. IF( ifldproc == narea ) CYCLE
  698. ibergs_to_rcv = nicbfldexpect(jn)
  699. IF( ibergs_to_rcv > 0 ) THEN
  700. CALL icb_increase_ibuffer(ibuffer_f, ibergs_to_rcv)
  701. CALL mpprecv( 12, ibuffer_f%data, ibergs_to_rcv*jp_buffer_width, ifldproc-1 )
  702. ENDIF
  703. !
  704. DO jk = 1, ibergs_to_rcv
  705. IF( nn_verbose_level >= 4 ) THEN
  706. WRITE(numicb,*) 'bergstep ',nktberg,' unpacking berg ',INT(ibuffer_f%data(16,jk)),' from north fold'
  707. CALL flush( numicb )
  708. ENDIF
  709. CALL icb_unpack_from_buffer(first_berg, ibuffer_f, jk )
  710. END DO
  711. ENDIF
  712. !
  713. END DO
  714. !
  715. ! Finally post the mpi waits if using immediate send protocol
  716. DO jn = 1, jpni
  717. IF( nicbfldproc(jn) /= -1 ) THEN
  718. ifldproc = nicbfldproc(jn)
  719. IF( ifldproc == narea ) CYCLE
  720. IF( l_isend ) CALL mpi_wait( nicbfldreq(jn), iml_stat, iml_err )
  721. ENDIF
  722. !
  723. END DO
  724. !
  725. END SUBROUTINE icb_lbc_mpp_nfld
  726. SUBROUTINE icb_pack_into_buffer( berg, pbuff, kb )
  727. !!----------------------------------------------------------------------
  728. !!----------------------------------------------------------------------
  729. TYPE(iceberg), POINTER :: berg
  730. TYPE(buffer) , POINTER :: pbuff
  731. INTEGER , INTENT(in) :: kb
  732. !
  733. INTEGER :: k ! local integer
  734. !!----------------------------------------------------------------------
  735. !
  736. IF( .NOT. ASSOCIATED(pbuff) ) CALL icb_increase_buffer( pbuff, jp_delta_buf )
  737. IF( kb .GT. pbuff%size ) CALL icb_increase_buffer( pbuff, jp_delta_buf )
  738. !! pack points into buffer
  739. pbuff%data( 1,kb) = berg%current_point%lon
  740. pbuff%data( 2,kb) = berg%current_point%lat
  741. pbuff%data( 3,kb) = berg%current_point%uvel
  742. pbuff%data( 4,kb) = berg%current_point%vvel
  743. pbuff%data( 5,kb) = berg%current_point%xi
  744. pbuff%data( 6,kb) = berg%current_point%yj
  745. pbuff%data( 7,kb) = float(berg%current_point%year)
  746. pbuff%data( 8,kb) = berg%current_point%day
  747. pbuff%data( 9,kb) = berg%current_point%mass
  748. pbuff%data(10,kb) = berg%current_point%thickness
  749. pbuff%data(11,kb) = berg%current_point%width
  750. pbuff%data(12,kb) = berg%current_point%length
  751. pbuff%data(13,kb) = berg%current_point%mass_of_bits
  752. pbuff%data(14,kb) = berg%current_point%heat_density
  753. pbuff%data(15,kb) = berg%mass_scaling
  754. DO k=1,nkounts
  755. pbuff%data(15+k,kb) = REAL( berg%number(k), wp )
  756. END DO
  757. !
  758. END SUBROUTINE icb_pack_into_buffer
  759. SUBROUTINE icb_unpack_from_buffer(first, pbuff, kb)
  760. !!----------------------------------------------------------------------
  761. !!----------------------------------------------------------------------
  762. TYPE(iceberg), POINTER :: first
  763. TYPE(buffer) , POINTER :: pbuff
  764. INTEGER , INTENT(in) :: kb
  765. !
  766. TYPE(iceberg) :: currentberg
  767. TYPE(point) :: pt
  768. INTEGER :: ik
  769. !!----------------------------------------------------------------------
  770. !
  771. pt%lon = pbuff%data( 1,kb)
  772. pt%lat = pbuff%data( 2,kb)
  773. pt%uvel = pbuff%data( 3,kb)
  774. pt%vvel = pbuff%data( 4,kb)
  775. pt%xi = pbuff%data( 5,kb)
  776. pt%yj = pbuff%data( 6,kb)
  777. pt%year = INT( pbuff%data( 7,kb) )
  778. pt%day = pbuff%data( 8,kb)
  779. pt%mass = pbuff%data( 9,kb)
  780. pt%thickness = pbuff%data(10,kb)
  781. pt%width = pbuff%data(11,kb)
  782. pt%length = pbuff%data(12,kb)
  783. pt%mass_of_bits = pbuff%data(13,kb)
  784. pt%heat_density = pbuff%data(14,kb)
  785. currentberg%mass_scaling = pbuff%data(15,kb)
  786. DO ik = 1, nkounts
  787. currentberg%number(ik) = INT( pbuff%data(15+ik,kb) )
  788. END DO
  789. !
  790. CALL icb_utl_add(currentberg, pt )
  791. !
  792. END SUBROUTINE icb_unpack_from_buffer
  793. SUBROUTINE icb_increase_buffer(old,kdelta)
  794. !!----------------------------------------------------------------------
  795. TYPE(buffer), POINTER :: old
  796. INTEGER , INTENT(in) :: kdelta
  797. !
  798. TYPE(buffer), POINTER :: new
  799. INTEGER :: inew_size
  800. !!----------------------------------------------------------------------
  801. !
  802. IF( .NOT. ASSOCIATED(old) ) THEN ; inew_size = kdelta
  803. ELSE ; inew_size = old%size + kdelta
  804. ENDIF
  805. ALLOCATE( new )
  806. ALLOCATE( new%data( jp_buffer_width, inew_size) )
  807. new%size = inew_size
  808. IF( ASSOCIATED(old) ) THEN
  809. new%data(:,1:old%size) = old%data(:,1:old%size)
  810. DEALLOCATE(old%data)
  811. DEALLOCATE(old)
  812. ENDIF
  813. old => new
  814. !
  815. END SUBROUTINE icb_increase_buffer
  816. SUBROUTINE icb_increase_ibuffer(old,kdelta)
  817. !!----------------------------------------------------------------------
  818. !!----------------------------------------------------------------------
  819. TYPE(buffer), POINTER :: old
  820. INTEGER , INTENT(in) :: kdelta
  821. !
  822. TYPE(buffer), POINTER :: new
  823. INTEGER :: inew_size, iold_size
  824. !!----------------------------------------------------------------------
  825. IF( .NOT. ASSOCIATED(old) ) THEN
  826. inew_size = kdelta + jp_delta_buf
  827. iold_size = 0
  828. ELSE
  829. iold_size = old%size
  830. IF( kdelta .LT. old%size ) THEN
  831. inew_size = old%size + kdelta
  832. ELSE
  833. inew_size = kdelta + jp_delta_buf
  834. ENDIF
  835. ENDIF
  836. IF( iold_size .NE. inew_size ) THEN
  837. ALLOCATE( new )
  838. ALLOCATE( new%data( jp_buffer_width, inew_size) )
  839. new%size = inew_size
  840. IF( ASSOCIATED(old) ) THEN
  841. new%data(:,1:old%size) = old%data(:,1:old%size)
  842. DEALLOCATE(old%data)
  843. DEALLOCATE(old)
  844. ENDIF
  845. old => new
  846. !WRITE( numicb,*) 'icb_increase_ibuffer',narea,' increased to',inew_size
  847. ENDIF
  848. !
  849. END SUBROUTINE icb_increase_ibuffer
  850. #else
  851. !!----------------------------------------------------------------------
  852. !! Default case: Dummy module share memory computing
  853. !!----------------------------------------------------------------------
  854. SUBROUTINE icb_lbc_mpp()
  855. WRITE(numout,*) 'icb_lbc_mpp: You should not have seen this message!!'
  856. END SUBROUTINE icb_lbc_mpp
  857. #endif
  858. !!======================================================================
  859. END MODULE icblbc