New URL for NEMO forge!   http://forge.nemo-ocean.eu

Since March 2022 along with NEMO 4.2 release, the code development moved to a self-hosted GitLab.
This present forge is now archived and remained online for history.
icedyn_rhg_evp.F90 in NEMO/branches/2020/dev_r13296_HPC-07_mocavero_mpi3/src/ICE – NEMO

source: NEMO/branches/2020/dev_r13296_HPC-07_mocavero_mpi3/src/ICE/icedyn_rhg_evp.F90 @ 14288

Last change on this file since 14288 was 13877, checked in by mocavero, 4 years ago

Align branch with the trunk@13747

  • Property svn:keywords set to Id
File size: 63.9 KB
Line 
1MODULE icedyn_rhg_evp
2   !!======================================================================
3   !!                     ***  MODULE  icedyn_rhg_evp  ***
4   !!   Sea-Ice dynamics : rheology Elasto-Viscous-Plastic
5   !!======================================================================
6   !! History :   -   !  2007-03  (M.A. Morales Maqueda, S. Bouillon) Original code
7   !!            3.0  !  2008-03  (M. Vancoppenolle) adaptation to new model
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 evp case
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 + landfast ice + mEVP (Bouillon 2013)
13   !!            3.7  !  2017     (C. Rousset)  add aEVP (Kimmritz 2016-2017)
14   !!            4.0  !  2018     (many people) SI3 [aka Sea Ice cube]
15   !!----------------------------------------------------------------------
16#if defined key_si3
17   !!----------------------------------------------------------------------
18   !!   'key_si3'                                       SI3 sea-ice model
19   !!----------------------------------------------------------------------
20   !!   ice_dyn_rhg_evp : computes ice velocities from EVP rheology
21   !!   rhg_evp_rst     : read/write EVP fields in ice restart
22   !!----------------------------------------------------------------------
23   USE phycst         ! Physical constant
24   USE dom_oce        ! Ocean domain
25   USE sbc_oce , ONLY : ln_ice_embd, nn_fsbc, ssh_m
26   USE sbc_ice , ONLY : utau_ice, vtau_ice, snwice_mass, snwice_mass_b
27   USE ice            ! sea-ice: ice variables
28   USE icevar         ! ice_var_sshdyn
29   USE icedyn_rdgrft  ! sea-ice: ice strength
30   USE bdy_oce , ONLY : ln_bdy 
31   USE bdyice 
32#if defined key_agrif
33   USE agrif_ice_interp
34#endif
35   !
36   USE in_out_manager ! I/O manager
37   USE iom            ! I/O manager library
38   USE lib_mpp        ! MPP library
39   USE lib_fortran    ! fortran utilities (glob_sum + no signed zero)
40   USE lbclnk         ! lateral boundary conditions (or mpp links)
41   USE prtctl         ! Print control
42
43   USE netcdf         ! NetCDF library for convergence test
44   IMPLICIT NONE
45   PRIVATE
46
47   PUBLIC   ice_dyn_rhg_evp   ! called by icedyn_rhg.F90
48   PUBLIC   rhg_evp_rst       ! called by icedyn_rhg.F90
49
50   !! * Substitutions
51#  include "do_loop_substitute.h90"
52#  include "domzgr_substitute.h90"
53
54   !! for convergence tests
55   INTEGER ::   ncvgid   ! netcdf file id
56   INTEGER ::   nvarid   ! netcdf variable id
57   REAL(wp), ALLOCATABLE, DIMENSION(:,:) ::   zmsk00, zmsk15
58   !!----------------------------------------------------------------------
59   !! NEMO/ICE 4.0 , NEMO Consortium (2018)
60   !! $Id$
61   !! Software governed by the CeCILL license (see ./LICENSE)
62   !!----------------------------------------------------------------------
63CONTAINS
64
65   SUBROUTINE ice_dyn_rhg_evp( kt, Kmm, pstress1_i, pstress2_i, pstress12_i, pshear_i, pdivu_i, pdelta_i )
66      !!-------------------------------------------------------------------
67      !!                 ***  SUBROUTINE ice_dyn_rhg_evp  ***
68      !!                             EVP-C-grid
69      !!
70      !! ** purpose : determines sea ice drift from wind stress, ice-ocean
71      !!  stress and sea-surface slope. Ice-ice interaction is described by
72      !!  a non-linear elasto-viscous-plastic (EVP) law including shear
73      !!  strength and a bulk rheology (Hunke and Dukowicz, 2002).   
74      !!
75      !!  The points in the C-grid look like this, dear reader
76      !!
77      !!                              (ji,jj)
78      !!                                 |
79      !!                                 |
80      !!                      (ji-1,jj)  |  (ji,jj)
81      !!                             ---------   
82      !!                            |         |
83      !!                            | (ji,jj) |------(ji,jj)
84      !!                            |         |
85      !!                             ---------   
86      !!                     (ji-1,jj-1)     (ji,jj-1)
87      !!
88      !! ** Inputs  : - wind forcing (stress), oceanic currents
89      !!                ice total volume (vt_i) per unit area
90      !!                snow total volume (vt_s) per unit area
91      !!
92      !! ** Action  : - compute u_ice, v_ice : the components of the
93      !!                sea-ice velocity vector
94      !!              - compute delta_i, shear_i, divu_i, which are inputs
95      !!                of the ice thickness distribution
96      !!
97      !! ** Steps   : 0) compute mask at F point
98      !!              1) Compute ice snow mass, ice strength
99      !!              2) Compute wind, oceanic stresses, mass terms and
100      !!                 coriolis terms of the momentum equation
101      !!              3) Solve the momentum equation (iterative procedure)
102      !!              4) Recompute delta, shear and divergence
103      !!                 (which are inputs of the ITD) & store stress
104      !!                 for the next time step
105      !!              5) Diagnostics including charge ellipse
106      !!
107      !! ** Notes   : There is the possibility to use aEVP from the nice work of Kimmritz et al. (2016 & 2017)
108      !!              by setting up ln_aEVP=T (i.e. changing alpha and beta parameters).
109      !!              This is an upgraded version of mEVP from Bouillon et al. 2013
110      !!              (i.e. more stable and better convergence)
111      !!
112      !! References : Hunke and Dukowicz, JPO97
113      !!              Bouillon et al., Ocean Modelling 2009
114      !!              Bouillon et al., Ocean Modelling 2013
115      !!              Kimmritz et al., Ocean Modelling 2016 & 2017
116      !!-------------------------------------------------------------------
117      INTEGER                 , INTENT(in   ) ::   kt                                    ! time step
118      INTEGER                 , INTENT(in   ) ::   Kmm                                   ! ocean time level index
119      REAL(wp), DIMENSION(:,:), INTENT(inout) ::   pstress1_i, pstress2_i, pstress12_i   !
120      REAL(wp), DIMENSION(:,:), INTENT(  out) ::   pshear_i  , pdivu_i   , pdelta_i      !
121      !!
122      INTEGER ::   ji, jj       ! dummy loop indices
123      INTEGER ::   jter         ! local integers
124      !
125      REAL(wp) ::   zrhoco                                              ! rho0 * rn_cio
126      REAL(wp) ::   zdtevp, z1_dtevp                                    ! time step for subcycling
127      REAL(wp) ::   ecc2, z1_ecc2                                       ! square of yield ellipse eccenticity
128      REAL(wp) ::   zalph1, z1_alph1, zalph2, z1_alph2                  ! alpha coef from Bouillon 2009 or Kimmritz 2017
129      REAl(wp) ::   zbetau, zbetav
130      REAL(wp) ::   zm1, zm2, zm3, zmassU, zmassV, zvU, zvV             ! ice/snow mass and volume
131      REAL(wp) ::   zp_delf, zds2, zdt, zdt2, zdiv, zdiv2               ! temporary scalars
132      REAL(wp) ::   zTauO, zTauB, zRHS, zvel                            ! temporary scalars
133      REAL(wp) ::   zkt                                                 ! isotropic tensile strength for landfast ice
134      REAL(wp) ::   zvCr                                                ! critical ice volume above which ice is landfast
135      !
136      REAL(wp) ::   zintb, zintn                                        ! dummy argument
137      REAL(wp) ::   zfac_x, zfac_y
138      REAL(wp) ::   zshear, zdum1, zdum2
139      !
140      REAL(wp), DIMENSION(jpi,jpj) ::   zdelta, zp_delt                 ! delta and P/delta at T points
141      REAL(wp), DIMENSION(jpi,jpj) ::   zbeta                           ! beta coef from Kimmritz 2017
142      !
143      REAL(wp), DIMENSION(jpi,jpj) ::   zdt_m                           ! (dt / ice-snow_mass) on T points
144      REAL(wp), DIMENSION(jpi,jpj) ::   zaU  , zaV                      ! ice fraction on U/V points
145      REAL(wp), DIMENSION(jpi,jpj) ::   zmU_t, zmV_t                    ! (ice-snow_mass / dt) on U/V points
146      REAL(wp), DIMENSION(jpi,jpj) ::   zmf                             ! coriolis parameter at T points
147      REAL(wp), DIMENSION(jpi,jpj) ::   v_oceU, u_oceV, v_iceU, u_iceV  ! ocean/ice u/v component on V/U points
148      !
149      REAL(wp), DIMENSION(jpi,jpj) ::   zds                             ! shear
150      REAL(wp), DIMENSION(jpi,jpj) ::   zten_i                          ! tension
151      REAL(wp), DIMENSION(jpi,jpj) ::   zs1, zs2, zs12                  ! stress tensor components
152      REAL(wp), DIMENSION(jpi,jpj) ::   zsshdyn                         ! array used for the calculation of ice surface slope:
153      !                                                                 !    ocean surface (ssh_m) if ice is not embedded
154      !                                                                 !    ice bottom surface if ice is embedded   
155      REAL(wp), DIMENSION(jpi,jpj) ::   zfU  , zfV                      ! internal stresses
156      REAL(wp), DIMENSION(jpi,jpj) ::   zspgU, zspgV                    ! surface pressure gradient at U/V points
157      REAL(wp), DIMENSION(jpi,jpj) ::   zCorU, zCorV                    ! Coriolis stress array
158      REAL(wp), DIMENSION(jpi,jpj) ::   ztaux_ai, ztauy_ai              ! ice-atm. stress at U-V points
159      REAL(wp), DIMENSION(jpi,jpj) ::   ztaux_oi, ztauy_oi              ! ice-ocean stress at U-V points
160      REAL(wp), DIMENSION(jpi,jpj) ::   ztaux_bi, ztauy_bi              ! ice-OceanBottom stress at U-V points (landfast)
161      REAL(wp), DIMENSION(jpi,jpj) ::   ztaux_base, ztauy_base          ! ice-bottom stress at U-V points (landfast)
162      !
163      REAL(wp), DIMENSION(jpi,jpj) ::   zmsk01x, zmsk01y                ! dummy arrays
164      REAL(wp), DIMENSION(jpi,jpj) ::   zmsk00x, zmsk00y                ! mask for ice presence
165      REAL(wp), DIMENSION(jpi,jpj) ::   zfmask                          ! mask at F points for the ice
166
167      REAL(wp), PARAMETER          ::   zepsi  = 1.0e-20_wp             ! tolerance parameter
168      REAL(wp), PARAMETER          ::   zmmin  = 1._wp                  ! ice mass (kg/m2)  below which ice velocity becomes very small
169      REAL(wp), PARAMETER          ::   zamin  = 0.001_wp               ! ice concentration below which ice velocity becomes very small
170      !! --- check convergence
171      REAL(wp), DIMENSION(jpi,jpj) ::   zu_ice, zv_ice
172      !! --- diags
173      REAL(wp) ::   zsig1, zsig2, zsig12, zfac, z1_strength
174      REAL(wp), ALLOCATABLE, DIMENSION(:,:) ::   zsig_I, zsig_II, zsig1_p, zsig2_p         
175      !! --- SIMIP diags
176      REAL(wp), ALLOCATABLE, DIMENSION(:,:) ::   zdiag_xmtrp_ice ! X-component of ice mass transport (kg/s)
177      REAL(wp), ALLOCATABLE, DIMENSION(:,:) ::   zdiag_ymtrp_ice ! Y-component of ice mass transport (kg/s)
178      REAL(wp), ALLOCATABLE, DIMENSION(:,:) ::   zdiag_xmtrp_snw ! X-component of snow mass transport (kg/s)
179      REAL(wp), ALLOCATABLE, DIMENSION(:,:) ::   zdiag_ymtrp_snw ! Y-component of snow mass transport (kg/s)
180      REAL(wp), ALLOCATABLE, DIMENSION(:,:) ::   zdiag_xatrp     ! X-component of area transport (m2/s)
181      REAL(wp), ALLOCATABLE, DIMENSION(:,:) ::   zdiag_yatrp     ! Y-component of area transport (m2/s)     
182      !!-------------------------------------------------------------------
183
184      IF( kt == nit000 .AND. lwp )   WRITE(numout,*) '-- ice_dyn_rhg_evp: EVP sea-ice rheology'
185      !
186      ! for diagnostics and convergence tests
187      ALLOCATE( zmsk00(jpi,jpj), zmsk15(jpi,jpj) )
188      DO_2D( 1, 1, 1, 1 )
189         zmsk00(ji,jj) = MAX( 0._wp , SIGN( 1._wp , at_i(ji,jj) - epsi06  ) ) ! 1 if ice    , 0 if no ice
190         zmsk15(ji,jj) = MAX( 0._wp , SIGN( 1._wp , at_i(ji,jj) - 0.15_wp ) ) ! 1 if 15% ice, 0 if less
191      END_2D
192      !
193      !!gm for Clem:  OPTIMIZATION:  I think zfmask can be computed one for all at the initialization....
194      !------------------------------------------------------------------------------!
195      ! 0) mask at F points for the ice
196      !------------------------------------------------------------------------------!
197      ! ocean/land mask
198      DO_2D( 1, 0, 1, 0 )
199         zfmask(ji,jj) = tmask(ji,jj,1) * tmask(ji+1,jj,1) * tmask(ji,jj+1,1) * tmask(ji+1,jj+1,1)
200      END_2D
201#if defined key_mpi3
202      CALL lbc_lnk_nc_multi( 'icedyn_rhg_evp', zfmask, 'F', 1._wp)
203#else
204      CALL lbc_lnk( 'icedyn_rhg_evp', zfmask, 'F', 1._wp)
205#endif
206
207      ! Lateral boundary conditions on velocity (modify zfmask)
208      DO_2D( 0, 0, 0, 0 )
209         IF( zfmask(ji,jj) == 0._wp ) THEN
210            zfmask(ji,jj) = rn_ishlat * MIN( 1._wp , MAX( umask(ji,jj,1), umask(ji,jj+1,1), &
211               &                                          vmask(ji,jj,1), vmask(ji+1,jj,1) ) )
212         ENDIF
213      END_2D
214      DO jj = 2, jpjm1
215         IF( zfmask(1,jj) == 0._wp ) THEN
216            zfmask(1  ,jj) = rn_ishlat * MIN( 1._wp , MAX( vmask(2,jj,1), umask(1,jj+1,1), umask(1,jj,1) ) )
217         ENDIF
218         IF( zfmask(jpi,jj) == 0._wp ) THEN
219            zfmask(jpi,jj) = rn_ishlat * MIN( 1._wp , MAX( umask(jpi,jj+1,1), vmask(jpim1,jj,1), umask(jpi,jj-1,1) ) )
220        ENDIF
221      END DO
222      DO ji = 2, jpim1
223         IF( zfmask(ji,1) == 0._wp ) THEN
224            zfmask(ji, 1 ) = rn_ishlat * MIN( 1._wp , MAX( vmask(ji+1,1,1), umask(ji,2,1), vmask(ji,1,1) ) )
225         ENDIF
226         IF( zfmask(ji,jpj) == 0._wp ) THEN
227            zfmask(ji,jpj) = rn_ishlat * MIN( 1._wp , MAX( vmask(ji+1,jpj,1), vmask(ji-1,jpj,1), umask(ji,jpjm1,1) ) )
228         ENDIF
229      END DO
230#if defined key_mpi3
231      CALL lbc_lnk_nc_multi( 'icedyn_rhg_evp', zfmask, 'F', 1._wp )
232#else
233      CALL lbc_lnk( 'icedyn_rhg_evp', zfmask, 'F', 1._wp )
234#endif
235
236      !------------------------------------------------------------------------------!
237      ! 1) define some variables and initialize arrays
238      !------------------------------------------------------------------------------!
239      zrhoco = rho0 * rn_cio 
240
241      ! ecc2: square of yield ellipse eccenticrity
242      ecc2    = rn_ecc * rn_ecc
243      z1_ecc2 = 1._wp / ecc2
244
245      ! alpha parameters (Bouillon 2009)
246      IF( .NOT. ln_aEVP ) THEN
247         zdtevp   = rDt_ice / REAL( nn_nevp )
248         zalph1 =   2._wp * rn_relast * REAL( nn_nevp )
249         zalph2 = zalph1 * z1_ecc2
250
251         z1_alph1 = 1._wp / ( zalph1 + 1._wp )
252         z1_alph2 = 1._wp / ( zalph2 + 1._wp )
253      ELSE
254         zdtevp   = rdt_ice
255         ! zalpha parameters set later on adaptatively
256      ENDIF
257      z1_dtevp = 1._wp / zdtevp
258         
259      ! Initialise stress tensor
260      zs1 (:,:) = pstress1_i (:,:) 
261      zs2 (:,:) = pstress2_i (:,:)
262      zs12(:,:) = pstress12_i(:,:)
263
264      ! Ice strength
265      CALL ice_strength
266
267      ! landfast param from Lemieux(2016): add isotropic tensile strength (following Konig Beatty and Holland, 2010)
268      IF( ln_landfast_L16 ) THEN   ;   zkt = rn_lf_tensile
269      ELSE                         ;   zkt = 0._wp
270      ENDIF
271      !
272      !------------------------------------------------------------------------------!
273      ! 2) Wind / ocean stress, mass terms, coriolis terms
274      !------------------------------------------------------------------------------!
275      ! sea surface height
276      !    embedded sea ice: compute representative ice top surface
277      !    non-embedded sea ice: use ocean surface for slope calculation
278      zsshdyn(:,:) = ice_var_sshdyn( ssh_m, snwice_mass, snwice_mass_b)
279
280      DO_2D( 0, 0, 0, 0 )
281
282         ! ice fraction at U-V points
283         zaU(ji,jj) = 0.5_wp * ( at_i(ji,jj) * e1e2t(ji,jj) + at_i(ji+1,jj) * e1e2t(ji+1,jj) ) * r1_e1e2u(ji,jj) * umask(ji,jj,1)
284         zaV(ji,jj) = 0.5_wp * ( at_i(ji,jj) * e1e2t(ji,jj) + at_i(ji,jj+1) * e1e2t(ji,jj+1) ) * r1_e1e2v(ji,jj) * vmask(ji,jj,1)
285
286         ! Ice/snow mass at U-V points
287         zm1 = ( rhos * vt_s(ji  ,jj  ) + rhoi * vt_i(ji  ,jj  ) )
288         zm2 = ( rhos * vt_s(ji+1,jj  ) + rhoi * vt_i(ji+1,jj  ) )
289         zm3 = ( rhos * vt_s(ji  ,jj+1) + rhoi * vt_i(ji  ,jj+1) )
290         zmassU = 0.5_wp * ( zm1 * e1e2t(ji,jj) + zm2 * e1e2t(ji+1,jj) ) * r1_e1e2u(ji,jj) * umask(ji,jj,1)
291         zmassV = 0.5_wp * ( zm1 * e1e2t(ji,jj) + zm3 * e1e2t(ji,jj+1) ) * r1_e1e2v(ji,jj) * vmask(ji,jj,1)
292
293         ! Ocean currents at U-V points
294         v_oceU(ji,jj)   = 0.25_wp * ( v_oce(ji,jj) + v_oce(ji,jj-1) + v_oce(ji+1,jj) + v_oce(ji+1,jj-1) ) * umask(ji,jj,1)
295         u_oceV(ji,jj)   = 0.25_wp * ( u_oce(ji,jj) + u_oce(ji-1,jj) + u_oce(ji,jj+1) + u_oce(ji-1,jj+1) ) * vmask(ji,jj,1)
296
297         ! Coriolis at T points (m*f)
298         zmf(ji,jj)      = zm1 * ff_t(ji,jj)
299
300         ! dt/m at T points (for alpha and beta coefficients)
301         zdt_m(ji,jj)    = zdtevp / MAX( zm1, zmmin )
302         
303         ! m/dt
304         zmU_t(ji,jj)    = zmassU * z1_dtevp
305         zmV_t(ji,jj)    = zmassV * z1_dtevp
306         
307         ! Drag ice-atm.
308         ztaux_ai(ji,jj) = zaU(ji,jj) * utau_ice(ji,jj)
309         ztauy_ai(ji,jj) = zaV(ji,jj) * vtau_ice(ji,jj)
310
311         ! Surface pressure gradient (- m*g*GRAD(ssh)) at U-V points
312         zspgU(ji,jj)    = - zmassU * grav * ( zsshdyn(ji+1,jj) - zsshdyn(ji,jj) ) * r1_e1u(ji,jj)
313         zspgV(ji,jj)    = - zmassV * grav * ( zsshdyn(ji,jj+1) - zsshdyn(ji,jj) ) * r1_e2v(ji,jj)
314
315         ! masks
316         zmsk00x(ji,jj) = 1._wp - MAX( 0._wp, SIGN( 1._wp, -zmassU ) )  ! 0 if no ice
317         zmsk00y(ji,jj) = 1._wp - MAX( 0._wp, SIGN( 1._wp, -zmassV ) )  ! 0 if no ice
318
319         ! switches
320         IF( zmassU <= zmmin .AND. zaU(ji,jj) <= zamin ) THEN   ;   zmsk01x(ji,jj) = 0._wp
321         ELSE                                                   ;   zmsk01x(ji,jj) = 1._wp   ;   ENDIF
322         IF( zmassV <= zmmin .AND. zaV(ji,jj) <= zamin ) THEN   ;   zmsk01y(ji,jj) = 0._wp
323         ELSE                                                   ;   zmsk01y(ji,jj) = 1._wp   ;   ENDIF
324
325      END_2D
326#if defined key_mpi3
327      CALL lbc_lnk_nc_multi( 'icedyn_rhg_evp', zmf, 'T', 1.0_wp, zdt_m, 'T', 1.0_wp )
328#else
329      CALL lbc_lnk_multi( 'icedyn_rhg_evp', zmf, 'T', 1.0_wp, zdt_m, 'T', 1.0_wp )
330#endif
331      !
332      !                                  !== Landfast ice parameterization ==!
333      !
334      IF( ln_landfast_L16 ) THEN         !-- Lemieux 2016
335         DO_2D( 0, 0, 0, 0 )
336            ! ice thickness at U-V points
337            zvU = 0.5_wp * ( vt_i(ji,jj) * e1e2t(ji,jj) + vt_i(ji+1,jj) * e1e2t(ji+1,jj) ) * r1_e1e2u(ji,jj) * umask(ji,jj,1)
338            zvV = 0.5_wp * ( vt_i(ji,jj) * e1e2t(ji,jj) + vt_i(ji,jj+1) * e1e2t(ji,jj+1) ) * r1_e1e2v(ji,jj) * vmask(ji,jj,1)
339            ! ice-bottom stress at U points
340            zvCr = zaU(ji,jj) * rn_lf_depfra * hu(ji,jj,Kmm)
341            ztaux_base(ji,jj) = - rn_lf_bfr * MAX( 0._wp, zvU - zvCr ) * EXP( -rn_crhg * ( 1._wp - zaU(ji,jj) ) )
342            ! ice-bottom stress at V points
343            zvCr = zaV(ji,jj) * rn_lf_depfra * hv(ji,jj,Kmm)
344            ztauy_base(ji,jj) = - rn_lf_bfr * MAX( 0._wp, zvV - zvCr ) * EXP( -rn_crhg * ( 1._wp - zaV(ji,jj) ) )
345            ! ice_bottom stress at T points
346            zvCr = at_i(ji,jj) * rn_lf_depfra * ht(ji,jj)
347            tau_icebfr(ji,jj) = - rn_lf_bfr * MAX( 0._wp, vt_i(ji,jj) - zvCr ) * EXP( -rn_crhg * ( 1._wp - at_i(ji,jj) ) )
348         END_2D
349#if defined key_mpi3
350         CALL lbc_lnk_nc_multi( 'icedyn_rhg_evp', tau_icebfr(:,:), 'T', 1.0_wp )
351#else
352         CALL lbc_lnk( 'icedyn_rhg_evp', tau_icebfr(:,:), 'T', 1.0_wp )
353#endif
354         !
355      ELSE                               !-- no landfast
356         DO_2D( 0, 0, 0, 0 )
357            ztaux_base(ji,jj) = 0._wp
358            ztauy_base(ji,jj) = 0._wp
359         END_2D
360      ENDIF
361
362      !------------------------------------------------------------------------------!
363      ! 3) Solution of the momentum equation, iterative procedure
364      !------------------------------------------------------------------------------!
365      !
366      !                                               ! ==================== !
367      DO jter = 1 , nn_nevp                           !    loop over jter    !
368         !                                            ! ==================== !       
369         l_full_nf_update = jter == nn_nevp   ! false: disable full North fold update (performances) for iter = 1 to nn_nevp-1
370         !
371         ! convergence test
372         IF( nn_rhg_chkcvg == 1 .OR. nn_rhg_chkcvg == 2  ) THEN
373            DO_2D( nn_hls, nn_hls, nn_hls, nn_hls )
374               zu_ice(ji,jj) = u_ice(ji,jj) * umask(ji,jj,1) ! velocity at previous time step
375               zv_ice(ji,jj) = v_ice(ji,jj) * vmask(ji,jj,1)
376            END_2D
377         ENDIF
378
379         ! --- divergence, tension & shear (Appendix B of Hunke & Dukowicz, 2002) --- !
380         DO_2D( 1, 0, 1, 0 )
381
382            ! shear at F points
383            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)   &
384               &         + ( v_ice(ji+1,jj) * r1_e2v(ji+1,jj) - v_ice(ji,jj) * r1_e2v(ji,jj) ) * e2f(ji,jj) * e2f(ji,jj)   &
385               &         ) * r1_e1e2f(ji,jj) * zfmask(ji,jj)
386
387         END_2D
388
389         DO_2D( 0, 0, 0, 0 )
390
391            ! shear**2 at T points (doc eq. A16)
392            zds2 = ( zds(ji,jj  ) * zds(ji,jj  ) * e1e2f(ji,jj  ) + zds(ji-1,jj  ) * zds(ji-1,jj  ) * e1e2f(ji-1,jj  )  &
393               &   + zds(ji,jj-1) * zds(ji,jj-1) * e1e2f(ji,jj-1) + zds(ji-1,jj-1) * zds(ji-1,jj-1) * e1e2f(ji-1,jj-1)  &
394               &   ) * 0.25_wp * r1_e1e2t(ji,jj)
395           
396            ! divergence at T points
397            zdiv  = ( e2u(ji,jj) * u_ice(ji,jj) - e2u(ji-1,jj) * u_ice(ji-1,jj)   &
398               &    + e1v(ji,jj) * v_ice(ji,jj) - e1v(ji,jj-1) * v_ice(ji,jj-1)   &
399               &    ) * r1_e1e2t(ji,jj)
400            zdiv2 = zdiv * zdiv
401           
402            ! tension at T points
403            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)   &
404               &   - ( v_ice(ji,jj) * r1_e1v(ji,jj) - v_ice(ji,jj-1) * r1_e1v(ji,jj-1) ) * e1t(ji,jj) * e1t(ji,jj)   &
405               &   ) * r1_e1e2t(ji,jj)
406            zdt2 = zdt * zdt
407           
408            ! delta at T points
409            zdelta(ji,jj) = SQRT( zdiv2 + ( zdt2 + zds2 ) * z1_ecc2 ) 
410
411         END_2D
412#if defined key_mpi3
413         CALL lbc_lnk_nc_multi( 'icedyn_rhg_evp', zdelta, 'T', 1.0_wp )
414#else
415         CALL lbc_lnk( 'icedyn_rhg_evp', zdelta, 'T', 1.0_wp )
416#endif
417         ! P/delta at T points
418         DO_2D( 1, 1, 1, 1 )
419            zp_delt(ji,jj) = strength(ji,jj) / ( zdelta(ji,jj) + rn_creepl )
420         END_2D
421
422         DO_2D( 0, 1, 0, 1 )   ! loop ends at jpi,jpj so that no lbc_lnk are needed for zs1 and zs2
423
424            ! divergence at T points (duplication to avoid communications)
425            zdiv  = ( e2u(ji,jj) * u_ice(ji,jj) - e2u(ji-1,jj) * u_ice(ji-1,jj)   &
426               &    + e1v(ji,jj) * v_ice(ji,jj) - e1v(ji,jj-1) * v_ice(ji,jj-1)   &
427               &    ) * r1_e1e2t(ji,jj)
428           
429            ! tension at T points (duplication to avoid communications)
430            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)   &
431               &   - ( v_ice(ji,jj) * r1_e1v(ji,jj) - v_ice(ji,jj-1) * r1_e1v(ji,jj-1) ) * e1t(ji,jj) * e1t(ji,jj)   &
432               &   ) * r1_e1e2t(ji,jj)
433           
434            ! alpha for aEVP
435            !   gamma = 0.5*P/(delta+creepl) * (c*pi)**2/Area * dt/m
436            !   alpha = beta = sqrt(4*gamma)
437            IF( ln_aEVP ) THEN
438               zalph1   = MAX( 50._wp, rpi * SQRT( 0.5_wp * zp_delt(ji,jj) * r1_e1e2t(ji,jj) * zdt_m(ji,jj) ) )
439               z1_alph1 = 1._wp / ( zalph1 + 1._wp )
440               zalph2   = zalph1
441               z1_alph2 = z1_alph1
442               ! explicit:
443               ! z1_alph1 = 1._wp / zalph1
444               ! z1_alph2 = 1._wp / zalph1
445               ! zalph1 = zalph1 - 1._wp
446               ! zalph2 = zalph1
447            ENDIF
448           
449            ! stress at T points (zkt/=0 if landfast)
450            zs1(ji,jj) = ( zs1(ji,jj)*zalph1 + zp_delt(ji,jj) * ( zdiv*(1._wp + zkt) - zdelta(ji,jj)*(1._wp - zkt) ) ) * z1_alph1
451            zs2(ji,jj) = ( zs2(ji,jj)*zalph2 + zp_delt(ji,jj) * ( zdt * z1_ecc2 * (1._wp + zkt) ) ) * z1_alph2
452         
453         END_2D
454         ! Save beta at T-points for further computations
455         IF( ln_aEVP ) THEN
456            DO_2D( 1, 1, 1, 1 )
457               zbeta(ji,jj) = MAX( 50._wp, rpi * SQRT( 0.5_wp * zp_delt(ji,jj) * r1_e1e2t(ji,jj) * zdt_m(ji,jj) ) )
458            END_2D
459         ENDIF
460         
461         DO_2D( 1, 0, 1, 0 )
462
463            ! alpha for aEVP
464            IF( ln_aEVP ) THEN
465               zalph2   = MAX( zbeta(ji,jj), zbeta(ji+1,jj), zbeta(ji,jj+1), zbeta(ji+1,jj+1) )
466               z1_alph2 = 1._wp / ( zalph2 + 1._wp )
467               ! explicit:
468               ! z1_alph2 = 1._wp / zalph2
469               ! zalph2 = zalph2 - 1._wp
470            ENDIF
471           
472            ! P/delta at F points
473            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) )
474           
475            ! stress at F points (zkt/=0 if landfast)
476            zs12(ji,jj)= ( zs12(ji,jj) * zalph2 + zp_delf * ( zds(ji,jj) * z1_ecc2 * (1._wp + zkt) ) * 0.5_wp ) * z1_alph2
477
478         END_2D
479
480         ! --- Ice internal stresses (Appendix C of Hunke and Dukowicz, 2002) --- !
481         DO_2D( 0, 0, 0, 0 )
482            !                   !--- U points
483            zfU(ji,jj) = 0.5_wp * ( ( zs1(ji+1,jj) - zs1(ji,jj) ) * e2u(ji,jj)                                             &
484               &                  + ( zs2(ji+1,jj) * e2t(ji+1,jj) * e2t(ji+1,jj) - zs2(ji,jj) * e2t(ji,jj) * e2t(ji,jj)    &
485               &                    ) * r1_e2u(ji,jj)                                                                      &
486               &                  + ( zs12(ji,jj) * e1f(ji,jj) * e1f(ji,jj) - zs12(ji,jj-1) * e1f(ji,jj-1) * e1f(ji,jj-1)  &
487               &                    ) * 2._wp * r1_e1u(ji,jj)                                                              &
488               &                  ) * r1_e1e2u(ji,jj)
489            !
490            !                !--- V points
491            zfV(ji,jj) = 0.5_wp * ( ( zs1(ji,jj+1) - zs1(ji,jj) ) * e1v(ji,jj)                                             &
492               &                  - ( zs2(ji,jj+1) * e1t(ji,jj+1) * e1t(ji,jj+1) - zs2(ji,jj) * e1t(ji,jj) * e1t(ji,jj)    &
493               &                    ) * r1_e1v(ji,jj)                                                                      &
494               &                  + ( zs12(ji,jj) * e2f(ji,jj) * e2f(ji,jj) - zs12(ji-1,jj) * e2f(ji-1,jj) * e2f(ji-1,jj)  &
495               &                    ) * 2._wp * r1_e2v(ji,jj)                                                              &
496               &                  ) * r1_e1e2v(ji,jj)
497            !
498            !                !--- ice currents at U-V point
499            v_iceU(ji,jj) = 0.25_wp * ( v_ice(ji,jj) + v_ice(ji,jj-1) + v_ice(ji+1,jj) + v_ice(ji+1,jj-1) ) * umask(ji,jj,1)
500            u_iceV(ji,jj) = 0.25_wp * ( u_ice(ji,jj) + u_ice(ji-1,jj) + u_ice(ji,jj+1) + u_ice(ji-1,jj+1) ) * vmask(ji,jj,1)
501            !
502         END_2D
503         !
504         ! --- Computation of ice velocity --- !
505         !  Bouillon et al. 2013 (eq 47-48) => unstable unless alpha, beta vary as in Kimmritz 2016 & 2017
506         !  Bouillon et al. 2009 (eq 34-35) => stable
507         IF( MOD(jter,2) == 0 ) THEN ! even iterations
508            !
509            DO_2D( 0, 0, 0, 0 )
510               !                 !--- tau_io/(v_oce - v_ice)
511               zTauO = zaV(ji,jj) * zrhoco * SQRT( ( v_ice (ji,jj) - v_oce (ji,jj) ) * ( v_ice (ji,jj) - v_oce (ji,jj) )  &
512                  &                              + ( u_iceV(ji,jj) - u_oceV(ji,jj) ) * ( u_iceV(ji,jj) - u_oceV(ji,jj) ) )
513               !                 !--- Ocean-to-Ice stress
514               ztauy_oi(ji,jj) = zTauO * ( v_oce(ji,jj) - v_ice(ji,jj) )
515               !
516               !                 !--- tau_bottom/v_ice
517               zvel  = 5.e-05_wp + SQRT( v_ice(ji,jj) * v_ice(ji,jj) + u_iceV(ji,jj) * u_iceV(ji,jj) )
518               zTauB = ztauy_base(ji,jj) / zvel
519               !                 !--- OceanBottom-to-Ice stress
520               ztauy_bi(ji,jj) = zTauB * v_ice(ji,jj)
521               !
522               !                 !--- Coriolis at V-points (energy conserving formulation)
523               zCorV(ji,jj)  = - 0.25_wp * r1_e2v(ji,jj) *  &
524                  &    ( zmf(ji,jj  ) * ( e2u(ji,jj  ) * u_ice(ji,jj  ) + e2u(ji-1,jj  ) * u_ice(ji-1,jj  ) )  &
525                  &    + zmf(ji,jj+1) * ( e2u(ji,jj+1) * u_ice(ji,jj+1) + e2u(ji-1,jj+1) * u_ice(ji-1,jj+1) ) )
526               !
527               !                 !--- Sum of external forces (explicit solution) = F + tau_ia + Coriolis + spg + tau_io
528               zRHS = zfV(ji,jj) + ztauy_ai(ji,jj) + zCorV(ji,jj) + zspgV(ji,jj) + ztauy_oi(ji,jj)
529               !
530               !                 !--- landfast switch => 0 = static  friction : TauB > RHS & sign(TauB) /= sign(RHS)
531               !                                         1 = sliding friction : TauB < RHS
532               rswitch = 1._wp - MIN( 1._wp, ABS( SIGN( 1._wp, zRHS + ztauy_base(ji,jj) ) - SIGN( 1._wp, zRHS ) ) )
533               !
534               IF( ln_aEVP ) THEN !--- ice velocity using aEVP (Kimmritz et al 2016 & 2017)
535                  zbetav = MAX( zbeta(ji,jj), zbeta(ji,jj+1) )
536                  v_ice(ji,jj) = ( (          rswitch   * ( zmV_t(ji,jj) * ( zbetav * v_ice(ji,jj) + v_ice_b(ji,jj) )         & ! previous velocity
537                     &                                    + zRHS + zTauO * v_ice(ji,jj)                                       & ! F + tau_ia + Coriolis + spg + tau_io(only ocean part)
538                     &                                    ) / MAX( zepsi, zmV_t(ji,jj) * ( zbetav + 1._wp ) + zTauO - zTauB ) & ! m/dt + tau_io(only ice part) + landfast
539                     &            + ( 1._wp - rswitch ) * (  v_ice_b(ji,jj)                                                   & 
540                     &                                     + v_ice  (ji,jj) * MAX( 0._wp, zbetav - zdtevp * rn_lf_relax )     & ! static friction => slow decrease to v=0
541                     &                                    ) / ( zbetav + 1._wp )                                              &
542                     &             ) * zmsk01y(ji,jj) + v_oce(ji,jj) * 0.01_wp * ( 1._wp - zmsk01y(ji,jj) )                   & ! v_ice = v_oce/100 if mass < zmmin & conc < zamin
543                     &           )   * zmsk00y(ji,jj)
544               ELSE               !--- ice velocity using EVP implicit formulation (cf Madec doc & Bouillon 2009)
545                  v_ice(ji,jj) = ( (          rswitch   * ( zmV_t(ji,jj) * v_ice(ji,jj)                                       & ! previous velocity
546                     &                                    + zRHS + zTauO * v_ice(ji,jj)                                       & ! F + tau_ia + Coriolis + spg + tau_io(only ocean part)
547                     &                                    ) / MAX( zepsi, zmV_t(ji,jj) + zTauO - zTauB )                      & ! m/dt + tau_io(only ice part) + landfast
548                     &            + ( 1._wp - rswitch ) *   v_ice(ji,jj) * MAX( 0._wp, 1._wp - zdtevp * rn_lf_relax )         & ! static friction => slow decrease to v=0
549                     &             ) * zmsk01y(ji,jj) + v_oce(ji,jj) * 0.01_wp * ( 1._wp - zmsk01y(ji,jj) )                   & ! v_ice = v_oce/100 if mass < zmmin & conc < zamin
550                     &            )  * zmsk00y(ji,jj)
551               ENDIF
552            END_2D
553#if defined key_mpi3
554            CALL lbc_lnk_nc_multi( 'icedyn_rhg_evp', v_ice, 'V', -1.0_wp )
555#else
556            CALL lbc_lnk( 'icedyn_rhg_evp', v_ice, 'V', -1.0_wp )
557#endif
558            !
559#if defined key_agrif
560!!            CALL agrif_interp_ice( 'V', jter, nn_nevp )
561            CALL agrif_interp_ice( 'V' )
562#endif
563            IF( ln_bdy )   CALL bdy_ice_dyn( 'V' )
564            !
565            DO_2D( 0, 0, 0, 0 )
566               !                 !--- tau_io/(u_oce - u_ice)
567               zTauO = zaU(ji,jj) * zrhoco * SQRT( ( u_ice (ji,jj) - u_oce (ji,jj) ) * ( u_ice (ji,jj) - u_oce (ji,jj) )  &
568                  &                              + ( v_iceU(ji,jj) - v_oceU(ji,jj) ) * ( v_iceU(ji,jj) - v_oceU(ji,jj) ) )
569               !                 !--- Ocean-to-Ice stress
570               ztaux_oi(ji,jj) = zTauO * ( u_oce(ji,jj) - u_ice(ji,jj) )
571               !
572               !                 !--- tau_bottom/u_ice
573               zvel  = 5.e-05_wp + SQRT( v_iceU(ji,jj) * v_iceU(ji,jj) + u_ice(ji,jj) * u_ice(ji,jj) )
574               zTauB = ztaux_base(ji,jj) / zvel
575               !                 !--- OceanBottom-to-Ice stress
576               ztaux_bi(ji,jj) = zTauB * u_ice(ji,jj)
577               !
578               !                 !--- Coriolis at U-points (energy conserving formulation)
579               zCorU(ji,jj)  =   0.25_wp * r1_e1u(ji,jj) *  &
580                  &    ( zmf(ji  ,jj) * ( e1v(ji  ,jj) * v_ice(ji  ,jj) + e1v(ji  ,jj-1) * v_ice(ji  ,jj-1) )  &
581                  &    + zmf(ji+1,jj) * ( e1v(ji+1,jj) * v_ice(ji+1,jj) + e1v(ji+1,jj-1) * v_ice(ji+1,jj-1) ) )
582               !
583               !                 !--- Sum of external forces (explicit solution) = F + tau_ia + Coriolis + spg + tau_io
584               zRHS = zfU(ji,jj) + ztaux_ai(ji,jj) + zCorU(ji,jj) + zspgU(ji,jj) + ztaux_oi(ji,jj)
585               !
586               !                 !--- landfast switch => 0 = static  friction : TauB > RHS & sign(TauB) /= sign(RHS)
587               !                                         1 = sliding friction : TauB < RHS
588               rswitch = 1._wp - MIN( 1._wp, ABS( SIGN( 1._wp, zRHS + ztaux_base(ji,jj) ) - SIGN( 1._wp, zRHS ) ) )
589               !
590               IF( ln_aEVP ) THEN !--- ice velocity using aEVP (Kimmritz et al 2016 & 2017)
591                  zbetau = MAX( zbeta(ji,jj), zbeta(ji+1,jj) )
592                  u_ice(ji,jj) = ( (          rswitch   * ( zmU_t(ji,jj) * ( zbetau * u_ice(ji,jj) + u_ice_b(ji,jj) )         & ! previous velocity
593                     &                                    + zRHS + zTauO * u_ice(ji,jj)                                       & ! F + tau_ia + Coriolis + spg + tau_io(only ocean part)
594                     &                                    ) / MAX( zepsi, zmU_t(ji,jj) * ( zbetau + 1._wp ) + zTauO - zTauB ) & ! m/dt + tau_io(only ice part) + landfast
595                     &            + ( 1._wp - rswitch ) * (  u_ice_b(ji,jj)                                                   &
596                     &                                     + u_ice  (ji,jj) * MAX( 0._wp, zbetau - zdtevp * rn_lf_relax )     & ! static friction => slow decrease to v=0
597                     &                                    ) / ( zbetau + 1._wp )                                              &
598                     &             ) * zmsk01x(ji,jj) + u_oce(ji,jj) * 0.01_wp * ( 1._wp - zmsk01x(ji,jj) )                   & ! v_ice = v_oce/100 if mass < zmmin & conc < zamin
599                     &           )   * zmsk00x(ji,jj)
600               ELSE               !--- ice velocity using EVP implicit formulation (cf Madec doc & Bouillon 2009)
601                  u_ice(ji,jj) = ( (          rswitch   * ( zmU_t(ji,jj) * u_ice(ji,jj)                                       & ! previous velocity
602                     &                                    + zRHS + zTauO * u_ice(ji,jj)                                       & ! F + tau_ia + Coriolis + spg + tau_io(only ocean part)
603                     &                                    ) / MAX( zepsi, zmU_t(ji,jj) + zTauO - zTauB )                      & ! m/dt + tau_io(only ice part) + landfast
604                     &            + ( 1._wp - rswitch ) *   u_ice(ji,jj) * MAX( 0._wp, 1._wp - zdtevp * rn_lf_relax )         & ! static friction => slow decrease to v=0
605                     &             ) * zmsk01x(ji,jj) + u_oce(ji,jj) * 0.01_wp * ( 1._wp - zmsk01x(ji,jj) )                   & ! v_ice = v_oce/100 if mass < zmmin & conc < zamin
606                     &           )   * zmsk00x(ji,jj)
607               ENDIF
608            END_2D
609#if defined key_mpi3
610            CALL lbc_lnk_nc_multi( 'icedyn_rhg_evp', u_ice, 'U', -1.0_wp )
611#else
612            CALL lbc_lnk( 'icedyn_rhg_evp', u_ice, 'U', -1.0_wp )
613#endif
614            !
615#if defined key_agrif
616!!            CALL agrif_interp_ice( 'U', jter, nn_nevp )
617            CALL agrif_interp_ice( 'U' )
618#endif
619            IF( ln_bdy )   CALL bdy_ice_dyn( 'U' )
620            !
621         ELSE ! odd iterations
622            !
623            DO_2D( 0, 0, 0, 0 )
624               !                 !--- tau_io/(u_oce - u_ice)
625               zTauO = zaU(ji,jj) * zrhoco * SQRT( ( u_ice (ji,jj) - u_oce (ji,jj) ) * ( u_ice (ji,jj) - u_oce (ji,jj) )  &
626                  &                              + ( v_iceU(ji,jj) - v_oceU(ji,jj) ) * ( v_iceU(ji,jj) - v_oceU(ji,jj) ) )
627               !                 !--- Ocean-to-Ice stress
628               ztaux_oi(ji,jj) = zTauO * ( u_oce(ji,jj) - u_ice(ji,jj) )
629               !
630               !                 !--- tau_bottom/u_ice
631               zvel  = 5.e-05_wp + SQRT( v_iceU(ji,jj) * v_iceU(ji,jj) + u_ice(ji,jj) * u_ice(ji,jj) )
632               zTauB = ztaux_base(ji,jj) / zvel
633               !                 !--- OceanBottom-to-Ice stress
634               ztaux_bi(ji,jj) = zTauB * u_ice(ji,jj)
635               !
636               !                 !--- Coriolis at U-points (energy conserving formulation)
637               zCorU(ji,jj)  =   0.25_wp * r1_e1u(ji,jj) *  &
638                  &    ( zmf(ji  ,jj) * ( e1v(ji  ,jj) * v_ice(ji  ,jj) + e1v(ji  ,jj-1) * v_ice(ji  ,jj-1) )  &
639                  &    + zmf(ji+1,jj) * ( e1v(ji+1,jj) * v_ice(ji+1,jj) + e1v(ji+1,jj-1) * v_ice(ji+1,jj-1) ) )
640               !
641               !                 !--- Sum of external forces (explicit solution) = F + tau_ia + Coriolis + spg + tau_io
642               zRHS = zfU(ji,jj) + ztaux_ai(ji,jj) + zCorU(ji,jj) + zspgU(ji,jj) + ztaux_oi(ji,jj)
643               !
644               !                 !--- landfast switch => 0 = static  friction : TauB > RHS & sign(TauB) /= sign(RHS)
645               !                                         1 = sliding friction : TauB < RHS
646               rswitch = 1._wp - MIN( 1._wp, ABS( SIGN( 1._wp, zRHS + ztaux_base(ji,jj) ) - SIGN( 1._wp, zRHS ) ) )
647               !
648               IF( ln_aEVP ) THEN !--- ice velocity using aEVP (Kimmritz et al 2016 & 2017)
649                  zbetau = MAX( zbeta(ji,jj), zbeta(ji+1,jj) )
650                  u_ice(ji,jj) = ( (          rswitch   * ( zmU_t(ji,jj) * ( zbetau * u_ice(ji,jj) + u_ice_b(ji,jj) )         & ! previous velocity
651                     &                                    + zRHS + zTauO * u_ice(ji,jj)                                       & ! F + tau_ia + Coriolis + spg + tau_io(only ocean part)
652                     &                                    ) / MAX( zepsi, zmU_t(ji,jj) * ( zbetau + 1._wp ) + zTauO - zTauB ) & ! m/dt + tau_io(only ice part) + landfast
653                     &            + ( 1._wp - rswitch ) * (  u_ice_b(ji,jj)                                                   &
654                     &                                     + u_ice  (ji,jj) * MAX( 0._wp, zbetau - zdtevp * rn_lf_relax )     & ! static friction => slow decrease to v=0
655                     &                                    ) / ( zbetau + 1._wp )                                              &
656                     &             ) * zmsk01x(ji,jj) + u_oce(ji,jj) * 0.01_wp * ( 1._wp - zmsk01x(ji,jj) )                   & ! v_ice = v_oce/100 if mass < zmmin & conc < zamin
657                     &           )   * zmsk00x(ji,jj)
658               ELSE               !--- ice velocity using EVP implicit formulation (cf Madec doc & Bouillon 2009)
659                  u_ice(ji,jj) = ( (          rswitch   * ( zmU_t(ji,jj) * u_ice(ji,jj)                                       & ! previous velocity
660                     &                                    + zRHS + zTauO * u_ice(ji,jj)                                       & ! F + tau_ia + Coriolis + spg + tau_io(only ocean part)
661                     &                                    ) / MAX( zepsi, zmU_t(ji,jj) + zTauO - zTauB )                      & ! m/dt + tau_io(only ice part) + landfast
662                     &            + ( 1._wp - rswitch ) *   u_ice(ji,jj) * MAX( 0._wp, 1._wp - zdtevp * rn_lf_relax )         & ! static friction => slow decrease to v=0
663                     &             ) * zmsk01x(ji,jj) + u_oce(ji,jj) * 0.01_wp * ( 1._wp - zmsk01x(ji,jj) )                   & ! v_ice = v_oce/100 if mass < zmmin & conc < zamin
664                     &           )   * zmsk00x(ji,jj)
665               ENDIF
666            END_2D
667#if defined key_mpi3
668            CALL lbc_lnk_nc_multi( 'icedyn_rhg_evp', u_ice, 'U', -1.0_wp )
669#else
670            CALL lbc_lnk( 'icedyn_rhg_evp', u_ice, 'U', -1.0_wp )
671#endif
672            !
673#if defined key_agrif
674!!            CALL agrif_interp_ice( 'U', jter, nn_nevp )
675            CALL agrif_interp_ice( 'U' )
676#endif
677            IF( ln_bdy )   CALL bdy_ice_dyn( 'U' )
678            !
679            DO_2D( 0, 0, 0, 0 )
680               !                 !--- tau_io/(v_oce - v_ice)
681               zTauO = zaV(ji,jj) * zrhoco * SQRT( ( v_ice (ji,jj) - v_oce (ji,jj) ) * ( v_ice (ji,jj) - v_oce (ji,jj) )  &
682                  &                              + ( u_iceV(ji,jj) - u_oceV(ji,jj) ) * ( u_iceV(ji,jj) - u_oceV(ji,jj) ) )
683               !                 !--- Ocean-to-Ice stress
684               ztauy_oi(ji,jj) = zTauO * ( v_oce(ji,jj) - v_ice(ji,jj) )
685               !
686               !                 !--- tau_bottom/v_ice
687               zvel  = 5.e-05_wp + SQRT( v_ice(ji,jj) * v_ice(ji,jj) + u_iceV(ji,jj) * u_iceV(ji,jj) )
688               zTauB = ztauy_base(ji,jj) / zvel
689               !                 !--- OceanBottom-to-Ice stress
690               ztauy_bi(ji,jj) = zTauB * v_ice(ji,jj)
691               !
692               !                 !--- Coriolis at v-points (energy conserving formulation)
693               zCorV(ji,jj)  = - 0.25_wp * r1_e2v(ji,jj) *  &
694                  &    ( zmf(ji,jj  ) * ( e2u(ji,jj  ) * u_ice(ji,jj  ) + e2u(ji-1,jj  ) * u_ice(ji-1,jj  ) )  &
695                  &    + zmf(ji,jj+1) * ( e2u(ji,jj+1) * u_ice(ji,jj+1) + e2u(ji-1,jj+1) * u_ice(ji-1,jj+1) ) )
696               !
697               !                 !--- Sum of external forces (explicit solution) = F + tau_ia + Coriolis + spg + tau_io
698               zRHS = zfV(ji,jj) + ztauy_ai(ji,jj) + zCorV(ji,jj) + zspgV(ji,jj) + ztauy_oi(ji,jj)
699               !
700               !                 !--- landfast switch => 0 = static  friction : TauB > RHS & sign(TauB) /= sign(RHS)
701               !                                         1 = sliding friction : TauB < RHS
702               rswitch = 1._wp - MIN( 1._wp, ABS( SIGN( 1._wp, zRHS + ztauy_base(ji,jj) ) - SIGN( 1._wp, zRHS ) ) )
703               !
704               IF( ln_aEVP ) THEN !--- ice velocity using aEVP (Kimmritz et al 2016 & 2017)
705                  zbetav = MAX( zbeta(ji,jj), zbeta(ji,jj+1) )
706                  v_ice(ji,jj) = ( (          rswitch   * ( zmV_t(ji,jj) * ( zbetav * v_ice(ji,jj) + v_ice_b(ji,jj) )         & ! previous velocity
707                     &                                    + zRHS + zTauO * v_ice(ji,jj)                                       & ! F + tau_ia + Coriolis + spg + tau_io(only ocean part)
708                     &                                    ) / MAX( zepsi, zmV_t(ji,jj) * ( zbetav + 1._wp ) + zTauO - zTauB ) & ! m/dt + tau_io(only ice part) + landfast
709                     &            + ( 1._wp - rswitch ) * (  v_ice_b(ji,jj)                                                   &
710                     &                                     + v_ice  (ji,jj) * MAX( 0._wp, zbetav - zdtevp * rn_lf_relax )     & ! static friction => slow decrease to v=0
711                     &                                    ) / ( zbetav + 1._wp )                                              & 
712                     &             ) * zmsk01y(ji,jj) + v_oce(ji,jj) * 0.01_wp * ( 1._wp - zmsk01y(ji,jj) )                   & ! v_ice = v_oce/100 if mass < zmmin & conc < zamin
713                     &           )   * zmsk00y(ji,jj)
714               ELSE               !--- ice velocity using EVP implicit formulation (cf Madec doc & Bouillon 2009)
715                  v_ice(ji,jj) = ( (          rswitch   * ( zmV_t(ji,jj) * v_ice(ji,jj)                                       & ! previous velocity
716                     &                                    + zRHS + zTauO * v_ice(ji,jj)                                       & ! F + tau_ia + Coriolis + spg + tau_io(only ocean part)
717                     &                                    ) / MAX( zepsi, zmV_t(ji,jj) + zTauO - zTauB )                      & ! m/dt + tau_io(only ice part) + landfast
718                     &            + ( 1._wp - rswitch ) *   v_ice(ji,jj) * MAX( 0._wp, 1._wp - zdtevp * rn_lf_relax )         & ! static friction => slow decrease to v=0
719                     &             ) * zmsk01y(ji,jj) + v_oce(ji,jj) * 0.01_wp * ( 1._wp - zmsk01y(ji,jj) )                   & ! v_ice = v_oce/100 if mass < zmmin & conc < zamin
720                     &           )   * zmsk00y(ji,jj)
721               ENDIF
722            END_2D
723#if defined key_mpi3
724            CALL lbc_lnk_nc_multi( 'icedyn_rhg_evp', v_ice, 'V', -1.0_wp )
725#else
726            CALL lbc_lnk( 'icedyn_rhg_evp', v_ice, 'V', -1.0_wp )
727#endif
728            !
729#if defined key_agrif
730!!            CALL agrif_interp_ice( 'V', jter, nn_nevp )
731            CALL agrif_interp_ice( 'V' )
732#endif
733            IF( ln_bdy )   CALL bdy_ice_dyn( 'V' )
734            !
735         ENDIF
736
737         ! convergence test
738         IF( nn_rhg_chkcvg == 2 )   CALL rhg_cvg( kt, jter, nn_nevp, u_ice, v_ice, zu_ice, zv_ice )
739         !
740         !                                                ! ==================== !
741      END DO                                              !  end loop over jter  !
742      !                                                   ! ==================== !
743      IF( ln_aEVP )   CALL iom_put( 'beta_evp' , zbeta )
744      !
745      !------------------------------------------------------------------------------!
746      ! 4) Recompute delta, shear and div (inputs for mechanical redistribution)
747      !------------------------------------------------------------------------------!
748      DO_2D( 1, 0, 1, 0 )
749
750         ! shear at F points
751         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)   &
752            &         + ( v_ice(ji+1,jj) * r1_e2v(ji+1,jj) - v_ice(ji,jj) * r1_e2v(ji,jj) ) * e2f(ji,jj) * e2f(ji,jj)   &
753            &         ) * r1_e1e2f(ji,jj) * zfmask(ji,jj)
754
755      END_2D
756     
757      DO_2D( 0, 0, 0, 0 )   ! no vector loop
758         
759         ! tension**2 at T points
760         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)   &
761            &   - ( v_ice(ji,jj) * r1_e1v(ji,jj) - v_ice(ji,jj-1) * r1_e1v(ji,jj-1) ) * e1t(ji,jj) * e1t(ji,jj)   &
762            &   ) * r1_e1e2t(ji,jj)
763         zdt2 = zdt * zdt
764
765         zten_i(ji,jj) = zdt
766         
767         ! shear**2 at T points (doc eq. A16)
768         zds2 = ( zds(ji,jj  ) * zds(ji,jj  ) * e1e2f(ji,jj  ) + zds(ji-1,jj  ) * zds(ji-1,jj  ) * e1e2f(ji-1,jj  )  &
769            &   + zds(ji,jj-1) * zds(ji,jj-1) * e1e2f(ji,jj-1) + zds(ji-1,jj-1) * zds(ji-1,jj-1) * e1e2f(ji-1,jj-1)  &
770            &   ) * 0.25_wp * r1_e1e2t(ji,jj)
771         
772         ! shear at T points
773         pshear_i(ji,jj) = SQRT( zdt2 + zds2 )
774
775         ! divergence at T points
776         pdivu_i(ji,jj) = ( e2u(ji,jj) * u_ice(ji,jj) - e2u(ji-1,jj) * u_ice(ji-1,jj)   &
777            &             + e1v(ji,jj) * v_ice(ji,jj) - e1v(ji,jj-1) * v_ice(ji,jj-1)   &
778            &             ) * r1_e1e2t(ji,jj)
779         
780         ! delta at T points
781         zfac            = SQRT( pdivu_i(ji,jj) * pdivu_i(ji,jj) + ( zdt2 + zds2 ) * z1_ecc2 ) ! delta 
782         rswitch         = 1._wp - MAX( 0._wp, SIGN( 1._wp, -zfac ) ) ! 0 if delta=0
783         pdelta_i(ji,jj) = zfac + rn_creepl * rswitch ! delta+creepl
784
785      END_2D
786#if defined key_mpi3
787      CALL lbc_lnk_nc_multi( 'icedyn_rhg_evp', pshear_i, 'T', 1._wp, pdivu_i, 'T', 1._wp, pdelta_i, 'T', 1._wp, zten_i, 'T', 1._wp, &
788         &                                  zs1     , 'T', 1._wp, zs2    , 'T', 1._wp, zs12    , 'F', 1._wp )
789#else
790      CALL lbc_lnk_multi( 'icedyn_rhg_evp', pshear_i, 'T', 1._wp, pdivu_i, 'T', 1._wp, pdelta_i, 'T', 1._wp, zten_i, 'T', 1._wp, &
791         &                                  zs1     , 'T', 1._wp, zs2    , 'T', 1._wp, zs12    , 'F', 1._wp )
792#endif
793     
794      ! --- Store the stress tensor for the next time step --- !
795      pstress1_i (:,:) = zs1 (:,:)
796      pstress2_i (:,:) = zs2 (:,:)
797      pstress12_i(:,:) = zs12(:,:)
798      !
799
800      !------------------------------------------------------------------------------!
801      ! 5) diagnostics
802      !------------------------------------------------------------------------------!
803      ! --- ice-ocean, ice-atm. & ice-oceanbottom(landfast) stresses --- !
804      IF(  iom_use('utau_oi') .OR. iom_use('vtau_oi') .OR. iom_use('utau_ai') .OR. iom_use('vtau_ai') .OR. &
805         & iom_use('utau_bi') .OR. iom_use('vtau_bi') ) THEN
806         !
807#if defined key_mpi3
808         CALL lbc_lnk_nc_multi( 'icedyn_rhg_evp', ztaux_oi, 'U', -1.0_wp, ztauy_oi, 'V', -1.0_wp, ztaux_ai, 'U', -1.0_wp, ztauy_ai, 'V', -1.0_wp, &
809            &                                  ztaux_bi, 'U', -1.0_wp, ztauy_bi, 'V', -1.0_wp )
810#else
811         CALL lbc_lnk_multi( 'icedyn_rhg_evp', ztaux_oi, 'U', -1.0_wp, ztauy_oi, 'V', -1.0_wp, ztaux_ai, 'U', -1.0_wp, ztauy_ai, 'V', -1.0_wp, &
812            &                                  ztaux_bi, 'U', -1.0_wp, ztauy_bi, 'V', -1.0_wp )
813#endif
814         !
815         CALL iom_put( 'utau_oi' , ztaux_oi * zmsk00 )
816         CALL iom_put( 'vtau_oi' , ztauy_oi * zmsk00 )
817         CALL iom_put( 'utau_ai' , ztaux_ai * zmsk00 )
818         CALL iom_put( 'vtau_ai' , ztauy_ai * zmsk00 )
819         CALL iom_put( 'utau_bi' , ztaux_bi * zmsk00 )
820         CALL iom_put( 'vtau_bi' , ztauy_bi * zmsk00 )
821      ENDIF
822       
823      ! --- divergence, shear and strength --- !
824      IF( iom_use('icediv') )   CALL iom_put( 'icediv' , pdivu_i  * zmsk00 )   ! divergence
825      IF( iom_use('iceshe') )   CALL iom_put( 'iceshe' , pshear_i * zmsk00 )   ! shear
826      IF( iom_use('icestr') )   CALL iom_put( 'icestr' , strength * zmsk00 )   ! strength
827
828      ! --- Stress tensor invariants (SIMIP diags) --- !
829      IF( iom_use('normstr') .OR. iom_use('sheastr') ) THEN
830         !
831         ALLOCATE( zsig_I(jpi,jpj) , zsig_II(jpi,jpj) )
832         !         
833         DO_2D( 1, 1, 1, 1 )
834           
835            ! Ice stresses
836            ! sigma1, sigma2, sigma12 are some useful recombination of the stresses (Hunke and Dukowicz MWR 2002, Bouillon et al., OM2013)
837            ! These are NOT stress tensor components, neither stress invariants, neither stress principal components
838            ! I know, this can be confusing...
839            zfac             =   strength(ji,jj) / ( pdelta_i(ji,jj) + rn_creepl ) 
840            zsig1            =   zfac * ( pdivu_i(ji,jj) - pdelta_i(ji,jj) )
841            zsig2            =   zfac * z1_ecc2 * zten_i(ji,jj)
842            zsig12           =   zfac * z1_ecc2 * pshear_i(ji,jj)
843           
844            ! Stress invariants (sigma_I, sigma_II, Coon 1974, Feltham 2008)
845            zsig_I (ji,jj)   =   zsig1 * 0.5_wp                                           ! 1st stress invariant, aka average normal stress, aka negative pressure
846            zsig_II(ji,jj)   =   SQRT ( MAX( 0._wp, zsig2 * zsig2 * 0.25_wp + zsig12 ) )  ! 2nd  ''       '', aka maximum shear stress
847               
848         END_2D         
849         !
850         ! Stress tensor invariants (normal and shear stress N/m) - SIMIP diags - definitions following Coon (1974) and Feltham (2008)
851         IF( iom_use('normstr') )   CALL iom_put( 'normstr', zsig_I (:,:) * zmsk00(:,:) ) ! Normal stress
852         IF( iom_use('sheastr') )   CALL iom_put( 'sheastr', zsig_II(:,:) * zmsk00(:,:) ) ! Maximum shear stress
853         
854         DEALLOCATE ( zsig_I, zsig_II )
855         
856      ENDIF
857
858      ! --- Normalized stress tensor principal components --- !
859      ! This are used to plot the normalized yield curve, see Lemieux & Dupont, 2020
860      ! Recommendation 1 : we use ice strength, not replacement pressure
861      ! Recommendation 2 : need to use deformations at PREVIOUS iterate for viscosities
862      IF( iom_use('sig1_pnorm') .OR. iom_use('sig2_pnorm') ) THEN
863         !
864         ALLOCATE( zsig1_p(jpi,jpj) , zsig2_p(jpi,jpj) , zsig_I(jpi,jpj) , zsig_II(jpi,jpj) )         
865         !         
866         DO_2D( 1, 1, 1, 1 )
867           
868            ! Ice stresses computed with **viscosities** (delta, p/delta) at **previous** iterates
869            !                        and **deformations** at current iterates
870            !                        following Lemieux & Dupont (2020)
871            zfac             =   zp_delt(ji,jj)
872            zsig1            =   zfac * ( pdivu_i(ji,jj) - ( zdelta(ji,jj) + rn_creepl ) )
873            zsig2            =   zfac * z1_ecc2 * zten_i(ji,jj)
874            zsig12           =   zfac * z1_ecc2 * pshear_i(ji,jj)
875           
876            ! Stress invariants (sigma_I, sigma_II, Coon 1974, Feltham 2008), T-point
877            zsig_I(ji,jj)    =   zsig1 * 0.5_wp                                            ! 1st stress invariant, aka average normal stress, aka negative pressure
878            zsig_II(ji,jj)   =   SQRT ( MAX( 0._wp, zsig2 * zsig2 * 0.25_wp + zsig12 ) )   ! 2nd  ''       '', aka maximum shear stress
879           
880            ! Normalized  principal stresses (used to display the ellipse)
881            z1_strength      =   1._wp / MAX( 1._wp, strength(ji,jj) )
882            zsig1_p(ji,jj)   =   ( zsig_I(ji,jj) + zsig_II(ji,jj) ) * z1_strength
883            zsig2_p(ji,jj)   =   ( zsig_I(ji,jj) - zsig_II(ji,jj) ) * z1_strength
884         END_2D             
885         !
886         CALL iom_put( 'sig1_pnorm' , zsig1_p ) 
887         CALL iom_put( 'sig2_pnorm' , zsig2_p ) 
888
889         DEALLOCATE( zsig1_p , zsig2_p , zsig_I, zsig_II )
890         
891      ENDIF
892
893      ! --- SIMIP --- !
894      IF(  iom_use('dssh_dx') .OR. iom_use('dssh_dy') .OR. &
895         & iom_use('corstrx') .OR. iom_use('corstry') .OR. iom_use('intstrx') .OR. iom_use('intstry') ) THEN
896         !
897#if defined key_mpi3
898         CALL lbc_lnk_nc_multi( 'icedyn_rhg_evp', zspgU, 'U', -1.0_wp, zspgV, 'V', -1.0_wp, &
899            &                                  zCorU, 'U', -1.0_wp, zCorV, 'V', -1.0_wp, zfU, 'U', -1.0_wp, zfV, 'V', -1.0_wp )
900#else
901         CALL lbc_lnk_multi( 'icedyn_rhg_evp', zspgU, 'U', -1.0_wp, zspgV, 'V', -1.0_wp, &
902            &                                  zCorU, 'U', -1.0_wp, zCorV, 'V', -1.0_wp, zfU, 'U', -1.0_wp, zfV, 'V', -1.0_wp )
903#endif
904
905         CALL iom_put( 'dssh_dx' , zspgU * zmsk00 )   ! Sea-surface tilt term in force balance (x)
906         CALL iom_put( 'dssh_dy' , zspgV * zmsk00 )   ! Sea-surface tilt term in force balance (y)
907         CALL iom_put( 'corstrx' , zCorU * zmsk00 )   ! Coriolis force term in force balance (x)
908         CALL iom_put( 'corstry' , zCorV * zmsk00 )   ! Coriolis force term in force balance (y)
909         CALL iom_put( 'intstrx' , zfU   * zmsk00 )   ! Internal force term in force balance (x)
910         CALL iom_put( 'intstry' , zfV   * zmsk00 )   ! Internal force term in force balance (y)
911      ENDIF
912
913      IF(  iom_use('xmtrpice') .OR. iom_use('ymtrpice') .OR. &
914         & iom_use('xmtrpsnw') .OR. iom_use('ymtrpsnw') .OR. iom_use('xatrp') .OR. iom_use('yatrp') ) THEN
915         !
916         ALLOCATE( zdiag_xmtrp_ice(jpi,jpj) , zdiag_ymtrp_ice(jpi,jpj) , &
917            &      zdiag_xmtrp_snw(jpi,jpj) , zdiag_ymtrp_snw(jpi,jpj) , zdiag_xatrp(jpi,jpj) , zdiag_yatrp(jpi,jpj) )
918         !
919         DO_2D( 0, 0, 0, 0 )
920            ! 2D ice mass, snow mass, area transport arrays (X, Y)
921            zfac_x = 0.5 * u_ice(ji,jj) * e2u(ji,jj) * zmsk00(ji,jj)
922            zfac_y = 0.5 * v_ice(ji,jj) * e1v(ji,jj) * zmsk00(ji,jj)
923
924            zdiag_xmtrp_ice(ji,jj) = rhoi * zfac_x * ( vt_i(ji+1,jj) + vt_i(ji,jj) ) ! ice mass transport, X-component
925            zdiag_ymtrp_ice(ji,jj) = rhoi * zfac_y * ( vt_i(ji,jj+1) + vt_i(ji,jj) ) !        ''           Y-   ''
926
927            zdiag_xmtrp_snw(ji,jj) = rhos * zfac_x * ( vt_s(ji+1,jj) + vt_s(ji,jj) ) ! snow mass transport, X-component
928            zdiag_ymtrp_snw(ji,jj) = rhos * zfac_y * ( vt_s(ji,jj+1) + vt_s(ji,jj) ) !          ''          Y-   ''
929
930            zdiag_xatrp(ji,jj)     = zfac_x * ( at_i(ji+1,jj) + at_i(ji,jj) )        ! area transport,      X-component
931            zdiag_yatrp(ji,jj)     = zfac_y * ( at_i(ji,jj+1) + at_i(ji,jj) )        !        ''            Y-   ''
932
933         END_2D
934
935#if defined key_mpi3
936         CALL lbc_lnk_nc_multi( 'icedyn_rhg_evp', zdiag_xmtrp_ice, 'U', -1.0_wp, zdiag_ymtrp_ice, 'V', -1.0_wp, &
937            &                                  zdiag_xmtrp_snw, 'U', -1.0_wp, zdiag_ymtrp_snw, 'V', -1.0_wp, &
938            &                                  zdiag_xatrp    , 'U', -1.0_wp, zdiag_yatrp    , 'V', -1.0_wp )
939#else
940         CALL lbc_lnk_multi( 'icedyn_rhg_evp', zdiag_xmtrp_ice, 'U', -1.0_wp, zdiag_ymtrp_ice, 'V', -1.0_wp, &
941            &                                  zdiag_xmtrp_snw, 'U', -1.0_wp, zdiag_ymtrp_snw, 'V', -1.0_wp, &
942            &                                  zdiag_xatrp    , 'U', -1.0_wp, zdiag_yatrp    , 'V', -1.0_wp )
943#endif
944
945         CALL iom_put( 'xmtrpice' , zdiag_xmtrp_ice )   ! X-component of sea-ice mass transport (kg/s)
946         CALL iom_put( 'ymtrpice' , zdiag_ymtrp_ice )   ! Y-component of sea-ice mass transport
947         CALL iom_put( 'xmtrpsnw' , zdiag_xmtrp_snw )   ! X-component of snow mass transport (kg/s)
948         CALL iom_put( 'ymtrpsnw' , zdiag_ymtrp_snw )   ! Y-component of snow mass transport
949         CALL iom_put( 'xatrp'    , zdiag_xatrp     )   ! X-component of ice area transport
950         CALL iom_put( 'yatrp'    , zdiag_yatrp     )   ! Y-component of ice area transport
951
952         DEALLOCATE( zdiag_xmtrp_ice , zdiag_ymtrp_ice , &
953            &        zdiag_xmtrp_snw , zdiag_ymtrp_snw , zdiag_xatrp , zdiag_yatrp )
954
955      ENDIF
956      !
957      ! --- convergence tests --- !
958      IF( nn_rhg_chkcvg == 1 .OR. nn_rhg_chkcvg == 2 ) THEN
959         IF( iom_use('uice_cvg') ) THEN
960            IF( ln_aEVP ) THEN   ! output: beta * ( u(t=nn_nevp) - u(t=nn_nevp-1) )
961               CALL iom_put( 'uice_cvg', MAX( ABS( u_ice(:,:) - zu_ice(:,:) ) * zbeta(:,:) * umask(:,:,1) , &
962                  &                           ABS( v_ice(:,:) - zv_ice(:,:) ) * zbeta(:,:) * vmask(:,:,1) ) * zmsk15(:,:) )
963            ELSE                 ! output: nn_nevp * ( u(t=nn_nevp) - u(t=nn_nevp-1) )
964               CALL iom_put( 'uice_cvg', REAL( nn_nevp ) * MAX( ABS( u_ice(:,:) - zu_ice(:,:) ) * umask(:,:,1) , &
965                  &                                             ABS( v_ice(:,:) - zv_ice(:,:) ) * vmask(:,:,1) ) * zmsk15(:,:) )
966            ENDIF
967         ENDIF
968      ENDIF     
969      !
970      DEALLOCATE( zmsk00, zmsk15 )
971      !
972   END SUBROUTINE ice_dyn_rhg_evp
973
974
975   SUBROUTINE rhg_cvg( kt, kiter, kitermax, pu, pv, pub, pvb )
976      !!----------------------------------------------------------------------
977      !!                    ***  ROUTINE rhg_cvg  ***
978      !!                     
979      !! ** Purpose :   check convergence of oce rheology
980      !!
981      !! ** Method  :   create a file ice_cvg.nc containing the convergence of ice velocity
982      !!                during the sub timestepping of rheology so as:
983      !!                  uice_cvg = MAX( u(t+1) - u(t) , v(t+1) - v(t) )
984      !!                This routine is called every sub-iteration, so it is cpu expensive
985      !!
986      !! ** Note    :   for the first sub-iteration, uice_cvg is set to 0 (too large otherwise)   
987      !!----------------------------------------------------------------------
988      INTEGER ,                 INTENT(in) ::   kt, kiter, kitermax       ! ocean time-step index
989      REAL(wp), DIMENSION(:,:), INTENT(in) ::   pu, pv, pub, pvb          ! now and before velocities
990      !!
991      INTEGER           ::   it, idtime, istatus
992      INTEGER           ::   ji, jj          ! dummy loop indices
993      REAL(wp)          ::   zresm           ! local real
994      CHARACTER(len=20) ::   clname
995      REAL(wp), DIMENSION(jpi,jpj) ::   zres           ! check convergence
996      !!----------------------------------------------------------------------
997
998      ! create file
999      IF( kt == nit000 .AND. kiter == 1 ) THEN
1000         !
1001         IF( lwp ) THEN
1002            WRITE(numout,*)
1003            WRITE(numout,*) 'rhg_cvg : ice rheology convergence control'
1004            WRITE(numout,*) '~~~~~~~'
1005         ENDIF
1006         !
1007         IF( lwm ) THEN
1008            clname = 'ice_cvg.nc'
1009            IF( .NOT. Agrif_Root() )   clname = TRIM(Agrif_CFixed())//"_"//TRIM(clname)
1010            istatus = NF90_CREATE( TRIM(clname), NF90_CLOBBER, ncvgid )
1011            istatus = NF90_DEF_DIM( ncvgid, 'time'  , NF90_UNLIMITED, idtime )
1012            istatus = NF90_DEF_VAR( ncvgid, 'uice_cvg', NF90_DOUBLE   , (/ idtime /), nvarid )
1013            istatus = NF90_ENDDEF(ncvgid)
1014         ENDIF
1015         !
1016      ENDIF
1017
1018      ! time
1019      it = ( kt - 1 ) * kitermax + kiter
1020     
1021      ! convergence
1022      IF( kiter == 1 ) THEN ! remove the first iteration for calculations of convergence (always very large)
1023         zresm = 0._wp
1024      ELSE
1025         DO_2D( 1, 1, 1, 1 )
1026            zres(ji,jj) = MAX( ABS( pu(ji,jj) - pub(ji,jj) ) * umask(ji,jj,1), &
1027               &               ABS( pv(ji,jj) - pvb(ji,jj) ) * vmask(ji,jj,1) ) * zmsk15(ji,jj)
1028         END_2D
1029         zresm = MAXVAL( zres )
1030         CALL mpp_max( 'icedyn_rhg_evp', zresm )   ! max over the global domain
1031      ENDIF
1032
1033      IF( lwm ) THEN
1034         ! write variables
1035         istatus = NF90_PUT_VAR( ncvgid, nvarid, (/zresm/), (/it/), (/1/) )
1036         ! close file
1037         IF( kt == nitend - nn_fsbc + 1 )   istatus = NF90_CLOSE(ncvgid)
1038      ENDIF
1039     
1040   END SUBROUTINE rhg_cvg
1041
1042
1043   SUBROUTINE rhg_evp_rst( cdrw, kt )
1044      !!---------------------------------------------------------------------
1045      !!                   ***  ROUTINE rhg_evp_rst  ***
1046      !!                     
1047      !! ** Purpose :   Read or write RHG file in restart file
1048      !!
1049      !! ** Method  :   use of IOM library
1050      !!----------------------------------------------------------------------
1051      CHARACTER(len=*) , INTENT(in) ::   cdrw   ! "READ"/"WRITE" flag
1052      INTEGER, OPTIONAL, INTENT(in) ::   kt     ! ice time-step
1053      !
1054      INTEGER  ::   iter            ! local integer
1055      INTEGER  ::   id1, id2, id3   ! local integers
1056      !!----------------------------------------------------------------------
1057      !
1058      IF( TRIM(cdrw) == 'READ' ) THEN        ! Read/initialize
1059         !                                   ! ---------------
1060         IF( ln_rstart ) THEN                   !* Read the restart file
1061            !
1062            id1 = iom_varid( numrir, 'stress1_i' , ldstop = .FALSE. )
1063            id2 = iom_varid( numrir, 'stress2_i' , ldstop = .FALSE. )
1064            id3 = iom_varid( numrir, 'stress12_i', ldstop = .FALSE. )
1065            !
1066            IF( MIN( id1, id2, id3 ) > 0 ) THEN      ! fields exist
1067               CALL iom_get( numrir, jpdom_auto, 'stress1_i' , stress1_i , cd_type = 'T' )
1068               CALL iom_get( numrir, jpdom_auto, 'stress2_i' , stress2_i , cd_type = 'T' )
1069               CALL iom_get( numrir, jpdom_auto, 'stress12_i', stress12_i, cd_type = 'F' )
1070            ELSE                                     ! start rheology from rest
1071               IF(lwp) WRITE(numout,*)
1072               IF(lwp) WRITE(numout,*) '   ==>>>   previous run without rheology, set stresses to 0'
1073               stress1_i (:,:) = 0._wp
1074               stress2_i (:,:) = 0._wp
1075               stress12_i(:,:) = 0._wp
1076            ENDIF
1077         ELSE                                   !* Start from rest
1078            IF(lwp) WRITE(numout,*)
1079            IF(lwp) WRITE(numout,*) '   ==>>>   start from rest: set stresses to 0'
1080            stress1_i (:,:) = 0._wp
1081            stress2_i (:,:) = 0._wp
1082            stress12_i(:,:) = 0._wp
1083         ENDIF
1084         !
1085      ELSEIF( TRIM(cdrw) == 'WRITE' ) THEN   ! Create restart file
1086         !                                   ! -------------------
1087         IF(lwp) WRITE(numout,*) '---- rhg-rst ----'
1088         iter = kt + nn_fsbc - 1             ! ice restarts are written at kt == nitrst - nn_fsbc + 1
1089         !
1090         CALL iom_rstput( iter, nitrst, numriw, 'stress1_i' , stress1_i  )
1091         CALL iom_rstput( iter, nitrst, numriw, 'stress2_i' , stress2_i  )
1092         CALL iom_rstput( iter, nitrst, numriw, 'stress12_i', stress12_i )
1093         !
1094      ENDIF
1095      !
1096   END SUBROUTINE rhg_evp_rst
1097
1098   
1099#else
1100   !!----------------------------------------------------------------------
1101   !!   Default option         Empty module           NO SI3 sea-ice model
1102   !!----------------------------------------------------------------------
1103#endif
1104
1105   !!==============================================================================
1106END MODULE icedyn_rhg_evp
Note: See TracBrowser for help on using the repository browser.