ldfdyn.F90 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. MODULE ldfdyn
  2. !!======================================================================
  3. !! *** MODULE ldfdyn ***
  4. !! Ocean physics: lateral viscosity coefficient
  5. !!=====================================================================
  6. !! History : OPA ! 1997-07 (G. Madec) multi dimensional coefficients
  7. !! NEMO 1.0 ! 2002-09 (G. Madec) F90: Free form and module
  8. !!----------------------------------------------------------------------
  9. !!----------------------------------------------------------------------
  10. !! ldf_dyn_init : initialization, namelist read, and parameters control
  11. !! ldf_dyn_c3d : 3D eddy viscosity coefficient initialization
  12. !! ldf_dyn_c2d : 2D eddy viscosity coefficient initialization
  13. !! ldf_dyn_c1d : 1D eddy viscosity coefficient initialization
  14. !!----------------------------------------------------------------------
  15. USE oce ! ocean dynamics and tracers
  16. USE dom_oce ! ocean space and time domain
  17. USE ldfdyn_oce ! ocean dynamics lateral physics
  18. USE phycst ! physical constants
  19. USE ldfslp ! ???
  20. USE ioipsl
  21. USE in_out_manager ! I/O manager
  22. USE lib_mpp ! distribued memory computing library
  23. USE lbclnk ! ocean lateral boundary conditions (or mpp link)
  24. USE wrk_nemo ! Memory Allocation
  25. IMPLICIT NONE
  26. PRIVATE
  27. PUBLIC ldf_dyn_init ! called by opa.F90
  28. INTERFACE ldf_zpf
  29. MODULE PROCEDURE ldf_zpf_1d, ldf_zpf_1d_3d, ldf_zpf_3d
  30. END INTERFACE
  31. !! * Substitutions
  32. # include "domzgr_substitute.h90"
  33. !!----------------------------------------------------------------------
  34. !! NEMO/OPA 3.3 , NEMO Consortium (2010)
  35. !! $Id: ldfdyn.F90 4624 2014-04-28 12:09:03Z acc $
  36. !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
  37. !!----------------------------------------------------------------------
  38. CONTAINS
  39. SUBROUTINE ldf_dyn_init
  40. !!----------------------------------------------------------------------
  41. !! *** ROUTINE ldf_dyn_init ***
  42. !!
  43. !! ** Purpose : set the horizontal ocean dynamics physics
  44. !!
  45. !! ** Method :
  46. !! - default option : ahm = constant coef. = rn_ahm_0 (namelist)
  47. !! - 'key_dynldf_c1d': ahm = F(depth) see ldf_dyn_c1d.h90
  48. !! - 'key_dynldf_c2d': ahm = F(latitude,longitude) see ldf_dyn_c2d.h90
  49. !! - 'key_dynldf_c3d': ahm = F(latitude,longitude,depth) see ldf_dyn_c3d.h90
  50. !!
  51. !! N.B. User defined include files. By default, 3d and 2d coef.
  52. !! are set to a constant value given in the namelist and the 1d
  53. !! coefficients are initialized to a hyperbolic tangent vertical
  54. !! profile.
  55. !!
  56. !! Reference : Madec, G. and M. Imbard, 1996: Climate Dynamics, 12, 381-388.
  57. !!----------------------------------------------------------------------
  58. INTEGER :: ioptio ! ???
  59. INTEGER :: ios ! Local : output status for namelist read
  60. LOGICAL :: ll_print = .FALSE. ! Logical flag for printing viscosity coef.
  61. !!
  62. NAMELIST/namdyn_ldf/ ln_dynldf_lap , ln_dynldf_bilap, &
  63. & ln_dynldf_level, ln_dynldf_hor , ln_dynldf_iso, &
  64. & rn_ahm_0_lap , rn_ahmb_0 , rn_ahm_0_blp , &
  65. & rn_cmsmag_1 , rn_cmsmag_2 , rn_cmsh, &
  66. & rn_ahm_m_lap , rn_ahm_m_blp
  67. !!----------------------------------------------------------------------
  68. REWIND( numnam_ref ) ! Namelist namdyn_ldf in reference namelist : Lateral physics
  69. READ ( numnam_ref, namdyn_ldf, IOSTAT = ios, ERR = 901)
  70. 901 IF( ios /= 0 ) CALL ctl_nam ( ios , 'namdyn_ldf in reference namelist', lwp )
  71. REWIND( numnam_cfg ) ! Namelist namdyn_ldf in configuration namelist : Lateral physics
  72. READ ( numnam_cfg, namdyn_ldf, IOSTAT = ios, ERR = 902 )
  73. 902 IF( ios /= 0 ) CALL ctl_nam ( ios , 'namdyn_ldf in configuration namelist', lwp )
  74. IF(lwm) WRITE ( numond, namdyn_ldf )
  75. IF(lwp) THEN ! Parameter print
  76. WRITE(numout,*)
  77. WRITE(numout,*) 'ldf_dyn : lateral momentum physics'
  78. WRITE(numout,*) '~~~~~~~'
  79. WRITE(numout,*) ' Namelist namdyn_ldf : set lateral mixing parameters'
  80. WRITE(numout,*) ' laplacian operator ln_dynldf_lap = ', ln_dynldf_lap
  81. WRITE(numout,*) ' bilaplacian operator ln_dynldf_bilap = ', ln_dynldf_bilap
  82. WRITE(numout,*) ' iso-level ln_dynldf_level = ', ln_dynldf_level
  83. WRITE(numout,*) ' horizontal (geopotential) ln_dynldf_hor = ', ln_dynldf_hor
  84. WRITE(numout,*) ' iso-neutral ln_dynldf_iso = ', ln_dynldf_iso
  85. WRITE(numout,*) ' horizontal laplacian eddy viscosity rn_ahm_0_lap = ', rn_ahm_0_lap
  86. WRITE(numout,*) ' background viscosity rn_ahmb_0 = ', rn_ahmb_0
  87. WRITE(numout,*) ' horizontal bilaplacian eddy viscosity rn_ahm_0_blp = ', rn_ahm_0_blp
  88. WRITE(numout,*) ' upper limit for laplacian eddy visc rn_ahm_m_lap = ', rn_ahm_m_lap
  89. WRITE(numout,*) ' upper limit for bilap eddy viscosity rn_ahm_m_blp = ', rn_ahm_m_blp
  90. ENDIF
  91. ahm0 = rn_ahm_0_lap ! OLD namelist variables defined from DOCTOR namelist variables
  92. ahmb0 = rn_ahmb_0
  93. ahm0_blp = rn_ahm_0_blp
  94. ! ... check of lateral diffusive operator on tracers
  95. ! ==> will be done in trazdf module
  96. ! ... Space variation of eddy coefficients
  97. ioptio = 0
  98. #if defined key_dynldf_c3d
  99. IF(lwp) WRITE(numout,*) ' momentum mixing coef. = F( latitude, longitude, depth)'
  100. ioptio = ioptio+1
  101. #endif
  102. #if defined key_dynldf_c2d
  103. IF(lwp) WRITE(numout,*) ' momentum mixing coef. = F( latitude, longitude)'
  104. ioptio = ioptio+1
  105. #endif
  106. #if defined key_dynldf_c1d
  107. IF(lwp) WRITE(numout,*) ' momentum mixing coef. = F( depth )'
  108. ioptio = ioptio+1
  109. IF( ln_sco ) CALL ctl_stop( 'key_dynldf_c1d cannot be used in s-coordinate (ln_sco)' )
  110. #endif
  111. IF( ioptio == 0 ) THEN
  112. IF(lwp) WRITE(numout,*) ' momentum mixing coef. = constant (default option)'
  113. ELSEIF( ioptio > 1 ) THEN
  114. CALL ctl_stop( 'use only one of the following keys: key_dynldf_c3d, key_dynldf_c2d, key_dynldf_c1d' )
  115. ENDIF
  116. IF( ln_dynldf_bilap ) THEN
  117. IF(lwp) WRITE(numout,*) ' biharmonic momentum diffusion'
  118. IF( .NOT. ln_dynldf_lap ) ahm0 = ahm0_blp ! Allow spatially varying coefs, which use ahm0 as input
  119. IF( ahm0_blp > 0 .AND. .NOT. lk_esopa ) CALL ctl_stop( 'The horizontal viscosity coef. ahm0 must be negative' )
  120. ELSE
  121. IF(lwp) WRITE(numout,*) ' harmonic momentum diff. (default)'
  122. IF( ahm0 < 0 .AND. .NOT. lk_esopa ) CALL ctl_stop( 'The horizontal viscosity coef. ahm0 must be positive' )
  123. ENDIF
  124. ! Lateral eddy viscosity
  125. ! ======================
  126. #if defined key_dynldf_c3d
  127. CALL ldf_dyn_c3d( ll_print ) ! ahm = 3D coef. = F( longitude, latitude, depth )
  128. #elif defined key_dynldf_c2d
  129. CALL ldf_dyn_c2d( ll_print ) ! ahm = 1D coef. = F( longitude, latitude )
  130. #elif defined key_dynldf_c1d
  131. CALL ldf_dyn_c1d( ll_print ) ! ahm = 1D coef. = F( depth )
  132. #else
  133. ! Constant coefficients
  134. IF(lwp) WRITE(numout,*)
  135. IF(lwp) WRITE(numout,*) 'inildf: constant eddy viscosity coef. '
  136. IF(lwp) WRITE(numout,*) '~~~~~~'
  137. IF(lwp) WRITE(numout,*) ' ahm1 = ahm2 = ahm0 = ',ahm0
  138. #endif
  139. nkahm_smag = 0
  140. #if defined key_dynldf_smag
  141. nkahm_smag = 1
  142. #endif
  143. !
  144. END SUBROUTINE ldf_dyn_init
  145. #if defined key_dynldf_c3d
  146. # include "ldfdyn_c3d.h90"
  147. #elif defined key_dynldf_c2d
  148. # include "ldfdyn_c2d.h90"
  149. #elif defined key_dynldf_c1d
  150. # include "ldfdyn_c1d.h90"
  151. #endif
  152. SUBROUTINE ldf_zpf_1d( ld_print, pdam, pwam, pbot, pdep, pah )
  153. !!----------------------------------------------------------------------
  154. !! *** ROUTINE ldf_zpf ***
  155. !!
  156. !! ** Purpose : vertical adimensional profile for eddy coefficient
  157. !!
  158. !! ** Method : 1D eddy viscosity coefficients ( depth )
  159. !!----------------------------------------------------------------------
  160. LOGICAL , INTENT(in ) :: ld_print ! If true, output arrays on numout
  161. REAL(wp), INTENT(in ) :: pdam ! depth of the inflection point
  162. REAL(wp), INTENT(in ) :: pwam ! width of inflection
  163. REAL(wp), INTENT(in ) :: pbot ! bottom value (0<pbot<= 1)
  164. REAL(wp), INTENT(in ), DIMENSION(jpk) :: pdep ! depth of the gridpoint (T, U, V, F)
  165. REAL(wp), INTENT(inout), DIMENSION(jpk) :: pah ! adimensional vertical profile
  166. !!
  167. INTEGER :: jk ! dummy loop indices
  168. REAL(wp) :: zm00, zm01, zmhb, zmhs ! temporary scalars
  169. !!----------------------------------------------------------------------
  170. zm00 = TANH( ( pdam - gdept_1d(1 ) ) / pwam )
  171. zm01 = TANH( ( pdam - gdept_1d(jpkm1) ) / pwam )
  172. zmhs = zm00 / zm01
  173. zmhb = ( 1.e0 - pbot ) / ( 1.e0 - zmhs ) / zm01
  174. DO jk = 1, jpk
  175. pah(jk) = 1.e0 + zmhb * ( zm00 - TANH( ( pdam - pdep(jk) ) / pwam ) )
  176. END DO
  177. IF(lwp .AND. ld_print ) THEN ! Control print
  178. WRITE(numout,*)
  179. WRITE(numout,*) ' ahm profile : '
  180. WRITE(numout,*)
  181. WRITE(numout,'(" jk ahm "," depth t-level " )')
  182. DO jk = 1, jpk
  183. WRITE(numout,'(i6,2f12.4,3x,2f12.4)') jk, pah(jk), pdep(jk)
  184. END DO
  185. ENDIF
  186. !
  187. END SUBROUTINE ldf_zpf_1d
  188. SUBROUTINE ldf_zpf_1d_3d( ld_print, pdam, pwam, pbot, pdep, pah )
  189. !!----------------------------------------------------------------------
  190. !! *** ROUTINE ldf_zpf ***
  191. !!
  192. !! ** Purpose : vertical adimensional profile for eddy coefficient
  193. !!
  194. !! ** Method : 1D eddy viscosity coefficients ( depth )
  195. !!----------------------------------------------------------------------
  196. LOGICAL , INTENT(in ) :: ld_print ! If true, output arrays on numout
  197. REAL(wp), INTENT(in ) :: pdam ! depth of the inflection point
  198. REAL(wp), INTENT(in ) :: pwam ! width of inflection
  199. REAL(wp), INTENT(in ) :: pbot ! bottom value (0<pbot<= 1)
  200. REAL(wp), INTENT(in ), DIMENSION (:) :: pdep ! depth of the gridpoint (T, U, V, F)
  201. REAL(wp), INTENT(inout), DIMENSION (:,:,:) :: pah ! adimensional vertical profile
  202. !!
  203. INTEGER :: jk ! dummy loop indices
  204. REAL(wp) :: zm00, zm01, zmhb, zmhs, zcf ! temporary scalars
  205. !!----------------------------------------------------------------------
  206. zm00 = TANH( ( pdam - gdept_1d(1 ) ) / pwam )
  207. zm01 = TANH( ( pdam - gdept_1d(jpkm1) ) / pwam )
  208. zmhs = zm00 / zm01
  209. zmhb = ( 1.e0 - pbot ) / ( 1.e0 - zmhs ) / zm01
  210. DO jk = 1, jpk
  211. zcf = 1.e0 + zmhb * ( zm00 - TANH( ( pdam - pdep(jk) ) / pwam ) )
  212. pah(:,:,jk) = zcf
  213. END DO
  214. IF(lwp .AND. ld_print ) THEN ! Control print
  215. WRITE(numout,*)
  216. WRITE(numout,*) ' ahm profile : '
  217. WRITE(numout,*)
  218. WRITE(numout,'(" jk ahm "," depth t-level " )')
  219. DO jk = 1, jpk
  220. WRITE(numout,'(i6,2f12.4,3x,2f12.4)') jk, pah(1,1,jk), pdep(jk)
  221. END DO
  222. ENDIF
  223. !
  224. END SUBROUTINE ldf_zpf_1d_3d
  225. SUBROUTINE ldf_zpf_3d( ld_print, pdam, pwam, pbot, pdep, pah )
  226. !!----------------------------------------------------------------------
  227. !! *** ROUTINE ldf_zpf ***
  228. !!
  229. !! ** Purpose : vertical adimensional profile for eddy coefficient
  230. !!
  231. !! ** Method : 3D for partial step or s-coordinate
  232. !!----------------------------------------------------------------------
  233. LOGICAL , INTENT(in ) :: ld_print ! If true, output arrays on numout
  234. REAL(wp), INTENT(in ) :: pdam ! depth of the inflection point
  235. REAL(wp), INTENT(in ) :: pwam ! width of inflection
  236. REAL(wp), INTENT(in ) :: pbot ! bottom value (0<pbot<= 1)
  237. REAL(wp), INTENT(in ), DIMENSION (:,:,:) :: pdep ! dep of the gridpoint (T, U, V, F)
  238. REAL(wp), INTENT(inout), DIMENSION (:,:,:) :: pah ! adimensional vertical profile
  239. !!
  240. INTEGER :: jk ! dummy loop indices
  241. REAL(wp) :: zm00, zm01, zmhb, zmhs ! temporary scalars
  242. !!----------------------------------------------------------------------
  243. zm00 = TANH( ( pdam - gdept_1d(1 ) ) / pwam )
  244. zm01 = TANH( ( pdam - gdept_1d(jpkm1) ) / pwam )
  245. zmhs = zm00 / zm01
  246. zmhb = ( 1.e0 - pbot ) / ( 1.e0 - zmhs ) / zm01
  247. DO jk = 1, jpk
  248. pah(:,:,jk) = 1.e0 + zmhb * ( zm00 - TANH( ( pdam - pdep(:,:,jk) ) / pwam ) )
  249. END DO
  250. IF(lwp .AND. ld_print ) THEN ! Control print
  251. WRITE(numout,*)
  252. WRITE(numout,*) ' ahm profile : '
  253. WRITE(numout,*)
  254. WRITE(numout,'(" jk ahm "," depth t-level " )')
  255. DO jk = 1, jpk
  256. WRITE(numout,'(i6,2f12.4,3x,2f12.4)') jk, pah(1,1,jk), pdep(1,1,jk)
  257. END DO
  258. ENDIF
  259. !
  260. END SUBROUTINE ldf_zpf_3d
  261. !!======================================================================
  262. END MODULE ldfdyn