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_algo_coare3p0.F90 in NEMO/branches/2019/dev_r11085_ASINTER-05_Brodeau_Advanced_Bulk/src/OCE/SBC – NEMO

source: NEMO/branches/2019/dev_r11085_ASINTER-05_Brodeau_Advanced_Bulk/src/OCE/SBC/sbcblk_algo_coare3p0.F90 @ 11772

Last change on this file since 11772 was 11772, checked in by laurent, 5 years ago

LB: solid updates+improvements of cool-skin/warm-layer capabilty of COARE and ECMWF bulk algorithms!

File size: 25.6 KB
Line 
1MODULE sbcblk_algo_coare3p0
2   !!======================================================================
3   !!                   ***  MODULE  sbcblk_algo_coare3p0  ***
4   !!
5   !!                After Fairall et al, 2003
6   !! Computes:
7   !!   * bulk transfer coefficients C_D, C_E and C_H
8   !!   * air temp. and spec. hum. adjusted from zt (2m) to zu (10m) if needed
9   !!   * the effective bulk wind speed at 10m U_blk
10   !!   => all these are used in bulk formulas in sbcblk.F90
11   !!
12   !!       Routine turb_coare3p0 maintained and developed in AeroBulk
13   !!                     (https://github.com/brodeau/aerobulk)
14   !!
15   !! ** Author: L. Brodeau, June 2019 / AeroBulk (https://github.com/brodeau/aerobulk)
16   !!----------------------------------------------------------------------
17   !! History :  4.0  !  2016-02  (L.Brodeau)   Original code
18   !!----------------------------------------------------------------------
19
20   !!----------------------------------------------------------------------
21   !!   turb_coare3p0  : computes the bulk turbulent transfer coefficients
22   !!                   adjusts t_air and q_air from zt to zu m
23   !!                   returns the effective bulk wind speed at 10m
24   !!----------------------------------------------------------------------
25   USE oce             ! ocean dynamics and tracers
26   USE dom_oce         ! ocean space and time domain
27   USE phycst          ! physical constants
28   USE iom             ! I/O manager library
29   USE lib_mpp         ! distribued memory computing library
30   USE in_out_manager  ! I/O manager
31   USE prtctl          ! Print control
32   USE sbcwave, ONLY   :  cdn_wave ! wave module
33#if defined key_si3 || defined key_cice
34   USE sbc_ice         ! Surface boundary condition: ice fields
35#endif
36   USE lib_fortran     ! to use key_nosignedzero
37
38   USE sbc_oce         ! Surface boundary condition: ocean fields
39   USE sbcblk_phy      ! all thermodynamics functions, rho_air, q_sat, etc... !LB
40   USE sbcblk_skin_coare ! cool-skin/warm layer scheme (CSWL_ECMWF) !LB
41
42   IMPLICIT NONE
43   PRIVATE
44
45   PUBLIC :: COARE3P0_INIT, TURB_COARE3P0
46
47   !                                              !! COARE own values for given constants:
48   REAL(wp), PARAMETER ::   zi0     = 600._wp     ! scale height of the atmospheric boundary layer...
49   REAL(wp), PARAMETER ::   Beta0   =   1.25_wp   ! gustiness parameter
50
51   INTEGER , PARAMETER ::   nb_itt = 10             ! number of itterations
52
53   !!----------------------------------------------------------------------
54CONTAINS
55
56
57   SUBROUTINE coare3p0_init(l_use_cs, l_use_wl)
58      !!---------------------------------------------------------------------
59      !!                  ***  FUNCTION coare3p0_init  ***
60      !!
61      !! INPUT :
62      !! -------
63      !!    * l_use_cs : use the cool-skin parameterization
64      !!    * l_use_wl : use the warm-layer parameterization
65      !!---------------------------------------------------------------------
66      LOGICAL , INTENT(in) ::   l_use_cs ! use the cool-skin parameterization
67      LOGICAL , INTENT(in) ::   l_use_wl ! use the warm-layer parameterization
68      INTEGER :: ierr
69      !!---------------------------------------------------------------------
70      IF ( l_use_wl ) THEN
71         ierr = 0
72         ALLOCATE ( Tau_ac(jpi,jpj) , Qnt_ac(jpi,jpj), Hz_wl(jpi,jpj), dT_wl(jpi,jpj), STAT=ierr )
73         !IF( ierr > 0 ) STOP ' COARE3P0_INIT => allocation of Tau_ac and Qnt_ac failed!'
74         Tau_ac(:,:) = 0._wp
75         Qnt_ac(:,:) = 0._wp
76         Hz_wl(:,:)  = Hwl_max
77         dT_wl(:,:)  = 0._wp
78      END IF
79      !!
80      IF ( l_use_cs ) THEN
81         ierr = 0
82         ALLOCATE ( dT_cs(jpi,jpj), STAT=ierr )
83         !IF( ierr > 0 ) STOP ' COARE3P0_INIT => allocation of dT_cs and Qnt_ac failed!'
84         dT_cs(:,:) = -0.25_wp  ! First guess of skin correction
85      END IF
86   END SUBROUTINE coare3p0_init
87
88
89
90   SUBROUTINE turb_coare3p0( kt, zt, zu, T_s, t_zt, q_s, q_zt, U_zu, l_use_cs, l_use_wl, &
91      &                      Cd, Ch, Ce, t_zu, q_zu, U_blk,                              &
92      &                      Cdn, Chn, Cen,                                              &
93      &                      Qsw, rad_lw, slp, pdT_cs,                                   & ! optionals for cool-skin (and warm-layer)
94      &                      pdT_wl, pHz_wl )                                                 ! optionals for warm-layer only
95      !!----------------------------------------------------------------------
96      !!                      ***  ROUTINE  turb_coare3p0  ***
97      !!
98      !! ** Purpose :   Computes turbulent transfert coefficients of surface
99      !!                fluxes according to Fairall et al. (2003)
100      !!                If relevant (zt /= zu), adjust temperature and humidity from height zt to zu
101      !!                Returns the effective bulk wind speed at zu to be used in the bulk formulas
102      !!
103      !!                Applies the cool-skin warm-layer correction of the SST to T_s
104      !!                if the net shortwave flux at the surface (Qsw), the downwelling longwave
105      !!                radiative fluxes at the surface (rad_lw), and the sea-leve pressure (slp)
106      !!                are provided as (optional) arguments!
107      !!
108      !! INPUT :
109      !! -------
110      !!    *  kt   : current time step (starts at 1)
111      !!    *  zt   : height for temperature and spec. hum. of air            [m]
112      !!    *  zu   : height for wind speed (usually 10m)                     [m]
113      !!    *  t_zt : potential air temperature at zt                         [K]
114      !!    *  q_zt : specific humidity of air at zt                          [kg/kg]
115      !!    *  U_zu : scalar wind speed at zu                                 [m/s]
116      !!    * l_use_cs : use the cool-skin parameterization
117      !!    * l_use_wl : use the warm-layer parameterization
118      !!
119      !! INPUT/OUTPUT:
120      !! -------------
121      !!    *  T_s  : always "bulk SST" as input                              [K]
122      !!              -> unchanged "bulk SST" as output if CSWL not used      [K]
123      !!              -> skin temperature as output if CSWL used              [K]
124      !!
125      !!    *  q_s  : SSQ aka saturation specific humidity at temp. T_s       [kg/kg]
126      !!              -> doesn't need to be given a value if skin temp computed (in case l_use_cs=True or l_use_wl=True)
127      !!              -> MUST be given the correct value if not computing skint temp. (in case l_use_cs=False or l_use_wl=False)
128      !!
129      !! OPTIONAL INPUT:
130      !! ---------------
131      !!    *  Qsw    : net solar flux (after albedo) at the surface (>0)     [W/m^2]
132      !!    *  rad_lw : downwelling longwave radiation at the surface  (>0)   [W/m^2]
133      !!    *  slp    : sea-level pressure                                    [Pa]
134      !!    * pdT_cs  : SST increment "dT" for cool-skin correction           [K]
135      !!    * pdT_wl  : SST increment "dT" for warm-layer correction          [K]
136      !!    * pHz_wl  : thickness of warm-layer                               [m]
137      !!
138      !! OUTPUT :
139      !! --------
140      !!    *  Cd     : drag coefficient
141      !!    *  Ch     : sensible heat coefficient
142      !!    *  Ce     : evaporation coefficient
143      !!    *  t_zu   : pot. air temperature adjusted at wind height zu       [K]
144      !!    *  q_zu   : specific humidity of air        //                    [kg/kg]
145      !!    *  U_blk  : bulk wind speed at zu                                 [m/s]
146      !!
147      !!
148      !! ** Author: L. Brodeau, June 2019 / AeroBulk (https://github.com/brodeau/aerobulk/)
149      !!----------------------------------------------------------------------------------
150      INTEGER,  INTENT(in   )                     ::   kt       ! current time step
151      REAL(wp), INTENT(in   )                     ::   zt       ! height for t_zt and q_zt                    [m]
152      REAL(wp), INTENT(in   )                     ::   zu       ! height for U_zu                             [m]
153      REAL(wp), INTENT(inout), DIMENSION(jpi,jpj) ::   T_s      ! sea surface temperature                [Kelvin]
154      REAL(wp), INTENT(in   ), DIMENSION(jpi,jpj) ::   t_zt     ! potential air temperature              [Kelvin]
155      REAL(wp), INTENT(inout), DIMENSION(jpi,jpj) ::   q_s      ! sea surface specific humidity           [kg/kg]
156      REAL(wp), INTENT(in   ), DIMENSION(jpi,jpj) ::   q_zt     ! specific air humidity at zt             [kg/kg]
157      REAL(wp), INTENT(in   ), DIMENSION(jpi,jpj) ::   U_zu     ! relative wind module at zu                [m/s]
158      LOGICAL , INTENT(in   )                     ::   l_use_cs ! use the cool-skin parameterization
159      LOGICAL , INTENT(in   )                     ::   l_use_wl ! use the warm-layer parameterization
160      REAL(wp), INTENT(  out), DIMENSION(jpi,jpj) ::   Cd       ! transfer coefficient for momentum         (tau)
161      REAL(wp), INTENT(  out), DIMENSION(jpi,jpj) ::   Ch       ! transfer coefficient for sensible heat (Q_sens)
162      REAL(wp), INTENT(  out), DIMENSION(jpi,jpj) ::   Ce       ! transfert coefficient for evaporation   (Q_lat)
163      REAL(wp), INTENT(  out), DIMENSION(jpi,jpj) ::   t_zu     ! pot. air temp. adjusted at zu               [K]
164      REAL(wp), INTENT(  out), DIMENSION(jpi,jpj) ::   q_zu     ! spec. humidity adjusted at zu           [kg/kg]
165      REAL(wp), INTENT(  out), DIMENSION(jpi,jpj) ::   U_blk    ! bulk wind speed at zu                     [m/s]
166      REAL(wp), INTENT(  out), DIMENSION(jpi,jpj) ::   Cdn, Chn, Cen ! neutral transfer coefficients
167      !
168      REAL(wp), INTENT(in   ), OPTIONAL, DIMENSION(jpi,jpj) ::   Qsw      !             [W/m^2]
169      REAL(wp), INTENT(in   ), OPTIONAL, DIMENSION(jpi,jpj) ::   rad_lw   !             [W/m^2]
170      REAL(wp), INTENT(in   ), OPTIONAL, DIMENSION(jpi,jpj) ::   slp      !             [Pa]
171      REAL(wp), INTENT(  out), OPTIONAL, DIMENSION(jpi,jpj) ::   pdT_cs
172      !
173      REAL(wp), INTENT(  out), OPTIONAL, DIMENSION(jpi,jpj) ::   pdT_wl   !             [K]
174      REAL(wp), INTENT(  out), OPTIONAL, DIMENSION(jpi,jpj) ::   pHz_wl   !             [m]
175      !
176      INTEGER :: j_itt
177      LOGICAL :: l_zt_equal_zu = .FALSE.      ! if q and t are given at same height as U
178      !
179      REAL(wp), DIMENSION(jpi,jpj) ::  &
180         &  u_star, t_star, q_star, &
181         &  dt_zu, dq_zu,    &
182         &  znu_a,           & !: Nu_air, Viscosity of air
183         &  z0, z0t
184      REAL(wp), DIMENSION(jpi,jpj) ::   zeta_u        ! stability parameter at height zu
185      REAL(wp), DIMENSION(jpi,jpj) ::   ztmp0, ztmp1, ztmp2
186      REAL(wp), DIMENSION(:,:), ALLOCATABLE ::   zeta_t        ! stability parameter at height zt
187      !
188      REAL(wp), DIMENSION(:,:), ALLOCATABLE :: &
189         &                zsst,   &  ! to back up the initial bulk SST
190         &                pdTc,   &  ! SST increment "dT" for cool-skin correction           [K]
191         &                pdTw,   &  ! SST increment "dT" for warm layer correction          [K]
192         &                zHwl       ! depth of warm-layer [m]
193      CHARACTER(len=40), PARAMETER :: crtnm = 'turb_coare3p0@sbcblk_algo_coare3p0'
194      !!----------------------------------------------------------------------------------
195
196      IF ( kt == nit000 ) CALL COARE3P0_INIT(l_use_cs, l_use_wl)
197
198      l_zt_equal_zu = .FALSE.
199      IF( ABS(zu - zt) < 0.01_wp )   l_zt_equal_zu = .TRUE.    ! testing "zu == zt" is risky with double precision
200      IF( .NOT. l_zt_equal_zu )  ALLOCATE( zeta_t(jpi,jpj) )
201
202      !! Initializations for cool skin and warm layer:
203      IF ( l_use_cs ) THEN
204         IF( .NOT.(PRESENT(Qsw) .AND. PRESENT(rad_lw) .AND. PRESENT(slp)) ) THEN
205            PRINT *, ' * PROBLEM ('//TRIM(crtnm)//'): you need to provide Qsw, rad_lw & slp to use cool-skin param!'; STOP
206         END IF
207      END IF
208
209      IF ( l_use_wl ) THEN
210         IF(.NOT.(PRESENT(Qsw) .AND. PRESENT(rad_lw) .AND. PRESENT(slp) )) THEN
211            PRINT *, ' * PROBLEM ('//TRIM(crtnm)//'): you need to provide Qsw, rad_lw & slp to use warm-layer param!'; STOP
212         END IF
213      END IF
214
215      IF ( l_use_cs .OR. l_use_wl ) THEN
216         ALLOCATE ( zsst(jpi,jpj) )
217         zsst = T_s ! backing up the bulk SST
218         IF( l_use_cs ) T_s = T_s - 0.25_wp   ! First guess of correction
219         q_s    = rdct_qsat_salt*q_sat(MAX(T_s, 200._wp), slp) ! First guess of q_s !LOLO WL too!!!
220      END IF
221
222
223      !! First guess of temperature and humidity at height zu:
224      t_zu = MAX( t_zt ,  180._wp )   ! who knows what's given on masked-continental regions...
225      q_zu = MAX( q_zt , 1.e-6_wp )   !               "
226
227      !! Pot. temp. difference (and we don't want it to be 0!)
228      dt_zu = t_zu - T_s ;   dt_zu = SIGN( MAX(ABS(dt_zu),1.E-6_wp), dt_zu )
229      dq_zu = q_zu - q_s ;   dq_zu = SIGN( MAX(ABS(dq_zu),1.E-9_wp), dq_zu )
230
231      znu_a = visc_air(t_zu) ! Air viscosity (m^2/s) at zt given from temperature in (K)
232
233      U_blk = SQRT(U_zu*U_zu + 0.5_wp*0.5_wp) ! initial guess for wind gustiness contribution
234
235      ztmp0   = LOG(    zu*10000._wp) ! optimization: 10000. == 1/z0 (with z0 first guess == 0.0001)
236      ztmp1   = LOG(10._wp*10000._wp) !       "                    "               "
237      u_star = 0.035_wp*U_blk*ztmp1/ztmp0       ! (u* = 0.035*Un10)
238
239      z0     = alfa_charn_3p0(U_zu)*u_star*u_star/grav + 0.11_wp*znu_a/u_star
240      z0     = MIN(ABS(z0), 0.001_wp)  ! (prevent FPE from stupid values from masked region later on...) !#LOLO
241      z0t    = 1._wp / ( 0.1_wp*EXP(vkarmn/(0.00115/(vkarmn/ztmp1))) )
242      z0t    = MIN(ABS(z0t), 0.001_wp)  ! (prevent FPE from stupid values from masked region later on...) !#LOLO
243
244      Cd     = (vkarmn/ztmp0)**2    ! first guess of Cd
245
246      ztmp0 = vkarmn*vkarmn/LOG(zt/z0t)/Cd
247
248      ztmp2 = Ri_bulk( zu, T_s, t_zu, q_s, q_zu, U_blk ) ! Bulk Richardson Number (BRN)
249
250      !! First estimate of zeta_u, depending on the stability, ie sign of BRN (ztmp2):
251      ztmp1 = 0.5 + SIGN( 0.5_wp , ztmp2 )
252      ztmp0 = ztmp0*ztmp2
253      zeta_u = (1._wp-ztmp1) * (ztmp0/(1._wp+ztmp2/(-zu/(zi0*0.004_wp*Beta0**3)))) & !  BRN < 0
254         &  +     ztmp1   * (ztmp0*(1._wp + 27._wp/9._wp*ztmp2/ztmp0))               !  BRN > 0
255      !#LB: should make sure that the "ztmp0" of "27./9.*ztmp2/ztmp0" is "ztmp0*ztmp2" and not "ztmp0==vkarmn*vkarmn/LOG(zt/z0t)/Cd" !
256
257      !! First guess M-O stability dependent scaling params.(u*,t*,q*) to estimate z0 and z/L
258      ztmp0  = vkarmn/(LOG(zu/z0t) - psi_h_coare(zeta_u))
259
260      u_star = U_blk*vkarmn/(LOG(zu) - LOG(z0)  - psi_m_coare(zeta_u))
261      t_star = dt_zu*ztmp0
262      q_star = dq_zu*ztmp0
263
264      ! What needs to be done if zt /= zu:
265      IF( .NOT. l_zt_equal_zu ) THEN
266         !! First update of values at zu (or zt for wind)
267         zeta_t = zt*zeta_u/zu
268         ztmp0 = psi_h_coare(zeta_u) - psi_h_coare(zeta_t)
269         ztmp1 = LOG(zt/zu) + ztmp0
270         t_zu = t_zt - t_star/vkarmn*ztmp1
271         q_zu = q_zt - q_star/vkarmn*ztmp1
272         q_zu = (0.5_wp + SIGN(0.5_wp,q_zu))*q_zu !Makes it impossible to have negative humidity :
273         !
274         dt_zu = t_zu - T_s  ; dt_zu = SIGN( MAX(ABS(dt_zu),1.E-6_wp), dt_zu )
275         dq_zu = q_zu - q_s  ; dq_zu = SIGN( MAX(ABS(dq_zu),1.E-9_wp), dq_zu )
276      END IF
277
278      !! ITERATION BLOCK
279      DO j_itt = 1, nb_itt
280
281         !!Inverse of Monin-Obukov length (1/L) :
282         ztmp0 = One_on_L(t_zu, q_zu, u_star, t_star, q_star)  ! 1/L == 1/[Monin-Obukhov length]
283         ztmp0 = SIGN( MIN(ABS(ztmp0),200._wp), ztmp0 ) ! (prevents FPE from stupid values from masked region later on...) !#LOLO
284
285         ztmp1 = u_star*u_star   ! u*^2
286
287         !! Update wind at zu with convection-related wind gustiness in unstable conditions (Fairall et al. 2003, Eq.8):
288         ztmp2 = Beta0*Beta0*ztmp1*(MAX(-zi0*ztmp0/vkarmn,0._wp))**(2._wp/3._wp) ! square of wind gustiness contribution, ztmp2 == Ug^2
289         !!   ! Only true when unstable (L<0) => when ztmp0 < 0 => explains "-" before zi0
290         U_blk = MAX(SQRT(U_zu*U_zu + ztmp2), 0.2_wp)        ! include gustiness in bulk wind speed
291         ! => 0.2 prevents U_blk to be 0 in stable case when U_zu=0.
292
293         !! Stability parameters:
294         zeta_u = zu*ztmp0
295         zeta_u = SIGN( MIN(ABS(zeta_u),50.0_wp), zeta_u )
296         IF( .NOT. l_zt_equal_zu ) THEN
297            zeta_t = zt*ztmp0
298            zeta_t = SIGN( MIN(ABS(zeta_t),50.0_wp), zeta_t )
299         END IF
300
301         !! Adjustment the wind at 10m (not needed in the current algo form):
302         !IF ( zu \= 10._wp ) U10 = U_zu + u_star/vkarmn*(LOG(10._wp/zu) - psi_m_coare(10._wp*ztmp0) + psi_m_coare(zeta_u))
303
304         !! Roughness lengthes z0, z0t (z0q = z0t) :
305         ztmp2 = u_star/vkarmn*LOG(10./z0)                                 ! Neutral wind speed at 10m
306         z0    = alfa_charn_3p0(ztmp2)*ztmp1/grav + 0.11_wp*znu_a/u_star   ! Roughness length (eq.6)
307         ztmp1 = ( znu_a / (z0*u_star) )**0.6_wp    ! (1./Re_r)^0.72 (Re_r: roughness Reynolds number) COARE3.6-specific!
308         z0t   = MIN( 1.1E-4_wp , 5.5E-5_wp*ztmp1 ) ! Scalar roughness for both theta and q (eq.28) #LOLO: some use 1.15 not 1.1 !!!
309
310         !! Turbulent scales at zu :
311         ztmp0   = psi_h_coare(zeta_u)
312         ztmp1   = vkarmn/(LOG(zu) - LOG(z0t) - ztmp0) ! #LOLO: in ztmp0, some use psi_h_coare(zeta_t) rather than psi_h_coare(zeta_t) ???
313
314         t_star = dt_zu*ztmp1
315         q_star = dq_zu*ztmp1
316         u_star = U_blk*vkarmn/(LOG(zu) - LOG(z0) - psi_m_coare(zeta_u))
317
318         IF( .NOT. l_zt_equal_zu ) THEN
319            !! Re-updating temperature and humidity at zu if zt /= zu :
320            ztmp1 = LOG(zt/zu) + ztmp0 - psi_h_coare(zeta_t)
321            t_zu = t_zt - t_star/vkarmn*ztmp1
322            q_zu = q_zt - q_star/vkarmn*ztmp1
323         END IF
324
325
326         IF( l_use_cs ) THEN
327            !! Cool-skin contribution
328
329            CALL UPDATE_QNSOL_TAU( zu, T_s, q_s, t_zu, q_zu, u_star, t_star, q_star, U_zu, U_blk, slp, rad_lw, &
330               &                   ztmp1, zeta_u,  Qlat=ztmp2)  ! Qnsol -> ztmp1 / Tau -> zeta_u
331
332            CALL CS_COARE( Qsw, ztmp1, u_star, zsst, ztmp2 )  ! ! Qnsol -> ztmp1 / Qlat -> ztmp2
333
334            T_s(:,:) = zsst(:,:) + dT_cs(:,:)*tmask(:,:,1)
335            IF( l_use_wl ) T_s(:,:) = T_s(:,:) + dT_wl(:,:)*tmask(:,:,1)
336            q_s(:,:) = rdct_qsat_salt*q_sat(MAX(T_s(:,:), 200._wp), slp(:,:))
337
338         END IF
339
340         IF( l_use_wl ) THEN
341            !! Warm-layer contribution
342            CALL UPDATE_QNSOL_TAU( zu, T_s, q_s, t_zu, q_zu, u_star, t_star, q_star, U_zu, U_blk, slp, rad_lw, &
343               &                   ztmp1, zeta_u)  ! Qnsol -> ztmp1 / Tau -> zeta_u
344            !! In WL_COARE or , Tau_ac and Qnt_ac must be updated at the final itteration step => add a flag to do this!
345            CALL WL_COARE( Qsw, ztmp1, zeta_u, zsst, MOD(nb_itt,j_itt) )
346
347            !! Updating T_s and q_s !!!
348            T_s(:,:) = zsst(:,:) + dT_wl(:,:)*tmask(:,:,1)
349            IF( l_use_cs ) T_s(:,:) = T_s(:,:) + dT_cs(:,:)*tmask(:,:,1)
350            q_s(:,:) = rdct_qsat_salt*q_sat(MAX(T_s(:,:), 200._wp), slp(:,:))
351         END IF
352
353         IF( l_use_cs .OR. l_use_wl .OR. (.NOT. l_zt_equal_zu) ) THEN
354            dt_zu = t_zu - T_s ;  dt_zu = SIGN( MAX(ABS(dt_zu),1.E-6_wp), dt_zu )
355            dq_zu = q_zu - q_s ;  dq_zu = SIGN( MAX(ABS(dq_zu),1.E-9_wp), dq_zu )
356         END IF
357
358      END DO !DO j_itt = 1, nb_itt
359
360      ! compute transfer coefficients at zu :
361      ztmp0 = u_star/U_blk
362      Cd   = ztmp0*ztmp0
363      Ch   = ztmp0*t_star/dt_zu
364      Ce   = ztmp0*q_star/dq_zu
365
366      ztmp1 = zu + z0
367      Cdn = vkarmn*vkarmn / (log(ztmp1/z0 )*log(ztmp1/z0 ))
368      Chn = vkarmn*vkarmn / (log(ztmp1/z0t)*log(ztmp1/z0t))
369      Cen = Chn
370
371      IF( .NOT. l_zt_equal_zu ) DEALLOCATE( zeta_t )
372
373      IF ( l_use_cs .AND. PRESENT(pdT_cs) ) pdT_cs = dT_cs
374      IF ( l_use_wl .AND. PRESENT(pdT_wl) ) pdT_wl = dT_wl
375      IF ( l_use_wl .AND. PRESENT(pHz_wl) ) pHz_wl = Hz_wl
376
377      IF ( l_use_cs .OR. l_use_wl ) DEALLOCATE ( zsst )
378
379   END SUBROUTINE turb_coare3p0
380
381
382   FUNCTION alfa_charn_3p0( pwnd )
383      !!-------------------------------------------------------------------
384      !! Compute the Charnock parameter as a function of the wind speed
385      !!
386      !! (Fairall et al., 2003 p.577-578)
387      !!
388      !! Wind below 10 m/s :  alfa = 0.011
389      !! Wind between 10 and 18 m/s : linear increase from 0.011 to 0.018
390      !! Wind greater than 18 m/s :  alfa = 0.018
391      !!
392      !! Author: L. Brodeau, June 2016 / AeroBulk  (https://github.com/brodeau/aerobulk/)
393      !!-------------------------------------------------------------------
394      REAL(wp), DIMENSION(jpi,jpj) :: alfa_charn_3p0
395      REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: pwnd   ! wind speed
396      !
397      INTEGER  ::   ji, jj         ! dummy loop indices
398      REAL(wp) :: zw, zgt10, zgt18
399      !!-------------------------------------------------------------------
400      !
401      DO jj = 1, jpj
402         DO ji = 1, jpi
403            !
404            zw = pwnd(ji,jj)   ! wind speed
405            !
406            ! Charnock's constant, increases with the wind :
407            zgt10 = 0.5 + SIGN(0.5_wp,(zw - 10))  ! If zw<10. --> 0, else --> 1
408            zgt18 = 0.5 + SIGN(0.5_wp,(zw - 18.)) ! If zw<18. --> 0, else --> 1
409            !
410            alfa_charn_3p0(ji,jj) =  (1. - zgt10)*0.011    &    ! wind is lower than 10 m/s
411               &     + zgt10*((1. - zgt18)*(0.011 + (0.018 - 0.011) &
412               &      *(zw - 10.)/(18. - 10.)) + zgt18*( 0.018 ) )    ! Hare et al. (1999)
413            !
414         END DO
415      END DO
416      !
417   END FUNCTION alfa_charn_3p0
418
419   FUNCTION psi_m_coare( pzeta )
420      !!----------------------------------------------------------------------------------
421      !! ** Purpose: compute the universal profile stability function for momentum
422      !!             COARE 3.0, Fairall et al. 2003
423      !!             pzeta : stability paramenter, z/L where z is altitude
424      !!                     measurement and L is M-O length
425      !!       Stability function for wind speed and scalars matching Kansas and free
426      !!       convection forms with weighting f convective form, follows Fairall et
427      !!       al (1996) with profile constants from Grachev et al (2000) BLM stable
428      !!       form from Beljaars and Holtslag (1991)
429      !!
430      !! ** Author: L. Brodeau, June 2016 / AeroBulk (https://github.com/brodeau/aerobulk/)
431      !!----------------------------------------------------------------------------------
432      REAL(wp), DIMENSION(jpi,jpj) :: psi_m_coare
433      REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: pzeta
434      !
435      INTEGER  ::   ji, jj    ! dummy loop indices
436      REAL(wp) :: zta, zphi_m, zphi_c, zpsi_k, zpsi_c, zf, zc, zstab
437      !!----------------------------------------------------------------------------------
438      !
439      DO jj = 1, jpj
440         DO ji = 1, jpi
441            !
442            zta = pzeta(ji,jj)
443            !
444            zphi_m = ABS(1. - 15.*zta)**.25    !!Kansas unstable
445            !
446            zpsi_k = 2.*LOG((1. + zphi_m)/2.) + LOG((1. + zphi_m*zphi_m)/2.)   &
447               & - 2.*ATAN(zphi_m) + 0.5*rpi
448            !
449            zphi_c = ABS(1. - 10.15*zta)**.3333                   !!Convective
450            !
451            zpsi_c = 1.5*LOG((1. + zphi_c + zphi_c*zphi_c)/3.) &
452               &     - 1.7320508*ATAN((1. + 2.*zphi_c)/1.7320508) + 1.813799447
453            !
454            zf = zta*zta
455            zf = zf/(1. + zf)
456            zc = MIN(50._wp, 0.35_wp*zta)
457            zstab = 0.5 + SIGN(0.5_wp, zta)
458            !
459            psi_m_coare(ji,jj) = (1. - zstab) * ( (1. - zf)*zpsi_k + zf*zpsi_c ) & ! (zta < 0)
460               &                -   zstab     * ( 1. + 1.*zta     &                ! (zta > 0)
461               &                         + 0.6667*(zta - 14.28)/EXP(zc) + 8.525 )   !     "
462            !
463         END DO
464      END DO
465      !
466   END FUNCTION psi_m_coare
467
468
469   FUNCTION psi_h_coare( pzeta )
470      !!---------------------------------------------------------------------
471      !! Universal profile stability function for temperature and humidity
472      !! COARE 3.0, Fairall et al. 2003
473      !!
474      !! pzeta : stability paramenter, z/L where z is altitude measurement
475      !!         and L is M-O length
476      !!
477      !! Stability function for wind speed and scalars matching Kansas and free
478      !! convection forms with weighting f convective form, follows Fairall et
479      !! al (1996) with profile constants from Grachev et al (2000) BLM stable
480      !! form from Beljaars and Holtslag (1991)
481      !!
482      !! Author: L. Brodeau, June 2016 / AeroBulk
483      !!         (https://github.com/brodeau/aerobulk/)
484      !!----------------------------------------------------------------
485      !!
486      REAL(wp), DIMENSION(jpi,jpj) :: psi_h_coare
487      REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: pzeta
488      !
489      INTEGER  ::   ji, jj     ! dummy loop indices
490      REAL(wp) :: zta, zphi_h, zphi_c, zpsi_k, zpsi_c, zf, zc, zstab
491      !
492      DO jj = 1, jpj
493         DO ji = 1, jpi
494            !
495            zta = pzeta(ji,jj)
496            !
497            zphi_h = (ABS(1. - 15.*zta))**.5  !! Kansas unstable   (zphi_h = zphi_m**2 when unstable, zphi_m when stable)
498            !
499            zpsi_k = 2.*LOG((1. + zphi_h)/2.)
500            !
501            zphi_c = (ABS(1. - 34.15*zta))**.3333   !! Convective
502            !
503            zpsi_c = 1.5*LOG((1. + zphi_c + zphi_c*zphi_c)/3.) &
504               &    -1.7320508*ATAN((1. + 2.*zphi_c)/1.7320508) + 1.813799447
505            !
506            zf = zta*zta
507            zf = zf/(1. + zf)
508            zc = MIN(50._wp,0.35_wp*zta)
509            zstab = 0.5 + SIGN(0.5_wp, zta)
510            !
511            psi_h_coare(ji,jj) = (1. - zstab) * ( (1. - zf)*zpsi_k + zf*zpsi_c ) &
512               &                -   zstab     * ( (ABS(1. + 2.*zta/3.))**1.5     &
513               &                           + .6667*(zta - 14.28)/EXP(zc) + 8.525 )
514            !
515         END DO
516      END DO
517      !
518   END FUNCTION psi_h_coare
519
520   !!======================================================================
521END MODULE sbcblk_algo_coare3p0
Note: See TracBrowser for help on using the repository browser.