/[lmdze]/trunk/libf/phylmd/coefkz.f90
ViewVC logotype

Contents of /trunk/libf/phylmd/coefkz.f90

Parent Directory Parent Directory | Revision Log Revision Log


Revision 47 - (show annotations)
Fri Jul 1 15:00:48 2011 UTC (12 years, 10 months ago) by guez
File size: 8804 byte(s)
Split "thermcell.f" and "cv3_routines.f".
Removed copies of files that are now in "L_util".
Moved "mva9" and "diagetpq" to their own files.
Unified variable names across procedures.

1 module coefkz_m
2
3 IMPLICIT none
4
5 contains
6
7 SUBROUTINE coefkz(nsrf, knon, paprs, pplay, ksta, ksta_ter, ts, rugos, u, v, &
8 t, q, qsurf, pcfm, pcfh)
9
10 ! Authors: F. Hourdin, M. Forichon, Z.X. Li (LMD/CNRS)
11 ! date: 1993/09/22
12 ! Objet : calculer le coefficient de frottement du sol ("Cdrag") et les
13 ! coefficients d'échange turbulent dans l'atmosphère.
14
15 USE indicesol, ONLY : is_oce
16 USE dimphy, ONLY : klev, klon, max
17 USE iniprint, ONLY : prt_level
18 USE suphec_m, ONLY : rcpd, rd, retv, rg, rkappa, rlstt, rlvtt, rtt
19 USE yoethf_m, ONLY : r2es, r5ies, r5les, rvtmp2
20 USE fcttre, ONLY : dqsatl, dqsats, foede, foeew, qsatl, qsats, thermcep
21 USE conf_phys_m, ONLY : iflag_pbl
22
23 ! Arguments:
24
25 integer, intent(in):: nsrf ! indicateur de la nature du sol
26 INTEGER, intent(in):: knon ! nombre de points a traiter
27
28 REAL, intent(in):: paprs(klon, klev+1)
29 ! pression a chaque intercouche (en Pa)
30
31 real, intent(in):: pplay(klon, klev)
32 ! pression au milieu de chaque couche (en Pa)
33
34 REAL, intent(in):: ksta, ksta_ter
35 REAL, intent(in):: ts(klon) ! temperature du sol (en Kelvin)
36 REAL, intent(in):: rugos(klon) ! longeur de rugosite (en m)
37 REAL, intent(in):: u(klon, klev), v(klon, klev) ! wind
38 REAL, intent(in):: t(klon, klev) ! temperature (K)
39 real, intent(in):: q(klon, klev) ! vapeur d'eau (kg/kg)
40 real, intent(in):: qsurf(klon)
41 REAL, intent(inout):: pcfm(klon, klev) ! coefficient, vitesse
42 real, intent(inout):: pcfh(klon, klev) ! coefficient, chaleur et humidité
43
44 ! Local:
45
46 INTEGER itop(klon) ! numero de couche du sommet de la couche limite
47
48 ! Quelques constantes et options:
49
50 REAL, PARAMETER:: cepdu2 =0.1**2
51 REAL, PARAMETER:: CKAP = 0.4
52 REAL, PARAMETER:: cb = 5.
53 REAL, PARAMETER:: cc = 5.
54 REAL, PARAMETER:: cd = 5.
55 REAL, PARAMETER:: clam = 160.
56 REAL, PARAMETER:: ratqs = 0.05 ! ! largeur de distribution de vapeur d'eau
57 LOGICAL, PARAMETER:: richum = .TRUE. ! utilise le nombre de Richardson humide
58 REAL, PARAMETER:: ric = 0.4 ! nombre de Richardson critique
59 REAL, PARAMETER:: prandtl = 0.4
60
61 REAL kstable ! diffusion minimale (situation stable)
62 REAL, PARAMETER:: mixlen = 35. ! constante controlant longueur de melange
63 INTEGER, PARAMETER:: isommet = klev ! le sommet de la couche limite
64
65 LOGICAL, PARAMETER:: tvirtu = .TRUE.
66 ! calculer Ri d'une maniere plus performante
67
68 LOGICAL, PARAMETER:: opt_ec = .FALSE.
69 ! formule du Centre Europeen dans l'atmosphere
70
71 INTEGER i, k, kk
72 REAL zgeop(klon, klev)
73 REAL zmgeom(klon)
74 REAL zri(klon)
75 REAL zl2(klon)
76
77 REAL u1(klon), v1(klon), t1(klon), q1(klon), z1(klon)
78 REAL pcfm1(klon), pcfh1(klon)
79
80 REAL zdphi, zdu2, ztvd, ztvu, zcdn
81 REAL zscf
82 REAL zt, zq, zdelta, zcvm5, zcor, zqs, zfr, zdqs
83 REAL z2geomf, zalh2, zalm2, zscfh, zscfm
84 REAL, PARAMETER:: t_coup = 273.15
85 REAL gamt(2:klev) ! contre-gradient pour la chaleur sensible: Kelvin/metre
86
87 !--------------------------------------------------------------------
88
89 ! Initialiser les sorties
90 DO k = 1, klev
91 DO i = 1, knon
92 pcfm(i, k) = 0.
93 pcfh(i, k) = 0.
94 ENDDO
95 ENDDO
96 DO i = 1, knon
97 itop(i) = 0
98 ENDDO
99
100 ! Prescrire la valeur de contre-gradient
101 if (iflag_pbl.eq.1) then
102 DO k = 3, klev
103 gamt(k) = -1.0E-03
104 ENDDO
105 gamt(2) = -2.5E-03
106 else
107 DO k = 2, klev
108 gamt(k) = 0.0
109 ENDDO
110 ENDIF
111
112 IF ( nsrf .NE. is_oce ) THEN
113 kstable = ksta_ter
114 ELSE
115 kstable = ksta
116 ENDIF
117
118 ! Calculer les géopotentiels de chaque couche
119 DO i = 1, knon
120 zgeop(i, 1) = RD * t(i, 1) / (0.5 * (paprs(i, 1) + pplay(i, 1))) &
121 * (paprs(i, 1) - pplay(i, 1))
122 ENDDO
123 DO k = 2, klev
124 DO i = 1, knon
125 zgeop(i, k) = zgeop(i, k-1) &
126 + RD * 0.5*(t(i, k-1)+t(i, k)) / paprs(i, k) &
127 * (pplay(i, k-1)-pplay(i, k))
128 ENDDO
129 ENDDO
130
131 ! Calculer le frottement au sol (Cdrag)
132
133 DO i = 1, knon
134 u1(i) = u(i, 1)
135 v1(i) = v(i, 1)
136 t1(i) = t(i, 1)
137 q1(i) = q(i, 1)
138 z1(i) = zgeop(i, 1)
139 ENDDO
140
141 CALL clcdrag(klon, knon, nsrf, .false., u1, v1, t1, q1, z1, ts, qsurf, &
142 rugos, pcfm1, pcfh1)
143
144 DO i = 1, knon
145 pcfm(i, 1) = pcfm1(i)
146 pcfh(i, 1) = pcfh1(i)
147 ENDDO
148
149 ! Calculer les coefficients turbulents dans l'atmosphere
150
151 DO i = 1, knon
152 itop(i) = isommet
153 ENDDO
154
155 loop_vertical: DO k = 2, isommet
156 loop_horiz: DO i = 1, knon
157 zdu2 = MAX(cepdu2, (u(i, k)-u(i, k-1))**2 &
158 +(v(i, k)-v(i, k-1))**2)
159 zmgeom(i) = zgeop(i, k)-zgeop(i, k-1)
160 zdphi =zmgeom(i) / 2.0
161 zt = (t(i, k)+t(i, k-1)) * 0.5
162 zq = (q(i, k)+q(i, k-1)) * 0.5
163
164 ! calculer Qs et dQs/dT:
165
166 IF (thermcep) THEN
167 zdelta = MAX(0., SIGN(1., RTT-zt))
168 zcvm5 = R5LES*RLVTT/RCPD/(1.0+RVTMP2*zq)*(1.-zdelta) &
169 + R5IES*RLSTT/RCPD/(1.0+RVTMP2*zq)*zdelta
170 zqs = R2ES * FOEEW(zt, zdelta) / pplay(i, k)
171 zqs = MIN(0.5, zqs)
172 zcor = 1./(1.-RETV*zqs)
173 zqs = zqs*zcor
174 zdqs = FOEDE(zt, zdelta, zcvm5, zqs, zcor)
175 ELSE
176 IF (zt .LT. t_coup) THEN
177 zqs = qsats(zt) / pplay(i, k)
178 zdqs = dqsats(zt, zqs)
179 ELSE
180 zqs = qsatl(zt) / pplay(i, k)
181 zdqs = dqsatl(zt, zqs)
182 ENDIF
183 ENDIF
184
185 ! calculer la fraction nuageuse (processus humide):
186
187 zfr = (zq+ratqs*zq-zqs) / (2.0*ratqs*zq)
188 zfr = MAX(0.0, MIN(1.0, zfr))
189 IF (.NOT.richum) zfr = 0.0
190
191 ! calculer le nombre de Richardson:
192
193 IF (tvirtu) THEN
194 ztvd =( t(i, k) &
195 + zdphi/RCPD/(1.+RVTMP2*zq) &
196 *( (1.-zfr) + zfr*(1.+RLVTT*zqs/RD/zt)/(1.+zdqs) ) &
197 )*(1.+RETV*q(i, k))
198 ztvu =( t(i, k-1) &
199 - zdphi/RCPD/(1.+RVTMP2*zq) &
200 *( (1.-zfr) + zfr*(1.+RLVTT*zqs/RD/zt)/(1.+zdqs) ) &
201 )*(1.+RETV*q(i, k-1))
202 zri(i) =zmgeom(i)*(ztvd-ztvu)/(zdu2*0.5*(ztvd+ztvu))
203 zri(i) = zri(i) &
204 + zmgeom(i)*zmgeom(i)/RG*gamt(k) &
205 *(paprs(i, k)/101325.0)**RKAPPA &
206 /(zdu2*0.5*(ztvd+ztvu))
207 ELSE
208 ! calcul de Ridchardson compatible LMD5
209 zri(i) =(RCPD*(t(i, k)-t(i, k-1)) &
210 -RD*0.5*(t(i, k)+t(i, k-1))/paprs(i, k) &
211 *(pplay(i, k)-pplay(i, k-1)) &
212 )*zmgeom(i)/(zdu2*0.5*RCPD*(t(i, k-1)+t(i, k)))
213 zri(i) = zri(i) + &
214 zmgeom(i)*zmgeom(i)*gamt(k)/RG &
215 *(paprs(i, k)/101325.0)**RKAPPA &
216 /(zdu2*0.5*(t(i, k-1)+t(i, k)))
217 ENDIF
218
219 ! finalement, les coefficients d'echange sont obtenus:
220
221 zcdn = SQRT(zdu2) / zmgeom(i) * RG
222
223 IF (opt_ec) THEN
224 z2geomf = zgeop(i, k-1)+zgeop(i, k)
225 zalm2 = (0.5*ckap/RG*z2geomf &
226 /(1.+0.5*ckap/rg/clam*z2geomf))**2
227 zalh2 = (0.5*ckap/rg*z2geomf &
228 /(1.+0.5*ckap/RG/(clam*SQRT(1.5*cd))*z2geomf))**2
229 IF (zri(i).LT.0.0) THEN
230 ! situation instable
231 zscf = ((zgeop(i, k)/zgeop(i, k-1))**(1./3.)-1.)**3 &
232 / (zmgeom(i)/RG)**3 / (zgeop(i, k-1)/RG)
233 zscf = SQRT(-zri(i)*zscf)
234 zscfm = 1.0 / (1.0+3.0*cb*cc*zalm2*zscf)
235 zscfh = 1.0 / (1.0+3.0*cb*cc*zalh2*zscf)
236 pcfm(i, k) = zcdn*zalm2*(1.-2.0*cb*zri(i)*zscfm)
237 pcfh(i, k) = zcdn*zalh2*(1.-3.0*cb*zri(i)*zscfh)
238 ELSE
239 ! situation stable
240 zscf = SQRT(1.+cd*zri(i))
241 pcfm(i, k) = zcdn*zalm2/(1.+2.0*cb*zri(i)/zscf)
242 pcfh(i, k) = zcdn*zalh2/(1.+3.0*cb*zri(i)*zscf)
243 ENDIF
244 ELSE
245 zl2(i) = (mixlen*MAX(0.0, (paprs(i, k)-paprs(i, itop(i)+1)) &
246 /(paprs(i, 2)-paprs(i, itop(i)+1)) ))**2
247 pcfm(i, k) = sqrt(max(zcdn*zcdn*(ric-zri(i))/ric, kstable))
248 pcfm(i, k)= zl2(i)* pcfm(i, k)
249 pcfh(i, k) = pcfm(i, k) /prandtl ! h et m different
250 ENDIF
251 ENDDO loop_horiz
252 ENDDO loop_vertical
253
254 ! Au-dela du sommet, pas de diffusion turbulente:
255
256 DO i = 1, knon
257 IF (itop(i)+1 .LE. klev) THEN
258 DO k = itop(i)+1, klev
259 pcfh(i, k) = 0.
260 pcfm(i, k) = 0.
261 ENDDO
262 ENDIF
263 ENDDO
264
265 END SUBROUTINE coefkz
266
267 end module coefkz_m

  ViewVC Help
Powered by ViewVC 1.1.21