domain.F90 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  1. MODULE domain
  2. !!==============================================================================
  3. !! *** MODULE domain ***
  4. !! Ocean initialization : domain initialization
  5. !!==============================================================================
  6. !! History : OPA ! 1990-10 (C. Levy - G. Madec) Original code
  7. !! ! 1992-01 (M. Imbard) insert time step initialization
  8. !! ! 1996-06 (G. Madec) generalized vertical coordinate
  9. !! ! 1997-02 (G. Madec) creation of domwri.F
  10. !! ! 2001-05 (E.Durand - G. Madec) insert closed sea
  11. !! NEMO 1.0 ! 2002-08 (G. Madec) F90: Free form and module
  12. !! 2.0 ! 2005-11 (V. Garnier) Surface pressure gradient organization
  13. !! 3.3 ! 2010-11 (G. Madec) initialisation in C1D configuration
  14. !! 3.6 ! 2013 ( J. Simeon, C. Calone, G. Madec, C. Ethe ) Online coarsening of outputs
  15. !!----------------------------------------------------------------------
  16. !!----------------------------------------------------------------------
  17. !! dom_init : initialize the space and time domain
  18. !! dom_nam : read and contral domain namelists
  19. !! dom_ctl : control print for the ocean domain
  20. !!----------------------------------------------------------------------
  21. USE oce ! ocean variables
  22. USE dom_oce ! domain: ocean
  23. USE sbc_oce ! surface boundary condition: ocean
  24. USE trc_oce ! shared ocean-passive tracers variables
  25. USE phycst ! physical constants
  26. USE closea ! closed seas
  27. USE in_out_manager ! I/O manager
  28. USE lib_mpp ! distributed memory computing library
  29. USE domhgr ! domain: set the horizontal mesh
  30. USE domzgr ! domain: set the vertical mesh
  31. USE domstp ! domain: set the time-step
  32. USE dommsk ! domain: set the mask system
  33. USE domwri ! domain: write the meshmask file
  34. USE domvvl ! variable volume
  35. USE c1d ! 1D vertical configuration
  36. USE dyncor_c1d ! Coriolis term (c1d case) (cor_c1d routine)
  37. USE timing ! Timing
  38. USE lbclnk ! ocean lateral boundary condition (or mpp link)
  39. IMPLICIT NONE
  40. PRIVATE
  41. PUBLIC dom_init ! called by opa.F90
  42. !! * Substitutions
  43. # include "domzgr_substitute.h90"
  44. !!-------------------------------------------------------------------------
  45. !! NEMO/OPA 3.3 , NEMO Consortium (2010)
  46. !! $Id: domain.F90 4990 2014-12-15 16:42:49Z timgraham $
  47. !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
  48. !!-------------------------------------------------------------------------
  49. CONTAINS
  50. SUBROUTINE dom_init
  51. !!----------------------------------------------------------------------
  52. !! *** ROUTINE dom_init ***
  53. !!
  54. !! ** Purpose : Domain initialization. Call the routines that are
  55. !! required to create the arrays which define the space
  56. !! and time domain of the ocean model.
  57. !!
  58. !! ** Method : - dom_msk: compute the masks from the bathymetry file
  59. !! - dom_hgr: compute or read the horizontal grid-point position
  60. !! and scale factors, and the coriolis factor
  61. !! - dom_zgr: define the vertical coordinate and the bathymetry
  62. !! - dom_stp: defined the model time step
  63. !! - dom_wri: create the meshmask file if nmsh=1
  64. !! - 1D configuration, move Coriolis, u and v at T-point
  65. !!----------------------------------------------------------------------
  66. INTEGER :: jk ! dummy loop argument
  67. INTEGER :: iconf = 0 ! local integers
  68. !!----------------------------------------------------------------------
  69. !
  70. IF( nn_timing == 1 ) CALL timing_start('dom_init')
  71. !
  72. IF(lwp) THEN
  73. WRITE(numout,*)
  74. WRITE(numout,*) 'dom_init : domain initialization'
  75. WRITE(numout,*) '~~~~~~~~'
  76. ENDIF
  77. !
  78. CALL dom_nam ! read namelist ( namrun, namdom, namcla )
  79. CALL dom_clo ! Closed seas and lake
  80. CALL dom_hgr ! Horizontal mesh
  81. CALL dom_zgr ! Vertical mesh and bathymetry
  82. CALL dom_msk ! Masks
  83. IF( ln_sco ) CALL dom_stiff ! Maximum stiffness ratio/hydrostatic consistency
  84. !
  85. ht_0(:,:) = 0.0_wp ! Reference ocean depth at T-points
  86. hu_0(:,:) = 0.0_wp ! Reference ocean depth at U-points
  87. hv_0(:,:) = 0.0_wp ! Reference ocean depth at V-points
  88. DO jk = 1, jpk
  89. ht_0(:,:) = ht_0(:,:) + e3t_0(:,:,jk) * tmask(:,:,jk)
  90. hu_0(:,:) = hu_0(:,:) + e3u_0(:,:,jk) * umask(:,:,jk)
  91. hv_0(:,:) = hv_0(:,:) + e3v_0(:,:,jk) * vmask(:,:,jk)
  92. END DO
  93. !
  94. IF( lk_c1d ) CALL cor_c1d ! 1D configuration: Coriolis set at T-point
  95. !
  96. IF( .NOT.lk_offline ) THEN
  97. !
  98. IF( lk_vvl ) CALL dom_vvl_init ! Vertical variable mesh
  99. !
  100. hu(:,:) = 0._wp ! Ocean depth at U-points
  101. hv(:,:) = 0._wp ! Ocean depth at V-points
  102. ht(:,:) = 0._wp ! Ocean depth at T-points
  103. DO jk = 1, jpkm1
  104. hu(:,:) = hu(:,:) + fse3u_n(:,:,jk) * umask(:,:,jk)
  105. hv(:,:) = hv(:,:) + fse3v_n(:,:,jk) * vmask(:,:,jk)
  106. ht(:,:) = ht(:,:) + fse3t_n(:,:,jk) * tmask(:,:,jk)
  107. END DO
  108. ! ! Inverse of the local depth
  109. hur(:,:) = 1._wp / ( hu(:,:) + 1._wp - umask_i(:,:) ) * umask_i(:,:)
  110. hvr(:,:) = 1._wp / ( hv(:,:) + 1._wp - vmask_i(:,:) ) * vmask_i(:,:)
  111. !
  112. ENDIF
  113. CALL dom_stp ! time step
  114. IF( nmsh /= 0 ) CALL dom_wri ! Create a domain file
  115. IF( .NOT.ln_rstart ) CALL dom_ctl ! Domain control
  116. !
  117. IF( nn_timing == 1 ) CALL timing_stop('dom_init')
  118. !
  119. END SUBROUTINE dom_init
  120. SUBROUTINE dom_nam
  121. !!----------------------------------------------------------------------
  122. !! *** ROUTINE dom_nam ***
  123. !!
  124. !! ** Purpose : read domaine namelists and print the variables.
  125. !!
  126. !! ** input : - namrun namelist
  127. !! - namdom namelist
  128. !! - namcla namelist
  129. !! - namnc4 namelist ! "key_netcdf4" only
  130. !!----------------------------------------------------------------------
  131. USE ioipsl
  132. NAMELIST/namrun/ cn_ocerst_indir, cn_ocerst_outdir, nn_stocklist, ln_rst_list, &
  133. & nn_no , cn_exp , cn_ocerst_in, cn_ocerst_out, ln_rstart , nn_rstctl, &
  134. & nn_it000, nn_itend , nn_date0 , nn_leapy , nn_istate , nn_stock , &
  135. & nn_write, ln_dimgnnn, ln_mskland , ln_cfmeta , ln_clobber, nn_chunksz, nn_euler
  136. NAMELIST/namdom/ nn_bathy, rn_bathy , rn_e3zps_min, rn_e3zps_rat, nn_msh, rn_hmin, &
  137. & nn_acc , rn_atfp , rn_rdt , rn_rdtmin , &
  138. & rn_rdtmax, rn_rdth , nn_closea , ln_crs, &
  139. & jphgr_msh, &
  140. & ppglam0, ppgphi0, ppe1_deg, ppe2_deg, ppe1_m, ppe2_m, &
  141. & ppsur, ppa0, ppa1, ppkth, ppacr, ppdzmin, pphmax, ldbletanh, &
  142. & ppa2, ppkth2, ppacr2
  143. NAMELIST/namcla/ nn_cla
  144. #if defined key_netcdf4
  145. NAMELIST/namnc4/ nn_nchunks_i, nn_nchunks_j, nn_nchunks_k, ln_nc4zip
  146. #endif
  147. INTEGER :: ios ! Local integer output status for namelist read
  148. !!----------------------------------------------------------------------
  149. REWIND( numnam_ref ) ! Namelist namrun in reference namelist : Parameters of the run
  150. READ ( numnam_ref, namrun, IOSTAT = ios, ERR = 901)
  151. 901 IF( ios /= 0 ) CALL ctl_nam ( ios , 'namrun in reference namelist', lwp )
  152. REWIND( numnam_cfg ) ! Namelist namrun in configuration namelist : Parameters of the run
  153. READ ( numnam_cfg, namrun, IOSTAT = ios, ERR = 902 )
  154. 902 IF( ios /= 0 ) CALL ctl_nam ( ios , 'namrun in configuration namelist', lwp )
  155. IF(lwm) WRITE ( numond, namrun )
  156. !
  157. IF(lwp) THEN ! control print
  158. WRITE(numout,*)
  159. WRITE(numout,*) 'dom_nam : domain initialization through namelist read'
  160. WRITE(numout,*) '~~~~~~~ '
  161. WRITE(numout,*) ' Namelist namrun'
  162. WRITE(numout,*) ' job number nn_no = ', nn_no
  163. WRITE(numout,*) ' experiment name for output cn_exp = ', cn_exp
  164. WRITE(numout,*) ' file prefix restart input cn_ocerst_in= ', cn_ocerst_in
  165. WRITE(numout,*) ' restart input directory cn_ocerst_indir= ', cn_ocerst_indir
  166. WRITE(numout,*) ' file prefix restart output cn_ocerst_out= ', cn_ocerst_out
  167. WRITE(numout,*) ' restart output directory cn_ocerst_outdir= ', cn_ocerst_outdir
  168. WRITE(numout,*) ' restart logical ln_rstart = ', ln_rstart
  169. WRITE(numout,*) ' start with forward time step nn_euler = ', nn_euler
  170. WRITE(numout,*) ' control of time step nn_rstctl = ', nn_rstctl
  171. WRITE(numout,*) ' number of the first time step nn_it000 = ', nn_it000
  172. WRITE(numout,*) ' number of the last time step nn_itend = ', nn_itend
  173. WRITE(numout,*) ' initial calendar date aammjj nn_date0 = ', nn_date0
  174. WRITE(numout,*) ' leap year calendar (0/1) nn_leapy = ', nn_leapy
  175. WRITE(numout,*) ' initial state output nn_istate = ', nn_istate
  176. IF( ln_rst_list ) THEN
  177. WRITE(numout,*) ' list of restart dump times nn_stocklist =', nn_stocklist
  178. ELSE
  179. WRITE(numout,*) ' frequency of restart file nn_stock = ', nn_stock
  180. ENDIF
  181. WRITE(numout,*) ' frequency of output file nn_write = ', nn_write
  182. WRITE(numout,*) ' multi file dimgout ln_dimgnnn = ', ln_dimgnnn
  183. WRITE(numout,*) ' mask land points ln_mskland = ', ln_mskland
  184. WRITE(numout,*) ' additional CF standard metadata ln_cfmeta = ', ln_cfmeta
  185. WRITE(numout,*) ' overwrite an existing file ln_clobber = ', ln_clobber
  186. WRITE(numout,*) ' NetCDF chunksize (bytes) nn_chunksz = ', nn_chunksz
  187. ENDIF
  188. no = nn_no ! conversion DOCTOR names into model names (this should disappear soon)
  189. cexper = cn_exp
  190. nrstdt = nn_rstctl
  191. nit000 = nn_it000
  192. nitend = nn_itend
  193. ndate0 = nn_date0
  194. nleapy = nn_leapy
  195. ninist = nn_istate
  196. nstock = nn_stock
  197. nstocklist = nn_stocklist
  198. nwrite = nn_write
  199. neuler = nn_euler
  200. IF ( neuler == 1 .AND. .NOT. ln_rstart ) THEN
  201. WRITE(ctmp1,*) 'ln_rstart =.FALSE., nn_euler is forced to 0 '
  202. CALL ctl_warn( ctmp1 )
  203. neuler = 0
  204. ENDIF
  205. ! ! control of output frequency
  206. IF ( nstock == 0 .OR. nstock > nitend ) THEN
  207. WRITE(ctmp1,*) 'nstock = ', nstock, ' it is forced to ', nitend
  208. CALL ctl_warn( ctmp1 )
  209. nstock = nitend
  210. ENDIF
  211. IF ( nwrite == 0 ) THEN
  212. WRITE(ctmp1,*) 'nwrite = ', nwrite, ' it is forced to ', nitend
  213. CALL ctl_warn( ctmp1 )
  214. nwrite = nitend
  215. ENDIF
  216. #if defined key_agrif
  217. IF( Agrif_Root() ) THEN
  218. #endif
  219. SELECT CASE ( nleapy ) ! Choose calendar for IOIPSL
  220. CASE ( 1 )
  221. CALL ioconf_calendar('gregorian')
  222. IF(lwp) WRITE(numout,*) ' The IOIPSL calendar is "gregorian", i.e. leap year'
  223. CASE ( 0 )
  224. CALL ioconf_calendar('noleap')
  225. IF(lwp) WRITE(numout,*) ' The IOIPSL calendar is "noleap", i.e. no leap year'
  226. CASE ( 30 )
  227. CALL ioconf_calendar('360d')
  228. IF(lwp) WRITE(numout,*) ' The IOIPSL calendar is "360d", i.e. 360 days in a year'
  229. END SELECT
  230. #if defined key_agrif
  231. ENDIF
  232. #endif
  233. REWIND( numnam_ref ) ! Namelist namdom in reference namelist : space & time domain (bathymetry, mesh, timestep)
  234. READ ( numnam_ref, namdom, IOSTAT = ios, ERR = 903)
  235. 903 IF( ios /= 0 ) CALL ctl_nam ( ios , 'namdom in reference namelist', lwp )
  236. !
  237. REWIND( numnam_cfg ) ! Namelist namdom in configuration namelist : space & time domain (bathymetry, mesh, timestep)
  238. READ ( numnam_cfg, namdom, IOSTAT = ios, ERR = 904 )
  239. 904 IF( ios /= 0 ) CALL ctl_nam ( ios , 'namdom in configuration namelist', lwp )
  240. IF(lwm) WRITE ( numond, namdom )
  241. IF(lwp) THEN
  242. WRITE(numout,*)
  243. WRITE(numout,*) ' Namelist namdom : space & time domain'
  244. WRITE(numout,*) ' flag read/compute bathymetry nn_bathy = ', nn_bathy
  245. WRITE(numout,*) ' Depth (if =0 bathy=jpkm1) rn_bathy = ', rn_bathy
  246. WRITE(numout,*) ' min depth of the ocean (>0) or rn_hmin = ', rn_hmin
  247. WRITE(numout,*) ' min number of ocean level (<0) '
  248. WRITE(numout,*) ' minimum thickness of partial rn_e3zps_min = ', rn_e3zps_min, ' (m)'
  249. WRITE(numout,*) ' step level rn_e3zps_rat = ', rn_e3zps_rat
  250. WRITE(numout,*) ' create mesh/mask file(s) nn_msh = ', nn_msh
  251. WRITE(numout,*) ' = 0 no file created '
  252. WRITE(numout,*) ' = 1 mesh_mask '
  253. WRITE(numout,*) ' = 2 mesh and mask '
  254. WRITE(numout,*) ' = 3 mesh_hgr, msh_zgr and mask'
  255. WRITE(numout,*) ' ocean time step rn_rdt = ', rn_rdt
  256. WRITE(numout,*) ' asselin time filter parameter rn_atfp = ', rn_atfp
  257. WRITE(numout,*) ' acceleration of converge nn_acc = ', nn_acc
  258. WRITE(numout,*) ' nn_acc=1: surface tracer rdt rn_rdtmin = ', rn_rdtmin
  259. WRITE(numout,*) ' bottom tracer rdt rdtmax = ', rn_rdtmax
  260. WRITE(numout,*) ' depth of transition rn_rdth = ', rn_rdth
  261. WRITE(numout,*) ' suppression of closed seas (=0) nn_closea = ', nn_closea
  262. WRITE(numout,*) ' online coarsening of dynamical fields ln_crs = ', ln_crs
  263. WRITE(numout,*) ' type of horizontal mesh jphgr_msh = ', jphgr_msh
  264. WRITE(numout,*) ' longitude of first raw and column T-point ppglam0 = ', ppglam0
  265. WRITE(numout,*) ' latitude of first raw and column T-point ppgphi0 = ', ppgphi0
  266. WRITE(numout,*) ' zonal grid-spacing (degrees) ppe1_deg = ', ppe1_deg
  267. WRITE(numout,*) ' meridional grid-spacing (degrees) ppe2_deg = ', ppe2_deg
  268. WRITE(numout,*) ' zonal grid-spacing (degrees) ppe1_m = ', ppe1_m
  269. WRITE(numout,*) ' meridional grid-spacing (degrees) ppe2_m = ', ppe2_m
  270. WRITE(numout,*) ' ORCA r4, r2 and r05 coefficients ppsur = ', ppsur
  271. WRITE(numout,*) ' ppa0 = ', ppa0
  272. WRITE(numout,*) ' ppa1 = ', ppa1
  273. WRITE(numout,*) ' ppkth = ', ppkth
  274. WRITE(numout,*) ' ppacr = ', ppacr
  275. WRITE(numout,*) ' Minimum vertical spacing ppdzmin = ', ppdzmin
  276. WRITE(numout,*) ' Maximum depth pphmax = ', pphmax
  277. WRITE(numout,*) ' Use double tanf function for vertical coordinates ldbletanh = ', ldbletanh
  278. WRITE(numout,*) ' Double tanh function parameters ppa2 = ', ppa2
  279. WRITE(numout,*) ' ppkth2 = ', ppkth2
  280. WRITE(numout,*) ' ppacr2 = ', ppacr2
  281. ENDIF
  282. ntopo = nn_bathy ! conversion DOCTOR names into model names (this should disappear soon)
  283. e3zps_min = rn_e3zps_min
  284. e3zps_rat = rn_e3zps_rat
  285. nmsh = nn_msh
  286. nacc = nn_acc
  287. atfp = rn_atfp
  288. rdt = rn_rdt
  289. rdtmin = rn_rdtmin
  290. rdtmax = rn_rdtmin
  291. rdth = rn_rdth
  292. REWIND( numnam_ref ) ! Namelist namcla in reference namelist : Cross land advection
  293. READ ( numnam_ref, namcla, IOSTAT = ios, ERR = 905)
  294. 905 IF( ios /= 0 ) CALL ctl_nam ( ios , 'namcla in reference namelist', lwp )
  295. REWIND( numnam_cfg ) ! Namelist namcla in configuration namelist : Cross land advection
  296. READ ( numnam_cfg, namcla, IOSTAT = ios, ERR = 906 )
  297. 906 IF( ios /= 0 ) CALL ctl_nam ( ios , 'namcla in configuration namelist', lwp )
  298. IF(lwm) WRITE( numond, namcla )
  299. IF(lwp) THEN
  300. WRITE(numout,*)
  301. WRITE(numout,*) ' Namelist namcla'
  302. WRITE(numout,*) ' cross land advection nn_cla = ', nn_cla
  303. ENDIF
  304. IF ( nn_cla .EQ. 1 ) THEN
  305. IF ( cp_cfg == "orca" .AND. jp_cfg == 2 ) THEN ! ORCA R2
  306. CONTINUE
  307. ELSE
  308. CALL ctl_stop( 'STOP', 'Cross land advation iplemented only for ORCA2 configuration: cp_cfg = "orca" and jp_cfg = 2 ' )
  309. ENDIF
  310. ENDIF
  311. #if defined key_netcdf4
  312. ! ! NetCDF 4 case ("key_netcdf4" defined)
  313. REWIND( numnam_ref ) ! Namelist namnc4 in reference namelist : NETCDF
  314. READ ( numnam_ref, namnc4, IOSTAT = ios, ERR = 907)
  315. 907 IF( ios /= 0 ) CALL ctl_nam ( ios , 'namnc4 in reference namelist', lwp )
  316. REWIND( numnam_cfg ) ! Namelist namnc4 in configuration namelist : NETCDF
  317. READ ( numnam_cfg, namnc4, IOSTAT = ios, ERR = 908 )
  318. 908 IF( ios /= 0 ) CALL ctl_nam ( ios , 'namnc4 in configuration namelist', lwp )
  319. IF(lwm) WRITE( numond, namnc4 )
  320. IF(lwp) THEN ! control print
  321. WRITE(numout,*)
  322. WRITE(numout,*) ' Namelist namnc4 - Netcdf4 chunking parameters'
  323. WRITE(numout,*) ' number of chunks in i-dimension nn_nchunks_i = ', nn_nchunks_i
  324. WRITE(numout,*) ' number of chunks in j-dimension nn_nchunks_j = ', nn_nchunks_j
  325. WRITE(numout,*) ' number of chunks in k-dimension nn_nchunks_k = ', nn_nchunks_k
  326. WRITE(numout,*) ' apply netcdf4/hdf5 chunking & compression ln_nc4zip = ', ln_nc4zip
  327. ENDIF
  328. ! Put the netcdf4 settings into a simple structure (snc4set, defined in in_out_manager module)
  329. ! Note the chunk size in the unlimited (time) dimension will be fixed at 1
  330. snc4set%ni = nn_nchunks_i
  331. snc4set%nj = nn_nchunks_j
  332. snc4set%nk = nn_nchunks_k
  333. snc4set%luse = ln_nc4zip
  334. #else
  335. snc4set%luse = .FALSE. ! No NetCDF 4 case
  336. #endif
  337. !
  338. END SUBROUTINE dom_nam
  339. SUBROUTINE dom_ctl
  340. !!----------------------------------------------------------------------
  341. !! *** ROUTINE dom_ctl ***
  342. !!
  343. !! ** Purpose : Domain control.
  344. !!
  345. !! ** Method : compute and print extrema of masked scale factors
  346. !!----------------------------------------------------------------------
  347. INTEGER :: iimi1, ijmi1, iimi2, ijmi2, iima1, ijma1, iima2, ijma2
  348. INTEGER, DIMENSION(2) :: iloc !
  349. REAL(wp) :: ze1min, ze1max, ze2min, ze2max
  350. !!----------------------------------------------------------------------
  351. !
  352. IF(lk_mpp) THEN
  353. CALL mpp_minloc( e1t(:,:), tmask_i(:,:), ze1min, iimi1,ijmi1 )
  354. CALL mpp_minloc( e2t(:,:), tmask_i(:,:), ze2min, iimi2,ijmi2 )
  355. CALL mpp_maxloc( e1t(:,:), tmask_i(:,:), ze1max, iima1,ijma1 )
  356. CALL mpp_maxloc( e2t(:,:), tmask_i(:,:), ze2max, iima2,ijma2 )
  357. ELSE
  358. ze1min = MINVAL( e1t(:,:), mask = tmask_i(:,:) == 1._wp )
  359. ze2min = MINVAL( e2t(:,:), mask = tmask_i(:,:) == 1._wp )
  360. ze1max = MAXVAL( e1t(:,:), mask = tmask_i(:,:) == 1._wp )
  361. ze2max = MAXVAL( e2t(:,:), mask = tmask_i(:,:) == 1._wp )
  362. iloc = MINLOC( e1t(:,:), mask = tmask_i(:,:) == 1._wp )
  363. iimi1 = iloc(1) + nimpp - 1
  364. ijmi1 = iloc(2) + njmpp - 1
  365. iloc = MINLOC( e2t(:,:), mask = tmask_i(:,:) == 1._wp )
  366. iimi2 = iloc(1) + nimpp - 1
  367. ijmi2 = iloc(2) + njmpp - 1
  368. iloc = MAXLOC( e1t(:,:), mask = tmask_i(:,:) == 1._wp )
  369. iima1 = iloc(1) + nimpp - 1
  370. ijma1 = iloc(2) + njmpp - 1
  371. iloc = MAXLOC( e2t(:,:), mask = tmask_i(:,:) == 1._wp )
  372. iima2 = iloc(1) + nimpp - 1
  373. ijma2 = iloc(2) + njmpp - 1
  374. ENDIF
  375. IF(lwp) THEN
  376. WRITE(numout,*)
  377. WRITE(numout,*) 'dom_ctl : extrema of the masked scale factors'
  378. WRITE(numout,*) '~~~~~~~'
  379. WRITE(numout,"(14x,'e1t maxi: ',1f10.2,' at i = ',i5,' j= ',i5)") ze1max, iima1, ijma1
  380. WRITE(numout,"(14x,'e1t mini: ',1f10.2,' at i = ',i5,' j= ',i5)") ze1min, iimi1, ijmi1
  381. WRITE(numout,"(14x,'e2t maxi: ',1f10.2,' at i = ',i5,' j= ',i5)") ze2max, iima2, ijma2
  382. WRITE(numout,"(14x,'e2t mini: ',1f10.2,' at i = ',i5,' j= ',i5)") ze2min, iimi2, ijmi2
  383. ENDIF
  384. !
  385. END SUBROUTINE dom_ctl
  386. SUBROUTINE dom_stiff
  387. !!----------------------------------------------------------------------
  388. !! *** ROUTINE dom_stiff ***
  389. !!
  390. !! ** Purpose : Diagnose maximum grid stiffness/hydrostatic consistency
  391. !!
  392. !! ** Method : Compute Haney (1991) hydrostatic condition ratio
  393. !! Save the maximum in the vertical direction
  394. !! (this number is only relevant in s-coordinates)
  395. !!
  396. !! Haney, R. L., 1991: On the pressure gradient force
  397. !! over steep topography in sigma coordinate ocean models.
  398. !! J. Phys. Oceanogr., 21, 610???619.
  399. !!----------------------------------------------------------------------
  400. INTEGER :: ji, jj, jk
  401. REAL(wp) :: zrxmax
  402. REAL(wp), DIMENSION(4) :: zr1
  403. !!----------------------------------------------------------------------
  404. rx1(:,:) = 0.e0
  405. zrxmax = 0.e0
  406. zr1(:) = 0.e0
  407. DO ji = 2, jpim1
  408. DO jj = 2, jpjm1
  409. DO jk = 1, jpkm1
  410. zr1(1) = umask(ji-1,jj ,jk) *abs( (gdepw_0(ji ,jj ,jk )-gdepw_0(ji-1,jj ,jk ) &
  411. & +gdepw_0(ji ,jj ,jk+1)-gdepw_0(ji-1,jj ,jk+1)) &
  412. & /(gdepw_0(ji ,jj ,jk )+gdepw_0(ji-1,jj ,jk ) &
  413. & -gdepw_0(ji ,jj ,jk+1)-gdepw_0(ji-1,jj ,jk+1) + rsmall) )
  414. zr1(2) = umask(ji ,jj ,jk) *abs( (gdepw_0(ji+1,jj ,jk )-gdepw_0(ji ,jj ,jk ) &
  415. & +gdepw_0(ji+1,jj ,jk+1)-gdepw_0(ji ,jj ,jk+1)) &
  416. & /(gdepw_0(ji+1,jj ,jk )+gdepw_0(ji ,jj ,jk ) &
  417. & -gdepw_0(ji+1,jj ,jk+1)-gdepw_0(ji ,jj ,jk+1) + rsmall) )
  418. zr1(3) = vmask(ji ,jj ,jk) *abs( (gdepw_0(ji ,jj+1,jk )-gdepw_0(ji ,jj ,jk ) &
  419. & +gdepw_0(ji ,jj+1,jk+1)-gdepw_0(ji ,jj ,jk+1)) &
  420. & /(gdepw_0(ji ,jj+1,jk )+gdepw_0(ji ,jj ,jk ) &
  421. & -gdepw_0(ji ,jj+1,jk+1)-gdepw_0(ji ,jj ,jk+1) + rsmall) )
  422. zr1(4) = vmask(ji ,jj-1,jk) *abs( (gdepw_0(ji ,jj ,jk )-gdepw_0(ji ,jj-1,jk ) &
  423. & +gdepw_0(ji ,jj ,jk+1)-gdepw_0(ji ,jj-1,jk+1)) &
  424. & /(gdepw_0(ji ,jj ,jk )+gdepw_0(ji ,jj-1,jk ) &
  425. & -gdepw_0(ji, jj ,jk+1)-gdepw_0(ji ,jj-1,jk+1) + rsmall) )
  426. zrxmax = MAXVAL(zr1(1:4))
  427. rx1(ji,jj) = MAX(rx1(ji,jj), zrxmax)
  428. END DO
  429. END DO
  430. END DO
  431. CALL lbc_lnk( rx1, 'T', 1. )
  432. zrxmax = MAXVAL(rx1)
  433. IF( lk_mpp ) CALL mpp_max( zrxmax ) ! max over the global domain
  434. IF(lwp) THEN
  435. WRITE(numout,*)
  436. WRITE(numout,*) 'dom_stiff : maximum grid stiffness ratio: ', zrxmax
  437. WRITE(numout,*) '~~~~~~~~~'
  438. ENDIF
  439. END SUBROUTINE dom_stiff
  440. !!======================================================================
  441. END MODULE domain