source: LMDZ6/trunk/libf/phylmd/calcul_fluxs_mod.F90 @ 3654

Last change on this file since 3654 was 3319, checked in by jyg, 7 years ago

Adding missing IMPLICIT NONE

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