dynzdf_exp.F90 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. MODULE dynzdf_exp
  2. !!==============================================================================
  3. !! *** MODULE dynzdf_exp ***
  4. !! Ocean dynamics: vertical component(s) of the momentum mixing trend
  5. !!==============================================================================
  6. !! History : OPA ! 1990-10 (B. Blanke) Original code
  7. !! 8.0 ! 1997-05 (G. Madec) vertical component of isopycnal
  8. !! NEMO 0.5 ! 2002-08 (G. Madec) F90: Free form and module
  9. !! 3.3 ! 2010-04 (M. Leclair, G. Madec) Forcing averaged over 2 time steps
  10. !!----------------------------------------------------------------------
  11. !!----------------------------------------------------------------------
  12. !! dyn_zdf_exp : update the momentum trend with the vertical diffu-
  13. !! sion using an explicit time-stepping scheme.
  14. !!----------------------------------------------------------------------
  15. USE oce ! ocean dynamics and tracers
  16. USE dom_oce ! ocean space and time domain
  17. USE phycst ! physical constants
  18. USE zdf_oce ! ocean vertical physics
  19. USE sbc_oce ! surface boundary condition: ocean
  20. USE lib_mpp ! MPP library
  21. USE in_out_manager ! I/O manager
  22. USE lib_mpp ! MPP library
  23. USE wrk_nemo ! Memory Allocation
  24. USE timing ! Timing
  25. IMPLICIT NONE
  26. PRIVATE
  27. PUBLIC dyn_zdf_exp ! called by step.F90
  28. !! * Substitutions
  29. # include "domzgr_substitute.h90"
  30. # include "vectopt_loop_substitute.h90"
  31. !!----------------------------------------------------------------------
  32. !! NEMO/OPA 3.3 , NEMO Consortium (2010)
  33. !! $Id: dynzdf_exp.F90 3625 2012-11-21 13:19:18Z acc $
  34. !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
  35. !!----------------------------------------------------------------------
  36. CONTAINS
  37. SUBROUTINE dyn_zdf_exp( kt, p2dt )
  38. !!----------------------------------------------------------------------
  39. !! *** ROUTINE dyn_zdf_exp ***
  40. !!
  41. !! ** Purpose : Compute the trend due to the vert. momentum diffusion
  42. !!
  43. !! ** Method : Explicit forward time stepping with a time splitting
  44. !! technique. The vertical diffusion of momentum is given by:
  45. !! diffu = dz( avmu dz(u) ) = 1/e3u dk+1( avmu/e3uw dk(ub) )
  46. !! Surface boundary conditions: wind stress input (averaged over kt-1/2 & kt+1/2)
  47. !! Bottom boundary conditions : bottom stress (cf zdfbfr.F90)
  48. !! Add this trend to the general trend ua :
  49. !! ua = ua + dz( avmu dz(u) )
  50. !!
  51. !! ** Action : - Update (ua,va) with the vertical diffusive trend
  52. !!---------------------------------------------------------------------
  53. INTEGER , INTENT(in) :: kt ! ocean time-step index
  54. REAL(wp), INTENT(in) :: p2dt ! time-step
  55. !
  56. INTEGER :: ji, jj, jk, jl ! dummy loop indices
  57. REAL(wp) :: zlavmr, zua, zva ! local scalars
  58. REAL(wp), POINTER, DIMENSION(:,:,:) :: zwx, zwy, zwz, zww
  59. !!----------------------------------------------------------------------
  60. !
  61. IF( nn_timing == 1 ) CALL timing_start('dyn_zdf_exp')
  62. !
  63. CALL wrk_alloc( jpi,jpj,jpk, zwx, zwy, zwz, zww )
  64. !
  65. IF( kt == nit000 .AND. lwp ) THEN
  66. WRITE(numout,*)
  67. WRITE(numout,*) 'dyn_zdf_exp : vertical momentum diffusion - explicit operator'
  68. WRITE(numout,*) '~~~~~~~~~~~ '
  69. ENDIF
  70. zlavmr = 1. / REAL( nn_zdfexp )
  71. DO jj = 2, jpjm1 ! Surface boundary condition
  72. DO ji = 2, jpim1
  73. zwy(ji,jj,1) = ( utau_b(ji,jj) + utau(ji,jj) ) * r1_rau0
  74. zww(ji,jj,1) = ( vtau_b(ji,jj) + vtau(ji,jj) ) * r1_rau0
  75. END DO
  76. END DO
  77. DO jk = 1, jpk ! Initialization of x, z and contingently trends array
  78. DO jj = 2, jpjm1
  79. DO ji = 2, jpim1
  80. zwx(ji,jj,jk) = ub(ji,jj,jk)
  81. zwz(ji,jj,jk) = vb(ji,jj,jk)
  82. END DO
  83. END DO
  84. END DO
  85. !
  86. DO jl = 1, nn_zdfexp ! Time splitting loop
  87. !
  88. DO jk = 2, jpk ! First vertical derivative
  89. DO jj = 2, jpjm1
  90. DO ji = 2, jpim1
  91. zwy(ji,jj,jk) = avmu(ji,jj,jk) * ( zwx(ji,jj,jk-1) - zwx(ji,jj,jk) ) / fse3uw(ji,jj,jk)
  92. zww(ji,jj,jk) = avmv(ji,jj,jk) * ( zwz(ji,jj,jk-1) - zwz(ji,jj,jk) ) / fse3vw(ji,jj,jk)
  93. END DO
  94. END DO
  95. END DO
  96. DO jk = 1, jpkm1 ! Second vertical derivative and trend estimation at kt+l*rdt/nn_zdfexp
  97. DO jj = 2, jpjm1
  98. DO ji = 2, jpim1
  99. zua = zlavmr * ( zwy(ji,jj,jk) - zwy(ji,jj,jk+1) ) / fse3u(ji,jj,jk)
  100. zva = zlavmr * ( zww(ji,jj,jk) - zww(ji,jj,jk+1) ) / fse3v(ji,jj,jk)
  101. ua(ji,jj,jk) = ua(ji,jj,jk) + zua
  102. va(ji,jj,jk) = va(ji,jj,jk) + zva
  103. !
  104. zwx(ji,jj,jk) = zwx(ji,jj,jk) + p2dt * zua * umask(ji,jj,jk)
  105. zwz(ji,jj,jk) = zwz(ji,jj,jk) + p2dt * zva * vmask(ji,jj,jk)
  106. END DO
  107. END DO
  108. END DO
  109. !
  110. END DO ! End of time splitting
  111. !
  112. CALL wrk_dealloc( jpi,jpj,jpk, zwx, zwy, zwz, zww )
  113. !
  114. IF( nn_timing == 1 ) CALL timing_stop('dyn_zdf_exp')
  115. !
  116. END SUBROUTINE dyn_zdf_exp
  117. !!==============================================================================
  118. END MODULE dynzdf_exp