source: LMDZ5/trunk/libf/phylmd/stdlevvar.F90 @ 2237

Last change on this file since 2237 was 2232, checked in by fhourdin, 10 years ago

1) Fusion des procédures clcdrag.F90 et coefcdrag.F90

dans une procédure unique cdrag.F90.
Les deux anciennes sont obsolètes mais maintenues dans le
code quelques mois pour d'éventuels tests.

2) modification du nom du module arth.F90 en arth_m.F90 pour

avoir le même nom de fichier et de module (règle adoptée
pour LMDZ et utilisée par makelmdz).

1) merging clcdrag.F90 and coefcdrag.F90 in one procedure cdrag.F90
2) renaming arth.F90 in arth_m.F90

  1. Wang/FH
  • Property copyright set to
    Name of program: LMDZ
    Creation date: 1984
    Version: LMDZ5
    License: CeCILL version 2
    Holder: Laboratoire de m\'et\'eorologie dynamique, CNRS, UMR 8539
    See the license file in the root directory
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.8 KB
Line 
1!
2! $Header$
3!
4      SUBROUTINE stdlevvar(klon, knon, nsrf, zxli, &
5                           u1, v1, t1, q1, z1, &
6                           ts1, qsurf, rugos, 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! rugos---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, rugos
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      CALL cdrag(knon, nsrf, &
106 &                   speed, t1, q1, z1, &
107 &                   psol, ts1, qsurf, rugos, &
108 &                   cdram, cdrah, zri1, pref)
109
110! --- special Dice: on force cdragm ( a defaut de forcer ustar) MPL 05082013
111     IF (ok_prescr_ust) then
112      DO i = 1, knon
113       print *,'cdram avant=',cdram(i)
114       cdram(i) = ust*ust/speed(i)/speed(i)
115       print *,'cdram ust speed apres=',cdram(i),ust,speed
116      ENDDO
117     ENDIF
118!
119!---------Star variables----------------------------------------------------
120!
121      DO i = 1, knon
122        ri1(i) = zri1(i)
123        tpot(i) = t1(i)* (psol(i)/pat1(i))**RKAPPA
124        ustar(i) = sqrt(cdram(i) * speed(i) * speed(i))
125        zdte(i) = tpot(i) - ts1(i)
126        zdq(i) = max(q1(i),0.0) - max(qsurf(i),0.0)
127!
128!
129!IM BUG BUG BUG       zdte(i) = max(zdte(i),1.e-10)
130        zdte(i) = sign(max(abs(zdte(i)),1.e-10),zdte(i))
131!
132        testar(i) = (cdrah(i) * zdte(i) * speed(i))/ustar(i)
133        qstar(i) = (cdrah(i) * zdq(i) * speed(i))/ustar(i)
134        lmon(i) = (ustar(i) * ustar(i) * tpot(i))/ &
135 &                (RKAR * RG * testar(i))
136      ENDDO
137!
138!----------First aproximation of variables at zref --------------------------
139      zref = 2.0
140      CALL screenp(klon, knon, nsrf, speed, tpot, q1, &
141 &                 ts1, qsurf, rugos, lmon, &
142 &                 ustar, testar, qstar, zref, &
143 &                 delu, delte, delq)
144!
145      DO i = 1, knon
146        u_zref(i) = delu(i)
147        q_zref(i) = max(qsurf(i),0.0) + delq(i)
148        te_zref(i) = ts1(i) + delte(i)
149        temp(i) = te_zref(i) * (psol(i)/pat1(i))**(-RKAPPA)
150        q_zref_p(i) = q_zref(i)
151!       te_zref_p(i) = te_zref(i)
152        temp_p(i) = temp(i)
153      ENDDO
154!
155! Iteration of the variables at the reference level zref : corrector calculation ; see Hess & McAvaney, 1995
156!
157      DO n = 1, niter
158!
159        okri=.TRUE.
160        CALL screenc(klon, knon, nsrf, zxli, &
161 &                   u_zref, temp, q_zref, zref, &
162 &                   ts1, qsurf, rugos, psol, &           
163 &                   ustar, testar, qstar, okri, ri1, &
164 &                   pref, delu, delte, delq)
165!
166        DO i = 1, knon
167          u_zref(i) = delu(i)
168          q_zref(i) = delq(i) + max(qsurf(i),0.0)
169          te_zref(i) = delte(i) + ts1(i)
170!
171! return to normal temperature
172!
173          temp(i) = te_zref(i) * (psol(i)/pref(i))**(-RKAPPA)
174!         temp(i) = te_zref(i) - (zref* RG)/RCPD/ &
175!                 (1 + RVTMP2 * max(q_zref(i),0.0))
176!
177!IM +++
178!         IF(temp(i).GT.350.) THEN
179!           WRITE(*,*) 'temp(i) GT 350 K !!',i,nsrf,temp(i)
180!         ENDIF
181!IM ---
182!
183        IF(n.EQ.ncon) THEN
184          te_zref_con(i) = te_zref(i)
185          q_zref_con(i) = q_zref(i)
186        ENDIF
187!
188        ENDDO
189!
190      ENDDO
191!
192! verifier le critere de convergence : 0.25% pour te_zref et 5% pour qe_zref
193!
194!       DO i = 1, knon
195!         conv_te(i) = (te_zref(i) - te_zref_con(i))/te_zref_con(i)
196!         conv_q(i) = (q_zref(i) - q_zref_con(i))/q_zref_con(i)
197!IM +++
198!         IF(abs(conv_te(i)).GE.0.0025.AND.abs(conv_q(i)).GE.0.05) THEN
199!           PRINT*,'DIV','i=',i,te_zref_con(i),te_zref(i),conv_te(i), &
200!           q_zref_con(i),q_zref(i),conv_q(i)
201!         ENDIF
202!IM ---
203!       ENDDO
204!
205      DO i = 1, knon
206        q_zref_c(i) = q_zref(i)
207        temp_c(i) = temp(i)
208!
209!       IF(zri1(i).LT.0.) THEN
210!         IF(nsrf.EQ.1) THEN
211!           ok_pred(i)=1.
212!           ok_corr(i)=0.
213!         ELSE
214!           ok_pred(i)=0.
215!           ok_corr(i)=1.
216!         ENDIF
217!       ELSE
218!         ok_pred(i)=0.
219!         ok_corr(i)=1.
220!       ENDIF
221!
222        ok_pred(i)=0.
223        ok_corr(i)=1.
224!
225        t_2m(i) = temp_p(i) * ok_pred(i) + temp_c(i) * ok_corr(i)
226        q_2m(i) = q_zref_p(i) * ok_pred(i) + q_zref_c(i) * ok_corr(i)
227!IM +++
228!       IF(n.EQ.niter) THEN
229!       IF(t_2m(i).LT.t1(i).AND.t_2m(i).LT.ts1(i)) THEN
230!         PRINT*,' BAD t2m LT ',i,nsrf,t_2m(i),t1(i),ts1(i)
231!       ELSEIF(t_2m(i).GT.t1(i).AND.t_2m(i).GT.ts1(i)) THEN
232!         PRINT*,' BAD t2m GT ',i,nsrf,t_2m(i),t1(i),ts1(i)
233!       ENDIF
234!       ENDIF
235!IM ---
236      ENDDO
237!
238!
239!----------First aproximation of variables at zref --------------------------
240!
241      zref = 10.0
242      CALL screenp(klon, knon, nsrf, speed, tpot, q1, &
243 &                 ts1, qsurf, rugos, lmon, &
244 &                 ustar, testar, qstar, zref, &
245 &                 delu, delte, delq)
246!
247      DO i = 1, knon
248        u_zref(i) = delu(i)
249        q_zref(i) = max(qsurf(i),0.0) + delq(i)
250        te_zref(i) = ts1(i) + delte(i)
251        temp(i) = te_zref(i) * (psol(i)/pat1(i))**(-RKAPPA)
252!       temp(i) = te_zref(i) - (zref* RG)/RCPD/ &
253!                 (1 + RVTMP2 * max(q_zref(i),0.0))
254        u_zref_p(i) = u_zref(i)
255      ENDDO
256!
257! Iteration of the variables at the reference level zref : corrector ; see Hess & McAvaney, 1995
258!
259      DO n = 1, niter
260!
261        okri=.TRUE.
262        CALL screenc(klon, knon, nsrf, zxli, &
263 &                   u_zref, temp, q_zref, zref, &
264 &                   ts1, qsurf, rugos, psol, &
265 &                   ustar, testar, qstar, okri, ri1, &
266 &                   pref, delu, delte, delq)
267!
268        DO i = 1, knon
269          u_zref(i) = delu(i)
270          q_zref(i) = delq(i) + max(qsurf(i),0.0)
271          te_zref(i) = delte(i) + ts1(i)
272          temp(i) = te_zref(i) * (psol(i)/pref(i))**(-RKAPPA)
273!         temp(i) = te_zref(i) - (zref* RG)/RCPD/ &
274!                   (1 + RVTMP2 * max(q_zref(i),0.0))
275        ENDDO
276!
277      ENDDO
278!
279      DO i = 1, knon
280        u_zref_c(i) = u_zref(i)
281!
282        u_10m(i) = u_zref_p(i) * ok_pred(i) + u_zref_c(i) * ok_corr(i)
283!
284!AM
285        q_zref_c(i) = q_zref(i)
286        temp_c(i) = temp(i)
287        t_10m(i) = temp_p(i) * ok_pred(i) + temp_c(i) * ok_corr(i)
288        q_10m(i) = q_zref_p(i) * ok_pred(i) + q_zref_c(i) * ok_corr(i)
289!MA
290      ENDDO
291!
292      RETURN
293      END subroutine stdlevvar
Note: See TracBrowser for help on using the repository browser.