/[lmdze]/trunk/Sources/phylmd/Thermcell/thermcell.f
ViewVC logotype

Diff of /trunk/Sources/phylmd/Thermcell/thermcell.f

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

trunk/libf/phylmd/thermcell.f revision 38 by guez, Thu Jan 6 17:52:19 2011 UTC trunk/libf/phylmd/Thermcell/thermcell.f90 revision 52 by guez, Fri Sep 23 12:28:01 2011 UTC
# Line 1  Line 1 
1        SUBROUTINE thermcell(ngrid,nlay,ptimestep  SUBROUTINE thermcell(ngrid, nlay, ptimestep, pplay, pplev, pphi, pu, pv, pt, &
2       s                  ,pplay,pplev,pphi       po, pduadj, pdvadj, pdtadj, pdoadj, fm0, entr0, r_aspect, l_mix, w2di, tho)
3       s                  ,pu,pv,pt,po  
4       s                  ,pduadj,pdvadj,pdtadj,pdoadj    use dimens_m
5       s                  ,fm0,entr0    use dimphy
6  c    s                  ,pu_therm,pv_therm    use SUPHEC_M
7       s                  ,r_aspect,l_mix,w2di,tho)  
8      IMPLICIT NONE
9        use dimens_m  
10        use dimphy    !   Calcul du transport verticale dans la couche limite en presence
11        use SUPHEC_M    !   de "thermiques" explicitement representes
12        IMPLICIT NONE  
13      !   Réécriture à partir d'un listing papier à Habas, le 14/02/00
14  c=======================================================================  
15  c    !   le thermique est supposé homogène et dissipé par mélange avec
16  c   Calcul du transport verticale dans la couche limite en presence    !   son environnement. la longueur l_mix contrôle l'efficacité du
17  c   de "thermiques" explicitement representes    !   mélange
18  c  
19  c   Réécriture à partir d'un listing papier à Habas, le 14/02/00    !   Le calcul du transport des différentes espèces se fait en prenant
20  c    !   en compte:
21  c   le thermique est supposé homogène et dissipé par mélange avec    !     1. un flux de masse montant
22  c   son environnement. la longueur l_mix contrôle l'efficacité du    !     2. un flux de masse descendant
23  c   mélange    !     3. un entrainement
24  c    !     4. un detrainement
25  c   Le calcul du transport des différentes espèces se fait en prenant  
26  c   en compte:    !   arguments:
27  c     1. un flux de masse montant  
28  c     2. un flux de masse descendant    INTEGER ngrid, nlay, w2di, tho
29  c     3. un entrainement    real ptimestep, l_mix, r_aspect
30  c     4. un detrainement    REAL, intent(in):: pt(ngrid, nlay)
31  c    real pdtadj(ngrid, nlay)
32  c=======================================================================    REAL pu(ngrid, nlay), pduadj(ngrid, nlay)
33      REAL pv(ngrid, nlay), pdvadj(ngrid, nlay)
34  c-----------------------------------------------------------------------    REAL po(ngrid, nlay), pdoadj(ngrid, nlay)
35  c   declarations:    REAL, intent(in):: pplay(ngrid, nlay)
36  c   -------------    real, intent(in):: pplev(ngrid, nlay+1)
37      real, intent(in):: pphi(ngrid, nlay)
38    
39  c   arguments:    integer idetr
40  c   ----------    save idetr
41      data idetr/3/
42        INTEGER ngrid,nlay,w2di,tho  
43        real ptimestep,l_mix,r_aspect    !   local:
44        REAL pt(ngrid,nlay),pdtadj(ngrid,nlay)  
45        REAL pu(ngrid,nlay),pduadj(ngrid,nlay)    INTEGER ig, k, l, lmaxa(klon), lmix(klon)
46        REAL pv(ngrid,nlay),pdvadj(ngrid,nlay)    real zsortie1d(klon)
47        REAL po(ngrid,nlay),pdoadj(ngrid,nlay)    ! CR: on remplace lmax(klon, klev+1)
48        REAL, intent(in):: pplay(ngrid,nlay)    INTEGER lmax(klon), lmin(klon), lentr(klon)
49        real, intent(in):: pplev(ngrid,nlay+1)    real linter(klon)
50        real pphi(ngrid,nlay)    real zmix(klon), fracazmix(klon)
51    
52        integer idetr    real zmax(klon), zw, zz, zw2(klon, klev+1), ztva(klon, klev), zzz
53        save idetr  
54        data idetr/3/    real zlev(klon, klev+1), zlay(klon, klev)
55      REAL zh(klon, klev), zdhadj(klon, klev)
56  c   local:    REAL ztv(klon, klev)
57  c   ------    real zu(klon, klev), zv(klon, klev), zo(klon, klev)
58      REAL wh(klon, klev+1)
59        INTEGER ig,k,l,lmaxa(klon),lmix(klon)    real wu(klon, klev+1), wv(klon, klev+1), wo(klon, klev+1)
60        real zsortie1d(klon)    real zla(klon, klev+1)
61  c CR: on remplace lmax(klon,klev+1)    real zwa(klon, klev+1)
62        INTEGER lmax(klon),lmin(klon),lentr(klon)    real zld(klon, klev+1)
63        real linter(klon)    real zwd(klon, klev+1)
64        real zmix(klon), fracazmix(klon)    real zsortie(klon, klev)
65  c RC    real zva(klon, klev)
66        real zmax(klon),zw,zz,zw2(klon,klev+1),ztva(klon,klev),zzz    real zua(klon, klev)
67      real zoa(klon, klev)
68        real zlev(klon,klev+1),zlay(klon,klev)  
69        REAL zh(klon,klev),zdhadj(klon,klev)    real zha(klon, klev)
70        REAL ztv(klon,klev)    real wa_moy(klon, klev+1)
71        real zu(klon,klev),zv(klon,klev),zo(klon,klev)    real fraca(klon, klev+1)
72        REAL wh(klon,klev+1)    real fracc(klon, klev+1)
73        real wu(klon,klev+1),wv(klon,klev+1),wo(klon,klev+1)    real zf, zf2
74        real zla(klon,klev+1)    real thetath2(klon, klev), wth2(klon, klev)
75        real zwa(klon,klev+1)    common/comtherm/thetath2, wth2
76        real zld(klon,klev+1)  
77        real zwd(klon,klev+1)    real count_time
78        real zsortie(klon,klev)    integer isplit, nsplit, ialt
79        real zva(klon,klev)    parameter (nsplit=10)
80        real zua(klon,klev)    data isplit/0/
81        real zoa(klon,klev)    save isplit
82    
83        real zha(klon,klev)    logical sorties
84        real wa_moy(klon,klev+1)    real rho(klon, klev), rhobarz(klon, klev+1), masse(klon, klev)
85        real fraca(klon,klev+1)    real zpspsk(klon, klev)
86        real fracc(klon,klev+1)  
87        real zf,zf2    real wmax(klon), wmaxa(klon)
88        real thetath2(klon,klev),wth2(klon,klev)    real wa(klon, klev, klev+1)
89        common/comtherm/thetath2,wth2    real wd(klon, klev+1)
90      real larg_part(klon, klev, klev+1)
91        real count_time    real fracd(klon, klev+1)
92        integer isplit,nsplit,ialt    real xxx(klon, klev+1)
93        parameter (nsplit=10)    real larg_cons(klon, klev+1)
94        data isplit/0/    real larg_detr(klon, klev+1)
95        save isplit    real fm0(klon, klev+1), entr0(klon, klev), detr(klon, klev)
96      real pu_therm(klon, klev), pv_therm(klon, klev)
97        logical sorties    real fm(klon, klev+1), entr(klon, klev)
98        real rho(klon,klev),rhobarz(klon,klev+1),masse(klon,klev)    real fmc(klon, klev+1)
99        real zpspsk(klon,klev)  
100      !CR:nouvelles variables
101  c     real wmax(klon,klev),wmaxa(klon)    real f_star(klon, klev+1), entr_star(klon, klev)
102        real wmax(klon),wmaxa(klon)    real entr_star_tot(klon), entr_star2(klon)
103        real wa(klon,klev,klev+1)    real f(klon), f0(klon)
104        real wd(klon,klev+1)    real zlevinter(klon)
105        real larg_part(klon,klev,klev+1)    logical first
106        real fracd(klon,klev+1)    data first /.false./
107        real xxx(klon,klev+1)    save first
108        real larg_cons(klon,klev+1)  
109        real larg_detr(klon,klev+1)    character*2 str2
110        real fm0(klon,klev+1),entr0(klon,klev),detr(klon,klev)    character*10 str10
111        real pu_therm(klon,klev),pv_therm(klon,klev)  
112        real fm(klon,klev+1),entr(klon,klev)    LOGICAL vtest(klon), down
113        real fmc(klon,klev+1)  
114      EXTERNAL SCOPY
115  cCR:nouvelles variables  
116        real f_star(klon,klev+1),entr_star(klon,klev)    integer ncorrec, ll
117        real entr_star_tot(klon),entr_star2(klon)    save ncorrec
118        real f(klon), f0(klon)    data ncorrec/0/
119        real zlevinter(klon)  
120        logical first    !-----------------------------------------------------------------------
121        data first /.false./  
122        save first    !   initialisation:
123  cRC  
124      sorties=.true.
125        character*2 str2    IF(ngrid.NE.klon) THEN
126        character*10 str10       PRINT *
127         PRINT *, 'STOP dans convadj'
128        LOGICAL vtest(klon),down       PRINT *, 'ngrid    =', ngrid
129         PRINT *, 'klon  =', klon
130        EXTERNAL SCOPY    ENDIF
131    
132        integer ncorrec,ll    !   incrementation eventuelle de tendances precedentes:
133        save ncorrec  
134        data ncorrec/0/    print *, '0 OK convect8'
135          
136  c    DO l=1, nlay
137  c-----------------------------------------------------------------------       DO ig=1, ngrid
138  c   initialisation:          zpspsk(ig, l)=(pplay(ig, l)/pplev(ig, 1))**RKAPPA
139  c   ---------------          zh(ig, l)=pt(ig, l)/zpspsk(ig, l)
140  c          zu(ig, l)=pu(ig, l)
141         sorties=.true.          zv(ig, l)=pv(ig, l)
142        IF(ngrid.NE.klon) THEN          zo(ig, l)=po(ig, l)
143           PRINT*          ztv(ig, l)=zh(ig, l)*(1.+0.61*zo(ig, l))
144           PRINT*,'STOP dans convadj'       end DO
145           PRINT*,'ngrid    =',ngrid    end DO
146           PRINT*,'klon  =',klon  
147        ENDIF    print *, '1 OK convect8'
148  c  
149  c-----------------------------------------------------------------------    !                       + + + + + + + + + + +
150  c   incrementation eventuelle de tendances precedentes:  
151  c   ---------------------------------------------------    !  wa, fraca, wd, fracd --------------------   zlev(2), rhobarz
152      !  wh, wt, wo ...
153         print*,'0 OK convect8'  
154      !                       + + + + + + + + + + +  zh, zu, zv, zo, rho
155        DO 1010 l=1,nlay  
156           DO 1015 ig=1,ngrid    !                       --------------------   zlev(1)
157              zpspsk(ig,l)=(pplay(ig,l)/pplev(ig,1))**RKAPPA    !                       \\\\\\\\\\\\\\\\\\\\
158              zh(ig,l)=pt(ig,l)/zpspsk(ig,l)  
159              zu(ig,l)=pu(ig,l)    !   Calcul des altitudes des couches
160              zv(ig,l)=pv(ig,l)  
161              zo(ig,l)=po(ig,l)    do l=2, nlay
162              ztv(ig,l)=zh(ig,l)*(1.+0.61*zo(ig,l))       do ig=1, ngrid
163  1015     CONTINUE          zlev(ig, l)=0.5*(pphi(ig, l)+pphi(ig, l-1))/RG
164  1010  CONTINUE       enddo
165      enddo
166         print*,'1 OK convect8'    do ig=1, ngrid
167  c                       --------------------       zlev(ig, 1)=0.
168  c       zlev(ig, nlay+1)=(2.*pphi(ig, klev)-pphi(ig, klev-1))/RG
169  c    enddo
170  c                       + + + + + + + + + + +    do l=1, nlay
171  c       do ig=1, ngrid
172  c          zlay(ig, l)=pphi(ig, l)/RG
173  c  wa, fraca, wd, fracd --------------------   zlev(2), rhobarz       enddo
174  c  wh,wt,wo ...    enddo
175  c  
176  c                       + + + + + + + + + + +  zh,zu,zv,zo,rho    !   Calcul des densites
177  c  
178  c    do l=1, nlay
179  c                       --------------------   zlev(1)       do ig=1, ngrid
180  c                       \\\\\\\\\\\\\\\\\\\\          rho(ig, l)=pplay(ig, l)/(zpspsk(ig, l)*RD*zh(ig, l))
181  c       enddo
182  c    enddo
183    
184  c-----------------------------------------------------------------------    do l=2, nlay
185  c   Calcul des altitudes des couches       do ig=1, ngrid
186  c-----------------------------------------------------------------------          rhobarz(ig, l)=0.5*(rho(ig, l)+rho(ig, l-1))
187         enddo
188        do l=2,nlay    enddo
189           do ig=1,ngrid  
190              zlev(ig,l)=0.5*(pphi(ig,l)+pphi(ig,l-1))/RG    do k=1, nlay
191           enddo       do l=1, nlay+1
192        enddo          do ig=1, ngrid
193        do ig=1,ngrid             wa(ig, k, l)=0.
194           zlev(ig,1)=0.          enddo
195           zlev(ig,nlay+1)=(2.*pphi(ig,klev)-pphi(ig,klev-1))/RG       enddo
196        enddo    enddo
197        do l=1,nlay  
198           do ig=1,ngrid    !   Calcul de w2, quarre de w a partir de la cape
199              zlay(ig,l)=pphi(ig,l)/RG    !   a partir de w2, on calcule wa, vitesse de l'ascendance
200           enddo  
201        enddo    !   ATTENTION: Dans cette version, pour cause d'economie de memoire,
202      !   w2 est stoke dans wa
203  c      print*,'2 OK convect8'  
204  c-----------------------------------------------------------------------    !   ATTENTION: dans convect8, on n'utilise le calcule des wa
205  c   Calcul des densites    !   independants par couches que pour calculer l'entrainement
206  c-----------------------------------------------------------------------    !   a la base et la hauteur max de l'ascendance.
207    
208        do l=1,nlay    !   Indicages:
209           do ig=1,ngrid    !   l'ascendance provenant du niveau k traverse l'interface l avec
210              rho(ig,l)=pplay(ig,l)/(zpspsk(ig,l)*RD*zh(ig,l))    !   une vitesse wa(k, l).
211           enddo  
212        enddo    !                       --------------------
213    
214        do l=2,nlay    !                       + + + + + + + + + +
215           do ig=1,ngrid  
216              rhobarz(ig,l)=0.5*(rho(ig,l)+rho(ig,l-1))    !  wa(k, l)   ----       --------------------    l
217           enddo    !             /\
218        enddo    !            /||\       + + + + + + + + + +
219      !             ||
220        do k=1,nlay    !             ||        --------------------
221           do l=1,nlay+1    !             ||
222              do ig=1,ngrid    !             ||        + + + + + + + + + +
223                 wa(ig,k,l)=0.    !             ||
224              enddo    !             ||        --------------------
225           enddo    !             ||__
226        enddo    !             |___      + + + + + + + + + +     k
227    
228  c      print*,'3 OK convect8'    !                       --------------------
229  c------------------------------------------------------------------  
230  c   Calcul de w2, quarre de w a partir de la cape    !CR: ponderation entrainement des couches instables
231  c   a partir de w2, on calcule wa, vitesse de l'ascendance    !def des entr_star tels que entr=f*entr_star
232  c    do l=1, klev
233  c   ATTENTION: Dans cette version, pour cause d'economie de memoire,       do ig=1, ngrid
234  c   w2 est stoke dans wa          entr_star(ig, l)=0.
235  c       enddo
236  c   ATTENTION: dans convect8, on n'utilise le calcule des wa    enddo
237  c   independants par couches que pour calculer l'entrainement    ! determination de la longueur de la couche d entrainement
238  c   a la base et la hauteur max de l'ascendance.    do ig=1, ngrid
239  c       lentr(ig)=1
240  c   Indicages:    enddo
241  c   l'ascendance provenant du niveau k traverse l'interface l avec  
242  c   une vitesse wa(k,l).    !on ne considere que les premieres couches instables
243  c    do k=nlay-2, 1, -1
244  c                       --------------------       do ig=1, ngrid
245  c          if (ztv(ig, k).gt.ztv(ig, k+1).and. &
246  c                       + + + + + + + + + +               ztv(ig, k+1).le.ztv(ig, k+2)) then
247  c             lentr(ig)=k
248  c  wa(k,l)   ----       --------------------    l          endif
249  c             /\       enddo
250  c            /||\       + + + + + + + + + +    enddo
251  c             ||  
252  c             ||        --------------------    ! determination du lmin: couche d ou provient le thermique
253  c             ||    do ig=1, ngrid
254  c             ||        + + + + + + + + + +       lmin(ig)=1
255  c             ||    enddo
256  c             ||        --------------------    do ig=1, ngrid
257  c             ||__       do l=nlay, 2, -1
258  c             |___      + + + + + + + + + +     k          if (ztv(ig, l-1).gt.ztv(ig, l)) then
259  c             lmin(ig)=l-1
260  c                       --------------------          endif
261  c       enddo
262  c    enddo
263  c  
264  c------------------------------------------------------------------    ! definition de l'entrainement des couches
265      do l=1, klev-1
266  cCR: ponderation entrainement des couches instables       do ig=1, ngrid
267  cdef des entr_star tels que entr=f*entr_star                if (ztv(ig, l).gt.ztv(ig, l+1).and. &
268        do l=1,klev               l.ge.lmin(ig).and.l.le.lentr(ig)) then
269           do ig=1,ngrid             entr_star(ig, l)=(ztv(ig, l)-ztv(ig, l+1))* &
270              entr_star(ig,l)=0.                  (zlev(ig, l+1)-zlev(ig, l))
271           enddo          endif
272        enddo       enddo
273  c determination de la longueur de la couche d entrainement    enddo
274        do ig=1,ngrid    ! pas de thermique si couches 1->5 stables
275           lentr(ig)=1    do ig=1, ngrid
276        enddo       if (lmin(ig).gt.5) then
277            do l=1, klev
278  con ne considere que les premieres couches instables             entr_star(ig, l)=0.
279        do k=nlay-2,1,-1          enddo
280           do ig=1,ngrid       endif
281              if (ztv(ig,k).gt.ztv(ig,k+1).and.    enddo
282       s          ztv(ig,k+1).le.ztv(ig,k+2)) then    ! calcul de l entrainement total
283                 lentr(ig)=k    do ig=1, ngrid
284              endif       entr_star_tot(ig)=0.
285            enddo    enddo
286        enddo    do ig=1, ngrid
287             do k=1, klev
288  c determination du lmin: couche d ou provient le thermique          entr_star_tot(ig)=entr_star_tot(ig)+entr_star(ig, k)
289        do ig=1,ngrid       enddo
290           lmin(ig)=1    enddo
291        enddo  
292        do ig=1,ngrid    print *, 'fin calcul entr_star'
293           do l=nlay,2,-1    do k=1, klev
294              if (ztv(ig,l-1).gt.ztv(ig,l)) then       do ig=1, ngrid
295                 lmin(ig)=l-1          ztva(ig, k)=ztv(ig, k)
296              endif       enddo
297           enddo    enddo
298        enddo  
299  c    do k=1, klev+1
300  c definition de l'entrainement des couches       do ig=1, ngrid
301        do l=1,klev-1          zw2(ig, k)=0.
302           do ig=1,ngrid          fmc(ig, k)=0.
303              if (ztv(ig,l).gt.ztv(ig,l+1).and.  
304       s          l.ge.lmin(ig).and.l.le.lentr(ig)) then          f_star(ig, k)=0.
305                   entr_star(ig,l)=(ztv(ig,l)-ztv(ig,l+1))*  
306       s                           (zlev(ig,l+1)-zlev(ig,l))          larg_cons(ig, k)=0.
307              endif          larg_detr(ig, k)=0.
308           enddo          wa_moy(ig, k)=0.
309        enddo       enddo
310  c pas de thermique si couches 1->5 stables    enddo
311        do ig=1,ngrid  
312           if (lmin(ig).gt.5) then    do ig=1, ngrid
313              do l=1,klev       linter(ig)=1.
314                 entr_star(ig,l)=0.       lmaxa(ig)=1
315              enddo       lmix(ig)=1
316           endif       wmaxa(ig)=0.
317        enddo    enddo
318  c calcul de l entrainement total  
319        do ig=1,ngrid    do l=1, nlay-2
320           entr_star_tot(ig)=0.       do ig=1, ngrid
321        enddo          if (ztv(ig, l).gt.ztv(ig, l+1) &
322        do ig=1,ngrid               .and.entr_star(ig, l).gt.1.e-10 &
323           do k=1,klev               .and.zw2(ig, l).lt.1e-10) then
324              entr_star_tot(ig)=entr_star_tot(ig)+entr_star(ig,k)             f_star(ig, l+1)=entr_star(ig, l)
325           enddo             !test:calcul de dteta
326        enddo             zw2(ig, l+1)=2.*RG*(ztv(ig, l)-ztv(ig, l+1))/ztv(ig, l+1) &
327  c                  *(zlev(ig, l+1)-zlev(ig, l)) &
328        print*,'fin calcul entr_star'                  *0.4*pphi(ig, l)/(pphi(ig, l+1)-pphi(ig, l))
329        do k=1,klev             larg_detr(ig, l)=0.
330           do ig=1,ngrid          else if ((zw2(ig, l).ge.1e-10).and. &
331              ztva(ig,k)=ztv(ig,k)               (f_star(ig, l)+entr_star(ig, l).gt.1.e-10)) then
332           enddo             f_star(ig, l+1)=f_star(ig, l)+entr_star(ig, l)
333        enddo             ztva(ig, l)=(f_star(ig, l)*ztva(ig, l-1)+entr_star(ig, l) &
334  cRC                  *ztv(ig, l))/f_star(ig, l+1)
335  c      print*,'7 OK convect8'             zw2(ig, l+1)=zw2(ig, l)*(f_star(ig, l)/f_star(ig, l+1))**2+ &
336        do k=1,klev+1                  2.*RG*(ztva(ig, l)-ztv(ig, l))/ztv(ig, l) &
337           do ig=1,ngrid                  *(zlev(ig, l+1)-zlev(ig, l))
338              zw2(ig,k)=0.          endif
339              fmc(ig,k)=0.          ! determination de zmax continu par interpolation lineaire
340  cCR          if (zw2(ig, l+1).lt.0.) then
341              f_star(ig,k)=0.             if (abs(zw2(ig, l+1)-zw2(ig, l)).lt.1e-10) then
342  cRC                print *, 'pb linter'
343              larg_cons(ig,k)=0.             endif
344              larg_detr(ig,k)=0.             linter(ig)=(l*(zw2(ig, l+1)-zw2(ig, l)) &
345              wa_moy(ig,k)=0.                  -zw2(ig, l))/(zw2(ig, l+1)-zw2(ig, l))
346           enddo             zw2(ig, l+1)=0.
347        enddo             lmaxa(ig)=l
348            else
349  c      print*,'8 OK convect8'             if (zw2(ig, l+1).lt.0.) then
350        do ig=1,ngrid                print *, 'pb1 zw2<0'
351           linter(ig)=1.             endif
352           lmaxa(ig)=1             wa_moy(ig, l+1)=sqrt(zw2(ig, l+1))
353           lmix(ig)=1          endif
354           wmaxa(ig)=0.          if (wa_moy(ig, l+1).gt.wmaxa(ig)) then
355        enddo             !   lmix est le niveau de la couche ou w (wa_moy) est maximum
356               lmix(ig)=l+1
357  cCR:             wmaxa(ig)=wa_moy(ig, l+1)
358        do l=1,nlay-2          endif
359           do ig=1,ngrid       enddo
360              if (ztv(ig,l).gt.ztv(ig,l+1)    enddo
361       s         .and.entr_star(ig,l).gt.1.e-10    print *, 'fin calcul zw2'
362       s         .and.zw2(ig,l).lt.1e-10) then  
363                 f_star(ig,l+1)=entr_star(ig,l)    ! Calcul de la couche correspondant a la hauteur du thermique
364  ctest:calcul de dteta    do ig=1, ngrid
365                 zw2(ig,l+1)=2.*RG*(ztv(ig,l)-ztv(ig,l+1))/ztv(ig,l+1)       lmax(ig)=lentr(ig)
366       s                     *(zlev(ig,l+1)-zlev(ig,l))    enddo
367       s                     *0.4*pphi(ig,l)/(pphi(ig,l+1)-pphi(ig,l))    do ig=1, ngrid
368                 larg_detr(ig,l)=0.       do l=nlay, lentr(ig)+1, -1
369              else if ((zw2(ig,l).ge.1e-10).and.          if (zw2(ig, l).le.1.e-10) then
370       s               (f_star(ig,l)+entr_star(ig,l).gt.1.e-10)) then             lmax(ig)=l-1
371                 f_star(ig,l+1)=f_star(ig,l)+entr_star(ig,l)          endif
372                 ztva(ig,l)=(f_star(ig,l)*ztva(ig,l-1)+entr_star(ig,l)       enddo
373       s                    *ztv(ig,l))/f_star(ig,l+1)    enddo
374                 zw2(ig,l+1)=zw2(ig,l)*(f_star(ig,l)/f_star(ig,l+1))**2+    ! pas de thermique si couches 1->5 stables
375       s                     2.*RG*(ztva(ig,l)-ztv(ig,l))/ztv(ig,l)    do ig=1, ngrid
376       s                     *(zlev(ig,l+1)-zlev(ig,l))       if (lmin(ig).gt.5) then
377              endif          lmax(ig)=1
378  c determination de zmax continu par interpolation lineaire          lmin(ig)=1
379              if (zw2(ig,l+1).lt.0.) then       endif
380  ctest    enddo
381                 if (abs(zw2(ig,l+1)-zw2(ig,l)).lt.1e-10) then  
382                    print*,'pb linter'    ! Determination de zw2 max
383                 endif    do ig=1, ngrid
384                 linter(ig)=(l*(zw2(ig,l+1)-zw2(ig,l))       wmax(ig)=0.
385       s           -zw2(ig,l))/(zw2(ig,l+1)-zw2(ig,l))    enddo
386                 zw2(ig,l+1)=0.  
387                 lmaxa(ig)=l    do l=1, nlay
388              else       do ig=1, ngrid
389                 if (zw2(ig,l+1).lt.0.) then          if (l.le.lmax(ig)) then
390                    print*,'pb1 zw2<0'             if (zw2(ig, l).lt.0.)then
391                 endif                print *, 'pb2 zw2<0'
392                 wa_moy(ig,l+1)=sqrt(zw2(ig,l+1))             endif
393              endif             zw2(ig, l)=sqrt(zw2(ig, l))
394              if (wa_moy(ig,l+1).gt.wmaxa(ig)) then             wmax(ig)=max(wmax(ig), zw2(ig, l))
395  c   lmix est le niveau de la couche ou w (wa_moy) est maximum          else
396                 lmix(ig)=l+1             zw2(ig, l)=0.
397                 wmaxa(ig)=wa_moy(ig,l+1)          endif
398              endif       enddo
399           enddo    enddo
400        enddo  
401        print*,'fin calcul zw2'    !   Longueur caracteristique correspondant a la hauteur des thermiques.
402  c    do  ig=1, ngrid
403  c Calcul de la couche correspondant a la hauteur du thermique       zmax(ig)=0.
404        do ig=1,ngrid       zlevinter(ig)=zlev(ig, 1)
405           lmax(ig)=lentr(ig)    enddo
406        enddo    do  ig=1, ngrid
407        do ig=1,ngrid       ! calcul de zlevinter
408           do l=nlay,lentr(ig)+1,-1       zlevinter(ig)=(zlev(ig, lmax(ig)+1)-zlev(ig, lmax(ig)))* &
409              if (zw2(ig,l).le.1.e-10) then            linter(ig)+zlev(ig, lmax(ig))-lmax(ig)*(zlev(ig, lmax(ig)+1) &
410                 lmax(ig)=l-1            -zlev(ig, lmax(ig)))
411              endif       zmax(ig)=max(zmax(ig), zlevinter(ig)-zlev(ig, lmin(ig)))
412           enddo    enddo
413        enddo  
414  c pas de thermique si couches 1->5 stables    print *, 'avant fermeture'
415        do ig=1,ngrid    ! Fermeture, determination de f
416           if (lmin(ig).gt.5) then    do ig=1, ngrid
417              lmax(ig)=1       entr_star2(ig)=0.
418              lmin(ig)=1    enddo
419           endif    do ig=1, ngrid
420        enddo       if (entr_star_tot(ig).LT.1.e-10) then
421  c              f(ig)=0.
422  c Determination de zw2 max       else
423        do ig=1,ngrid          do k=lmin(ig), lentr(ig)
424           wmax(ig)=0.             entr_star2(ig)=entr_star2(ig)+entr_star(ig, k)**2 &
425        enddo                  /(rho(ig, k)*(zlev(ig, k+1)-zlev(ig, k)))
426            enddo
427        do l=1,nlay          ! Nouvelle fermeture
428           do ig=1,ngrid          f(ig)=wmax(ig)/(max(500., zmax(ig))*r_aspect &
429              if (l.le.lmax(ig)) then               *entr_star2(ig))*entr_star_tot(ig)
430                  if (zw2(ig,l).lt.0.)then       endif
431                    print*,'pb2 zw2<0'    enddo
432                  endif    print *, 'apres fermeture'
433                  zw2(ig,l)=sqrt(zw2(ig,l))  
434                  wmax(ig)=max(wmax(ig),zw2(ig,l))    ! Calcul de l'entrainement
435              else    do k=1, klev
436                   zw2(ig,l)=0.       do ig=1, ngrid
437              endif          entr(ig, k)=f(ig)*entr_star(ig, k)
438            enddo       enddo
439        enddo    enddo
440      ! Calcul des flux
441  c   Longueur caracteristique correspondant a la hauteur des thermiques.    do ig=1, ngrid
442        do  ig=1,ngrid       do l=1, lmax(ig)-1
443           zmax(ig)=0.          fmc(ig, l+1)=fmc(ig, l)+entr(ig, l)
444           zlevinter(ig)=zlev(ig,1)       enddo
445        enddo    enddo
446        do  ig=1,ngrid  
447  c calcul de zlevinter    !   determination de l'indice du debut de la mixed layer ou w decroit
448            zlevinter(ig)=(zlev(ig,lmax(ig)+1)-zlev(ig,lmax(ig)))*  
449       s    linter(ig)+zlev(ig,lmax(ig))-lmax(ig)*(zlev(ig,lmax(ig)+1)    !   calcul de la largeur de chaque ascendance dans le cas conservatif.
450       s    -zlev(ig,lmax(ig)))    !   dans ce cas simple, on suppose que la largeur de l'ascendance provenant
451         zmax(ig)=max(zmax(ig),zlevinter(ig)-zlev(ig,lmin(ig)))    !   d'une couche est égale à la hauteur de la couche alimentante.
452        enddo    !   La vitesse maximale dans l'ascendance est aussi prise comme estimation
453      !   de la vitesse d'entrainement horizontal dans la couche alimentante.
454        print*,'avant fermeture'  
455  c Fermeture,determination de f    do l=2, nlay
456        do ig=1,ngrid       do ig=1, ngrid
457           entr_star2(ig)=0.          if (l.le.lmaxa(ig)) then
458        enddo             zw=max(wa_moy(ig, l), 1.e-10)
459        do ig=1,ngrid             larg_cons(ig, l)=zmax(ig)*r_aspect &
460           if (entr_star_tot(ig).LT.1.e-10) then                  *fmc(ig, l)/(rhobarz(ig, l)*zw)
461              f(ig)=0.          endif
462           else       enddo
463               do k=lmin(ig),lentr(ig)    enddo
464                  entr_star2(ig)=entr_star2(ig)+entr_star(ig,k)**2  
465       s                    /(rho(ig,k)*(zlev(ig,k+1)-zlev(ig,k)))    do l=2, nlay
466               enddo       do ig=1, ngrid
467  c Nouvelle fermeture          if (l.le.lmaxa(ig)) then
468               f(ig)=wmax(ig)/(max(500.,zmax(ig))*r_aspect             if ((l_mix*zlev(ig, l)).lt.0.)then
469       s             *entr_star2(ig))*entr_star_tot(ig)                print *, 'pb l_mix*zlev<0'
 ctest  
 c             if (first) then  
 c             f(ig)=f(ig)+(f0(ig)-f(ig))*exp(-ptimestep/zmax(ig)  
 c     s             *wmax(ig))  
 c             endif  
          endif  
 c         f0(ig)=f(ig)  
 c         first=.true.  
       enddo  
       print*,'apres fermeture'  
   
 c Calcul de l'entrainement  
        do k=1,klev  
          do ig=1,ngrid  
             entr(ig,k)=f(ig)*entr_star(ig,k)  
          enddo  
       enddo  
 c Calcul des flux  
       do ig=1,ngrid  
          do l=1,lmax(ig)-1  
             fmc(ig,l+1)=fmc(ig,l)+entr(ig,l)  
          enddo  
       enddo  
   
 cRC  
   
   
 c      print*,'9 OK convect8'  
 c     print*,'WA1 ',wa_moy  
   
 c   determination de l'indice du debut de la mixed layer ou w decroit  
   
 c   calcul de la largeur de chaque ascendance dans le cas conservatif.  
 c   dans ce cas simple, on suppose que la largeur de l'ascendance provenant  
 c   d'une couche est égale à la hauteur de la couche alimentante.  
 c   La vitesse maximale dans l'ascendance est aussi prise comme estimation  
 c   de la vitesse d'entrainement horizontal dans la couche alimentante.  
   
       do l=2,nlay  
          do ig=1,ngrid  
             if (l.le.lmaxa(ig)) then  
                zw=max(wa_moy(ig,l),1.e-10)  
                larg_cons(ig,l)=zmax(ig)*r_aspect  
      s         *fmc(ig,l)/(rhobarz(ig,l)*zw)  
             endif  
          enddo  
       enddo  
   
       do l=2,nlay  
          do ig=1,ngrid  
             if (l.le.lmaxa(ig)) then  
 c              if (idetr.eq.0) then  
 c  cette option est finalement en dur.  
                   if ((l_mix*zlev(ig,l)).lt.0.)then  
                    print*,'pb l_mix*zlev<0'  
                   endif  
                   larg_detr(ig,l)=sqrt(l_mix*zlev(ig,l))  
 c              else if (idetr.eq.1) then  
 c                 larg_detr(ig,l)=larg_cons(ig,l)  
 c    s            *sqrt(l_mix*zlev(ig,l))/larg_cons(ig,lmix(ig))  
 c              else if (idetr.eq.2) then  
 c                 larg_detr(ig,l)=sqrt(l_mix*zlev(ig,l))  
 c    s            *sqrt(wa_moy(ig,l))  
 c              else if (idetr.eq.4) then  
 c                 larg_detr(ig,l)=sqrt(l_mix*zlev(ig,l))  
 c    s            *wa_moy(ig,l)  
 c              endif  
             endif  
          enddo  
        enddo  
   
 c      print*,'10 OK convect8'  
 c     print*,'WA2 ',wa_moy  
 c   calcul de la fraction de la maille concernée par l'ascendance en tenant  
 c   compte de l'epluchage du thermique.  
 c  
 cCR def de  zmix continu (profil parabolique des vitesses)  
       do ig=1,ngrid  
            if (lmix(ig).gt.1.) then  
 c test  
               if (((zw2(ig,lmix(ig)-1)-zw2(ig,lmix(ig)))  
      s        *((zlev(ig,lmix(ig)))-(zlev(ig,lmix(ig)+1)))  
      s        -(zw2(ig,lmix(ig))-zw2(ig,lmix(ig)+1))  
      s        *((zlev(ig,lmix(ig)-1))-(zlev(ig,lmix(ig))))).gt.1e-10)  
      s        then  
 c              
             zmix(ig)=((zw2(ig,lmix(ig)-1)-zw2(ig,lmix(ig)))  
      s        *((zlev(ig,lmix(ig)))**2-(zlev(ig,lmix(ig)+1))**2)  
      s        -(zw2(ig,lmix(ig))-zw2(ig,lmix(ig)+1))  
      s        *((zlev(ig,lmix(ig)-1))**2-(zlev(ig,lmix(ig)))**2))  
      s        /(2.*((zw2(ig,lmix(ig)-1)-zw2(ig,lmix(ig)))  
      s        *((zlev(ig,lmix(ig)))-(zlev(ig,lmix(ig)+1)))  
      s        -(zw2(ig,lmix(ig))-zw2(ig,lmix(ig)+1))  
      s        *((zlev(ig,lmix(ig)-1))-(zlev(ig,lmix(ig))))))  
             else  
             zmix(ig)=zlev(ig,lmix(ig))  
             print*,'pb zmix'  
             endif  
          else  
          zmix(ig)=0.  
          endif  
 ctest  
          if ((zmax(ig)-zmix(ig)).lt.0.) then  
             zmix(ig)=0.99*zmax(ig)  
 c            print*,'pb zmix>zmax'  
          endif  
       enddo  
 c  
 c calcul du nouveau lmix correspondant  
       do ig=1,ngrid  
          do l=1,klev  
             if (zmix(ig).ge.zlev(ig,l).and.  
      s          zmix(ig).lt.zlev(ig,l+1)) then  
               lmix(ig)=l  
              endif  
           enddo  
       enddo  
 c  
       do l=2,nlay  
          do ig=1,ngrid  
             if(larg_cons(ig,l).gt.1.) then  
 c     print*,ig,l,lmix(ig),lmaxa(ig),larg_cons(ig,l),'  KKK'  
                fraca(ig,l)=(larg_cons(ig,l)-larg_detr(ig,l))  
      s            /(r_aspect*zmax(ig))  
 c test  
                fraca(ig,l)=max(fraca(ig,l),0.)  
                fraca(ig,l)=min(fraca(ig,l),0.5)  
                fracd(ig,l)=1.-fraca(ig,l)  
                fracc(ig,l)=larg_cons(ig,l)/(r_aspect*zmax(ig))  
             else  
 c              wa_moy(ig,l)=0.  
                fraca(ig,l)=0.  
                fracc(ig,l)=0.  
                fracd(ig,l)=1.  
             endif  
          enddo  
       enddo                    
 cCR: calcul de fracazmix  
        do ig=1,ngrid  
           fracazmix(ig)=(fraca(ig,lmix(ig)+1)-fraca(ig,lmix(ig)))/  
      s     (zlev(ig,lmix(ig)+1)-zlev(ig,lmix(ig)))*zmix(ig)  
      s    +fraca(ig,lmix(ig))-zlev(ig,lmix(ig))*(fraca(ig,lmix(ig)+1)  
      s    -fraca(ig,lmix(ig)))/(zlev(ig,lmix(ig)+1)-zlev(ig,lmix(ig)))  
        enddo  
 c  
        do l=2,nlay  
           do ig=1,ngrid  
              if(larg_cons(ig,l).gt.1.) then  
                if (l.gt.lmix(ig)) then  
 ctest  
                  if (zmax(ig)-zmix(ig).lt.1.e-10) then  
 c                   print*,'pb xxx'  
                    xxx(ig,l)=(lmaxa(ig)+1.-l)/(lmaxa(ig)+1.-lmix(ig))  
                  else  
                  xxx(ig,l)=(zmax(ig)-zlev(ig,l))/(zmax(ig)-zmix(ig))  
                  endif  
            if (idetr.eq.0) then  
                fraca(ig,l)=fracazmix(ig)  
            else if (idetr.eq.1) then  
                fraca(ig,l)=fracazmix(ig)*xxx(ig,l)  
            else if (idetr.eq.2) then  
                fraca(ig,l)=fracazmix(ig)*(1.-(1.-xxx(ig,l))**2)  
            else  
                fraca(ig,l)=fracazmix(ig)*xxx(ig,l)**2  
