source: LMDZ.3.3/branches/rel-LF/libf/phylmd/clmain.F @ 293

Last change on this file since 293 was 293, checked in by lmdzadmin, 23 years ago

On passait a ORCHIDEE un flux solaire albedoise deux fois (je me comprends)
LF

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 62.2 KB
Line 
1c
2c $Header$
3c
4
5      SUBROUTINE clmain(dtime,itap,date0,pctsrf,
6     .                  t,q,u,v,
7     .                  jour, rmu0,
8     .                  ok_veget, ocean, npas, nexca, ts,
9     .                  soil_model,ftsoil,
10     .                  paprs,pplay,radsol,snow,qsol,evap,albe,alblw,
11     .                  fluxlat,
12     .                  rain_f, snow_f, solsw, sollw, sollwdown, fder,
13     .                  rlon, rlat, cufi, cvfi, rugos,
14     .                  debut, lafin, agesno,rugoro,
15     .                  d_t,d_q,d_u,d_v,d_ts,
16     .                  flux_t,flux_q,flux_u,flux_v,cdragh,cdragm,
17     .                  dflux_t,dflux_q,
18     .                  zcoefh,zu1,zv1)
19cAA .                  itr, tr, flux_surf, d_tr)
20cAA REM:
21cAA-----
22cAA Tout ce qui a trait au traceurs est dans phytrac maintenant
23cAA pour l'instant le calcul de la couche limite pour les traceurs
24cAA se fait avec cltrac et ne tient pas compte de la differentiation
25cAA des sous-fraction de sol.
26cAA REM bis :
27cAA----------
28cAA Pour pouvoir extraire les coefficient d'echanges et le vent
29cAA dans la premiere couche, 3 champs supplementaires ont ete crees
30cAA zcoefh,zu1 et zv1. Pour l'instant nous avons moyenne les valeurs
31cAA de ces trois champs sur les 4 subsurfaces du modele. Dans l'avenir
32cAA si les informations des subsurfaces doivent etre prises en compte
33cAA il faudra sortir ces memes champs en leur ajoutant une dimension,
34cAA c'est a dire nbsrf (nbre de subsurface).
35      USE ioipsl
36      USE interface_surf
37      IMPLICIT none
38c======================================================================
39c Auteur(s) Z.X. Li (LMD/CNRS) date: 19930818
40c Objet: interface de "couche limite" (diffusion verticale)
41c Arguments:
42c dtime----input-R- interval du temps (secondes)
43c itap-----input-I- numero du pas de temps
44c date0----input-R- jour initial
45c t--------input-R- temperature (K)
46c q--------input-R- vapeur d'eau (kg/kg)
47c u--------input-R- vitesse u
48c v--------input-R- vitesse v
49c ts-------input-R- temperature du sol (en Kelvin)
50c paprs----input-R- pression a intercouche (Pa)
51c pplay----input-R- pression au milieu de couche (Pa)
52c radsol---input-R- flux radiatif net (positif vers le sol) en W/m**2
53c rlat-----input-R- latitude en degree
54c rugos----input-R- longeur de rugosite (en m)
55c cufi-----input-R- resolution des mailles en x (m)
56c cvfi-----input-R- resolution des mailles en y (m)
57c
58c d_t------output-R- le changement pour "t"
59c d_q------output-R- le changement pour "q"
60c d_u------output-R- le changement pour "u"
61c d_v------output-R- le changement pour "v"
62c d_ts-----output-R- le changement pour "ts"
63c flux_t---output-R- flux de chaleur sensible (CpT) J/m**2/s (W/m**2)
64c                    (orientation positive vers le bas)
65c flux_q---output-R- flux de vapeur d'eau (kg/m**2/s)
66c flux_u---output-R- tension du vent X: (kg m/s)/(m**2 s) ou Pascal
67c flux_v---output-R- tension du vent Y: (kg m/s)/(m**2 s) ou Pascal
68c dflux_t derive du flux sensible
69c dflux_q derive du flux latent
70cAA on rajoute en output yu1 et yv1 qui sont les vents dans
71cAA la premiere couche
72cAA ces 4 variables sont maintenant traites dans phytrac
73c itr--------input-I- nombre de traceurs
74c tr---------input-R- q. de traceurs
75c flux_surf--input-R- flux de traceurs a la surface
76c d_tr-------output-R tendance de traceurs
77c======================================================================
78#include "dimensions.h"
79#include "dimphy.h"
80#include "indicesol.h"
81c$$$ PB ajout pour soil
82#include "dimsoil.h"
83c
84      REAL dtime
85      real date0
86      integer itap
87      REAL t(klon,klev), q(klon,klev)
88      REAL u(klon,klev), v(klon,klev)
89      REAL paprs(klon,klev+1), pplay(klon,klev), radsol(klon)
90      REAL rlon(klon), rlat(klon), cufi(klon), cvfi(klon)
91      REAL d_t(klon, klev), d_q(klon, klev)
92      REAL d_u(klon, klev), d_v(klon, klev)
93      REAL flux_t(klon,klev, nbsrf), flux_q(klon,klev, nbsrf)
94      REAL dflux_t(klon), dflux_q(klon)
95      REAL flux_u(klon,klev, nbsrf), flux_v(klon,klev, nbsrf)
96      REAL rugmer(klon), agesno(klon,nbsrf),rugoro(klon)
97      REAL cdragh(klon), cdragm(klon)
98      integer jour            ! jour de l'annee en cours
99      real rmu0(klon)         ! cosinus de l'angle solaire zenithal
100      LOGICAL debut, lafin, ok_veget
101      character*6 ocean
102      integer npas, nexca
103cAA      INTEGER itr
104cAA      REAL tr(klon,klev,nbtr)
105cAA      REAL d_tr(klon,klev,nbtr)
106cAA      REAL flux_surf(klon,nbtr)
107c
108      REAL pctsrf(klon,nbsrf)
109      REAL ts(klon,nbsrf)
110      REAL d_ts(klon,nbsrf)
111      REAL snow(klon,nbsrf)
112      REAL qsol(klon,nbsrf)
113      REAL evap(klon,nbsrf)
114      REAL albe(klon,nbsrf)
115      REAL alblw(klon,nbsrf)
116c$$$ PB
117      REAL fluxlat(klon,nbsrf)
118C
119      real rain_f(klon), snow_f(klon)
120      REAL fder(klon)
121      REAL sollw(klon), solsw(klon), sollwdown(klon)
122      REAL rugos(klon,nbsrf)
123C la nouvelle repartition des surfaces sortie de l'interface
124      REAL pctsrf_new(klon,nbsrf)
125cAA
126      REAL zcoefh(klon,klev)
127      REAL zu1(klon)
128      REAL zv1(klon)
129cAA
130c$$$ PB ajout pour soil
131      LOGICAL soil_model
132      REAL ftsoil(klon,nsoilmx,nbsrf)
133      REAL ytsoil(klon,nsoilmx)
134c======================================================================
135      EXTERNAL clqh, clvent, coefkz, calbeta, cltrac
136c======================================================================
137      REAL yts(klon), yrugos(klon), ypct(klon), yz0_new(klon)
138      REAL yalb(klon)
139      REAL yalblw(klon)
140      REAL yu1(klon), yv1(klon)
141      real ysnow(klon), yqsol(klon), yagesno(klon)
142      real yrain_f(klon), ysnow_f(klon)
143      real ysollw(klon), ysolsw(klon), ysollwdown(klon)
144      real yfder(klon), ytaux(klon), ytauy(klon)
145      REAL yrugm(klon), yrads(klon),yrugoro(klon)
146c$$$ PB
147      REAL yfluxlat(klon)
148C
149      REAL y_d_ts(klon)
150      REAL y_d_t(klon, klev), y_d_q(klon, klev)
151      REAL y_d_u(klon, klev), y_d_v(klon, klev)
152      REAL y_flux_t(klon,klev), y_flux_q(klon,klev)
153      REAL y_flux_u(klon,klev), y_flux_v(klon,klev)
154      REAL y_dflux_t(klon), y_dflux_q(klon)
155      REAL ycoefh(klon,klev), ycoefm(klon,klev)
156      REAL yu(klon,klev), yv(klon,klev)
157      REAL yt(klon,klev), yq(klon,klev)
158      REAL ypaprs(klon,klev+1), ypplay(klon,klev), ydelp(klon,klev)
159cAA      REAL ytr(klon,klev,nbtr)
160cAA      REAL y_d_tr(klon,klev,nbtr)
161cAA      REAL yflxsrf(klon,nbtr)
162c
163      LOGICAL contreg
164      PARAMETER (contreg=.TRUE.)
165c
166      LOGICAL ok_nonloc
167      PARAMETER (ok_nonloc=.FALSE.)
168      REAL ycoefm0(klon,klev), ycoefh0(klon,klev)
169c
170#include "YOMCST.h"
171      REAL u1lay(klon), v1lay(klon)
172      REAL delp(klon,klev)
173      REAL totalflu(klon)
174      INTEGER i, k, nsrf
175cAA   INTEGER it
176      INTEGER ni(klon), knon, j
177c Introduction d'une variable "pourcentage potentiel" pour tenir compte
178c des eventuelles apparitions et/ou disparitions de la glace de mer
179      REAL pctsrf_pot(klon,nbsrf)
180     
181c======================================================================
182      REAL zx_alf1, zx_alf2 !valeur ambiante par extrapola.
183c======================================================================
184c
185c maf pour sorties IOISPL en cas de debugagage
186c
187      CHARACTER*80 cldebug
188      SAVE cldebug
189      CHARACTER*8 cl_surf(nbsrf)
190      SAVE cl_surf
191      INTEGER nhoridbg, nidbg
192      SAVE nhoridbg, nidbg
193      INTEGER ndexbg(iim*(jjm+1))
194      REAL zx_lon(iim,jjm+1), zx_lat(iim,jjm+1), zjulian
195      REAL tabindx(klon)
196      REAL debugtab(iim,jjm+1)
197      LOGICAL first_appel
198      SAVE first_appel
199      DATA first_appel/.true./
200      LOGICAL debugindex
201      SAVE debugindex
202      DATA debugindex/.true./
203#include "temps.h"
204     
205      IF (first_appel) THEN
206          first_appel=.false.
207!
208! initialisation sorties netcdf
209!
210          CALL ymds2ju(anne_ini, 1, 1, 0.0, zjulian)
211          zjulian = zjulian + day_ini
212          CALL gr_fi_ecrit(1,klon,iim,jjm+1,rlon,zx_lon)
213          DO i = 1, iim
214            zx_lon(i,1) = rlon(i+1)
215            zx_lon(i,jjm+1) = rlon(i+1)
216          ENDDO
217          CALL gr_fi_ecrit(1,klon,iim,jjm+1,rlat,zx_lat)
218          cldebug='sous_index'
219          CALL histbeg(cldebug, iim,zx_lon,jjm+1,zx_lat,1,iim,1,jjm
220     $        +1, 0,zjulian,dtime,nhoridbg,nidbg)
221! no vertical axis
222          cl_surf(1)='ter'
223          cl_surf(2)='lic'
224          cl_surf(3)='oce'
225          cl_surf(4)='sic'
226          DO nsrf=1,nbsrf
227            CALL histdef(nidbg, cl_surf(nsrf),cl_surf(nsrf), "-",iim,
228     $          jjm+1,nhoridbg, 1, 1, 1, -99, 32, "inst", dtime,dtime)
229          END DO
230          CALL histend(nidbg)
231          CALL histsync(nidbg)
232      ENDIF
233         
234      DO k = 1, klev   ! epaisseur de couche
235      DO i = 1, klon
236         delp(i,k) = paprs(i,k)-paprs(i,k+1)
237      ENDDO
238      ENDDO
239      DO i = 1, klon  ! vent de la premiere couche
240ccc         zx_alf1 = (paprs(i,1)-pplay(i,2))/(pplay(i,1)-pplay(i,2))
241         zx_alf1 = 1.0
242         zx_alf2 = 1.0 - zx_alf1
243         u1lay(i) = u(i,1)*zx_alf1 + u(i,2)*zx_alf2
244         v1lay(i) = v(i,1)*zx_alf1 + v(i,2)*zx_alf2
245      ENDDO
246c
247c initialisation:
248c
249      DO i = 1, klon
250         rugmer(i) = 0.0
251         cdragh(i) = 0.0
252         cdragm(i) = 0.0
253         dflux_t(i) = 0.0
254         dflux_q(i) = 0.0
255         zu1(i) = 0.0
256         zv1(i) = 0.0
257      ENDDO
258      ypct = 0.0
259      yts = 0.0
260      ysnow = 0.0
261      yqsol = 0.0
262      yalb = 0.0
263      yalblw = 0.0
264      yrain_f = 0.0
265      ysnow_f = 0.0
266      yfder = 0.0
267      ytaux = 0.0
268      ytauy = 0.0
269      ysolsw = 0.0
270      ysollw = 0.0
271      ysollwdown = 0.0
272      yrugos = 0.0
273      yu1 = 0.0
274      yv1 = 0.0
275      yrads = 0.0
276      ypaprs = 0.0
277      ypaprs = 0.0
278      ypplay = 0.0
279      ydelp = 0.0
280      yu = 0.0
281      yv = 0.0
282      yt = 0.0
283      yq = 0.0
284      pctsrf_new = 0.0
285      y_flux_u = 0.0
286      y_flux_v = 0.0
287C$$ PB
288      y_dflux_t = 0.0
289      y_dflux_q = 0.0
290      ytsoil = 999999.
291      yrugoro = 0.
292
293      DO nsrf = 1, nbsrf
294      DO i = 1, klon
295         d_ts(i,nsrf) = 0.0
296      ENDDO
297      END DO
298C§§§ PB
299      yfluxlat=0.
300      flux_t = 0.
301      flux_q = 0.
302      flux_u = 0.
303      flux_v = 0.
304      DO k = 1, klev
305      DO i = 1, klon
306         d_t(i,k) = 0.0
307         d_q(i,k) = 0.0
308c$$$         flux_t(i,k) = 0.0
309c$$$         flux_q(i,k) = 0.0
310         d_u(i,k) = 0.0
311         d_v(i,k) = 0.0
312c$$$         flux_u(i,k) = 0.0
313c$$$         flux_v(i,k) = 0.0
314         zcoefh(i,k) = 0.0
315      ENDDO
316      ENDDO
317cAA      IF (itr.GE.1) THEN
318cAA      DO it = 1, itr
319cAA      DO k = 1, klev
320cAA      DO i = 1, klon
321cAA         d_tr(i,k,it) = 0.0
322cAA      ENDDO
323cAA      ENDDO
324cAA      ENDDO
325cAA      ENDIF
326
327c
328c Boucler sur toutes les sous-fractions du sol:
329c
330C Initialisation des "pourcentages potentiels". On considere ici qu'on
331C peut avoir potentiellementdela glace sur tout le domaine oceanique
332C (a affiner)
333
334      pctsrf_pot = pctsrf
335      pctsrf_pot(:,is_oce) = 1. - zmasq(:)
336      pctsrf_pot(:,is_sic) = 1. - zmasq(:)
337
338      DO 99999 nsrf = 1, nbsrf
339       totalflu = radsol
340
341c chercher les indices:
342      DO j = 1, klon
343         ni(j) = 0
344      ENDDO
345      knon = 0
346      DO i = 1, klon
347
348C pour determiner le domaine a traiter on utilise les surfaces "potentielles"
349
350      IF (pctsrf_pot(i,nsrf).GT.epsfra) THEN
351         knon = knon + 1
352         ni(knon) = i
353      ENDIF
354      ENDDO
355c
356      write(*,*)'CLMAIN, nsrf, knon =',nsrf, knon
357c
358c variables pour avoir une sortie IOIPSL des INDEX
359c
360      IF (debugindex) THEN
361          tabindx(:)=0.
362c          tabindx(1:knon)=(/FLOAT(i),i=1:knon/)
363          DO i=1,knon
364            tabindx(1:knon)=FLOAT(i)
365          END DO
366          debugtab(:,:)=0.
367          ndexbg(:)=0
368          CALL gath2cpl(tabindx,debugtab,klon,knon,iim,jjm,ni)
369          CALL histwrite(nidbg,cl_surf(nsrf),itap,debugtab,iim*(jjm+1)
370     $        ,ndexbg)
371      ENDIF
372      IF (knon.EQ.0) GOTO 99999
373      DO j = 1, knon
374      i = ni(j)
375        ypct(j) = pctsrf(i,nsrf)
376        yts(j) = ts(i,nsrf)
377        ysnow(j) = snow(i,nsrf)
378        yqsol(j) = qsol(i,nsrf)
379        yalb(j) = albe(i,nsrf)
380        yalblw(j) = alblw(i,nsrf)
381        yrain_f(j) = rain_f(i)
382        ysnow_f(j) = snow_f(i)
383        yagesno(j) = agesno(i,nsrf)
384        yfder(j) = fder(i)
385        ytaux(j) = flux_u(i,1,nsrf)
386        ytauy(j) = flux_v(i,1,nsrf)
387c$$$        ysolsw(j) = solsw(i)
388       ysolsw(j) = (1 - albe(i,nsrf))
389     $      /(1 - pctsrf(i,is_ter) * albe(i,is_ter)
390     $      - pctsrf(i, is_lic) *albe(i,is_lic)
391     $      - pctsrf(i, is_oce) *albe(i,is_oce)
392     $      - pctsrf(i, is_sic) *albe(i,is_sic)
393     $      ) * solsw(i)
394        ysollw(j) = sollw(i)
395        ysollwdown(j) = sollwdown(i)
396        yrugos(j) = rugos(i,nsrf)
397        yrugoro(j) = rugoro(i)
398        yu1(j) = u1lay(i)
399        yv1(j) = v1lay(i)
400c$$$        yrads(j) = totalflu(i)
401        yrads(j) = (1 - albe(i,nsrf))
402     $      /(1 - pctsrf(i,is_ter) * albe(i,is_ter)
403     $      - pctsrf(i, is_lic) *albe(i,is_lic)
404     $      - pctsrf(i, is_oce) *albe(i,is_oce)
405     $      - pctsrf(i, is_sic) *albe(i,is_sic)
406     $      ) * solsw(i) + sollw(i)
407        ypaprs(j,klev+1) = paprs(i,klev+1)
408      END DO
409c$$$ PB ajour pour soil
410      DO k = 1, nsoilmx
411        DO j = 1, knon
412          i = ni(j)
413          ytsoil(j,k) = ftsoil(i,k,nsrf)
414        END DO 
415      END DO
416      DO k = 1, klev
417      DO j = 1, knon
418      i = ni(j)
419        ypaprs(j,k) = paprs(i,k)
420        ypplay(j,k) = pplay(i,k)
421        ydelp(j,k) = delp(i,k)
422        yu(j,k) = u(i,k)
423        yv(j,k) = v(i,k)
424        yt(j,k) = t(i,k)
425        yq(j,k) = q(i,k)
426      ENDDO
427      ENDDO
428c
429c
430c calculer Cdrag et les coefficients d'echange
431      CALL coefkz(nsrf, knon, ypaprs, ypplay,
432     .            yts, yrugos, yu, yv, yt, yq,
433     .            ycoefm, ycoefh)
434      CALL coefkz2(nsrf, knon, ypaprs, ypplay,yt,
435     .                  ycoefm0, ycoefh0)
436      write(*,*)'Cdrag maximal = ',maxval(ycoefh(:,1)),
437     .                               maxval(ycoefh0(:,1))
438      DO k = 1, klev
439      DO i = 1, knon
440         ycoefm(i,k) = MAX(ycoefm(i,k),ycoefm0(i,k))
441         ycoefh(i,k) = MAX(ycoefh(i,k),ycoefh0(i,k))
442      ENDDO
443      ENDDO
444
445      write(*,*)'Cdrag maximal = ',maxloc(ycoefh(:,1)),
446     .                             maxval(ycoefh(:,1))
447c
448c
449c calculer la diffusion des vitesses "u" et "v"
450      CALL clvent(knon,dtime,yu1,yv1,ycoefm,yt,yu,ypaprs,ypplay,ydelp,
451     s            y_d_u,y_flux_u)
452      CALL clvent(knon,dtime,yu1,yv1,ycoefm,yt,yv,ypaprs,ypplay,ydelp,
453     s            y_d_v,y_flux_v)
454
455c pour le couplage
456      ytaux = y_flux_u(:,1)
457      ytauy = y_flux_v(:,1)
458
459c calculer la diffusion de "q" et de "h"
460      CALL clqh(dtime, itap, date0,jour, debut,lafin,
461     e          rlon, rlat, cufi, cvfi,
462     e          knon, nsrf, ni, pctsrf,
463     e          soil_model, ytsoil,
464     e          ok_veget, ocean, npas, nexca,
465     e          rmu0, yrugos, yrugoro,
466     e          yu1, yv1, ycoefh,
467     e          yt,yq,yts,ypaprs,ypplay,
468     e          ydelp,yrads,yalb, yalblw, ysnow, yqsol,
469     e          yrain_f, ysnow_f, yfder, ytaux, ytauy,
470c$$$     e          ysollw, ysolsw,
471     e          ysollw, ysollwdown, ysolsw,yfluxlat,
472     s          pctsrf_new, yagesno,
473     s          y_d_t, y_d_q, y_d_ts, yz0_new,
474     s          y_flux_t, y_flux_q, y_dflux_t, y_dflux_q)
475c
476c calculer la longueur de rugosite sur ocean
477      yrugm=0.
478      IF (nsrf.EQ.is_oce) THEN
479      DO j = 1, knon
480         yrugm(j) = 0.018*ycoefm(j,1) * (yu1(j)**2+yv1(j)**2)/RG
481         yrugm(j) = MAX(1.5e-05,yrugm(j))
482      ENDDO
483      ENDIF
484      DO j = 1, knon
485         y_dflux_t(j) = y_dflux_t(j) * ypct(j)
486         y_dflux_q(j) = y_dflux_q(j) * ypct(j)
487         yu1(j) = yu1(j) *  ypct(j)
488         yv1(j) = yv1(j) *  ypct(j)
489      ENDDO
490c
491      DO k = 1, klev
492        DO j = 1, knon
493          i = ni(j)
494          ycoefh(j,k) = ycoefh(j,k) * ypct(j)
495          ycoefm(j,k) = ycoefm(j,k) * ypct(j)
496          y_d_t(j,k) = y_d_t(j,k) * ypct(j)
497          y_d_q(j,k) = y_d_q(j,k) * ypct(j)
498C§§§ PB
499          flux_t(i,k,nsrf) = y_flux_t(j,k)
500          flux_q(i,k,nsrf) = y_flux_q(j,k)
501          flux_u(i,k,nsrf) = y_flux_u(j,k)
502          flux_v(i,k,nsrf) = y_flux_v(j,k)
503c$$$ PB        y_flux_t(j,k) = y_flux_t(j,k) * ypct(j)
504c$$$ PB        y_flux_q(j,k) = y_flux_q(j,k) * ypct(j)
505          y_d_u(j,k) = y_d_u(j,k) * ypct(j)
506          y_d_v(j,k) = y_d_v(j,k) * ypct(j)
507c$$$ PB        y_flux_u(j,k) = y_flux_u(j,k) * ypct(j)
508c$$$ PB        y_flux_v(j,k) = y_flux_v(j,k) * ypct(j)
509        ENDDO
510      ENDDO
511
512
513      evap(:,nsrf) = - flux_q(:,1,nsrf)
514c
515      albe(:, nsrf) = 0.
516      alblw(:, nsrf) = 0.
517      snow(:, nsrf) = 0.
518      qsol(:, nsrf) = 0.
519      rugos(:, nsrf) = 0.
520      fluxlat(:,nsrf) = 0.
521      DO j = 1, knon
522         i = ni(j)
523         d_ts(i,nsrf) = y_d_ts(j)
524         albe(i,nsrf) = yalb(j)
525         alblw(i,nsrf) = yalblw(j)
526         snow(i,nsrf) = ysnow(j)
527         qsol(i,nsrf) = yqsol(j)
528         rugos(i,nsrf) = yz0_new(j)
529         fluxlat(i,nsrf) = yfluxlat(j)
530c$$$ pb         rugmer(i) = yrugm(j)
531         IF (nsrf .EQ. is_oce) then
532               rugmer(i) = yrugm(j)
533               rugos(i,nsrf) = yrugm(i)
534          endif
535         cdragh(i) = cdragh(i) + ycoefh(j,1)
536         cdragm(i) = cdragm(i) + ycoefm(j,1)
537         dflux_t(i) = dflux_t(i) + y_dflux_t(j)
538         dflux_q(i) = dflux_q(i) + y_dflux_q(j)
539         zu1(i) = zu1(i) + yu1(j)
540         zv1(i) = zv1(i) + yv1(j)
541      END DO
542c$$$ PB ajout pour soil
543      ftsoil(:,:,nsrf) = 0.
544      DO k = 1, nsoilmx
545        DO j = 1, knon
546          i = ni(j)
547          ftsoil(i, k, nsrf) = ytsoil(j,k)
548        END DO
549      END DO
550c
551#ifdef CRAY
552      DO k = 1, klev
553      DO j = 1, knon
554      i = ni(j)
555#else
556      DO j = 1, knon
557      i = ni(j)
558      DO k = 1, klev
559#endif
560         d_t(i,k) = d_t(i,k) + y_d_t(j,k)
561         d_q(i,k) = d_q(i,k) + y_d_q(j,k)
562c$$$ PB        flux_t(i,k) = flux_t(i,k) + y_flux_t(j,k)
563c$$$         flux_q(i,k) = flux_q(i,k) + y_flux_q(j,k)
564         d_u(i,k) = d_u(i,k) + y_d_u(j,k)
565         d_v(i,k) = d_v(i,k) + y_d_v(j,k)
566c$$$  PB       flux_u(i,k) = flux_u(i,k) + y_flux_u(j,k)
567c$$$         flux_v(i,k) = flux_v(i,k) + y_flux_v(j,k)
568         zcoefh(i,k) = zcoefh(i,k) + ycoefh(j,k)
569      ENDDO
570      ENDDO
571c
57299999 CONTINUE
573c
574C
575C On utilise les nouvelles surfaces
576C A rajouter: conservation de l'albedo
577C
578      rugos(:,is_oce) = rugmer
579      pctsrf = pctsrf_new
580
581      RETURN
582      END
583      SUBROUTINE clqh(dtime,itime, date0,jour,debut,lafin,
584     e                rlon, rlat, cufi, cvfi,
585     e                knon, nisurf, knindex, pctsrf,
586     $                soil_model,tsoil,
587     e                ok_veget, ocean, npas, nexca,
588     e                rmu0, rugos, rugoro,
589     e                u1lay,v1lay,coef,
590     e                t,q,ts,paprs,pplay,
591     e                delp,radsol,albedo,alblw,snow,qsol,
592     e                precip_rain, precip_snow, fder, taux, tauy,
593     $                sollw, sollwdown, swnet,fluxlat,
594     s                pctsrf_new, agesno,
595     s                d_t, d_q, d_ts, z0_new,
596     s                flux_t, flux_q,dflux_s,dflux_l)
597
598      USE interface_surf
599
600      IMPLICIT none
601c======================================================================
602c Auteur(s): Z.X. Li (LMD/CNRS) date: 19930818
603c Objet: diffusion verticale de "q" et de "h"
604c======================================================================
605#include "dimensions.h"
606#include "dimphy.h"
607#include "YOMCST.h"
608#include "YOETHF.h"
609#include "FCTTRE.h"
610#include "indicesol.h"
611#include "dimsoil.h"
612c Arguments:
613      INTEGER knon
614      REAL dtime              ! intervalle du temps (s)
615      real date0
616      REAL u1lay(klon)        ! vitesse u de la 1ere couche (m/s)
617      REAL v1lay(klon)        ! vitesse v de la 1ere couche (m/s)
618      REAL coef(klon,klev)    ! le coefficient d'echange (m**2/s)
619c                               multiplie par le cisaillement du
620c                               vent (dV/dz); la premiere valeur
621c                               indique la valeur de Cdrag (sans unite)
622      REAL t(klon,klev)       ! temperature (K)
623      REAL q(klon,klev)       ! humidite specifique (kg/kg)
624      REAL ts(klon)           ! temperature du sol (K)
625      REAL evap(klon)         ! evaporation au sol
626      REAL paprs(klon,klev+1) ! pression a inter-couche (Pa)
627      REAL pplay(klon,klev)   ! pression au milieu de couche (Pa)
628      REAL delp(klon,klev)    ! epaisseur de couche en pression (Pa)
629      REAL radsol(klon)       ! ray. net au sol (Solaire+IR) W/m2
630      REAL albedo(klon)       ! albedo de la surface
631      REAL alblw(klon)
632      REAL snow(klon)         ! hauteur de neige
633      REAL qsol(klon)         ! humidite de la surface
634      real precip_rain(klon), precip_snow(klon)
635      REAL agesno(klon)
636      REAL rugoro(klon)
637      integer jour            ! jour de l'annee en cours
638      real rmu0(klon)         ! cosinus de l'angle solaire zenithal
639      real rugos(klon)        ! rugosite
640      integer knindex(klon)
641      real pctsrf(klon,nbsrf)
642      real rlon(klon), rlat(klon), cufi(klon), cvfi(klon)
643      logical ok_veget
644      character*6 ocean
645      integer npas, nexca
646
647c
648      REAL d_t(klon,klev)     ! incrementation de "t"
649      REAL d_q(klon,klev)     ! incrementation de "q"
650      REAL d_ts(klon)         ! incrementation de "ts"
651      REAL flux_t(klon,klev)  ! (diagnostic) flux de la chaleur
652c                               sensible, flux de Cp*T, positif vers
653c                               le bas: j/(m**2 s) c.a.d.: W/m2
654      REAL flux_q(klon,klev)  ! flux de la vapeur d'eau:kg/(m**2 s)
655      REAL dflux_s(klon) ! derivee du flux sensible dF/dTs
656      REAL dflux_l(klon) ! derivee du flux latent dF/dTs
657c======================================================================
658      REAL t_grnd  ! temperature de rappel pour glace de mer
659      PARAMETER (t_grnd=271.35)
660      REAL t_coup
661      PARAMETER(t_coup=273.15)
662c======================================================================
663      INTEGER i, k
664      REAL zx_cq(klon,klev)
665      REAL zx_dq(klon,klev)
666      REAL zx_ch(klon,klev)
667      REAL zx_dh(klon,klev)
668      REAL zx_buf1(klon)
669      REAL zx_buf2(klon)
670      REAL zx_coef(klon,klev)
671      REAL local_h(klon,klev) ! enthalpie potentielle
672      REAL local_q(klon,klev)
673      REAL local_ts(klon)
674      REAL psref(klon) ! pression de reference pour temperature potent.
675      REAL zx_pkh(klon,klev), zx_pkf(klon,klev)
676c======================================================================
677c contre-gradient pour la vapeur d'eau: (kg/kg)/metre
678      REAL gamq(klon,2:klev)
679c contre-gradient pour la chaleur sensible: Kelvin/metre
680      REAL gamt(klon,2:klev)
681      REAL z_gamaq(klon,2:klev), z_gamah(klon,2:klev)
682      REAL zdelz
683c======================================================================
684      logical contreg
685      parameter (contreg=.true.)
686c======================================================================
687c Rajout pour l'interface
688      integer itime
689      integer nisurf
690      logical debut, lafin
691      real zlev1(klon)
692      real fder(klon), taux(klon), tauy(klon)
693      real temp_air(klon), spechum(klon)
694      real epot_air(klon), ccanopy(klon)
695      real tq_cdrag(klon), petAcoef(klon), peqAcoef(klon)
696      real petBcoef(klon), peqBcoef(klon)
697      real sollw(klon), sollwdown(klon), swnet(klon), swdown(klon)
698      real p1lay(klon)
699c$$$C PB ajout pour soil
700      LOGICAL soil_model
701      REAL tsoil(klon, nsoilmx)
702
703! Parametres de sortie
704      real fluxsens(klon), fluxlat(klon)
705      real tsol_rad(klon), tsurf_new(klon), alb_new(klon)
706      real emis_new(klon), z0_new(klon)
707      real pctsrf_new(klon,nbsrf)
708     
709c
710
711      if (.not. contreg) then
712        do k = 2, klev
713          do i = 1, knon
714            gamq(i,k) = 0.0
715            gamt(i,k) = 0.0
716          enddo
717        enddo
718      else
719        do k = 3, klev
720          do i = 1, knon
721            gamq(i,k)= 0.0
722            gamt(i,k)=  -1.0e-03
723          enddo
724        enddo
725        do i = 1, knon
726          gamq(i,2) = 0.0
727          gamt(i,2) = -2.5e-03
728        enddo
729      endif
730
731      DO i = 1, knon
732         psref(i) = paprs(i,1) !pression de reference est celle au sol
733         local_ts(i) = ts(i)
734      ENDDO
735      DO k = 1, klev
736      DO i = 1, knon
737         zx_pkh(i,k) = (psref(i)/paprs(i,k))**RKAPPA
738         zx_pkf(i,k) = (psref(i)/pplay(i,k))**RKAPPA
739         local_h(i,k) = RCPD * t(i,k) * zx_pkf(i,k)
740         local_q(i,k) = q(i,k)
741      ENDDO
742      ENDDO
743c
744c Convertir les coefficients en variables convenables au calcul:
745c
746c
747      DO k = 2, klev
748      DO i = 1, knon
749         zx_coef(i,k) = coef(i,k)*RG/(pplay(i,k-1)-pplay(i,k))
750     .                  *(paprs(i,k)*2/(t(i,k)+t(i,k-1))/RD)**2
751         zx_coef(i,k) = zx_coef(i,k) * dtime*RG
752      ENDDO
753      ENDDO
754c
755c Preparer les flux lies aux contre-gardients
756c
757      DO k = 2, klev
758      DO i = 1, knon
759         zdelz = RD * (t(i,k-1)+t(i,k))/2.0 / RG /paprs(i,k)
760     .              *(pplay(i,k-1)-pplay(i,k))
761         z_gamaq(i,k) = gamq(i,k) * zdelz
762         z_gamah(i,k) = gamt(i,k) * zdelz *RCPD * zx_pkh(i,k)
763      ENDDO
764      ENDDO
765      DO i = 1, knon
766         zx_buf1(i) = zx_coef(i,klev) + delp(i,klev)
767         zx_cq(i,klev) = (local_q(i,klev)*delp(i,klev)
768     .                   -zx_coef(i,klev)*z_gamaq(i,klev))/zx_buf1(i)
769         zx_dq(i,klev) = zx_coef(i,klev) / zx_buf1(i)
770c
771         zx_buf2(i) = delp(i,klev) + zx_coef(i,klev)
772         zx_ch(i,klev) = (local_h(i,klev)*delp(i,klev)
773     .                   -zx_coef(i,klev)*z_gamah(i,klev))/zx_buf2(i)
774         zx_dh(i,klev) = zx_coef(i,klev) / zx_buf2(i)
775      ENDDO
776      DO k = klev-1, 2 , -1
777      DO i = 1, knon
778         zx_buf1(i) = delp(i,k)+zx_coef(i,k)
779     .               +zx_coef(i,k+1)*(1.-zx_dq(i,k+1))
780         zx_cq(i,k) = (local_q(i,k)*delp(i,k)
781     .                 +zx_coef(i,k+1)*zx_cq(i,k+1)
782     .                 +zx_coef(i,k+1)*z_gamaq(i,k+1)
783     .                 -zx_coef(i,k)*z_gamaq(i,k))/zx_buf1(i)
784         zx_dq(i,k) = zx_coef(i,k) / zx_buf1(i)
785c
786         zx_buf2(i) = delp(i,k)+zx_coef(i,k)
787     .               +zx_coef(i,k+1)*(1.-zx_dh(i,k+1))
788         zx_ch(i,k) = (local_h(i,k)*delp(i,k)
789     .                 +zx_coef(i,k+1)*zx_ch(i,k+1)
790     .                 +zx_coef(i,k+1)*z_gamah(i,k+1)
791     .                 -zx_coef(i,k)*z_gamah(i,k))/zx_buf2(i)
792         zx_dh(i,k) = zx_coef(i,k) / zx_buf2(i)
793      ENDDO
794      ENDDO
795C
796C nouvelle formulation JL Dufresne
797C
798C q1 = zx_cq(i,1) + zx_dq(i,1) * Flux_Q(i,1) * dt
799C h1 = zx_ch(i,1) + zx_dh(i,1) * Flux_H(i,1) * dt
800C
801      DO i = 1, knon
802         zx_buf1(i) = delp(i,1) + zx_coef(i,2)*(1.-zx_dq(i,2))
803         zx_cq(i,1) = (local_q(i,1)*delp(i,1)
804     .                 +zx_coef(i,2)*(z_gamaq(i,2)+zx_cq(i,2)))
805     .                /zx_buf1(i)
806         zx_dq(i,1) = -1. * RG / zx_buf1(i)
807c
808         zx_buf2(i) = delp(i,1) + zx_coef(i,2)*(1.-zx_dh(i,2))
809         zx_ch(i,1) = (local_h(i,1)*delp(i,1)
810     .                 +zx_coef(i,2)*(z_gamah(i,2)+zx_ch(i,2)))
811     .                /zx_buf2(i)
812         zx_dh(i,1) = -1. * RG / zx_buf2(i)
813      ENDDO
814
815C Appel a interfsurf (appel generique) routine d'interface avec la surface
816
817c initialisation
818       petAcoef =0.
819        peqAcoef = 0.
820        petBcoef =0.
821        peqBcoef = 0.
822        p1lay =0.
823       
824c      do i = 1, knon
825        petAcoef(1:knon) = zx_ch(1:knon,1)
826        peqAcoef(1:knon) = zx_cq(1:knon,1)
827        petBcoef(1:knon) =  zx_dh(1:knon,1)
828        peqBcoef(1:knon) = zx_dq(1:knon,1)
829        tq_cdrag(1:knon) =coef(1:knon,1)
830        temp_air(1:knon) =t(1:knon,1)
831        epot_air(1:knon) =local_h(1:knon,1)
832        spechum(1:knon)=q(1:knon,1)
833        p1lay(1:knon) = pplay(1:knon,1)
834        zlev1(1:knon) = delp(1:knon,1)
835c        swnet = swdown * (1. - albedo)
836        swdown(1:knon) = swnet(1:knon)
837c      enddo
838c En attendant mieux
839      ccanopy = 365.
840
841      CALL interfsurf(itime, dtime, date0, jour, rmu0,
842     e klon, iim, jjm, nisurf, knon, knindex, pctsrf,
843     e rlon, rlat, cufi, cvfi,
844     e debut, lafin, ok_veget, soil_model, nsoilmx,tsoil,
845     e zlev1,  u1lay, v1lay, temp_air, spechum, epot_air, ccanopy,
846     e tq_cdrag, petAcoef, peqAcoef, petBcoef, peqBcoef,
847     e precip_rain, precip_snow, sollw, sollwdown, swnet, swdown,
848     e fder, taux, tauy, rugos, rugoro,
849     e albedo, snow, qsol,
850     e ts, p1lay, psref, radsol,
851     e ocean, npas, nexca, zmasq,
852     s evap, fluxsens, fluxlat, dflux_l, dflux_s,             
853     s tsol_rad, tsurf_new, alb_new, alblw, emis_new, z0_new,
854     s pctsrf_new, agesno)
855
856
857      do i = 1, knon
858        flux_t(i,1) = fluxsens(i)
859        flux_q(i,1) = - evap(i)
860        d_ts(i) = tsurf_new(i) - ts(i)
861        albedo(i) = alb_new(i)
862      enddo
863
864c==== une fois on a zx_h_ts, on peut faire l'iteration ========
865      DO i = 1, knon
866         local_h(i,1) = zx_ch(i,1) + zx_dh(i,1)*flux_t(i,1)*dtime
867         local_q(i,1) = zx_cq(i,1) + zx_dq(i,1)*flux_q(i,1)*dtime
868      ENDDO
869      DO k = 2, klev
870      DO i = 1, knon
871        local_q(i,k) = zx_cq(i,k) + zx_dq(i,k)*local_q(i,k-1)
872        local_h(i,k) = zx_ch(i,k) + zx_dh(i,k)*local_h(i,k-1)
873      ENDDO
874      ENDDO
875c======================================================================
876c== flux_q est le flux de vapeur d'eau: kg/(m**2 s)  positive vers bas
877c== flux_t est le flux de cpt (energie sensible): j/(m**2 s)
878      DO k = 2, klev
879      DO i = 1, knon
880        flux_q(i,k) = (zx_coef(i,k)/RG/dtime)
881     .                * (local_q(i,k)-local_q(i,k-1)+z_gamaq(i,k))
882        flux_t(i,k) = (zx_coef(i,k)/RG/dtime)
883     .                * (local_h(i,k)-local_h(i,k-1)+z_gamah(i,k))
884     .                / zx_pkh(i,k)
885      ENDDO
886      ENDDO
887c======================================================================
888C Calcul tendances
889      DO k = 1, klev
890      DO i = 1, knon
891         d_t(i,k) = local_h(i,k)/zx_pkf(i,k)/RCPD - t(i,k)
892         d_q(i,k) = local_q(i,k) - q(i,k)
893      ENDDO
894      ENDDO
895c
896
897      RETURN
898      END
899      SUBROUTINE clvent(knon,dtime, u1lay,v1lay,coef,t,ven,
900     e                  paprs,pplay,delp,
901     s                  d_ven,flux_v)
902      IMPLICIT none
903c======================================================================
904c Auteur(s): Z.X. Li (LMD/CNRS) date: 19930818
905c Objet: diffusion vertical de la vitesse "ven"
906c======================================================================
907c Arguments:
908c dtime----input-R- intervalle du temps (en second)
909c u1lay----input-R- vent u de la premiere couche (m/s)
910c v1lay----input-R- vent v de la premiere couche (m/s)
911c coef-----input-R- le coefficient d'echange (m**2/s) multiplie par
912c                   le cisaillement du vent (dV/dz); la premiere
913c                   valeur indique la valeur de Cdrag (sans unite)
914c t--------input-R- temperature (K)
915c ven------input-R- vitesse horizontale (m/s)
916c paprs----input-R- pression a inter-couche (Pa)
917c pplay----input-R- pression au milieu de couche (Pa)
918c delp-----input-R- epaisseur de couche (Pa)
919c
920c
921c d_ven----output-R- le changement de "ven"
922c flux_v---output-R- (diagnostic) flux du vent: (kg m/s)/(m**2 s)
923c======================================================================
924#include "dimensions.h"
925#include "dimphy.h"
926      INTEGER knon
927      REAL dtime
928      REAL u1lay(klon), v1lay(klon)
929      REAL coef(klon,klev)
930      REAL t(klon,klev), ven(klon,klev)
931      REAL paprs(klon,klev+1), pplay(klon,klev), delp(klon,klev)
932      REAL d_ven(klon,klev)
933      REAL flux_v(klon,klev)
934c======================================================================
935#include "YOMCST.h"
936c======================================================================
937      INTEGER i, k
938      REAL zx_cv(klon,2:klev)
939      REAL zx_dv(klon,2:klev)
940      REAL zx_buf(klon)
941      REAL zx_coef(klon,klev)
942      REAL local_ven(klon,klev)
943      REAL zx_alf1(klon), zx_alf2(klon)
944c======================================================================
945      DO k = 1, klev
946      DO i = 1, knon
947         local_ven(i,k) = ven(i,k)
948      ENDDO
949      ENDDO
950c======================================================================
951      DO i = 1, knon
952ccc         zx_alf1(i) = (paprs(i,1)-pplay(i,2))/(pplay(i,1)-pplay(i,2))
953         zx_alf1(i) = 1.0
954         zx_alf2(i) = 1.0 - zx_alf1(i)
955         zx_coef(i,1) = coef(i,1)
956     .                 * (1.0+SQRT(u1lay(i)**2+v1lay(i)**2))
957     .                 * pplay(i,1)/(RD*t(i,1))
958         zx_coef(i,1) = zx_coef(i,1) * dtime*RG
959      ENDDO
960c======================================================================
961      DO k = 2, klev
962      DO i = 1, knon
963         zx_coef(i,k) = coef(i,k)*RG/(pplay(i,k-1)-pplay(i,k))
964     .                  *(paprs(i,k)*2/(t(i,k)+t(i,k-1))/RD)**2
965         zx_coef(i,k) = zx_coef(i,k) * dtime*RG
966      ENDDO
967      ENDDO
968c======================================================================
969      DO i = 1, knon
970         zx_buf(i) = delp(i,1) + zx_coef(i,1)*zx_alf1(i)+zx_coef(i,2)
971         zx_cv(i,2) = local_ven(i,1)*delp(i,1) / zx_buf(i)
972         zx_dv(i,2) = (zx_coef(i,2)-zx_alf2(i)*zx_coef(i,1))
973     .                /zx_buf(i)
974      ENDDO
975      DO k = 3, klev
976      DO i = 1, knon
977         zx_buf(i) = delp(i,k-1) + zx_coef(i,k)
978     .                         + zx_coef(i,k-1)*(1.-zx_dv(i,k-1))
979         zx_cv(i,k) = (local_ven(i,k-1)*delp(i,k-1)
980     .                  +zx_coef(i,k-1)*zx_cv(i,k-1) )/zx_buf(i)
981         zx_dv(i,k) = zx_coef(i,k)/zx_buf(i)
982      ENDDO
983      ENDDO
984      DO i = 1, knon
985         local_ven(i,klev) = ( local_ven(i,klev)*delp(i,klev)
986     .                        +zx_coef(i,klev)*zx_cv(i,klev) )
987     .                   / ( delp(i,klev) + zx_coef(i,klev)
988     .                       -zx_coef(i,klev)*zx_dv(i,klev) )
989      ENDDO
990      DO k = klev-1, 1, -1
991      DO i = 1, knon
992         local_ven(i,k) = zx_cv(i,k+1) + zx_dv(i,k+1)*local_ven(i,k+1)
993      ENDDO
994      ENDDO
995c======================================================================
996c== flux_v est le flux de moment angulaire (positif vers bas)
997c== dont l'unite est: (kg m/s)/(m**2 s)
998      DO i = 1, knon
999         flux_v(i,1) = zx_coef(i,1)/(RG*dtime)
1000     .                 *(local_ven(i,1)*zx_alf1(i)
1001     .                  +local_ven(i,2)*zx_alf2(i))
1002      ENDDO
1003      DO k = 2, klev
1004      DO i = 1, knon
1005         flux_v(i,k) = zx_coef(i,k)/(RG*dtime)
1006     .               * (local_ven(i,k)-local_ven(i,k-1))
1007      ENDDO
1008      ENDDO
1009c
1010      DO k = 1, klev
1011      DO i = 1, knon
1012         d_ven(i,k) = local_ven(i,k) - ven(i,k)
1013      ENDDO
1014      ENDDO
1015c
1016      RETURN
1017      END
1018      SUBROUTINE coefkz(nsrf, knon, paprs, pplay,
1019     .                  ts, rugos,
1020     .                  u,v,t,q,
1021     .                  pcfm, pcfh)
1022      IMPLICIT none
1023c======================================================================
1024c Auteur(s) F. Hourdin, M. Forichon, Z.X. Li (LMD/CNRS) date: 19930922
1025c           (une version strictement identique a l'ancien modele)
1026c Objet: calculer le coefficient du frottement du sol (Cdrag) et les
1027c        coefficients d'echange turbulent dans l'atmosphere.
1028c Arguments:
1029c nsrf-----input-I- indicateur de la nature du sol
1030c knon-----input-I- nombre de points a traiter
1031c paprs----input-R- pression a chaque intercouche (en Pa)
1032c pplay----input-R- pression au milieu de chaque couche (en Pa)
1033c ts-------input-R- temperature du sol (en Kelvin)
1034c rugos----input-R- longeur de rugosite (en m)
1035c u--------input-R- vitesse u
1036c v--------input-R- vitesse v
1037c t--------input-R- temperature (K)
1038c q--------input-R- vapeur d'eau (kg/kg)
1039c
1040c itop-----output-I- numero de couche du sommet de la couche limite
1041c pcfm-----output-R- coefficients a calculer (vitesse)
1042c pcfh-----output-R- coefficients a calculer (chaleur et humidite)
1043c======================================================================
1044#include "dimensions.h"
1045#include "dimphy.h"
1046#include "YOMCST.h"
1047#include "indicesol.h"
1048c
1049c Arguments:
1050c
1051      INTEGER knon, nsrf
1052      REAL ts(klon)
1053      REAL paprs(klon,klev+1), pplay(klon,klev)
1054      REAL u(klon,klev), v(klon,klev), t(klon,klev), q(klon,klev)
1055      REAL rugos(klon)
1056c
1057      REAL pcfm(klon,klev), pcfh(klon,klev)
1058      INTEGER itop(klon)
1059c
1060c Quelques constantes et options:
1061c
1062      REAL cepdu2, ckap, cb, cc, cd, clam
1063      PARAMETER (cepdu2 =(0.1)**2)
1064      PARAMETER (ckap=0.35)
1065      PARAMETER (cb=5.0)
1066      PARAMETER (cc=5.0)
1067      PARAMETER (cd=5.0)
1068      PARAMETER (clam=160.0)
1069      REAL ratqs ! largeur de distribution de vapeur d'eau
1070      PARAMETER (ratqs=0.05)
1071      LOGICAL richum ! utilise le nombre de Richardson humide
1072      PARAMETER (richum=.TRUE.)
1073      REAL ric ! nombre de Richardson critique
1074      PARAMETER(ric=0.4)
1075      REAL prandtl
1076      PARAMETER (prandtl=0.4)
1077      REAL kstable ! diffusion minimale (situation stable)
1078      PARAMETER (kstable=1.0e-10)
1079      REAL mixlen ! constante controlant longueur de melange
1080      PARAMETER (mixlen=35.0)
1081      INTEGER isommet ! le sommet de la couche limite
1082      PARAMETER (isommet=klev)
1083      LOGICAL tvirtu ! calculer Ri d'une maniere plus performante
1084      PARAMETER (tvirtu=.TRUE.)
1085      LOGICAL opt_ec ! formule du Centre Europeen dans l'atmosphere
1086      PARAMETER (opt_ec=.FALSE.)
1087      LOGICAL contreg ! utiliser le contre-gradient dans Ri
1088      PARAMETER (contreg=.TRUE.)
1089c
1090c Variables locales:
1091c
1092      INTEGER i, k
1093      REAL zgeop(klon,klev)
1094      REAL zmgeom(klon)
1095      REAL zri(klon)
1096      REAL zl2(klon)
1097      REAL zcfm1(klon), zcfm2(klon)
1098      REAL zcfh1(klon), zcfh2(klon)
1099      REAL zdphi, zdu2, ztvd, ztvu, ztsolv, zcdn
1100      REAL zscf, zucf, zcr
1101      REAL zt, zq, zdelta, zcvm5, zcor, zqs, zfr, zdqs
1102      REAL z2geomf, zalh2, zalm2, zscfh, zscfm
1103      REAL t_coup
1104      PARAMETER (t_coup=273.15)
1105c
1106c contre-gradient pour la chaleur sensible: Kelvin/metre
1107      REAL gamt(2:klev)
1108c essai qsurf
1109      real qsurf(klon)
1110      real friv, frih
1111c
1112      LOGICAL appel1er
1113      SAVE appel1er
1114c
1115c Fonctions thermodynamiques et fonctions d'instabilite
1116      REAL fsta, fins, x
1117      LOGICAL zxli ! utiliser un jeu de fonctions simples
1118      PARAMETER (zxli=.FALSE.)
1119c
1120#include "YOETHF.h"
1121#include "FCTTRE.h"
1122      fsta(x) = 1.0 / (1.0+10.0*x*(1+8.0*x))
1123      fins(x) = SQRT(1.0-18.0*x)
1124c
1125      DATA appel1er /.TRUE./
1126c
1127      IF (appel1er) THEN
1128         PRINT*, 'coefkz, opt_ec:', opt_ec
1129         PRINT*, 'coefkz, richum:', richum
1130         IF (richum) PRINT*, 'coefkz, ratqs:', ratqs
1131         PRINT*, 'coefkz, isommet:', isommet
1132         PRINT*, 'coefkz, tvirtu:', tvirtu
1133         appel1er = .FALSE.
1134      ENDIF
1135c
1136c Initialiser les sorties
1137c
1138      DO k = 1, klev
1139      DO i = 1, knon
1140         pcfm(i,k) = 0.0
1141         pcfh(i,k) = 0.0
1142      ENDDO
1143      ENDDO
1144      DO i = 1, knon
1145         itop(i) = 0
1146      ENDDO
1147
1148      do i = 1, knon
1149        qsurf(i) = qsatl(ts(i))/paprs(i,1)
1150      enddo
1151
1152c
1153c Prescrire la valeur de contre-gradient
1154c
1155      IF (.NOT.contreg) THEN
1156         DO k = 2, klev
1157            gamt(k) = 0.0
1158         ENDDO
1159      ELSE
1160         DO k = 3, klev
1161            gamt(k) = -1.0E-03
1162         ENDDO
1163         gamt(2) = -2.5E-03
1164      ENDIF
1165c
1166c Calculer les geopotentiels de chaque couche
1167c
1168      DO i = 1, knon
1169         zgeop(i,1) = RD * t(i,1) / (0.5*(paprs(i,1)+pplay(i,1)))
1170     .                   * (paprs(i,1)-pplay(i,1))
1171      ENDDO
1172      DO k = 2, klev
1173      DO i = 1, knon
1174         zgeop(i,k) = zgeop(i,k-1)
1175     .              + RD * 0.5*(t(i,k-1)+t(i,k)) / paprs(i,k)
1176     .                   * (pplay(i,k-1)-pplay(i,k))
1177      ENDDO
1178      ENDDO
1179c
1180c Calculer le frottement au sol (Cdrag)
1181c
1182      DO i = 1, knon
1183         zdu2=max(cepdu2,u(i,1)**2+v(i,1)**2)
1184         zdphi=zgeop(i,1)
1185c         ztsolv = ts(i) * (1.0+RETV*q(i,1)) ! qsol approx = q(i,1)
1186         ztsolv = ts(i) * (1.0+RETV*qsurf(i))
1187         ztvd=(t(i,1)+zdphi/RCPD/(1.+RVTMP2*q(i,1)))
1188     .       *(1.+RETV*q(i,1))
1189         zri(i)=zgeop(i,1)*(ztvd-ztsolv)/(zdu2*ztvd)
1190         zcdn = (ckap/log(1.+zgeop(i,1)/(RG*rugos(i))))**2
1191         IF (zri(i) .ge. 0.) THEN ! situation stable
1192           IF (.NOT.zxli) THEN
1193           zscf=SQRT(1.+cd*ABS(zri(i)))
1194           FRIV = AMAX1(1. / (1.+2.*CB*zri(i)/ZSCF), 0.1)
1195!           zcfm1(i) = zcdn/(1.+2.0*cb*zri(i)/ zscf)
1196           zcfm1(i) = zcdn * FRIV
1197           FRIH = AMAX1(1./ (1.+3.*CB*zri(i)*ZSCF), 0.1 )
1198!           zcfh1(i) = zcdn/(1.+3.0*cb*zri(i)*zscf)
1199           zcfh1(i) = zcdn * FRIH
1200           pcfm(i,1) = zcfm1(i)
1201           pcfh(i,1) = zcfh1(i)
1202           ELSE
1203           pcfm(i,1) = zcdn* fsta(zri(i))
1204           pcfh(i,1) = zcdn* fsta(zri(i))
1205           ENDIF
1206         ELSE ! situation instable
1207           IF (.NOT.zxli) THEN
1208           zucf=1./(1.+3.0*cb*cc*zcdn*SQRT(ABS(zri(i))
1209     .              *(1.0+zgeop(i,1)/(RG*rugos(i)))))
1210           zcfm2(i) = zcdn*amax1((1.-2.0*cb*zri(i)*zucf),0.1)
1211           zcfh2(i) = zcdn*amax1((1.-3.0*cb*zri(i)*zucf),0.1)
1212           pcfm(i,1) = zcfm2(i)
1213           pcfh(i,1) = zcfh2(i)
1214           ELSE
1215           pcfm(i,1) = zcdn* fins(zri(i))
1216           pcfh(i,1) = zcdn* fins(zri(i))
1217           ENDIF
1218           zcr = (0.0016/(zcdn*SQRT(zdu2)))*ABS(ztvd-ztsolv)**(1./3.)
1219           IF(nsrf.EQ.is_oce)pcfh(i,1)=zcdn*(1.0+zcr**1.25)**(1./1.25)
1220         ENDIF
1221      ENDDO
1222
1223c
1224c Calculer les coefficients turbulents dans l'atmosphere
1225c
1226      DO i = 1, knon
1227         itop(i) = isommet
1228      ENDDO
1229
1230      DO k = 2, isommet
1231      DO i = 1, knon
1232            zdu2=MAX(cepdu2,(u(i,k)-u(i,k-1))**2
1233     .                     +(v(i,k)-v(i,k-1))**2)
1234            zmgeom(i)=zgeop(i,k)-zgeop(i,k-1)
1235            zdphi =zmgeom(i) / 2.0
1236            zt = (t(i,k)+t(i,k-1)) * 0.5
1237            zq = (q(i,k)+q(i,k-1)) * 0.5
1238c
1239c           calculer Qs et dQs/dT:
1240c
1241            IF (thermcep) THEN
1242              zdelta = MAX(0.,SIGN(1.,RTT-zt))
1243              zcvm5 = R5LES*RLVTT/RCPD/(1.0+RVTMP2*zq)*(1.-zdelta)
1244     .            + R5IES*RLSTT/RCPD/(1.0+RVTMP2*zq)*zdelta
1245              zqs = R2ES * FOEEW(zt,zdelta) / pplay(i,k)
1246              zqs = MIN(0.5,zqs)
1247              zcor = 1./(1.-RETV*zqs)
1248              zqs = zqs*zcor
1249              zdqs = FOEDE(zt,zdelta,zcvm5,zqs,zcor)
1250            ELSE
1251              IF (zt .LT. t_coup) THEN
1252                 zqs = qsats(zt) / pplay(i,k)
1253                 zdqs = dqsats(zt,zqs)
1254              ELSE
1255                 zqs = qsatl(zt) / pplay(i,k)
1256                 zdqs = dqsatl(zt,zqs)
1257              ENDIF
1258            ENDIF
1259c
1260c           calculer la fraction nuageuse (processus humide):
1261c
1262            zfr = (zq+ratqs*zq-zqs) / (2.0*ratqs*zq)
1263            zfr = MAX(0.0,MIN(1.0,zfr))
1264            IF (.NOT.richum) zfr = 0.0
1265c
1266c           calculer le nombre de Richardson:
1267c
1268            IF (tvirtu) THEN
1269            ztvd =( t(i,k)
1270     .             + zdphi/RCPD/(1.+RVTMP2*zq)
1271     .              *( (1.-zfr) + zfr*(1.+RLVTT*zqs/RD/zt)/(1.+zdqs) )
1272     .            )*(1.+RETV*q(i,k))
1273            ztvu =( t(i,k-1)
1274     .             - zdphi/RCPD/(1.+RVTMP2*zq)
1275     .              *( (1.-zfr) + zfr*(1.+RLVTT*zqs/RD/zt)/(1.+zdqs) )
1276     .            )*(1.+RETV*q(i,k-1))
1277            zri(i) =zmgeom(i)*(ztvd-ztvu)/(zdu2*0.5*(ztvd+ztvu))
1278            zri(i) = zri(i)
1279     .             + zmgeom(i)*zmgeom(i)/RG*gamt(k)
1280     .               *(paprs(i,k)/101325.0)**RKAPPA
1281     .               /(zdu2*0.5*(ztvd+ztvu))
1282c
1283            ELSE ! calcul de Ridchardson compatible LMD5
1284c
1285            zri(i) =(RCPD*(t(i,k)-t(i,k-1))
1286     .              -RD*0.5*(t(i,k)+t(i,k-1))/paprs(i,k)
1287     .               *(pplay(i,k)-pplay(i,k-1))
1288     .              )*zmgeom(i)/(zdu2*0.5*RCPD*(t(i,k-1)+t(i,k)))
1289            zri(i) = zri(i) +
1290     .             zmgeom(i)*zmgeom(i)*gamt(k)/RG
1291cSB     .             /(paprs(i,k)/101325.0)**RKAPPA
1292     .             *(paprs(i,k)/101325.0)**RKAPPA
1293     .             /(zdu2*0.5*(t(i,k-1)+t(i,k)))
1294            ENDIF
1295c
1296c           finalement, les coefficients d'echange sont obtenus:
1297c
1298            zcdn=SQRT(zdu2) / zmgeom(i) * RG
1299c
1300          IF (opt_ec) THEN
1301            z2geomf=zgeop(i,k-1)+zgeop(i,k)
1302            zalm2=(0.5*ckap/RG*z2geomf
1303     .             /(1.+0.5*ckap/rg/clam*z2geomf))**2
1304            zalh2=(0.5*ckap/rg*z2geomf
1305     .             /(1.+0.5*ckap/RG/(clam*SQRT(1.5*cd))*z2geomf))**2
1306            IF (zri(i).LT.0.0) THEN  ! situation instable
1307               zscf = ((zgeop(i,k)/zgeop(i,k-1))**(1./3.)-1.)**3
1308     .                / (zmgeom(i)/RG)**3 / (zgeop(i,k-1)/RG)
1309               zscf = SQRT(-zri(i)*zscf)
1310               zscfm = 1.0 / (1.0+3.0*cb*cc*zalm2*zscf)
1311               zscfh = 1.0 / (1.0+3.0*cb*cc*zalh2*zscf)
1312               pcfm(i,k)=zcdn*zalm2*(1.-2.0*cb*zri(i)*zscfm)
1313               pcfh(i,k)=zcdn*zalh2*(1.-3.0*cb*zri(i)*zscfh)
1314            ELSE ! situation stable
1315               zscf=SQRT(1.+cd*zri(i))
1316               pcfm(i,k)=zcdn*zalm2/(1.+2.0*cb*zri(i)/zscf)
1317               pcfh(i,k)=zcdn*zalh2/(1.+3.0*cb*zri(i)*zscf)
1318            ENDIF
1319          ELSE
1320            zl2(i)=(mixlen*MAX(0.0,(paprs(i,k)-paprs(i,itop(i)+1))
1321     .                          /(paprs(i,2)-paprs(i,itop(i)+1)) ))**2
1322            pcfm(i,k)=sqrt(max(zcdn*zcdn*(ric-zri(i))/ric, kstable))
1323            pcfm(i,k)= zl2(i)* pcfm(i,k)
1324            pcfh(i,k) = pcfm(i,k) /prandtl ! h et m different
1325          ENDIF
1326      ENDDO
1327      ENDDO
1328c
1329c Au-dela du sommet, pas de diffusion turbulente:
1330c
1331      DO i = 1, knon
1332         IF (itop(i)+1 .LE. klev) THEN
1333            DO k = itop(i)+1, klev
1334               pcfh(i,k) = 0.0
1335               pcfm(i,k) = 0.0
1336            ENDDO
1337         ENDIF
1338      ENDDO
1339c
1340      RETURN
1341      END
1342      SUBROUTINE coefkz2(nsrf, knon, paprs, pplay,t,
1343     .                  pcfm, pcfh)
1344      IMPLICIT none
1345c======================================================================
1346c J'introduit un peu de diffusion sauf dans les endroits
1347c ou une forte inversion est presente
1348c On peut dire qu'il represente la convection peu profonde
1349c
1350c Arguments:
1351c nsrf-----input-I- indicateur de la nature du sol
1352c knon-----input-I- nombre de points a traiter
1353c paprs----input-R- pression a chaque intercouche (en Pa)
1354c pplay----input-R- pression au milieu de chaque couche (en Pa)
1355c t--------input-R- temperature (K)
1356c
1357c pcfm-----output-R- coefficients a calculer (vitesse)
1358c pcfh-----output-R- coefficients a calculer (chaleur et humidite)
1359c======================================================================
1360#include "dimensions.h"
1361#include "dimphy.h"
1362#include "YOMCST.h"
1363#include "indicesol.h"
1364c
1365c Arguments:
1366c
1367      INTEGER knon, nsrf
1368      REAL paprs(klon,klev+1), pplay(klon,klev)
1369      REAL t(klon,klev)
1370c
1371      REAL pcfm(klon,klev), pcfh(klon,klev)
1372c
1373c Quelques constantes et options:
1374c
1375      REAL prandtl
1376      PARAMETER (prandtl=0.4)
1377      REAL kstable
1378      PARAMETER (kstable=0.002)
1379ccc      PARAMETER (kstable=0.001)
1380      REAL mixlen ! constante controlant longueur de melange
1381      PARAMETER (mixlen=35.0)
1382      REAL seuil ! au-dela l'inversion est consideree trop faible
1383      PARAMETER (seuil=-0.02)
1384ccc      PARAMETER (seuil=-0.04)
1385ccc      PARAMETER (seuil=-0.06)
1386ccc      PARAMETER (seuil=-0.09)
1387c
1388c Variables locales:
1389c
1390      INTEGER i, k, invb(knon)
1391      REAL zl2(knon)
1392      REAL zdthmin(knon), zdthdp
1393c
1394c Initialiser les sorties
1395c
1396      DO k = 1, klev
1397      DO i = 1, knon
1398         pcfm(i,k) = 0.0
1399         pcfh(i,k) = 0.0
1400      ENDDO
1401      ENDDO
1402c
1403c Chercher la zone d'inversion forte
1404c
1405      DO i = 1, knon
1406         invb(i) = klev
1407         zdthmin(i)=0.0
1408      ENDDO
1409      DO k = 2, klev/2-1
1410      DO i = 1, knon
1411         zdthdp = (t(i,k)-t(i,k+1))/(pplay(i,k)-pplay(i,k+1))
1412     .          - RD * 0.5*(t(i,k)+t(i,k+1))/RCPD/paprs(i,k+1)
1413         zdthdp = zdthdp * 100.0
1414         IF (pplay(i,k).GT.0.8*paprs(i,1) .AND.
1415     .       zdthdp.LT.zdthmin(i) ) THEN
1416            zdthmin(i) = zdthdp
1417            invb(i) = k
1418         ENDIF
1419      ENDDO
1420      ENDDO
1421c
1422c Introduire une diffusion:
1423c
1424      DO k = 2, klev
1425      DO i = 1, knon
1426      IF ( (nsrf.NE.is_oce) .OR.  ! si ce n'est pas sur l'ocean
1427     .     (invb(i).EQ.klev) .OR. ! s'il n'y a pas d'inversion
1428     .     (zdthmin(i).GT.seuil) )THEN ! si l'inversion est trop faible
1429         zl2(i)=(mixlen*MAX(0.0,(paprs(i,k)-paprs(i,klev+1))
1430     .                       /(paprs(i,2)-paprs(i,klev+1)) ))**2
1431         pcfm(i,k)= zl2(i)* kstable
1432         pcfh(i,k) = pcfm(i,k) /prandtl ! h et m different
1433      ENDIF
1434      ENDDO
1435      ENDDO
1436c
1437      RETURN
1438      END
1439      SUBROUTINE calbeta(dtime,indice,knon,snow,qsol,
1440     .                    vbeta,vcal,vdif)
1441      IMPLICIT none
1442c======================================================================
1443c Auteur(s): Z.X. Li (LMD/CNRS) (adaptation du GCM du LMD)
1444c date: 19940414
1445c======================================================================
1446c
1447c Calculer quelques parametres pour appliquer la couche limite
1448c ------------------------------------------------------------
1449#include "dimensions.h"
1450#include "dimphy.h"
1451#include "YOMCST.h"
1452#include "indicesol.h"
1453      REAL tau_gl ! temps de relaxation pour la glace de mer
1454ccc      PARAMETER (tau_gl=86400.0*30.0)
1455      PARAMETER (tau_gl=86400.0*5.0)
1456      REAL mx_eau_sol
1457      PARAMETER (mx_eau_sol=150.0)
1458c
1459      REAL calsol, calsno, calice ! epaisseur du sol: 0.15 m
1460      PARAMETER (calsol=1.0/(2.5578E+06*0.15))
1461      PARAMETER (calsno=1.0/(2.3867E+06*0.15))
1462      PARAMETER (calice=1.0/(5.1444E+06*0.15))
1463C
1464      INTEGER i
1465c
1466      REAL dtime
1467      REAL snow(klon), qsol(klon)
1468      INTEGER indice, knon
1469C
1470      REAL vbeta(klon)
1471      REAL vcal(klon)
1472      REAL vdif(klon)
1473C
1474
1475      IF (indice.EQ.is_oce) THEN
1476      DO i = 1, knon
1477          vcal(i)   = 0.0
1478          vbeta(i)  = 1.0
1479          vdif(i) = 0.0
1480      ENDDO
1481      ENDIF
1482c
1483      IF (indice.EQ.is_sic) THEN
1484      DO i = 1, knon
1485          vcal(i) = calice
1486          IF (snow(i) .GT. 0.0) vcal(i) = calsno
1487          vbeta(i)  = 1.0
1488          vdif(i) = 1.0/tau_gl
1489ccc          vdif(i) = calice/tau_gl ! c'etait une erreur
1490      ENDDO
1491      ENDIF
1492c
1493      IF (indice.EQ.is_ter) THEN
1494      DO i = 1, knon
1495          vcal(i) = calsol
1496          IF (snow(i) .GT. 0.0) vcal(i) = calsno
1497          vbeta(i)  = MIN(2.0*qsol(i)/mx_eau_sol, 1.0)
1498          vdif(i) = 0.0
1499      ENDDO
1500      ENDIF
1501c
1502      IF (indice.EQ.is_lic) THEN
1503      DO i = 1, knon
1504          vcal(i) = calice
1505          IF (snow(i) .GT. 0.0) vcal(i) = calsno
1506          vbeta(i)  = 1.0
1507          vdif(i) = 0.0
1508      ENDDO
1509      ENDIF
1510c
1511      RETURN
1512      END
1513C======================================================================
1514      SUBROUTINE nonlocal(knon, paprs, pplay,
1515     .                    tsol,beta,u,v,t,q,
1516     .                    cd_h, cd_m, pcfh, pcfm, cgh, cgq)
1517      IMPLICIT none
1518c======================================================================
1519c Laurent Li (LMD/CNRS), le 30 septembre 1998
1520c Couche limite non-locale. Adaptation du code du CCM3.
1521c Code non teste, donc a ne pas utiliser.
1522c======================================================================
1523c Nonlocal scheme that determines eddy diffusivities based on a
1524c diagnosed boundary layer height and a turbulent velocity scale.
1525c Also countergradient effects for heat and moisture are included.
1526c
1527c For more information, see Holtslag, A.A.M., and B.A. Boville, 1993:
1528c Local versus nonlocal boundary-layer diffusion in a global climate
1529c model. J. of Climate, vol. 6, 1825-1842.
1530c======================================================================
1531#include "dimensions.h"
1532#include "dimphy.h"
1533#include "YOMCST.h"
1534c
1535c Arguments:
1536c
1537      INTEGER knon ! nombre de points a calculer
1538      REAL tsol(klon) ! temperature du sol (K)
1539      REAL beta(klon) ! efficacite d'evaporation (entre 0 et 1)
1540      REAL paprs(klon,klev+1) ! pression a inter-couche (Pa)
1541      REAL pplay(klon,klev)   ! pression au milieu de couche (Pa)
1542      REAL u(klon,klev) ! vitesse U (m/s)
1543      REAL v(klon,klev) ! vitesse V (m/s)
1544      REAL t(klon,klev) ! temperature (K)
1545      REAL q(klon,klev) ! vapeur d'eau (kg/kg)
1546      REAL cd_h(klon) ! coefficient de friction au sol pour chaleur
1547      REAL cd_m(klon) ! coefficient de friction au sol pour vitesse
1548c
1549      INTEGER isommet
1550      PARAMETER (isommet=klev)
1551      REAL vk
1552      PARAMETER (vk=0.35)
1553      REAL ricr
1554      PARAMETER (ricr=0.4)
1555      REAL fak
1556      PARAMETER (fak=8.5)
1557      REAL fakn
1558      PARAMETER (fakn=7.2)
1559      REAL onet
1560      PARAMETER (onet=1.0/3.0)
1561      REAL t_coup
1562      PARAMETER(t_coup=273.15)
1563      REAL zkmin
1564      PARAMETER (zkmin=0.01)
1565      REAL betam
1566      PARAMETER (betam=15.0)
1567      REAL betah
1568      PARAMETER (betah=15.0)
1569      REAL betas
1570      PARAMETER (betas=5.0)
1571      REAL sffrac
1572      PARAMETER (sffrac=0.1)
1573      REAL binm
1574      PARAMETER (binm=betam*sffrac)
1575      REAL binh
1576      PARAMETER (binh=betah*sffrac)
1577      REAL ccon
1578      PARAMETER (ccon=fak*sffrac*vk)
1579c
1580      REAL z(klon,klev)
1581      REAL pcfm(klon,klev), pcfh(klon,klev)
1582c
1583      INTEGER i, k
1584      REAL zxt, zxq, zxu, zxv, zxmod, taux, tauy
1585      REAL zx_alf1, zx_alf2 ! parametres pour extrapolation
1586      REAL khfs(klon)       ! surface kinematic heat flux [mK/s]
1587      REAL kqfs(klon)       ! sfc kinematic constituent flux [m/s]
1588      REAL heatv(klon)      ! surface virtual heat flux
1589      REAL ustar(klon)
1590      REAL rino(klon,klev)  ! bulk Richardon no. from level to ref lev
1591      LOGICAL unstbl(klon)  ! pts w/unstbl pbl (positive virtual ht flx)
1592      LOGICAL stblev(klon)  ! stable pbl with levels within pbl
1593      LOGICAL unslev(klon)  ! unstbl pbl with levels within pbl
1594      LOGICAL unssrf(klon)  ! unstb pbl w/lvls within srf pbl lyr
1595      LOGICAL unsout(klon)  ! unstb pbl w/lvls in outer pbl lyr
1596      LOGICAL check(klon)   ! True=>chk if Richardson no.>critcal
1597      REAL pblh(klon)
1598      REAL cgh(klon,2:klev) ! counter-gradient term for heat [K/m]
1599      REAL cgq(klon,2:klev) ! counter-gradient term for constituents
1600      REAL cgs(klon,2:klev) ! counter-gradient star (cg/flux)
1601      REAL obklen(klon)
1602      REAL ztvd, ztvu, zdu2
1603      REAL therm(klon)      ! thermal virtual temperature excess
1604      REAL phiminv(klon)    ! inverse phi function for momentum
1605      REAL phihinv(klon)    ! inverse phi function for heat
1606      REAL wm(klon)         ! turbulent velocity scale for momentum
1607      REAL fak1(klon)       ! k*ustar*pblh
1608      REAL fak2(klon)       ! k*wm*pblh
1609      REAL fak3(klon)       ! fakn*wstr/wm
1610      REAL pblk(klon)       ! level eddy diffusivity for momentum
1611      REAL pr(klon)         ! Prandtl number for eddy diffusivities
1612      REAL zl(klon)         ! zmzp / Obukhov length
1613      REAL zh(klon)         ! zmzp / pblh
1614      REAL zzh(klon)        ! (1-(zmzp/pblh))**2
1615      REAL wstr(klon)       ! w*, convective velocity scale
1616      REAL zm(klon)         ! current level height
1617      REAL zp(klon)         ! current level height + one level up
1618      REAL zcor, zdelta, zcvm5, zxqs
1619      REAL fac, pblmin, zmzp, term
1620c
1621#include "YOETHF.h"
1622#include "FCTTRE.h"
1623c
1624c Initialisation
1625c
1626      DO i = 1, klon
1627         pcfh(i,1) = cd_h(i)
1628         pcfm(i,1) = cd_m(i)
1629      ENDDO
1630      DO k = 2, klev
1631      DO i = 1, klon
1632         pcfh(i,k) = zkmin
1633         pcfm(i,k) = zkmin
1634         cgs(i,k) = 0.0
1635         cgh(i,k) = 0.0
1636         cgq(i,k) = 0.0
1637      ENDDO
1638      ENDDO
1639c
1640c Calculer les hauteurs de chaque couche
1641c
1642      DO i = 1, knon
1643         z(i,1) = RD * t(i,1) / (0.5*(paprs(i,1)+pplay(i,1)))
1644     .               * (paprs(i,1)-pplay(i,1)) / RG
1645      ENDDO
1646      DO k = 2, klev
1647      DO i = 1, knon
1648         z(i,k) = z(i,k-1)
1649     .              + RD * 0.5*(t(i,k-1)+t(i,k)) / paprs(i,k)
1650     .                   * (pplay(i,k-1)-pplay(i,k)) / RG
1651      ENDDO
1652      ENDDO
1653c
1654      DO i = 1, knon
1655         IF (thermcep) THEN
1656           zdelta=MAX(0.,SIGN(1.,RTT-tsol(i)))
1657           zcvm5 = R5LES*RLVTT*(1.-zdelta) + R5IES*RLSTT*zdelta
1658           zcvm5 = zcvm5 / RCPD / (1.0+RVTMP2*q(i,1))
1659           zxqs= r2es * FOEEW(tsol(i),zdelta)/paprs(i,1)
1660           zxqs=MIN(0.5,zxqs)
1661           zcor=1./(1.-retv*zxqs)
1662           zxqs=zxqs*zcor
1663         ELSE
1664           IF (tsol(i).LT.t_coup) THEN
1665              zxqs = qsats(tsol(i)) / paprs(i,1)
1666           ELSE
1667              zxqs = qsatl(tsol(i)) / paprs(i,1)
1668           ENDIF
1669         ENDIF
1670        zx_alf1 = 1.0
1671        zx_alf2 = 1.0 - zx_alf1
1672        zxt = (t(i,1)+z(i,1)*RG/RCPD/(1.+RVTMP2*q(i,1)))
1673     .        *(1.+RETV*q(i,1))*zx_alf1
1674     .      + (t(i,2)+z(i,2)*RG/RCPD/(1.+RVTMP2*q(i,2)))
1675     .        *(1.+RETV*q(i,2))*zx_alf2
1676        zxu = u(i,1)*zx_alf1+u(i,2)*zx_alf2
1677        zxv = v(i,1)*zx_alf1+v(i,2)*zx_alf2
1678        zxq = q(i,1)*zx_alf1+q(i,2)*zx_alf2
1679        zxmod = 1.0+SQRT(zxu**2+zxv**2)
1680        khfs(i) = (tsol(i)*(1.+RETV*q(i,1))-zxt) *zxmod*cd_h(i)
1681        kqfs(i) = (zxqs-zxq) *zxmod*cd_h(i) * beta(i)
1682        heatv(i) = khfs(i) + 0.61*zxt*kqfs(i)
1683        taux = zxu *zxmod*cd_m(i)
1684        tauy = zxv *zxmod*cd_m(i)
1685        ustar(i) = SQRT(taux**2+tauy**2)
1686        ustar(i) = MAX(SQRT(ustar(i)),0.01)
1687      ENDDO
1688c
1689      DO i = 1, knon
1690         rino(i,1) = 0.0
1691         check(i) = .TRUE.
1692         pblh(i) = z(i,1)
1693         obklen(i) = -t(i,1)*ustar(i)**3/(RG*vk*heatv(i))
1694      ENDDO
1695
1696C
1697C PBL height calculation:
1698C Search for level of pbl. Scan upward until the Richardson number between
1699C the first level and the current level exceeds the "critical" value.
1700C
1701      fac = 100.0
1702      DO k = 1, isommet
1703      DO i = 1, knon
1704      IF (check(i)) THEN
1705         zdu2 = (u(i,k)-u(i,1))**2+(v(i,k)-v(i,1))**2+fac*ustar(i)**2
1706         zdu2 = max(zdu2,1.0e-20)
1707         ztvd =(t(i,k)+z(i,k)*0.5*RG/RCPD/(1.+RVTMP2*q(i,k)))
1708     .         *(1.+RETV*q(i,k))
1709         ztvu =(t(i,1)-z(i,k)*0.5*RG/RCPD/(1.+RVTMP2*q(i,1)))
1710     .         *(1.+RETV*q(i,1))
1711         rino(i,k) = (z(i,k)-z(i,1))*RG*(ztvd-ztvu)
1712     .               /(zdu2*0.5*(ztvd+ztvu))
1713         IF (rino(i,k).GE.ricr) THEN
1714           pblh(i) = z(i,k-1) + (z(i,k-1)-z(i,k)) *
1715     .              (ricr-rino(i,k-1))/(rino(i,k-1)-rino(i,k))
1716           check(i) = .FALSE.
1717         ENDIF
1718      ENDIF
1719      ENDDO
1720      ENDDO
1721
1722C
1723C Set pbl height to maximum value where computation exceeds number of
1724C layers allowed
1725C
1726      DO i = 1, knon
1727        if (check(i)) pblh(i) = z(i,isommet)
1728      ENDDO
1729C
1730C Improve estimate of pbl height for the unstable points.
1731C Find unstable points (sensible heat flux is upward):
1732C
1733      DO i = 1, knon
1734      IF (heatv(i) .GT. 0.) THEN
1735        unstbl(i) = .TRUE.
1736        check(i) = .TRUE.
1737      ELSE
1738        unstbl(i) = .FALSE.
1739        check(i) = .FALSE.
1740      ENDIF
1741      ENDDO
1742C
1743C For the unstable case, compute velocity scale and the
1744C convective temperature excess:
1745C
1746      DO i = 1, knon
1747      IF (check(i)) THEN
1748        phiminv(i) = (1.-binm*pblh(i)/obklen(i))**onet
1749        wm(i)= ustar(i)*phiminv(i)
1750        therm(i) = heatv(i)*fak/wm(i)
1751        rino(i,1) = 0.0
1752      ENDIF
1753      ENDDO
1754C
1755C Improve pblh estimate for unstable conditions using the
1756C convective temperature excess:
1757C
1758      DO k = 1, isommet
1759      DO i = 1, knon
1760      IF (check(i)) THEN
1761         zdu2 = (u(i,k)-u(i,1))**2+(v(i,k)-v(i,1))**2+fac*ustar(i)**2
1762         zdu2 = max(zdu2,1.0e-20)
1763         ztvd =(t(i,k)+z(i,k)*0.5*RG/RCPD/(1.+RVTMP2*q(i,k)))
1764     .         *(1.+RETV*q(i,k))
1765         ztvu =(t(i,1)+therm(i)-z(i,k)*0.5*RG/RCPD/(1.+RVTMP2*q(i,1)))
1766     .         *(1.+RETV*q(i,1))
1767         rino(i,k) = (z(i,k)-z(i,1))*RG*(ztvd-ztvu)
1768     .               /(zdu2*0.5*(ztvd+ztvu))
1769         IF (rino(i,k).GE.ricr) THEN
1770           pblh(i) = z(i,k-1) + (z(i,k-1)-z(i,k)) *
1771     .              (ricr-rino(i,k-1))/(rino(i,k-1)-rino(i,k))
1772           check(i) = .FALSE.
1773         ENDIF
1774      ENDIF
1775      ENDDO
1776      ENDDO
1777C
1778C Set pbl height to maximum value where computation exceeds number of
1779C layers allowed
1780C
1781      DO i = 1, knon
1782        if (check(i)) pblh(i) = z(i,isommet)
1783      ENDDO
1784C
1785C Points for which pblh exceeds number of pbl layers allowed;
1786C set to maximum
1787C
1788      DO i = 1, knon
1789        IF (check(i)) pblh(i) = z(i,isommet)
1790      ENDDO
1791C
1792C PBL height must be greater than some minimum mechanical mixing depth
1793C Several investigators have proposed minimum mechanical mixing depth
1794C relationships as a function of the local friction velocity, u*.  We
1795C make use of a linear relationship of the form h = c u* where c=700.
1796C The scaling arguments that give rise to this relationship most often
1797C represent the coefficient c as some constant over the local coriolis
1798C parameter.  Here we make use of the experimental results of Koracin
1799C and Berkowicz (1988) [BLM, Vol 43] for wich they recommend 0.07/f
1800C where f was evaluated at 39.5 N and 52 N.  Thus we use a typical mid
1801C latitude value for f so that c = 0.07/f = 700.
1802C
1803      DO i = 1, knon
1804        pblmin  = 700.0*ustar(i)
1805        pblh(i) = MAX(pblh(i),pblmin)
1806      ENDDO
1807C
1808C pblh is now available; do preparation for diffusivity calculation:
1809C
1810      DO i = 1, knon
1811        pblk(i) = 0.0
1812        fak1(i) = ustar(i)*pblh(i)*vk
1813C
1814C Do additional preparation for unstable cases only, set temperature
1815C and moisture perturbations depending on stability.
1816C
1817        IF (unstbl(i)) THEN
1818          zxt=(t(i,1)-z(i,1)*0.5*RG/RCPD/(1.+RVTMP2*q(i,1)))
1819     .         *(1.+RETV*q(i,1))
1820          phiminv(i) = (1. - binm*pblh(i)/obklen(i))**onet
1821          phihinv(i) = sqrt(1. - binh*pblh(i)/obklen(i))
1822          wm(i)      = ustar(i)*phiminv(i)
1823          fak2(i)    = wm(i)*pblh(i)*vk
1824          wstr(i)    = (heatv(i)*RG*pblh(i)/zxt)**onet
1825          fak3(i)    = fakn*wstr(i)/wm(i)
1826        ENDIF
1827      ENDDO
1828
1829C Main level loop to compute the diffusivities and
1830C counter-gradient terms:
1831C
1832      DO 1000 k = 2, isommet
1833C
1834C Find levels within boundary layer:
1835C
1836        DO i = 1, knon
1837          unslev(i) = .FALSE.
1838          stblev(i) = .FALSE.
1839          zm(i) = z(i,k-1)
1840          zp(i) = z(i,k)
1841          IF (zkmin.EQ.0.0 .AND. zp(i).GT.pblh(i)) zp(i) = pblh(i)
1842          IF (zm(i) .LT. pblh(i)) THEN
1843            zmzp = 0.5*(zm(i) + zp(i))
1844            zh(i) = zmzp/pblh(i)
1845            zl(i) = zmzp/obklen(i)
1846            zzh(i) = 0.
1847            IF (zh(i).LE.1.0) zzh(i) = (1. - zh(i))**2
1848C
1849C stblev for points zm < plbh and stable and neutral
1850C unslev for points zm < plbh and unstable
1851C
1852            IF (unstbl(i)) THEN
1853              unslev(i) = .TRUE.
1854            ELSE
1855              stblev(i) = .TRUE.
1856            ENDIF
1857          ENDIF
1858        ENDDO
1859C
1860C Stable and neutral points; set diffusivities; counter-gradient
1861C terms zero for stable case:
1862C
1863        DO i = 1, knon
1864          IF (stblev(i)) THEN
1865            IF (zl(i).LE.1.) THEN
1866              pblk(i) = fak1(i)*zh(i)*zzh(i)/(1. + betas*zl(i))
1867            ELSE
1868              pblk(i) = fak1(i)*zh(i)*zzh(i)/(betas + zl(i))
1869            ENDIF
1870            pcfm(i,k) = pblk(i)
1871            pcfh(i,k) = pcfm(i,k)
1872          ENDIF
1873        ENDDO
1874C
1875C unssrf, unstable within surface layer of pbl
1876C unsout, unstable within outer   layer of pbl
1877C
1878        DO i = 1, knon
1879          unssrf(i) = .FALSE.
1880          unsout(i) = .FALSE.
1881          IF (unslev(i)) THEN
1882            IF (zh(i).lt.sffrac) THEN
1883              unssrf(i) = .TRUE.
1884            ELSE
1885              unsout(i) = .TRUE.
1886            ENDIF
1887          ENDIF
1888        ENDDO
1889C
1890C Unstable for surface layer; counter-gradient terms zero
1891C
1892        DO i = 1, knon
1893          IF (unssrf(i)) THEN
1894            term = (1. - betam*zl(i))**onet
1895            pblk(i) = fak1(i)*zh(i)*zzh(i)*term
1896            pr(i) = term/sqrt(1. - betah*zl(i))
1897          ENDIF
1898        ENDDO
1899C
1900C Unstable for outer layer; counter-gradient terms non-zero:
1901C
1902        DO i = 1, knon
1903          IF (unsout(i)) THEN
1904            pblk(i) = fak2(i)*zh(i)*zzh(i)
1905            cgs(i,k) = fak3(i)/(pblh(i)*wm(i))
1906            cgh(i,k) = khfs(i)*cgs(i,k)
1907            pr(i) = phiminv(i)/phihinv(i) + ccon*fak3(i)/fak
1908            cgq(i,k) = kqfs(i)*cgs(i,k)
1909          ENDIF
1910        ENDDO
1911C
1912C For all unstable layers, set diffusivities
1913C
1914        DO i = 1, knon
1915        IF (unslev(i)) THEN
1916            pcfm(i,k) = pblk(i)
1917            pcfh(i,k) = pblk(i)/pr(i)
1918        ENDIF
1919        ENDDO
1920 1000 continue           ! end of level loop
1921
1922      RETURN
1923      END
Note: See TracBrowser for help on using the repository browser.