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.
limthd_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/limthd_2.F90 @ 7508

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

changes on code duplication and workshare construct

  • Property svn:keywords set to Id
File size: 36.4 KB
Line 
1MODULE limthd_2
2   !!======================================================================
3   !!                  ***  MODULE limthd_2   ***
4   !!              LIM thermo ice model : ice thermodynamic
5   !!======================================================================
6   !! History :  1.0  ! 2000-01 (LIM)
7   !!            2.0  ! 2002-07 (C. Ethe, G. Madec) F90
8   !!            2.0  ! 2003-08 (C. Ethe)  add lim_thd_init
9   !!             -   ! 2008-2008  (A. Caubel, G. Madec, E. Maisonnave, S. Masson ) generic coupled interface
10   !!---------------------------------------------------------------------
11#if defined key_lim2
12   !!----------------------------------------------------------------------
13   !!   'key_lim2' :                                  LIM 2.0 sea-ice model
14   !!----------------------------------------------------------------------
15   !!   lim_thd_2       : thermodynamic of sea ice
16   !!   lim_thd_init_2  : initialisation of sea-ice thermodynamic
17   !!----------------------------------------------------------------------
18   USE phycst           ! physical constants
19   USE dom_oce          ! ocean space and time domain variables
20   USE domvvl           ! ocean domain
21   USE ice_2            ! LIM sea-ice variables
22   USE sbc_oce          ! surface boundary condition: ocean
23   USE sbc_ice          ! surface boundary condition: sea-ice
24   USE thd_ice_2        ! LIM thermodynamic sea-ice variables
25   USE dom_ice_2        ! LIM sea-ice domain
26   USE limthd_zdf_2     !
27   USE limthd_lac_2     !
28   USE limtab_2         !
29   !
30   USE in_out_manager   ! I/O manager
31   USE lbclnk           !
32   USE lib_mpp          !
33   USE wrk_nemo         ! work arrays
34   USE iom              ! IOM library
35   USE prtctl           ! Print control
36   USE lib_fortran      ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined) 
37   
38   IMPLICIT NONE
39   PRIVATE
40
41   PUBLIC   lim_thd_2  ! called by lim_step
42
43   REAL(wp) ::   epsi20 = 1.e-20   ! constant values
44   REAL(wp) ::   epsi16 = 1.e-16   !
45   REAL(wp) ::   epsi04 = 1.e-04   !
46   REAL(wp) ::   rzero  = 0._wp    !
47   REAL(wp) ::   rone   = 1._wp    !
48
49   !! * Substitutions
50#  include "vectopt_loop_substitute.h90"
51   !!-------- -------------------------------------------------------------
52   !! NEMO/LIM2 3.3 , UCL - NEMO Consortium (2010)
53   !! $Id$
54   !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
55   !!----------------------------------------------------------------------
56CONTAINS
57
58   SUBROUTINE lim_thd_2( kt )
59      !!-------------------------------------------------------------------
60      !!                ***  ROUTINE lim_thd_2  ***       
61      !! 
62      !! ** Purpose : This routine manages the ice thermodynamic.
63      !!         
64      !! ** Action : - Initialisation of some variables
65      !!             - Some preliminary computation (oceanic heat flux
66      !!               at the ice base, snow acc.,heat budget of the leads)
67      !!             - selection of the icy points and put them in an array
68      !!             - call lim_vert_ther for vert ice thermodynamic
69      !!             - back to the geographic grid
70      !!             - selection of points for lateral accretion
71      !!             - call lim_lat_acc  for the ice accretion
72      !!             - back to the geographic grid
73      !!
74      !! References :   Goosse et al. 1996, Bul. Soc. Roy. Sc. Liege, 65, 87-90
75      !!---------------------------------------------------------------------
76      INTEGER, INTENT(in) ::   kt     ! number of iteration
77      !
78      INTEGER  ::   ji, jj, jk           ! dummy loop indices
79      INTEGER  ::   nbpb                 ! nb of icy pts for thermo. cal.
80      INTEGER  ::   nbpac                ! nb of pts for lateral accretion
81      CHARACTER (len=22) :: charout
82      REAL(wp) ::   zfric_umin = 5e-03   ! lower bound for the friction velocity
83      REAL(wp) ::   zfric_umax = 2e-02   ! upper bound for the friction velocity
84      REAL(wp) ::   zinda                ! switch for test. the val. of concen.
85      REAL(wp) ::   zindb, zindg         ! switches for test. the val of arg
86      REAL(wp) ::   zfricp               ! temporary scalar
87      REAL(wp) ::   za , zh, zthsnice    !
88      REAL(wp) ::   zfric_u              ! friction velocity
89      REAL(wp) ::   zfntlat, zpareff     ! test. the val. of lead heat budget
90
91      REAL(wp) ::   zuice_m, zvice_m     ! Sea-ice velocities at U & V-points
92      REAL(wp) ::   zhice_u, zhice_v     ! Sea-ice volume at U & V-points
93      REAL(wp) ::   ztr_fram             ! Sea-ice transport through Fram strait
94      REAL(wp) ::   zrhoij, zrhoijm1     ! temporary scalars
95      REAL(wp) ::   zztmp                ! temporary scalars within a loop
96      REAL(wp), POINTER, DIMENSION(:,:)     ::   ztmp      ! 2D workspace
97      REAL(wp), POINTER, DIMENSION(:,:)     ::   zqlbsbq   ! link with lead energy budget qldif
98      REAL(wp), POINTER, DIMENSION(:,:)     ::   zlicegr   ! link with lateral ice growth
99!!$      REAL(wp), DIMENSION(:,:) ::   firic         ! IR flux over the ice            (outputs only)
100!!$      REAL(wp), DIMENSION(:,:) ::   fcsic         ! Sensible heat flux over the ice (outputs only)
101!!$      REAL(wp), DIMENSION(:,:) ::   fleic         ! Latent heat flux over the ice   (outputs only)
102!!$      REAL(wp), DIMENSION(:,:) ::   qlatic        ! latent flux                     (outputs only)
103      REAL(wp), POINTER, DIMENSION(:,:) ::   zdvosif       ! Variation of volume at surface                (outputs only)
104      REAL(wp), POINTER, DIMENSION(:,:) ::   zdvobif       ! Variation of ice volume at the bottom ice     (outputs only)
105      REAL(wp), POINTER, DIMENSION(:,:) ::   zdvolif       ! Total variation of ice volume                 (outputs only)
106      REAL(wp), POINTER, DIMENSION(:,:) ::   zdvonif       ! Surface accretion Snow to Ice transformation  (outputs only)
107      REAL(wp), POINTER, DIMENSION(:,:) ::   zdvomif       ! Bottom variation of ice volume due to melting (outputs only)
108      REAL(wp), POINTER, DIMENSION(:,:) ::   zu_imasstr    ! Sea-ice transport along i-axis at U-point     (outputs only)
109      REAL(wp), POINTER, DIMENSION(:,:) ::   zv_imasstr    ! Sea-ice transport along j-axis at V-point     (outputs only)
110      REAL(wp), POINTER, DIMENSION(:,:,:) ::   zmsk        ! 3D workspace
111      !!-------------------------------------------------------------------
112
113      CALL wrk_alloc( jpi, jpj, ztmp, zqlbsbq, zlicegr, zdvosif, zdvobif, zdvolif, zdvonif, zdvomif, zu_imasstr, zv_imasstr )
114      CALL wrk_alloc( jpi, jpj, jpk, zmsk )
115
116      IF( kt == nit000 )   CALL lim_thd_init_2   ! Initialization (first time-step only)
117   
118      !-------------------------------------------!
119      !   Initilization of diagnostic variables   !
120      !-------------------------------------------!
121     
122!!gm needed?  yes at least for some of these arrays
123      ztr_fram     = 0.e0   ! sea-ice transport through Fram strait
124!$OMP PARALLEL
125!$OMP DO schedule(static) private(jj,ji)
126      DO jj = 1, jpj
127         DO ji = 1, jpi
128            zdvosif(ji,jj) = 0.e0   ! variation of ice volume at surface
129            zdvobif(ji,jj) = 0.e0   ! variation of ice volume at bottom
130            zdvolif(ji,jj) = 0.e0   ! total variation of ice volume
131            zdvonif(ji,jj) = 0.e0   ! transformation of snow to sea-ice volume
132            zlicegr(ji,jj) = 0.e0   ! lateral variation of ice volume
133            zdvomif(ji,jj) = 0.e0   ! variation of ice volume at bottom due to melting only
134            fstric (ji,jj) = 0.e0   ! part of solar radiation absorbing inside the ice
135            fscmbq (ji,jj) = 0.e0   ! linked with fstric
136            ffltbif(ji,jj) = 0.e0   ! linked with fstric
137            qfvbq  (ji,jj) = 0.e0   ! linked with fstric
138            rdm_snw(ji,jj) = 0.e0   ! variation of snow mass over 1 time step
139            rdq_snw(ji,jj) = 0.e0   ! heat content associated with rdm_snw
140            rdm_ice(ji,jj) = 0.e0   ! variation of ice mass over 1 time step
141            rdq_ice(ji,jj) = 0.e0   ! heat content associated with rdm_ice
142         END DO
143      END DO
144!$OMP END DO NOWAIT
145!$OMP DO schedule(static) private(jk,jj,ji)
146      DO jk = 1, jpk
147         DO jj = 1, jpj
148            DO ji = 1, jpi
149               zmsk (ji,jj,jk) = 0.e0
150            END DO
151         END DO
152      END DO
153!$OMP END DO NOWAIT
154
155      ! set to zero snow thickness smaller than epsi04
156!$OMP DO schedule(static) private(jj,ji)
157      DO jj = 1, jpj
158         DO ji = 1, jpi
159            hsnif(ji,jj)  = hsnif(ji,jj) *  MAX( rzero, SIGN( rone , hsnif(ji,jj) - epsi04 ) )
160         END DO
161      END DO
162!$OMP END DO NOWAIT
163!$OMP END PARALLEL
164!!gm better coded (do not use SIGN...)
165!     WHERE( hsnif(:,:) < epsi04 )   hsnif(:,:) = 0.e0
166!!gm
167
168      IF(ln_ctl)   CALL prt_ctl( tab2d_1=hsnif, clinfo1=' lim_thd: hsnif   : ' )
169     
170      !-----------------------------------!
171      !   Treatment of particular cases   !
172      !-----------------------------------!
173     
174!$OMP PARALLEL DO schedule(static) private(jj,ji,zindg,zthsnice,zindb,za,zh)
175      DO jj = 1, jpj
176         DO ji = 1, jpi
177            !  snow is transformed into ice if the original ice cover disappears.
178            zindg         = tms(ji,jj) *  MAX( rzero , SIGN( rone , -hicif(ji,jj) ) )
179            hicif(ji,jj)  = hicif(ji,jj) + zindg * rhosn * hsnif(ji,jj) / rau0
180            hsnif(ji,jj)  = ( rone - zindg ) * hsnif(ji,jj) + zindg * hicif(ji,jj) * ( rau0 - rhoic ) / rhosn
181            dmgwi(ji,jj)  = zindg * (1.0 - frld(ji,jj)) * rhoic * hicif(ji,jj)   ! snow/ice mass
182           
183            !  the lead fraction, frld, must be little than or equal to amax (ice ridging).
184            zthsnice      = hsnif(ji,jj) + hicif(ji,jj)
185            zindb         = tms(ji,jj) * ( 1.0 - MAX( rzero , SIGN( rone , - zthsnice ) ) ) 
186            za            = zindb * MIN( rone, ( 1.0 - frld(ji,jj) ) * uscomi )
187            hsnif (ji,jj) = hsnif(ji,jj)  * za
188            hicif (ji,jj) = hicif(ji,jj)  * za
189            qstoif(ji,jj) = qstoif(ji,jj) * za
190            frld  (ji,jj) = 1.0 - zindb * ( 1.0 - frld(ji,jj) ) / MAX( za, epsi20 )
191           
192            !  the in situ ice thickness, hicif, must be equal to or greater than hiclim.
193            zh            = MAX( rone , zindb * hiclim  / MAX( hicif(ji,jj), epsi20 ) )
194            hsnif (ji,jj) = hsnif(ji,jj)  * zh
195            hicif (ji,jj) = hicif(ji,jj)  * zh
196            qstoif(ji,jj) = qstoif(ji,jj) * zh
197            frld  (ji,jj) = ( frld(ji,jj) + ( zh - 1.0 ) ) / zh
198         END DO
199      END DO
200
201      IF(ln_ctl) THEN
202         CALL prt_ctl( tab2d_1=hicif , clinfo1=' lim_thd: hicif   : ' )
203         CALL prt_ctl( tab2d_1=hsnif , clinfo1=' lim_thd: hsnif   : ' )
204         CALL prt_ctl( tab2d_1=dmgwi , clinfo1=' lim_thd: dmgwi   : ' )
205         CALL prt_ctl( tab2d_1=qstoif, clinfo1=' lim_thd: qstoif  : ' )
206         CALL prt_ctl( tab2d_1=frld  , clinfo1=' lim_thd: frld    : ' )
207      ENDIF
208
209     
210      !-------------------------------!
211      !   Thermodynamics of sea ice   !
212      !-------------------------------!
213     
214      !      Partial computation of forcing for the thermodynamic sea ice model.
215      !--------------------------------------------------------------------------
216
217!$OMP PARALLEL DO schedule(static) private(jj,ji,zthsnice,zindb,zinda,zfricp,zfric_u,zfntlat,zpareff)
218      DO jj = 1, jpj
219         DO ji = 1, jpi
220            zthsnice       = hsnif(ji,jj) + hicif(ji,jj)
221            zindb          = tms(ji,jj) * ( 1.0 - MAX( rzero , SIGN( rone , - zthsnice ) ) ) 
222            pfrld(ji,jj)   = frld(ji,jj)
223            zfricp         = 1.0 - frld(ji,jj)
224            zinda          = 1.0 - MAX( rzero , SIGN( rone , - zfricp ) )
225           
226            !  solar irradiance transmission at the mixed layer bottom and used in the lead heat budget
227            thcm(ji,jj)    = 0.e0 
228           
229            !  net downward heat flux from the ice to the ocean, expressed as a function of ocean
230            !  temperature and turbulent mixing (McPhee, 1992)
231            zfric_u        = MAX ( MIN( SQRT( ust2s(ji,jj) ) , zfric_umax ) , zfric_umin )  ! friction velocity
232            fdtcn(ji,jj)  = zindb * rau0 * rcp * 0.006  * zfric_u * ( sst_m(ji,jj) + rt0 - tfu(ji,jj) ) 
233            qdtcn(ji,jj)  = zindb * fdtcn(ji,jj) * frld(ji,jj) * rdt_ice
234                       
235            !  partial computation of the lead energy budget (qldif)
236            IF( ln_cpl ) THEN
237               qldif(ji,jj)   = tms(ji,jj) * rdt_ice                                                  &
238                  &    * (   ( qsr_tot(ji,jj) - qsr_ice(ji,jj,1) * zfricp ) * ( 1.0 - thcm(ji,jj) )   &
239                  &        + ( qns_tot(ji,jj) - qns_ice(ji,jj,1) * zfricp )                           &
240                  &        + frld(ji,jj) * ( fdtcn(ji,jj) + ( 1.0 - zindb ) * fsbbq(ji,jj) )   )
241            ELSE
242               qldif(ji,jj)   = tms(ji,jj) * rdt_ice * frld(ji,jj)                    &
243                  &                        * (  qsr(ji,jj) * ( 1.0 - thcm(ji,jj) )    &
244                  &                           + qns(ji,jj)  +  fdtcn(ji,jj)           &
245                  &                           + ( 1.0 - zindb ) * fsbbq(ji,jj)      )
246            ENDIF
247            !  parlat : percentage of energy used for lateral ablation (0.0)
248            zfntlat        = 1.0 - MAX( rzero , SIGN( rone ,  - qldif(ji,jj) ) )
249            zpareff        = 1.0 + ( parlat - 1.0 ) * zinda * zfntlat
250            zqlbsbq(ji,jj) = qldif(ji,jj) * ( 1.0 - zpareff ) / MAX( (1.0 - frld(ji,jj)) * rdt_ice , epsi16 )
251            qldif  (ji,jj) = zpareff *  qldif(ji,jj)
252            qdtcn  (ji,jj) = zpareff * qdtcn(ji,jj)
253           
254            !  energy needed to bring ocean surface layer until its freezing
255            qcmif  (ji,jj) =  rau0 * rcp * e3t_m(ji,jj) * ( tfu(ji,jj) - sst_m(ji,jj) - rt0 ) * ( 1 - zinda )
256           
257            !  calculate oceanic heat flux.
258            fbif   (ji,jj) = zindb * (  fsbbq(ji,jj) / MAX( (1.0 - frld(ji,jj)) , epsi20 ) + fdtcn(ji,jj) )
259           
260            ! computation of the thermodynamic ice production (only needed for output)
261            hicifp(ji,jj) = hicif(ji,jj) * ( 1.0 - frld(ji,jj) )
262         END DO
263      END DO
264     
265      !         Select icy points and fulfill arrays for the vectorial grid.
266      !----------------------------------------------------------------------
267      nbpb = 0
268      DO jj = 1, jpj
269         DO ji = 1, jpi
270            IF ( frld(ji,jj) < 1.0 ) THEN     
271               nbpb      = nbpb + 1
272               npb(nbpb) = (jj - 1) * jpi + ji
273            ENDIF
274         END DO
275      END DO
276
277      IF(ln_ctl) THEN
278         CALL prt_ctl(tab2d_1=pfrld, clinfo1=' lim_thd: pfrld   : ', tab2d_2=thcm   , clinfo2='  thcm    : ')
279         CALL prt_ctl(tab2d_1=fdtcn, clinfo1=' lim_thd: fdtcn   : ', tab2d_2=qdtcn  , clinfo2='  qdtcn   : ')
280         CALL prt_ctl(tab2d_1=qldif, clinfo1=' lim_thd: qldif   : ', tab2d_2=zqlbsbq, clinfo2='  zqlbsbq : ')
281         CALL prt_ctl(tab2d_1=qcmif, clinfo1=' lim_thd: qcmif   : ', tab2d_2=fbif   , clinfo2='  fbif    : ')
282         zmsk(:,:,1) = tms(:,:)
283         CALL prt_ctl(tab2d_1=qcmif , clinfo1=' lim_thd: qcmif  : ', mask1=zmsk)
284         CALL prt_ctl(tab2d_1=hicifp, clinfo1=' lim_thd: hicifp : ')
285         WRITE(charout, FMT="('lim_thd: nbpb = ',I4)") nbpb
286         CALL prt_ctl_info(charout)
287      ENDIF
288     
289     
290      ! If there is no ice, do nothing. Otherwise, compute Top and Bottom accretion/ablation
291      !------------------------------------------------------------------------------------
292
293      IF( nbpb > 0 ) THEN
294         !   
295         !  put the variable in a 1-D array for thermodynamics process
296         CALL tab_2d_1d_2( nbpb, frld_1d    (1:nbpb)     , frld           , jpi, jpj, npb(1:nbpb) )
297         CALL tab_2d_1d_2( nbpb, h_ice_1d   (1:nbpb)     , hicif          , jpi, jpj, npb(1:nbpb) )
298         CALL tab_2d_1d_2( nbpb, h_snow_1d  (1:nbpb)     , hsnif          , jpi, jpj, npb(1:nbpb) )
299         CALL tab_2d_1d_2( nbpb, sist_1d    (1:nbpb)     , sist           , jpi, jpj, npb(1:nbpb) )
300         CALL tab_2d_1d_2( nbpb, tbif_1d    (1:nbpb , 1 ), tbif(:,:,1)    , jpi, jpj, npb(1:nbpb) )
301         CALL tab_2d_1d_2( nbpb, tbif_1d    (1:nbpb , 2 ), tbif(:,:,2)    , jpi, jpj, npb(1:nbpb) )
302         CALL tab_2d_1d_2( nbpb, tbif_1d    (1:nbpb , 3 ), tbif(:,:,3)    , jpi, jpj, npb(1:nbpb) )
303         CALL tab_2d_1d_2( nbpb, qsr_ice_1d (1:nbpb)     , qsr_ice(:,:,1) , jpi, jpj, npb(1:nbpb) )
304         CALL tab_2d_1d_2( nbpb, fr1_i0_1d  (1:nbpb)     , fr1_i0         , jpi, jpj, npb(1:nbpb) )
305         CALL tab_2d_1d_2( nbpb, fr2_i0_1d  (1:nbpb)     , fr2_i0         , jpi, jpj, npb(1:nbpb) )
306         CALL tab_2d_1d_2( nbpb,  qns_ice_1d(1:nbpb)     ,  qns_ice(:,:,1), jpi, jpj, npb(1:nbpb) )
307         CALL tab_2d_1d_2( nbpb, dqns_ice_1d(1:nbpb)     , dqns_ice(:,:,1), jpi, jpj, npb(1:nbpb) )
308         IF( .NOT. ln_cpl ) THEN
309            CALL tab_2d_1d_2( nbpb, qla_ice_1d (1:nbpb)     ,  qla_ice(:,:,1), jpi, jpj, npb(1:nbpb) )
310            CALL tab_2d_1d_2( nbpb, dqla_ice_1d(1:nbpb)     , dqla_ice(:,:,1), jpi, jpj, npb(1:nbpb) )
311         ENDIF
312         CALL tab_2d_1d_2( nbpb, tfu_1d     (1:nbpb)     , tfu        , jpi, jpj, npb(1:nbpb) )
313         CALL tab_2d_1d_2( nbpb, sprecip_1d (1:nbpb)     , sprecip    , jpi, jpj, npb(1:nbpb) ) 
314         CALL tab_2d_1d_2( nbpb, fbif_1d    (1:nbpb)     , fbif       , jpi, jpj, npb(1:nbpb) )
315         CALL tab_2d_1d_2( nbpb, thcm_1d    (1:nbpb)     , thcm       , jpi, jpj, npb(1:nbpb) )
316         CALL tab_2d_1d_2( nbpb, qldif_1d   (1:nbpb)     , qldif      , jpi, jpj, npb(1:nbpb) )
317         CALL tab_2d_1d_2( nbpb, qstbif_1d  (1:nbpb)     , qstoif     , jpi, jpj, npb(1:nbpb) )
318         CALL tab_2d_1d_2( nbpb, rdm_ice_1d (1:nbpb)     , rdm_ice    , jpi, jpj, npb(1:nbpb) )
319         CALL tab_2d_1d_2( nbpb, rdq_ice_1d (1:nbpb)     , rdq_ice    , jpi, jpj, npb(1:nbpb) )
320         CALL tab_2d_1d_2( nbpb, dmgwi_1d   (1:nbpb)     , dmgwi      , jpi, jpj, npb(1:nbpb) )
321         CALL tab_2d_1d_2( nbpb, rdm_snw_1d (1:nbpb)     , rdm_snw    , jpi, jpj, npb(1:nbpb) )
322         CALL tab_2d_1d_2( nbpb, rdq_snw_1d (1:nbpb)     , rdq_snw    , jpi, jpj, npb(1:nbpb) )
323         CALL tab_2d_1d_2( nbpb, qlbbq_1d   (1:nbpb)     , zqlbsbq    , jpi, jpj, npb(1:nbpb) )
324         !
325         CALL lim_thd_zdf_2( 1, nbpb )       !  compute ice growth
326         !
327         !  back to the geographic grid.
328         CALL tab_1d_2d_2( nbpb, frld       , npb, frld_1d   (1:nbpb)     , jpi, jpj )
329         CALL tab_1d_2d_2( nbpb, hicif      , npb, h_ice_1d  (1:nbpb)     , jpi, jpj )
330         CALL tab_1d_2d_2( nbpb, hsnif      , npb, h_snow_1d (1:nbpb)     , jpi, jpj )
331         CALL tab_1d_2d_2( nbpb, sist       , npb, sist_1d   (1:nbpb)     , jpi, jpj )
332         CALL tab_1d_2d_2( nbpb, tbif(:,:,1), npb, tbif_1d   (1:nbpb , 1 ), jpi, jpj )   
333         CALL tab_1d_2d_2( nbpb, tbif(:,:,2), npb, tbif_1d   (1:nbpb , 2 ), jpi, jpj )   
334         CALL tab_1d_2d_2( nbpb, tbif(:,:,3), npb, tbif_1d   (1:nbpb , 3 ), jpi, jpj )   
335         CALL tab_1d_2d_2( nbpb, fscmbq     , npb, fscbq_1d  (1:nbpb)     , jpi, jpj )
336         CALL tab_1d_2d_2( nbpb, ffltbif    , npb, fltbif_1d (1:nbpb)     , jpi, jpj )
337         CALL tab_1d_2d_2( nbpb, fstric     , npb, fstbif_1d (1:nbpb)     , jpi, jpj )
338         CALL tab_1d_2d_2( nbpb, qldif      , npb, qldif_1d  (1:nbpb)     , jpi, jpj )
339         CALL tab_1d_2d_2( nbpb, qfvbq      , npb, qfvbq_1d  (1:nbpb)     , jpi, jpj )
340         CALL tab_1d_2d_2( nbpb, qstoif     , npb, qstbif_1d (1:nbpb)     , jpi, jpj )
341         CALL tab_1d_2d_2( nbpb, rdm_ice    , npb, rdm_ice_1d(1:nbpb)     , jpi, jpj )
342         CALL tab_1d_2d_2( nbpb, rdq_ice    , npb, rdq_ice_1d(1:nbpb)     , jpi, jpj )
343         CALL tab_1d_2d_2( nbpb, dmgwi      , npb, dmgwi_1d  (1:nbpb)     , jpi, jpj )
344         CALL tab_1d_2d_2( nbpb, rdm_snw    , npb, rdm_snw_1d(1:nbpb)     , jpi, jpj )
345         CALL tab_1d_2d_2( nbpb, rdq_snw    , npb, rdq_snw_1d(1:nbpb)     , jpi, jpj )
346         CALL tab_1d_2d_2( nbpb, zdvosif    , npb, dvsbq_1d  (1:nbpb)     , jpi, jpj )
347         CALL tab_1d_2d_2( nbpb, zdvobif    , npb, dvbbq_1d  (1:nbpb)     , jpi, jpj )
348         CALL tab_1d_2d_2( nbpb, zdvomif    , npb, rdvomif_1d(1:nbpb)     , jpi, jpj )
349         CALL tab_1d_2d_2( nbpb, zdvolif    , npb, dvlbq_1d  (1:nbpb)     , jpi, jpj )
350         CALL tab_1d_2d_2( nbpb, zdvonif    , npb, dvnbq_1d  (1:nbpb)     , jpi, jpj ) 
351         CALL tab_1d_2d_2( nbpb, qsr_ice(:,:,1), npb, qsr_ice_1d(1:nbpb)  , jpi, jpj )
352         CALL tab_1d_2d_2( nbpb, qns_ice(:,:,1), npb, qns_ice_1d(1:nbpb)  , jpi, jpj )
353         IF( .NOT. ln_cpl )   CALL tab_1d_2d_2( nbpb, qla_ice(:,:,1), npb, qla_ice_1d(1:nbpb), jpi, jpj )
354         !
355      ENDIF
356
357      ! Up-date sea ice thickness
358      !--------------------------
359!$OMP PARALLEL DO schedule(static) private(jj,ji)
360      DO jj = 1, jpj
361         DO ji = 1, jpi
362            phicif(ji,jj) = hicif(ji,jj) 
363            hicif(ji,jj)  = hicif(ji,jj) *  ( rone -  MAX( rzero, SIGN( rone, - ( 1.0 - frld(ji,jj) ) ) ) )
364         END DO
365      END DO
366
367     
368      ! Tricky trick : add 2 to frld in the Southern Hemisphere
369      !--------------------------------------------------------
370      IF( fcor(1,1) < 0.e0 ) THEN
371!$OMP PARALLEL DO schedule(static) private(jj,ji)
372         DO jj = 1, njeqm1
373            DO ji = 1, jpi
374               frld(ji,jj) = frld(ji,jj) + 2.0
375            END DO
376         END DO
377      ENDIF
378
379      CALL lbc_lnk( frld , 'T', 1. )     
380     
381      ! Select points for lateral accretion (this occurs when heat exchange
382      ! between ice and ocean is negative; ocean losing heat)
383      !-----------------------------------------------------------------
384      nbpac = 0
385      DO jj = 1, jpj
386         DO ji = 1, jpi
387!i yes!     IF ( ( qcmif(ji,jj) - qldif(ji,jj) ) > 0.e0 ) THEN
388            IF ( tms(ji,jj) * ( qcmif(ji,jj) - qldif(ji,jj) ) > 0.e0 ) THEN
389               nbpac = nbpac + 1
390               npac( nbpac ) = (jj - 1) * jpi + ji
391            ENDIF
392         END DO
393      END DO
394     
395      IF(ln_ctl) THEN
396         CALL prt_ctl(tab2d_1=phicif, clinfo1=' lim_thd: phicif  : ', tab2d_2=hicif, clinfo2=' hicif : ')
397         WRITE(charout, FMT="('lim_thd: nbpac = ',I4)") nbpac
398         CALL prt_ctl_info(charout)
399      ENDIF
400
401
402      ! If ocean gains heat do nothing ; otherwise, one performs lateral accretion
403      !--------------------------------------------------------------------------------
404      IF( nbpac > 0 ) THEN
405         !
406         zlicegr(:,:) = rdm_ice(:,:)      ! to output the lateral sea-ice growth
407         !...Put the variable in a 1-D array for lateral accretion
408         CALL tab_2d_1d_2( nbpac, frld_1d   (1:nbpac)     , frld       , jpi, jpj, npac(1:nbpac) )
409         CALL tab_2d_1d_2( nbpac, h_snow_1d (1:nbpac)     , hsnif      , jpi, jpj, npac(1:nbpac) )
410         CALL tab_2d_1d_2( nbpac, h_ice_1d  (1:nbpac)     , hicif      , jpi, jpj, npac(1:nbpac) )
411         CALL tab_2d_1d_2( nbpac, tbif_1d   (1:nbpac , 1 ), tbif(:,:,1), jpi, jpj, npac(1:nbpac) )   
412         CALL tab_2d_1d_2( nbpac, tbif_1d   (1:nbpac , 2 ), tbif(:,:,2), jpi, jpj, npac(1:nbpac) )   
413         CALL tab_2d_1d_2( nbpac, tbif_1d   (1:nbpac , 3 ), tbif(:,:,3), jpi, jpj, npac(1:nbpac) )   
414         CALL tab_2d_1d_2( nbpac, qldif_1d  (1:nbpac)     , qldif      , jpi, jpj, npac(1:nbpac) )
415         CALL tab_2d_1d_2( nbpac, qcmif_1d  (1:nbpac)     , qcmif      , jpi, jpj, npac(1:nbpac) )
416         CALL tab_2d_1d_2( nbpac, qstbif_1d (1:nbpac)     , qstoif     , jpi, jpj, npac(1:nbpac) )
417         CALL tab_2d_1d_2( nbpac, rdm_ice_1d(1:nbpac)     , rdm_ice    , jpi, jpj, npac(1:nbpac) )
418         CALL tab_2d_1d_2( nbpac, rdq_ice_1d(1:nbpac)     , rdq_ice    , jpi, jpj, npac(1:nbpac) )
419         CALL tab_2d_1d_2( nbpac, dvlbq_1d  (1:nbpac)     , zdvolif    , jpi, jpj, npac(1:nbpac) )
420         CALL tab_2d_1d_2( nbpac, tfu_1d    (1:nbpac)     , tfu        , jpi, jpj, npac(1:nbpac) )
421         !
422         CALL lim_thd_lac_2( 1 , nbpac )         ! lateral accretion routine.
423         !
424         !   back to the geographic grid
425         CALL tab_1d_2d_2( nbpac, frld       , npac(1:nbpac), frld_1d   (1:nbpac)     , jpi, jpj )
426         CALL tab_1d_2d_2( nbpac, hsnif      , npac(1:nbpac), h_snow_1d (1:nbpac)     , jpi, jpj )
427         CALL tab_1d_2d_2( nbpac, hicif      , npac(1:nbpac), h_ice_1d  (1:nbpac)     , jpi, jpj )
428         CALL tab_1d_2d_2( nbpac, tbif(:,:,1), npac(1:nbpac), tbif_1d   (1:nbpac , 1 ), jpi, jpj )
429         CALL tab_1d_2d_2( nbpac, tbif(:,:,2), npac(1:nbpac), tbif_1d   (1:nbpac , 2 ), jpi, jpj )
430         CALL tab_1d_2d_2( nbpac, tbif(:,:,3), npac(1:nbpac), tbif_1d   (1:nbpac , 3 ), jpi, jpj )
431         CALL tab_1d_2d_2( nbpac, qstoif     , npac(1:nbpac), qstbif_1d (1:nbpac)     , jpi, jpj )
432         CALL tab_1d_2d_2( nbpac, rdm_ice    , npac(1:nbpac), rdm_ice_1d(1:nbpac)     , jpi, jpj )
433         CALL tab_1d_2d_2( nbpac, rdq_ice    , npac(1:nbpac), rdq_ice_1d(1:nbpac)     , jpi, jpj )
434         CALL tab_1d_2d_2( nbpac, zdvolif    , npac(1:nbpac), dvlbq_1d  (1:nbpac)     , jpi, jpj )
435         !
436      ENDIF
437       
438       
439      ! Recover frld values between 0 and 1 in the Southern Hemisphere (tricky trick)
440      ! Update daily thermodynamic ice production.   
441      !------------------------------------------------------------------------------
442!$OMP PARALLEL DO schedule(static) private(jj,ji)
443      DO jj = 1, jpj
444         DO ji = 1, jpi
445            frld  (ji,jj) = MIN( frld(ji,jj), ABS( frld(ji,jj) - 2.0 ) )
446            fr_i  (ji,jj) = 1.0 - frld(ji,jj) 
447            hicifp(ji,jj) = hicif(ji,jj) * fr_i(ji,jj) - hicifp(ji,jj)
448            ztmp(ji,jj) = 1. - pfrld(ji,jj)                              ! fraction of ice after the dynamic, before the thermodynamic
449         END DO
450      END DO
451
452      ! Outputs
453      !--------------------------------------------------------------------------------
454      IF( iom_use('ist_cea'    ) )   CALL iom_put( 'ist_cea', (sist(:,:) - rt0) * ztmp(:,:) )   ! Ice surface temperature   [Celius]
455      IF( iom_use('qsr_ai_cea' ) )   CALL iom_put( 'qsr_ai_cea', qsr_ice(:,:,1) * ztmp(:,:) )   ! Solar flux over the ice     [W/m2]
456      IF( iom_use('qns_ai_cea' ) )   CALL iom_put( 'qns_ai_cea', qns_ice(:,:,1) * ztmp(:,:) )   ! Non-solar flux over the ice [W/m2]
457      IF( iom_use('qla_ai_cea' ) .AND. .NOT. ln_cpl ) &
458         &                           CALL iom_put( 'qla_ai_cea', qla_ice(:,:,1) * ztmp(:,:) )   ! Latent flux over the ice [W/m2]
459      !
460      IF( iom_use('snowthic_cea'))   CALL iom_put( 'snowthic_cea', hsnif  (:,:) * fr_i(:,:) )   ! Snow thickness           [m]
461      IF( iom_use('icethic_cea' ))   CALL iom_put( 'icethic_cea' , hicif  (:,:) * fr_i(:,:) )   ! Ice thickness            [m]
462      zztmp = 1.0 / rdt_ice
463      IF( iom_use('iceprod_cea') )   CALL iom_put( 'iceprod_cea' , hicifp (:,:) * zztmp     )   ! Ice produced             [m/s]
464      IF( iom_use('iiceconc'   ) )   CALL iom_put( 'iiceconc'    , fr_i(:,:)                )   ! Ice concentration        [-]
465      IF( iom_use('snowmel_cea') )   CALL iom_put( 'snowmel_cea' , rdm_snw(:,:) * zztmp     )   ! Snow melt                [kg/m2/s]
466      zztmp = rhoic / rdt_ice
467      IF( iom_use('sntoice_cea') )   CALL iom_put( 'sntoice_cea' , zdvonif(:,:) * zztmp     ) ! Snow to Ice transformation [kg/m2/s]
468      IF( iom_use('ticemel_cea') )   CALL iom_put( 'ticemel_cea' , zdvosif(:,:) * zztmp     )   ! Melt at Sea Ice top      [kg/m2/s]
469      IF( iom_use('bicemel_cea') )   CALL iom_put( 'bicemel_cea' , zdvomif(:,:) * zztmp     )   ! Melt at Sea Ice bottom   [kg/m2/s]
470      IF( iom_use('licepro_cea') ) THEN
471         zlicegr(:,:) = MAX( 0.e0, rdm_ice(:,:)-zlicegr(:,:) )
472                                     CALL iom_put( 'licepro_cea' , zlicegr(:,:) * zztmp     )   ! Lateral sea ice growth   [kg/m2/s]
473      ENDIF
474      !
475      ! Compute the Eastward & Northward sea-ice transport
476      IF( iom_use('u_imasstr') ) THEN
477         zztmp = 0.25 * rhoic
478!$OMP PARALLEL DO schedule(static) private(jj,ji,zuice_m,zhice_u)
479         DO jj = 1, jpjm1 
480            DO ji = 1, jpim1   ! NO vector opt.
481               ! Ice velocities, volume & transport at U-points
482               zuice_m = u_ice(ji+1,jj+1) + u_ice(ji+1,jj )
483               zhice_u = hicif(ji,jj)*e2t(ji,jj)*fr_i(ji,jj) + hicif(ji+1,jj  )*e2t(ji+1,jj  )*fr_i(ji+1,jj  )
484               zu_imasstr(ji,jj) = zztmp * zhice_u * zuice_m 
485            END DO
486         END DO
487         CALL lbc_lnk( zu_imasstr, 'U', -1. )
488         CALL iom_put( 'u_imasstr',  zu_imasstr(:,:) )   ! Ice transport along i-axis at U-point [kg/s]
489      ENDIF
490      IF( iom_use('v_imasstr') ) THEN
491         zztmp = 0.25 * rhoic
492!$OMP PARALLEL DO schedule(static) private(jj,ji,zvice_m,zhice_v)
493         DO jj = 1, jpjm1 
494            DO ji = 1, jpim1   ! NO vector opt.
495               ! Ice velocities, volume & transport at V-points
496               zvice_m = v_ice(ji+1,jj+1) + v_ice(ji ,jj+1)
497               zhice_v = hicif(ji,jj)*e1t(ji,jj)*fr_i(ji,jj) + hicif(ji  ,jj+1)*e1t(ji  ,jj+1)*fr_i(ji  ,jj+1)
498               zv_imasstr(ji,jj) = zztmp * zhice_v * zvice_m 
499            END DO
500         END DO
501         CALL lbc_lnk( zv_imasstr, 'V', -1. )
502         CALL iom_put( 'v_imasstr',  zv_imasstr(:,:) )   ! Ice transport along j-axis at V-point [kg/s]
503      ENDIF
504
505      !! Fram Strait sea-ice transport (sea-ice + snow)  (in ORCA2 = 5 points)
506      IF( iom_use('fram_trans') .and. cp_cfg == "orca" .AND. jp_cfg == 2 ) THEN    ! ORCA R2 configuration
507!$OMP PARALLEL DO schedule(static) private(jj,ji,zrhoij,zrhoijm1,ztr_fram)
508         DO jj = mj0(137), mj1(137) ! B grid
509            IF( mj0(jj-1) >= nldj ) THEN
510               DO ji = MAX(mi0(134),nldi), MIN(mi1(138),nlei)
511                  zrhoij    = e1t(ji,jj  ) * fr_i(ji,jj  ) * ( rhoic*hicif(ji,jj  ) + rhosn*hsnif(ji,jj  ) ) 
512                  zrhoijm1  = e1t(ji,jj-1) * fr_i(ji,jj-1) * ( rhoic*hicif(ji,jj-1) + rhosn*hsnif(ji,jj-1) ) 
513                  ztr_fram  = ztr_fram - 0.25 * ( v_ice(ji,jj)+ v_ice(ji+1,jj) ) * ( zrhoij + zrhoijm1 )
514               END DO
515            ENDIF
516         END DO
517         IF( lk_mpp )   CALL mpp_sum( ztr_fram )
518         CALL iom_put( 'fram_trans', ztr_fram )   ! Ice transport through Fram strait     [kg/s]
519      ENDIF
520
521      IF( iom_use('ice_pres') .OR. iom_use('ist_ipa') .OR. iom_use('uice_ipa') .OR. iom_use('vice_ipa') ) THEN
522!! ce     ztmp(:,:) = 1. - AINT( frld(:,:), wp )                        ! return 1 as soon as there is ice
523!! ce     A big warning because the model crashes on IDRIS/IBM SP6 with xlf 13.1.0.3, see ticket #761
524!! ce     We Unroll the loop and everything works fine     
525!$OMP PARALLEL DO schedule(static) private(jj,ji)
526         DO jj = 1, jpj
527            DO ji = 1, jpi
528               ztmp(ji,jj) = 1. - AINT( frld(ji,jj), wp )                ! return 1 as soon as there is ice
529            END DO
530         END DO
531         !
532         IF( iom_use('ice_pres') ) CALL iom_put( 'ice_pres', ztmp                            )   ! Ice presence                 [-]
533         IF( iom_use('ist_ipa' ) ) CALL iom_put( 'ist_ipa' , ( sist(:,:) - rt0 ) * ztmp(:,:) )   ! Ice surface temperature [Celius]
534         IF( iom_use('uice_ipa') ) CALL iom_put( 'uice_ipa', u_ice(:,:) * ztmp(:,:) ) ! Ice velocity along i-axis at I-point  [m/s]
535         IF( iom_use('vice_ipa') ) CALL iom_put( 'vice_ipa', v_ice(:,:) * ztmp(:,:) ) ! Ice velocity along j-axis at I-point  [m/s]
536      ENDIF
537
538      IF(ln_ctl) THEN
539         CALL prt_ctl_info(' lim_thd  end  ')
540         CALL prt_ctl( tab2d_1=hicif      , clinfo1=' lim_thd: hicif   : ', tab2d_2=hsnif , clinfo2=' hsnif  : ' )
541         CALL prt_ctl( tab2d_1=frld       , clinfo1=' lim_thd: frld    : ', tab2d_2=hicifp, clinfo2=' hicifp : ' )
542         CALL prt_ctl( tab2d_1=phicif     , clinfo1=' lim_thd: phicif  : ', tab2d_2=pfrld , clinfo2=' pfrld  : ' )
543         CALL prt_ctl( tab2d_1=sist       , clinfo1=' lim_thd: sist    : ' )
544         CALL prt_ctl( tab2d_1=tbif(:,:,1), clinfo1=' lim_thd: tbif 1  : ' )
545         CALL prt_ctl( tab2d_1=tbif(:,:,2), clinfo1=' lim_thd: tbif 2  : ' )
546         CALL prt_ctl( tab2d_1=tbif(:,:,3), clinfo1=' lim_thd: tbif 3  : ' )
547         CALL prt_ctl( tab2d_1=fdtcn      , clinfo1=' lim_thd: fdtcn   : ', tab2d_2=qdtcn , clinfo2=' qdtcn  : ' )
548         CALL prt_ctl( tab2d_1=qstoif     , clinfo1=' lim_thd: qstoif  : ', tab2d_2=fsbbq , clinfo2=' fsbbq  : ' )
549      ENDIF
550       !
551      CALL wrk_dealloc( jpi, jpj, ztmp, zqlbsbq, zlicegr, zdvosif, zdvobif, zdvolif, zdvonif, zdvomif, zu_imasstr, zv_imasstr )
552      CALL wrk_dealloc( jpi, jpj, jpk, zmsk )
553      !
554    END SUBROUTINE lim_thd_2
555
556
557    SUBROUTINE lim_thd_init_2
558      !!-------------------------------------------------------------------
559      !!                   ***  ROUTINE lim_thd_init_2 ***
560      !!                 
561      !! ** Purpose :   Physical constants and parameters linked to the ice
562      !!      thermodynamics
563      !!
564      !! ** Method  :   Read the namicethd namelist and check the ice-thermo
565      !!       parameter values called at the first timestep (nit000)
566      !!
567      !! ** input   :   Namelist namicether
568      !!-------------------------------------------------------------------
569      INTEGER  ::   ios                 ! Local integer output status for namelist read
570      NAMELIST/namicethd/ hmelt , hiccrit, hicmin, hiclim, amax  ,        &
571         &                swiqst, sbeta  , parlat, hakspl, hibspl, exld,  &
572         &                hakdif, hnzst  , thth  , parsub, alphs
573      !!-------------------------------------------------------------------
574                   
575      REWIND( numnam_ice_ref )              ! Namelist namicethd in reference namelist : Ice thermodynamics
576      READ  ( numnam_ice_ref, namicethd, IOSTAT = ios, ERR = 901)
577901   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namicethd in reference namelist', lwp )
578
579      REWIND( numnam_ice_cfg )              ! Namelist namicethd in configuration namelist : Ice thermodynamics
580      READ  ( numnam_ice_cfg, namicethd, IOSTAT = ios, ERR = 902 )
581902   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namicethd in configuration namelist', lwp )
582      IF(lwm) WRITE ( numoni, namicethd )
583
584      IF( ln_cpl .AND. parsub /= 0.0 )   CALL ctl_stop( 'In coupled mode, use parsub = 0. or send dqla' )
585      !
586      IF(lwp) THEN                          ! control print
587         WRITE(numout,*)
588         WRITE(numout,*)'lim_thd_init_2: ice parameters for ice thermodynamic computation '
589         WRITE(numout,*)'~~~~~~~~~~~~~~'
590         WRITE(numout,*)'       maximum melting at the bottom                           hmelt        = ', hmelt
591         WRITE(numout,*)'       ice thick. for lateral accretion in NH (SH)             hiccrit(1/2) = ', hiccrit
592         WRITE(numout,*)'       ice thick. corr. to max. energy stored in brine pocket  hicmin       = ', hicmin 
593         WRITE(numout,*)'       minimum ice thickness                                   hiclim       = ', hiclim 
594         WRITE(numout,*)'       maximum lead fraction                                   amax         = ', amax
595         WRITE(numout,*)'       energy stored in brine pocket (=1) or not (=0)          swiqst       = ', swiqst 
596         WRITE(numout,*)'       numerical carac. of the scheme for diffusion in ice '
597         WRITE(numout,*)'       Cranck-Nicholson (=0.5), implicit (=1), explicit (=0)   sbeta        = ', sbeta
598         WRITE(numout,*)'       percentage of energy used for lateral ablation          parlat       = ', parlat
599         WRITE(numout,*)'       slope of distr. for Hakkinen-Mellor lateral melting     hakspl       = ', hakspl 
600         WRITE(numout,*)'       slope of distribution for Hibler lateral melting        hibspl       = ', hibspl
601         WRITE(numout,*)'       exponent for leads-closure rate                         exld         = ', exld
602         WRITE(numout,*)'       coefficient for diffusions of ice and snow              hakdif       = ', hakdif
603         WRITE(numout,*)'       threshold thick. for comp. of eq. thermal conductivity  zhth         = ', thth 
604         WRITE(numout,*)'       thickness of the surf. layer in temp. computation       hnzst        = ', hnzst
605         WRITE(numout,*)'       switch for snow sublimation  (=1) or not (=0)           parsub       = ', parsub 
606         WRITE(numout,*)'       coefficient for snow density when snow ice formation    alphs        = ', alphs
607      ENDIF
608      !         
609      uscomi = 1.0 / ( 1.0 - amax )   ! inverse of minimum lead fraction
610      rcdsn = hakdif * rcdsn 
611      rcdic = hakdif * rcdic
612      !
613      IF( hsndif > 100.e0 .OR. hicdif > 100.e0 ) THEN
614         cnscg = 0.e0
615      ELSE
616         cnscg = rcpsn / rcpic   ! ratio  rcpsn/rcpic
617      ENDIF
618      !
619   END SUBROUTINE lim_thd_init_2
620
621#else
622   !!----------------------------------------------------------------------
623   !!   Default option          Dummy module       NO LIM 2.0 sea-ice model
624   !!----------------------------------------------------------------------
625CONTAINS
626   SUBROUTINE lim_thd_2         ! Dummy routine
627   END SUBROUTINE lim_thd_2
628#endif
629
630   !!======================================================================
631END MODULE limthd_2
Note: See TracBrowser for help on using the repository browser.