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/2016/dev_r6519_HPC_4/NEMOGCM/NEMO/LIM_SRC_3 – NEMO

source: branches/2016/dev_r6519_HPC_4/NEMOGCM/NEMO/LIM_SRC_3/limrhg.F90 @ 7037

Last change on this file since 7037 was 7037, checked in by mocavero, 8 years ago

ORCA2_LIM_PISCES hybrid version update

  • Property svn:keywords set to Id
File size: 37.8 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   !!----------------------------------------------------------------------
13#if defined key_lim3 || (  defined key_lim2 && ! defined key_lim2_vp )
14   !!----------------------------------------------------------------------
15   !!   'key_lim3'               OR                     LIM-3 sea-ice model
16   !!   'key_lim2' AND NOT 'key_lim2_vp'            EVP LIM-2 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#if defined key_lim3
27   USE ice            ! LIM-3: ice variables
28   USE dom_ice        ! LIM-3: ice domain
29   USE limitd_me      ! LIM-3:
30#else
31   USE ice_2          ! LIM-2: ice variables
32   USE dom_ice_2      ! LIM-2: ice domain
33#endif
34   USE lbclnk         ! Lateral Boundary Condition / MPP link
35   USE lib_mpp        ! MPP library
36   USE wrk_nemo       ! work arrays
37   USE in_out_manager ! I/O manager
38   USE prtctl         ! Print control
39   USE lib_fortran    ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined) 
40#if defined key_agrif && defined key_lim2
41   USE agrif_lim2_interp
42#endif
43#if defined key_bdy
44   USE bdyice_lim
45#endif
46
47   IMPLICIT NONE
48   PRIVATE
49
50   PUBLIC   lim_rhg        ! routine called by lim_dyn (or lim_dyn_2)
51
52   !! * Substitutions
53#  include "vectopt_loop_substitute.h90"
54   !!----------------------------------------------------------------------
55   !! NEMO/LIM3 4.0 , UCL - NEMO Consortium (2011)
56   !! $Id$
57   !! Software governed by the CeCILL licence     (NEMOGCM/NEMO_CeCILL.txt)
58   !!----------------------------------------------------------------------
59CONTAINS
60
61   SUBROUTINE lim_rhg( k_j1, k_jpj )
62      !!-------------------------------------------------------------------
63      !!                 ***  SUBROUTINE lim_rhg  ***
64      !!                          EVP-C-grid
65      !!
66      !! ** purpose : determines sea ice drift from wind stress, ice-ocean
67      !!  stress and sea-surface slope. Ice-ice interaction is described by
68      !!  a non-linear elasto-viscous-plastic (EVP) law including shear
69      !!  strength and a bulk rheology (Hunke and Dukowicz, 2002).   
70      !!
71      !!  The points in the C-grid look like this, dear reader
72      !!
73      !!                              (ji,jj)
74      !!                                 |
75      !!                                 |
76      !!                      (ji-1,jj)  |  (ji,jj)
77      !!                             ---------   
78      !!                            |         |
79      !!                            | (ji,jj) |------(ji,jj)
80      !!                            |         |
81      !!                             ---------   
82      !!                     (ji-1,jj-1)     (ji,jj-1)
83      !!
84      !! ** Inputs  : - wind forcing (stress), oceanic currents
85      !!                ice total volume (vt_i) per unit area
86      !!                snow total volume (vt_s) per unit area
87      !!
88      !! ** Action  : - compute u_ice, v_ice : the components of the
89      !!                sea-ice velocity vector
90      !!              - compute delta_i, shear_i, divu_i, which are inputs
91      !!                of the ice thickness distribution
92      !!
93      !! ** Steps   : 1) Compute ice snow mass, ice strength
94      !!              2) Compute wind, oceanic stresses, mass terms and
95      !!                 coriolis terms of the momentum equation
96      !!              3) Solve the momentum equation (iterative procedure)
97      !!              4) Prevent high velocities if the ice is thin
98      !!              5) Recompute invariants of the strain rate tensor
99      !!                 which are inputs of the ITD, store stress
100      !!                 for the next time step
101      !!              6) Control prints of residual (convergence)
102      !!                 and charge ellipse.
103      !!                 The user should make sure that the parameters
104      !!                 nn_nevp, elastic time scale and rn_creepl maintain stress state
105      !!                 on the charge ellipse for plastic flow
106      !!                 e.g. in the Canadian Archipelago
107      !!
108      !! References : Hunke and Dukowicz, JPO97
109      !!              Bouillon et al., Ocean Modelling 2009
110      !!-------------------------------------------------------------------
111      INTEGER, INTENT(in) ::   k_j1    ! southern j-index for ice computation
112      INTEGER, INTENT(in) ::   k_jpj   ! northern j-index for ice computation
113      !!
114      INTEGER ::   ji, jj   ! dummy loop indices
115      INTEGER ::   jter     ! local integers
116      CHARACTER (len=50) ::   charout
117      REAL(wp) ::   zt11, zt12, zt21, zt22, ztagnx, ztagny, delta                         !
118      REAL(wp) ::   za, zstms          ! local scalars
119      REAL(wp) ::   zc1, zc2, zc3      ! ice mass
120
121      REAL(wp) ::   dtevp , z1_dtevp              ! time step for subcycling
122      REAL(wp) ::   dtotel, z1_dtotel, ecc2, ecci ! square of yield ellipse eccenticity
123      REAL(wp) ::   z0, zr, zcca, zccb            ! temporary scalars
124      REAL(wp) ::   zu_ice2, zv_ice1              !
125      REAL(wp) ::   zddc, zdtc                    ! delta on corners and on centre
126      REAL(wp) ::   zdst                          ! shear at the center of the grid point
127      REAL(wp) ::   zdsshx, zdsshy                ! term for the gradient of ocean surface
128      REAL(wp) ::   sigma1, sigma2                ! internal ice stress
129
130      REAL(wp) ::   zresm         ! Maximal error on ice velocity
131      REAL(wp) ::   zintb, zintn  ! dummy argument
132
133      REAL(wp), POINTER, DIMENSION(:,:) ::   zpresh           ! temporary array for ice strength
134      REAL(wp), POINTER, DIMENSION(:,:) ::   zpreshc          ! Ice strength on grid cell corners (zpreshc)
135      REAL(wp), POINTER, DIMENSION(:,:) ::   zfrld1, zfrld2   ! lead fraction on U/V points
136      REAL(wp), POINTER, DIMENSION(:,:) ::   zmass1, zmass2   ! ice/snow mass on U/V points
137      REAL(wp), POINTER, DIMENSION(:,:) ::   zcorl1, zcorl2   ! coriolis parameter on U/V points
138      REAL(wp), POINTER, DIMENSION(:,:) ::   za1ct , za2ct    ! temporary arrays
139      REAL(wp), POINTER, DIMENSION(:,:) ::   v_oce1           ! ocean u/v component on U points                           
140      REAL(wp), POINTER, DIMENSION(:,:) ::   u_oce2           ! ocean u/v component on V points
141      REAL(wp), POINTER, DIMENSION(:,:) ::   u_ice2, v_ice1   ! ice u/v component on V/U point
142      REAL(wp), POINTER, DIMENSION(:,:) ::   zf1   , zf2      ! arrays for internal stresses
143      REAL(wp), POINTER, DIMENSION(:,:) ::   zmask            ! mask ocean grid points
144     
145      REAL(wp), POINTER, DIMENSION(:,:) ::   zdt              ! tension at centre of grid cells
146      REAL(wp), POINTER, DIMENSION(:,:) ::   zds              ! Shear on northeast corner of grid cells
147      REAL(wp), POINTER, DIMENSION(:,:) ::   zs1   , zs2      ! Diagonal stress tensor components zs1 and zs2
148      REAL(wp), POINTER, DIMENSION(:,:) ::   zs12             ! Non-diagonal stress tensor component zs12
149      REAL(wp), POINTER, DIMENSION(:,:) ::   zu_ice, zv_ice, zresr   ! Local error on velocity
150      REAL(wp), POINTER, DIMENSION(:,:) ::   zpice            ! array used for the calculation of ice surface slope:
151                                                              !   ocean surface (ssh_m) if ice is not embedded
152                                                              !   ice top surface if ice is embedded   
153
154      REAL(wp), PARAMETER               ::   zepsi = 1.0e-20_wp ! tolerance parameter
155      REAL(wp), PARAMETER               ::   zvmin = 1.0e-03_wp ! ice volume below which ice velocity equals ocean velocity
156      !!-------------------------------------------------------------------
157
158      CALL wrk_alloc( jpi,jpj, zpresh, zfrld1, zmass1, zcorl1, za1ct , zpreshc, zfrld2, zmass2, zcorl2, za2ct )
159      CALL wrk_alloc( jpi,jpj, u_oce2, u_ice2, v_oce1 , v_ice1 , zmask               )
160      CALL wrk_alloc( jpi,jpj, zf1   , zu_ice, zf2   , zv_ice , zdt    , zds  )
161      CALL wrk_alloc( jpi,jpj, zs1   , zs2   , zs12   , zresr , zpice                 )
162
163#if  defined key_lim2 && ! defined key_lim2_vp
164# if defined key_agrif
165      USE ice_2, vt_s => hsnm
166      USE ice_2, vt_i => hicm
167# else
168      vt_s => hsnm
169      vt_i => hicm
170# endif
171      at_i(:,:) = 1. - frld(:,:)
172#endif
173#if defined key_agrif && defined key_lim2 
174      CALL agrif_rhg_lim2_load      ! First interpolation of coarse values
175#endif
176      !
177      !------------------------------------------------------------------------------!
178      ! 1) Ice strength (zpresh)                                !
179      !------------------------------------------------------------------------------!
180      !
181      ! Put every vector to 0
182
183#if defined key_lim3
184      CALL lim_itd_me_icestrength( nn_icestr )      ! LIM-3: Ice strength on T-points
185#endif
186
187!$OMP PARALLEL
188!$OMP WORKSHARE
189      delta_i(:,:) = 0._wp   ;
190      zpresh (:,:) = 0._wp   ; 
191      zpreshc(:,:) = 0._wp
192      u_ice2 (:,:) = 0._wp   ;   v_ice1(:,:) = 0._wp
193      divu_i (:,:) = 0._wp   ;   zdt   (:,:) = 0._wp   ;   zds(:,:) = 0._wp
194      shear_i(:,:) = 0._wp
195!$OMP END WORKSHARE
196
197!$OMP DO schedule(static) private(jj,ji)
198      DO jj = k_j1 , k_jpj       ! Ice mass and temp variables
199         DO ji = 1 , jpi
200#if defined key_lim3
201            zpresh(ji,jj) = tmask(ji,jj,1) *  strength(ji,jj)
202#endif
203#if defined key_lim2
204            zpresh(ji,jj) = tmask(ji,jj,1) *  pstar * vt_i(ji,jj) * EXP( -c_rhg * (1. - at_i(ji,jj) ) )
205#endif
206            ! zmask = 1 where there is ice or on land
207            zmask(ji,jj)    = 1._wp - ( 1._wp - MAX( 0._wp , SIGN ( 1._wp , vt_i(ji,jj) - zepsi ) ) ) * tmask(ji,jj,1)
208         END DO
209      END DO
210
211      ! Ice strength on grid cell corners (zpreshc)
212      ! needed for calculation of shear stress
213!$OMP DO schedule(static) private(jj,ji,zstms)
214      DO jj = k_j1+1, k_jpj-1
215         DO ji = 2, jpim1 !RB caution no fs_ (ji+1,jj+1)
216            zstms          =  tmask(ji+1,jj+1,1) * wght(ji+1,jj+1,2,2) + tmask(ji,jj+1,1) * wght(ji+1,jj+1,1,2) +   &
217               &              tmask(ji+1,jj,1)   * wght(ji+1,jj+1,2,1) + tmask(ji,jj,1)   * wght(ji+1,jj+1,1,1)
218            zpreshc(ji,jj) = ( zpresh(ji+1,jj+1) * wght(ji+1,jj+1,2,2) + zpresh(ji,jj+1) * wght(ji+1,jj+1,1,2) +   &
219               &               zpresh(ji+1,jj)   * wght(ji+1,jj+1,2,1) + zpresh(ji,jj)   * wght(ji+1,jj+1,1,1)     &
220               &             ) / MAX( zstms, zepsi )
221         END DO
222      END DO
223!$OMP END DO NOWAIT
224!$OMP END PARALLEL
225      CALL lbc_lnk( zpreshc(:,:), 'F', 1. )
226      !
227      !------------------------------------------------------------------------------!
228      ! 2) Wind / ocean stress, mass terms, coriolis terms
229      !------------------------------------------------------------------------------!
230      !
231      !  Wind stress, coriolis and mass terms on the sides of the squares       
232      !  zfrld1: lead fraction on U-points                                     
233      !  zfrld2: lead fraction on V-points                                     
234      !  zmass1: ice/snow mass on U-points                                   
235      !  zmass2: ice/snow mass on V-points                                   
236      !  zcorl1: Coriolis parameter on U-points                             
237      !  zcorl2: Coriolis parameter on V-points                           
238      !  (ztagnx,ztagny): wind stress on U/V points                       
239      !  v_oce1: ocean v component on u points                         
240      !  u_oce2: ocean u component on v points                         
241
242      IF( nn_ice_embd == 2 ) THEN             !== embedded sea ice: compute representative ice top surface ==!
243         !                                           
244         ! average interpolation coeff as used in dynspg = (1/nn_fsbc) * {SUM[n/nn_fsbc], n=0,nn_fsbc-1}
245         !                                               = (1/nn_fsbc)^2 * {SUM[n], n=0,nn_fsbc-1}
246         zintn = REAL( nn_fsbc - 1 ) / REAL( nn_fsbc ) * 0.5_wp     
247         !
248         ! average interpolation coeff as used in dynspg = (1/nn_fsbc) * {SUM[1-n/nn_fsbc], n=0,nn_fsbc-1}
249         !                                               = (1/nn_fsbc)^2 * (nn_fsbc^2 - {SUM[n], n=0,nn_fsbc-1})
250         zintb = REAL( nn_fsbc + 1 ) / REAL( nn_fsbc ) * 0.5_wp
251         !
252!$OMP PARALLEL WORKSHARE
253         zpice(:,:) = ssh_m(:,:) + (  zintn * snwice_mass(:,:) +  zintb * snwice_mass_b(:,:)  ) * r1_rau0
254!$OMP END PARALLEL WORKSHARE
255         !
256      ELSE                                    !== non-embedded sea ice: use ocean surface for slope calculation ==!
257!$OMP PARALLEL WORKSHARE
258         zpice(:,:) = ssh_m(:,:)
259!$OMP END PARALLEL WORKSHARE
260      ENDIF
261
262!$OMP PARALLEL DO schedule(static) private(jj,ji,zc1,zc2,zc3,zt11,zt12,zt21,zt22,ztagnx,ztagny,zdsshx,zdsshy)
263      DO jj = k_j1+1, k_jpj-1
264         DO ji = fs_2, fs_jpim1
265
266            zc1 = tmask(ji  ,jj  ,1) * ( rhosn * vt_s(ji  ,jj  ) + rhoic * vt_i(ji  ,jj  ) )
267            zc2 = tmask(ji+1,jj  ,1) * ( rhosn * vt_s(ji+1,jj  ) + rhoic * vt_i(ji+1,jj  ) )
268            zc3 = tmask(ji  ,jj+1,1) * ( rhosn * vt_s(ji  ,jj+1) + rhoic * vt_i(ji  ,jj+1) )
269
270            zt11 = tmask(ji  ,jj,1) * e1t(ji  ,jj)
271            zt12 = tmask(ji+1,jj,1) * e1t(ji+1,jj)
272            zt21 = tmask(ji,jj  ,1) * e2t(ji,jj  )
273            zt22 = tmask(ji,jj+1,1) * e2t(ji,jj+1)
274
275            ! Leads area.
276            zfrld1(ji,jj) = ( zt12 * ( 1.0 - at_i(ji,jj) ) + zt11 * ( 1.0 - at_i(ji+1,jj) ) ) / ( zt11 + zt12 + zepsi )
277            zfrld2(ji,jj) = ( zt22 * ( 1.0 - at_i(ji,jj) ) + zt21 * ( 1.0 - at_i(ji,jj+1) ) ) / ( zt21 + zt22 + zepsi )
278
279            ! Mass, coriolis coeff. and currents
280            zmass1(ji,jj) = ( zt12 * zc1 + zt11 * zc2 ) / ( zt11 + zt12 + zepsi )
281            zmass2(ji,jj) = ( zt22 * zc1 + zt21 * zc3 ) / ( zt21 + zt22 + zepsi )
282            zcorl1(ji,jj) = zmass1(ji,jj) * ( e1t(ji+1,jj) * fcor(ji,jj) + e1t(ji,jj) * fcor(ji+1,jj) )   &
283               &                          / ( e1t(ji,jj) + e1t(ji+1,jj) + zepsi )
284            zcorl2(ji,jj) = zmass2(ji,jj) * ( e2t(ji,jj+1) * fcor(ji,jj) + e2t(ji,jj) * fcor(ji,jj+1) )   &
285               &                          / ( e2t(ji,jj+1) + e2t(ji,jj) + zepsi )
286            !
287            ! Ocean has no slip boundary condition
288            v_oce1(ji,jj)  = 0.5 * ( ( v_oce(ji  ,jj) + v_oce(ji  ,jj-1) ) * e1t(ji,jj)      &
289               &                   + ( v_oce(ji+1,jj) + v_oce(ji+1,jj-1) ) * e1t(ji+1,jj) )  &
290               &                   / ( e1t(ji+1,jj) + e1t(ji,jj) ) * umask(ji,jj,1) 
291
292            u_oce2(ji,jj)  = 0.5 * ( ( u_oce(ji,jj  ) + u_oce(ji-1,jj  ) ) * e2t(ji,jj)      &
293               &                   + ( u_oce(ji,jj+1) + u_oce(ji-1,jj+1) ) * e2t(ji,jj+1) )  &
294               &                   / ( e2t(ji,jj+1) + e2t(ji,jj) ) * vmask(ji,jj,1)
295
296            ! Wind stress at U,V-point
297            ztagnx = ( 1. - zfrld1(ji,jj) ) * utau_ice(ji,jj)
298            ztagny = ( 1. - zfrld2(ji,jj) ) * vtau_ice(ji,jj)
299
300            ! Computation of the velocity field taking into account the ice internal interaction.
301            ! Terms that are independent of the velocity field.
302
303            ! SB On utilise maintenant le gradient de la pente de l'ocean
304            ! include it later
305
306            zdsshx =  ( zpice(ji+1,jj) - zpice(ji,jj) ) * r1_e1u(ji,jj)
307            zdsshy =  ( zpice(ji,jj+1) - zpice(ji,jj) ) * r1_e2v(ji,jj)
308
309            za1ct(ji,jj) = ztagnx - zmass1(ji,jj) * grav * zdsshx
310            za2ct(ji,jj) = ztagny - zmass2(ji,jj) * grav * zdsshy
311
312         END DO
313      END DO
314
315      !
316      !------------------------------------------------------------------------------!
317      ! 3) Solution of the momentum equation, iterative procedure
318      !------------------------------------------------------------------------------!
319      !
320      ! Time step for subcycling
321      dtevp  = rdt_ice / nn_nevp
322#if defined key_lim3
323      dtotel = dtevp / ( 2._wp * rn_relast * rdt_ice )
324#else
325      dtotel = dtevp / ( 2._wp * telast )
326#endif
327      z1_dtotel = 1._wp / ( 1._wp + dtotel )
328      z1_dtevp  = 1._wp / dtevp
329      !-ecc2: square of yield ellipse eccenticrity (reminder: must become a namelist parameter)
330      ecc2 = rn_ecc * rn_ecc
331      ecci = 1. / ecc2
332
333      !-Initialise stress tensor
334!$OMP PARALLEL WORKSHARE
335      zs1 (:,:) = stress1_i (:,:) 
336      zs2 (:,:) = stress2_i (:,:)
337      zs12(:,:) = stress12_i(:,:)
338!$OMP END PARALLEL WORKSHARE
339
340      !                                               !----------------------!
341      DO jter = 1 , nn_nevp                           !    loop over jter    !
342         !                                            !----------------------!       
343!$OMP PARALLEL
344!$OMP DO schedule(static) private(jj,ji)
345         DO jj = k_j1, k_jpj-1
346            DO ji = 1, jpi
347               zu_ice(ji,jj) = u_ice(ji,jj)    ! velocity at previous time step
348               zv_ice(ji,jj) = v_ice(ji,jj)
349            END DO
350         END DO
351!$OMP END DO NOWAIT
352
353!$OMP DO schedule(static) private(jj,ji)
354         DO jj = k_j1+1, k_jpj-1
355            DO ji = fs_2, fs_jpim1   !RB bug no vect opt due to zmask
356
357               
358               !- Divergence, tension and shear (Section a. Appendix B of Hunke & Dukowicz, 2002)
359               !- divu_i(:,:), zdt(:,:): divergence and tension at centre of grid cells
360               !- zds(:,:): shear on northeast corner of grid cells
361               !
362               !- IMPORTANT REMINDER: Dear Gurvan, note that, the way these terms are coded,
363               !                      there are many repeated calculations.
364               !                      Speed could be improved by regrouping terms. For
365               !                      the moment, however, the stress is on clarity of coding to avoid
366               !                      bugs (Martin, for Miguel).
367               !
368               !- ALSO: arrays zdt, zds and delta could
369               !  be removed in the future to minimise memory demand.
370               !
371               !- MORE NOTES: Note that we are calculating deformation rates and stresses on the corners of
372               !              grid cells, exactly as in the B grid case. For simplicity, the indexation on
373               !              the corners is the same as in the B grid.
374               !
375               !
376               divu_i(ji,jj) = (  e2u(ji,jj) * u_ice(ji,jj) - e2u(ji-1,jj) * u_ice(ji-1,jj)   &
377                  &             + e1v(ji,jj) * v_ice(ji,jj) - e1v(ji,jj-1) * v_ice(ji,jj-1)   &
378                  &            ) * r1_e1e2t(ji,jj)
379
380               zdt(ji,jj) = ( ( u_ice(ji,jj) * r1_e2u(ji,jj) - u_ice(ji-1,jj) * r1_e2u(ji-1,jj) ) * e2t(ji,jj) * e2t(ji,jj)   &
381                  &         - ( v_ice(ji,jj) * r1_e1v(ji,jj) - v_ice(ji,jj-1) * r1_e1v(ji,jj-1) ) * e1t(ji,jj) * e1t(ji,jj)   &
382                  &         ) * r1_e1e2t(ji,jj)
383
384               !
385               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)   &
386                  &         + ( v_ice(ji+1,jj) * r1_e2v(ji+1,jj) - v_ice(ji,jj) * r1_e2v(ji,jj) ) * e2f(ji,jj) * e2f(ji,jj)   &
387                  &         ) * r1_e1e2f(ji,jj) * ( 2._wp - fmask(ji,jj,1) )   &
388                  &         * zmask(ji,jj) * zmask(ji,jj+1) * zmask(ji+1,jj) * zmask(ji+1,jj+1)
389
390
391               v_ice1(ji,jj)  = 0.5_wp * ( ( v_ice(ji  ,jj) + v_ice(ji  ,jj-1) ) * e1t(ji+1,jj)     &
392                  &                      + ( v_ice(ji+1,jj) + v_ice(ji+1,jj-1) ) * e1t(ji  ,jj) )   &
393                  &                      / ( e1t(ji+1,jj) + e1t(ji,jj) ) * umask(ji,jj,1) 
394
395               u_ice2(ji,jj)  = 0.5_wp * ( ( u_ice(ji,jj  ) + u_ice(ji-1,jj  ) ) * e2t(ji,jj+1)     &
396                  &                      + ( u_ice(ji,jj+1) + u_ice(ji-1,jj+1) ) * e2t(ji,jj  ) )   &
397                  &                      / ( e2t(ji,jj+1) + e2t(ji,jj) ) * vmask(ji,jj,1)
398            END DO
399         END DO
400!$OMP END DO NOWAIT
401!$OMP END PARALLEL
402
403         CALL lbc_lnk_multi( v_ice1, 'U', -1., u_ice2, 'V', -1. )      ! lateral boundary cond.
404         
405!$OMP PARALLEL DO schedule(static) private(jj,ji,zdst,delta,zddc,zdtc)
406         DO jj = k_j1+1, k_jpj-1
407            DO ji = fs_2, fs_jpim1
408
409               !- Calculate Delta at centre of grid cells
410               zdst          = ( e2u(ji,jj) * v_ice1(ji,jj) - e2u(ji-1,jj  ) * v_ice1(ji-1,jj  )   &
411                  &            + e1v(ji,jj) * u_ice2(ji,jj) - e1v(ji  ,jj-1) * u_ice2(ji  ,jj-1)   &
412                  &            ) * r1_e1e2t(ji,jj)
413
414               delta          = SQRT( divu_i(ji,jj)**2 + ( zdt(ji,jj)**2 + zdst**2 ) * usecc2 ) 
415               delta_i(ji,jj) = delta + rn_creepl
416
417               !- Calculate Delta on corners
418               zddc  = (  ( v_ice1(ji,jj+1) * r1_e1u(ji,jj+1) - v_ice1(ji,jj) * r1_e1u(ji,jj) ) * e1f(ji,jj) * e1f(ji,jj)  &
419                  &     + ( u_ice2(ji+1,jj) * r1_e2v(ji+1,jj) - u_ice2(ji,jj) * r1_e2v(ji,jj) ) * e2f(ji,jj) * e2f(ji,jj)  &
420                  &    ) * r1_e1e2f(ji,jj)
421
422               zdtc  = (- ( v_ice1(ji,jj+1) * r1_e1u(ji,jj+1) - v_ice1(ji,jj) * r1_e1u(ji,jj) ) * e1f(ji,jj) * e1f(ji,jj)  &
423                  &     + ( u_ice2(ji+1,jj) * r1_e2v(ji+1,jj) - u_ice2(ji,jj) * r1_e2v(ji,jj) ) * e2f(ji,jj) * e2f(ji,jj)  &
424                  &    ) * r1_e1e2f(ji,jj)
425
426               zddc = SQRT( zddc**2 + ( zdtc**2 + zds(ji,jj)**2 ) * usecc2 ) + rn_creepl
427
428               !-Calculate stress tensor components zs1 and zs2 at centre of grid cells (see section 3.5 of CICE user's guide).
429               zs1(ji,jj)  = ( zs1 (ji,jj) + dtotel * ( divu_i(ji,jj) - delta ) / delta_i(ji,jj)   * zpresh(ji,jj)   &
430                  &          ) * z1_dtotel
431               zs2(ji,jj)  = ( zs2 (ji,jj) + dtotel *         ecci * zdt(ji,jj) / delta_i(ji,jj)   * zpresh(ji,jj)   &
432                  &          ) * z1_dtotel
433               !-Calculate stress tensor component zs12 at corners
434               zs12(ji,jj) = ( zs12(ji,jj) + dtotel *         ecci * zds(ji,jj) / ( 2._wp * zddc ) * zpreshc(ji,jj)  &
435                  &          ) * z1_dtotel 
436
437            END DO
438         END DO
439
440         CALL lbc_lnk_multi( zs1 , 'T', 1., zs2, 'T', 1., zs12, 'F', 1. )
441 
442         ! Ice internal stresses (Appendix C of Hunke and Dukowicz, 2002)
443!$OMP PARALLEL DO schedule(static) private(jj,ji)
444         DO jj = k_j1+1, k_jpj-1
445            DO ji = fs_2, fs_jpim1
446               !- contribution of zs1, zs2 and zs12 to zf1
447               zf1(ji,jj) = 0.5 * ( ( zs1(ji+1,jj) - zs1(ji,jj) ) * e2u(ji,jj)  &
448                  &             + ( zs2(ji+1,jj) * e2t(ji+1,jj)**2 - zs2(ji,jj) * e2t(ji,jj)**2 ) * r1_e2u(ji,jj)          &
449                  &             + 2.0 * ( zs12(ji,jj) * e1f(ji,jj)**2 - zs12(ji,jj-1) * e1f(ji,jj-1)**2 ) * r1_e1u(ji,jj)  &
450                  &                ) * r1_e1e2u(ji,jj)
451               ! contribution of zs1, zs2 and zs12 to zf2
452               zf2(ji,jj) = 0.5 * ( ( zs1(ji,jj+1) - zs1(ji,jj) ) * e1v(ji,jj)  &
453                  &             - ( zs2(ji,jj+1) * e1t(ji,jj+1)**2 - zs2(ji,jj) * e1t(ji,jj)**2 ) * r1_e1v(ji,jj)          &
454                  &             + 2.0 * ( zs12(ji,jj) * e2f(ji,jj)**2 - zs12(ji-1,jj) * e2f(ji-1,jj)**2 ) * r1_e2v(ji,jj)  &
455                  &               )  * r1_e1e2v(ji,jj)
456            END DO
457         END DO
458         !
459         ! Computation of ice velocity
460         !
461         ! Both the Coriolis term and the ice-ocean drag are solved semi-implicitly.
462         !
463         IF (MOD(jter,2).eq.0) THEN 
464
465!$OMP PARALLEL DO schedule(static) private(jj,ji,rswitch,z0,zv_ice1,za,zr,zcca,zccb)
466            DO jj = k_j1+1, k_jpj-1
467               DO ji = fs_2, fs_jpim1
468                  rswitch      = ( 1.0 - MAX( 0._wp, SIGN( 1._wp, -zmass1(ji,jj) ) ) ) * umask(ji,jj,1)
469                  z0           = zmass1(ji,jj) * z1_dtevp
470
471                  ! SB modif because ocean has no slip boundary condition
472                  zv_ice1      = 0.5 * ( ( v_ice(ji  ,jj) + v_ice(ji  ,jj-1) ) * e1t(ji  ,jj)     &
473                     &                 + ( v_ice(ji+1,jj) + v_ice(ji+1,jj-1) ) * e1t(ji+1,jj) )   &
474                     &                 / ( e1t(ji+1,jj) + e1t(ji,jj) ) * umask(ji,jj,1)
475                  za           = rhoco * SQRT( ( u_ice(ji,jj) - u_oce(ji,jj) )**2 +  &
476                     &                         ( zv_ice1 - v_oce1(ji,jj) )**2 ) * ( 1.0 - zfrld1(ji,jj) )
477                  zr           = z0 * u_ice(ji,jj) + zf1(ji,jj) + za1ct(ji,jj) + za * u_oce(ji,jj)
478                  zcca         = z0 + za
479                  zccb         = zcorl1(ji,jj)
480                  u_ice(ji,jj) = ( zr + zccb * zv_ice1 ) / ( zcca + zepsi ) * rswitch 
481               END DO
482            END DO
483
484            CALL lbc_lnk( u_ice(:,:), 'U', -1. )
485#if defined key_agrif && defined key_lim2
486            CALL agrif_rhg_lim2( jter, nn_nevp, 'U' )
487#endif
488#if defined key_bdy
489         CALL bdy_ice_lim_dyn( 'U' )
490#endif         
491
492!$OMP PARALLEL DO schedule(static) private(jj,ji,rswitch,z0,zu_ice2,za,zr,zcca,zccb)
493            DO jj = k_j1+1, k_jpj-1
494               DO ji = fs_2, fs_jpim1
495
496                  rswitch      = ( 1.0 - MAX( 0._wp, SIGN( 1._wp, -zmass2(ji,jj) ) ) ) * vmask(ji,jj,1)
497                  z0           = zmass2(ji,jj) * z1_dtevp
498                  ! SB modif because ocean has no slip boundary condition
499                  zu_ice2      = 0.5 * ( ( u_ice(ji,jj  ) + u_ice(ji-1,jj  ) ) * e2t(ji,jj)       &
500                     &                 + ( u_ice(ji,jj+1) + u_ice(ji-1,jj+1) ) * e2t(ji,jj+1) )   &
501                     &                 / ( e2t(ji,jj+1) + e2t(ji,jj) ) * vmask(ji,jj,1)
502                  za           = rhoco * SQRT( ( zu_ice2 - u_oce2(ji,jj) )**2 +  & 
503                     &                         ( v_ice(ji,jj) - v_oce(ji,jj))**2 ) * ( 1.0 - zfrld2(ji,jj) )
504                  zr           = z0 * v_ice(ji,jj) + zf2(ji,jj) + za2ct(ji,jj) + za * v_oce(ji,jj)
505                  zcca         = z0 + za
506                  zccb         = zcorl2(ji,jj)
507                  v_ice(ji,jj) = ( zr - zccb * zu_ice2 ) / ( zcca + zepsi ) * rswitch
508               END DO
509            END DO
510
511            CALL lbc_lnk( v_ice(:,:), 'V', -1. )
512#if defined key_agrif && defined key_lim2
513            CALL agrif_rhg_lim2( jter, nn_nevp, 'V' )
514#endif
515#if defined key_bdy
516         CALL bdy_ice_lim_dyn( 'V' )
517#endif         
518
519         ELSE 
520!$OMP PARALLEL DO schedule(static) private(jj,ji,rswitch,z0,zu_ice2,za,zr,zcca,zccb)
521            DO jj = k_j1+1, k_jpj-1
522               DO ji = fs_2, fs_jpim1
523                  rswitch      = ( 1.0 - MAX( 0._wp, SIGN( 1._wp, -zmass2(ji,jj) ) ) ) * vmask(ji,jj,1)
524                  z0           = zmass2(ji,jj) * z1_dtevp
525                  ! SB modif because ocean has no slip boundary condition
526                  zu_ice2      = 0.5 * ( ( u_ice(ji,jj  ) + u_ice(ji-1,jj  ) ) * e2t(ji,jj)       &
527                     &                  +( u_ice(ji,jj+1) + u_ice(ji-1,jj+1) ) * e2t(ji,jj+1) )   &
528                     &                 / ( e2t(ji,jj+1) + e2t(ji,jj) ) * vmask(ji,jj,1)   
529
530                  za           = rhoco * SQRT( ( zu_ice2 - u_oce2(ji,jj) )**2 +  &
531                     &                         ( v_ice(ji,jj) - v_oce(ji,jj) )**2 ) * ( 1.0 - zfrld2(ji,jj) )
532                  zr           = z0 * v_ice(ji,jj) + zf2(ji,jj) + za2ct(ji,jj) + za * v_oce(ji,jj)
533                  zcca         = z0 + za
534                  zccb         = zcorl2(ji,jj)
535                  v_ice(ji,jj) = ( zr - zccb * zu_ice2 ) / ( zcca + zepsi ) * rswitch
536               END DO
537            END DO
538
539            CALL lbc_lnk( v_ice(:,:), 'V', -1. )
540#if defined key_agrif && defined key_lim2
541            CALL agrif_rhg_lim2( jter, nn_nevp, 'V' )
542#endif
543#if defined key_bdy
544         CALL bdy_ice_lim_dyn( 'V' )
545#endif         
546
547!$OMP PARALLEL DO schedule(static) private(jj,ji,rswitch,z0,zv_ice1,za,zr,zcca,zccb)
548            DO jj = k_j1+1, k_jpj-1
549               DO ji = fs_2, fs_jpim1
550                  rswitch      = ( 1.0 - MAX( 0._wp, SIGN( 1._wp, -zmass1(ji,jj) ) ) ) * umask(ji,jj,1)
551                  z0           = zmass1(ji,jj) * z1_dtevp
552                  zv_ice1      = 0.5 * ( ( v_ice(ji  ,jj) + v_ice(ji  ,jj-1) ) * e1t(ji,jj)       &
553                     &                 + ( v_ice(ji+1,jj) + v_ice(ji+1,jj-1) ) * e1t(ji+1,jj) )   &
554                     &                 / ( e1t(ji+1,jj) + e1t(ji,jj) ) * umask(ji,jj,1)
555
556                  za           = rhoco * SQRT( ( u_ice(ji,jj) - u_oce(ji,jj) )**2 +  &
557                     &                         ( zv_ice1 - v_oce1(ji,jj) )**2 ) * ( 1.0 - zfrld1(ji,jj) )
558                  zr           = z0 * u_ice(ji,jj) + zf1(ji,jj) + za1ct(ji,jj) + za * u_oce(ji,jj)
559                  zcca         = z0 + za
560                  zccb         = zcorl1(ji,jj)
561                  u_ice(ji,jj) = ( zr + zccb * zv_ice1 ) / ( zcca + zepsi ) * rswitch 
562               END DO
563            END DO
564
565            CALL lbc_lnk( u_ice(:,:), 'U', -1. )
566#if defined key_agrif && defined key_lim2
567            CALL agrif_rhg_lim2( jter, nn_nevp, 'U' )
568#endif
569#if defined key_bdy
570         CALL bdy_ice_lim_dyn( 'U' )
571#endif         
572
573         ENDIF
574         
575         IF(ln_ctl) THEN
576            !---  Convergence test.
577            DO jj = k_j1+1 , k_jpj-1
578               zresr(:,jj) = MAX( ABS( u_ice(:,jj) - zu_ice(:,jj) ), ABS( v_ice(:,jj) - zv_ice(:,jj) ) )
579            END DO
580            zresm = MAXVAL( zresr( 1:jpi, k_j1+1:k_jpj-1 ) )
581            IF( lk_mpp )   CALL mpp_max( zresm )   ! max over the global domain
582         ENDIF
583
584         !                                                ! ==================== !
585      END DO                                              !  end loop over jter  !
586      !                                                   ! ==================== !
587      !
588      !------------------------------------------------------------------------------!
589      ! 4) Prevent ice velocities when the ice is thin
590      !------------------------------------------------------------------------------!
591      ! If the ice volume is below zvmin then ice velocity should equal the
592      ! ocean velocity. This prevents high velocity when ice is thin
593!$OMP PARALLEL DO schedule(static) private(jj,ji)
594      DO jj = k_j1+1, k_jpj-1
595         DO ji = fs_2, fs_jpim1
596            IF ( vt_i(ji,jj) <= zvmin ) THEN
597               u_ice(ji,jj) = u_oce(ji,jj)
598               v_ice(ji,jj) = v_oce(ji,jj)
599            ENDIF
600         END DO
601      END DO
602
603      CALL lbc_lnk_multi( u_ice(:,:), 'U', -1., v_ice(:,:), 'V', -1. )
604
605#if defined key_agrif && defined key_lim2
606      CALL agrif_rhg_lim2( nn_nevp , nn_nevp, 'U' )
607      CALL agrif_rhg_lim2( nn_nevp , nn_nevp, 'V' )
608#endif
609#if defined key_bdy
610      CALL bdy_ice_lim_dyn( 'U' )
611      CALL bdy_ice_lim_dyn( 'V' )
612#endif         
613
614!$OMP PARALLEL DO schedule(static) private(jj,ji)
615      DO jj = k_j1+1, k_jpj-1 
616         DO ji = fs_2, fs_jpim1
617            IF ( vt_i(ji,jj) <= zvmin ) THEN
618               v_ice1(ji,jj)  = 0.5_wp * ( ( v_ice(ji  ,jj) + v_ice(ji,  jj-1) ) * e1t(ji+1,jj)     &
619                  &                      + ( v_ice(ji+1,jj) + v_ice(ji+1,jj-1) ) * e1t(ji  ,jj) )   &
620                  &                      / ( e1t(ji+1,jj) + e1t(ji,jj) ) * umask(ji,jj,1)
621
622               u_ice2(ji,jj)  = 0.5_wp * ( ( u_ice(ji,jj  ) + u_ice(ji-1,jj  ) ) * e2t(ji,jj+1)     &
623                  &                      + ( u_ice(ji,jj+1) + u_ice(ji-1,jj+1) ) * e2t(ji,jj  ) )   &
624                  &                      / ( e2t(ji,jj+1) + e2t(ji,jj) ) * vmask(ji,jj,1)
625            ENDIF
626         END DO
627      END DO
628
629      CALL lbc_lnk_multi( u_ice2(:,:), 'V', -1., v_ice1(:,:), 'U', -1. )
630
631      ! Recompute delta, shear and div, inputs for mechanical redistribution
632!$OMP PARALLEL
633!$OMP DO schedule(static) private(jj,ji,zdst,delta)
634      DO jj = k_j1+1, k_jpj-1
635         DO ji = fs_2, jpim1   !RB bug no vect opt due to zmask
636            !- divu_i(:,:), zdt(:,:): divergence and tension at centre
637            !- zds(:,:): shear on northeast corner of grid cells
638            IF ( vt_i(ji,jj) <= zvmin ) THEN
639
640               divu_i(ji,jj) = (  e2u(ji,jj) * u_ice(ji,jj) - e2u(ji-1,jj  ) * u_ice(ji-1,jj  )   &
641                  &             + e1v(ji,jj) * v_ice(ji,jj) - e1v(ji  ,jj-1) * v_ice(ji  ,jj-1)   &
642                  &            ) * r1_e1e2t(ji,jj)
643
644               zdt(ji,jj) = ( ( u_ice(ji,jj) * r1_e2u(ji,jj) - u_ice(ji-1,jj) * r1_e2u(ji-1,jj) ) * e2t(ji,jj) * e2t(ji,jj)  &
645                  &          -( v_ice(ji,jj) * r1_e1v(ji,jj) - v_ice(ji,jj-1) * r1_e1v(ji,jj-1) ) * e1t(ji,jj) * e1t(ji,jj)  &
646                  &         ) * r1_e1e2t(ji,jj)
647               !
648               ! SB modif because ocean has no slip boundary condition
649               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)  &
650                  &          +( v_ice(ji+1,jj) * r1_e2v(ji+1,jj) - v_ice(ji,jj) * r1_e2v(ji,jj) ) * e2f(ji,jj) * e2f(ji,jj)  &
651                  &         ) * r1_e1e2f(ji,jj) * ( 2.0 - fmask(ji,jj,1) )                                     &
652                  &         * zmask(ji,jj) * zmask(ji,jj+1) * zmask(ji+1,jj) * zmask(ji+1,jj+1)
653
654               zdst = ( e2u(ji,jj) * v_ice1(ji,jj) - e2u(ji-1,jj  ) * v_ice1(ji-1,jj  )    &
655                  &   + e1v(ji,jj) * u_ice2(ji,jj) - e1v(ji  ,jj-1) * u_ice2(ji  ,jj-1) ) * r1_e1e2t(ji,jj)
656
657               delta = SQRT( divu_i(ji,jj)**2 + ( zdt(ji,jj)**2 + zdst**2 ) * usecc2 ) 
658               delta_i(ji,jj) = delta + rn_creepl
659           
660            ENDIF
661         END DO
662      END DO
663      !
664      !------------------------------------------------------------------------------!
665      ! 5) Store stress tensor and its invariants
666      !------------------------------------------------------------------------------!
667      ! * Invariants of the stress tensor are required for limitd_me
668      !   (accelerates convergence and improves stability)
669!$OMP DO schedule(static) private(jj,ji,zdst)
670      DO jj = k_j1+1, k_jpj-1
671         DO ji = fs_2, fs_jpim1
672            zdst           = (  e2u(ji,jj) * v_ice1(ji,jj) - e2u( ji-1, jj   ) * v_ice1(ji-1,jj)  &   
673               &              + e1v(ji,jj) * u_ice2(ji,jj) - e1v( ji  , jj-1 ) * u_ice2(ji,jj-1) ) * r1_e1e2t(ji,jj) 
674            shear_i(ji,jj) = SQRT( zdt(ji,jj) * zdt(ji,jj) + zdst * zdst )
675         END DO
676      END DO
677!$OMP END DO NOWAIT
678      ! * Store the stress tensor for the next time step
679!$OMP WORKSHARE
680      stress1_i (:,:) = zs1 (:,:)
681      stress2_i (:,:) = zs2 (:,:)
682      stress12_i(:,:) = zs12(:,:)
683!$OMP END WORKSHARE NOWAIT
684!$OMP END PARALLEL
685      ! Lateral boundary condition
686      CALL lbc_lnk_multi( divu_i (:,:), 'T', 1., delta_i(:,:), 'T', 1.,  shear_i(:,:), 'T', 1. )
687
688      !
689      !------------------------------------------------------------------------------!
690      ! 6) Control prints of residual and charge ellipse
691      !------------------------------------------------------------------------------!
692      !
693      ! print the residual for convergence
694      IF(ln_ctl) THEN
695         WRITE(charout,FMT="('lim_rhg  : res =',D23.16, ' iter =',I4)") zresm, jter
696         CALL prt_ctl_info(charout)
697         CALL prt_ctl(tab2d_1=u_ice, clinfo1=' lim_rhg  : u_ice :', tab2d_2=v_ice, clinfo2=' v_ice :')
698      ENDIF
699
700      ! print charge ellipse
701      ! This can be desactivated once the user is sure that the stress state
702      ! lie on the charge ellipse. See Bouillon et al. 08 for more details
703      IF(ln_ctl) THEN
704         CALL prt_ctl_info('lim_rhg  : numit  :',ivar1=numit)
705         CALL prt_ctl_info('lim_rhg  : nwrite :',ivar1=nwrite)
706         CALL prt_ctl_info('lim_rhg  : MOD    :',ivar1=MOD(numit,nwrite))
707         IF( MOD(numit,nwrite) .EQ. 0 ) THEN
708            WRITE(charout,FMT="('lim_rhg  :', I4, I6, I1, I1, A10)") 1000, numit, 0, 0, ' ch. ell. '
709            CALL prt_ctl_info(charout)
710            DO jj = k_j1+1, k_jpj-1
711               DO ji = 2, jpim1
712                  IF (zpresh(ji,jj) > 1.0) THEN
713                     sigma1 = ( zs1(ji,jj) + (zs2(ji,jj)**2 + 4*zs12(ji,jj)**2 )**0.5 ) / ( 2*zpresh(ji,jj) ) 
714                     sigma2 = ( zs1(ji,jj) - (zs2(ji,jj)**2 + 4*zs12(ji,jj)**2 )**0.5 ) / ( 2*zpresh(ji,jj) )
715                     WRITE(charout,FMT="('lim_rhg  :', I4, I4, D23.16, D23.16, D23.16, D23.16, A10)")
716                     CALL prt_ctl_info(charout)
717                  ENDIF
718               END DO
719            END DO
720            WRITE(charout,FMT="('lim_rhg  :', I4, I6, I1, I1, A10)") 2000, numit, 0, 0, ' ch. ell. '
721            CALL prt_ctl_info(charout)
722         ENDIF
723      ENDIF
724      !
725      CALL wrk_dealloc( jpi,jpj, zpresh, zfrld1, zmass1, zcorl1, za1ct , zpreshc, zfrld2, zmass2, zcorl2, za2ct )
726      CALL wrk_dealloc( jpi,jpj, u_oce2, u_ice2, v_oce1 , v_ice1 , zmask               )
727      CALL wrk_dealloc( jpi,jpj, zf1   , zu_ice, zf2   , zv_ice , zdt    , zds  )
728      CALL wrk_dealloc( jpi,jpj, zs1   , zs2   , zs12   , zresr , zpice                 )
729
730   END SUBROUTINE lim_rhg
731
732#else
733   !!----------------------------------------------------------------------
734   !!   Default option          Dummy module           NO LIM sea-ice model
735   !!----------------------------------------------------------------------
736CONTAINS
737   SUBROUTINE lim_rhg( k1 , k2 )         ! Dummy routine
738      WRITE(*,*) 'lim_rhg: You should not have seen this print! error?', k1, k2
739   END SUBROUTINE lim_rhg
740#endif
741
742   !!==============================================================================
743END MODULE limrhg
Note: See TracBrowser for help on using the repository browser.