/[lmdze]/trunk/phylmd/coefkz.f
ViewVC logotype

Contents of /trunk/phylmd/coefkz.f

Parent Directory Parent Directory | Revision Log Revision Log


Revision 40 - (show annotations)
Tue Feb 22 13:49:36 2011 UTC (13 years, 3 months ago) by guez
Original Path: trunk/libf/phylmd/coefkz.f90
File size: 9499 byte(s)
"alpha" useless, always 0, in "exner_hyb".

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

  ViewVC Help
Powered by ViewVC 1.1.21