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.
limrhg.F90 in branches/2017/dev_r7881_no_wrk_alloc/NEMOGCM/NEMO/LIM_SRC_3 – NEMO

source: branches/2017/dev_r7881_no_wrk_alloc/NEMOGCM/NEMO/LIM_SRC_3/limrhg.F90 @ 7910

Last change on this file since 7910 was 7910, checked in by timgraham, 7 years ago

All wrk_alloc removed

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