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

Annotation of /trunk/phylmd/coefkz.f

Parent Directory Parent Directory | Revision Log Revision Log


Revision 40 - (hide 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 guez 40 SUBROUTINE coefkz(nsrf, knon, paprs, pplay, ksta, ksta_ter, ts, rugos, u, v, &
2     t, q, qsurf, pcfm, pcfh)
3 guez 3
4 guez 40 ! 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 guez 3
9 guez 40 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 guez 3
17 guez 40 IMPLICIT none
18 guez 3
19 guez 40 ! 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 guez 3
30 guez 40 ! 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