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.
limdyn_2.F90 in branches/2016/dev_r6519_HPC_4/NEMOGCM/NEMO/LIM_SRC_2 – NEMO

source: branches/2016/dev_r6519_HPC_4/NEMOGCM/NEMO/LIM_SRC_2/limdyn_2.F90 @ 7512

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

changes on code duplication and workshare construct

  • Property svn:keywords set to Id
File size: 15.3 KB
Line 
1MODULE limdyn_2
2   !!======================================================================
3   !!                     ***  MODULE  limdyn_2  ***
4   !!   Sea-Ice dynamics : 
5   !!======================================================================
6   !! History :  1.0  ! 2001-04  (LIM)  Original code
7   !!            2.0  ! 2002-08  (C. Ethe, G. Madec)  F90, mpp
8   !!            2.0  ! 2003-08  (C. Ethe) add lim_dyn_init
9   !!            2.0  ! 2006-07  (G. Madec)  Surface module
10   !!            3.3  ! 2009-05 (G. Garric, C. Bricaud) addition of the lim2_evp case
11   !!---------------------------------------------------------------------
12#if defined key_lim2
13   !!----------------------------------------------------------------------
14   !!   'key_lim2' :                                  LIM 2.0 sea-ice model
15   !!----------------------------------------------------------------------
16   !!    lim_dyn_2      : computes ice velocities
17   !!    lim_dyn_init_2 : initialization and namelist read
18   !!----------------------------------------------------------------------
19   USE dom_oce          ! ocean space and time domain
20   USE sbc_oce          ! ocean surface boundary condition
21   USE phycst           ! physical constant
22   USE ice_2            ! LIM-2: ice variables
23   USE sbc_ice          ! Surface boundary condition: sea-ice fields
24   USE dom_ice_2        ! LIM-2: ice domain
25   USE limistate_2      ! LIM-2: initial state
26   USE limrhg_2         ! LIM-2: VP  ice rheology
27   USE limrhg           ! LIM  : EVP ice rheology
28   USE lbclnk           ! lateral boundary condition - MPP link
29   USE lib_mpp          ! MPP library
30   USE wrk_nemo         ! work arrays
31   USE in_out_manager   ! I/O manager
32   USE prtctl           ! Print control
33   USE lib_fortran      ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined) 
34
35   IMPLICIT NONE
36   PRIVATE
37
38   PUBLIC   lim_dyn_2   ! routine called by sbc_ice_lim
39
40   !! * Substitutions
41#  include "vectopt_loop_substitute.h90"
42   !!----------------------------------------------------------------------
43   !! NEMO/LIM2 3.3 , UCL - NEMO Consortium (2010)
44   !! $Id$
45   !! Software governed by the CeCILL licence     (NEMOGCM/NEMO_CeCILL.txt)
46   !!----------------------------------------------------------------------
47CONTAINS
48
49   SUBROUTINE lim_dyn_2( kt )
50      !!-------------------------------------------------------------------
51      !!               ***  ROUTINE lim_dyn_2  ***
52      !!               
53      !! ** Purpose :   compute ice velocity and ocean-ice friction velocity
54      !!               
55      !! ** Method  :
56      !!
57      !! ** Action  : - Initialisation
58      !!              - Call of the dynamic routine for each hemisphere
59      !!              - computation of the friction velocity at the sea-ice base
60      !!              - treatment of the case if no ice dynamic
61      !!---------------------------------------------------------------------
62      INTEGER, INTENT(in) ::   kt     ! number of iteration
63      !!
64      INTEGER  ::   ji, jj             ! dummy loop indices
65      INTEGER  ::   i_j1, i_jpj        ! Starting/ending j-indices for rheology
66      REAL(wp) ::   zcoef              ! temporary scalar
67      REAL(wp), POINTER, DIMENSION(:  ) ::   zind           ! i-averaged indicator of sea-ice
68      REAL(wp), POINTER, DIMENSION(:  ) ::   zmsk           ! i-averaged of tmask
69      REAL(wp), POINTER, DIMENSION(:,:) ::   zu_io, zv_io   ! ice-ocean velocity
70      !!---------------------------------------------------------------------
71
72      CALL wrk_alloc( jpi, jpj, zu_io, zv_io )
73      CALL wrk_alloc(      jpj, zind , zmsk  )
74
75      IF( kt == nit000 )   CALL lim_dyn_init_2   ! Initialization (first time-step only)
76     
77      IF( ln_limdyn ) THEN
78         !
79         ! Mean ice and snow thicknesses.         
80!$OMP PARALLEL DO schedule(static) private(jj, ji)
81      DO jj = 1, jpj
82         DO ji = 1, jpi
83            hsnm(ji,jj)  = ( 1.0 - frld(ji,jj) ) * hsnif(ji,jj)
84            hicm(ji,jj)  = ( 1.0 - frld(ji,jj) ) * hicif(ji,jj)
85         END DO
86      END DO
87         !
88         !                                     ! Rheology (ice dynamics)
89         !                                     ! ========
90         
91         !  Define the j-limits where ice rheology is computed
92         ! ---------------------------------------------------
93         
94         IF( lk_mpp .OR. lk_mpp_rep ) THEN                    ! mpp: compute over the whole domain
95            i_j1 = 1   
96            i_jpj = jpj
97            IF(ln_ctl)   CALL prt_ctl_info( 'lim_dyn  :    i_j1 = ', ivar1=i_j1, clinfo2=' ij_jpj = ', ivar2=i_jpj )
98            IF( lk_lim2_vp )   THEN   ;   CALL lim_rhg_2( i_j1, i_jpj )             !  VP rheology
99            ELSE                      ;   CALL lim_rhg  ( i_j1, i_jpj )             ! EVP rheology
100            ENDIF
101            !
102         ELSE                                 ! optimization of the computational area
103            !
104            DO jj = 1, jpj
105               zind(jj) = SUM( frld (:,jj  ) )   ! = REAL(jpj) if ocean everywhere on a j-line
106               zmsk(jj) = SUM( tmask(:,jj,1) )   ! = 0         if land  everywhere on a j-line
107            END DO
108            !
109            IF( l_jeq ) THEN                     ! local domain include both hemisphere
110               !                                 ! Rheology is computed in each hemisphere
111               !                                 ! only over the ice cover latitude strip
112               ! Northern hemisphere
113               i_j1  = njeq
114               i_jpj = jpj
115               DO WHILE ( i_j1 <= jpj .AND. zind(i_j1) == FLOAT(jpi) .AND. zmsk(i_j1) /=0 )
116                  i_j1 = i_j1 + 1
117               END DO
118               IF( lk_lim2_vp )   THEN             ! VP  rheology
119                  i_j1 = MAX( 1, i_j1-1 )
120                  CALL lim_rhg_2( i_j1, i_jpj )
121               ELSE                                ! EVP rheology
122                  i_j1 = MAX( 1, i_j1-2 )
123                  CALL lim_rhg( i_j1, i_jpj )
124               ENDIF
125               IF(ln_ctl)   WRITE(numout,*) 'lim_dyn : NH i_j1 = ', i_j1, 'ij_jpj = ', i_jpj
126               !
127               ! Southern hemisphere
128               i_j1  =  1 
129               i_jpj = njeq
130               DO WHILE ( i_jpj >= 1 .AND. zind(i_jpj) == FLOAT(jpi) .AND. zmsk(i_jpj) /=0 )
131                  i_jpj = i_jpj - 1
132               END DO
133               IF( lk_lim2_vp )   THEN             ! VP  rheology
134                  i_jpj = MIN( jpj, i_jpj+2 )
135                  CALL lim_rhg_2( i_j1, i_jpj )
136               ELSE                                ! EVP rheology
137                  i_jpj = MIN( jpj, i_jpj+1 )
138                  CALL lim_rhg( i_j1, i_jpj )
139               ENDIF
140               IF(ln_ctl)   WRITE(numout,*) 'lim_dyn : SH i_j1 = ', i_j1, 'ij_jpj = ', i_jpj
141               !
142            ELSE                                 ! local domain extends over one hemisphere only
143               !                                 ! Rheology is computed only over the ice cover
144               !                                 ! latitude strip
145               i_j1  = 1
146               DO WHILE ( i_j1 <= jpj .AND. zind(i_j1) == FLOAT(jpi) .AND. zmsk(i_j1) /=0 )
147                  i_j1 = i_j1 + 1
148               END DO
149               i_j1 = MAX( 1, i_j1-1 )
150   
151               i_jpj  = jpj
152               DO WHILE ( i_jpj >= 1  .AND. zind(i_jpj) == FLOAT(jpi) .AND. zmsk(i_jpj) /=0 )
153                  i_jpj = i_jpj - 1
154               END DO
155               i_jpj = MIN( jpj, i_jpj+2 )
156               !
157               IF( lk_lim2_vp )   THEN             ! VP  rheology
158                  i_jpj = MIN( jpj, i_jpj+2 )
159                  CALL lim_rhg_2( i_j1, i_jpj )                !  VP rheology
160               ELSE                                ! EVP rheology
161                  i_j1  = MAX( 1  , i_j1-2  )
162                  i_jpj = MIN( jpj, i_jpj+1 )
163                  CALL lim_rhg  ( i_j1, i_jpj )                ! EVP rheology
164               ENDIF
165               IF(ln_ctl)   WRITE(numout,*) 'lim_dyn : one hemisphere: i_j1 = ', i_j1, ' ij_jpj = ', i_jpj
166               !
167            ENDIF
168            !
169         ENDIF
170
171         IF(ln_ctl)   CALL prt_ctl(tab2d_1=u_ice , clinfo1=' lim_dyn  : u_ice :', tab2d_2=v_ice , clinfo2=' v_ice :')
172         
173         ! computation of friction velocity
174         ! --------------------------------
175         SELECT CASE( cp_ice_msh )           ! ice-ocean relative velocity at u- & v-pts
176         CASE( 'C' )                               ! EVP : C-grid ice dynamics
177!$OMP PARALLEL DO schedule(static) private(jj, ji)
178            DO jj = 1, jpj
179               DO ji = 1, jpi
180                  zu_io(ji,jj) = u_ice(ji,jj) - ssu_m(ji,jj)           ! ice-ocean & ice velocity at ocean velocity points
181                  zv_io(ji,jj) = v_ice(ji,jj) - ssv_m(ji,jj)
182               END DO
183            END DO
184         CASE( 'I' )                               ! VP  : B-grid ice dynamics (I-point)
185!$OMP PARALLEL DO schedule(static) private(jj, ji)
186            DO jj = 1, jpjm1                               ! u_ice v_ice at I-point ; ssu_m, ssv_m at U- & V-points
187               DO ji = 1, jpim1   ! NO vector opt.         !
188                  zu_io(ji,jj) = 0.5_wp * ( u_ice(ji+1,jj+1) + u_ice(ji+1,jj  ) ) - ssu_m(ji,jj)
189                  zv_io(ji,jj) = 0.5_wp * ( v_ice(ji+1,jj+1) + v_ice(ji  ,jj+1) ) - ssv_m(ji,jj)
190               END DO
191            END DO
192         END SELECT
193
194         ! frictional velocity at T-point
195         zcoef = 0.5_wp * cw
196!$OMP PARALLEL DO schedule(static) private(jj, ji)
197         DO jj = 2, jpjm1
198            DO ji = 2, jpim1   ! NO vector opt. because of zu_io
199               ust2s(ji,jj) = zcoef * (  zu_io(ji,jj) * zu_io(ji,jj) + zu_io(ji-1,jj) * zu_io(ji-1,jj)   &
200                  &                    + zv_io(ji,jj) * zv_io(ji,jj) + zv_io(ji,jj-1) * zv_io(ji,jj-1)   ) * tms(ji,jj)
201            END DO
202         END DO
203         !
204      ELSE      ! no ice dynamics : transmit directly the atmospheric stress to the ocean
205         !
206         zcoef = SQRT( 0.5 ) / rau0
207!$OMP PARALLEL DO schedule(static) private(jj, ji)
208         DO jj = 2, jpjm1
209            DO ji = fs_2, fs_jpim1   ! vector opt.
210               ust2s(ji,jj) = zcoef * SQRT(  utau(ji,jj) * utau(ji,jj) + utau(ji-1,jj) * utau(ji-1,jj)   &
211                  &                        + vtau(ji,jj) * vtau(ji,jj) + vtau(ji,jj-1) * vtau(ji,jj-1)   ) * tms(ji,jj)
212            END DO
213         END DO
214         !
215      ENDIF
216      !
217      CALL lbc_lnk( ust2s, 'T',  1. )   ! T-point
218      !
219      IF(ln_ctl)   CALL prt_ctl(tab2d_1=ust2s , clinfo1=' lim_dyn  : ust2s :')
220      !
221      CALL wrk_dealloc( jpi, jpj, zu_io, zv_io )
222      CALL wrk_dealloc(      jpj, zind , zmsk  )
223      !
224   END SUBROUTINE lim_dyn_2
225
226
227   SUBROUTINE lim_dyn_init_2
228      !!-------------------------------------------------------------------
229      !!                  ***  ROUTINE lim_dyn_init_2  ***
230      !!
231      !! ** Purpose :   Physical constants and parameters linked to the ice
232      !!              dynamics
233      !!
234      !! ** Method  :   Read the namicedyn namelist and check the ice-dynamic
235      !!              parameter values
236      !!
237      !! ** input   :   Namelist namicedyn
238      !!-------------------------------------------------------------------
239      INTEGER  ::   ios                 ! Local integer output status for namelist read
240      INTEGER  ::   ji, jj             ! dummy loop indices
241      NAMELIST/namicedyn/ epsd, alpha,     &
242         &                dm, nbiter, nbitdr, om, resl, cw, angvg, pstar,   &
243         &                c_rhg, etamn, rn_creepl, rn_ecc, ahi0,                  &
244         &                nn_nevp, telast, alphaevp
245      !!-------------------------------------------------------------------
246                   
247      REWIND( numnam_ice_ref )              ! Namelist namicedyn in reference namelist : Ice dynamics
248      READ  ( numnam_ice_ref, namicedyn, IOSTAT = ios, ERR = 901)
249901   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namicedyn in reference namelist', lwp )
250
251      REWIND( numnam_ice_cfg )              ! Namelist namicedyn in configuration namelist : Ice dynamics
252      READ  ( numnam_ice_cfg, namicedyn, IOSTAT = ios, ERR = 902 )
253902   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namicedyn in configuration namelist', lwp )
254      IF(lwm) WRITE ( numoni, namicedyn )
255
256      IF(lwp) THEN                                ! Control print
257         WRITE(numout,*)
258         WRITE(numout,*) 'lim_dyn_init_2: ice parameters for ice dynamics '
259         WRITE(numout,*) '~~~~~~~~~~~~~~'
260         WRITE(numout,*) '       tolerance parameter                              epsd   = ', epsd
261         WRITE(numout,*) '       coefficient for semi-implicit coriolis           alpha  = ', alpha
262         WRITE(numout,*) '       diffusion constant for dynamics                  dm     = ', dm
263         WRITE(numout,*) '       number of sub-time steps for relaxation          nbiter = ', nbiter
264         WRITE(numout,*) '       maximum number of iterations for relaxation      nbitdr = ', nbitdr
265         WRITE(numout,*) '       relaxation constant                              om     = ', om
266         WRITE(numout,*) '       maximum value for the residual of relaxation     resl   = ', resl
267         WRITE(numout,*) '       drag coefficient for oceanic stress              cw     = ', cw
268         WRITE(numout,*) '       turning angle for oceanic stress                 angvg  = ', angvg, ' degrees'
269         WRITE(numout,*) '       first bulk-rheology parameter                    pstar  = ', pstar
270         WRITE(numout,*) '       second bulk-rhelogy parameter                    c_rhg  = ', c_rhg
271         WRITE(numout,*) '       minimun value for viscosity                      etamn  = ', etamn
272         WRITE(numout,*) '       creep limit                                      rn_creepl = ', rn_creepl
273         WRITE(numout,*) '       eccentricity of the elliptical yield curve       rn_ecc = ', rn_ecc
274         WRITE(numout,*) '       horizontal diffusivity coeff. for sea-ice        ahi0   = ', ahi0
275         WRITE(numout,*) '       number of iterations for subcycling              nn_nevp= ', nn_nevp
276         WRITE(numout,*) '       timescale for elastic waves telast = ', telast
277         WRITE(numout,*) '       coefficient for the solution of int. stresses alphaevp = ', alphaevp
278      ENDIF
279      !
280      IF( angvg /= 0._wp .AND. .NOT.lk_lim2_vp ) THEN
281         CALL ctl_warn( 'lim_dyn_init_2: turning angle for oceanic stress not properly coded for EVP ',   &
282            &           '(see limsbc_2 module). We force  angvg = 0._wp'  )
283         angvg = 0._wp
284      ENDIF
285
286      !  Initialization
287      usecc2 = 1.0 / ( rn_ecc * rn_ecc )
288      rhoco  = rau0 * cw
289      angvg  = angvg * rad      ! convert angvg from degree to radian
290      sangvg = SIN( angvg )
291      cangvg = COS( angvg )
292      pstarh = pstar / 2.0
293      !
294!$OMP PARALLEL DO schedule(static) private(jj, ji)
295      DO jj = 1, jpj
296         DO ji = 1, jpi
297            ahiu(ji,jj) = ahi0 * umask(ji,jj,1)            ! Ice eddy Diffusivity coefficients.
298            ahiv(ji,jj) = ahi0 * vmask(ji,jj,1)
299         END DO
300      END DO
301      !
302   END SUBROUTINE lim_dyn_init_2
303
304#else
305   !!----------------------------------------------------------------------
306   !!   Default option          Empty module       NO LIM 2.0 sea-ice model
307   !!----------------------------------------------------------------------
308CONTAINS
309   SUBROUTINE lim_dyn_2         ! Empty routine
310   END SUBROUTINE lim_dyn_2
311#endif 
312
313   !!======================================================================
314END MODULE limdyn_2
Note: See TracBrowser for help on using the repository browser.