dynadv_cen2.F90 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. MODULE dynadv_cen2
  2. !!======================================================================
  3. !! *** MODULE dynadv ***
  4. !! Ocean dynamics: Update the momentum trend with the flux form advection
  5. !! using a 2nd order centred scheme
  6. !!======================================================================
  7. !! History : 2.0 ! 2006-08 (G. Madec, S. Theetten) Original code
  8. !! 3.2 ! 2009-07 (R. Benshila) Suppression of rigid-lid option
  9. !!----------------------------------------------------------------------
  10. !!----------------------------------------------------------------------
  11. !! dyn_adv_cen2 : flux form momentum advection (ln_dynadv_cen2=T)
  12. !! trends using a 2nd order centred scheme
  13. !!----------------------------------------------------------------------
  14. USE oce ! ocean dynamics and tracers
  15. USE dom_oce ! ocean space and time domain
  16. USE trd_oce ! trends: ocean variables
  17. USE trddyn ! trend manager: dynamics
  18. !
  19. USE in_out_manager ! I/O manager
  20. USE lib_mpp ! MPP library
  21. USE prtctl ! Print control
  22. USE wrk_nemo ! Memory Allocation
  23. USE timing ! Timing
  24. IMPLICIT NONE
  25. PRIVATE
  26. PUBLIC dyn_adv_cen2 ! routine called by step.F90
  27. !! * Substitutions
  28. # include "domzgr_substitute.h90"
  29. # include "vectopt_loop_substitute.h90"
  30. !!----------------------------------------------------------------------
  31. !! NEMO/OPA 4.0 , NEMO Consortium (2011)
  32. !! $Id: dynadv_cen2.F90 4990 2014-12-15 16:42:49Z timgraham $
  33. !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
  34. !!----------------------------------------------------------------------
  35. CONTAINS
  36. SUBROUTINE dyn_adv_cen2( kt )
  37. !!----------------------------------------------------------------------
  38. !! *** ROUTINE dyn_adv_cen2 ***
  39. !!
  40. !! ** Purpose : Compute the now momentum advection trend in flux form
  41. !! and the general trend of the momentum equation.
  42. !!
  43. !! ** Method : Trend evaluated using now fields (centered in time)
  44. !!
  45. !! ** Action : (ua,va) updated with the now vorticity term trend
  46. !!----------------------------------------------------------------------
  47. INTEGER, INTENT( in ) :: kt ! ocean time-step index
  48. !
  49. INTEGER :: ji, jj, jk ! dummy loop indices
  50. REAL(wp) :: zbu, zbv ! local scalars
  51. REAL(wp), POINTER, DIMENSION(:,:,:) :: zfu_t, zfv_t, zfu_f, zfv_f, zfu_uw, zfv_vw, zfw
  52. REAL(wp), POINTER, DIMENSION(:,:,:) :: zfu, zfv
  53. !!----------------------------------------------------------------------
  54. !
  55. IF( nn_timing == 1 ) CALL timing_start('dyn_adv_cen2')
  56. !
  57. CALL wrk_alloc( jpi, jpj, jpk, zfu_t, zfv_t, zfu_f, zfv_f, zfu_uw, zfv_vw, zfu, zfv, zfw )
  58. !
  59. IF( kt == nit000 .AND. lwp ) THEN
  60. WRITE(numout,*)
  61. WRITE(numout,*) 'dyn_adv_cen2 : 2nd order flux form momentum advection'
  62. WRITE(numout,*) '~~~~~~~~~~~~'
  63. ENDIF
  64. !
  65. IF( l_trddyn ) THEN ! Save ua and va trends
  66. zfu_uw(:,:,:) = ua(:,:,:)
  67. zfv_vw(:,:,:) = va(:,:,:)
  68. ENDIF
  69. ! ! ====================== !
  70. ! ! Horizontal advection !
  71. DO jk = 1, jpkm1 ! ====================== !
  72. ! ! horizontal volume fluxes
  73. zfu(:,:,jk) = 0.25 * e2u(:,:) * fse3u(:,:,jk) * un(:,:,jk)
  74. zfv(:,:,jk) = 0.25 * e1v(:,:) * fse3v(:,:,jk) * vn(:,:,jk)
  75. !
  76. DO jj = 1, jpjm1 ! horizontal momentum fluxes at T- and F-point
  77. DO ji = 1, fs_jpim1 ! vector opt.
  78. zfu_t(ji+1,jj ,jk) = ( zfu(ji,jj,jk) + zfu(ji+1,jj ,jk) ) * ( un(ji,jj,jk) + un(ji+1,jj ,jk) )
  79. zfv_f(ji ,jj ,jk) = ( zfv(ji,jj,jk) + zfv(ji+1,jj ,jk) ) * ( un(ji,jj,jk) + un(ji ,jj+1,jk) )
  80. zfu_f(ji ,jj ,jk) = ( zfu(ji,jj,jk) + zfu(ji ,jj+1,jk) ) * ( vn(ji,jj,jk) + vn(ji+1,jj ,jk) )
  81. zfv_t(ji ,jj+1,jk) = ( zfv(ji,jj,jk) + zfv(ji ,jj+1,jk) ) * ( vn(ji,jj,jk) + vn(ji ,jj+1,jk) )
  82. END DO
  83. END DO
  84. DO jj = 2, jpjm1 ! divergence of horizontal momentum fluxes
  85. DO ji = fs_2, fs_jpim1 ! vector opt.
  86. zbu = e1u(ji,jj) * e2u(ji,jj) * fse3u(ji,jj,jk)
  87. zbv = e1v(ji,jj) * e2v(ji,jj) * fse3v(ji,jj,jk)
  88. !
  89. ua(ji,jj,jk) = ua(ji,jj,jk) - ( zfu_t(ji+1,jj ,jk) - zfu_t(ji ,jj ,jk) &
  90. & + zfv_f(ji ,jj ,jk) - zfv_f(ji ,jj-1,jk) ) / zbu
  91. va(ji,jj,jk) = va(ji,jj,jk) - ( zfu_f(ji ,jj ,jk) - zfu_f(ji-1,jj ,jk) &
  92. & + zfv_t(ji ,jj+1,jk) - zfv_t(ji ,jj ,jk) ) / zbv
  93. END DO
  94. END DO
  95. END DO
  96. !
  97. IF( l_trddyn ) THEN ! save the horizontal advection trend for diagnostic
  98. zfu_uw(:,:,:) = ua(:,:,:) - zfu_uw(:,:,:)
  99. zfv_vw(:,:,:) = va(:,:,:) - zfv_vw(:,:,:)
  100. CALL trd_dyn( zfu_uw, zfv_vw, jpdyn_keg, kt )
  101. zfu_t(:,:,:) = ua(:,:,:)
  102. zfv_t(:,:,:) = va(:,:,:)
  103. ENDIF
  104. !
  105. ! ! ==================== !
  106. ! ! Vertical advection !
  107. DO jk = 1, jpkm1 ! ==================== !
  108. ! ! Vertical volume fluxesÊ
  109. zfw(:,:,jk) = 0.25 * e1t(:,:) * e2t(:,:) * wn(:,:,jk)
  110. !
  111. IF( jk == 1 ) THEN ! surface/bottom advective fluxes
  112. zfu_uw(:,:,jpk) = 0.e0 ! Bottom value : flux set to zero
  113. zfv_vw(:,:,jpk) = 0.e0
  114. ! ! Surface value :
  115. IF( lk_vvl ) THEN ! variable volume : flux set to zero
  116. zfu_uw(:,:, 1 ) = 0.e0
  117. zfv_vw(:,:, 1 ) = 0.e0
  118. ELSE ! constant volume : advection through the surface
  119. DO jj = 2, jpjm1
  120. DO ji = fs_2, fs_jpim1
  121. zfu_uw(ji,jj, 1 ) = 2.e0 * ( zfw(ji,jj,1) + zfw(ji+1,jj ,1) ) * un(ji,jj,1)
  122. zfv_vw(ji,jj, 1 ) = 2.e0 * ( zfw(ji,jj,1) + zfw(ji ,jj+1,1) ) * vn(ji,jj,1)
  123. END DO
  124. END DO
  125. ENDIF
  126. ELSE ! interior fluxes
  127. DO jj = 2, jpjm1
  128. DO ji = fs_2, fs_jpim1 ! vector opt.
  129. zfu_uw(ji,jj,jk) = ( zfw(ji,jj,jk)+ zfw(ji+1,jj ,jk) ) * ( un(ji,jj,jk) + un(ji,jj,jk-1) )
  130. zfv_vw(ji,jj,jk) = ( zfw(ji,jj,jk)+ zfw(ji ,jj+1,jk) ) * ( vn(ji,jj,jk) + vn(ji,jj,jk-1) )
  131. END DO
  132. END DO
  133. ENDIF
  134. END DO
  135. DO jk = 1, jpkm1 ! divergence of vertical momentum flux divergence
  136. DO jj = 2, jpjm1
  137. DO ji = fs_2, fs_jpim1 ! vector opt.
  138. ua(ji,jj,jk) = ua(ji,jj,jk) - ( zfu_uw(ji,jj,jk) - zfu_uw(ji,jj,jk+1) ) &
  139. & / ( e1u(ji,jj) * e2u(ji,jj) * fse3u(ji,jj,jk) )
  140. va(ji,jj,jk) = va(ji,jj,jk) - ( zfv_vw(ji,jj,jk) - zfv_vw(ji,jj,jk+1) ) &
  141. & / ( e1v(ji,jj) * e2v(ji,jj) * fse3v(ji,jj,jk) )
  142. END DO
  143. END DO
  144. END DO
  145. !
  146. IF( l_trddyn ) THEN ! save the vertical advection trend for diagnostic
  147. zfu_t(:,:,:) = ua(:,:,:) - zfu_t(:,:,:)
  148. zfv_t(:,:,:) = va(:,:,:) - zfv_t(:,:,:)
  149. CALL trd_dyn( zfu_t, zfv_t, jpdyn_zad, kt )
  150. ENDIF
  151. ! ! Control print
  152. IF(ln_ctl) CALL prt_ctl( tab3d_1=ua, clinfo1=' cen2 adv - Ua: ', mask1=umask, &
  153. & tab3d_2=va, clinfo2= ' Va: ', mask2=vmask, clinfo3='dyn' )
  154. !
  155. CALL wrk_dealloc( jpi, jpj, jpk, zfu_t, zfv_t, zfu_f, zfv_f, zfu_uw, zfv_vw, zfu, zfv, zfw )
  156. !
  157. IF( nn_timing == 1 ) CALL timing_stop('dyn_adv_cen2')
  158. !
  159. END SUBROUTINE dyn_adv_cen2
  160. !!==============================================================================
  161. END MODULE dynadv_cen2