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 branches/2017/dev_merge_2017/NEMOGCM/NEMO/LIM_SRC_3 – NEMO

source: branches/2017/dev_merge_2017/NEMOGCM/NEMO/LIM_SRC_3/icedyn_rhg_evp.F90 @ 9119

Last change on this file since 9119 was 9049, checked in by clem, 6 years ago

group one communcation in diags

File size: 55.5 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) LIM3
8   !!             -   !  2008-11  (M. Vancoppenolle, S. Bouillon, Y. Aksenov) add surface tilt in ice rheolohy
9   !!            3.3  !  2009-05  (G.Garric) addition of the evp cas
10   !!            3.4  !  2011-01  (A. Porter)  dynamical allocation
11   !!            3.5  !  2012-08  (R. Benshila)  AGRIF
12   !!            3.6  !  2016-06  (C. Rousset) Rewriting + landfast ice + possibility to use mEVP (Bouillon 2013)
13   !!----------------------------------------------------------------------
14#if defined key_lim3
15   !!----------------------------------------------------------------------
16   !!   'key_lim3'                                       ESIM sea-ice model
17   !!----------------------------------------------------------------------
18   !!   ice_dyn_rhg_evp : computes ice velocities from EVP rheology
19   !!   rhg_evp_rst     : read/write EVP fields in ice restart
20   !!----------------------------------------------------------------------
21   USE phycst         ! Physical constant
22   USE dom_oce        ! Ocean domain
23   USE sbc_oce , ONLY : ln_ice_embd, nn_fsbc, ssh_m
24   USE sbc_ice , ONLY : utau_ice, vtau_ice, snwice_mass, snwice_mass_b
25   USE ice            ! sea-ice: ice variables
26   USE icedyn_rdgrft  ! sea-ice: ice strength
27   USE bdy_oce , ONLY : ln_bdy 
28   USE bdyice 
29#if defined key_agrif
30   USE agrif_lim3_interp
31#endif
32   !
33   USE in_out_manager ! I/O manager
34   USE iom            ! I/O manager library
35   USE lib_mpp        ! MPP library
36   USE lib_fortran    ! fortran utilities (glob_sum + no signed zero)
37   USE lbclnk         ! lateral boundary conditions (or mpp links)
38   USE prtctl         ! Print control
39
40   IMPLICIT NONE
41   PRIVATE
42
43   PUBLIC   ice_dyn_rhg_evp   ! called by icedyn_rhg.F90
44   PUBLIC   rhg_evp_rst       ! called by icedyn_rhg.F90
45
46   !! * Substitutions
47#  include "vectopt_loop_substitute.h90"
48   !!----------------------------------------------------------------------
49   !! NEMO/ICE 4.0 , NEMO Consortium (2017)
50   !! $Id: icedyn_rhg_evp.F90 8378 2017-07-26 13:55:59Z clem $
51   !! Software governed by the CeCILL licence     (NEMOGCM/NEMO_CeCILL.txt)
52   !!----------------------------------------------------------------------
53CONTAINS
54
55   SUBROUTINE ice_dyn_rhg_evp( kt, pstress1_i, pstress2_i, pstress12_i, pshear_i, pdivu_i, pdelta_i )
56      !!-------------------------------------------------------------------
57      !!                 ***  SUBROUTINE ice_dyn_rhg_evp  ***
58      !!                             EVP-C-grid
59      !!
60      !! ** purpose : determines sea ice drift from wind stress, ice-ocean
61      !!  stress and sea-surface slope. Ice-ice interaction is described by
62      !!  a non-linear elasto-viscous-plastic (EVP) law including shear
63      !!  strength and a bulk rheology (Hunke and Dukowicz, 2002).   
64      !!
65      !!  The points in the C-grid look like this, dear reader
66      !!
67      !!                              (ji,jj)
68      !!                                 |
69      !!                                 |
70      !!                      (ji-1,jj)  |  (ji,jj)
71      !!                             ---------   
72      !!                            |         |
73      !!                            | (ji,jj) |------(ji,jj)
74      !!                            |         |
75      !!                             ---------   
76      !!                     (ji-1,jj-1)     (ji,jj-1)
77      !!
78      !! ** Inputs  : - wind forcing (stress), oceanic currents
79      !!                ice total volume (vt_i) per unit area
80      !!                snow total volume (vt_s) per unit area
81      !!
82      !! ** Action  : - compute u_ice, v_ice : the components of the
83      !!                sea-ice velocity vector
84      !!              - compute delta_i, shear_i, divu_i, which are inputs
85      !!                of the ice thickness distribution
86      !!
87      !! ** Steps   : 0) compute mask at F point
88      !!              1) Compute ice snow mass, ice strength
89      !!              2) Compute wind, oceanic stresses, mass terms and
90      !!                 coriolis terms of the momentum equation
91      !!              3) Solve the momentum equation (iterative procedure)
92      !!              4) Recompute delta, shear and divergence
93      !!                 (which are inputs of the ITD) & store stress
94      !!                 for the next time step
95      !!              5) Diagnostics including charge ellipse
96      !!
97      !! ** Notes   : There is the possibility to use aEVP from the nice work of Kimmritz et al. (2016 & 2017)
98      !!              by setting up ln_aEVP=T (i.e. changing alpha and beta parameters).
99      !!              This is an upgraded version of mEVP from Bouillon et al. 2013
100      !!              (i.e. more stable and better convergence)
101      !!
102      !! References : Hunke and Dukowicz, JPO97
103      !!              Bouillon et al., Ocean Modelling 2009
104      !!              Bouillon et al., Ocean Modelling 2013
105      !!              Kimmritz et al., Ocean Modelling 2016 & 2017
106      !!-------------------------------------------------------------------
107      INTEGER                 , INTENT(in   ) ::   kt                                    ! time step
108      REAL(wp), DIMENSION(:,:), INTENT(inout) ::   pstress1_i, pstress2_i, pstress12_i   !
109      REAL(wp), DIMENSION(:,:), INTENT(  out) ::   pshear_i  , pdivu_i   , pdelta_i      !
110      !!
111      INTEGER ::   ji, jj       ! dummy loop indices
112      INTEGER ::   jter         ! local integers
113      !
114      REAL(wp) ::   zrhoco                                              ! rau0 * rn_cio
115      REAL(wp) ::   zdtevp, z1_dtevp                                    ! time step for subcycling
116      REAL(wp) ::   ecc2, z1_ecc2                                       ! square of yield ellipse eccenticity
117      REAL(wp) ::   zalph1, z1_alph1, zalph2, z1_alph2                  ! alpha coef from Bouillon 2009 or Kimmritz 2017
118      REAL(wp) ::   zm1, zm2, zm3, zmassU, zmassV                       ! ice/snow mass
119      REAL(wp) ::   zdelta, zp_delf, zds2, zdt, zdt2, zdiv, zdiv2       ! temporary scalars
120      REAL(wp) ::   zTauO, zTauB, zTauE, zvel                           ! temporary scalars
121      !
122      REAL(wp) ::   zresm                                               ! Maximal error on ice velocity
123      REAL(wp) ::   zintb, zintn                                        ! dummy argument
124      REAL(wp) ::   zfac_x, zfac_y
125      REAL(wp) ::   zshear, zdum1, zdum2
126      !
127      REAL(wp), DIMENSION(jpi,jpj) ::   z1_e1t0, z1_e2t0                ! scale factors
128      REAL(wp), DIMENSION(jpi,jpj) ::   zp_delt                         ! P/delta at T points
129      REAL(wp), DIMENSION(jpi,jpj) ::   zbeta                           ! beta coef from Kimmritz 2017
130      !
131      REAL(wp), DIMENSION(jpi,jpj) ::   zdt_m                           ! (dt / ice-snow_mass) on T points
132      REAL(wp), DIMENSION(jpi,jpj) ::   zaU   , zaV                     ! ice fraction on U/V points
133      REAL(wp), DIMENSION(jpi,jpj) ::   zmU_t, zmV_t                    ! (ice-snow_mass / dt) on U/V points
134      REAL(wp), DIMENSION(jpi,jpj) ::   zmf                             ! coriolis parameter at T points
135      REAL(wp), DIMENSION(jpi,jpj) ::   zTauU_ia , ztauV_ia             ! ice-atm. stress at U-V points
136      REAL(wp), DIMENSION(jpi,jpj) ::   zspgU , zspgV                   ! surface pressure gradient at U/V points
137      REAL(wp), DIMENSION(jpi,jpj) ::   v_oceU, u_oceV, v_iceU, u_iceV  ! ocean/ice u/v component on V/U points                           
138      REAL(wp), DIMENSION(jpi,jpj) ::   zfU   , zfV                     ! internal stresses
139      !
140      REAL(wp), DIMENSION(jpi,jpj) ::   zds                             ! shear
141      REAL(wp), DIMENSION(jpi,jpj) ::   zs1, zs2, zs12                  ! stress tensor components
142      REAL(wp), DIMENSION(jpi,jpj) ::   zu_ice, zv_ice, zresr           ! check convergence
143      REAL(wp), DIMENSION(jpi,jpj) ::   zpice                           ! array used for the calculation of ice surface slope:
144      !                                                                 !    ocean surface (ssh_m) if ice is not embedded
145      !                                                                 !    ice top surface if ice is embedded   
146      REAL(wp), DIMENSION(jpi,jpj) ::   zCorx, zCory                    ! Coriolis stress array
147      REAL(wp), DIMENSION(jpi,jpj) ::   ztaux_oi, ztauy_oi              ! Ocean-to-ice stress array
148      !
149      REAL(wp), DIMENSION(jpi,jpj) ::   zswitchU, zswitchV              ! dummy arrays
150      REAL(wp), DIMENSION(jpi,jpj) ::   zmaskU, zmaskV                  ! mask for ice presence
151      REAL(wp), DIMENSION(jpi,jpj) ::   zfmask, zwf                     ! mask at F points for the ice
152
153      REAL(wp), PARAMETER          ::   zepsi  = 1.0e-20_wp             ! tolerance parameter
154      REAL(wp), PARAMETER          ::   zmmin  = 1._wp                  ! ice mass (kg/m2) below which ice velocity equals ocean velocity
155      !! --- diags
156      REAL(wp), DIMENSION(jpi,jpj) ::   zswi
157      REAL(wp), ALLOCATABLE, DIMENSION(:,:) ::   zsig1, zsig2, zsig3
158      !! --- SIMIP diags
159      REAL(wp), ALLOCATABLE, DIMENSION(:,:) ::   zdiag_sig1      ! Average normal stress in sea ice   
160      REAL(wp), ALLOCATABLE, DIMENSION(:,:) ::   zdiag_sig2      ! Maximum shear stress in sea ice
161      REAL(wp), ALLOCATABLE, DIMENSION(:,:) ::   zdiag_dssh_dx   ! X-direction sea-surface tilt term (N/m2)
162      REAL(wp), ALLOCATABLE, DIMENSION(:,:) ::   zdiag_dssh_dy   ! X-direction sea-surface tilt term (N/m2)
163      REAL(wp), ALLOCATABLE, DIMENSION(:,:) ::   zdiag_corstrx   ! X-direction coriolis stress (N/m2)
164      REAL(wp), ALLOCATABLE, DIMENSION(:,:) ::   zdiag_corstry   ! Y-direction coriolis stress (N/m2)
165      REAL(wp), ALLOCATABLE, DIMENSION(:,:) ::   zdiag_intstrx   ! X-direction internal stress (N/m2)
166      REAL(wp), ALLOCATABLE, DIMENSION(:,:) ::   zdiag_intstry   ! Y-direction internal stress (N/m2)
167      REAL(wp), ALLOCATABLE, DIMENSION(:,:) ::   zdiag_utau_oi   ! X-direction ocean-ice stress
168      REAL(wp), ALLOCATABLE, DIMENSION(:,:) ::   zdiag_vtau_oi   ! Y-direction ocean-ice stress 
169      REAL(wp), ALLOCATABLE, DIMENSION(:,:) ::   zdiag_xmtrp_ice ! X-component of ice mass transport (kg/s)
170      REAL(wp), ALLOCATABLE, DIMENSION(:,:) ::   zdiag_ymtrp_ice ! Y-component of ice mass transport (kg/s)
171      REAL(wp), ALLOCATABLE, DIMENSION(:,:) ::   zdiag_xmtrp_snw ! X-component of snow mass transport (kg/s)
172      REAL(wp), ALLOCATABLE, DIMENSION(:,:) ::   zdiag_ymtrp_snw ! Y-component of snow mass transport (kg/s)
173      REAL(wp), ALLOCATABLE, DIMENSION(:,:) ::   zdiag_xatrp     ! X-component of area transport (m2/s)
174      REAL(wp), ALLOCATABLE, DIMENSION(:,:) ::   zdiag_yatrp     ! Y-component of area transport (m2/s)     
175      !!-------------------------------------------------------------------
176
177      IF( kt == nit000 .AND. lwp )   WRITE(numout,*) '-- ice_dyn_rhg_evp: EVP sea-ice rheology'
178
179#if defined key_agrif 
180      CALL agrif_interp_lim3( 'U', 0, nn_nevp )   ! First interpolation of coarse values
181      CALL agrif_interp_lim3( 'V', 0, nn_nevp )
182#endif
183      !
184!!gm for Clem:  OPTIMIZATION:  I think zfmask can be computed one for all at the initialization....
185      !------------------------------------------------------------------------------!
186      ! 0) mask at F points for the ice
187      !------------------------------------------------------------------------------!
188      ! ocean/land mask
189      DO jj = 1, jpjm1
190         DO ji = 1, jpim1      ! NO vector opt.
191            zfmask(ji,jj) = tmask(ji,jj,1) * tmask(ji+1,jj,1) * tmask(ji,jj+1,1) * tmask(ji+1,jj+1,1)
192         END DO
193      END DO
194      CALL lbc_lnk( zfmask, 'F', 1._wp )
195
196      ! Lateral boundary conditions on velocity (modify zfmask)
197      zwf(:,:) = zfmask(:,:)
198      DO jj = 2, jpjm1
199         DO ji = fs_2, fs_jpim1   ! vector opt.
200            IF( zfmask(ji,jj) == 0._wp ) THEN
201               zfmask(ji,jj) = rn_ishlat * MIN( 1._wp , MAX( zwf(ji+1,jj), zwf(ji,jj+1), zwf(ji-1,jj), zwf(ji,jj-1) ) )
202            ENDIF
203         END DO
204      END DO
205      DO jj = 2, jpjm1
206         IF( zfmask(1,jj) == 0._wp ) THEN
207            zfmask(1  ,jj) = rn_ishlat * MIN( 1._wp , MAX( zwf(2,jj), zwf(1,jj+1), zwf(1,jj-1) ) )
208         ENDIF
209         IF( zfmask(jpi,jj) == 0._wp ) THEN
210            zfmask(jpi,jj) = rn_ishlat * MIN( 1._wp , MAX( zwf(jpi,jj+1), zwf(jpim1,jj), zwf(jpi,jj-1) ) )
211         ENDIF
212      END DO
213      DO ji = 2, jpim1
214         IF( zfmask(ji,1) == 0._wp ) THEN
215            zfmask(ji,1  ) = rn_ishlat * MIN( 1._wp , MAX( zwf(ji+1,1), zwf(ji,2), zwf(ji-1,1) ) )
216         ENDIF
217         IF( zfmask(ji,jpj) == 0._wp ) THEN
218            zfmask(ji,jpj) = rn_ishlat * MIN( 1._wp , MAX( zwf(ji+1,jpj), zwf(ji-1,jpj), zwf(ji,jpjm1) ) )
219         ENDIF
220      END DO
221      CALL lbc_lnk( zfmask, 'F', 1._wp )
222
223      !------------------------------------------------------------------------------!
224      ! 1) define some variables and initialize arrays
225      !------------------------------------------------------------------------------!
226      zrhoco = rau0 * rn_cio 
227
228      ! ecc2: square of yield ellipse eccenticrity
229      ecc2    = rn_ecc * rn_ecc
230      z1_ecc2 = 1._wp / ecc2
231
232      ! Time step for subcycling
233      zdtevp   = rdt_ice / REAL( nn_nevp )
234      z1_dtevp = 1._wp / zdtevp
235
236      ! alpha parameters (Bouillon 2009)
237      IF( .NOT. ln_aEVP ) THEN
238         zalph1 = ( 2._wp * rn_relast * rdt_ice ) * z1_dtevp
239         zalph2 = zalph1 * z1_ecc2
240
241         z1_alph1 = 1._wp / ( zalph1 + 1._wp )
242         z1_alph2 = 1._wp / ( zalph2 + 1._wp )
243      ENDIF
244         
245      ! Initialise stress tensor
246      zs1 (:,:) = pstress1_i (:,:) 
247      zs2 (:,:) = pstress2_i (:,:)
248      zs12(:,:) = pstress12_i(:,:)
249
250      ! Ice strength
251      CALL ice_strength
252
253      ! scale factors
254      DO jj = 2, jpjm1
255         DO ji = fs_2, fs_jpim1
256            z1_e1t0(ji,jj) = 1._wp / ( e1t(ji+1,jj  ) + e1t(ji,jj  ) )
257            z1_e2t0(ji,jj) = 1._wp / ( e2t(ji  ,jj+1) + e2t(ji,jj  ) )
258         END DO
259      END DO
260           
261      !
262      !------------------------------------------------------------------------------!
263      ! 2) Wind / ocean stress, mass terms, coriolis terms
264      !------------------------------------------------------------------------------!
265
266      IF( ln_ice_embd ) THEN             !== embedded sea ice: compute representative ice top surface ==!
267         !                                           
268         ! average interpolation coeff as used in dynspg = (1/nn_fsbc)   * {SUM[n/nn_fsbc], n=0,nn_fsbc-1}
269         !                                               = (1/nn_fsbc)^2 * {SUM[n]        , n=0,nn_fsbc-1}
270         zintn = REAL( nn_fsbc - 1 ) / REAL( nn_fsbc ) * 0.5_wp     
271         !
272         ! average interpolation coeff as used in dynspg = (1/nn_fsbc)   *    {SUM[1-n/nn_fsbc], n=0,nn_fsbc-1}
273         !                                               = (1/nn_fsbc)^2 * (nn_fsbc^2 - {SUM[n], n=0,nn_fsbc-1})
274         zintb = REAL( nn_fsbc + 1 ) / REAL( nn_fsbc ) * 0.5_wp
275         !
276         zpice(:,:) = ssh_m(:,:) + ( zintn * snwice_mass(:,:) + zintb * snwice_mass_b(:,:) ) * r1_rau0
277         !
278      ELSE                                    !== non-embedded sea ice: use ocean surface for slope calculation ==!
279         zpice(:,:) = ssh_m(:,:)
280      ENDIF
281
282      DO jj = 2, jpjm1
283         DO ji = fs_2, fs_jpim1
284
285            ! ice fraction at U-V points
286            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)
287            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)
288
289            ! Ice/snow mass at U-V points
290            zm1 = ( rhosn * vt_s(ji  ,jj  ) + rhoic * vt_i(ji  ,jj  ) )
291            zm2 = ( rhosn * vt_s(ji+1,jj  ) + rhoic * vt_i(ji+1,jj  ) )
292            zm3 = ( rhosn * vt_s(ji  ,jj+1) + rhoic * vt_i(ji  ,jj+1) )
293            zmassU = 0.5_wp * ( zm1 * e1e2t(ji,jj) + zm2 * e1e2t(ji+1,jj) ) * r1_e1e2u(ji,jj) * umask(ji,jj,1)
294            zmassV = 0.5_wp * ( zm1 * e1e2t(ji,jj) + zm3 * e1e2t(ji,jj+1) ) * r1_e1e2v(ji,jj) * vmask(ji,jj,1)
295
296            ! Ocean currents at U-V points
297            v_oceU(ji,jj)   = 0.5_wp * ( ( v_oce(ji  ,jj) + v_oce(ji  ,jj-1) ) * e1t(ji+1,jj)    &
298               &                       + ( v_oce(ji+1,jj) + v_oce(ji+1,jj-1) ) * e1t(ji  ,jj) ) * z1_e1t0(ji,jj) * umask(ji,jj,1)
299           
300            u_oceV(ji,jj)   = 0.5_wp * ( ( u_oce(ji,jj  ) + u_oce(ji-1,jj  ) ) * e2t(ji,jj+1)    &
301               &                       + ( u_oce(ji,jj+1) + u_oce(ji-1,jj+1) ) * e2t(ji,jj  ) ) * z1_e2t0(ji,jj) * vmask(ji,jj,1)
302
303            ! Coriolis at T points (m*f)
304            zmf(ji,jj)      = zm1 * ff_t(ji,jj)
305
306            ! dt/m at T points (for alpha and beta coefficients)
307            zdt_m(ji,jj)    = zdtevp / MAX( zm1, zmmin )
308           
309            ! m/dt
310            zmU_t(ji,jj)    = zmassU * z1_dtevp
311            zmV_t(ji,jj)    = zmassV * z1_dtevp
312           
313            ! Drag ice-atm.
314            zTauU_ia(ji,jj) = zaU(ji,jj) * utau_ice(ji,jj)
315            zTauV_ia(ji,jj) = zaV(ji,jj) * vtau_ice(ji,jj)
316
317            ! Surface pressure gradient (- m*g*GRAD(ssh)) at U-V points
318            zspgU(ji,jj)    = - zmassU * grav * ( zpice(ji+1,jj) - zpice(ji,jj) ) * r1_e1u(ji,jj)
319            zspgV(ji,jj)    = - zmassV * grav * ( zpice(ji,jj+1) - zpice(ji,jj) ) * r1_e2v(ji,jj)
320
321            ! masks
322            zmaskU(ji,jj) = 1._wp - MAX( 0._wp, SIGN( 1._wp, -zmassU ) )  ! 0 if no ice
323            zmaskV(ji,jj) = 1._wp - MAX( 0._wp, SIGN( 1._wp, -zmassV ) )  ! 0 if no ice
324
325            ! switches
326            zswitchU(ji,jj) = MAX( 0._wp, SIGN( 1._wp, zmassU - zmmin ) ) ! 0 if ice mass < zmmin
327            zswitchV(ji,jj) = MAX( 0._wp, SIGN( 1._wp, zmassV - zmmin ) ) ! 0 if ice mass < zmmin
328
329         END DO
330      END DO
331      CALL lbc_lnk_multi( zmf, 'T', 1., zdt_m, 'T', 1. )
332      !
333      !------------------------------------------------------------------------------!
334      ! 3) Solution of the momentum equation, iterative procedure
335      !------------------------------------------------------------------------------!
336      !
337      !                                               !----------------------!
338      DO jter = 1 , nn_nevp                           !    loop over jter    !
339         !                                            !----------------------!       
340         IF(ln_ctl) THEN   ! Convergence test
341            DO jj = 1, jpjm1
342               zu_ice(:,jj) = u_ice(:,jj) ! velocity at previous time step
343               zv_ice(:,jj) = v_ice(:,jj)
344            END DO
345         ENDIF
346
347         ! --- divergence, tension & shear (Appendix B of Hunke & Dukowicz, 2002) --- !
348         DO jj = 1, jpjm1         ! loops start at 1 since there is no boundary condition (lbc_lnk) at i=1 and j=1 for F points
349            DO ji = 1, jpim1
350
351               ! shear at F points
352               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)   &
353                  &         + ( v_ice(ji+1,jj) * r1_e2v(ji+1,jj) - v_ice(ji,jj) * r1_e2v(ji,jj) ) * e2f(ji,jj) * e2f(ji,jj)   &
354                  &         ) * r1_e1e2f(ji,jj) * zfmask(ji,jj)
355
356            END DO
357         END DO
358         CALL lbc_lnk( zds, 'F', 1. )
359
360         DO jj = 2, jpj    ! loop to jpi,jpj to avoid making a communication for zs1,zs2,zs12
361            DO ji = 2, jpi ! no vector loop
362
363               ! shear**2 at T points (doc eq. A16)
364               zds2 = ( zds(ji,jj  ) * zds(ji,jj  ) * e1e2f(ji,jj  ) + zds(ji-1,jj  ) * zds(ji-1,jj  ) * e1e2f(ji-1,jj  )  &
365                  &   + 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)  &
366                  &   ) * 0.25_wp * r1_e1e2t(ji,jj)
367             
368               ! divergence at T points
369               zdiv  = ( e2u(ji,jj) * u_ice(ji,jj) - e2u(ji-1,jj) * u_ice(ji-1,jj)   &
370                  &    + e1v(ji,jj) * v_ice(ji,jj) - e1v(ji,jj-1) * v_ice(ji,jj-1)   &
371                  &    ) * r1_e1e2t(ji,jj)
372               zdiv2 = zdiv * zdiv
373               
374               ! tension at T points
375               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)   &
376                  &   - ( v_ice(ji,jj) * r1_e1v(ji,jj) - v_ice(ji,jj-1) * r1_e1v(ji,jj-1) ) * e1t(ji,jj) * e1t(ji,jj)   &
377                  &   ) * r1_e1e2t(ji,jj)
378               zdt2 = zdt * zdt
379               
380               ! delta at T points
381               zdelta = SQRT( zdiv2 + ( zdt2 + zds2 ) * z1_ecc2 ) 
382
383               ! P/delta at T points
384               zp_delt(ji,jj) = strength(ji,jj) / ( zdelta + rn_creepl )
385
386               ! alpha & beta for aEVP
387               !   gamma = 0.5*P/(delta+creepl) * (c*pi)**2/Area * dt/m
388               !   alpha = beta = sqrt(4*gamma)
389               IF( ln_aEVP ) THEN
390                  zalph1   = MAX( 50._wp, rpi * SQRT( 0.5_wp * zp_delt(ji,jj) * r1_e1e2t(ji,jj) * zdt_m(ji,jj) ) )
391                  z1_alph1 = 1._wp / ( zalph1 + 1._wp )
392                  zalph2   = zalph1
393                  z1_alph2 = z1_alph1
394               ENDIF
395               
396               ! stress at T points
397               zs1(ji,jj) = ( zs1(ji,jj) * zalph1 + zp_delt(ji,jj) * ( zdiv - zdelta ) ) * z1_alph1
398               zs2(ji,jj) = ( zs2(ji,jj) * zalph2 + zp_delt(ji,jj) * ( zdt * z1_ecc2 ) ) * z1_alph2
399             
400            END DO
401         END DO
402         CALL lbc_lnk( zp_delt, 'T', 1. )
403
404         DO jj = 1, jpjm1
405            DO ji = 1, jpim1
406
407               ! alpha & beta for aEVP
408               IF( ln_aEVP ) THEN
409                  zalph2   = MAX( 50._wp, rpi * SQRT( 0.5_wp * zp_delt(ji,jj) * r1_e1e2t(ji,jj) * zdt_m(ji,jj) ) )
410                  z1_alph2 = 1._wp / ( zalph2 + 1._wp )
411                  zbeta(ji,jj) = zalph2
412               ENDIF
413               
414               ! P/delta at F points
415               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) )
416               
417               ! stress at F points
418               zs12(ji,jj)= ( zs12(ji,jj) * zalph2 + zp_delf * ( zds(ji,jj) * z1_ecc2 ) * 0.5_wp ) * z1_alph2
419
420            END DO
421         END DO
422
423         ! --- Ice internal stresses (Appendix C of Hunke and Dukowicz, 2002) --- !
424         DO jj = 2, jpjm1
425            DO ji = fs_2, fs_jpim1               
426               !                   !--- U points
427               zfU(ji,jj) = 0.5_wp * ( ( zs1(ji+1,jj) - zs1(ji,jj) ) * e2u(ji,jj)                                             &
428                  &                  + ( zs2(ji+1,jj) * e2t(ji+1,jj) * e2t(ji+1,jj) - zs2(ji,jj) * e2t(ji,jj) * e2t(ji,jj)    &
429                  &                    ) * r1_e2u(ji,jj)                                                                      &
430                  &                  + ( zs12(ji,jj) * e1f(ji,jj) * e1f(ji,jj) - zs12(ji,jj-1) * e1f(ji,jj-1) * e1f(ji,jj-1)  &
431                  &                    ) * 2._wp * r1_e1u(ji,jj)                                                              &
432                  &                  ) * r1_e1e2u(ji,jj)
433               !
434               !                !--- V points
435               zfV(ji,jj) = 0.5_wp * ( ( zs1(ji,jj+1) - zs1(ji,jj) ) * e1v(ji,jj)                                             &
436                  &                  - ( zs2(ji,jj+1) * e1t(ji,jj+1) * e1t(ji,jj+1) - zs2(ji,jj) * e1t(ji,jj) * e1t(ji,jj)    &
437                  &                    ) * r1_e1v(ji,jj)                                                                      &
438                  &                  + ( zs12(ji,jj) * e2f(ji,jj) * e2f(ji,jj) - zs12(ji-1,jj) * e2f(ji-1,jj) * e2f(ji-1,jj)  &
439                  &                    ) * 2._wp * r1_e2v(ji,jj)                                                              &
440                  &                  ) * r1_e1e2v(ji,jj)
441               !
442               !                !--- u_ice at V point
443               u_iceV(ji,jj) = 0.5_wp * ( ( u_ice(ji,jj  ) + u_ice(ji-1,jj  ) ) * e2t(ji,jj+1)     &
444                  &                     + ( u_ice(ji,jj+1) + u_ice(ji-1,jj+1) ) * e2t(ji,jj  ) ) * z1_e2t0(ji,jj) * vmask(ji,jj,1)
445               !
446               !                !--- v_ice at U point
447               v_iceU(ji,jj) = 0.5_wp * ( ( v_ice(ji  ,jj) + v_ice(ji  ,jj-1) ) * e1t(ji+1,jj)     &
448                  &                     + ( v_ice(ji+1,jj) + v_ice(ji+1,jj-1) ) * e1t(ji  ,jj) ) * z1_e1t0(ji,jj) * umask(ji,jj,1)
449            END DO
450         END DO
451         !
452         ! --- Computation of ice velocity --- !
453         !  Bouillon et al. 2013 (eq 47-48) => unstable unless alpha, beta vary as in Kimmritz 2016 & 2017
454         !  Bouillon et al. 2009 (eq 34-35) => stable
455         IF( MOD(jter,2) == 0 ) THEN ! even iterations
456            !
457            DO jj = 2, jpjm1
458               DO ji = fs_2, fs_jpim1
459                  !                 !--- tau_io/(v_oce - v_ice)
460                  zTauO = zaV(ji,jj) * zrhoco * SQRT( ( v_ice (ji,jj) - v_oce (ji,jj) ) * ( v_ice (ji,jj) - v_oce (ji,jj) )  &
461                     &                              + ( u_iceV(ji,jj) - u_oceV(ji,jj) ) * ( u_iceV(ji,jj) - u_oceV(ji,jj) ) )
462                  !                 !--- Ocean-to-Ice stress
463                  ztauy_oi(ji,jj) = zTauO * ( v_oce(ji,jj) - v_ice(ji,jj) )
464                  !
465                  !                 !--- tau_bottom/v_ice
466                  zvel  = MAX( zepsi, SQRT( v_ice(ji,jj) * v_ice(ji,jj) + u_iceV(ji,jj) * u_iceV(ji,jj) ) )
467                  zTauB = - tau_icebfr(ji,jj) / zvel
468                  !
469                  !                 !--- Coriolis at V-points (energy conserving formulation)
470                  zCory(ji,jj)  = - 0.25_wp * r1_e2v(ji,jj) *  &
471                     &    ( zmf(ji,jj  ) * ( e2u(ji,jj  ) * u_ice(ji,jj  ) + e2u(ji-1,jj  ) * u_ice(ji-1,jj  ) )  &
472                     &    + zmf(ji,jj+1) * ( e2u(ji,jj+1) * u_ice(ji,jj+1) + e2u(ji-1,jj+1) * u_ice(ji-1,jj+1) ) )
473                  !
474                  !                 !--- Sum of external forces (explicit solution) = F + tau_ia + Coriolis + spg + tau_io
475                  zTauE = zfV(ji,jj) + zTauV_ia(ji,jj) + zCory(ji,jj) + zspgV(ji,jj) + ztauy_oi(ji,jj)
476                  !
477                  !                 !--- landfast switch => 0 = static friction ; 1 = sliding friction
478                  rswitch = 1._wp - MIN( 1._wp, ABS( SIGN( 1._wp, ztauE - tau_icebfr(ji,jj) ) - SIGN( 1._wp, zTauE ) ) )
479                  !
480                  IF( ln_aEVP ) THEN !--- ice velocity using aEVP (Kimmritz et al 2016 & 2017)
481                  v_ice(ji,jj) = ( (          rswitch * ( zmV_t(ji,jj) * ( zbeta(ji,jj) * v_ice(ji,jj) + v_ice_b(ji,jj) )         & ! previous velocity
482                     &                                  + zTauE + zTauO * v_ice(ji,jj)                                            & ! F + tau_ia + Coriolis + spg + tau_io(only ocean part)
483                     &                                  ) / MAX( zepsi, zmV_t(ji,jj) * ( zbeta(ji,jj) + 1._wp ) + zTauO - zTauB ) & ! m/dt + tau_io(only ice part) + landfast
484                     &                 + ( 1._wp - rswitch ) * v_ice(ji,jj) * MAX( 0._wp, 1._wp - zdtevp * rn_lfrelax )           & ! static friction => slow decrease to v=0
485                     &             ) * zswitchV(ji,jj) + v_oce(ji,jj) * ( 1._wp - zswitchV(ji,jj) )                               & ! v_ice = v_oce if mass < zmmin
486                     &           ) * zmaskV(ji,jj)
487                  ELSE               !--- ice velocity using EVP implicit formulation (cf Madec doc & Bouillon 2009)
488                  v_ice(ji,jj) = ( (           rswitch   * ( zmV_t(ji,jj)  * v_ice(ji,jj)                             &  ! previous velocity
489                     &                                     + zTauE + zTauO * v_ice(ji,jj)                             &  ! F + tau_ia + Coriolis + spg + tau_io(only ocean part)
490                     &                                     ) / MAX( zepsi, zmV_t(ji,jj) + zTauO - zTauB )             &  ! m/dt + tau_io(only ice part) + landfast
491                     &              + ( 1._wp - rswitch ) * v_ice(ji,jj) * MAX( 0._wp, 1._wp - zdtevp * rn_lfrelax )  &  ! static friction => slow decrease to v=0
492                     &              ) * zswitchV(ji,jj) + v_oce(ji,jj) * ( 1._wp - zswitchV(ji,jj) )                  &  ! v_ice = v_oce if mass < zmmin
493                     &            ) * zmaskV(ji,jj)
494                  ENDIF
495               END DO
496            END DO
497            CALL lbc_lnk( v_ice, 'V', -1. )
498            !
499#if defined key_agrif
500!!            CALL agrif_interp_lim3( 'V', jter, nn_nevp )
501            CALL agrif_interp_lim3( 'V' )
502#endif
503            IF( ln_bdy ) CALL bdy_ice_dyn( 'V' )
504            !
505            DO jj = 2, jpjm1
506               DO ji = fs_2, fs_jpim1         
507                  !                 !--- tau_io/(u_oce - u_ice)
508                  zTauO = zaU(ji,jj) * zrhoco * SQRT( ( u_ice (ji,jj) - u_oce (ji,jj) ) * ( u_ice (ji,jj) - u_oce (ji,jj) )  &
509                     &                              + ( v_iceU(ji,jj) - v_oceU(ji,jj) ) * ( v_iceU(ji,jj) - v_oceU(ji,jj) ) )
510                  !                 !--- Ocean-to-Ice stress
511                  ztaux_oi(ji,jj) = zTauO * ( u_oce(ji,jj) - u_ice(ji,jj) )
512                  !
513                  !                 !--- tau_bottom/u_ice
514                  zvel  = MAX( zepsi, SQRT( v_iceU(ji,jj) * v_iceU(ji,jj) + u_ice(ji,jj) * u_ice(ji,jj) ) )
515                  zTauB = - tau_icebfr(ji,jj) / zvel
516                  !
517                  !                 !--- Coriolis at U-points (energy conserving formulation)
518                  zCorx(ji,jj)  =   0.25_wp * r1_e1u(ji,jj) *  &
519                     &    ( zmf(ji  ,jj) * ( e1v(ji  ,jj) * v_ice(ji  ,jj) + e1v(ji  ,jj-1) * v_ice(ji  ,jj-1) )  &
520                     &    + zmf(ji+1,jj) * ( e1v(ji+1,jj) * v_ice(ji+1,jj) + e1v(ji+1,jj-1) * v_ice(ji+1,jj-1) ) )
521                  !
522                  !                 !--- Sum of external forces (explicit solution) = F + tau_ia + Coriolis + spg + tau_io
523                  zTauE = zfU(ji,jj) + zTauU_ia(ji,jj) + zCorx(ji,jj) + zspgU(ji,jj) + ztaux_oi(ji,jj)
524                  !
525                  !                 !--- landfast switch => 0 = static friction ; 1 = sliding friction
526                  rswitch = 1._wp - MIN( 1._wp, ABS( SIGN( 1._wp, ztauE - tau_icebfr(ji,jj) ) - SIGN( 1._wp, zTauE ) ) )
527                  !
528                  IF( ln_aEVP ) THEN !--- ice velocity using aEVP (Kimmritz et al 2016 & 2017)
529                  u_ice(ji,jj) = ( (          rswitch * ( zmU_t(ji,jj) * ( zbeta(ji,jj) * u_ice(ji,jj) + u_ice_b(ji,jj) )         & ! previous velocity
530                     &                                     + zTauE + zTauO * u_ice(ji,jj)                                         & ! F + tau_ia + Coriolis + spg + tau_io(only ocean part)
531                     &                                  ) / MAX( zepsi, zmU_t(ji,jj) * ( zbeta(ji,jj) + 1._wp ) + zTauO - zTauB ) & ! m/dt + tau_io(only ice part) + landfast
532                     &              + ( 1._wp - rswitch ) * u_ice(ji,jj) * MAX( 0._wp, 1._wp - zdtevp * rn_lfrelax )              & ! static friction => slow decrease to v=0
533                     &              ) * zswitchU(ji,jj) + u_oce(ji,jj) * ( 1._wp - zswitchU(ji,jj) )                              & ! v_ice = v_oce if mass < zmmin
534                     &            ) * zmaskU(ji,jj)
535                  ELSE               !--- ice velocity using EVP implicit formulation (cf Madec doc & Bouillon 2009)
536                  u_ice(ji,jj) = ( (           rswitch   * ( zmU_t(ji,jj)  * u_ice(ji,jj)                             &  ! previous velocity
537                     &                                     + zTauE + zTauO * u_ice(ji,jj)                             &  ! F + tau_ia + Coriolis + spg + tau_io(only ocean part)
538                     &                                     ) / MAX( zepsi, zmU_t(ji,jj) + zTauO - zTauB )             &  ! m/dt + tau_io(only ice part) + landfast
539                     &              + ( 1._wp - rswitch ) * u_ice(ji,jj) * MAX( 0._wp, 1._wp - zdtevp * rn_lfrelax )  &  ! static friction => slow decrease to v=0
540                     &              ) * zswitchU(ji,jj) + u_oce(ji,jj) * ( 1._wp - zswitchU(ji,jj) )                  &  ! v_ice = v_oce if mass < zmmin
541                     &            ) * zmaskU(ji,jj)
542                  ENDIF
543               END DO
544            END DO
545            CALL lbc_lnk( u_ice, 'U', -1. )
546            !
547#if defined key_agrif
548!!            CALL agrif_interp_lim3( 'U', jter, nn_nevp )
549            CALL agrif_interp_lim3( 'U' )
550#endif
551            IF( ln_bdy ) CALL bdy_ice_dyn( 'U' )
552            !
553         ELSE ! odd iterations
554            !
555            DO jj = 2, jpjm1
556               DO ji = fs_2, fs_jpim1
557                  !                 !--- tau_io/(u_oce - u_ice)
558                  zTauO = zaU(ji,jj) * zrhoco * SQRT( ( u_ice (ji,jj) - u_oce (ji,jj) ) * ( u_ice (ji,jj) - u_oce (ji,jj) )  &
559                     &                              + ( v_iceU(ji,jj) - v_oceU(ji,jj) ) * ( v_iceU(ji,jj) - v_oceU(ji,jj) ) )
560                  !                 !--- Ocean-to-Ice stress
561                  ztaux_oi(ji,jj) = zTauO * ( u_oce(ji,jj) - u_ice(ji,jj) )
562                  !
563                  !                 !--- tau_bottom/u_ice
564                  zvel  = MAX( zepsi, SQRT( v_iceU(ji,jj) * v_iceU(ji,jj) + u_ice(ji,jj) * u_ice(ji,jj) ) )
565                  zTauB = - tau_icebfr(ji,jj) / zvel
566                  !
567                  !                 !--- Coriolis at U-points (energy conserving formulation)
568                  zCorx(ji,jj)  =   0.25_wp * r1_e1u(ji,jj) *  &
569                     &    ( zmf(ji  ,jj) * ( e1v(ji  ,jj) * v_ice(ji  ,jj) + e1v(ji  ,jj-1) * v_ice(ji  ,jj-1) )  &
570                     &    + zmf(ji+1,jj) * ( e1v(ji+1,jj) * v_ice(ji+1,jj) + e1v(ji+1,jj-1) * v_ice(ji+1,jj-1) ) )
571                  !
572                  !                 !--- Sum of external forces (explicit solution) = F + tau_ia + Coriolis + spg + tau_io
573                  zTauE = zfU(ji,jj) + zTauU_ia(ji,jj) + zCorx(ji,jj) + zspgU(ji,jj) + ztaux_oi(ji,jj)
574                  !
575                  !                 !--- landfast switch => 0 = static friction ; 1 = sliding friction
576                  rswitch = 1._wp - MIN( 1._wp, ABS( SIGN( 1._wp, ztauE - tau_icebfr(ji,jj) ) - SIGN( 1._wp, zTauE ) ) )
577                  !
578                  IF( ln_aEVP ) THEN !--- ice velocity using aEVP (Kimmritz et al 2016 & 2017)
579                  u_ice(ji,jj) = ( (          rswitch * ( zmU_t(ji,jj) * ( zbeta(ji,jj) * u_ice(ji,jj) + u_ice_b(ji,jj) )         & ! previous velocity
580                     &                                     + zTauE + zTauO * u_ice(ji,jj)                                         & ! F + tau_ia + Coriolis + spg + tau_io(only ocean part)
581                     &                                  ) / MAX( zepsi, zmU_t(ji,jj) * ( zbeta(ji,jj) + 1._wp ) + zTauO - zTauB ) & ! m/dt + tau_io(only ice part) + landfast
582                     &              + ( 1._wp - rswitch ) * u_ice(ji,jj) * MAX( 0._wp, 1._wp - zdtevp * rn_lfrelax )              & ! static friction => slow decrease to v=0
583                     &              ) * zswitchU(ji,jj) + u_oce(ji,jj) * ( 1._wp - zswitchU(ji,jj) )                              & ! v_ice = v_oce if mass < zmmin
584                     &            ) * zmaskU(ji,jj)
585                  ELSE               !--- ice velocity using EVP implicit formulation (cf Madec doc & Bouillon 2009)
586                  u_ice(ji,jj) = ( (           rswitch   * ( zmU_t(ji,jj)  * u_ice(ji,jj)                             &  ! previous velocity
587                     &                                     + zTauE + zTauO * u_ice(ji,jj)                             &  ! F + tau_ia + Coriolis + spg + tau_io(only ocean part)
588                     &                                     ) / MAX( zepsi, zmU_t(ji,jj) + zTauO - zTauB )             &  ! m/dt + tau_io(only ice part) + landfast
589                     &              + ( 1._wp - rswitch ) * u_ice(ji,jj) * MAX( 0._wp, 1._wp - zdtevp * rn_lfrelax )  &  ! static friction => slow decrease to v=0
590                     &              ) * zswitchU(ji,jj) + u_oce(ji,jj) * ( 1._wp - zswitchU(ji,jj) )                  &  ! v_ice = v_oce if mass < zmmin
591                     &            ) * zmaskU(ji,jj)
592                  ENDIF
593               END DO
594            END DO
595            CALL lbc_lnk( u_ice, 'U', -1. )
596            !
597#if defined key_agrif
598!!            CALL agrif_interp_lim3( 'U', jter, nn_nevp )
599            CALL agrif_interp_lim3( 'U' )
600#endif
601            IF( ln_bdy ) CALL bdy_ice_dyn( 'U' )
602            !
603            DO jj = 2, jpjm1
604               DO ji = fs_2, fs_jpim1
605                  !                 !--- tau_io/(v_oce - v_ice)
606                  zTauO = zaV(ji,jj) * zrhoco * SQRT( ( v_ice (ji,jj) - v_oce (ji,jj) ) * ( v_ice (ji,jj) - v_oce (ji,jj) )  &
607                     &                              + ( u_iceV(ji,jj) - u_oceV(ji,jj) ) * ( u_iceV(ji,jj) - u_oceV(ji,jj) ) )
608                  !                 !--- Ocean-to-Ice stress
609                  ztauy_oi(ji,jj) = zTauO * ( v_oce(ji,jj) - v_ice(ji,jj) )
610                  !
611                  !                 !--- tau_bottom/v_ice
612                  zvel  = MAX( zepsi, SQRT( v_ice(ji,jj) * v_ice(ji,jj) + u_iceV(ji,jj) * u_iceV(ji,jj) ) )
613                  ztauB = - tau_icebfr(ji,jj) / zvel
614                  !
615                  !                 !--- Coriolis at v-points (energy conserving formulation)
616                  zCory(ji,jj)  = - 0.25_wp * r1_e2v(ji,jj) *  &
617                     &    ( zmf(ji,jj  ) * ( e2u(ji,jj  ) * u_ice(ji,jj  ) + e2u(ji-1,jj  ) * u_ice(ji-1,jj  ) )  &
618                     &    + zmf(ji,jj+1) * ( e2u(ji,jj+1) * u_ice(ji,jj+1) + e2u(ji-1,jj+1) * u_ice(ji-1,jj+1) ) )
619                  !
620                  !                 !--- Sum of external forces (explicit solution) = F + tau_ia + Coriolis + spg + tau_io
621                  zTauE = zfV(ji,jj) + zTauV_ia(ji,jj) + zCory(ji,jj) + zspgV(ji,jj) + ztauy_oi(ji,jj)
622                  !
623                  !                 !--- landfast switch => 0 = static friction ; 1 = sliding friction
624                  rswitch = 1._wp - MIN( 1._wp, ABS( SIGN( 1._wp, zTauE - tau_icebfr(ji,jj) ) - SIGN( 1._wp, zTauE ) ) )
625                  !
626                  IF( ln_aEVP ) THEN !--- ice velocity using aEVP (Kimmritz et al 2016 & 2017)
627                  v_ice(ji,jj) = ( (          rswitch * ( zmV_t(ji,jj) * ( zbeta(ji,jj) * v_ice(ji,jj) + v_ice_b(ji,jj) )         & ! previous velocity
628                     &                                  + zTauE + zTauO * v_ice(ji,jj)                                            & ! F + tau_ia + Coriolis + spg + tau_io(only ocean part)
629                     &                                  ) / MAX( zepsi, zmV_t(ji,jj) * ( zbeta(ji,jj) + 1._wp ) + zTauO - zTauB ) & ! m/dt + tau_io(only ice part) + landfast
630                     &                 + ( 1._wp - rswitch ) * v_ice(ji,jj) * MAX( 0._wp, 1._wp - zdtevp * rn_lfrelax )           & ! static friction => slow decrease to v=0
631                     &             ) * zswitchV(ji,jj) + v_oce(ji,jj) * ( 1._wp - zswitchV(ji,jj) )                               & ! v_ice = v_oce if mass < zmmin
632                     &           ) * zmaskV(ji,jj)
633                  ELSE               !--- ice velocity using EVP implicit formulation (cf Madec doc & Bouillon 2009)
634                  v_ice(ji,jj) = ( (           rswitch   * ( zmV_t(ji,jj)  * v_ice(ji,jj)                             &  ! previous velocity
635                     &                                     + zTauE + zTauO * v_ice(ji,jj)                             &  ! F + tau_ia + Coriolis + spg + tau_io(only ocean part)
636                     &                                     ) / MAX( zepsi, zmV_t(ji,jj) + zTauO - zTauB )             &  ! m/dt + tau_io(only ice part) + landfast
637                     &              + ( 1._wp - rswitch ) * v_ice(ji,jj) * MAX( 0._wp, 1._wp - zdtevp * rn_lfrelax )  &  ! static friction => slow decrease to v=0
638                     &              ) * zswitchV(ji,jj) + v_oce(ji,jj) * ( 1._wp - zswitchV(ji,jj) )                  &  ! v_ice = v_oce if mass < zmmin
639                     &            ) * zmaskV(ji,jj)
640                  ENDIF
641               END DO
642            END DO
643            CALL lbc_lnk( v_ice, 'V', -1. )
644            !
645#if defined key_agrif
646!!            CALL agrif_interp_lim3( 'V', jter, nn_nevp )
647            CALL agrif_interp_lim3( 'V' )
648#endif
649            IF( ln_bdy ) CALL bdy_ice_dyn( 'V' )
650            !
651         ENDIF
652         
653         IF(ln_ctl) THEN   ! Convergence test
654            DO jj = 2 , jpjm1
655               zresr(:,jj) = MAX( ABS( u_ice(:,jj) - zu_ice(:,jj) ), ABS( v_ice(:,jj) - zv_ice(:,jj) ) )
656            END DO
657            zresm = MAXVAL( zresr( 1:jpi, 2:jpjm1 ) )
658            IF( lk_mpp )   CALL mpp_max( zresm )   ! max over the global domain
659         ENDIF
660         !
661         !                                                ! ==================== !
662      END DO                                              !  end loop over jter  !
663      !                                                   ! ==================== !
664      !
665      !------------------------------------------------------------------------------!
666      ! 4) Recompute delta, shear and div (inputs for mechanical redistribution)
667      !------------------------------------------------------------------------------!
668      DO jj = 1, jpjm1
669         DO ji = 1, jpim1
670
671            ! shear at F points
672            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)   &
673               &         + ( v_ice(ji+1,jj) * r1_e2v(ji+1,jj) - v_ice(ji,jj) * r1_e2v(ji,jj) ) * e2f(ji,jj) * e2f(ji,jj)   &
674               &         ) * r1_e1e2f(ji,jj) * zfmask(ji,jj)
675
676         END DO
677      END DO           
678     
679      DO jj = 2, jpjm1
680         DO ji = 2, jpim1 ! no vector loop
681           
682            ! tension**2 at T points
683            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)   &
684               &   - ( v_ice(ji,jj) * r1_e1v(ji,jj) - v_ice(ji,jj-1) * r1_e1v(ji,jj-1) ) * e1t(ji,jj) * e1t(ji,jj)   &
685               &   ) * r1_e1e2t(ji,jj)
686            zdt2 = zdt * zdt
687           
688            ! shear**2 at T points (doc eq. A16)
689            zds2 = ( zds(ji,jj  ) * zds(ji,jj  ) * e1e2f(ji,jj  ) + zds(ji-1,jj  ) * zds(ji-1,jj  ) * e1e2f(ji-1,jj  )  &
690               &   + 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)  &
691               &   ) * 0.25_wp * r1_e1e2t(ji,jj)
692           
693            ! shear at T points
694            pshear_i(ji,jj) = SQRT( zdt2 + zds2 )
695
696            ! divergence at T points
697            pdivu_i(ji,jj) = ( e2u(ji,jj) * u_ice(ji,jj) - e2u(ji-1,jj) * u_ice(ji-1,jj)   &
698               &             + e1v(ji,jj) * v_ice(ji,jj) - e1v(ji,jj-1) * v_ice(ji,jj-1)   &
699               &             ) * r1_e1e2t(ji,jj)
700           
701            ! delta at T points
702            zdelta         = SQRT( pdivu_i(ji,jj) * pdivu_i(ji,jj) + ( zdt2 + zds2 ) * z1_ecc2 ) 
703            rswitch        = 1._wp - MAX( 0._wp, SIGN( 1._wp, -zdelta ) ) ! 0 if delta=0
704            pdelta_i(ji,jj) = zdelta + rn_creepl * rswitch
705
706         END DO
707      END DO
708      CALL lbc_lnk_multi( pshear_i, 'T', 1., pdivu_i, 'T', 1., pdelta_i, 'T', 1. )
709     
710      ! --- Store the stress tensor for the next time step --- !
711      CALL lbc_lnk_multi( zs1, 'T', 1., zs2, 'T', 1., zs12, 'F', 1. )
712      pstress1_i (:,:) = zs1 (:,:)
713      pstress2_i (:,:) = zs2 (:,:)
714      pstress12_i(:,:) = zs12(:,:)
715      !
716
717      !------------------------------------------------------------------------------!
718      ! 5) diagnostics
719      !------------------------------------------------------------------------------!
720      DO jj = 1, jpj
721         DO ji = 1, jpi
722            zswi(ji,jj) = MAX( 0._wp , SIGN( 1._wp , at_i(ji,jj) - epsi06 ) ) ! 1 if ice, 0 if no ice
723         END DO
724      END DO
725
726      ! --- divergence, shear and strength --- !
727      IF( iom_use('icediv') )   CALL iom_put( "icediv" , pdivu_i (:,:) * zswi(:,:) )   ! divergence
728      IF( iom_use('iceshe') )   CALL iom_put( "iceshe" , pshear_i(:,:) * zswi(:,:) )   ! shear
729      IF( iom_use('icestr') )   CALL iom_put( "icestr" , strength(:,:) * zswi(:,:) )   ! Ice strength
730
731      ! --- charge ellipse --- !
732      IF( iom_use('isig1') .OR. iom_use('isig2') .OR. iom_use('isig3') ) THEN
733         !
734         ALLOCATE( zsig1(jpi,jpj) , zsig2(jpi,jpj) , zsig3(jpi,jpj) )
735         !         
736         DO jj = 2, jpjm1
737            DO ji = 2, jpim1
738               zdum1 = ( zswi(ji-1,jj) * pstress12_i(ji-1,jj) + zswi(ji  ,jj-1) * pstress12_i(ji  ,jj-1) +  &  ! stress12_i at T-point
739                  &      zswi(ji  ,jj) * pstress12_i(ji  ,jj) + zswi(ji-1,jj-1) * pstress12_i(ji-1,jj-1) )  &
740                  &    / MAX( 1._wp, zswi(ji-1,jj) + zswi(ji,jj-1) + zswi(ji,jj) + zswi(ji-1,jj-1) )
741
742               zshear = SQRT( pstress2_i(ji,jj) * pstress2_i(ji,jj) + 4._wp * zdum1 * zdum1 ) ! shear stress 
743
744               zdum2 = zswi(ji,jj) / MAX( 1._wp, strength(ji,jj) )
745
746!!               zsig1(ji,jj) = 0.5_wp * zdum2 * ( pstress1_i(ji,jj) + zshear ) ! principal stress (y-direction, see Hunke & Dukowicz 2002)
747!!               zsig2(ji,jj) = 0.5_wp * zdum2 * ( pstress1_i(ji,jj) - zshear ) ! principal stress (x-direction, see Hunke & Dukowicz 2002)
748!!               zsig3(ji,jj) = zdum2**2 * ( ( pstress1_i(ji,jj) + strength(ji,jj) )**2 + ( rn_ecc * zshear )**2 ) ! quadratic relation linking compressive stress to shear stress
749!!                                                                                                               ! (scheme converges if this value is ~1, see Bouillon et al 2009 (eq. 11))
750               zsig1(ji,jj) = 0.5_wp * zdum2 * ( pstress1_i(ji,jj) )          ! compressive stress, see Bouillon et al. 2015
751               zsig2(ji,jj) = 0.5_wp * zdum2 * ( zshear )                     ! shear stress
752               zsig3(ji,jj) = zdum2**2 * ( ( pstress1_i(ji,jj) + strength(ji,jj) )**2 + ( rn_ecc * zshear )**2 )
753            END DO
754         END DO
755         CALL lbc_lnk_multi( zsig1, 'T', 1., zsig2, 'T', 1., zsig3, 'T', 1. )
756         !
757         IF( iom_use('isig1') )   CALL iom_put( "isig1" , zsig1 )
758         IF( iom_use('isig2') )   CALL iom_put( "isig2" , zsig2 )
759         IF( iom_use('isig3') )   CALL iom_put( "isig3" , zsig3 )
760         !
761         DEALLOCATE( zsig1 , zsig2 , zsig3 )
762      ENDIF
763     
764      ! --- SIMIP --- !
765      IF ( iom_use( 'normstr'  ) .OR. iom_use( 'sheastr'  ) .OR. iom_use( 'dssh_dx'  ) .OR. iom_use( 'dssh_dy'  ) .OR. &
766         & iom_use( 'corstrx'  ) .OR. iom_use( 'corstry'  ) .OR. iom_use( 'intstrx'  ) .OR. iom_use( 'intstry'  ) .OR. &
767         & iom_use( 'utau_oi'  ) .OR. iom_use( 'vtau_oi'  ) .OR. iom_use( 'xmtrpice' ) .OR. iom_use( 'ymtrpice' ) .OR. &
768         & iom_use( 'xmtrpsnw' ) .OR. iom_use( 'ymtrpsnw' ) .OR. iom_use( 'xatrp'    ) .OR. iom_use( 'yatrp'    ) ) THEN
769
770         ALLOCATE( zdiag_sig1     (jpi,jpj) , zdiag_sig2     (jpi,jpj) , zdiag_dssh_dx  (jpi,jpj) , zdiag_dssh_dy  (jpi,jpj) ,  &
771            &      zdiag_corstrx  (jpi,jpj) , zdiag_corstry  (jpi,jpj) , zdiag_intstrx  (jpi,jpj) , zdiag_intstry  (jpi,jpj) ,  &
772            &      zdiag_utau_oi  (jpi,jpj) , zdiag_vtau_oi  (jpi,jpj) , zdiag_xmtrp_ice(jpi,jpj) , zdiag_ymtrp_ice(jpi,jpj) ,  &
773            &      zdiag_xmtrp_snw(jpi,jpj) , zdiag_ymtrp_snw(jpi,jpj) , zdiag_xatrp    (jpi,jpj) , zdiag_yatrp    (jpi,jpj) )
774         
775         DO jj = 2, jpjm1
776            DO ji = 2, jpim1
777               rswitch  = MAX( 0._wp , SIGN( 1._wp , at_i(ji,jj) - epsi06 ) ) ! 1 if ice, 0 if no ice
778               
779               ! Stress tensor invariants (normal and shear stress N/m)
780               zdiag_sig1(ji,jj) = ( zs1(ji,jj) + zs2(ji,jj) ) * rswitch                                 ! normal stress
781               zdiag_sig2(ji,jj) = SQRT( ( zs1(ji,jj) - zs2(ji,jj) )**2 + 4*zs12(ji,jj)**2 ) * rswitch   ! shear stress
782               
783               ! Stress terms of the momentum equation (N/m2)
784               zdiag_dssh_dx(ji,jj) = zspgU(ji,jj) * rswitch     ! sea surface slope stress term
785               zdiag_dssh_dy(ji,jj) = zspgV(ji,jj) * rswitch
786               
787               zdiag_corstrx(ji,jj) = zCorx(ji,jj) * rswitch     ! Coriolis stress term
788               zdiag_corstry(ji,jj) = zCory(ji,jj) * rswitch
789               
790               zdiag_intstrx(ji,jj) = zfU(ji,jj)   * rswitch     ! internal stress term
791               zdiag_intstry(ji,jj) = zfV(ji,jj)   * rswitch
792               
793               zdiag_utau_oi(ji,jj) = ztaux_oi(ji,jj) * rswitch  ! oceanic stress
794               zdiag_vtau_oi(ji,jj) = ztauy_oi(ji,jj) * rswitch
795               
796               ! 2D ice mass, snow mass, area transport arrays (X, Y)
797               zfac_x = 0.5 * u_ice(ji,jj) * e2u(ji,jj) * rswitch
798               zfac_y = 0.5 * v_ice(ji,jj) * e1v(ji,jj) * rswitch
799               
800               zdiag_xmtrp_ice(ji,jj) = rhoic * zfac_x * ( vt_i(ji+1,jj) + vt_i(ji,jj) ) ! ice mass transport, X-component
801               zdiag_ymtrp_ice(ji,jj) = rhoic * zfac_y * ( vt_i(ji,jj+1) + vt_i(ji,jj) ) !        ''           Y-   ''
802               
803               zdiag_xmtrp_snw(ji,jj) = rhosn * zfac_x * ( vt_s(ji+1,jj) + vt_s(ji,jj) ) ! snow mass transport, X-component
804               zdiag_ymtrp_snw(ji,jj) = rhosn * zfac_y * ( vt_s(ji,jj+1) + vt_s(ji,jj) ) !          ''          Y-   ''
805               
806               zdiag_xatrp(ji,jj)     = zfac_x * ( at_i(ji+1,jj) + at_i(ji,jj) )         ! area transport,      X-component
807               zdiag_yatrp(ji,jj)     = zfac_y * ( at_i(ji,jj+1) + at_i(ji,jj) )         !        ''            Y-   ''
808               
809            END DO
810         END DO
811         
812         CALL lbc_lnk_multi( zdiag_sig1   , 'T',  1., zdiag_sig2   , 'T',  1.,   &
813            &                zdiag_dssh_dx, 'U', -1., zdiag_dssh_dy, 'V', -1.,   &
814            &                zdiag_corstrx, 'U', -1., zdiag_corstry, 'V', -1.,   & 
815            &                zdiag_intstrx, 'U', -1., zdiag_intstry, 'V', -1.    )
816                 
817         CALL lbc_lnk_multi( zdiag_utau_oi  , 'U', -1., zdiag_vtau_oi  , 'V', -1.,   &
818            &                zdiag_xmtrp_ice, 'U', -1., zdiag_xmtrp_snw, 'U', -1.,   &
819            &                zdiag_xatrp    , 'U', -1., zdiag_ymtrp_ice, 'V', -1.,   &
820            &                zdiag_ymtrp_snw, 'V', -1., zdiag_yatrp    , 'V', -1.    )
821         
822         IF( iom_use('normstr' ) )   CALL iom_put( 'normstr'  ,  zdiag_sig1(:,:)      )   ! Normal stress
823         IF( iom_use('sheastr' ) )   CALL iom_put( 'sheastr'  ,  zdiag_sig2(:,:)      )   ! Shear stress
824         IF( iom_use('dssh_dx' ) )   CALL iom_put( 'dssh_dx'  ,  zdiag_dssh_dx(:,:)   )   ! Sea-surface tilt term in force balance (x)
825         IF( iom_use('dssh_dy' ) )   CALL iom_put( 'dssh_dy'  ,  zdiag_dssh_dy(:,:)   )   ! Sea-surface tilt term in force balance (y)
826         IF( iom_use('corstrx' ) )   CALL iom_put( 'corstrx'  ,  zdiag_corstrx(:,:)   )   ! Coriolis force term in force balance (x)
827         IF( iom_use('corstry' ) )   CALL iom_put( 'corstry'  ,  zdiag_corstry(:,:)   )   ! Coriolis force term in force balance (y)
828         IF( iom_use('intstrx' ) )   CALL iom_put( 'intstrx'  ,  zdiag_intstrx(:,:)   )   ! Internal force term in force balance (x)
829         IF( iom_use('intstry' ) )   CALL iom_put( 'intstry'  ,  zdiag_intstry(:,:)   )   ! Internal force term in force balance (y)
830         IF( iom_use('utau_oi' ) )   CALL iom_put( 'utau_oi'  ,  zdiag_utau_oi(:,:)   )   ! Ocean stress term in force balance (x)
831         IF( iom_use('vtau_oi' ) )   CALL iom_put( 'vtau_oi'  ,  zdiag_vtau_oi(:,:)   )   ! Ocean stress term in force balance (y)
832         IF( iom_use('xmtrpice') )   CALL iom_put( 'xmtrpice' ,  zdiag_xmtrp_ice(:,:) )   ! X-component of sea-ice mass transport (kg/s)
833         IF( iom_use('ymtrpice') )   CALL iom_put( 'ymtrpice' ,  zdiag_ymtrp_ice(:,:) )   ! Y-component of sea-ice mass transport
834         IF( iom_use('xmtrpsnw') )   CALL iom_put( 'xmtrpsnw' ,  zdiag_xmtrp_snw(:,:) )   ! X-component of snow mass transport (kg/s)
835         IF( iom_use('ymtrpsnw') )   CALL iom_put( 'ymtrpsnw' ,  zdiag_ymtrp_snw(:,:) )   ! Y-component of snow mass transport
836         IF( iom_use('xatrp'   ) )   CALL iom_put( 'xatrp'    ,  zdiag_xatrp(:,:)     )   ! X-component of ice area transport
837         IF( iom_use('yatrp'   ) )   CALL iom_put( 'yatrp'    ,  zdiag_yatrp(:,:)     )   ! Y-component of ice area transport
838
839         DEALLOCATE( zdiag_sig1      , zdiag_sig2      , zdiag_dssh_dx   , zdiag_dssh_dy   ,  &
840            &        zdiag_corstrx   , zdiag_corstry   , zdiag_intstrx   , zdiag_intstry   ,  &
841            &        zdiag_utau_oi   , zdiag_vtau_oi   , zdiag_xmtrp_ice , zdiag_ymtrp_ice ,  &
842            &        zdiag_xmtrp_snw , zdiag_ymtrp_snw , zdiag_xatrp     , zdiag_yatrp     )
843
844      ENDIF
845      !
846   END SUBROUTINE ice_dyn_rhg_evp
847
848
849   SUBROUTINE rhg_evp_rst( cdrw, kt )
850      !!---------------------------------------------------------------------
851      !!                   ***  ROUTINE rhg_evp_rst  ***
852      !!                     
853      !! ** Purpose :   Read or write RHG file in restart file
854      !!
855      !! ** Method  :   use of IOM library
856      !!----------------------------------------------------------------------
857      CHARACTER(len=*) , INTENT(in) ::   cdrw   ! "READ"/"WRITE" flag
858      INTEGER, OPTIONAL, INTENT(in) ::   kt     ! ice time-step
859      !
860      INTEGER  ::   iter            ! local integer
861      INTEGER  ::   id1, id2, id3   ! local integers
862      !!----------------------------------------------------------------------
863      !
864      IF( TRIM(cdrw) == 'READ' ) THEN        ! Read/initialize
865         !                                   ! ---------------
866         IF( ln_rstart ) THEN                   !* Read the restart file
867            !
868            id1 = iom_varid( numrir, 'stress1_i' , ldstop = .FALSE. )
869            id2 = iom_varid( numrir, 'stress2_i' , ldstop = .FALSE. )
870            id3 = iom_varid( numrir, 'stress12_i', ldstop = .FALSE. )
871            !
872            IF( MIN( id1, id2, id3 ) > 0 ) THEN      ! fields exist
873               CALL iom_get( numrir, jpdom_autoglo, 'stress1_i' , stress1_i  )
874               CALL iom_get( numrir, jpdom_autoglo, 'stress2_i' , stress2_i  )
875               CALL iom_get( numrir, jpdom_autoglo, 'stress12_i', stress12_i )
876            ELSE                                     ! start rheology from rest
877               IF(lwp) WRITE(numout,*) '   ==>>   previous run without rheology, set stresses to 0'
878               stress1_i (:,:) = 0._wp
879               stress2_i (:,:) = 0._wp
880               stress12_i(:,:) = 0._wp
881            ENDIF
882         ELSE                                   !* Start from rest
883            IF(lwp) WRITE(numout,*) '   ==>>   start from rest: set stresses to 0'
884            stress1_i (:,:) = 0._wp
885            stress2_i (:,:) = 0._wp
886            stress12_i(:,:) = 0._wp
887         ENDIF
888         !
889      ELSEIF( TRIM(cdrw) == 'WRITE' ) THEN   ! Create restart file
890         !                                   ! -------------------
891         IF(lwp) WRITE(numout,*) '---- rhg-rst ----'
892         iter = kt + nn_fsbc - 1             ! ice restarts are written at kt == nitrst - nn_fsbc + 1
893         !
894         CALL iom_rstput( iter, nitrst, numriw, 'stress1_i' , stress1_i  )
895         CALL iom_rstput( iter, nitrst, numriw, 'stress2_i' , stress2_i  )
896         CALL iom_rstput( iter, nitrst, numriw, 'stress12_i', stress12_i )
897         !
898      ENDIF
899      !
900   END SUBROUTINE rhg_evp_rst
901
902#else
903   !!----------------------------------------------------------------------
904   !!   Default option         Empty module           NO ESIM sea-ice model
905   !!----------------------------------------------------------------------
906#endif
907
908   !!==============================================================================
909END MODULE icedyn_rhg_evp
Note: See TracBrowser for help on using the repository browser.