dommsk.F90 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705
  1. MODULE dommsk
  2. !!======================================================================
  3. !! *** MODULE dommsk ***
  4. !! Ocean initialization : domain land/sea mask
  5. !!======================================================================
  6. !! History : OPA ! 1987-07 (G. Madec) Original code
  7. !! 6.0 ! 1993-03 (M. Guyon) symetrical conditions (M. Guyon)
  8. !! 7.0 ! 1996-01 (G. Madec) suppression of common work arrays
  9. !! - ! 1996-05 (G. Madec) mask computed from tmask and sup-
  10. !! ! pression of the double computation of bmask
  11. !! 8.0 ! 1997-02 (G. Madec) mesh information put in domhgr.F
  12. !! 8.1 ! 1997-07 (G. Madec) modification of mbathy and fmask
  13. !! - ! 1998-05 (G. Roullet) free surface
  14. !! 8.2 ! 2000-03 (G. Madec) no slip accurate
  15. !! - ! 2001-09 (J.-M. Molines) Open boundaries
  16. !! NEMO 1.0 ! 2002-08 (G. Madec) F90: Free form and module
  17. !! - ! 2005-11 (V. Garnier) Surface pressure gradient organization
  18. !! 3.2 ! 2009-07 (R. Benshila) Suppression of rigid-lid option
  19. !!----------------------------------------------------------------------
  20. !!----------------------------------------------------------------------
  21. !! dom_msk : compute land/ocean mask
  22. !! dom_msk_nsa : update land/ocean mask when no-slip accurate option is used.
  23. !!----------------------------------------------------------------------
  24. USE oce ! ocean dynamics and tracers
  25. USE dom_oce ! ocean space and time domain
  26. USE in_out_manager ! I/O manager
  27. USE lbclnk ! ocean lateral boundary conditions (or mpp link)
  28. USE lib_mpp
  29. USE dynspg_oce ! choice/control of key cpp for surface pressure gradient
  30. USE wrk_nemo ! Memory allocation
  31. USE timing ! Timing
  32. IMPLICIT NONE
  33. PRIVATE
  34. PUBLIC dom_msk ! routine called by inidom.F90
  35. PUBLIC dom_msk_alloc ! routine called by nemogcm.F90
  36. ! !!* Namelist namlbc : lateral boundary condition *
  37. REAL(wp) :: rn_shlat ! type of lateral boundary condition on velocity
  38. LOGICAL, PUBLIC :: ln_vorlat ! consistency of vorticity boundary condition
  39. ! with analytical eqs.
  40. INTEGER, ALLOCATABLE, SAVE, DIMENSION(:,:) :: icoord ! Workspace for dom_msk_nsa()
  41. !! * Substitutions
  42. # include "vectopt_loop_substitute.h90"
  43. !!----------------------------------------------------------------------
  44. !! NEMO/OPA 3.2 , LODYC-IPSL (2009)
  45. !! $Id: dommsk.F90 5551 2015-07-06 16:38:51Z acc $
  46. !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
  47. !!----------------------------------------------------------------------
  48. CONTAINS
  49. INTEGER FUNCTION dom_msk_alloc()
  50. !!---------------------------------------------------------------------
  51. !! *** FUNCTION dom_msk_alloc ***
  52. !!---------------------------------------------------------------------
  53. dom_msk_alloc = 0
  54. #if defined key_noslip_accurate
  55. ALLOCATE(icoord(jpi*jpj*jpk,3), STAT=dom_msk_alloc)
  56. #endif
  57. IF( dom_msk_alloc /= 0 ) CALL ctl_warn('dom_msk_alloc: failed to allocate icoord array')
  58. !
  59. END FUNCTION dom_msk_alloc
  60. SUBROUTINE dom_msk
  61. !!---------------------------------------------------------------------
  62. !! *** ROUTINE dom_msk ***
  63. !!
  64. !! ** Purpose : Compute land/ocean mask arrays at tracer points, hori-
  65. !! zontal velocity points (u & v), vorticity points (f) and baro-
  66. !! tropic stream function points (b).
  67. !!
  68. !! ** Method : The ocean/land mask is computed from the basin bathy-
  69. !! metry in level (mbathy) which is defined or read in dommba.
  70. !! mbathy equals 0 over continental T-point
  71. !! and the number of ocean level over the ocean.
  72. !!
  73. !! At a given position (ji,jj,jk) the ocean/land mask is given by:
  74. !! t-point : 0. IF mbathy( ji ,jj) =< 0
  75. !! 1. IF mbathy( ji ,jj) >= jk
  76. !! u-point : 0. IF mbathy( ji ,jj) or mbathy(ji+1, jj ) =< 0
  77. !! 1. IF mbathy( ji ,jj) and mbathy(ji+1, jj ) >= jk.
  78. !! v-point : 0. IF mbathy( ji ,jj) or mbathy( ji ,jj+1) =< 0
  79. !! 1. IF mbathy( ji ,jj) and mbathy( ji ,jj+1) >= jk.
  80. !! f-point : 0. IF mbathy( ji ,jj) or mbathy( ji ,jj+1)
  81. !! or mbathy(ji+1,jj) or mbathy(ji+1,jj+1) =< 0
  82. !! 1. IF mbathy( ji ,jj) and mbathy( ji ,jj+1)
  83. !! and mbathy(ji+1,jj) and mbathy(ji+1,jj+1) >= jk.
  84. !! b-point : the same definition as for f-point of the first ocean
  85. !! level (surface level) but with 0 along coastlines.
  86. !! tmask_i : interior ocean mask at t-point, i.e. excluding duplicated
  87. !! rows/lines due to cyclic or North Fold boundaries as well
  88. !! as MPP halos.
  89. !!
  90. !! The lateral friction is set through the value of fmask along
  91. !! the coast and topography. This value is defined by rn_shlat, a
  92. !! namelist parameter:
  93. !! rn_shlat = 0, free slip (no shear along the coast)
  94. !! rn_shlat = 2, no slip (specified zero velocity at the coast)
  95. !! 0 < rn_shlat < 2, partial slip | non-linear velocity profile
  96. !! 2 < rn_shlat, strong slip | in the lateral boundary layer
  97. !!
  98. !! N.B. If nperio not equal to 0, the land/ocean mask arrays
  99. !! are defined with the proper value at lateral domain boundaries,
  100. !! but bmask. indeed, bmask defined the domain over which the
  101. !! barotropic stream function is computed. this domain cannot
  102. !! contain identical columns because the matrix associated with
  103. !! the barotropic stream function equation is then no more inverti-
  104. !! ble. therefore bmask is set to 0 along lateral domain boundaries
  105. !! even IF nperio is not zero.
  106. !!
  107. !! In case of open boundaries (lk_bdy=T):
  108. !! - tmask is set to 1 on the points to be computed bay the open
  109. !! boundaries routines.
  110. !! - bmask is set to 0 on the open boundaries.
  111. !!
  112. !! ** Action : tmask : land/ocean mask at t-point (=0. or 1.)
  113. !! umask : land/ocean mask at u-point (=0. or 1.)
  114. !! vmask : land/ocean mask at v-point (=0. or 1.)
  115. !! fmask : land/ocean mask at f-point (=0. or 1.)
  116. !! =rn_shlat along lateral boundaries
  117. !! bmask : land/ocean mask at barotropic stream
  118. !! function point (=0. or 1.) and set to 0 along lateral boundaries
  119. !! tmask_i : interior ocean mask
  120. !!----------------------------------------------------------------------
  121. !
  122. INTEGER :: ji, jj, jk ! dummy loop indices
  123. INTEGER :: iif, iil, ii0, ii1, ii ! local integers
  124. INTEGER :: ijf, ijl, ij0, ij1 ! - -
  125. INTEGER :: ios
  126. INTEGER :: isrow ! index for ORCA1 starting row
  127. INTEGER , POINTER, DIMENSION(:,:) :: imsk
  128. REAL(wp), POINTER, DIMENSION(:,:) :: zwf
  129. !!
  130. NAMELIST/namlbc/ rn_shlat, ln_vorlat
  131. !!---------------------------------------------------------------------
  132. !
  133. IF( nn_timing == 1 ) CALL timing_start('dom_msk')
  134. !
  135. CALL wrk_alloc( jpi, jpj, imsk )
  136. CALL wrk_alloc( jpi, jpj, zwf )
  137. !
  138. REWIND( numnam_ref ) ! Namelist namlbc in reference namelist : Lateral momentum boundary condition
  139. READ ( numnam_ref, namlbc, IOSTAT = ios, ERR = 901 )
  140. 901 IF( ios /= 0 ) CALL ctl_nam ( ios , 'namlbc in reference namelist', lwp )
  141. REWIND( numnam_cfg ) ! Namelist namlbc in configuration namelist : Lateral momentum boundary condition
  142. READ ( numnam_cfg, namlbc, IOSTAT = ios, ERR = 902 )
  143. 902 IF( ios /= 0 ) CALL ctl_nam ( ios , 'namlbc in configuration namelist', lwp )
  144. IF(lwm) WRITE ( numond, namlbc )
  145. IF(lwp) THEN ! control print
  146. WRITE(numout,*)
  147. WRITE(numout,*) 'dommsk : ocean mask '
  148. WRITE(numout,*) '~~~~~~'
  149. WRITE(numout,*) ' Namelist namlbc'
  150. WRITE(numout,*) ' lateral momentum boundary cond. rn_shlat = ',rn_shlat
  151. WRITE(numout,*) ' consistency with analytical form ln_vorlat = ',ln_vorlat
  152. ENDIF
  153. IF ( rn_shlat == 0. ) THEN ; IF(lwp) WRITE(numout,*) ' ocean lateral free-slip '
  154. ELSEIF ( rn_shlat == 2. ) THEN ; IF(lwp) WRITE(numout,*) ' ocean lateral no-slip '
  155. ELSEIF ( 0. < rn_shlat .AND. rn_shlat < 2. ) THEN ; IF(lwp) WRITE(numout,*) ' ocean lateral partial-slip '
  156. ELSEIF ( 2. < rn_shlat ) THEN ; IF(lwp) WRITE(numout,*) ' ocean lateral strong-slip '
  157. ELSE
  158. WRITE(ctmp1,*) ' rn_shlat is negative = ', rn_shlat
  159. CALL ctl_stop( ctmp1 )
  160. ENDIF
  161. ! 1. Ocean/land mask at t-point (computed from mbathy)
  162. ! -----------------------------
  163. ! N.B. tmask has already the right boundary conditions since mbathy is ok
  164. !
  165. tmask(:,:,:) = 0._wp
  166. DO jk = 1, jpk
  167. DO jj = 1, jpj
  168. DO ji = 1, jpi
  169. IF( REAL( mbathy(ji,jj) - jk, wp ) + 0.1_wp >= 0._wp ) tmask(ji,jj,jk) = 1._wp
  170. END DO
  171. END DO
  172. END DO
  173. ! (ISF) define barotropic mask and mask the ice shelf point
  174. ssmask(:,:)=tmask(:,:,1) ! at this stage ice shelf is not masked
  175. DO jk = 1, jpk
  176. DO jj = 1, jpj
  177. DO ji = 1, jpi
  178. IF( REAL( misfdep(ji,jj) - jk, wp ) - 0.1_wp >= 0._wp ) THEN
  179. tmask(ji,jj,jk) = 0._wp
  180. END IF
  181. END DO
  182. END DO
  183. END DO
  184. !!gm ????
  185. #if defined key_zdfkpp
  186. IF( cp_cfg == 'orca' ) THEN
  187. IF( jp_cfg == 2 ) THEN ! land point on Bab el Mandeb zonal section
  188. ij0 = 87 ; ij1 = 88
  189. ii0 = 160 ; ii1 = 161
  190. tmask( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) , 1:jpk ) = 0._wp
  191. ELSE
  192. IF(lwp) WRITE(numout,*)
  193. IF(lwp) WRITE(numout,cform_war)
  194. IF(lwp) WRITE(numout,*)
  195. IF(lwp) WRITE(numout,*)' A mask must be applied on Bab el Mandeb strait'
  196. IF(lwp) WRITE(numout,*)' in case of ORCAs configurations'
  197. IF(lwp) WRITE(numout,*)' This is a problem which is not yet solved'
  198. IF(lwp) WRITE(numout,*)
  199. ENDIF
  200. ENDIF
  201. #endif
  202. !!gm end
  203. ! Interior domain mask (used for global sum)
  204. ! --------------------
  205. tmask_i(:,:) = ssmask(:,:) ! (ISH) tmask_i = 1 even on the ice shelf
  206. iif = jpreci ! ???
  207. iil = nlci - jpreci + 1
  208. ijf = jprecj ! ???
  209. ijl = nlcj - jprecj + 1
  210. tmask_i( 1 :iif, : ) = 0._wp ! first columns
  211. tmask_i(iil:jpi, : ) = 0._wp ! last columns (including mpp extra columns)
  212. tmask_i( : , 1 :ijf) = 0._wp ! first rows
  213. tmask_i( : ,ijl:jpj) = 0._wp ! last rows (including mpp extra rows)
  214. ! north fold mask
  215. ! ---------------
  216. tpol(1:jpiglo) = 1._wp
  217. fpol(1:jpiglo) = 1._wp
  218. IF( jperio == 3 .OR. jperio == 4 ) THEN ! T-point pivot
  219. tpol(jpiglo/2+1:jpiglo) = 0._wp
  220. fpol( 1 :jpiglo) = 0._wp
  221. IF( mjg(nlej) == jpjglo ) THEN ! only half of the nlcj-1 row
  222. DO ji = iif+1, iil-1
  223. tmask_i(ji,nlej-1) = tmask_i(ji,nlej-1) * tpol(mig(ji))
  224. END DO
  225. ENDIF
  226. ENDIF
  227. IF( jperio == 5 .OR. jperio == 6 ) THEN ! F-point pivot
  228. tpol( 1 :jpiglo) = 0._wp
  229. fpol(jpiglo/2+1:jpiglo) = 0._wp
  230. ENDIF
  231. ! 2. Ocean/land mask at u-, v-, and z-points (computed from tmask)
  232. ! -------------------------------------------
  233. DO jk = 1, jpk
  234. DO jj = 1, jpjm1
  235. DO ji = 1, fs_jpim1 ! vector loop
  236. umask(ji,jj,jk) = tmask(ji,jj ,jk) * tmask(ji+1,jj ,jk)
  237. vmask(ji,jj,jk) = tmask(ji,jj ,jk) * tmask(ji ,jj+1,jk)
  238. END DO
  239. DO ji = 1, jpim1 ! NO vector opt.
  240. fmask(ji,jj,jk) = tmask(ji,jj ,jk) * tmask(ji+1,jj ,jk) &
  241. & * tmask(ji,jj+1,jk) * tmask(ji+1,jj+1,jk)
  242. END DO
  243. END DO
  244. END DO
  245. ! (ISF) MIN(1,SUM(umask)) is here to check if you have effectively at least 1 wet u point
  246. DO jj = 1, jpjm1
  247. DO ji = 1, fs_jpim1 ! vector loop
  248. umask_i(ji,jj) = ssmask(ji,jj) * ssmask(ji+1,jj ) * MIN(1._wp,SUM(umask(ji,jj,:)))
  249. vmask_i(ji,jj) = ssmask(ji,jj) * ssmask(ji ,jj+1) * MIN(1._wp,SUM(vmask(ji,jj,:)))
  250. END DO
  251. DO ji = 1, jpim1 ! NO vector opt.
  252. fmask_i(ji,jj) = ssmask(ji,jj ) * ssmask(ji+1,jj ) &
  253. & * ssmask(ji,jj+1) * ssmask(ji+1,jj+1) * MIN(1._wp,SUM(fmask(ji,jj,:)))
  254. END DO
  255. END DO
  256. CALL lbc_lnk( umask, 'U', 1._wp ) ! Lateral boundary conditions
  257. CALL lbc_lnk( vmask, 'V', 1._wp )
  258. CALL lbc_lnk( fmask, 'F', 1._wp )
  259. CALL lbc_lnk( umask_i, 'U', 1._wp ) ! Lateral boundary conditions
  260. CALL lbc_lnk( vmask_i, 'V', 1._wp )
  261. CALL lbc_lnk( fmask_i, 'F', 1._wp )
  262. ! 3. Ocean/land mask at wu-, wv- and w points
  263. !----------------------------------------------
  264. wmask (:,:,1) = tmask(:,:,1) ! ????????
  265. wumask(:,:,1) = umask(:,:,1) ! ????????
  266. wvmask(:,:,1) = vmask(:,:,1) ! ????????
  267. DO jk=2,jpk
  268. wmask (:,:,jk)=tmask(:,:,jk) * tmask(:,:,jk-1)
  269. wumask(:,:,jk)=umask(:,:,jk) * umask(:,:,jk-1)
  270. wvmask(:,:,jk)=vmask(:,:,jk) * vmask(:,:,jk-1)
  271. END DO
  272. ! 4. ocean/land mask for the elliptic equation
  273. ! --------------------------------------------
  274. bmask(:,:) = ssmask(:,:) ! elliptic equation is written at t-point
  275. !
  276. ! ! Boundary conditions
  277. ! ! cyclic east-west : bmask must be set to 0. on rows 1 and jpi
  278. IF( nperio == 1 .OR. nperio == 4 .OR. nperio == 6 ) THEN
  279. bmask( 1 ,:) = 0._wp
  280. bmask(jpi,:) = 0._wp
  281. ENDIF
  282. IF( nperio == 2 ) THEN ! south symmetric : bmask must be set to 0. on row 1
  283. bmask(:, 1 ) = 0._wp
  284. ENDIF
  285. ! ! north fold :
  286. IF( nperio == 3 .OR. nperio == 4 ) THEN ! T-pt pivot : bmask set to 0. on row jpj and on half jpjglo-1 row
  287. DO ji = 1, jpi
  288. ii = ji + nimpp - 1
  289. bmask(ji,jpj-1) = bmask(ji,jpj-1) * tpol(ii)
  290. bmask(ji,jpj ) = 0._wp
  291. END DO
  292. ENDIF
  293. IF( nperio == 5 .OR. nperio == 6 ) THEN ! F-pt pivot and T-pt elliptic eq. : bmask set to 0. on row jpj
  294. bmask(:,jpj) = 0._wp
  295. ENDIF
  296. !
  297. IF( lk_mpp ) THEN ! mpp specificities
  298. ! ! bmask is set to zero on the overlap region
  299. IF( nbondi /= -1 .AND. nbondi /= 2 ) bmask( 1 :jpreci,:) = 0._wp
  300. IF( nbondi /= 1 .AND. nbondi /= 2 ) bmask(nlci:jpi ,:) = 0._wp
  301. IF( nbondj /= -1 .AND. nbondj /= 2 ) bmask(:, 1 :jprecj) = 0._wp
  302. IF( nbondj /= 1 .AND. nbondj /= 2 ) bmask(:,nlcj:jpj ) = 0._wp
  303. !
  304. IF( npolj == 3 .OR. npolj == 4 ) THEN ! north fold : bmask must be set to 0. on rows jpj-1 and jpj
  305. DO ji = 1, nlci
  306. ii = ji + nimpp - 1
  307. bmask(ji,nlcj-1) = bmask(ji,nlcj-1) * tpol(ii)
  308. bmask(ji,nlcj ) = 0._wp
  309. END DO
  310. ENDIF
  311. IF( npolj == 5 .OR. npolj == 6 ) THEN ! F-pt pivot and T-pt elliptic eq. : bmask set to 0. on row jpj
  312. DO ji = 1, nlci
  313. bmask(ji,nlcj ) = 0._wp
  314. END DO
  315. ENDIF
  316. ENDIF
  317. ! mask for second order calculation of vorticity
  318. ! ----------------------------------------------
  319. CALL dom_msk_nsa
  320. ! Lateral boundary conditions on velocity (modify fmask)
  321. ! ---------------------------------------
  322. DO jk = 1, jpk
  323. zwf(:,:) = fmask(:,:,jk)
  324. DO jj = 2, jpjm1
  325. DO ji = fs_2, fs_jpim1 ! vector opt.
  326. IF( fmask(ji,jj,jk) == 0._wp ) THEN
  327. fmask(ji,jj,jk) = rn_shlat * MIN( 1._wp , MAX( zwf(ji+1,jj), zwf(ji,jj+1), &
  328. & zwf(ji-1,jj), zwf(ji,jj-1) ) )
  329. ENDIF
  330. END DO
  331. END DO
  332. DO jj = 2, jpjm1
  333. IF( fmask(1,jj,jk) == 0._wp ) THEN
  334. fmask(1 ,jj,jk) = rn_shlat * MIN( 1._wp , MAX( zwf(2,jj), zwf(1,jj+1), zwf(1,jj-1) ) )
  335. ENDIF
  336. IF( fmask(jpi,jj,jk) == 0._wp ) THEN
  337. fmask(jpi,jj,jk) = rn_shlat * MIN( 1._wp , MAX( zwf(jpi,jj+1), zwf(jpim1,jj), zwf(jpi,jj-1) ) )
  338. ENDIF
  339. END DO
  340. DO ji = 2, jpim1
  341. IF( fmask(ji,1,jk) == 0._wp ) THEN
  342. fmask(ji, 1 ,jk) = rn_shlat * MIN( 1._wp , MAX( zwf(ji+1,1), zwf(ji,2), zwf(ji-1,1) ) )
  343. ENDIF
  344. IF( fmask(ji,jpj,jk) == 0._wp ) THEN
  345. fmask(ji,jpj,jk) = rn_shlat * MIN( 1._wp , MAX( zwf(ji+1,jpj), zwf(ji-1,jpj), zwf(ji,jpjm1) ) )
  346. ENDIF
  347. END DO
  348. #if defined key_agrif
  349. IF( .NOT. AGRIF_Root() ) THEN
  350. IF ((nbondi == 1).OR.(nbondi == 2)) fmask(nlci-1 , : ,jk) = 0.e0 ! east
  351. IF ((nbondi == -1).OR.(nbondi == 2)) fmask(1 , : ,jk) = 0.e0 ! west
  352. IF ((nbondj == 1).OR.(nbondj == 2)) fmask(: ,nlcj-1 ,jk) = 0.e0 ! north
  353. IF ((nbondj == -1).OR.(nbondj == 2)) fmask(: ,1 ,jk) = 0.e0 ! south
  354. ENDIF
  355. #endif
  356. END DO
  357. !
  358. IF( cp_cfg == "orca" .AND. jp_cfg == 2 ) THEN ! ORCA_R2 configuration
  359. ! ! Increased lateral friction near of some straits
  360. IF( nn_cla == 0 ) THEN
  361. ! ! Gibraltar strait : partial slip (fmask=0.5)
  362. ij0 = 101 ; ij1 = 101
  363. ii0 = 139 ; ii1 = 140 ; fmask( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) , 1:jpk ) = 0.5_wp
  364. ij0 = 102 ; ij1 = 102
  365. ii0 = 139 ; ii1 = 140 ; fmask( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) , 1:jpk ) = 0.5_wp
  366. !
  367. ! ! Bab el Mandeb : partial slip (fmask=1)
  368. ij0 = 87 ; ij1 = 88
  369. ii0 = 160 ; ii1 = 160 ; fmask( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) , 1:jpk ) = 1._wp
  370. ij0 = 88 ; ij1 = 88
  371. ii0 = 159 ; ii1 = 159 ; fmask( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) , 1:jpk ) = 1._wp
  372. !
  373. ENDIF
  374. ! ! Danish straits : strong slip (fmask > 2)
  375. ! We keep this as an example but it is instable in this case
  376. ! ij0 = 115 ; ij1 = 115
  377. ! ii0 = 145 ; ii1 = 146 ; fmask( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) , 1:jpk ) = 4._wp
  378. ! ij0 = 116 ; ij1 = 116
  379. ! ii0 = 145 ; ii1 = 146 ; fmask( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) , 1:jpk ) = 4._wp
  380. !
  381. ENDIF
  382. !
  383. IF( cp_cfg == "orca" .AND. jp_cfg == 1 ) THEN ! ORCA R1 configuration
  384. ! ! Increased lateral friction near of some straits
  385. ! This dirty section will be suppressed by simplification process:
  386. ! all this will come back in input files
  387. ! Currently these hard-wired indices relate to configuration with
  388. ! extend grid (jpjglo=332)
  389. !
  390. isrow = 332 - jpjglo
  391. !
  392. IF(lwp) WRITE(numout,*)
  393. IF(lwp) WRITE(numout,*) ' orca_r1: increase friction near the following straits : '
  394. IF(lwp) WRITE(numout,*) ' Gibraltar '
  395. ii0 = 282 ; ii1 = 283 ! Gibraltar Strait
  396. ij0 = 241 - isrow ; ij1 = 241 - isrow ; fmask( mi0(ii0):mi1(ii1),mj0(ij0):mj1(ij1),1:jpk ) = 2._wp
  397. IF(lwp) WRITE(numout,*) ' Bhosporus '
  398. ii0 = 314 ; ii1 = 315 ! Bhosporus Strait
  399. ij0 = 248 - isrow ; ij1 = 248 - isrow ; fmask( mi0(ii0):mi1(ii1),mj0(ij0):mj1(ij1),1:jpk ) = 2._wp
  400. IF(lwp) WRITE(numout,*) ' Makassar (Top) '
  401. ii0 = 48 ; ii1 = 48 ! Makassar Strait (Top)
  402. ij0 = 189 - isrow ; ij1 = 190 - isrow ; fmask( mi0(ii0):mi1(ii1),mj0(ij0):mj1(ij1),1:jpk ) = 3._wp
  403. IF(lwp) WRITE(numout,*) ' Lombok '
  404. ii0 = 44 ; ii1 = 44 ! Lombok Strait
  405. ij0 = 164 - isrow ; ij1 = 165 - isrow ; fmask( mi0(ii0):mi1(ii1),mj0(ij0):mj1(ij1),1:jpk ) = 2._wp
  406. IF(lwp) WRITE(numout,*) ' Ombai '
  407. ii0 = 53 ; ii1 = 53 ! Ombai Strait
  408. ij0 = 164 - isrow ; ij1 = 165 - isrow ; fmask( mi0(ii0):mi1(ii1),mj0(ij0):mj1(ij1),1:jpk ) = 2._wp
  409. IF(lwp) WRITE(numout,*) ' Timor Passage '
  410. ii0 = 56 ; ii1 = 56 ! Timor Passage
  411. ij0 = 164 - isrow ; ij1 = 165 - isrow ; fmask( mi0(ii0):mi1(ii1),mj0(ij0):mj1(ij1),1:jpk ) = 2._wp
  412. IF(lwp) WRITE(numout,*) ' West Halmahera '
  413. ii0 = 58 ; ii1 = 58 ! West Halmahera Strait
  414. ij0 = 181 - isrow ; ij1 = 182 - isrow ; fmask( mi0(ii0):mi1(ii1),mj0(ij0):mj1(ij1),1:jpk ) = 3._wp
  415. IF(lwp) WRITE(numout,*) ' East Halmahera '
  416. ii0 = 55 ; ii1 = 55 ! East Halmahera Strait
  417. ij0 = 181 - isrow ; ij1 = 182 - isrow ; fmask( mi0(ii0):mi1(ii1),mj0(ij0):mj1(ij1),1:jpk ) = 3._wp
  418. !
  419. ENDIF
  420. !
  421. CALL lbc_lnk( fmask, 'F', 1._wp ) ! Lateral boundary conditions on fmask
  422. ! CAUTION : The fmask may be further modified in dyn_vor_init ( dynvor.F90 )
  423. IF( nprint == 1 .AND. lwp ) THEN ! Control print
  424. imsk(:,:) = INT( tmask_i(:,:) )
  425. WRITE(numout,*) ' tmask_i : '
  426. CALL prihin( imsk(:,:), jpi, jpj, 1, jpi, 1, &
  427. & 1, jpj, 1, 1, numout)
  428. WRITE (numout,*)
  429. WRITE (numout,*) ' dommsk: tmask for each level'
  430. WRITE (numout,*) ' ----------------------------'
  431. DO jk = 1, jpk
  432. imsk(:,:) = INT( tmask(:,:,jk) )
  433. WRITE(numout,*)
  434. WRITE(numout,*) ' level = ',jk
  435. CALL prihin( imsk(:,:), jpi, jpj, 1, jpi, 1, &
  436. & 1, jpj, 1, 1, numout)
  437. END DO
  438. WRITE(numout,*)
  439. WRITE(numout,*) ' dom_msk: vmask for each level'
  440. WRITE(numout,*) ' -----------------------------'
  441. DO jk = 1, jpk
  442. imsk(:,:) = INT( vmask(:,:,jk) )
  443. WRITE(numout,*)
  444. WRITE(numout,*) ' level = ',jk
  445. CALL prihin( imsk(:,:), jpi, jpj, 1, jpi, 1, &
  446. & 1, jpj, 1, 1, numout)
  447. END DO
  448. WRITE(numout,*)
  449. WRITE(numout,*) ' dom_msk: fmask for each level'
  450. WRITE(numout,*) ' -----------------------------'
  451. DO jk = 1, jpk
  452. imsk(:,:) = INT( fmask(:,:,jk) )
  453. WRITE(numout,*)
  454. WRITE(numout,*) ' level = ',jk
  455. CALL prihin( imsk(:,:), jpi, jpj, 1, jpi, 1, &
  456. & 1, jpj, 1, 1, numout )
  457. END DO
  458. WRITE(numout,*)
  459. WRITE(numout,*) ' dom_msk: bmask '
  460. WRITE(numout,*) ' ---------------'
  461. WRITE(numout,*)
  462. imsk(:,:) = INT( bmask(:,:) )
  463. CALL prihin( imsk(:,:), jpi, jpj, 1, jpi, 1, &
  464. & 1, jpj, 1, 1, numout )
  465. ENDIF
  466. !
  467. CALL wrk_dealloc( jpi, jpj, imsk )
  468. CALL wrk_dealloc( jpi, jpj, zwf )
  469. !
  470. IF( nn_timing == 1 ) CALL timing_stop('dom_msk')
  471. !
  472. END SUBROUTINE dom_msk
  473. #if defined key_noslip_accurate
  474. !!----------------------------------------------------------------------
  475. !! 'key_noslip_accurate' : accurate no-slip boundary condition
  476. !!----------------------------------------------------------------------
  477. SUBROUTINE dom_msk_nsa
  478. !!---------------------------------------------------------------------
  479. !! *** ROUTINE dom_msk_nsa ***
  480. !!
  481. !! ** Purpose :
  482. !!
  483. !! ** Method :
  484. !!
  485. !! ** Action :
  486. !!----------------------------------------------------------------------
  487. INTEGER :: ji, jj, jk, jl ! dummy loop indices
  488. INTEGER :: ine, inw, ins, inn, itest, ierror, iind, ijnd
  489. REAL(wp) :: zaa
  490. !!---------------------------------------------------------------------
  491. !
  492. IF( nn_timing == 1 ) CALL timing_start('dom_msk_nsa')
  493. !
  494. IF(lwp) WRITE(numout,*)
  495. IF(lwp) WRITE(numout,*) 'dom_msk_nsa : noslip accurate boundary condition'
  496. IF(lwp) WRITE(numout,*) '~~~~~~~~~~~ using Schchepetkin and O Brian scheme'
  497. IF( lk_mpp ) CALL ctl_stop( ' mpp version is not yet implemented' )
  498. ! mask for second order calculation of vorticity
  499. ! ----------------------------------------------
  500. ! noslip boundary condition: fmask=1 at convex corner, store
  501. ! index of straight coast meshes ( 'west', refering to a coast,
  502. ! means west of the ocean, aso)
  503. DO jk = 1, jpk
  504. DO jl = 1, 4
  505. npcoa(jl,jk) = 0
  506. DO ji = 1, 2*(jpi+jpj)
  507. nicoa(ji,jl,jk) = 0
  508. njcoa(ji,jl,jk) = 0
  509. END DO
  510. END DO
  511. END DO
  512. IF( jperio == 2 ) THEN
  513. WRITE(numout,*) ' '
  514. WRITE(numout,*) ' symetric boundary conditions need special'
  515. WRITE(numout,*) ' treatment not implemented. we stop.'
  516. STOP
  517. ENDIF
  518. ! convex corners
  519. DO jk = 1, jpkm1
  520. DO jj = 1, jpjm1
  521. DO ji = 1, jpim1
  522. zaa = tmask(ji ,jj,jk) + tmask(ji ,jj+1,jk) &
  523. &+ tmask(ji+1,jj,jk) + tmask(ji+1,jj+1,jk)
  524. IF( ABS(zaa-3._wp) <= 0.1_wp ) fmask(ji,jj,jk) = 1._wp
  525. END DO
  526. END DO
  527. END DO
  528. ! north-south straight coast
  529. DO jk = 1, jpkm1
  530. inw = 0
  531. ine = 0
  532. DO jj = 2, jpjm1
  533. DO ji = 2, jpim1
  534. zaa = tmask(ji+1,jj,jk) + tmask(ji+1,jj+1,jk)
  535. IF( ABS(zaa-2._wp) <= 0.1_wp .AND. fmask(ji,jj,jk) == 0._wp ) THEN
  536. inw = inw + 1
  537. nicoa(inw,1,jk) = ji
  538. njcoa(inw,1,jk) = jj
  539. IF( nprint == 1 ) WRITE(numout,*) ' west : ', jk, inw, ji, jj
  540. ENDIF
  541. zaa = tmask(ji,jj,jk) + tmask(ji,jj+1,jk)
  542. IF( ABS(zaa-2._wp) <= 0.1_wp .AND. fmask(ji,jj,jk) == 0._wp ) THEN
  543. ine = ine + 1
  544. nicoa(ine,2,jk) = ji
  545. njcoa(ine,2,jk) = jj
  546. IF( nprint == 1 ) WRITE(numout,*) ' east : ', jk, ine, ji, jj
  547. ENDIF
  548. END DO
  549. END DO
  550. npcoa(1,jk) = inw
  551. npcoa(2,jk) = ine
  552. END DO
  553. ! west-east straight coast
  554. DO jk = 1, jpkm1
  555. ins = 0
  556. inn = 0
  557. DO jj = 2, jpjm1
  558. DO ji =2, jpim1
  559. zaa = tmask(ji,jj+1,jk) + tmask(ji+1,jj+1,jk)
  560. IF( ABS(zaa-2._wp) <= 0.1_wp .AND. fmask(ji,jj,jk) == 0._wp ) THEN
  561. ins = ins + 1
  562. nicoa(ins,3,jk) = ji
  563. njcoa(ins,3,jk) = jj
  564. IF( nprint == 1 ) WRITE(numout,*) ' south : ', jk, ins, ji, jj
  565. ENDIF
  566. zaa = tmask(ji+1,jj,jk) + tmask(ji,jj,jk)
  567. IF( ABS(zaa-2._wp) <= 0.1_wp .AND. fmask(ji,jj,jk) == 0._wp ) THEN
  568. inn = inn + 1
  569. nicoa(inn,4,jk) = ji
  570. njcoa(inn,4,jk) = jj
  571. IF( nprint == 1 ) WRITE(numout,*) ' north : ', jk, inn, ji, jj
  572. ENDIF
  573. END DO
  574. END DO
  575. npcoa(3,jk) = ins
  576. npcoa(4,jk) = inn
  577. END DO
  578. itest = 2 * ( jpi + jpj )
  579. DO jk = 1, jpk
  580. IF( npcoa(1,jk) > itest .OR. npcoa(2,jk) > itest .OR. &
  581. npcoa(3,jk) > itest .OR. npcoa(4,jk) > itest ) THEN
  582. WRITE(ctmp1,*) ' level jk = ',jk
  583. WRITE(ctmp2,*) ' straight coast index arraies are too small.:'
  584. WRITE(ctmp3,*) ' npe, npw, nps, npn = ', npcoa(1,jk), npcoa(2,jk), &
  585. & npcoa(3,jk), npcoa(4,jk)
  586. WRITE(ctmp4,*) ' 2*(jpi+jpj) = ',itest,'. we stop.'
  587. CALL ctl_stop( ctmp1, ctmp2, ctmp3, ctmp4 )
  588. ENDIF
  589. END DO
  590. ierror = 0
  591. iind = 0
  592. ijnd = 0
  593. IF( nperio == 1 .OR. nperio == 4 .OR. nperio == 6 ) iind = 2
  594. IF( nperio == 3 .OR. nperio == 4 .OR. nperio == 5 .OR. nperio == 6 ) ijnd = 2
  595. DO jk = 1, jpk
  596. DO jl = 1, npcoa(1,jk)
  597. IF( nicoa(jl,1,jk)+3 > jpi+iind ) THEN
  598. ierror = ierror+1
  599. icoord(ierror,1) = nicoa(jl,1,jk)
  600. icoord(ierror,2) = njcoa(jl,1,jk)
  601. icoord(ierror,3) = jk
  602. ENDIF
  603. END DO
  604. DO jl = 1, npcoa(2,jk)
  605. IF(nicoa(jl,2,jk)-2 < 1-iind ) THEN
  606. ierror = ierror + 1
  607. icoord(ierror,1) = nicoa(jl,2,jk)
  608. icoord(ierror,2) = njcoa(jl,2,jk)
  609. icoord(ierror,3) = jk
  610. ENDIF
  611. END DO
  612. DO jl = 1, npcoa(3,jk)
  613. IF( njcoa(jl,3,jk)+3 > jpj+ijnd ) THEN
  614. ierror = ierror + 1
  615. icoord(ierror,1) = nicoa(jl,3,jk)
  616. icoord(ierror,2) = njcoa(jl,3,jk)
  617. icoord(ierror,3) = jk
  618. ENDIF
  619. END DO
  620. DO jl = 1, npcoa(4,jk)
  621. IF( njcoa(jl,4,jk)-2 < 1) THEN
  622. ierror=ierror + 1
  623. icoord(ierror,1) = nicoa(jl,4,jk)
  624. icoord(ierror,2) = njcoa(jl,4,jk)
  625. icoord(ierror,3) = jk
  626. ENDIF
  627. END DO
  628. END DO
  629. IF( ierror > 0 ) THEN
  630. IF(lwp) WRITE(numout,*)
  631. IF(lwp) WRITE(numout,*) ' Problem on lateral conditions'
  632. IF(lwp) WRITE(numout,*) ' Bad marking off at points:'
  633. DO jl = 1, ierror
  634. IF(lwp) WRITE(numout,*) 'Level:',icoord(jl,3), &
  635. & ' Point(',icoord(jl,1),',',icoord(jl,2),')'
  636. END DO
  637. CALL ctl_stop( 'We stop...' )
  638. ENDIF
  639. !
  640. IF( nn_timing == 1 ) CALL timing_stop('dom_msk_nsa')
  641. !
  642. END SUBROUTINE dom_msk_nsa
  643. #else
  644. !!----------------------------------------------------------------------
  645. !! Default option : Empty routine
  646. !!----------------------------------------------------------------------
  647. SUBROUTINE dom_msk_nsa
  648. END SUBROUTINE dom_msk_nsa
  649. #endif
  650. !!======================================================================
  651. END MODULE dommsk