limwri_2.F90 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. MODULE limwri_2
  2. !!======================================================================
  3. !! *** MODULE limwri_2 ***
  4. !! Ice diagnostics : write ice output files
  5. !!======================================================================
  6. !! history : 2.0 ! 2003-08 (C. Ethe) original code
  7. !! 2.0 ! 2004-10 (C. Ethe ) 1D configuration
  8. !! - ! 2009-06 (B. Lemaire ) iom_put + lim_wri_state_2
  9. !!-------------------------------------------------------------------
  10. #if defined key_lim2
  11. !!----------------------------------------------------------------------
  12. !! 'key_lim2' LIM 2.0 sea-ice model
  13. !!----------------------------------------------------------------------
  14. !!----------------------------------------------------------------------
  15. !! lim_wri_2 : write of the diagnostics variables in ouput file
  16. !! lim_wri_init_2 : initialization and namelist read
  17. !! lim_wri_state_2 : write for initial state or/and abandon:
  18. !! > output.init.nc (if ninist = 1 in namelist)
  19. !! > output.abort.nc
  20. !!----------------------------------------------------------------------
  21. USE phycst
  22. USE dom_oce
  23. USE sbc_oce
  24. USE sbc_ice
  25. USE dom_ice_2
  26. USE ice_2
  27. USE dianam ! build name of file (routine)
  28. USE lbclnk
  29. USE in_out_manager
  30. USE lib_mpp ! MPP library
  31. USE wrk_nemo ! work arrays
  32. USE iom
  33. USE ioipsl
  34. USE lib_fortran ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined)
  35. IMPLICIT NONE
  36. PRIVATE
  37. #if ! defined key_iomput
  38. PUBLIC lim_wri_2 ! called by sbc_ice_lim_2
  39. #endif
  40. PUBLIC lim_wri_state_2 ! called by dia_wri_state
  41. PUBLIC lim_wri_alloc_2 ! called by nemogcm.F90
  42. INTEGER, PARAMETER :: jpnoumax = 40 ! maximum number of variable for ice output
  43. INTEGER :: noumef ! number of fields
  44. REAL(wp) , DIMENSION(jpnoumax) :: cmulti , & ! multiplicative constant
  45. & cadd ! additive constant
  46. CHARACTER(len = 35), DIMENSION(jpnoumax) :: titn ! title of the field
  47. CHARACTER(len = 8 ), DIMENSION(jpnoumax) :: nam ! name of the field
  48. CHARACTER(len = 8 ), DIMENSION(jpnoumax) :: uni ! unit of the field
  49. INTEGER , DIMENSION(jpnoumax) :: nc ! switch for saving field ( = 1 ) or not ( = 0 )
  50. INTEGER :: nice, nhorid, ndim, niter, ndepid ! ????
  51. INTEGER, ALLOCATABLE, SAVE, DIMENSION(:) :: ndex51 ! ????
  52. REAL(wp) :: epsi16 = 1.e-16_wp ! constant values
  53. REAL(wp) :: zzero = 0._wp ! - -
  54. REAL(wp) :: zone = 1._wp ! - -
  55. REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: zcmo ! Workspace array for netcdf writer.
  56. !! * Substitutions
  57. # include "vectopt_loop_substitute.h90"
  58. !!----------------------------------------------------------------------
  59. !! NEMO/LIM2 3.3 , UCL - NEMO Consortium (2010)
  60. !! $Id: limwri_2.F90 4696 2014-06-26 13:10:44Z clem $
  61. !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
  62. !!----------------------------------------------------------------------
  63. CONTAINS
  64. INTEGER FUNCTION lim_wri_alloc_2()
  65. !!-------------------------------------------------------------------
  66. !! *** ROUTINE lim_wri_alloc_2 ***
  67. !!-------------------------------------------------------------------
  68. ALLOCATE( ndex51(jpij), zcmo(jpi,jpj,jpnoumax), STAT=lim_wri_alloc_2)
  69. !
  70. IF( lk_mpp ) CALL mpp_sum ( lim_wri_alloc_2 )
  71. IF( lim_wri_alloc_2 /= 0 ) CALL ctl_warn('lim_wri_alloc_2: failed to allocate array ndex51')
  72. !
  73. END FUNCTION lim_wri_alloc_2
  74. #if ! defined key_iomput
  75. # if defined key_dimgout
  76. !!----------------------------------------------------------------------
  77. !! 'key_dimgout' Direct Access file
  78. !!----------------------------------------------------------------------
  79. # include "limwri_dimg_2.h90"
  80. # else
  81. SUBROUTINE lim_wri_2( kt )
  82. !!-------------------------------------------------------------------
  83. !! *** ROUTINE lim_wri_2 ***
  84. !!
  85. !! ** Purpose : write the sea-ice output file in NetCDF
  86. !!
  87. !! ** Method : computes the average of some variables and write
  88. !! it in the NetCDF ouput files
  89. !! CAUTION: the sea-ice time-step must be an integer fraction
  90. !! of a day
  91. !!-------------------------------------------------------------------
  92. INTEGER, INTENT(in) :: kt ! number of iteration
  93. !!
  94. INTEGER :: ji, jj, jf ! dummy loop indices
  95. CHARACTER(len = 80) :: clhstnam, clop
  96. REAL(wp) :: zsto, zjulian, zout, & ! temporary scalars
  97. & zindh, zinda, zindb, ztmu
  98. REAL(wp), DIMENSION(1) :: zdept
  99. REAL(wp), POINTER, DIMENSION(:,:) :: zfield
  100. !!-------------------------------------------------------------------
  101. CALL wrk_alloc( jpi, jpj, zfield )
  102. !--------------------!
  103. IF( kt == nit000 ) THEN ! Initialisation !
  104. ! !--------------------!
  105. CALL lim_wri_init_2
  106. zsto = rdt_ice
  107. IF( ln_mskland ) THEN ; clop = "ave(only(x))" ! put 1.e+20 on land (very expensive!!)
  108. ELSE ; clop = "ave(x)" ! no use of the mask value (require less cpu time)
  109. ENDIF
  110. zout = nwrite * rdt_ice / nn_fsbc
  111. niter = ( nit000 - 1 ) / nn_fsbc
  112. zdept(1) = 0.
  113. CALL ymds2ju ( nyear, nmonth, nday, rdt, zjulian )
  114. zjulian = zjulian - adatrj ! set calendar origin to the beginning of the experiment
  115. CALL dia_nam ( clhstnam, nwrite, 'icemod' )
  116. CALL histbeg ( clhstnam, jpi, glamt, jpj, gphit, &
  117. & 1, jpi, 1, jpj, niter, zjulian, rdt_ice, nhorid, nice , domain_id=nidom, snc4chunks=snc4set)
  118. CALL histvert( nice, "deptht", "Vertical T levels", "m", 1, zdept, ndepid, "down")
  119. CALL wheneq ( jpij , tmask(:,:,1), 1, 1., ndex51, ndim)
  120. DO jf = 1, noumef
  121. IF( nc(jf) == 1 ) CALL histdef( nice, nam(jf), titn(jf), uni(jf), jpi, jpj &
  122. & , nhorid, 1, 1, 1, -99, 32, clop, zsto, zout )
  123. END DO
  124. CALL histend( nice, snc4set )
  125. !
  126. ENDIF
  127. ! !--------------------!
  128. ! ! Cumulate at kt !
  129. ! !--------------------!
  130. !-- Store instantaneous values in zcmo
  131. zcmo(:,:, 1:jpnoumax ) = 0.e0
  132. DO jj = 2 , jpjm1
  133. DO ji = 2 , jpim1 ! NO vector opt.
  134. zindh = MAX( zzero , SIGN( zone , hicif(ji,jj) * (1.0 - frld(ji,jj) ) - 0.10 ) )
  135. zinda = MAX( zzero , SIGN( zone , ( 1.0 - frld(ji,jj) ) - 0.10 ) )
  136. zindb = zindh * zinda
  137. ztmu = MAX( 0.5 * zone , ( tmu(ji,jj) + tmu(ji+1,jj) + tmu(ji,jj+1) + tmu(ji+1,jj+1) ) )
  138. zcmo(ji,jj,1) = hsnif (ji,jj)
  139. zcmo(ji,jj,2) = hicif (ji,jj)
  140. zcmo(ji,jj,3) = hicifp(ji,jj)
  141. zcmo(ji,jj,4) = frld (ji,jj)
  142. zcmo(ji,jj,5) = sist (ji,jj)
  143. zcmo(ji,jj,6) = fbif (ji,jj)
  144. IF (lk_lim2_vp) THEN
  145. zcmo(ji,jj,7) = zindb * ( u_ice(ji,jj ) * tmu(ji,jj ) + u_ice(ji+1,jj ) * tmu(ji+1,jj ) &
  146. + u_ice(ji,jj+1) * tmu(ji,jj+1) + u_ice(ji+1,jj+1) * tmu(ji+1,jj+1) ) &
  147. / ztmu
  148. zcmo(ji,jj,8) = zindb * ( v_ice(ji,jj ) * tmu(ji,jj ) + v_ice(ji+1,jj ) * tmu(ji+1,jj ) &
  149. + v_ice(ji,jj+1) * tmu(ji,jj+1) + v_ice(ji+1,jj+1) * tmu(ji+1,jj+1) ) &
  150. / ztmu
  151. ELSE
  152. zcmo(ji,jj,7) = zindb * ( u_ice(ji,jj ) * tmu(ji,jj) &
  153. & + u_ice(ji-1,jj) * tmu(ji-1,jj) ) &
  154. & / 2.0
  155. zcmo(ji,jj,8) = zindb * ( v_ice(ji,jj ) * tmv(ji,jj) &
  156. & + v_ice(ji,jj-1) * tmv(ji,jj-1) ) &
  157. & / 2.0
  158. ENDIF
  159. zcmo(ji,jj,9) = sst_m(ji,jj)
  160. zcmo(ji,jj,10) = sss_m(ji,jj)
  161. zcmo(ji,jj,11) = qns(ji,jj) + qsr(ji,jj)
  162. zcmo(ji,jj,12) = qsr(ji,jj)
  163. zcmo(ji,jj,13) = qns(ji,jj)
  164. ! See thersf for the coefficient
  165. zcmo(ji,jj,14) = - sfx (ji,jj) * rday * ( sss_m(ji,jj) + epsi16 ) / soce !!gm ???
  166. zcmo(ji,jj,15) = utau_ice(ji,jj)
  167. zcmo(ji,jj,16) = vtau_ice(ji,jj)
  168. zcmo(ji,jj,17) = qsr_ice(ji,jj,1)
  169. zcmo(ji,jj,18) = qns_ice(ji,jj,1)
  170. zcmo(ji,jj,19) = sprecip(ji,jj)
  171. END DO
  172. END DO
  173. !
  174. ! Write the netcdf file
  175. !
  176. niter = niter + 1
  177. DO jf = 1 , noumef
  178. zfield(:,:) = zcmo(:,:,jf) * cmulti(jf) + cadd(jf) * tmask(:,:,1)
  179. SELECT CASE ( jf )
  180. CASE ( 7, 8, 15, 16, 20, 21 ) ! velocity or stress fields (vectors)
  181. CALL lbc_lnk( zfield, 'T', -1. )
  182. CASE DEFAULT ! scalar fields
  183. CALL lbc_lnk( zfield, 'T', 1. )
  184. END SELECT
  185. IF( nc(jf) == 1 ) CALL histwrite( nice, nam(jf), niter, zfield, ndim, ndex51 )
  186. END DO
  187. IF( ( nn_fsbc * niter ) >= nitend ) CALL histclo( nice )
  188. CALL wrk_dealloc( jpi, jpj, zfield )
  189. !
  190. END SUBROUTINE lim_wri_2
  191. #endif
  192. SUBROUTINE lim_wri_init_2
  193. !!-------------------------------------------------------------------
  194. !! *** ROUTINE lim_wri_init_2 ***
  195. !!
  196. !! ** Purpose : intialisation of LIM sea-ice output
  197. !!
  198. !! ** Method : Read the namicewri namelist and check the parameter
  199. !! values called at the first timestep (nit000)
  200. !!
  201. !! ** input : Namelist namicewri
  202. !!-------------------------------------------------------------------
  203. INTEGER :: nf ! ???
  204. INTEGER :: ios ! Local integer output status for namelist read
  205. TYPE FIELD
  206. CHARACTER(len = 35) :: ztitle
  207. CHARACTER(len = 8 ) :: zname
  208. CHARACTER(len = 8 ) :: zunit
  209. INTEGER :: znc
  210. REAL :: zcmulti
  211. REAL :: zcadd
  212. END TYPE FIELD
  213. TYPE(FIELD) :: &
  214. field_1 , field_2 , field_3 , field_4 , field_5 , field_6 , &
  215. field_7 , field_8 , field_9 , field_10, field_11, field_12, &
  216. field_13, field_14, field_15, field_16, field_17, field_18, &
  217. field_19
  218. TYPE(FIELD) , DIMENSION(jpnoumax) :: zfield
  219. NAMELIST/namiceout/ noumef, &
  220. field_1 , field_2 , field_3 , field_4 , field_5 , field_6 , &
  221. field_7 , field_8 , field_9 , field_10, field_11, field_12, &
  222. field_13, field_14, field_15, field_16, field_17, field_18, &
  223. field_19
  224. !!-------------------------------------------------------------------
  225. !
  226. IF( lim_wri_alloc_2() /= 0 ) THEN ! allocate lim_wri arrrays
  227. CALL ctl_stop( 'STOP', 'lim_wri_init_2 : unable to allocate standard arrays' ) ; RETURN
  228. ENDIF
  229. REWIND( numnam_ice_ref ) ! Namelist namiceout in reference namelist : Ice outputs
  230. READ ( numnam_ice_ref, namiceout, IOSTAT = ios, ERR = 901)
  231. 901 IF( ios /= 0 ) CALL ctl_nam ( ios , 'namiceout in reference namelist', lwp )
  232. REWIND( numnam_ice_cfg ) ! Namelist namiceout in configuration namelist : Ice outputs
  233. READ ( numnam_ice_cfg, namiceout, IOSTAT = ios, ERR = 902 )
  234. 902 IF( ios /= 0 ) CALL ctl_nam ( ios , 'namiceout in configuration namelist', lwp )
  235. IF(lwm) WRITE ( numoni, namiceout )
  236. zfield( 1) = field_1
  237. zfield( 2) = field_2
  238. zfield( 3) = field_3
  239. zfield( 4) = field_4
  240. zfield( 5) = field_5
  241. zfield( 6) = field_6
  242. zfield( 7) = field_7
  243. zfield( 8) = field_8
  244. zfield( 9) = field_9
  245. zfield(10) = field_10
  246. zfield(11) = field_11
  247. zfield(12) = field_12
  248. zfield(13) = field_13
  249. zfield(14) = field_14
  250. zfield(15) = field_15
  251. zfield(16) = field_16
  252. zfield(17) = field_17
  253. zfield(18) = field_18
  254. zfield(19) = field_19
  255. DO nf = 1, noumef
  256. titn (nf) = zfield(nf)%ztitle
  257. nam (nf) = zfield(nf)%zname
  258. uni (nf) = zfield(nf)%zunit
  259. nc (nf) = zfield(nf)%znc
  260. cmulti(nf) = zfield(nf)%zcmulti
  261. cadd (nf) = zfield(nf)%zcadd
  262. END DO
  263. IF(lwp) THEN
  264. WRITE(numout,*)
  265. WRITE(numout,*) 'lim_wri_init_2 : Ice parameters for outputs'
  266. WRITE(numout,*) '~~~~~~~~~~~~~~'
  267. WRITE(numout,*) ' number of fields to be stored noumef = ', noumef
  268. WRITE(numout,*) ' title name unit Saving (1/0) ', &
  269. & ' multiplicative constant additive constant '
  270. DO nf = 1 , noumef
  271. WRITE(numout,*) ' ', titn(nf), ' ', nam(nf),' ', uni(nf),' ', nc(nf),' ', cmulti(nf), &
  272. & ' ', cadd(nf)
  273. END DO
  274. ENDIF
  275. !
  276. END SUBROUTINE lim_wri_init_2
  277. #endif
  278. SUBROUTINE lim_wri_state_2( kt, kid, kh_i )
  279. !!---------------------------------------------------------------------
  280. !! *** ROUTINE lim_wri_state_2 ***
  281. !!
  282. !! ** Purpose : create a NetCDF file named cdfile_name which contains
  283. !! the instantaneous ice state and forcing fields for ice model
  284. !! Used to find errors in the initial state or save the last
  285. !! ocean state in case of abnormal end of a simulation
  286. !!
  287. !! History :
  288. !! 2.0 ! 2009-06 (B. Lemaire)
  289. !!----------------------------------------------------------------------
  290. INTEGER, INTENT( in ) :: kt ! ocean time-step index)
  291. INTEGER, INTENT( in ) :: kid , kh_i
  292. !!----------------------------------------------------------------------
  293. CALL histdef( kid, "isnowthi", "Snow thickness" , "m" , jpi, jpj, kh_i, 1, 1, 1, -99, 32, "inst(x)", rdt, rdt )
  294. CALL histdef( kid, "iicethic", "Ice thickness" , "m" , jpi, jpj, kh_i, 1, 1, 1, -99, 32, "inst(x)", rdt, rdt )
  295. CALL histdef( kid, "iiceprod", "Ice produced" , "m/kt" , jpi, jpj, kh_i, 1, 1, 1, -99, 32, "inst(x)", rdt, rdt )
  296. CALL histdef( kid, "ileadfra", "Ice concentration" , "-" , jpi, jpj, kh_i, 1, 1, 1, -99, 32, "inst(x)", rdt, rdt )
  297. CALL histdef( kid, "iicetemp", "Ice temperature" , "K" , jpi, jpj, kh_i, 1, 1, 1, -99, 32, "inst(x)", rdt, rdt )
  298. CALL histdef( kid, "iicevelu", "i-Ice speed (I-point)" , "m/s" , jpi, jpj, kh_i, 1, 1, 1, -99, 32, "inst(x)", rdt, rdt )
  299. CALL histdef( kid, "iicevelv", "j-Ice speed (I-point)" , "m/s" , jpi, jpj, kh_i, 1, 1, 1, -99, 32, "inst(x)", rdt, rdt )
  300. CALL histdef( kid, "isstempe", "Sea surface temperature" , "C" , jpi, jpj, kh_i, 1, 1, 1, -99, 32, "inst(x)", rdt, rdt )
  301. CALL histdef( kid, "isssalin", "Sea surface salinity" , "PSU" , jpi, jpj, kh_i, 1, 1, 1, -99, 32, "inst(x)", rdt, rdt )
  302. CALL histdef( kid, "iicestru", "i-Wind stress over ice (I-pt)", "Pa", jpi, jpj, kh_i, 1, 1, 1, -99, 32, "inst(x)", rdt, rdt )
  303. CALL histdef( kid, "iicestrv", "j-Wind stress over ice (I-pt)", "Pa", jpi, jpj, kh_i, 1, 1, 1, -99, 32, "inst(x)", rdt, rdt )
  304. CALL histdef( kid, "iicesflx", "Solar flux over ice" , "w/m2" , jpi, jpj, kh_i, 1, 1, 1, -99, 32, "inst(x)", rdt, rdt )
  305. CALL histdef( kid, "iicenflx", "Non-solar flux over ice" , "w/m2" , jpi, jpj, kh_i, 1, 1, 1, -99, 32, "inst(x)", rdt, rdt )
  306. CALL histdef( kid, "isnowpre", "Snow precipitation" , "kg/m2/s", jpi, jpj, kh_i, 1, 1, 1, -99, 32, "inst(x)", rdt, rdt )
  307. CALL histend( kid, snc4set ) ! end of the file definition
  308. CALL histwrite( kid, "isnowthi", kt, hsnif , jpi*jpj, (/1/) )
  309. CALL histwrite( kid, "iicethic", kt, hicif , jpi*jpj, (/1/) )
  310. CALL histwrite( kid, "iiceprod", kt, hicifp , jpi*jpj, (/1/) )
  311. CALL histwrite( kid, "ileadfra", kt, 1. - frld(:,:) , jpi*jpj, (/1/) )
  312. CALL histwrite( kid, "iicetemp", kt, sist(:,:) - rt0, jpi*jpj, (/1/) )
  313. CALL histwrite( kid, "iicevelu", kt, u_ice , jpi*jpj, (/1/) )
  314. CALL histwrite( kid, "iicevelv", kt, v_ice , jpi*jpj, (/1/) )
  315. CALL histwrite( kid, "isstempe", kt, sst_m , jpi*jpj, (/1/) )
  316. CALL histwrite( kid, "isssalin", kt, sss_m , jpi*jpj, (/1/) )
  317. CALL histwrite( kid, "iicestru", kt, utau_ice , jpi*jpj, (/1/) )
  318. CALL histwrite( kid, "iicestrv", kt, vtau_ice , jpi*jpj, (/1/) )
  319. CALL histwrite( kid, "iicesflx", kt, qsr_ice(:,:,1) , jpi*jpj, (/1/) )
  320. CALL histwrite( kid, "iicenflx", kt, qns_ice(:,:,1) , jpi*jpj, (/1/) )
  321. CALL histwrite( kid, "isnowpre", kt, sprecip , jpi*jpj, (/1/) )
  322. END SUBROUTINE lim_wri_state_2
  323. #else
  324. !!----------------------------------------------------------------------
  325. !! Default option : Empty module NO LIM 2.0 sea-ice model
  326. !!----------------------------------------------------------------------
  327. CONTAINS
  328. SUBROUTINE lim_wri_2 ! Empty routine
  329. END SUBROUTINE lim_wri_2
  330. #endif
  331. !!======================================================================
  332. END MODULE limwri_2