SURFEX  V8_0
Surfex V8_0 release
 All Classes Files Functions Variables
coupling_ideal_flux.F90
Go to the documentation of this file.
1 !SFX_LIC Copyright 1994-2014 CNRS, Meteo-France and Universite Paul Sabatier
2 !SFX_LIC This is part of the SURFEX software governed by the CeCILL-C licence
3 !SFX_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt
4 !SFX_LIC for details. version 1.
5 ! ############################################################
6 SUBROUTINE coupling_ideal_flux (DGL, &
7  hprogram, hcoupling, ptimec, &
8  ptstep, kyear, kmonth, kday, ptime, ki, ksv, ksw, ptsun, pzenith, pazim, &
9  pzref, puref, pzs, pu, pv, pqa, pta, prhoa, psv, pco2, hsv, &
10  prain, psnow, plw, pdir_sw, psca_sw, psw_bands, pps, ppa, &
11  psftq, psfth, psfts, psfco2, psfu, psfv, &
12  ptrad, pdir_alb, psca_alb, pemis, ptsurf, pz0, pz0h, pqsurf, &
13  ppew_a_coef, ppew_b_coef, &
14  ppet_a_coef, ppeq_a_coef, ppet_b_coef, ppeq_b_coef, &
15  htest )
16 ! ############################################################
17 !
18 !!**** *COUPLING_IDEAL_FLUX * - Computes the surface fluxes for the temperature,
19 !! vapor, horizontal components of the wind and the scalar variables.
20 !!
21 !! PURPOSE
22 !! -------
23 ! Give prescribed values of the surface fluxes for the potential
24 ! temperature, the vapor, the horizontal components of the wind and the
25 ! scalar variables. These fluxes are unsteady when a diurnal cycle
26 ! is taken into account.
27 !
28 !!** METHOD
29 !! ------
30 !! A temporal interpolation is performed to recover the values of the
31 !! fluxes at every instant of the simulation. The different values of the
32 !! prescribed fluxes are given at their declarations.
33 !! For the wind, z0 can also be prescribed and the flux is determined
34 !! with a neutral drag coefficient.
35 !!
36 !!
37 !! REFERENCE
38 !! ---------
39 !!
40 !!
41 !! AUTHOR
42 !! ------
43 !! V. Masson
44 !! (from J. Cuxart and J. Stein)
45 !!
46 !! MODIFICATIONS
47 !! -------------
48 !! Original 01/2004
49 !! Modified 09/2012 : J. Escobar , SIZE(PTA) not allowed without-interface , replace by KI
50 !! B. Decharme 04/2013 new coupling variables
51 !! P. Le Moigne 03/2015 add diagnostics IDEAL case
52 !! R. ROEHRIG 06/2015 add PTSTEP in TEMP_FORC_DISTS
53 !-------------------------------------------------------------------------------
54 !
55 !* 0. DECLARATIONS
56 ! ------------
57 !
58 !
60 !
61 USE modd_csts, ONLY : xrd, xcpd, xp00, xpi, xlvtt, xday, xkarman, xtt, &
62  xlstt, xstefan
63 USE modd_ideal_flux, ONLY : nforcf, nforct, xsfth, xsftq, xsfts, xsfco2, &
64  custartype, xustar, xz0, xalb, xemis, xtsrad, &
65  xtimef, xtimet
66 USE modd_surf_par, ONLY : xundef
67 !
68 USE mode_sbls
69 USE mode_thermos
70 !
71 USE modi_diag_inline_ideal_n
72 USE modi_surface_aero_cond
73 USE modi_surface_ri
74 USE modi_surface_cd
75 !
76 USE yomhook ,ONLY : lhook, dr_hook
77 USE parkind1 ,ONLY : jprb
78 !
79 USE modi_abor1_sfx
80 !
81 IMPLICIT NONE
82 !
83 !* 0.1 declarations of arguments
84 !
85 !
86 TYPE(diag_ideal_t), INTENT(INOUT) :: dgl
87 !
88  CHARACTER(LEN=6), INTENT(IN) :: hprogram ! program calling surf. schemes
89  CHARACTER(LEN=1), INTENT(IN) :: hcoupling ! type of coupling
90  ! 'E' : explicit
91  ! 'I' : implicit
92 REAL, INTENT(IN) :: ptimec ! cumulated time since beginning of simulation
93 INTEGER, INTENT(IN) :: kyear ! current year (UTC)
94 INTEGER, INTENT(IN) :: kmonth ! current month (UTC)
95 INTEGER, INTENT(IN) :: kday ! current day (UTC)
96 REAL, INTENT(IN) :: ptime ! current time since midnight (UTC, s)
97 INTEGER, INTENT(IN) :: ki ! number of points
98 INTEGER, INTENT(IN) :: ksv ! number of scalars
99 INTEGER, INTENT(IN) :: ksw ! number of short-wave spectral bands
100 REAL, DIMENSION(KI), INTENT(IN) :: ptsun ! solar time (s from midnight)
101 REAL, INTENT(IN) :: ptstep ! atmospheric time-step (s)
102 REAL, DIMENSION(KI), INTENT(IN) :: pzref ! height of T,q forcing (m)
103 REAL, DIMENSION(KI), INTENT(IN) :: puref ! height of wind forcing (m)
104 !
105 REAL, DIMENSION(KI), INTENT(IN) :: pta ! air temperature forcing (K)
106 REAL, DIMENSION(KI), INTENT(IN) :: pqa ! air humidity forcing (kg/m3)
107 REAL, DIMENSION(KI), INTENT(IN) :: prhoa ! air density (kg/m3)
108 REAL, DIMENSION(KI,KSV),INTENT(IN) :: psv ! scalar variables
109 ! ! chemistry: first char. in HSV: '#' (molecule/m3)
110 ! !
111  CHARACTER(LEN=6), DIMENSION(KSV),INTENT(IN):: hsv ! name of all scalar variables
112 REAL, DIMENSION(KI), INTENT(IN) :: pu ! zonal wind (m/s)
113 REAL, DIMENSION(KI), INTENT(IN) :: pv ! meridian wind (m/s)
114 REAL, DIMENSION(KI,KSW),INTENT(IN) :: pdir_sw ! direct solar radiation (on horizontal surf.)
115 ! ! (W/m2)
116 REAL, DIMENSION(KI,KSW),INTENT(IN) :: psca_sw ! diffuse solar radiation (on horizontal surf.)
117 ! ! (W/m2)
118 REAL, DIMENSION(KSW),INTENT(IN) :: psw_bands ! mean wavelength of each shortwave band (m)
119 REAL, DIMENSION(KI), INTENT(IN) :: pzenith ! zenithal angle (radian from the vertical)
120 REAL, DIMENSION(KI), INTENT(IN) :: pazim ! azimuthal angle (radian from North, clockwise)
121 REAL, DIMENSION(KI), INTENT(IN) :: plw ! longwave radiation (on horizontal surf.)
122 ! ! (W/m2)
123 REAL, DIMENSION(KI), INTENT(IN) :: pps ! pressure at atmospheric model surface (Pa)
124 REAL, DIMENSION(KI), INTENT(IN) :: ppa ! pressure at forcing level (Pa)
125 REAL, DIMENSION(KI), INTENT(IN) :: pzs ! atmospheric model orography (m)
126 REAL, DIMENSION(KI), INTENT(IN) :: pco2 ! CO2 concentration in the air (kg/m3)
127 REAL, DIMENSION(KI), INTENT(IN) :: psnow ! snow precipitation (kg/m2/s)
128 REAL, DIMENSION(KI), INTENT(IN) :: prain ! liquid precipitation (kg/m2/s)
129 !
130 !
131 REAL, DIMENSION(KI), INTENT(OUT) :: psfth ! flux of heat (W/m2)
132 REAL, DIMENSION(KI), INTENT(OUT) :: psftq ! flux of water vapor (kg/m2/s)
133 REAL, DIMENSION(KI), INTENT(OUT) :: psfu ! zonal momentum flux (Pa)
134 REAL, DIMENSION(KI), INTENT(OUT) :: psfv ! meridian momentum flux (Pa)
135 REAL, DIMENSION(KI), INTENT(OUT) :: psfco2 ! flux of CO2 (m/s*kg_CO2/kg_air)
136 REAL, DIMENSION(KI,KSV),INTENT(OUT):: psfts ! flux of scalar var. (kg/m2/s)
137 !
138 REAL, DIMENSION(KI), INTENT(OUT) :: ptrad ! radiative temperature (K)
139 REAL, DIMENSION(KI,KSW),INTENT(OUT):: pdir_alb! direct albedo for each spectral band (-)
140 REAL, DIMENSION(KI,KSW),INTENT(OUT):: psca_alb! diffuse albedo for each spectral band (-)
141 REAL, DIMENSION(KI), INTENT(OUT) :: pemis ! emissivity (-)
142 !
143 REAL, DIMENSION(KI), INTENT(OUT) :: ptsurf ! surface effective temperature (K)
144 REAL, DIMENSION(KI), INTENT(OUT) :: pz0 ! roughness length for momentum (m)
145 REAL, DIMENSION(KI), INTENT(OUT) :: pz0h ! roughness length for heat (m)
146 REAL, DIMENSION(KI), INTENT(OUT) :: pqsurf ! specific humidity at surface (kg/kg)
147 !
148 REAL, DIMENSION(KI), INTENT(IN) :: ppew_a_coef! implicit coefficients
149 REAL, DIMENSION(KI), INTENT(IN) :: ppew_b_coef! needed if HCOUPLING='I'
150 REAL, DIMENSION(KI), INTENT(IN) :: ppet_a_coef
151 REAL, DIMENSION(KI), INTENT(IN) :: ppeq_a_coef
152 REAL, DIMENSION(KI), INTENT(IN) :: ppet_b_coef
153 REAL, DIMENSION(KI), INTENT(IN) :: ppeq_b_coef
154  CHARACTER(LEN=2), INTENT(IN) :: htest ! must be equal to 'OK'
155 
156 !
157 !
158 !* 0.2 declarations of local variables
159 !
160 REAL, DIMENSION(KI) :: zz0 ! roughness length
161 REAL, DIMENSION(KI) :: zlmo ! Monin-Obuhkov length
162 REAL, DIMENSION(KI) :: ztha ! air potential temperature
163 REAL, DIMENSION(KI) :: zrva ! water vapor mixing ratio
164 REAL, DIMENSION(KI) :: zustar ! friction velocity
165 REAL, DIMENSION(KI) :: zwind ! wind
166 REAL, DIMENSION(KI) :: zq0 ! surface temperature flux (mK/s)
167 REAL, DIMENSION(KI) :: ze0 ! surface vapor flux (mkg/kg/s)
168 REAL, DIMENSION(KI) :: zqa ! specific humidity (kg/kg)
169 REAL, DIMENSION(KI) :: zdircoszw
170 REAL, DIMENSION(KI) :: zexns, zexna
171 REAL, DIMENSION(KI) :: zac, zra, zch, zcd, zcdn, zri
172 REAL, DIMENSION(KI) :: zhu
173 REAL, DIMENSION(KI) :: zle ! total latent heat flux (W/m2)
174 REAL, DIMENSION(KI) :: zlei ! sublimation heat flux (W/m2)
175 REAL, DIMENSION(KI) :: zsubl ! sublimation (kg/m2/s)
176 REAL, DIMENSION(KI) :: zlwup ! upward longwave flux at t
177 REAL, DIMENSION(KI,KSW) :: zdir_alb ! Direct albedo at time t ,
178 REAL, DIMENSION(KI,KSW) :: zsca_alb ! Diffuse albedo at time t
179 !
180 INTEGER :: iswb ! number of shortwave spectral bands
181 INTEGER :: jswb ! loop counter on shortwave spectral bands
182 !
183 REAL :: zalpha ! interpolation coefficient
184 INTEGER :: ihourf ! number of hours since midnight
185 INTEGER :: ihourt
186 INTEGER :: jiter ! convergence loop counter
187 INTEGER :: jsv ! loop on scalar variables
188 !
189 LOGICAL :: gcall_lmo ! flag in non-neutral case
190 !
191 INTEGER :: iluout ! output listing logical unit
192 REAL(KIND=JPRB) :: zhook_handle
193 !
194 !-------------------------------------------------------------------------------------
195 IF (lhook) CALL dr_hook('COUPLING_IDEAL_FLUX',0,zhook_handle)
196 IF (htest/='OK') THEN
197  CALL abor1_sfx('COUPLING_IDEAL_FLUX: FATAL ERROR DURING ARGUMENT TRANSFER')
198 END IF
199 !----------------------------------------------------------------------------------
200 zle(:) = xundef
201 zlei(:) = xundef
202 zsubl(:) = xundef
203 zlwup(:) = xundef
204 !
205 !* 2. COMPUTE TIME
206 ! ------------
207 !
208  CALL temp_forc_dists(ptimec,ptstep,nforcf,xtimef,ihourf,zalpha)
209 !
210 !----------------------------------------------------------------------------------
211 !
212 !* 3. CONS. TEMPERATURE SURFACE FLUX
213 ! ------------------------------
214 !
215 psfth(:) = xsfth(ihourf) + ( xsfth(ihourf+1)-xsfth(ihourf) )*zalpha
216 !
217 gcall_lmo = ( xsfth(ihourf) + ( xsfth(ihourf+1)-xsfth(ihourf) )*zalpha ) /=0.
218 !----------------------------------------------------------------------------------
219 !
220 !* 4. CONS. MIXING RATIO SURFACE FLUX
221 ! -------------------------------
222 !
223 psftq(:) = xsftq(ihourf) + ( xsftq(ihourf+1)-xsftq(ihourf) )*zalpha
224 !
225 gcall_lmo = gcall_lmo .OR. ( xsftq(ihourf) + ( xsftq(ihourf+1)-xsftq(ihourf) )*zalpha ) /=0.
226 !----------------------------------------------------------------------------------
227 !
228 !* 5. WIND SURFACE FLUX
229 ! -----------------
230 !
231 !* 5.1 wind
232 !
233 zwind(:) = sqrt(pu**2+pv**2)
234 !
235 !* 5.2 Compute the surface stresses
236 !
237 SELECT CASE (custartype)
238 !
239 !
240  CASE ('USTAR')
241  ! when u* is prescribed
242  zustar(:) = xustar(ihourf) + ( xustar(ihourf+1)-xustar(ihourf) )*zalpha
243  !
244  CASE ('Z0 ')
245  !
246  !* spatialized roughness length
247  !
248  zz0(:) = xz0
249  !
250  !* water mixing ratio
251  !
252  zrva(:) = 0.
253  zqa(:) = pqa(:) / prhoa(:)
254  !
255  WHERE (zqa(:)/=0.) zrva(:) = 1./(1./zqa(:) - 1.)
256  !
257  !* air potential temperature
258  ztha(:) = pta(:) * (xp00/ppa(:))**(xrd/xcpd)
259  !
260  !* cinematic surface fluxes
261  zq0(:) = psfth(:) / xcpd / prhoa(:)
262  ze0(:) = psftq(:) / prhoa(:)
263  !
264  !
265  !* neutral case, as guess
266  zlmo(:) = xundef
267  zustar(:) = ustar(zwind(:),pzref(:),zz0(:),zlmo(:))
268  !
269  !* iterations in non-neutral case
270  IF (gcall_lmo) THEN
271  zustar(:) = max( zustar(:), 0.01 )
272  DO jiter=1,10
273  zlmo(:) = lmo(zustar(:),ztha(:),zrva(:),zq0(:),ze0(:))
274  zustar(:) = ustar(zwind(:),pzref(:),zz0(:),zlmo(:))
275  END DO
276  END IF
277  !
278  !
279 END SELECT
280 !
281 psfu = 0.
282 psfv = 0.
283 WHERE (zwind>0.)
284  psfu = - prhoa * zustar**2 * pu / zwind
285  psfv = - prhoa * zustar**2 * pv / zwind
286 END WHERE
287 !
288 !-------------------------------------------------------------------------------
289 !
290 !* 6. SCALAR VARIABLES FLUXES.
291 ! -----------------------
292 !
293 DO jsv=1,SIZE(psfts,2)
294  psfts(:,jsv) = xsfts(ihourf,jsv) + ( xsfts(ihourf+1,jsv)-xsfts(ihourf,jsv) )*zalpha
295 END DO
296 !
297 !-------------------------------------------------------------------------------
298 !
299 !* 7. CO2 FLUXES.
300 ! ----------
301 !
302 psfco2(:) = xsfco2(ihourf) + ( xsfco2(ihourf+1)-xsfco2(ihourf) )*zalpha
303 !
304 !-------------------------------------------------------------------------------
305 !
306 !* 8. OTHER OUTPUTS (RADIATIVE QUANTITIES) SET TO A CONSTANT VALUE
307 ! ------------------------------------
308 !
309  CALL temp_forc_dists(ptimec,ptstep,nforct,xtimet,ihourt,zalpha)
310 !
311 ptrad(:) = xtsrad(ihourt) + ( xtsrad(ihourt+1)-xtsrad(ihourt) )*zalpha
312 !
313 pdir_alb = xalb
314 psca_alb = xalb
315 pemis = xemis
316 !
317 ptsurf(:) = ptrad(:)
318 pz0(:) = xz0
319 pz0h(:) = xz0
320 pqsurf(:) = qsat(ptsurf(:),pps(:))
321 !
322 !-------------------------------------------------------------------------------
323 !
324 !* 9. INLINE DIAGNOSTICS
325 ! ------------------
326 !
327 zdircoszw = 1.
328 !
329 zexns(:) = (pps(:)/xp00)**(xrd/xcpd)
330 zexna(:) = (ppa(:)/xp00)**(xrd/xcpd)
331 zqa(:) = pqa(:) / prhoa(:)
332 !
333 zhu(:)=1.
334 !
335 WHERE (ptsurf(:)<xtt)
336  zle(:) = psftq(:) * xlstt
337  zlei(:) = psftq(:) * xlstt
338  zsubl(:) = psftq(:)
339 ELSEWHERE
340  zle(:) = psftq(:) * xlvtt
341  zlei(:) = 0.0
342  zsubl(:) = 0.0
343 END WHERE
344 !
345 zlwup(:)=(1.-pemis(:))*plw(:)+pemis(:)*xstefan*ptsurf(:)**4
346 !
347  CALL surface_ri(ptsurf,pqsurf,zexns,zexna,pta,pqa, &
348  pzref, puref, zdircoszw,zwind,zri)
349 
350  CALL surface_aero_cond(zri, pzref, puref, zwind, pz0, pz0h, zac, zra, zch)
351 
352  CALL surface_cd(zri, pzref, puref, pz0, pz0h, zcd, zcdn)
353 
354  CALL diag_inline_ideal_n(dgl, ptstep, pta, ptsurf, zqa, ppa, pps, prhoa, pu, &
355  pv, pzref, puref, prain, psnow, &
356  zcd, zcdn, zch, zri, zhu, pz0, &
357  pz0h, pqsurf, psfth, psftq, psfu, psfv, &
358  pdir_sw, psca_sw, plw, pdir_alb, psca_alb, &
359  zle, zlei, zsubl, zlwup )
360 !
361 IF (lhook) CALL dr_hook('COUPLING_IDEAL_FLUX',1,zhook_handle)
362 !
363 !-------------------------------------------------------------------------------
364  CONTAINS
365 !
366 SUBROUTINE temp_forc_dists (PTIMEIN,PSTEP,KFORC,PTIMES,KHOUR,PALPHA)
367 !
368 IMPLICIT NONE
369 !
370 REAL, INTENT(IN) :: ptimein
371 REAL, INTENT(IN) :: pstep
372 INTEGER, INTENT(IN) :: kforc
373 REAL, DIMENSION(:), INTENT(IN) :: ptimes
374 INTEGER, INTENT(OUT):: khour
375 REAL, INTENT(OUT):: palpha
376 !
377 INTEGER :: jt
378 REAL :: ztimein
379 REAL(KIND=JPRB) :: zhook_handle
380 !
381 IF (lhook) CALL dr_hook('COUPLING_IDEAL_FLUX:TEMP_FORC_DISTS',0,zhook_handle)
382 !
383 ztimein = ptimein
384 !
385 IF (ptimes(kforc)==xundef) THEN
386  khour = 1
387  palpha = 0.
388 ELSEIF (ztimein<ptimes(1).OR.ztimein>ptimes(kforc)) THEN
389  WRITE(*,*) 'COUPLING_IDEAL_FLUX', ztimein, ptimes(1), ptimes(kforc)
390  CALL abor1_sfx("COUPLING_IDEAL_FLUX:TEMP_FORC_DISTS: PTIMEC OUT OF BOUNDS!!!")
391 ELSEIF (ztimein==ptimes(kforc)) THEN
392  khour = kforc
393  palpha = 0.
394 ELSE
395  DO jt = kforc,1,-1
396  IF (ptimein.GE.ptimes(jt)) THEN
397  khour = jt
398  EXIT
399  ENDIF
400  ENDDO
401  palpha = (ptimein-ptimes(khour)) / (ptimes(khour+1)-ptimes(khour))
402 ENDIF
403 !
404 IF (lhook) CALL dr_hook('COUPLING_IDEAL_FLUX:TEMP_FORC_DISTS',1,zhook_handle)
405 !
406 END SUBROUTINE temp_forc_dists
407 !
408 END SUBROUTINE coupling_ideal_flux
subroutine surface_ri(PTG, PQS, PEXNS, PEXNA, PTA, PQA, PZREF, PUREF, PDIRCOSZW, PVMOD, PRI)
Definition: surface_ri.F90:6
subroutine temp_forc_dists(PTIMEIN, PSTEP, KFORC, PTIMES, KHOUR, PALPHA)
subroutine coupling_ideal_flux(DGL, HPROGRAM, HCOUPLING, PTIMEC, PTSTEP, KYEAR, KMONTH, KDAY, PTIME, KI, KSV, KSW, PTSUN, PZENITH, PAZIM, PZREF, PUREF, PZS, PU, PV, PQA, PTA, PRHOA, PSV, PCO2, HSV, PRAIN, PSNOW, PLW, PDIR_SW, PSCA_SW, PSW_BANDS, PPS, PPA, PSFTQ, PSFTH, PSFTS, PSFCO2, PSFU, PSFV, PTRAD, PDIR_ALB, PSCA_ALB, PEMIS, PTSURF, PZ0, PZ0H, PQSURF, PPEW_A_COEF, PPEW_B_COEF, PPET_A_COEF, PPEQ_A_COEF, PPET_B_COEF, PPEQ_B_COEF, HTEST)
subroutine abor1_sfx(YTEXT)
Definition: abor1_sfx.F90:6
subroutine surface_aero_cond(PRI, PZREF, PUREF, PVMOD, PZ0, PZ0H, PAC, PRA, PCH)
subroutine surface_cd(PRI, PZREF, PUREF, PZ0EFF, PZ0H, PCD, PCDN)
Definition: surface_cd.F90:6
subroutine diag_inline_ideal_n(DGL, PTSTEP, PTA, PTS, PQA, PPA, PPS, PRHOA, PZONA, PMERA, PHT, PHW, PRAIN, PSNOW, PCD, PCDN, PCH, PRI, PHU, PZ0, PZ0H, PQSAT, PSFTH, PSFTQ, PSFZON, PSFMER, PDIR_SW, PSCA_SW, PLW, PDIR_ALB, PSCA_ALB, PLE, PLEI, PSUBL, PLWUP)