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_coare3p6.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_coare3p6.F90 @ 11666

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

LB: improved syntax

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