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

Contents of /trunk/Sources/phylmd/coefkz.f

Parent Directory Parent Directory | Revision Log Revision Log


Revision 178 - (show annotations)
Fri Mar 11 18:47:26 2016 UTC (8 years, 2 months ago) by guez
File size: 8370 byte(s)
Moved variables date0, deltat, datasz_max, ncvar_ids, point, buff_pos,
buffer, regular from module histcom_var to modules where they are
defined.

Removed procedure ioipslmpp, useless for a sequential program.

Added argument datasz_max to histwrite_real (to avoid circular
dependency with histwrite).

Removed useless variables and computations everywhere.

Changed real litteral constants from default kind to double precision
in lwb, lwu, lwvn, sw1s, swtt, swtt1, swu.

Removed unused arguments: paer of sw, sw1s, sw2s, swclr; pcldsw of
sw1s, sw2s; pdsig, prayl of swr; co2_ppm of clmain, clqh; tsol of
transp_lay; nsrf of screenp; kcrit and kknu of gwstress; pstd of
orosetup.

Added output of relative humidity.

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

  ViewVC Help
Powered by ViewVC 1.1.21