obs_rot_vel.F90 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. MODULE obs_rot_vel
  2. !!======================================================================
  3. !! *** MODULE obs_rot_vel ***
  4. !! Observation diagnostics: Read the velocity profile observations
  5. !!======================================================================
  6. !!----------------------------------------------------------------------
  7. !! obs_rotvel : Rotate velocity data into N-S,E-W directorions
  8. !!----------------------------------------------------------------------
  9. !! * Modules used
  10. USE wrk_nemo ! Memory Allocation
  11. USE par_kind ! Precision variables
  12. USE par_oce ! Ocean parameters
  13. USE in_out_manager ! I/O manager
  14. USE dom_oce ! Ocean space and time domain variables
  15. USE obs_grid ! Grid search
  16. USE obs_utils ! For error handling
  17. USE obs_profiles_def ! Profile definitions
  18. USE obs_inter_h2d ! Horizontal interpolation
  19. USE obs_inter_sup ! MPP support routines for interpolation
  20. USE geo2ocean ! Rotation of vectors
  21. USE obs_fbm ! Feedback definitions
  22. IMPLICIT NONE
  23. !! * Routine accessibility
  24. PRIVATE
  25. PUBLIC obs_rotvel ! Rotate the observations
  26. !!----------------------------------------------------------------------
  27. !! NEMO/OPA 3.3 , NEMO Consortium (2010)
  28. !! $Id: obs_rot_vel.F90 3294 2012-01-28 16:44:18Z rblod $
  29. !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
  30. !!----------------------------------------------------------------------
  31. CONTAINS
  32. SUBROUTINE obs_rotvel( profdata, k2dint, pu, pv )
  33. !!---------------------------------------------------------------------
  34. !!
  35. !! *** ROUTINE obs_rea_pro_dri ***
  36. !!
  37. !! ** Purpose : Rotate velocity data into N-S,E-W directorions
  38. !!
  39. !! ** Method : Interpolation of geo2ocean coefficients on U,V grid
  40. !! to observation point followed by a similar computations
  41. !! as in geo2ocean.
  42. !!
  43. !! ** Action : Review if there is a better way to do this.
  44. !!
  45. !! References :
  46. !!
  47. !! History :
  48. !! ! : 2009-02 (K. Mogensen) : New routine
  49. !!----------------------------------------------------------------------
  50. !! * Modules used
  51. !! * Arguments
  52. TYPE(obs_prof), INTENT(INOUT) :: profdata ! Profile data to be read
  53. INTEGER, INTENT(IN) :: k2dint ! Horizontal interpolation methed
  54. REAL(wp), DIMENSION(*) :: &
  55. & pu, &
  56. & pv
  57. !! * Local declarations
  58. REAL(wp), DIMENSION(2,2,1) :: zweig
  59. REAL(wp), DIMENSION(:,:,:), ALLOCATABLE :: &
  60. & zmasku, &
  61. & zmaskv, &
  62. & zcoslu, &
  63. & zsinlu, &
  64. & zcoslv, &
  65. & zsinlv, &
  66. & zglamu, &
  67. & zgphiu, &
  68. & zglamv, &
  69. & zgphiv
  70. REAL(wp), DIMENSION(1) :: &
  71. & zsinu, &
  72. & zcosu, &
  73. & zsinv, &
  74. & zcosv
  75. REAL(wp) :: zsin
  76. REAL(wp) :: zcos
  77. REAL(wp), DIMENSION(1) :: zobsmask
  78. REAL(wp), POINTER, DIMENSION(:,:) :: zsingu,zcosgu,zsingv,zcosgv
  79. INTEGER, DIMENSION(:,:,:), ALLOCATABLE :: &
  80. & igrdiu, &
  81. & igrdju, &
  82. & igrdiv, &
  83. & igrdjv
  84. INTEGER :: ji
  85. INTEGER :: jk
  86. CALL wrk_alloc(jpi,jpj,zsingu,zcosgu,zsingv,zcosgv)
  87. !-----------------------------------------------------------------------
  88. ! Allocate data for message parsing and interpolation
  89. !-----------------------------------------------------------------------
  90. ALLOCATE( &
  91. & igrdiu(2,2,profdata%nprof), &
  92. & igrdju(2,2,profdata%nprof), &
  93. & zglamu(2,2,profdata%nprof), &
  94. & zgphiu(2,2,profdata%nprof), &
  95. & zmasku(2,2,profdata%nprof), &
  96. & zcoslu(2,2,profdata%nprof), &
  97. & zsinlu(2,2,profdata%nprof), &
  98. & igrdiv(2,2,profdata%nprof), &
  99. & igrdjv(2,2,profdata%nprof), &
  100. & zglamv(2,2,profdata%nprof), &
  101. & zgphiv(2,2,profdata%nprof), &
  102. & zmaskv(2,2,profdata%nprof), &
  103. & zcoslv(2,2,profdata%nprof), &
  104. & zsinlv(2,2,profdata%nprof) &
  105. & )
  106. !-----------------------------------------------------------------------
  107. ! Receive the angles on the U and V grids.
  108. !-----------------------------------------------------------------------
  109. CALL obs_rot( zsingu, zcosgu, zsingv, zcosgv )
  110. DO ji = 1, profdata%nprof
  111. igrdiu(1,1,ji) = profdata%mi(ji,1)-1
  112. igrdju(1,1,ji) = profdata%mj(ji,1)-1
  113. igrdiu(1,2,ji) = profdata%mi(ji,1)-1
  114. igrdju(1,2,ji) = profdata%mj(ji,1)
  115. igrdiu(2,1,ji) = profdata%mi(ji,1)
  116. igrdju(2,1,ji) = profdata%mj(ji,1)-1
  117. igrdiu(2,2,ji) = profdata%mi(ji,1)
  118. igrdju(2,2,ji) = profdata%mj(ji,1)
  119. igrdiv(1,1,ji) = profdata%mi(ji,2)-1
  120. igrdjv(1,1,ji) = profdata%mj(ji,2)-1
  121. igrdiv(1,2,ji) = profdata%mi(ji,2)-1
  122. igrdjv(1,2,ji) = profdata%mj(ji,2)
  123. igrdiv(2,1,ji) = profdata%mi(ji,2)
  124. igrdjv(2,1,ji) = profdata%mj(ji,2)-1
  125. igrdiv(2,2,ji) = profdata%mi(ji,2)
  126. igrdjv(2,2,ji) = profdata%mj(ji,2)
  127. END DO
  128. CALL obs_int_comm_2d( 2, 2, profdata%nprof, igrdiu, igrdju, &
  129. & glamu, zglamu )
  130. CALL obs_int_comm_2d( 2, 2, profdata%nprof, igrdiu, igrdju, &
  131. & gphiu, zgphiu )
  132. CALL obs_int_comm_2d( 2, 2, profdata%nprof, igrdiu, igrdju, &
  133. & umask(:,:,1), zmasku )
  134. CALL obs_int_comm_2d( 2, 2, profdata%nprof, igrdiu, igrdju, &
  135. & zsingu, zsinlu )
  136. CALL obs_int_comm_2d( 2, 2, profdata%nprof, igrdiu, igrdju, &
  137. & zcosgu, zcoslu )
  138. CALL obs_int_comm_2d( 2, 2, profdata%nprof, igrdiv, igrdjv, &
  139. & glamv, zglamv )
  140. CALL obs_int_comm_2d( 2, 2, profdata%nprof, igrdiv, igrdjv, &
  141. & gphiv, zgphiv )
  142. CALL obs_int_comm_2d( 2, 2, profdata%nprof, igrdiv, igrdjv, &
  143. & vmask(:,:,1), zmaskv )
  144. CALL obs_int_comm_2d( 2, 2, profdata%nprof, igrdiv, igrdjv, &
  145. & zsingv, zsinlv )
  146. CALL obs_int_comm_2d( 2, 2, profdata%nprof, igrdiv, igrdjv, &
  147. & zcosgv, zcoslv )
  148. DO ji = 1, profdata%nprof
  149. CALL obs_int_h2d_init( 1, 1, k2dint, &
  150. & profdata%rlam(ji), profdata%rphi(ji), &
  151. & zglamu(:,:,ji), zgphiu(:,:,ji), &
  152. & zmasku(:,:,ji), zweig, zobsmask )
  153. CALL obs_int_h2d( 1, 1, zweig, zsinlu(:,:,ji), zsinu )
  154. CALL obs_int_h2d( 1, 1, zweig, zcoslu(:,:,ji), zcosu )
  155. CALL obs_int_h2d_init( 1, 1, k2dint, &
  156. & profdata%rlam(ji), profdata%rphi(ji), &
  157. & zglamv(:,:,ji), zgphiv(:,:,ji), &
  158. & zmaskv(:,:,ji), zweig, zobsmask )
  159. CALL obs_int_h2d( 1, 1, zweig, zsinlv(:,:,ji), zsinv )
  160. CALL obs_int_h2d( 1, 1, zweig, zcoslv(:,:,ji), zcosv )
  161. ! Assume that the angle at observation point is the
  162. ! mean of u and v cosines/sines
  163. zcos = 0.5_wp * ( zcosu(1) + zcosv(1) )
  164. zsin = 0.5_wp * ( zsinu(1) + zsinv(1) )
  165. IF ( ( profdata%npvsta(ji,1) /= profdata%npvsta(ji,2) ) .OR. &
  166. & ( profdata%npvend(ji,1) /= profdata%npvend(ji,2) ) ) THEN
  167. CALL fatal_error( 'Different number of U and V observations '// &
  168. 'in a profile in obs_rotvel', __LINE__ )
  169. ENDIF
  170. DO jk = profdata%npvsta(ji,1), profdata%npvend(ji,1)
  171. IF ( ( profdata%var(1)%vmod(jk) /= fbrmdi ) .AND. &
  172. & ( profdata%var(1)%vmod(jk) /= fbrmdi ) ) THEN
  173. pu(jk) = profdata%var(1)%vmod(jk) * zcos - &
  174. & profdata%var(2)%vmod(jk) * zsin
  175. pv(jk) = profdata%var(2)%vmod(jk) * zcos + &
  176. & profdata%var(1)%vmod(jk) * zsin
  177. ELSE
  178. pu(jk) = fbrmdi
  179. pv(jk) = fbrmdi
  180. ENDIF
  181. END DO
  182. END DO
  183. DEALLOCATE( &
  184. & igrdiu, &
  185. & igrdju, &
  186. & zglamu, &
  187. & zgphiu, &
  188. & zmasku, &
  189. & zcoslu, &
  190. & zsinlu, &
  191. & igrdiv, &
  192. & igrdjv, &
  193. & zglamv, &
  194. & zgphiv, &
  195. & zmaskv, &
  196. & zcoslv, &
  197. & zsinlv &
  198. & )
  199. CALL wrk_dealloc(jpi,jpj,zsingu,zcosgu,zsingv,zcosgv)
  200. END SUBROUTINE obs_rotvel
  201. END MODULE obs_rot_vel