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/2019/dev_r11842_SI3-10_EAP/tests/ICE_RHEO/MY_SRC – NEMO

source: NEMO/branches/2019/dev_r11842_SI3-10_EAP/tests/ICE_RHEO/MY_SRC/icedyn_rhg_evp.F90 @ 13746

Last change on this file since 13746 was 13746, checked in by stefryn, 3 years ago

update test case

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