domain.F90 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480
  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 7522 2017-01-02 10:06:49Z cetlod $
  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, ln_mskutil
  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,*) ' output without halos ln_mskutil = ', ln_mskutil
  185. WRITE(numout,*) ' additional CF standard metadata ln_cfmeta = ', ln_cfmeta
  186. WRITE(numout,*) ' overwrite an existing file ln_clobber = ', ln_clobber
  187. WRITE(numout,*) ' NetCDF chunksize (bytes) nn_chunksz = ', nn_chunksz
  188. ENDIF
  189. no = nn_no ! conversion DOCTOR names into model names (this should disappear soon)
  190. cexper = cn_exp
  191. nrstdt = nn_rstctl
  192. nit000 = nn_it000
  193. nitend = nn_itend
  194. ndate0 = nn_date0
  195. nleapy = nn_leapy
  196. ninist = nn_istate
  197. nstock = nn_stock
  198. nstocklist = nn_stocklist
  199. nwrite = nn_write
  200. neuler = nn_euler
  201. IF ( neuler == 1 .AND. .NOT. ln_rstart ) THEN
  202. WRITE(ctmp1,*) 'ln_rstart =.FALSE., nn_euler is forced to 0 '
  203. CALL ctl_warn( ctmp1 )
  204. neuler = 0
  205. ENDIF
  206. ! ! control of output frequency
  207. IF ( nstock == 0 .OR. nstock > nitend ) THEN
  208. WRITE(ctmp1,*) 'nstock = ', nstock, ' it is forced to ', nitend
  209. CALL ctl_warn( ctmp1 )
  210. nstock = nitend
  211. ENDIF
  212. IF ( nwrite == 0 ) THEN
  213. WRITE(ctmp1,*) 'nwrite = ', nwrite, ' it is forced to ', nitend
  214. CALL ctl_warn( ctmp1 )
  215. nwrite = nitend
  216. ENDIF
  217. #if defined key_agrif
  218. IF( Agrif_Root() ) THEN
  219. #endif
  220. SELECT CASE ( nleapy ) ! Choose calendar for IOIPSL
  221. CASE ( 1 )
  222. CALL ioconf_calendar('gregorian')
  223. IF(lwp) WRITE(numout,*) ' The IOIPSL calendar is "gregorian", i.e. leap year'
  224. CASE ( 0 )
  225. CALL ioconf_calendar('noleap')
  226. IF(lwp) WRITE(numout,*) ' The IOIPSL calendar is "noleap", i.e. no leap year'
  227. CASE ( 30 )
  228. CALL ioconf_calendar('360d')
  229. IF(lwp) WRITE(numout,*) ' The IOIPSL calendar is "360d", i.e. 360 days in a year'
  230. END SELECT
  231. #if defined key_agrif
  232. ENDIF
  233. #endif
  234. REWIND( numnam_ref ) ! Namelist namdom in reference namelist : space & time domain (bathymetry, mesh, timestep)
  235. READ ( numnam_ref, namdom, IOSTAT = ios, ERR = 903)
  236. 903 IF( ios /= 0 ) CALL ctl_nam ( ios , 'namdom in reference namelist', lwp )
  237. !
  238. REWIND( numnam_cfg ) ! Namelist namdom in configuration namelist : space & time domain (bathymetry, mesh, timestep)
  239. READ ( numnam_cfg, namdom, IOSTAT = ios, ERR = 904 )
  240. 904 IF( ios /= 0 ) CALL ctl_nam ( ios , 'namdom in configuration namelist', lwp )
  241. IF(lwm) WRITE ( numond, namdom )
  242. IF(lwp) THEN
  243. WRITE(numout,*)
  244. WRITE(numout,*) ' Namelist namdom : space & time domain'
  245. WRITE(numout,*) ' flag read/compute bathymetry nn_bathy = ', nn_bathy
  246. WRITE(numout,*) ' Depth (if =0 bathy=jpkm1) rn_bathy = ', rn_bathy
  247. WRITE(numout,*) ' min depth of the ocean (>0) or rn_hmin = ', rn_hmin
  248. WRITE(numout,*) ' min number of ocean level (<0) '
  249. WRITE(numout,*) ' minimum thickness of partial rn_e3zps_min = ', rn_e3zps_min, ' (m)'
  250. WRITE(numout,*) ' step level rn_e3zps_rat = ', rn_e3zps_rat
  251. WRITE(numout,*) ' create mesh/mask file(s) nn_msh = ', nn_msh
  252. WRITE(numout,*) ' = 0 no file created '
  253. WRITE(numout,*) ' = 1 mesh_mask '
  254. WRITE(numout,*) ' = 2 mesh and mask '
  255. WRITE(numout,*) ' = 3 mesh_hgr, msh_zgr and mask'
  256. WRITE(numout,*) ' ocean time step rn_rdt = ', rn_rdt
  257. WRITE(numout,*) ' asselin time filter parameter rn_atfp = ', rn_atfp
  258. WRITE(numout,*) ' acceleration of converge nn_acc = ', nn_acc
  259. WRITE(numout,*) ' nn_acc=1: surface tracer rdt rn_rdtmin = ', rn_rdtmin
  260. WRITE(numout,*) ' bottom tracer rdt rdtmax = ', rn_rdtmax
  261. WRITE(numout,*) ' depth of transition rn_rdth = ', rn_rdth
  262. WRITE(numout,*) ' suppression of closed seas (=0) nn_closea = ', nn_closea
  263. WRITE(numout,*) ' online coarsening of dynamical fields ln_crs = ', ln_crs
  264. WRITE(numout,*) ' type of horizontal mesh jphgr_msh = ', jphgr_msh
  265. WRITE(numout,*) ' longitude of first raw and column T-point ppglam0 = ', ppglam0
  266. WRITE(numout,*) ' latitude of first raw and column T-point ppgphi0 = ', ppgphi0
  267. WRITE(numout,*) ' zonal grid-spacing (degrees) ppe1_deg = ', ppe1_deg
  268. WRITE(numout,*) ' meridional grid-spacing (degrees) ppe2_deg = ', ppe2_deg
  269. WRITE(numout,*) ' zonal grid-spacing (degrees) ppe1_m = ', ppe1_m
  270. WRITE(numout,*) ' meridional grid-spacing (degrees) ppe2_m = ', ppe2_m
  271. WRITE(numout,*) ' ORCA r4, r2 and r05 coefficients ppsur = ', ppsur
  272. WRITE(numout,*) ' ppa0 = ', ppa0
  273. WRITE(numout,*) ' ppa1 = ', ppa1
  274. WRITE(numout,*) ' ppkth = ', ppkth
  275. WRITE(numout,*) ' ppacr = ', ppacr
  276. WRITE(numout,*) ' Minimum vertical spacing ppdzmin = ', ppdzmin
  277. WRITE(numout,*) ' Maximum depth pphmax = ', pphmax
  278. WRITE(numout,*) ' Use double tanf function for vertical coordinates ldbletanh = ', ldbletanh
  279. WRITE(numout,*) ' Double tanh function parameters ppa2 = ', ppa2
  280. WRITE(numout,*) ' ppkth2 = ', ppkth2
  281. WRITE(numout,*) ' ppacr2 = ', ppacr2
  282. ENDIF
  283. ntopo = nn_bathy ! conversion DOCTOR names into model names (this should disappear soon)
  284. e3zps_min = rn_e3zps_min
  285. e3zps_rat = rn_e3zps_rat
  286. nmsh = nn_msh
  287. nacc = nn_acc
  288. atfp = rn_atfp
  289. rdt = rn_rdt
  290. rdtmin = rn_rdtmin
  291. rdtmax = rn_rdtmin
  292. rdth = rn_rdth
  293. REWIND( numnam_ref ) ! Namelist namcla in reference namelist : Cross land advection
  294. READ ( numnam_ref, namcla, IOSTAT = ios, ERR = 905)
  295. 905 IF( ios /= 0 ) CALL ctl_nam ( ios , 'namcla in reference namelist', lwp )
  296. REWIND( numnam_cfg ) ! Namelist namcla in configuration namelist : Cross land advection
  297. READ ( numnam_cfg, namcla, IOSTAT = ios, ERR = 906 )
  298. 906 IF( ios /= 0 ) CALL ctl_nam ( ios , 'namcla in configuration namelist', lwp )
  299. IF(lwm) WRITE( numond, namcla )
  300. IF(lwp) THEN
  301. WRITE(numout,*)
  302. WRITE(numout,*) ' Namelist namcla'
  303. WRITE(numout,*) ' cross land advection nn_cla = ', nn_cla
  304. ENDIF
  305. IF ( nn_cla .EQ. 1 ) THEN
  306. IF ( cp_cfg == "orca" .AND. jp_cfg == 2 ) THEN ! ORCA R2
  307. CONTINUE
  308. ELSE
  309. CALL ctl_stop( 'STOP', 'Cross land advation iplemented only for ORCA2 configuration: cp_cfg = "orca" and jp_cfg = 2 ' )
  310. ENDIF
  311. ENDIF
  312. #if defined key_netcdf4
  313. ! ! NetCDF 4 case ("key_netcdf4" defined)
  314. REWIND( numnam_ref ) ! Namelist namnc4 in reference namelist : NETCDF
  315. READ ( numnam_ref, namnc4, IOSTAT = ios, ERR = 907)
  316. 907 IF( ios /= 0 ) CALL ctl_nam ( ios , 'namnc4 in reference namelist', lwp )
  317. REWIND( numnam_cfg ) ! Namelist namnc4 in configuration namelist : NETCDF
  318. READ ( numnam_cfg, namnc4, IOSTAT = ios, ERR = 908 )
  319. 908 IF( ios /= 0 ) CALL ctl_nam ( ios , 'namnc4 in configuration namelist', lwp )
  320. IF(lwm) WRITE( numond, namnc4 )
  321. IF(lwp) THEN ! control print
  322. WRITE(numout,*)
  323. WRITE(numout,*) ' Namelist namnc4 - Netcdf4 chunking parameters'
  324. WRITE(numout,*) ' number of chunks in i-dimension nn_nchunks_i = ', nn_nchunks_i
  325. WRITE(numout,*) ' number of chunks in j-dimension nn_nchunks_j = ', nn_nchunks_j
  326. WRITE(numout,*) ' number of chunks in k-dimension nn_nchunks_k = ', nn_nchunks_k
  327. WRITE(numout,*) ' apply netcdf4/hdf5 chunking & compression ln_nc4zip = ', ln_nc4zip
  328. ENDIF
  329. ! Put the netcdf4 settings into a simple structure (snc4set, defined in in_out_manager module)
  330. ! Note the chunk size in the unlimited (time) dimension will be fixed at 1
  331. snc4set%ni = nn_nchunks_i
  332. snc4set%nj = nn_nchunks_j
  333. snc4set%nk = nn_nchunks_k
  334. snc4set%luse = ln_nc4zip
  335. #else
  336. snc4set%luse = .FALSE. ! No NetCDF 4 case
  337. #endif
  338. !
  339. END SUBROUTINE dom_nam
  340. SUBROUTINE dom_ctl
  341. !!----------------------------------------------------------------------
  342. !! *** ROUTINE dom_ctl ***
  343. !!
  344. !! ** Purpose : Domain control.
  345. !!
  346. !! ** Method : compute and print extrema of masked scale factors
  347. !!----------------------------------------------------------------------
  348. INTEGER :: iimi1, ijmi1, iimi2, ijmi2, iima1, ijma1, iima2, ijma2
  349. INTEGER, DIMENSION(2) :: iloc !
  350. REAL(wp) :: ze1min, ze1max, ze2min, ze2max
  351. !!----------------------------------------------------------------------
  352. !
  353. IF(lk_mpp) THEN
  354. CALL mpp_minloc( e1t(:,:), tmask_i(:,:), ze1min, iimi1,ijmi1 )
  355. CALL mpp_minloc( e2t(:,:), tmask_i(:,:), ze2min, iimi2,ijmi2 )
  356. CALL mpp_maxloc( e1t(:,:), tmask_i(:,:), ze1max, iima1,ijma1 )
  357. CALL mpp_maxloc( e2t(:,:), tmask_i(:,:), ze2max, iima2,ijma2 )
  358. ELSE
  359. ze1min = MINVAL( e1t(:,:), mask = tmask_i(:,:) == 1._wp )
  360. ze2min = MINVAL( e2t(:,:), mask = tmask_i(:,:) == 1._wp )
  361. ze1max = MAXVAL( e1t(:,:), mask = tmask_i(:,:) == 1._wp )
  362. ze2max = MAXVAL( e2t(:,:), mask = tmask_i(:,:) == 1._wp )
  363. iloc = MINLOC( e1t(:,:), mask = tmask_i(:,:) == 1._wp )
  364. iimi1 = iloc(1) + nimpp - 1
  365. ijmi1 = iloc(2) + njmpp - 1
  366. iloc = MINLOC( e2t(:,:), mask = tmask_i(:,:) == 1._wp )
  367. iimi2 = iloc(1) + nimpp - 1
  368. ijmi2 = iloc(2) + njmpp - 1
  369. iloc = MAXLOC( e1t(:,:), mask = tmask_i(:,:) == 1._wp )
  370. iima1 = iloc(1) + nimpp - 1
  371. ijma1 = iloc(2) + njmpp - 1
  372. iloc = MAXLOC( e2t(:,:), mask = tmask_i(:,:) == 1._wp )
  373. iima2 = iloc(1) + nimpp - 1
  374. ijma2 = iloc(2) + njmpp - 1
  375. ENDIF
  376. IF(lwp) THEN
  377. WRITE(numout,*)
  378. WRITE(numout,*) 'dom_ctl : extrema of the masked scale factors'
  379. WRITE(numout,*) '~~~~~~~'
  380. WRITE(numout,"(14x,'e1t maxi: ',1f10.2,' at i = ',i5,' j= ',i5)") ze1max, iima1, ijma1
  381. WRITE(numout,"(14x,'e1t mini: ',1f10.2,' at i = ',i5,' j= ',i5)") ze1min, iimi1, ijmi1
  382. WRITE(numout,"(14x,'e2t maxi: ',1f10.2,' at i = ',i5,' j= ',i5)") ze2max, iima2, ijma2
  383. WRITE(numout,"(14x,'e2t mini: ',1f10.2,' at i = ',i5,' j= ',i5)") ze2min, iimi2, ijmi2
  384. ENDIF
  385. !
  386. END SUBROUTINE dom_ctl
  387. SUBROUTINE dom_stiff
  388. !!----------------------------------------------------------------------
  389. !! *** ROUTINE dom_stiff ***
  390. !!
  391. !! ** Purpose : Diagnose maximum grid stiffness/hydrostatic consistency
  392. !!
  393. !! ** Method : Compute Haney (1991) hydrostatic condition ratio
  394. !! Save the maximum in the vertical direction
  395. !! (this number is only relevant in s-coordinates)
  396. !!
  397. !! Haney, R. L., 1991: On the pressure gradient force
  398. !! over steep topography in sigma coordinate ocean models.
  399. !! J. Phys. Oceanogr., 21, 610???619.
  400. !!----------------------------------------------------------------------
  401. INTEGER :: ji, jj, jk
  402. REAL(wp) :: zrxmax
  403. REAL(wp), DIMENSION(4) :: zr1
  404. !!----------------------------------------------------------------------
  405. rx1(:,:) = 0.e0
  406. zrxmax = 0.e0
  407. zr1(:) = 0.e0
  408. DO ji = 2, jpim1
  409. DO jj = 2, jpjm1
  410. DO jk = 1, jpkm1
  411. zr1(1) = umask(ji-1,jj ,jk) *abs( (gdepw_0(ji ,jj ,jk )-gdepw_0(ji-1,jj ,jk ) &
  412. & +gdepw_0(ji ,jj ,jk+1)-gdepw_0(ji-1,jj ,jk+1)) &
  413. & /(gdepw_0(ji ,jj ,jk )+gdepw_0(ji-1,jj ,jk ) &
  414. & -gdepw_0(ji ,jj ,jk+1)-gdepw_0(ji-1,jj ,jk+1) + rsmall) )
  415. zr1(2) = umask(ji ,jj ,jk) *abs( (gdepw_0(ji+1,jj ,jk )-gdepw_0(ji ,jj ,jk ) &
  416. & +gdepw_0(ji+1,jj ,jk+1)-gdepw_0(ji ,jj ,jk+1)) &
  417. & /(gdepw_0(ji+1,jj ,jk )+gdepw_0(ji ,jj ,jk ) &
  418. & -gdepw_0(ji+1,jj ,jk+1)-gdepw_0(ji ,jj ,jk+1) + rsmall) )
  419. zr1(3) = vmask(ji ,jj ,jk) *abs( (gdepw_0(ji ,jj+1,jk )-gdepw_0(ji ,jj ,jk ) &
  420. & +gdepw_0(ji ,jj+1,jk+1)-gdepw_0(ji ,jj ,jk+1)) &
  421. & /(gdepw_0(ji ,jj+1,jk )+gdepw_0(ji ,jj ,jk ) &
  422. & -gdepw_0(ji ,jj+1,jk+1)-gdepw_0(ji ,jj ,jk+1) + rsmall) )
  423. zr1(4) = vmask(ji ,jj-1,jk) *abs( (gdepw_0(ji ,jj ,jk )-gdepw_0(ji ,jj-1,jk ) &
  424. & +gdepw_0(ji ,jj ,jk+1)-gdepw_0(ji ,jj-1,jk+1)) &
  425. & /(gdepw_0(ji ,jj ,jk )+gdepw_0(ji ,jj-1,jk ) &
  426. & -gdepw_0(ji, jj ,jk+1)-gdepw_0(ji ,jj-1,jk+1) + rsmall) )
  427. zrxmax = MAXVAL(zr1(1:4))
  428. rx1(ji,jj) = MAX(rx1(ji,jj), zrxmax)
  429. END DO
  430. END DO
  431. END DO
  432. CALL lbc_lnk( rx1, 'T', 1. )
  433. zrxmax = MAXVAL(rx1)
  434. IF( lk_mpp ) CALL mpp_max( zrxmax ) ! max over the global domain
  435. IF(lwp) THEN
  436. WRITE(numout,*)
  437. WRITE(numout,*) 'dom_stiff : maximum grid stiffness ratio: ', zrxmax
  438. WRITE(numout,*) '~~~~~~~~~'
  439. ENDIF
  440. END SUBROUTINE dom_stiff
  441. !!======================================================================
  442. END MODULE domain