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

Contents of /trunk/phylmd/coefkz.f

Parent Directory Parent Directory | Revision Log Revision Log


Revision 103 - (show annotations)
Fri Aug 29 13:00:05 2014 UTC (9 years, 8 months ago) by guez
File size: 8410 byte(s)
Renamed module cvparam to cv_param. Deleted procedure
cv_param. Changed variables of module cv_param into parameters.

In procedures cv_driver, cv_uncompress and cv3_uncompress, removed
some arguments giving dimensions and used module variables klon and
klev instead.

In procedures gradiv2, laplacien_gam and laplacien, changed
declarations of local variables because klevel is not always klev.

Removed code for nudging surface pressure.

Removed arguments pim and pjm of tau2alpha. Added assignment of false
to variable first.

Replaced real argument del of procedures foeew and FOEDE by logical
argument.

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, coefm, coefh)
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
17 USE conf_gcm_m, 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 use clcdrag_m, only: clcdrag
23
24 ! Arguments:
25
26 integer, intent(in):: nsrf ! indicateur de la nature du sol
27 INTEGER, intent(in):: knon ! nombre de points a traiter
28
29 REAL, intent(in):: paprs(klon, klev+1)
30 ! pression a chaque intercouche (en Pa)
31
32 real, intent(in):: pplay(klon, klev)
33 ! pression au milieu de chaque couche (en Pa)
34
35 REAL, intent(in):: ksta, ksta_ter
36 REAL, intent(in):: ts(klon) ! temperature du sol (en Kelvin)
37 REAL, intent(in):: rugos(klon) ! longeur de rugosite (en m)
38 REAL, intent(in):: u(klon, klev), v(klon, klev) ! wind
39 REAL, intent(in):: t(klon, klev) ! temperature (K)
40 real, intent(in):: q(klon, klev) ! vapeur d'eau (kg/kg)
41 real, intent(in):: qsurf(klon)
42 REAL, intent(out):: coefm(:, :) ! (knon, klev) coefficient, vitesse
43
44 real, intent(out):: coefh(:, :) ! (knon, klev)
45 ! coefficient, chaleur et humidité
46
47 ! Local:
48
49 INTEGER itop(knon) ! numero de couche du sommet de la couche limite
50
51 ! Quelques constantes et options:
52
53 REAL, PARAMETER:: cepdu2 =0.1**2
54 REAL, PARAMETER:: CKAP = 0.4
55 REAL, PARAMETER:: cb = 5.
56 REAL, PARAMETER:: cc = 5.
57 REAL, PARAMETER:: cd = 5.
58 REAL, PARAMETER:: clam = 160.
59 REAL, PARAMETER:: ratqs = 0.05 ! largeur de distribution de vapeur d'eau
60
61 LOGICAL, PARAMETER:: richum = .TRUE.
62 ! utilise le nombre de Richardson humide
63
64 REAL, PARAMETER:: ric = 0.4 ! nombre de Richardson critique
65 REAL, PARAMETER:: prandtl = 0.4
66
67 REAL kstable ! diffusion minimale (situation stable)
68 REAL, PARAMETER:: mixlen = 35. ! constante contrôlant longueur de mélange
69 INTEGER, PARAMETER:: isommet = klev ! sommet de la couche limite
70
71 LOGICAL, PARAMETER:: tvirtu = .TRUE.
72 ! calculer Ri d'une maniere plus performante
73
74 LOGICAL, PARAMETER:: opt_ec = .FALSE.
75 ! formule du Centre Europeen dans l'atmosphere
76
77 INTEGER i, k, kk
78 REAL zgeop(klon, klev)
79 REAL zmgeom(klon)
80 REAL ri(klon)
81 REAL l2(klon)
82
83 REAL u1(klon), v1(klon), t1(klon), q1(klon), z1(klon)
84
85 REAL zdphi, zdu2, ztvd, ztvu, cdn
86 REAL scf
87 REAL zt, zq, zcvm5, zcor, zqs, zfr, zdqs
88 logical zdelta
89 REAL z2geomf, zalh2, alm2, zscfh, scfm
90 REAL, PARAMETER:: t_coup = 273.15
91 REAL gamt(2:klev) ! contre-gradient pour la chaleur sensible: Kelvin/metre
92
93 !--------------------------------------------------------------------
94
95 ! Prescrire la valeur de contre-gradient
96 if (iflag_pbl.eq.1) then
97 DO k = 3, klev
98 gamt(k) = -1.0E-03
99 ENDDO
100 gamt(2) = -2.5E-03
101 else
102 DO k = 2, klev
103 gamt(k) = 0.0
104 ENDDO
105 ENDIF
106
107 IF ( nsrf .NE. is_oce ) THEN
108 kstable = ksta_ter
109 ELSE
110 kstable = ksta
111 ENDIF
112
113 ! Calculer les géopotentiels de chaque couche
114 DO i = 1, knon
115 zgeop(i, 1) = RD * t(i, 1) / (0.5 * (paprs(i, 1) + pplay(i, 1))) &
116 * (paprs(i, 1) - pplay(i, 1))
117 ENDDO
118 DO k = 2, klev
119 DO i = 1, knon
120 zgeop(i, k) = zgeop(i, k-1) &
121 + RD * 0.5*(t(i, k-1)+t(i, k)) / paprs(i, k) &
122 * (pplay(i, k-1)-pplay(i, k))
123 ENDDO
124 ENDDO
125
126 ! Calculer le frottement au sol (Cdrag)
127
128 DO i = 1, knon
129 u1(i) = u(i, 1)
130 v1(i) = v(i, 1)
131 t1(i) = t(i, 1)
132 q1(i) = q(i, 1)
133 z1(i) = zgeop(i, 1)
134 ENDDO
135
136 CALL clcdrag(klon, knon, nsrf, .false., u1, v1, t1, q1, z1, ts, qsurf, &
137 rugos, coefm(:, 1), coefh(:, 1))
138
139 ! Calculer les coefficients turbulents dans l'atmosphere
140
141 itop = isommet
142
143 loop_vertical: DO k = 2, isommet
144 loop_horiz: DO i = 1, knon
145 zdu2 = MAX(cepdu2, (u(i, k)-u(i, k-1))**2 &
146 +(v(i, k)-v(i, k-1))**2)
147 zmgeom(i) = zgeop(i, k)-zgeop(i, k-1)
148 zdphi =zmgeom(i) / 2.0
149 zt = (t(i, k)+t(i, k-1)) * 0.5
150 zq = (q(i, k)+q(i, k-1)) * 0.5
151
152 ! calculer Qs et dQs/dT:
153
154 IF (thermcep) THEN
155 zdelta = RTT >=zt
156 zcvm5 = merge(R5IES * RLSTT, R5LES * RLVTT, zdelta) / RCPD &
157 / (1. + RVTMP2*zq)
158 zqs = R2ES * FOEEW(zt, zdelta) / pplay(i, k)
159 zqs = MIN(0.5, zqs)
160 zcor = 1./(1.-RETV*zqs)
161 zqs = zqs*zcor
162 zdqs = FOEDE(zt, zdelta, zcvm5, zqs, zcor)
163 ELSE
164 IF (zt < t_coup) THEN
165 zqs = qsats(zt) / pplay(i, k)
166 zdqs = dqsats(zt, zqs)
167 ELSE
168 zqs = qsatl(zt) / pplay(i, k)
169 zdqs = dqsatl(zt, zqs)
170 ENDIF
171 ENDIF
172
173 ! calculer la fraction nuageuse (processus humide):
174
175 zfr = (zq+ratqs*zq-zqs) / (2.0*ratqs*zq)
176 zfr = MAX(0.0, MIN(1.0, zfr))
177 IF (.NOT.richum) zfr = 0.0
178
179 ! calculer le nombre de Richardson:
180
181 IF (tvirtu) THEN
182 ztvd =( t(i, k) &
183 + zdphi/RCPD/(1.+RVTMP2*zq) &
184 *( (1.-zfr) + zfr*(1.+RLVTT*zqs/RD/zt)/(1.+zdqs) ) &
185 )*(1.+RETV*q(i, k))
186 ztvu =( t(i, k-1) &
187 - zdphi/RCPD/(1.+RVTMP2*zq) &
188 *( (1.-zfr) + zfr*(1.+RLVTT*zqs/RD/zt)/(1.+zdqs) ) &
189 )*(1.+RETV*q(i, k-1))
190 ri(i) =zmgeom(i)*(ztvd-ztvu)/(zdu2*0.5*(ztvd+ztvu))
191 ri(i) = ri(i) &
192 + zmgeom(i)*zmgeom(i)/RG*gamt(k) &
193 *(paprs(i, k)/101325.0)**RKAPPA &
194 /(zdu2*0.5*(ztvd+ztvu))
195 ELSE
196 ! calcul de Ridchardson compatible LMD5
197 ri(i) =(RCPD*(t(i, k)-t(i, k-1)) &
198 -RD*0.5*(t(i, k)+t(i, k-1))/paprs(i, k) &
199 *(pplay(i, k)-pplay(i, k-1)) &
200 )*zmgeom(i)/(zdu2*0.5*RCPD*(t(i, k-1)+t(i, k)))
201 ri(i) = ri(i) + &
202 zmgeom(i)*zmgeom(i)*gamt(k)/RG &
203 *(paprs(i, k)/101325.0)**RKAPPA &
204 /(zdu2*0.5*(t(i, k-1)+t(i, k)))
205 ENDIF
206
207 ! finalement, les coefficients d'echange sont obtenus:
208
209 cdn = SQRT(zdu2) / zmgeom(i) * RG
210
211 IF (opt_ec) THEN
212 z2geomf = zgeop(i, k-1)+zgeop(i, k)
213 alm2 = (0.5*ckap/RG*z2geomf &
214 /(1.+0.5*ckap/rg/clam*z2geomf))**2
215 zalh2 = (0.5*ckap/rg*z2geomf &
216 /(1.+0.5*ckap/RG/(clam*SQRT(1.5*cd))*z2geomf))**2
217 IF (ri(i) < 0.) THEN
218 ! situation instable
219 scf = ((zgeop(i, k)/zgeop(i, k-1))**(1./3.)-1.)**3 &
220 / (zmgeom(i)/RG)**3 / (zgeop(i, k-1)/RG)
221 scf = SQRT(-ri(i)*scf)
222 scfm = 1.0 / (1.0+3.0*cb*cc*alm2*scf)
223 zscfh = 1.0 / (1.0+3.0*cb*cc*zalh2*scf)
224 coefm(i, k) = cdn * alm2 * (1. - 2. * cb * ri(i) * scfm)
225 coefh(i, k) = cdn*zalh2*(1.-3.0*cb*ri(i)*zscfh)
226 ELSE
227 ! situation stable
228 scf = SQRT(1.+cd*ri(i))
229 coefm(i, k) = cdn * alm2 / (1. + 2. * cb * ri(i) / scf)
230 coefh(i, k) = cdn*zalh2/(1.+3.0*cb*ri(i)*scf)
231 ENDIF
232 ELSE
233 l2(i) = (mixlen*MAX(0.0, (paprs(i, k)-paprs(i, itop(i)+1)) &
234 /(paprs(i, 2)-paprs(i, itop(i)+1)) ))**2
235 coefm(i, k) = sqrt(max(cdn**2 * (ric - ri(i)) / ric, kstable))
236 coefm(i, k)= l2(i) * coefm(i, k)
237 coefh(i, k) = coefm(i, k) / prandtl ! h et m different
238 ENDIF
239 ENDDO loop_horiz
240 ENDDO loop_vertical
241
242 ! Au-delà du sommet, pas de diffusion turbulente :
243 forall (i = 1: knon)
244 coefh(i, itop(i) + 1:) = 0.
245 coefm(i, itop(i) + 1:) = 0.
246 END forall
247
248 END SUBROUTINE coefkz
249
250 end module coefkz_m

  ViewVC Help
Powered by ViewVC 1.1.21