limrhg.F90 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836
  1. MODULE limrhg
  2. !!======================================================================
  3. !! *** MODULE limrhg ***
  4. !! Ice rheology : sea ice rheology
  5. !!======================================================================
  6. !! History : - ! 2007-03 (M.A. Morales Maqueda, S. Bouillon) Original code
  7. !! 3.0 ! 2008-03 (M. Vancoppenolle) LIM3
  8. !! - ! 2008-11 (M. Vancoppenolle, S. Bouillon, Y. Aksenov) add surface tilt in ice rheolohy
  9. !! 3.3 ! 2009-05 (G.Garric) addition of the lim2_evp cas
  10. !! 3.4 ! 2011-01 (A. Porter) dynamical allocation
  11. !! 3.5 ! 2012-08 (R. Benshila) AGRIF
  12. !! 3.6 ! 2016-06 (C. Rousset) Rewriting (conserves energy)
  13. !!----------------------------------------------------------------------
  14. #if defined key_lim3 || ( defined key_lim2 && ! defined key_lim2_vp )
  15. !!----------------------------------------------------------------------
  16. !! 'key_lim3' OR LIM-3 sea-ice model
  17. !! 'key_lim2' AND NOT 'key_lim2_vp' EVP LIM-2 sea-ice model
  18. !!----------------------------------------------------------------------
  19. !! lim_rhg : computes ice velocities
  20. !!----------------------------------------------------------------------
  21. USE phycst ! Physical constant
  22. USE oce , ONLY : snwice_mass, snwice_mass_b
  23. USE par_oce ! Ocean parameters
  24. USE dom_oce ! Ocean domain
  25. USE sbc_oce ! Surface boundary condition: ocean fields
  26. USE sbc_ice ! Surface boundary condition: ice fields
  27. #if defined key_lim3
  28. USE ice ! LIM-3: ice variables
  29. USE dom_ice ! LIM-3: ice domain
  30. USE limitd_me ! LIM-3:
  31. #else
  32. USE ice_2 ! LIM-2: ice variables
  33. USE dom_ice_2 ! LIM-2: ice domain
  34. #endif
  35. USE lbclnk ! Lateral Boundary Condition / MPP link
  36. USE lib_mpp ! MPP library
  37. USE wrk_nemo ! work arrays
  38. USE in_out_manager ! I/O manager
  39. USE prtctl ! Print control
  40. USE iom
  41. USE lib_fortran ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined)
  42. #if defined key_agrif && defined key_lim2
  43. USE agrif_lim2_interp
  44. #endif
  45. #if defined key_bdy
  46. USE bdyice_lim
  47. #endif
  48. IMPLICIT NONE
  49. PRIVATE
  50. PUBLIC lim_rhg ! routine called by lim_dyn (or lim_dyn_2)
  51. !! * Substitutions
  52. # include "vectopt_loop_substitute.h90"
  53. !!----------------------------------------------------------------------
  54. !! NEMO/LIM3 4.0 , UCL - NEMO Consortium (2011)
  55. !! $Id: limrhg.F90 8285 2017-07-06 06:40:51Z vancop $
  56. !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
  57. !!----------------------------------------------------------------------
  58. CONTAINS
  59. SUBROUTINE lim_rhg( k_j1, k_jpj )
  60. !!-------------------------------------------------------------------
  61. !! *** SUBROUTINE lim_rhg ***
  62. !! EVP-C-grid
  63. !!
  64. !! ** purpose : determines sea ice drift from wind stress, ice-ocean
  65. !! stress and sea-surface slope. Ice-ice interaction is described by
  66. !! a non-linear elasto-viscous-plastic (EVP) law including shear
  67. !! strength and a bulk rheology (Hunke and Dukowicz, 2002).
  68. !!
  69. !! The points in the C-grid look like this, dear reader
  70. !!
  71. !! (ji,jj)
  72. !! |
  73. !! |
  74. !! (ji-1,jj) | (ji,jj)
  75. !! ---------
  76. !! | |
  77. !! | (ji,jj) |------(ji,jj)
  78. !! | |
  79. !! ---------
  80. !! (ji-1,jj-1) (ji,jj-1)
  81. !!
  82. !! ** Inputs : - wind forcing (stress), oceanic currents
  83. !! ice total volume (vt_i) per unit area
  84. !! snow total volume (vt_s) per unit area
  85. !!
  86. !! ** Action : - compute u_ice, v_ice : the components of the
  87. !! sea-ice velocity vector
  88. !! - compute delta_i, shear_i, divu_i, which are inputs
  89. !! of the ice thickness distribution
  90. !!
  91. !! ** Steps : 1) Compute ice snow mass, ice strength
  92. !! 2) Compute wind, oceanic stresses, mass terms and
  93. !! coriolis terms of the momentum equation
  94. !! 3) Solve the momentum equation (iterative procedure)
  95. !! 4) Recompute invariants of the strain rate tensor
  96. !! which are inputs of the ITD, store stress
  97. !! for the next time step
  98. !! 5) Control prints of residual (convergence)
  99. !! and charge ellipse.
  100. !! The user should make sure that the parameters
  101. !! nn_nevp, elastic time scale and rn_creepl maintain stress state
  102. !! on the charge ellipse for plastic flow
  103. !! e.g. in the Canadian Archipelago
  104. !!
  105. !! ** Notes : Boundary condition for ice is chosen no-slip
  106. !! but can be adjusted with param rn_shlat
  107. !!
  108. !! References : Hunke and Dukowicz, JPO97
  109. !! Bouillon et al., Ocean Modelling 2009
  110. !!-------------------------------------------------------------------
  111. INTEGER, INTENT(in) :: k_j1 ! southern j-index for ice computation
  112. INTEGER, INTENT(in) :: k_jpj ! northern j-index for ice computation
  113. !!
  114. INTEGER :: ji, jj ! dummy loop indices
  115. INTEGER :: jter ! local integers
  116. CHARACTER (len=50) :: charout
  117. REAL(wp) :: zdtevp, z1_dtevp ! time step for subcycling
  118. REAL(wp) :: ecc2, z1_ecc2 ! square of yield ellipse eccenticity
  119. REAL(wp) :: zbeta, zalph1, z1_alph1, zalph2, z1_alph2 ! alpha and beta from Bouillon 2009 and 2013
  120. REAL(wp) :: zm1, zm2, zm3, zmassU, zmassV ! ice/snow mass
  121. REAL(wp) :: zdelta, zp_delf, zds2, zdt, zdt2, zdiv, zdiv2 ! temporary scalars
  122. REAL(wp) :: zTauO, zTauE ! temporary scalars
  123. REAL(wp) :: zsig1, zsig2 ! internal ice stress
  124. REAL(wp) :: zresm ! Maximal error on ice velocity
  125. REAL(wp) :: zintb, zintn ! dummy argument
  126. REAL(wp) :: zfac_x, zfac_y
  127. REAL(wp), POINTER, DIMENSION(:,:) :: zpresh ! temporary array for ice strength
  128. REAL(wp), POINTER, DIMENSION(:,:) :: z1_e1t0, z1_e2t0 ! scale factors
  129. REAL(wp), POINTER, DIMENSION(:,:) :: zp_delt ! P/delta at T points
  130. !
  131. REAL(wp), POINTER, DIMENSION(:,:) :: zaU , zaV ! ice fraction on U/V points
  132. REAL(wp), POINTER, DIMENSION(:,:) :: zmU_t, zmV_t ! ice/snow mass/dt on U/V points
  133. REAL(wp), POINTER, DIMENSION(:,:) :: zmf ! coriolis parameter at T points
  134. REAL(wp), POINTER, DIMENSION(:,:) :: zTauU_ia , ztauV_ia ! ice-atm. stress at U-V points
  135. REAL(wp), POINTER, DIMENSION(:,:) :: zspgU , zspgV ! surface pressure gradient at U/V points
  136. REAL(wp), POINTER, DIMENSION(:,:) :: v_oceU, u_oceV, v_iceU, u_iceV ! ocean/ice u/v component on V/U points
  137. REAL(wp), POINTER, DIMENSION(:,:) :: zfU , zfV ! internal stresses
  138. REAL(wp), POINTER, DIMENSION(:,:) :: zds ! shear
  139. REAL(wp), POINTER, DIMENSION(:,:) :: zs1, zs2, zs12 ! stress tensor components
  140. REAL(wp), POINTER, DIMENSION(:,:) :: zu_ice, zv_ice, zresr ! check convergence
  141. REAL(wp), POINTER, DIMENSION(:,:) :: zpice ! array used for the calculation of ice surface slope:
  142. ! ocean surface (ssh_m) if ice is not embedded
  143. ! ice top surface if ice is embedded
  144. REAL(wp), POINTER, DIMENSION(:,:) :: zCorx, zCory ! Coriolis stress array
  145. REAL(wp), POINTER, DIMENSION(:,:) :: ztaux_oi, ztauy_oi ! Ocean-to-ice stress array
  146. REAL(wp), POINTER, DIMENSION(:,:) :: zswitchU, zswitchV ! dummy arrays
  147. REAL(wp), POINTER, DIMENSION(:,:) :: zmaskU, zmaskV ! mask for ice presence
  148. REAL(wp), POINTER, DIMENSION(:,:) :: zfmask, zwf ! mask at F points for the ice
  149. REAL(wp), POINTER, DIMENSION(:,:) :: zdiag_xmtrp_ice ! X-component of ice mass transport (kg/s)
  150. REAL(wp), POINTER, DIMENSION(:,:) :: zdiag_ymtrp_ice ! Y-component of ice mass transport (kg/s)
  151. REAL(wp), POINTER, DIMENSION(:,:) :: zdiag_xmtrp_snw ! X-component of snow mass transport (kg/s)
  152. REAL(wp), POINTER, DIMENSION(:,:) :: zdiag_ymtrp_snw ! Y-component of snow mass transport (kg/s)
  153. REAL(wp), POINTER, DIMENSION(:,:) :: zdiag_xatrp ! X-component of area transport (m2/s)
  154. REAL(wp), POINTER, DIMENSION(:,:) :: zdiag_yatrp ! Y-component of area transport (m2/s)
  155. REAL(wp), POINTER, DIMENSION(:,:) :: zdiag_utau_oi ! X-direction ocean-ice stress
  156. REAL(wp), POINTER, DIMENSION(:,:) :: zdiag_vtau_oi ! Y-direction ocean-ice stress
  157. REAL(wp), POINTER, DIMENSION(:,:) :: zdiag_dssh_dx ! X-direction sea-surface tilt term (N/m2)
  158. REAL(wp), POINTER, DIMENSION(:,:) :: zdiag_dssh_dy ! X-direction sea-surface tilt term (N/m2)
  159. REAL(wp), POINTER, DIMENSION(:,:) :: zdiag_corstrx ! X-direction coriolis stress (N/m2)
  160. REAL(wp), POINTER, DIMENSION(:,:) :: zdiag_corstry ! Y-direction coriolis stress (N/m2)
  161. REAL(wp), POINTER, DIMENSION(:,:) :: zdiag_intstrx ! X-direction internal stress (N/m2)
  162. REAL(wp), POINTER, DIMENSION(:,:) :: zdiag_intstry ! Y-direction internal stress (N/m2)
  163. REAL(wp), POINTER, DIMENSION(:,:) :: zdiag_sig1 ! Average normal stress in sea ice
  164. REAL(wp), POINTER, DIMENSION(:,:) :: zdiag_sig2 ! Maximum shear stress in sea ice
  165. REAL(wp), POINTER, DIMENSION(:,:) :: zswi, zmiss ! Switch & missing value array
  166. REAL(wp), PARAMETER :: zepsi = 1.0e-20_wp ! tolerance parameter
  167. REAL(wp), PARAMETER :: zmmin = 1._wp ! ice mass (kg/m2) below which ice velocity equals ocean velocity
  168. REAL(wp), PARAMETER :: zshlat = 2._wp ! boundary condition for sea-ice velocity (2=no slip ; 0=free slip)
  169. REAL(wp), PARAMETER :: zmiss_val = 1.0e+20 ! missing value for outputs
  170. !!-------------------------------------------------------------------
  171. CALL wrk_alloc( jpi,jpj, zpresh, z1_e1t0, z1_e2t0, zp_delt )
  172. CALL wrk_alloc( jpi,jpj, zaU, zaV, zmU_t, zmV_t, zmf, zTauU_ia, ztauV_ia )
  173. CALL wrk_alloc( jpi,jpj, zspgU, zspgV, v_oceU, u_oceV, v_iceU, u_iceV, zfU, zfV )
  174. CALL wrk_alloc( jpi,jpj, zds, zs1, zs2, zs12, zu_ice, zv_ice, zresr, zpice )
  175. CALL wrk_alloc( jpi,jpj, zswitchU, zswitchV, zmaskU, zmaskV, zfmask, zwf )
  176. CALL wrk_alloc( jpi,jpj, zCorx, zCory)
  177. CALL wrk_alloc( jpi,jpj, ztaux_oi, ztauy_oi)
  178. CALL wrk_alloc( jpi,jpj, zdiag_xmtrp_ice, zdiag_ymtrp_ice )
  179. CALL wrk_alloc( jpi,jpj, zdiag_xmtrp_snw, zdiag_ymtrp_snw )
  180. CALL wrk_alloc( jpi,jpj, zdiag_xatrp , zdiag_yatrp )
  181. CALL wrk_alloc( jpi,jpj, zdiag_utau_oi , zdiag_vtau_oi )
  182. CALL wrk_alloc( jpi,jpj, zdiag_dssh_dx , zdiag_dssh_dy )
  183. CALL wrk_alloc( jpi,jpj, zdiag_corstrx , zdiag_corstry )
  184. CALL wrk_alloc( jpi,jpj, zdiag_intstrx , zdiag_intstry )
  185. CALL wrk_alloc( jpi,jpj, zdiag_sig1 , zdiag_sig2 )
  186. CALL wrk_alloc( jpi,jpj, zswi , zmiss )
  187. #if defined key_lim2 && ! defined key_lim2_vp
  188. # if defined key_agrif
  189. USE ice_2, vt_s => hsnm
  190. USE ice_2, vt_i => hicm
  191. # else
  192. vt_s => hsnm
  193. vt_i => hicm
  194. # endif
  195. at_i(:,:) = 1. - frld(:,:)
  196. #endif
  197. #if defined key_agrif && defined key_lim2
  198. CALL agrif_rhg_lim2_load ! First interpolation of coarse values
  199. #endif
  200. !
  201. !------------------------------------------------------------------------------!
  202. ! 0) mask at F points for the ice (on the whole domain, not only k_j1,k_jpj)
  203. !------------------------------------------------------------------------------!
  204. ! ocean/land mask
  205. DO jj = 1, jpjm1
  206. DO ji = 1, jpim1 ! NO vector opt.
  207. zfmask(ji,jj) = tmask(ji,jj,1) * tmask(ji+1,jj,1) * tmask(ji,jj+1,1) * tmask(ji+1,jj+1,1)
  208. END DO
  209. END DO
  210. CALL lbc_lnk( zfmask, 'F', 1._wp )
  211. ! Lateral boundary conditions on velocity (modify zfmask)
  212. zwf(:,:) = zfmask(:,:)
  213. DO jj = 2, jpjm1
  214. DO ji = fs_2, fs_jpim1 ! vector opt.
  215. IF( zfmask(ji,jj) == 0._wp ) THEN
  216. zfmask(ji,jj) = zshlat * MIN( 1._wp , MAX( zwf(ji+1,jj), zwf(ji,jj+1), zwf(ji-1,jj), zwf(ji,jj-1) ) )
  217. ENDIF
  218. END DO
  219. END DO
  220. DO jj = 2, jpjm1
  221. IF( zfmask(1,jj) == 0._wp ) THEN
  222. zfmask(1 ,jj) = zshlat * MIN( 1._wp , MAX( zwf(2,jj), zwf(1,jj+1), zwf(1,jj-1) ) )
  223. ENDIF
  224. IF( zfmask(jpi,jj) == 0._wp ) THEN
  225. zfmask(jpi,jj) = zshlat * MIN( 1._wp , MAX( zwf(jpi,jj+1), zwf(jpim1,jj), zwf(jpi,jj-1) ) )
  226. ENDIF
  227. END DO
  228. DO ji = 2, jpim1
  229. IF( zfmask(ji,1) == 0._wp ) THEN
  230. zfmask(ji,1 ) = zshlat * MIN( 1._wp , MAX( zwf(ji+1,1), zwf(ji,2), zwf(ji-1,1) ) )
  231. ENDIF
  232. IF( zfmask(ji,jpj) == 0._wp ) THEN
  233. zfmask(ji,jpj) = zshlat * MIN( 1._wp , MAX( zwf(ji+1,jpj), zwf(ji-1,jpj), zwf(ji,jpjm1) ) )
  234. ENDIF
  235. END DO
  236. CALL lbc_lnk( zfmask, 'F', 1._wp )
  237. !------------------------------------------------------------------------------!
  238. ! 1) define some variables and initialize arrays
  239. !------------------------------------------------------------------------------!
  240. ! ecc2: square of yield ellipse eccenticrity
  241. ecc2 = rn_ecc * rn_ecc
  242. z1_ecc2 = 1._wp / ecc2
  243. ! Time step for subcycling
  244. zdtevp = rdt_ice / REAL( nn_nevp )
  245. z1_dtevp = 1._wp / zdtevp
  246. ! alpha parameters (Bouillon 2009)
  247. #if defined key_lim3
  248. zalph1 = ( 2._wp * rn_relast * rdt_ice ) * z1_dtevp
  249. #else
  250. zalph1 = ( 2._wp * telast ) * z1_dtevp
  251. #endif
  252. zalph2 = zalph1 * z1_ecc2
  253. z1_alph1 = 1._wp / ( zalph1 + 1._wp )
  254. z1_alph2 = 1._wp / ( zalph2 + 1._wp )
  255. ! Initialise stress tensor
  256. zs1 (:,:) = stress1_i (:,:)
  257. zs2 (:,:) = stress2_i (:,:)
  258. zs12(:,:) = stress12_i(:,:)
  259. ! Ice strength
  260. #if defined key_lim3
  261. CALL lim_itd_me_icestrength( nn_icestr )
  262. zpresh(:,:) = tmask(:,:,1) * strength(:,:)
  263. #else
  264. zpresh(:,:) = tmask(:,:,1) * pstar * vt_i(:,:) * EXP( -c_rhg * (1. - at_i(:,:) ) )
  265. #endif
  266. ! scale factors
  267. DO jj = k_j1+1, k_jpj-1
  268. DO ji = fs_2, fs_jpim1
  269. z1_e1t0(ji,jj) = 1._wp / ( e1t(ji+1,jj ) + e1t(ji,jj ) )
  270. z1_e2t0(ji,jj) = 1._wp / ( e2t(ji ,jj+1) + e2t(ji,jj ) )
  271. END DO
  272. END DO
  273. !
  274. !------------------------------------------------------------------------------!
  275. ! 2) Wind / ocean stress, mass terms, coriolis terms
  276. !------------------------------------------------------------------------------!
  277. IF( nn_ice_embd == 2 ) THEN !== embedded sea ice: compute representative ice top surface ==!
  278. !
  279. ! average interpolation coeff as used in dynspg = (1/nn_fsbc) * {SUM[n/nn_fsbc], n=0,nn_fsbc-1}
  280. ! = (1/nn_fsbc)^2 * {SUM[n], n=0,nn_fsbc-1}
  281. zintn = REAL( nn_fsbc - 1 ) / REAL( nn_fsbc ) * 0.5_wp
  282. !
  283. ! average interpolation coeff as used in dynspg = (1/nn_fsbc) * {SUM[1-n/nn_fsbc], n=0,nn_fsbc-1}
  284. ! = (1/nn_fsbc)^2 * (nn_fsbc^2 - {SUM[n], n=0,nn_fsbc-1})
  285. zintb = REAL( nn_fsbc + 1 ) / REAL( nn_fsbc ) * 0.5_wp
  286. !
  287. zpice(:,:) = ssh_m(:,:) + ( zintn * snwice_mass(:,:) + zintb * snwice_mass_b(:,:) ) * r1_rau0
  288. !
  289. ELSE !== non-embedded sea ice: use ocean surface for slope calculation ==!
  290. zpice(:,:) = ssh_m(:,:)
  291. ENDIF
  292. DO jj = k_j1+1, k_jpj-1
  293. DO ji = fs_2, fs_jpim1
  294. ! ice fraction at U-V points
  295. zaU(ji,jj) = 0.5_wp * ( at_i(ji,jj) * e12t(ji,jj) + at_i(ji+1,jj) * e12t(ji+1,jj) ) * r1_e12u(ji,jj) * umask(ji,jj,1)
  296. zaV(ji,jj) = 0.5_wp * ( at_i(ji,jj) * e12t(ji,jj) + at_i(ji,jj+1) * e12t(ji,jj+1) ) * r1_e12v(ji,jj) * vmask(ji,jj,1)
  297. ! Ice/snow mass at U-V points
  298. zm1 = ( rhosn * vt_s(ji ,jj ) + rhoic * vt_i(ji ,jj ) )
  299. zm2 = ( rhosn * vt_s(ji+1,jj ) + rhoic * vt_i(ji+1,jj ) )
  300. zm3 = ( rhosn * vt_s(ji ,jj+1) + rhoic * vt_i(ji ,jj+1) )
  301. zmassU = 0.5_wp * ( zm1 * e12t(ji,jj) + zm2 * e12t(ji+1,jj) ) * r1_e12u(ji,jj) * umask(ji,jj,1)
  302. zmassV = 0.5_wp * ( zm1 * e12t(ji,jj) + zm3 * e12t(ji,jj+1) ) * r1_e12v(ji,jj) * vmask(ji,jj,1)
  303. ! Ocean currents at U-V points
  304. v_oceU(ji,jj) = 0.5_wp * ( ( v_oce(ji ,jj) + v_oce(ji ,jj-1) ) * e1t(ji+1,jj) &
  305. & + ( v_oce(ji+1,jj) + v_oce(ji+1,jj-1) ) * e1t(ji ,jj) ) * z1_e1t0(ji,jj) * umask(ji,jj,1)
  306. u_oceV(ji,jj) = 0.5_wp * ( ( u_oce(ji,jj ) + u_oce(ji-1,jj ) ) * e2t(ji,jj+1) &
  307. & + ( u_oce(ji,jj+1) + u_oce(ji-1,jj+1) ) * e2t(ji,jj ) ) * z1_e2t0(ji,jj) * vmask(ji,jj,1)
  308. ! Coriolis at T points (m*f)
  309. zmf(ji,jj) = zm1 * fcor(ji,jj)
  310. ! m/dt
  311. zmU_t(ji,jj) = zmassU * z1_dtevp
  312. zmV_t(ji,jj) = zmassV * z1_dtevp
  313. ! Drag ice-atm.
  314. zTauU_ia(ji,jj) = zaU(ji,jj) * utau_ice(ji,jj)
  315. zTauV_ia(ji,jj) = zaV(ji,jj) * vtau_ice(ji,jj)
  316. ! Surface pressure gradient (- m*g*GRAD(ssh)) at U-V points
  317. zspgU(ji,jj) = - zmassU * grav * ( zpice(ji+1,jj) - zpice(ji,jj) ) * r1_e1u(ji,jj)
  318. zspgV(ji,jj) = - zmassV * grav * ( zpice(ji,jj+1) - zpice(ji,jj) ) * r1_e2v(ji,jj)
  319. ! masks
  320. zmaskU(ji,jj) = 1._wp - MAX( 0._wp, SIGN( 1._wp, -zmassU ) ) ! 0 if no ice
  321. zmaskV(ji,jj) = 1._wp - MAX( 0._wp, SIGN( 1._wp, -zmassV ) ) ! 0 if no ice
  322. ! switches
  323. zswitchU(ji,jj) = MAX( 0._wp, SIGN( 1._wp, zmassU - zmmin ) ) ! 0 if ice mass < zmmin
  324. zswitchV(ji,jj) = MAX( 0._wp, SIGN( 1._wp, zmassV - zmmin ) ) ! 0 if ice mass < zmmin
  325. END DO
  326. END DO
  327. CALL lbc_lnk( zmf, 'T', 1. )
  328. !
  329. !------------------------------------------------------------------------------!
  330. ! 3) Solution of the momentum equation, iterative procedure
  331. !------------------------------------------------------------------------------!
  332. !
  333. ! !----------------------!
  334. DO jter = 1 , nn_nevp ! loop over jter !
  335. ! !----------------------!
  336. IF(ln_ctl) THEN ! Convergence test
  337. DO jj = k_j1, k_jpj-1
  338. zu_ice(:,jj) = u_ice(:,jj) ! velocity at previous time step
  339. zv_ice(:,jj) = v_ice(:,jj)
  340. END DO
  341. ENDIF
  342. ! --- divergence, tension & shear (Appendix B of Hunke & Dukowicz, 2002) --- !
  343. DO jj = k_j1, k_jpj-1 ! loops start at 1 since there is no boundary condition (lbc_lnk) at i=1 and j=1 for F points
  344. DO ji = 1, jpim1
  345. ! shear at F points
  346. zds(ji,jj) = ( ( u_ice(ji,jj+1) * r1_e1u(ji,jj+1) - u_ice(ji,jj) * r1_e1u(ji,jj) ) * e1f(ji,jj) * e1f(ji,jj) &
  347. & + ( v_ice(ji+1,jj) * r1_e2v(ji+1,jj) - v_ice(ji,jj) * r1_e2v(ji,jj) ) * e2f(ji,jj) * e2f(ji,jj) &
  348. & ) * r1_e12f(ji,jj) * zfmask(ji,jj)
  349. END DO
  350. END DO
  351. CALL lbc_lnk( zds, 'F', 1. )
  352. DO jj = k_j1+1, k_jpj-1
  353. DO ji = 2, jpim1 ! no vector loop
  354. ! shear**2 at T points (doc eq. A16)
  355. zds2 = ( zds(ji,jj ) * zds(ji,jj ) * e12f(ji,jj ) + zds(ji-1,jj ) * zds(ji-1,jj ) * e12f(ji-1,jj ) &
  356. & + zds(ji,jj-1) * zds(ji,jj-1) * e12f(ji,jj-1) + zds(ji-1,jj-1) * zds(ji-1,jj-1) * e12f(ji-1,jj-1) &
  357. & ) * 0.25_wp * r1_e12t(ji,jj)
  358. ! divergence at T points
  359. zdiv = ( e2u(ji,jj) * u_ice(ji,jj) - e2u(ji-1,jj) * u_ice(ji-1,jj) &
  360. & + e1v(ji,jj) * v_ice(ji,jj) - e1v(ji,jj-1) * v_ice(ji,jj-1) &
  361. & ) * r1_e12t(ji,jj)
  362. zdiv2 = zdiv * zdiv
  363. ! tension at T points
  364. zdt = ( ( u_ice(ji,jj) * r1_e2u(ji,jj) - u_ice(ji-1,jj) * r1_e2u(ji-1,jj) ) * e2t(ji,jj) * e2t(ji,jj) &
  365. & - ( v_ice(ji,jj) * r1_e1v(ji,jj) - v_ice(ji,jj-1) * r1_e1v(ji,jj-1) ) * e1t(ji,jj) * e1t(ji,jj) &
  366. & ) * r1_e12t(ji,jj)
  367. zdt2 = zdt * zdt
  368. ! delta at T points
  369. zdelta = SQRT( zdiv2 + ( zdt2 + zds2 ) * usecc2 )
  370. ! P/delta at T points
  371. zp_delt(ji,jj) = zpresh(ji,jj) / ( zdelta + rn_creepl )
  372. ! stress at T points
  373. zs1(ji,jj) = ( zs1(ji,jj) * zalph1 + zp_delt(ji,jj) * ( zdiv - zdelta ) ) * z1_alph1
  374. zs2(ji,jj) = ( zs2(ji,jj) * zalph2 + zp_delt(ji,jj) * ( zdt * z1_ecc2 ) ) * z1_alph2
  375. END DO
  376. END DO
  377. CALL lbc_lnk( zp_delt, 'T', 1. )
  378. DO jj = k_j1, k_jpj-1
  379. DO ji = 1, jpim1
  380. ! P/delta at F points
  381. zp_delf = 0.25_wp * ( zp_delt(ji,jj) + zp_delt(ji+1,jj) + zp_delt(ji,jj+1) + zp_delt(ji+1,jj+1) )
  382. ! stress at F points
  383. zs12(ji,jj)= ( zs12(ji,jj) * zalph2 + zp_delf * ( zds(ji,jj) * z1_ecc2 ) * 0.5_wp ) * z1_alph2
  384. END DO
  385. END DO
  386. CALL lbc_lnk_multi( zs1, 'T', 1., zs2, 'T', 1., zs12, 'F', 1. )
  387. ! --- Ice internal stresses (Appendix C of Hunke and Dukowicz, 2002) --- !
  388. DO jj = k_j1+1, k_jpj-1
  389. DO ji = fs_2, fs_jpim1
  390. ! U points
  391. zfU(ji,jj) = 0.5_wp * ( ( zs1(ji+1,jj) - zs1(ji,jj) ) * e2u(ji,jj) &
  392. & + ( zs2(ji+1,jj) * e2t(ji+1,jj) * e2t(ji+1,jj) - zs2(ji,jj) * e2t(ji,jj) * e2t(ji,jj) &
  393. & ) * r1_e2u(ji,jj) &
  394. & + ( zs12(ji,jj) * e1f(ji,jj) * e1f(ji,jj) - zs12(ji,jj-1) * e1f(ji,jj-1) * e1f(ji,jj-1) &
  395. & ) * 2._wp * r1_e1u(ji,jj) &
  396. & ) * r1_e12u(ji,jj)
  397. ! V points
  398. zfV(ji,jj) = 0.5_wp * ( ( zs1(ji,jj+1) - zs1(ji,jj) ) * e1v(ji,jj) &
  399. & - ( zs2(ji,jj+1) * e1t(ji,jj+1) * e1t(ji,jj+1) - zs2(ji,jj) * e1t(ji,jj) * e1t(ji,jj) &
  400. & ) * r1_e1v(ji,jj) &
  401. & + ( zs12(ji,jj) * e2f(ji,jj) * e2f(ji,jj) - zs12(ji-1,jj) * e2f(ji-1,jj) * e2f(ji-1,jj) &
  402. & ) * 2._wp * r1_e2v(ji,jj) &
  403. & ) * r1_e12v(ji,jj)
  404. ! u_ice at V point
  405. u_iceV(ji,jj) = 0.5_wp * ( ( u_ice(ji,jj ) + u_ice(ji-1,jj ) ) * e2t(ji,jj+1) &
  406. & + ( u_ice(ji,jj+1) + u_ice(ji-1,jj+1) ) * e2t(ji,jj ) ) * z1_e2t0(ji,jj) * vmask(ji,jj,1)
  407. ! v_ice at U point
  408. v_iceU(ji,jj) = 0.5_wp * ( ( v_ice(ji ,jj) + v_ice(ji ,jj-1) ) * e1t(ji+1,jj) &
  409. & + ( v_ice(ji+1,jj) + v_ice(ji+1,jj-1) ) * e1t(ji ,jj) ) * z1_e1t0(ji,jj) * umask(ji,jj,1)
  410. END DO
  411. END DO
  412. !
  413. ! --- Computation of ice velocity --- !
  414. ! Bouillon et al. 2013 (eq 47-48) => unstable unless alpha, beta are chosen wisely and large nn_nevp
  415. ! Bouillon et al. 2009 (eq 34-35) => stable
  416. IF( MOD(jter,2) .EQ. 0 ) THEN ! even iterations
  417. DO jj = k_j1+1, k_jpj-1
  418. DO ji = fs_2, fs_jpim1
  419. ! tau_io/(v_oce - v_ice)
  420. zTauO = zaV(ji,jj) * rhoco * SQRT( ( v_ice (ji,jj) - v_oce (ji,jj) ) * ( v_ice (ji,jj) - v_oce (ji,jj) ) &
  421. & + ( u_iceV(ji,jj) - u_oceV(ji,jj) ) * ( u_iceV(ji,jj) - u_oceV(ji,jj) ) )
  422. ! Ocean-to-Ice stress
  423. ztauy_oi(ji,jj) = zTauO * ( v_oce(ji,jj) - v_ice(ji,jj) )
  424. ! Coriolis at V-points (energy conserving formulation)
  425. zCory(ji,jj) = - 0.25_wp * r1_e2v(ji,jj) * &
  426. & ( zmf(ji,jj ) * ( e2u(ji,jj ) * u_ice(ji,jj ) + e2u(ji-1,jj ) * u_ice(ji-1,jj ) ) &
  427. & + zmf(ji,jj+1) * ( e2u(ji,jj+1) * u_ice(ji,jj+1) + e2u(ji-1,jj+1) * u_ice(ji-1,jj+1) ) )
  428. ! Sum of external forces (explicit solution) = F + tau_ia + Coriolis + spg + tau_io
  429. zTauE = zfV(ji,jj) + zTauV_ia(ji,jj) + zCory(ji,jj) + zspgV(ji,jj) + ztauy_oi(ji,jj)
  430. ! ice velocity using implicit formulation (cf Madec doc & Bouillon 2009)
  431. v_ice(ji,jj) = ( ( zmV_t(ji,jj) * v_ice(ji,jj) + zTauE + zTauO * v_ice(ji,jj) & ! F + tau_ia + Coriolis + spg + tau_io(only ocean part)
  432. & ) / MAX( zepsi, zmV_t(ji,jj) + zTauO ) * zswitchV(ji,jj) & ! m/dt + tau_io(only ice part)
  433. & + v_oce(ji,jj) * ( 1._wp - zswitchV(ji,jj) ) & ! v_ice = v_oce if mass < zmmin
  434. & ) * zmaskV(ji,jj)
  435. END DO
  436. END DO
  437. CALL lbc_lnk( v_ice, 'V', -1. )
  438. #if defined key_agrif && defined key_lim2
  439. CALL agrif_rhg_lim2( jter, nn_nevp, 'V' )
  440. #endif
  441. #if defined key_bdy
  442. CALL bdy_ice_lim_dyn( 'V' )
  443. #endif
  444. DO jj = k_j1+1, k_jpj-1
  445. DO ji = fs_2, fs_jpim1
  446. ! tau_io/(u_oce - u_ice)
  447. zTauO = zaU(ji,jj) * rhoco * SQRT( ( u_ice (ji,jj) - u_oce (ji,jj) ) * ( u_ice (ji,jj) - u_oce (ji,jj) ) &
  448. & + ( v_iceU(ji,jj) - v_oceU(ji,jj) ) * ( v_iceU(ji,jj) - v_oceU(ji,jj) ) )
  449. ! Ocean-to-Ice stress
  450. ztaux_oi(ji,jj) = zTauO * ( u_oce(ji,jj) - u_ice(ji,jj) )
  451. ! Coriolis at U-points (energy conserving formulation)
  452. zCorx(ji,jj) = 0.25_wp * r1_e1u(ji,jj) * &
  453. & ( zmf(ji ,jj) * ( e1v(ji ,jj) * v_ice(ji ,jj) + e1v(ji ,jj-1) * v_ice(ji ,jj-1) ) &
  454. & + zmf(ji+1,jj) * ( e1v(ji+1,jj) * v_ice(ji+1,jj) + e1v(ji+1,jj-1) * v_ice(ji+1,jj-1) ) )
  455. ! Sum of external forces (explicit solution) = F + tau_ia + Coriolis + spg + tau_io
  456. zTauE = zfU(ji,jj) + zTauU_ia(ji,jj) + zCorx(ji,jj) + zspgU(ji,jj) + ztaux_oi(ji,jj)
  457. ! ice velocity using implicit formulation (cf Madec doc & Bouillon 2009)
  458. u_ice(ji,jj) = ( ( zmU_t(ji,jj) * u_ice(ji,jj) + zTauE + zTauO * u_ice(ji,jj) & ! F + tau_ia + Coriolis + spg + tau_io(only ocean part)
  459. & ) / MAX( zepsi, zmU_t(ji,jj) + zTauO ) * zswitchU(ji,jj) & ! m/dt + tau_io(only ice part)
  460. & + u_oce(ji,jj) * ( 1._wp - zswitchU(ji,jj) ) & ! v_ice = v_oce if mass < zmmin
  461. & ) * zmaskU(ji,jj)
  462. END DO
  463. END DO
  464. CALL lbc_lnk( u_ice, 'U', -1. )
  465. #if defined key_agrif && defined key_lim2
  466. CALL agrif_rhg_lim2( jter, nn_nevp, 'U' )
  467. #endif
  468. #if defined key_bdy
  469. CALL bdy_ice_lim_dyn( 'U' )
  470. #endif
  471. ELSE ! odd iterations
  472. DO jj = k_j1+1, k_jpj-1
  473. DO ji = fs_2, fs_jpim1
  474. ! tau_io/(u_oce - u_ice)
  475. zTauO = zaU(ji,jj) * rhoco * SQRT( ( u_ice (ji,jj) - u_oce (ji,jj) ) * ( u_ice (ji,jj) - u_oce (ji,jj) ) &
  476. & + ( v_iceU(ji,jj) - v_oceU(ji,jj) ) * ( v_iceU(ji,jj) - v_oceU(ji,jj) ) )
  477. ! Ocean-to-Ice stress
  478. ztaux_oi(ji,jj) = zTauO * ( u_oce(ji,jj) - u_ice(ji,jj) )
  479. ! Coriolis at U-points (energy conserving formulation)
  480. zCorx(ji,jj) = 0.25_wp * r1_e1u(ji,jj) * &
  481. & ( zmf(ji ,jj) * ( e1v(ji ,jj) * v_ice(ji ,jj) + e1v(ji ,jj-1) * v_ice(ji ,jj-1) ) &
  482. & + zmf(ji+1,jj) * ( e1v(ji+1,jj) * v_ice(ji+1,jj) + e1v(ji+1,jj-1) * v_ice(ji+1,jj-1) ) )
  483. ! Sum of external forces (explicit solution) = F + tau_ia + Coriolis + spg + tau_io
  484. zTauE = zfU(ji,jj) + zTauU_ia(ji,jj) + zCorx(ji,jj) + zspgU(ji,jj) + ztaux_oi(ji,jj)
  485. ! ice velocity using implicit formulation (cf Madec doc & Bouillon 2009)
  486. u_ice(ji,jj) = ( ( zmU_t(ji,jj) * u_ice(ji,jj) + zTauE + zTauO * u_ice(ji,jj) & ! F + tau_ia + Coriolis + spg + tau_io(only ocean part)
  487. & ) / MAX( zepsi, zmU_t(ji,jj) + zTauO ) * zswitchU(ji,jj) & ! m/dt + tau_io(only ice part)
  488. & + u_oce(ji,jj) * ( 1._wp - zswitchU(ji,jj) ) & ! v_ice = v_oce if mass < zmmin
  489. & ) * zmaskU(ji,jj)
  490. END DO
  491. END DO
  492. CALL lbc_lnk( u_ice, 'U', -1. )
  493. #if defined key_agrif && defined key_lim2
  494. CALL agrif_rhg_lim2( jter, nn_nevp, 'U' )
  495. #endif
  496. #if defined key_bdy
  497. CALL bdy_ice_lim_dyn( 'U' )
  498. #endif
  499. DO jj = k_j1+1, k_jpj-1
  500. DO ji = fs_2, fs_jpim1
  501. ! tau_io/(v_oce - v_ice)
  502. zTauO = zaV(ji,jj) * rhoco * SQRT( ( v_ice (ji,jj) - v_oce (ji,jj) ) * ( v_ice (ji,jj) - v_oce (ji,jj) ) &
  503. & + ( u_iceV(ji,jj) - u_oceV(ji,jj) ) * ( u_iceV(ji,jj) - u_oceV(ji,jj) ) )
  504. ! Ocean-to-Ice stress
  505. ztauy_oi(ji,jj) = zTauO * ( v_oce(ji,jj) - v_ice(ji,jj) )
  506. ! Coriolis at V-points (energy conserving formulation)
  507. zCory(ji,jj) = - 0.25_wp * r1_e2v(ji,jj) * &
  508. & ( zmf(ji,jj ) * ( e2u(ji,jj ) * u_ice(ji,jj ) + e2u(ji-1,jj ) * u_ice(ji-1,jj ) ) &
  509. & + zmf(ji,jj+1) * ( e2u(ji,jj+1) * u_ice(ji,jj+1) + e2u(ji-1,jj+1) * u_ice(ji-1,jj+1) ) )
  510. ! Sum of external forces (explicit solution) = F + tau_ia + Coriolis + spg + tau_io
  511. zTauE = zfV(ji,jj) + zTauV_ia(ji,jj) + zCory(ji,jj) + zspgV(ji,jj) + ztauy_oi(ji,jj)
  512. ! ice velocity using implicit formulation (cf Madec doc & Bouillon 2009)
  513. v_ice(ji,jj) = ( ( zmV_t(ji,jj) * v_ice(ji,jj) + zTauE + zTauO * v_ice(ji,jj) & ! F + tau_ia + Coriolis + spg + tau_io(only ocean part)
  514. & ) / MAX( zepsi, zmV_t(ji,jj) + zTauO ) * zswitchV(ji,jj) & ! m/dt + tau_io(only ice part)
  515. & + v_oce(ji,jj) * ( 1._wp - zswitchV(ji,jj) ) & ! v_ice = v_oce if mass < zmmin
  516. & ) * zmaskV(ji,jj)
  517. END DO
  518. END DO
  519. CALL lbc_lnk( v_ice, 'V', -1. )
  520. #if defined key_agrif && defined key_lim2
  521. CALL agrif_rhg_lim2( jter, nn_nevp, 'V' )
  522. #endif
  523. #if defined key_bdy
  524. CALL bdy_ice_lim_dyn( 'V' )
  525. #endif
  526. ENDIF
  527. IF(ln_ctl) THEN ! Convergence test
  528. DO jj = k_j1+1, k_jpj-1
  529. zresr(:,jj) = MAX( ABS( u_ice(:,jj) - zu_ice(:,jj) ), ABS( v_ice(:,jj) - zv_ice(:,jj) ) )
  530. END DO
  531. zresm = MAXVAL( zresr( 1:jpi, k_j1+1:k_jpj-1 ) )
  532. IF( lk_mpp ) CALL mpp_max( zresm ) ! max over the global domain
  533. ENDIF
  534. !
  535. ! ! ==================== !
  536. END DO ! end loop over jter !
  537. ! ! ==================== !
  538. !
  539. !------------------------------------------------------------------------------!
  540. ! 4) Recompute delta, shear and div (inputs for mechanical redistribution)
  541. !------------------------------------------------------------------------------!
  542. DO jj = k_j1, k_jpj-1
  543. DO ji = 1, jpim1
  544. ! shear at F points
  545. zds(ji,jj) = ( ( u_ice(ji,jj+1) * r1_e1u(ji,jj+1) - u_ice(ji,jj) * r1_e1u(ji,jj) ) * e1f(ji,jj) * e1f(ji,jj) &
  546. & + ( v_ice(ji+1,jj) * r1_e2v(ji+1,jj) - v_ice(ji,jj) * r1_e2v(ji,jj) ) * e2f(ji,jj) * e2f(ji,jj) &
  547. & ) * r1_e12f(ji,jj) * zfmask(ji,jj)
  548. END DO
  549. END DO
  550. CALL lbc_lnk( zds, 'F', 1. )
  551. DO jj = k_j1+1, k_jpj-1
  552. DO ji = 2, jpim1 ! no vector loop
  553. ! tension**2 at T points
  554. zdt = ( ( u_ice(ji,jj) * r1_e2u(ji,jj) - u_ice(ji-1,jj) * r1_e2u(ji-1,jj) ) * e2t(ji,jj) * e2t(ji,jj) &
  555. & - ( v_ice(ji,jj) * r1_e1v(ji,jj) - v_ice(ji,jj-1) * r1_e1v(ji,jj-1) ) * e1t(ji,jj) * e1t(ji,jj) &
  556. & ) * r1_e12t(ji,jj)
  557. zdt2 = zdt * zdt
  558. ! shear**2 at T points (doc eq. A16)
  559. zds2 = ( zds(ji,jj ) * zds(ji,jj ) * e12f(ji,jj ) + zds(ji-1,jj ) * zds(ji-1,jj ) * e12f(ji-1,jj ) &
  560. & + zds(ji,jj-1) * zds(ji,jj-1) * e12f(ji,jj-1) + zds(ji-1,jj-1) * zds(ji-1,jj-1) * e12f(ji-1,jj-1) &
  561. & ) * 0.25_wp * r1_e12t(ji,jj)
  562. ! shear at T points
  563. shear_i(ji,jj) = SQRT( zdt2 + zds2 )
  564. ! divergence at T points
  565. divu_i(ji,jj) = ( e2u(ji,jj) * u_ice(ji,jj) - e2u(ji-1,jj) * u_ice(ji-1,jj) &
  566. & + e1v(ji,jj) * v_ice(ji,jj) - e1v(ji,jj-1) * v_ice(ji,jj-1) &
  567. & ) * r1_e12t(ji,jj)
  568. ! delta at T points
  569. zdelta = SQRT( divu_i(ji,jj) * divu_i(ji,jj) + ( zdt2 + zds2 ) * usecc2 )
  570. rswitch = 1._wp - MAX( 0._wp, SIGN( 1._wp, -zdelta ) ) ! 0 if delta=0
  571. delta_i(ji,jj) = zdelta + rn_creepl * rswitch
  572. END DO
  573. END DO
  574. CALL lbc_lnk_multi( shear_i, 'T', 1., divu_i, 'T', 1., delta_i, 'T', 1. )
  575. ! --- Store the stress tensor for the next time step --- !
  576. stress1_i (:,:) = zs1 (:,:)
  577. stress2_i (:,:) = zs2 (:,:)
  578. stress12_i(:,:) = zs12(:,:)
  579. !------------------------------------------------------------------------------!
  580. ! 5) SIMIP diagnostics
  581. !------------------------------------------------------------------------------!
  582. DO jj = 1, jpj
  583. DO ji = 1, jpi
  584. zswi(ji,jj) = MAX( 0._wp , SIGN( 1._wp , at_i(ji,jj) - epsi06 ) ) ! 1 if ice, 0 if no ice
  585. END DO
  586. END DO
  587. zmiss(:,:) = zmiss_val * ( 1. - zswi(:,:) )
  588. DO jj = k_j1+1, k_jpj-1
  589. DO ji = 2, jpim1
  590. ! Stress tensor invariants (normal and shear stress N/m)
  591. zdiag_sig1(ji,jj) = ( zs1(ji,jj) + zs2(ji,jj) ) * zswi(ji,jj) ! normal stress
  592. zdiag_sig2(ji,jj) = SQRT( ( zs1(ji,jj) - zs2(ji,jj) )**2 + 4*zs12(ji,jj)**2 ) * zswi(ji,jj) ! shear stress
  593. ! Stress terms of the momentum equation (N/m2)
  594. zdiag_dssh_dx(ji,jj) = zspgU(ji,jj) * zswi(ji,jj) ! sea surface slope stress term
  595. zdiag_dssh_dy(ji,jj) = zspgV(ji,jj) * zswi(ji,jj)
  596. zdiag_corstrx(ji,jj) = zCorx(ji,jj) * zswi(ji,jj) ! Coriolis stress term
  597. zdiag_corstry(ji,jj) = zCory(ji,jj) * zswi(ji,jj)
  598. zdiag_intstrx(ji,jj) = zfU(ji,jj) * zswi(ji,jj) ! internal stress term
  599. zdiag_intstry(ji,jj) = zfV(ji,jj) * zswi(ji,jj)
  600. zdiag_utau_oi(ji,jj) = ztaux_oi(ji,jj) * zswi(ji,jj) ! oceanic stress
  601. zdiag_vtau_oi(ji,jj) = ztauy_oi(ji,jj) * zswi(ji,jj)
  602. ! 2D ice mass, snow mass, area transport arrays (X, Y)
  603. zfac_x = 0.5 * u_ice(ji,jj) * e2u(ji,jj) * zswi(ji,jj)
  604. zfac_y = 0.5 * v_ice(ji,jj) * e1v(ji,jj) * zswi(ji,jj)
  605. zdiag_xmtrp_ice(ji,jj) = rhoic * zfac_x * ( vt_i(ji+1,jj) + vt_i(ji,jj) ) ! ice mass transport, X-component (kg/s)
  606. zdiag_ymtrp_ice(ji,jj) = rhoic * zfac_y * ( vt_i(ji,jj+1) + vt_i(ji,jj) ) ! '' Y- ''
  607. zdiag_xmtrp_snw(ji,jj) = rhosn * zfac_x * ( vt_s(ji+1,jj) + vt_s(ji,jj) ) ! snow mass transport, X-component
  608. zdiag_ymtrp_snw(ji,jj) = rhosn * zfac_y * ( vt_s(ji,jj+1) + vt_s(ji,jj) ) ! '' Y- ''
  609. zdiag_xatrp(ji,jj) = zfac_x * ( at_i(ji+1,jj) + at_i(ji,jj) ) ! area transport, X-component (m2/s)
  610. zdiag_yatrp(ji,jj) = zfac_y * ( at_i(ji,jj+1) + at_i(ji,jj) ) ! '' Y- ''
  611. END DO
  612. END DO
  613. CALL lbc_lnk_multi( zdiag_sig1 , 'T', 1., zdiag_sig2 , 'T', 1., &
  614. & zdiag_dssh_dx, 'U', -1., zdiag_dssh_dy, 'V', -1., &
  615. & zdiag_corstrx, 'U', -1., zdiag_corstry, 'V', -1., &
  616. & zdiag_intstrx, 'U', -1., zdiag_intstry, 'V', -1. )
  617. CALL lbc_lnk_multi( zdiag_utau_oi, 'U', -1., zdiag_vtau_oi, 'V', -1. )
  618. CALL lbc_lnk_multi( zdiag_xmtrp_ice, 'U', -1., zdiag_xmtrp_snw, 'U', -1., &
  619. & zdiag_xatrp , 'U', -1., zdiag_ymtrp_ice, 'V', -1., &
  620. & zdiag_ymtrp_snw, 'V', -1., zdiag_yatrp , 'V', -1. )
  621. IF ( iom_use( "xmtrpice" ) ) CALL iom_put( "xmtrpice" , zdiag_xmtrp_ice(:,:) ) ! X-component of sea-ice mass transport (kg/s)
  622. IF ( iom_use( "ymtrpice" ) ) CALL iom_put( "ymtrpice" , zdiag_ymtrp_ice(:,:) ) ! Y-component of sea-ice mass transport
  623. IF ( iom_use( "xmtrpsnw" ) ) CALL iom_put( "xmtrpsnw" , zdiag_xmtrp_snw(:,:) ) ! X-component of snow mass transport (kg/s)
  624. IF ( iom_use( "ymtrpsnw" ) ) CALL iom_put( "ymtrpsnw" , zdiag_ymtrp_snw(:,:) ) ! Y-component of snow mass transport
  625. IF ( iom_use( "xatrp" ) ) CALL iom_put( "xatrp" , zdiag_xatrp(:,:) ) ! X-component of ice area transport
  626. IF ( iom_use( "yatrp" ) ) CALL iom_put( "yatrp" , zdiag_yatrp(:,:) ) ! Y-component of ice area transport
  627. IF ( iom_use( "utau_ice" ) ) CALL iom_put( "utau_ice" , utau_ice(:,:) * zswi(:,:) + zmiss(:,:) ) ! Wind stress term in force balance (x)
  628. IF ( iom_use( "vtau_ice" ) ) CALL iom_put( "vtau_ice" , vtau_ice(:,:) * zswi(:,:) + zmiss(:,:) ) ! Wind stress term in force balance (y)
  629. IF ( iom_use( "utau_oi" ) ) CALL iom_put( "utau_oi" , zdiag_utau_oi(:,:) * zswi(:,:) + zmiss(:,:) ) ! Ocean stress term in force balance (x)
  630. IF ( iom_use( "vtau_oi" ) ) CALL iom_put( "vtau_oi" , zdiag_vtau_oi(:,:) * zswi(:,:) + zmiss(:,:) ) ! Ocean stress term in force balance (y)
  631. IF ( iom_use( "dssh_dx" ) ) CALL iom_put( "dssh_dx" , zdiag_dssh_dx(:,:) * zswi(:,:) + zmiss(:,:) ) ! Sea-surface tilt term in force balance (x)
  632. IF ( iom_use( "dssh_dy" ) ) CALL iom_put( "dssh_dy" , zdiag_dssh_dy(:,:) * zswi(:,:) + zmiss(:,:) ) ! Sea-surface tilt term in force balance (y)
  633. IF ( iom_use( "corstrx" ) ) CALL iom_put( "corstrx" , zdiag_corstrx(:,:) * zswi(:,:) + zmiss(:,:) ) ! Coriolis force term in force balance (x)
  634. IF ( iom_use( "corstry" ) ) CALL iom_put( "corstry" , zdiag_corstry(:,:) * zswi(:,:) + zmiss(:,:) ) ! Coriolis force term in force balance (y)
  635. IF ( iom_use( "intstrx" ) ) CALL iom_put( "intstrx" , zdiag_intstrx(:,:) * zswi(:,:) + zmiss(:,:) ) ! Internal force term in force balance (x)
  636. IF ( iom_use( "intstry" ) ) CALL iom_put( "intstry" , zdiag_intstry(:,:) * zswi(:,:) + zmiss(:,:) ) ! Internal force term in force balance (y)
  637. IF ( iom_use( "normstr" ) ) CALL iom_put( "normstr" , zdiag_sig1(:,:) * zswi(:,:) + zmiss(:,:) ) ! Normal stress
  638. IF ( iom_use( "sheastr" ) ) CALL iom_put( "sheastr" , zdiag_sig2(:,:) * zswi(:,:) + zmiss(:,:) ) ! Shear stress
  639. !
  640. !------------------------------------------------------------------------------!
  641. ! 6) Control prints of residual and charge ellipse
  642. !------------------------------------------------------------------------------!
  643. !
  644. ! print the residual for convergence
  645. IF(ln_ctl) THEN
  646. WRITE(charout,FMT="('lim_rhg : res =',D23.16, ' iter =',I4)") zresm, jter
  647. CALL prt_ctl_info(charout)
  648. CALL prt_ctl(tab2d_1=u_ice, clinfo1=' lim_rhg : u_ice :', tab2d_2=v_ice, clinfo2=' v_ice :')
  649. ENDIF
  650. ! print charge ellipse
  651. ! This can be desactivated once the user is sure that the stress state
  652. ! lie on the charge ellipse. See Bouillon et al. 08 for more details
  653. IF(ln_ctl) THEN
  654. CALL prt_ctl_info('lim_rhg : numit :',ivar1=numit)
  655. CALL prt_ctl_info('lim_rhg : nwrite :',ivar1=nwrite)
  656. CALL prt_ctl_info('lim_rhg : MOD :',ivar1=MOD(numit,nwrite))
  657. IF( MOD(numit,nwrite) .EQ. 0 ) THEN
  658. WRITE(charout,FMT="('lim_rhg :', I4, I6, I1, I1, A10)") 1000, numit, 0, 0, ' ch. ell. '
  659. CALL prt_ctl_info(charout)
  660. DO jj = k_j1+1, k_jpj-1
  661. DO ji = 2, jpim1
  662. IF (zpresh(ji,jj) > 1.0) THEN
  663. zsig1 = ( zs1(ji,jj) + (zs2(ji,jj)**2 + 4*zs12(ji,jj)**2 )**0.5 ) / ( 2*zpresh(ji,jj) )
  664. zsig2 = ( zs1(ji,jj) - (zs2(ji,jj)**2 + 4*zs12(ji,jj)**2 )**0.5 ) / ( 2*zpresh(ji,jj) )
  665. WRITE(charout,FMT="('lim_rhg :', I4, I4, D23.16, D23.16, D23.16, D23.16, A10)")
  666. CALL prt_ctl_info(charout)
  667. ENDIF
  668. END DO
  669. END DO
  670. WRITE(charout,FMT="('lim_rhg :', I4, I6, I1, I1, A10)") 2000, numit, 0, 0, ' ch. ell. '
  671. CALL prt_ctl_info(charout)
  672. ENDIF
  673. ENDIF
  674. !
  675. CALL wrk_dealloc( jpi,jpj, zpresh, z1_e1t0, z1_e2t0, zp_delt )
  676. CALL wrk_dealloc( jpi,jpj, zaU, zaV, zmU_t, zmV_t, zmf, zTauU_ia, ztauV_ia )
  677. CALL wrk_dealloc( jpi,jpj, zspgU, zspgV, v_oceU, u_oceV, v_iceU, u_iceV, zfU, zfV )
  678. CALL wrk_dealloc( jpi,jpj, zds, zs1, zs2, zs12, zu_ice, zv_ice, zresr, zpice )
  679. CALL wrk_dealloc( jpi,jpj, zswitchU, zswitchV, zmaskU, zmaskV, zfmask, zwf )
  680. CALL wrk_dealloc( jpi,jpj, zCorx, zCory )
  681. CALL wrk_dealloc( jpi,jpj, ztaux_oi, ztauy_oi )
  682. CALL wrk_dealloc( jpi,jpj, zdiag_xmtrp_ice, zdiag_ymtrp_ice )
  683. CALL wrk_dealloc( jpi,jpj, zdiag_xmtrp_snw, zdiag_ymtrp_snw )
  684. CALL wrk_dealloc( jpi,jpj, zdiag_xatrp , zdiag_yatrp )
  685. CALL wrk_dealloc( jpi,jpj, zdiag_utau_oi , zdiag_vtau_oi )
  686. CALL wrk_dealloc( jpi,jpj, zdiag_dssh_dx , zdiag_dssh_dy )
  687. CALL wrk_dealloc( jpi,jpj, zdiag_corstrx , zdiag_corstry )
  688. CALL wrk_dealloc( jpi,jpj, zdiag_intstrx , zdiag_intstry )
  689. CALL wrk_dealloc( jpi,jpj, zdiag_sig1 , zdiag_sig2 )
  690. CALL wrk_dealloc( jpi,jpj, zswi , zmiss )
  691. END SUBROUTINE lim_rhg
  692. #else
  693. !!----------------------------------------------------------------------
  694. !! Default option Dummy module NO LIM sea-ice model
  695. !!----------------------------------------------------------------------
  696. CONTAINS
  697. SUBROUTINE lim_rhg( k1 , k2 ) ! Dummy routine
  698. WRITE(*,*) 'lim_rhg: You should not have seen this print! error?', k1, k2
  699. END SUBROUTINE lim_rhg
  700. #endif
  701. !!==============================================================================
  702. END MODULE limrhg