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 @ 7506

Last change on this file since 7506 was 7506, checked in by vancop, 8 years ago

Commit a first set of modifications

  • Property svn:keywords set to Id
File size: 36.1 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     
132      REAL(wp), POINTER, DIMENSION(:,:) ::   zpresh                          ! temporary array for ice strength
133      REAL(wp), POINTER, DIMENSION(:,:) ::   z1_e1t0, z1_e2t0                ! scale factors
134      REAL(wp), POINTER, DIMENSION(:,:) ::   zp_delt                         ! P/delta at T points
135      !
136      REAL(wp), POINTER, DIMENSION(:,:) ::   zaU   , zaV                     ! ice fraction on U/V points
137      REAL(wp), POINTER, DIMENSION(:,:) ::   zmU_t, zmV_t                    ! ice/snow mass/dt on U/V points
138      REAL(wp), POINTER, DIMENSION(:,:) ::   zmf                             ! coriolis parameter at T points
139      REAL(wp), POINTER, DIMENSION(:,:) ::   zTauU_ia , ztauV_ia             ! ice-atm. stress at U-V points
140      REAL(wp), POINTER, DIMENSION(:,:) ::   zspgU , zspgV                   ! surface pressure gradient at U/V points
141      REAL(wp), POINTER, DIMENSION(:,:) ::   v_oceU, u_oceV, v_iceU, u_iceV  ! ocean/ice u/v component on V/U points                           
142      REAL(wp), POINTER, DIMENSION(:,:) ::   zfU   , zfV                     ! internal stresses
143     
144      REAL(wp), POINTER, DIMENSION(:,:) ::   zds                             ! shear
145      REAL(wp), POINTER, DIMENSION(:,:) ::   zs1, zs2, zs12                  ! stress tensor components
146      REAL(wp), POINTER, DIMENSION(:,:) ::   zu_ice, zv_ice, zresr           ! check convergence
147      REAL(wp), POINTER, DIMENSION(:,:) ::   zpice                           ! array used for the calculation of ice surface slope:
148                                                                             !   ocean surface (ssh_m) if ice is not embedded
149                                                                             !   ice top surface if ice is embedded   
150      REAL(wp), POINTER, DIMENSION(:,:) ::   zCor                            ! Coriolis stress array (SIMIP)
151      REAL(wp), POINTER, DIMENSION(:,:) ::   zswitchU, zswitchV              ! dummy arrays
152      REAL(wp), POINTER, DIMENSION(:,:) ::   zmaskU, zmaskV                  ! mask for ice presence
153      REAL(wp), POINTER, DIMENSION(:,:) ::   zfmask, zwf                     ! mask at F points for the ice
154
155      REAL(wp), PARAMETER               ::   zepsi  = 1.0e-20_wp             ! tolerance parameter
156      REAL(wp), PARAMETER               ::   zmmin  = 1._wp                  ! ice mass (kg/m2) below which ice velocity equals ocean velocity
157      REAL(wp), PARAMETER               ::   zshlat = 2._wp                  ! boundary condition for sea-ice velocity (2=no slip ; 0=free slip)
158      !!-------------------------------------------------------------------
159
160      CALL wrk_alloc( jpi,jpj, zpresh, z1_e1t0, z1_e2t0, zp_delt )
161      CALL wrk_alloc( jpi,jpj, zaU, zaV, zmU_t, zmV_t, zmf, zTauU_ia, ztauV_ia )
162      CALL wrk_alloc( jpi,jpj, zspgU, zspgV, v_oceU, u_oceV, v_iceU, u_iceV, zfU, zfV )
163      CALL wrk_alloc( jpi,jpj, zds, zs1, zs2, zs12, zu_ice, zv_ice, zresr, zpice )
164      CALL wrk_alloc( jpi,jpj, zswitchU, zswitchV, zmaskU, zmaskV, zfmask, zwf )
165      CALL wrk_alloc( jpi,jpj, zCor)
166
167#if  defined key_lim2 && ! defined key_lim2_vp
168# if defined key_agrif
169      USE ice_2, vt_s => hsnm
170      USE ice_2, vt_i => hicm
171# else
172      vt_s => hsnm
173      vt_i => hicm
174# endif
175      at_i(:,:) = 1. - frld(:,:)
176#endif
177#if defined key_agrif && defined key_lim2 
178      CALL agrif_rhg_lim2_load      ! First interpolation of coarse values
179#endif
180      !
181      !------------------------------------------------------------------------------!
182      ! 0) mask at F points for the ice (on the whole domain, not only k_j1,k_jpj)
183      !------------------------------------------------------------------------------!
184      ! ocean/land mask
185      DO jj = 1, jpjm1
186         DO ji = 1, jpim1      ! NO vector opt.
187            zfmask(ji,jj) = tmask(ji,jj,1) * tmask(ji+1,jj,1) * tmask(ji,jj+1,1) * tmask(ji+1,jj+1,1)
188         END DO
189      END DO
190      CALL lbc_lnk( zfmask, 'F', 1._wp )
191
192      ! Lateral boundary conditions on velocity (modify zfmask)
193      zwf(:,:) = zfmask(:,:)
194      DO jj = 2, jpjm1
195         DO ji = fs_2, fs_jpim1   ! vector opt.
196            IF( zfmask(ji,jj) == 0._wp ) THEN
197               zfmask(ji,jj) = zshlat * MIN( 1._wp , MAX( zwf(ji+1,jj), zwf(ji,jj+1), zwf(ji-1,jj), zwf(ji,jj-1) ) )
198            ENDIF
199         END DO
200      END DO
201      DO jj = 2, jpjm1
202         IF( zfmask(1,jj) == 0._wp ) THEN
203            zfmask(1  ,jj) = zshlat * MIN( 1._wp , MAX( zwf(2,jj), zwf(1,jj+1), zwf(1,jj-1) ) )
204         ENDIF
205         IF( zfmask(jpi,jj) == 0._wp ) THEN
206            zfmask(jpi,jj) = zshlat * MIN( 1._wp , MAX( zwf(jpi,jj+1), zwf(jpim1,jj), zwf(jpi,jj-1) ) )
207         ENDIF
208      END DO
209      DO ji = 2, jpim1
210         IF( zfmask(ji,1) == 0._wp ) THEN
211            zfmask(ji,1  ) = zshlat * MIN( 1._wp , MAX( zwf(ji+1,1), zwf(ji,2), zwf(ji-1,1) ) )
212         ENDIF
213         IF( zfmask(ji,jpj) == 0._wp ) THEN
214            zfmask(ji,jpj) = zshlat * MIN( 1._wp , MAX( zwf(ji+1,jpj), zwf(ji-1,jpj), zwf(ji,jpjm1) ) )
215         ENDIF
216      END DO
217      CALL lbc_lnk( zfmask, 'F', 1._wp )
218
219      !------------------------------------------------------------------------------!
220      ! 1) define some variables and initialize arrays
221      !------------------------------------------------------------------------------!
222      ! ecc2: square of yield ellipse eccenticrity
223      ecc2    = rn_ecc * rn_ecc
224      z1_ecc2 = 1._wp / ecc2
225
226      ! Time step for subcycling
227      zdtevp   = rdt_ice / REAL( nn_nevp )
228      z1_dtevp = 1._wp / zdtevp
229
230      ! alpha parameters (Bouillon 2009)
231#if defined key_lim3
232      zalph1 = ( 2._wp * rn_relast * rdt_ice ) * z1_dtevp
233#else
234      zalph1 = ( 2._wp * telast ) * z1_dtevp
235#endif
236      zalph2 = zalph1 * z1_ecc2
237
238      z1_alph1 = 1._wp / ( zalph1 + 1._wp )
239      z1_alph2 = 1._wp / ( zalph2 + 1._wp )
240
241      ! Initialise stress tensor
242      zs1 (:,:) = stress1_i (:,:) 
243      zs2 (:,:) = stress2_i (:,:)
244      zs12(:,:) = stress12_i(:,:)
245
246      ! Ice strength
247#if defined key_lim3
248      CALL lim_itd_me_icestrength( nn_icestr )
249      zpresh(:,:) = tmask(:,:,1) *  strength(:,:)
250#else
251      zpresh(:,:) = tmask(:,:,1) *  pstar * vt_i(:,:) * EXP( -c_rhg * (1. - at_i(:,:) ) )
252#endif
253
254      ! scale factors
255      DO jj = k_j1+1, k_jpj-1
256         DO ji = fs_2, fs_jpim1
257            z1_e1t0(ji,jj) = 1._wp / ( e1t(ji+1,jj  ) + e1t(ji,jj  ) )
258            z1_e2t0(ji,jj) = 1._wp / ( e2t(ji  ,jj+1) + e2t(ji,jj  ) )
259         END DO
260      END DO
261           
262      !
263      !------------------------------------------------------------------------------!
264      ! 2) Wind / ocean stress, mass terms, coriolis terms
265      !------------------------------------------------------------------------------!
266
267      IF( nn_ice_embd == 2 ) THEN             !== embedded sea ice: compute representative ice top surface ==!
268         !                                           
269         ! average interpolation coeff as used in dynspg = (1/nn_fsbc) * {SUM[n/nn_fsbc], n=0,nn_fsbc-1}
270         !                                               = (1/nn_fsbc)^2 * {SUM[n], n=0,nn_fsbc-1}
271         zintn = REAL( nn_fsbc - 1 ) / REAL( nn_fsbc ) * 0.5_wp     
272         !
273         ! average interpolation coeff as used in dynspg = (1/nn_fsbc) * {SUM[1-n/nn_fsbc], n=0,nn_fsbc-1}
274         !                                               = (1/nn_fsbc)^2 * (nn_fsbc^2 - {SUM[n], n=0,nn_fsbc-1})
275         zintb = REAL( nn_fsbc + 1 ) / REAL( nn_fsbc ) * 0.5_wp
276         !
277         zpice(:,:) = ssh_m(:,:) + ( zintn * snwice_mass(:,:) + zintb * snwice_mass_b(:,:) ) * r1_rau0
278         !
279      ELSE                                    !== non-embedded sea ice: use ocean surface for slope calculation ==!
280         zpice(:,:) = ssh_m(:,:)
281      ENDIF
282
283      DO jj = k_j1+1, k_jpj-1
284         DO ji = fs_2, fs_jpim1
285
286            ! ice fraction at U-V points
287            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)
288            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)
289
290            ! Ice/snow mass at U-V points
291            zm1 = ( rhosn * vt_s(ji  ,jj  ) + rhoic * vt_i(ji  ,jj  ) )
292            zm2 = ( rhosn * vt_s(ji+1,jj  ) + rhoic * vt_i(ji+1,jj  ) )
293            zm3 = ( rhosn * vt_s(ji  ,jj+1) + rhoic * vt_i(ji  ,jj+1) )
294            zmassU = 0.5_wp * ( zm1 * e12t(ji,jj) + zm2 * e12t(ji+1,jj) ) * r1_e12u(ji,jj) * umask(ji,jj,1)
295            zmassV = 0.5_wp * ( zm1 * e12t(ji,jj) + zm3 * e12t(ji,jj+1) ) * r1_e12v(ji,jj) * vmask(ji,jj,1)
296
297            ! Ocean currents at U-V points
298            v_oceU(ji,jj)   = 0.5_wp * ( ( v_oce(ji  ,jj) + v_oce(ji  ,jj-1) ) * e1t(ji+1,jj)    &
299               &                       + ( v_oce(ji+1,jj) + v_oce(ji+1,jj-1) ) * e1t(ji  ,jj) ) * z1_e1t0(ji,jj) * umask(ji,jj,1)
300           
301            u_oceV(ji,jj)   = 0.5_wp * ( ( u_oce(ji,jj  ) + u_oce(ji-1,jj  ) ) * e2t(ji,jj+1)    &
302               &                       + ( u_oce(ji,jj+1) + u_oce(ji-1,jj+1) ) * e2t(ji,jj  ) ) * z1_e2t0(ji,jj) * vmask(ji,jj,1)
303
304            ! Coriolis at T points (m*f)
305            zmf(ji,jj)      = zm1 * fcor(ji,jj)
306
307            ! m/dt
308            zmU_t(ji,jj)    = zmassU * z1_dtevp
309            zmV_t(ji,jj)    = zmassV * z1_dtevp
310
311            ! Drag ice-atm.
312            zTauU_ia(ji,jj) = zaU(ji,jj) * utau_ice(ji,jj)
313            zTauV_ia(ji,jj) = zaV(ji,jj) * vtau_ice(ji,jj)
314
315            ! Surface pressure gradient (- m*g*GRAD(ssh)) at U-V points
316            zspgU(ji,jj)    = - zmassU * grav * ( zpice(ji+1,jj) - zpice(ji,jj) ) * r1_e1u(ji,jj)
317            zspgV(ji,jj)    = - zmassV * grav * ( zpice(ji,jj+1) - zpice(ji,jj) ) * r1_e2v(ji,jj)
318
319            ! masks
320            zmaskU(ji,jj) = 1._wp - MAX( 0._wp, SIGN( 1._wp, -zmassU ) )  ! 0 if no ice
321            zmaskV(ji,jj) = 1._wp - MAX( 0._wp, SIGN( 1._wp, -zmassV ) )  ! 0 if no ice
322
323            ! switches
324            zswitchU(ji,jj) = MAX( 0._wp, SIGN( 1._wp, zmassU - zmmin ) ) ! 0 if ice mass < zmmin
325            zswitchV(ji,jj) = MAX( 0._wp, SIGN( 1._wp, zmassV - zmmin ) ) ! 0 if ice mass < zmmin
326
327         END DO
328      END DO
329
330      CALL lbc_lnk( zmf, 'T', 1. )
331      !
332      !------------------------------------------------------------------------------!
333      ! 3) Solution of the momentum equation, iterative procedure
334      !------------------------------------------------------------------------------!
335      !
336      !                                               !----------------------!
337      DO jter = 1 , nn_nevp                           !    loop over jter    !
338         !                                            !----------------------!       
339         IF(ln_ctl) THEN   ! Convergence test
340            DO jj = k_j1, k_jpj-1
341               zu_ice(:,jj) = u_ice(:,jj) ! velocity at previous time step
342               zv_ice(:,jj) = v_ice(:,jj)
343            END DO
344         ENDIF
345
346         ! --- divergence, tension & shear (Appendix B of Hunke & Dukowicz, 2002) --- !
347         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
348            DO ji = 1, jpim1
349
350               ! shear at F points
351               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)   &
352                  &         + ( v_ice(ji+1,jj) * r1_e2v(ji+1,jj) - v_ice(ji,jj) * r1_e2v(ji,jj) ) * e2f(ji,jj) * e2f(ji,jj)   &
353                  &         ) * r1_e12f(ji,jj) * zfmask(ji,jj)
354
355            END DO
356         END DO
357         CALL lbc_lnk( zds, 'F', 1. )
358
359         DO jj = k_j1+1, k_jpj-1
360            DO ji = 2, jpim1 ! no vector loop
361
362               ! shear**2 at T points (doc eq. A16)
363               zds2 = ( zds(ji,jj  ) * zds(ji,jj  ) * e12f(ji,jj  ) + zds(ji-1,jj  ) * zds(ji-1,jj  ) * e12f(ji-1,jj  )  &
364                  &   + 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)  &
365                  &   ) * 0.25_wp * r1_e12t(ji,jj)
366             
367               ! divergence at T points
368               zdiv  = ( e2u(ji,jj) * u_ice(ji,jj) - e2u(ji-1,jj) * u_ice(ji-1,jj)   &
369                  &    + e1v(ji,jj) * v_ice(ji,jj) - e1v(ji,jj-1) * v_ice(ji,jj-1)   &
370                  &    ) * r1_e12t(ji,jj)
371               zdiv2 = zdiv * zdiv
372               
373               ! tension at T points
374               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)   &
375                  &   - ( v_ice(ji,jj) * r1_e1v(ji,jj) - v_ice(ji,jj-1) * r1_e1v(ji,jj-1) ) * e1t(ji,jj) * e1t(ji,jj)   &
376                  &   ) * r1_e12t(ji,jj)
377               zdt2 = zdt * zdt
378               
379               ! delta at T points
380               zdelta = SQRT( zdiv2 + ( zdt2 + zds2 ) * usecc2 ) 
381
382               ! P/delta at T points
383               zp_delt(ji,jj) = zpresh(ji,jj) / ( zdelta + rn_creepl )
384               
385               ! stress at T points
386               zs1(ji,jj) = ( zs1(ji,jj) * zalph1 + zp_delt(ji,jj) * ( zdiv - zdelta ) ) * z1_alph1
387               zs2(ji,jj) = ( zs2(ji,jj) * zalph2 + zp_delt(ji,jj) * ( zdt * z1_ecc2 ) ) * z1_alph2
388             
389            END DO
390         END DO
391         CALL lbc_lnk( zp_delt, 'T', 1. )
392
393         DO jj = k_j1, k_jpj-1
394            DO ji = 1, jpim1
395
396               ! P/delta at F points
397               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) )
398               
399               ! stress at F points
400               zs12(ji,jj)= ( zs12(ji,jj) * zalph2 + zp_delf * ( zds(ji,jj) * z1_ecc2 ) * 0.5_wp ) * z1_alph2
401
402            END DO
403         END DO
404         CALL lbc_lnk_multi( zs1, 'T', 1., zs2, 'T', 1., zs12, 'F', 1. )
405 
406         ! --- Ice internal stresses (Appendix C of Hunke and Dukowicz, 2002) --- !
407         DO jj = k_j1+1, k_jpj-1
408            DO ji = fs_2, fs_jpim1               
409
410               ! U points
411               zfU(ji,jj) = 0.5_wp * ( ( zs1(ji+1,jj) - zs1(ji,jj) ) * e2u(ji,jj)                                             &
412                  &                  + ( zs2(ji+1,jj) * e2t(ji+1,jj) * e2t(ji+1,jj) - zs2(ji,jj) * e2t(ji,jj) * e2t(ji,jj)    &
413                  &                    ) * r1_e2u(ji,jj)                                                                      &
414                  &                  + ( zs12(ji,jj) * e1f(ji,jj) * e1f(ji,jj) - zs12(ji,jj-1) * e1f(ji,jj-1) * e1f(ji,jj-1)  &
415                  &                    ) * 2._wp * r1_e1u(ji,jj)                                                              &
416                  &                  ) * r1_e12u(ji,jj)
417
418               ! V points
419               zfV(ji,jj) = 0.5_wp * ( ( zs1(ji,jj+1) - zs1(ji,jj) ) * e1v(ji,jj)                                             &
420                  &                  - ( zs2(ji,jj+1) * e1t(ji,jj+1) * e1t(ji,jj+1) - zs2(ji,jj) * e1t(ji,jj) * e1t(ji,jj)    &
421                  &                    ) * r1_e1v(ji,jj)                                                                      &
422                  &                  + ( zs12(ji,jj) * e2f(ji,jj) * e2f(ji,jj) - zs12(ji-1,jj) * e2f(ji-1,jj) * e2f(ji-1,jj)  &
423                  &                    ) * 2._wp * r1_e2v(ji,jj)                                                              &
424                  &                  ) * r1_e12v(ji,jj)
425
426               ! u_ice at V point
427               u_iceV(ji,jj) = 0.5_wp * ( ( u_ice(ji,jj  ) + u_ice(ji-1,jj  ) ) * e2t(ji,jj+1)     &
428                  &                     + ( u_ice(ji,jj+1) + u_ice(ji-1,jj+1) ) * e2t(ji,jj  ) ) * z1_e2t0(ji,jj) * vmask(ji,jj,1)
429               
430               ! v_ice at U point
431               v_iceU(ji,jj) = 0.5_wp * ( ( v_ice(ji  ,jj) + v_ice(ji  ,jj-1) ) * e1t(ji+1,jj)     &
432                  &                     + ( v_ice(ji+1,jj) + v_ice(ji+1,jj-1) ) * e1t(ji  ,jj) ) * z1_e1t0(ji,jj) * umask(ji,jj,1)
433
434            END DO
435         END DO
436         !
437         ! --- Computation of ice velocity --- !
438         !  Bouillon et al. 2013 (eq 47-48) => unstable unless alpha, beta are chosen wisely and large nn_nevp
439         !  Bouillon et al. 2009 (eq 34-35) => stable
440         IF( MOD(jter,2) .EQ. 0 ) THEN ! even iterations
441           
442            DO jj = k_j1+1, k_jpj-1
443               DO ji = fs_2, fs_jpim1
444
445                  ! tau_io/(v_oce - v_ice)
446                  zTauO = zaV(ji,jj) * rhoco * SQRT( ( v_ice (ji,jj) - v_oce (ji,jj) ) * ( v_ice (ji,jj) - v_oce (ji,jj) )  &
447                     &                             + ( u_iceV(ji,jj) - u_oceV(ji,jj) ) * ( u_iceV(ji,jj) - u_oceV(ji,jj) ) )
448
449                  ! Coriolis at V-points (energy conserving formulation)
450                  zCor(ji,jj)  = - 0.25_wp * r1_e2v(ji,jj) *  &
451                     &    ( zmf(ji,jj  ) * ( e2u(ji,jj  ) * u_ice(ji,jj  ) + e2u(ji-1,jj  ) * u_ice(ji-1,jj  ) )  &
452                     &    + zmf(ji,jj+1) * ( e2u(ji,jj+1) * u_ice(ji,jj+1) + e2u(ji-1,jj+1) * u_ice(ji-1,jj+1) ) )
453
454                  ! Sum of external forces (explicit solution) = F + tau_ia + Coriolis + spg + tau_io
455                  zTauE = zfV(ji,jj) + zTauV_ia(ji,jj) + zCor(ji,jj) + zspgV(ji,jj) + zTauO * ( v_oce(ji,jj) - v_ice(ji,jj) )
456                 
457                  ! ice velocity using implicit formulation (cf Madec doc & Bouillon 2009)
458                  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)
459                     &             ) / MAX( zepsi, zmV_t(ji,jj) + zTauO ) * zswitchV(ji,jj)      &  ! m/dt + tau_io(only ice part)
460                     &             + v_oce(ji,jj) * ( 1._wp - zswitchV(ji,jj) )                  &  ! v_ice = v_oce if mass < zmmin
461                     &           ) * zmaskV(ji,jj)
462               END DO
463            END DO
464            CALL lbc_lnk( v_ice, 'V', -1. )
465
466            ! SIMIP diag
467            IF ( jter .EQ. nn_nevp ) THEN
468               diag_corstry(:,:) = zCor(:,:) 
469            ENDIF
470           
471#if defined key_agrif && defined key_lim2
472            CALL agrif_rhg_lim2( jter, nn_nevp, 'V' )
473#endif
474#if defined key_bdy
475            CALL bdy_ice_lim_dyn( 'V' )
476#endif         
477
478            DO jj = k_j1+1, k_jpj-1
479               DO ji = fs_2, fs_jpim1
480                               
481                  ! tau_io/(u_oce - u_ice)
482                  zTauO = zaU(ji,jj) * rhoco * SQRT( ( u_ice (ji,jj) - u_oce (ji,jj) ) * ( u_ice (ji,jj) - u_oce (ji,jj) )  &
483                     &                             + ( v_iceU(ji,jj) - v_oceU(ji,jj) ) * ( v_iceU(ji,jj) - v_oceU(ji,jj) ) )
484
485                  ! Coriolis at U-points (energy conserving formulation)
486                  zCor(ji,jj)  =   0.25_wp * r1_e1u(ji,jj) *  &
487                     &    ( zmf(ji  ,jj) * ( e1v(ji  ,jj) * v_ice(ji  ,jj) + e1v(ji  ,jj-1) * v_ice(ji  ,jj-1) )  &
488                     &    + zmf(ji+1,jj) * ( e1v(ji+1,jj) * v_ice(ji+1,jj) + e1v(ji+1,jj-1) * v_ice(ji+1,jj-1) ) )
489                 
490                  ! Sum of external forces (explicit solution) = F + tau_ia + Coriolis + spg + tau_io
491                  zTauE = zfU(ji,jj) + zTauU_ia(ji,jj) + zCor(ji,jj) + zspgU(ji,jj) + zTauO * ( u_oce(ji,jj) - u_ice(ji,jj) )
492
493                  ! ice velocity using implicit formulation (cf Madec doc & Bouillon 2009)
494                  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)
495                     &             ) / MAX( zepsi, zmU_t(ji,jj) + zTauO ) * zswitchU(ji,jj)      &  ! m/dt + tau_io(only ice part)
496                     &             + u_oce(ji,jj) * ( 1._wp - zswitchU(ji,jj) )                  &  ! v_ice = v_oce if mass < zmmin
497                     &           ) * zmaskU(ji,jj)
498               END DO
499            END DO
500            CALL lbc_lnk( u_ice, 'U', -1. )
501            IF ( jter .EQ. nn_nevp ) THEN
502               diag_corstrx(:,:) = zCor(:,:) 
503            ENDIF
504           
505#if defined key_agrif && defined key_lim2
506            CALL agrif_rhg_lim2( jter, nn_nevp, 'U' )
507#endif
508#if defined key_bdy
509            CALL bdy_ice_lim_dyn( 'U' )
510#endif         
511
512         ELSE ! odd iterations
513
514            DO jj = k_j1+1, k_jpj-1
515               DO ji = fs_2, fs_jpim1
516                               
517                  ! tau_io/(u_oce - u_ice)
518                  zTauO = zaU(ji,jj) * rhoco * SQRT( ( u_ice (ji,jj) - u_oce (ji,jj) ) * ( u_ice (ji,jj) - u_oce (ji,jj) )  &
519                     &                             + ( v_iceU(ji,jj) - v_oceU(ji,jj) ) * ( v_iceU(ji,jj) - v_oceU(ji,jj) ) )
520
521                  ! Coriolis at U-points (energy conserving formulation)
522                  zCor(ji,jj)  =   0.25_wp * r1_e1u(ji,jj) *  &
523                     &    ( zmf(ji  ,jj) * ( e1v(ji  ,jj) * v_ice(ji  ,jj) + e1v(ji  ,jj-1) * v_ice(ji  ,jj-1) )  &
524                     &    + zmf(ji+1,jj) * ( e1v(ji+1,jj) * v_ice(ji+1,jj) + e1v(ji+1,jj-1) * v_ice(ji+1,jj-1) ) )
525                 
526                  ! Sum of external forces (explicit solution) = F + tau_ia + Coriolis + spg + tau_io
527                  zTauE = zfU(ji,jj) + zTauU_ia(ji,jj) + zCor(ji,jj) + zspgU(ji,jj) + zTauO * ( u_oce(ji,jj) - u_ice(ji,jj) )
528
529                  ! ice velocity using implicit formulation (cf Madec doc & Bouillon 2009)
530                  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)
531                     &             ) / MAX( zepsi, zmU_t(ji,jj) + zTauO ) * zswitchU(ji,jj)      &  ! m/dt + tau_io(only ice part)
532                     &             + u_oce(ji,jj) * ( 1._wp - zswitchU(ji,jj) )                  &  ! v_ice = v_oce if mass < zmmin
533                     &           ) * zmaskU(ji,jj)
534               END DO
535            END DO
536            CALL lbc_lnk( u_ice, 'U', -1. )
537           
538#if defined key_agrif && defined key_lim2
539            CALL agrif_rhg_lim2( jter, nn_nevp, 'U' )
540#endif
541#if defined key_bdy
542            CALL bdy_ice_lim_dyn( 'U' )
543#endif         
544
545           DO jj = k_j1+1, k_jpj-1
546               DO ji = fs_2, fs_jpim1
547
548                  ! tau_io/(v_oce - v_ice)
549                  zTauO = zaV(ji,jj) * rhoco * SQRT( ( v_ice (ji,jj) - v_oce (ji,jj) ) * ( v_ice (ji,jj) - v_oce (ji,jj) )  &
550                     &                             + ( u_iceV(ji,jj) - u_oceV(ji,jj) ) * ( u_iceV(ji,jj) - u_oceV(ji,jj) ) )
551
552                  ! Coriolis at V-points (energy conserving formulation)
553                  zCor(ji,jj)  = - 0.25_wp * r1_e2v(ji,jj) *  &
554                     &    ( zmf(ji,jj  ) * ( e2u(ji,jj  ) * u_ice(ji,jj  ) + e2u(ji-1,jj  ) * u_ice(ji-1,jj  ) )  &
555                     &    + zmf(ji,jj+1) * ( e2u(ji,jj+1) * u_ice(ji,jj+1) + e2u(ji-1,jj+1) * u_ice(ji-1,jj+1) ) )
556
557                  ! Sum of external forces (explicit solution) = F + tau_ia + Coriolis + spg + tau_io
558                  zTauE = zfV(ji,jj) + zTauV_ia(ji,jj) + zCor(ji,jj) + zspgV(ji,jj) + zTauO * ( v_oce(ji,jj) - v_ice(ji,jj) )
559                 
560                  ! ice velocity using implicit formulation (cf Madec doc & Bouillon 2009)
561                  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)
562                     &             ) / MAX( zepsi, zmV_t(ji,jj) + zTauO ) * zswitchV(ji,jj)      &  ! m/dt + tau_io(only ice part)
563                     &             + v_oce(ji,jj) * ( 1._wp - zswitchV(ji,jj) )                  &  ! v_ice = v_oce if mass < zmmin
564                     &           ) * zmaskV(ji,jj)
565               END DO
566            END DO
567            CALL lbc_lnk( v_ice, 'V', -1. )
568           
569#if defined key_agrif && defined key_lim2
570            CALL agrif_rhg_lim2( jter, nn_nevp, 'V' )
571#endif
572#if defined key_bdy
573            CALL bdy_ice_lim_dyn( 'V' )
574#endif         
575
576         ENDIF
577
578         IF(ln_ctl) THEN   ! Convergence test
579            DO jj = k_j1+1, k_jpj-1
580               zresr(:,jj) = MAX( ABS( u_ice(:,jj) - zu_ice(:,jj) ), ABS( v_ice(:,jj) - zv_ice(:,jj) ) )
581            END DO
582            zresm = MAXVAL( zresr( 1:jpi, k_j1+1:k_jpj-1 ) )
583            IF( lk_mpp )   CALL mpp_max( zresm )   ! max over the global domain
584         ENDIF
585         !
586         !                                                ! ==================== !
587      END DO                                              !  end loop over jter  !
588      !                                                   ! ==================== !
589      !
590      !------------------------------------------------------------------------------!
591      ! 4) Recompute delta, shear and div (inputs for mechanical redistribution)
592      !------------------------------------------------------------------------------!
593      DO jj = k_j1, k_jpj-1 
594         DO ji = 1, jpim1
595
596            ! shear at F points
597            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)   &
598               &         + ( v_ice(ji+1,jj) * r1_e2v(ji+1,jj) - v_ice(ji,jj) * r1_e2v(ji,jj) ) * e2f(ji,jj) * e2f(ji,jj)   &
599               &         ) * r1_e12f(ji,jj) * zfmask(ji,jj)
600
601         END DO
602      END DO           
603      CALL lbc_lnk( zds, 'F', 1. )
604     
605      DO jj = k_j1+1, k_jpj-1 
606         DO ji = 2, jpim1 ! no vector loop
607           
608            ! tension**2 at T points
609            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)   &
610               &   - ( v_ice(ji,jj) * r1_e1v(ji,jj) - v_ice(ji,jj-1) * r1_e1v(ji,jj-1) ) * e1t(ji,jj) * e1t(ji,jj)   &
611               &   ) * r1_e12t(ji,jj)
612            zdt2 = zdt * zdt
613           
614            ! shear**2 at T points (doc eq. A16)
615            zds2 = ( zds(ji,jj  ) * zds(ji,jj  ) * e12f(ji,jj  ) + zds(ji-1,jj  ) * zds(ji-1,jj  ) * e12f(ji-1,jj  )  &
616               &   + 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)  &
617               &   ) * 0.25_wp * r1_e12t(ji,jj)
618           
619            ! shear at T points
620            shear_i(ji,jj) = SQRT( zdt2 + zds2 )
621
622            ! divergence at T points
623            divu_i(ji,jj) = ( e2u(ji,jj) * u_ice(ji,jj) - e2u(ji-1,jj) * u_ice(ji-1,jj)   &
624               &            + e1v(ji,jj) * v_ice(ji,jj) - e1v(ji,jj-1) * v_ice(ji,jj-1)   &
625               &            ) * r1_e12t(ji,jj)
626           
627            ! delta at T points
628            zdelta         = SQRT( divu_i(ji,jj) * divu_i(ji,jj) + ( zdt2 + zds2 ) * usecc2 ) 
629            rswitch        = 1._wp - MAX( 0._wp, SIGN( 1._wp, -zdelta ) ) ! 0 if delta=0
630            delta_i(ji,jj) = zdelta + rn_creepl * rswitch
631
632         END DO
633      END DO
634      CALL lbc_lnk_multi( shear_i, 'T', 1., divu_i, 'T', 1., delta_i, 'T', 1. )
635     
636      ! --- Store the stress tensor for the next time step --- !
637      stress1_i (:,:) = zs1 (:,:)
638      stress2_i (:,:) = zs2 (:,:)
639      stress12_i(:,:) = zs12(:,:)
640
641      ! SIMIP diagnostic internal stress
642      diag_dssh_dx(:,:) = zspgU(:,:)
643      diag_dssh_dy(:,:) = zspgV(:,:)
644      CALL lbc_lnk( diag_dssh_dx, 'U', -1. )
645      CALL lbc_lnk( diag_dssh_dy, 'V', -1. )
646
647      diag_intstrx(:,:) = zfU(:,:)
648      diag_intstry(:,:) = zfV(:,:)
649      CALL lbc_lnk( diag_intstrx, 'U', -1. )
650      CALL lbc_lnk( diag_intstry, 'V', -1. )
651
652      !
653      !------------------------------------------------------------------------------!
654      ! 5) Control prints of residual and charge ellipse
655      !------------------------------------------------------------------------------!
656      !
657      ! print the residual for convergence
658      IF(ln_ctl) THEN
659         WRITE(charout,FMT="('lim_rhg  : res =',D23.16, ' iter =',I4)") zresm, jter
660         CALL prt_ctl_info(charout)
661         CALL prt_ctl(tab2d_1=u_ice, clinfo1=' lim_rhg  : u_ice :', tab2d_2=v_ice, clinfo2=' v_ice :')
662      ENDIF
663
664      ! print charge ellipse
665      ! This can be desactivated once the user is sure that the stress state
666      ! lie on the charge ellipse. See Bouillon et al. 08 for more details
667      IF(ln_ctl) THEN
668         CALL prt_ctl_info('lim_rhg  : numit  :',ivar1=numit)
669         CALL prt_ctl_info('lim_rhg  : nwrite :',ivar1=nwrite)
670         CALL prt_ctl_info('lim_rhg  : MOD    :',ivar1=MOD(numit,nwrite))
671         IF( MOD(numit,nwrite) .EQ. 0 ) THEN
672            WRITE(charout,FMT="('lim_rhg  :', I4, I6, I1, I1, A10)") 1000, numit, 0, 0, ' ch. ell. '
673            CALL prt_ctl_info(charout)
674            DO jj = k_j1+1, k_jpj-1
675               DO ji = 2, jpim1
676                  IF (zpresh(ji,jj) > 1.0) THEN
677                     zsig1 = ( zs1(ji,jj) + (zs2(ji,jj)**2 + 4*zs12(ji,jj)**2 )**0.5 ) / ( 2*zpresh(ji,jj) ) 
678                     zsig2 = ( zs1(ji,jj) - (zs2(ji,jj)**2 + 4*zs12(ji,jj)**2 )**0.5 ) / ( 2*zpresh(ji,jj) )
679                     WRITE(charout,FMT="('lim_rhg  :', I4, I4, D23.16, D23.16, D23.16, D23.16, A10)")
680                     CALL prt_ctl_info(charout)
681                  ENDIF
682               END DO
683            END DO
684            WRITE(charout,FMT="('lim_rhg  :', I4, I6, I1, I1, A10)") 2000, numit, 0, 0, ' ch. ell. '
685            CALL prt_ctl_info(charout)
686         ENDIF
687      ENDIF
688      !
689      CALL wrk_dealloc( jpi,jpj, zpresh, z1_e1t0, z1_e2t0, zp_delt )
690      CALL wrk_dealloc( jpi,jpj, zaU, zaV, zmU_t, zmV_t, zmf, zTauU_ia, ztauV_ia )
691      CALL wrk_dealloc( jpi,jpj, zspgU, zspgV, v_oceU, u_oceV, v_iceU, u_iceV, zfU, zfV )
692      CALL wrk_dealloc( jpi,jpj, zds, zs1, zs2, zs12, zu_ice, zv_ice, zresr, zpice )
693      CALL wrk_dealloc( jpi,jpj, zswitchU, zswitchV, zmaskU, zmaskV, zfmask, zwf )
694      CALL wrk_dealloc( jpi,jpj, zCor )
695
696   END SUBROUTINE lim_rhg
697
698#else
699   !!----------------------------------------------------------------------
700   !!   Default option          Dummy module           NO LIM sea-ice model
701   !!----------------------------------------------------------------------
702CONTAINS
703   SUBROUTINE lim_rhg( k1 , k2 )         ! Dummy routine
704      WRITE(*,*) 'lim_rhg: You should not have seen this print! error?', k1, k2
705   END SUBROUTINE lim_rhg
706#endif
707
708   !!==============================================================================
709END MODULE limrhg
Note: See TracBrowser for help on using the repository browser.