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.
limtrp.F90 in trunk/NEMOGCM/NEMO/LIM_SRC_3 – NEMO

source: trunk/NEMOGCM/NEMO/LIM_SRC_3/limtrp.F90 @ 7698

Last change on this file since 7698 was 7698, checked in by mocavero, 7 years ago

update trunk with OpenMP parallelization

  • Property svn:keywords set to Id
File size: 35.8 KB
Line 
1MODULE limtrp
2   !!======================================================================
3   !!                       ***  MODULE limtrp   ***
4   !! LIM transport ice model : sea-ice advection/diffusion
5   !!======================================================================
6   !! History : LIM-2 ! 2000-01 (M.A. Morales Maqueda, H. Goosse, and T. Fichefet)  Original code
7   !!            3.0  ! 2005-11 (M. Vancoppenolle)   Multi-layer sea ice, salinity variations
8   !!            4.0  ! 2011-02 (G. Madec) dynamical allocation
9   !!----------------------------------------------------------------------
10#if defined key_lim3
11   !!----------------------------------------------------------------------
12   !!   'key_lim3'                                      LIM3 sea-ice model
13   !!----------------------------------------------------------------------
14   !!   lim_trp      : advection/diffusion process of sea ice
15   !!----------------------------------------------------------------------
16   USE phycst         ! physical constant
17   USE dom_oce        ! ocean domain
18   USE sbc_oce        ! ocean surface boundary condition
19   USE ice            ! ice variables
20   USE limhdf         ! ice horizontal diffusion
21   USE limvar         !
22   USE limadv_prather ! advection scheme (Prather)
23   USE limadv_umx     ! advection scheme (ultimate-macho)
24   !
25   USE in_out_manager ! I/O manager
26   USE lbclnk         ! lateral boundary conditions -- MPP exchanges
27   USE lib_mpp        ! MPP library
28   USE wrk_nemo       ! work arrays
29   USE prtctl         ! Print control
30   USE lib_fortran    ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined) 
31   USE timing         ! Timing
32   USE limcons        ! conservation tests
33   USE limctl         ! control prints
34
35   IMPLICIT NONE
36   PRIVATE
37
38   PUBLIC   lim_trp    ! called by sbcice_lim
39
40   INTEGER  ::   ncfl                 ! number of ice time step with CFL>1/2 
41
42   !! * Substitution
43#  include "vectopt_loop_substitute.h90"
44   !!----------------------------------------------------------------------
45   !! NEMO/LIM3 4.0 , UCL - NEMO Consortium (2011)
46   !! $Id$
47   !! Software governed by the CeCILL licence     (NEMOGCM/NEMO_CeCILL.txt)
48   !!----------------------------------------------------------------------
49CONTAINS
50
51   SUBROUTINE lim_trp( kt ) 
52      !!-------------------------------------------------------------------
53      !!                   ***  ROUTINE lim_trp ***
54      !!                   
55      !! ** purpose : advection/diffusion process of sea ice
56      !!
57      !! ** method  : variables included in the process are scalar,   
58      !!     other values are considered as second order.
59      !!     For advection, one can choose between
60      !!     a) an Ultimate-Macho scheme (whose order is defined by nn_limadv_ord) => nn_limadv=0
61      !!     b) and a second order Prather scheme => nn_limadv=-1
62      !!
63      !! ** action :
64      !!---------------------------------------------------------------------
65      INTEGER, INTENT(in) ::   kt   ! number of iteration
66      !
67      INTEGER  ::   ji, jj, jk, jm, jl, jt  ! dummy loop indices
68      INTEGER  ::   initad                  ! number of sub-timestep for the advection
69      REAL(wp) ::   zcfl , zusnit           !   -      -
70      CHARACTER(len=80) :: cltmp
71      !
72      REAL(wp) ::    zvi_b, zsmv_b, zei_b, zfs_b, zfw_b, zft_b
73      REAL(wp) ::    zdv, zda
74      REAL(wp), POINTER, DIMENSION(:,:)      ::   zatold, zeiold, zesold, zsmvold 
75      REAL(wp), POINTER, DIMENSION(:,:,:)    ::   zhimax, zviold, zvsold
76      ! --- diffusion --- !
77      REAL(wp), POINTER, DIMENSION(:,:,:)    ::   zhdfptab
78      INTEGER , PARAMETER                    ::   ihdf_vars  = 6 ! Number of variables in which we apply horizontal diffusion
79                                                                 !  inside limtrp for each ice category , not counting the
80                                                                 !  variables corresponding to ice_layers
81      ! --- ultimate macho only --- !
82      REAL(wp)                               ::   zdt
83      REAL(wp), POINTER, DIMENSION(:,:)      ::   zudy, zvdx, zcu_box, zcv_box
84      ! --- prather only --- !
85      REAL(wp), POINTER, DIMENSION(:,:)      ::   zarea
86      REAL(wp), POINTER, DIMENSION(:,:,:)    ::   z0opw
87      REAL(wp), POINTER, DIMENSION(:,:,:)    ::   z0ice, z0snw, z0ai, z0es , z0smi , z0oi
88      REAL(wp), POINTER, DIMENSION(:,:,:,:)  ::   z0ei
89      !!
90      !!---------------------------------------------------------------------
91      IF( nn_timing == 1 )  CALL timing_start('limtrp')
92
93      CALL wrk_alloc( jpi,jpj,                            zatold, zeiold, zesold, zsmvold )
94      CALL wrk_alloc( jpi,jpj,jpl,                        zhimax, zviold, zvsold )
95      CALL wrk_alloc( jpi,jpj,jpl*(ihdf_vars + nlay_i)+1, zhdfptab)
96 
97      IF( kt == nit000 .AND. lwp ) THEN
98         WRITE(numout,*)''
99         WRITE(numout,*)'limtrp'
100         WRITE(numout,*)'~~~~~~'
101         ncfl = 0                ! nb of time step with CFL > 1/2
102      ENDIF
103     
104      CALL lim_var_agg( 1 ) ! integrated values + ato_i
105
106      !-------------------------------------!
107      !   Advection of sea ice properties   !
108      !-------------------------------------!
109
110      ! conservation test
111      IF( ln_limdiachk )   CALL lim_cons_hsm(0, 'limtrp', zvi_b, zsmv_b, zei_b, zfw_b, zfs_b, zft_b)
112     
113      ! store old values for diag
114      zviold = v_i
115      zvsold = v_s
116!$OMP PARALLEL
117!$OMP DO schedule(static) private(jj,ji)
118      DO jj = 1, jpj
119         DO ji = 1, jpi
120            zsmvold(ji,jj) = 0._wp
121         END DO
122      END DO
123      DO jl = 1, jpl
124!$OMP DO schedule(static) private(jj,ji)
125         DO jj = 1, jpj
126            DO ji = 1, jpi
127               zsmvold(ji,jj) = zsmvold(ji,jj) + smv_i(ji,jj,jl)
128            END DO
129         END DO
130      END DO
131!$OMP DO schedule(static) private(jj,ji)
132      DO jj = 1, jpj
133         DO ji = 1, jpi
134            zeiold (ji,jj) = et_i(ji,jj)
135            zesold (ji,jj) = et_s(ji,jj)
136
137            !--- Thickness correction init. --- !
138            zatold (ji,jj) = at_i(ji,jj)
139         END DO
140      END DO
141      DO jl = 1, jpl
142!$OMP DO schedule(static) private(jj,ji,rswitch)
143         DO jj = 1, jpj
144            DO ji = 1, jpi
145               rswitch          = MAX( 0._wp , SIGN( 1._wp, a_i(ji,jj,jl) - epsi20 ) )
146               ht_i  (ji,jj,jl) = v_i (ji,jj,jl) / MAX( a_i(ji,jj,jl) , epsi20 ) * rswitch
147               ht_s  (ji,jj,jl) = v_s (ji,jj,jl) / MAX( a_i(ji,jj,jl) , epsi20 ) * rswitch
148            END DO
149         END DO
150      END DO
151      ! --- Record max of the surrounding ice thicknesses for correction in case advection creates ice too thick --- !
152      DO jl = 1, jpl
153!$OMP DO schedule(static) private(jj,ji)
154         DO jj = 1, jpj
155            DO ji = 1, jpi
156               zhimax(ji,jj,jl) = ht_i(ji,jj,jl) + ht_s(ji,jj,jl)
157            END DO
158         END DO
159      END DO
160!$OMP END PARALLEL
161      DO jl = 1, jpl
162!$OMP PARALLEL DO schedule(static) private(jj,ji)
163         DO jj = 2, jpjm1
164            DO ji = 2, jpim1
165               zhimax(ji,jj,jl) = MAXVAL( ht_i(ji-1:ji+1,jj-1:jj+1,jl) + ht_s(ji-1:ji+1,jj-1:jj+1,jl) )
166            END DO
167         END DO
168         CALL lbc_lnk(zhimax(:,:,jl),'T',1.)
169      END DO
170         
171      ! --- If ice drift field is too fast, use an appropriate time step for advection --- !       
172      zcfl  =            MAXVAL( ABS( u_ice(:,:) ) * rdt_ice * r1_e1u(:,:) )    ! CFL test for stability
173      zcfl  = MAX( zcfl, MAXVAL( ABS( v_ice(:,:) ) * rdt_ice * r1_e2v(:,:) ) )
174      IF( lk_mpp )   CALL mpp_max( zcfl )
175     
176      IF( zcfl > 0.5 ) THEN   ;   initad = 2   ;   zusnit = 0.5_wp
177      ELSE                    ;   initad = 1   ;   zusnit = 1.0_wp
178      ENDIF
179     
180!!      IF( zcfl > 0.5_wp .AND. lwp ) THEN
181!!         ncfl = ncfl + 1
182!!         IF( ncfl > 0 ) THEN   
183!!            WRITE(cltmp,'(i6.1)') ncfl
184!!            CALL ctl_warn( 'lim_trp: ncfl= ', TRIM(cltmp), 'advective ice time-step using a split in sub-time-step ')
185!!         ENDIF
186!!      ENDIF
187
188      SELECT CASE ( nn_limadv )
189         
190                       !=============================!
191      CASE ( 0 )       !==  Ultimate-MACHO scheme  ==!                   
192                       !=============================!
193     
194         CALL wrk_alloc( jpi,jpj, zudy, zvdx, zcu_box, zcv_box )
195     
196         IF( kt == nit000 .AND. lwp ) THEN
197            WRITE(numout,*)''
198            WRITE(numout,*)'lim_adv_umx : Ultimate-MACHO advection scheme'
199            WRITE(numout,*)'~~~~~~~~~~~'
200         ENDIF
201         !
202         zdt = rdt_ice / REAL(initad)
203         
204!$OMP PARALLEL
205         ! transport
206!$OMP DO schedule(static) private(jj,ji)
207         DO jj = 1, jpj
208            DO ji = 1, jpi
209               zudy(ji,jj) = u_ice(ji,jj) * e2u(ji,jj)
210               zvdx(ji,jj) = v_ice(ji,jj) * e1v(ji,jj)
211            END DO
212         END DO
213         
214         ! define velocity for advection: u*grad(H)
215!$OMP DO schedule(static) private(jj,ji)
216         DO jj = 2, jpjm1
217            DO ji = fs_2, fs_jpim1
218               IF    ( u_ice(ji,jj) * u_ice(ji-1,jj) <= 0._wp ) THEN   ;   zcu_box(ji,jj) = 0._wp
219               ELSEIF( u_ice(ji,jj)                  >  0._wp ) THEN   ;   zcu_box(ji,jj) = u_ice(ji-1,jj)
220               ELSE                                                    ;   zcu_box(ji,jj) = u_ice(ji  ,jj)
221               ENDIF
222               
223               IF    ( v_ice(ji,jj) * v_ice(ji,jj-1) <= 0._wp ) THEN   ;   zcv_box(ji,jj) = 0._wp
224               ELSEIF( v_ice(ji,jj)                  >  0._wp ) THEN   ;   zcv_box(ji,jj) = v_ice(ji,jj-1)
225               ELSE                                                    ;   zcv_box(ji,jj) = v_ice(ji,jj  )
226               ENDIF
227            END DO
228         END DO
229!$OMP END PARALLEL
230         
231         ! advection
232         DO jt = 1, initad
233            CALL lim_adv_umx( kt, zdt, zudy, zvdx, zcu_box, zcv_box, ato_i(:,:) )       ! Open water area
234            DO jl = 1, jpl
235               CALL lim_adv_umx( kt, zdt, zudy, zvdx, zcu_box, zcv_box, a_i(:,:,jl) )      ! Ice area
236               CALL lim_adv_umx( kt, zdt, zudy, zvdx, zcu_box, zcv_box, v_i(:,:,jl) )      ! Ice  volume
237               CALL lim_adv_umx( kt, zdt, zudy, zvdx, zcu_box, zcv_box, smv_i(:,:,jl) )    ! Salt content
238               CALL lim_adv_umx( kt, zdt, zudy, zvdx, zcu_box, zcv_box, oa_i (:,:,jl) )    ! Age content
239               DO jk = 1, nlay_i
240                  CALL lim_adv_umx( kt, zdt, zudy, zvdx, zcu_box, zcv_box, e_i(:,:,jk,jl) )   ! Ice  heat content
241               END DO
242               CALL lim_adv_umx( kt, zdt, zudy, zvdx, zcu_box, zcv_box, v_s(:,:,jl) )      ! Snow volume
243               CALL lim_adv_umx( kt, zdt, zudy, zvdx, zcu_box, zcv_box, e_s(:,:,1,jl) )    ! Snow heat content
244            END DO
245         END DO
246         !
247!$OMP PARALLEL
248!$OMP DO schedule(static) private(jj,ji)
249         DO jj = 1, jpj
250            DO ji = 1, jpi
251               at_i(ji,jj) = a_i(ji,jj,1)      ! total ice fraction
252            END DO
253         END DO
254         DO jl = 2, jpl
255!$OMP DO schedule(static) private(jj,ji)
256            DO jj = 1, jpj
257               DO ji = 1, jpi
258                  at_i(ji,jj) = at_i(ji,jj) + a_i(ji,jj,jl)
259               END DO
260            END DO
261         END DO
262!$OMP END PARALLEL
263         !
264         CALL wrk_dealloc( jpi,jpj, zudy, zvdx, zcu_box, zcv_box )
265         
266                       !=============================!
267      CASE ( -1 )      !==     Prather scheme      ==!                   
268                       !=============================!
269
270         CALL wrk_alloc( jpi,jpj,            zarea )
271         CALL wrk_alloc( jpi,jpj,1,          z0opw )
272         CALL wrk_alloc( jpi,jpj,jpl,        z0ice, z0snw, z0ai, z0es , z0smi , z0oi )
273         CALL wrk_alloc( jpi,jpj,nlay_i,jpl, z0ei )
274         
275         IF( kt == nit000 .AND. lwp ) THEN
276            WRITE(numout,*)''
277            WRITE(numout,*)'lim_adv_xy : Prather advection scheme'
278            WRITE(numout,*)'~~~~~~~~~~~'
279         ENDIF
280         
281!$OMP PARALLEL
282!$OMP DO schedule(static) private(jj,ji)
283         DO jj = 1, jpj
284            DO ji = 1, jpi
285               zarea(ji,jj) = e1e2t(ji,jj)
286         
287               !-------------------------
288               ! transported fields                                       
289               !-------------------------
290               z0opw(ji,jj,1) = ato_i(ji,jj) * e1e2t(ji,jj)             ! Open water area
291            END DO
292         END DO
293         DO jl = 1, jpl
294!$OMP DO schedule(static) private(jj,ji)
295            DO jj = 1, jpj
296               DO ji = 1, jpi
297                  z0snw (ji,jj,jl)  = v_s  (ji,jj,  jl) * e1e2t(ji,jj)  ! Snow volume
298                  z0ice(ji,jj,jl)   = v_i  (ji,jj,  jl) * e1e2t(ji,jj)  ! Ice  volume
299                  z0ai  (ji,jj,jl)  = a_i  (ji,jj,  jl) * e1e2t(ji,jj)  ! Ice area
300                  z0smi (ji,jj,jl)  = smv_i(ji,jj,  jl) * e1e2t(ji,jj)  ! Salt content
301                  z0oi (ji,jj,jl)   = oa_i (ji,jj,  jl) * e1e2t(ji,jj)  ! Age content
302                  z0es (ji,jj,jl)   = e_s  (ji,jj,1,jl) * e1e2t(ji,jj)  ! Snow heat content
303               END DO
304            END DO
305            DO jk = 1, nlay_i
306!$OMP DO schedule(static) private(jj,ji)
307               DO jj = 1, jpj
308                  DO ji = 1, jpi
309                     z0ei  (ji,jj,jk,jl) = e_i  (ji,jj,jk,jl) * e1e2t(ji,jj) ! Ice  heat content
310                  END DO
311               END DO
312            END DO
313         END DO
314!$OMP END PARALLEL
315
316
317         IF( MOD( ( kt - 1) / nn_fsbc , 2 ) == 0 ) THEN       !==  odd ice time step:  adv_x then adv_y  ==!
318            DO jt = 1, initad
319               CALL lim_adv_x( zusnit, u_ice, 1._wp, zarea, z0opw (:,:,1), sxopw(:,:),   &             !--- ice open water area
320                  &                                         sxxopw(:,:)  , syopw(:,:), syyopw(:,:), sxyopw(:,:)  )
321               CALL lim_adv_y( zusnit, v_ice, 0._wp, zarea, z0opw (:,:,1), sxopw(:,:),   &
322                  &                                         sxxopw(:,:)  , syopw(:,:), syyopw(:,:), sxyopw(:,:)  )
323               DO jl = 1, jpl
324                  CALL lim_adv_x( zusnit, u_ice, 1._wp, zarea, z0ice (:,:,jl), sxice(:,:,jl),   &    !--- ice volume  ---
325                     &                                         sxxice(:,:,jl), syice(:,:,jl), syyice(:,:,jl), sxyice(:,:,jl)  )
326                  CALL lim_adv_y( zusnit, v_ice, 0._wp, zarea, z0ice (:,:,jl), sxice(:,:,jl),   &
327                     &                                         sxxice(:,:,jl), syice(:,:,jl), syyice(:,:,jl), sxyice(:,:,jl)  )
328                  CALL lim_adv_x( zusnit, u_ice, 1._wp, zarea, z0snw (:,:,jl), sxsn (:,:,jl),   &    !--- snow volume  ---
329                     &                                         sxxsn (:,:,jl), sysn (:,:,jl), syysn (:,:,jl), sxysn (:,:,jl)  )
330                  CALL lim_adv_y( zusnit, v_ice, 0._wp, zarea, z0snw (:,:,jl), sxsn (:,:,jl),   &
331                     &                                         sxxsn (:,:,jl), sysn (:,:,jl), syysn (:,:,jl), sxysn (:,:,jl)  )
332                  CALL lim_adv_x( zusnit, u_ice, 1._wp, zarea, z0smi (:,:,jl), sxsal(:,:,jl),   &    !--- ice salinity ---
333                     &                                         sxxsal(:,:,jl), sysal(:,:,jl), syysal(:,:,jl), sxysal(:,:,jl)  )
334                  CALL lim_adv_y( zusnit, v_ice, 0._wp, zarea, z0smi (:,:,jl), sxsal(:,:,jl),   &
335                     &                                         sxxsal(:,:,jl), sysal(:,:,jl), syysal(:,:,jl), sxysal(:,:,jl)  )
336                  CALL lim_adv_x( zusnit, u_ice, 1._wp, zarea, z0oi  (:,:,jl), sxage(:,:,jl),   &    !--- ice age      ---     
337                     &                                         sxxage(:,:,jl), syage(:,:,jl), syyage(:,:,jl), sxyage(:,:,jl)  )
338                  CALL lim_adv_y( zusnit, v_ice, 0._wp, zarea, z0oi  (:,:,jl), sxage(:,:,jl),   &
339                     &                                         sxxage(:,:,jl), syage(:,:,jl), syyage(:,:,jl), sxyage(:,:,jl)  )
340                  CALL lim_adv_x( zusnit, u_ice, 1._wp, zarea, z0ai  (:,:,jl), sxa  (:,:,jl),   &    !--- ice concentrations ---
341                     &                                         sxxa  (:,:,jl), sya  (:,:,jl), syya  (:,:,jl), sxya  (:,:,jl)  )
342                  CALL lim_adv_y( zusnit, v_ice, 0._wp, zarea, z0ai  (:,:,jl), sxa  (:,:,jl),   & 
343                     &                                         sxxa  (:,:,jl), sya  (:,:,jl), syya  (:,:,jl), sxya  (:,:,jl)  )
344                  CALL lim_adv_x( zusnit, u_ice, 1._wp, zarea, z0es  (:,:,jl), sxc0 (:,:,jl),   &    !--- snow heat contents ---
345                     &                                         sxxc0 (:,:,jl), syc0 (:,:,jl), syyc0 (:,:,jl), sxyc0 (:,:,jl)  )
346                  CALL lim_adv_y( zusnit, v_ice, 0._wp, zarea, z0es  (:,:,jl), sxc0 (:,:,jl),   &
347                     &                                         sxxc0 (:,:,jl), syc0 (:,:,jl), syyc0 (:,:,jl), sxyc0 (:,:,jl)  )
348                  DO jk = 1, nlay_i                                                                !--- ice heat contents ---
349                     CALL lim_adv_x( zusnit, u_ice, 1._wp, zarea, z0ei(:,:,jk,jl), sxe (:,:,jk,jl),   & 
350                        &                                         sxxe(:,:,jk,jl), sye (:,:,jk,jl),   &
351                        &                                         syye(:,:,jk,jl), sxye(:,:,jk,jl) )
352                     CALL lim_adv_y( zusnit, v_ice, 0._wp, zarea, z0ei(:,:,jk,jl), sxe (:,:,jk,jl),   & 
353                        &                                         sxxe(:,:,jk,jl), sye (:,:,jk,jl),   &
354                        &                                         syye(:,:,jk,jl), sxye(:,:,jk,jl) )
355                  END DO
356               END DO
357            END DO
358         ELSE
359            DO jt = 1, initad
360               CALL lim_adv_y( zusnit, v_ice, 1._wp, zarea, z0opw (:,:,1), sxopw(:,:),   &             !--- ice open water area
361                  &                                         sxxopw(:,:)  , syopw(:,:), syyopw(:,:), sxyopw(:,:)  )
362               CALL lim_adv_x( zusnit, u_ice, 0._wp, zarea, z0opw (:,:,1), sxopw(:,:),   &
363                  &                                         sxxopw(:,:)  , syopw(:,:), syyopw(:,:), sxyopw(:,:)  )
364               DO jl = 1, jpl
365                  CALL lim_adv_y( zusnit, v_ice, 1._wp, zarea, z0ice (:,:,jl), sxice(:,:,jl),   &    !--- ice volume  ---
366                     &                                         sxxice(:,:,jl), syice(:,:,jl), syyice(:,:,jl), sxyice(:,:,jl)  )
367                  CALL lim_adv_x( zusnit, u_ice, 0._wp, zarea, z0ice (:,:,jl), sxice(:,:,jl),   &
368                     &                                         sxxice(:,:,jl), syice(:,:,jl), syyice(:,:,jl), sxyice(:,:,jl)  )
369                  CALL lim_adv_y( zusnit, v_ice, 1._wp, zarea, z0snw (:,:,jl), sxsn (:,:,jl),   &    !--- snow volume  ---
370                     &                                         sxxsn (:,:,jl), sysn (:,:,jl), syysn (:,:,jl), sxysn (:,:,jl)  )
371                  CALL lim_adv_x( zusnit, u_ice, 0._wp, zarea, z0snw (:,:,jl), sxsn (:,:,jl),   &
372                     &                                         sxxsn (:,:,jl), sysn (:,:,jl), syysn (:,:,jl), sxysn (:,:,jl)  )
373                  CALL lim_adv_y( zusnit, v_ice, 1._wp, zarea, z0smi (:,:,jl), sxsal(:,:,jl),   &    !--- ice salinity ---
374                     &                                         sxxsal(:,:,jl), sysal(:,:,jl), syysal(:,:,jl), sxysal(:,:,jl)  )
375                  CALL lim_adv_x( zusnit, u_ice, 0._wp, zarea, z0smi (:,:,jl), sxsal(:,:,jl),   &
376                     &                                         sxxsal(:,:,jl), sysal(:,:,jl), syysal(:,:,jl), sxysal(:,:,jl)  )
377                  CALL lim_adv_y( zusnit, v_ice, 1._wp, zarea, z0oi  (:,:,jl), sxage(:,:,jl),   &   !--- ice age      ---
378                     &                                         sxxage(:,:,jl), syage(:,:,jl), syyage(:,:,jl), sxyage(:,:,jl)  )
379                  CALL lim_adv_x( zusnit, u_ice, 0._wp, zarea, z0oi  (:,:,jl), sxage(:,:,jl),   &
380                     &                                         sxxage(:,:,jl), syage(:,:,jl), syyage(:,:,jl), sxyage(:,:,jl)  )
381                  CALL lim_adv_y( zusnit, v_ice, 1._wp, zarea, z0ai  (:,:,jl), sxa  (:,:,jl),   &   !--- ice concentrations ---
382                     &                                         sxxa  (:,:,jl), sya  (:,:,jl), syya  (:,:,jl), sxya  (:,:,jl)  )
383                  CALL lim_adv_x( zusnit, u_ice, 0._wp, zarea, z0ai  (:,:,jl), sxa  (:,:,jl),   &
384                     &                                         sxxa  (:,:,jl), sya  (:,:,jl), syya  (:,:,jl), sxya  (:,:,jl)  )
385                  CALL lim_adv_y( zusnit, v_ice, 1._wp, zarea, z0es  (:,:,jl), sxc0 (:,:,jl),   &  !--- snow heat contents ---
386                     &                                         sxxc0 (:,:,jl), syc0 (:,:,jl), syyc0 (:,:,jl), sxyc0 (:,:,jl)  )
387                  CALL lim_adv_x( zusnit, u_ice, 0._wp, zarea, z0es  (:,:,jl), sxc0 (:,:,jl),   &
388                     &                                         sxxc0 (:,:,jl), syc0 (:,:,jl), syyc0 (:,:,jl), sxyc0 (:,:,jl)  )
389                  DO jk = 1, nlay_i                                                           !--- ice heat contents ---
390                     CALL lim_adv_y( zusnit, v_ice, 1._wp, zarea, z0ei(:,:,jk,jl), sxe (:,:,jk,jl),   & 
391                        &                                         sxxe(:,:,jk,jl), sye (:,:,jk,jl),   &
392                        &                                         syye(:,:,jk,jl), sxye(:,:,jk,jl) )
393                     CALL lim_adv_x( zusnit, u_ice, 0._wp, zarea, z0ei(:,:,jk,jl), sxe (:,:,jk,jl),   & 
394                        &                                         sxxe(:,:,jk,jl), sye (:,:,jk,jl),   &
395                        &                                         syye(:,:,jk,jl), sxye(:,:,jk,jl) )
396                  END DO
397               END DO
398            END DO
399         ENDIF
400
401         !-------------------------------------------
402         ! Recover the properties from their contents
403         !-------------------------------------------
404!$OMP PARALLEL
405!$OMP DO schedule(static) private(jj,ji)
406         DO jj = 1, jpj
407            DO ji = 1, jpi
408               ato_i(ji,jj) = z0opw(ji,jj,1) * r1_e1e2t(ji,jj)
409            END DO
410         END DO
411         DO jl = 1, jpl
412!$OMP DO schedule(static) private(jj,ji)
413            DO jj = 1, jpj
414               DO ji = 1, jpi
415                  v_i  (ji,jj,  jl) = z0ice(ji,jj,jl) * r1_e1e2t(ji,jj)
416                  v_s  (ji,jj,  jl) = z0snw(ji,jj,jl) * r1_e1e2t(ji,jj)
417                  smv_i(ji,jj,  jl) = z0smi(ji,jj,jl) * r1_e1e2t(ji,jj)
418                  oa_i (ji,jj,  jl) = z0oi (ji,jj,jl) * r1_e1e2t(ji,jj)
419                  a_i  (ji,jj,  jl) = z0ai (ji,jj,jl) * r1_e1e2t(ji,jj)
420                  e_s  (ji,jj,1,jl) = z0es (ji,jj,jl) * r1_e1e2t(ji,jj)
421               END DO
422            END DO
423            DO jk = 1, nlay_i
424!$OMP DO schedule(static) private(jj,ji)
425               DO jj = 1, jpj
426                  DO ji = 1, jpi
427                     e_i(ji,jj,jk,jl) = z0ei(ji,jj,jk,jl) * r1_e1e2t(ji,jj)
428                  END DO
429               END DO
430            END DO
431         END DO
432
433!$OMP DO schedule(static) private(jj,ji)
434         DO jj = 1, jpj
435            DO ji = 1, jpi
436               at_i(ji,jj) = a_i(ji,jj,1)      ! total ice fraction
437            END DO
438         END DO
439         DO jl = 2, jpl
440!$OMP DO schedule(static) private(jj,ji)
441            DO jj = 1, jpj
442               DO ji = 1, jpi
443                  at_i(ji,jj) = at_i(ji,jj) + a_i(ji,jj,jl)
444               END DO
445            END DO
446         END DO
447!$OMP END PARALLEL
448         
449         CALL wrk_dealloc( jpi,jpj,            zarea )
450         CALL wrk_dealloc( jpi,jpj,1,          z0opw )
451         CALL wrk_dealloc( jpi,jpj,jpl,        z0ice, z0snw, z0ai, z0es , z0smi , z0oi )
452         CALL wrk_dealloc( jpi,jpj,nlay_i,jpl, z0ei )
453
454      END SELECT
455     
456      !------------------------------!
457      ! Diffusion of Ice fields                 
458      !------------------------------!
459      IF( nn_ahi0 /= -1 .AND. nn_limdyn == 2 ) THEN
460         !
461         ! --- Prepare diffusion for variables with categories --- !
462         !     mask eddy diffusivity coefficient at ocean U- and V-points
463         jm=1
464!$OMP PARALLEL
465         DO jl = 1, jpl
466!$OMP DO schedule(static) private(jj,ji)
467            DO jj = 1, jpjm1                 ! NB: has not to be defined on jpj line and jpi row
468               DO ji = 1 , fs_jpim1
469                  pahu3D(ji,jj,jl) = ( 1._wp - MAX( 0._wp, SIGN( 1._wp, -a_i(ji  ,jj,  jl ) ) ) )   &
470                  &                * ( 1._wp - MAX( 0._wp, SIGN( 1._wp, -a_i(ji+1,jj,  jl ) ) ) ) * ahiu(ji,jj)
471                  pahv3D(ji,jj,jl) = ( 1._wp - MAX( 0._wp, SIGN( 1._wp, -a_i(ji,  jj,  jl ) ) ) )   &
472                  &                * ( 1._wp - MAX( 0._wp, SIGN( 1._wp,- a_i(ji,  jj+1,jl ) ) ) ) * ahiv(ji,jj)
473               END DO
474            END DO
475
476!$OMP DO schedule(static) private(jj,ji)
477            DO jj = 1, jpj
478               DO ji = 1, jpi
479                  zhdfptab(ji,jj,jm)= a_i  (ji,jj,  jl)
480               END DO
481            END DO
482            jm = jm + 1
483!$OMP DO schedule(static) private(jj,ji)
484            DO jj = 1, jpj
485               DO ji = 1, jpi
486                  zhdfptab(ji,jj,jm)= v_i  (ji,jj,  jl)
487               END DO
488            END DO
489            jm = jm + 1
490!$OMP DO schedule(static) private(jj,ji)
491            DO jj = 1, jpj
492               DO ji = 1, jpi
493                  zhdfptab(ji,jj,jm)= v_s  (ji,jj,  jl)
494               END DO
495            END DO
496            jm = jm + 1
497!$OMP DO schedule(static) private(jj,ji)
498            DO jj = 1, jpj
499               DO ji = 1, jpi
500                  zhdfptab(ji,jj,jm)= smv_i(ji,jj,  jl)
501               END DO
502            END DO
503            jm = jm + 1
504!$OMP DO schedule(static) private(jj,ji)
505            DO jj = 1, jpj
506               DO ji = 1, jpi
507                  zhdfptab(ji,jj,jm)= oa_i (ji,jj,  jl)
508               END DO
509            END DO
510            jm = jm + 1
511!$OMP DO schedule(static) private(jj,ji)
512            DO jj = 1, jpj
513               DO ji = 1, jpi
514                  zhdfptab(ji,jj,jm)= e_s  (ji,jj,1,jl)
515               END DO
516            END DO
517            jm = jm + 1
518            ! Sample of adding more variables to apply lim_hdf (ihdf_vars must be increased)
519            !   zhdfptab(:,:,jm) = variable_1 (:,:,1,jl); jm = jm + 1 
520            !   zhdfptab(:,:,jm) = variable_2 (:,:,1,jl); jm = jm + 1
521            DO jk = 1, nlay_i
522!$OMP DO schedule(static) private(jj,ji)
523               DO jj = 1, jpj
524                  DO ji = 1, jpi
525                     zhdfptab(ji,jj,jm)=e_i(ji,jj,jk,jl)
526                  END DO
527               END DO
528               jm= jm+1
529            END DO
530         END DO
531
532         ! --- Prepare diffusion for open water area --- !
533         !     mask eddy diffusivity coefficient at ocean U- and V-points
534!$OMP DO schedule(static) private(jj,ji)
535         DO jj = 1, jpjm1                    ! NB: has not to be defined on jpj line and jpi row
536            DO ji = 1 , fs_jpim1
537               pahu3D(ji,jj,jpl+1) = ( 1._wp - MAX( 0._wp, SIGN( 1._wp, -at_i(ji  ,jj) ) ) )   &
538                  &                * ( 1._wp - MAX( 0._wp, SIGN( 1._wp, -at_i(ji+1,jj) ) ) ) * ahiu(ji,jj)
539               pahv3D(ji,jj,jpl+1) = ( 1._wp - MAX( 0._wp, SIGN( 1._wp, -at_i(ji,jj  ) ) ) )   &
540                  &                * ( 1._wp - MAX( 0._wp, SIGN( 1._wp,- at_i(ji,jj+1) ) ) ) * ahiv(ji,jj)
541            END DO
542         END DO
543         !
544!$OMP DO schedule(static) private(jj,ji)
545         DO jj = 1, jpj
546            DO ji = 1, jpi
547               zhdfptab(ji,jj,jm)= ato_i  (ji,jj);
548            END DO
549         END DO
550!$OMP END PARALLEL
551
552         ! --- Apply diffusion --- !
553         CALL lim_hdf( zhdfptab, ihdf_vars )
554
555         ! --- Recover properties --- !
556         jm=1
557!$OMP PARALLEL
558         DO jl = 1, jpl
559!$OMP DO schedule(static) private(jj,ji)
560            DO jj = 1, jpj
561               DO ji = 1, jpi
562                  a_i  (ji,jj,  jl)=zhdfptab(ji,jj,jm)
563               END DO
564            END DO
565            jm = jm + 1
566!$OMP DO schedule(static) private(jj,ji)
567            DO jj = 1, jpj
568               DO ji = 1, jpi
569                  v_i  (ji,jj,  jl)=zhdfptab(ji,jj,jm)
570               END DO
571            END DO
572            jm = jm + 1
573!$OMP DO schedule(static) private(jj,ji)
574            DO jj = 1, jpj
575               DO ji = 1, jpi
576                  v_s  (ji,jj,  jl)=zhdfptab(ji,jj,jm)
577               END DO
578            END DO
579            jm = jm + 1
580!$OMP DO schedule(static) private(jj,ji)
581            DO jj = 1, jpj
582               DO ji = 1, jpi
583                  smv_i(ji,jj,  jl)=zhdfptab(ji,jj,jm)
584               END DO
585            END DO
586            jm = jm + 1
587!$OMP DO schedule(static) private(jj,ji)
588            DO jj = 1, jpj
589               DO ji = 1, jpi
590                  oa_i (ji,jj,  jl)=zhdfptab(ji,jj,jm)
591               END DO
592            END DO
593            jm = jm + 1
594!$OMP DO schedule(static) private(jj,ji)
595            DO jj = 1, jpj
596               DO ji = 1, jpi
597                  e_s  (ji,jj,1,jl)=zhdfptab(ji,jj,jm)
598               END DO
599            END DO
600            jm = jm + 1
601
602            ! Sample of adding more variables to apply lim_hdf
603            !   variable_1  (:,:,1,jl) = zhdfptab(:,:, jm  ) ; jm + 1
604            !   variable_2  (:,:,1,jl) = zhdfptab(:,:, jm  ) ; jm + 1
605            DO jk = 1, nlay_i
606!$OMP DO schedule(static) private(jj,ji)
607               DO jj = 1, jpj
608                  DO ji = 1, jpi
609                     e_i(ji,jj,jk,jl) = zhdfptab(ji,jj,jm)
610                  END DO
611               END DO
612               jm = jm + 1
613            END DO
614         END DO
615!$OMP DO schedule(static) private(jj,ji)
616         DO jj = 1, jpj
617            DO ji = 1, jpi
618               ato_i  (ji,jj) = zhdfptab(ji,jj,jm)
619            END DO
620         END DO
621!$OMP END PARALLEL
622             
623      ENDIF
624
625      ! --- diags ---
626!$OMP PARALLEL DO schedule(static) private(jj,ji)
627      DO jj = 1, jpj
628         DO ji = 1, jpi
629            diag_trp_ei (ji,jj) = ( SUM( e_i  (ji,jj,1:nlay_i,:) ) -  zeiold(ji,jj) ) * r1_rdtice
630            diag_trp_es (ji,jj) = ( SUM( e_s  (ji,jj,1:nlay_s,:) ) -  zesold(ji,jj) ) * r1_rdtice
631            diag_trp_smv(ji,jj) = ( SUM( smv_i(ji,jj,:)          ) - zsmvold(ji,jj) ) * r1_rdtice
632            diag_trp_vi (ji,jj) =   SUM(   v_i(ji,jj,:)            -  zviold(ji,jj,:) ) * r1_rdtice
633            diag_trp_vs (ji,jj) =   SUM(   v_s(ji,jj,:)            -  zvsold(ji,jj,:) ) * r1_rdtice
634         END DO
635      END DO
636     
637      IF( nn_limdyn == 2) THEN
638
639         ! zap small areas
640         CALL lim_var_zapsmall
641           
642         !--- Thickness correction in case too high --- !
643!$OMP PARALLEL
644         DO jl = 1, jpl
645!$OMP DO schedule(static) private(jj,ji,rswitch,zdv)
646            DO jj = 1, jpj
647               DO ji = 1, jpi
648                 
649                  IF ( v_i(ji,jj,jl) > 0._wp ) THEN
650                     
651                     rswitch          = MAX( 0._wp , SIGN( 1._wp, a_i(ji,jj,jl) - epsi20 ) )
652                     ht_i  (ji,jj,jl) = v_i (ji,jj,jl) / MAX( a_i(ji,jj,jl) , epsi20 ) * rswitch
653                     ht_s  (ji,jj,jl) = v_s (ji,jj,jl) / MAX( a_i(ji,jj,jl) , epsi20 ) * rswitch
654                     
655                     zdv  = v_i(ji,jj,jl) + v_s(ji,jj,jl) - zviold(ji,jj,jl) - zvsold(ji,jj,jl) 
656                     
657                     IF ( ( zdv >  0.0 .AND. (ht_i(ji,jj,jl)+ht_s(ji,jj,jl)) > zhimax(ji,jj,jl) .AND. zatold(ji,jj) < 0.80 ) .OR. &
658                        & ( zdv <= 0.0 .AND. (ht_i(ji,jj,jl)+ht_s(ji,jj,jl)) > zhimax(ji,jj,jl) ) ) THEN
659                       
660                        rswitch        = MAX( 0._wp, SIGN( 1._wp, zhimax(ji,jj,jl) - epsi20 ) )
661                        a_i(ji,jj,jl)  = rswitch * ( v_i(ji,jj,jl) + v_s(ji,jj,jl) ) / MAX( zhimax(ji,jj,jl), epsi20 )
662                       
663                        ! small correction due to *rswitch for a_i
664                        v_i  (ji,jj,jl)        = rswitch * v_i  (ji,jj,jl)
665                        v_s  (ji,jj,jl)        = rswitch * v_s  (ji,jj,jl)
666                        smv_i(ji,jj,jl)        = rswitch * smv_i(ji,jj,jl)
667                        e_s(ji,jj,1,jl)        = rswitch * e_s(ji,jj,1,jl)
668                        e_i(ji,jj,1:nlay_i,jl) = rswitch * e_i(ji,jj,1:nlay_i,jl)
669                                               
670                     ENDIF
671                     
672                  ENDIF
673               
674               END DO
675            END DO
676         END DO
677         ! -------------------------------------------------
678         
679         ! Force the upper limit of ht_i to always be < hi_max (99 m).
680!$OMP DO schedule(static) private(jj,ji,rswitch)
681         DO jj = 1, jpj
682            DO ji = 1, jpi
683               rswitch         = MAX( 0._wp , SIGN( 1._wp, ht_i(ji,jj,jpl) - epsi20 ) )
684               ht_i(ji,jj,jpl) = MIN( ht_i(ji,jj,jpl) , hi_max(jpl) )
685               a_i (ji,jj,jpl) = v_i(ji,jj,jpl) / MAX( ht_i(ji,jj,jpl) , epsi20 ) * rswitch
686            END DO
687         END DO
688!$OMP END PARALLEL
689
690      ENDIF
691         
692      !------------------------------------------------------------
693      ! Impose a_i < amax if no ridging/rafting or in mono-category
694      !------------------------------------------------------------
695      !
696!$OMP PARALLEL
697!$OMP DO schedule(static) private(jj,ji)
698         DO jj = 1, jpj
699            DO ji = 1, jpi
700               at_i(ji,jj) = 0._wp
701            END DO
702         END DO
703         DO jl = 1, jpl
704!$OMP DO schedule(static) private(jj,ji)
705            DO jj = 1, jpj
706               DO ji = 1, jpi
707                  at_i(ji,jj) = at_i(ji,jj) + a_i(ji,jj,jl)
708               END DO
709            END DO
710         END DO
711!$OMP END PARALLEL
712
713      IF ( nn_limdyn == 1 .OR. ( ( nn_monocat == 2 ) .AND. ( jpl == 1 ) ) ) THEN ! simple conservative piling, comparable with LIM2
714         DO jl = 1, jpl
715!$OMP PARALLEL DO schedule(static) private(jj,ji,rswitch,zda)
716            DO jj = 1, jpj
717               DO ji = 1, jpi
718                  rswitch       = MAX( 0._wp, SIGN( 1._wp, at_i(ji,jj) - epsi20 ) )
719                  zda           = rswitch * MIN( rn_amax_2d(ji,jj) - at_i(ji,jj), 0._wp )  &
720                     &                    * a_i(ji,jj,jl) / MAX( at_i(ji,jj), epsi20 )
721                  a_i(ji,jj,jl) = a_i(ji,jj,jl) + zda
722               END DO
723            END DO
724         END DO
725      ENDIF
726     
727      ! --- agglomerate variables -----------------
728!$OMP PARALLEL
729!$OMP DO schedule(static) private(jj,ji)
730      DO jj = 1, jpj
731         DO ji = 1, jpi
732            vt_i(ji,jj) = 0._wp
733            vt_s(ji,jj) = 0._wp
734            at_i(ji,jj) = 0._wp
735         END DO
736      END DO
737      DO jl = 1, jpl
738!$OMP DO schedule(static) private(jj,ji)
739         DO jj = 1, jpj
740            DO ji = 1, jpi
741               vt_i(ji,jj) = vt_i(ji,jj) + v_i(ji,jj,jl)
742               vt_s(ji,jj) = vt_s(ji,jj) + v_s(ji,jj,jl)
743               at_i(ji,jj) = at_i(ji,jj) + a_i(ji,jj,jl)
744            END DO
745         END DO
746      END DO
747     
748      ! --- open water = 1 if at_i=0 --------------------------------
749!$OMP DO schedule(static) private(jj,ji)
750      DO jj = 1, jpj
751         DO ji = 1, jpi
752            IF( at_i(ji,jj) == 0._wp ) ato_i(ji,jj) = 1._wp 
753         END DO
754      END DO
755!$OMP END PARALLEL
756     
757      ! conservation test
758      IF( ln_limdiachk )   CALL lim_cons_hsm(1, 'limtrp', zvi_b, zsmv_b, zei_b, zfw_b, zfs_b, zft_b)
759       
760      ! -------------------------------------------------
761      ! control prints
762      ! -------------------------------------------------
763      IF( ln_limctl )   CALL lim_prt( kt, iiceprt, jiceprt,-1, ' - ice dyn & trp - ' )
764      !
765      CALL wrk_dealloc( jpi,jpj,                            zatold, zeiold, zesold, zsmvold )
766      CALL wrk_dealloc( jpi,jpj,jpl,                        zhimax, zviold, zvsold )
767      CALL wrk_dealloc( jpi,jpj,jpl*(ihdf_vars + nlay_i)+1, zhdfptab)
768      !
769      IF( nn_timing == 1 )  CALL timing_stop('limtrp')
770      !
771   END SUBROUTINE lim_trp
772
773#else
774   !!----------------------------------------------------------------------
775   !!   Default option         Empty Module                No sea-ice model
776   !!----------------------------------------------------------------------
777CONTAINS
778   SUBROUTINE lim_trp        ! Empty routine
779   END SUBROUTINE lim_trp
780#endif
781   !!======================================================================
782END MODULE limtrp
783
Note: See TracBrowser for help on using the repository browser.