dtatsd.F90 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. MODULE dtatsd
  2. !!======================================================================
  3. !! *** MODULE dtatsd ***
  4. !! Ocean data : read ocean Temperature & Salinity Data from gridded data
  5. !!======================================================================
  6. !! History : OPA ! 1991-03 () Original code
  7. !! - ! 1992-07 (M. Imbard)
  8. !! 8.0 ! 1999-10 (M.A. Foujols, M. Imbard) NetCDF FORMAT
  9. !! NEMO 1.0 ! 2002-06 (G. Madec) F90: Free form and module
  10. !! 3.3 ! 2010-10 (C. Bricaud, S. Masson) use of fldread
  11. !! 3.4 ! 2010-11 (G. Madec, C. Ethe) Merge of dtatem and dtasal + suppression of CPP keys
  12. !!----------------------------------------------------------------------
  13. !!----------------------------------------------------------------------
  14. !! dta_tsd : read and time interpolated ocean Temperature & Salinity Data
  15. !!----------------------------------------------------------------------
  16. USE oce ! ocean dynamics and tracers
  17. USE dom_oce ! ocean space and time domain
  18. USE fldread ! read input fields
  19. USE in_out_manager ! I/O manager
  20. USE phycst ! physical constants
  21. USE lib_mpp ! MPP library
  22. USE wrk_nemo ! Memory allocation
  23. USE timing ! Timing
  24. IMPLICIT NONE
  25. PRIVATE
  26. PUBLIC dta_tsd_init ! called by opa.F90
  27. PUBLIC dta_tsd ! called by istate.F90 and tradmp.90
  28. LOGICAL , PUBLIC :: ln_tsd_init !: T & S data flag
  29. LOGICAL , PUBLIC :: ln_tsd_tradmp !: internal damping toward input data flag
  30. TYPE(FLD), ALLOCATABLE, DIMENSION(:) :: sf_tsd ! structure of input SST (file informations, fields read)
  31. !! * Substitutions
  32. # include "domzgr_substitute.h90"
  33. !!----------------------------------------------------------------------
  34. !! NEMO/OPA 3.3 , NEMO Consortium (2010)
  35. !! $Id: dtatsd.F90 2355 2015-05-20 07:11:50Z ufla $
  36. !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
  37. !!----------------------------------------------------------------------
  38. CONTAINS
  39. SUBROUTINE dta_tsd_init( ld_tradmp )
  40. !!----------------------------------------------------------------------
  41. !! *** ROUTINE dta_tsd_init ***
  42. !!
  43. !! ** Purpose : initialisation of T & S input data
  44. !!
  45. !! ** Method : - Read namtsd namelist
  46. !! - allocates T & S data structure
  47. !!----------------------------------------------------------------------
  48. LOGICAL, INTENT(in), OPTIONAL :: ld_tradmp ! force the initialization when tradp is used
  49. !
  50. INTEGER :: ierr0, ierr1, ierr2, ierr3 ! temporary integers
  51. !
  52. CHARACTER(len=100) :: cn_dir ! Root directory for location of ssr files
  53. TYPE(FLD_N), DIMENSION( jpts) :: slf_i ! array of namelist informations on the fields to read
  54. TYPE(FLD_N) :: sn_tem, sn_sal
  55. !!
  56. NAMELIST/namtsd/ ln_tsd_init, ln_tsd_tradmp, cn_dir, sn_tem, sn_sal
  57. INTEGER :: ios
  58. !!----------------------------------------------------------------------
  59. !
  60. IF( nn_timing == 1 ) CALL timing_start('dta_tsd_init')
  61. !
  62. ! Initialisation
  63. ierr0 = 0 ; ierr1 = 0 ; ierr2 = 0 ; ierr3 = 0
  64. !
  65. REWIND( numnam_ref ) ! Namelist namtsd in reference namelist :
  66. READ ( numnam_ref, namtsd, IOSTAT = ios, ERR = 901)
  67. 901 IF( ios /= 0 ) CALL ctl_nam ( ios , 'namtsd in reference namelist', lwp )
  68. REWIND( numnam_cfg ) ! Namelist namtsd in configuration namelist : Parameters of the run
  69. READ ( numnam_cfg, namtsd, IOSTAT = ios, ERR = 902 )
  70. 902 IF( ios /= 0 ) CALL ctl_nam ( ios , 'namtsd in configuration namelist', lwp )
  71. IF(lwm) WRITE ( numond, namtsd )
  72. IF( PRESENT( ld_tradmp ) ) ln_tsd_tradmp = .TRUE. ! forces the initialization when tradmp is used
  73. IF(lwp) THEN ! control print
  74. WRITE(numout,*)
  75. WRITE(numout,*) 'dta_tsd_init : Temperature & Salinity data '
  76. WRITE(numout,*) '~~~~~~~~~~~~ '
  77. WRITE(numout,*) ' Namelist namtsd'
  78. WRITE(numout,*) ' Initialisation of ocean T & S with T &S input data ln_tsd_init = ', ln_tsd_init
  79. WRITE(numout,*) ' damping of ocean T & S toward T &S input data ln_tsd_tradmp = ', ln_tsd_tradmp
  80. WRITE(numout,*)
  81. IF( .NOT.ln_tsd_init .AND. .NOT.ln_tsd_tradmp ) THEN
  82. WRITE(numout,*)
  83. WRITE(numout,*) ' T & S data not used'
  84. ENDIF
  85. ENDIF
  86. !
  87. IF( ln_rstart .AND. ln_tsd_init ) THEN
  88. CALL ctl_warn( 'dta_tsd_init: ocean restart and T & S data intialisation, ', &
  89. & 'we keep the restart T & S values and set ln_tsd_init to FALSE' )
  90. ln_tsd_init = .FALSE.
  91. ENDIF
  92. !
  93. ! ! allocate the arrays (if necessary)
  94. IF( ln_tsd_init .OR. ln_tsd_tradmp ) THEN
  95. !
  96. ALLOCATE( sf_tsd(jpts), STAT=ierr0 )
  97. IF( ierr0 > 0 ) THEN
  98. CALL ctl_stop( 'dta_tsd_init: unable to allocate sf_tsd structure' ) ; RETURN
  99. ENDIF
  100. !
  101. ALLOCATE( sf_tsd(jp_tem)%fnow(jpi,jpj,jpk) , STAT=ierr0 )
  102. IF( sn_tem%ln_tint ) ALLOCATE( sf_tsd(jp_tem)%fdta(jpi,jpj,jpk,2) , STAT=ierr1 )
  103. ALLOCATE( sf_tsd(jp_sal)%fnow(jpi,jpj,jpk) , STAT=ierr2 )
  104. IF( sn_sal%ln_tint ) ALLOCATE( sf_tsd(jp_sal)%fdta(jpi,jpj,jpk,2) , STAT=ierr3 )
  105. !
  106. IF( ierr0 + ierr1 + ierr2 + ierr3 > 0 ) THEN
  107. CALL ctl_stop( 'dta_tsd : unable to allocate T & S data arrays' ) ; RETURN
  108. ENDIF
  109. ! ! fill sf_tsd with sn_tem & sn_sal and control print
  110. slf_i(jp_tem) = sn_tem ; slf_i(jp_sal) = sn_sal
  111. CALL fld_fill( sf_tsd, slf_i, cn_dir, 'dta_tsd', 'Temperature & Salinity data', 'namtsd' )
  112. !
  113. ENDIF
  114. !
  115. IF( nn_timing == 1 ) CALL timing_stop('dta_tsd_init')
  116. !
  117. END SUBROUTINE dta_tsd_init
  118. SUBROUTINE dta_tsd( kt, ptsd )
  119. !!----------------------------------------------------------------------
  120. !! *** ROUTINE dta_tsd ***
  121. !!
  122. !! ** Purpose : provides T and S data at kt
  123. !!
  124. !! ** Method : - call fldread routine
  125. !! - ORCA_R2: add some hand made alteration to read data
  126. !! - 'key_orca_lev10' interpolates on 10 times more levels
  127. !! - s- or mixed z-s coordinate: vertical interpolation on model mesh
  128. !! - ln_tsd_tradmp=F: deallocates the T-S data structure
  129. !! as T-S data are no are used
  130. !!
  131. !! ** Action : ptsd T-S data on medl mesh and interpolated at time-step kt
  132. !!----------------------------------------------------------------------
  133. INTEGER , INTENT(in ) :: kt ! ocean time-step
  134. REAL(wp), DIMENSION(jpi,jpj,jpk,jpts), INTENT( out) :: ptsd ! T & S data
  135. !
  136. INTEGER :: ji, jj, jk, jl, jkk ! dummy loop indicies
  137. INTEGER :: ik, il0, il1, ii0, ii1, ij0, ij1 ! local integers
  138. REAL(wp):: zl, zi
  139. REAL(wp), POINTER, DIMENSION(:) :: ztp, zsp ! 1D workspace
  140. !!----------------------------------------------------------------------
  141. !
  142. IF( nn_timing == 1 ) CALL timing_start('dta_tsd')
  143. !
  144. CALL fld_read( kt, 1, sf_tsd ) !== read T & S data at kt time step ==!
  145. !
  146. !
  147. ! !== ORCA_R2 configuration and T & S damping ==!
  148. IF( cp_cfg == "orca" .AND. jp_cfg == 2 .AND. ln_tsd_tradmp ) THEN ! some hand made alterations
  149. !
  150. ij0 = 101 ; ij1 = 109 ! Reduced T & S in the Alboran Sea
  151. ii0 = 141 ; ii1 = 155
  152. DO jj = mj0(ij0), mj1(ij1)
  153. DO ji = mi0(ii0), mi1(ii1)
  154. sf_tsd(jp_tem)%fnow(ji,jj,13:13) = sf_tsd(jp_tem)%fnow(ji,jj,13:13) - 0.20_wp
  155. sf_tsd(jp_tem)%fnow(ji,jj,14:15) = sf_tsd(jp_tem)%fnow(ji,jj,14:15) - 0.35_wp
  156. sf_tsd(jp_tem)%fnow(ji,jj,16:25) = sf_tsd(jp_tem)%fnow(ji,jj,16:25) - 0.40_wp
  157. !
  158. sf_tsd(jp_sal)%fnow(ji,jj,13:13) = sf_tsd(jp_sal)%fnow(ji,jj,13:13) - 0.15_wp
  159. sf_tsd(jp_sal)%fnow(ji,jj,14:15) = sf_tsd(jp_sal)%fnow(ji,jj,14:15) - 0.25_wp
  160. sf_tsd(jp_sal)%fnow(ji,jj,16:17) = sf_tsd(jp_sal)%fnow(ji,jj,16:17) - 0.30_wp
  161. sf_tsd(jp_sal)%fnow(ji,jj,18:25) = sf_tsd(jp_sal)%fnow(ji,jj,18:25) - 0.35_wp
  162. END DO
  163. END DO
  164. IF( nn_cla == 1 ) THEN ! Cross Land advection
  165. il0 = 138 ; il1 = 138 ! set T & S profile at Gibraltar Strait
  166. ij0 = 101 ; ij1 = 102
  167. ii0 = 139 ; ii1 = 139
  168. DO jl = mi0(il0), mi1(il1)
  169. DO jj = mj0(ij0), mj1(ij1)
  170. DO ji = mi0(ii0), mi1(ii1)
  171. sf_tsd(jp_tem)%fnow(ji,jj,:) = sf_tsd(jp_tem)%fnow(jl,jj,:)
  172. sf_tsd(jp_sal)%fnow(ji,jj,:) = sf_tsd(jp_sal)%fnow(jl,jj,:)
  173. END DO
  174. END DO
  175. END DO
  176. il0 = 164 ; il1 = 164 ! set T & S profile at Bab el Mandeb Strait
  177. ij0 = 87 ; ij1 = 88
  178. ii0 = 161 ; ii1 = 163
  179. DO jl = mi0(il0), mi1(il1)
  180. DO jj = mj0(ij0), mj1(ij1)
  181. DO ji = mi0(ii0), mi1(ii1)
  182. sf_tsd(jp_tem)%fnow(ji,jj,:) = sf_tsd(jp_tem)%fnow(jl,jj,:)
  183. sf_tsd(jp_sal)%fnow(ji,jj,:) = sf_tsd(jp_sal)%fnow(jl,jj,:)
  184. END DO
  185. END DO
  186. END DO
  187. ELSE ! No Cross Land advection
  188. ij0 = 87 ; ij1 = 96 ! Reduced temperature in Red Sea
  189. ii0 = 148 ; ii1 = 160
  190. sf_tsd(jp_tem)%fnow( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) , 4:10 ) = 7.0_wp
  191. sf_tsd(jp_tem)%fnow( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) , 11:13 ) = 6.5_wp
  192. sf_tsd(jp_tem)%fnow( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) , 14:20 ) = 6.0_wp
  193. ENDIF
  194. ENDIF
  195. !
  196. ptsd(:,:,:,jp_tem) = sf_tsd(jp_tem)%fnow(:,:,:) ! NO mask
  197. ptsd(:,:,:,jp_sal) = sf_tsd(jp_sal)%fnow(:,:,:)
  198. !
  199. IF( ln_sco ) THEN !== s- or mixed s-zps-coordinate ==!
  200. !
  201. CALL wrk_alloc( jpk, ztp, zsp )
  202. !
  203. IF( kt == nit000 .AND. lwp )THEN
  204. WRITE(numout,*)
  205. WRITE(numout,*) 'dta_tsd: interpolates T & S data onto the s- or mixed s-z-coordinate mesh'
  206. ENDIF
  207. !
  208. DO jj = 1, jpj ! vertical interpolation of T & S
  209. DO ji = 1, jpi
  210. DO jk = 1, jpk ! determines the intepolated T-S profiles at each (i,j) points
  211. zl = gdept_0(ji,jj,jk)
  212. IF( zl < gdept_1d(1 ) ) THEN ! above the first level of data
  213. ztp(jk) = ptsd(ji,jj,1 ,jp_tem)
  214. zsp(jk) = ptsd(ji,jj,1 ,jp_sal)
  215. ELSEIF( zl > gdept_1d(jpk) ) THEN ! below the last level of data
  216. ztp(jk) = ptsd(ji,jj,jpkm1,jp_tem)
  217. zsp(jk) = ptsd(ji,jj,jpkm1,jp_sal)
  218. ELSE ! inbetween : vertical interpolation between jkk & jkk+1
  219. DO jkk = 1, jpkm1 ! when gdept(jkk) < zl < gdept(jkk+1)
  220. IF( (zl-gdept_1d(jkk)) * (zl-gdept_1d(jkk+1)) <= 0._wp ) THEN
  221. zi = ( zl - gdept_1d(jkk) ) / (gdept_1d(jkk+1)-gdept_1d(jkk))
  222. ztp(jk) = ptsd(ji,jj,jkk,jp_tem) + ( ptsd(ji,jj,jkk+1,jp_tem) - ptsd(ji,jj,jkk,jp_tem) ) * zi
  223. zsp(jk) = ptsd(ji,jj,jkk,jp_sal) + ( ptsd(ji,jj,jkk+1,jp_sal) - ptsd(ji,jj,jkk,jp_sal) ) * zi
  224. ENDIF
  225. END DO
  226. ENDIF
  227. END DO
  228. DO jk = 1, jpkm1
  229. ptsd(ji,jj,jk,jp_tem) = ztp(jk) * tmask(ji,jj,jk) ! mask required for mixed zps-s-coord
  230. ptsd(ji,jj,jk,jp_sal) = zsp(jk) * tmask(ji,jj,jk)
  231. END DO
  232. ptsd(ji,jj,jpk,jp_tem) = 0._wp
  233. ptsd(ji,jj,jpk,jp_sal) = 0._wp
  234. END DO
  235. END DO
  236. !
  237. CALL wrk_dealloc( jpk, ztp, zsp )
  238. !
  239. ELSE !== z- or zps- coordinate ==!
  240. !
  241. ptsd(:,:,:,jp_tem) = ptsd(:,:,:,jp_tem) * tmask(:,:,:) ! Mask
  242. ptsd(:,:,:,jp_sal) = ptsd(:,:,:,jp_sal) * tmask(:,:,:)
  243. !
  244. IF( ln_zps ) THEN ! zps-coordinate (partial steps) interpolation at the last ocean level
  245. DO jj = 1, jpj
  246. DO ji = 1, jpi
  247. ik = mbkt(ji,jj)
  248. IF( ik > 1 ) THEN
  249. zl = ( gdept_1d(ik) - gdept_0(ji,jj,ik) ) / ( gdept_1d(ik) - gdept_1d(ik-1) )
  250. ptsd(ji,jj,ik,jp_tem) = (1.-zl) * ptsd(ji,jj,ik,jp_tem) + zl * ptsd(ji,jj,ik-1,jp_tem)
  251. ptsd(ji,jj,ik,jp_sal) = (1.-zl) * ptsd(ji,jj,ik,jp_sal) + zl * ptsd(ji,jj,ik-1,jp_sal)
  252. ENDIF
  253. ik = mikt(ji,jj)
  254. IF( ik > 1 ) THEN
  255. zl = ( gdept_0(ji,jj,ik) - gdept_1d(ik) ) / ( gdept_1d(ik+1) - gdept_1d(ik) )
  256. ptsd(ji,jj,ik,jp_tem) = (1.-zl) * ptsd(ji,jj,ik,jp_tem) + zl * ptsd(ji,jj,ik+1,jp_tem)
  257. ptsd(ji,jj,ik,jp_sal) = (1.-zl) * ptsd(ji,jj,ik,jp_sal) + zl * ptsd(ji,jj,ik+1,jp_sal)
  258. END IF
  259. END DO
  260. END DO
  261. ENDIF
  262. !
  263. ENDIF
  264. !
  265. IF( lwp .AND. kt == nit000 ) THEN
  266. WRITE(numout,*) ' temperature Levitus '
  267. WRITE(numout,*)
  268. WRITE(numout,*)' level = 1'
  269. CALL prihre( ptsd(:,:,1 ,jp_tem), jpi, jpj, 1, jpi, 20, 1, jpj, 20, 1., numout )
  270. WRITE(numout,*)' level = ', jpk/2
  271. CALL prihre( ptsd(:,:,jpk/2,jp_tem), jpi, jpj, 1, jpi, 20, 1, jpj, 20, 1., numout )
  272. WRITE(numout,*)' level = ', jpkm1
  273. CALL prihre( ptsd(:,:,jpkm1,jp_tem), jpi, jpj, 1, jpi, 20, 1, jpj, 20, 1., numout )
  274. WRITE(numout,*)
  275. WRITE(numout,*) ' salinity Levitus '
  276. WRITE(numout,*)
  277. WRITE(numout,*)' level = 1'
  278. CALL prihre( ptsd(:,:,1 ,jp_sal), jpi, jpj, 1, jpi, 20, 1, jpj, 20, 1., numout )
  279. WRITE(numout,*)' level = ', jpk/2
  280. CALL prihre( ptsd(:,:,jpk/2,jp_sal), jpi, jpj, 1, jpi, 20, 1, jpj, 20, 1., numout )
  281. WRITE(numout,*)' level = ', jpkm1
  282. CALL prihre( ptsd(:,:,jpkm1,jp_sal), jpi, jpj, 1, jpi, 20, 1, jpj, 20, 1., numout )
  283. WRITE(numout,*)
  284. ENDIF
  285. !
  286. IF( .NOT.ln_tsd_tradmp ) THEN !== deallocate T & S structure ==!
  287. ! (data used only for initialisation)
  288. IF(lwp) WRITE(numout,*) 'dta_tsd: deallocte T & S arrays as they are only use to initialize the run'
  289. DEALLOCATE( sf_tsd(jp_tem)%fnow ) ! T arrays in the structure
  290. IF( sf_tsd(jp_tem)%ln_tint ) DEALLOCATE( sf_tsd(jp_tem)%fdta )
  291. DEALLOCATE( sf_tsd(jp_sal)%fnow ) ! S arrays in the structure
  292. IF( sf_tsd(jp_sal)%ln_tint ) DEALLOCATE( sf_tsd(jp_sal)%fdta )
  293. DEALLOCATE( sf_tsd ) ! the structure itself
  294. ENDIF
  295. !
  296. IF( nn_timing == 1 ) CALL timing_stop('dta_tsd')
  297. !
  298. END SUBROUTINE dta_tsd
  299. !!======================================================================
  300. END MODULE dtatsd