New URL for NEMO forge!   http://forge.nemo-ocean.eu

Since March 2022 along with NEMO 4.2 release, the code development moved to a self-hosted GitLab.
This present forge is now archived and remained online for history.
sbcblk_clio.F90 in branches/UKMO/test_moci_test_suite/NEMOGCM/NEMO/OPA_SRC/SBC – NEMO

source: branches/UKMO/test_moci_test_suite/NEMOGCM/NEMO/OPA_SRC/SBC/sbcblk_clio.F90 @ 8243

Last change on this file since 8243 was 8243, checked in by andmirek, 7 years ago

#1914 working XIOS read, XIOS write and single processor read

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