dyndmp.F90 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. MODULE dyndmp
  2. !!======================================================================
  3. !! *** MODULE dyndmp ***
  4. !! Ocean dynamics: internal restoring trend on momentum (U and V current)
  5. !! This should only be used for C1D case in current form
  6. !!======================================================================
  7. !! History : 3.5 ! 2013-08 (D. Calvert) Original code
  8. !! 3.6 ! 2014-08 (T. Graham) Modified to use netcdf file of
  9. !! restoration coefficients supplied to tradmp
  10. !!----------------------------------------------------------------------
  11. !!----------------------------------------------------------------------
  12. !! dyn_dmp_alloc : allocate dyndmp arrays
  13. !! dyn_dmp_init : namelist read, parameter control and resto coeff.
  14. !! dyn_dmp : update the momentum trend with the internal damping
  15. !!----------------------------------------------------------------------
  16. USE oce ! ocean: variables
  17. USE dom_oce ! ocean: domain variables
  18. USE c1d ! 1D vertical configuration
  19. USE tradmp ! ocean: internal damping
  20. USE zdf_oce ! ocean: vertical physics
  21. USE phycst ! physical constants
  22. USE dtauvd ! data: U & V current
  23. USE zdfmxl ! vertical physics: mixed layer depth
  24. USE in_out_manager ! I/O manager
  25. USE lib_mpp ! MPP library
  26. USE prtctl ! Print control
  27. USE wrk_nemo ! Memory allocation
  28. USE timing ! Timing
  29. USE iom ! I/O manager
  30. IMPLICIT NONE
  31. PRIVATE
  32. PUBLIC dyn_dmp_init ! routine called by nemogcm.F90
  33. PUBLIC dyn_dmp ! routine called by step_c1d.F90
  34. LOGICAL, PUBLIC :: ln_dyndmp ! Flag for Newtonian damping
  35. REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: utrdmp ! damping U current trend (m/s2)
  36. REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: vtrdmp ! damping V current trend (m/s2)
  37. REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: resto_uv ! restoring coeff. on U & V current
  38. !! * Substitutions
  39. # include "domzgr_substitute.h90"
  40. # include "vectopt_loop_substitute.h90"
  41. !!----------------------------------------------------------------------
  42. !! NEMO/OPA 3.3 , NEMO Consortium (2010)
  43. !! $Id: dyndmp.F90 2355 2015-05-20 07:11:50Z ufla $
  44. !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
  45. !!----------------------------------------------------------------------
  46. CONTAINS
  47. INTEGER FUNCTION dyn_dmp_alloc()
  48. !!----------------------------------------------------------------------
  49. !! *** FUNCTION dyn_dmp_alloc ***
  50. !!----------------------------------------------------------------------
  51. ALLOCATE( utrdmp(jpi,jpj,jpk), vtrdmp(jpi,jpj,jpk), resto_uv(jpi,jpj,jpk), STAT= dyn_dmp_alloc )
  52. !
  53. IF( lk_mpp ) CALL mpp_sum ( dyn_dmp_alloc )
  54. IF( dyn_dmp_alloc > 0 ) CALL ctl_warn('dyn_dmp_alloc: allocation of arrays failed')
  55. !
  56. END FUNCTION dyn_dmp_alloc
  57. SUBROUTINE dyn_dmp_init
  58. !!----------------------------------------------------------------------
  59. !! *** ROUTINE dyn_dmp_init ***
  60. !!
  61. !! ** Purpose : Initialization for the Newtonian damping
  62. !!
  63. !! ** Method : - read the ln_dyndmp parameter from the namc1d_dyndmp namelist
  64. !! - allocate damping arrays
  65. !! - check the parameters of the namtra_dmp namelist
  66. !! - calculate damping coefficient
  67. !!----------------------------------------------------------------------
  68. NAMELIST/namc1d_dyndmp/ ln_dyndmp
  69. INTEGER :: ios
  70. INTEGER :: imask
  71. !!----------------------------------------------------------------------
  72. REWIND( numnam_ref ) ! Namelist namc1d_dyndmp in reference namelist :
  73. READ ( numnam_ref, namc1d_dyndmp, IOSTAT = ios, ERR = 901)
  74. 901 IF( ios /= 0 ) CALL ctl_nam ( ios , 'namc1d_dyndmp in reference namelist', lwp )
  75. REWIND( numnam_cfg ) ! Namelist namc1d_dyndmp in configuration namelist : Parameters of the run
  76. READ ( numnam_cfg, namc1d_dyndmp, IOSTAT = ios, ERR = 902 )
  77. 902 IF( ios /= 0 ) CALL ctl_nam ( ios , 'namc1d_dyndmp in configuration namelist', lwp )
  78. IF(lwm) WRITE ( numond, namc1d_dyndmp )
  79. IF(lwp) THEN ! control print
  80. WRITE(numout,*)
  81. WRITE(numout,*) 'dyn_dmp_init : U and V current Newtonian damping'
  82. WRITE(numout,*) '~~~~~~~~~~~~'
  83. WRITE(numout,*) ' Namelist namc1d_dyndmp : Set damping flag'
  84. WRITE(numout,*) ' add a damping term or not ln_dyndmp = ', ln_dyndmp
  85. WRITE(numout,*) ' Namelist namtra_dmp : Set damping parameters'
  86. WRITE(numout,*) ' Apply relaxation or not ln_tradmp = ', ln_tradmp
  87. WRITE(numout,*) ' mixed layer damping option nn_zdmp = ', nn_zdmp
  88. WRITE(numout,*) ' Damping file name cn_resto = ', cn_resto
  89. WRITE(numout,*)
  90. ENDIF
  91. IF( ln_dyndmp ) THEN
  92. ! !== allocate the data arrays ==!
  93. IF( dyn_dmp_alloc() /= 0 ) CALL ctl_stop( 'STOP', 'dyn_dmp_init: unable to allocate arrays' )
  94. !
  95. SELECT CASE ( nn_zdmp ) !== control print of vertical option ==!
  96. CASE ( 0 ) ; IF(lwp) WRITE(numout,*) ' momentum damping throughout the water column'
  97. CASE ( 1 ) ; IF(lwp) WRITE(numout,*) ' no momentum damping in the turbocline (avt > 5 cm2/s)'
  98. CASE ( 2 ) ; IF(lwp) WRITE(numout,*) ' no momentum damping in the mixed layer'
  99. CASE DEFAULT
  100. WRITE(ctmp1,*) ' bad flag value for nn_zdmp = ', nn_zdmp
  101. CALL ctl_stop(ctmp1)
  102. END SELECT
  103. !
  104. IF( .NOT. ln_uvd_dyndmp ) THEN ! force the initialization of U & V current data for damping
  105. CALL ctl_warn( 'dyn_dmp_init: U & V current read data not initialized, we force ln_uvd_dyndmp=T' )
  106. CALL dta_uvd_init( ld_dyndmp=ln_dyndmp )
  107. ENDIF
  108. !
  109. utrdmp(:,:,:) = 0._wp ! internal damping trends
  110. vtrdmp(:,:,:) = 0._wp
  111. !
  112. !Read in mask from file
  113. CALL iom_open ( cn_resto, imask)
  114. CALL iom_get ( imask, jpdom_autoglo, 'resto', resto)
  115. CALL iom_close( imask )
  116. ENDIF
  117. !
  118. END SUBROUTINE dyn_dmp_init
  119. SUBROUTINE dyn_dmp( kt )
  120. !!----------------------------------------------------------------------
  121. !! *** ROUTINE dyn_dmp ***
  122. !!
  123. !! ** Purpose : Compute the momentum trends due to a newtonian damping
  124. !! of the ocean velocities towards the given data and add it to the
  125. !! general momentum trends.
  126. !!
  127. !! ** Method : Compute Newtonian damping towards u_dta and v_dta
  128. !! and add to the general momentum trends:
  129. !! ua = ua + resto_uv * (u_dta - ub)
  130. !! va = va + resto_uv * (v_dta - vb)
  131. !! The trend is computed either throughout the water column
  132. !! (nn_zdmp=0), where the vertical mixing is weak (nn_zdmp=1) or
  133. !! below the well mixed layer (nn_zdmp=2)
  134. !!
  135. !! ** Action : - (ua,va) momentum trends updated with the damping trend
  136. !!----------------------------------------------------------------------
  137. INTEGER, INTENT(in) :: kt ! ocean time-step index
  138. !!
  139. INTEGER :: ji, jj, jk ! dummy loop indices
  140. REAL(wp) :: zua, zva ! local scalars
  141. REAL(wp), POINTER, DIMENSION(:,:,:,:) :: zuv_dta ! Read in data
  142. !!----------------------------------------------------------------------
  143. !
  144. IF( nn_timing == 1 ) CALL timing_start( 'dyn_dmp' )
  145. !
  146. CALL wrk_alloc( jpi, jpj, jpk, 2, zuv_dta )
  147. !
  148. ! !== read and interpolate U & V current data at kt ==!
  149. CALL dta_uvd( kt, zuv_dta ) !!! NOTE: This subroutine must be altered for use outside
  150. !!! the C1D context (use of U,V grid variables)
  151. !
  152. SELECT CASE ( nn_zdmp ) !== Calculate/add Newtonian damping to the momentum trend ==!
  153. !
  154. CASE( 0 ) ! Newtonian damping throughout the water column
  155. DO jk = 1, jpkm1
  156. DO jj = 2, jpjm1
  157. DO ji = fs_2, fs_jpim1 ! vector opt.
  158. zua = resto_uv(ji,jj,jk) * ( zuv_dta(ji,jj,jk,1) - ub(ji,jj,jk) )
  159. zva = resto_uv(ji,jj,jk) * ( zuv_dta(ji,jj,jk,2) - vb(ji,jj,jk) )
  160. ua(ji,jj,jk) = ua(ji,jj,jk) + zua
  161. va(ji,jj,jk) = va(ji,jj,jk) + zva
  162. utrdmp(ji,jj,jk) = zua ! save the trends
  163. vtrdmp(ji,jj,jk) = zva
  164. END DO
  165. END DO
  166. END DO
  167. !
  168. CASE ( 1 ) ! no damping above the turbocline (avt > 5 cm2/s)
  169. DO jk = 1, jpkm1
  170. DO jj = 2, jpjm1
  171. DO ji = fs_2, fs_jpim1 ! vector opt.
  172. IF( avt(ji,jj,jk) <= 5.e-4_wp ) THEN
  173. zua = resto_uv(ji,jj,jk) * ( zuv_dta(ji,jj,jk,1) - ub(ji,jj,jk) )
  174. zva = resto_uv(ji,jj,jk) * ( zuv_dta(ji,jj,jk,2) - vb(ji,jj,jk) )
  175. ELSE
  176. zua = 0._wp
  177. zva = 0._wp
  178. ENDIF
  179. ua(ji,jj,jk) = ua(ji,jj,jk) + zua
  180. va(ji,jj,jk) = va(ji,jj,jk) + zva
  181. utrdmp(ji,jj,jk) = zua ! save the trends
  182. vtrdmp(ji,jj,jk) = zva
  183. END DO
  184. END DO
  185. END DO
  186. !
  187. CASE ( 2 ) ! no damping in the mixed layer
  188. DO jk = 1, jpkm1
  189. DO jj = 2, jpjm1
  190. DO ji = fs_2, fs_jpim1 ! vector opt.
  191. IF( fsdept(ji,jj,jk) >= hmlp (ji,jj) ) THEN
  192. zua = resto_uv(ji,jj,jk) * ( zuv_dta(ji,jj,jk,1) - ub(ji,jj,jk) )
  193. zva = resto_uv(ji,jj,jk) * ( zuv_dta(ji,jj,jk,2) - vb(ji,jj,jk) )
  194. ELSE
  195. zua = 0._wp
  196. zva = 0._wp
  197. ENDIF
  198. ua(ji,jj,jk) = ua(ji,jj,jk) + zua
  199. va(ji,jj,jk) = va(ji,jj,jk) + zva
  200. utrdmp(ji,jj,jk) = zua ! save the trends
  201. vtrdmp(ji,jj,jk) = zva
  202. END DO
  203. END DO
  204. END DO
  205. !
  206. END SELECT
  207. !
  208. !!gm ! ! Trend diagnostic
  209. !!gm IF( l_trddyn ) CALL trd_mod( utrdmp, vtrdmp, jpdyn_trd_dat, 'DYN', kt )
  210. !
  211. ! ! Control print
  212. IF( ln_ctl ) CALL prt_ctl( tab3d_1=ua(:,:,:), clinfo1=' dmp - Ua: ', mask1=umask, &
  213. & tab3d_2=va(:,:,:), clinfo2= ' Va: ', mask2=vmask, clinfo3='dyn' )
  214. !
  215. CALL wrk_dealloc( jpi, jpj, jpk, 2, zuv_dta )
  216. !
  217. IF( nn_timing == 1 ) CALL timing_stop( 'dyn_dmp')
  218. !
  219. END SUBROUTINE dyn_dmp
  220. !!======================================================================
  221. END MODULE dyndmp