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

source: branches/2016/v3_6_CMIP6_ice_diagnostics/NEMOGCM/NEMO/LIM_SRC_3/limrhg.F90 @ 7517

Last change on this file since 7517 was 7517, checked in by vancop, 7 years ago

more outputs

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