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.
sbcblk_clio.F90 in branches/UKMO/dev_r5518_GO6_under_ice_relax_dr_hook/NEMOGCM/NEMO/OPA_SRC/SBC – NEMO

source: branches/UKMO/dev_r5518_GO6_under_ice_relax_dr_hook/NEMOGCM/NEMO/OPA_SRC/SBC/sbcblk_clio.F90 @ 11738

Last change on this file since 11738 was 11738, checked in by marc, 5 years ago

The Dr Hook changes from my perl code.

File size: 60.0 KB
Line 
1MODULE sbcblk_clio
2   !!======================================================================
3   !!                   ***  MODULE  sbcblk_clio  ***
4   !! Ocean forcing:  bulk thermohaline forcing of the ocean (or ice)
5   !!=====================================================================
6   !! History :  OPA  !  1997-06 (Louvain-La-Neuve)  Original code
7   !!                 !  2001-04 (C. Ethe) add flx_blk_declin
8   !!   NEMO     2.0  !  2002-08 (C. Ethe, G. Madec) F90: Free form and module
9   !!            3.0  !  2008-03 (C. Talandier, G. Madec) surface module + LIM3
10   !!            3.2  !  2009-04 (B. Lemaire) Introduce iom_put
11   !!----------------------------------------------------------------------
12
13   !!----------------------------------------------------------------------
14   !!   sbc_blk_clio     : CLIO bulk formulation: read and update required input fields
15   !!   blk_clio_oce     : ocean CLIO bulk formulea: compute momentum, heat and freswater fluxes for the ocean
16   !!   blk_ice_clio     : ice   CLIO bulk formulea: compute momentum, heat and freswater fluxes for the sea-ice
17   !!   blk_clio_qsr_oce : shortwave radiation for ocean computed from the cloud cover
18   !!   blk_clio_qsr_ice : shortwave radiation for ice   computed from the cloud cover
19   !!   flx_blk_declin   : solar declination
20   !!----------------------------------------------------------------------
21   USE oce            ! ocean dynamics and tracers
22   USE dom_oce        ! ocean space and time domain
23   USE phycst         ! physical constants
24   USE fldread        ! read input fields
25   USE sbc_oce        ! Surface boundary condition: ocean fields
26   USE iom            ! I/O manager library
27   USE in_out_manager ! I/O manager
28   USE lib_mpp        ! distribued memory computing library
29   USE wrk_nemo       ! work arrays
30   USE timing         ! Timing
31   USE lbclnk         ! ocean lateral boundary conditions (or mpp link)
32   USE lib_fortran    ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined) 
33
34   USE albedo
35   USE prtctl          ! Print control
36#if defined key_lim3 
37   USE ice
38   USE sbc_ice         ! Surface boundary condition: ice fields
39   USE limthd_dh       ! for CALL lim_thd_snwblow
40#elif defined key_lim2
41   USE ice_2
42   USE sbc_ice         ! Surface boundary condition: ice fields
43   USE par_ice_2       ! Surface boundary condition: ice fields
44#endif
45
46   USE yomhook, ONLY: lhook, dr_hook
47   USE parkind1, ONLY: jprb, jpim
48
49   IMPLICIT NONE
50   PRIVATE
51
52   PUBLIC sbc_blk_clio        ! routine called by sbcmod.F90
53#if defined key_lim2 || defined key_lim3
54   PUBLIC blk_ice_clio_tau    ! routine called by sbcice_lim.F90
55   PUBLIC blk_ice_clio_flx    ! routine called by sbcice_lim.F90
56#endif
57
58   INTEGER , PARAMETER ::   jpfld   = 7           ! maximum number of files to read
59   INTEGER , PARAMETER ::   jp_utau = 1           ! index of wind stress (i-component)      (N/m2)    at U-point
60   INTEGER , PARAMETER ::   jp_vtau = 2           ! index of wind stress (j-component)      (N/m2)    at V-point
61   INTEGER , PARAMETER ::   jp_wndm = 3           ! index of 10m wind module                 (m/s)    at T-point
62   INTEGER , PARAMETER ::   jp_humi = 4           ! index of specific humidity               ( % )
63   INTEGER , PARAMETER ::   jp_ccov = 5           ! index of cloud cover                     ( % )
64   INTEGER , PARAMETER ::   jp_tair = 6           ! index of 10m air temperature             (Kelvin)
65   INTEGER , PARAMETER ::   jp_prec = 7           ! index of total precipitation (rain+snow) (Kg/m2/s)
66
67   TYPE(FLD),ALLOCATABLE,DIMENSION(:) :: sf  ! structure of input fields (file informations, fields read)
68
69   INTEGER, PARAMETER  ::   jpintsr = 24          ! number of time step between sunrise and sunset
70   !                                              ! uses for heat flux computation
71   LOGICAL ::   lbulk_init = .TRUE.               ! flag, bulk initialization done or not)
72
73   REAL(wp) ::   cai = 1.40e-3 ! best estimate of atm drag in order to get correct FS export in ORCA2-LIM
74   REAL(wp) ::   cao = 1.00e-3 ! chosen by default  ==> should depends on many things...  !!gmto be updated
75
76   REAL(wp) ::   rdtbs2      !:   
77   
78   REAL(wp), DIMENSION(19)  ::  budyko            ! BUDYKO's coefficient (cloudiness effect on LW radiation)
79   DATA budyko / 1.00, 0.98, 0.95, 0.92, 0.89, 0.86, 0.83, 0.80, 0.78, 0.75,   &
80      &          0.72, 0.69, 0.67, 0.64, 0.61, 0.58, 0.56, 0.53, 0.50 /
81   REAL(wp), DIMENSION(20)  :: tauco              ! cloud optical depth coefficient
82   DATA tauco / 6.6, 6.6, 7.0, 7.2, 7.1, 6.8, 6.5, 6.6, 7.1, 7.6,   &
83      &         6.6, 6.1, 5.6, 5.5, 5.8, 5.8, 5.6, 5.6, 5.6, 5.6 /
84   !!
85   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) ::   sbudyko      ! cloudiness effect on LW radiation
86   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) ::   stauc        ! cloud optical depth
87   
88   REAL(wp) ::   eps20  = 1.e-20   ! constant values
89   
90   !! * Substitutions
91#  include "vectopt_loop_substitute.h90"
92   !!----------------------------------------------------------------------
93   !! NEMO/OPA 4.0 , NEMO Consortium (2011)
94   !! $Id$
95   !! Software governed by the CeCILL licence     (NEMOGCM/NEMO_CeCILL.txt)
96   !!----------------------------------------------------------------------
97CONTAINS
98
99   SUBROUTINE sbc_blk_clio( kt )
100      !!---------------------------------------------------------------------
101      !!                    ***  ROUTINE sbc_blk_clio  ***
102      !!                   
103      !! ** Purpose :   provide at each time step the surface ocean fluxes
104      !!      (momentum, heat, freshwater and runoff)
105      !!
106      !! ** Method  : (1) READ each fluxes in NetCDF files:
107      !!      the i-component of the stress                (N/m2)
108      !!      the j-component of the stress                (N/m2)
109      !!      the 10m wind speed module                    (m/s)
110      !!      the 10m air temperature                      (Kelvin)
111      !!      the 10m specific humidity                    (%)
112      !!      the cloud cover                              (%)
113      !!      the total precipitation (rain+snow)          (Kg/m2/s)
114      !!              (2) CALL blk_oce_clio
115      !!
116      !!      C A U T I O N : never mask the surface stress fields
117      !!                      the stress is assumed to be in the (i,j) mesh referential
118      !!
119      !! ** Action  :   defined at each time-step at the air-sea interface
120      !!              - utau, vtau  i- and j-component of the wind stress
121      !!              - taum        wind stress module at T-point
122      !!              - wndm        10m wind module at T-point over free ocean or leads in presence of sea-ice
123      !!              - qns         non-solar heat flux including latent heat of solid
124      !!                            precip. melting and emp heat content
125      !!              - qsr         solar heat flux
126      !!              - emp         upward mass flux (evap. - precip)
127      !!              - sfx         salt flux; set to zero at nit000 but possibly non-zero
128      !!                            if ice is present (computed in limsbc(_2).F90)
129      !!----------------------------------------------------------------------
130      INTEGER, INTENT( in  ) ::   kt   ! ocean time step
131      !!
132      INTEGER  ::   ifpr, jfpr                   ! dummy indices
133      INTEGER  ::   ierr0, ierr1, ierr2, ierr3   ! return error code
134      INTEGER  ::   ios                          ! Local integer output status for namelist read
135      !!
136      CHARACTER(len=100) ::  cn_dir                            !   Root directory for location of CLIO files
137      TYPE(FLD_N), DIMENSION(jpfld) ::   slf_i                 ! array of namelist informations on the fields to read
138      TYPE(FLD_N) ::   sn_utau, sn_vtau, sn_wndm, sn_tair      ! informations about the fields to be read
139      TYPE(FLD_N) ::   sn_humi, sn_ccov, sn_prec               !   "                                 "
140      !!
141      NAMELIST/namsbc_clio/ cn_dir, sn_utau, sn_vtau, sn_wndm, sn_humi,   &
142         &                          sn_ccov, sn_tair, sn_prec
143         INTEGER(KIND=jpim), PARAMETER :: zhook_in = 0
144         INTEGER(KIND=jpim), PARAMETER :: zhook_out = 1
145         REAL(KIND=jprb)               :: zhook_handle
146
147         CHARACTER(LEN=*), PARAMETER :: RoutineName='SBC_BLK_CLIO'
148
149         IF (lhook) CALL dr_hook(RoutineName,zhook_in,zhook_handle)
150
151      !!---------------------------------------------------------------------
152
153      !                                         ! ====================== !
154      IF( kt == nit000 ) THEN                   !  First call kt=nit000  !
155         !                                      ! ====================== !
156
157         REWIND( numnam_ref )              ! Namelist namsbc_clio in reference namelist : CLIO files
158         READ  ( numnam_ref, namsbc_clio, IOSTAT = ios, ERR = 901)
159901      IF( ios /= 0 ) CALL ctl_nam ( ios , 'namsbc_clio in reference namelist', lwp )
160
161         REWIND( numnam_cfg )              ! Namelist namsbc_clio in configuration namelist : CLIO files
162         READ  ( numnam_cfg, namsbc_clio, IOSTAT = ios, ERR = 902 )
163902      IF( ios /= 0 ) CALL ctl_nam ( ios , 'namsbc_clio in configuration namelist', lwp )
164         IF(lwm) WRITE ( numond, namsbc_clio )
165
166         ! store namelist information in an array
167         slf_i(jp_utau) = sn_utau   ;   slf_i(jp_vtau) = sn_vtau   ;   slf_i(jp_wndm) = sn_wndm
168         slf_i(jp_tair) = sn_tair   ;   slf_i(jp_humi) = sn_humi
169         slf_i(jp_ccov) = sn_ccov   ;   slf_i(jp_prec) = sn_prec
170         
171         ! set sf structure
172         ALLOCATE( sf(jpfld), STAT=ierr0 )
173         IF( ierr0 > 0 )   CALL ctl_stop( 'STOP', 'sbc_blk_clio: unable to allocate sf structure' )
174         DO ifpr= 1, jpfld
175            ALLOCATE( sf(ifpr)%fnow(jpi,jpj,1) , STAT=ierr1)
176            IF( slf_i(ifpr)%ln_tint ) ALLOCATE( sf(ifpr)%fdta(jpi,jpj,1,2) , STAT=ierr2 )
177         END DO
178         IF( ierr1+ierr2 > 0 )   CALL ctl_stop( 'STOP', 'sbc_blk_clio: unable to allocate sf array structure' )
179         ! fill sf with slf_i and control print
180         CALL fld_fill( sf, slf_i, cn_dir, 'sbc_blk_clio', 'flux formulation for ocean surface boundary condition', 'namsbc_clio' )
181         
182         ! allocate sbcblk clio arrays
183         ALLOCATE( sbudyko(jpi,jpj) , stauc(jpi,jpj), STAT=ierr3 )
184         IF( ierr3 > 0 )   CALL ctl_stop( 'STOP', 'sbc_blk_clio: unable to allocate arrays' )
185         !
186         sfx(:,:) = 0._wp                       ! salt flux; zero unless ice is present (computed in limsbc(_2).F90)
187         !
188      ENDIF
189      !                                         ! ====================== !
190      !                                         !    At each time-step   !
191      !                                         ! ====================== !
192      !
193      CALL fld_read( kt, nn_fsbc, sf )                ! input fields provided at the current time-step
194      !
195      IF( MOD( kt - 1, nn_fsbc ) == 0 )   CALL blk_oce_clio( sf, sst_m )
196      !
197         IF (lhook) CALL dr_hook(RoutineName,zhook_out,zhook_handle)
198   END SUBROUTINE sbc_blk_clio
199
200
201   SUBROUTINE blk_oce_clio( sf, pst )
202      !!---------------------------------------------------------------------------
203      !!                     ***  ROUTINE blk_oce_clio  ***
204      !!                 
205      !!  ** Purpose :   Compute momentum, heat and freshwater fluxes at ocean surface
206      !!               using CLIO bulk formulea
207      !!         
208      !!  ** Method  :   The flux of heat at the ocean surfaces are derived
209      !!       from semi-empirical ( or bulk ) formulae which relate the flux to
210      !!       the properties of the surface and of the lower atmosphere. Here, we
211      !!       follow the work of Oberhuber, 1988   
212      !!               - momentum flux (stresses) directly read in files at U- and V-points
213      !!               - compute ocean/ice albedos (call albedo_oce/albedo_ice) 
214      !!               - compute shortwave radiation for ocean (call blk_clio_qsr_oce)
215      !!               - compute long-wave radiation for the ocean
216      !!               - compute the turbulent heat fluxes over the ocean
217      !!               - deduce the evaporation over the ocean
218      !!  ** Action  :   Fluxes over the ocean:
219      !!               - utau, vtau  i- and j-component of the wind stress
220      !!               - taum        wind stress module at T-point
221      !!               - wndm        10m wind module at T-point over free ocean or leads in presence of sea-ice
222      !!               - qns         non-solar heat flux including latent heat of solid
223      !!                             precip. melting and emp heat content
224      !!               - qsr         solar heat flux
225      !!               - emp         suface mass flux (evap.-precip.)
226      !!  ** Nota    :   sf has to be a dummy argument for AGRIF on NEC
227      !!----------------------------------------------------------------------
228      TYPE(fld), INTENT(in), DIMENSION(:)       ::   sf    ! input data
229      REAL(wp) , INTENT(in), DIMENSION(jpi,jpj) ::   pst   ! surface temperature                      [Celcius]
230      !!
231      INTEGER  ::   ji, jj   ! dummy loop indices
232      !!
233      REAL(wp) ::   zrhova, zcsho, zcleo, zcldeff               ! temporary scalars
234      REAL(wp) ::   zqsato, zdteta, zdeltaq, ztvmoy, zobouks    !    -         -
235      REAL(wp) ::   zpsims, zpsihs, zpsils, zobouku, zxins, zpsimu   !    -         -
236      REAL(wp) ::   zpsihu, zpsilu, zstab,zpsim, zpsih, zpsil   !    -         -
237      REAL(wp) ::   zvatmg, zcmn, zchn, zcln, zcmcmn, zdenum    !    -         -
238      REAL(wp) ::   zdtetar, ztvmoyr, zlxins, zchcm, zclcm      !    -         -
239      REAL(wp) ::   zmt1, zmt2, zmt3, ztatm3, ztamr, ztaevbk    !    -         -
240      REAL(wp) ::   zsst, ztatm, zcco1, zpatm, zcmax, zrmax     !    -         -
241      REAL(wp) ::   zrhoa, zev, zes, zeso, zqatm, zevsqr        !    -         -
242      REAL(wp) ::   ztx2, zty2, zcevap, zcprec                  !    -         -
243      REAL(wp), POINTER, DIMENSION(:,:) ::   zqlw        ! long-wave heat flux over ocean
244      REAL(wp), POINTER, DIMENSION(:,:) ::   zqla        ! latent heat flux over ocean
245      REAL(wp), POINTER, DIMENSION(:,:) ::   zqsb        ! sensible heat flux over ocean
246      INTEGER(KIND=jpim), PARAMETER :: zhook_in = 0
247      INTEGER(KIND=jpim), PARAMETER :: zhook_out = 1
248      REAL(KIND=jprb)               :: zhook_handle
249
250      CHARACTER(LEN=*), PARAMETER :: RoutineName='BLK_OCE_CLIO'
251
252      IF (lhook) CALL dr_hook(RoutineName,zhook_in,zhook_handle)
253
254      !!---------------------------------------------------------------------
255      !
256      IF( nn_timing == 1 )  CALL timing_start('blk_oce_clio')
257      !
258      CALL wrk_alloc( jpi,jpj, zqlw, zqla, zqsb )
259
260      zpatm = 101000._wp      ! atmospheric pressure  (assumed constant here)
261
262      !------------------------------------!
263      !   momentum fluxes  (utau, vtau )   !
264      !------------------------------------!
265!CDIR COLLAPSE
266      utau(:,:) = sf(jp_utau)%fnow(:,:,1)
267!CDIR COLLAPSE
268      vtau(:,:) = sf(jp_vtau)%fnow(:,:,1)
269
270      !------------------------------------!
271      !   wind stress module (taum )       !
272      !------------------------------------!
273!CDIR NOVERRCHK
274      DO jj = 2, jpjm1
275!CDIR NOVERRCHK
276         DO ji = fs_2, fs_jpim1   ! vector opt.
277            ztx2 = utau(ji-1,jj  ) + utau(ji,jj)
278            zty2 = vtau(ji  ,jj-1) + vtau(ji,jj)
279            taum(ji,jj) = 0.5 * SQRT( ztx2 * ztx2 + zty2 * zty2 )
280         END DO
281      END DO
282      utau(:,:) = utau(:,:) * umask(:,:,1)
283      vtau(:,:) = vtau(:,:) * vmask(:,:,1)
284      taum(:,:) = taum(:,:) * tmask(:,:,1)
285      CALL lbc_lnk( taum, 'T', 1. )
286
287      !------------------------------------!
288      !   store the wind speed  (wndm )    !
289      !------------------------------------!
290!CDIR COLLAPSE
291      wndm(:,:) = sf(jp_wndm)%fnow(:,:,1)
292      wndm(:,:) = wndm(:,:) * tmask(:,:,1)
293
294      !------------------------------------------------!
295      !   Shortwave radiation for ocean and snow/ice   !
296      !------------------------------------------------!
297     
298      CALL blk_clio_qsr_oce( qsr )
299      qsr(:,:) = qsr(:,:) * tmask(:,:,1) ! no shortwave radiation into the ocean beneath ice shelf
300      !------------------------!
301      !   Other ocean fluxes   !
302      !------------------------!
303!CDIR NOVERRCHK
304!CDIR COLLAPSE
305      DO jj = 1, jpj
306!CDIR NOVERRCHK
307         DO ji = 1, jpi
308            !
309            zsst  = pst(ji,jj)              + rt0           ! converte Celcius to Kelvin the SST
310            ztatm = sf(jp_tair)%fnow(ji,jj,1)               ! and set minimum value far above 0 K (=rt0 over land)
311            zcco1 = 1.0 - sf(jp_ccov)%fnow(ji,jj,1)         ! fraction of clear sky ( 1 - cloud cover)
312            zrhoa = zpatm / ( 287.04 * ztatm )              ! air density (equation of state for dry air)
313            ztamr = ztatm - rtt                             ! Saturation water vapour
314            zmt1  = SIGN( 17.269,  ztamr )                  !           ||
315            zmt2  = SIGN( 21.875,  ztamr )                  !          \  /
316            zmt3  = SIGN( 28.200, -ztamr )                  !           \/
317            zes   = 611.0 * EXP(  ABS( ztamr ) * MIN ( zmt1, zmt2 ) / ( ztatm - 35.86  + MAX( 0.e0, zmt3 ) )  )
318            zev    = sf(jp_humi)%fnow(ji,jj,1) * zes        ! vapour pressure 
319            zevsqr = SQRT( zev * 0.01 )                     ! square-root of vapour pressure
320            zqatm = 0.622 * zev / ( zpatm - 0.378 * zev )   ! specific humidity
321
322            !--------------------------------------!
323            !  long-wave radiation over the ocean  !  ( Berliand 1952 ; all latitudes )
324            !--------------------------------------!
325            ztatm3  = ztatm * ztatm * ztatm
326            zcldeff = 1.0 - sbudyko(ji,jj) * sf(jp_ccov)%fnow(ji,jj,1) * sf(jp_ccov)%fnow(ji,jj,1)   
327            ztaevbk = ztatm * ztatm3 * zcldeff * ( 0.39 - 0.05 * zevsqr ) 
328            !
329            zqlw(ji,jj) = - emic * stefan * ( ztaevbk + 4. * ztatm3 * ( zsst - ztatm ) ) 
330
331            !--------------------------------------------------
332            !  Latent and sensible heat fluxes over the ocean
333            !--------------------------------------------------
334            !                                                          ! vapour pressure at saturation of ocean
335            zeso =  611.0 * EXP ( 17.2693884 * ( zsst - rtt ) * tmask(ji,jj,1) / ( zsst - 35.86 ) )
336
337            zqsato = ( 0.622 * zeso ) / ( zpatm - 0.378 * zeso )       ! humidity close to the ocean surface (at saturation)
338
339            ! Drag coefficients from Large and Pond (1981,1982)
340            !                                                          ! Stability parameters
341            zdteta  = zsst - ztatm
342            zdeltaq = zqatm - zqsato
343            ztvmoy  = ztatm * ( 1. + 2.2e-3 * ztatm * zqatm )
344            zdenum  = MAX( sf(jp_wndm)%fnow(ji,jj,1) * sf(jp_wndm)%fnow(ji,jj,1) * ztvmoy, eps20 )
345            zdtetar = zdteta / zdenum
346            ztvmoyr = ztvmoy * ztvmoy * zdeltaq / zdenum
347            !                                                          ! case of stable atmospheric conditions
348            zobouks = -70.0 * 10. * ( zdtetar + 3.2e-3 * ztvmoyr )
349            zobouks = MAX( 0.e0, zobouks )
350            zpsims = -7.0 * zobouks
351            zpsihs =  zpsims
352            zpsils =  zpsims
353            !                                                          ! case of unstable atmospheric conditions
354            zobouku = MIN(  0.e0, -100.0 * 10.0 * ( zdtetar + 2.2e-3 * ztvmoyr )  )
355            zxins   = ( 1. - 16. * zobouku )**0.25
356            zlxins  = LOG( ( 1. + zxins * zxins ) / 2. )
357            zpsimu  = 2. * LOG( ( 1 + zxins ) * 0.5 )  + zlxins - 2. * ATAN( zxins ) + rpi * 0.5
358            zpsihu  = 2. * zlxins
359            zpsilu  = zpsihu
360            !                                                          ! intermediate values
361            zstab   = MAX( 0.e0, SIGN( 1.e0, zdteta ) )
362            zpsim   = zstab * zpsimu + ( 1.0 - zstab ) * zpsims
363            zpsih   = zstab * zpsihu + ( 1.0 - zstab ) * zpsihs
364            zpsil   = zpsih
365           
366            zvatmg         = MAX( 0.032 * 1.5e-3 * sf(jp_wndm)%fnow(ji,jj,1) * sf(jp_wndm)%fnow(ji,jj,1) / grav, eps20 )
367            zcmn           = vkarmn / LOG ( 10. / zvatmg )
368            zchn           = 0.0327 * zcmn
369            zcln           = 0.0346 * zcmn
370            zcmcmn         = 1. / ( 1. - zcmn * zpsim / vkarmn )
371            ! sometimes the ratio zchn * zpsih / ( vkarmn * zcmn ) is too close to 1 and zchcm becomes very very big
372            zcmax = 0.1               ! choice for maximum value of the heat transfer coefficient, guided by my intuition
373            zrmax = 1 - 3.e-4 / zcmax ! maximum value of the ratio
374            zchcm = zcmcmn / ( 1. - MIN ( zchn * zpsih / ( vkarmn * zcmn ) , zrmax ) )
375            zclcm          = zchcm
376            !                                                          ! transfert coef. (Large and Pond 1981,1982)
377            zcsho          = zchn * zchcm                               
378            zcleo          = zcln * zclcm 
379
380            zrhova         = zrhoa * sf(jp_wndm)%fnow(ji,jj,1)
381
382            ! sensible heat flux
383            zqsb(ji,jj) = zrhova * zcsho * 1004.0  * ( zsst - ztatm ) 
384         
385            ! latent heat flux (bounded by zero)
386            zqla(ji,jj) = MAX(  0.e0, zrhova * zcleo * 2.5e+06 * ( zqsato - zqatm )  )
387            !               
388         END DO
389      END DO
390     
391      ! ----------------------------------------------------------------------------- !
392      !     III    Total FLUXES                                                       !
393      ! ----------------------------------------------------------------------------- !
394      zcevap = rcp /  cevap    ! convert zqla ==> evap (Kg/m2/s) ==> m/s ==> W/m2
395      zcprec = rcp /  rday     ! convert prec ( mm/day ==> m/s)  ==> W/m2
396
397!CDIR COLLAPSE
398      emp(:,:) = zqla(:,:) / cevap                                        &   ! freshwater flux
399         &     - sf(jp_prec)%fnow(:,:,1) / rday * tmask(:,:,1)
400      !
401!CDIR COLLAPSE
402      qns(:,:) = zqlw(:,:) - zqsb(:,:) - zqla(:,:)                        &   ! Downward Non Solar flux
403         &     - zqla(:,:)             * pst(:,:) * zcevap                &   ! remove evap.   heat content at SST in Celcius
404         &     + sf(jp_prec)%fnow(:,:,1) * sf(jp_tair)%fnow(:,:,1) * zcprec   ! add    precip. heat content at Tair in Celcius
405      qns(:,:) = qns(:,:) * tmask(:,:,1)
406#if defined key_lim3
407      qns_oce(:,:) = zqlw(:,:) - zqsb(:,:) - zqla(:,:)
408      qsr_oce(:,:) = qsr(:,:)
409#endif
410      ! NB: if sea-ice model, the snow precip are computed and the associated heat is added to qns (see blk_ice_clio)
411
412      IF ( nn_ice == 0 ) THEN
413         CALL iom_put( "qlw_oce" ,   zqlw )                 ! output downward longwave  heat over the ocean
414         CALL iom_put( "qsb_oce" , - zqsb )                 ! output downward sensible  heat over the ocean
415         CALL iom_put( "qla_oce" , - zqla )                 ! output downward latent    heat over the ocean
416         CALL iom_put( "qemp_oce",   qns-zqlw+zqsb+zqla )   ! output downward heat content of E-P over the ocean
417         CALL iom_put( "qns_oce" ,   qns  )                 ! output downward non solar heat over the ocean
418         CALL iom_put( "qsr_oce" ,   qsr  )                 ! output downward solar heat over the ocean
419         CALL iom_put( "qt_oce"  ,   qns+qsr )              ! output total downward heat over the ocean
420      ENDIF
421
422      IF(ln_ctl) THEN
423         CALL prt_ctl(tab2d_1=zqsb , clinfo1=' blk_oce_clio: zqsb   : ', tab2d_2=zqlw , clinfo2=' zqlw  : ')
424         CALL prt_ctl(tab2d_1=zqla , clinfo1=' blk_oce_clio: zqla   : ', tab2d_2=qsr  , clinfo2=' qsr   : ')
425         CALL prt_ctl(tab2d_1=pst  , clinfo1=' blk_oce_clio: pst    : ', tab2d_2=emp  , clinfo2=' emp   : ')
426         CALL prt_ctl(tab2d_1=utau , clinfo1=' blk_oce_clio: utau   : ', mask1=umask,   &
427            &         tab2d_2=vtau , clinfo2=' vtau : ', mask2=vmask )
428      ENDIF
429
430      CALL wrk_dealloc( jpi,jpj, zqlw, zqla, zqsb )
431      !
432      IF( nn_timing == 1 )  CALL timing_stop('blk_oce_clio')
433      !
434      IF (lhook) CALL dr_hook(RoutineName,zhook_out,zhook_handle)
435   END SUBROUTINE blk_oce_clio
436
437# if defined key_lim2 || defined key_lim3
438   SUBROUTINE blk_ice_clio_tau
439      !!---------------------------------------------------------------------------
440      !!                     ***  ROUTINE blk_ice_clio_tau  ***
441      !!                 
442      !!  ** Purpose :   Computation momentum flux at the ice-atm interface 
443      !!         
444      !!  ** Method  :   Read utau from a forcing file. Rearrange if C-grid
445      !!
446      !!----------------------------------------------------------------------
447      REAL(wp) ::   zcoef
448      INTEGER  ::   ji, jj   ! dummy loop indices
449      INTEGER(KIND=jpim), PARAMETER :: zhook_in = 0
450      INTEGER(KIND=jpim), PARAMETER :: zhook_out = 1
451      REAL(KIND=jprb)               :: zhook_handle
452
453      CHARACTER(LEN=*), PARAMETER :: RoutineName='BLK_ICE_CLIO_TAU'
454
455      IF (lhook) CALL dr_hook(RoutineName,zhook_in,zhook_handle)
456
457      !!---------------------------------------------------------------------
458      !
459      IF( nn_timing == 1 )  CALL timing_start('blk_ice_clio_tau')
460
461      SELECT CASE( cp_ice_msh )
462
463      CASE( 'C' )                          ! C-grid ice dynamics
464
465         zcoef  = cai / cao                         ! Change from air-sea stress to air-ice stress
466         utau_ice(:,:) = zcoef * utau(:,:)
467         vtau_ice(:,:) = zcoef * vtau(:,:)
468
469      CASE( 'I' )                          ! I-grid ice dynamics:  I-point (i.e. F-point lower-left corner)
470
471         zcoef  = 0.5_wp * cai / cao                ! Change from air-sea stress to air-ice stress
472         DO jj = 2, jpj         ! stress from ocean U- and V-points to ice U,V point
473            DO ji = 2, jpi   ! I-grid : no vector opt.
474               utau_ice(ji,jj) = zcoef * ( utau(ji-1,jj  ) + utau(ji-1,jj-1) )
475               vtau_ice(ji,jj) = zcoef * ( vtau(ji  ,jj-1) + vtau(ji-1,jj-1) )
476            END DO
477         END DO
478
479         CALL lbc_lnk( utau_ice(:,:), 'I', -1. )   ;   CALL lbc_lnk( vtau_ice(:,:), 'I', -1. )   ! I-point
480
481      END SELECT
482
483      IF(ln_ctl) THEN
484         CALL prt_ctl(tab2d_1=utau_ice , clinfo1=' blk_ice_clio: utau_ice : ', tab2d_2=vtau_ice , clinfo2=' vtau_ice : ')
485      ENDIF
486
487      IF( nn_timing == 1 )  CALL timing_stop('blk_ice_clio_tau')
488
489      IF (lhook) CALL dr_hook(RoutineName,zhook_out,zhook_handle)
490   END SUBROUTINE blk_ice_clio_tau
491#endif
492
493# if defined key_lim2 || defined key_lim3
494   SUBROUTINE blk_ice_clio_flx(  ptsu , palb_cs, palb_os, palb )
495      !!---------------------------------------------------------------------------
496      !!                     ***  ROUTINE blk_ice_clio_flx ***
497      !!                 
498      !!  ** Purpose :   Computation of the heat fluxes at ocean and snow/ice
499      !!       surface the solar heat at ocean and snow/ice surfaces and the
500      !!       sensitivity of total heat fluxes to the SST variations
501      !!         
502      !!  ** Method  :   The flux of heat at the ice and ocean surfaces are derived
503      !!       from semi-empirical ( or bulk ) formulae which relate the flux to
504      !!       the properties of the surface and of the lower atmosphere. Here, we
505      !!       follow the work of Oberhuber, 1988   
506      !!
507      !!  ** Action  :   call albedo_oce/albedo_ice to compute ocean/ice albedo
508      !!               - snow precipitation
509      !!               - solar flux at the ocean and ice surfaces
510      !!               - the long-wave radiation for the ocean and sea/ice
511      !!               - turbulent heat fluxes over water and ice
512      !!               - evaporation over water
513      !!               - total heat fluxes sensitivity over ice (dQ/dT)
514      !!               - latent heat flux sensitivity over ice (dQla/dT)
515      !!               - qns  :  modified the non solar heat flux over the ocean
516      !!                         to take into account solid precip latent heat flux
517      !!----------------------------------------------------------------------
518      REAL(wp), INTENT(in   ), DIMENSION(:,:,:)   ::   ptsu      ! ice surface temperature                   [Kelvin]
519      REAL(wp), INTENT(in   ), DIMENSION(:,:,:)   ::   palb_cs  ! ice albedo (clear    sky) (alb_ice_cs)         [-]
520      REAL(wp), INTENT(in   ), DIMENSION(:,:,:)   ::   palb_os  ! ice albedo (overcast sky) (alb_ice_os)         [-]
521      REAL(wp), INTENT(  out), DIMENSION(:,:,:)   ::   palb     ! ice albedo (actual value)                      [-]
522      !!
523      INTEGER  ::   ji, jj, jl    ! dummy loop indices
524      !!
525      REAL(wp) ::   zmt1, zmt2, zmt3, ztatm3                    ! temporary scalars
526      REAL(wp) ::   ztaevbk, zind1, zind2, zind3, ztamr         !    -         -
527      REAL(wp) ::   zesi, zqsati, zdesidt                       !    -         -
528      REAL(wp) ::   zdqla, zcldeff, zev, zes, zpatm, zrhova     !    -         -
529      REAL(wp) ::   zcshi, zclei, zrhovaclei, zrhovacshi        !    -         -
530      REAL(wp) ::   ztice3, zticemb, zticemb2, zdqlw, zdqsb     !    -         -
531      REAL(wp) ::   z1_lsub                                     !    -         -
532      !!
533      REAL(wp), DIMENSION(:,:)  , POINTER ::   ztatm   ! Tair in Kelvin
534      REAL(wp), DIMENSION(:,:)  , POINTER ::   zqatm   ! specific humidity
535      REAL(wp), DIMENSION(:,:)  , POINTER ::   zevsqr  ! vapour pressure square-root
536      REAL(wp), DIMENSION(:,:)  , POINTER ::   zrhoa   ! air density
537      REAL(wp), DIMENSION(:,:,:), POINTER ::   z_qlw, z_qsb
538      REAL(wp), DIMENSION(:,:)  , POINTER ::   zevap, zsnw
539      INTEGER(KIND=jpim), PARAMETER :: zhook_in = 0
540      INTEGER(KIND=jpim), PARAMETER :: zhook_out = 1
541      REAL(KIND=jprb)               :: zhook_handle
542
543      CHARACTER(LEN=*), PARAMETER :: RoutineName='BLK_ICE_CLIO_FLX'
544
545      IF (lhook) CALL dr_hook(RoutineName,zhook_in,zhook_handle)
546
547      !!---------------------------------------------------------------------
548      !
549      IF( nn_timing == 1 )  CALL timing_start('blk_ice_clio_flx')
550      !
551      CALL wrk_alloc( jpi,jpj, ztatm, zqatm, zevsqr, zrhoa )
552      CALL wrk_alloc( jpi,jpj, jpl, z_qlw, z_qsb )
553
554      zpatm = 101000.                        ! atmospheric pressure  (assumed constant  here)
555      !--------------------------------------------------------------------------------
556      !  Determine cloud optical depths as a function of latitude (Chou et al., 1981).
557      !  and the correction factor for taking into account  the effect of clouds
558      !--------------------------------------------------------------------------------
559
560!CDIR NOVERRCHK
561!CDIR COLLAPSE
562      DO jj = 1, jpj
563!CDIR NOVERRCHK
564         DO ji = 1, jpi
565            ztatm (ji,jj) = sf(jp_tair)%fnow(ji,jj,1)                ! air temperature in Kelvins
566     
567            zrhoa(ji,jj) = zpatm / ( 287.04 * ztatm(ji,jj) )         ! air density (equation of state for dry air)
568     
569            ztamr = ztatm(ji,jj) - rtt                               ! Saturation water vapour
570            zmt1  = SIGN( 17.269,  ztamr )
571            zmt2  = SIGN( 21.875,  ztamr )
572            zmt3  = SIGN( 28.200, -ztamr )
573            zes   = 611.0 * EXP(  ABS( ztamr ) * MIN ( zmt1, zmt2 )   &
574               &                / ( ztatm(ji,jj) - 35.86  + MAX( 0.e0, zmt3 ) )  )
575
576            zev = sf(jp_humi)%fnow(ji,jj,1) * zes                    ! vapour pressure 
577            zevsqr(ji,jj) = SQRT( zev * 0.01 )                       ! square-root of vapour pressure
578            zqatm(ji,jj) = 0.622 * zev / ( zpatm - 0.378 * zev )     ! specific humidity
579
580            !----------------------------------------------------
581            !   Computation of snow precipitation (Ledley, 1985) |
582            !----------------------------------------------------
583            zmt1  =   253.0 - ztatm(ji,jj)            ;   zind1 = MAX( 0.e0, SIGN( 1.e0, zmt1 ) )
584            zmt2  = ( 272.0 - ztatm(ji,jj) ) / 38.0   ;   zind2 = MAX( 0.e0, SIGN( 1.e0, zmt2 ) )
585            zmt3  = ( 281.0 - ztatm(ji,jj) ) / 18.0   ;   zind3 = MAX( 0.e0, SIGN( 1.e0, zmt3 ) )
586            sprecip(ji,jj) = sf(jp_prec)%fnow(ji,jj,1) / rday   &      ! rday = converte mm/day to kg/m2/s
587               &         * (          zind1      &                   ! solid  (snow) precipitation [kg/m2/s]
588               &            + ( 1.0 - zind1 ) * (          zind2   * ( 0.5 + zmt2 )   &
589               &                                 + ( 1.0 - zind2 ) *  zind3 * zmt3  )   ) 
590
591            !----------------------------------------------------!
592            !  fraction of net penetrative shortwave radiation   !
593            !----------------------------------------------------!
594            ! fraction of qsr_ice which is NOT absorbed in the thin surface layer
595            ! and thus which penetrates inside the ice cover ( Maykut and Untersteiner, 1971 ; Elbert anbd Curry, 1993 )
596            fr1_i0(ji,jj) = 0.18  * ( 1.e0 - sf(jp_ccov)%fnow(ji,jj,1) ) + 0.35 * sf(jp_ccov)%fnow(ji,jj,1) 
597            fr2_i0(ji,jj) = 0.82  * ( 1.e0 - sf(jp_ccov)%fnow(ji,jj,1) ) + 0.65 * sf(jp_ccov)%fnow(ji,jj,1)
598         END DO
599      END DO
600      CALL iom_put( 'snowpre', sprecip )   ! Snow precipitation
601     
602      !-----------------------------------------------------------!
603      !  snow/ice Shortwave radiation   (abedo already computed)  !
604      !-----------------------------------------------------------!
605      CALL blk_clio_qsr_ice( palb_cs, palb_os, qsr_ice )
606     
607      DO jl = 1, jpl
608         palb(:,:,jl) = ( palb_cs(:,:,jl) * ( 1.e0 - sf(jp_ccov)%fnow(:,:,1) )   &
609            &         +   palb_os(:,:,jl) * sf(jp_ccov)%fnow(:,:,1) )
610      END DO
611
612      !                                     ! ========================== !
613      DO jl = 1, jpl                       !  Loop over ice categories  !
614         !                                  ! ========================== !
615!CDIR NOVERRCHK
616!CDIR COLLAPSE
617         DO jj = 1 , jpj
618!CDIR NOVERRCHK
619            DO ji = 1, jpi
620               !-------------------------------------------!
621               !  long-wave radiation over ice categories  !  ( Berliand 1952 ; all latitudes )
622               !-------------------------------------------!
623               ztatm3  = ztatm(ji,jj) * ztatm(ji,jj) * ztatm(ji,jj)
624               zcldeff = 1.0 - sbudyko(ji,jj) * sf(jp_ccov)%fnow(ji,jj,1) * sf(jp_ccov)%fnow(ji,jj,1)   
625               ztaevbk = ztatm3 * ztatm(ji,jj) * zcldeff * ( 0.39 - 0.05 * zevsqr(ji,jj) ) 
626               !
627               z_qlw(ji,jj,jl) = - emic * stefan * ( ztaevbk + 4. * ztatm3 * ( ptsu(ji,jj,jl) - ztatm(ji,jj) ) ) 
628
629               !----------------------------------------
630               !  Turbulent heat fluxes over snow/ice     ( Latent and sensible )
631               !----------------------------------------       
632
633               ! vapour pressure at saturation of ice (tmask to avoid overflow in the exponential)
634               zesi =  611.0 * EXP( 21.8745587 * tmask(ji,jj,1) * ( ptsu(ji,jj,jl) - rtt )/ ( ptsu(ji,jj,jl) - 7.66 ) )
635               ! humidity close to the ice surface (at saturation)
636               zqsati   = ( 0.622 * zesi ) / ( zpatm - 0.378 * zesi )
637               
638               !  computation of intermediate values
639               zticemb  = ptsu(ji,jj,jl) - 7.66
640               zticemb2 = zticemb * zticemb 
641               ztice3   = ptsu(ji,jj,jl) * ptsu(ji,jj,jl) * ptsu(ji,jj,jl)
642               zdesidt  = zesi * ( 9.5 * LOG( 10.0 ) * ( rtt - 7.66 )  / zticemb2 )
643               
644               !  Transfer cofficients assumed to be constant (Parkinson 1979 ; Maykut 1982)
645               zcshi    = 1.75e-03
646               zclei    = zcshi
647               
648               !  sensible and latent fluxes over ice
649               zrhova     = zrhoa(ji,jj) * sf(jp_wndm)%fnow(ji,jj,1)      ! computation of intermediate values
650               zrhovaclei = zrhova * zcshi * 2.834e+06
651               zrhovacshi = zrhova * zclei * 1004.0
652           
653               !  sensible heat flux
654               z_qsb(ji,jj,jl) = zrhovacshi * ( ptsu(ji,jj,jl) - ztatm(ji,jj) )
655           
656               !  latent heat flux
657               qla_ice(ji,jj,jl) = MAX(  0.e0, zrhovaclei * ( zqsati - zqatm(ji,jj) )  )
658             
659               !  sensitivity of non solar fluxes (dQ/dT) (long-wave, sensible and latent fluxes)
660               zdqlw = 4.0 * emic * stefan * ztice3
661               zdqsb = zrhovacshi
662               zdqla = zrhovaclei * ( zdesidt * ( zqsati * zqsati / ( zesi * zesi ) ) * ( zpatm / 0.622 ) )   
663               !
664               dqla_ice(ji,jj,jl) = zdqla                           ! latent flux sensitivity
665               dqns_ice(ji,jj,jl) = -( zdqlw + zdqsb + zdqla )      !  total non solar sensitivity
666            END DO
667            !
668         END DO
669         !
670      END DO
671      !
672      ! ----------------------------------------------------------------------------- !
673      !    Total FLUXES                                                               !
674      ! ----------------------------------------------------------------------------- !
675      !
676!CDIR COLLAPSE
677      qns_ice(:,:,:) = z_qlw (:,:,:) - z_qsb (:,:,:) - qla_ice (:,:,:)      ! Downward Non Solar flux
678!CDIR COLLAPSE
679      tprecip(:,:)   = sf(jp_prec)%fnow(:,:,1) / rday                     ! total precipitation [kg/m2/s]
680      !
681      ! ----------------------------------------------------------------------------- !
682      !    Correct the OCEAN non solar flux with the existence of solid precipitation !
683      ! ---------------=====--------------------------------------------------------- !
684!CDIR COLLAPSE
685      qns(:,:) = qns(:,:)                                                           &   ! update the non-solar heat flux with:
686         &     - sprecip(:,:) * lfus                                                  &   ! remove melting solid precip
687         &     + sprecip(:,:) * MIN( sf(jp_tair)%fnow(:,:,1), rt0_snow - rt0 ) * cpic &   ! add solid P at least below melting
688         &     - sprecip(:,:) * sf(jp_tair)%fnow(:,:,1)                        * rcp      ! remove solid precip. at Tair
689
690#if defined key_lim3
691      ! ----------------------------------------------------------------------------- !
692      !    Distribute evapo, precip & associated heat over ice and ocean
693      ! ---------------=====--------------------------------------------------------- !
694      CALL wrk_alloc( jpi,jpj, zevap, zsnw ) 
695
696      ! --- evaporation --- !
697      z1_lsub = 1._wp / Lsub
698      evap_ice (:,:,:) = qla_ice (:,:,:) * z1_lsub ! sublimation
699      devap_ice(:,:,:) = dqla_ice(:,:,:) * z1_lsub
700      zevap    (:,:)   = emp(:,:) + tprecip(:,:)   ! evaporation over ocean
701
702      ! --- evaporation minus precipitation --- !
703      zsnw(:,:) = 0._wp
704      CALL lim_thd_snwblow( pfrld, zsnw )          ! snow redistribution by wind
705      emp_oce(:,:) = pfrld(:,:) * zevap(:,:) - ( tprecip(:,:) - sprecip(:,:) ) - sprecip(:,:) * ( 1._wp - zsnw )
706      emp_ice(:,:) = SUM( a_i_b(:,:,:) * evap_ice(:,:,:), dim=3 ) - sprecip(:,:) * zsnw
707      emp_tot(:,:) = emp_oce(:,:) + emp_ice(:,:)
708
709      ! --- heat flux associated with emp --- !
710      qemp_oce(:,:) = - pfrld(:,:) * zevap(:,:) * sst_m(:,:) * rcp                               & ! evap
711         &          + ( tprecip(:,:) - sprecip(:,:) ) * ( sf(jp_tair)%fnow(:,:,1) - rt0 ) * rcp  & ! liquid precip
712         &          +   sprecip(:,:) * ( 1._wp - zsnw ) *                                        & ! solid precip
713         &              ( ( MIN( sf(jp_tair)%fnow(:,:,1), rt0_snow ) - rt0 ) * cpic * tmask(:,:,1) - lfus )
714      qemp_ice(:,:) =   sprecip(:,:) * zsnw *                                                    & ! solid precip (only)
715         &              ( ( MIN( sf(jp_tair)%fnow(:,:,1), rt0_snow ) - rt0 ) * cpic * tmask(:,:,1) - lfus )
716
717      ! --- total solar and non solar fluxes --- !
718      qns_tot(:,:) = pfrld(:,:) * qns_oce(:,:) + SUM( a_i_b(:,:,:) * qns_ice(:,:,:), dim=3 ) + qemp_ice(:,:) + qemp_oce(:,:)
719      qsr_tot(:,:) = pfrld(:,:) * qsr_oce(:,:) + SUM( a_i_b(:,:,:) * qsr_ice(:,:,:), dim=3 )
720
721      ! --- heat content of precip over ice in J/m3 (to be used in 1D-thermo) --- !
722      qprec_ice(:,:) = rhosn * ( ( MIN( sf(jp_tair)%fnow(:,:,1), rt0_snow ) - rt0 ) * cpic * tmask(:,:,1) - lfus )
723
724      ! --- heat content of evap over ice in W/m2 (to be used in 1D-thermo) --- !
725      DO jl = 1, jpl
726         qevap_ice(:,:,jl) = 0._wp ! should be -evap_ice(:,:,jl)*( ( Tice - rt0 ) * cpic * tmask(:,:,1) - lfus )
727                                   ! but then qemp_ice should also include sublimation
728      END DO
729
730      CALL wrk_dealloc( jpi,jpj, zevap, zsnw ) 
731#endif
732
733!!gm : not necessary as all input data are lbc_lnk...
734      CALL lbc_lnk( fr1_i0  (:,:) , 'T', 1. )
735      CALL lbc_lnk( fr2_i0  (:,:) , 'T', 1. )
736      DO jl = 1, jpl
737         CALL lbc_lnk( qns_ice (:,:,jl) , 'T', 1. )
738         CALL lbc_lnk( dqns_ice(:,:,jl) , 'T', 1. )
739         CALL lbc_lnk( qla_ice (:,:,jl) , 'T', 1. )
740         CALL lbc_lnk( dqla_ice(:,:,jl) , 'T', 1. )
741      END DO
742
743!!gm : mask is not required on forcing
744      DO jl = 1, jpl
745         qns_ice (:,:,jl) = qns_ice (:,:,jl) * tmask(:,:,1)
746         qla_ice (:,:,jl) = qla_ice (:,:,jl) * tmask(:,:,1)
747         dqns_ice(:,:,jl) = dqns_ice(:,:,jl) * tmask(:,:,1)
748         dqla_ice(:,:,jl) = dqla_ice(:,:,jl) * tmask(:,:,1)
749      END DO
750
751      CALL wrk_dealloc( jpi,jpj, ztatm, zqatm, zevsqr, zrhoa )
752      CALL wrk_dealloc( jpi,jpj, jpl  , z_qlw, z_qsb )
753
754      IF(ln_ctl) THEN
755         CALL prt_ctl(tab3d_1=z_qsb  , clinfo1=' blk_ice_clio: z_qsb  : ', tab3d_2=z_qlw  , clinfo2=' z_qlw  : ', kdim=jpl)
756         CALL prt_ctl(tab3d_1=qla_ice  , clinfo1=' blk_ice_clio: z_qla  : ', tab3d_2=qsr_ice  , clinfo2=' qsr_ice  : ', kdim=jpl)
757         CALL prt_ctl(tab3d_1=dqns_ice , clinfo1=' blk_ice_clio: dqns_ice : ', tab3d_2=qns_ice  , clinfo2=' qns_ice  : ', kdim=jpl)
758         CALL prt_ctl(tab3d_1=dqla_ice , clinfo1=' blk_ice_clio: dqla_ice : ', tab3d_2=ptsu    , clinfo2=' ptsu    : ', kdim=jpl)
759         CALL prt_ctl(tab2d_1=tprecip  , clinfo1=' blk_ice_clio: tprecip  : ', tab2d_2=sprecip  , clinfo2=' sprecip  : ')
760      ENDIF
761
762      IF( nn_timing == 1 )  CALL timing_stop('blk_ice_clio_flx')
763      !
764      IF (lhook) CALL dr_hook(RoutineName,zhook_out,zhook_handle)
765   END SUBROUTINE blk_ice_clio_flx
766
767#endif
768
769   SUBROUTINE blk_clio_qsr_oce( pqsr_oce )
770      !!---------------------------------------------------------------------------
771      !!                     ***  ROUTINE blk_clio_qsr_oce  ***
772      !!                 
773      !!  ** Purpose :   Computation of the shortwave radiation at the ocean and the
774      !!               snow/ice surfaces.
775      !!         
776      !!  ** Method  : - computed qsr from the cloud cover for both ice and ocean
777      !!               - also initialise sbudyko and stauc once for all
778      !!----------------------------------------------------------------------
779      REAL(wp), INTENT(  out), DIMENSION(jpi,jpj)     ::   pqsr_oce    ! shortwave radiation  over the ocean
780      !!
781      INTEGER, PARAMETER  ::   jp24 = 24   ! sampling of the daylight period (sunrise to sunset) into 24 equal parts
782      !!     
783      INTEGER  ::   ji, jj, jt    ! dummy loop indices
784      INTEGER  ::   indaet            !  = -1, 0, 1 for odd, normal and leap years resp.
785      INTEGER  ::   iday              ! integer part of day
786      INTEGER  ::   indxb, indxc      ! index for cloud depth coefficient
787
788      REAL(wp)  ::   zalat , zclat, zcmue, zcmue2    ! local scalars
789      REAL(wp)  ::   zmt1, zmt2, zmt3                !
790      REAL(wp)  ::   zdecl, zsdecl , zcdecl          !
791      REAL(wp)  ::   za_oce, ztamr                   !
792
793      REAL(wp) ::   zdl, zlha                        ! local scalars
794      REAL(wp) ::   zlmunoon, zcldcor, zdaycor       !   
795      REAL(wp) ::   zxday, zdist, zcoef, zcoef1      !
796      REAL(wp) ::   zes
797     
798      REAL(wp), DIMENSION(:,:), POINTER ::   zev          ! vapour pressure
799      REAL(wp), DIMENSION(:,:), POINTER ::   zdlha, zlsrise, zlsset     ! 2D workspace
800      REAL(wp), DIMENSION(:,:), POINTER ::   zps, zpc   ! sine (cosine) of latitude per sine (cosine) of solar declination
801      INTEGER(KIND=jpim), PARAMETER :: zhook_in = 0
802      INTEGER(KIND=jpim), PARAMETER :: zhook_out = 1
803      REAL(KIND=jprb)               :: zhook_handle
804
805      CHARACTER(LEN=*), PARAMETER :: RoutineName='BLK_CLIO_QSR_OCE'
806
807      IF (lhook) CALL dr_hook(RoutineName,zhook_in,zhook_handle)
808
809      !!---------------------------------------------------------------------
810      !
811      IF( nn_timing == 1 )  CALL timing_start('blk_clio_qsr_oce')
812      !
813      CALL wrk_alloc( jpi,jpj, zev, zdlha, zlsrise, zlsset, zps, zpc )
814
815      IF( lbulk_init ) THEN             !   Initilization at first time step only
816         rdtbs2 = nn_fsbc * rdt * 0.5
817         ! cloud optical depths as a function of latitude (Chou et al., 1981).
818         ! and the correction factor for taking into account  the effect of clouds
819         DO jj = 1, jpj
820            DO ji = 1 , jpi
821               zalat          = ( 90.e0 - ABS( gphit(ji,jj) ) ) /  5.e0
822               zclat          = ( 95.e0 -      gphit(ji,jj)   ) / 10.e0
823               indxb          = 1 + INT( zalat )
824               indxc          = 1 + INT( zclat )
825               zdl            = zclat - INT( zclat )
826               !  correction factor to account for the effect of clouds
827               sbudyko(ji,jj) = budyko(indxb)
828               stauc  (ji,jj) = ( 1.e0 - zdl ) * tauco( indxc ) + zdl * tauco( indxc + 1 )
829            END DO
830         END DO
831         lbulk_init = .FALSE.
832      ENDIF
833
834
835      ! Saturated water vapour and vapour pressure
836      ! ------------------------------------------
837!CDIR NOVERRCHK
838!CDIR COLLAPSE
839      DO jj = 1, jpj
840!CDIR NOVERRCHK
841         DO ji = 1, jpi
842            ztamr = sf(jp_tair)%fnow(ji,jj,1) - rtt
843            zmt1  = SIGN( 17.269,  ztamr )
844            zmt2  = SIGN( 21.875,  ztamr )
845            zmt3  = SIGN( 28.200, -ztamr )
846            zes = 611.0 * EXP(  ABS( ztamr ) * MIN ( zmt1, zmt2 )   &              ! Saturation water vapour
847               &                     / ( sf(jp_tair)%fnow(ji,jj,1) - 35.86  + MAX( 0.e0, zmt3 ) )  )
848            zev(ji,jj) = sf(jp_humi)%fnow(ji,jj,1) * zes * 1.0e-05                 ! vapour pressure 
849         END DO
850      END DO
851
852      !-----------------------------------!
853      !  Computation of solar irradiance  !
854      !-----------------------------------!
855!!gm : hard coded  leap year ???
856      indaet   = 1                                    ! = -1, 0, 1 for odd, normal and leap years resp.
857      zxday = nday_year + rdtbs2 / rday               ! day of the year at which the fluxes are calculated
858      iday  = INT( zxday )                            ! (centred at the middle of the ice time step)
859      CALL flx_blk_declin( indaet, iday, zdecl )      ! solar declination of the current day
860      zsdecl = SIN( zdecl * rad )                     ! its sine
861      zcdecl = COS( zdecl * rad )                     ! its cosine
862
863
864      !  correction factor added for computation of shortwave flux to take into account the variation of
865      !  the distance between the sun and the earth during the year (Oberhuber 1988)
866      zdist    = zxday * 2. * rpi / REAL(nyear_len(1), wp)
867      zdaycor  = 1.0 + 0.0013 * SIN( zdist ) + 0.0342 * COS( zdist )
868
869!CDIR NOVERRCHK
870      DO jj = 1, jpj
871!CDIR NOVERRCHK
872         DO ji = 1, jpi
873            !  product of sine (cosine) of latitude and sine (cosine) of solar declination
874            zps(ji,jj) = SIN( gphit(ji,jj) * rad ) * zsdecl
875            zpc(ji,jj) = COS( gphit(ji,jj) * rad ) * zcdecl
876            !  computation of the both local time of sunrise and sunset
877            zlsrise(ji,jj) = ACOS( - SIGN( 1.e0, zps(ji,jj) )    &
878               &                   * MIN(  1.e0, SIGN( 1.e0, zps(ji,jj) ) * ( zps(ji,jj) / zpc(ji,jj) )  )   )
879            zlsset (ji,jj) = - zlsrise(ji,jj)
880            !  dividing the solar day into jp24 segments of length zdlha
881            zdlha  (ji,jj) = ( zlsrise(ji,jj) - zlsset(ji,jj) ) / REAL( jp24, wp )
882         END DO
883      END DO
884
885
886      !---------------------------------------------!
887      !  shortwave radiation absorbed by the ocean  !
888      !---------------------------------------------!
889      pqsr_oce(:,:)   = 0.e0      ! set ocean qsr to zero     
890
891      ! compute and sum ocean qsr over the daylight (i.e. between sunrise and sunset)
892!CDIR NOVERRCHK   
893      DO jt = 1, jp24
894         zcoef = FLOAT( jt ) - 0.5
895!CDIR NOVERRCHK     
896!CDIR COLLAPSE
897         DO jj = 1, jpj
898!CDIR NOVERRCHK
899            DO ji = 1, jpi
900               zlha = COS(  zlsrise(ji,jj) - zcoef * zdlha(ji,jj)  )                  ! local hour angle
901               zcmue              = MAX( 0.e0 ,   zps(ji,jj) + zpc(ji,jj) * zlha  )   ! cos of local solar altitude
902               zcmue2             = 1368.0 * zcmue * zcmue
903
904               ! ocean albedo depending on the cloud cover (Payne, 1972)
905               za_oce     = ( 1.0 - sf(jp_ccov)%fnow(ji,jj,1) ) * 0.05 / ( 1.1 * zcmue**1.4 + 0.15 )   &   ! clear sky
906                  &       +         sf(jp_ccov)%fnow(ji,jj,1)   * 0.06                                     ! overcast
907
908                  ! solar heat flux absorbed by the ocean (Zillman, 1972)
909               pqsr_oce(ji,jj) = pqsr_oce(ji,jj)                                         &
910                  &            + ( 1.0 - za_oce ) * zdlha(ji,jj) * zcmue2                &
911                  &            / ( ( zcmue + 2.7 ) * zev(ji,jj) + 1.085 * zcmue +  0.10 )
912            END DO
913         END DO
914      END DO
915      ! Taking into account the ellipsity of the earth orbit, the clouds AND masked if sea-ice cover > 0%
916      zcoef1 = srgamma * zdaycor / ( 2. * rpi )
917!CDIR COLLAPSE
918      DO jj = 1, jpj
919         DO ji = 1, jpi
920            zlmunoon = ASIN( zps(ji,jj) + zpc(ji,jj) ) / rad                         ! local noon solar altitude
921            zcldcor  = MIN(  1.e0, ( 1.e0 - 0.62 * sf(jp_ccov)%fnow(ji,jj,1)   &     ! cloud correction (Reed 1977)
922               &                          + 0.0019 * zlmunoon )                 )
923            pqsr_oce(ji,jj) = zcoef1 * zcldcor * pqsr_oce(ji,jj) * tmask(ji,jj,1)    ! and zcoef1: ellipsity
924         END DO
925      END DO
926
927      CALL wrk_dealloc( jpi,jpj, zev, zdlha, zlsrise, zlsset, zps, zpc )
928      !
929      IF( nn_timing == 1 )  CALL timing_stop('blk_clio_qsr_oce')
930      !
931      IF (lhook) CALL dr_hook(RoutineName,zhook_out,zhook_handle)
932   END SUBROUTINE blk_clio_qsr_oce
933
934
935   SUBROUTINE blk_clio_qsr_ice( pa_ice_cs, pa_ice_os, pqsr_ice )
936      !!---------------------------------------------------------------------------
937      !!                     ***  ROUTINE blk_clio_qsr_ice  ***
938      !!                 
939      !!  ** Purpose :   Computation of the shortwave radiation at the ocean and the
940      !!               snow/ice surfaces.
941      !!         
942      !!  ** Method  : - computed qsr from the cloud cover for both ice and ocean
943      !!               - also initialise sbudyko and stauc once for all
944      !!----------------------------------------------------------------------
945      REAL(wp), INTENT(in   ), DIMENSION(:,:,:) ::   pa_ice_cs   ! albedo of ice under clear sky
946      REAL(wp), INTENT(in   ), DIMENSION(:,:,:) ::   pa_ice_os   ! albedo of ice under overcast sky
947      REAL(wp), INTENT(  out), DIMENSION(:,:,:) ::   pqsr_ice    ! shortwave radiation over the ice/snow
948      !!
949      INTEGER, PARAMETER  ::   jp24 = 24   ! sampling of the daylight period (sunrise to sunset) into 24 equal parts
950      !!
951      INTEGER  ::   ji, jj, jl, jt    ! dummy loop indices
952      INTEGER  ::   ijpl              ! number of ice categories (3rd dim of pqsr_ice)
953      INTEGER  ::   indaet            !  = -1, 0, 1 for odd, normal and leap years resp.
954      INTEGER  ::   iday              ! integer part of day
955      !!
956      REAL(wp) ::   zcmue, zcmue2, ztamr          ! temporary scalars
957      REAL(wp) ::   zmt1, zmt2, zmt3              !    -         -
958      REAL(wp) ::   zdecl, zsdecl, zcdecl         !    -         -
959      REAL(wp) ::   zlha, zdaycor, zes            !    -         -
960      REAL(wp) ::   zxday, zdist, zcoef, zcoef1   !    -         -
961      REAL(wp) ::   zqsr_ice_cs, zqsr_ice_os      !    -         -
962
963      REAL(wp), DIMENSION(:,:), POINTER ::   zev                      ! vapour pressure
964      REAL(wp), DIMENSION(:,:), POINTER ::   zdlha, zlsrise, zlsset   ! 2D workspace
965      REAL(wp), DIMENSION(:,:), POINTER ::   zps, zpc   ! sine (cosine) of latitude per sine (cosine) of solar declination
966      INTEGER(KIND=jpim), PARAMETER :: zhook_in = 0
967      INTEGER(KIND=jpim), PARAMETER :: zhook_out = 1
968      REAL(KIND=jprb)               :: zhook_handle
969
970      CHARACTER(LEN=*), PARAMETER :: RoutineName='BLK_CLIO_QSR_ICE'
971
972      IF (lhook) CALL dr_hook(RoutineName,zhook_in,zhook_handle)
973
974      !!---------------------------------------------------------------------
975      !
976      IF( nn_timing == 1 )  CALL timing_start('blk_clio_qsr_ice')
977      !
978      CALL wrk_alloc( jpi,jpj, zev, zdlha, zlsrise, zlsset, zps, zpc )
979
980      ijpl = SIZE(pqsr_ice, 3 )      ! number of ice categories
981     
982      ! Saturated water vapour and vapour pressure
983      ! ------------------------------------------
984!CDIR NOVERRCHK
985!CDIR COLLAPSE
986      DO jj = 1, jpj
987!CDIR NOVERRCHK
988         DO ji = 1, jpi           
989            ztamr = sf(jp_tair)%fnow(ji,jj,1) - rtt           
990            zmt1  = SIGN( 17.269,  ztamr )
991            zmt2  = SIGN( 21.875,  ztamr )
992            zmt3  = SIGN( 28.200, -ztamr )
993            zes = 611.0 * EXP(  ABS( ztamr ) * MIN ( zmt1, zmt2 )   &              ! Saturation water vapour
994               &                     / ( sf(jp_tair)%fnow(ji,jj,1) - 35.86  + MAX( 0.e0, zmt3 ) )  )
995            zev(ji,jj) = sf(jp_humi)%fnow(ji,jj,1) * zes * 1.0e-05                 ! vapour pressure 
996         END DO
997      END DO
998
999      !-----------------------------------!
1000      !  Computation of solar irradiance  !
1001      !-----------------------------------!
1002!!gm : hard coded  leap year ???
1003      indaet   = 1                                    ! = -1, 0, 1 for odd, normal and leap years resp.
1004      zxday = nday_year + rdtbs2 / rday               ! day of the year at which the fluxes are calculated
1005      iday  = INT( zxday )                            ! (centred at the middle of the ice time step)
1006      CALL flx_blk_declin( indaet, iday, zdecl )      ! solar declination of the current day
1007      zsdecl = SIN( zdecl * rad )                     ! its sine
1008      zcdecl = COS( zdecl * rad )                     ! its cosine
1009
1010     
1011      !  correction factor added for computation of shortwave flux to take into account the variation of
1012      !  the distance between the sun and the earth during the year (Oberhuber 1988)
1013      zdist    = zxday * 2. * rpi / REAL(nyear_len(1), wp)
1014      zdaycor  = 1.0 + 0.0013 * SIN( zdist ) + 0.0342 * COS( zdist )
1015
1016!CDIR NOVERRCHK
1017      DO jj = 1, jpj
1018!CDIR NOVERRCHK
1019         DO ji = 1, jpi
1020            !  product of sine (cosine) of latitude and sine (cosine) of solar declination
1021            zps(ji,jj) = SIN( gphit(ji,jj) * rad ) * zsdecl
1022            zpc(ji,jj) = COS( gphit(ji,jj) * rad ) * zcdecl
1023            !  computation of the both local time of sunrise and sunset
1024            zlsrise(ji,jj) = ACOS( - SIGN( 1.e0, zps(ji,jj) )    &
1025               &                   * MIN(  1.e0, SIGN( 1.e0, zps(ji,jj) ) * ( zps(ji,jj) / zpc(ji,jj) )  )   ) 
1026            zlsset (ji,jj) = - zlsrise(ji,jj)
1027            !  dividing the solar day into jp24 segments of length zdlha
1028            zdlha  (ji,jj) = ( zlsrise(ji,jj) - zlsset(ji,jj) ) / REAL( jp24, wp )
1029         END DO
1030      END DO
1031
1032
1033      !---------------------------------------------!
1034      !  shortwave radiation absorbed by the ice    !
1035      !---------------------------------------------!
1036      ! compute and sum ice qsr over the daylight for each ice categories
1037      pqsr_ice(:,:,:) = 0.e0
1038      zcoef1 = zdaycor / ( 2. * rpi )       ! Correction for the ellipsity of the earth orbit
1039     
1040      !                    !----------------------------!
1041      DO jl = 1, ijpl      !  loop over ice categories  !
1042         !                 !----------------------------!
1043!CDIR NOVERRCHK   
1044         DO jt = 1, jp24   
1045            zcoef = FLOAT( jt ) - 0.5
1046!CDIR NOVERRCHK     
1047!CDIR COLLAPSE
1048            DO jj = 1, jpj
1049!CDIR NOVERRCHK
1050               DO ji = 1, jpi
1051                  zlha = COS(  zlsrise(ji,jj) - zcoef * zdlha(ji,jj)  )                  ! local hour angle
1052                  zcmue              = MAX( 0.e0 ,   zps(ji,jj) + zpc(ji,jj) * zlha  )   ! cos of local solar altitude
1053                  zcmue2             = 1368.0 * zcmue * zcmue
1054                 
1055                  !  solar heat flux absorbed by the ice/snow system (Shine and Crane 1984 adapted to high albedo)
1056                  zqsr_ice_cs =  ( 1.0 - pa_ice_cs(ji,jj,jl) ) * zdlha(ji,jj) * zcmue2        &   ! clear sky
1057                     &        / ( ( 1.0 + zcmue ) * zev(ji,jj) + 1.2 * zcmue + 0.0455 )
1058                  zqsr_ice_os = zdlha(ji,jj) * SQRT( zcmue )                                  &   ! overcast sky
1059                     &        * ( 53.5 + 1274.5 * zcmue )      * ( 1.0 - 0.996  * pa_ice_os(ji,jj,jl) )    &
1060                     &        / (  1.0 + 0.139  * stauc(ji,jj) * ( 1.0 - 0.9435 * pa_ice_os(ji,jj,jl) ) )       
1061             
1062                  pqsr_ice(ji,jj,jl) = pqsr_ice(ji,jj,jl) + (  ( 1.0 - sf(jp_ccov)%fnow(ji,jj,1) ) * zqsr_ice_cs    &
1063                     &                                       +         sf(jp_ccov)%fnow(ji,jj,1)   * zqsr_ice_os  )
1064               END DO
1065            END DO
1066         END DO
1067         !
1068         ! Correction : Taking into account the ellipsity of the earth orbit
1069         pqsr_ice(:,:,jl) = pqsr_ice(:,:,jl) * zcoef1 * tmask(:,:,1)
1070         !
1071         !                 !--------------------------------!
1072      END DO               !  end loop over ice categories  !
1073      !                    !--------------------------------!
1074
1075
1076!!gm  : this should be suppress as input data have been passed through lbc_lnk
1077      DO jl = 1, ijpl
1078         CALL lbc_lnk( pqsr_ice(:,:,jl) , 'T', 1. )
1079      END DO
1080      !
1081      CALL wrk_dealloc( jpi,jpj, zev, zdlha, zlsrise, zlsset, zps, zpc )
1082      !
1083      IF( nn_timing == 1 )  CALL timing_stop('blk_clio_qsr_ice')
1084      !
1085      IF (lhook) CALL dr_hook(RoutineName,zhook_out,zhook_handle)
1086   END SUBROUTINE blk_clio_qsr_ice
1087
1088
1089   SUBROUTINE flx_blk_declin( ky, kday, pdecl )
1090      !!---------------------------------------------------------------------------
1091      !!               ***  ROUTINE flx_blk_declin  ***
1092      !!         
1093      !! ** Purpose :   Computation of the solar declination for the day
1094      !!       
1095      !! ** Method  :   ???
1096      !!---------------------------------------------------------------------
1097      INTEGER , INTENT(in   ) ::   ky      ! = -1, 0, 1 for odd, normal and leap years resp.
1098      INTEGER , INTENT(in   ) ::   kday    ! day of the year ( kday = 1 on january 1)
1099      REAL(wp), INTENT(  out) ::   pdecl   ! solar declination
1100      !!
1101      REAL(wp) ::   a0  =  0.39507671      ! coefficients for solar declinaison computation
1102      REAL(wp) ::   a1  = 22.85684301      !     "              ""                 "
1103      REAL(wp) ::   a2  = -0.38637317      !     "              ""                 "
1104      REAL(wp) ::   a3  =  0.15096535      !     "              ""                 "
1105      REAL(wp) ::   a4  = -0.00961411      !     "              ""                 "
1106      REAL(wp) ::   b1  = -4.29692073      !     "              ""                 "
1107      REAL(wp) ::   b2  =  0.05702074      !     "              ""                 "
1108      REAL(wp) ::   b3  = -0.09028607      !     "              ""                 "
1109      REAL(wp) ::   b4  =  0.00592797
1110      !!
1111      REAL(wp) ::   zday   ! corresponding day of type year (cf. ky)
1112      REAL(wp) ::   zp     ! temporary scalars
1113      INTEGER(KIND=jpim), PARAMETER :: zhook_in = 0
1114      INTEGER(KIND=jpim), PARAMETER :: zhook_out = 1
1115      REAL(KIND=jprb)               :: zhook_handle
1116
1117      CHARACTER(LEN=*), PARAMETER :: RoutineName='FLX_BLK_DECLIN'
1118
1119      IF (lhook) CALL dr_hook(RoutineName,zhook_in,zhook_handle)
1120
1121      !!---------------------------------------------------------------------
1122           
1123      IF    ( ky == 1 )  THEN   ;   zday = REAL( kday, wp ) - 0.5
1124      ELSEIF( ky == 3 )  THEN   ;   zday = REAL( kday, wp ) - 1.
1125      ELSE                      ;   zday = REAL( kday, wp )
1126      ENDIF
1127     
1128      zp = rpi * ( 2.0 * zday - 367.0 ) / REAL(nyear_len(1), wp)
1129     
1130      pdecl  = a0                                                                      &
1131         &   + a1 * COS( zp ) + a2 * COS( 2. * zp ) + a3 * COS( 3. * zp ) + a4 * COS( 4. * zp )   &
1132         &   + b1 * SIN( zp ) + b2 * SIN( 2. * zp ) + b3 * SIN( 3. * zp ) + b4 * SIN( 4. * zp )
1133      !
1134      IF (lhook) CALL dr_hook(RoutineName,zhook_out,zhook_handle)
1135   END SUBROUTINE flx_blk_declin
1136
1137   !!======================================================================
1138END MODULE sbcblk_clio
Note: See TracBrowser for help on using the repository browser.