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

Last change on this file since 224 was 223, checked in by lmdzadmin, 24 years ago

Impression debug dans clmain MAFO
Introduction du physiq.def LF
LF

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