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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 42 - (show annotations)
Thu Mar 24 11:52:41 2011 UTC (13 years, 2 months ago) by guez
File size: 9441 byte(s)
Removed programs "test_inter_barxy" and "test_disvert".

Added option "read" for "s_sampling" in "disvert".

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, u1, v1, t1, q1, z1, ts, qsurf, rugos, &
187 pcfm1, pcfh1)
188
189 DO i = 1, knon
190 pcfm(i, 1)=pcfm1(i)
191 pcfh(i, 1)=pcfh1(i)
192 ENDDO
193
194 ! Calculer les coefficients turbulents dans l'atmosphere
195
196 DO i = 1, knon
197 itop(i) = isommet
198 ENDDO
199
200 DO k = 2, isommet
201 DO i = 1, knon
202 zdu2=MAX(cepdu2, (u(i, k)-u(i, k-1))**2 &
203 +(v(i, k)-v(i, k-1))**2)
204 zmgeom(i)=zgeop(i, k)-zgeop(i, k-1)
205 zdphi =zmgeom(i) / 2.0
206 zt = (t(i, k)+t(i, k-1)) * 0.5
207 zq = (q(i, k)+q(i, k-1)) * 0.5
208
209 ! calculer Qs et dQs/dT:
210
211 IF (thermcep) THEN
212 zdelta = MAX(0., SIGN(1., RTT-zt))
213 zcvm5 = R5LES*RLVTT/RCPD/(1.0+RVTMP2*zq)*(1.-zdelta) &
214 + R5IES*RLSTT/RCPD/(1.0+RVTMP2*zq)*zdelta
215 zqs = R2ES * FOEEW(zt, zdelta) / pplay(i, k)
216 zqs = MIN(0.5, zqs)
217 zcor = 1./(1.-RETV*zqs)
218 zqs = zqs*zcor
219 zdqs = FOEDE(zt, zdelta, zcvm5, zqs, zcor)
220 ELSE
221 IF (zt .LT. t_coup) THEN
222 zqs = qsats(zt) / pplay(i, k)
223 zdqs = dqsats(zt, zqs)
224 ELSE
225 zqs = qsatl(zt) / pplay(i, k)
226 zdqs = dqsatl(zt, zqs)
227 ENDIF
228 ENDIF
229
230 ! calculer la fraction nuageuse (processus humide):
231
232 zfr = (zq+ratqs*zq-zqs) / (2.0*ratqs*zq)
233 zfr = MAX(0.0, MIN(1.0, zfr))
234 IF (.NOT.richum) zfr = 0.0
235
236 ! calculer le nombre de Richardson:
237
238 IF (tvirtu) THEN
239 ztvd =( t(i, k) &
240 + zdphi/RCPD/(1.+RVTMP2*zq) &
241 *( (1.-zfr) + zfr*(1.+RLVTT*zqs/RD/zt)/(1.+zdqs) ) &
242 )*(1.+RETV*q(i, k))
243 ztvu =( t(i, k-1) &
244 - zdphi/RCPD/(1.+RVTMP2*zq) &
245 *( (1.-zfr) + zfr*(1.+RLVTT*zqs/RD/zt)/(1.+zdqs) ) &
246 )*(1.+RETV*q(i, k-1))
247 zri(i) =zmgeom(i)*(ztvd-ztvu)/(zdu2*0.5*(ztvd+ztvu))
248 zri(i) = zri(i) &
249 + zmgeom(i)*zmgeom(i)/RG*gamt(k) &
250 *(paprs(i, k)/101325.0)**RKAPPA &
251 /(zdu2*0.5*(ztvd+ztvu))
252
253 ELSE ! calcul de Ridchardson compatible LMD5
254
255 zri(i) =(RCPD*(t(i, k)-t(i, k-1)) &
256 -RD*0.5*(t(i, k)+t(i, k-1))/paprs(i, k) &
257 *(pplay(i, k)-pplay(i, k-1)) &
258 )*zmgeom(i)/(zdu2*0.5*RCPD*(t(i, k-1)+t(i, k)))
259 zri(i) = zri(i) + &
260 zmgeom(i)*zmgeom(i)*gamt(k)/RG &
261 *(paprs(i, k)/101325.0)**RKAPPA &
262 /(zdu2*0.5*(t(i, k-1)+t(i, k)))
263 ENDIF
264
265 ! finalement, les coefficients d'echange sont obtenus:
266
267 zcdn=SQRT(zdu2) / zmgeom(i) * RG
268
269 IF (opt_ec) THEN
270 z2geomf=zgeop(i, k-1)+zgeop(i, k)
271 zalm2=(0.5*ckap/RG*z2geomf &
272 /(1.+0.5*ckap/rg/clam*z2geomf))**2
273 zalh2=(0.5*ckap/rg*z2geomf &
274 /(1.+0.5*ckap/RG/(clam*SQRT(1.5*cd))*z2geomf))**2
275 IF (zri(i).LT.0.0) THEN ! situation instable
276 zscf = ((zgeop(i, k)/zgeop(i, k-1))**(1./3.)-1.)**3 &
277 / (zmgeom(i)/RG)**3 / (zgeop(i, k-1)/RG)
278 zscf = SQRT(-zri(i)*zscf)
279 zscfm = 1.0 / (1.0+3.0*cb*cc*zalm2*zscf)
280 zscfh = 1.0 / (1.0+3.0*cb*cc*zalh2*zscf)
281 pcfm(i, k)=zcdn*zalm2*(1.-2.0*cb*zri(i)*zscfm)
282 pcfh(i, k)=zcdn*zalh2*(1.-3.0*cb*zri(i)*zscfh)
283 ELSE ! situation stable
284 zscf=SQRT(1.+cd*zri(i))
285 pcfm(i, k)=zcdn*zalm2/(1.+2.0*cb*zri(i)/zscf)
286 pcfh(i, k)=zcdn*zalh2/(1.+3.0*cb*zri(i)*zscf)
287 ENDIF
288 ELSE
289 zl2(i)=(mixlen*MAX(0.0, (paprs(i, k)-paprs(i, itop(i)+1)) &
290 /(paprs(i, 2)-paprs(i, itop(i)+1)) ))**2
291 pcfm(i, k)=sqrt(max(zcdn*zcdn*(ric-zri(i))/ric, kstable))
292 pcfm(i, k)= zl2(i)* pcfm(i, k)
293 pcfh(i, k) = pcfm(i, k) /prandtl ! h et m different
294 ENDIF
295 ENDDO
296 ENDDO
297
298 ! Au-dela du sommet, pas de diffusion turbulente:
299
300 DO i = 1, knon
301 IF (itop(i)+1 .LE. klev) THEN
302 DO k = itop(i)+1, klev
303 pcfh(i, k) = 0.0
304 pcfm(i, k) = 0.0
305 ENDDO
306 ENDIF
307 ENDDO
308
309 END SUBROUTINE coefkz

  ViewVC Help
Powered by ViewVC 1.1.21