/[lmdze]/trunk/dyn3d/vlspltqs.f
ViewVC logotype

Diff of /trunk/dyn3d/vlspltqs.f

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

trunk/libf/dyn3d/vlspltqs.f revision 10 by guez, Fri Apr 18 14:45:53 2008 UTC trunk/dyn3d/vlspltqs.f revision 254 by guez, Mon Feb 5 10:39:38 2018 UTC
# Line 1  Line 1 
1  !  module vlspltqs_m
 ! $Header: /home/cvsroot/LMDZ4/libf/dyn3d/vlspltqs.F,v 1.2 2005/02/24 12:16:57 fairhead Exp $  
 !  
        SUBROUTINE vlspltqs ( q,pente_max,masse,w,pbaru,pbarv,pdt,  
      ,                                  p,pk,teta                 )  
 c  
 c     Auteurs:   P.Le Van, F.Hourdin, F.Forget, F.Codron  
 c  
 c    ********************************************************************  
 c          Shema  d'advection " pseudo amont " .  
 c      + test sur humidite specifique: Q advecte< Qsat aval  
 c                   (F. Codron, 10/99)  
 c    ********************************************************************  
 c     q,pbaru,pbarv,w sont des arguments d'entree  pour le s-pg ....  
 c  
 c     pente_max facteur de limitation des pentes: 2 en general  
 c                                                0 pour un schema amont  
 c     pbaru,pbarv,w flux de masse en u ,v ,w  
 c     pdt pas de temps  
 c  
 c     teta temperature potentielle, p pression aux interfaces,  
 c     pk exner au milieu des couches necessaire pour calculer Qsat  
 c   --------------------------------------------------------------------  
       use dimens_m  
       use paramet_m  
       use comconst  
       use comvert  
       use logic  
       IMPLICIT NONE  
 c  
   
 c  
 c   Arguments:  
 c   ----------  
       REAL masse(ip1jmp1,llm),pente_max  
       REAL pbaru( ip1jmp1,llm ),pbarv( ip1jm,llm)  
       REAL q(ip1jmp1,llm)  
       REAL w(ip1jmp1,llm),pdt  
       REAL, intent(in):: p(ip1jmp1,llmp1)  
       real teta(ip1jmp1,llm),pk(ip1jmp1,llm)  
 c  
 c      Local  
 c   ---------  
 c  
       INTEGER i,ij,l,j,ii  
 c  
       REAL qsat(ip1jmp1,llm)  
       REAL zm(ip1jmp1,llm)  
       REAL mu(ip1jmp1,llm)  
       REAL mv(ip1jm,llm)  
       REAL mw(ip1jmp1,llm+1)  
       REAL zq(ip1jmp1,llm)  
       REAL temps1,temps2,temps3  
       REAL zzpbar, zzw  
       LOGICAL testcpu  
       SAVE testcpu  
       SAVE temps1,temps2,temps3  
   
       REAL qmin,qmax  
       DATA qmin,qmax/0.,1.e33/  
       DATA testcpu/.false./  
       DATA temps1,temps2,temps3/0.,0.,0./  
   
 c--pour rapport de melange saturant--  
   
       REAL rtt,retv,r2es,r3les,r3ies,r4les,r4ies,play  
       REAL ptarg,pdelarg,foeew,zdelta  
       REAL tempe(ip1jmp1)  
   
 c    fonction psat(T)  
   
        FOEEW ( PTARG,PDELARG ) = EXP (  
      *          (R3LES*(1.-PDELARG)+R3IES*PDELARG) * (PTARG-RTT)  
      * / (PTARG-(R4LES*(1.-PDELARG)+R4IES*PDELARG)) )  
   
         r2es  = 380.11733  
         r3les = 17.269  
         r3ies = 21.875  
         r4les = 35.86  
         r4ies = 7.66  
         retv = 0.6077667  
         rtt  = 273.16  
   
 c-- Calcul de Qsat en chaque point  
 c-- approximation: au milieu des couches play(l)=(p(l)+p(l+1))/2  
 c   pour eviter une exponentielle.  
         DO l = 1, llm  
          DO ij = 1, ip1jmp1  
           tempe(ij) = teta(ij,l) * pk(ij,l) /cpp  
          ENDDO  
          DO ij = 1, ip1jmp1  
           zdelta = MAX( 0., SIGN(1., rtt - tempe(ij)) )  
           play   = 0.5*(p(ij,l)+p(ij,l+1))  
           qsat(ij,l) = MIN(0.5, r2es* FOEEW(tempe(ij),zdelta) / play )  
           qsat(ij,l) = qsat(ij,l) / ( 1. - retv * qsat(ij,l) )  
          ENDDO  
         ENDDO  
   
 c      PRINT*,'Debut vlsplt version debug sans vlyqs'  
   
         zzpbar = 0.5 * pdt  
         zzw    = pdt  
       DO l=1,llm  
         DO ij = iip2,ip1jm  
             mu(ij,l)=pbaru(ij,l) * zzpbar  
          ENDDO  
          DO ij=1,ip1jm  
             mv(ij,l)=pbarv(ij,l) * zzpbar  
          ENDDO  
          DO ij=1,ip1jmp1  
             mw(ij,l)=w(ij,l) * zzw  
          ENDDO  
       ENDDO  
   
       DO ij=1,ip1jmp1  
          mw(ij,llm+1)=0.  
       ENDDO  
   
       CALL SCOPY(ijp1llm,q,1,zq,1)  
       CALL SCOPY(ijp1llm,masse,1,zm,1)  
   
 c      call minmaxq(zq,qmin,qmax,'avant vlxqs     ')  
       call vlxqs(zq,pente_max,zm,mu,qsat)  
   
   
 c     call minmaxq(zq,qmin,qmax,'avant vlyqs     ')  
   
       call vlyqs(zq,pente_max,zm,mv,qsat)  
   
   
 c      call minmaxq(zq,qmin,qmax,'avant vlz     ')  
   
       call vlz(zq,pente_max,zm,mw)  
   
   
 c     call minmaxq(zq,qmin,qmax,'avant vlyqs     ')  
 c     call minmaxq(zm,qmin,qmax,'M avant vlyqs     ')  
   
       call vlyqs(zq,pente_max,zm,mv,qsat)  
   
   
 c     call minmaxq(zq,qmin,qmax,'avant vlxqs     ')  
 c     call minmaxq(zm,qmin,qmax,'M avant vlxqs     ')  
   
       call vlxqs(zq,pente_max,zm,mu,qsat)  
   
 c     call minmaxq(zq,qmin,qmax,'apres vlxqs     ')  
 c     call minmaxq(zm,qmin,qmax,'M apres vlxqs     ')  
   
   
       DO l=1,llm  
          DO ij=1,ip1jmp1  
            q(ij,l)=zq(ij,l)  
          ENDDO  
          DO ij=1,ip1jm+1,iip1  
             q(ij+iim,l)=q(ij,l)  
          ENDDO  
       ENDDO  
   
       RETURN  
       END  
       SUBROUTINE vlxqs(q,pente_max,masse,u_m,qsat)  
 c  
 c     Auteurs:   P.Le Van, F.Hourdin, F.Forget  
 c  
 c    ********************************************************************  
 c     Shema  d'advection " pseudo amont " .  
 c    ********************************************************************  
 c  
 c   --------------------------------------------------------------------  
       use dimens_m  
       use paramet_m  
       use comconst  
       use comvert  
       use logic  
       IMPLICIT NONE  
 c  
 c  
 c  
 c   Arguments:  
 c   ----------  
       REAL masse(ip1jmp1,llm),pente_max  
       REAL u_m( ip1jmp1,llm )  
       REAL q(ip1jmp1,llm)  
       REAL qsat(ip1jmp1,llm)  
 c  
 c      Local  
 c   ---------  
 c  
       INTEGER ij,l,j,i,iju,ijq,indu(ip1jmp1),niju  
       INTEGER n0,iadvplus(ip1jmp1,llm),nl(llm)  
 c  
       REAL new_m,zu_m,zdum(ip1jmp1,llm)  
       REAL dxq(ip1jmp1,llm),dxqu(ip1jmp1)  
       REAL zz(ip1jmp1)  
       REAL adxqu(ip1jmp1),dxqmax(ip1jmp1,llm)  
       REAL u_mq(ip1jmp1,llm)  
   
       Logical first,testcpu  
       SAVE first,testcpu  
   
       REAL      SSUM  
       REAL temps0,temps1,temps2,temps3,temps4,temps5  
       SAVE temps0,temps1,temps2,temps3,temps4,temps5  
   
   
       DATA first,testcpu/.true.,.false./  
   
       IF(first) THEN  
          temps1=0.  
          temps2=0.  
          temps3=0.  
          temps4=0.  
          temps5=0.  
          first=.false.  
       ENDIF  
   
 c   calcul de la pente a droite et a gauche de la maille  
   
   
       IF (pente_max.gt.-1.e-5) THEN  
 c     IF (pente_max.gt.10) THEN  
   
 c   calcul des pentes avec limitation, Van Leer scheme I:  
 c   -----------------------------------------------------  
   
 c   calcul de la pente aux points u  
          DO l = 1, llm  
             DO ij=iip2,ip1jm-1  
                dxqu(ij)=q(ij+1,l)-q(ij,l)  
 c              IF(u_m(ij,l).lt.0.) stop'limx n admet pas les U<0'  
 c              sigu(ij)=u_m(ij,l)/masse(ij,l)  
             ENDDO  
             DO ij=iip1+iip1,ip1jm,iip1  
                dxqu(ij)=dxqu(ij-iim)  
 c              sigu(ij)=sigu(ij-iim)  
             ENDDO  
   
             DO ij=iip2,ip1jm  
                adxqu(ij)=abs(dxqu(ij))  
             ENDDO  
   
 c   calcul de la pente maximum dans la maille en valeur absolue  
   
             DO ij=iip2+1,ip1jm  
                dxqmax(ij,l)=pente_max*  
      ,      min(adxqu(ij-1),adxqu(ij))  
 c limitation subtile  
 c    ,      min(adxqu(ij-1)/sigu(ij-1),adxqu(ij)/(1.-sigu(ij)))  
             
   
             ENDDO  
   
             DO ij=iip1+iip1,ip1jm,iip1  
                dxqmax(ij-iim,l)=dxqmax(ij,l)  
             ENDDO  
   
             DO ij=iip2+1,ip1jm  
                IF(dxqu(ij-1)*dxqu(ij).gt.0) THEN  
                   dxq(ij,l)=dxqu(ij-1)+dxqu(ij)  
                ELSE  
 c   extremum local  
                   dxq(ij,l)=0.  
                ENDIF  
                dxq(ij,l)=0.5*dxq(ij,l)  
                dxq(ij,l)=  
      ,         sign(min(abs(dxq(ij,l)),dxqmax(ij,l)),dxq(ij,l))  
             ENDDO  
   
          ENDDO ! l=1,llm  
   
       ELSE ! (pente_max.lt.-1.e-5)  
   
 c   Pentes produits:  
 c   ----------------  
   
          DO l = 1, llm  
             DO ij=iip2,ip1jm-1  
                dxqu(ij)=q(ij+1,l)-q(ij,l)  
             ENDDO  
             DO ij=iip1+iip1,ip1jm,iip1  
                dxqu(ij)=dxqu(ij-iim)  
             ENDDO  
   
             DO ij=iip2+1,ip1jm  
                zz(ij)=dxqu(ij-1)*dxqu(ij)  
                zz(ij)=zz(ij)+zz(ij)  
                IF(zz(ij).gt.0) THEN  
                   dxq(ij,l)=zz(ij)/(dxqu(ij-1)+dxqu(ij))  
                ELSE  
 c   extremum local  
                   dxq(ij,l)=0.  
                ENDIF  
             ENDDO  
   
          ENDDO  
   
       ENDIF ! (pente_max.lt.-1.e-5)  
   
 c   bouclage de la pente en iip1:  
 c   -----------------------------  
   
       DO l=1,llm  
          DO ij=iip1+iip1,ip1jm,iip1  
             dxq(ij-iim,l)=dxq(ij,l)  
          ENDDO  
   
          DO ij=1,ip1jmp1  
             iadvplus(ij,l)=0  
          ENDDO  
   
       ENDDO  
   
   
 c   calcul des flux a gauche et a droite  
   
 c   on cumule le flux correspondant a toutes les mailles dont la masse  
 c   au travers de la paroi pENDant le pas de temps.  
 c   le rapport de melange de l'air advecte est min(q_vanleer, Qsat_downwind)  
       DO l=1,llm  
        DO ij=iip2,ip1jm-1  
           IF (u_m(ij,l).gt.0.) THEN  
              zdum(ij,l)=1.-u_m(ij,l)/masse(ij,l)  
              u_mq(ij,l)=u_m(ij,l)*  
      $         min(q(ij,l)+0.5*zdum(ij,l)*dxq(ij,l),qsat(ij+1,l))  
           ELSE  
              zdum(ij,l)=1.+u_m(ij,l)/masse(ij+1,l)  
              u_mq(ij,l)=u_m(ij,l)*  
      $         min(q(ij+1,l)-0.5*zdum(ij,l)*dxq(ij+1,l),qsat(ij,l))  
           ENDIF  
        ENDDO  
       ENDDO  
