LMDZ
stdlevvar.F90
Go to the documentation of this file.
1 !
2 ! $Id: stdlevvar.F90 2243 2015-03-24 13:28:51Z fhourdin $
3 !
4  SUBROUTINE stdlevvar(klon, knon, nsrf, zxli, &
5  u1, v1, t1, q1, z1, &
6  ts1, qsurf, z0m, z0h, psol, pat1, &
7  t_2m, q_2m, t_10m, q_10m, u_10m, ustar)
8  IMPLICIT NONE
9 !-------------------------------------------------------------------------
10 !
11 ! Objet : calcul de la temperature et l'humidite relative a 2m et du
12 ! module du vent a 10m a partir des relations de Dyer-Businger et
13 ! des equations de Louis.
14 !
15 ! Reference : Hess, Colman et McAvaney (1995)
16 !
17 ! I. Musat, 01.07.2002
18 !
19 !AM On rajoute en sortie t et q a 10m pr le calcule d'hbtm2 dans clmain
20 !
21 !-------------------------------------------------------------------------
22 !
23 ! klon----input-I- dimension de la grille physique (= nb_pts_latitude X nb_pts_longitude)
24 ! knon----input-I- nombre de points pour un type de surface
25 ! nsrf----input-I- indice pour le type de surface; voir indice_sol_mod.F90
26 ! zxli----input-L- TRUE si calcul des cdrags selon Laurent Li
27 ! u1------input-R- vent zonal au 1er niveau du modele
28 ! v1------input-R- vent meridien au 1er niveau du modele
29 ! t1------input-R- temperature de l'air au 1er niveau du modele
30 ! q1------input-R- humidite relative au 1er niveau du modele
31 ! z1------input-R- geopotentiel au 1er niveau du modele
32 ! ts1-----input-R- temperature de l'air a la surface
33 ! qsurf---input-R- humidite relative a la surface
34 ! z0m, z0h---input-R- rugosite
35 ! psol----input-R- pression au sol
36 ! pat1----input-R- pression au 1er niveau du modele
37 !
38 ! t_2m---output-R- temperature de l'air a 2m
39 ! q_2m---output-R- humidite relative a 2m
40 ! u_10m--output-R- vitesse du vent a 10m
41 !AM
42 ! t_10m--output-R- temperature de l'air a 10m
43 ! q_10m--output-R- humidite specifique a 10m
44 ! ustar--output-R- u*
45 !
46  INTEGER, intent(in) :: klon, knon, nsrf
47  LOGICAL, intent(in) :: zxli
48  REAL, dimension(klon), intent(in) :: u1, v1, t1, q1, z1, ts1
49  REAL, dimension(klon), intent(in) :: qsurf, z0m, z0h
50  REAL, dimension(klon), intent(in) :: psol, pat1
51 !
52  REAL, dimension(klon), intent(out) :: t_2m, q_2m, ustar
53  REAL, dimension(klon), intent(out) :: u_10m, t_10m, q_10m
54 !-------------------------------------------------------------------------
55  include "flux_arp.h"
56  include "YOMCST.h"
57 !IM PLUS
58  include "YOETHF.h"
59 !
60 ! Quelques constantes et options:
61 !
62 ! RKAR : constante de von Karman
63  REAL, PARAMETER :: RKAR=0.40
64 ! niter : nombre iterations calcul "corrector"
65 ! INTEGER, parameter :: niter=6, ncon=niter-1
66  INTEGER, parameter :: niter=2, ncon=niter-1
67 !
68 ! Variables locales
69  INTEGER :: i, n
70  REAL :: zref
71  REAL, dimension(klon) :: speed
72 ! tpot : temperature potentielle
73  REAL, dimension(klon) :: tpot
74  REAL, dimension(klon) :: zri1, cdran
75  REAL, dimension(klon) :: cdram, cdrah
76 ! ri1 : nb. de Richardson entre la surface --> la 1ere couche
77  REAL, dimension(klon) :: ri1
78  REAL, dimension(klon) :: testar, qstar
79  REAL, dimension(klon) :: zdte, zdq
80 ! lmon : longueur de Monin-Obukhov selon Hess, Colman and McAvaney
81  DOUBLE PRECISION, dimension(klon) :: lmon
82  DOUBLE PRECISION, parameter :: eps=1.0d-20
83  REAL, dimension(klon) :: delu, delte, delq
84  REAL, dimension(klon) :: u_zref, te_zref, q_zref
85  REAL, dimension(klon) :: temp, pref
86  LOGICAL :: okri
87  REAL, dimension(klon) :: u_zref_p, te_zref_p, temp_p, q_zref_p
88 !convertgence
89  REAL, dimension(klon) :: te_zref_con, q_zref_con
90  REAL, dimension(klon) :: u_zref_c, te_zref_c, temp_c, q_zref_c
91  REAL, dimension(klon) :: ok_pred, ok_corr
92 ! REAL, dimension(klon) :: conv_te, conv_q
93 !-------------------------------------------------------------------------
94  DO i=1, knon
95  speed(i)=sqrt(u1(i)**2+v1(i)**2)
96  ri1(i) = 0.0
97  ENDDO
98 !
99  okri=.false.
100 ! CALL coefcdrag(klon, knon, nsrf, zxli, &
101 ! & speed, t1, q1, z1, psol, &
102 ! & ts1, qsurf, rugos, okri, ri1, &
103 ! & cdram, cdrah, cdran, zri1, pref)
104 ! Fuxing WANG, 04/03/2015, replace the coefcdrag by the merged version: cdrag
105 
106  CALL cdrag(knon, nsrf, &
107  & speed, t1, q1, z1, &
108  & psol, ts1, qsurf, z0m, z0h, &
109  & cdram, cdrah, zri1, pref)
110 
111 ! --- special Dice: on force cdragm ( a defaut de forcer ustar) MPL 05082013
112  IF (ok_prescr_ust) then
113  DO i = 1, knon
114  print *,'cdram avant=',cdram(i)
115  cdram(i) = ust*ust/speed(i)/speed(i)
116  print *,'cdram ust speed apres=',cdram(i),ust,speed
117  ENDDO
118  ENDIF
119 !
120 !---------Star variables----------------------------------------------------
121 !
122  DO i = 1, knon
123  ri1(i) = zri1(i)
124  tpot(i) = t1(i)* (psol(i)/pat1(i))**rkappa
125  ustar(i) = sqrt(cdram(i) * speed(i) * speed(i))
126  zdte(i) = tpot(i) - ts1(i)
127  zdq(i) = max(q1(i),0.0) - max(qsurf(i),0.0)
128 !
129 !
130 !IM BUG BUG BUG zdte(i) = max(zdte(i),1.e-10)
131  zdte(i) = sign(max(abs(zdte(i)),1.e-10),zdte(i))
132 !
133  testar(i) = (cdrah(i) * zdte(i) * speed(i))/ustar(i)
134  qstar(i) = (cdrah(i) * zdq(i) * speed(i))/ustar(i)
135  lmon(i) = (ustar(i) * ustar(i) * tpot(i))/ &
136  & (rkar * rg * testar(i))
137  ENDDO
138 !
139 !----------First aproximation of variables at zref --------------------------
140  zref = 2.0
141  CALL screenp(klon, knon, nsrf, speed, tpot, q1, &
142  & ts1, qsurf, z0m, lmon, &
143  & ustar, testar, qstar, zref, &
144  & delu, delte, delq)
145 !
146  DO i = 1, knon
147  u_zref(i) = delu(i)
148  q_zref(i) = max(qsurf(i),0.0) + delq(i)
149  te_zref(i) = ts1(i) + delte(i)
150  temp(i) = te_zref(i) * (psol(i)/pat1(i))**(-rkappa)
151  q_zref_p(i) = q_zref(i)
152 ! te_zref_p(i) = te_zref(i)
153  temp_p(i) = temp(i)
154  ENDDO
155 !
156 ! Iteration of the variables at the reference level zref : corrector calculation ; see Hess & McAvaney, 1995
157 !
158  DO n = 1, niter
159 !
160  okri=.true.
161  CALL screenc(klon, knon, nsrf, zxli, &
162  & u_zref, temp, q_zref, zref, &
163  & ts1, qsurf, z0m, z0h, psol, &
164  & ustar, testar, qstar, okri, ri1, &
165  & pref, delu, delte, delq)
166 !
167  DO i = 1, knon
168  u_zref(i) = delu(i)
169  q_zref(i) = delq(i) + max(qsurf(i),0.0)
170  te_zref(i) = delte(i) + ts1(i)
171 !
172 ! return to normal temperature
173 !
174  temp(i) = te_zref(i) * (psol(i)/pref(i))**(-rkappa)
175 ! temp(i) = te_zref(i) - (zref* RG)/RCPD/ &
176 ! (1 + RVTMP2 * max(q_zref(i),0.0))
177 !
178 !IM +++
179 ! IF(temp(i).GT.350.) THEN
180 ! WRITE(*,*) 'temp(i) GT 350 K !!',i,nsrf,temp(i)
181 ! ENDIF
182 !IM ---
183 !
184  IF(n.EQ.ncon) THEN
185  te_zref_con(i) = te_zref(i)
186  q_zref_con(i) = q_zref(i)
187  ENDIF
188 !
189  ENDDO
190 !
191  ENDDO
192 !
193 ! verifier le critere de convergence : 0.25% pour te_zref et 5% pour qe_zref
194 !
195 ! DO i = 1, knon
196 ! conv_te(i) = (te_zref(i) - te_zref_con(i))/te_zref_con(i)
197 ! conv_q(i) = (q_zref(i) - q_zref_con(i))/q_zref_con(i)
198 !IM +++
199 ! IF(abs(conv_te(i)).GE.0.0025.AND.abs(conv_q(i)).GE.0.05) THEN
200 ! PRINT*,'DIV','i=',i,te_zref_con(i),te_zref(i),conv_te(i), &
201 ! q_zref_con(i),q_zref(i),conv_q(i)
202 ! ENDIF
203 !IM ---
204 ! ENDDO
205 !
206  DO i = 1, knon
207  q_zref_c(i) = q_zref(i)
208  temp_c(i) = temp(i)
209 !
210 ! IF(zri1(i).LT.0.) THEN
211 ! IF(nsrf.EQ.1) THEN
212 ! ok_pred(i)=1.
213 ! ok_corr(i)=0.
214 ! ELSE
215 ! ok_pred(i)=0.
216 ! ok_corr(i)=1.
217 ! ENDIF
218 ! ELSE
219 ! ok_pred(i)=0.
220 ! ok_corr(i)=1.
221 ! ENDIF
222 !
223  ok_pred(i)=0.
224  ok_corr(i)=1.
225 !
226  t_2m(i) = temp_p(i) * ok_pred(i) + temp_c(i) * ok_corr(i)
227  q_2m(i) = q_zref_p(i) * ok_pred(i) + q_zref_c(i) * ok_corr(i)
228 !IM +++
229 ! IF(n.EQ.niter) THEN
230 ! IF(t_2m(i).LT.t1(i).AND.t_2m(i).LT.ts1(i)) THEN
231 ! PRINT*,' BAD t2m LT ',i,nsrf,t_2m(i),t1(i),ts1(i)
232 ! ELSEIF(t_2m(i).GT.t1(i).AND.t_2m(i).GT.ts1(i)) THEN
233 ! PRINT*,' BAD t2m GT ',i,nsrf,t_2m(i),t1(i),ts1(i)
234 ! ENDIF
235 ! ENDIF
236 !IM ---
237  ENDDO
238 !
239 !
240 !----------First aproximation of variables at zref --------------------------
241 !
242  zref = 10.0
243  CALL screenp(klon, knon, nsrf, speed, tpot, q1, &
244  & ts1, qsurf, z0m, lmon, &
245  & ustar, testar, qstar, zref, &
246  & delu, delte, delq)
247 !
248  DO i = 1, knon
249  u_zref(i) = delu(i)
250  q_zref(i) = max(qsurf(i),0.0) + delq(i)
251  te_zref(i) = ts1(i) + delte(i)
252  temp(i) = te_zref(i) * (psol(i)/pat1(i))**(-rkappa)
253 ! temp(i) = te_zref(i) - (zref* RG)/RCPD/ &
254 ! (1 + RVTMP2 * max(q_zref(i),0.0))
255  u_zref_p(i) = u_zref(i)
256  ENDDO
257 !
258 ! Iteration of the variables at the reference level zref : corrector ; see Hess & McAvaney, 1995
259 !
260  DO n = 1, niter
261 !
262  okri=.true.
263  CALL screenc(klon, knon, nsrf, zxli, &
264  & u_zref, temp, q_zref, zref, &
265  & ts1, qsurf, z0m, z0h, psol, &
266  & ustar, testar, qstar, okri, ri1, &
267  & pref, delu, delte, delq)
268 !
269  DO i = 1, knon
270  u_zref(i) = delu(i)
271  q_zref(i) = delq(i) + max(qsurf(i),0.0)
272  te_zref(i) = delte(i) + ts1(i)
273  temp(i) = te_zref(i) * (psol(i)/pref(i))**(-rkappa)
274 ! temp(i) = te_zref(i) - (zref* RG)/RCPD/ &
275 ! (1 + RVTMP2 * max(q_zref(i),0.0))
276  ENDDO
277 !
278  ENDDO
279 !
280  DO i = 1, knon
281  u_zref_c(i) = u_zref(i)
282 !
283  u_10m(i) = u_zref_p(i) * ok_pred(i) + u_zref_c(i) * ok_corr(i)
284 !
285 !AM
286  q_zref_c(i) = q_zref(i)
287  temp_c(i) = temp(i)
288  t_10m(i) = temp_p(i) * ok_pred(i) + temp_c(i) * ok_corr(i)
289  q_10m(i) = q_zref_p(i) * ok_pred(i) + q_zref_c(i) * ok_corr(i)
290 !MA
291  ENDDO
292 !
293  RETURN
294  END subroutine stdlevvar
subroutine stdlevvar(klon, knon, nsrf, zxli, u1, v1, t1, q1, z1, ts1, qsurf, z0m, z0h, psol, pat1, t_2m, q_2m, t_10m, q_10m, u_10m, ustar)
Definition: stdlevvar.F90:8
!$Id ust
Definition: flux_arp.h:11
subroutine screenp(klon, knon, nsrf, speed, tair, qair, ts, qsurf, rugos, lmon, ustar, testar, qstar, zref, delu, delte, delq)
Definition: screenp.F90:9
!$Id itapm1 ENDIF!IM on interpole les champs sur les niveaux STD de pression!IM a chaque pas de temps de la physique c!positionnement de l argument logique a false c!pour ne pas recalculer deux fois la meme chose!c!a cet effet un appel a plevel_new a ete deplace c!a la fin de la serie d appels c!la boucle DO nlevSTD a ete internalisee c!dans d ou la creation de cette routine c c!CALL false
Definition: calcul_STDlev.h:26
subroutine screenc(klon, knon, nsrf, zxli, speed, temp, q_zref, zref, ts, qsurf, z0m, z0h, psol, ustar, testar, qstar, okri, ri1, pref, delu, delte, delq)
Definition: screenc.F90:9
!$Id itapm1 ENDIF!IM on interpole les champs sur les niveaux STD de pression!IM a chaque pas de temps de la physique c!positionnement de l argument logique a false c!pour ne pas recalculer deux fois la meme chose!c!a cet effet un appel a plevel_new a ete deplace c!a la fin de la serie d appels c!la boucle DO nlevSTD a ete internalisee c!dans d ou la creation de cette routine c c!CALL ulevSTD CALL &zphi philevSTD CALL &zx_rh rhlevSTD!DO klev DO klon klev DO klon klev DO klon klev DO klon klev DO klon klev DO klon klev DO klon klev DO klon klev DO klon klev DO klon du jour ou toutes les read_climoz CALL true
subroutine cdrag(knon, nsrf, speed, t1, q1, zgeop1, psol, tsurf, qsurf, z0m, z0h, pcfm, pcfh, zri, pref)
Definition: cdrag.F90:8
real rg
Definition: comcstphy.h:1