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_skin_ecmwf.F90 in NEMO/trunk/src/OCE/SBC – NEMO

source: NEMO/trunk/src/OCE/SBC/sbcblk_skin_ecmwf.F90 @ 14072

Last change on this file since 14072 was 14072, checked in by laurent, 3 years ago

Merging branch "2020/dev_r13648_ASINTER-04_laurent_bulk_ice", ticket #2369

File size: 15.7 KB
Line 
1MODULE sbcblk_skin_ecmwf
2   !!======================================================================
3   !!                   ***  MODULE  sbcblk_skin_ecmwf  ***
4   !!
5   !!   Module that gathers the cool-skin and warm-layer parameterization used
6   !!   by the IFS at ECMWF (recoded from scratch =>
7   !!   https://github.com/brodeau/aerobulk)
8   !!
9   !!  Mainly based on Zeng & Beljaars, 2005 with the more recent add-up from
10   !!  Takaya et al., 2010 when it comes to the warm-layer parameterization
11   !!  (contribution of extra mixing due to Langmuir circulation)
12   !!
13   !!  - Zeng X., and A. Beljaars, 2005: A prognostic scheme of sea surface skin
14   !!    temperature for modeling and data assimilation. Geophysical Research
15   !!    Letters, 32 (14) , pp. 1-4.
16   !!
17   !!  - Takaya, Y., J.-R. Bildot, A. C. M. Beljaars, and P. A. E. M. Janssen,
18   !!    2010: Refinements to a prognostic scheme of skin sea surface
19   !!    temperature. J. Geophys. Res., 115, C06009, doi:10.1029/2009JC005985
20   !!
21   !!   Most of the formula are taken from the documentation of IFS of ECMWF
22   !!            (cycle 40r1) (avaible online on the ECMWF's website)
23   !!
24   !!   Routine 'sbcblk_skin_ecmwf' also maintained and developed in AeroBulk (as
25   !!            'mod_skin_ecmwf')
26   !!    (https://github.com/brodeau/aerobulk)
27   !!
28   !! ** Author: L. Brodeau, November 2019 / AeroBulk (https://github.com/brodeau/aerobulk)
29   !!----------------------------------------------------------------------
30   !! History :  4.0  ! 2019-11  (L.Brodeau)   Original code
31   !!            4.2  ! 2020-12  (L. Brodeau) Introduction of various air-ice bulk parameterizations + improvements
32   !!----------------------------------------------------------------------
33   USE oce             ! ocean dynamics and tracers
34   USE dom_oce         ! ocean space and time domain
35   USE phycst          ! physical constants
36   USE sbc_oce         ! Surface boundary condition: ocean fields
37
38   USE sbc_phy         ! Catalog of functions for physical/meteorological parameters in the marine boundary layer
39
40   USE lib_mpp         ! distribued memory computing library
41   USE in_out_manager  ! I/O manager
42   USE lib_fortran     ! to use key_nosignedzero
43
44   IMPLICIT NONE
45   PRIVATE
46
47   PUBLIC :: CS_ECMWF, WL_ECMWF
48   !! * Substitutions
49#  include "do_loop_substitute.h90"
50
51   !! Cool-skin related parameters:
52   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:), PUBLIC :: dT_cs !: dT due to cool-skin effect
53   !                                                      ! => temperature difference between air-sea interface (z=0)
54   !                                                      !    and right below viscous layer (z=delta)
55
56   !! Warm-layer related parameters:
57   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:), PUBLIC :: dT_wl !: dT due to warm-layer effect
58   !                                                      ! => difference between "almost surface (right below
59   !                                                      !    viscous layer, z=delta) and depth of bulk SST (z=gdept_1d(1))
60   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:), PUBLIC :: Hz_wl !: depth (aka thickness) of warm-layer [m]
61   !
62   REAL(wp), PARAMETER, PUBLIC :: rd0  = 3.    !: Depth scale [m] of warm layer, "d" in Eq.11 (Zeng & Beljaars 2005)
63   REAL(wp), PARAMETER         :: zRhoCp_w = rho0_w*rCp0_w
64   !
65   REAL(wp), PARAMETER         :: rNuwl0 = 0.5  !: Nu (exponent of temperature profile) Eq.11
66   !                                            !: (Zeng & Beljaars 2005) !: set to 0.5 instead of
67   !                                            !: 0.3 to respect a warming of +3 K in calm
68   !                                            !: condition for the insolation peak of +1000W/m^2
69   !!----------------------------------------------------------------------
70CONTAINS
71
72
73   SUBROUTINE CS_ECMWF( pQsw, pQnsol, pustar, pSST )
74      !!---------------------------------------------------------------------
75      !!
76      !! Cool-skin parameterization, based on Fairall et al., 1996:
77      !!
78      !!  - Zeng X., and A. Beljaars, 2005: A prognostic scheme of sea surface
79      !!    skin temperature for modeling and data assimilation. Geophysical
80      !!    Research Letters, 32 (14) , pp. 1-4.
81      !!
82      !!------------------------------------------------------------------
83      !!
84      !!  **   INPUT:
85      !!     *pQsw*       surface net solar radiation into the ocean     [W/m^2] => >= 0 !
86      !!     *pQnsol*     surface net non-solar heat flux into the ocean [W/m^2] => normally < 0 !
87      !!     *pustar*     friction velocity u*                           [m/s]
88      !!     *pSST*       bulk SST (taken at depth gdept_1d(1))          [K]
89      !!------------------------------------------------------------------
90      REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: pQsw   ! net solar a.k.a shortwave radiation into the ocean (after albedo) [W/m^2]
91      REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: pQnsol ! non-solar heat flux to the ocean [W/m^2]
92      REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: pustar  ! friction velocity, temperature and humidity (u*,t*,q*)
93      REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: pSST ! bulk SST [K]
94      !!---------------------------------------------------------------------
95      INTEGER  :: ji, jj, jc
96      REAL(wp) :: zQabs, zdlt, zfr, zalfa, zus
97      !!---------------------------------------------------------------------
98      DO_2D( nn_hls, nn_hls, nn_hls, nn_hls )
99
100         zQabs = pQnsol(ji,jj) ! first guess of heat flux absorbed within the viscous sublayer of thicknes delta,
101         !                     !   => we DO not miss a lot assuming 0 solar flux absorbed in the tiny layer of thicknes zdlt...
102
103         zalfa = alpha_sw(pSST(ji,jj)) ! (crude) thermal expansion coefficient of sea-water [1/K]
104         zus   = pustar(ji,jj)
105
106         zdlt = delta_skin_layer( zalfa, zQabs, zus )
107
108         DO jc = 1, 4 ! because implicit in terms of zdlt...
109            zfr = MAX( 0.065_wp + 11._wp*zdlt  &
110               &       - 6.6E-5_wp/zdlt*(1._wp - EXP(-zdlt/8.E-4_wp)) &
111               &      , 0.01_wp ) ! Solar absorption, Eq.(5) Zeng & Beljaars, 2005
112            !                     !  =>  (WARNING: 0.065 rather than 0.137 in Fairal et al. 1996)
113            zQabs = pQnsol(ji,jj) + zfr*pQsw(ji,jj)
114            zdlt = delta_skin_layer( zalfa, zQabs, zus )
115         END DO
116
117         dT_cs(ji,jj) = zQabs*zdlt/rk0_w   ! temperature increment, yes dT_cs can actually > 0, if Qabs > 0 (rare but possible!)
118
119      END_2D
120
121   END SUBROUTINE CS_ECMWF
122
123
124   SUBROUTINE WL_ECMWF( pQsw, pQnsol, pustar, pSST,  pustk )
125      !!---------------------------------------------------------------------
126      !!
127      !!  Warm-Layer scheme according to Zeng & Beljaars, 2005 (GRL) with the
128      !!  more recent add-up from Takaya et al., 2010 when it comes to the
129      !!  warm-layer parameterization (contribution of extra mixing due to
130      !!  Langmuir circulation)
131      !!
132      !!  - Zeng X., and A. Beljaars, 2005: A prognostic scheme of sea surface skin
133      !!    temperature for modeling and data assimilation. Geophysical Research
134      !!    Letters, 32 (14) , pp. 1-4.
135      !!
136      !!  - Takaya, Y., J.-R. Bildot, A. C. M. Beljaars, and P. A. E. M. Janssen,
137      !!    2010: Refinements to a prognostic scheme of skin sea surface
138      !!    temperature. J. Geophys. Res., 115, C06009, doi:10.1029/2009JC005985
139      !!
140      !!  STIL NO PROGNOSTIC EQUATION FOR THE DEPTH OF THE WARM-LAYER!
141      !!
142      !!     ------------------------------------------------------------------
143      !!
144      !!  **   INPUT:
145      !!     *pQsw*       surface net solar radiation into the ocean     [W/m^2] => >= 0 !
146      !!     *pQnsol*     surface net non-solar heat flux into the ocean [W/m^2] => normally < 0 !
147      !!     *pustar*     friction velocity u*                           [m/s]
148      !!     *pSST*       bulk SST  (taken at depth gdept_1d(1))         [K]
149      !!------------------------------------------------------------------
150      REAL(wp), DIMENSION(jpi,jpj), INTENT(in)  :: pQsw     ! surface net solar radiation into the ocean [W/m^2]     => >= 0 !
151      REAL(wp), DIMENSION(jpi,jpj), INTENT(in)  :: pQnsol   ! surface net non-solar heat flux into the ocean [W/m^2] => normally < 0 !
152      REAL(wp), DIMENSION(jpi,jpj), INTENT(in)  :: pustar   ! friction velocity [m/s]
153      REAL(wp), DIMENSION(jpi,jpj), INTENT(in)  :: pSST     ! bulk SST at depth gdept_1d(1) [K]
154      !!
155      REAL(wp), DIMENSION(jpi,jpj), OPTIONAL, INTENT(in) :: pustk ! surface Stokes velocity [m/s]
156      !
157      INTEGER :: ji, jj, jc
158      !
159      REAL(wp) :: zHwl      !: thickness of the warm-layer [m]
160      REAL(wp) :: ztcorr    !: correction of dT w.r.t measurement depth of bulk SST (first T-point)
161      REAL(wp) :: zalfa     !: thermal expansion coefficient of sea-water [1/K]
162      REAL(wp) :: zdTwl_b, zdTwl_n  !: temp. diff. between "almost surface (right below viscous layer) and bottom of WL
163      REAL(wp) :: zfr, zeta
164      REAL(wp) :: zusw, zusw2
165      REAL(wp) :: zLa, zfLa
166      REAL(wp) :: flg, zwf, zQabs
167      REAL(wp) :: ZA, ZB, zL1, zL2
168      REAL(wp) :: zcst0, zcst1, zcst2, zcst3
169      !
170      LOGICAL :: l_pustk_known
171      !!---------------------------------------------------------------------
172
173      l_pustk_known = .FALSE.
174      IF( PRESENT(pustk) ) l_pustk_known = .TRUE.
175
176      DO_2D( nn_hls, nn_hls, nn_hls, nn_hls )
177
178         zHwl = Hz_wl(ji,jj) ! first guess for warm-layer depth (and unique..., less advanced than COARE3p6 !)
179         ! it is = rd0 (3m) in default Zeng & Beljaars case...
180
181         !! Previous value of dT / warm-layer, adapted to depth:
182         flg = 0.5_wp + SIGN( 0.5_wp , gdept_1d(1)-zHwl ) ! => 1 when gdept_1d(1)>zHwl (dT_wl(ji,jj) = zdTwl) | 0 when z_s$
183         ztcorr = flg + (1._wp - flg)*gdept_1d(1)/zHwl
184         zdTwl_b = MAX ( dT_wl(ji,jj) / ztcorr , 0._wp )
185         ! zdTwl is the difference between "almost surface (right below viscous layer) and bottom of WL (here zHwl)
186         ! pdT         "                          "                                    and depth of bulk SST (here gdept_1d(1))!
187         !! => but of course in general the bulk SST is taken shallower than zHwl !!! So correction less pronounced!
188         !! => so here since pdT is difference between surface and gdept_1d(1), need to increase fof zdTwl !
189
190         zalfa = alpha_sw( pSST(ji,jj) ) ! (crude) thermal expansion coefficient of sea-water [1/K] (SST accurate enough!)
191
192         ! *** zfr = Fraction of solar radiation absorbed in warm layer (-)
193         zfr = 1._wp - 0.28_wp*EXP(-71.5_wp*zHwl) - 0.27_wp*EXP(-2.8_wp*zHwl) - 0.45_wp*EXP(-0.07_wp*zHwl)  !: Eq. 8.157
194
195         zQabs = zfr*pQsw(ji,jj) + pQnsol(ji,jj)       ! tot heat absorbed in warm layer
196
197         zusw  = MAX( pustar(ji,jj), 1.E-4_wp ) * sq_radrw    ! u* in the water
198         zusw2 = zusw*zusw
199
200         ! Langmuir:
201         IF( l_pustk_known ) THEN
202            zLa = SQRT(zusw/MAX(pustk(ji,jj),1.E-6))
203         ELSE
204            zla = 0.3_wp
205         ENDIF
206         zfLa = MAX( zla**(-2._wp/3._wp) , 1._wp )   ! Eq.(6)
207
208         zwf = 0.5_wp + SIGN(0.5_wp, zQabs)  ! zQabs > 0. => 1.  / zQabs < 0. => 0.
209
210         zcst1 = vkarmn*grav*zalfa
211
212         ! 1/L when zQabs > 0 :
213         zL2 = zcst1*zQabs / (zRhoCp_w*zusw2*zusw)
214
215         zcst2 = zcst1 / ( 5._wp*zHwl*zusw2 )  !OR: zcst2 = zcst1*rNuwl0 / ( 5._wp*zHwl*zusw2 ) ???
216
217         zcst0 = rn_Dt * (rNuwl0 + 1._wp) / zHwl
218
219         ZA = zcst0 * zQabs / ( rNuwl0 * zRhoCp_w )
220
221         zcst3 = -zcst0 * vkarmn * zusw * zfLa
222
223         !! Sorry about all these constants ( constant w.r.t zdTwl), it's for
224         !! the sake of optimizations... So all these operations are not done
225         !! over and over within the iteration loop...
226
227         !! T R U L L Y   I M P L I C I T => needs itteration
228         !! => have to itterate just because the 1/(Monin-Obukhov length), zL1, uses zdTwl when zQabs < 0..
229         !!    (without this term otherwize the implicit analytical solution is straightforward...)
230         zdTwl_n = zdTwl_b
231         DO jc = 1, 10
232
233            zdTwl_n = 0.5_wp * ( zdTwl_n + zdTwl_b ) ! semi implicit, for faster convergence
234
235            ! 1/L when zdTwl > 0 .AND. zQabs < 0 :
236            zL1 =         SQRT( zdTwl_n * zcst2 ) ! / zusw !!! Or??? => vkarmn * SQRT( zdTwl_n*grav*zalfa/( 5._wp*zHwl ) ) / zusw
237
238            ! Stability parameter (z/L):
239            zeta =  (1._wp - zwf) * zHwl*zL1   +   zwf * zHwl*zL2
240
241            ZB = zcst3 / PHI(zeta)
242
243            zdTwl_n = MAX ( zdTwl_b + ZA + ZB*zdTwl_n , 0._wp )  ! Eq.(6)
244
245         END DO
246
247         !! Update:
248         dT_wl(ji,jj) = zdTwl_n * ztcorr
249
250      END_2D
251
252   END SUBROUTINE WL_ECMWF
253
254
255   FUNCTION delta_skin_layer( palpha, pQd, pustar_a )
256      !!---------------------------------------------------------------------
257      !! Computes the thickness (m) of the viscous skin layer.
258      !! Based on Fairall et al., 1996
259      !!
260      !! Fairall, C. W., Bradley, E. F., Godfrey, J. S., Wick, G. A.,
261      !! Edson, J. B., and Young, G. S. ( 1996), Cool‐skin and warm‐layer
262      !! effects on sea surface temperature, J. Geophys. Res., 101( C1), 1295-1308,
263      !! doi:10.1029/95JC03190.
264      !!
265      !! L. Brodeau, october 2019
266      !!---------------------------------------------------------------------
267      REAL(wp)                :: delta_skin_layer
268      REAL(wp), INTENT(in)    :: palpha   ! thermal expansion coefficient of sea-water (SST accurate enough!)
269      REAL(wp), INTENT(in)    :: pQd ! < 0 !!! part of the net heat flux actually absorbed in the WL [W/m^2]
270      !                              !  => term "Q + Rs*fs" in eq.6 of Fairall et al. 1996
271      REAL(wp), INTENT(in)    :: pustar_a ! friction velocity in the air (u*) [m/s]
272      !!---------------------------------------------------------------------
273      REAL(wp) :: zusw, zusw2, zlamb, ztf, ztmp
274      !!---------------------------------------------------------------------
275      ztf = 0.5_wp + SIGN(0.5_wp, pQd)  ! Qabs < 0 => cooling of the viscous layer => ztf = 0 (regular case)
276      !                                 ! Qabs > 0 => warming of the viscous layer => ztf = 1
277      !                                 !    (ex: weak evaporation and strong positive sensible heat flux)
278      zusw  = MAX(pustar_a, 1.E-4_wp) * sq_radrw    ! u* in the water
279      zusw2 = zusw*zusw
280      !
281      zlamb = 6._wp*( 1._wp + MAX(palpha*rcst_cs/(zusw2*zusw2)*pQd, 0._wp)**0.75 )**(-1./3.) ! see Eq.(14) in Fairall et al., 1996
282      !  => zlamb is not used when Qd > 0, and since rcst_cs < 0, we just use this "MAX" to prevent FPE errors (something_negative)**0.75
283      !
284      ztmp = rnu0_w/zusw
285      delta_skin_layer = (1._wp-ztf) *     zlamb*ztmp           &  ! regular case, Qd < 0, see Eq.(12) in Fairall et al., 1996
286         &               +   ztf     * MIN(6._wp*ztmp , 0.007_wp)  ! when Qd > 0
287   END FUNCTION delta_skin_layer
288
289
290   FUNCTION PHI( pzeta)
291      !!---------------------------------------------------------------------
292      !!
293      !! Takaya et al., 2010
294      !!  Eq.(5)
295      !! L. Brodeau, october 2019
296      !!---------------------------------------------------------------------
297      REAL(wp)                :: PHI
298      REAL(wp), INTENT(in)    :: pzeta    ! stability parameter
299      !!---------------------------------------------------------------------
300      REAL(wp) :: ztf, zzt2
301      !!---------------------------------------------------------------------
302      zzt2 = pzeta*pzeta
303      ztf = 0.5_wp + SIGN(0.5_wp, pzeta)  ! zeta > 0 => ztf = 1
304      !                                   ! zeta < 0 => ztf = 0
305      PHI =      ztf     * ( 1. + (5.*pzeta + 4.*zzt2)/(1. + 3.*pzeta + 0.25*zzt2) ) &   ! zeta > 0
306         &  + (1. - ztf) * 1./SQRT( 1. - 16.*(-ABS(pzeta)) )                             ! zeta < 0
307   END FUNCTION PHI
308
309   !!======================================================================
310END MODULE sbcblk_skin_ecmwf
Note: See TracBrowser for help on using the repository browser.