2    
3      IMPLICIT NONE
4    
5  c   detection des points ou on advecte plus que la masse de la  contains
6  c   maille  
7        DO l=1,llm    SUBROUTINE vlspltqs(q, pente_max, masse, w, pbaru, pbarv, pdt, p, pk, teta)
8           DO ij=iip2,ip1jm-1  
9              IF(zdum(ij,l).lt.0) THEN      ! From LMDZ4/libf/dyn3d/vlspltqs.F, version 1.2 2005/02/24 12:16:57 fairhead
10                 iadvplus(ij,l)=1  
11                 u_mq(ij,l)=0.      ! Authors: P. Le Van, F. Hourdin, F. Forget, F. Codron
12              ENDIF  
13           ENDDO      ! Schéma d'advection "pseudo amont"
14        ENDDO      ! + test sur humidité spécifique : Q advecté < Qsat aval
15        DO l=1,llm      ! (F. Codron, 10/99)
16         DO ij=iip1+iip1,ip1jm,iip1  
17            iadvplus(ij,l)=iadvplus(ij-iim,l)      ! q, pbaru, pbarv, w sont des arguments d'entree pour le sous-programme
18         ENDDO  
19        ENDDO      ! pente_max facteur de limitation des pentes: 2 en général
20        ! 0 pour un schéma amont
21        ! pbaru, pbarv, w flux de masse en u , v , w
22        ! pdt pas de temps
23    
24        ! teta température potentielle, p pression aux interfaces,
25        ! pk exner au milieu des couches nécessaire pour calculer Qsat
26    
27        USE dimens_m, ONLY : iim, llm
28        use FCTTRE, only: foeew
29        USE paramet_m, ONLY : iip1, iip2, ijp1llm, ip1jm, ip1jmp1, llmp1
30        USE comconst, ONLY : cpp
31        use SUPHEC_M, only: rtt
32    
33        ! Arguments:
34    
35        REAL masse(ip1jmp1, llm), pente_max
36        REAL, intent(in):: pbaru(ip1jmp1, llm), pbarv(ip1jm, llm)
37        REAL q(ip1jmp1, llm)
38        REAL w(ip1jmp1, llm)
39        real, intent(in):: pdt
40        REAL, intent(in):: p(ip1jmp1, llmp1)
41        real, intent(in):: teta(ip1jmp1, llm)
42        real, intent(in):: pk(ip1jmp1, llm)
43    
44        ! Local
45    
46        INTEGER ij, l
47    
48        REAL qsat(ip1jmp1, llm)
49        REAL zm(ip1jmp1, llm)
50        REAL mu(ip1jmp1, llm)
51        REAL mv(ip1jm, llm)
52        REAL mw(ip1jmp1, llm+1)
53        REAL zq(ip1jmp1, llm)
54        REAL zzpbar, zzw
55    
56        !--pour rapport de melange saturant--
57    
58        REAL retv, r2es, play
59        logical zdelta
60        REAL tempe(ip1jmp1)
61    
62        !------------------------------------------------------------------
63    
64        r2es = 380.11733
65        retv = 0.6077667
66    
67        !-- Calcul de Qsat en chaque point
68        !-- approximation: au milieu des couches play(l)=(p(l)+p(l+1))/2
69        ! pour eviter une exponentielle.
70        DO l = 1, llm
71           DO ij = 1, ip1jmp1
72              tempe(ij) = teta(ij, l) * pk(ij, l) /cpp
73           ENDDO
74           DO ij = 1, ip1jmp1
75              zdelta = rtt > tempe(ij)
76              play = 0.5*(p(ij, l)+p(ij, l+1))
77              qsat(ij, l) = MIN(0.5, r2es* FOEEW(tempe(ij), zdelta) / play)
78              qsat(ij, l) = qsat(ij, l) / (1. - retv * qsat(ij, l))
79           ENDDO
80        ENDDO
81    
82  c   traitement special pour le cas ou on advecte en longitude plus que le      zzpbar = 0.5 * pdt
83  c   contenu de la maille.      zzw = pdt
84  c   cette partie est mal vectorisee.      DO l=1, llm
85           DO ij = iip2, ip1jm
86  c   pas d'influence de la pression saturante (pour l'instant)            mu(ij, l)=pbaru(ij, l) * zzpbar
87           ENDDO
88  c  calcul du nombre de maille sur lequel on advecte plus que la maille.         DO ij=1, ip1jm
89              mv(ij, l)=pbarv(ij, l) * zzpbar
       n0=0  
       DO l=1,llm  
          nl(l)=0  
          DO ij=iip2,ip1jm  
             nl(l)=nl(l)+iadvplus(ij,l)  
          ENDDO  
          n0=n0+nl(l)  
       ENDDO  
   
       IF(n0.gt.0) THEN  
 ccc      PRINT*,'Nombre de points pour lesquels on advect plus que le'  
 ccc     &       ,'contenu de la maille : ',n0  
   
          DO l=1,llm  
             IF(nl(l).gt.0) THEN  
                iju=0  
 c   indicage des mailles concernees par le traitement special  
                DO ij=iip2,ip1jm  
                   IF(iadvplus(ij,l).eq.1.and.mod(ij,iip1).ne.0) THEN  
                      iju=iju+1  
                      indu(iju)=ij  
                   ENDIF  
                ENDDO  
                niju=iju  
 c              PRINT*,'niju,nl',niju,nl(l)  
   
 c  traitement des mailles  
                DO iju=1,niju  
                   ij=indu(iju)  
                   j=(ij-1)/iip1+1  
                   zu_m=u_m(ij,l)  
                   u_mq(ij,l)=0.  
                   IF(zu_m.gt.0.) THEN  
                      ijq=ij  
                      i=ijq-(j-1)*iip1  
 c   accumulation pour les mailles completements advectees  
                      do while(zu_m.gt.masse(ijq,l))  
                         u_mq(ij,l)=u_mq(ij,l)+q(ijq,l)*masse(ijq,l)  
                         zu_m=zu_m-masse(ijq,l)  
                         i=mod(i-2+iim,iim)+1  
                         ijq=(j-1)*iip1+i  
                      ENDDO  
 c   ajout de la maille non completement advectee  
                      u_mq(ij,l)=u_mq(ij,l)+zu_m*  
      &               (q(ijq,l)+0.5*(1.-zu_m/masse(ijq,l))*dxq(ijq,l))  
                   ELSE  
                      ijq=ij+1  
                      i=ijq-(j-1)*iip1  
 c   accumulation pour les mailles completements advectees  
                      do while(-zu_m.gt.masse(ijq,l))  
                         u_mq(ij,l)=u_mq(ij,l)-q(ijq,l)*masse(ijq,l)  
                         zu_m=zu_m+masse(ijq,l)  
                         i=mod(i,iim)+1  
                         ijq=(j-1)*iip1+i  
                      ENDDO  
 c   ajout de la maille non completement advectee  
                      u_mq(ij,l)=u_mq(ij,l)+zu_m*(q(ijq,l)-  
      &               0.5*(1.+zu_m/masse(ijq,l))*dxq(ijq,l))  
                   ENDIF  
                ENDDO  
             ENDIF  
          ENDDO  
       ENDIF  ! n0.gt.0  
   
   
   
 c   bouclage en latitude  
   
       DO l=1,llm  
         DO ij=iip1+iip1,ip1jm,iip1  
            u_mq(ij,l)=u_mq(ij-iim,l)  
         ENDDO  
       ENDDO  
   
   
 c   calcul des tendances  
   
       DO l=1,llm  
          DO ij=iip2+1,ip1jm  
             new_m=masse(ij,l)+u_m(ij-1,l)-u_m(ij,l)  
             q(ij,l)=(q(ij,l)*masse(ij,l)+  
      &      u_mq(ij-1,l)-u_mq(ij,l))  
      &      /new_m  
             masse(ij,l)=new_m  
          ENDDO  
 c   Modif Fred 22 03 96 correction d'un bug (les scopy ci-dessous)  
          DO ij=iip1+iip1,ip1jm,iip1  
             q(ij-iim,l)=q(ij,l)  
             masse(ij-iim,l)=masse(ij,l)  
          ENDDO  
       ENDDO  
   
 c     CALL SCOPY((jjm-1)*llm,q(iip1+iip1,1),iip1,q(iip2,1),iip1)  
 c     CALL SCOPY((jjm-1)*llm,masse(iip1+iip1,1),iip1,masse(iip2,1),iip1)  
   
   
       RETURN  
       END  
       SUBROUTINE vlyqs(q,pente_max,masse,masse_adv_v,qsat)  
 c  
 c     Auteurs:   P.Le Van, F.Hourdin, F.Forget  
 c  
 c    ********************************************************************  
 c     Shema  d'advection " pseudo amont " .  
 c    ********************************************************************  
 c     q,masse_adv_v,w sont des arguments d'entree  pour le s-pg ....  
 c     qsat             est   un argument de sortie pour le s-pg ....  
 c  
 c  
 c   --------------------------------------------------------------------  
 c  
       use dimens_m  
       use paramet_m  
       use comconst  
       use comvert  
       use logic  
       use comgeom  
       IMPLICIT NONE  
 c  
 c  
 c   Arguments:  
 c   ----------  
       REAL masse(ip1jmp1,llm),pente_max  
       REAL masse_adv_v( ip1jm,llm)  
       REAL q(ip1jmp1,llm)  
       REAL qsat(ip1jmp1,llm)  
 c  
 c      Local  
 c   ---------  
 c  
       INTEGER i,ij,l  
 c  
       REAL airej2,airejjm,airescb(iim),airesch(iim)  
       REAL dyq(ip1jmp1,llm),dyqv(ip1jm)  
       REAL adyqv(ip1jm),dyqmax(ip1jmp1)  
       REAL qbyv(ip1jm,llm)  
   
       REAL qpns,qpsn,dyn1,dys1,dyn2,dys2,newmasse,fn,fs  
 c     REAL newq,oldmasse  
       Logical first,testcpu  
       REAL temps0,temps1,temps2,temps3,temps4,temps5  
       SAVE temps0,temps1,temps2,temps3,temps4,temps5  
       SAVE first,testcpu  
   
       REAL convpn,convps,convmpn,convmps  
       REAL sinlon(iip1),sinlondlon(iip1)  
       REAL coslon(iip1),coslondlon(iip1)  
       SAVE sinlon,coslon,sinlondlon,coslondlon  
       SAVE airej2,airejjm  
 c  
 c  
       REAL      SSUM  
   
       DATA first,testcpu/.true.,.false./  
       DATA temps0,temps1,temps2,temps3,temps4,temps5/0.,0.,0.,0.,0.,0./  
   
       IF(first) THEN  
          PRINT*,'Shema  Amont nouveau  appele dans  Vanleer   '  
          first=.false.  
          do i=2,iip1  
             coslon(i)=cos(rlonv(i))  
             sinlon(i)=sin(rlonv(i))  
             coslondlon(i)=coslon(i)*(rlonu(i)-rlonu(i-1))/pi  
             sinlondlon(i)=sinlon(i)*(rlonu(i)-rlonu(i-1))/pi  
          ENDDO  
          coslon(1)=coslon(iip1)  
          coslondlon(1)=coslondlon(iip1)  
          sinlon(1)=sinlon(iip1)  
          sinlondlon(1)=sinlondlon(iip1)  
          airej2 = SSUM( iim, aire(iip2), 1 )  
          airejjm= SSUM( iim, aire(ip1jm -iim), 1 )  
       ENDIF  
   
 c  
   
   
       DO l = 1, llm  
 c  
 c   --------------------------------  
 c      CALCUL EN LATITUDE  
 c   --------------------------------  
   
 c   On commence par calculer la valeur du traceur moyenne sur le premier cercle  
 c   de latitude autour du pole (qpns pour le pole nord et qpsn pour  
 c    le pole nord) qui sera utilisee pour evaluer les pentes au pole.  
   
       DO i = 1, iim  
       airescb(i) = aire(i+ iip1) * q(i+ iip1,l)  
       airesch(i) = aire(i+ ip1jm- iip1) * q(i+ ip1jm- iip1,l)  
       ENDDO  
       qpns   = SSUM( iim,  airescb ,1 ) / airej2  
       qpsn   = SSUM( iim,  airesch ,1 ) / airejjm  
   
 c   calcul des pentes aux points v  
   
       DO ij=1,ip1jm  
          dyqv(ij)=q(ij,l)-q(ij+iip1,l)  
          adyqv(ij)=abs(dyqv(ij))  
       ENDDO  
   
 c   calcul des pentes aux points scalaires  
   
       DO ij=iip2,ip1jm  
          dyq(ij,l)=.5*(dyqv(ij-iip1)+dyqv(ij))  
          dyqmax(ij)=min(adyqv(ij-iip1),adyqv(ij))  
          dyqmax(ij)=pente_max*dyqmax(ij)  
       ENDDO  
   
 c   calcul des pentes aux poles  
   
       DO ij=1,iip1  
          dyq(ij,l)=qpns-q(ij+iip1,l)  
          dyq(ip1jm+ij,l)=q(ip1jm+ij-iip1,l)-qpsn  
       ENDDO  
   
 c   filtrage de la derivee  
       dyn1=0.  
       dys1=0.  
       dyn2=0.  
       dys2=0.  
       DO ij=1,iim  
          dyn1=dyn1+sinlondlon(ij)*dyq(ij,l)  
          dys1=dys1+sinlondlon(ij)*dyq(ip1jm+ij,l)  
          dyn2=dyn2+coslondlon(ij)*dyq(ij,l)  
          dys2=dys2+coslondlon(ij)*dyq(ip1jm+ij,l)  
       ENDDO  
       DO ij=1,iip1  
          dyq(ij,l)=dyn1*sinlon(ij)+dyn2*coslon(ij)  
          dyq(ip1jm+ij,l)=dys1*sinlon(ij)+dys2*coslon(ij)  
       ENDDO  
   
 c   calcul des pentes limites aux poles  
   
       fn=1.  
       fs=1.  
       DO ij=1,iim  
          IF(pente_max*adyqv(ij).lt.abs(dyq(ij,l))) THEN  
             fn=min(pente_max*adyqv(ij)/abs(dyq(ij,l)),fn)  
          ENDIF  
       IF(pente_max*adyqv(ij+ip1jm-iip1).lt.abs(dyq(ij+ip1jm,l))) THEN  
          fs=min(pente_max*adyqv(ij+ip1jm-iip1)/abs(dyq(ij+ip1jm,l)),fs)  
          ENDIF  
       ENDDO  
       DO ij=1,iip1  
          dyq(ij,l)=fn*dyq(ij,l)  
          dyq(ip1jm+ij,l)=fs*dyq(ip1jm+ij,l)  
       ENDDO  
   
 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC  
 C  En memoire de dIFferents tests sur la  
 C  limitation des pentes aux poles.  
 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC  
 C     PRINT*,dyq(1)  
 C     PRINT*,dyqv(iip1+1)  
 C     apn=abs(dyq(1)/dyqv(iip1+1))  
 C     PRINT*,dyq(ip1jm+1)  
 C     PRINT*,dyqv(ip1jm-iip1+1)  
 C     aps=abs(dyq(ip1jm+1)/dyqv(ip1jm-iip1+1))  
 C     DO ij=2,iim  
 C        apn=amax1(abs(dyq(ij)/dyqv(ij)),apn)  
 C        aps=amax1(abs(dyq(ip1jm+ij)/dyqv(ip1jm-iip1+ij)),aps)  
 C     ENDDO  
 C     apn=min(pente_max/apn,1.)  
 C     aps=min(pente_max/aps,1.)  
 C  
 C  
 C   cas ou on a un extremum au pole  
 C  
 C     IF(dyqv(ismin(iim,dyqv,1))*dyqv(ismax(iim,dyqv,1)).le.0.)  
 C    &   apn=0.  
 C     IF(dyqv(ismax(iim,dyqv(ip1jm-iip1+1),1)+ip1jm-iip1+1)*  
 C    &   dyqv(ismin(iim,dyqv(ip1jm-iip1+1),1)+ip1jm-iip1+1).le.0.)  
 C    &   aps=0.  
 C  
 C   limitation des pentes aux poles  
 C     DO ij=1,iip1  
 C        dyq(ij)=apn*dyq(ij)  
 C        dyq(ip1jm+ij)=aps*dyq(ip1jm+ij)  
 C     ENDDO  
 C  
 C   test  
 C      DO ij=1,iip1  
 C         dyq(iip1+ij)=0.  
 C         dyq(ip1jm+ij-iip1)=0.  
 C      ENDDO  
 C      DO ij=1,ip1jmp1  
 C         dyq(ij)=dyq(ij)*cos(rlatu((ij-1)/iip1+1))  
 C      ENDDO  
 C  
 C changement 10 07 96  
 C     IF(dyqv(ismin(iim,dyqv,1))*dyqv(ismax(iim,dyqv,1)).le.0.)  
 C    &   THEN  
 C        DO ij=1,iip1  
 C           dyqmax(ij)=0.  
 C        ENDDO  
 C     ELSE  
 C        DO ij=1,iip1  
 C           dyqmax(ij)=pente_max*abs(dyqv(ij))  
 C        ENDDO  
 C     ENDIF  
 C  
 C     IF(dyqv(ismax(iim,dyqv(ip1jm-iip1+1),1)+ip1jm-iip1+1)*  
 C    & dyqv(ismin(iim,dyqv(ip1jm-iip1+1),1)+ip1jm-iip1+1).le.0.)  
 C    &THEN  
 C        DO ij=ip1jm+1,ip1jmp1  
 C           dyqmax(ij)=0.  
 C        ENDDO  
 C     ELSE  
 C        DO ij=ip1jm+1,ip1jmp1  
 C           dyqmax(ij)=pente_max*abs(dyqv(ij-iip1))  
 C        ENDDO  
 C     ENDIF  
 C   fin changement 10 07 96  
 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC  
   
 c   calcul des pentes limitees  
   
       DO ij=iip2,ip1jm  
          IF(dyqv(ij)*dyqv(ij-iip1).gt.0.) THEN  
             dyq(ij,l)=sign(min(abs(dyq(ij,l)),dyqmax(ij)),dyq(ij,l))  
          ELSE  
             dyq(ij,l)=0.  
          ENDIF  
       ENDDO  
   
       ENDDO  
   
       DO l=1,llm  
        DO ij=1,ip1jm  
          IF( masse_adv_v(ij,l).GT.0. ) THEN  
            qbyv(ij,l)= MIN( qsat(ij+iip1,l), q(ij+iip1,l )  +  
      ,      dyq(ij+iip1,l)*0.5*(1.-masse_adv_v(ij,l)/masse(ij+iip1,l)))  
          ELSE  
               qbyv(ij,l)= MIN( qsat(ij,l), q(ij,l) - dyq(ij,l) *  
      ,                   0.5*(1.+masse_adv_v(ij,l)/masse(ij,l)) )  
          ENDIF  
           qbyv(ij,l) = masse_adv_v(ij,l)*qbyv(ij,l)  
