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

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

  ViewVC Help
Powered by ViewVC 1.1.21