GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
! |
||
2 |
! $Id: calcul_fluxs_mod.F90 3815 2021-02-01 14:30:57Z lguez $ |
||
3 |
! |
||
4 |
MODULE calcul_fluxs_mod |
||
5 |
|||
6 |
IMPLICIT NONE |
||
7 |
|||
8 |
CONTAINS |
||
9 |
473954 |
SUBROUTINE calcul_fluxs( knon, nisurf, dtime, & |
|
10 |
tsurf, p1lay, cal, beta, cdragh, cdragq, ps, & |
||
11 |
precip_rain, precip_snow, snow, qsurf, & |
||
12 |
1152 |
radsol, dif_grnd, t1lay, q1lay, u1lay, v1lay, gustiness, & |
|
13 |
fqsat, petAcoef, peqAcoef, petBcoef, peqBcoef, & |
||
14 |
tsurf_new, evap, fluxlat, fluxsens, dflux_s, dflux_l, & |
||
15 |
✓✓✓✗ ✗✓✓✓ ✓✗✗✓ ✓✓✓✗ ✗✓ |
1152 |
sens_prec_liq, sens_prec_sol, lat_prec_liq, lat_prec_sol, rhoa) |
16 |
|||
17 |
|||
18 |
USE dimphy, ONLY : klon |
||
19 |
USE indice_sol_mod |
||
20 |
use sens_heat_rain_m, only: sens_heat_rain |
||
21 |
|||
22 |
INCLUDE "clesphys.h" |
||
23 |
|||
24 |
! Cette routine calcule les fluxs en h et q a l'interface et eventuellement |
||
25 |
! une temperature de surface (au cas ou ok_veget = false) |
||
26 |
! |
||
27 |
! L. Fairhead 4/2000 |
||
28 |
! |
||
29 |
! input: |
||
30 |
! knon nombre de points a traiter |
||
31 |
! nisurf surface a traiter |
||
32 |
! tsurf temperature de surface |
||
33 |
! p1lay pression 1er niveau (milieu de couche) |
||
34 |
! cal capacite calorifique du sol |
||
35 |
! beta evap reelle |
||
36 |
! cdragh coefficient d'echange temperature |
||
37 |
! cdragq coefficient d'echange evaporation |
||
38 |
! ps pression au sol |
||
39 |
! precip_rain precipitations liquides |
||
40 |
! precip_snow precipitations solides |
||
41 |
! snow champs hauteur de neige |
||
42 |
! runoff runoff en cas de trop plein |
||
43 |
! petAcoef coeff. A de la resolution de la CL pour t |
||
44 |
! peqAcoef coeff. A de la resolution de la CL pour q |
||
45 |
! petBcoef coeff. B de la resolution de la CL pour t |
||
46 |
! peqBcoef coeff. B de la resolution de la CL pour q |
||
47 |
! radsol rayonnement net aus sol (LW + SW) |
||
48 |
! dif_grnd coeff. diffusion vers le sol profond |
||
49 |
! |
||
50 |
! output: |
||
51 |
! tsurf_new temperature au sol |
||
52 |
! qsurf humidite de l'air au dessus du sol |
||
53 |
! fluxsens flux de chaleur sensible |
||
54 |
! fluxlat flux de chaleur latente |
||
55 |
! dflux_s derivee du flux de chaleur sensible / Ts |
||
56 |
! dflux_l derivee du flux de chaleur latente / Ts |
||
57 |
! sens_prec_liq flux sensible li� aux echanges de precipitations liquides |
||
58 |
! sens_prec_sol precipitations solides |
||
59 |
! lat_prec_liq flux latent li� aux echanges de precipitations liquides |
||
60 |
! lat_prec_sol precipitations solides |
||
61 |
|||
62 |
INCLUDE "YOETHF.h" |
||
63 |
INCLUDE "FCTTRE.h" |
||
64 |
INCLUDE "YOMCST.h" |
||
65 |
|||
66 |
! Parametres d'entree |
||
67 |
!**************************************************************************************** |
||
68 |
INTEGER, INTENT(IN) :: knon, nisurf |
||
69 |
REAL , INTENT(IN) :: dtime |
||
70 |
REAL, DIMENSION(klon), INTENT(IN) :: petAcoef, peqAcoef |
||
71 |
REAL, DIMENSION(klon), INTENT(IN) :: petBcoef, peqBcoef |
||
72 |
REAL, DIMENSION(klon), INTENT(IN) :: ps, q1lay |
||
73 |
REAL, DIMENSION(klon), INTENT(IN) :: tsurf, p1lay, cal, beta, cdragh,cdragq |
||
74 |
REAL, DIMENSION(klon), INTENT(IN) :: precip_rain, precip_snow |
||
75 |
REAL, DIMENSION(klon), INTENT(IN) :: radsol, dif_grnd |
||
76 |
REAL, DIMENSION(klon), INTENT(IN) :: t1lay, u1lay, v1lay,gustiness |
||
77 |
REAL, INTENT(IN) :: fqsat ! correction factor on qsat (generally 0.98 over salty water, 1 everywhere else) |
||
78 |
|||
79 |
real, intent(in), optional:: rhoa(:) ! (knon) |
||
80 |
! density of moist air (kg / m3) |
||
81 |
|||
82 |
! Parametres entree-sorties |
||
83 |
!**************************************************************************************** |
||
84 |
REAL, DIMENSION(klon), INTENT(INOUT) :: snow ! snow pas utile |
||
85 |
|||
86 |
! Parametres sorties |
||
87 |
!**************************************************************************************** |
||
88 |
REAL, DIMENSION(klon), INTENT(OUT) :: qsurf |
||
89 |
REAL, DIMENSION(klon), INTENT(OUT) :: tsurf_new, evap, fluxsens, fluxlat |
||
90 |
REAL, DIMENSION(klon), INTENT(OUT) :: dflux_s, dflux_l |
||
91 |
REAL, intent(out), OPTIONAL:: sens_prec_liq(:), sens_prec_sol(:) ! (knon) |
||
92 |
REAL, DIMENSION(klon), OPTIONAL :: lat_prec_liq, lat_prec_sol |
||
93 |
|||
94 |
! Variables locales |
||
95 |
!**************************************************************************************** |
||
96 |
INTEGER :: i |
||
97 |
2304 |
REAL, DIMENSION(klon) :: zx_mh, zx_nh, zx_oh |
|
98 |
2304 |
REAL, DIMENSION(klon) :: zx_mq, zx_nq, zx_oq |
|
99 |
2304 |
REAL, DIMENSION(klon) :: zx_pkh, zx_dq_s_dt, zx_qsat |
|
100 |
2304 |
REAL, DIMENSION(klon) :: zx_sl, zx_coefh, zx_coefq, zx_wind |
|
101 |
2304 |
REAL, DIMENSION(klon) :: d_ts |
|
102 |
REAL :: zdelta, zcvm5, zx_qs, zcor, zx_dq_s_dh |
||
103 |
REAL :: qsat_new, q1_new |
||
104 |
REAL, PARAMETER :: t_grnd = 271.35, t_coup = 273.15 |
||
105 |
REAL, PARAMETER :: max_eau_sol = 150.0 |
||
106 |
CHARACTER (len = 20) :: modname = 'calcul_fluxs' |
||
107 |
LOGICAL :: fonte_neige |
||
108 |
LOGICAL, SAVE :: check = .FALSE. |
||
109 |
!$OMP THREADPRIVATE(check) |
||
110 |
|||
111 |
! End definition |
||
112 |
!**************************************************************************************** |
||
113 |
|||
114 |
✗✓ | 1152 |
IF (check) WRITE(*,*)'Entree ', modname,' surface = ',nisurf |
115 |
|||
116 |
✗✓ | 1152 |
IF (check) THEN |
117 |
WRITE(*,*)' radsol (min, max)', & |
||
118 |
MINVAL(radsol(1:knon)), MAXVAL(radsol(1:knon)) |
||
119 |
ENDIF |
||
120 |
|||
121 |
! Traitement neige et humidite du sol |
||
122 |
!**************************************************************************************** |
||
123 |
! |
||
124 |
!!$ WRITE(*,*)'test calcul_flux, surface ', nisurf |
||
125 |
!!PB test |
||
126 |
!!$ if (nisurf == is_oce) then |
||
127 |
!!$ snow = 0. |
||
128 |
!!$ qsol = max_eau_sol |
||
129 |
!!$ else |
||
130 |
!!$ where (precip_snow > 0.) snow = snow + (precip_snow * dtime) |
||
131 |
!!$ where (snow > epsilon(snow)) snow = max(0.0, snow - (evap * dtime)) |
||
132 |
!!$! snow = max(0.0, snow + (precip_snow - evap) * dtime) |
||
133 |
!!$ where (precip_rain > 0.) qsol = qsol + (precip_rain - evap) * dtime |
||
134 |
!!$ endif |
||
135 |
!!$ IF (nisurf /= is_ter) qsol = max_eau_sol |
||
136 |
|||
137 |
|||
138 |
! |
||
139 |
! Initialisation |
||
140 |
!**************************************************************************************** |
||
141 |
✓✓ | 1146240 |
evap = 0. |
142 |
✓✓ | 1146240 |
fluxsens=0. |
143 |
✓✓ | 1146240 |
fluxlat=0. |
144 |
✓✓ | 1146240 |
dflux_s = 0. |
145 |
✓✓ | 1146240 |
dflux_l = 0. |
146 |
✓✓✓✓ |
573696 |
if (PRESENT(lat_prec_liq)) lat_prec_liq = 0. |
147 |
✓✓✓✓ |
573696 |
if (PRESENT(lat_prec_sol)) lat_prec_sol = 0. |
148 |
! |
||
149 |
! zx_qs = qsat en kg/kg |
||
150 |
!**************************************************************************************** |
||
151 |
✓✓ | 473954 |
DO i = 1, knon |
152 |
472802 |
zx_pkh(i) = (ps(i)/ps(i))**RKAPPA |
|
153 |
IF (thermcep) THEN |
||
154 |
472802 |
zdelta=MAX(0.,SIGN(1.,rtt-tsurf(i))) |
|
155 |
472802 |
zcvm5 = R5LES*RLVTT*(1.-zdelta) + R5IES*RLSTT*zdelta |
|
156 |
472802 |
zcvm5 = zcvm5 / RCPD / (1.0+RVTMP2*q1lay(i)) |
|
157 |
472802 |
zx_qs= r2es * FOEEW(tsurf(i),zdelta)/ps(i) |
|
158 |
472802 |
zx_qs=MIN(0.5,zx_qs) |
|
159 |
472802 |
zcor=1./(1.-retv*zx_qs) |
|
160 |
472802 |
zx_qs=zx_qs*zcor |
|
161 |
zx_dq_s_dh = FOEDE(tsurf(i),zdelta,zcvm5,zx_qs,zcor) & |
||
162 |
472802 |
/RLVTT / zx_pkh(i) |
|
163 |
ELSE |
||
164 |
IF (tsurf(i).LT.t_coup) THEN |
||
165 |
zx_qs = qsats(tsurf(i)) / ps(i) |
||
166 |
zx_dq_s_dh = dqsats(tsurf(i),zx_qs)/RLVTT & |
||
167 |
/ zx_pkh(i) |
||
168 |
ELSE |
||
169 |
zx_qs = qsatl(tsurf(i)) / ps(i) |
||
170 |
zx_dq_s_dh = dqsatl(tsurf(i),zx_qs)/RLVTT & |
||
171 |
/ zx_pkh(i) |
||
172 |
ENDIF |
||
173 |
ENDIF |
||
174 |
472802 |
zx_dq_s_dt(i) = RCPD * zx_pkh(i) * zx_dq_s_dh |
|
175 |
472802 |
zx_qsat(i) = zx_qs |
|
176 |
472802 |
zx_wind(i)=min_wind_speed+SQRT(gustiness(i)+u1lay(i)**2+v1lay(i)**2) |
|
177 |
472802 |
zx_coefh(i) = cdragh(i) * zx_wind(i) * p1lay(i)/(RD*t1lay(i)) |
|
178 |
1152 |
zx_coefq(i) = cdragq(i) * zx_wind(i) * p1lay(i)/(RD*t1lay(i)) |
|
179 |
! zx_wind(i)=min_wind_speed+SQRT(gustiness(i)+u1lay(i)**2+v1lay(i)**2) & |
||
180 |
! * p1lay(i)/(RD*t1lay(i)) |
||
181 |
! zx_coefh(i) = cdragh(i) * zx_wind(i) |
||
182 |
! zx_coefq(i) = cdragq(i) * zx_wind(i) |
||
183 |
ENDDO |
||
184 |
|||
185 |
|||
186 |
! === Calcul de la temperature de surface === |
||
187 |
! zx_sl = chaleur latente d'evaporation ou de sublimation |
||
188 |
!**************************************************************************************** |
||
189 |
|||
190 |
✓✓ | 473954 |
DO i = 1, knon |
191 |
472802 |
zx_sl(i) = RLVTT |
|
192 |
1152 |
IF (tsurf(i) .LT. RTT) zx_sl(i) = RLSTT |
|
193 |
ENDDO |
||
194 |
|||
195 |
|||
196 |
✓✓ | 473954 |
DO i = 1, knon |
197 |
! Q |
||
198 |
472802 |
zx_oq(i) = 1. - (beta(i) * zx_coefq(i) * peqBcoef(i) * dtime) |
|
199 |
zx_mq(i) = beta(i) * zx_coefq(i) * & |
||
200 |
(peqAcoef(i) - & |
||
201 |
! conv num avec precedente version |
||
202 |
fqsat * zx_qsat(i) + fqsat * zx_dq_s_dt(i) * tsurf(i)) & |
||
203 |
! fqsat * ( zx_qsat(i) - zx_dq_s_dt(i) * tsurf(i)) ) & |
||
204 |
472802 |
/ zx_oq(i) |
|
205 |
zx_nq(i) = beta(i) * zx_coefq(i) * (- fqsat * zx_dq_s_dt(i)) & |
||
206 |
472802 |
/ zx_oq(i) |
|
207 |
|||
208 |
! H |
||
209 |
472802 |
zx_oh(i) = 1. - (zx_coefh(i) * petBcoef(i) * dtime) |
|
210 |
472802 |
zx_mh(i) = zx_coefh(i) * petAcoef(i) / zx_oh(i) |
|
211 |
472802 |
zx_nh(i) = - (zx_coefh(i) * RCPD * zx_pkh(i))/ zx_oh(i) |
|
212 |
|||
213 |
! Tsurface |
||
214 |
tsurf_new(i) = (tsurf(i) + cal(i)/(RCPD * zx_pkh(i)) * dtime * & |
||
215 |
(radsol(i) + zx_mh(i) + zx_sl(i) * zx_mq(i)) & |
||
216 |
+ dif_grnd(i) * t_grnd * dtime)/ & |
||
217 |
( 1. - dtime * cal(i)/(RCPD * zx_pkh(i)) * ( & |
||
218 |
zx_nh(i) + zx_sl(i) * zx_nq(i)) & |
||
219 |
472802 |
+ dtime * dif_grnd(i)) |
|
220 |
|||
221 |
! |
||
222 |
! Y'a-t-il fonte de neige? |
||
223 |
! |
||
224 |
! fonte_neige = (nisurf /= is_oce) .AND. & |
||
225 |
! & (snow(i) > epsfra .OR. nisurf == is_sic .OR. nisurf == is_lic) & |
||
226 |
! & .AND. (tsurf_new(i) >= RTT) |
||
227 |
! if (fonte_neige) tsurf_new(i) = RTT |
||
228 |
472802 |
d_ts(i) = tsurf_new(i) - tsurf(i) |
|
229 |
! zx_h_ts(i) = tsurf_new(i) * RCPD * zx_pkh(i) |
||
230 |
! zx_q_0(i) = zx_qsat(i) + zx_dq_s_dt(i) * d_ts(i) |
||
231 |
|||
232 |
!== flux_q est le flux de vapeur d'eau: kg/(m**2 s) positive vers bas |
||
233 |
!== flux_t est le flux de cpt (energie sensible): j/(m**2 s) |
||
234 |
472802 |
evap(i) = - zx_mq(i) - zx_nq(i) * tsurf_new(i) |
|
235 |
472802 |
fluxlat(i) = - evap(i) * zx_sl(i) |
|
236 |
472802 |
fluxsens(i) = zx_mh(i) + zx_nh(i) * tsurf_new(i) |
|
237 |
|||
238 |
! Derives des flux dF/dTs (W m-2 K-1): |
||
239 |
472802 |
dflux_s(i) = zx_nh(i) |
|
240 |
472802 |
dflux_l(i) = (zx_sl(i) * zx_nq(i)) |
|
241 |
|||
242 |
! Nouvelle valeure de l'humidite au dessus du sol |
||
243 |
472802 |
qsat_new=zx_qsat(i) + zx_dq_s_dt(i) * d_ts(i) |
|
244 |
472802 |
q1_new = peqAcoef(i) - peqBcoef(i)*evap(i)*dtime |
|
245 |
472802 |
qsurf(i)=q1_new*(1.-beta(i)) + beta(i)*qsat_new |
|
246 |
! |
||
247 |
! en cas de fonte de neige |
||
248 |
! |
||
249 |
! if (fonte_neige) then |
||
250 |
! bilan_f = radsol(i) + fluxsens(i) - (zx_sl(i) * evap (i)) - & |
||
251 |
! & dif_grnd(i) * (tsurf_new(i) - t_grnd) - & |
||
252 |
! & RCPD * (zx_pkh(i))/cal(i)/dtime * (tsurf_new(i) - tsurf(i)) |
||
253 |
! bilan_f = max(0., bilan_f) |
||
254 |
! fq_fonte = bilan_f / zx_sl(i) |
||
255 |
! snow(i) = max(0., snow(i) - fq_fonte * dtime) |
||
256 |
! qsol(i) = qsol(i) + (fq_fonte * dtime) |
||
257 |
! endif |
||
258 |
!!$ if (nisurf == is_ter) & |
||
259 |
!!$ & run_off(i) = run_off(i) + max(qsol(i) - max_eau_sol, 0.0) |
||
260 |
!!$ qsol(i) = min(qsol(i), max_eau_sol) |
||
261 |
! |
||
262 |
! calcul de l'enthalpie des precipitations liquides et solides |
||
263 |
✓✗ | 280418 |
if (PRESENT(sens_prec_liq)) sens_prec_liq(i) & |
264 |
= - sens_heat_rain(precip_rain(i) + precip_snow(i), t1lay(i), & |
||
265 |
280418 |
q1lay(i), rhoa(i), rlvtt, tsurf_new(i), ps(i)) |
|
266 |
✓✓✓✗ |
472802 |
if (PRESENT(sens_prec_sol)) sens_prec_sol(i) = 0. |
267 |
! On calcule par rapport a T=0 |
||
268 |
!! sens_prec_liq(i) = rcw * (t1lay(i) - RTT) * precip_rain(i) |
||
269 |
!! sens_prec_sol(i) = rcs * (t1lay(i) - RTT) * precip_snow(i) |
||
270 |
|||
271 |
✓✓ | 472802 |
if (PRESENT(lat_prec_liq)) & |
272 |
280418 |
lat_prec_liq(i) = precip_rain(i) * (RLVTT - RLVTT) |
|
273 |
✓✓ | 472802 |
if (PRESENT(lat_prec_sol)) & |
274 |
1152 |
lat_prec_sol(i) = precip_snow(i) * (RLSTT - RLVTT) |
|
275 |
ENDDO |
||
276 |
|||
277 |
|||
278 |
!************************************************************************** |
||
279 |
! |
||
280 |
✓✓✓✓ |
1728 |
END SUBROUTINE calcul_fluxs |
281 |
! |
||
282 |
!**************************************************************************************** |
||
283 |
! |
||
284 |
1152 |
SUBROUTINE calcul_flux_wind(knon, dtime, & |
|
285 |
u0, v0, u1, v1, gustiness, cdrag_m, & |
||
286 |
AcoefU, AcoefV, BcoefU, BcoefV, & |
||
287 |
p1lay, t1lay, & |
||
288 |
flux_u1, flux_v1) |
||
289 |
|||
290 |
✓✓✓✓ |
1979242 |
USE dimphy |
291 |
INCLUDE "YOMCST.h" |
||
292 |
INCLUDE "clesphys.h" |
||
293 |
|||
294 |
! Input arguments |
||
295 |
!**************************************************************************************** |
||
296 |
INTEGER, INTENT(IN) :: knon |
||
297 |
REAL, INTENT(IN) :: dtime |
||
298 |
REAL, DIMENSION(klon), INTENT(IN) :: u0, v0 ! u and v at niveau 0 |
||
299 |
REAL, DIMENSION(klon), INTENT(IN) :: u1, v1, gustiness ! u and v at niveau 1 |
||
300 |
REAL, DIMENSION(klon), INTENT(IN) :: cdrag_m ! cdrag pour momentum |
||
301 |
REAL, DIMENSION(klon), INTENT(IN) :: AcoefU, AcoefV, BcoefU, BcoefV |
||
302 |
REAL, DIMENSION(klon), INTENT(IN) :: p1lay ! pression 1er niveau (milieu de couche) |
||
303 |
REAL, DIMENSION(klon), INTENT(IN) :: t1lay ! temperature |
||
304 |
! Output arguments |
||
305 |
!**************************************************************************************** |
||
306 |
REAL, DIMENSION(klon), INTENT(OUT) :: flux_u1 |
||
307 |
REAL, DIMENSION(klon), INTENT(OUT) :: flux_v1 |
||
308 |
|||
309 |
! Local variables |
||
310 |
!**************************************************************************************** |
||
311 |
INTEGER :: i |
||
312 |
REAL :: mod_wind, buf |
||
313 |
|||
314 |
!**************************************************************************************** |
||
315 |
! Calculate the surface flux |
||
316 |
! |
||
317 |
!**************************************************************************************** |
||
318 |
✓✓ | 473954 |
DO i=1,knon |
319 |
472802 |
mod_wind = min_wind_speed + SQRT(gustiness(i)+(u1(i) - u0(i))**2 + (v1(i)-v0(i))**2) |
|
320 |
472802 |
buf = cdrag_m(i) * mod_wind * p1lay(i)/(RD*t1lay(i)) |
|
321 |
472802 |
flux_u1(i) = (AcoefU(i) - u0(i)) / (1/buf - BcoefU(i)*dtime ) |
|
322 |
473954 |
flux_v1(i) = (AcoefV(i) - v0(i)) / (1/buf - BcoefV(i)*dtime ) |
|
323 |
END DO |
||
324 |
|||
325 |
1152 |
END SUBROUTINE calcul_flux_wind |
|
326 |
! |
||
327 |
!**************************************************************************************** |
||
328 |
! |
||
329 |
END MODULE calcul_fluxs_mod |
Generated by: GCOVR (Version 4.2) |