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

Last change on this file since 5420 was 2243, checked in by fhourdin, 10 years ago

Revisite de la formule des flux de surface
(en priorité sur l'océan) en tenant compte des bourrasques de
vent et de la différence entre les hauteurs de rugosités pour
la quantité de mouvement, l'enthalpie et éventuellement l'humidité.

Etape 2 :

  • Séparation des z0 pour la quantité de mouvement et l'enthalpie.

rugs (ou frugs, rugos, yrugos ...) disparait au profit de z0m, z0h.
Les variables qui étaient à la fois dans pbl_surface_init et

  • dans l'interface de pbl_surface sont suprimées de pbl_surface_init.

On travaille directement pour ces variables (evap, z0, qsol, agesno)
avec les versions de phys_state_var_mod (qui étaient
précédemment dans phys_local_var_mod

  • Nouveaux paramètres de contrôle :
    • iflag_z0_oce (par défaut 0, et seule option active jusque là)
    • z0m_seaice_omp, z0h_seaice_omp, comme leur nom l'indique (utilisées dans surf_landice
    • z0min appliqué sur z0m et z0h dans pbl_surface
  • Introduction des fonction phyeta0_get et phyetat0_srf pour lire

les conditions de initiales dans startphy.
Du coup une seule ligne suffit pour lire et contrôler d'éventuels
problèmes.

  • Pour la variable fxrugs, elle est remplacée par z0m(:,nbsrf+1)

Ce choix déjà utilisé pour d'autres variables pourrait être
systématiser pour alléger l'interface de pbl_surface_mod.

  • Dans les sorties, les variables rugs* ont été remplacées par

des z0m* et z0h*

  • Nettoyage des anciens alb1/alb2 dans les lectures/écritures

des états de redémarrage (et dans pbl_surface_mod.F90).

  • 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, 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
Note: See TracBrowser for help on using the repository browser.