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/2012/dev_r3385_NOCS04_HAMF/NEMOGCM/NEMO/OPA_SRC/SBC – NEMO

source: branches/2012/dev_r3385_NOCS04_HAMF/NEMOGCM/NEMO/OPA_SRC/SBC/sbcblk_clio.F90 @ 3396

Last change on this file since 3396 was 3396, checked in by acc, 12 years ago

Branch: dev_r3385_NOCS04_HAMF; #665. Stage 1 of 2012 development: porting of changes on old development branch (2011/DEV_r1837_mass_heat_salt_fluxes) into new branch. Corrected a few errors on the way. This branch now compiles but is incomplete. Still missing LIM3 changes which must reside on a certain persons laptop somewhere

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