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/2013/dev_r4028_CNRS_LIM3/NEMOGCM/NEMO/OPA_SRC/SBC – NEMO

source: branches/2013/dev_r4028_CNRS_LIM3/NEMOGCM/NEMO/OPA_SRC/SBC/sbcblk_clio.F90 @ 4634

Last change on this file since 4634 was 4634, checked in by clem, 10 years ago

major changes in heat budget

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