cdfsigtrp.f90 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646
  1. PROGRAM cdfsigtrp
  2. !!---------------------------------------------------------------------
  3. !! *** PROGRAM cdfsigtrp ***
  4. !!
  5. !! ** Purpose: Compute density class Mass Transports across a section
  6. !! PARTIAL STEPS version
  7. !!
  8. !! ** Method:
  9. !! -The beginner and end point of the section are given in term of f-points index.
  10. !! -The progracdfm works for zonal or meridional sections.
  11. !! -The section definitions are given in an ASCII FILE dens_section.dat
  12. !! foreach sections, 2 lines : (i) : section name (String, no blank)
  13. !! (ii) : imin imax jmin jmax for the section
  14. !! -Only vertical slices corrsponding to the sections are read in the files.
  15. !! read metrics, depth, etc
  16. !! read normal velocity (either uo or vo )
  17. !! read 2 rows of T and S ( i i+1 or j j+1 )
  18. !! compute the mean value at velocity point
  19. !! compute sigma0 (can be easily modified for sigmai )
  20. !! compute the depths of isopyncal surfaces
  21. !! compute the transport from surface to the isopycn
  22. !! compute the transport in each class of density
  23. !! compute the total transport (for information)
  24. !!
  25. !! history :
  26. !! Original : J.M. Molines March 2006
  27. !! : R. Dussin (Jul. 2009) add cdf output
  28. !!---------------------------------------------------------------------
  29. !! $Rev: 322 $
  30. !! $Date: 2010-05-20 07:14:33 +0200 (Thu, 20 May 2010) $
  31. !! $Id: cdfsigtrp.f90 322 2010-05-20 05:14:33Z molines $
  32. !!--------------------------------------------------------------
  33. !! * Modules used
  34. USE netcdf
  35. USE cdfio
  36. USE io_ezcdf
  37. USE eos
  38. !! * Local variables
  39. IMPLICIT NONE
  40. INTEGER :: nbins !: number of density classes
  41. INTEGER :: ji, jk, jt, jclass, jsec,jiso , jbin,jarg !: dummy loop index
  42. INTEGER :: narg, iargc !: command line
  43. INTEGER :: npiglo,npjglo, npk, nk, nt !: vertical size, number of wet layers in the section
  44. INTEGER :: nsection !: number of sections (overall)
  45. INTEGER ,DIMENSION(:), ALLOCATABLE :: imina, imaxa, jmina, jmaxa !: sections limits
  46. INTEGER :: imin, imax, jmin, jmax !: working section limits
  47. INTEGER :: npts !: working section number of h-points
  48. ! added to write in netcdf
  49. INTEGER :: kx=1, ky=1 ! dims of netcdf output file
  50. INTEGER :: nboutput=2 ! number of values to write in cdf output
  51. INTEGER :: ierr, istatus ! for netcdf output
  52. INTEGER, DIMENSION(:), ALLOCATABLE :: ipk, id_varout
  53. REAL(KIND=4), DIMENSION (:), ALLOCATABLE :: gdept, gdepw !: depth of T and W points
  54. REAL(KIND=4), DIMENSION (:,:), ALLOCATABLE :: zs, zt !: salinity and temperature from file
  55. REAL(KIND=4), DIMENSION (:,:,:), ALLOCATABLE :: XOUT, tmpm, tmpz !: temporary arrays
  56. ! double precision for cumulative variables and densities
  57. REAL(KIND=8), DIMENSION (:), ALLOCATABLE :: eu !: either e1v or e2u
  58. REAL(KIND=8), DIMENSION (:,:), ALLOCATABLE :: zu, e3 , zmask !: velocities e3 and umask
  59. REAL(KIND=8), DIMENSION (:,:), ALLOCATABLE :: zsig ,gdepu !: density, depth of vel points
  60. REAL(KIND=8) :: sigma_min, sigma_max,dsigma !: Min and Max for sigma bining
  61. REAL(KIND=8) :: sigma,zalfa !: current working sigma
  62. REAL(KIND=8), DIMENSION (:), ALLOCATABLE :: sigma_lev, sigma_lev_center !: built array with sigma levels
  63. REAL(KIND=8), DIMENSION (:,:), ALLOCATABLE :: hiso !: depth of isopycns
  64. REAL(KIND=8), DIMENSION (:,:), ALLOCATABLE :: zwtrp, zwtrpbin !: transport arrays
  65. ! added to write in netcdf
  66. REAL(KIND=4), DIMENSION(:,:), ALLOCATABLE :: dumlon, dumlat
  67. REAL(KIND=4) ,DIMENSION(:), ALLOCATABLE :: tim !LB
  68. TYPE(variable), DIMENSION(:), ALLOCATABLE :: typvar ! structure of output
  69. TYPE(variable), DIMENSION(:), ALLOCATABLE :: typvarin !: structure for recovering input informations such as iwght
  70. CHARACTER(LEN=256), DIMENSION(:),ALLOCATABLE :: cvarname !: names of input variables
  71. INTEGER :: nvarin !: number of variables in input file
  72. INTEGER :: iweight !: weight of input file for further averaging
  73. CHARACTER(LEN=256) :: cd_out = '.', cf_out
  74. REAL :: ryear
  75. CHARACTER(LEN=256), DIMENSION (:), ALLOCATABLE :: csection !: section name
  76. CHARACTER(LEN=256) :: cfilet, cfileu, cfilev, cfilesec='dens_section.dat' !: files name
  77. CHARACTER(LEN=256) :: cf_mm='mesh_mask.nc' !: coordinates files
  78. CHARACTER(LEN=256) :: cdum
  79. ! added to write in netcdf
  80. CHARACTER(LEN=256) :: ctim
  81. LOGICAL :: l_merid !: flag is true for meridional working section
  82. LOGICAL :: lfncout = .false.
  83. CHARACTER(LEN=80) :: cfor9000, cfor9001, cfor9002, cfor9003, cfor9004
  84. REAL(4), DIMENSION(:,:), ALLOCATABLE :: E2U_2D, E1V_2D
  85. REAL(4), DIMENSION(:,:,:), ALLOCATABLE :: T_3D, S_3D, U_3D, V_3D, E3U_3D, E3V_3D, E3W_3D
  86. INTEGER, DIMENSION(:), ALLOCATABLE :: id_var_out
  87. CHARACTER(LEN=64) :: cv_t, cv_s, cv_u, cv_v
  88. INTEGER :: jt_pos, idf_out, idd_t, idd_sbins, idv_time, idv_sbins
  89. INTEGER :: idf_0=0, idv_0=0, idf_t=0, idv_t=0, idf_s=0, idv_s=0, idf_u=0, &
  90. & idv_u=0, idf_v=0, idv_v=0
  91. !! * Initialisations
  92. ! Read command line and output usage message if not compliant.
  93. narg= iargc()
  94. IF ( narg < 12 ) THEN
  95. PRINT *, ''
  96. PRINT *,' Usage: cdfsigtrp.x <Tfile> <Ufile> <Vfile> s_min s_max nbins <year> <DIROUT> <name T> <name S> <name U> <name V>'
  97. PRINT *,' * s_min, s_max : limit for density bining '
  98. PRINT *,' * nbins : number of bins to use '
  99. PRINT *, ''
  100. PRINT *,' File mesh_mask.nc must be in the current directory'
  101. PRINT *,' File dens_section.dat must also be in the current directory '
  102. STOP
  103. ENDIF
  104. !! Read arguments
  105. CALL getarg (1, cfilet)
  106. CALL getarg (2, cfileu)
  107. CALL getarg (3, cfilev)
  108. CALL getarg (4,cdum) ; READ(cdum,*) sigma_min
  109. CALL getarg (5,cdum) ; READ(cdum,*) sigma_max
  110. CALL getarg (6,cdum) ; READ(cdum,*) nbins
  111. CALL getarg (7, cdum) ; READ(cdum,*) ryear
  112. CALL getarg (8, cd_out)
  113. CALL getarg (9, cv_t)
  114. CALL getarg (10, cv_s)
  115. CALL getarg (11, cv_u)
  116. CALL getarg (12, cv_v)
  117. ! start for netcdf:
  118. nvarin=getnvar(cfileu) ! smaller than cfilet
  119. ALLOCATE(typvarin(nvarin), cvarname(nvarin) )
  120. cvarname(:)=getvarname(cfileu,nvarin,typvarin)
  121. DO jarg=1,nvarin
  122. IF ( TRIM(cvarname(jarg)) == trim(cv_u) ) THEN
  123. iweight=typvarin(jarg)%iwght
  124. EXIT ! loop
  125. ENDIF
  126. END DO
  127. ALLOCATE ( typvar(nboutput), ipk(nboutput), id_varout(nboutput) )
  128. ALLOCATE (dumlon(kx,ky) , dumlat(kx,ky) )
  129. dumlon(:,:)=0.
  130. dumlat(:,:)=0.
  131. ipk(1)=nbins ! sigma for each level
  132. ipk(2)=nbins ! transport for each level
  133. ! define new variables for output
  134. typvar(1)%name='sigma_class'
  135. typvar%units='[]'
  136. typvar%missing_value=99999.
  137. typvar%valid_min= 0.
  138. typvar%valid_max= 100.
  139. typvar%scale_factor= 1.
  140. typvar%add_offset= 0.
  141. typvar%savelog10= 0.
  142. typvar%iwght=iweight
  143. typvar(1)%long_name='class of potential density'
  144. typvar(1)%short_name='sigma_class'
  145. typvar%online_operation='N/A'
  146. typvar%axis='ZT'
  147. typvar(2)%name='sigtrp'
  148. typvar(2)%units='Sv'
  149. typvar(2)%valid_min= -1000.
  150. typvar(2)%valid_max= 1000.
  151. typvar(2)%long_name='transport in sigma class'
  152. typvar(2)%short_name='sigtrp'
  153. !end of netcdf...
  154. INQUIRE( FILE=cfilesec, EXIST=lfncout )
  155. IF ( .NOT. lfncout ) THEN
  156. PRINT *, 'ERROR: file '//trim(cfilesec)//' not found!' ; STOP
  157. END IF
  158. ! Initialise sections from file
  159. ! first call to get nsection and allocate arrays
  160. nsection = 0 ; CALL section_init(cfilesec, csection,imina,imaxa,jmina,jmaxa, nsection)
  161. ALLOCATE ( csection(nsection), imina(nsection), imaxa(nsection), jmina(nsection),jmaxa(nsection) )
  162. CALL section_init(cfilesec, csection,imina,imaxa,jmina,jmaxa, nsection)
  163. ! Allocate and build sigma levels and section array
  164. ALLOCATE ( sigma_lev(nbins+1), sigma_lev_center(nbins) )
  165. sigma_lev(1)=sigma_min
  166. dsigma=( sigma_max - sigma_min) / nbins
  167. DO jclass =2, nbins+1
  168. sigma_lev(jclass)= sigma_lev(1) + (jclass-1) * dsigma
  169. END DO
  170. DO jclass =1, nbins
  171. sigma_lev_center(jclass) = 0.5*(sigma_lev(jclass) + sigma_lev(jclass+1))
  172. END DO
  173. ctim = 'none'
  174. nt = getdim (cfilet,'time',cdtrue=ctim,kstatus=istatus) !LB
  175. ALLOCATE ( tim(nt), XOUT(nsection, nbins, nt), id_var_out(nsection) ) !LB
  176. ! Look for vertical size of the domain
  177. npiglo= getdim (cfilet,'x')
  178. npjglo= getdim (cfilet,'y')
  179. npk = getdim (cfilet,'olevel')
  180. ALLOCATE ( gdept(npk), gdepw(npk) )
  181. ALLOCATE ( T_3D(npiglo,npjglo,npk), S_3D(npiglo,npjglo,npk), &
  182. & U_3D(npiglo,npjglo,npk), V_3D(npiglo,npjglo,npk), &
  183. & E2U_2D(npiglo,npjglo), E1V_2D(npiglo,npjglo), &
  184. & E3U_3D(npiglo,npjglo,npk), E3V_3D(npiglo,npjglo,npk), E3W_3D(npiglo,npjglo,npk) )
  185. ! read gdept, gdepw : it is OK even in partial cells, as we never use the bottom gdep
  186. gdept(:) = getvare3(cf_mm,'gdept', npk)
  187. gdepw(:) = getvare3(cf_mm,'gdepw', npk)
  188. !lolo
  189. ! get e3u, e3v at all levels
  190. CALL GETVAR_2D(idf_0, idv_0, cf_mm, 'e2u', 0, 0, 0, E2U_2D) ; idf_0 = 0 ; idv_0 = 0
  191. CALL GETVAR_2D(idf_0, idv_0, cf_mm, 'e1v', 0, 0, 0, E1V_2D) ; idf_0 = 0 ; idv_0 = 0
  192. CALL GETVAR_3D(idf_0, idv_0, cf_mm, 'e3u_0', 0, 0, E3U_3D) ; idf_0 = 0 ; idv_0 = 0
  193. CALL GETVAR_3D(idf_0, idv_0, cf_mm, 'e3v_0', 0, 0, E3V_3D) ; idf_0 = 0 ; idv_0 = 0
  194. CALL GETVAR_3D(idf_0, idv_0, cf_mm, 'e3w_0', 0, 0, E3W_3D)
  195. !! * Main loop on sections
  196. DO jt = 1, nt !LB
  197. PRINT *, 'Time record = ', jt
  198. CALL GETVAR_3D(idf_t, idv_t, cfilet, trim(cv_t), nt, jt, T_3D)
  199. CALL GETVAR_3D(idf_s, idv_s, cfilet, trim(cv_s), nt, jt, S_3D)
  200. CALL GETVAR_3D(idf_u, idv_u, cfileu, trim(cv_u), nt, jt, U_3D)
  201. CALL GETVAR_3D(idf_v, idv_v, cfilev, trim(cv_v), nt, jt, V_3D)
  202. DO jsec=1,nsection
  203. PRINT *, 'Treating section '//TRIM(csection(jsec))
  204. l_merid=.FALSE.
  205. imin=imina(jsec) ; imax=imaxa(jsec) ; jmin=jmina(jsec) ; jmax=jmaxa(jsec)
  206. IF (imin == imax ) THEN ! meridional section
  207. l_merid=.TRUE.
  208. npts=jmax-jmin
  209. ELSE IF ( jmin == jmax ) THEN ! zonal section
  210. npts=imax-imin
  211. ELSE
  212. PRINT *,' Section ',TRIM(csection(jsec)),' is neither zonal nor meridional :('
  213. PRINT *,' We skip this section .'
  214. CYCLE
  215. ENDIF
  216. !PRINT *, 'Allocating for jt, jsec =', jt, jsec
  217. ALLOCATE ( zu(npts, npk), zt(npts,npk), zs(npts,npk) ,zsig(npts,0:npk) )
  218. ALLOCATE ( eu(npts), e3(npts,npk), gdepu(npts, 0:npk), zmask(npts,npk) )
  219. ALLOCATE ( tmpm(1,npts+1,2), tmpz(npts+1,1,2) )
  220. ALLOCATE ( zwtrp(npts, nbins+1) , hiso(npts,nbins+1), zwtrpbin(npts,nbins) )
  221. !END IF
  222. !PRINT *, ' filling with 0...'
  223. zt = 0. ; zs = 0. ; zu = 0. ; gdepu= 0. ; zmask = 0. ; zsig=0.d0
  224. IF (l_merid ) THEN ! meridional section at i=imin=imax
  225. !tmpm(:,:,1)=getvar(cf_mm, 'e2u', 1,1,npts, kimin=imin, kjmin=jmin+1)
  226. !PRINT *, 'LOLO 1 =>', tmpm(:,:,1)
  227. tmpm(1,:,1) = E2U_2D(imin,jmin+1:jmin+1+npts)
  228. !PRINT *, 'LOLO 2 =>', tmpm(:,:,1)
  229. !STOP
  230. eu(:)=tmpm(1,1:npts,1) ! metrics varies only horizontally
  231. DO jk=1,npk
  232. ! initiliaze gdepu to gdept()
  233. gdepu(:,jk) = gdept(jk)
  234. ! vertical metrics (PS case)
  235. !tmpm(:,:,1)=getvar(cf_mm,'e3u_ps',jk,1,npts, kimin=imin, kjmin=jmin+1, ldiom=.TRUE.)
  236. !PRINT *, 'LOLO1 =>', tmpm(:,:,1)
  237. tmpm(1,:,1) = E3U_3D(imin,jmin+1:jmin+1+npts,jk)
  238. !PRINT *, 'LOLO2 =>', tmpm(:,:,1)
  239. e3(:,jk)=tmpm(1,1:npts,1)
  240. !tmpm(:,:,1)=getvar(cf_mm,'e3w_ps',jk,1,npts, kimin=imin, kjmin=jmin+1, ldiom=.TRUE.)
  241. !tmpm(:,:,2)=getvar(cf_mm,'e3w_ps',jk,1,npts, kimin=imin+1, kjmin=jmin+1, ldiom=.TRUE.)
  242. tmpm(1,:,1) = E3W_3D(imin, jmin+1:jmin+1+npts,jk)
  243. tmpm(1,:,2) = E3W_3D(imin+1,jmin+1:jmin+1+npts,jk)
  244. IF (jk >= 2 ) THEN
  245. DO ji=1,npts
  246. gdepu(ji,jk)= gdepu(ji,jk-1) + MIN(tmpm(1,ji,1), tmpm(1,ji,2))
  247. END DO
  248. ENDIF
  249. ! Normal velocity
  250. tmpm(1,:,1) = U_3D(imin,jmin+1:jmin+1+npts,jk)
  251. zu(:,jk)=tmpm(1,1:npts,1)
  252. ! salinity and deduce umask for the section
  253. tmpm(1,:,1) = S_3D(imin, jmin+1:jmin+1+npts,jk)
  254. tmpm(1,:,2) = S_3D(imin+1,jmin+1:jmin+1+npts,jk)
  255. zmask(:,jk)=tmpm(1,1:npts,1)*tmpm(1,1:npts,2)
  256. WHERE ( zmask(:,jk) /= 0._8 ) zmask(:,jk)=1._8
  257. ! do not take special care for land value, as the corresponding velocity point is masked
  258. zs(:,jk) = 0.5 * ( tmpm(1,1:npts,1) + tmpm(1,1:npts,2) )
  259. ! limitation to 'wet' points
  260. IF ( SUM(zs(:,jk)) == 0._8 ) THEN
  261. nk=jk ! first vertical point of the section full on land
  262. EXIT ! as soon as all the points are on land
  263. ENDIF
  264. ! temperature
  265. tmpm(1,:,1) = T_3D(imin, jmin+1:jmin+1+npts,jk)
  266. tmpm(1,:,2) = T_3D(imin+1,jmin+1:jmin+1+npts,jk)
  267. zt(:,jk) = 0.5 * ( tmpm(1,1:npts,1) + tmpm(1,1:npts,2) )
  268. END DO
  269. ELSE ! zonal section at j=jmin=jmax
  270. !tmpz(npts,1,2)
  271. !tmpz(:,:,1)=getvar(cf_mm, 'e1v', 1,npts,1,kimin=imin, kjmin=jmin)
  272. !PRINT *, 'LOLO1 tmpz =>', tmpz(:,:,1)
  273. tmpz(:,1,1) = E1V_2D(imin:imin+npts,jmin)
  274. !PRINT *, 'LOLO2 tmpz =>', tmpz(:,:,1)
  275. eu=tmpz(1:npts,1,1)
  276. DO jk=1,npk
  277. ! initiliaze gdepu to gdept()
  278. gdepu(:,jk) = gdept(jk)
  279. ! vertical metrics (PS case)
  280. !tmpz(:,:,1)=getvar(cf_mm,'e3v_ps',jk, npts, 1, kimin=imin+1, kjmin=jmin, ldiom=.TRUE.)
  281. tmpz(:,1,1) = E3V_3D(imin+1:imin+1+npts,jmin,jk)
  282. e3(:,jk)=tmpz(1:npts,1,1)
  283. !tmpz(:,:,1)=getvar(cf_mm,'e3w_ps',jk,npts,1, kimin=imin+1, kjmin=jmin, ldiom=.TRUE.)
  284. !tmpz(:,:,2)=getvar(cf_mm,'e3w_ps',jk,npts,1, kimin=imin+1, kjmin=jmin+1, ldiom=.TRUE.)
  285. tmpz(:,1,1) = E3W_3D(imin+1:imin+1+npts,jmin, jk)
  286. tmpz(:,1,2) = E3W_3D(imin+1:imin+1+npts,jmin+1,jk)
  287. IF (jk >= 2 ) THEN
  288. DO ji=1,npts
  289. gdepu(ji,jk)= gdepu(ji,jk-1) + MIN(tmpz(ji,1,1), tmpz(ji,1,2))
  290. END DO
  291. ENDIF
  292. ! Normal velocity
  293. tmpz(:,1,1) = V_3D(imin+1:imin+1+npts,jmin, jk)
  294. zu(:,jk)=tmpz(1:npts,1,1)
  295. ! salinity and mask
  296. tmpz(:,1,1) = S_3D(imin+1:imin+1+npts,jmin, jk)
  297. tmpz(:,1,2) = S_3D(imin+1:imin+1+npts,jmin+1,jk)
  298. zmask(:,jk)=tmpz(1:npts,1,1)*tmpz(1:npts,1,2)
  299. WHERE ( zmask(:,jk) /= 0._8 ) zmask(:,jk)=1._8
  300. ! do not take special care for land value, as the corresponding velocity point is masked
  301. zs(:,jk) = 0.5 * ( tmpz(1:npts,1,1) + tmpz(1:npts,1,2) )
  302. ! limitation to 'wet' points
  303. IF ( SUM(zs(:,jk)) == 0._8 ) THEN
  304. nk=jk ! first vertical point of the section full on land
  305. EXIT ! as soon as all the points are on land
  306. ENDIF
  307. ! temperature
  308. tmpz(:,1,1) = T_3D(imin+1:imin+1+npts,jmin, jk)
  309. tmpz(:,1,2) = T_3D(imin+1:imin+1+npts,jmin+1,jk)
  310. zt(:,jk) = 0.5 * ( tmpz(1:npts,1,1) + tmpz(1:npts,1,2) )
  311. END DO
  312. ENDIF !(l_merid)
  313. ! compute density only for wet points
  314. zsig(:,1:nk)=sigma0( zt, zs, npts, nk)*zmask(:,1:nk)
  315. zsig(:,0)=zsig(:,1)-1.e-4 ! dummy layer for easy interpolation
  316. WRITE(cfor9000,'(a,i3,a)') '(i7,',npts,'f8.3)'
  317. WRITE(cfor9001,'(a,i3,a)') '(i7,',npts,'f8.0)'
  318. WRITE(cfor9002,'(a,i3,a)') '(f7.3,',npts,'f8.0)'
  319. WRITE(cfor9003,'(a,i3,a)') '(f7.3,',npts,'f8.3)'
  320. WRITE(cfor9004,'(a,i3,a)') '(f7.3,',npts+1,'f8.3)'
  321. DO jiso =1, nbins+1
  322. sigma=sigma_lev(jiso)
  323. DO ji=1,npts
  324. hiso(ji,jiso) = gdept(npk)
  325. DO jk=1,nk
  326. IF ( zsig(ji,jk) < sigma ) THEN
  327. ELSE
  328. ! interpolate between jk-1 and jk
  329. zalfa=(sigma - zsig(ji,jk-1)) / ( zsig(ji,jk) -zsig(ji,jk-1) )
  330. IF (ABS(zalfa) > 1.1 .OR. zalfa < 0 ) THEN ! case zsig(0) = zsig(1)-1.e-4
  331. hiso(ji,jiso)= 0.
  332. ELSE
  333. hiso(ji,jiso)= gdepu(ji,jk)*zalfa + (1.-zalfa)* gdepu(ji,jk-1)
  334. ENDIF
  335. EXIT
  336. ENDIF
  337. END DO
  338. END DO
  339. END DO
  340. DO jiso = 1, nbins + 1
  341. sigma=sigma_lev(jiso)
  342. DO ji=1,npts
  343. zwtrp(ji,jiso) = 0.d0
  344. DO jk=1, nk-1
  345. IF ( gdepw(jk+1) < hiso(ji,jiso) ) THEN
  346. zwtrp(ji,jiso)= zwtrp(ji,jiso) + eu(ji)*e3(ji,jk)*zu(ji,jk)
  347. ELSE ! last box ( fraction)
  348. zwtrp(ji,jiso)= zwtrp(ji,jiso) + eu(ji)*(hiso(ji,jiso)-gdepw(jk))*zu(ji,jk)
  349. EXIT ! jk loop
  350. ENDIF
  351. END DO
  352. END DO
  353. END DO
  354. !DO jbin=1, nbins
  355. ! sigma=sigma_lev(jbin)
  356. ! DO ji=1, npts
  357. ! zwtrpbin(ji,jbin) = zwtrp(ji,jbin+1) - zwtrp(ji,jbin)
  358. ! END DO
  359. ! trpbin(jsec,jbin)=SUM(zwtrpbin(:,jbin) )
  360. !END DO
  361. DO jbin=1, nbins
  362. sigma=sigma_lev(jbin)
  363. DO ji=1, npts
  364. zwtrpbin(ji,jbin) = zwtrp(ji,jbin+1) - zwtrp(ji,jbin)
  365. END DO
  366. XOUT(jsec,jbin,jt)= REAL( SUM(zwtrpbin(:,jbin))/1.e6 , 4)
  367. END DO
  368. ! free memory for the next section
  369. DEALLOCATE ( zu,zt, zs ,zsig ,gdepu, hiso, zwtrp, zwtrpbin )
  370. DEALLOCATE ( eu, e3 ,tmpm, tmpz,zmask )
  371. CLOSE(15)
  372. END DO !DO jsec=1,nsection
  373. END DO !DO jt = 1, nt
  374. WRITE(cf_out, '(a,"/transport_by_sigma_class.nc")') trim(cd_out)
  375. id_var_out(:) = 0
  376. INQUIRE( FILE=cf_out, EXIST=lfncout )
  377. IF ( .NOT. lfncout ) THEN
  378. !! Creating file
  379. PRINT *, ' Creating file '//trim(cf_out)//' !!!'
  380. ierr = NF90_CREATE(cf_out, NF90_CLOBBER, idf_out)
  381. ierr = NF90_DEF_DIM(idf_out, 'time', NF90_UNLIMITED, idd_t)
  382. ierr = NF90_DEF_DIM(idf_out, 'sigma_bins', nbins, idd_sbins)
  383. ierr = NF90_DEF_VAR(idf_out, 'time', NF90_DOUBLE, idd_t, idv_time)
  384. ierr = NF90_DEF_VAR(idf_out, 'sigma_bins', NF90_DOUBLE, idd_sbins, idv_sbins)
  385. WRITE(cdum,'(f8.4)') dsigma
  386. ierr = NF90_PUT_ATT(idf_out, idv_sbins, 'long_name', 'Center of sigma bin (dsigma = '//TRIM(cdum)//')')
  387. DO jsec=1, nsection
  388. ierr = NF90_DEF_VAR(idf_out, 'sigtrsp_'//TRIM(csection(jsec)), &
  389. & NF90_FLOAT, (/idd_sbins,idd_t/), id_var_out(jsec))
  390. ierr = NF90_PUT_ATT(idf_out, id_var_out(jsec), 'long_name', 'Transport by sigma class in section '//TRIM(csection(jsec)))
  391. ierr = NF90_PUT_ATT(idf_out, id_var_out(jsec), 'units', 'Sv')
  392. END DO
  393. ierr = NF90_PUT_ATT(idf_out, NF90_GLOBAL, 'About', &
  394. & 'Created by BaraKuda (cdfsigtrp.f90) => https://github.com/brodeau/barakuda')
  395. ierr = NF90_ENDDEF(idf_out)
  396. jt_pos = 0
  397. ierr = NF90_PUT_VAR( idf_out, idv_sbins, sigma_lev_center(:))
  398. ELSE
  399. !! Opening already existing file
  400. ierr = NF90_OPEN (cf_out, NF90_WRITE, idf_out)
  401. !! Need IDs of variables to append... NF90_INQ_VARID
  402. DO jsec=1, nsection
  403. ierr = NF90_INQ_VARID(idf_out, 'sigtrsp_'//TRIM(csection(jsec)), id_var_out(jsec))
  404. END DO
  405. ! Get ID of unlimited dimension
  406. ierr = NF90_INQUIRE(idf_out, unlimitedDimId = idv_time)
  407. ! Need to know jt_pos, record number of the last time record writen in the file
  408. ierr = NF90_INQUIRE_DIMENSION(idf_out, idv_time, name=cdum, len=jt_pos)
  409. END IF
  410. WRITE(*,'("Going to write record ",i4.4," to ",i4.4," into ",a)') jt_pos+1, jt_pos+1+nt, trim(cf_out)
  411. DO jt = 1, nt
  412. ! Writing record jt for time vector and 1d fields:
  413. ierr = NF90_PUT_VAR( idf_out, idv_time, (/ryear+1./12.*(REAL(jt)-1.+0.5)/), start=(/jt_pos+jt/), count=(/1/) )
  414. DO jsec=1, nsection
  415. ierr = NF90_PUT_VAR(idf_out, id_var_out(jsec), XOUT(jsec,:,jt), start=(/1,jt_pos+jt/), count=(/nbins,1/))
  416. END DO
  417. END DO
  418. ierr = NF90_CLOSE(idf_out)
  419. PRINT *, ' *** cdfsigtrp => '//TRIM(cf_out)//' written!'; PRINT *, ''
  420. CONTAINS
  421. SUBROUTINE section_init(cdfile,cdsection,kimin,kimax,kjmin,kjmax,knumber)
  422. IMPLICIT NONE
  423. ! Arguments
  424. ! INTEGER, DIMENSION(:),ALLOCATABLE :: kimin,kimax, kjmin,kjmax
  425. INTEGER, INTENT(INOUT) :: knumber
  426. INTEGER, DIMENSION(knumber) :: kimin,kimax, kjmin,kjmax
  427. ! CHARACTER(LEN=256), DIMENSION(:), ALLOCATABLE :: cdsection
  428. CHARACTER(LEN=256), DIMENSION(knumber) :: cdsection
  429. CHARACTER(LEN=*), INTENT(IN) :: cdfile
  430. ! Local variables
  431. INTEGER :: ii, numit=10, jsec
  432. CHARACTER(LEN=256) :: cline
  433. LOGICAL :: lfirst
  434. INTEGER :: idf_0=0, idv_0=0, idf_t=0, idv_t=0, idf_s=0, idv_s=0, &
  435. & idf_u=0, idv_u=0, idf_v=0, idv_v=0
  436. lfirst=.FALSE.
  437. IF ( knumber == 0 ) lfirst=.TRUE.
  438. OPEN(numit, FILE=cdfile, STATUS='old')
  439. REWIND(numit)
  440. ii=0
  441. DO
  442. READ(numit,'(a)') cline
  443. IF (INDEX(cline,'EOF') == 0 ) THEN
  444. READ(numit,*) ! skip one line
  445. ii = ii + 1
  446. ELSE
  447. EXIT
  448. ENDIF
  449. END DO
  450. knumber=ii
  451. IF ( lfirst ) RETURN
  452. ! ALLOCATE( cdsection(knumber) )
  453. ! ALLOCATE( kimin(knumber), kimax(knumber), kjmin(knumber), kjmax(knumber) )
  454. REWIND(numit)
  455. DO jsec=1,knumber
  456. READ(numit,'(a)') cdsection(jsec)
  457. READ(numit,*) kimin(jsec), kimax(jsec), kjmin(jsec), kjmax(jsec)
  458. END DO
  459. CLOSE(numit)
  460. END SUBROUTINE section_init
  461. END PROGRAM cdfsigtrp