470             endif             endif
471  c     print*,ig,l,lmix(ig),lmaxa(ig),xxx(ig,l),'LLLLLLL'             larg_detr(ig, l)=sqrt(l_mix*zlev(ig, l))
472                 fraca(ig,l)=max(fraca(ig,l),0.)          endif
473                 fraca(ig,l)=min(fraca(ig,l),0.5)       enddo
474                 fracd(ig,l)=1.-fraca(ig,l)    enddo
475                 fracc(ig,l)=larg_cons(ig,l)/(r_aspect*zmax(ig))  
476               endif    !   calcul de la fraction de la maille concernée par l'ascendance en tenant
477              endif    !   compte de l'epluchage du thermique.
478           enddo  
479        enddo    !CR def de  zmix continu (profil parabolique des vitesses)
480            do ig=1, ngrid
481        print*,'fin calcul fraca'       if (lmix(ig).gt.1.) then
482  c      print*,'11 OK convect8'          if (((zw2(ig, lmix(ig)-1)-zw2(ig, lmix(ig))) &
483  c     print*,'Ea3 ',wa_moy               *((zlev(ig, lmix(ig)))-(zlev(ig, lmix(ig)+1))) &
484  c------------------------------------------------------------------               -(zw2(ig, lmix(ig))-zw2(ig, lmix(ig)+1)) &
485  c   Calcul de fracd, wd               *((zlev(ig, lmix(ig)-1))-(zlev(ig, lmix(ig))))).gt.1e-10) &
486  c   somme wa - wd = 0               then
487  c------------------------------------------------------------------  
488               zmix(ig)=((zw2(ig, lmix(ig)-1)-zw2(ig, lmix(ig))) &
489                    *((zlev(ig, lmix(ig)))**2-(zlev(ig, lmix(ig)+1))**2) &
490        do ig=1,ngrid                  -(zw2(ig, lmix(ig))-zw2(ig, lmix(ig)+1)) &
491           fm(ig,1)=0.                  *((zlev(ig, lmix(ig)-1))**2-(zlev(ig, lmix(ig)))**2)) &
492           fm(ig,nlay+1)=0.                  /(2.*((zw2(ig, lmix(ig)-1)-zw2(ig, lmix(ig))) &
493        enddo                  *((zlev(ig, lmix(ig)))-(zlev(ig, lmix(ig)+1))) &
494                    -(zw2(ig, lmix(ig))-zw2(ig, lmix(ig)+1)) &
495        do l=2,nlay                  *((zlev(ig, lmix(ig)-1))-(zlev(ig, lmix(ig))))))
496             do ig=1,ngrid          else
497                fm(ig,l)=fraca(ig,l)*wa_moy(ig,l)*rhobarz(ig,l)             zmix(ig)=zlev(ig, lmix(ig))
498  cCR:test             print *, 'pb zmix'
499                if (entr(ig,l-1).lt.1e-10.and.fm(ig,l).gt.fm(ig,l-1)          endif
500       s            .and.l.gt.lmix(ig)) then       else
501                   fm(ig,l)=fm(ig,l-1)          zmix(ig)=0.
502  c                 write(1,*)'ajustement fm, l',l       endif
503    
504         if ((zmax(ig)-zmix(ig)).lt.0.) then
505            zmix(ig)=0.99*zmax(ig)
506         endif
507      enddo
508    
509      ! calcul du nouveau lmix correspondant
510      do ig=1, ngrid
511         do l=1, klev
512            if (zmix(ig).ge.zlev(ig, l).and. &
513                 zmix(ig).lt.zlev(ig, l+1)) then
514               lmix(ig)=l
515            endif
516         enddo
517      enddo
518    
519      do l=2, nlay
520         do ig=1, ngrid
521            if(larg_cons(ig, l).gt.1.) then
522               fraca(ig, l)=(larg_cons(ig, l)-larg_detr(ig, l)) &
523                    /(r_aspect*zmax(ig))
524               fraca(ig, l)=max(fraca(ig, l), 0.)
525               fraca(ig, l)=min(fraca(ig, l), 0.5)
526               fracd(ig, l)=1.-fraca(ig, l)
527               fracc(ig, l)=larg_cons(ig, l)/(r_aspect*zmax(ig))
528            else
529               fraca(ig, l)=0.
530               fracc(ig, l)=0.
531               fracd(ig, l)=1.
532            endif
533         enddo
534      enddo
535      !CR: calcul de fracazmix
536      do ig=1, ngrid
537         fracazmix(ig)=(fraca(ig, lmix(ig)+1)-fraca(ig, lmix(ig)))/ &
538              (zlev(ig, lmix(ig)+1)-zlev(ig, lmix(ig)))*zmix(ig) &
539              +fraca(ig, lmix(ig))-zlev(ig, lmix(ig))*(fraca(ig, lmix(ig)+1) &
540              -fraca(ig, lmix(ig)))/(zlev(ig, lmix(ig)+1)-zlev(ig, lmix(ig)))
541      enddo
542    
543      do l=2, nlay
544         do ig=1, ngrid
545            if(larg_cons(ig, l).gt.1.) then
546               if (l.gt.lmix(ig)) then
547                  if (zmax(ig)-zmix(ig).lt.1.e-10) then
548                     xxx(ig, l)=(lmaxa(ig)+1.-l)/(lmaxa(ig)+1.-lmix(ig))
549                  else
550                     xxx(ig, l)=(zmax(ig)-zlev(ig, l))/(zmax(ig)-zmix(ig))
551                endif                endif
552  c              write(1,*)'ig,l,fm(ig,l)',ig,l,fm(ig,l)                if (idetr.eq.0) then
553  cRC                   fraca(ig, l)=fracazmix(ig)
554             enddo                else if (idetr.eq.1) then
555           do ig=1,ngrid                   fraca(ig, l)=fracazmix(ig)*xxx(ig, l)
556              if(fracd(ig,l).lt.0.1) then                else if (idetr.eq.2) then
557                 stop'fracd trop petit'                   fraca(ig, l)=fracazmix(ig)*(1.-(1.-xxx(ig, l))**2)
558              else                else
559  c    vitesse descendante "diagnostique"                   fraca(ig, l)=fracazmix(ig)*xxx(ig, l)**2
560                 wd(ig,l)=fm(ig,l)/(fracd(ig,l)*rhobarz(ig,l))                endif
561              endif                fraca(ig, l)=max(fraca(ig, l), 0.)
562           enddo                fraca(ig, l)=min(fraca(ig, l), 0.5)
563        enddo                fracd(ig, l)=1.-fraca(ig, l)
564                  fracc(ig, l)=larg_cons(ig, l)/(r_aspect*zmax(ig))
565        do l=1,nlay             endif
566           do ig=1,ngrid          endif
567  c           masse(ig,l)=rho(ig,l)*(zlev(ig,l+1)-zlev(ig,l))       enddo
568              masse(ig,l)=(pplev(ig,l)-pplev(ig,l+1))/RG    enddo
569           enddo  
570        enddo    print *, 'fin calcul fraca'
571    
572        print*,'12 OK convect8'    !   Calcul de fracd, wd
573  c     print*,'WA4 ',wa_moy    !   somme wa - wd = 0
574  cc------------------------------------------------------------------  
575  c   calcul du transport vertical    do ig=1, ngrid
576  c------------------------------------------------------------------       fm(ig, 1)=0.
577         fm(ig, nlay+1)=0.
578        go to 4444    enddo
579  c     print*,'XXXXXXXXXXXXXXX ptimestep= ',ptimestep  
580        do l=2,nlay-1    do l=2, nlay
581           do ig=1,ngrid       do ig=1, ngrid
582              if(fm(ig,l+1)*ptimestep.gt.masse(ig,l)          fm(ig, l)=fraca(ig, l)*wa_moy(ig, l)*rhobarz(ig, l)
583       s      .and.fm(ig,l+1)*ptimestep.gt.masse(ig,l+1)) then          if (entr(ig, l-1).lt.1e-10.and.fm(ig, l).gt.fm(ig, l-1) &
584  c     print*,'WARN!!! FM>M ig=',ig,' l=',l,'  FM='               .and.l.gt.lmix(ig)) then
585  c    s         ,fm(ig,l+1)*ptimestep             fm(ig, l)=fm(ig, l-1)
586  c    s         ,'   M=',masse(ig,l),masse(ig,l+1)          endif
587               endif       enddo
588           enddo       do ig=1, ngrid
589        enddo          if(fracd(ig, l).lt.0.1) then
590               stop'fracd trop petit'
591        do l=1,nlay          else
592           do ig=1,ngrid             !    vitesse descendante "diagnostique"
593              if(entr(ig,l)*ptimestep.gt.masse(ig,l)) then             wd(ig, l)=fm(ig, l)/(fracd(ig, l)*rhobarz(ig, l))
594  c     print*,'WARN!!! E>M ig=',ig,' l=',l,'  E=='          endif
595  c    s         ,entr(ig,l)*ptimestep       enddo
596  c    s         ,'   M=',masse(ig,l)    enddo
597               endif  
598           enddo    do l=1, nlay
599        enddo       do ig=1, ngrid
600            masse(ig, l)=(pplev(ig, l)-pplev(ig, l+1))/RG
601        do l=1,nlay       enddo
602           do ig=1,ngrid    enddo
603              if(.not.fm(ig,l).ge.0..or..not.fm(ig,l).le.10.) then  
604  c     print*,'WARN!!! fm exagere ig=',ig,'   l=',l    print *, '12 OK convect8'
605  c    s         ,'   FM=',fm(ig,l)  
606              endif    !   calcul du transport vertical
607              if(.not.masse(ig,l).ge.1.e-10  
608       s         .or..not.masse(ig,l).le.1.e4) then    !CR:redefinition du entr
609              endif    do l=1, nlay
610              if(.not.entr(ig,l).ge.0..or..not.entr(ig,l).le.10.) then       do ig=1, ngrid
611  c     print*,'WARN!!! entr exagere ig=',ig,'   l=',l          detr(ig, l)=fm(ig, l)+entr(ig, l)-fm(ig, l+1)
612  c    s         ,'   E=',entr(ig,l)          if (detr(ig, l).lt.0.) then
613              endif             entr(ig, l)=entr(ig, l)-detr(ig, l)
614           enddo             detr(ig, l)=0.
615        enddo          endif
616         enddo
617  4444   continue    enddo
618    
619  cCR:redefinition du entr    if (w2di.eq.1) then
620         do l=1,nlay       fm0=fm0+ptimestep*(fm-fm0)/float(tho)
621           do ig=1,ngrid       entr0=entr0+ptimestep*(entr-entr0)/float(tho)
622              detr(ig,l)=fm(ig,l)+entr(ig,l)-fm(ig,l+1)    else
623              if (detr(ig,l).lt.0.) then       fm0=fm
624                  entr(ig,l)=entr(ig,l)-detr(ig,l)       entr0=entr
625                  detr(ig,l)=0.    endif
626  c     print*,'WARNING !!! detrainement negatif ',ig,l  
627              endif    if (1.eq.1) then
628           enddo       call dqthermcell(ngrid, nlay, ptimestep, fm0, entr0, masse &
629        enddo            , zh, zdhadj, zha)
630  cRC       call dqthermcell(ngrid, nlay, ptimestep, fm0, entr0, masse &
631        if (w2di.eq.1) then            , zo, pdoadj, zoa)
632           fm0=fm0+ptimestep*(fm-fm0)/float(tho)    else
633           entr0=entr0+ptimestep*(entr-entr0)/float(tho)       call dqthermcell2(ngrid, nlay, ptimestep, fm0, entr0, masse, fraca &
634        else            , zh, zdhadj, zha)
635           fm0=fm       call dqthermcell2(ngrid, nlay, ptimestep, fm0, entr0, masse, fraca &
636           entr0=entr            , zo, pdoadj, zoa)
637        endif    endif
638    
639        if (1.eq.1) then    if (1.eq.0) then
640           call dqthermcell(ngrid,nlay,ptimestep,fm0,entr0,masse       call dvthermcell2(ngrid, nlay, ptimestep, fm0, entr0, masse &
641       .    ,zh,zdhadj,zha)            , fraca, zmax &
642           call dqthermcell(ngrid,nlay,ptimestep,fm0,entr0,masse            , zu, zv, pduadj, pdvadj, zua, zva)
643       .    ,zo,pdoadj,zoa)    else
644        else       call dqthermcell(ngrid, nlay, ptimestep, fm0, entr0, masse &
645           call dqthermcell2(ngrid,nlay,ptimestep,fm0,entr0,masse,fraca            , zu, pduadj, zua)
646       .    ,zh,zdhadj,zha)       call dqthermcell(ngrid, nlay, ptimestep, fm0, entr0, masse &
647           call dqthermcell2(ngrid,nlay,ptimestep,fm0,entr0,masse,fraca            , zv, pdvadj, zva)
648       .    ,zo,pdoadj,zoa)    endif
649        endif  
650      do l=1, nlay
651        if (1.eq.0) then       do ig=1, ngrid
652           call dvthermcell2(ngrid,nlay,ptimestep,fm0,entr0,masse          zf=0.5*(fracc(ig, l)+fracc(ig, l+1))
653       .    ,fraca,zmax          zf2=zf/(1.-zf)
654       .    ,zu,zv,pduadj,pdvadj,zua,zva)          thetath2(ig, l)=zf2*(zha(ig, l)-zh(ig, l))**2
655        else          wth2(ig, l)=zf2*(0.5*(wa_moy(ig, l)+wa_moy(ig, l+1)))**2
656           call dqthermcell(ngrid,nlay,ptimestep,fm0,entr0,masse       enddo
657       .    ,zu,pduadj,zua)    enddo
658           call dqthermcell(ngrid,nlay,ptimestep,fm0,entr0,masse  
659       .    ,zv,pdvadj,zva)    do l=1, nlay
660        endif       do ig=1, ngrid
661            pdtadj(ig, l)=zdhadj(ig, l)*zpspsk(ig, l)
662        do l=1,nlay       enddo
663           do ig=1,ngrid    enddo
664              zf=0.5*(fracc(ig,l)+fracc(ig,l+1))  
665              zf2=zf/(1.-zf)    print *, '14 OK convect8'
666              thetath2(ig,l)=zf2*(zha(ig,l)-zh(ig,l))**2  
667              wth2(ig,l)=zf2*(0.5*(wa_moy(ig,l)+wa_moy(ig,l+1)))**2    !   Calculs pour les sorties
668           enddo  
669        enddo    if(sorties) then
670         do l=1, nlay
671            do ig=1, ngrid
672               zla(ig, l)=(1.-fracd(ig, l))*zmax(ig)
673  c     print*,'13 OK convect8'             zld(ig, l)=fracd(ig, l)*zmax(ig)
674  c     print*,'WA5 ',wa_moy             if(1.-fracd(ig, l).gt.1.e-10) &
675        do l=1,nlay                  zwa(ig, l)=wd(ig, l)*fracd(ig, l)/(1.-fracd(ig, l))
676           do ig=1,ngrid          enddo
677              pdtadj(ig,l)=zdhadj(ig,l)*zpspsk(ig,l)       enddo
678           enddo  
679        enddo       isplit=isplit+1
680      endif
681    
682  c     do l=1,nlay    print *, '19 OK convect8'
 c        do ig=1,ngrid  
 c           if(abs(pdtadj(ig,l))*86400..gt.500.) then  
 c     print*,'WARN!!! ig=',ig,'  l=',l  
 c    s         ,'   pdtadj=',pdtadj(ig,l)  
 c           endif  
 c           if(abs(pdoadj(ig,l))*86400..gt.1.) then  
 c     print*,'WARN!!! ig=',ig,'  l=',l  
 c    s         ,'   pdoadj=',pdoadj(ig,l)  
 c           endif  
 c        enddo  
 c      enddo  
   
       print*,'14 OK convect8'  
 c------------------------------------------------------------------  
 c   Calculs pour les sorties  
 c------------------------------------------------------------------  
   
       if(sorties) then  
       do l=1,nlay  
          do ig=1,ngrid  
             zla(ig,l)=(1.-fracd(ig,l))*zmax(ig)  
             zld(ig,l)=fracd(ig,l)*zmax(ig)  
             if(1.-fracd(ig,l).gt.1.e-10)  
      s      zwa(ig,l)=wd(ig,l)*fracd(ig,l)/(1.-fracd(ig,l))  
          enddo  
       enddo  
   
 cdeja fait  
 c      do l=1,nlay  
 c         do ig=1,ngrid  
 c            detr(ig,l)=fm(ig,l)+entr(ig,l)-fm(ig,l+1)  
 c            if (detr(ig,l).lt.0.) then  
 c                entr(ig,l)=entr(ig,l)-detr(ig,l)  
 c                detr(ig,l)=0.  
 c     print*,'WARNING !!! detrainement negatif ',ig,l  
 c            endif  
 c         enddo  
 c      enddo  
   
 c     print*,'15 OK convect8'  
   
       isplit=isplit+1  
   
   
         goto 123  
 123   continue  
   
       endif  
   
 c     if(wa_moy(1,4).gt.1.e-10) stop  
   
       print*,'19 OK convect8'  
       return  
       end  
   
       subroutine dqthermcell(ngrid,nlay,ptimestep,fm,entr,masse  
      .    ,q,dq,qa)  
       use dimens_m  
       use dimphy  
       implicit none  
   
 c=======================================================================  
 c  
 c   Calcul du transport verticale dans la couche limite en presence  
 c   de "thermiques" explicitement representes  
 c   calcul du dq/dt une fois qu'on connait les ascendances  
 c  
 c=======================================================================  
   
   
       integer ngrid,nlay  
   
       real ptimestep  
       real, intent(in):: masse(ngrid,nlay)  
       real fm(ngrid,nlay+1)  
       real entr(ngrid,nlay)  
       real q(ngrid,nlay)  
       real dq(ngrid,nlay)  
   
       real qa(klon,klev),detr(klon,klev),wqd(klon,klev+1)  
   
       integer ig,k  
   
 c   calcul du detrainement  
   
       do k=1,nlay  
          do ig=1,ngrid  
             detr(ig,k)=fm(ig,k)-fm(ig,k+1)+entr(ig,k)  
          enddo  
       enddo  
   
 c   calcul de la valeur dans les ascendances  
       do ig=1,ngrid  
          qa(ig,1)=q(ig,1)  
       enddo  
   
       do k=2,nlay  
          do ig=1,ngrid  
             if ((fm(ig,k+1)+detr(ig,k))*ptimestep.gt.  
      s         1.e-5*masse(ig,k)) then  
                qa(ig,k)=(fm(ig,k)*qa(ig,k-1)+entr(ig,k)*q(ig,k))  
      s         /(fm(ig,k+1)+detr(ig,k))  
             else  
                qa(ig,k)=q(ig,k)  
             endif  
          enddo  
       enddo  
   
       do k=2,nlay  
          do ig=1,ngrid  
 c             wqd(ig,k)=fm(ig,k)*0.5*(q(ig,k-1)+q(ig,k))  
             wqd(ig,k)=fm(ig,k)*q(ig,k)  
          enddo  
       enddo  
       do ig=1,ngrid  
          wqd(ig,1)=0.  
          wqd(ig,nlay+1)=0.  
       enddo  
   
       do k=1,nlay  
          do ig=1,ngrid  
             dq(ig,k)=(detr(ig,k)*qa(ig,k)-entr(ig,k)*q(ig,k)  
      s               -wqd(ig,k)+wqd(ig,k+1))  
      s               /masse(ig,k)  
          enddo  
       enddo  
   
       return  
       end  
   
       subroutine dqthermcell2(ngrid,nlay,ptimestep,fm,entr,masse,frac  
      .    ,q,dq,qa)  
       use dimens_m  
       use dimphy  
       implicit none  
   
 c=======================================================================  
 c  
 c   Calcul du transport verticale dans la couche limite en presence  
 c   de "thermiques" explicitement representes  
 c   calcul du dq/dt une fois qu'on connait les ascendances  
 c  
 c=======================================================================  
   
   
       integer ngrid,nlay  
   
       real ptimestep  
       real masse(ngrid,nlay),fm(ngrid,nlay+1)  
       real entr(ngrid,nlay),frac(ngrid,nlay)  
       real q(ngrid,nlay)  
       real dq(ngrid,nlay)  
   
       real qa(klon,klev),detr(klon,klev),wqd(klon,klev+1)  
       real qe(klon,klev),zf,zf2  
   
       integer ig,k  
   
 c   calcul du detrainement  
   
       do k=1,nlay  
          do ig=1,ngrid  
             detr(ig,k)=fm(ig,k)-fm(ig,k+1)+entr(ig,k)  
          enddo  
       enddo  
   
 c   calcul de la valeur dans les ascendances  
       do ig=1,ngrid  
          qa(ig,1)=q(ig,1)  
          qe(ig,1)=q(ig,1)  
       enddo  
   
       do k=2,nlay  
          do ig=1,ngrid  
             if ((fm(ig,k+1)+detr(ig,k))*ptimestep.gt.  
      s         1.e-5*masse(ig,k)) then  
                zf=0.5*(frac(ig,k)+frac(ig,k+1))  
                zf2=1./(1.-zf)  
                qa(ig,k)=(fm(ig,k)*qa(ig,k-1)+zf2*entr(ig,k)*q(ig,k))  
      s         /(fm(ig,k+1)+detr(ig,k)+entr(ig,k)*zf*zf2)  
                qe(ig,k)=(q(ig,k)-zf*qa(ig,k))*zf2  
             else  
                qa(ig,k)=q(ig,k)  
                qe(ig,k)=q(ig,k)  
             endif  
          enddo  
       enddo  
   
       do k=2,nlay  
          do ig=1,ngrid  
 c             wqd(ig,k)=fm(ig,k)*0.5*(q(ig,k-1)+q(ig,k))  
             wqd(ig,k)=fm(ig,k)*qe(ig,k)  
          enddo  
       enddo  
       do ig=1,ngrid  
          wqd(ig,1)=0.  
          wqd(ig,nlay+1)=0.  
       enddo  
   
       do k=1,nlay  
          do ig=1,ngrid  
             dq(ig,k)=(detr(ig,k)*qa(ig,k)-entr(ig,k)*qe(ig,k)  
      s               -wqd(ig,k)+wqd(ig,k+1))  
      s               /masse(ig,k)  
          enddo  
       enddo  
   
       return  
       end  
       subroutine dvthermcell2(ngrid,nlay,ptimestep,fm,entr,masse  
      .    ,fraca,larga  
      .    ,u,v,du,dv,ua,va)  
       use dimens_m  
       use dimphy  
       implicit none  
   
 c=======================================================================  
 c  
 c   Calcul du transport verticale dans la couche limite en presence  
 c   de "thermiques" explicitement representes  
 c   calcul du dq/dt une fois qu'on connait les ascendances  
 c  
 c=======================================================================  
   
   
       integer ngrid,nlay  
   
       real ptimestep  
       real masse(ngrid,nlay),fm(ngrid,nlay+1)  
       real fraca(ngrid,nlay+1)  
       real larga(ngrid)  
       real entr(ngrid,nlay)  
       real u(ngrid,nlay)  
       real ua(ngrid,nlay)  
       real du(ngrid,nlay)  
       real v(ngrid,nlay)  
       real va(ngrid,nlay)  
       real dv(ngrid,nlay)  
   
       real qa(klon,klev),detr(klon,klev),zf,zf2  
       real wvd(klon,klev+1),wud(klon,klev+1)  
       real gamma0,gamma(klon,klev+1)  
       real ue(klon,klev),ve(klon,klev)  
       real dua,dva  
       integer iter  
   
       integer ig,k  
   
 c   calcul du detrainement  
   
       do k=1,nlay  
          do ig=1,ngrid  
             detr(ig,k)=fm(ig,k)-fm(ig,k+1)+entr(ig,k)  
          enddo  
       enddo  
   
 c   calcul de la valeur dans les ascendances  
       do ig=1,ngrid  
          ua(ig,1)=u(ig,1)  
          va(ig,1)=v(ig,1)  
          ue(ig,1)=u(ig,1)  
          ve(ig,1)=v(ig,1)  
       enddo  
   
       do k=2,nlay  
          do ig=1,ngrid  
             if ((fm(ig,k+1)+detr(ig,k))*ptimestep.gt.  
      s         1.e-5*masse(ig,k)) then  
 c   On itère sur la valeur du coeff de freinage.  
 c              gamma0=rho(ig,k)*(zlev(ig,k+1)-zlev(ig,k))  
                gamma0=masse(ig,k)  
      s         *sqrt( 0.5*(fraca(ig,k+1)+fraca(ig,k)) )  
      s         *0.5/larga(ig)  
      s         *1.  
 c    s         *0.5  
 c              gamma0=0.  
                zf=0.5*(fraca(ig,k)+fraca(ig,k+1))  
                zf=0.  
                zf2=1./(1.-zf)  
 c   la première fois on multiplie le coefficient de freinage  
 c   par le module du vent dans la couche en dessous.  
                dua=ua(ig,k-1)-u(ig,k-1)  
                dva=va(ig,k-1)-v(ig,k-1)  
                do iter=1,5  
 c   On choisit une relaxation lineaire.  
                   gamma(ig,k)=gamma0  
 c   On choisit une relaxation quadratique.  
                   gamma(ig,k)=gamma0*sqrt(dua**2+dva**2)  
                   ua(ig,k)=(fm(ig,k)*ua(ig,k-1)  
      s               +(zf2*entr(ig,k)+gamma(ig,k))*u(ig,k))  
      s               /(fm(ig,k+1)+detr(ig,k)+entr(ig,k)*zf*zf2  
      s                 +gamma(ig,k))  
                   va(ig,k)=(fm(ig,k)*va(ig,k-1)  
      s               +(zf2*entr(ig,k)+gamma(ig,k))*v(ig,k))  
      s               /(fm(ig,k+1)+detr(ig,k)+entr(ig,k)*zf*zf2  
      s                 +gamma(ig,k))  
 c                 print*,k,ua(ig,k),va(ig,k),u(ig,k),v(ig,k),dua,dva  
                   dua=ua(ig,k)-u(ig,k)  
                   dva=va(ig,k)-v(ig,k)  
                   ue(ig,k)=(u(ig,k)-zf*ua(ig,k))*zf2  
                   ve(ig,k)=(v(ig,k)-zf*va(ig,k))*zf2  
                enddo  
             else  
                ua(ig,k)=u(ig,k)  
                va(ig,k)=v(ig,k)  
                ue(ig,k)=u(ig,k)  
                ve(ig,k)=v(ig,k)  
                gamma(ig,k)=0.  
             endif  
          enddo  
       enddo  
   
       do k=2,nlay  
          do ig=1,ngrid  
             wud(ig,k)=fm(ig,k)*ue(ig,k)  
             wvd(ig,k)=fm(ig,k)*ve(ig,k)  
          enddo  
       enddo  
       do ig=1,ngrid  
          wud(ig,1)=0.  
          wud(ig,nlay+1)=0.  
          wvd(ig,1)=0.  
          wvd(ig,nlay+1)=0.  
       enddo  
   
       do k=1,nlay  
          do ig=1,ngrid  
             du(ig,k)=((detr(ig,k)+gamma(ig,k))*ua(ig,k)  
      s               -(entr(ig,k)+gamma(ig,k))*ue(ig,k)  
      s               -wud(ig,k)+wud(ig,k+1))  
      s               /masse(ig,k)  
             dv(ig,k)=((detr(ig,k)+gamma(ig,k))*va(ig,k)  
      s               -(entr(ig,k)+gamma(ig,k))*ve(ig,k)  
      s               -wvd(ig,k)+wvd(ig,k+1))  
      s               /masse(ig,k)  
          enddo  
       enddo  
683    
684        return  end SUBROUTINE thermcell
       end  

Legend:
Removed from v.38  
changed lines
  Added in v.52

  ViewVC Help
Powered by ViewVC 1.1.21