domhgr.F90 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682
  1. MODULE domhgr
  2. !!==============================================================================
  3. !! *** MODULE domhgr ***
  4. !! Ocean initialization : domain initialization
  5. !!==============================================================================
  6. !! History : OPA ! 1988-03 (G. Madec) Original code
  7. !! 7.0 ! 1996-01 (G. Madec) terrain following coordinates
  8. !! 8.0 ! 1997-02 (G. Madec) print mesh informations
  9. !! 8.1 ! 1999-11 (M. Imbard) NetCDF format with IO-IPSL
  10. !! 8.2 ! 2000-08 (D. Ludicone) Reduced section at Bab el Mandeb
  11. !! - ! 2001-09 (M. Levy) eel config: grid in km, beta-plane
  12. !! NEMO 1.0 ! 2002-08 (G. Madec) F90: Free form and module, namelist
  13. !! - ! 2004-01 (A.M. Treguier, J.M. Molines) Case 4 (Mercator mesh)
  14. !! use of parameters in par_CONFIG-Rxx.h90, not in namelist
  15. !! - ! 2004-05 (A. Koch-Larrouy) Add Gyre configuration
  16. !! 4.0 ! 2011-02 (G. Madec) add cell surface (e1e2t)
  17. !!----------------------------------------------------------------------
  18. !!----------------------------------------------------------------------
  19. !! dom_hgr : initialize the horizontal mesh
  20. !! hgr_read : read "coordinate" NetCDF file
  21. !!----------------------------------------------------------------------
  22. USE dom_oce ! ocean space and time domain
  23. USE phycst ! physical constants
  24. USE in_out_manager ! I/O manager
  25. USE lib_mpp ! MPP library
  26. USE timing ! Timing
  27. IMPLICIT NONE
  28. PRIVATE
  29. REAL(wp) :: glam0, gphi0 ! variables corresponding to parameters ppglam0 ppgphi0 set in par_oce
  30. PUBLIC dom_hgr ! called by domain.F90
  31. !!----------------------------------------------------------------------
  32. !! NEMO/OPA 4.0 , NEMO Consortium (2011)
  33. !! $Id: domhgr.F90 5551 2015-07-06 16:38:51Z acc $
  34. !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
  35. !!----------------------------------------------------------------------
  36. CONTAINS
  37. SUBROUTINE dom_hgr
  38. !!----------------------------------------------------------------------
  39. !! *** ROUTINE dom_hgr ***
  40. !!
  41. !! ** Purpose : Compute the geographical position (in degre) of the
  42. !! model grid-points, the horizontal scale factors (in meters) and
  43. !! the Coriolis factor (in s-1).
  44. !!
  45. !! ** Method : The geographical position of the model grid-points is
  46. !! defined from analytical functions, fslam and fsphi, the deriva-
  47. !! tives of which gives the horizontal scale factors e1,e2.
  48. !! Defining two function fslam and fsphi and their derivatives in
  49. !! the two horizontal directions (fse1 and fse2), the model grid-
  50. !! point position and scale factors are given by:
  51. !! t-point:
  52. !! glamt(i,j) = fslam(i ,j ) e1t(i,j) = fse1(i ,j )
  53. !! gphit(i,j) = fsphi(i ,j ) e2t(i,j) = fse2(i ,j )
  54. !! u-point:
  55. !! glamu(i,j) = fslam(i+1/2,j ) e1u(i,j) = fse1(i+1/2,j )
  56. !! gphiu(i,j) = fsphi(i+1/2,j ) e2u(i,j) = fse2(i+1/2,j )
  57. !! v-point:
  58. !! glamv(i,j) = fslam(i ,j+1/2) e1v(i,j) = fse1(i ,j+1/2)
  59. !! gphiv(i,j) = fsphi(i ,j+1/2) e2v(i,j) = fse2(i ,j+1/2)
  60. !! f-point:
  61. !! glamf(i,j) = fslam(i+1/2,j+1/2) e1f(i,j) = fse1(i+1/2,j+1/2)
  62. !! gphif(i,j) = fsphi(i+1/2,j+1/2) e2f(i,j) = fse2(i+1/2,j+1/2)
  63. !! Where fse1 and fse2 are defined by:
  64. !! fse1(i,j) = ra * rad * SQRT( (cos(phi) di(fslam))**2
  65. !! + di(fsphi) **2 )(i,j)
  66. !! fse2(i,j) = ra * rad * SQRT( (cos(phi) dj(fslam))**2
  67. !! + dj(fsphi) **2 )(i,j)
  68. !!
  69. !! The coriolis factor is given at z-point by:
  70. !! ff = 2.*omega*sin(gphif) (in s-1)
  71. !!
  72. !! This routine is given as an example, it must be modified
  73. !! following the user s desiderata. nevertheless, the output as
  74. !! well as the way to compute the model grid-point position and
  75. !! horizontal scale factors must be respected in order to insure
  76. !! second order accuracy schemes.
  77. !!
  78. !! N.B. If the domain is periodic, verify that scale factors are also
  79. !! periodic, and the coriolis term again.
  80. !!
  81. !! ** Action : - define glamt, glamu, glamv, glamf: longitude of t-,
  82. !! u-, v- and f-points (in degre)
  83. !! - define gphit, gphiu, gphiv, gphit: latitude of t-,
  84. !! u-, v- and f-points (in degre)
  85. !! define e1t, e2t, e1u, e2u, e1v, e2v, e1f, e2f: horizontal
  86. !! scale factors (in meters) at t-, u-, v-, and f-points.
  87. !! define ff: coriolis factor at f-point
  88. !!
  89. !! References : Marti, Madec and Delecluse, 1992, JGR
  90. !! Madec, Imbard, 1996, Clim. Dyn.
  91. !!----------------------------------------------------------------------
  92. INTEGER :: ji, jj ! dummy loop indices
  93. INTEGER :: ii0, ii1, ij0, ij1 ! temporary integers
  94. INTEGER :: ijeq ! index of equator T point (used in case 4)
  95. REAL(wp) :: zti, zui, zvi, zfi ! local scalars
  96. REAL(wp) :: ztj, zuj, zvj, zfj ! - -
  97. REAL(wp) :: zphi0, zbeta, znorme !
  98. REAL(wp) :: zarg, zf0, zminff, zmaxff
  99. REAL(wp) :: zlam1, zcos_alpha, zim1 , zjm1 , ze1, ze1deg
  100. REAL(wp) :: zphi1, zsin_alpha, zim05, zjm05
  101. INTEGER :: isrow ! index for ORCA1 starting row
  102. !!----------------------------------------------------------------------
  103. !
  104. IF( nn_timing == 1 ) CALL timing_start('dom_hgr')
  105. !
  106. IF(lwp) THEN
  107. WRITE(numout,*)
  108. WRITE(numout,*) 'dom_hgr : define the horizontal mesh from ithe following par_oce parameters '
  109. WRITE(numout,*) '~~~~~~~ type of horizontal mesh jphgr_msh = ', jphgr_msh
  110. WRITE(numout,*) ' position of the first row and ppglam0 = ', ppglam0
  111. WRITE(numout,*) ' column grid-point (degrees) ppgphi0 = ', ppgphi0
  112. WRITE(numout,*) ' zonal grid-spacing (degrees) ppe1_deg = ', ppe1_deg
  113. WRITE(numout,*) ' meridional grid-spacing (degrees) ppe2_deg = ', ppe2_deg
  114. WRITE(numout,*) ' zonal grid-spacing (meters) ppe1_m = ', ppe1_m
  115. WRITE(numout,*) ' meridional grid-spacing (meters) ppe2_m = ', ppe2_m
  116. ENDIF
  117. SELECT CASE( jphgr_msh ) ! type of horizontal mesh
  118. CASE ( 0 ) ! curvilinear coordinate on the sphere read in coordinate.nc file
  119. IF(lwp) WRITE(numout,*)
  120. IF(lwp) WRITE(numout,*) ' curvilinear coordinate on the sphere read in "coordinate" file'
  121. CALL hgr_read ! Defaultl option : NetCDF file
  122. ! ! =====================
  123. IF( cp_cfg == "orca" .AND. jp_cfg == 2 ) THEN ! ORCA R2 configuration
  124. ! ! =====================
  125. IF( nn_cla == 0 ) THEN
  126. !
  127. ii0 = 139 ; ii1 = 140 ! Gibraltar Strait (e2u = 20 km)
  128. ij0 = 102 ; ij1 = 102 ; e2u( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 20.e3
  129. IF(lwp) WRITE(numout,*)
  130. IF(lwp) WRITE(numout,*) ' orca_r2: Gibraltar : e2u reduced to 20 km'
  131. !
  132. ii0 = 160 ; ii1 = 160 ! Bab el Mandeb (e2u = 18 km)
  133. ij0 = 88 ; ij1 = 88 ; e1v( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 18.e3
  134. e2u( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 30.e3
  135. IF(lwp) WRITE(numout,*)
  136. IF(lwp) WRITE(numout,*) ' orca_r2: Bab el Mandeb: e2u reduced to 30 km'
  137. IF(lwp) WRITE(numout,*) ' e1v reduced to 18 km'
  138. ENDIF
  139. ii0 = 145 ; ii1 = 146 ! Danish Straits (e2u = 10 km)
  140. ij0 = 116 ; ij1 = 116 ; e2u( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 10.e3
  141. IF(lwp) WRITE(numout,*)
  142. IF(lwp) WRITE(numout,*) ' orca_r2: Danish Straits : e2u reduced to 10 km'
  143. !
  144. ENDIF
  145. ! ! =====================
  146. IF( cp_cfg == "orca" .AND. jp_cfg == 1 ) THEN ! ORCA R1 configuration
  147. ! ! =====================
  148. ! This dirty section will be suppressed by simplification process: all this will come back in input files
  149. ! Currently these hard-wired indices relate to configuration with
  150. ! extend grid (jpjglo=332)
  151. ! which had a grid-size of 362x292.
  152. !
  153. isrow = 332 - jpjglo
  154. !
  155. ii0 = 282 ; ii1 = 283 ! Gibraltar Strait (e2u = 20 km)
  156. ij0 = 241 - isrow ; ij1 = 241 - isrow ; e2u( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 20.e3
  157. IF(lwp) WRITE(numout,*)
  158. IF(lwp) WRITE(numout,*) ' orca_r1: Gibraltar : e2u reduced to 20 km'
  159. ii0 = 314 ; ii1 = 315 ! Bhosporus Strait (e2u = 10 km)
  160. ij0 = 248 - isrow ; ij1 = 248 - isrow ; e2u( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 10.e3
  161. IF(lwp) WRITE(numout,*)
  162. IF(lwp) WRITE(numout,*) ' orca_r1: Bhosporus : e2u reduced to 10 km'
  163. ii0 = 44 ; ii1 = 44 ! Lombok Strait (e1v = 13 km)
  164. ij0 = 164 - isrow ; ij1 = 165 - isrow ; e1v( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 13.e3
  165. IF(lwp) WRITE(numout,*)
  166. IF(lwp) WRITE(numout,*) ' orca_r1: Lombok : e1v reduced to 10 km'
  167. ii0 = 48 ; ii1 = 48 ! Sumba Strait (e1v = 8 km) [closed from bathy_11 on]
  168. ij0 = 164 - isrow ; ij1 = 165 - isrow ; e1v( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 8.e3
  169. IF(lwp) WRITE(numout,*)
  170. IF(lwp) WRITE(numout,*) ' orca_r1: Sumba : e1v reduced to 8 km'
  171. ii0 = 53 ; ii1 = 53 ! Ombai Strait (e1v = 13 km)
  172. ij0 = 164 - isrow ; ij1 = 165 - isrow ; e1v( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 13.e3
  173. IF(lwp) WRITE(numout,*)
  174. IF(lwp) WRITE(numout,*) ' orca_r1: Ombai : e1v reduced to 13 km'
  175. ii0 = 56 ; ii1 = 56 ! Timor Passage (e1v = 20 km)
  176. ij0 = 164 - isrow ; ij1 = 145 - isrow ; e1v( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 20.e3
  177. IF(lwp) WRITE(numout,*)
  178. IF(lwp) WRITE(numout,*) ' orca_r1: Timor Passage : e1v reduced to 20 km'
  179. ii0 = 55 ; ii1 = 55 ! West Halmahera Strait (e1v = 30 km)
  180. ij0 = 181 - isrow ; ij1 = 182 - isrow ; e1v( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 30.e3
  181. IF(lwp) WRITE(numout,*)
  182. IF(lwp) WRITE(numout,*) ' orca_r1: W Halmahera : e1v reduced to 30 km'
  183. ii0 = 58 ; ii1 = 58 ! East Halmahera Strait (e1v = 50 km)
  184. ij0 = 181 - isrow ; ij1 = 182 - isrow ; e1v( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 50.e3
  185. IF(lwp) WRITE(numout,*)
  186. IF(lwp) WRITE(numout,*) ' orca_r1: E Halmahera : e1v reduced to 50 km'
  187. !
  188. !
  189. ENDIF
  190. ! ! ======================
  191. IF( cp_cfg == "orca" .AND. jp_cfg == 05 ) THEN ! ORCA R05 configuration
  192. ! ! ======================
  193. ii0 = 563 ; ii1 = 564 ! Gibraltar Strait (e2u = 20 km)
  194. ij0 = 327 ; ij1 = 327 ; e2u( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 20.e3
  195. IF(lwp) WRITE(numout,*)
  196. IF(lwp) WRITE(numout,*) ' orca_r05: Reduced e2u at the Gibraltar Strait'
  197. !
  198. ii0 = 627 ; ii1 = 628 ! Bosphore Strait (e2u = 10 km)
  199. ij0 = 343 ; ij1 = 343 ; e2u( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 10.e3
  200. IF(lwp) WRITE(numout,*)
  201. IF(lwp) WRITE(numout,*) ' orca_r05: Reduced e2u at the Bosphore Strait'
  202. !
  203. ii0 = 93 ; ii1 = 94 ! Sumba Strait (e2u = 40 km)
  204. ij0 = 232 ; ij1 = 232 ; e2u( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 40.e3
  205. IF(lwp) WRITE(numout,*)
  206. IF(lwp) WRITE(numout,*) ' orca_r05: Reduced e2u at the Sumba Strait'
  207. !
  208. ii0 = 103 ; ii1 = 103 ! Ombai Strait (e2u = 15 km)
  209. ij0 = 232 ; ij1 = 232 ; e2u( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 15.e3
  210. IF(lwp) WRITE(numout,*)
  211. IF(lwp) WRITE(numout,*) ' orca_r05: Reduced e2u at the Ombai Strait'
  212. !
  213. ii0 = 15 ; ii1 = 15 ! Palk Strait (e2u = 10 km)
  214. ij0 = 270 ; ij1 = 270 ; e2u( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 10.e3
  215. IF(lwp) WRITE(numout,*)
  216. IF(lwp) WRITE(numout,*) ' orca_r05: Reduced e2u at the Palk Strait'
  217. !
  218. ii0 = 87 ; ii1 = 87 ! Lombok Strait (e1v = 10 km)
  219. ij0 = 232 ; ij1 = 233 ; e1v( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 10.e3
  220. IF(lwp) WRITE(numout,*)
  221. IF(lwp) WRITE(numout,*) ' orca_r05: Reduced e1v at the Lombok Strait'
  222. !
  223. !
  224. ii0 = 662 ; ii1 = 662 ! Bab el Mandeb (e1v = 25 km)
  225. ij0 = 276 ; ij1 = 276 ; e1v( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 25.e3
  226. IF(lwp) WRITE(numout,*)
  227. IF(lwp) WRITE(numout,*) ' orca_r05: Reduced e1v at the Bab el Mandeb'
  228. !
  229. ENDIF
  230. ! N.B. : General case, lat and long function of both i and j indices:
  231. ! e1t(ji,jj) = ra * rad * SQRT( ( cos( rad*gphit(ji,jj) ) * fsdila( zti, ztj ) )**2 &
  232. ! + ( fsdiph( zti, ztj ) )**2 )
  233. ! e1u(ji,jj) = ra * rad * SQRT( ( cos( rad*gphiu(ji,jj) ) * fsdila( zui, zuj ) )**2 &
  234. ! + ( fsdiph( zui, zuj ) )**2 )
  235. ! e1v(ji,jj) = ra * rad * SQRT( ( cos( rad*gphiv(ji,jj) ) * fsdila( zvi, zvj ) )**2 &
  236. ! + ( fsdiph( zvi, zvj ) )**2 )
  237. ! e1f(ji,jj) = ra * rad * SQRT( ( cos( rad*gphif(ji,jj) ) * fsdila( zfi, zfj ) )**2 &
  238. ! + ( fsdiph( zfi, zfj ) )**2 )
  239. !
  240. ! e2t(ji,jj) = ra * rad * SQRT( ( cos( rad*gphit(ji,jj) ) * fsdjla( zti, ztj ) )**2 &
  241. ! + ( fsdjph( zti, ztj ) )**2 )
  242. ! e2u(ji,jj) = ra * rad * SQRT( ( cos( rad*gphiu(ji,jj) ) * fsdjla( zui, zuj ) )**2 &
  243. ! + ( fsdjph( zui, zuj ) )**2 )
  244. ! e2v(ji,jj) = ra * rad * SQRT( ( cos( rad*gphiv(ji,jj) ) * fsdjla( zvi, zvj ) )**2 &
  245. ! + ( fsdjph( zvi, zvj ) )**2 )
  246. ! e2f(ji,jj) = ra * rad * SQRT( ( cos( rad*gphif(ji,jj) ) * fsdjla( zfi, zfj ) )**2 &
  247. ! + ( fsdjph( zfi, zfj ) )**2 )
  248. CASE ( 1 ) ! geographical mesh on the sphere with regular grid-spacing
  249. IF(lwp) WRITE(numout,*)
  250. IF(lwp) WRITE(numout,*) ' geographical mesh on the sphere with regular grid-spacing'
  251. IF(lwp) WRITE(numout,*) ' given by ppe1_deg and ppe2_deg'
  252. DO jj = 1, jpj
  253. DO ji = 1, jpi
  254. zti = FLOAT( ji - 1 + nimpp - 1 ) ; ztj = FLOAT( jj - 1 + njmpp - 1 )
  255. zui = FLOAT( ji - 1 + nimpp - 1 ) + 0.5 ; zuj = FLOAT( jj - 1 + njmpp - 1 )
  256. zvi = FLOAT( ji - 1 + nimpp - 1 ) ; zvj = FLOAT( jj - 1 + njmpp - 1 ) + 0.5
  257. zfi = FLOAT( ji - 1 + nimpp - 1 ) + 0.5 ; zfj = FLOAT( jj - 1 + njmpp - 1 ) + 0.5
  258. ! Longitude
  259. glamt(ji,jj) = ppglam0 + ppe1_deg * zti
  260. glamu(ji,jj) = ppglam0 + ppe1_deg * zui
  261. glamv(ji,jj) = ppglam0 + ppe1_deg * zvi
  262. glamf(ji,jj) = ppglam0 + ppe1_deg * zfi
  263. ! Latitude
  264. gphit(ji,jj) = ppgphi0 + ppe2_deg * ztj
  265. gphiu(ji,jj) = ppgphi0 + ppe2_deg * zuj
  266. gphiv(ji,jj) = ppgphi0 + ppe2_deg * zvj
  267. gphif(ji,jj) = ppgphi0 + ppe2_deg * zfj
  268. ! e1
  269. e1t(ji,jj) = ra * rad * COS( rad * gphit(ji,jj) ) * ppe1_deg
  270. e1u(ji,jj) = ra * rad * COS( rad * gphiu(ji,jj) ) * ppe1_deg
  271. e1v(ji,jj) = ra * rad * COS( rad * gphiv(ji,jj) ) * ppe1_deg
  272. e1f(ji,jj) = ra * rad * COS( rad * gphif(ji,jj) ) * ppe1_deg
  273. ! e2
  274. e2t(ji,jj) = ra * rad * ppe2_deg
  275. e2u(ji,jj) = ra * rad * ppe2_deg
  276. e2v(ji,jj) = ra * rad * ppe2_deg
  277. e2f(ji,jj) = ra * rad * ppe2_deg
  278. END DO
  279. END DO
  280. CASE ( 2:3 ) ! f- or beta-plane with regular grid-spacing
  281. IF(lwp) WRITE(numout,*)
  282. IF(lwp) WRITE(numout,*) ' f- or beta-plane with regular grid-spacing'
  283. IF(lwp) WRITE(numout,*) ' given by ppe1_m and ppe2_m'
  284. ! Position coordinates (in kilometers)
  285. ! ==========
  286. glam0 = 0.e0
  287. gphi0 = - ppe2_m * 1.e-3
  288. #if defined key_agrif
  289. IF ( cp_cfg == 'eel' .AND. jp_cfg == 6 ) THEN ! for EEL6 configuration only
  290. IF( .NOT. Agrif_Root() ) THEN
  291. glam0 = Agrif_Parent(glam0) + (Agrif_ix())*Agrif_Parent(ppe1_m) * 1.e-3
  292. gphi0 = Agrif_Parent(gphi0) + (Agrif_iy())*Agrif_Parent(ppe2_m) * 1.e-3
  293. ppe1_m = Agrif_Parent(ppe1_m)/Agrif_Rhox()
  294. ppe2_m = Agrif_Parent(ppe2_m)/Agrif_Rhoy()
  295. ENDIF
  296. ENDIF
  297. #endif
  298. DO jj = 1, jpj
  299. DO ji = 1, jpi
  300. glamt(ji,jj) = glam0 + ppe1_m * 1.e-3 * ( FLOAT( ji - 1 + nimpp - 1 ) )
  301. glamu(ji,jj) = glam0 + ppe1_m * 1.e-3 * ( FLOAT( ji - 1 + nimpp - 1 ) + 0.5 )
  302. glamv(ji,jj) = glamt(ji,jj)
  303. glamf(ji,jj) = glamu(ji,jj)
  304. gphit(ji,jj) = gphi0 + ppe2_m * 1.e-3 * ( FLOAT( jj - 1 + njmpp - 1 ) )
  305. gphiu(ji,jj) = gphit(ji,jj)
  306. gphiv(ji,jj) = gphi0 + ppe2_m * 1.e-3 * ( FLOAT( jj - 1 + njmpp - 1 ) + 0.5 )
  307. gphif(ji,jj) = gphiv(ji,jj)
  308. END DO
  309. END DO
  310. ! Horizontal scale factors (in meters)
  311. ! ======
  312. e1t(:,:) = ppe1_m ; e2t(:,:) = ppe2_m
  313. e1u(:,:) = ppe1_m ; e2u(:,:) = ppe2_m
  314. e1v(:,:) = ppe1_m ; e2v(:,:) = ppe2_m
  315. e1f(:,:) = ppe1_m ; e2f(:,:) = ppe2_m
  316. CASE ( 4 ) ! geographical mesh on the sphere, isotropic MERCATOR type
  317. IF(lwp) WRITE(numout,*)
  318. IF(lwp) WRITE(numout,*) ' geographical mesh on the sphere, MERCATOR type'
  319. IF(lwp) WRITE(numout,*) ' longitudinal/latitudinal spacing given by ppe1_deg'
  320. IF ( ppgphi0 == -90 ) CALL ctl_stop( ' Mercator grid cannot start at south pole !!!! ' )
  321. ! Find index corresponding to the equator, given the grid spacing e1_deg
  322. ! and the (approximate) southern latitude ppgphi0.
  323. ! This way we ensure that the equator is at a "T / U" point, when in the domain.
  324. ! The formula should work even if the equator is outside the domain.
  325. zarg = rpi / 4. - rpi / 180. * ppgphi0 / 2.
  326. ijeq = ABS( 180./rpi * LOG( COS( zarg ) / SIN( zarg ) ) / ppe1_deg )
  327. IF( ppgphi0 > 0 ) ijeq = -ijeq
  328. IF(lwp) WRITE(numout,*) ' Index of the equator on the MERCATOR grid:', ijeq
  329. DO jj = 1, jpj
  330. DO ji = 1, jpi
  331. zti = FLOAT( ji - 1 + nimpp - 1 ) ; ztj = FLOAT( jj - ijeq + njmpp - 1 )
  332. zui = FLOAT( ji - 1 + nimpp - 1 ) + 0.5 ; zuj = FLOAT( jj - ijeq + njmpp - 1 )
  333. zvi = FLOAT( ji - 1 + nimpp - 1 ) ; zvj = FLOAT( jj - ijeq + njmpp - 1 ) + 0.5
  334. zfi = FLOAT( ji - 1 + nimpp - 1 ) + 0.5 ; zfj = FLOAT( jj - ijeq + njmpp - 1 ) + 0.5
  335. ! Longitude
  336. glamt(ji,jj) = ppglam0 + ppe1_deg * zti
  337. glamu(ji,jj) = ppglam0 + ppe1_deg * zui
  338. glamv(ji,jj) = ppglam0 + ppe1_deg * zvi
  339. glamf(ji,jj) = ppglam0 + ppe1_deg * zfi
  340. ! Latitude
  341. gphit(ji,jj) = 1./rad * ASIN ( TANH( ppe1_deg *rad* ztj ) )
  342. gphiu(ji,jj) = 1./rad * ASIN ( TANH( ppe1_deg *rad* zuj ) )
  343. gphiv(ji,jj) = 1./rad * ASIN ( TANH( ppe1_deg *rad* zvj ) )
  344. gphif(ji,jj) = 1./rad * ASIN ( TANH( ppe1_deg *rad* zfj ) )
  345. ! e1
  346. e1t(ji,jj) = ra * rad * COS( rad * gphit(ji,jj) ) * ppe1_deg
  347. e1u(ji,jj) = ra * rad * COS( rad * gphiu(ji,jj) ) * ppe1_deg
  348. e1v(ji,jj) = ra * rad * COS( rad * gphiv(ji,jj) ) * ppe1_deg
  349. e1f(ji,jj) = ra * rad * COS( rad * gphif(ji,jj) ) * ppe1_deg
  350. ! e2
  351. e2t(ji,jj) = ra * rad * COS( rad * gphit(ji,jj) ) * ppe1_deg
  352. e2u(ji,jj) = ra * rad * COS( rad * gphiu(ji,jj) ) * ppe1_deg
  353. e2v(ji,jj) = ra * rad * COS( rad * gphiv(ji,jj) ) * ppe1_deg
  354. e2f(ji,jj) = ra * rad * COS( rad * gphif(ji,jj) ) * ppe1_deg
  355. END DO
  356. END DO
  357. CASE ( 5 ) ! beta-plane with regular grid-spacing and rotated domain (GYRE configuration)
  358. IF(lwp) WRITE(numout,*)
  359. IF(lwp) WRITE(numout,*) ' beta-plane with regular grid-spacing and rotated domain (GYRE configuration)'
  360. IF(lwp) WRITE(numout,*) ' given by ppe1_m and ppe2_m'
  361. ! Position coordinates (in kilometers)
  362. ! ==========
  363. ! angle 45deg and ze1=106.e+3 / jp_cfg forced -> zlam1 = -85deg, zphi1 = 29degN
  364. zlam1 = -85
  365. zphi1 = 29
  366. ! resolution in meters
  367. ze1 = 106000. / FLOAT(jp_cfg)
  368. ! benchmark: forced the resolution to be about 100 km
  369. IF( nbench /= 0 ) ze1 = 106000.e0
  370. zsin_alpha = - SQRT( 2. ) / 2.
  371. zcos_alpha = SQRT( 2. ) / 2.
  372. ze1deg = ze1 / (ra * rad)
  373. IF( nbench /= 0 ) ze1deg = ze1deg / FLOAT(jp_cfg) ! benchmark: keep the lat/+lon
  374. ! ! at the right jp_cfg resolution
  375. glam0 = zlam1 + zcos_alpha * ze1deg * FLOAT( jpjglo-2 )
  376. gphi0 = zphi1 + zsin_alpha * ze1deg * FLOAT( jpjglo-2 )
  377. IF( nprint==1 .AND. lwp ) THEN
  378. WRITE(numout,*) ' ze1', ze1, 'cosalpha', zcos_alpha, 'sinalpha', zsin_alpha
  379. WRITE(numout,*) ' ze1deg', ze1deg, 'glam0', glam0, 'gphi0', gphi0
  380. ENDIF
  381. DO jj = 1, jpj
  382. DO ji = 1, jpi
  383. zim1 = FLOAT( ji + nimpp - 1 ) - 1. ; zim05 = FLOAT( ji + nimpp - 1 ) - 1.5
  384. zjm1 = FLOAT( jj + njmpp - 1 ) - 1. ; zjm05 = FLOAT( jj + njmpp - 1 ) - 1.5
  385. glamf(ji,jj) = glam0 + zim1 * ze1deg * zcos_alpha + zjm1 * ze1deg * zsin_alpha
  386. gphif(ji,jj) = gphi0 - zim1 * ze1deg * zsin_alpha + zjm1 * ze1deg * zcos_alpha
  387. glamt(ji,jj) = glam0 + zim05 * ze1deg * zcos_alpha + zjm05 * ze1deg * zsin_alpha
  388. gphit(ji,jj) = gphi0 - zim05 * ze1deg * zsin_alpha + zjm05 * ze1deg * zcos_alpha
  389. glamu(ji,jj) = glam0 + zim1 * ze1deg * zcos_alpha + zjm05 * ze1deg * zsin_alpha
  390. gphiu(ji,jj) = gphi0 - zim1 * ze1deg * zsin_alpha + zjm05 * ze1deg * zcos_alpha
  391. glamv(ji,jj) = glam0 + zim05 * ze1deg * zcos_alpha + zjm1 * ze1deg * zsin_alpha
  392. gphiv(ji,jj) = gphi0 - zim05 * ze1deg * zsin_alpha + zjm1 * ze1deg * zcos_alpha
  393. END DO
  394. END DO
  395. ! Horizontal scale factors (in meters)
  396. ! ======
  397. e1t(:,:) = ze1 ; e2t(:,:) = ze1
  398. e1u(:,:) = ze1 ; e2u(:,:) = ze1
  399. e1v(:,:) = ze1 ; e2v(:,:) = ze1
  400. e1f(:,:) = ze1 ; e2f(:,:) = ze1
  401. CASE DEFAULT
  402. WRITE(ctmp1,*) ' bad flag value for jphgr_msh = ', jphgr_msh
  403. CALL ctl_stop( ctmp1 )
  404. END SELECT
  405. ! T-cell surface
  406. ! --------------
  407. e1e2t(:,:) = e1t(:,:) * e2t(:,:)
  408. ! Useful shortcuts (JC: note the duplicated e2e2t array ! Need some cleaning)
  409. ! ---------------------------------------------------------------------------
  410. e12t (:,:) = e1t(:,:) * e2t(:,:)
  411. e12u (:,:) = e1u(:,:) * e2u(:,:)
  412. e12v (:,:) = e1v(:,:) * e2v(:,:)
  413. e12f (:,:) = e1f(:,:) * e2f(:,:)
  414. r1_e12t (:,:) = 1._wp / e12t(:,:)
  415. r1_e12u (:,:) = 1._wp / e12u(:,:)
  416. r1_e12v (:,:) = 1._wp / e12v(:,:)
  417. r1_e12f (:,:) = 1._wp / e12f(:,:)
  418. re2u_e1u(:,:) = e2u(:,:) / e1u(:,:)
  419. re1v_e2v(:,:) = e1v(:,:) / e2v(:,:)
  420. r1_e1t (:,:) = 1._wp / e1t(:,:)
  421. r1_e1u (:,:) = 1._wp / e1u(:,:)
  422. r1_e1v (:,:) = 1._wp / e1v(:,:)
  423. r1_e1f (:,:) = 1._wp / e1f(:,:)
  424. r1_e2t (:,:) = 1._wp / e2t(:,:)
  425. r1_e2u (:,:) = 1._wp / e2u(:,:)
  426. r1_e2v (:,:) = 1._wp / e2v(:,:)
  427. r1_e2f (:,:) = 1._wp / e2f(:,:)
  428. ! Control printing : Grid informations (if not restart)
  429. ! ----------------
  430. IF( lwp .AND. .NOT.ln_rstart ) THEN
  431. WRITE(numout,*)
  432. WRITE(numout,*) ' longitude and e1 scale factors'
  433. WRITE(numout,*) ' ------------------------------'
  434. WRITE(numout,9300) ( ji, glamt(ji,1), glamu(ji,1), &
  435. glamv(ji,1), glamf(ji,1), &
  436. e1t(ji,1), e1u(ji,1), &
  437. e1v(ji,1), e1f(ji,1), ji = 1, jpi,10)
  438. 9300 FORMAT( 1x, i4, f8.2,1x, f8.2,1x, f8.2,1x, f8.2, 1x, &
  439. f19.10, 1x, f19.10, 1x, f19.10, 1x, f19.10 )
  440. WRITE(numout,*)
  441. WRITE(numout,*) ' latitude and e2 scale factors'
  442. WRITE(numout,*) ' -----------------------------'
  443. WRITE(numout,9300) ( jj, gphit(1,jj), gphiu(1,jj), &
  444. & gphiv(1,jj), gphif(1,jj), &
  445. & e2t (1,jj), e2u (1,jj), &
  446. & e2v (1,jj), e2f (1,jj), jj = 1, jpj, 10 )
  447. ENDIF
  448. IF( nprint == 1 .AND. lwp ) THEN
  449. WRITE(numout,*) ' e1u e2u '
  450. CALL prihre( e1u,jpi,jpj,jpi-5,jpi,1,jpj-5,jpj,1,0.,numout )
  451. CALL prihre( e2u,jpi,jpj,jpi-5,jpi,1,jpj-5,jpj,1,0.,numout )
  452. WRITE(numout,*) ' e1v e2v '
  453. CALL prihre( e1v,jpi,jpj,jpi-5,jpi,1,jpj-5,jpj,1,0.,numout )
  454. CALL prihre( e2v,jpi,jpj,jpi-5,jpi,1,jpj-5,jpj,1,0.,numout )
  455. WRITE(numout,*) ' e1f e2f '
  456. CALL prihre( e1f,jpi,jpj,jpi-5,jpi,1,jpj-5,jpj,1,0.,numout )
  457. CALL prihre( e2f,jpi,jpj,jpi-5,jpi,1,jpj-5,jpj,1,0.,numout )
  458. ENDIF
  459. ! ================= !
  460. ! Coriolis factor !
  461. ! ================= !
  462. SELECT CASE( jphgr_msh ) ! type of horizontal mesh
  463. CASE ( 0, 1, 4 ) ! mesh on the sphere
  464. ff(:,:) = 2. * omega * SIN( rad * gphif(:,:) )
  465. CASE ( 2 ) ! f-plane at ppgphi0
  466. ff(:,:) = 2. * omega * SIN( rad * ppgphi0 )
  467. IF(lwp) WRITE(numout,*) ' f-plane: Coriolis parameter = constant = ', ff(1,1)
  468. CASE ( 3 ) ! beta-plane
  469. zbeta = 2. * omega * COS( rad * ppgphi0 ) / ra ! beta at latitude ppgphi0
  470. zphi0 = ppgphi0 - FLOAT( jpjglo/2) * ppe2_m / ( ra * rad ) ! latitude of the first row F-points
  471. #if defined key_agrif
  472. IF ( cp_cfg == 'eel' .AND. jp_cfg == 6 ) THEN ! for EEL6 configuration only
  473. IF( .NOT. Agrif_Root() ) THEN
  474. zphi0 = ppgphi0 - FLOAT( Agrif_Parent(jpjglo)/2)*Agrif_Parent(ppe2_m) &
  475. & / (ra * rad)
  476. ENDIF
  477. ENDIF
  478. #endif
  479. zf0 = 2. * omega * SIN( rad * zphi0 ) ! compute f0 1st point south
  480. ff(:,:) = ( zf0 + zbeta * gphif(:,:) * 1.e+3 ) ! f = f0 +beta* y ( y=0 at south)
  481. IF(lwp) THEN
  482. WRITE(numout,*)
  483. WRITE(numout,*) ' Beta-plane: Beta parameter = constant = ', ff(nldi,nldj)
  484. WRITE(numout,*) ' Coriolis parameter varies from ', ff(nldi,nldj),' to ', ff(nldi,nlej)
  485. ENDIF
  486. IF( lk_mpp ) THEN
  487. zminff=ff(nldi,nldj)
  488. zmaxff=ff(nldi,nlej)
  489. CALL mpp_min( zminff ) ! min over the global domain
  490. CALL mpp_max( zmaxff ) ! max over the global domain
  491. IF(lwp) WRITE(numout,*) ' Coriolis parameter varies globally from ', zminff,' to ', zmaxff
  492. END IF
  493. CASE ( 5 ) ! beta-plane and rotated domain (gyre configuration)
  494. zbeta = 2. * omega * COS( rad * ppgphi0 ) / ra ! beta at latitude ppgphi0
  495. zphi0 = 15.e0 ! latitude of the first row F-points
  496. zf0 = 2. * omega * SIN( rad * zphi0 ) ! compute f0 1st point south
  497. ff(:,:) = ( zf0 + zbeta * ABS( gphif(:,:) - zphi0 ) * rad * ra ) ! f = f0 +beta* y ( y=0 at south)
  498. IF(lwp) THEN
  499. WRITE(numout,*)
  500. WRITE(numout,*) ' Beta-plane and rotated domain : '
  501. WRITE(numout,*) ' Coriolis parameter varies in this processor from ', ff(nldi,nldj),' to ', ff(nldi,nlej)
  502. ENDIF
  503. IF( lk_mpp ) THEN
  504. zminff=ff(nldi,nldj)
  505. zmaxff=ff(nldi,nlej)
  506. CALL mpp_min( zminff ) ! min over the global domain
  507. CALL mpp_max( zmaxff ) ! max over the global domain
  508. IF(lwp) WRITE(numout,*) ' Coriolis parameter varies globally from ', zminff,' to ', zmaxff
  509. END IF
  510. END SELECT
  511. ! Control of domain for symetrical condition
  512. ! ------------------------------------------
  513. ! The equator line must be the latitude coordinate axe
  514. IF( nperio == 2 ) THEN
  515. znorme = SQRT( SUM( gphiu(:,2) * gphiu(:,2) ) ) / FLOAT( jpi )
  516. IF( znorme > 1.e-13 ) CALL ctl_stop( ' ===>>>> : symmetrical condition: rerun with good equator line' )
  517. ENDIF
  518. !
  519. IF( nn_timing == 1 ) CALL timing_stop('dom_hgr')
  520. !
  521. END SUBROUTINE dom_hgr
  522. SUBROUTINE hgr_read
  523. !!---------------------------------------------------------------------
  524. !! *** ROUTINE hgr_read ***
  525. !!
  526. !! ** Purpose : Read a coordinate file in NetCDF format
  527. !!
  528. !! ** Method : The mesh file has been defined trough a analytical
  529. !! or semi-analytical method. It is read in a NetCDF file.
  530. !!
  531. !!----------------------------------------------------------------------
  532. USE iom
  533. INTEGER :: inum ! temporary logical unit
  534. !!----------------------------------------------------------------------
  535. IF(lwp) THEN
  536. WRITE(numout,*)
  537. WRITE(numout,*) 'hgr_read : read the horizontal coordinates'
  538. WRITE(numout,*) '~~~~~~~~ jpiglo = ', jpiglo, ' jpjglo = ', jpjglo, ' jpk = ', jpk
  539. ENDIF
  540. CALL iom_open( 'coordinates', inum )
  541. CALL iom_get( inum, jpdom_data, 'glamt', glamt, lrowattr=ln_use_jattr )
  542. CALL iom_get( inum, jpdom_data, 'glamu', glamu, lrowattr=ln_use_jattr )
  543. CALL iom_get( inum, jpdom_data, 'glamv', glamv, lrowattr=ln_use_jattr )
  544. CALL iom_get( inum, jpdom_data, 'glamf', glamf, lrowattr=ln_use_jattr )
  545. CALL iom_get( inum, jpdom_data, 'gphit', gphit, lrowattr=ln_use_jattr )
  546. CALL iom_get( inum, jpdom_data, 'gphiu', gphiu, lrowattr=ln_use_jattr )
  547. CALL iom_get( inum, jpdom_data, 'gphiv', gphiv, lrowattr=ln_use_jattr )
  548. CALL iom_get( inum, jpdom_data, 'gphif', gphif, lrowattr=ln_use_jattr )
  549. CALL iom_get( inum, jpdom_data, 'e1t', e1t, lrowattr=ln_use_jattr )
  550. CALL iom_get( inum, jpdom_data, 'e1u', e1u, lrowattr=ln_use_jattr )
  551. CALL iom_get( inum, jpdom_data, 'e1v', e1v, lrowattr=ln_use_jattr )
  552. CALL iom_get( inum, jpdom_data, 'e1f', e1f, lrowattr=ln_use_jattr )
  553. CALL iom_get( inum, jpdom_data, 'e2t', e2t, lrowattr=ln_use_jattr )
  554. CALL iom_get( inum, jpdom_data, 'e2u', e2u, lrowattr=ln_use_jattr )
  555. CALL iom_get( inum, jpdom_data, 'e2v', e2v, lrowattr=ln_use_jattr )
  556. CALL iom_get( inum, jpdom_data, 'e2f', e2f, lrowattr=ln_use_jattr )
  557. CALL iom_close( inum )
  558. ! need to be define for the extended grid south of -80S
  559. ! some point are undefined but you need to have e1 and e2 .NE. 0
  560. WHERE (e1t==0.0_wp)
  561. e1t=1.0e2
  562. END WHERE
  563. WHERE (e1v==0.0_wp)
  564. e1v=1.0e2
  565. END WHERE
  566. WHERE (e1u==0.0_wp)
  567. e1u=1.0e2
  568. END WHERE
  569. WHERE (e1f==0.0_wp)
  570. e1f=1.0e2
  571. END WHERE
  572. WHERE (e2t==0.0_wp)
  573. e2t=1.0e2
  574. END WHERE
  575. WHERE (e2v==0.0_wp)
  576. e2v=1.0e2
  577. END WHERE
  578. WHERE (e2u==0.0_wp)
  579. e2u=1.0e2
  580. END WHERE
  581. WHERE (e2f==0.0_wp)
  582. e2f=1.0e2
  583. END WHERE
  584. END SUBROUTINE hgr_read
  585. !!======================================================================
  586. END MODULE domhgr