90         ENDDO         ENDDO
91        ENDDO         DO ij=1, ip1jmp1
92              mw(ij, l)=w(ij, l) * zzw
93           ENDDO
94        ENDDO
95    
96        DO ij=1, ip1jmp1
97           mw(ij, llm+1)=0.
98        ENDDO
99    
100        CALL SCOPY(ijp1llm, q, 1, zq, 1)
101        CALL SCOPY(ijp1llm, masse, 1, zm, 1)
102    
103        ! call minmaxq(zq, qmin, qmax, 'avant vlxqs ')
104        call vlxqs(zq, pente_max, zm, mu, qsat)
105    
106        ! call minmaxq(zq, qmin, qmax, 'avant vlyqs ')
107    
108        call vlyqs(zq, pente_max, zm, mv, qsat)
109    
110        ! call minmaxq(zq, qmin, qmax, 'avant vlz ')
111    
112        call vlz(zq, pente_max, zm, mw)
113    
114        ! call minmaxq(zq, qmin, qmax, 'avant vlyqs ')
115        ! call minmaxq(zm, qmin, qmax, 'M avant vlyqs ')
116    
117        call vlyqs(zq, pente_max, zm, mv, qsat)
118    
119        ! call minmaxq(zq, qmin, qmax, 'avant vlxqs ')
120        ! call minmaxq(zm, qmin, qmax, 'M avant vlxqs ')
121    
122        call vlxqs(zq, pente_max, zm, mu, qsat)
123    
124        ! call minmaxq(zq, qmin, qmax, 'apres vlxqs ')
125        ! call minmaxq(zm, qmin, qmax, 'M apres vlxqs ')
126    
127        DO l=1, llm
128           DO ij=1, ip1jmp1
129              q(ij, l)=zq(ij, l)
130           ENDDO
131           DO ij=1, ip1jm+1, iip1
132              q(ij+iim, l)=q(ij, l)
133           ENDDO
134        ENDDO
135    
136        DO l=1,llm    END SUBROUTINE vlspltqs
          DO ij=iip2,ip1jm  
             newmasse=masse(ij,l)  
      &      +masse_adv_v(ij,l)-masse_adv_v(ij-iip1,l)  
             q(ij,l)=(q(ij,l)*masse(ij,l)+qbyv(ij,l)-qbyv(ij-iip1,l))  
      &         /newmasse  
             masse(ij,l)=newmasse  
          ENDDO  
 c.-. ancienne version  
          convpn=SSUM(iim,qbyv(1,l),1)/apoln  
          convmpn=ssum(iim,masse_adv_v(1,l),1)/apoln  
          DO ij = 1,iip1  
             newmasse=masse(ij,l)+convmpn*aire(ij)  
             q(ij,l)=(q(ij,l)*masse(ij,l)+convpn*aire(ij))/  
      &               newmasse  
             masse(ij,l)=newmasse  
          ENDDO  
          convps  = -SSUM(iim,qbyv(ip1jm-iim,l),1)/apols  
          convmps = -SSUM(iim,masse_adv_v(ip1jm-iim,l),1)/apols  
          DO ij = ip1jm+1,ip1jmp1  
             newmasse=masse(ij,l)+convmps*aire(ij)  
             q(ij,l)=(q(ij,l)*masse(ij,l)+convps*aire(ij))/  
      &               newmasse  
             masse(ij,l)=newmasse  
          ENDDO  
 c.-. fin ancienne version  
   
 c._. nouvelle version  
 c        convpn=SSUM(iim,qbyv(1,l),1)  
 c        convmpn=ssum(iim,masse_adv_v(1,l),1)  
 c        oldmasse=ssum(iim,masse(1,l),1)  
 c        newmasse=oldmasse+convmpn  
 c        newq=(q(1,l)*oldmasse+convpn)/newmasse  
 c        newmasse=newmasse/apoln  
 c        DO ij = 1,iip1  
 c           q(ij,l)=newq  
 c           masse(ij,l)=newmasse*aire(ij)  
 c        ENDDO  
 c        convps=-SSUM(iim,qbyv(ip1jm-iim,l),1)  
 c        convmps=-ssum(iim,masse_adv_v(ip1jm-iim,l),1)  
 c        oldmasse=ssum(iim,masse(ip1jm-iim,l),1)  
 c        newmasse=oldmasse+convmps  
 c        newq=(q(ip1jmp1,l)*oldmasse+convps)/newmasse  
 c        newmasse=newmasse/apols  
 c        DO ij = ip1jm+1,ip1jmp1  
 c           q(ij,l)=newq  
 c           masse(ij,l)=newmasse*aire(ij)  
 c        ENDDO  
 c._. fin nouvelle version  
       ENDDO  
137    
138        RETURN  end module vlspltqs_m
       END  

Legend:
Removed from v.10  
changed lines
  Added in v.254

  ViewVC Help
Powered by ViewVC 1.1.21