5 |
contains |
contains |
6 |
|
|
7 |
SUBROUTINE coefkz(nsrf, knon, paprs, pplay, ksta, ksta_ter, ts, rugos, u, v, & |
SUBROUTINE coefkz(nsrf, knon, paprs, pplay, ksta, ksta_ter, ts, rugos, u, v, & |
8 |
t, q, qsurf, pcfm, pcfh) |
t, q, qsurf, coefm, coefh) |
9 |
|
|
10 |
! Authors: F. Hourdin, M. Forichon, Z.X. Li (LMD/CNRS) |
! Authors: F. Hourdin, M. Forichon, Z. X. Li (LMD/CNRS) |
11 |
! date: 1993/09/22 |
! date: 1993/09/22 |
12 |
! Objet : calculer le coefficient de frottement du sol ("Cdrag") et les |
! Objet : calculer le coefficient de frottement du sol ("Cdrag") et les |
13 |
! coefficients d'échange turbulent dans l'atmosphère. |
! coefficients d'échange turbulent dans l'atmosphère. |
14 |
|
|
15 |
USE indicesol, ONLY : is_oce |
USE indicesol, ONLY: is_oce |
16 |
USE dimphy, ONLY : klev, klon, max |
USE dimphy, ONLY: klev, klon, max |
17 |
USE iniprint, ONLY : prt_level |
USE conf_gcm_m, ONLY: prt_level |
18 |
USE suphec_m, ONLY : rcpd, rd, retv, rg, rkappa, rlstt, rlvtt, rtt |
USE suphec_m, ONLY: rcpd, rd, retv, rg, rkappa, rlstt, rlvtt, rtt |
19 |
USE yoethf_m, ONLY : r2es, r5ies, r5les, rvtmp2 |
USE yoethf_m, ONLY: r2es, r5ies, r5les, rvtmp2 |
20 |
USE fcttre, ONLY : dqsatl, dqsats, foede, foeew, qsatl, qsats, thermcep |
USE fcttre, ONLY: dqsatl, dqsats, foede, foeew, qsatl, qsats, thermcep |
21 |
USE conf_phys_m, ONLY : iflag_pbl |
USE conf_phys_m, ONLY: iflag_pbl |
22 |
|
use clcdrag_m, only: clcdrag |
23 |
|
|
24 |
! Arguments: |
! Arguments: |
25 |
|
|
39 |
REAL, intent(in):: t(klon, klev) ! temperature (K) |
REAL, intent(in):: t(klon, klev) ! temperature (K) |
40 |
real, intent(in):: q(klon, klev) ! vapeur d'eau (kg/kg) |
real, intent(in):: q(klon, klev) ! vapeur d'eau (kg/kg) |
41 |
real, intent(in):: qsurf(klon) |
real, intent(in):: qsurf(klon) |
42 |
REAL, intent(inout):: pcfm(klon, klev) ! coefficient, vitesse |
REAL, intent(out):: coefm(:, :) ! (knon, klev) coefficient, vitesse |
43 |
real, intent(inout):: pcfh(klon, klev) ! coefficient, chaleur et humidité |
|
44 |
|
real, intent(out):: coefh(:, :) ! (knon, klev) |
45 |
|
! coefficient, chaleur et humidité |
46 |
|
|
47 |
! Local: |
! Local: |
48 |
|
|
49 |
INTEGER itop(klon) ! numero de couche du sommet de la couche limite |
INTEGER itop(knon) ! numero de couche du sommet de la couche limite |
50 |
|
|
51 |
! Quelques constantes et options: |
! Quelques constantes et options: |
52 |
|
|
56 |
REAL, PARAMETER:: cc = 5. |
REAL, PARAMETER:: cc = 5. |
57 |
REAL, PARAMETER:: cd = 5. |
REAL, PARAMETER:: cd = 5. |
58 |
REAL, PARAMETER:: clam = 160. |
REAL, PARAMETER:: clam = 160. |
59 |
REAL, PARAMETER:: ratqs = 0.05 ! ! largeur de distribution de vapeur d'eau |
REAL, PARAMETER:: ratqs = 0.05 ! largeur de distribution de vapeur d'eau |
60 |
LOGICAL, PARAMETER:: richum = .TRUE. ! utilise le nombre de Richardson humide |
|
61 |
|
LOGICAL, PARAMETER:: richum = .TRUE. |
62 |
|
! utilise le nombre de Richardson humide |
63 |
|
|
64 |
REAL, PARAMETER:: ric = 0.4 ! nombre de Richardson critique |
REAL, PARAMETER:: ric = 0.4 ! nombre de Richardson critique |
65 |
REAL, PARAMETER:: prandtl = 0.4 |
REAL, PARAMETER:: prandtl = 0.4 |
66 |
|
|
67 |
REAL kstable ! diffusion minimale (situation stable) |
REAL kstable ! diffusion minimale (situation stable) |
68 |
REAL, PARAMETER:: mixlen = 35. ! constante controlant longueur de melange |
REAL, PARAMETER:: mixlen = 35. ! constante contrôlant longueur de mélange |
69 |
INTEGER, PARAMETER:: isommet = klev ! le sommet de la couche limite |
INTEGER, PARAMETER:: isommet = klev ! sommet de la couche limite |
70 |
|
|
71 |
LOGICAL, PARAMETER:: tvirtu = .TRUE. |
LOGICAL, PARAMETER:: tvirtu = .TRUE. |
72 |
! calculer Ri d'une maniere plus performante |
! calculer Ri d'une maniere plus performante |
77 |
INTEGER i, k, kk |
INTEGER i, k, kk |
78 |
REAL zgeop(klon, klev) |
REAL zgeop(klon, klev) |
79 |
REAL zmgeom(klon) |
REAL zmgeom(klon) |
80 |
REAL zri(klon) |
REAL ri(klon) |
81 |
REAL zl2(klon) |
REAL l2(klon) |
82 |
|
|
83 |
REAL u1(klon), v1(klon), t1(klon), q1(klon), z1(klon) |
REAL u1(klon), v1(klon), t1(klon), q1(klon), z1(klon) |
|
REAL pcfm1(klon), pcfh1(klon) |
|
84 |
|
|
85 |
REAL zdphi, zdu2, ztvd, ztvu, zcdn |
REAL zdphi, zdu2, ztvd, ztvu, cdn |
86 |
REAL zscf |
REAL scf |
87 |
REAL zt, zq, zdelta, zcvm5, zcor, zqs, zfr, zdqs |
REAL zt, zq, zdelta, zcvm5, zcor, zqs, zfr, zdqs |
88 |
REAL z2geomf, zalh2, zalm2, zscfh, zscfm |
REAL z2geomf, zalh2, alm2, zscfh, scfm |
89 |
REAL, PARAMETER:: t_coup = 273.15 |
REAL, PARAMETER:: t_coup = 273.15 |
90 |
REAL gamt(2:klev) ! contre-gradient pour la chaleur sensible: Kelvin/metre |
REAL gamt(2:klev) ! contre-gradient pour la chaleur sensible: Kelvin/metre |
91 |
|
|
92 |
!-------------------------------------------------------------------- |
!-------------------------------------------------------------------- |
93 |
|
|
|
! Initialiser les sorties |
|
|
DO k = 1, klev |
|
|
DO i = 1, knon |
|
|
pcfm(i, k) = 0. |
|
|
pcfh(i, k) = 0. |
|
|
ENDDO |
|
|
ENDDO |
|
|
DO i = 1, knon |
|
|
itop(i) = 0 |
|
|
ENDDO |
|
|
|
|
94 |
! Prescrire la valeur de contre-gradient |
! Prescrire la valeur de contre-gradient |
95 |
if (iflag_pbl.eq.1) then |
if (iflag_pbl.eq.1) then |
96 |
DO k = 3, klev |
DO k = 3, klev |
133 |
ENDDO |
ENDDO |
134 |
|
|
135 |
CALL clcdrag(klon, knon, nsrf, .false., u1, v1, t1, q1, z1, ts, qsurf, & |
CALL clcdrag(klon, knon, nsrf, .false., u1, v1, t1, q1, z1, ts, qsurf, & |
136 |
rugos, pcfm1, pcfh1) |
rugos, coefm(:, 1), coefh(:, 1)) |
|
|
|
|
DO i = 1, knon |
|
|
pcfm(i, 1) = pcfm1(i) |
|
|
pcfh(i, 1) = pcfh1(i) |
|
|
ENDDO |
|
137 |
|
|
138 |
! Calculer les coefficients turbulents dans l'atmosphere |
! Calculer les coefficients turbulents dans l'atmosphere |
139 |
|
|
140 |
DO i = 1, knon |
itop = isommet |
|
itop(i) = isommet |
|
|
ENDDO |
|
141 |
|
|
142 |
loop_vertical: DO k = 2, isommet |
loop_vertical: DO k = 2, isommet |
143 |
loop_horiz: DO i = 1, knon |
loop_horiz: DO i = 1, knon |
160 |
zqs = zqs*zcor |
zqs = zqs*zcor |
161 |
zdqs = FOEDE(zt, zdelta, zcvm5, zqs, zcor) |
zdqs = FOEDE(zt, zdelta, zcvm5, zqs, zcor) |
162 |
ELSE |
ELSE |
163 |
IF (zt .LT. t_coup) THEN |
IF (zt < t_coup) THEN |
164 |
zqs = qsats(zt) / pplay(i, k) |
zqs = qsats(zt) / pplay(i, k) |
165 |
zdqs = dqsats(zt, zqs) |
zdqs = dqsats(zt, zqs) |
166 |
ELSE |
ELSE |
186 |
- zdphi/RCPD/(1.+RVTMP2*zq) & |
- zdphi/RCPD/(1.+RVTMP2*zq) & |
187 |
*( (1.-zfr) + zfr*(1.+RLVTT*zqs/RD/zt)/(1.+zdqs) ) & |
*( (1.-zfr) + zfr*(1.+RLVTT*zqs/RD/zt)/(1.+zdqs) ) & |
188 |
)*(1.+RETV*q(i, k-1)) |
)*(1.+RETV*q(i, k-1)) |
189 |
zri(i) =zmgeom(i)*(ztvd-ztvu)/(zdu2*0.5*(ztvd+ztvu)) |
ri(i) =zmgeom(i)*(ztvd-ztvu)/(zdu2*0.5*(ztvd+ztvu)) |
190 |
zri(i) = zri(i) & |
ri(i) = ri(i) & |
191 |
+ zmgeom(i)*zmgeom(i)/RG*gamt(k) & |
+ zmgeom(i)*zmgeom(i)/RG*gamt(k) & |
192 |
*(paprs(i, k)/101325.0)**RKAPPA & |
*(paprs(i, k)/101325.0)**RKAPPA & |
193 |
/(zdu2*0.5*(ztvd+ztvu)) |
/(zdu2*0.5*(ztvd+ztvu)) |
194 |
ELSE |
ELSE |
195 |
! calcul de Ridchardson compatible LMD5 |
! calcul de Ridchardson compatible LMD5 |
196 |
zri(i) =(RCPD*(t(i, k)-t(i, k-1)) & |
ri(i) =(RCPD*(t(i, k)-t(i, k-1)) & |
197 |
-RD*0.5*(t(i, k)+t(i, k-1))/paprs(i, k) & |
-RD*0.5*(t(i, k)+t(i, k-1))/paprs(i, k) & |
198 |
*(pplay(i, k)-pplay(i, k-1)) & |
*(pplay(i, k)-pplay(i, k-1)) & |
199 |
)*zmgeom(i)/(zdu2*0.5*RCPD*(t(i, k-1)+t(i, k))) |
)*zmgeom(i)/(zdu2*0.5*RCPD*(t(i, k-1)+t(i, k))) |
200 |
zri(i) = zri(i) + & |
ri(i) = ri(i) + & |
201 |
zmgeom(i)*zmgeom(i)*gamt(k)/RG & |
zmgeom(i)*zmgeom(i)*gamt(k)/RG & |
202 |
*(paprs(i, k)/101325.0)**RKAPPA & |
*(paprs(i, k)/101325.0)**RKAPPA & |
203 |
/(zdu2*0.5*(t(i, k-1)+t(i, k))) |
/(zdu2*0.5*(t(i, k-1)+t(i, k))) |
205 |
|
|
206 |
! finalement, les coefficients d'echange sont obtenus: |
! finalement, les coefficients d'echange sont obtenus: |
207 |
|
|
208 |
zcdn = SQRT(zdu2) / zmgeom(i) * RG |
cdn = SQRT(zdu2) / zmgeom(i) * RG |
209 |
|
|
210 |
IF (opt_ec) THEN |
IF (opt_ec) THEN |
211 |
z2geomf = zgeop(i, k-1)+zgeop(i, k) |
z2geomf = zgeop(i, k-1)+zgeop(i, k) |
212 |
zalm2 = (0.5*ckap/RG*z2geomf & |
alm2 = (0.5*ckap/RG*z2geomf & |
213 |
/(1.+0.5*ckap/rg/clam*z2geomf))**2 |
/(1.+0.5*ckap/rg/clam*z2geomf))**2 |
214 |
zalh2 = (0.5*ckap/rg*z2geomf & |
zalh2 = (0.5*ckap/rg*z2geomf & |
215 |
/(1.+0.5*ckap/RG/(clam*SQRT(1.5*cd))*z2geomf))**2 |
/(1.+0.5*ckap/RG/(clam*SQRT(1.5*cd))*z2geomf))**2 |
216 |
IF (zri(i).LT.0.0) THEN |
IF (ri(i) < 0.) THEN |
217 |
! situation instable |
! situation instable |
218 |
zscf = ((zgeop(i, k)/zgeop(i, k-1))**(1./3.)-1.)**3 & |
scf = ((zgeop(i, k)/zgeop(i, k-1))**(1./3.)-1.)**3 & |
219 |
/ (zmgeom(i)/RG)**3 / (zgeop(i, k-1)/RG) |
/ (zmgeom(i)/RG)**3 / (zgeop(i, k-1)/RG) |
220 |
zscf = SQRT(-zri(i)*zscf) |
scf = SQRT(-ri(i)*scf) |
221 |
zscfm = 1.0 / (1.0+3.0*cb*cc*zalm2*zscf) |
scfm = 1.0 / (1.0+3.0*cb*cc*alm2*scf) |
222 |
zscfh = 1.0 / (1.0+3.0*cb*cc*zalh2*zscf) |
zscfh = 1.0 / (1.0+3.0*cb*cc*zalh2*scf) |
223 |
pcfm(i, k) = zcdn*zalm2*(1.-2.0*cb*zri(i)*zscfm) |
coefm(i, k) = cdn * alm2 * (1. - 2. * cb * ri(i) * scfm) |
224 |
pcfh(i, k) = zcdn*zalh2*(1.-3.0*cb*zri(i)*zscfh) |
coefh(i, k) = cdn*zalh2*(1.-3.0*cb*ri(i)*zscfh) |
225 |
ELSE |
ELSE |
226 |
! situation stable |
! situation stable |
227 |
zscf = SQRT(1.+cd*zri(i)) |
scf = SQRT(1.+cd*ri(i)) |
228 |
pcfm(i, k) = zcdn*zalm2/(1.+2.0*cb*zri(i)/zscf) |
coefm(i, k) = cdn * alm2 / (1. + 2. * cb * ri(i) / scf) |
229 |
pcfh(i, k) = zcdn*zalh2/(1.+3.0*cb*zri(i)*zscf) |
coefh(i, k) = cdn*zalh2/(1.+3.0*cb*ri(i)*scf) |
230 |
ENDIF |
ENDIF |
231 |
ELSE |
ELSE |
232 |
zl2(i) = (mixlen*MAX(0.0, (paprs(i, k)-paprs(i, itop(i)+1)) & |
l2(i) = (mixlen*MAX(0.0, (paprs(i, k)-paprs(i, itop(i)+1)) & |
233 |
/(paprs(i, 2)-paprs(i, itop(i)+1)) ))**2 |
/(paprs(i, 2)-paprs(i, itop(i)+1)) ))**2 |
234 |
pcfm(i, k) = sqrt(max(zcdn*zcdn*(ric-zri(i))/ric, kstable)) |
coefm(i, k) = sqrt(max(cdn**2 * (ric - ri(i)) / ric, kstable)) |
235 |
pcfm(i, k)= zl2(i)* pcfm(i, k) |
coefm(i, k)= l2(i) * coefm(i, k) |
236 |
pcfh(i, k) = pcfm(i, k) /prandtl ! h et m different |
coefh(i, k) = coefm(i, k) / prandtl ! h et m different |
237 |
ENDIF |
ENDIF |
238 |
ENDDO loop_horiz |
ENDDO loop_horiz |
239 |
ENDDO loop_vertical |
ENDDO loop_vertical |
240 |
|
|
241 |
! Au-dela du sommet, pas de diffusion turbulente: |
! Au-delà du sommet, pas de diffusion turbulente : |
242 |
|
forall (i = 1: knon) |
243 |
DO i = 1, knon |
coefh(i, itop(i) + 1:) = 0. |
244 |
IF (itop(i)+1 .LE. klev) THEN |
coefm(i, itop(i) + 1:) = 0. |
245 |
DO k = itop(i)+1, klev |
END forall |
|
pcfh(i, k) = 0. |
|
|
pcfm(i, k) = 0. |
|
|
ENDDO |
|
|
ENDIF |
|
|
ENDDO |
|
246 |
|
|
247 |
END SUBROUTINE coefkz |
END SUBROUTINE coefkz |
248 |
|
|